summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h2
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c171
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c21
3 files changed, 151 insertions, 43 deletions
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, &regval, 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, &regval, false);
-
- regval = 0x48;//tap threshold
- err = sdata->cdata->tf->write(sdata->cdata,
- ST_LSM6DS3_TAP_THS_6D_ADDR,
- 1, &regval, 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