From 4e63ed6b90803eeb400c392e9ff493200d926b06 Mon Sep 17 00:00:00 2001 From: Tomer Maimon Date: Sun, 7 Apr 2019 11:19:28 +0300 Subject: [PATCH 1/5] iio: adc: modify NPCM ADC read reference voltage Checking if regulator is valid before reading NPCM ADC regulator voltage to avoid system crash in a case the regulator is not valid. Signed-off-by: Tomer Maimon Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/npcm_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c index 9e25bbec9c70..193b3b81de4d 100644 --- a/drivers/iio/adc/npcm_adc.c +++ b/drivers/iio/adc/npcm_adc.c @@ -149,7 +149,7 @@ static int npcm_adc_read_raw(struct iio_dev *indio_dev, } return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - if (info->vref) { + if (!IS_ERR(info->vref)) { vref_uv = regulator_get_voltage(info->vref); *val = vref_uv / 1000; } else { From 0db8aa49a97e7f40852a64fd35abcc1292a7c365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Sun, 31 Mar 2019 20:54:23 +0200 Subject: [PATCH 2/5] iio: adc: ads124: avoid buffer overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When initializing the priv->data array starting from index 1, there is one less element to consider than when initializing the full array. Fixes: e717f8c6dfec8f76 ("iio: adc: Add the TI ads124s08 ADC code") Signed-off-by: Vincent Stehlé Reviewed-by: Mukesh Ojha Reviewed-by: Dan Murphy Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads124s08.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c index 53f17e4f2f23..552c2be8d87a 100644 --- a/drivers/iio/adc/ti-ads124s08.c +++ b/drivers/iio/adc/ti-ads124s08.c @@ -202,7 +202,7 @@ static int ads124s_read(struct iio_dev *indio_dev, unsigned int chan) }; priv->data[0] = ADS124S08_CMD_RDATA; - memset(&priv->data[1], ADS124S08_CMD_NOP, sizeof(priv->data)); + memset(&priv->data[1], ADS124S08_CMD_NOP, sizeof(priv->data) - 1); ret = spi_sync_transfer(priv->spi, t, ARRAY_SIZE(t)); if (ret < 0) From 1615fe41a1959a2ee2814ba62736b2bb54e9802a Mon Sep 17 00:00:00 2001 From: Steve Moskovchenko Date: Tue, 2 Apr 2019 23:28:56 -0700 Subject: [PATCH 3/5] iio: imu: mpu6050: Fix FIFO layout for ICM20602 The MPU6050 driver has recently gained support for the ICM20602 IMU, which is very similar to MPU6xxx. However, the ICM20602's FIFO data specifically includes temperature readings, which were not present on MPU6xxx parts. As a result, the driver will under-read the ICM20602's FIFO register, causing the same (partial) sample to be returned for all reads, until the FIFO overflows. Fix this by adding a table of scan elements specifically for the ICM20602, which takes the extra temperature data into consideration. While we're at it, fix the temperature offset and scaling on ICM20602, since it uses different scale/offset constants than the rest of the MPU6xxx devices. Signed-off-by: Steve Moskovchenko Fixes: 22904bdff978 ("iio: imu: mpu6050: Add support for the ICM 20602 IMU") Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 46 ++++++++++++++++++++-- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 20 +++++++++- drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 3 ++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 650de0fefb7b..385f14a4d5a7 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -471,7 +471,10 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: *val = 0; - *val2 = INV_MPU6050_TEMP_SCALE; + if (st->chip_type == INV_ICM20602) + *val2 = INV_ICM20602_TEMP_SCALE; + else + *val2 = INV_MPU6050_TEMP_SCALE; return IIO_VAL_INT_PLUS_MICRO; default: @@ -480,7 +483,10 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_OFFSET: switch (chan->type) { case IIO_TEMP: - *val = INV_MPU6050_TEMP_OFFSET; + if (st->chip_type == INV_ICM20602) + *val = INV_ICM20602_TEMP_OFFSET; + else + *val = INV_MPU6050_TEMP_OFFSET; return IIO_VAL_INT; default: @@ -845,6 +851,32 @@ static const struct iio_chan_spec inv_mpu_channels[] = { INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z), }; +static const struct iio_chan_spec inv_icm20602_channels[] = { + IIO_CHAN_SOFT_TIMESTAMP(INV_ICM20602_SCAN_TIMESTAMP), + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) + | BIT(IIO_CHAN_INFO_OFFSET) + | BIT(IIO_CHAN_INFO_SCALE), + .scan_index = INV_ICM20602_SCAN_TEMP, + .scan_type = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + .shift = 0, + .endianness = IIO_BE, + }, + }, + + INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_ICM20602_SCAN_GYRO_X), + INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_ICM20602_SCAN_GYRO_Y), + INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_ICM20602_SCAN_GYRO_Z), + + INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_ICM20602_SCAN_ACCL_Y), + INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_ICM20602_SCAN_ACCL_X), + INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_ICM20602_SCAN_ACCL_Z), +}; + /* * The user can choose any frequency between INV_MPU6050_MIN_FIFO_RATE and * INV_MPU6050_MAX_FIFO_RATE, but only these frequencies are matched by the @@ -1100,8 +1132,14 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, indio_dev->name = name; else indio_dev->name = dev_name(dev); - indio_dev->channels = inv_mpu_channels; - indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); + + if (chip_type == INV_ICM20602) { + indio_dev->channels = inv_icm20602_channels; + indio_dev->num_channels = ARRAY_SIZE(inv_icm20602_channels); + } else { + indio_dev->channels = inv_mpu_channels; + indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); + } indio_dev->info = &mpu_info; indio_dev->modes = INDIO_BUFFER_TRIGGERED; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index 325afd9f5f61..3d5fe4474378 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -208,6 +208,9 @@ struct inv_mpu6050_state { #define INV_MPU6050_BYTES_PER_3AXIS_SENSOR 6 #define INV_MPU6050_FIFO_COUNT_BYTE 2 +/* ICM20602 FIFO samples include temperature readings */ +#define INV_ICM20602_BYTES_PER_TEMP_SENSOR 2 + /* mpu6500 registers */ #define INV_MPU6500_REG_ACCEL_CONFIG_2 0x1D #define INV_MPU6500_REG_ACCEL_OFFSET 0x77 @@ -229,6 +232,9 @@ struct inv_mpu6050_state { #define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT 3 #define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT 3 +#define INV_ICM20602_TEMP_OFFSET 8170 +#define INV_ICM20602_TEMP_SCALE 3060 + /* 6 + 6 round up and plus 8 */ #define INV_MPU6050_OUTPUT_DATA_SIZE 24 @@ -270,7 +276,7 @@ struct inv_mpu6050_state { #define INV_ICM20608_WHOAMI_VALUE 0xAF #define INV_ICM20602_WHOAMI_VALUE 0x12 -/* scan element definition */ +/* scan element definition for generic MPU6xxx devices */ enum inv_mpu6050_scan { INV_MPU6050_SCAN_ACCL_X, INV_MPU6050_SCAN_ACCL_Y, @@ -281,6 +287,18 @@ enum inv_mpu6050_scan { INV_MPU6050_SCAN_TIMESTAMP, }; +/* scan element definition for ICM20602, which includes temperature */ +enum inv_icm20602_scan { + INV_ICM20602_SCAN_ACCL_X, + INV_ICM20602_SCAN_ACCL_Y, + INV_ICM20602_SCAN_ACCL_Z, + INV_ICM20602_SCAN_TEMP, + INV_ICM20602_SCAN_GYRO_X, + INV_ICM20602_SCAN_GYRO_Y, + INV_ICM20602_SCAN_GYRO_Z, + INV_ICM20602_SCAN_TIMESTAMP, +}; + enum inv_mpu6050_filter_e { INV_MPU6050_FILTER_256HZ_NOLPF2 = 0, INV_MPU6050_FILTER_188HZ, diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index 548e042f7b5b..57bd11bde56b 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -207,6 +207,9 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) if (st->chip_config.gyro_fifo_enable) bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR; + if (st->chip_type == INV_ICM20602) + bytes_per_datum += INV_ICM20602_BYTES_PER_TEMP_SENSOR; + /* * read fifo_count register to know how many bytes are inside the FIFO * right now From 60f2208699ec08ff9fdf1f97639a661a92a18f1c Mon Sep 17 00:00:00 2001 From: Ruslan Babayev Date: Sun, 5 May 2019 12:24:37 -0700 Subject: [PATCH 4/5] iio: dac: ds4422/ds4424 fix chip verification The ds4424_get_value function takes channel number as it's 3rd argument and translates it internally into I2C address using DS4424_DAC_ADDR macro. The caller ds4424_verify_chip was passing an already translated I2C address as its last argument. Signed-off-by: Ruslan Babayev Cc: xe-linux-external@cisco.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ds4424.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c index 883a47562055..714a97f91319 100644 --- a/drivers/iio/dac/ds4424.c +++ b/drivers/iio/dac/ds4424.c @@ -166,7 +166,7 @@ static int ds4424_verify_chip(struct iio_dev *indio_dev) { int ret, val; - ret = ds4424_get_value(indio_dev, &val, DS4424_DAC_ADDR(0)); + ret = ds4424_get_value(indio_dev, &val, 0); if (ret < 0) dev_err(&indio_dev->dev, "%s failed. ret: %d\n", __func__, ret); From e6d12298310fa1dc11f1d747e05b168016057fdd Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Tue, 7 May 2019 10:23:04 +0200 Subject: [PATCH 5/5] iio: adc: ti-ads8688: fix timestamp is not updated in buffer When using the hrtimer iio trigger timestamp isn't updated. If we use iio_get_time_ns it is updated correctly. Fixes: 2a86487786b5c ("iio: adc: ti-ads8688: add trigger and buffer support") Signed-off-by: Sean Nyekjaer Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads8688.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 8b4568edd5cb..7f16c77b99fb 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c @@ -397,7 +397,7 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p) } iio_push_to_buffers_with_timestamp(indio_dev, buffer, - pf->timestamp); + iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig);