Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8216ef62 authored by Puneet Yatnal's avatar Puneet Yatnal Committed by Gerrit - the friendly Code Review server
Browse files

driver: iio: imu: Fixed minor bugs of ASM330 sensor



Fixed NULL pointer dereference of sensor ASM330 in initalization
of early buffer feature and avoid writing to any syfs entry from
userspace while buffering sensor data because which leads
to buffer data loss.
Fixed the initial values of gyro is high in early buffer data
because sensor not initialized properly. Its expected to have
delay after each write and fix order of config as well.

Change-Id: I0f5ddc7b0b485c256ec1401f1ac83431c8f67493
Signed-off-by: default avatarPuneet Yatnal <puneet@codeaurora.org>
parent e68392dd
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ static void store_acc_gyro_boot_sample(struct st_asm330lhh_sensor *sensor,
static int st_asm330lhh_read_fifo(struct st_asm330lhh_hw *hw)
{
	u8 iio_buf[ALIGN(ST_ASM330LHH_SAMPLE_SIZE, sizeof(s64)) + sizeof(s64)];
	u8 buf[6 * ST_ASM330LHH_FIFO_SAMPLE_SIZE], tag, *ptr;
	u8 buf[30 * ST_ASM330LHH_FIFO_SAMPLE_SIZE], tag, *ptr;
	s64 ts_delta_hw_ts = 0, ts_irq;
	s64 ts_delta_offs;
	int i, err, read_len, word_len, fifo_len;
@@ -374,7 +374,7 @@ ssize_t st_asm330lhh_set_watermark(struct device *dev,
	int err, val;

	if (asm330_check_acc_gyro_early_buff_enable_flag(sensor))
		return 0;
		return -EBUSY;

	mutex_lock(&iio_dev->mlock);
	if (iio_buffer_enabled(iio_dev)) {
@@ -504,10 +504,9 @@ static irqreturn_t st_asm330lhh_handler_thread(int irq, void *private)
static int st_asm330lhh_buffer_preenable(struct iio_dev *iio_dev)
{
	struct st_asm330lhh_sensor *sensor = iio_priv(iio_dev);
	int err = -1;

	if (asm330_check_acc_gyro_early_buff_enable_flag(sensor))
		return err;
		return 0;
	else
		return st_asm330lhh_update_fifo(iio_dev, true);
}
@@ -515,10 +514,9 @@ static int st_asm330lhh_buffer_preenable(struct iio_dev *iio_dev)
static int st_asm330lhh_buffer_postdisable(struct iio_dev *iio_dev)
{
	struct st_asm330lhh_sensor *sensor = iio_priv(iio_dev);
	int err = -1;

	if (asm330_check_acc_gyro_early_buff_enable_flag(sensor))
		return err;
		return 0;
	else
		return st_asm330lhh_update_fifo(iio_dev, false);
}
+36 −22
Original line number Diff line number Diff line
@@ -324,7 +324,7 @@ static int st_asm330lhh_read_oneshot(struct st_asm330lhh_sensor *sensor,
				     u8 addr, int *val)
{
	int err, delay;
	__le16 data;
	__le16 data = 0;

	if (sensor->id == ST_ASM330LHH_ID_TEMP) {
		u8 status;
@@ -841,6 +841,7 @@ static void st_asm330lhh_enable_acc_gyro(struct st_asm330lhh_hw *hw)
	struct st_asm330lhh_sensor *sensor;
	int  acc_gain = ST_ASM330LHH_ACC_FS_2G_GAIN;
	int  gyro_gain = ST_ASM330LHH_GYRO_FS_125_GAIN;
	int  delay;

	for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
		if (!hw->iio_devs[i])
@@ -848,16 +849,29 @@ static void st_asm330lhh_enable_acc_gyro(struct st_asm330lhh_hw *hw)
		sensor = iio_priv(hw->iio_devs[i]);
		sensor->odr = 104;
		sensor->watermark = 30;
		st_asm330lhh_update_fifo(hw->iio_devs[i], false);
		delay = 1000000 / sensor->odr;

		if (sensor->id == ST_ASM330LHH_ID_ACC)
		if (sensor->id == ST_ASM330LHH_ID_ACC) {
			st_asm330lhh_set_full_scale(sensor, acc_gain);
		else if (sensor->id == ST_ASM330LHH_ID_GYRO)
			usleep_range(delay, 2 * delay);
			st_asm330lhh_set_odr(sensor, sensor->odr);
			usleep_range(delay, 2 * delay);
			st_asm330lhh_update_watermark(sensor,
					sensor->watermark);
			usleep_range(delay, 2 * delay);
			st_asm330lhh_update_fifo(hw->iio_devs[i], true);
			usleep_range(delay, 2 * delay);
		} else if (sensor->id == ST_ASM330LHH_ID_GYRO) {
			st_asm330lhh_set_full_scale(sensor, gyro_gain);

		st_asm330lhh_update_watermark(sensor, sensor->watermark);

			usleep_range(delay, 2 * delay);
			st_asm330lhh_set_odr(sensor, sensor->odr);
			usleep_range(delay, 2 * delay);
			st_asm330lhh_update_watermark(sensor,
					sensor->watermark);
			usleep_range(delay, 2 * delay);
			st_asm330lhh_update_fifo(hw->iio_devs[i], true);
			usleep_range(delay, 2 * delay);
		}
	}
}

@@ -885,7 +899,7 @@ static int asm330_acc_gyro_early_buff_init(struct st_asm330lhh_hw *hw)
		dev_err(hw->dev,
				"asm_acc_cachepool cache create failed\n");
		err = -ENOMEM;
		goto clean_exit1;
		return 0;
	}

	for (i = 0; i < ASM_MAXSAMPLE; i++) {
@@ -894,7 +908,7 @@ static int asm330_acc_gyro_early_buff_init(struct st_asm330lhh_hw *hw)
					GFP_KERNEL);
		if (!acc->asm_samplist[i]) {
			err = -ENOMEM;
			goto clean_exit2;
			goto clean_exit1;
		}
	}

@@ -905,7 +919,7 @@ static int asm330_acc_gyro_early_buff_init(struct st_asm330lhh_hw *hw)
		dev_err(hw->dev,
				"asm_gyro_cachepool cache create failed\n");
		err = -ENOMEM;
		goto clean_exit3;
		goto clean_exit1;
	}

	for (i = 0; i < ASM_MAXSAMPLE; i++) {
@@ -914,7 +928,7 @@ static int asm330_acc_gyro_early_buff_init(struct st_asm330lhh_hw *hw)
					GFP_KERNEL);
		if (!gyro->asm_samplist[i]) {
			err = -ENOMEM;
			goto clean_exit4;
			goto clean_exit2;
		}
	}

@@ -922,7 +936,7 @@ static int asm330_acc_gyro_early_buff_init(struct st_asm330lhh_hw *hw)
	if (!acc->buf_dev) {
		err = -ENOMEM;
		dev_err(hw->dev, "input device allocation failed\n");
		goto clean_exit5;
		goto clean_exit2;
	}
	acc->buf_dev->name = "asm_accbuf";
	acc->buf_dev->id.bustype = BUS_I2C;
@@ -944,14 +958,14 @@ static int asm330_acc_gyro_early_buff_init(struct st_asm330lhh_hw *hw)
		dev_err(hw->dev,
				"unable to register input device %s\n",
				acc->buf_dev->name);
		goto clean_exit5;
		goto clean_exit3;
	}

	gyro->buf_dev = input_allocate_device();
	if (!gyro->buf_dev) {
		err = -ENOMEM;
		dev_err(hw->dev, "input device allocation failed\n");
		goto clean_exit6;
		goto clean_exit4;
	}
	gyro->buf_dev->name = "asm_gyrobuf";
	gyro->buf_dev->id.bustype = BUS_I2C;
@@ -973,30 +987,30 @@ static int asm330_acc_gyro_early_buff_init(struct st_asm330lhh_hw *hw)
		dev_err(hw->dev,
				"unable to register input device %s\n",
				gyro->buf_dev->name);
		goto clean_exit6;
		goto clean_exit5;
	}

	acc->buffer_asm_samples = true;
	gyro->buffer_asm_samples = true;

	return 1;
clean_exit6:
clean_exit5:
	input_free_device(gyro->buf_dev);
clean_exit4:
	input_unregister_device(acc->buf_dev);
clean_exit5:
clean_exit3:
	input_free_device(acc->buf_dev);
clean_exit4:
clean_exit2:
	for (i = 0; i < ASM_MAXSAMPLE; i++)
		kmem_cache_free(gyro->asm_cachepool,
				gyro->asm_samplist[i]);
clean_exit3:
	kmem_cache_destroy(gyro->asm_cachepool);
clean_exit2:
clean_exit1:
	for (i = 0; i < ASM_MAXSAMPLE; i++)
		kmem_cache_free(acc->asm_cachepool,
				acc->asm_samplist[i]);
clean_exit1:
	kmem_cache_destroy(acc->asm_cachepool);

	return 0;
}
#else