On Wed, 2024-05-22 at 14:59 +0300, ranechita wrote: > Added support for ad7770,ad7771,ad7779 ADCs. The > data is streamed only on the spi-mode, without > using the data lines. > > Signed-off-by: ranechita <ramona.nechita@xxxxxxxxxx> > --- > drivers/iio/adc/Kconfig | 11 + > drivers/iio/adc/Makefile | 1 + > drivers/iio/adc/ad7779.c | 1182 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 1194 insertions(+) > create mode 100644 drivers/iio/adc/ad7779.c > > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > index 0d9282fa67f5..3e42cbc365d7 100644 > --- a/drivers/iio/adc/Kconfig > +++ b/drivers/iio/adc/Kconfig > @@ -206,6 +206,17 @@ config AD7768_1 > To compile this driver as a module, choose M here: the module will be > called ad7768-1. > > +config AD7779 > + tristate "Analog Devices AD7779 ADC driver" > + depends on SPI > + select IIO_BUFFER > + help > + Say yes here to build support for Analog Devices AD7779 SPI > + analog to digital converter (ADC) > + > + To compile this driver as a module, choose M here: the module will be > + called ad7779. > + > config AD7780 > tristate "Analog Devices AD7780 and similar ADCs driver" > depends on SPI > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile > index b3c434722364..e25997e926bb 100644 > --- a/drivers/iio/adc/Makefile > +++ b/drivers/iio/adc/Makefile > @@ -24,6 +24,7 @@ obj-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o > obj-$(CONFIG_AD7606) += ad7606.o > obj-$(CONFIG_AD7766) += ad7766.o > obj-$(CONFIG_AD7768_1) += ad7768-1.o > +obj-$(CONFIG_AD7779) += ad7779.o > obj-$(CONFIG_AD7780) += ad7780.o > obj-$(CONFIG_AD7791) += ad7791.o > obj-$(CONFIG_AD7793) += ad7793.o > diff --git a/drivers/iio/adc/ad7779.c b/drivers/iio/adc/ad7779.c > new file mode 100644 > index 000000000000..d2c1b14464ff > --- /dev/null > +++ b/drivers/iio/adc/ad7779.c > @@ -0,0 +1,1182 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * AD777X ADC > + * > + * Copyright 2023 Analog Devices Inc. > + */ > + > +#include <linux/bitfield.h> > +#include <linux/bitops.h> > +#include <linux/clk.h> > +#include <linux/crc8.h> > +#include <linux/delay.h> > +#include <linux/err.h> > +#include <linux/interrupt.h> > +#include <linux/irq.h> > +#include <linux/gpio.h> > +#include <linux/gpio/consumer.h> > +#include <linux/module.h> > +#include <linux/regulator/consumer.h> > +#include <linux/spi/spi.h> > +#include <linux/string.h> > + > +#include <linux/iio/iio.h> > +#include <linux/iio/buffer.h> > +#include <linux/iio/kfifo_buf.h> > +#include <linux/iio/sysfs.h> > + > +#include "cf_axi_adc.h" > + > +#define AD777X_SPI_READ_CMD BIT(7) > + > +#define AD777X_DISABLE_SD BIT(7) > + > +#define AD777X_REG_CH_DISABLE 0x08 > +#define AD777X_REG_CH_SYNC_OFFSET(ch) (0x09 + (ch)) > +#define AD777X_REG_CH_CONFIG(ch) (0x00 + (ch)) > +#define AD777X_REG_GENERAL_USER_CONFIG_1 0x11 > +#define AD777X_REG_GENERAL_USER_CONFIG_2 0x12 > +#define AD777X_REG_GENERAL_USER_CONFIG_3 0x13 > +#define AD777X_REG_DOUT_FORMAT 0x14 > +#define AD777X_REG_ADC_MUX_CONFIG 0x15 > +#define AD777X_REG_GPIO_CONFIG 0x17 > +#define AD777X_REG_BUFFER_CONFIG_1 0x19 > +#define AD777X_REG_GLOBAL_MUX_CONFIG 0x16 > +#define AD777X_REG_BUFFER_CONFIG_2 0x1A > +#define AD777X_REG_GPIO_DATA 0x18 > +#define AD777X_REG_CH_OFFSET_UPPER_BYTE(ch) (0x1C + (ch) * 6) > +#define AD777X_REG_CH_OFFSET_LOWER_BYTE(ch) (0x1E + (ch) * 6) > +#define AD777X_REG_CH_GAIN_UPPER_BYTE(ch) (0x1F + (ch) * 6) > +#define AD777X_REG_CH_OFFSET_MID_BYTE(ch) (0x1D + (ch) * 6) > +#define AD777X_REG_CH_GAIN_MID_BYTE(ch) (0x20 + (ch) * 6) > +#define AD777X_REG_CH_ERR_REG(ch) (0x4C + (ch)) > +#define AD777X_REG_CH0_1_SAT_ERR 0x54 > +#define AD777X_REG_CH_GAIN_LOWER_BYTE(ch) (0x21 + (ch) * 6) > +#define AD777X_REG_CH2_3_SAT_ERR 0x55 > +#define AD777X_REG_CH4_5_SAT_ERR 0x56 > +#define AD777X_REG_CH6_7_SAT_ERR 0x57 > +#define AD777X_REG_CHX_ERR_REG_EN 0x58 > +#define AD777X_REG_GEN_ERR_REG_1 0x59 > +#define AD777X_REG_GEN_ERR_REG_1_EN 0x5A > +#define AD777X_REG_GEN_ERR_REG_2 0x5B > +#define AD777X_REG_GEN_ERR_REG_2_EN 0x5C > +#define AD777X_REG_STATUS_REG_1 0x5D > +#define AD777X_REG_STATUS_REG_2 0x5E > +#define AD777X_REG_STATUS_REG_3 0x5F > +#define AD777X_REG_SRC_N_MSB 0x60 > +#define AD777X_REG_SRC_N_LSB 0x61 > +#define AD777X_REG_SRC_IF_MSB 0x62 > +#define AD777X_REG_SRC_IF_LSB 0x63 > +#define AD777X_REG_SRC_UPDATE 0x64 > + > +#define AD777X_FILTER_MSK BIT(6) > +#define AD777X_MOD_POWERMODE_MSK BIT(6) > +#define AD777X_MOD_PDB_REFOUT_MSK BIT(4) > +#define AD777X_MOD_SPI_EN_MSK BIT(4) > + > +/* AD777X_REG_DOUT_FORMAT */ > +#define AD777X_DOUT_FORMAT_MSK GENMASK(7, 6) > +#define AD777X_DOUT_HEADER_FORMAT BIT(5) > +#define AD777X_DCLK_CLK_DIV_MSK GENMASK(3, 1) > + > +#define AD777X_REFMUX_CTRL_MSK GENMASK(7, 6) > +#define AD777X_SPI_CRC_EN_MSK BIT(0) > + > +#define AD777X_MAXCLK_LOWPOWER 4096000 > +#define AD777X_NUM_CHANNELS 8 > +#define AD777X_RESET_BUF_SIZE 8 > + > +#define AD777X_LOWPOWER_DIV 512 > +#define AD777X_HIGHPOWER_DIV 2048 > + > +#define AD777X_SINC3_MAXFREQ 16000 > +#define AD777X_SINC5_MAXFREQ 128000 > + > +#define AD777X_DEFAULT_SAMPLING_FREQ 8000 > +#define AD777X_DEFAULT_SAMPLING_2LINE 4000 > +#define AD777X_DEFAULT_SAMPLING_1LINE 2000 > + > +#define AD777X_SPIMODE_MAX_SAMP_FREQ 16000 > + > +/* AXI CONTROL REGS VALUES FOR DATA LINES */ > +#define AXI_CTRL_4_LINES 0x400 > +#define AXI_CTRL_2_LINES 0x200 > +#define AXI_CTRL_1_LINE 0x100 > + > +#define DEC3 1000 > +#define DEC6 1000000 > + > +#define GAIN_REL 0x555555 > +#define AD777X_FREQ_MSB_MSK GENMASK(15, 8) > +#define AD777X_FREQ_LSB_MSK GENMASK(7, 0) > +#define AD777X_UPPER GENMASK(23, 16) > +#define AD777X_MID GENMASK(15, 8) > +#define AD777X_LOWER GENMASK(7, 0) > + > +#define AD777X_CRC8_POLY 0x07 > +DECLARE_CRC8_TABLE(ad777x_crc8_table); > + > +enum ad777x_data_lines { > + AD777x_4LINES, > + AD777x_2LINES, > + AD777x_1LINE, > +}; > + > +enum ad777x_filter { > + AD777X_SINC3, > + AD777X_SINC5, > +}; > + > +enum ad777x_variant { > + ad7770, > + ad7771, > + ad7779, > +}; > + > +enum ad777x_power_mode { > + AD777X_LOW_POWER, > + AD777X_HIGH_POWER, > +}; > + > +struct ad777x_chip_info { > + const char *name; > +}; > + > +struct ad777x_state { > + struct spi_device *spi; > + const struct ad777x_chip_info *chip_info; > + struct clk *mclk; > + struct regulator *vref; > + unsigned int sampling_freq; > + enum ad777x_power_mode power_mode; > + enum ad777x_data_lines data_lines; > + enum ad777x_filter filter_enabled; > + unsigned int active_ch; > + unsigned int spidata_mode; > + unsigned int crc_enabled; > + > + /* > + * DMA (thus cache coherency maintenance) requires the > + * transfer buffers to live in their own cache lines. > + */ > + u8 reg_rx_buf[3] ____cacheline_aligned; > + u8 reg_tx_buf[3]; > + u8 spidata_rx[32]; > + u8 spidata_tx[32]; > + u8 reset_buf[8]; > +}; > + > +static const char * const ad777x_filter_type[] = { > + [AD777X_SINC3] = "sinc3_filter", > + [AD777X_SINC5] = "sinc5_filter", > +}; > + > +static const char * const ad777x_data_lines_modes[] = { > + [AD777x_4LINES] = "4_data_lines", > + [AD777x_2LINES] = "2_data_lines", > + [AD777x_1LINE] = "1_data_line", > +}; > + > +static bool ad777x_has_axi_adc(struct device *dev) > +{ > + return device_property_present(dev, "spibus-connected"); > +} > + > +static struct ad777x_state *ad777x_get_data(struct iio_dev *indio_dev) > +{ > + struct axiadc_converter *conv; > + > + if (ad777x_has_axi_adc(&indio_dev->dev)) { > + conv = iio_device_get_drvdata(indio_dev); > + return conv->phy; > + } > + > + return iio_priv(indio_dev); > +} > + Hi Ramona, Is this even compiling? This is definitely not code to be upstreamed since it relies on the our out-of-tree/legacy driver for the adi-axi-adc. You need to convert this to use the IIO backend framework (adding new interfaces if needed). - Nuno Sá