xref: /linux/drivers/iio/adc/ad4030.c (revision c26f4fbd58375bd6ef74f95eb73d61762ad97c59)
10cb8b324SEsteban Blanc // SPDX-License-Identifier: GPL-2.0-only
20cb8b324SEsteban Blanc /*
30cb8b324SEsteban Blanc  * Analog Devices AD4030 and AD4630 ADC family driver.
40cb8b324SEsteban Blanc  *
50cb8b324SEsteban Blanc  * Copyright 2024 Analog Devices, Inc.
60cb8b324SEsteban Blanc  * Copyright 2024 BayLibre, SAS
70cb8b324SEsteban Blanc  *
80cb8b324SEsteban Blanc  * based on code from:
90cb8b324SEsteban Blanc  *	Analog Devices, Inc.
100cb8b324SEsteban Blanc  *	  Sergiu Cuciurean <sergiu.cuciurean@analog.com>
110cb8b324SEsteban Blanc  *	  Nuno Sa <nuno.sa@analog.com>
120cb8b324SEsteban Blanc  *	  Marcelo Schmitt <marcelo.schmitt@analog.com>
130cb8b324SEsteban Blanc  *	  Liviu Adace <liviu.adace@analog.com>
140cb8b324SEsteban Blanc  */
150cb8b324SEsteban Blanc 
160cb8b324SEsteban Blanc #include <linux/bitfield.h>
170cb8b324SEsteban Blanc #include <linux/clk.h>
180cb8b324SEsteban Blanc #include <linux/iio/iio.h>
190cb8b324SEsteban Blanc #include <linux/iio/trigger_consumer.h>
200cb8b324SEsteban Blanc #include <linux/iio/triggered_buffer.h>
210cb8b324SEsteban Blanc #include <linux/regmap.h>
220cb8b324SEsteban Blanc #include <linux/regulator/consumer.h>
230cb8b324SEsteban Blanc #include <linux/spi/spi.h>
240cb8b324SEsteban Blanc #include <linux/unaligned.h>
250cb8b324SEsteban Blanc #include <linux/units.h>
260cb8b324SEsteban Blanc 
270cb8b324SEsteban Blanc #define AD4030_REG_INTERFACE_CONFIG_A			0x00
280cb8b324SEsteban Blanc #define     AD4030_REG_INTERFACE_CONFIG_A_SW_RESET	(BIT(0) | BIT(7))
290cb8b324SEsteban Blanc #define AD4030_REG_INTERFACE_CONFIG_B			0x01
300cb8b324SEsteban Blanc #define AD4030_REG_DEVICE_CONFIG			0x02
310cb8b324SEsteban Blanc #define AD4030_REG_CHIP_TYPE				0x03
320cb8b324SEsteban Blanc #define AD4030_REG_PRODUCT_ID_L				0x04
330cb8b324SEsteban Blanc #define AD4030_REG_PRODUCT_ID_H				0x05
340cb8b324SEsteban Blanc #define AD4030_REG_CHIP_GRADE				0x06
350cb8b324SEsteban Blanc #define     AD4030_REG_CHIP_GRADE_AD4030_24_GRADE	0x10
36c8ed843cSEsteban Blanc #define     AD4030_REG_CHIP_GRADE_AD4630_16_GRADE	0x03
37c8ed843cSEsteban Blanc #define     AD4030_REG_CHIP_GRADE_AD4630_24_GRADE	0x00
38ec25cf6fSEsteban Blanc #define     AD4030_REG_CHIP_GRADE_AD4632_16_GRADE	0x05
39ec25cf6fSEsteban Blanc #define     AD4030_REG_CHIP_GRADE_AD4632_24_GRADE	0x02
400cb8b324SEsteban Blanc #define     AD4030_REG_CHIP_GRADE_MASK_CHIP_GRADE	GENMASK(7, 3)
410cb8b324SEsteban Blanc #define AD4030_REG_SCRATCH_PAD			0x0A
420cb8b324SEsteban Blanc #define AD4030_REG_SPI_REVISION			0x0B
430cb8b324SEsteban Blanc #define AD4030_REG_VENDOR_L			0x0C
440cb8b324SEsteban Blanc #define AD4030_REG_VENDOR_H			0x0D
450cb8b324SEsteban Blanc #define AD4030_REG_STREAM_MODE			0x0E
460cb8b324SEsteban Blanc #define AD4030_REG_INTERFACE_CONFIG_C		0x10
470cb8b324SEsteban Blanc #define AD4030_REG_INTERFACE_STATUS_A		0x11
480cb8b324SEsteban Blanc #define AD4030_REG_EXIT_CFG_MODE		0x14
490cb8b324SEsteban Blanc #define     AD4030_REG_EXIT_CFG_MODE_EXIT_MSK	BIT(0)
500cb8b324SEsteban Blanc #define AD4030_REG_AVG				0x15
510cb8b324SEsteban Blanc #define     AD4030_REG_AVG_MASK_AVG_SYNC	BIT(7)
520cb8b324SEsteban Blanc #define     AD4030_REG_AVG_MASK_AVG_VAL		GENMASK(4, 0)
530cb8b324SEsteban Blanc #define AD4030_REG_OFFSET_X0_0			0x16
540cb8b324SEsteban Blanc #define AD4030_REG_OFFSET_X0_1			0x17
550cb8b324SEsteban Blanc #define AD4030_REG_OFFSET_X0_2			0x18
560cb8b324SEsteban Blanc #define AD4030_REG_OFFSET_X1_0			0x19
570cb8b324SEsteban Blanc #define AD4030_REG_OFFSET_X1_1			0x1A
580cb8b324SEsteban Blanc #define AD4030_REG_OFFSET_X1_2			0x1B
590cb8b324SEsteban Blanc #define     AD4030_REG_OFFSET_BYTES_NB		3
600cb8b324SEsteban Blanc #define     AD4030_REG_OFFSET_CHAN(ch)		\
610cb8b324SEsteban Blanc 	(AD4030_REG_OFFSET_X0_2 + (AD4030_REG_OFFSET_BYTES_NB * (ch)))
620cb8b324SEsteban Blanc #define AD4030_REG_GAIN_X0_LSB			0x1C
630cb8b324SEsteban Blanc #define AD4030_REG_GAIN_X0_MSB			0x1D
640cb8b324SEsteban Blanc #define AD4030_REG_GAIN_X1_LSB			0x1E
650cb8b324SEsteban Blanc #define AD4030_REG_GAIN_X1_MSB			0x1F
660cb8b324SEsteban Blanc #define     AD4030_REG_GAIN_MAX_GAIN		1999970
670cb8b324SEsteban Blanc #define     AD4030_REG_GAIN_BYTES_NB		2
680cb8b324SEsteban Blanc #define     AD4030_REG_GAIN_CHAN(ch)		\
690cb8b324SEsteban Blanc 	(AD4030_REG_GAIN_X0_MSB + (AD4030_REG_GAIN_BYTES_NB * (ch)))
700cb8b324SEsteban Blanc #define AD4030_REG_MODES			0x20
710cb8b324SEsteban Blanc #define     AD4030_REG_MODES_MASK_OUT_DATA_MODE	GENMASK(2, 0)
720cb8b324SEsteban Blanc #define     AD4030_REG_MODES_MASK_LANE_MODE	GENMASK(7, 6)
730cb8b324SEsteban Blanc #define AD4030_REG_OSCILATOR			0x21
740cb8b324SEsteban Blanc #define AD4030_REG_IO				0x22
750cb8b324SEsteban Blanc #define     AD4030_REG_IO_MASK_IO2X		BIT(1)
760cb8b324SEsteban Blanc #define AD4030_REG_PAT0				0x23
770cb8b324SEsteban Blanc #define AD4030_REG_PAT1				0x24
780cb8b324SEsteban Blanc #define AD4030_REG_PAT2				0x25
790cb8b324SEsteban Blanc #define AD4030_REG_PAT3				0x26
800cb8b324SEsteban Blanc #define AD4030_REG_DIG_DIAG			0x34
810cb8b324SEsteban Blanc #define AD4030_REG_DIG_ERR			0x35
820cb8b324SEsteban Blanc 
830cb8b324SEsteban Blanc /* Sequence starting with "1 0 1" to enable reg access */
840cb8b324SEsteban Blanc #define AD4030_REG_ACCESS			0xA0
850cb8b324SEsteban Blanc 
860cb8b324SEsteban Blanc #define AD4030_MAX_IIO_SAMPLE_SIZE_BUFFERED	BITS_TO_BYTES(64)
870cb8b324SEsteban Blanc #define AD4030_MAX_HARDWARE_CHANNEL_NB		2
880cb8b324SEsteban Blanc #define AD4030_MAX_IIO_CHANNEL_NB		5
890cb8b324SEsteban Blanc #define AD4030_SINGLE_COMMON_BYTE_CHANNELS_MASK	0b10
90c8ed843cSEsteban Blanc #define AD4030_DUAL_COMMON_BYTE_CHANNELS_MASK	0b1100
910cb8b324SEsteban Blanc #define AD4030_GAIN_MIDLE_POINT			0x8000
920cb8b324SEsteban Blanc /*
930cb8b324SEsteban Blanc  * This accounts for 1 sample per channel plus one s64 for the timestamp,
940cb8b324SEsteban Blanc  * aligned on a s64 boundary
950cb8b324SEsteban Blanc  */
960cb8b324SEsteban Blanc #define AD4030_MAXIMUM_RX_BUFFER_SIZE			\
970cb8b324SEsteban Blanc 	(ALIGN(AD4030_MAX_IIO_SAMPLE_SIZE_BUFFERED *	\
980cb8b324SEsteban Blanc 	      AD4030_MAX_HARDWARE_CHANNEL_NB,		\
990cb8b324SEsteban Blanc 	      sizeof(s64)) + sizeof(s64))
1000cb8b324SEsteban Blanc 
1010cb8b324SEsteban Blanc #define AD4030_VREF_MIN_UV		(4096 * MILLI)
1020cb8b324SEsteban Blanc #define AD4030_VREF_MAX_UV		(5000 * MILLI)
1030cb8b324SEsteban Blanc #define AD4030_VIO_THRESHOLD_UV		(1400 * MILLI)
1040cb8b324SEsteban Blanc #define AD4030_SPI_MAX_XFER_LEN		8
1050cb8b324SEsteban Blanc #define AD4030_SPI_MAX_REG_XFER_SPEED	(80 * MEGA)
1060cb8b324SEsteban Blanc #define AD4030_TCNVH_NS			10
1070cb8b324SEsteban Blanc #define AD4030_TCNVL_NS			20
1080cb8b324SEsteban Blanc #define AD4030_TCYC_NS			500
1090cb8b324SEsteban Blanc #define AD4030_TCYC_ADJUSTED_NS		(AD4030_TCYC_NS - AD4030_TCNVL_NS)
1100cb8b324SEsteban Blanc #define AD4030_TRESET_PW_NS		50
111ec25cf6fSEsteban Blanc #define AD4632_TCYC_NS			2000
112ec25cf6fSEsteban Blanc #define AD4632_TCYC_ADJUSTED_NS		(AD4632_TCYC_NS - AD4030_TCNVL_NS)
113ec25cf6fSEsteban Blanc #define AD4030_TRESET_COM_DELAY_MS	750
1140cb8b324SEsteban Blanc 
1150cb8b324SEsteban Blanc enum ad4030_out_mode {
1160cb8b324SEsteban Blanc 	AD4030_OUT_DATA_MD_DIFF,
1170cb8b324SEsteban Blanc 	AD4030_OUT_DATA_MD_16_DIFF_8_COM,
1180cb8b324SEsteban Blanc 	AD4030_OUT_DATA_MD_24_DIFF_8_COM,
1190cb8b324SEsteban Blanc 	AD4030_OUT_DATA_MD_30_AVERAGED_DIFF,
1200cb8b324SEsteban Blanc 	AD4030_OUT_DATA_MD_32_PATTERN,
1210cb8b324SEsteban Blanc };
1220cb8b324SEsteban Blanc 
123949abd1cSEsteban Blanc enum {
124c8ed843cSEsteban Blanc 	AD4030_LANE_MD_1_PER_CH,
125c8ed843cSEsteban Blanc 	AD4030_LANE_MD_2_PER_CH,
126c8ed843cSEsteban Blanc 	AD4030_LANE_MD_4_PER_CH,
127c8ed843cSEsteban Blanc 	AD4030_LANE_MD_INTERLEAVED,
128c8ed843cSEsteban Blanc };
129c8ed843cSEsteban Blanc 
130c8ed843cSEsteban Blanc enum {
131949abd1cSEsteban Blanc 	AD4030_SCAN_TYPE_NORMAL,
132949abd1cSEsteban Blanc 	AD4030_SCAN_TYPE_AVG,
133949abd1cSEsteban Blanc };
134949abd1cSEsteban Blanc 
1350cb8b324SEsteban Blanc struct ad4030_chip_info {
1360cb8b324SEsteban Blanc 	const char *name;
1370cb8b324SEsteban Blanc 	const unsigned long *available_masks;
1380cb8b324SEsteban Blanc 	const struct iio_chan_spec channels[AD4030_MAX_IIO_CHANNEL_NB];
1390cb8b324SEsteban Blanc 	u8 grade;
1400cb8b324SEsteban Blanc 	u8 precision_bits;
1410cb8b324SEsteban Blanc 	/* Number of hardware channels */
1420cb8b324SEsteban Blanc 	int num_voltage_inputs;
1430cb8b324SEsteban Blanc 	unsigned int tcyc_ns;
1440cb8b324SEsteban Blanc };
1450cb8b324SEsteban Blanc 
1460cb8b324SEsteban Blanc struct ad4030_state {
1470cb8b324SEsteban Blanc 	struct spi_device *spi;
1480cb8b324SEsteban Blanc 	struct regmap *regmap;
1490cb8b324SEsteban Blanc 	const struct ad4030_chip_info *chip;
1500cb8b324SEsteban Blanc 	struct gpio_desc *cnv_gpio;
1510cb8b324SEsteban Blanc 	int vref_uv;
1520cb8b324SEsteban Blanc 	int vio_uv;
1530cb8b324SEsteban Blanc 	int offset_avail[3];
154949abd1cSEsteban Blanc 	unsigned int avg_log2;
1550cb8b324SEsteban Blanc 	enum ad4030_out_mode mode;
1560cb8b324SEsteban Blanc 
1570cb8b324SEsteban Blanc 	/*
1580cb8b324SEsteban Blanc 	 * DMA (thus cache coherency maintenance) requires the transfer buffers
1590cb8b324SEsteban Blanc 	 * to live in their own cache lines.
1600cb8b324SEsteban Blanc 	 */
1610cb8b324SEsteban Blanc 	u8 tx_data[AD4030_SPI_MAX_XFER_LEN] __aligned(IIO_DMA_MINALIGN);
1620cb8b324SEsteban Blanc 	union {
1630cb8b324SEsteban Blanc 		u8 raw[AD4030_MAXIMUM_RX_BUFFER_SIZE];
1640cb8b324SEsteban Blanc 		struct {
1650cb8b324SEsteban Blanc 			s32 diff;
1660cb8b324SEsteban Blanc 			u8 common;
167c8ed843cSEsteban Blanc 		} single;
168c8ed843cSEsteban Blanc 		struct {
169c8ed843cSEsteban Blanc 			s32 diff[2];
170c8ed843cSEsteban Blanc 			u8 common[2];
171c8ed843cSEsteban Blanc 		} dual;
1720cb8b324SEsteban Blanc 	} rx_data;
1730cb8b324SEsteban Blanc };
1740cb8b324SEsteban Blanc 
1750cb8b324SEsteban Blanc /*
1760cb8b324SEsteban Blanc  * For a chip with 2 hardware channel this will be used to create 2 common-mode
1770cb8b324SEsteban Blanc  * channels:
1780cb8b324SEsteban Blanc  * - voltage4
1790cb8b324SEsteban Blanc  * - voltage5
1800cb8b324SEsteban Blanc  * As the common-mode channels are after the differential ones, we compute the
1810cb8b324SEsteban Blanc  * channel number like this:
1820cb8b324SEsteban Blanc  * - _idx is the scan_index (the order in the output buffer)
1830cb8b324SEsteban Blanc  * - _ch is the hardware channel number this common-mode channel is related
1840cb8b324SEsteban Blanc  * - _idx - _ch gives us the number of channel in the chip
1850cb8b324SEsteban Blanc  * - _idx - _ch * 2 is the starting number of the common-mode channels, since
1860cb8b324SEsteban Blanc  *   for each differential channel there is a common-mode channel
1870cb8b324SEsteban Blanc  * - _idx - _ch * 2 + _ch gives the channel number for this specific common-mode
1880cb8b324SEsteban Blanc  *   channel
1890cb8b324SEsteban Blanc  */
1900cb8b324SEsteban Blanc #define AD4030_CHAN_CMO(_idx, _ch)  {					\
1910cb8b324SEsteban Blanc 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |			\
1920cb8b324SEsteban Blanc 		BIT(IIO_CHAN_INFO_SCALE),				\
1930cb8b324SEsteban Blanc 	.type = IIO_VOLTAGE,						\
1940cb8b324SEsteban Blanc 	.indexed = 1,							\
1950cb8b324SEsteban Blanc 	.address = (_ch),						\
1960cb8b324SEsteban Blanc 	.channel = ((_idx) - (_ch)) * 2 + (_ch),			\
1970cb8b324SEsteban Blanc 	.scan_index = (_idx),						\
1980cb8b324SEsteban Blanc 	.scan_type = {							\
1990cb8b324SEsteban Blanc 		.sign = 'u',						\
2000cb8b324SEsteban Blanc 		.storagebits = 8,					\
2010cb8b324SEsteban Blanc 		.realbits = 8,						\
2020cb8b324SEsteban Blanc 		.endianness = IIO_BE,					\
2030cb8b324SEsteban Blanc 	},								\
2040cb8b324SEsteban Blanc }
2050cb8b324SEsteban Blanc 
2060cb8b324SEsteban Blanc /*
2070cb8b324SEsteban Blanc  * For a chip with 2 hardware channel this will be used to create 2 differential
2080cb8b324SEsteban Blanc  * channels:
2090cb8b324SEsteban Blanc  * - voltage0-voltage1
2100cb8b324SEsteban Blanc  * - voltage2-voltage3
2110cb8b324SEsteban Blanc  */
212949abd1cSEsteban Blanc #define AD4030_CHAN_DIFF(_idx, _scan_type) {				\
213949abd1cSEsteban Blanc 	.info_mask_shared_by_all =					\
214949abd1cSEsteban Blanc 		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),			\
215949abd1cSEsteban Blanc 	.info_mask_shared_by_all_available =				\
216949abd1cSEsteban Blanc 		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),			\
2170cb8b324SEsteban Blanc 	.info_mask_separate = BIT(IIO_CHAN_INFO_SCALE) |		\
2180cb8b324SEsteban Blanc 		BIT(IIO_CHAN_INFO_CALIBSCALE) |				\
2190cb8b324SEsteban Blanc 		BIT(IIO_CHAN_INFO_CALIBBIAS) |				\
2200cb8b324SEsteban Blanc 		BIT(IIO_CHAN_INFO_RAW),					\
2210cb8b324SEsteban Blanc 	.info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBBIAS) |	\
2220cb8b324SEsteban Blanc 		BIT(IIO_CHAN_INFO_CALIBSCALE),				\
2230cb8b324SEsteban Blanc 	.type = IIO_VOLTAGE,						\
2240cb8b324SEsteban Blanc 	.indexed = 1,							\
2250cb8b324SEsteban Blanc 	.address = (_idx),						\
2260cb8b324SEsteban Blanc 	.channel = (_idx) * 2,						\
2270cb8b324SEsteban Blanc 	.channel2 = (_idx) * 2 + 1,					\
2280cb8b324SEsteban Blanc 	.scan_index = (_idx),						\
2290cb8b324SEsteban Blanc 	.differential = true,						\
230949abd1cSEsteban Blanc 	.has_ext_scan_type = 1,						\
231949abd1cSEsteban Blanc 	.ext_scan_type = _scan_type,					\
232949abd1cSEsteban Blanc 	.num_ext_scan_type = ARRAY_SIZE(_scan_type),			\
2330cb8b324SEsteban Blanc }
2340cb8b324SEsteban Blanc 
235949abd1cSEsteban Blanc static const int ad4030_average_modes[] = {
236949abd1cSEsteban Blanc 	1, 2, 4, 8, 16, 32, 64, 128,
237949abd1cSEsteban Blanc 	256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
238949abd1cSEsteban Blanc 	65536,
239949abd1cSEsteban Blanc };
240949abd1cSEsteban Blanc 
ad4030_enter_config_mode(struct ad4030_state * st)2410cb8b324SEsteban Blanc static int ad4030_enter_config_mode(struct ad4030_state *st)
2420cb8b324SEsteban Blanc {
2430cb8b324SEsteban Blanc 	st->tx_data[0] = AD4030_REG_ACCESS;
2440cb8b324SEsteban Blanc 
2450cb8b324SEsteban Blanc 	struct spi_transfer xfer = {
2460cb8b324SEsteban Blanc 		.tx_buf = st->tx_data,
2470cb8b324SEsteban Blanc 		.len = 1,
2480cb8b324SEsteban Blanc 		.speed_hz = AD4030_SPI_MAX_REG_XFER_SPEED,
2490cb8b324SEsteban Blanc 	};
2500cb8b324SEsteban Blanc 
2510cb8b324SEsteban Blanc 	return spi_sync_transfer(st->spi, &xfer, 1);
2520cb8b324SEsteban Blanc }
2530cb8b324SEsteban Blanc 
ad4030_exit_config_mode(struct ad4030_state * st)2540cb8b324SEsteban Blanc static int ad4030_exit_config_mode(struct ad4030_state *st)
2550cb8b324SEsteban Blanc {
2560cb8b324SEsteban Blanc 	st->tx_data[0] = 0;
2570cb8b324SEsteban Blanc 	st->tx_data[1] = AD4030_REG_EXIT_CFG_MODE;
2580cb8b324SEsteban Blanc 	st->tx_data[2] = AD4030_REG_EXIT_CFG_MODE_EXIT_MSK;
2590cb8b324SEsteban Blanc 
2600cb8b324SEsteban Blanc 	struct spi_transfer xfer = {
2610cb8b324SEsteban Blanc 		.tx_buf = st->tx_data,
2620cb8b324SEsteban Blanc 		.len = 3,
2630cb8b324SEsteban Blanc 		.speed_hz = AD4030_SPI_MAX_REG_XFER_SPEED,
2640cb8b324SEsteban Blanc 	};
2650cb8b324SEsteban Blanc 
2660cb8b324SEsteban Blanc 	return spi_sync_transfer(st->spi, &xfer, 1);
2670cb8b324SEsteban Blanc }
2680cb8b324SEsteban Blanc 
ad4030_spi_read(void * context,const void * reg,size_t reg_size,void * val,size_t val_size)2690cb8b324SEsteban Blanc static int ad4030_spi_read(void *context, const void *reg, size_t reg_size,
2700cb8b324SEsteban Blanc 			   void *val, size_t val_size)
2710cb8b324SEsteban Blanc {
2720cb8b324SEsteban Blanc 	int ret;
2730cb8b324SEsteban Blanc 	struct ad4030_state *st = context;
2740cb8b324SEsteban Blanc 	struct spi_transfer xfer = {
2750cb8b324SEsteban Blanc 		.tx_buf = st->tx_data,
2760cb8b324SEsteban Blanc 		.rx_buf = st->rx_data.raw,
2770cb8b324SEsteban Blanc 		.len = reg_size + val_size,
2780cb8b324SEsteban Blanc 		.speed_hz = AD4030_SPI_MAX_REG_XFER_SPEED,
2790cb8b324SEsteban Blanc 	};
2800cb8b324SEsteban Blanc 
2810cb8b324SEsteban Blanc 	if (xfer.len > sizeof(st->tx_data) ||
2820cb8b324SEsteban Blanc 	    xfer.len > sizeof(st->rx_data.raw))
2830cb8b324SEsteban Blanc 		return  -EINVAL;
2840cb8b324SEsteban Blanc 
2850cb8b324SEsteban Blanc 	ret = ad4030_enter_config_mode(st);
2860cb8b324SEsteban Blanc 	if (ret)
2870cb8b324SEsteban Blanc 		return ret;
2880cb8b324SEsteban Blanc 
2890cb8b324SEsteban Blanc 	memset(st->tx_data, 0, sizeof(st->tx_data));
2900cb8b324SEsteban Blanc 	memcpy(st->tx_data, reg, reg_size);
2910cb8b324SEsteban Blanc 
2920cb8b324SEsteban Blanc 	ret = spi_sync_transfer(st->spi, &xfer, 1);
2930cb8b324SEsteban Blanc 	if (ret)
2940cb8b324SEsteban Blanc 		return ret;
2950cb8b324SEsteban Blanc 
2960cb8b324SEsteban Blanc 	memcpy(val, &st->rx_data.raw[reg_size], val_size);
2970cb8b324SEsteban Blanc 
2980cb8b324SEsteban Blanc 	return ad4030_exit_config_mode(st);
2990cb8b324SEsteban Blanc }
3000cb8b324SEsteban Blanc 
ad4030_spi_write(void * context,const void * data,size_t count)3010cb8b324SEsteban Blanc static int ad4030_spi_write(void *context, const void *data, size_t count)
3020cb8b324SEsteban Blanc {
3030cb8b324SEsteban Blanc 	int ret;
3040cb8b324SEsteban Blanc 	struct ad4030_state *st = context;
3050cb8b324SEsteban Blanc 	bool is_reset = count >= 3 &&
3060cb8b324SEsteban Blanc 			((u8 *)data)[0] == 0 &&
3070cb8b324SEsteban Blanc 			((u8 *)data)[1] == 0 &&
3080cb8b324SEsteban Blanc 			((u8 *)data)[2] == 0x81;
3090cb8b324SEsteban Blanc 	struct spi_transfer xfer = {
3100cb8b324SEsteban Blanc 		.tx_buf = st->tx_data,
3110cb8b324SEsteban Blanc 		.len = count,
3120cb8b324SEsteban Blanc 		.speed_hz = AD4030_SPI_MAX_REG_XFER_SPEED,
3130cb8b324SEsteban Blanc 	};
3140cb8b324SEsteban Blanc 
3150cb8b324SEsteban Blanc 	if (count > sizeof(st->tx_data))
3160cb8b324SEsteban Blanc 		return  -EINVAL;
3170cb8b324SEsteban Blanc 
3180cb8b324SEsteban Blanc 	ret = ad4030_enter_config_mode(st);
3190cb8b324SEsteban Blanc 	if (ret)
3200cb8b324SEsteban Blanc 		return ret;
3210cb8b324SEsteban Blanc 
3220cb8b324SEsteban Blanc 	memcpy(st->tx_data, data, count);
3230cb8b324SEsteban Blanc 
3240cb8b324SEsteban Blanc 	ret = spi_sync_transfer(st->spi, &xfer, 1);
3250cb8b324SEsteban Blanc 	if (ret)
3260cb8b324SEsteban Blanc 		return ret;
3270cb8b324SEsteban Blanc 
3280cb8b324SEsteban Blanc 	/*
3290cb8b324SEsteban Blanc 	 * From datasheet: "After a [...] reset, no SPI commands or conversions
3300cb8b324SEsteban Blanc 	 * can be started for 750us"
3310cb8b324SEsteban Blanc 	 *  After a reset we are in conversion mode, no need to exit config mode
3320cb8b324SEsteban Blanc 	 */
3330cb8b324SEsteban Blanc 	if (is_reset) {
3340cb8b324SEsteban Blanc 		fsleep(750);
3350cb8b324SEsteban Blanc 		return 0;
3360cb8b324SEsteban Blanc 	}
3370cb8b324SEsteban Blanc 
3380cb8b324SEsteban Blanc 	return ad4030_exit_config_mode(st);
3390cb8b324SEsteban Blanc }
3400cb8b324SEsteban Blanc 
3410cb8b324SEsteban Blanc static const struct regmap_bus ad4030_regmap_bus = {
3420cb8b324SEsteban Blanc 	.read = ad4030_spi_read,
3430cb8b324SEsteban Blanc 	.write = ad4030_spi_write,
3440cb8b324SEsteban Blanc 	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
3450cb8b324SEsteban Blanc };
3460cb8b324SEsteban Blanc 
3470cb8b324SEsteban Blanc static const struct regmap_range ad4030_regmap_rd_range[] = {
3480cb8b324SEsteban Blanc 	regmap_reg_range(AD4030_REG_INTERFACE_CONFIG_A, AD4030_REG_CHIP_GRADE),
3490cb8b324SEsteban Blanc 	regmap_reg_range(AD4030_REG_SCRATCH_PAD, AD4030_REG_STREAM_MODE),
3500cb8b324SEsteban Blanc 	regmap_reg_range(AD4030_REG_INTERFACE_CONFIG_C,
3510cb8b324SEsteban Blanc 			 AD4030_REG_INTERFACE_STATUS_A),
3520cb8b324SEsteban Blanc 	regmap_reg_range(AD4030_REG_EXIT_CFG_MODE, AD4030_REG_PAT3),
3530cb8b324SEsteban Blanc 	regmap_reg_range(AD4030_REG_DIG_DIAG, AD4030_REG_DIG_ERR),
3540cb8b324SEsteban Blanc };
3550cb8b324SEsteban Blanc 
3560cb8b324SEsteban Blanc static const struct regmap_range ad4030_regmap_wr_range[] = {
3570cb8b324SEsteban Blanc 	regmap_reg_range(AD4030_REG_CHIP_TYPE, AD4030_REG_CHIP_GRADE),
3580cb8b324SEsteban Blanc 	regmap_reg_range(AD4030_REG_SPI_REVISION, AD4030_REG_VENDOR_H),
3590cb8b324SEsteban Blanc };
3600cb8b324SEsteban Blanc 
3610cb8b324SEsteban Blanc static const struct regmap_access_table ad4030_regmap_rd_table = {
3620cb8b324SEsteban Blanc 	.yes_ranges = ad4030_regmap_rd_range,
3630cb8b324SEsteban Blanc 	.n_yes_ranges = ARRAY_SIZE(ad4030_regmap_rd_range),
3640cb8b324SEsteban Blanc };
3650cb8b324SEsteban Blanc 
3660cb8b324SEsteban Blanc static const struct regmap_access_table ad4030_regmap_wr_table = {
3670cb8b324SEsteban Blanc 	.no_ranges = ad4030_regmap_wr_range,
3680cb8b324SEsteban Blanc 	.n_no_ranges = ARRAY_SIZE(ad4030_regmap_wr_range),
3690cb8b324SEsteban Blanc };
3700cb8b324SEsteban Blanc 
3710cb8b324SEsteban Blanc static const struct regmap_config ad4030_regmap_config = {
3720cb8b324SEsteban Blanc 	.reg_bits = 16,
3730cb8b324SEsteban Blanc 	.val_bits = 8,
3740cb8b324SEsteban Blanc 	.read_flag_mask = 0x80,
3750cb8b324SEsteban Blanc 	.rd_table = &ad4030_regmap_rd_table,
3760cb8b324SEsteban Blanc 	.wr_table = &ad4030_regmap_wr_table,
3770cb8b324SEsteban Blanc 	.max_register = AD4030_REG_DIG_ERR,
3780cb8b324SEsteban Blanc };
3790cb8b324SEsteban Blanc 
ad4030_get_chan_scale(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2)3800cb8b324SEsteban Blanc static int ad4030_get_chan_scale(struct iio_dev *indio_dev,
3810cb8b324SEsteban Blanc 				 struct iio_chan_spec const *chan,
3820cb8b324SEsteban Blanc 				 int *val,
3830cb8b324SEsteban Blanc 				 int *val2)
3840cb8b324SEsteban Blanc {
3850cb8b324SEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
386949abd1cSEsteban Blanc 	const struct iio_scan_type *scan_type;
3870cb8b324SEsteban Blanc 
388de67f28aSDavid Lechner 	scan_type = iio_get_current_scan_type(indio_dev, st->chip->channels);
389de67f28aSDavid Lechner 	if (IS_ERR(scan_type))
390de67f28aSDavid Lechner 		return PTR_ERR(scan_type);
391de67f28aSDavid Lechner 
392dc78e71dSDavid Lechner 	if (chan->differential)
3930cb8b324SEsteban Blanc 		*val = (st->vref_uv * 2) / MILLI;
394dc78e71dSDavid Lechner 	else
3950cb8b324SEsteban Blanc 		*val = st->vref_uv / MILLI;
396dc78e71dSDavid Lechner 
397de67f28aSDavid Lechner 	*val2 = scan_type->realbits;
398dc78e71dSDavid Lechner 
3990cb8b324SEsteban Blanc 	return IIO_VAL_FRACTIONAL_LOG2;
4000cb8b324SEsteban Blanc }
4010cb8b324SEsteban Blanc 
ad4030_get_chan_calibscale(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2)4020cb8b324SEsteban Blanc static int ad4030_get_chan_calibscale(struct iio_dev *indio_dev,
4030cb8b324SEsteban Blanc 				      struct iio_chan_spec const *chan,
4040cb8b324SEsteban Blanc 				      int *val,
4050cb8b324SEsteban Blanc 				      int *val2)
4060cb8b324SEsteban Blanc {
4070cb8b324SEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
4080cb8b324SEsteban Blanc 	u16 gain;
4090cb8b324SEsteban Blanc 	int ret;
4100cb8b324SEsteban Blanc 
4110cb8b324SEsteban Blanc 	ret = regmap_bulk_read(st->regmap, AD4030_REG_GAIN_CHAN(chan->address),
4120cb8b324SEsteban Blanc 			       st->rx_data.raw, AD4030_REG_GAIN_BYTES_NB);
4130cb8b324SEsteban Blanc 	if (ret)
4140cb8b324SEsteban Blanc 		return ret;
4150cb8b324SEsteban Blanc 
4160cb8b324SEsteban Blanc 	gain = get_unaligned_be16(st->rx_data.raw);
4170cb8b324SEsteban Blanc 
4180cb8b324SEsteban Blanc 	/* From datasheet: multiplied output = input × gain word/0x8000 */
4190cb8b324SEsteban Blanc 	*val = gain / AD4030_GAIN_MIDLE_POINT;
4200cb8b324SEsteban Blanc 	*val2 = mul_u64_u32_div(gain % AD4030_GAIN_MIDLE_POINT, NANO,
4210cb8b324SEsteban Blanc 				AD4030_GAIN_MIDLE_POINT);
4220cb8b324SEsteban Blanc 
4230cb8b324SEsteban Blanc 	return IIO_VAL_INT_PLUS_NANO;
4240cb8b324SEsteban Blanc }
4250cb8b324SEsteban Blanc 
4260cb8b324SEsteban Blanc /* Returns the offset where 1 LSB = (VREF/2^precision_bits - 1)/gain */
ad4030_get_chan_calibbias(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val)4270cb8b324SEsteban Blanc static int ad4030_get_chan_calibbias(struct iio_dev *indio_dev,
4280cb8b324SEsteban Blanc 				     struct iio_chan_spec const *chan,
4290cb8b324SEsteban Blanc 				     int *val)
4300cb8b324SEsteban Blanc {
4310cb8b324SEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
4320cb8b324SEsteban Blanc 	int ret;
4330cb8b324SEsteban Blanc 
4340cb8b324SEsteban Blanc 	ret = regmap_bulk_read(st->regmap,
4350cb8b324SEsteban Blanc 			       AD4030_REG_OFFSET_CHAN(chan->address),
4360cb8b324SEsteban Blanc 			       st->rx_data.raw, AD4030_REG_OFFSET_BYTES_NB);
4370cb8b324SEsteban Blanc 	if (ret)
4380cb8b324SEsteban Blanc 		return ret;
4390cb8b324SEsteban Blanc 
4400cb8b324SEsteban Blanc 	switch (st->chip->precision_bits) {
4410cb8b324SEsteban Blanc 	case 16:
4420cb8b324SEsteban Blanc 		*val = sign_extend32(get_unaligned_be16(st->rx_data.raw), 15);
4430cb8b324SEsteban Blanc 		return IIO_VAL_INT;
4440cb8b324SEsteban Blanc 
4450cb8b324SEsteban Blanc 	case 24:
4460cb8b324SEsteban Blanc 		*val = sign_extend32(get_unaligned_be24(st->rx_data.raw), 23);
4470cb8b324SEsteban Blanc 		return IIO_VAL_INT;
4480cb8b324SEsteban Blanc 
4490cb8b324SEsteban Blanc 	default:
4500cb8b324SEsteban Blanc 		return -EINVAL;
4510cb8b324SEsteban Blanc 	}
4520cb8b324SEsteban Blanc }
4530cb8b324SEsteban Blanc 
ad4030_set_chan_calibscale(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int gain_int,int gain_frac)4540cb8b324SEsteban Blanc static int ad4030_set_chan_calibscale(struct iio_dev *indio_dev,
4550cb8b324SEsteban Blanc 				      struct iio_chan_spec const *chan,
4560cb8b324SEsteban Blanc 				      int gain_int,
4570cb8b324SEsteban Blanc 				      int gain_frac)
4580cb8b324SEsteban Blanc {
4590cb8b324SEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
4600cb8b324SEsteban Blanc 	u64 gain;
4610cb8b324SEsteban Blanc 
4620cb8b324SEsteban Blanc 	if (gain_int < 0 || gain_frac < 0)
4630cb8b324SEsteban Blanc 		return -EINVAL;
4640cb8b324SEsteban Blanc 
4650cb8b324SEsteban Blanc 	gain = mul_u32_u32(gain_int, MICRO) + gain_frac;
4660cb8b324SEsteban Blanc 
4670cb8b324SEsteban Blanc 	if (gain > AD4030_REG_GAIN_MAX_GAIN)
4680cb8b324SEsteban Blanc 		return -EINVAL;
4690cb8b324SEsteban Blanc 
4700cb8b324SEsteban Blanc 	put_unaligned_be16(DIV_ROUND_CLOSEST_ULL(gain * AD4030_GAIN_MIDLE_POINT,
4710cb8b324SEsteban Blanc 						 MICRO),
4720cb8b324SEsteban Blanc 			   st->tx_data);
4730cb8b324SEsteban Blanc 
4740cb8b324SEsteban Blanc 	return regmap_bulk_write(st->regmap,
4750cb8b324SEsteban Blanc 				 AD4030_REG_GAIN_CHAN(chan->address),
4760cb8b324SEsteban Blanc 				 st->tx_data, AD4030_REG_GAIN_BYTES_NB);
4770cb8b324SEsteban Blanc }
4780cb8b324SEsteban Blanc 
ad4030_set_chan_calibbias(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int offset)4790cb8b324SEsteban Blanc static int ad4030_set_chan_calibbias(struct iio_dev *indio_dev,
4800cb8b324SEsteban Blanc 				     struct iio_chan_spec const *chan,
4810cb8b324SEsteban Blanc 				     int offset)
4820cb8b324SEsteban Blanc {
4830cb8b324SEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
4840cb8b324SEsteban Blanc 
4850cb8b324SEsteban Blanc 	if (offset < st->offset_avail[0] || offset > st->offset_avail[2])
4860cb8b324SEsteban Blanc 		return -EINVAL;
4870cb8b324SEsteban Blanc 
4880cb8b324SEsteban Blanc 	st->tx_data[2] = 0;
4890cb8b324SEsteban Blanc 
4900cb8b324SEsteban Blanc 	switch (st->chip->precision_bits) {
4910cb8b324SEsteban Blanc 	case 16:
4920cb8b324SEsteban Blanc 		put_unaligned_be16(offset, st->tx_data);
4930cb8b324SEsteban Blanc 		break;
4940cb8b324SEsteban Blanc 
4950cb8b324SEsteban Blanc 	case 24:
4960cb8b324SEsteban Blanc 		put_unaligned_be24(offset, st->tx_data);
4970cb8b324SEsteban Blanc 		break;
4980cb8b324SEsteban Blanc 
4990cb8b324SEsteban Blanc 	default:
5000cb8b324SEsteban Blanc 		return -EINVAL;
5010cb8b324SEsteban Blanc 	}
5020cb8b324SEsteban Blanc 
5030cb8b324SEsteban Blanc 	return regmap_bulk_write(st->regmap,
5040cb8b324SEsteban Blanc 				 AD4030_REG_OFFSET_CHAN(chan->address),
5050cb8b324SEsteban Blanc 				 st->tx_data, AD4030_REG_OFFSET_BYTES_NB);
5060cb8b324SEsteban Blanc }
5070cb8b324SEsteban Blanc 
ad4030_set_avg_frame_len(struct iio_dev * dev,int avg_val)508949abd1cSEsteban Blanc static int ad4030_set_avg_frame_len(struct iio_dev *dev, int avg_val)
509949abd1cSEsteban Blanc {
510949abd1cSEsteban Blanc 	struct ad4030_state *st = iio_priv(dev);
511949abd1cSEsteban Blanc 	unsigned int avg_log2 = ilog2(avg_val);
512949abd1cSEsteban Blanc 	unsigned int last_avg_idx = ARRAY_SIZE(ad4030_average_modes) - 1;
513949abd1cSEsteban Blanc 	int ret;
514949abd1cSEsteban Blanc 
515949abd1cSEsteban Blanc 	if (avg_val < 0 || avg_val > ad4030_average_modes[last_avg_idx])
516949abd1cSEsteban Blanc 		return -EINVAL;
517949abd1cSEsteban Blanc 
518949abd1cSEsteban Blanc 	ret = regmap_write(st->regmap, AD4030_REG_AVG,
519949abd1cSEsteban Blanc 			   AD4030_REG_AVG_MASK_AVG_SYNC |
520949abd1cSEsteban Blanc 			   FIELD_PREP(AD4030_REG_AVG_MASK_AVG_VAL, avg_log2));
521949abd1cSEsteban Blanc 	if (ret)
522949abd1cSEsteban Blanc 		return ret;
523949abd1cSEsteban Blanc 
524949abd1cSEsteban Blanc 	st->avg_log2 = avg_log2;
525949abd1cSEsteban Blanc 
526949abd1cSEsteban Blanc 	return 0;
527949abd1cSEsteban Blanc }
528949abd1cSEsteban Blanc 
ad4030_is_common_byte_asked(struct ad4030_state * st,unsigned int mask)5290cb8b324SEsteban Blanc static bool ad4030_is_common_byte_asked(struct ad4030_state *st,
5300cb8b324SEsteban Blanc 					unsigned int mask)
5310cb8b324SEsteban Blanc {
532c8ed843cSEsteban Blanc 	return mask & (st->chip->num_voltage_inputs == 1 ?
533c8ed843cSEsteban Blanc 		AD4030_SINGLE_COMMON_BYTE_CHANNELS_MASK :
534c8ed843cSEsteban Blanc 		AD4030_DUAL_COMMON_BYTE_CHANNELS_MASK);
5350cb8b324SEsteban Blanc }
5360cb8b324SEsteban Blanc 
ad4030_set_mode(struct iio_dev * indio_dev,unsigned long mask)5370cb8b324SEsteban Blanc static int ad4030_set_mode(struct iio_dev *indio_dev, unsigned long mask)
5380cb8b324SEsteban Blanc {
5390cb8b324SEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
5400cb8b324SEsteban Blanc 
541c8ed843cSEsteban Blanc 	if (st->avg_log2 > 0) {
542949abd1cSEsteban Blanc 		st->mode = AD4030_OUT_DATA_MD_30_AVERAGED_DIFF;
543c8ed843cSEsteban Blanc 	} else if (ad4030_is_common_byte_asked(st, mask)) {
544c8ed843cSEsteban Blanc 		switch (st->chip->precision_bits) {
545c8ed843cSEsteban Blanc 		case 16:
546c8ed843cSEsteban Blanc 			st->mode = AD4030_OUT_DATA_MD_16_DIFF_8_COM;
547c8ed843cSEsteban Blanc 			break;
548c8ed843cSEsteban Blanc 
549c8ed843cSEsteban Blanc 		case 24:
5500cb8b324SEsteban Blanc 			st->mode = AD4030_OUT_DATA_MD_24_DIFF_8_COM;
551c8ed843cSEsteban Blanc 			break;
552c8ed843cSEsteban Blanc 
553c8ed843cSEsteban Blanc 		default:
554c8ed843cSEsteban Blanc 			return -EINVAL;
555c8ed843cSEsteban Blanc 		}
556c8ed843cSEsteban Blanc 	} else {
5570cb8b324SEsteban Blanc 		st->mode = AD4030_OUT_DATA_MD_DIFF;
558c8ed843cSEsteban Blanc 	}
5590cb8b324SEsteban Blanc 
5600cb8b324SEsteban Blanc 	return regmap_update_bits(st->regmap, AD4030_REG_MODES,
5610cb8b324SEsteban Blanc 				  AD4030_REG_MODES_MASK_OUT_DATA_MODE,
5620cb8b324SEsteban Blanc 				  st->mode);
5630cb8b324SEsteban Blanc }
5640cb8b324SEsteban Blanc 
565c8ed843cSEsteban Blanc /*
566c8ed843cSEsteban Blanc  * Descramble 2 32bits numbers out of a 64bits. The bits are interleaved:
567c8ed843cSEsteban Blanc  * 1 bit for first number, 1 bit for the second, and so on...
568c8ed843cSEsteban Blanc  */
ad4030_extract_interleaved(u8 * src,u32 * ch0,u32 * ch1)569c8ed843cSEsteban Blanc static void ad4030_extract_interleaved(u8 *src, u32 *ch0, u32 *ch1)
570c8ed843cSEsteban Blanc {
571c8ed843cSEsteban Blanc 	u8 h0, h1, l0, l1;
572c8ed843cSEsteban Blanc 	u32 out0, out1;
573c8ed843cSEsteban Blanc 	u8 *out0_raw = (u8 *)&out0;
574c8ed843cSEsteban Blanc 	u8 *out1_raw = (u8 *)&out1;
575c8ed843cSEsteban Blanc 
576c8ed843cSEsteban Blanc 	for (int i = 0; i < 4; i++) {
577c8ed843cSEsteban Blanc 		h0 = src[i * 2];
578c8ed843cSEsteban Blanc 		l1 = src[i * 2 + 1];
579c8ed843cSEsteban Blanc 		h1 = h0 << 1;
580c8ed843cSEsteban Blanc 		l0 = l1 >> 1;
581c8ed843cSEsteban Blanc 
582c8ed843cSEsteban Blanc 		h0 &= 0xAA;
583c8ed843cSEsteban Blanc 		l0 &= 0x55;
584c8ed843cSEsteban Blanc 		h1 &= 0xAA;
585c8ed843cSEsteban Blanc 		l1 &= 0x55;
586c8ed843cSEsteban Blanc 
587c8ed843cSEsteban Blanc 		h0 = (h0 | h0 << 001) & 0xCC;
588c8ed843cSEsteban Blanc 		h1 = (h1 | h1 << 001) & 0xCC;
589c8ed843cSEsteban Blanc 		l0 = (l0 | l0 >> 001) & 0x33;
590c8ed843cSEsteban Blanc 		l1 = (l1 | l1 >> 001) & 0x33;
591c8ed843cSEsteban Blanc 		h0 = (h0 | h0 << 002) & 0xF0;
592c8ed843cSEsteban Blanc 		h1 = (h1 | h1 << 002) & 0xF0;
593c8ed843cSEsteban Blanc 		l0 = (l0 | l0 >> 002) & 0x0F;
594c8ed843cSEsteban Blanc 		l1 = (l1 | l1 >> 002) & 0x0F;
595c8ed843cSEsteban Blanc 
596c8ed843cSEsteban Blanc 		out0_raw[i] = h0 | l0;
597c8ed843cSEsteban Blanc 		out1_raw[i] = h1 | l1;
598c8ed843cSEsteban Blanc 	}
599c8ed843cSEsteban Blanc 
600c8ed843cSEsteban Blanc 	*ch0 = out0;
601c8ed843cSEsteban Blanc 	*ch1 = out1;
602c8ed843cSEsteban Blanc }
603c8ed843cSEsteban Blanc 
ad4030_conversion(struct iio_dev * indio_dev)6040cb8b324SEsteban Blanc static int ad4030_conversion(struct iio_dev *indio_dev)
6050cb8b324SEsteban Blanc {
6060cb8b324SEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
60715ffee89SDavid Lechner 	const struct iio_scan_type *scan_type;
60815ffee89SDavid Lechner 	unsigned char diff_realbytes, diff_storagebytes;
6090cb8b324SEsteban Blanc 	unsigned int bytes_to_read;
610949abd1cSEsteban Blanc 	unsigned long cnv_nb = BIT(st->avg_log2);
611949abd1cSEsteban Blanc 	unsigned int i;
6120cb8b324SEsteban Blanc 	int ret;
6130cb8b324SEsteban Blanc 
61415ffee89SDavid Lechner 	scan_type = iio_get_current_scan_type(indio_dev, st->chip->channels);
61515ffee89SDavid Lechner 	if (IS_ERR(scan_type))
61615ffee89SDavid Lechner 		return PTR_ERR(scan_type);
61715ffee89SDavid Lechner 
61815ffee89SDavid Lechner 	diff_realbytes = BITS_TO_BYTES(scan_type->realbits);
61915ffee89SDavid Lechner 	diff_storagebytes = BITS_TO_BYTES(scan_type->storagebits);
62015ffee89SDavid Lechner 
6210cb8b324SEsteban Blanc 	/* Number of bytes for one differential channel */
6220cb8b324SEsteban Blanc 	bytes_to_read = diff_realbytes;
6230cb8b324SEsteban Blanc 	/* Add one byte if we are using a differential + common byte mode */
6240cb8b324SEsteban Blanc 	bytes_to_read += (st->mode == AD4030_OUT_DATA_MD_24_DIFF_8_COM ||
6250cb8b324SEsteban Blanc 			st->mode == AD4030_OUT_DATA_MD_16_DIFF_8_COM) ? 1 : 0;
6260cb8b324SEsteban Blanc 	/* Mulitiply by the number of hardware channels */
6270cb8b324SEsteban Blanc 	bytes_to_read *= st->chip->num_voltage_inputs;
6280cb8b324SEsteban Blanc 
629949abd1cSEsteban Blanc 	for (i = 0; i < cnv_nb; i++) {
6300cb8b324SEsteban Blanc 		gpiod_set_value_cansleep(st->cnv_gpio, 1);
6310cb8b324SEsteban Blanc 		ndelay(AD4030_TCNVH_NS);
6320cb8b324SEsteban Blanc 		gpiod_set_value_cansleep(st->cnv_gpio, 0);
6330cb8b324SEsteban Blanc 		ndelay(st->chip->tcyc_ns);
634949abd1cSEsteban Blanc 	}
6350cb8b324SEsteban Blanc 
6360cb8b324SEsteban Blanc 	ret = spi_read(st->spi, st->rx_data.raw, bytes_to_read);
6370cb8b324SEsteban Blanc 	if (ret)
6380cb8b324SEsteban Blanc 		return ret;
6390cb8b324SEsteban Blanc 
640c8ed843cSEsteban Blanc 	if (st->chip->num_voltage_inputs == 2)
641c8ed843cSEsteban Blanc 		ad4030_extract_interleaved(st->rx_data.raw,
642c8ed843cSEsteban Blanc 					   &st->rx_data.dual.diff[0],
643c8ed843cSEsteban Blanc 					   &st->rx_data.dual.diff[1]);
644c8ed843cSEsteban Blanc 
6459415c8b5SDavid Lechner 	/*
6469415c8b5SDavid Lechner 	 * If no common mode voltage channel is enabled, we can use the raw
6479415c8b5SDavid Lechner 	 * data as is. Otherwise, we need to rearrange the data a bit to match
6489415c8b5SDavid Lechner 	 * the natural alignment of the IIO buffer.
6499415c8b5SDavid Lechner 	 */
6509415c8b5SDavid Lechner 
651c8ed843cSEsteban Blanc 	if (st->mode != AD4030_OUT_DATA_MD_16_DIFF_8_COM &&
652c8ed843cSEsteban Blanc 	    st->mode != AD4030_OUT_DATA_MD_24_DIFF_8_COM)
6530cb8b324SEsteban Blanc 		return 0;
6540cb8b324SEsteban Blanc 
655c8ed843cSEsteban Blanc 	if (st->chip->num_voltage_inputs == 1) {
656c8ed843cSEsteban Blanc 		st->rx_data.single.common = st->rx_data.raw[diff_realbytes];
657c8ed843cSEsteban Blanc 		return 0;
658c8ed843cSEsteban Blanc 	}
659c8ed843cSEsteban Blanc 
660c8ed843cSEsteban Blanc 	for (i = 0; i < st->chip->num_voltage_inputs; i++)
661c8ed843cSEsteban Blanc 		st->rx_data.dual.common[i] =
662c8ed843cSEsteban Blanc 			st->rx_data.raw[diff_storagebytes * i + diff_realbytes];
6630cb8b324SEsteban Blanc 
6640cb8b324SEsteban Blanc 	return 0;
6650cb8b324SEsteban Blanc }
6660cb8b324SEsteban Blanc 
ad4030_single_conversion(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int * val)6670cb8b324SEsteban Blanc static int ad4030_single_conversion(struct iio_dev *indio_dev,
6680cb8b324SEsteban Blanc 				    const struct iio_chan_spec *chan, int *val)
6690cb8b324SEsteban Blanc {
6700cb8b324SEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
6710cb8b324SEsteban Blanc 	int ret;
6720cb8b324SEsteban Blanc 
6730cb8b324SEsteban Blanc 	ret = ad4030_set_mode(indio_dev, BIT(chan->scan_index));
6740cb8b324SEsteban Blanc 	if (ret)
6750cb8b324SEsteban Blanc 		return ret;
6760cb8b324SEsteban Blanc 
6770cb8b324SEsteban Blanc 	ret = ad4030_conversion(indio_dev);
6780cb8b324SEsteban Blanc 	if (ret)
6790cb8b324SEsteban Blanc 		return ret;
6800cb8b324SEsteban Blanc 
6810cb8b324SEsteban Blanc 	if (chan->differential)
682c8ed843cSEsteban Blanc 		if (st->chip->num_voltage_inputs == 1)
683c8ed843cSEsteban Blanc 			*val = st->rx_data.single.diff;
6840cb8b324SEsteban Blanc 		else
685c8ed843cSEsteban Blanc 			*val = st->rx_data.dual.diff[chan->address];
686c8ed843cSEsteban Blanc 	else
687c8ed843cSEsteban Blanc 		if (st->chip->num_voltage_inputs == 1)
688c8ed843cSEsteban Blanc 			*val = st->rx_data.single.common;
689c8ed843cSEsteban Blanc 		else
690c8ed843cSEsteban Blanc 			*val = st->rx_data.dual.common[chan->address];
6910cb8b324SEsteban Blanc 
6920cb8b324SEsteban Blanc 	return IIO_VAL_INT;
6930cb8b324SEsteban Blanc }
6940cb8b324SEsteban Blanc 
ad4030_trigger_handler(int irq,void * p)6950cb8b324SEsteban Blanc static irqreturn_t ad4030_trigger_handler(int irq, void *p)
6960cb8b324SEsteban Blanc {
6970cb8b324SEsteban Blanc 	struct iio_poll_func *pf = p;
6980cb8b324SEsteban Blanc 	struct iio_dev *indio_dev = pf->indio_dev;
6990cb8b324SEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
7000cb8b324SEsteban Blanc 	int ret;
7010cb8b324SEsteban Blanc 
7020cb8b324SEsteban Blanc 	ret = ad4030_conversion(indio_dev);
7030cb8b324SEsteban Blanc 	if (ret)
7040cb8b324SEsteban Blanc 		goto out;
7050cb8b324SEsteban Blanc 
706*c65d3f3fSJonathan Cameron 	iio_push_to_buffers_with_ts(indio_dev, &st->rx_data, sizeof(st->rx_data),
7070cb8b324SEsteban Blanc 				    pf->timestamp);
7080cb8b324SEsteban Blanc 
7090cb8b324SEsteban Blanc out:
7100cb8b324SEsteban Blanc 	iio_trigger_notify_done(indio_dev->trig);
7110cb8b324SEsteban Blanc 
7120cb8b324SEsteban Blanc 	return IRQ_HANDLED;
7130cb8b324SEsteban Blanc }
7140cb8b324SEsteban Blanc 
7150cb8b324SEsteban Blanc static const int ad4030_gain_avail[3][2] = {
7160cb8b324SEsteban Blanc 	{ 0, 0 },
7170cb8b324SEsteban Blanc 	{ 0, 30518 },
7180cb8b324SEsteban Blanc 	{ 1, 999969482 },
7190cb8b324SEsteban Blanc };
7200cb8b324SEsteban Blanc 
ad4030_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * channel,const int ** vals,int * type,int * length,long mask)7210cb8b324SEsteban Blanc static int ad4030_read_avail(struct iio_dev *indio_dev,
7220cb8b324SEsteban Blanc 			     struct iio_chan_spec const *channel,
7230cb8b324SEsteban Blanc 			     const int **vals, int *type,
7240cb8b324SEsteban Blanc 			     int *length, long mask)
7250cb8b324SEsteban Blanc {
7260cb8b324SEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
7270cb8b324SEsteban Blanc 
7280cb8b324SEsteban Blanc 	switch (mask) {
7290cb8b324SEsteban Blanc 	case IIO_CHAN_INFO_CALIBBIAS:
7300cb8b324SEsteban Blanc 		*vals = st->offset_avail;
7310cb8b324SEsteban Blanc 		*type = IIO_VAL_INT;
7320cb8b324SEsteban Blanc 		return IIO_AVAIL_RANGE;
7330cb8b324SEsteban Blanc 
7340cb8b324SEsteban Blanc 	case IIO_CHAN_INFO_CALIBSCALE:
7350cb8b324SEsteban Blanc 		*vals = (void *)ad4030_gain_avail;
7360cb8b324SEsteban Blanc 		*type = IIO_VAL_INT_PLUS_NANO;
7370cb8b324SEsteban Blanc 		return IIO_AVAIL_RANGE;
7380cb8b324SEsteban Blanc 
739949abd1cSEsteban Blanc 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
740949abd1cSEsteban Blanc 		*vals = ad4030_average_modes;
741949abd1cSEsteban Blanc 		*type = IIO_VAL_INT;
742949abd1cSEsteban Blanc 		*length = ARRAY_SIZE(ad4030_average_modes);
743949abd1cSEsteban Blanc 		return IIO_AVAIL_LIST;
744949abd1cSEsteban Blanc 
7450cb8b324SEsteban Blanc 	default:
7460cb8b324SEsteban Blanc 		return -EINVAL;
7470cb8b324SEsteban Blanc 	}
7480cb8b324SEsteban Blanc }
7490cb8b324SEsteban Blanc 
ad4030_read_raw_dispatch(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long info)7500cb8b324SEsteban Blanc static int ad4030_read_raw_dispatch(struct iio_dev *indio_dev,
7510cb8b324SEsteban Blanc 				    struct iio_chan_spec const *chan, int *val,
7520cb8b324SEsteban Blanc 				    int *val2, long info)
7530cb8b324SEsteban Blanc {
754949abd1cSEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
755949abd1cSEsteban Blanc 
7560cb8b324SEsteban Blanc 	switch (info) {
7570cb8b324SEsteban Blanc 	case IIO_CHAN_INFO_RAW:
7580cb8b324SEsteban Blanc 		return ad4030_single_conversion(indio_dev, chan, val);
7590cb8b324SEsteban Blanc 
7600cb8b324SEsteban Blanc 	case IIO_CHAN_INFO_CALIBSCALE:
7610cb8b324SEsteban Blanc 		return ad4030_get_chan_calibscale(indio_dev, chan, val, val2);
7620cb8b324SEsteban Blanc 
7630cb8b324SEsteban Blanc 	case IIO_CHAN_INFO_CALIBBIAS:
7640cb8b324SEsteban Blanc 		return ad4030_get_chan_calibbias(indio_dev, chan, val);
7650cb8b324SEsteban Blanc 
766949abd1cSEsteban Blanc 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
767949abd1cSEsteban Blanc 		*val = BIT(st->avg_log2);
768949abd1cSEsteban Blanc 		return IIO_VAL_INT;
769949abd1cSEsteban Blanc 
7700cb8b324SEsteban Blanc 	default:
7710cb8b324SEsteban Blanc 		return -EINVAL;
7720cb8b324SEsteban Blanc 	}
7730cb8b324SEsteban Blanc }
7740cb8b324SEsteban Blanc 
ad4030_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long info)7750cb8b324SEsteban Blanc static int ad4030_read_raw(struct iio_dev *indio_dev,
7760cb8b324SEsteban Blanc 			   struct iio_chan_spec const *chan, int *val,
7770cb8b324SEsteban Blanc 			   int *val2, long info)
7780cb8b324SEsteban Blanc {
7790cb8b324SEsteban Blanc 	int ret;
7800cb8b324SEsteban Blanc 
7810cb8b324SEsteban Blanc 	if (info == IIO_CHAN_INFO_SCALE)
7820cb8b324SEsteban Blanc 		return ad4030_get_chan_scale(indio_dev, chan, val, val2);
7830cb8b324SEsteban Blanc 
7845ff6b02dSJonathan Cameron 	if (!iio_device_claim_direct(indio_dev))
7855ff6b02dSJonathan Cameron 		return -EBUSY;
7860cb8b324SEsteban Blanc 
7870cb8b324SEsteban Blanc 	ret = ad4030_read_raw_dispatch(indio_dev, chan, val, val2, info);
7880cb8b324SEsteban Blanc 
7895ff6b02dSJonathan Cameron 	iio_device_release_direct(indio_dev);
7900cb8b324SEsteban Blanc 
7910cb8b324SEsteban Blanc 	return ret;
7920cb8b324SEsteban Blanc }
7930cb8b324SEsteban Blanc 
ad4030_write_raw_dispatch(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long info)7940cb8b324SEsteban Blanc static int ad4030_write_raw_dispatch(struct iio_dev *indio_dev,
7950cb8b324SEsteban Blanc 				     struct iio_chan_spec const *chan, int val,
7960cb8b324SEsteban Blanc 				     int val2, long info)
7970cb8b324SEsteban Blanc {
7980cb8b324SEsteban Blanc 	switch (info) {
7990cb8b324SEsteban Blanc 	case IIO_CHAN_INFO_CALIBSCALE:
8000cb8b324SEsteban Blanc 		return ad4030_set_chan_calibscale(indio_dev, chan, val, val2);
8010cb8b324SEsteban Blanc 
8020cb8b324SEsteban Blanc 	case IIO_CHAN_INFO_CALIBBIAS:
8030cb8b324SEsteban Blanc 		if (val2 != 0)
8040cb8b324SEsteban Blanc 			return -EINVAL;
8050cb8b324SEsteban Blanc 		return ad4030_set_chan_calibbias(indio_dev, chan, val);
8060cb8b324SEsteban Blanc 
807949abd1cSEsteban Blanc 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
808949abd1cSEsteban Blanc 		return ad4030_set_avg_frame_len(indio_dev, val);
809949abd1cSEsteban Blanc 
8100cb8b324SEsteban Blanc 	default:
8110cb8b324SEsteban Blanc 		return -EINVAL;
8120cb8b324SEsteban Blanc 	}
8130cb8b324SEsteban Blanc }
8140cb8b324SEsteban Blanc 
ad4030_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long info)8150cb8b324SEsteban Blanc static int ad4030_write_raw(struct iio_dev *indio_dev,
8160cb8b324SEsteban Blanc 			    struct iio_chan_spec const *chan, int val,
8170cb8b324SEsteban Blanc 			    int val2, long info)
8180cb8b324SEsteban Blanc {
8190cb8b324SEsteban Blanc 	int ret;
8200cb8b324SEsteban Blanc 
8215ff6b02dSJonathan Cameron 	if (!iio_device_claim_direct(indio_dev))
8225ff6b02dSJonathan Cameron 		return -EBUSY;
8230cb8b324SEsteban Blanc 
8240cb8b324SEsteban Blanc 	ret = ad4030_write_raw_dispatch(indio_dev, chan, val, val2, info);
8250cb8b324SEsteban Blanc 
8265ff6b02dSJonathan Cameron 	iio_device_release_direct(indio_dev);
8270cb8b324SEsteban Blanc 
8280cb8b324SEsteban Blanc 	return ret;
8290cb8b324SEsteban Blanc }
8300cb8b324SEsteban Blanc 
ad4030_reg_access(struct iio_dev * indio_dev,unsigned int reg,unsigned int writeval,unsigned int * readval)8310cb8b324SEsteban Blanc static int ad4030_reg_access(struct iio_dev *indio_dev, unsigned int reg,
8320cb8b324SEsteban Blanc 			     unsigned int writeval, unsigned int *readval)
8330cb8b324SEsteban Blanc {
8340cb8b324SEsteban Blanc 	const struct ad4030_state *st = iio_priv(indio_dev);
8350cb8b324SEsteban Blanc 	int ret;
8360cb8b324SEsteban Blanc 
8375ff6b02dSJonathan Cameron 	if (!iio_device_claim_direct(indio_dev))
8385ff6b02dSJonathan Cameron 		return -EBUSY;
8390cb8b324SEsteban Blanc 
8400cb8b324SEsteban Blanc 	if (readval)
8410cb8b324SEsteban Blanc 		ret = regmap_read(st->regmap, reg, readval);
8420cb8b324SEsteban Blanc 	else
8430cb8b324SEsteban Blanc 		ret = regmap_write(st->regmap, reg, writeval);
8440cb8b324SEsteban Blanc 
8455ff6b02dSJonathan Cameron 	iio_device_release_direct(indio_dev);
8460cb8b324SEsteban Blanc 
8470cb8b324SEsteban Blanc 	return ret;
8480cb8b324SEsteban Blanc }
8490cb8b324SEsteban Blanc 
ad4030_read_label(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,char * label)8500cb8b324SEsteban Blanc static int ad4030_read_label(struct iio_dev *indio_dev,
8510cb8b324SEsteban Blanc 			     struct iio_chan_spec const *chan,
8520cb8b324SEsteban Blanc 			     char *label)
8530cb8b324SEsteban Blanc {
8540cb8b324SEsteban Blanc 	if (chan->differential)
8550cb8b324SEsteban Blanc 		return sprintf(label, "differential%lu\n", chan->address);
8560cb8b324SEsteban Blanc 	return sprintf(label, "common-mode%lu\n", chan->address);
8570cb8b324SEsteban Blanc }
8580cb8b324SEsteban Blanc 
ad4030_get_current_scan_type(const struct iio_dev * indio_dev,const struct iio_chan_spec * chan)859949abd1cSEsteban Blanc static int ad4030_get_current_scan_type(const struct iio_dev *indio_dev,
860949abd1cSEsteban Blanc 					const struct iio_chan_spec *chan)
861949abd1cSEsteban Blanc {
862949abd1cSEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
863949abd1cSEsteban Blanc 
864949abd1cSEsteban Blanc 	return st->avg_log2 ? AD4030_SCAN_TYPE_AVG : AD4030_SCAN_TYPE_NORMAL;
865949abd1cSEsteban Blanc }
866949abd1cSEsteban Blanc 
ad4030_update_scan_mode(struct iio_dev * indio_dev,const unsigned long * scan_mask)867efaa981eSDavid Lechner static int ad4030_update_scan_mode(struct iio_dev *indio_dev,
868efaa981eSDavid Lechner 				   const unsigned long *scan_mask)
869efaa981eSDavid Lechner {
870efaa981eSDavid Lechner 	return ad4030_set_mode(indio_dev, *scan_mask);
871efaa981eSDavid Lechner }
872efaa981eSDavid Lechner 
8730cb8b324SEsteban Blanc static const struct iio_info ad4030_iio_info = {
8740cb8b324SEsteban Blanc 	.read_avail = ad4030_read_avail,
8750cb8b324SEsteban Blanc 	.read_raw = ad4030_read_raw,
8760cb8b324SEsteban Blanc 	.write_raw = ad4030_write_raw,
8770cb8b324SEsteban Blanc 	.debugfs_reg_access = ad4030_reg_access,
8780cb8b324SEsteban Blanc 	.read_label = ad4030_read_label,
879949abd1cSEsteban Blanc 	.get_current_scan_type = ad4030_get_current_scan_type,
880efaa981eSDavid Lechner 	.update_scan_mode  = ad4030_update_scan_mode,
8810cb8b324SEsteban Blanc };
8820cb8b324SEsteban Blanc 
ad4030_validate_scan_mask(struct iio_dev * indio_dev,const unsigned long * scan_mask)883949abd1cSEsteban Blanc static bool ad4030_validate_scan_mask(struct iio_dev *indio_dev,
884949abd1cSEsteban Blanc 				      const unsigned long *scan_mask)
885949abd1cSEsteban Blanc {
886949abd1cSEsteban Blanc 	struct ad4030_state *st = iio_priv(indio_dev);
887949abd1cSEsteban Blanc 
888949abd1cSEsteban Blanc 	/* Asking for both common channels and averaging */
889949abd1cSEsteban Blanc 	if (st->avg_log2 && ad4030_is_common_byte_asked(st, *scan_mask))
890949abd1cSEsteban Blanc 		return false;
891949abd1cSEsteban Blanc 
892949abd1cSEsteban Blanc 	return true;
893949abd1cSEsteban Blanc }
894949abd1cSEsteban Blanc 
8950cb8b324SEsteban Blanc static const struct iio_buffer_setup_ops ad4030_buffer_setup_ops = {
896949abd1cSEsteban Blanc 	.validate_scan_mask = ad4030_validate_scan_mask,
8970cb8b324SEsteban Blanc };
8980cb8b324SEsteban Blanc 
ad4030_regulators_get(struct ad4030_state * st)8990cb8b324SEsteban Blanc static int ad4030_regulators_get(struct ad4030_state *st)
9000cb8b324SEsteban Blanc {
9010cb8b324SEsteban Blanc 	struct device *dev = &st->spi->dev;
9020cb8b324SEsteban Blanc 	static const char * const ids[] = { "vdd-5v", "vdd-1v8" };
9030cb8b324SEsteban Blanc 	int ret;
9040cb8b324SEsteban Blanc 
9050cb8b324SEsteban Blanc 	ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(ids), ids);
9060cb8b324SEsteban Blanc 	if (ret)
9070cb8b324SEsteban Blanc 		return dev_err_probe(dev, ret, "Failed to enable regulators\n");
9080cb8b324SEsteban Blanc 
9090cb8b324SEsteban Blanc 	st->vio_uv = devm_regulator_get_enable_read_voltage(dev, "vio");
9100cb8b324SEsteban Blanc 	if (st->vio_uv < 0)
9110cb8b324SEsteban Blanc 		return dev_err_probe(dev, st->vio_uv,
9120cb8b324SEsteban Blanc 				     "Failed to enable and read vio voltage\n");
9130cb8b324SEsteban Blanc 
9140cb8b324SEsteban Blanc 	st->vref_uv = devm_regulator_get_enable_read_voltage(dev, "ref");
9150cb8b324SEsteban Blanc 	if (st->vref_uv < 0) {
9160cb8b324SEsteban Blanc 		if (st->vref_uv != -ENODEV)
9170cb8b324SEsteban Blanc 			return dev_err_probe(dev, st->vref_uv,
9180cb8b324SEsteban Blanc 					     "Failed to read ref voltage\n");
9190cb8b324SEsteban Blanc 
9200cb8b324SEsteban Blanc 		/* if not using optional REF, the REFIN must be used */
9210cb8b324SEsteban Blanc 		st->vref_uv = devm_regulator_get_enable_read_voltage(dev,
9220cb8b324SEsteban Blanc 								     "refin");
9230cb8b324SEsteban Blanc 		if (st->vref_uv < 0)
9240cb8b324SEsteban Blanc 			return dev_err_probe(dev, st->vref_uv,
9250cb8b324SEsteban Blanc 					     "Failed to read refin voltage\n");
9260cb8b324SEsteban Blanc 	}
9270cb8b324SEsteban Blanc 
9280cb8b324SEsteban Blanc 	return 0;
9290cb8b324SEsteban Blanc }
9300cb8b324SEsteban Blanc 
ad4030_reset(struct ad4030_state * st)9310cb8b324SEsteban Blanc static int ad4030_reset(struct ad4030_state *st)
9320cb8b324SEsteban Blanc {
9330cb8b324SEsteban Blanc 	struct device *dev = &st->spi->dev;
9340cb8b324SEsteban Blanc 	struct gpio_desc *reset;
9350cb8b324SEsteban Blanc 
9360cb8b324SEsteban Blanc 	reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
9370cb8b324SEsteban Blanc 	if (IS_ERR(reset))
9380cb8b324SEsteban Blanc 		return dev_err_probe(dev, PTR_ERR(reset),
9390cb8b324SEsteban Blanc 				     "Failed to get reset GPIO\n");
9400cb8b324SEsteban Blanc 
9410cb8b324SEsteban Blanc 	if (reset) {
9420cb8b324SEsteban Blanc 		ndelay(50);
9430cb8b324SEsteban Blanc 		gpiod_set_value_cansleep(reset, 0);
9440cb8b324SEsteban Blanc 		return 0;
9450cb8b324SEsteban Blanc 	}
9460cb8b324SEsteban Blanc 
9470cb8b324SEsteban Blanc 	return regmap_write(st->regmap, AD4030_REG_INTERFACE_CONFIG_A,
9480cb8b324SEsteban Blanc 			   AD4030_REG_INTERFACE_CONFIG_A_SW_RESET);
9490cb8b324SEsteban Blanc }
9500cb8b324SEsteban Blanc 
ad4030_detect_chip_info(const struct ad4030_state * st)9510cb8b324SEsteban Blanc static int ad4030_detect_chip_info(const struct ad4030_state *st)
9520cb8b324SEsteban Blanc {
9530cb8b324SEsteban Blanc 	unsigned int grade;
9540cb8b324SEsteban Blanc 	int ret;
9550cb8b324SEsteban Blanc 
9560cb8b324SEsteban Blanc 	ret = regmap_read(st->regmap, AD4030_REG_CHIP_GRADE, &grade);
9570cb8b324SEsteban Blanc 	if (ret)
9580cb8b324SEsteban Blanc 		return ret;
9590cb8b324SEsteban Blanc 
9600cb8b324SEsteban Blanc 	grade = FIELD_GET(AD4030_REG_CHIP_GRADE_MASK_CHIP_GRADE, grade);
9610cb8b324SEsteban Blanc 	if (grade != st->chip->grade)
9620cb8b324SEsteban Blanc 		dev_warn(&st->spi->dev, "Unknown grade(0x%x) for %s\n", grade,
9630cb8b324SEsteban Blanc 			 st->chip->name);
9640cb8b324SEsteban Blanc 
9650cb8b324SEsteban Blanc 	return 0;
9660cb8b324SEsteban Blanc }
9670cb8b324SEsteban Blanc 
ad4030_config(struct ad4030_state * st)9680cb8b324SEsteban Blanc static int ad4030_config(struct ad4030_state *st)
9690cb8b324SEsteban Blanc {
970c8ed843cSEsteban Blanc 	int ret;
971c8ed843cSEsteban Blanc 	u8 reg_modes;
972c8ed843cSEsteban Blanc 
9730cb8b324SEsteban Blanc 	st->offset_avail[0] = (int)BIT(st->chip->precision_bits - 1) * -1;
9740cb8b324SEsteban Blanc 	st->offset_avail[1] = 1;
9750cb8b324SEsteban Blanc 	st->offset_avail[2] = BIT(st->chip->precision_bits - 1) - 1;
9760cb8b324SEsteban Blanc 
977c8ed843cSEsteban Blanc 	if (st->chip->num_voltage_inputs > 1)
978c8ed843cSEsteban Blanc 		reg_modes = FIELD_PREP(AD4030_REG_MODES_MASK_LANE_MODE,
979c8ed843cSEsteban Blanc 				       AD4030_LANE_MD_INTERLEAVED);
980c8ed843cSEsteban Blanc 	else
981c8ed843cSEsteban Blanc 		reg_modes = FIELD_PREP(AD4030_REG_MODES_MASK_LANE_MODE,
982c8ed843cSEsteban Blanc 				       AD4030_LANE_MD_1_PER_CH);
983c8ed843cSEsteban Blanc 
984c8ed843cSEsteban Blanc 	ret = regmap_write(st->regmap, AD4030_REG_MODES, reg_modes);
985c8ed843cSEsteban Blanc 	if (ret)
986c8ed843cSEsteban Blanc 		return ret;
987c8ed843cSEsteban Blanc 
9880cb8b324SEsteban Blanc 	if (st->vio_uv < AD4030_VIO_THRESHOLD_UV)
9890cb8b324SEsteban Blanc 		return regmap_write(st->regmap, AD4030_REG_IO,
9900cb8b324SEsteban Blanc 				    AD4030_REG_IO_MASK_IO2X);
9910cb8b324SEsteban Blanc 
9920cb8b324SEsteban Blanc 	return 0;
9930cb8b324SEsteban Blanc }
9940cb8b324SEsteban Blanc 
ad4030_probe(struct spi_device * spi)9950cb8b324SEsteban Blanc static int ad4030_probe(struct spi_device *spi)
9960cb8b324SEsteban Blanc {
9970cb8b324SEsteban Blanc 	struct device *dev = &spi->dev;
9980cb8b324SEsteban Blanc 	struct iio_dev *indio_dev;
9990cb8b324SEsteban Blanc 	struct ad4030_state *st;
10000cb8b324SEsteban Blanc 	int ret;
10010cb8b324SEsteban Blanc 
10020cb8b324SEsteban Blanc 	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
10030cb8b324SEsteban Blanc 	if (!indio_dev)
10040cb8b324SEsteban Blanc 		return -ENOMEM;
10050cb8b324SEsteban Blanc 
10060cb8b324SEsteban Blanc 	st = iio_priv(indio_dev);
10070cb8b324SEsteban Blanc 	st->spi = spi;
10080cb8b324SEsteban Blanc 
10090cb8b324SEsteban Blanc 	st->regmap = devm_regmap_init(dev, &ad4030_regmap_bus, st,
10100cb8b324SEsteban Blanc 				      &ad4030_regmap_config);
10110cb8b324SEsteban Blanc 	if (IS_ERR(st->regmap))
101215a007e7SDan Carpenter 		return dev_err_probe(dev, PTR_ERR(st->regmap),
10130cb8b324SEsteban Blanc 				     "Failed to initialize regmap\n");
10140cb8b324SEsteban Blanc 
10150cb8b324SEsteban Blanc 	st->chip = spi_get_device_match_data(spi);
10160cb8b324SEsteban Blanc 	if (!st->chip)
10170cb8b324SEsteban Blanc 		return -EINVAL;
10180cb8b324SEsteban Blanc 
10190cb8b324SEsteban Blanc 	ret = ad4030_regulators_get(st);
10200cb8b324SEsteban Blanc 	if (ret)
10210cb8b324SEsteban Blanc 		return ret;
10220cb8b324SEsteban Blanc 
10230cb8b324SEsteban Blanc 	/*
10240cb8b324SEsteban Blanc 	 * From datasheet: "Perform a reset no sooner than 3ms after the power
10250cb8b324SEsteban Blanc 	 * supplies are valid and stable"
10260cb8b324SEsteban Blanc 	 */
10270cb8b324SEsteban Blanc 	fsleep(3000);
10280cb8b324SEsteban Blanc 
10290cb8b324SEsteban Blanc 	ret = ad4030_reset(st);
10300cb8b324SEsteban Blanc 	if (ret)
10310cb8b324SEsteban Blanc 		return ret;
10320cb8b324SEsteban Blanc 
10330cb8b324SEsteban Blanc 	ret = ad4030_detect_chip_info(st);
10340cb8b324SEsteban Blanc 	if (ret)
10350cb8b324SEsteban Blanc 		return ret;
10360cb8b324SEsteban Blanc 
10370cb8b324SEsteban Blanc 	ret = ad4030_config(st);
10380cb8b324SEsteban Blanc 	if (ret)
10390cb8b324SEsteban Blanc 		return ret;
10400cb8b324SEsteban Blanc 
10410cb8b324SEsteban Blanc 	st->cnv_gpio = devm_gpiod_get(dev, "cnv", GPIOD_OUT_LOW);
10420cb8b324SEsteban Blanc 	if (IS_ERR(st->cnv_gpio))
10430cb8b324SEsteban Blanc 		return dev_err_probe(dev, PTR_ERR(st->cnv_gpio),
10440cb8b324SEsteban Blanc 				     "Failed to get cnv gpio\n");
10450cb8b324SEsteban Blanc 
10460cb8b324SEsteban Blanc 	/*
10470cb8b324SEsteban Blanc 	 * One hardware channel is split in two software channels when using
10480cb8b324SEsteban Blanc 	 * common byte mode. Add one more channel for the timestamp.
10490cb8b324SEsteban Blanc 	 */
10500cb8b324SEsteban Blanc 	indio_dev->num_channels = 2 * st->chip->num_voltage_inputs + 1;
10510cb8b324SEsteban Blanc 	indio_dev->name = st->chip->name;
10520cb8b324SEsteban Blanc 	indio_dev->modes = INDIO_DIRECT_MODE;
10530cb8b324SEsteban Blanc 	indio_dev->info = &ad4030_iio_info;
10540cb8b324SEsteban Blanc 	indio_dev->channels = st->chip->channels;
10550cb8b324SEsteban Blanc 	indio_dev->available_scan_masks = st->chip->available_masks;
10560cb8b324SEsteban Blanc 
10570cb8b324SEsteban Blanc 	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
10580cb8b324SEsteban Blanc 					      iio_pollfunc_store_time,
10590cb8b324SEsteban Blanc 					      ad4030_trigger_handler,
10600cb8b324SEsteban Blanc 					      &ad4030_buffer_setup_ops);
10610cb8b324SEsteban Blanc 	if (ret)
10620cb8b324SEsteban Blanc 		return dev_err_probe(dev, ret,
10630cb8b324SEsteban Blanc 				     "Failed to setup triggered buffer\n");
10640cb8b324SEsteban Blanc 
10650cb8b324SEsteban Blanc 	return devm_iio_device_register(dev, indio_dev);
10660cb8b324SEsteban Blanc }
10670cb8b324SEsteban Blanc 
10680cb8b324SEsteban Blanc static const unsigned long ad4030_channel_masks[] = {
10690cb8b324SEsteban Blanc 	/* Differential only */
10700cb8b324SEsteban Blanc 	BIT(0),
10710cb8b324SEsteban Blanc 	/* Differential and common-mode voltage */
10720cb8b324SEsteban Blanc 	GENMASK(1, 0),
10730cb8b324SEsteban Blanc 	0,
10740cb8b324SEsteban Blanc };
10750cb8b324SEsteban Blanc 
1076c8ed843cSEsteban Blanc static const unsigned long ad4630_channel_masks[] = {
1077c8ed843cSEsteban Blanc 	/* Differential only */
1078c8ed843cSEsteban Blanc 	BIT(1) | BIT(0),
1079c8ed843cSEsteban Blanc 	/* Differential with common byte */
1080c8ed843cSEsteban Blanc 	GENMASK(3, 0),
1081c8ed843cSEsteban Blanc 	0,
1082c8ed843cSEsteban Blanc };
1083c8ed843cSEsteban Blanc 
1084949abd1cSEsteban Blanc static const struct iio_scan_type ad4030_24_scan_types[] = {
1085949abd1cSEsteban Blanc 	[AD4030_SCAN_TYPE_NORMAL] = {
1086949abd1cSEsteban Blanc 		.sign = 's',
1087949abd1cSEsteban Blanc 		.storagebits = 32,
1088949abd1cSEsteban Blanc 		.realbits = 24,
1089949abd1cSEsteban Blanc 		.shift = 8,
1090949abd1cSEsteban Blanc 		.endianness = IIO_BE,
1091949abd1cSEsteban Blanc 	},
1092949abd1cSEsteban Blanc 	[AD4030_SCAN_TYPE_AVG] = {
1093949abd1cSEsteban Blanc 		.sign = 's',
1094949abd1cSEsteban Blanc 		.storagebits = 32,
1095949abd1cSEsteban Blanc 		.realbits = 30,
1096949abd1cSEsteban Blanc 		.shift = 2,
1097949abd1cSEsteban Blanc 		.endianness = IIO_BE,
1098949abd1cSEsteban Blanc 	},
1099949abd1cSEsteban Blanc };
1100949abd1cSEsteban Blanc 
1101c8ed843cSEsteban Blanc static const struct iio_scan_type ad4030_16_scan_types[] = {
1102c8ed843cSEsteban Blanc 	[AD4030_SCAN_TYPE_NORMAL] = {
1103c8ed843cSEsteban Blanc 		.sign = 's',
1104c8ed843cSEsteban Blanc 		.storagebits = 32,
1105c8ed843cSEsteban Blanc 		.realbits = 16,
1106c8ed843cSEsteban Blanc 		.shift = 16,
1107c8ed843cSEsteban Blanc 		.endianness = IIO_BE,
1108c8ed843cSEsteban Blanc 	},
1109c8ed843cSEsteban Blanc 	[AD4030_SCAN_TYPE_AVG] = {
1110c8ed843cSEsteban Blanc 		.sign = 's',
1111c8ed843cSEsteban Blanc 		.storagebits = 32,
1112c8ed843cSEsteban Blanc 		.realbits = 30,
1113c8ed843cSEsteban Blanc 		.shift = 2,
1114c8ed843cSEsteban Blanc 		.endianness = IIO_BE,
1115c8ed843cSEsteban Blanc 	}
1116c8ed843cSEsteban Blanc };
1117c8ed843cSEsteban Blanc 
11180cb8b324SEsteban Blanc static const struct ad4030_chip_info ad4030_24_chip_info = {
11190cb8b324SEsteban Blanc 	.name = "ad4030-24",
11200cb8b324SEsteban Blanc 	.available_masks = ad4030_channel_masks,
11210cb8b324SEsteban Blanc 	.channels = {
1122949abd1cSEsteban Blanc 		AD4030_CHAN_DIFF(0, ad4030_24_scan_types),
11230cb8b324SEsteban Blanc 		AD4030_CHAN_CMO(1, 0),
11240cb8b324SEsteban Blanc 		IIO_CHAN_SOFT_TIMESTAMP(2),
11250cb8b324SEsteban Blanc 	},
11260cb8b324SEsteban Blanc 	.grade = AD4030_REG_CHIP_GRADE_AD4030_24_GRADE,
11270cb8b324SEsteban Blanc 	.precision_bits = 24,
11280cb8b324SEsteban Blanc 	.num_voltage_inputs = 1,
11290cb8b324SEsteban Blanc 	.tcyc_ns = AD4030_TCYC_ADJUSTED_NS,
11300cb8b324SEsteban Blanc };
11310cb8b324SEsteban Blanc 
1132c8ed843cSEsteban Blanc static const struct ad4030_chip_info ad4630_16_chip_info = {
1133c8ed843cSEsteban Blanc 	.name = "ad4630-16",
1134c8ed843cSEsteban Blanc 	.available_masks = ad4630_channel_masks,
1135c8ed843cSEsteban Blanc 	.channels = {
1136c8ed843cSEsteban Blanc 		AD4030_CHAN_DIFF(0, ad4030_16_scan_types),
1137c8ed843cSEsteban Blanc 		AD4030_CHAN_DIFF(1, ad4030_16_scan_types),
1138c8ed843cSEsteban Blanc 		AD4030_CHAN_CMO(2, 0),
1139c8ed843cSEsteban Blanc 		AD4030_CHAN_CMO(3, 1),
1140c8ed843cSEsteban Blanc 		IIO_CHAN_SOFT_TIMESTAMP(4),
1141c8ed843cSEsteban Blanc 	},
1142c8ed843cSEsteban Blanc 	.grade = AD4030_REG_CHIP_GRADE_AD4630_16_GRADE,
1143c8ed843cSEsteban Blanc 	.precision_bits = 16,
1144c8ed843cSEsteban Blanc 	.num_voltage_inputs = 2,
1145c8ed843cSEsteban Blanc 	.tcyc_ns = AD4030_TCYC_ADJUSTED_NS,
1146c8ed843cSEsteban Blanc };
1147c8ed843cSEsteban Blanc 
1148c8ed843cSEsteban Blanc static const struct ad4030_chip_info ad4630_24_chip_info = {
1149c8ed843cSEsteban Blanc 	.name = "ad4630-24",
1150c8ed843cSEsteban Blanc 	.available_masks = ad4630_channel_masks,
1151c8ed843cSEsteban Blanc 	.channels = {
1152c8ed843cSEsteban Blanc 		AD4030_CHAN_DIFF(0, ad4030_24_scan_types),
1153c8ed843cSEsteban Blanc 		AD4030_CHAN_DIFF(1, ad4030_24_scan_types),
1154c8ed843cSEsteban Blanc 		AD4030_CHAN_CMO(2, 0),
1155c8ed843cSEsteban Blanc 		AD4030_CHAN_CMO(3, 1),
1156c8ed843cSEsteban Blanc 		IIO_CHAN_SOFT_TIMESTAMP(4),
1157c8ed843cSEsteban Blanc 	},
1158c8ed843cSEsteban Blanc 	.grade = AD4030_REG_CHIP_GRADE_AD4630_24_GRADE,
1159c8ed843cSEsteban Blanc 	.precision_bits = 24,
1160c8ed843cSEsteban Blanc 	.num_voltage_inputs = 2,
1161c8ed843cSEsteban Blanc 	.tcyc_ns = AD4030_TCYC_ADJUSTED_NS,
1162c8ed843cSEsteban Blanc };
1163c8ed843cSEsteban Blanc 
1164ec25cf6fSEsteban Blanc static const struct ad4030_chip_info ad4632_16_chip_info = {
1165ec25cf6fSEsteban Blanc 	.name = "ad4632-16",
1166ec25cf6fSEsteban Blanc 	.available_masks = ad4630_channel_masks,
1167ec25cf6fSEsteban Blanc 	.channels = {
1168ec25cf6fSEsteban Blanc 		AD4030_CHAN_DIFF(0, ad4030_16_scan_types),
1169ec25cf6fSEsteban Blanc 		AD4030_CHAN_DIFF(1, ad4030_16_scan_types),
1170ec25cf6fSEsteban Blanc 		AD4030_CHAN_CMO(2, 0),
1171ec25cf6fSEsteban Blanc 		AD4030_CHAN_CMO(3, 1),
1172ec25cf6fSEsteban Blanc 		IIO_CHAN_SOFT_TIMESTAMP(4),
1173ec25cf6fSEsteban Blanc 	},
1174ec25cf6fSEsteban Blanc 	.grade = AD4030_REG_CHIP_GRADE_AD4632_16_GRADE,
1175ec25cf6fSEsteban Blanc 	.precision_bits = 16,
1176ec25cf6fSEsteban Blanc 	.num_voltage_inputs = 2,
1177ec25cf6fSEsteban Blanc 	.tcyc_ns = AD4632_TCYC_ADJUSTED_NS,
1178ec25cf6fSEsteban Blanc };
1179ec25cf6fSEsteban Blanc 
1180ec25cf6fSEsteban Blanc static const struct ad4030_chip_info ad4632_24_chip_info = {
1181ec25cf6fSEsteban Blanc 	.name = "ad4632-24",
1182ec25cf6fSEsteban Blanc 	.available_masks = ad4630_channel_masks,
1183ec25cf6fSEsteban Blanc 	.channels = {
1184ec25cf6fSEsteban Blanc 		AD4030_CHAN_DIFF(0, ad4030_24_scan_types),
1185ec25cf6fSEsteban Blanc 		AD4030_CHAN_DIFF(1, ad4030_24_scan_types),
1186ec25cf6fSEsteban Blanc 		AD4030_CHAN_CMO(2, 0),
1187ec25cf6fSEsteban Blanc 		AD4030_CHAN_CMO(3, 1),
1188ec25cf6fSEsteban Blanc 		IIO_CHAN_SOFT_TIMESTAMP(4),
1189ec25cf6fSEsteban Blanc 	},
1190ec25cf6fSEsteban Blanc 	.grade = AD4030_REG_CHIP_GRADE_AD4632_24_GRADE,
1191ec25cf6fSEsteban Blanc 	.precision_bits = 24,
1192ec25cf6fSEsteban Blanc 	.num_voltage_inputs = 2,
1193ec25cf6fSEsteban Blanc 	.tcyc_ns = AD4632_TCYC_ADJUSTED_NS,
1194ec25cf6fSEsteban Blanc };
1195ec25cf6fSEsteban Blanc 
11960cb8b324SEsteban Blanc static const struct spi_device_id ad4030_id_table[] = {
11970cb8b324SEsteban Blanc 	{ "ad4030-24", (kernel_ulong_t)&ad4030_24_chip_info },
1198c8ed843cSEsteban Blanc 	{ "ad4630-16", (kernel_ulong_t)&ad4630_16_chip_info },
1199c8ed843cSEsteban Blanc 	{ "ad4630-24", (kernel_ulong_t)&ad4630_24_chip_info },
1200ec25cf6fSEsteban Blanc 	{ "ad4632-16", (kernel_ulong_t)&ad4632_16_chip_info },
1201ec25cf6fSEsteban Blanc 	{ "ad4632-24", (kernel_ulong_t)&ad4632_24_chip_info },
12020cb8b324SEsteban Blanc 	{ }
12030cb8b324SEsteban Blanc };
12040cb8b324SEsteban Blanc MODULE_DEVICE_TABLE(spi, ad4030_id_table);
12050cb8b324SEsteban Blanc 
12060cb8b324SEsteban Blanc static const struct of_device_id ad4030_of_match[] = {
12070cb8b324SEsteban Blanc 	{ .compatible = "adi,ad4030-24", .data = &ad4030_24_chip_info },
1208c8ed843cSEsteban Blanc 	{ .compatible = "adi,ad4630-16", .data = &ad4630_16_chip_info },
1209c8ed843cSEsteban Blanc 	{ .compatible = "adi,ad4630-24", .data = &ad4630_24_chip_info },
1210ec25cf6fSEsteban Blanc 	{ .compatible = "adi,ad4632-16", .data = &ad4632_16_chip_info },
1211ec25cf6fSEsteban Blanc 	{ .compatible = "adi,ad4632-24", .data = &ad4632_24_chip_info },
12120cb8b324SEsteban Blanc 	{ }
12130cb8b324SEsteban Blanc };
12140cb8b324SEsteban Blanc MODULE_DEVICE_TABLE(of, ad4030_of_match);
12150cb8b324SEsteban Blanc 
12160cb8b324SEsteban Blanc static struct spi_driver ad4030_driver = {
12170cb8b324SEsteban Blanc 	.driver = {
12180cb8b324SEsteban Blanc 		.name = "ad4030",
12190cb8b324SEsteban Blanc 		.of_match_table = ad4030_of_match,
12200cb8b324SEsteban Blanc 	},
12210cb8b324SEsteban Blanc 	.probe = ad4030_probe,
12220cb8b324SEsteban Blanc 	.id_table = ad4030_id_table,
12230cb8b324SEsteban Blanc };
12240cb8b324SEsteban Blanc module_spi_driver(ad4030_driver);
12250cb8b324SEsteban Blanc 
12260cb8b324SEsteban Blanc MODULE_AUTHOR("Esteban Blanc <eblanc@baylibre.com>");
12270cb8b324SEsteban Blanc MODULE_DESCRIPTION("Analog Devices AD4630 ADC family driver");
12280cb8b324SEsteban Blanc MODULE_LICENSE("GPL");
1229