File Index
Files and directories
Sign in
FILE

ad5770r.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/dac/ad5770r.c 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
 83enum ad5770r_ch0_modes {
 84	AD5770R_CH0_0_300 = 0,
 85	AD5770R_CH0_NEG_60_0,
 86	AD5770R_CH0_NEG_60_300
 87};
 88
 89enum 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
 95enum ad5770r_ch2_5_modes {
 96	AD5770R_CH_LOW_RANGE = 0,
 97	AD5770R_CH_HIGH_RANGE
 98};
 99
100enum 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
107enum 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
116struct 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 */
133struct 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
145static const struct regmap_config ad5770r_spi_regmap_config = {
146	.reg_bits = 8,
147	.val_bits = 8,
148	.read_flag_mask = BIT(7),
149};
150
151struct ad5770r_output_modes {
152	unsigned int ch;
153	u8 mode;
154	int min;
155	int max;
156};
157
158static const 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
175static const unsigned int ad5770r_filter_freqs[] = {
176	153, 357, 715, 1400, 2800, 262000,
177};
178
179static 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
188static 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
201static 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
226static 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
232static 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
248static 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
269static 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
292static 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
311static 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 ret;
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
354static 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
373static 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
389static 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
402static 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
409static 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
428static 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
438static 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
479static 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
504static 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
513static 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
545static 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
592static 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
638static const struct of_device_id ad5770r_of_id[] = {
639	{ .compatible = "adi,ad5770r", },
640	{ }
641};
642MODULE_DEVICE_TABLE(of, ad5770r_of_id);
643
644static const struct spi_device_id ad5770r_id[] = {
645	{ "ad5770r", 0 },
646	{ }
647};
648MODULE_DEVICE_TABLE(spi, ad5770r_id);
649
650static 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
659module_spi_driver(ad5770r_driver);
660
661MODULE_AUTHOR("Mircea Caprioru <mircea.caprioru@analog.com>");
662MODULE_DESCRIPTION("Analog Devices AD5770R IDAC");
663MODULE_LICENSE("GPL v2");
~/ Read-only file preview.