Message ID | 20191011144347.19146-1-miquel.raynal@bootlin.com |
---|---|
Headers | show |
Series | Introduce max12xx ADC support | expand |
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);
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);
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:
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");
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 */