]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iio: adc: hx711: move scale computation to per-device storage
authorPiyush Patle <piyushpatle228@gmail.com>
Mon, 11 May 2026 17:43:30 +0000 (23:13 +0530)
committerJonathan Cameron <jic23@kernel.org>
Sun, 31 May 2026 09:59:39 +0000 (10:59 +0100)
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>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/adc/hx711.c

index 1db8b68a8f64e7b1b92dbb4e1011f383dc993fa8..86d2a70dd3de8329076d321331828d6e14fcd477 100644 (file)
 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;