diff options
-rw-r--r-- | baseboard/grunt/baseboard.c | 477 | ||||
-rw-r--r-- | baseboard/grunt/baseboard.h | 208 | ||||
-rw-r--r-- | baseboard/grunt/battery.c (renamed from board/grunt/battery.c) | 3 | ||||
-rw-r--r-- | baseboard/grunt/build.mk | 11 | ||||
-rw-r--r-- | baseboard/grunt/usb_pd_policy.c (renamed from board/grunt/usb_pd_policy.c) | 4 | ||||
-rw-r--r-- | board/careena/board.c | 281 | ||||
-rw-r--r-- | board/careena/board.h | 44 | ||||
-rw-r--r-- | board/careena/build.mk | 14 | ||||
-rw-r--r-- | board/careena/ec.tasklist | 37 | ||||
-rw-r--r-- | board/careena/gpio.inc | 121 | ||||
-rw-r--r-- | board/careena/led.c | 66 | ||||
-rw-r--r-- | board/grunt/board.c | 551 | ||||
-rw-r--r-- | board/grunt/board.h | 202 | ||||
-rw-r--r-- | board/grunt/build.mk | 3 |
14 files changed, 1335 insertions, 687 deletions
diff --git a/baseboard/grunt/baseboard.c b/baseboard/grunt/baseboard.c new file mode 100644 index 0000000000..8bd2232cb9 --- /dev/null +++ b/baseboard/grunt/baseboard.c @@ -0,0 +1,477 @@ +/* Copyright 2018 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. + */ + +/* Grunt family-specific configuration */ + +#include "adc.h" +#include "adc_chip.h" +#include "button.h" +#include "charge_manager.h" +#include "charge_state.h" +#include "charge_state_v2.h" +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "driver/accel_kionix.h" +#include "driver/accel_kx022.h" +#include "driver/accelgyro_bmi160.h" +#include "driver/bc12/bq24392.h" +#include "driver/led/lm3630a.h" +#include "driver/ppc/sn5s330.h" +#include "driver/tcpm/anx74xx.h" +#include "driver/tcpm/ps8xxx.h" +#include "driver/temp_sensor/sb_tsi.h" +#include "ec_commands.h" +#include "extpower.h" +#include "gpio.h" +#include "hooks.h" +#include "i2c.h" +#include "keyboard_scan.h" +#include "lid_switch.h" +#include "motion_sense.h" +#include "power.h" +#include "power_button.h" +#include "pwm.h" +#include "pwm_chip.h" +#include "registers.h" +#include "switch.h" +#include "system.h" +#include "task.h" +#include "tcpci.h" +#include "temp_sensor.h" +#include "thermistor.h" +#include "usb_mux.h" +#include "usb_pd_tcpm.h" +#include "usbc_ppc.h" +#include "util.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +const enum gpio_signal hibernate_wake_pins[] = { + GPIO_LID_OPEN, + GPIO_AC_PRESENT, + GPIO_POWER_BUTTON_L, +}; +const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); + +const struct adc_t adc_channels[] = { + [ADC_TEMP_SENSOR_CHARGER] = { + "CHARGER", NPCX_ADC_CH0, ADC_MAX_VOLT, ADC_READ_MAX+1, 0 + }, + [ADC_TEMP_SENSOR_SOC] = { + "SOC", NPCX_ADC_CH1, ADC_MAX_VOLT, ADC_READ_MAX+1, 0 + }, + [ADC_VBUS] = { + "VBUS", NPCX_ADC_CH8, ADC_MAX_VOLT*10, ADC_READ_MAX+1, 0 + }, + [ADC_SKU_ID1] = { + "SKU1", NPCX_ADC_CH9, ADC_MAX_VOLT, ADC_READ_MAX+1, 0 + }, + [ADC_SKU_ID2] = { + "SKU2", NPCX_ADC_CH4, ADC_MAX_VOLT, ADC_READ_MAX+1, 0 + }, +}; +BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); + +/* Power signal list. Must match order of enum power_signal. */ +const struct power_signal_info power_signal_list[] = { + {GPIO_PCH_SLP_S3_L, POWER_SIGNAL_ACTIVE_HIGH, "SLP_S3_DEASSERTED"}, + {GPIO_PCH_SLP_S5_L, POWER_SIGNAL_ACTIVE_HIGH, "SLP_S5_DEASSERTED"}, + {GPIO_S0_PGOOD, POWER_SIGNAL_ACTIVE_HIGH, "S0_PGOOD"}, + {GPIO_S5_PGOOD, POWER_SIGNAL_ACTIVE_HIGH, "S5_PGOOD"}, +}; +BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT); + +const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = { + [USB_PD_PORT_ANX74XX] = { + .i2c_host_port = I2C_PORT_TCPC0, + .i2c_slave_addr = ANX74XX_I2C_ADDR1, + .drv = &anx74xx_tcpm_drv, + .pol = TCPC_ALERT_ACTIVE_LOW, + }, + [USB_PD_PORT_PS8751] = { + .i2c_host_port = I2C_PORT_TCPC1, + .i2c_slave_addr = PS8751_I2C_ADDR1, + .drv = &ps8xxx_tcpm_drv, + .pol = TCPC_ALERT_ACTIVE_LOW, + }, +}; + +struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_COUNT] = { + [USB_PD_PORT_ANX74XX] = { + .port_addr = USB_PD_PORT_ANX74XX, + .driver = &anx74xx_tcpm_usb_mux_driver, + .hpd_update = &anx74xx_tcpc_update_hpd_status, + }, + [USB_PD_PORT_PS8751] = { + .port_addr = USB_PD_PORT_PS8751, + .driver = &tcpci_tcpm_usb_mux_driver, + .hpd_update = &ps8xxx_tcpc_update_hpd_status, + /* TODO(ecgh): ps8751_tune_mux needed? */ + } +}; + +struct ppc_config_t ppc_chips[] = { + { + .i2c_port = I2C_PORT_TCPC0, + .i2c_addr = SN5S330_ADDR0, + .drv = &sn5s330_drv + }, + { + .i2c_port = I2C_PORT_TCPC1, + .i2c_addr = SN5S330_ADDR0, + .drv = &sn5s330_drv + }, +}; +unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); + +/* BC 1.2 chip Configuration */ +const struct bq24392_config_t bq24392_config[CONFIG_USB_PD_PORT_COUNT] = { + [USB_PD_PORT_ANX74XX] = { + .chip_enable_pin = GPIO_USB_C0_BC12_VBUS_ON_L_V2, + .chg_det_pin = GPIO_USB_C0_BC12_CHG_DET, + .flags = BQ24392_FLAGS_ENABLE_ACTIVE_LOW, + }, + [USB_PD_PORT_PS8751] = { + .chip_enable_pin = GPIO_USB_C1_BC12_VBUS_ON_L, + .chg_det_pin = GPIO_USB_C1_BC12_CHG_DET, + .flags = BQ24392_FLAGS_ENABLE_ACTIVE_LOW, + }, +}; + +const int usb_port_enable[USB_PORT_COUNT] = { + GPIO_EN_USB_A0_5V, + GPIO_EN_USB_A1_5V, +}; + +static void baseboard_chipset_suspend(void) +{ + /* + * Turn off display backlight. This ensures that the backlight stays off + * in S3, no matter what the AP has it set to. The AP also controls it. + * This is here more for legacy reasons. + */ + gpio_set_level(GPIO_ENABLE_BACKLIGHT_L, 1); +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, baseboard_chipset_suspend, + HOOK_PRIO_DEFAULT); + +static void baseboard_chipset_resume(void) +{ + /* Allow display backlight to turn on. See above backlight comment */ + gpio_set_level(GPIO_ENABLE_BACKLIGHT_L, 0); + +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, baseboard_chipset_resume, HOOK_PRIO_DEFAULT); + +static void baseboard_chipset_startup(void) +{ + /* + * Enable sensor power (lid accel, gyro) in S3 for calculating the lid + * angle (needed on convertibles to disable resume from keyboard in + * tablet mode). + */ + gpio_set_level(GPIO_EN_PP1800_SENSOR, 1); +} +DECLARE_HOOK(HOOK_CHIPSET_STARTUP, baseboard_chipset_startup, + HOOK_PRIO_DEFAULT); + +static void baseboard_chipset_shutdown(void) +{ + /* Disable sensor power (lid accel, gyro) in S5. */ + gpio_set_level(GPIO_EN_PP1800_SENSOR, 0); +} +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, baseboard_chipset_shutdown, + HOOK_PRIO_DEFAULT); + +int board_set_active_charge_port(int port) +{ + int i; + + CPRINTS("New chg p%d", port); + + if (port == CHARGE_PORT_NONE) { + /* Disable all ports. */ + for (i = 0; i < ppc_cnt; i++) { + if (ppc_vbus_sink_enable(i, 0)) + CPRINTS("p%d: sink disable failed.", i); + } + + return EC_SUCCESS; + } + + /* Check if the port is sourcing VBUS. */ + if (ppc_is_sourcing_vbus(port)) { + CPRINTF("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < ppc_cnt; i++) { + if (i == port) + continue; + + if (ppc_vbus_sink_enable(i, 0)) + CPRINTS("p%d: sink disable failed.", i); + } + + /* Enable requested charge port. */ + if (ppc_vbus_sink_enable(port, 1)) { + CPRINTS("p%d: sink enable failed."); + return EC_ERROR_UNKNOWN; + } + + return EC_SUCCESS; +} + +void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + charge_set_input_current_limit(MAX(charge_ma, + CONFIG_CHARGER_INPUT_CURRENT), + charge_mv); +} + +/* Keyboard scan setting */ +struct keyboard_scan_config keyscan_config = { + /* Extra delay when KSO2 is tied to Cr50. */ + .output_settle_us = 60, + .debounce_down_us = 6 * MSEC, + .debounce_up_us = 30 * MSEC, + .scan_period_us = 1500, + .min_post_scan_delay_us = 1000, + .poll_timeout_us = SECOND, + .actual_key_mask = { + 0x3c, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, + 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */ + }, +}; + +/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */ +const struct pwm_t pwm_channels[] = { + [PWM_CH_KBLIGHT] = { 5, 0, 100 }, + [PWM_CH_LED1_AMBER] = { + 0, PWM_CONFIG_OPEN_DRAIN | PWM_CONFIG_ACTIVE_LOW | + PWM_CONFIG_DSLEEP, 100 + }, + [PWM_CH_LED2_BLUE] = { + 2, PWM_CONFIG_OPEN_DRAIN | PWM_CONFIG_ACTIVE_LOW | + PWM_CONFIG_DSLEEP, 100 + }, +}; +BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); + +/* + * We use 11 as the scaling factor so that the maximum mV value below (2761) + * can be compressed to fit in a uint8_t. + */ +#define THERMISTOR_SCALING_FACTOR 11 + +/* + * Values are calculated from the "Resistance VS. Temperature" table on the + * Murata page for part NCP15WB473F03RC. Vdd=3.3V, R=30.9Kohm. + */ +static const struct thermistor_data_pair thermistor_data[] = { + { 2761 / THERMISTOR_SCALING_FACTOR, 0}, + { 2492 / THERMISTOR_SCALING_FACTOR, 10}, + { 2167 / THERMISTOR_SCALING_FACTOR, 20}, + { 1812 / THERMISTOR_SCALING_FACTOR, 30}, + { 1462 / THERMISTOR_SCALING_FACTOR, 40}, + { 1146 / THERMISTOR_SCALING_FACTOR, 50}, + { 878 / THERMISTOR_SCALING_FACTOR, 60}, + { 665 / THERMISTOR_SCALING_FACTOR, 70}, + { 500 / THERMISTOR_SCALING_FACTOR, 80}, + { 434 / THERMISTOR_SCALING_FACTOR, 85}, + { 376 / THERMISTOR_SCALING_FACTOR, 90}, + { 326 / THERMISTOR_SCALING_FACTOR, 95}, + { 283 / THERMISTOR_SCALING_FACTOR, 100} +}; + +static const struct thermistor_info thermistor_info = { + .scaling_factor = THERMISTOR_SCALING_FACTOR, + .num_pairs = ARRAY_SIZE(thermistor_data), + .data = thermistor_data, +}; + +static int board_get_temp(int idx, int *temp_k) +{ + /* idx is the sensor index set below in temp_sensors[] */ + int mv = adc_read_channel( + idx ? ADC_TEMP_SENSOR_SOC : ADC_TEMP_SENSOR_CHARGER); + int temp_c; + + if (mv < 0) + return -1; + + temp_c = thermistor_linear_interpolate(mv, &thermistor_info); + *temp_k = C_TO_K(temp_c); + return 0; +} + +const struct temp_sensor_t temp_sensors[] = { + {"Charger", TEMP_SENSOR_TYPE_BOARD, board_get_temp, 0, 1}, + {"SOC", TEMP_SENSOR_TYPE_BOARD, board_get_temp, 1, 5}, + {"CPU", TEMP_SENSOR_TYPE_CPU, sb_tsi_get_val, 0, 4}, +}; +BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); + +/* Motion sensors */ +static struct mutex g_lid_mutex; +static struct mutex g_base_mutex; + +/* + * Matrix to rotate accelerator into standard reference frame + * + * TODO(teravest): Update this when we can physically test a Grunt. + */ +const matrix_3x3_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; + +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 = 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_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, + .default_range = 2, /* g, enough for laptop */ + .rot_standard_ref = &base_standard_ref, + .min_frequency = BMI160_ACCEL_MIN_FREQ, + .max_frequency = BMI160_ACCEL_MAX_FREQ, + .config = { + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S0] = { + .odr = 10000 | ROUND_UP_FLAG, + .ec_rate = 100, + }, + /* EC use accel for angle detection */ + [SENSOR_CONFIG_EC_S3] = { + .odr = 10000 | ROUND_UP_FLAG, + }, + }, + }, + + [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, + }, +}; + +const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); + +#ifndef TEST_BUILD +void lid_angle_peripheral_enable(int enable) +{ + keyboard_scan_enable(enable, KB_SCAN_DISABLE_LID_ANGLE); +} +#endif + +static const int sku_thresh_mv[] = { + /* Vin = 3.3V, Ideal voltage, R2 values listed below */ + /* R1 = 51.1 kOhm */ + 200, /* 124 mV, 2.0 Kohm */ + 366, /* 278 mV, 4.7 Kohm */ + 550, /* 456 mV, 8.2 Kohm */ + 752, /* 644 mV, 12.4 Kohm */ + 927, /* 860 mV, 18.0 Kohm */ + 1073, /* 993 mV, 22.0 Kohm */ + 1235, /* 1152 mV, 27.4 Kohm */ + 1386, /* 1318 mV, 34.0 Kohm */ + 1552, /* 1453 mV, 40.2 Kohm */ + /* R1 = 10.0 kOhm */ + 1739, /* 1650 mV, 10.0 Kohm */ + 1976, /* 1827 mV, 12.4 Kohm */ + 2197, /* 2121 mV, 18.0 Kohm */ + 2344, /* 2269 mV, 22.0 Kohm */ + 2484, /* 2418 mV, 27.4 Kohm */ + 2636, /* 2550 mV, 34.0 Kohm */ + 2823, /* 2721 mV, 47.0 Kohm */ +}; + +static int board_read_sku_adc(enum adc_channel chan) +{ + int mv; + int i; + + mv = adc_read_channel(chan); + + if (mv == ADC_READ_ERROR) + return -1; + + for (i = 0; i < ARRAY_SIZE(sku_thresh_mv); i++) + if (mv < sku_thresh_mv[i]) + return i; + + return -1; +} + +uint32_t system_get_sku_id(void) +{ + static uint32_t sku_id = -1; + int sku_id1, sku_id2; + + if (sku_id != -1) + return sku_id; + + sku_id1 = board_read_sku_adc(ADC_SKU_ID1); + sku_id2 = board_read_sku_adc(ADC_SKU_ID2); + + if (sku_id1 < 0 || sku_id2 < 0) + return 0; + + sku_id = (sku_id2 << 4) | sku_id1; + return sku_id; +} diff --git a/baseboard/grunt/baseboard.h b/baseboard/grunt/baseboard.h new file mode 100644 index 0000000000..9ee1e8ca67 --- /dev/null +++ b/baseboard/grunt/baseboard.h @@ -0,0 +1,208 @@ +/* Copyright 2018 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. + */ + +/* Grunt family-specific configuration */ + +#ifndef __CROS_EC_BASEBOARD_H +#define __CROS_EC_BASEBOARD_H + +/* NPCX7 config */ +#define NPCX_UART_MODULE2 1 /* GPIO64/65 are used as UART pins. */ +#define NPCX_TACH_SEL2 0 /* No tach. */ +#define NPCX7_PWM1_SEL 0 /* GPIO C2 is not used as PWM1. */ + +/* Internal SPI flash on NPCX7 */ +/* Flash is 1MB but reserve half for future use. */ +#define CONFIG_FLASH_SIZE (512 * 1024) +#define CONFIG_SPI_FLASH_REGS +#define CONFIG_SPI_FLASH_W25Q80 /* Internal SPI flash type. */ + +/* + * Enable 1 slot of secure temporary storage to support + * suspend/resume with read/write memory training. + */ +#define CONFIG_VSTORE +#define CONFIG_VSTORE_SLOT_COUNT 1 + +#define CONFIG_ADC +#define CONFIG_BACKLIGHT_LID +#define CONFIG_BACKLIGHT_LID_ACTIVE_LOW +#define CONFIG_BOARD_VERSION_GPIO +#define CONFIG_HIBERNATE_PSL +#define CONFIG_HOSTCMD_LPC +#define CONFIG_HOSTCMD_SKUID +#define CONFIG_I2C +#define CONFIG_I2C_MASTER +#define CONFIG_PWM +#define CONFIG_PWM_KBLIGHT +#define CONFIG_TEMP_SENSOR +#define CONFIG_THERMISTOR_NCP15WB +#define CONFIG_VBOOT_HASH +#define CONFIG_VOLUME_BUTTONS + +#define CONFIG_BATTERY_CUT_OFF +#define CONFIG_BATTERY_HW_PRESENT_CUSTOM +#define CONFIG_BATTERY_PRESENT_CUSTOM +#define CONFIG_BATTERY_SMART + +#define CONFIG_BC12_DETECT_BQ24392 +#define CONFIG_CHARGER +#define CONFIG_CHARGER_V2 +#define CONFIG_CHARGE_MANAGER +#define CONFIG_CHARGER_DISCHARGE_ON_AC +#define CONFIG_CHARGER_INPUT_CURRENT 128 +#define CONFIG_CHARGER_ISL9238 +#define CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON 1 +#define CONFIG_CHARGER_SENSE_RESISTOR 10 +#define CONFIG_CHARGER_SENSE_RESISTOR_AC 20 +#define CONFIG_CHARGE_RAMP_HW +#define CONFIG_USB_CHARGER + +#define CONFIG_CHIPSET_STONEY +#define CONFIG_CHIPSET_RESET_HOOK +/* + * ACOK from ISL9238 sometimes has a negative pulse after connecting + * USB-C power. We want to ignore it. b/77455171 + */ +#undef CONFIG_EXTPOWER_DEBOUNCE_MS +#define CONFIG_EXTPOWER_DEBOUNCE_MS 200 +#define CONFIG_EXTPOWER_GPIO +#define CONFIG_POWER_COMMON +#define CONFIG_POWER_SHUTDOWN_PAUSE_IN_S5 +#define CONFIG_POWER_BUTTON +#define CONFIG_POWER_BUTTON_X86 + +#define CONFIG_KEYBOARD_BOARD_CONFIG +#define CONFIG_KEYBOARD_COL2_INVERTED +#define CONFIG_KEYBOARD_PROTOCOL_8042 +#define CONFIG_KEYBOARD_REFRESH_ROW3 +#define CONFIG_KEYBOARD_IGNORE_REFRESH_BOOT_KEY +#define CONFIG_KEYBOARD_PWRBTN_ASSERTS_KSI3 + +#define CONFIG_USB_POWER_DELIVERY +#define CONFIG_CMD_PD_CONTROL +#define CONFIG_USB_PD_ALT_MODE +#define CONFIG_USB_PD_ALT_MODE_DFP +#define CONFIG_USB_PD_COMM_LOCKED +#define CONFIG_USB_PD_DISCHARGE_PPC +#define CONFIG_USB_PD_DUAL_ROLE +#define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE +#define CONFIG_USB_PD_LOGGING +#define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 +#define CONFIG_USB_PD_PORT_COUNT 2 +#define CONFIG_USB_PD_TCPC_LOW_POWER +#define CONFIG_USB_PD_TCPM_ANX3429 +#define CONFIG_USB_PD_TCPM_MUX +#define CONFIG_USB_PD_TCPM_PS8751 +#define CONFIG_USB_PD_TCPM_TCPCI +#define CONFIG_USB_PD_TRY_SRC +#define CONFIG_USB_PD_VBUS_DETECT_PPC +#define CONFIG_USBC_PPC_SN5S330 +#define CONFIG_USBC_SS_MUX +#define CONFIG_USBC_SS_MUX_DFP_ONLY +#define CONFIG_USBC_VCONN +#define CONFIG_USBC_VCONN_SWAP + +/* USB-A config */ +#define CONFIG_USB_PORT_POWER_DUMB +#define USB_PORT_COUNT 2 + +/* TODO(b/69683108): Use correct PD delay values */ +#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */ +#define PD_POWER_SUPPLY_TURN_OFF_DELAY 250000 /* us */ +#define PD_VCONN_SWAP_DELAY 5000 /* us */ + +/* TODO(b/69683178): Use correct PD power values */ +#define PD_OPERATING_POWER_MW 15000 +#define PD_MAX_POWER_MW 45000 +#define PD_MAX_CURRENT_MA 3000 +#define PD_MAX_VOLTAGE_MV 20000 + +#define I2C_PORT_BATTERY I2C_PORT_POWER +#define I2C_PORT_CHARGER I2C_PORT_POWER +#define I2C_PORT_POWER NPCX_I2C_PORT0_0 +#define I2C_PORT_TCPC0 NPCX_I2C_PORT1_0 +#define I2C_PORT_TCPC1 NPCX_I2C_PORT2_0 +#define I2C_PORT_THERMAL NPCX_I2C_PORT3_0 +#define I2C_PORT_SENSOR NPCX_I2C_PORT7_0 +/* Accelerometer and Gyroscope are the same device. */ +#define I2C_PORT_ACCEL I2C_PORT_SENSOR + +/* Sensors */ +#define CONFIG_MKBP_EVENT +#define CONFIG_MKBP_USE_HOST_EVENT +#define CONFIG_ACCELGYRO_BMI160 +#define CONFIG_ACCELGYRO_BMI160_INT_EVENT TASK_EVENT_CUSTOM(4) +#define CONFIG_ACCEL_INTERRUPTS +#define CONFIG_ACCEL_KX022 +#define CONFIG_CMD_ACCELS +#define CONFIG_CMD_ACCEL_INFO +#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 + +/* Thermal */ +#define CONFIG_TEMP_SENSOR_SB_TSI + +/* FIFO size is a power of 2. */ +#define CONFIG_ACCEL_FIFO 1024 /* TODO(teravest): Check this value. */ + +/* Depends on how fast the AP boots and typical ODRs. */ +#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO / 3) + +#define USB_PD_PORT_ANX74XX 0 +#define USB_PD_PORT_PS8751 1 + +#ifndef __ASSEMBLER__ + +#include "gpio_signal.h" +#include "registers.h" + +enum adc_channel { + ADC_TEMP_SENSOR_CHARGER, + ADC_TEMP_SENSOR_SOC, + ADC_VBUS, + ADC_SKU_ID1, + ADC_SKU_ID2, + ADC_CH_COUNT +}; + +enum power_signal { + X86_SLP_S3_N, + X86_SLP_S5_N, + X86_S0_PGOOD, + X86_S5_PGOOD, + POWER_SIGNAL_COUNT +}; + +enum temp_sensor_id { + TEMP_SENSOR_CHARGER = 0, + TEMP_SENSOR_SOC, + TEMP_SENSOR_CPU, + TEMP_SENSOR_COUNT +}; + +enum pwm_channel { + PWM_CH_KBLIGHT = 0, + PWM_CH_LED1_AMBER, + PWM_CH_LED2_BLUE, + PWM_CH_COUNT +}; + +enum sensor_id { + LID_ACCEL, + BASE_ACCEL, + BASE_GYRO, +}; + +/* Sensors without hardware FIFO are in forced mode */ +#define CONFIG_ACCEL_FORCE_MODE_MASK (1 << LID_ACCEL) + +void board_reset_pd_mcu(void); + +#endif /* !__ASSEMBLER__ */ + +#endif /* __CROS_EC_BASEBOARD_H */ diff --git a/board/grunt/battery.c b/baseboard/grunt/battery.c index d3a10e75f5..8c9755daac 100644 --- a/board/grunt/battery.c +++ b/baseboard/grunt/battery.c @@ -1,9 +1,10 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. +/* Copyright 2018 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.h" #include "battery_smart.h" #include "console.h" diff --git a/baseboard/grunt/build.mk b/baseboard/grunt/build.mk new file mode 100644 index 0000000000..5a5942a0c6 --- /dev/null +++ b/baseboard/grunt/build.mk @@ -0,0 +1,11 @@ +# -*- makefile -*- +# Copyright 2018 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. +# +# Baseboard specific files build +# + +baseboard-y=baseboard.o +baseboard-$(CONFIG_BATTERY_SMART)+=battery.o +baseboard-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_policy.o diff --git a/board/grunt/usb_pd_policy.c b/baseboard/grunt/usb_pd_policy.c index e4cf87efa4..0d18aad5f1 100644 --- a/board/grunt/usb_pd_policy.c +++ b/baseboard/grunt/usb_pd_policy.c @@ -1,8 +1,10 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. +/* Copyright 2018 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. */ +/* Shared USB-C policy for Grunt boards */ + #include "charge_manager.h" #include "common.h" #include "compile_time_macros.h" diff --git a/board/careena/board.c b/board/careena/board.c new file mode 100644 index 0000000000..cdf0652307 --- /dev/null +++ b/board/careena/board.c @@ -0,0 +1,281 @@ +/* Copyright 2018 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. + */ + +/* Careena board-specific configuration */ + +#include "adc.h" +#include "adc_chip.h" +#include "button.h" +#include "charge_manager.h" +#include "charge_state.h" +#include "charge_state_v2.h" +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "driver/accel_kionix.h" +#include "driver/accel_kx022.h" +#include "driver/accelgyro_bmi160.h" +#include "driver/bc12/bq24392.h" +#include "driver/led/lm3630a.h" +#include "driver/ppc/sn5s330.h" +#include "driver/tcpm/anx74xx.h" +#include "driver/tcpm/ps8xxx.h" +#include "driver/temp_sensor/sb_tsi.h" +#include "ec_commands.h" +#include "extpower.h" +#include "gpio.h" +#include "hooks.h" +#include "i2c.h" +#include "keyboard_scan.h" +#include "lid_switch.h" +#include "motion_sense.h" +#include "power.h" +#include "power_button.h" +#include "pwm.h" +#include "pwm_chip.h" +#include "registers.h" +#include "switch.h" +#include "system.h" +#include "task.h" +#include "tcpci.h" +#include "temp_sensor.h" +#include "thermistor.h" +#include "usb_mux.h" +#include "usb_pd_tcpm.h" +#include "usbc_ppc.h" +#include "util.h" + +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + +/* + * These GPIOs change pins depending on board version. They are configured + * in board_init. + */ +static enum gpio_signal gpio_usb_c1_oc_l = GPIO_USB_C1_OC_L_V2; +static enum gpio_signal gpio_usb_c0_pd_rst_l = GPIO_USB_C0_PD_RST_L_V2; + +static void tcpc_alert_event(enum gpio_signal signal) +{ + if ((signal == GPIO_USB_C0_PD_INT_ODL) && + !gpio_get_level(gpio_usb_c0_pd_rst_l)) + return; + + if ((signal == GPIO_USB_C1_PD_INT_ODL) && + !gpio_get_level(GPIO_USB_C1_PD_RST_L)) + return; + +#ifdef HAS_TASK_PDCMD + /* Exchange status with TCPCs */ + host_command_pd_send_status(PD_CHARGE_NO_CHANGE); +#endif +} + +#ifdef CONFIG_USB_PD_TCPC_LOW_POWER +static void anx74xx_cable_det_handler(void) +{ + int cable_det = gpio_get_level(GPIO_USB_C0_CABLE_DET); + int reset_n = gpio_get_level(gpio_usb_c0_pd_rst_l); + + /* + * A cable_det low->high transition was detected. If following the + * debounce time, cable_det is high, and reset_n is low, then ANX3429 is + * currently in standby mode and needs to be woken up. Set the + * TCPC_RESET event which will bring the ANX3429 out of standby + * mode. Setting this event is gated on reset_n being low because the + * ANX3429 will always set cable_det when transitioning to normal mode + * and if in normal mode, then there is no need to trigger a tcpc reset. + */ + if (cable_det && !reset_n) + task_set_event(TASK_ID_PD_C0, PD_EVENT_TCPC_RESET, 0); +} +DECLARE_DEFERRED(anx74xx_cable_det_handler); + +void anx74xx_cable_det_interrupt(enum gpio_signal signal) +{ + /* debounce for 2 msec */ + hook_call_deferred(&anx74xx_cable_det_handler_data, (2 * MSEC)); +} +#endif + +static void ppc_interrupt(enum gpio_signal signal) +{ + int port = (signal == GPIO_USB_C0_SWCTL_INT_ODL) ? 0 : 1; + + sn5s330_interrupt(port); +} + +#include "gpio_list.h" + +/* I2C port map. */ +const struct i2c_port_t i2c_ports[] = { + {"power", I2C_PORT_POWER, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, + {"tcpc0", I2C_PORT_TCPC0, 400, GPIO_I2C1_SCL, GPIO_I2C1_SDA}, + {"tcpc1", I2C_PORT_TCPC1, 400, GPIO_I2C2_SCL, GPIO_I2C2_SDA}, + {"thermal", I2C_PORT_THERMAL, 400, GPIO_I2C3_SCL, GPIO_I2C3_SDA}, + {"kblight", I2C_PORT_KBLIGHT, 100, GPIO_I2C5_SCL, GPIO_I2C5_SDA}, + {"sensor", I2C_PORT_SENSOR, 400, GPIO_I2C7_SCL, GPIO_I2C7_SDA}, +}; +const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); + +static void board_init(void) +{ + if (system_get_board_version() < 2) { + /* + * These GPIOs change pins depending on board version. Change + * them here from the V2 pin to the V0 pin. + */ + gpio_usb_c1_oc_l = GPIO_USB_C1_OC_L_V0; + gpio_usb_c0_pd_rst_l = GPIO_USB_C0_PD_RST_L_V0; + } else { + /* Alternate functions for board version 2 only. */ + gpio_set_alternate_function(GPIO_F, 0x02, 1); /* ADC8 */ + gpio_set_alternate_function(GPIO_0, 0x10, 0); /* KSO_13 */ + gpio_set_alternate_function(GPIO_8, 0x04, 0); /* KSO_14 */ + } + + /* Now that we know which pin to use, set the correct output mode. */ + gpio_set_flags(gpio_usb_c1_oc_l, GPIO_OUT_HIGH); + gpio_set_flags(gpio_usb_c0_pd_rst_l, GPIO_OUT_HIGH); + + /* Enable Gyro interrupts */ + gpio_enable_interrupt(GPIO_6AXIS_INT_L); +} +DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); + +void board_overcurrent_event(int port) +{ + enum gpio_signal signal = (port == 0) ? GPIO_USB_C0_OC_L + : gpio_usb_c1_oc_l; + + gpio_set_level(signal, 0); + + CPRINTS("p%d: overcurrent!", port); +} + +void board_tcpc_init(void) +{ + int count = 0; + int port; + + /* Wait for disconnected battery to wake up */ + while (battery_hw_present() == BP_YES && + battery_is_present() == BP_NO) { + usleep(100 * MSEC); + /* Give up waiting after 1 second */ + if (++count > 10) + break; + } + + /* Only reset TCPC if not sysjump */ + if (!system_jumped_to_this_image()) + board_reset_pd_mcu(); + + /* Enable PPC interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_SWCTL_INT_ODL); + if (system_get_board_version() < 2) + gpio_enable_interrupt(GPIO_USB_C1_SWCTL_INT_ODL_V0); + else + gpio_enable_interrupt(GPIO_USB_C1_SWCTL_INT_ODL_V2); + + /* Enable TCPC interrupts. */ + gpio_enable_interrupt(GPIO_USB_C0_PD_INT_ODL); + gpio_enable_interrupt(GPIO_USB_C1_PD_INT_ODL); + +#ifdef CONFIG_USB_PD_TCPC_LOW_POWER + /* Enable CABLE_DET interrupt for ANX3429 wake from standby */ + gpio_enable_interrupt(GPIO_USB_C0_CABLE_DET); +#endif + /* + * Initialize HPD to low; after sysjump SOC needs to see + * HPD pulse to enable video path + */ + for (port = 0; port < CONFIG_USB_PD_PORT_COUNT; port++) { + const struct usb_mux *mux = &usb_muxes[port]; + + mux->hpd_update(port, 0, 0); + } +} +DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1); + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + + if (!gpio_get_level(GPIO_USB_C0_PD_INT_ODL)) { + if (gpio_get_level(gpio_usb_c0_pd_rst_l)) + status |= PD_STATUS_TCPC_ALERT_0; + } + + if (!gpio_get_level(GPIO_USB_C1_PD_INT_ODL)) { + if (gpio_get_level(GPIO_USB_C1_PD_RST_L)) + status |= PD_STATUS_TCPC_ALERT_1; + } + + return status; +} + +/** + * Power on (or off) a single TCPC. + * minimum on/off delays are included. + * + * @param port Port number of TCPC. + * @param mode 0: power off, 1: power on. + */ +void board_set_tcpc_power_mode(int port, int mode) +{ + if (port != USB_PD_PORT_ANX74XX) + return; + + switch (mode) { + case ANX74XX_NORMAL_MODE: + gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 1); + msleep(ANX74XX_PWR_H_RST_H_DELAY_MS); + gpio_set_level(gpio_usb_c0_pd_rst_l, 1); + break; + case ANX74XX_STANDBY_MODE: + gpio_set_level(gpio_usb_c0_pd_rst_l, 0); + msleep(ANX74XX_RST_L_PWR_L_DELAY_MS); + gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 0); + msleep(ANX74XX_PWR_L_PWR_H_DELAY_MS); + break; + default: + break; + } +} + +void board_reset_pd_mcu(void) +{ + /* Assert reset to TCPC1 (ps8751) */ + gpio_set_level(GPIO_USB_C1_PD_RST_L, 0); + + /* Assert reset to TCPC0 (anx3429) */ + gpio_set_level(gpio_usb_c0_pd_rst_l, 0); + + /* TCPC1 (ps8751) requires 1ms reset down assertion */ + msleep(MAX(1, ANX74XX_RST_L_PWR_L_DELAY_MS)); + + /* Deassert reset to TCPC1 */ + gpio_set_level(GPIO_USB_C1_PD_RST_L, 1); + /* Disable TCPC0 power */ + gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 0); + + /* + * anx3429 requires 10ms reset/power down assertion + */ + msleep(ANX74XX_PWR_L_PWR_H_DELAY_MS); + board_set_tcpc_power_mode(USB_PD_PORT_ANX74XX, 1); +} + +static void board_kblight_init(void) +{ + /* + * Enable keyboard backlight. This needs to be done here because + * the chip doesn't have power until PP3300_S0 comes up. + */ + gpio_set_level(GPIO_KB_BL_EN, 1); + lm3630a_poweron(); +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_kblight_init, HOOK_PRIO_DEFAULT); diff --git a/board/careena/board.h b/board/careena/board.h new file mode 100644 index 0000000000..7f0906ddec --- /dev/null +++ b/board/careena/board.h @@ -0,0 +1,44 @@ +/* Copyright 2018 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. + */ + +/* Careena board configuration */ + +#ifndef __CROS_EC_BOARD_H +#define __CROS_EC_BOARD_H + +#include "baseboard.h" + +/* + * By default, enable all console messages excepted HC, ACPI and event: + * The sensor stack is generating a lot of activity. + */ +#define CC_DEFAULT (CC_ALL & ~(CC_MASK(CC_EVENTS) | CC_MASK(CC_LPC))) +#undef CONFIG_HOSTCMD_DEBUG_MODE +#define CONFIG_HOSTCMD_DEBUG_MODE HCDEBUG_OFF + +#define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands while in dev. */ + +/* Power and battery LEDs */ +#define CONFIG_LED_COMMON +#define CONFIG_CMD_LEDTEST + +#undef CONFIG_LED_PWM_NEAR_FULL_COLOR +#undef CONFIG_LED_PWM_CHARGE_ERROR_COLOR +#undef CONFIG_LED_PWM_SOC_ON_COLOR +#undef CONFIG_LED_PWM_SOC_SUSPEND_COLOR + +#define CONFIG_LED_PWM_NEAR_FULL_COLOR EC_LED_COLOR_BLUE +#define CONFIG_LED_PWM_CHARGE_ERROR_COLOR EC_LED_COLOR_AMBER +#define CONFIG_LED_PWM_SOC_ON_COLOR EC_LED_COLOR_BLUE +#define CONFIG_LED_PWM_SOC_SUSPEND_COLOR EC_LED_COLOR_BLUE + +#define CONFIG_LED_PWM_COUNT 1 + +#define I2C_PORT_KBLIGHT NPCX_I2C_PORT5_0 + +/* KB backlight driver */ +#define CONFIG_LED_DRIVER_LM3630A + +#endif /* __CROS_EC_BOARD_H */ diff --git a/board/careena/build.mk b/board/careena/build.mk new file mode 100644 index 0000000000..9620af3152 --- /dev/null +++ b/board/careena/build.mk @@ -0,0 +1,14 @@ +# -*- makefile -*- +# Copyright 2015 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 +# + +CHIP:=npcx +CHIP_FAMILY:=npcx7 +CHIP_VARIANT:=npcx7m6f +BASEBOARD:=grunt + +board-y=board.o led.o diff --git a/board/careena/ec.tasklist b/board/careena/ec.tasklist new file mode 100644 index 0000000000..be1dbcc21f --- /dev/null +++ b/board/careena/ec.tasklist @@ -0,0 +1,37 @@ +/* Copyright 2017 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. + */ + +/* + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK_ALWAYS(n, r, d, s) for base tasks and + * TASK_NOTEST(n, r, d, s) for tasks that can be excluded in test binaries, + * where : + * 'n' in the name of the task + * 'r' in the main routine of the task + * 'd' in an opaque parameter passed to the routine at startup + * 's' is the stack size in bytes; must be a multiple of 8 + * + * For USB PD tasks, IDs must be in consecutive order and correspond to + * the port which they are for. See TASK_ID_TO_PD_PORT() macro. + */ + +#define CONFIG_TASK_LIST \ + TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_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, 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, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(HOSTCMD, host_command_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS(POWERBTN, power_button_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C0, pd_task, NULL, LARGER_TASK_STACK_SIZE) \ + TASK_ALWAYS(PD_C1, pd_task, NULL, LARGER_TASK_STACK_SIZE) diff --git a/board/careena/gpio.inc b/board/careena/gpio.inc new file mode 100644 index 0000000000..bfdbd0e376 --- /dev/null +++ b/board/careena/gpio.inc @@ -0,0 +1,121 @@ +/* -*- mode:c -*- + * + * Copyright 2017 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 GPIOs that we care about. + * Note: Those with interrupt handlers must be declared first. */ + +GPIO_INT(USB_C0_PD_INT_ODL, PIN(A, 0), GPIO_INT_FALLING, tcpc_alert_event) +GPIO_INT(USB_C1_PD_INT_ODL, PIN(F, 5), GPIO_INT_FALLING, tcpc_alert_event) +GPIO_INT(USB_C0_SWCTL_INT_ODL, PIN(0, 3), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(USB_C1_SWCTL_INT_ODL_V0, PIN(0, 4), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(USB_C1_SWCTL_INT_ODL_V2, PIN(D, 4), GPIO_INT_FALLING, ppc_interrupt) +GPIO_INT(PCH_SLP_S3_L, PIN(A, 6), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(PCH_SLP_S5_L, PIN(A, 3), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(S0_PGOOD, PIN(F, 4), GPIO_INT_BOTH, power_signal_interrupt) +GPIO_INT(S5_PGOOD, PIN(6, 3), GPIO_INT_BOTH | GPIO_PULL_UP, power_signal_interrupt) +GPIO_INT(POWER_BUTTON_L, PIN(0, 1), GPIO_INT_BOTH, power_button_interrupt) +GPIO_INT(LID_OPEN, PIN(D, 2), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, lid_interrupt) +GPIO_INT(AC_PRESENT, PIN(0, 0), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, extpower_interrupt) +GPIO_INT(WP_L, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) +GPIO_INT(VOLUME_DOWN_L, PIN(7, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) +GPIO_INT(VOLUME_UP_L, PIN(7, 5), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) +GPIO_INT(USB_C0_CABLE_DET, PIN(3, 7), GPIO_INT_RISING, anx74xx_cable_det_interrupt) +GPIO_INT(6AXIS_INT_L, PIN(8, 6), GPIO_INT_FALLING | GPIO_SEL_1P8V, bmi160_interrupt) + +GPIO(EN_PWR_A, PIN(E, 2), GPIO_OUT_LOW) /* Enable Power */ +GPIO(EN_PP1800_SENSOR, PIN(6, 7), GPIO_OUT_LOW) /* Enable Power */ +GPIO(ENABLE_BACKLIGHT_L, PIN(D, 3), GPIO_OUT_HIGH) /* Enable Backlight */ +GPIO(PCH_RSMRST_L, PIN(C, 2), GPIO_OUT_LOW) /* RSMRST# to SOC */ +GPIO(PCH_PWRBTN_L, PIN(C, 1), GPIO_OUT_HIGH) /* Power Button to SOC */ +GPIO(PCH_WAKE_L, PIN(7, 4), GPIO_OUT_HIGH) /* Wake SOC */ +GPIO(PCH_RCIN_L, PIN(0, 2), GPIO_ODR_HIGH) /* Cold Reset to SOC */ +GPIO(CCD_MODE_ODL, PIN(E, 3), GPIO_INPUT) /* Case Closed Debug Mode */ +GPIO(ENTERING_RW, PIN(E, 1), GPIO_OUT_LOW) /* EC Entering RW */ +GPIO(EC_BATT_PRES_ODL, PIN(E, 5), GPIO_INPUT | GPIO_PULL_UP) /* Battery Present */ +GPIO(PCH_SYS_PWROK, PIN(D, 6), GPIO_OUT_LOW) /* Power OK to SOC */ +GPIO(EC_APU_RST, PIN(E, 4), GPIO_INPUT) /* Reset to SOC */ +GPIO(CPU_PROCHOT, PIN(3, 4), GPIO_INPUT | GPIO_SEL_1P8V) /* PROCHOT to SOC */ +GPIO(APU_ALERT_L, PIN(A, 2), GPIO_INPUT) /* Alert to SOC */ +GPIO(3AXIS_INT_L, PIN(5, 0), GPIO_INPUT | GPIO_SEL_1P8V) /* 3 Axis Accel */ +GPIO(KB_BL_EN, PIN(F, 2), GPIO_OUT_LOW) /* Enable KB Backlight */ + +/* We don't have 5V rail control but the BQ24392 driver expects the GPIO */ +UNIMPLEMENTED(EN_PP5000) + +/* I2C pins - these will be reconfigured for alternate function below */ +GPIO(I2C0_SCL, PIN(B, 5), GPIO_INPUT) /* EC_I2C_POWER_SCL */ +GPIO(I2C0_SDA, PIN(B, 4), GPIO_INPUT) /* EC_I2C_POWER_SDA */ +GPIO(I2C1_SCL, PIN(9, 0), GPIO_INPUT) /* EC_I2C_USB_C0_PD_SCL */ +GPIO(I2C1_SDA, PIN(8, 7), GPIO_INPUT) /* EC_I2C_USB_C0_PD_SDA */ +GPIO(I2C2_SCL, PIN(9, 2), GPIO_INPUT) /* EC_I2C_USB_C1_PD_SCL */ +GPIO(I2C2_SDA, PIN(9, 1), GPIO_INPUT) /* EC_I2C_USB_C1_PD_SDA */ +GPIO(I2C3_SCL, PIN(D, 1), GPIO_INPUT | GPIO_SEL_1P8V) /* APU_SIC */ +GPIO(I2C3_SDA, PIN(D, 0), GPIO_INPUT | GPIO_SEL_1P8V) /* APU_SID */ +GPIO(I2C5_SCL, PIN(3, 3), GPIO_INPUT) /* EC_I2C_EEPROM_SCL and + EC_I2C_KB_BL_SCL */ +GPIO(I2C5_SDA, PIN(3, 6), GPIO_INPUT) /* EC_I2C_EEPROM_SDA and + EC_I2C_KB_BL_SDA */ +GPIO(I2C7_SCL, PIN(B, 3), GPIO_INPUT | GPIO_SEL_1P8V) /* EC_I2C_SENSOR_SCL */ +GPIO(I2C7_SDA, PIN(B, 2), GPIO_INPUT | GPIO_SEL_1P8V) /* EC_I2C_SENSOR_SDA */ + +/* + * The NPCX LPC driver configures and controls SCI and SMI, + * so PCH_SCI_ODL [PIN(7, 6)] and PCH_SMI_ODL [PIN(C, 6)] are + * not defined here as GPIOs. + */ +GPIO(PCH_SLP_S0_L, PIN(A, 4), GPIO_INPUT) + +GPIO(EN_USB_A0_5V, PIN(6, 1), GPIO_OUT_LOW) /* Enable A0 5V Charging */ +GPIO(EN_USB_A1_5V, PIN(C, 0), GPIO_OUT_LOW) /* Enable A1 5V Charging */ +GPIO(EN_USB_C0_TCPC_PWR, PIN(6, 0), GPIO_OUT_LOW) /* Enable C0 TCPC Power */ +GPIO(USB_C0_OC_L, PIN(7, 3), GPIO_OUT_HIGH) /* C0 Over Current */ +GPIO(USB_C1_OC_L_V0, PIN(D, 7), GPIO_INPUT) /* C1 Over Current */ +GPIO(USB_C1_OC_L_V2, PIN(7, 2), GPIO_INPUT) /* C1 Over Current */ +GPIO(USB_C0_PD_RST_L_V0, PIN(F, 1), GPIO_INPUT) /* C0 PD Reset */ +GPIO(USB_C0_PD_RST_L_V2, PIN(3, 2), GPIO_INPUT) /* C0 PD Reset */ +GPIO(USB_C1_PD_RST_L, PIN(D, 5), GPIO_OUT_HIGH) /* C1 PD Reset */ +GPIO(USB_C0_BC12_VBUS_ON_L_V0, PIN(8, 2), GPIO_INPUT) /* C0 BC1.2 Power */ +GPIO(USB_C0_BC12_VBUS_ON_L_V2, PIN(4, 0), GPIO_ODR_HIGH) /* C0 BC1.2 Power */ +GPIO(USB_C1_BC12_VBUS_ON_L, PIN(B, 1), GPIO_ODR_HIGH) /* C1 BC1.2 Power */ +GPIO(USB_C0_BC12_CHG_DET, PIN(6, 2), GPIO_INPUT) /* C0 BC1.2 Detect */ +GPIO(USB_C1_BC12_CHG_DET, PIN(8, 3), GPIO_INPUT) /* C1 BC1.2 Detect */ +GPIO(USB_C0_DP_HPD, PIN(9, 5), GPIO_OUT_LOW) /* C0 DP Hotplug Detect */ +GPIO(USB_C1_DP_HPD, PIN(9, 6), GPIO_OUT_LOW) /* C1 DP Hotplug Detect */ + +/* Board ID */ +GPIO(BOARD_VERSION1, PIN(C, 7), GPIO_INPUT) +GPIO(BOARD_VERSION2, PIN(9, 3), GPIO_INPUT) +GPIO(BOARD_VERSION3, PIN(8, 0), GPIO_INPUT) +GPIO(SKU_ID1, PIN(F, 0), GPIO_INPUT) +GPIO(SKU_ID2, PIN(4, 1), GPIO_INPUT) + +/* Alternate functions GPIO definitions */ +/* Cr50 requires no pull-ups on UART pins. */ +ALTERNATE(PIN_MASK(6, 0x30), 0, MODULE_UART, 0) /* UART from EC to Servo */ +ALTERNATE(PIN_MASK(B, 0x30), 1, MODULE_I2C, 0) /* I2C0 */ +ALTERNATE(PIN_MASK(9, 0x07), 1, MODULE_I2C, 0) /* I2C1 SCL / I2C2 */ +ALTERNATE(PIN_MASK(8, 0x80), 1, MODULE_I2C, 0) /* I2C1 SDA */ +ALTERNATE(PIN_MASK(D, 0x03), 1, MODULE_I2C, 0) /* I2C3 */ +ALTERNATE(PIN_MASK(3, 0x48), 1, MODULE_I2C, 0) /* I2C5 */ +ALTERNATE(PIN_MASK(B, 0x0C), 1, MODULE_I2C, 0) /* I2C7 */ +ALTERNATE(PIN_MASK(4, 0x30), 1, MODULE_ADC, 0) /* ADC0-1 */ +ALTERNATE(PIN_MASK(4, 0x02), 1, MODULE_ADC, 0) /* ADC4 */ +ALTERNATE(PIN_MASK(F, 0x01), 1, MODULE_ADC, 0) /* ADC9 */ +ALTERNATE(PIN_MASK(B, 0x80), 1, MODULE_PWM, 0) /* KB Backlight */ +ALTERNATE(PIN_MASK(C, 0x18), 1, MODULE_PWM, 0) /* LED 1 & 2 */ + +/* Keyboard Pins */ +ALTERNATE(PIN_MASK(3, 0x03), 0, MODULE_KEYBOARD_SCAN, GPIO_INPUT) /* KSI_00-01 */ +ALTERNATE(PIN_MASK(2, 0xFC), 0, MODULE_KEYBOARD_SCAN, GPIO_INPUT) /* KSI_02-07 */ +ALTERNATE(PIN_MASK(2, 0x03), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO_00-01 */ +GPIO(KBD_KSO2, PIN(1, 7), GPIO_OUT_LOW) /* KSO_02 inverted */ +ALTERNATE(PIN_MASK(1, 0x7F), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO_03-09 */ +ALTERNATE(PIN_MASK(0, 0xE0), 0, MODULE_KEYBOARD_SCAN, GPIO_ODR_HIGH) /* KSO_10-12 */ + +/* Power Switch Logic (PSL) inputs */ +ALTERNATE(PIN_MASK(0, 0x03), 1, MODULE_PMU, 0) /* GPIO00, GPIO01 */ +ALTERNATE(PIN_MASK(D, 0x04), 1, MODULE_PMU, 0) /* GPIOD2 */ diff --git a/board/careena/led.c b/board/careena/led.c new file mode 100644 index 0000000000..fc6f427cd2 --- /dev/null +++ b/board/careena/led.c @@ -0,0 +1,66 @@ +/* Copyright 2018 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 "common.h" +#include "ec_commands.h" +#include "led_pwm.h" +#include "util.h" + +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_POWER_LED, +}; +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +/* + * We only have a blue and an amber LED, so setting any other colour results in + * both LEDs being off. + */ +struct pwm_led led_color_map[EC_LED_COLOR_COUNT] = { + /* Amber, Blue */ + [EC_LED_COLOR_RED] = { 0, 0 }, + [EC_LED_COLOR_GREEN] = { 0, 0 }, + [EC_LED_COLOR_BLUE] = { 0, 100 }, + [EC_LED_COLOR_YELLOW] = { 0, 0 }, + [EC_LED_COLOR_WHITE] = { 0, 0 }, + [EC_LED_COLOR_AMBER] = { 100, 0 }, +}; + +/* One logical LED with amber and blue channels. */ +struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = { + { + PWM_CH_LED1_AMBER, + PWM_CH_LED2_BLUE, + PWM_LED_NO_CHANNEL, + }, +}; + +void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) +{ + memset(brightness_range, '\0', + sizeof(*brightness_range) * EC_LED_COLOR_COUNT); + brightness_range[EC_LED_COLOR_AMBER] = 100; + brightness_range[EC_LED_COLOR_BLUE] = 100; +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + enum pwm_led_id pwm_id; + + /* Convert ec_led_id to pwm_led_id. */ + if (led_id == EC_LED_ID_POWER_LED) + pwm_id = PWM_LED0; + else + return EC_ERROR_UNKNOWN; + + if (brightness[EC_LED_COLOR_BLUE]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_BLUE); + else if (brightness[EC_LED_COLOR_AMBER]) + set_pwm_led_color(pwm_id, EC_LED_COLOR_AMBER); + else + /* Otherwise, the "color" is "off". */ + set_pwm_led_color(pwm_id, -1); + + return EC_SUCCESS; +} diff --git a/board/grunt/board.c b/board/grunt/board.c index 5f6ac0084b..107531901f 100644 --- a/board/grunt/board.c +++ b/board/grunt/board.c @@ -47,6 +47,9 @@ #include "usbc_ppc.h" #include "util.h" +#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) + /* * These GPIOs change pins depending on board version. They are configured * in board_init. @@ -54,9 +57,6 @@ static enum gpio_signal gpio_usb_c1_oc_l = GPIO_USB_C1_OC_L_V2; static enum gpio_signal gpio_usb_c0_pd_rst_l = GPIO_USB_C0_PD_RST_L_V2; -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) - static void tcpc_alert_event(enum gpio_signal signal) { if ((signal == GPIO_USB_C0_PD_INT_ODL) && @@ -109,41 +109,6 @@ static void ppc_interrupt(enum gpio_signal signal) #include "gpio_list.h" -const enum gpio_signal hibernate_wake_pins[] = { - GPIO_LID_OPEN, - GPIO_AC_PRESENT, - GPIO_POWER_BUTTON_L, -}; -const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins); - -const struct adc_t adc_channels[] = { - [ADC_TEMP_SENSOR_CHARGER] = { - "CHARGER", NPCX_ADC_CH0, ADC_MAX_VOLT, ADC_READ_MAX+1, 0 - }, - [ADC_TEMP_SENSOR_SOC] = { - "SOC", NPCX_ADC_CH1, ADC_MAX_VOLT, ADC_READ_MAX+1, 0 - }, - [ADC_VBUS] = { - "VBUS", NPCX_ADC_CH8, ADC_MAX_VOLT*10, ADC_READ_MAX+1, 0 - }, - [ADC_SKU_ID1] = { - "SKU1", NPCX_ADC_CH9, ADC_MAX_VOLT, ADC_READ_MAX+1, 0 - }, - [ADC_SKU_ID2] = { - "SKU2", NPCX_ADC_CH4, ADC_MAX_VOLT, ADC_READ_MAX+1, 0 - }, -}; -BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); - -/* Power signal list. Must match order of enum power_signal. */ -const struct power_signal_info power_signal_list[] = { - {GPIO_PCH_SLP_S3_L, POWER_SIGNAL_ACTIVE_HIGH, "SLP_S3_DEASSERTED"}, - {GPIO_PCH_SLP_S5_L, POWER_SIGNAL_ACTIVE_HIGH, "SLP_S5_DEASSERTED"}, - {GPIO_S0_PGOOD, POWER_SIGNAL_ACTIVE_HIGH, "S0_PGOOD"}, - {GPIO_S5_PGOOD, POWER_SIGNAL_ACTIVE_HIGH, "S5_PGOOD"}, -}; -BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT); - /* I2C port map. */ const struct i2c_port_t i2c_ports[] = { {"power", I2C_PORT_POWER, 100, GPIO_I2C0_SCL, GPIO_I2C0_SDA}, @@ -155,88 +120,6 @@ const struct i2c_port_t i2c_ports[] = { }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); -#define USB_PD_PORT_ANX74XX 0 -#define USB_PD_PORT_PS8751 1 - -const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_COUNT] = { - [USB_PD_PORT_ANX74XX] = { - .i2c_host_port = I2C_PORT_TCPC0, - .i2c_slave_addr = ANX74XX_I2C_ADDR1, - .drv = &anx74xx_tcpm_drv, - .pol = TCPC_ALERT_ACTIVE_LOW, - }, - [USB_PD_PORT_PS8751] = { - .i2c_host_port = I2C_PORT_TCPC1, - .i2c_slave_addr = PS8751_I2C_ADDR1, - .drv = &ps8xxx_tcpm_drv, - .pol = TCPC_ALERT_ACTIVE_LOW, - }, -}; - -uint16_t tcpc_get_alert_status(void) -{ - uint16_t status = 0; - - if (!gpio_get_level(GPIO_USB_C0_PD_INT_ODL)) { - if (gpio_get_level(gpio_usb_c0_pd_rst_l)) - status |= PD_STATUS_TCPC_ALERT_0; - } - - if (!gpio_get_level(GPIO_USB_C1_PD_INT_ODL)) { - if (gpio_get_level(GPIO_USB_C1_PD_RST_L)) - status |= PD_STATUS_TCPC_ALERT_1; - } - - return status; -} - -struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_COUNT] = { - [USB_PD_PORT_ANX74XX] = { - .port_addr = USB_PD_PORT_ANX74XX, - .driver = &anx74xx_tcpm_usb_mux_driver, - .hpd_update = &anx74xx_tcpc_update_hpd_status, - }, - [USB_PD_PORT_PS8751] = { - .port_addr = USB_PD_PORT_PS8751, - .driver = &tcpci_tcpm_usb_mux_driver, - .hpd_update = &ps8xxx_tcpc_update_hpd_status, - /* TODO(ecgh): ps8751_tune_mux needed? */ - } -}; - -struct ppc_config_t ppc_chips[] = { - { - .i2c_port = I2C_PORT_TCPC0, - .i2c_addr = SN5S330_ADDR0, - .drv = &sn5s330_drv - }, - { - .i2c_port = I2C_PORT_TCPC1, - .i2c_addr = SN5S330_ADDR0, - .drv = &sn5s330_drv - }, -}; -unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); - -/* BC 1.2 chip Configuration */ -const struct bq24392_config_t bq24392_config[CONFIG_USB_PD_PORT_COUNT] = { - [USB_PD_PORT_ANX74XX] = { - .chip_enable_pin = GPIO_USB_C0_BC12_VBUS_ON_L_V2, - .chg_det_pin = GPIO_USB_C0_BC12_CHG_DET, - .flags = BQ24392_FLAGS_ENABLE_ACTIVE_LOW, - }, - [USB_PD_PORT_PS8751] = { - .chip_enable_pin = GPIO_USB_C1_BC12_VBUS_ON_L, - .chg_det_pin = GPIO_USB_C1_BC12_CHG_DET, - .flags = BQ24392_FLAGS_ENABLE_ACTIVE_LOW, - }, -}; - -const int usb_port_enable[USB_PORT_COUNT] = { - GPIO_EN_USB_A0_5V, - GPIO_EN_USB_A1_5V, -}; - static void board_init(void) { if (system_get_board_version() < 2) { @@ -262,99 +145,14 @@ static void board_init(void) } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); -static void board_chipset_suspend(void) -{ - /* - * Turn off display backlight. This ensures that the backlight stays off - * in S3, no matter what the AP has it set to. The AP also controls it. - * This is here more for legacy reasons. - */ - gpio_set_level(GPIO_ENABLE_BACKLIGHT_L, 1); -} -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_chipset_suspend, HOOK_PRIO_DEFAULT); - -static void board_chipset_resume(void) -{ - /* Allow display backlight to turn on. See above backlight comment */ - gpio_set_level(GPIO_ENABLE_BACKLIGHT_L, 0); - - /* - * Enable keyboard backlight. This needs to be done here because - * the chip doesn't have power until PP3300_S0 comes up. - */ - gpio_set_level(GPIO_KB_BL_EN, 1); - lm3630a_poweron(); -} -DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_chipset_resume, HOOK_PRIO_DEFAULT); - -static void board_chipset_startup(void) -{ - /* - * Enable sensor power (lid accel, gyro) in S3 for calculating the lid - * angle (needed on convertibles to disable resume from keyboard in - * tablet mode). - */ - gpio_set_level(GPIO_EN_PP1800_SENSOR, 1); -} -DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_chipset_startup, HOOK_PRIO_DEFAULT); - -static void board_chipset_shutdown(void) -{ - /* Disable sensor power (lid accel, gyro) in S5. */ - gpio_set_level(GPIO_EN_PP1800_SENSOR, 0); -} -DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, board_chipset_shutdown, HOOK_PRIO_DEFAULT); - -/** - * Power on (or off) a single TCPC. - * minimum on/off delays are included. - * - * @param port Port number of TCPC. - * @param mode 0: power off, 1: power on. - */ -void board_set_tcpc_power_mode(int port, int mode) -{ - if (port != USB_PD_PORT_ANX74XX) - return; - - switch (mode) { - case ANX74XX_NORMAL_MODE: - gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 1); - msleep(ANX74XX_PWR_H_RST_H_DELAY_MS); - gpio_set_level(gpio_usb_c0_pd_rst_l, 1); - break; - case ANX74XX_STANDBY_MODE: - gpio_set_level(gpio_usb_c0_pd_rst_l, 0); - msleep(ANX74XX_RST_L_PWR_L_DELAY_MS); - gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 0); - msleep(ANX74XX_PWR_L_PWR_H_DELAY_MS); - break; - default: - break; - } -} - -void board_reset_pd_mcu(void) +void board_overcurrent_event(int port) { - /* Assert reset to TCPC1 (ps8751) */ - gpio_set_level(GPIO_USB_C1_PD_RST_L, 0); - - /* Assert reset to TCPC0 (anx3429) */ - gpio_set_level(gpio_usb_c0_pd_rst_l, 0); - - /* TCPC1 (ps8751) requires 1ms reset down assertion */ - msleep(MAX(1, ANX74XX_RST_L_PWR_L_DELAY_MS)); + enum gpio_signal signal = (port == 0) ? GPIO_USB_C0_OC_L + : gpio_usb_c1_oc_l; - /* Deassert reset to TCPC1 */ - gpio_set_level(GPIO_USB_C1_PD_RST_L, 1); - /* Disable TCPC0 power */ - gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 0); + gpio_set_level(signal, 0); - /* - * anx3429 requires 10ms reset/power down assertion - */ - msleep(ANX74XX_PWR_L_PWR_H_DELAY_MS); - board_set_tcpc_power_mode(USB_PD_PORT_ANX74XX, 1); + CPRINTS("p%d: overcurrent!", port); } void board_tcpc_init(void) @@ -402,301 +200,82 @@ void board_tcpc_init(void) } DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1); -void board_overcurrent_event(int port) -{ - enum gpio_signal signal = (port == 0) ? GPIO_USB_C0_OC_L - : gpio_usb_c1_oc_l; - - gpio_set_level(signal, 0); - - CPRINTS("p%d: overcurrent!", port); -} - -int board_set_active_charge_port(int port) +uint16_t tcpc_get_alert_status(void) { - int i; - - CPRINTS("New chg p%d", port); - - if (port == CHARGE_PORT_NONE) { - /* Disable all ports. */ - for (i = 0; i < ppc_cnt; i++) { - if (ppc_vbus_sink_enable(i, 0)) - CPRINTS("p%d: sink disable failed.", i); - } - - return EC_SUCCESS; - } - - /* Check if the port is sourcing VBUS. */ - if (ppc_is_sourcing_vbus(port)) { - CPRINTF("Skip enable p%d", port); - return EC_ERROR_INVAL; - } - - /* - * Turn off the other ports' sink path FETs, before enabling the - * requested charge port. - */ - for (i = 0; i < ppc_cnt; i++) { - if (i == port) - continue; + uint16_t status = 0; - if (ppc_vbus_sink_enable(i, 0)) - CPRINTS("p%d: sink disable failed.", i); + if (!gpio_get_level(GPIO_USB_C0_PD_INT_ODL)) { + if (gpio_get_level(gpio_usb_c0_pd_rst_l)) + status |= PD_STATUS_TCPC_ALERT_0; } - /* Enable requested charge port. */ - if (ppc_vbus_sink_enable(port, 1)) { - CPRINTS("p%d: sink enable failed."); - return EC_ERROR_UNKNOWN; + if (!gpio_get_level(GPIO_USB_C1_PD_INT_ODL)) { + if (gpio_get_level(GPIO_USB_C1_PD_RST_L)) + status |= PD_STATUS_TCPC_ALERT_1; } - return EC_SUCCESS; -} - -void board_set_charge_limit(int port, int supplier, int charge_ma, - int max_ma, int charge_mv) -{ - charge_set_input_current_limit(MAX(charge_ma, - CONFIG_CHARGER_INPUT_CURRENT), - charge_mv); -} - -/* Keyboard scan setting */ -struct keyboard_scan_config keyscan_config = { - /* Extra delay when KSO2 is tied to Cr50. */ - .output_settle_us = 60, - .debounce_down_us = 6 * MSEC, - .debounce_up_us = 30 * MSEC, - .scan_period_us = 1500, - .min_post_scan_delay_us = 1000, - .poll_timeout_us = SECOND, - .actual_key_mask = { - 0x3c, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, - 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */ - }, -}; - -/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */ -const struct pwm_t pwm_channels[] = { - [PWM_CH_KBLIGHT] = { 5, 0, 100 }, - [PWM_CH_LED1_AMBER] = { - 0, PWM_CONFIG_OPEN_DRAIN | PWM_CONFIG_ACTIVE_LOW | - PWM_CONFIG_DSLEEP, 100 - }, - [PWM_CH_LED2_BLUE] = { - 2, PWM_CONFIG_OPEN_DRAIN | PWM_CONFIG_ACTIVE_LOW | - PWM_CONFIG_DSLEEP, 100 - }, -}; -BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); - -/* - * We use 11 as the scaling factor so that the maximum mV value below (2761) - * can be compressed to fit in a uint8_t. - */ -#define THERMISTOR_SCALING_FACTOR 11 - -/* - * Values are calculated from the "Resistance VS. Temperature" table on the - * Murata page for part NCP15WB473F03RC. Vdd=3.3V, R=30.9Kohm. - */ -static const struct thermistor_data_pair thermistor_data[] = { - { 2761 / THERMISTOR_SCALING_FACTOR, 0}, - { 2492 / THERMISTOR_SCALING_FACTOR, 10}, - { 2167 / THERMISTOR_SCALING_FACTOR, 20}, - { 1812 / THERMISTOR_SCALING_FACTOR, 30}, - { 1462 / THERMISTOR_SCALING_FACTOR, 40}, - { 1146 / THERMISTOR_SCALING_FACTOR, 50}, - { 878 / THERMISTOR_SCALING_FACTOR, 60}, - { 665 / THERMISTOR_SCALING_FACTOR, 70}, - { 500 / THERMISTOR_SCALING_FACTOR, 80}, - { 434 / THERMISTOR_SCALING_FACTOR, 85}, - { 376 / THERMISTOR_SCALING_FACTOR, 90}, - { 326 / THERMISTOR_SCALING_FACTOR, 95}, - { 283 / THERMISTOR_SCALING_FACTOR, 100} -}; - -static const struct thermistor_info thermistor_info = { - .scaling_factor = THERMISTOR_SCALING_FACTOR, - .num_pairs = ARRAY_SIZE(thermistor_data), - .data = thermistor_data, -}; - -static int board_get_temp(int idx, int *temp_k) -{ - /* idx is the sensor index set below in temp_sensors[] */ - int mv = adc_read_channel( - idx ? ADC_TEMP_SENSOR_SOC : ADC_TEMP_SENSOR_CHARGER); - int temp_c; - - if (mv < 0) - return -1; - - temp_c = thermistor_linear_interpolate(mv, &thermistor_info); - *temp_k = C_TO_K(temp_c); - return 0; + return status; } -const struct temp_sensor_t temp_sensors[] = { - {"Charger", TEMP_SENSOR_TYPE_BOARD, board_get_temp, 0, 1}, - {"SOC", TEMP_SENSOR_TYPE_BOARD, board_get_temp, 1, 5}, - {"CPU", TEMP_SENSOR_TYPE_CPU, sb_tsi_get_val, 0, 4}, -}; -BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); - -/* Motion sensors */ -static struct mutex g_lid_mutex; -static struct mutex g_base_mutex; - -/* - * Matrix to rotate accelerator into standard reference frame +/** + * Power on (or off) a single TCPC. + * minimum on/off delays are included. * - * TODO(teravest): Update this when we can physically test a Grunt. + * @param port Port number of TCPC. + * @param mode 0: power off, 1: power on. */ -const matrix_3x3_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; - -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 = 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_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, - .default_range = 2, /* g, enough for laptop */ - .rot_standard_ref = &base_standard_ref, - .min_frequency = BMI160_ACCEL_MIN_FREQ, - .max_frequency = BMI160_ACCEL_MAX_FREQ, - .config = { - /* EC use accel for angle detection */ - [SENSOR_CONFIG_EC_S0] = { - .odr = 10000 | ROUND_UP_FLAG, - .ec_rate = 100, - }, - /* EC use accel for angle detection */ - [SENSOR_CONFIG_EC_S3] = { - .odr = 10000 | ROUND_UP_FLAG, - }, - }, - }, - - [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, - }, -}; - -const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); - -#ifndef TEST_BUILD -void lid_angle_peripheral_enable(int enable) +void board_set_tcpc_power_mode(int port, int mode) { - keyboard_scan_enable(enable, KB_SCAN_DISABLE_LID_ANGLE); -} -#endif + if (port != USB_PD_PORT_ANX74XX) + return; -static const int sku_thresh_mv[] = { - /* Vin = 3.3V, Ideal voltage, R2 values listed below */ - /* R1 = 51.1 kOhm */ - 200, /* 124 mV, 2.0 Kohm */ - 366, /* 278 mV, 4.7 Kohm */ - 550, /* 456 mV, 8.2 Kohm */ - 752, /* 644 mV, 12.4 Kohm */ - 927, /* 860 mV, 18.0 Kohm */ - 1073, /* 993 mV, 22.0 Kohm */ - 1235, /* 1152 mV, 27.4 Kohm */ - 1386, /* 1318 mV, 34.0 Kohm */ - 1552, /* 1453 mV, 40.2 Kohm */ - /* R1 = 10.0 kOhm */ - 1739, /* 1650 mV, 10.0 Kohm */ - 1976, /* 1827 mV, 12.4 Kohm */ - 2197, /* 2121 mV, 18.0 Kohm */ - 2344, /* 2269 mV, 22.0 Kohm */ - 2484, /* 2418 mV, 27.4 Kohm */ - 2636, /* 2550 mV, 34.0 Kohm */ - 2823, /* 2721 mV, 47.0 Kohm */ -}; + switch (mode) { + case ANX74XX_NORMAL_MODE: + gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 1); + msleep(ANX74XX_PWR_H_RST_H_DELAY_MS); + gpio_set_level(gpio_usb_c0_pd_rst_l, 1); + break; + case ANX74XX_STANDBY_MODE: + gpio_set_level(gpio_usb_c0_pd_rst_l, 0); + msleep(ANX74XX_RST_L_PWR_L_DELAY_MS); + gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 0); + msleep(ANX74XX_PWR_L_PWR_H_DELAY_MS); + break; + default: + break; + } +} -static int board_read_sku_adc(enum adc_channel chan) +void board_reset_pd_mcu(void) { - int mv; - int i; + /* Assert reset to TCPC1 (ps8751) */ + gpio_set_level(GPIO_USB_C1_PD_RST_L, 0); - mv = adc_read_channel(chan); + /* Assert reset to TCPC0 (anx3429) */ + gpio_set_level(gpio_usb_c0_pd_rst_l, 0); - if (mv == ADC_READ_ERROR) - return -1; + /* TCPC1 (ps8751) requires 1ms reset down assertion */ + msleep(MAX(1, ANX74XX_RST_L_PWR_L_DELAY_MS)); - for (i = 0; i < ARRAY_SIZE(sku_thresh_mv); i++) - if (mv < sku_thresh_mv[i]) - return i; + /* Deassert reset to TCPC1 */ + gpio_set_level(GPIO_USB_C1_PD_RST_L, 1); + /* Disable TCPC0 power */ + gpio_set_level(GPIO_EN_USB_C0_TCPC_PWR, 0); - return -1; + /* + * anx3429 requires 10ms reset/power down assertion + */ + msleep(ANX74XX_PWR_L_PWR_H_DELAY_MS); + board_set_tcpc_power_mode(USB_PD_PORT_ANX74XX, 1); } -uint32_t system_get_sku_id(void) +static void board_kblight_init(void) { - static uint32_t sku_id = -1; - int sku_id1, sku_id2; - - if (sku_id != -1) - return sku_id; - - sku_id1 = board_read_sku_adc(ADC_SKU_ID1); - sku_id2 = board_read_sku_adc(ADC_SKU_ID2); - - if (sku_id1 < 0 || sku_id2 < 0) - return 0; - - sku_id = (sku_id2 << 4) | sku_id1; - return sku_id; + /* + * Enable keyboard backlight. This needs to be done here because + * the chip doesn't have power until PP3300_S0 comes up. + */ + gpio_set_level(GPIO_KB_BL_EN, 1); + lm3630a_poweron(); } +DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_kblight_init, HOOK_PRIO_DEFAULT); diff --git a/board/grunt/board.h b/board/grunt/board.h index 64d21ffaa5..56a43db7cc 100644 --- a/board/grunt/board.h +++ b/board/grunt/board.h @@ -8,6 +8,8 @@ #ifndef __CROS_EC_BOARD_H #define __CROS_EC_BOARD_H +#include "baseboard.h" + /* * By default, enable all console messages excepted HC, ACPI and event: * The sensor stack is generating a lot of activity. @@ -16,148 +18,7 @@ #undef CONFIG_HOSTCMD_DEBUG_MODE #define CONFIG_HOSTCMD_DEBUG_MODE HCDEBUG_OFF -/* Optional features */ -#define CONFIG_HIBERNATE_PSL -#define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands. */ - -/* NPCX7 config */ -#define NPCX_UART_MODULE2 1 /* GPIO64/65 are used as UART pins. */ -#define NPCX_TACH_SEL2 0 /* No tach. */ -#define NPCX7_PWM1_SEL 0 /* GPIO C2 is not used as PWM1. */ - -/* Internal SPI flash on NPCX7 */ -/* Flash is 1MB but reserve half for future use. */ -#define CONFIG_FLASH_SIZE (512 * 1024) -#define CONFIG_SPI_FLASH_REGS -#define CONFIG_SPI_FLASH_W25Q80 /* Internal SPI flash type. */ - -/* - * Enable 1 slot of secure temporary storage to support - * suspend/resume with read/write memory training. - */ -#define CONFIG_VSTORE -#define CONFIG_VSTORE_SLOT_COUNT 1 - -#define CONFIG_ADC -#define CONFIG_BACKLIGHT_LID -#define CONFIG_BACKLIGHT_LID_ACTIVE_LOW -#define CONFIG_BOARD_VERSION_GPIO -#define CONFIG_HOSTCMD_SKUID -#define CONFIG_I2C -#define CONFIG_I2C_MASTER -#define CONFIG_HOSTCMD_LPC -#define CONFIG_PWM -#define CONFIG_PWM_KBLIGHT -#define CONFIG_TEMP_SENSOR -#define CONFIG_THERMISTOR_NCP15WB -#define CONFIG_VBOOT_HASH -#define CONFIG_VOLUME_BUTTONS - -#define CONFIG_BATTERY_CUT_OFF -#define CONFIG_BATTERY_HW_PRESENT_CUSTOM -#define CONFIG_BATTERY_PRESENT_CUSTOM -#define CONFIG_BATTERY_SMART - -#define CONFIG_BC12_DETECT_BQ24392 -#define CONFIG_CHARGER -#define CONFIG_CHARGER_V2 -#define CONFIG_CHARGE_MANAGER -#define CONFIG_CHARGER_DISCHARGE_ON_AC -#define CONFIG_CHARGER_INPUT_CURRENT 128 -#define CONFIG_CHARGER_ISL9238 -#define CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON 1 -#define CONFIG_CHARGER_SENSE_RESISTOR 10 -#define CONFIG_CHARGER_SENSE_RESISTOR_AC 20 -#define CONFIG_CHARGE_RAMP_HW -#define CONFIG_USB_CHARGER - -#define CONFIG_CHIPSET_STONEY -#define CONFIG_CHIPSET_RESET_HOOK -/* - * ACOK from ISL9238 sometimes has a negative pulse after connecting - * USB-C power. We want to ignore it. b/77455171 - */ -#undef CONFIG_EXTPOWER_DEBOUNCE_MS -#define CONFIG_EXTPOWER_DEBOUNCE_MS 200 -#define CONFIG_EXTPOWER_GPIO -#define CONFIG_POWER_COMMON -#define CONFIG_POWER_SHUTDOWN_PAUSE_IN_S5 -#define CONFIG_POWER_BUTTON -#define CONFIG_POWER_BUTTON_X86 - -#define CONFIG_KEYBOARD_BOARD_CONFIG -#define CONFIG_KEYBOARD_COL2_INVERTED -#define CONFIG_KEYBOARD_PROTOCOL_8042 -#define CONFIG_KEYBOARD_REFRESH_ROW3 -#define CONFIG_KEYBOARD_IGNORE_REFRESH_BOOT_KEY -#define CONFIG_KEYBOARD_PWRBTN_ASSERTS_KSI3 - -#define CONFIG_USB_POWER_DELIVERY -#define CONFIG_CMD_PD_CONTROL -#define CONFIG_USB_PD_ALT_MODE -#define CONFIG_USB_PD_ALT_MODE_DFP -#define CONFIG_USB_PD_COMM_LOCKED -#define CONFIG_USB_PD_DISCHARGE_PPC -#define CONFIG_USB_PD_DUAL_ROLE -#define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE -#define CONFIG_USB_PD_LOGGING -#define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0 -#define CONFIG_USB_PD_PORT_COUNT 2 -#define CONFIG_USB_PD_TCPC_LOW_POWER -#define CONFIG_USB_PD_TCPM_ANX3429 -#define CONFIG_USB_PD_TCPM_MUX -#define CONFIG_USB_PD_TCPM_PS8751 -#define CONFIG_USB_PD_TCPM_TCPCI -#define CONFIG_USB_PD_TRY_SRC -#define CONFIG_USB_PD_VBUS_DETECT_PPC -#define CONFIG_USBC_PPC_SN5S330 -#define CONFIG_USBC_SS_MUX -#define CONFIG_USBC_SS_MUX_DFP_ONLY -#define CONFIG_USBC_VCONN -#define CONFIG_USBC_VCONN_SWAP - -/* USB-A config */ -#define CONFIG_USB_PORT_POWER_DUMB -#define USB_PORT_COUNT 2 - -/* TODO(b/69683108): Use correct PD delay values */ -#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */ -#define PD_POWER_SUPPLY_TURN_OFF_DELAY 250000 /* us */ -#define PD_VCONN_SWAP_DELAY 5000 /* us */ - -/* TODO(b/69683178): Use correct PD power values */ -#define PD_OPERATING_POWER_MW 15000 -#define PD_MAX_POWER_MW 45000 -#define PD_MAX_CURRENT_MA 3000 -#define PD_MAX_VOLTAGE_MV 20000 - -#define I2C_PORT_BATTERY I2C_PORT_POWER -#define I2C_PORT_CHARGER I2C_PORT_POWER -#define I2C_PORT_POWER NPCX_I2C_PORT0_0 -#define I2C_PORT_TCPC0 NPCX_I2C_PORT1_0 -#define I2C_PORT_TCPC1 NPCX_I2C_PORT2_0 -#define I2C_PORT_THERMAL NPCX_I2C_PORT3_0 -#define I2C_PORT_KBLIGHT NPCX_I2C_PORT5_0 -#define I2C_PORT_SENSOR NPCX_I2C_PORT7_0 -/* Accelerometer and Gyroscope are the same device. */ -#define I2C_PORT_ACCEL I2C_PORT_SENSOR - -/* Sensors */ -#define CONFIG_MKBP_EVENT -#define CONFIG_MKBP_USE_HOST_EVENT -#define CONFIG_ACCELGYRO_BMI160 -#define CONFIG_ACCELGYRO_BMI160_INT_EVENT TASK_EVENT_CUSTOM(4) -#define CONFIG_ACCEL_INTERRUPTS -#define CONFIG_ACCEL_KX022 -#define CONFIG_CMD_ACCELS -#define CONFIG_CMD_ACCEL_INFO -#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 - -/* Thermal */ -#define CONFIG_TEMP_SENSOR_SB_TSI +#define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands while in dev. */ /* Power and battery LEDs */ #define CONFIG_LED_COMMON @@ -175,62 +36,9 @@ #define CONFIG_LED_PWM_COUNT 1 +#define I2C_PORT_KBLIGHT NPCX_I2C_PORT5_0 + /* KB backlight driver */ #define CONFIG_LED_DRIVER_LM3630A -/* FIFO size is a power of 2. */ -#define CONFIG_ACCEL_FIFO 1024 /* TODO(teravest): Check this value. */ - -/* Depends on how fast the AP boots and typical ODRs. */ -#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO / 3) - -#ifndef __ASSEMBLER__ - -#include "gpio_signal.h" -#include "registers.h" - -enum adc_channel { - ADC_TEMP_SENSOR_CHARGER, - ADC_TEMP_SENSOR_SOC, - ADC_VBUS, - ADC_SKU_ID1, - ADC_SKU_ID2, - ADC_CH_COUNT -}; - -enum power_signal { - X86_SLP_S3_N, - X86_SLP_S5_N, - X86_S0_PGOOD, - X86_S5_PGOOD, - POWER_SIGNAL_COUNT -}; - -enum temp_sensor_id { - TEMP_SENSOR_CHARGER = 0, - TEMP_SENSOR_SOC, - TEMP_SENSOR_CPU, - TEMP_SENSOR_COUNT -}; - -enum pwm_channel { - PWM_CH_KBLIGHT = 0, - PWM_CH_LED1_AMBER, - PWM_CH_LED2_BLUE, - PWM_CH_COUNT -}; - -enum sensor_id { - LID_ACCEL, - BASE_ACCEL, - BASE_GYRO, -}; - -/* Sensors without hardware FIFO are in forced mode */ -#define CONFIG_ACCEL_FORCE_MODE_MASK (1 << LID_ACCEL) - -void board_reset_pd_mcu(void); - -#endif /* !__ASSEMBLER__ */ - #endif /* __CROS_EC_BOARD_H */ diff --git a/board/grunt/build.mk b/board/grunt/build.mk index 17edac9b50..9620af3152 100644 --- a/board/grunt/build.mk +++ b/board/grunt/build.mk @@ -9,7 +9,6 @@ CHIP:=npcx CHIP_FAMILY:=npcx7 CHIP_VARIANT:=npcx7m6f +BASEBOARD:=grunt board-y=board.o led.o -board-$(CONFIG_BATTERY_SMART)+=battery.o -board-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_policy.o |