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