diff options
author | Gwendal Grignou <gwendal@chromium.org> | 2016-05-30 16:27:35 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-06-30 23:10:58 -0700 |
commit | f6b26dee24f4a4006e1a5509031972f8c0b5e9fc (patch) | |
tree | 2f43794cda731f3b573d08af41b1335634da3b39 | |
parent | 4aba826dcf93eb67f30e816acbd02ceba530d335 (diff) | |
download | chrome-ec-f6b26dee24f4a4006e1a5509031972f8c0b5e9fc.tar.gz |
motion: Add ability to stop ring interrupts.
Currently, it is assumed the host will sooner or later retrieve the
events from the sensor ring: It is only used by Android and the sensor
HAL is enabling the ring buffer at boot.
But if nobody processes the ring, and the ring is almost full, the EC will
generate interrupt for every new events.
This can happen with ARC, where events generated for ChromeOS
will be in the ring but nobody will process them until Android is
started.
Add a command to allow sending ring MKBP events. It will be used when
the IIO ring buffer is enabled / disabled.
It also can be used for preventing raising interrupt when the device is
about to go to sleep.
BRANCH=ryu,cyan
BUG=b:25425420,b:27849483
TEST=Check with fiforead that no events are queued when IIO ring
buffer is disabled.
Check with ectool and androsensor that interrupt generation stops.
Change-Id: Ibc85eed2e0eae3a9ec07d191e692118bc2fd0dab
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/356689
-rw-r--r-- | common/motion_sense.c | 32 | ||||
-rw-r--r-- | include/ec_commands.h | 36 | ||||
-rw-r--r-- | util/ectool.c | 19 |
3 files changed, 70 insertions, 17 deletions
diff --git a/common/motion_sense.c b/common/motion_sense.c index cf201ba4e4..758d995e83 100644 --- a/common/motion_sense.c +++ b/common/motion_sense.c @@ -54,7 +54,7 @@ static int accel_disp; /* * Adjustment in us to ec rate when calculating interrupt interval: * To be sure the EC will send an interrupt even if it finishes processing - * events slighly ealier than the previous period. + * events slightly earlier than the previous period. */ #define MOTION_SENSOR_INT_ADJUSTMENT_US 10 @@ -79,6 +79,7 @@ static int wake_up_needed; static int fifo_flush_needed; /* Number of element the AP should collect */ static int fifo_queue_count; +static int fifo_int_enabled; struct queue motion_sense_fifo = QUEUE_NULL(CONFIG_ACCEL_FIFO, struct ec_response_motion_sensor_data); @@ -268,7 +269,7 @@ static int motion_sense_set_ec_rate_from_ap( * 2 measurements. * To prevent that, increase the EC period by 5% to be sure to get at * least one measurement at every collection time. - * We wll apply that correction only if the ec rate is within 10% of + * We will apply that correction only if the ec rate is within 10% of * the data rate. */ if (SECOND * 1100 / odr_mhz > new_rate_us) @@ -284,7 +285,7 @@ end_set_ec_rate_from_ap: * * Calculate the ec_rate for a given sensor. * - sensor: sensor to use - * - config_id: determine the requestor (AP or EC). + * - config_id: determine the requester (AP or EC). * - interrupt: * If interrupt is set: return the sampling rate requested by AP or EC. * If interrupt is not set and the sensor is in forced mode, @@ -472,7 +473,7 @@ static void motion_sense_shutdown(void) int activity = get_next_bit(&enabled); sensor->drv->manage_activity(sensor, activity, 0, NULL); } - /* Renable double tap in case AP disabled it */ + /* Re-enable double tap in case AP disabled it */ sensor->drv->manage_activity(sensor, MOTIONSENSE_ACTIVITY_DOUBLE_TAP, 1, NULL); } @@ -804,11 +805,13 @@ void motion_sense_task(void) mutex_unlock(&g_sensor_mutex); #ifdef CONFIG_MKBP_EVENT /* - * We don't currently support wake up sensor. - * When we do, add per sensor test to know - * when sending the event. + * Send an event if we know we are in S0 and the kernel + * driver is listening, or the AP needs to be waken up. + * In the latter case, the driver pulls the event and + * will resume listening until it is suspended again. */ - if (sensor_active == SENSOR_ACTIVE_S0 || + if ((fifo_int_enabled && + sensor_active == SENSOR_ACTIVE_S0) || wake_up_needed) { mkbp_send_event(EC_MKBP_EVENT_SENSOR_FIFO); wake_up_needed = 0; @@ -1126,6 +1129,19 @@ static int host_cmd_motion_sense(struct host_cmd_handler_args *args) args->response_size = sizeof(out->fifo_read) + reported * motion_sense_fifo.unit_bytes; break; + case MOTIONSENSE_CMD_FIFO_INT_ENABLE: + switch (in->fifo_int_enable.enable) { + case 0: + case 1: + fifo_int_enabled = in->fifo_int_enable.enable; + case EC_MOTION_SENSE_NO_VALUE: + out->fifo_int_enable.ret = fifo_int_enabled; + args->response_size = sizeof(out->fifo_int_enable); + break; + default: + return EC_RES_INVALID_PARAM; + } + break; #else case MOTIONSENSE_CMD_FIFO_INFO: /* Only support the INFO command, to tell there is no FIFO. */ diff --git a/include/ec_commands.h b/include/ec_commands.h index af6d5948c7..f532dfe84b 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -475,7 +475,7 @@ struct ec_lpc_host_args { * If EC gets a command and this flag is not set, this is an old-style command. * Command version is 0 and params from host are at EC_LPC_ADDR_OLD_PARAM with * unknown length. EC must respond with an old-style response (that is, - * withouth setting EC_HOST_ARGS_FLAG_TO_HOST). + * without setting EC_HOST_ARGS_FLAG_TO_HOST). */ #define EC_HOST_ARGS_FLAG_FROM_HOST 0x01 /* @@ -795,7 +795,7 @@ struct ec_response_get_cmd_versions { } __packed; /* - * Check EC communcations status (busy). This is needed on i2c/spi but not + * Check EC communications status (busy). This is needed on i2c/spi but not * on lpc since it has its own out-of-band busy indicator. * * lpc must read the status from the command register. Attempting this on @@ -827,7 +827,7 @@ struct ec_response_test_protocol { uint8_t buf[32]; } __packed; -/* Get prococol information */ +/* Get protocol information */ #define EC_CMD_GET_PROTOCOL_INFO 0x0b /* Flags for ec_response_get_protocol_info.flags */ @@ -939,7 +939,7 @@ enum ec_feature_code { * (Common Smart Battery System Interface Specification) */ EC_FEATURE_SMART_BATTERY = 18, - /* EC can dectect when the host hangs. */ + /* EC can detect when the host hangs. */ EC_FEATURE_HANG_DETECT = 19, /* Report power information, for pit only */ EC_FEATURE_PMU = 20, @@ -1764,6 +1764,13 @@ enum motionsense_command { */ MOTIONSENSE_CMD_LID_ANGLE = 14, + /* + * Allow the FIFO to trigger interrupt via MKBP events. + * By default the FIFO does not send interrupt to process the FIFO + * until the AP is ready or it is coming from a wakeup sensor. + */ + MOTIONSENSE_CMD_FIFO_INT_ENABLE = 15, + /* Number of motionsense sub-commands. */ MOTIONSENSE_NUM_CMDS }; @@ -1824,7 +1831,7 @@ struct ec_response_motion_sense_fifo_info { uint16_t size; /* Amount of space used in the fifo */ uint16_t count; - /* TImestamp recorded in us */ + /* Timestamp recorded in us */ uint32_t timestamp; /* Total amount of vector lost */ uint16_t total_lost; @@ -1859,7 +1866,7 @@ struct ec_motion_sense_activity { #define MOTIONSENSE_SENSOR_FLAG_PRESENT (1<<0) /* - * Flush entry for synchronisation. + * Flush entry for synchronization. * data contains time stamp */ #define MOTIONSENSE_SENSOR_FLAG_FLUSH (1<<0) @@ -1973,6 +1980,15 @@ struct ec_params_motion_sense { /* Used for MOTIONSENSE_CMD_LID_ANGLE */ struct { } lid_angle; + + /* Used for MOTIONSENSE_CMD_FIFO_INT_ENABLE */ + struct { + /* + * 1: enable, 0 disable fifo, + * EC_MOTION_SENSE_NO_VALUE return value. + */ + int8_t enable; + } fifo_int_enable; }; } __packed; @@ -2010,13 +2026,15 @@ struct ec_response_motion_sense { /* * Used for MOTIONSENSE_CMD_EC_RATE, MOTIONSENSE_CMD_SENSOR_ODR, - * MOTIONSENSE_CMD_SENSOR_RANGE, and - * MOTIONSENSE_CMD_KB_WAKE_ANGLE. + * MOTIONSENSE_CMD_SENSOR_RANGE, + * MOTIONSENSE_CMD_KB_WAKE_ANGLE and + * MOTIONSENSE_CMD_FIFO_INT_ENABLE. */ struct { /* Current value of the parameter queried. */ int32_t ret; - } ec_rate, sensor_odr, sensor_range, kb_wake_angle; + } ec_rate, sensor_odr, sensor_range, kb_wake_angle, + fifo_int_enable; /* Used for MOTIONSENSE_CMD_SENSOR_OFFSET */ struct { diff --git a/util/ectool.c b/util/ectool.c index 07bd5adeb9..47c0303505 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -3366,6 +3366,7 @@ static const struct { MS_SIZES(list_activities), MS_SIZES(set_activity), MS_SIZES(lid_angle), + MS_SIZES(fifo_int_enable), }; BUILD_ASSERT(ARRAY_SIZE(ms_command_sizes) == MOTIONSENSE_NUM_CMDS); #undef MS_SIZES @@ -3384,6 +3385,8 @@ static int ms_help(const char *cmd) printf(" %s data NUM - read sensor latest data\n", cmd); printf(" %s fifo_info - print fifo info\n", cmd); + printf(" %s fifo_int enable [0/1] - enable/disable/get fifo " + "interrupt status\n", cmd); printf(" %s fifo_read MAX_DATA - read fifo data\n", cmd); printf(" %s fifo_flush NUM - trigger fifo interrupt\n", cmd); @@ -3692,6 +3695,22 @@ static int cmd_motionsense(int argc, char **argv) return 0; } + if (argc >= 2 && !strcasecmp(argv[1], "fifo_int_enable")) { + param.cmd = MOTIONSENSE_CMD_FIFO_INT_ENABLE; + if (argc == 3) + param.fifo_int_enable.enable = strtol(argv[2], &e, 0); + else + param.fifo_int_enable.enable = EC_MOTION_SENSE_NO_VALUE; + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, + ¶m, ms_command_sizes[param.cmd].outsize, + resp, ms_command_sizes[param.cmd].insize); + if (rv < 0) + return rv; + + printf("%d\n", resp->fifo_int_enable.ret); + return 0; + } + if (argc == 3 && !strcasecmp(argv[1], "fifo_read")) { /* large number to test fragmentation */ struct { |