Commit fe4c5939 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-fixes-for-5.4b' of...

Merge tag 'iio-fixes-for-5.4b' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus

Second set of IIO fixes for the 5.4 cycle.

* adis16480
  - Prevent negative numbers being accepted for sampling frequency.
* inv_mpu6050
  - Fix an issue where fifo overflow bits don't actually work as expected,
    by checking the fifo count instead.
* srf04
  - Allow more time for echo to signal as some sensors supported have
    a higher range.
* stm32-adc
  - Fix a potential race in dma disable by ensuring all transfers are done.

* tag 'iio-fixes-for-5.4b' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio:
  iio: adc: stm32-adc: fix stopping dma
  iio: imu: inv_mpu6050: fix no data on MPU6050
  iio: srf04: fix wrong limitation in distance measuring
  iio: imu: adis16480: make sure provided frequency is positive
parents df402865 e6afcf6c
...@@ -1399,7 +1399,7 @@ static int stm32_adc_dma_start(struct iio_dev *indio_dev) ...@@ -1399,7 +1399,7 @@ static int stm32_adc_dma_start(struct iio_dev *indio_dev)
cookie = dmaengine_submit(desc); cookie = dmaengine_submit(desc);
ret = dma_submit_error(cookie); ret = dma_submit_error(cookie);
if (ret) { if (ret) {
dmaengine_terminate_all(adc->dma_chan); dmaengine_terminate_sync(adc->dma_chan);
return ret; return ret;
} }
...@@ -1477,7 +1477,7 @@ static void __stm32_adc_buffer_predisable(struct iio_dev *indio_dev) ...@@ -1477,7 +1477,7 @@ static void __stm32_adc_buffer_predisable(struct iio_dev *indio_dev)
stm32_adc_conv_irq_disable(adc); stm32_adc_conv_irq_disable(adc);
if (adc->dma_chan) if (adc->dma_chan)
dmaengine_terminate_all(adc->dma_chan); dmaengine_terminate_sync(adc->dma_chan);
if (stm32_adc_set_trig(indio_dev, NULL)) if (stm32_adc_set_trig(indio_dev, NULL))
dev_err(&indio_dev->dev, "Can't clear trigger\n"); dev_err(&indio_dev->dev, "Can't clear trigger\n");
......
...@@ -317,8 +317,11 @@ static int adis16480_set_freq(struct iio_dev *indio_dev, int val, int val2) ...@@ -317,8 +317,11 @@ static int adis16480_set_freq(struct iio_dev *indio_dev, int val, int val2)
struct adis16480 *st = iio_priv(indio_dev); struct adis16480 *st = iio_priv(indio_dev);
unsigned int t, reg; unsigned int t, reg;
if (val < 0 || val2 < 0)
return -EINVAL;
t = val * 1000 + val2 / 1000; t = val * 1000 + val2 / 1000;
if (t <= 0) if (t == 0)
return -EINVAL; return -EINVAL;
/* /*
......
...@@ -114,54 +114,63 @@ static const struct inv_mpu6050_hw hw_info[] = { ...@@ -114,54 +114,63 @@ static const struct inv_mpu6050_hw hw_info[] = {
.name = "MPU6050", .name = "MPU6050",
.reg = &reg_set_6050, .reg = &reg_set_6050,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 1024,
}, },
{ {
.whoami = INV_MPU6500_WHOAMI_VALUE, .whoami = INV_MPU6500_WHOAMI_VALUE,
.name = "MPU6500", .name = "MPU6500",
.reg = &reg_set_6500, .reg = &reg_set_6500,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 512,
}, },
{ {
.whoami = INV_MPU6515_WHOAMI_VALUE, .whoami = INV_MPU6515_WHOAMI_VALUE,
.name = "MPU6515", .name = "MPU6515",
.reg = &reg_set_6500, .reg = &reg_set_6500,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 512,
}, },
{ {
.whoami = INV_MPU6000_WHOAMI_VALUE, .whoami = INV_MPU6000_WHOAMI_VALUE,
.name = "MPU6000", .name = "MPU6000",
.reg = &reg_set_6050, .reg = &reg_set_6050,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 1024,
}, },
{ {
.whoami = INV_MPU9150_WHOAMI_VALUE, .whoami = INV_MPU9150_WHOAMI_VALUE,
.name = "MPU9150", .name = "MPU9150",
.reg = &reg_set_6050, .reg = &reg_set_6050,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 1024,
}, },
{ {
.whoami = INV_MPU9250_WHOAMI_VALUE, .whoami = INV_MPU9250_WHOAMI_VALUE,
.name = "MPU9250", .name = "MPU9250",
.reg = &reg_set_6500, .reg = &reg_set_6500,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 512,
}, },
{ {
.whoami = INV_MPU9255_WHOAMI_VALUE, .whoami = INV_MPU9255_WHOAMI_VALUE,
.name = "MPU9255", .name = "MPU9255",
.reg = &reg_set_6500, .reg = &reg_set_6500,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 512,
}, },
{ {
.whoami = INV_ICM20608_WHOAMI_VALUE, .whoami = INV_ICM20608_WHOAMI_VALUE,
.name = "ICM20608", .name = "ICM20608",
.reg = &reg_set_6500, .reg = &reg_set_6500,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 512,
}, },
{ {
.whoami = INV_ICM20602_WHOAMI_VALUE, .whoami = INV_ICM20602_WHOAMI_VALUE,
.name = "ICM20602", .name = "ICM20602",
.reg = &reg_set_icm20602, .reg = &reg_set_icm20602,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 1008,
}, },
}; };
......
...@@ -100,12 +100,14 @@ struct inv_mpu6050_chip_config { ...@@ -100,12 +100,14 @@ struct inv_mpu6050_chip_config {
* @name: name of the chip. * @name: name of the chip.
* @reg: register map of the chip. * @reg: register map of the chip.
* @config: configuration of the chip. * @config: configuration of the chip.
* @fifo_size: size of the FIFO in bytes.
*/ */
struct inv_mpu6050_hw { struct inv_mpu6050_hw {
u8 whoami; u8 whoami;
u8 *name; u8 *name;
const struct inv_mpu6050_reg_map *reg; const struct inv_mpu6050_reg_map *reg;
const struct inv_mpu6050_chip_config *config; const struct inv_mpu6050_chip_config *config;
size_t fifo_size;
}; };
/* /*
......
...@@ -180,9 +180,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) ...@@ -180,9 +180,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
"failed to ack interrupt\n"); "failed to ack interrupt\n");
goto flush_fifo; goto flush_fifo;
} }
/* handle fifo overflow by reseting fifo */
if (int_status & INV_MPU6050_BIT_FIFO_OVERFLOW_INT)
goto flush_fifo;
if (!(int_status & INV_MPU6050_BIT_RAW_DATA_RDY_INT)) { if (!(int_status & INV_MPU6050_BIT_RAW_DATA_RDY_INT)) {
dev_warn(regmap_get_device(st->map), dev_warn(regmap_get_device(st->map),
"spurious interrupt with status 0x%x\n", int_status); "spurious interrupt with status 0x%x\n", int_status);
...@@ -211,6 +208,18 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) ...@@ -211,6 +208,18 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
if (result) if (result)
goto end_session; goto end_session;
fifo_count = get_unaligned_be16(&data[0]); fifo_count = get_unaligned_be16(&data[0]);
/*
* Handle fifo overflow by resetting fifo.
* Reset if there is only 3 data set free remaining to mitigate
* possible delay between reading fifo count and fifo data.
*/
nb = 3 * bytes_per_datum;
if (fifo_count >= st->hw->fifo_size - nb) {
dev_warn(regmap_get_device(st->map), "fifo overflow reset\n");
goto flush_fifo;
}
/* compute and process all complete datum */ /* compute and process all complete datum */
nb = fifo_count / bytes_per_datum; nb = fifo_count / bytes_per_datum;
inv_mpu6050_update_period(st, pf->timestamp, nb); inv_mpu6050_update_period(st, pf->timestamp, nb);
......
...@@ -110,7 +110,7 @@ static int srf04_read(struct srf04_data *data) ...@@ -110,7 +110,7 @@ static int srf04_read(struct srf04_data *data)
udelay(data->cfg->trigger_pulse_us); udelay(data->cfg->trigger_pulse_us);
gpiod_set_value(data->gpiod_trig, 0); 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); ret = wait_for_completion_killable_timeout(&data->rising, HZ/50);
if (ret < 0) { if (ret < 0) {
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
...@@ -120,7 +120,8 @@ static int srf04_read(struct srf04_data *data) ...@@ -120,7 +120,8 @@ static int srf04_read(struct srf04_data *data)
return -ETIMEDOUT; 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) { if (ret < 0) {
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
return ret; return ret;
...@@ -135,19 +136,19 @@ static int srf04_read(struct srf04_data *data) ...@@ -135,19 +136,19 @@ static int srf04_read(struct srf04_data *data)
dt_ns = ktime_to_ns(ktime_dt); dt_ns = ktime_to_ns(ktime_dt);
/* /*
* measuring more than 3 meters is beyond the capabilities of * measuring more than 6,45 meters is beyond the capabilities of
* the sensor * the supported sensors
* ==> filter out invalid results for not measuring echos of * ==> filter out invalid results for not measuring echos of
* another us sensor * another us sensor
* *
* formula: * formula:
* distance 3 m * distance 6,45 * 2 m
* time = ---------- = --------- = 9404389 ns * time = ---------- = ------------ = 40438871 ns
* speed 319 m/s * speed 319 m/s
* *
* using a minimum speed at -20 °C of 319 m/s * using a minimum speed at -20 °C of 319 m/s
*/ */
if (dt_ns > 9404389) if (dt_ns > 40438871)
return -EIO; return -EIO;
time_ns = dt_ns; time_ns = dt_ns;
...@@ -159,20 +160,20 @@ static int srf04_read(struct srf04_data *data) ...@@ -159,20 +160,20 @@ static int srf04_read(struct srf04_data *data)
* with Temp in °C * with Temp in °C
* and speed in m/s * 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 * temperature
* *
* therefore: * therefore:
* time 343 * time 343,5 time * 106
* distance = ------ * ----- * distance = ------ * ------- = ------------
* 10^6 2 * 10^6 2 617176
* with time in ns * with time in ns
* and distance in mm (one way) * 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 * fits into 32 bit
*/ */
distance_mm = time_ns * 343 / 2000000; distance_mm = time_ns * 106 / 617176;
return distance_mm; return distance_mm;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment