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

Commit c34e2b01 authored by Puneet yatnala's avatar Puneet yatnala
Browse files

driver: iio: imu: IAM20680 early buff implemented



This patch allows to buffer IAM20680 accel and gyro samples from driver
up to time till user space services are up and running
(or upto nth second). Buffered samples can be retrived at any time via
input subsystem by writing to below sysfs entry.

echo 1 > /sys/bus/iio/devices/iio:device0/read_acc_boot_sample
echo 1 > /sys/bus/iio/devices/iio:device0/read_gyro_boot_sample

Use config option to enable buffering feature.

Change-Id: Ic13cd2032a2f7bad3f1cde0f0b01eae88e6f819f
Signed-off-by: default avatarPuneet yatnala <puneet@codeaurora.org>
parent e4a4d8bb
Loading
Loading
Loading
Loading
+204 −2
Original line number Diff line number Diff line
@@ -311,6 +311,26 @@ static int _misc_attr_store(struct device *dev,
	return result;
}

#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
static inline int inv_check_acc_gyro_early_buff_enable_flag(
		struct iio_dev *indio_dev)
{
	struct inv_mpu_state *st = iio_priv(indio_dev);

	if (st->acc_buffer_inv_samples == true ||
			st->gyro_buffer_inv_samples == true)
		return 1;
	else
		return 0;
}
#else
static inline int inv_check_acc_gyro_early_buff_enable_flag(
		struct iio_dev *indio_dev)
{
	return 0;
}
#endif

/*
 * inv_misc_attr_store() -  calling this function
 */
@@ -321,6 +341,9 @@ static ssize_t inv_misc_attr_store(struct device *dev,
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	int result;

	if (inv_check_acc_gyro_early_buff_enable_flag(indio_dev))
		return count;

	mutex_lock(&indio_dev->mlock);
	result = _misc_attr_store(dev, attr, buf, count);
	mutex_unlock(&indio_dev->mlock);
@@ -351,6 +374,9 @@ static ssize_t inv_sensor_rate_store(struct device *dev,
	int data, rate, ind;
	int result;

	if (inv_check_acc_gyro_early_buff_enable_flag(indio_dev))
		return count;

	result = kstrtoint(buf, 10, &data);
	if (result)
		return -EINVAL;
@@ -398,6 +424,9 @@ static ssize_t inv_sensor_on_store(struct device *dev,
	int data, on, ind;
	int result;

	if (inv_check_acc_gyro_early_buff_enable_flag(indio_dev))
		return count;

	result = kstrtoint(buf, 10, &data);
	if (result)
		return -EINVAL;
@@ -493,7 +522,7 @@ static int _basic_attr_store(struct device *dev,
			p1[0] = ((power_on_data >> 16) & 0xff);
			p1[1] = ((power_on_data >> 24) & 0xff);

			if (st->bus_type == BUS_SPI) {
			if (st->bus_type == BUS_IIO_SPI) {
				struct spi_transfer power_on;
				struct spi_message msg;

@@ -508,7 +537,7 @@ static int _basic_attr_store(struct device *dev,
				spi_message_add_tail(&power_on, &msg);
				spi_sync(to_spi_device(st->dev), &msg);

			} else if (st->bus_type == BUS_I2C) {
			} else if (st->bus_type == BUS_IIO_I2C) {
				struct i2c_msg msgs[2];

				p0[0] &= 0x7f;
@@ -771,6 +800,169 @@ static ssize_t inv_flush_batch_store(struct device *dev,
	return count;
}

#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
static int inv_gyro_read_bootsampl(struct inv_mpu_state *st,
		unsigned long enable_read)
{
	int i = 0;

	if (enable_read) {
		st->gyro_buffer_inv_samples = false;
		for (i = 0; i < st->gyro_bufsample_cnt; i++) {
			dev_dbg(st->dev, "gyro_cnt=%d,x=%d,y=%d,z=%d,tsec=%d,nsec=%lld\n",
					i, st->inv_gyro_samplist[i]->xyz[0],
					st->inv_gyro_samplist[i]->xyz[1],
					st->inv_gyro_samplist[i]->xyz[2],
					st->inv_gyro_samplist[i]->tsec,
					st->inv_gyro_samplist[i]->tnsec);
			input_report_abs(st->gyrobuf_dev, ABS_X,
					st->inv_gyro_samplist[i]->xyz[0]);
			input_report_abs(st->gyrobuf_dev, ABS_Y,
					st->inv_gyro_samplist[i]->xyz[1]);
			input_report_abs(st->gyrobuf_dev, ABS_Z,
					st->inv_gyro_samplist[i]->xyz[2]);
			input_report_abs(st->gyrobuf_dev, ABS_RX,
					st->inv_gyro_samplist[i]->tsec);
			input_report_abs(st->gyrobuf_dev, ABS_RY,
					st->inv_gyro_samplist[i]->tnsec);
			input_sync(st->gyrobuf_dev);
		}
	} else {
		/* clean up */
		if (st->gyro_bufsample_cnt != 0) {
			for (i = 0; i < INV_GYRO_MAXSAMPLE; i++)
				kmem_cache_free(st->inv_gyro_cachepool,
						st->inv_gyro_samplist[i]);
			kmem_cache_destroy(st->inv_gyro_cachepool);
			st->gyro_bufsample_cnt = 0;
		}

	}
	/*SYN_CONFIG indicates end of data*/
	input_event(st->gyrobuf_dev, EV_SYN, SYN_CONFIG, 0xFFFFFFFF);
	input_sync(st->gyrobuf_dev);
	dev_dbg(st->dev, "End of gyro samples bufsample_cnt=%d\n",
			st->gyro_bufsample_cnt);
	return 0;
}
static int inv_acc_read_bootsampl(struct inv_mpu_state *st,
		unsigned long enable_read)
{
	int i = 0;

	if (enable_read) {
		st->acc_buffer_inv_samples = false;
		for (i = 0; i < st->acc_bufsample_cnt; i++) {
			dev_dbg(st->dev, "acc_cnt=%d,x=%d,y=%d,z=%d,tsec=%d,nsec=%lld\n",
					i, st->inv_acc_samplist[i]->xyz[0],
					st->inv_acc_samplist[i]->xyz[1],
					st->inv_acc_samplist[i]->xyz[2],
					st->inv_acc_samplist[i]->tsec,
					st->inv_acc_samplist[i]->tnsec);
			input_report_abs(st->accbuf_dev, ABS_X,
					st->inv_acc_samplist[i]->xyz[0]);
			input_report_abs(st->accbuf_dev, ABS_Y,
					st->inv_acc_samplist[i]->xyz[1]);
			input_report_abs(st->accbuf_dev, ABS_Z,
					st->inv_acc_samplist[i]->xyz[2]);
			input_report_abs(st->accbuf_dev, ABS_RX,
					st->inv_acc_samplist[i]->tsec);
			input_report_abs(st->accbuf_dev, ABS_RY,
					st->inv_acc_samplist[i]->tnsec);
			input_sync(st->accbuf_dev);
		}
	} else {
		/* clean up */
		if (st->acc_bufsample_cnt != 0) {
			for (i = 0; i < INV_ACC_MAXSAMPLE; i++)
				kmem_cache_free(st->inv_acc_cachepool,
						st->inv_acc_samplist[i]);
			kmem_cache_destroy(st->inv_acc_cachepool);
			st->acc_bufsample_cnt = 0;
		}

	}
	/*SYN_CONFIG indicates end of data*/
	input_event(st->accbuf_dev, EV_SYN, SYN_CONFIG, 0xFFFFFFFF);
	input_sync(st->accbuf_dev);
	dev_dbg(st->dev, "End of acc samples bufsample_cnt=%d\n",
			st->acc_bufsample_cnt);
	return 0;
}

static ssize_t read_gyro_boot_sample_show(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct inv_mpu_state *st = iio_priv(indio_dev);

	return snprintf(buf, MAX_WR_SZ, "%d\n",
			st->read_gyro_boot_sample);
}

static ssize_t read_gyro_boot_sample_store(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t count)
{
	int err;
	unsigned long enable = 0;

	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct inv_mpu_state *st = iio_priv(indio_dev);

	err = kstrtoul(buf, 10, &enable);
	if (err)
		return err;
	if (enable > 1) {
		err = dev_err(st->dev,
				"Invalid value of input, input=%ld\n", enable);
		return -EINVAL;
	}
	err = inv_gyro_read_bootsampl(st, enable);
	if (err)
		return err;
	st->read_gyro_boot_sample = enable;
	return count;

}

static ssize_t read_acc_boot_sample_show(struct device *dev,
		struct device_attribute *attr,
		char *buf)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct inv_mpu_state *st = iio_priv(indio_dev);

	return snprintf(buf, MAX_WR_SZ, "%d\n",
			st->read_acc_boot_sample);
}
static ssize_t read_acc_boot_sample_store(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t count)
{
	int err;
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct inv_mpu_state *st = iio_priv(indio_dev);

	unsigned long enable = 0;

	err = kstrtoul(buf, 10, &enable);
	if (err)
		return err;
	if (enable > 1) {
		err = dev_err(st->dev,
				"Invalid value of input, input=%ld\n", enable);
		return -EINVAL;
	}
	err = inv_acc_read_bootsampl(st, enable);
	if (err)
		return err;
	st->read_acc_boot_sample = enable;
	return count;
}
#endif

static const struct iio_chan_spec inv_mpu_channels[] = {
	IIO_CHAN_SOFT_TIMESTAMP(INV_MPU_SCAN_TIMESTAMP),
};
@@ -780,6 +972,12 @@ static DEVICE_ATTR(debug_reg_dump, S_IRUGO | S_IWUSR, inv_reg_dump_show, NULL);
static DEVICE_ATTR(out_temperature, S_IRUGO | S_IWUSR,
			inv_temperature_show, NULL);
static DEVICE_ATTR(misc_self_test, S_IRUGO | S_IWUSR, inv_self_test, NULL);
#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
static IIO_DEVICE_ATTR(read_acc_boot_sample, S_IRUGO | S_IWUSR,
	read_acc_boot_sample_show, read_acc_boot_sample_store, SENSOR_L_ACCEL);
static IIO_DEVICE_ATTR(read_gyro_boot_sample, S_IRUGO | S_IWUSR,
	read_gyro_boot_sample_show, read_gyro_boot_sample_store, SENSOR_L_GYRO);
#endif

static IIO_DEVICE_ATTR(info_anglvel_matrix, S_IRUGO, inv_attr_show, NULL,
			ATTR_GYRO_MATRIX);
@@ -913,6 +1111,10 @@ static const struct attribute *inv_raw_attributes[] = {
	&dev_attr_misc_self_test.attr,
#ifndef SUPPORT_ONLY_BASIC_FEATURES
	&iio_dev_attr_in_power_on.dev_attr.attr,
#endif
#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
	&iio_dev_attr_read_acc_boot_sample.dev_attr.attr,
	&iio_dev_attr_read_gyro_boot_sample.dev_attr.attr,
#endif
	&iio_dev_attr_in_accel_enable.dev_attr.attr,
	&iio_dev_attr_in_accel_wake_enable.dev_attr.attr,
+212 −2
Original line number Diff line number Diff line
@@ -278,6 +278,212 @@ static int inv_i2c_mem_read(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
	return res;
}

#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
static void inv_enable_acc_gyro(struct inv_mpu_state *st)
{
	struct iio_dev *indio_dev = iio_priv_to_dev(st);
	int accel_hz = 100;
	int gyro_hz = 100;

	/**Enable the ACCEL**/
	st->chip_config.accel_fs = ACCEL_FSR_2G;
	inv_set_accel_sf(st);
	st->trigger_state = MISC_TRIGGER;
	set_inv_enable(indio_dev);

	st->sensor_l[SENSOR_L_ACCEL].rate = accel_hz;
	st->trigger_state = DATA_TRIGGER;
	inv_check_sensor_on(st);
	set_inv_enable(indio_dev);

	st->sensor_l[SENSOR_L_ACCEL].on = 1;
	st->trigger_state = RATE_TRIGGER;
	inv_check_sensor_on(st);
	set_inv_enable(indio_dev);

	/**Enable the GYRO**/
	st->chip_config.fsr = GYRO_FSR_250DPS;
	inv_set_gyro_sf(st);
	st->trigger_state = MISC_TRIGGER;
	set_inv_enable(indio_dev);

	st->sensor_l[SENSOR_L_GYRO].rate = gyro_hz;
	st->trigger_state = DATA_TRIGGER;
	inv_check_sensor_on(st);
	set_inv_enable(indio_dev);

	st->sensor_l[SENSOR_L_GYRO].on = 1;
	st->trigger_state = RATE_TRIGGER;
	inv_check_sensor_on(st);
	set_inv_enable(indio_dev);
}
#else
static void inv_enable_acc_gyro(struct inv_mpu_state *st)
{
}
#endif

#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
static int inv_acc_gyro_early_buff_init(struct iio_dev *indio_dev)
{
	int i = 0, err = 0;
	struct inv_mpu_state *st;

	st = iio_priv(indio_dev);
	st->acc_bufsample_cnt = 0;
	st->gyro_bufsample_cnt = 0;
	st->report_evt_cnt = 5;
	st->max_buffer_time = 40;

	st->inv_acc_cachepool = kmem_cache_create("acc_sensor_sample",
			sizeof(struct inv_acc_sample),
			0,
			SLAB_HWCACHE_ALIGN, NULL);
	if (!st->inv_acc_cachepool) {
		pr_err("inv_acc_cachepool cache create failed\n");
		err = -ENOMEM;
		goto clean_exit1;
	}

	for (i = 0; i < INV_ACC_MAXSAMPLE; i++) {
		st->inv_acc_samplist[i] =
			kmem_cache_alloc(st->inv_acc_cachepool,
					GFP_KERNEL);
		if (!st->inv_acc_samplist[i]) {
			err = -ENOMEM;
			goto clean_exit2;
		}
	}

	st->inv_gyro_cachepool = kmem_cache_create("gyro_sensor_sample"
			, sizeof(struct inv_gyro_sample), 0,
			SLAB_HWCACHE_ALIGN, NULL);
	if (!st->inv_gyro_cachepool) {
		pr_err("inv_gyro_cachepool cache create failed\n");
		err = -ENOMEM;
		goto clean_exit3;
	}

	for (i = 0; i < INV_GYRO_MAXSAMPLE; i++) {
		st->inv_gyro_samplist[i] =
			kmem_cache_alloc(st->inv_gyro_cachepool,
					GFP_KERNEL);
		if (!st->inv_gyro_samplist[i]) {
			err = -ENOMEM;
			goto clean_exit4;
		}
	}

	st->accbuf_dev = input_allocate_device();
	if (!st->accbuf_dev) {
		err = -ENOMEM;
		pr_err("input device allocation failed\n");
		goto clean_exit5;
	}
	st->accbuf_dev->name = "inv_accbuf";
	st->accbuf_dev->id.bustype = BUS_I2C;
	input_set_events_per_packet(st->accbuf_dev,
			st->report_evt_cnt * INV_ACC_MAXSAMPLE);
	set_bit(EV_ABS, st->accbuf_dev->evbit);
	input_set_abs_params(st->accbuf_dev, ABS_X,
			-G_MAX, G_MAX, 0, 0);
	input_set_abs_params(st->accbuf_dev, ABS_Y,
			-G_MAX, G_MAX, 0, 0);
	input_set_abs_params(st->accbuf_dev, ABS_Z,
			-G_MAX, G_MAX, 0, 0);
	input_set_abs_params(st->accbuf_dev, ABS_RX,
			-G_MAX, G_MAX, 0, 0);
	input_set_abs_params(st->accbuf_dev, ABS_RY,
			-G_MAX, G_MAX, 0, 0);
	err = input_register_device(st->accbuf_dev);
	if (err) {
		pr_err("unable to register input device %s\n",
				st->accbuf_dev->name);
		goto clean_exit5;
	}

	st->gyrobuf_dev = input_allocate_device();
	if (!st->gyrobuf_dev) {
		err = -ENOMEM;
		pr_err("input device allocation failed\n");
		goto clean_exit6;
	}
	st->gyrobuf_dev->name = "inv_gyrobuf";
	st->gyrobuf_dev->id.bustype = BUS_I2C;
	input_set_events_per_packet(st->gyrobuf_dev,
			st->report_evt_cnt * INV_GYRO_MAXSAMPLE);
	set_bit(EV_ABS, st->gyrobuf_dev->evbit);
	input_set_abs_params(st->gyrobuf_dev, ABS_X,
			-G_MAX, G_MAX, 0, 0);
	input_set_abs_params(st->gyrobuf_dev, ABS_Y,
			-G_MAX, G_MAX, 0, 0);
	input_set_abs_params(st->gyrobuf_dev, ABS_Z,
			-G_MAX, G_MAX, 0, 0);
	input_set_abs_params(st->gyrobuf_dev, ABS_RX,
			-G_MAX, G_MAX, 0, 0);
	input_set_abs_params(st->gyrobuf_dev, ABS_RY,
			-G_MAX, G_MAX, 0, 0);
	err = input_register_device(st->gyrobuf_dev);
	if (err) {
		pr_err("unable to register input device %s\n",
				st->gyrobuf_dev->name);
		goto clean_exit6;
	}

	st->acc_buffer_inv_samples = true;
	st->gyro_buffer_inv_samples = true;
	inv_enable_acc_gyro(st);

	return 1;
clean_exit6:
	input_free_device(st->gyrobuf_dev);
	input_unregister_device(st->accbuf_dev);
clean_exit5:
	input_free_device(st->accbuf_dev);
clean_exit4:
	for (i = 0; i < INV_GYRO_MAXSAMPLE; i++)
		kmem_cache_free(st->inv_gyro_cachepool,
				st->inv_gyro_samplist[i]);
clean_exit3:
	kmem_cache_destroy(st->inv_gyro_cachepool);
clean_exit2:
	for (i = 0; i < INV_ACC_MAXSAMPLE; i++)
		kmem_cache_free(st->inv_acc_cachepool,
				st->inv_acc_samplist[i]);
clean_exit1:
	kmem_cache_destroy(st->inv_acc_cachepool);
	return 0;
}
static void inv_acc_gyro_input_cleanup(
		struct iio_dev *indio_dev)
{
	int i = 0;
	struct inv_mpu_state *st;

	st = iio_priv(indio_dev);
	input_free_device(st->accbuf_dev);
	input_unregister_device(st->gyrobuf_dev);
	input_free_device(st->gyrobuf_dev);
	for (i = 0; i < INV_GYRO_MAXSAMPLE; i++)
		kmem_cache_free(st->inv_gyro_cachepool,
				st->inv_gyro_samplist[i]);
	kmem_cache_destroy(st->inv_gyro_cachepool);
	for (i = 0; i < INV_ACC_MAXSAMPLE; i++)
		kmem_cache_free(st->inv_acc_cachepool,
				st->inv_acc_samplist[i]);
	kmem_cache_destroy(st->inv_acc_cachepool);
}
#else
static int inv_acc_gyro_early_buff_init(struct iio_dev *indio_dev)
{
	return 1;
}
static void inv_acc_gyro_input_cleanup(
		struct iio_dev *indio_dev)
{
}
#endif

/*
 *  inv_mpu_probe() - probe function.
 */
@@ -318,7 +524,7 @@ static int inv_mpu_probe(struct i2c_client *client,
	st->mem_write = inv_i2c_mem_write;
	st->mem_read = inv_i2c_mem_read;
	st->dev = &client->dev;
	st->bus_type = BUS_I2C;
	st->bus_type = BUS_IIO_I2C;
#ifdef CONFIG_OF
	result = invensense_mpu_parse_dt(st->dev, &st->plat_data);
	if (result)
@@ -420,6 +626,9 @@ static int inv_mpu_probe(struct i2c_client *client,
#ifdef TIMER_BASED_BATCHING
	pr_info("Timer based batching\n");
#endif
	result = inv_acc_gyro_early_buff_init(indio_dev);
	if (!result)
		return -EIO;

	return 0;
#ifdef KERNEL_VERSION_4_X
@@ -438,10 +647,10 @@ out_remove_ring:
out_unreg_ring:
	inv_mpu_unconfigure_ring(indio_dev);
out_free:
	dev_err(st->dev, "%s failed %d\n", __func__, result);
	iio_device_free(indio_dev);
out_no_free:
#endif
	dev_err(st->dev, "%s failed %d\n", __func__, result);

	return -EIO;
}
@@ -479,6 +688,7 @@ static int inv_mpu_remove(struct i2c_client *client)
	struct iio_dev *indio_dev = i2c_get_clientdata(client);
	struct inv_mpu_state *st = iio_priv(indio_dev);

	inv_acc_gyro_input_cleanup(indio_dev);
#ifdef KERNEL_VERSION_4_X
	devm_iio_device_unregister(st->dev, indio_dev);
#else
+51 −3
Original line number Diff line number Diff line
@@ -37,7 +37,9 @@
#include <linux/iio/sysfs.h>
#include <linux/iio/iio.h>
#include <linux/iio/kfifo_buf.h>

#include <linux/input.h>
#include <linux/ktime.h>
#include <linux/slab.h>
#ifdef CONFIG_INV_MPU_IIO_ICM20648
#include "icm20648/dmp3Default.h"
#endif
@@ -131,9 +133,37 @@
#define COVARIANCE_SIZE          14
#define ACCEL_COVARIANCE_SIZE  (COVARIANCE_SIZE * sizeof(int))

#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
#define INV_ACC_MAXSAMPLE        4000
#define INV_GYRO_MAXSAMPLE       4000
#define G_MAX                    23920640
struct inv_acc_sample {
	int xyz[3];
	unsigned int tsec;
	unsigned long long tnsec;
};
struct inv_gyro_sample {
	int xyz[3];
	unsigned int tsec;
	unsigned long long tnsec;
};
enum {
	ACCEL_FSR_2G = 0,
	ACCEL_FSR_4G = 1,
	ACCEL_FSR_8G = 2,
	ACCEL_FSR_16G = 3
};
enum {
	GYRO_FSR_250DPS = 0,
	GYRO_FSR_500DPS = 1,
	GYRO_FSR_1000DPS = 2,
	GYRO_FSR_2000DPS = 3
};
#endif

enum inv_bus_type {
	BUS_I2C = 0,
	BUS_SPI,
	BUS_IIO_I2C = 0,
	BUS_IIO_SPI,
};

struct inv_mpu_state;
@@ -825,6 +855,24 @@ struct inv_mpu_state {
	u8 int_en_2;
	u8 gesture_int_count;
	u8 smplrt_div;
#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
	bool read_acc_boot_sample;
	bool read_gyro_boot_sample;
	int acc_bufsample_cnt;
	int gyro_bufsample_cnt;
	bool acc_buffer_inv_samples;
	bool gyro_buffer_inv_samples;
	struct kmem_cache *inv_acc_cachepool;
	struct kmem_cache *inv_gyro_cachepool;
	struct inv_acc_sample *inv_acc_samplist[INV_ACC_MAXSAMPLE];
	struct inv_gyro_sample *inv_gyro_samplist[INV_GYRO_MAXSAMPLE];
	ktime_t timestamp;
	int max_buffer_time;
	struct input_dev *accbuf_dev;
	struct input_dev *gyrobuf_dev;
	int report_evt_cnt;
#endif

};

/**
+76 −1
Original line number Diff line number Diff line
@@ -297,6 +297,80 @@ void inv_convert_and_push_8bytes(struct inv_mpu_state *st, u16 hdr,

	inv_push_8bytes_buffer(st, hdr, t, out);
}
#ifdef CONFIG_ENABLE_ACC_GYRO_BUFFERING
static void store_acc_boot_sample(struct inv_mpu_state *st, u64 t,
						s16 x, s16 y, s16 z)
{
	if (false == st->acc_buffer_inv_samples)
		return;
	st->timestamp.tv64 = t;
	if (ktime_to_timespec(st->timestamp).tv_sec
			<  st->max_buffer_time) {
		if (st->acc_bufsample_cnt < INV_ACC_MAXSAMPLE) {
			st->inv_acc_samplist[st->
				acc_bufsample_cnt]->xyz[0] = x;
			st->inv_acc_samplist[st->
				acc_bufsample_cnt]->xyz[1] = y;
			st->inv_acc_samplist[st->
				acc_bufsample_cnt]->xyz[2] = z;
			st->inv_acc_samplist[st->
				acc_bufsample_cnt]->tsec =
				ktime_to_timespec(st
						->timestamp).tv_sec;
			st->inv_acc_samplist[st->
				acc_bufsample_cnt]->tnsec =
				ktime_to_timespec(st
						->timestamp).tv_nsec;
			st->acc_bufsample_cnt++;
		}
	} else {
		dev_info(st->dev, "End of ACC buffering %d\n",
					st->acc_bufsample_cnt);
		st->acc_buffer_inv_samples = false;
	}
}
static void store_gyro_boot_sample(struct inv_mpu_state *st, u64 t,
						s16 x, s16 y, s16 z)
{

	if (false == st->gyro_buffer_inv_samples)
		return;
	st->timestamp.tv64 = t;
	if (ktime_to_timespec(st->timestamp).tv_sec
			<  st->max_buffer_time) {
		if (st->gyro_bufsample_cnt < INV_GYRO_MAXSAMPLE) {
			st->inv_gyro_samplist[st->
				gyro_bufsample_cnt]->xyz[0] = x;
			st->inv_gyro_samplist[st->
				gyro_bufsample_cnt]->xyz[1] = y;
			st->inv_gyro_samplist[st->
				gyro_bufsample_cnt]->xyz[2] = z;
			st->inv_gyro_samplist[st->
				gyro_bufsample_cnt]->tsec =
				ktime_to_timespec(st->
						timestamp).tv_sec;
			st->inv_gyro_samplist[st->
				gyro_bufsample_cnt]->tnsec =
				ktime_to_timespec(st->
						timestamp).tv_nsec;
			st->gyro_bufsample_cnt++;
		}
	} else {
		dev_info(st->dev, "End of GYRO buffering %d\n",
					st->gyro_bufsample_cnt);
		st->gyro_buffer_inv_samples = false;
	}
}
#else
static void store_acc_boot_sample(struct inv_mpu_state *st, u64 t,
						s16 x, s16 y, s16 z)
{
}
static void store_gyro_boot_sample(struct inv_mpu_state *st, u64 t,
						s16 x, s16 y, s16 z)
{
}
#endif

int inv_push_special_8bytes_buffer(struct inv_mpu_state *st,
				   u16 hdr, u64 t, s16 *d)
@@ -309,6 +383,7 @@ int inv_push_special_8bytes_buffer(struct inv_mpu_state *st,
	memcpy(&buf[2], &d[0], sizeof(d[0]));
	for (j = 0; j < 2; j++)
		memcpy(&buf[4 + j * 2], &d[j + 1], sizeof(d[j]));
	store_gyro_boot_sample(st, t, d[0], d[1], d[2]);
	iio_push_to_buffers(indio_dev, buf);
	inv_push_timestamp(indio_dev, t);

@@ -399,7 +474,7 @@ int inv_push_8bytes_buffer(struct inv_mpu_state *st, u16 sensor, u64 t, s16 *d)
				for (j = 0; j < 2; j++)
					memcpy(&buf[4 + j * 2], &d[j + 1],
					       sizeof(d[j]));

				store_acc_boot_sample(st, t, d[0], d[1], d[2]);
				iio_push_to_buffers(indio_dev, buf);
				inv_push_timestamp(indio_dev, t);
				st->sensor_l[ii].counter = 0;
+1 −1
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ static int inv_mpu_probe(struct spi_device *spi)
	&& !defined(CONFIG_INV_MPU_IIO_IAM20680)
	st->i2c_dis = BIT_I2C_IF_DIS;
#endif
	st->bus_type = BUS_SPI;
	st->bus_type = BUS_IIO_SPI;
	spi_set_drvdata(spi, indio_dev);
	indio_dev->dev.parent = &spi->dev;
	indio_dev->name = id->name;