diff options
Diffstat (limited to 'drivers/iio/imu')
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h | 1 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c | 7 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c | 53 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c | 6 |
4 files changed, 57 insertions, 10 deletions
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h index 2533a9b78de..718c8ea4280 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h @@ -162,6 +162,7 @@ struct lsm6ds3_data { u16 fifo_threshold; u32 samples_to_keep_on_wake; + u32 min_latency_samples; int irq; diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c index b89141689a1..c555927769d 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c @@ -29,6 +29,8 @@ #define ST_LSM6DS3_FIFO_DATA_OUT_L 0x3e #define ST_LSM6DS3_FIFO_DATA_OVR_2REGS 0x4000 +static int64_t last_timestamp = 0; + static void st_lsm6ds3_push_data_with_timestamp(struct lsm6ds3_data *cdata, u8 index, u8 *data, int64_t timestamp) { @@ -154,7 +156,7 @@ void st_lsm6ds3_push_tap_to_fifo(struct lsm6ds3_data *cdata) st_lsm6ds3_push_data_with_timestamp( cdata, ST_INDIO_DEV_ACCEL, fake_tap, - cdata->accel_timestamp -1); + last_timestamp); } @@ -165,7 +167,7 @@ void st_lsm6ds3_push_d6d_to_fifo(struct lsm6ds3_data *cdata) st_lsm6ds3_push_data_with_timestamp( cdata, ST_INDIO_DEV_ACCEL, d6d_signature, - cdata->accel_timestamp -1); + last_timestamp); } @@ -221,6 +223,7 @@ void st_lsm6ds3_read_fifo(struct lsm6ds3_data *cdata, bool check_fifo_len, bool } } + last_timestamp = cdata->timestamp + 1; read_len *= ST_LSM6DS3_BYTE_FOR_CHANNEL; #ifdef CONFIG_ST_LSM6DS3_IIO_MASTER_SUPPORT diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c index 96cd843b55f..12dc8cbf1c7 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c @@ -204,6 +204,7 @@ st_lsm6ds3_sysfs_scale_avail, NULL , 0); #define ST_LSM6DS3_SAMPLES_ON_WAKE_DEFAULT 52 +#define ST_LSM6DS3_MIN_LATENCY_SAMPLES 12 static struct st_lsm6ds3_selftest_table { char *string_mode; @@ -801,6 +802,11 @@ int st_lsm6ds3_set_fifo_decimators_and_threshold(struct lsm6ds3_data *cdata) if (fifo_len > 0) { fifo_threshold = fifo_len / 2; + if(fifo_threshold > cdata->min_latency_samples * ST_LSM6DS3_FIFO_ELEMENT_LEN_BYTE){ + fifo_threshold = cdata->min_latency_samples * ST_LSM6DS3_FIFO_ELEMENT_LEN_BYTE; + fifo_threshold /= 2; //LSB of the register is 1 word + } + dev_info(cdata->dev,"setting FIFO length/threshold: 0x%x 0x%x ", fifo_len, fifo_threshold); err = cdata->tf->write(cdata, ST_LSM6DS3_FIFO_THR_L_ADDR, @@ -1984,6 +1990,33 @@ static ssize_t st_lsm6ds3_sysfs_suspend_samples_set(struct device *dev, return size; } + +ssize_t st_lsm6ds3_sysfs_min_latency_samples_get(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct lsm6ds3_sensor_data *sdata = iio_priv(dev_get_drvdata(dev)); + ssize_t ret = sprintf(buf, "0x%02x\n", sdata->cdata->min_latency_samples); + return ret; +} + + +static ssize_t st_lsm6ds3_sysfs_min_latency_samples_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int ret ; + struct lsm6ds3_sensor_data *sdata = iio_priv(dev_get_drvdata(dev)); + uint32_t val; + ret = sscanf(buf, "%i", &val); + dev_info(sdata->cdata->dev, "read: 0x%x ", val); + if(ret != 1 || val <= 1){ + return -EINVAL; + } + + sdata->cdata->min_latency_samples = val; + + return size; +} + static ST_LSM6DS3_DEV_ATTR_SAMP_FREQ(); static ST_LSM6DS3_DEV_ATTR_SAMP_FREQ_AVAIL(); static ST_LSM6DS3_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available); @@ -2032,6 +2065,10 @@ static IIO_DEVICE_ATTR(suspend_samples, S_IRUGO | S_IWUSR, st_lsm6ds3_sysfs_suspend_samples_get, st_lsm6ds3_sysfs_suspend_samples_set, 0); +static IIO_DEVICE_ATTR(min_latency_samples, S_IRUGO | S_IWUSR, + st_lsm6ds3_sysfs_min_latency_samples_get, + st_lsm6ds3_sysfs_min_latency_samples_set, 0); + static struct attribute *st_lsm6ds3_accel_attributes[] = { &iio_dev_attr_sampling_frequency_available.dev_attr.attr, &iio_dev_attr_in_accel_scale_available.dev_attr.attr, @@ -2047,6 +2084,7 @@ static struct attribute *st_lsm6ds3_accel_attributes[] = { &iio_dev_attr_sixd_wake_mask.dev_attr.attr, &iio_dev_attr_suspend_samples.dev_attr.attr, &iio_dev_attr_ack_wakeup_irq.dev_attr.attr, + &iio_dev_attr_min_latency_samples.dev_attr.attr, NULL, }; @@ -2166,7 +2204,7 @@ static int check_wai(struct lsm6ds3_data *cdata) { get_monotonic_boottime(&ts); current_time = ts.tv_sec; - dev_err(cdata->dev, "Last timestamp delta: %d \n", current_time-cdata->irq_timestamp); + //dev_err(cdata->dev, "Last timestamp delta: %d \n", current_time-cdata->irq_timestamp); if(current_time-cdata->irq_timestamp > 15/*minutes*/*60) { return st_lsm6ds3_reset(cdata, true); } @@ -2218,11 +2256,6 @@ int st_lsm6ds3_reset(struct lsm6ds3_data *cdata, bool hard_reset) { msleep(20); - // err = check_wai(cdata); - // if (err < 0) { - // dev_err(cdata->dev, "Failed to check Who-Am-I register.\n"); - // return err; - // } err = st_lsm6ds3_init_sensor(cdata); if (err < 0) @@ -2254,6 +2287,7 @@ int st_lsm6ds3_common_probe(struct lsm6ds3_data *cdata, int irq) cdata->reg_accel = 0; cdata->fifo_data = 0; cdata->samples_to_keep_on_wake = ST_LSM6DS3_SAMPLES_ON_WAKE_DEFAULT; + cdata->min_latency_samples = ST_LSM6DS3_MIN_LATENCY_SAMPLES; for (i = 0; i < ST_INDIO_DEV_NUM; i++) { cdata->indio_dev[i] = iio_device_alloc(sizeof(*sdata)); @@ -2467,6 +2501,12 @@ int st_lsm6ds3_common_suspend(struct lsm6ds3_data *cdata) //limit wakeup fifo sleep_fifo_size = cdata->samples_to_keep_on_wake * 3; //3 samples/chan + if(cdata->samples_to_keep_on_wake >= cdata->indio_dev[ST_INDIO_DEV_ACCEL]->buffer->length){ + //Resize one or the other if you get this warning + dev_err(cdata->dev, "Error: Buffer length(%i) is to small to hold %i samples in sleep.", + cdata->indio_dev[ST_INDIO_DEV_ACCEL]->buffer->length, cdata->samples_to_keep_on_wake); + } + dev_info(cdata->dev , "Setting sleep fifo size to: %i, samples: %i", sleep_fifo_size, cdata->samples_to_keep_on_wake); reg_value = sleep_fifo_size & 0xFF; err = cdata->tf->write(cdata, @@ -2479,6 +2519,7 @@ int st_lsm6ds3_common_suspend(struct lsm6ds3_data *cdata) reg_value = ST_LSM6DS3_CTRL4_STOP_ON_FTH_MASK; //set stop on fth to limit fifo err = cdata->tf->write(cdata, ST_LSM6DS3_CTRL4_ADDR, 1, ®_value, true); + #ifdef FIFO_SLEEP_DEBUG err = cdata->tf->read(cdata, ST_LSM6DS3_FIFO_THR_L_ADDR, 1, ®_value, true); diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c index 7c497447640..a97a5da517c 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c @@ -205,7 +205,7 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) } if(!ignore_event && (tap_event || d6d_event) && cdata->first_irq_from_resume){ - wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(600)); + wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(1000)); #ifdef WAKE_STATS_DEBUG_INFO wakeup_irq_stayawake_count++; #endif @@ -214,7 +214,7 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) } } else if(d6d_event && !ignore_event) { //negative roll - wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(200)); + wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(600)); #ifdef WAKE_STATS_DEBUG_INFO wakeup_irq_keepawake_count++; #endif @@ -270,6 +270,8 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) if(cdata->first_irq_from_resume){ cdata->first_irq_from_resume = 0; + //reset the fifo threshold + //fifo stop on threshold is cleared in common_resume st_lsm6ds3_reconfigure_fifo(cdata, false); #ifdef WAKE_STATS_DEBUG_INFO print_wake_stats(cdata); |