xref: /linux/drivers/iio/adc/ad4851.c (revision c26f4fbd58375bd6ef74f95eb73d61762ad97c59)
16250803fSAntoniu Miclaus // SPDX-License-Identifier: GPL-2.0-only
26250803fSAntoniu Miclaus /*
36250803fSAntoniu Miclaus  * Analog Devices AD4851 DAS driver
46250803fSAntoniu Miclaus  *
56250803fSAntoniu Miclaus  * Copyright 2024 Analog Devices Inc.
66250803fSAntoniu Miclaus  */
76250803fSAntoniu Miclaus 
86250803fSAntoniu Miclaus #include <linux/array_size.h>
96250803fSAntoniu Miclaus #include <linux/bitfield.h>
106250803fSAntoniu Miclaus #include <linux/bits.h>
116250803fSAntoniu Miclaus #include <linux/delay.h>
126250803fSAntoniu Miclaus #include <linux/device.h>
136250803fSAntoniu Miclaus #include <linux/err.h>
146250803fSAntoniu Miclaus #include <linux/minmax.h>
156250803fSAntoniu Miclaus #include <linux/mod_devicetable.h>
166250803fSAntoniu Miclaus #include <linux/module.h>
176250803fSAntoniu Miclaus #include <linux/mutex.h>
186250803fSAntoniu Miclaus #include <linux/pwm.h>
196250803fSAntoniu Miclaus #include <linux/regmap.h>
206250803fSAntoniu Miclaus #include <linux/regulator/consumer.h>
216250803fSAntoniu Miclaus #include <linux/spi/spi.h>
226250803fSAntoniu Miclaus #include <linux/types.h>
236250803fSAntoniu Miclaus #include <linux/unaligned.h>
246250803fSAntoniu Miclaus #include <linux/units.h>
256250803fSAntoniu Miclaus 
266250803fSAntoniu Miclaus #include <linux/iio/backend.h>
276250803fSAntoniu Miclaus #include <linux/iio/iio.h>
286250803fSAntoniu Miclaus 
296250803fSAntoniu Miclaus #define AD4851_REG_INTERFACE_CONFIG_A	0x00
306250803fSAntoniu Miclaus #define AD4851_REG_INTERFACE_CONFIG_B	0x01
316250803fSAntoniu Miclaus #define AD4851_REG_PRODUCT_ID_L		0x04
326250803fSAntoniu Miclaus #define AD4851_REG_PRODUCT_ID_H		0x05
336250803fSAntoniu Miclaus #define AD4851_REG_DEVICE_CTRL		0x25
346250803fSAntoniu Miclaus #define AD4851_REG_PACKET		0x26
356250803fSAntoniu Miclaus #define AD4851_REG_OVERSAMPLE		0x27
366250803fSAntoniu Miclaus 
376250803fSAntoniu Miclaus #define AD4851_REG_CH_CONFIG_BASE	0x2A
386250803fSAntoniu Miclaus #define AD4851_REG_CHX_SOFTSPAN(ch)	((0x12 * (ch)) + AD4851_REG_CH_CONFIG_BASE)
396250803fSAntoniu Miclaus #define AD4851_REG_CHX_OFFSET(ch)	(AD4851_REG_CHX_SOFTSPAN(ch) + 0x01)
406250803fSAntoniu Miclaus #define AD4851_REG_CHX_OFFSET_LSB(ch)	AD4851_REG_CHX_OFFSET(ch)
416250803fSAntoniu Miclaus #define AD4851_REG_CHX_OFFSET_MID(ch)	(AD4851_REG_CHX_OFFSET_LSB(ch) + 0x01)
426250803fSAntoniu Miclaus #define AD4851_REG_CHX_OFFSET_MSB(ch)	(AD4851_REG_CHX_OFFSET_MID(ch) + 0x01)
436250803fSAntoniu Miclaus #define AD4851_REG_CHX_GAIN(ch)		(AD4851_REG_CHX_OFFSET(ch) + 0x03)
446250803fSAntoniu Miclaus #define AD4851_REG_CHX_GAIN_LSB(ch)	AD4851_REG_CHX_GAIN(ch)
456250803fSAntoniu Miclaus #define AD4851_REG_CHX_GAIN_MSB(ch)	(AD4851_REG_CHX_GAIN(ch) + 0x01)
466250803fSAntoniu Miclaus #define AD4851_REG_CHX_PHASE(ch)	(AD4851_REG_CHX_GAIN(ch) + 0x02)
476250803fSAntoniu Miclaus #define AD4851_REG_CHX_PHASE_LSB(ch)	AD4851_REG_CHX_PHASE(ch)
486250803fSAntoniu Miclaus #define AD4851_REG_CHX_PHASE_MSB(ch)	(AD4851_REG_CHX_PHASE_LSB(ch) + 0x01)
496250803fSAntoniu Miclaus 
506250803fSAntoniu Miclaus #define AD4851_REG_TESTPAT_0(c)		(0x38 + (c) * 0x12)
516250803fSAntoniu Miclaus #define AD4851_REG_TESTPAT_1(c)		(0x39 + (c) * 0x12)
526250803fSAntoniu Miclaus #define AD4851_REG_TESTPAT_2(c)		(0x3A + (c) * 0x12)
536250803fSAntoniu Miclaus #define AD4851_REG_TESTPAT_3(c)		(0x3B + (c) * 0x12)
546250803fSAntoniu Miclaus 
556250803fSAntoniu Miclaus #define AD4851_SW_RESET			(BIT(7) | BIT(0))
566250803fSAntoniu Miclaus #define AD4851_SDO_ENABLE		BIT(4)
576250803fSAntoniu Miclaus #define AD4851_SINGLE_INSTRUCTION	BIT(7)
586250803fSAntoniu Miclaus #define AD4851_REFBUF			BIT(2)
596250803fSAntoniu Miclaus #define AD4851_REFSEL			BIT(1)
606250803fSAntoniu Miclaus #define AD4851_ECHO_CLOCK_MODE		BIT(0)
616250803fSAntoniu Miclaus 
626250803fSAntoniu Miclaus #define AD4851_PACKET_FORMAT_0		0
636250803fSAntoniu Miclaus #define AD4851_PACKET_FORMAT_1		1
646250803fSAntoniu Miclaus #define AD4851_PACKET_FORMAT_MASK	GENMASK(1, 0)
656250803fSAntoniu Miclaus 
666250803fSAntoniu Miclaus #define AD4851_OS_EN_MSK		BIT(7)
676250803fSAntoniu Miclaus #define AD4851_OS_RATIO_MSK		GENMASK(3, 0)
686250803fSAntoniu Miclaus 
696250803fSAntoniu Miclaus #define AD4851_TEST_PAT			BIT(2)
706250803fSAntoniu Miclaus 
716250803fSAntoniu Miclaus #define AD4858_PACKET_SIZE_20		0
726250803fSAntoniu Miclaus #define AD4858_PACKET_SIZE_24		1
736250803fSAntoniu Miclaus #define AD4858_PACKET_SIZE_32		2
746250803fSAntoniu Miclaus 
756250803fSAntoniu Miclaus #define AD4857_PACKET_SIZE_16		0
766250803fSAntoniu Miclaus #define AD4857_PACKET_SIZE_24		1
776250803fSAntoniu Miclaus 
786250803fSAntoniu Miclaus #define AD4851_TESTPAT_0_DEFAULT	0x2A
796250803fSAntoniu Miclaus #define AD4851_TESTPAT_1_DEFAULT	0x3C
806250803fSAntoniu Miclaus #define AD4851_TESTPAT_2_DEFAULT	0xCE
816250803fSAntoniu Miclaus #define AD4851_TESTPAT_3_DEFAULT(c)	(0x0A + (0x10 * (c)))
826250803fSAntoniu Miclaus 
836250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_2V5		0
846250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N2V5_2V5	1
856250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_5V		2
866250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N5V_5V		3
876250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_6V25		4
886250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N6V25_6V25	5
896250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_10V		6
906250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N10V_10V	7
916250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_12V5		8
926250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N12V5_12V5	9
936250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_20V		10
946250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N20V_20V	11
956250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_25V		12
966250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N25V_25V	13
976250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_0V_40V		14
986250803fSAntoniu Miclaus #define AD4851_SOFTSPAN_N40V_40V	15
996250803fSAntoniu Miclaus 
1006250803fSAntoniu Miclaus #define AD4851_MAX_LANES		8
1016250803fSAntoniu Miclaus #define AD4851_MAX_IODELAY		32
1026250803fSAntoniu Miclaus 
1036250803fSAntoniu Miclaus #define AD4851_T_CNVH_NS		40
1046250803fSAntoniu Miclaus #define AD4851_T_CNVH_NS_MARGIN		10
1056250803fSAntoniu Miclaus 
1066250803fSAntoniu Miclaus #define AD4841_MAX_SCALE_AVAIL		8
1076250803fSAntoniu Miclaus 
1086250803fSAntoniu Miclaus #define AD4851_MAX_CH_NR		8
1096250803fSAntoniu Miclaus #define AD4851_CH_START			0
1106250803fSAntoniu Miclaus 
1116250803fSAntoniu Miclaus struct ad4851_scale {
1126250803fSAntoniu Miclaus 	unsigned int scale_val;
1136250803fSAntoniu Miclaus 	u8 reg_val;
1146250803fSAntoniu Miclaus };
1156250803fSAntoniu Miclaus 
1166250803fSAntoniu Miclaus static const struct ad4851_scale ad4851_scale_table_unipolar[] = {
1176250803fSAntoniu Miclaus 	{ 2500, 0x0 },
1186250803fSAntoniu Miclaus 	{ 5000, 0x2 },
1196250803fSAntoniu Miclaus 	{ 6250, 0x4 },
1206250803fSAntoniu Miclaus 	{ 10000, 0x6 },
1216250803fSAntoniu Miclaus 	{ 12500, 0x8 },
1226250803fSAntoniu Miclaus 	{ 20000, 0xA },
1236250803fSAntoniu Miclaus 	{ 25000, 0xC },
1246250803fSAntoniu Miclaus 	{ 40000, 0xE },
1256250803fSAntoniu Miclaus };
1266250803fSAntoniu Miclaus 
1276250803fSAntoniu Miclaus static const struct ad4851_scale ad4851_scale_table_bipolar[] = {
1286250803fSAntoniu Miclaus 	{ 5000, 0x1 },
1296250803fSAntoniu Miclaus 	{ 10000, 0x3 },
1306250803fSAntoniu Miclaus 	{ 12500, 0x5 },
1316250803fSAntoniu Miclaus 	{ 20000, 0x7 },
1326250803fSAntoniu Miclaus 	{ 25000, 0x9 },
1336250803fSAntoniu Miclaus 	{ 40000, 0xB },
1346250803fSAntoniu Miclaus 	{ 50000, 0xD },
1356250803fSAntoniu Miclaus 	{ 80000, 0xF },
1366250803fSAntoniu Miclaus };
1376250803fSAntoniu Miclaus 
1386250803fSAntoniu Miclaus static const unsigned int ad4851_scale_avail_unipolar[] = {
1396250803fSAntoniu Miclaus 	2500,
1406250803fSAntoniu Miclaus 	5000,
1416250803fSAntoniu Miclaus 	6250,
1426250803fSAntoniu Miclaus 	10000,
1436250803fSAntoniu Miclaus 	12500,
1446250803fSAntoniu Miclaus 	20000,
1456250803fSAntoniu Miclaus 	25000,
1466250803fSAntoniu Miclaus 	40000,
1476250803fSAntoniu Miclaus };
1486250803fSAntoniu Miclaus 
1496250803fSAntoniu Miclaus static const unsigned int ad4851_scale_avail_bipolar[] = {
1506250803fSAntoniu Miclaus 	5000,
1516250803fSAntoniu Miclaus 	10000,
1526250803fSAntoniu Miclaus 	12500,
1536250803fSAntoniu Miclaus 	20000,
1546250803fSAntoniu Miclaus 	25000,
1556250803fSAntoniu Miclaus 	40000,
1566250803fSAntoniu Miclaus 	50000,
1576250803fSAntoniu Miclaus 	80000,
1586250803fSAntoniu Miclaus };
1596250803fSAntoniu Miclaus 
1606250803fSAntoniu Miclaus struct ad4851_chip_info {
1616250803fSAntoniu Miclaus 	const char *name;
1626250803fSAntoniu Miclaus 	unsigned int product_id;
1636250803fSAntoniu Miclaus 	int num_scales;
1646250803fSAntoniu Miclaus 	unsigned long max_sample_rate_hz;
1656250803fSAntoniu Miclaus 	unsigned int resolution;
1666250803fSAntoniu Miclaus 	unsigned int max_channels;
1676250803fSAntoniu Miclaus 	int (*parse_channels)(struct iio_dev *indio_dev);
1686250803fSAntoniu Miclaus };
1696250803fSAntoniu Miclaus 
1706250803fSAntoniu Miclaus enum {
1716250803fSAntoniu Miclaus 	AD4851_SCAN_TYPE_NORMAL,
1726250803fSAntoniu Miclaus 	AD4851_SCAN_TYPE_RESOLUTION_BOOST,
1736250803fSAntoniu Miclaus };
1746250803fSAntoniu Miclaus 
1756250803fSAntoniu Miclaus struct ad4851_state {
1766250803fSAntoniu Miclaus 	struct spi_device *spi;
1776250803fSAntoniu Miclaus 	struct pwm_device *cnv;
1786250803fSAntoniu Miclaus 	struct iio_backend *back;
1796250803fSAntoniu Miclaus 	/*
1806250803fSAntoniu Miclaus 	 * Synchronize access to members the of driver state, and ensure
1816250803fSAntoniu Miclaus 	 * atomicity of consecutive regmap operations.
1826250803fSAntoniu Miclaus 	 */
1836250803fSAntoniu Miclaus 	struct mutex lock;
1846250803fSAntoniu Miclaus 	struct regmap *regmap;
1856250803fSAntoniu Miclaus 	const struct ad4851_chip_info *info;
1866250803fSAntoniu Miclaus 	struct gpio_desc *pd_gpio;
1876250803fSAntoniu Miclaus 	bool resolution_boost_enabled;
1886250803fSAntoniu Miclaus 	unsigned long cnv_trigger_rate_hz;
1896250803fSAntoniu Miclaus 	unsigned int osr;
1906250803fSAntoniu Miclaus 	bool vrefbuf_en;
1916250803fSAntoniu Miclaus 	bool vrefio_en;
1926250803fSAntoniu Miclaus 	bool bipolar_ch[AD4851_MAX_CH_NR];
1936250803fSAntoniu Miclaus 	unsigned int scales_unipolar[AD4841_MAX_SCALE_AVAIL][2];
1946250803fSAntoniu Miclaus 	unsigned int scales_bipolar[AD4841_MAX_SCALE_AVAIL][2];
1956250803fSAntoniu Miclaus };
1966250803fSAntoniu Miclaus 
ad4851_reg_access(struct iio_dev * indio_dev,unsigned int reg,unsigned int writeval,unsigned int * readval)1976250803fSAntoniu Miclaus static int ad4851_reg_access(struct iio_dev *indio_dev,
1986250803fSAntoniu Miclaus 			     unsigned int reg,
1996250803fSAntoniu Miclaus 			     unsigned int writeval,
2006250803fSAntoniu Miclaus 			     unsigned int *readval)
2016250803fSAntoniu Miclaus {
2026250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
2036250803fSAntoniu Miclaus 
2046250803fSAntoniu Miclaus 	if (readval)
2056250803fSAntoniu Miclaus 		return regmap_read(st->regmap, reg, readval);
2066250803fSAntoniu Miclaus 
2076250803fSAntoniu Miclaus 	return regmap_write(st->regmap, reg, writeval);
2086250803fSAntoniu Miclaus }
2096250803fSAntoniu Miclaus 
ad4851_set_sampling_freq(struct ad4851_state * st,unsigned int freq)2106250803fSAntoniu Miclaus static int ad4851_set_sampling_freq(struct ad4851_state *st, unsigned int freq)
2116250803fSAntoniu Miclaus {
2126250803fSAntoniu Miclaus 	struct pwm_state cnv_state = {
2136250803fSAntoniu Miclaus 		.duty_cycle = AD4851_T_CNVH_NS + AD4851_T_CNVH_NS_MARGIN,
2146250803fSAntoniu Miclaus 		.enabled = true,
2156250803fSAntoniu Miclaus 	};
2166250803fSAntoniu Miclaus 	int ret;
2176250803fSAntoniu Miclaus 
2186250803fSAntoniu Miclaus 	freq = clamp(freq, 1, st->info->max_sample_rate_hz);
2196250803fSAntoniu Miclaus 
2206250803fSAntoniu Miclaus 	cnv_state.period = DIV_ROUND_UP_ULL(NSEC_PER_SEC, freq);
2216250803fSAntoniu Miclaus 
2226250803fSAntoniu Miclaus 	ret = pwm_apply_might_sleep(st->cnv, &cnv_state);
2236250803fSAntoniu Miclaus 	if (ret)
2246250803fSAntoniu Miclaus 		return ret;
2256250803fSAntoniu Miclaus 
2266250803fSAntoniu Miclaus 	st->cnv_trigger_rate_hz = freq;
2276250803fSAntoniu Miclaus 
2286250803fSAntoniu Miclaus 	return 0;
2296250803fSAntoniu Miclaus }
2306250803fSAntoniu Miclaus 
2316250803fSAntoniu Miclaus static const int ad4851_oversampling_ratios[] = {
2326250803fSAntoniu Miclaus 	1, 2, 4, 8, 16,	32, 64, 128,
2336250803fSAntoniu Miclaus 	256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
2346250803fSAntoniu Miclaus 	65536,
2356250803fSAntoniu Miclaus };
2366250803fSAntoniu Miclaus 
ad4851_osr_to_regval(unsigned int ratio)2376250803fSAntoniu Miclaus static int ad4851_osr_to_regval(unsigned int ratio)
2386250803fSAntoniu Miclaus {
2396250803fSAntoniu Miclaus 	int i;
2406250803fSAntoniu Miclaus 
2416250803fSAntoniu Miclaus 	for (i = 1; i < ARRAY_SIZE(ad4851_oversampling_ratios); i++)
2426250803fSAntoniu Miclaus 		if (ratio == ad4851_oversampling_ratios[i])
2436250803fSAntoniu Miclaus 			return i - 1;
2446250803fSAntoniu Miclaus 
2456250803fSAntoniu Miclaus 	return -EINVAL;
2466250803fSAntoniu Miclaus }
2476250803fSAntoniu Miclaus 
__ad4851_get_scale(struct iio_dev * indio_dev,int scale_tbl,unsigned int * val,unsigned int * val2)2486250803fSAntoniu Miclaus static int __ad4851_get_scale(struct iio_dev *indio_dev, int scale_tbl,
2496250803fSAntoniu Miclaus 			      unsigned int *val, unsigned int *val2)
2506250803fSAntoniu Miclaus {
2516250803fSAntoniu Miclaus 	const struct iio_scan_type *scan_type;
2526250803fSAntoniu Miclaus 	unsigned int tmp;
2536250803fSAntoniu Miclaus 
2546250803fSAntoniu Miclaus 	scan_type = iio_get_current_scan_type(indio_dev, &indio_dev->channels[0]);
2556250803fSAntoniu Miclaus 	if (IS_ERR(scan_type))
2566250803fSAntoniu Miclaus 		return PTR_ERR(scan_type);
2576250803fSAntoniu Miclaus 
2586250803fSAntoniu Miclaus 	tmp = ((u64)scale_tbl * MICRO) >> scan_type->realbits;
2596250803fSAntoniu Miclaus 	*val = tmp / MICRO;
2606250803fSAntoniu Miclaus 	*val2 = tmp % MICRO;
2616250803fSAntoniu Miclaus 
2626250803fSAntoniu Miclaus 	return 0;
2636250803fSAntoniu Miclaus }
2646250803fSAntoniu Miclaus 
ad4851_scale_fill(struct iio_dev * indio_dev)2656250803fSAntoniu Miclaus static int ad4851_scale_fill(struct iio_dev *indio_dev)
2666250803fSAntoniu Miclaus {
2676250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
2686250803fSAntoniu Miclaus 	unsigned int i, val1, val2;
2696250803fSAntoniu Miclaus 	int ret;
2706250803fSAntoniu Miclaus 
2716250803fSAntoniu Miclaus 	for (i = 0; i < ARRAY_SIZE(ad4851_scale_avail_unipolar); i++) {
2726250803fSAntoniu Miclaus 		ret = __ad4851_get_scale(indio_dev,
2736250803fSAntoniu Miclaus 					 ad4851_scale_avail_unipolar[i],
2746250803fSAntoniu Miclaus 					 &val1, &val2);
2756250803fSAntoniu Miclaus 		if (ret)
2766250803fSAntoniu Miclaus 			return ret;
2776250803fSAntoniu Miclaus 
2786250803fSAntoniu Miclaus 		st->scales_unipolar[i][0] = val1;
2796250803fSAntoniu Miclaus 		st->scales_unipolar[i][1] = val2;
2806250803fSAntoniu Miclaus 	}
2816250803fSAntoniu Miclaus 
2826250803fSAntoniu Miclaus 	for (i = 0; i < ARRAY_SIZE(ad4851_scale_avail_bipolar); i++) {
2836250803fSAntoniu Miclaus 		ret = __ad4851_get_scale(indio_dev,
2846250803fSAntoniu Miclaus 					 ad4851_scale_avail_bipolar[i],
2856250803fSAntoniu Miclaus 					 &val1, &val2);
2866250803fSAntoniu Miclaus 		if (ret)
2876250803fSAntoniu Miclaus 			return ret;
2886250803fSAntoniu Miclaus 
2896250803fSAntoniu Miclaus 		st->scales_bipolar[i][0] = val1;
2906250803fSAntoniu Miclaus 		st->scales_bipolar[i][1] = val2;
2916250803fSAntoniu Miclaus 	}
2926250803fSAntoniu Miclaus 
2936250803fSAntoniu Miclaus 	return 0;
2946250803fSAntoniu Miclaus }
2956250803fSAntoniu Miclaus 
ad4851_set_oversampling_ratio(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,unsigned int osr)2966250803fSAntoniu Miclaus static int ad4851_set_oversampling_ratio(struct iio_dev *indio_dev,
2976250803fSAntoniu Miclaus 					 const struct iio_chan_spec *chan,
2986250803fSAntoniu Miclaus 					 unsigned int osr)
2996250803fSAntoniu Miclaus {
3006250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
3016250803fSAntoniu Miclaus 	int val, ret;
3026250803fSAntoniu Miclaus 
3036250803fSAntoniu Miclaus 	guard(mutex)(&st->lock);
3046250803fSAntoniu Miclaus 
3056250803fSAntoniu Miclaus 	if (osr == 1) {
3066250803fSAntoniu Miclaus 		ret = regmap_clear_bits(st->regmap, AD4851_REG_OVERSAMPLE,
3076250803fSAntoniu Miclaus 					AD4851_OS_EN_MSK);
3086250803fSAntoniu Miclaus 		if (ret)
3096250803fSAntoniu Miclaus 			return ret;
3106250803fSAntoniu Miclaus 	} else {
3116250803fSAntoniu Miclaus 		val = ad4851_osr_to_regval(osr);
3126250803fSAntoniu Miclaus 		if (val < 0)
3136250803fSAntoniu Miclaus 			return -EINVAL;
3146250803fSAntoniu Miclaus 
3156250803fSAntoniu Miclaus 		ret = regmap_update_bits(st->regmap, AD4851_REG_OVERSAMPLE,
3166250803fSAntoniu Miclaus 					 AD4851_OS_EN_MSK |
3176250803fSAntoniu Miclaus 					 AD4851_OS_RATIO_MSK,
3186250803fSAntoniu Miclaus 					 FIELD_PREP(AD4851_OS_EN_MSK, 1) |
3196250803fSAntoniu Miclaus 					 FIELD_PREP(AD4851_OS_RATIO_MSK, val));
3206250803fSAntoniu Miclaus 		if (ret)
3216250803fSAntoniu Miclaus 			return ret;
3226250803fSAntoniu Miclaus 	}
3236250803fSAntoniu Miclaus 
3246250803fSAntoniu Miclaus 	ret = iio_backend_oversampling_ratio_set(st->back, osr);
3256250803fSAntoniu Miclaus 	if (ret)
3266250803fSAntoniu Miclaus 		return ret;
3276250803fSAntoniu Miclaus 
3286250803fSAntoniu Miclaus 	switch (st->info->resolution) {
3296250803fSAntoniu Miclaus 	case 20:
3306250803fSAntoniu Miclaus 		switch (osr) {
3316250803fSAntoniu Miclaus 		case 0:
3326250803fSAntoniu Miclaus 			return -EINVAL;
3336250803fSAntoniu Miclaus 		case 1:
3346250803fSAntoniu Miclaus 			val = 20;
3356250803fSAntoniu Miclaus 			break;
3366250803fSAntoniu Miclaus 		default:
3376250803fSAntoniu Miclaus 			val = 24;
3386250803fSAntoniu Miclaus 			break;
3396250803fSAntoniu Miclaus 		}
3406250803fSAntoniu Miclaus 		break;
3416250803fSAntoniu Miclaus 	case 16:
3426250803fSAntoniu Miclaus 		val = 16;
3436250803fSAntoniu Miclaus 		break;
3446250803fSAntoniu Miclaus 	default:
3456250803fSAntoniu Miclaus 		return -EINVAL;
3466250803fSAntoniu Miclaus 	}
3476250803fSAntoniu Miclaus 
3486250803fSAntoniu Miclaus 	ret = iio_backend_data_size_set(st->back, val);
3496250803fSAntoniu Miclaus 	if (ret)
3506250803fSAntoniu Miclaus 		return ret;
3516250803fSAntoniu Miclaus 
3526250803fSAntoniu Miclaus 	if (osr == 1 || st->info->resolution == 16) {
3536250803fSAntoniu Miclaus 		ret = regmap_clear_bits(st->regmap, AD4851_REG_PACKET,
3546250803fSAntoniu Miclaus 					AD4851_PACKET_FORMAT_MASK);
3556250803fSAntoniu Miclaus 		if (ret)
3566250803fSAntoniu Miclaus 			return ret;
3576250803fSAntoniu Miclaus 
3586250803fSAntoniu Miclaus 		st->resolution_boost_enabled = false;
3596250803fSAntoniu Miclaus 	} else {
3606250803fSAntoniu Miclaus 		ret = regmap_update_bits(st->regmap, AD4851_REG_PACKET,
3616250803fSAntoniu Miclaus 					 AD4851_PACKET_FORMAT_MASK,
3626250803fSAntoniu Miclaus 					 FIELD_PREP(AD4851_PACKET_FORMAT_MASK, 1));
3636250803fSAntoniu Miclaus 		if (ret)
3646250803fSAntoniu Miclaus 			return ret;
3656250803fSAntoniu Miclaus 
3666250803fSAntoniu Miclaus 		st->resolution_boost_enabled = true;
3676250803fSAntoniu Miclaus 	}
3686250803fSAntoniu Miclaus 
3696250803fSAntoniu Miclaus 	if (st->osr != osr) {
3706250803fSAntoniu Miclaus 		ret = ad4851_scale_fill(indio_dev);
3716250803fSAntoniu Miclaus 		if (ret)
3726250803fSAntoniu Miclaus 			return ret;
3736250803fSAntoniu Miclaus 
3746250803fSAntoniu Miclaus 		st->osr = osr;
3756250803fSAntoniu Miclaus 	}
3766250803fSAntoniu Miclaus 
3776250803fSAntoniu Miclaus 	return 0;
3786250803fSAntoniu Miclaus }
3796250803fSAntoniu Miclaus 
ad4851_get_oversampling_ratio(struct ad4851_state * st,unsigned int * val)3806250803fSAntoniu Miclaus static int ad4851_get_oversampling_ratio(struct ad4851_state *st, unsigned int *val)
3816250803fSAntoniu Miclaus {
3826250803fSAntoniu Miclaus 	unsigned int osr;
3836250803fSAntoniu Miclaus 	int ret;
3846250803fSAntoniu Miclaus 
3856250803fSAntoniu Miclaus 	guard(mutex)(&st->lock);
3866250803fSAntoniu Miclaus 
3876250803fSAntoniu Miclaus 	ret = regmap_read(st->regmap, AD4851_REG_OVERSAMPLE, &osr);
3886250803fSAntoniu Miclaus 	if (ret)
3896250803fSAntoniu Miclaus 		return ret;
3906250803fSAntoniu Miclaus 
3916250803fSAntoniu Miclaus 	if (!FIELD_GET(AD4851_OS_EN_MSK, osr))
3926250803fSAntoniu Miclaus 		*val = 1;
3936250803fSAntoniu Miclaus 	else
3946250803fSAntoniu Miclaus 		*val = ad4851_oversampling_ratios[FIELD_GET(AD4851_OS_RATIO_MSK, osr) + 1];
3956250803fSAntoniu Miclaus 
3966250803fSAntoniu Miclaus 	st->osr = *val;
3976250803fSAntoniu Miclaus 
3986250803fSAntoniu Miclaus 	return IIO_VAL_INT;
3996250803fSAntoniu Miclaus }
4006250803fSAntoniu Miclaus 
ad4851_pwm_disable(void * data)4016250803fSAntoniu Miclaus static void ad4851_pwm_disable(void *data)
4026250803fSAntoniu Miclaus {
4036250803fSAntoniu Miclaus 	pwm_disable(data);
4046250803fSAntoniu Miclaus }
4056250803fSAntoniu Miclaus 
ad4851_setup(struct ad4851_state * st)4066250803fSAntoniu Miclaus static int ad4851_setup(struct ad4851_state *st)
4076250803fSAntoniu Miclaus {
4086250803fSAntoniu Miclaus 	unsigned int product_id;
4096250803fSAntoniu Miclaus 	int ret;
4106250803fSAntoniu Miclaus 
4116250803fSAntoniu Miclaus 	if (st->pd_gpio) {
4126250803fSAntoniu Miclaus 		/* To initiate a global reset, bring the PD pin high twice */
4136250803fSAntoniu Miclaus 		gpiod_set_value(st->pd_gpio, 1);
4146250803fSAntoniu Miclaus 		fsleep(1);
4156250803fSAntoniu Miclaus 		gpiod_set_value(st->pd_gpio, 0);
4166250803fSAntoniu Miclaus 		fsleep(1);
4176250803fSAntoniu Miclaus 		gpiod_set_value(st->pd_gpio, 1);
4186250803fSAntoniu Miclaus 		fsleep(1);
4196250803fSAntoniu Miclaus 		gpiod_set_value(st->pd_gpio, 0);
4206250803fSAntoniu Miclaus 		fsleep(1000);
4216250803fSAntoniu Miclaus 	} else {
4226250803fSAntoniu Miclaus 		ret = regmap_set_bits(st->regmap, AD4851_REG_INTERFACE_CONFIG_A,
4236250803fSAntoniu Miclaus 				      AD4851_SW_RESET);
4246250803fSAntoniu Miclaus 		if (ret)
4256250803fSAntoniu Miclaus 			return ret;
4266250803fSAntoniu Miclaus 	}
4276250803fSAntoniu Miclaus 
4286250803fSAntoniu Miclaus 	if (st->vrefbuf_en) {
4296250803fSAntoniu Miclaus 		ret = regmap_set_bits(st->regmap, AD4851_REG_DEVICE_CTRL,
4306250803fSAntoniu Miclaus 				      AD4851_REFBUF);
4316250803fSAntoniu Miclaus 		if (ret)
4326250803fSAntoniu Miclaus 			return ret;
4336250803fSAntoniu Miclaus 	}
4346250803fSAntoniu Miclaus 
4356250803fSAntoniu Miclaus 	if (st->vrefio_en) {
4366250803fSAntoniu Miclaus 		ret = regmap_set_bits(st->regmap, AD4851_REG_DEVICE_CTRL,
4376250803fSAntoniu Miclaus 				      AD4851_REFSEL);
4386250803fSAntoniu Miclaus 		if (ret)
4396250803fSAntoniu Miclaus 			return ret;
4406250803fSAntoniu Miclaus 	}
4416250803fSAntoniu Miclaus 
4426250803fSAntoniu Miclaus 	ret = regmap_write(st->regmap, AD4851_REG_INTERFACE_CONFIG_B,
4436250803fSAntoniu Miclaus 			   AD4851_SINGLE_INSTRUCTION);
4446250803fSAntoniu Miclaus 	if (ret)
4456250803fSAntoniu Miclaus 		return ret;
4466250803fSAntoniu Miclaus 
4476250803fSAntoniu Miclaus 	ret = regmap_write(st->regmap, AD4851_REG_INTERFACE_CONFIG_A,
4486250803fSAntoniu Miclaus 			   AD4851_SDO_ENABLE);
4496250803fSAntoniu Miclaus 	if (ret)
4506250803fSAntoniu Miclaus 		return ret;
4516250803fSAntoniu Miclaus 
4526250803fSAntoniu Miclaus 	ret = regmap_read(st->regmap, AD4851_REG_PRODUCT_ID_L, &product_id);
4536250803fSAntoniu Miclaus 	if (ret)
4546250803fSAntoniu Miclaus 		return ret;
4556250803fSAntoniu Miclaus 
4566250803fSAntoniu Miclaus 	if (product_id != st->info->product_id)
4576250803fSAntoniu Miclaus 		dev_info(&st->spi->dev, "Unknown product ID: 0x%02X\n",
4586250803fSAntoniu Miclaus 			 product_id);
4596250803fSAntoniu Miclaus 
4606250803fSAntoniu Miclaus 	ret = regmap_set_bits(st->regmap, AD4851_REG_DEVICE_CTRL,
4616250803fSAntoniu Miclaus 			      AD4851_ECHO_CLOCK_MODE);
4626250803fSAntoniu Miclaus 	if (ret)
4636250803fSAntoniu Miclaus 		return ret;
4646250803fSAntoniu Miclaus 
4656250803fSAntoniu Miclaus 	return regmap_write(st->regmap, AD4851_REG_PACKET, 0);
4666250803fSAntoniu Miclaus }
4676250803fSAntoniu Miclaus 
4686250803fSAntoniu Miclaus /*
4696250803fSAntoniu Miclaus  * Find the longest consecutive sequence of false values from field
4706250803fSAntoniu Miclaus  * and return starting index.
4716250803fSAntoniu Miclaus  */
ad4851_find_opt(const unsigned long * field,unsigned int start,unsigned int nbits,unsigned int * val)4726250803fSAntoniu Miclaus static int ad4851_find_opt(const unsigned long *field, unsigned int start,
4736250803fSAntoniu Miclaus 			   unsigned int nbits, unsigned int *val)
4746250803fSAntoniu Miclaus {
4756250803fSAntoniu Miclaus 	unsigned int bit = start, end, start_cnt, cnt = 0;
4766250803fSAntoniu Miclaus 
4776250803fSAntoniu Miclaus 	for_each_clear_bitrange_from(bit, end, field, start + nbits) {
4786250803fSAntoniu Miclaus 		if (end - bit > cnt) {
4796250803fSAntoniu Miclaus 			cnt = end - bit;
4806250803fSAntoniu Miclaus 			start_cnt = bit - start;
4816250803fSAntoniu Miclaus 		}
4826250803fSAntoniu Miclaus 	}
4836250803fSAntoniu Miclaus 
4846250803fSAntoniu Miclaus 	if (!cnt)
4856250803fSAntoniu Miclaus 		return -ENOENT;
4866250803fSAntoniu Miclaus 
4876250803fSAntoniu Miclaus 	*val = start_cnt;
4886250803fSAntoniu Miclaus 
4896250803fSAntoniu Miclaus 	return cnt;
4906250803fSAntoniu Miclaus }
4916250803fSAntoniu Miclaus 
ad4851_calibrate(struct iio_dev * indio_dev)4926250803fSAntoniu Miclaus static int ad4851_calibrate(struct iio_dev *indio_dev)
4936250803fSAntoniu Miclaus {
4946250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
495eb2f9ab1SDan Carpenter 	unsigned int opt_delay, num_lanes, delay, i, s;
4966250803fSAntoniu Miclaus 	enum iio_backend_interface_type interface_type;
4976250803fSAntoniu Miclaus 	DECLARE_BITMAP(pn_status, AD4851_MAX_LANES * AD4851_MAX_IODELAY);
4986250803fSAntoniu Miclaus 	bool status;
499eb2f9ab1SDan Carpenter 	int c, ret;
5006250803fSAntoniu Miclaus 
5016250803fSAntoniu Miclaus 	ret = iio_backend_interface_type_get(st->back, &interface_type);
5026250803fSAntoniu Miclaus 	if (ret)
5036250803fSAntoniu Miclaus 		return ret;
5046250803fSAntoniu Miclaus 
5056250803fSAntoniu Miclaus 	switch (interface_type) {
5066250803fSAntoniu Miclaus 	case IIO_BACKEND_INTERFACE_SERIAL_CMOS:
5076250803fSAntoniu Miclaus 		num_lanes = indio_dev->num_channels;
5086250803fSAntoniu Miclaus 		break;
5096250803fSAntoniu Miclaus 	case IIO_BACKEND_INTERFACE_SERIAL_LVDS:
5106250803fSAntoniu Miclaus 		num_lanes = 1;
5116250803fSAntoniu Miclaus 		break;
5126250803fSAntoniu Miclaus 	default:
5136250803fSAntoniu Miclaus 		return -EINVAL;
5146250803fSAntoniu Miclaus 	}
5156250803fSAntoniu Miclaus 
5166250803fSAntoniu Miclaus 	if (st->info->resolution == 16) {
5176250803fSAntoniu Miclaus 		ret = iio_backend_data_size_set(st->back, 24);
5186250803fSAntoniu Miclaus 		if (ret)
5196250803fSAntoniu Miclaus 			return ret;
5206250803fSAntoniu Miclaus 
5216250803fSAntoniu Miclaus 		ret = regmap_write(st->regmap, AD4851_REG_PACKET,
5226250803fSAntoniu Miclaus 				   AD4851_TEST_PAT | AD4857_PACKET_SIZE_24);
5236250803fSAntoniu Miclaus 		if (ret)
5246250803fSAntoniu Miclaus 			return ret;
5256250803fSAntoniu Miclaus 	} else {
5266250803fSAntoniu Miclaus 		ret = iio_backend_data_size_set(st->back, 32);
5276250803fSAntoniu Miclaus 		if (ret)
5286250803fSAntoniu Miclaus 			return ret;
5296250803fSAntoniu Miclaus 
5306250803fSAntoniu Miclaus 		ret = regmap_write(st->regmap, AD4851_REG_PACKET,
5316250803fSAntoniu Miclaus 				   AD4851_TEST_PAT | AD4858_PACKET_SIZE_32);
5326250803fSAntoniu Miclaus 		if (ret)
5336250803fSAntoniu Miclaus 			return ret;
5346250803fSAntoniu Miclaus 	}
5356250803fSAntoniu Miclaus 
5366250803fSAntoniu Miclaus 	for (i = 0; i < indio_dev->num_channels; i++) {
5376250803fSAntoniu Miclaus 		ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_0(i),
5386250803fSAntoniu Miclaus 				   AD4851_TESTPAT_0_DEFAULT);
5396250803fSAntoniu Miclaus 		if (ret)
5406250803fSAntoniu Miclaus 			return ret;
5416250803fSAntoniu Miclaus 
5426250803fSAntoniu Miclaus 		ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_1(i),
5436250803fSAntoniu Miclaus 				   AD4851_TESTPAT_1_DEFAULT);
5446250803fSAntoniu Miclaus 		if (ret)
5456250803fSAntoniu Miclaus 			return ret;
5466250803fSAntoniu Miclaus 
5476250803fSAntoniu Miclaus 		ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_2(i),
5486250803fSAntoniu Miclaus 				   AD4851_TESTPAT_2_DEFAULT);
5496250803fSAntoniu Miclaus 		if (ret)
5506250803fSAntoniu Miclaus 			return ret;
5516250803fSAntoniu Miclaus 
5526250803fSAntoniu Miclaus 		ret = regmap_write(st->regmap, AD4851_REG_TESTPAT_3(i),
5536250803fSAntoniu Miclaus 				   AD4851_TESTPAT_3_DEFAULT(i));
5546250803fSAntoniu Miclaus 		if (ret)
5556250803fSAntoniu Miclaus 			return ret;
5566250803fSAntoniu Miclaus 
5576250803fSAntoniu Miclaus 		ret = iio_backend_chan_enable(st->back,
5586250803fSAntoniu Miclaus 					      indio_dev->channels[i].channel);
5596250803fSAntoniu Miclaus 		if (ret)
5606250803fSAntoniu Miclaus 			return ret;
5616250803fSAntoniu Miclaus 	}
5626250803fSAntoniu Miclaus 
5636250803fSAntoniu Miclaus 	for (i = 0; i < num_lanes; i++) {
5646250803fSAntoniu Miclaus 		for (delay = 0; delay < AD4851_MAX_IODELAY; delay++) {
5656250803fSAntoniu Miclaus 			ret = iio_backend_iodelay_set(st->back, i, delay);
5666250803fSAntoniu Miclaus 			if (ret)
5676250803fSAntoniu Miclaus 				return ret;
5686250803fSAntoniu Miclaus 
5696250803fSAntoniu Miclaus 			ret = iio_backend_chan_status(st->back, i, &status);
5706250803fSAntoniu Miclaus 			if (ret)
5716250803fSAntoniu Miclaus 				return ret;
5726250803fSAntoniu Miclaus 
5736250803fSAntoniu Miclaus 			__assign_bit(i * AD4851_MAX_IODELAY + delay, pn_status,
5746250803fSAntoniu Miclaus 				     status);
5756250803fSAntoniu Miclaus 		}
5766250803fSAntoniu Miclaus 	}
5776250803fSAntoniu Miclaus 
5786250803fSAntoniu Miclaus 	for (i = 0; i < num_lanes; i++) {
5796250803fSAntoniu Miclaus 		c = ad4851_find_opt(pn_status, i * AD4851_MAX_IODELAY,
5806250803fSAntoniu Miclaus 				    AD4851_MAX_IODELAY, &s);
5816250803fSAntoniu Miclaus 		if (c < 0)
5826250803fSAntoniu Miclaus 			return c;
5836250803fSAntoniu Miclaus 
5846250803fSAntoniu Miclaus 		opt_delay = s + c / 2;
5856250803fSAntoniu Miclaus 		ret = iio_backend_iodelay_set(st->back, i, opt_delay);
5866250803fSAntoniu Miclaus 		if (ret)
5876250803fSAntoniu Miclaus 			return ret;
5886250803fSAntoniu Miclaus 	}
5896250803fSAntoniu Miclaus 
5906250803fSAntoniu Miclaus 	for (i = 0; i < indio_dev->num_channels; i++) {
5916250803fSAntoniu Miclaus 		ret = iio_backend_chan_disable(st->back, i);
5926250803fSAntoniu Miclaus 		if (ret)
5936250803fSAntoniu Miclaus 			return ret;
5946250803fSAntoniu Miclaus 	}
5956250803fSAntoniu Miclaus 
5966250803fSAntoniu Miclaus 	ret = iio_backend_data_size_set(st->back, 20);
5976250803fSAntoniu Miclaus 	if (ret)
5986250803fSAntoniu Miclaus 		return ret;
5996250803fSAntoniu Miclaus 
6006250803fSAntoniu Miclaus 	return regmap_write(st->regmap, AD4851_REG_PACKET, 0);
6016250803fSAntoniu Miclaus }
6026250803fSAntoniu Miclaus 
ad4851_get_calibscale(struct ad4851_state * st,int ch,int * val,int * val2)6036250803fSAntoniu Miclaus static int ad4851_get_calibscale(struct ad4851_state *st, int ch, int *val, int *val2)
6046250803fSAntoniu Miclaus {
6056250803fSAntoniu Miclaus 	unsigned int reg_val;
6066250803fSAntoniu Miclaus 	int gain;
6076250803fSAntoniu Miclaus 	int ret;
6086250803fSAntoniu Miclaus 
6096250803fSAntoniu Miclaus 	guard(mutex)(&st->lock);
6106250803fSAntoniu Miclaus 
6116250803fSAntoniu Miclaus 	ret = regmap_read(st->regmap, AD4851_REG_CHX_GAIN_MSB(ch), &reg_val);
6126250803fSAntoniu Miclaus 	if (ret)
6136250803fSAntoniu Miclaus 		return ret;
6146250803fSAntoniu Miclaus 
6156250803fSAntoniu Miclaus 	gain = reg_val << 8;
6166250803fSAntoniu Miclaus 
6176250803fSAntoniu Miclaus 	ret = regmap_read(st->regmap, AD4851_REG_CHX_GAIN_LSB(ch), &reg_val);
6186250803fSAntoniu Miclaus 	if (ret)
6196250803fSAntoniu Miclaus 		return ret;
6206250803fSAntoniu Miclaus 
6216250803fSAntoniu Miclaus 	gain |= reg_val;
6226250803fSAntoniu Miclaus 
6236250803fSAntoniu Miclaus 	*val = gain;
6246250803fSAntoniu Miclaus 	*val2 = 15;
6256250803fSAntoniu Miclaus 
6266250803fSAntoniu Miclaus 	return IIO_VAL_FRACTIONAL_LOG2;
6276250803fSAntoniu Miclaus }
6286250803fSAntoniu Miclaus 
ad4851_set_calibscale(struct ad4851_state * st,int ch,int val,int val2)6296250803fSAntoniu Miclaus static int ad4851_set_calibscale(struct ad4851_state *st, int ch, int val,
6306250803fSAntoniu Miclaus 				 int val2)
6316250803fSAntoniu Miclaus {
6326250803fSAntoniu Miclaus 	u64 gain;
6336250803fSAntoniu Miclaus 	u8 buf[2];
6346250803fSAntoniu Miclaus 	int ret;
6356250803fSAntoniu Miclaus 
6366250803fSAntoniu Miclaus 	if (val < 0 || val2 < 0)
6376250803fSAntoniu Miclaus 		return -EINVAL;
6386250803fSAntoniu Miclaus 
6396250803fSAntoniu Miclaus 	gain = val * MICRO + val2;
6406250803fSAntoniu Miclaus 	gain = DIV_U64_ROUND_CLOSEST(gain * 32768, MICRO);
6416250803fSAntoniu Miclaus 
6426250803fSAntoniu Miclaus 	put_unaligned_be16(gain, buf);
6436250803fSAntoniu Miclaus 
6446250803fSAntoniu Miclaus 	guard(mutex)(&st->lock);
6456250803fSAntoniu Miclaus 
6466250803fSAntoniu Miclaus 	ret = regmap_write(st->regmap, AD4851_REG_CHX_GAIN_MSB(ch), buf[0]);
6476250803fSAntoniu Miclaus 	if (ret)
6486250803fSAntoniu Miclaus 		return ret;
6496250803fSAntoniu Miclaus 
6506250803fSAntoniu Miclaus 	return regmap_write(st->regmap, AD4851_REG_CHX_GAIN_LSB(ch), buf[1]);
6516250803fSAntoniu Miclaus }
6526250803fSAntoniu Miclaus 
ad4851_get_calibbias(struct ad4851_state * st,int ch,int * val)6536250803fSAntoniu Miclaus static int ad4851_get_calibbias(struct ad4851_state *st, int ch, int *val)
6546250803fSAntoniu Miclaus {
6556250803fSAntoniu Miclaus 	unsigned int lsb, mid, msb;
6566250803fSAntoniu Miclaus 	int ret;
6576250803fSAntoniu Miclaus 
6586250803fSAntoniu Miclaus 	guard(mutex)(&st->lock);
6596250803fSAntoniu Miclaus 	/*
6606250803fSAntoniu Miclaus 	 * After testing, the bulk_write operations doesn't work as expected
6616250803fSAntoniu Miclaus 	 * here since the cs needs to be raised after each byte transaction.
6626250803fSAntoniu Miclaus 	 */
6636250803fSAntoniu Miclaus 	ret = regmap_read(st->regmap, AD4851_REG_CHX_OFFSET_MSB(ch), &msb);
6646250803fSAntoniu Miclaus 	if (ret)
6656250803fSAntoniu Miclaus 		return ret;
6666250803fSAntoniu Miclaus 
6676250803fSAntoniu Miclaus 	ret = regmap_read(st->regmap, AD4851_REG_CHX_OFFSET_MID(ch), &mid);
6686250803fSAntoniu Miclaus 	if (ret)
6696250803fSAntoniu Miclaus 		return ret;
6706250803fSAntoniu Miclaus 
6716250803fSAntoniu Miclaus 	ret = regmap_read(st->regmap, AD4851_REG_CHX_OFFSET_LSB(ch), &lsb);
6726250803fSAntoniu Miclaus 	if (ret)
6736250803fSAntoniu Miclaus 		return ret;
6746250803fSAntoniu Miclaus 
6756250803fSAntoniu Miclaus 	if (st->info->resolution == 16) {
6766250803fSAntoniu Miclaus 		*val = msb << 8;
6776250803fSAntoniu Miclaus 		*val |= mid;
6786250803fSAntoniu Miclaus 		*val = sign_extend32(*val, 15);
6796250803fSAntoniu Miclaus 	} else {
6806250803fSAntoniu Miclaus 		*val = msb << 12;
6816250803fSAntoniu Miclaus 		*val |= mid << 4;
6826250803fSAntoniu Miclaus 		*val |= lsb >> 4;
6836250803fSAntoniu Miclaus 		*val = sign_extend32(*val, 19);
6846250803fSAntoniu Miclaus 	}
6856250803fSAntoniu Miclaus 
6866250803fSAntoniu Miclaus 	return IIO_VAL_INT;
6876250803fSAntoniu Miclaus }
6886250803fSAntoniu Miclaus 
ad4851_set_calibbias(struct ad4851_state * st,int ch,int val)6896250803fSAntoniu Miclaus static int ad4851_set_calibbias(struct ad4851_state *st, int ch, int val)
6906250803fSAntoniu Miclaus {
6916250803fSAntoniu Miclaus 	u8 buf[3];
6926250803fSAntoniu Miclaus 	int ret;
6936250803fSAntoniu Miclaus 
6946250803fSAntoniu Miclaus 	if (val < 0)
6956250803fSAntoniu Miclaus 		return -EINVAL;
6966250803fSAntoniu Miclaus 
6976250803fSAntoniu Miclaus 	if (st->info->resolution == 16)
6986250803fSAntoniu Miclaus 		put_unaligned_be16(val, buf);
6996250803fSAntoniu Miclaus 	else
7006250803fSAntoniu Miclaus 		put_unaligned_be24(val << 4, buf);
7016250803fSAntoniu Miclaus 
7026250803fSAntoniu Miclaus 	guard(mutex)(&st->lock);
7036250803fSAntoniu Miclaus 	/*
7046250803fSAntoniu Miclaus 	 * After testing, the bulk_write operations doesn't work as expected
7056250803fSAntoniu Miclaus 	 * here since the cs needs to be raised after each byte transaction.
7066250803fSAntoniu Miclaus 	 */
7076250803fSAntoniu Miclaus 	ret = regmap_write(st->regmap, AD4851_REG_CHX_OFFSET_LSB(ch), buf[2]);
7086250803fSAntoniu Miclaus 	if (ret)
7096250803fSAntoniu Miclaus 		return ret;
7106250803fSAntoniu Miclaus 
7116250803fSAntoniu Miclaus 	ret = regmap_write(st->regmap, AD4851_REG_CHX_OFFSET_MID(ch), buf[1]);
7126250803fSAntoniu Miclaus 	if (ret)
7136250803fSAntoniu Miclaus 		return ret;
7146250803fSAntoniu Miclaus 
7156250803fSAntoniu Miclaus 	return regmap_write(st->regmap, AD4851_REG_CHX_OFFSET_MSB(ch), buf[0]);
7166250803fSAntoniu Miclaus }
7176250803fSAntoniu Miclaus 
ad4851_set_scale(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int val,int val2)7186250803fSAntoniu Miclaus static int ad4851_set_scale(struct iio_dev *indio_dev,
7196250803fSAntoniu Miclaus 			    const struct iio_chan_spec *chan, int val, int val2)
7206250803fSAntoniu Miclaus {
7216250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
7226250803fSAntoniu Miclaus 	unsigned int scale_val[2];
7236250803fSAntoniu Miclaus 	unsigned int i;
7246250803fSAntoniu Miclaus 	const struct ad4851_scale *scale_table;
7256250803fSAntoniu Miclaus 	size_t table_size;
7266250803fSAntoniu Miclaus 	int ret;
7276250803fSAntoniu Miclaus 
7286250803fSAntoniu Miclaus 	if (st->bipolar_ch[chan->channel]) {
7296250803fSAntoniu Miclaus 		scale_table = ad4851_scale_table_bipolar;
7306250803fSAntoniu Miclaus 		table_size = ARRAY_SIZE(ad4851_scale_table_bipolar);
7316250803fSAntoniu Miclaus 	} else {
7326250803fSAntoniu Miclaus 		scale_table = ad4851_scale_table_unipolar;
7336250803fSAntoniu Miclaus 		table_size = ARRAY_SIZE(ad4851_scale_table_unipolar);
7346250803fSAntoniu Miclaus 	}
7356250803fSAntoniu Miclaus 
7366250803fSAntoniu Miclaus 	for (i = 0; i < table_size; i++) {
7376250803fSAntoniu Miclaus 		ret = __ad4851_get_scale(indio_dev, scale_table[i].scale_val,
7386250803fSAntoniu Miclaus 					 &scale_val[0], &scale_val[1]);
7396250803fSAntoniu Miclaus 		if (ret)
7406250803fSAntoniu Miclaus 			return ret;
7416250803fSAntoniu Miclaus 
7426250803fSAntoniu Miclaus 		if (scale_val[0] != val || scale_val[1] != val2)
7436250803fSAntoniu Miclaus 			continue;
7446250803fSAntoniu Miclaus 
7456250803fSAntoniu Miclaus 		return regmap_write(st->regmap,
7466250803fSAntoniu Miclaus 				    AD4851_REG_CHX_SOFTSPAN(chan->channel),
7476250803fSAntoniu Miclaus 				    scale_table[i].reg_val);
7486250803fSAntoniu Miclaus 	}
7496250803fSAntoniu Miclaus 
7506250803fSAntoniu Miclaus 	return -EINVAL;
7516250803fSAntoniu Miclaus }
7526250803fSAntoniu Miclaus 
ad4851_get_scale(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int * val,int * val2)7536250803fSAntoniu Miclaus static int ad4851_get_scale(struct iio_dev *indio_dev,
7546250803fSAntoniu Miclaus 			    const struct iio_chan_spec *chan, int *val,
7556250803fSAntoniu Miclaus 			    int *val2)
7566250803fSAntoniu Miclaus {
7576250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
7586250803fSAntoniu Miclaus 	const struct ad4851_scale *scale_table;
7596250803fSAntoniu Miclaus 	size_t table_size;
7606250803fSAntoniu Miclaus 	u32 softspan_val;
7616250803fSAntoniu Miclaus 	int i, ret;
7626250803fSAntoniu Miclaus 
7636250803fSAntoniu Miclaus 	if (st->bipolar_ch[chan->channel]) {
7646250803fSAntoniu Miclaus 		scale_table = ad4851_scale_table_bipolar;
7656250803fSAntoniu Miclaus 		table_size = ARRAY_SIZE(ad4851_scale_table_bipolar);
7666250803fSAntoniu Miclaus 	} else {
7676250803fSAntoniu Miclaus 		scale_table = ad4851_scale_table_unipolar;
7686250803fSAntoniu Miclaus 		table_size = ARRAY_SIZE(ad4851_scale_table_unipolar);
7696250803fSAntoniu Miclaus 	}
7706250803fSAntoniu Miclaus 
7716250803fSAntoniu Miclaus 	ret = regmap_read(st->regmap, AD4851_REG_CHX_SOFTSPAN(chan->channel),
7726250803fSAntoniu Miclaus 			  &softspan_val);
7736250803fSAntoniu Miclaus 	if (ret)
7746250803fSAntoniu Miclaus 		return ret;
7756250803fSAntoniu Miclaus 
7766250803fSAntoniu Miclaus 	for (i = 0; i < table_size; i++) {
7776250803fSAntoniu Miclaus 		if (softspan_val == scale_table[i].reg_val)
7786250803fSAntoniu Miclaus 			break;
7796250803fSAntoniu Miclaus 	}
7806250803fSAntoniu Miclaus 
7816250803fSAntoniu Miclaus 	if (i == table_size)
7826250803fSAntoniu Miclaus 		return -EIO;
7836250803fSAntoniu Miclaus 
7846250803fSAntoniu Miclaus 	ret = __ad4851_get_scale(indio_dev, scale_table[i].scale_val, val,
7856250803fSAntoniu Miclaus 				 val2);
7866250803fSAntoniu Miclaus 	if (ret)
7876250803fSAntoniu Miclaus 		return ret;
7886250803fSAntoniu Miclaus 
7896250803fSAntoniu Miclaus 	return IIO_VAL_INT_PLUS_MICRO;
7906250803fSAntoniu Miclaus }
7916250803fSAntoniu Miclaus 
ad4851_read_raw(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int * val,int * val2,long info)7926250803fSAntoniu Miclaus static int ad4851_read_raw(struct iio_dev *indio_dev,
7936250803fSAntoniu Miclaus 			   const struct iio_chan_spec *chan,
7946250803fSAntoniu Miclaus 			   int *val, int *val2, long info)
7956250803fSAntoniu Miclaus {
7966250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
7976250803fSAntoniu Miclaus 
7986250803fSAntoniu Miclaus 	switch (info) {
7996250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_SAMP_FREQ:
8006250803fSAntoniu Miclaus 		*val = st->cnv_trigger_rate_hz;
8016250803fSAntoniu Miclaus 		*val2 = st->osr;
8026250803fSAntoniu Miclaus 		return IIO_VAL_FRACTIONAL;
8036250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_CALIBSCALE:
8046250803fSAntoniu Miclaus 		return ad4851_get_calibscale(st, chan->channel, val, val2);
8056250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_SCALE:
8066250803fSAntoniu Miclaus 		return ad4851_get_scale(indio_dev, chan, val, val2);
8076250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_CALIBBIAS:
8086250803fSAntoniu Miclaus 		return ad4851_get_calibbias(st, chan->channel, val);
8096250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
8106250803fSAntoniu Miclaus 		return ad4851_get_oversampling_ratio(st, val);
8116250803fSAntoniu Miclaus 	default:
8126250803fSAntoniu Miclaus 		return -EINVAL;
8136250803fSAntoniu Miclaus 	}
8146250803fSAntoniu Miclaus }
8156250803fSAntoniu Miclaus 
ad4851_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long info)8166250803fSAntoniu Miclaus static int ad4851_write_raw(struct iio_dev *indio_dev,
8176250803fSAntoniu Miclaus 			    struct iio_chan_spec const *chan,
8186250803fSAntoniu Miclaus 			    int val, int val2, long info)
8196250803fSAntoniu Miclaus {
8206250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
8216250803fSAntoniu Miclaus 
8226250803fSAntoniu Miclaus 	switch (info) {
8236250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_SAMP_FREQ:
8246250803fSAntoniu Miclaus 		if (val < 0 || val2 < 0)
8256250803fSAntoniu Miclaus 			return -EINVAL;
8266250803fSAntoniu Miclaus 		return ad4851_set_sampling_freq(st, val * st->osr + val2 * st->osr / MICRO);
8276250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_SCALE:
8286250803fSAntoniu Miclaus 		return ad4851_set_scale(indio_dev, chan, val, val2);
8296250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_CALIBSCALE:
8306250803fSAntoniu Miclaus 		return ad4851_set_calibscale(st, chan->channel, val, val2);
8316250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_CALIBBIAS:
8326250803fSAntoniu Miclaus 		return ad4851_set_calibbias(st, chan->channel, val);
8336250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
8346250803fSAntoniu Miclaus 		return ad4851_set_oversampling_ratio(indio_dev, chan, val);
8356250803fSAntoniu Miclaus 	default:
8366250803fSAntoniu Miclaus 		return -EINVAL;
8376250803fSAntoniu Miclaus 	}
8386250803fSAntoniu Miclaus }
8396250803fSAntoniu Miclaus 
ad4851_update_scan_mode(struct iio_dev * indio_dev,const unsigned long * scan_mask)8406250803fSAntoniu Miclaus static int ad4851_update_scan_mode(struct iio_dev *indio_dev,
8416250803fSAntoniu Miclaus 				   const unsigned long *scan_mask)
8426250803fSAntoniu Miclaus {
8436250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
8446250803fSAntoniu Miclaus 	unsigned int c;
8456250803fSAntoniu Miclaus 	int ret;
8466250803fSAntoniu Miclaus 
8476250803fSAntoniu Miclaus 	for (c = 0; c < indio_dev->num_channels; c++) {
8486250803fSAntoniu Miclaus 		if (test_bit(c, scan_mask))
8496250803fSAntoniu Miclaus 			ret = iio_backend_chan_enable(st->back, c);
8506250803fSAntoniu Miclaus 		else
8516250803fSAntoniu Miclaus 			ret = iio_backend_chan_disable(st->back, c);
8526250803fSAntoniu Miclaus 		if (ret)
8536250803fSAntoniu Miclaus 			return ret;
8546250803fSAntoniu Miclaus 	}
8556250803fSAntoniu Miclaus 
8566250803fSAntoniu Miclaus 	return 0;
8576250803fSAntoniu Miclaus }
8586250803fSAntoniu Miclaus 
ad4851_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)8596250803fSAntoniu Miclaus static int ad4851_read_avail(struct iio_dev *indio_dev,
8606250803fSAntoniu Miclaus 			     struct iio_chan_spec const *chan,
8616250803fSAntoniu Miclaus 			     const int **vals, int *type, int *length,
8626250803fSAntoniu Miclaus 			     long mask)
8636250803fSAntoniu Miclaus {
8646250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
8656250803fSAntoniu Miclaus 
8666250803fSAntoniu Miclaus 	switch (mask) {
8676250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_SCALE:
8686250803fSAntoniu Miclaus 		if (st->bipolar_ch[chan->channel]) {
8696250803fSAntoniu Miclaus 			*vals = (const int *)st->scales_bipolar;
8706250803fSAntoniu Miclaus 			*type = IIO_VAL_INT_PLUS_MICRO;
8716250803fSAntoniu Miclaus 			/* Values are stored in a 2D matrix */
8726250803fSAntoniu Miclaus 			*length = ARRAY_SIZE(ad4851_scale_avail_bipolar) * 2;
8736250803fSAntoniu Miclaus 		} else {
8746250803fSAntoniu Miclaus 			*vals = (const int *)st->scales_unipolar;
8756250803fSAntoniu Miclaus 			*type = IIO_VAL_INT_PLUS_MICRO;
8766250803fSAntoniu Miclaus 			/* Values are stored in a 2D matrix */
8776250803fSAntoniu Miclaus 			*length = ARRAY_SIZE(ad4851_scale_avail_unipolar) * 2;
8786250803fSAntoniu Miclaus 		}
8796250803fSAntoniu Miclaus 		return IIO_AVAIL_LIST;
8806250803fSAntoniu Miclaus 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
8816250803fSAntoniu Miclaus 		*vals = ad4851_oversampling_ratios;
8826250803fSAntoniu Miclaus 		*length = ARRAY_SIZE(ad4851_oversampling_ratios);
8836250803fSAntoniu Miclaus 		*type = IIO_VAL_INT;
8846250803fSAntoniu Miclaus 		return IIO_AVAIL_LIST;
8856250803fSAntoniu Miclaus 	default:
8866250803fSAntoniu Miclaus 		return -EINVAL;
8876250803fSAntoniu Miclaus 	}
8886250803fSAntoniu Miclaus }
8896250803fSAntoniu Miclaus 
8906250803fSAntoniu Miclaus static const struct iio_scan_type ad4851_scan_type_20_u[] = {
8916250803fSAntoniu Miclaus 	[AD4851_SCAN_TYPE_NORMAL] = {
8926250803fSAntoniu Miclaus 		.sign = 'u',
8936250803fSAntoniu Miclaus 		.realbits = 20,
8946250803fSAntoniu Miclaus 		.storagebits = 32,
8956250803fSAntoniu Miclaus 	},
8966250803fSAntoniu Miclaus 	[AD4851_SCAN_TYPE_RESOLUTION_BOOST] = {
8976250803fSAntoniu Miclaus 		.sign = 'u',
8986250803fSAntoniu Miclaus 		.realbits = 24,
8996250803fSAntoniu Miclaus 		.storagebits = 32,
9006250803fSAntoniu Miclaus 	},
9016250803fSAntoniu Miclaus };
9026250803fSAntoniu Miclaus 
9036250803fSAntoniu Miclaus static const struct iio_scan_type ad4851_scan_type_20_b[] = {
9046250803fSAntoniu Miclaus 	[AD4851_SCAN_TYPE_NORMAL] = {
9056250803fSAntoniu Miclaus 		.sign = 's',
9066250803fSAntoniu Miclaus 		.realbits = 20,
9076250803fSAntoniu Miclaus 		.storagebits = 32,
9086250803fSAntoniu Miclaus 	},
9096250803fSAntoniu Miclaus 	[AD4851_SCAN_TYPE_RESOLUTION_BOOST] = {
9106250803fSAntoniu Miclaus 		.sign = 's',
9116250803fSAntoniu Miclaus 		.realbits = 24,
9126250803fSAntoniu Miclaus 		.storagebits = 32,
9136250803fSAntoniu Miclaus 	},
9146250803fSAntoniu Miclaus };
9156250803fSAntoniu Miclaus 
ad4851_get_current_scan_type(const struct iio_dev * indio_dev,const struct iio_chan_spec * chan)9166250803fSAntoniu Miclaus static int ad4851_get_current_scan_type(const struct iio_dev *indio_dev,
9176250803fSAntoniu Miclaus 					const struct iio_chan_spec *chan)
9186250803fSAntoniu Miclaus {
9196250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
9206250803fSAntoniu Miclaus 
9216250803fSAntoniu Miclaus 	return st->resolution_boost_enabled ? AD4851_SCAN_TYPE_RESOLUTION_BOOST
9226250803fSAntoniu Miclaus 					    : AD4851_SCAN_TYPE_NORMAL;
9236250803fSAntoniu Miclaus }
9246250803fSAntoniu Miclaus 
9256250803fSAntoniu Miclaus #define AD4851_IIO_CHANNEL							\
9266250803fSAntoniu Miclaus 	.type = IIO_VOLTAGE,							\
9276250803fSAntoniu Miclaus 	.info_mask_separate = BIT(IIO_CHAN_INFO_CALIBSCALE) |			\
9286250803fSAntoniu Miclaus 		BIT(IIO_CHAN_INFO_CALIBBIAS) |					\
9296250803fSAntoniu Miclaus 		BIT(IIO_CHAN_INFO_SCALE),					\
9306250803fSAntoniu Miclaus 	.info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE),		\
9316250803fSAntoniu Miclaus 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) |		\
9326250803fSAntoniu Miclaus 		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),				\
9336250803fSAntoniu Miclaus 	.info_mask_shared_by_all_available =					\
9346250803fSAntoniu Miclaus 		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),				\
9356250803fSAntoniu Miclaus 	.indexed = 1
9366250803fSAntoniu Miclaus 
9376250803fSAntoniu Miclaus /*
9386250803fSAntoniu Miclaus  * In case of AD4858_IIO_CHANNEL the scan_type is handled dynamically during the
9396250803fSAntoniu Miclaus  * parse_channels function.
9406250803fSAntoniu Miclaus  */
9416250803fSAntoniu Miclaus #define AD4858_IIO_CHANNEL							\
9426250803fSAntoniu Miclaus {										\
9436250803fSAntoniu Miclaus 	AD4851_IIO_CHANNEL							\
9446250803fSAntoniu Miclaus }
9456250803fSAntoniu Miclaus 
9466250803fSAntoniu Miclaus #define AD4857_IIO_CHANNEL							\
9476250803fSAntoniu Miclaus {										\
9486250803fSAntoniu Miclaus 	AD4851_IIO_CHANNEL,							\
9496250803fSAntoniu Miclaus 	.scan_type = {								\
9506250803fSAntoniu Miclaus 		.sign = 'u',							\
9516250803fSAntoniu Miclaus 		.realbits = 16,							\
9526250803fSAntoniu Miclaus 		.storagebits = 16,						\
9536250803fSAntoniu Miclaus 	},									\
9546250803fSAntoniu Miclaus }
9556250803fSAntoniu Miclaus 
ad4851_parse_channels_common(struct iio_dev * indio_dev,struct iio_chan_spec ** chans,const struct iio_chan_spec ad4851_chan)9566250803fSAntoniu Miclaus static int ad4851_parse_channels_common(struct iio_dev *indio_dev,
9576250803fSAntoniu Miclaus 					struct iio_chan_spec **chans,
9586250803fSAntoniu Miclaus 					const struct iio_chan_spec ad4851_chan)
9596250803fSAntoniu Miclaus {
9606250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
9616250803fSAntoniu Miclaus 	struct device *dev = &st->spi->dev;
9626250803fSAntoniu Miclaus 	struct iio_chan_spec *channels, *chan_start;
9636250803fSAntoniu Miclaus 	unsigned int num_channels, reg;
9646250803fSAntoniu Miclaus 	unsigned int index = 0;
9656250803fSAntoniu Miclaus 	int ret;
9666250803fSAntoniu Miclaus 
9676250803fSAntoniu Miclaus 	num_channels = device_get_child_node_count(dev);
9686250803fSAntoniu Miclaus 	if (num_channels > AD4851_MAX_CH_NR)
9696250803fSAntoniu Miclaus 		return dev_err_probe(dev, -EINVAL, "Too many channels: %u\n",
9706250803fSAntoniu Miclaus 				     num_channels);
9716250803fSAntoniu Miclaus 
9726250803fSAntoniu Miclaus 	channels = devm_kcalloc(dev, num_channels, sizeof(*channels), GFP_KERNEL);
9736250803fSAntoniu Miclaus 	if (!channels)
9746250803fSAntoniu Miclaus 		return -ENOMEM;
9756250803fSAntoniu Miclaus 
9766250803fSAntoniu Miclaus 	chan_start = channels;
9776250803fSAntoniu Miclaus 
9786250803fSAntoniu Miclaus 	device_for_each_child_node_scoped(dev, child) {
9796250803fSAntoniu Miclaus 		ret = fwnode_property_read_u32(child, "reg", &reg);
9806250803fSAntoniu Miclaus 		if (ret)
9816250803fSAntoniu Miclaus 			return dev_err_probe(dev, ret,
9826250803fSAntoniu Miclaus 					     "Missing channel number\n");
9836250803fSAntoniu Miclaus 		if (reg >= AD4851_MAX_CH_NR)
9846250803fSAntoniu Miclaus 			return dev_err_probe(dev, -EINVAL,
9856250803fSAntoniu Miclaus 					     "Invalid channel number\n");
9866250803fSAntoniu Miclaus 		*channels = ad4851_chan;
9876250803fSAntoniu Miclaus 		channels->scan_index = index++;
9886250803fSAntoniu Miclaus 		channels->channel = reg;
9896250803fSAntoniu Miclaus 
9906250803fSAntoniu Miclaus 		if (fwnode_property_present(child, "diff-channels")) {
9916250803fSAntoniu Miclaus 			channels->channel2 = reg + st->info->max_channels;
9926250803fSAntoniu Miclaus 			channels->differential = 1;
9936250803fSAntoniu Miclaus 		}
9946250803fSAntoniu Miclaus 
9956250803fSAntoniu Miclaus 		st->bipolar_ch[reg] = fwnode_property_read_bool(child, "bipolar");
9966250803fSAntoniu Miclaus 
9976250803fSAntoniu Miclaus 		if (st->bipolar_ch[reg]) {
9986250803fSAntoniu Miclaus 			channels->scan_type.sign = 's';
9996250803fSAntoniu Miclaus 		} else {
10006250803fSAntoniu Miclaus 			ret = regmap_write(st->regmap, AD4851_REG_CHX_SOFTSPAN(reg),
10016250803fSAntoniu Miclaus 					   AD4851_SOFTSPAN_0V_40V);
10026250803fSAntoniu Miclaus 			if (ret)
10036250803fSAntoniu Miclaus 				return ret;
10046250803fSAntoniu Miclaus 		}
10056250803fSAntoniu Miclaus 
10066250803fSAntoniu Miclaus 		channels++;
10076250803fSAntoniu Miclaus 	}
10086250803fSAntoniu Miclaus 
10096250803fSAntoniu Miclaus 	*chans = chan_start;
10106250803fSAntoniu Miclaus 
10116250803fSAntoniu Miclaus 	return num_channels;
10126250803fSAntoniu Miclaus }
10136250803fSAntoniu Miclaus 
ad4857_parse_channels(struct iio_dev * indio_dev)10146250803fSAntoniu Miclaus static int ad4857_parse_channels(struct iio_dev *indio_dev)
10156250803fSAntoniu Miclaus {
10166250803fSAntoniu Miclaus 	struct iio_chan_spec *ad4851_channels;
10176250803fSAntoniu Miclaus 	const struct iio_chan_spec ad4851_chan = AD4857_IIO_CHANNEL;
10186250803fSAntoniu Miclaus 	int ret;
10196250803fSAntoniu Miclaus 
10206250803fSAntoniu Miclaus 	ret = ad4851_parse_channels_common(indio_dev, &ad4851_channels,
10216250803fSAntoniu Miclaus 					   ad4851_chan);
10226250803fSAntoniu Miclaus 	if (ret < 0)
10236250803fSAntoniu Miclaus 		return ret;
10246250803fSAntoniu Miclaus 
10256250803fSAntoniu Miclaus 	indio_dev->channels = ad4851_channels;
10266250803fSAntoniu Miclaus 	indio_dev->num_channels = ret;
10276250803fSAntoniu Miclaus 
10286250803fSAntoniu Miclaus 	return 0;
10296250803fSAntoniu Miclaus }
10306250803fSAntoniu Miclaus 
ad4858_parse_channels(struct iio_dev * indio_dev)10316250803fSAntoniu Miclaus static int ad4858_parse_channels(struct iio_dev *indio_dev)
10326250803fSAntoniu Miclaus {
10336250803fSAntoniu Miclaus 	struct ad4851_state *st = iio_priv(indio_dev);
10346250803fSAntoniu Miclaus 	struct device *dev = &st->spi->dev;
10356250803fSAntoniu Miclaus 	struct iio_chan_spec *ad4851_channels;
10366250803fSAntoniu Miclaus 	const struct iio_chan_spec ad4851_chan = AD4858_IIO_CHANNEL;
1037*499a8ceeSAntoniu Miclaus 	int ret, i = 0;
10386250803fSAntoniu Miclaus 
10396250803fSAntoniu Miclaus 	ret = ad4851_parse_channels_common(indio_dev, &ad4851_channels,
10406250803fSAntoniu Miclaus 					   ad4851_chan);
10416250803fSAntoniu Miclaus 	if (ret < 0)
10426250803fSAntoniu Miclaus 		return ret;
10436250803fSAntoniu Miclaus 
10446250803fSAntoniu Miclaus 	device_for_each_child_node_scoped(dev, child) {
1045*499a8ceeSAntoniu Miclaus 		ad4851_channels[i].has_ext_scan_type = 1;
10466250803fSAntoniu Miclaus 		if (fwnode_property_read_bool(child, "bipolar")) {
1047*499a8ceeSAntoniu Miclaus 			ad4851_channels[i].ext_scan_type = ad4851_scan_type_20_b;
1048*499a8ceeSAntoniu Miclaus 			ad4851_channels[i].num_ext_scan_type = ARRAY_SIZE(ad4851_scan_type_20_b);
10496250803fSAntoniu Miclaus 		} else {
1050*499a8ceeSAntoniu Miclaus 			ad4851_channels[i].ext_scan_type = ad4851_scan_type_20_u;
1051*499a8ceeSAntoniu Miclaus 			ad4851_channels[i].num_ext_scan_type = ARRAY_SIZE(ad4851_scan_type_20_u);
10526250803fSAntoniu Miclaus 		}
1053*499a8ceeSAntoniu Miclaus 		i++;
10546250803fSAntoniu Miclaus 	}
10556250803fSAntoniu Miclaus 
10566250803fSAntoniu Miclaus 	indio_dev->channels = ad4851_channels;
10576250803fSAntoniu Miclaus 	indio_dev->num_channels = ret;
10586250803fSAntoniu Miclaus 
10596250803fSAntoniu Miclaus 	return 0;
10606250803fSAntoniu Miclaus }
10616250803fSAntoniu Miclaus 
10626250803fSAntoniu Miclaus /*
10636250803fSAntoniu Miclaus  * parse_channels() function handles the rest of the channel related attributes
10646250803fSAntoniu Miclaus  * that are usually are stored in the chip info structure.
10656250803fSAntoniu Miclaus  */
10666250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4851_info = {
10676250803fSAntoniu Miclaus 	.name = "ad4851",
10686250803fSAntoniu Miclaus 	.product_id = 0x67,
10696250803fSAntoniu Miclaus 	.max_sample_rate_hz = 250 * KILO,
10706250803fSAntoniu Miclaus 	.resolution = 16,
10716250803fSAntoniu Miclaus 	.max_channels = AD4851_MAX_CH_NR,
10726250803fSAntoniu Miclaus 	.parse_channels = ad4857_parse_channels,
10736250803fSAntoniu Miclaus };
10746250803fSAntoniu Miclaus 
10756250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4852_info = {
10766250803fSAntoniu Miclaus 	.name = "ad4852",
10776250803fSAntoniu Miclaus 	.product_id = 0x66,
10786250803fSAntoniu Miclaus 	.max_sample_rate_hz = 250 * KILO,
10796250803fSAntoniu Miclaus 	.resolution = 20,
10806250803fSAntoniu Miclaus 	.max_channels = AD4851_MAX_CH_NR,
10816250803fSAntoniu Miclaus 	.parse_channels = ad4858_parse_channels,
10826250803fSAntoniu Miclaus };
10836250803fSAntoniu Miclaus 
10846250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4853_info = {
10856250803fSAntoniu Miclaus 	.name = "ad4853",
10866250803fSAntoniu Miclaus 	.product_id = 0x65,
10876250803fSAntoniu Miclaus 	.max_sample_rate_hz = 1 * MEGA,
10886250803fSAntoniu Miclaus 	.resolution = 16,
10896250803fSAntoniu Miclaus 	.max_channels = AD4851_MAX_CH_NR,
10906250803fSAntoniu Miclaus 	.parse_channels = ad4857_parse_channels,
10916250803fSAntoniu Miclaus };
10926250803fSAntoniu Miclaus 
10936250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4854_info = {
10946250803fSAntoniu Miclaus 	.name = "ad4854",
10956250803fSAntoniu Miclaus 	.product_id = 0x64,
10966250803fSAntoniu Miclaus 	.max_sample_rate_hz = 1 * MEGA,
10976250803fSAntoniu Miclaus 	.resolution = 20,
10986250803fSAntoniu Miclaus 	.max_channels = AD4851_MAX_CH_NR,
10996250803fSAntoniu Miclaus 	.parse_channels = ad4858_parse_channels,
11006250803fSAntoniu Miclaus };
11016250803fSAntoniu Miclaus 
11026250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4855_info = {
11036250803fSAntoniu Miclaus 	.name = "ad4855",
11046250803fSAntoniu Miclaus 	.product_id = 0x63,
11056250803fSAntoniu Miclaus 	.max_sample_rate_hz = 250 * KILO,
11066250803fSAntoniu Miclaus 	.resolution = 16,
11076250803fSAntoniu Miclaus 	.max_channels = AD4851_MAX_CH_NR,
11086250803fSAntoniu Miclaus 	.parse_channels = ad4857_parse_channels,
11096250803fSAntoniu Miclaus };
11106250803fSAntoniu Miclaus 
11116250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4856_info = {
11126250803fSAntoniu Miclaus 	.name = "ad4856",
11136250803fSAntoniu Miclaus 	.product_id = 0x62,
11146250803fSAntoniu Miclaus 	.max_sample_rate_hz = 250 * KILO,
11156250803fSAntoniu Miclaus 	.resolution = 20,
11166250803fSAntoniu Miclaus 	.max_channels = AD4851_MAX_CH_NR,
11176250803fSAntoniu Miclaus 	.parse_channels = ad4858_parse_channels,
11186250803fSAntoniu Miclaus };
11196250803fSAntoniu Miclaus 
11206250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4857_info = {
11216250803fSAntoniu Miclaus 	.name = "ad4857",
11226250803fSAntoniu Miclaus 	.product_id = 0x61,
11236250803fSAntoniu Miclaus 	.max_sample_rate_hz = 1 * MEGA,
11246250803fSAntoniu Miclaus 	.resolution = 16,
11256250803fSAntoniu Miclaus 	.max_channels = AD4851_MAX_CH_NR,
11266250803fSAntoniu Miclaus 	.parse_channels = ad4857_parse_channels,
11276250803fSAntoniu Miclaus };
11286250803fSAntoniu Miclaus 
11296250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4858_info = {
11306250803fSAntoniu Miclaus 	.name = "ad4858",
11316250803fSAntoniu Miclaus 	.product_id = 0x60,
11326250803fSAntoniu Miclaus 	.max_sample_rate_hz = 1 * MEGA,
11336250803fSAntoniu Miclaus 	.resolution = 20,
11346250803fSAntoniu Miclaus 	.max_channels = AD4851_MAX_CH_NR,
11356250803fSAntoniu Miclaus 	.parse_channels = ad4858_parse_channels,
11366250803fSAntoniu Miclaus };
11376250803fSAntoniu Miclaus 
11386250803fSAntoniu Miclaus static const struct ad4851_chip_info ad4858i_info = {
11396250803fSAntoniu Miclaus 	.name = "ad4858i",
11406250803fSAntoniu Miclaus 	.product_id = 0x6F,
11416250803fSAntoniu Miclaus 	.max_sample_rate_hz = 1 * MEGA,
11426250803fSAntoniu Miclaus 	.resolution = 20,
11436250803fSAntoniu Miclaus 	.max_channels = AD4851_MAX_CH_NR,
11446250803fSAntoniu Miclaus 	.parse_channels = ad4858_parse_channels,
11456250803fSAntoniu Miclaus };
11466250803fSAntoniu Miclaus 
11476250803fSAntoniu Miclaus static const struct iio_info ad4851_iio_info = {
11486250803fSAntoniu Miclaus 	.debugfs_reg_access = ad4851_reg_access,
11496250803fSAntoniu Miclaus 	.read_raw = ad4851_read_raw,
11506250803fSAntoniu Miclaus 	.write_raw = ad4851_write_raw,
11516250803fSAntoniu Miclaus 	.update_scan_mode = ad4851_update_scan_mode,
11526250803fSAntoniu Miclaus 	.get_current_scan_type = ad4851_get_current_scan_type,
11536250803fSAntoniu Miclaus 	.read_avail = ad4851_read_avail,
11546250803fSAntoniu Miclaus };
11556250803fSAntoniu Miclaus 
11566250803fSAntoniu Miclaus static const struct regmap_config regmap_config = {
11576250803fSAntoniu Miclaus 	.reg_bits = 16,
11586250803fSAntoniu Miclaus 	.val_bits = 8,
11596250803fSAntoniu Miclaus 	.read_flag_mask = BIT(7),
11606250803fSAntoniu Miclaus };
11616250803fSAntoniu Miclaus 
11626250803fSAntoniu Miclaus static const char * const ad4851_power_supplies[] = {
11636250803fSAntoniu Miclaus 	"vcc",	"vdd", "vee", "vio",
11646250803fSAntoniu Miclaus };
11656250803fSAntoniu Miclaus 
ad4851_probe(struct spi_device * spi)11666250803fSAntoniu Miclaus static int ad4851_probe(struct spi_device *spi)
11676250803fSAntoniu Miclaus {
11686250803fSAntoniu Miclaus 	struct iio_dev *indio_dev;
11696250803fSAntoniu Miclaus 	struct device *dev = &spi->dev;
11706250803fSAntoniu Miclaus 	struct ad4851_state *st;
11716250803fSAntoniu Miclaus 	int ret;
11726250803fSAntoniu Miclaus 
11736250803fSAntoniu Miclaus 	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
11746250803fSAntoniu Miclaus 	if (!indio_dev)
11756250803fSAntoniu Miclaus 		return -ENOMEM;
11766250803fSAntoniu Miclaus 
11776250803fSAntoniu Miclaus 	st = iio_priv(indio_dev);
11786250803fSAntoniu Miclaus 	st->spi = spi;
11796250803fSAntoniu Miclaus 
11806250803fSAntoniu Miclaus 	ret = devm_mutex_init(dev, &st->lock);
11816250803fSAntoniu Miclaus 	if (ret)
11826250803fSAntoniu Miclaus 		return ret;
11836250803fSAntoniu Miclaus 
11846250803fSAntoniu Miclaus 	ret = devm_regulator_bulk_get_enable(dev,
11856250803fSAntoniu Miclaus 					     ARRAY_SIZE(ad4851_power_supplies),
11866250803fSAntoniu Miclaus 					     ad4851_power_supplies);
11876250803fSAntoniu Miclaus 	if (ret)
11886250803fSAntoniu Miclaus 		return dev_err_probe(dev, ret,
11896250803fSAntoniu Miclaus 				     "failed to get and enable supplies\n");
11906250803fSAntoniu Miclaus 
11916250803fSAntoniu Miclaus 	ret = devm_regulator_get_enable_optional(dev, "vddh");
11926250803fSAntoniu Miclaus 	if (ret < 0 && ret != -ENODEV)
11936250803fSAntoniu Miclaus 		return dev_err_probe(dev, ret, "failed to enable vddh voltage\n");
11946250803fSAntoniu Miclaus 
11956250803fSAntoniu Miclaus 	ret = devm_regulator_get_enable_optional(dev, "vddl");
11966250803fSAntoniu Miclaus 	if (ret < 0 && ret != -ENODEV)
11976250803fSAntoniu Miclaus 		return dev_err_probe(dev, ret, "failed to enable vddl voltage\n");
11986250803fSAntoniu Miclaus 
11996250803fSAntoniu Miclaus 	ret = devm_regulator_get_enable_optional(dev, "vrefbuf");
12006250803fSAntoniu Miclaus 	if (ret < 0 && ret != -ENODEV)
12016250803fSAntoniu Miclaus 		return dev_err_probe(dev, ret, "failed to enable vrefbuf voltage\n");
12026250803fSAntoniu Miclaus 
12036250803fSAntoniu Miclaus 	st->vrefbuf_en = ret != -ENODEV;
12046250803fSAntoniu Miclaus 
12056250803fSAntoniu Miclaus 	ret = devm_regulator_get_enable_optional(dev, "vrefio");
12066250803fSAntoniu Miclaus 	if (ret < 0 && ret != -ENODEV)
12076250803fSAntoniu Miclaus 		return dev_err_probe(dev, ret, "failed to enable vrefio voltage\n");
12086250803fSAntoniu Miclaus 
12096250803fSAntoniu Miclaus 	st->vrefio_en = ret != -ENODEV;
12106250803fSAntoniu Miclaus 
12116250803fSAntoniu Miclaus 	st->pd_gpio = devm_gpiod_get_optional(dev, "pd", GPIOD_OUT_LOW);
12126250803fSAntoniu Miclaus 	if (IS_ERR(st->pd_gpio))
12136250803fSAntoniu Miclaus 		return dev_err_probe(dev, PTR_ERR(st->pd_gpio),
12146250803fSAntoniu Miclaus 				     "Error on requesting pd GPIO\n");
12156250803fSAntoniu Miclaus 
12166250803fSAntoniu Miclaus 	st->cnv = devm_pwm_get(dev, NULL);
12176250803fSAntoniu Miclaus 	if (IS_ERR(st->cnv))
12186250803fSAntoniu Miclaus 		return dev_err_probe(dev, PTR_ERR(st->cnv),
12196250803fSAntoniu Miclaus 				     "Error on requesting pwm\n");
12206250803fSAntoniu Miclaus 
12216250803fSAntoniu Miclaus 	st->info = spi_get_device_match_data(spi);
12226250803fSAntoniu Miclaus 	if (!st->info)
12236250803fSAntoniu Miclaus 		return -ENODEV;
12246250803fSAntoniu Miclaus 
12256250803fSAntoniu Miclaus 	st->regmap = devm_regmap_init_spi(spi, &regmap_config);
12266250803fSAntoniu Miclaus 	if (IS_ERR(st->regmap))
12276250803fSAntoniu Miclaus 		return PTR_ERR(st->regmap);
12286250803fSAntoniu Miclaus 
12296250803fSAntoniu Miclaus 	ret = ad4851_set_sampling_freq(st, HZ_PER_MHZ);
12306250803fSAntoniu Miclaus 	if (ret)
12316250803fSAntoniu Miclaus 		return ret;
12326250803fSAntoniu Miclaus 
12336250803fSAntoniu Miclaus 	ret = devm_add_action_or_reset(&st->spi->dev, ad4851_pwm_disable,
12346250803fSAntoniu Miclaus 				       st->cnv);
12356250803fSAntoniu Miclaus 	if (ret)
12366250803fSAntoniu Miclaus 		return ret;
12376250803fSAntoniu Miclaus 
12386250803fSAntoniu Miclaus 	ret = ad4851_setup(st);
12396250803fSAntoniu Miclaus 	if (ret)
12406250803fSAntoniu Miclaus 		return ret;
12416250803fSAntoniu Miclaus 
12426250803fSAntoniu Miclaus 	indio_dev->name = st->info->name;
12436250803fSAntoniu Miclaus 	indio_dev->info = &ad4851_iio_info;
12446250803fSAntoniu Miclaus 	indio_dev->modes = INDIO_DIRECT_MODE;
12456250803fSAntoniu Miclaus 
12466250803fSAntoniu Miclaus 	ret = st->info->parse_channels(indio_dev);
12476250803fSAntoniu Miclaus 	if (ret)
12486250803fSAntoniu Miclaus 		return ret;
12496250803fSAntoniu Miclaus 
12506250803fSAntoniu Miclaus 	ret = ad4851_scale_fill(indio_dev);
12516250803fSAntoniu Miclaus 	if (ret)
12526250803fSAntoniu Miclaus 		return ret;
12536250803fSAntoniu Miclaus 
12546250803fSAntoniu Miclaus 	st->back = devm_iio_backend_get(dev, NULL);
12556250803fSAntoniu Miclaus 	if (IS_ERR(st->back))
12566250803fSAntoniu Miclaus 		return PTR_ERR(st->back);
12576250803fSAntoniu Miclaus 
12586250803fSAntoniu Miclaus 	ret = devm_iio_backend_request_buffer(dev, st->back, indio_dev);
12596250803fSAntoniu Miclaus 	if (ret)
12606250803fSAntoniu Miclaus 		return ret;
12616250803fSAntoniu Miclaus 
12626250803fSAntoniu Miclaus 	ret = devm_iio_backend_enable(dev, st->back);
12636250803fSAntoniu Miclaus 	if (ret)
12646250803fSAntoniu Miclaus 		return ret;
12656250803fSAntoniu Miclaus 
12666250803fSAntoniu Miclaus 	ret = ad4851_calibrate(indio_dev);
12676250803fSAntoniu Miclaus 	if (ret)
12686250803fSAntoniu Miclaus 		return ret;
12696250803fSAntoniu Miclaus 
12706250803fSAntoniu Miclaus 	return devm_iio_device_register(dev, indio_dev);
12716250803fSAntoniu Miclaus }
12726250803fSAntoniu Miclaus 
12736250803fSAntoniu Miclaus static const struct of_device_id ad4851_of_match[] = {
12746250803fSAntoniu Miclaus 	{ .compatible = "adi,ad4851", .data = &ad4851_info, },
12756250803fSAntoniu Miclaus 	{ .compatible = "adi,ad4852", .data = &ad4852_info, },
12766250803fSAntoniu Miclaus 	{ .compatible = "adi,ad4853", .data = &ad4853_info, },
12776250803fSAntoniu Miclaus 	{ .compatible = "adi,ad4854", .data = &ad4854_info, },
12786250803fSAntoniu Miclaus 	{ .compatible = "adi,ad4855", .data = &ad4855_info, },
12796250803fSAntoniu Miclaus 	{ .compatible = "adi,ad4856", .data = &ad4856_info, },
12806250803fSAntoniu Miclaus 	{ .compatible = "adi,ad4857", .data = &ad4857_info, },
12816250803fSAntoniu Miclaus 	{ .compatible = "adi,ad4858", .data = &ad4858_info, },
12826250803fSAntoniu Miclaus 	{ .compatible = "adi,ad4858i", .data = &ad4858i_info, },
12836250803fSAntoniu Miclaus 	{ }
12846250803fSAntoniu Miclaus };
12856250803fSAntoniu Miclaus 
12866250803fSAntoniu Miclaus static const struct spi_device_id ad4851_spi_id[] = {
12876250803fSAntoniu Miclaus 	{ "ad4851", (kernel_ulong_t)&ad4851_info },
12886250803fSAntoniu Miclaus 	{ "ad4852", (kernel_ulong_t)&ad4852_info },
12896250803fSAntoniu Miclaus 	{ "ad4853", (kernel_ulong_t)&ad4853_info },
12906250803fSAntoniu Miclaus 	{ "ad4854", (kernel_ulong_t)&ad4854_info },
12916250803fSAntoniu Miclaus 	{ "ad4855", (kernel_ulong_t)&ad4855_info },
12926250803fSAntoniu Miclaus 	{ "ad4856", (kernel_ulong_t)&ad4856_info },
12936250803fSAntoniu Miclaus 	{ "ad4857", (kernel_ulong_t)&ad4857_info },
12946250803fSAntoniu Miclaus 	{ "ad4858", (kernel_ulong_t)&ad4858_info },
12956250803fSAntoniu Miclaus 	{ "ad4858i", (kernel_ulong_t)&ad4858i_info },
12966250803fSAntoniu Miclaus 	{ }
12976250803fSAntoniu Miclaus };
12986250803fSAntoniu Miclaus MODULE_DEVICE_TABLE(spi, ad4851_spi_id);
12996250803fSAntoniu Miclaus 
13006250803fSAntoniu Miclaus static struct spi_driver ad4851_driver = {
13016250803fSAntoniu Miclaus 	.probe = ad4851_probe,
13026250803fSAntoniu Miclaus 	.driver = {
13036250803fSAntoniu Miclaus 		.name = "ad4851",
13046250803fSAntoniu Miclaus 		.of_match_table = ad4851_of_match,
13056250803fSAntoniu Miclaus 	},
13066250803fSAntoniu Miclaus 	.id_table = ad4851_spi_id,
13076250803fSAntoniu Miclaus };
13086250803fSAntoniu Miclaus module_spi_driver(ad4851_driver);
13096250803fSAntoniu Miclaus 
13106250803fSAntoniu Miclaus MODULE_AUTHOR("Sergiu Cuciurean <sergiu.cuciurean@analog.com>");
13116250803fSAntoniu Miclaus MODULE_AUTHOR("Dragos Bogdan <dragos.bogdan@analog.com>");
13126250803fSAntoniu Miclaus MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>");
13136250803fSAntoniu Miclaus MODULE_DESCRIPTION("Analog Devices AD4851 DAS driver");
13146250803fSAntoniu Miclaus MODULE_LICENSE("GPL");
13156250803fSAntoniu Miclaus MODULE_IMPORT_NS("IIO_BACKEND");
1316