diff options
author | Ting Shen <phoenixshen@google.com> | 2019-05-24 15:06:18 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-06-25 07:02:09 +0000 |
commit | ae22b703601122b14005dd1afadd327939b5dfab (patch) | |
tree | 6a7e93f9fca23c90c9fd6ece926a282525456cfd /driver/als_tcs3400.c | |
parent | c355a4f1730c4951857e0a521571f327d44c0759 (diff) | |
download | chrome-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.c | 36 |
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; |