summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjerry2.huang <jerry2.huang@lcfc.corp-partner.google.com>2020-09-28 19:44:24 +0800
committerCommit Bot <commit-bot@chromium.org>2020-10-07 08:10:26 +0000
commit90268827732825a4c537c40a95c0ae7fb9bcc75f (patch)
treec01a06b78c5b7420ae8ddf42e0a20a97ad8b931d
parent8347cde45488634cab4f60aa387a259a6dadf0b3 (diff)
downloadchrome-ec-90268827732825a4c537c40a95c0ae7fb9bcc75f.tar.gz
lindar: Add lid and base accel sensors for lindar and lillipup
Lindar uses LSM6DS3TR as base accel sensor. Lillipup uses LIS2DE12TR as lid accel sensor,and LSM6DS3TR as base accel sensor. The Lindar and Lillipup use the combination firmware, so add lid and base accel sensors at the same time. BUG=b:169530752 BRANCH=none TEST=make buildall -j Signed-off-by: jerry2.huang <jerry2.huang@lcfc.corp-partner.google.com> Change-Id: Ibc8733991f763d2f5c25112bd97ea8f18a61261e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2435170 Reviewed-by: YH Lin <yueherngl@chromium.org> Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r--board/lindar/board.c142
-rw-r--r--board/lindar/board.h30
-rw-r--r--board/lindar/ec.tasklist1
-rw-r--r--board/lindar/gpio.inc16
4 files changed, 179 insertions, 10 deletions
diff --git a/board/lindar/board.c b/board/lindar/board.c
index a4e685a837..ce30e301c9 100644
--- a/board/lindar/board.c
+++ b/board/lindar/board.c
@@ -8,6 +8,8 @@
#include "button.h"
#include "cbi_ec_fw_config.h"
#include "common.h"
+#include "driver/accel_lis2dh.h"
+#include "driver/accelgyro_lsm6dsm.h"
#include "driver/bc12/pi3usb9201.h"
#include "driver/ppc/sn5s330.h"
#include "driver/ppc/syv682x.h"
@@ -68,6 +70,17 @@ union volteer_cbi_fw_config fw_config_defaults = {
static void board_init(void)
{
+ if (ec_cfg_has_tabletmode()) {
+ /* Enable gpio interrupt for base accelgyro sensor */
+ gpio_enable_interrupt(GPIO_EC_IMU_INT_L);
+ } else {
+ motion_sensor_count = 0;
+ /* Device is clamshell only */
+ tablet_set_mode(0);
+ /* Gyro is not present, don't allow line to float */
+ gpio_set_flags(GPIO_EC_IMU_INT_L, GPIO_INPUT | GPIO_PULL_DOWN);
+ }
+
/*
* TODO: b/154447182 - Malefor will control power LED and battery LED
* independently, and keep the max brightness of power LED and battery
@@ -78,6 +91,128 @@ static void board_init(void)
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
+int board_is_lid_angle_tablet_mode(void)
+{
+ return ec_cfg_has_tabletmode();
+}
+
+/* Enable or disable input devices, based on tablet mode or chipset state */
+#ifndef TEST_BUILD
+void lid_angle_peripheral_enable(int enable)
+{
+ if (ec_cfg_has_tabletmode()) {
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF) ||
+ tablet_get_mode())
+ enable = 0;
+ keyboard_scan_enable(enable, KB_SCAN_DISABLE_LID_ANGLE);
+ }
+}
+#endif
+
+/******************************************************************************/
+/* Sensors */
+/* Lid and base Sensor mutex */
+static struct mutex g_lid_accel_mutex;
+static struct mutex g_base_mutex;
+
+/* Lid and base accel private data */
+static struct stprivate_data g_lis2dh_data;
+static struct lsm6dsm_data lsm6dsm_data = LSM6DSM_DATA;
+
+/* Matrix to rotate lid and base sensor into standard reference frame */
+static const mat33_fp_t lid_standard_ref = {
+ { 0, FLOAT_TO_FP(1), 0},
+ { FLOAT_TO_FP(1), 0, 0},
+ { 0, 0, FLOAT_TO_FP(-1)}
+};
+
+static const mat33_fp_t base_standard_ref = {
+ { FLOAT_TO_FP(1), 0, 0},
+ { 0, FLOAT_TO_FP(-1), 0},
+ { 0, 0, FLOAT_TO_FP(-1)}
+};
+
+struct motion_sensor_t motion_sensors[] = {
+ [LID_ACCEL] = {
+ .name = "Lid Accel",
+ .active_mask = SENSOR_ACTIVE_S0_S3,
+ .chip = MOTIONSENSE_CHIP_LIS2DE,
+ .type = MOTIONSENSE_TYPE_ACCEL,
+ .location = MOTIONSENSE_LOC_LID,
+ .drv = &lis2dh_drv,
+ .mutex = &g_lid_accel_mutex,
+ .drv_data = &g_lis2dh_data,
+ .port = I2C_PORT_SENSOR,
+ .i2c_spi_addr_flags = LIS2DH_ADDR1_FLAGS,
+ .rot_standard_ref = &lid_standard_ref,
+ .min_frequency = LIS2DH_ODR_MIN_VAL,
+ .max_frequency = LIS2DH_ODR_MAX_VAL,
+ .default_range = 2, /* g, to support tablet mode */
+ .config = {
+ /* EC use accel for angle detection */
+ [SENSOR_CONFIG_EC_S0] = {
+ .odr = 10000 | ROUND_UP_FLAG,
+ },
+ /* Sensor on in S3 */
+ [SENSOR_CONFIG_EC_S3] = {
+ .odr = 10000 | ROUND_UP_FLAG,
+ },
+ },
+ },
+
+ [BASE_ACCEL] = {
+ .name = "Base Accel",
+ .active_mask = SENSOR_ACTIVE_S0_S3,
+ .chip = MOTIONSENSE_CHIP_LSM6DSM,
+ .type = MOTIONSENSE_TYPE_ACCEL,
+ .location = MOTIONSENSE_LOC_BASE,
+ .drv = &lsm6dsm_drv,
+ .mutex = &g_base_mutex,
+ .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data,
+ MOTIONSENSE_TYPE_ACCEL),
+ .int_signal = GPIO_EC_IMU_INT_L,
+ .flags = MOTIONSENSE_FLAG_INT_SIGNAL,
+ .port = I2C_PORT_SENSOR,
+ .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS,
+ .rot_standard_ref = &base_standard_ref,
+ .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs */
+ .min_frequency = LSM6DSM_ODR_MIN_VAL,
+ .max_frequency = LSM6DSM_ODR_MAX_VAL,
+ .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_LSM6DSM,
+ .type = MOTIONSENSE_TYPE_GYRO,
+ .location = MOTIONSENSE_LOC_BASE,
+ .drv = &lsm6dsm_drv,
+ .mutex = &g_base_mutex,
+ .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data,
+ MOTIONSENSE_TYPE_GYRO),
+ .int_signal = GPIO_EC_IMU_INT_L,
+ .flags = MOTIONSENSE_FLAG_INT_SIGNAL,
+ .port = I2C_PORT_SENSOR,
+ .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS,
+ .default_range = 1000 | ROUND_UP_FLAG, /* dps */
+ .rot_standard_ref = &base_standard_ref,
+ .min_frequency = LSM6DSM_ODR_MIN_VAL,
+ .max_frequency = LSM6DSM_ODR_MAX_VAL,
+ },
+};
+unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors);
/******************************************************************************/
/* Physical fans. These are logically separate from pwm_channels. */
@@ -176,6 +311,13 @@ BUILD_ASSERT(ARRAY_SIZE(mft_channels) == MFT_CH_COUNT);
/* I2C port map configuration */
const struct i2c_port_t i2c_ports[] = {
{
+ .name = "sensor",
+ .port = I2C_PORT_SENSOR,
+ .kbps = 400,
+ .scl = GPIO_EC_I2C0_SENSOR_SCL,
+ .sda = GPIO_EC_I2C0_SENSOR_SDA,
+ },
+ {
.name = "usb_c0",
.port = I2C_PORT_USB_C0,
.kbps = 1000,
diff --git a/board/lindar/board.h b/board/lindar/board.h
index 151b300ff1..bacac9d015 100644
--- a/board/lindar/board.h
+++ b/board/lindar/board.h
@@ -25,10 +25,22 @@
/* Keyboard features */
-/* Sensors not supported*/
-#undef CONFIG_ACCEL_FIFO
-#undef CONFIG_TABLET_MODE
-#undef CONFIG_MKBP_EVENT
+/* Sensors */
+#define CONFIG_DYNAMIC_MOTION_SENSOR_COUNT
+#define CONFIG_ACCEL_LIS2DE /* Lid accel */
+#define CONFIG_ACCELGYRO_LSM6DSM /* Base accel */
+
+/* Sensors without hardware FIFO are in forced mode */
+#define CONFIG_ACCEL_FORCE_MODE_MASK \
+ BIT(LID_ACCEL)
+
+#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_LSM6DSM_INT_EVENT \
+ TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL)
/* USB Type C and USB PD defines */
#define CONFIG_USB_PD_PORT_MAX_COUNT 2
@@ -82,6 +94,7 @@
* which purpose.
*/
#define GPIO_AC_PRESENT GPIO_ACOK_OD
+#define GPIO_EC_INT_L GPIO_EC_PCH_INT_ODL
#define GPIO_EN_PP5000 GPIO_EN_PP5000_A
#define GPIO_ENTERING_RW GPIO_EC_ENTERING_RW
#define GPIO_LID_OPEN GPIO_EC_LID_OPEN
@@ -102,9 +115,11 @@
#define GPIO_USB_C1_BC12_INT_ODL GPIO_USB_C1_MIX_INT_ODL
#define GPIO_VOLUME_UP_L GPIO_EC_VOLUP_BTN_ODL
#define GPIO_VOLUME_DOWN_L GPIO_EC_VOLDN_MUTE_BTN_ODL
+#define GMR_TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L
/* I2C Bus Configuration */
#define CONFIG_I2C
+#define I2C_PORT_SENSOR NPCX_I2C_PORT0_0
#define I2C_PORT_USB_C0 NPCX_I2C_PORT1_0
#define I2C_PORT_USB_C1 NPCX_I2C_PORT2_0
#define I2C_PORT_LIGHTBAR NPCX_I2C_PORT3_0
@@ -137,6 +152,13 @@ enum pwm_channel {
PWM_CH_COUNT
};
+enum sensor_id {
+ LID_ACCEL = 0,
+ BASE_ACCEL,
+ BASE_GYRO,
+ SENSOR_COUNT,
+};
+
enum usbc_port {
USBC_PORT_C0 = 0,
USBC_PORT_C1,
diff --git a/board/lindar/ec.tasklist b/board/lindar/ec.tasklist
index 2c9a9e8e32..292de51cdb 100644
--- a/board/lindar/ec.tasklist
+++ b/board/lindar/ec.tasklist
@@ -13,6 +13,7 @@
TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, TASK_STACK_SIZE) \
TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 0, TASK_STACK_SIZE) \
TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \
TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \
TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \
TASK_ALWAYS(HOSTCMD, host_command_task, NULL, LARGER_TASK_STACK_SIZE) \
diff --git a/board/lindar/gpio.inc b/board/lindar/gpio.inc
index 4c3bce9696..611512a7b6 100644
--- a/board/lindar/gpio.inc
+++ b/board/lindar/gpio.inc
@@ -24,6 +24,11 @@ GPIO_INT(PG_EC_RSMRST_ODL, PIN(E, 2), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(PG_EC_DSW_PWROK, PIN(C, 7), GPIO_INT_BOTH, power_signal_interrupt)
GPIO_INT(PG_EC_ALL_SYS_PWRGD, PIN(F, 4), GPIO_INT_BOTH, power_signal_interrupt)
+/* Sensor Interrupts */
+GPIO_INT(EC_IMU_INT_L, PIN(5, 6), GPIO_INT_FALLING | GPIO_SEL_1P8V, lsm6dsm_interrupt)
+GPIO(EC_ACCEL_INT_L, PIN(8, 1), GPIO_INPUT | GPIO_SEL_1P8V)
+GPIO_INT(TABLET_MODE_L, PIN(9, 5), GPIO_INT_BOTH, gmr_tablet_switch_isr)
+
/* USB-C interrupts */
GPIO_INT(USB_C0_TCPC_INT_ODL, PIN(E, 0), GPIO_INT_BOTH, tcpc_alert_event)
GPIO_INT(USB_C1_TCPC_INT_ODL, PIN(A, 2), GPIO_INT_BOTH, tcpc_alert_event)
@@ -75,6 +80,8 @@ GPIO(EC_PROCHOT_ODL, PIN(6, 3), GPIO_ODR_HIGH)
UNIMPLEMENTED(EC_PROCHOT_IN_L)
GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH)
+GPIO(EC_PCH_INT_ODL, PIN(B, 0), GPIO_ODR_HIGH)
+
/* USB and USBC Signals */
GPIO(USB_C1_RT_RST_ODL, PIN(8, 3), GPIO_ODR_LOW) /* USB_C1 Reset on boards board ID >=1 */
GPIO(USB_C0_OC_ODL, PIN(B, 1), GPIO_ODR_HIGH)
@@ -101,6 +108,8 @@ GPIO(M2_SSD_PLA, PIN(7, 0), GPIO_INPUT) /* SSD power-loss acknoledgement */
GPIO(EC_EDP_BL_EN, PIN(D, 3), GPIO_OUT_HIGH)
/* I2C pins - Alternate function below configures I2C module on these pins */
+GPIO(EC_I2C0_SENSOR_SCL, PIN(B, 5), GPIO_INPUT | GPIO_SEL_1P8V)
+GPIO(EC_I2C0_SENSOR_SDA, PIN(B, 4), GPIO_INPUT | GPIO_SEL_1P8V)
GPIO(EC_I2C1_USB_C0_SCL, PIN(9, 0), GPIO_INPUT)
GPIO(EC_I2C1_USB_C0_SDA, PIN(8, 7), GPIO_INPUT)
GPIO(EC_I2C2_USB_C1_SCL, PIN(9, 2), GPIO_INPUT)
@@ -121,6 +130,7 @@ GPIO(LED_2_L, PIN(C, 3), GPIO_OUT_HIGH) /* Battery - Red LED */
GPIO(LED_3_L, PIN(C, 2), GPIO_OUT_HIGH) /* Power - White LED */
/* Alternate functions GPIO definitions */
+ALTERNATE(PIN_MASK(B, BIT(5) | BIT(4)), 0, MODULE_I2C, (GPIO_INPUT | GPIO_SEL_1P8V)) /* I2C0 */
ALTERNATE(PIN_MASK(9, BIT(0) | BIT(2) | BIT(1)), 0, MODULE_I2C, 0) /* I2C1 SCL / I2C2 */
ALTERNATE(PIN_MASK(8, BIT(7)), 0, MODULE_I2C, 0) /* I2C1 SDA */
ALTERNATE(PIN_MASK(D, BIT(1) | BIT(0)), 0, MODULE_I2C, 0) /* I2C3 */
@@ -153,14 +163,8 @@ ALTERNATE(PIN_MASK(0, BIT(0) | BIT(1) | BIT(2)), 0, MODULE_PMU, 0) /* GPIO00 =
GPIO02 = EC_RST_ODL */
/* Unused signals */
-GPIO(UNUSED_GPIO81, PIN(8, 1), GPIO_INPUT | GPIO_PULL_UP)
-GPIO(UNUSED_GPIOB5, PIN(B, 5), GPIO_INPUT | GPIO_PULL_UP)
-GPIO(UNUSED_GPIOB4, PIN(B, 4), GPIO_INPUT | GPIO_PULL_UP)
GPIO(UNUSED_GPIO60, PIN(6, 0), GPIO_INPUT | GPIO_PULL_UP)
GPIO(UNUSED_GPIO34, PIN(3, 4), GPIO_INPUT | GPIO_PULL_UP)
GPIO(UNUSED_GPIO96, PIN(9, 6), GPIO_INPUT | GPIO_PULL_UP)
GPIO(UNUSED_GPIOF2, PIN(F, 2), GPIO_INPUT | GPIO_PULL_UP)
GPIO(UNUSED_GPIOF3, PIN(F, 3), GPIO_INPUT | GPIO_PULL_UP)
-GPIO(UNUSED_GPIO56, PIN(5, 6), GPIO_INPUT | GPIO_PULL_UP)
-GPIO(UNUSED_GPIO95, PIN(9, 5), GPIO_INPUT | GPIO_PULL_UP)
-GPIO(UNUSED_GPIOB0, PIN(B, 0), GPIO_INPUT | GPIO_PULL_UP)