1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * AD5770R Digital to analog converters driver
4 *
5 * Copyright 2018 Analog Devices Inc.
6 */
7
8 #include <linux/bits.h>
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/gpio/consumer.h>
12 #include <linux/iio/iio.h>
13 #include <linux/iio/sysfs.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/property.h>
17 #include <linux/regmap.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/spi/spi.h>
20
21 #define ADI_SPI_IF_CONFIG_A 0x00
22 #define ADI_SPI_IF_CONFIG_B 0x01
23 #define ADI_SPI_IF_DEVICE_CONFIG 0x02
24 #define ADI_SPI_IF_CHIP_TYPE 0x03
25 #define ADI_SPI_IF_PRODUCT_ID_L 0x04
26 #define ADI_SPI_IF_PRODUCT_ID_H 0x05
27 #define ADI_SPI_IF_CHIP_GRADE 0x06
28 #define ADI_SPI_IF_SCRACTH_PAD 0x0A
29 #define ADI_SPI_IF_SPI_REVISION 0x0B
30 #define ADI_SPI_IF_SPI_VENDOR_L 0x0C
31 #define ADI_SPI_IF_SPI_VENDOR_H 0x0D
32 #define ADI_SPI_IF_SPI_STREAM_MODE 0x0E
33 #define ADI_SPI_IF_CONFIG_C 0x10
34 #define ADI_SPI_IF_STATUS_A 0x11
35
36 /* ADI_SPI_IF_CONFIG_A */
37 #define ADI_SPI_IF_SW_RESET_MSK (BIT(0) | BIT(7))
38 #define ADI_SPI_IF_SW_RESET_SEL(x) ((x) & ADI_SPI_IF_SW_RESET_MSK)
39 #define ADI_SPI_IF_ADDR_ASC_MSK (BIT(2) | BIT(5))
40 #define ADI_SPI_IF_ADDR_ASC_SEL(x) (((x) << 2) & ADI_SPI_IF_ADDR_ASC_MSK)
41
42 /* ADI_SPI_IF_CONFIG_B */
43 #define ADI_SPI_IF_SINGLE_INS_MSK BIT(7)
44 #define ADI_SPI_IF_SINGLE_INS_SEL(x) FIELD_PREP(ADI_SPI_IF_SINGLE_INS_MSK, x)
45 #define ADI_SPI_IF_SHORT_INS_MSK BIT(7)
46 #define ADI_SPI_IF_SHORT_INS_SEL(x) FIELD_PREP(ADI_SPI_IF_SINGLE_INS_MSK, x)
47
48 /* ADI_SPI_IF_CONFIG_C */
49 #define ADI_SPI_IF_STRICT_REG_MSK BIT(5)
50 #define ADI_SPI_IF_STRICT_REG_GET(x) FIELD_GET(ADI_SPI_IF_STRICT_REG_MSK, x)
51
52 /* AD5770R configuration registers */
53 #define AD5770R_CHANNEL_CONFIG 0x14
54 #define AD5770R_OUTPUT_RANGE(ch) (0x15 + (ch))
55 #define AD5770R_FILTER_RESISTOR(ch) (0x1D + (ch))
56 #define AD5770R_REFERENCE 0x1B
57 #define AD5770R_DAC_LSB(ch) (0x26 + 2 * (ch))
58 #define AD5770R_DAC_MSB(ch) (0x27 + 2 * (ch))
59 #define AD5770R_CH_SELECT 0x34
60 #define AD5770R_CH_ENABLE 0x44
61
62 /* AD5770R_CHANNEL_CONFIG */
63 #define AD5770R_CFG_CH0_SINK_EN(x) (((x) & 0x1) << 7)
64 #define AD5770R_CFG_SHUTDOWN_B(x, ch) (((x) & 0x1) << (ch))
65
66 /* AD5770R_OUTPUT_RANGE */
67 #define AD5770R_RANGE_OUTPUT_SCALING(x) (((x) & GENMASK(5, 0)) << 2)
68 #define AD5770R_RANGE_MODE(x) ((x) & GENMASK(1, 0))
69
70 /* AD5770R_REFERENCE */
71 #define AD5770R_REF_RESISTOR_SEL(x) (((x) & 0x1) << 2)
72 #define AD5770R_REF_SEL(x) ((x) & GENMASK(1, 0))
73
74 /* AD5770R_CH_ENABLE */
75 #define AD5770R_CH_SET(x, ch) (((x) & 0x1) << (ch))
76
77 #define AD5770R_MAX_CHANNELS 6
78 #define AD5770R_MAX_CH_MODES 14
79 #define AD5770R_LOW_VREF_mV 1250
80 #define AD5770R_HIGH_VREF_mV 2500
81
82 enum ad5770r_ch0_modes {
83 AD5770R_CH0_0_300 = 0,
84 AD5770R_CH0_NEG_60_0,
85 AD5770R_CH0_NEG_60_300
86 };
87
88 enum ad5770r_ch1_modes {
89 AD5770R_CH1_0_140_LOW_HEAD = 1,
90 AD5770R_CH1_0_140_LOW_NOISE,
91 AD5770R_CH1_0_250
92 };
93
94 enum ad5770r_ch2_5_modes {
95 AD5770R_CH_LOW_RANGE = 0,
96 AD5770R_CH_HIGH_RANGE
97 };
98
99 enum ad5770r_ref_v {
100 AD5770R_EXT_2_5_V = 0,
101 AD5770R_INT_1_25_V_OUT_ON,
102 AD5770R_EXT_1_25_V,
103 AD5770R_INT_1_25_V_OUT_OFF
104 };
105
106 enum ad5770r_output_filter_resistor {
107 AD5770R_FILTER_60_OHM = 0x0,
108 AD5770R_FILTER_5_6_KOHM = 0x5,
109 AD5770R_FILTER_11_2_KOHM,
110 AD5770R_FILTER_22_2_KOHM,
111 AD5770R_FILTER_44_4_KOHM,
112 AD5770R_FILTER_104_KOHM,
113 };
114
115 struct ad5770r_out_range {
116 u8 out_scale;
117 u8 out_range_mode;
118 };
119
120 /**
121 * struct ad5770R_state - driver instance specific data
122 * @spi: spi_device
123 * @regmap: regmap
124 * @vref_reg: fixed regulator for reference configuration
125 * @gpio_reset: gpio descriptor
126 * @output_mode: array contains channels output ranges
127 * @vref: reference value
128 * @ch_pwr_down: powerdown flags
129 * @internal_ref: internal reference flag
130 * @external_res: external 2.5k resistor flag
131 * @transf_buf: cache aligned buffer for spi read/write
132 */
133 struct ad5770r_state {
134 struct spi_device *spi;
135 struct regmap *regmap;
136 struct regulator *vref_reg;
137 struct gpio_desc *gpio_reset;
138 struct ad5770r_out_range output_mode[AD5770R_MAX_CHANNELS];
139 int vref;
140 bool ch_pwr_down[AD5770R_MAX_CHANNELS];
141 bool internal_ref;
142 bool external_res;
143 u8 transf_buf[2] ____cacheline_aligned;
144 };
145
146 static const struct regmap_config ad5770r_spi_regmap_config = {
147 .reg_bits = 8,
148 .val_bits = 8,
149 .read_flag_mask = BIT(7),
150 };
151
152 struct ad5770r_output_modes {
153 unsigned int ch;
154 u8 mode;
155 int min;
156 int max;
157 };
158
159 static struct ad5770r_output_modes ad5770r_rng_tbl[] = {
160 { 0, AD5770R_CH0_0_300, 0, 300 },
161 { 0, AD5770R_CH0_NEG_60_0, -60, 0 },
162 { 0, AD5770R_CH0_NEG_60_300, -60, 300 },
163 { 1, AD5770R_CH1_0_140_LOW_HEAD, 0, 140 },
164 { 1, AD5770R_CH1_0_140_LOW_NOISE, 0, 140 },
165 { 1, AD5770R_CH1_0_250, 0, 250 },
166 { 2, AD5770R_CH_LOW_RANGE, 0, 55 },
167 { 2, AD5770R_CH_HIGH_RANGE, 0, 150 },
168 { 3, AD5770R_CH_LOW_RANGE, 0, 45 },
169 { 3, AD5770R_CH_HIGH_RANGE, 0, 100 },
170 { 4, AD5770R_CH_LOW_RANGE, 0, 45 },
171 { 4, AD5770R_CH_HIGH_RANGE, 0, 100 },
172 { 5, AD5770R_CH_LOW_RANGE, 0, 45 },
173 { 5, AD5770R_CH_HIGH_RANGE, 0, 100 },
174 };
175
176 static const unsigned int ad5770r_filter_freqs[] = {
177 153, 357, 715, 1400, 2800, 262000,
178 };
179
180 static const unsigned int ad5770r_filter_reg_vals[] = {
181 AD5770R_FILTER_104_KOHM,
182 AD5770R_FILTER_44_4_KOHM,
183 AD5770R_FILTER_22_2_KOHM,
184 AD5770R_FILTER_11_2_KOHM,
185 AD5770R_FILTER_5_6_KOHM,
186 AD5770R_FILTER_60_OHM
187 };
188
ad5770r_set_output_mode(struct ad5770r_state * st,const struct ad5770r_out_range * out_mode,int channel)189 static int ad5770r_set_output_mode(struct ad5770r_state *st,
190 const struct ad5770r_out_range *out_mode,
191 int channel)
192 {
193 unsigned int regval;
194
195 regval = AD5770R_RANGE_OUTPUT_SCALING(out_mode->out_scale) |
196 AD5770R_RANGE_MODE(out_mode->out_range_mode);
197
198 return regmap_write(st->regmap,
199 AD5770R_OUTPUT_RANGE(channel), regval);
200 }
201
ad5770r_set_reference(struct ad5770r_state * st)202 static int ad5770r_set_reference(struct ad5770r_state *st)
203 {
204 unsigned int regval;
205
206 regval = AD5770R_REF_RESISTOR_SEL(st->external_res);
207
208 if (st->internal_ref) {
209 regval |= AD5770R_REF_SEL(AD5770R_INT_1_25_V_OUT_OFF);
210 } else {
211 switch (st->vref) {
212 case AD5770R_LOW_VREF_mV:
213 regval |= AD5770R_REF_SEL(AD5770R_EXT_1_25_V);
214 break;
215 case AD5770R_HIGH_VREF_mV:
216 regval |= AD5770R_REF_SEL(AD5770R_EXT_2_5_V);
217 break;
218 default:
219 regval = AD5770R_REF_SEL(AD5770R_INT_1_25_V_OUT_OFF);
220 break;
221 }
222 }
223
224 return regmap_write(st->regmap, AD5770R_REFERENCE, regval);
225 }
226
ad5770r_soft_reset(struct ad5770r_state * st)227 static int ad5770r_soft_reset(struct ad5770r_state *st)
228 {
229 return regmap_write(st->regmap, ADI_SPI_IF_CONFIG_A,
230 ADI_SPI_IF_SW_RESET_SEL(1));
231 }
232
ad5770r_reset(struct ad5770r_state * st)233 static int ad5770r_reset(struct ad5770r_state *st)
234 {
235 /* Perform software reset if no GPIO provided */
236 if (!st->gpio_reset)
237 return ad5770r_soft_reset(st);
238
239 gpiod_set_value_cansleep(st->gpio_reset, 0);
240 usleep_range(10, 20);
241 gpiod_set_value_cansleep(st->gpio_reset, 1);
242
243 /* data must not be written during reset timeframe */
244 usleep_range(100, 200);
245
246 return 0;
247 }
248
ad5770r_get_range(struct ad5770r_state * st,int ch,int * min,int * max)249 static int ad5770r_get_range(struct ad5770r_state *st,
250 int ch, int *min, int *max)
251 {
252 int i;
253 u8 tbl_ch, tbl_mode, out_range;
254
255 out_range = st->output_mode[ch].out_range_mode;
256
257 for (i = 0; i < AD5770R_MAX_CH_MODES; i++) {
258 tbl_ch = ad5770r_rng_tbl[i].ch;
259 tbl_mode = ad5770r_rng_tbl[i].mode;
260 if (tbl_ch == ch && tbl_mode == out_range) {
261 *min = ad5770r_rng_tbl[i].min;
262 *max = ad5770r_rng_tbl[i].max;
263 return 0;
264 }
265 }
266
267 return -EINVAL;
268 }
269
ad5770r_get_filter_freq(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int * freq)270 static int ad5770r_get_filter_freq(struct iio_dev *indio_dev,
271 const struct iio_chan_spec *chan, int *freq)
272 {
273 struct ad5770r_state *st = iio_priv(indio_dev);
274 int ret;
275 unsigned int regval, i;
276
277 ret = regmap_read(st->regmap,
278 AD5770R_FILTER_RESISTOR(chan->channel), ®val);
279 if (ret < 0)
280 return ret;
281
282 for (i = 0; i < ARRAY_SIZE(ad5770r_filter_reg_vals); i++)
283 if (regval == ad5770r_filter_reg_vals[i])
284 break;
285 if (i == ARRAY_SIZE(ad5770r_filter_reg_vals))
286 return -EINVAL;
287
288 *freq = ad5770r_filter_freqs[i];
289
290 return IIO_VAL_INT;
291 }
292
ad5770r_set_filter_freq(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,unsigned int freq)293 static int ad5770r_set_filter_freq(struct iio_dev *indio_dev,
294 const struct iio_chan_spec *chan,
295 unsigned int freq)
296 {
297 struct ad5770r_state *st = iio_priv(indio_dev);
298 unsigned int regval, i;
299
300 for (i = 0; i < ARRAY_SIZE(ad5770r_filter_freqs); i++)
301 if (ad5770r_filter_freqs[i] >= freq)
302 break;
303 if (i == ARRAY_SIZE(ad5770r_filter_freqs))
304 return -EINVAL;
305
306 regval = ad5770r_filter_reg_vals[i];
307
308 return regmap_write(st->regmap, AD5770R_FILTER_RESISTOR(chan->channel),
309 regval);
310 }
311
ad5770r_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long info)312 static int ad5770r_read_raw(struct iio_dev *indio_dev,
313 struct iio_chan_spec const *chan,
314 int *val, int *val2, long info)
315 {
316 struct ad5770r_state *st = iio_priv(indio_dev);
317 int max, min, ret;
318 u16 buf16;
319
320 switch (info) {
321 case IIO_CHAN_INFO_RAW:
322 ret = regmap_bulk_read(st->regmap,
323 chan->address,
324 st->transf_buf, 2);
325 if (ret)
326 return 0;
327
328 buf16 = st->transf_buf[0] + (st->transf_buf[1] << 8);
329 *val = buf16 >> 2;
330 return IIO_VAL_INT;
331 case IIO_CHAN_INFO_SCALE:
332 ret = ad5770r_get_range(st, chan->channel, &min, &max);
333 if (ret < 0)
334 return ret;
335 *val = max - min;
336 /* There is no sign bit. (negative current is mapped from 0)
337 * (sourced/sinked) current = raw * scale + offset
338 * where offset in case of CH0 can be negative.
339 */
340 *val2 = 14;
341 return IIO_VAL_FRACTIONAL_LOG2;
342 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
343 return ad5770r_get_filter_freq(indio_dev, chan, val);
344 case IIO_CHAN_INFO_OFFSET:
345 ret = ad5770r_get_range(st, chan->channel, &min, &max);
346 if (ret < 0)
347 return ret;
348 *val = min;
349 return IIO_VAL_INT;
350 default:
351 return -EINVAL;
352 }
353 }
354
ad5770r_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long info)355 static int ad5770r_write_raw(struct iio_dev *indio_dev,
356 struct iio_chan_spec const *chan,
357 int val, int val2, long info)
358 {
359 struct ad5770r_state *st = iio_priv(indio_dev);
360
361 switch (info) {
362 case IIO_CHAN_INFO_RAW:
363 st->transf_buf[0] = ((u16)val >> 6);
364 st->transf_buf[1] = (val & GENMASK(5, 0)) << 2;
365 return regmap_bulk_write(st->regmap, chan->address,
366 st->transf_buf, 2);
367 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
368 return ad5770r_set_filter_freq(indio_dev, chan, val);
369 default:
370 return -EINVAL;
371 }
372 }
373
ad5770r_read_freq_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)374 static int ad5770r_read_freq_avail(struct iio_dev *indio_dev,
375 struct iio_chan_spec const *chan,
376 const int **vals, int *type, int *length,
377 long mask)
378 {
379 switch (mask) {
380 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
381 *type = IIO_VAL_INT;
382 *vals = ad5770r_filter_freqs;
383 *length = ARRAY_SIZE(ad5770r_filter_freqs);
384 return IIO_AVAIL_LIST;
385 }
386
387 return -EINVAL;
388 }
389
ad5770r_reg_access(struct iio_dev * indio_dev,unsigned int reg,unsigned int writeval,unsigned int * readval)390 static int ad5770r_reg_access(struct iio_dev *indio_dev,
391 unsigned int reg,
392 unsigned int writeval,
393 unsigned int *readval)
394 {
395 struct ad5770r_state *st = iio_priv(indio_dev);
396
397 if (readval)
398 return regmap_read(st->regmap, reg, readval);
399 else
400 return regmap_write(st->regmap, reg, writeval);
401 }
402
403 static const struct iio_info ad5770r_info = {
404 .read_raw = ad5770r_read_raw,
405 .write_raw = ad5770r_write_raw,
406 .read_avail = ad5770r_read_freq_avail,
407 .debugfs_reg_access = &ad5770r_reg_access,
408 };
409
ad5770r_store_output_range(struct ad5770r_state * st,int min,int max,int index)410 static int ad5770r_store_output_range(struct ad5770r_state *st,
411 int min, int max, int index)
412 {
413 int i;
414
415 for (i = 0; i < AD5770R_MAX_CH_MODES; i++) {
416 if (ad5770r_rng_tbl[i].ch != index)
417 continue;
418 if (ad5770r_rng_tbl[i].min != min ||
419 ad5770r_rng_tbl[i].max != max)
420 continue;
421 st->output_mode[index].out_range_mode = ad5770r_rng_tbl[i].mode;
422
423 return 0;
424 }
425
426 return -EINVAL;
427 }
428
ad5770r_read_dac_powerdown(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,char * buf)429 static ssize_t ad5770r_read_dac_powerdown(struct iio_dev *indio_dev,
430 uintptr_t private,
431 const struct iio_chan_spec *chan,
432 char *buf)
433 {
434 struct ad5770r_state *st = iio_priv(indio_dev);
435
436 return sprintf(buf, "%d\n", st->ch_pwr_down[chan->channel]);
437 }
438
ad5770r_write_dac_powerdown(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,const char * buf,size_t len)439 static ssize_t ad5770r_write_dac_powerdown(struct iio_dev *indio_dev,
440 uintptr_t private,
441 const struct iio_chan_spec *chan,
442 const char *buf, size_t len)
443 {
444 struct ad5770r_state *st = iio_priv(indio_dev);
445 unsigned int regval;
446 unsigned int mask;
447 bool readin;
448 int ret;
449
450 ret = kstrtobool(buf, &readin);
451 if (ret)
452 return ret;
453
454 readin = !readin;
455
456 regval = AD5770R_CFG_SHUTDOWN_B(readin, chan->channel);
457 if (chan->channel == 0 &&
458 st->output_mode[0].out_range_mode > AD5770R_CH0_0_300) {
459 regval |= AD5770R_CFG_CH0_SINK_EN(readin);
460 mask = BIT(chan->channel) + BIT(7);
461 } else {
462 mask = BIT(chan->channel);
463 }
464 ret = regmap_update_bits(st->regmap, AD5770R_CHANNEL_CONFIG, mask,
465 regval);
466 if (ret)
467 return ret;
468
469 regval = AD5770R_CH_SET(readin, chan->channel);
470 ret = regmap_update_bits(st->regmap, AD5770R_CH_ENABLE,
471 BIT(chan->channel), regval);
472 if (ret)
473 return ret;
474
475 st->ch_pwr_down[chan->channel] = !readin;
476
477 return len;
478 }
479
480 static const struct iio_chan_spec_ext_info ad5770r_ext_info[] = {
481 {
482 .name = "powerdown",
483 .read = ad5770r_read_dac_powerdown,
484 .write = ad5770r_write_dac_powerdown,
485 .shared = IIO_SEPARATE,
486 },
487 { }
488 };
489
490 #define AD5770R_IDAC_CHANNEL(index, reg) { \
491 .type = IIO_CURRENT, \
492 .address = reg, \
493 .indexed = 1, \
494 .channel = index, \
495 .output = 1, \
496 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
497 BIT(IIO_CHAN_INFO_SCALE) | \
498 BIT(IIO_CHAN_INFO_OFFSET) | \
499 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
500 .info_mask_shared_by_type_available = \
501 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
502 .ext_info = ad5770r_ext_info, \
503 }
504
505 static const struct iio_chan_spec ad5770r_channels[] = {
506 AD5770R_IDAC_CHANNEL(0, AD5770R_DAC_MSB(0)),
507 AD5770R_IDAC_CHANNEL(1, AD5770R_DAC_MSB(1)),
508 AD5770R_IDAC_CHANNEL(2, AD5770R_DAC_MSB(2)),
509 AD5770R_IDAC_CHANNEL(3, AD5770R_DAC_MSB(3)),
510 AD5770R_IDAC_CHANNEL(4, AD5770R_DAC_MSB(4)),
511 AD5770R_IDAC_CHANNEL(5, AD5770R_DAC_MSB(5)),
512 };
513
ad5770r_channel_config(struct ad5770r_state * st)514 static int ad5770r_channel_config(struct ad5770r_state *st)
515 {
516 int ret, tmp[2], min, max;
517 unsigned int num;
518 struct fwnode_handle *child;
519
520 num = device_get_child_node_count(&st->spi->dev);
521 if (num != AD5770R_MAX_CHANNELS)
522 return -EINVAL;
523
524 device_for_each_child_node(&st->spi->dev, child) {
525 ret = fwnode_property_read_u32(child, "num", &num);
526 if (ret)
527 return ret;
528 if (num >= AD5770R_MAX_CHANNELS)
529 return -EINVAL;
530
531 ret = fwnode_property_read_u32_array(child,
532 "adi,range-microamp",
533 tmp, 2);
534 if (ret)
535 return ret;
536
537 min = tmp[0] / 1000;
538 max = tmp[1] / 1000;
539 ret = ad5770r_store_output_range(st, min, max, num);
540 if (ret)
541 return ret;
542 }
543
544 return ret;
545 }
546
ad5770r_init(struct ad5770r_state * st)547 static int ad5770r_init(struct ad5770r_state *st)
548 {
549 int ret, i;
550
551 st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset",
552 GPIOD_OUT_HIGH);
553 if (IS_ERR(st->gpio_reset))
554 return PTR_ERR(st->gpio_reset);
555
556 /* Perform a reset */
557 ret = ad5770r_reset(st);
558 if (ret)
559 return ret;
560
561 /* Set output range */
562 ret = ad5770r_channel_config(st);
563 if (ret)
564 return ret;
565
566 for (i = 0; i < AD5770R_MAX_CHANNELS; i++) {
567 ret = ad5770r_set_output_mode(st, &st->output_mode[i], i);
568 if (ret)
569 return ret;
570 }
571
572 st->external_res = fwnode_property_read_bool(st->spi->dev.fwnode,
573 "adi,external-resistor");
574
575 ret = ad5770r_set_reference(st);
576 if (ret)
577 return ret;
578
579 /* Set outputs off */
580 ret = regmap_write(st->regmap, AD5770R_CHANNEL_CONFIG, 0x00);
581 if (ret)
582 return ret;
583
584 ret = regmap_write(st->regmap, AD5770R_CH_ENABLE, 0x00);
585 if (ret)
586 return ret;
587
588 for (i = 0; i < AD5770R_MAX_CHANNELS; i++)
589 st->ch_pwr_down[i] = true;
590
591 return ret;
592 }
593
ad5770r_disable_regulator(void * data)594 static void ad5770r_disable_regulator(void *data)
595 {
596 struct ad5770r_state *st = data;
597
598 regulator_disable(st->vref_reg);
599 }
600
ad5770r_probe(struct spi_device * spi)601 static int ad5770r_probe(struct spi_device *spi)
602 {
603 struct ad5770r_state *st;
604 struct iio_dev *indio_dev;
605 struct regmap *regmap;
606 int ret;
607
608 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
609 if (!indio_dev)
610 return -ENOMEM;
611
612 st = iio_priv(indio_dev);
613 spi_set_drvdata(spi, indio_dev);
614
615 st->spi = spi;
616
617 regmap = devm_regmap_init_spi(spi, &ad5770r_spi_regmap_config);
618 if (IS_ERR(regmap)) {
619 dev_err(&spi->dev, "Error initializing spi regmap: %ld\n",
620 PTR_ERR(regmap));
621 return PTR_ERR(regmap);
622 }
623 st->regmap = regmap;
624
625 st->vref_reg = devm_regulator_get_optional(&spi->dev, "vref");
626 if (!IS_ERR(st->vref_reg)) {
627 ret = regulator_enable(st->vref_reg);
628 if (ret) {
629 dev_err(&spi->dev,
630 "Failed to enable vref regulators: %d\n", ret);
631 return ret;
632 }
633
634 ret = devm_add_action_or_reset(&spi->dev,
635 ad5770r_disable_regulator,
636 st);
637 if (ret < 0)
638 return ret;
639
640 ret = regulator_get_voltage(st->vref_reg);
641 if (ret < 0)
642 return ret;
643
644 st->vref = ret / 1000;
645 } else {
646 if (PTR_ERR(st->vref_reg) == -ENODEV) {
647 st->vref = AD5770R_LOW_VREF_mV;
648 st->internal_ref = true;
649 } else {
650 return PTR_ERR(st->vref_reg);
651 }
652 }
653
654 indio_dev->name = spi_get_device_id(spi)->name;
655 indio_dev->info = &ad5770r_info;
656 indio_dev->modes = INDIO_DIRECT_MODE;
657 indio_dev->channels = ad5770r_channels;
658 indio_dev->num_channels = ARRAY_SIZE(ad5770r_channels);
659
660 ret = ad5770r_init(st);
661 if (ret < 0) {
662 dev_err(&spi->dev, "AD5770R init failed\n");
663 return ret;
664 }
665
666 return devm_iio_device_register(&st->spi->dev, indio_dev);
667 }
668
669 static const struct of_device_id ad5770r_of_id[] = {
670 { .compatible = "adi,ad5770r", },
671 {},
672 };
673 MODULE_DEVICE_TABLE(of, ad5770r_of_id);
674
675 static const struct spi_device_id ad5770r_id[] = {
676 { "ad5770r", 0 },
677 {},
678 };
679 MODULE_DEVICE_TABLE(spi, ad5770r_id);
680
681 static struct spi_driver ad5770r_driver = {
682 .driver = {
683 .name = KBUILD_MODNAME,
684 .of_match_table = ad5770r_of_id,
685 },
686 .probe = ad5770r_probe,
687 .id_table = ad5770r_id,
688 };
689
690 module_spi_driver(ad5770r_driver);
691
692 MODULE_AUTHOR("Mircea Caprioru <mircea.caprioru@analog.com>");
693 MODULE_DESCRIPTION("Analog Devices AD5770R IDAC");
694 MODULE_LICENSE("GPL v2");
695