[v4,0/8] Introduce max12xx ADC support
mbox series

Message ID 20191011144347.19146-1-miquel.raynal@bootlin.com
Headers show
Series
  • Introduce max12xx ADC support
Related show

Message

Miquel Raynal Oct. 11, 2019, 2:43 p.m. UTC
Hello, here is a patchset updating the existing max1027.c driver (for
10-bit max1027/29/31 ADCs) with a few corrections/improvements and
then introducing their 12-bit cousins named max1227/29/31.

As on my hardware setup the "start conversion" and "end of conversion"
pin are not wired (which is absolutely fine for this chip), I also
updated the driver and the bindings to support optional interrupts. In
this case, triggered buffers are not available and the user must poll
the value from sysfs.

Thanks,
Miquèl


Changes in v4:
==============
* In the v3, I removed the bindings documentation for the max10xx
  devices, in favor of the trivial devices bindings. Unfortunately, I
  didn't spot that in the following patch adding support for the
  max12xx series, I was adding the compatibles to the trivial devices
  list but also re-introducing the bindings documentation with the
  three new compatibles. Just drop this part of the last patch to only
  have the trivial devices file, not the specific bindings. All the
  rest is the same.

Changes in v3:
==============
* Updated the commit message of the patch adding debugfs read access
  to better explain why I decided to limit the number of bytes read to
  two.
* Updated the macros to define the number of channels per device as
  proposed by Jonathan.
* Re-used the realbits entry instead of adding my own (called .depth).
* Started doing DT-bindings yaml conversion, but realized that after
  the first patch offering the interrupt as optional, the
  documentation was fitting pretty well the trivial devices
  representation. Dropped the specific bindings files and updated the
  trivial devices list instead.

Changes in v2:
==============
* Removed the addition of three compatibles from patch 4 (the
  preparation patch) to add these lines back in patch 5 (the actual
  introduction).


Miquel Raynal (8):
  iio: adc: max1027: Add debugfs register read support
  iio: adc: max1027: Make it optional to use interrupts
  iio: adc: max1027: Reset the device at probe time
  iio: adc: max1027: Prepare the introduction of different resolutions
  iio: adc: max1027: Introduce 12-bit devices support
  dt-bindings: iio: adc: max1027: Mark interrupts as optional
  dt-bindings: Add 1027/1029/1031 SPI ADCs as trivial devices
  dt-bindings: Add max12xx SPI ADC series as trivial devices

 .../bindings/iio/adc/max1027-adc.txt          |  20 --
 .../devicetree/bindings/trivial-devices.yaml  |  12 ++
 drivers/iio/adc/Kconfig                       |   4 +-
 drivers/iio/adc/max1027.c                     | 180 +++++++++++-------
 4 files changed, 125 insertions(+), 91 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/iio/adc/max1027-adc.txt

Comments

Jonathan Cameron Oct. 12, 2019, 11:25 a.m. UTC | #1
On Fri, 11 Oct 2019 16:43:40 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> Until now, only write operations were supported. Force two bytes read
> operation when reading, which should fit most of the development
> purposes. Of course, extended operations like buffered reads on
> multiple channels or even temperature + voltage reads will not be read
> entirely. Usually, just starting a new operation will work but in any
> case a software reset (done through the debufs interface too) will
> return the device in a usable state.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Applied to the togreg branch of iio.git and pushed out as testing for
the autobuilders to play with it.

thanks,

Jonathan

> ---
>  drivers/iio/adc/max1027.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c
> index 214883458582..6cdfe9ef73fc 100644
> --- a/drivers/iio/adc/max1027.c
> +++ b/drivers/iio/adc/max1027.c
> @@ -309,8 +309,11 @@ static int max1027_debugfs_reg_access(struct iio_dev *indio_dev,
>  	struct max1027_state *st = iio_priv(indio_dev);
>  	u8 *val = (u8 *)st->buffer;
>  
> -	if (readval != NULL)
> -		return -EINVAL;
> +	if (readval) {
> +		int ret = spi_read(st->spi, val, 2);
> +		*readval = be16_to_cpu(st->buffer[0]);
> +		return ret;
> +	}
>  
>  	*val = (u8)writeval;
>  	return spi_write(st->spi, val, 1);
Jonathan Cameron Oct. 12, 2019, 11:28 a.m. UTC | #2
On Fri, 11 Oct 2019 16:43:42 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> All the registers are configured by the driver, let's reset the chip
> at probe time, avoiding any conflict with a possible earlier
> configuration.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Applied.

Thanks,

Jonathan

> ---
>  drivers/iio/adc/max1027.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c
> index 823223b77a70..f9b473ee6711 100644
> --- a/drivers/iio/adc/max1027.c
> +++ b/drivers/iio/adc/max1027.c
> @@ -466,6 +466,14 @@ static int max1027_probe(struct spi_device *spi)
>  		}
>  	}
>  
> +	/* Internal reset */
> +	st->reg = MAX1027_RST_REG;
> +	ret = spi_write(st->spi, &st->reg, 1);
> +	if (ret < 0) {
> +		dev_err(&indio_dev->dev, "Failed to reset the ADC\n");
> +		return ret;
> +	}
> +
>  	/* Disable averaging */
>  	st->reg = MAX1027_AVG_REG;
>  	ret = spi_write(st->spi, &st->reg, 1);
Jonathan Cameron Oct. 12, 2019, 11:29 a.m. UTC | #3
On Fri, 11 Oct 2019 16:43:43 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> Maxim's max1027/29/31 series returns the measured voltages with a
> resolution of 10 bits. There is a very similar series, max1227/29/31
> which works identically but uses a resolution of 12 bits. Prepare the
> support for these chips by turning the 'depth' into a macro parameter
> instead of hardcoding it everywhere. Also reorganize just a bit the
> macros at the top to avoid repeating tens of lines when adding support
> for a new chip.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Applied.

Thanks,

Jonathan

> ---
>  drivers/iio/adc/max1027.c | 74 +++++++++++++++++----------------------
>  1 file changed, 32 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c
> index f9b473ee6711..8b449044bef5 100644
> --- a/drivers/iio/adc/max1027.c
> +++ b/drivers/iio/adc/max1027.c
> @@ -83,7 +83,7 @@ static const struct of_device_id max1027_adc_dt_ids[] = {
>  MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids);
>  #endif
>  
> -#define MAX1027_V_CHAN(index)						\
> +#define MAX1027_V_CHAN(index, depth)					\
>  	{								\
>  		.type = IIO_VOLTAGE,					\
>  		.indexed = 1,						\
> @@ -93,7 +93,7 @@ MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids);
>  		.scan_index = index + 1,				\
>  		.scan_type = {						\
>  			.sign = 'u',					\
> -			.realbits = 10,					\
> +			.realbits = depth,				\
>  			.storagebits = 16,				\
>  			.shift = 2,					\
>  			.endianness = IIO_BE,				\
> @@ -115,52 +115,42 @@ MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids);
>  		},							\
>  	}
>  
> +#define MAX1X27_CHANNELS(depth)			\
> +	MAX1027_T_CHAN,				\
> +	MAX1027_V_CHAN(0, depth),		\
> +	MAX1027_V_CHAN(1, depth),		\
> +	MAX1027_V_CHAN(2, depth),		\
> +	MAX1027_V_CHAN(3, depth),		\
> +	MAX1027_V_CHAN(4, depth),		\
> +	MAX1027_V_CHAN(5, depth),		\
> +	MAX1027_V_CHAN(6, depth),		\
> +	MAX1027_V_CHAN(7, depth)
> +
> +#define MAX1X29_CHANNELS(depth)			\
> +	MAX1X27_CHANNELS(depth),		\
> +	MAX1027_V_CHAN(8, depth),		\
> +	MAX1027_V_CHAN(9, depth),		\
> +	MAX1027_V_CHAN(10, depth),		\
> +	MAX1027_V_CHAN(11, depth)
> +
> +#define MAX1X31_CHANNELS(depth)			\
> +	MAX1X27_CHANNELS(depth),		\
> +	MAX1X29_CHANNELS(depth),		\
> +	MAX1027_V_CHAN(12, depth),		\
> +	MAX1027_V_CHAN(13, depth),		\
> +	MAX1027_V_CHAN(14, depth),		\
> +	MAX1027_V_CHAN(15, depth)
> +
>  static const struct iio_chan_spec max1027_channels[] = {
> -	MAX1027_T_CHAN,
> -	MAX1027_V_CHAN(0),
> -	MAX1027_V_CHAN(1),
> -	MAX1027_V_CHAN(2),
> -	MAX1027_V_CHAN(3),
> -	MAX1027_V_CHAN(4),
> -	MAX1027_V_CHAN(5),
> -	MAX1027_V_CHAN(6),
> -	MAX1027_V_CHAN(7)
> +	MAX1X27_CHANNELS(10),
>  };
>  
>  static const struct iio_chan_spec max1029_channels[] = {
> -	MAX1027_T_CHAN,
> -	MAX1027_V_CHAN(0),
> -	MAX1027_V_CHAN(1),
> -	MAX1027_V_CHAN(2),
> -	MAX1027_V_CHAN(3),
> -	MAX1027_V_CHAN(4),
> -	MAX1027_V_CHAN(5),
> -	MAX1027_V_CHAN(6),
> -	MAX1027_V_CHAN(7),
> -	MAX1027_V_CHAN(8),
> -	MAX1027_V_CHAN(9),
> -	MAX1027_V_CHAN(10),
> -	MAX1027_V_CHAN(11)
> +	MAX1X29_CHANNELS(10),
>  };
>  
>  static const struct iio_chan_spec max1031_channels[] = {
> -	MAX1027_T_CHAN,
> -	MAX1027_V_CHAN(0),
> -	MAX1027_V_CHAN(1),
> -	MAX1027_V_CHAN(2),
> -	MAX1027_V_CHAN(3),
> -	MAX1027_V_CHAN(4),
> -	MAX1027_V_CHAN(5),
> -	MAX1027_V_CHAN(6),
> -	MAX1027_V_CHAN(7),
> -	MAX1027_V_CHAN(8),
> -	MAX1027_V_CHAN(9),
> -	MAX1027_V_CHAN(10),
> -	MAX1027_V_CHAN(11),
> -	MAX1027_V_CHAN(12),
> -	MAX1027_V_CHAN(13),
> -	MAX1027_V_CHAN(14),
> -	MAX1027_V_CHAN(15)
> +	MAX1X31_CHANNELS(10),
>  };
>  
>  static const unsigned long max1027_available_scan_masks[] = {
> @@ -284,7 +274,7 @@ static int max1027_read_raw(struct iio_dev *indio_dev,
>  			break;
>  		case IIO_VOLTAGE:
>  			*val = 2500;
> -			*val2 = 10;
> +			*val2 = chan->scan_type.realbits;
>  			ret = IIO_VAL_FRACTIONAL_LOG2;
>  			break;
>  		default:
Jonathan Cameron Oct. 12, 2019, 11:30 a.m. UTC | #4
On Fri, 11 Oct 2019 16:43:44 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> Maxim's max12xx series is very similar to the max10xx series, with the
> difference of the measurements depth which is upgraded from 10 to 12
> bits per channel. Everything else looks the same.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Applied.

Thanks,

Jonathan

> ---
>  drivers/iio/adc/Kconfig   |  4 ++--
>  drivers/iio/adc/max1027.c | 38 +++++++++++++++++++++++++++++++++++++-
>  2 files changed, 39 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index f0af3a42f53c..6ac16d738822 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -508,8 +508,8 @@ config MAX1027
>  	select IIO_BUFFER
>  	select IIO_TRIGGERED_BUFFER
>  	help
> -	  Say yes here to build support for Maxim SPI ADC models
> -	  max1027, max1029 and max1031.
> +	  Say yes here to build support for Maxim SPI {10,12}-bit ADC models:
> +	  max1027, max1029, max1031, max1227, max1229 and max1231.
>  
>  	  To compile this driver as a module, choose M here: the module will be
>  	  called max1027.
> diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c
> index 8b449044bef5..e171db20c04a 100644
> --- a/drivers/iio/adc/max1027.c
> +++ b/drivers/iio/adc/max1027.c
> @@ -63,12 +63,18 @@ enum max1027_id {
>  	max1027,
>  	max1029,
>  	max1031,
> +	max1227,
> +	max1229,
> +	max1231,
>  };
>  
>  static const struct spi_device_id max1027_id[] = {
>  	{"max1027", max1027},
>  	{"max1029", max1029},
>  	{"max1031", max1031},
> +	{"max1227", max1227},
> +	{"max1229", max1229},
> +	{"max1231", max1231},
>  	{}
>  };
>  MODULE_DEVICE_TABLE(spi, max1027_id);
> @@ -78,6 +84,9 @@ static const struct of_device_id max1027_adc_dt_ids[] = {
>  	{ .compatible = "maxim,max1027" },
>  	{ .compatible = "maxim,max1029" },
>  	{ .compatible = "maxim,max1031" },
> +	{ .compatible = "maxim,max1227" },
> +	{ .compatible = "maxim,max1229" },
> +	{ .compatible = "maxim,max1231" },
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids);
> @@ -153,6 +162,18 @@ static const struct iio_chan_spec max1031_channels[] = {
>  	MAX1X31_CHANNELS(10),
>  };
>  
> +static const struct iio_chan_spec max1227_channels[] = {
> +	MAX1X27_CHANNELS(12),
> +};
> +
> +static const struct iio_chan_spec max1229_channels[] = {
> +	MAX1X29_CHANNELS(12),
> +};
> +
> +static const struct iio_chan_spec max1231_channels[] = {
> +	MAX1X31_CHANNELS(12),
> +};
> +
>  static const unsigned long max1027_available_scan_masks[] = {
>  	0x000001ff,
>  	0x00000000,
> @@ -190,6 +211,21 @@ static const struct max1027_chip_info max1027_chip_info_tbl[] = {
>  		.num_channels = ARRAY_SIZE(max1031_channels),
>  		.available_scan_masks = max1031_available_scan_masks,
>  	},
> +	[max1227] = {
> +		.channels = max1227_channels,
> +		.num_channels = ARRAY_SIZE(max1227_channels),
> +		.available_scan_masks = max1027_available_scan_masks,
> +	},
> +	[max1229] = {
> +		.channels = max1229_channels,
> +		.num_channels = ARRAY_SIZE(max1229_channels),
> +		.available_scan_masks = max1029_available_scan_masks,
> +	},
> +	[max1231] = {
> +		.channels = max1231_channels,
> +		.num_channels = ARRAY_SIZE(max1231_channels),
> +		.available_scan_masks = max1031_available_scan_masks,
> +	},
>  };
>  
>  struct max1027_state {
> @@ -486,5 +522,5 @@ static struct spi_driver max1027_driver = {
>  module_spi_driver(max1027_driver);
>  
>  MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>");
> -MODULE_DESCRIPTION("MAX1027/MAX1029/MAX1031 ADC");
> +MODULE_DESCRIPTION("MAX1X27/MAX1X29/MAX1X31 ADC");
>  MODULE_LICENSE("GPL v2");
Jonathan Cameron Oct. 12, 2019, 11:34 a.m. UTC | #5
On Fri, 11 Oct 2019 16:43:41 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:

> The chip has a 'start conversion' and a 'end of conversion' pair of
> pins. They can be used but this is absolutely not mandatory as regular
> polling of the value is totally fine with the current internal
> clocking setup. Turn the interrupts optional and do not error out if
> they are not inquired in the device tree. This has the effect to
> prevent triggered buffers use though.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Applied.

Thanks,

> ---
>  drivers/iio/adc/max1027.c | 57 +++++++++++++++++++++------------------
>  1 file changed, 31 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c
> index 6cdfe9ef73fc..823223b77a70 100644
> --- a/drivers/iio/adc/max1027.c
> +++ b/drivers/iio/adc/max1027.c
> @@ -430,35 +430,40 @@ static int max1027_probe(struct spi_device *spi)
>  		return -ENOMEM;
>  	}
>  
> -	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
> -					&iio_pollfunc_store_time,
> -					&max1027_trigger_handler, NULL);
> -	if (ret < 0) {
> -		dev_err(&indio_dev->dev, "Failed to setup buffer\n");
> -		return ret;
> -	}
> +	if (spi->irq) {
> +		ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
> +						      &iio_pollfunc_store_time,
> +						      &max1027_trigger_handler,
> +						      NULL);
> +		if (ret < 0) {
> +			dev_err(&indio_dev->dev, "Failed to setup buffer\n");
> +			return ret;
> +		}
>  
> -	st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-trigger",
> -							indio_dev->name);
> -	if (st->trig == NULL) {
> -		ret = -ENOMEM;
> -		dev_err(&indio_dev->dev, "Failed to allocate iio trigger\n");
> -		return ret;
> -	}
> +		st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-trigger",
> +						  indio_dev->name);
> +		if (st->trig == NULL) {
> +			ret = -ENOMEM;
> +			dev_err(&indio_dev->dev,
> +				"Failed to allocate iio trigger\n");
> +			return ret;
> +		}
>  
> -	st->trig->ops = &max1027_trigger_ops;
> -	st->trig->dev.parent = &spi->dev;
> -	iio_trigger_set_drvdata(st->trig, indio_dev);
> -	iio_trigger_register(st->trig);
> +		st->trig->ops = &max1027_trigger_ops;
> +		st->trig->dev.parent = &spi->dev;
> +		iio_trigger_set_drvdata(st->trig, indio_dev);
> +		iio_trigger_register(st->trig);
>  
> -	ret = devm_request_threaded_irq(&spi->dev, spi->irq,
> -					iio_trigger_generic_data_rdy_poll,
> -					NULL,
> -					IRQF_TRIGGER_FALLING,
> -					spi->dev.driver->name, st->trig);
> -	if (ret < 0) {
> -		dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n");
> -		return ret;
> +		ret = devm_request_threaded_irq(&spi->dev, spi->irq,
> +						iio_trigger_generic_data_rdy_poll,
> +						NULL,
> +						IRQF_TRIGGER_FALLING,
> +						spi->dev.driver->name,
> +						st->trig);
> +		if (ret < 0) {
> +			dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n");
> +			return ret;
> +		}
>  	}
>  
>  	/* Disable averaging */