xref: /linux/drivers/iio/addac/ad74413r.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1fea251b6SCosmin Tanislav // SPDX-License-Identifier: GPL-2.0
2fea251b6SCosmin Tanislav /*
3fea251b6SCosmin Tanislav  * Copyright (C) 2021 Analog Devices, Inc.
4fea251b6SCosmin Tanislav  * Author: Cosmin Tanislav <cosmin.tanislav@analog.com>
5fea251b6SCosmin Tanislav  */
6fea251b6SCosmin Tanislav 
7fea251b6SCosmin Tanislav #include <asm/unaligned.h>
8fea251b6SCosmin Tanislav #include <linux/bitfield.h>
9fea251b6SCosmin Tanislav #include <linux/crc8.h>
10fea251b6SCosmin Tanislav #include <linux/device.h>
11fea251b6SCosmin Tanislav #include <linux/err.h>
12fea251b6SCosmin Tanislav #include <linux/gpio/driver.h>
13fea251b6SCosmin Tanislav #include <linux/iio/buffer.h>
14fea251b6SCosmin Tanislav #include <linux/iio/iio.h>
15fea251b6SCosmin Tanislav #include <linux/iio/sysfs.h>
16fea251b6SCosmin Tanislav #include <linux/iio/trigger.h>
17fea251b6SCosmin Tanislav #include <linux/iio/trigger_consumer.h>
18fea251b6SCosmin Tanislav #include <linux/iio/triggered_buffer.h>
19fea251b6SCosmin Tanislav #include <linux/interrupt.h>
20fea251b6SCosmin Tanislav #include <linux/mod_devicetable.h>
21fea251b6SCosmin Tanislav #include <linux/property.h>
22fea251b6SCosmin Tanislav #include <linux/regmap.h>
23fea251b6SCosmin Tanislav #include <linux/regulator/consumer.h>
24fea251b6SCosmin Tanislav #include <linux/spi/spi.h>
25fea251b6SCosmin Tanislav 
26fea251b6SCosmin Tanislav #include <dt-bindings/iio/addac/adi,ad74413r.h>
27fea251b6SCosmin Tanislav 
28fea251b6SCosmin Tanislav #define AD74413R_CRC_POLYNOMIAL	0x7
29fea251b6SCosmin Tanislav DECLARE_CRC8_TABLE(ad74413r_crc8_table);
30fea251b6SCosmin Tanislav 
31fea251b6SCosmin Tanislav #define AD74413R_CHANNEL_MAX	4
32fea251b6SCosmin Tanislav 
33fea251b6SCosmin Tanislav #define AD74413R_FRAME_SIZE	4
34fea251b6SCosmin Tanislav 
35fea251b6SCosmin Tanislav struct ad74413r_chip_info {
36fea251b6SCosmin Tanislav 	const char	*name;
37fea251b6SCosmin Tanislav 	bool		hart_support;
38fea251b6SCosmin Tanislav };
39fea251b6SCosmin Tanislav 
40fea251b6SCosmin Tanislav struct ad74413r_channel_config {
41fea251b6SCosmin Tanislav 	u32		func;
42fea251b6SCosmin Tanislav 	bool		gpo_comparator;
43fea251b6SCosmin Tanislav 	bool		initialized;
44fea251b6SCosmin Tanislav };
45fea251b6SCosmin Tanislav 
46fea251b6SCosmin Tanislav struct ad74413r_channels {
47fea251b6SCosmin Tanislav 	struct iio_chan_spec	*channels;
48fea251b6SCosmin Tanislav 	unsigned int		num_channels;
49fea251b6SCosmin Tanislav };
50fea251b6SCosmin Tanislav 
51fea251b6SCosmin Tanislav struct ad74413r_state {
52fea251b6SCosmin Tanislav 	struct ad74413r_channel_config	channel_configs[AD74413R_CHANNEL_MAX];
53fea251b6SCosmin Tanislav 	unsigned int			gpo_gpio_offsets[AD74413R_CHANNEL_MAX];
54fea251b6SCosmin Tanislav 	unsigned int			comp_gpio_offsets[AD74413R_CHANNEL_MAX];
55fea251b6SCosmin Tanislav 	struct gpio_chip		gpo_gpiochip;
56fea251b6SCosmin Tanislav 	struct gpio_chip		comp_gpiochip;
57fea251b6SCosmin Tanislav 	struct completion		adc_data_completion;
58fea251b6SCosmin Tanislav 	unsigned int			num_gpo_gpios;
59fea251b6SCosmin Tanislav 	unsigned int			num_comparator_gpios;
60fea251b6SCosmin Tanislav 	u32				sense_resistor_ohms;
61fea251b6SCosmin Tanislav 
62fea251b6SCosmin Tanislav 	/*
63fea251b6SCosmin Tanislav 	 * Synchronize consecutive operations when doing a one-shot
64fea251b6SCosmin Tanislav 	 * conversion and when updating the ADC samples SPI message.
65fea251b6SCosmin Tanislav 	 */
66fea251b6SCosmin Tanislav 	struct mutex			lock;
67fea251b6SCosmin Tanislav 
68fea251b6SCosmin Tanislav 	const struct ad74413r_chip_info	*chip_info;
69fea251b6SCosmin Tanislav 	struct spi_device		*spi;
70fea251b6SCosmin Tanislav 	struct regulator		*refin_reg;
71fea251b6SCosmin Tanislav 	struct regmap			*regmap;
72fea251b6SCosmin Tanislav 	struct device			*dev;
73fea251b6SCosmin Tanislav 	struct iio_trigger		*trig;
74fea251b6SCosmin Tanislav 
75fea251b6SCosmin Tanislav 	size_t			adc_active_channels;
76fea251b6SCosmin Tanislav 	struct spi_message	adc_samples_msg;
77fea251b6SCosmin Tanislav 	struct spi_transfer	adc_samples_xfer[AD74413R_CHANNEL_MAX + 1];
78fea251b6SCosmin Tanislav 
79fea251b6SCosmin Tanislav 	/*
80fea251b6SCosmin Tanislav 	 * DMA (thus cache coherency maintenance) requires the
81fea251b6SCosmin Tanislav 	 * transfer buffers to live in their own cache lines.
82fea251b6SCosmin Tanislav 	 */
83fea251b6SCosmin Tanislav 	struct {
84fea251b6SCosmin Tanislav 		u8 rx_buf[AD74413R_FRAME_SIZE * AD74413R_CHANNEL_MAX];
85fea251b6SCosmin Tanislav 		s64 timestamp;
86fea251b6SCosmin Tanislav 	} adc_samples_buf ____cacheline_aligned;
87fea251b6SCosmin Tanislav 
88fea251b6SCosmin Tanislav 	u8	adc_samples_tx_buf[AD74413R_FRAME_SIZE * AD74413R_CHANNEL_MAX];
89fea251b6SCosmin Tanislav 	u8	reg_tx_buf[AD74413R_FRAME_SIZE];
90fea251b6SCosmin Tanislav 	u8	reg_rx_buf[AD74413R_FRAME_SIZE];
91fea251b6SCosmin Tanislav };
92fea251b6SCosmin Tanislav 
93fea251b6SCosmin Tanislav #define AD74413R_REG_NOP		0x00
94fea251b6SCosmin Tanislav 
95fea251b6SCosmin Tanislav #define AD74413R_REG_CH_FUNC_SETUP_X(x)	(0x01 + (x))
96fea251b6SCosmin Tanislav #define AD74413R_CH_FUNC_SETUP_MASK	GENMASK(3, 0)
97fea251b6SCosmin Tanislav 
98fea251b6SCosmin Tanislav #define AD74413R_REG_ADC_CONFIG_X(x)		(0x05 + (x))
99fea251b6SCosmin Tanislav #define AD74413R_ADC_CONFIG_RANGE_MASK		GENMASK(7, 5)
100fea251b6SCosmin Tanislav #define AD74413R_ADC_CONFIG_REJECTION_MASK	GENMASK(4, 3)
101fea251b6SCosmin Tanislav #define AD74413R_ADC_RANGE_10V			0b000
102fea251b6SCosmin Tanislav #define AD74413R_ADC_RANGE_2P5V_EXT_POW		0b001
103fea251b6SCosmin Tanislav #define AD74413R_ADC_RANGE_2P5V_INT_POW		0b010
104fea251b6SCosmin Tanislav #define AD74413R_ADC_RANGE_5V_BI_DIR		0b011
105fea251b6SCosmin Tanislav #define AD74413R_ADC_REJECTION_50_60		0b00
106fea251b6SCosmin Tanislav #define AD74413R_ADC_REJECTION_NONE		0b01
107fea251b6SCosmin Tanislav #define AD74413R_ADC_REJECTION_50_60_HART	0b10
108fea251b6SCosmin Tanislav #define AD74413R_ADC_REJECTION_HART		0b11
109fea251b6SCosmin Tanislav 
110fea251b6SCosmin Tanislav #define AD74413R_REG_DIN_CONFIG_X(x)	(0x09 + (x))
111fea251b6SCosmin Tanislav #define AD74413R_DIN_DEBOUNCE_MASK	GENMASK(4, 0)
112fea251b6SCosmin Tanislav #define AD74413R_DIN_DEBOUNCE_LEN	BIT(5)
113fea251b6SCosmin Tanislav 
114fea251b6SCosmin Tanislav #define AD74413R_REG_DAC_CODE_X(x)	(0x16 + (x))
115fea251b6SCosmin Tanislav #define AD74413R_DAC_CODE_MAX		GENMASK(12, 0)
116fea251b6SCosmin Tanislav #define AD74413R_DAC_VOLTAGE_MAX	11000
117fea251b6SCosmin Tanislav 
118fea251b6SCosmin Tanislav #define AD74413R_REG_GPO_PAR_DATA		0x0d
119fea251b6SCosmin Tanislav #define AD74413R_REG_GPO_CONFIG_X(x)		(0x0e + (x))
120fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_DATA_MASK	BIT(3)
121fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_SELECT_MASK		GENMASK(2, 0)
122fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_100K_PULL_DOWN	0b000
123fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_LOGIC		0b001
124fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_LOGIC_PARALLEL	0b010
125fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_COMPARATOR		0b011
126fea251b6SCosmin Tanislav #define AD74413R_GPO_CONFIG_HIGH_IMPEDANCE	0b100
127fea251b6SCosmin Tanislav 
128fea251b6SCosmin Tanislav #define AD74413R_REG_ADC_CONV_CTRL	0x23
129fea251b6SCosmin Tanislav #define AD74413R_CONV_SEQ_MASK		GENMASK(9, 8)
130fea251b6SCosmin Tanislav #define AD74413R_CONV_SEQ_ON		0b00
131fea251b6SCosmin Tanislav #define AD74413R_CONV_SEQ_SINGLE	0b01
132fea251b6SCosmin Tanislav #define AD74413R_CONV_SEQ_CONTINUOUS	0b10
133fea251b6SCosmin Tanislav #define AD74413R_CONV_SEQ_OFF		0b11
134fea251b6SCosmin Tanislav #define AD74413R_CH_EN_MASK(x)		BIT(x)
135fea251b6SCosmin Tanislav 
136fea251b6SCosmin Tanislav #define AD74413R_REG_DIN_COMP_OUT		0x25
137fea251b6SCosmin Tanislav 
138fea251b6SCosmin Tanislav #define AD74413R_REG_ADC_RESULT_X(x)	(0x26 + (x))
139fea251b6SCosmin Tanislav #define AD74413R_ADC_RESULT_MAX		GENMASK(15, 0)
140fea251b6SCosmin Tanislav 
141fea251b6SCosmin Tanislav #define AD74413R_REG_READ_SELECT	0x41
142fea251b6SCosmin Tanislav 
143fea251b6SCosmin Tanislav #define AD74413R_REG_CMD_KEY		0x44
144fea251b6SCosmin Tanislav #define AD74413R_CMD_KEY_LDAC		0x953a
145fea251b6SCosmin Tanislav #define AD74413R_CMD_KEY_RESET1		0x15fa
146fea251b6SCosmin Tanislav #define AD74413R_CMD_KEY_RESET2		0xaf51
147fea251b6SCosmin Tanislav 
148fea251b6SCosmin Tanislav static const int ad74413r_adc_sampling_rates[] = {
149fea251b6SCosmin Tanislav 	20, 4800,
150fea251b6SCosmin Tanislav };
151fea251b6SCosmin Tanislav 
152fea251b6SCosmin Tanislav static const int ad74413r_adc_sampling_rates_hart[] = {
153fea251b6SCosmin Tanislav 	10, 20, 1200, 4800,
154fea251b6SCosmin Tanislav };
155fea251b6SCosmin Tanislav 
156fea251b6SCosmin Tanislav static int ad74413r_crc(u8 *buf)
157fea251b6SCosmin Tanislav {
158fea251b6SCosmin Tanislav 	return crc8(ad74413r_crc8_table, buf, 3, 0);
159fea251b6SCosmin Tanislav }
160fea251b6SCosmin Tanislav 
161fea251b6SCosmin Tanislav static void ad74413r_format_reg_write(u8 reg, u16 val, u8 *buf)
162fea251b6SCosmin Tanislav {
163fea251b6SCosmin Tanislav 	buf[0] = reg;
164fea251b6SCosmin Tanislav 	put_unaligned_be16(val, &buf[1]);
165fea251b6SCosmin Tanislav 	buf[3] = ad74413r_crc(buf);
166fea251b6SCosmin Tanislav }
167fea251b6SCosmin Tanislav 
168fea251b6SCosmin Tanislav static int ad74413r_reg_write(void *context, unsigned int reg, unsigned int val)
169fea251b6SCosmin Tanislav {
170fea251b6SCosmin Tanislav 	struct ad74413r_state *st = context;
171fea251b6SCosmin Tanislav 
172fea251b6SCosmin Tanislav 	ad74413r_format_reg_write(reg, val, st->reg_tx_buf);
173fea251b6SCosmin Tanislav 
174fea251b6SCosmin Tanislav 	return spi_write(st->spi, st->reg_tx_buf, AD74413R_FRAME_SIZE);
175fea251b6SCosmin Tanislav }
176fea251b6SCosmin Tanislav 
177fea251b6SCosmin Tanislav static int ad74413r_crc_check(struct ad74413r_state *st, u8 *buf)
178fea251b6SCosmin Tanislav {
179fea251b6SCosmin Tanislav 	u8 expected_crc = ad74413r_crc(buf);
180fea251b6SCosmin Tanislav 
181fea251b6SCosmin Tanislav 	if (buf[3] != expected_crc) {
182fea251b6SCosmin Tanislav 		dev_err(st->dev, "Bad CRC %02x for %02x%02x%02x\n",
183fea251b6SCosmin Tanislav 			buf[3], buf[0], buf[1], buf[2]);
184fea251b6SCosmin Tanislav 		return -EINVAL;
185fea251b6SCosmin Tanislav 	}
186fea251b6SCosmin Tanislav 
187fea251b6SCosmin Tanislav 	return 0;
188fea251b6SCosmin Tanislav }
189fea251b6SCosmin Tanislav 
190fea251b6SCosmin Tanislav static int ad74413r_reg_read(void *context, unsigned int reg, unsigned int *val)
191fea251b6SCosmin Tanislav {
192fea251b6SCosmin Tanislav 	struct ad74413r_state *st = context;
193fea251b6SCosmin Tanislav 	struct spi_transfer reg_read_xfer[] = {
194fea251b6SCosmin Tanislav 		{
195fea251b6SCosmin Tanislav 			.tx_buf = st->reg_tx_buf,
196fea251b6SCosmin Tanislav 			.len = AD74413R_FRAME_SIZE,
197fea251b6SCosmin Tanislav 			.cs_change = 1,
198fea251b6SCosmin Tanislav 		},
199fea251b6SCosmin Tanislav 		{
200fea251b6SCosmin Tanislav 			.rx_buf = st->reg_rx_buf,
201fea251b6SCosmin Tanislav 			.len = AD74413R_FRAME_SIZE,
202fea251b6SCosmin Tanislav 		},
203fea251b6SCosmin Tanislav 	};
204fea251b6SCosmin Tanislav 	int ret;
205fea251b6SCosmin Tanislav 
206fea251b6SCosmin Tanislav 	ad74413r_format_reg_write(AD74413R_REG_READ_SELECT, reg,
207fea251b6SCosmin Tanislav 				  st->reg_tx_buf);
208fea251b6SCosmin Tanislav 
209fea251b6SCosmin Tanislav 	ret = spi_sync_transfer(st->spi, reg_read_xfer,
210fea251b6SCosmin Tanislav 				ARRAY_SIZE(reg_read_xfer));
211fea251b6SCosmin Tanislav 	if (ret)
212fea251b6SCosmin Tanislav 		return ret;
213fea251b6SCosmin Tanislav 
214fea251b6SCosmin Tanislav 	ret = ad74413r_crc_check(st, st->reg_rx_buf);
215fea251b6SCosmin Tanislav 	if (ret)
216fea251b6SCosmin Tanislav 		return ret;
217fea251b6SCosmin Tanislav 
218fea251b6SCosmin Tanislav 	*val = get_unaligned_be16(&st->reg_rx_buf[1]);
219fea251b6SCosmin Tanislav 
220fea251b6SCosmin Tanislav 	return 0;
221fea251b6SCosmin Tanislav }
222fea251b6SCosmin Tanislav 
223fea251b6SCosmin Tanislav static const struct regmap_config ad74413r_regmap_config = {
224fea251b6SCosmin Tanislav 	.reg_bits = 8,
225fea251b6SCosmin Tanislav 	.val_bits = 16,
226fea251b6SCosmin Tanislav 	.reg_read = ad74413r_reg_read,
227fea251b6SCosmin Tanislav 	.reg_write = ad74413r_reg_write,
228fea251b6SCosmin Tanislav };
229fea251b6SCosmin Tanislav 
230fea251b6SCosmin Tanislav static int ad74413r_set_gpo_config(struct ad74413r_state *st,
231fea251b6SCosmin Tanislav 				   unsigned int offset, u8 mode)
232fea251b6SCosmin Tanislav {
233fea251b6SCosmin Tanislav 	return regmap_update_bits(st->regmap, AD74413R_REG_GPO_CONFIG_X(offset),
234fea251b6SCosmin Tanislav 				  AD74413R_GPO_CONFIG_SELECT_MASK, mode);
235fea251b6SCosmin Tanislav }
236fea251b6SCosmin Tanislav 
237fea251b6SCosmin Tanislav static const unsigned int ad74413r_debounce_map[AD74413R_DIN_DEBOUNCE_LEN] = {
238fea251b6SCosmin Tanislav 	0,     13,    18,    24,    32,    42,    56,    75,
239fea251b6SCosmin Tanislav 	100,   130,   180,   240,   320,   420,   560,   750,
240fea251b6SCosmin Tanislav 	1000,  1300,  1800,  2400,  3200,  4200,  5600,  7500,
241fea251b6SCosmin Tanislav 	10000, 13000, 18000, 24000, 32000, 42000, 56000, 75000,
242fea251b6SCosmin Tanislav };
243fea251b6SCosmin Tanislav 
244fea251b6SCosmin Tanislav static int ad74413r_set_comp_debounce(struct ad74413r_state *st,
245fea251b6SCosmin Tanislav 				      unsigned int offset,
246fea251b6SCosmin Tanislav 				      unsigned int debounce)
247fea251b6SCosmin Tanislav {
248fea251b6SCosmin Tanislav 	unsigned int val = AD74413R_DIN_DEBOUNCE_LEN - 1;
249fea251b6SCosmin Tanislav 	unsigned int i;
250fea251b6SCosmin Tanislav 
251fea251b6SCosmin Tanislav 	for (i = 0; i < AD74413R_DIN_DEBOUNCE_LEN; i++)
252fea251b6SCosmin Tanislav 		if (debounce <= ad74413r_debounce_map[i]) {
253fea251b6SCosmin Tanislav 			val = i;
254fea251b6SCosmin Tanislav 			break;
255fea251b6SCosmin Tanislav 		}
256fea251b6SCosmin Tanislav 
257fea251b6SCosmin Tanislav 	return regmap_update_bits(st->regmap,
258fea251b6SCosmin Tanislav 				  AD74413R_REG_DIN_CONFIG_X(offset),
259fea251b6SCosmin Tanislav 				  AD74413R_DIN_DEBOUNCE_MASK,
260fea251b6SCosmin Tanislav 				  val);
261fea251b6SCosmin Tanislav }
262fea251b6SCosmin Tanislav 
263fea251b6SCosmin Tanislav static void ad74413r_gpio_set(struct gpio_chip *chip,
264fea251b6SCosmin Tanislav 			      unsigned int offset, int val)
265fea251b6SCosmin Tanislav {
266fea251b6SCosmin Tanislav 	struct ad74413r_state *st = gpiochip_get_data(chip);
267fea251b6SCosmin Tanislav 	unsigned int real_offset = st->gpo_gpio_offsets[offset];
268fea251b6SCosmin Tanislav 	int ret;
269fea251b6SCosmin Tanislav 
270fea251b6SCosmin Tanislav 	ret = ad74413r_set_gpo_config(st, real_offset,
271fea251b6SCosmin Tanislav 				      AD74413R_GPO_CONFIG_LOGIC);
272fea251b6SCosmin Tanislav 	if (ret)
273fea251b6SCosmin Tanislav 		return;
274fea251b6SCosmin Tanislav 
275fea251b6SCosmin Tanislav 	regmap_update_bits(st->regmap, AD74413R_REG_GPO_CONFIG_X(real_offset),
276fea251b6SCosmin Tanislav 			   AD74413R_GPO_CONFIG_DATA_MASK,
277fea251b6SCosmin Tanislav 			   val ? AD74413R_GPO_CONFIG_DATA_MASK : 0);
278fea251b6SCosmin Tanislav }
279fea251b6SCosmin Tanislav 
280fea251b6SCosmin Tanislav static void ad74413r_gpio_set_multiple(struct gpio_chip *chip,
281fea251b6SCosmin Tanislav 				       unsigned long *mask,
282fea251b6SCosmin Tanislav 				       unsigned long *bits)
283fea251b6SCosmin Tanislav {
284fea251b6SCosmin Tanislav 	struct ad74413r_state *st = gpiochip_get_data(chip);
285fea251b6SCosmin Tanislav 	unsigned long real_mask = 0;
286fea251b6SCosmin Tanislav 	unsigned long real_bits = 0;
287fea251b6SCosmin Tanislav 	unsigned int offset = 0;
288fea251b6SCosmin Tanislav 	int ret;
289fea251b6SCosmin Tanislav 
2908a3e4a56SCosmin Tanislav 	for_each_set_bit_from(offset, mask, chip->ngpio) {
291fea251b6SCosmin Tanislav 		unsigned int real_offset = st->gpo_gpio_offsets[offset];
292fea251b6SCosmin Tanislav 
293fea251b6SCosmin Tanislav 		ret = ad74413r_set_gpo_config(st, real_offset,
294fea251b6SCosmin Tanislav 			AD74413R_GPO_CONFIG_LOGIC_PARALLEL);
295fea251b6SCosmin Tanislav 		if (ret)
296fea251b6SCosmin Tanislav 			return;
297fea251b6SCosmin Tanislav 
298fea251b6SCosmin Tanislav 		real_mask |= BIT(real_offset);
299fea251b6SCosmin Tanislav 		if (*bits & offset)
300fea251b6SCosmin Tanislav 			real_bits |= BIT(real_offset);
301fea251b6SCosmin Tanislav 	}
302fea251b6SCosmin Tanislav 
303fea251b6SCosmin Tanislav 	regmap_update_bits(st->regmap, AD74413R_REG_GPO_PAR_DATA,
304fea251b6SCosmin Tanislav 			   real_mask, real_bits);
305fea251b6SCosmin Tanislav }
306fea251b6SCosmin Tanislav 
307fea251b6SCosmin Tanislav static int ad74413r_gpio_get(struct gpio_chip *chip, unsigned int offset)
308fea251b6SCosmin Tanislav {
309fea251b6SCosmin Tanislav 	struct ad74413r_state *st = gpiochip_get_data(chip);
310fea251b6SCosmin Tanislav 	unsigned int real_offset = st->comp_gpio_offsets[offset];
311fea251b6SCosmin Tanislav 	unsigned int status;
312fea251b6SCosmin Tanislav 	int ret;
313fea251b6SCosmin Tanislav 
314fea251b6SCosmin Tanislav 	ret = regmap_read(st->regmap, AD74413R_REG_DIN_COMP_OUT, &status);
315fea251b6SCosmin Tanislav 	if (ret)
316fea251b6SCosmin Tanislav 		return ret;
317fea251b6SCosmin Tanislav 
318*4165456fSCosmin Tanislav 	status &= BIT(real_offset);
319fea251b6SCosmin Tanislav 
320fea251b6SCosmin Tanislav 	return status ? 1 : 0;
321fea251b6SCosmin Tanislav }
322fea251b6SCosmin Tanislav 
323fea251b6SCosmin Tanislav static int ad74413r_gpio_get_multiple(struct gpio_chip *chip,
324fea251b6SCosmin Tanislav 				      unsigned long *mask,
325fea251b6SCosmin Tanislav 				      unsigned long *bits)
326fea251b6SCosmin Tanislav {
327fea251b6SCosmin Tanislav 	struct ad74413r_state *st = gpiochip_get_data(chip);
328fea251b6SCosmin Tanislav 	unsigned int offset = 0;
329fea251b6SCosmin Tanislav 	unsigned int val;
330fea251b6SCosmin Tanislav 	int ret;
331fea251b6SCosmin Tanislav 
332fea251b6SCosmin Tanislav 	ret = regmap_read(st->regmap, AD74413R_REG_DIN_COMP_OUT, &val);
333fea251b6SCosmin Tanislav 	if (ret)
334fea251b6SCosmin Tanislav 		return ret;
335fea251b6SCosmin Tanislav 
3368a3e4a56SCosmin Tanislav 	for_each_set_bit_from(offset, mask, chip->ngpio) {
337fea251b6SCosmin Tanislav 		unsigned int real_offset = st->comp_gpio_offsets[offset];
338fea251b6SCosmin Tanislav 
339*4165456fSCosmin Tanislav 		__assign_bit(offset, bits, val & BIT(real_offset));
340fea251b6SCosmin Tanislav 	}
341fea251b6SCosmin Tanislav 
342fea251b6SCosmin Tanislav 	return ret;
343fea251b6SCosmin Tanislav }
344fea251b6SCosmin Tanislav 
345fea251b6SCosmin Tanislav static int ad74413r_gpio_get_gpo_direction(struct gpio_chip *chip,
346fea251b6SCosmin Tanislav 					   unsigned int offset)
347fea251b6SCosmin Tanislav {
348fea251b6SCosmin Tanislav 	return GPIO_LINE_DIRECTION_OUT;
349fea251b6SCosmin Tanislav }
350fea251b6SCosmin Tanislav 
351fea251b6SCosmin Tanislav static int ad74413r_gpio_get_comp_direction(struct gpio_chip *chip,
352fea251b6SCosmin Tanislav 					    unsigned int offset)
353fea251b6SCosmin Tanislav {
354fea251b6SCosmin Tanislav 	return GPIO_LINE_DIRECTION_IN;
355fea251b6SCosmin Tanislav }
356fea251b6SCosmin Tanislav 
357fea251b6SCosmin Tanislav static int ad74413r_gpio_set_gpo_config(struct gpio_chip *chip,
358fea251b6SCosmin Tanislav 					unsigned int offset,
359fea251b6SCosmin Tanislav 					unsigned long config)
360fea251b6SCosmin Tanislav {
361fea251b6SCosmin Tanislav 	struct ad74413r_state *st = gpiochip_get_data(chip);
362fea251b6SCosmin Tanislav 	unsigned int real_offset = st->gpo_gpio_offsets[offset];
363fea251b6SCosmin Tanislav 
364fea251b6SCosmin Tanislav 	switch (pinconf_to_config_param(config)) {
365fea251b6SCosmin Tanislav 	case PIN_CONFIG_BIAS_PULL_DOWN:
366fea251b6SCosmin Tanislav 		return ad74413r_set_gpo_config(st, real_offset,
367fea251b6SCosmin Tanislav 			AD74413R_GPO_CONFIG_100K_PULL_DOWN);
368fea251b6SCosmin Tanislav 	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
369fea251b6SCosmin Tanislav 		return ad74413r_set_gpo_config(st, real_offset,
370fea251b6SCosmin Tanislav 			AD74413R_GPO_CONFIG_HIGH_IMPEDANCE);
371fea251b6SCosmin Tanislav 	default:
372fea251b6SCosmin Tanislav 		return -ENOTSUPP;
373fea251b6SCosmin Tanislav 	}
374fea251b6SCosmin Tanislav }
375fea251b6SCosmin Tanislav 
376fea251b6SCosmin Tanislav static int ad74413r_gpio_set_comp_config(struct gpio_chip *chip,
377fea251b6SCosmin Tanislav 					 unsigned int offset,
378fea251b6SCosmin Tanislav 					 unsigned long config)
379fea251b6SCosmin Tanislav {
380fea251b6SCosmin Tanislav 	struct ad74413r_state *st = gpiochip_get_data(chip);
381fea251b6SCosmin Tanislav 	unsigned int real_offset = st->comp_gpio_offsets[offset];
382fea251b6SCosmin Tanislav 
383fea251b6SCosmin Tanislav 	switch (pinconf_to_config_param(config)) {
384fea251b6SCosmin Tanislav 	case PIN_CONFIG_INPUT_DEBOUNCE:
385fea251b6SCosmin Tanislav 		return ad74413r_set_comp_debounce(st, real_offset,
386fea251b6SCosmin Tanislav 			pinconf_to_config_argument(config));
387fea251b6SCosmin Tanislav 	default:
388fea251b6SCosmin Tanislav 		return -ENOTSUPP;
389fea251b6SCosmin Tanislav 	}
390fea251b6SCosmin Tanislav }
391fea251b6SCosmin Tanislav 
392fea251b6SCosmin Tanislav static int ad74413r_reset(struct ad74413r_state *st)
393fea251b6SCosmin Tanislav {
394fea251b6SCosmin Tanislav 	int ret;
395fea251b6SCosmin Tanislav 
396fea251b6SCosmin Tanislav 	ret = regmap_write(st->regmap, AD74413R_REG_CMD_KEY,
397fea251b6SCosmin Tanislav 			   AD74413R_CMD_KEY_RESET1);
398fea251b6SCosmin Tanislav 	if (ret)
399fea251b6SCosmin Tanislav 		return ret;
400fea251b6SCosmin Tanislav 
401fea251b6SCosmin Tanislav 	return regmap_write(st->regmap, AD74413R_REG_CMD_KEY,
402fea251b6SCosmin Tanislav 			    AD74413R_CMD_KEY_RESET2);
403fea251b6SCosmin Tanislav }
404fea251b6SCosmin Tanislav 
405fea251b6SCosmin Tanislav static int ad74413r_set_channel_dac_code(struct ad74413r_state *st,
406fea251b6SCosmin Tanislav 					 unsigned int channel, int dac_code)
407fea251b6SCosmin Tanislav {
408fea251b6SCosmin Tanislav 	struct reg_sequence reg_seq[2] = {
409fea251b6SCosmin Tanislav 		{ AD74413R_REG_DAC_CODE_X(channel), dac_code },
410fea251b6SCosmin Tanislav 		{ AD74413R_REG_CMD_KEY, AD74413R_CMD_KEY_LDAC },
411fea251b6SCosmin Tanislav 	};
412fea251b6SCosmin Tanislav 
413fea251b6SCosmin Tanislav 	return regmap_multi_reg_write(st->regmap, reg_seq, 2);
414fea251b6SCosmin Tanislav }
415fea251b6SCosmin Tanislav 
416fea251b6SCosmin Tanislav static int ad74413r_set_channel_function(struct ad74413r_state *st,
417fea251b6SCosmin Tanislav 					 unsigned int channel, u8 func)
418fea251b6SCosmin Tanislav {
419fea251b6SCosmin Tanislav 	return regmap_update_bits(st->regmap,
420fea251b6SCosmin Tanislav 				  AD74413R_REG_CH_FUNC_SETUP_X(channel),
421fea251b6SCosmin Tanislav 				  AD74413R_CH_FUNC_SETUP_MASK, func);
422fea251b6SCosmin Tanislav }
423fea251b6SCosmin Tanislav 
424fea251b6SCosmin Tanislav static int ad74413r_set_adc_conv_seq(struct ad74413r_state *st,
425fea251b6SCosmin Tanislav 				     unsigned int status)
426fea251b6SCosmin Tanislav {
427fea251b6SCosmin Tanislav 	int ret;
428fea251b6SCosmin Tanislav 
429fea251b6SCosmin Tanislav 	/*
430fea251b6SCosmin Tanislav 	 * These bits do not clear when a conversion completes.
431fea251b6SCosmin Tanislav 	 * To enable a subsequent conversion, repeat the write.
432fea251b6SCosmin Tanislav 	 */
433fea251b6SCosmin Tanislav 	ret = regmap_write_bits(st->regmap, AD74413R_REG_ADC_CONV_CTRL,
434fea251b6SCosmin Tanislav 				AD74413R_CONV_SEQ_MASK,
435fea251b6SCosmin Tanislav 				FIELD_PREP(AD74413R_CONV_SEQ_MASK, status));
436fea251b6SCosmin Tanislav 	if (ret)
437fea251b6SCosmin Tanislav 		return ret;
438fea251b6SCosmin Tanislav 
439fea251b6SCosmin Tanislav 	/*
440fea251b6SCosmin Tanislav 	 * Wait 100us before starting conversions.
441fea251b6SCosmin Tanislav 	 */
442fea251b6SCosmin Tanislav 	usleep_range(100, 120);
443fea251b6SCosmin Tanislav 
444fea251b6SCosmin Tanislav 	return 0;
445fea251b6SCosmin Tanislav }
446fea251b6SCosmin Tanislav 
447fea251b6SCosmin Tanislav static int ad74413r_set_adc_channel_enable(struct ad74413r_state *st,
448fea251b6SCosmin Tanislav 					   unsigned int channel,
449fea251b6SCosmin Tanislav 					   bool status)
450fea251b6SCosmin Tanislav {
451fea251b6SCosmin Tanislav 	return regmap_update_bits(st->regmap, AD74413R_REG_ADC_CONV_CTRL,
452fea251b6SCosmin Tanislav 				  AD74413R_CH_EN_MASK(channel),
453fea251b6SCosmin Tanislav 				  status ? AD74413R_CH_EN_MASK(channel) : 0);
454fea251b6SCosmin Tanislav }
455fea251b6SCosmin Tanislav 
456fea251b6SCosmin Tanislav static int ad74413r_get_adc_range(struct ad74413r_state *st,
457fea251b6SCosmin Tanislav 				  unsigned int channel,
458fea251b6SCosmin Tanislav 				  unsigned int *val)
459fea251b6SCosmin Tanislav {
460fea251b6SCosmin Tanislav 	int ret;
461fea251b6SCosmin Tanislav 
462fea251b6SCosmin Tanislav 	ret = regmap_read(st->regmap, AD74413R_REG_ADC_CONFIG_X(channel), val);
463fea251b6SCosmin Tanislav 	if (ret)
464fea251b6SCosmin Tanislav 		return ret;
465fea251b6SCosmin Tanislav 
466fea251b6SCosmin Tanislav 	*val = FIELD_GET(AD74413R_ADC_CONFIG_RANGE_MASK, *val);
467fea251b6SCosmin Tanislav 
468fea251b6SCosmin Tanislav 	return 0;
469fea251b6SCosmin Tanislav }
470fea251b6SCosmin Tanislav 
471fea251b6SCosmin Tanislav static int ad74413r_get_adc_rejection(struct ad74413r_state *st,
472fea251b6SCosmin Tanislav 				      unsigned int channel,
473fea251b6SCosmin Tanislav 				      unsigned int *val)
474fea251b6SCosmin Tanislav {
475fea251b6SCosmin Tanislav 	int ret;
476fea251b6SCosmin Tanislav 
477fea251b6SCosmin Tanislav 	ret = regmap_read(st->regmap, AD74413R_REG_ADC_CONFIG_X(channel), val);
478fea251b6SCosmin Tanislav 	if (ret)
479fea251b6SCosmin Tanislav 		return ret;
480fea251b6SCosmin Tanislav 
481fea251b6SCosmin Tanislav 	*val = FIELD_GET(AD74413R_ADC_CONFIG_REJECTION_MASK, *val);
482fea251b6SCosmin Tanislav 
483fea251b6SCosmin Tanislav 	return 0;
484fea251b6SCosmin Tanislav }
485fea251b6SCosmin Tanislav 
486fea251b6SCosmin Tanislav static int ad74413r_set_adc_rejection(struct ad74413r_state *st,
487fea251b6SCosmin Tanislav 				      unsigned int channel,
488fea251b6SCosmin Tanislav 				      unsigned int val)
489fea251b6SCosmin Tanislav {
490fea251b6SCosmin Tanislav 	return regmap_update_bits(st->regmap,
491fea251b6SCosmin Tanislav 				  AD74413R_REG_ADC_CONFIG_X(channel),
492fea251b6SCosmin Tanislav 				  AD74413R_ADC_CONFIG_REJECTION_MASK,
493fea251b6SCosmin Tanislav 				  FIELD_PREP(AD74413R_ADC_CONFIG_REJECTION_MASK,
494fea251b6SCosmin Tanislav 					     val));
495fea251b6SCosmin Tanislav }
496fea251b6SCosmin Tanislav 
497fea251b6SCosmin Tanislav static int ad74413r_rejection_to_rate(struct ad74413r_state *st,
498fea251b6SCosmin Tanislav 				      unsigned int rej, int *val)
499fea251b6SCosmin Tanislav {
500fea251b6SCosmin Tanislav 	switch (rej) {
501fea251b6SCosmin Tanislav 	case AD74413R_ADC_REJECTION_50_60:
502fea251b6SCosmin Tanislav 		*val = 20;
503fea251b6SCosmin Tanislav 		return 0;
504fea251b6SCosmin Tanislav 	case AD74413R_ADC_REJECTION_NONE:
505fea251b6SCosmin Tanislav 		*val = 4800;
506fea251b6SCosmin Tanislav 		return 0;
507fea251b6SCosmin Tanislav 	case AD74413R_ADC_REJECTION_50_60_HART:
508fea251b6SCosmin Tanislav 		*val = 10;
509fea251b6SCosmin Tanislav 		return 0;
510fea251b6SCosmin Tanislav 	case AD74413R_ADC_REJECTION_HART:
511fea251b6SCosmin Tanislav 		*val = 1200;
512fea251b6SCosmin Tanislav 		return 0;
513fea251b6SCosmin Tanislav 	default:
514fea251b6SCosmin Tanislav 		dev_err(st->dev, "ADC rejection invalid\n");
515fea251b6SCosmin Tanislav 		return -EINVAL;
516fea251b6SCosmin Tanislav 	}
517fea251b6SCosmin Tanislav }
518fea251b6SCosmin Tanislav 
519fea251b6SCosmin Tanislav static int ad74413r_rate_to_rejection(struct ad74413r_state *st,
520fea251b6SCosmin Tanislav 				      int rate, unsigned int *val)
521fea251b6SCosmin Tanislav {
522fea251b6SCosmin Tanislav 	switch (rate) {
523fea251b6SCosmin Tanislav 	case 20:
524fea251b6SCosmin Tanislav 		*val = AD74413R_ADC_REJECTION_50_60;
525fea251b6SCosmin Tanislav 		return 0;
526fea251b6SCosmin Tanislav 	case 4800:
527fea251b6SCosmin Tanislav 		*val = AD74413R_ADC_REJECTION_NONE;
528fea251b6SCosmin Tanislav 		return 0;
529fea251b6SCosmin Tanislav 	case 10:
530fea251b6SCosmin Tanislav 		*val = AD74413R_ADC_REJECTION_50_60_HART;
531fea251b6SCosmin Tanislav 		return 0;
532fea251b6SCosmin Tanislav 	case 1200:
533fea251b6SCosmin Tanislav 		*val = AD74413R_ADC_REJECTION_HART;
534fea251b6SCosmin Tanislav 		return 0;
535fea251b6SCosmin Tanislav 	default:
536fea251b6SCosmin Tanislav 		dev_err(st->dev, "ADC rate invalid\n");
537fea251b6SCosmin Tanislav 		return -EINVAL;
538fea251b6SCosmin Tanislav 	}
539fea251b6SCosmin Tanislav }
540fea251b6SCosmin Tanislav 
541fea251b6SCosmin Tanislav static int ad74413r_range_to_voltage_range(struct ad74413r_state *st,
542fea251b6SCosmin Tanislav 					   unsigned int range, int *val)
543fea251b6SCosmin Tanislav {
544fea251b6SCosmin Tanislav 	switch (range) {
545fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_10V:
546fea251b6SCosmin Tanislav 		*val = 10000;
547fea251b6SCosmin Tanislav 		return 0;
548fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_2P5V_EXT_POW:
549fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_2P5V_INT_POW:
550fea251b6SCosmin Tanislav 		*val = 2500;
551fea251b6SCosmin Tanislav 		return 0;
552fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_5V_BI_DIR:
553fea251b6SCosmin Tanislav 		*val = 5000;
554fea251b6SCosmin Tanislav 		return 0;
555fea251b6SCosmin Tanislav 	default:
556fea251b6SCosmin Tanislav 		dev_err(st->dev, "ADC range invalid\n");
557fea251b6SCosmin Tanislav 		return -EINVAL;
558fea251b6SCosmin Tanislav 	}
559fea251b6SCosmin Tanislav }
560fea251b6SCosmin Tanislav 
561fea251b6SCosmin Tanislav static int ad74413r_range_to_voltage_offset(struct ad74413r_state *st,
562fea251b6SCosmin Tanislav 					    unsigned int range, int *val)
563fea251b6SCosmin Tanislav {
564fea251b6SCosmin Tanislav 	switch (range) {
565fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_10V:
566fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_2P5V_EXT_POW:
567fea251b6SCosmin Tanislav 		*val = 0;
568fea251b6SCosmin Tanislav 		return 0;
569fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_2P5V_INT_POW:
570fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_5V_BI_DIR:
571fea251b6SCosmin Tanislav 		*val = -2500;
572fea251b6SCosmin Tanislav 		return 0;
573fea251b6SCosmin Tanislav 	default:
574fea251b6SCosmin Tanislav 		dev_err(st->dev, "ADC range invalid\n");
575fea251b6SCosmin Tanislav 		return -EINVAL;
576fea251b6SCosmin Tanislav 	}
577fea251b6SCosmin Tanislav }
578fea251b6SCosmin Tanislav 
579fea251b6SCosmin Tanislav static int ad74413r_range_to_voltage_offset_raw(struct ad74413r_state *st,
580fea251b6SCosmin Tanislav 						unsigned int range, int *val)
581fea251b6SCosmin Tanislav {
582fea251b6SCosmin Tanislav 	switch (range) {
583fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_10V:
584fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_2P5V_EXT_POW:
585fea251b6SCosmin Tanislav 		*val = 0;
586fea251b6SCosmin Tanislav 		return 0;
587fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_2P5V_INT_POW:
588fea251b6SCosmin Tanislav 		*val = -((int)AD74413R_ADC_RESULT_MAX);
589fea251b6SCosmin Tanislav 		return 0;
590fea251b6SCosmin Tanislav 	case AD74413R_ADC_RANGE_5V_BI_DIR:
591fea251b6SCosmin Tanislav 		*val = -((int)AD74413R_ADC_RESULT_MAX / 2);
592fea251b6SCosmin Tanislav 		return 0;
593fea251b6SCosmin Tanislav 	default:
594fea251b6SCosmin Tanislav 		dev_err(st->dev, "ADC range invalid\n");
595fea251b6SCosmin Tanislav 		return -EINVAL;
596fea251b6SCosmin Tanislav 	}
597fea251b6SCosmin Tanislav }
598fea251b6SCosmin Tanislav 
599fea251b6SCosmin Tanislav static int ad74413r_get_output_voltage_scale(struct ad74413r_state *st,
600fea251b6SCosmin Tanislav 					     int *val, int *val2)
601fea251b6SCosmin Tanislav {
602fea251b6SCosmin Tanislav 	*val = AD74413R_DAC_VOLTAGE_MAX;
603fea251b6SCosmin Tanislav 	*val2 = AD74413R_DAC_CODE_MAX;
604fea251b6SCosmin Tanislav 
605fea251b6SCosmin Tanislav 	return IIO_VAL_FRACTIONAL;
606fea251b6SCosmin Tanislav }
607fea251b6SCosmin Tanislav 
608fea251b6SCosmin Tanislav static int ad74413r_get_output_current_scale(struct ad74413r_state *st,
609fea251b6SCosmin Tanislav 					     int *val, int *val2)
610fea251b6SCosmin Tanislav {
611fea251b6SCosmin Tanislav 	*val = regulator_get_voltage(st->refin_reg);
612fea251b6SCosmin Tanislav 	*val2 = st->sense_resistor_ohms * AD74413R_DAC_CODE_MAX * 1000;
613fea251b6SCosmin Tanislav 
614fea251b6SCosmin Tanislav 	return IIO_VAL_FRACTIONAL;
615fea251b6SCosmin Tanislav }
616fea251b6SCosmin Tanislav 
617fea251b6SCosmin Tanislav static int ad74413r_get_input_voltage_scale(struct ad74413r_state *st,
618fea251b6SCosmin Tanislav 					    unsigned int channel,
619fea251b6SCosmin Tanislav 					    int *val, int *val2)
620fea251b6SCosmin Tanislav {
621fea251b6SCosmin Tanislav 	unsigned int range;
622fea251b6SCosmin Tanislav 	int ret;
623fea251b6SCosmin Tanislav 
624fea251b6SCosmin Tanislav 	ret = ad74413r_get_adc_range(st, channel, &range);
625fea251b6SCosmin Tanislav 	if (ret)
626fea251b6SCosmin Tanislav 		return ret;
627fea251b6SCosmin Tanislav 
628fea251b6SCosmin Tanislav 	ret = ad74413r_range_to_voltage_range(st, range, val);
629fea251b6SCosmin Tanislav 	if (ret)
630fea251b6SCosmin Tanislav 		return ret;
631fea251b6SCosmin Tanislav 
632fea251b6SCosmin Tanislav 	*val2 = AD74413R_ADC_RESULT_MAX;
633fea251b6SCosmin Tanislav 
634fea251b6SCosmin Tanislav 	return IIO_VAL_FRACTIONAL;
635fea251b6SCosmin Tanislav }
636fea251b6SCosmin Tanislav 
637fea251b6SCosmin Tanislav static int ad74413r_get_input_voltage_offset(struct ad74413r_state *st,
638fea251b6SCosmin Tanislav 					     unsigned int channel, int *val)
639fea251b6SCosmin Tanislav {
640fea251b6SCosmin Tanislav 	unsigned int range;
641fea251b6SCosmin Tanislav 	int ret;
642fea251b6SCosmin Tanislav 
643fea251b6SCosmin Tanislav 	ret = ad74413r_get_adc_range(st, channel, &range);
644fea251b6SCosmin Tanislav 	if (ret)
645fea251b6SCosmin Tanislav 		return ret;
646fea251b6SCosmin Tanislav 
647fea251b6SCosmin Tanislav 	ret = ad74413r_range_to_voltage_offset_raw(st, range, val);
648fea251b6SCosmin Tanislav 	if (ret)
649fea251b6SCosmin Tanislav 		return ret;
650fea251b6SCosmin Tanislav 
651fea251b6SCosmin Tanislav 	return IIO_VAL_INT;
652fea251b6SCosmin Tanislav }
653fea251b6SCosmin Tanislav 
654fea251b6SCosmin Tanislav static int ad74413r_get_input_current_scale(struct ad74413r_state *st,
655fea251b6SCosmin Tanislav 					    unsigned int channel, int *val,
656fea251b6SCosmin Tanislav 					    int *val2)
657fea251b6SCosmin Tanislav {
658fea251b6SCosmin Tanislav 	unsigned int range;
659fea251b6SCosmin Tanislav 	int ret;
660fea251b6SCosmin Tanislav 
661fea251b6SCosmin Tanislav 	ret = ad74413r_get_adc_range(st, channel, &range);
662fea251b6SCosmin Tanislav 	if (ret)
663fea251b6SCosmin Tanislav 		return ret;
664fea251b6SCosmin Tanislav 
665fea251b6SCosmin Tanislav 	ret = ad74413r_range_to_voltage_range(st, range, val);
666fea251b6SCosmin Tanislav 	if (ret)
667fea251b6SCosmin Tanislav 		return ret;
668fea251b6SCosmin Tanislav 
669fea251b6SCosmin Tanislav 	*val2 = AD74413R_ADC_RESULT_MAX * st->sense_resistor_ohms;
670fea251b6SCosmin Tanislav 
671fea251b6SCosmin Tanislav 	return IIO_VAL_FRACTIONAL;
672fea251b6SCosmin Tanislav }
673fea251b6SCosmin Tanislav 
674fea251b6SCosmin Tanislav static int ad74413_get_input_current_offset(struct ad74413r_state *st,
675fea251b6SCosmin Tanislav 					    unsigned int channel, int *val)
676fea251b6SCosmin Tanislav {
677fea251b6SCosmin Tanislav 	unsigned int range;
678fea251b6SCosmin Tanislav 	int voltage_range;
679fea251b6SCosmin Tanislav 	int voltage_offset;
680fea251b6SCosmin Tanislav 	int ret;
681fea251b6SCosmin Tanislav 
682fea251b6SCosmin Tanislav 	ret = ad74413r_get_adc_range(st, channel, &range);
683fea251b6SCosmin Tanislav 	if (ret)
684fea251b6SCosmin Tanislav 		return ret;
685fea251b6SCosmin Tanislav 
686fea251b6SCosmin Tanislav 	ret = ad74413r_range_to_voltage_range(st, range, &voltage_range);
687fea251b6SCosmin Tanislav 	if (ret)
688fea251b6SCosmin Tanislav 		return ret;
689fea251b6SCosmin Tanislav 
690fea251b6SCosmin Tanislav 	ret = ad74413r_range_to_voltage_offset(st, range, &voltage_offset);
691fea251b6SCosmin Tanislav 	if (ret)
692fea251b6SCosmin Tanislav 		return ret;
693fea251b6SCosmin Tanislav 
694fea251b6SCosmin Tanislav 	*val = voltage_offset * AD74413R_ADC_RESULT_MAX / voltage_range;
695fea251b6SCosmin Tanislav 
696fea251b6SCosmin Tanislav 	return IIO_VAL_INT;
697fea251b6SCosmin Tanislav }
698fea251b6SCosmin Tanislav 
699fea251b6SCosmin Tanislav static int ad74413r_get_adc_rate(struct ad74413r_state *st,
700fea251b6SCosmin Tanislav 				 unsigned int channel, int *val)
701fea251b6SCosmin Tanislav {
702fea251b6SCosmin Tanislav 	unsigned int rejection;
703fea251b6SCosmin Tanislav 	int ret;
704fea251b6SCosmin Tanislav 
705fea251b6SCosmin Tanislav 	ret = ad74413r_get_adc_rejection(st, channel, &rejection);
706fea251b6SCosmin Tanislav 	if (ret)
707fea251b6SCosmin Tanislav 		return ret;
708fea251b6SCosmin Tanislav 
709fea251b6SCosmin Tanislav 	ret = ad74413r_rejection_to_rate(st, rejection, val);
710fea251b6SCosmin Tanislav 	if (ret)
711fea251b6SCosmin Tanislav 		return ret;
712fea251b6SCosmin Tanislav 
713fea251b6SCosmin Tanislav 	return IIO_VAL_INT;
714fea251b6SCosmin Tanislav }
715fea251b6SCosmin Tanislav 
716fea251b6SCosmin Tanislav static int ad74413r_set_adc_rate(struct ad74413r_state *st,
717fea251b6SCosmin Tanislav 				 unsigned int channel, int val)
718fea251b6SCosmin Tanislav {
719fea251b6SCosmin Tanislav 	unsigned int rejection;
720fea251b6SCosmin Tanislav 	int ret;
721fea251b6SCosmin Tanislav 
722fea251b6SCosmin Tanislav 	ret = ad74413r_rate_to_rejection(st, val, &rejection);
723fea251b6SCosmin Tanislav 	if (ret)
724fea251b6SCosmin Tanislav 		return ret;
725fea251b6SCosmin Tanislav 
726fea251b6SCosmin Tanislav 	return ad74413r_set_adc_rejection(st, channel, rejection);
727fea251b6SCosmin Tanislav }
728fea251b6SCosmin Tanislav 
729fea251b6SCosmin Tanislav static irqreturn_t ad74413r_trigger_handler(int irq, void *p)
730fea251b6SCosmin Tanislav {
731fea251b6SCosmin Tanislav 	struct iio_poll_func *pf = p;
732fea251b6SCosmin Tanislav 	struct iio_dev *indio_dev = pf->indio_dev;
733fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
734fea251b6SCosmin Tanislav 	u8 *rx_buf = st->adc_samples_buf.rx_buf;
735fea251b6SCosmin Tanislav 	unsigned int i;
736fea251b6SCosmin Tanislav 	int ret;
737fea251b6SCosmin Tanislav 
738fea251b6SCosmin Tanislav 	ret = spi_sync(st->spi, &st->adc_samples_msg);
739fea251b6SCosmin Tanislav 	if (ret)
740fea251b6SCosmin Tanislav 		goto out;
741fea251b6SCosmin Tanislav 
742fea251b6SCosmin Tanislav 	for (i = 0; i < st->adc_active_channels; i++)
743fea251b6SCosmin Tanislav 		ad74413r_crc_check(st, &rx_buf[i * AD74413R_FRAME_SIZE]);
744fea251b6SCosmin Tanislav 
745fea251b6SCosmin Tanislav 	iio_push_to_buffers_with_timestamp(indio_dev, &st->adc_samples_buf,
746fea251b6SCosmin Tanislav 					   iio_get_time_ns(indio_dev));
747fea251b6SCosmin Tanislav 
748fea251b6SCosmin Tanislav out:
749fea251b6SCosmin Tanislav 	iio_trigger_notify_done(indio_dev->trig);
750fea251b6SCosmin Tanislav 
751fea251b6SCosmin Tanislav 	return IRQ_HANDLED;
752fea251b6SCosmin Tanislav }
753fea251b6SCosmin Tanislav 
754fea251b6SCosmin Tanislav static irqreturn_t ad74413r_adc_data_interrupt(int irq, void *data)
755fea251b6SCosmin Tanislav {
756fea251b6SCosmin Tanislav 	struct iio_dev *indio_dev = data;
757fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
758fea251b6SCosmin Tanislav 
759fea251b6SCosmin Tanislav 	if (iio_buffer_enabled(indio_dev))
760fea251b6SCosmin Tanislav 		iio_trigger_poll(st->trig);
761fea251b6SCosmin Tanislav 	else
762fea251b6SCosmin Tanislav 		complete(&st->adc_data_completion);
763fea251b6SCosmin Tanislav 
764fea251b6SCosmin Tanislav 	return IRQ_HANDLED;
765fea251b6SCosmin Tanislav }
766fea251b6SCosmin Tanislav 
767fea251b6SCosmin Tanislav static int _ad74413r_get_single_adc_result(struct ad74413r_state *st,
768fea251b6SCosmin Tanislav 					   unsigned int channel, int *val)
769fea251b6SCosmin Tanislav {
770fea251b6SCosmin Tanislav 	unsigned int uval;
771fea251b6SCosmin Tanislav 	int ret;
772fea251b6SCosmin Tanislav 
773fea251b6SCosmin Tanislav 	reinit_completion(&st->adc_data_completion);
774fea251b6SCosmin Tanislav 
775fea251b6SCosmin Tanislav 	ret = ad74413r_set_adc_channel_enable(st, channel, true);
776fea251b6SCosmin Tanislav 	if (ret)
777fea251b6SCosmin Tanislav 		return ret;
778fea251b6SCosmin Tanislav 
779fea251b6SCosmin Tanislav 	ret = ad74413r_set_adc_conv_seq(st, AD74413R_CONV_SEQ_SINGLE);
780fea251b6SCosmin Tanislav 	if (ret)
781fea251b6SCosmin Tanislav 		return ret;
782fea251b6SCosmin Tanislav 
783fea251b6SCosmin Tanislav 	ret = wait_for_completion_timeout(&st->adc_data_completion,
784fea251b6SCosmin Tanislav 					  msecs_to_jiffies(1000));
785fea251b6SCosmin Tanislav 	if (!ret) {
786fea251b6SCosmin Tanislav 		ret = -ETIMEDOUT;
787fea251b6SCosmin Tanislav 		return ret;
788fea251b6SCosmin Tanislav 	}
789fea251b6SCosmin Tanislav 
790fea251b6SCosmin Tanislav 	ret = regmap_read(st->regmap, AD74413R_REG_ADC_RESULT_X(channel),
791fea251b6SCosmin Tanislav 			  &uval);
792fea251b6SCosmin Tanislav 	if (ret)
793fea251b6SCosmin Tanislav 		return ret;
794fea251b6SCosmin Tanislav 
795fea251b6SCosmin Tanislav 	ret = ad74413r_set_adc_conv_seq(st, AD74413R_CONV_SEQ_OFF);
796fea251b6SCosmin Tanislav 	if (ret)
797fea251b6SCosmin Tanislav 		return ret;
798fea251b6SCosmin Tanislav 
799fea251b6SCosmin Tanislav 	ret = ad74413r_set_adc_channel_enable(st, channel, false);
800fea251b6SCosmin Tanislav 	if (ret)
801fea251b6SCosmin Tanislav 		return ret;
802fea251b6SCosmin Tanislav 
803fea251b6SCosmin Tanislav 	*val = uval;
804fea251b6SCosmin Tanislav 
805fea251b6SCosmin Tanislav 	return IIO_VAL_INT;
806fea251b6SCosmin Tanislav }
807fea251b6SCosmin Tanislav 
808fea251b6SCosmin Tanislav static int ad74413r_get_single_adc_result(struct iio_dev *indio_dev,
809fea251b6SCosmin Tanislav 					  unsigned int channel, int *val)
810fea251b6SCosmin Tanislav {
811fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
812fea251b6SCosmin Tanislav 	int ret;
813fea251b6SCosmin Tanislav 
814fea251b6SCosmin Tanislav 	ret = iio_device_claim_direct_mode(indio_dev);
815fea251b6SCosmin Tanislav 	if (ret)
816fea251b6SCosmin Tanislav 		return ret;
817fea251b6SCosmin Tanislav 
818fea251b6SCosmin Tanislav 	mutex_lock(&st->lock);
819fea251b6SCosmin Tanislav 	ret = _ad74413r_get_single_adc_result(st, channel, val);
820fea251b6SCosmin Tanislav 	mutex_unlock(&st->lock);
821fea251b6SCosmin Tanislav 
822fea251b6SCosmin Tanislav 	iio_device_release_direct_mode(indio_dev);
823fea251b6SCosmin Tanislav 
824fea251b6SCosmin Tanislav 	return ret;
825fea251b6SCosmin Tanislav }
826fea251b6SCosmin Tanislav 
827fea251b6SCosmin Tanislav static void ad74413r_adc_to_resistance_result(int adc_result, int *val)
828fea251b6SCosmin Tanislav {
829fea251b6SCosmin Tanislav 	if (adc_result == AD74413R_ADC_RESULT_MAX)
830fea251b6SCosmin Tanislav 		adc_result = AD74413R_ADC_RESULT_MAX - 1;
831fea251b6SCosmin Tanislav 
832fea251b6SCosmin Tanislav 	*val = DIV_ROUND_CLOSEST(adc_result * 2100,
833fea251b6SCosmin Tanislav 				 AD74413R_ADC_RESULT_MAX - adc_result);
834fea251b6SCosmin Tanislav }
835fea251b6SCosmin Tanislav 
836fea251b6SCosmin Tanislav static int ad74413r_update_scan_mode(struct iio_dev *indio_dev,
837fea251b6SCosmin Tanislav 				     const unsigned long *active_scan_mask)
838fea251b6SCosmin Tanislav {
839fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
840fea251b6SCosmin Tanislav 	struct spi_transfer *xfer = st->adc_samples_xfer;
841e7a3290dSKees Cook 	u8 *rx_buf = st->adc_samples_buf.rx_buf;
842fea251b6SCosmin Tanislav 	u8 *tx_buf = st->adc_samples_tx_buf;
843fea251b6SCosmin Tanislav 	unsigned int channel;
844f4a73a97SJonathan Cameron 	int ret = -EINVAL;
845fea251b6SCosmin Tanislav 
846fea251b6SCosmin Tanislav 	mutex_lock(&st->lock);
847fea251b6SCosmin Tanislav 
848fea251b6SCosmin Tanislav 	spi_message_init(&st->adc_samples_msg);
849fea251b6SCosmin Tanislav 	st->adc_active_channels = 0;
850fea251b6SCosmin Tanislav 
851fea251b6SCosmin Tanislav 	for_each_clear_bit(channel, active_scan_mask, AD74413R_CHANNEL_MAX) {
852fea251b6SCosmin Tanislav 		ret = ad74413r_set_adc_channel_enable(st, channel, false);
853fea251b6SCosmin Tanislav 		if (ret)
854fea251b6SCosmin Tanislav 			goto out;
855fea251b6SCosmin Tanislav 	}
856fea251b6SCosmin Tanislav 
857fea251b6SCosmin Tanislav 	if (*active_scan_mask == 0)
858fea251b6SCosmin Tanislav 		goto out;
859fea251b6SCosmin Tanislav 
860fea251b6SCosmin Tanislav 	/*
861fea251b6SCosmin Tanislav 	 * The read select register is used to select which register's value
862fea251b6SCosmin Tanislav 	 * will be sent by the slave on the next SPI frame.
863fea251b6SCosmin Tanislav 	 *
864fea251b6SCosmin Tanislav 	 * Create an SPI message that, on each step, writes to the read select
865fea251b6SCosmin Tanislav 	 * register to select the ADC result of the next enabled channel, and
866fea251b6SCosmin Tanislav 	 * reads the ADC result of the previous enabled channel.
867fea251b6SCosmin Tanislav 	 *
868fea251b6SCosmin Tanislav 	 * Example:
869fea251b6SCosmin Tanislav 	 * W: [WCH1] [WCH2] [WCH2] [WCH3] [    ]
870fea251b6SCosmin Tanislav 	 * R: [    ] [RCH1] [RCH2] [RCH3] [RCH4]
871fea251b6SCosmin Tanislav 	 */
872fea251b6SCosmin Tanislav 
873fea251b6SCosmin Tanislav 	for_each_set_bit(channel, active_scan_mask, AD74413R_CHANNEL_MAX) {
874fea251b6SCosmin Tanislav 		ret = ad74413r_set_adc_channel_enable(st, channel, true);
875fea251b6SCosmin Tanislav 		if (ret)
876fea251b6SCosmin Tanislav 			goto out;
877fea251b6SCosmin Tanislav 
878fea251b6SCosmin Tanislav 		st->adc_active_channels++;
879fea251b6SCosmin Tanislav 
880fea251b6SCosmin Tanislav 		if (xfer == st->adc_samples_xfer)
881fea251b6SCosmin Tanislav 			xfer->rx_buf = NULL;
882fea251b6SCosmin Tanislav 		else
883fea251b6SCosmin Tanislav 			xfer->rx_buf = rx_buf;
884fea251b6SCosmin Tanislav 
885fea251b6SCosmin Tanislav 		xfer->tx_buf = tx_buf;
886fea251b6SCosmin Tanislav 		xfer->len = AD74413R_FRAME_SIZE;
887fea251b6SCosmin Tanislav 		xfer->cs_change = 1;
888fea251b6SCosmin Tanislav 
889fea251b6SCosmin Tanislav 		ad74413r_format_reg_write(AD74413R_REG_READ_SELECT,
890fea251b6SCosmin Tanislav 					  AD74413R_REG_ADC_RESULT_X(channel),
891fea251b6SCosmin Tanislav 					  tx_buf);
892fea251b6SCosmin Tanislav 
893fea251b6SCosmin Tanislav 		spi_message_add_tail(xfer, &st->adc_samples_msg);
894fea251b6SCosmin Tanislav 
895fea251b6SCosmin Tanislav 		tx_buf += AD74413R_FRAME_SIZE;
896e7a3290dSKees Cook 		if (xfer != st->adc_samples_xfer)
897fea251b6SCosmin Tanislav 			rx_buf += AD74413R_FRAME_SIZE;
898e7a3290dSKees Cook 		xfer++;
899fea251b6SCosmin Tanislav 	}
900fea251b6SCosmin Tanislav 
901fea251b6SCosmin Tanislav 	xfer->rx_buf = rx_buf;
902fea251b6SCosmin Tanislav 	xfer->tx_buf = NULL;
903fea251b6SCosmin Tanislav 	xfer->len = AD74413R_FRAME_SIZE;
904fea251b6SCosmin Tanislav 	xfer->cs_change = 0;
905fea251b6SCosmin Tanislav 
906fea251b6SCosmin Tanislav 	spi_message_add_tail(xfer, &st->adc_samples_msg);
907fea251b6SCosmin Tanislav 
908fea251b6SCosmin Tanislav out:
909fea251b6SCosmin Tanislav 	mutex_unlock(&st->lock);
910fea251b6SCosmin Tanislav 
911fea251b6SCosmin Tanislav 	return ret;
912fea251b6SCosmin Tanislav }
913fea251b6SCosmin Tanislav 
914fea251b6SCosmin Tanislav static int ad74413r_buffer_postenable(struct iio_dev *indio_dev)
915fea251b6SCosmin Tanislav {
916fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
917fea251b6SCosmin Tanislav 
918fea251b6SCosmin Tanislav 	return ad74413r_set_adc_conv_seq(st, AD74413R_CONV_SEQ_CONTINUOUS);
919fea251b6SCosmin Tanislav }
920fea251b6SCosmin Tanislav 
921fea251b6SCosmin Tanislav static int ad74413r_buffer_predisable(struct iio_dev *indio_dev)
922fea251b6SCosmin Tanislav {
923fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
924fea251b6SCosmin Tanislav 
925fea251b6SCosmin Tanislav 	return ad74413r_set_adc_conv_seq(st, AD74413R_CONV_SEQ_OFF);
926fea251b6SCosmin Tanislav }
927fea251b6SCosmin Tanislav 
928fea251b6SCosmin Tanislav static int ad74413r_read_raw(struct iio_dev *indio_dev,
929fea251b6SCosmin Tanislav 			     struct iio_chan_spec const *chan,
930fea251b6SCosmin Tanislav 			     int *val, int *val2, long info)
931fea251b6SCosmin Tanislav {
932fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
933fea251b6SCosmin Tanislav 
934fea251b6SCosmin Tanislav 	switch (info) {
935fea251b6SCosmin Tanislav 	case IIO_CHAN_INFO_SCALE:
936fea251b6SCosmin Tanislav 		switch (chan->type) {
937fea251b6SCosmin Tanislav 		case IIO_VOLTAGE:
938fea251b6SCosmin Tanislav 			if (chan->output)
939fea251b6SCosmin Tanislav 				return ad74413r_get_output_voltage_scale(st,
940fea251b6SCosmin Tanislav 					val, val2);
941fea251b6SCosmin Tanislav 			else
942fea251b6SCosmin Tanislav 				return ad74413r_get_input_voltage_scale(st,
943fea251b6SCosmin Tanislav 					chan->channel, val, val2);
944fea251b6SCosmin Tanislav 		case IIO_CURRENT:
945fea251b6SCosmin Tanislav 			if (chan->output)
946fea251b6SCosmin Tanislav 				return ad74413r_get_output_current_scale(st,
947fea251b6SCosmin Tanislav 					val, val2);
948fea251b6SCosmin Tanislav 			else
949fea251b6SCosmin Tanislav 				return ad74413r_get_input_current_scale(st,
950fea251b6SCosmin Tanislav 					chan->channel, val, val2);
951fea251b6SCosmin Tanislav 		default:
952fea251b6SCosmin Tanislav 			return -EINVAL;
953fea251b6SCosmin Tanislav 		}
954fea251b6SCosmin Tanislav 	case IIO_CHAN_INFO_OFFSET:
955fea251b6SCosmin Tanislav 		switch (chan->type) {
956fea251b6SCosmin Tanislav 		case IIO_VOLTAGE:
957fea251b6SCosmin Tanislav 			return ad74413r_get_input_voltage_offset(st,
958fea251b6SCosmin Tanislav 				chan->channel, val);
959fea251b6SCosmin Tanislav 		case IIO_CURRENT:
960fea251b6SCosmin Tanislav 			return ad74413_get_input_current_offset(st,
961fea251b6SCosmin Tanislav 				chan->channel, val);
962fea251b6SCosmin Tanislav 		default:
963fea251b6SCosmin Tanislav 			return -EINVAL;
964fea251b6SCosmin Tanislav 		}
965fea251b6SCosmin Tanislav 	case IIO_CHAN_INFO_RAW:
966fea251b6SCosmin Tanislav 		if (chan->output)
967fea251b6SCosmin Tanislav 			return -EINVAL;
968fea251b6SCosmin Tanislav 
969fea251b6SCosmin Tanislav 		return ad74413r_get_single_adc_result(indio_dev, chan->channel,
970fea251b6SCosmin Tanislav 						      val);
971fea251b6SCosmin Tanislav 	case IIO_CHAN_INFO_PROCESSED: {
972fea251b6SCosmin Tanislav 		int ret;
973fea251b6SCosmin Tanislav 
974fea251b6SCosmin Tanislav 		ret = ad74413r_get_single_adc_result(indio_dev, chan->channel,
975fea251b6SCosmin Tanislav 						     val);
976fea251b6SCosmin Tanislav 		if (ret)
977fea251b6SCosmin Tanislav 			return ret;
978fea251b6SCosmin Tanislav 
979fea251b6SCosmin Tanislav 		ad74413r_adc_to_resistance_result(*val, val);
980fea251b6SCosmin Tanislav 
981fea251b6SCosmin Tanislav 		return ret;
982fea251b6SCosmin Tanislav 	}
983fea251b6SCosmin Tanislav 	case IIO_CHAN_INFO_SAMP_FREQ:
984fea251b6SCosmin Tanislav 		return ad74413r_get_adc_rate(st, chan->channel, val);
985fea251b6SCosmin Tanislav 	default:
986fea251b6SCosmin Tanislav 		return -EINVAL;
987fea251b6SCosmin Tanislav 	}
988fea251b6SCosmin Tanislav }
989fea251b6SCosmin Tanislav 
990fea251b6SCosmin Tanislav static int ad74413r_write_raw(struct iio_dev *indio_dev,
991fea251b6SCosmin Tanislav 			      struct iio_chan_spec const *chan,
992fea251b6SCosmin Tanislav 			      int val, int val2, long info)
993fea251b6SCosmin Tanislav {
994fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
995fea251b6SCosmin Tanislav 
996fea251b6SCosmin Tanislav 	switch (info) {
997fea251b6SCosmin Tanislav 	case IIO_CHAN_INFO_RAW:
998fea251b6SCosmin Tanislav 		if (!chan->output)
999fea251b6SCosmin Tanislav 			return -EINVAL;
1000fea251b6SCosmin Tanislav 
1001fea251b6SCosmin Tanislav 		if (val < 0 || val > AD74413R_DAC_CODE_MAX) {
1002fea251b6SCosmin Tanislav 			dev_err(st->dev, "Invalid DAC code\n");
1003fea251b6SCosmin Tanislav 			return -EINVAL;
1004fea251b6SCosmin Tanislav 		}
1005fea251b6SCosmin Tanislav 
1006fea251b6SCosmin Tanislav 		return ad74413r_set_channel_dac_code(st, chan->channel, val);
1007fea251b6SCosmin Tanislav 	case IIO_CHAN_INFO_SAMP_FREQ:
1008fea251b6SCosmin Tanislav 		return ad74413r_set_adc_rate(st, chan->channel, val);
1009fea251b6SCosmin Tanislav 	default:
1010fea251b6SCosmin Tanislav 		return -EINVAL;
1011fea251b6SCosmin Tanislav 	}
1012fea251b6SCosmin Tanislav }
1013fea251b6SCosmin Tanislav 
1014fea251b6SCosmin Tanislav static int ad74413r_read_avail(struct iio_dev *indio_dev,
1015fea251b6SCosmin Tanislav 			       struct iio_chan_spec const *chan,
1016fea251b6SCosmin Tanislav 			       const int **vals, int *type, int *length,
1017fea251b6SCosmin Tanislav 			       long info)
1018fea251b6SCosmin Tanislav {
1019fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
1020fea251b6SCosmin Tanislav 
1021fea251b6SCosmin Tanislav 	switch (info) {
1022fea251b6SCosmin Tanislav 	case IIO_CHAN_INFO_SAMP_FREQ:
1023fea251b6SCosmin Tanislav 		if (st->chip_info->hart_support) {
1024fea251b6SCosmin Tanislav 			*vals = ad74413r_adc_sampling_rates_hart;
1025fea251b6SCosmin Tanislav 			*length = ARRAY_SIZE(ad74413r_adc_sampling_rates_hart);
1026fea251b6SCosmin Tanislav 		} else {
1027fea251b6SCosmin Tanislav 			*vals = ad74413r_adc_sampling_rates;
1028fea251b6SCosmin Tanislav 			*length = ARRAY_SIZE(ad74413r_adc_sampling_rates);
1029fea251b6SCosmin Tanislav 		}
1030fea251b6SCosmin Tanislav 		*type = IIO_VAL_INT;
1031fea251b6SCosmin Tanislav 		return IIO_AVAIL_LIST;
1032fea251b6SCosmin Tanislav 	default:
1033fea251b6SCosmin Tanislav 		return -EINVAL;
1034fea251b6SCosmin Tanislav 	}
1035fea251b6SCosmin Tanislav }
1036fea251b6SCosmin Tanislav 
1037fea251b6SCosmin Tanislav static const struct iio_buffer_setup_ops ad74413r_buffer_ops = {
1038fea251b6SCosmin Tanislav 	.postenable = &ad74413r_buffer_postenable,
1039fea251b6SCosmin Tanislav 	.predisable = &ad74413r_buffer_predisable,
1040fea251b6SCosmin Tanislav };
1041fea251b6SCosmin Tanislav 
1042fea251b6SCosmin Tanislav static const struct iio_trigger_ops ad74413r_trigger_ops = {
1043fea251b6SCosmin Tanislav 	.validate_device = iio_trigger_validate_own_device,
1044fea251b6SCosmin Tanislav };
1045fea251b6SCosmin Tanislav 
1046fea251b6SCosmin Tanislav static const struct iio_info ad74413r_info = {
1047fea251b6SCosmin Tanislav 	.read_raw = &ad74413r_read_raw,
1048fea251b6SCosmin Tanislav 	.write_raw = &ad74413r_write_raw,
1049fea251b6SCosmin Tanislav 	.read_avail = &ad74413r_read_avail,
1050fea251b6SCosmin Tanislav 	.update_scan_mode = &ad74413r_update_scan_mode,
1051fea251b6SCosmin Tanislav };
1052fea251b6SCosmin Tanislav 
1053fea251b6SCosmin Tanislav #define AD74413R_DAC_CHANNEL(_type, extra_mask_separate)		\
1054fea251b6SCosmin Tanislav 	{								\
1055fea251b6SCosmin Tanislav 		.type = (_type),					\
1056fea251b6SCosmin Tanislav 		.indexed = 1,						\
1057fea251b6SCosmin Tanislav 		.output = 1,						\
1058fea251b6SCosmin Tanislav 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW)		\
1059fea251b6SCosmin Tanislav 				      | (extra_mask_separate),		\
1060fea251b6SCosmin Tanislav 	}
1061fea251b6SCosmin Tanislav 
1062fea251b6SCosmin Tanislav #define AD74413R_ADC_CHANNEL(_type, extra_mask_separate)		\
1063fea251b6SCosmin Tanislav 	{								\
1064fea251b6SCosmin Tanislav 		.type = (_type),					\
1065fea251b6SCosmin Tanislav 		.indexed = 1,						\
1066fea251b6SCosmin Tanislav 		.output = 0,						\
1067fea251b6SCosmin Tanislav 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW)		\
1068fea251b6SCosmin Tanislav 				      | BIT(IIO_CHAN_INFO_SAMP_FREQ)	\
1069fea251b6SCosmin Tanislav 				      | (extra_mask_separate),		\
1070fea251b6SCosmin Tanislav 		.info_mask_separate_available =				\
1071fea251b6SCosmin Tanislav 					BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
1072fea251b6SCosmin Tanislav 		.scan_type = {						\
1073fea251b6SCosmin Tanislav 			.sign = 'u',					\
1074fea251b6SCosmin Tanislav 			.realbits = 16,					\
1075fea251b6SCosmin Tanislav 			.storagebits = 32,				\
1076fea251b6SCosmin Tanislav 			.shift = 8,					\
1077fea251b6SCosmin Tanislav 			.endianness = IIO_BE,				\
1078fea251b6SCosmin Tanislav 		},							\
1079fea251b6SCosmin Tanislav 	}
1080fea251b6SCosmin Tanislav 
1081fea251b6SCosmin Tanislav #define AD74413R_ADC_VOLTAGE_CHANNEL					\
1082fea251b6SCosmin Tanislav 	AD74413R_ADC_CHANNEL(IIO_VOLTAGE, BIT(IIO_CHAN_INFO_SCALE)	\
1083fea251b6SCosmin Tanislav 			     | BIT(IIO_CHAN_INFO_OFFSET))
1084fea251b6SCosmin Tanislav 
1085fea251b6SCosmin Tanislav #define AD74413R_ADC_CURRENT_CHANNEL					\
1086fea251b6SCosmin Tanislav 	AD74413R_ADC_CHANNEL(IIO_CURRENT,  BIT(IIO_CHAN_INFO_SCALE)	\
1087fea251b6SCosmin Tanislav 			     | BIT(IIO_CHAN_INFO_OFFSET))
1088fea251b6SCosmin Tanislav 
1089fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_voltage_output_channels[] = {
1090fea251b6SCosmin Tanislav 	AD74413R_DAC_CHANNEL(IIO_VOLTAGE, BIT(IIO_CHAN_INFO_SCALE)),
1091fea251b6SCosmin Tanislav 	AD74413R_ADC_CURRENT_CHANNEL,
1092fea251b6SCosmin Tanislav };
1093fea251b6SCosmin Tanislav 
1094fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_current_output_channels[] = {
1095fea251b6SCosmin Tanislav 	AD74413R_DAC_CHANNEL(IIO_CURRENT, BIT(IIO_CHAN_INFO_SCALE)),
1096fea251b6SCosmin Tanislav 	AD74413R_ADC_VOLTAGE_CHANNEL,
1097fea251b6SCosmin Tanislav };
1098fea251b6SCosmin Tanislav 
1099fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_voltage_input_channels[] = {
1100fea251b6SCosmin Tanislav 	AD74413R_ADC_VOLTAGE_CHANNEL,
1101fea251b6SCosmin Tanislav };
1102fea251b6SCosmin Tanislav 
1103fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_current_input_channels[] = {
1104fea251b6SCosmin Tanislav 	AD74413R_ADC_CURRENT_CHANNEL,
1105fea251b6SCosmin Tanislav };
1106fea251b6SCosmin Tanislav 
1107fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_resistance_input_channels[] = {
1108fea251b6SCosmin Tanislav 	AD74413R_ADC_CHANNEL(IIO_RESISTANCE, BIT(IIO_CHAN_INFO_PROCESSED)),
1109fea251b6SCosmin Tanislav };
1110fea251b6SCosmin Tanislav 
1111fea251b6SCosmin Tanislav static struct iio_chan_spec ad74413r_digital_input_channels[] = {
1112fea251b6SCosmin Tanislav 	AD74413R_ADC_VOLTAGE_CHANNEL,
1113fea251b6SCosmin Tanislav };
1114fea251b6SCosmin Tanislav 
1115fea251b6SCosmin Tanislav #define _AD74413R_CHANNELS(_channels)			\
1116fea251b6SCosmin Tanislav 	{						\
1117fea251b6SCosmin Tanislav 		.channels = _channels,			\
1118fea251b6SCosmin Tanislav 		.num_channels = ARRAY_SIZE(_channels),	\
1119fea251b6SCosmin Tanislav 	}
1120fea251b6SCosmin Tanislav 
1121fea251b6SCosmin Tanislav #define AD74413R_CHANNELS(name) \
1122fea251b6SCosmin Tanislav 	_AD74413R_CHANNELS(ad74413r_ ## name ## _channels)
1123fea251b6SCosmin Tanislav 
1124fea251b6SCosmin Tanislav static const struct ad74413r_channels ad74413r_channels_map[] = {
1125fea251b6SCosmin Tanislav 	[CH_FUNC_HIGH_IMPEDANCE] = AD74413R_CHANNELS(voltage_input),
1126fea251b6SCosmin Tanislav 	[CH_FUNC_VOLTAGE_OUTPUT] = AD74413R_CHANNELS(voltage_output),
1127fea251b6SCosmin Tanislav 	[CH_FUNC_CURRENT_OUTPUT] = AD74413R_CHANNELS(current_output),
1128fea251b6SCosmin Tanislav 	[CH_FUNC_VOLTAGE_INPUT] = AD74413R_CHANNELS(voltage_input),
1129fea251b6SCosmin Tanislav 	[CH_FUNC_CURRENT_INPUT_EXT_POWER] = AD74413R_CHANNELS(current_input),
1130fea251b6SCosmin Tanislav 	[CH_FUNC_CURRENT_INPUT_LOOP_POWER] = AD74413R_CHANNELS(current_input),
1131fea251b6SCosmin Tanislav 	[CH_FUNC_RESISTANCE_INPUT] = AD74413R_CHANNELS(resistance_input),
1132fea251b6SCosmin Tanislav 	[CH_FUNC_DIGITAL_INPUT_LOGIC] = AD74413R_CHANNELS(digital_input),
1133fea251b6SCosmin Tanislav 	[CH_FUNC_DIGITAL_INPUT_LOOP_POWER] = AD74413R_CHANNELS(digital_input),
1134fea251b6SCosmin Tanislav 	[CH_FUNC_CURRENT_INPUT_EXT_POWER_HART] = AD74413R_CHANNELS(current_input),
1135fea251b6SCosmin Tanislav 	[CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART] = AD74413R_CHANNELS(current_input),
1136fea251b6SCosmin Tanislav };
1137fea251b6SCosmin Tanislav 
1138fea251b6SCosmin Tanislav static int ad74413r_parse_channel_config(struct iio_dev *indio_dev,
1139fea251b6SCosmin Tanislav 					 struct fwnode_handle *channel_node)
1140fea251b6SCosmin Tanislav {
1141fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
1142fea251b6SCosmin Tanislav 	struct ad74413r_channel_config *config;
1143fea251b6SCosmin Tanislav 	u32 index;
1144fea251b6SCosmin Tanislav 	int ret;
1145fea251b6SCosmin Tanislav 
1146fea251b6SCosmin Tanislav 	ret = fwnode_property_read_u32(channel_node, "reg", &index);
1147fea251b6SCosmin Tanislav 	if (ret) {
1148fea251b6SCosmin Tanislav 		dev_err(st->dev, "Failed to read channel reg: %d\n", ret);
1149fea251b6SCosmin Tanislav 		return ret;
1150fea251b6SCosmin Tanislav 	}
1151fea251b6SCosmin Tanislav 
11525d97d9e9SDan Carpenter 	if (index >= AD74413R_CHANNEL_MAX) {
1153fea251b6SCosmin Tanislav 		dev_err(st->dev, "Channel index %u is too large\n", index);
1154fea251b6SCosmin Tanislav 		return -EINVAL;
1155fea251b6SCosmin Tanislav 	}
1156fea251b6SCosmin Tanislav 
1157fea251b6SCosmin Tanislav 	config = &st->channel_configs[index];
1158fea251b6SCosmin Tanislav 	if (config->initialized) {
1159fea251b6SCosmin Tanislav 		dev_err(st->dev, "Channel %u already initialized\n", index);
1160fea251b6SCosmin Tanislav 		return -EINVAL;
1161fea251b6SCosmin Tanislav 	}
1162fea251b6SCosmin Tanislav 
1163fea251b6SCosmin Tanislav 	config->func = CH_FUNC_HIGH_IMPEDANCE;
1164fea251b6SCosmin Tanislav 	fwnode_property_read_u32(channel_node, "adi,ch-func", &config->func);
1165fea251b6SCosmin Tanislav 
1166fea251b6SCosmin Tanislav 	if (config->func < CH_FUNC_MIN || config->func > CH_FUNC_MAX) {
1167fea251b6SCosmin Tanislav 		dev_err(st->dev, "Invalid channel function %u\n", config->func);
1168fea251b6SCosmin Tanislav 		return -EINVAL;
1169fea251b6SCosmin Tanislav 	}
1170fea251b6SCosmin Tanislav 
1171fea251b6SCosmin Tanislav 	if (!st->chip_info->hart_support &&
1172fea251b6SCosmin Tanislav 	    (config->func == CH_FUNC_CURRENT_INPUT_EXT_POWER_HART ||
1173fea251b6SCosmin Tanislav 	     config->func == CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART)) {
1174fea251b6SCosmin Tanislav 		dev_err(st->dev, "Unsupported HART function %u\n", config->func);
1175fea251b6SCosmin Tanislav 		return -EINVAL;
1176fea251b6SCosmin Tanislav 	}
1177fea251b6SCosmin Tanislav 
1178fea251b6SCosmin Tanislav 	if (config->func == CH_FUNC_DIGITAL_INPUT_LOGIC ||
1179fea251b6SCosmin Tanislav 	    config->func == CH_FUNC_DIGITAL_INPUT_LOOP_POWER)
1180fea251b6SCosmin Tanislav 		st->num_comparator_gpios++;
1181fea251b6SCosmin Tanislav 
1182fea251b6SCosmin Tanislav 	config->gpo_comparator = fwnode_property_read_bool(channel_node,
1183fea251b6SCosmin Tanislav 		"adi,gpo-comparator");
1184fea251b6SCosmin Tanislav 
1185fea251b6SCosmin Tanislav 	if (!config->gpo_comparator)
1186fea251b6SCosmin Tanislav 		st->num_gpo_gpios++;
1187fea251b6SCosmin Tanislav 
1188fea251b6SCosmin Tanislav 	indio_dev->num_channels += ad74413r_channels_map[config->func].num_channels;
1189fea251b6SCosmin Tanislav 
1190fea251b6SCosmin Tanislav 	config->initialized = true;
1191fea251b6SCosmin Tanislav 
1192fea251b6SCosmin Tanislav 	return 0;
1193fea251b6SCosmin Tanislav }
1194fea251b6SCosmin Tanislav 
1195fea251b6SCosmin Tanislav static int ad74413r_parse_channel_configs(struct iio_dev *indio_dev)
1196fea251b6SCosmin Tanislav {
1197fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
1198fea251b6SCosmin Tanislav 	struct fwnode_handle *channel_node = NULL;
1199fea251b6SCosmin Tanislav 	int ret;
1200fea251b6SCosmin Tanislav 
1201fea251b6SCosmin Tanislav 	fwnode_for_each_available_child_node(dev_fwnode(st->dev), channel_node) {
1202fea251b6SCosmin Tanislav 		ret = ad74413r_parse_channel_config(indio_dev, channel_node);
1203fea251b6SCosmin Tanislav 		if (ret)
1204fea251b6SCosmin Tanislav 			goto put_channel_node;
1205fea251b6SCosmin Tanislav 	}
1206fea251b6SCosmin Tanislav 
1207fea251b6SCosmin Tanislav 	return 0;
1208fea251b6SCosmin Tanislav 
1209fea251b6SCosmin Tanislav put_channel_node:
1210fea251b6SCosmin Tanislav 	fwnode_handle_put(channel_node);
1211fea251b6SCosmin Tanislav 
1212fea251b6SCosmin Tanislav 	return ret;
1213fea251b6SCosmin Tanislav }
1214fea251b6SCosmin Tanislav 
1215fea251b6SCosmin Tanislav static int ad74413r_setup_channels(struct iio_dev *indio_dev)
1216fea251b6SCosmin Tanislav {
1217fea251b6SCosmin Tanislav 	struct ad74413r_state *st = iio_priv(indio_dev);
1218fea251b6SCosmin Tanislav 	struct ad74413r_channel_config *config;
1219fea251b6SCosmin Tanislav 	struct iio_chan_spec *channels, *chans;
1220fea251b6SCosmin Tanislav 	unsigned int i, num_chans, chan_i;
1221fea251b6SCosmin Tanislav 	int ret;
1222fea251b6SCosmin Tanislav 
1223fea251b6SCosmin Tanislav 	channels = devm_kcalloc(st->dev, sizeof(*channels),
1224fea251b6SCosmin Tanislav 				indio_dev->num_channels, GFP_KERNEL);
1225fea251b6SCosmin Tanislav 	if (!channels)
1226fea251b6SCosmin Tanislav 		return -ENOMEM;
1227fea251b6SCosmin Tanislav 
1228fea251b6SCosmin Tanislav 	indio_dev->channels = channels;
1229fea251b6SCosmin Tanislav 
1230fea251b6SCosmin Tanislav 	for (i = 0; i < AD74413R_CHANNEL_MAX; i++) {
1231fea251b6SCosmin Tanislav 		config = &st->channel_configs[i];
1232fea251b6SCosmin Tanislav 		chans = ad74413r_channels_map[config->func].channels;
1233fea251b6SCosmin Tanislav 		num_chans = ad74413r_channels_map[config->func].num_channels;
1234fea251b6SCosmin Tanislav 
1235fea251b6SCosmin Tanislav 		memcpy(channels, chans, num_chans * sizeof(*chans));
1236fea251b6SCosmin Tanislav 
1237fea251b6SCosmin Tanislav 		for (chan_i = 0; chan_i < num_chans; chan_i++) {
1238fea251b6SCosmin Tanislav 			struct iio_chan_spec *chan = &channels[chan_i];
1239fea251b6SCosmin Tanislav 
1240fea251b6SCosmin Tanislav 			chan->channel = i;
1241fea251b6SCosmin Tanislav 			if (chan->output)
1242fea251b6SCosmin Tanislav 				chan->scan_index = -1;
1243fea251b6SCosmin Tanislav 			else
1244fea251b6SCosmin Tanislav 				chan->scan_index = i;
1245fea251b6SCosmin Tanislav 		}
1246fea251b6SCosmin Tanislav 
1247fea251b6SCosmin Tanislav 		ret = ad74413r_set_channel_function(st, i, config->func);
1248fea251b6SCosmin Tanislav 		if (ret)
1249fea251b6SCosmin Tanislav 			return ret;
1250fea251b6SCosmin Tanislav 
1251fea251b6SCosmin Tanislav 		channels += num_chans;
1252fea251b6SCosmin Tanislav 	}
1253fea251b6SCosmin Tanislav 
1254fea251b6SCosmin Tanislav 	return 0;
1255fea251b6SCosmin Tanislav }
1256fea251b6SCosmin Tanislav 
1257fea251b6SCosmin Tanislav static int ad74413r_setup_gpios(struct ad74413r_state *st)
1258fea251b6SCosmin Tanislav {
1259fea251b6SCosmin Tanislav 	struct ad74413r_channel_config *config;
1260fea251b6SCosmin Tanislav 	unsigned int comp_gpio_i = 0;
1261fea251b6SCosmin Tanislav 	unsigned int gpo_gpio_i = 0;
1262fea251b6SCosmin Tanislav 	unsigned int i;
1263fea251b6SCosmin Tanislav 	u8 gpo_config;
1264fea251b6SCosmin Tanislav 	int ret;
1265fea251b6SCosmin Tanislav 
1266fea251b6SCosmin Tanislav 	for (i = 0; i < AD74413R_CHANNEL_MAX; i++) {
1267fea251b6SCosmin Tanislav 		config = &st->channel_configs[i];
1268fea251b6SCosmin Tanislav 
1269fea251b6SCosmin Tanislav 		if (config->gpo_comparator) {
1270fea251b6SCosmin Tanislav 			gpo_config = AD74413R_GPO_CONFIG_COMPARATOR;
1271fea251b6SCosmin Tanislav 		} else {
1272fea251b6SCosmin Tanislav 			gpo_config = AD74413R_GPO_CONFIG_LOGIC;
1273fea251b6SCosmin Tanislav 			st->gpo_gpio_offsets[gpo_gpio_i++] = i;
1274fea251b6SCosmin Tanislav 		}
1275fea251b6SCosmin Tanislav 
1276fea251b6SCosmin Tanislav 		if (config->func == CH_FUNC_DIGITAL_INPUT_LOGIC ||
1277fea251b6SCosmin Tanislav 		    config->func == CH_FUNC_DIGITAL_INPUT_LOOP_POWER)
1278fea251b6SCosmin Tanislav 			st->comp_gpio_offsets[comp_gpio_i++] = i;
1279fea251b6SCosmin Tanislav 
1280fea251b6SCosmin Tanislav 		ret = ad74413r_set_gpo_config(st, i, gpo_config);
1281fea251b6SCosmin Tanislav 		if (ret)
1282fea251b6SCosmin Tanislav 			return ret;
1283fea251b6SCosmin Tanislav 	}
1284fea251b6SCosmin Tanislav 
1285fea251b6SCosmin Tanislav 	return 0;
1286fea251b6SCosmin Tanislav }
1287fea251b6SCosmin Tanislav 
1288fea251b6SCosmin Tanislav static void ad74413r_regulator_disable(void *regulator)
1289fea251b6SCosmin Tanislav {
1290fea251b6SCosmin Tanislav 	regulator_disable(regulator);
1291fea251b6SCosmin Tanislav }
1292fea251b6SCosmin Tanislav 
1293fea251b6SCosmin Tanislav static int ad74413r_probe(struct spi_device *spi)
1294fea251b6SCosmin Tanislav {
1295fea251b6SCosmin Tanislav 	struct ad74413r_state *st;
1296fea251b6SCosmin Tanislav 	struct iio_dev *indio_dev;
1297fea251b6SCosmin Tanislav 	int ret;
1298fea251b6SCosmin Tanislav 
1299fea251b6SCosmin Tanislav 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
1300fea251b6SCosmin Tanislav 	if (!indio_dev)
1301fea251b6SCosmin Tanislav 		return -ENOMEM;
1302fea251b6SCosmin Tanislav 
1303fea251b6SCosmin Tanislav 	st = iio_priv(indio_dev);
1304fea251b6SCosmin Tanislav 
1305fea251b6SCosmin Tanislav 	st->spi = spi;
1306fea251b6SCosmin Tanislav 	st->dev = &spi->dev;
1307fea251b6SCosmin Tanislav 	st->chip_info = device_get_match_data(&spi->dev);
1308fea251b6SCosmin Tanislav 	mutex_init(&st->lock);
1309fea251b6SCosmin Tanislav 	init_completion(&st->adc_data_completion);
1310fea251b6SCosmin Tanislav 
1311fea251b6SCosmin Tanislav 	st->regmap = devm_regmap_init(st->dev, NULL, st,
1312fea251b6SCosmin Tanislav 				      &ad74413r_regmap_config);
1313fea251b6SCosmin Tanislav 	if (IS_ERR(st->regmap))
1314fea251b6SCosmin Tanislav 		return PTR_ERR(st->regmap);
1315fea251b6SCosmin Tanislav 
1316fea251b6SCosmin Tanislav 	st->refin_reg = devm_regulator_get(st->dev, "refin");
1317fea251b6SCosmin Tanislav 	if (IS_ERR(st->refin_reg))
1318fea251b6SCosmin Tanislav 		return dev_err_probe(st->dev, PTR_ERR(st->refin_reg),
1319fea251b6SCosmin Tanislav 				     "Failed to get refin regulator\n");
1320fea251b6SCosmin Tanislav 
1321fea251b6SCosmin Tanislav 	ret = regulator_enable(st->refin_reg);
1322fea251b6SCosmin Tanislav 	if (ret)
1323fea251b6SCosmin Tanislav 		return ret;
1324fea251b6SCosmin Tanislav 
1325fea251b6SCosmin Tanislav 	ret = devm_add_action_or_reset(st->dev, ad74413r_regulator_disable,
1326fea251b6SCosmin Tanislav 				       st->refin_reg);
1327fea251b6SCosmin Tanislav 	if (ret)
1328fea251b6SCosmin Tanislav 		return ret;
1329fea251b6SCosmin Tanislav 
1330fea251b6SCosmin Tanislav 	st->sense_resistor_ohms = 100000000;
1331fea251b6SCosmin Tanislav 	device_property_read_u32(st->dev, "shunt-resistor-micro-ohms",
1332fea251b6SCosmin Tanislav 				 &st->sense_resistor_ohms);
1333fea251b6SCosmin Tanislav 	st->sense_resistor_ohms /= 1000000;
1334fea251b6SCosmin Tanislav 
1335fea251b6SCosmin Tanislav 	st->trig = devm_iio_trigger_alloc(st->dev, "%s-dev%d",
1336fea251b6SCosmin Tanislav 					  st->chip_info->name, iio_device_id(indio_dev));
1337fea251b6SCosmin Tanislav 	if (!st->trig)
1338fea251b6SCosmin Tanislav 		return -ENOMEM;
1339fea251b6SCosmin Tanislav 
1340fea251b6SCosmin Tanislav 	st->trig->ops = &ad74413r_trigger_ops;
1341fea251b6SCosmin Tanislav 	iio_trigger_set_drvdata(st->trig, st);
1342fea251b6SCosmin Tanislav 
1343fea251b6SCosmin Tanislav 	ret = devm_iio_trigger_register(st->dev, st->trig);
1344fea251b6SCosmin Tanislav 	if (ret)
1345fea251b6SCosmin Tanislav 		return ret;
1346fea251b6SCosmin Tanislav 
1347fea251b6SCosmin Tanislav 	indio_dev->name = st->chip_info->name;
1348fea251b6SCosmin Tanislav 	indio_dev->modes = INDIO_DIRECT_MODE;
1349fea251b6SCosmin Tanislav 	indio_dev->info = &ad74413r_info;
1350fea251b6SCosmin Tanislav 	indio_dev->trig = iio_trigger_get(st->trig);
1351fea251b6SCosmin Tanislav 
1352fea251b6SCosmin Tanislav 	ret = ad74413r_reset(st);
1353fea251b6SCosmin Tanislav 	if (ret)
1354fea251b6SCosmin Tanislav 		return ret;
1355fea251b6SCosmin Tanislav 
1356fea251b6SCosmin Tanislav 	ret = ad74413r_parse_channel_configs(indio_dev);
1357fea251b6SCosmin Tanislav 	if (ret)
1358fea251b6SCosmin Tanislav 		return ret;
1359fea251b6SCosmin Tanislav 
1360fea251b6SCosmin Tanislav 	ret = ad74413r_setup_channels(indio_dev);
1361fea251b6SCosmin Tanislav 	if (ret)
1362fea251b6SCosmin Tanislav 		return ret;
1363fea251b6SCosmin Tanislav 
1364fea251b6SCosmin Tanislav 	ret = ad74413r_setup_gpios(st);
1365fea251b6SCosmin Tanislav 	if (ret)
1366fea251b6SCosmin Tanislav 		return ret;
1367fea251b6SCosmin Tanislav 
1368fea251b6SCosmin Tanislav 	if (st->num_gpo_gpios) {
1369fea251b6SCosmin Tanislav 		st->gpo_gpiochip.owner = THIS_MODULE;
1370fea251b6SCosmin Tanislav 		st->gpo_gpiochip.label = st->chip_info->name;
1371fea251b6SCosmin Tanislav 		st->gpo_gpiochip.base = -1;
1372fea251b6SCosmin Tanislav 		st->gpo_gpiochip.ngpio = st->num_gpo_gpios;
1373fea251b6SCosmin Tanislav 		st->gpo_gpiochip.parent = st->dev;
1374fea251b6SCosmin Tanislav 		st->gpo_gpiochip.can_sleep = true;
1375fea251b6SCosmin Tanislav 		st->gpo_gpiochip.set = ad74413r_gpio_set;
1376fea251b6SCosmin Tanislav 		st->gpo_gpiochip.set_multiple = ad74413r_gpio_set_multiple;
1377fea251b6SCosmin Tanislav 		st->gpo_gpiochip.set_config = ad74413r_gpio_set_gpo_config;
1378fea251b6SCosmin Tanislav 		st->gpo_gpiochip.get_direction =
1379fea251b6SCosmin Tanislav 			ad74413r_gpio_get_gpo_direction;
1380fea251b6SCosmin Tanislav 
1381fea251b6SCosmin Tanislav 		ret = devm_gpiochip_add_data(st->dev, &st->gpo_gpiochip, st);
1382fea251b6SCosmin Tanislav 		if (ret)
1383fea251b6SCosmin Tanislav 			return ret;
1384fea251b6SCosmin Tanislav 	}
1385fea251b6SCosmin Tanislav 
1386fea251b6SCosmin Tanislav 	if (st->num_comparator_gpios) {
1387fea251b6SCosmin Tanislav 		st->comp_gpiochip.owner = THIS_MODULE;
1388fea251b6SCosmin Tanislav 		st->comp_gpiochip.label = st->chip_info->name;
1389fea251b6SCosmin Tanislav 		st->comp_gpiochip.base = -1;
1390fea251b6SCosmin Tanislav 		st->comp_gpiochip.ngpio = st->num_comparator_gpios;
1391fea251b6SCosmin Tanislav 		st->comp_gpiochip.parent = st->dev;
1392fea251b6SCosmin Tanislav 		st->comp_gpiochip.can_sleep = true;
1393fea251b6SCosmin Tanislav 		st->comp_gpiochip.get = ad74413r_gpio_get;
1394fea251b6SCosmin Tanislav 		st->comp_gpiochip.get_multiple = ad74413r_gpio_get_multiple;
1395fea251b6SCosmin Tanislav 		st->comp_gpiochip.set_config = ad74413r_gpio_set_comp_config;
1396fea251b6SCosmin Tanislav 		st->comp_gpiochip.get_direction =
1397fea251b6SCosmin Tanislav 			ad74413r_gpio_get_comp_direction;
1398fea251b6SCosmin Tanislav 
1399fea251b6SCosmin Tanislav 		ret = devm_gpiochip_add_data(st->dev, &st->comp_gpiochip, st);
1400fea251b6SCosmin Tanislav 		if (ret)
1401fea251b6SCosmin Tanislav 			return ret;
1402fea251b6SCosmin Tanislav 	}
1403fea251b6SCosmin Tanislav 
1404fea251b6SCosmin Tanislav 	ret = ad74413r_set_adc_conv_seq(st, AD74413R_CONV_SEQ_OFF);
1405fea251b6SCosmin Tanislav 	if (ret)
1406fea251b6SCosmin Tanislav 		return ret;
1407fea251b6SCosmin Tanislav 
1408fea251b6SCosmin Tanislav 	ret = devm_request_irq(st->dev, spi->irq, ad74413r_adc_data_interrupt,
1409fea251b6SCosmin Tanislav 			       0, st->chip_info->name, indio_dev);
1410fea251b6SCosmin Tanislav 	if (ret)
1411fea251b6SCosmin Tanislav 		return dev_err_probe(st->dev, ret, "Failed to request irq\n");
1412fea251b6SCosmin Tanislav 
1413fea251b6SCosmin Tanislav 	ret = devm_iio_triggered_buffer_setup(st->dev, indio_dev,
1414fea251b6SCosmin Tanislav 					      &iio_pollfunc_store_time,
1415fea251b6SCosmin Tanislav 					      &ad74413r_trigger_handler,
1416fea251b6SCosmin Tanislav 					      &ad74413r_buffer_ops);
1417fea251b6SCosmin Tanislav 	if (ret)
1418fea251b6SCosmin Tanislav 		return ret;
1419fea251b6SCosmin Tanislav 
1420fea251b6SCosmin Tanislav 	return devm_iio_device_register(st->dev, indio_dev);
1421fea251b6SCosmin Tanislav }
1422fea251b6SCosmin Tanislav 
1423fea251b6SCosmin Tanislav static int ad74413r_unregister_driver(struct spi_driver *spi)
1424fea251b6SCosmin Tanislav {
1425fea251b6SCosmin Tanislav 	spi_unregister_driver(spi);
1426fea251b6SCosmin Tanislav 
1427fea251b6SCosmin Tanislav 	return 0;
1428fea251b6SCosmin Tanislav }
1429fea251b6SCosmin Tanislav 
1430fea251b6SCosmin Tanislav static int __init ad74413r_register_driver(struct spi_driver *spi)
1431fea251b6SCosmin Tanislav {
1432fea251b6SCosmin Tanislav 	crc8_populate_msb(ad74413r_crc8_table, AD74413R_CRC_POLYNOMIAL);
1433fea251b6SCosmin Tanislav 
1434fea251b6SCosmin Tanislav 	return spi_register_driver(spi);
1435fea251b6SCosmin Tanislav }
1436fea251b6SCosmin Tanislav 
1437fea251b6SCosmin Tanislav static const struct ad74413r_chip_info ad74412r_chip_info_data = {
1438fea251b6SCosmin Tanislav 	.hart_support = false,
1439fea251b6SCosmin Tanislav 	.name = "ad74412r",
1440fea251b6SCosmin Tanislav };
1441fea251b6SCosmin Tanislav 
1442fea251b6SCosmin Tanislav static const struct ad74413r_chip_info ad74413r_chip_info_data = {
1443fea251b6SCosmin Tanislav 	.hart_support = true,
1444fea251b6SCosmin Tanislav 	.name = "ad74413r",
1445fea251b6SCosmin Tanislav };
1446fea251b6SCosmin Tanislav 
1447fea251b6SCosmin Tanislav static const struct of_device_id ad74413r_dt_id[] = {
1448fea251b6SCosmin Tanislav 	{
1449fea251b6SCosmin Tanislav 		.compatible = "adi,ad74412r",
1450fea251b6SCosmin Tanislav 		.data = &ad74412r_chip_info_data,
1451fea251b6SCosmin Tanislav 	},
1452fea251b6SCosmin Tanislav 	{
1453fea251b6SCosmin Tanislav 		.compatible = "adi,ad74413r",
1454fea251b6SCosmin Tanislav 		.data = &ad74413r_chip_info_data,
1455fea251b6SCosmin Tanislav 	},
1456fea251b6SCosmin Tanislav 	{},
1457fea251b6SCosmin Tanislav };
1458fea251b6SCosmin Tanislav MODULE_DEVICE_TABLE(of, ad74413r_dt_id);
1459fea251b6SCosmin Tanislav 
1460fea251b6SCosmin Tanislav static struct spi_driver ad74413r_driver = {
1461fea251b6SCosmin Tanislav 	.driver = {
1462fea251b6SCosmin Tanislav 		   .name = "ad74413r",
1463fea251b6SCosmin Tanislav 		   .of_match_table = ad74413r_dt_id,
1464fea251b6SCosmin Tanislav 	},
1465fea251b6SCosmin Tanislav 	.probe = ad74413r_probe,
1466fea251b6SCosmin Tanislav };
1467fea251b6SCosmin Tanislav 
1468fea251b6SCosmin Tanislav module_driver(ad74413r_driver,
1469fea251b6SCosmin Tanislav 	      ad74413r_register_driver,
1470fea251b6SCosmin Tanislav 	      ad74413r_unregister_driver);
1471fea251b6SCosmin Tanislav 
1472fea251b6SCosmin Tanislav MODULE_AUTHOR("Cosmin Tanislav <cosmin.tanislav@analog.com>");
1473fea251b6SCosmin Tanislav MODULE_DESCRIPTION("Analog Devices AD74413R ADDAC");
1474fea251b6SCosmin Tanislav MODULE_LICENSE("GPL v2");
1475