Devicetree
 help / color / mirror / Atom feed
* [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC
@ 2026-05-25 10:51 Piyush Patle
  2026-05-25 10:51 ` [PATCH v10 01/11] dt-bindings: iio: adc: hx711: clean up existing binding text Piyush Patle
                   ` (12 more replies)
  0 siblings, 13 replies; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

The HX710B is a 24-bit ADC from AVIA Semiconductor, related to the
HX711 already supported in this driver.  Unlike the HX711 (which has
selectable gain and two input channels), the HX710B has a fixed gain
of 128 and two operating modes selected by the trailing PD_SCK pulse
count after each conversion:

  25 pulses (1 trailing): differential input at 10 SPS
  26 pulses (2 trailing): DVDD-AVDD supply monitor at 40 SPS
  27 pulses (3 trailing): differential input at 40 SPS

This series first extends the existing HX711 binding and driver with
preparatory refactoring, then adds HX710B support on top.

The differential input is exposed as a single IIO channel with
IIO_CHAN_INFO_SAMP_FREQ, allowing userspace to select 10 or 40 SPS
without needing two separate channels for the same physical input.
The supply monitor is a second channel at fixed 40 SPS.

Patches 01/11, 02/11, 03/11, and 05/11 have already been applied to
the iio.git testing branch.  They are re-included here so the series
applies cleanly as a unit.

Changes from v9:
  - 02/11: Added dvdd-supply alongside vsup-supply. Per the v8
    discussion, DVDD is a board-supplied digital rail on the HX711
    (figure 1 of the datasheet shows it as a separate input supply,
    not merely a bypass capacitor point). It was missing from the
    original binding. Moved its declaration from 04/11 to this earlier
    shared-supply patch.
  - 04/11: Removed dvdd-supply declaration (now in 02/11). Updated
    commit message to reflect the patch now adds only vref-supply and
    the allOf constraint.
  - 06/11: No code change. Removed inaccurate below-the-line note
    about __counted_by_ptr() commit reference.
  - 08/11: Remove blank line between val = hx711_wait_for_ready() and
    if (val) check in hx711_reset().
  - 11/11: Revert IIO_DECLARE_BUFFER_WITH_TS() to explicit named
    struct (both variants have exactly 2 channels). Add
    iio_device_claim_direct_mode() in hx710b_write_raw() to prevent
    concurrent hardware changes during triggered buffer capture; drop
    channel_set = 0 reset (hx711_set_hx710b_channel() re-programs the
    chip automatically on the next read). MODULE_DESCRIPTION: change
    'compatible' to 'similar'.

Piyush Patle (11):
  dt-bindings: iio: adc: hx711: clean up existing binding text
  dt-bindings: iio: adc: hx711: add VSUP supply property
  dt-bindings: iio: adc: hx711: add RATE GPIO property
  dt-bindings: iio: adc: hx711: add HX710B support
  iio: adc: hx711: move scale computation to per-device storage
  iio: adc: hx711: introduce hx711_chip_info structure
  iio: adc: hx711: pass trailing pulse count into hx711_read
  iio: adc: hx711: split variable assignments in hx711_read and
    hx711_reset
  iio: adc: hx711: localize loop iterators in hx711_read
  iio: adc: hx711: pass iio_chan_spec to hx711_reset_read
  iio: adc: hx711: add support for HX710B

 .../bindings/iio/adc/avia-hx711.yaml          |  79 +++-
 drivers/iio/adc/Kconfig                       |   8 +-
 drivers/iio/adc/hx711.c                       | 351 +++++++++++++++---
 3 files changed, 363 insertions(+), 75 deletions(-)

-- 
2.43.0


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

* [PATCH v10 01/11] dt-bindings: iio: adc: hx711: clean up existing binding text
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 10:51 ` [PATCH v10 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property Piyush Patle
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

Rewrite the binding description and property text so it describes the
existing HX711 hardware behavior directly instead of documenting old
driver implementation details.

Also clarify that clock-frequency controls the SCK bit-bang timing.

No functional change.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
---
 .../bindings/iio/adc/avia-hx711.yaml          | 25 ++++++++-----------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
index 9c57eb13f892..1ea60dff98d5 100644
--- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
@@ -10,14 +10,9 @@ maintainers:
   - Andreas Klinger <ak@it-klinger.de>
 
 description: |
-  Bit-banging driver using two GPIOs:
-  - sck-gpio gives a clock to the sensor with 24 cycles for data retrieval
-    and up to 3 cycles for selection of the input channel and gain for the
-    next measurement
-  - dout-gpio is the sensor data the sensor responds to the clock
-
-  Specifications about the driver can be found at:
-  http://www.aviaic.com/ENProducts.aspx
+  The HX711 is a 24-bit ADC with selectable gain (32/64/128) and two
+  differential input channels. Channel A supports gain 64 and 128;
+  channel B supports gain 32.
 
 properties:
   compatible:
@@ -26,23 +21,23 @@ properties:
 
   sck-gpios:
     description:
-      Definition of the GPIO for the clock (output). In the datasheet it is
-      named PD_SCK
+      GPIO for the clock output (PD_SCK in the datasheet).
     maxItems: 1
 
   dout-gpios:
     description:
-      Definition of the GPIO for the data-out sent by the sensor in
-      response to the clock (input).
-      See Documentation/devicetree/bindings/gpio/gpio.txt for information
-      on how to specify a consumer gpio.
+      GPIO for the data output from the sensor (DOUT in the datasheet).
     maxItems: 1
 
   avdd-supply:
     description:
-      Definition of the regulator used as analog supply
+      Analog supply voltage (AVDD).
 
   clock-frequency:
+    description:
+      Controls the SCK bit-bang timing. The value is used to derive the
+      delay between SCK edges; keep the SCK high time below 60 us to
+      avoid triggering chip power-down mode.
     minimum: 20000
     maximum: 2500000
     default: 400000
-- 
2.43.0


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

* [PATCH v10 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
  2026-05-25 10:51 ` [PATCH v10 01/11] dt-bindings: iio: adc: hx711: clean up existing binding text Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 10:58   ` sashiko-bot
  2026-05-27 17:34   ` Jonathan Cameron
  2026-05-25 10:51 ` [PATCH v10 03/11] dt-bindings: iio: adc: hx711: add RATE GPIO property Piyush Patle
                   ` (10 subsequent siblings)
  12 siblings, 2 replies; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

Document the optional VSUP supply used by the HX711 on-chip regulator.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
---
 .../devicetree/bindings/iio/adc/avia-hx711.yaml     | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
index 1ea60dff98d5..0baf620e9057 100644
--- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
@@ -33,6 +33,19 @@ properties:
     description:
       Analog supply voltage (AVDD).
 
+  vsup-supply:
+    description:
+      Supply voltage for the on-chip regulator (VSUP).
+
+  dvdd-supply:
+    description:
+      Digital supply voltage (DVDD). On the HX711, DVDD is a
+      board-supplied digital rail; it was missing from the original
+      binding. On the HX710B, DVDD must be greater than or equal to
+      AVDD; when DVDD is a battery rail and AVDD is a regulated supply,
+      one channel monitors the DVDD-AVDD difference for battery level
+      detection.
+
   clock-frequency:
     description:
       Controls the SCK bit-bang timing. The value is used to derive the
-- 
2.43.0


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

* [PATCH v10 03/11] dt-bindings: iio: adc: hx711: add RATE GPIO property
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
  2026-05-25 10:51 ` [PATCH v10 01/11] dt-bindings: iio: adc: hx711: clean up existing binding text Piyush Patle
  2026-05-25 10:51 ` [PATCH v10 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 10:51 ` [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support Piyush Patle
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

Document the optional RATE pin GPIO used to select the HX711 output
data rate.

Update the example to show the property in use.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
---
 Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
index 0baf620e9057..099235b5fd54 100644
--- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
@@ -46,6 +46,13 @@ properties:
       one channel monitors the DVDD-AVDD difference for battery level
       detection.
 
+  rate-gpios:
+    description:
+      GPIO connected to the RATE pin. When driven low the output data
+      rate is 10 SPS; when driven high it is 80 SPS. If omitted the
+      RATE pin state is determined by the board wiring.
+    maxItems: 1
+
   clock-frequency:
     description:
       Controls the SCK bit-bang timing. The value is used to derive the
@@ -70,6 +77,7 @@ examples:
         compatible = "avia,hx711";
         sck-gpios = <&gpio3 10 GPIO_ACTIVE_HIGH>;
         dout-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+        rate-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
         avdd-supply = <&avdd>;
         clock-frequency = <100000>;
     };
-- 
2.43.0


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

* [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
                   ` (2 preceding siblings ...)
  2026-05-25 10:51 ` [PATCH v10 03/11] dt-bindings: iio: adc: hx711: add RATE GPIO property Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 11:11   ` sashiko-bot
  2026-05-27 17:37   ` Jonathan Cameron
  2026-05-25 10:51 ` [PATCH v10 05/11] iio: adc: hx711: move scale computation to per-device storage Piyush Patle
                   ` (8 subsequent siblings)
  12 siblings, 2 replies; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

Add the avia,hx710b compatible and document the HX710B-specific
DVDD and VREF supplies.

Add constraints that forbid HX711-only properties on HX710B nodes and
require vref-supply for HX710B, then add a separate HX710B example.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
---
 .../bindings/iio/adc/avia-hx711.yaml          | 35 ++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
index 099235b5fd54..f0aeb15e9eb9 100644
--- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/iio/adc/avia-hx711.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: AVIA HX711 ADC chip for weight cells
+title: AVIA HX711 and HX710B ADCs
 
 maintainers:
   - Andreas Klinger <ak@it-klinger.de>
@@ -14,9 +14,14 @@ description: |
   differential input channels. Channel A supports gain 64 and 128;
   channel B supports gain 32.
 
+  The HX710B is a 24-bit ADC with fixed gain of 128. One input measures
+  the differential voltage between the two input pins; a second measures
+  the DVDD-AVDD supply voltage difference for battery level detection.
+
 properties:
   compatible:
     enum:
+      - avia,hx710b
       - avia,hx711
 
   sck-gpios:
@@ -53,6 +58,10 @@ properties:
       RATE pin state is determined by the board wiring.
     maxItems: 1
 
+  vref-supply:
+    description:
+      Reference voltage input (VREF).
+
   clock-frequency:
     description:
       Controls the SCK bit-bang timing. The value is used to derive the
@@ -62,6 +71,21 @@ properties:
     maximum: 2500000
     default: 400000
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          const: avia,hx710b
+    then:
+      properties:
+        vsup-supply: false
+        rate-gpios: false
+      required:
+        - vref-supply
+    else:
+      properties:
+        vref-supply: false
+
 required:
   - compatible
   - sck-gpios
@@ -81,3 +105,12 @@ examples:
         avdd-supply = <&avdd>;
         clock-frequency = <100000>;
     };
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    weight {
+        compatible = "avia,hx710b";
+        sck-gpios = <&gpio3 10 GPIO_ACTIVE_HIGH>;
+        dout-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+        avdd-supply = <&avdd>;
+        vref-supply = <&vref>;
+    };
-- 
2.43.0


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

* [PATCH v10 05/11] iio: adc: hx711: move scale computation to per-device storage
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
                   ` (3 preceding siblings ...)
  2026-05-25 10:51 ` [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 10:51 ` [PATCH v10 06/11] iio: adc: hx711: introduce hx711_chip_info structure Piyush Patle
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

The gain-to-scale table is global today, so probe-time scale updates for
one device overwrite the values used by any earlier device instance.

Fix this by making the gain table const and storing the computed scale
values per device in hx711_data.

No functional change for single-sensor configurations.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
---
 drivers/iio/adc/hx711.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index 1db8b68a8f64..86d2a70dd3de 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -28,22 +28,20 @@
 struct hx711_gain_to_scale {
 	int			gain;
 	int			gain_pulse;
-	int			scale;
 	int			channel;
 };
 
 /*
  * .scale depends on AVDD which in turn is known as soon as the regulator
- * is available
- * therefore we set .scale in hx711_probe()
+ * is available; it is stored per device in hx711_data.gain_scale[]
  *
  * channel A in documentation is channel 0 in source code
  * channel B in documentation is channel 1 in source code
  */
-static struct hx711_gain_to_scale hx711_gain_to_scale[HX711_GAIN_MAX] = {
-	{ 128, 1, 0, 0 },
-	{  32, 2, 0, 1 },
-	{  64, 3, 0, 0 }
+static const struct hx711_gain_to_scale hx711_gain_to_scale[HX711_GAIN_MAX] = {
+	{ 128, 1, 0 },
+	{  32, 2, 1 },
+	{  64, 3, 0 },
 };
 
 static int hx711_get_gain_to_pulse(int gain)
@@ -56,22 +54,22 @@ static int hx711_get_gain_to_pulse(int gain)
 	return 1;
 }
 
-static int hx711_get_gain_to_scale(int gain)
+static int hx711_get_gain_to_scale(const int *gain_scale, int gain)
 {
 	int i;
 
 	for (i = 0; i < HX711_GAIN_MAX; i++)
 		if (hx711_gain_to_scale[i].gain == gain)
-			return hx711_gain_to_scale[i].scale;
+			return gain_scale[i];
 	return 0;
 }
 
-static int hx711_get_scale_to_gain(int scale)
+static int hx711_get_scale_to_gain(const int *gain_scale, int scale)
 {
 	int i;
 
 	for (i = 0; i < HX711_GAIN_MAX; i++)
-		if (hx711_gain_to_scale[i].scale == scale)
+		if (gain_scale[i] == scale)
 			return hx711_gain_to_scale[i].gain;
 	return -EINVAL;
 }
@@ -82,6 +80,7 @@ struct hx711_data {
 	struct gpio_desc	*gpiod_dout;
 	int			gain_set;	/* gain set on device */
 	int			gain_chan_a;	/* gain for channel A */
+	int			gain_scale[HX711_GAIN_MAX];
 	struct mutex		lock;
 	/*
 	 * triggered buffer
@@ -290,7 +289,8 @@ static int hx711_read_raw(struct iio_dev *indio_dev,
 		*val = 0;
 		mutex_lock(&hx711_data->lock);
 
-		*val2 = hx711_get_gain_to_scale(hx711_data->gain_set);
+		*val2 = hx711_get_gain_to_scale(hx711_data->gain_scale,
+						hx711_data->gain_set);
 
 		mutex_unlock(&hx711_data->lock);
 
@@ -321,7 +321,7 @@ static int hx711_write_raw(struct iio_dev *indio_dev,
 
 		mutex_lock(&hx711_data->lock);
 
-		gain = hx711_get_scale_to_gain(val2);
+		gain = hx711_get_scale_to_gain(hx711_data->gain_scale, val2);
 		if (gain < 0) {
 			mutex_unlock(&hx711_data->lock);
 			return gain;
@@ -386,6 +386,7 @@ static ssize_t hx711_scale_available_show(struct device *dev,
 				struct device_attribute *attr,
 				char *buf)
 {
+	struct hx711_data *hx711_data = iio_priv(dev_to_iio_dev(dev));
 	struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr);
 	int channel = iio_attr->address;
 	int i, len = 0;
@@ -393,7 +394,7 @@ static ssize_t hx711_scale_available_show(struct device *dev,
 	for (i = 0; i < HX711_GAIN_MAX; i++)
 		if (hx711_gain_to_scale[i].channel == channel)
 			len += sprintf(buf + len, "0.%09d ",
-					hx711_gain_to_scale[i].scale);
+				       hx711_data->gain_scale[i]);
 
 	len += sprintf(buf + len, "\n");
 
@@ -511,7 +512,7 @@ static int hx711_probe(struct platform_device *pdev)
 	ret *= 100;
 
 	for (i = 0; i < HX711_GAIN_MAX; i++)
-		hx711_gain_to_scale[i].scale =
+		hx711_data->gain_scale[i] =
 			ret / hx711_gain_to_scale[i].gain / 1678;
 
 	hx711_data->gain_set = 128;
-- 
2.43.0


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

* [PATCH v10 06/11] iio: adc: hx711: introduce hx711_chip_info structure
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
                   ` (4 preceding siblings ...)
  2026-05-25 10:51 ` [PATCH v10 05/11] iio: adc: hx711: move scale computation to per-device storage Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 11:34   ` sashiko-bot
  2026-05-25 10:51 ` [PATCH v10 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read Piyush Patle
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

Add a per-variant static configuration structure and populate the IIO
device fields from it at probe time.

This is a preparatory change for adding support for more HX711-compatible
hardware variants without duplicating the probe-time setup.

No functional change for existing HX711 users.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
---
 drivers/iio/adc/hx711.c | 41 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index 86d2a70dd3de..10ccc69f209b 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -4,6 +4,8 @@
  *
  * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
  */
+#include <linux/array_size.h>
+#include <linux/dev_printk.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -74,6 +76,20 @@ static int hx711_get_scale_to_gain(const int *gain_scale, int scale)
 	return -EINVAL;
 }
 
+/**
+ * struct hx711_chip_info - per-variant static configuration
+ * @name: IIO device name
+ * @channels: channel specification array
+ * @num_channels: number of entries in @channels
+ * @iio_info: IIO info ops for this variant
+ */
+struct hx711_chip_info {
+	const char			*name;
+	const struct iio_chan_spec	*channels __counted_by_ptr(num_channels);
+	unsigned int			num_channels;
+	const struct iio_info		*iio_info;
+};
+
 struct hx711_data {
 	struct device		*dev;
 	struct gpio_desc	*gpiod_pd_sck;
@@ -81,6 +97,7 @@ struct hx711_data {
 	int			gain_set;	/* gain set on device */
 	int			gain_chan_a;	/* gain for channel A */
 	int			gain_scale[HX711_GAIN_MAX];
+	const struct hx711_chip_info	*chip_info;
 	struct mutex		lock;
 	/*
 	 * triggered buffer
@@ -456,8 +473,16 @@ static const struct iio_chan_spec hx711_chan_spec[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(2),
 };
 
+static const struct hx711_chip_info hx711_chip = {
+	.name		= "hx711",
+	.channels	= hx711_chan_spec,
+	.iio_info	= &hx711_iio_info,
+	.num_channels	= ARRAY_SIZE(hx711_chan_spec),
+};
+
 static int hx711_probe(struct platform_device *pdev)
 {
+	const struct hx711_chip_info *chip_info;
 	struct device *dev = &pdev->dev;
 	struct hx711_data *hx711_data;
 	struct iio_dev *indio_dev;
@@ -473,6 +498,12 @@ static int hx711_probe(struct platform_device *pdev)
 
 	mutex_init(&hx711_data->lock);
 
+	chip_info = device_get_match_data(dev);
+	if (!chip_info)
+		return dev_err_probe(dev, -ENODEV, "missing driver data\n");
+
+	hx711_data->chip_info = chip_info;
+
 	/*
 	 * PD_SCK stands for power down and serial clock input of HX711
 	 * in the driver it is an output
@@ -534,11 +565,11 @@ static int hx711_probe(struct platform_device *pdev)
 	hx711_data->data_ready_delay_ns =
 				1000000000 / hx711_data->clock_frequency;
 
-	indio_dev->name = "hx711";
-	indio_dev->info = &hx711_iio_info;
+	indio_dev->name = chip_info->name;
+	indio_dev->info = chip_info->iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
-	indio_dev->channels = hx711_chan_spec;
-	indio_dev->num_channels = ARRAY_SIZE(hx711_chan_spec);
+	indio_dev->channels = chip_info->channels;
+	indio_dev->num_channels = chip_info->num_channels;
 
 	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
 					      iio_pollfunc_store_time,
@@ -555,7 +586,7 @@ static int hx711_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id of_hx711_match[] = {
-	{ .compatible = "avia,hx711", },
+	{ .compatible = "avia,hx711", .data = &hx711_chip },
 	{ }
 };
 
-- 
2.43.0


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

* [PATCH v10 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
                   ` (5 preceding siblings ...)
  2026-05-25 10:51 ` [PATCH v10 06/11] iio: adc: hx711: introduce hx711_chip_info structure Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 11:10   ` sashiko-bot
  2026-05-25 10:51 ` [PATCH v10 08/11] iio: adc: hx711: split variable assignments in hx711_read and hx711_reset Piyush Patle
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

Move the trailing-pulse selection out of hx711_read() and into its
callers.

This is a preparatory change so later variant-specific code can pass the
per-channel pulse count without adding a separate read path.

No functional change.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
---
 drivers/iio/adc/hx711.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index 10ccc69f209b..30e1ce321747 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -155,7 +155,7 @@ static int hx711_cycle(struct hx711_data *hx711_data)
 	return gpiod_get_value(hx711_data->gpiod_dout);
 }
 
-static int hx711_read(struct hx711_data *hx711_data)
+static int hx711_read(struct hx711_data *hx711_data, int trailing_pulses)
 {
 	int i, ret;
 	int value = 0;
@@ -174,7 +174,7 @@ static int hx711_read(struct hx711_data *hx711_data)
 
 	value ^= 0x800000;
 
-	for (i = 0; i < hx711_get_gain_to_pulse(hx711_data->gain_set); i++)
+	for (i = 0; i < trailing_pulses; i++)
 		hx711_cycle(hx711_data);
 
 	return value;
@@ -237,7 +237,8 @@ static int hx711_set_gain_for_channel(struct hx711_data *hx711_data, int chan)
 		if (hx711_data->gain_set == 32) {
 			hx711_data->gain_set = hx711_data->gain_chan_a;
 
-			ret = hx711_read(hx711_data);
+			ret = hx711_read(hx711_data,
+					 hx711_get_gain_to_pulse(hx711_data->gain_set));
 			if (ret < 0)
 				return ret;
 
@@ -249,7 +250,8 @@ static int hx711_set_gain_for_channel(struct hx711_data *hx711_data, int chan)
 		if (hx711_data->gain_set != 32) {
 			hx711_data->gain_set = 32;
 
-			ret = hx711_read(hx711_data);
+			ret = hx711_read(hx711_data,
+					 hx711_get_gain_to_pulse(hx711_data->gain_set));
 			if (ret < 0)
 				return ret;
 
@@ -264,8 +266,8 @@ static int hx711_set_gain_for_channel(struct hx711_data *hx711_data, int chan)
 
 static int hx711_reset_read(struct hx711_data *hx711_data, int chan)
 {
+	int trailing_pulses;
 	int ret;
-	int val;
 
 	/*
 	 * hx711_reset() must be called from here
@@ -280,9 +282,8 @@ static int hx711_reset_read(struct hx711_data *hx711_data, int chan)
 	if (ret < 0)
 		return ret;
 
-	val = hx711_read(hx711_data);
-
-	return val;
+	trailing_pulses = hx711_get_gain_to_pulse(hx711_data->gain_set);
+	return hx711_read(hx711_data, trailing_pulses);
 }
 
 static int hx711_read_raw(struct iio_dev *indio_dev,
@@ -349,7 +350,8 @@ static int hx711_write_raw(struct iio_dev *indio_dev,
 			if (gain != 32)
 				hx711_data->gain_chan_a = gain;
 
-			ret = hx711_read(hx711_data);
+			ret = hx711_read(hx711_data,
+					 hx711_get_gain_to_pulse(hx711_data->gain_set));
 			if (ret < 0) {
 				mutex_unlock(&hx711_data->lock);
 				return ret;
-- 
2.43.0


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

* [PATCH v10 08/11] iio: adc: hx711: split variable assignments in hx711_read and hx711_reset
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
                   ` (6 preceding siblings ...)
  2026-05-25 10:51 ` [PATCH v10 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 10:51 ` [PATCH v10 09/11] iio: adc: hx711: localize loop iterators in hx711_read Piyush Patle
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

Separate the initial value assignments from the declarations in
hx711_read() and hx711_reset().

This is a small preparatory cleanup before the later loop-iterator and
variant-specific changes adjust the local variable layout in these
functions.

No functional change.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
---
 drivers/iio/adc/hx711.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index 30e1ce321747..4ccb0bf2d71f 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -159,9 +159,10 @@ static int hx711_read(struct hx711_data *hx711_data, int trailing_pulses)
 {
 	int i, ret;
 	int value = 0;
-	int val = gpiod_get_value(hx711_data->gpiod_dout);
+	int val;
 
 	/* we double check if it's really down */
+	val = gpiod_get_value(hx711_data->gpiod_dout);
 	if (val)
 		return -EIO;
 
@@ -204,8 +205,9 @@ static int hx711_wait_for_ready(struct hx711_data *hx711_data)
 
 static int hx711_reset(struct hx711_data *hx711_data)
 {
-	int val = hx711_wait_for_ready(hx711_data);
+	int val;
 
+	val = hx711_wait_for_ready(hx711_data);
 	if (val) {
 		/*
 		 * an examination with the oszilloscope indicated
-- 
2.43.0


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

* [PATCH v10 09/11] iio: adc: hx711: localize loop iterators in hx711_read
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
                   ` (7 preceding siblings ...)
  2026-05-25 10:51 ` [PATCH v10 08/11] iio: adc: hx711: split variable assignments in hx711_read and hx711_reset Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 10:51 ` [PATCH v10 10/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read Piyush Patle
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

Tighten the scope of the loop variables in hx711_read() now that
trailing-pulse selection is already handled by the callers.

Also replace the 24-bit loop bound with a named constant while touching
the same code.

Suggested-by: Andy Shevchenko <andy@kernel.org>
Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
---
 drivers/iio/adc/hx711.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index 4ccb0bf2d71f..e5d842853b71 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -23,6 +23,8 @@
 #include <linux/gpio/consumer.h>
 #include <linux/regulator/consumer.h>
 
+#define HX711_DATA_BITS		24
+
 /* gain to pulse and scale conversion */
 #define HX711_GAIN_MAX		3
 #define HX711_RESET_GAIN	128
@@ -157,16 +159,16 @@ static int hx711_cycle(struct hx711_data *hx711_data)
 
 static int hx711_read(struct hx711_data *hx711_data, int trailing_pulses)
 {
-	int i, ret;
 	int value = 0;
 	int val;
+	int ret;
 
 	/* we double check if it's really down */
 	val = gpiod_get_value(hx711_data->gpiod_dout);
 	if (val)
 		return -EIO;
 
-	for (i = 0; i < 24; i++) {
+	for (int i = 0; i < HX711_DATA_BITS; i++) {
 		value <<= 1;
 		ret = hx711_cycle(hx711_data);
 		if (ret)
@@ -175,7 +177,7 @@ static int hx711_read(struct hx711_data *hx711_data, int trailing_pulses)
 
 	value ^= 0x800000;
 
-	for (i = 0; i < trailing_pulses; i++)
+	for (int i = 0; i < trailing_pulses; i++)
 		hx711_cycle(hx711_data);
 
 	return value;
-- 
2.43.0


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

* [PATCH v10 10/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
                   ` (8 preceding siblings ...)
  2026-05-25 10:51 ` [PATCH v10 09/11] iio: adc: hx711: localize loop iterators in hx711_read Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 11:25   ` sashiko-bot
  2026-05-25 10:51 ` [PATCH v10 11/11] iio: adc: hx711: add support for HX710B Piyush Patle
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

Change hx711_reset_read() to accept the channel descriptor directly and
update its callers accordingly.

Split the existing HX711 channel-selection work into a small helper so a
later variant-specific change can add a matching helper without growing
hx711_reset_read() further.

No functional change.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
---
 drivers/iio/adc/hx711.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index e5d842853b71..fde95758b9a0 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -268,7 +268,23 @@ static int hx711_set_gain_for_channel(struct hx711_data *hx711_data, int chan)
 	return 0;
 }
 
-static int hx711_reset_read(struct hx711_data *hx711_data, int chan)
+static int hx711_set_hx711_channel(struct hx711_data *hx711_data,
+				   const struct iio_chan_spec *chan,
+				   int *trailing_pulses)
+{
+	int ret;
+
+	ret = hx711_set_gain_for_channel(hx711_data, chan->channel);
+	if (ret < 0)
+		return ret;
+
+	*trailing_pulses = hx711_get_gain_to_pulse(hx711_data->gain_set);
+
+	return 0;
+}
+
+static int hx711_reset_read(struct hx711_data *hx711_data,
+			    const struct iio_chan_spec *chan)
 {
 	int trailing_pulses;
 	int ret;
@@ -282,11 +298,10 @@ static int hx711_reset_read(struct hx711_data *hx711_data, int chan)
 		return -EIO;
 	}
 
-	ret = hx711_set_gain_for_channel(hx711_data, chan);
+	ret = hx711_set_hx711_channel(hx711_data, chan, &trailing_pulses);
 	if (ret < 0)
 		return ret;
 
-	trailing_pulses = hx711_get_gain_to_pulse(hx711_data->gain_set);
 	return hx711_read(hx711_data, trailing_pulses);
 }
 
@@ -300,7 +315,7 @@ static int hx711_read_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_RAW:
 		mutex_lock(&hx711_data->lock);
 
-		*val = hx711_reset_read(hx711_data, chan->channel);
+		*val = hx711_reset_read(hx711_data, chan);
 
 		mutex_unlock(&hx711_data->lock);
 
@@ -390,8 +405,8 @@ static irqreturn_t hx711_trigger(int irq, void *p)
 	memset(&hx711_data->buffer, 0, sizeof(hx711_data->buffer));
 
 	iio_for_each_active_channel(indio_dev, i) {
-		hx711_data->buffer.channel[j] = hx711_reset_read(hx711_data,
-					indio_dev->channels[i].channel);
+		hx711_data->buffer.channel[j] =
+			hx711_reset_read(hx711_data, &indio_dev->channels[i]);
 		j++;
 	}
 
-- 
2.43.0


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

* [PATCH v10 11/11] iio: adc: hx711: add support for HX710B
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
                   ` (9 preceding siblings ...)
  2026-05-25 10:51 ` [PATCH v10 10/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read Piyush Patle
@ 2026-05-25 10:51 ` Piyush Patle
  2026-05-25 11:33   ` sashiko-bot
  2026-05-27 17:54   ` Jonathan Cameron
  2026-05-27 17:32 ` [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Jonathan Cameron
  2026-05-27 17:45 ` Jonathan Cameron
  12 siblings, 2 replies; 28+ messages in thread
From: Piyush Patle @ 2026-05-25 10:51 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-kernel
  Cc: jic23, ak, robh, krzk+dt, conor+dt, andy, nuno.sa, dlechner

Add support for the AVIA HX710B ADC, which shares the HX711 GPIO
interface but uses trailing PD_SCK pulses to select the active mode.

Model the HX710B with variant-specific channel tables and IIO info,
track the active channel across conversions, and use the fixed gain
value when computing scale.

Also update the adjacent Kconfig text, file header, and module
description so the driver text matches the newly supported variant.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
---
 drivers/iio/adc/Kconfig |   8 +-
 drivers/iio/adc/hx711.c | 230 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 212 insertions(+), 26 deletions(-)

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index a9dedbb8eb46..38ba8cae13f1 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -791,13 +791,15 @@ config HI8435
 	  called hi8435.
 
 config HX711
-	tristate "AVIA HX711 ADC for weight cells"
+	tristate "AVIA HX711 and compatible ADCs"
 	depends on GPIOLIB
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	help
-	  If you say yes here you get support for AVIA HX711 ADC which is used
-	  for weigh cells
+	  If you say Y here you get support for the following AVIA ADCs:
+	    - HX710B
+	    - HX711
+	  which are used for bridge sensors such as weigh cells.
 
 	  This driver uses two GPIOs, one acts as the clock and controls the
 	  channel selection and gain, the other one is used for the measurement
diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index fde95758b9a0..32a35f644834 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
- * HX711: analog to digital converter for weight sensor module
+ * HX711 and compatible ADCs driver for weigh sensor modules
  *
  * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
  */
@@ -15,6 +15,8 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/types.h>
+
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/buffer.h>
@@ -84,12 +86,16 @@ static int hx711_get_scale_to_gain(const int *gain_scale, int scale)
  * @channels: channel specification array
  * @num_channels: number of entries in @channels
  * @iio_info: IIO info ops for this variant
+ * @fixed_gain_val: fixed PGA gain (used when @has_fixed_gain is true)
+ * @has_fixed_gain: true if the variant has a fixed ADC gain
  */
 struct hx711_chip_info {
 	const char			*name;
 	const struct iio_chan_spec	*channels __counted_by_ptr(num_channels);
 	unsigned int			num_channels;
 	const struct iio_info		*iio_info;
+	unsigned int			fixed_gain_val;
+	bool				has_fixed_gain;
 };
 
 struct hx711_data {
@@ -99,6 +105,8 @@ struct hx711_data {
 	int			gain_set;	/* gain set on device */
 	int			gain_chan_a;	/* gain for channel A */
 	int			gain_scale[HX711_GAIN_MAX];
+	int			channel_set;	/* HX710B active channel */
+	unsigned int		samp_freq;	/* HX710B differential channel sample rate */
 	const struct hx711_chip_info	*chip_info;
 	struct mutex		lock;
 	/*
@@ -207,6 +215,7 @@ static int hx711_wait_for_ready(struct hx711_data *hx711_data)
 
 static int hx711_reset(struct hx711_data *hx711_data)
 {
+	const struct hx711_chip_info *info = hx711_data->chip_info;
 	int val;
 
 	val = hx711_wait_for_ready(hx711_data);
@@ -226,8 +235,11 @@ static int hx711_reset(struct hx711_data *hx711_data)
 
 		val = hx711_wait_for_ready(hx711_data);
 
-		/* after a reset the gain is 128 */
-		hx711_data->gain_set = HX711_RESET_GAIN;
+		if (info->has_fixed_gain)
+			hx711_data->channel_set = 0;
+		else
+			/* after a reset the gain is 128 */
+			hx711_data->gain_set = HX711_RESET_GAIN;
 	}
 
 	return val;
@@ -283,9 +295,51 @@ static int hx711_set_hx711_channel(struct hx711_data *hx711_data,
 	return 0;
 }
 
+/*
+ * Return the trailing pulse count for an HX710B channel (Table 3 in
+ * the datasheet).  The supply-monitor channel always uses 2 trailing
+ * pulses; the differential channel uses 1 (10 SPS) or 3 (40 SPS).
+ */
+static int hx710b_trailing_pulses(const struct hx711_data *hx711_data,
+				  const struct iio_chan_spec *chan)
+{
+	if (!chan->differential)
+		return 2;
+	return hx711_data->samp_freq == 10 ? 1 : 3;
+}
+
+/*
+ * Switch the HX710B to the requested channel for the next conversion.
+ * channel_set tracks the trailing pulse count that was last sent to the
+ * chip; it is updated immediately after hx711_read() commits the new
+ * mode in hardware, before waiting for the chip to be ready again.
+ */
+static int hx711_set_hx710b_channel(struct hx711_data *hx711_data,
+				    const struct iio_chan_spec *chan)
+{
+	int trailing_pulses = hx710b_trailing_pulses(hx711_data, chan);
+	int ret;
+
+	if (hx711_data->channel_set == trailing_pulses)
+		return 0;
+
+	ret = hx711_read(hx711_data, trailing_pulses);
+	if (ret < 0)
+		return ret;
+
+	hx711_data->channel_set = trailing_pulses;
+
+	ret = hx711_wait_for_ready(hx711_data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int hx711_reset_read(struct hx711_data *hx711_data,
 			    const struct iio_chan_spec *chan)
 {
+	const struct hx711_chip_info *info = hx711_data->chip_info;
 	int trailing_pulses;
 	int ret;
 
@@ -298,9 +352,16 @@ static int hx711_reset_read(struct hx711_data *hx711_data,
 		return -EIO;
 	}
 
-	ret = hx711_set_hx711_channel(hx711_data, chan, &trailing_pulses);
-	if (ret < 0)
-		return ret;
+	if (info->has_fixed_gain) {
+		ret = hx711_set_hx710b_channel(hx711_data, chan);
+		if (ret < 0)
+			return ret;
+		trailing_pulses = hx710b_trailing_pulses(hx711_data, chan);
+	} else {
+		ret = hx711_set_hx711_channel(hx711_data, chan, &trailing_pulses);
+		if (ret < 0)
+			return ret;
+	}
 
 	return hx711_read(hx711_data, trailing_pulses);
 }
@@ -322,6 +383,9 @@ static int hx711_read_raw(struct iio_dev *indio_dev,
 		if (*val < 0)
 			return *val;
 		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = hx711_data->samp_freq;
+		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
 		*val = 0;
 		mutex_lock(&hx711_data->lock);
@@ -399,20 +463,26 @@ static irqreturn_t hx711_trigger(int irq, void *p)
 	struct iio_dev *indio_dev = pf->indio_dev;
 	struct hx711_data *hx711_data = iio_priv(indio_dev);
 	int i, j = 0;
+	int ret;
 
 	mutex_lock(&hx711_data->lock);
 
 	memset(&hx711_data->buffer, 0, sizeof(hx711_data->buffer));
 
 	iio_for_each_active_channel(indio_dev, i) {
-		hx711_data->buffer.channel[j] =
-			hx711_reset_read(hx711_data, &indio_dev->channels[i]);
-		j++;
+		ret = hx711_reset_read(hx711_data, &indio_dev->channels[i]);
+		if (ret < 0) {
+			dev_err_ratelimited(hx711_data->dev,
+					    "read failed: %d\n", ret);
+			goto out_unlock;
+		}
+		hx711_data->buffer.channel[j++] = ret;
 	}
 
 	iio_push_to_buffers_with_timestamp(indio_dev, &hx711_data->buffer,
-							pf->timestamp);
+					   pf->timestamp);
 
+out_unlock:
 	mutex_unlock(&hx711_data->lock);
 
 	iio_trigger_notify_done(indio_dev->trig);
@@ -462,6 +532,54 @@ static const struct iio_info hx711_iio_info = {
 	.attrs			= &hx711_attribute_group,
 };
 
+static const int hx710b_samp_freq_avail[] = { 10, 40 };
+
+static int hx710b_read_avail(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     const int **vals, int *type, int *length,
+			     long mask)
+{
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*vals = hx710b_samp_freq_avail;
+		*type = IIO_VAL_INT;
+		*length = ARRAY_SIZE(hx710b_samp_freq_avail);
+		return IIO_AVAIL_LIST;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int hx710b_write_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int val, int val2, long mask)
+{
+	struct hx711_data *hx711_data = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		if (val != 10 && val != 40)
+			return -EINVAL;
+		ret = iio_device_claim_direct_mode(indio_dev);
+		if (ret)
+			return ret;
+		mutex_lock(&hx711_data->lock);
+		hx711_data->samp_freq = val;
+		mutex_unlock(&hx711_data->lock);
+		iio_device_release_direct_mode(indio_dev);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct iio_info hx710b_iio_info = {
+	.read_raw		= hx711_read_raw,
+	.write_raw		= hx710b_write_raw,
+	.read_avail		= hx710b_read_avail,
+};
+
 static const struct iio_chan_spec hx711_chan_spec[] = {
 	{
 		.type = IIO_VOLTAGE,
@@ -494,6 +612,51 @@ static const struct iio_chan_spec hx711_chan_spec[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(2),
 };
 
+/*
+ * HX710B channels (Table 3 in datasheet).
+ * 25 pulses (1 trailing): differential input, 10 SPS
+ * 26 pulses (2 trailing): DVDD-AVDD supply monitor, 40 SPS
+ * 27 pulses (3 trailing): differential input, 40 SPS
+ * Channel 0 exposes both differential rates via IIO_CHAN_INFO_SAMP_FREQ.
+ * Channel 2 is used for the supply monitor to avoid aliasing the
+ * channel2 terminal of the differential pair.
+ */
+static const struct iio_chan_spec hx710b_chan_spec[] = {
+	{
+		.type = IIO_VOLTAGE,
+		.differential = 1,
+		.channel = 0,
+		.channel2 = 1,
+		.indexed = 1,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				      BIT(IIO_CHAN_INFO_SCALE) |
+				      BIT(IIO_CHAN_INFO_SAMP_FREQ),
+		.info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+		.scan_index = 0,
+		.scan_type = {
+			.sign = 'u',
+			.realbits = 24,
+			.storagebits = 32,
+			.endianness = IIO_CPU,
+		},
+	},
+	{
+		.type = IIO_VOLTAGE,
+		.channel = 2,
+		.indexed = 1,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				      BIT(IIO_CHAN_INFO_SCALE),
+		.scan_index = 1,
+		.scan_type = {
+			.sign = 'u',
+			.realbits = 24,
+			.storagebits = 32,
+			.endianness = IIO_CPU,
+		},
+	},
+	IIO_CHAN_SOFT_TIMESTAMP(2),
+};
+
 static const struct hx711_chip_info hx711_chip = {
 	.name		= "hx711",
 	.channels	= hx711_chan_spec,
@@ -501,6 +664,15 @@ static const struct hx711_chip_info hx711_chip = {
 	.num_channels	= ARRAY_SIZE(hx711_chan_spec),
 };
 
+static const struct hx711_chip_info hx710b_chip = {
+	.name		= "hx710b",
+	.channels	= hx710b_chan_spec,
+	.iio_info	= &hx710b_iio_info,
+	.num_channels	= ARRAY_SIZE(hx710b_chan_spec),
+	.fixed_gain_val	= 128,
+	.has_fixed_gain	= true,
+};
+
 static int hx711_probe(struct platform_device *pdev)
 {
 	const struct hx711_chip_info *chip_info;
@@ -543,32 +715,43 @@ static int hx711_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(hx711_data->gpiod_dout),
 				     "failed to get dout-gpiod\n");
 
-	ret = devm_regulator_get_enable_read_voltage(dev, "avdd");
+	if (chip_info->has_fixed_gain)
+		ret = devm_regulator_get_enable_read_voltage(dev, "vref");
+	else
+		ret = devm_regulator_get_enable_read_voltage(dev, "avdd");
 	if (ret < 0)
 		return ret;
 
 	/*
-	 * with
-	 * full scale differential input range: AVDD / GAIN
+	 * With
+	 * full scale differential input range: reference / GAIN
 	 * full scale output data: 2^24
 	 * we can say:
-	 *     AVDD / GAIN = 2^24
+	 *     reference / GAIN = 2^24
 	 * therefore:
-	 *     1 LSB = AVDD / GAIN / 2^24
-	 * AVDD is in uV, but we need 10^-9 mV
+	 *     1 LSB = reference / GAIN / 2^24
+	 * reference is in uV, but we need 10^-9 mV
 	 * approximately to fit into a 32 bit number:
-	 * 1 LSB = (AVDD * 100) / GAIN / 1678 [10^-9 mV]
+	 * 1 LSB = (reference * 100) / GAIN / 1678 [10^-9 mV]
 	 */
 
 	/* we need 10^-9 mV */
 	ret *= 100;
 
-	for (i = 0; i < HX711_GAIN_MAX; i++)
-		hx711_data->gain_scale[i] =
-			ret / hx711_gain_to_scale[i].gain / 1678;
+	if (chip_info->has_fixed_gain) {
+		for (i = 0; i < HX711_GAIN_MAX; i++)
+			hx711_data->gain_scale[i] =
+				ret / chip_info->fixed_gain_val / 1678;
+		hx711_data->gain_set = chip_info->fixed_gain_val;
+		hx711_data->samp_freq = 10;
+	} else {
+		for (i = 0; i < HX711_GAIN_MAX; i++)
+			hx711_data->gain_scale[i] =
+				ret / hx711_gain_to_scale[i].gain / 1678;
 
-	hx711_data->gain_set = 128;
-	hx711_data->gain_chan_a = 128;
+		hx711_data->gain_set = 128;
+		hx711_data->gain_chan_a = 128;
+	}
 
 	hx711_data->clock_frequency = 400000;
 	ret = device_property_read_u32(&pdev->dev, "clock-frequency",
@@ -607,6 +790,7 @@ static int hx711_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id of_hx711_match[] = {
+	{ .compatible = "avia,hx710b", .data = &hx710b_chip },
 	{ .compatible = "avia,hx711", .data = &hx711_chip },
 	{ }
 };
@@ -624,7 +808,7 @@ static struct platform_driver hx711_driver = {
 module_platform_driver(hx711_driver);
 
 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
-MODULE_DESCRIPTION("HX711 bitbanging driver - ADC for weight cells");
+MODULE_DESCRIPTION("HX711 and similar bitbanging ADC driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:hx711-gpio");
 
-- 
2.43.0


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

* Re: [PATCH v10 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property
  2026-05-25 10:51 ` [PATCH v10 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property Piyush Patle
@ 2026-05-25 10:58   ` sashiko-bot
  2026-05-27 17:34   ` Jonathan Cameron
  1 sibling, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-05-25 10:58 UTC (permalink / raw)
  To: Piyush Patle; +Cc: conor+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The commit message only mentions adding the `vsup-supply` property, but the patch also introduces the `dvdd-supply` property.
--

commit 08268b52281271722eaa018a9daabd0f4d0e5e0e
Author: Piyush Patle <piyushpatle228@gmail.com>

dt-bindings: iio: adc: hx711: add VSUP supply property

This commit updates the avia-hx711 binding to document the optional
vsup-supply property used by the on-chip regulator.

> diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> index 1ea60dff98d59..0baf620e90572 100644
> --- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> +++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
[ ... ]
> @@ -33,6 +33,19 @@ properties:
>      description:
>        Analog supply voltage (AVDD).
>  
> +  vsup-supply:
> +    description:
> +      Supply voltage for the on-chip regulator (VSUP).
> +
> +  dvdd-supply:
> +    description:
> +      Digital supply voltage (DVDD). On the HX711, DVDD is a
> +      board-supplied digital rail; it was missing from the original
> +      binding. On the HX710B, DVDD must be greater than or equal to
> +      AVDD; when DVDD is a battery rail and AVDD is a regulated supply,
> +      one channel monitors the DVDD-AVDD difference for battery level
> +      detection.

[Severity: Medium]
Could the commit message be updated to reflect the full scope of these
changes?

The commit title and message only mention adding the vsup-supply property,
but this code also introduces the dvdd-supply property and references the
hx710b device.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260525105127.180156-1-piyushpatle228@gmail.com?part=2

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

* Re: [PATCH v10 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read
  2026-05-25 10:51 ` [PATCH v10 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read Piyush Patle
@ 2026-05-25 11:10   ` sashiko-bot
  0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-05-25 11:10 UTC (permalink / raw)
  To: Piyush Patle; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] The driver calls `gpiod_set_value()` inside a `local_irq_save()` block in `hx711_cycle()`. If the provided GPIO is on a sleeping bus (like an I2C or SPI expander), this will attempt to sleep with interrupts disabled, leading to a system panic or deadlock.
--

commit 06c110d4ea7407a2f984ef3a29933a8a8f62d351
Author: Piyush Patle <piyushpatle228@gmail.com>
Subject: iio: adc: hx711: pass trailing pulse count into hx711_read

This commit modifies hx711_read() to accept the number of trailing pulses
as a parameter. It moves the selection of trailing pulses from the read
function to its callers, preparing the driver for variant-specific code
without needing a separate read path.

> diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
> index 062d6860da7d6..a18ac3ecf2c59 100644
> --- a/drivers/iio/adc/hx711.c
> +++ b/drivers/iio/adc/hx711.c
> @@ -155,7 +155,7 @@ static int hx711_cycle(struct hx711_data *hx711_data)
>  	return gpiod_get_value(hx711_data->gpiod_dout);
>  }
>  
> -static int hx711_read(struct hx711_data *hx711_data)
> +static int hx711_read(struct hx711_data *hx711_data, int trailing_pulses)
>  {

[ ... ]

> -	for (i = 0; i < hx711_get_gain_to_pulse(hx711_data->gain_set); i++)
> +	for (i = 0; i < trailing_pulses; i++)
>  		hx711_cycle(hx711_data);

[Severity: High]
This is a pre-existing issue, but does this driver ensure the requested
GPIOs are not on a sleeping bus?

Looking at hx711_cycle(), the driver disables interrupts via
local_irq_save() to meet strict timing constraints, and then calls
gpiod_set_value() inside that atomic block:

hx711_cycle()
    local_irq_save(flags);
    gpiod_set_value(hx711_data->gpiod_pd_sck, 1);

If a user wires the HX711 to a GPIO controller on a sleeping bus (like
an I2C or SPI expander), calling gpiod_set_value() will trigger the
underlying controller's set operation, which might attempt to acquire a
mutex or wait for I/O completion.

Could this attempt to sleep inside an atomic context and trigger a
"scheduling while atomic" panic or deadlock?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260525105127.180156-1-piyushpatle228@gmail.com?part=7

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

* Re: [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support
  2026-05-25 10:51 ` [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support Piyush Patle
@ 2026-05-25 11:11   ` sashiko-bot
  2026-05-25 17:01     ` Conor Dooley
  2026-05-27 17:37   ` Jonathan Cameron
  1 sibling, 1 reply; 28+ messages in thread
From: sashiko-bot @ 2026-05-25 11:11 UTC (permalink / raw)
  To: Piyush Patle; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] The `dvdd-supply` property is utilized by the HX710B and mentioned in the commit message, but it is not enforced as a required property for the new compatible or included in the example.
- [Low] The `if` condition for the `avia,hx710b` compatible incorrectly uses `const` instead of `contains: const`, causing schema validation to always fail for HX710B nodes.
--

commit 006ef740da7a1ce47e48ea34371f93f0e9dd9a9a
Author: Piyush Patle <piyushpatle228@gmail.com>

dt-bindings: iio: adc: hx711: add HX710B support
    
Add the avia,hx710b compatible and document the HX710B-specific
DVDD and VREF supplies. Add constraints that forbid HX711-only
properties on HX710B nodes and require vref-supply for HX710B,
then add a separate HX710B example.

>     Add the avia,hx710b compatible and document the HX710B-specific
>     DVDD and VREF supplies.

[Severity: Medium]
The commit message mentions documenting the DVDD supply, and the binding
description notes the HX710B measures the DVDD-AVDD supply voltage difference.
However, dvdd-supply is not enforced as a required property for the new
compatible, nor is it included in the new example node.

Should dvdd-supply be added to the required properties and the example to
ensure complete schema constraints?

[ ... ]

> diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> index 099235b5fd548..f0aeb15e9eb9e 100644
> --- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> +++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
[ ... ]
> @@ -62,6 +71,21 @@ properties:
>      maximum: 2500000
>      default: 400000
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          const: avia,hx710b

[Severity: Low]
Is this the correct way to match the compatible string? Since the compatible
property is evaluated as a string array, using a strict scalar comparison here
evaluates to false, causing the schema to always fall through to the else block.

Would it be better to use contains: const: avia,hx710b instead so that it
properly evaluates the array and enforces the constraints in the then block?

> +    then:
> +      properties:
> +        vsup-supply: false
> +        rate-gpios: false

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260525105127.180156-1-piyushpatle228@gmail.com?part=4

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

* Re: [PATCH v10 10/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read
  2026-05-25 10:51 ` [PATCH v10 10/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read Piyush Patle
@ 2026-05-25 11:25   ` sashiko-bot
  0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-05-25 11:25 UTC (permalink / raw)
  To: Piyush Patle; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing `iio_device_claim_direct_mode()` allows concurrent sysfs reads to disrupt triggered buffer continuous sampling.
- [High] Out-of-bounds Array Write in `hx711_trigger()` when the timestamp channel is enabled.
--

commit b8324538619dcb536bed461da5b5bd5e89ca409b
Author: Piyush Patle <piyushpatle228@gmail.com>

iio: adc: hx711: pass iio_chan_spec to hx711_reset_read

Change hx711_reset_read() to accept the channel descriptor directly and
update its callers accordingly. Split the existing HX711 channel-selection
work into a small helper so a later variant-specific change can add a
matching helper without growing hx711_reset_read() further.

> diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
> --- a/drivers/iio/adc/hx711.c
> +++ b/drivers/iio/adc/hx711.c
[ ... ]
> @@ -300,7 +315,7 @@ static int hx711_read_raw(struct iio_dev *indio_dev,
>  	case IIO_CHAN_INFO_RAW:
>  		mutex_lock(&hx711_data->lock);
>  
> -		*val = hx711_reset_read(hx711_data, chan->channel);
> +		*val = hx711_reset_read(hx711_data, chan);
>  
>  		mutex_unlock(&hx711_data->lock);
>  

[Severity: High]
This is a pre-existing issue, but does this function need to call
iio_device_claim_direct_mode() before accessing the hardware?

If a triggered buffer is active, couldn't a concurrent sysfs read to
in_voltage0_raw take the lock, wait for the device to be ready, and perform
a hardware read?

This might steal a sample from the continuous buffer stream, introduce
massive timing jitter due to gain changes, and disrupt the functional
behavior of the triggered buffer.

[ ... ]
> @@ -390,8 +405,8 @@ static irqreturn_t hx711_trigger(int irq, void *p)
>  	memset(&hx711_data->buffer, 0, sizeof(hx711_data->buffer));
>  
>  	iio_for_each_active_channel(indio_dev, i) {
> -		hx711_data->buffer.channel[j] = hx711_reset_read(hx711_data,
> -					indio_dev->channels[i].channel);
> +		hx711_data->buffer.channel[j] =
> +			hx711_reset_read(hx711_data, &indio_dev->channels[i]);
>  		j++;
>  	}
>  

[Severity: High]
This isn't a bug introduced by this patch, but does this loop correctly
handle the timestamp channel?

Since iio_for_each_active_channel() iterates over all bits set in the
active_scan_mask, wouldn't it include the soft timestamp channel if enabled
by userspace?

If the loop doesn't explicitly skip the timestamp channel, it appears it
would treat it as an ADC channel and call hx711_reset_read() on it, wasting
time on a hardware conversion.

Furthermore, when j reaches 2, writing to channel[j] would be an
out-of-bounds array access on the 2-element array, potentially triggering a
kernel panic when compiled with UBSAN bounds checking.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260525105127.180156-1-piyushpatle228@gmail.com?part=10

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

* Re: [PATCH v10 11/11] iio: adc: hx711: add support for HX710B
  2026-05-25 10:51 ` [PATCH v10 11/11] iio: adc: hx711: add support for HX710B Piyush Patle
@ 2026-05-25 11:33   ` sashiko-bot
  2026-05-27 17:54   ` Jonathan Cameron
  1 sibling, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-05-25 11:33 UTC (permalink / raw)
  To: Piyush Patle; +Cc: devicetree, conor+dt, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing iio_device_claim_direct_mode() in hx711_read_raw and hx711_write_raw allows sysfs access to race with triggered buffer scans, causing data corruption for the HX711 variant.
--

commit b65710cec2d2223666cdb19d42f5604d7de0dec1
Author: Piyush Patle <piyushpatle228@gmail.com>

iio: adc: hx711: add support for HX710B

This commit adds support for the AVIA HX710B ADC, which shares the HX711
GPIO interface but uses trailing PD_SCK pulses to select the active mode.
It models the HX710B with variant-specific channel tables and tracks the
active channel across conversions.

> diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
> index 5c326f01c5543..1dac9cc8b63fe 100644
> --- a/drivers/iio/adc/hx711.c
> +++ b/drivers/iio/adc/hx711.c

[ ... ]

> @@ -322,6 +383,9 @@ static int hx711_read_raw(struct iio_dev *indio_dev,
>  		if (*val < 0)
>  			return *val;
>  		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		*val = hx711_data->samp_freq;
> +		return IIO_VAL_INT;
>  	case IIO_CHAN_INFO_SCALE:
>  		*val = 0;
>  		mutex_lock(&hx711_data->lock);

[Severity: High]
This isn't a bug introduced by this patch, but is it possible for sysfs access
to race with triggered buffer scans here?

It looks like hx711_read_raw() and the corresponding hx711_write_raw() do not
call iio_device_claim_direct_mode(), which allows sysfs reads and writes to
execute concurrently with an active triggered buffer session (serialized only
by the internal lock).

For the HX711 variant, changing the channel or gain consumes a hardware sample
and sets the mode for the next conversion without doing a dummy read and wait.
If a sysfs read or write intercepts the triggered buffer, it alters the
trailing-pulse state machine. When the buffer trigger next executes, it would
receive the data converted under the sysfs operation's mode, potentially
causing data corruption in the sample sequence stream.

The newly added HX710B variant seems to handle channel switching robustly via
dummy reads and waits, but the HX711 variant appears to remain vulnerable to
this stream corruption. Does the original code need an update to use
iio_device_claim_direct_mode() to prevent these races?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260525105127.180156-1-piyushpatle228@gmail.com?part=11

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

* Re: [PATCH v10 06/11] iio: adc: hx711: introduce hx711_chip_info structure
  2026-05-25 10:51 ` [PATCH v10 06/11] iio: adc: hx711: introduce hx711_chip_info structure Piyush Patle
@ 2026-05-25 11:34   ` sashiko-bot
  0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-05-25 11:34 UTC (permalink / raw)
  To: Piyush Patle; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Probing fails unconditionally with `-ENODEV` for devices bound by platform name instead of Device Tree or ACPI.
- [Low] Use of undeclared macro `__counted_by_ptr` causes an immediate compilation error.
--

commit 2560eb8cf3b905048ac157fc1d9dd7c2068b2f2d
Author: Piyush Patle <piyushpatle228@gmail.com>

iio: adc: hx711: introduce hx711_chip_info structure

This patch introduces a per-variant static configuration structure for the 
hx711 driver. It populates IIO device fields from this structure at probe time
to prepare for supporting additional hardware variants.

> diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
> index 823fd74f9cf95..062d6860da7d6 100644
> --- a/drivers/iio/adc/hx711.c
> +++ b/drivers/iio/adc/hx711.c
[ ... ]
> @@ -74,6 +76,20 @@ static int hx711_get_scale_to_gain(const int *gain_scale, int scale)
>  	return -EINVAL;
>  }
>  
> +/**
> + * struct hx711_chip_info - per-variant static configuration
> + * @name: IIO device name
> + * @channels: channel specification array
> + * @num_channels: number of entries in @channels
> + * @iio_info: IIO info ops for this variant
> + */
> +struct hx711_chip_info {
> +	const char			*name;
> +	const struct iio_chan_spec	*channels __counted_by_ptr(num_channels);

[Severity: Low]
Does __counted_by_ptr exist in the kernel headers?

The kernel supports __counted_by for flexible array members, but it looks
like __counted_by_ptr is undefined. Using an undeclared macro here might
cause an immediate compilation error.

> +	unsigned int			num_channels;
> +	const struct iio_info		*iio_info;
> +};
> +
[ ... ]
> @@ -473,6 +498,12 @@ static int hx711_probe(struct platform_device *pdev)
>  
>  	mutex_init(&hx711_data->lock);
>  
> +	chip_info = device_get_match_data(dev);
> +	if (!chip_info)
> +		return dev_err_probe(dev, -ENODEV, "missing driver data\n");

[Severity: Medium]
Will this unconditionally fail for devices bound by platform name instead
of Device Tree or ACPI?

For traditional platform devices instantiated manually,
device_get_match_data() returns NULL because the device lacks a firmware
node and the driver lacks an id_table. platform_match() will fall back to
name matching, but this new probe check will now reject the bind with
-ENODEV.

Would it be better to fall back to the default hx711_chip configuration
or provide an id_table to prevent breaking backward compatibility for
non-DT/ACPI users?

> +
> +	hx711_data->chip_info = chip_info;
> +
>  	/*
>  	 * PD_SCK stands for power down and serial clock input of HX711
>  	 * in the driver it is an output

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260525105127.180156-1-piyushpatle228@gmail.com?part=6

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

* Re: [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support
  2026-05-25 11:11   ` sashiko-bot
@ 2026-05-25 17:01     ` Conor Dooley
  2026-05-27 17:41       ` Jonathan Cameron
  0 siblings, 1 reply; 28+ messages in thread
From: Conor Dooley @ 2026-05-25 17:01 UTC (permalink / raw)
  To: sashiko-reviews, jic23; +Cc: Piyush Patle, robh, conor+dt, devicetree

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

Jonathan,

Here's an example of the sort of stuff it complains about on every
iteration.

On Mon, May 25, 2026 at 11:11:44AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [Medium] The `dvdd-supply` property is utilized by the HX710B and mentioned in the commit message, but it is not enforced as a required property for the new compatible or included in the example.
> - [Low] The `if` condition for the `avia,hx710b` compatible incorrectly uses `const` instead of `contains: const`, causing schema validation to always fail for HX710B nodes.
> --
> 
> commit 006ef740da7a1ce47e48ea34371f93f0e9dd9a9a
> Author: Piyush Patle <piyushpatle228@gmail.com>
> 
> dt-bindings: iio: adc: hx711: add HX710B support
>     
> Add the avia,hx710b compatible and document the HX710B-specific
> DVDD and VREF supplies. Add constraints that forbid HX711-only
> properties on HX710B nodes and require vref-supply for HX710B,
> then add a separate HX710B example.
> 
> >     Add the avia,hx710b compatible and document the HX710B-specific
> >     DVDD and VREF supplies.
> 
> [Severity: Medium]
> The commit message mentions documenting the DVDD supply, and the binding
> description notes the HX710B measures the DVDD-AVDD supply voltage difference.
> However, dvdd-supply is not enforced as a required property for the new
> compatible, nor is it included in the new example node.
> 
> Should dvdd-supply be added to the required properties and the example to
> ensure complete schema constraints?
> 
> [ ... ]
> 
> > diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> > index 099235b5fd548..f0aeb15e9eb9e 100644
> > --- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> > +++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> [ ... ]
> > @@ -62,6 +71,21 @@ properties:
> >      maximum: 2500000
> >      default: 400000
> >  
> > +allOf:
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          const: avia,hx710b
> 
> [Severity: Low]
> Is this the correct way to match the compatible string? Since the compatible
> property is evaluated as a string array, using a strict scalar comparison here
> evaluates to false, causing the schema to always fall through to the else block.
> 
> Would it be better to use contains: const: avia,hx710b instead so that it
> properly evaluates the array and enforces the constraints in the then block?
> 
> > +    then:
> > +      properties:
> > +        vsup-supply: false
> > +        rate-gpios: false
> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260525105127.180156-1-piyushpatle228@gmail.com?part=4

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

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

* Re: [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
                   ` (10 preceding siblings ...)
  2026-05-25 10:51 ` [PATCH v10 11/11] iio: adc: hx711: add support for HX710B Piyush Patle
@ 2026-05-27 17:32 ` Jonathan Cameron
  2026-05-27 17:45 ` Jonathan Cameron
  12 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2026-05-27 17:32 UTC (permalink / raw)
  To: Piyush Patle
  Cc: linux-iio, devicetree, linux-kernel, ak, robh, krzk+dt, conor+dt,
	andy, nuno.sa, dlechner

On Mon, 25 May 2026 16:21:16 +0530
Piyush Patle <piyushpatle228@gmail.com> wrote:

> The HX710B is a 24-bit ADC from AVIA Semiconductor, related to the
> HX711 already supported in this driver.  Unlike the HX711 (which has
> selectable gain and two input channels), the HX710B has a fixed gain
> of 128 and two operating modes selected by the trailing PD_SCK pulse
> count after each conversion:
> 
>   25 pulses (1 trailing): differential input at 10 SPS
>   26 pulses (2 trailing): DVDD-AVDD supply monitor at 40 SPS
>   27 pulses (3 trailing): differential input at 40 SPS
> 
> This series first extends the existing HX711 binding and driver with
> preparatory refactoring, then adds HX710B support on top.
> 
> The differential input is exposed as a single IIO channel with
> IIO_CHAN_INFO_SAMP_FREQ, allowing userspace to select 10 or 40 SPS
> without needing two separate channels for the same physical input.
> The supply monitor is a second channel at fixed 40 SPS.
> 
> Patches 01/11, 02/11, 03/11, and 05/11 have already been applied to
> the iio.git testing branch.  They are re-included here so the series
> applies cleanly as a unit.

Given the version I had of patch 2 was rather different from current
I've rebased my tree to drop it and patch 3.
Thankfully that didn't result in an sha hashes changing for the few
fixes I have queued up.  Hopefully not too painful for anyone
based on my togreg tree. Briefly that will be out of sync with testing
as I have other stuff being tested on there.

> 
> Changes from v9:
>   - 02/11: Added dvdd-supply alongside vsup-supply. Per the v8
>     discussion, DVDD is a board-supplied digital rail on the HX711
>     (figure 1 of the datasheet shows it as a separate input supply,
>     not merely a bypass capacitor point). It was missing from the
>     original binding. Moved its declaration from 04/11 to this earlier
>     shared-supply patch.
>   - 04/11: Removed dvdd-supply declaration (now in 02/11). Updated
>     commit message to reflect the patch now adds only vref-supply and
>     the allOf constraint.
>   - 06/11: No code change. Removed inaccurate below-the-line note
>     about __counted_by_ptr() commit reference.
>   - 08/11: Remove blank line between val = hx711_wait_for_ready() and
>     if (val) check in hx711_reset().
>   - 11/11: Revert IIO_DECLARE_BUFFER_WITH_TS() to explicit named
>     struct (both variants have exactly 2 channels). Add
>     iio_device_claim_direct_mode() in hx710b_write_raw() to prevent
>     concurrent hardware changes during triggered buffer capture; drop
>     channel_set = 0 reset (hx711_set_hx710b_channel() re-programs the
>     chip automatically on the next read). MODULE_DESCRIPTION: change
>     'compatible' to 'similar'.
> 
> Piyush Patle (11):
>   dt-bindings: iio: adc: hx711: clean up existing binding text
>   dt-bindings: iio: adc: hx711: add VSUP supply property
>   dt-bindings: iio: adc: hx711: add RATE GPIO property
>   dt-bindings: iio: adc: hx711: add HX710B support
>   iio: adc: hx711: move scale computation to per-device storage
>   iio: adc: hx711: introduce hx711_chip_info structure
>   iio: adc: hx711: pass trailing pulse count into hx711_read
>   iio: adc: hx711: split variable assignments in hx711_read and
>     hx711_reset
>   iio: adc: hx711: localize loop iterators in hx711_read
>   iio: adc: hx711: pass iio_chan_spec to hx711_reset_read
>   iio: adc: hx711: add support for HX710B
> 
>  .../bindings/iio/adc/avia-hx711.yaml          |  79 +++-
>  drivers/iio/adc/Kconfig                       |   8 +-
>  drivers/iio/adc/hx711.c                       | 351 +++++++++++++++---
>  3 files changed, 363 insertions(+), 75 deletions(-)
> 


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

* Re: [PATCH v10 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property
  2026-05-25 10:51 ` [PATCH v10 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property Piyush Patle
  2026-05-25 10:58   ` sashiko-bot
@ 2026-05-27 17:34   ` Jonathan Cameron
  1 sibling, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2026-05-27 17:34 UTC (permalink / raw)
  To: Piyush Patle
  Cc: linux-iio, devicetree, linux-kernel, ak, robh, krzk+dt, conor+dt,
	andy, nuno.sa, dlechner

On Mon, 25 May 2026 16:21:18 +0530
Piyush Patle <piyushpatle228@gmail.com> wrote:

> Document the optional VSUP supply used by the HX711 on-chip regulator.

Commit message and patch title are out of sync with the patch.
Update them appropriately.
> 
> Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> ---
>  .../devicetree/bindings/iio/adc/avia-hx711.yaml     | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> index 1ea60dff98d5..0baf620e9057 100644
> --- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> +++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> @@ -33,6 +33,19 @@ properties:
>      description:
>        Analog supply voltage (AVDD).
>  
> +  vsup-supply:
> +    description:
> +      Supply voltage for the on-chip regulator (VSUP).
> +
> +  dvdd-supply:
> +    description:
> +      Digital supply voltage (DVDD). On the HX711, DVDD is a
> +      board-supplied digital rail; it was missing from the original
> +      binding. On the HX710B, DVDD must be greater than or equal to
> +      AVDD; when DVDD is a battery rail and AVDD is a regulated supply,
> +      one channel monitors the DVDD-AVDD difference for battery level
> +      detection.
> +
>    clock-frequency:
>      description:
>        Controls the SCK bit-bang timing. The value is used to derive the


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

* Re: [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support
  2026-05-25 10:51 ` [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support Piyush Patle
  2026-05-25 11:11   ` sashiko-bot
@ 2026-05-27 17:37   ` Jonathan Cameron
  1 sibling, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2026-05-27 17:37 UTC (permalink / raw)
  To: Piyush Patle
  Cc: linux-iio, devicetree, linux-kernel, ak, robh, krzk+dt, conor+dt,
	andy, nuno.sa, dlechner

On Mon, 25 May 2026 16:21:20 +0530
Piyush Patle <piyushpatle228@gmail.com> wrote:

> Add the avia,hx710b compatible and document the HX710B-specific
> DVDD and VREF supplies.
Sashiko has called out that the commit message is not in sync
with the current patch content. Rewrite it to not mention dvdd
as hx710b specific.

https://sashiko.dev/#/patchset/20260525105127.180156-1-piyushpatle228%40gmail.com
Also, I think it is correct that for this new device binding at least
dvdd-supply should be required.


I'm not sure about the other bit of feedback on correct way to match
compatible strings. What is here seems to me to work (I hacked the file
to test the constraints were applied).

Conor is that one right or not?

> 
> Add constraints that forbid HX711-only properties on HX710B nodes and
> require vref-supply for HX710B, then add a separate HX710B example.
> 
> Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> ---
>  .../bindings/iio/adc/avia-hx711.yaml          | 35 ++++++++++++++++++-
>  1 file changed, 34 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> index 099235b5fd54..f0aeb15e9eb9 100644
> --- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> +++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> @@ -4,7 +4,7 @@
>  $id: http://devicetree.org/schemas/iio/adc/avia-hx711.yaml#
>  $schema: http://devicetree.org/meta-schemas/core.yaml#
>  
> -title: AVIA HX711 ADC chip for weight cells
> +title: AVIA HX711 and HX710B ADCs
>  
>  maintainers:
>    - Andreas Klinger <ak@it-klinger.de>
> @@ -14,9 +14,14 @@ description: |
>    differential input channels. Channel A supports gain 64 and 128;
>    channel B supports gain 32.
>  
> +  The HX710B is a 24-bit ADC with fixed gain of 128. One input measures
> +  the differential voltage between the two input pins; a second measures
> +  the DVDD-AVDD supply voltage difference for battery level detection.
> +
>  properties:
>    compatible:
>      enum:
> +      - avia,hx710b
>        - avia,hx711
>  
>    sck-gpios:
> @@ -53,6 +58,10 @@ properties:
>        RATE pin state is determined by the board wiring.
>      maxItems: 1
>  
> +  vref-supply:
> +    description:
> +      Reference voltage input (VREF).
> +
>    clock-frequency:
>      description:
>        Controls the SCK bit-bang timing. The value is used to derive the
> @@ -62,6 +71,21 @@ properties:
>      maximum: 2500000
>      default: 400000
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          const: avia,hx710b
> +    then:
> +      properties:
> +        vsup-supply: false
> +        rate-gpios: false
> +      required:
> +        - vref-supply
> +    else:
> +      properties:
> +        vref-supply: false
> +
>  required:
>    - compatible
>    - sck-gpios
> @@ -81,3 +105,12 @@ examples:
>          avdd-supply = <&avdd>;
>          clock-frequency = <100000>;
>      };
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +    weight {
> +        compatible = "avia,hx710b";
> +        sck-gpios = <&gpio3 10 GPIO_ACTIVE_HIGH>;
> +        dout-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
> +        avdd-supply = <&avdd>;
> +        vref-supply = <&vref>;
> +    };


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

* Re: [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support
  2026-05-25 17:01     ` Conor Dooley
@ 2026-05-27 17:41       ` Jonathan Cameron
  2026-05-28  8:54         ` Conor Dooley
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2026-05-27 17:41 UTC (permalink / raw)
  To: Conor Dooley
  Cc: sashiko-reviews, Piyush Patle, robh, conor+dt, devicetree,
	linux-iio

On Mon, 25 May 2026 18:01:41 +0100
Conor Dooley <conor@kernel.org> wrote:

> Jonathan,
> 
> Here's an example of the sort of stuff it complains about on every
> iteration.
> 
Thanks. +cc linux-iio@vger.kernel.org

> On Mon, May 25, 2026 at 11:11:44AM +0000, sashiko-bot@kernel.org wrote:
> > Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> > - [Medium] The `dvdd-supply` property is utilized by the HX710B and mentioned in the commit message, but it is not enforced as a required property for the new compatible or included in the example.
Yup. This stuff needs fixing.

> > - [Low] The `if` condition for the `avia,hx710b` compatible incorrectly uses `const` instead of `contains: const`, causing schema validation to always fail for HX710B nodes.

This one I'm not sure on. Is it right?  I tested by hacking
the example to have a supply it shouldn't and the schema validation failed
as expected making me think this is a false positive.
I have zero natural feel for yaml so no idea :)

+CC linux-iio@vger.kernel.org


> > --
> > 
> > commit 006ef740da7a1ce47e48ea34371f93f0e9dd9a9a
> > Author: Piyush Patle <piyushpatle228@gmail.com>
> > 
> > dt-bindings: iio: adc: hx711: add HX710B support
> >     
> > Add the avia,hx710b compatible and document the HX710B-specific
> > DVDD and VREF supplies. Add constraints that forbid HX711-only
> > properties on HX710B nodes and require vref-supply for HX710B,
> > then add a separate HX710B example.
> >   
> > >     Add the avia,hx710b compatible and document the HX710B-specific
> > >     DVDD and VREF supplies.  
> > 
> > [Severity: Medium]
> > The commit message mentions documenting the DVDD supply, and the binding
> > description notes the HX710B measures the DVDD-AVDD supply voltage difference.
> > However, dvdd-supply is not enforced as a required property for the new
> > compatible, nor is it included in the new example node.
> > 
> > Should dvdd-supply be added to the required properties and the example to
> > ensure complete schema constraints?
> > 
> > [ ... ]
> >   
> > > diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> > > index 099235b5fd548..f0aeb15e9eb9e 100644
> > > --- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> > > +++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml  
> > [ ... ]  
> > > @@ -62,6 +71,21 @@ properties:
> > >      maximum: 2500000
> > >      default: 400000
> > >  
> > > +allOf:
> > > +  - if:
> > > +      properties:
> > > +        compatible:
> > > +          const: avia,hx710b  
> > 
> > [Severity: Low]
> > Is this the correct way to match the compatible string? Since the compatible
> > property is evaluated as a string array, using a strict scalar comparison here
> > evaluates to false, causing the schema to always fall through to the else block.
> > 
> > Would it be better to use contains: const: avia,hx710b instead so that it
> > properly evaluates the array and enforces the constraints in the then block?
> >   
> > > +    then:
> > > +      properties:
> > > +        vsup-supply: false
> > > +        rate-gpios: false  
> > 
> > -- 
> > Sashiko AI review · https://sashiko.dev/#/patchset/20260525105127.180156-1-piyushpatle228@gmail.com?part=4  


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

* Re: [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC
  2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
                   ` (11 preceding siblings ...)
  2026-05-27 17:32 ` [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Jonathan Cameron
@ 2026-05-27 17:45 ` Jonathan Cameron
  12 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2026-05-27 17:45 UTC (permalink / raw)
  To: Piyush Patle
  Cc: linux-iio, devicetree, linux-kernel, ak, robh, krzk+dt, conor+dt,
	andy, nuno.sa, dlechner

On Mon, 25 May 2026 16:21:16 +0530
Piyush Patle <piyushpatle228@gmail.com> wrote:

> The HX710B is a 24-bit ADC from AVIA Semiconductor, related to the
> HX711 already supported in this driver.  Unlike the HX711 (which has
> selectable gain and two input channels), the HX710B has a fixed gain
> of 128 and two operating modes selected by the trailing PD_SCK pulse
> count after each conversion:
> 
>   25 pulses (1 trailing): differential input at 10 SPS
>   26 pulses (2 trailing): DVDD-AVDD supply monitor at 40 SPS
>   27 pulses (3 trailing): differential input at 40 SPS
> 
> This series first extends the existing HX711 binding and driver with
> preparatory refactoring, then adds HX710B support on top.
> 
> The differential input is exposed as a single IIO channel with
> IIO_CHAN_INFO_SAMP_FREQ, allowing userspace to select 10 or 40 SPS
> without needing two separate channels for the same physical input.
> The supply monitor is a second channel at fixed 40 SPS.
> 
> Patches 01/11, 02/11, 03/11, and 05/11 have already been applied to
> the iio.git testing branch.  They are re-included here so the series
> applies cleanly as a unit.

FWIW I took a look at Sashiko's feedback and other than patch descriptions
and the dt-binding dicussion that is ongoing they were either
- wrong, though that sometimes was for subtle reasons - like the fact we
  can't just guess the device if the driver is forced to bind.  We should
  fail in that case.
- pre existing issues.  If you have time to look at those, then great
  but I'm not going to insist on that.

Jonathan

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

* Re: [PATCH v10 11/11] iio: adc: hx711: add support for HX710B
  2026-05-25 10:51 ` [PATCH v10 11/11] iio: adc: hx711: add support for HX710B Piyush Patle
  2026-05-25 11:33   ` sashiko-bot
@ 2026-05-27 17:54   ` Jonathan Cameron
  1 sibling, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2026-05-27 17:54 UTC (permalink / raw)
  To: Piyush Patle
  Cc: linux-iio, devicetree, linux-kernel, ak, robh, krzk+dt, conor+dt,
	andy, nuno.sa, dlechner

On Mon, 25 May 2026 16:21:27 +0530
Piyush Patle <piyushpatle228@gmail.com> wrote:

> Add support for the AVIA HX710B ADC, which shares the HX711 GPIO
> interface but uses trailing PD_SCK pulses to select the active mode.
> 
> Model the HX710B with variant-specific channel tables and IIO info,
> track the active channel across conversions, and use the fixed gain
> value when computing scale.
> 
> Also update the adjacent Kconfig text, file header, and module
> description so the driver text matches the newly supported variant.
> 
> Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Hi

A few small things in here seeing as you are going to be doing a v11 for
the patch description updates on the dt patches.

> ---
>  drivers/iio/adc/Kconfig |   8 +-
>  drivers/iio/adc/hx711.c | 230 ++++++++++++++++++++++++++++++++++++----
>  2 files changed, 212 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index a9dedbb8eb46..38ba8cae13f1 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -791,13 +791,15 @@ config HI8435
>  	  called hi8435.
>  
>  config HX711
> -	tristate "AVIA HX711 ADC for weight cells"
> +	tristate "AVIA HX711 and compatible ADCs"
As below - and similar (not and compatible because they aren't quite).
>  	depends on GPIOLIB
>  	select IIO_BUFFER
>  	select IIO_TRIGGERED_BUFFER
>  	help
> -	  If you say yes here you get support for AVIA HX711 ADC which is used
> -	  for weigh cells
> +	  If you say Y here you get support for the following AVIA ADCs:
> +	    - HX710B
> +	    - HX711
> +	  which are used for bridge sensors such as weigh cells.
>  
>  	  This driver uses two GPIOs, one acts as the clock and controls the
>  	  channel selection and gain, the other one is used for the measurement
> diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
> index fde95758b9a0..32a35f644834 100644
> --- a/drivers/iio/adc/hx711.c
> +++ b/drivers/iio/adc/hx711.c
> @@ -1,6 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0-or-later
>  /*
> - * HX711: analog to digital converter for weight sensor module
> + * HX711 and compatible ADCs driver for weigh sensor modules

Never use 'and compatible' when the driver needs to handle things differently
for each part.  'and similar' is the most common weasel words for this.

> +
> +/*
> + * Switch the HX710B to the requested channel for the next conversion.
> + * channel_set tracks the trailing pulse count that was last sent to the
> + * chip; it is updated immediately after hx711_read() commits the new
> + * mode in hardware, before waiting for the chip to be ready again.
> + */
> +static int hx711_set_hx710b_channel(struct hx711_data *hx711_data,
> +				    const struct iio_chan_spec *chan)
> +{
> +	int trailing_pulses = hx710b_trailing_pulses(hx711_data, chan);
> +	int ret;
> +
> +	if (hx711_data->channel_set == trailing_pulses)
> +		return 0;
> +
> +	ret = hx711_read(hx711_data, trailing_pulses);
> +	if (ret < 0)
> +		return ret;
> +
> +	hx711_data->channel_set = trailing_pulses;
> +
> +	ret = hx711_wait_for_ready(hx711_data);
> +	if (ret)
> +		return ret;
> +
> +	return 0;

	return hx711_wait_for_read(hx711_data);
doesn't obviously hurt readability here and saves us a few lines of code.

> +}
> +
>  static int hx711_reset_read(struct hx711_data *hx711_data,
>  			    const struct iio_chan_spec *chan)
>  {
> +	const struct hx711_chip_info *info = hx711_data->chip_info;
>  	int trailing_pulses;
>  	int ret;
>  
> @@ -298,9 +352,16 @@ static int hx711_reset_read(struct hx711_data *hx711_data,
>  		return -EIO;
>  	}
>  
> -	ret = hx711_set_hx711_channel(hx711_data, chan, &trailing_pulses);
> -	if (ret < 0)
> -		return ret;
> +	if (info->has_fixed_gain) {
> +		ret = hx711_set_hx710b_channel(hx711_data, chan);
> +		if (ret < 0)
> +			return ret;
> +		trailing_pulses = hx710b_trailing_pulses(hx711_data, chan);
> +	} else {
> +		ret = hx711_set_hx711_channel(hx711_data, chan, &trailing_pulses);
> +		if (ret < 0)
> +			return ret;
> +	}
>  
>  	return hx711_read(hx711_data, trailing_pulses);
>  }
> @@ -322,6 +383,9 @@ static int hx711_read_raw(struct iio_dev *indio_dev,
>  		if (*val < 0)
>  			return *val;
>  		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		*val = hx711_data->samp_freq;
> +		return IIO_VAL_INT;
>  	case IIO_CHAN_INFO_SCALE:
>  		*val = 0;
>  		mutex_lock(&hx711_data->lock);
> @@ -399,20 +463,26 @@ static irqreturn_t hx711_trigger(int irq, void *p)
>  	struct iio_dev *indio_dev = pf->indio_dev;
>  	struct hx711_data *hx711_data = iio_priv(indio_dev);
>  	int i, j = 0;
> +	int ret;
>  
>  	mutex_lock(&hx711_data->lock);
>  
>  	memset(&hx711_data->buffer, 0, sizeof(hx711_data->buffer));
>  
>  	iio_for_each_active_channel(indio_dev, i) {
> -		hx711_data->buffer.channel[j] =
> -			hx711_reset_read(hx711_data, &indio_dev->channels[i]);
> -		j++;
> +		ret = hx711_reset_read(hx711_data, &indio_dev->channels[i]);
> +		if (ret < 0) {
> +			dev_err_ratelimited(hx711_data->dev,
> +					    "read failed: %d\n", ret);
> +			goto out_unlock;
> +		}
> +		hx711_data->buffer.channel[j++] = ret;
>  	}
>  
>  	iio_push_to_buffers_with_timestamp(indio_dev, &hx711_data->buffer,
> -							pf->timestamp);
> +					   pf->timestamp);

This an unrelated change so should not be in a patch doing anything
significant like this one is.

>  
> +out_unlock:
>  	mutex_unlock(&hx711_data->lock);
>  
>  	iio_trigger_notify_done(indio_dev->trig);
> @@ -462,6 +532,54 @@ static const struct iio_info hx711_iio_info = {
>  	.attrs			= &hx711_attribute_group,
>  };


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

* Re: [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support
  2026-05-27 17:41       ` Jonathan Cameron
@ 2026-05-28  8:54         ` Conor Dooley
  2026-05-28 13:08           ` Jonathan Cameron
  0 siblings, 1 reply; 28+ messages in thread
From: Conor Dooley @ 2026-05-28  8:54 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: sashiko-reviews, Piyush Patle, robh, conor+dt, devicetree,
	linux-iio

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

On Wed, May 27, 2026 at 06:41:28PM +0100, Jonathan Cameron wrote:
> On Mon, 25 May 2026 18:01:41 +0100
> Conor Dooley <conor@kernel.org> wrote:
> 
> > Jonathan,
> > 
> > Here's an example of the sort of stuff it complains about on every
> > iteration.
> > 
> Thanks. +cc linux-iio@vger.kernel.org
> 
> > On Mon, May 25, 2026 at 11:11:44AM +0000, sashiko-bot@kernel.org wrote:
> > > Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> > > - [Medium] The `dvdd-supply` property is utilized by the HX710B and mentioned in the commit message, but it is not enforced as a required property for the new compatible or included in the example.
> Yup. This stuff needs fixing.
> 
> > > - [Low] The `if` condition for the `avia,hx710b` compatible incorrectly uses `const` instead of `contains: const`, causing schema validation to always fail for HX710B nodes.
> 
> This one I'm not sure on. Is it right?  I tested by hacking
> the example to have a supply it shouldn't and the schema validation failed
> as expected making me think this is a false positive.
> I have zero natural feel for yaml so no idea :)

It's not the common pattern, but it does work.
IIRC the difference between it and "contains: const: ..." is that it doesn't
apply the condition when the compatible is used as a fallback.


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

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

* Re: [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support
  2026-05-28  8:54         ` Conor Dooley
@ 2026-05-28 13:08           ` Jonathan Cameron
  2026-05-28 14:09             ` Conor Dooley
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2026-05-28 13:08 UTC (permalink / raw)
  To: Conor Dooley
  Cc: sashiko-reviews, Piyush Patle, robh, conor+dt, devicetree,
	linux-iio

On Thu, 28 May 2026 09:54:39 +0100
Conor Dooley <conor@kernel.org> wrote:

> On Wed, May 27, 2026 at 06:41:28PM +0100, Jonathan Cameron wrote:
> > On Mon, 25 May 2026 18:01:41 +0100
> > Conor Dooley <conor@kernel.org> wrote:
> >   
> > > Jonathan,
> > > 
> > > Here's an example of the sort of stuff it complains about on every
> > > iteration.
> > >   
> > Thanks. +cc linux-iio@vger.kernel.org
> >   
> > > On Mon, May 25, 2026 at 11:11:44AM +0000, sashiko-bot@kernel.org wrote:  
> > > > Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> > > > - [Medium] The `dvdd-supply` property is utilized by the HX710B and mentioned in the commit message, but it is not enforced as a required property for the new compatible or included in the example.  
> > Yup. This stuff needs fixing.
> >   
> > > > - [Low] The `if` condition for the `avia,hx710b` compatible incorrectly uses `const` instead of `contains: const`, causing schema validation to always fail for HX710B nodes.  
> > 
> > This one I'm not sure on. Is it right?  I tested by hacking
> > the example to have a supply it shouldn't and the schema validation failed
> > as expected making me think this is a false positive.
> > I have zero natural feel for yaml so no idea :)  
> 
> It's not the common pattern, but it does work.
> IIRC the difference between it and "contains: const: ..." is that it doesn't
> apply the condition when the compatible is used as a fallback.
> 
Makes sense. Given we may have fallbacks in future, it would be
good to use contains version.

Jonathan


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

* Re: [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support
  2026-05-28 13:08           ` Jonathan Cameron
@ 2026-05-28 14:09             ` Conor Dooley
  0 siblings, 0 replies; 28+ messages in thread
From: Conor Dooley @ 2026-05-28 14:09 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: sashiko-reviews, Piyush Patle, robh, conor+dt, devicetree,
	linux-iio

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

On Thu, May 28, 2026 at 02:08:38PM +0100, Jonathan Cameron wrote:
> On Thu, 28 May 2026 09:54:39 +0100
> Conor Dooley <conor@kernel.org> wrote:
> 
> > On Wed, May 27, 2026 at 06:41:28PM +0100, Jonathan Cameron wrote:
> > > On Mon, 25 May 2026 18:01:41 +0100
> > > Conor Dooley <conor@kernel.org> wrote:
> > >   
> > > > Jonathan,
> > > > 
> > > > Here's an example of the sort of stuff it complains about on every
> > > > iteration.
> > > >   
> > > Thanks. +cc linux-iio@vger.kernel.org
> > >   
> > > > On Mon, May 25, 2026 at 11:11:44AM +0000, sashiko-bot@kernel.org wrote:  
> > > > > Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> > > > > - [Medium] The `dvdd-supply` property is utilized by the HX710B and mentioned in the commit message, but it is not enforced as a required property for the new compatible or included in the example.  
> > > Yup. This stuff needs fixing.
> > >   
> > > > > - [Low] The `if` condition for the `avia,hx710b` compatible incorrectly uses `const` instead of `contains: const`, causing schema validation to always fail for HX710B nodes.  
> > > 
> > > This one I'm not sure on. Is it right?  I tested by hacking
> > > the example to have a supply it shouldn't and the schema validation failed
> > > as expected making me think this is a false positive.
> > > I have zero natural feel for yaml so no idea :)  
> > 
> > It's not the common pattern, but it does work.
> > IIRC the difference between it and "contains: const: ..." is that it doesn't
> > apply the condition when the compatible is used as a fallback.
> > 
> Makes sense. Given we may have fallbacks in future, it would be
> good to use contains version.

Or change it in the future when the user of the fallback arrives, since
the binding will need to be modified anyway at that point. That's why
I didn't ask for the change to be made.

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

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

end of thread, other threads:[~2026-05-28 14:09 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-25 10:51 [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Piyush Patle
2026-05-25 10:51 ` [PATCH v10 01/11] dt-bindings: iio: adc: hx711: clean up existing binding text Piyush Patle
2026-05-25 10:51 ` [PATCH v10 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property Piyush Patle
2026-05-25 10:58   ` sashiko-bot
2026-05-27 17:34   ` Jonathan Cameron
2026-05-25 10:51 ` [PATCH v10 03/11] dt-bindings: iio: adc: hx711: add RATE GPIO property Piyush Patle
2026-05-25 10:51 ` [PATCH v10 04/11] dt-bindings: iio: adc: hx711: add HX710B support Piyush Patle
2026-05-25 11:11   ` sashiko-bot
2026-05-25 17:01     ` Conor Dooley
2026-05-27 17:41       ` Jonathan Cameron
2026-05-28  8:54         ` Conor Dooley
2026-05-28 13:08           ` Jonathan Cameron
2026-05-28 14:09             ` Conor Dooley
2026-05-27 17:37   ` Jonathan Cameron
2026-05-25 10:51 ` [PATCH v10 05/11] iio: adc: hx711: move scale computation to per-device storage Piyush Patle
2026-05-25 10:51 ` [PATCH v10 06/11] iio: adc: hx711: introduce hx711_chip_info structure Piyush Patle
2026-05-25 11:34   ` sashiko-bot
2026-05-25 10:51 ` [PATCH v10 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read Piyush Patle
2026-05-25 11:10   ` sashiko-bot
2026-05-25 10:51 ` [PATCH v10 08/11] iio: adc: hx711: split variable assignments in hx711_read and hx711_reset Piyush Patle
2026-05-25 10:51 ` [PATCH v10 09/11] iio: adc: hx711: localize loop iterators in hx711_read Piyush Patle
2026-05-25 10:51 ` [PATCH v10 10/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read Piyush Patle
2026-05-25 11:25   ` sashiko-bot
2026-05-25 10:51 ` [PATCH v10 11/11] iio: adc: hx711: add support for HX710B Piyush Patle
2026-05-25 11:33   ` sashiko-bot
2026-05-27 17:54   ` Jonathan Cameron
2026-05-27 17:32 ` [PATCH v10 00/11] iio: adc: Add support for AVIA HX710B ADC Jonathan Cameron
2026-05-27 17:45 ` Jonathan Cameron

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