summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-11-24 12:21:44 -0800
committerchrome-bot <chrome-bot@chromium.org>2015-12-01 03:46:34 -0800
commit53fa1d1f0938f7021727880207631f2c9b82e115 (patch)
treea11d2cdabb180945178f920564bdfa30274b5d53
parente803e811147212bfea43ad62bfe9d9ed293c8f8b (diff)
downloadchrome-ec-53fa1d1f0938f7021727880207631f2c9b82e115.tar.gz
driver: si114x: Unlock the device if stuck
It is possible for the ALS state machine and the chip to not agree: The EC thinks the device is busy making a measurement, while the chip is waiting for the IRQ status register to be written. It is not clear how it happened, an IRQ must have been lost. Reinitiliazed the chip is stuck for 10s. BRANCH=smaug BUG=chrome-os-partner:45627 TEST=With an extra patch that force the IRQ handler to not do anything every 100th, check the device recovers. Use andro sensor to monitor light/proximity outputs. Change-Id: I80d50bf92af127f85f82dc5c0ae318d4cfe06812 Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/313668
-rw-r--r--driver/als_si114x.c25
-rw-r--r--driver/als_si114x.h3
2 files changed, 27 insertions, 1 deletions
diff --git a/driver/als_si114x.c b/driver/als_si114x.c
index e3cb87a2a4..bdd39fa5b0 100644
--- a/driver/als_si114x.c
+++ b/driver/als_si114x.c
@@ -21,6 +21,8 @@
#define CPRINTF(format, args...) cprintf(CC_ACCEL, format, ## args)
#define CPRINTS(format, args...) cprints(CC_ACCEL, format, ## args)
+static int init(const struct motion_sensor_t *s);
+
/**
* Read 8bit register from device.
*/
@@ -259,8 +261,29 @@ static int read(const struct motion_sensor_t *s, vector_3_t v)
break;
case SI114X_ALS_IN_PROGRESS_PS_PENDING:
case SI114X_PS_IN_PROGRESS_ALS_PENDING:
- default:
ret = EC_ERROR_ACCESS_DENIED;
+ break;
+ case SI114X_NOT_READY:
+ ret = EC_ERROR_NOT_POWERED;
+ }
+ if (ret == EC_ERROR_ACCESS_DENIED &&
+ s->type == MOTIONSENSE_TYPE_LIGHT) {
+ timestamp_t ts_now = get_time();
+
+ /*
+ * We were unable to access the sensor for THRES time.
+ * We should reset the sensor to clear the interrupt register
+ * and the state machine.
+ */
+ if (time_after(ts_now.le.lo,
+ s->last_collection + SI114X_DENIED_THRESHOLD)) {
+ int ret, val;
+
+ ret = raw_read8(s->addr, SI114X_REG_IRQ_STATUS, &val);
+ CPRINTS("%d stuck IRQ_STATUS 0x%02x - ret %d",
+ s->name, val, ret);
+ init(s);
+ }
}
return ret;
}
diff --git a/driver/als_si114x.h b/driver/als_si114x.h
index 93e9b9a9bc..5fbc3c665f 100644
--- a/driver/als_si114x.h
+++ b/driver/als_si114x.h
@@ -208,6 +208,9 @@
#define SI114X_COVERED_THRESHOLD 5
#define SI114X_OVERFLOW 0xffff
+/* Time to wait before re-initializing the device if access is denied */
+#define SI114X_DENIED_THRESHOLD (10 * SECOND)
+
extern const struct accelgyro_drv si114x_drv;
enum si114x_state {