linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/9] Improve MCP3911 driver
@ 2022-07-04 17:21 Marcus Folkesson
  2022-07-04 17:21 ` [PATCH v3 1/9] iio: adc: mcp3911: make use of the sign bit Marcus Folkesson
                   ` (9 more replies)
  0 siblings, 10 replies; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-04 17:21 UTC (permalink / raw)
  To: Marcus Folkesson, Kent Gustavsson, Jonathan Cameron,
	Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski
  Cc: linux-iio, devicetree, linux-kernel

Hi,

This patch series intend to fix bugs and add functionality to the
MCP3911 driver.
The main features added are
- Support for buffers
- Interrupt driven readings
- Support for oversampling ratio
- Support for set scale values (Gain)

Among the bug fixes, there are changes in the formula for calculate raw
value and a fix for mismatch in the devicetree property.

Another general improvement for the driver is to use managed resources
for all allocated resources.

See patch notes for more specific changes between versions.

General changes for the series:

v3:
- Drop Phase patch
- Add Fixes tags for those patches that are fixes
- Move Fixes patches to the beginning of the patchset


Best regards,
Marcus Folkesson



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 1/9] iio: adc: mcp3911: make use of the sign bit
  2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
@ 2022-07-04 17:21 ` Marcus Folkesson
  2022-07-04 17:21 ` [PATCH v3 2/9] iio: adc: mcp3911: correct "microchip,device-addr" property Marcus Folkesson
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-04 17:21 UTC (permalink / raw)
  To: Marcus Folkesson, Kent Gustavsson, Jonathan Cameron,
	Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski
  Cc: linux-iio, devicetree, linux-kernel

The device supports negative values as well.

Fixes: 3a89b289df5d ("iio: adc: add support for mcp3911")
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
 drivers/iio/adc/mcp3911.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index 1cb4590fe412..f581cefb6719 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -113,6 +113,8 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
 		if (ret)
 			goto out;
 
+		*val = sign_extend32(*val, 23);
+
 		ret = IIO_VAL_INT;
 		break;
 
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 2/9] iio: adc: mcp3911: correct "microchip,device-addr" property
  2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
  2022-07-04 17:21 ` [PATCH v3 1/9] iio: adc: mcp3911: make use of the sign bit Marcus Folkesson
@ 2022-07-04 17:21 ` Marcus Folkesson
  2022-07-04 17:21 ` [PATCH v3 3/9] iio: adc: mcp3911: use correct formula for AD conversion Marcus Folkesson
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-04 17:21 UTC (permalink / raw)
  To: Marcus Folkesson, Kent Gustavsson, Jonathan Cameron,
	Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski
  Cc: linux-iio, devicetree, linux-kernel

Go for the right property name that is documented in the bindings.

Fixes: 3a89b289df5d ("iio: adc: add support for mcp3911")
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
 drivers/iio/adc/mcp3911.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index f581cefb6719..f8875076ae80 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -210,7 +210,14 @@ static int mcp3911_config(struct mcp3911 *adc)
 	u32 configreg;
 	int ret;
 
-	device_property_read_u32(dev, "device-addr", &adc->dev_addr);
+	ret = device_property_read_u32(dev, "microchip,device-addr", &adc->dev_addr);
+
+	/*
+	 * Fallback to "device-addr" due to historical mismatch between
+	 * dt-bindings and implementation
+	 */
+	if (ret)
+		device_property_read_u32(dev, "device-addr", &adc->dev_addr);
 	if (adc->dev_addr > 3) {
 		dev_err(&adc->spi->dev,
 			"invalid device address (%i). Must be in range 0-3.\n",
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 3/9] iio: adc: mcp3911: use correct formula for AD conversion
  2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
  2022-07-04 17:21 ` [PATCH v3 1/9] iio: adc: mcp3911: make use of the sign bit Marcus Folkesson
  2022-07-04 17:21 ` [PATCH v3 2/9] iio: adc: mcp3911: correct "microchip,device-addr" property Marcus Folkesson
@ 2022-07-04 17:21 ` Marcus Folkesson
  2022-07-16 17:18   ` Jonathan Cameron
  2022-07-04 17:21 ` [PATCH v3 4/9] iio: adc: mcp3911: use resource-managed version of iio_device_register Marcus Folkesson
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-04 17:21 UTC (permalink / raw)
  To: Marcus Folkesson, Kent Gustavsson, Jonathan Cameron,
	Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski
  Cc: linux-iio, devicetree, linux-kernel

The ADC conversion is actually not rail-to-rail but with a factor 1.5.
Make use of this factor when calculating actual voltage.

Fixes: 3a89b289df5d ("iio: adc: add support for mcp3911")
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
Acked-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/adc/mcp3911.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index f8875076ae80..890af7dca62d 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -40,8 +40,8 @@
 #define MCP3911_CHANNEL(x)		(MCP3911_REG_CHANNEL0 + x * 3)
 #define MCP3911_OFFCAL(x)		(MCP3911_REG_OFFCAL_CH0 + x * 6)
 
-/* Internal voltage reference in uV */
-#define MCP3911_INT_VREF_UV		1200000
+/* Internal voltage reference in mV */
+#define MCP3911_INT_VREF_MV		1200
 
 #define MCP3911_REG_READ(reg, id)	((((reg) << 1) | ((id) << 5) | (1 << 0)) & 0xff)
 #define MCP3911_REG_WRITE(reg, id)	((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff)
@@ -139,11 +139,18 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
 
 			*val = ret / 1000;
 		} else {
-			*val = MCP3911_INT_VREF_UV;
+			*val = MCP3911_INT_VREF_MV;
 		}
 
-		*val2 = 24;
-		ret = IIO_VAL_FRACTIONAL_LOG2;
+		/*
+		 * For 24bit Conversion
+		 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
+		 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
+		 */
+
+		/* val2 = (2^23 * 1.5) */
+		*val2 = 12582912;
+		ret = IIO_VAL_FRACTIONAL;
 		break;
 	}
 
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 4/9] iio: adc: mcp3911: use resource-managed version of iio_device_register
  2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
                   ` (2 preceding siblings ...)
  2022-07-04 17:21 ` [PATCH v3 3/9] iio: adc: mcp3911: use correct formula for AD conversion Marcus Folkesson
@ 2022-07-04 17:21 ` Marcus Folkesson
  2022-07-16 17:22   ` Jonathan Cameron
  2022-07-04 17:21 ` [PATCH v3 5/9] iio: adc: mcp3911: add support for buffers Marcus Folkesson
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-04 17:21 UTC (permalink / raw)
  To: Marcus Folkesson, Kent Gustavsson, Jonathan Cameron,
	Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski
  Cc: linux-iio, devicetree, linux-kernel

Keep using managed resources as much as possible.

Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
 drivers/iio/adc/mcp3911.c | 43 ++++++++++++++++-----------------------
 1 file changed, 18 insertions(+), 25 deletions(-)

diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index 890af7dca62d..f5fd9da6ab55 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -258,6 +258,16 @@ static int mcp3911_config(struct mcp3911 *adc)
 	return  mcp3911_write(adc, MCP3911_REG_CONFIG, configreg, 2);
 }
 
+static void mcp3911_cleanup(void *_adc)
+{
+	struct mcp3911 *adc = _adc;
+
+	if (adc->clki)
+		clk_disable_unprepare(adc->clki);
+	if (adc->vref)
+		regulator_disable(adc->vref);
+}
+
 static int mcp3911_probe(struct spi_device *spi)
 {
 	struct iio_dev *indio_dev;
@@ -271,6 +281,10 @@ static int mcp3911_probe(struct spi_device *spi)
 	adc = iio_priv(indio_dev);
 	adc->spi = spi;
 
+	ret = devm_add_action_or_reset(&spi->dev, mcp3911_cleanup, adc);
+	if (ret)
+		return ret;
+
 	adc->vref = devm_regulator_get_optional(&adc->spi->dev, "vref");
 	if (IS_ERR(adc->vref)) {
 		if (PTR_ERR(adc->vref) == -ENODEV) {
@@ -296,21 +310,20 @@ static int mcp3911_probe(struct spi_device *spi)
 			dev_err(&adc->spi->dev,
 				"failed to get adc clk (%ld)\n",
 				PTR_ERR(adc->clki));
-			ret = PTR_ERR(adc->clki);
-			goto reg_disable;
+			return PTR_ERR(adc->clki);
 		}
 	} else {
 		ret = clk_prepare_enable(adc->clki);
 		if (ret < 0) {
 			dev_err(&adc->spi->dev,
 				"Failed to enable clki: %d\n", ret);
-			goto reg_disable;
+			return ret;
 		}
 	}
 
 	ret = mcp3911_config(adc);
 	if (ret)
-		goto clk_disable;
+		return ret;
 
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
@@ -322,31 +335,11 @@ static int mcp3911_probe(struct spi_device *spi)
 
 	mutex_init(&adc->lock);
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto clk_disable;
-
-	return ret;
-
-clk_disable:
-	clk_disable_unprepare(adc->clki);
-reg_disable:
-	if (adc->vref)
-		regulator_disable(adc->vref);
-
-	return ret;
+	return devm_iio_device_register(&adc->spi->dev, indio_dev);
 }
 
 static void mcp3911_remove(struct spi_device *spi)
 {
-	struct iio_dev *indio_dev = spi_get_drvdata(spi);
-	struct mcp3911 *adc = iio_priv(indio_dev);
-
-	iio_device_unregister(indio_dev);
-
-	clk_disable_unprepare(adc->clki);
-	if (adc->vref)
-		regulator_disable(adc->vref);
 }
 
 static const struct of_device_id mcp3911_dt_ids[] = {
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 5/9] iio: adc: mcp3911: add support for buffers
  2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
                   ` (3 preceding siblings ...)
  2022-07-04 17:21 ` [PATCH v3 4/9] iio: adc: mcp3911: use resource-managed version of iio_device_register Marcus Folkesson
@ 2022-07-04 17:21 ` Marcus Folkesson
  2022-07-04 21:56   ` Andy Shevchenko
  2022-07-04 17:21 ` [PATCH v3 6/9] iio: adc: mcp3911: add support for interrupts Marcus Folkesson
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-04 17:21 UTC (permalink / raw)
  To: Marcus Folkesson, Kent Gustavsson, Jonathan Cameron,
	Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski
  Cc: linux-iio, devicetree, linux-kernel

Add support for buffers to make the driver fit for more usecases.

Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
 drivers/iio/adc/mcp3911.c | 99 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 92 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index f5fd9da6ab55..cf4dacc7de06 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -5,10 +5,16 @@
  * Copyright (C) 2018 Marcus Folkesson <marcus.folkesson@gmail.com>
  * Copyright (C) 2018 Kent Gustavsson <kent@minoris.se>
  */
+#include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/trigger.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
 #include <linux/property.h>
@@ -22,6 +28,7 @@
 #define MCP3911_REG_GAIN		0x09
 
 #define MCP3911_REG_STATUSCOM		0x0a
+#define MCP3911_STATUSCOM_READ		GENMASK(7, 6)
 #define MCP3911_STATUSCOM_CH1_24WIDTH	BIT(4)
 #define MCP3911_STATUSCOM_CH0_24WIDTH	BIT(3)
 #define MCP3911_STATUSCOM_EN_OFFCAL	BIT(2)
@@ -54,6 +61,13 @@ struct mcp3911 {
 	struct regulator *vref;
 	struct clk *clki;
 	u32 dev_addr;
+	struct {
+		u32 channels[MCP3911_NUM_CHANNELS];
+		s64 ts __aligned(8);
+	} scan;
+
+	u8 tx_buf[MCP3911_NUM_CHANNELS * 3] __aligned(IIO_DMA_MINALIGN);
+	u8 rx_buf[MCP3911_NUM_CHANNELS * 3];
 };
 
 static int mcp3911_read(struct mcp3911 *adc, u8 reg, u32 *val, u8 len)
@@ -196,16 +210,66 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev,
 		.type = IIO_VOLTAGE,				\
 		.indexed = 1,					\
 		.channel = idx,					\
+		.scan_index = idx,				\
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
 			BIT(IIO_CHAN_INFO_OFFSET) |		\
 			BIT(IIO_CHAN_INFO_SCALE),		\
+		.scan_type = {					\
+			.sign = 's',				\
+			.realbits = 24,				\
+			.storagebits = 32,			\
+		},						\
 }
 
 static const struct iio_chan_spec mcp3911_channels[] = {
 	MCP3911_CHAN(0),
 	MCP3911_CHAN(1),
+	IIO_CHAN_SOFT_TIMESTAMP(2),
 };
 
+static irqreturn_t mcp3911_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct mcp3911 *adc = iio_priv(indio_dev);
+	struct spi_transfer xfer = {
+		.tx_buf = adc->tx_buf,
+		.rx_buf = adc->rx_buf,
+		.len = sizeof(adc->rx_buf),
+	};
+	int scan_index;
+	int i = 0;
+	int ret;
+
+	mutex_lock(&adc->lock);
+	adc->tx_buf[0] = MCP3911_REG_READ(MCP3911_CHANNEL(0), adc->dev_addr);
+	ret = spi_sync_transfer(adc->spi, &xfer, 1);
+	if (ret < 0) {
+		dev_warn(&adc->spi->dev,
+				"failed to get conversion data\n");
+		goto out;
+	}
+
+	for_each_set_bit(scan_index, indio_dev->active_scan_mask,
+			indio_dev->masklength) {
+		const struct iio_chan_spec *scan_chan =
+			&indio_dev->channels[scan_index];
+
+		adc->scan.channels[i] = adc->rx_buf[scan_chan->channel * 3 + 0] << 16 |
+					adc->rx_buf[scan_chan->channel * 3 + 1] << 8 |
+					adc->rx_buf[scan_chan->channel * 3 + 2] << 0;
+
+		i++;
+	}
+	iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan,
+			iio_get_time_ns(indio_dev));
+out:
+	mutex_unlock(&adc->lock);
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
 static const struct iio_info mcp3911_info = {
 	.read_raw = mcp3911_read_raw,
 	.write_raw = mcp3911_write_raw,
@@ -214,7 +278,7 @@ static const struct iio_info mcp3911_info = {
 static int mcp3911_config(struct mcp3911 *adc)
 {
 	struct device *dev = &adc->spi->dev;
-	u32 configreg;
+	u32 regval;
 	int ret;
 
 	ret = device_property_read_u32(dev, "microchip,device-addr", &adc->dev_addr);
@@ -233,29 +297,43 @@ static int mcp3911_config(struct mcp3911 *adc)
 	}
 	dev_dbg(&adc->spi->dev, "use device address %i\n", adc->dev_addr);
 
-	ret = mcp3911_read(adc, MCP3911_REG_CONFIG, &configreg, 2);
+	ret = mcp3911_read(adc, MCP3911_REG_CONFIG, &regval, 2);
 	if (ret)
 		return ret;
 
+	regval &= ~MCP3911_CONFIG_VREFEXT;
 	if (adc->vref) {
 		dev_dbg(&adc->spi->dev, "use external voltage reference\n");
-		configreg |= MCP3911_CONFIG_VREFEXT;
+		regval |= FIELD_PREP(MCP3911_CONFIG_VREFEXT, 1);
 	} else {
 		dev_dbg(&adc->spi->dev,
 			"use internal voltage reference (1.2V)\n");
-		configreg &= ~MCP3911_CONFIG_VREFEXT;
+		regval |= FIELD_PREP(MCP3911_CONFIG_VREFEXT, 0);
 	}
 
+	regval &= ~MCP3911_CONFIG_CLKEXT;
 	if (adc->clki) {
 		dev_dbg(&adc->spi->dev, "use external clock as clocksource\n");
-		configreg |= MCP3911_CONFIG_CLKEXT;
+		regval |= FIELD_PREP(MCP3911_CONFIG_CLKEXT, 1);
 	} else {
 		dev_dbg(&adc->spi->dev,
 			"use crystal oscillator as clocksource\n");
-		configreg &= ~MCP3911_CONFIG_CLKEXT;
+		regval |= FIELD_PREP(MCP3911_CONFIG_CLKEXT, 0);
 	}
 
-	return  mcp3911_write(adc, MCP3911_REG_CONFIG, configreg, 2);
+	ret = mcp3911_write(adc, MCP3911_REG_CONFIG, regval, 2);
+	if (ret)
+		return ret;
+
+	ret = mcp3911_read(adc, MCP3911_REG_STATUSCOM, &regval, 2);
+	if (ret)
+		return ret;
+
+	/* Address counter incremented, cycle through register types */
+	regval &= ~MCP3911_STATUSCOM_READ;
+	regval |= FIELD_PREP(MCP3911_STATUSCOM_READ, 0x02);
+
+	return  mcp3911_write(adc, MCP3911_REG_STATUSCOM, regval, 2);
 }
 
 static void mcp3911_cleanup(void *_adc)
@@ -325,6 +403,7 @@ static int mcp3911_probe(struct spi_device *spi)
 	if (ret)
 		return ret;
 
+
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &mcp3911_info;
@@ -335,6 +414,12 @@ static int mcp3911_probe(struct spi_device *spi)
 
 	mutex_init(&adc->lock);
 
+	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
+			NULL,
+			mcp3911_trigger_handler, NULL);
+	if (ret)
+		return ret;
+
 	return devm_iio_device_register(&adc->spi->dev, indio_dev);
 }
 
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 6/9] iio: adc: mcp3911: add support for interrupts
  2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
                   ` (4 preceding siblings ...)
  2022-07-04 17:21 ` [PATCH v3 5/9] iio: adc: mcp3911: add support for buffers Marcus Folkesson
@ 2022-07-04 17:21 ` Marcus Folkesson
  2022-07-04 21:57   ` Andy Shevchenko
  2022-07-04 17:21 ` [PATCH v3 7/9] dt-bindings: iio: adc: mcp3911: add microchip,data-ready-hiz entry Marcus Folkesson
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-04 17:21 UTC (permalink / raw)
  To: Marcus Folkesson, Kent Gustavsson, Jonathan Cameron,
	Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski
  Cc: linux-iio, devicetree, linux-kernel

Make it possible to read values upon interrupts.
Configure Data Ready Signal Output Pin to either HiZ or push-pull and
use it as interrupt source.

Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
 drivers/iio/adc/mcp3911.c | 52 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index cf4dacc7de06..9c6f456bdbdf 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -28,6 +28,7 @@
 #define MCP3911_REG_GAIN		0x09
 
 #define MCP3911_REG_STATUSCOM		0x0a
+#define MCP3911_STATUSCOM_DRHIZ         BIT(12)
 #define MCP3911_STATUSCOM_READ		GENMASK(7, 6)
 #define MCP3911_STATUSCOM_CH1_24WIDTH	BIT(4)
 #define MCP3911_STATUSCOM_CH0_24WIDTH	BIT(3)
@@ -61,6 +62,7 @@ struct mcp3911 {
 	struct regulator *vref;
 	struct clk *clki;
 	u32 dev_addr;
+	struct iio_trigger *trig;
 	struct {
 		u32 channels[MCP3911_NUM_CHANNELS];
 		s64 ts __aligned(8);
@@ -346,6 +348,23 @@ static void mcp3911_cleanup(void *_adc)
 		regulator_disable(adc->vref);
 }
 
+static int mcp3911_set_trigger_state(struct iio_trigger *trig, bool enable)
+{
+	struct mcp3911 *adc = iio_trigger_get_drvdata(trig);
+
+	if (enable)
+		enable_irq(adc->spi->irq);
+	else
+		disable_irq(adc->spi->irq);
+
+	return 0;
+}
+
+static const struct iio_trigger_ops mcp3911_trigger_ops = {
+	.validate_device = iio_trigger_validate_own_device,
+	.set_trigger_state = mcp3911_set_trigger_state,
+};
+
 static int mcp3911_probe(struct spi_device *spi)
 {
 	struct iio_dev *indio_dev;
@@ -403,6 +422,14 @@ static int mcp3911_probe(struct spi_device *spi)
 	if (ret)
 		return ret;
 
+	if (device_property_read_bool(&adc->spi->dev, "microchip,data-ready-hiz"))
+		ret = mcp3911_update(adc, MCP3911_REG_STATUSCOM, MCP3911_STATUSCOM_DRHIZ,
+				0, 2);
+	else
+		ret = mcp3911_update(adc, MCP3911_REG_STATUSCOM, MCP3911_STATUSCOM_DRHIZ,
+				MCP3911_STATUSCOM_DRHIZ, 2);
+	if (ret)
+		return ret;
 
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
@@ -414,6 +441,31 @@ static int mcp3911_probe(struct spi_device *spi)
 
 	mutex_init(&adc->lock);
 
+	if (spi->irq > 0) {
+		adc->trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d",
+				indio_dev->name,
+				iio_device_id(indio_dev));
+		if (!adc->trig)
+			return PTR_ERR(adc->trig);
+
+		adc->trig->ops = &mcp3911_trigger_ops;
+		iio_trigger_set_drvdata(adc->trig, adc);
+		ret = devm_iio_trigger_register(&spi->dev, adc->trig);
+		if (ret)
+			return ret;
+
+		/*
+		 * The device generates interrupts as long as it is powered up.
+		 * Some platforms might not allow the option to power it down so
+		 * don't enable the interrupt to avoid extra load on the system
+		 */
+		ret = devm_request_irq(&spi->dev, spi->irq,
+				&iio_trigger_generic_data_rdy_poll, IRQF_NO_AUTOEN | IRQF_ONESHOT,
+				indio_dev->name, adc->trig);
+		if (ret)
+			return ret;
+	}
+
 	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
 			NULL,
 			mcp3911_trigger_handler, NULL);
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 7/9] dt-bindings: iio: adc: mcp3911: add microchip,data-ready-hiz entry
  2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
                   ` (5 preceding siblings ...)
  2022-07-04 17:21 ` [PATCH v3 6/9] iio: adc: mcp3911: add support for interrupts Marcus Folkesson
@ 2022-07-04 17:21 ` Marcus Folkesson
  2022-07-04 17:21 ` [PATCH v3 8/9] iio: adc: mcp3911: add support for oversampling ratio Marcus Folkesson
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-04 17:21 UTC (permalink / raw)
  To: Marcus Folkesson, Kent Gustavsson, Jonathan Cameron,
	Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski
  Cc: linux-iio, devicetree, linux-kernel, Krzysztof Kozlowski

The Data Ready Output Pin is either hard wired to work as high
impedance or push-pull. Make it configurable.

Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
 .../devicetree/bindings/iio/adc/microchip,mcp3911.yaml     | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/microchip,mcp3911.yaml b/Documentation/devicetree/bindings/iio/adc/microchip,mcp3911.yaml
index 95ab285f4eba..57a16380f864 100644
--- a/Documentation/devicetree/bindings/iio/adc/microchip,mcp3911.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/microchip,mcp3911.yaml
@@ -36,6 +36,13 @@ properties:
     description: IRQ line of the ADC
     maxItems: 1
 
+  microchip,data-ready-hiz:
+    description:
+      Data Ready Pin Inactive State Control
+      true = The DR pin state is high-impedance when data are NOT ready
+      false = The DR pin state is a logic high when data are NOT ready
+    type: boolean
+
   microchip,device-addr:
     description: Device address when multiple MCP3911 chips are present on the same SPI bus.
     $ref: /schemas/types.yaml#/definitions/uint32
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 8/9] iio: adc: mcp3911: add support for oversampling ratio
  2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
                   ` (6 preceding siblings ...)
  2022-07-04 17:21 ` [PATCH v3 7/9] dt-bindings: iio: adc: mcp3911: add microchip,data-ready-hiz entry Marcus Folkesson
@ 2022-07-04 17:21 ` Marcus Folkesson
  2022-07-04 21:58   ` Andy Shevchenko
  2022-07-04 17:21 ` [PATCH v3 9/9] iio: adc: mcp3911: add support to set PGA Marcus Folkesson
  2022-07-04 22:03 ` [PATCH v3 0/9] Improve MCP3911 driver Andy Shevchenko
  9 siblings, 1 reply; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-04 17:21 UTC (permalink / raw)
  To: Marcus Folkesson, Kent Gustavsson, Jonathan Cameron,
	Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski
  Cc: linux-iio, devicetree, linux-kernel

The chip supports oversampling ratio, so expose it to userspace.

Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
 drivers/iio/adc/mcp3911.c | 59 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index 9c6f456bdbdf..c6e30471bb81 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -38,6 +38,7 @@
 #define MCP3911_REG_CONFIG		0x0c
 #define MCP3911_CONFIG_CLKEXT		BIT(1)
 #define MCP3911_CONFIG_VREFEXT		BIT(2)
+#define MCP3911_CONFIG_OSR		GENMASK(13, 11)
 
 #define MCP3911_REG_OFFCAL_CH0		0x0e
 #define MCP3911_REG_GAINCAL_CH0		0x11
@@ -56,6 +57,8 @@
 
 #define MCP3911_NUM_CHANNELS		2
 
+static const int mcp3911_osr_table[] = { 32, 64, 128, 256, 512, 1024, 2048, 4096 };
+
 struct mcp3911 {
 	struct spi_device *spi;
 	struct mutex lock;
@@ -114,6 +117,36 @@ static int mcp3911_update(struct mcp3911 *adc, u8 reg, u32 mask,
 	return mcp3911_write(adc, reg, val, len);
 }
 
+static int mcp3911_write_raw_get_fmt(struct iio_dev *indio_dev,
+					struct iio_chan_spec const *chan,
+					long mask)
+{
+	switch (mask) {
+	case IIO_CHAN_INFO_SCALE:
+		return IIO_VAL_INT_PLUS_NANO;
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		return IIO_VAL_INT;
+	default:
+		return IIO_VAL_INT_PLUS_NANO;
+	}
+}
+
+static int mcp3911_read_avail(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     const int **vals, int *type, int *length,
+			     long info)
+{
+	switch (info) {
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		*type = IIO_VAL_INT;
+		*vals = mcp3911_osr_table;
+		*length = ARRAY_SIZE(mcp3911_osr_table);
+		return IIO_AVAIL_LIST;
+	default:
+		return -EINVAL;
+	}
+}
+
 static int mcp3911_read_raw(struct iio_dev *indio_dev,
 			    struct iio_chan_spec const *channel, int *val,
 			    int *val2, long mask)
@@ -142,6 +175,16 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
 
 		ret = IIO_VAL_INT;
 		break;
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		ret = mcp3911_read(adc,
+				MCP3911_REG_CONFIG, val, 2);
+		if (ret)
+			goto out;
+
+		*val = FIELD_GET(MCP3911_CONFIG_OSR, *val);
+		*val = 32 << *val;
+		ret = IIO_VAL_INT;
+		break;
 
 	case IIO_CHAN_INFO_SCALE:
 		if (adc->vref) {
@@ -201,6 +244,17 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev,
 				MCP3911_STATUSCOM_EN_OFFCAL,
 				MCP3911_STATUSCOM_EN_OFFCAL, 2);
 		break;
+
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		for (int i = 0; i < sizeof(mcp3911_osr_table); i++) {
+			if (val == mcp3911_osr_table[i]) {
+				val = FIELD_PREP(MCP3911_CONFIG_OSR, i);
+				ret = mcp3911_update(adc, MCP3911_REG_CONFIG, MCP3911_CONFIG_OSR,
+						val, 2);
+				break;
+			}
+		}
+		break;
 	}
 
 out:
@@ -213,9 +267,12 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev,
 		.indexed = 1,					\
 		.channel = idx,					\
 		.scan_index = idx,				\
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
 			BIT(IIO_CHAN_INFO_OFFSET) |		\
 			BIT(IIO_CHAN_INFO_SCALE),		\
+		.info_mask_shared_by_type_available =		\
+			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
 		.scan_type = {					\
 			.sign = 's',				\
 			.realbits = 24,				\
@@ -275,6 +332,8 @@ static irqreturn_t mcp3911_trigger_handler(int irq, void *p)
 static const struct iio_info mcp3911_info = {
 	.read_raw = mcp3911_read_raw,
 	.write_raw = mcp3911_write_raw,
+	.read_avail = mcp3911_read_avail,
+	.write_raw_get_fmt = mcp3911_write_raw_get_fmt,
 };
 
 static int mcp3911_config(struct mcp3911 *adc)
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v3 9/9] iio: adc: mcp3911: add support to set PGA
  2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
                   ` (7 preceding siblings ...)
  2022-07-04 17:21 ` [PATCH v3 8/9] iio: adc: mcp3911: add support for oversampling ratio Marcus Folkesson
@ 2022-07-04 17:21 ` Marcus Folkesson
  2022-07-04 22:02   ` Andy Shevchenko
  2022-07-04 22:03 ` [PATCH v3 0/9] Improve MCP3911 driver Andy Shevchenko
  9 siblings, 1 reply; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-04 17:21 UTC (permalink / raw)
  To: Marcus Folkesson, Kent Gustavsson, Jonathan Cameron,
	Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski
  Cc: linux-iio, devicetree, linux-kernel

Add support for setting the Programmable Gain Amplifiers by adjust the
scale value.

Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
---
 drivers/iio/adc/mcp3911.c | 107 +++++++++++++++++++++++++++++---------
 1 file changed, 83 insertions(+), 24 deletions(-)

diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
index c6e30471bb81..7fc53f0057d6 100644
--- a/drivers/iio/adc/mcp3911.c
+++ b/drivers/iio/adc/mcp3911.c
@@ -26,6 +26,8 @@
 #define MCP3911_REG_MOD			0x06
 #define MCP3911_REG_PHASE		0x07
 #define MCP3911_REG_GAIN		0x09
+#define MCP3911_GAIN_MASK(ch)          (0x7 << 3 * ch)
+#define MCP3911_GAIN_VAL(ch, val)      ((val << 3 * ch) & MCP3911_GAIN_MASK(ch))
 
 #define MCP3911_REG_STATUSCOM		0x0a
 #define MCP3911_STATUSCOM_DRHIZ         BIT(12)
@@ -56,8 +58,10 @@
 #define MCP3911_REG_WRITE(reg, id)	((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff)
 
 #define MCP3911_NUM_CHANNELS		2
+#define MCP3911_NUM_SCALES		6
 
 static const int mcp3911_osr_table[] = { 32, 64, 128, 256, 512, 1024, 2048, 4096 };
+static u32 mcp3911_scale_table[MCP3911_NUM_SCALES][2];
 
 struct mcp3911 {
 	struct spi_device *spi;
@@ -66,6 +70,7 @@ struct mcp3911 {
 	struct clk *clki;
 	u32 dev_addr;
 	struct iio_trigger *trig;
+	u32 gain[MCP3911_NUM_CHANNELS];
 	struct {
 		u32 channels[MCP3911_NUM_CHANNELS];
 		s64 ts __aligned(8);
@@ -142,6 +147,11 @@ static int mcp3911_read_avail(struct iio_dev *indio_dev,
 		*vals = mcp3911_osr_table;
 		*length = ARRAY_SIZE(mcp3911_osr_table);
 		return IIO_AVAIL_LIST;
+	case IIO_CHAN_INFO_SCALE:
+		*type = IIO_VAL_INT_PLUS_NANO;
+		*vals = (int *)mcp3911_scale_table;
+		*length = ARRAY_SIZE(mcp3911_scale_table) * 2;
+		return IIO_AVAIL_LIST;
 	default:
 		return -EINVAL;
 	}
@@ -187,29 +197,9 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
 		break;
 
 	case IIO_CHAN_INFO_SCALE:
-		if (adc->vref) {
-			ret = regulator_get_voltage(adc->vref);
-			if (ret < 0) {
-				dev_err(indio_dev->dev.parent,
-					"failed to get vref voltage: %d\n",
-				       ret);
-				goto out;
-			}
-
-			*val = ret / 1000;
-		} else {
-			*val = MCP3911_INT_VREF_MV;
-		}
-
-		/*
-		 * For 24bit Conversion
-		 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
-		 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
-		 */
-
-		/* val2 = (2^23 * 1.5) */
-		*val2 = 12582912;
-		ret = IIO_VAL_FRACTIONAL;
+		*val = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][0];
+		*val2 = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][1];
+		ret = IIO_VAL_INT_PLUS_NANO;
 		break;
 	}
 
@@ -227,6 +217,18 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev,
 
 	mutex_lock(&adc->lock);
 	switch (mask) {
+	case IIO_CHAN_INFO_SCALE:
+		for (int i = 0; i < MCP3911_NUM_SCALES; i++) {
+			if (val == mcp3911_scale_table[i][0] &&
+				val2 == mcp3911_scale_table[i][1]) {
+
+				adc->gain[channel->channel] = BIT(i);
+				ret = mcp3911_update(adc, MCP3911_REG_GAIN,
+						MCP3911_GAIN_MASK(channel->channel),
+						MCP3911_GAIN_VAL(channel->channel, i), 1);
+			}
+		}
+		break;
 	case IIO_CHAN_INFO_OFFSET:
 		if (val2 != 0) {
 			ret = -EINVAL;
@@ -262,6 +264,47 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev,
 	return ret;
 }
 
+static int mcp3911_calc_scale_table(struct mcp3911 *adc)
+{
+	u32 ref = MCP3911_INT_VREF_MV;
+	u32 div;
+	int ret;
+	int tmp0, tmp1;
+	s64 tmp2;
+
+	if (adc->vref) {
+		ret = regulator_get_voltage(adc->vref);
+		if (ret < 0) {
+			dev_err(&adc->spi->dev,
+				"failed to get vref voltage: %d\n",
+			       ret);
+			return ret;
+		}
+
+		ref = ret / 1000;
+	}
+
+	/*
+	 * For 24bit Conversion
+	 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
+	 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
+	 *
+	 * ref = Reference voltage
+	 * div = (2^23 * 1.5 * gain) = 12582912 * gain
+	 */
+	for (int i = 0; i < MCP3911_NUM_SCALES; i++) {
+		div = 12582912 * BIT(i);
+		tmp2 = div_s64((s64)ref * 1000000000LL, div);
+		tmp1 = div;
+		tmp0 = (int)div_s64_rem(tmp2, 1000000000, &tmp1);
+
+		mcp3911_scale_table[i][0] = 0;
+		mcp3911_scale_table[i][1] = tmp1;
+	}
+
+	return 0;
+}
+
 #define MCP3911_CHAN(idx) {					\
 		.type = IIO_VOLTAGE,				\
 		.indexed = 1,					\
@@ -271,8 +314,10 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
 			BIT(IIO_CHAN_INFO_OFFSET) |		\
 			BIT(IIO_CHAN_INFO_SCALE),		\
-		.info_mask_shared_by_type_available =		\
+		.info_mask_shared_by_type_available =           \
 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
+		.info_mask_separate_available =			\
+			BIT(IIO_CHAN_INFO_SCALE),		\
 		.scan_type = {					\
 			.sign = 's',				\
 			.realbits = 24,				\
@@ -490,6 +535,20 @@ static int mcp3911_probe(struct spi_device *spi)
 	if (ret)
 		return ret;
 
+	ret = mcp3911_calc_scale_table(adc);
+	if (ret)
+		return ret;
+
+       /* Set gain to a known value (1) */
+	for (int i = 0; i < MCP3911_NUM_CHANNELS; i++) {
+		adc->gain[i] = 1;
+		ret = mcp3911_update(adc, MCP3911_REG_GAIN,
+				MCP3911_GAIN_MASK(i),
+				MCP3911_GAIN_VAL(i, 0), 1);
+		if (ret)
+			return ret;
+	}
+
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &mcp3911_info;
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 5/9] iio: adc: mcp3911: add support for buffers
  2022-07-04 17:21 ` [PATCH v3 5/9] iio: adc: mcp3911: add support for buffers Marcus Folkesson
@ 2022-07-04 21:56   ` Andy Shevchenko
  0 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2022-07-04 21:56 UTC (permalink / raw)
  To: Marcus Folkesson
  Cc: Kent Gustavsson, Jonathan Cameron, Lars-Peter Clausen,
	Rob Herring, Krzysztof Kozlowski, linux-iio, devicetree,
	Linux Kernel Mailing List

On Mon, Jul 4, 2022 at 7:20 PM Marcus Folkesson
<marcus.folkesson@gmail.com> wrote:
>
> Add support for buffers to make the driver fit for more usecases.

use cases

...

> +       for_each_set_bit(scan_index, indio_dev->active_scan_mask,
> +                       indio_dev->masklength) {
> +               const struct iio_chan_spec *scan_chan =
> +                       &indio_dev->channels[scan_index];
> +
> +               adc->scan.channels[i] = adc->rx_buf[scan_chan->channel * 3 + 0] << 16 |
> +                                       adc->rx_buf[scan_chan->channel * 3 + 1] << 8 |
> +                                       adc->rx_buf[scan_chan->channel * 3 + 2] << 0;

get_unaligned_be24()

> +               i++;
> +       }

...

> @@ -325,6 +403,7 @@ static int mcp3911_probe(struct spi_device *spi)
>         if (ret)
>                 return ret;
>
> +
>         indio_dev->name = spi_get_device_id(spi)->name;
>         indio_dev->modes = INDIO_DIRECT_MODE;
>         indio_dev->info = &mcp3911_info;

Stray change.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 6/9] iio: adc: mcp3911: add support for interrupts
  2022-07-04 17:21 ` [PATCH v3 6/9] iio: adc: mcp3911: add support for interrupts Marcus Folkesson
@ 2022-07-04 21:57   ` Andy Shevchenko
  0 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2022-07-04 21:57 UTC (permalink / raw)
  To: Marcus Folkesson
  Cc: Kent Gustavsson, Jonathan Cameron, Lars-Peter Clausen,
	Rob Herring, Krzysztof Kozlowski, linux-iio, devicetree,
	Linux Kernel Mailing List

On Mon, Jul 4, 2022 at 7:21 PM Marcus Folkesson
<marcus.folkesson@gmail.com> wrote:
>
> Make it possible to read values upon interrupts.
> Configure Data Ready Signal Output Pin to either HiZ or push-pull and
> use it as interrupt source.

...

> +               /*
> +                * The device generates interrupts as long as it is powered up.
> +                * Some platforms might not allow the option to power it down so
> +                * don't enable the interrupt to avoid extra load on the system

Missed period.

> +                */

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 8/9] iio: adc: mcp3911: add support for oversampling ratio
  2022-07-04 17:21 ` [PATCH v3 8/9] iio: adc: mcp3911: add support for oversampling ratio Marcus Folkesson
@ 2022-07-04 21:58   ` Andy Shevchenko
  0 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2022-07-04 21:58 UTC (permalink / raw)
  To: Marcus Folkesson
  Cc: Kent Gustavsson, Jonathan Cameron, Lars-Peter Clausen,
	Rob Herring, Krzysztof Kozlowski, linux-iio, devicetree,
	Linux Kernel Mailing List

On Mon, Jul 4, 2022 at 7:22 PM Marcus Folkesson
<marcus.folkesson@gmail.com> wrote:
>
> The chip supports oversampling ratio, so expose it to userspace.

...

> +               ret = mcp3911_read(adc,
> +                               MCP3911_REG_CONFIG, val, 2);

One line?

> +               if (ret)
> +                       goto out;

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 9/9] iio: adc: mcp3911: add support to set PGA
  2022-07-04 17:21 ` [PATCH v3 9/9] iio: adc: mcp3911: add support to set PGA Marcus Folkesson
@ 2022-07-04 22:02   ` Andy Shevchenko
  0 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2022-07-04 22:02 UTC (permalink / raw)
  To: Marcus Folkesson
  Cc: Kent Gustavsson, Jonathan Cameron, Lars-Peter Clausen,
	Rob Herring, Krzysztof Kozlowski, linux-iio, devicetree,
	Linux Kernel Mailing List

On Mon, Jul 4, 2022 at 7:23 PM Marcus Folkesson
<marcus.folkesson@gmail.com> wrote:
>
> Add support for setting the Programmable Gain Amplifiers by adjust the
> scale value.

...

> +#define MCP3911_GAIN_MASK(ch)          (0x7 << 3 * ch)

GENMASK()

...

> +       /*
> +        * For 24bit Conversion

24-bit

> +        * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
> +        * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
> +        *
> +        * ref = Reference voltage
> +        * div = (2^23 * 1.5 * gain) = 12582912 * gain
> +        */

...

> +       /* Set gain to a known value (1) */

What is '(1)'? In parentheses we usually refer to something like a
formula somewhere.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 0/9] Improve MCP3911 driver
  2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
                   ` (8 preceding siblings ...)
  2022-07-04 17:21 ` [PATCH v3 9/9] iio: adc: mcp3911: add support to set PGA Marcus Folkesson
@ 2022-07-04 22:03 ` Andy Shevchenko
  9 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2022-07-04 22:03 UTC (permalink / raw)
  To: Marcus Folkesson
  Cc: Kent Gustavsson, Jonathan Cameron, Lars-Peter Clausen,
	Rob Herring, Krzysztof Kozlowski, linux-iio, devicetree,
	Linux Kernel Mailing List

On Mon, Jul 4, 2022 at 7:20 PM Marcus Folkesson
<marcus.folkesson@gmail.com> wrote:
>
> Hi,
>
> This patch series intend to fix bugs and add functionality to the
> MCP3911 driver.
> The main features added are
> - Support for buffers
> - Interrupt driven readings
> - Support for oversampling ratio
> - Support for set scale values (Gain)
>
> Among the bug fixes, there are changes in the formula for calculate raw
> value and a fix for mismatch in the devicetree property.
>
> Another general improvement for the driver is to use managed resources
> for all allocated resources.
>
> See patch notes for more specific changes between versions.
>
> General changes for the series:

For non-commented patches (excluding patch 7!)
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

For commented ones, you may take the tag if you are going to address
them as suggested.

> v3:
> - Drop Phase patch
> - Add Fixes tags for those patches that are fixes
> - Move Fixes patches to the beginning of the patchset

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 3/9] iio: adc: mcp3911: use correct formula for AD conversion
  2022-07-04 17:21 ` [PATCH v3 3/9] iio: adc: mcp3911: use correct formula for AD conversion Marcus Folkesson
@ 2022-07-16 17:18   ` Jonathan Cameron
  2022-07-17 13:58     ` Marcus Folkesson
  0 siblings, 1 reply; 18+ messages in thread
From: Jonathan Cameron @ 2022-07-16 17:18 UTC (permalink / raw)
  To: Marcus Folkesson
  Cc: Kent Gustavsson, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, linux-iio, devicetree, linux-kernel

On Mon,  4 Jul 2022 19:21:10 +0200
Marcus Folkesson <marcus.folkesson@gmail.com> wrote:

> The ADC conversion is actually not rail-to-rail but with a factor 1.5.
> Make use of this factor when calculating actual voltage.
> 
> Fixes: 3a89b289df5d ("iio: adc: add support for mcp3911")
> Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
> Acked-by: Jonathan Cameron <jic23@kernel.org>
?  I doubt I gave a tag (mostly because I don't give tags to patches
I'll pick up and give a SoB on.

Note that tags have to be given explicitly in full form before you can
add them to a patch.  If in doubt (people often given handwavey responses)
then ask people to give an explicit tag.

Jonathan


> ---
>  drivers/iio/adc/mcp3911.c | 17 ++++++++++++-----
>  1 file changed, 12 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
> index f8875076ae80..890af7dca62d 100644
> --- a/drivers/iio/adc/mcp3911.c
> +++ b/drivers/iio/adc/mcp3911.c
> @@ -40,8 +40,8 @@
>  #define MCP3911_CHANNEL(x)		(MCP3911_REG_CHANNEL0 + x * 3)
>  #define MCP3911_OFFCAL(x)		(MCP3911_REG_OFFCAL_CH0 + x * 6)
>  
> -/* Internal voltage reference in uV */
> -#define MCP3911_INT_VREF_UV		1200000
> +/* Internal voltage reference in mV */
> +#define MCP3911_INT_VREF_MV		1200
>  
>  #define MCP3911_REG_READ(reg, id)	((((reg) << 1) | ((id) << 5) | (1 << 0)) & 0xff)
>  #define MCP3911_REG_WRITE(reg, id)	((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff)
> @@ -139,11 +139,18 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
>  
>  			*val = ret / 1000;
>  		} else {
> -			*val = MCP3911_INT_VREF_UV;
> +			*val = MCP3911_INT_VREF_MV;
>  		}
>  
> -		*val2 = 24;
> -		ret = IIO_VAL_FRACTIONAL_LOG2;
> +		/*
> +		 * For 24bit Conversion
> +		 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
> +		 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
> +		 */
> +
> +		/* val2 = (2^23 * 1.5) */
> +		*val2 = 12582912;
> +		ret = IIO_VAL_FRACTIONAL;
>  		break;
>  	}
>  


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 4/9] iio: adc: mcp3911: use resource-managed version of iio_device_register
  2022-07-04 17:21 ` [PATCH v3 4/9] iio: adc: mcp3911: use resource-managed version of iio_device_register Marcus Folkesson
@ 2022-07-16 17:22   ` Jonathan Cameron
  0 siblings, 0 replies; 18+ messages in thread
From: Jonathan Cameron @ 2022-07-16 17:22 UTC (permalink / raw)
  To: Marcus Folkesson
  Cc: Kent Gustavsson, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, linux-iio, devicetree, linux-kernel

On Mon,  4 Jul 2022 19:21:11 +0200
Marcus Folkesson <marcus.folkesson@gmail.com> wrote:

> Keep using managed resources as much as possible.
> 
> Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
> ---
>  drivers/iio/adc/mcp3911.c | 43 ++++++++++++++++-----------------------
>  1 file changed, 18 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c
> index 890af7dca62d..f5fd9da6ab55 100644
> --- a/drivers/iio/adc/mcp3911.c
> +++ b/drivers/iio/adc/mcp3911.c
> @@ -258,6 +258,16 @@ static int mcp3911_config(struct mcp3911 *adc)
>  	return  mcp3911_write(adc, MCP3911_REG_CONFIG, configreg, 2);
>  }
>  
> +static void mcp3911_cleanup(void *_adc)

Very rarely a good idea to cleanup more than one thing in a given
devm_ callback.

> +{
> +	struct mcp3911 *adc = _adc;
> +
> +	if (adc->clki)
> +		clk_disable_unprepare(adc->clki);
> +	if (adc->vref)
> +		regulator_disable(adc->vref);
> +}
> +
>  static int mcp3911_probe(struct spi_device *spi)
>  {
>  	struct iio_dev *indio_dev;
> @@ -271,6 +281,10 @@ static int mcp3911_probe(struct spi_device *spi)
>  	adc = iio_priv(indio_dev);
>  	adc->spi = spi;
>  
> +	ret = devm_add_action_or_reset(&spi->dev, mcp3911_cleanup, adc);
> +	if (ret)
> +		return ret;

You should only register this 'after' what it cleans up.  I want to see
a clear pairing between setup and tear down.

In this particular case register two callbacks, and only register them
if they have anything to do. i.e. the ->clki and ->vref are not null
respectively.

Jonathan


> +
>  	adc->vref = devm_regulator_get_optional(&adc->spi->dev, "vref");
>  	if (IS_ERR(adc->vref)) {
>  		if (PTR_ERR(adc->vref) == -ENODEV) {
> @@ -296,21 +310,20 @@ static int mcp3911_probe(struct spi_device *spi)
>  			dev_err(&adc->spi->dev,
>  				"failed to get adc clk (%ld)\n",
>  				PTR_ERR(adc->clki));
> -			ret = PTR_ERR(adc->clki);
> -			goto reg_disable;
> +			return PTR_ERR(adc->clki);
>  		}
>  	} else {
>  		ret = clk_prepare_enable(adc->clki);
>  		if (ret < 0) {
>  			dev_err(&adc->spi->dev,
>  				"Failed to enable clki: %d\n", ret);
> -			goto reg_disable;
> +			return ret;
>  		}
>  	}
>  
>  	ret = mcp3911_config(adc);
>  	if (ret)
> -		goto clk_disable;
> +		return ret;
>  
>  	indio_dev->name = spi_get_device_id(spi)->name;
>  	indio_dev->modes = INDIO_DIRECT_MODE;
> @@ -322,31 +335,11 @@ static int mcp3911_probe(struct spi_device *spi)
>  
>  	mutex_init(&adc->lock);
>  
> -	ret = iio_device_register(indio_dev);
> -	if (ret)
> -		goto clk_disable;
> -
> -	return ret;
> -
> -clk_disable:
> -	clk_disable_unprepare(adc->clki);
> -reg_disable:
> -	if (adc->vref)
> -		regulator_disable(adc->vref);
> -
> -	return ret;
> +	return devm_iio_device_register(&adc->spi->dev, indio_dev);
>  }
>  
>  static void mcp3911_remove(struct spi_device *spi)
>  {
> -	struct iio_dev *indio_dev = spi_get_drvdata(spi);
> -	struct mcp3911 *adc = iio_priv(indio_dev);
> -
> -	iio_device_unregister(indio_dev);
> -
> -	clk_disable_unprepare(adc->clki);
> -	if (adc->vref)
> -		regulator_disable(adc->vref);
>  }
>  
>  static const struct of_device_id mcp3911_dt_ids[] = {


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 3/9] iio: adc: mcp3911: use correct formula for AD conversion
  2022-07-16 17:18   ` Jonathan Cameron
@ 2022-07-17 13:58     ` Marcus Folkesson
  0 siblings, 0 replies; 18+ messages in thread
From: Marcus Folkesson @ 2022-07-17 13:58 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Kent Gustavsson, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, linux-iio, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1004 bytes --]

Hi,

On Sat, Jul 16, 2022 at 06:18:37PM +0100, Jonathan Cameron wrote:
> On Mon,  4 Jul 2022 19:21:10 +0200
> Marcus Folkesson <marcus.folkesson@gmail.com> wrote:
> 
> > The ADC conversion is actually not rail-to-rail but with a factor 1.5.
> > Make use of this factor when calculating actual voltage.
> > 
> > Fixes: 3a89b289df5d ("iio: adc: add support for mcp3911")
> > Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
> > Acked-by: Jonathan Cameron <jic23@kernel.org>
> ?  I doubt I gave a tag (mostly because I don't give tags to patches
> I'll pick up and give a SoB on.
> 
> Note that tags have to be given explicitly in full form before you can
> add them to a patch.  If in doubt (people often given handwavey responses)
> then ask people to give an explicit tag.

Sorry for that. I will remove the tag.
I interpreted your "Otherwise looks good to me." as an acked-by.

I will only go for explicit tags forward. 

Thanks,
Marcus Folkesson

> 
> Jonathan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2022-07-17 13:55 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-04 17:21 [PATCH v3 0/9] Improve MCP3911 driver Marcus Folkesson
2022-07-04 17:21 ` [PATCH v3 1/9] iio: adc: mcp3911: make use of the sign bit Marcus Folkesson
2022-07-04 17:21 ` [PATCH v3 2/9] iio: adc: mcp3911: correct "microchip,device-addr" property Marcus Folkesson
2022-07-04 17:21 ` [PATCH v3 3/9] iio: adc: mcp3911: use correct formula for AD conversion Marcus Folkesson
2022-07-16 17:18   ` Jonathan Cameron
2022-07-17 13:58     ` Marcus Folkesson
2022-07-04 17:21 ` [PATCH v3 4/9] iio: adc: mcp3911: use resource-managed version of iio_device_register Marcus Folkesson
2022-07-16 17:22   ` Jonathan Cameron
2022-07-04 17:21 ` [PATCH v3 5/9] iio: adc: mcp3911: add support for buffers Marcus Folkesson
2022-07-04 21:56   ` Andy Shevchenko
2022-07-04 17:21 ` [PATCH v3 6/9] iio: adc: mcp3911: add support for interrupts Marcus Folkesson
2022-07-04 21:57   ` Andy Shevchenko
2022-07-04 17:21 ` [PATCH v3 7/9] dt-bindings: iio: adc: mcp3911: add microchip,data-ready-hiz entry Marcus Folkesson
2022-07-04 17:21 ` [PATCH v3 8/9] iio: adc: mcp3911: add support for oversampling ratio Marcus Folkesson
2022-07-04 21:58   ` Andy Shevchenko
2022-07-04 17:21 ` [PATCH v3 9/9] iio: adc: mcp3911: add support to set PGA Marcus Folkesson
2022-07-04 22:02   ` Andy Shevchenko
2022-07-04 22:03 ` [PATCH v3 0/9] Improve MCP3911 driver Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).