diff options
| -rw-r--r-- | arch/arm/configs/omap3_h1_defconfig | 8 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h | 2 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c | 171 | ||||
| -rw-r--r-- | drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c | 21 |
4 files changed, 155 insertions, 47 deletions
diff --git a/arch/arm/configs/omap3_h1_defconfig b/arch/arm/configs/omap3_h1_defconfig index 42b30e2846a..39876f868a8 100644 --- a/arch/arm/configs/omap3_h1_defconfig +++ b/arch/arm/configs/omap3_h1_defconfig @@ -2691,14 +2691,14 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_TOUCHSCREEN_DEBUG is not set # CONFIG_DEBUG_SHIRQ is not set CONFIG_LOCKUP_DETECTOR=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 CONFIG_PANIC_ON_OOPS=y CONFIG_PANIC_ON_OOPS_VALUE=1 CONFIG_DETECT_HUNG_TASK=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 # CONFIG_SCHED_DEBUG is not set # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h index 718c8ea4280..25443f64c75 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h @@ -140,6 +140,8 @@ struct lsm6ds3_data { struct wake_lock tap_wlock; u8 first_irq_from_resume; u8 reg_read; + u8 sixd_ths; + u8 tap_ths; #define SIXD_MASK_VALID_BITS (0x21) u8 sixd_mask; u8 int1_save; diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c index 12dc8cbf1c7..9ca073cd5db 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c @@ -177,11 +177,22 @@ #define ST_LSM6DS3_TILT_EN_MASK 0x20 #define ST_LSM6DS3_TILT_DRDY_IRQ_MASK 0x02 -/* 6d Constants */ - +/* 6d and Tap Constants */ #define ST_LSM6DS3_6D_MD1_INT_MASK 0x04 -#define ST_LSM6DS3_SINGTAP_MD1_INT_MASK 0x40 +#define ST_LSM6DS3_TAP_MD1_INT_MASK 0x48 +#define ST_LSM6DS3_TAP_CFG_ADDR 0x58 +#define ST_LSM6DS3_TAP_CFG_XYZ_MASK (0xE) + //1 is for latch enable +#define ST_LSM6DS3_TAP_THS_6D_ADDR 0x59 +#define ST_LSM6DS3_SIXD_THS_MASK 0x60 +#define ST_LSM6DS3_TAP_THS_MASK 0x1F +#define ST_LSM6DS3_INT_DUR2_ADDR 0x5A +#define ST_LSM6DS3_CTRL8_ADDR 0x17 +#define ST_LSM6DS3_CTRL8_LPF_ON_6D 0x01 +#define ST_LSM6DS3_CTRL8_LPF_ON_ACCEL 0x80 +#define ST_LSM6DS3_CTRL4_ADDR 0x13 +#define ST_LSM6DS3_CTRL4_STOP_ON_FTH_MASK 0x1 #define ST_LSM6DS3_ACCEL_SUFFIX_NAME "accel" #define ST_LSM6DS3_GYRO_SUFFIX_NAME "gyro" @@ -932,7 +943,7 @@ int st_lsm6ds3_set_drdy_irq(struct lsm6ds3_sensor_data *sdata, bool state) reg_addr, mask, value, true); reg_addr = ST_LSM6DS3_MD1_ADDR; - mask = ST_LSM6DS3_SINGTAP_MD1_INT_MASK; + mask = ST_LSM6DS3_TAP_MD1_INT_MASK; //written at end of func break; case ST_INDIO_DEV_STEP_COUNTER: @@ -1080,10 +1091,57 @@ static int st_lsm6ds3_enable_pedometer(struct lsm6ds3_sensor_data *sdata, } +static int st_lsm6ds3_set_sixd_ths(struct lsm6ds3_data *cdata, int sixd_ths) { + int err = 0; + + dev_info(cdata->dev, "Setting 6d ths: %d", sixd_ths); + if(sixd_ths < 0 || sixd_ths > 4) { + return -EINVAL; + } else if(sixd_ths == 0) { + err = st_lsm6ds3_write_data_with_mask(cdata, ST_LSM6DS3_MD1_ADDR, ST_LSM6DS3_6D_MD1_INT_MASK, 0, true); + } else { + err = st_lsm6ds3_write_data_with_mask(cdata, ST_LSM6DS3_MD1_ADDR, ST_LSM6DS3_6D_MD1_INT_MASK, 1, true); + if(err < 0) { + return -EIO; + } + err = st_lsm6ds3_write_data_with_mask(cdata, ST_LSM6DS3_TAP_THS_6D_ADDR, ST_LSM6DS3_SIXD_THS_MASK, sixd_ths-1, true); + } + + if(err < 0) { + return -EIO; + } + + cdata->sixd_ths = sixd_ths; + + return 0; +} + +static int st_lsm6ds3_set_tap_ths(struct lsm6ds3_data *cdata, int tap_ths) { + int err = 0; + + dev_info(cdata->dev, "Setting tap ths: %d", tap_ths); + if(tap_ths < 0 || tap_ths > 31) { + return -EINVAL; + } else { + err = st_lsm6ds3_write_data_with_mask(cdata, ST_LSM6DS3_TAP_THS_6D_ADDR, ST_LSM6DS3_TAP_THS_MASK, tap_ths, true); + } + + if(err < 0) { + return -EIO; + } + + cdata->tap_ths = tap_ths; + + return 0; +} + static int st_lsm6ds3_enable_sensors(struct lsm6ds3_sensor_data *sdata) { + u8 regval; int err, i; + dev_info(sdata->cdata->dev, "Enabling sensor: %d", sdata->sindex); + switch (sdata->sindex) { case ST_INDIO_DEV_ACCEL: case ST_INDIO_DEV_GYRO: @@ -1097,6 +1155,21 @@ static int st_lsm6ds3_enable_sensors(struct lsm6ds3_sensor_data *sdata) if (sdata->sindex == ST_INDIO_DEV_ACCEL) { sdata->cdata->accel_samples_to_discard = ST_LSM6DS3_ACCEL_STD; + + dev_info(sdata->cdata->dev, "Enabling tap interrupt."); + regval = ST_LSM6DS3_TAP_MD1_INT_MASK; + err = sdata->cdata->tf->write(sdata->cdata, ST_LSM6DS3_MD1_ADDR, 1, ®val, false); + if(err < 0) { + return err; + } + err = st_lsm6ds3_set_sixd_ths(sdata->cdata, sdata->cdata->sixd_ths); + if (err < 0) { + return err; + } + err = st_lsm6ds3_set_tap_ths(sdata->cdata, sdata->cdata->tap_ths); + if(err < 0) { + return err; + } } sdata->cdata->gyro_samples_to_discard = ST_LSM6DS3_GYRO_STD; @@ -1120,7 +1193,7 @@ static int st_lsm6ds3_enable_sensors(struct lsm6ds3_sensor_data *sdata) if (err < 0) return err; err = st_lsm6ds3_write_data_with_mask(sdata->cdata, - ST_LSM6DS3_MD1_ADDR, ST_LSM6DS3_SINGTAP_MD1_INT_MASK, ST_LSM6DS3_EN_BIT, true); + ST_LSM6DS3_MD1_ADDR, ST_LSM6DS3_TAP_MD1_INT_MASK, ST_LSM6DS3_EN_BIT, true); if (err < 0) return err; break; @@ -1536,25 +1609,6 @@ static int st_lsm6ds3_init_sensor(struct lsm6ds3_data *cdata) if (err < 0) goto st_lsm6ds3_init_sensor_mutex_unlock; //set up tap stuff -#define ST_LSM6DS3_TAP_CFG_ADDR 0x58 -#define ST_LSM6DS3_TAP_CFG_XYZ_MASK (0xE) - //1 is for latch enable -#define ST_LSM6DS3_TAP_THS_6D_ADDR 0x59 -#define ST_LSM6DS3_INT_DUR2_ADDR 0x5A -#define ST_LSM6DS3_CTRL8_ADDR 0x17 -#define ST_LSM6DS3_CTRL8_LPF_ON_6D 0x01 -#define ST_LSM6DS3_CTRL8_LPF_ON_ACCEL 0x80 -#define ST_LSM6DS3_CTRL4_ADDR 0x13 -#define ST_LSM6DS3_CTRL4_STOP_ON_FTH_MASK 0x1 - regval = 0x44; // MD1 (6D and Tap on INT1) - err = sdata->cdata->tf->write(sdata->cdata, - ST_LSM6DS3_MD1_ADDR, - 1, ®val, false); - - regval = 0x48;//tap threshold - err = sdata->cdata->tf->write(sdata->cdata, - ST_LSM6DS3_TAP_THS_6D_ADDR, - 1, ®val, false); regval = 0x6; //quiet and shock times err = sdata->cdata->tf->write(sdata->cdata, @@ -1908,6 +1962,61 @@ static ssize_t st_lsm6ds3_sysfs_reset(struct device *dev, st_lsm6ds3_reset(sdata->cdata, true); return size; } + +static ssize_t st_lsm6ds3_sysfs_sixd_ths_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)); + int sixd_ths; + ret = sscanf(buf, "%i", &sixd_ths); + if(ret != 1){ + dev_err(sdata->cdata->dev,"error, sixd_ths range: 0-4"); + return -EINVAL; + } + + ret = st_lsm6ds3_set_sixd_ths(sdata->cdata, sixd_ths); + if(ret < 0) + return ret; + return size; +} + + +ssize_t st_lsm6ds3_sysfs_sixd_ths_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, "%d\n", sdata->cdata->sixd_ths); + return ret; +} + +static ssize_t st_lsm6ds3_sysfs_tap_ths_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)); + int tap_ths; + ret = sscanf(buf, "%i", &tap_ths); + if(ret != 1){ + dev_err(sdata->cdata->dev,"error, tap_ths range: 0-31"); + return -EINVAL; + } + + ret = st_lsm6ds3_set_tap_ths(sdata->cdata, tap_ths); + if(ret < 0) + return ret; + return size; +} + + +ssize_t st_lsm6ds3_sysfs_tap_ths_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, "%d\n", sdata->cdata->tap_ths); + return ret; +} + static ssize_t st_lsm6ds3_sysfs_read_reg_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { @@ -2057,6 +2166,12 @@ static IIO_DEVICE_ATTR(read_reg, S_IRUGO | S_IWUSR, static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, st_lsm6ds3_sysfs_reset, 0); +static IIO_DEVICE_ATTR(sixd_ths, S_IRUGO | S_IWUSR, + st_lsm6ds3_sysfs_sixd_ths_get, st_lsm6ds3_sysfs_sixd_ths_set, 0); + +static IIO_DEVICE_ATTR(tap_ths, S_IRUGO | S_IWUSR, + st_lsm6ds3_sysfs_tap_ths_get, st_lsm6ds3_sysfs_tap_ths_set, 0); + static IIO_DEVICE_ATTR(sixd_wake_mask, S_IRUGO | S_IWUSR, st_lsm6ds3_sysfs_sixd_wake_mask_get, st_lsm6ds3_sysfs_sixd_wake_mask_set, 0); @@ -2081,6 +2196,8 @@ static struct attribute *st_lsm6ds3_accel_attributes[] = { &iio_dev_attr_write_reg.dev_attr.attr, &iio_dev_attr_read_reg.dev_attr.attr, &iio_dev_attr_reset.dev_attr.attr, + &iio_dev_attr_sixd_ths.dev_attr.attr, + &iio_dev_attr_tap_ths.dev_attr.attr, &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, @@ -2216,6 +2333,7 @@ int st_lsm6ds3_reset(struct lsm6ds3_data *cdata, bool hard_reset) { int err; struct lsm6ds3_sensor_data *sdata; + dev_info(cdata->dev, "Resetting accel. Hard reset: %b", hard_reset); if(hard_reset) { if(!cdata->reg_accel) { @@ -2312,7 +2430,10 @@ int st_lsm6ds3_common_probe(struct lsm6ds3_data *cdata, int irq) dev_info(cdata->dev, "driver use DRDY int pin 1\n"); } + // default values cdata->sixd_mask = 0x21; + cdata->sixd_ths = 0x1; + cdata->tap_ths = 0x8; cdata->indio_dev[ST_INDIO_DEV_ACCEL]->name = kasprintf(GFP_KERNEL, "%s_%s", cdata->name, @@ -2530,6 +2651,8 @@ int st_lsm6ds3_common_suspend(struct lsm6ds3_data *cdata) dev_info(cdata->dev, "before suspend 0x13 ctrl4: %x err:%i", reg_value, err); #endif + st_lsm6ds3_flush_works(); + return 0; } EXPORT_SYMBOL(st_lsm6ds3_common_suspend); diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c index a97a5da517c..15eff9445f9 100644 --- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c +++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c @@ -146,13 +146,11 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) u8 src_value = 0x00, src_fifo = 0x00; u8 d6d_event = 0; u8 tap_event = 0; - int wake_irq; int ignore_event = 0; cdata = container_of((struct work_struct *)data_work, struct lsm6ds3_data, data_work); - wake_irq = last_wakeup_reason_test(cdata->irq); mutex_lock(&cdata->fifo_lock); cdata->tf->read(cdata, ST_LSM6DS3_6D_SRC_ADDR, 1, &d6d_src_reg, true); cdata->tf->read(cdata, ST_LSM6DS3_TAP_SRC_ADDR, 1, &tap_src_reg, true); @@ -160,9 +158,6 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) cdata->tf->read(cdata, ST_LSM6DS3_FIFO_DATA_AVL_ADDR, 1, &src_fifo, true); - dev_dbg(cdata->dev, "ST irq start :src_value, 6d, tap:%x %x %x", - src_value, d6d_src_reg, tap_src_reg); - if(d6d_src_reg & ST_LSM6DS3_6D_SRC_DETECTED_MASK){ #ifdef WAKE_STATS_DEBUG_INFO update_orient_stats(d6d_src_reg, cdata->timestamp); @@ -191,21 +186,9 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work) dev_info(cdata->dev, "Ignoring tap"); } } - - if(cdata->first_irq_from_resume && wake_irq){ -#ifdef WAKE_STATS_DEBUG_INFO - wakeup_irq_count++; -#endif - if(!d6d_event && !tap_event && !ignore_event){ - dev_info(cdata->dev, "No event from first resume, assuming lost TAP"); - tap_event = 1; - cdata->last_wakeup_source |= LSM6DS3_WAKEUP_TAP; - dev_info(cdata->dev, "Valid Tap from sleep"); - } - } if(!ignore_event && (tap_event || d6d_event) && cdata->first_irq_from_resume){ - wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(1000)); + wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(750)); #ifdef WAKE_STATS_DEBUG_INFO wakeup_irq_stayawake_count++; #endif @@ -214,7 +197,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(600)); + wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(400)); #ifdef WAKE_STATS_DEBUG_INFO wakeup_irq_keepawake_count++; #endif |