On Wed, Aug 31, 2022 at 4:36 PM Ramona Bolboaca <ramona.bolboaca@xxxxxxxxxx> wrote: > > Adding support for max11205 16-bit single-channel ultra-low power > delta-sigma adc. > The MAX11205 is compatible with the 2-wire interface and uses > SCLK and RDY/DOUT for serial communications. In this mode, all > controls are implemented by timing the high or low phase of the SCLK. > The 2-wire serial interface only allows for data to be read out through > the RDY/DOUT output. Couple of minor comments, if you are going to address them, Reviewed-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx> > Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX11205.pdf > Signed-off-by: Ramona Bolboaca <ramona.bolboaca@xxxxxxxxxx> > --- > changes in v2: > - add chip_info null pointer check > - add support for probing with ACPI table > - remove function for module removal > - remove irq flag from max11205_sigma_delta_info > - add missing commas and missing spaces > - remove redundant blank line > - wrap text to 75-80 chars > - removed typos in commit message > drivers/iio/adc/Kconfig | 14 +++ > drivers/iio/adc/Makefile | 1 + > drivers/iio/adc/max11205.c | 183 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 198 insertions(+) > create mode 100644 drivers/iio/adc/max11205.c > > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > index 7fe5930891e0..0c8f376b65d8 100644 > --- a/drivers/iio/adc/Kconfig > +++ b/drivers/iio/adc/Kconfig > @@ -653,6 +653,20 @@ config MAX1118 > To compile this driver as a module, choose M here: the module will be > called max1118. > > +config MAX11205 > + tristate "Maxim max11205 ADC driver" > + depends on SPI > + select AD_SIGMA_DELTA > + select IIO_BUFFER > + select IIO_TRIGGERED_BUFFER > + > + help > + Say yes here to build support for Maxim max11205 16-bit, single-channel > + ultra-low power delta-sigma ADC. > + > + To compile this driver as a module, choose M here: the module will be > + called max11205. > + > config MAX1241 > tristate "Maxim max1241 ADC driver" > depends on SPI_MASTER > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile > index 1772a549a3c8..bb681844e497 100644 > --- a/drivers/iio/adc/Makefile > +++ b/drivers/iio/adc/Makefile > @@ -61,6 +61,7 @@ obj-$(CONFIG_LTC2497) += ltc2497.o ltc2497-core.o > obj-$(CONFIG_MAX1027) += max1027.o > obj-$(CONFIG_MAX11100) += max11100.o > obj-$(CONFIG_MAX1118) += max1118.o > +obj-$(CONFIG_MAX11205) += max11205.o > obj-$(CONFIG_MAX1241) += max1241.o > obj-$(CONFIG_MAX1363) += max1363.o > obj-$(CONFIG_MAX9611) += max9611.o > diff --git a/drivers/iio/adc/max11205.c b/drivers/iio/adc/max11205.c > new file mode 100644 > index 000000000000..68e6082e70e5 > --- /dev/null > +++ b/drivers/iio/adc/max11205.c > @@ -0,0 +1,183 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * max11205 16-Bit Delta-Sigma ADC Can you spell the vendor and part number verbosely? Something like "Maxim MAX11205" or similar. > + * > + * Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX1240-max11205.pdf > + * Copyright (C) 2022 Analog Devices, Inc. > + * Author: Ramona Bolboaca <ramona.bolboaca@xxxxxxxxxx> > + */ > + > +#include <linux/device.h> > +#include <linux/module.h> > +#include <linux/regulator/consumer.h> > +#include <linux/spi/spi.h> > + > +#include <linux/iio/iio.h> > +#include <linux/iio/adc/ad_sigma_delta.h> > + > +#define MAX11205_BIT_SCALE 15 > +#define MAX11205A_OUT_DATA_RATE 116 > +#define MAX11205B_OUT_DATA_RATE 13 > + > +enum chip_type { > + TYPE_MAX11205A, > + TYPE_MAX11205B, > +}; > + > +struct chip_info { > + unsigned int out_data_rate; > + const char *name; > +}; > + > +struct max11205_state { > + const struct chip_info *chip_info; > + struct regulator *vref; > + struct ad_sigma_delta sd; > +}; > + > +static const struct ad_sigma_delta_info max11205_sigma_delta_info = { > + .has_registers = false, > +}; > + > +static int max11205_read_raw(struct iio_dev *indio_dev, > + struct iio_chan_spec const *chan, > + int *val, int *val2, long mask) > +{ > + struct max11205_state *st = iio_priv(indio_dev); > + int reg_mv; > + > + switch (mask) { > + case IIO_CHAN_INFO_RAW: > + return ad_sigma_delta_single_conversion(indio_dev, chan, val); > + case IIO_CHAN_INFO_SCALE: > + reg_mv = regulator_get_voltage(st->vref); > + if (reg_mv < 0) > + return reg_mv; > + reg_mv /= 1000; > + *val = reg_mv; > + *val2 = MAX11205_BIT_SCALE; > + return IIO_VAL_FRACTIONAL_LOG2; > + case IIO_CHAN_INFO_SAMP_FREQ: > + *val = st->chip_info->out_data_rate; > + return IIO_VAL_INT; > + default: > + return -EINVAL; > + } > +} > + > +static const struct iio_info max11205_iio_info = { > + .read_raw = max11205_read_raw, > + .validate_trigger = ad_sd_validate_trigger, > +}; > + > +static const struct iio_chan_spec max11205_channels[] = { > + { > + .type = IIO_VOLTAGE, > + .indexed = 1, > + .scan_type = { > + .sign = 's', > + .realbits = 16, > + .storagebits = 16, > + .endianness = IIO_BE > + }, > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | > + BIT(IIO_CHAN_INFO_SAMP_FREQ) | > + BIT(IIO_CHAN_INFO_SCALE), > + }, > +}; > + > +static const struct chip_info max11205_chip_info[] = { > + [TYPE_MAX11205A] = { > + .out_data_rate = MAX11205A_OUT_DATA_RATE, > + .name = "max11205a", > + }, > + [TYPE_MAX11205B] = { > + .out_data_rate = MAX11205B_OUT_DATA_RATE, > + .name = "max11205b", > + }, > +}; > + > +static void max11205_reg_disable(void *reg) > +{ > + regulator_disable(reg); > +} > + > +static int max11205_probe(struct spi_device *spi) > +{ > + struct max11205_state *st; > + struct iio_dev *indio_dev; > + int ret; > + > + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); > + if (!indio_dev) > + return -ENOMEM; > + > + st = iio_priv(indio_dev); > + > + ad_sd_init(&st->sd, indio_dev, spi, &max11205_sigma_delta_info); > + st->chip_info = device_get_match_data(&spi->dev); > + Unneeded blank line. > + if (!st->chip_info) > + st->chip_info = (const struct chip_info *)spi_get_device_id(spi)->driver_data; > + > + indio_dev->name = st->chip_info->name; > + indio_dev->modes = INDIO_DIRECT_MODE; > + indio_dev->channels = max11205_channels; > + indio_dev->num_channels = 1; > + indio_dev->info = &max11205_iio_info; > + > + st->vref = devm_regulator_get(&spi->dev, "vref"); devm_regulator_get_enable() ? > + if (IS_ERR(st->vref)) > + return dev_err_probe(&spi->dev, PTR_ERR(st->vref), > + "Failed to get vref regulator\n"); > + > + ret = regulator_enable(st->vref); > + if (ret) > + return ret; > + > + ret = devm_add_action_or_reset(&spi->dev, max11205_reg_disable, st->vref); > + if (ret) > + return ret; > + > + ret = devm_ad_sd_setup_buffer_and_trigger(&spi->dev, indio_dev); > + if (ret) > + return ret; > + > + return devm_iio_device_register(&spi->dev, indio_dev); > +} > + > +static const struct spi_device_id max11205_spi_ids[] = { > + { "max11205a", (kernel_ulong_t)&max11205_chip_info[TYPE_MAX11205A] }, > + { "max11205b", (kernel_ulong_t)&max11205_chip_info[TYPE_MAX11205B] }, > + { } > +}; > +MODULE_DEVICE_TABLE(spi, max11205_spi_ids); > + > +static const struct of_device_id max11205_dt_ids[] = { > + { > + .compatible = "maxim,max11205a", > + .data = &max11205_chip_info[TYPE_MAX11205A], > + }, > + { > + .compatible = "maxim,max11205b", > + .data = &max11205_chip_info[TYPE_MAX11205B], > + }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, max11205_dt_ids); > + > +static struct spi_driver max11205_spi_driver = { > + .driver = { > + .name = "max11205", > + .of_match_table = max11205_dt_ids, > + }, > + .probe = max11205_probe, > + .id_table = max11205_spi_ids, > +}; > +module_spi_driver(max11205_spi_driver); > + > +MODULE_AUTHOR("Ramona Bolboaca <ramona.bolboaca@xxxxxxxxxx>"); > +MODULE_DESCRIPTION("MAX11205 ADC driver"); > +MODULE_LICENSE("GPL v2"); > +MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); > -- > 2.25.1 > -- With Best Regards, Andy Shevchenko