xref: /openbmc/linux/drivers/iio/dac/ltc2688.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1832cb9eeSNuno Sá // SPDX-License-Identifier: GPL-2.0
2832cb9eeSNuno Sá /*
3832cb9eeSNuno Sá  * LTC2688 16 channel, 16 bit Voltage Output SoftSpan DAC driver
4832cb9eeSNuno Sá  *
5832cb9eeSNuno Sá  * Copyright 2022 Analog Devices Inc.
6832cb9eeSNuno Sá  */
7832cb9eeSNuno Sá #include <linux/bitfield.h>
8832cb9eeSNuno Sá #include <linux/bits.h>
9832cb9eeSNuno Sá #include <linux/clk.h>
10832cb9eeSNuno Sá #include <linux/device.h>
11832cb9eeSNuno Sá #include <linux/gpio/consumer.h>
12832cb9eeSNuno Sá #include <linux/iio/iio.h>
13832cb9eeSNuno Sá #include <linux/limits.h>
14832cb9eeSNuno Sá #include <linux/kernel.h>
15832cb9eeSNuno Sá #include <linux/module.h>
16832cb9eeSNuno Sá #include <linux/mod_devicetable.h>
17832cb9eeSNuno Sá #include <linux/mutex.h>
18832cb9eeSNuno Sá #include <linux/of.h>
19832cb9eeSNuno Sá #include <linux/property.h>
20832cb9eeSNuno Sá #include <linux/regmap.h>
21832cb9eeSNuno Sá #include <linux/regulator/consumer.h>
22832cb9eeSNuno Sá #include <linux/spi/spi.h>
23832cb9eeSNuno Sá 
24832cb9eeSNuno Sá #define LTC2688_DAC_CHANNELS			16
25832cb9eeSNuno Sá 
26832cb9eeSNuno Sá #define LTC2688_CMD_CH_CODE(x)			(0x00 + (x))
27832cb9eeSNuno Sá #define LTC2688_CMD_CH_SETTING(x)		(0x10 + (x))
28832cb9eeSNuno Sá #define LTC2688_CMD_CH_OFFSET(x)		(0X20 + (x))
29832cb9eeSNuno Sá #define LTC2688_CMD_CH_GAIN(x)			(0x30 + (x))
30832cb9eeSNuno Sá #define LTC2688_CMD_CH_CODE_UPDATE(x)		(0x40 + (x))
31832cb9eeSNuno Sá 
32832cb9eeSNuno Sá #define LTC2688_CMD_CONFIG			0x70
33832cb9eeSNuno Sá #define LTC2688_CMD_POWERDOWN			0x71
34832cb9eeSNuno Sá #define LTC2688_CMD_A_B_SELECT			0x72
35832cb9eeSNuno Sá #define LTC2688_CMD_SW_TOGGLE			0x73
36832cb9eeSNuno Sá #define LTC2688_CMD_TOGGLE_DITHER_EN		0x74
37832cb9eeSNuno Sá #define LTC2688_CMD_THERMAL_STAT		0x77
38832cb9eeSNuno Sá #define LTC2688_CMD_UPDATE_ALL			0x7C
39832cb9eeSNuno Sá #define LTC2688_CMD_NOOP			0xFF
40832cb9eeSNuno Sá 
41832cb9eeSNuno Sá #define LTC2688_READ_OPERATION			0x80
42832cb9eeSNuno Sá 
43832cb9eeSNuno Sá /* Channel Settings */
44832cb9eeSNuno Sá #define LTC2688_CH_SPAN_MSK			GENMASK(2, 0)
45832cb9eeSNuno Sá #define LTC2688_CH_OVERRANGE_MSK		BIT(3)
46832cb9eeSNuno Sá #define LTC2688_CH_TD_SEL_MSK			GENMASK(5, 4)
47832cb9eeSNuno Sá #define LTC2688_CH_TGP_MAX			3
48832cb9eeSNuno Sá #define LTC2688_CH_DIT_PER_MSK			GENMASK(8, 6)
49832cb9eeSNuno Sá #define LTC2688_CH_DIT_PH_MSK			GENMASK(10, 9)
50832cb9eeSNuno Sá #define LTC2688_CH_MODE_MSK			BIT(11)
51832cb9eeSNuno Sá 
52832cb9eeSNuno Sá #define LTC2688_DITHER_RAW_MASK			GENMASK(15, 2)
53832cb9eeSNuno Sá #define LTC2688_CH_CALIBBIAS_MASK		GENMASK(15, 2)
54832cb9eeSNuno Sá #define LTC2688_DITHER_RAW_MAX_VAL		(BIT(14) - 1)
55832cb9eeSNuno Sá #define LTC2688_CH_CALIBBIAS_MAX_VAL		(BIT(14) - 1)
56832cb9eeSNuno Sá 
57832cb9eeSNuno Sá /* Configuration register */
58832cb9eeSNuno Sá #define LTC2688_CONFIG_RST			BIT(15)
59832cb9eeSNuno Sá #define LTC2688_CONFIG_EXT_REF			BIT(1)
60832cb9eeSNuno Sá 
61832cb9eeSNuno Sá #define LTC2688_DITHER_FREQ_AVAIL_N		5
62832cb9eeSNuno Sá 
63832cb9eeSNuno Sá enum {
64832cb9eeSNuno Sá 	LTC2688_SPAN_RANGE_0V_5V,
65832cb9eeSNuno Sá 	LTC2688_SPAN_RANGE_0V_10V,
66832cb9eeSNuno Sá 	LTC2688_SPAN_RANGE_M5V_5V,
67832cb9eeSNuno Sá 	LTC2688_SPAN_RANGE_M10V_10V,
68832cb9eeSNuno Sá 	LTC2688_SPAN_RANGE_M15V_15V,
69832cb9eeSNuno Sá 	LTC2688_SPAN_RANGE_MAX
70832cb9eeSNuno Sá };
71832cb9eeSNuno Sá 
72832cb9eeSNuno Sá enum {
73832cb9eeSNuno Sá 	LTC2688_MODE_DEFAULT,
74832cb9eeSNuno Sá 	LTC2688_MODE_DITHER_TOGGLE,
75832cb9eeSNuno Sá };
76832cb9eeSNuno Sá 
77832cb9eeSNuno Sá struct ltc2688_chan {
78832cb9eeSNuno Sá 	long dither_frequency[LTC2688_DITHER_FREQ_AVAIL_N];
79832cb9eeSNuno Sá 	bool overrange;
80832cb9eeSNuno Sá 	bool toggle_chan;
81832cb9eeSNuno Sá 	u8 mode;
82832cb9eeSNuno Sá };
83832cb9eeSNuno Sá 
84832cb9eeSNuno Sá struct ltc2688_state {
85832cb9eeSNuno Sá 	struct spi_device *spi;
86832cb9eeSNuno Sá 	struct regmap *regmap;
87832cb9eeSNuno Sá 	struct ltc2688_chan channels[LTC2688_DAC_CHANNELS];
88832cb9eeSNuno Sá 	struct iio_chan_spec *iio_chan;
89832cb9eeSNuno Sá 	/* lock to protect against multiple access to the device and shared data */
90832cb9eeSNuno Sá 	struct mutex lock;
91832cb9eeSNuno Sá 	int vref;
92832cb9eeSNuno Sá 	/*
9320307083SJonathan Cameron 	 * DMA (thus cache coherency maintenance) may require the
94832cb9eeSNuno Sá 	 * transfer buffers to live in their own cache lines.
95832cb9eeSNuno Sá 	 */
9620307083SJonathan Cameron 	u8 tx_data[6] __aligned(IIO_DMA_MINALIGN);
97832cb9eeSNuno Sá 	u8 rx_data[3];
98832cb9eeSNuno Sá };
99832cb9eeSNuno Sá 
ltc2688_spi_read(void * context,const void * reg,size_t reg_size,void * val,size_t val_size)100832cb9eeSNuno Sá static int ltc2688_spi_read(void *context, const void *reg, size_t reg_size,
101832cb9eeSNuno Sá 			    void *val, size_t val_size)
102832cb9eeSNuno Sá {
103832cb9eeSNuno Sá 	struct ltc2688_state *st = context;
104832cb9eeSNuno Sá 	struct spi_transfer xfers[] = {
105832cb9eeSNuno Sá 		{
106832cb9eeSNuno Sá 			.tx_buf = st->tx_data,
107832cb9eeSNuno Sá 			.bits_per_word = 8,
108832cb9eeSNuno Sá 			.len = reg_size + val_size,
109832cb9eeSNuno Sá 			.cs_change = 1,
110832cb9eeSNuno Sá 		}, {
111832cb9eeSNuno Sá 			.tx_buf = st->tx_data + 3,
112832cb9eeSNuno Sá 			.rx_buf = st->rx_data,
113832cb9eeSNuno Sá 			.bits_per_word = 8,
114832cb9eeSNuno Sá 			.len = reg_size + val_size,
115832cb9eeSNuno Sá 		},
116832cb9eeSNuno Sá 	};
117832cb9eeSNuno Sá 	int ret;
118832cb9eeSNuno Sá 
119832cb9eeSNuno Sá 	memcpy(st->tx_data, reg, reg_size);
120832cb9eeSNuno Sá 
121832cb9eeSNuno Sá 	ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
122832cb9eeSNuno Sá 	if (ret)
123832cb9eeSNuno Sá 		return ret;
124832cb9eeSNuno Sá 
125832cb9eeSNuno Sá 	memcpy(val, &st->rx_data[1], val_size);
126832cb9eeSNuno Sá 
127832cb9eeSNuno Sá 	return 0;
128832cb9eeSNuno Sá }
129832cb9eeSNuno Sá 
ltc2688_spi_write(void * context,const void * data,size_t count)130832cb9eeSNuno Sá static int ltc2688_spi_write(void *context, const void *data, size_t count)
131832cb9eeSNuno Sá {
132832cb9eeSNuno Sá 	struct ltc2688_state *st = context;
133832cb9eeSNuno Sá 
134832cb9eeSNuno Sá 	return spi_write(st->spi, data, count);
135832cb9eeSNuno Sá }
136832cb9eeSNuno Sá 
ltc2688_span_get(const struct ltc2688_state * st,int c)137832cb9eeSNuno Sá static int ltc2688_span_get(const struct ltc2688_state *st, int c)
138832cb9eeSNuno Sá {
139832cb9eeSNuno Sá 	int ret, reg, span;
140832cb9eeSNuno Sá 
141832cb9eeSNuno Sá 	ret = regmap_read(st->regmap, LTC2688_CMD_CH_SETTING(c), &reg);
142832cb9eeSNuno Sá 	if (ret)
143832cb9eeSNuno Sá 		return ret;
144832cb9eeSNuno Sá 
145832cb9eeSNuno Sá 	span = FIELD_GET(LTC2688_CH_SPAN_MSK, reg);
146832cb9eeSNuno Sá 	/* sanity check to make sure we don't get any weird value from the HW */
147832cb9eeSNuno Sá 	if (span >= LTC2688_SPAN_RANGE_MAX)
148832cb9eeSNuno Sá 		return -EIO;
149832cb9eeSNuno Sá 
150832cb9eeSNuno Sá 	return span;
151832cb9eeSNuno Sá }
152832cb9eeSNuno Sá 
153832cb9eeSNuno Sá static const int ltc2688_span_helper[LTC2688_SPAN_RANGE_MAX][2] = {
154832cb9eeSNuno Sá 	{0, 5000}, {0, 10000}, {-5000, 5000}, {-10000, 10000}, {-15000, 15000},
155832cb9eeSNuno Sá };
156832cb9eeSNuno Sá 
ltc2688_scale_get(const struct ltc2688_state * st,int c,int * val)157832cb9eeSNuno Sá static int ltc2688_scale_get(const struct ltc2688_state *st, int c, int *val)
158832cb9eeSNuno Sá {
159832cb9eeSNuno Sá 	const struct ltc2688_chan *chan = &st->channels[c];
160832cb9eeSNuno Sá 	int span, fs;
161832cb9eeSNuno Sá 
162832cb9eeSNuno Sá 	span = ltc2688_span_get(st, c);
163832cb9eeSNuno Sá 	if (span < 0)
164832cb9eeSNuno Sá 		return span;
165832cb9eeSNuno Sá 
166832cb9eeSNuno Sá 	fs = ltc2688_span_helper[span][1] - ltc2688_span_helper[span][0];
167832cb9eeSNuno Sá 	if (chan->overrange)
168832cb9eeSNuno Sá 		fs = mult_frac(fs, 105, 100);
169832cb9eeSNuno Sá 
170832cb9eeSNuno Sá 	*val = DIV_ROUND_CLOSEST(fs * st->vref, 4096);
171832cb9eeSNuno Sá 
172832cb9eeSNuno Sá 	return 0;
173832cb9eeSNuno Sá }
174832cb9eeSNuno Sá 
ltc2688_offset_get(const struct ltc2688_state * st,int c,int * val)175832cb9eeSNuno Sá static int ltc2688_offset_get(const struct ltc2688_state *st, int c, int *val)
176832cb9eeSNuno Sá {
177832cb9eeSNuno Sá 	int span;
178832cb9eeSNuno Sá 
179832cb9eeSNuno Sá 	span = ltc2688_span_get(st, c);
180832cb9eeSNuno Sá 	if (span < 0)
181832cb9eeSNuno Sá 		return span;
182832cb9eeSNuno Sá 
183832cb9eeSNuno Sá 	if (ltc2688_span_helper[span][0] < 0)
184832cb9eeSNuno Sá 		*val = -32768;
185832cb9eeSNuno Sá 	else
186832cb9eeSNuno Sá 		*val = 0;
187832cb9eeSNuno Sá 
188832cb9eeSNuno Sá 	return 0;
189832cb9eeSNuno Sá }
190832cb9eeSNuno Sá 
191832cb9eeSNuno Sá enum {
192832cb9eeSNuno Sá 	LTC2688_INPUT_A,
193832cb9eeSNuno Sá 	LTC2688_INPUT_B,
194832cb9eeSNuno Sá 	LTC2688_INPUT_B_AVAIL,
195832cb9eeSNuno Sá 	LTC2688_DITHER_OFF,
196832cb9eeSNuno Sá 	LTC2688_DITHER_FREQ_AVAIL,
197832cb9eeSNuno Sá };
198832cb9eeSNuno Sá 
ltc2688_dac_code_write(struct ltc2688_state * st,u32 chan,u32 input,u16 code)199832cb9eeSNuno Sá static int ltc2688_dac_code_write(struct ltc2688_state *st, u32 chan, u32 input,
200832cb9eeSNuno Sá 				  u16 code)
201832cb9eeSNuno Sá {
202832cb9eeSNuno Sá 	struct ltc2688_chan *c = &st->channels[chan];
203832cb9eeSNuno Sá 	int ret, reg;
204832cb9eeSNuno Sá 
205832cb9eeSNuno Sá 	/* 2 LSBs set to 0 if writing dither amplitude */
206832cb9eeSNuno Sá 	if (!c->toggle_chan && input == LTC2688_INPUT_B) {
207832cb9eeSNuno Sá 		if (code > LTC2688_DITHER_RAW_MAX_VAL)
208832cb9eeSNuno Sá 			return -EINVAL;
209832cb9eeSNuno Sá 
210832cb9eeSNuno Sá 		code = FIELD_PREP(LTC2688_DITHER_RAW_MASK, code);
211832cb9eeSNuno Sá 	}
212832cb9eeSNuno Sá 
213832cb9eeSNuno Sá 	mutex_lock(&st->lock);
214832cb9eeSNuno Sá 	/* select the correct input register to read from */
215832cb9eeSNuno Sá 	ret = regmap_update_bits(st->regmap, LTC2688_CMD_A_B_SELECT, BIT(chan),
216832cb9eeSNuno Sá 				 input << chan);
217832cb9eeSNuno Sá 	if (ret)
218832cb9eeSNuno Sá 		goto out_unlock;
219832cb9eeSNuno Sá 
220832cb9eeSNuno Sá 	/*
221832cb9eeSNuno Sá 	 * If in dither/toggle mode the dac should be updated by an
222832cb9eeSNuno Sá 	 * external signal (or sw toggle) and not here.
223832cb9eeSNuno Sá 	 */
224832cb9eeSNuno Sá 	if (c->mode == LTC2688_MODE_DEFAULT)
225832cb9eeSNuno Sá 		reg = LTC2688_CMD_CH_CODE_UPDATE(chan);
226832cb9eeSNuno Sá 	else
227832cb9eeSNuno Sá 		reg = LTC2688_CMD_CH_CODE(chan);
228832cb9eeSNuno Sá 
229832cb9eeSNuno Sá 	ret = regmap_write(st->regmap, reg, code);
230832cb9eeSNuno Sá out_unlock:
231832cb9eeSNuno Sá 	mutex_unlock(&st->lock);
232832cb9eeSNuno Sá 	return ret;
233832cb9eeSNuno Sá }
234832cb9eeSNuno Sá 
ltc2688_dac_code_read(struct ltc2688_state * st,u32 chan,u32 input,u32 * code)235832cb9eeSNuno Sá static int ltc2688_dac_code_read(struct ltc2688_state *st, u32 chan, u32 input,
236832cb9eeSNuno Sá 				 u32 *code)
237832cb9eeSNuno Sá {
238832cb9eeSNuno Sá 	struct ltc2688_chan *c = &st->channels[chan];
239832cb9eeSNuno Sá 	int ret;
240832cb9eeSNuno Sá 
241832cb9eeSNuno Sá 	mutex_lock(&st->lock);
242832cb9eeSNuno Sá 	ret = regmap_update_bits(st->regmap, LTC2688_CMD_A_B_SELECT, BIT(chan),
243832cb9eeSNuno Sá 				 input << chan);
244832cb9eeSNuno Sá 	if (ret)
245832cb9eeSNuno Sá 		goto out_unlock;
246832cb9eeSNuno Sá 
247832cb9eeSNuno Sá 	ret = regmap_read(st->regmap, LTC2688_CMD_CH_CODE(chan), code);
248832cb9eeSNuno Sá out_unlock:
249832cb9eeSNuno Sá 	mutex_unlock(&st->lock);
250832cb9eeSNuno Sá 
251832cb9eeSNuno Sá 	if (!c->toggle_chan && input == LTC2688_INPUT_B)
252832cb9eeSNuno Sá 		*code = FIELD_GET(LTC2688_DITHER_RAW_MASK, *code);
253832cb9eeSNuno Sá 
254832cb9eeSNuno Sá 	return ret;
255832cb9eeSNuno Sá }
256832cb9eeSNuno Sá 
257832cb9eeSNuno Sá static const int ltc2688_raw_range[] = {0, 1, U16_MAX};
258832cb9eeSNuno Sá 
ltc2688_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long info)259832cb9eeSNuno Sá static int ltc2688_read_avail(struct iio_dev *indio_dev,
260832cb9eeSNuno Sá 			      struct iio_chan_spec const *chan,
261832cb9eeSNuno Sá 			      const int **vals, int *type, int *length,
262832cb9eeSNuno Sá 			      long info)
263832cb9eeSNuno Sá {
264832cb9eeSNuno Sá 	switch (info) {
265832cb9eeSNuno Sá 	case IIO_CHAN_INFO_RAW:
266832cb9eeSNuno Sá 		*vals = ltc2688_raw_range;
267832cb9eeSNuno Sá 		*type = IIO_VAL_INT;
268832cb9eeSNuno Sá 		return IIO_AVAIL_RANGE;
269832cb9eeSNuno Sá 	default:
270832cb9eeSNuno Sá 		return -EINVAL;
271832cb9eeSNuno Sá 	}
272832cb9eeSNuno Sá }
273832cb9eeSNuno Sá 
ltc2688_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long info)274832cb9eeSNuno Sá static int ltc2688_read_raw(struct iio_dev *indio_dev,
275832cb9eeSNuno Sá 			    struct iio_chan_spec const *chan, int *val,
276832cb9eeSNuno Sá 			    int *val2, long info)
277832cb9eeSNuno Sá {
278832cb9eeSNuno Sá 	struct ltc2688_state *st = iio_priv(indio_dev);
279832cb9eeSNuno Sá 	int ret;
280832cb9eeSNuno Sá 
281832cb9eeSNuno Sá 	switch (info) {
282832cb9eeSNuno Sá 	case IIO_CHAN_INFO_RAW:
283832cb9eeSNuno Sá 		ret = ltc2688_dac_code_read(st, chan->channel, LTC2688_INPUT_A,
284832cb9eeSNuno Sá 					    val);
285832cb9eeSNuno Sá 		if (ret)
286832cb9eeSNuno Sá 			return ret;
287832cb9eeSNuno Sá 
288832cb9eeSNuno Sá 		return IIO_VAL_INT;
289832cb9eeSNuno Sá 	case IIO_CHAN_INFO_OFFSET:
290832cb9eeSNuno Sá 		ret = ltc2688_offset_get(st, chan->channel, val);
291832cb9eeSNuno Sá 		if (ret)
292832cb9eeSNuno Sá 			return ret;
293832cb9eeSNuno Sá 
294832cb9eeSNuno Sá 		return IIO_VAL_INT;
295832cb9eeSNuno Sá 	case IIO_CHAN_INFO_SCALE:
296832cb9eeSNuno Sá 		ret = ltc2688_scale_get(st, chan->channel, val);
297832cb9eeSNuno Sá 		if (ret)
298832cb9eeSNuno Sá 			return ret;
299832cb9eeSNuno Sá 
300e7e51eb0SNuno Sá 		*val2 = 16;
301832cb9eeSNuno Sá 		return IIO_VAL_FRACTIONAL_LOG2;
302832cb9eeSNuno Sá 	case IIO_CHAN_INFO_CALIBBIAS:
303832cb9eeSNuno Sá 		ret = regmap_read(st->regmap,
304832cb9eeSNuno Sá 				  LTC2688_CMD_CH_OFFSET(chan->channel), val);
305832cb9eeSNuno Sá 		if (ret)
306832cb9eeSNuno Sá 			return ret;
307832cb9eeSNuno Sá 
308832cb9eeSNuno Sá 		*val = FIELD_GET(LTC2688_CH_CALIBBIAS_MASK, *val);
309832cb9eeSNuno Sá 		return IIO_VAL_INT;
310832cb9eeSNuno Sá 	case IIO_CHAN_INFO_CALIBSCALE:
311832cb9eeSNuno Sá 		ret = regmap_read(st->regmap,
312832cb9eeSNuno Sá 				  LTC2688_CMD_CH_GAIN(chan->channel), val);
313832cb9eeSNuno Sá 		if (ret)
314832cb9eeSNuno Sá 			return ret;
315832cb9eeSNuno Sá 
316832cb9eeSNuno Sá 		return IIO_VAL_INT;
317832cb9eeSNuno Sá 	default:
318832cb9eeSNuno Sá 		return -EINVAL;
319832cb9eeSNuno Sá 	}
320832cb9eeSNuno Sá }
321832cb9eeSNuno Sá 
ltc2688_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long info)322832cb9eeSNuno Sá static int ltc2688_write_raw(struct iio_dev *indio_dev,
323832cb9eeSNuno Sá 			     struct iio_chan_spec const *chan, int val,
324832cb9eeSNuno Sá 			     int val2, long info)
325832cb9eeSNuno Sá {
326832cb9eeSNuno Sá 	struct ltc2688_state *st = iio_priv(indio_dev);
327832cb9eeSNuno Sá 
328832cb9eeSNuno Sá 	switch (info) {
329832cb9eeSNuno Sá 	case IIO_CHAN_INFO_RAW:
330832cb9eeSNuno Sá 		if (val > U16_MAX || val < 0)
331832cb9eeSNuno Sá 			return -EINVAL;
332832cb9eeSNuno Sá 
333832cb9eeSNuno Sá 		return ltc2688_dac_code_write(st, chan->channel,
334832cb9eeSNuno Sá 					      LTC2688_INPUT_A, val);
335832cb9eeSNuno Sá 	case IIO_CHAN_INFO_CALIBBIAS:
336832cb9eeSNuno Sá 		if (val > LTC2688_CH_CALIBBIAS_MAX_VAL)
337832cb9eeSNuno Sá 			return -EINVAL;
338832cb9eeSNuno Sá 
339832cb9eeSNuno Sá 		return regmap_write(st->regmap,
340832cb9eeSNuno Sá 				    LTC2688_CMD_CH_OFFSET(chan->channel),
341832cb9eeSNuno Sá 				    FIELD_PREP(LTC2688_CH_CALIBBIAS_MASK, val));
342832cb9eeSNuno Sá 	case IIO_CHAN_INFO_CALIBSCALE:
343832cb9eeSNuno Sá 		return regmap_write(st->regmap,
344832cb9eeSNuno Sá 				    LTC2688_CMD_CH_GAIN(chan->channel), val);
345832cb9eeSNuno Sá 	default:
346832cb9eeSNuno Sá 		return -EINVAL;
347832cb9eeSNuno Sá 	}
348832cb9eeSNuno Sá }
349832cb9eeSNuno Sá 
ltc2688_dither_toggle_set(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,const char * buf,size_t len)350832cb9eeSNuno Sá static ssize_t ltc2688_dither_toggle_set(struct iio_dev *indio_dev,
351832cb9eeSNuno Sá 					 uintptr_t private,
352832cb9eeSNuno Sá 					 const struct iio_chan_spec *chan,
353832cb9eeSNuno Sá 					 const char *buf, size_t len)
354832cb9eeSNuno Sá {
355832cb9eeSNuno Sá 	struct ltc2688_state *st = iio_priv(indio_dev);
356832cb9eeSNuno Sá 	struct ltc2688_chan *c = &st->channels[chan->channel];
357832cb9eeSNuno Sá 	int ret;
358832cb9eeSNuno Sá 	bool en;
359832cb9eeSNuno Sá 
360832cb9eeSNuno Sá 	ret = kstrtobool(buf, &en);
361832cb9eeSNuno Sá 	if (ret)
362832cb9eeSNuno Sá 		return ret;
363832cb9eeSNuno Sá 
364832cb9eeSNuno Sá 	mutex_lock(&st->lock);
365832cb9eeSNuno Sá 	ret = regmap_update_bits(st->regmap, LTC2688_CMD_TOGGLE_DITHER_EN,
366832cb9eeSNuno Sá 				 BIT(chan->channel), en << chan->channel);
367832cb9eeSNuno Sá 	if (ret)
368832cb9eeSNuno Sá 		goto out_unlock;
369832cb9eeSNuno Sá 
370832cb9eeSNuno Sá 	c->mode = en ? LTC2688_MODE_DITHER_TOGGLE : LTC2688_MODE_DEFAULT;
371832cb9eeSNuno Sá out_unlock:
372832cb9eeSNuno Sá 	mutex_unlock(&st->lock);
373832cb9eeSNuno Sá 
374832cb9eeSNuno Sá 	return ret ?: len;
375832cb9eeSNuno Sá }
376832cb9eeSNuno Sá 
ltc2688_reg_bool_get(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,char * buf)377832cb9eeSNuno Sá static ssize_t ltc2688_reg_bool_get(struct iio_dev *indio_dev,
378832cb9eeSNuno Sá 				    uintptr_t private,
379832cb9eeSNuno Sá 				    const struct iio_chan_spec *chan,
380832cb9eeSNuno Sá 				    char *buf)
381832cb9eeSNuno Sá {
382832cb9eeSNuno Sá 	const struct ltc2688_state *st = iio_priv(indio_dev);
383832cb9eeSNuno Sá 	int ret;
384832cb9eeSNuno Sá 	u32 val;
385832cb9eeSNuno Sá 
386832cb9eeSNuno Sá 	ret = regmap_read(st->regmap, private, &val);
387832cb9eeSNuno Sá 	if (ret)
388832cb9eeSNuno Sá 		return ret;
389832cb9eeSNuno Sá 
390832cb9eeSNuno Sá 	return sysfs_emit(buf, "%u\n", !!(val & BIT(chan->channel)));
391832cb9eeSNuno Sá }
392832cb9eeSNuno Sá 
ltc2688_reg_bool_set(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,const char * buf,size_t len)393832cb9eeSNuno Sá static ssize_t ltc2688_reg_bool_set(struct iio_dev *indio_dev,
394832cb9eeSNuno Sá 				    uintptr_t private,
395832cb9eeSNuno Sá 				    const struct iio_chan_spec *chan,
396832cb9eeSNuno Sá 				    const char *buf, size_t len)
397832cb9eeSNuno Sá {
398832cb9eeSNuno Sá 	const struct ltc2688_state *st = iio_priv(indio_dev);
399832cb9eeSNuno Sá 	int ret;
400832cb9eeSNuno Sá 	bool en;
401832cb9eeSNuno Sá 
402832cb9eeSNuno Sá 	ret = kstrtobool(buf, &en);
403832cb9eeSNuno Sá 	if (ret)
404832cb9eeSNuno Sá 		return ret;
405832cb9eeSNuno Sá 
406832cb9eeSNuno Sá 	ret = regmap_update_bits(st->regmap, private, BIT(chan->channel),
407832cb9eeSNuno Sá 				 en << chan->channel);
408832cb9eeSNuno Sá 	if (ret)
409832cb9eeSNuno Sá 		return ret;
410832cb9eeSNuno Sá 
411832cb9eeSNuno Sá 	return len;
412832cb9eeSNuno Sá }
413832cb9eeSNuno Sá 
ltc2688_dither_freq_avail(const struct ltc2688_state * st,const struct ltc2688_chan * chan,char * buf)414832cb9eeSNuno Sá static ssize_t ltc2688_dither_freq_avail(const struct ltc2688_state *st,
415832cb9eeSNuno Sá 					 const struct ltc2688_chan *chan,
416832cb9eeSNuno Sá 					 char *buf)
417832cb9eeSNuno Sá {
418832cb9eeSNuno Sá 	int sz = 0;
419832cb9eeSNuno Sá 	u32 f;
420832cb9eeSNuno Sá 
421832cb9eeSNuno Sá 	for (f = 0; f < ARRAY_SIZE(chan->dither_frequency); f++)
422832cb9eeSNuno Sá 		sz += sysfs_emit_at(buf, sz, "%ld ", chan->dither_frequency[f]);
423832cb9eeSNuno Sá 
424832cb9eeSNuno Sá 	buf[sz - 1] = '\n';
425832cb9eeSNuno Sá 
426832cb9eeSNuno Sá 	return sz;
427832cb9eeSNuno Sá }
428832cb9eeSNuno Sá 
ltc2688_dither_freq_get(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,char * buf)429832cb9eeSNuno Sá static ssize_t ltc2688_dither_freq_get(struct iio_dev *indio_dev,
430832cb9eeSNuno Sá 				       uintptr_t private,
431832cb9eeSNuno Sá 				       const struct iio_chan_spec *chan,
432832cb9eeSNuno Sá 				       char *buf)
433832cb9eeSNuno Sá {
434832cb9eeSNuno Sá 	const struct ltc2688_state *st = iio_priv(indio_dev);
435832cb9eeSNuno Sá 	const struct ltc2688_chan *c = &st->channels[chan->channel];
436832cb9eeSNuno Sá 	u32 reg, freq;
437832cb9eeSNuno Sá 	int ret;
438832cb9eeSNuno Sá 
439832cb9eeSNuno Sá 	if (private == LTC2688_DITHER_FREQ_AVAIL)
440832cb9eeSNuno Sá 		return ltc2688_dither_freq_avail(st, c, buf);
441832cb9eeSNuno Sá 
442832cb9eeSNuno Sá 	ret = regmap_read(st->regmap, LTC2688_CMD_CH_SETTING(chan->channel),
443832cb9eeSNuno Sá 			  &reg);
444832cb9eeSNuno Sá 	if (ret)
445832cb9eeSNuno Sá 		return ret;
446832cb9eeSNuno Sá 
447832cb9eeSNuno Sá 	freq = FIELD_GET(LTC2688_CH_DIT_PER_MSK, reg);
448832cb9eeSNuno Sá 	if (freq >= ARRAY_SIZE(c->dither_frequency))
449832cb9eeSNuno Sá 		return -EIO;
450832cb9eeSNuno Sá 
451832cb9eeSNuno Sá 	return sysfs_emit(buf, "%ld\n", c->dither_frequency[freq]);
452832cb9eeSNuno Sá }
453832cb9eeSNuno Sá 
ltc2688_dither_freq_set(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,const char * buf,size_t len)454832cb9eeSNuno Sá static ssize_t ltc2688_dither_freq_set(struct iio_dev *indio_dev,
455832cb9eeSNuno Sá 				       uintptr_t private,
456832cb9eeSNuno Sá 				       const struct iio_chan_spec *chan,
457832cb9eeSNuno Sá 				       const char *buf, size_t len)
458832cb9eeSNuno Sá {
459832cb9eeSNuno Sá 	const struct ltc2688_state *st = iio_priv(indio_dev);
460832cb9eeSNuno Sá 	const struct ltc2688_chan *c = &st->channels[chan->channel];
461832cb9eeSNuno Sá 	long val;
462832cb9eeSNuno Sá 	u32 freq;
463832cb9eeSNuno Sá 	int ret;
464832cb9eeSNuno Sá 
465832cb9eeSNuno Sá 	if (private == LTC2688_DITHER_FREQ_AVAIL)
466832cb9eeSNuno Sá 		return -EINVAL;
467832cb9eeSNuno Sá 
468832cb9eeSNuno Sá 	ret = kstrtol(buf, 10, &val);
469832cb9eeSNuno Sá 	if (ret)
470832cb9eeSNuno Sá 		return ret;
471832cb9eeSNuno Sá 
472832cb9eeSNuno Sá 	for (freq = 0; freq < ARRAY_SIZE(c->dither_frequency); freq++) {
473832cb9eeSNuno Sá 		if (val == c->dither_frequency[freq])
474832cb9eeSNuno Sá 			break;
475832cb9eeSNuno Sá 	}
476832cb9eeSNuno Sá 
477832cb9eeSNuno Sá 	if (freq == ARRAY_SIZE(c->dither_frequency))
478832cb9eeSNuno Sá 		return -EINVAL;
479832cb9eeSNuno Sá 
480832cb9eeSNuno Sá 	ret = regmap_update_bits(st->regmap,
481832cb9eeSNuno Sá 				 LTC2688_CMD_CH_SETTING(chan->channel),
482832cb9eeSNuno Sá 				 LTC2688_CH_DIT_PER_MSK,
483832cb9eeSNuno Sá 				 FIELD_PREP(LTC2688_CH_DIT_PER_MSK, freq));
484832cb9eeSNuno Sá 	if (ret)
485832cb9eeSNuno Sá 		return ret;
486832cb9eeSNuno Sá 
487832cb9eeSNuno Sá 	return len;
488832cb9eeSNuno Sá }
489832cb9eeSNuno Sá 
ltc2688_dac_input_read(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,char * buf)490832cb9eeSNuno Sá static ssize_t ltc2688_dac_input_read(struct iio_dev *indio_dev,
491832cb9eeSNuno Sá 				      uintptr_t private,
492832cb9eeSNuno Sá 				      const struct iio_chan_spec *chan,
493832cb9eeSNuno Sá 				      char *buf)
494832cb9eeSNuno Sá {
495832cb9eeSNuno Sá 	struct ltc2688_state *st = iio_priv(indio_dev);
496832cb9eeSNuno Sá 	int ret;
497832cb9eeSNuno Sá 	u32 val;
498832cb9eeSNuno Sá 
499832cb9eeSNuno Sá 	if (private == LTC2688_INPUT_B_AVAIL)
500832cb9eeSNuno Sá 		return sysfs_emit(buf, "[%u %u %u]\n", ltc2688_raw_range[0],
501832cb9eeSNuno Sá 				  ltc2688_raw_range[1],
502832cb9eeSNuno Sá 				  ltc2688_raw_range[2] / 4);
503832cb9eeSNuno Sá 
504832cb9eeSNuno Sá 	if (private == LTC2688_DITHER_OFF)
505832cb9eeSNuno Sá 		return sysfs_emit(buf, "0\n");
506832cb9eeSNuno Sá 
507832cb9eeSNuno Sá 	ret = ltc2688_dac_code_read(st, chan->channel, private, &val);
508832cb9eeSNuno Sá 	if (ret)
509832cb9eeSNuno Sá 		return ret;
510832cb9eeSNuno Sá 
511832cb9eeSNuno Sá 	return sysfs_emit(buf, "%u\n", val);
512832cb9eeSNuno Sá }
513832cb9eeSNuno Sá 
ltc2688_dac_input_write(struct iio_dev * indio_dev,uintptr_t private,const struct iio_chan_spec * chan,const char * buf,size_t len)514832cb9eeSNuno Sá static ssize_t ltc2688_dac_input_write(struct iio_dev *indio_dev,
515832cb9eeSNuno Sá 				       uintptr_t private,
516832cb9eeSNuno Sá 				       const struct iio_chan_spec *chan,
517832cb9eeSNuno Sá 				       const char *buf, size_t len)
518832cb9eeSNuno Sá {
519832cb9eeSNuno Sá 	struct ltc2688_state *st = iio_priv(indio_dev);
520832cb9eeSNuno Sá 	int ret;
521832cb9eeSNuno Sá 	u16 val;
522832cb9eeSNuno Sá 
523832cb9eeSNuno Sá 	if (private == LTC2688_INPUT_B_AVAIL || private == LTC2688_DITHER_OFF)
524832cb9eeSNuno Sá 		return -EINVAL;
525832cb9eeSNuno Sá 
526832cb9eeSNuno Sá 	ret = kstrtou16(buf, 10, &val);
527832cb9eeSNuno Sá 	if (ret)
528832cb9eeSNuno Sá 		return ret;
529832cb9eeSNuno Sá 
530832cb9eeSNuno Sá 	ret = ltc2688_dac_code_write(st, chan->channel, private, val);
531832cb9eeSNuno Sá 	if (ret)
532832cb9eeSNuno Sá 		return ret;
533832cb9eeSNuno Sá 
534832cb9eeSNuno Sá 	return len;
535832cb9eeSNuno Sá }
536832cb9eeSNuno Sá 
ltc2688_get_dither_phase(struct iio_dev * dev,const struct iio_chan_spec * chan)537832cb9eeSNuno Sá static int ltc2688_get_dither_phase(struct iio_dev *dev,
538832cb9eeSNuno Sá 				    const struct iio_chan_spec *chan)
539832cb9eeSNuno Sá {
540832cb9eeSNuno Sá 	struct ltc2688_state *st = iio_priv(dev);
541832cb9eeSNuno Sá 	int ret, regval;
542832cb9eeSNuno Sá 
543832cb9eeSNuno Sá 	ret = regmap_read(st->regmap, LTC2688_CMD_CH_SETTING(chan->channel),
544832cb9eeSNuno Sá 			  &regval);
545832cb9eeSNuno Sá 	if (ret)
546832cb9eeSNuno Sá 		return ret;
547832cb9eeSNuno Sá 
548832cb9eeSNuno Sá 	return FIELD_GET(LTC2688_CH_DIT_PH_MSK, regval);
549832cb9eeSNuno Sá }
550832cb9eeSNuno Sá 
ltc2688_set_dither_phase(struct iio_dev * dev,const struct iio_chan_spec * chan,unsigned int phase)551832cb9eeSNuno Sá static int ltc2688_set_dither_phase(struct iio_dev *dev,
552832cb9eeSNuno Sá 				    const struct iio_chan_spec *chan,
553832cb9eeSNuno Sá 				    unsigned int phase)
554832cb9eeSNuno Sá {
555832cb9eeSNuno Sá 	struct ltc2688_state *st = iio_priv(dev);
556832cb9eeSNuno Sá 
557832cb9eeSNuno Sá 	return regmap_update_bits(st->regmap,
558832cb9eeSNuno Sá 				  LTC2688_CMD_CH_SETTING(chan->channel),
559832cb9eeSNuno Sá 				  LTC2688_CH_DIT_PH_MSK,
560832cb9eeSNuno Sá 				  FIELD_PREP(LTC2688_CH_DIT_PH_MSK, phase));
561832cb9eeSNuno Sá }
562832cb9eeSNuno Sá 
ltc2688_reg_access(struct iio_dev * indio_dev,unsigned int reg,unsigned int writeval,unsigned int * readval)563832cb9eeSNuno Sá static int ltc2688_reg_access(struct iio_dev *indio_dev,
564832cb9eeSNuno Sá 			      unsigned int reg,
565832cb9eeSNuno Sá 			      unsigned int writeval,
566832cb9eeSNuno Sá 			      unsigned int *readval)
567832cb9eeSNuno Sá {
568832cb9eeSNuno Sá 	struct ltc2688_state *st = iio_priv(indio_dev);
569832cb9eeSNuno Sá 
570832cb9eeSNuno Sá 	if (readval)
571832cb9eeSNuno Sá 		return regmap_read(st->regmap, reg, readval);
572832cb9eeSNuno Sá 
573832cb9eeSNuno Sá 	return regmap_write(st->regmap, reg, writeval);
574832cb9eeSNuno Sá }
575832cb9eeSNuno Sá 
576832cb9eeSNuno Sá static const char * const ltc2688_dither_phase[] = {
577832cb9eeSNuno Sá 	"0", "1.5708", "3.14159", "4.71239",
578832cb9eeSNuno Sá };
579832cb9eeSNuno Sá 
580832cb9eeSNuno Sá static const struct iio_enum ltc2688_dither_phase_enum = {
581832cb9eeSNuno Sá 	.items = ltc2688_dither_phase,
582832cb9eeSNuno Sá 	.num_items = ARRAY_SIZE(ltc2688_dither_phase),
583832cb9eeSNuno Sá 	.set = ltc2688_set_dither_phase,
584832cb9eeSNuno Sá 	.get = ltc2688_get_dither_phase,
585832cb9eeSNuno Sá };
586832cb9eeSNuno Sá 
587832cb9eeSNuno Sá #define LTC2688_CHAN_EXT_INFO(_name, _what, _shared, _read, _write) {	\
588832cb9eeSNuno Sá 	.name = _name,							\
589832cb9eeSNuno Sá 	.read = (_read),						\
590832cb9eeSNuno Sá 	.write = (_write),						\
591832cb9eeSNuno Sá 	.private = (_what),						\
592832cb9eeSNuno Sá 	.shared = (_shared),						\
593832cb9eeSNuno Sá }
594832cb9eeSNuno Sá 
595832cb9eeSNuno Sá /*
596832cb9eeSNuno Sá  * For toggle mode we only expose the symbol attr (sw_toggle) in case a TGPx is
597832cb9eeSNuno Sá  * not provided in dts.
598832cb9eeSNuno Sá  */
599832cb9eeSNuno Sá static const struct iio_chan_spec_ext_info ltc2688_toggle_sym_ext_info[] = {
600832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("raw0", LTC2688_INPUT_A, IIO_SEPARATE,
601832cb9eeSNuno Sá 			      ltc2688_dac_input_read, ltc2688_dac_input_write),
602832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("raw1", LTC2688_INPUT_B, IIO_SEPARATE,
603832cb9eeSNuno Sá 			      ltc2688_dac_input_read, ltc2688_dac_input_write),
604832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("toggle_en", LTC2688_CMD_TOGGLE_DITHER_EN,
605832cb9eeSNuno Sá 			      IIO_SEPARATE, ltc2688_reg_bool_get,
606832cb9eeSNuno Sá 			      ltc2688_dither_toggle_set),
607832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("powerdown", LTC2688_CMD_POWERDOWN, IIO_SEPARATE,
608832cb9eeSNuno Sá 			      ltc2688_reg_bool_get, ltc2688_reg_bool_set),
609832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("symbol", LTC2688_CMD_SW_TOGGLE, IIO_SEPARATE,
610832cb9eeSNuno Sá 			      ltc2688_reg_bool_get, ltc2688_reg_bool_set),
611832cb9eeSNuno Sá 	{}
612832cb9eeSNuno Sá };
613832cb9eeSNuno Sá 
614832cb9eeSNuno Sá static const struct iio_chan_spec_ext_info ltc2688_toggle_ext_info[] = {
615832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("raw0", LTC2688_INPUT_A, IIO_SEPARATE,
616832cb9eeSNuno Sá 			      ltc2688_dac_input_read, ltc2688_dac_input_write),
617832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("raw1", LTC2688_INPUT_B, IIO_SEPARATE,
618832cb9eeSNuno Sá 			      ltc2688_dac_input_read, ltc2688_dac_input_write),
619832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("toggle_en", LTC2688_CMD_TOGGLE_DITHER_EN,
620832cb9eeSNuno Sá 			      IIO_SEPARATE, ltc2688_reg_bool_get,
621832cb9eeSNuno Sá 			      ltc2688_dither_toggle_set),
622832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("powerdown", LTC2688_CMD_POWERDOWN, IIO_SEPARATE,
623832cb9eeSNuno Sá 			      ltc2688_reg_bool_get, ltc2688_reg_bool_set),
624832cb9eeSNuno Sá 	{}
625832cb9eeSNuno Sá };
626832cb9eeSNuno Sá 
627832cb9eeSNuno Sá static struct iio_chan_spec_ext_info ltc2688_dither_ext_info[] = {
628832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("dither_raw", LTC2688_INPUT_B, IIO_SEPARATE,
629832cb9eeSNuno Sá 			      ltc2688_dac_input_read, ltc2688_dac_input_write),
630832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("dither_raw_available", LTC2688_INPUT_B_AVAIL,
631832cb9eeSNuno Sá 			      IIO_SEPARATE, ltc2688_dac_input_read,
632832cb9eeSNuno Sá 			      ltc2688_dac_input_write),
633832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("dither_offset", LTC2688_DITHER_OFF, IIO_SEPARATE,
634832cb9eeSNuno Sá 			      ltc2688_dac_input_read, ltc2688_dac_input_write),
635832cb9eeSNuno Sá 	/*
636832cb9eeSNuno Sá 	 * Not IIO_ENUM because the available freq needs to be computed at
637832cb9eeSNuno Sá 	 * probe. We could still use it, but it didn't felt much right.
638832cb9eeSNuno Sá 	 */
639832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("dither_frequency", 0, IIO_SEPARATE,
640832cb9eeSNuno Sá 			      ltc2688_dither_freq_get, ltc2688_dither_freq_set),
641832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("dither_frequency_available",
642832cb9eeSNuno Sá 			      LTC2688_DITHER_FREQ_AVAIL, IIO_SEPARATE,
643832cb9eeSNuno Sá 			      ltc2688_dither_freq_get, ltc2688_dither_freq_set),
644832cb9eeSNuno Sá 	IIO_ENUM("dither_phase", IIO_SEPARATE, &ltc2688_dither_phase_enum),
645832cb9eeSNuno Sá 	IIO_ENUM_AVAILABLE("dither_phase", IIO_SEPARATE,
646832cb9eeSNuno Sá 			   &ltc2688_dither_phase_enum),
647832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("dither_en", LTC2688_CMD_TOGGLE_DITHER_EN,
648832cb9eeSNuno Sá 			      IIO_SEPARATE, ltc2688_reg_bool_get,
649832cb9eeSNuno Sá 			      ltc2688_dither_toggle_set),
650832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("powerdown", LTC2688_CMD_POWERDOWN, IIO_SEPARATE,
651832cb9eeSNuno Sá 			      ltc2688_reg_bool_get, ltc2688_reg_bool_set),
652832cb9eeSNuno Sá 	{}
653832cb9eeSNuno Sá };
654832cb9eeSNuno Sá 
655832cb9eeSNuno Sá static const struct iio_chan_spec_ext_info ltc2688_ext_info[] = {
656832cb9eeSNuno Sá 	LTC2688_CHAN_EXT_INFO("powerdown", LTC2688_CMD_POWERDOWN, IIO_SEPARATE,
657832cb9eeSNuno Sá 			      ltc2688_reg_bool_get, ltc2688_reg_bool_set),
658832cb9eeSNuno Sá 	{}
659832cb9eeSNuno Sá };
660832cb9eeSNuno Sá 
661832cb9eeSNuno Sá #define LTC2688_CHANNEL(_chan) {					\
662832cb9eeSNuno Sá 	.type = IIO_VOLTAGE,						\
663832cb9eeSNuno Sá 	.indexed = 1,							\
664832cb9eeSNuno Sá 	.output = 1,							\
665832cb9eeSNuno Sá 	.channel = (_chan),						\
666832cb9eeSNuno Sá 	.info_mask_separate = BIT(IIO_CHAN_INFO_CALIBSCALE) |		\
667832cb9eeSNuno Sá 		BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET) |	\
668832cb9eeSNuno Sá 		BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_RAW),	\
669832cb9eeSNuno Sá 	.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW),		\
670832cb9eeSNuno Sá 	.ext_info = ltc2688_ext_info,					\
671832cb9eeSNuno Sá }
672832cb9eeSNuno Sá 
673832cb9eeSNuno Sá static const struct iio_chan_spec ltc2688_channels[] = {
674832cb9eeSNuno Sá 	LTC2688_CHANNEL(0),
675832cb9eeSNuno Sá 	LTC2688_CHANNEL(1),
676832cb9eeSNuno Sá 	LTC2688_CHANNEL(2),
677832cb9eeSNuno Sá 	LTC2688_CHANNEL(3),
678832cb9eeSNuno Sá 	LTC2688_CHANNEL(4),
679832cb9eeSNuno Sá 	LTC2688_CHANNEL(5),
680832cb9eeSNuno Sá 	LTC2688_CHANNEL(6),
681832cb9eeSNuno Sá 	LTC2688_CHANNEL(7),
682832cb9eeSNuno Sá 	LTC2688_CHANNEL(8),
683832cb9eeSNuno Sá 	LTC2688_CHANNEL(9),
684832cb9eeSNuno Sá 	LTC2688_CHANNEL(10),
685832cb9eeSNuno Sá 	LTC2688_CHANNEL(11),
686832cb9eeSNuno Sá 	LTC2688_CHANNEL(12),
687832cb9eeSNuno Sá 	LTC2688_CHANNEL(13),
688832cb9eeSNuno Sá 	LTC2688_CHANNEL(14),
689832cb9eeSNuno Sá 	LTC2688_CHANNEL(15),
690832cb9eeSNuno Sá };
691832cb9eeSNuno Sá 
ltc2688_clk_disable(void * clk)692832cb9eeSNuno Sá static void ltc2688_clk_disable(void *clk)
693832cb9eeSNuno Sá {
694832cb9eeSNuno Sá 	clk_disable_unprepare(clk);
695832cb9eeSNuno Sá }
696832cb9eeSNuno Sá 
697832cb9eeSNuno Sá static const int ltc2688_period[LTC2688_DITHER_FREQ_AVAIL_N] = {
698832cb9eeSNuno Sá 	4, 8, 16, 32, 64,
699832cb9eeSNuno Sá };
700832cb9eeSNuno Sá 
ltc2688_tgp_clk_setup(struct ltc2688_state * st,struct ltc2688_chan * chan,struct fwnode_handle * node,int tgp)701832cb9eeSNuno Sá static int ltc2688_tgp_clk_setup(struct ltc2688_state *st,
702832cb9eeSNuno Sá 				 struct ltc2688_chan *chan,
703832cb9eeSNuno Sá 				 struct fwnode_handle *node, int tgp)
704832cb9eeSNuno Sá {
705fee4ac32SAndy Shevchenko 	struct device *dev = &st->spi->dev;
706832cb9eeSNuno Sá 	unsigned long rate;
707832cb9eeSNuno Sá 	struct clk *clk;
708832cb9eeSNuno Sá 	int ret, f;
709832cb9eeSNuno Sá 
710fee4ac32SAndy Shevchenko 	clk = devm_get_clk_from_child(dev, to_of_node(node), NULL);
711832cb9eeSNuno Sá 	if (IS_ERR(clk))
712fee4ac32SAndy Shevchenko 		return dev_err_probe(dev, PTR_ERR(clk), "failed to get tgp clk.\n");
713832cb9eeSNuno Sá 
714832cb9eeSNuno Sá 	ret = clk_prepare_enable(clk);
715832cb9eeSNuno Sá 	if (ret)
716fee4ac32SAndy Shevchenko 		return dev_err_probe(dev, ret, "failed to enable tgp clk.\n");
717832cb9eeSNuno Sá 
718fee4ac32SAndy Shevchenko 	ret = devm_add_action_or_reset(dev, ltc2688_clk_disable, clk);
719832cb9eeSNuno Sá 	if (ret)
720832cb9eeSNuno Sá 		return ret;
721832cb9eeSNuno Sá 
722832cb9eeSNuno Sá 	if (chan->toggle_chan)
723832cb9eeSNuno Sá 		return 0;
724832cb9eeSNuno Sá 
725832cb9eeSNuno Sá 	/* calculate available dither frequencies */
726832cb9eeSNuno Sá 	rate = clk_get_rate(clk);
727832cb9eeSNuno Sá 	for (f = 0; f < ARRAY_SIZE(chan->dither_frequency); f++)
728832cb9eeSNuno Sá 		chan->dither_frequency[f] = DIV_ROUND_CLOSEST(rate, ltc2688_period[f]);
729832cb9eeSNuno Sá 
730832cb9eeSNuno Sá 	return 0;
731832cb9eeSNuno Sá }
732832cb9eeSNuno Sá 
ltc2688_span_lookup(const struct ltc2688_state * st,int min,int max)733832cb9eeSNuno Sá static int ltc2688_span_lookup(const struct ltc2688_state *st, int min, int max)
734832cb9eeSNuno Sá {
735832cb9eeSNuno Sá 	u32 span;
736832cb9eeSNuno Sá 
737832cb9eeSNuno Sá 	for (span = 0; span < ARRAY_SIZE(ltc2688_span_helper); span++) {
738832cb9eeSNuno Sá 		if (min == ltc2688_span_helper[span][0] &&
739832cb9eeSNuno Sá 		    max == ltc2688_span_helper[span][1])
740832cb9eeSNuno Sá 			return span;
741832cb9eeSNuno Sá 	}
742832cb9eeSNuno Sá 
743832cb9eeSNuno Sá 	return -EINVAL;
744832cb9eeSNuno Sá }
745832cb9eeSNuno Sá 
ltc2688_channel_config(struct ltc2688_state * st)746832cb9eeSNuno Sá static int ltc2688_channel_config(struct ltc2688_state *st)
747832cb9eeSNuno Sá {
748832cb9eeSNuno Sá 	struct device *dev = &st->spi->dev;
749832cb9eeSNuno Sá 	struct fwnode_handle *child;
750832cb9eeSNuno Sá 	u32 reg, clk_input, val, tmp[2];
751832cb9eeSNuno Sá 	int ret, span;
752832cb9eeSNuno Sá 
753832cb9eeSNuno Sá 	device_for_each_child_node(dev, child) {
754832cb9eeSNuno Sá 		struct ltc2688_chan *chan;
755832cb9eeSNuno Sá 
756832cb9eeSNuno Sá 		ret = fwnode_property_read_u32(child, "reg", &reg);
757832cb9eeSNuno Sá 		if (ret) {
758832cb9eeSNuno Sá 			fwnode_handle_put(child);
759832cb9eeSNuno Sá 			return dev_err_probe(dev, ret,
760832cb9eeSNuno Sá 					     "Failed to get reg property\n");
761832cb9eeSNuno Sá 		}
762832cb9eeSNuno Sá 
763832cb9eeSNuno Sá 		if (reg >= LTC2688_DAC_CHANNELS) {
764832cb9eeSNuno Sá 			fwnode_handle_put(child);
765832cb9eeSNuno Sá 			return dev_err_probe(dev, -EINVAL,
766832cb9eeSNuno Sá 					     "reg bigger than: %d\n",
767832cb9eeSNuno Sá 					     LTC2688_DAC_CHANNELS);
768832cb9eeSNuno Sá 		}
769832cb9eeSNuno Sá 
770832cb9eeSNuno Sá 		val = 0;
771832cb9eeSNuno Sá 		chan = &st->channels[reg];
772832cb9eeSNuno Sá 		if (fwnode_property_read_bool(child, "adi,toggle-mode")) {
773832cb9eeSNuno Sá 			chan->toggle_chan = true;
774832cb9eeSNuno Sá 			/* assume sw toggle ABI */
775832cb9eeSNuno Sá 			st->iio_chan[reg].ext_info = ltc2688_toggle_sym_ext_info;
776832cb9eeSNuno Sá 			/*
777832cb9eeSNuno Sá 			 * Clear IIO_CHAN_INFO_RAW bit as toggle channels expose
778832cb9eeSNuno Sá 			 * out_voltage_raw{0|1} files.
779832cb9eeSNuno Sá 			 */
780832cb9eeSNuno Sá 			__clear_bit(IIO_CHAN_INFO_RAW,
781832cb9eeSNuno Sá 				    &st->iio_chan[reg].info_mask_separate);
782832cb9eeSNuno Sá 		}
783832cb9eeSNuno Sá 
784832cb9eeSNuno Sá 		ret = fwnode_property_read_u32_array(child, "adi,output-range-microvolt",
785832cb9eeSNuno Sá 						     tmp, ARRAY_SIZE(tmp));
786832cb9eeSNuno Sá 		if (!ret) {
787832cb9eeSNuno Sá 			span = ltc2688_span_lookup(st, (int)tmp[0] / 1000,
788832cb9eeSNuno Sá 						   tmp[1] / 1000);
789832cb9eeSNuno Sá 			if (span < 0) {
790832cb9eeSNuno Sá 				fwnode_handle_put(child);
791832cb9eeSNuno Sá 				return dev_err_probe(dev, -EINVAL,
792832cb9eeSNuno Sá 						     "output range not valid:[%d %d]\n",
793832cb9eeSNuno Sá 						     tmp[0], tmp[1]);
794832cb9eeSNuno Sá 			}
795832cb9eeSNuno Sá 
796832cb9eeSNuno Sá 			val |= FIELD_PREP(LTC2688_CH_SPAN_MSK, span);
797832cb9eeSNuno Sá 		}
798832cb9eeSNuno Sá 
799832cb9eeSNuno Sá 		ret = fwnode_property_read_u32(child, "adi,toggle-dither-input",
800832cb9eeSNuno Sá 					       &clk_input);
801832cb9eeSNuno Sá 		if (!ret) {
802832cb9eeSNuno Sá 			if (clk_input >= LTC2688_CH_TGP_MAX) {
803832cb9eeSNuno Sá 				fwnode_handle_put(child);
804832cb9eeSNuno Sá 				return dev_err_probe(dev, -EINVAL,
805832cb9eeSNuno Sá 						     "toggle-dither-input inv value(%d)\n",
806832cb9eeSNuno Sá 						     clk_input);
807832cb9eeSNuno Sá 			}
808832cb9eeSNuno Sá 
809832cb9eeSNuno Sá 			ret = ltc2688_tgp_clk_setup(st, chan, child, clk_input);
810832cb9eeSNuno Sá 			if (ret) {
811832cb9eeSNuno Sá 				fwnode_handle_put(child);
812832cb9eeSNuno Sá 				return ret;
813832cb9eeSNuno Sá 			}
814832cb9eeSNuno Sá 
815832cb9eeSNuno Sá 			/*
816832cb9eeSNuno Sá 			 * 0 means software toggle which is the default mode.
817832cb9eeSNuno Sá 			 * Hence the +1.
818832cb9eeSNuno Sá 			 */
819832cb9eeSNuno Sá 			val |= FIELD_PREP(LTC2688_CH_TD_SEL_MSK, clk_input + 1);
820832cb9eeSNuno Sá 
821832cb9eeSNuno Sá 			/*
822832cb9eeSNuno Sá 			 * If a TGPx is given, we automatically assume a dither
823832cb9eeSNuno Sá 			 * capable channel (unless toggle is already enabled).
824832cb9eeSNuno Sá 			 * On top of this we just set here the dither bit in the
825832cb9eeSNuno Sá 			 * channel settings. It won't have any effect until the
826832cb9eeSNuno Sá 			 * global toggle/dither bit is enabled.
827832cb9eeSNuno Sá 			 */
828832cb9eeSNuno Sá 			if (!chan->toggle_chan) {
829832cb9eeSNuno Sá 				val |= FIELD_PREP(LTC2688_CH_MODE_MSK, 1);
830832cb9eeSNuno Sá 				st->iio_chan[reg].ext_info = ltc2688_dither_ext_info;
831832cb9eeSNuno Sá 			} else {
832832cb9eeSNuno Sá 				/* wait, no sw toggle after all */
833832cb9eeSNuno Sá 				st->iio_chan[reg].ext_info = ltc2688_toggle_ext_info;
834832cb9eeSNuno Sá 			}
835832cb9eeSNuno Sá 		}
836832cb9eeSNuno Sá 
837832cb9eeSNuno Sá 		if (fwnode_property_read_bool(child, "adi,overrange")) {
838832cb9eeSNuno Sá 			chan->overrange = true;
839832cb9eeSNuno Sá 			val |= LTC2688_CH_OVERRANGE_MSK;
840832cb9eeSNuno Sá 		}
841832cb9eeSNuno Sá 
842832cb9eeSNuno Sá 		if (!val)
843832cb9eeSNuno Sá 			continue;
844832cb9eeSNuno Sá 
845832cb9eeSNuno Sá 		ret = regmap_write(st->regmap, LTC2688_CMD_CH_SETTING(reg),
846832cb9eeSNuno Sá 				   val);
847832cb9eeSNuno Sá 		if (ret) {
848832cb9eeSNuno Sá 			fwnode_handle_put(child);
849832cb9eeSNuno Sá 			return dev_err_probe(dev, -EINVAL,
850832cb9eeSNuno Sá 					     "failed to set chan settings\n");
851832cb9eeSNuno Sá 		}
852832cb9eeSNuno Sá 	}
853832cb9eeSNuno Sá 
854832cb9eeSNuno Sá 	return 0;
855832cb9eeSNuno Sá }
856832cb9eeSNuno Sá 
ltc2688_setup(struct ltc2688_state * st,struct regulator * vref)857832cb9eeSNuno Sá static int ltc2688_setup(struct ltc2688_state *st, struct regulator *vref)
858832cb9eeSNuno Sá {
859fee4ac32SAndy Shevchenko 	struct device *dev = &st->spi->dev;
860832cb9eeSNuno Sá 	struct gpio_desc *gpio;
861832cb9eeSNuno Sá 	int ret;
862832cb9eeSNuno Sá 
863832cb9eeSNuno Sá 	/*
864832cb9eeSNuno Sá 	 * If we have a reset pin, use that to reset the board, If not, use
865832cb9eeSNuno Sá 	 * the reset bit.
866832cb9eeSNuno Sá 	 */
867fee4ac32SAndy Shevchenko 	gpio = devm_gpiod_get_optional(dev, "clr", GPIOD_OUT_HIGH);
868832cb9eeSNuno Sá 	if (IS_ERR(gpio))
869fee4ac32SAndy Shevchenko 		return dev_err_probe(dev, PTR_ERR(gpio), "Failed to get reset gpio");
870832cb9eeSNuno Sá 	if (gpio) {
871832cb9eeSNuno Sá 		usleep_range(1000, 1200);
872832cb9eeSNuno Sá 		/* bring device out of reset */
873832cb9eeSNuno Sá 		gpiod_set_value_cansleep(gpio, 0);
874832cb9eeSNuno Sá 	} else {
875832cb9eeSNuno Sá 		ret = regmap_update_bits(st->regmap, LTC2688_CMD_CONFIG,
876832cb9eeSNuno Sá 					 LTC2688_CONFIG_RST,
877832cb9eeSNuno Sá 					 LTC2688_CONFIG_RST);
878832cb9eeSNuno Sá 		if (ret)
879832cb9eeSNuno Sá 			return ret;
880832cb9eeSNuno Sá 	}
881832cb9eeSNuno Sá 
882832cb9eeSNuno Sá 	usleep_range(10000, 12000);
883832cb9eeSNuno Sá 
884832cb9eeSNuno Sá 	/*
885832cb9eeSNuno Sá 	 * Duplicate the default channel configuration as it can change during
886832cb9eeSNuno Sá 	 * @ltc2688_channel_config()
887832cb9eeSNuno Sá 	 */
888fee4ac32SAndy Shevchenko 	st->iio_chan = devm_kmemdup(dev, ltc2688_channels,
889832cb9eeSNuno Sá 				    sizeof(ltc2688_channels), GFP_KERNEL);
890832cb9eeSNuno Sá 	if (!st->iio_chan)
891832cb9eeSNuno Sá 		return -ENOMEM;
892832cb9eeSNuno Sá 
893832cb9eeSNuno Sá 	ret = ltc2688_channel_config(st);
894832cb9eeSNuno Sá 	if (ret)
895832cb9eeSNuno Sá 		return ret;
896832cb9eeSNuno Sá 
897832cb9eeSNuno Sá 	if (!vref)
898832cb9eeSNuno Sá 		return 0;
899832cb9eeSNuno Sá 
900832cb9eeSNuno Sá 	return regmap_set_bits(st->regmap, LTC2688_CMD_CONFIG,
901832cb9eeSNuno Sá 			       LTC2688_CONFIG_EXT_REF);
902832cb9eeSNuno Sá }
903832cb9eeSNuno Sá 
ltc2688_disable_regulator(void * regulator)904832cb9eeSNuno Sá static void ltc2688_disable_regulator(void *regulator)
905832cb9eeSNuno Sá {
906832cb9eeSNuno Sá 	regulator_disable(regulator);
907832cb9eeSNuno Sá }
908832cb9eeSNuno Sá 
ltc2688_reg_readable(struct device * dev,unsigned int reg)909832cb9eeSNuno Sá static bool ltc2688_reg_readable(struct device *dev, unsigned int reg)
910832cb9eeSNuno Sá {
911832cb9eeSNuno Sá 	switch (reg) {
912832cb9eeSNuno Sá 	case LTC2688_CMD_CH_CODE(0) ... LTC2688_CMD_CH_GAIN(15):
913832cb9eeSNuno Sá 		return true;
914832cb9eeSNuno Sá 	case LTC2688_CMD_CONFIG ... LTC2688_CMD_THERMAL_STAT:
915832cb9eeSNuno Sá 		return true;
916832cb9eeSNuno Sá 	default:
917832cb9eeSNuno Sá 		return false;
918832cb9eeSNuno Sá 	}
919832cb9eeSNuno Sá }
920832cb9eeSNuno Sá 
ltc2688_reg_writable(struct device * dev,unsigned int reg)921832cb9eeSNuno Sá static bool ltc2688_reg_writable(struct device *dev, unsigned int reg)
922832cb9eeSNuno Sá {
923832cb9eeSNuno Sá 	/*
924832cb9eeSNuno Sá 	 * There's a jump from 0x76 to 0x78 in the write codes and the thermal
925832cb9eeSNuno Sá 	 * status code is 0x77 (which is read only) so that we need to check
926832cb9eeSNuno Sá 	 * that special condition.
927832cb9eeSNuno Sá 	 */
928832cb9eeSNuno Sá 	if (reg <= LTC2688_CMD_UPDATE_ALL && reg != LTC2688_CMD_THERMAL_STAT)
929832cb9eeSNuno Sá 		return true;
930832cb9eeSNuno Sá 
931832cb9eeSNuno Sá 	return false;
932832cb9eeSNuno Sá }
933832cb9eeSNuno Sá 
934832cb9eeSNuno Sá static struct regmap_bus ltc2688_regmap_bus = {
935832cb9eeSNuno Sá 	.read = ltc2688_spi_read,
936832cb9eeSNuno Sá 	.write = ltc2688_spi_write,
937832cb9eeSNuno Sá 	.read_flag_mask = LTC2688_READ_OPERATION,
938832cb9eeSNuno Sá 	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
939832cb9eeSNuno Sá 	.val_format_endian_default = REGMAP_ENDIAN_BIG,
940832cb9eeSNuno Sá };
941832cb9eeSNuno Sá 
942832cb9eeSNuno Sá static const struct regmap_config ltc2688_regmap_config = {
943832cb9eeSNuno Sá 	.reg_bits = 8,
944832cb9eeSNuno Sá 	.val_bits = 16,
945832cb9eeSNuno Sá 	.readable_reg = ltc2688_reg_readable,
946832cb9eeSNuno Sá 	.writeable_reg = ltc2688_reg_writable,
947832cb9eeSNuno Sá 	/* ignoring the no op command */
948832cb9eeSNuno Sá 	.max_register = LTC2688_CMD_UPDATE_ALL,
949832cb9eeSNuno Sá };
950832cb9eeSNuno Sá 
951832cb9eeSNuno Sá static const struct iio_info ltc2688_info = {
952832cb9eeSNuno Sá 	.write_raw = ltc2688_write_raw,
953832cb9eeSNuno Sá 	.read_raw = ltc2688_read_raw,
954832cb9eeSNuno Sá 	.read_avail = ltc2688_read_avail,
955832cb9eeSNuno Sá 	.debugfs_reg_access = ltc2688_reg_access,
956832cb9eeSNuno Sá };
957832cb9eeSNuno Sá 
ltc2688_probe(struct spi_device * spi)958832cb9eeSNuno Sá static int ltc2688_probe(struct spi_device *spi)
959832cb9eeSNuno Sá {
960*08f75f18SMatti Vaittinen 	static const char * const regulators[] = { "vcc", "iovcc" };
961832cb9eeSNuno Sá 	struct ltc2688_state *st;
962832cb9eeSNuno Sá 	struct iio_dev *indio_dev;
963832cb9eeSNuno Sá 	struct regulator *vref_reg;
964832cb9eeSNuno Sá 	struct device *dev = &spi->dev;
965832cb9eeSNuno Sá 	int ret;
966832cb9eeSNuno Sá 
967832cb9eeSNuno Sá 	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
968832cb9eeSNuno Sá 	if (!indio_dev)
969832cb9eeSNuno Sá 		return -ENOMEM;
970832cb9eeSNuno Sá 
971832cb9eeSNuno Sá 	st = iio_priv(indio_dev);
972832cb9eeSNuno Sá 	st->spi = spi;
973832cb9eeSNuno Sá 
974832cb9eeSNuno Sá 	/* Just write this once. No need to do it in every regmap read. */
975832cb9eeSNuno Sá 	st->tx_data[3] = LTC2688_CMD_NOOP;
976832cb9eeSNuno Sá 	mutex_init(&st->lock);
977832cb9eeSNuno Sá 
978832cb9eeSNuno Sá 	st->regmap = devm_regmap_init(dev, &ltc2688_regmap_bus, st,
979832cb9eeSNuno Sá 				      &ltc2688_regmap_config);
980832cb9eeSNuno Sá 	if (IS_ERR(st->regmap))
981832cb9eeSNuno Sá 		return dev_err_probe(dev, PTR_ERR(st->regmap),
982832cb9eeSNuno Sá 				     "Failed to init regmap");
983832cb9eeSNuno Sá 
984*08f75f18SMatti Vaittinen 	ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators),
985*08f75f18SMatti Vaittinen 					     regulators);
986832cb9eeSNuno Sá 	if (ret)
987832cb9eeSNuno Sá 		return dev_err_probe(dev, ret, "Failed to enable regulators\n");
988832cb9eeSNuno Sá 
989832cb9eeSNuno Sá 	vref_reg = devm_regulator_get_optional(dev, "vref");
990832cb9eeSNuno Sá 	if (IS_ERR(vref_reg)) {
991832cb9eeSNuno Sá 		if (PTR_ERR(vref_reg) != -ENODEV)
992832cb9eeSNuno Sá 			return dev_err_probe(dev, PTR_ERR(vref_reg),
993832cb9eeSNuno Sá 					     "Failed to get vref regulator");
994832cb9eeSNuno Sá 
995832cb9eeSNuno Sá 		vref_reg = NULL;
996832cb9eeSNuno Sá 		/* internal reference */
997832cb9eeSNuno Sá 		st->vref = 4096;
998832cb9eeSNuno Sá 	} else {
999832cb9eeSNuno Sá 		ret = regulator_enable(vref_reg);
1000832cb9eeSNuno Sá 		if (ret)
1001832cb9eeSNuno Sá 			return dev_err_probe(dev, ret,
1002832cb9eeSNuno Sá 					     "Failed to enable vref regulators\n");
1003832cb9eeSNuno Sá 
1004832cb9eeSNuno Sá 		ret = devm_add_action_or_reset(dev, ltc2688_disable_regulator,
1005832cb9eeSNuno Sá 					       vref_reg);
1006832cb9eeSNuno Sá 		if (ret)
1007832cb9eeSNuno Sá 			return ret;
1008832cb9eeSNuno Sá 
1009832cb9eeSNuno Sá 		ret = regulator_get_voltage(vref_reg);
1010832cb9eeSNuno Sá 		if (ret < 0)
1011832cb9eeSNuno Sá 			return dev_err_probe(dev, ret, "Failed to get vref\n");
1012832cb9eeSNuno Sá 
1013832cb9eeSNuno Sá 		st->vref = ret / 1000;
1014832cb9eeSNuno Sá 	}
1015832cb9eeSNuno Sá 
1016832cb9eeSNuno Sá 	ret = ltc2688_setup(st, vref_reg);
1017832cb9eeSNuno Sá 	if (ret)
1018832cb9eeSNuno Sá 		return ret;
1019832cb9eeSNuno Sá 
1020832cb9eeSNuno Sá 	indio_dev->name = "ltc2688";
1021832cb9eeSNuno Sá 	indio_dev->info = &ltc2688_info;
1022832cb9eeSNuno Sá 	indio_dev->modes = INDIO_DIRECT_MODE;
1023832cb9eeSNuno Sá 	indio_dev->channels = st->iio_chan;
1024832cb9eeSNuno Sá 	indio_dev->num_channels = ARRAY_SIZE(ltc2688_channels);
1025832cb9eeSNuno Sá 
1026832cb9eeSNuno Sá 	return devm_iio_device_register(dev, indio_dev);
1027832cb9eeSNuno Sá }
1028832cb9eeSNuno Sá 
1029832cb9eeSNuno Sá static const struct of_device_id ltc2688_of_id[] = {
1030832cb9eeSNuno Sá 	{ .compatible = "adi,ltc2688" },
1031832cb9eeSNuno Sá 	{}
1032832cb9eeSNuno Sá };
1033832cb9eeSNuno Sá MODULE_DEVICE_TABLE(of, ltc2688_of_id);
1034832cb9eeSNuno Sá 
1035832cb9eeSNuno Sá static const struct spi_device_id ltc2688_id[] = {
1036832cb9eeSNuno Sá 	{ "ltc2688" },
1037832cb9eeSNuno Sá 	{}
1038832cb9eeSNuno Sá };
1039832cb9eeSNuno Sá MODULE_DEVICE_TABLE(spi, ltc2688_id);
1040832cb9eeSNuno Sá 
1041832cb9eeSNuno Sá static struct spi_driver ltc2688_driver = {
1042832cb9eeSNuno Sá 	.driver = {
1043832cb9eeSNuno Sá 		.name = "ltc2688",
1044832cb9eeSNuno Sá 		.of_match_table = ltc2688_of_id,
1045832cb9eeSNuno Sá 	},
1046832cb9eeSNuno Sá 	.probe = ltc2688_probe,
1047832cb9eeSNuno Sá 	.id_table = ltc2688_id,
1048832cb9eeSNuno Sá };
1049832cb9eeSNuno Sá module_spi_driver(ltc2688_driver);
1050832cb9eeSNuno Sá 
1051832cb9eeSNuno Sá MODULE_AUTHOR("Nuno Sá <nuno.sa@analog.com>");
1052832cb9eeSNuno Sá MODULE_DESCRIPTION("Analog Devices LTC2688 DAC");
1053832cb9eeSNuno Sá MODULE_LICENSE("GPL");
1054