xref: /linux/drivers/iio/dac/ad5761.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1fda8d26eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2131497acSRicardo Ribalda Delgado /*
3131497acSRicardo Ribalda Delgado  * AD5721, AD5721R, AD5761, AD5761R, Voltage Output Digital to Analog Converter
4131497acSRicardo Ribalda Delgado  *
5131497acSRicardo Ribalda Delgado  * Copyright 2016 Qtechnology A/S
6cea0fad0SRicardo Ribalda Delgado  * 2016 Ricardo Ribalda <ribalda@kernel.org>
7131497acSRicardo Ribalda Delgado  */
8131497acSRicardo Ribalda Delgado #include <linux/kernel.h>
9131497acSRicardo Ribalda Delgado #include <linux/module.h>
10131497acSRicardo Ribalda Delgado #include <linux/spi/spi.h>
11131497acSRicardo Ribalda Delgado #include <linux/bitops.h>
12131497acSRicardo Ribalda Delgado #include <linux/iio/iio.h>
13131497acSRicardo Ribalda Delgado #include <linux/iio/sysfs.h>
14131497acSRicardo Ribalda Delgado #include <linux/regulator/consumer.h>
15131497acSRicardo Ribalda Delgado #include <linux/platform_data/ad5761.h>
16131497acSRicardo Ribalda Delgado 
17131497acSRicardo Ribalda Delgado #define AD5761_ADDR(addr)		((addr & 0xf) << 16)
18131497acSRicardo Ribalda Delgado #define AD5761_ADDR_NOOP		0x0
19131497acSRicardo Ribalda Delgado #define AD5761_ADDR_DAC_WRITE		0x3
20131497acSRicardo Ribalda Delgado #define AD5761_ADDR_CTRL_WRITE_REG	0x4
21131497acSRicardo Ribalda Delgado #define AD5761_ADDR_SW_DATA_RESET	0x7
22131497acSRicardo Ribalda Delgado #define AD5761_ADDR_DAC_READ		0xb
23131497acSRicardo Ribalda Delgado #define AD5761_ADDR_CTRL_READ_REG	0xc
24131497acSRicardo Ribalda Delgado #define AD5761_ADDR_SW_FULL_RESET	0xf
25131497acSRicardo Ribalda Delgado 
26131497acSRicardo Ribalda Delgado #define AD5761_CTRL_USE_INTVREF		BIT(5)
27131497acSRicardo Ribalda Delgado #define AD5761_CTRL_ETS			BIT(6)
28131497acSRicardo Ribalda Delgado 
29131497acSRicardo Ribalda Delgado /**
30131497acSRicardo Ribalda Delgado  * struct ad5761_chip_info - chip specific information
31131497acSRicardo Ribalda Delgado  * @int_vref:	Value of the internal reference voltage in mV - 0 if external
32131497acSRicardo Ribalda Delgado  *		reference voltage is used
33131497acSRicardo Ribalda Delgado  * @channel:	channel specification
34131497acSRicardo Ribalda Delgado */
35131497acSRicardo Ribalda Delgado 
36131497acSRicardo Ribalda Delgado struct ad5761_chip_info {
37131497acSRicardo Ribalda Delgado 	unsigned long int_vref;
38131497acSRicardo Ribalda Delgado 	const struct iio_chan_spec channel;
39131497acSRicardo Ribalda Delgado };
40131497acSRicardo Ribalda Delgado 
41131497acSRicardo Ribalda Delgado struct ad5761_range_params {
42131497acSRicardo Ribalda Delgado 	int m;
43131497acSRicardo Ribalda Delgado 	int c;
44131497acSRicardo Ribalda Delgado };
45131497acSRicardo Ribalda Delgado 
46131497acSRicardo Ribalda Delgado enum ad5761_supported_device_ids {
47131497acSRicardo Ribalda Delgado 	ID_AD5721,
48131497acSRicardo Ribalda Delgado 	ID_AD5721R,
49131497acSRicardo Ribalda Delgado 	ID_AD5761,
50131497acSRicardo Ribalda Delgado 	ID_AD5761R,
51131497acSRicardo Ribalda Delgado };
52131497acSRicardo Ribalda Delgado 
53131497acSRicardo Ribalda Delgado /**
54131497acSRicardo Ribalda Delgado  * struct ad5761_state - driver instance specific data
55131497acSRicardo Ribalda Delgado  * @spi:		spi_device
56131497acSRicardo Ribalda Delgado  * @vref_reg:		reference voltage regulator
57131497acSRicardo Ribalda Delgado  * @use_intref:		true when the internal voltage reference is used
58131497acSRicardo Ribalda Delgado  * @vref:		actual voltage reference in mVolts
59131497acSRicardo Ribalda Delgado  * @range:		output range mode used
6053001d55SLee Jones  * @lock:		lock to protect the data buffer during SPI ops
61131497acSRicardo Ribalda Delgado  * @data:		cache aligned spi buffer
62131497acSRicardo Ribalda Delgado  */
63131497acSRicardo Ribalda Delgado struct ad5761_state {
64131497acSRicardo Ribalda Delgado 	struct spi_device		*spi;
65131497acSRicardo Ribalda Delgado 	struct regulator		*vref_reg;
6619710bffSSergiu Cuciurean 	struct mutex			lock;
67131497acSRicardo Ribalda Delgado 
68131497acSRicardo Ribalda Delgado 	bool use_intref;
69131497acSRicardo Ribalda Delgado 	int vref;
70131497acSRicardo Ribalda Delgado 	enum ad5761_voltage_range range;
71131497acSRicardo Ribalda Delgado 
72131497acSRicardo Ribalda Delgado 	/*
73*7d12a611SJonathan Cameron 	 * DMA (thus cache coherency maintenance) may require the
74131497acSRicardo Ribalda Delgado 	 * transfer buffers to live in their own cache lines.
75131497acSRicardo Ribalda Delgado 	 */
76131497acSRicardo Ribalda Delgado 	union {
77131497acSRicardo Ribalda Delgado 		__be32 d32;
78131497acSRicardo Ribalda Delgado 		u8 d8[4];
79*7d12a611SJonathan Cameron 	} data[3] __aligned(IIO_DMA_MINALIGN);
80131497acSRicardo Ribalda Delgado };
81131497acSRicardo Ribalda Delgado 
82131497acSRicardo Ribalda Delgado static const struct ad5761_range_params ad5761_range_params[] = {
83131497acSRicardo Ribalda Delgado 	[AD5761_VOLTAGE_RANGE_M10V_10V] = {
84131497acSRicardo Ribalda Delgado 		.m = 80,
85131497acSRicardo Ribalda Delgado 		.c = 40,
86131497acSRicardo Ribalda Delgado 	},
87131497acSRicardo Ribalda Delgado 	[AD5761_VOLTAGE_RANGE_0V_10V] = {
88131497acSRicardo Ribalda Delgado 		.m = 40,
89131497acSRicardo Ribalda Delgado 		.c = 0,
90131497acSRicardo Ribalda Delgado 	},
91131497acSRicardo Ribalda Delgado 	[AD5761_VOLTAGE_RANGE_M5V_5V] = {
92131497acSRicardo Ribalda Delgado 		.m = 40,
93131497acSRicardo Ribalda Delgado 		.c = 20,
94131497acSRicardo Ribalda Delgado 	},
95131497acSRicardo Ribalda Delgado 	[AD5761_VOLTAGE_RANGE_0V_5V] = {
96131497acSRicardo Ribalda Delgado 		.m = 20,
97131497acSRicardo Ribalda Delgado 		.c = 0,
98131497acSRicardo Ribalda Delgado 	},
99131497acSRicardo Ribalda Delgado 	[AD5761_VOLTAGE_RANGE_M2V5_7V5] = {
100131497acSRicardo Ribalda Delgado 		.m = 40,
101131497acSRicardo Ribalda Delgado 		.c = 10,
102131497acSRicardo Ribalda Delgado 	},
103131497acSRicardo Ribalda Delgado 	[AD5761_VOLTAGE_RANGE_M3V_3V] = {
104131497acSRicardo Ribalda Delgado 		.m = 24,
105131497acSRicardo Ribalda Delgado 		.c = 12,
106131497acSRicardo Ribalda Delgado 	},
107131497acSRicardo Ribalda Delgado 	[AD5761_VOLTAGE_RANGE_0V_16V] = {
108131497acSRicardo Ribalda Delgado 		.m = 64,
109131497acSRicardo Ribalda Delgado 		.c = 0,
110131497acSRicardo Ribalda Delgado 	},
111131497acSRicardo Ribalda Delgado 	[AD5761_VOLTAGE_RANGE_0V_20V] = {
112131497acSRicardo Ribalda Delgado 		.m = 80,
113131497acSRicardo Ribalda Delgado 		.c = 0,
114131497acSRicardo Ribalda Delgado 	},
115131497acSRicardo Ribalda Delgado };
116131497acSRicardo Ribalda Delgado 
_ad5761_spi_write(struct ad5761_state * st,u8 addr,u16 val)117131497acSRicardo Ribalda Delgado static int _ad5761_spi_write(struct ad5761_state *st, u8 addr, u16 val)
118131497acSRicardo Ribalda Delgado {
119131497acSRicardo Ribalda Delgado 	st->data[0].d32 = cpu_to_be32(AD5761_ADDR(addr) | val);
120131497acSRicardo Ribalda Delgado 
121131497acSRicardo Ribalda Delgado 	return spi_write(st->spi, &st->data[0].d8[1], 3);
122131497acSRicardo Ribalda Delgado }
123131497acSRicardo Ribalda Delgado 
ad5761_spi_write(struct iio_dev * indio_dev,u8 addr,u16 val)124131497acSRicardo Ribalda Delgado static int ad5761_spi_write(struct iio_dev *indio_dev, u8 addr, u16 val)
125131497acSRicardo Ribalda Delgado {
126131497acSRicardo Ribalda Delgado 	struct ad5761_state *st = iio_priv(indio_dev);
127131497acSRicardo Ribalda Delgado 	int ret;
128131497acSRicardo Ribalda Delgado 
12919710bffSSergiu Cuciurean 	mutex_lock(&st->lock);
130131497acSRicardo Ribalda Delgado 	ret = _ad5761_spi_write(st, addr, val);
13119710bffSSergiu Cuciurean 	mutex_unlock(&st->lock);
132131497acSRicardo Ribalda Delgado 
133131497acSRicardo Ribalda Delgado 	return ret;
134131497acSRicardo Ribalda Delgado }
135131497acSRicardo Ribalda Delgado 
_ad5761_spi_read(struct ad5761_state * st,u8 addr,u16 * val)136131497acSRicardo Ribalda Delgado static int _ad5761_spi_read(struct ad5761_state *st, u8 addr, u16 *val)
137131497acSRicardo Ribalda Delgado {
138131497acSRicardo Ribalda Delgado 	int ret;
139131497acSRicardo Ribalda Delgado 	struct spi_transfer xfers[] = {
140131497acSRicardo Ribalda Delgado 		{
141131497acSRicardo Ribalda Delgado 			.tx_buf = &st->data[0].d8[1],
142131497acSRicardo Ribalda Delgado 			.bits_per_word = 8,
143131497acSRicardo Ribalda Delgado 			.len = 3,
144131497acSRicardo Ribalda Delgado 			.cs_change = true,
145131497acSRicardo Ribalda Delgado 		}, {
146131497acSRicardo Ribalda Delgado 			.tx_buf = &st->data[1].d8[1],
147131497acSRicardo Ribalda Delgado 			.rx_buf = &st->data[2].d8[1],
148131497acSRicardo Ribalda Delgado 			.bits_per_word = 8,
149131497acSRicardo Ribalda Delgado 			.len = 3,
150131497acSRicardo Ribalda Delgado 		},
151131497acSRicardo Ribalda Delgado 	};
152131497acSRicardo Ribalda Delgado 
153131497acSRicardo Ribalda Delgado 	st->data[0].d32 = cpu_to_be32(AD5761_ADDR(addr));
154131497acSRicardo Ribalda Delgado 	st->data[1].d32 = cpu_to_be32(AD5761_ADDR(AD5761_ADDR_NOOP));
155131497acSRicardo Ribalda Delgado 
156131497acSRicardo Ribalda Delgado 	ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
157131497acSRicardo Ribalda Delgado 
158131497acSRicardo Ribalda Delgado 	*val = be32_to_cpu(st->data[2].d32);
159131497acSRicardo Ribalda Delgado 
160131497acSRicardo Ribalda Delgado 	return ret;
161131497acSRicardo Ribalda Delgado }
162131497acSRicardo Ribalda Delgado 
ad5761_spi_read(struct iio_dev * indio_dev,u8 addr,u16 * val)163131497acSRicardo Ribalda Delgado static int ad5761_spi_read(struct iio_dev *indio_dev, u8 addr, u16 *val)
164131497acSRicardo Ribalda Delgado {
165131497acSRicardo Ribalda Delgado 	struct ad5761_state *st = iio_priv(indio_dev);
166131497acSRicardo Ribalda Delgado 	int ret;
167131497acSRicardo Ribalda Delgado 
16819710bffSSergiu Cuciurean 	mutex_lock(&st->lock);
169131497acSRicardo Ribalda Delgado 	ret = _ad5761_spi_read(st, addr, val);
17019710bffSSergiu Cuciurean 	mutex_unlock(&st->lock);
171131497acSRicardo Ribalda Delgado 
172131497acSRicardo Ribalda Delgado 	return ret;
173131497acSRicardo Ribalda Delgado }
174131497acSRicardo Ribalda Delgado 
ad5761_spi_set_range(struct ad5761_state * st,enum ad5761_voltage_range range)175131497acSRicardo Ribalda Delgado static int ad5761_spi_set_range(struct ad5761_state *st,
176131497acSRicardo Ribalda Delgado 				enum ad5761_voltage_range range)
177131497acSRicardo Ribalda Delgado {
178131497acSRicardo Ribalda Delgado 	u16 aux;
179131497acSRicardo Ribalda Delgado 	int ret;
180131497acSRicardo Ribalda Delgado 
181131497acSRicardo Ribalda Delgado 	aux = (range & 0x7) | AD5761_CTRL_ETS;
182131497acSRicardo Ribalda Delgado 
183131497acSRicardo Ribalda Delgado 	if (st->use_intref)
184131497acSRicardo Ribalda Delgado 		aux |= AD5761_CTRL_USE_INTVREF;
185131497acSRicardo Ribalda Delgado 
186131497acSRicardo Ribalda Delgado 	ret = _ad5761_spi_write(st, AD5761_ADDR_SW_FULL_RESET, 0);
187131497acSRicardo Ribalda Delgado 	if (ret)
188131497acSRicardo Ribalda Delgado 		return ret;
189131497acSRicardo Ribalda Delgado 
190131497acSRicardo Ribalda Delgado 	ret = _ad5761_spi_write(st, AD5761_ADDR_CTRL_WRITE_REG, aux);
191131497acSRicardo Ribalda Delgado 	if (ret)
192131497acSRicardo Ribalda Delgado 		return ret;
193131497acSRicardo Ribalda Delgado 
194131497acSRicardo Ribalda Delgado 	st->range = range;
195131497acSRicardo Ribalda Delgado 
196131497acSRicardo Ribalda Delgado 	return 0;
197131497acSRicardo Ribalda Delgado }
198131497acSRicardo Ribalda Delgado 
ad5761_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)199131497acSRicardo Ribalda Delgado static int ad5761_read_raw(struct iio_dev *indio_dev,
200131497acSRicardo Ribalda Delgado 			   struct iio_chan_spec const *chan,
201131497acSRicardo Ribalda Delgado 			   int *val,
202131497acSRicardo Ribalda Delgado 			   int *val2,
203131497acSRicardo Ribalda Delgado 			   long mask)
204131497acSRicardo Ribalda Delgado {
205131497acSRicardo Ribalda Delgado 	struct ad5761_state *st;
206131497acSRicardo Ribalda Delgado 	int ret;
207131497acSRicardo Ribalda Delgado 	u16 aux;
208131497acSRicardo Ribalda Delgado 
209131497acSRicardo Ribalda Delgado 	switch (mask) {
210131497acSRicardo Ribalda Delgado 	case IIO_CHAN_INFO_RAW:
211131497acSRicardo Ribalda Delgado 		ret = ad5761_spi_read(indio_dev, AD5761_ADDR_DAC_READ, &aux);
212131497acSRicardo Ribalda Delgado 		if (ret)
213131497acSRicardo Ribalda Delgado 			return ret;
214131497acSRicardo Ribalda Delgado 		*val = aux >> chan->scan_type.shift;
215131497acSRicardo Ribalda Delgado 		return IIO_VAL_INT;
216131497acSRicardo Ribalda Delgado 	case IIO_CHAN_INFO_SCALE:
217131497acSRicardo Ribalda Delgado 		st = iio_priv(indio_dev);
218131497acSRicardo Ribalda Delgado 		*val = st->vref * ad5761_range_params[st->range].m;
219131497acSRicardo Ribalda Delgado 		*val /= 10;
220131497acSRicardo Ribalda Delgado 		*val2 = chan->scan_type.realbits;
221131497acSRicardo Ribalda Delgado 		return IIO_VAL_FRACTIONAL_LOG2;
222131497acSRicardo Ribalda Delgado 	case IIO_CHAN_INFO_OFFSET:
223131497acSRicardo Ribalda Delgado 		st = iio_priv(indio_dev);
224131497acSRicardo Ribalda Delgado 		*val = -(1 << chan->scan_type.realbits);
225131497acSRicardo Ribalda Delgado 		*val *=	ad5761_range_params[st->range].c;
226131497acSRicardo Ribalda Delgado 		*val /=	ad5761_range_params[st->range].m;
227131497acSRicardo Ribalda Delgado 		return IIO_VAL_INT;
228131497acSRicardo Ribalda Delgado 	default:
229131497acSRicardo Ribalda Delgado 		return -EINVAL;
230131497acSRicardo Ribalda Delgado 	}
231131497acSRicardo Ribalda Delgado }
232131497acSRicardo Ribalda Delgado 
ad5761_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)233131497acSRicardo Ribalda Delgado static int ad5761_write_raw(struct iio_dev *indio_dev,
234131497acSRicardo Ribalda Delgado 			    struct iio_chan_spec const *chan,
235131497acSRicardo Ribalda Delgado 			    int val,
236131497acSRicardo Ribalda Delgado 			    int val2,
237131497acSRicardo Ribalda Delgado 			    long mask)
238131497acSRicardo Ribalda Delgado {
239131497acSRicardo Ribalda Delgado 	u16 aux;
240131497acSRicardo Ribalda Delgado 
241131497acSRicardo Ribalda Delgado 	if (mask != IIO_CHAN_INFO_RAW)
242131497acSRicardo Ribalda Delgado 		return -EINVAL;
243131497acSRicardo Ribalda Delgado 
244131497acSRicardo Ribalda Delgado 	if (val2 || (val << chan->scan_type.shift) > 0xffff || val < 0)
245131497acSRicardo Ribalda Delgado 		return -EINVAL;
246131497acSRicardo Ribalda Delgado 
247131497acSRicardo Ribalda Delgado 	aux = val << chan->scan_type.shift;
248131497acSRicardo Ribalda Delgado 
249131497acSRicardo Ribalda Delgado 	return ad5761_spi_write(indio_dev, AD5761_ADDR_DAC_WRITE, aux);
250131497acSRicardo Ribalda Delgado }
251131497acSRicardo Ribalda Delgado 
252131497acSRicardo Ribalda Delgado static const struct iio_info ad5761_info = {
253131497acSRicardo Ribalda Delgado 	.read_raw = &ad5761_read_raw,
254131497acSRicardo Ribalda Delgado 	.write_raw = &ad5761_write_raw,
255131497acSRicardo Ribalda Delgado };
256131497acSRicardo Ribalda Delgado 
257131497acSRicardo Ribalda Delgado #define AD5761_CHAN(_bits) {				\
258131497acSRicardo Ribalda Delgado 	.type = IIO_VOLTAGE,				\
259131497acSRicardo Ribalda Delgado 	.output = 1,					\
260131497acSRicardo Ribalda Delgado 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
261131497acSRicardo Ribalda Delgado 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
262131497acSRicardo Ribalda Delgado 		BIT(IIO_CHAN_INFO_OFFSET),		\
263131497acSRicardo Ribalda Delgado 	.scan_type = {					\
264131497acSRicardo Ribalda Delgado 		.sign = 'u',				\
265131497acSRicardo Ribalda Delgado 		.realbits = (_bits),			\
266131497acSRicardo Ribalda Delgado 		.storagebits = 16,			\
267131497acSRicardo Ribalda Delgado 		.shift = 16 - (_bits),			\
268131497acSRicardo Ribalda Delgado 	},						\
269131497acSRicardo Ribalda Delgado }
270131497acSRicardo Ribalda Delgado 
271131497acSRicardo Ribalda Delgado static const struct ad5761_chip_info ad5761_chip_infos[] = {
272131497acSRicardo Ribalda Delgado 	[ID_AD5721] = {
273131497acSRicardo Ribalda Delgado 		.int_vref = 0,
274131497acSRicardo Ribalda Delgado 		.channel = AD5761_CHAN(12),
275131497acSRicardo Ribalda Delgado 	},
276131497acSRicardo Ribalda Delgado 	[ID_AD5721R] = {
277131497acSRicardo Ribalda Delgado 		.int_vref = 2500,
278131497acSRicardo Ribalda Delgado 		.channel = AD5761_CHAN(12),
279131497acSRicardo Ribalda Delgado 	},
280131497acSRicardo Ribalda Delgado 	[ID_AD5761] = {
281131497acSRicardo Ribalda Delgado 		.int_vref = 0,
282131497acSRicardo Ribalda Delgado 		.channel = AD5761_CHAN(16),
283131497acSRicardo Ribalda Delgado 	},
284131497acSRicardo Ribalda Delgado 	[ID_AD5761R] = {
285131497acSRicardo Ribalda Delgado 		.int_vref = 2500,
286131497acSRicardo Ribalda Delgado 		.channel = AD5761_CHAN(16),
287131497acSRicardo Ribalda Delgado 	},
288131497acSRicardo Ribalda Delgado };
289131497acSRicardo Ribalda Delgado 
ad5761_get_vref(struct ad5761_state * st,const struct ad5761_chip_info * chip_info)290131497acSRicardo Ribalda Delgado static int ad5761_get_vref(struct ad5761_state *st,
291131497acSRicardo Ribalda Delgado 			   const struct ad5761_chip_info *chip_info)
292131497acSRicardo Ribalda Delgado {
293131497acSRicardo Ribalda Delgado 	int ret;
294131497acSRicardo Ribalda Delgado 
295131497acSRicardo Ribalda Delgado 	st->vref_reg = devm_regulator_get_optional(&st->spi->dev, "vref");
296131497acSRicardo Ribalda Delgado 	if (PTR_ERR(st->vref_reg) == -ENODEV) {
297131497acSRicardo Ribalda Delgado 		/* Use Internal regulator */
298131497acSRicardo Ribalda Delgado 		if (!chip_info->int_vref) {
299131497acSRicardo Ribalda Delgado 			dev_err(&st->spi->dev,
300131497acSRicardo Ribalda Delgado 				"Voltage reference not found\n");
301131497acSRicardo Ribalda Delgado 			return -EIO;
302131497acSRicardo Ribalda Delgado 		}
303131497acSRicardo Ribalda Delgado 
304131497acSRicardo Ribalda Delgado 		st->use_intref = true;
305131497acSRicardo Ribalda Delgado 		st->vref = chip_info->int_vref;
306131497acSRicardo Ribalda Delgado 		return 0;
307131497acSRicardo Ribalda Delgado 	}
308131497acSRicardo Ribalda Delgado 
309131497acSRicardo Ribalda Delgado 	if (IS_ERR(st->vref_reg)) {
310131497acSRicardo Ribalda Delgado 		dev_err(&st->spi->dev,
311131497acSRicardo Ribalda Delgado 			"Error getting voltage reference regulator\n");
312131497acSRicardo Ribalda Delgado 		return PTR_ERR(st->vref_reg);
313131497acSRicardo Ribalda Delgado 	}
314131497acSRicardo Ribalda Delgado 
315131497acSRicardo Ribalda Delgado 	ret = regulator_enable(st->vref_reg);
316131497acSRicardo Ribalda Delgado 	if (ret) {
317131497acSRicardo Ribalda Delgado 		dev_err(&st->spi->dev,
318131497acSRicardo Ribalda Delgado 			 "Failed to enable voltage reference\n");
319131497acSRicardo Ribalda Delgado 		return ret;
320131497acSRicardo Ribalda Delgado 	}
321131497acSRicardo Ribalda Delgado 
322131497acSRicardo Ribalda Delgado 	ret = regulator_get_voltage(st->vref_reg);
323131497acSRicardo Ribalda Delgado 	if (ret < 0) {
324131497acSRicardo Ribalda Delgado 		dev_err(&st->spi->dev,
325131497acSRicardo Ribalda Delgado 			 "Failed to get voltage reference value\n");
326131497acSRicardo Ribalda Delgado 		goto disable_regulator_vref;
327131497acSRicardo Ribalda Delgado 	}
328131497acSRicardo Ribalda Delgado 
329131497acSRicardo Ribalda Delgado 	if (ret < 2000000 || ret > 3000000) {
330131497acSRicardo Ribalda Delgado 		dev_warn(&st->spi->dev,
331131497acSRicardo Ribalda Delgado 			 "Invalid external voltage ref. value %d uV\n", ret);
332131497acSRicardo Ribalda Delgado 		ret = -EIO;
333131497acSRicardo Ribalda Delgado 		goto disable_regulator_vref;
334131497acSRicardo Ribalda Delgado 	}
335131497acSRicardo Ribalda Delgado 
336131497acSRicardo Ribalda Delgado 	st->vref = ret / 1000;
337131497acSRicardo Ribalda Delgado 	st->use_intref = false;
338131497acSRicardo Ribalda Delgado 
339131497acSRicardo Ribalda Delgado 	return 0;
340131497acSRicardo Ribalda Delgado 
341131497acSRicardo Ribalda Delgado disable_regulator_vref:
342131497acSRicardo Ribalda Delgado 	regulator_disable(st->vref_reg);
343131497acSRicardo Ribalda Delgado 	st->vref_reg = NULL;
344131497acSRicardo Ribalda Delgado 	return ret;
345131497acSRicardo Ribalda Delgado }
346131497acSRicardo Ribalda Delgado 
ad5761_probe(struct spi_device * spi)347131497acSRicardo Ribalda Delgado static int ad5761_probe(struct spi_device *spi)
348131497acSRicardo Ribalda Delgado {
349131497acSRicardo Ribalda Delgado 	struct iio_dev *iio_dev;
350131497acSRicardo Ribalda Delgado 	struct ad5761_state *st;
351131497acSRicardo Ribalda Delgado 	int ret;
352131497acSRicardo Ribalda Delgado 	const struct ad5761_chip_info *chip_info =
353131497acSRicardo Ribalda Delgado 		&ad5761_chip_infos[spi_get_device_id(spi)->driver_data];
354131497acSRicardo Ribalda Delgado 	enum ad5761_voltage_range voltage_range = AD5761_VOLTAGE_RANGE_0V_5V;
355131497acSRicardo Ribalda Delgado 	struct ad5761_platform_data *pdata = dev_get_platdata(&spi->dev);
356131497acSRicardo Ribalda Delgado 
357131497acSRicardo Ribalda Delgado 	iio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
358131497acSRicardo Ribalda Delgado 	if (!iio_dev)
359131497acSRicardo Ribalda Delgado 		return -ENOMEM;
360131497acSRicardo Ribalda Delgado 
361131497acSRicardo Ribalda Delgado 	st = iio_priv(iio_dev);
362131497acSRicardo Ribalda Delgado 
363131497acSRicardo Ribalda Delgado 	st->spi = spi;
364131497acSRicardo Ribalda Delgado 	spi_set_drvdata(spi, iio_dev);
365131497acSRicardo Ribalda Delgado 
366131497acSRicardo Ribalda Delgado 	ret = ad5761_get_vref(st, chip_info);
367131497acSRicardo Ribalda Delgado 	if (ret)
368131497acSRicardo Ribalda Delgado 		return ret;
369131497acSRicardo Ribalda Delgado 
370131497acSRicardo Ribalda Delgado 	if (pdata)
371131497acSRicardo Ribalda Delgado 		voltage_range = pdata->voltage_range;
372131497acSRicardo Ribalda Delgado 
37319710bffSSergiu Cuciurean 	mutex_init(&st->lock);
37419710bffSSergiu Cuciurean 
375131497acSRicardo Ribalda Delgado 	ret = ad5761_spi_set_range(st, voltage_range);
376131497acSRicardo Ribalda Delgado 	if (ret)
377131497acSRicardo Ribalda Delgado 		goto disable_regulator_err;
378131497acSRicardo Ribalda Delgado 
379131497acSRicardo Ribalda Delgado 	iio_dev->info = &ad5761_info;
380131497acSRicardo Ribalda Delgado 	iio_dev->modes = INDIO_DIRECT_MODE;
381131497acSRicardo Ribalda Delgado 	iio_dev->channels = &chip_info->channel;
382131497acSRicardo Ribalda Delgado 	iio_dev->num_channels = 1;
383131497acSRicardo Ribalda Delgado 	iio_dev->name = spi_get_device_id(st->spi)->name;
384131497acSRicardo Ribalda Delgado 	ret = iio_device_register(iio_dev);
385131497acSRicardo Ribalda Delgado 	if (ret)
386131497acSRicardo Ribalda Delgado 		goto disable_regulator_err;
387131497acSRicardo Ribalda Delgado 
388131497acSRicardo Ribalda Delgado 	return 0;
389131497acSRicardo Ribalda Delgado 
390131497acSRicardo Ribalda Delgado disable_regulator_err:
391131497acSRicardo Ribalda Delgado 	if (!IS_ERR_OR_NULL(st->vref_reg))
392131497acSRicardo Ribalda Delgado 		regulator_disable(st->vref_reg);
393131497acSRicardo Ribalda Delgado 
394131497acSRicardo Ribalda Delgado 	return ret;
395131497acSRicardo Ribalda Delgado }
396131497acSRicardo Ribalda Delgado 
ad5761_remove(struct spi_device * spi)397a0386bbaSUwe Kleine-König static void ad5761_remove(struct spi_device *spi)
398131497acSRicardo Ribalda Delgado {
399131497acSRicardo Ribalda Delgado 	struct iio_dev *iio_dev = spi_get_drvdata(spi);
400131497acSRicardo Ribalda Delgado 	struct ad5761_state *st = iio_priv(iio_dev);
401131497acSRicardo Ribalda Delgado 
402131497acSRicardo Ribalda Delgado 	iio_device_unregister(iio_dev);
403131497acSRicardo Ribalda Delgado 
404131497acSRicardo Ribalda Delgado 	if (!IS_ERR_OR_NULL(st->vref_reg))
405131497acSRicardo Ribalda Delgado 		regulator_disable(st->vref_reg);
406131497acSRicardo Ribalda Delgado }
407131497acSRicardo Ribalda Delgado 
408131497acSRicardo Ribalda Delgado static const struct spi_device_id ad5761_id[] = {
409131497acSRicardo Ribalda Delgado 	{"ad5721", ID_AD5721},
410131497acSRicardo Ribalda Delgado 	{"ad5721r", ID_AD5721R},
411131497acSRicardo Ribalda Delgado 	{"ad5761", ID_AD5761},
412131497acSRicardo Ribalda Delgado 	{"ad5761r", ID_AD5761R},
413131497acSRicardo Ribalda Delgado 	{}
414131497acSRicardo Ribalda Delgado };
415131497acSRicardo Ribalda Delgado MODULE_DEVICE_TABLE(spi, ad5761_id);
416131497acSRicardo Ribalda Delgado 
417131497acSRicardo Ribalda Delgado static struct spi_driver ad5761_driver = {
418131497acSRicardo Ribalda Delgado 	.driver = {
419131497acSRicardo Ribalda Delgado 		   .name = "ad5761",
420131497acSRicardo Ribalda Delgado 		   },
421131497acSRicardo Ribalda Delgado 	.probe = ad5761_probe,
422131497acSRicardo Ribalda Delgado 	.remove = ad5761_remove,
423131497acSRicardo Ribalda Delgado 	.id_table = ad5761_id,
424131497acSRicardo Ribalda Delgado };
425131497acSRicardo Ribalda Delgado module_spi_driver(ad5761_driver);
426131497acSRicardo Ribalda Delgado 
427cea0fad0SRicardo Ribalda Delgado MODULE_AUTHOR("Ricardo Ribalda <ribalda@kernel.org>");
428131497acSRicardo Ribalda Delgado MODULE_DESCRIPTION("Analog Devices AD5721, AD5721R, AD5761, AD5761R driver");
429131497acSRicardo Ribalda Delgado MODULE_LICENSE("GPL v2");
430