summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Barnaś <mb@semihalf.com>2021-01-19 18:58:11 +0100
committerCommit Bot <commit-bot@chromium.org>2021-02-23 19:12:37 +0000
commit25fa055c3ecd98c5d339cc4002054c584f99cb1b (patch)
tree1c2075387722a2a41f396da1b663e7639a4de337
parent9497502d59d5979d4a60abb58a67eda7a8051fa4 (diff)
downloadchrome-ec-25fa055c3ecd98c5d339cc4002054c584f99cb1b.tar.gz
servo_v4p1: improve I/O expander implementation
Remove servo_v4p1 custom ioex implementations for TCA64xxA modules. Enable I/O expander module and move from custom interface to generic one. Due to the lack of flash in RW section, IOEX is not available there and required 'board_id_det' function is stubbed using raw i2c functions. This results in IOEX and DAC functions available only in RO section, so their initialization functions are moved to RO-only init. BUG=b:168385201 BRANCH=main TEST=Connect to servo's console and execute 'ioexget' command. All IOEX pins' states should be printed in terminal. Pin TCA_GPIO_DBG_LED_K_ODL should change as LED is blinking. TEST=Connect to servo's console. Plug USB-C charger to servo power port. 'ioexget' command should display EN_PP5000_ALT_3P3 value as 1. Execute 'ioexset EN_PP5000_ALT_3P3 0' command. Unplug fast the servo charger. Servo should be fully operational without any sign of reboot. Signed-off-by: Michał Barnaś <mb@semihalf.com> Change-Id: Iff98b37746a95d6a59954507ab18defac65d6329 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2700297 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r--board/servo_v4p1/board.c38
-rw-r--r--board/servo_v4p1/board.h16
-rw-r--r--board/servo_v4p1/build.mk2
-rw-r--r--board/servo_v4p1/dacs.c2
-rw-r--r--board/servo_v4p1/gpio.inc47
-rw-r--r--board/servo_v4p1/ioexpanders.c233
-rw-r--r--board/servo_v4p1/ioexpanders.h4
-rw-r--r--board/servo_v4p1/tca6416a.c63
-rw-r--r--board/servo_v4p1/tca6416a.h66
-rw-r--r--board/servo_v4p1/tca6424a.c63
-rw-r--r--board/servo_v4p1/tca6424a.h69
11 files changed, 190 insertions, 413 deletions
diff --git a/board/servo_v4p1/board.c b/board/servo_v4p1/board.c
index 79a8a20fe6..7d92c603c8 100644
--- a/board/servo_v4p1/board.c
+++ b/board/servo_v4p1/board.c
@@ -12,6 +12,7 @@
#include "console.h"
#include "dacs.h"
#include <driver/gl3590.h>
+#include "driver/ioexpander/tca64xxa.h"
#include "ec_version.h"
#include "fusb302b.h"
#include "gpio.h"
@@ -425,24 +426,25 @@ static void board_init(void)
/* Delay DUT hub to avoid brownout. */
usleep(MSEC);
- init_ioexpanders();
- CPRINTS("Board ID is %d", board_id_det());
-
- vbus_dischrg_en(0);
-
- init_dacs();
init_pi3usb9201();
/* 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_ioexpanders();
+ CPRINTS("Board ID is %d", board_id_det());
+
+ init_dacs();
+ init_uservo_port();
+ init_pathsel();
init_ina231s();
init_fusb302b(1);
+ vbus_dischrg_en(0);
+
+ /* Bring atmel part out of reset */
+ atmel_reset_l(1);
/*
* Get data about available input power. Defer this check, since we need
@@ -474,6 +476,8 @@ static void board_init(void)
/* Start SuzyQ detection */
start_ccd_meas_sbu_cycle();
+#else /* SECTION_IS_RO */
+ CPRINTS("Board ID is %d", board_id_det());
#endif /* SECTION_IS_RO */
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
@@ -499,4 +503,20 @@ void tick_event(void)
}
}
DECLARE_HOOK(HOOK_TICK, tick_event, HOOK_PRIO_DEFAULT);
+
+struct ioexpander_config_t ioex_config[] = {
+ [0] = {
+ .drv = &tca64xxa_ioexpander_drv,
+ .i2c_host_port = TCA6416A_PORT,
+ .i2c_slave_addr = TCA6416A_ADDR,
+ .flags = TCA64XXA_FLAG_VER_TCA6416A
+ },
+ [1] = {
+ .drv = &tca64xxa_ioexpander_drv,
+ .i2c_host_port = TCA6424A_PORT,
+ .i2c_slave_addr = TCA6424A_ADDR,
+ .flags = TCA64XXA_FLAG_VER_TCA6424A
+ }
+};
+
#endif /* SECTION_IS_RO */
diff --git a/board/servo_v4p1/board.h b/board/servo_v4p1/board.h
index 98a5fcc6a1..273014f15b 100644
--- a/board/servo_v4p1/board.h
+++ b/board/servo_v4p1/board.h
@@ -24,6 +24,14 @@
#define DUT 1
/*
+ * IO expanders I2C addresses and ports
+ */
+#define TCA6416A_PORT 1
+#define TCA6416A_ADDR 0x21
+#define TCA6424A_PORT 1
+#define TCA6424A_ADDR 0x23
+
+/*
* 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.
* RO has size 92K and usb_updater along with the majority of code is placed
@@ -140,6 +148,14 @@
/* Enable console recasting of GPIO type. */
#define CONFIG_CMD_GPIO_EXTENDED
+/* Enable I/O expander */
+#ifdef SECTION_IS_RO
+#define CONFIG_IO_EXPANDER
+#define CONFIG_IO_EXPANDER_SUPPORT_GET_PORT
+#define CONFIG_IO_EXPANDER_TCA64XXA
+#define CONFIG_IO_EXPANDER_PORT_COUNT 2
+#endif
+
/* This is not actually an EC so disable some features. */
#undef CONFIG_WATCHDOG_HELP
#undef CONFIG_LID_SWITCH
diff --git a/board/servo_v4p1/build.mk b/board/servo_v4p1/build.mk
index 3433b808cd..872b4d4281 100644
--- a/board/servo_v4p1/build.mk
+++ b/board/servo_v4p1/build.mk
@@ -14,7 +14,7 @@ CHIP_VARIANT:=stm32f07x
test-list-y=
# These files are compiled into RO and RW
-board-y=board.o tca6416a.o tca6424a.o
+board-y=board.o
board-y+=ioexpanders.o
board-y+=dacs.o
board-y+=pi3usb9201.o
diff --git a/board/servo_v4p1/dacs.c b/board/servo_v4p1/dacs.c
index b5c62bb438..d042836a2b 100644
--- a/board/servo_v4p1/dacs.c
+++ b/board/servo_v4p1/dacs.c
@@ -101,6 +101,7 @@ int write_dac(enum dac_t dac, uint16_t value)
return EC_SUCCESS;
}
+#ifdef SECION_IS_RO
static int cmd_cc_dac(int argc, char *argv[])
{
uint8_t dac;
@@ -136,3 +137,4 @@ static int cmd_cc_dac(int argc, char *argv[])
DECLARE_CONSOLE_COMMAND(cc_dac, cmd_cc_dac,
"dac <\"on\"|\"off\"|mv>",
"Set Servo v4.1 CC dacs");
+#endif
diff --git a/board/servo_v4p1/gpio.inc b/board/servo_v4p1/gpio.inc
index 52a689c03f..070aa90098 100644
--- a/board/servo_v4p1/gpio.inc
+++ b/board/servo_v4p1/gpio.inc
@@ -65,6 +65,53 @@ GPIO(USB_DUT_TX_CLKIN, PIN(B, 13), GPIO_INPUT)
GPIO(MASTER_I2C_SCL, PIN(B, 10), GPIO_INPUT)
GPIO(MASTER_I2C_SDA, PIN(B, 11), GPIO_INPUT)
+/* IOEX */
+#ifdef SECTION_IS_RO
+
+IOEX(SBU_UART_SEL, EXPIN(0, 0, 0), GPIO_OUT_LOW)
+IOEX(ATMEL_RESET_L, EXPIN(0, 0, 1), GPIO_OUT_LOW)
+IOEX(SBU_FLIP_SEL, EXPIN(0, 0, 2), GPIO_OUT_HIGH)
+IOEX(USB3_A0_MUX_SEL, EXPIN(0, 0, 3), GPIO_OUT_HIGH)
+IOEX(USB3_A0_MUX_EN_L, EXPIN(0, 0, 4), GPIO_OUT_LOW)
+IOEX(USB3_A0_PWR_EN, EXPIN(0, 0, 5), GPIO_OUT_LOW)
+IOEX(UART_18_SEL, EXPIN(0, 0, 6), GPIO_OUT_LOW)
+IOEX(USERVO_POWER_EN, EXPIN(0, 0, 7), GPIO_OUT_LOW)
+IOEX(USERVO_FASTBOOT_MUX_SEL, EXPIN(0, 1, 0), GPIO_OUT_LOW)
+IOEX(USB3_A1_PWR_EN, EXPIN(0, 1, 1), GPIO_OUT_LOW)
+IOEX(USB3_A1_MUX_SEL, EXPIN(0, 1, 2), GPIO_OUT_HIGH)
+IOEX(BOARD_ID_DET0, EXPIN(0, 1, 3), GPIO_INPUT)
+IOEX(BOARD_ID_DET1, EXPIN(0, 1, 4), GPIO_INPUT)
+IOEX(BOARD_ID_DET2, EXPIN(0, 1, 5), GPIO_INPUT)
+IOEX(VBUS_DISCHRG_EN, EXPIN(0, 1, 6), GPIO_OUT_LOW)
+IOEX(DONGLE_DET, EXPIN(0, 1, 7), GPIO_INPUT)
+
+IOEX(EN_PP5000_ALT_3P3, EXPIN(1, 0, 0), GPIO_OUT_LOW)
+IOEX(EN_PP3300_ETH, EXPIN(1, 0, 1), GPIO_OUT_HIGH)
+IOEX(EN_PP3300_DP, EXPIN(1, 0, 2), GPIO_OUT_HIGH)
+IOEX(FAULT_CLEAR_CC, EXPIN(1, 0, 3), GPIO_OUT_LOW)
+IOEX(EN_VOUT_BUF_CC1, EXPIN(1, 0, 4), GPIO_OUT_LOW)
+IOEX(EN_VOUT_BUF_CC2, EXPIN(1, 0, 5), GPIO_OUT_LOW)
+IOEX(DUT_CHG_EN, EXPIN(1, 0, 6), GPIO_OUT_LOW)
+IOEX(HOST_OR_CHG_CTL, EXPIN(1, 0, 7), GPIO_OUT_LOW)
+IOEX(USERVO_FAULT_L, EXPIN(1, 1, 0), GPIO_INPUT)
+IOEX(USB3_A0_FAULT_L, EXPIN(1, 1, 1), GPIO_INPUT)
+IOEX(USB3_A1_FAULT_L, EXPIN(1, 1, 2), GPIO_INPUT)
+IOEX(USB_DUTCHG_FLT_ODL, EXPIN(1, 1, 3), GPIO_INPUT)
+IOEX(PP3300_DP_FAULT_L, EXPIN(1, 1, 4), GPIO_INPUT)
+IOEX(DAC_BUF1_LATCH_FAULT_L, EXPIN(1, 1, 5), GPIO_INPUT)
+IOEX(DAC_BUF2_LATCH_FAULT_L, EXPIN(1, 1, 6), GPIO_INPUT)
+IOEX(PP5000_SRC_SEL, EXPIN(1, 1, 7), GPIO_INPUT)
+IOEX(HOST_CHRG_DET, EXPIN(1, 2, 0), GPIO_INPUT)
+IOEX(USBH_PWRDN_L, EXPIN(1, 2, 1), GPIO_OUT_HIGH)
+IOEX(ATMEL_SS, EXPIN(1, 2, 2), GPIO_INPUT)
+IOEX(ATMEL_SCLK, EXPIN(1, 2, 3), GPIO_INPUT)
+IOEX(ATMEL_MOSI, EXPIN(1, 2, 4), GPIO_INPUT)
+IOEX(ATMEL_MISO, EXPIN(1, 2, 5), GPIO_INPUT)
+IOEX(SYS_PWR_IRQ_ODL, EXPIN(1, 2, 6), GPIO_INPUT)
+IOEX(TCA_GPIO_DBG_LED_K_ODL, EXPIN(1, 2, 7), GPIO_OUT_LOW)
+
+#endif
+
/* Unimplemented signals since we are not an EC */
UNIMPLEMENTED(ENTERING_RW)
UNIMPLEMENTED(WP_L)
diff --git a/board/servo_v4p1/ioexpanders.c b/board/servo_v4p1/ioexpanders.c
index 6be5ed26ba..50690321fd 100644
--- a/board/servo_v4p1/ioexpanders.c
+++ b/board/servo_v4p1/ioexpanders.c
@@ -5,125 +5,23 @@
#include "hooks.h"
#include "i2c.h"
+#include "ioexpander.h"
#include "ioexpanders.h"
-#include "tca6416a.h"
-#include "tca6424a.h"
/******************************************************************************
* Initialize IOExpanders.
*/
+static enum servo_board_id board_id_val = BOARD_ID_UNSET;
+
+#ifdef SECTION_IS_RO
+
static int dut_chg_en_state;
static int bc12_charger;
-static enum servo_board_id board_id_val = BOARD_ID_UNSET;
-
/* 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 (VBUS_DISCHRG_EN) | O | 0
- * BIT-7 (DONGLE_DET) | I | x
- */
- ret = tca6416a_write_byte(1, TCA6416A_OUT_PORT_1, 0x0);
- 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 (HOST_CHRG_DET) | I | x
- * 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 (SYS_PWR_IRQ_ODL) | 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, 0x7d);
- if (ret != EC_SUCCESS)
- return ret;
-
/* Clear any faults and other IRQs*/
read_faults();
read_irqs();
@@ -133,7 +31,7 @@ int init_ioexpanders(void)
* notifies about event on both low and high levels, while notification
* should happen only when state has changed.
*/
- bc12_charger = get_host_chrg_det();
+ ioex_get_level(IOEX_HOST_CHRG_DET, &bc12_charger);
return EC_SUCCESS;
}
@@ -172,11 +70,11 @@ static void ioexpanders_irq(void)
ccprintf("off DAC1 to clear the fault\n");
}
- if (((irqs & HOST_CHRG_DET) != bc12_charger) &&
+ if ((!!(irqs & HOST_CHRG_DET) != bc12_charger) &&
(board_id_det() <= BOARD_ID_REV1)) {
ccprintf("BC1.2 charger %s\n", (irqs & HOST_CHRG_DET) ?
"plugged" : "unplugged");
- bc12_charger = irqs & HOST_CHRG_DET;
+ bc12_charger = !!(irqs & HOST_CHRG_DET);
}
if (!(irqs & SYS_PWR_IRQ_ODL))
@@ -192,118 +90,125 @@ int irq_ioexpanders(void)
inline int sbu_uart_sel(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 0, en);
+ return ioex_set_level(IOEX_SBU_UART_SEL, en);
}
inline int atmel_reset_l(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 1, en);
+ return ioex_set_level(IOEX_ATMEL_RESET_L, en);
}
inline int sbu_flip_sel(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 2, en);
+ return ioex_set_level(IOEX_SBU_FLIP_SEL, en);
}
inline int usb3_a0_mux_sel(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 3, en);
+ return ioex_set_level(IOEX_USB3_A0_MUX_SEL, en);
}
inline int usb3_a0_mux_en_l(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 4, en);
+ return ioex_set_level(IOEX_USB3_A0_MUX_EN_L, en);
}
inline int ec_usb3_a0_pwr_en(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 5, en);
+ return ioex_set_level(IOEX_USB3_A0_PWR_EN, en);
}
inline int uart_18_sel(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 6, en);
+ return ioex_set_level(IOEX_UART_18_SEL, en);
}
inline int ec_uservo_power_en(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_0, 7, en);
+ return ioex_set_level(IOEX_USERVO_POWER_EN, 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);
+ return ioex_set_level(IOEX_USERVO_FASTBOOT_MUX_SEL, (int)sel);
}
inline int ec_usb3_a1_pwr_en(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_1, 1, en);
+ return ioex_set_level(IOEX_USB3_A1_PWR_EN, en);
}
inline int usb3_a1_mux_sel(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_1, 2, en);
+ return ioex_set_level(IOEX_USB3_A1_MUX_SEL, en);
}
inline int board_id_det(void)
{
- int id;
if (board_id_val == BOARD_ID_UNSET) {
+ int id;
+
/* Cache board ID at init */
- id = tca6416a_read_byte(1, TCA6416A_IN_PORT_1);
- if (id < 0)
+ if (ioex_get_port(IOEX_GET_INFO(IOEX_BOARD_ID_DET0)->ioex,
+ IOEX_GET_INFO(IOEX_BOARD_ID_DET0)->port,
+ &id))
return id;
- board_id_val = id;
+
+ /* Board ID consists of bits 5, 4, and 3 */
+ board_id_val = (id >> BOARD_ID_DET_OFFSET) & BOARD_ID_DET_MASK;
}
- /* Board ID consists of bits 5, 4, and 3 */
- return (board_id_val >> 3) & 0x7;
+ return board_id_val;
}
inline int dongle_det(void)
{
- return tca6416a_read_bit(1, TCA6416A_IN_PORT_1, 7);
+ int val;
+ ioex_get_level(IOEX_DONGLE_DET, &val);
+ return val;
}
inline int get_host_chrg_det(void)
{
- return tca6424a_read_bit(1, TCA6424A_IN_PORT_2, 0);
+ int val;
+ ioex_get_level(IOEX_HOST_CHRG_DET, &val);
+ return val;
}
inline int en_pp5000_alt_3p3(int en)
{
- return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 0, en);
+ return ioex_set_level(IOEX_EN_PP5000_ALT_3P3, en);
}
inline int en_pp3300_eth(int en)
{
- return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 1, en);
+ return ioex_set_level(IOEX_EN_PP3300_ETH, en);
}
inline int en_pp3300_dp(int en)
{
- return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 2, en);
+ return ioex_set_level(IOEX_EN_PP3300_DP, en);
}
inline int fault_clear_cc(int en)
{
- return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 3, en);
+ return ioex_set_level(IOEX_FAULT_CLEAR_CC, en);
}
inline int en_vout_buf_cc1(int en)
{
- return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 4, en);
+ return ioex_set_level(IOEX_EN_VOUT_BUF_CC1, en);
}
inline int en_vout_buf_cc2(int en)
{
- return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 5, en);
+ return ioex_set_level(IOEX_EN_VOUT_BUF_CC2, en);
}
int dut_chg_en(int en)
{
dut_chg_en_state = en;
- return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 6, en);
+ return ioex_set_level(IOEX_DUT_CHG_EN, en);
}
int get_dut_chg_en(void)
@@ -313,30 +218,74 @@ int get_dut_chg_en(void)
inline int host_or_chg_ctl(int en)
{
- return tca6424a_write_bit(1, TCA6424A_OUT_PORT_0, 7, en);
+ return ioex_set_level(IOEX_HOST_OR_CHG_CTL, en);
}
inline int read_faults(void)
{
- return tca6424a_read_byte(1, TCA6424A_IN_PORT_1);
+ int val;
+
+ ioex_get_port(IOEX_GET_INFO(IOEX_USERVO_FAULT_L)->ioex,
+ IOEX_GET_INFO(IOEX_USERVO_FAULT_L)->port,
+ &val);
+
+ return val;
}
inline int read_irqs(void)
{
- return tca6424a_read_byte(1, TCA6424A_IN_PORT_2);
+ int val;
+
+ ioex_get_port(IOEX_GET_INFO(IOEX_SYS_PWR_IRQ_ODL)->ioex,
+ IOEX_GET_INFO(IOEX_SYS_PWR_IRQ_ODL)->port,
+ &val);
+
+ return val;
}
inline int vbus_dischrg_en(int en)
{
- return tca6416a_write_bit(1, TCA6416A_OUT_PORT_1, 6, en);
+ return ioex_set_level(IOEX_VBUS_DISCHRG_EN, en);
}
inline int usbh_pwrdn_l(int en)
{
- return tca6424a_write_bit(1, TCA6424A_OUT_PORT_2, 1, en);
+ return ioex_set_level(IOEX_USBH_PWRDN_L, en);
}
inline int tca_gpio_dbg_led_k_odl(int en)
{
- return tca6424a_write_bit(1, TCA6424A_OUT_PORT_2, 7, !en);
+ return ioex_set_level(IOEX_TCA_GPIO_DBG_LED_K_ODL, !en);
+}
+
+#else /* SECTION_IS_RO */
+
+/*
+ * Due to lack of flash in RW section, it is not possible to use IOEX subsystem
+ * in it. Instead, RO section uses IOEX, and RW implements only required
+ * function with raw i2c operation. This function is required by 'version'
+ * console command and should work without any special initialization.
+ */
+inline int board_id_det(void)
+{
+ if (board_id_val == BOARD_ID_UNSET) {
+ int id;
+ int res;
+
+ /* Cache board ID at init */
+ res = i2c_read8(TCA6416A_PORT,
+ TCA6416A_ADDR,
+ BOARD_ID_DET_PORT,
+ &id);
+ if (res != EC_SUCCESS)
+ return res;
+
+ /* Board ID consists of bits 5, 4, and 3 */
+ board_id_val = (id >> BOARD_ID_DET_OFFSET) & BOARD_ID_DET_MASK;
+ }
+
+ /* Board ID consists of bits 5, 4, and 3 */
+ return board_id_val;
}
+
+#endif /* SECTION_IS_RO */
diff --git a/board/servo_v4p1/ioexpanders.h b/board/servo_v4p1/ioexpanders.h
index e6b44a9d45..6565992857 100644
--- a/board/servo_v4p1/ioexpanders.h
+++ b/board/servo_v4p1/ioexpanders.h
@@ -6,6 +6,10 @@
#ifndef __CROS_EC_IOEXPANDERS_H
#define __CROS_EC_IOEXPANDERS_H
+#define BOARD_ID_DET_MASK 0x7
+#define BOARD_ID_DET_OFFSET 3
+#define BOARD_ID_DET_PORT 1
+
enum uservo_fastboot_mux_sel_t {
MUX_SEL_USERVO = 0,
MUX_SEL_FASTBOOT = 1
diff --git a/board/servo_v4p1/tca6416a.c b/board/servo_v4p1/tca6416a.c
deleted file mode 100644
index d776ad86fe..0000000000
--- a/board/servo_v4p1/tca6416a.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* 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 "tca6416a.h"
-
-int tca6416a_write_bit(int port, enum tca6416a_bank bank, uint8_t bit, int val)
-{
- int tmp;
- int ret;
-
- /* Read output port register */
- ret = i2c_read8(port, TCA6416A_ADDR_FLAGS, bank, &tmp);
- if (ret != EC_SUCCESS)
- return ret;
-
- if (val)
- tmp |= BIT(bit);
- else
- tmp &= ~BIT(bit);
-
- /* Write back modified output port register */
- ret = i2c_write8(port, TCA6416A_ADDR_FLAGS, bank, tmp);
- if (ret != EC_SUCCESS)
- return ret;
-
- return EC_SUCCESS;
-}
-
-int tca6416a_write_byte(int port, enum tca6416a_bank bank, uint8_t val)
-{
- int ret;
-
- ret = i2c_write8(port, TCA6416A_ADDR_FLAGS, bank, val);
- if (ret != EC_SUCCESS)
- return ret;
-
- return EC_SUCCESS;
-}
-
-int tca6416a_read_byte(int port, enum tca6416a_bank bank)
-{
- int tmp;
-
- if (i2c_read8(port, TCA6416A_ADDR_FLAGS, bank, &tmp) != EC_SUCCESS)
- return -1;
-
- return tmp;
-}
-
-int tca6416a_read_bit(int port, enum tca6416a_bank bank, uint8_t bit)
-{
- int tmp;
- int mask = 1 << bit;
-
- /* Read input port register */
- if (i2c_read8(port, TCA6416A_ADDR_FLAGS, bank, &tmp) != EC_SUCCESS)
- return -1;
-
- return (tmp & mask) >> bit;
-}
diff --git a/board/servo_v4p1/tca6416a.h b/board/servo_v4p1/tca6416a.h
deleted file mode 100644
index 5255059d99..0000000000
--- a/board/servo_v4p1/tca6416a.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* 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_IOEXPANDER_TCA6416A_H
-#define __CROS_EC_IOEXPANDER_TCA6416A_H
-
-#include <stdint.h>
-
-#define TCA6416A_ADDR_FLAGS 0x21
-
-enum tca6416a_bank {
- TCA6416A_IN_PORT_0 = 0x0,
- TCA6416A_IN_PORT_1 = 0x1,
- TCA6416A_OUT_PORT_0 = 0x2,
- TCA6416A_OUT_PORT_1 = 0x3,
- TCA6416A_DIR_PORT_0 = 0x6,
- TCA6416A_DIR_PORT_1 = 0x7,
-};
-
-/*
- * Set a bit in the supplied bank
- *
- * @param port The I2C port of TCA6416A.
- * @param bank The bank the bit belongs to.
- * @param bit The index of the bit to set.
- * @param val The value to set.
- *
- * @return EC_SUCCESS, or EC_ERROR_* on error.
- */
-int tca6416a_write_bit(int port,
- enum tca6416a_bank bank, uint8_t bit, int val);
-
-/*
- * Get a bit in the supplied bank
- *
- * @param port The I2C port of TCA6416A.
- * @param bank The bank the bit belongs to.
- * @param bit The index of the bit to get.
- *
- * @return bit value, or -1 on error.
- */
-int tca6416a_read_bit(int port, enum tca6416a_bank bank, uint8_t bit);
-
-/*
- * Write a byt to the supplied bank
- *
- * @param port The I2C port of TCA6416A.
- * @param bank The bank to write the byte to.
- *
- * @return EC_SUCCESS, or EC_ERROR_* on error.
- */
-int tca6416a_write_byte(int port, enum tca6416a_bank bank, uint8_t val);
-
-/*
- * Read a byte in the supplied bank
- *
- * @param port The I2C port of TCA6416A.
- * @param bank The bank to read byte from.
- *
- * @return byte value, or -1 on error.
- */
-int tca6416a_read_byte(int port, enum tca6416a_bank bank);
-
-#endif /* __CROS_EC_IOEXPANDER_TCA6416A_H */
diff --git a/board/servo_v4p1/tca6424a.c b/board/servo_v4p1/tca6424a.c
deleted file mode 100644
index 28c768b046..0000000000
--- a/board/servo_v4p1/tca6424a.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* 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 "tca6424a.h"
-
-int tca6424a_write_bit(int port, enum tca6424a_bank bank, uint8_t bit, int val)
-{
- int tmp;
- int ret;
-
- /* Read output port register */
- ret = i2c_read8(port, TCA6424A_ADDR_FLAGS, bank, &tmp);
- if (ret != EC_SUCCESS)
- return ret;
-
- if (val)
- tmp |= BIT(bit);
- else
- tmp &= ~BIT(bit);
-
- /* Write back modified output port register */
- ret = i2c_write8(port, TCA6424A_ADDR_FLAGS, bank, tmp);
- if (ret != EC_SUCCESS)
- return ret;
-
- return EC_SUCCESS;
-}
-
-int tca6424a_write_byte(int port, enum tca6424a_bank bank, uint8_t val)
-{
- int ret;
-
- ret = i2c_write8(port, TCA6424A_ADDR_FLAGS, bank, val);
- if (ret != EC_SUCCESS)
- return ret;
-
- return EC_SUCCESS;
-}
-
-int tca6424a_read_byte(int port, enum tca6424a_bank bank)
-{
- int tmp;
-
- if (i2c_read8(port, TCA6424A_ADDR_FLAGS, bank, &tmp) != EC_SUCCESS)
- return -1;
-
- return tmp;
-}
-
-int tca6424a_read_bit(int port, enum tca6424a_bank bank, uint8_t bit)
-{
- int tmp;
- int mask = 1 << bit;
-
- /* Read input port register */
- if (i2c_read8(port, TCA6424A_ADDR_FLAGS, bank, &tmp) != EC_SUCCESS)
- return -1;
-
- return (tmp & mask) >> bit;
-}
diff --git a/board/servo_v4p1/tca6424a.h b/board/servo_v4p1/tca6424a.h
deleted file mode 100644
index 80db7ebdba..0000000000
--- a/board/servo_v4p1/tca6424a.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* 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_IOEXPANDER_TCA6424A_H
-#define __CROS_EC_IOEXPANDER_TCA6424A_H
-
-#include <stdint.h>
-
-#define TCA6424A_ADDR_FLAGS 0x23
-
-enum tca6424a_bank {
- TCA6424A_IN_PORT_0 = 0x0,
- TCA6424A_IN_PORT_1 = 0x1,
- TCA6424A_IN_PORT_2 = 0x2,
- TCA6424A_OUT_PORT_0 = 0x4,
- TCA6424A_OUT_PORT_1 = 0x5,
- TCA6424A_OUT_PORT_2 = 0x6,
- TCA6424A_DIR_PORT_0 = 0xc,
- TCA6424A_DIR_PORT_1 = 0xd,
- TCA6424A_DIR_PORT_2 = 0xe,
-};
-
-/*
- * Set a bit in the supplied bank
- *
- * @param port The I2C port of TCA6424A.
- * @param bank The bank the bit belongs to.
- * @param bit The index of the bit to set.
- * @param val The value to set.
- *
- * @return EC_SUCCESS, or EC_ERROR_* on error.
- */
-int tca6424a_write_bit(int port,
- enum tca6424a_bank bank, uint8_t bit, int val);
-
-/*
- * Get a bit in the supplied bank
- *
- * @param port The I2C port of TCA6424A.
- * @param bank The bank the bit belongs to.
- * @param bit The index of the bit to get.
- *
- * @return bit value, or -1 on error.
- */
-int tca6424a_read_bit(int port, enum tca6424a_bank bank, uint8_t bit);
-
-/*
- * Write a byt to the supplied bank
- *
- * @param port The I2C port of TCA6424A.
- * @param bank The bank to write the byte to.
- *
- * @return EC_SUCCESS, or EC_ERROR_* on error.
- */
-int tca6424a_write_byte(int port, enum tca6424a_bank bank, uint8_t val);
-
-/*
- * Read a byte in the supplied bank
- *
- * @param port The I2C port of TCA6424A.
- * @param bank The bank to read byte from.
- *
- * @return byte value, or -1 on error.
- */
-int tca6424a_read_byte(int port, enum tca6424a_bank bank);
-
-#endif /* __CROS_EC_IOEXPANDER_TCA6424A_H */