diff options
-rw-r--r-- | board/lazor/board.c | 148 | ||||
-rw-r--r-- | board/lazor/board.h | 10 | ||||
-rw-r--r-- | board/lazor/gpio.inc | 2 |
3 files changed, 154 insertions, 6 deletions
diff --git a/board/lazor/board.c b/board/lazor/board.c index 66701af613..49d59c10fa 100644 --- a/board/lazor/board.c +++ b/board/lazor/board.c @@ -13,6 +13,10 @@ #include "extpower.h" #include "driver/accel_bma2x2.h" #include "driver/accelgyro_bmi_common.h" +#include "driver/accelgyro_icm_common.h" +#include "driver/accelgyro_icm426xx.h" +#include "driver/accel_kionix.h" +#include "driver/accel_kx022.h" #include "driver/ppc/sn5s330.h" #include "driver/tcpm/ps8xxx.h" #include "driver/tcpm/tcpci.h" @@ -287,22 +291,42 @@ const struct pi3usb9201_config_t pi3usb9201_bc12_chips[] = { static struct mutex g_base_mutex; static struct mutex g_lid_mutex; +static struct kionix_accel_data g_kx022_data; static struct bmi_drv_data_t g_bmi160_data; +static struct icm_drv_data_t g_icm426xx_data; static struct accelgyro_saved_data_t g_bma255_data; +enum base_accelgyro_type { + BASE_GYRO_NONE = 0, + BASE_GYRO_BMI160 = 1, + BASE_GYRO_ICM426XX = 2, +}; + /* Matrix to rotate accelerometer into standard reference frame */ -const mat33_fp_t base_standard_ref = { +const mat33_fp_t base_standard_ref_bmi160 = { { FLOAT_TO_FP(1), 0, 0}, { 0, FLOAT_TO_FP(-1), 0}, { 0, 0, FLOAT_TO_FP(-1)} }; -static const mat33_fp_t lid_standard_ref = { +const mat33_fp_t base_standard_ref_icm426xx = { + { 0, FLOAT_TO_FP(1), 0}, + { FLOAT_TO_FP(1), 0, 0}, + { 0, 0, FLOAT_TO_FP(-1)} +}; + +static const mat33_fp_t lid_standard_ref_bma255 = { { FLOAT_TO_FP(-1), 0, 0}, { 0, FLOAT_TO_FP(-1), 0}, { 0, 0, FLOAT_TO_FP(1)} }; +static const mat33_fp_t lid_standard_ref_kx022 = { + { 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", @@ -315,7 +339,7 @@ struct motion_sensor_t motion_sensors[] = { .drv_data = &g_bma255_data, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = BMA2x2_I2C_ADDR1_FLAGS, - .rot_standard_ref = &lid_standard_ref, + .rot_standard_ref = &lid_standard_ref_bma255, .default_range = 2, /* g, to support lid angle calculation. */ .min_frequency = BMA255_ACCEL_MIN_FREQ, .max_frequency = BMA255_ACCEL_MAX_FREQ, @@ -346,7 +370,7 @@ struct motion_sensor_t motion_sensors[] = { .drv_data = &g_bmi160_data, .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, - .rot_standard_ref = &base_standard_ref, + .rot_standard_ref = &base_standard_ref_bmi160, .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs */ .min_frequency = BMI_ACCEL_MIN_FREQ, .max_frequency = BMI_ACCEL_MAX_FREQ, @@ -373,13 +397,84 @@ struct motion_sensor_t motion_sensors[] = { .port = I2C_PORT_SENSOR, .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, .default_range = 1000, /* dps */ - .rot_standard_ref = &base_standard_ref, + .rot_standard_ref = &base_standard_ref_bmi160, .min_frequency = BMI_GYRO_MIN_FREQ, .max_frequency = BMI_GYRO_MAX_FREQ, }, }; unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); +struct motion_sensor_t kx022_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, + .i2c_spi_addr_flags = KX022_ADDR1_FLAGS, + .rot_standard_ref = &lid_standard_ref_kx022, + .default_range = 2, /* g, enough for laptop. */ + .min_frequency = KX022_ACCEL_MIN_FREQ, + .max_frequency = KX022_ACCEL_MAX_FREQ, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, +}; + +struct motion_sensor_t icm426xx_base_accel = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_ICM426XX, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &icm426xx_drv, + .mutex = &g_base_mutex, + .drv_data = &g_icm426xx_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = ICM426XX_ADDR0_FLAGS, + .default_range = 2, /* g, enough for laptop */ + .rot_standard_ref = &base_standard_ref_icm426xx, + .min_frequency = ICM426XX_ACCEL_MIN_FREQ, + .max_frequency = ICM426XX_ACCEL_MAX_FREQ, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, +}; + +struct motion_sensor_t icm426xx_base_gyro = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_ICM426XX, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &icm426xx_drv, + .mutex = &g_base_mutex, + .drv_data = &g_icm426xx_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = ICM426XX_ADDR0_FLAGS, + .default_range = 1000, /* dps */ + .rot_standard_ref = &base_standard_ref_icm426xx, + .min_frequency = ICM426XX_GYRO_MIN_FREQ, + .max_frequency = ICM426XX_GYRO_MAX_FREQ, +}; + #ifndef TEST_BUILD /* This callback disables keyboard when convertibles are fully open */ void lid_angle_peripheral_enable(int enable) @@ -429,6 +524,48 @@ __override int board_get_default_battery_type(void) return DEFAULT_BATTERY_TYPE; } +static int base_accelgyro_config; + +void motion_interrupt(enum gpio_signal signal) +{ + switch (base_accelgyro_config) { + case BASE_GYRO_ICM426XX: + icm426xx_interrupt(signal); + break; + case BASE_GYRO_BMI160: + default: + bmi160_interrupt(signal); + break; + } +} + +static void board_detect_motionsensor(void) +{ + int ret; + int val; + + /* Check lid accel chip */ + ret = i2c_read8(I2C_PORT_SENSOR, KX022_ADDR1_FLAGS, + KX022_WHOAMI, &val); + + if (!ret) + motion_sensors[LID_ACCEL] = kx022_lid_accel; + + CPRINTS("Lid Accel: %s", ret ? "BMA255" : "KX022"); + + /* Check base accelgyro chip */ + ret = icm_read8(&icm426xx_base_accel, ICM426XX_REG_WHO_AM_I, &val); + if (val == ICM426XX_CHIP_ICM40608) { + motion_sensors[BASE_ACCEL] = icm426xx_base_accel; + motion_sensors[BASE_GYRO] = icm426xx_base_gyro; + } + + base_accelgyro_config = (val == ICM426XX_CHIP_ICM40608) + ? BASE_GYRO_ICM426XX : BASE_GYRO_BMI160; + CPRINTS("Base Accelgyro: %s", (val == ICM426XX_CHIP_ICM40608) + ? "ICM40608" : "BMI160"); +} + static void board_update_sensor_config_from_sku(void) { if (board_is_clamshell()) { @@ -440,6 +577,7 @@ static void board_update_sensor_config_from_sku(void) gpio_set_flags(GPIO_LID_ACCEL_INT_L, GPIO_INPUT | GPIO_PULL_DOWN); } else { + board_detect_motionsensor(); motion_sensor_count = ARRAY_SIZE(motion_sensors); /* Enable interrupt for the base accel sensor */ gpio_enable_interrupt(GPIO_ACCEL_GYRO_INT_L); diff --git a/board/lazor/board.h b/board/lazor/board.h index 6bb8dc806b..0d0d3b2733 100644 --- a/board/lazor/board.h +++ b/board/lazor/board.h @@ -49,6 +49,14 @@ TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) #define OPT3001_I2C_ADDR_FLAGS OPT3001_I2C_ADDR1_FLAGS +/* ICM426XX Base accel/gyro */ +#define CONFIG_ACCELGYRO_ICM426XX +#define CONFIG_ACCELGYRO_ICM426XX_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) + +/* KX022 lid accel */ +#define CONFIG_ACCEL_KX022 + /* BMA253 lid accel */ #define CONFIG_ACCEL_BMA255 #define CONFIG_ACCEL_FORCE_MODE_MASK BIT(LID_ACCEL) @@ -118,6 +126,8 @@ int board_vbus_sink_enable(int port, int enable); /* Reset all TCPCs. */ void board_reset_pd_mcu(void); void board_set_tcpc_power_mode(int port, int mode); +/* Motion sensor interrupt */ +void motion_interrupt(enum gpio_signal signal); #endif /* !defined(__ASSEMBLER__) */ diff --git a/board/lazor/gpio.inc b/board/lazor/gpio.inc index aed9239885..49eb60064f 100644 --- a/board/lazor/gpio.inc +++ b/board/lazor/gpio.inc @@ -41,7 +41,7 @@ GPIO_INT(AP_EC_SPI_CS_L, PIN(5, 3), GPIO_INT_FALLING | GPIO_PULL_DOWN, shi_cs /* Sensor interrupts */ GPIO_INT(TABLET_MODE_L, PIN(C, 6), GPIO_INT_BOTH, gmr_tablet_switch_isr) -GPIO_INT(ACCEL_GYRO_INT_L, PIN(A, 0), GPIO_INT_FALLING, bmi160_interrupt) /* Accelerometer/gyro interrupt */ +GPIO_INT(ACCEL_GYRO_INT_L, PIN(A, 0), GPIO_INT_FALLING, motion_interrupt) /* Accelerometer/gyro interrupt */ /* Switchcap * |