From 8c83a01a75414131a5b49aed464215a62d16cb02 Mon Sep 17 00:00:00 2001 From: Bhanu Prakash Maiya Date: Fri, 13 Aug 2021 15:25:26 -0700 Subject: nipperkin: Initial EC image Create the initial EC image for the nipperkin variant by copying the guybrush reference board EC files into a new directory named for the variant. (Auto-Generated by create_initial_ec_image.sh version 1.5.0). BUG=b:194031783 BRANCH=None TEST=make BOARD=nipperkin Signed-off-by: Bhanu Prakash Maiya Change-Id: Ie7b7207a7fee40b120e14199ad3d41e8c0f9d108 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3093489 Commit-Queue: Diana Z Reviewed-by: Diana Z --- board/nipperkin/battery.c | 127 +++++++++++++ board/nipperkin/board.c | 374 ++++++++++++++++++++++++++++++++++++++ board/nipperkin/board.h | 76 ++++++++ board/nipperkin/board_fw_config.c | 42 +++++ board/nipperkin/board_fw_config.h | 38 ++++ board/nipperkin/build.mk | 12 ++ board/nipperkin/ec.tasklist | 26 +++ board/nipperkin/gpio.inc | 13 ++ board/nipperkin/led.c | 91 ++++++++++ board/nipperkin/vif_override.xml | 3 + 10 files changed, 802 insertions(+) create mode 100644 board/nipperkin/battery.c create mode 100644 board/nipperkin/board.c create mode 100644 board/nipperkin/board.h create mode 100644 board/nipperkin/board_fw_config.c create mode 100644 board/nipperkin/board_fw_config.h create mode 100644 board/nipperkin/build.mk create mode 100644 board/nipperkin/ec.tasklist create mode 100644 board/nipperkin/gpio.inc create mode 100644 board/nipperkin/led.c create mode 100644 board/nipperkin/vif_override.xml (limited to 'board/nipperkin') diff --git a/board/nipperkin/battery.c b/board/nipperkin/battery.c new file mode 100644 index 0000000000..ddf3adff50 --- /dev/null +++ b/board/nipperkin/battery.c @@ -0,0 +1,127 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery pack vendor provided charging profile + */ + +#include "battery_fuel_gauge.h" + +/* + * Battery info for all Guybrush battery types. Note that the fields + * start_charging_min/max and charging_min/max are not used for the charger. + * The effective temperature limits are given by discharging_min/max_c. + * + * Fuel Gauge (FG) parameters which are used for determining if the battery + * is connected, the appropriate ship mode (battery cutoff) command, and the + * charge/discharge FETs status. + * + * Ship mode (battery cutoff) requires 2 writes to the appropriate smart battery + * register. For some batteries, the charge/discharge FET bits are set when + * charging/discharging is active, in other types, these bits set mean that + * charging/discharging is disabled. Therefore, in addition to the mask for + * these bits, a disconnect value must be specified. Note that for TI fuel + * gauge, the charge/discharge FET status is found in Operation Status (0x54), + * but a read of Manufacturer Access (0x00) will return the lower 16 bits of + * Operation status which contains the FET status bits. + * + * The assumption for battery types supported is that the charge/discharge FET + * status can be read with a sb_read() command and therefore, only the register + * address, mask, and disconnect value need to be provided. + */ +const struct board_batt_params board_battery_info[] = { + /* AEC 5477109 */ + [BATTERY_AEC] = { + .fuel_gauge = { + .manuf_name = "AEC", + .ship_mode = { + .reg_addr = 0x00, + .reg_data = { 0x0010, 0x0010 }, + }, + .sleep_mode = { + .sleep_supported = true, + .reg_addr = 0x00, + .reg_data = 0x0011, + }, + .fet = { + .reg_addr = 0x0, + .reg_mask = 0x2000, + .disconnect_val = 0x2000, + } + }, + .batt_info = { + .voltage_max = 8700, /* mV */ + .voltage_normal = 7600, + .voltage_min = 6000, + .precharge_current = 100, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 50, + .discharging_min_c = -20, + .discharging_max_c = 60, + }, + }, + /* AP18F4M / LIS4163ACPC */ + [BATTERY_AP18F4M] = { + .fuel_gauge = { + .manuf_name = "Murata KT00404001", + .ship_mode = { + .reg_addr = 0x3A, + .reg_data = { 0xC574, 0xC574 }, + }, + .fet = { + .reg_addr = 0x0, + .reg_mask = 0x2000, + .disconnect_val = 0x2000, + } + }, + .batt_info = { + .voltage_max = 8700, /* mV */ + .voltage_normal = 7600, + .voltage_min = 5500, + .precharge_current = 256, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 50, + .charging_min_c = 0, + .charging_max_c = 60, + .discharging_min_c = -20, + .discharging_max_c = 75, + }, + }, + /* POW-TECH Battery Information */ + [BATTERY_POWER_TECH] = { + .fuel_gauge = { + .manuf_name = "POW-TECH", + .ship_mode = { + .reg_addr = 0x0, + .reg_data = { 0x10, 0x10 }, + }, + .sleep_mode = { + .sleep_supported = true, + .reg_addr = 0x00, + .reg_data = 0x0011, + }, + .fet = { + .reg_addr = 0x00, + .reg_mask = 0x2000, + .disconnect_val = 0x2000, + } + }, + .batt_info = { + .voltage_max = 8800, /* mV */ + .voltage_normal = 7700, + .voltage_min = 6000, + .precharge_current = 88, /* mA */ + .start_charging_min_c = 0, + .start_charging_max_c = 45, + .charging_min_c = 0, + .charging_max_c = 45, + .discharging_min_c = -20, + .discharging_max_c = 60, + }, + }, +}; +BUILD_ASSERT(ARRAY_SIZE(board_battery_info) == BATTERY_TYPE_COUNT); + +const enum battery_type DEFAULT_BATTERY_TYPE = BATTERY_AP18F4M; diff --git a/board/nipperkin/board.c b/board/nipperkin/board.c new file mode 100644 index 0000000000..54cc3a61a5 --- /dev/null +++ b/board/nipperkin/board.c @@ -0,0 +1,374 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Guybrush board-specific configuration */ + +#include "base_fw_config.h" +#include "board_fw_config.h" +#include "button.h" +#include "common.h" +#include "cros_board_info.h" +#include "driver/accelgyro_bmi_common.h" +#include "driver/accelgyro_bmi160.h" +#include "driver/accelgyro_bmi323.h" +#include "driver/accel_bma422.h" +#include "driver/retimer/ps8811.h" +#include "driver/retimer/ps8818.h" +#include "extpower.h" +#include "gpio.h" +#include "hooks.h" +#include "keyboard_scan.h" +#include "lid_switch.h" +#include "power.h" +#include "power_button.h" +#include "switch.h" +#include "tablet_mode.h" +#include "temp_sensor/thermistor.h" +#include "temp_sensor/tmp112.h" +#include "usb_mux.h" + +#include "gpio_list.h" /* Must come after other header files. */ + +/* Motion sensor mutex */ +static struct mutex g_lid_mutex; +static struct mutex g_base_mutex; + +/* Motion sensor private data */ +static struct bmi_drv_data_t g_bmi160_data; +static struct bmi3xx_drv_data g_bmi323_data; +static struct accelgyro_saved_data_t g_bma422_data; + +/* Matrix to rotate accelrator into standard reference frame */ +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)} +}; + +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)} +}; + +/* + * We have total 30 pins for keyboard connecter {-1, -1} mean + * the N/A pin that don't consider it and reserve index 0 area + * that we don't have pin 0. + */ +const int keyboard_factory_scan_pins[][2] = { + {-1, -1}, {0, 5}, {1, 1}, {1, 0}, {0, 6}, + {0, 7}, {-1, -1}, {-1, -1}, {1, 4}, {1, 3}, + {-1, -1}, {1, 6}, {1, 7}, {3, 1}, {2, 0}, + {1, 5}, {2, 6}, {2, 7}, {2, 1}, {2, 4}, + {2, 5}, {1, 2}, {2, 3}, {2, 2}, {3, 0}, + {-1, -1}, {0, 4}, {-1, -1}, {8, 2}, {-1, -1}, + {-1, -1}, +}; +const int keyboard_factory_scan_pins_used = + ARRAY_SIZE(keyboard_factory_scan_pins); + +struct motion_sensor_t motion_sensors[] = { + [BASE_ACCEL] = { + .name = "Base Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMI323, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_BASE, + .drv = &bmi3xx_drv, + .mutex = &g_base_mutex, + .drv_data = &g_bmi323_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = BMI3_ADDR_I2C_PRIM, + .rot_standard_ref = &base_standard_ref, + .min_frequency = BMI_ACCEL_MIN_FREQ, + .max_frequency = BMI_ACCEL_MAX_FREQ, + .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs */ + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 12500 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* Sensor on in S3 */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 12500 | ROUND_UP_FLAG, + .ec_rate = 0, + }, + }, + }, + [LID_ACCEL] = { + .name = "Lid Accel", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMA422, + .type = MOTIONSENSE_TYPE_ACCEL, + .location = MOTIONSENSE_LOC_LID, + .drv = &bma4_accel_drv, + .mutex = &g_lid_mutex, + .drv_data = &g_bma422_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = BMA4_I2C_ADDR_PRIMARY, + .rot_standard_ref = &lid_standard_ref, + .min_frequency = BMA4_ACCEL_MIN_FREQ, + .max_frequency = BMA4_ACCEL_MAX_FREQ, + .default_range = 2, /* g, enough for laptop. */ + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 12500 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* Sensor on in S3 */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 12500 | ROUND_UP_FLAG, + .ec_rate = 0, + }, + }, + }, + [BASE_GYRO] = { + .name = "Base Gyro", + .active_mask = SENSOR_ACTIVE_S0_S3, + .chip = MOTIONSENSE_CHIP_BMI323, + .type = MOTIONSENSE_TYPE_GYRO, + .location = MOTIONSENSE_LOC_BASE, + .drv = &bmi3xx_drv, + .mutex = &g_base_mutex, + .drv_data = &g_bmi323_data, + .port = I2C_PORT_SENSOR, + .i2c_spi_addr_flags = BMI3_ADDR_I2C_PRIM, + .default_range = 1000, /* dps */ + .rot_standard_ref = &base_standard_ref, + .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 bmi160_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, + .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, + .rot_standard_ref = &base_standard_ref, + .min_frequency = BMI_ACCEL_MIN_FREQ, + .max_frequency = BMI_ACCEL_MAX_FREQ, + .default_range = 4, /* g, to meet CDD 7.3.1/C-1-4 reqs */ + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100 * MSEC, + }, + /* Sensor on in S3 */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 0, + }, + }, +}; + +struct motion_sensor_t bmi160_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, + .i2c_spi_addr_flags = BMI160_ADDR0_FLAGS, + .default_range = 1000, /* dps */ + .rot_standard_ref = &base_standard_ref, + .min_frequency = BMI_GYRO_MIN_FREQ, + .max_frequency = BMI_GYRO_MAX_FREQ, +}; + +__override enum ec_error_list +board_a1_ps8811_retimer_init(const struct usb_mux *me) +{ + /* Set channel A output swing */ + RETURN_ERROR(ps8811_i2c_field_update( + me, PS8811_REG_PAGE1, PS8811_REG1_USB_CHAN_A_SWING, + PS8811_CHAN_A_SWING_MASK, 0x2 << PS8811_CHAN_A_SWING_SHIFT)); + + /* Set channel B output swing */ + RETURN_ERROR(ps8811_i2c_field_update( + me, PS8811_REG_PAGE1, PS8811_REG1_USB_CHAN_B_SWING, + PS8811_CHAN_B_SWING_MASK, 0x2 << PS8811_CHAN_B_SWING_SHIFT)); + + /* Set channel B de-emphasis to -6dB and pre-shoot to 1.5 dB */ + RETURN_ERROR(ps8811_i2c_field_update( + me, PS8811_REG_PAGE1, PS8811_REG1_USB_CHAN_B_DE_PS_LSB, + PS8811_CHAN_B_DE_PS_LSB_MASK, PS8811_CHAN_B_DE_6_PS_1_5_LSB)); + + RETURN_ERROR(ps8811_i2c_field_update( + me, PS8811_REG_PAGE1, PS8811_REG1_USB_CHAN_B_DE_PS_MSB, + PS8811_CHAN_B_DE_PS_MSB_MASK, PS8811_CHAN_B_DE_6_PS_1_5_MSB)); + + return EC_SUCCESS; +} + +/* + * PS8818 set mux board tuning. + * Adds in board specific gain and DP lane count configuration + * TODO(b/179036200): Adjust PS8818 tuning for guybrush reference + */ +__override int board_c1_ps8818_mux_set(const struct usb_mux *me, + mux_state_t mux_state) +{ + int rv = EC_SUCCESS; + + /* USB specific config */ + if (mux_state & USB_PD_MUX_USB_ENABLED) { + /* Boost the USB gain */ + rv = ps8818_i2c_field_update8(me, + PS8818_REG_PAGE1, + PS8818_REG1_APTX1EQ_10G_LEVEL, + PS8818_EQ_LEVEL_UP_MASK, + PS8818_EQ_LEVEL_UP_19DB); + if (rv) + return rv; + + rv = ps8818_i2c_field_update8(me, + PS8818_REG_PAGE1, + PS8818_REG1_APTX2EQ_10G_LEVEL, + PS8818_EQ_LEVEL_UP_MASK, + PS8818_EQ_LEVEL_UP_19DB); + if (rv) + return rv; + + rv = ps8818_i2c_field_update8(me, + PS8818_REG_PAGE1, + PS8818_REG1_APTX1EQ_5G_LEVEL, + PS8818_EQ_LEVEL_UP_MASK, + PS8818_EQ_LEVEL_UP_19DB); + if (rv) + return rv; + + rv = ps8818_i2c_field_update8(me, + PS8818_REG_PAGE1, + PS8818_REG1_APTX2EQ_5G_LEVEL, + PS8818_EQ_LEVEL_UP_MASK, + PS8818_EQ_LEVEL_UP_19DB); + if (rv) + return rv; + + /* Set the RX input termination */ + rv = ps8818_i2c_field_update8(me, + PS8818_REG_PAGE1, + PS8818_REG1_RX_PHY, + PS8818_RX_INPUT_TERM_MASK, + PS8818_RX_INPUT_TERM_112_OHM); + if (rv) + return rv; + } + + /* DP specific config */ + if (mux_state & USB_PD_MUX_DP_ENABLED) { + /* Boost the DP gain */ + rv = ps8818_i2c_field_update8(me, + PS8818_REG_PAGE1, + PS8818_REG1_DPEQ_LEVEL, + PS8818_DPEQ_LEVEL_UP_MASK, + PS8818_DPEQ_LEVEL_UP_19DB); + if (rv) + return rv; + + /* Enable HPD on the DB */ + gpio_set_level(GPIO_USB_C1_HPD, 1); + } else { + /* Disable HPD on the DB */ + gpio_set_level(GPIO_USB_C1_HPD, 0); + } + + return rv; +} + +/* + * ANX7491(A1) and ANX7451(C1) are on the same i2c bus. Both default + * to 0x29 for the USB i2c address. This moves ANX7451(C1) USB i2c + * address to 0x2A. ANX7491(A1) will stay at the default 0x29. + */ +uint16_t board_anx7451_get_usb_i2c_addr(const struct usb_mux *me) +{ + ASSERT(me->usb_port == USBC_PORT_C1); + return 0x2a; +} + +/* + * Base Gyro Sensor dynamic configuration + */ +static int base_gyro_config; + +static void board_update_motion_sensor_config(void) +{ + if (board_is_convertible()) { + if (get_board_version() == 1) { + motion_sensors[BASE_ACCEL] = bmi160_base_accel; + motion_sensors[BASE_GYRO] = bmi160_base_gyro; + base_gyro_config = BASE_GYRO_BMI160; + ccprints("BASE GYRO is BMI160"); + } else { + base_gyro_config = BASE_GYRO_BMI323; + ccprints("BASE GYRO is BMI323"); + } + + motion_sensor_count = ARRAY_SIZE(motion_sensors); + /* Enable Base Accel and Gyro interrupt */ + gpio_enable_interrupt(GPIO_6AXIS_INT_L); + } else { + motion_sensor_count = 0; + gmr_tablet_switch_disable(); + /* Base accel is not stuffed, don't allow line to float */ + gpio_set_flags(GPIO_6AXIS_INT_L, GPIO_INPUT | GPIO_PULL_DOWN); + } +} + +void motion_interrupt(enum gpio_signal signal) +{ + switch (base_gyro_config) { + case BASE_GYRO_BMI160: + bmi160_interrupt(signal); + break; + case BASE_GYRO_BMI323: + default: + bmi3xx_interrupt(signal); + break; + } +} + +static void board_init(void) +{ + board_update_motion_sensor_config(); +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +static void board_chipset_startup(void) +{ + if (get_board_version() > 1) + tmp112_init(); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_chipset_startup, + HOOK_PRIO_DEFAULT); + +int board_get_soc_temp(int idx, int *temp_k) +{ + uint32_t board_version = get_board_version(); + + if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) + return EC_ERROR_NOT_POWERED; + + if (board_version == 1) + return get_temp_3v3_30k9_47k_4050b(ADC_TEMP_SENSOR_SOC, temp_k); + + return tmp112_get_val(idx, temp_k); +} diff --git a/board/nipperkin/board.h b/board/nipperkin/board.h new file mode 100644 index 0000000000..dc09530e8e --- /dev/null +++ b/board/nipperkin/board.h @@ -0,0 +1,76 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Guybrush board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +/* Baseboard features */ +#include "baseboard.h" + +/* Motion sensing drivers */ + +/* Keyboard features */ +#define CONFIG_KEYBOARD_FACTORY_TEST + +/* Sensors */ +#define CONFIG_ACCELGYRO_BMI160 +#define CONFIG_ACCELGYRO_BMI160_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) +#define CONFIG_ACCELGYRO_BMI3XX +#define CONFIG_ACCELGYRO_BMI3XX_INT_EVENT \ + TASK_EVENT_MOTION_SENSOR_INTERRUPT(BASE_ACCEL) +#define CONFIG_ACCEL_INTERRUPTS +#define CONFIG_ACCEL_BMA4XX + +#define I2C_PORT_ACCEL I2C_PORT_SENSOR + +/* EC console commands */ +#define CONFIG_CMD_ACCELS +#define CONFIG_CMD_ACCEL_INFO +#define CONFIG_CMD_BUTTON + +/* USB Type C and USB PD defines */ +#define CONFIG_USB_MUX_ANX7451 +#define CONFIG_USBC_RETIMER_ANX7451 + +/* USB Type A Features */ + +/* BC 1.2 */ + +/* Volume Button feature */ + +/* Fan features */ + +/* LED features */ +#define CONFIG_LED_COMMON +#define CONFIG_LED_ONOFF_STATES + +#ifndef __ASSEMBLER__ + +#include "gpio_signal.h" +#include "registers.h" + +/* Motion sensor interrupt */ +void motion_interrupt(enum gpio_signal signal); + +/* Battery Types */ +enum battery_type { + BATTERY_AEC, + BATTERY_AP18F4M, + BATTERY_POWER_TECH, + BATTERY_TYPE_COUNT, +}; + +enum base_accelgyro_type { + BASE_GYRO_NONE = 0, + BASE_GYRO_BMI160 = 1, + BASE_GYRO_BMI323 = 2, +}; + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/nipperkin/board_fw_config.c b/board/nipperkin/board_fw_config.c new file mode 100644 index 0000000000..c919d82851 --- /dev/null +++ b/board/nipperkin/board_fw_config.c @@ -0,0 +1,42 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "base_fw_config.h" +#include "board_fw_config.h" + +bool board_is_convertible(void) +{ + return (get_fw_config_field(FW_CONFIG_FORM_FACTOR_OFFSET, + FW_CONFIG_FORM_FACTOR_WIDTH) + == FW_CONFIG_FORM_FACTOR_CONVERTIBLE); +} + +bool board_has_kblight(void) +{ + return (get_fw_config_field(FW_CONFIG_KBLIGHT_OFFSET, + FW_CONFIG_KBLIGHT_WIDTH) == FW_CONFIG_KBLIGHT_YES); +} + +enum board_usb_c1_mux board_get_usb_c1_mux(void) +{ + int usb_db = get_fw_config_field(FW_CONFIG_USB_DB_OFFSET, + FW_CONFIG_USB_DB_WIDTH); + if (usb_db == FW_CONFIG_USB_DB_A1_PS8811_C1_PS8818) + return USB_C1_MUX_PS8818; + if (usb_db == FW_CONFIG_USB_DB_A1_ANX7491_C1_ANX7451) + return USB_C1_MUX_ANX7451; + return USB_C1_MUX_UNKNOWN; +}; + +enum board_usb_a1_retimer board_get_usb_a1_retimer(void) +{ + int usb_db = get_fw_config_field(FW_CONFIG_USB_DB_OFFSET, + FW_CONFIG_USB_DB_WIDTH); + if (usb_db == FW_CONFIG_USB_DB_A1_PS8811_C1_PS8818) + return USB_A1_RETIMER_PS8811; + if (usb_db == FW_CONFIG_USB_DB_A1_ANX7491_C1_ANX7451) + return USB_A1_RETIMER_ANX7491; + return USB_A1_RETIMER_UNKNOWN; +}; diff --git a/board/nipperkin/board_fw_config.h b/board/nipperkin/board_fw_config.h new file mode 100644 index 0000000000..1de417d77a --- /dev/null +++ b/board/nipperkin/board_fw_config.h @@ -0,0 +1,38 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef _GUYBRUSH_BOARD_FW_CONFIG__H_ +#define _GUYBRUSH_BOARD_FW_CONFIG__H_ + +/**************************************************************************** + * Guybrush CBI FW Configuration + */ + +/* + * USB Daughter Board (2 bits) + */ +#define FW_CONFIG_USB_DB_OFFSET 0 +#define FW_CONFIG_USB_DB_WIDTH 2 +#define FW_CONFIG_USB_DB_A1_PS8811_C1_PS8818 0 +#define FW_CONFIG_USB_DB_A1_ANX7491_C1_ANX7451 1 + +/* + * Form Factor (1 bits) + */ +#define FW_CONFIG_FORM_FACTOR_OFFSET 2 +#define FW_CONFIG_FORM_FACTOR_WIDTH 1 +#define FW_CONFIG_FORM_FACTOR_CLAMSHELL 0 +#define FW_CONFIG_FORM_FACTOR_CONVERTIBLE 1 + +/* + * Keyboard Backlight (1 bit) + */ +#define FW_CONFIG_KBLIGHT_OFFSET 3 +#define FW_CONFIG_KBLIGHT_WIDTH 1 +#define FW_CONFIG_KBLIGHT_NO 0 +#define FW_CONFIG_KBLIGHT_YES 1 + + +#endif /* _GUYBRUSH_CBI_FW_CONFIG__H_ */ diff --git a/board/nipperkin/build.mk b/board/nipperkin/build.mk new file mode 100644 index 0000000000..e4fdcf4afd --- /dev/null +++ b/board/nipperkin/build.mk @@ -0,0 +1,12 @@ +# -*- makefile -*- +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Board specific files build +# + +BASEBOARD:=guybrush + +board-y=board.o +board-y+=board_fw_config.o led.o battery.o diff --git a/board/nipperkin/ec.tasklist b/board/nipperkin/ec.tasklist new file mode 100644 index 0000000000..94ff657db3 --- /dev/null +++ b/board/nipperkin/ec.tasklist @@ -0,0 +1,26 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * See CONFIG_TASK_LIST in config.h for details. + */ + +#define CONFIG_TASK_LIST \ + TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(CHG_RAMP, chg_ramp_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(USB_CHG_P0, usb_charger_task, 0, TASK_STACK_SIZE) \ + TASK_ALWAYS(USB_CHG_P1, usb_charger_task, 1, 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(CHIPSET, chipset_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(HOSTCMD, host_command_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(POWERBTN, power_button_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C1, pd_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C0, pd_interrupt_handler_task, 0, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_INT_C1, pd_interrupt_handler_task, 1, VENTI_TASK_STACK_SIZE) diff --git a/board/nipperkin/gpio.inc b/board/nipperkin/gpio.inc new file mode 100644 index 0000000000..c2db7a2a68 --- /dev/null +++ b/board/nipperkin/gpio.inc @@ -0,0 +1,13 @@ +/* -*- mode:c -*- + * + * Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Declare symbolic names for all the board GPIOs that we care about. */ + +#include "base_gpio.inc" + +GPIO_INT(6AXIS_INT_L, PIN(A, 0), GPIO_INT_FALLING | GPIO_PULL_UP, motion_interrupt) /* 6 Axis IMU */ +GPIO_INT(TABLET_MODE, PIN(C, 1), GPIO_INT_BOTH, gmr_tablet_switch_isr) /* 360 Tablet Mode */ diff --git a/board/nipperkin/led.c b/board/nipperkin/led.c new file mode 100644 index 0000000000..b17c8be488 --- /dev/null +++ b/board/nipperkin/led.c @@ -0,0 +1,91 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Guybrush specific PWM LED settings. + */ + +#include "common.h" +#include "led_onoff_states.h" +#include "led_common.h" +#include "gpio.h" +#include "pwm.h" + +/* Note PWM LEDs are active low */ +#define LED_OFF_LVL 1 +#define LED_ON_LVL 0 + +#define CPRINTS(format, args...) cprints(CC_PWM, format, ## args) + +__override const int led_charge_lvl_1 = 5; + +__override const int led_charge_lvl_2 = 97; + +__override struct led_descriptor + led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { + [STATE_CHARGING_LVL_1] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S3] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, + {LED_OFF, 1 * LED_ONE_SEC} }, + [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_BATTERY_ERROR] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 1 * LED_ONE_SEC} }, + [STATE_FACTORY_TEST] = {{EC_LED_COLOR_AMBER, 2 * LED_ONE_SEC}, + {EC_LED_COLOR_WHITE, 2 * LED_ONE_SEC} }, +}; + +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_BATTERY_LED, +}; + +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +__override void led_set_color_battery(enum ec_led_colors color) +{ + switch (color) { + case EC_LED_COLOR_AMBER: + pwm_enable(PWM_CH_LED_CHRG, LED_ON_LVL); + pwm_enable(PWM_CH_LED_FULL, LED_OFF_LVL); + break; + case EC_LED_COLOR_WHITE: + pwm_enable(PWM_CH_LED_CHRG, LED_OFF_LVL); + pwm_enable(PWM_CH_LED_FULL, LED_ON_LVL); + break; + case LED_OFF: + pwm_enable(PWM_CH_LED_CHRG, LED_OFF_LVL); + pwm_enable(PWM_CH_LED_FULL, LED_OFF_LVL); + break; + default: /* Unsupported colors */ + CPRINTS("Unsupported LED color: %d", color); + pwm_enable(PWM_CH_LED_CHRG, LED_OFF_LVL); + pwm_enable(PWM_CH_LED_FULL, LED_OFF_LVL); + break; + } +} + +void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +{ + if (led_id == EC_LED_ID_BATTERY_LED) { + brightness_range[EC_LED_COLOR_AMBER] = 1; + brightness_range[EC_LED_COLOR_WHITE] = 1; + } +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + if (led_id == EC_LED_ID_BATTERY_LED) { + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_battery(EC_LED_COLOR_WHITE); + else if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(EC_LED_COLOR_AMBER); + else + led_set_color_battery(LED_OFF); + } else { + CPRINTS("Unsupported LED set: %d", led_id); + return EC_ERROR_INVAL; + } + + return EC_SUCCESS; +} diff --git a/board/nipperkin/vif_override.xml b/board/nipperkin/vif_override.xml new file mode 100644 index 0000000000..32736caf64 --- /dev/null +++ b/board/nipperkin/vif_override.xml @@ -0,0 +1,3 @@ + -- cgit v1.2.1