1 // SPDX-License-Identifier: GPL-2.0-only
3 * AD7303 Digital to analog converters driver
5 * Copyright 2013 Analog Devices Inc.
9 #include <linux/module.h>
10 #include <linux/mod_devicetable.h>
11 #include <linux/kernel.h>
12 #include <linux/spi/spi.h>
13 #include <linux/slab.h>
14 #include <linux/sysfs.h>
15 #include <linux/regulator/consumer.h>
17 #include <linux/iio/iio.h>
18 #include <linux/iio/sysfs.h>
20 #define AD7303_CFG_EXTERNAL_VREF BIT(15)
21 #define AD7303_CFG_POWER_DOWN(ch) BIT(11 + (ch))
22 #define AD7303_CFG_ADDR_OFFSET 10
24 #define AD7303_CMD_UPDATE_DAC (0x3 << 8)
27 * struct ad7303_state - driver instance specific data
28 * @spi: the device for this driver instance
29 * @config: cached config register value
30 * @dac_cache: current DAC raw value (chip does not support readback)
31 * @vdd_reg: reference to VDD regulator
32 * @vref_reg: reference to VREF regulator
33 * @lock: protect writes and cache updates
34 * @data: spi transfer buffer
38 struct spi_device
*spi
;
42 struct regulator
*vdd_reg
;
43 struct regulator
*vref_reg
;
47 * DMA (thus cache coherency maintenance) requires the
48 * transfer buffers to live in their own cache lines.
50 __be16 data ____cacheline_aligned
;
53 static int ad7303_write(struct ad7303_state
*st
, unsigned int chan
,
56 st
->data
= cpu_to_be16(AD7303_CMD_UPDATE_DAC
|
57 (chan
<< AD7303_CFG_ADDR_OFFSET
) |
60 return spi_write(st
->spi
, &st
->data
, sizeof(st
->data
));
63 static ssize_t
ad7303_read_dac_powerdown(struct iio_dev
*indio_dev
,
64 uintptr_t private, const struct iio_chan_spec
*chan
, char *buf
)
66 struct ad7303_state
*st
= iio_priv(indio_dev
);
68 return sprintf(buf
, "%d\n", (bool)(st
->config
&
69 AD7303_CFG_POWER_DOWN(chan
->channel
)));
72 static ssize_t
ad7303_write_dac_powerdown(struct iio_dev
*indio_dev
,
73 uintptr_t private, const struct iio_chan_spec
*chan
, const char *buf
,
76 struct ad7303_state
*st
= iio_priv(indio_dev
);
80 ret
= strtobool(buf
, &pwr_down
);
84 mutex_lock(&st
->lock
);
87 st
->config
|= AD7303_CFG_POWER_DOWN(chan
->channel
);
89 st
->config
&= ~AD7303_CFG_POWER_DOWN(chan
->channel
);
91 /* There is no noop cmd which allows us to only update the powerdown
92 * mode, so just write one of the DAC channels again */
93 ad7303_write(st
, chan
->channel
, st
->dac_cache
[chan
->channel
]);
95 mutex_unlock(&st
->lock
);
99 static int ad7303_get_vref(struct ad7303_state
*st
,
100 struct iio_chan_spec
const *chan
)
104 if (st
->config
& AD7303_CFG_EXTERNAL_VREF
)
105 return regulator_get_voltage(st
->vref_reg
);
107 ret
= regulator_get_voltage(st
->vdd_reg
);
113 static int ad7303_read_raw(struct iio_dev
*indio_dev
,
114 struct iio_chan_spec
const *chan
, int *val
, int *val2
, long info
)
116 struct ad7303_state
*st
= iio_priv(indio_dev
);
120 case IIO_CHAN_INFO_RAW
:
121 mutex_lock(&st
->lock
);
122 *val
= st
->dac_cache
[chan
->channel
];
123 mutex_unlock(&st
->lock
);
125 case IIO_CHAN_INFO_SCALE
:
126 vref_uv
= ad7303_get_vref(st
, chan
);
130 *val
= 2 * vref_uv
/ 1000;
131 *val2
= chan
->scan_type
.realbits
;
133 return IIO_VAL_FRACTIONAL_LOG2
;
140 static int ad7303_write_raw(struct iio_dev
*indio_dev
,
141 struct iio_chan_spec
const *chan
, int val
, int val2
, long mask
)
143 struct ad7303_state
*st
= iio_priv(indio_dev
);
147 case IIO_CHAN_INFO_RAW
:
148 if (val
>= (1 << chan
->scan_type
.realbits
) || val
< 0)
151 mutex_lock(&st
->lock
);
152 ret
= ad7303_write(st
, chan
->address
, val
);
154 st
->dac_cache
[chan
->channel
] = val
;
155 mutex_unlock(&st
->lock
);
164 static const struct iio_info ad7303_info
= {
165 .read_raw
= ad7303_read_raw
,
166 .write_raw
= ad7303_write_raw
,
169 static const struct iio_chan_spec_ext_info ad7303_ext_info
[] = {
172 .read
= ad7303_read_dac_powerdown
,
173 .write
= ad7303_write_dac_powerdown
,
174 .shared
= IIO_SEPARATE
,
179 #define AD7303_CHANNEL(chan) { \
180 .type = IIO_VOLTAGE, \
184 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
185 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
193 .ext_info = ad7303_ext_info, \
196 static const struct iio_chan_spec ad7303_channels
[] = {
201 static int ad7303_probe(struct spi_device
*spi
)
203 const struct spi_device_id
*id
= spi_get_device_id(spi
);
204 struct iio_dev
*indio_dev
;
205 struct ad7303_state
*st
;
208 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*st
));
209 if (indio_dev
== NULL
)
212 st
= iio_priv(indio_dev
);
213 spi_set_drvdata(spi
, indio_dev
);
217 mutex_init(&st
->lock
);
219 st
->vdd_reg
= devm_regulator_get(&spi
->dev
, "Vdd");
220 if (IS_ERR(st
->vdd_reg
))
221 return PTR_ERR(st
->vdd_reg
);
223 ret
= regulator_enable(st
->vdd_reg
);
227 st
->vref_reg
= devm_regulator_get_optional(&spi
->dev
, "REF");
228 if (IS_ERR(st
->vref_reg
)) {
229 ret
= PTR_ERR(st
->vref_reg
);
231 goto err_disable_vdd_reg
;
236 ret
= regulator_enable(st
->vref_reg
);
238 goto err_disable_vdd_reg
;
240 st
->config
|= AD7303_CFG_EXTERNAL_VREF
;
243 indio_dev
->name
= id
->name
;
244 indio_dev
->info
= &ad7303_info
;
245 indio_dev
->modes
= INDIO_DIRECT_MODE
;
246 indio_dev
->channels
= ad7303_channels
;
247 indio_dev
->num_channels
= ARRAY_SIZE(ad7303_channels
);
249 ret
= iio_device_register(indio_dev
);
251 goto err_disable_vref_reg
;
255 err_disable_vref_reg
:
257 regulator_disable(st
->vref_reg
);
259 regulator_disable(st
->vdd_reg
);
263 static int ad7303_remove(struct spi_device
*spi
)
265 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
266 struct ad7303_state
*st
= iio_priv(indio_dev
);
268 iio_device_unregister(indio_dev
);
271 regulator_disable(st
->vref_reg
);
272 regulator_disable(st
->vdd_reg
);
277 static const struct of_device_id ad7303_spi_of_match
[] = {
278 { .compatible
= "adi,ad7303", },
281 MODULE_DEVICE_TABLE(of
, ad7303_spi_of_match
);
283 static const struct spi_device_id ad7303_spi_ids
[] = {
287 MODULE_DEVICE_TABLE(spi
, ad7303_spi_ids
);
289 static struct spi_driver ad7303_driver
= {
292 .of_match_table
= ad7303_spi_of_match
,
294 .probe
= ad7303_probe
,
295 .remove
= ad7303_remove
,
296 .id_table
= ad7303_spi_ids
,
298 module_spi_driver(ad7303_driver
);
300 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
301 MODULE_DESCRIPTION("Analog Devices AD7303 DAC driver");
302 MODULE_LICENSE("GPL v2");