1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * AD5415, AD5426, AD5429, AD5432, AD5439, AD5443, AD5449 Digital to Analog |
4 | * Converter driver. |
5 | * |
6 | * Copyright 2012 Analog Devices Inc. |
7 | * Author: Lars-Peter Clausen <lars@metafoo.de> |
8 | */ |
9 | |
10 | #include <linux/device.h> |
11 | #include <linux/err.h> |
12 | #include <linux/module.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/spi/spi.h> |
15 | #include <linux/slab.h> |
16 | #include <linux/sysfs.h> |
17 | #include <linux/regulator/consumer.h> |
18 | #include <asm/unaligned.h> |
19 | |
20 | #include <linux/iio/iio.h> |
21 | #include <linux/iio/sysfs.h> |
22 | |
23 | #include <linux/platform_data/ad5449.h> |
24 | |
25 | #define AD5449_MAX_CHANNELS 2 |
26 | #define AD5449_MAX_VREFS 2 |
27 | |
28 | #define AD5449_CMD_NOOP 0x0 |
29 | #define AD5449_CMD_LOAD_AND_UPDATE(x) (0x1 + (x) * 3) |
30 | #define AD5449_CMD_READ(x) (0x2 + (x) * 3) |
31 | #define AD5449_CMD_LOAD(x) (0x3 + (x) * 3) |
32 | #define AD5449_CMD_CTRL 13 |
33 | |
34 | #define AD5449_CTRL_SDO_OFFSET 10 |
35 | #define AD5449_CTRL_DAISY_CHAIN BIT(9) |
36 | #define AD5449_CTRL_HCLR_TO_MIDSCALE BIT(8) |
37 | #define AD5449_CTRL_SAMPLE_RISING BIT(7) |
38 | |
39 | /** |
40 | * struct ad5449_chip_info - chip specific information |
41 | * @channels: Channel specification |
42 | * @num_channels: Number of channels |
43 | * @has_ctrl: Chip has a control register |
44 | */ |
45 | struct ad5449_chip_info { |
46 | const struct iio_chan_spec *channels; |
47 | unsigned int num_channels; |
48 | bool has_ctrl; |
49 | }; |
50 | |
51 | /** |
52 | * struct ad5449 - driver instance specific data |
53 | * @spi: the SPI device for this driver instance |
54 | * @chip_info: chip model specific constants, available modes etc |
55 | * @vref_reg: vref supply regulators |
56 | * @has_sdo: whether the SDO line is connected |
57 | * @dac_cache: Cache for the DAC values |
58 | * @data: spi transfer buffers |
59 | * @lock: lock to protect the data buffer during SPI ops |
60 | */ |
61 | struct ad5449 { |
62 | struct spi_device *spi; |
63 | const struct ad5449_chip_info *chip_info; |
64 | struct regulator_bulk_data vref_reg[AD5449_MAX_VREFS]; |
65 | struct mutex lock; |
66 | |
67 | bool has_sdo; |
68 | uint16_t dac_cache[AD5449_MAX_CHANNELS]; |
69 | |
70 | /* |
71 | * DMA (thus cache coherency maintenance) may require the |
72 | * transfer buffers to live in their own cache lines. |
73 | */ |
74 | __be16 data[2] __aligned(IIO_DMA_MINALIGN); |
75 | }; |
76 | |
77 | enum ad5449_type { |
78 | ID_AD5426, |
79 | ID_AD5429, |
80 | ID_AD5432, |
81 | ID_AD5439, |
82 | ID_AD5443, |
83 | ID_AD5449, |
84 | }; |
85 | |
86 | static int ad5449_write(struct iio_dev *indio_dev, unsigned int addr, |
87 | unsigned int val) |
88 | { |
89 | struct ad5449 *st = iio_priv(indio_dev); |
90 | int ret; |
91 | |
92 | mutex_lock(&st->lock); |
93 | st->data[0] = cpu_to_be16((addr << 12) | val); |
94 | ret = spi_write(spi: st->spi, buf: st->data, len: 2); |
95 | mutex_unlock(lock: &st->lock); |
96 | |
97 | return ret; |
98 | } |
99 | |
100 | static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr, |
101 | unsigned int *val) |
102 | { |
103 | struct ad5449 *st = iio_priv(indio_dev); |
104 | int ret; |
105 | struct spi_transfer t[] = { |
106 | { |
107 | .tx_buf = &st->data[0], |
108 | .len = 2, |
109 | .cs_change = 1, |
110 | }, { |
111 | .tx_buf = &st->data[1], |
112 | .rx_buf = &st->data[1], |
113 | .len = 2, |
114 | }, |
115 | }; |
116 | |
117 | mutex_lock(&st->lock); |
118 | st->data[0] = cpu_to_be16(addr << 12); |
119 | st->data[1] = cpu_to_be16(AD5449_CMD_NOOP); |
120 | |
121 | ret = spi_sync_transfer(spi: st->spi, xfers: t, ARRAY_SIZE(t)); |
122 | if (ret < 0) |
123 | goto out_unlock; |
124 | |
125 | *val = be16_to_cpu(st->data[1]); |
126 | |
127 | out_unlock: |
128 | mutex_unlock(lock: &st->lock); |
129 | return ret; |
130 | } |
131 | |
132 | static int ad5449_read_raw(struct iio_dev *indio_dev, |
133 | struct iio_chan_spec const *chan, int *val, int *val2, long info) |
134 | { |
135 | struct ad5449 *st = iio_priv(indio_dev); |
136 | struct regulator_bulk_data *reg; |
137 | int scale_uv; |
138 | int ret; |
139 | |
140 | switch (info) { |
141 | case IIO_CHAN_INFO_RAW: |
142 | if (st->has_sdo) { |
143 | ret = ad5449_read(indio_dev, |
144 | AD5449_CMD_READ(chan->address), val); |
145 | if (ret) |
146 | return ret; |
147 | *val &= 0xfff; |
148 | } else { |
149 | *val = st->dac_cache[chan->address]; |
150 | } |
151 | |
152 | return IIO_VAL_INT; |
153 | case IIO_CHAN_INFO_SCALE: |
154 | reg = &st->vref_reg[chan->channel]; |
155 | scale_uv = regulator_get_voltage(regulator: reg->consumer); |
156 | if (scale_uv < 0) |
157 | return scale_uv; |
158 | |
159 | *val = scale_uv / 1000; |
160 | *val2 = chan->scan_type.realbits; |
161 | |
162 | return IIO_VAL_FRACTIONAL_LOG2; |
163 | default: |
164 | break; |
165 | } |
166 | |
167 | return -EINVAL; |
168 | } |
169 | |
170 | static int ad5449_write_raw(struct iio_dev *indio_dev, |
171 | struct iio_chan_spec const *chan, int val, int val2, long info) |
172 | { |
173 | struct ad5449 *st = iio_priv(indio_dev); |
174 | int ret; |
175 | |
176 | switch (info) { |
177 | case IIO_CHAN_INFO_RAW: |
178 | if (val < 0 || val >= (1 << chan->scan_type.realbits)) |
179 | return -EINVAL; |
180 | |
181 | ret = ad5449_write(indio_dev, |
182 | AD5449_CMD_LOAD_AND_UPDATE(chan->address), |
183 | val: val << chan->scan_type.shift); |
184 | if (ret == 0) |
185 | st->dac_cache[chan->address] = val; |
186 | break; |
187 | default: |
188 | ret = -EINVAL; |
189 | } |
190 | |
191 | return ret; |
192 | } |
193 | |
194 | static const struct iio_info ad5449_info = { |
195 | .read_raw = ad5449_read_raw, |
196 | .write_raw = ad5449_write_raw, |
197 | }; |
198 | |
199 | #define AD5449_CHANNEL(chan, bits) { \ |
200 | .type = IIO_VOLTAGE, \ |
201 | .indexed = 1, \ |
202 | .output = 1, \ |
203 | .channel = (chan), \ |
204 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
205 | BIT(IIO_CHAN_INFO_SCALE), \ |
206 | .address = (chan), \ |
207 | .scan_type = { \ |
208 | .sign = 'u', \ |
209 | .realbits = (bits), \ |
210 | .storagebits = 16, \ |
211 | .shift = 12 - (bits), \ |
212 | }, \ |
213 | } |
214 | |
215 | #define DECLARE_AD5449_CHANNELS(name, bits) \ |
216 | const struct iio_chan_spec name[] = { \ |
217 | AD5449_CHANNEL(0, bits), \ |
218 | AD5449_CHANNEL(1, bits), \ |
219 | } |
220 | |
221 | static DECLARE_AD5449_CHANNELS(ad5429_channels, 8); |
222 | static DECLARE_AD5449_CHANNELS(ad5439_channels, 10); |
223 | static DECLARE_AD5449_CHANNELS(ad5449_channels, 12); |
224 | |
225 | static const struct ad5449_chip_info ad5449_chip_info[] = { |
226 | [ID_AD5426] = { |
227 | .channels = ad5429_channels, |
228 | .num_channels = 1, |
229 | .has_ctrl = false, |
230 | }, |
231 | [ID_AD5429] = { |
232 | .channels = ad5429_channels, |
233 | .num_channels = 2, |
234 | .has_ctrl = true, |
235 | }, |
236 | [ID_AD5432] = { |
237 | .channels = ad5439_channels, |
238 | .num_channels = 1, |
239 | .has_ctrl = false, |
240 | }, |
241 | [ID_AD5439] = { |
242 | .channels = ad5439_channels, |
243 | .num_channels = 2, |
244 | .has_ctrl = true, |
245 | }, |
246 | [ID_AD5443] = { |
247 | .channels = ad5449_channels, |
248 | .num_channels = 1, |
249 | .has_ctrl = false, |
250 | }, |
251 | [ID_AD5449] = { |
252 | .channels = ad5449_channels, |
253 | .num_channels = 2, |
254 | .has_ctrl = true, |
255 | }, |
256 | }; |
257 | |
258 | static const char *ad5449_vref_name(struct ad5449 *st, int n) |
259 | { |
260 | if (st->chip_info->num_channels == 1) |
261 | return "VREF" ; |
262 | |
263 | if (n == 0) |
264 | return "VREFA" ; |
265 | else |
266 | return "VREFB" ; |
267 | } |
268 | |
269 | static int ad5449_spi_probe(struct spi_device *spi) |
270 | { |
271 | struct ad5449_platform_data *pdata = spi->dev.platform_data; |
272 | const struct spi_device_id *id = spi_get_device_id(sdev: spi); |
273 | struct iio_dev *indio_dev; |
274 | struct ad5449 *st; |
275 | unsigned int i; |
276 | int ret; |
277 | |
278 | indio_dev = devm_iio_device_alloc(parent: &spi->dev, sizeof_priv: sizeof(*st)); |
279 | if (indio_dev == NULL) |
280 | return -ENOMEM; |
281 | |
282 | st = iio_priv(indio_dev); |
283 | spi_set_drvdata(spi, data: indio_dev); |
284 | |
285 | st->chip_info = &ad5449_chip_info[id->driver_data]; |
286 | st->spi = spi; |
287 | |
288 | for (i = 0; i < st->chip_info->num_channels; ++i) |
289 | st->vref_reg[i].supply = ad5449_vref_name(st, n: i); |
290 | |
291 | ret = devm_regulator_bulk_get(dev: &spi->dev, num_consumers: st->chip_info->num_channels, |
292 | consumers: st->vref_reg); |
293 | if (ret) |
294 | return ret; |
295 | |
296 | ret = regulator_bulk_enable(num_consumers: st->chip_info->num_channels, consumers: st->vref_reg); |
297 | if (ret) |
298 | return ret; |
299 | |
300 | indio_dev->name = id->name; |
301 | indio_dev->info = &ad5449_info; |
302 | indio_dev->modes = INDIO_DIRECT_MODE; |
303 | indio_dev->channels = st->chip_info->channels; |
304 | indio_dev->num_channels = st->chip_info->num_channels; |
305 | |
306 | mutex_init(&st->lock); |
307 | |
308 | if (st->chip_info->has_ctrl) { |
309 | unsigned int ctrl = 0x00; |
310 | if (pdata) { |
311 | if (pdata->hardware_clear_to_midscale) |
312 | ctrl |= AD5449_CTRL_HCLR_TO_MIDSCALE; |
313 | ctrl |= pdata->sdo_mode << AD5449_CTRL_SDO_OFFSET; |
314 | st->has_sdo = pdata->sdo_mode != AD5449_SDO_DISABLED; |
315 | } else { |
316 | st->has_sdo = true; |
317 | } |
318 | ad5449_write(indio_dev, AD5449_CMD_CTRL, val: ctrl); |
319 | } |
320 | |
321 | ret = iio_device_register(indio_dev); |
322 | if (ret) |
323 | goto error_disable_reg; |
324 | |
325 | return 0; |
326 | |
327 | error_disable_reg: |
328 | regulator_bulk_disable(num_consumers: st->chip_info->num_channels, consumers: st->vref_reg); |
329 | |
330 | return ret; |
331 | } |
332 | |
333 | static void ad5449_spi_remove(struct spi_device *spi) |
334 | { |
335 | struct iio_dev *indio_dev = spi_get_drvdata(spi); |
336 | struct ad5449 *st = iio_priv(indio_dev); |
337 | |
338 | iio_device_unregister(indio_dev); |
339 | |
340 | regulator_bulk_disable(num_consumers: st->chip_info->num_channels, consumers: st->vref_reg); |
341 | } |
342 | |
343 | static const struct spi_device_id ad5449_spi_ids[] = { |
344 | { "ad5415" , ID_AD5449 }, |
345 | { "ad5426" , ID_AD5426 }, |
346 | { "ad5429" , ID_AD5429 }, |
347 | { "ad5432" , ID_AD5432 }, |
348 | { "ad5439" , ID_AD5439 }, |
349 | { "ad5443" , ID_AD5443 }, |
350 | { "ad5449" , ID_AD5449 }, |
351 | {} |
352 | }; |
353 | MODULE_DEVICE_TABLE(spi, ad5449_spi_ids); |
354 | |
355 | static struct spi_driver ad5449_spi_driver = { |
356 | .driver = { |
357 | .name = "ad5449" , |
358 | }, |
359 | .probe = ad5449_spi_probe, |
360 | .remove = ad5449_spi_remove, |
361 | .id_table = ad5449_spi_ids, |
362 | }; |
363 | module_spi_driver(ad5449_spi_driver); |
364 | |
365 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>" ); |
366 | MODULE_DESCRIPTION("Analog Devices AD5449 and similar DACs" ); |
367 | MODULE_LICENSE("GPL v2" ); |
368 | |