summaryrefslogtreecommitdiff
path: root/common/motion_sense.c
diff options
context:
space:
mode:
authorSheng-Liang Song <ssl@chromium.org>2014-09-29 11:38:40 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-10-08 02:51:17 +0000
commitac261c00c1b28c549a13aa54bac62b423d10fc6c (patch)
tree4354aa9ce74f90df73621d499f5985d3d099727d /common/motion_sense.c
parentc5b30aa9f2fa726ec77a825a5bc04f985d584ec5 (diff)
downloadchrome-ec-ac261c00c1b28c549a13aa54bac62b423d10fc6c.tar.gz
samus: support sensor at different power state.
Design Goals: 1. Every time the AP boots, the same default sensor settings are configured. 2. If the AP goes to suspend (S3) and wakes back up (S0), then the AP sensor settings will be restored. 3. In S3 and in S5, only sample specific sensors that are needed. BUG=chrome-os-partner:32368 BRANCH=ToT TEST=Verified on Samus. Verified suspend and resume logic with EC console messages. - Test Case0: close lid & open lid - Test Case1: powerd_dbus_suspend Change-Id: I553c53e63ecfcb39d5e649a7189aa6ea02589471 Signed-off-by: Sheng-Liang Song <ssl@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/220371 Reviewed-by: Alec Berg <alecaberg@chromium.org>
Diffstat (limited to 'common/motion_sense.c')
-rw-r--r--common/motion_sense.c89
1 files changed, 58 insertions, 31 deletions
diff --git a/common/motion_sense.c b/common/motion_sense.c
index 12d893f826..ac531bb021 100644
--- a/common/motion_sense.c
+++ b/common/motion_sense.c
@@ -160,26 +160,53 @@ static void clock_chipset_shutdown(void)
{
int i;
struct motion_sensor_t *sensor;
- accel_interval_ms = accel_interval_ap_suspend_ms;
+
for (i = 0; i < motion_sensor_count; i++) {
sensor = &motion_sensors[i];
+ sensor->active = SENSOR_ACTIVE_S5;
+ sensor->odr = sensor->default_odr;
+ sensor->range = sensor->default_range;
sensor->state = SENSOR_NOT_INITIALIZED;
- sensor->power = SENSOR_POWER_OFF;
+ if ((sensor->state == SENSOR_INITIALIZED) &&
+ !(sensor->active_mask & sensor->active))
+ sensor->drv->set_data_rate(sensor, 0, 0);
}
}
DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, clock_chipset_shutdown, HOOK_PRIO_DEFAULT);
-static void clock_chipset_startup(void)
+static void clock_chipset_suspend(void)
+{
+ int i;
+ struct motion_sensor_t *sensor;
+ accel_interval_ms = accel_interval_ap_suspend_ms;
+
+ for (i = 0; i < motion_sensor_count; i++) {
+ sensor = &motion_sensors[i];
+ sensor->active = SENSOR_ACTIVE_S3;
+
+ /* Saving power if the sensor is not active in S3 */
+ if ((sensor->state == SENSOR_INITIALIZED) &&
+ !(sensor->active_mask & sensor->active)) {
+ sensor->drv->set_data_rate(sensor, 0, 0);
+ sensor->state = SENSOR_NOT_INITIALIZED;
+ }
+ }
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, clock_chipset_suspend, HOOK_PRIO_DEFAULT);
+
+static void clock_chipset_resume(void)
{
int i;
struct motion_sensor_t *sensor;
+
accel_interval_ms = accel_interval_ap_on_ms;
+
for (i = 0; i < motion_sensor_count; i++) {
sensor = &motion_sensors[i];
- sensor->power = SENSOR_POWER_ON;
+ sensor->active = SENSOR_ACTIVE_S0;
}
}
-DECLARE_HOOK(HOOK_CHIPSET_STARTUP, clock_chipset_startup, HOOK_PRIO_DEFAULT);
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, clock_chipset_resume, HOOK_PRIO_DEFAULT);
/* Write to LPC status byte to represent that accelerometers are present. */
static inline void set_present(uint8_t *lpc_status)
@@ -231,22 +258,12 @@ static inline void motion_sense_init(struct motion_sensor_t *sensor)
{
int ret;
- if (sensor->power == SENSOR_POWER_OFF)
- return;
-
- if (sensor->state != SENSOR_NOT_INITIALIZED)
- return;
-
/* Initialize accelerometers. */
ret = sensor->drv->init(sensor);
if (ret != EC_SUCCESS) {
sensor->state = SENSOR_INIT_ERROR;
return;
}
-
- /* Initialize sampling interval. */
- accel_interval_ms = accel_interval_ap_suspend_ms;
-
sensor->state = SENSOR_INITIALIZED;
}
@@ -255,9 +272,6 @@ static int motion_sense_read(struct motion_sensor_t *sensor)
{
int ret;
- if (sensor->power == SENSOR_POWER_OFF)
- return EC_ERROR_UNKNOWN;
-
if (sensor->state != SENSOR_INITIALIZED)
return EC_ERROR_UNKNOWN;
@@ -301,6 +315,10 @@ void motion_sense_task(void)
for (i = 0; i < motion_sensor_count; ++i) {
sensor = &motion_sensors[i];
sensor->state = SENSOR_NOT_INITIALIZED;
+
+ sensor->odr = sensor->default_odr;
+ sensor->range = sensor->default_range;
+
if ((LOCATION_BASE == sensor->location)
&& (SENSOR_ACCELEROMETER == sensor->type))
accel_base = sensor;
@@ -313,6 +331,9 @@ void motion_sense_task(void)
set_present(lpc_status);
+ /* Initialize sampling interval. */
+ accel_interval_ms = accel_interval_ap_suspend_ms;
+
while (1) {
ts0 = get_time();
rd_cnt = 0;
@@ -320,13 +341,15 @@ void motion_sense_task(void)
sensor = &motion_sensors[i];
- if (sensor->power == SENSOR_POWER_OFF)
- continue;
+ /* if the sensor is active in the current power state */
+ if (sensor->active & sensor->active_mask) {
- motion_sense_init(sensor);
+ if (sensor->state == SENSOR_NOT_INITIALIZED)
+ motion_sense_init(sensor);
- if (EC_SUCCESS == motion_sense_read(sensor))
- rd_cnt++;
+ if (EC_SUCCESS == motion_sense_read(sensor))
+ rd_cnt++;
+ }
/*
* Rotate the lid accel vector
@@ -355,10 +378,6 @@ void motion_sense_task(void)
for (i = 0; i < motion_sensor_count; ++i) {
sensor = &motion_sensors[i];
- /*
- * TODO(crosbug.com/p/25597):
- * Add filter to smooth lid angle.
- */
/* Rotate accels into standard reference frame. */
if (sensor->type == SENSOR_ACCELEROMETER)
rotate(sensor->xyz,
@@ -456,9 +475,10 @@ static struct motion_sensor_t
if (i == motion_sensor_count)
return NULL;
- if ((sensor->power == SENSOR_POWER_ON)
+ /* if sensor is powered and initialized, return match */
+ if ((sensor->active & sensor->active_mask)
&& (sensor->state == SENSOR_INITIALIZED))
- return sensor;
+ return sensor;
/* If no match then the EC currently doesn't support ID received. */
return NULL;
@@ -561,6 +581,9 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
}
sensor->drv->get_data_rate(sensor, &data);
+
+ /* Save configuration parameter: ODR */
+ sensor->odr = data;
out->sensor_odr.ret = data;
args->response_size = sizeof(out->sensor_odr);
@@ -586,8 +609,11 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
}
sensor->drv->get_range(sensor, &data);
- out->sensor_range.ret = data;
+ /* Save configuration parameter: range */
+ sensor->range = data;
+
+ out->sensor_range.ret = data;
args->response_size = sizeof(out->sensor_range);
break;
@@ -849,7 +875,8 @@ static int command_accel_init(int argc, char **argv)
return EC_ERROR_PARAM1;
sensor = &motion_sensors[id];
- sensor->drv->init(sensor);
+ motion_sense_init(sensor);
+
ccprintf("%s\n", sensor->name);
return EC_SUCCESS;
}