Loading drivers/iio/imu/inv_mpu/iam20680/inv_mpu_core_20680.c +204 −2 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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), }; Loading @@ -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); Loading Loading @@ -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, Loading drivers/iio/imu/inv_mpu/inv_mpu_i2c.c +212 −2 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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) Loading Loading @@ -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 Loading @@ -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; } Loading Loading @@ -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 Loading drivers/iio/imu/inv_mpu/inv_mpu_iio.h +51 −3 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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 }; /** Loading drivers/iio/imu/inv_mpu/inv_mpu_ring.c +76 −1 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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); Loading Loading @@ -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; Loading drivers/iio/imu/inv_mpu/inv_mpu_spi.c +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
drivers/iio/imu/inv_mpu/iam20680/inv_mpu_core_20680.c +204 −2 Original line number Diff line number Diff line Loading @@ -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 */ Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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), }; Loading @@ -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); Loading Loading @@ -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, Loading
drivers/iio/imu/inv_mpu/inv_mpu_i2c.c +212 −2 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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) Loading Loading @@ -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 Loading @@ -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; } Loading Loading @@ -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 Loading
drivers/iio/imu/inv_mpu/inv_mpu_iio.h +51 −3 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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 }; /** Loading
drivers/iio/imu/inv_mpu/inv_mpu_ring.c +76 −1 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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); Loading Loading @@ -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; Loading
drivers/iio/imu/inv_mpu/inv_mpu_spi.c +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading