162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Analog Devices AD7768-1 SPI ADC driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2017 Analog Devices Inc.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#include <linux/bitfield.h>
862306a36Sopenharmony_ci#include <linux/clk.h>
962306a36Sopenharmony_ci#include <linux/delay.h>
1062306a36Sopenharmony_ci#include <linux/device.h>
1162306a36Sopenharmony_ci#include <linux/err.h>
1262306a36Sopenharmony_ci#include <linux/gpio/consumer.h>
1362306a36Sopenharmony_ci#include <linux/kernel.h>
1462306a36Sopenharmony_ci#include <linux/module.h>
1562306a36Sopenharmony_ci#include <linux/regulator/consumer.h>
1662306a36Sopenharmony_ci#include <linux/sysfs.h>
1762306a36Sopenharmony_ci#include <linux/spi/spi.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include <linux/iio/buffer.h>
2062306a36Sopenharmony_ci#include <linux/iio/iio.h>
2162306a36Sopenharmony_ci#include <linux/iio/sysfs.h>
2262306a36Sopenharmony_ci#include <linux/iio/trigger.h>
2362306a36Sopenharmony_ci#include <linux/iio/triggered_buffer.h>
2462306a36Sopenharmony_ci#include <linux/iio/trigger_consumer.h>
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci/* AD7768 registers definition */
2762306a36Sopenharmony_ci#define AD7768_REG_CHIP_TYPE		0x3
2862306a36Sopenharmony_ci#define AD7768_REG_PROD_ID_L		0x4
2962306a36Sopenharmony_ci#define AD7768_REG_PROD_ID_H		0x5
3062306a36Sopenharmony_ci#define AD7768_REG_CHIP_GRADE		0x6
3162306a36Sopenharmony_ci#define AD7768_REG_SCRATCH_PAD		0x0A
3262306a36Sopenharmony_ci#define AD7768_REG_VENDOR_L		0x0C
3362306a36Sopenharmony_ci#define AD7768_REG_VENDOR_H		0x0D
3462306a36Sopenharmony_ci#define AD7768_REG_INTERFACE_FORMAT	0x14
3562306a36Sopenharmony_ci#define AD7768_REG_POWER_CLOCK		0x15
3662306a36Sopenharmony_ci#define AD7768_REG_ANALOG		0x16
3762306a36Sopenharmony_ci#define AD7768_REG_ANALOG2		0x17
3862306a36Sopenharmony_ci#define AD7768_REG_CONVERSION		0x18
3962306a36Sopenharmony_ci#define AD7768_REG_DIGITAL_FILTER	0x19
4062306a36Sopenharmony_ci#define AD7768_REG_SINC3_DEC_RATE_MSB	0x1A
4162306a36Sopenharmony_ci#define AD7768_REG_SINC3_DEC_RATE_LSB	0x1B
4262306a36Sopenharmony_ci#define AD7768_REG_DUTY_CYCLE_RATIO	0x1C
4362306a36Sopenharmony_ci#define AD7768_REG_SYNC_RESET		0x1D
4462306a36Sopenharmony_ci#define AD7768_REG_GPIO_CONTROL		0x1E
4562306a36Sopenharmony_ci#define AD7768_REG_GPIO_WRITE		0x1F
4662306a36Sopenharmony_ci#define AD7768_REG_GPIO_READ		0x20
4762306a36Sopenharmony_ci#define AD7768_REG_OFFSET_HI		0x21
4862306a36Sopenharmony_ci#define AD7768_REG_OFFSET_MID		0x22
4962306a36Sopenharmony_ci#define AD7768_REG_OFFSET_LO		0x23
5062306a36Sopenharmony_ci#define AD7768_REG_GAIN_HI		0x24
5162306a36Sopenharmony_ci#define AD7768_REG_GAIN_MID		0x25
5262306a36Sopenharmony_ci#define AD7768_REG_GAIN_LO		0x26
5362306a36Sopenharmony_ci#define AD7768_REG_SPI_DIAG_ENABLE	0x28
5462306a36Sopenharmony_ci#define AD7768_REG_ADC_DIAG_ENABLE	0x29
5562306a36Sopenharmony_ci#define AD7768_REG_DIG_DIAG_ENABLE	0x2A
5662306a36Sopenharmony_ci#define AD7768_REG_ADC_DATA		0x2C
5762306a36Sopenharmony_ci#define AD7768_REG_MASTER_STATUS	0x2D
5862306a36Sopenharmony_ci#define AD7768_REG_SPI_DIAG_STATUS	0x2E
5962306a36Sopenharmony_ci#define AD7768_REG_ADC_DIAG_STATUS	0x2F
6062306a36Sopenharmony_ci#define AD7768_REG_DIG_DIAG_STATUS	0x30
6162306a36Sopenharmony_ci#define AD7768_REG_MCLK_COUNTER		0x31
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci/* AD7768_REG_POWER_CLOCK */
6462306a36Sopenharmony_ci#define AD7768_PWR_MCLK_DIV_MSK		GENMASK(5, 4)
6562306a36Sopenharmony_ci#define AD7768_PWR_MCLK_DIV(x)		FIELD_PREP(AD7768_PWR_MCLK_DIV_MSK, x)
6662306a36Sopenharmony_ci#define AD7768_PWR_PWRMODE_MSK		GENMASK(1, 0)
6762306a36Sopenharmony_ci#define AD7768_PWR_PWRMODE(x)		FIELD_PREP(AD7768_PWR_PWRMODE_MSK, x)
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci/* AD7768_REG_DIGITAL_FILTER */
7062306a36Sopenharmony_ci#define AD7768_DIG_FIL_FIL_MSK		GENMASK(6, 4)
7162306a36Sopenharmony_ci#define AD7768_DIG_FIL_FIL(x)		FIELD_PREP(AD7768_DIG_FIL_FIL_MSK, x)
7262306a36Sopenharmony_ci#define AD7768_DIG_FIL_DEC_MSK		GENMASK(2, 0)
7362306a36Sopenharmony_ci#define AD7768_DIG_FIL_DEC_RATE(x)	FIELD_PREP(AD7768_DIG_FIL_DEC_MSK, x)
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci/* AD7768_REG_CONVERSION */
7662306a36Sopenharmony_ci#define AD7768_CONV_MODE_MSK		GENMASK(2, 0)
7762306a36Sopenharmony_ci#define AD7768_CONV_MODE(x)		FIELD_PREP(AD7768_CONV_MODE_MSK, x)
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci#define AD7768_RD_FLAG_MSK(x)		(BIT(6) | ((x) & 0x3F))
8062306a36Sopenharmony_ci#define AD7768_WR_FLAG_MSK(x)		((x) & 0x3F)
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cienum ad7768_conv_mode {
8362306a36Sopenharmony_ci	AD7768_CONTINUOUS,
8462306a36Sopenharmony_ci	AD7768_ONE_SHOT,
8562306a36Sopenharmony_ci	AD7768_SINGLE,
8662306a36Sopenharmony_ci	AD7768_PERIODIC,
8762306a36Sopenharmony_ci	AD7768_STANDBY
8862306a36Sopenharmony_ci};
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_cienum ad7768_pwrmode {
9162306a36Sopenharmony_ci	AD7768_ECO_MODE = 0,
9262306a36Sopenharmony_ci	AD7768_MED_MODE = 2,
9362306a36Sopenharmony_ci	AD7768_FAST_MODE = 3
9462306a36Sopenharmony_ci};
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_cienum ad7768_mclk_div {
9762306a36Sopenharmony_ci	AD7768_MCLK_DIV_16,
9862306a36Sopenharmony_ci	AD7768_MCLK_DIV_8,
9962306a36Sopenharmony_ci	AD7768_MCLK_DIV_4,
10062306a36Sopenharmony_ci	AD7768_MCLK_DIV_2
10162306a36Sopenharmony_ci};
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cienum ad7768_dec_rate {
10462306a36Sopenharmony_ci	AD7768_DEC_RATE_32 = 0,
10562306a36Sopenharmony_ci	AD7768_DEC_RATE_64 = 1,
10662306a36Sopenharmony_ci	AD7768_DEC_RATE_128 = 2,
10762306a36Sopenharmony_ci	AD7768_DEC_RATE_256 = 3,
10862306a36Sopenharmony_ci	AD7768_DEC_RATE_512 = 4,
10962306a36Sopenharmony_ci	AD7768_DEC_RATE_1024 = 5,
11062306a36Sopenharmony_ci	AD7768_DEC_RATE_8 = 9,
11162306a36Sopenharmony_ci	AD7768_DEC_RATE_16 = 10
11262306a36Sopenharmony_ci};
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistruct ad7768_clk_configuration {
11562306a36Sopenharmony_ci	enum ad7768_mclk_div mclk_div;
11662306a36Sopenharmony_ci	enum ad7768_dec_rate dec_rate;
11762306a36Sopenharmony_ci	unsigned int clk_div;
11862306a36Sopenharmony_ci	enum ad7768_pwrmode pwrmode;
11962306a36Sopenharmony_ci};
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistatic const struct ad7768_clk_configuration ad7768_clk_config[] = {
12262306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_2, AD7768_DEC_RATE_8, 16,  AD7768_FAST_MODE },
12362306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_2, AD7768_DEC_RATE_16, 32,  AD7768_FAST_MODE },
12462306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_2, AD7768_DEC_RATE_32, 64, AD7768_FAST_MODE },
12562306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_2, AD7768_DEC_RATE_64, 128, AD7768_FAST_MODE },
12662306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_2, AD7768_DEC_RATE_128, 256, AD7768_FAST_MODE },
12762306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_4, AD7768_DEC_RATE_128, 512, AD7768_MED_MODE },
12862306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_4, AD7768_DEC_RATE_256, 1024, AD7768_MED_MODE },
12962306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_4, AD7768_DEC_RATE_512, 2048, AD7768_MED_MODE },
13062306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_4, AD7768_DEC_RATE_1024, 4096, AD7768_MED_MODE },
13162306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_8, AD7768_DEC_RATE_1024, 8192, AD7768_MED_MODE },
13262306a36Sopenharmony_ci	{ AD7768_MCLK_DIV_16, AD7768_DEC_RATE_1024, 16384, AD7768_ECO_MODE },
13362306a36Sopenharmony_ci};
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic const struct iio_chan_spec ad7768_channels[] = {
13662306a36Sopenharmony_ci	{
13762306a36Sopenharmony_ci		.type = IIO_VOLTAGE,
13862306a36Sopenharmony_ci		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
13962306a36Sopenharmony_ci		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
14062306a36Sopenharmony_ci		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
14162306a36Sopenharmony_ci		.indexed = 1,
14262306a36Sopenharmony_ci		.channel = 0,
14362306a36Sopenharmony_ci		.scan_index = 0,
14462306a36Sopenharmony_ci		.scan_type = {
14562306a36Sopenharmony_ci			.sign = 'u',
14662306a36Sopenharmony_ci			.realbits = 24,
14762306a36Sopenharmony_ci			.storagebits = 32,
14862306a36Sopenharmony_ci			.shift = 8,
14962306a36Sopenharmony_ci			.endianness = IIO_BE,
15062306a36Sopenharmony_ci		},
15162306a36Sopenharmony_ci	},
15262306a36Sopenharmony_ci};
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_cistruct ad7768_state {
15562306a36Sopenharmony_ci	struct spi_device *spi;
15662306a36Sopenharmony_ci	struct regulator *vref;
15762306a36Sopenharmony_ci	struct mutex lock;
15862306a36Sopenharmony_ci	struct clk *mclk;
15962306a36Sopenharmony_ci	unsigned int mclk_freq;
16062306a36Sopenharmony_ci	unsigned int samp_freq;
16162306a36Sopenharmony_ci	struct completion completion;
16262306a36Sopenharmony_ci	struct iio_trigger *trig;
16362306a36Sopenharmony_ci	struct gpio_desc *gpio_sync_in;
16462306a36Sopenharmony_ci	const char *labels[ARRAY_SIZE(ad7768_channels)];
16562306a36Sopenharmony_ci	/*
16662306a36Sopenharmony_ci	 * DMA (thus cache coherency maintenance) may require the
16762306a36Sopenharmony_ci	 * transfer buffers to live in their own cache lines.
16862306a36Sopenharmony_ci	 */
16962306a36Sopenharmony_ci	union {
17062306a36Sopenharmony_ci		struct {
17162306a36Sopenharmony_ci			__be32 chan;
17262306a36Sopenharmony_ci			s64 timestamp;
17362306a36Sopenharmony_ci		} scan;
17462306a36Sopenharmony_ci		__be32 d32;
17562306a36Sopenharmony_ci		u8 d8[2];
17662306a36Sopenharmony_ci	} data __aligned(IIO_DMA_MINALIGN);
17762306a36Sopenharmony_ci};
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_cistatic int ad7768_spi_reg_read(struct ad7768_state *st, unsigned int addr,
18062306a36Sopenharmony_ci			       unsigned int len)
18162306a36Sopenharmony_ci{
18262306a36Sopenharmony_ci	unsigned int shift;
18362306a36Sopenharmony_ci	int ret;
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	shift = 32 - (8 * len);
18662306a36Sopenharmony_ci	st->data.d8[0] = AD7768_RD_FLAG_MSK(addr);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	ret = spi_write_then_read(st->spi, st->data.d8, 1,
18962306a36Sopenharmony_ci				  &st->data.d32, len);
19062306a36Sopenharmony_ci	if (ret < 0)
19162306a36Sopenharmony_ci		return ret;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	return (be32_to_cpu(st->data.d32) >> shift);
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_cistatic int ad7768_spi_reg_write(struct ad7768_state *st,
19762306a36Sopenharmony_ci				unsigned int addr,
19862306a36Sopenharmony_ci				unsigned int val)
19962306a36Sopenharmony_ci{
20062306a36Sopenharmony_ci	st->data.d8[0] = AD7768_WR_FLAG_MSK(addr);
20162306a36Sopenharmony_ci	st->data.d8[1] = val & 0xFF;
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	return spi_write(st->spi, st->data.d8, 2);
20462306a36Sopenharmony_ci}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_cistatic int ad7768_set_mode(struct ad7768_state *st,
20762306a36Sopenharmony_ci			   enum ad7768_conv_mode mode)
20862306a36Sopenharmony_ci{
20962306a36Sopenharmony_ci	int regval;
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	regval = ad7768_spi_reg_read(st, AD7768_REG_CONVERSION, 1);
21262306a36Sopenharmony_ci	if (regval < 0)
21362306a36Sopenharmony_ci		return regval;
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	regval &= ~AD7768_CONV_MODE_MSK;
21662306a36Sopenharmony_ci	regval |= AD7768_CONV_MODE(mode);
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	return ad7768_spi_reg_write(st, AD7768_REG_CONVERSION, regval);
21962306a36Sopenharmony_ci}
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_cistatic int ad7768_scan_direct(struct iio_dev *indio_dev)
22262306a36Sopenharmony_ci{
22362306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
22462306a36Sopenharmony_ci	int readval, ret;
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	reinit_completion(&st->completion);
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	ret = ad7768_set_mode(st, AD7768_ONE_SHOT);
22962306a36Sopenharmony_ci	if (ret < 0)
23062306a36Sopenharmony_ci		return ret;
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	ret = wait_for_completion_timeout(&st->completion,
23362306a36Sopenharmony_ci					  msecs_to_jiffies(1000));
23462306a36Sopenharmony_ci	if (!ret)
23562306a36Sopenharmony_ci		return -ETIMEDOUT;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	readval = ad7768_spi_reg_read(st, AD7768_REG_ADC_DATA, 3);
23862306a36Sopenharmony_ci	if (readval < 0)
23962306a36Sopenharmony_ci		return readval;
24062306a36Sopenharmony_ci	/*
24162306a36Sopenharmony_ci	 * Any SPI configuration of the AD7768-1 can only be
24262306a36Sopenharmony_ci	 * performed in continuous conversion mode.
24362306a36Sopenharmony_ci	 */
24462306a36Sopenharmony_ci	ret = ad7768_set_mode(st, AD7768_CONTINUOUS);
24562306a36Sopenharmony_ci	if (ret < 0)
24662306a36Sopenharmony_ci		return ret;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	return readval;
24962306a36Sopenharmony_ci}
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cistatic int ad7768_reg_access(struct iio_dev *indio_dev,
25262306a36Sopenharmony_ci			     unsigned int reg,
25362306a36Sopenharmony_ci			     unsigned int writeval,
25462306a36Sopenharmony_ci			     unsigned int *readval)
25562306a36Sopenharmony_ci{
25662306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
25762306a36Sopenharmony_ci	int ret;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	mutex_lock(&st->lock);
26062306a36Sopenharmony_ci	if (readval) {
26162306a36Sopenharmony_ci		ret = ad7768_spi_reg_read(st, reg, 1);
26262306a36Sopenharmony_ci		if (ret < 0)
26362306a36Sopenharmony_ci			goto err_unlock;
26462306a36Sopenharmony_ci		*readval = ret;
26562306a36Sopenharmony_ci		ret = 0;
26662306a36Sopenharmony_ci	} else {
26762306a36Sopenharmony_ci		ret = ad7768_spi_reg_write(st, reg, writeval);
26862306a36Sopenharmony_ci	}
26962306a36Sopenharmony_cierr_unlock:
27062306a36Sopenharmony_ci	mutex_unlock(&st->lock);
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	return ret;
27362306a36Sopenharmony_ci}
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_cistatic int ad7768_set_dig_fil(struct ad7768_state *st,
27662306a36Sopenharmony_ci			      enum ad7768_dec_rate dec_rate)
27762306a36Sopenharmony_ci{
27862306a36Sopenharmony_ci	unsigned int mode;
27962306a36Sopenharmony_ci	int ret;
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	if (dec_rate == AD7768_DEC_RATE_8 || dec_rate == AD7768_DEC_RATE_16)
28262306a36Sopenharmony_ci		mode = AD7768_DIG_FIL_FIL(dec_rate);
28362306a36Sopenharmony_ci	else
28462306a36Sopenharmony_ci		mode = AD7768_DIG_FIL_DEC_RATE(dec_rate);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	ret = ad7768_spi_reg_write(st, AD7768_REG_DIGITAL_FILTER, mode);
28762306a36Sopenharmony_ci	if (ret < 0)
28862306a36Sopenharmony_ci		return ret;
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci	/* A sync-in pulse is required every time the filter dec rate changes */
29162306a36Sopenharmony_ci	gpiod_set_value(st->gpio_sync_in, 1);
29262306a36Sopenharmony_ci	gpiod_set_value(st->gpio_sync_in, 0);
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	return 0;
29562306a36Sopenharmony_ci}
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_cistatic int ad7768_set_freq(struct ad7768_state *st,
29862306a36Sopenharmony_ci			   unsigned int freq)
29962306a36Sopenharmony_ci{
30062306a36Sopenharmony_ci	unsigned int diff_new, diff_old, pwr_mode, i, idx;
30162306a36Sopenharmony_ci	int res, ret;
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	diff_old = U32_MAX;
30462306a36Sopenharmony_ci	idx = 0;
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	res = DIV_ROUND_CLOSEST(st->mclk_freq, freq);
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	/* Find the closest match for the desired sampling frequency */
30962306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(ad7768_clk_config); i++) {
31062306a36Sopenharmony_ci		diff_new = abs(res - ad7768_clk_config[i].clk_div);
31162306a36Sopenharmony_ci		if (diff_new < diff_old) {
31262306a36Sopenharmony_ci			diff_old = diff_new;
31362306a36Sopenharmony_ci			idx = i;
31462306a36Sopenharmony_ci		}
31562306a36Sopenharmony_ci	}
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	/*
31862306a36Sopenharmony_ci	 * Set both the mclk_div and pwrmode with a single write to the
31962306a36Sopenharmony_ci	 * POWER_CLOCK register
32062306a36Sopenharmony_ci	 */
32162306a36Sopenharmony_ci	pwr_mode = AD7768_PWR_MCLK_DIV(ad7768_clk_config[idx].mclk_div) |
32262306a36Sopenharmony_ci		   AD7768_PWR_PWRMODE(ad7768_clk_config[idx].pwrmode);
32362306a36Sopenharmony_ci	ret = ad7768_spi_reg_write(st, AD7768_REG_POWER_CLOCK, pwr_mode);
32462306a36Sopenharmony_ci	if (ret < 0)
32562306a36Sopenharmony_ci		return ret;
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	ret =  ad7768_set_dig_fil(st, ad7768_clk_config[idx].dec_rate);
32862306a36Sopenharmony_ci	if (ret < 0)
32962306a36Sopenharmony_ci		return ret;
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	st->samp_freq = DIV_ROUND_CLOSEST(st->mclk_freq,
33262306a36Sopenharmony_ci					  ad7768_clk_config[idx].clk_div);
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	return 0;
33562306a36Sopenharmony_ci}
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_cistatic ssize_t ad7768_sampling_freq_avail(struct device *dev,
33862306a36Sopenharmony_ci					  struct device_attribute *attr,
33962306a36Sopenharmony_ci					  char *buf)
34062306a36Sopenharmony_ci{
34162306a36Sopenharmony_ci	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
34262306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
34362306a36Sopenharmony_ci	unsigned int freq;
34462306a36Sopenharmony_ci	int i, len = 0;
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(ad7768_clk_config); i++) {
34762306a36Sopenharmony_ci		freq = DIV_ROUND_CLOSEST(st->mclk_freq,
34862306a36Sopenharmony_ci					 ad7768_clk_config[i].clk_div);
34962306a36Sopenharmony_ci		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", freq);
35062306a36Sopenharmony_ci	}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	buf[len - 1] = '\n';
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	return len;
35562306a36Sopenharmony_ci}
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_cistatic IIO_DEV_ATTR_SAMP_FREQ_AVAIL(ad7768_sampling_freq_avail);
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_cistatic int ad7768_read_raw(struct iio_dev *indio_dev,
36062306a36Sopenharmony_ci			   struct iio_chan_spec const *chan,
36162306a36Sopenharmony_ci			   int *val, int *val2, long info)
36262306a36Sopenharmony_ci{
36362306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
36462306a36Sopenharmony_ci	int scale_uv, ret;
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	switch (info) {
36762306a36Sopenharmony_ci	case IIO_CHAN_INFO_RAW:
36862306a36Sopenharmony_ci		ret = iio_device_claim_direct_mode(indio_dev);
36962306a36Sopenharmony_ci		if (ret)
37062306a36Sopenharmony_ci			return ret;
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci		ret = ad7768_scan_direct(indio_dev);
37362306a36Sopenharmony_ci		if (ret >= 0)
37462306a36Sopenharmony_ci			*val = ret;
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci		iio_device_release_direct_mode(indio_dev);
37762306a36Sopenharmony_ci		if (ret < 0)
37862306a36Sopenharmony_ci			return ret;
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci		return IIO_VAL_INT;
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
38362306a36Sopenharmony_ci		scale_uv = regulator_get_voltage(st->vref);
38462306a36Sopenharmony_ci		if (scale_uv < 0)
38562306a36Sopenharmony_ci			return scale_uv;
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci		*val = (scale_uv * 2) / 1000;
38862306a36Sopenharmony_ci		*val2 = chan->scan_type.realbits;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci		return IIO_VAL_FRACTIONAL_LOG2;
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	case IIO_CHAN_INFO_SAMP_FREQ:
39362306a36Sopenharmony_ci		*val = st->samp_freq;
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci		return IIO_VAL_INT;
39662306a36Sopenharmony_ci	}
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	return -EINVAL;
39962306a36Sopenharmony_ci}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_cistatic int ad7768_write_raw(struct iio_dev *indio_dev,
40262306a36Sopenharmony_ci			    struct iio_chan_spec const *chan,
40362306a36Sopenharmony_ci			    int val, int val2, long info)
40462306a36Sopenharmony_ci{
40562306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci	switch (info) {
40862306a36Sopenharmony_ci	case IIO_CHAN_INFO_SAMP_FREQ:
40962306a36Sopenharmony_ci		return ad7768_set_freq(st, val);
41062306a36Sopenharmony_ci	default:
41162306a36Sopenharmony_ci		return -EINVAL;
41262306a36Sopenharmony_ci	}
41362306a36Sopenharmony_ci}
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_cistatic int ad7768_read_label(struct iio_dev *indio_dev,
41662306a36Sopenharmony_ci	const struct iio_chan_spec *chan, char *label)
41762306a36Sopenharmony_ci{
41862306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci	return sprintf(label, "%s\n", st->labels[chan->channel]);
42162306a36Sopenharmony_ci}
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_cistatic struct attribute *ad7768_attributes[] = {
42462306a36Sopenharmony_ci	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
42562306a36Sopenharmony_ci	NULL
42662306a36Sopenharmony_ci};
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_cistatic const struct attribute_group ad7768_group = {
42962306a36Sopenharmony_ci	.attrs = ad7768_attributes,
43062306a36Sopenharmony_ci};
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_cistatic const struct iio_info ad7768_info = {
43362306a36Sopenharmony_ci	.attrs = &ad7768_group,
43462306a36Sopenharmony_ci	.read_raw = &ad7768_read_raw,
43562306a36Sopenharmony_ci	.write_raw = &ad7768_write_raw,
43662306a36Sopenharmony_ci	.read_label = ad7768_read_label,
43762306a36Sopenharmony_ci	.debugfs_reg_access = &ad7768_reg_access,
43862306a36Sopenharmony_ci};
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_cistatic int ad7768_setup(struct ad7768_state *st)
44162306a36Sopenharmony_ci{
44262306a36Sopenharmony_ci	int ret;
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci	/*
44562306a36Sopenharmony_ci	 * Two writes to the SPI_RESET[1:0] bits are required to initiate
44662306a36Sopenharmony_ci	 * a software reset. The bits must first be set to 11, and then
44762306a36Sopenharmony_ci	 * to 10. When the sequence is detected, the reset occurs.
44862306a36Sopenharmony_ci	 * See the datasheet, page 70.
44962306a36Sopenharmony_ci	 */
45062306a36Sopenharmony_ci	ret = ad7768_spi_reg_write(st, AD7768_REG_SYNC_RESET, 0x3);
45162306a36Sopenharmony_ci	if (ret)
45262306a36Sopenharmony_ci		return ret;
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci	ret = ad7768_spi_reg_write(st, AD7768_REG_SYNC_RESET, 0x2);
45562306a36Sopenharmony_ci	if (ret)
45662306a36Sopenharmony_ci		return ret;
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci	st->gpio_sync_in = devm_gpiod_get(&st->spi->dev, "adi,sync-in",
45962306a36Sopenharmony_ci					  GPIOD_OUT_LOW);
46062306a36Sopenharmony_ci	if (IS_ERR(st->gpio_sync_in))
46162306a36Sopenharmony_ci		return PTR_ERR(st->gpio_sync_in);
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	/* Set the default sampling frequency to 32000 kSPS */
46462306a36Sopenharmony_ci	return ad7768_set_freq(st, 32000);
46562306a36Sopenharmony_ci}
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_cistatic irqreturn_t ad7768_trigger_handler(int irq, void *p)
46862306a36Sopenharmony_ci{
46962306a36Sopenharmony_ci	struct iio_poll_func *pf = p;
47062306a36Sopenharmony_ci	struct iio_dev *indio_dev = pf->indio_dev;
47162306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
47262306a36Sopenharmony_ci	int ret;
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ci	mutex_lock(&st->lock);
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	ret = spi_read(st->spi, &st->data.scan.chan, 3);
47762306a36Sopenharmony_ci	if (ret < 0)
47862306a36Sopenharmony_ci		goto err_unlock;
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci	iio_push_to_buffers_with_timestamp(indio_dev, &st->data.scan,
48162306a36Sopenharmony_ci					   iio_get_time_ns(indio_dev));
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_cierr_unlock:
48462306a36Sopenharmony_ci	iio_trigger_notify_done(indio_dev->trig);
48562306a36Sopenharmony_ci	mutex_unlock(&st->lock);
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	return IRQ_HANDLED;
48862306a36Sopenharmony_ci}
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_cistatic irqreturn_t ad7768_interrupt(int irq, void *dev_id)
49162306a36Sopenharmony_ci{
49262306a36Sopenharmony_ci	struct iio_dev *indio_dev = dev_id;
49362306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	if (iio_buffer_enabled(indio_dev))
49662306a36Sopenharmony_ci		iio_trigger_poll(st->trig);
49762306a36Sopenharmony_ci	else
49862306a36Sopenharmony_ci		complete(&st->completion);
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	return IRQ_HANDLED;
50162306a36Sopenharmony_ci};
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_cistatic int ad7768_buffer_postenable(struct iio_dev *indio_dev)
50462306a36Sopenharmony_ci{
50562306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	/*
50862306a36Sopenharmony_ci	 * Write a 1 to the LSB of the INTERFACE_FORMAT register to enter
50962306a36Sopenharmony_ci	 * continuous read mode. Subsequent data reads do not require an
51062306a36Sopenharmony_ci	 * initial 8-bit write to query the ADC_DATA register.
51162306a36Sopenharmony_ci	 */
51262306a36Sopenharmony_ci	return ad7768_spi_reg_write(st, AD7768_REG_INTERFACE_FORMAT, 0x01);
51362306a36Sopenharmony_ci}
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_cistatic int ad7768_buffer_predisable(struct iio_dev *indio_dev)
51662306a36Sopenharmony_ci{
51762306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	/*
52062306a36Sopenharmony_ci	 * To exit continuous read mode, perform a single read of the ADC_DATA
52162306a36Sopenharmony_ci	 * reg (0x2C), which allows further configuration of the device.
52262306a36Sopenharmony_ci	 */
52362306a36Sopenharmony_ci	return ad7768_spi_reg_read(st, AD7768_REG_ADC_DATA, 3);
52462306a36Sopenharmony_ci}
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_cistatic const struct iio_buffer_setup_ops ad7768_buffer_ops = {
52762306a36Sopenharmony_ci	.postenable = &ad7768_buffer_postenable,
52862306a36Sopenharmony_ci	.predisable = &ad7768_buffer_predisable,
52962306a36Sopenharmony_ci};
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_cistatic const struct iio_trigger_ops ad7768_trigger_ops = {
53262306a36Sopenharmony_ci	.validate_device = iio_trigger_validate_own_device,
53362306a36Sopenharmony_ci};
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_cistatic void ad7768_regulator_disable(void *data)
53662306a36Sopenharmony_ci{
53762306a36Sopenharmony_ci	struct ad7768_state *st = data;
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci	regulator_disable(st->vref);
54062306a36Sopenharmony_ci}
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_cistatic int ad7768_set_channel_label(struct iio_dev *indio_dev,
54362306a36Sopenharmony_ci						int num_channels)
54462306a36Sopenharmony_ci{
54562306a36Sopenharmony_ci	struct ad7768_state *st = iio_priv(indio_dev);
54662306a36Sopenharmony_ci	struct device *device = indio_dev->dev.parent;
54762306a36Sopenharmony_ci	struct fwnode_handle *fwnode;
54862306a36Sopenharmony_ci	struct fwnode_handle *child;
54962306a36Sopenharmony_ci	const char *label;
55062306a36Sopenharmony_ci	int crt_ch = 0;
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci	fwnode = dev_fwnode(device);
55362306a36Sopenharmony_ci	fwnode_for_each_child_node(fwnode, child) {
55462306a36Sopenharmony_ci		if (fwnode_property_read_u32(child, "reg", &crt_ch))
55562306a36Sopenharmony_ci			continue;
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci		if (crt_ch >= num_channels)
55862306a36Sopenharmony_ci			continue;
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci		if (fwnode_property_read_string(child, "label", &label))
56162306a36Sopenharmony_ci			continue;
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci		st->labels[crt_ch] = label;
56462306a36Sopenharmony_ci	}
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_ci	return 0;
56762306a36Sopenharmony_ci}
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_cistatic int ad7768_probe(struct spi_device *spi)
57062306a36Sopenharmony_ci{
57162306a36Sopenharmony_ci	struct ad7768_state *st;
57262306a36Sopenharmony_ci	struct iio_dev *indio_dev;
57362306a36Sopenharmony_ci	int ret;
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
57662306a36Sopenharmony_ci	if (!indio_dev)
57762306a36Sopenharmony_ci		return -ENOMEM;
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	st = iio_priv(indio_dev);
58062306a36Sopenharmony_ci	st->spi = spi;
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci	st->vref = devm_regulator_get(&spi->dev, "vref");
58362306a36Sopenharmony_ci	if (IS_ERR(st->vref))
58462306a36Sopenharmony_ci		return PTR_ERR(st->vref);
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ci	ret = regulator_enable(st->vref);
58762306a36Sopenharmony_ci	if (ret) {
58862306a36Sopenharmony_ci		dev_err(&spi->dev, "Failed to enable specified vref supply\n");
58962306a36Sopenharmony_ci		return ret;
59062306a36Sopenharmony_ci	}
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	ret = devm_add_action_or_reset(&spi->dev, ad7768_regulator_disable, st);
59362306a36Sopenharmony_ci	if (ret)
59462306a36Sopenharmony_ci		return ret;
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	st->mclk = devm_clk_get_enabled(&spi->dev, "mclk");
59762306a36Sopenharmony_ci	if (IS_ERR(st->mclk))
59862306a36Sopenharmony_ci		return PTR_ERR(st->mclk);
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_ci	st->mclk_freq = clk_get_rate(st->mclk);
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci	mutex_init(&st->lock);
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	indio_dev->channels = ad7768_channels;
60562306a36Sopenharmony_ci	indio_dev->num_channels = ARRAY_SIZE(ad7768_channels);
60662306a36Sopenharmony_ci	indio_dev->name = spi_get_device_id(spi)->name;
60762306a36Sopenharmony_ci	indio_dev->info = &ad7768_info;
60862306a36Sopenharmony_ci	indio_dev->modes = INDIO_DIRECT_MODE;
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	ret = ad7768_setup(st);
61162306a36Sopenharmony_ci	if (ret < 0) {
61262306a36Sopenharmony_ci		dev_err(&spi->dev, "AD7768 setup failed\n");
61362306a36Sopenharmony_ci		return ret;
61462306a36Sopenharmony_ci	}
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_ci	st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d",
61762306a36Sopenharmony_ci					  indio_dev->name,
61862306a36Sopenharmony_ci					  iio_device_id(indio_dev));
61962306a36Sopenharmony_ci	if (!st->trig)
62062306a36Sopenharmony_ci		return -ENOMEM;
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	st->trig->ops = &ad7768_trigger_ops;
62362306a36Sopenharmony_ci	iio_trigger_set_drvdata(st->trig, indio_dev);
62462306a36Sopenharmony_ci	ret = devm_iio_trigger_register(&spi->dev, st->trig);
62562306a36Sopenharmony_ci	if (ret)
62662306a36Sopenharmony_ci		return ret;
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci	indio_dev->trig = iio_trigger_get(st->trig);
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci	init_completion(&st->completion);
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci	ret = ad7768_set_channel_label(indio_dev, ARRAY_SIZE(ad7768_channels));
63362306a36Sopenharmony_ci	if (ret)
63462306a36Sopenharmony_ci		return ret;
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci	ret = devm_request_irq(&spi->dev, spi->irq,
63762306a36Sopenharmony_ci			       &ad7768_interrupt,
63862306a36Sopenharmony_ci			       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
63962306a36Sopenharmony_ci			       indio_dev->name, indio_dev);
64062306a36Sopenharmony_ci	if (ret)
64162306a36Sopenharmony_ci		return ret;
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
64462306a36Sopenharmony_ci					      &iio_pollfunc_store_time,
64562306a36Sopenharmony_ci					      &ad7768_trigger_handler,
64662306a36Sopenharmony_ci					      &ad7768_buffer_ops);
64762306a36Sopenharmony_ci	if (ret)
64862306a36Sopenharmony_ci		return ret;
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci	return devm_iio_device_register(&spi->dev, indio_dev);
65162306a36Sopenharmony_ci}
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_cistatic const struct spi_device_id ad7768_id_table[] = {
65462306a36Sopenharmony_ci	{ "ad7768-1", 0 },
65562306a36Sopenharmony_ci	{}
65662306a36Sopenharmony_ci};
65762306a36Sopenharmony_ciMODULE_DEVICE_TABLE(spi, ad7768_id_table);
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_cistatic const struct of_device_id ad7768_of_match[] = {
66062306a36Sopenharmony_ci	{ .compatible = "adi,ad7768-1" },
66162306a36Sopenharmony_ci	{ },
66262306a36Sopenharmony_ci};
66362306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, ad7768_of_match);
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_cistatic struct spi_driver ad7768_driver = {
66662306a36Sopenharmony_ci	.driver = {
66762306a36Sopenharmony_ci		.name = "ad7768-1",
66862306a36Sopenharmony_ci		.of_match_table = ad7768_of_match,
66962306a36Sopenharmony_ci	},
67062306a36Sopenharmony_ci	.probe = ad7768_probe,
67162306a36Sopenharmony_ci	.id_table = ad7768_id_table,
67262306a36Sopenharmony_ci};
67362306a36Sopenharmony_cimodule_spi_driver(ad7768_driver);
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ciMODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
67662306a36Sopenharmony_ciMODULE_DESCRIPTION("Analog Devices AD7768-1 ADC driver");
67762306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
678