Message ID | b0c7976d4bc817b7056ef40e3ce870b42e8a2d80.1741268122.git.Jonathan.Santos@analog.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | iio: adc: ad7768-1: Add features, improvements, and fixes | expand |
On 03/06, Jonathan Santos wrote: > Convert the AD7768-1 driver to use the regmap API for register > access. This change simplifies and standardizes register interactions, > reducing code duplication and improving maintainability. > > Create two regmap configurations, one for 8-bit register values and > other for 24-bit register values. > > Since we are using regmap now, define the remaining registers from 0x32 > to 0x34. > > Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com> > --- > v4 Changes: > * Add `REGMAP24` to the register macros with 24-bit value. > * Add `select REGMAP_SPI` line to the Kconfig. > > v3 Changes: > * Included a second register map for the 24-bit register values. > * Added register tables to separate the 24-bit from the 8-bit values. > > v2 Changes: > * New patch in v2. > --- > drivers/iio/adc/Kconfig | 1 + > drivers/iio/adc/ad7768-1.c | 151 +++++++++++++++++++++++++------------ > 2 files changed, 104 insertions(+), 48 deletions(-) > > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > index 849c90203071..a2fdb7e03a66 100644 > --- a/drivers/iio/adc/Kconfig > +++ b/drivers/iio/adc/Kconfig > @@ -277,6 +277,7 @@ config AD7766 > config AD7768_1 > tristate "Analog Devices AD7768-1 ADC driver" > depends on SPI > + select REGMAP_SPI > select IIO_BUFFER > select IIO_TRIGGER > select IIO_TRIGGERED_BUFFER > diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c > index f5509a0a36ab..04a26e5b7d5c 100644 > --- a/drivers/iio/adc/ad7768-1.c > +++ b/drivers/iio/adc/ad7768-1.c > @@ -12,6 +12,7 @@ > #include <linux/gpio/consumer.h> > #include <linux/kernel.h> > #include <linux/module.h> > +#include <linux/regmap.h> > #include <linux/regulator/consumer.h> > #include <linux/sysfs.h> > #include <linux/spi/spi.h> > @@ -53,12 +54,15 @@ > #define AD7768_REG_SPI_DIAG_ENABLE 0x28 > #define AD7768_REG_ADC_DIAG_ENABLE 0x29 > #define AD7768_REG_DIG_DIAG_ENABLE 0x2A > -#define AD7768_REG_ADC_DATA 0x2C > +#define AD7768_REG24_ADC_DATA 0x2C > #define AD7768_REG_MASTER_STATUS 0x2D > #define AD7768_REG_SPI_DIAG_STATUS 0x2E > #define AD7768_REG_ADC_DIAG_STATUS 0x2F > #define AD7768_REG_DIG_DIAG_STATUS 0x30 > #define AD7768_REG_MCLK_COUNTER 0x31 > +#define AD7768_REG_COEFF_CONTROL 0x32 > +#define AD7768_REG24_COEFF_DATA 0x33 > +#define AD7768_REG_ACCESS_KEY 0x34 > > /* AD7768_REG_POWER_CLOCK */ > #define AD7768_PWR_MCLK_DIV_MSK GENMASK(5, 4) > @@ -153,6 +157,8 @@ static const struct iio_chan_spec ad7768_channels[] = { > > struct ad7768_state { > struct spi_device *spi; > + struct regmap *regmap; > + struct regmap *regmap24; > struct regulator *vref; > struct clk *mclk; > unsigned int mclk_freq; > @@ -175,46 +181,76 @@ struct ad7768_state { > } data __aligned(IIO_DMA_MINALIGN); > }; > > -static int ad7768_spi_reg_read(struct ad7768_state *st, unsigned int addr, > - unsigned int len) > -{ > - unsigned int shift; > - int ret; > +static const struct regmap_range ad7768_regmap_rd_ranges[] = { > + regmap_reg_range(AD7768_REG_CHIP_TYPE, AD7768_REG_DIG_DIAG_ENABLE), > + regmap_reg_range(AD7768_REG_MASTER_STATUS, AD7768_REG_COEFF_CONTROL), > + regmap_reg_range(AD7768_REG_ACCESS_KEY, AD7768_REG_ACCESS_KEY), > +}; > > - shift = 32 - (8 * len); > - st->data.d8[0] = AD7768_RD_FLAG_MSK(addr); > +static const struct regmap_access_table ad7768_regmap_rd_table = { > + .yes_ranges = ad7768_regmap_rd_ranges, > + .n_yes_ranges = ARRAY_SIZE(ad7768_regmap_rd_ranges), > +}; > > - ret = spi_write_then_read(st->spi, st->data.d8, 1, > - &st->data.d32, len); > - if (ret < 0) > - return ret; > +static const struct regmap_range ad7768_regmap_wr_ranges[] = { > + regmap_reg_range(AD7768_REG_SCRATCH_PAD, AD7768_REG_SCRATCH_PAD), > + regmap_reg_range(AD7768_REG_INTERFACE_FORMAT, AD7768_REG_GPIO_WRITE), > + regmap_reg_range(AD7768_REG_OFFSET_HI, AD7768_REG_DIG_DIAG_ENABLE), > + regmap_reg_range(AD7768_REG_SPI_DIAG_STATUS, AD7768_REG_SPI_DIAG_STATUS), > + regmap_reg_range(AD7768_REG_COEFF_CONTROL, AD7768_REG_COEFF_CONTROL), > +}; > > - return (be32_to_cpu(st->data.d32) >> shift); > -} > +static const struct regmap_access_table ad7768_regmap_wr_table = { > + .yes_ranges = ad7768_regmap_wr_ranges, > + .n_yes_ranges = ARRAY_SIZE(ad7768_regmap_wr_ranges), > +}; > > -static int ad7768_spi_reg_write(struct ad7768_state *st, > - unsigned int addr, > - unsigned int val) > -{ > - st->data.d8[0] = AD7768_WR_FLAG_MSK(addr); > - st->data.d8[1] = val & 0xFF; > +static const struct regmap_config ad7768_regmap_config = { > + .name = "ad7768-1-8", > + .reg_bits = 8, > + .val_bits = 8, > + .read_flag_mask = BIT(6), > + .rd_table = &ad7768_regmap_rd_table, > + .wr_table = &ad7768_regmap_wr_table, > + .max_register = AD7768_REG_ACCESS_KEY, > + .use_single_write = true, > + .use_single_read = true, > +}; > > - return spi_write(st->spi, st->data.d8, 2); > -} > +static const struct regmap_range ad7768_regmap24_rd_ranges[] = { > + regmap_reg_range(AD7768_REG24_ADC_DATA, AD7768_REG24_ADC_DATA), > + regmap_reg_range(AD7768_REG24_COEFF_DATA, AD7768_REG24_COEFF_DATA), So, this device has only two registers that are 24-bit size? Also, one of those is the ADC_DATA register which you will probably want to read with optimized SPI messages in the future (devm_spi_optimize_message()). That makes me wonder if the 24-bit regmap worth's the boiler plate to have it. Does the driver access AD7768_REG24_COEFF_DATA after the patches from this series is applied? If not, maybe drop the 24-bit regmap and implement ADC_DATA with usual spi_message/spi_transfer interfaces? > +}; > > -static int ad7768_set_mode(struct ad7768_state *st, > - enum ad7768_conv_mode mode) > -{ > - int regval; > +static const struct regmap_access_table ad7768_regmap24_rd_table = { > + .yes_ranges = ad7768_regmap24_rd_ranges, > + .n_yes_ranges = ARRAY_SIZE(ad7768_regmap24_rd_ranges), > +}; > > - regval = ad7768_spi_reg_read(st, AD7768_REG_CONVERSION, 1); > - if (regval < 0) > - return regval; > +static const struct regmap_range ad7768_regmap24_wr_ranges[] = { > + regmap_reg_range(AD7768_REG24_COEFF_DATA, AD7768_REG24_COEFF_DATA), > +}; > > - regval &= ~AD7768_CONV_MODE_MSK; > - regval |= AD7768_CONV_MODE(mode); > +static const struct regmap_access_table ad7768_regmap24_wr_table = { > + .yes_ranges = ad7768_regmap24_wr_ranges, > + .n_yes_ranges = ARRAY_SIZE(ad7768_regmap24_wr_ranges), > +}; > + > +static const struct regmap_config ad7768_regmap24_config = { > + .name = "ad7768-1-24", > + .reg_bits = 8, > + .val_bits = 24, > + .read_flag_mask = BIT(6), > + .rd_table = &ad7768_regmap24_rd_table, > + .wr_table = &ad7768_regmap24_wr_table, > + .max_register = AD7768_REG24_COEFF_DATA, > +}; > > - return ad7768_spi_reg_write(st, AD7768_REG_CONVERSION, regval); > +static int ad7768_set_mode(struct ad7768_state *st, > + enum ad7768_conv_mode mode) > +{ > + return regmap_update_bits(st->regmap, AD7768_REG_CONVERSION, > + AD7768_CONV_MODE_MSK, AD7768_CONV_MODE(mode)); > } > > static int ad7768_scan_direct(struct iio_dev *indio_dev) > @@ -233,9 +269,10 @@ static int ad7768_scan_direct(struct iio_dev *indio_dev) > if (!ret) > return -ETIMEDOUT; > > - readval = ad7768_spi_reg_read(st, AD7768_REG_ADC_DATA, 3); > - if (readval < 0) > - return readval; > + ret = regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &readval); > + if (ret) > + return ret; > + > /* > * Any SPI configuration of the AD7768-1 can only be > * performed in continuous conversion mode. > @@ -259,16 +296,23 @@ static int ad7768_reg_access(struct iio_dev *indio_dev, > if (ret) > return ret; > > + ret = -EINVAL; > if (readval) { > - ret = ad7768_spi_reg_read(st, reg, 1); > - if (ret < 0) > - goto err_release; > - *readval = ret; > - ret = 0; > + if (regmap_check_range_table(st->regmap, reg, &ad7768_regmap_rd_table)) > + ret = regmap_read(st->regmap, reg, readval); > + > + if (regmap_check_range_table(st->regmap24, reg, &ad7768_regmap24_rd_table)) > + ret = regmap_read(st->regmap24, reg, readval); > + > } else { > - ret = ad7768_spi_reg_write(st, reg, writeval); > + if (regmap_check_range_table(st->regmap, reg, &ad7768_regmap_wr_table)) > + ret = regmap_write(st->regmap, reg, writeval); > + > + if (regmap_check_range_table(st->regmap24, reg, &ad7768_regmap24_wr_table)) > + ret = regmap_write(st->regmap24, reg, writeval); > + > } > -err_release: > + > iio_device_release_direct_mode(indio_dev); > > return ret; > @@ -285,7 +329,7 @@ static int ad7768_set_dig_fil(struct ad7768_state *st, > else > mode = AD7768_DIG_FIL_DEC_RATE(dec_rate); > > - ret = ad7768_spi_reg_write(st, AD7768_REG_DIGITAL_FILTER, mode); > + ret = regmap_write(st->regmap, AD7768_REG_DIGITAL_FILTER, mode); > if (ret < 0) > return ret; > > @@ -322,7 +366,7 @@ static int ad7768_set_freq(struct ad7768_state *st, > */ > pwr_mode = AD7768_PWR_MCLK_DIV(ad7768_clk_config[idx].mclk_div) | > AD7768_PWR_PWRMODE(ad7768_clk_config[idx].pwrmode); > - ret = ad7768_spi_reg_write(st, AD7768_REG_POWER_CLOCK, pwr_mode); > + ret = regmap_write(st->regmap, AD7768_REG_POWER_CLOCK, pwr_mode); > if (ret < 0) > return ret; > > @@ -449,11 +493,11 @@ static int ad7768_setup(struct ad7768_state *st) > * to 10. When the sequence is detected, the reset occurs. > * See the datasheet, page 70. > */ > - ret = ad7768_spi_reg_write(st, AD7768_REG_SYNC_RESET, 0x3); > + ret = regmap_write(st->regmap, AD7768_REG_SYNC_RESET, 0x3); > if (ret) > return ret; > > - ret = ad7768_spi_reg_write(st, AD7768_REG_SYNC_RESET, 0x2); > + ret = regmap_write(st->regmap, AD7768_REG_SYNC_RESET, 0x2); > if (ret) > return ret; > > @@ -508,18 +552,19 @@ static int ad7768_buffer_postenable(struct iio_dev *indio_dev) > * continuous read mode. Subsequent data reads do not require an > * initial 8-bit write to query the ADC_DATA register. > */ > - return ad7768_spi_reg_write(st, AD7768_REG_INTERFACE_FORMAT, 0x01); > + return regmap_write(st->regmap, AD7768_REG_INTERFACE_FORMAT, 0x01); > } > > static int ad7768_buffer_predisable(struct iio_dev *indio_dev) > { > struct ad7768_state *st = iio_priv(indio_dev); > + unsigned int unused; > > /* > * To exit continuous read mode, perform a single read of the ADC_DATA > * reg (0x2C), which allows further configuration of the device. > */ > - return ad7768_spi_reg_read(st, AD7768_REG_ADC_DATA, 3); > + return regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &unused); > } > > static const struct iio_buffer_setup_ops ad7768_buffer_ops = { > @@ -590,6 +635,16 @@ static int ad7768_probe(struct spi_device *spi) > > st->spi = spi; > > + st->regmap = devm_regmap_init_spi(spi, &ad7768_regmap_config); > + if (IS_ERR(st->regmap)) > + return dev_err_probe(&spi->dev, PTR_ERR(st->regmap), > + "Failed to initialize regmap"); > + > + st->regmap24 = devm_regmap_init_spi(spi, &ad7768_regmap24_config); > + if (IS_ERR(st->regmap24)) > + return dev_err_probe(&spi->dev, PTR_ERR(st->regmap24), > + "Failed to initialize regmap24"); > + > st->vref = devm_regulator_get(&spi->dev, "vref"); > if (IS_ERR(st->vref)) > return PTR_ERR(st->vref); > -- > 2.34.1 >
On Fri, 7 Mar 2025 10:20:04 -0300 Marcelo Schmitt <marcelo.schmitt1@gmail.com> wrote: > On 03/06, Jonathan Santos wrote: > > Convert the AD7768-1 driver to use the regmap API for register > > access. This change simplifies and standardizes register interactions, > > reducing code duplication and improving maintainability. > > > > Create two regmap configurations, one for 8-bit register values and > > other for 24-bit register values. > > > > Since we are using regmap now, define the remaining registers from 0x32 > > to 0x34. > > Marcelo, crop to just the bit you reply to. Reduces chance that key part is missed when someone is scrolling through. > > -static int ad7768_spi_reg_write(struct ad7768_state *st, > > - unsigned int addr, > > - unsigned int val) > > -{ > > - st->data.d8[0] = AD7768_WR_FLAG_MSK(addr); > > - st->data.d8[1] = val & 0xFF; > > +static const struct regmap_config ad7768_regmap_config = { > > + .name = "ad7768-1-8", > > + .reg_bits = 8, > > + .val_bits = 8, > > + .read_flag_mask = BIT(6), > > + .rd_table = &ad7768_regmap_rd_table, > > + .wr_table = &ad7768_regmap_wr_table, > > + .max_register = AD7768_REG_ACCESS_KEY, > > + .use_single_write = true, > > + .use_single_read = true, > > +}; > > > > - return spi_write(st->spi, st->data.d8, 2); > > -} > > +static const struct regmap_range ad7768_regmap24_rd_ranges[] = { > > + regmap_reg_range(AD7768_REG24_ADC_DATA, AD7768_REG24_ADC_DATA), > > + regmap_reg_range(AD7768_REG24_COEFF_DATA, AD7768_REG24_COEFF_DATA), > > So, this device has only two registers that are 24-bit size? > Also, one of those is the ADC_DATA register which you will probably want > to read with optimized SPI messages in the future (devm_spi_optimize_message()). > That makes me wonder if the 24-bit regmap worth's the boiler plate to have it. > Does the driver access AD7768_REG24_COEFF_DATA after the patches from this > series is applied? If not, maybe drop the 24-bit regmap and implement ADC_DATA > with usual spi_message/spi_transfer interfaces? Given it's used today and is better than a mix of regmap and non-regmap (as no need to go SPI specific yet) I'd keep it for now. If it ends up completely unused, then fair enough to rip it out again. It's not a lot of code. Jonathan
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 849c90203071..a2fdb7e03a66 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -277,6 +277,7 @@ config AD7766 config AD7768_1 tristate "Analog Devices AD7768-1 ADC driver" depends on SPI + select REGMAP_SPI select IIO_BUFFER select IIO_TRIGGER select IIO_TRIGGERED_BUFFER diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c index f5509a0a36ab..04a26e5b7d5c 100644 --- a/drivers/iio/adc/ad7768-1.c +++ b/drivers/iio/adc/ad7768-1.c @@ -12,6 +12,7 @@ #include <linux/gpio/consumer.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/sysfs.h> #include <linux/spi/spi.h> @@ -53,12 +54,15 @@ #define AD7768_REG_SPI_DIAG_ENABLE 0x28 #define AD7768_REG_ADC_DIAG_ENABLE 0x29 #define AD7768_REG_DIG_DIAG_ENABLE 0x2A -#define AD7768_REG_ADC_DATA 0x2C +#define AD7768_REG24_ADC_DATA 0x2C #define AD7768_REG_MASTER_STATUS 0x2D #define AD7768_REG_SPI_DIAG_STATUS 0x2E #define AD7768_REG_ADC_DIAG_STATUS 0x2F #define AD7768_REG_DIG_DIAG_STATUS 0x30 #define AD7768_REG_MCLK_COUNTER 0x31 +#define AD7768_REG_COEFF_CONTROL 0x32 +#define AD7768_REG24_COEFF_DATA 0x33 +#define AD7768_REG_ACCESS_KEY 0x34 /* AD7768_REG_POWER_CLOCK */ #define AD7768_PWR_MCLK_DIV_MSK GENMASK(5, 4) @@ -153,6 +157,8 @@ static const struct iio_chan_spec ad7768_channels[] = { struct ad7768_state { struct spi_device *spi; + struct regmap *regmap; + struct regmap *regmap24; struct regulator *vref; struct clk *mclk; unsigned int mclk_freq; @@ -175,46 +181,76 @@ struct ad7768_state { } data __aligned(IIO_DMA_MINALIGN); }; -static int ad7768_spi_reg_read(struct ad7768_state *st, unsigned int addr, - unsigned int len) -{ - unsigned int shift; - int ret; +static const struct regmap_range ad7768_regmap_rd_ranges[] = { + regmap_reg_range(AD7768_REG_CHIP_TYPE, AD7768_REG_DIG_DIAG_ENABLE), + regmap_reg_range(AD7768_REG_MASTER_STATUS, AD7768_REG_COEFF_CONTROL), + regmap_reg_range(AD7768_REG_ACCESS_KEY, AD7768_REG_ACCESS_KEY), +}; - shift = 32 - (8 * len); - st->data.d8[0] = AD7768_RD_FLAG_MSK(addr); +static const struct regmap_access_table ad7768_regmap_rd_table = { + .yes_ranges = ad7768_regmap_rd_ranges, + .n_yes_ranges = ARRAY_SIZE(ad7768_regmap_rd_ranges), +}; - ret = spi_write_then_read(st->spi, st->data.d8, 1, - &st->data.d32, len); - if (ret < 0) - return ret; +static const struct regmap_range ad7768_regmap_wr_ranges[] = { + regmap_reg_range(AD7768_REG_SCRATCH_PAD, AD7768_REG_SCRATCH_PAD), + regmap_reg_range(AD7768_REG_INTERFACE_FORMAT, AD7768_REG_GPIO_WRITE), + regmap_reg_range(AD7768_REG_OFFSET_HI, AD7768_REG_DIG_DIAG_ENABLE), + regmap_reg_range(AD7768_REG_SPI_DIAG_STATUS, AD7768_REG_SPI_DIAG_STATUS), + regmap_reg_range(AD7768_REG_COEFF_CONTROL, AD7768_REG_COEFF_CONTROL), +}; - return (be32_to_cpu(st->data.d32) >> shift); -} +static const struct regmap_access_table ad7768_regmap_wr_table = { + .yes_ranges = ad7768_regmap_wr_ranges, + .n_yes_ranges = ARRAY_SIZE(ad7768_regmap_wr_ranges), +}; -static int ad7768_spi_reg_write(struct ad7768_state *st, - unsigned int addr, - unsigned int val) -{ - st->data.d8[0] = AD7768_WR_FLAG_MSK(addr); - st->data.d8[1] = val & 0xFF; +static const struct regmap_config ad7768_regmap_config = { + .name = "ad7768-1-8", + .reg_bits = 8, + .val_bits = 8, + .read_flag_mask = BIT(6), + .rd_table = &ad7768_regmap_rd_table, + .wr_table = &ad7768_regmap_wr_table, + .max_register = AD7768_REG_ACCESS_KEY, + .use_single_write = true, + .use_single_read = true, +}; - return spi_write(st->spi, st->data.d8, 2); -} +static const struct regmap_range ad7768_regmap24_rd_ranges[] = { + regmap_reg_range(AD7768_REG24_ADC_DATA, AD7768_REG24_ADC_DATA), + regmap_reg_range(AD7768_REG24_COEFF_DATA, AD7768_REG24_COEFF_DATA), +}; -static int ad7768_set_mode(struct ad7768_state *st, - enum ad7768_conv_mode mode) -{ - int regval; +static const struct regmap_access_table ad7768_regmap24_rd_table = { + .yes_ranges = ad7768_regmap24_rd_ranges, + .n_yes_ranges = ARRAY_SIZE(ad7768_regmap24_rd_ranges), +}; - regval = ad7768_spi_reg_read(st, AD7768_REG_CONVERSION, 1); - if (regval < 0) - return regval; +static const struct regmap_range ad7768_regmap24_wr_ranges[] = { + regmap_reg_range(AD7768_REG24_COEFF_DATA, AD7768_REG24_COEFF_DATA), +}; - regval &= ~AD7768_CONV_MODE_MSK; - regval |= AD7768_CONV_MODE(mode); +static const struct regmap_access_table ad7768_regmap24_wr_table = { + .yes_ranges = ad7768_regmap24_wr_ranges, + .n_yes_ranges = ARRAY_SIZE(ad7768_regmap24_wr_ranges), +}; + +static const struct regmap_config ad7768_regmap24_config = { + .name = "ad7768-1-24", + .reg_bits = 8, + .val_bits = 24, + .read_flag_mask = BIT(6), + .rd_table = &ad7768_regmap24_rd_table, + .wr_table = &ad7768_regmap24_wr_table, + .max_register = AD7768_REG24_COEFF_DATA, +}; - return ad7768_spi_reg_write(st, AD7768_REG_CONVERSION, regval); +static int ad7768_set_mode(struct ad7768_state *st, + enum ad7768_conv_mode mode) +{ + return regmap_update_bits(st->regmap, AD7768_REG_CONVERSION, + AD7768_CONV_MODE_MSK, AD7768_CONV_MODE(mode)); } static int ad7768_scan_direct(struct iio_dev *indio_dev) @@ -233,9 +269,10 @@ static int ad7768_scan_direct(struct iio_dev *indio_dev) if (!ret) return -ETIMEDOUT; - readval = ad7768_spi_reg_read(st, AD7768_REG_ADC_DATA, 3); - if (readval < 0) - return readval; + ret = regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &readval); + if (ret) + return ret; + /* * Any SPI configuration of the AD7768-1 can only be * performed in continuous conversion mode. @@ -259,16 +296,23 @@ static int ad7768_reg_access(struct iio_dev *indio_dev, if (ret) return ret; + ret = -EINVAL; if (readval) { - ret = ad7768_spi_reg_read(st, reg, 1); - if (ret < 0) - goto err_release; - *readval = ret; - ret = 0; + if (regmap_check_range_table(st->regmap, reg, &ad7768_regmap_rd_table)) + ret = regmap_read(st->regmap, reg, readval); + + if (regmap_check_range_table(st->regmap24, reg, &ad7768_regmap24_rd_table)) + ret = regmap_read(st->regmap24, reg, readval); + } else { - ret = ad7768_spi_reg_write(st, reg, writeval); + if (regmap_check_range_table(st->regmap, reg, &ad7768_regmap_wr_table)) + ret = regmap_write(st->regmap, reg, writeval); + + if (regmap_check_range_table(st->regmap24, reg, &ad7768_regmap24_wr_table)) + ret = regmap_write(st->regmap24, reg, writeval); + } -err_release: + iio_device_release_direct_mode(indio_dev); return ret; @@ -285,7 +329,7 @@ static int ad7768_set_dig_fil(struct ad7768_state *st, else mode = AD7768_DIG_FIL_DEC_RATE(dec_rate); - ret = ad7768_spi_reg_write(st, AD7768_REG_DIGITAL_FILTER, mode); + ret = regmap_write(st->regmap, AD7768_REG_DIGITAL_FILTER, mode); if (ret < 0) return ret; @@ -322,7 +366,7 @@ static int ad7768_set_freq(struct ad7768_state *st, */ pwr_mode = AD7768_PWR_MCLK_DIV(ad7768_clk_config[idx].mclk_div) | AD7768_PWR_PWRMODE(ad7768_clk_config[idx].pwrmode); - ret = ad7768_spi_reg_write(st, AD7768_REG_POWER_CLOCK, pwr_mode); + ret = regmap_write(st->regmap, AD7768_REG_POWER_CLOCK, pwr_mode); if (ret < 0) return ret; @@ -449,11 +493,11 @@ static int ad7768_setup(struct ad7768_state *st) * to 10. When the sequence is detected, the reset occurs. * See the datasheet, page 70. */ - ret = ad7768_spi_reg_write(st, AD7768_REG_SYNC_RESET, 0x3); + ret = regmap_write(st->regmap, AD7768_REG_SYNC_RESET, 0x3); if (ret) return ret; - ret = ad7768_spi_reg_write(st, AD7768_REG_SYNC_RESET, 0x2); + ret = regmap_write(st->regmap, AD7768_REG_SYNC_RESET, 0x2); if (ret) return ret; @@ -508,18 +552,19 @@ static int ad7768_buffer_postenable(struct iio_dev *indio_dev) * continuous read mode. Subsequent data reads do not require an * initial 8-bit write to query the ADC_DATA register. */ - return ad7768_spi_reg_write(st, AD7768_REG_INTERFACE_FORMAT, 0x01); + return regmap_write(st->regmap, AD7768_REG_INTERFACE_FORMAT, 0x01); } static int ad7768_buffer_predisable(struct iio_dev *indio_dev) { struct ad7768_state *st = iio_priv(indio_dev); + unsigned int unused; /* * To exit continuous read mode, perform a single read of the ADC_DATA * reg (0x2C), which allows further configuration of the device. */ - return ad7768_spi_reg_read(st, AD7768_REG_ADC_DATA, 3); + return regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &unused); } static const struct iio_buffer_setup_ops ad7768_buffer_ops = { @@ -590,6 +635,16 @@ static int ad7768_probe(struct spi_device *spi) st->spi = spi; + st->regmap = devm_regmap_init_spi(spi, &ad7768_regmap_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(&spi->dev, PTR_ERR(st->regmap), + "Failed to initialize regmap"); + + st->regmap24 = devm_regmap_init_spi(spi, &ad7768_regmap24_config); + if (IS_ERR(st->regmap24)) + return dev_err_probe(&spi->dev, PTR_ERR(st->regmap24), + "Failed to initialize regmap24"); + st->vref = devm_regulator_get(&spi->dev, "vref"); if (IS_ERR(st->vref)) return PTR_ERR(st->vref);
Convert the AD7768-1 driver to use the regmap API for register access. This change simplifies and standardizes register interactions, reducing code duplication and improving maintainability. Create two regmap configurations, one for 8-bit register values and other for 24-bit register values. Since we are using regmap now, define the remaining registers from 0x32 to 0x34. Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com> --- v4 Changes: * Add `REGMAP24` to the register macros with 24-bit value. * Add `select REGMAP_SPI` line to the Kconfig. v3 Changes: * Included a second register map for the 24-bit register values. * Added register tables to separate the 24-bit from the 8-bit values. v2 Changes: * New patch in v2. --- drivers/iio/adc/Kconfig | 1 + drivers/iio/adc/ad7768-1.c | 151 +++++++++++++++++++++++++------------ 2 files changed, 104 insertions(+), 48 deletions(-)