public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add support for the DFRobot SEN0322 oxygen sensor
@ 2025-04-28 10:50 Tóth János via B4 Relay
  2025-04-28 10:50 ` [PATCH 1/2] dt-bindings: iio: chemical: Document SEN0322 Tóth János via B4 Relay
  2025-04-28 10:50 ` [PATCH 2/2] iio: chemical: Add driver for SEN0322 Tóth János via B4 Relay
  0 siblings, 2 replies; 10+ messages in thread
From: Tóth János via B4 Relay @ 2025-04-28 10:50 UTC (permalink / raw)
  To: Jonathan Cameron, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-iio, devicetree, linux-kernel, Tóth János

This patchset adds a driver and the documentation for the
DFRobot SEN0322 oxygen sensor.

Signed-off-by: Tóth János <gomba007@gmail.com>
---
Tóth János (2):
      dt-bindings: iio: chemical: Document SEN0322
      iio: chemical: Add driver for SEN0322

 .../bindings/iio/chemical/dfrobot,sen0322.yaml     |  41 ++++
 MAINTAINERS                                        |   6 +
 drivers/iio/chemical/Kconfig                       |  10 +
 drivers/iio/chemical/Makefile                      |   1 +
 drivers/iio/chemical/sen0322.c                     | 238 +++++++++++++++++++++
 5 files changed, 296 insertions(+)
---
base-commit: b4432656b36e5cc1d50a1f2dc15357543add530e
change-id: 20250428-iio-chemical-sen0322-cf8fbbbe7546

Best regards,
-- 
Tóth János <gomba007@gmail.com>



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

* [PATCH 1/2] dt-bindings: iio: chemical: Document SEN0322
  2025-04-28 10:50 [PATCH 0/2] Add support for the DFRobot SEN0322 oxygen sensor Tóth János via B4 Relay
@ 2025-04-28 10:50 ` Tóth János via B4 Relay
  2025-04-28 14:30   ` Krzysztof Kozlowski
  2025-04-28 10:50 ` [PATCH 2/2] iio: chemical: Add driver for SEN0322 Tóth János via B4 Relay
  1 sibling, 1 reply; 10+ messages in thread
From: Tóth János via B4 Relay @ 2025-04-28 10:50 UTC (permalink / raw)
  To: Jonathan Cameron, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-iio, devicetree, linux-kernel, Tóth János

From: Tóth János <gomba007@gmail.com>

Add documentation for the DFRobot SEN0322 oxygen sensor.

Signed-off-by: Tóth János <gomba007@gmail.com>
---
 .../bindings/iio/chemical/dfrobot,sen0322.yaml     | 41 ++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/chemical/dfrobot,sen0322.yaml b/Documentation/devicetree/bindings/iio/chemical/dfrobot,sen0322.yaml
new file mode 100644
index 000000000000..9410d04fb91d
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/chemical/dfrobot,sen0322.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/chemical/dfrobot,sen0322.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DFRobot SEN0322 oxygen sensor
+
+maintainers:
+  - Tóth János <gomba007@gmail.com>
+
+description: >
+  DFRobot SEN0322 is an oxygen sensor. It supports I2C for communication.
+
+  Datasheet:
+    https://wiki.dfrobot.com/Gravity_I2C_Oxygen_Sensor_SKU_SEN0322
+
+properties:
+  compatible:
+    const: dfrobot,sen0322
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      sen0322@73 {
+        compatible = "dfrobot,sen0322";
+        reg = <0x73>;
+      };
+    };

-- 
2.34.1



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

* [PATCH 2/2] iio: chemical: Add driver for SEN0322
  2025-04-28 10:50 [PATCH 0/2] Add support for the DFRobot SEN0322 oxygen sensor Tóth János via B4 Relay
  2025-04-28 10:50 ` [PATCH 1/2] dt-bindings: iio: chemical: Document SEN0322 Tóth János via B4 Relay
@ 2025-04-28 10:50 ` Tóth János via B4 Relay
  2025-05-04 18:40   ` Jonathan Cameron
  1 sibling, 1 reply; 10+ messages in thread
From: Tóth János via B4 Relay @ 2025-04-28 10:50 UTC (permalink / raw)
  To: Jonathan Cameron, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-iio, devicetree, linux-kernel, Tóth János

From: Tóth János <gomba007@gmail.com>

Add support for the DFRobot SEN0322 oxygen sensor.

Datasheet:
	https://wiki.dfrobot.com/Gravity_I2C_Oxygen_Sensor_SKU_SEN0322

To instantiate (assuming device is connected to I2C-2):
	echo 'sen0322 0x73' > /sys/class/i2c-dev/i2c-2/device/new_device

To read the oxygen concentration (assuming device is iio:device0):
	cat /sys/bus/iio/devices/iio:device0/in_concentration_input

Signed-off-by: Tóth János <gomba007@gmail.com>
---
 MAINTAINERS                    |   6 ++
 drivers/iio/chemical/Kconfig   |  10 ++
 drivers/iio/chemical/Makefile  |   1 +
 drivers/iio/chemical/sen0322.c | 238 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 255 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3cbf9ac0d83f..6fda7a2f1248 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6852,6 +6852,12 @@ L:	linux-rtc@vger.kernel.org
 S:	Maintained
 F:	drivers/rtc/rtc-sd2405al.c
 
+DFROBOT SEN0322 DRIVER
+M:	Tóth János <gomba007@gmail.com>
+L:	linux-iio@vger.kernel.org
+S:	Maintained
+F:	drivers/iio/chemical/sen0322.c
+
 DH ELECTRONICS DHSOM SOM AND BOARD SUPPORT
 M:	Christoph Niedermaier <cniedermaier@dh-electronics.com>
 M:	Marek Vasut <marex@denx.de>
diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig
index 330fe0af946f..60a81863d123 100644
--- a/drivers/iio/chemical/Kconfig
+++ b/drivers/iio/chemical/Kconfig
@@ -166,6 +166,16 @@ config SCD4X
 	  To compile this driver as a module, choose M here: the module will
 	  be called scd4x.
 
+config SEN0322
+	tristate "SEN0322 oxygen sensor"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  Say Y here to build support for the DFRobot SEN0322 oxygen sensor.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called sen0322.
+
 config SENSIRION_SGP30
 	tristate "Sensirion SGPxx gas sensors"
 	depends on I2C
diff --git a/drivers/iio/chemical/Makefile b/drivers/iio/chemical/Makefile
index 4866db06bdc9..deeff0e4e6f7 100644
--- a/drivers/iio/chemical/Makefile
+++ b/drivers/iio/chemical/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_SCD30_CORE) += scd30_core.o
 obj-$(CONFIG_SCD30_I2C) += scd30_i2c.o
 obj-$(CONFIG_SCD30_SERIAL) += scd30_serial.o
 obj-$(CONFIG_SCD4X) += scd4x.o
+obj-$(CONFIG_SEN0322)	+= sen0322.o
 obj-$(CONFIG_SENSEAIR_SUNRISE_CO2) += sunrise_co2.o
 obj-$(CONFIG_SENSIRION_SGP30)	+= sgp30.o
 obj-$(CONFIG_SENSIRION_SGP40)	+= sgp40.o
diff --git a/drivers/iio/chemical/sen0322.c b/drivers/iio/chemical/sen0322.c
new file mode 100644
index 000000000000..5f1f4528401e
--- /dev/null
+++ b/drivers/iio/chemical/sen0322.c
@@ -0,0 +1,238 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the DFRobot SEN0322 oxygen sensor.
+ *
+ * Datasheet:
+ *	https://wiki.dfrobot.com/Gravity_I2C_Oxygen_Sensor_SKU_SEN0322
+ *
+ * Possible I2C slave addresses:
+ *	0x70
+ *	0x71
+ *	0x72
+ *	0x73
+ *
+ * Copyright (C) 2025 Tóth János <gomba007@gmail.com>
+ */
+
+#include <linux/i2c.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include <linux/iio/iio.h>
+
+#define DRIVER_NAME "sen0322"
+
+#define SEN0322_REG_DATA	0x03
+#define SEN0322_REG_COEFF	0x0A
+
+#define FIXED_FRAC_BITS		18
+#define FIXED_INT(x)		((fixed_t)((x) << FIXED_FRAC_BITS))
+
+typedef u32 fixed_t;
+
+struct sen0322 {
+	struct i2c_client	*client;
+	struct regmap		*regmap;
+	fixed_t			coeff;
+};
+
+static fixed_t fixed_mul(fixed_t a, fixed_t b)
+{
+	u64 tmp;
+
+	tmp = (u64)a * (u64)b;
+	tmp = (tmp >> FIXED_FRAC_BITS) + ((tmp >> FIXED_FRAC_BITS) & 1);
+
+	if (tmp > U32_MAX)
+		return (fixed_t)U32_MAX;
+	else
+		return (fixed_t)tmp;
+}
+
+static fixed_t fixed_div(fixed_t a, fixed_t b)
+{
+	u64 tmp;
+
+	tmp = (uint64_t)a << FIXED_FRAC_BITS;
+	tmp += (b >> 1);
+
+	return (fixed_t)(div_u64(tmp, b));
+}
+
+static int sen0322_read_coeff(struct sen0322 *sen0322)
+{
+	u32 val;
+	int ret;
+
+	ret = regmap_read(sen0322->regmap, SEN0322_REG_COEFF, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val)
+		sen0322->coeff = fixed_div(FIXED_INT(val), FIXED_INT(1000));
+	else
+		sen0322->coeff = fixed_div(FIXED_INT(209), FIXED_INT(1200));
+
+	dev_dbg(&sen0322->client->dev, "coeff: %08X\n", sen0322->coeff);
+
+	return 0;
+}
+
+static int sen0322_read_data(struct sen0322 *sen0322)
+{
+	u8 data[4] = { 0 };
+	int ret;
+
+	ret = regmap_bulk_read(sen0322->regmap, SEN0322_REG_DATA, data, 3);
+	if (ret < 0)
+		return ret;
+
+	ret = data[0] * 100 +  data[1] * 10 + data[2];
+
+	dev_dbg(&sen0322->client->dev, "raw data: %d\n", ret);
+
+	return ret;
+}
+
+static int sen0322_read_prep_data(struct sen0322 *sen0322)
+{
+	fixed_t val;
+	int ret;
+
+	if (!sen0322->coeff) {
+		ret = sen0322_read_coeff(sen0322);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = sen0322_read_data(sen0322);
+	if (ret < 0)
+		return ret;
+
+	val = fixed_mul(sen0322->coeff, FIXED_INT(ret));
+
+	dev_dbg(&sen0322->client->dev, "prep data: %08X\n", val);
+
+	return val >> FIXED_FRAC_BITS;
+}
+
+static int sen0322_read_raw(struct iio_dev *iio_dev,
+			    const struct iio_chan_spec *chan,
+			    int *val, int *val2, long mask)
+{
+	struct sen0322 *sen0322 = iio_priv(iio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		switch (chan->type) {
+		case IIO_CONCENTRATION:
+			ret = sen0322_read_data(sen0322);
+			if (ret < 0)
+				return ret;
+
+			*val = ret;
+			return IIO_VAL_INT;
+
+		default:
+			return -EINVAL;
+		}
+
+	case IIO_CHAN_INFO_PROCESSED:
+		switch (chan->type) {
+		case IIO_CONCENTRATION:
+			ret = sen0322_read_prep_data(sen0322);
+			if (ret < 0)
+				return ret;
+
+			*val = ret;
+			return IIO_VAL_INT;
+
+		default:
+			return -EINVAL;
+		}
+
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_CONCENTRATION:
+			*val = 1;
+			*val2 = 100;
+			return IIO_VAL_FRACTIONAL;
+
+		default:
+			return -EINVAL;
+		}
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct iio_info sen0322_info = {
+	.read_raw = sen0322_read_raw,
+};
+
+static const struct regmap_config sen0322_regmap_conf = {
+	.reg_bits = 8,
+	.val_bits = 8,
+};
+
+static const struct iio_chan_spec sen0322_channels[] = {
+	{
+		.type = IIO_CONCENTRATION,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				      BIT(IIO_CHAN_INFO_PROCESSED) |
+				      BIT(IIO_CHAN_INFO_SCALE),
+	},
+};
+
+static int sen0322_probe(struct i2c_client *client)
+{
+	struct sen0322 *sen0322;
+	struct iio_dev *iio_dev;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+		return -ENODEV;
+
+	iio_dev = devm_iio_device_alloc(&client->dev, sizeof(*sen0322));
+	if (!iio_dev)
+		return -ENOMEM;
+
+	sen0322 = iio_priv(iio_dev);
+	sen0322->client = client;
+	sen0322->coeff = 0;
+
+	sen0322->regmap = devm_regmap_init_i2c(client, &sen0322_regmap_conf);
+	if (IS_ERR(sen0322->regmap))
+		return PTR_ERR(sen0322->regmap);
+
+	i2c_set_clientdata(client, sen0322);
+
+	iio_dev->info = &sen0322_info;
+	iio_dev->name = DRIVER_NAME;
+	iio_dev->channels = sen0322_channels;
+	iio_dev->num_channels = ARRAY_SIZE(sen0322_channels);
+	iio_dev->modes = INDIO_DIRECT_MODE;
+
+	return devm_iio_device_register(&client->dev, iio_dev);
+}
+
+static const struct of_device_id sen0322_of_match[] = {
+	{ .compatible = "dfrobot,sen0322" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sen0322_of_match);
+
+static struct i2c_driver sen0322_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.of_match_table = sen0322_of_match,
+	},
+	.probe = sen0322_probe,
+};
+module_i2c_driver(sen0322_driver);
+
+MODULE_AUTHOR("Tóth János <gomba007@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SEN0322 oxygen sensor driver");

-- 
2.34.1



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

* Re: [PATCH 1/2] dt-bindings: iio: chemical: Document SEN0322
  2025-04-28 10:50 ` [PATCH 1/2] dt-bindings: iio: chemical: Document SEN0322 Tóth János via B4 Relay
@ 2025-04-28 14:30   ` Krzysztof Kozlowski
  2025-04-28 14:45     ` Tóth János
  0 siblings, 1 reply; 10+ messages in thread
From: Krzysztof Kozlowski @ 2025-04-28 14:30 UTC (permalink / raw)
  To: gomba007, Jonathan Cameron, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-iio, devicetree, linux-kernel

On 28/04/2025 12:50, Tóth János via B4 Relay wrote:
> +
> +description: >
> +  DFRobot SEN0322 is an oxygen sensor. It supports I2C for communication.
> +
> +  Datasheet:
> +    https://wiki.dfrobot.com/Gravity_I2C_Oxygen_Sensor_SKU_SEN0322
> +
> +properties:
> +  compatible:
> +    const: dfrobot,sen0322
> +
> +  reg:
> +    maxItems: 1

No other properties like supplies or configuration? If so, this could go
to trivial-devices.

> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    i2c {
> +      #address-cells = <1>;
> +      #size-cells = <0>;
> +
> +      sen0322@73 {

Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation

Choose something from above or similar devices.



Best regards,
Krzysztof

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

* Re: [PATCH 1/2] dt-bindings: iio: chemical: Document SEN0322
  2025-04-28 14:30   ` Krzysztof Kozlowski
@ 2025-04-28 14:45     ` Tóth János
  2025-05-04 18:27       ` Jonathan Cameron
  0 siblings, 1 reply; 10+ messages in thread
From: Tóth János @ 2025-04-28 14:45 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Jonathan Cameron, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
	linux-kernel

Hi!

> No other properties like supplies or configuration? If so, this could go
> to trivial-devices.

I don't think so, I'll add it as a trivial-device then.

> > +      sen0322@73 {
> 
> Node names should be generic. See also an explanation and list of
> examples (not exhaustive) in DT specification:
> https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
> 
> Choose something from above or similar devices.

Noted, thanks!

Best regards,
János


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

* Re: [PATCH 1/2] dt-bindings: iio: chemical: Document SEN0322
  2025-04-28 14:45     ` Tóth János
@ 2025-05-04 18:27       ` Jonathan Cameron
  2025-05-05  6:32         ` Tóth János
  0 siblings, 1 reply; 10+ messages in thread
From: Jonathan Cameron @ 2025-05-04 18:27 UTC (permalink / raw)
  To: Tóth János
  Cc: Krzysztof Kozlowski, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
	linux-kernel

On Mon, 28 Apr 2025 16:45:32 +0200
Tóth János <gomba007@gmail.com> wrote:

> Hi!
> 
> > No other properties like supplies or configuration? If so, this could go
> > to trivial-devices.  
> 
> I don't think so, I'll add it as a trivial-device then.

vcc-supply?

It is very common to see later boards have controllable supplies
(or someone to enable that on an existing board for power saving) so
good and trivial to support just turning the supply on when we probe
the driver and off when we remove it.


> 
> > > +      sen0322@73 {  
> > 
> > Node names should be generic. See also an explanation and list of
> > examples (not exhaustive) in DT specification:
> > https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
> > 
> > Choose something from above or similar devices.  
> 
> Noted, thanks!
> 
> Best regards,
> János
> 
> 


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

* Re: [PATCH 2/2] iio: chemical: Add driver for SEN0322
  2025-04-28 10:50 ` [PATCH 2/2] iio: chemical: Add driver for SEN0322 Tóth János via B4 Relay
@ 2025-05-04 18:40   ` Jonathan Cameron
  2025-05-05  6:22     ` Tóth János
  0 siblings, 1 reply; 10+ messages in thread
From: Jonathan Cameron @ 2025-05-04 18:40 UTC (permalink / raw)
  To: Tóth János via B4 Relay
  Cc: gomba007, Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, linux-iio, devicetree, linux-kernel

On Mon, 28 Apr 2025 12:50:14 +0200
Tóth János via B4 Relay <devnull+gomba007.gmail.com@kernel.org> wrote:

> From: Tóth János <gomba007@gmail.com>
> 
> Add support for the DFRobot SEN0322 oxygen sensor.
> 
> Datasheet:
> 	https://wiki.dfrobot.com/Gravity_I2C_Oxygen_Sensor_SKU_SEN0322
> 
> To instantiate (assuming device is connected to I2C-2):
> 	echo 'sen0322 0x73' > /sys/class/i2c-dev/i2c-2/device/new_device
> 
> To read the oxygen concentration (assuming device is iio:device0):
> 	cat /sys/bus/iio/devices/iio:device0/in_concentration_input
> 
> Signed-off-by: Tóth János <gomba007@gmail.com>

Hi Tóth

Nice little driver.  Main questions are around the userspace ABI and why
we have both _RAW and _PROCESSED reported. There are few reasons we
let drivers do that and I don't see what reason applies here.

Mostly it just confuses userspace by providing multiple ways to read the
same thing.

Jonathan

> diff --git a/drivers/iio/chemical/sen0322.c b/drivers/iio/chemical/sen0322.c
> new file mode 100644
> index 000000000000..5f1f4528401e
> --- /dev/null
> +++ b/drivers/iio/chemical/sen0322.c
> @@ -0,0 +1,238 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for the DFRobot SEN0322 oxygen sensor.
> + *
> + * Datasheet:
> + *	https://wiki.dfrobot.com/Gravity_I2C_Oxygen_Sensor_SKU_SEN0322
> + *
> + * Possible I2C slave addresses:
> + *	0x70
> + *	0x71
> + *	0x72
> + *	0x73
> + *
> + * Copyright (C) 2025 Tóth János <gomba007@gmail.com>
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/math64.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +
> +#include <linux/iio/iio.h>
> +
> +#define DRIVER_NAME "sen0322"
> +
> +#define SEN0322_REG_DATA	0x03
> +#define SEN0322_REG_COEFF	0x0A
> +
> +#define FIXED_FRAC_BITS		18
> +#define FIXED_INT(x)		((fixed_t)((x) << FIXED_FRAC_BITS))
> +
> +typedef u32 fixed_t;
> +
> +struct sen0322 {
> +	struct i2c_client	*client;
What do you need client for after probe?

There is a function to get the struct device from the regmap.

> +	struct regmap		*regmap;
> +	fixed_t			coeff;
> +};
> +
> +static fixed_t fixed_mul(fixed_t a, fixed_t b)
> +{
> +	u64 tmp;
> +
> +	tmp = (u64)a * (u64)b;
> +	tmp = (tmp >> FIXED_FRAC_BITS) + ((tmp >> FIXED_FRAC_BITS) & 1);

These need some comments.  It's moderately fiddly fixed point maths
and there are many ways to do that.

> +
> +	if (tmp > U32_MAX)
> +		return (fixed_t)U32_MAX;
> +	else
> +		return (fixed_t)tmp;
> +}
> +
> +static fixed_t fixed_div(fixed_t a, fixed_t b)
> +{
> +	u64 tmp;
> +
> +	tmp = (uint64_t)a << FIXED_FRAC_BITS;
> +	tmp += (b >> 1);
> +
> +	return (fixed_t)(div_u64(tmp, b));
> +}
> +
> +static int sen0322_read_coeff(struct sen0322 *sen0322)
> +{
> +	u32 val;
> +	int ret;
> +
> +	ret = regmap_read(sen0322->regmap, SEN0322_REG_COEFF, &val);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (val)
> +		sen0322->coeff = fixed_div(FIXED_INT(val), FIXED_INT(1000));
> +	else
> +		sen0322->coeff = fixed_div(FIXED_INT(209), FIXED_INT(1200));

This second one is just a number. Why not just put the constant here?

> +
> +	dev_dbg(&sen0322->client->dev, "coeff: %08X\n", sen0322->coeff);
> +
> +	return 0;
> +}
> +
> +static int sen0322_read_data(struct sen0322 *sen0322)
> +{
> +	u8 data[4] = { 0 };
> +	int ret;
> +
> +	ret = regmap_bulk_read(sen0322->regmap, SEN0322_REG_DATA, data, 3);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = data[0] * 100 +  data[1] * 10 + data[2];
> +
> +	dev_dbg(&sen0322->client->dev, "raw data: %d\n", ret);
> +
> +	return ret;
> +}
> +
> +static int sen0322_read_prep_data(struct sen0322 *sen0322)
> +{
> +	fixed_t val;
> +	int ret;
> +
> +	if (!sen0322->coeff) {
> +		ret = sen0322_read_coeff(sen0322);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	ret = sen0322_read_data(sen0322);
> +	if (ret < 0)
> +		return ret;
> +
> +	val = fixed_mul(sen0322->coeff, FIXED_INT(ret));
Superficially looks like you could compute a correct _SCALE and
make this maths a userspace problem?

> +
> +	dev_dbg(&sen0322->client->dev, "prep data: %08X\n", val);
> +
> +	return val >> FIXED_FRAC_BITS;
> +}
> +
> +static int sen0322_read_raw(struct iio_dev *iio_dev,
> +			    const struct iio_chan_spec *chan,
> +			    int *val, int *val2, long mask)
> +{
> +	struct sen0322 *sen0322 = iio_priv(iio_dev);
> +	int ret;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		switch (chan->type) {
> +		case IIO_CONCENTRATION:

You need a strong reason to provide both _RAW and _PROCESSED.
What was your thinking here? 

As a general rule, if the conversion is linear, then we provide
_RAW and _SCALE. If it's non linear then _PROCESSED.

The _RAW + _SCALE thing is for 2 reasons.
1 - userspace is better at maths as it has floating point easily
    available.
2 - if we ever add buffered capture then _RAW tends to be of a defined
    number of bits whereas processed is more complex.

> +			ret = sen0322_read_data(sen0322);
> +			if (ret < 0)
> +				return ret;
> +
> +			*val = ret;
> +			return IIO_VAL_INT;
> +
> +		default:
> +			return -EINVAL;
> +		}
> +
> +	case IIO_CHAN_INFO_PROCESSED:
> +		switch (chan->type) {
> +		case IIO_CONCENTRATION:
> +			ret = sen0322_read_prep_data(sen0322);
> +			if (ret < 0)
> +				return ret;
> +
> +			*val = ret;
> +			return IIO_VAL_INT;
> +
> +		default:
> +			return -EINVAL;
> +		}
> +
> +	case IIO_CHAN_INFO_SCALE:
> +		switch (chan->type) {
> +		case IIO_CONCENTRATION:
> +			*val = 1;
> +			*val2 = 100;

Given above you use the coeff in the calculation of processed
I don't understand what this scale is indicating.
Scale only applies to _RAW channels.

> +			return IIO_VAL_FRACTIONAL;
> +
> +		default:
> +			return -EINVAL;
> +		}
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}

> +static const struct iio_chan_spec sen0322_channels[] = {
> +	{
> +		.type = IIO_CONCENTRATION,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_PROCESSED) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
> +	},
> +};
This doesn't need to be an array. Can just use one structure
and pass the address plus an explicit 1 for the number of channels
below.   Quite a few drivers do it like this though and I don't mind
much.

> +
> +static int sen0322_probe(struct i2c_client *client)
> +{
> +	struct sen0322 *sen0322;
> +	struct iio_dev *iio_dev;
> +
> +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
> +		return -ENODEV;
> +
> +	iio_dev = devm_iio_device_alloc(&client->dev, sizeof(*sen0322));
> +	if (!iio_dev)
> +		return -ENOMEM;
> +
> +	sen0322 = iio_priv(iio_dev);
> +	sen0322->client = client;
> +	sen0322->coeff = 0;
> +
> +	sen0322->regmap = devm_regmap_init_i2c(client, &sen0322_regmap_conf);
> +	if (IS_ERR(sen0322->regmap))
> +		return PTR_ERR(sen0322->regmap);
> +
> +	i2c_set_clientdata(client, sen0322);

I don't immediately see where this is used. If it's not then drop setting it.

> +
> +	iio_dev->info = &sen0322_info;
> +	iio_dev->name = DRIVER_NAME;

As below. I'd rather see the name here as a string.

> +	iio_dev->channels = sen0322_channels;
> +	iio_dev->num_channels = ARRAY_SIZE(sen0322_channels);
> +	iio_dev->modes = INDIO_DIRECT_MODE;
> +
> +	return devm_iio_device_register(&client->dev, iio_dev);
> +}
> +
> +static const struct of_device_id sen0322_of_match[] = {
> +	{ .compatible = "dfrobot,sen0322" },
> +	{ /* sentinel */ }

No real need for the comment.

> +};
> +MODULE_DEVICE_TABLE(of, sen0322_of_match);
> +
> +static struct i2c_driver sen0322_driver = {
> +	.driver = {

> +		.name = DRIVER_NAME,
I'd rather see the string directly here.  There is no reason
why the iio_dev->name above would always match this so in general
it is easier to just see the strings in each place rather than
under a define.

> +		.of_match_table = sen0322_of_match,
> +	},
> +	.probe = sen0322_probe,
> +};
> +module_i2c_driver(sen0322_driver);
> +
> +MODULE_AUTHOR("Tóth János <gomba007@gmail.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("SEN0322 oxygen sensor driver");
> 


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

* Re: [PATCH 2/2] iio: chemical: Add driver for SEN0322
  2025-05-04 18:40   ` Jonathan Cameron
@ 2025-05-05  6:22     ` Tóth János
  0 siblings, 0 replies; 10+ messages in thread
From: Tóth János @ 2025-05-05  6:22 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Tóth János via B4 Relay, Lars-Peter Clausen,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-iio,
	devicetree, linux-kernel

Hi Jonathan!

Thank you for the review and the explanation! I've misunderstood the purpose of
_SCALE. I'll rewrite the driver to use only _RAW and _SCALE.

Regards,
János

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

* Re: [PATCH 1/2] dt-bindings: iio: chemical: Document SEN0322
  2025-05-04 18:27       ` Jonathan Cameron
@ 2025-05-05  6:32         ` Tóth János
  2025-05-05 13:23           ` Jonathan Cameron
  0 siblings, 1 reply; 10+ messages in thread
From: Tóth János @ 2025-05-05  6:32 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Krzysztof Kozlowski, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
	linux-kernel

Hi!

> > > No other properties like supplies or configuration? If so, this could go
> > > to trivial-devices.  
> > 
> > I don't think so, I'll add it as a trivial-device then.
> 
> vcc-supply?

It has no switchable VCC supply.

Regards,
János

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

* Re: [PATCH 1/2] dt-bindings: iio: chemical: Document SEN0322
  2025-05-05  6:32         ` Tóth János
@ 2025-05-05 13:23           ` Jonathan Cameron
  0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2025-05-05 13:23 UTC (permalink / raw)
  To: Tóth János
  Cc: Krzysztof Kozlowski, Lars-Peter Clausen, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
	linux-kernel

On Mon, 5 May 2025 08:32:02 +0200
Tóth János <gomba007@gmail.com> wrote:

> Hi!
> 
> > > > No other properties like supplies or configuration? If so, this could go
> > > > to trivial-devices.    
> > > 
> > > I don't think so, I'll add it as a trivial-device then.  
> > 
> > vcc-supply?  
> 
> It has no switchable VCC supply.

Your board may have no switchable vcc-supply. In general someone else's
board with this part in use may well have a switchable vcc-supply.
Ideally the DT binding should support that and the driver should just
turn it on at probe.  A stub / fake regulator will be provided by
the regulator core so there is no need for special handling of boards
that don't have switchable vcc-supply - they will just work.

Jonathan

> 
> Regards,
> János
> 


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

end of thread, other threads:[~2025-05-05 13:23 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-28 10:50 [PATCH 0/2] Add support for the DFRobot SEN0322 oxygen sensor Tóth János via B4 Relay
2025-04-28 10:50 ` [PATCH 1/2] dt-bindings: iio: chemical: Document SEN0322 Tóth János via B4 Relay
2025-04-28 14:30   ` Krzysztof Kozlowski
2025-04-28 14:45     ` Tóth János
2025-05-04 18:27       ` Jonathan Cameron
2025-05-05  6:32         ` Tóth János
2025-05-05 13:23           ` Jonathan Cameron
2025-04-28 10:50 ` [PATCH 2/2] iio: chemical: Add driver for SEN0322 Tóth János via B4 Relay
2025-05-04 18:40   ` Jonathan Cameron
2025-05-05  6:22     ` Tóth János

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox