diff options
author | Enrico Granata <egranata@chromium.org> | 2019-02-01 14:09:18 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-02-28 11:01:49 -0800 |
commit | bf646a9ebc3b9bf9cbf0ce64968204adf799ef2d (patch) | |
tree | fb89e709910d63e67c20d0f3b43b56dc3bfb0eae /common | |
parent | 8bd60cc9c994c026dc60b6efc62b26480be5f03a (diff) | |
download | chrome-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>
Diffstat (limited to 'common')
-rw-r--r-- | common/motion_sense.c | 37 |
1 files changed, 31 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 |