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

Commit a6ffbc29 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "driver: iio: imu: IAM20680 early buff implemented"

parents a4542030 6cf41405
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -60,4 +60,11 @@ config INV_MPU_IIO_SPI
	  This driver can be built as a module. The module will be called
	  inv-mpu-iio-spi.

config ENABLE_IAM_ACC_GYRO_BUFFERING
	bool "Enable accel & gyro  boot time sensor sample buffering"
	depends on INV_MPU_IIO
	help
	  Say Y here if you want to buffer boot time sensor
	  samples for IAM20680 accelerometer and gyroscope

source "drivers/iio/imu/inv_mpu/inv_test/Kconfig"
+205 −3
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_IAM_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;
@@ -717,7 +746,7 @@ static ssize_t inv_temperature_show(struct device *dev,
		return res;
	mutex_unlock(&indio_dev->mlock);

	temp = (s32)be16_to_cpup((__be16 *)(data)) * 10000;
	temp = (s16)be16_to_cpup((__be16 *)(data)) * 10000;
	temp = temp / TEMP_SENSITIVITY + TEMP_OFFSET;

	return snprintf(buf, MAX_WR_SZ, "%d %lld\n", temp, get_time_ns());
@@ -771,6 +800,169 @@ static ssize_t inv_flush_batch_store(struct device *dev,
	return count;
}

#ifdef CONFIG_ENABLE_IAM_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) {
		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) {
		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_IAM_ACC_GYRO_BUFFERING
static IIO_DEVICE_ATTR(read_acc_boot_sample, 0644,
	read_acc_boot_sample_show, read_acc_boot_sample_store, SENSOR_L_ACCEL);
static IIO_DEVICE_ATTR(read_gyro_boot_sample, 0644,
	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_IAM_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,
+3 −0
Original line number Diff line number Diff line
@@ -271,6 +271,9 @@ static int inv_set_batch(struct inv_mpu_state *st)
	u64 timeout;
	int required_fifo_size;

#ifdef CONFIG_ENABLE_IAM_ACC_GYRO_BUFFERING
	st->batch.timeout = 100;
#endif
	if (st->batch.timeout) {
		required_fifo_size = st->batch.timeout * st->eng_info[ENGINE_GYRO].running_rate
					* st->batch.pk_size / 1000;
+219 −2
Original line number Diff line number Diff line
@@ -278,6 +278,219 @@ static int inv_i2c_mem_read(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
	return res;
}

#ifdef CONFIG_ENABLE_IAM_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->sensor_l[SENSOR_L_ACCEL].on = 0;
	st->trigger_state = RATE_TRIGGER;
	inv_check_sensor_on(st);
	set_inv_enable(indio_dev);

	inv_switch_power_in_lp(st, true);
	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->sensor_l[SENSOR_L_GYRO].on = 0;
	st->trigger_state = RATE_TRIGGER;
	inv_check_sensor_on(st);
	set_inv_enable(indio_dev);

	inv_switch_power_in_lp(st, true);
	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);
}

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 +531,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 +633,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 +654,10 @@ static int inv_mpu_probe(struct i2c_client *client,
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 +695,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_IAM_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_IAM_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

};

/**
Loading