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