xref: /OK3568_Linux_fs/kernel/drivers/iio/adc/ad7793.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * AD7785/AD7792/AD7793/AD7794/AD7795 SPI ADC driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright 2011-2012 Analog Devices Inc.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/interrupt.h>
9*4882a593Smuzhiyun #include <linux/device.h>
10*4882a593Smuzhiyun #include <linux/kernel.h>
11*4882a593Smuzhiyun #include <linux/slab.h>
12*4882a593Smuzhiyun #include <linux/sysfs.h>
13*4882a593Smuzhiyun #include <linux/spi/spi.h>
14*4882a593Smuzhiyun #include <linux/regulator/consumer.h>
15*4882a593Smuzhiyun #include <linux/err.h>
16*4882a593Smuzhiyun #include <linux/sched.h>
17*4882a593Smuzhiyun #include <linux/delay.h>
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include <linux/iio/iio.h>
21*4882a593Smuzhiyun #include <linux/iio/sysfs.h>
22*4882a593Smuzhiyun #include <linux/iio/buffer.h>
23*4882a593Smuzhiyun #include <linux/iio/trigger.h>
24*4882a593Smuzhiyun #include <linux/iio/trigger_consumer.h>
25*4882a593Smuzhiyun #include <linux/iio/triggered_buffer.h>
26*4882a593Smuzhiyun #include <linux/iio/adc/ad_sigma_delta.h>
27*4882a593Smuzhiyun #include <linux/platform_data/ad7793.h>
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /* Registers */
30*4882a593Smuzhiyun #define AD7793_REG_COMM		0 /* Communications Register (WO, 8-bit) */
31*4882a593Smuzhiyun #define AD7793_REG_STAT		0 /* Status Register	     (RO, 8-bit) */
32*4882a593Smuzhiyun #define AD7793_REG_MODE		1 /* Mode Register	     (RW, 16-bit */
33*4882a593Smuzhiyun #define AD7793_REG_CONF		2 /* Configuration Register  (RW, 16-bit) */
34*4882a593Smuzhiyun #define AD7793_REG_DATA		3 /* Data Register	     (RO, 16-/24-bit) */
35*4882a593Smuzhiyun #define AD7793_REG_ID		4 /* ID Register	     (RO, 8-bit) */
36*4882a593Smuzhiyun #define AD7793_REG_IO		5 /* IO Register	     (RO, 8-bit) */
37*4882a593Smuzhiyun #define AD7793_REG_OFFSET	6 /* Offset Register	     (RW, 16-bit
38*4882a593Smuzhiyun 				   * (AD7792)/24-bit (AD7793)) */
39*4882a593Smuzhiyun #define AD7793_REG_FULLSALE	7 /* Full-Scale Register
40*4882a593Smuzhiyun 				   * (RW, 16-bit (AD7792)/24-bit (AD7793)) */
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /* Communications Register Bit Designations (AD7793_REG_COMM) */
43*4882a593Smuzhiyun #define AD7793_COMM_WEN		(1 << 7) /* Write Enable */
44*4882a593Smuzhiyun #define AD7793_COMM_WRITE	(0 << 6) /* Write Operation */
45*4882a593Smuzhiyun #define AD7793_COMM_READ	(1 << 6) /* Read Operation */
46*4882a593Smuzhiyun #define AD7793_COMM_ADDR(x)	(((x) & 0x7) << 3) /* Register Address */
47*4882a593Smuzhiyun #define AD7793_COMM_CREAD	(1 << 2) /* Continuous Read of Data Register */
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /* Status Register Bit Designations (AD7793_REG_STAT) */
50*4882a593Smuzhiyun #define AD7793_STAT_RDY		(1 << 7) /* Ready */
51*4882a593Smuzhiyun #define AD7793_STAT_ERR		(1 << 6) /* Error (Overrange, Underrange) */
52*4882a593Smuzhiyun #define AD7793_STAT_CH3		(1 << 2) /* Channel 3 */
53*4882a593Smuzhiyun #define AD7793_STAT_CH2		(1 << 1) /* Channel 2 */
54*4882a593Smuzhiyun #define AD7793_STAT_CH1		(1 << 0) /* Channel 1 */
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun /* Mode Register Bit Designations (AD7793_REG_MODE) */
57*4882a593Smuzhiyun #define AD7793_MODE_SEL(x)	(((x) & 0x7) << 13) /* Operation Mode Select */
58*4882a593Smuzhiyun #define AD7793_MODE_SEL_MASK	(0x7 << 13) /* Operation Mode Select mask */
59*4882a593Smuzhiyun #define AD7793_MODE_CLKSRC(x)	(((x) & 0x3) << 6) /* ADC Clock Source Select */
60*4882a593Smuzhiyun #define AD7793_MODE_RATE(x)	((x) & 0xF) /* Filter Update Rate Select */
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun #define AD7793_MODE_CONT		0 /* Continuous Conversion Mode */
63*4882a593Smuzhiyun #define AD7793_MODE_SINGLE		1 /* Single Conversion Mode */
64*4882a593Smuzhiyun #define AD7793_MODE_IDLE		2 /* Idle Mode */
65*4882a593Smuzhiyun #define AD7793_MODE_PWRDN		3 /* Power-Down Mode */
66*4882a593Smuzhiyun #define AD7793_MODE_CAL_INT_ZERO	4 /* Internal Zero-Scale Calibration */
67*4882a593Smuzhiyun #define AD7793_MODE_CAL_INT_FULL	5 /* Internal Full-Scale Calibration */
68*4882a593Smuzhiyun #define AD7793_MODE_CAL_SYS_ZERO	6 /* System Zero-Scale Calibration */
69*4882a593Smuzhiyun #define AD7793_MODE_CAL_SYS_FULL	7 /* System Full-Scale Calibration */
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun #define AD7793_CLK_INT		0 /* Internal 64 kHz Clock not
72*4882a593Smuzhiyun 				   * available at the CLK pin */
73*4882a593Smuzhiyun #define AD7793_CLK_INT_CO	1 /* Internal 64 kHz Clock available
74*4882a593Smuzhiyun 				   * at the CLK pin */
75*4882a593Smuzhiyun #define AD7793_CLK_EXT		2 /* External 64 kHz Clock */
76*4882a593Smuzhiyun #define AD7793_CLK_EXT_DIV2	3 /* External Clock divided by 2 */
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /* Configuration Register Bit Designations (AD7793_REG_CONF) */
79*4882a593Smuzhiyun #define AD7793_CONF_VBIAS(x)	(((x) & 0x3) << 14) /* Bias Voltage
80*4882a593Smuzhiyun 						     * Generator Enable */
81*4882a593Smuzhiyun #define AD7793_CONF_BO_EN	(1 << 13) /* Burnout Current Enable */
82*4882a593Smuzhiyun #define AD7793_CONF_UNIPOLAR	(1 << 12) /* Unipolar/Bipolar Enable */
83*4882a593Smuzhiyun #define AD7793_CONF_BOOST	(1 << 11) /* Boost Enable */
84*4882a593Smuzhiyun #define AD7793_CONF_GAIN(x)	(((x) & 0x7) << 8) /* Gain Select */
85*4882a593Smuzhiyun #define AD7793_CONF_REFSEL(x)	((x) << 6) /* INT/EXT Reference Select */
86*4882a593Smuzhiyun #define AD7793_CONF_BUF		(1 << 4) /* Buffered Mode Enable */
87*4882a593Smuzhiyun #define AD7793_CONF_CHAN(x)	((x) & 0xf) /* Channel select */
88*4882a593Smuzhiyun #define AD7793_CONF_CHAN_MASK	0xf /* Channel select mask */
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun #define AD7793_CH_AIN1P_AIN1M	0 /* AIN1(+) - AIN1(-) */
91*4882a593Smuzhiyun #define AD7793_CH_AIN2P_AIN2M	1 /* AIN2(+) - AIN2(-) */
92*4882a593Smuzhiyun #define AD7793_CH_AIN3P_AIN3M	2 /* AIN3(+) - AIN3(-) */
93*4882a593Smuzhiyun #define AD7793_CH_AIN1M_AIN1M	3 /* AIN1(-) - AIN1(-) */
94*4882a593Smuzhiyun #define AD7793_CH_TEMP		6 /* Temp Sensor */
95*4882a593Smuzhiyun #define AD7793_CH_AVDD_MONITOR	7 /* AVDD Monitor */
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun #define AD7795_CH_AIN4P_AIN4M	4 /* AIN4(+) - AIN4(-) */
98*4882a593Smuzhiyun #define AD7795_CH_AIN5P_AIN5M	5 /* AIN5(+) - AIN5(-) */
99*4882a593Smuzhiyun #define AD7795_CH_AIN6P_AIN6M	6 /* AIN6(+) - AIN6(-) */
100*4882a593Smuzhiyun #define AD7795_CH_AIN1M_AIN1M	8 /* AIN1(-) - AIN1(-) */
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun /* ID Register Bit Designations (AD7793_REG_ID) */
103*4882a593Smuzhiyun #define AD7785_ID		0x3
104*4882a593Smuzhiyun #define AD7792_ID		0xA
105*4882a593Smuzhiyun #define AD7793_ID		0xB
106*4882a593Smuzhiyun #define AD7794_ID		0xF
107*4882a593Smuzhiyun #define AD7795_ID		0xF
108*4882a593Smuzhiyun #define AD7796_ID		0xA
109*4882a593Smuzhiyun #define AD7797_ID		0xB
110*4882a593Smuzhiyun #define AD7798_ID		0x8
111*4882a593Smuzhiyun #define AD7799_ID		0x9
112*4882a593Smuzhiyun #define AD7793_ID_MASK		0xF
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun /* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */
115*4882a593Smuzhiyun #define AD7793_IO_IEXC1_IOUT1_IEXC2_IOUT2	0 /* IEXC1 connect to IOUT1,
116*4882a593Smuzhiyun 						   * IEXC2 connect to IOUT2 */
117*4882a593Smuzhiyun #define AD7793_IO_IEXC1_IOUT2_IEXC2_IOUT1	1 /* IEXC1 connect to IOUT2,
118*4882a593Smuzhiyun 						   * IEXC2 connect to IOUT1 */
119*4882a593Smuzhiyun #define AD7793_IO_IEXC1_IEXC2_IOUT1		2 /* Both current sources
120*4882a593Smuzhiyun 						   * IEXC1,2 connect to IOUT1 */
121*4882a593Smuzhiyun #define AD7793_IO_IEXC1_IEXC2_IOUT2		3 /* Both current sources
122*4882a593Smuzhiyun 						   * IEXC1,2 connect to IOUT2 */
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun #define AD7793_IO_IXCEN_10uA	(1 << 0) /* Excitation Current 10uA */
125*4882a593Smuzhiyun #define AD7793_IO_IXCEN_210uA	(2 << 0) /* Excitation Current 210uA */
126*4882a593Smuzhiyun #define AD7793_IO_IXCEN_1mA	(3 << 0) /* Excitation Current 1mA */
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun /* NOTE:
129*4882a593Smuzhiyun  * The AD7792/AD7793 features a dual use data out ready DOUT/RDY output.
130*4882a593Smuzhiyun  * In order to avoid contentions on the SPI bus, it's therefore necessary
131*4882a593Smuzhiyun  * to use spi bus locking.
132*4882a593Smuzhiyun  *
133*4882a593Smuzhiyun  * The DOUT/RDY output must also be wired to an interrupt capable GPIO.
134*4882a593Smuzhiyun  */
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun #define AD7793_FLAG_HAS_CLKSEL		BIT(0)
137*4882a593Smuzhiyun #define AD7793_FLAG_HAS_REFSEL		BIT(1)
138*4882a593Smuzhiyun #define AD7793_FLAG_HAS_VBIAS		BIT(2)
139*4882a593Smuzhiyun #define AD7793_HAS_EXITATION_CURRENT	BIT(3)
140*4882a593Smuzhiyun #define AD7793_FLAG_HAS_GAIN		BIT(4)
141*4882a593Smuzhiyun #define AD7793_FLAG_HAS_BUFFER		BIT(5)
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun struct ad7793_chip_info {
144*4882a593Smuzhiyun 	unsigned int id;
145*4882a593Smuzhiyun 	const struct iio_chan_spec *channels;
146*4882a593Smuzhiyun 	unsigned int num_channels;
147*4882a593Smuzhiyun 	unsigned int flags;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	const struct iio_info *iio_info;
150*4882a593Smuzhiyun 	const u16 *sample_freq_avail;
151*4882a593Smuzhiyun };
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun struct ad7793_state {
154*4882a593Smuzhiyun 	const struct ad7793_chip_info	*chip_info;
155*4882a593Smuzhiyun 	struct regulator		*reg;
156*4882a593Smuzhiyun 	u16				int_vref_mv;
157*4882a593Smuzhiyun 	u16				mode;
158*4882a593Smuzhiyun 	u16				conf;
159*4882a593Smuzhiyun 	u32				scale_avail[8][2];
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	struct ad_sigma_delta		sd;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun };
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun enum ad7793_supported_device_ids {
166*4882a593Smuzhiyun 	ID_AD7785,
167*4882a593Smuzhiyun 	ID_AD7792,
168*4882a593Smuzhiyun 	ID_AD7793,
169*4882a593Smuzhiyun 	ID_AD7794,
170*4882a593Smuzhiyun 	ID_AD7795,
171*4882a593Smuzhiyun 	ID_AD7796,
172*4882a593Smuzhiyun 	ID_AD7797,
173*4882a593Smuzhiyun 	ID_AD7798,
174*4882a593Smuzhiyun 	ID_AD7799,
175*4882a593Smuzhiyun };
176*4882a593Smuzhiyun 
ad_sigma_delta_to_ad7793(struct ad_sigma_delta * sd)177*4882a593Smuzhiyun static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun 	return container_of(sd, struct ad7793_state, sd);
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun 
ad7793_set_channel(struct ad_sigma_delta * sd,unsigned int channel)182*4882a593Smuzhiyun static int ad7793_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd);
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	st->conf &= ~AD7793_CONF_CHAN_MASK;
187*4882a593Smuzhiyun 	st->conf |= AD7793_CONF_CHAN(channel);
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	return ad_sd_write_reg(&st->sd, AD7793_REG_CONF, 2, st->conf);
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun 
ad7793_set_mode(struct ad_sigma_delta * sd,enum ad_sigma_delta_mode mode)192*4882a593Smuzhiyun static int ad7793_set_mode(struct ad_sigma_delta *sd,
193*4882a593Smuzhiyun 			   enum ad_sigma_delta_mode mode)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun 	struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	st->mode &= ~AD7793_MODE_SEL_MASK;
198*4882a593Smuzhiyun 	st->mode |= AD7793_MODE_SEL(mode);
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	return ad_sd_write_reg(&st->sd, AD7793_REG_MODE, 2, st->mode);
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun static const struct ad_sigma_delta_info ad7793_sigma_delta_info = {
204*4882a593Smuzhiyun 	.set_channel = ad7793_set_channel,
205*4882a593Smuzhiyun 	.set_mode = ad7793_set_mode,
206*4882a593Smuzhiyun 	.has_registers = true,
207*4882a593Smuzhiyun 	.addr_shift = 3,
208*4882a593Smuzhiyun 	.read_mask = BIT(6),
209*4882a593Smuzhiyun 	.irq_flags = IRQF_TRIGGER_FALLING,
210*4882a593Smuzhiyun };
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun static const struct ad_sd_calib_data ad7793_calib_arr[6] = {
213*4882a593Smuzhiyun 	{AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M},
214*4882a593Smuzhiyun 	{AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M},
215*4882a593Smuzhiyun 	{AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M},
216*4882a593Smuzhiyun 	{AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN2P_AIN2M},
217*4882a593Smuzhiyun 	{AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN3P_AIN3M},
218*4882a593Smuzhiyun 	{AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN3P_AIN3M}
219*4882a593Smuzhiyun };
220*4882a593Smuzhiyun 
ad7793_calibrate_all(struct ad7793_state * st)221*4882a593Smuzhiyun static int ad7793_calibrate_all(struct ad7793_state *st)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	return ad_sd_calibrate_all(&st->sd, ad7793_calib_arr,
224*4882a593Smuzhiyun 				   ARRAY_SIZE(ad7793_calib_arr));
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun 
ad7793_check_platform_data(struct ad7793_state * st,const struct ad7793_platform_data * pdata)227*4882a593Smuzhiyun static int ad7793_check_platform_data(struct ad7793_state *st,
228*4882a593Smuzhiyun 	const struct ad7793_platform_data *pdata)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	if ((pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT1 ||
231*4882a593Smuzhiyun 		pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT2) &&
232*4882a593Smuzhiyun 		((pdata->exitation_current != AD7793_IX_10uA) &&
233*4882a593Smuzhiyun 		(pdata->exitation_current != AD7793_IX_210uA)))
234*4882a593Smuzhiyun 		return -EINVAL;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	if (!(st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL) &&
237*4882a593Smuzhiyun 		pdata->clock_src != AD7793_CLK_SRC_INT)
238*4882a593Smuzhiyun 		return -EINVAL;
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	if (!(st->chip_info->flags & AD7793_FLAG_HAS_REFSEL) &&
241*4882a593Smuzhiyun 		pdata->refsel != AD7793_REFSEL_REFIN1)
242*4882a593Smuzhiyun 		return -EINVAL;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	if (!(st->chip_info->flags & AD7793_FLAG_HAS_VBIAS) &&
245*4882a593Smuzhiyun 		pdata->bias_voltage != AD7793_BIAS_VOLTAGE_DISABLED)
246*4882a593Smuzhiyun 		return -EINVAL;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	if (!(st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) &&
249*4882a593Smuzhiyun 		pdata->exitation_current != AD7793_IX_DISABLED)
250*4882a593Smuzhiyun 		return -EINVAL;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	return 0;
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun 
ad7793_setup(struct iio_dev * indio_dev,const struct ad7793_platform_data * pdata,unsigned int vref_mv)255*4882a593Smuzhiyun static int ad7793_setup(struct iio_dev *indio_dev,
256*4882a593Smuzhiyun 	const struct ad7793_platform_data *pdata,
257*4882a593Smuzhiyun 	unsigned int vref_mv)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun 	struct ad7793_state *st = iio_priv(indio_dev);
260*4882a593Smuzhiyun 	int i, ret;
261*4882a593Smuzhiyun 	unsigned long long scale_uv;
262*4882a593Smuzhiyun 	u32 id;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	ret = ad7793_check_platform_data(st, pdata);
265*4882a593Smuzhiyun 	if (ret)
266*4882a593Smuzhiyun 		return ret;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	/* reset the serial interface */
269*4882a593Smuzhiyun 	ret = ad_sd_reset(&st->sd, 32);
270*4882a593Smuzhiyun 	if (ret < 0)
271*4882a593Smuzhiyun 		goto out;
272*4882a593Smuzhiyun 	usleep_range(500, 2000); /* Wait for at least 500us */
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	/* write/read test for device presence */
275*4882a593Smuzhiyun 	ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id);
276*4882a593Smuzhiyun 	if (ret)
277*4882a593Smuzhiyun 		goto out;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	id &= AD7793_ID_MASK;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	if (id != st->chip_info->id) {
282*4882a593Smuzhiyun 		ret = -ENODEV;
283*4882a593Smuzhiyun 		dev_err(&st->sd.spi->dev, "device ID query failed\n");
284*4882a593Smuzhiyun 		goto out;
285*4882a593Smuzhiyun 	}
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 	st->mode = AD7793_MODE_RATE(1);
288*4882a593Smuzhiyun 	st->conf = 0;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	if (st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL)
291*4882a593Smuzhiyun 		st->mode |= AD7793_MODE_CLKSRC(pdata->clock_src);
292*4882a593Smuzhiyun 	if (st->chip_info->flags & AD7793_FLAG_HAS_REFSEL)
293*4882a593Smuzhiyun 		st->conf |= AD7793_CONF_REFSEL(pdata->refsel);
294*4882a593Smuzhiyun 	if (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS)
295*4882a593Smuzhiyun 		st->conf |= AD7793_CONF_VBIAS(pdata->bias_voltage);
296*4882a593Smuzhiyun 	if (pdata->buffered || !(st->chip_info->flags & AD7793_FLAG_HAS_BUFFER))
297*4882a593Smuzhiyun 		st->conf |= AD7793_CONF_BUF;
298*4882a593Smuzhiyun 	if (pdata->boost_enable &&
299*4882a593Smuzhiyun 		(st->chip_info->flags & AD7793_FLAG_HAS_VBIAS))
300*4882a593Smuzhiyun 		st->conf |= AD7793_CONF_BOOST;
301*4882a593Smuzhiyun 	if (pdata->burnout_current)
302*4882a593Smuzhiyun 		st->conf |= AD7793_CONF_BO_EN;
303*4882a593Smuzhiyun 	if (pdata->unipolar)
304*4882a593Smuzhiyun 		st->conf |= AD7793_CONF_UNIPOLAR;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	if (!(st->chip_info->flags & AD7793_FLAG_HAS_GAIN))
307*4882a593Smuzhiyun 		st->conf |= AD7793_CONF_GAIN(7);
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	ret = ad7793_set_mode(&st->sd, AD_SD_MODE_IDLE);
310*4882a593Smuzhiyun 	if (ret)
311*4882a593Smuzhiyun 		goto out;
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	ret = ad7793_set_channel(&st->sd, 0);
314*4882a593Smuzhiyun 	if (ret)
315*4882a593Smuzhiyun 		goto out;
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	if (st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) {
318*4882a593Smuzhiyun 		ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, 1,
319*4882a593Smuzhiyun 				pdata->exitation_current |
320*4882a593Smuzhiyun 				(pdata->current_source_direction << 2));
321*4882a593Smuzhiyun 		if (ret)
322*4882a593Smuzhiyun 			goto out;
323*4882a593Smuzhiyun 	}
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	ret = ad7793_calibrate_all(st);
326*4882a593Smuzhiyun 	if (ret)
327*4882a593Smuzhiyun 		goto out;
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	/* Populate available ADC input ranges */
330*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) {
331*4882a593Smuzhiyun 		scale_uv = ((u64)vref_mv * 100000000)
332*4882a593Smuzhiyun 			>> (st->chip_info->channels[0].scan_type.realbits -
333*4882a593Smuzhiyun 			(!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1));
334*4882a593Smuzhiyun 		scale_uv >>= i;
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 		st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10;
337*4882a593Smuzhiyun 		st->scale_avail[i][0] = scale_uv;
338*4882a593Smuzhiyun 	}
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	return 0;
341*4882a593Smuzhiyun out:
342*4882a593Smuzhiyun 	dev_err(&st->sd.spi->dev, "setup failed\n");
343*4882a593Smuzhiyun 	return ret;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39,
347*4882a593Smuzhiyun 					33, 19, 17, 16, 12, 10, 8, 6, 4};
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun static const u16 ad7797_sample_freq_avail[16] = {0, 0, 0, 123, 62, 50, 0,
350*4882a593Smuzhiyun 					33, 0, 17, 16, 12, 10, 8, 6, 4};
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
353*4882a593Smuzhiyun 	"470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun static IIO_CONST_ATTR_NAMED(sampling_frequency_available_ad7797,
356*4882a593Smuzhiyun 	sampling_frequency_available, "123 62 50 33 17 16 12 10 8 6 4");
357*4882a593Smuzhiyun 
ad7793_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)358*4882a593Smuzhiyun static int ad7793_read_avail(struct iio_dev *indio_dev,
359*4882a593Smuzhiyun 			     struct iio_chan_spec const *chan,
360*4882a593Smuzhiyun 			     const int **vals, int *type, int *length,
361*4882a593Smuzhiyun 			     long mask)
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun 	struct ad7793_state *st = iio_priv(indio_dev);
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	switch (mask) {
366*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
367*4882a593Smuzhiyun 		*vals = (int *)st->scale_avail;
368*4882a593Smuzhiyun 		*type = IIO_VAL_INT_PLUS_NANO;
369*4882a593Smuzhiyun 		/* Values are stored in a 2D matrix  */
370*4882a593Smuzhiyun 		*length = ARRAY_SIZE(st->scale_avail) * 2;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 		return IIO_AVAIL_LIST;
373*4882a593Smuzhiyun 	default:
374*4882a593Smuzhiyun 		return -EINVAL;
375*4882a593Smuzhiyun 	}
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun static struct attribute *ad7793_attributes[] = {
379*4882a593Smuzhiyun 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
380*4882a593Smuzhiyun 	NULL
381*4882a593Smuzhiyun };
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun static const struct attribute_group ad7793_attribute_group = {
384*4882a593Smuzhiyun 	.attrs = ad7793_attributes,
385*4882a593Smuzhiyun };
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun static struct attribute *ad7797_attributes[] = {
388*4882a593Smuzhiyun 	&iio_const_attr_sampling_frequency_available_ad7797.dev_attr.attr,
389*4882a593Smuzhiyun 	NULL
390*4882a593Smuzhiyun };
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun static const struct attribute_group ad7797_attribute_group = {
393*4882a593Smuzhiyun 	.attrs = ad7797_attributes,
394*4882a593Smuzhiyun };
395*4882a593Smuzhiyun 
ad7793_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long m)396*4882a593Smuzhiyun static int ad7793_read_raw(struct iio_dev *indio_dev,
397*4882a593Smuzhiyun 			   struct iio_chan_spec const *chan,
398*4882a593Smuzhiyun 			   int *val,
399*4882a593Smuzhiyun 			   int *val2,
400*4882a593Smuzhiyun 			   long m)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun 	struct ad7793_state *st = iio_priv(indio_dev);
403*4882a593Smuzhiyun 	int ret;
404*4882a593Smuzhiyun 	unsigned long long scale_uv;
405*4882a593Smuzhiyun 	bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR);
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	switch (m) {
408*4882a593Smuzhiyun 	case IIO_CHAN_INFO_RAW:
409*4882a593Smuzhiyun 		ret = ad_sigma_delta_single_conversion(indio_dev, chan, val);
410*4882a593Smuzhiyun 		if (ret < 0)
411*4882a593Smuzhiyun 			return ret;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 		return IIO_VAL_INT;
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
416*4882a593Smuzhiyun 		switch (chan->type) {
417*4882a593Smuzhiyun 		case IIO_VOLTAGE:
418*4882a593Smuzhiyun 			if (chan->differential) {
419*4882a593Smuzhiyun 				*val = st->
420*4882a593Smuzhiyun 					scale_avail[(st->conf >> 8) & 0x7][0];
421*4882a593Smuzhiyun 				*val2 = st->
422*4882a593Smuzhiyun 					scale_avail[(st->conf >> 8) & 0x7][1];
423*4882a593Smuzhiyun 				return IIO_VAL_INT_PLUS_NANO;
424*4882a593Smuzhiyun 			}
425*4882a593Smuzhiyun 			/* 1170mV / 2^23 * 6 */
426*4882a593Smuzhiyun 			scale_uv = (1170ULL * 1000000000ULL * 6ULL);
427*4882a593Smuzhiyun 			break;
428*4882a593Smuzhiyun 		case IIO_TEMP:
429*4882a593Smuzhiyun 				/* 1170mV / 0.81 mV/C / 2^23 */
430*4882a593Smuzhiyun 				scale_uv = 1444444444444444ULL;
431*4882a593Smuzhiyun 			break;
432*4882a593Smuzhiyun 		default:
433*4882a593Smuzhiyun 			return -EINVAL;
434*4882a593Smuzhiyun 		}
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 		scale_uv >>= (chan->scan_type.realbits - (unipolar ? 0 : 1));
437*4882a593Smuzhiyun 		*val = 0;
438*4882a593Smuzhiyun 		*val2 = scale_uv;
439*4882a593Smuzhiyun 		return IIO_VAL_INT_PLUS_NANO;
440*4882a593Smuzhiyun 	case IIO_CHAN_INFO_OFFSET:
441*4882a593Smuzhiyun 		if (!unipolar)
442*4882a593Smuzhiyun 			*val = -(1 << (chan->scan_type.realbits - 1));
443*4882a593Smuzhiyun 		else
444*4882a593Smuzhiyun 			*val = 0;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 		/* Kelvin to Celsius */
447*4882a593Smuzhiyun 		if (chan->type == IIO_TEMP) {
448*4882a593Smuzhiyun 			unsigned long long offset;
449*4882a593Smuzhiyun 			unsigned int shift;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 			shift = chan->scan_type.realbits - (unipolar ? 0 : 1);
452*4882a593Smuzhiyun 			offset = 273ULL << shift;
453*4882a593Smuzhiyun 			do_div(offset, 1444);
454*4882a593Smuzhiyun 			*val -= offset;
455*4882a593Smuzhiyun 		}
456*4882a593Smuzhiyun 		return IIO_VAL_INT;
457*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SAMP_FREQ:
458*4882a593Smuzhiyun 		*val = st->chip_info
459*4882a593Smuzhiyun 			       ->sample_freq_avail[AD7793_MODE_RATE(st->mode)];
460*4882a593Smuzhiyun 		return IIO_VAL_INT;
461*4882a593Smuzhiyun 	}
462*4882a593Smuzhiyun 	return -EINVAL;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun 
ad7793_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)465*4882a593Smuzhiyun static int ad7793_write_raw(struct iio_dev *indio_dev,
466*4882a593Smuzhiyun 			       struct iio_chan_spec const *chan,
467*4882a593Smuzhiyun 			       int val,
468*4882a593Smuzhiyun 			       int val2,
469*4882a593Smuzhiyun 			       long mask)
470*4882a593Smuzhiyun {
471*4882a593Smuzhiyun 	struct ad7793_state *st = iio_priv(indio_dev);
472*4882a593Smuzhiyun 	int ret, i;
473*4882a593Smuzhiyun 	unsigned int tmp;
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	ret = iio_device_claim_direct_mode(indio_dev);
476*4882a593Smuzhiyun 	if (ret)
477*4882a593Smuzhiyun 		return ret;
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 	switch (mask) {
480*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
481*4882a593Smuzhiyun 		ret = -EINVAL;
482*4882a593Smuzhiyun 		for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
483*4882a593Smuzhiyun 			if (val2 == st->scale_avail[i][1]) {
484*4882a593Smuzhiyun 				ret = 0;
485*4882a593Smuzhiyun 				tmp = st->conf;
486*4882a593Smuzhiyun 				st->conf &= ~AD7793_CONF_GAIN(-1);
487*4882a593Smuzhiyun 				st->conf |= AD7793_CONF_GAIN(i);
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 				if (tmp == st->conf)
490*4882a593Smuzhiyun 					break;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 				ad_sd_write_reg(&st->sd, AD7793_REG_CONF,
493*4882a593Smuzhiyun 						sizeof(st->conf), st->conf);
494*4882a593Smuzhiyun 				ad7793_calibrate_all(st);
495*4882a593Smuzhiyun 				break;
496*4882a593Smuzhiyun 			}
497*4882a593Smuzhiyun 		break;
498*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SAMP_FREQ:
499*4882a593Smuzhiyun 		if (!val) {
500*4882a593Smuzhiyun 			ret = -EINVAL;
501*4882a593Smuzhiyun 			break;
502*4882a593Smuzhiyun 		}
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 		for (i = 0; i < 16; i++)
505*4882a593Smuzhiyun 			if (val == st->chip_info->sample_freq_avail[i])
506*4882a593Smuzhiyun 				break;
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 		if (i == 16) {
509*4882a593Smuzhiyun 			ret = -EINVAL;
510*4882a593Smuzhiyun 			break;
511*4882a593Smuzhiyun 		}
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 		st->mode &= ~AD7793_MODE_RATE(-1);
514*4882a593Smuzhiyun 		st->mode |= AD7793_MODE_RATE(i);
515*4882a593Smuzhiyun 		ad_sd_write_reg(&st->sd, AD7793_REG_MODE, sizeof(st->mode),
516*4882a593Smuzhiyun 				st->mode);
517*4882a593Smuzhiyun 		break;
518*4882a593Smuzhiyun 	default:
519*4882a593Smuzhiyun 		ret = -EINVAL;
520*4882a593Smuzhiyun 	}
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 	iio_device_release_direct_mode(indio_dev);
523*4882a593Smuzhiyun 	return ret;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun 
ad7793_write_raw_get_fmt(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,long mask)526*4882a593Smuzhiyun static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev,
527*4882a593Smuzhiyun 			       struct iio_chan_spec const *chan,
528*4882a593Smuzhiyun 			       long mask)
529*4882a593Smuzhiyun {
530*4882a593Smuzhiyun 	return IIO_VAL_INT_PLUS_NANO;
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun static const struct iio_info ad7793_info = {
534*4882a593Smuzhiyun 	.read_raw = &ad7793_read_raw,
535*4882a593Smuzhiyun 	.write_raw = &ad7793_write_raw,
536*4882a593Smuzhiyun 	.write_raw_get_fmt = &ad7793_write_raw_get_fmt,
537*4882a593Smuzhiyun 	.read_avail = ad7793_read_avail,
538*4882a593Smuzhiyun 	.attrs = &ad7793_attribute_group,
539*4882a593Smuzhiyun 	.validate_trigger = ad_sd_validate_trigger,
540*4882a593Smuzhiyun };
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun static const struct iio_info ad7797_info = {
543*4882a593Smuzhiyun 	.read_raw = &ad7793_read_raw,
544*4882a593Smuzhiyun 	.write_raw = &ad7793_write_raw,
545*4882a593Smuzhiyun 	.write_raw_get_fmt = &ad7793_write_raw_get_fmt,
546*4882a593Smuzhiyun 	.attrs = &ad7797_attribute_group,
547*4882a593Smuzhiyun 	.validate_trigger = ad_sd_validate_trigger,
548*4882a593Smuzhiyun };
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun #define __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
551*4882a593Smuzhiyun 	_storagebits, _shift, _extend_name, _type, _mask_type_av, _mask_all) \
552*4882a593Smuzhiyun 	{ \
553*4882a593Smuzhiyun 		.type = (_type), \
554*4882a593Smuzhiyun 		.differential = (_channel2 == -1 ? 0 : 1), \
555*4882a593Smuzhiyun 		.indexed = 1, \
556*4882a593Smuzhiyun 		.channel = (_channel1), \
557*4882a593Smuzhiyun 		.channel2 = (_channel2), \
558*4882a593Smuzhiyun 		.address = (_address), \
559*4882a593Smuzhiyun 		.extend_name = (_extend_name), \
560*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
561*4882a593Smuzhiyun 			BIT(IIO_CHAN_INFO_OFFSET), \
562*4882a593Smuzhiyun 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
563*4882a593Smuzhiyun 		.info_mask_shared_by_type_available = (_mask_type_av), \
564*4882a593Smuzhiyun 		.info_mask_shared_by_all = _mask_all, \
565*4882a593Smuzhiyun 		.scan_index = (_si), \
566*4882a593Smuzhiyun 		.scan_type = { \
567*4882a593Smuzhiyun 			.sign = 'u', \
568*4882a593Smuzhiyun 			.realbits = (_bits), \
569*4882a593Smuzhiyun 			.storagebits = (_storagebits), \
570*4882a593Smuzhiyun 			.shift = (_shift), \
571*4882a593Smuzhiyun 			.endianness = IIO_BE, \
572*4882a593Smuzhiyun 		}, \
573*4882a593Smuzhiyun 	}
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun #define AD7793_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
576*4882a593Smuzhiyun 	_storagebits, _shift) \
577*4882a593Smuzhiyun 	__AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
578*4882a593Smuzhiyun 		_storagebits, _shift, NULL, IIO_VOLTAGE, \
579*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SCALE), \
580*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun #define AD7793_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
583*4882a593Smuzhiyun 	_storagebits, _shift) \
584*4882a593Smuzhiyun 	__AD7793_CHANNEL(_si, _channel, _channel, _address, _bits, \
585*4882a593Smuzhiyun 		_storagebits, _shift, "shorted", IIO_VOLTAGE, \
586*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SCALE), \
587*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun #define AD7793_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \
590*4882a593Smuzhiyun 	__AD7793_CHANNEL(_si, 0, -1, _address, _bits, \
591*4882a593Smuzhiyun 		_storagebits, _shift, NULL, IIO_TEMP, \
592*4882a593Smuzhiyun 		0, \
593*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun #define AD7793_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \
596*4882a593Smuzhiyun 	_shift) \
597*4882a593Smuzhiyun 	__AD7793_CHANNEL(_si, _channel, -1, _address, _bits, \
598*4882a593Smuzhiyun 		_storagebits, _shift, "supply", IIO_VOLTAGE, \
599*4882a593Smuzhiyun 		0, \
600*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun #define AD7797_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
603*4882a593Smuzhiyun 	_storagebits, _shift) \
604*4882a593Smuzhiyun 	__AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
605*4882a593Smuzhiyun 		_storagebits, _shift, NULL, IIO_VOLTAGE, \
606*4882a593Smuzhiyun 		0, \
607*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun #define AD7797_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
610*4882a593Smuzhiyun 	_storagebits, _shift) \
611*4882a593Smuzhiyun 	__AD7793_CHANNEL(_si, _channel, _channel, _address, _bits, \
612*4882a593Smuzhiyun 		_storagebits, _shift, "shorted", IIO_VOLTAGE, \
613*4882a593Smuzhiyun 		0, \
614*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SAMP_FREQ))
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun #define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
617*4882a593Smuzhiyun const struct iio_chan_spec _name##_channels[] = { \
618*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \
619*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \
620*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \
621*4882a593Smuzhiyun 	AD7793_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \
622*4882a593Smuzhiyun 	AD7793_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \
623*4882a593Smuzhiyun 	AD7793_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \
624*4882a593Smuzhiyun 	IIO_CHAN_SOFT_TIMESTAMP(6), \
625*4882a593Smuzhiyun }
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun #define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \
628*4882a593Smuzhiyun const struct iio_chan_spec _name##_channels[] = { \
629*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
630*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
631*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
632*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \
633*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \
634*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \
635*4882a593Smuzhiyun 	AD7793_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
636*4882a593Smuzhiyun 	AD7793_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \
637*4882a593Smuzhiyun 	AD7793_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
638*4882a593Smuzhiyun 	IIO_CHAN_SOFT_TIMESTAMP(9), \
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun #define DECLARE_AD7797_CHANNELS(_name, _b, _sb) \
642*4882a593Smuzhiyun const struct iio_chan_spec _name##_channels[] = { \
643*4882a593Smuzhiyun 	AD7797_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
644*4882a593Smuzhiyun 	AD7797_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
645*4882a593Smuzhiyun 	AD7793_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0), \
646*4882a593Smuzhiyun 	AD7793_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
647*4882a593Smuzhiyun 	IIO_CHAN_SOFT_TIMESTAMP(4), \
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
651*4882a593Smuzhiyun const struct iio_chan_spec _name##_channels[] = { \
652*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
653*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
654*4882a593Smuzhiyun 	AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
655*4882a593Smuzhiyun 	AD7793_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
656*4882a593Smuzhiyun 	AD7793_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
657*4882a593Smuzhiyun 	IIO_CHAN_SOFT_TIMESTAMP(5), \
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4);
661*4882a593Smuzhiyun static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0);
662*4882a593Smuzhiyun static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0);
663*4882a593Smuzhiyun static DECLARE_AD7795_CHANNELS(ad7794, 16, 32);
664*4882a593Smuzhiyun static DECLARE_AD7795_CHANNELS(ad7795, 24, 32);
665*4882a593Smuzhiyun static DECLARE_AD7797_CHANNELS(ad7796, 16, 16);
666*4882a593Smuzhiyun static DECLARE_AD7797_CHANNELS(ad7797, 24, 32);
667*4882a593Smuzhiyun static DECLARE_AD7799_CHANNELS(ad7798, 16, 16);
668*4882a593Smuzhiyun static DECLARE_AD7799_CHANNELS(ad7799, 24, 32);
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
671*4882a593Smuzhiyun 	[ID_AD7785] = {
672*4882a593Smuzhiyun 		.id = AD7785_ID,
673*4882a593Smuzhiyun 		.channels = ad7785_channels,
674*4882a593Smuzhiyun 		.num_channels = ARRAY_SIZE(ad7785_channels),
675*4882a593Smuzhiyun 		.iio_info = &ad7793_info,
676*4882a593Smuzhiyun 		.sample_freq_avail = ad7793_sample_freq_avail,
677*4882a593Smuzhiyun 		.flags = AD7793_FLAG_HAS_CLKSEL |
678*4882a593Smuzhiyun 			AD7793_FLAG_HAS_REFSEL |
679*4882a593Smuzhiyun 			AD7793_FLAG_HAS_VBIAS |
680*4882a593Smuzhiyun 			AD7793_HAS_EXITATION_CURRENT |
681*4882a593Smuzhiyun 			AD7793_FLAG_HAS_GAIN |
682*4882a593Smuzhiyun 			AD7793_FLAG_HAS_BUFFER,
683*4882a593Smuzhiyun 	},
684*4882a593Smuzhiyun 	[ID_AD7792] = {
685*4882a593Smuzhiyun 		.id = AD7792_ID,
686*4882a593Smuzhiyun 		.channels = ad7792_channels,
687*4882a593Smuzhiyun 		.num_channels = ARRAY_SIZE(ad7792_channels),
688*4882a593Smuzhiyun 		.iio_info = &ad7793_info,
689*4882a593Smuzhiyun 		.sample_freq_avail = ad7793_sample_freq_avail,
690*4882a593Smuzhiyun 		.flags = AD7793_FLAG_HAS_CLKSEL |
691*4882a593Smuzhiyun 			AD7793_FLAG_HAS_REFSEL |
692*4882a593Smuzhiyun 			AD7793_FLAG_HAS_VBIAS |
693*4882a593Smuzhiyun 			AD7793_HAS_EXITATION_CURRENT |
694*4882a593Smuzhiyun 			AD7793_FLAG_HAS_GAIN |
695*4882a593Smuzhiyun 			AD7793_FLAG_HAS_BUFFER,
696*4882a593Smuzhiyun 	},
697*4882a593Smuzhiyun 	[ID_AD7793] = {
698*4882a593Smuzhiyun 		.id = AD7793_ID,
699*4882a593Smuzhiyun 		.channels = ad7793_channels,
700*4882a593Smuzhiyun 		.num_channels = ARRAY_SIZE(ad7793_channels),
701*4882a593Smuzhiyun 		.iio_info = &ad7793_info,
702*4882a593Smuzhiyun 		.sample_freq_avail = ad7793_sample_freq_avail,
703*4882a593Smuzhiyun 		.flags = AD7793_FLAG_HAS_CLKSEL |
704*4882a593Smuzhiyun 			AD7793_FLAG_HAS_REFSEL |
705*4882a593Smuzhiyun 			AD7793_FLAG_HAS_VBIAS |
706*4882a593Smuzhiyun 			AD7793_HAS_EXITATION_CURRENT |
707*4882a593Smuzhiyun 			AD7793_FLAG_HAS_GAIN |
708*4882a593Smuzhiyun 			AD7793_FLAG_HAS_BUFFER,
709*4882a593Smuzhiyun 	},
710*4882a593Smuzhiyun 	[ID_AD7794] = {
711*4882a593Smuzhiyun 		.id = AD7794_ID,
712*4882a593Smuzhiyun 		.channels = ad7794_channels,
713*4882a593Smuzhiyun 		.num_channels = ARRAY_SIZE(ad7794_channels),
714*4882a593Smuzhiyun 		.iio_info = &ad7793_info,
715*4882a593Smuzhiyun 		.sample_freq_avail = ad7793_sample_freq_avail,
716*4882a593Smuzhiyun 		.flags = AD7793_FLAG_HAS_CLKSEL |
717*4882a593Smuzhiyun 			AD7793_FLAG_HAS_REFSEL |
718*4882a593Smuzhiyun 			AD7793_FLAG_HAS_VBIAS |
719*4882a593Smuzhiyun 			AD7793_HAS_EXITATION_CURRENT |
720*4882a593Smuzhiyun 			AD7793_FLAG_HAS_GAIN |
721*4882a593Smuzhiyun 			AD7793_FLAG_HAS_BUFFER,
722*4882a593Smuzhiyun 	},
723*4882a593Smuzhiyun 	[ID_AD7795] = {
724*4882a593Smuzhiyun 		.id = AD7795_ID,
725*4882a593Smuzhiyun 		.channels = ad7795_channels,
726*4882a593Smuzhiyun 		.num_channels = ARRAY_SIZE(ad7795_channels),
727*4882a593Smuzhiyun 		.iio_info = &ad7793_info,
728*4882a593Smuzhiyun 		.sample_freq_avail = ad7793_sample_freq_avail,
729*4882a593Smuzhiyun 		.flags = AD7793_FLAG_HAS_CLKSEL |
730*4882a593Smuzhiyun 			AD7793_FLAG_HAS_REFSEL |
731*4882a593Smuzhiyun 			AD7793_FLAG_HAS_VBIAS |
732*4882a593Smuzhiyun 			AD7793_HAS_EXITATION_CURRENT |
733*4882a593Smuzhiyun 			AD7793_FLAG_HAS_GAIN |
734*4882a593Smuzhiyun 			AD7793_FLAG_HAS_BUFFER,
735*4882a593Smuzhiyun 	},
736*4882a593Smuzhiyun 	[ID_AD7796] = {
737*4882a593Smuzhiyun 		.id = AD7796_ID,
738*4882a593Smuzhiyun 		.channels = ad7796_channels,
739*4882a593Smuzhiyun 		.num_channels = ARRAY_SIZE(ad7796_channels),
740*4882a593Smuzhiyun 		.iio_info = &ad7797_info,
741*4882a593Smuzhiyun 		.sample_freq_avail = ad7797_sample_freq_avail,
742*4882a593Smuzhiyun 		.flags = AD7793_FLAG_HAS_CLKSEL,
743*4882a593Smuzhiyun 	},
744*4882a593Smuzhiyun 	[ID_AD7797] = {
745*4882a593Smuzhiyun 		.id = AD7797_ID,
746*4882a593Smuzhiyun 		.channels = ad7797_channels,
747*4882a593Smuzhiyun 		.num_channels = ARRAY_SIZE(ad7797_channels),
748*4882a593Smuzhiyun 		.iio_info = &ad7797_info,
749*4882a593Smuzhiyun 		.sample_freq_avail = ad7797_sample_freq_avail,
750*4882a593Smuzhiyun 		.flags = AD7793_FLAG_HAS_CLKSEL,
751*4882a593Smuzhiyun 	},
752*4882a593Smuzhiyun 	[ID_AD7798] = {
753*4882a593Smuzhiyun 		.id = AD7798_ID,
754*4882a593Smuzhiyun 		.channels = ad7798_channels,
755*4882a593Smuzhiyun 		.num_channels = ARRAY_SIZE(ad7798_channels),
756*4882a593Smuzhiyun 		.iio_info = &ad7793_info,
757*4882a593Smuzhiyun 		.sample_freq_avail = ad7793_sample_freq_avail,
758*4882a593Smuzhiyun 		.flags = AD7793_FLAG_HAS_GAIN |
759*4882a593Smuzhiyun 			AD7793_FLAG_HAS_BUFFER,
760*4882a593Smuzhiyun 	},
761*4882a593Smuzhiyun 	[ID_AD7799] = {
762*4882a593Smuzhiyun 		.id = AD7799_ID,
763*4882a593Smuzhiyun 		.channels = ad7799_channels,
764*4882a593Smuzhiyun 		.num_channels = ARRAY_SIZE(ad7799_channels),
765*4882a593Smuzhiyun 		.iio_info = &ad7793_info,
766*4882a593Smuzhiyun 		.sample_freq_avail = ad7793_sample_freq_avail,
767*4882a593Smuzhiyun 		.flags = AD7793_FLAG_HAS_GAIN |
768*4882a593Smuzhiyun 			AD7793_FLAG_HAS_BUFFER,
769*4882a593Smuzhiyun 	},
770*4882a593Smuzhiyun };
771*4882a593Smuzhiyun 
ad7793_probe(struct spi_device * spi)772*4882a593Smuzhiyun static int ad7793_probe(struct spi_device *spi)
773*4882a593Smuzhiyun {
774*4882a593Smuzhiyun 	const struct ad7793_platform_data *pdata = spi->dev.platform_data;
775*4882a593Smuzhiyun 	struct ad7793_state *st;
776*4882a593Smuzhiyun 	struct iio_dev *indio_dev;
777*4882a593Smuzhiyun 	int ret, vref_mv = 0;
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 	if (!pdata) {
780*4882a593Smuzhiyun 		dev_err(&spi->dev, "no platform data?\n");
781*4882a593Smuzhiyun 		return -ENODEV;
782*4882a593Smuzhiyun 	}
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun 	if (!spi->irq) {
785*4882a593Smuzhiyun 		dev_err(&spi->dev, "no IRQ?\n");
786*4882a593Smuzhiyun 		return -ENODEV;
787*4882a593Smuzhiyun 	}
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
790*4882a593Smuzhiyun 	if (indio_dev == NULL)
791*4882a593Smuzhiyun 		return -ENOMEM;
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun 	st = iio_priv(indio_dev);
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun 	ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
796*4882a593Smuzhiyun 
797*4882a593Smuzhiyun 	if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
798*4882a593Smuzhiyun 		st->reg = devm_regulator_get(&spi->dev, "refin");
799*4882a593Smuzhiyun 		if (IS_ERR(st->reg))
800*4882a593Smuzhiyun 			return PTR_ERR(st->reg);
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 		ret = regulator_enable(st->reg);
803*4882a593Smuzhiyun 		if (ret)
804*4882a593Smuzhiyun 			return ret;
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun 		vref_mv = regulator_get_voltage(st->reg);
807*4882a593Smuzhiyun 		if (vref_mv < 0) {
808*4882a593Smuzhiyun 			ret = vref_mv;
809*4882a593Smuzhiyun 			goto error_disable_reg;
810*4882a593Smuzhiyun 		}
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 		vref_mv /= 1000;
813*4882a593Smuzhiyun 	} else {
814*4882a593Smuzhiyun 		vref_mv = 1170; /* Build-in ref */
815*4882a593Smuzhiyun 	}
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun 	st->chip_info =
818*4882a593Smuzhiyun 		&ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data];
819*4882a593Smuzhiyun 
820*4882a593Smuzhiyun 	spi_set_drvdata(spi, indio_dev);
821*4882a593Smuzhiyun 
822*4882a593Smuzhiyun 	indio_dev->name = spi_get_device_id(spi)->name;
823*4882a593Smuzhiyun 	indio_dev->modes = INDIO_DIRECT_MODE;
824*4882a593Smuzhiyun 	indio_dev->channels = st->chip_info->channels;
825*4882a593Smuzhiyun 	indio_dev->num_channels = st->chip_info->num_channels;
826*4882a593Smuzhiyun 	indio_dev->info = st->chip_info->iio_info;
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun 	ret = ad_sd_setup_buffer_and_trigger(indio_dev);
829*4882a593Smuzhiyun 	if (ret)
830*4882a593Smuzhiyun 		goto error_disable_reg;
831*4882a593Smuzhiyun 
832*4882a593Smuzhiyun 	ret = ad7793_setup(indio_dev, pdata, vref_mv);
833*4882a593Smuzhiyun 	if (ret)
834*4882a593Smuzhiyun 		goto error_remove_trigger;
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun 	ret = iio_device_register(indio_dev);
837*4882a593Smuzhiyun 	if (ret)
838*4882a593Smuzhiyun 		goto error_remove_trigger;
839*4882a593Smuzhiyun 
840*4882a593Smuzhiyun 	return 0;
841*4882a593Smuzhiyun 
842*4882a593Smuzhiyun error_remove_trigger:
843*4882a593Smuzhiyun 	ad_sd_cleanup_buffer_and_trigger(indio_dev);
844*4882a593Smuzhiyun error_disable_reg:
845*4882a593Smuzhiyun 	if (pdata->refsel != AD7793_REFSEL_INTERNAL)
846*4882a593Smuzhiyun 		regulator_disable(st->reg);
847*4882a593Smuzhiyun 
848*4882a593Smuzhiyun 	return ret;
849*4882a593Smuzhiyun }
850*4882a593Smuzhiyun 
ad7793_remove(struct spi_device * spi)851*4882a593Smuzhiyun static int ad7793_remove(struct spi_device *spi)
852*4882a593Smuzhiyun {
853*4882a593Smuzhiyun 	const struct ad7793_platform_data *pdata = spi->dev.platform_data;
854*4882a593Smuzhiyun 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
855*4882a593Smuzhiyun 	struct ad7793_state *st = iio_priv(indio_dev);
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun 	iio_device_unregister(indio_dev);
858*4882a593Smuzhiyun 	ad_sd_cleanup_buffer_and_trigger(indio_dev);
859*4882a593Smuzhiyun 
860*4882a593Smuzhiyun 	if (pdata->refsel != AD7793_REFSEL_INTERNAL)
861*4882a593Smuzhiyun 		regulator_disable(st->reg);
862*4882a593Smuzhiyun 
863*4882a593Smuzhiyun 	return 0;
864*4882a593Smuzhiyun }
865*4882a593Smuzhiyun 
866*4882a593Smuzhiyun static const struct spi_device_id ad7793_id[] = {
867*4882a593Smuzhiyun 	{"ad7785", ID_AD7785},
868*4882a593Smuzhiyun 	{"ad7792", ID_AD7792},
869*4882a593Smuzhiyun 	{"ad7793", ID_AD7793},
870*4882a593Smuzhiyun 	{"ad7794", ID_AD7794},
871*4882a593Smuzhiyun 	{"ad7795", ID_AD7795},
872*4882a593Smuzhiyun 	{"ad7796", ID_AD7796},
873*4882a593Smuzhiyun 	{"ad7797", ID_AD7797},
874*4882a593Smuzhiyun 	{"ad7798", ID_AD7798},
875*4882a593Smuzhiyun 	{"ad7799", ID_AD7799},
876*4882a593Smuzhiyun 	{}
877*4882a593Smuzhiyun };
878*4882a593Smuzhiyun MODULE_DEVICE_TABLE(spi, ad7793_id);
879*4882a593Smuzhiyun 
880*4882a593Smuzhiyun static struct spi_driver ad7793_driver = {
881*4882a593Smuzhiyun 	.driver = {
882*4882a593Smuzhiyun 		.name	= "ad7793",
883*4882a593Smuzhiyun 	},
884*4882a593Smuzhiyun 	.probe		= ad7793_probe,
885*4882a593Smuzhiyun 	.remove		= ad7793_remove,
886*4882a593Smuzhiyun 	.id_table	= ad7793_id,
887*4882a593Smuzhiyun };
888*4882a593Smuzhiyun module_spi_driver(ad7793_driver);
889*4882a593Smuzhiyun 
890*4882a593Smuzhiyun MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
891*4882a593Smuzhiyun MODULE_DESCRIPTION("Analog Devices AD7793 and similar ADCs");
892*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
893