summaryrefslogtreecommitdiff
path: root/baseboard
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2021-06-23 17:28:37 -0700
committerCommit Bot <commit-bot@chromium.org>2021-06-28 22:26:40 +0000
commitbf3c4f24fd2e4d84fc35ee643fcaac489ef391d2 (patch)
tree941678364cf1a5947cfd30f4706b8dc823a9573d /baseboard
parent28423f8a28bb34343f8c6358659d3857b73ab862 (diff)
downloadchrome-ec-bf3c4f24fd2e4d84fc35ee643fcaac489ef391d2.tar.gz
herobrine: Initial board commit for herobrine_npcx7
This CL first copies: * baseboard/trogdor -> baseboard/herobrine * board/trogdor -> board/herobrine_npcx7 And update the following: * Rename "Trogdor" to "Herobrine" * Update the copyright year * Use the Herobrine USB PID BRANCH=None BUG=b:191803008 TEST=Built the herobrine_npcx7 image successfully. Change-Id: I604671b686fc0212bcb49865f59e23d46f6275cf Signed-off-by: Wai-Hong Tam <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2984400 Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Diffstat (limited to 'baseboard')
-rw-r--r--baseboard/herobrine/baseboard.c22
-rw-r--r--baseboard/herobrine/baseboard.h216
-rw-r--r--baseboard/herobrine/build.mk12
-rw-r--r--baseboard/herobrine/hibernate.c13
-rw-r--r--baseboard/herobrine/usb_pd_policy.c258
-rw-r--r--baseboard/herobrine/usbc_config.c60
6 files changed, 581 insertions, 0 deletions
diff --git a/baseboard/herobrine/baseboard.c b/baseboard/herobrine/baseboard.c
new file mode 100644
index 0000000000..e1eef9c374
--- /dev/null
+++ b/baseboard/herobrine/baseboard.c
@@ -0,0 +1,22 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Herobrine baseboard-specific configuration */
+
+#include "i2c.h"
+
+/* Wake-up pins for hibernate */
+const enum gpio_signal hibernate_wake_pins[] = {
+ GPIO_LID_OPEN,
+ GPIO_AC_PRESENT,
+ GPIO_POWER_BUTTON_L,
+ GPIO_EC_RST_ODL,
+};
+const int hibernate_wake_pins_used = ARRAY_SIZE(hibernate_wake_pins);
+
+int board_allow_i2c_passthru(int port)
+{
+ return (port == I2C_PORT_VIRTUAL_BATTERY);
+}
diff --git a/baseboard/herobrine/baseboard.h b/baseboard/herobrine/baseboard.h
new file mode 100644
index 0000000000..bd38fe38ba
--- /dev/null
+++ b/baseboard/herobrine/baseboard.h
@@ -0,0 +1,216 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Herobrine baseboard configuration */
+
+#ifndef __CROS_EC_BASEBOARD_H
+#define __CROS_EC_BASEBOARD_H
+
+/*
+ * By default, enable all console messages excepted event and HC:
+ * The sensor stack is generating a lot of activity.
+ * They can be enabled through the console command 'chan'.
+ */
+#define CC_DEFAULT (CC_ALL & ~(CC_MASK(CC_HOSTCMD)))
+
+/* 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 */
+#define CONFIG_SPI_FLASH_REGS
+#define CONFIG_SPI_FLASH_W25Q80 /* Internal SPI flash type. */
+
+/* EC Modules */
+#define CONFIG_I2C
+#define CONFIG_I2C_CONTROLLER
+#define CONFIG_I2C_VIRTUAL_BATTERY
+#define CONFIG_I2C_PASSTHRU_RESTRICTED
+#define CONFIG_LED_COMMON
+#define CONFIG_LOW_POWER_IDLE
+#define CONFIG_ADC
+#define CONFIG_BACKLIGHT_LID
+#define CONFIG_FPU
+#define CONFIG_PWM
+#define CONFIG_PWM_DISPLIGHT
+
+#define CONFIG_VBOOT_HASH
+
+#undef CONFIG_PECI
+
+#define CONFIG_HOSTCMD_SPS
+#define CONFIG_HOST_COMMAND_STATUS
+#define CONFIG_HOSTCMD_SECTION_SORTED
+#define CONFIG_KEYBOARD_COL2_INVERTED
+#define CONFIG_MKBP_USE_GPIO
+
+#define CONFIG_BOARD_VERSION_GPIO
+#define CONFIG_POWER_BUTTON
+#define CONFIG_VOLUME_BUTTONS
+#define CONFIG_EMULATED_SYSRQ
+#define CONFIG_CMD_BUTTON
+#define CONFIG_SWITCH
+#define CONFIG_LID_SWITCH
+#define CONFIG_EXTPOWER_GPIO
+
+/*
+ * On power-on, H1 releases the EC from reset but then quickly asserts and
+ * releases the reset a second time. This means the EC sees 2 resets:
+ * (1) power-on reset, (2) reset-pin reset. This config will
+ * allow the second reset to be treated as a power-on.
+ */
+#define CONFIG_BOARD_RESET_AFTER_POWER_ON
+
+/* Increase console output buffer since we have the RAM available. */
+#undef CONFIG_UART_TX_BUF_SIZE
+#define CONFIG_UART_TX_BUF_SIZE 4096
+
+/* Battery */
+#define CONFIG_BATTERY_CUT_OFF
+#define CONFIG_BATTERY_PRESENT_GPIO GPIO_BATT_PRES_ODL
+#define CONFIG_BATTERY_SMART
+
+/* Charger */
+#define CONFIG_CHARGER
+#define CONFIG_CHARGE_MANAGER
+#define CONFIG_CHARGER_ISL9238
+#define CONFIG_CHARGER_PROFILE_OVERRIDE
+#define CONFIG_CHARGE_RAMP_HW
+#define CONFIG_USB_CHARGER
+#define CONFIG_CMD_CHARGER_ADC_AMON_BMON
+#define CONFIG_CHARGER_PSYS
+#define CONFIG_CHARGER_PSYS_READ
+#define CONFIG_CHARGER_DISCHARGE_ON_AC
+
+#define CONFIG_CHARGER_INPUT_CURRENT 512
+#define CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON 10000
+#define CONFIG_CHARGER_SENSE_RESISTOR 10
+#define CONFIG_CHARGER_SENSE_RESISTOR_AC 20
+
+/*
+ * USB ID
+ *
+ * This is allocated specifically for Herobrine
+ * http://google3/hardware/standards/usb/
+ */
+#define CONFIG_USB_PID 0x5055
+
+/* USB */
+#define CONFIG_USB_POWER_DELIVERY
+#define CONFIG_USB_PD_TCPMV2
+#define CONFIG_USB_DRP_ACC_TRYSRC
+#define CONFIG_USB_PD_DECODE_SOP
+#define CONFIG_HOSTCMD_PD_CONTROL
+#define CONFIG_USB_PD_ALT_MODE
+#define CONFIG_USB_PD_ALT_MODE_DFP
+#define CONFIG_USB_PD_DISCHARGE_PPC
+#define CONFIG_USB_PD_DUAL_ROLE
+#define CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE
+#define CONFIG_USB_PD_TCPC_LOW_POWER
+#define CONFIG_USB_PD_LOGGING
+#define CONFIG_USB_PD_TCPM_MUX
+#define CONFIG_USB_PD_TCPM_TCPCI
+#define CONFIG_CMD_TCPC_DUMP
+#define CONFIG_USB_PD_TRY_SRC
+#define CONFIG_USB_PD_VBUS_DETECT_TCPC
+#define CONFIG_USB_PD_5V_EN_CUSTOM
+#define CONFIG_USBC_SS_MUX
+#define CONFIG_USBC_SS_MUX_DFP_ONLY
+#define CONFIG_USBC_VCONN
+#define CONFIG_USBC_VCONN_SWAP
+
+/* RTC */
+#define CONFIG_CMD_RTC
+#define CONFIG_HOSTCMD_RTC
+
+/* Sensors */
+/* Enable sensor fifo, must also define the _SIZE and _THRES */
+#define CONFIG_ACCEL_FIFO
+/* FIFO size is a power of 2. */
+#define CONFIG_ACCEL_FIFO_SIZE 256
+/* Depends on how fast the AP boots and typical ODRs. */
+#define CONFIG_ACCEL_FIFO_THRES (CONFIG_ACCEL_FIFO_SIZE / 3)
+#define CONFIG_CMD_ACCELS
+#define CONFIG_CMD_ACCEL_INFO
+
+/* PD */
+#define PD_POWER_SUPPLY_TURN_ON_DELAY 30000 /* us */
+#define PD_POWER_SUPPLY_TURN_OFF_DELAY 250000 /* us */
+
+#define PD_OPERATING_POWER_MW 10000
+#define PD_MAX_POWER_MW ((PD_MAX_VOLTAGE_MV * PD_MAX_CURRENT_MA) / 1000)
+#define PD_MAX_CURRENT_MA 3000
+#define PD_MAX_VOLTAGE_MV 20000
+
+/* Chipset */
+#define CONFIG_CHIPSET_SC7180
+#define CONFIG_CHIPSET_RESET_HOOK
+#define CONFIG_CHIPSET_RESUME_INIT_HOOK
+#define CONFIG_POWER_COMMON
+#define CONFIG_POWER_PP5000_CONTROL
+#define CONFIG_POWER_TRACK_HOST_SLEEP_STATE
+#define CONFIG_POWER_SLEEP_FAILURE_DETECTION
+#define CONFIG_CMD_AP_RESET_LOG
+
+/*
+ * Macros for GPIO signals used in common code that don't match the
+ * schematic names. Signal names in gpio.inc match the schematic and are
+ * then redefined here to so it's more clear which signal is being used for
+ * which purpose.
+ */
+#define GPIO_POWER_BUTTON_L GPIO_EC_PWR_BTN_ODL
+#define GPIO_VOLUME_DOWN_L GPIO_EC_VOLDN_BTN_ODL
+#define GPIO_VOLUME_UP_L GPIO_EC_VOLUP_BTN_ODL
+#define GPIO_LID_OPEN GPIO_LID_OPEN_EC
+#define GPIO_SHI_CS_L GPIO_AP_EC_SPI_CS_L
+#define GPIO_ENTERING_RW GPIO_EC_ENTERING_RW
+#define GPIO_BATT_PRES_ODL GPIO_EC_BATT_PRES_ODL
+#define GPIO_EN_PP5000 GPIO_EN_PP5000_A
+#define GPIO_ENABLE_BACKLIGHT GPIO_EC_BL_DISABLE_L
+#define GPIO_BOARD_VERSION1 GPIO_BRD_ID0
+#define GPIO_BOARD_VERSION2 GPIO_BRD_ID1
+#define GPIO_BOARD_VERSION3 GPIO_BRD_ID2
+#define GPIO_KBD_KSO2 GPIO_EC_KSO_02_INV
+
+/* I2C Ports */
+#define I2C_PORT_BATTERY I2C_PORT_POWER
+#define I2C_PORT_VIRTUAL_BATTERY I2C_PORT_BATTERY
+#define I2C_PORT_CHARGER I2C_PORT_POWER
+#define I2C_PORT_ACCEL I2C_PORT_SENSOR
+#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_WLC NPCX_I2C_PORT3_0
+#define I2C_PORT_EEPROM NPCX_I2C_PORT5_0
+#define I2C_PORT_SENSOR NPCX_I2C_PORT7_0
+
+/* UART */
+#define CONFIG_CMD_CHARGEN
+
+/* Define the host events which are allowed to wake AP up from S3 */
+#define CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK \
+ (EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN) | \
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON) | \
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED) | \
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED) | \
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_HANG_DETECT) | \
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC) | \
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_MODE_CHANGE) | \
+ EC_HOST_EVENT_MASK(EC_HOST_EVENT_DEVICE))
+
+/* And the MKBP events */
+#ifdef HAS_TASK_KEYSCAN
+#define CONFIG_MKBP_EVENT_WAKEUP_MASK \
+ (BIT(EC_MKBP_EVENT_KEY_MATRIX) | \
+ BIT(EC_MKBP_EVENT_HOST_EVENT) | \
+ BIT(EC_MKBP_EVENT_SENSOR_FIFO))
+#else
+#define CONFIG_MKBP_EVENT_WAKEUP_MASK \
+ (BIT(EC_MKBP_EVENT_HOST_EVENT) | \
+ BIT(EC_MKBP_EVENT_SENSOR_FIFO))
+#endif
+
+#endif /* __CROS_EC_BASEBOARD_H */
diff --git a/baseboard/herobrine/build.mk b/baseboard/herobrine/build.mk
new file mode 100644
index 0000000000..f4d2b5edb6
--- /dev/null
+++ b/baseboard/herobrine/build.mk
@@ -0,0 +1,12 @@
+# -*- makefile -*-
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# Baseboard specific files build
+#
+
+baseboard-y+=baseboard.o
+baseboard-y+=hibernate.o
+baseboard-y+=usbc_config.o
+baseboard-y+=usb_pd_policy.o
diff --git a/baseboard/herobrine/hibernate.c b/baseboard/herobrine/hibernate.c
new file mode 100644
index 0000000000..c28082e75d
--- /dev/null
+++ b/baseboard/herobrine/hibernate.c
@@ -0,0 +1,13 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gpio.h"
+#include "system.h"
+
+void board_hibernate_late(void)
+{
+ /* Set the hibernate GPIO to turn off the rails */
+ gpio_set_level(GPIO_HIBERNATE_L, 0);
+}
diff --git a/baseboard/herobrine/usb_pd_policy.c b/baseboard/herobrine/usb_pd_policy.c
new file mode 100644
index 0000000000..87d47c32e2
--- /dev/null
+++ b/baseboard/herobrine/usb_pd_policy.c
@@ -0,0 +1,258 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "charge_manager.h"
+#include "chipset.h"
+#include "console.h"
+#include "gpio.h"
+#include "system.h"
+#include "usb_mux.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)
+
+int pd_check_vconn_swap(int port)
+{
+ /* In G3, do not allow vconn swap since PP5000 rail is off */
+ return gpio_get_level(GPIO_EN_PP5000);
+}
+
+static uint8_t vbus_en[CONFIG_USB_PD_PORT_MAX_COUNT];
+#if CONFIG_USB_PD_PORT_MAX_COUNT == 1
+static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5};
+#else
+static uint8_t vbus_rp[CONFIG_USB_PD_PORT_MAX_COUNT] = {TYPEC_RP_1A5,
+ TYPEC_RP_1A5};
+#endif
+
+static void board_vbus_update_source_current(int port)
+{
+ /* Both port are controlled by PPC SN5S330. */
+ ppc_set_vbus_source_current_limit(port, vbus_rp[port]);
+ ppc_vbus_source_enable(port, vbus_en[port]);
+}
+
+void pd_power_supply_reset(int port)
+{
+ int prev_en;
+
+ prev_en = vbus_en[port];
+
+ /* Disable VBUS */
+ vbus_en[port] = 0;
+ board_vbus_update_source_current(port);
+
+ /* Enable discharge if we were previously sourcing 5V */
+ if (prev_en)
+ pd_set_vbus_discharge(port, 1);
+
+ /* notify host of power info change */
+ pd_send_host_event(PD_EVENT_POWER_CHANGE);
+}
+
+int pd_set_power_supply_ready(int port)
+{
+ /* Disable charging */
+ board_vbus_sink_enable(port, 0);
+
+ pd_set_vbus_discharge(port, 0);
+
+ /* Provide VBUS */
+ vbus_en[port] = 1;
+ board_vbus_update_source_current(port);
+
+ /* notify host of power info change */
+ pd_send_host_event(PD_EVENT_POWER_CHANGE);
+
+ return EC_SUCCESS; /* we are ready */
+}
+
+int board_vbus_source_enabled(int port)
+{
+ return vbus_en[port];
+}
+
+__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp)
+{
+ vbus_rp[port] = rp;
+ board_vbus_update_source_current(port);
+}
+
+int pd_snk_is_vbus_provided(int port)
+{
+ return tcpm_check_vbus_level(port, VBUS_PRESENT);
+}
+
+/* ----------------- Vendor Defined Messages ------------------ */
+#ifdef CONFIG_USB_PD_ALT_MODE_DFP
+__override int svdm_dp_config(int port, uint32_t *payload)
+{
+ int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT);
+ uint8_t pin_mode = get_dp_pin_mode(port);
+
+ if (!pin_mode)
+ return 0;
+
+ /*
+ * Defer setting the usb_mux until HPD goes high, svdm_dp_attention().
+ * The AP only supports one DP phy. An external DP mux switches between
+ * the two ports. Should switch those muxes when it is really used,
+ * i.e. HPD high; otherwise, the real use case is preempted, like:
+ * (1) plug a dongle without monitor connected to port-0,
+ * (2) plug a dongle without monitor connected to port-1,
+ * (3) plug a monitor to the port-1 dongle.
+ */
+
+ payload[0] = VDO(USB_SID_DISPLAYPORT, 1,
+ CMD_DP_CONFIG | VDO_OPOS(opos));
+ payload[1] = VDO_DP_CFG(pin_mode, /* pin mode */
+ 1, /* DPv1.3 signaling */
+ 2); /* UFP connected */
+ return 2;
+};
+
+__override void svdm_dp_post_config(int port)
+{
+ dp_flags[port] |= DP_FLAGS_DP_ON;
+}
+
+/**
+ * Is the port fine to be muxed its DisplayPort lines?
+ *
+ * Only one port can be muxed to DisplayPort at a time.
+ *
+ * @param port Port number of TCPC.
+ * @return 1 is fine; 0 is bad as other port is already muxed;
+ */
+static int is_dp_muxable(int port)
+{
+ int i;
+
+ for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++)
+ if (i != port) {
+ if (usb_mux_get(i) & USB_PD_MUX_DP_ENABLED)
+ return 0;
+ }
+
+ return 1;
+}
+
+__override int svdm_dp_attention(int port, uint32_t *payload)
+{
+ enum gpio_signal hpd = GPIO_DP_HOT_PLUG_DET;
+ int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
+ int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
+ int cur_lvl = gpio_get_level(hpd);
+
+ dp_status[port] = payload[1];
+
+ if (!is_dp_muxable(port)) {
+ /* TODO(waihong): Info user? */
+ CPRINTS("p%d: The other port is already muxed.", port);
+ return 0;
+ }
+
+ /*
+ * Initial implementation to handle HPD. Only the first-plugged port
+ * works, i.e. sending HPD signal to AP. The second-plugged port
+ * will be ignored.
+ *
+ * TODO(waihong): Continue the above case, if the first-plugged port
+ * is then unplugged, switch to the second-plugged port and signal AP?
+ */
+ if (lvl) {
+ /*
+ * Enable and switch the DP port selection mux to the
+ * correct port.
+ *
+ * TODO(waihong): Better to move switching DP mux to
+ * the usb_mux abstraction.
+ */
+ gpio_set_level(GPIO_DP_MUX_SEL, port == 1);
+ gpio_set_level(GPIO_DP_MUX_OE_L, 0);
+
+ /* Connect the SBU lines in PPC chip. */
+ if (IS_ENABLED(CONFIG_USBC_PPC_SBU))
+ ppc_set_sbu(port, 1);
+
+ /*
+ * Connect the USB SS/DP lines in TCPC chip.
+ *
+ * When mf_pref not true, still use the dock muxing
+ * because of the board USB-C topology (limited to 2
+ * lanes DP).
+ */
+ usb_mux_set(port, USB_PD_MUX_DOCK,
+ USB_SWITCH_CONNECT,
+ polarity_rm_dts(pd_get_polarity(port)));
+ } else {
+ /* Disconnect the DP port selection mux. */
+ gpio_set_level(GPIO_DP_MUX_OE_L, 1);
+ gpio_set_level(GPIO_DP_MUX_SEL, 0);
+
+ /* Disconnect the SBU lines in PPC chip. */
+ if (IS_ENABLED(CONFIG_USBC_PPC_SBU))
+ ppc_set_sbu(port, 0);
+
+ /* Disconnect the DP but keep the USB SS lines in TCPC chip. */
+ usb_mux_set(port, USB_PD_MUX_USB_ENABLED,
+ USB_SWITCH_CONNECT,
+ polarity_rm_dts(pd_get_polarity(port)));
+ }
+
+ if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) &&
+ (irq || lvl))
+ /*
+ * Wake up the AP. IRQ or level high indicates a DP sink is now
+ * present.
+ */
+ pd_notify_dp_alt_mode_entry(port);
+
+ /* Configure TCPC for the HPD event, for proper muxing */
+ usb_mux_hpd_update(port, lvl, irq);
+
+ /* Signal AP for the HPD event, through GPIO to AP */
+ if (irq & cur_lvl) {
+ uint64_t now = get_time().val;
+ /* Wait for the minimum spacing between IRQ_HPD if needed */
+ if (now < svdm_hpd_deadline[port])
+ usleep(svdm_hpd_deadline[port] - now);
+
+ /* Generate IRQ_HPD pulse */
+ gpio_set_level(hpd, 0);
+ usleep(HPD_DSTREAM_DEBOUNCE_IRQ);
+ gpio_set_level(hpd, 1);
+
+ /* Set the minimum time delay (2ms) for the next HPD IRQ */
+ svdm_hpd_deadline[port] = get_time().val +
+ HPD_USTREAM_DEBOUNCE_LVL;
+ } else if (irq & !lvl) {
+ CPRINTF("ERR:HPD:IRQ&LOW\n");
+ return 0;
+ } else {
+ gpio_set_level(hpd, lvl);
+ /* Set the minimum time delay (2ms) for the next HPD IRQ */
+ svdm_hpd_deadline[port] = get_time().val +
+ HPD_USTREAM_DEBOUNCE_LVL;
+ }
+
+ return 1;
+}
+
+__override void svdm_exit_dp_mode(int port)
+{
+ if (is_dp_muxable(port)) {
+ /* Disconnect the DP port selection mux. */
+ gpio_set_level(GPIO_DP_MUX_OE_L, 1);
+ gpio_set_level(GPIO_DP_MUX_SEL, 0);
+
+ /* Signal AP for the HPD low event */
+ usb_mux_hpd_update(port, 0, 0);
+ gpio_set_level(GPIO_DP_HOT_PLUG_DET, 0);
+ }
+}
+#endif /* CONFIG_USB_PD_ALT_MODE_DFP */
diff --git a/baseboard/herobrine/usbc_config.c b/baseboard/herobrine/usbc_config.c
new file mode 100644
index 0000000000..5e613c40a5
--- /dev/null
+++ b/baseboard/herobrine/usbc_config.c
@@ -0,0 +1,60 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Herobrine family-specific USB-C configuration */
+
+#include "charger.h"
+#include "charger/isl923x_public.h"
+#include "charge_state.h"
+#include "usb_pd.h"
+
+#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)
+
+const struct charger_config_t chg_chips[] = {
+ {
+ .i2c_port = I2C_PORT_CHARGER,
+ .i2c_addr_flags = ISL923X_ADDR_FLAGS,
+ .drv = &isl923x_drv,
+ },
+};
+
+int charger_profile_override(struct charge_state_data *curr)
+{
+ int usb_mv;
+ int port;
+
+ if (curr->state != ST_CHARGE)
+ return 0;
+
+ /* Lower the max requested voltage to 5V when battery is full. */
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF) &&
+ !(curr->batt.flags & BATT_FLAG_BAD_STATUS) &&
+ !(curr->batt.flags & BATT_FLAG_WANT_CHARGE) &&
+ (curr->batt.status & STATUS_FULLY_CHARGED))
+ usb_mv = 5000;
+ else
+ usb_mv = PD_MAX_VOLTAGE_MV;
+
+ if (pd_get_max_voltage() != usb_mv) {
+ CPRINTS("VBUS limited to %dmV", usb_mv);
+ for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++)
+ pd_set_external_voltage_limit(port, usb_mv);
+ }
+
+ return 0;
+}
+
+enum ec_status charger_profile_override_get_param(uint32_t param,
+ uint32_t *value)
+{
+ return EC_RES_INVALID_PARAM;
+}
+
+enum ec_status charger_profile_override_set_param(uint32_t param,
+ uint32_t value)
+{
+ return EC_RES_INVALID_PARAM;
+}