* [PATCH v5 01/11] dt-bindings: iio: adc: hx711: clean up existing binding text
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 5:45 ` [PATCH v5 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property Piyush Patle
` (10 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
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>
---
Changes in v5:
- New patch split out of the old combined binding update during review.
- Limit this patch to cleanup of the existing HX711 binding text and the
clock-frequency description.
Changes in v4:
- This cleanup was part of the old combined binding patch.
Changes in v3:
- Restore the example node name to weight and drop the repeated
clock-frequency default wording in the old combined patch.
Changes in v2:
- Remove driver implementation details from the binding description and
clarify clock-frequency as SCK bit-bang timing.
---
.../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] 23+ messages in thread* [PATCH v5 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
2026-04-29 5:45 ` [PATCH v5 01/11] dt-bindings: iio: adc: hx711: clean up existing binding text Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 5:45 ` [PATCH v5 03/11] dt-bindings: iio: adc: hx711: add RATE GPIO property Piyush Patle
` (9 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
Document the optional VSUP supply used by the HX711 on-chip regulator.
Keep this separate from the HX710B support so the existing HX711
binding extension stands on its own.
No functional change for existing users.
Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
---
Changes in v5:
- New patch split out of the old combined binding update during review.
- Document the existing HX711-only VSUP supply separately from the new
HX710B support.
Changes in v4:
- This property was part of the old combined binding patch.
Changes in v2:
- Document the optional VSUP supply for HX711 nodes.
---
Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
index 1ea60dff98d5..a8eaa1f18de5 100644
--- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
@@ -33,6 +33,10 @@ properties:
description:
Analog supply voltage (AVDD).
+ vsup-supply:
+ description:
+ Supply voltage for the on-chip regulator (VSUP).
+
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] 23+ messages in thread* [PATCH v5 03/11] dt-bindings: iio: adc: hx711: add RATE GPIO property
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
2026-04-29 5:45 ` [PATCH v5 01/11] dt-bindings: iio: adc: hx711: clean up existing binding text Piyush Patle
2026-04-29 5:45 ` [PATCH v5 02/11] dt-bindings: iio: adc: hx711: add VSUP supply property Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 5:45 ` [PATCH v5 04/11] dt-bindings: iio: adc: hx711: add HX710B support Piyush Patle
` (8 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
Document the optional RATE pin GPIO used to select the HX711 output
data rate.
Update the example to show the property in use.
No functional change for existing users.
Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
---
Changes in v5:
- New patch split out of the old combined binding update during review.
- Document the existing HX711-only RATE GPIO separately and move the
example update here.
Changes in v4:
- This property and example update were part of the old combined
binding patch.
Changes in v2:
- Add the optional RATE GPIO property for the HX711 RATE pin.
---
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 a8eaa1f18de5..9134bbe41379 100644
--- a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
@@ -37,6 +37,13 @@ properties:
description:
Supply voltage for the on-chip regulator (VSUP).
+ 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
@@ -61,6 +68,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] 23+ messages in thread* [PATCH v5 04/11] dt-bindings: iio: adc: hx711: add HX710B support
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
` (2 preceding siblings ...)
2026-04-29 5:45 ` [PATCH v5 03/11] dt-bindings: iio: adc: hx711: add RATE GPIO property Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 5:45 ` [PATCH v5 05/11] iio: adc: hx711: move scale computation to per-device storage Piyush Patle
` (7 subsequent siblings)
11 siblings, 0 replies; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
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.
Keep the existing HX711-only binding extensions in earlier patches so
this change is limited to the new variant.
Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
---
Changes in v5:
- Split this out of the old combined binding update so the HX710B
additions stand on their own.
- Require explicit vref-supply for HX710B nodes instead of documenting
an implicit fallback.
- Use a single if/then/else schema block for the HX710B versus HX711
property constraints.
Changes in v4:
- Add vref-supply for the HX710B VREF pin.
- Remove dvdd-supply from the HX710B forbidden properties.
- Add an HX710B example and the vref-supply constraint for HX711/HX710B.
- Update the HX710B description to avoid channel-number wording.
Changes in v3:
- Drop the old vref wording from avdd-supply and remove the separate
HX710B example used earlier.
Changes in v2:
- Add the HX710B-compatible, dvdd-supply, and the initial HX710B/HX711
constraints in the combined binding update.
---
.../bindings/iio/adc/avia-hx711.yaml | 42 ++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml b/Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
index 9134bbe41379..b2b5c7bdf05e 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:
@@ -44,6 +49,17 @@ properties:
RATE pin state is determined by the board wiring.
maxItems: 1
+ dvdd-supply:
+ description:
+ Digital supply voltage (DVDD). For 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.
+
+ vref-supply:
+ description:
+ Reference voltage input (VREF).
+
clock-frequency:
description:
Controls the SCK bit-bang timing. The value is used to derive the
@@ -53,6 +69,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
@@ -72,3 +103,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] 23+ messages in thread* [PATCH v5 05/11] iio: adc: hx711: move scale computation to per-device storage
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
` (3 preceding siblings ...)
2026-04-29 5:45 ` [PATCH v5 04/11] dt-bindings: iio: adc: hx711: add HX710B support Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 18:41 ` Andy Shevchenko
2026-04-29 5:45 ` [PATCH v5 06/11] iio: adc: hx711: introduce hx711_chip_info structure Piyush Patle
` (6 subsequent siblings)
11 siblings, 1 reply; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
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>
---
Changes in v5:
- Add trailing commas in the hx711_gain_to_scale[] initializers.
- Keep the hx711_data declaration in hx711_scale_available_show() on one
line and preserve local declaration ordering.
Changes in v4:
- New patch added to fix the pre-existing global scale mutation bug
reported during review.
---
drivers/iio/adc/hx711.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index 1db8b68a8f64..8485e18c949d 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;
@@ -574,4 +575,3 @@ MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
MODULE_DESCRIPTION("HX711 bitbanging driver - ADC for weight cells");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:hx711-gpio");
-
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v5 05/11] iio: adc: hx711: move scale computation to per-device storage
2026-04-29 5:45 ` [PATCH v5 05/11] iio: adc: hx711: move scale computation to per-device storage Piyush Patle
@ 2026-04-29 18:41 ` Andy Shevchenko
0 siblings, 0 replies; 23+ messages in thread
From: Andy Shevchenko @ 2026-04-29 18:41 UTC (permalink / raw)
To: Piyush Patle
Cc: ak, jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
linux-iio, devicetree, linux-kernel
On Wed, Apr 29, 2026 at 11:15:38AM +0530, Piyush Patle wrote:
> 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.
...
> @@ -574,4 +575,3 @@ MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
> MODULE_DESCRIPTION("HX711 bitbanging driver - ADC for weight cells");
> MODULE_LICENSE("GPL");
> MODULE_ALIAS("platform:hx711-gpio");
> -
Stray change.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5 06/11] iio: adc: hx711: introduce hx711_chip_info structure
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
` (4 preceding siblings ...)
2026-04-29 5:45 ` [PATCH v5 05/11] iio: adc: hx711: move scale computation to per-device storage Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 18:44 ` Andy Shevchenko
2026-04-29 5:45 ` [PATCH v5 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read Piyush Patle
` (5 subsequent siblings)
11 siblings, 1 reply; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
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>
---
Changes in v5:
- State explicitly that this is preparatory for adding another
HX711-compatible variant.
- Move linux/array_size.h and linux/dev_printk.h here where they become
needed.
- Use "missing driver data" for the NULL guard and preserve local
declaration ordering.
Changes in v4:
- New patch split out from the earlier refactor during review.
- Keep hx711_chip_info fields in their final order from introduction.
- Add the NULL guard on device_get_match_data().
---
drivers/iio/adc/hx711.c | 43 +++++++++++++++++++++++++++++++++++------
1 file changed, 37 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index 8485e18c949d..666f64284a0d 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
+ * @iio_info: IIO info ops for this variant
+ * @num_channels: number of entries in @channels
+ */
+struct hx711_chip_info {
+ const char *name;
+ const struct iio_chan_spec *channels;
+ const struct iio_info *iio_info;
+ unsigned int num_channels;
+};
+
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,11 +473,19 @@ 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)
{
- struct device *dev = &pdev->dev;
+ const struct hx711_chip_info *chip_info;
struct hx711_data *hx711_data;
struct iio_dev *indio_dev;
+ struct device *dev = &pdev->dev;
int ret;
int i;
@@ -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] 23+ messages in thread* Re: [PATCH v5 06/11] iio: adc: hx711: introduce hx711_chip_info structure
2026-04-29 5:45 ` [PATCH v5 06/11] iio: adc: hx711: introduce hx711_chip_info structure Piyush Patle
@ 2026-04-29 18:44 ` Andy Shevchenko
0 siblings, 0 replies; 23+ messages in thread
From: Andy Shevchenko @ 2026-04-29 18:44 UTC (permalink / raw)
To: Piyush Patle
Cc: ak, jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
linux-iio, devicetree, linux-kernel
On Wed, Apr 29, 2026 at 11:15:39AM +0530, Piyush Patle wrote:
> 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.
...
> static int hx711_probe(struct platform_device *pdev)
> {
> - struct device *dev = &pdev->dev;
> + const struct hx711_chip_info *chip_info;
> struct hx711_data *hx711_data;
> struct iio_dev *indio_dev;
> + struct device *dev = &pdev->dev;
Follow reversed xmas tree order, please. This should be two lines up.
> int ret;
> int i;
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
` (5 preceding siblings ...)
2026-04-29 5:45 ` [PATCH v5 06/11] iio: adc: hx711: introduce hx711_chip_info structure Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 18:53 ` Andy Shevchenko
2026-04-29 5:45 ` [PATCH v5 08/11] iio: adc: hx711: localize loop iterators in hx711_read Piyush Patle
` (4 subsequent siblings)
11 siblings, 1 reply; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
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>
---
Changes in v5:
- Split the trailing-pulse refactor from the loop-iterator cleanup.
- Keep the loop variables unchanged in this patch.
Changes in v4:
- New patch split out from the earlier refactor during review.
---
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 666f64284a0d..d85ff2f4a3dd 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] 23+ messages in thread* Re: [PATCH v5 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read
2026-04-29 5:45 ` [PATCH v5 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read Piyush Patle
@ 2026-04-29 18:53 ` Andy Shevchenko
0 siblings, 0 replies; 23+ messages in thread
From: Andy Shevchenko @ 2026-04-29 18:53 UTC (permalink / raw)
To: Piyush Patle
Cc: ak, jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
linux-iio, devicetree, linux-kernel
On Wed, Apr 29, 2026 at 11:15:40AM +0530, Piyush Patle wrote:
> 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.
This one LGTM.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5 08/11] iio: adc: hx711: localize loop iterators in hx711_read
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
` (6 preceding siblings ...)
2026-04-29 5:45 ` [PATCH v5 07/11] iio: adc: hx711: pass trailing pulse count into hx711_read Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 15:01 ` Joshua Crofts
2026-04-29 18:49 ` Andy Shevchenko
2026-04-29 5:45 ` [PATCH v5 09/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read Piyush Patle
` (3 subsequent siblings)
11 siblings, 2 replies; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
Tighten the scope of the loop variables in hx711_read() now that the
trailing-pulse refactor is in place.
No functional change.
Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
---
Changes in v5:
- New patch split out of the trailing-pulse refactor during review.
- Use unsigned scoped loop iterators in hx711_read().
Changes in v4:
- The scoped loop-variable cleanup was previously bundled with the
trailing-pulse patch.
---
drivers/iio/adc/hx711.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index d85ff2f4a3dd..15b9f78b6a25 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -157,7 +157,7 @@ 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 ret;
int value = 0;
int val = gpiod_get_value(hx711_data->gpiod_dout);
@@ -165,7 +165,7 @@ static int hx711_read(struct hx711_data *hx711_data, int trailing_pulses)
if (val)
return -EIO;
- for (i = 0; i < 24; i++) {
+ for (unsigned int i = 0; i < 24; i++) {
value <<= 1;
ret = hx711_cycle(hx711_data);
if (ret)
@@ -174,7 +174,7 @@ static int hx711_read(struct hx711_data *hx711_data, int trailing_pulses)
value ^= 0x800000;
- for (i = 0; i < trailing_pulses; i++)
+ for (unsigned int i = 0; i < trailing_pulses; i++)
hx711_cycle(hx711_data);
return value;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v5 08/11] iio: adc: hx711: localize loop iterators in hx711_read
2026-04-29 5:45 ` [PATCH v5 08/11] iio: adc: hx711: localize loop iterators in hx711_read Piyush Patle
@ 2026-04-29 15:01 ` Joshua Crofts
2026-04-29 18:51 ` Andy Shevchenko
2026-04-29 18:49 ` Andy Shevchenko
1 sibling, 1 reply; 23+ messages in thread
From: Joshua Crofts @ 2026-04-29 15:01 UTC (permalink / raw)
To: Piyush Patle
Cc: ak, jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
linux-iio, devicetree, linux-kernel
On Wed, 29 Apr 2026 at 07:48, Piyush Patle <piyushpatle228@gmail.com> wrote:
> - for (i = 0; i < 24; i++) {
> + for (unsigned int i = 0; i < 24; i++) {
Might be a nitpick, but wouldn't it be better to have a macro or a local
variable for the 24?
> value <<= 1;
> ret = hx711_cycle(hx711_data);
> if (ret)
> @@ -174,7 +174,7 @@ static int hx711_read(struct hx711_data *hx711_data, int trailing_pulses)
>
> value ^= 0x800000;
>
> - for (i = 0; i < trailing_pulses; i++)
> + for (unsigned int i = 0; i < trailing_pulses; i++)
Why is the index unsigned when trailing_pulses is signed (this goes
for the for loop above as well)?
--
Kind regards
CJD
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH v5 08/11] iio: adc: hx711: localize loop iterators in hx711_read
2026-04-29 15:01 ` Joshua Crofts
@ 2026-04-29 18:51 ` Andy Shevchenko
0 siblings, 0 replies; 23+ messages in thread
From: Andy Shevchenko @ 2026-04-29 18:51 UTC (permalink / raw)
To: Joshua Crofts
Cc: Piyush Patle, ak, jic23, dlechner, nuno.sa, andy, robh, krzk+dt,
conor+dt, linux-iio, devicetree, linux-kernel
On Wed, Apr 29, 2026 at 05:01:35PM +0200, Joshua Crofts wrote:
> On Wed, 29 Apr 2026 at 07:48, Piyush Patle <piyushpatle228@gmail.com> wrote:
...
> > - for (i = 0; i < 24; i++) {
> > + for (unsigned int i = 0; i < 24; i++) {
>
> Might be a nitpick, but wouldn't it be better to have a macro or a local
> variable for the 24?
If so, should be a separate change. For now I don't mind to have it like this.
...
> > - for (i = 0; i < trailing_pulses; i++)
> > + for (unsigned int i = 0; i < trailing_pulses; i++)
>
> Why is the index unsigned when trailing_pulses is signed (this goes
> for the for loop above as well)?
It's probably me who suggested the unsigned variant. But I agree, better to
follow the type of the (upper) limit.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v5 08/11] iio: adc: hx711: localize loop iterators in hx711_read
2026-04-29 5:45 ` [PATCH v5 08/11] iio: adc: hx711: localize loop iterators in hx711_read Piyush Patle
2026-04-29 15:01 ` Joshua Crofts
@ 2026-04-29 18:49 ` Andy Shevchenko
1 sibling, 0 replies; 23+ messages in thread
From: Andy Shevchenko @ 2026-04-29 18:49 UTC (permalink / raw)
To: Piyush Patle
Cc: ak, jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
linux-iio, devicetree, linux-kernel
On Wed, Apr 29, 2026 at 11:15:41AM +0530, Piyush Patle wrote:
> Tighten the scope of the loop variables in hx711_read() now that the
> trailing-pulse refactor is in place.
>
> No functional change.
Suggested-by:?
...
> static int hx711_read(struct hx711_data *hx711_data, int trailing_pulses)
> {
> - int i, ret;
> + int ret;
> int value = 0;
> int val = gpiod_get_value(hx711_data->gpiod_dout);
Try to place it to follow reversed xmas tree order (yes, it doesn't and won't
fully be, but it will be step closer).
int value = 0;
int val = gpiod_get_value(hx711_data->gpiod_dout);
int ret;
But as you see, this needs to be coupled with splitting definition and
assignment of val, hence
int value = 0;
int val;
int ret;
val = gpiod_get_value(hx711_data->gpiod_dout);
This part should be in a separate change before you are doing the loop
iterators.
TL;DR: Should be two patches here: 1) split val assignment; 2) this patch with
proper location of int ret.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5 09/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
` (7 preceding siblings ...)
2026-04-29 5:45 ` [PATCH v5 08/11] iio: adc: hx711: localize loop iterators in hx711_read Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 18:54 ` Andy Shevchenko
2026-04-29 5:45 ` [PATCH v5 10/11] iio: adc: hx711: split hx711_reset variable assignment Piyush Patle
` (2 subsequent siblings)
11 siblings, 1 reply; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
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>
---
Changes in v5:
- Use "change" instead of "patch" when referring to the later HX710B
follow-up.
- Extract hx711_set_hx711_channel() so the HX710B patch can add a
matching helper.
- Reindent the triggered-buffer call site as requested.
Changes in v4:
- New patch split out from the earlier refactor during review.
---
drivers/iio/adc/hx711.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index 15b9f78b6a25..914c6efd0f96 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -264,7 +264,22 @@ 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;
@@ -278,11 +293,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);
}
@@ -296,7 +310,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);
@@ -386,8 +400,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] 23+ messages in thread* Re: [PATCH v5 09/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read
2026-04-29 5:45 ` [PATCH v5 09/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read Piyush Patle
@ 2026-04-29 18:54 ` Andy Shevchenko
0 siblings, 0 replies; 23+ messages in thread
From: Andy Shevchenko @ 2026-04-29 18:54 UTC (permalink / raw)
To: Piyush Patle
Cc: ak, jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
linux-iio, devicetree, linux-kernel
On Wed, Apr 29, 2026 at 11:15:42AM +0530, Piyush Patle wrote:
> 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.
This one LGTM.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5 10/11] iio: adc: hx711: split hx711_reset variable assignment
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
` (8 preceding siblings ...)
2026-04-29 5:45 ` [PATCH v5 09/11] iio: adc: hx711: pass iio_chan_spec to hx711_reset_read Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 18:55 ` Andy Shevchenko
2026-04-29 5:45 ` [PATCH v5 11/11] iio: adc: hx711: add support for HX710B Piyush Patle
2026-04-29 19:08 ` [PATCH v5 0/11] iio: adc: hx711: add HX710B support Andy Shevchenko
11 siblings, 1 reply; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
Separate the hx711_wait_for_ready() assignment from the declaration in
hx711_reset().
This is a small preparatory cleanup before the later variant-specific
changes add another local variable in the same function.
No functional change.
Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
---
Changes in v5:
- New preparatory patch requested during review.
- Split the hx711_wait_for_ready() assignment from the declaration
before the later HX710B change adds another local variable in
hx711_reset().
- Keep this separate specifically because Andy Shevchenko asked for the
prep split rather than mixing it into the HX710B feature patch.
---
drivers/iio/adc/hx711.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
index 914c6efd0f96..e72f3c2cdbcf 100644
--- a/drivers/iio/adc/hx711.c
+++ b/drivers/iio/adc/hx711.c
@@ -204,7 +204,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) {
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v5 10/11] iio: adc: hx711: split hx711_reset variable assignment
2026-04-29 5:45 ` [PATCH v5 10/11] iio: adc: hx711: split hx711_reset variable assignment Piyush Patle
@ 2026-04-29 18:55 ` Andy Shevchenko
0 siblings, 0 replies; 23+ messages in thread
From: Andy Shevchenko @ 2026-04-29 18:55 UTC (permalink / raw)
To: Piyush Patle
Cc: ak, jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
linux-iio, devicetree, linux-kernel
On Wed, Apr 29, 2026 at 11:15:43AM +0530, Piyush Patle wrote:
> Separate the hx711_wait_for_ready() assignment from the declaration in
> hx711_reset().
>
> This is a small preparatory cleanup before the later variant-specific
> changes add another local variable in the same function.
>
> No functional change.
As I pointed out this also should be done for val assignment in other case.
And it should go before loop iterator patch.
...
> 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);
>
This blank line has to be removed now.
> if (val) {
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5 11/11] iio: adc: hx711: add support for HX710B
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
` (9 preceding siblings ...)
2026-04-29 5:45 ` [PATCH v5 10/11] iio: adc: hx711: split hx711_reset variable assignment Piyush Patle
@ 2026-04-29 5:45 ` Piyush Patle
2026-04-29 19:06 ` Andy Shevchenko
2026-04-29 19:08 ` [PATCH v5 0/11] iio: adc: hx711: add HX710B support Andy Shevchenko
11 siblings, 1 reply; 23+ messages in thread
From: Piyush Patle @ 2026-04-29 5:45 UTC (permalink / raw)
To: ak, jic23
Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-iio,
devicetree, linux-kernel
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>
---
Changes in v5:
- Fold the Kconfig help text, file header, and MODULE_DESCRIPTION
updates into the final new-hardware support patch.
- Add linux/types.h here where the fixed-gain fields become needed.
- Keep a single gain_scale[] path for HX710B instead of introducing a
separate per-device scale field.
- Add hx711_set_hx710b_channel() alongside the existing HX711 helper and
update comments and formatting per review.
- Read the HX710B ADC reference from vref-supply and require it in the
binding instead of describing an implicit AVDD fallback.
Changes in v4:
- Add the third HX710B channel (27 pulses, differential 40 SPS).
- Use .channel = 2 for the supply monitor to avoid the differential-pair
indexing clash.
- Update channel_set only after both hx711_read() and
hx711_wait_for_ready() succeed.
- Keep a single fixed-gain scale derived from gain 128.
Changes in v3:
- Add HX710B support on top of the separate hx711_chip_info refactor.
- Keep chan->address for HX710B trailing pulse counts and describe the
first HX710B channel as a differential IIO channel.
- Use unsigned state where appropriate and verify chip_info layout with
pahole.
Changes in v2:
- Fix the pulse-count bug by storing trailing pulse counts instead of
total SCK cycles.
- Add .differential/.channel2 for HX710B input channels.
- Replace the old channel-pulse tests with explicit fixed-gain support.
---
drivers/iio/adc/Kconfig | 8 +-
drivers/iio/adc/hx711.c | 173 +++++++++++++++++++++++++++++++++++-----
2 files changed, 157 insertions(+), 24 deletions(-)
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 60038ae8dfc4..09a1b29fbd9c 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -784,13 +784,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 e72f3c2cdbcf..4c087e8b9abf 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 weight sensor modules
*
* Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
*/
@@ -9,6 +9,7 @@
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/types.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/property.h>
@@ -82,12 +83,16 @@ static int hx711_get_scale_to_gain(const int *gain_scale, int scale)
* @channels: channel specification array
* @iio_info: IIO info ops for this variant
* @num_channels: number of entries in @channels
+ * @fixed_gain_val: fixed PGA gain (used when @fixed_gain is true)
+ * @fixed_gain: true if the variant has a fixed ADC gain
*/
struct hx711_chip_info {
const char *name;
const struct iio_chan_spec *channels;
const struct iio_info *iio_info;
unsigned int num_channels;
+ unsigned int fixed_gain_val;
+ bool fixed_gain;
};
struct hx711_data {
@@ -97,14 +102,16 @@ struct hx711_data {
int gain_set; /* gain set on device */
int gain_chan_a; /* gain for channel A */
int gain_scale[HX711_GAIN_MAX];
+ unsigned int channel_set; /* HX710B active channel */
const struct hx711_chip_info *chip_info;
struct mutex lock;
/*
* triggered buffer
- * 2x32-bit channel + 64-bit naturally aligned timestamp
+ * up to 3x32-bit channels + pad + 64-bit naturally aligned timestamp
*/
struct {
- u32 channel[2];
+ u32 channel[3];
+ u32 pad;
aligned_s64 timestamp;
} buffer;
/*
@@ -204,6 +211,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);
@@ -224,8 +232,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->fixed_gain)
+ hx711_data->channel_set = 0;
+ else
+ /* after a reset the gain is 128 */
+ hx711_data->gain_set = HX711_RESET_GAIN;
}
return val;
@@ -280,9 +291,36 @@ static int hx711_set_hx711_channel(struct hx711_data *hx711_data,
return 0;
}
+/*
+ * Switch the HX710B to the requested channel for the next conversion.
+ * chan->address holds the trailing pulse count (Table 3 in datasheet).
+ * channel_set is updated only after both reads succeed.
+ */
+static int hx711_set_hx710b_channel(struct hx711_data *hx711_data,
+ const struct iio_chan_spec *chan)
+{
+ int ret;
+
+ if (hx711_data->channel_set == (unsigned int)chan->channel)
+ return 0;
+
+ ret = hx711_read(hx711_data, chan->address);
+ if (ret < 0)
+ return ret;
+
+ ret = hx711_wait_for_ready(hx711_data);
+ if (ret)
+ return ret;
+
+ hx711_data->channel_set = chan->channel;
+
+ 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;
@@ -295,9 +333,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->fixed_gain) {
+ ret = hx711_set_hx710b_channel(hx711_data, chan);
+ if (ret < 0)
+ return ret;
+ trailing_pulses = chan->address;
+ } else {
+ ret = hx711_set_hx711_channel(hx711_data, chan, &trailing_pulses);
+ if (ret < 0)
+ return ret;
+ }
return hx711_read(hx711_data, trailing_pulses);
}
@@ -459,6 +504,10 @@ static const struct iio_info hx711_iio_info = {
.attrs = &hx711_attribute_group,
};
+static const struct iio_info hx710b_iio_info = {
+ .read_raw = hx711_read_raw,
+};
+
static const struct iio_chan_spec hx711_chan_spec[] = {
{
.type = IIO_VOLTAGE,
@@ -491,6 +540,68 @@ 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 -> channel 0
+ * 26 pulses (2 trailing): DVDD-AVDD supply monitor, 40 SPS -> channel 2
+ * 27 pulses (3 trailing): differential input, 40 SPS -> channel 3
+ * .address stores the trailing pulse count for hx711_set_hx710b_channel().
+ * Channel 2 is used for the supply monitor to avoid aliasing the
+ * channel2 terminal of the first differential pair.
+ */
+static const struct iio_chan_spec hx710b_chan_spec[] = {
+ {
+ .type = IIO_VOLTAGE,
+ .differential = 1,
+ .channel = 0,
+ .channel2 = 1,
+ .indexed = 1,
+ .address = 1,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 24,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ },
+ },
+ {
+ .type = IIO_VOLTAGE,
+ .channel = 2,
+ .indexed = 1,
+ .address = 2,
+ .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,
+ },
+ },
+ {
+ .type = IIO_VOLTAGE,
+ .differential = 1,
+ .channel = 3,
+ .channel2 = 4,
+ .indexed = 1,
+ .address = 3,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 2,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 24,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
static const struct hx711_chip_info hx711_chip = {
.name = "hx711",
.channels = hx711_chan_spec,
@@ -498,6 +609,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,
+ .fixed_gain = true,
+};
+
static int hx711_probe(struct platform_device *pdev)
{
const struct hx711_chip_info *chip_info;
@@ -540,32 +660,42 @@ 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->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->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;
+ } 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",
@@ -604,6 +734,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 },
{ }
};
@@ -621,6 +752,6 @@ 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 compatible bitbanging ADC driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:hx711-gpio");
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH v5 11/11] iio: adc: hx711: add support for HX710B
2026-04-29 5:45 ` [PATCH v5 11/11] iio: adc: hx711: add support for HX710B Piyush Patle
@ 2026-04-29 19:06 ` Andy Shevchenko
2026-05-04 15:56 ` Jonathan Cameron
0 siblings, 1 reply; 23+ messages in thread
From: Andy Shevchenko @ 2026-04-29 19:06 UTC (permalink / raw)
To: Piyush Patle
Cc: ak, jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
linux-iio, devicetree, linux-kernel
On Wed, Apr 29, 2026 at 11:15:44AM +0530, Piyush Patle 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.
...
> /*
> - * HX711: analog to digital converter for weight sensor module
> + * HX711 and compatible ADCs driver for weight sensor modules
As noticed in previous round, shouldn't we fix weight --> weigh?
> *
> * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
> */
...
> #include <linux/err.h>
> #include <linux/kernel.h>
> #include <linux/module.h>
> +#include <linux/types.h>
No, you clearly see the order. Please, preserve it.
> #include <linux/mod_devicetable.h>
> #include <linux/platform_device.h>
> #include <linux/property.h>
...
> + * @fixed_gain: true if the variant has a fixed ADC gain
> + bool fixed_gain;
In accordance with the kernel-doc, name the variable "has_fixed_gain".
...
> /*
> * triggered buffer
> - * 2x32-bit channel + 64-bit naturally aligned timestamp
> + * up to 3x32-bit channels + pad + 64-bit naturally aligned timestamp
> */
> struct {
> - u32 channel[2];
> + u32 channel[3];
> + u32 pad;
> aligned_s64 timestamp;
> } buffer;
I think I still doesn't follow if this kind of changes affects ABI or not.
Jonathan, is it usually okay to inject more entries in this structure?
...
> +static int hx711_set_hx710b_channel(struct hx711_data *hx711_data,
> + const struct iio_chan_spec *chan)
> +{
> + int ret;
> +
> + if (hx711_data->channel_set == (unsigned int)chan->channel)
Why do we need explicit casting?
> + return 0;
> +
> + ret = hx711_read(hx711_data, chan->address);
> + if (ret < 0)
> + return ret;
> +
> + ret = hx711_wait_for_ready(hx711_data);
> + if (ret)
> + return ret;
> +
> + hx711_data->channel_set = chan->channel;
> +
> + return 0;
> +}
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH v5 11/11] iio: adc: hx711: add support for HX710B
2026-04-29 19:06 ` Andy Shevchenko
@ 2026-05-04 15:56 ` Jonathan Cameron
0 siblings, 0 replies; 23+ messages in thread
From: Jonathan Cameron @ 2026-05-04 15:56 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Piyush Patle, ak, dlechner, nuno.sa, andy, robh, krzk+dt,
conor+dt, linux-iio, devicetree, linux-kernel
On Wed, 29 Apr 2026 22:06:34 +0300
Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> On Wed, Apr 29, 2026 at 11:15:44AM +0530, Piyush Patle 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.
>
> ...
A few follow up responses inline.
>
> > /*
> > - * HX711: analog to digital converter for weight sensor module
> > + * HX711 and compatible ADCs driver for weight sensor modules
>
> As noticed in previous round, shouldn't we fix weight --> weigh?
Just for clarity on this following are correct (I think)
Weight sensor
Weigh cell
Not that I care that much give the meaning is clear for all combinations.
>
> In accordance with the kernel-doc, name the variable "has_fixed_gain".
>
> ...
>
> > /*
> > * triggered buffer
> > - * 2x32-bit channel + 64-bit naturally aligned timestamp
> > + * up to 3x32-bit channels + pad + 64-bit naturally aligned timestamp
> > */
> > struct {
> > - u32 channel[2];
> > + u32 channel[3];
> > + u32 pad;
> > aligned_s64 timestamp;
> > } buffer;
>
> I think I still doesn't follow if this kind of changes affects ABI or not.
> Jonathan, is it usually okay to inject more entries in this structure?
Good point.
Using an explicit structure here is now misleading. The timestamp
will move if only two channels are enabled vs all 3 enabled.
So this should change to instead use IIO_DECLARE_BUFFER_WITH_TS()
Also unless this driver explicitly writes to pad that shouldn't be there. The
aligned_s64 will ensure the padding is there without it and generally in
IIO we rely on that rather that adding padding by hand.
>
> ...
>
> > +static int hx711_set_hx710b_channel(struct hx711_data *hx711_data,
> > + const struct iio_chan_spec *chan)
> > +{
> > + int ret;
> > +
> > + if (hx711_data->channel_set == (unsigned int)chan->channel)
>
> Why do we need explicit casting?
>
> > + return 0;
> > +
> > + ret = hx711_read(hx711_data, chan->address);
> > + if (ret < 0)
> > + return ret;
> > +
> > + ret = hx711_wait_for_ready(hx711_data);
> > + if (ret)
> > + return ret;
> > +
> > + hx711_data->channel_set = chan->channel;
> > +
> > + return 0;
> > +}
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v5 0/11] iio: adc: hx711: add HX710B support
2026-04-29 5:45 [PATCH v5 0/11] iio: adc: hx711: add HX710B support Piyush Patle
` (10 preceding siblings ...)
2026-04-29 5:45 ` [PATCH v5 11/11] iio: adc: hx711: add support for HX710B Piyush Patle
@ 2026-04-29 19:08 ` Andy Shevchenko
11 siblings, 0 replies; 23+ messages in thread
From: Andy Shevchenko @ 2026-04-29 19:08 UTC (permalink / raw)
To: Piyush Patle
Cc: ak, jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
linux-iio, devicetree, linux-kernel
On Wed, Apr 29, 2026 at 11:15:33AM +0530, Piyush Patle wrote:
> Add support for the AVIA HX710B ADC, a HX711-compatible converter with
> the same GPIO interface but a different channel-selection model and a
> fixed gain of 128.
>
> Compared to v4, this series is split more finely to match the review
> boundaries requested during review rather than because the feature
> itself grew materially:
>
> - the DT binding work is now split into cleanup of the existing HX711
> binding, HX711-only VSUP documentation, HX711-only RATE GPIO
> documentation, and the HX710B binding addition
> - the driver refactoring is now split further so the trailing-pulse
> parameterization, loop-iterator cleanup, and hx711_reset() declaration
> cleanup all stand alone
> - the Kconfig help text, file header, and MODULE_DESCRIPTION updates now
> sit adjacent to the final HX710B support patch instead of appearing in
> the middle of the refactor sequence
>
> The resulting series is longer than v4, but each patch is narrower and
> maps more directly to the requested review boundaries.
>
> Tested on PocketBeagle2 with an HX710B breakout module. The device
> probed successfully, all three channels returned stable raw readings,
> and alternating reads confirmed channel switching between the
> differential input and the DVDD-AVDD supply monitor path.
>
> Build-tested with:
> - make -s W=1 drivers/iio/adc/hx711.o
> - make -s dt_binding_check \
> DT_SCHEMA_FILES=Documentation/devicetree/bindings/iio/adc/avia-hx711.yaml
> - pahole -C hx711_chip_info drivers/iio/adc/hx711.o
>
> pahole reports hx711_chip_info as 40 bytes with no internal holes. The
> remaining 7 bytes are tail padding from 8-byte pointer alignment.
This is almost ready-to-push series. I have a few nit-picks here and there,
most important ones are the patch organisation (splitting) and the question
about new entries in the buffer structure.
I believe next version will be final (but wait until we settle down on the
opens).
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 23+ messages in thread