summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Short <keithshort@chromium.org>2019-11-03 11:18:36 -0700
committerCommit Bot <commit-bot@chromium.org>2019-11-21 17:40:06 +0000
commit6eedf800139ba2656b437b7c91e2e7b326cf9a86 (patch)
treeb7d4f5d052403e41e9b5b84165f280599e613a24
parentbd460722c37638e23fb37177fb4b6ac8a467e31a (diff)
downloadchrome-ec-6eedf800139ba2656b437b7c91e2e7b326cf9a86.tar.gz
Volteer: configure USBC port 0
Configure PPC, and TCPC for USBC port 0. Includes battery and charger stubs. USB PD policy is stubbed or TODO. BUG=b:140572591 BRANCH=none TEST=make buildall TEST=connect 45W charger to Volteer, observe that PD negotiates 15V/3A operation. Change-Id: Iec92a93dd99286289d77e59865c6f0b52f26dffa Signed-off-by: Keith Short <keithshort@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1896641 Reviewed-by: Abe Levkoy <alevkoy@chromium.org> Signed-off-by: Keith Short <keithshort@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1929348
-rw-r--r--baseboard/volteer/baseboard.c189
-rw-r--r--baseboard/volteer/baseboard.h64
-rw-r--r--baseboard/volteer/build.mk1
-rw-r--r--baseboard/volteer/usb_pd_policy.c210
-rw-r--r--board/volteer/board.h8
-rw-r--r--board/volteer/ec.tasklist5
-rw-r--r--board/volteer/gpio.inc3
7 files changed, 477 insertions, 3 deletions
diff --git a/baseboard/volteer/baseboard.c b/baseboard/volteer/baseboard.c
index 2c914b0fa5..cc32ff4b4d 100644
--- a/baseboard/volteer/baseboard.c
+++ b/baseboard/volteer/baseboard.c
@@ -5,12 +5,27 @@
/* Volteer family-specific configuration */
#include "adc_chip.h"
+#include "charge_manager.h"
#include "charge_state.h"
+#include "driver/ppc/sn5s330.h"
+#include "driver/tcpm/tusb422.h"
#include "gpio.h"
+#include "hooks.h"
#include "i2c.h"
#include "keyboard_scan.h"
#include "pwm.h"
#include "pwm_chip.h"
+#include "usbc_ppc.h"
+#include "usb_mux.h"
+#include "usb_pd.h"
+#include "usb_pd_tcpm.h"
+#include "util.h"
+
+#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_CHIPSET, format, ## args)
+
+#define CPRINTSUSB(format, args...) cprints(CC_USBCHARGE, format, ## args)
+#define CPRINTFUSB(format, args...) cprintf(CC_USBCHARGE, format, ## args)
/******************************************************************************/
/* ADC configuration */
@@ -123,6 +138,8 @@ const struct i2c_port_t i2c_ports[] = {
};
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
+/******************************************************************************/
+/* PWM configuration */
const struct pwm_t pwm_channels[] = {
[PWM_CH_LED1_BLUE] = {
.channel = 2,
@@ -141,3 +158,175 @@ const struct pwm_t pwm_channels[] = {
},
};
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
+
+
+
+
+
+/******************************************************************************/
+/* USBC TCPC configuration */
+const struct tcpc_config_t tcpc_config[] = {
+ [USBC_PORT_C0] = {
+ .bus_type = EC_BUS_TYPE_I2C,
+ .i2c_info = {
+ .port = I2C_PORT_USB_C0,
+ .addr_flags = TUSB422_I2C_ADDR_FLAGS,
+ },
+ .drv = &tusb422_tcpm_drv,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT);
+BUILD_ASSERT(CONFIG_USB_PD_PORT_MAX_COUNT == USBC_PORT_COUNT);
+
+/******************************************************************************/
+/* USBC PPC configuration */
+struct ppc_config_t ppc_chips[] = {
+ [USBC_PORT_C0] = {
+ .i2c_port = I2C_PORT_USB_C0,
+ .i2c_addr_flags = SN5S330_ADDR0_FLAGS,
+ .drv = &sn5s330_drv
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(ppc_chips) == USBC_PORT_COUNT);
+unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
+
+/******************************************************************************/
+/* USBC mux configuration - Tiger Lake includes internal mux */
+struct usb_mux usb_muxes[] = {
+ [USBC_PORT_C0] = {
+ .driver = &virtual_usb_mux_driver,
+ },
+};
+BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT);
+
+
+static void baseboard_tcpc_init(void)
+{
+ /* Enable PPC interrupts. */
+ gpio_enable_interrupt(GPIO_USB_C0_PPC_INT_ODL);
+
+ /* Enable TCPC interrupts. */
+ gpio_enable_interrupt(GPIO_USB_C0_TCPC_INT_ODL);
+}
+DECLARE_HOOK(HOOK_INIT, baseboard_tcpc_init, HOOK_PRIO_INIT_I2C + 1);
+
+/******************************************************************************/
+/* PPC support routines */
+void ppc_interrupt(enum gpio_signal signal)
+{
+ switch (signal) {
+ case GPIO_USB_C0_PPC_INT_ODL:
+ sn5s330_interrupt(USBC_PORT_C0);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/******************************************************************************/
+/* TCPC support routines */
+void board_reset_pd_mcu(void)
+{
+ /* No reset available for TCPC on port 0 */
+}
+
+uint16_t tcpc_get_alert_status(void)
+{
+ uint16_t status = 0;
+
+ /*
+ * Check which port has the ALERT line set
+ */
+ if (!gpio_get_level(GPIO_USB_C0_TCPC_INT_ODL))
+ status |= PD_STATUS_TCPC_ALERT_0;
+
+ return status;
+}
+
+void tcpc_alert_event(enum gpio_signal signal)
+{
+ /* TODO: b/140572591 - check correct operation for Volteer */
+
+ int port = -1;
+
+ switch (signal) {
+ case GPIO_USB_C0_TCPC_INT_ODL:
+ port = 0;
+ break;
+ default:
+ return;
+ }
+
+ schedule_deferred_pd_interrupt(port);
+}
+
+int board_set_active_charge_port(int port)
+{
+ /* TODO: b/140561826 - check correct operation for Volteer */
+
+ int is_valid_port = (port >= 0 &&
+ port < CONFIG_USB_PD_PORT_MAX_COUNT);
+ int i;
+
+ if (port == CHARGE_PORT_NONE) {
+ CPRINTSUSB("Disabling all charger ports");
+
+ /* Disable all ports. */
+ for (i = 0; i < ppc_cnt; i++) {
+ /*
+ * Do not return early if one fails otherwise we can
+ * get into a boot loop assertion failure.
+ */
+ if (ppc_vbus_sink_enable(i, 0))
+ CPRINTSUSB("Disabling C%d as sink failed.", i);
+ }
+
+ return EC_SUCCESS;
+ } else if (!is_valid_port) {
+ return EC_ERROR_INVAL;
+ }
+
+
+ /* Check if the port is sourcing VBUS. */
+ if (ppc_is_sourcing_vbus(port)) {
+ CPRINTFUSB("Skip enable C%d", port);
+ return EC_ERROR_INVAL;
+ }
+
+ CPRINTSUSB("New charge port: C%d", port);
+
+ /*
+ * 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))
+ CPRINTSUSB("C%d: sink path disable failed.", i);
+ }
+
+ /* Enable requested charge port. */
+ if (ppc_vbus_sink_enable(port, 1)) {
+ CPRINTSUSB("C%d: sink path enable failed.", port);
+ 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);
+}
+
+void board_overcurrent_event(int port, int is_overcurrented)
+{
+ /* TODO: b/140561826 - check correct operation for Volteer */
+}
+
diff --git a/baseboard/volteer/baseboard.h b/baseboard/volteer/baseboard.h
index 9c638577c2..585be60309 100644
--- a/baseboard/volteer/baseboard.h
+++ b/baseboard/volteer/baseboard.h
@@ -8,7 +8,6 @@
#ifndef __CROS_EC_BASEBOARD_H
#define __CROS_EC_BASEBOARD_H
-
/* NPCX7 config */
#define NPCX7_PWM1_SEL 0 /* GPIO C2 is not used as PWM1. */
#define NPCX_UART_MODULE2 1 /* GPIO64/65 are used as UART pins. */
@@ -64,6 +63,7 @@
/* Sensors */
/* Common charger defines */
+#define CONFIG_CHARGE_MANAGER
#define CONFIG_CHARGER
#define CONFIG_CHARGER_DISCHARGE_ON_AC
#define CONFIG_CHARGER_INPUT_CURRENT 512
@@ -78,8 +78,54 @@
/* #define CONFIG_BATTERY_CUT_OFF */
/* USB Type C and USB PD defines */
+/* Enable the new USB-C PD stack */
+#define CONFIG_USB_SM_FRAMEWORK
+#define CONFIG_USB_TYPEC_SM
+#define CONFIG_USB_PRL_SM
+#define CONFIG_USB_PE_SM
+#define CONFIG_USB_TYPEC_DRP_ACC_TRYSRC
+
+#define CONFIG_USB_POWER_DELIVERY
+#define CONFIG_USB_PD_DISCHARGE_PPC
+#define CONFIG_USB_PD_DUAL_ROLE
+#define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0
+#define CONFIG_USB_PD_PORT_MAX_COUNT 1
+#define CONFIG_USB_PD_TCPC_LOW_POWER
+#define CONFIG_USB_PD_TCPM_TCPCI
+#define CONFIG_USB_PD_TCPM_TUSB422 /* USBC port C0 */
+#define CONFIG_USB_PD_TRY_SRC
+#define CONFIG_USB_PD_VBUS_DETECT_PPC
+#define CONFIG_USB_PD_VBUS_MEASURE_NOT_PRESENT
+
+#define CONFIG_USBC_PPC
+#define CONFIG_CMD_PPC_DUMP
+/* Note - SN5S330 support automatically adds
+ * CONFIG_USBC_PPC_POLARITY
+ * CONFIG_USBC_PPC_SBU
+ * CONFIG_USBC_PPC_VCONN
+ */
+#define CONFIG_USBC_PPC_SN5S330 /* USBC port C0 */
+
+#define CONFIG_USBC_SS_MUX
+#define CONFIG_USB_MUX_VIRTUAL
+
+#define CONFIG_USBC_VCONN
+#define CONFIG_USBC_VCONN_SWAP
+
+/* TODO: b/144165680 - measure and check these values on Volteer */
+#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */
+#define PD_POWER_SUPPLY_TURN_OFF_DELAY 30000 /* us */
+#define PD_VCONN_SWAP_DELAY 5000 /* us */
+
+/*
+ * SN5S30 PPC supports up to 24V VBUS source and sink, however passive USB-C
+ * cables only support up to 60W.
+ */
+#define PD_OPERATING_POWER_MW 15000
+#define PD_MAX_POWER_MW 60000
+#define PD_MAX_CURRENT_MA 3000
+#define PD_MAX_VOLTAGE_MV 20000
-/* BC 1.2 */
/* I2C Bus Configuration */
#define CONFIG_I2C
@@ -99,6 +145,9 @@
#ifndef __ASSEMBLER__
+#include "gpio_signal.h"
+
+
enum adc_channel {
ADC_TEMP_SENSOR_1_CHARGER,
ADC_TEMP_SENSOR_2_PP3300_REGULATOR,
@@ -114,6 +163,17 @@ enum pwm_channel {
PWM_CH_COUNT
};
+enum usbc_port {
+ USBC_PORT_C0 = 0,
+ USBC_PORT_COUNT
+};
+
+void board_reset_pd_mcu(void);
+
+/* Common definition for the USB PD interrupt handlers. */
+void ppc_interrupt(enum gpio_signal signal);
+void tcpc_alert_event(enum gpio_signal signal);
+
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BASEBOARD_H */
diff --git a/baseboard/volteer/build.mk b/baseboard/volteer/build.mk
index 296bc15520..ee12262052 100644
--- a/baseboard/volteer/build.mk
+++ b/baseboard/volteer/build.mk
@@ -9,3 +9,4 @@
baseboard-y=baseboard.o
baseboard-y+=led.o
baseboard-y+=battery_presence.o
+baseboard-y+=usb_pd_policy.o
diff --git a/baseboard/volteer/usb_pd_policy.c b/baseboard/volteer/usb_pd_policy.c
new file mode 100644
index 0000000000..ac424984e4
--- /dev/null
+++ b/baseboard/volteer/usb_pd_policy.c
@@ -0,0 +1,210 @@
+/* Copyright 2019 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 Volteer boards */
+#include "charge_manager.h"
+#include "compile_time_macros.h"
+#include "console.h"
+#include "gpio.h"
+#include "usb_mux.h"
+#include "usbc_ppc.h"
+#include "usb_pd.h"
+#include "system.h"
+
+#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
+
+/*
+ * TODO(b/140578872): Whole file copied from zork. Figure out correct values for
+ * volteer.
+ */
+#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\
+ PDO_FIXED_COMM_CAP)
+const uint32_t pd_src_pdo[] = {
+ PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS),
+};
+const uint32_t pd_src_pdo_max[] = {
+ PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS),
+};
+const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max);
+
+const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
+const uint32_t pd_snk_pdo[] = {
+ PDO_FIXED(5000, 500, PDO_FIXED_FLAGS),
+ PDO_BATT(4750, 21000, 15000),
+ PDO_VAR(4750, 21000, 3000),
+};
+const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
+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);
+}
+
+int pd_check_power_swap(int port)
+{
+ /* TODO - check correct operation for Volteer */
+
+ /*
+ * Allow power swap if we are acting as a dual role device. If we are
+ * not acting as dual role (ex. suspended), then only allow power swap
+ * if we are sourcing when we could be sinking.
+ */
+ if (pd_get_dual_role(port) == PD_DRP_TOGGLE_ON)
+ return 1;
+ else if (pd_get_role(port) == PD_ROLE_SOURCE)
+ return 1;
+ else
+ return 0;
+}
+
+int pd_check_vconn_swap(int port)
+{
+ /* TODO - check correct operation for Volteer */
+ return 0;
+}
+
+void pd_power_supply_reset(int port)
+{
+ /* TODO - check correct operation for Volteer */
+}
+
+void pd_execute_data_swap(int port, int data_role)
+{
+ /* TODO - check correct operation for Volteer */
+
+ /* Do nothing */
+}
+
+int pd_is_valid_input_voltage(int mv)
+{
+ /* TODO - check correct operation for Volteer */
+
+ return 1;
+}
+
+int pd_set_power_supply_ready(int port)
+{
+ int rv;
+
+ /* Disable charging. */
+ rv = ppc_vbus_sink_enable(port, 0);
+ if (rv)
+ return rv;
+
+ pd_set_vbus_discharge(port, 0);
+
+ /* Provide Vbus. */
+ rv = ppc_vbus_source_enable(port, 1);
+ if (rv)
+ return rv;
+
+#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT
+ /* Ensure we advertise the proper available current quota */
+ charge_manager_source_port(port, 1);
+#endif /* defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */
+
+ /* Notify host of power info change. */
+ pd_send_host_event(PD_EVENT_POWER_CHANGE);
+
+ return EC_SUCCESS;
+}
+
+void pd_transition_voltage(int idx)
+{
+ /* TODO - check correct operation for Volteer */
+
+ /* No-operation: we are always 5V */
+}
+
+int pd_snk_is_vbus_provided(int port)
+{
+ return ppc_is_vbus_present(port);
+}
+
+void typec_set_source_current_limit(int port, enum tcpc_rp_value rp)
+{
+ ppc_set_vbus_source_current_limit(port, rp);
+}
+
+int board_vbus_source_enabled(int port)
+{
+ return ppc_is_sourcing_vbus(port);
+}
+
+
+/* ----------------- Vendor Defined Messages ------------------ */
+const struct svdm_response svdm_rsp = {
+ .identity = NULL,
+ .svids = NULL,
+ .modes = NULL,
+};
+
+int pd_custom_vdm(int port, int cnt, uint32_t *payload,
+ uint32_t **rpayload)
+{
+ /* TODO - check correct operation for Volteer */
+
+ int cmd = PD_VDO_CMD(payload[0]);
+ uint16_t dev_id = 0;
+ int is_rw, is_latest;
+
+ /* make sure we have some payload */
+ if (cnt == 0)
+ return 0;
+
+ switch (cmd) {
+ case VDO_CMD_VERSION:
+ /* guarantee last byte of payload is null character */
+ *(payload + cnt - 1) = 0;
+ CPRINTF("version: %s\n", (char *)(payload+1));
+ break;
+ case VDO_CMD_READ_INFO:
+ case VDO_CMD_SEND_INFO:
+ /* copy hash */
+ if (cnt == 7) {
+ dev_id = VDO_INFO_HW_DEV_ID(payload[6]);
+ is_rw = VDO_INFO_IS_RW(payload[6]);
+
+ is_latest = pd_dev_store_rw_hash(port,
+ dev_id,
+ payload + 1,
+ 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.
+ */
+ if (!is_rw || !is_latest)
+ pd_send_host_event(PD_EVENT_UPDATE_DEVICE);
+
+ CPRINTF("DevId:%d.%d SW:%d RW:%d\n",
+ HW_DEV_ID_MAJ(dev_id),
+ HW_DEV_ID_MIN(dev_id),
+ VDO_INFO_SW_DBG_VER(payload[6]),
+ is_rw);
+ } else if (cnt == 6) {
+ /* really old devices don't have last byte */
+ pd_dev_store_rw_hash(port, dev_id, payload + 1,
+ SYSTEM_IMAGE_UNKNOWN);
+ }
+ break;
+ case VDO_CMD_CURRENT:
+ CPRINTF("Current: %dmA\n", payload[1]);
+ break;
+ case VDO_CMD_FLIP:
+ usb_mux_flip(port);
+ break;
+#ifdef CONFIG_USB_PD_LOGGING
+ case VDO_CMD_GET_LOG:
+ pd_log_recv_vdm(port, cnt, payload);
+ break;
+#endif /* CONFIG_USB_PD_LOGGING */
+ }
+
+ return 0;
+}
+
+
diff --git a/board/volteer/board.h b/board/volteer/board.h
index 0d645c99c3..06d13e1526 100644
--- a/board/volteer/board.h
+++ b/board/volteer/board.h
@@ -22,6 +22,14 @@
#define CONFIG_POWER_BUTTON
+/*
+ * USB ID
+ * TODO(b/140578872): Figure out what volteer's is.
+ * This is allocated specifically for Zork:Trembyle
+ * http://google3/hardware/standards/usb/
+ */
+#define CONFIG_USB_PID 0x503E
+
#undef CONFIG_UART_TX_BUF_SIZE
#define CONFIG_UART_TX_BUF_SIZE 4096
diff --git a/board/volteer/ec.tasklist b/board/volteer/ec.tasklist
index ebb4205d6c..d5f38958eb 100644
--- a/board/volteer/ec.tasklist
+++ b/board/volteer/ec.tasklist
@@ -12,7 +12,10 @@
TASK_ALWAYS(CHARGER, charger_task, NULL, VENTI_TASK_STACK_SIZE) \
TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \
TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_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, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS(PD_INT_C0, pd_interrupt_handler_task, 0, TASK_STACK_SIZE)
diff --git a/board/volteer/gpio.inc b/board/volteer/gpio.inc
index 5ce78773b6..e9575587c0 100644
--- a/board/volteer/gpio.inc
+++ b/board/volteer/gpio.inc
@@ -32,6 +32,8 @@ GPIO_INT(PG_EC_ALL_SYS_PWRGD, PIN(F, 4), GPIO_INT_BOTH, power_signal_interrupt
/* Sensor Interrupts */
/* USB-C interrupts */
+GPIO_INT(USB_C0_TCPC_INT_ODL, PIN(E, 0), GPIO_INT_BOTH, tcpc_alert_event)
+GPIO_INT(USB_C0_PPC_INT_ODL, PIN(6, 2), GPIO_INT_BOTH, ppc_interrupt)
/* HDMI interrupts */
@@ -81,6 +83,7 @@ GPIO(SYS_RST_ODL, PIN(C, 5), GPIO_ODR_HIGH)
GPIO(EC_PCH_INT_ODL, PIN(D, 6), GPIO_ODR_HIGH) /* TODO - b/140557015 - implement with MKBD sensor events */
/* USB and USBC Signals */
+GPIO(EN_PP3300_AG, PIN(8, 5), GPIO_OUT_LOW)
/* Misc Signals */
/* This selects between an LED module on the motherboard and one on the daughter