summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-10-14 21:36:29 -0700
committerchrome-bot <chrome-bot@chromium.org>2015-10-15 21:40:37 -0700
commit917effebbf4f64607a94b10490c143817bf10801 (patch)
treefcaf9c61902689d7018bc3aab64ff37c8a3f1ddb
parent3fa05020369579459898dd1d822f9a8a07ac3751 (diff)
downloadchrome-ec-917effebbf4f64607a94b10490c143817bf10801.tar.gz
common: motion: Fix forced mode computation
When the sensor is defined to be used in forced mode, ec rate was not calculated properly: if the AP rate was rounded up, ec_rate requested by the AP would always be 0. If the EC rate is 0, the sensor may potientally never be queried. Also, when the sensor was disable for a long time, the last timestamp of collection may appear to be in the future, so collection was not initiated. (long time more than 35 minutes, less than 71 minutes). We still see instance where the sensor seems locked up. accelinit would not help because the state machine was not reseted, fix that. BRANCH=smaug BUG=chrome-os-partner:45627 TEST=With accelerate 3/4, check the value is now correct. Check proximity sensor is not stuck 45 minutes after last collection. Change-Id: Ia6805b75f67b048cb0b42c0f91a73dfaf94a254f Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/305823 Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--board/ryu/board.c2
-rw-r--r--common/motion_sense.c33
-rw-r--r--driver/als_si114x.c3
3 files changed, 23 insertions, 15 deletions
diff --git a/board/ryu/board.c b/board/ryu/board.c
index 073e6cfab0..02e9ed0191 100644
--- a/board/ryu/board.c
+++ b/board/ryu/board.c
@@ -405,7 +405,7 @@ struct motion_sensor_t motion_sensors[] = {
/* EC needs sensor for light adaptive brightness */
[SENSOR_CONFIG_EC_S0] = {
.odr = 1000,
- .ec_rate = 1000,
+ .ec_rate = 0,
},
[SENSOR_CONFIG_EC_S3] = {
.odr = 1000,
diff --git a/common/motion_sense.c b/common/motion_sense.c
index 6aeb04bc10..2095882a6f 100644
--- a/common/motion_sense.c
+++ b/common/motion_sense.c
@@ -96,7 +96,7 @@ void motion_sense_fifo_add_unit(struct ec_response_motion_sensor_data *data,
/* For valid sensors, check if AP really needs this data */
if (valid_data) {
- /* Use Hz, conversion to FP will overflow with mHz */
+ /* Use Hz, conversion to FP will overflow with kHz */
fp_t ap_odr =
fp_div(BASE_ODR(sensor->config[SENSOR_CONFIG_AP].odr),
1000);
@@ -188,7 +188,7 @@ static inline int motion_sensor_time_to_read(const timestamp_t *ts,
if (rate == 0)
return 0;
/*
- * converting from mHz to us, need 1e9,
+ * converting from kHz to us, need 1e9,
* If within 95% of the time, check sensor.
*/
return time_after(ts->le.lo,
@@ -219,6 +219,7 @@ int motion_sense_set_data_rate(struct motion_sensor_t *sensor)
{
int roundup = 0, ec_odr = 0, odr = 0;
enum sensor_config config_id;
+ timestamp_t ts = get_time();
/* We assume the sensor is initialized */
@@ -238,21 +239,27 @@ int motion_sense_set_data_rate(struct motion_sensor_t *sensor)
sensor->name, odr, roundup, config_id,
BASE_ODR(sensor->config[SENSOR_CONFIG_AP].odr));
sensor->oversampling = 0;
+ /*
+ * Reset last collection: the last collection may be so much in the past
+ * it may appear to be in the future.
+ */
+ sensor->last_collection = ts.le.lo;
return sensor->drv->set_data_rate(sensor, odr, roundup);
}
-static inline int motion_sense_select_ec_rate(
+static int motion_sense_select_ec_rate(
const struct motion_sensor_t *sensor,
enum sensor_config config_id)
{
#ifdef CONFIG_ACCEL_FORCE_MODE_MASK
- if (CONFIG_ACCEL_FORCE_MODE_MASK & (1 << (sensor - motion_sensors)))
+ if (CONFIG_ACCEL_FORCE_MODE_MASK & (1 << (sensor - motion_sensors))) {
+ int rate = BASE_ODR(sensor->config[config_id].odr);
/* we have to run ec at the sensor frequency rate.*/
- if (sensor->config[config_id].odr > 0)
- return 1000000 / sensor->config[config_id].odr;
+ if (rate > 0)
+ return 1000000 / rate;
else
return 0;
- else
+ } else
#endif
return sensor->config[config_id].ec_rate;
}
@@ -275,9 +282,9 @@ static int motion_sense_ec_rate(struct motion_sensor_t *sensor)
ec_rate_from_cfg = motion_sense_select_ec_rate(
sensor, motion_sense_get_ec_config());
- if ((ec_rate == 0 && ec_rate_from_cfg != 0) ||
- (ec_rate_from_cfg != 0 && ec_rate_from_cfg < ec_rate))
- ec_rate = ec_rate_from_cfg;
+ if (ec_rate_from_cfg != 0)
+ if (ec_rate == 0 || ec_rate_from_cfg < ec_rate)
+ ec_rate = ec_rate_from_cfg;
return ec_rate * MSEC;
}
@@ -308,7 +315,8 @@ int motion_sense_set_motion_intervals(void)
if (ec_rate == 0 || sensor_ec_rate < ec_rate)
ec_rate = sensor_ec_rate;
- sensor_ec_rate = sensor->config[SENSOR_CONFIG_AP].ec_rate;
+ sensor_ec_rate = motion_sense_select_ec_rate(
+ sensor, SENSOR_CONFIG_AP);
if (ec_int_rate_ms == 0 ||
(sensor_ec_rate && sensor_ec_rate < ec_int_rate_ms))
ec_int_rate_ms = sensor_ec_rate;
@@ -341,9 +349,7 @@ static inline int motion_sense_init(struct motion_sensor_t *sensor)
if (ret != EC_SUCCESS) {
sensor->state = SENSOR_INIT_ERROR;
} else {
- timestamp_t ts = get_time();
sensor->state = SENSOR_INITIALIZED;
- sensor->last_collection = ts.le.lo;
motion_sense_set_data_rate(sensor);
}
return ret;
@@ -637,7 +643,6 @@ void motion_sense_task(void)
continue;
}
- ts_begin_task = get_time();
ret = motion_sense_process(sensor, &event,
&ts_begin_task);
if (ret != EC_SUCCESS)
diff --git a/driver/als_si114x.c b/driver/als_si114x.c
index fb927e9367..fb4a19fc6a 100644
--- a/driver/als_si114x.c
+++ b/driver/als_si114x.c
@@ -482,6 +482,7 @@ static int set_interrupt(const struct motion_sensor_t *s,
static int init(const struct motion_sensor_t *s)
{
int ret, resol;
+ struct si114x_drv_data_t *data = SI114X_GET_DATA(s);
/* initialize only once: light must be declared first. */
if (s->type == MOTIONSENSE_TYPE_LIGHT) {
@@ -493,6 +494,8 @@ static int init(const struct motion_sensor_t *s)
ret = si114x_initialize(s);
if (ret != EC_SUCCESS)
return ret;
+
+ data->state = SI114X_IDLE;
resol = 7;
} else {
resol = 5;