summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Hurst <shurst@google.com>2020-05-27 20:26:13 -0700
committerCommit Bot <commit-bot@chromium.org>2020-07-31 20:53:51 +0000
commit9db6959eed78c8262649695856c19bfb228c4a00 (patch)
treeeea6f320214d1a1cb85dbd17b569e0622555189b
parenta4ad4b40ad26eb9bed5dcdaeb71c707fbd3d3e37 (diff)
downloadchrome-ec-9db6959eed78c8262649695856c19bfb228c4a00.tar.gz
servo_v4p1: Add IO Expander functionality and board setup code
The IO Expander and board setup functionality are available in RW and RO BRANCH=none BUG=b:146793000 TEST=make -j buildall Signed-off-by: Sam Hurst <shurst@google.com> Change-Id: Ic740169607bd1f97be5145caef08715050ece1ad Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2219119 Reviewed-by: Wai-Hong Tam <waihong@google.com> (cherry picked from commit 8a834c60790e232db196032eec905f56032c5515) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2332238
-rw-r--r--board/servo_v4p1/board.c105
-rw-r--r--board/servo_v4p1/board.h76
-rw-r--r--board/servo_v4p1/build.mk4
-rw-r--r--board/servo_v4p1/ioexpanders.c270
-rw-r--r--board/servo_v4p1/ioexpanders.h292
-rw-r--r--board/servo_v4p1/ro_files.c7
6 files changed, 753 insertions, 1 deletions
diff --git a/board/servo_v4p1/board.c b/board/servo_v4p1/board.c
index 0ace86b3d3..bffa5a6436 100644
--- a/board/servo_v4p1/board.c
+++ b/board/servo_v4p1/board.c
@@ -12,6 +12,7 @@
#include "gpio.h"
#include "hooks.h"
#include "i2c.h"
+#include "ioexpanders.h"
#include "queue_policies.h"
#include "registers.h"
#include "spi.h"
@@ -24,6 +25,7 @@
#include "usart_rx_dma.h"
#include "usb_gpio.h"
#include "usb_i2c.h"
+#include "usb_pd.h"
#include "usb_spi.h"
#include "usb-stream.h"
#include "util.h"
@@ -48,22 +50,70 @@ static void vbus1_evt(enum gpio_signal signal)
static void tca_evt(enum gpio_signal signal)
{
+ uint8_t fault;
+
+ fault = read_faults();
+
+ if (!(fault & USERVO_FAULT_L))
+ ccprintf("FAULT: Microservo USB A port load switch\n");
+
+ if (!(fault & USB3_A0_FAULT_L))
+ ccprintf("FAULT: USB3 A0 port load switch\n");
+
+ if (!(fault & USB3_A1_FAULT_L))
+ ccprintf("FAULT: USB3 A1 port load switch\n");
+
+ if (!(fault & USB_DUTCHG_FLT_ODL))
+ ccprintf("FAULT: Overcurrent on Charger or DUB CC/SBU lines\n");
+
+ if (!(fault & PP3300_DP_FAULT_L))
+ ccprintf("FAULT: Overcurrent on DisplayPort\n");
+
+ if (!(fault & DAC_BUF1_LATCH_FAULT_L)) {
+ ccprintf("FAULT: CC1 drive circuitry has exceeded thermal ");
+ ccprintf("limits or exceeded current limits. Power ");
+ ccprintf("off DAC0 to clear the fault\n");
+ }
+
+ if (!(fault & DAC_BUF1_LATCH_FAULT_L)) {
+ ccprintf("FAULT: CC2 drive circuitry has exceeded thermal ");
+ ccprintf("limits or exceeded current limits. Power ");
+ ccprintf("off DAC1 to clear the fault\n");
+ }
}
static void dp_evt(enum gpio_signal signal)
{
+ ccprintf("DP detected\n");
}
static void tcpc_evt(enum gpio_signal signal)
{
+ ccprintf("tcpc event\n");
}
static void hub_evt(enum gpio_signal signal)
{
+ ccprintf("hub event\n");
}
static void bc12_evt(enum gpio_signal signal)
{
+ ccprintf("bc12_evt\n");
+}
+
+/* Enable uservo USB. */
+static void init_uservo_port(void)
+{
+ /* Enable USERVO_POWER_EN */
+ uservo_power_en(1);
+ /* Connect uservo to host hub */
+ uservo_fastboot_mux_sel(0);
+}
+#else
+void pd_task(void *u)
+{
+ /* DO NOTHING */
}
#endif /* SECTION_IS_RO */
@@ -234,7 +284,7 @@ int usb_i2c_board_is_enabled(void) { return 1; }
int board_get_version(void)
{
- return 0;
+ return board_id_det();
}
static void board_init(void)
@@ -248,5 +298,58 @@ static void board_init(void)
/* UART init */
usart_init(&usart3);
usart_init(&usart4);
+
+ /* Delay DUT hub to avoid brownout. */
+ usleep(MSEC);
+
+ init_ioexpanders();
+
+ /* Clear BBRAM, we don't want any PD state carried over on reset. */
+ system_set_bbram(SYSTEM_BBRAM_IDX_PD0, 0);
+ system_set_bbram(SYSTEM_BBRAM_IDX_PD1, 0);
+
+ /* Bring atmel part out of reset */
+ atmel_reset_l(1);
+
+#ifdef SECTION_IS_RO
+ init_uservo_port();
+
+ /* Enable DUT USB2.0 pair. */
+ gpio_set_level(GPIO_FASTBOOT_DUTHUB_MUX_EN_L, 0);
+
+ /* Enable VBUS detection to wake PD tasks fast enough */
+ gpio_enable_interrupt(GPIO_USB_DET_PP_CHG);
+ gpio_enable_interrupt(GPIO_USB_DET_PP_DUT);
+
+ gpio_enable_interrupt(GPIO_STM_FAULT_IRQ_L);
+ gpio_enable_interrupt(GPIO_DP_HPD);
+ gpio_enable_interrupt(GPIO_CHGSRV_TCPC_INT_ODL);
+ gpio_enable_interrupt(GPIO_USBH_I2C_BUSY_INT);
+ gpio_enable_interrupt(GPIO_BC12_INT_ODL);
+
+#endif /* SECTION_IS_RO */
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
+
+#ifdef SECTION_IS_RO
+void tick_event(void)
+{
+ static int i = 0;
+
+ i++;
+ switch (i) {
+ case 1:
+ tca_gpio_dbg_led_k_odl(1);
+ break;
+ case 2:
+ break;
+ case 3:
+ tca_gpio_dbg_led_k_odl(0);
+ break;
+ case 4:
+ i = 0;
+ break;
+ }
+}
+DECLARE_HOOK(HOOK_TICK, tick_event, HOOK_PRIO_DEFAULT);
+#endif /* SECTION_IS_RO */
diff --git a/board/servo_v4p1/board.h b/board/servo_v4p1/board.h
index 17d8f6a7cd..8f7b517695 100644
--- a/board/servo_v4p1/board.h
+++ b/board/servo_v4p1/board.h
@@ -16,6 +16,15 @@
/* 48 MHz SYSCLK clock frequency */
#define CPU_CLOCK 48000000
+/* Servo V4.1 Ports:
+ * CHG - port 0
+ * DUT - port 1
+ * ALT - port 2
+ */
+#define CHG 0
+#define DUT 1
+#define ALT 2
+
/*
* Flash layout: we redefine the sections offsets and sizes as we want to
* include a pstate region, and will use RO/RW regions of different sizes.
@@ -162,7 +171,26 @@
* can't be processed in time and can't support USB PD messaging.
*/
#undef CONFIG_TASK_PROFILING
+
+#define CONFIG_USB_PD_PORT_MAX_COUNT 2
+
+#ifdef SECTION_IS_RO
+/*
+ * TODO(crosbug.com/p/60792): The delay values are currently just place holders
+ * and the delay will need to be relative to the circuitry that allows VBUS to
+ * be supplied to the DUT port from the CHG port.
+ */
+#define PD_POWER_SUPPLY_TURN_ON_DELAY 50000 /* us */
+#define PD_POWER_SUPPLY_TURN_OFF_DELAY 50000 /* us */
+
+/* Define typical operating power and max power */
+#define PD_OPERATING_POWER_MW 15000
+#define PD_MAX_POWER_MW 60000
+#define PD_MAX_CURRENT_MA 3000
+#define PD_MAX_VOLTAGE_MV 20000
+#else
#undef CONFIG_USB_POWER_DELIVERY
+#endif /* SECTION_IS_RO */
/*
* If task profiling is enabled then the rx falling edge detection interrupts
@@ -215,10 +243,58 @@ enum adc_channel {
};
/**
+ * Compare cc_voltage to disconnect threshold
+ *
+ * This function can be used for boards that support variable Rp settings and
+ * require a different voltage threshold based on the Rp value attached to a
+ * given cc line.
+ *
+ * @param port USB-C port number
+ * @param cc_volt voltage measured in mV of the CC line
+ * @param cc_sel cc1 or cc2 selection
+ * @return 1 if voltage is >= threshold value for disconnect
+ */
+int pd_tcpc_cc_nc(int port, int cc_volt, int cc_sel);
+
+/**
+ * Compare cc_voltage to Ra threshold
+ *
+ * This function can be used for boards that support variable Rp settings and
+ * require a different voltage threshold based on the Rp value attached to a
+ * given cc line.
+ *
+ * @param port USB-C port number
+ * @param cc_volt voltage measured in mV of the CC line
+ * @param cc_sel cc1 or cc2 selection
+ * @return 1 if voltage is < threshold value for Ra attach
+ */
+int pd_tcpc_cc_ra(int port, int cc_volt, int cc_sel);
+
+/**
+ * Set Rp or Rd resistor for CC lines
+ *
+ * This function is used to configure the CC pullup or pulldown resistor to
+ * the requested value.
+ *
+ * @param port USB-C port number
+ * @param cc_pull 1 for Rp and 0 for Rd
+ * @param rp_value If cc_pull == 1, the value of Rp to use
+ * @return 1 if cc_pull == 1 and Rp is invalid, otherwise 0
+ */
+int pd_set_rp_rd(int port, int cc_pull, int rp_value);
+
+/**
* Get board HW ID version
*
* @return HW ID version
*/
int board_get_version(void);
+
+/**
+ * Enable or disable CCD
+ *
+ * @param enable Enable CCD if true, otherwise disable
+ */
+void ccd_enable(int enable);
#endif /* !__ASSEMBLER__ */
#endif /* __CROS_EC_BOARD_H */
diff --git a/board/servo_v4p1/build.mk b/board/servo_v4p1/build.mk
index f08de907e1..a54fdbf506 100644
--- a/board/servo_v4p1/build.mk
+++ b/board/servo_v4p1/build.mk
@@ -15,5 +15,9 @@ test-list-y=
# These files are compiled into RO and RW
board-y=board.o tca6416a.o tca6424a.o
+board-y+=ioexpanders.o
+
+# These files are compiled into RO only
+board-y+=ro_files.o
all_deps=$(patsubst ro,,$(def_all_deps))
diff --git a/board/servo_v4p1/ioexpanders.c b/board/servo_v4p1/ioexpanders.c
new file mode 100644
index 0000000000..ac0f616b8a
--- /dev/null
+++ b/board/servo_v4p1/ioexpanders.c
@@ -0,0 +1,270 @@
+/* Copyright 2020 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 "i2c.h"
+#include "ioexpanders.h"
+#include "tca6416a.h"
+#include "tca6424a.h"
+
+/******************************************************************************
+ * Initialize IOExpanders.
+ */
+
+static int dut_chg_en_state;
+
+/* Enable all ioexpander outputs. */
+int init_ioexpanders(void)
+{
+ int ret;
+
+ /*
+ * Init TCA6416A, PORT 0
+ * NAME | DIR | Initial setting
+ * -------------------------------------------------
+ * BIT-0 (SBU_UART_SEL) | O | 0
+ * BIT-1 (ATMEL_RESET_L) | O | 0
+ * BIT-2 (SBU_FLIP_SEL) | O | 1
+ * BIT-3 (USB3_A0_MUX_SEL) | O | 0
+ * BIT-4 (USB3_A0_MUX_EN_L) | O | 0
+ * BIT-5 (USB3_A0_PWR_EN) | O | 0
+ * BIT-6 (UART_18_SEL) | O | 0
+ * BIT-7 (USERVO_POWER_EN) | O | 0
+ */
+ ret = tca6416a_write_byte(1, TCA6416A_OUT_PORT_0, 0x04);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ ret = tca6416a_write_byte(1, TCA6416A_DIR_PORT_0, 0x00);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ /*
+ * Init TCA6416A, PORT 1
+ * NAME | DIR | Initial setting
+ * -------------------------------------------------------
+ * BIT-0 (USERVO_FASTBOOT_MUX_SEL) | O | 0
+ * BIT-1 (USB3_A1_PWR_EN) | O | 0
+ * BIT-2 (USB3_A1_MUX_SEL) | O | 0
+ * BIT-3 (BOARD_ID) | I | x
+ * BIT-4 (BOARD ID) | I | x
+ * BIT-5 (BOARD_ID) | I | x
+ * BIT-6 (CMUX_EN) | O | 1
+ * BIT-7 (DONGLE_DET) | I | x
+ */
+ ret = tca6416a_write_byte(1, TCA6416A_OUT_PORT_1, 0x40);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ ret = tca6416a_write_byte(1, TCA6416A_DIR_PORT_1, 0xb8);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ /*
+ * Init TCA6424A, PORT 0
+ * NAME | DIR | Initial setting
+ * -------------------------------------------------
+ * BIT-0 (EN_PP5000_ALT_3P3) | O | 0
+ * BIT-1 (EN_PP3300_ETH) | O | 1
+ * BIT-2 (EN_PP3300_DP) | O | 0
+ * BIT-3 (FAULT_CLEAR_CC) | O | 0
+ * BIT-4 (EN_VOUT_BUF_CC1) | O | 0
+ * BIT-5 (EN_VOUT_BUF_CC2) | O | 0
+ * BIT-6 (DUT_CHG_EN) | O | 0
+ * BIT-7 (HOST_OR_CHG_CTL | O | 0
+ */
+ ret = tca6424a_write_byte(1, TCA6424A_OUT_PORT_0, 0x02);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ ret = tca6424a_write_byte(1, TCA6424A_DIR_PORT_0, 0x00);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ /*
+ * Init TCA6424A, PORT 1
+ * NAME | DIR | Initial setting
+ * ------------------------------------------------------
+ * BIT-0 (USERVO_FAULT_L) | I | x
+ * BIT-1 (USB3_A0_FAULT_L) | I | x
+ * BIT-2 (USB3_A1_FAULT_L) | I | x
+ * BIT-3 (USB_DUTCHG_FLT_ODL) | I | x
+ * BIT-4 (PP3300_DP_FAULT_L) | I | x
+ * BIT-5 (DAC_BUF1_LATCH_FAULT_L) | I | x
+ * BIT-6 (DAC_BUF2_LATCH_FAULT_L) | I | x
+ * BIT-7 (PP5000_SRC_SEL) | I | x
+ */
+ ret = tca6424a_write_byte(1, TCA6424A_DIR_PORT_1, 0xff);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ /*
+ * Init TCA6424A, PORT 2
+ * NAME | DIR | Initial setting
+ * ------------------------------------------------
+ * BIT-0 (VBUS_DISCHRG_EN) | O | 0
+ * BIT-1 (USBH_PWRDN_L) | O | 1
+ * BIT-2 (UNUSED) | I | x
+ * BIT-3 (UNUSED) | I | x
+ * BIT-4 (UNUSED) | I | x
+ * BIT-5 (UNUSED) | I | x
+ * BIT-6 (UNUSED) | I | x
+ * BIT-7 (DBG_LED_K_ODL) | O | 0
+ */
+ ret = tca6424a_write_byte(1, TCA6424A_OUT_PORT_2, 0x02);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ ret = tca6424a_write_byte(1, TCA6424A_DIR_PORT_2, 0x7c);
+ if (ret != EC_SUCCESS)
+ return ret;
+
+ /* Clear any faults */
+ read_faults();
+
+ return EC_SUCCESS;
+}
+
+inline int sbu_uart_sel(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 0, en);
+}
+
+inline int atmel_reset_l(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 1, en);
+}
+
+inline int sbu_flip_sel(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 2, en);
+}
+
+inline int usb3_a0_mux_sel(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 3, en);
+}
+
+inline int usb3_a0_mux_en_l(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 4, en);
+}
+
+inline int usb3_a0_pwr_en(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 5, en);
+}
+
+inline int uart_18_sel(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 6, en);
+}
+
+inline int uservo_power_en(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 7, en);
+}
+
+inline int uservo_fastboot_mux_sel(enum uservo_fastboot_mux_sel_t sel)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_1, 0, sel);
+}
+
+inline int usb3_a1_pwr_en(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_1, 1, en);
+}
+
+inline int usb3_a1_mux_sel(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_1, 2, en);
+}
+
+inline int board_id_det(void)
+{
+ int id;
+
+ id = tca6416a_read_byte(1, TCA6416A_IN_PORT_1);
+ if (id < 0)
+ return id;
+
+ /* Board ID consists of bits 5, 4, and 3 */
+ return (id >> 3) & 0x7;
+}
+
+inline int cmux_en(int en)
+{
+ return tca6416a_write_bit(1, TCA6416A_OUT_PORT_1, 6, en);
+}
+
+inline int dongle_det(void)
+{
+ return tca6416a_read_bit(1, TCA6416A_IN_PORT_1, 7);
+}
+
+inline int en_pp5000_alt_3p3(int en)
+{
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 0, en);
+}
+
+inline int en_pp3300_eth(int en)
+{
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 1, en);
+}
+
+inline int en_pp3300_dp(int en)
+{
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 2, en);
+}
+
+inline int fault_clear_cc(int en)
+{
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 3, en);
+}
+
+inline int en_vout_buf_cc1(int en)
+{
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 4, en);
+}
+
+inline int en_vout_buf_cc2(int en)
+{
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 5, en);
+}
+
+int dut_chg_en(int en)
+{
+ dut_chg_en_state = en;
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 6, en);
+}
+
+int get_dut_chg_en(void)
+{
+ return dut_chg_en_state;
+}
+
+inline int host_or_chg_ctl(int en)
+{
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 7, en);
+}
+
+inline int read_faults(void)
+{
+ return tca6424a_read_byte(1, TCA6424A_IN_PORT_1);
+}
+
+inline int vbus_dischrg_en(int en)
+{
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_2, 0, en);
+}
+
+inline int usbh_pwrdn_l(int en)
+{
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_2, 1, en);
+}
+
+inline int tca_gpio_dbg_led_k_odl(int en)
+{
+ return tca6424a_write_bit(1, TCA6424A_OUT_PORT_2, 7, !en);
+}
diff --git a/board/servo_v4p1/ioexpanders.h b/board/servo_v4p1/ioexpanders.h
new file mode 100644
index 0000000000..7d96448e2f
--- /dev/null
+++ b/board/servo_v4p1/ioexpanders.h
@@ -0,0 +1,292 @@
+/* Copyright 2020 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __CROS_EC_IOEXPANDERS_H
+#define __CROS_EC_IOEXPANDERS_H
+
+enum uservo_fastboot_mux_sel_t {
+ MUX_SEL_USERVO = 0,
+ MUX_SEL_FASTBOOT = 1
+};
+
+/*
+ * Initialize Ioexpanders
+ */
+int init_ioexpanders(void);
+
+/**
+ * SBU Crosspoint select
+ *
+ * @param en 0 - HOST SBU to DUT SBU connected
+ * 1 - STM UART to DUT SBU connected
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int sbu_uart_sel(int en);
+
+/**
+ * Host KBC Controller reset
+ *
+ * @param en 0 - Assert reset
+ * 1 - Deassert reset
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int atmel_reset_l(int en);
+
+/**
+ * SBU Crosspoint polarity flip for DTU SBU to STM USART/Host SBU
+ *
+ * @param en 0 - Retain polarity (no inversion)
+ * 1 - Swap P for N polarity
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int sbu_flip_sel(int en);
+
+/**
+ * USB data path for general USB type A port
+ *
+ * @param en 0 - Host hub
+ * 1 - DUT hub
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int usb3_a0_mux_sel(int en);
+
+/**
+ * USB data path enable for general USB type A port, first on J2
+ *
+ * @param en 0 - Data connected / enabled
+ * 1 - Data disconnected
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int usb3_a0_mux_en_l(int en);
+
+/**
+ * Controls load switches for 5V to general USB type A
+ *
+ * @param en 0 - Disable power
+ * 1 - Enable power
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int usb3_a0_pwr_en(int en);
+
+/**
+ * Controls logic to select 1.8V or 3.3V UART from STM to DUT on SBU lines
+ *
+ * @param en 0 - 3.3V level
+ * 1 - 1.8V level
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int uart_18_sel(int en);
+
+/**
+ * Controls load switches for 5V to uservo USB type A port
+ *
+ * @param en 0 - Disable power
+ * 1 - Enable power
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int uservo_power_en(int en);
+
+/**
+ * USB data path enable from host hub to downstream userv or DUT peripheral
+ *
+ * @param sel MUX_SEL_USERVO - hub connected to uservo
+ * MUX_SEL_FASTBOOT - hub connected to DUT
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int uservo_fastboot_mux_sel(enum uservo_fastboot_mux_sel_t sel);
+
+/**
+ * Controls load switches for 5V to general USB type A second port
+ *
+ * @param en 0 - power off
+ * 1 - power enabled
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int usb3_a1_pwr_en(int en);
+
+/**
+ * USB data path for general USB type A port, second on J2
+ *
+ * @param en 0 - Host hub
+ * 1 - DUT hub
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int usb3_a1_mux_sel(int en);
+
+/**
+ * Reads the 3-bit Servo V4.1 version ID
+ *
+ * @return version ID
+ */
+int board_id_det(void);
+
+/**
+ * USBC 4:6 redriver enable
+ *
+ * @param en 0 - TUSB1064 disabled
+ * 1 - TUSB1064 enabled
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int cmux_en(int en);
+
+/**
+ * Reads the TypeA/TypeC DUT cable assembly pigtail
+ *
+ * @return 0 - for TypeA
+ * 1 - for TypeC
+ */
+int dongle_det(void);
+
+/**
+ * Enable signal for supplemental power supply. This supply will support higher
+ * wattage servo needs. 10ms after enabling this bit, the server supply should
+ * switch over from the host supply and the higher wattage will be available
+ *
+ * @param en 0 - Alternate supply disabled
+ * 1 - Supply enabled
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int en_pp5000_alt_3p3(int en);
+
+/**
+ * Controls load switches for the RTL8153. By default, ethernet is enabled but
+ * power can be removed as a way to clear any bad conditions
+ *
+ * @param en 0 - disable power
+ * 1 - enable power
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int en_pp3300_eth(int en);
+
+/**
+ * Controls load switches that enables 3.3V supply on the Display Port
+ * connector. On by default
+ *
+ * @param en 0 - disable 3.3V to DP connector
+ * 1 - enable 3.3V to DP connector
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int en_pp3300_dp(int en);
+
+/**
+ * The rising edge of this signal clears the latched condition when thermal
+ * or overcurrent fault has occurred from both CC1 and CC2 channels. Note
+ * that if the CC drive circuitry continues to be overheated, it will reset
+ * the fault regardless of the FAULT_CLEAR_CC signal.
+ *
+ * @param en 0 to 1 transition - clear fault
+ * 1 to 0 transition, 0, or 1 - No change in fault
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int fault_clear_cc(int en);
+
+/**
+ * CC1 Drive circuitry enable
+ *
+ * @param en 0 - disable CC1 high output drive (normal CC Operation by STM)
+ * 1 - enable CC1 high drive output
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int en_vout_buf_cc1(int en);
+
+/**
+ * CC2 Drive circuitry enable
+ *
+ * @param en 0 - disable CC2 high output drive (normal CC Operation by STM)
+ * 1 - enable CC2 high drive output
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int en_vout_buf_cc2(int en);
+
+/**
+ * Controls load switches for servo to power DUT Vusb
+ *
+ * @param en 0 - disable power
+ * 1 - enable power
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int dut_chg_en(int en);
+
+/**
+ * Get state of DUT Vusb
+ *
+ * @return 0 - power is disabled
+ * 1 - power is enabled
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int get_dut_chg_en(void);
+
+/**
+ * Selects power source for DUT Vusb from servo
+ *
+ * @param en 0 - 5V
+ * 1 - charger Vbus
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int host_or_chg_ctl(int en);
+
+#define USERVO_FAULT_L BIT(0)
+#define USB3_A0_FAULT_L BIT(1)
+#define USB3_A1_FAULT_L BIT(2)
+#define USB_DUTCHG_FLT_ODL BIT(3)
+#define PP3300_DP_FAULT_L BIT(4)
+#define DAC_BUF1_LATCH_FAULT_L BIT(5)
+#define DAC_BUF2_LATCH_FAULT_L BIT(6)
+#define PP5000_SRC_SEL BIT(7)
+
+/**
+ * Read any faults that may have occurred. A fault has occurred if the
+ * corresponding bit is 0.
+ *
+ * BIT:
+ * 0 (USERVO_FAULT_L) - Fault for port microservo USB A load switch
+ * 1 (USB3_A0_FAULT_L) - Fault for general port USB A load switch
+ * 2 (USB3_A1_FAULT_L) - Fault for general port USB A load switch
+ * 3 (USB_DUTCHG_FLT_ODL) - Overcurrent fault on Charger or DUB CC/SBU lines
+ * 4 (PP3300_DP_FAULT_L) - Overcurrent fault on DisplayPort
+ * 5 (DAC_BUF1_LATCH_FAULT_L) - Fault to indicate CC drive circuitry has
+ * exceeded thermal limits or exceeded current
+ * limits; when faults occur, the driver is
+ * disabled and needs to be reset.
+ * 6 (DAC_BUF2_LATCH_FAULT_L) - Fault to indicate CC drive circuitry has
+ * exceeded thermal limits or exceeded current
+ * limits; when faults occur, the driver is
+ * disabled and needs to be reset.
+ * 7 (PP5000_SRC_SEL) - Used to monitor whether Host power or Servo Charger
+ * USBC is providing source to PP5000. This may flip
+ * sources upon fault and should be monitored.
+ * 0 - USBC Servo charger is source
+ * 1 - host cable is source
+ */
+int read_faults(void);
+
+/**
+ * Enables active discharge for USB DUT Charger
+ *
+ * @param en 0 - disable active discharge (default)
+ * 1 - enable active discharge circuitry
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int vbus_dischrg_en(int en);
+
+/**
+ * Enables Hub
+ *
+ * @param en 0 - place hub in suspend (low power state)
+ * 1 - enable hub activity (including i2c)
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int usbh_pwrdn_l(int en);
+
+/**
+ * Debug LED
+ *
+ * @param en 0 - LED is OFF
+ * 1 - LED is ON
+ * @return EC_SUCCESS or EC_xxx on error
+ */
+int tca_gpio_dbg_led_k_odl(int en);
+
+#endif /* __CROS_EC_IOEXPANDERS_H */
diff --git a/board/servo_v4p1/ro_files.c b/board/servo_v4p1/ro_files.c
new file mode 100644
index 0000000000..bef61ca8b9
--- /dev/null
+++ b/board/servo_v4p1/ro_files.c
@@ -0,0 +1,7 @@
+/* Copyright 2020 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.
+ */
+
+#ifdef SECTION_IS_RO
+#endif /* SECTION_IS_RO */