From 1d2845d2db7c9023d6c2ee6203cf9ddc1c968abc Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 7 Nov 2013 14:10:38 -0800 Subject: Add EC_MEMMAP_ALS, update it once per second This adds space for up to two ALS lux readings to be available to the AP through the memory-mapped LPC region. If enabled, the values are updated once a second. The ALS will be reinitialized at every AP resume, since it's typically unpowered otherwise. The reported value will be zero when the ALS is off. BUG=chrome-os-partner:23380 BRANCH=samus TEST=manual Boot the AP, then from the EC console run "als" or just monitor the memory-mapped region directly ("rw 0x40080780" on Samus), while pointing the sensor at bright and dim areas. The value should change. Change-Id: I705371fcd57345dc9adae1231ea30c7ff024aaf8 Signed-off-by: Bill Richardson Reviewed-on: https://chromium-review.googlesource.com/176142 Reviewed-by: Randall Spangler --- common/als.c | 19 +++++++++++++++++++ driver/als_isl29035.c | 31 +++++++++++++++++++------------ include/ec_commands.h | 6 ++++++ 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/common/als.c b/common/als.c index bb2854132f..e8b99e0d20 100644 --- a/common/als.c +++ b/common/als.c @@ -10,6 +10,7 @@ #include "als.h" #include "common.h" #include "console.h" +#include "hooks.h" #include "host_command.h" #include "util.h" @@ -18,6 +19,24 @@ int als_read(enum als_id id, int *lux) return als[id].read(lux); } +/*****************************************************************************/ +/* Hooks */ + +static void als_update(void) +{ + int i, rv, val; + uint16_t *mapped = (uint16_t *)host_get_memmap(EC_MEMMAP_ALS); + + for (i = 0; i < EC_ALS_ENTRIES && i < ALS_COUNT; i++) { + rv = als_read(i, &val); + if (rv == EC_SUCCESS) + mapped[i] = val; + else + mapped[i] = 0; + } +} +DECLARE_HOOK(HOOK_SECOND, als_update, HOOK_PRIO_DEFAULT); + /*****************************************************************************/ /* Console commands */ diff --git a/driver/als_isl29035.c b/driver/als_isl29035.c index 13e5d77c14..3eef3a170e 100644 --- a/driver/als_isl29035.c +++ b/driver/als_isl29035.c @@ -7,6 +7,7 @@ #include "driver/als_isl29035.h" #include "common.h" +#include "hooks.h" #include "i2c.h" #include "timer.h" @@ -22,22 +23,27 @@ #define ILS29035_REG_INT_HT_MSB 7 #define ILS29035_REG_ID 15 +static void isl29035_init(void) +{ + /* + * Tell it to read continually. This uses 70uA, as opposed to nearly + * zero, but it makes the hook/update code cleaner (we don't want to + * wait 90ms to read on demand while processing hook callbacks). + */ + (void)i2c_write8(I2C_PORT_ALS, ILS29035_I2C_ADDR, + ILS29035_REG_COMMAND_I, 0xa0); +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, isl29035_init, HOOK_PRIO_DEFAULT); + int isl29035_read_lux(int *lux) { int rv, lsb, msb, data; - /* Tell it to read once */ - rv = i2c_write8(I2C_PORT_ALS, ILS29035_I2C_ADDR, - ILS29035_REG_COMMAND_I, 0x20); - if (rv) - return rv; - - /* The highest precision (default) should take ~90ms */ - usleep(100 * MSEC); - - /* NOTE: It is necessary to read the LSB first, then the MSB. If you do + /* + * NOTE: It is necessary to read the LSB first, then the MSB. If you do * it in the opposite order, the results are not correct. This is - * apparently an undocumented "feature". + * apparently an undocumented "feature". It's especially noticeable in + * one-shot mode. */ /* Read lsb */ @@ -57,7 +63,8 @@ int isl29035_read_lux(int *lux) /* * The default power-on values will give 16 bits of precision: * 0x0000-0xffff indicates 0-1000 lux. If you change the defaults, - * you'll need to change the scale factor accordingly. + * you'll need to change the scale factor accordingly (and maybe this + * expression, to avoid rounding errors). */ *lux = data * 1000 / 0xffff; diff --git a/include/ec_commands.h b/include/ec_commands.h index 4ed4890f0b..f561681f35 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -81,6 +81,7 @@ #define EC_MEMMAP_BATT_MODEL 0x68 /* Battery Model Number String */ #define EC_MEMMAP_BATT_SERIAL 0x70 /* Battery Serial Number String */ #define EC_MEMMAP_BATT_TYPE 0x78 /* Battery Type String */ +#define EC_MEMMAP_ALS 0x80 /* ALS readings in lux (uint16_t) */ /* Number of temp sensors at EC_MEMMAP_TEMP_SENSOR */ #define EC_TEMP_SENSOR_ENTRIES 16 @@ -102,6 +103,11 @@ */ #define EC_TEMP_SENSOR_OFFSET 200 +/* + * Number of ALS readings at EC_MEMMAP_ALS + */ +#define EC_ALS_ENTRIES 2 + /* * The default value a temperature sensor will return when it is present but * has not been read this boot. This is a reasonable number to avoid -- cgit v1.2.1