summaryrefslogtreecommitdiff
path: root/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c')
-rw-r--r--drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c110
1 files changed, 99 insertions, 11 deletions
diff --git a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c
index d4106ad5071..d5f6ed5fcf4 100644
--- a/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c
+++ b/drivers/iio/imu/st_lsm6ds3/st_lsm6ds3_trigger.c
@@ -7,9 +7,8 @@
*
* Licensed under the GPL-2.
*/
-
-/* #define DEBUG */
-
+//#define WAKE_STATS_DEBUG_INFO
+//#define DEBUG
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/module.h>
@@ -38,7 +37,7 @@
#define ST_LSM6DS3_TAP_SRC_Z_AXIS_MASK (1<<0)
#define ST_LSM6DS3_6D_SRC_ADDR 0x1d
-
+#define ST_LSM6DS3_6D_SRC_DETECTED_MASK (1<<6)
static struct workqueue_struct *st_lsm6ds3_wq;
@@ -63,6 +62,82 @@ irqreturn_t st_lsm6ds3_save_timestamp(int irq, void *private)
return IRQ_HANDLED;
}
+#ifdef WAKE_STATS_DEBUG_INFO
+static int wakeup_irq_count = 0;
+static int wakeup_irq_stayawake_count = 0;
+static int wakeup_irq_keepawake_count = 0;
+#define MAX_ORIENTATIONS 6
+static int wake_up_orient_count[MAX_ORIENTATIONS] = {0};
+static long wake_up_orient_times[MAX_ORIENTATIONS] = {0};
+s64 last_orient_change_time_ns = 0;
+int last_orient;
+
+
+static void update_orient_stats(u8 d6d_src_reg, s64 ctime_ns)
+{
+ return;
+ s64 delta = 0;
+ int orient_val;
+ d6d_src_reg &= SIXD_MASK_VALID_BITS;
+ orient_val = __ffs(d6d_src_reg);
+ if( orient_val >= MAX_ORIENTATIONS){
+ return;
+ }
+
+ wake_up_orient_count[orient_val]++;
+ if(last_orient_change_time_ns != 0){
+ delta = ctime_ns - last_orient_change_time_ns;
+ do_div(delta, 1E6); //down to milliseconds
+ wake_up_orient_times[last_orient] += delta;
+ }
+ last_orient_change_time_ns = ctime_ns;
+ last_orient = orient_val;
+}
+
+static void print_wake_stats(struct lsm6ds3_data *cdata)
+{
+ struct timespec monotonic, boot, misc;
+ s64 mon_ns, boot_ns, misc_ns, tot_ms=0;
+ int i;
+
+ get_monotonic_boottime(&monotonic);
+ ktime_get_ts(&boot);
+ getnstimeofday(&misc);
+ mon_ns = timespec_to_ns(&monotonic);
+ boot_ns = timespec_to_ns(&boot);
+ misc_ns = timespec_to_ns(&misc);
+ do_div(mon_ns,1E9);
+ do_div(boot_ns,1E9);
+ do_div(misc_ns,1E9);
+
+ dev_info(cdata->dev, "wkstat: unignored/total/keepawake: \t%i\t%i\t%i", wakeup_irq_stayawake_count, wakeup_irq_count,
+ wakeup_irq_keepawake_count);
+ dev_info(cdata->dev, "wkstat times: tot:\t%lld\tawake:\t%lld", mon_ns, boot_ns);
+ dev_info(cdata->dev, "wkstat all orient count: 5-0 %i\t%i\t%i\t%i\t%i\t%i",
+ wake_up_orient_count[5],
+ wake_up_orient_count[4],
+ wake_up_orient_count[3],
+ wake_up_orient_count[2],
+ wake_up_orient_count[1],
+ wake_up_orient_count[0]);
+
+ for(i=0; i<MAX_ORIENTATIONS; i++)
+ tot_ms += wake_up_orient_times[i];
+
+ dev_info(cdata->dev, "wkstat orient times(uS): 5-0 %ld\t%ld\t%ld\t%ld\t%ld\t%ld\ttot:%lld",
+ wake_up_orient_times[5],
+ wake_up_orient_times[4],
+ wake_up_orient_times[3],
+ wake_up_orient_times[2],
+ wake_up_orient_times[1],
+ wake_up_orient_times[0], tot_ms);
+
+}
+#endif /* WAKE_STATS_DEBUG_INFO */
+
+
+
+
static void st_lsm6ds3_irq_management(struct work_struct *data_work)
{
struct lsm6ds3_data *cdata;
@@ -73,13 +148,10 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
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);
@@ -89,7 +161,10 @@ 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)){
+ if(d6d_src_reg & ST_LSM6DS3_6D_SRC_DETECTED_MASK){
+#ifdef WAKE_STATS_DEBUG_INFO
+ update_orient_stats(d6d_src_reg, cdata->timestamp);
+#endif
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;
@@ -113,7 +188,9 @@ 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");
+#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;
@@ -124,8 +201,16 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
}
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));
+ wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(500));
+#ifdef WAKE_STATS_DEBUG_INFO
+ wakeup_irq_stayawake_count++;
+#endif
+ }
+ else if(d6d_event && !ignore_event){//negative roll
+ wake_lock_timeout(&cdata->tap_wlock,msecs_to_jiffies(200));
+#ifdef WAKE_STATS_DEBUG_INFO
+ wakeup_irq_keepawake_count++;
+#endif
}
//significant motion event processing
if(tap_event){
@@ -179,6 +264,9 @@ static void st_lsm6ds3_irq_management(struct work_struct *data_work)
if(cdata->first_irq_from_resume){
cdata->first_irq_from_resume = 0;
st_lsm6ds3_reconfigure_fifo(cdata, false);
+#ifdef WAKE_STATS_DEBUG_INFO
+ print_wake_stats(cdata);
+#endif
}
enable_irq(cdata->irq);
return;