2 * AD7303 Digital to analog converters driver
4 * Copyright 2013 Analog Devices Inc.
6 * Licensed under the GPL-2.
10 #include <linux/module.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>
18 #include <linux/iio/iio.h>
19 #include <linux/iio/sysfs.h>
21 #include <linux/platform_data/ad7303.h>
23 #define AD7303_CFG_EXTERNAL_VREF BIT(15)
24 #define AD7303_CFG_POWER_DOWN(ch) BIT(11 + (ch))
25 #define AD7303_CFG_ADDR_OFFSET 10
27 #define AD7303_CMD_UPDATE_DAC (0x3 << 8)
30 * struct ad7303_state - driver instance specific data
31 * @spi: the device for this driver instance
32 * @config: cached config register value
33 * @dac_cache: current DAC raw value (chip does not support readback)
34 * @data: spi transfer buffer
38 struct spi_device
*spi
;
42 struct regulator
*vdd_reg
;
43 struct regulator
*vref_reg
;
46 * DMA (thus cache coherency maintenance) requires the
47 * transfer buffers to live in their own cache lines.
49 __be16 data ____cacheline_aligned
;
52 static int ad7303_write(struct ad7303_state
*st
, unsigned int chan
,
55 st
->data
= cpu_to_be16(AD7303_CMD_UPDATE_DAC
|
56 (chan
<< AD7303_CFG_ADDR_OFFSET
) |
59 return spi_write(st
->spi
, &st
->data
, sizeof(st
->data
));
62 static ssize_t
ad7303_read_dac_powerdown(struct iio_dev
*indio_dev
,
63 uintptr_t private, const struct iio_chan_spec
*chan
, char *buf
)
65 struct ad7303_state
*st
= iio_priv(indio_dev
);
67 return sprintf(buf
, "%d\n", (bool)(st
->config
&
68 AD7303_CFG_POWER_DOWN(chan
->channel
)));
71 static ssize_t
ad7303_write_dac_powerdown(struct iio_dev
*indio_dev
,
72 uintptr_t private, const struct iio_chan_spec
*chan
, const char *buf
,
75 struct ad7303_state
*st
= iio_priv(indio_dev
);
79 ret
= strtobool(buf
, &pwr_down
);
83 mutex_lock(&indio_dev
->mlock
);
86 st
->config
|= AD7303_CFG_POWER_DOWN(chan
->channel
);
88 st
->config
&= ~AD7303_CFG_POWER_DOWN(chan
->channel
);
90 /* There is no noop cmd which allows us to only update the powerdown
91 * mode, so just write one of the DAC channels again */
92 ad7303_write(st
, chan
->channel
, st
->dac_cache
[chan
->channel
]);
94 mutex_unlock(&indio_dev
->mlock
);
98 static int ad7303_get_vref(struct ad7303_state
*st
,
99 struct iio_chan_spec
const *chan
)
103 if (st
->config
& AD7303_CFG_EXTERNAL_VREF
)
104 return regulator_get_voltage(st
->vref_reg
);
106 ret
= regulator_get_voltage(st
->vdd_reg
);
112 static int ad7303_read_raw(struct iio_dev
*indio_dev
,
113 struct iio_chan_spec
const *chan
, int *val
, int *val2
, long info
)
115 struct ad7303_state
*st
= iio_priv(indio_dev
);
119 case IIO_CHAN_INFO_RAW
:
120 *val
= st
->dac_cache
[chan
->channel
];
122 case IIO_CHAN_INFO_SCALE
:
123 vref_uv
= ad7303_get_vref(st
, chan
);
127 *val
= 2 * vref_uv
/ 1000;
128 *val2
= chan
->scan_type
.realbits
;
130 return IIO_VAL_FRACTIONAL_LOG2
;
137 static int ad7303_write_raw(struct iio_dev
*indio_dev
,
138 struct iio_chan_spec
const *chan
, int val
, int val2
, long mask
)
140 struct ad7303_state
*st
= iio_priv(indio_dev
);
144 case IIO_CHAN_INFO_RAW
:
145 if (val
>= (1 << chan
->scan_type
.realbits
) || val
< 0)
148 mutex_lock(&indio_dev
->mlock
);
149 ret
= ad7303_write(st
, chan
->address
, val
);
151 st
->dac_cache
[chan
->channel
] = val
;
152 mutex_unlock(&indio_dev
->mlock
);
161 static const struct iio_info ad7303_info
= {
162 .read_raw
= ad7303_read_raw
,
163 .write_raw
= ad7303_write_raw
,
166 static const struct iio_chan_spec_ext_info ad7303_ext_info
[] = {
169 .read
= ad7303_read_dac_powerdown
,
170 .write
= ad7303_write_dac_powerdown
,
171 .shared
= IIO_SEPARATE
,
176 #define AD7303_CHANNEL(chan) { \
177 .type = IIO_VOLTAGE, \
181 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
182 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
190 .ext_info = ad7303_ext_info, \
193 static const struct iio_chan_spec ad7303_channels
[] = {
198 static int ad7303_probe(struct spi_device
*spi
)
200 const struct spi_device_id
*id
= spi_get_device_id(spi
);
201 struct iio_dev
*indio_dev
;
202 struct ad7303_state
*st
;
206 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*st
));
207 if (indio_dev
== NULL
)
210 st
= iio_priv(indio_dev
);
211 spi_set_drvdata(spi
, indio_dev
);
215 st
->vdd_reg
= devm_regulator_get(&spi
->dev
, "Vdd");
216 if (IS_ERR(st
->vdd_reg
))
217 return PTR_ERR(st
->vdd_reg
);
219 ret
= regulator_enable(st
->vdd_reg
);
223 if (spi
->dev
.of_node
) {
224 ext_ref
= of_property_read_bool(spi
->dev
.of_node
,
227 struct ad7303_platform_data
*pdata
= spi
->dev
.platform_data
;
228 if (pdata
&& pdata
->use_external_ref
)
235 st
->vref_reg
= devm_regulator_get(&spi
->dev
, "REF");
236 if (IS_ERR(st
->vref_reg
)) {
237 ret
= PTR_ERR(st
->vref_reg
);
238 goto err_disable_vdd_reg
;
241 ret
= regulator_enable(st
->vref_reg
);
243 goto err_disable_vdd_reg
;
245 st
->config
|= AD7303_CFG_EXTERNAL_VREF
;
248 indio_dev
->dev
.parent
= &spi
->dev
;
249 indio_dev
->name
= id
->name
;
250 indio_dev
->info
= &ad7303_info
;
251 indio_dev
->modes
= INDIO_DIRECT_MODE
;
252 indio_dev
->channels
= ad7303_channels
;
253 indio_dev
->num_channels
= ARRAY_SIZE(ad7303_channels
);
255 ret
= iio_device_register(indio_dev
);
257 goto err_disable_vref_reg
;
261 err_disable_vref_reg
:
263 regulator_disable(st
->vref_reg
);
265 regulator_disable(st
->vdd_reg
);
269 static int ad7303_remove(struct spi_device
*spi
)
271 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
272 struct ad7303_state
*st
= iio_priv(indio_dev
);
274 iio_device_unregister(indio_dev
);
277 regulator_disable(st
->vref_reg
);
278 regulator_disable(st
->vdd_reg
);
283 static const struct of_device_id ad7303_spi_of_match
[] = {
284 { .compatible
= "adi,ad7303", },
287 MODULE_DEVICE_TABLE(of
, ad7303_spi_of_match
);
289 static const struct spi_device_id ad7303_spi_ids
[] = {
293 MODULE_DEVICE_TABLE(spi
, ad7303_spi_ids
);
295 static struct spi_driver ad7303_driver
= {
298 .of_match_table
= of_match_ptr(ad7303_spi_of_match
),
300 .probe
= ad7303_probe
,
301 .remove
= ad7303_remove
,
302 .id_table
= ad7303_spi_ids
,
304 module_spi_driver(ad7303_driver
);
306 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
307 MODULE_DESCRIPTION("Analog Devices AD7303 DAC driver");
308 MODULE_LICENSE("GPL v2");