summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnrico Granata <egranata@chromium.org>2019-02-01 14:09:18 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-02-28 11:01:49 -0800
commitbf646a9ebc3b9bf9cbf0ce64968204adf799ef2d (patch)
treefb89e709910d63e67c20d0f3b43b56dc3bfb0eae
parent8bd60cc9c994c026dc60b6efc62b26480be5f03a (diff)
downloadchrome-ec-bf646a9ebc3b9bf9cbf0ce64968204adf799ef2d.tar.gz
motion_sense: send ODR events to the AP
This commits enables the EC to send a motion sense event to the AP when a sensor's ODR is changed. This is done in a way that is backwards compatible on the AP side, in order to enable previous kernels to continue to work (albeit at a loss of new functionality) with up-to-date ECs. Since clients are not required to use a FLUSH when changing ODR, it is possible for the sensor ring to get in a state where it is spreading based on out-of-date delay information, which we observed leading to spreading of overly large intervals, and thus too far into the future. This patch ameliorates that by causing an ODR change to implicitly flush the batching history. BUG=b:123700100 TEST=run CTS sensor tests, observe the sensor ring not spreading too far into the future due to a period change BRANCH=bobba Change-Id: I5a881e9fc5ddb1dbe6690c455d43dc20bffe889a Signed-off-by: Enrico Granata <egranata@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1450288 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Tested-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
-rw-r--r--common/motion_sense.c37
-rw-r--r--include/ec_commands.h1
2 files changed, 32 insertions, 6 deletions
diff --git a/common/motion_sense.c b/common/motion_sense.c
index deb71b9944..e013305701 100644
--- a/common/motion_sense.c
+++ b/common/motion_sense.c
@@ -101,6 +101,9 @@ struct queue motion_sense_fifo = QUEUE_NULL(CONFIG_ACCEL_FIFO,
struct ec_response_motion_sensor_data);
static int motion_sense_fifo_lost;
+/* Flags to control whether to send an ODR change event for a sensor */
+static uint32_t odr_event_required;
+
/*
* Do not use this function directly if you just want to add sensor data, use
* motion_sense_fifo_add_data instead to get a proper timestamp too.
@@ -150,11 +153,18 @@ static void motion_sense_fifo_add_unit(
mutex_unlock(&g_sensor_mutex);
}
-static void motion_sense_insert_flush(struct motion_sensor_t *sensor)
+enum motion_sense_async_event {
+ ASYNC_EVENT_FLUSH = MOTIONSENSE_SENSOR_FLAG_FLUSH |
+ MOTIONSENSE_SENSOR_FLAG_TIMESTAMP,
+ ASYNC_EVENT_ODR = MOTIONSENSE_SENSOR_FLAG_ODR |
+ MOTIONSENSE_SENSOR_FLAG_TIMESTAMP,
+};
+
+static void motion_sense_insert_async_event(struct motion_sensor_t *sensor,
+ enum motion_sense_async_event evt)
{
struct ec_response_motion_sensor_data vector;
- vector.flags = MOTIONSENSE_SENSOR_FLAG_FLUSH |
- MOTIONSENSE_SENSOR_FLAG_TIMESTAMP;
+ vector.flags = evt;
vector.timestamp = __hw_clock_source_read();
vector.sensor_num = sensor - motion_sensors;
@@ -264,6 +274,7 @@ int motion_sense_set_data_rate(struct motion_sensor_t *sensor)
config_id = SENSOR_CONFIG_AP;
}
roundup = !!(sensor->config[config_id].odr & ROUND_UP_FLAG);
+
ret = sensor->drv->set_data_rate(sensor, odr, roundup);
if (ret)
return ret;
@@ -745,11 +756,23 @@ static int motion_sense_process(struct motion_sensor_t *sensor,
ret = EC_ERROR_BUSY;
}
}
+ if (*event & TASK_EVENT_MOTION_ODR_CHANGE) {
+ const int sensor_bit = 1 << (sensor - motion_sensors);
+ int odr_pending = atomic_read_clear(&odr_event_required);
+
+ if (odr_pending & sensor_bit) {
+ motion_sense_insert_async_event(sensor,
+ ASYNC_EVENT_ODR);
+ odr_pending &= ~sensor_bit;
+ }
+ atomic_or(&odr_event_required, odr_pending);
+ }
if (*event & TASK_EVENT_MOTION_FLUSH_PENDING) {
- int flush_pending;
- flush_pending = atomic_read_clear(&sensor->flush_pending);
+ int flush_pending = atomic_read_clear(&sensor->flush_pending);
+
for (; flush_pending > 0; flush_pending--) {
- motion_sense_insert_flush(sensor);
+ motion_sense_insert_async_event(sensor,
+ ASYNC_EVENT_FLUSH);
}
}
#else
@@ -1212,6 +1235,8 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
* The new ODR may suspend sensor, leaving samples
* in the FIFO. Flush it explicitly.
*/
+ atomic_or(&odr_event_required,
+ 1 << (sensor - motion_sensors));
task_set_event(TASK_ID_MOTIONSENSE,
TASK_EVENT_MOTION_ODR_CHANGE, 0);
#endif
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 8d534cff9c..687b90a935 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2516,6 +2516,7 @@ struct ec_motion_sense_activity {
#define MOTIONSENSE_SENSOR_FLAG_TIMESTAMP (1<<1)
#define MOTIONSENSE_SENSOR_FLAG_WAKEUP (1<<2)
#define MOTIONSENSE_SENSOR_FLAG_TABLET_MODE (1<<3)
+#define MOTIONSENSE_SENSOR_FLAG_ODR (1<<4)
/*
* Send this value for the data element to only perform a read. If you