xref: /openbmc/linux/drivers/iio/adc/ad7793.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1fda8d26eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2f87f1a23SLars-Peter Clausen /*
3f87f1a23SLars-Peter Clausen  * AD7785/AD7792/AD7793/AD7794/AD7795 SPI ADC driver
4f87f1a23SLars-Peter Clausen  *
5f87f1a23SLars-Peter Clausen  * Copyright 2011-2012 Analog Devices Inc.
6f87f1a23SLars-Peter Clausen  */
7f87f1a23SLars-Peter Clausen 
8f87f1a23SLars-Peter Clausen #include <linux/interrupt.h>
9f87f1a23SLars-Peter Clausen #include <linux/device.h>
10f87f1a23SLars-Peter Clausen #include <linux/kernel.h>
11f87f1a23SLars-Peter Clausen #include <linux/slab.h>
12f87f1a23SLars-Peter Clausen #include <linux/sysfs.h>
13f87f1a23SLars-Peter Clausen #include <linux/spi/spi.h>
14f87f1a23SLars-Peter Clausen #include <linux/regulator/consumer.h>
15f87f1a23SLars-Peter Clausen #include <linux/err.h>
16f87f1a23SLars-Peter Clausen #include <linux/sched.h>
17f87f1a23SLars-Peter Clausen #include <linux/delay.h>
18f87f1a23SLars-Peter Clausen #include <linux/module.h>
19f87f1a23SLars-Peter Clausen 
20f87f1a23SLars-Peter Clausen #include <linux/iio/iio.h>
21f87f1a23SLars-Peter Clausen #include <linux/iio/sysfs.h>
22f87f1a23SLars-Peter Clausen #include <linux/iio/buffer.h>
23f87f1a23SLars-Peter Clausen #include <linux/iio/trigger.h>
24f87f1a23SLars-Peter Clausen #include <linux/iio/trigger_consumer.h>
25f87f1a23SLars-Peter Clausen #include <linux/iio/triggered_buffer.h>
26f87f1a23SLars-Peter Clausen #include <linux/iio/adc/ad_sigma_delta.h>
27f87f1a23SLars-Peter Clausen #include <linux/platform_data/ad7793.h>
28f87f1a23SLars-Peter Clausen 
29f87f1a23SLars-Peter Clausen /* Registers */
30f87f1a23SLars-Peter Clausen #define AD7793_REG_COMM		0 /* Communications Register (WO, 8-bit) */
31f87f1a23SLars-Peter Clausen #define AD7793_REG_STAT		0 /* Status Register	     (RO, 8-bit) */
32f87f1a23SLars-Peter Clausen #define AD7793_REG_MODE		1 /* Mode Register	     (RW, 16-bit */
33f87f1a23SLars-Peter Clausen #define AD7793_REG_CONF		2 /* Configuration Register  (RW, 16-bit) */
34f87f1a23SLars-Peter Clausen #define AD7793_REG_DATA		3 /* Data Register	     (RO, 16-/24-bit) */
35f87f1a23SLars-Peter Clausen #define AD7793_REG_ID		4 /* ID Register	     (RO, 8-bit) */
36f87f1a23SLars-Peter Clausen #define AD7793_REG_IO		5 /* IO Register	     (RO, 8-bit) */
37f87f1a23SLars-Peter Clausen #define AD7793_REG_OFFSET	6 /* Offset Register	     (RW, 16-bit
38f87f1a23SLars-Peter Clausen 				   * (AD7792)/24-bit (AD7793)) */
39f87f1a23SLars-Peter Clausen #define AD7793_REG_FULLSALE	7 /* Full-Scale Register
40f87f1a23SLars-Peter Clausen 				   * (RW, 16-bit (AD7792)/24-bit (AD7793)) */
41f87f1a23SLars-Peter Clausen 
42f87f1a23SLars-Peter Clausen /* Communications Register Bit Designations (AD7793_REG_COMM) */
43f87f1a23SLars-Peter Clausen #define AD7793_COMM_WEN		(1 << 7) /* Write Enable */
44f87f1a23SLars-Peter Clausen #define AD7793_COMM_WRITE	(0 << 6) /* Write Operation */
45f87f1a23SLars-Peter Clausen #define AD7793_COMM_READ	(1 << 6) /* Read Operation */
46f87f1a23SLars-Peter Clausen #define AD7793_COMM_ADDR(x)	(((x) & 0x7) << 3) /* Register Address */
47f87f1a23SLars-Peter Clausen #define AD7793_COMM_CREAD	(1 << 2) /* Continuous Read of Data Register */
48f87f1a23SLars-Peter Clausen 
49f87f1a23SLars-Peter Clausen /* Status Register Bit Designations (AD7793_REG_STAT) */
50f87f1a23SLars-Peter Clausen #define AD7793_STAT_RDY		(1 << 7) /* Ready */
51f87f1a23SLars-Peter Clausen #define AD7793_STAT_ERR		(1 << 6) /* Error (Overrange, Underrange) */
52f87f1a23SLars-Peter Clausen #define AD7793_STAT_CH3		(1 << 2) /* Channel 3 */
53f87f1a23SLars-Peter Clausen #define AD7793_STAT_CH2		(1 << 1) /* Channel 2 */
54f87f1a23SLars-Peter Clausen #define AD7793_STAT_CH1		(1 << 0) /* Channel 1 */
55f87f1a23SLars-Peter Clausen 
56f87f1a23SLars-Peter Clausen /* Mode Register Bit Designations (AD7793_REG_MODE) */
57f87f1a23SLars-Peter Clausen #define AD7793_MODE_SEL(x)	(((x) & 0x7) << 13) /* Operation Mode Select */
58f87f1a23SLars-Peter Clausen #define AD7793_MODE_SEL_MASK	(0x7 << 13) /* Operation Mode Select mask */
59f87f1a23SLars-Peter Clausen #define AD7793_MODE_CLKSRC(x)	(((x) & 0x3) << 6) /* ADC Clock Source Select */
60f87f1a23SLars-Peter Clausen #define AD7793_MODE_RATE(x)	((x) & 0xF) /* Filter Update Rate Select */
61f87f1a23SLars-Peter Clausen 
62f87f1a23SLars-Peter Clausen #define AD7793_MODE_CONT		0 /* Continuous Conversion Mode */
63f87f1a23SLars-Peter Clausen #define AD7793_MODE_SINGLE		1 /* Single Conversion Mode */
64f87f1a23SLars-Peter Clausen #define AD7793_MODE_IDLE		2 /* Idle Mode */
65f87f1a23SLars-Peter Clausen #define AD7793_MODE_PWRDN		3 /* Power-Down Mode */
66f87f1a23SLars-Peter Clausen #define AD7793_MODE_CAL_INT_ZERO	4 /* Internal Zero-Scale Calibration */
67f87f1a23SLars-Peter Clausen #define AD7793_MODE_CAL_INT_FULL	5 /* Internal Full-Scale Calibration */
68f87f1a23SLars-Peter Clausen #define AD7793_MODE_CAL_SYS_ZERO	6 /* System Zero-Scale Calibration */
69f87f1a23SLars-Peter Clausen #define AD7793_MODE_CAL_SYS_FULL	7 /* System Full-Scale Calibration */
70f87f1a23SLars-Peter Clausen 
71f87f1a23SLars-Peter Clausen #define AD7793_CLK_INT		0 /* Internal 64 kHz Clock not
72f87f1a23SLars-Peter Clausen 				   * available at the CLK pin */
73f87f1a23SLars-Peter Clausen #define AD7793_CLK_INT_CO	1 /* Internal 64 kHz Clock available
74f87f1a23SLars-Peter Clausen 				   * at the CLK pin */
75f87f1a23SLars-Peter Clausen #define AD7793_CLK_EXT		2 /* External 64 kHz Clock */
76f87f1a23SLars-Peter Clausen #define AD7793_CLK_EXT_DIV2	3 /* External Clock divided by 2 */
77f87f1a23SLars-Peter Clausen 
78f87f1a23SLars-Peter Clausen /* Configuration Register Bit Designations (AD7793_REG_CONF) */
79f87f1a23SLars-Peter Clausen #define AD7793_CONF_VBIAS(x)	(((x) & 0x3) << 14) /* Bias Voltage
80f87f1a23SLars-Peter Clausen 						     * Generator Enable */
81f87f1a23SLars-Peter Clausen #define AD7793_CONF_BO_EN	(1 << 13) /* Burnout Current Enable */
82f87f1a23SLars-Peter Clausen #define AD7793_CONF_UNIPOLAR	(1 << 12) /* Unipolar/Bipolar Enable */
83f87f1a23SLars-Peter Clausen #define AD7793_CONF_BOOST	(1 << 11) /* Boost Enable */
84f87f1a23SLars-Peter Clausen #define AD7793_CONF_GAIN(x)	(((x) & 0x7) << 8) /* Gain Select */
85f87f1a23SLars-Peter Clausen #define AD7793_CONF_REFSEL(x)	((x) << 6) /* INT/EXT Reference Select */
86f87f1a23SLars-Peter Clausen #define AD7793_CONF_BUF		(1 << 4) /* Buffered Mode Enable */
87f87f1a23SLars-Peter Clausen #define AD7793_CONF_CHAN(x)	((x) & 0xf) /* Channel select */
88f87f1a23SLars-Peter Clausen #define AD7793_CONF_CHAN_MASK	0xf /* Channel select mask */
89f87f1a23SLars-Peter Clausen 
90f87f1a23SLars-Peter Clausen #define AD7793_CH_AIN1P_AIN1M	0 /* AIN1(+) - AIN1(-) */
91f87f1a23SLars-Peter Clausen #define AD7793_CH_AIN2P_AIN2M	1 /* AIN2(+) - AIN2(-) */
92f87f1a23SLars-Peter Clausen #define AD7793_CH_AIN3P_AIN3M	2 /* AIN3(+) - AIN3(-) */
93f87f1a23SLars-Peter Clausen #define AD7793_CH_AIN1M_AIN1M	3 /* AIN1(-) - AIN1(-) */
94f87f1a23SLars-Peter Clausen #define AD7793_CH_TEMP		6 /* Temp Sensor */
95f87f1a23SLars-Peter Clausen #define AD7793_CH_AVDD_MONITOR	7 /* AVDD Monitor */
96f87f1a23SLars-Peter Clausen 
97f87f1a23SLars-Peter Clausen #define AD7795_CH_AIN4P_AIN4M	4 /* AIN4(+) - AIN4(-) */
98f87f1a23SLars-Peter Clausen #define AD7795_CH_AIN5P_AIN5M	5 /* AIN5(+) - AIN5(-) */
99f87f1a23SLars-Peter Clausen #define AD7795_CH_AIN6P_AIN6M	6 /* AIN6(+) - AIN6(-) */
100f87f1a23SLars-Peter Clausen #define AD7795_CH_AIN1M_AIN1M	8 /* AIN1(-) - AIN1(-) */
101f87f1a23SLars-Peter Clausen 
102f87f1a23SLars-Peter Clausen /* ID Register Bit Designations (AD7793_REG_ID) */
103785171fdSLars-Peter Clausen #define AD7785_ID		0x3
104f87f1a23SLars-Peter Clausen #define AD7792_ID		0xA
105f87f1a23SLars-Peter Clausen #define AD7793_ID		0xB
106f87f1a23SLars-Peter Clausen #define AD7794_ID		0xF
107f87f1a23SLars-Peter Clausen #define AD7795_ID		0xF
108fd1a8b91SLars-Peter Clausen #define AD7796_ID		0xA
109fd1a8b91SLars-Peter Clausen #define AD7797_ID		0xB
1102edb769dSLars-Peter Clausen #define AD7798_ID		0x8
1112edb769dSLars-Peter Clausen #define AD7799_ID		0x9
112f87f1a23SLars-Peter Clausen #define AD7793_ID_MASK		0xF
113f87f1a23SLars-Peter Clausen 
114f87f1a23SLars-Peter Clausen /* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */
115f87f1a23SLars-Peter Clausen #define AD7793_IO_IEXC1_IOUT1_IEXC2_IOUT2	0 /* IEXC1 connect to IOUT1,
116f87f1a23SLars-Peter Clausen 						   * IEXC2 connect to IOUT2 */
117f87f1a23SLars-Peter Clausen #define AD7793_IO_IEXC1_IOUT2_IEXC2_IOUT1	1 /* IEXC1 connect to IOUT2,
118f87f1a23SLars-Peter Clausen 						   * IEXC2 connect to IOUT1 */
119f87f1a23SLars-Peter Clausen #define AD7793_IO_IEXC1_IEXC2_IOUT1		2 /* Both current sources
120f87f1a23SLars-Peter Clausen 						   * IEXC1,2 connect to IOUT1 */
121f87f1a23SLars-Peter Clausen #define AD7793_IO_IEXC1_IEXC2_IOUT2		3 /* Both current sources
122f87f1a23SLars-Peter Clausen 						   * IEXC1,2 connect to IOUT2 */
123f87f1a23SLars-Peter Clausen 
124f87f1a23SLars-Peter Clausen #define AD7793_IO_IXCEN_10uA	(1 << 0) /* Excitation Current 10uA */
125f87f1a23SLars-Peter Clausen #define AD7793_IO_IXCEN_210uA	(2 << 0) /* Excitation Current 210uA */
126f87f1a23SLars-Peter Clausen #define AD7793_IO_IXCEN_1mA	(3 << 0) /* Excitation Current 1mA */
127f87f1a23SLars-Peter Clausen 
128f87f1a23SLars-Peter Clausen /* NOTE:
129f87f1a23SLars-Peter Clausen  * The AD7792/AD7793 features a dual use data out ready DOUT/RDY output.
130f87f1a23SLars-Peter Clausen  * In order to avoid contentions on the SPI bus, it's therefore necessary
131f87f1a23SLars-Peter Clausen  * to use spi bus locking.
132f87f1a23SLars-Peter Clausen  *
133f87f1a23SLars-Peter Clausen  * The DOUT/RDY output must also be wired to an interrupt capable GPIO.
134f87f1a23SLars-Peter Clausen  */
135f87f1a23SLars-Peter Clausen 
1362edb769dSLars-Peter Clausen #define AD7793_FLAG_HAS_CLKSEL		BIT(0)
1372edb769dSLars-Peter Clausen #define AD7793_FLAG_HAS_REFSEL		BIT(1)
1382edb769dSLars-Peter Clausen #define AD7793_FLAG_HAS_VBIAS		BIT(2)
1392edb769dSLars-Peter Clausen #define AD7793_HAS_EXITATION_CURRENT	BIT(3)
140fd1a8b91SLars-Peter Clausen #define AD7793_FLAG_HAS_GAIN		BIT(4)
141fd1a8b91SLars-Peter Clausen #define AD7793_FLAG_HAS_BUFFER		BIT(5)
1422edb769dSLars-Peter Clausen 
143f87f1a23SLars-Peter Clausen struct ad7793_chip_info {
144f87f1a23SLars-Peter Clausen 	unsigned int id;
145f87f1a23SLars-Peter Clausen 	const struct iio_chan_spec *channels;
146f87f1a23SLars-Peter Clausen 	unsigned int num_channels;
1472edb769dSLars-Peter Clausen 	unsigned int flags;
148fd1a8b91SLars-Peter Clausen 
149fd1a8b91SLars-Peter Clausen 	const struct iio_info *iio_info;
150fd1a8b91SLars-Peter Clausen 	const u16 *sample_freq_avail;
151f87f1a23SLars-Peter Clausen };
152f87f1a23SLars-Peter Clausen 
153f87f1a23SLars-Peter Clausen struct ad7793_state {
154f87f1a23SLars-Peter Clausen 	const struct ad7793_chip_info	*chip_info;
155f87f1a23SLars-Peter Clausen 	struct regulator		*reg;
156f87f1a23SLars-Peter Clausen 	u16				int_vref_mv;
157f87f1a23SLars-Peter Clausen 	u16				mode;
158f87f1a23SLars-Peter Clausen 	u16				conf;
159f87f1a23SLars-Peter Clausen 	u32				scale_avail[8][2];
160f87f1a23SLars-Peter Clausen 
161f87f1a23SLars-Peter Clausen 	struct ad_sigma_delta		sd;
162f87f1a23SLars-Peter Clausen 
163f87f1a23SLars-Peter Clausen };
164f87f1a23SLars-Peter Clausen 
165f87f1a23SLars-Peter Clausen enum ad7793_supported_device_ids {
166f87f1a23SLars-Peter Clausen 	ID_AD7785,
167f87f1a23SLars-Peter Clausen 	ID_AD7792,
168f87f1a23SLars-Peter Clausen 	ID_AD7793,
169f87f1a23SLars-Peter Clausen 	ID_AD7794,
170f87f1a23SLars-Peter Clausen 	ID_AD7795,
171fd1a8b91SLars-Peter Clausen 	ID_AD7796,
172fd1a8b91SLars-Peter Clausen 	ID_AD7797,
1732edb769dSLars-Peter Clausen 	ID_AD7798,
1742edb769dSLars-Peter Clausen 	ID_AD7799,
175f87f1a23SLars-Peter Clausen };
176f87f1a23SLars-Peter Clausen 
ad_sigma_delta_to_ad7793(struct ad_sigma_delta * sd)177f87f1a23SLars-Peter Clausen static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd)
178f87f1a23SLars-Peter Clausen {
179f87f1a23SLars-Peter Clausen 	return container_of(sd, struct ad7793_state, sd);
180f87f1a23SLars-Peter Clausen }
181f87f1a23SLars-Peter Clausen 
ad7793_set_channel(struct ad_sigma_delta * sd,unsigned int channel)182f87f1a23SLars-Peter Clausen static int ad7793_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
183f87f1a23SLars-Peter Clausen {
184f87f1a23SLars-Peter Clausen 	struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd);
185f87f1a23SLars-Peter Clausen 
186f87f1a23SLars-Peter Clausen 	st->conf &= ~AD7793_CONF_CHAN_MASK;
187f87f1a23SLars-Peter Clausen 	st->conf |= AD7793_CONF_CHAN(channel);
188f87f1a23SLars-Peter Clausen 
189f87f1a23SLars-Peter Clausen 	return ad_sd_write_reg(&st->sd, AD7793_REG_CONF, 2, st->conf);
190f87f1a23SLars-Peter Clausen }
191f87f1a23SLars-Peter Clausen 
ad7793_set_mode(struct ad_sigma_delta * sd,enum ad_sigma_delta_mode mode)192f87f1a23SLars-Peter Clausen static int ad7793_set_mode(struct ad_sigma_delta *sd,
193f87f1a23SLars-Peter Clausen 			   enum ad_sigma_delta_mode mode)
194f87f1a23SLars-Peter Clausen {
195f87f1a23SLars-Peter Clausen 	struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd);
196f87f1a23SLars-Peter Clausen 
197f87f1a23SLars-Peter Clausen 	st->mode &= ~AD7793_MODE_SEL_MASK;
198f87f1a23SLars-Peter Clausen 	st->mode |= AD7793_MODE_SEL(mode);
199f87f1a23SLars-Peter Clausen 
200f87f1a23SLars-Peter Clausen 	return ad_sd_write_reg(&st->sd, AD7793_REG_MODE, 2, st->mode);
201f87f1a23SLars-Peter Clausen }
202f87f1a23SLars-Peter Clausen 
203f87f1a23SLars-Peter Clausen static const struct ad_sigma_delta_info ad7793_sigma_delta_info = {
204f87f1a23SLars-Peter Clausen 	.set_channel = ad7793_set_channel,
205f87f1a23SLars-Peter Clausen 	.set_mode = ad7793_set_mode,
206f87f1a23SLars-Peter Clausen 	.has_registers = true,
207f87f1a23SLars-Peter Clausen 	.addr_shift = 3,
208f87f1a23SLars-Peter Clausen 	.read_mask = BIT(6),
2091a913270SAlexandru Tachici 	.irq_flags = IRQF_TRIGGER_FALLING,
210f87f1a23SLars-Peter Clausen };
211f87f1a23SLars-Peter Clausen 
212f87f1a23SLars-Peter Clausen static const struct ad_sd_calib_data ad7793_calib_arr[6] = {
213f87f1a23SLars-Peter Clausen 	{AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M},
214f87f1a23SLars-Peter Clausen 	{AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M},
215f87f1a23SLars-Peter Clausen 	{AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M},
216f87f1a23SLars-Peter Clausen 	{AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN2P_AIN2M},
217f87f1a23SLars-Peter Clausen 	{AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN3P_AIN3M},
218f87f1a23SLars-Peter Clausen 	{AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN3P_AIN3M}
219f87f1a23SLars-Peter Clausen };
220f87f1a23SLars-Peter Clausen 
ad7793_calibrate_all(struct ad7793_state * st)221f87f1a23SLars-Peter Clausen static int ad7793_calibrate_all(struct ad7793_state *st)
222f87f1a23SLars-Peter Clausen {
223f87f1a23SLars-Peter Clausen 	return ad_sd_calibrate_all(&st->sd, ad7793_calib_arr,
224f87f1a23SLars-Peter Clausen 				   ARRAY_SIZE(ad7793_calib_arr));
225f87f1a23SLars-Peter Clausen }
226f87f1a23SLars-Peter Clausen 
ad7793_check_platform_data(struct ad7793_state * st,const struct ad7793_platform_data * pdata)2272edb769dSLars-Peter Clausen static int ad7793_check_platform_data(struct ad7793_state *st,
2282edb769dSLars-Peter Clausen 	const struct ad7793_platform_data *pdata)
2292edb769dSLars-Peter Clausen {
2302edb769dSLars-Peter Clausen 	if ((pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT1 ||
2312edb769dSLars-Peter Clausen 		pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT2) &&
2322edb769dSLars-Peter Clausen 		((pdata->exitation_current != AD7793_IX_10uA) &&
2332edb769dSLars-Peter Clausen 		(pdata->exitation_current != AD7793_IX_210uA)))
2342edb769dSLars-Peter Clausen 		return -EINVAL;
2352edb769dSLars-Peter Clausen 
2362edb769dSLars-Peter Clausen 	if (!(st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL) &&
2372edb769dSLars-Peter Clausen 		pdata->clock_src != AD7793_CLK_SRC_INT)
2382edb769dSLars-Peter Clausen 		return -EINVAL;
2392edb769dSLars-Peter Clausen 
2402edb769dSLars-Peter Clausen 	if (!(st->chip_info->flags & AD7793_FLAG_HAS_REFSEL) &&
2412edb769dSLars-Peter Clausen 		pdata->refsel != AD7793_REFSEL_REFIN1)
2422edb769dSLars-Peter Clausen 		return -EINVAL;
2432edb769dSLars-Peter Clausen 
2442edb769dSLars-Peter Clausen 	if (!(st->chip_info->flags & AD7793_FLAG_HAS_VBIAS) &&
2452edb769dSLars-Peter Clausen 		pdata->bias_voltage != AD7793_BIAS_VOLTAGE_DISABLED)
2462edb769dSLars-Peter Clausen 		return -EINVAL;
2472edb769dSLars-Peter Clausen 
2482edb769dSLars-Peter Clausen 	if (!(st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) &&
2492edb769dSLars-Peter Clausen 		pdata->exitation_current != AD7793_IX_DISABLED)
2502edb769dSLars-Peter Clausen 		return -EINVAL;
2512edb769dSLars-Peter Clausen 
2522edb769dSLars-Peter Clausen 	return 0;
2532edb769dSLars-Peter Clausen }
2542edb769dSLars-Peter Clausen 
ad7793_setup(struct iio_dev * indio_dev,const struct ad7793_platform_data * pdata,unsigned int vref_mv)255f87f1a23SLars-Peter Clausen static int ad7793_setup(struct iio_dev *indio_dev,
256f87f1a23SLars-Peter Clausen 	const struct ad7793_platform_data *pdata,
257f87f1a23SLars-Peter Clausen 	unsigned int vref_mv)
258f87f1a23SLars-Peter Clausen {
259f87f1a23SLars-Peter Clausen 	struct ad7793_state *st = iio_priv(indio_dev);
2607ee3b7ebSDragos Bogdan 	int i, ret;
261f87f1a23SLars-Peter Clausen 	unsigned long long scale_uv;
262f87f1a23SLars-Peter Clausen 	u32 id;
263f87f1a23SLars-Peter Clausen 
2642edb769dSLars-Peter Clausen 	ret = ad7793_check_platform_data(st, pdata);
2652edb769dSLars-Peter Clausen 	if (ret)
2662edb769dSLars-Peter Clausen 		return ret;
267f87f1a23SLars-Peter Clausen 
268f87f1a23SLars-Peter Clausen 	/* reset the serial interface */
2697ee3b7ebSDragos Bogdan 	ret = ad_sd_reset(&st->sd, 32);
270f87f1a23SLars-Peter Clausen 	if (ret < 0)
271f87f1a23SLars-Peter Clausen 		goto out;
272f87f1a23SLars-Peter Clausen 	usleep_range(500, 2000); /* Wait for at least 500us */
273f87f1a23SLars-Peter Clausen 
274f87f1a23SLars-Peter Clausen 	/* write/read test for device presence */
275f87f1a23SLars-Peter Clausen 	ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id);
276f87f1a23SLars-Peter Clausen 	if (ret)
277f87f1a23SLars-Peter Clausen 		goto out;
278f87f1a23SLars-Peter Clausen 
279f87f1a23SLars-Peter Clausen 	id &= AD7793_ID_MASK;
280f87f1a23SLars-Peter Clausen 
281f87f1a23SLars-Peter Clausen 	if (id != st->chip_info->id) {
2824ed243b1SYueHaibing 		ret = -ENODEV;
283f87f1a23SLars-Peter Clausen 		dev_err(&st->sd.spi->dev, "device ID query failed\n");
284f87f1a23SLars-Peter Clausen 		goto out;
285f87f1a23SLars-Peter Clausen 	}
286f87f1a23SLars-Peter Clausen 
287f87f1a23SLars-Peter Clausen 	st->mode = AD7793_MODE_RATE(1);
2882edb769dSLars-Peter Clausen 	st->conf = 0;
2892edb769dSLars-Peter Clausen 
2902edb769dSLars-Peter Clausen 	if (st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL)
291f87f1a23SLars-Peter Clausen 		st->mode |= AD7793_MODE_CLKSRC(pdata->clock_src);
2922edb769dSLars-Peter Clausen 	if (st->chip_info->flags & AD7793_FLAG_HAS_REFSEL)
2932edb769dSLars-Peter Clausen 		st->conf |= AD7793_CONF_REFSEL(pdata->refsel);
2942edb769dSLars-Peter Clausen 	if (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS)
295f87f1a23SLars-Peter Clausen 		st->conf |= AD7793_CONF_VBIAS(pdata->bias_voltage);
296fd1a8b91SLars-Peter Clausen 	if (pdata->buffered || !(st->chip_info->flags & AD7793_FLAG_HAS_BUFFER))
297f87f1a23SLars-Peter Clausen 		st->conf |= AD7793_CONF_BUF;
2982edb769dSLars-Peter Clausen 	if (pdata->boost_enable &&
2992edb769dSLars-Peter Clausen 		(st->chip_info->flags & AD7793_FLAG_HAS_VBIAS))
300f87f1a23SLars-Peter Clausen 		st->conf |= AD7793_CONF_BOOST;
301f87f1a23SLars-Peter Clausen 	if (pdata->burnout_current)
302f87f1a23SLars-Peter Clausen 		st->conf |= AD7793_CONF_BO_EN;
303f87f1a23SLars-Peter Clausen 	if (pdata->unipolar)
304f87f1a23SLars-Peter Clausen 		st->conf |= AD7793_CONF_UNIPOLAR;
305f87f1a23SLars-Peter Clausen 
306fd1a8b91SLars-Peter Clausen 	if (!(st->chip_info->flags & AD7793_FLAG_HAS_GAIN))
307fd1a8b91SLars-Peter Clausen 		st->conf |= AD7793_CONF_GAIN(7);
308fd1a8b91SLars-Peter Clausen 
309f87f1a23SLars-Peter Clausen 	ret = ad7793_set_mode(&st->sd, AD_SD_MODE_IDLE);
310f87f1a23SLars-Peter Clausen 	if (ret)
311f87f1a23SLars-Peter Clausen 		goto out;
312f87f1a23SLars-Peter Clausen 
313f87f1a23SLars-Peter Clausen 	ret = ad7793_set_channel(&st->sd, 0);
314f87f1a23SLars-Peter Clausen 	if (ret)
315f87f1a23SLars-Peter Clausen 		goto out;
316f87f1a23SLars-Peter Clausen 
3172edb769dSLars-Peter Clausen 	if (st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) {
318f87f1a23SLars-Peter Clausen 		ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, 1,
319f87f1a23SLars-Peter Clausen 				pdata->exitation_current |
320f87f1a23SLars-Peter Clausen 				(pdata->current_source_direction << 2));
321f87f1a23SLars-Peter Clausen 		if (ret)
322f87f1a23SLars-Peter Clausen 			goto out;
3232edb769dSLars-Peter Clausen 	}
324f87f1a23SLars-Peter Clausen 
325f87f1a23SLars-Peter Clausen 	ret = ad7793_calibrate_all(st);
326f87f1a23SLars-Peter Clausen 	if (ret)
327f87f1a23SLars-Peter Clausen 		goto out;
328f87f1a23SLars-Peter Clausen 
329f87f1a23SLars-Peter Clausen 	/* Populate available ADC input ranges */
330f87f1a23SLars-Peter Clausen 	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) {
331f87f1a23SLars-Peter Clausen 		scale_uv = ((u64)vref_mv * 100000000)
332f87f1a23SLars-Peter Clausen 			>> (st->chip_info->channels[0].scan_type.realbits -
333f87f1a23SLars-Peter Clausen 			(!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1));
334f87f1a23SLars-Peter Clausen 		scale_uv >>= i;
335f87f1a23SLars-Peter Clausen 
336f87f1a23SLars-Peter Clausen 		st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10;
337f87f1a23SLars-Peter Clausen 		st->scale_avail[i][0] = scale_uv;
338f87f1a23SLars-Peter Clausen 	}
339f87f1a23SLars-Peter Clausen 
340f87f1a23SLars-Peter Clausen 	return 0;
341f87f1a23SLars-Peter Clausen out:
342f87f1a23SLars-Peter Clausen 	dev_err(&st->sd.spi->dev, "setup failed\n");
343f87f1a23SLars-Peter Clausen 	return ret;
344f87f1a23SLars-Peter Clausen }
345f87f1a23SLars-Peter Clausen 
346fd1a8b91SLars-Peter Clausen static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39,
347fd1a8b91SLars-Peter Clausen 					33, 19, 17, 16, 12, 10, 8, 6, 4};
348fd1a8b91SLars-Peter Clausen 
349fd1a8b91SLars-Peter Clausen static const u16 ad7797_sample_freq_avail[16] = {0, 0, 0, 123, 62, 50, 0,
350fd1a8b91SLars-Peter Clausen 					33, 0, 17, 16, 12, 10, 8, 6, 4};
351f87f1a23SLars-Peter Clausen 
352f87f1a23SLars-Peter Clausen static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
353f87f1a23SLars-Peter Clausen 	"470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
354f87f1a23SLars-Peter Clausen 
355fd1a8b91SLars-Peter Clausen static IIO_CONST_ATTR_NAMED(sampling_frequency_available_ad7797,
356fd1a8b91SLars-Peter Clausen 	sampling_frequency_available, "123 62 50 33 17 16 12 10 8 6 4");
357fd1a8b91SLars-Peter Clausen 
ad7793_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)3581cfe38fcSAlexandru Ardelean static int ad7793_read_avail(struct iio_dev *indio_dev,
3591cfe38fcSAlexandru Ardelean 			     struct iio_chan_spec const *chan,
3601cfe38fcSAlexandru Ardelean 			     const int **vals, int *type, int *length,
3611cfe38fcSAlexandru Ardelean 			     long mask)
362f87f1a23SLars-Peter Clausen {
363f87f1a23SLars-Peter Clausen 	struct ad7793_state *st = iio_priv(indio_dev);
364f87f1a23SLars-Peter Clausen 
3651cfe38fcSAlexandru Ardelean 	switch (mask) {
3661cfe38fcSAlexandru Ardelean 	case IIO_CHAN_INFO_SCALE:
3671cfe38fcSAlexandru Ardelean 		*vals = (int *)st->scale_avail;
3681cfe38fcSAlexandru Ardelean 		*type = IIO_VAL_INT_PLUS_NANO;
3691cfe38fcSAlexandru Ardelean 		/* Values are stored in a 2D matrix  */
3701cfe38fcSAlexandru Ardelean 		*length = ARRAY_SIZE(st->scale_avail) * 2;
371f87f1a23SLars-Peter Clausen 
3721cfe38fcSAlexandru Ardelean 		return IIO_AVAIL_LIST;
3731cfe38fcSAlexandru Ardelean 	default:
3741cfe38fcSAlexandru Ardelean 		return -EINVAL;
375f87f1a23SLars-Peter Clausen 	}
3761cfe38fcSAlexandru Ardelean }
377f87f1a23SLars-Peter Clausen 
378f87f1a23SLars-Peter Clausen static struct attribute *ad7793_attributes[] = {
379f87f1a23SLars-Peter Clausen 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
380f87f1a23SLars-Peter Clausen 	NULL
381f87f1a23SLars-Peter Clausen };
382f87f1a23SLars-Peter Clausen 
383f87f1a23SLars-Peter Clausen static const struct attribute_group ad7793_attribute_group = {
384f87f1a23SLars-Peter Clausen 	.attrs = ad7793_attributes,
385f87f1a23SLars-Peter Clausen };
386f87f1a23SLars-Peter Clausen 
387fd1a8b91SLars-Peter Clausen static struct attribute *ad7797_attributes[] = {
388fd1a8b91SLars-Peter Clausen 	&iio_const_attr_sampling_frequency_available_ad7797.dev_attr.attr,
389fd1a8b91SLars-Peter Clausen 	NULL
390fd1a8b91SLars-Peter Clausen };
391fd1a8b91SLars-Peter Clausen 
392fd1a8b91SLars-Peter Clausen static const struct attribute_group ad7797_attribute_group = {
393fd1a8b91SLars-Peter Clausen 	.attrs = ad7797_attributes,
394fd1a8b91SLars-Peter Clausen };
395fd1a8b91SLars-Peter Clausen 
ad7793_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long m)396f87f1a23SLars-Peter Clausen static int ad7793_read_raw(struct iio_dev *indio_dev,
397f87f1a23SLars-Peter Clausen 			   struct iio_chan_spec const *chan,
398f87f1a23SLars-Peter Clausen 			   int *val,
399f87f1a23SLars-Peter Clausen 			   int *val2,
400f87f1a23SLars-Peter Clausen 			   long m)
401f87f1a23SLars-Peter Clausen {
402f87f1a23SLars-Peter Clausen 	struct ad7793_state *st = iio_priv(indio_dev);
403f87f1a23SLars-Peter Clausen 	int ret;
404f87f1a23SLars-Peter Clausen 	unsigned long long scale_uv;
405f87f1a23SLars-Peter Clausen 	bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR);
406f87f1a23SLars-Peter Clausen 
407f87f1a23SLars-Peter Clausen 	switch (m) {
408f87f1a23SLars-Peter Clausen 	case IIO_CHAN_INFO_RAW:
409f87f1a23SLars-Peter Clausen 		ret = ad_sigma_delta_single_conversion(indio_dev, chan, val);
410f87f1a23SLars-Peter Clausen 		if (ret < 0)
411f87f1a23SLars-Peter Clausen 			return ret;
412f87f1a23SLars-Peter Clausen 
413f87f1a23SLars-Peter Clausen 		return IIO_VAL_INT;
414f87f1a23SLars-Peter Clausen 
415f87f1a23SLars-Peter Clausen 	case IIO_CHAN_INFO_SCALE:
416f87f1a23SLars-Peter Clausen 		switch (chan->type) {
417f87f1a23SLars-Peter Clausen 		case IIO_VOLTAGE:
418f87f1a23SLars-Peter Clausen 			if (chan->differential) {
419f87f1a23SLars-Peter Clausen 				*val = st->
420f87f1a23SLars-Peter Clausen 					scale_avail[(st->conf >> 8) & 0x7][0];
421f87f1a23SLars-Peter Clausen 				*val2 = st->
422f87f1a23SLars-Peter Clausen 					scale_avail[(st->conf >> 8) & 0x7][1];
423f87f1a23SLars-Peter Clausen 				return IIO_VAL_INT_PLUS_NANO;
4247d173f26SNizam Haider 			}
425f87f1a23SLars-Peter Clausen 			/* 1170mV / 2^23 * 6 */
426f87f1a23SLars-Peter Clausen 			scale_uv = (1170ULL * 1000000000ULL * 6ULL);
427f87f1a23SLars-Peter Clausen 			break;
428f87f1a23SLars-Peter Clausen 		case IIO_TEMP:
429f87f1a23SLars-Peter Clausen 				/* 1170mV / 0.81 mV/C / 2^23 */
430f87f1a23SLars-Peter Clausen 				scale_uv = 1444444444444444ULL;
431f87f1a23SLars-Peter Clausen 			break;
432f87f1a23SLars-Peter Clausen 		default:
433f87f1a23SLars-Peter Clausen 			return -EINVAL;
434f87f1a23SLars-Peter Clausen 		}
435f87f1a23SLars-Peter Clausen 
436f87f1a23SLars-Peter Clausen 		scale_uv >>= (chan->scan_type.realbits - (unipolar ? 0 : 1));
437f87f1a23SLars-Peter Clausen 		*val = 0;
438f87f1a23SLars-Peter Clausen 		*val2 = scale_uv;
439f87f1a23SLars-Peter Clausen 		return IIO_VAL_INT_PLUS_NANO;
440f87f1a23SLars-Peter Clausen 	case IIO_CHAN_INFO_OFFSET:
441f87f1a23SLars-Peter Clausen 		if (!unipolar)
442f87f1a23SLars-Peter Clausen 			*val = -(1 << (chan->scan_type.realbits - 1));
443f87f1a23SLars-Peter Clausen 		else
444f87f1a23SLars-Peter Clausen 			*val = 0;
445f87f1a23SLars-Peter Clausen 
446f87f1a23SLars-Peter Clausen 		/* Kelvin to Celsius */
447f87f1a23SLars-Peter Clausen 		if (chan->type == IIO_TEMP) {
448f87f1a23SLars-Peter Clausen 			unsigned long long offset;
449f87f1a23SLars-Peter Clausen 			unsigned int shift;
450f87f1a23SLars-Peter Clausen 
451f87f1a23SLars-Peter Clausen 			shift = chan->scan_type.realbits - (unipolar ? 0 : 1);
452f87f1a23SLars-Peter Clausen 			offset = 273ULL << shift;
453f87f1a23SLars-Peter Clausen 			do_div(offset, 1444);
454f87f1a23SLars-Peter Clausen 			*val -= offset;
455f87f1a23SLars-Peter Clausen 		}
456f87f1a23SLars-Peter Clausen 		return IIO_VAL_INT;
457490fba90SMichael Nosthoff 	case IIO_CHAN_INFO_SAMP_FREQ:
458490fba90SMichael Nosthoff 		*val = st->chip_info
459490fba90SMichael Nosthoff 			       ->sample_freq_avail[AD7793_MODE_RATE(st->mode)];
460490fba90SMichael Nosthoff 		return IIO_VAL_INT;
461f87f1a23SLars-Peter Clausen 	}
462f87f1a23SLars-Peter Clausen 	return -EINVAL;
463f87f1a23SLars-Peter Clausen }
464f87f1a23SLars-Peter Clausen 
ad7793_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)465f87f1a23SLars-Peter Clausen static int ad7793_write_raw(struct iio_dev *indio_dev,
466f87f1a23SLars-Peter Clausen 			       struct iio_chan_spec const *chan,
467f87f1a23SLars-Peter Clausen 			       int val,
468f87f1a23SLars-Peter Clausen 			       int val2,
469f87f1a23SLars-Peter Clausen 			       long mask)
470f87f1a23SLars-Peter Clausen {
471f87f1a23SLars-Peter Clausen 	struct ad7793_state *st = iio_priv(indio_dev);
472f87f1a23SLars-Peter Clausen 	int ret, i;
473f87f1a23SLars-Peter Clausen 	unsigned int tmp;
474f87f1a23SLars-Peter Clausen 
475b4d46409SAlison Schofield 	ret = iio_device_claim_direct_mode(indio_dev);
476b4d46409SAlison Schofield 	if (ret)
477b4d46409SAlison Schofield 		return ret;
478f87f1a23SLars-Peter Clausen 
479f87f1a23SLars-Peter Clausen 	switch (mask) {
480f87f1a23SLars-Peter Clausen 	case IIO_CHAN_INFO_SCALE:
481f87f1a23SLars-Peter Clausen 		ret = -EINVAL;
482f87f1a23SLars-Peter Clausen 		for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
483f87f1a23SLars-Peter Clausen 			if (val2 == st->scale_avail[i][1]) {
484f87f1a23SLars-Peter Clausen 				ret = 0;
485f87f1a23SLars-Peter Clausen 				tmp = st->conf;
486f87f1a23SLars-Peter Clausen 				st->conf &= ~AD7793_CONF_GAIN(-1);
487f87f1a23SLars-Peter Clausen 				st->conf |= AD7793_CONF_GAIN(i);
488f87f1a23SLars-Peter Clausen 
489f87f1a23SLars-Peter Clausen 				if (tmp == st->conf)
490f87f1a23SLars-Peter Clausen 					break;
491f87f1a23SLars-Peter Clausen 
492f87f1a23SLars-Peter Clausen 				ad_sd_write_reg(&st->sd, AD7793_REG_CONF,
493f87f1a23SLars-Peter Clausen 						sizeof(st->conf), st->conf);
494f87f1a23SLars-Peter Clausen 				ad7793_calibrate_all(st);
495f87f1a23SLars-Peter Clausen 				break;
496f87f1a23SLars-Peter Clausen 			}
497f87f1a23SLars-Peter Clausen 		break;
498490fba90SMichael Nosthoff 	case IIO_CHAN_INFO_SAMP_FREQ:
499490fba90SMichael Nosthoff 		if (!val) {
500490fba90SMichael Nosthoff 			ret = -EINVAL;
501490fba90SMichael Nosthoff 			break;
502490fba90SMichael Nosthoff 		}
503490fba90SMichael Nosthoff 
504490fba90SMichael Nosthoff 		for (i = 0; i < 16; i++)
505490fba90SMichael Nosthoff 			if (val == st->chip_info->sample_freq_avail[i])
506490fba90SMichael Nosthoff 				break;
507490fba90SMichael Nosthoff 
508490fba90SMichael Nosthoff 		if (i == 16) {
509490fba90SMichael Nosthoff 			ret = -EINVAL;
510490fba90SMichael Nosthoff 			break;
511490fba90SMichael Nosthoff 		}
512490fba90SMichael Nosthoff 
513490fba90SMichael Nosthoff 		st->mode &= ~AD7793_MODE_RATE(-1);
514490fba90SMichael Nosthoff 		st->mode |= AD7793_MODE_RATE(i);
515490fba90SMichael Nosthoff 		ad_sd_write_reg(&st->sd, AD7793_REG_MODE, sizeof(st->mode),
516490fba90SMichael Nosthoff 				st->mode);
517490fba90SMichael Nosthoff 		break;
518f87f1a23SLars-Peter Clausen 	default:
519f87f1a23SLars-Peter Clausen 		ret = -EINVAL;
520f87f1a23SLars-Peter Clausen 	}
521f87f1a23SLars-Peter Clausen 
522b4d46409SAlison Schofield 	iio_device_release_direct_mode(indio_dev);
523f87f1a23SLars-Peter Clausen 	return ret;
524f87f1a23SLars-Peter Clausen }
525f87f1a23SLars-Peter Clausen 
ad7793_write_raw_get_fmt(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,long mask)526f87f1a23SLars-Peter Clausen static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev,
527f87f1a23SLars-Peter Clausen 			       struct iio_chan_spec const *chan,
528f87f1a23SLars-Peter Clausen 			       long mask)
529f87f1a23SLars-Peter Clausen {
530f87f1a23SLars-Peter Clausen 	return IIO_VAL_INT_PLUS_NANO;
531f87f1a23SLars-Peter Clausen }
532f87f1a23SLars-Peter Clausen 
533f87f1a23SLars-Peter Clausen static const struct iio_info ad7793_info = {
534f87f1a23SLars-Peter Clausen 	.read_raw = &ad7793_read_raw,
535f87f1a23SLars-Peter Clausen 	.write_raw = &ad7793_write_raw,
536f87f1a23SLars-Peter Clausen 	.write_raw_get_fmt = &ad7793_write_raw_get_fmt,
5371cfe38fcSAlexandru Ardelean 	.read_avail = ad7793_read_avail,
538f87f1a23SLars-Peter Clausen 	.attrs = &ad7793_attribute_group,
539f87f1a23SLars-Peter Clausen 	.validate_trigger = ad_sd_validate_trigger,
540f87f1a23SLars-Peter Clausen };
541f87f1a23SLars-Peter Clausen 
542fd1a8b91SLars-Peter Clausen static const struct iio_info ad7797_info = {
543fd1a8b91SLars-Peter Clausen 	.read_raw = &ad7793_read_raw,
544fd1a8b91SLars-Peter Clausen 	.write_raw = &ad7793_write_raw,
545fd1a8b91SLars-Peter Clausen 	.write_raw_get_fmt = &ad7793_write_raw_get_fmt,
54628535877SYueHaibing 	.attrs = &ad7797_attribute_group,
547fd1a8b91SLars-Peter Clausen 	.validate_trigger = ad_sd_validate_trigger,
548fd1a8b91SLars-Peter Clausen };
549fd1a8b91SLars-Peter Clausen 
550aebefb44SAlexandru Ardelean #define __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
5511cfe38fcSAlexandru Ardelean 	_storagebits, _shift, _extend_name, _type, _mask_type_av, _mask_all) \
552aebefb44SAlexandru Ardelean 	{ \
553aebefb44SAlexandru Ardelean 		.type = (_type), \
554aebefb44SAlexandru Ardelean 		.differential = (_channel2 == -1 ? 0 : 1), \
555aebefb44SAlexandru Ardelean 		.indexed = 1, \
556aebefb44SAlexandru Ardelean 		.channel = (_channel1), \
557aebefb44SAlexandru Ardelean 		.channel2 = (_channel2), \
558aebefb44SAlexandru Ardelean 		.address = (_address), \
559aebefb44SAlexandru Ardelean 		.extend_name = (_extend_name), \
560aebefb44SAlexandru Ardelean 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
561aebefb44SAlexandru Ardelean 			BIT(IIO_CHAN_INFO_OFFSET), \
562aebefb44SAlexandru Ardelean 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
5631cfe38fcSAlexandru Ardelean 		.info_mask_shared_by_type_available = (_mask_type_av), \
564aebefb44SAlexandru Ardelean 		.info_mask_shared_by_all = _mask_all, \
565aebefb44SAlexandru Ardelean 		.scan_index = (_si), \
566aebefb44SAlexandru Ardelean 		.scan_type = { \
567aebefb44SAlexandru Ardelean 			.sign = 'u', \
568aebefb44SAlexandru Ardelean 			.realbits = (_bits), \
569aebefb44SAlexandru Ardelean 			.storagebits = (_storagebits), \
570aebefb44SAlexandru Ardelean 			.shift = (_shift), \
571aebefb44SAlexandru Ardelean 			.endianness = IIO_BE, \
572aebefb44SAlexandru Ardelean 		}, \
573aebefb44SAlexandru Ardelean 	}
574aebefb44SAlexandru Ardelean 
575aebefb44SAlexandru Ardelean #define AD7793_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
576aebefb44SAlexandru Ardelean 	_storagebits, _shift) \
577aebefb44SAlexandru Ardelean 	__AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
578aebefb44SAlexandru Ardelean 		_storagebits, _shift, NULL, IIO_VOLTAGE, \
5791cfe38fcSAlexandru Ardelean 		BIT(IIO_CHAN_INFO_SCALE), \
580aebefb44SAlexandru Ardelean 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
581aebefb44SAlexandru Ardelean 
582aebefb44SAlexandru Ardelean #define AD7793_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
583aebefb44SAlexandru Ardelean 	_storagebits, _shift) \
584aebefb44SAlexandru Ardelean 	__AD7793_CHANNEL(_si, _channel, _channel, _address, _bits, \
585aebefb44SAlexandru Ardelean 		_storagebits, _shift, "shorted", IIO_VOLTAGE, \
5861cfe38fcSAlexandru Ardelean 		BIT(IIO_CHAN_INFO_SCALE), \
587aebefb44SAlexandru Ardelean 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
588aebefb44SAlexandru Ardelean 
589aebefb44SAlexandru Ardelean #define AD7793_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \
590aebefb44SAlexandru Ardelean 	__AD7793_CHANNEL(_si, 0, -1, _address, _bits, \
591aebefb44SAlexandru Ardelean 		_storagebits, _shift, NULL, IIO_TEMP, \
5921cfe38fcSAlexandru Ardelean 		0, \
593aebefb44SAlexandru Ardelean 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
594aebefb44SAlexandru Ardelean 
595aebefb44SAlexandru Ardelean #define AD7793_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \
596aebefb44SAlexandru Ardelean 	_shift) \
597aebefb44SAlexandru Ardelean 	__AD7793_CHANNEL(_si, _channel, -1, _address, _bits, \
598aebefb44SAlexandru Ardelean 		_storagebits, _shift, "supply", IIO_VOLTAGE, \
5991cfe38fcSAlexandru Ardelean 		0, \
6001cfe38fcSAlexandru Ardelean 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
6011cfe38fcSAlexandru Ardelean 
6021cfe38fcSAlexandru Ardelean #define AD7797_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
6031cfe38fcSAlexandru Ardelean 	_storagebits, _shift) \
6041cfe38fcSAlexandru Ardelean 	__AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
6051cfe38fcSAlexandru Ardelean 		_storagebits, _shift, NULL, IIO_VOLTAGE, \
6061cfe38fcSAlexandru Ardelean 		0, \
6071cfe38fcSAlexandru Ardelean 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
6081cfe38fcSAlexandru Ardelean 
6091cfe38fcSAlexandru Ardelean #define AD7797_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
6101cfe38fcSAlexandru Ardelean 	_storagebits, _shift) \
6111cfe38fcSAlexandru Ardelean 	__AD7793_CHANNEL(_si, _channel, _channel, _address, _bits, \
6121cfe38fcSAlexandru Ardelean 		_storagebits, _shift, "shorted", IIO_VOLTAGE, \
6131cfe38fcSAlexandru Ardelean 		0, \
614aebefb44SAlexandru Ardelean 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
615aebefb44SAlexandru Ardelean 
616f87f1a23SLars-Peter Clausen #define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
617f87f1a23SLars-Peter Clausen const struct iio_chan_spec _name##_channels[] = { \
618aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \
619aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \
620aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \
621aebefb44SAlexandru Ardelean 	AD7793_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \
622aebefb44SAlexandru Ardelean 	AD7793_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \
623aebefb44SAlexandru Ardelean 	AD7793_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \
624f87f1a23SLars-Peter Clausen 	IIO_CHAN_SOFT_TIMESTAMP(6), \
625f87f1a23SLars-Peter Clausen }
626f87f1a23SLars-Peter Clausen 
627f87f1a23SLars-Peter Clausen #define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \
628f87f1a23SLars-Peter Clausen const struct iio_chan_spec _name##_channels[] = { \
629aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
630aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
631aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
632aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \
633aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \
634aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \
635aebefb44SAlexandru Ardelean 	AD7793_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
636aebefb44SAlexandru Ardelean 	AD7793_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \
637aebefb44SAlexandru Ardelean 	AD7793_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
638f87f1a23SLars-Peter Clausen 	IIO_CHAN_SOFT_TIMESTAMP(9), \
639f87f1a23SLars-Peter Clausen }
640f87f1a23SLars-Peter Clausen 
641fd1a8b91SLars-Peter Clausen #define DECLARE_AD7797_CHANNELS(_name, _b, _sb) \
642fd1a8b91SLars-Peter Clausen const struct iio_chan_spec _name##_channels[] = { \
6431cfe38fcSAlexandru Ardelean 	AD7797_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
6441cfe38fcSAlexandru Ardelean 	AD7797_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
645aebefb44SAlexandru Ardelean 	AD7793_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0), \
646aebefb44SAlexandru Ardelean 	AD7793_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
647fd1a8b91SLars-Peter Clausen 	IIO_CHAN_SOFT_TIMESTAMP(4), \
648fd1a8b91SLars-Peter Clausen }
649fd1a8b91SLars-Peter Clausen 
6502edb769dSLars-Peter Clausen #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
6512edb769dSLars-Peter Clausen const struct iio_chan_spec _name##_channels[] = { \
652aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
653aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
654aebefb44SAlexandru Ardelean 	AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
655aebefb44SAlexandru Ardelean 	AD7793_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
656aebefb44SAlexandru Ardelean 	AD7793_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
6572edb769dSLars-Peter Clausen 	IIO_CHAN_SOFT_TIMESTAMP(5), \
6582edb769dSLars-Peter Clausen }
6592edb769dSLars-Peter Clausen 
660f87f1a23SLars-Peter Clausen static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4);
661f87f1a23SLars-Peter Clausen static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0);
662f87f1a23SLars-Peter Clausen static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0);
663f87f1a23SLars-Peter Clausen static DECLARE_AD7795_CHANNELS(ad7794, 16, 32);
664f87f1a23SLars-Peter Clausen static DECLARE_AD7795_CHANNELS(ad7795, 24, 32);
665fd1a8b91SLars-Peter Clausen static DECLARE_AD7797_CHANNELS(ad7796, 16, 16);
666fd1a8b91SLars-Peter Clausen static DECLARE_AD7797_CHANNELS(ad7797, 24, 32);
6672edb769dSLars-Peter Clausen static DECLARE_AD7799_CHANNELS(ad7798, 16, 16);
6682edb769dSLars-Peter Clausen static DECLARE_AD7799_CHANNELS(ad7799, 24, 32);
669f87f1a23SLars-Peter Clausen 
670f87f1a23SLars-Peter Clausen static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
671f87f1a23SLars-Peter Clausen 	[ID_AD7785] = {
672f87f1a23SLars-Peter Clausen 		.id = AD7785_ID,
673f87f1a23SLars-Peter Clausen 		.channels = ad7785_channels,
674f87f1a23SLars-Peter Clausen 		.num_channels = ARRAY_SIZE(ad7785_channels),
675fd1a8b91SLars-Peter Clausen 		.iio_info = &ad7793_info,
676fd1a8b91SLars-Peter Clausen 		.sample_freq_avail = ad7793_sample_freq_avail,
6772edb769dSLars-Peter Clausen 		.flags = AD7793_FLAG_HAS_CLKSEL |
6782edb769dSLars-Peter Clausen 			AD7793_FLAG_HAS_REFSEL |
6792edb769dSLars-Peter Clausen 			AD7793_FLAG_HAS_VBIAS |
680fd1a8b91SLars-Peter Clausen 			AD7793_HAS_EXITATION_CURRENT |
681fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_GAIN |
682fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_BUFFER,
683f87f1a23SLars-Peter Clausen 	},
684f87f1a23SLars-Peter Clausen 	[ID_AD7792] = {
685f87f1a23SLars-Peter Clausen 		.id = AD7792_ID,
686f87f1a23SLars-Peter Clausen 		.channels = ad7792_channels,
687f87f1a23SLars-Peter Clausen 		.num_channels = ARRAY_SIZE(ad7792_channels),
688fd1a8b91SLars-Peter Clausen 		.iio_info = &ad7793_info,
689fd1a8b91SLars-Peter Clausen 		.sample_freq_avail = ad7793_sample_freq_avail,
6902edb769dSLars-Peter Clausen 		.flags = AD7793_FLAG_HAS_CLKSEL |
6912edb769dSLars-Peter Clausen 			AD7793_FLAG_HAS_REFSEL |
6922edb769dSLars-Peter Clausen 			AD7793_FLAG_HAS_VBIAS |
693fd1a8b91SLars-Peter Clausen 			AD7793_HAS_EXITATION_CURRENT |
694fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_GAIN |
695fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_BUFFER,
696f87f1a23SLars-Peter Clausen 	},
697f87f1a23SLars-Peter Clausen 	[ID_AD7793] = {
698f87f1a23SLars-Peter Clausen 		.id = AD7793_ID,
699f87f1a23SLars-Peter Clausen 		.channels = ad7793_channels,
700f87f1a23SLars-Peter Clausen 		.num_channels = ARRAY_SIZE(ad7793_channels),
701fd1a8b91SLars-Peter Clausen 		.iio_info = &ad7793_info,
702fd1a8b91SLars-Peter Clausen 		.sample_freq_avail = ad7793_sample_freq_avail,
7032edb769dSLars-Peter Clausen 		.flags = AD7793_FLAG_HAS_CLKSEL |
7042edb769dSLars-Peter Clausen 			AD7793_FLAG_HAS_REFSEL |
7052edb769dSLars-Peter Clausen 			AD7793_FLAG_HAS_VBIAS |
706fd1a8b91SLars-Peter Clausen 			AD7793_HAS_EXITATION_CURRENT |
707fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_GAIN |
708fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_BUFFER,
709f87f1a23SLars-Peter Clausen 	},
710f87f1a23SLars-Peter Clausen 	[ID_AD7794] = {
711f87f1a23SLars-Peter Clausen 		.id = AD7794_ID,
712f87f1a23SLars-Peter Clausen 		.channels = ad7794_channels,
713f87f1a23SLars-Peter Clausen 		.num_channels = ARRAY_SIZE(ad7794_channels),
714fd1a8b91SLars-Peter Clausen 		.iio_info = &ad7793_info,
715fd1a8b91SLars-Peter Clausen 		.sample_freq_avail = ad7793_sample_freq_avail,
7162edb769dSLars-Peter Clausen 		.flags = AD7793_FLAG_HAS_CLKSEL |
7172edb769dSLars-Peter Clausen 			AD7793_FLAG_HAS_REFSEL |
7182edb769dSLars-Peter Clausen 			AD7793_FLAG_HAS_VBIAS |
719fd1a8b91SLars-Peter Clausen 			AD7793_HAS_EXITATION_CURRENT |
720fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_GAIN |
721fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_BUFFER,
722f87f1a23SLars-Peter Clausen 	},
723f87f1a23SLars-Peter Clausen 	[ID_AD7795] = {
724f87f1a23SLars-Peter Clausen 		.id = AD7795_ID,
725f87f1a23SLars-Peter Clausen 		.channels = ad7795_channels,
726f87f1a23SLars-Peter Clausen 		.num_channels = ARRAY_SIZE(ad7795_channels),
727fd1a8b91SLars-Peter Clausen 		.iio_info = &ad7793_info,
728fd1a8b91SLars-Peter Clausen 		.sample_freq_avail = ad7793_sample_freq_avail,
7292edb769dSLars-Peter Clausen 		.flags = AD7793_FLAG_HAS_CLKSEL |
7302edb769dSLars-Peter Clausen 			AD7793_FLAG_HAS_REFSEL |
7312edb769dSLars-Peter Clausen 			AD7793_FLAG_HAS_VBIAS |
732fd1a8b91SLars-Peter Clausen 			AD7793_HAS_EXITATION_CURRENT |
733fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_GAIN |
734fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_BUFFER,
735fd1a8b91SLars-Peter Clausen 	},
736fd1a8b91SLars-Peter Clausen 	[ID_AD7796] = {
737fd1a8b91SLars-Peter Clausen 		.id = AD7796_ID,
738fd1a8b91SLars-Peter Clausen 		.channels = ad7796_channels,
739fd1a8b91SLars-Peter Clausen 		.num_channels = ARRAY_SIZE(ad7796_channels),
740fd1a8b91SLars-Peter Clausen 		.iio_info = &ad7797_info,
741fd1a8b91SLars-Peter Clausen 		.sample_freq_avail = ad7797_sample_freq_avail,
742fd1a8b91SLars-Peter Clausen 		.flags = AD7793_FLAG_HAS_CLKSEL,
743fd1a8b91SLars-Peter Clausen 	},
744fd1a8b91SLars-Peter Clausen 	[ID_AD7797] = {
745fd1a8b91SLars-Peter Clausen 		.id = AD7797_ID,
746fd1a8b91SLars-Peter Clausen 		.channels = ad7797_channels,
747fd1a8b91SLars-Peter Clausen 		.num_channels = ARRAY_SIZE(ad7797_channels),
748fd1a8b91SLars-Peter Clausen 		.iio_info = &ad7797_info,
749fd1a8b91SLars-Peter Clausen 		.sample_freq_avail = ad7797_sample_freq_avail,
750fd1a8b91SLars-Peter Clausen 		.flags = AD7793_FLAG_HAS_CLKSEL,
7512edb769dSLars-Peter Clausen 	},
7522edb769dSLars-Peter Clausen 	[ID_AD7798] = {
7532edb769dSLars-Peter Clausen 		.id = AD7798_ID,
7542edb769dSLars-Peter Clausen 		.channels = ad7798_channels,
7552edb769dSLars-Peter Clausen 		.num_channels = ARRAY_SIZE(ad7798_channels),
756fd1a8b91SLars-Peter Clausen 		.iio_info = &ad7793_info,
757fd1a8b91SLars-Peter Clausen 		.sample_freq_avail = ad7793_sample_freq_avail,
758fd1a8b91SLars-Peter Clausen 		.flags = AD7793_FLAG_HAS_GAIN |
759fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_BUFFER,
7602edb769dSLars-Peter Clausen 	},
7612edb769dSLars-Peter Clausen 	[ID_AD7799] = {
7622edb769dSLars-Peter Clausen 		.id = AD7799_ID,
7632edb769dSLars-Peter Clausen 		.channels = ad7799_channels,
7642edb769dSLars-Peter Clausen 		.num_channels = ARRAY_SIZE(ad7799_channels),
765fd1a8b91SLars-Peter Clausen 		.iio_info = &ad7793_info,
766fd1a8b91SLars-Peter Clausen 		.sample_freq_avail = ad7793_sample_freq_avail,
767fd1a8b91SLars-Peter Clausen 		.flags = AD7793_FLAG_HAS_GAIN |
768fd1a8b91SLars-Peter Clausen 			AD7793_FLAG_HAS_BUFFER,
769f87f1a23SLars-Peter Clausen 	},
770f87f1a23SLars-Peter Clausen };
771f87f1a23SLars-Peter Clausen 
ad7793_reg_disable(void * reg)772801a80efSAlexandru Ardelean static void ad7793_reg_disable(void *reg)
773801a80efSAlexandru Ardelean {
774801a80efSAlexandru Ardelean 	regulator_disable(reg);
775801a80efSAlexandru Ardelean }
776801a80efSAlexandru Ardelean 
ad7793_probe(struct spi_device * spi)777f87f1a23SLars-Peter Clausen static int ad7793_probe(struct spi_device *spi)
778f87f1a23SLars-Peter Clausen {
779f87f1a23SLars-Peter Clausen 	const struct ad7793_platform_data *pdata = spi->dev.platform_data;
780f87f1a23SLars-Peter Clausen 	struct ad7793_state *st;
781f87f1a23SLars-Peter Clausen 	struct iio_dev *indio_dev;
782f87f1a23SLars-Peter Clausen 	int ret, vref_mv = 0;
783f87f1a23SLars-Peter Clausen 
784f87f1a23SLars-Peter Clausen 	if (!pdata) {
785f87f1a23SLars-Peter Clausen 		dev_err(&spi->dev, "no platform data?\n");
786f87f1a23SLars-Peter Clausen 		return -ENODEV;
787f87f1a23SLars-Peter Clausen 	}
788f87f1a23SLars-Peter Clausen 
789f87f1a23SLars-Peter Clausen 	if (!spi->irq) {
790f87f1a23SLars-Peter Clausen 		dev_err(&spi->dev, "no IRQ?\n");
791f87f1a23SLars-Peter Clausen 		return -ENODEV;
792f87f1a23SLars-Peter Clausen 	}
793f87f1a23SLars-Peter Clausen 
794a3580132SSachin Kamat 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
795f87f1a23SLars-Peter Clausen 	if (indio_dev == NULL)
796f87f1a23SLars-Peter Clausen 		return -ENOMEM;
797f87f1a23SLars-Peter Clausen 
798f87f1a23SLars-Peter Clausen 	st = iio_priv(indio_dev);
799f87f1a23SLars-Peter Clausen 
800f87f1a23SLars-Peter Clausen 	ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
801f87f1a23SLars-Peter Clausen 
802f87f1a23SLars-Peter Clausen 	if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
803a3580132SSachin Kamat 		st->reg = devm_regulator_get(&spi->dev, "refin");
804a3580132SSachin Kamat 		if (IS_ERR(st->reg))
805a3580132SSachin Kamat 			return PTR_ERR(st->reg);
806f87f1a23SLars-Peter Clausen 
807f87f1a23SLars-Peter Clausen 		ret = regulator_enable(st->reg);
808f87f1a23SLars-Peter Clausen 		if (ret)
809a3580132SSachin Kamat 			return ret;
810f87f1a23SLars-Peter Clausen 
811801a80efSAlexandru Ardelean 		ret = devm_add_action_or_reset(&spi->dev, ad7793_reg_disable, st->reg);
812801a80efSAlexandru Ardelean 		if (ret)
813801a80efSAlexandru Ardelean 			return ret;
814801a80efSAlexandru Ardelean 
815f87f1a23SLars-Peter Clausen 		vref_mv = regulator_get_voltage(st->reg);
816801a80efSAlexandru Ardelean 		if (vref_mv < 0)
817801a80efSAlexandru Ardelean 			return vref_mv;
818f87f1a23SLars-Peter Clausen 
819f87f1a23SLars-Peter Clausen 		vref_mv /= 1000;
820f87f1a23SLars-Peter Clausen 	} else {
821f87f1a23SLars-Peter Clausen 		vref_mv = 1170; /* Build-in ref */
822f87f1a23SLars-Peter Clausen 	}
823f87f1a23SLars-Peter Clausen 
824f87f1a23SLars-Peter Clausen 	st->chip_info =
825f87f1a23SLars-Peter Clausen 		&ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data];
826f87f1a23SLars-Peter Clausen 
827f87f1a23SLars-Peter Clausen 	indio_dev->name = spi_get_device_id(spi)->name;
828f87f1a23SLars-Peter Clausen 	indio_dev->modes = INDIO_DIRECT_MODE;
829f87f1a23SLars-Peter Clausen 	indio_dev->channels = st->chip_info->channels;
830f87f1a23SLars-Peter Clausen 	indio_dev->num_channels = st->chip_info->num_channels;
831fd1a8b91SLars-Peter Clausen 	indio_dev->info = st->chip_info->iio_info;
832f87f1a23SLars-Peter Clausen 
833801a80efSAlexandru Ardelean 	ret = devm_ad_sd_setup_buffer_and_trigger(&spi->dev, indio_dev);
834f87f1a23SLars-Peter Clausen 	if (ret)
835801a80efSAlexandru Ardelean 		return ret;
836f87f1a23SLars-Peter Clausen 
837f87f1a23SLars-Peter Clausen 	ret = ad7793_setup(indio_dev, pdata, vref_mv);
838f87f1a23SLars-Peter Clausen 	if (ret)
839f87f1a23SLars-Peter Clausen 		return ret;
840f87f1a23SLars-Peter Clausen 
841801a80efSAlexandru Ardelean 	return devm_iio_device_register(&spi->dev, indio_dev);
842f87f1a23SLars-Peter Clausen }
843f87f1a23SLars-Peter Clausen 
844f87f1a23SLars-Peter Clausen static const struct spi_device_id ad7793_id[] = {
845f87f1a23SLars-Peter Clausen 	{"ad7785", ID_AD7785},
846f87f1a23SLars-Peter Clausen 	{"ad7792", ID_AD7792},
847f87f1a23SLars-Peter Clausen 	{"ad7793", ID_AD7793},
848f87f1a23SLars-Peter Clausen 	{"ad7794", ID_AD7794},
849f87f1a23SLars-Peter Clausen 	{"ad7795", ID_AD7795},
850fd1a8b91SLars-Peter Clausen 	{"ad7796", ID_AD7796},
851fd1a8b91SLars-Peter Clausen 	{"ad7797", ID_AD7797},
8522edb769dSLars-Peter Clausen 	{"ad7798", ID_AD7798},
8532edb769dSLars-Peter Clausen 	{"ad7799", ID_AD7799},
854f87f1a23SLars-Peter Clausen 	{}
855f87f1a23SLars-Peter Clausen };
856f87f1a23SLars-Peter Clausen MODULE_DEVICE_TABLE(spi, ad7793_id);
857f87f1a23SLars-Peter Clausen 
858f87f1a23SLars-Peter Clausen static struct spi_driver ad7793_driver = {
859f87f1a23SLars-Peter Clausen 	.driver = {
860f87f1a23SLars-Peter Clausen 		.name	= "ad7793",
861f87f1a23SLars-Peter Clausen 	},
862f87f1a23SLars-Peter Clausen 	.probe		= ad7793_probe,
863f87f1a23SLars-Peter Clausen 	.id_table	= ad7793_id,
864f87f1a23SLars-Peter Clausen };
865f87f1a23SLars-Peter Clausen module_spi_driver(ad7793_driver);
866f87f1a23SLars-Peter Clausen 
8679920ed25SMichael Hennerich MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
8681672d933SMasanari Iida MODULE_DESCRIPTION("Analog Devices AD7793 and similar ADCs");
869f87f1a23SLars-Peter Clausen MODULE_LICENSE("GPL v2");
870*ef807729SJonathan Cameron MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA);
871