xref: /openbmc/linux/drivers/iio/adc/ad4130.c (revision c595db6d7c8bcf87ef42204391fa890e5950e566)
162094060SCosmin Tanislav // SPDX-License-Identifier: GPL-2.0+
262094060SCosmin Tanislav /*
362094060SCosmin Tanislav  * Copyright (C) 2022 Analog Devices, Inc.
462094060SCosmin Tanislav  * Author: Cosmin Tanislav <cosmin.tanislav@analog.com>
562094060SCosmin Tanislav  */
662094060SCosmin Tanislav 
762094060SCosmin Tanislav #include <linux/bitfield.h>
862094060SCosmin Tanislav #include <linux/bitops.h>
962094060SCosmin Tanislav #include <linux/clk.h>
1062094060SCosmin Tanislav #include <linux/clk-provider.h>
1162094060SCosmin Tanislav #include <linux/delay.h>
1262094060SCosmin Tanislav #include <linux/device.h>
1362094060SCosmin Tanislav #include <linux/err.h>
1462094060SCosmin Tanislav #include <linux/gpio/driver.h>
1562094060SCosmin Tanislav #include <linux/interrupt.h>
1662094060SCosmin Tanislav #include <linux/irq.h>
1762094060SCosmin Tanislav #include <linux/kernel.h>
1862094060SCosmin Tanislav #include <linux/module.h>
1962094060SCosmin Tanislav #include <linux/property.h>
2062094060SCosmin Tanislav #include <linux/regmap.h>
2162094060SCosmin Tanislav #include <linux/regulator/consumer.h>
2262094060SCosmin Tanislav #include <linux/spi/spi.h>
2362094060SCosmin Tanislav #include <linux/units.h>
2462094060SCosmin Tanislav 
2562094060SCosmin Tanislav #include <asm/div64.h>
2662094060SCosmin Tanislav #include <asm/unaligned.h>
2762094060SCosmin Tanislav 
2862094060SCosmin Tanislav #include <linux/iio/buffer.h>
2962094060SCosmin Tanislav #include <linux/iio/iio.h>
3062094060SCosmin Tanislav #include <linux/iio/kfifo_buf.h>
3162094060SCosmin Tanislav #include <linux/iio/sysfs.h>
3262094060SCosmin Tanislav 
3362094060SCosmin Tanislav #define AD4130_NAME				"ad4130"
3462094060SCosmin Tanislav 
3562094060SCosmin Tanislav #define AD4130_COMMS_READ_MASK			BIT(6)
3662094060SCosmin Tanislav 
3762094060SCosmin Tanislav #define AD4130_STATUS_REG			0x00
3862094060SCosmin Tanislav 
3962094060SCosmin Tanislav #define AD4130_ADC_CONTROL_REG			0x01
4062094060SCosmin Tanislav #define AD4130_ADC_CONTROL_BIPOLAR_MASK		BIT(14)
4162094060SCosmin Tanislav #define AD4130_ADC_CONTROL_INT_REF_VAL_MASK	BIT(13)
4262094060SCosmin Tanislav #define AD4130_INT_REF_2_5V			2500000
4362094060SCosmin Tanislav #define AD4130_INT_REF_1_25V			1250000
4462094060SCosmin Tanislav #define AD4130_ADC_CONTROL_CSB_EN_MASK		BIT(9)
4562094060SCosmin Tanislav #define AD4130_ADC_CONTROL_INT_REF_EN_MASK	BIT(8)
4662094060SCosmin Tanislav #define AD4130_ADC_CONTROL_MODE_MASK		GENMASK(5, 2)
4762094060SCosmin Tanislav #define AD4130_ADC_CONTROL_MCLK_SEL_MASK	GENMASK(1, 0)
4862094060SCosmin Tanislav #define AD4130_MCLK_FREQ_76_8KHZ		76800
4962094060SCosmin Tanislav #define AD4130_MCLK_FREQ_153_6KHZ		153600
5062094060SCosmin Tanislav 
5162094060SCosmin Tanislav #define AD4130_DATA_REG				0x02
5262094060SCosmin Tanislav 
5362094060SCosmin Tanislav #define AD4130_IO_CONTROL_REG			0x03
5462094060SCosmin Tanislav #define AD4130_IO_CONTROL_INT_PIN_SEL_MASK	GENMASK(9, 8)
5562094060SCosmin Tanislav #define AD4130_IO_CONTROL_GPIO_DATA_MASK	GENMASK(7, 4)
5662094060SCosmin Tanislav #define AD4130_IO_CONTROL_GPIO_CTRL_MASK	GENMASK(3, 0)
5762094060SCosmin Tanislav 
5862094060SCosmin Tanislav #define AD4130_VBIAS_REG			0x04
5962094060SCosmin Tanislav 
6062094060SCosmin Tanislav #define AD4130_ID_REG				0x05
6162094060SCosmin Tanislav 
6262094060SCosmin Tanislav #define AD4130_ERROR_REG			0x06
6362094060SCosmin Tanislav 
6462094060SCosmin Tanislav #define AD4130_ERROR_EN_REG			0x07
6562094060SCosmin Tanislav 
6662094060SCosmin Tanislav #define AD4130_MCLK_COUNT_REG			0x08
6762094060SCosmin Tanislav 
6862094060SCosmin Tanislav #define AD4130_CHANNEL_X_REG(x)			(0x09 + (x))
6962094060SCosmin Tanislav #define AD4130_CHANNEL_EN_MASK			BIT(23)
7062094060SCosmin Tanislav #define AD4130_CHANNEL_SETUP_MASK		GENMASK(22, 20)
7162094060SCosmin Tanislav #define AD4130_CHANNEL_AINP_MASK		GENMASK(17, 13)
7262094060SCosmin Tanislav #define AD4130_CHANNEL_AINM_MASK		GENMASK(12, 8)
7362094060SCosmin Tanislav #define AD4130_CHANNEL_IOUT1_MASK		GENMASK(7, 4)
7462094060SCosmin Tanislav #define AD4130_CHANNEL_IOUT2_MASK		GENMASK(3, 0)
7562094060SCosmin Tanislav 
7662094060SCosmin Tanislav #define AD4130_CONFIG_X_REG(x)			(0x19 + (x))
7762094060SCosmin Tanislav #define AD4130_CONFIG_IOUT1_VAL_MASK		GENMASK(15, 13)
7862094060SCosmin Tanislav #define AD4130_CONFIG_IOUT2_VAL_MASK		GENMASK(12, 10)
7962094060SCosmin Tanislav #define AD4130_CONFIG_BURNOUT_MASK		GENMASK(9, 8)
8062094060SCosmin Tanislav #define AD4130_CONFIG_REF_BUFP_MASK		BIT(7)
8162094060SCosmin Tanislav #define AD4130_CONFIG_REF_BUFM_MASK		BIT(6)
8262094060SCosmin Tanislav #define AD4130_CONFIG_REF_SEL_MASK		GENMASK(5, 4)
8362094060SCosmin Tanislav #define AD4130_CONFIG_PGA_MASK			GENMASK(3, 1)
8462094060SCosmin Tanislav 
8562094060SCosmin Tanislav #define AD4130_FILTER_X_REG(x)			(0x21 + (x))
8662094060SCosmin Tanislav #define AD4130_FILTER_MODE_MASK			GENMASK(15, 12)
8762094060SCosmin Tanislav #define AD4130_FILTER_SELECT_MASK		GENMASK(10, 0)
8862094060SCosmin Tanislav #define AD4130_FILTER_SELECT_MIN		1
8962094060SCosmin Tanislav 
9062094060SCosmin Tanislav #define AD4130_OFFSET_X_REG(x)			(0x29 + (x))
9162094060SCosmin Tanislav 
9262094060SCosmin Tanislav #define AD4130_GAIN_X_REG(x)			(0x31 + (x))
9362094060SCosmin Tanislav 
9462094060SCosmin Tanislav #define AD4130_MISC_REG				0x39
9562094060SCosmin Tanislav 
9662094060SCosmin Tanislav #define AD4130_FIFO_CONTROL_REG			0x3a
9762094060SCosmin Tanislav #define AD4130_FIFO_CONTROL_HEADER_MASK		BIT(18)
9862094060SCosmin Tanislav #define AD4130_FIFO_CONTROL_MODE_MASK		GENMASK(17, 16)
9962094060SCosmin Tanislav #define AD4130_FIFO_CONTROL_WM_INT_EN_MASK	BIT(9)
10062094060SCosmin Tanislav #define AD4130_FIFO_CONTROL_WM_MASK		GENMASK(7, 0)
10162094060SCosmin Tanislav #define AD4130_WATERMARK_256			0
10262094060SCosmin Tanislav 
10362094060SCosmin Tanislav #define AD4130_FIFO_STATUS_REG			0x3b
10462094060SCosmin Tanislav 
10562094060SCosmin Tanislav #define AD4130_FIFO_THRESHOLD_REG		0x3c
10662094060SCosmin Tanislav 
10762094060SCosmin Tanislav #define AD4130_FIFO_DATA_REG			0x3d
10862094060SCosmin Tanislav #define AD4130_FIFO_SIZE			256
10962094060SCosmin Tanislav #define AD4130_FIFO_MAX_SAMPLE_SIZE		3
11062094060SCosmin Tanislav 
11162094060SCosmin Tanislav #define AD4130_MAX_ANALOG_PINS			16
11262094060SCosmin Tanislav #define AD4130_MAX_CHANNELS			16
11362094060SCosmin Tanislav #define AD4130_MAX_DIFF_INPUTS			30
11462094060SCosmin Tanislav #define AD4130_MAX_GPIOS			4
11562094060SCosmin Tanislav #define AD4130_MAX_ODR				2400
11662094060SCosmin Tanislav #define AD4130_MAX_PGA				8
11762094060SCosmin Tanislav #define AD4130_MAX_SETUPS			8
11862094060SCosmin Tanislav 
11962094060SCosmin Tanislav #define AD4130_AIN2_P1				0x2
12062094060SCosmin Tanislav #define AD4130_AIN3_P2				0x3
12162094060SCosmin Tanislav 
12262094060SCosmin Tanislav #define AD4130_RESET_BUF_SIZE			8
12362094060SCosmin Tanislav #define AD4130_RESET_SLEEP_US			(160 * MICRO / AD4130_MCLK_FREQ_76_8KHZ)
12462094060SCosmin Tanislav 
12562094060SCosmin Tanislav #define AD4130_INVALID_SLOT			-1
12662094060SCosmin Tanislav 
12762094060SCosmin Tanislav static const unsigned int ad4130_reg_size[] = {
12862094060SCosmin Tanislav 	[AD4130_STATUS_REG] = 1,
12962094060SCosmin Tanislav 	[AD4130_ADC_CONTROL_REG] = 2,
13062094060SCosmin Tanislav 	[AD4130_DATA_REG] = 3,
13162094060SCosmin Tanislav 	[AD4130_IO_CONTROL_REG] = 2,
13262094060SCosmin Tanislav 	[AD4130_VBIAS_REG] = 2,
13362094060SCosmin Tanislav 	[AD4130_ID_REG] = 1,
13462094060SCosmin Tanislav 	[AD4130_ERROR_REG] = 2,
13562094060SCosmin Tanislav 	[AD4130_ERROR_EN_REG] = 2,
13662094060SCosmin Tanislav 	[AD4130_MCLK_COUNT_REG] = 1,
13762094060SCosmin Tanislav 	[AD4130_CHANNEL_X_REG(0) ... AD4130_CHANNEL_X_REG(AD4130_MAX_CHANNELS - 1)] = 3,
13862094060SCosmin Tanislav 	[AD4130_CONFIG_X_REG(0) ... AD4130_CONFIG_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
13962094060SCosmin Tanislav 	[AD4130_FILTER_X_REG(0) ... AD4130_FILTER_X_REG(AD4130_MAX_SETUPS - 1)] = 3,
14062094060SCosmin Tanislav 	[AD4130_OFFSET_X_REG(0) ... AD4130_OFFSET_X_REG(AD4130_MAX_SETUPS - 1)] = 3,
14162094060SCosmin Tanislav 	[AD4130_GAIN_X_REG(0) ... AD4130_GAIN_X_REG(AD4130_MAX_SETUPS - 1)] = 3,
14262094060SCosmin Tanislav 	[AD4130_MISC_REG] = 2,
14362094060SCosmin Tanislav 	[AD4130_FIFO_CONTROL_REG] = 3,
14462094060SCosmin Tanislav 	[AD4130_FIFO_STATUS_REG] = 1,
14562094060SCosmin Tanislav 	[AD4130_FIFO_THRESHOLD_REG] = 3,
14662094060SCosmin Tanislav 	[AD4130_FIFO_DATA_REG] = 3,
14762094060SCosmin Tanislav };
14862094060SCosmin Tanislav 
14962094060SCosmin Tanislav enum ad4130_int_ref_val {
15062094060SCosmin Tanislav 	AD4130_INT_REF_VAL_2_5V,
15162094060SCosmin Tanislav 	AD4130_INT_REF_VAL_1_25V,
15262094060SCosmin Tanislav };
15362094060SCosmin Tanislav 
15462094060SCosmin Tanislav enum ad4130_mclk_sel {
15562094060SCosmin Tanislav 	AD4130_MCLK_76_8KHZ,
15662094060SCosmin Tanislav 	AD4130_MCLK_76_8KHZ_OUT,
15762094060SCosmin Tanislav 	AD4130_MCLK_76_8KHZ_EXT,
15862094060SCosmin Tanislav 	AD4130_MCLK_153_6KHZ_EXT,
15962094060SCosmin Tanislav };
16062094060SCosmin Tanislav 
16162094060SCosmin Tanislav enum ad4130_int_pin_sel {
16262094060SCosmin Tanislav 	AD4130_INT_PIN_INT,
16362094060SCosmin Tanislav 	AD4130_INT_PIN_CLK,
16462094060SCosmin Tanislav 	AD4130_INT_PIN_P2,
16562094060SCosmin Tanislav 	AD4130_INT_PIN_DOUT,
16662094060SCosmin Tanislav };
16762094060SCosmin Tanislav 
16862094060SCosmin Tanislav enum ad4130_iout {
16962094060SCosmin Tanislav 	AD4130_IOUT_OFF,
17062094060SCosmin Tanislav 	AD4130_IOUT_10000NA,
17162094060SCosmin Tanislav 	AD4130_IOUT_20000NA,
17262094060SCosmin Tanislav 	AD4130_IOUT_50000NA,
17362094060SCosmin Tanislav 	AD4130_IOUT_100000NA,
17462094060SCosmin Tanislav 	AD4130_IOUT_150000NA,
17562094060SCosmin Tanislav 	AD4130_IOUT_200000NA,
17662094060SCosmin Tanislav 	AD4130_IOUT_100NA,
17762094060SCosmin Tanislav 	AD4130_IOUT_MAX
17862094060SCosmin Tanislav };
17962094060SCosmin Tanislav 
18062094060SCosmin Tanislav enum ad4130_burnout {
18162094060SCosmin Tanislav 	AD4130_BURNOUT_OFF,
18262094060SCosmin Tanislav 	AD4130_BURNOUT_500NA,
18362094060SCosmin Tanislav 	AD4130_BURNOUT_2000NA,
18462094060SCosmin Tanislav 	AD4130_BURNOUT_4000NA,
18562094060SCosmin Tanislav 	AD4130_BURNOUT_MAX
18662094060SCosmin Tanislav };
18762094060SCosmin Tanislav 
18862094060SCosmin Tanislav enum ad4130_ref_sel {
18962094060SCosmin Tanislav 	AD4130_REF_REFIN1,
19062094060SCosmin Tanislav 	AD4130_REF_REFIN2,
19162094060SCosmin Tanislav 	AD4130_REF_REFOUT_AVSS,
19262094060SCosmin Tanislav 	AD4130_REF_AVDD_AVSS,
19362094060SCosmin Tanislav 	AD4130_REF_SEL_MAX
19462094060SCosmin Tanislav };
19562094060SCosmin Tanislav 
19662094060SCosmin Tanislav enum ad4130_fifo_mode {
19762094060SCosmin Tanislav 	AD4130_FIFO_MODE_DISABLED = 0b00,
19862094060SCosmin Tanislav 	AD4130_FIFO_MODE_WM = 0b01,
19962094060SCosmin Tanislav };
20062094060SCosmin Tanislav 
20162094060SCosmin Tanislav enum ad4130_mode {
20262094060SCosmin Tanislav 	AD4130_MODE_CONTINUOUS = 0b0000,
20362094060SCosmin Tanislav 	AD4130_MODE_IDLE = 0b0100,
20462094060SCosmin Tanislav };
20562094060SCosmin Tanislav 
20662094060SCosmin Tanislav enum ad4130_filter_mode {
20762094060SCosmin Tanislav 	AD4130_FILTER_SINC4,
20862094060SCosmin Tanislav 	AD4130_FILTER_SINC4_SINC1,
20962094060SCosmin Tanislav 	AD4130_FILTER_SINC3,
21062094060SCosmin Tanislav 	AD4130_FILTER_SINC3_REJ60,
21162094060SCosmin Tanislav 	AD4130_FILTER_SINC3_SINC1,
21262094060SCosmin Tanislav 	AD4130_FILTER_SINC3_PF1,
21362094060SCosmin Tanislav 	AD4130_FILTER_SINC3_PF2,
21462094060SCosmin Tanislav 	AD4130_FILTER_SINC3_PF3,
21562094060SCosmin Tanislav 	AD4130_FILTER_SINC3_PF4,
21662094060SCosmin Tanislav };
21762094060SCosmin Tanislav 
21862094060SCosmin Tanislav enum ad4130_pin_function {
21962094060SCosmin Tanislav 	AD4130_PIN_FN_NONE,
22062094060SCosmin Tanislav 	AD4130_PIN_FN_SPECIAL = BIT(0),
22162094060SCosmin Tanislav 	AD4130_PIN_FN_DIFF = BIT(1),
22262094060SCosmin Tanislav 	AD4130_PIN_FN_EXCITATION = BIT(2),
22362094060SCosmin Tanislav 	AD4130_PIN_FN_VBIAS = BIT(3),
22462094060SCosmin Tanislav };
22562094060SCosmin Tanislav 
22662094060SCosmin Tanislav struct ad4130_setup_info {
22762094060SCosmin Tanislav 	unsigned int			iout0_val;
22862094060SCosmin Tanislav 	unsigned int			iout1_val;
22962094060SCosmin Tanislav 	unsigned int			burnout;
23062094060SCosmin Tanislav 	unsigned int			pga;
23162094060SCosmin Tanislav 	unsigned int			fs;
23262094060SCosmin Tanislav 	u32				ref_sel;
23362094060SCosmin Tanislav 	enum ad4130_filter_mode		filter_mode;
23462094060SCosmin Tanislav 	bool				ref_bufp;
23562094060SCosmin Tanislav 	bool				ref_bufm;
23662094060SCosmin Tanislav };
23762094060SCosmin Tanislav 
23862094060SCosmin Tanislav struct ad4130_slot_info {
23962094060SCosmin Tanislav 	struct ad4130_setup_info	setup;
24062094060SCosmin Tanislav 	unsigned int			enabled_channels;
24162094060SCosmin Tanislav 	unsigned int			channels;
24262094060SCosmin Tanislav };
24362094060SCosmin Tanislav 
24462094060SCosmin Tanislav struct ad4130_chan_info {
24562094060SCosmin Tanislav 	struct ad4130_setup_info	setup;
24662094060SCosmin Tanislav 	u32				iout0;
24762094060SCosmin Tanislav 	u32				iout1;
24862094060SCosmin Tanislav 	int				slot;
24962094060SCosmin Tanislav 	bool				enabled;
25062094060SCosmin Tanislav 	bool				initialized;
25162094060SCosmin Tanislav };
25262094060SCosmin Tanislav 
25362094060SCosmin Tanislav struct ad4130_filter_config {
25462094060SCosmin Tanislav 	enum ad4130_filter_mode		filter_mode;
25562094060SCosmin Tanislav 	unsigned int			odr_div;
25662094060SCosmin Tanislav 	unsigned int			fs_max;
25762094060SCosmin Tanislav 	enum iio_available_type		samp_freq_avail_type;
25862094060SCosmin Tanislav 	int				samp_freq_avail_len;
25962094060SCosmin Tanislav 	int				samp_freq_avail[3][2];
26062094060SCosmin Tanislav };
26162094060SCosmin Tanislav 
26262094060SCosmin Tanislav struct ad4130_state {
26362094060SCosmin Tanislav 	struct regmap			*regmap;
26462094060SCosmin Tanislav 	struct spi_device		*spi;
26562094060SCosmin Tanislav 	struct clk			*mclk;
26662094060SCosmin Tanislav 	struct regulator_bulk_data	regulators[4];
26762094060SCosmin Tanislav 	u32				irq_trigger;
26862094060SCosmin Tanislav 	u32				inv_irq_trigger;
26962094060SCosmin Tanislav 
27062094060SCosmin Tanislav 	/*
27162094060SCosmin Tanislav 	 * Synchronize access to members the of driver state, and ensure
27262094060SCosmin Tanislav 	 * atomicity of consecutive regmap operations.
27362094060SCosmin Tanislav 	 */
27462094060SCosmin Tanislav 	struct mutex			lock;
27562094060SCosmin Tanislav 	struct completion		completion;
27662094060SCosmin Tanislav 
27762094060SCosmin Tanislav 	struct iio_chan_spec		chans[AD4130_MAX_CHANNELS];
27862094060SCosmin Tanislav 	struct ad4130_chan_info		chans_info[AD4130_MAX_CHANNELS];
27962094060SCosmin Tanislav 	struct ad4130_slot_info		slots_info[AD4130_MAX_SETUPS];
28062094060SCosmin Tanislav 	enum ad4130_pin_function	pins_fn[AD4130_MAX_ANALOG_PINS];
28162094060SCosmin Tanislav 	u32				vbias_pins[AD4130_MAX_ANALOG_PINS];
28262094060SCosmin Tanislav 	u32				num_vbias_pins;
28362094060SCosmin Tanislav 	int				scale_tbls[AD4130_REF_SEL_MAX][AD4130_MAX_PGA][2];
28462094060SCosmin Tanislav 	struct gpio_chip		gc;
28562094060SCosmin Tanislav 	struct clk_hw			int_clk_hw;
28662094060SCosmin Tanislav 
28762094060SCosmin Tanislav 	u32			int_pin_sel;
28862094060SCosmin Tanislav 	u32			int_ref_uv;
28962094060SCosmin Tanislav 	u32			mclk_sel;
29062094060SCosmin Tanislav 	bool			int_ref_en;
29162094060SCosmin Tanislav 	bool			bipolar;
29262094060SCosmin Tanislav 
29362094060SCosmin Tanislav 	unsigned int		num_enabled_channels;
29462094060SCosmin Tanislav 	unsigned int		effective_watermark;
29562094060SCosmin Tanislav 	unsigned int		watermark;
29662094060SCosmin Tanislav 
29762094060SCosmin Tanislav 	struct spi_message	fifo_msg;
29862094060SCosmin Tanislav 	struct spi_transfer	fifo_xfer[2];
29962094060SCosmin Tanislav 
30062094060SCosmin Tanislav 	/*
30162094060SCosmin Tanislav 	 * DMA (thus cache coherency maintenance) requires any transfer
30262094060SCosmin Tanislav 	 * buffers to live in their own cache lines. As the use of these
30362094060SCosmin Tanislav 	 * buffers is synchronous, all of the buffers used for DMA in this
30462094060SCosmin Tanislav 	 * driver may share a cache line.
30562094060SCosmin Tanislav 	 */
30662094060SCosmin Tanislav 	u8			reset_buf[AD4130_RESET_BUF_SIZE] __aligned(IIO_DMA_MINALIGN);
30762094060SCosmin Tanislav 	u8			reg_write_tx_buf[4];
30862094060SCosmin Tanislav 	u8			reg_read_tx_buf[1];
30962094060SCosmin Tanislav 	u8			reg_read_rx_buf[3];
31062094060SCosmin Tanislav 	u8			fifo_tx_buf[2];
31162094060SCosmin Tanislav 	u8			fifo_rx_buf[AD4130_FIFO_SIZE *
31262094060SCosmin Tanislav 					    AD4130_FIFO_MAX_SAMPLE_SIZE];
31362094060SCosmin Tanislav };
31462094060SCosmin Tanislav 
31562094060SCosmin Tanislav static const char * const ad4130_int_pin_names[] = {
31662094060SCosmin Tanislav 	[AD4130_INT_PIN_INT] = "int",
31762094060SCosmin Tanislav 	[AD4130_INT_PIN_CLK] = "clk",
31862094060SCosmin Tanislav 	[AD4130_INT_PIN_P2] = "p2",
31962094060SCosmin Tanislav 	[AD4130_INT_PIN_DOUT] = "dout",
32062094060SCosmin Tanislav };
32162094060SCosmin Tanislav 
32262094060SCosmin Tanislav static const unsigned int ad4130_iout_current_na_tbl[AD4130_IOUT_MAX] = {
32362094060SCosmin Tanislav 	[AD4130_IOUT_OFF] = 0,
32462094060SCosmin Tanislav 	[AD4130_IOUT_100NA] = 100,
32562094060SCosmin Tanislav 	[AD4130_IOUT_10000NA] = 10000,
32662094060SCosmin Tanislav 	[AD4130_IOUT_20000NA] = 20000,
32762094060SCosmin Tanislav 	[AD4130_IOUT_50000NA] = 50000,
32862094060SCosmin Tanislav 	[AD4130_IOUT_100000NA] = 100000,
32962094060SCosmin Tanislav 	[AD4130_IOUT_150000NA] = 150000,
33062094060SCosmin Tanislav 	[AD4130_IOUT_200000NA] = 200000,
33162094060SCosmin Tanislav };
33262094060SCosmin Tanislav 
33362094060SCosmin Tanislav static const unsigned int ad4130_burnout_current_na_tbl[AD4130_BURNOUT_MAX] = {
33462094060SCosmin Tanislav 	[AD4130_BURNOUT_OFF] = 0,
33562094060SCosmin Tanislav 	[AD4130_BURNOUT_500NA] = 500,
33662094060SCosmin Tanislav 	[AD4130_BURNOUT_2000NA] = 2000,
33762094060SCosmin Tanislav 	[AD4130_BURNOUT_4000NA] = 4000,
33862094060SCosmin Tanislav };
33962094060SCosmin Tanislav 
34062094060SCosmin Tanislav #define AD4130_VARIABLE_ODR_CONFIG(_filter_mode, _odr_div, _fs_max)	\
34162094060SCosmin Tanislav {									\
34262094060SCosmin Tanislav 		.filter_mode = (_filter_mode),				\
34362094060SCosmin Tanislav 		.odr_div = (_odr_div),					\
34462094060SCosmin Tanislav 		.fs_max = (_fs_max),					\
34562094060SCosmin Tanislav 		.samp_freq_avail_type = IIO_AVAIL_RANGE,		\
34662094060SCosmin Tanislav 		.samp_freq_avail = {					\
34762094060SCosmin Tanislav 			{ AD4130_MAX_ODR, (_odr_div) * (_fs_max) },	\
34862094060SCosmin Tanislav 			{ AD4130_MAX_ODR, (_odr_div) * (_fs_max) },	\
34962094060SCosmin Tanislav 			{ AD4130_MAX_ODR, (_odr_div) },			\
35062094060SCosmin Tanislav 		},							\
35162094060SCosmin Tanislav }
35262094060SCosmin Tanislav 
35362094060SCosmin Tanislav #define AD4130_FIXED_ODR_CONFIG(_filter_mode, _odr_div)			\
35462094060SCosmin Tanislav {									\
35562094060SCosmin Tanislav 		.filter_mode = (_filter_mode),				\
35662094060SCosmin Tanislav 		.odr_div = (_odr_div),					\
35762094060SCosmin Tanislav 		.fs_max = AD4130_FILTER_SELECT_MIN,			\
35862094060SCosmin Tanislav 		.samp_freq_avail_type = IIO_AVAIL_LIST,			\
35962094060SCosmin Tanislav 		.samp_freq_avail_len = 1,				\
36062094060SCosmin Tanislav 		.samp_freq_avail = {					\
36162094060SCosmin Tanislav 			{ AD4130_MAX_ODR, (_odr_div) },			\
36262094060SCosmin Tanislav 		},							\
36362094060SCosmin Tanislav }
36462094060SCosmin Tanislav 
36562094060SCosmin Tanislav static const struct ad4130_filter_config ad4130_filter_configs[] = {
36662094060SCosmin Tanislav 	AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC4,       1,  10),
36762094060SCosmin Tanislav 	AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC4_SINC1, 11, 10),
36862094060SCosmin Tanislav 	AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC3,       1,  2047),
36962094060SCosmin Tanislav 	AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC3_REJ60, 1,  2047),
37062094060SCosmin Tanislav 	AD4130_VARIABLE_ODR_CONFIG(AD4130_FILTER_SINC3_SINC1, 10, 2047),
37162094060SCosmin Tanislav 	AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF1,      92),
37262094060SCosmin Tanislav 	AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF2,      100),
37362094060SCosmin Tanislav 	AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF3,      124),
37462094060SCosmin Tanislav 	AD4130_FIXED_ODR_CONFIG(AD4130_FILTER_SINC3_PF4,      148),
37562094060SCosmin Tanislav };
37662094060SCosmin Tanislav 
37762094060SCosmin Tanislav static const char * const ad4130_filter_modes_str[] = {
37862094060SCosmin Tanislav 	[AD4130_FILTER_SINC4] = "sinc4",
37962094060SCosmin Tanislav 	[AD4130_FILTER_SINC4_SINC1] = "sinc4+sinc1",
38062094060SCosmin Tanislav 	[AD4130_FILTER_SINC3] = "sinc3",
38162094060SCosmin Tanislav 	[AD4130_FILTER_SINC3_REJ60] = "sinc3+rej60",
38262094060SCosmin Tanislav 	[AD4130_FILTER_SINC3_SINC1] = "sinc3+sinc1",
38362094060SCosmin Tanislav 	[AD4130_FILTER_SINC3_PF1] = "sinc3+pf1",
38462094060SCosmin Tanislav 	[AD4130_FILTER_SINC3_PF2] = "sinc3+pf2",
38562094060SCosmin Tanislav 	[AD4130_FILTER_SINC3_PF3] = "sinc3+pf3",
38662094060SCosmin Tanislav 	[AD4130_FILTER_SINC3_PF4] = "sinc3+pf4",
38762094060SCosmin Tanislav };
38862094060SCosmin Tanislav 
ad4130_get_reg_size(struct ad4130_state * st,unsigned int reg,unsigned int * size)38962094060SCosmin Tanislav static int ad4130_get_reg_size(struct ad4130_state *st, unsigned int reg,
39062094060SCosmin Tanislav 			       unsigned int *size)
39162094060SCosmin Tanislav {
39262094060SCosmin Tanislav 	if (reg >= ARRAY_SIZE(ad4130_reg_size))
39362094060SCosmin Tanislav 		return -EINVAL;
39462094060SCosmin Tanislav 
39562094060SCosmin Tanislav 	*size = ad4130_reg_size[reg];
39662094060SCosmin Tanislav 
39762094060SCosmin Tanislav 	return 0;
39862094060SCosmin Tanislav }
39962094060SCosmin Tanislav 
ad4130_data_reg_size(struct ad4130_state * st)40062094060SCosmin Tanislav static unsigned int ad4130_data_reg_size(struct ad4130_state *st)
40162094060SCosmin Tanislav {
40262094060SCosmin Tanislav 	unsigned int data_reg_size;
40362094060SCosmin Tanislav 	int ret;
40462094060SCosmin Tanislav 
40562094060SCosmin Tanislav 	ret = ad4130_get_reg_size(st, AD4130_DATA_REG, &data_reg_size);
40662094060SCosmin Tanislav 	if (ret)
40762094060SCosmin Tanislav 		return 0;
40862094060SCosmin Tanislav 
40962094060SCosmin Tanislav 	return data_reg_size;
41062094060SCosmin Tanislav }
41162094060SCosmin Tanislav 
ad4130_resolution(struct ad4130_state * st)41262094060SCosmin Tanislav static unsigned int ad4130_resolution(struct ad4130_state *st)
41362094060SCosmin Tanislav {
41462094060SCosmin Tanislav 	return ad4130_data_reg_size(st) * BITS_PER_BYTE;
41562094060SCosmin Tanislav }
41662094060SCosmin Tanislav 
ad4130_reg_write(void * context,unsigned int reg,unsigned int val)41762094060SCosmin Tanislav static int ad4130_reg_write(void *context, unsigned int reg, unsigned int val)
41862094060SCosmin Tanislav {
41962094060SCosmin Tanislav 	struct ad4130_state *st = context;
42062094060SCosmin Tanislav 	unsigned int size;
42162094060SCosmin Tanislav 	int ret;
42262094060SCosmin Tanislav 
42362094060SCosmin Tanislav 	ret = ad4130_get_reg_size(st, reg, &size);
42462094060SCosmin Tanislav 	if (ret)
42562094060SCosmin Tanislav 		return ret;
42662094060SCosmin Tanislav 
42762094060SCosmin Tanislav 	st->reg_write_tx_buf[0] = reg;
42862094060SCosmin Tanislav 
42962094060SCosmin Tanislav 	switch (size) {
43062094060SCosmin Tanislav 	case 3:
43162094060SCosmin Tanislav 		put_unaligned_be24(val, &st->reg_write_tx_buf[1]);
43262094060SCosmin Tanislav 		break;
43362094060SCosmin Tanislav 	case 2:
43462094060SCosmin Tanislav 		put_unaligned_be16(val, &st->reg_write_tx_buf[1]);
43562094060SCosmin Tanislav 		break;
43662094060SCosmin Tanislav 	case 1:
43762094060SCosmin Tanislav 		st->reg_write_tx_buf[1] = val;
43862094060SCosmin Tanislav 		break;
43962094060SCosmin Tanislav 	default:
44062094060SCosmin Tanislav 		return -EINVAL;
44162094060SCosmin Tanislav 	}
44262094060SCosmin Tanislav 
44362094060SCosmin Tanislav 	return spi_write(st->spi, st->reg_write_tx_buf, size + 1);
44462094060SCosmin Tanislav }
44562094060SCosmin Tanislav 
ad4130_reg_read(void * context,unsigned int reg,unsigned int * val)44662094060SCosmin Tanislav static int ad4130_reg_read(void *context, unsigned int reg, unsigned int *val)
44762094060SCosmin Tanislav {
44862094060SCosmin Tanislav 	struct ad4130_state *st = context;
44962094060SCosmin Tanislav 	struct spi_transfer t[] = {
45062094060SCosmin Tanislav 		{
45162094060SCosmin Tanislav 			.tx_buf = st->reg_read_tx_buf,
45262094060SCosmin Tanislav 			.len = sizeof(st->reg_read_tx_buf),
45362094060SCosmin Tanislav 		},
45462094060SCosmin Tanislav 		{
45562094060SCosmin Tanislav 			.rx_buf = st->reg_read_rx_buf,
45662094060SCosmin Tanislav 		},
45762094060SCosmin Tanislav 	};
45862094060SCosmin Tanislav 	unsigned int size;
45962094060SCosmin Tanislav 	int ret;
46062094060SCosmin Tanislav 
46162094060SCosmin Tanislav 	ret = ad4130_get_reg_size(st, reg, &size);
46262094060SCosmin Tanislav 	if (ret)
46362094060SCosmin Tanislav 		return ret;
46462094060SCosmin Tanislav 
46562094060SCosmin Tanislav 	st->reg_read_tx_buf[0] = AD4130_COMMS_READ_MASK | reg;
46662094060SCosmin Tanislav 	t[1].len = size;
46762094060SCosmin Tanislav 
46862094060SCosmin Tanislav 	ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
46962094060SCosmin Tanislav 	if (ret)
47062094060SCosmin Tanislav 		return ret;
47162094060SCosmin Tanislav 
47262094060SCosmin Tanislav 	switch (size) {
47362094060SCosmin Tanislav 	case 3:
47462094060SCosmin Tanislav 		*val = get_unaligned_be24(st->reg_read_rx_buf);
47562094060SCosmin Tanislav 		break;
47662094060SCosmin Tanislav 	case 2:
47762094060SCosmin Tanislav 		*val = get_unaligned_be16(st->reg_read_rx_buf);
47862094060SCosmin Tanislav 		break;
47962094060SCosmin Tanislav 	case 1:
48062094060SCosmin Tanislav 		*val = st->reg_read_rx_buf[0];
48162094060SCosmin Tanislav 		break;
48262094060SCosmin Tanislav 	default:
48362094060SCosmin Tanislav 		return -EINVAL;
48462094060SCosmin Tanislav 	}
48562094060SCosmin Tanislav 
48662094060SCosmin Tanislav 	return 0;
48762094060SCosmin Tanislav }
48862094060SCosmin Tanislav 
48962094060SCosmin Tanislav static const struct regmap_config ad4130_regmap_config = {
49062094060SCosmin Tanislav 	.reg_read = ad4130_reg_read,
49162094060SCosmin Tanislav 	.reg_write = ad4130_reg_write,
49262094060SCosmin Tanislav };
49362094060SCosmin Tanislav 
ad4130_gpio_init_valid_mask(struct gpio_chip * gc,unsigned long * valid_mask,unsigned int ngpios)49462094060SCosmin Tanislav static int ad4130_gpio_init_valid_mask(struct gpio_chip *gc,
49562094060SCosmin Tanislav 				       unsigned long *valid_mask,
49662094060SCosmin Tanislav 				       unsigned int ngpios)
49762094060SCosmin Tanislav {
49862094060SCosmin Tanislav 	struct ad4130_state *st = gpiochip_get_data(gc);
49962094060SCosmin Tanislav 	unsigned int i;
50062094060SCosmin Tanislav 
50162094060SCosmin Tanislav 	/*
50262094060SCosmin Tanislav 	 * Output-only GPIO functionality is available on pins AIN2 through
50362094060SCosmin Tanislav 	 * AIN5. If these pins are used for anything else, do not expose them.
50462094060SCosmin Tanislav 	 */
50562094060SCosmin Tanislav 	for (i = 0; i < ngpios; i++) {
50662094060SCosmin Tanislav 		unsigned int pin = i + AD4130_AIN2_P1;
50762094060SCosmin Tanislav 		bool valid = st->pins_fn[pin] == AD4130_PIN_FN_NONE;
50862094060SCosmin Tanislav 
50962094060SCosmin Tanislav 		__assign_bit(i, valid_mask, valid);
51062094060SCosmin Tanislav 	}
51162094060SCosmin Tanislav 
51262094060SCosmin Tanislav 	return 0;
51362094060SCosmin Tanislav }
51462094060SCosmin Tanislav 
ad4130_gpio_get_direction(struct gpio_chip * gc,unsigned int offset)51562094060SCosmin Tanislav static int ad4130_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
51662094060SCosmin Tanislav {
51762094060SCosmin Tanislav 	return GPIO_LINE_DIRECTION_OUT;
51862094060SCosmin Tanislav }
51962094060SCosmin Tanislav 
ad4130_gpio_set(struct gpio_chip * gc,unsigned int offset,int value)52062094060SCosmin Tanislav static void ad4130_gpio_set(struct gpio_chip *gc, unsigned int offset,
52162094060SCosmin Tanislav 			    int value)
52262094060SCosmin Tanislav {
52362094060SCosmin Tanislav 	struct ad4130_state *st = gpiochip_get_data(gc);
52462094060SCosmin Tanislav 	unsigned int mask = FIELD_PREP(AD4130_IO_CONTROL_GPIO_DATA_MASK,
52562094060SCosmin Tanislav 				       BIT(offset));
52662094060SCosmin Tanislav 
52762094060SCosmin Tanislav 	regmap_update_bits(st->regmap, AD4130_IO_CONTROL_REG, mask,
52862094060SCosmin Tanislav 			   value ? mask : 0);
52962094060SCosmin Tanislav }
53062094060SCosmin Tanislav 
ad4130_set_mode(struct ad4130_state * st,enum ad4130_mode mode)53162094060SCosmin Tanislav static int ad4130_set_mode(struct ad4130_state *st, enum ad4130_mode mode)
53262094060SCosmin Tanislav {
53362094060SCosmin Tanislav 	return regmap_update_bits(st->regmap, AD4130_ADC_CONTROL_REG,
53462094060SCosmin Tanislav 				  AD4130_ADC_CONTROL_MODE_MASK,
53562094060SCosmin Tanislav 				  FIELD_PREP(AD4130_ADC_CONTROL_MODE_MASK, mode));
53662094060SCosmin Tanislav }
53762094060SCosmin Tanislav 
ad4130_set_watermark_interrupt_en(struct ad4130_state * st,bool en)53862094060SCosmin Tanislav static int ad4130_set_watermark_interrupt_en(struct ad4130_state *st, bool en)
53962094060SCosmin Tanislav {
54062094060SCosmin Tanislav 	return regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG,
54162094060SCosmin Tanislav 				  AD4130_FIFO_CONTROL_WM_INT_EN_MASK,
54262094060SCosmin Tanislav 				  FIELD_PREP(AD4130_FIFO_CONTROL_WM_INT_EN_MASK, en));
54362094060SCosmin Tanislav }
54462094060SCosmin Tanislav 
ad4130_watermark_reg_val(unsigned int val)54562094060SCosmin Tanislav static unsigned int ad4130_watermark_reg_val(unsigned int val)
54662094060SCosmin Tanislav {
54762094060SCosmin Tanislav 	if (val == AD4130_FIFO_SIZE)
54862094060SCosmin Tanislav 		val = AD4130_WATERMARK_256;
54962094060SCosmin Tanislav 
55062094060SCosmin Tanislav 	return val;
55162094060SCosmin Tanislav }
55262094060SCosmin Tanislav 
ad4130_set_fifo_mode(struct ad4130_state * st,enum ad4130_fifo_mode mode)55362094060SCosmin Tanislav static int ad4130_set_fifo_mode(struct ad4130_state *st,
55462094060SCosmin Tanislav 				enum ad4130_fifo_mode mode)
55562094060SCosmin Tanislav {
55662094060SCosmin Tanislav 	return regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG,
55762094060SCosmin Tanislav 				  AD4130_FIFO_CONTROL_MODE_MASK,
55862094060SCosmin Tanislav 				  FIELD_PREP(AD4130_FIFO_CONTROL_MODE_MASK, mode));
55962094060SCosmin Tanislav }
56062094060SCosmin Tanislav 
ad4130_push_fifo_data(struct iio_dev * indio_dev)56162094060SCosmin Tanislav static void ad4130_push_fifo_data(struct iio_dev *indio_dev)
56262094060SCosmin Tanislav {
56362094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
56462094060SCosmin Tanislav 	unsigned int data_reg_size = ad4130_data_reg_size(st);
56562094060SCosmin Tanislav 	unsigned int transfer_len = st->effective_watermark * data_reg_size;
56662094060SCosmin Tanislav 	unsigned int set_size = st->num_enabled_channels * data_reg_size;
56762094060SCosmin Tanislav 	unsigned int i;
56862094060SCosmin Tanislav 	int ret;
56962094060SCosmin Tanislav 
57062094060SCosmin Tanislav 	st->fifo_tx_buf[1] = ad4130_watermark_reg_val(st->effective_watermark);
57162094060SCosmin Tanislav 	st->fifo_xfer[1].len = transfer_len;
57262094060SCosmin Tanislav 
57362094060SCosmin Tanislav 	ret = spi_sync(st->spi, &st->fifo_msg);
57462094060SCosmin Tanislav 	if (ret)
57562094060SCosmin Tanislav 		return;
57662094060SCosmin Tanislav 
57762094060SCosmin Tanislav 	for (i = 0; i < transfer_len; i += set_size)
57862094060SCosmin Tanislav 		iio_push_to_buffers(indio_dev, &st->fifo_rx_buf[i]);
57962094060SCosmin Tanislav }
58062094060SCosmin Tanislav 
ad4130_irq_handler(int irq,void * private)58162094060SCosmin Tanislav static irqreturn_t ad4130_irq_handler(int irq, void *private)
58262094060SCosmin Tanislav {
58362094060SCosmin Tanislav 	struct iio_dev *indio_dev = private;
58462094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
58562094060SCosmin Tanislav 
58662094060SCosmin Tanislav 	if (iio_buffer_enabled(indio_dev))
58762094060SCosmin Tanislav 		ad4130_push_fifo_data(indio_dev);
58862094060SCosmin Tanislav 	else
58962094060SCosmin Tanislav 		complete(&st->completion);
59062094060SCosmin Tanislav 
59162094060SCosmin Tanislav 	return IRQ_HANDLED;
59262094060SCosmin Tanislav }
59362094060SCosmin Tanislav 
ad4130_find_slot(struct ad4130_state * st,struct ad4130_setup_info * target_setup_info,unsigned int * slot,bool * overwrite)59462094060SCosmin Tanislav static int ad4130_find_slot(struct ad4130_state *st,
59562094060SCosmin Tanislav 			    struct ad4130_setup_info *target_setup_info,
59662094060SCosmin Tanislav 			    unsigned int *slot, bool *overwrite)
59762094060SCosmin Tanislav {
59862094060SCosmin Tanislav 	unsigned int i;
59962094060SCosmin Tanislav 
60062094060SCosmin Tanislav 	*slot = AD4130_INVALID_SLOT;
60162094060SCosmin Tanislav 	*overwrite = false;
60262094060SCosmin Tanislav 
60362094060SCosmin Tanislav 	for (i = 0; i < AD4130_MAX_SETUPS; i++) {
60462094060SCosmin Tanislav 		struct ad4130_slot_info *slot_info = &st->slots_info[i];
60562094060SCosmin Tanislav 
60662094060SCosmin Tanislav 		/* Immediately accept a matching setup info. */
60762094060SCosmin Tanislav 		if (!memcmp(target_setup_info, &slot_info->setup,
60862094060SCosmin Tanislav 			    sizeof(*target_setup_info))) {
60962094060SCosmin Tanislav 			*slot = i;
61062094060SCosmin Tanislav 			return 0;
61162094060SCosmin Tanislav 		}
61262094060SCosmin Tanislav 
61362094060SCosmin Tanislav 		/* Ignore all setups which are used by enabled channels. */
61462094060SCosmin Tanislav 		if (slot_info->enabled_channels)
61562094060SCosmin Tanislav 			continue;
61662094060SCosmin Tanislav 
61762094060SCosmin Tanislav 		/* Find the least used slot. */
61862094060SCosmin Tanislav 		if (*slot == AD4130_INVALID_SLOT ||
61962094060SCosmin Tanislav 		    slot_info->channels < st->slots_info[*slot].channels)
62062094060SCosmin Tanislav 			*slot = i;
62162094060SCosmin Tanislav 	}
62262094060SCosmin Tanislav 
62362094060SCosmin Tanislav 	if (*slot == AD4130_INVALID_SLOT)
62462094060SCosmin Tanislav 		return -EINVAL;
62562094060SCosmin Tanislav 
62662094060SCosmin Tanislav 	*overwrite = true;
62762094060SCosmin Tanislav 
62862094060SCosmin Tanislav 	return 0;
62962094060SCosmin Tanislav }
63062094060SCosmin Tanislav 
ad4130_unlink_channel(struct ad4130_state * st,unsigned int channel)63162094060SCosmin Tanislav static void ad4130_unlink_channel(struct ad4130_state *st, unsigned int channel)
63262094060SCosmin Tanislav {
63362094060SCosmin Tanislav 	struct ad4130_chan_info *chan_info = &st->chans_info[channel];
63462094060SCosmin Tanislav 	struct ad4130_slot_info *slot_info = &st->slots_info[chan_info->slot];
63562094060SCosmin Tanislav 
63662094060SCosmin Tanislav 	chan_info->slot = AD4130_INVALID_SLOT;
63762094060SCosmin Tanislav 	slot_info->channels--;
63862094060SCosmin Tanislav }
63962094060SCosmin Tanislav 
ad4130_unlink_slot(struct ad4130_state * st,unsigned int slot)64062094060SCosmin Tanislav static int ad4130_unlink_slot(struct ad4130_state *st, unsigned int slot)
64162094060SCosmin Tanislav {
64262094060SCosmin Tanislav 	unsigned int i;
64362094060SCosmin Tanislav 
64462094060SCosmin Tanislav 	for (i = 0; i < AD4130_MAX_CHANNELS; i++) {
64562094060SCosmin Tanislav 		struct ad4130_chan_info *chan_info = &st->chans_info[i];
64662094060SCosmin Tanislav 
64762094060SCosmin Tanislav 		if (!chan_info->initialized || chan_info->slot != slot)
64862094060SCosmin Tanislav 			continue;
64962094060SCosmin Tanislav 
65062094060SCosmin Tanislav 		ad4130_unlink_channel(st, i);
65162094060SCosmin Tanislav 	}
65262094060SCosmin Tanislav 
65362094060SCosmin Tanislav 	return 0;
65462094060SCosmin Tanislav }
65562094060SCosmin Tanislav 
ad4130_link_channel_slot(struct ad4130_state * st,unsigned int channel,unsigned int slot)65662094060SCosmin Tanislav static int ad4130_link_channel_slot(struct ad4130_state *st,
65762094060SCosmin Tanislav 				    unsigned int channel, unsigned int slot)
65862094060SCosmin Tanislav {
65962094060SCosmin Tanislav 	struct ad4130_slot_info *slot_info = &st->slots_info[slot];
66062094060SCosmin Tanislav 	struct ad4130_chan_info *chan_info = &st->chans_info[channel];
66162094060SCosmin Tanislav 	int ret;
66262094060SCosmin Tanislav 
66362094060SCosmin Tanislav 	ret = regmap_update_bits(st->regmap, AD4130_CHANNEL_X_REG(channel),
66462094060SCosmin Tanislav 				 AD4130_CHANNEL_SETUP_MASK,
66562094060SCosmin Tanislav 				 FIELD_PREP(AD4130_CHANNEL_SETUP_MASK, slot));
66662094060SCosmin Tanislav 	if (ret)
66762094060SCosmin Tanislav 		return ret;
66862094060SCosmin Tanislav 
66962094060SCosmin Tanislav 	chan_info->slot = slot;
67062094060SCosmin Tanislav 	slot_info->channels++;
67162094060SCosmin Tanislav 
67262094060SCosmin Tanislav 	return 0;
67362094060SCosmin Tanislav }
67462094060SCosmin Tanislav 
ad4130_write_slot_setup(struct ad4130_state * st,unsigned int slot,struct ad4130_setup_info * setup_info)67562094060SCosmin Tanislav static int ad4130_write_slot_setup(struct ad4130_state *st,
67662094060SCosmin Tanislav 				   unsigned int slot,
67762094060SCosmin Tanislav 				   struct ad4130_setup_info *setup_info)
67862094060SCosmin Tanislav {
67962094060SCosmin Tanislav 	unsigned int val;
68062094060SCosmin Tanislav 	int ret;
68162094060SCosmin Tanislav 
68262094060SCosmin Tanislav 	val = FIELD_PREP(AD4130_CONFIG_IOUT1_VAL_MASK, setup_info->iout0_val) |
68362094060SCosmin Tanislav 	      FIELD_PREP(AD4130_CONFIG_IOUT1_VAL_MASK, setup_info->iout1_val) |
68462094060SCosmin Tanislav 	      FIELD_PREP(AD4130_CONFIG_BURNOUT_MASK, setup_info->burnout) |
68562094060SCosmin Tanislav 	      FIELD_PREP(AD4130_CONFIG_REF_BUFP_MASK, setup_info->ref_bufp) |
68662094060SCosmin Tanislav 	      FIELD_PREP(AD4130_CONFIG_REF_BUFM_MASK, setup_info->ref_bufm) |
68762094060SCosmin Tanislav 	      FIELD_PREP(AD4130_CONFIG_REF_SEL_MASK, setup_info->ref_sel) |
68862094060SCosmin Tanislav 	      FIELD_PREP(AD4130_CONFIG_PGA_MASK, setup_info->pga);
68962094060SCosmin Tanislav 
69062094060SCosmin Tanislav 	ret = regmap_write(st->regmap, AD4130_CONFIG_X_REG(slot), val);
69162094060SCosmin Tanislav 	if (ret)
69262094060SCosmin Tanislav 		return ret;
69362094060SCosmin Tanislav 
69462094060SCosmin Tanislav 	val = FIELD_PREP(AD4130_FILTER_MODE_MASK, setup_info->filter_mode) |
69562094060SCosmin Tanislav 	      FIELD_PREP(AD4130_FILTER_SELECT_MASK, setup_info->fs);
69662094060SCosmin Tanislav 
69762094060SCosmin Tanislav 	ret = regmap_write(st->regmap, AD4130_FILTER_X_REG(slot), val);
69862094060SCosmin Tanislav 	if (ret)
69962094060SCosmin Tanislav 		return ret;
70062094060SCosmin Tanislav 
70162094060SCosmin Tanislav 	memcpy(&st->slots_info[slot].setup, setup_info, sizeof(*setup_info));
70262094060SCosmin Tanislav 
70362094060SCosmin Tanislav 	return 0;
70462094060SCosmin Tanislav }
70562094060SCosmin Tanislav 
ad4130_write_channel_setup(struct ad4130_state * st,unsigned int channel,bool on_enable)70662094060SCosmin Tanislav static int ad4130_write_channel_setup(struct ad4130_state *st,
70762094060SCosmin Tanislav 				      unsigned int channel, bool on_enable)
70862094060SCosmin Tanislav {
70962094060SCosmin Tanislav 	struct ad4130_chan_info *chan_info = &st->chans_info[channel];
71062094060SCosmin Tanislav 	struct ad4130_setup_info *setup_info = &chan_info->setup;
71162094060SCosmin Tanislav 	bool overwrite;
71262094060SCosmin Tanislav 	int slot;
71362094060SCosmin Tanislav 	int ret;
71462094060SCosmin Tanislav 
71562094060SCosmin Tanislav 	/*
71662094060SCosmin Tanislav 	 * The following cases need to be handled.
71762094060SCosmin Tanislav 	 *
71862094060SCosmin Tanislav 	 * 1. Enabled and linked channel with setup changes:
71962094060SCosmin Tanislav 	 *    - Find a slot. If not possible, return error.
72062094060SCosmin Tanislav 	 *    - Unlink channel from current slot.
72162094060SCosmin Tanislav 	 *    - If the slot has channels linked to it, unlink all channels, and
72262094060SCosmin Tanislav 	 *      write the new setup to it.
72362094060SCosmin Tanislav 	 *    - Link channel to new slot.
72462094060SCosmin Tanislav 	 *
72562094060SCosmin Tanislav 	 * 2. Soon to be enabled and unlinked channel:
72662094060SCosmin Tanislav 	 *    - Find a slot. If not possible, return error.
72762094060SCosmin Tanislav 	 *    - If the slot has channels linked to it, unlink all channels, and
72862094060SCosmin Tanislav 	 *      write the new setup to it.
72962094060SCosmin Tanislav 	 *    - Link channel to the slot.
73062094060SCosmin Tanislav 	 *
73162094060SCosmin Tanislav 	 * 3. Disabled and linked channel with setup changes:
73262094060SCosmin Tanislav 	 *    - Unlink channel from current slot.
73362094060SCosmin Tanislav 	 *
73462094060SCosmin Tanislav 	 * 4. Soon to be enabled and linked channel:
73562094060SCosmin Tanislav 	 * 5. Disabled and unlinked channel with setup changes:
73662094060SCosmin Tanislav 	 *    - Do nothing.
73762094060SCosmin Tanislav 	 */
73862094060SCosmin Tanislav 
73962094060SCosmin Tanislav 	/* Case 4 */
74062094060SCosmin Tanislav 	if (on_enable && chan_info->slot != AD4130_INVALID_SLOT)
74162094060SCosmin Tanislav 		return 0;
74262094060SCosmin Tanislav 
74362094060SCosmin Tanislav 	if (!on_enable && !chan_info->enabled) {
74462094060SCosmin Tanislav 		if (chan_info->slot != AD4130_INVALID_SLOT)
74562094060SCosmin Tanislav 			/* Case 3 */
74662094060SCosmin Tanislav 			ad4130_unlink_channel(st, channel);
74762094060SCosmin Tanislav 
74862094060SCosmin Tanislav 		/* Cases 3 & 5 */
74962094060SCosmin Tanislav 		return 0;
75062094060SCosmin Tanislav 	}
75162094060SCosmin Tanislav 
75262094060SCosmin Tanislav 	/* Cases 1 & 2 */
75362094060SCosmin Tanislav 	ret = ad4130_find_slot(st, setup_info, &slot, &overwrite);
75462094060SCosmin Tanislav 	if (ret)
75562094060SCosmin Tanislav 		return ret;
75662094060SCosmin Tanislav 
75762094060SCosmin Tanislav 	if (chan_info->slot != AD4130_INVALID_SLOT)
75862094060SCosmin Tanislav 		/* Case 1 */
75962094060SCosmin Tanislav 		ad4130_unlink_channel(st, channel);
76062094060SCosmin Tanislav 
76162094060SCosmin Tanislav 	if (overwrite) {
76262094060SCosmin Tanislav 		ret = ad4130_unlink_slot(st, slot);
76362094060SCosmin Tanislav 		if (ret)
76462094060SCosmin Tanislav 			return ret;
76562094060SCosmin Tanislav 
76662094060SCosmin Tanislav 		ret = ad4130_write_slot_setup(st, slot, setup_info);
76762094060SCosmin Tanislav 		if (ret)
76862094060SCosmin Tanislav 			return ret;
76962094060SCosmin Tanislav 	}
77062094060SCosmin Tanislav 
77162094060SCosmin Tanislav 	return ad4130_link_channel_slot(st, channel, slot);
77262094060SCosmin Tanislav }
77362094060SCosmin Tanislav 
ad4130_set_channel_enable(struct ad4130_state * st,unsigned int channel,bool status)77462094060SCosmin Tanislav static int ad4130_set_channel_enable(struct ad4130_state *st,
77562094060SCosmin Tanislav 				     unsigned int channel, bool status)
77662094060SCosmin Tanislav {
77762094060SCosmin Tanislav 	struct ad4130_chan_info *chan_info = &st->chans_info[channel];
77862094060SCosmin Tanislav 	struct ad4130_slot_info *slot_info;
77962094060SCosmin Tanislav 	int ret;
78062094060SCosmin Tanislav 
78162094060SCosmin Tanislav 	if (chan_info->enabled == status)
78262094060SCosmin Tanislav 		return 0;
78362094060SCosmin Tanislav 
78462094060SCosmin Tanislav 	if (status) {
78562094060SCosmin Tanislav 		ret = ad4130_write_channel_setup(st, channel, true);
78662094060SCosmin Tanislav 		if (ret)
78762094060SCosmin Tanislav 			return ret;
78862094060SCosmin Tanislav 	}
78962094060SCosmin Tanislav 
79062094060SCosmin Tanislav 	slot_info = &st->slots_info[chan_info->slot];
79162094060SCosmin Tanislav 
79262094060SCosmin Tanislav 	ret = regmap_update_bits(st->regmap, AD4130_CHANNEL_X_REG(channel),
79362094060SCosmin Tanislav 				 AD4130_CHANNEL_EN_MASK,
79462094060SCosmin Tanislav 				 FIELD_PREP(AD4130_CHANNEL_EN_MASK, status));
79562094060SCosmin Tanislav 	if (ret)
79662094060SCosmin Tanislav 		return ret;
79762094060SCosmin Tanislav 
79862094060SCosmin Tanislav 	slot_info->enabled_channels += status ? 1 : -1;
79962094060SCosmin Tanislav 	chan_info->enabled = status;
80062094060SCosmin Tanislav 
80162094060SCosmin Tanislav 	return 0;
80262094060SCosmin Tanislav }
80362094060SCosmin Tanislav 
80462094060SCosmin Tanislav /*
80562094060SCosmin Tanislav  * Table 58. FILTER_MODE_n bits and Filter Types of the datasheet describes
80662094060SCosmin Tanislav  * the relation between filter mode, ODR and FS.
80762094060SCosmin Tanislav  *
80862094060SCosmin Tanislav  * Notice that the max ODR of each filter mode is not necessarily the
80962094060SCosmin Tanislav  * absolute max ODR supported by the chip.
81062094060SCosmin Tanislav  *
81162094060SCosmin Tanislav  * The ODR divider is not explicitly specified, but it can be deduced based
81262094060SCosmin Tanislav  * on the ODR range of each filter mode.
81362094060SCosmin Tanislav  *
81462094060SCosmin Tanislav  * For example, for Sinc4+Sinc1, max ODR is 218.18. That means that the
81562094060SCosmin Tanislav  * absolute max ODR is divided by 11 to achieve the max ODR of this filter
81662094060SCosmin Tanislav  * mode.
81762094060SCosmin Tanislav  *
81862094060SCosmin Tanislav  * The formulas for converting between ODR and FS for a specific filter
81962094060SCosmin Tanislav  * mode can be deduced from the same table.
82062094060SCosmin Tanislav  *
82162094060SCosmin Tanislav  * Notice that FS = 1 actually means max ODR, and that ODR decreases by
82262094060SCosmin Tanislav  * (maximum ODR / maximum FS) for each increment of FS.
82362094060SCosmin Tanislav  *
82462094060SCosmin Tanislav  * odr = MAX_ODR / odr_div * (1 - (fs - 1) / fs_max) <=>
82562094060SCosmin Tanislav  * odr = MAX_ODR * (1 - (fs - 1) / fs_max) / odr_div <=>
82662094060SCosmin Tanislav  * odr = MAX_ODR * (1 - (fs - 1) / fs_max) / odr_div <=>
82762094060SCosmin Tanislav  * odr = MAX_ODR * (fs_max - fs + 1) / (fs_max * odr_div)
82862094060SCosmin Tanislav  * (used in ad4130_fs_to_freq)
82962094060SCosmin Tanislav  *
83062094060SCosmin Tanislav  * For the opposite formula, FS can be extracted from the last one.
83162094060SCosmin Tanislav  *
83262094060SCosmin Tanislav  * MAX_ODR * (fs_max - fs + 1) = fs_max * odr_div * odr <=>
83362094060SCosmin Tanislav  * fs_max - fs + 1 = fs_max * odr_div * odr / MAX_ODR <=>
83462094060SCosmin Tanislav  * fs = 1 + fs_max - fs_max * odr_div * odr / MAX_ODR
83562094060SCosmin Tanislav  * (used in ad4130_fs_to_freq)
83662094060SCosmin Tanislav  */
83762094060SCosmin Tanislav 
ad4130_freq_to_fs(enum ad4130_filter_mode filter_mode,int val,int val2,unsigned int * fs)83862094060SCosmin Tanislav static void ad4130_freq_to_fs(enum ad4130_filter_mode filter_mode,
83962094060SCosmin Tanislav 			      int val, int val2, unsigned int *fs)
84062094060SCosmin Tanislav {
84162094060SCosmin Tanislav 	const struct ad4130_filter_config *filter_config =
84262094060SCosmin Tanislav 		&ad4130_filter_configs[filter_mode];
84362094060SCosmin Tanislav 	u64 dividend, divisor;
84462094060SCosmin Tanislav 	int temp;
84562094060SCosmin Tanislav 
84662094060SCosmin Tanislav 	dividend = filter_config->fs_max * filter_config->odr_div *
84762094060SCosmin Tanislav 		   ((u64)val * NANO + val2);
84862094060SCosmin Tanislav 	divisor = (u64)AD4130_MAX_ODR * NANO;
84962094060SCosmin Tanislav 
85062094060SCosmin Tanislav 	temp = AD4130_FILTER_SELECT_MIN + filter_config->fs_max -
85162094060SCosmin Tanislav 	       DIV64_U64_ROUND_CLOSEST(dividend, divisor);
85262094060SCosmin Tanislav 
85362094060SCosmin Tanislav 	if (temp < AD4130_FILTER_SELECT_MIN)
85462094060SCosmin Tanislav 		temp = AD4130_FILTER_SELECT_MIN;
85562094060SCosmin Tanislav 	else if (temp > filter_config->fs_max)
85662094060SCosmin Tanislav 		temp = filter_config->fs_max;
85762094060SCosmin Tanislav 
85862094060SCosmin Tanislav 	*fs = temp;
85962094060SCosmin Tanislav }
86062094060SCosmin Tanislav 
ad4130_fs_to_freq(enum ad4130_filter_mode filter_mode,unsigned int fs,int * val,int * val2)86162094060SCosmin Tanislav static void ad4130_fs_to_freq(enum ad4130_filter_mode filter_mode,
86262094060SCosmin Tanislav 			      unsigned int fs, int *val, int *val2)
86362094060SCosmin Tanislav {
86462094060SCosmin Tanislav 	const struct ad4130_filter_config *filter_config =
86562094060SCosmin Tanislav 		&ad4130_filter_configs[filter_mode];
86662094060SCosmin Tanislav 	unsigned int dividend, divisor;
86762094060SCosmin Tanislav 	u64 temp;
86862094060SCosmin Tanislav 
86962094060SCosmin Tanislav 	dividend = (filter_config->fs_max - fs + AD4130_FILTER_SELECT_MIN) *
87062094060SCosmin Tanislav 		   AD4130_MAX_ODR;
87162094060SCosmin Tanislav 	divisor = filter_config->fs_max * filter_config->odr_div;
87262094060SCosmin Tanislav 
87362094060SCosmin Tanislav 	temp = div_u64((u64)dividend * NANO, divisor);
87462094060SCosmin Tanislav 	*val = div_u64_rem(temp, NANO, val2);
87562094060SCosmin Tanislav }
87662094060SCosmin Tanislav 
ad4130_set_filter_mode(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,unsigned int val)87762094060SCosmin Tanislav static int ad4130_set_filter_mode(struct iio_dev *indio_dev,
87862094060SCosmin Tanislav 				  const struct iio_chan_spec *chan,
87962094060SCosmin Tanislav 				  unsigned int val)
88062094060SCosmin Tanislav {
88162094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
88262094060SCosmin Tanislav 	unsigned int channel = chan->scan_index;
88362094060SCosmin Tanislav 	struct ad4130_chan_info *chan_info = &st->chans_info[channel];
88462094060SCosmin Tanislav 	struct ad4130_setup_info *setup_info = &chan_info->setup;
88562094060SCosmin Tanislav 	enum ad4130_filter_mode old_filter_mode;
88662094060SCosmin Tanislav 	int freq_val, freq_val2;
88762094060SCosmin Tanislav 	unsigned int old_fs;
88862094060SCosmin Tanislav 	int ret = 0;
88962094060SCosmin Tanislav 
89062094060SCosmin Tanislav 	mutex_lock(&st->lock);
89162094060SCosmin Tanislav 	if (setup_info->filter_mode == val)
89262094060SCosmin Tanislav 		goto out;
89362094060SCosmin Tanislav 
89462094060SCosmin Tanislav 	old_fs = setup_info->fs;
89562094060SCosmin Tanislav 	old_filter_mode = setup_info->filter_mode;
89662094060SCosmin Tanislav 
89762094060SCosmin Tanislav 	/*
89862094060SCosmin Tanislav 	 * When switching between filter modes, try to match the ODR as
89962094060SCosmin Tanislav 	 * close as possible. To do this, convert the current FS into ODR
90062094060SCosmin Tanislav 	 * using the old filter mode, then convert it back into FS using
90162094060SCosmin Tanislav 	 * the new filter mode.
90262094060SCosmin Tanislav 	 */
90362094060SCosmin Tanislav 	ad4130_fs_to_freq(setup_info->filter_mode, setup_info->fs,
90462094060SCosmin Tanislav 			  &freq_val, &freq_val2);
90562094060SCosmin Tanislav 
90662094060SCosmin Tanislav 	ad4130_freq_to_fs(val, freq_val, freq_val2, &setup_info->fs);
90762094060SCosmin Tanislav 
90862094060SCosmin Tanislav 	setup_info->filter_mode = val;
90962094060SCosmin Tanislav 
91062094060SCosmin Tanislav 	ret = ad4130_write_channel_setup(st, channel, false);
91162094060SCosmin Tanislav 	if (ret) {
91262094060SCosmin Tanislav 		setup_info->fs = old_fs;
91362094060SCosmin Tanislav 		setup_info->filter_mode = old_filter_mode;
91462094060SCosmin Tanislav 	}
91562094060SCosmin Tanislav 
91662094060SCosmin Tanislav  out:
91762094060SCosmin Tanislav 	mutex_unlock(&st->lock);
91862094060SCosmin Tanislav 
91962094060SCosmin Tanislav 	return ret;
92062094060SCosmin Tanislav }
92162094060SCosmin Tanislav 
ad4130_get_filter_mode(struct iio_dev * indio_dev,const struct iio_chan_spec * chan)92262094060SCosmin Tanislav static int ad4130_get_filter_mode(struct iio_dev *indio_dev,
92362094060SCosmin Tanislav 				  const struct iio_chan_spec *chan)
92462094060SCosmin Tanislav {
92562094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
92662094060SCosmin Tanislav 	unsigned int channel = chan->scan_index;
92762094060SCosmin Tanislav 	struct ad4130_setup_info *setup_info = &st->chans_info[channel].setup;
92862094060SCosmin Tanislav 	enum ad4130_filter_mode filter_mode;
92962094060SCosmin Tanislav 
93062094060SCosmin Tanislav 	mutex_lock(&st->lock);
93162094060SCosmin Tanislav 	filter_mode = setup_info->filter_mode;
93262094060SCosmin Tanislav 	mutex_unlock(&st->lock);
93362094060SCosmin Tanislav 
93462094060SCosmin Tanislav 	return filter_mode;
93562094060SCosmin Tanislav }
93662094060SCosmin Tanislav 
93762094060SCosmin Tanislav static const struct iio_enum ad4130_filter_mode_enum = {
93862094060SCosmin Tanislav 	.items = ad4130_filter_modes_str,
93962094060SCosmin Tanislav 	.num_items = ARRAY_SIZE(ad4130_filter_modes_str),
94062094060SCosmin Tanislav 	.set = ad4130_set_filter_mode,
94162094060SCosmin Tanislav 	.get = ad4130_get_filter_mode,
94262094060SCosmin Tanislav };
94362094060SCosmin Tanislav 
94462094060SCosmin Tanislav static const struct iio_chan_spec_ext_info ad4130_filter_mode_ext_info[] = {
94562094060SCosmin Tanislav 	IIO_ENUM("filter_mode", IIO_SEPARATE, &ad4130_filter_mode_enum),
94662094060SCosmin Tanislav 	IIO_ENUM_AVAILABLE("filter_mode", IIO_SHARED_BY_TYPE,
94762094060SCosmin Tanislav 			   &ad4130_filter_mode_enum),
94862094060SCosmin Tanislav 	{ }
94962094060SCosmin Tanislav };
95062094060SCosmin Tanislav 
95162094060SCosmin Tanislav static const struct iio_chan_spec ad4130_channel_template = {
95262094060SCosmin Tanislav 	.type = IIO_VOLTAGE,
95362094060SCosmin Tanislav 	.indexed = 1,
95462094060SCosmin Tanislav 	.differential = 1,
95562094060SCosmin Tanislav 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
95662094060SCosmin Tanislav 			      BIT(IIO_CHAN_INFO_SCALE) |
95762094060SCosmin Tanislav 			      BIT(IIO_CHAN_INFO_OFFSET) |
95862094060SCosmin Tanislav 			      BIT(IIO_CHAN_INFO_SAMP_FREQ),
95962094060SCosmin Tanislav 	.info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE) |
96062094060SCosmin Tanislav 					BIT(IIO_CHAN_INFO_SAMP_FREQ),
96162094060SCosmin Tanislav 	.ext_info = ad4130_filter_mode_ext_info,
96262094060SCosmin Tanislav 	.scan_type = {
96362094060SCosmin Tanislav 		.sign = 'u',
96462094060SCosmin Tanislav 		.endianness = IIO_BE,
96562094060SCosmin Tanislav 	},
96662094060SCosmin Tanislav };
96762094060SCosmin Tanislav 
ad4130_set_channel_pga(struct ad4130_state * st,unsigned int channel,int val,int val2)96862094060SCosmin Tanislav static int ad4130_set_channel_pga(struct ad4130_state *st, unsigned int channel,
96962094060SCosmin Tanislav 				  int val, int val2)
97062094060SCosmin Tanislav {
97162094060SCosmin Tanislav 	struct ad4130_chan_info *chan_info = &st->chans_info[channel];
97262094060SCosmin Tanislav 	struct ad4130_setup_info *setup_info = &chan_info->setup;
97362094060SCosmin Tanislav 	unsigned int pga, old_pga;
97462094060SCosmin Tanislav 	int ret = 0;
97562094060SCosmin Tanislav 
97662094060SCosmin Tanislav 	for (pga = 0; pga < AD4130_MAX_PGA; pga++)
97762094060SCosmin Tanislav 		if (val == st->scale_tbls[setup_info->ref_sel][pga][0] &&
97862094060SCosmin Tanislav 		    val2 == st->scale_tbls[setup_info->ref_sel][pga][1])
97962094060SCosmin Tanislav 			break;
98062094060SCosmin Tanislav 
98162094060SCosmin Tanislav 	if (pga == AD4130_MAX_PGA)
98262094060SCosmin Tanislav 		return -EINVAL;
98362094060SCosmin Tanislav 
98462094060SCosmin Tanislav 	mutex_lock(&st->lock);
98562094060SCosmin Tanislav 	if (pga == setup_info->pga)
98662094060SCosmin Tanislav 		goto out;
98762094060SCosmin Tanislav 
98862094060SCosmin Tanislav 	old_pga = setup_info->pga;
98962094060SCosmin Tanislav 	setup_info->pga = pga;
99062094060SCosmin Tanislav 
99162094060SCosmin Tanislav 	ret = ad4130_write_channel_setup(st, channel, false);
99262094060SCosmin Tanislav 	if (ret)
99362094060SCosmin Tanislav 		setup_info->pga = old_pga;
99462094060SCosmin Tanislav 
99562094060SCosmin Tanislav out:
99662094060SCosmin Tanislav 	mutex_unlock(&st->lock);
99762094060SCosmin Tanislav 
99862094060SCosmin Tanislav 	return ret;
99962094060SCosmin Tanislav }
100062094060SCosmin Tanislav 
ad4130_set_channel_freq(struct ad4130_state * st,unsigned int channel,int val,int val2)100162094060SCosmin Tanislav static int ad4130_set_channel_freq(struct ad4130_state *st,
100262094060SCosmin Tanislav 				   unsigned int channel, int val, int val2)
100362094060SCosmin Tanislav {
100462094060SCosmin Tanislav 	struct ad4130_chan_info *chan_info = &st->chans_info[channel];
100562094060SCosmin Tanislav 	struct ad4130_setup_info *setup_info = &chan_info->setup;
100662094060SCosmin Tanislav 	unsigned int fs, old_fs;
100762094060SCosmin Tanislav 	int ret = 0;
100862094060SCosmin Tanislav 
100962094060SCosmin Tanislav 	mutex_lock(&st->lock);
101062094060SCosmin Tanislav 	old_fs = setup_info->fs;
101162094060SCosmin Tanislav 
101262094060SCosmin Tanislav 	ad4130_freq_to_fs(setup_info->filter_mode, val, val2, &fs);
101362094060SCosmin Tanislav 
101462094060SCosmin Tanislav 	if (fs == setup_info->fs)
101562094060SCosmin Tanislav 		goto out;
101662094060SCosmin Tanislav 
101762094060SCosmin Tanislav 	setup_info->fs = fs;
101862094060SCosmin Tanislav 
101962094060SCosmin Tanislav 	ret = ad4130_write_channel_setup(st, channel, false);
102062094060SCosmin Tanislav 	if (ret)
102162094060SCosmin Tanislav 		setup_info->fs = old_fs;
102262094060SCosmin Tanislav 
102362094060SCosmin Tanislav out:
102462094060SCosmin Tanislav 	mutex_unlock(&st->lock);
102562094060SCosmin Tanislav 
102662094060SCosmin Tanislav 	return ret;
102762094060SCosmin Tanislav }
102862094060SCosmin Tanislav 
_ad4130_read_sample(struct iio_dev * indio_dev,unsigned int channel,int * val)102962094060SCosmin Tanislav static int _ad4130_read_sample(struct iio_dev *indio_dev, unsigned int channel,
103062094060SCosmin Tanislav 			       int *val)
103162094060SCosmin Tanislav {
103262094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
103362094060SCosmin Tanislav 	int ret;
103462094060SCosmin Tanislav 
103562094060SCosmin Tanislav 	ret = ad4130_set_channel_enable(st, channel, true);
103662094060SCosmin Tanislav 	if (ret)
103762094060SCosmin Tanislav 		return ret;
103862094060SCosmin Tanislav 
103962094060SCosmin Tanislav 	reinit_completion(&st->completion);
104062094060SCosmin Tanislav 
104162094060SCosmin Tanislav 	ret = ad4130_set_mode(st, AD4130_MODE_CONTINUOUS);
104262094060SCosmin Tanislav 	if (ret)
104362094060SCosmin Tanislav 		return ret;
104462094060SCosmin Tanislav 
104562094060SCosmin Tanislav 	ret = wait_for_completion_timeout(&st->completion,
104662094060SCosmin Tanislav 					  msecs_to_jiffies(1000));
104762094060SCosmin Tanislav 	if (!ret)
104862094060SCosmin Tanislav 		return -ETIMEDOUT;
104962094060SCosmin Tanislav 
105062094060SCosmin Tanislav 	ret = ad4130_set_mode(st, AD4130_MODE_IDLE);
105162094060SCosmin Tanislav 	if (ret)
105262094060SCosmin Tanislav 		return ret;
105362094060SCosmin Tanislav 
105462094060SCosmin Tanislav 	ret = regmap_read(st->regmap, AD4130_DATA_REG, val);
105562094060SCosmin Tanislav 	if (ret)
105662094060SCosmin Tanislav 		return ret;
105762094060SCosmin Tanislav 
105862094060SCosmin Tanislav 	ret = ad4130_set_channel_enable(st, channel, false);
105962094060SCosmin Tanislav 	if (ret)
106062094060SCosmin Tanislav 		return ret;
106162094060SCosmin Tanislav 
106262094060SCosmin Tanislav 	return IIO_VAL_INT;
106362094060SCosmin Tanislav }
106462094060SCosmin Tanislav 
ad4130_read_sample(struct iio_dev * indio_dev,unsigned int channel,int * val)106562094060SCosmin Tanislav static int ad4130_read_sample(struct iio_dev *indio_dev, unsigned int channel,
106662094060SCosmin Tanislav 			      int *val)
106762094060SCosmin Tanislav {
106862094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
106962094060SCosmin Tanislav 	int ret;
107062094060SCosmin Tanislav 
107162094060SCosmin Tanislav 	ret = iio_device_claim_direct_mode(indio_dev);
107262094060SCosmin Tanislav 	if (ret)
107362094060SCosmin Tanislav 		return ret;
107462094060SCosmin Tanislav 
107562094060SCosmin Tanislav 	mutex_lock(&st->lock);
107662094060SCosmin Tanislav 	ret = _ad4130_read_sample(indio_dev, channel, val);
107762094060SCosmin Tanislav 	mutex_unlock(&st->lock);
107862094060SCosmin Tanislav 
107962094060SCosmin Tanislav 	iio_device_release_direct_mode(indio_dev);
108062094060SCosmin Tanislav 
108162094060SCosmin Tanislav 	return ret;
108262094060SCosmin Tanislav }
108362094060SCosmin Tanislav 
ad4130_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long info)108462094060SCosmin Tanislav static int ad4130_read_raw(struct iio_dev *indio_dev,
108562094060SCosmin Tanislav 			   struct iio_chan_spec const *chan,
108662094060SCosmin Tanislav 			   int *val, int *val2, long info)
108762094060SCosmin Tanislav {
108862094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
108962094060SCosmin Tanislav 	unsigned int channel = chan->scan_index;
109062094060SCosmin Tanislav 	struct ad4130_setup_info *setup_info = &st->chans_info[channel].setup;
109162094060SCosmin Tanislav 
109262094060SCosmin Tanislav 	switch (info) {
109362094060SCosmin Tanislav 	case IIO_CHAN_INFO_RAW:
109462094060SCosmin Tanislav 		return ad4130_read_sample(indio_dev, channel, val);
109562094060SCosmin Tanislav 	case IIO_CHAN_INFO_SCALE:
109662094060SCosmin Tanislav 		mutex_lock(&st->lock);
109762094060SCosmin Tanislav 		*val = st->scale_tbls[setup_info->ref_sel][setup_info->pga][0];
109862094060SCosmin Tanislav 		*val2 = st->scale_tbls[setup_info->ref_sel][setup_info->pga][1];
109962094060SCosmin Tanislav 		mutex_unlock(&st->lock);
110062094060SCosmin Tanislav 
110162094060SCosmin Tanislav 		return IIO_VAL_INT_PLUS_NANO;
110262094060SCosmin Tanislav 	case IIO_CHAN_INFO_OFFSET:
110362094060SCosmin Tanislav 		*val = st->bipolar ? -BIT(chan->scan_type.realbits - 1) : 0;
110462094060SCosmin Tanislav 
110562094060SCosmin Tanislav 		return IIO_VAL_INT;
110662094060SCosmin Tanislav 	case IIO_CHAN_INFO_SAMP_FREQ:
110762094060SCosmin Tanislav 		mutex_lock(&st->lock);
110862094060SCosmin Tanislav 		ad4130_fs_to_freq(setup_info->filter_mode, setup_info->fs,
110962094060SCosmin Tanislav 				  val, val2);
111062094060SCosmin Tanislav 		mutex_unlock(&st->lock);
111162094060SCosmin Tanislav 
111262094060SCosmin Tanislav 		return IIO_VAL_INT_PLUS_NANO;
111362094060SCosmin Tanislav 	default:
111462094060SCosmin Tanislav 		return -EINVAL;
111562094060SCosmin Tanislav 	}
111662094060SCosmin Tanislav }
111762094060SCosmin Tanislav 
ad4130_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long info)111862094060SCosmin Tanislav static int ad4130_read_avail(struct iio_dev *indio_dev,
111962094060SCosmin Tanislav 			     struct iio_chan_spec const *chan,
112062094060SCosmin Tanislav 			     const int **vals, int *type, int *length,
112162094060SCosmin Tanislav 			     long info)
112262094060SCosmin Tanislav {
112362094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
112462094060SCosmin Tanislav 	unsigned int channel = chan->scan_index;
112562094060SCosmin Tanislav 	struct ad4130_setup_info *setup_info = &st->chans_info[channel].setup;
112662094060SCosmin Tanislav 	const struct ad4130_filter_config *filter_config;
112762094060SCosmin Tanislav 
112862094060SCosmin Tanislav 	switch (info) {
112962094060SCosmin Tanislav 	case IIO_CHAN_INFO_SCALE:
113062094060SCosmin Tanislav 		*vals = (int *)st->scale_tbls[setup_info->ref_sel];
113162094060SCosmin Tanislav 		*length = ARRAY_SIZE(st->scale_tbls[setup_info->ref_sel]) * 2;
113262094060SCosmin Tanislav 
113362094060SCosmin Tanislav 		*type = IIO_VAL_INT_PLUS_NANO;
113462094060SCosmin Tanislav 
113562094060SCosmin Tanislav 		return IIO_AVAIL_LIST;
113662094060SCosmin Tanislav 	case IIO_CHAN_INFO_SAMP_FREQ:
113762094060SCosmin Tanislav 		mutex_lock(&st->lock);
113862094060SCosmin Tanislav 		filter_config = &ad4130_filter_configs[setup_info->filter_mode];
113962094060SCosmin Tanislav 		mutex_unlock(&st->lock);
114062094060SCosmin Tanislav 
114162094060SCosmin Tanislav 		*vals = (int *)filter_config->samp_freq_avail;
114262094060SCosmin Tanislav 		*length = filter_config->samp_freq_avail_len * 2;
114362094060SCosmin Tanislav 		*type = IIO_VAL_FRACTIONAL;
114462094060SCosmin Tanislav 
114562094060SCosmin Tanislav 		return filter_config->samp_freq_avail_type;
114662094060SCosmin Tanislav 	default:
114762094060SCosmin Tanislav 		return -EINVAL;
114862094060SCosmin Tanislav 	}
114962094060SCosmin Tanislav }
115062094060SCosmin Tanislav 
ad4130_write_raw_get_fmt(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,long info)115162094060SCosmin Tanislav static int ad4130_write_raw_get_fmt(struct iio_dev *indio_dev,
115262094060SCosmin Tanislav 				    struct iio_chan_spec const *chan,
115362094060SCosmin Tanislav 				    long info)
115462094060SCosmin Tanislav {
115562094060SCosmin Tanislav 	switch (info) {
115662094060SCosmin Tanislav 	case IIO_CHAN_INFO_SCALE:
115762094060SCosmin Tanislav 	case IIO_CHAN_INFO_SAMP_FREQ:
115862094060SCosmin Tanislav 		return IIO_VAL_INT_PLUS_NANO;
115962094060SCosmin Tanislav 	default:
116062094060SCosmin Tanislav 		return -EINVAL;
116162094060SCosmin Tanislav 	}
116262094060SCosmin Tanislav }
116362094060SCosmin Tanislav 
ad4130_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long info)116462094060SCosmin Tanislav static int ad4130_write_raw(struct iio_dev *indio_dev,
116562094060SCosmin Tanislav 			    struct iio_chan_spec const *chan,
116662094060SCosmin Tanislav 			    int val, int val2, long info)
116762094060SCosmin Tanislav {
116862094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
116962094060SCosmin Tanislav 	unsigned int channel = chan->scan_index;
117062094060SCosmin Tanislav 
117162094060SCosmin Tanislav 	switch (info) {
117262094060SCosmin Tanislav 	case IIO_CHAN_INFO_SCALE:
117362094060SCosmin Tanislav 		return ad4130_set_channel_pga(st, channel, val, val2);
117462094060SCosmin Tanislav 	case IIO_CHAN_INFO_SAMP_FREQ:
117562094060SCosmin Tanislav 		return ad4130_set_channel_freq(st, channel, val, val2);
117662094060SCosmin Tanislav 	default:
117762094060SCosmin Tanislav 		return -EINVAL;
117862094060SCosmin Tanislav 	}
117962094060SCosmin Tanislav }
118062094060SCosmin Tanislav 
ad4130_reg_access(struct iio_dev * indio_dev,unsigned int reg,unsigned int writeval,unsigned int * readval)118162094060SCosmin Tanislav static int ad4130_reg_access(struct iio_dev *indio_dev, unsigned int reg,
118262094060SCosmin Tanislav 			     unsigned int writeval, unsigned int *readval)
118362094060SCosmin Tanislav {
118462094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
118562094060SCosmin Tanislav 
118662094060SCosmin Tanislav 	if (readval)
118762094060SCosmin Tanislav 		return regmap_read(st->regmap, reg, readval);
118862094060SCosmin Tanislav 
118962094060SCosmin Tanislav 	return regmap_write(st->regmap, reg, writeval);
119062094060SCosmin Tanislav }
119162094060SCosmin Tanislav 
ad4130_update_scan_mode(struct iio_dev * indio_dev,const unsigned long * scan_mask)119262094060SCosmin Tanislav static int ad4130_update_scan_mode(struct iio_dev *indio_dev,
119362094060SCosmin Tanislav 				   const unsigned long *scan_mask)
119462094060SCosmin Tanislav {
119562094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
119662094060SCosmin Tanislav 	unsigned int channel;
119762094060SCosmin Tanislav 	unsigned int val = 0;
119862094060SCosmin Tanislav 	int ret;
119962094060SCosmin Tanislav 
120062094060SCosmin Tanislav 	mutex_lock(&st->lock);
120162094060SCosmin Tanislav 
120262094060SCosmin Tanislav 	for_each_set_bit(channel, scan_mask, indio_dev->num_channels) {
120362094060SCosmin Tanislav 		ret = ad4130_set_channel_enable(st, channel, true);
120462094060SCosmin Tanislav 		if (ret)
120562094060SCosmin Tanislav 			goto out;
120662094060SCosmin Tanislav 
120762094060SCosmin Tanislav 		val++;
120862094060SCosmin Tanislav 	}
120962094060SCosmin Tanislav 
121062094060SCosmin Tanislav 	st->num_enabled_channels = val;
121162094060SCosmin Tanislav 
121262094060SCosmin Tanislav out:
121362094060SCosmin Tanislav 	mutex_unlock(&st->lock);
121462094060SCosmin Tanislav 
121562094060SCosmin Tanislav 	return 0;
121662094060SCosmin Tanislav }
121762094060SCosmin Tanislav 
ad4130_set_fifo_watermark(struct iio_dev * indio_dev,unsigned int val)121862094060SCosmin Tanislav static int ad4130_set_fifo_watermark(struct iio_dev *indio_dev, unsigned int val)
121962094060SCosmin Tanislav {
122062094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
122162094060SCosmin Tanislav 	unsigned int eff;
122262094060SCosmin Tanislav 	int ret;
122362094060SCosmin Tanislav 
122462094060SCosmin Tanislav 	if (val > AD4130_FIFO_SIZE)
122562094060SCosmin Tanislav 		return -EINVAL;
122662094060SCosmin Tanislav 
122762094060SCosmin Tanislav 	eff = val * st->num_enabled_channels;
122862094060SCosmin Tanislav 	if (eff > AD4130_FIFO_SIZE)
122962094060SCosmin Tanislav 		/*
123062094060SCosmin Tanislav 		 * Always set watermark to a multiple of the number of
123162094060SCosmin Tanislav 		 * enabled channels to avoid making the FIFO unaligned.
123262094060SCosmin Tanislav 		 */
123362094060SCosmin Tanislav 		eff = rounddown(AD4130_FIFO_SIZE, st->num_enabled_channels);
123462094060SCosmin Tanislav 
123562094060SCosmin Tanislav 	mutex_lock(&st->lock);
123662094060SCosmin Tanislav 
123762094060SCosmin Tanislav 	ret = regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG,
123862094060SCosmin Tanislav 				 AD4130_FIFO_CONTROL_WM_MASK,
123962094060SCosmin Tanislav 				 FIELD_PREP(AD4130_FIFO_CONTROL_WM_MASK,
124062094060SCosmin Tanislav 					    ad4130_watermark_reg_val(eff)));
124162094060SCosmin Tanislav 	if (ret)
124262094060SCosmin Tanislav 		goto out;
124362094060SCosmin Tanislav 
124462094060SCosmin Tanislav 	st->effective_watermark = eff;
124562094060SCosmin Tanislav 	st->watermark = val;
124662094060SCosmin Tanislav 
124762094060SCosmin Tanislav out:
124862094060SCosmin Tanislav 	mutex_unlock(&st->lock);
124962094060SCosmin Tanislav 
125062094060SCosmin Tanislav 	return ret;
125162094060SCosmin Tanislav }
125262094060SCosmin Tanislav 
125362094060SCosmin Tanislav static const struct iio_info ad4130_info = {
125462094060SCosmin Tanislav 	.read_raw = ad4130_read_raw,
125562094060SCosmin Tanislav 	.read_avail = ad4130_read_avail,
125662094060SCosmin Tanislav 	.write_raw_get_fmt = ad4130_write_raw_get_fmt,
125762094060SCosmin Tanislav 	.write_raw = ad4130_write_raw,
125862094060SCosmin Tanislav 	.update_scan_mode = ad4130_update_scan_mode,
125962094060SCosmin Tanislav 	.hwfifo_set_watermark = ad4130_set_fifo_watermark,
126062094060SCosmin Tanislav 	.debugfs_reg_access = ad4130_reg_access,
126162094060SCosmin Tanislav };
126262094060SCosmin Tanislav 
ad4130_buffer_postenable(struct iio_dev * indio_dev)126362094060SCosmin Tanislav static int ad4130_buffer_postenable(struct iio_dev *indio_dev)
126462094060SCosmin Tanislav {
126562094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
126662094060SCosmin Tanislav 	int ret;
126762094060SCosmin Tanislav 
126862094060SCosmin Tanislav 	mutex_lock(&st->lock);
126962094060SCosmin Tanislav 
127062094060SCosmin Tanislav 	ret = ad4130_set_watermark_interrupt_en(st, true);
127162094060SCosmin Tanislav 	if (ret)
127262094060SCosmin Tanislav 		goto out;
127362094060SCosmin Tanislav 
127462094060SCosmin Tanislav 	ret = irq_set_irq_type(st->spi->irq, st->inv_irq_trigger);
127562094060SCosmin Tanislav 	if (ret)
127662094060SCosmin Tanislav 		goto out;
127762094060SCosmin Tanislav 
127862094060SCosmin Tanislav 	ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_WM);
127962094060SCosmin Tanislav 	if (ret)
128062094060SCosmin Tanislav 		goto out;
128162094060SCosmin Tanislav 
128262094060SCosmin Tanislav 	ret = ad4130_set_mode(st, AD4130_MODE_CONTINUOUS);
128362094060SCosmin Tanislav 
128462094060SCosmin Tanislav out:
128562094060SCosmin Tanislav 	mutex_unlock(&st->lock);
128662094060SCosmin Tanislav 
128762094060SCosmin Tanislav 	return ret;
128862094060SCosmin Tanislav }
128962094060SCosmin Tanislav 
ad4130_buffer_predisable(struct iio_dev * indio_dev)129062094060SCosmin Tanislav static int ad4130_buffer_predisable(struct iio_dev *indio_dev)
129162094060SCosmin Tanislav {
129262094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
129362094060SCosmin Tanislav 	unsigned int i;
129462094060SCosmin Tanislav 	int ret;
129562094060SCosmin Tanislav 
129662094060SCosmin Tanislav 	mutex_lock(&st->lock);
129762094060SCosmin Tanislav 
129862094060SCosmin Tanislav 	ret = ad4130_set_mode(st, AD4130_MODE_IDLE);
129962094060SCosmin Tanislav 	if (ret)
130062094060SCosmin Tanislav 		goto out;
130162094060SCosmin Tanislav 
130262094060SCosmin Tanislav 	ret = irq_set_irq_type(st->spi->irq, st->irq_trigger);
130362094060SCosmin Tanislav 	if (ret)
130462094060SCosmin Tanislav 		goto out;
130562094060SCosmin Tanislav 
130662094060SCosmin Tanislav 	ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_DISABLED);
130762094060SCosmin Tanislav 	if (ret)
130862094060SCosmin Tanislav 		goto out;
130962094060SCosmin Tanislav 
131062094060SCosmin Tanislav 	ret = ad4130_set_watermark_interrupt_en(st, false);
131162094060SCosmin Tanislav 	if (ret)
131262094060SCosmin Tanislav 		goto out;
131362094060SCosmin Tanislav 
131462094060SCosmin Tanislav 	/*
131562094060SCosmin Tanislav 	 * update_scan_mode() is not called in the disable path, disable all
131662094060SCosmin Tanislav 	 * channels here.
131762094060SCosmin Tanislav 	 */
131862094060SCosmin Tanislav 	for (i = 0; i < indio_dev->num_channels; i++) {
131962094060SCosmin Tanislav 		ret = ad4130_set_channel_enable(st, i, false);
132062094060SCosmin Tanislav 		if (ret)
132162094060SCosmin Tanislav 			goto out;
132262094060SCosmin Tanislav 	}
132362094060SCosmin Tanislav 
132462094060SCosmin Tanislav out:
132562094060SCosmin Tanislav 	mutex_unlock(&st->lock);
132662094060SCosmin Tanislav 
132762094060SCosmin Tanislav 	return ret;
132862094060SCosmin Tanislav }
132962094060SCosmin Tanislav 
133062094060SCosmin Tanislav static const struct iio_buffer_setup_ops ad4130_buffer_ops = {
133162094060SCosmin Tanislav 	.postenable = ad4130_buffer_postenable,
133262094060SCosmin Tanislav 	.predisable = ad4130_buffer_predisable,
133362094060SCosmin Tanislav };
133462094060SCosmin Tanislav 
hwfifo_watermark_show(struct device * dev,struct device_attribute * attr,char * buf)133562094060SCosmin Tanislav static ssize_t hwfifo_watermark_show(struct device *dev,
133662094060SCosmin Tanislav 				     struct device_attribute *attr, char *buf)
133762094060SCosmin Tanislav {
133862094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(dev_to_iio_dev(dev));
133962094060SCosmin Tanislav 	unsigned int val;
134062094060SCosmin Tanislav 
134162094060SCosmin Tanislav 	mutex_lock(&st->lock);
134262094060SCosmin Tanislav 	val = st->watermark;
134362094060SCosmin Tanislav 	mutex_unlock(&st->lock);
134462094060SCosmin Tanislav 
134562094060SCosmin Tanislav 	return sysfs_emit(buf, "%d\n", val);
134662094060SCosmin Tanislav }
134762094060SCosmin Tanislav 
hwfifo_enabled_show(struct device * dev,struct device_attribute * attr,char * buf)134862094060SCosmin Tanislav static ssize_t hwfifo_enabled_show(struct device *dev,
134962094060SCosmin Tanislav 				   struct device_attribute *attr, char *buf)
135062094060SCosmin Tanislav {
135162094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(dev_to_iio_dev(dev));
135262094060SCosmin Tanislav 	unsigned int val;
135362094060SCosmin Tanislav 	int ret;
135462094060SCosmin Tanislav 
135562094060SCosmin Tanislav 	ret = regmap_read(st->regmap, AD4130_FIFO_CONTROL_REG, &val);
135662094060SCosmin Tanislav 	if (ret)
135762094060SCosmin Tanislav 		return ret;
135862094060SCosmin Tanislav 
135962094060SCosmin Tanislav 	val = FIELD_GET(AD4130_FIFO_CONTROL_MODE_MASK, val);
136062094060SCosmin Tanislav 
136162094060SCosmin Tanislav 	return sysfs_emit(buf, "%d\n", val != AD4130_FIFO_MODE_DISABLED);
136262094060SCosmin Tanislav }
136362094060SCosmin Tanislav 
hwfifo_watermark_min_show(struct device * dev,struct device_attribute * attr,char * buf)136462094060SCosmin Tanislav static ssize_t hwfifo_watermark_min_show(struct device *dev,
136562094060SCosmin Tanislav 					 struct device_attribute *attr,
136662094060SCosmin Tanislav 					 char *buf)
136762094060SCosmin Tanislav {
136862094060SCosmin Tanislav 	return sysfs_emit(buf, "%s\n", "1");
136962094060SCosmin Tanislav }
137062094060SCosmin Tanislav 
hwfifo_watermark_max_show(struct device * dev,struct device_attribute * attr,char * buf)137162094060SCosmin Tanislav static ssize_t hwfifo_watermark_max_show(struct device *dev,
137262094060SCosmin Tanislav 					 struct device_attribute *attr,
137362094060SCosmin Tanislav 					 char *buf)
137462094060SCosmin Tanislav {
137562094060SCosmin Tanislav 	return sysfs_emit(buf, "%s\n", __stringify(AD4130_FIFO_SIZE));
137662094060SCosmin Tanislav }
137762094060SCosmin Tanislav 
137862094060SCosmin Tanislav static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0);
137962094060SCosmin Tanislav static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
138062094060SCosmin Tanislav static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0);
138162094060SCosmin Tanislav static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0);
138262094060SCosmin Tanislav 
13830a33755cSMatti Vaittinen static const struct iio_dev_attr *ad4130_fifo_attributes[] = {
13840a33755cSMatti Vaittinen 	&iio_dev_attr_hwfifo_watermark_min,
13850a33755cSMatti Vaittinen 	&iio_dev_attr_hwfifo_watermark_max,
13860a33755cSMatti Vaittinen 	&iio_dev_attr_hwfifo_watermark,
13870a33755cSMatti Vaittinen 	&iio_dev_attr_hwfifo_enabled,
138862094060SCosmin Tanislav 	NULL
138962094060SCosmin Tanislav };
139062094060SCosmin Tanislav 
_ad4130_find_table_index(const unsigned int * tbl,size_t len,unsigned int val)139162094060SCosmin Tanislav static int _ad4130_find_table_index(const unsigned int *tbl, size_t len,
139262094060SCosmin Tanislav 				    unsigned int val)
139362094060SCosmin Tanislav {
139462094060SCosmin Tanislav 	unsigned int i;
139562094060SCosmin Tanislav 
139662094060SCosmin Tanislav 	for (i = 0; i < len; i++)
139762094060SCosmin Tanislav 		if (tbl[i] == val)
139862094060SCosmin Tanislav 			return i;
139962094060SCosmin Tanislav 
140062094060SCosmin Tanislav 	return -EINVAL;
140162094060SCosmin Tanislav }
140262094060SCosmin Tanislav 
140362094060SCosmin Tanislav #define ad4130_find_table_index(table, val) \
140462094060SCosmin Tanislav 	_ad4130_find_table_index(table, ARRAY_SIZE(table), val)
140562094060SCosmin Tanislav 
ad4130_get_ref_voltage(struct ad4130_state * st,enum ad4130_ref_sel ref_sel)140662094060SCosmin Tanislav static int ad4130_get_ref_voltage(struct ad4130_state *st,
140762094060SCosmin Tanislav 				  enum ad4130_ref_sel ref_sel)
140862094060SCosmin Tanislav {
140962094060SCosmin Tanislav 	switch (ref_sel) {
141062094060SCosmin Tanislav 	case AD4130_REF_REFIN1:
141162094060SCosmin Tanislav 		return regulator_get_voltage(st->regulators[2].consumer);
141262094060SCosmin Tanislav 	case AD4130_REF_REFIN2:
141362094060SCosmin Tanislav 		return regulator_get_voltage(st->regulators[3].consumer);
141462094060SCosmin Tanislav 	case AD4130_REF_AVDD_AVSS:
141562094060SCosmin Tanislav 		return regulator_get_voltage(st->regulators[0].consumer);
141662094060SCosmin Tanislav 	case AD4130_REF_REFOUT_AVSS:
141762094060SCosmin Tanislav 		return st->int_ref_uv;
141862094060SCosmin Tanislav 	default:
141962094060SCosmin Tanislav 		return -EINVAL;
142062094060SCosmin Tanislav 	}
142162094060SCosmin Tanislav }
142262094060SCosmin Tanislav 
ad4130_parse_fw_setup(struct ad4130_state * st,struct fwnode_handle * child,struct ad4130_setup_info * setup_info)142362094060SCosmin Tanislav static int ad4130_parse_fw_setup(struct ad4130_state *st,
142462094060SCosmin Tanislav 				 struct fwnode_handle *child,
142562094060SCosmin Tanislav 				 struct ad4130_setup_info *setup_info)
142662094060SCosmin Tanislav {
142762094060SCosmin Tanislav 	struct device *dev = &st->spi->dev;
142862094060SCosmin Tanislav 	u32 tmp;
142962094060SCosmin Tanislav 	int ret;
143062094060SCosmin Tanislav 
143162094060SCosmin Tanislav 	tmp = 0;
143262094060SCosmin Tanislav 	fwnode_property_read_u32(child, "adi,excitation-current-0-nanoamp", &tmp);
143362094060SCosmin Tanislav 	ret = ad4130_find_table_index(ad4130_iout_current_na_tbl, tmp);
143462094060SCosmin Tanislav 	if (ret < 0)
143562094060SCosmin Tanislav 		return dev_err_probe(dev, ret,
143662094060SCosmin Tanislav 				     "Invalid excitation current %unA\n", tmp);
143762094060SCosmin Tanislav 	setup_info->iout0_val = ret;
143862094060SCosmin Tanislav 
143962094060SCosmin Tanislav 	tmp = 0;
144062094060SCosmin Tanislav 	fwnode_property_read_u32(child, "adi,excitation-current-1-nanoamp", &tmp);
144162094060SCosmin Tanislav 	ret = ad4130_find_table_index(ad4130_iout_current_na_tbl, tmp);
144262094060SCosmin Tanislav 	if (ret < 0)
144362094060SCosmin Tanislav 		return dev_err_probe(dev, ret,
144462094060SCosmin Tanislav 				     "Invalid excitation current %unA\n", tmp);
144562094060SCosmin Tanislav 	setup_info->iout1_val = ret;
144662094060SCosmin Tanislav 
144762094060SCosmin Tanislav 	tmp = 0;
144862094060SCosmin Tanislav 	fwnode_property_read_u32(child, "adi,burnout-current-nanoamp", &tmp);
144962094060SCosmin Tanislav 	ret = ad4130_find_table_index(ad4130_burnout_current_na_tbl, tmp);
145062094060SCosmin Tanislav 	if (ret < 0)
145162094060SCosmin Tanislav 		return dev_err_probe(dev, ret,
145262094060SCosmin Tanislav 				     "Invalid burnout current %unA\n", tmp);
145362094060SCosmin Tanislav 	setup_info->burnout = ret;
145462094060SCosmin Tanislav 
145562094060SCosmin Tanislav 	setup_info->ref_bufp = fwnode_property_read_bool(child, "adi,buffered-positive");
145662094060SCosmin Tanislav 	setup_info->ref_bufm = fwnode_property_read_bool(child, "adi,buffered-negative");
145762094060SCosmin Tanislav 
145862094060SCosmin Tanislav 	setup_info->ref_sel = AD4130_REF_REFIN1;
145962094060SCosmin Tanislav 	fwnode_property_read_u32(child, "adi,reference-select",
146062094060SCosmin Tanislav 				 &setup_info->ref_sel);
146162094060SCosmin Tanislav 	if (setup_info->ref_sel >= AD4130_REF_SEL_MAX)
146262094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL,
146362094060SCosmin Tanislav 				     "Invalid reference selected %u\n",
146462094060SCosmin Tanislav 				     setup_info->ref_sel);
146562094060SCosmin Tanislav 
146662094060SCosmin Tanislav 	if (setup_info->ref_sel == AD4130_REF_REFOUT_AVSS)
146762094060SCosmin Tanislav 		st->int_ref_en = true;
146862094060SCosmin Tanislav 
146962094060SCosmin Tanislav 	ret = ad4130_get_ref_voltage(st, setup_info->ref_sel);
147062094060SCosmin Tanislav 	if (ret < 0)
147162094060SCosmin Tanislav 		return dev_err_probe(dev, ret, "Cannot use reference %u\n",
147262094060SCosmin Tanislav 				     setup_info->ref_sel);
147362094060SCosmin Tanislav 
147462094060SCosmin Tanislav 	return 0;
147562094060SCosmin Tanislav }
147662094060SCosmin Tanislav 
ad4130_validate_diff_channel(struct ad4130_state * st,u32 pin)147762094060SCosmin Tanislav static int ad4130_validate_diff_channel(struct ad4130_state *st, u32 pin)
147862094060SCosmin Tanislav {
147962094060SCosmin Tanislav 	struct device *dev = &st->spi->dev;
148062094060SCosmin Tanislav 
148162094060SCosmin Tanislav 	if (pin >= AD4130_MAX_DIFF_INPUTS)
148262094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL,
14836abcb19eSColin Ian King 				     "Invalid differential channel %u\n", pin);
148462094060SCosmin Tanislav 
148562094060SCosmin Tanislav 	if (pin >= AD4130_MAX_ANALOG_PINS)
148662094060SCosmin Tanislav 		return 0;
148762094060SCosmin Tanislav 
148862094060SCosmin Tanislav 	if (st->pins_fn[pin] == AD4130_PIN_FN_SPECIAL)
148962094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL,
149062094060SCosmin Tanislav 				     "Pin %u already used with fn %u\n", pin,
149162094060SCosmin Tanislav 				     st->pins_fn[pin]);
149262094060SCosmin Tanislav 
149362094060SCosmin Tanislav 	st->pins_fn[pin] |= AD4130_PIN_FN_DIFF;
149462094060SCosmin Tanislav 
149562094060SCosmin Tanislav 	return 0;
149662094060SCosmin Tanislav }
149762094060SCosmin Tanislav 
ad4130_validate_diff_channels(struct ad4130_state * st,u32 * pins,unsigned int len)149862094060SCosmin Tanislav static int ad4130_validate_diff_channels(struct ad4130_state *st,
149962094060SCosmin Tanislav 					 u32 *pins, unsigned int len)
150062094060SCosmin Tanislav {
150162094060SCosmin Tanislav 	unsigned int i;
150262094060SCosmin Tanislav 	int ret;
150362094060SCosmin Tanislav 
150462094060SCosmin Tanislav 	for (i = 0; i < len; i++) {
150562094060SCosmin Tanislav 		ret = ad4130_validate_diff_channel(st, pins[i]);
150662094060SCosmin Tanislav 		if (ret)
150762094060SCosmin Tanislav 			return ret;
150862094060SCosmin Tanislav 	}
150962094060SCosmin Tanislav 
151062094060SCosmin Tanislav 	return 0;
151162094060SCosmin Tanislav }
151262094060SCosmin Tanislav 
ad4130_validate_excitation_pin(struct ad4130_state * st,u32 pin)151362094060SCosmin Tanislav static int ad4130_validate_excitation_pin(struct ad4130_state *st, u32 pin)
151462094060SCosmin Tanislav {
151562094060SCosmin Tanislav 	struct device *dev = &st->spi->dev;
151662094060SCosmin Tanislav 
151762094060SCosmin Tanislav 	if (pin >= AD4130_MAX_ANALOG_PINS)
151862094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL,
151962094060SCosmin Tanislav 				     "Invalid excitation pin %u\n", pin);
152062094060SCosmin Tanislav 
152162094060SCosmin Tanislav 	if (st->pins_fn[pin] == AD4130_PIN_FN_SPECIAL)
152262094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL,
152362094060SCosmin Tanislav 				     "Pin %u already used with fn %u\n", pin,
152462094060SCosmin Tanislav 				     st->pins_fn[pin]);
152562094060SCosmin Tanislav 
152662094060SCosmin Tanislav 	st->pins_fn[pin] |= AD4130_PIN_FN_EXCITATION;
152762094060SCosmin Tanislav 
152862094060SCosmin Tanislav 	return 0;
152962094060SCosmin Tanislav }
153062094060SCosmin Tanislav 
ad4130_validate_vbias_pin(struct ad4130_state * st,u32 pin)153162094060SCosmin Tanislav static int ad4130_validate_vbias_pin(struct ad4130_state *st, u32 pin)
153262094060SCosmin Tanislav {
153362094060SCosmin Tanislav 	struct device *dev = &st->spi->dev;
153462094060SCosmin Tanislav 
153562094060SCosmin Tanislav 	if (pin >= AD4130_MAX_ANALOG_PINS)
153662094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL, "Invalid vbias pin %u\n",
153762094060SCosmin Tanislav 				     pin);
153862094060SCosmin Tanislav 
153962094060SCosmin Tanislav 	if (st->pins_fn[pin] == AD4130_PIN_FN_SPECIAL)
154062094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL,
154162094060SCosmin Tanislav 				     "Pin %u already used with fn %u\n", pin,
154262094060SCosmin Tanislav 				     st->pins_fn[pin]);
154362094060SCosmin Tanislav 
154462094060SCosmin Tanislav 	st->pins_fn[pin] |= AD4130_PIN_FN_VBIAS;
154562094060SCosmin Tanislav 
154662094060SCosmin Tanislav 	return 0;
154762094060SCosmin Tanislav }
154862094060SCosmin Tanislav 
ad4130_validate_vbias_pins(struct ad4130_state * st,u32 * pins,unsigned int len)154962094060SCosmin Tanislav static int ad4130_validate_vbias_pins(struct ad4130_state *st,
155062094060SCosmin Tanislav 				      u32 *pins, unsigned int len)
155162094060SCosmin Tanislav {
155262094060SCosmin Tanislav 	unsigned int i;
155362094060SCosmin Tanislav 	int ret;
155462094060SCosmin Tanislav 
155562094060SCosmin Tanislav 	for (i = 0; i < st->num_vbias_pins; i++) {
155662094060SCosmin Tanislav 		ret = ad4130_validate_vbias_pin(st, pins[i]);
155762094060SCosmin Tanislav 		if (ret)
155862094060SCosmin Tanislav 			return ret;
155962094060SCosmin Tanislav 	}
156062094060SCosmin Tanislav 
156162094060SCosmin Tanislav 	return 0;
156262094060SCosmin Tanislav }
156362094060SCosmin Tanislav 
ad4130_parse_fw_channel(struct iio_dev * indio_dev,struct fwnode_handle * child)156462094060SCosmin Tanislav static int ad4130_parse_fw_channel(struct iio_dev *indio_dev,
156562094060SCosmin Tanislav 				   struct fwnode_handle *child)
156662094060SCosmin Tanislav {
156762094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
156862094060SCosmin Tanislav 	unsigned int resolution = ad4130_resolution(st);
156962094060SCosmin Tanislav 	unsigned int index = indio_dev->num_channels++;
157062094060SCosmin Tanislav 	struct device *dev = &st->spi->dev;
157162094060SCosmin Tanislav 	struct ad4130_chan_info *chan_info;
157262094060SCosmin Tanislav 	struct iio_chan_spec *chan;
157362094060SCosmin Tanislav 	u32 pins[2];
157462094060SCosmin Tanislav 	int ret;
157562094060SCosmin Tanislav 
157662094060SCosmin Tanislav 	if (index >= AD4130_MAX_CHANNELS)
157762094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL, "Too many channels\n");
157862094060SCosmin Tanislav 
157962094060SCosmin Tanislav 	chan = &st->chans[index];
158062094060SCosmin Tanislav 	chan_info = &st->chans_info[index];
158162094060SCosmin Tanislav 
158262094060SCosmin Tanislav 	*chan = ad4130_channel_template;
158362094060SCosmin Tanislav 	chan->scan_type.realbits = resolution;
158462094060SCosmin Tanislav 	chan->scan_type.storagebits = resolution;
158562094060SCosmin Tanislav 	chan->scan_index = index;
158662094060SCosmin Tanislav 
158762094060SCosmin Tanislav 	chan_info->slot = AD4130_INVALID_SLOT;
158862094060SCosmin Tanislav 	chan_info->setup.fs = AD4130_FILTER_SELECT_MIN;
158962094060SCosmin Tanislav 	chan_info->initialized = true;
159062094060SCosmin Tanislav 
159162094060SCosmin Tanislav 	ret = fwnode_property_read_u32_array(child, "diff-channels", pins,
159262094060SCosmin Tanislav 					     ARRAY_SIZE(pins));
159362094060SCosmin Tanislav 	if (ret)
159462094060SCosmin Tanislav 		return ret;
159562094060SCosmin Tanislav 
159662094060SCosmin Tanislav 	ret = ad4130_validate_diff_channels(st, pins, ARRAY_SIZE(pins));
159762094060SCosmin Tanislav 	if (ret)
159862094060SCosmin Tanislav 		return ret;
159962094060SCosmin Tanislav 
160062094060SCosmin Tanislav 	chan->channel = pins[0];
160162094060SCosmin Tanislav 	chan->channel2 = pins[1];
160262094060SCosmin Tanislav 
160362094060SCosmin Tanislav 	ret = ad4130_parse_fw_setup(st, child, &chan_info->setup);
160462094060SCosmin Tanislav 	if (ret)
160562094060SCosmin Tanislav 		return ret;
160662094060SCosmin Tanislav 
160762094060SCosmin Tanislav 	fwnode_property_read_u32(child, "adi,excitation-pin-0",
160862094060SCosmin Tanislav 				 &chan_info->iout0);
160962094060SCosmin Tanislav 	if (chan_info->setup.iout0_val != AD4130_IOUT_OFF) {
161062094060SCosmin Tanislav 		ret = ad4130_validate_excitation_pin(st, chan_info->iout0);
161162094060SCosmin Tanislav 		if (ret)
161262094060SCosmin Tanislav 			return ret;
161362094060SCosmin Tanislav 	}
161462094060SCosmin Tanislav 
161562094060SCosmin Tanislav 	fwnode_property_read_u32(child, "adi,excitation-pin-1",
161662094060SCosmin Tanislav 				 &chan_info->iout1);
161762094060SCosmin Tanislav 	if (chan_info->setup.iout1_val != AD4130_IOUT_OFF) {
161862094060SCosmin Tanislav 		ret = ad4130_validate_excitation_pin(st, chan_info->iout1);
161962094060SCosmin Tanislav 		if (ret)
162062094060SCosmin Tanislav 			return ret;
162162094060SCosmin Tanislav 	}
162262094060SCosmin Tanislav 
162362094060SCosmin Tanislav 	return 0;
162462094060SCosmin Tanislav }
162562094060SCosmin Tanislav 
ad4130_parse_fw_children(struct iio_dev * indio_dev)162662094060SCosmin Tanislav static int ad4130_parse_fw_children(struct iio_dev *indio_dev)
162762094060SCosmin Tanislav {
162862094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
162962094060SCosmin Tanislav 	struct device *dev = &st->spi->dev;
163062094060SCosmin Tanislav 	struct fwnode_handle *child;
163162094060SCosmin Tanislav 	int ret;
163262094060SCosmin Tanislav 
163362094060SCosmin Tanislav 	indio_dev->channels = st->chans;
163462094060SCosmin Tanislav 
163562094060SCosmin Tanislav 	device_for_each_child_node(dev, child) {
163662094060SCosmin Tanislav 		ret = ad4130_parse_fw_channel(indio_dev, child);
163762094060SCosmin Tanislav 		if (ret) {
163862094060SCosmin Tanislav 			fwnode_handle_put(child);
163962094060SCosmin Tanislav 			return ret;
164062094060SCosmin Tanislav 		}
164162094060SCosmin Tanislav 	}
164262094060SCosmin Tanislav 
164362094060SCosmin Tanislav 	return 0;
164462094060SCosmin Tanislav }
164562094060SCosmin Tanislav 
ad4310_parse_fw(struct iio_dev * indio_dev)164662094060SCosmin Tanislav static int ad4310_parse_fw(struct iio_dev *indio_dev)
164762094060SCosmin Tanislav {
164862094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
164962094060SCosmin Tanislav 	struct device *dev = &st->spi->dev;
165062094060SCosmin Tanislav 	u32 ext_clk_freq = AD4130_MCLK_FREQ_76_8KHZ;
165162094060SCosmin Tanislav 	unsigned int i;
165262094060SCosmin Tanislav 	int avdd_uv;
165362094060SCosmin Tanislav 	int irq;
165462094060SCosmin Tanislav 	int ret;
165562094060SCosmin Tanislav 
165662094060SCosmin Tanislav 	st->mclk = devm_clk_get_optional(dev, "mclk");
165762094060SCosmin Tanislav 	if (IS_ERR(st->mclk))
165862094060SCosmin Tanislav 		return dev_err_probe(dev, PTR_ERR(st->mclk),
165962094060SCosmin Tanislav 				     "Failed to get mclk\n");
166062094060SCosmin Tanislav 
166162094060SCosmin Tanislav 	st->int_pin_sel = AD4130_INT_PIN_INT;
166262094060SCosmin Tanislav 
166362094060SCosmin Tanislav 	for (i = 0; i < ARRAY_SIZE(ad4130_int_pin_names); i++) {
166462094060SCosmin Tanislav 		irq = fwnode_irq_get_byname(dev_fwnode(dev),
166562094060SCosmin Tanislav 					    ad4130_int_pin_names[i]);
166662094060SCosmin Tanislav 		if (irq > 0) {
166762094060SCosmin Tanislav 			st->int_pin_sel = i;
166862094060SCosmin Tanislav 			break;
166962094060SCosmin Tanislav 		}
167062094060SCosmin Tanislav 	}
167162094060SCosmin Tanislav 
167262094060SCosmin Tanislav 	if (st->int_pin_sel == AD4130_INT_PIN_DOUT)
167362094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL,
167462094060SCosmin Tanislav 				     "Cannot use DOUT as interrupt pin\n");
167562094060SCosmin Tanislav 
167662094060SCosmin Tanislav 	if (st->int_pin_sel == AD4130_INT_PIN_P2)
167762094060SCosmin Tanislav 		st->pins_fn[AD4130_AIN3_P2] = AD4130_PIN_FN_SPECIAL;
167862094060SCosmin Tanislav 
167962094060SCosmin Tanislav 	device_property_read_u32(dev, "adi,ext-clk-freq-hz", &ext_clk_freq);
168062094060SCosmin Tanislav 	if (ext_clk_freq != AD4130_MCLK_FREQ_153_6KHZ &&
168162094060SCosmin Tanislav 	    ext_clk_freq != AD4130_MCLK_FREQ_76_8KHZ)
168262094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL,
168362094060SCosmin Tanislav 				     "Invalid external clock frequency %u\n",
168462094060SCosmin Tanislav 				     ext_clk_freq);
168562094060SCosmin Tanislav 
168662094060SCosmin Tanislav 	if (st->mclk && ext_clk_freq == AD4130_MCLK_FREQ_153_6KHZ)
168762094060SCosmin Tanislav 		st->mclk_sel = AD4130_MCLK_153_6KHZ_EXT;
168862094060SCosmin Tanislav 	else if (st->mclk)
168962094060SCosmin Tanislav 		st->mclk_sel = AD4130_MCLK_76_8KHZ_EXT;
169062094060SCosmin Tanislav 	else
169162094060SCosmin Tanislav 		st->mclk_sel = AD4130_MCLK_76_8KHZ;
169262094060SCosmin Tanislav 
169362094060SCosmin Tanislav 	if (st->int_pin_sel == AD4130_INT_PIN_CLK &&
169462094060SCosmin Tanislav 	    st->mclk_sel != AD4130_MCLK_76_8KHZ)
169562094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL,
169662094060SCosmin Tanislav 				     "Invalid clock %u for interrupt pin %u\n",
169762094060SCosmin Tanislav 				     st->mclk_sel, st->int_pin_sel);
169862094060SCosmin Tanislav 
169962094060SCosmin Tanislav 	st->int_ref_uv = AD4130_INT_REF_2_5V;
170062094060SCosmin Tanislav 
170162094060SCosmin Tanislav 	/*
170262094060SCosmin Tanislav 	 * When the AVDD supply is set to below 2.5V the internal reference of
170362094060SCosmin Tanislav 	 * 1.25V should be selected.
170462094060SCosmin Tanislav 	 * See datasheet page 37, section ADC REFERENCE.
170562094060SCosmin Tanislav 	 */
170662094060SCosmin Tanislav 	avdd_uv = regulator_get_voltage(st->regulators[0].consumer);
170762094060SCosmin Tanislav 	if (avdd_uv > 0 && avdd_uv < AD4130_INT_REF_2_5V)
170862094060SCosmin Tanislav 		st->int_ref_uv = AD4130_INT_REF_1_25V;
170962094060SCosmin Tanislav 
171062094060SCosmin Tanislav 	st->bipolar = device_property_read_bool(dev, "adi,bipolar");
171162094060SCosmin Tanislav 
171262094060SCosmin Tanislav 	ret = device_property_count_u32(dev, "adi,vbias-pins");
171362094060SCosmin Tanislav 	if (ret > 0) {
171462094060SCosmin Tanislav 		if (ret > AD4130_MAX_ANALOG_PINS)
171562094060SCosmin Tanislav 			return dev_err_probe(dev, -EINVAL,
171662094060SCosmin Tanislav 					     "Too many vbias pins %u\n", ret);
171762094060SCosmin Tanislav 
171862094060SCosmin Tanislav 		st->num_vbias_pins = ret;
171962094060SCosmin Tanislav 
172062094060SCosmin Tanislav 		ret = device_property_read_u32_array(dev, "adi,vbias-pins",
172162094060SCosmin Tanislav 						     st->vbias_pins,
172262094060SCosmin Tanislav 						     st->num_vbias_pins);
172362094060SCosmin Tanislav 		if (ret)
172462094060SCosmin Tanislav 			return dev_err_probe(dev, ret,
172562094060SCosmin Tanislav 					     "Failed to read vbias pins\n");
172662094060SCosmin Tanislav 
172762094060SCosmin Tanislav 		ret = ad4130_validate_vbias_pins(st, st->vbias_pins,
172862094060SCosmin Tanislav 						 st->num_vbias_pins);
172962094060SCosmin Tanislav 		if (ret)
173062094060SCosmin Tanislav 			return ret;
173162094060SCosmin Tanislav 	}
173262094060SCosmin Tanislav 
173362094060SCosmin Tanislav 	ret = ad4130_parse_fw_children(indio_dev);
173462094060SCosmin Tanislav 	if (ret)
173562094060SCosmin Tanislav 		return ret;
173662094060SCosmin Tanislav 
173762094060SCosmin Tanislav 	return 0;
173862094060SCosmin Tanislav }
173962094060SCosmin Tanislav 
ad4130_fill_scale_tbls(struct ad4130_state * st)174062094060SCosmin Tanislav static void ad4130_fill_scale_tbls(struct ad4130_state *st)
174162094060SCosmin Tanislav {
174262094060SCosmin Tanislav 	unsigned int pow = ad4130_resolution(st) - st->bipolar;
174362094060SCosmin Tanislav 	unsigned int i, j;
174462094060SCosmin Tanislav 
174562094060SCosmin Tanislav 	for (i = 0; i < AD4130_REF_SEL_MAX; i++) {
174662094060SCosmin Tanislav 		int ret;
174762094060SCosmin Tanislav 		u64 nv;
174862094060SCosmin Tanislav 
174962094060SCosmin Tanislav 		ret = ad4130_get_ref_voltage(st, i);
175062094060SCosmin Tanislav 		if (ret < 0)
175162094060SCosmin Tanislav 			continue;
175262094060SCosmin Tanislav 
175362094060SCosmin Tanislav 		nv = (u64)ret * NANO;
175462094060SCosmin Tanislav 
175562094060SCosmin Tanislav 		for (j = 0; j < AD4130_MAX_PGA; j++)
175662094060SCosmin Tanislav 			st->scale_tbls[i][j][1] = div_u64(nv >> (pow + j), MILLI);
175762094060SCosmin Tanislav 	}
175862094060SCosmin Tanislav }
175962094060SCosmin Tanislav 
ad4130_clk_disable_unprepare(void * clk)176062094060SCosmin Tanislav static void ad4130_clk_disable_unprepare(void *clk)
176162094060SCosmin Tanislav {
176262094060SCosmin Tanislav 	clk_disable_unprepare(clk);
176362094060SCosmin Tanislav }
176462094060SCosmin Tanislav 
ad4130_set_mclk_sel(struct ad4130_state * st,enum ad4130_mclk_sel mclk_sel)176562094060SCosmin Tanislav static int ad4130_set_mclk_sel(struct ad4130_state *st,
176662094060SCosmin Tanislav 			       enum ad4130_mclk_sel mclk_sel)
176762094060SCosmin Tanislav {
176862094060SCosmin Tanislav 	return regmap_update_bits(st->regmap, AD4130_ADC_CONTROL_REG,
176962094060SCosmin Tanislav 				 AD4130_ADC_CONTROL_MCLK_SEL_MASK,
177062094060SCosmin Tanislav 				 FIELD_PREP(AD4130_ADC_CONTROL_MCLK_SEL_MASK,
177162094060SCosmin Tanislav 					    mclk_sel));
177262094060SCosmin Tanislav }
177362094060SCosmin Tanislav 
ad4130_int_clk_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)177462094060SCosmin Tanislav static unsigned long ad4130_int_clk_recalc_rate(struct clk_hw *hw,
177562094060SCosmin Tanislav 						unsigned long parent_rate)
177662094060SCosmin Tanislav {
177762094060SCosmin Tanislav 	return AD4130_MCLK_FREQ_76_8KHZ;
177862094060SCosmin Tanislav }
177962094060SCosmin Tanislav 
ad4130_int_clk_is_enabled(struct clk_hw * hw)178062094060SCosmin Tanislav static int ad4130_int_clk_is_enabled(struct clk_hw *hw)
178162094060SCosmin Tanislav {
178262094060SCosmin Tanislav 	struct ad4130_state *st = container_of(hw, struct ad4130_state, int_clk_hw);
178362094060SCosmin Tanislav 
178462094060SCosmin Tanislav 	return st->mclk_sel == AD4130_MCLK_76_8KHZ_OUT;
178562094060SCosmin Tanislav }
178662094060SCosmin Tanislav 
ad4130_int_clk_prepare(struct clk_hw * hw)178762094060SCosmin Tanislav static int ad4130_int_clk_prepare(struct clk_hw *hw)
178862094060SCosmin Tanislav {
178962094060SCosmin Tanislav 	struct ad4130_state *st = container_of(hw, struct ad4130_state, int_clk_hw);
179062094060SCosmin Tanislav 	int ret;
179162094060SCosmin Tanislav 
179262094060SCosmin Tanislav 	ret = ad4130_set_mclk_sel(st, AD4130_MCLK_76_8KHZ_OUT);
179362094060SCosmin Tanislav 	if (ret)
179462094060SCosmin Tanislav 		return ret;
179562094060SCosmin Tanislav 
179662094060SCosmin Tanislav 	st->mclk_sel = AD4130_MCLK_76_8KHZ_OUT;
179762094060SCosmin Tanislav 
179862094060SCosmin Tanislav 	return 0;
179962094060SCosmin Tanislav }
180062094060SCosmin Tanislav 
ad4130_int_clk_unprepare(struct clk_hw * hw)180162094060SCosmin Tanislav static void ad4130_int_clk_unprepare(struct clk_hw *hw)
180262094060SCosmin Tanislav {
180362094060SCosmin Tanislav 	struct ad4130_state *st = container_of(hw, struct ad4130_state, int_clk_hw);
180462094060SCosmin Tanislav 	int ret;
180562094060SCosmin Tanislav 
180662094060SCosmin Tanislav 	ret = ad4130_set_mclk_sel(st, AD4130_MCLK_76_8KHZ);
180762094060SCosmin Tanislav 	if (ret)
180862094060SCosmin Tanislav 		return;
180962094060SCosmin Tanislav 
181062094060SCosmin Tanislav 	st->mclk_sel = AD4130_MCLK_76_8KHZ;
181162094060SCosmin Tanislav }
181262094060SCosmin Tanislav 
181362094060SCosmin Tanislav static const struct clk_ops ad4130_int_clk_ops = {
181462094060SCosmin Tanislav 	.recalc_rate = ad4130_int_clk_recalc_rate,
181562094060SCosmin Tanislav 	.is_enabled = ad4130_int_clk_is_enabled,
181662094060SCosmin Tanislav 	.prepare = ad4130_int_clk_prepare,
181762094060SCosmin Tanislav 	.unprepare = ad4130_int_clk_unprepare,
181862094060SCosmin Tanislav };
181962094060SCosmin Tanislav 
ad4130_clk_del_provider(void * of_node)182028f73dedSLars-Peter Clausen static void ad4130_clk_del_provider(void *of_node)
182128f73dedSLars-Peter Clausen {
182228f73dedSLars-Peter Clausen 	of_clk_del_provider(of_node);
182328f73dedSLars-Peter Clausen }
182428f73dedSLars-Peter Clausen 
ad4130_setup_int_clk(struct ad4130_state * st)182562094060SCosmin Tanislav static int ad4130_setup_int_clk(struct ad4130_state *st)
182662094060SCosmin Tanislav {
182762094060SCosmin Tanislav 	struct device *dev = &st->spi->dev;
182862094060SCosmin Tanislav 	struct device_node *of_node = dev_of_node(dev);
18290e0dab37SCosmin Tanislav 	struct clk_init_data init = {};
183062094060SCosmin Tanislav 	const char *clk_name;
183162094060SCosmin Tanislav 	struct clk *clk;
183228f73dedSLars-Peter Clausen 	int ret;
183362094060SCosmin Tanislav 
183462094060SCosmin Tanislav 	if (st->int_pin_sel == AD4130_INT_PIN_CLK ||
183562094060SCosmin Tanislav 	    st->mclk_sel != AD4130_MCLK_76_8KHZ)
183662094060SCosmin Tanislav 		return 0;
183762094060SCosmin Tanislav 
183862094060SCosmin Tanislav 	if (!of_node)
183962094060SCosmin Tanislav 		return 0;
184062094060SCosmin Tanislav 
184162094060SCosmin Tanislav 	clk_name = of_node->name;
184262094060SCosmin Tanislav 	of_property_read_string(of_node, "clock-output-names", &clk_name);
184362094060SCosmin Tanislav 
184462094060SCosmin Tanislav 	init.name = clk_name;
184562094060SCosmin Tanislav 	init.ops = &ad4130_int_clk_ops;
184662094060SCosmin Tanislav 
184762094060SCosmin Tanislav 	st->int_clk_hw.init = &init;
184862094060SCosmin Tanislav 	clk = devm_clk_register(dev, &st->int_clk_hw);
184962094060SCosmin Tanislav 	if (IS_ERR(clk))
185062094060SCosmin Tanislav 		return PTR_ERR(clk);
185162094060SCosmin Tanislav 
185228f73dedSLars-Peter Clausen 	ret = of_clk_add_provider(of_node, of_clk_src_simple_get, clk);
185328f73dedSLars-Peter Clausen 	if (ret)
185428f73dedSLars-Peter Clausen 		return ret;
185528f73dedSLars-Peter Clausen 
185628f73dedSLars-Peter Clausen 	return devm_add_action_or_reset(dev, ad4130_clk_del_provider, of_node);
185762094060SCosmin Tanislav }
185862094060SCosmin Tanislav 
ad4130_setup(struct iio_dev * indio_dev)185962094060SCosmin Tanislav static int ad4130_setup(struct iio_dev *indio_dev)
186062094060SCosmin Tanislav {
186162094060SCosmin Tanislav 	struct ad4130_state *st = iio_priv(indio_dev);
186262094060SCosmin Tanislav 	struct device *dev = &st->spi->dev;
186362094060SCosmin Tanislav 	unsigned int int_ref_val;
186462094060SCosmin Tanislav 	unsigned long rate = AD4130_MCLK_FREQ_76_8KHZ;
186562094060SCosmin Tanislav 	unsigned int val;
186662094060SCosmin Tanislav 	unsigned int i;
186762094060SCosmin Tanislav 	int ret;
186862094060SCosmin Tanislav 
186962094060SCosmin Tanislav 	if (st->mclk_sel == AD4130_MCLK_153_6KHZ_EXT)
187062094060SCosmin Tanislav 		rate = AD4130_MCLK_FREQ_153_6KHZ;
187162094060SCosmin Tanislav 
187262094060SCosmin Tanislav 	ret = clk_set_rate(st->mclk, rate);
187362094060SCosmin Tanislav 	if (ret)
187462094060SCosmin Tanislav 		return ret;
187562094060SCosmin Tanislav 
187662094060SCosmin Tanislav 	ret = clk_prepare_enable(st->mclk);
187762094060SCosmin Tanislav 	if (ret)
187862094060SCosmin Tanislav 		return ret;
187962094060SCosmin Tanislav 
188062094060SCosmin Tanislav 	ret = devm_add_action_or_reset(dev, ad4130_clk_disable_unprepare,
188162094060SCosmin Tanislav 				       st->mclk);
188262094060SCosmin Tanislav 	if (ret)
188362094060SCosmin Tanislav 		return ret;
188462094060SCosmin Tanislav 
188562094060SCosmin Tanislav 	if (st->int_ref_uv == AD4130_INT_REF_2_5V)
188662094060SCosmin Tanislav 		int_ref_val = AD4130_INT_REF_VAL_2_5V;
188762094060SCosmin Tanislav 	else
188862094060SCosmin Tanislav 		int_ref_val = AD4130_INT_REF_VAL_1_25V;
188962094060SCosmin Tanislav 
189062094060SCosmin Tanislav 	/* Switch to SPI 4-wire mode. */
189162094060SCosmin Tanislav 	val =  FIELD_PREP(AD4130_ADC_CONTROL_CSB_EN_MASK, 1);
189262094060SCosmin Tanislav 	val |= FIELD_PREP(AD4130_ADC_CONTROL_BIPOLAR_MASK, st->bipolar);
189362094060SCosmin Tanislav 	val |= FIELD_PREP(AD4130_ADC_CONTROL_INT_REF_EN_MASK, st->int_ref_en);
189462094060SCosmin Tanislav 	val |= FIELD_PREP(AD4130_ADC_CONTROL_MODE_MASK, AD4130_MODE_IDLE);
189562094060SCosmin Tanislav 	val |= FIELD_PREP(AD4130_ADC_CONTROL_MCLK_SEL_MASK, st->mclk_sel);
189662094060SCosmin Tanislav 	val |= FIELD_PREP(AD4130_ADC_CONTROL_INT_REF_VAL_MASK, int_ref_val);
189762094060SCosmin Tanislav 
189862094060SCosmin Tanislav 	ret = regmap_write(st->regmap, AD4130_ADC_CONTROL_REG, val);
189962094060SCosmin Tanislav 	if (ret)
190062094060SCosmin Tanislav 		return ret;
190162094060SCosmin Tanislav 
190262094060SCosmin Tanislav 	/*
1903*e7f744f6SCosmin Tanislav 	 * Configure unused GPIOs for output. If configured, the interrupt
1904*e7f744f6SCosmin Tanislav 	 * function of P2 takes priority over the GPIO out function.
190562094060SCosmin Tanislav 	 */
1906*e7f744f6SCosmin Tanislav 	val = 0;
1907*e7f744f6SCosmin Tanislav 	for (i = 0; i < AD4130_MAX_GPIOS; i++)
1908*e7f744f6SCosmin Tanislav 		if (st->pins_fn[i + AD4130_AIN2_P1] == AD4130_PIN_FN_NONE)
1909*e7f744f6SCosmin Tanislav 			val |= FIELD_PREP(AD4130_IO_CONTROL_GPIO_CTRL_MASK, BIT(i));
1910*e7f744f6SCosmin Tanislav 
191162094060SCosmin Tanislav 	val |= FIELD_PREP(AD4130_IO_CONTROL_INT_PIN_SEL_MASK, st->int_pin_sel);
191262094060SCosmin Tanislav 
191362094060SCosmin Tanislav 	ret = regmap_write(st->regmap, AD4130_IO_CONTROL_REG, val);
191462094060SCosmin Tanislav 	if (ret)
191562094060SCosmin Tanislav 		return ret;
191662094060SCosmin Tanislav 
191762094060SCosmin Tanislav 	val = 0;
191862094060SCosmin Tanislav 	for (i = 0; i < st->num_vbias_pins; i++)
191962094060SCosmin Tanislav 		val |= BIT(st->vbias_pins[i]);
192062094060SCosmin Tanislav 
192162094060SCosmin Tanislav 	ret = regmap_write(st->regmap, AD4130_VBIAS_REG, val);
192262094060SCosmin Tanislav 	if (ret)
192362094060SCosmin Tanislav 		return ret;
192462094060SCosmin Tanislav 
192562094060SCosmin Tanislav 	ret = regmap_update_bits(st->regmap, AD4130_FIFO_CONTROL_REG,
192662094060SCosmin Tanislav 				 AD4130_FIFO_CONTROL_HEADER_MASK, 0);
192762094060SCosmin Tanislav 	if (ret)
192862094060SCosmin Tanislav 		return ret;
192962094060SCosmin Tanislav 
193062094060SCosmin Tanislav 	/* FIFO watermark interrupt starts out as enabled, disable it. */
193162094060SCosmin Tanislav 	ret = ad4130_set_watermark_interrupt_en(st, false);
193262094060SCosmin Tanislav 	if (ret)
193362094060SCosmin Tanislav 		return ret;
193462094060SCosmin Tanislav 
193562094060SCosmin Tanislav 	/* Setup channels. */
193662094060SCosmin Tanislav 	for (i = 0; i < indio_dev->num_channels; i++) {
193762094060SCosmin Tanislav 		struct ad4130_chan_info *chan_info = &st->chans_info[i];
193862094060SCosmin Tanislav 		struct iio_chan_spec *chan = &st->chans[i];
193962094060SCosmin Tanislav 		unsigned int val;
194062094060SCosmin Tanislav 
194162094060SCosmin Tanislav 		val = FIELD_PREP(AD4130_CHANNEL_AINP_MASK, chan->channel) |
194262094060SCosmin Tanislav 		      FIELD_PREP(AD4130_CHANNEL_AINM_MASK, chan->channel2) |
194362094060SCosmin Tanislav 		      FIELD_PREP(AD4130_CHANNEL_IOUT1_MASK, chan_info->iout0) |
194462094060SCosmin Tanislav 		      FIELD_PREP(AD4130_CHANNEL_IOUT2_MASK, chan_info->iout1);
194562094060SCosmin Tanislav 
194662094060SCosmin Tanislav 		ret = regmap_write(st->regmap, AD4130_CHANNEL_X_REG(i), val);
194762094060SCosmin Tanislav 		if (ret)
194862094060SCosmin Tanislav 			return ret;
194962094060SCosmin Tanislav 	}
195062094060SCosmin Tanislav 
195162094060SCosmin Tanislav 	return 0;
195262094060SCosmin Tanislav }
195362094060SCosmin Tanislav 
ad4130_soft_reset(struct ad4130_state * st)195462094060SCosmin Tanislav static int ad4130_soft_reset(struct ad4130_state *st)
195562094060SCosmin Tanislav {
195662094060SCosmin Tanislav 	int ret;
195762094060SCosmin Tanislav 
195862094060SCosmin Tanislav 	ret = spi_write(st->spi, st->reset_buf, sizeof(st->reset_buf));
195962094060SCosmin Tanislav 	if (ret)
196062094060SCosmin Tanislav 		return ret;
196162094060SCosmin Tanislav 
196262094060SCosmin Tanislav 	fsleep(AD4130_RESET_SLEEP_US);
196362094060SCosmin Tanislav 
196462094060SCosmin Tanislav 	return 0;
196562094060SCosmin Tanislav }
196662094060SCosmin Tanislav 
ad4130_disable_regulators(void * data)196762094060SCosmin Tanislav static void ad4130_disable_regulators(void *data)
196862094060SCosmin Tanislav {
196962094060SCosmin Tanislav 	struct ad4130_state *st = data;
197062094060SCosmin Tanislav 
197162094060SCosmin Tanislav 	regulator_bulk_disable(ARRAY_SIZE(st->regulators), st->regulators);
197262094060SCosmin Tanislav }
197362094060SCosmin Tanislav 
ad4130_probe(struct spi_device * spi)197462094060SCosmin Tanislav static int ad4130_probe(struct spi_device *spi)
197562094060SCosmin Tanislav {
197662094060SCosmin Tanislav 	struct device *dev = &spi->dev;
197762094060SCosmin Tanislav 	struct iio_dev *indio_dev;
197862094060SCosmin Tanislav 	struct ad4130_state *st;
197962094060SCosmin Tanislav 	int ret;
198062094060SCosmin Tanislav 
198162094060SCosmin Tanislav 	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
198262094060SCosmin Tanislav 	if (!indio_dev)
198362094060SCosmin Tanislav 		return -ENOMEM;
198462094060SCosmin Tanislav 
198562094060SCosmin Tanislav 	st = iio_priv(indio_dev);
198662094060SCosmin Tanislav 
198762094060SCosmin Tanislav 	memset(st->reset_buf, 0xff, sizeof(st->reset_buf));
198862094060SCosmin Tanislav 	init_completion(&st->completion);
198962094060SCosmin Tanislav 	mutex_init(&st->lock);
199062094060SCosmin Tanislav 	st->spi = spi;
199162094060SCosmin Tanislav 
199262094060SCosmin Tanislav 	/*
199362094060SCosmin Tanislav 	 * Xfer:   [ XFR1 ] [         XFR2         ]
199462094060SCosmin Tanislav 	 * Master:  0x7D N   ......................
199562094060SCosmin Tanislav 	 * Slave:   ......   DATA1 DATA2 ... DATAN
199662094060SCosmin Tanislav 	 */
199762094060SCosmin Tanislav 	st->fifo_tx_buf[0] = AD4130_COMMS_READ_MASK | AD4130_FIFO_DATA_REG;
199862094060SCosmin Tanislav 	st->fifo_xfer[0].tx_buf = st->fifo_tx_buf;
199962094060SCosmin Tanislav 	st->fifo_xfer[0].len = sizeof(st->fifo_tx_buf);
200062094060SCosmin Tanislav 	st->fifo_xfer[1].rx_buf = st->fifo_rx_buf;
200162094060SCosmin Tanislav 	spi_message_init_with_transfers(&st->fifo_msg, st->fifo_xfer,
200262094060SCosmin Tanislav 					ARRAY_SIZE(st->fifo_xfer));
200362094060SCosmin Tanislav 
200462094060SCosmin Tanislav 	indio_dev->name = AD4130_NAME;
200562094060SCosmin Tanislav 	indio_dev->modes = INDIO_DIRECT_MODE;
200662094060SCosmin Tanislav 	indio_dev->info = &ad4130_info;
200762094060SCosmin Tanislav 
200862094060SCosmin Tanislav 	st->regmap = devm_regmap_init(dev, NULL, st, &ad4130_regmap_config);
200962094060SCosmin Tanislav 	if (IS_ERR(st->regmap))
201062094060SCosmin Tanislav 		return PTR_ERR(st->regmap);
201162094060SCosmin Tanislav 
201262094060SCosmin Tanislav 	st->regulators[0].supply = "avdd";
201362094060SCosmin Tanislav 	st->regulators[1].supply = "iovdd";
201462094060SCosmin Tanislav 	st->regulators[2].supply = "refin1";
201562094060SCosmin Tanislav 	st->regulators[3].supply = "refin2";
201662094060SCosmin Tanislav 
201762094060SCosmin Tanislav 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(st->regulators),
201862094060SCosmin Tanislav 				      st->regulators);
201962094060SCosmin Tanislav 	if (ret)
202062094060SCosmin Tanislav 		return dev_err_probe(dev, ret, "Failed to get regulators\n");
202162094060SCosmin Tanislav 
202262094060SCosmin Tanislav 	ret = regulator_bulk_enable(ARRAY_SIZE(st->regulators), st->regulators);
202362094060SCosmin Tanislav 	if (ret)
202462094060SCosmin Tanislav 		return dev_err_probe(dev, ret, "Failed to enable regulators\n");
202562094060SCosmin Tanislav 
202662094060SCosmin Tanislav 	ret = devm_add_action_or_reset(dev, ad4130_disable_regulators, st);
202762094060SCosmin Tanislav 	if (ret)
202862094060SCosmin Tanislav 		return dev_err_probe(dev, ret,
202962094060SCosmin Tanislav 				     "Failed to add regulators disable action\n");
203062094060SCosmin Tanislav 
203162094060SCosmin Tanislav 	ret = ad4130_soft_reset(st);
203262094060SCosmin Tanislav 	if (ret)
203362094060SCosmin Tanislav 		return ret;
203462094060SCosmin Tanislav 
203562094060SCosmin Tanislav 	ret = ad4310_parse_fw(indio_dev);
203662094060SCosmin Tanislav 	if (ret)
203762094060SCosmin Tanislav 		return ret;
203862094060SCosmin Tanislav 
203962094060SCosmin Tanislav 	ret = ad4130_setup(indio_dev);
204062094060SCosmin Tanislav 	if (ret)
204162094060SCosmin Tanislav 		return ret;
204262094060SCosmin Tanislav 
204362094060SCosmin Tanislav 	ret = ad4130_setup_int_clk(st);
204462094060SCosmin Tanislav 	if (ret)
204562094060SCosmin Tanislav 		return ret;
204662094060SCosmin Tanislav 
204762094060SCosmin Tanislav 	ad4130_fill_scale_tbls(st);
204862094060SCosmin Tanislav 
204962094060SCosmin Tanislav 	st->gc.owner = THIS_MODULE;
205062094060SCosmin Tanislav 	st->gc.label = AD4130_NAME;
205162094060SCosmin Tanislav 	st->gc.base = -1;
205262094060SCosmin Tanislav 	st->gc.ngpio = AD4130_MAX_GPIOS;
205362094060SCosmin Tanislav 	st->gc.parent = dev;
205462094060SCosmin Tanislav 	st->gc.can_sleep = true;
205562094060SCosmin Tanislav 	st->gc.init_valid_mask = ad4130_gpio_init_valid_mask;
205662094060SCosmin Tanislav 	st->gc.get_direction = ad4130_gpio_get_direction;
205762094060SCosmin Tanislav 	st->gc.set = ad4130_gpio_set;
205862094060SCosmin Tanislav 
205962094060SCosmin Tanislav 	ret = devm_gpiochip_add_data(dev, &st->gc, st);
206062094060SCosmin Tanislav 	if (ret)
206162094060SCosmin Tanislav 		return ret;
206262094060SCosmin Tanislav 
206362094060SCosmin Tanislav 	ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev,
206462094060SCosmin Tanislav 					      &ad4130_buffer_ops,
206562094060SCosmin Tanislav 					      ad4130_fifo_attributes);
206662094060SCosmin Tanislav 	if (ret)
206762094060SCosmin Tanislav 		return ret;
206862094060SCosmin Tanislav 
206962094060SCosmin Tanislav 	ret = devm_request_threaded_irq(dev, spi->irq, NULL,
207062094060SCosmin Tanislav 					ad4130_irq_handler, IRQF_ONESHOT,
207162094060SCosmin Tanislav 					indio_dev->name, indio_dev);
207262094060SCosmin Tanislav 	if (ret)
207362094060SCosmin Tanislav 		return dev_err_probe(dev, ret, "Failed to request irq\n");
207462094060SCosmin Tanislav 
207562094060SCosmin Tanislav 	/*
207662094060SCosmin Tanislav 	 * When the chip enters FIFO mode, IRQ polarity is inverted.
207762094060SCosmin Tanislav 	 * When the chip exits FIFO mode, IRQ polarity returns to normal.
207862094060SCosmin Tanislav 	 * See datasheet pages: 65, FIFO Watermark Interrupt section,
207962094060SCosmin Tanislav 	 * and 71, Bit Descriptions for STATUS Register, RDYB.
208062094060SCosmin Tanislav 	 * Cache the normal and inverted IRQ triggers to set them when
208162094060SCosmin Tanislav 	 * entering and exiting FIFO mode.
208262094060SCosmin Tanislav 	 */
208362094060SCosmin Tanislav 	st->irq_trigger = irq_get_trigger_type(spi->irq);
208462094060SCosmin Tanislav 	if (st->irq_trigger & IRQF_TRIGGER_RISING)
208562094060SCosmin Tanislav 		st->inv_irq_trigger = IRQF_TRIGGER_FALLING;
208662094060SCosmin Tanislav 	else if (st->irq_trigger & IRQF_TRIGGER_FALLING)
208762094060SCosmin Tanislav 		st->inv_irq_trigger = IRQF_TRIGGER_RISING;
208862094060SCosmin Tanislav 	else
208962094060SCosmin Tanislav 		return dev_err_probe(dev, -EINVAL, "Invalid irq flags: %u\n",
209062094060SCosmin Tanislav 				     st->irq_trigger);
209162094060SCosmin Tanislav 
209262094060SCosmin Tanislav 	return devm_iio_device_register(dev, indio_dev);
209362094060SCosmin Tanislav }
209462094060SCosmin Tanislav 
209562094060SCosmin Tanislav static const struct of_device_id ad4130_of_match[] = {
209662094060SCosmin Tanislav 	{
209762094060SCosmin Tanislav 		.compatible = "adi,ad4130",
209862094060SCosmin Tanislav 	},
209962094060SCosmin Tanislav 	{ }
210062094060SCosmin Tanislav };
210162094060SCosmin Tanislav MODULE_DEVICE_TABLE(of, ad4130_of_match);
210262094060SCosmin Tanislav 
210362094060SCosmin Tanislav static struct spi_driver ad4130_driver = {
210462094060SCosmin Tanislav 	.driver = {
210562094060SCosmin Tanislav 		.name = AD4130_NAME,
210662094060SCosmin Tanislav 		.of_match_table = ad4130_of_match,
210762094060SCosmin Tanislav 	},
210862094060SCosmin Tanislav 	.probe = ad4130_probe,
210962094060SCosmin Tanislav };
211062094060SCosmin Tanislav module_spi_driver(ad4130_driver);
211162094060SCosmin Tanislav 
211262094060SCosmin Tanislav MODULE_AUTHOR("Cosmin Tanislav <cosmin.tanislav@analog.com>");
211362094060SCosmin Tanislav MODULE_DESCRIPTION("Analog Devices AD4130 SPI driver");
211462094060SCosmin Tanislav MODULE_LICENSE("GPL");
2115