From d22f5518f0e5413ace4a7cfc476e4f244d78a010 Mon Sep 17 00:00:00 2001 From: Edward Hill Date: Fri, 17 Nov 2017 16:17:55 -0700 Subject: grunt: Initial USB PD board code. Add USB PD tasks and start of board code. Update GPIOs to match V1.2 schematics. Grunt V1.2 USB HW: C0: TCPC ANX3429, Switch SN5S330, BC1.2 BQ24392 C1: TCPC PS8751, Switch SN5S330, BC1.2 BQ24392 A0: SN1702001 A1: SN1702001 Charger: ISL9238 BUG=b:69378796 BRANCH=none TEST=make BOARD=grunt Change-Id: I66918abe3e9452c8d60e51245e730d1bcc168fd3 Signed-off-by: Edward Hill Reviewed-on: https://chromium-review.googlesource.com/777407 Reviewed-by: Aaron Durbin Reviewed-by: Vincent Palatin --- board/grunt/board.c | 221 +++++++++++++++++++++++++++++++++++++++++++- board/grunt/board.h | 68 ++++++++++++++ board/grunt/ec.tasklist | 8 +- board/grunt/gpio.inc | 44 +++++---- board/grunt/usb_pd_policy.c | 42 ++++----- driver/bc12/bq24392.c | 1 + 6 files changed, 339 insertions(+), 45 deletions(-) diff --git a/board/grunt/board.c b/board/grunt/board.c index 68d765dab4..23e8e0dad6 100644 --- a/board/grunt/board.c +++ b/board/grunt/board.c @@ -11,8 +11,11 @@ #include "charge_state.h" #include "charge_state_v2.h" #include "common.h" -#include "console.h" #include "compile_time_macros.h" +#include "console.h" +#include "driver/ppc/sn5s330.h" +#include "driver/tcpm/anx74xx.h" +#include "driver/tcpm/ps8xxx.h" #include "ec_commands.h" #include "extpower.h" #include "gpio.h" @@ -23,8 +26,9 @@ #include "power.h" #include "power_button.h" #include "registers.h" -#include "system.h" #include "switch.h" +#include "system.h" +#include "task.h" #include "tcpci.h" #include "usb_mux.h" #include "usb_pd_tcpm.h" @@ -32,8 +36,46 @@ static void tcpc_alert_event(enum gpio_signal signal) { - /* TODO(ecgh) */ + 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 #include "gpio_list.h" @@ -72,6 +114,179 @@ 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 = 0x50, + .drv = &anx74xx_tcpm_drv, + .pol = TCPC_ALERT_ACTIVE_LOW, + }, + [USB_PD_PORT_PS8751] = { + .i2c_host_port = I2C_PORT_TCPC1, + .i2c_slave_addr = 0x16, + .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] = { + { + .port_addr = USB_PD_PORT_ANX74XX, /* don't care / unused */ + .driver = &anx74xx_tcpm_usb_mux_driver, + .hpd_update = &anx74xx_tcpc_update_hpd_status, + }, + { + .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? */ + } +}; + +const struct sn5s330_config sn5s330_chips[] = { + {I2C_PORT_TCPC0, SN5S330_ADDR0}, + {I2C_PORT_TCPC1, SN5S330_ADDR0}, +}; +const unsigned int sn5s330_cnt = ARRAY_SIZE(sn5s330_chips); + +const int usb_port_enable[CONFIG_USB_PORT_POWER_SMART_PORT_COUNT] = { + GPIO_EN_USB_A0_5V, + GPIO_EN_USB_A1_5V, +}; + +/** + * 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); +} + +void board_tcpc_init(void) +{ + int port; + + /* TODO(ecgh): need to wait for disconnected battery? */ + + /* Only reset TCPC if not sysjump */ + if (!system_jumped_to_this_image()) + board_reset_pd_mcu(); + + /* Enable TCPC0 interrupt */ + gpio_enable_interrupt(GPIO_USB_C0_PD_INT_ODL); + + /* Enable TCPC1 interrupt */ + 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); + } +} + +int pd_snk_is_vbus_provided(int port) +{ + /* TODO(ecgh): Detect VBUS via SWCTL_INT and I2C to SN5S330 */ + return 0; +} + +int board_set_active_charge_port(int port) +{ + /* TODO(ecgh): how to disable/enable charge ports? */ + /* TODO(ecgh): how to check if port sourcing VBUS? */ + /* TODO(ecgh): disable/enable SN5S330 FETs? */ + return EC_SUCCESS; +} + +void board_set_charge_limit(int port, int supplier, int charge_ma, + int max_ma, int charge_mv) +{ + /* TODO(ecgh): check limits */ + /* + * To protect the charge inductor, at voltages above 18V we should + * set the current limit to 2.7A. + */ + if (charge_mv > 18000) + charge_ma = MIN(2700, charge_ma); + + 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. */ diff --git a/board/grunt/board.h b/board/grunt/board.h index 5a23be8c5c..056a5f0b29 100644 --- a/board/grunt/board.h +++ b/board/grunt/board.h @@ -28,8 +28,24 @@ #define CONFIG_I2C #define CONFIG_LPC +#define CONFIG_BATTERY_CUT_OFF +#define CONFIG_BATTERY_PRESENT_GPIO GPIO_EC_BATT_PRES_ODL +#define CONFIG_BATTERY_SMART + #define CONFIG_BOARD_VERSION +#define CONFIG_BC12_DETECT_BQ24392 +#define CONFIG_CHARGER +#define CONFIG_CHARGER_V2 +#define CONFIG_CHARGE_MANAGER +#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 #define CONFIG_EXTPOWER_GPIO @@ -49,7 +65,57 @@ #define GPIO_VOLUME_DOWN_L GPIO_VOLDN_BTN_ODL #define GPIO_VOLUME_UP_L GPIO_VOLUP_BTN_ODL +#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 +#define CONFIG_USB_PD_DISCHARGE_TCPC +#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_BOARD_INIT +#define CONFIG_USB_PD_TCPC_LOW_POWER +#define CONFIG_USB_PD_TCPM_ANX74XX +#define CONFIG_USB_PD_TCPM_MUX +#define CONFIG_USB_PD_TCPM_PS8751 +#define CONFIG_USB_PD_TCPM_TCPCI +#define CONFIG_USB_PD_TRY_SRC +/* TODO(ecgh): Detect VBUS via SWCTL_INT and I2C to SN5S330 */ +#define CONFIG_USB_PD_VBUS_DETECT_GPIO +/* + * TODO(ecgh) + * CONFIG_USBC_PPC_SN5S330: Need to resolve + * CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT build error + */ +#define CONFIG_USBC_SS_MUX +#define CONFIG_USBC_SS_MUX_DFP_ONLY +#define CONFIG_USBC_VCONN +#define CONFIG_USBC_VCONN_SWAP + +/* USB Type-A Port BC1.2 support */ +#define CONFIG_USB_PORT_POWER_SMART +#define CONFIG_USB_PORT_POWER_SMART_CDP_SDP_ONLY +#define CONFIG_USB_PORT_POWER_SMART_INVERTED +#define GPIO_USB1_ILIM_SEL GPIO_USB_A0_CHARGE_EN_L +#define GPIO_USB2_ILIM_SEL GPIO_USB_A1_CHARGE_EN_L + +/* 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 @@ -64,6 +130,7 @@ #include "registers.h" enum adc_channel { + ADC_VBUS = -1, ADC_TEMP_SENSOR_CHARGER, ADC_TEMP_SENSOR_SOC, ADC_CH_COUNT @@ -78,6 +145,7 @@ enum power_signal { }; void board_reset_pd_mcu(void); +void board_tcpc_init(void); #endif /* !__ASSEMBLER__ */ diff --git a/board/grunt/ec.tasklist b/board/grunt/ec.tasklist index 1cc4d81ac5..0ce94f2da3 100644 --- a/board/grunt/ec.tasklist +++ b/board/grunt/ec.tasklist @@ -22,9 +22,15 @@ #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_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_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/grunt/gpio.inc b/board/grunt/gpio.inc index 406c350d9b..4fae22910c 100644 --- a/board/grunt/gpio.inc +++ b/board/grunt/gpio.inc @@ -8,7 +8,7 @@ /* 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(6, 1), GPIO_INT_FALLING, tcpc_alert_event) +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(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) @@ -20,6 +20,7 @@ GPIO_INT(AC_PRESENT, PIN(0, 0), GPIO_INT_BOTH | GPIO_HIB_WAKE_HIGH, extpower_in GPIO_INT(WP_L, PIN(A, 1), GPIO_INT_BOTH, switch_interrupt) GPIO_INT(VOLDN_BTN_ODL, PIN(7, 0), GPIO_INT_BOTH | GPIO_PULL_UP, button_interrupt) GPIO_INT(VOLUP_BTN_ODL, 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(EN_PWR_A, PIN(E, 2), GPIO_OUT_HIGH) /* Enable Power */ GPIO(EN_PP1800_SENSOR, PIN(6, 7), GPIO_OUT_HIGH) /* Enable Power */ @@ -31,10 +32,15 @@ GPIO(PCH_RCIN_L, PIN(0, 2), GPIO_OUT_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) /* Battery Present */ -GPIO(PCH_SYS_PWROK, PIN(3, 7), GPIO_OUT_LOW) /* Power OK to SOC */ +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_PULL_UP) /* PROCHOT to SOC */ -GPIO(EC_APU_ALERT_L, PIN(4, 0), GPIO_INPUT | GPIO_PULL_UP) /* Alert 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(6AXIS_INT_L, PIN(8, 6), GPIO_INPUT | GPIO_SEL_1P8V) /* 6 Axis Accel */ + +/* 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 */ @@ -43,33 +49,37 @@ 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) /* APU_SIC */ -GPIO(I2C3_SDA, PIN(D, 0), GPIO_INPUT) /* APU_SID */ -GPIO(I2C7_SCL, PIN(B, 3), GPIO_INPUT) /* EC_I2C_SENSOR_SCL */ -GPIO(I2C7_SDA, PIN(B, 2), GPIO_INPUT) /* EC_I2C_SENSOR_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(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 */ GPIO(PCH_SCI_ODL, PIN(7, 6), GPIO_ODR_HIGH) GPIO(PCH_SMI_ODL, PIN(C, 6), GPIO_ODR_HIGH) GPIO(PCH_SLP_S0_L, PIN(A, 4), GPIO_INPUT) -GPIO(EN_USB_A0_5V, PIN(A, 0), GPIO_OUT_LOW) /* Enable A0 5V Charging */ +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(USB_A0_CHARGE_EN_L, PIN(A, 2), GPIO_OUT_HIGH) /* Enable A0 1.5A Charging */ +GPIO(USB_A0_CHARGE_EN_L, PIN(4, 0), GPIO_OUT_HIGH) /* Enable A0 1.5A Charging */ GPIO(USB_A1_CHARGE_EN_L, PIN(D, 4), GPIO_OUT_HIGH) /* Enable A1 1.5A 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, PIN(D, 7), GPIO_OUT_HIGH) /* C1 Over Current */ GPIO(USB_C0_PD_RST_L, PIN(F, 1), GPIO_OUT_HIGH) /* C0 PD Reset */ GPIO(USB_C1_PD_RST_L, PIN(D, 5), GPIO_OUT_HIGH) /* C1 PD Reset */ -GPIO(USB_C0_SWCTL_INT_ODL, PIN(0, 3), GPIO_INPUT) /* C0 Switch Control Interrupt */ -GPIO(USB_C1_SWCTL_INT_ODL, PIN(0, 4), GPIO_INPUT) /* C1 Switch Control Interrupt */ -GPIO(USB_C0_BC12_VBUS_ON_ODL, PIN(8, 2), GPIO_ODR_HIGH) /* C0 BC1.2 Power */ -GPIO(USB_C1_BC12_VBUS_ON_ODL, PIN(B, 1), GPIO_ODR_HIGH) /* C1 BC1.2 Power */ -GPIO(USB_C0_BC12_CHG_MAX, PIN(6, 2), GPIO_INPUT) /* C0 BC1.2 Detect */ -GPIO(USB_C1_BC12_CHG_MAX, PIN(8, 3), GPIO_INPUT) /* C1 BC1.2 Detect */ +GPIO(USB_C0_SWCTL_INT_ODL, PIN(0, 3), GPIO_INPUT) /* C0 Switch Interrupt */ +GPIO(USB_C1_SWCTL_INT_ODL, PIN(0, 4), GPIO_INPUT) /* C1 Switch Interrupt */ +GPIO(USB_C0_BC12_VBUS_ON_L, PIN(8, 2), 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 */ + +/* TODO(ecgh): CONFIG_USB_CHARGER assumes GPIO_USB_Cx_5V_EN */ +UNIMPLEMENTED(USB_C0_5V_EN) +UNIMPLEMENTED(USB_C1_5V_EN) /* Board ID */ -GPIO(BOARD_VERSION1, PIN(9, 6), GPIO_INPUT) +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) diff --git a/board/grunt/usb_pd_policy.c b/board/grunt/usb_pd_policy.c index 64b32ed937..9b9020a280 100644 --- a/board/grunt/usb_pd_policy.c +++ b/board/grunt/usb_pd_policy.c @@ -8,6 +8,7 @@ #include "charge_manager.h" #include "common.h" #include "console.h" +#include "driver/tcpm/anx74xx.h" #include "driver/tcpm/ps8xxx.h" #include "gpio.h" #include "hooks.h" @@ -27,7 +28,7 @@ #define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\ PDO_FIXED_COMM_CAP) -/* TODO: fill in correct source and sink capabilities */ +/* TODO(ecgh): fill in correct source and sink capabilities */ const uint32_t pd_src_pdo[] = { PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS), }; @@ -64,19 +65,7 @@ int board_vbus_source_enabled(int port) static void board_vbus_update_source_current(int port) { - enum gpio_signal gpio = port ? GPIO_USB_C1_5V_EN : GPIO_USB_C0_5V_EN; - int flags = (vbus_rp[port] == TYPEC_RP_1A5 && vbus_en[port]) ? - (GPIO_INPUT | GPIO_PULL_UP) : (GPIO_OUTPUT | GPIO_PULL_UP); - - /* - * Driving USB_Cx_5V_EN high, actually put a 16.5k resistance - * (2x 33k in parallel) on the NX5P3290 load switch ILIM pin, - * setting a minimum OCP current of 3186 mA. - * Putting an internal pull-up on USB_Cx_5V_EN, effectively put a 33k - * resistor on ILIM, setting a minimum OCP current of 1505 mA. - */ - gpio_set_level(gpio, vbus_en[port]); - gpio_set_flags(gpio, flags); + /* TODO(ecgh): how to set VBUS on/off and 1.5/3.0 A? */ } void typec_set_source_current_limit(int port, int rp) @@ -89,17 +78,14 @@ void typec_set_source_current_limit(int port, int rp) int pd_set_power_supply_ready(int port) { - enum gpio_signal gpio = port ? GPIO_USB_C1_5V_EN : GPIO_USB_C0_5V_EN; - enum gpio_signal gpio_AC = port ? - GPIO_USB_C1_20V_EN : GPIO_USB_C0_20V_EN; - /* Ensure we're not charging from this port */ - gpio_set_level(gpio, 0); - gpio_set_level(gpio_AC, 0); + /* Disable charging */ + /* TODO(ecgh): how to disable charging? */ /* Ensure we advertise the proper available current quota */ charge_manager_source_port(port, 1); pd_set_vbus_discharge(port, 0); + /* Provide VBUS */ vbus_en[port] = 1; board_vbus_update_source_current(port); @@ -148,8 +134,15 @@ int pd_check_power_swap(int port) int pd_check_data_swap(int port, int data_role) { - /* Allow data swap if we are a UFP, otherwise don't allow */ - return (data_role == PD_ROLE_UFP) ? 1 : 0; + /* + * Allow data swap if we are a UFP, otherwise don't allow. + * + * When we are still in the Read-Only firmware, avoid swapping roles + * so we don't jump in RW as a SNK/DFP and potentially confuse the + * power supply by sending a soft-reset with wrong data role. + */ + return (data_role == PD_ROLE_UFP) && + (system_get_image_copy() != SYSTEM_IMAGE_RO) ? 1 : 0; } int pd_check_vconn_swap(int port) @@ -187,7 +180,9 @@ void pd_check_pr_role(int port, int pr_role, int flags) void pd_check_dr_role(int port, int dr_role, int flags) { /* If UFP, try to switch to DFP */ - if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) + if ((flags & PD_FLAGS_PARTNER_DR_DATA) && + dr_role == PD_ROLE_UFP && + system_get_image_copy() != SYSTEM_IMAGE_RO) pd_request_data_swap(port); } /* ----------------- Vendor Defined Messages ------------------ */ @@ -227,7 +222,6 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload, is_rw ? SYSTEM_IMAGE_RW : SYSTEM_IMAGE_RO); - /* * Send update host event unless our RW hash is * already known to be the latest update RW. diff --git a/driver/bc12/bq24392.c b/driver/bc12/bq24392.c index 23e9e99eb0..8f97ad704f 100644 --- a/driver/bc12/bq24392.c +++ b/driver/bc12/bq24392.c @@ -23,6 +23,7 @@ #include "tcpm.h" #include "timer.h" #include "usb_charge.h" +#include "usb_pd.h" #include "util.h" struct bq24392_pins { -- cgit v1.2.1