[PATCH 4.19 035/125] iio: srf04: fix wrong limitation in distance measuring

From: Greg Kroah-Hartman
Date: Mon Nov 11 2019 - 13:44:45 EST


From: Andreas Klinger <ak@xxxxxxxxxxxxx>

commit 431f7667bd6889a274913162dfd19cce9d84848e upstream.

The measured time value in the driver is limited to the maximum distance
which can be read by the sensor. This limitation was wrong and is fixed
by this patch.

It also takes into account that we are supporting a variety of sensors
today and that the recently added sensors have a higher maximum
distance range.

Changes in v2:
- Added a Tested-by

Suggested-by: ZbynÄk Kocur <zbynek.kocur@xxxxxxxxxxx>
Tested-by: ZbynÄk Kocur <zbynek.kocur@xxxxxxxxxxx>
Signed-off-by: Andreas Klinger <ak@xxxxxxxxxxxxx>
Cc:<Stable@xxxxxxxxxxxxxxx>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/iio/proximity/srf04.c | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)

--- a/drivers/iio/proximity/srf04.c
+++ b/drivers/iio/proximity/srf04.c
@@ -105,7 +105,7 @@ static int srf04_read(struct srf04_data
udelay(10);
gpiod_set_value(data->gpiod_trig, 0);

- /* it cannot take more than 20 ms */
+ /* it should not take more than 20 ms until echo is rising */
ret = wait_for_completion_killable_timeout(&data->rising, HZ/50);
if (ret < 0) {
mutex_unlock(&data->lock);
@@ -115,7 +115,8 @@ static int srf04_read(struct srf04_data
return -ETIMEDOUT;
}

- ret = wait_for_completion_killable_timeout(&data->falling, HZ/50);
+ /* it cannot take more than 50 ms until echo is falling */
+ ret = wait_for_completion_killable_timeout(&data->falling, HZ/20);
if (ret < 0) {
mutex_unlock(&data->lock);
return ret;
@@ -130,19 +131,19 @@ static int srf04_read(struct srf04_data

dt_ns = ktime_to_ns(ktime_dt);
/*
- * measuring more than 3 meters is beyond the capabilities of
- * the sensor
+ * measuring more than 6,45 meters is beyond the capabilities of
+ * the supported sensors
* ==> filter out invalid results for not measuring echos of
* another us sensor
*
* formula:
- * distance 3 m
- * time = ---------- = --------- = 9404389 ns
- * speed 319 m/s
+ * distance 6,45 * 2 m
+ * time = ---------- = ------------ = 40438871 ns
+ * speed 319 m/s
*
* using a minimum speed at -20 ÂC of 319 m/s
*/
- if (dt_ns > 9404389)
+ if (dt_ns > 40438871)
return -EIO;

time_ns = dt_ns;
@@ -154,20 +155,20 @@ static int srf04_read(struct srf04_data
* with Temp in ÂC
* and speed in m/s
*
- * use 343 m/s as ultrasonic speed at 20 ÂC here in absence of the
+ * use 343,5 m/s as ultrasonic speed at 20 ÂC here in absence of the
* temperature
*
* therefore:
- * time 343
- * distance = ------ * -----
- * 10^6 2
+ * time 343,5 time * 106
+ * distance = ------ * ------- = ------------
+ * 10^6 2 617176
* with time in ns
* and distance in mm (one way)
*
- * because we limit to 3 meters the multiplication with 343 just
+ * because we limit to 6,45 meters the multiplication with 106 just
* fits into 32 bit
*/
- distance_mm = time_ns * 343 / 2000000;
+ distance_mm = time_ns * 106 / 617176;

return distance_mm;
}