| From 1b376de46bc205790e7157277ad01afeb537fab8 Mon Sep 17 00:00:00 2001 |
| From: Andreas Klinger <ak@it-klinger.de> |
| Date: Mon, 9 Sep 2019 14:37:21 +0200 |
| Subject: [PATCH] iio: adc: hx711: fix bug in sampling of data |
| |
| commit 4043ecfb5fc4355a090111e14faf7945ff0fdbd5 upstream. |
| |
| Fix bug in sampling function hx711_cycle() when interrupt occures while |
| PD_SCK is high. If PD_SCK is high for at least 60 us power down mode of |
| the sensor is entered which in turn leads to a wrong measurement. |
| |
| Switch off interrupts during a PD_SCK high period and move query of DOUT |
| to the latest point of time which is at the end of PD_SCK low period. |
| |
| This bug exists in the driver since it's initial addition. The more |
| interrupts on the system the higher is the probability that it happens. |
| |
| Fixes: c3b2fdd0ea7e ("iio: adc: hx711: Add IIO driver for AVIA HX711") |
| Signed-off-by: Andreas Klinger <ak@it-klinger.de> |
| Cc: <Stable@vger.kernel.org> |
| Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c |
| index 88c7fe15003b..62e6c8badd22 100644 |
| --- a/drivers/iio/adc/hx711.c |
| +++ b/drivers/iio/adc/hx711.c |
| @@ -100,14 +100,14 @@ struct hx711_data { |
| |
| static int hx711_cycle(struct hx711_data *hx711_data) |
| { |
| - int val; |
| + unsigned long flags; |
| |
| /* |
| * if preempted for more then 60us while PD_SCK is high: |
| * hx711 is going in reset |
| * ==> measuring is false |
| */ |
| - preempt_disable(); |
| + local_irq_save(flags); |
| gpiod_set_value(hx711_data->gpiod_pd_sck, 1); |
| |
| /* |
| @@ -117,7 +117,6 @@ static int hx711_cycle(struct hx711_data *hx711_data) |
| */ |
| ndelay(hx711_data->data_ready_delay_ns); |
| |
| - val = gpiod_get_value(hx711_data->gpiod_dout); |
| /* |
| * here we are not waiting for 0.2 us as suggested by the datasheet, |
| * because the oscilloscope showed in a test scenario |
| @@ -125,7 +124,7 @@ static int hx711_cycle(struct hx711_data *hx711_data) |
| * and 0.56 us for PD_SCK low on TI Sitara with 800 MHz |
| */ |
| gpiod_set_value(hx711_data->gpiod_pd_sck, 0); |
| - preempt_enable(); |
| + local_irq_restore(flags); |
| |
| /* |
| * make it a square wave for addressing cases with capacitance on |
| @@ -133,7 +132,8 @@ static int hx711_cycle(struct hx711_data *hx711_data) |
| */ |
| ndelay(hx711_data->data_ready_delay_ns); |
| |
| - return val; |
| + /* sample as late as possible */ |
| + return gpiod_get_value(hx711_data->gpiod_dout); |
| } |
| |
| static int hx711_read(struct hx711_data *hx711_data) |
| -- |
| 2.7.4 |
| |