1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * AD5755, AD5755-1, AD5757, AD5735, AD5737 Digital to analog converters driver |
4 | * |
5 | * Copyright 2012 Analog Devices Inc. |
6 | */ |
7 | |
8 | #include <linux/device.h> |
9 | #include <linux/err.h> |
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/delay.h> |
16 | #include <linux/property.h> |
17 | |
18 | #include <linux/iio/iio.h> |
19 | #include <linux/iio/sysfs.h> |
20 | |
21 | #define AD5755_NUM_CHANNELS 4 |
22 | |
23 | #define AD5755_ADDR(x) ((x) << 16) |
24 | |
25 | #define AD5755_WRITE_REG_DATA(chan) (chan) |
26 | #define AD5755_WRITE_REG_GAIN(chan) (0x08 | (chan)) |
27 | #define AD5755_WRITE_REG_OFFSET(chan) (0x10 | (chan)) |
28 | #define AD5755_WRITE_REG_CTRL(chan) (0x1c | (chan)) |
29 | |
30 | #define AD5755_READ_REG_DATA(chan) (chan) |
31 | #define AD5755_READ_REG_CTRL(chan) (0x4 | (chan)) |
32 | #define AD5755_READ_REG_GAIN(chan) (0x8 | (chan)) |
33 | #define AD5755_READ_REG_OFFSET(chan) (0xc | (chan)) |
34 | #define AD5755_READ_REG_CLEAR(chan) (0x10 | (chan)) |
35 | #define AD5755_READ_REG_SLEW(chan) (0x14 | (chan)) |
36 | #define AD5755_READ_REG_STATUS 0x18 |
37 | #define AD5755_READ_REG_MAIN 0x19 |
38 | #define AD5755_READ_REG_DC_DC 0x1a |
39 | |
40 | #define AD5755_CTRL_REG_SLEW 0x0 |
41 | #define AD5755_CTRL_REG_MAIN 0x1 |
42 | #define AD5755_CTRL_REG_DAC 0x2 |
43 | #define AD5755_CTRL_REG_DC_DC 0x3 |
44 | #define AD5755_CTRL_REG_SW 0x4 |
45 | |
46 | #define AD5755_READ_FLAG 0x800000 |
47 | |
48 | #define AD5755_NOOP 0x1CE000 |
49 | |
50 | #define AD5755_DAC_INT_EN BIT(8) |
51 | #define AD5755_DAC_CLR_EN BIT(7) |
52 | #define AD5755_DAC_OUT_EN BIT(6) |
53 | #define AD5755_DAC_INT_CURRENT_SENSE_RESISTOR BIT(5) |
54 | #define AD5755_DAC_DC_DC_EN BIT(4) |
55 | #define AD5755_DAC_VOLTAGE_OVERRANGE_EN BIT(3) |
56 | |
57 | #define AD5755_DC_DC_MAXV 0 |
58 | #define AD5755_DC_DC_FREQ_SHIFT 2 |
59 | #define AD5755_DC_DC_PHASE_SHIFT 4 |
60 | #define AD5755_EXT_DC_DC_COMP_RES BIT(6) |
61 | |
62 | #define AD5755_SLEW_STEP_SIZE_SHIFT 0 |
63 | #define AD5755_SLEW_RATE_SHIFT 3 |
64 | #define AD5755_SLEW_ENABLE BIT(12) |
65 | |
66 | enum ad5755_mode { |
67 | AD5755_MODE_VOLTAGE_0V_5V = 0, |
68 | AD5755_MODE_VOLTAGE_0V_10V = 1, |
69 | AD5755_MODE_VOLTAGE_PLUSMINUS_5V = 2, |
70 | AD5755_MODE_VOLTAGE_PLUSMINUS_10V = 3, |
71 | AD5755_MODE_CURRENT_4mA_20mA = 4, |
72 | AD5755_MODE_CURRENT_0mA_20mA = 5, |
73 | AD5755_MODE_CURRENT_0mA_24mA = 6, |
74 | }; |
75 | |
76 | enum ad5755_dc_dc_phase { |
77 | AD5755_DC_DC_PHASE_ALL_SAME_EDGE = 0, |
78 | AD5755_DC_DC_PHASE_A_B_SAME_EDGE_C_D_OPP_EDGE = 1, |
79 | AD5755_DC_DC_PHASE_A_C_SAME_EDGE_B_D_OPP_EDGE = 2, |
80 | AD5755_DC_DC_PHASE_90_DEGREE = 3, |
81 | }; |
82 | |
83 | enum ad5755_dc_dc_freq { |
84 | AD5755_DC_DC_FREQ_250kHZ = 0, |
85 | AD5755_DC_DC_FREQ_410kHZ = 1, |
86 | AD5755_DC_DC_FREQ_650kHZ = 2, |
87 | }; |
88 | |
89 | enum ad5755_dc_dc_maxv { |
90 | AD5755_DC_DC_MAXV_23V = 0, |
91 | AD5755_DC_DC_MAXV_24V5 = 1, |
92 | AD5755_DC_DC_MAXV_27V = 2, |
93 | AD5755_DC_DC_MAXV_29V5 = 3, |
94 | }; |
95 | |
96 | enum ad5755_slew_rate { |
97 | AD5755_SLEW_RATE_64k = 0, |
98 | AD5755_SLEW_RATE_32k = 1, |
99 | AD5755_SLEW_RATE_16k = 2, |
100 | AD5755_SLEW_RATE_8k = 3, |
101 | AD5755_SLEW_RATE_4k = 4, |
102 | AD5755_SLEW_RATE_2k = 5, |
103 | AD5755_SLEW_RATE_1k = 6, |
104 | AD5755_SLEW_RATE_500 = 7, |
105 | AD5755_SLEW_RATE_250 = 8, |
106 | AD5755_SLEW_RATE_125 = 9, |
107 | AD5755_SLEW_RATE_64 = 10, |
108 | AD5755_SLEW_RATE_32 = 11, |
109 | AD5755_SLEW_RATE_16 = 12, |
110 | AD5755_SLEW_RATE_8 = 13, |
111 | AD5755_SLEW_RATE_4 = 14, |
112 | AD5755_SLEW_RATE_0_5 = 15, |
113 | }; |
114 | |
115 | enum ad5755_slew_step_size { |
116 | AD5755_SLEW_STEP_SIZE_1 = 0, |
117 | AD5755_SLEW_STEP_SIZE_2 = 1, |
118 | AD5755_SLEW_STEP_SIZE_4 = 2, |
119 | AD5755_SLEW_STEP_SIZE_8 = 3, |
120 | AD5755_SLEW_STEP_SIZE_16 = 4, |
121 | AD5755_SLEW_STEP_SIZE_32 = 5, |
122 | AD5755_SLEW_STEP_SIZE_64 = 6, |
123 | AD5755_SLEW_STEP_SIZE_128 = 7, |
124 | AD5755_SLEW_STEP_SIZE_256 = 8, |
125 | }; |
126 | |
127 | /** |
128 | * struct ad5755_platform_data - AD5755 DAC driver platform data |
129 | * @ext_dc_dc_compenstation_resistor: Whether an external DC-DC converter |
130 | * compensation register is used. |
131 | * @dc_dc_phase: DC-DC converter phase. |
132 | * @dc_dc_freq: DC-DC converter frequency. |
133 | * @dc_dc_maxv: DC-DC maximum allowed boost voltage. |
134 | * @dac: Per DAC instance parameters. |
135 | * @dac.mode: The mode to be used for the DAC output. |
136 | * @dac.ext_current_sense_resistor: Whether an external current sense resistor |
137 | * is used. |
138 | * @dac.enable_voltage_overrange: Whether to enable 20% voltage output overrange. |
139 | * @dac.slew.enable: Whether to enable digital slew. |
140 | * @dac.slew.rate: Slew rate of the digital slew. |
141 | * @dac.slew.step_size: Slew step size of the digital slew. |
142 | **/ |
143 | struct ad5755_platform_data { |
144 | bool ext_dc_dc_compenstation_resistor; |
145 | enum ad5755_dc_dc_phase dc_dc_phase; |
146 | enum ad5755_dc_dc_freq dc_dc_freq; |
147 | enum ad5755_dc_dc_maxv dc_dc_maxv; |
148 | |
149 | struct { |
150 | enum ad5755_mode mode; |
151 | bool ext_current_sense_resistor; |
152 | bool enable_voltage_overrange; |
153 | struct { |
154 | bool enable; |
155 | enum ad5755_slew_rate rate; |
156 | enum ad5755_slew_step_size step_size; |
157 | } slew; |
158 | } dac[4]; |
159 | }; |
160 | |
161 | /** |
162 | * struct ad5755_chip_info - chip specific information |
163 | * @channel_template: channel specification |
164 | * @calib_shift: shift for the calibration data registers |
165 | * @has_voltage_out: whether the chip has voltage outputs |
166 | */ |
167 | struct ad5755_chip_info { |
168 | const struct iio_chan_spec channel_template; |
169 | unsigned int calib_shift; |
170 | bool has_voltage_out; |
171 | }; |
172 | |
173 | /** |
174 | * struct ad5755_state - driver instance specific data |
175 | * @spi: spi device the driver is attached to |
176 | * @chip_info: chip model specific constants, available modes etc |
177 | * @pwr_down: bitmask which contains hether a channel is powered down or not |
178 | * @ctrl: software shadow of the channel ctrl registers |
179 | * @channels: iio channel spec for the device |
180 | * @lock: lock to protect the data buffer during SPI ops |
181 | * @data: spi transfer buffers |
182 | */ |
183 | struct ad5755_state { |
184 | struct spi_device *spi; |
185 | const struct ad5755_chip_info *chip_info; |
186 | unsigned int pwr_down; |
187 | unsigned int ctrl[AD5755_NUM_CHANNELS]; |
188 | struct iio_chan_spec channels[AD5755_NUM_CHANNELS]; |
189 | struct mutex lock; |
190 | |
191 | /* |
192 | * DMA (thus cache coherency maintenance) may require the |
193 | * transfer buffers to live in their own cache lines. |
194 | */ |
195 | |
196 | union { |
197 | __be32 d32; |
198 | u8 d8[4]; |
199 | } data[2] __aligned(IIO_DMA_MINALIGN); |
200 | }; |
201 | |
202 | enum ad5755_type { |
203 | ID_AD5755, |
204 | ID_AD5757, |
205 | ID_AD5735, |
206 | ID_AD5737, |
207 | }; |
208 | |
209 | static const int ad5755_dcdc_freq_table[][2] = { |
210 | { 250000, AD5755_DC_DC_FREQ_250kHZ }, |
211 | { 410000, AD5755_DC_DC_FREQ_410kHZ }, |
212 | { 650000, AD5755_DC_DC_FREQ_650kHZ } |
213 | }; |
214 | |
215 | static const int ad5755_dcdc_maxv_table[][2] = { |
216 | { 23000000, AD5755_DC_DC_MAXV_23V }, |
217 | { 24500000, AD5755_DC_DC_MAXV_24V5 }, |
218 | { 27000000, AD5755_DC_DC_MAXV_27V }, |
219 | { 29500000, AD5755_DC_DC_MAXV_29V5 }, |
220 | }; |
221 | |
222 | static const int ad5755_slew_rate_table[][2] = { |
223 | { 64000, AD5755_SLEW_RATE_64k }, |
224 | { 32000, AD5755_SLEW_RATE_32k }, |
225 | { 16000, AD5755_SLEW_RATE_16k }, |
226 | { 8000, AD5755_SLEW_RATE_8k }, |
227 | { 4000, AD5755_SLEW_RATE_4k }, |
228 | { 2000, AD5755_SLEW_RATE_2k }, |
229 | { 1000, AD5755_SLEW_RATE_1k }, |
230 | { 500, AD5755_SLEW_RATE_500 }, |
231 | { 250, AD5755_SLEW_RATE_250 }, |
232 | { 125, AD5755_SLEW_RATE_125 }, |
233 | { 64, AD5755_SLEW_RATE_64 }, |
234 | { 32, AD5755_SLEW_RATE_32 }, |
235 | { 16, AD5755_SLEW_RATE_16 }, |
236 | { 8, AD5755_SLEW_RATE_8 }, |
237 | { 4, AD5755_SLEW_RATE_4 }, |
238 | { 0, AD5755_SLEW_RATE_0_5 }, |
239 | }; |
240 | |
241 | static const int ad5755_slew_step_table[][2] = { |
242 | { 256, AD5755_SLEW_STEP_SIZE_256 }, |
243 | { 128, AD5755_SLEW_STEP_SIZE_128 }, |
244 | { 64, AD5755_SLEW_STEP_SIZE_64 }, |
245 | { 32, AD5755_SLEW_STEP_SIZE_32 }, |
246 | { 16, AD5755_SLEW_STEP_SIZE_16 }, |
247 | { 4, AD5755_SLEW_STEP_SIZE_4 }, |
248 | { 2, AD5755_SLEW_STEP_SIZE_2 }, |
249 | { 1, AD5755_SLEW_STEP_SIZE_1 }, |
250 | }; |
251 | |
252 | static int ad5755_write_unlocked(struct iio_dev *indio_dev, |
253 | unsigned int reg, unsigned int val) |
254 | { |
255 | struct ad5755_state *st = iio_priv(indio_dev); |
256 | |
257 | st->data[0].d32 = cpu_to_be32((reg << 16) | val); |
258 | |
259 | return spi_write(spi: st->spi, buf: &st->data[0].d8[1], len: 3); |
260 | } |
261 | |
262 | static int ad5755_write_ctrl_unlocked(struct iio_dev *indio_dev, |
263 | unsigned int channel, unsigned int reg, unsigned int val) |
264 | { |
265 | return ad5755_write_unlocked(indio_dev, |
266 | AD5755_WRITE_REG_CTRL(channel), val: (reg << 13) | val); |
267 | } |
268 | |
269 | static int ad5755_write(struct iio_dev *indio_dev, unsigned int reg, |
270 | unsigned int val) |
271 | { |
272 | struct ad5755_state *st = iio_priv(indio_dev); |
273 | int ret; |
274 | |
275 | mutex_lock(&st->lock); |
276 | ret = ad5755_write_unlocked(indio_dev, reg, val); |
277 | mutex_unlock(lock: &st->lock); |
278 | |
279 | return ret; |
280 | } |
281 | |
282 | static int ad5755_write_ctrl(struct iio_dev *indio_dev, unsigned int channel, |
283 | unsigned int reg, unsigned int val) |
284 | { |
285 | struct ad5755_state *st = iio_priv(indio_dev); |
286 | int ret; |
287 | |
288 | mutex_lock(&st->lock); |
289 | ret = ad5755_write_ctrl_unlocked(indio_dev, channel, reg, val); |
290 | mutex_unlock(lock: &st->lock); |
291 | |
292 | return ret; |
293 | } |
294 | |
295 | static int ad5755_read(struct iio_dev *indio_dev, unsigned int addr) |
296 | { |
297 | struct ad5755_state *st = iio_priv(indio_dev); |
298 | int ret; |
299 | struct spi_transfer t[] = { |
300 | { |
301 | .tx_buf = &st->data[0].d8[1], |
302 | .len = 3, |
303 | .cs_change = 1, |
304 | }, { |
305 | .tx_buf = &st->data[1].d8[1], |
306 | .rx_buf = &st->data[1].d8[1], |
307 | .len = 3, |
308 | }, |
309 | }; |
310 | |
311 | mutex_lock(&st->lock); |
312 | |
313 | st->data[0].d32 = cpu_to_be32(AD5755_READ_FLAG | (addr << 16)); |
314 | st->data[1].d32 = cpu_to_be32(AD5755_NOOP); |
315 | |
316 | ret = spi_sync_transfer(spi: st->spi, xfers: t, ARRAY_SIZE(t)); |
317 | if (ret >= 0) |
318 | ret = be32_to_cpu(st->data[1].d32) & 0xffff; |
319 | |
320 | mutex_unlock(lock: &st->lock); |
321 | |
322 | return ret; |
323 | } |
324 | |
325 | static int ad5755_update_dac_ctrl(struct iio_dev *indio_dev, |
326 | unsigned int channel, unsigned int set, unsigned int clr) |
327 | { |
328 | struct ad5755_state *st = iio_priv(indio_dev); |
329 | int ret; |
330 | |
331 | st->ctrl[channel] |= set; |
332 | st->ctrl[channel] &= ~clr; |
333 | |
334 | ret = ad5755_write_ctrl_unlocked(indio_dev, channel, |
335 | AD5755_CTRL_REG_DAC, val: st->ctrl[channel]); |
336 | |
337 | return ret; |
338 | } |
339 | |
340 | static int ad5755_set_channel_pwr_down(struct iio_dev *indio_dev, |
341 | unsigned int channel, bool pwr_down) |
342 | { |
343 | struct ad5755_state *st = iio_priv(indio_dev); |
344 | unsigned int mask = BIT(channel); |
345 | |
346 | mutex_lock(&st->lock); |
347 | |
348 | if ((bool)(st->pwr_down & mask) == pwr_down) |
349 | goto out_unlock; |
350 | |
351 | if (!pwr_down) { |
352 | st->pwr_down &= ~mask; |
353 | ad5755_update_dac_ctrl(indio_dev, channel, |
354 | AD5755_DAC_INT_EN | AD5755_DAC_DC_DC_EN, clr: 0); |
355 | udelay(200); |
356 | ad5755_update_dac_ctrl(indio_dev, channel, |
357 | AD5755_DAC_OUT_EN, clr: 0); |
358 | } else { |
359 | st->pwr_down |= mask; |
360 | ad5755_update_dac_ctrl(indio_dev, channel, |
361 | set: 0, AD5755_DAC_INT_EN | AD5755_DAC_OUT_EN | |
362 | AD5755_DAC_DC_DC_EN); |
363 | } |
364 | |
365 | out_unlock: |
366 | mutex_unlock(lock: &st->lock); |
367 | |
368 | return 0; |
369 | } |
370 | |
371 | static const int ad5755_min_max_table[][2] = { |
372 | [AD5755_MODE_VOLTAGE_0V_5V] = { 0, 5000 }, |
373 | [AD5755_MODE_VOLTAGE_0V_10V] = { 0, 10000 }, |
374 | [AD5755_MODE_VOLTAGE_PLUSMINUS_5V] = { -5000, 5000 }, |
375 | [AD5755_MODE_VOLTAGE_PLUSMINUS_10V] = { -10000, 10000 }, |
376 | [AD5755_MODE_CURRENT_4mA_20mA] = { 4, 20 }, |
377 | [AD5755_MODE_CURRENT_0mA_20mA] = { 0, 20 }, |
378 | [AD5755_MODE_CURRENT_0mA_24mA] = { 0, 24 }, |
379 | }; |
380 | |
381 | static void ad5755_get_min_max(struct ad5755_state *st, |
382 | struct iio_chan_spec const *chan, int *min, int *max) |
383 | { |
384 | enum ad5755_mode mode = st->ctrl[chan->channel] & 7; |
385 | *min = ad5755_min_max_table[mode][0]; |
386 | *max = ad5755_min_max_table[mode][1]; |
387 | } |
388 | |
389 | static inline int ad5755_get_offset(struct ad5755_state *st, |
390 | struct iio_chan_spec const *chan) |
391 | { |
392 | int min, max; |
393 | |
394 | ad5755_get_min_max(st, chan, min: &min, max: &max); |
395 | return (min * (1 << chan->scan_type.realbits)) / (max - min); |
396 | } |
397 | |
398 | static int ad5755_chan_reg_info(struct ad5755_state *st, |
399 | struct iio_chan_spec const *chan, long info, bool write, |
400 | unsigned int *reg, unsigned int *shift, unsigned int *offset) |
401 | { |
402 | switch (info) { |
403 | case IIO_CHAN_INFO_RAW: |
404 | if (write) |
405 | *reg = AD5755_WRITE_REG_DATA(chan->address); |
406 | else |
407 | *reg = AD5755_READ_REG_DATA(chan->address); |
408 | *shift = chan->scan_type.shift; |
409 | *offset = 0; |
410 | break; |
411 | case IIO_CHAN_INFO_CALIBBIAS: |
412 | if (write) |
413 | *reg = AD5755_WRITE_REG_OFFSET(chan->address); |
414 | else |
415 | *reg = AD5755_READ_REG_OFFSET(chan->address); |
416 | *shift = st->chip_info->calib_shift; |
417 | *offset = 32768; |
418 | break; |
419 | case IIO_CHAN_INFO_CALIBSCALE: |
420 | if (write) |
421 | *reg = AD5755_WRITE_REG_GAIN(chan->address); |
422 | else |
423 | *reg = AD5755_READ_REG_GAIN(chan->address); |
424 | *shift = st->chip_info->calib_shift; |
425 | *offset = 0; |
426 | break; |
427 | default: |
428 | return -EINVAL; |
429 | } |
430 | |
431 | return 0; |
432 | } |
433 | |
434 | static int ad5755_read_raw(struct iio_dev *indio_dev, |
435 | const struct iio_chan_spec *chan, int *val, int *val2, long info) |
436 | { |
437 | struct ad5755_state *st = iio_priv(indio_dev); |
438 | unsigned int reg, shift, offset; |
439 | int min, max; |
440 | int ret; |
441 | |
442 | switch (info) { |
443 | case IIO_CHAN_INFO_SCALE: |
444 | ad5755_get_min_max(st, chan, min: &min, max: &max); |
445 | *val = max - min; |
446 | *val2 = chan->scan_type.realbits; |
447 | return IIO_VAL_FRACTIONAL_LOG2; |
448 | case IIO_CHAN_INFO_OFFSET: |
449 | *val = ad5755_get_offset(st, chan); |
450 | return IIO_VAL_INT; |
451 | default: |
452 | ret = ad5755_chan_reg_info(st, chan, info, write: false, |
453 | reg: ®, shift: &shift, offset: &offset); |
454 | if (ret) |
455 | return ret; |
456 | |
457 | ret = ad5755_read(indio_dev, addr: reg); |
458 | if (ret < 0) |
459 | return ret; |
460 | |
461 | *val = (ret - offset) >> shift; |
462 | |
463 | return IIO_VAL_INT; |
464 | } |
465 | |
466 | return -EINVAL; |
467 | } |
468 | |
469 | static int ad5755_write_raw(struct iio_dev *indio_dev, |
470 | const struct iio_chan_spec *chan, int val, int val2, long info) |
471 | { |
472 | struct ad5755_state *st = iio_priv(indio_dev); |
473 | unsigned int shift, reg, offset; |
474 | int ret; |
475 | |
476 | ret = ad5755_chan_reg_info(st, chan, info, write: true, |
477 | reg: ®, shift: &shift, offset: &offset); |
478 | if (ret) |
479 | return ret; |
480 | |
481 | val <<= shift; |
482 | val += offset; |
483 | |
484 | if (val < 0 || val > 0xffff) |
485 | return -EINVAL; |
486 | |
487 | return ad5755_write(indio_dev, reg, val); |
488 | } |
489 | |
490 | static ssize_t ad5755_read_powerdown(struct iio_dev *indio_dev, uintptr_t priv, |
491 | const struct iio_chan_spec *chan, char *buf) |
492 | { |
493 | struct ad5755_state *st = iio_priv(indio_dev); |
494 | |
495 | return sysfs_emit(buf, fmt: "%d\n" , |
496 | (bool)(st->pwr_down & (1 << chan->channel))); |
497 | } |
498 | |
499 | static ssize_t ad5755_write_powerdown(struct iio_dev *indio_dev, uintptr_t priv, |
500 | struct iio_chan_spec const *chan, const char *buf, size_t len) |
501 | { |
502 | bool pwr_down; |
503 | int ret; |
504 | |
505 | ret = kstrtobool(s: buf, res: &pwr_down); |
506 | if (ret) |
507 | return ret; |
508 | |
509 | ret = ad5755_set_channel_pwr_down(indio_dev, channel: chan->channel, pwr_down); |
510 | return ret ? ret : len; |
511 | } |
512 | |
513 | static const struct iio_info ad5755_info = { |
514 | .read_raw = ad5755_read_raw, |
515 | .write_raw = ad5755_write_raw, |
516 | }; |
517 | |
518 | static const struct iio_chan_spec_ext_info ad5755_ext_info[] = { |
519 | { |
520 | .name = "powerdown" , |
521 | .read = ad5755_read_powerdown, |
522 | .write = ad5755_write_powerdown, |
523 | .shared = IIO_SEPARATE, |
524 | }, |
525 | { }, |
526 | }; |
527 | |
528 | #define AD5755_CHANNEL(_bits) { \ |
529 | .indexed = 1, \ |
530 | .output = 1, \ |
531 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
532 | BIT(IIO_CHAN_INFO_SCALE) | \ |
533 | BIT(IIO_CHAN_INFO_OFFSET) | \ |
534 | BIT(IIO_CHAN_INFO_CALIBSCALE) | \ |
535 | BIT(IIO_CHAN_INFO_CALIBBIAS), \ |
536 | .scan_type = { \ |
537 | .sign = 'u', \ |
538 | .realbits = (_bits), \ |
539 | .storagebits = 16, \ |
540 | .shift = 16 - (_bits), \ |
541 | }, \ |
542 | .ext_info = ad5755_ext_info, \ |
543 | } |
544 | |
545 | static const struct ad5755_chip_info ad5755_chip_info_tbl[] = { |
546 | [ID_AD5735] = { |
547 | .channel_template = AD5755_CHANNEL(14), |
548 | .has_voltage_out = true, |
549 | .calib_shift = 4, |
550 | }, |
551 | [ID_AD5737] = { |
552 | .channel_template = AD5755_CHANNEL(14), |
553 | .has_voltage_out = false, |
554 | .calib_shift = 4, |
555 | }, |
556 | [ID_AD5755] = { |
557 | .channel_template = AD5755_CHANNEL(16), |
558 | .has_voltage_out = true, |
559 | .calib_shift = 0, |
560 | }, |
561 | [ID_AD5757] = { |
562 | .channel_template = AD5755_CHANNEL(16), |
563 | .has_voltage_out = false, |
564 | .calib_shift = 0, |
565 | }, |
566 | }; |
567 | |
568 | static bool ad5755_is_valid_mode(struct ad5755_state *st, enum ad5755_mode mode) |
569 | { |
570 | switch (mode) { |
571 | case AD5755_MODE_VOLTAGE_0V_5V: |
572 | case AD5755_MODE_VOLTAGE_0V_10V: |
573 | case AD5755_MODE_VOLTAGE_PLUSMINUS_5V: |
574 | case AD5755_MODE_VOLTAGE_PLUSMINUS_10V: |
575 | return st->chip_info->has_voltage_out; |
576 | case AD5755_MODE_CURRENT_4mA_20mA: |
577 | case AD5755_MODE_CURRENT_0mA_20mA: |
578 | case AD5755_MODE_CURRENT_0mA_24mA: |
579 | return true; |
580 | default: |
581 | return false; |
582 | } |
583 | } |
584 | |
585 | static int ad5755_setup_pdata(struct iio_dev *indio_dev, |
586 | const struct ad5755_platform_data *pdata) |
587 | { |
588 | struct ad5755_state *st = iio_priv(indio_dev); |
589 | unsigned int val; |
590 | unsigned int i; |
591 | int ret; |
592 | |
593 | if (pdata->dc_dc_phase > AD5755_DC_DC_PHASE_90_DEGREE || |
594 | pdata->dc_dc_freq > AD5755_DC_DC_FREQ_650kHZ || |
595 | pdata->dc_dc_maxv > AD5755_DC_DC_MAXV_29V5) |
596 | return -EINVAL; |
597 | |
598 | val = pdata->dc_dc_maxv << AD5755_DC_DC_MAXV; |
599 | val |= pdata->dc_dc_freq << AD5755_DC_DC_FREQ_SHIFT; |
600 | val |= pdata->dc_dc_phase << AD5755_DC_DC_PHASE_SHIFT; |
601 | if (pdata->ext_dc_dc_compenstation_resistor) |
602 | val |= AD5755_EXT_DC_DC_COMP_RES; |
603 | |
604 | ret = ad5755_write_ctrl(indio_dev, channel: 0, AD5755_CTRL_REG_DC_DC, val); |
605 | if (ret < 0) |
606 | return ret; |
607 | |
608 | for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) { |
609 | val = pdata->dac[i].slew.step_size << |
610 | AD5755_SLEW_STEP_SIZE_SHIFT; |
611 | val |= pdata->dac[i].slew.rate << |
612 | AD5755_SLEW_RATE_SHIFT; |
613 | if (pdata->dac[i].slew.enable) |
614 | val |= AD5755_SLEW_ENABLE; |
615 | |
616 | ret = ad5755_write_ctrl(indio_dev, channel: i, |
617 | AD5755_CTRL_REG_SLEW, val); |
618 | if (ret < 0) |
619 | return ret; |
620 | } |
621 | |
622 | for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) { |
623 | if (!ad5755_is_valid_mode(st, mode: pdata->dac[i].mode)) |
624 | return -EINVAL; |
625 | |
626 | val = 0; |
627 | if (!pdata->dac[i].ext_current_sense_resistor) |
628 | val |= AD5755_DAC_INT_CURRENT_SENSE_RESISTOR; |
629 | if (pdata->dac[i].enable_voltage_overrange) |
630 | val |= AD5755_DAC_VOLTAGE_OVERRANGE_EN; |
631 | val |= pdata->dac[i].mode; |
632 | |
633 | ret = ad5755_update_dac_ctrl(indio_dev, channel: i, set: val, clr: 0); |
634 | if (ret < 0) |
635 | return ret; |
636 | } |
637 | |
638 | return 0; |
639 | } |
640 | |
641 | static bool ad5755_is_voltage_mode(enum ad5755_mode mode) |
642 | { |
643 | switch (mode) { |
644 | case AD5755_MODE_VOLTAGE_0V_5V: |
645 | case AD5755_MODE_VOLTAGE_0V_10V: |
646 | case AD5755_MODE_VOLTAGE_PLUSMINUS_5V: |
647 | case AD5755_MODE_VOLTAGE_PLUSMINUS_10V: |
648 | return true; |
649 | default: |
650 | return false; |
651 | } |
652 | } |
653 | |
654 | static int ad5755_init_channels(struct iio_dev *indio_dev, |
655 | const struct ad5755_platform_data *pdata) |
656 | { |
657 | struct ad5755_state *st = iio_priv(indio_dev); |
658 | struct iio_chan_spec *channels = st->channels; |
659 | unsigned int i; |
660 | |
661 | for (i = 0; i < AD5755_NUM_CHANNELS; ++i) { |
662 | channels[i] = st->chip_info->channel_template; |
663 | channels[i].channel = i; |
664 | channels[i].address = i; |
665 | if (pdata && ad5755_is_voltage_mode(mode: pdata->dac[i].mode)) |
666 | channels[i].type = IIO_VOLTAGE; |
667 | else |
668 | channels[i].type = IIO_CURRENT; |
669 | } |
670 | |
671 | indio_dev->channels = channels; |
672 | |
673 | return 0; |
674 | } |
675 | |
676 | #define AD5755_DEFAULT_DAC_PDATA { \ |
677 | .mode = AD5755_MODE_CURRENT_4mA_20mA, \ |
678 | .ext_current_sense_resistor = true, \ |
679 | .enable_voltage_overrange = false, \ |
680 | .slew = { \ |
681 | .enable = false, \ |
682 | .rate = AD5755_SLEW_RATE_64k, \ |
683 | .step_size = AD5755_SLEW_STEP_SIZE_1, \ |
684 | }, \ |
685 | } |
686 | |
687 | static const struct ad5755_platform_data ad5755_default_pdata = { |
688 | .ext_dc_dc_compenstation_resistor = false, |
689 | .dc_dc_phase = AD5755_DC_DC_PHASE_ALL_SAME_EDGE, |
690 | .dc_dc_freq = AD5755_DC_DC_FREQ_410kHZ, |
691 | .dc_dc_maxv = AD5755_DC_DC_MAXV_23V, |
692 | .dac = { |
693 | [0] = AD5755_DEFAULT_DAC_PDATA, |
694 | [1] = AD5755_DEFAULT_DAC_PDATA, |
695 | [2] = AD5755_DEFAULT_DAC_PDATA, |
696 | [3] = AD5755_DEFAULT_DAC_PDATA, |
697 | }, |
698 | }; |
699 | |
700 | static struct ad5755_platform_data *ad5755_parse_fw(struct device *dev) |
701 | { |
702 | struct fwnode_handle *pp; |
703 | struct ad5755_platform_data *pdata; |
704 | unsigned int tmp; |
705 | unsigned int tmparray[3]; |
706 | int devnr, i; |
707 | |
708 | if (!dev_fwnode(dev)) |
709 | return NULL; |
710 | |
711 | pdata = devm_kzalloc(dev, size: sizeof(*pdata), GFP_KERNEL); |
712 | if (!pdata) |
713 | return NULL; |
714 | |
715 | pdata->ext_dc_dc_compenstation_resistor = |
716 | device_property_read_bool(dev, propname: "adi,ext-dc-dc-compenstation-resistor" ); |
717 | |
718 | pdata->dc_dc_phase = AD5755_DC_DC_PHASE_ALL_SAME_EDGE; |
719 | device_property_read_u32(dev, propname: "adi,dc-dc-phase" , val: &pdata->dc_dc_phase); |
720 | |
721 | pdata->dc_dc_freq = AD5755_DC_DC_FREQ_410kHZ; |
722 | if (!device_property_read_u32(dev, propname: "adi,dc-dc-freq-hz" , val: &tmp)) { |
723 | for (i = 0; i < ARRAY_SIZE(ad5755_dcdc_freq_table); i++) { |
724 | if (tmp == ad5755_dcdc_freq_table[i][0]) { |
725 | pdata->dc_dc_freq = ad5755_dcdc_freq_table[i][1]; |
726 | break; |
727 | } |
728 | } |
729 | |
730 | if (i == ARRAY_SIZE(ad5755_dcdc_freq_table)) |
731 | dev_err(dev, |
732 | "adi,dc-dc-freq out of range selecting 410kHz\n" ); |
733 | } |
734 | |
735 | pdata->dc_dc_maxv = AD5755_DC_DC_MAXV_23V; |
736 | if (!device_property_read_u32(dev, propname: "adi,dc-dc-max-microvolt" , val: &tmp)) { |
737 | for (i = 0; i < ARRAY_SIZE(ad5755_dcdc_maxv_table); i++) { |
738 | if (tmp == ad5755_dcdc_maxv_table[i][0]) { |
739 | pdata->dc_dc_maxv = ad5755_dcdc_maxv_table[i][1]; |
740 | break; |
741 | } |
742 | } |
743 | if (i == ARRAY_SIZE(ad5755_dcdc_maxv_table)) |
744 | dev_err(dev, |
745 | "adi,dc-dc-maxv out of range selecting 23V\n" ); |
746 | } |
747 | |
748 | devnr = 0; |
749 | device_for_each_child_node(dev, pp) { |
750 | if (devnr >= AD5755_NUM_CHANNELS) { |
751 | dev_err(dev, |
752 | "There are too many channels defined in DT\n" ); |
753 | goto error_out; |
754 | } |
755 | |
756 | pdata->dac[devnr].mode = AD5755_MODE_CURRENT_4mA_20mA; |
757 | fwnode_property_read_u32(fwnode: pp, propname: "adi,mode" , val: &pdata->dac[devnr].mode); |
758 | |
759 | pdata->dac[devnr].ext_current_sense_resistor = |
760 | fwnode_property_read_bool(fwnode: pp, propname: "adi,ext-current-sense-resistor" ); |
761 | |
762 | pdata->dac[devnr].enable_voltage_overrange = |
763 | fwnode_property_read_bool(fwnode: pp, propname: "adi,enable-voltage-overrange" ); |
764 | |
765 | if (!fwnode_property_read_u32_array(fwnode: pp, propname: "adi,slew" , val: tmparray, nval: 3)) { |
766 | pdata->dac[devnr].slew.enable = tmparray[0]; |
767 | |
768 | pdata->dac[devnr].slew.rate = AD5755_SLEW_RATE_64k; |
769 | for (i = 0; i < ARRAY_SIZE(ad5755_slew_rate_table); i++) { |
770 | if (tmparray[1] == ad5755_slew_rate_table[i][0]) { |
771 | pdata->dac[devnr].slew.rate = |
772 | ad5755_slew_rate_table[i][1]; |
773 | break; |
774 | } |
775 | } |
776 | if (i == ARRAY_SIZE(ad5755_slew_rate_table)) |
777 | dev_err(dev, |
778 | "channel %d slew rate out of range selecting 64kHz\n" , |
779 | devnr); |
780 | |
781 | pdata->dac[devnr].slew.step_size = AD5755_SLEW_STEP_SIZE_1; |
782 | for (i = 0; i < ARRAY_SIZE(ad5755_slew_step_table); i++) { |
783 | if (tmparray[2] == ad5755_slew_step_table[i][0]) { |
784 | pdata->dac[devnr].slew.step_size = |
785 | ad5755_slew_step_table[i][1]; |
786 | break; |
787 | } |
788 | } |
789 | if (i == ARRAY_SIZE(ad5755_slew_step_table)) |
790 | dev_err(dev, |
791 | "channel %d slew step size out of range selecting 1 LSB\n" , |
792 | devnr); |
793 | } else { |
794 | pdata->dac[devnr].slew.enable = false; |
795 | pdata->dac[devnr].slew.rate = AD5755_SLEW_RATE_64k; |
796 | pdata->dac[devnr].slew.step_size = |
797 | AD5755_SLEW_STEP_SIZE_1; |
798 | } |
799 | devnr++; |
800 | } |
801 | |
802 | return pdata; |
803 | |
804 | error_out: |
805 | fwnode_handle_put(fwnode: pp); |
806 | devm_kfree(dev, p: pdata); |
807 | return NULL; |
808 | } |
809 | |
810 | static int ad5755_probe(struct spi_device *spi) |
811 | { |
812 | enum ad5755_type type = spi_get_device_id(sdev: spi)->driver_data; |
813 | const struct ad5755_platform_data *pdata; |
814 | struct iio_dev *indio_dev; |
815 | struct ad5755_state *st; |
816 | int ret; |
817 | |
818 | indio_dev = devm_iio_device_alloc(parent: &spi->dev, sizeof_priv: sizeof(*st)); |
819 | if (indio_dev == NULL) { |
820 | dev_err(&spi->dev, "Failed to allocate iio device\n" ); |
821 | return -ENOMEM; |
822 | } |
823 | |
824 | st = iio_priv(indio_dev); |
825 | spi_set_drvdata(spi, data: indio_dev); |
826 | |
827 | st->chip_info = &ad5755_chip_info_tbl[type]; |
828 | st->spi = spi; |
829 | st->pwr_down = 0xf; |
830 | |
831 | indio_dev->name = spi_get_device_id(sdev: spi)->name; |
832 | indio_dev->info = &ad5755_info; |
833 | indio_dev->modes = INDIO_DIRECT_MODE; |
834 | indio_dev->num_channels = AD5755_NUM_CHANNELS; |
835 | |
836 | mutex_init(&st->lock); |
837 | |
838 | |
839 | pdata = ad5755_parse_fw(dev: &spi->dev); |
840 | if (!pdata) { |
841 | dev_warn(&spi->dev, "no firmware provided parameters? using default\n" ); |
842 | pdata = &ad5755_default_pdata; |
843 | } |
844 | |
845 | ret = ad5755_init_channels(indio_dev, pdata); |
846 | if (ret) |
847 | return ret; |
848 | |
849 | ret = ad5755_setup_pdata(indio_dev, pdata); |
850 | if (ret) |
851 | return ret; |
852 | |
853 | return devm_iio_device_register(&spi->dev, indio_dev); |
854 | } |
855 | |
856 | static const struct spi_device_id ad5755_id[] = { |
857 | { "ad5755" , ID_AD5755 }, |
858 | { "ad5755-1" , ID_AD5755 }, |
859 | { "ad5757" , ID_AD5757 }, |
860 | { "ad5735" , ID_AD5735 }, |
861 | { "ad5737" , ID_AD5737 }, |
862 | {} |
863 | }; |
864 | MODULE_DEVICE_TABLE(spi, ad5755_id); |
865 | |
866 | static const struct of_device_id ad5755_of_match[] = { |
867 | { .compatible = "adi,ad5755" }, |
868 | { .compatible = "adi,ad5755-1" }, |
869 | { .compatible = "adi,ad5757" }, |
870 | { .compatible = "adi,ad5735" }, |
871 | { .compatible = "adi,ad5737" }, |
872 | { } |
873 | }; |
874 | MODULE_DEVICE_TABLE(of, ad5755_of_match); |
875 | |
876 | static struct spi_driver ad5755_driver = { |
877 | .driver = { |
878 | .name = "ad5755" , |
879 | }, |
880 | .probe = ad5755_probe, |
881 | .id_table = ad5755_id, |
882 | }; |
883 | module_spi_driver(ad5755_driver); |
884 | |
885 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>" ); |
886 | MODULE_DESCRIPTION("Analog Devices AD5755/55-1/57/35/37 DAC" ); |
887 | MODULE_LICENSE("GPL v2" ); |
888 | |