summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h3
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c13
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c56
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c43
4 files changed, 47 insertions, 68 deletions
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h
index ba971628496..edc5de95b1d 100644
--- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h
+++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3.h
@@ -139,7 +139,7 @@ struct lsm6ds3_data {
struct wake_lock tap_wlock;
u8 first_irq_from_resume;
u8 reg_read;
-#define SIXD_MASK_VALID_BITS (0x3f)
+#define SIXD_MASK_VALID_BITS (0x21)
u8 sixd_mask;
u8 int1_save;
@@ -236,6 +236,7 @@ int st_lsm6ds3_allocate_rings(struct lsm6ds3_data *cdata);
void st_lsm6ds3_deallocate_rings(struct lsm6ds3_data *cdata);
int st_lsm6ds3_trig_set_state(struct iio_trigger *trig, bool state);
void st_lsm6ds3_read_fifo(struct lsm6ds3_data *cdata, bool check_fifo_len, bool update_discard);
+void st_lsm6ds3_push_tap_to_fifo(struct lsm6ds3_data *cdata);
int st_lsm6ds3_set_fifo_decimators_and_threshold(struct lsm6ds3_data *cdata);
#define ST_LSM6DS3_TRIGGER_SET_STATE (&st_lsm6ds3_trig_set_state)
#else /* CONFIG_IIO_BUFFER */
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c
index 87cea6f349a..2789d0dbd67 100644
--- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c
+++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_buffer.c
@@ -146,6 +146,17 @@ static void st_lsm6ds3_parse_fifo_data(struct lsm6ds3_data *cdata, u16 read_len)
return;
}
+void st_lsm6ds3_push_tap_to_fifo(struct lsm6ds3_data *cdata)
+{
+ int i;
+ u8 fake_tap[6] = {0};
+ dev_info(cdata->dev, "Sending Fake tap through accel data @:%llu", cdata->accel_timestamp-1);
+ st_lsm6ds3_push_data_with_timestamp(
+ cdata, ST_INDIO_DEV_ACCEL,
+ fake_tap,
+ cdata->accel_timestamp -1);
+}
+
void st_lsm6ds3_read_fifo(struct lsm6ds3_data *cdata, bool check_fifo_len, bool update_discard)
{
int err;
@@ -194,7 +205,7 @@ void st_lsm6ds3_read_fifo(struct lsm6ds3_data *cdata, bool check_fifo_len, bool
#endif
cdata->accel_timestamp = cdata->timestamp - (cdata->accel_deltatime * (read_len/3)); //backdate timestamp
if(update_discard){
- dev_info(cdata->dev, "first accel timestamp:%lld last:%lld ", cdata->accel_timestamp, cdata->timestamp);
+ dev_dbg(cdata->dev, "timestamp:%lld last:%lld ", cdata->accel_timestamp, cdata->timestamp);
}
}
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c
index 499fda71e59..b0df8009aa8 100644
--- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c
+++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_core.c
@@ -918,20 +918,6 @@ int st_lsm6ds3_set_drdy_irq(struct lsm6ds3_sensor_data *sdata, bool state)
}
dev_info(sdata->cdata->dev,"--sig mot irq setup: %i", value);
- if(value == 0 ){
- //need this so that sig motion can reregister before we sleep,
- //otherwise we'll sleep and never wake up
- wake_lock_timeout(&sdata->cdata->wlock, msecs_to_jiffies(1000));
- dev_err(sdata->cdata->dev, "IRQ disabled for md1 sig motion");
- //dump_stack();
-
- }
-#if 0
- reg_addr = ST_LSM6DS3_INT1_ADDR;
- mask = ST_LSM6DS3_STEP_DETECTOR_DRDY_IRQ_MASK;
- st_lsm6ds3_write_data_with_mask(sdata->cdata,
- reg_addr, mask, value, true);
-#endif
//TODO: move this to init since we don't need to set up the parameters every time
reg_addr = ST_LSM6DS3_MD1_ADDR;
mask = ST_LSM6DS3_6D_MD1_INT_MASK;
@@ -1116,37 +1102,19 @@ static int st_lsm6ds3_enable_sensors(struct lsm6ds3_sensor_data *sdata)
return err;
sdata->c_odr = st_lsm6ds3_odr_table.odr_avl[i].hz;
-
- break;
+ //enable tap and
+ //passthrough since we always want 6d and tap enabled;
+
case ST_INDIO_DEV_SIGN_MOTION:
+
err = st_lsm6ds3_write_data_with_mask(sdata->cdata,
- ST_LSM6DS3_SIGN_MOTION_EN_ADDR,
- ST_LSM6DS3_SIGN_MOTION_EN_MASK,
- ST_LSM6DS3_EN_BIT, true);
+ ST_LSM6DS3_MD1_ADDR, ST_LSM6DS3_6D_MD1_INT_MASK, ST_LSM6DS3_EN_BIT, true);
+ 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);
if (err < 0)
return err;
-
- if ((sdata->cdata->sensors_enabled & ~(1 << sdata->sindex)) &
- ST_LSM6DS3_PEDOMETER_DEPENDENCY) {
- err = st_lsm6ds3_write_data_with_mask(sdata->cdata,
- ST_LSM6DS3_PEDOMETER_EN_ADDR,
- ST_LSM6DS3_PEDOMETER_EN_MASK,
- ST_LSM6DS3_DIS_BIT, true);
- if (err < 0)
- return err;
-
- err = st_lsm6ds3_write_data_with_mask(sdata->cdata,
- ST_LSM6DS3_PEDOMETER_EN_ADDR,
- ST_LSM6DS3_PEDOMETER_EN_MASK,
- ST_LSM6DS3_EN_BIT, true);
- if (err < 0)
- return err;
- } else {
- err = st_lsm6ds3_enable_pedometer(sdata, true);
- if (err < 0)
- return err;
- }
-
break;
case ST_INDIO_DEV_STEP_COUNTER:
err = st_lsm6ds3_write_data_with_mask(sdata->cdata,
@@ -1568,7 +1536,7 @@ static int st_lsm6ds3_init_sensor(struct lsm6ds3_data *cdata)
#define ST_LSM6DS3_CTRL8_LPF_ON_ACCEL 0x80
#define ST_LSM6DS3_CTRL4_ADDR 0x13
#define ST_LSM6DS3_CTRL4_STOP_ON_FTH_MASK 0x1
- regval = 0x50;//tap threshold
+ regval = 0x28;//tap threshold
err = sdata->cdata->tf->write(sdata->cdata,
ST_LSM6DS3_TAP_THS_6D_ADDR,
1, &regval, false);
@@ -1935,7 +1903,7 @@ static ssize_t st_lsm6ds3_sysfs_sixd_wake_mask_set(struct device *dev,
uint32_t maskval;
ret = sscanf(buf, "%i", &maskval);
dev_info(sdata->cdata->dev, "read: 0x%x ", maskval);
- if(ret != 1 || maskval ){
+ if(ret != 1 || (maskval > SIXD_MASK_VALID_BITS)){
dev_info(sdata->cdata->dev, "read: 0x%x ", maskval);
dev_err(sdata->cdata->dev,"error, sixd_mask usage: mask sig mot events from");
dev_err(sdata->cdata->dev,"ZH | ZL | YH | YL | XH | XL \n");
@@ -2319,7 +2287,7 @@ int st_lsm6ds3_common_suspend(struct lsm6ds3_data *cdata)
if ((i == ST_INDIO_DEV_SIGN_MOTION) || (i == ST_INDIO_DEV_TILT))
continue;
if(i == ST_INDIO_DEV_ACCEL){
- //stop the fifo
+ //stop the fifo irq
err = st_lsm6ds3_set_drdy_irq(sdata, false);
cdata->int1_save = 1;
continue; //do not disable
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c
index 1805e8f8fb5..905ad01a9bd 100644
--- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c
+++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c
@@ -71,6 +71,8 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
u8 d6d_event = 0;
u8 tap_event = 0;
int wake_irq;
+ int ignore_event = 0;
+
cdata = container_of((struct work_struct *)data_work,
@@ -78,9 +80,7 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
wake_irq = last_wakeup_reason_test(cdata->irq);
-// if(!wake_lock_active(&cdata->wlock))
-// wake_lock(&cdata->wlock);
- mutex_lock(&cdata->fifo_lock);
+ 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);
cdata->tf->read(cdata, ST_LSM6DS3_SRC_FUNC_ADDR, 1, &src_value, true);
@@ -90,12 +90,13 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
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 & (1<<6)){
- dev_info(cdata->dev, "D6D IRQ");
+ dev_info(cdata->dev, "D6D IRQ val:0x%x mask:0x%x", SIXD_MASK_VALID_BITS & d6d_src_reg, cdata->sixd_mask);
if(cdata->sixd_mask & d6d_src_reg){
d6d_event = 1;
cdata->last_wakeup_source |= LSM6DS3_WAKEUP_6D;
}
else{
+ ignore_event = 1;
dev_info(cdata->dev, "ignoring 6d interrupt, wrong axis. mask: 0x%x", cdata->sixd_mask);
}
@@ -113,28 +114,23 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
}
if(cdata->first_irq_from_resume && wake_irq){
dev_info(cdata->dev, "First IRQ from a RESUME");
- if(!d6d_event && !tap_event){
+ 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 (src_fifo & ST_LSM6DS3_FIFO_DATA_AVL) {
- if(cdata->first_irq_from_resume){
- st_lsm6ds3_read_fifo(cdata, true, true);
- }
- else{
- st_lsm6ds3_read_fifo(cdata, true, false);
- }
+ if(!ignore_event && (tap_event || d6d_event) && cdata->first_irq_from_resume){
+ dev_info(cdata->dev, "Setting wake lock");
+ wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(1500));
}
//significant motion event processing
- if(d6d_event || tap_event){
- dev_info(cdata->dev, "Sending sig mot event; ready:%i",cdata->sign_motion_event_ready);
- wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(1500));
+ if(tap_event){
+ dev_info(cdata->dev, "Sending sig mot event(tap); ready:%i",cdata->sign_motion_event_ready);
+ st_lsm6ds3_push_tap_to_fifo(cdata);
iio_push_event(cdata->indio_dev[
ST_INDIO_DEV_SIGN_MOTION],
IIO_UNMOD_EVENT_CODE(IIO_SIGN_MOTION,
@@ -144,6 +140,10 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
cdata->sign_motion_event_ready = false;
}
+ if (src_fifo & ST_LSM6DS3_FIFO_DATA_AVL) {
+ st_lsm6ds3_read_fifo(cdata, true, true);
+ }
+
if (src_value & ST_LSM6DS3_SRC_STEP_DETECTOR_DATA_AVL) {
iio_push_event(cdata->indio_dev[ST_INDIO_DEV_STEP_DETECTOR],
IIO_UNMOD_EVENT_CODE(IIO_STEP_DETECTOR,
@@ -174,14 +174,13 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
cdata->timestamp);
}
- enable_irq(cdata->irq);
mutex_unlock(&cdata->fifo_lock);
-
-// if(wake_lock_active(&cdata->wlock))
-// wake_unlock(&cdata->wlock);
-
- cdata->first_irq_from_resume = 0;
+ if(cdata->first_irq_from_resume){
+ cdata->first_irq_from_resume = 0;
+ st_lsm6ds3_reconfigure_fifo(cdata, false);
+ }
+ enable_irq(cdata->irq);
return;
}