summaryrefslogtreecommitdiff
path: root/driver/als_tcs3400.c
diff options
context:
space:
mode:
authorTing Shen <phoenixshen@google.com>2019-05-24 15:06:18 +0800
committerCommit Bot <commit-bot@chromium.org>2019-06-25 07:02:09 +0000
commitae22b703601122b14005dd1afadd327939b5dfab (patch)
tree6a7e93f9fca23c90c9fd6ece926a282525456cfd /driver/als_tcs3400.c
parentc355a4f1730c4951857e0a521571f327d44c0759 (diff)
downloadchrome-ec-ae22b703601122b14005dd1afadd327939b5dfab.tar.gz
driver: add an option to emulate irq event in TCS3400
Krane does not reserve an interrupt pin for ALS, so we need another way to trigger the irq handler. Add a new config option CONFIG_ALS_TCS3400_EMULATED_IRQ_EVENT to support this use case. BUG=b:129419982 BRANCH=None TEST=verify that `accelread 3` outputs reasonable data on krane. Change-Id: I960df249d29c0ac21810057e25f14d4bac3e14f5 Signed-off-by: Ting Shen <phoenixshen@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1621449 Reviewed-by: Nick Vaccaro <nvaccaro@google.com> Commit-Queue: Ting Shen <phoenixshen@chromium.org> Tested-by: Ting Shen <phoenixshen@chromium.org>
Diffstat (limited to 'driver/als_tcs3400.c')
-rw-r--r--driver/als_tcs3400.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/driver/als_tcs3400.c b/driver/als_tcs3400.c
index da7994e023..5e9c53e784 100644
--- a/driver/als_tcs3400.c
+++ b/driver/als_tcs3400.c
@@ -9,6 +9,7 @@
#include "common.h"
#include "console.h"
#include "driver/als_tcs3400.h"
+#include "hooks.h"
#include "hwtimer.h"
#include "i2c.h"
#include "math_util.h"
@@ -32,12 +33,37 @@ static inline int tcs3400_i2c_write8(const struct motion_sensor_t *s,
return i2c_write8(s->port, s->addr, reg, data);
}
+static void tcs3400_read_deferred(void)
+{
+ task_set_event(TASK_ID_MOTIONSENSE, CONFIG_ALS_TCS3400_INT_EVENT, 0);
+}
+DECLARE_DEFERRED(tcs3400_read_deferred);
+
+/* convert ATIME register to integration time, in microseconds */
+static int tcs3400_get_integration_time(int atime)
+{
+ return 2780 * (256 - atime);
+}
+
static int tcs3400_read(const struct motion_sensor_t *s, intv3_t v)
{
int ret;
/* Enable power, ADC, and interrupt to start cycle */
ret = tcs3400_i2c_write8(s, TCS_I2C_ENABLE, TCS3400_MODE_COLLECTING);
+ if (ret)
+ return ret;
+
+ if (IS_ENABLED(CONFIG_ALS_TCS3400_EMULATED_IRQ_EVENT)) {
+ int atime;
+
+ ret = tcs3400_i2c_read8(s, TCS_I2C_ATIME, &atime);
+ if (ret)
+ return ret;
+
+ hook_call_deferred(&tcs3400_read_deferred_data,
+ tcs3400_get_integration_time(atime));
+ }
/*
* If write succeeded, we've started the read process, but can't
@@ -45,10 +71,7 @@ static int tcs3400_read(const struct motion_sensor_t *s, intv3_t v)
* to inform upper level that read data process is under way and data
* will be delivered when available.
*/
- if (ret == EC_SUCCESS)
- ret = EC_RES_IN_PROGRESS;
-
- return ret;
+ return EC_RES_IN_PROGRESS;
}
static int tcs3400_rgb_read(const struct motion_sensor_t *s, intv3_t v)
@@ -223,8 +246,9 @@ static int tcs3400_irq_handler(struct motion_sensor_t *s, uint32_t *event)
return ret;
if ((status & TCS_I2C_STATUS_RGBC_VALID) ||
- ((status & TCS_I2C_STATUS_ALS_IRQ) &&
- (status & TCS_I2C_STATUS_ALS_VALID))) {
+ ((status & TCS_I2C_STATUS_ALS_IRQ) &&
+ (status & TCS_I2C_STATUS_ALS_VALID)) ||
+ IS_ENABLED(CONFIG_ALS_TCS3400_EMULATED_IRQ_EVENT)) {
ret = tcs3400_post_events(s, last_interrupt_timestamp);
if (ret)
return ret;