From aefbc98e7e117864012170703e96972366603166 Mon Sep 17 00:00:00 2001 From: Diana Z Date: Thu, 18 Oct 2018 13:54:02 -0600 Subject: Ampton: add initial motion sensor code Adds initial motion sensor code for ampton and apel, based on the code for similar boards. Sensors will only be present on ampton SKUs (currently numbered 1 and 2). BRANCH=None BUG=b:115501243 TEST=builds Change-Id: I61de2ec824df27b2944dd291c0e3bdbdae13a04b Signed-off-by: Diana Z Reviewed-on: https://chromium-review.googlesource.com/1310094 Reviewed-by: Furquan Shaikh Reviewed-by: Justin TerAvest --- board/ampton/board.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++- board/ampton/board.h | 38 ++++++++++++ board/ampton/ec.tasklist | 1 + 3 files changed, 183 insertions(+), 3 deletions(-) (limited to 'board/ampton') diff --git a/board/ampton/board.c b/board/ampton/board.c index be6c20f1d3..63e124fa79 100644 --- a/board/ampton/board.c +++ b/board/ampton/board.c @@ -10,6 +10,9 @@ #include "button.h" #include "charge_state.h" #include "common.h" +#include "cros_board_info.h" +#include "driver/accel_kionix.h" +#include "driver/accelgyro_bmi160.h" #include "driver/ppc/sn5s330.h" #include "driver/tcpm/it83xx_pd.h" #include "driver/tcpm/ps8xxx.h" @@ -21,13 +24,14 @@ #include "intc.h" #include "keyboard_scan.h" #include "lid_switch.h" +#include "motion_sense.h" #include "power.h" #include "power_button.h" #include "spi.h" #include "switch.h" #include "system.h" -#include "tcpci.h" #include "tablet_mode.h" +#include "tcpci.h" #include "temp_sensor.h" #include "thermistor.h" #include "uart.h" @@ -35,6 +39,8 @@ #include "usbc_ppc.h" #include "util.h" +static uint8_t sku_id; + static void ppc_interrupt(enum gpio_signal signal) { if (signal == GPIO_USB_C0_PD_INT_ODL) @@ -100,6 +106,127 @@ const struct temp_sensor_t temp_sensors[] = { }; BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); +/* Motion sensors */ +/* Mutexes */ +static struct mutex g_lid_mutex; +static struct mutex g_base_mutex; + +/* Matrix to rotate accelrator into standard reference frame */ +/* TODO(b/118756407): Ampton/Apel: tune motion sensors */ +const mat33_fp_t base_standard_ref = { + { 0, FLOAT_TO_FP(-1), 0}, + { FLOAT_TO_FP(1), 0, 0}, + { 0, 0, FLOAT_TO_FP(1)} +}; + +/* sensor private data */ +static struct kionix_accel_data g_kx022_data; +static struct bmi160_drv_data_t g_bmi160_data; + +/* Drivers */ +struct motion_sensor_t motion_sensors[] = { + [LID_ACCEL] = { + .name = "Lid Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_KX022, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &kionix_accel_drv, + .mutex = &g_lid_mutex, + .drv_data = &g_kx022_data, + .port = I2C_PORT_SENSOR, + .addr = KX022_ADDR1, + .rot_standard_ref = NULL, /* Identity matrix. */ + .default_range = 4, /* g */ + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + /* Sensor on for lid angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, + }, + [BASE_ACCEL] = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMI160, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &bmi160_drv, + .mutex = &g_base_mutex, + .drv_data = &g_bmi160_data, + .port = I2C_PORT_SENSOR, + .addr = BMI160_ADDR0, + .rot_standard_ref = &base_standard_ref, + .default_range = 4, /* g */ + .min_frequency = BMI160_ACCEL_MIN_FREQ, + .max_frequency = BMI160_ACCEL_MAX_FREQ, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 13000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* Sensor on for angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + }, + }, + [BASE_GYRO] = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMI160, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &bmi160_drv, + .mutex = &g_base_mutex, + .drv_data = &g_bmi160_data, + .port = I2C_PORT_SENSOR, + .addr = BMI160_ADDR0, + .default_range = 1000, /* dps */ + .rot_standard_ref = &base_standard_ref, + .min_frequency = BMI160_GYRO_MIN_FREQ, + .max_frequency = BMI160_GYRO_MAX_FREQ, + }, +}; + +unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); + +static int board_is_convertible(void) +{ + /* SKU IDs of Ampton & unprovisioned: 1, 2, 255 */ + return sku_id == 1 || sku_id == 2 || sku_id == 255; +} + +static void board_update_sensor_config_from_sku(void) +{ + if (board_is_convertible()) { + motion_sensor_count = ARRAY_SIZE(motion_sensors); + } else { + motion_sensor_count = 0; + tablet_disable_switch(); + } +} + +/* Read CBI from i2c eeprom and initialize variables for board variants */ +static void cbi_init(void) +{ + uint32_t val; + + if (cbi_get_sku_id(&val) != EC_SUCCESS) + return; + sku_id = val; + ccprints("SKU: %d", sku_id); + + board_update_sensor_config_from_sku(); +} +DECLARE_HOOK(HOOK_INIT, cbi_init, HOOK_PRIO_INIT_I2C + 1); + void board_hibernate_late(void) { /* @@ -112,10 +239,24 @@ void board_hibernate_late(void) gpio_set_flags_by_mask(GPIO_KSI, 0xff, GPIO_INPUT); } -/* TODO(b/115501243): Ampton/Apel: implement motion sensors in EC code */ - void board_overcurrent_event(int port) { /* TODO(b/78344554): pass this signal upstream once hardware reworked */ cprints(CC_USBPD, "p%d: overcurrent!", port); } + +#ifndef TEST_BUILD +/* This callback disables keyboard when convertibles are fully open */ +void lid_angle_peripheral_enable(int enable) +{ + /* + * If the lid is in tablet position via other sensors, + * ignore the lid angle, which might be faulty then + * disable keyboard. + */ + if (tablet_get_mode()) + enable = 0; + if (board_is_convertible()) + keyboard_scan_enable(enable, KB_SCAN_DISABLE_LID_ANGLE); +} +#endif diff --git a/board/ampton/board.h b/board/ampton/board.h index da96365bd3..518333bacb 100644 --- a/board/ampton/board.h +++ b/board/ampton/board.h @@ -13,6 +13,13 @@ #define VARIANT_OCTOPUS_CHARGER_ISL9238 #include "baseboard.h" +/* I2C bus configuraiton */ +#define I2C_PORT_ACCEL I2C_PORT_SENSOR + +/* EC console commands */ +#define CONFIG_CMD_ACCELS +#define CONFIG_CMD_ACCEL_INFO + #define CONFIG_VOLUME_BUTTONS #define GPIO_VOLUME_UP_L GPIO_EC_VOLUP_BTN_ODL #define GPIO_VOLUME_DOWN_L GPIO_EC_VOLDN_BTN_ODL @@ -26,6 +33,13 @@ #define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B #define CONFIG_STEINHART_HART_3V3_13K7_47K_4050B +#define CONFIG_ACCEL_KX022 /* Lid accel */ +#define CONFIG_ACCELGYRO_BMI160 /* Base accel */ + +#define CONFIG_DYNAMIC_MOTION_SENSOR_COUNT +/* Sensors without hardware FIFO are in forced mode */ +#define CONFIG_ACCEL_FORCE_MODE_MASK (1 << LID_ACCEL) + #undef CONFIG_UART_TX_BUF_SIZE #define CONFIG_UART_TX_BUF_SIZE 4096 @@ -35,6 +49,22 @@ #define CONFIG_LED_COMMON +#define CONFIG_LID_ANGLE +#define CONFIG_LID_ANGLE_UPDATE +#define CONFIG_LID_ANGLE_SENSOR_BASE BASE_ACCEL +#define CONFIG_LID_ANGLE_SENSOR_LID LID_ACCEL + +#define CONFIG_ACCEL_INTERRUPTS +/* FIFO size is in power of 2. */ +#define CONFIG_ACCEL_FIFO 1024 + +/* Depends on how fast the AP boots and typical ODRs */ +#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO / 3) +#define CONFIG_MKBP_EVENT +#define CONFIG_MKBP_USE_HOST_EVENT + +#define CONFIG_ACCELGYRO_BMI160_INT_EVENT TASK_EVENT_CUSTOM(1 << 2) + #ifndef __ASSEMBLER__ #include "gpio_signal.h" @@ -55,6 +85,14 @@ enum temp_sensor_id { TEMP_SENSOR_COUNT }; +/* Motion sensors */ +enum sensor_id { + LID_ACCEL, + BASE_ACCEL, + BASE_GYRO, + SENSOR_COUNT +}; + /* List of possible batteries */ enum battery_type { BATTERY_C214, diff --git a/board/ampton/ec.tasklist b/board/ampton/ec.tasklist index 75447efa1f..6f719b4acc 100644 --- a/board/ampton/ec.tasklist +++ b/board/ampton/ec.tasklist @@ -25,6 +25,7 @@ TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, LARGER_TASK_STACK_SIZE) \ TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 1, LARGER_TASK_STACK_SIZE) \ TASK_ALWAYS(CHARGER, charger_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \ TASK_NOTEST(PDCMD, pd_command_task, NULL, TASK_STACK_SIZE) \ -- cgit v1.2.1