summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-08-30 21:07:03 -0700
committerchrome-bot <chrome-bot@chromium.org>2015-09-18 20:57:22 -0700
commit6b5a49ef15354c5b31be51f32006dbb4d7dc7c62 (patch)
tree7df76a93bfedaecdfda598278591a7411e3602f8 /common
parent13a7ae7b6fe5c67446adeb95256271547a0c777b (diff)
downloadchrome-ec-6b5a49ef15354c5b31be51f32006dbb4d7dc7c62.tar.gz
motion: Add Gesture Interface
Add an interface with the host to set up gesture recognition. Today, only significant motion is supported. Add a virtual sensor for concentrating gesture support from host. BRANCH=smaug BUG=b:23570481 TEST=On ryu, enable significant motion from host. Change-Id: I906fa2d2d7b4ca2771ea2f58b91de8d97bf4e2e3 Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/296213
Diffstat (limited to 'common')
-rw-r--r--common/motion_sense.c158
1 files changed, 138 insertions, 20 deletions
diff --git a/common/motion_sense.c b/common/motion_sense.c
index 6874b0614e..89d2f4e77b 100644
--- a/common/motion_sense.c
+++ b/common/motion_sense.c
@@ -77,8 +77,6 @@ void motion_sense_fifo_add_unit(struct ec_response_motion_sensor_data *data,
struct ec_response_motion_sensor_data vector;
int i;
- data->sensor_num = sensor - motion_sensors;
-
mutex_lock(&g_sensor_mutex);
if (queue_space(&motion_sense_fifo) == 0) {
queue_remove_unit(&motion_sense_fifo, &vector);
@@ -139,6 +137,8 @@ static void motion_sense_insert_flush(struct motion_sensor_t *sensor)
vector.flags = MOTIONSENSE_SENSOR_FLAG_FLUSH |
MOTIONSENSE_SENSOR_FLAG_TIMESTAMP;
vector.timestamp = __hw_clock_source_read();
+ vector.sensor_num = sensor - motion_sensors;
+
motion_sense_fifo_add_unit(&vector, sensor, 0);
}
@@ -147,7 +147,8 @@ static void motion_sense_insert_timestamp(void)
struct ec_response_motion_sensor_data vector;
vector.flags = MOTIONSENSE_SENSOR_FLAG_TIMESTAMP;
vector.timestamp = __hw_clock_source_read();
- motion_sense_fifo_add_unit(&vector, motion_sensors, 0);
+ vector.sensor_num = 0;
+ motion_sense_fifo_add_unit(&vector, NULL, 0);
}
static void motion_sense_get_fifo_info(
@@ -342,6 +343,9 @@ static void motion_sense_shutdown(void)
{
int i;
struct motion_sensor_t *sensor;
+#ifdef CONFIG_GESTURE_DETECTION_MASK
+ uint32_t enabled = 0, disabled, mask;
+#endif
sensor_active = SENSOR_ACTIVE_S5;
@@ -351,9 +355,24 @@ static void motion_sense_shutdown(void)
sensor->config[SENSOR_CONFIG_AP].odr = 0;
sensor->config[SENSOR_CONFIG_AP].ec_rate = 0;
sensor->drv->set_range(sensor, sensor->default_range, 0);
-
}
motion_sense_switch_sensor_rate();
+ /* Forget activities set by the AP */
+#ifdef CONFIG_GESTURE_DETECTION_MASK
+ mask = CONFIG_GESTURE_DETECTION_MASK;
+ while (mask) {
+ i = 31 - __builtin_clz(mask);
+ mask &= (1 << mask);
+ sensor = &motion_sensors[i];
+ sensor->drv->list_activities(sensor,
+ &enabled, &disabled);
+ while (enabled) {
+ int activity = 31 - __builtin_clz(enabled);
+ enabled &= ~(1 << activity);
+ sensor->drv->manage_activity(sensor, activity, 0, NULL);
+ }
+ }
+#endif
}
DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, motion_sense_shutdown,
MOTION_SENSE_HOOK_PRIO);
@@ -491,6 +510,7 @@ static int motion_sense_process(struct motion_sensor_t *sensor,
ret = motion_sense_read(sensor);
if (ret == EC_SUCCESS) {
vector.flags = 0;
+ vector.sensor_num = sensor - motion_sensors;
vector.data[X] = sensor->raw_xyz[X];
vector.data[Y] = sensor->raw_xyz[Y];
vector.data[Z] = sensor->raw_xyz[Z];
@@ -593,6 +613,28 @@ void motion_sense_task(void)
lightbar_sequence(LIGHTBAR_TAP);
}
#endif
+#ifdef CONFIG_GESTURE_SIGMO
+ if (event & CONFIG_GESTURE_SIGMO_EVENT) {
+ struct motion_sensor_t *activity_sensor;
+#ifdef CONFIG_ACCEL_FIFO
+ struct ec_response_motion_sensor_data vector;
+
+ CPRINTS("significant motion");
+ /* Send events to the FIFO */
+ vector.flags = MOTIONSENSE_SENSOR_FLAG_WAKEUP;
+ vector.activity = MOTIONSENSE_ACTIVITY_SIG_MOTION;
+ vector.state = 1; /* triggered */
+ vector.sensor_num = MOTION_SENSE_ACTIVITY_SENSOR_ID;
+ motion_sense_fifo_add_unit(&vector, NULL, 0);
+#endif
+ /* Disable further detection */
+ activity_sensor = &motion_sensors[CONFIG_GESTURE_SIGMO];
+ activity_sensor->drv->manage_activity(
+ activity_sensor,
+ MOTIONSENSE_ACTIVITY_SIG_MOTION,
+ 0, NULL);
+ }
+#endif
#endif
#ifdef CONFIG_LID_ANGLE
/*
@@ -693,7 +735,7 @@ DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_SENSOR_FIFO, motion_sense_get_next_event);
/* Function to map host sensor IDs to motion sensor. */
static struct motion_sensor_t
- *host_sensor_id_to_motion_sensor(int host_id)
+ *host_sensor_id_to_real_sensor(int host_id)
{
struct motion_sensor_t *sensor;
@@ -709,6 +751,21 @@ static struct motion_sensor_t
return NULL;
}
+static struct motion_sensor_t
+ *host_sensor_id_to_motion_sensor(int host_id)
+{
+#ifdef CONFIG_GESTURE_HOST_DETECTION
+ if (host_id == MOTION_SENSE_ACTIVITY_SENSOR_ID)
+ /*
+ * Return the info for the first sensor that
+ * support some gestures.
+ */
+ return host_sensor_id_to_real_sensor(
+ __builtin_ctz(CONFIG_GESTURE_DETECTION_MASK));
+#endif
+ return host_sensor_id_to_real_sensor(host_id);
+}
+
static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
{
const struct ec_params_motion_sense *in = args->params;
@@ -722,18 +779,23 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
(*(host_get_memmap(EC_MEMMAP_ACC_STATUS)) &
EC_MEMMAP_ACC_STATUS_PRESENCE_BIT) ?
MOTIONSENSE_MODULE_FLAG_ACTIVE : 0;
- out->dump.sensor_count = motion_sensor_count;
+ out->dump.sensor_count = ALL_MOTION_SENSORS;
args->response_size = sizeof(out->dump);
- reported = MIN(motion_sensor_count, in->dump.max_sensor_count);
+ reported = MIN(ALL_MOTION_SENSORS, in->dump.max_sensor_count);
mutex_lock(&g_sensor_mutex);
for (i = 0; i < reported; i++) {
- sensor = &motion_sensors[i];
out->dump.sensor[i].flags =
MOTIONSENSE_SENSOR_FLAG_PRESENT;
- /* casting from int to s16 */
- out->dump.sensor[i].data[X] = sensor->xyz[X];
- out->dump.sensor[i].data[Y] = sensor->xyz[Y];
- out->dump.sensor[i].data[Z] = sensor->xyz[Z];
+ if (i < motion_sensor_count) {
+ sensor = &motion_sensors[i];
+ /* casting from int to s16 */
+ out->dump.sensor[i].data[X] = sensor->xyz[X];
+ out->dump.sensor[i].data[Y] = sensor->xyz[Y];
+ out->dump.sensor[i].data[Z] = sensor->xyz[Z];
+ } else {
+ memset(out->dump.sensor[i].data, 0,
+ 3 * sizeof(int16_t));
+ }
}
mutex_unlock(&g_sensor_mutex);
args->response_size += reported *
@@ -741,7 +803,7 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
break;
case MOTIONSENSE_CMD_DATA:
- sensor = host_sensor_id_to_motion_sensor(
+ sensor = host_sensor_id_to_real_sensor(
in->sensor_odr.sensor_num);
if (sensor == NULL)
return EC_RES_INVALID_PARAM;
@@ -762,7 +824,13 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
if (sensor == NULL)
return EC_RES_INVALID_PARAM;
- out->info.type = sensor->type;
+#ifdef CONFIG_GESTURE_HOST_DETECTION
+ if (in->sensor_odr.sensor_num ==
+ MOTION_SENSE_ACTIVITY_SENSOR_ID)
+ out->info.type = MOTIONSENSE_TYPE_ACTIVITY;
+ else
+#endif
+ out->info.type = sensor->type;
out->info.location = sensor->location;
out->info.chip = sensor->chip;
@@ -770,7 +838,7 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
break;
case MOTIONSENSE_CMD_EC_RATE:
- sensor = host_sensor_id_to_motion_sensor(
+ sensor = host_sensor_id_to_real_sensor(
in->sensor_odr.sensor_num);
if (sensor == NULL)
return EC_RES_INVALID_PARAM;
@@ -798,7 +866,7 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
case MOTIONSENSE_CMD_SENSOR_ODR:
/* Verify sensor number is valid. */
- sensor = host_sensor_id_to_motion_sensor(
+ sensor = host_sensor_id_to_real_sensor(
in->sensor_odr.sensor_num);
if (sensor == NULL)
return EC_RES_INVALID_PARAM;
@@ -836,7 +904,7 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
case MOTIONSENSE_CMD_SENSOR_RANGE:
/* Verify sensor number is valid. */
- sensor = host_sensor_id_to_motion_sensor(
+ sensor = host_sensor_id_to_real_sensor(
in->sensor_range.sensor_num);
if (sensor == NULL)
return EC_RES_INVALID_PARAM;
@@ -857,7 +925,7 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
case MOTIONSENSE_CMD_SENSOR_OFFSET:
/* Verify sensor number is valid. */
- sensor = host_sensor_id_to_motion_sensor(
+ sensor = host_sensor_id_to_real_sensor(
in->sensor_offset.sensor_num);
if (sensor == NULL)
return EC_RES_INVALID_PARAM;
@@ -880,7 +948,7 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
case MOTIONSENSE_CMD_PERFORM_CALIB:
/* Verify sensor number is valid. */
- sensor = host_sensor_id_to_motion_sensor(
+ sensor = host_sensor_id_to_real_sensor(
in->sensor_offset.sensor_num);
if (sensor == NULL)
return EC_RES_INVALID_PARAM;
@@ -899,7 +967,7 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
#ifdef CONFIG_ACCEL_FIFO
case MOTIONSENSE_CMD_FIFO_FLUSH:
- sensor = host_sensor_id_to_motion_sensor(
+ sensor = host_sensor_id_to_real_sensor(
in->sensor_odr.sensor_num);
if (sensor == NULL)
return EC_RES_INVALID_PARAM;
@@ -940,6 +1008,56 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args)
args->response_size = sizeof(out->fifo_info);
break;
#endif
+#ifdef CONFIG_GESTURE_HOST_DETECTION
+ case MOTIONSENSE_CMD_LIST_ACTIVITIES: {
+ uint32_t enabled, disabled, mask, i;
+ if (in->sensor_offset.sensor_num !=
+ MOTION_SENSE_ACTIVITY_SENSOR_ID)
+ return EC_RES_INVALID_PARAM;
+ out->list_activities.enabled = 0;
+ out->list_activities.disabled = 0;
+ ret = EC_RES_SUCCESS;
+ mask = CONFIG_GESTURE_DETECTION_MASK;
+ while (mask && ret == EC_RES_SUCCESS) {
+ i = 31 - __builtin_clz(mask);
+ mask &= (1 << mask);
+ sensor = &motion_sensors[i];
+ ret = sensor->drv->list_activities(sensor,
+ &enabled, &disabled);
+ if (ret == EC_RES_SUCCESS) {
+ out->list_activities.enabled |= enabled;
+ out->list_activities.disabled |= disabled;
+ }
+ }
+ if (ret != EC_RES_SUCCESS)
+ return ret;
+ args->response_size = sizeof(out->list_activities);
+ break;
+ }
+ case MOTIONSENSE_CMD_SET_ACTIVITY: {
+ uint32_t enabled, disabled, mask, i;
+ if (in->sensor_offset.sensor_num !=
+ MOTION_SENSE_ACTIVITY_SENSOR_ID)
+ return EC_RES_INVALID_PARAM;
+ mask = CONFIG_GESTURE_DETECTION_MASK;
+ while (mask && ret == EC_RES_SUCCESS) {
+ i = 31 - __builtin_clz(mask);
+ mask &= (1 << mask);
+ sensor = &motion_sensors[i];
+ sensor->drv->list_activities(sensor,
+ &enabled, &disabled);
+ if (in->set_activity.activity & (enabled | disabled))
+ ret = sensor->drv->manage_activity(sensor,
+ in->set_activity.activity,
+ in->set_activity.enable,
+ NULL);
+ }
+ if (ret != EC_RES_SUCCESS)
+ return ret;
+ args->response_size = sizeof(out->set_activity);
+ break;
+ }
+#endif
default:
/* Call other users of the motion task */
#ifdef CONFIG_LID_ANGLE