diff options
Diffstat (limited to 'zephyr/projects/skyrim/usbc_config.c')
-rw-r--r-- | zephyr/projects/skyrim/usbc_config.c | 180 |
1 files changed, 46 insertions, 134 deletions
diff --git a/zephyr/projects/skyrim/usbc_config.c b/zephyr/projects/skyrim/usbc_config.c index 524bba5933..32a53d2772 100644 --- a/zephyr/projects/skyrim/usbc_config.c +++ b/zephyr/projects/skyrim/usbc_config.c @@ -8,6 +8,7 @@ #include <drivers/gpio.h> #include "cros_board_info.h" +#include "cros_cbi.h" #include "battery_fuel_gauge.h" #include "charge_manager.h" #include "charge_ramp.h" @@ -18,11 +19,10 @@ #include "driver/charger/isl9241.h" #include "driver/ppc/aoz1380.h" #include "driver/ppc/nx20p348x.h" -#include "driver/retimer/anx7491.h" +#include "driver/retimer/anx7483_public.h" #include "driver/retimer/ps8811.h" #include "driver/retimer/ps8818.h" #include "driver/tcpm/nct38xx.h" -#include "driver/usb_mux/anx7451.h" #include "driver/usb_mux/amd_fp6.h" #include "gpio/gpio_int.h" #include "hooks.h" @@ -121,18 +121,23 @@ unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); * not needed as well. usb_mux.c can handle the situation * properly. */ -static int fsusb42umx_set_mux(const struct usb_mux*, mux_state_t, bool *); -struct usb_mux_driver usbc0_sbu_mux_driver = { - .set = fsusb42umx_set_mux, +static int ioex_set_flip(const struct usb_mux*, mux_state_t, bool *); +struct usb_mux_driver ioex_sbu_mux_driver = { + .set = ioex_set_flip, }; /* - * Since FSUSB42UMX is not a i2c device, .i2c_port and + * Since NX3DV221GM is not a i2c device, .i2c_port and * .i2c_addr_flags are not required here. */ struct usb_mux usbc0_sbu_mux = { .usb_port = USBC_PORT_C0, - .driver = &usbc0_sbu_mux_driver, + .driver = &ioex_sbu_mux_driver, +}; + +struct usb_mux usbc1_sbu_mux = { + .usb_port = USBC_PORT_C1, + .driver = &ioex_sbu_mux_driver, }; __overridable int board_c1_ps8818_mux_set(const struct usb_mux *me, @@ -151,33 +156,12 @@ struct usb_mux usbc1_ps8818 = { .board_set = &board_c1_ps8818_mux_set, }; -/* TODO: ANX7483 support */ - -/* - * ANX7491(A1) and ANX7451(C1) are on the same i2c bus. Both default - * to 0x29 for the USB i2c address. This moves ANX7451(C1) USB i2c - * address to 0x2A. ANX7491(A1) will stay at the default 0x29. - */ -uint16_t board_anx7451_get_usb_i2c_addr(const struct usb_mux *me) -{ - ASSERT(me->usb_port == USBC_PORT_C1); - return 0x2a; -} - -__overridable int board_c1_anx7451_mux_set(const struct usb_mux *me, - mux_state_t mux_state) -{ - CPRINTSUSB("C1: ANX7451 mux using default tuning"); - return 0; -} - -struct usb_mux usbc1_anx7451 = { +struct usb_mux usbc1_anx7483 = { .usb_port = USBC_PORT_C1, .i2c_port = I2C_PORT_TCPC1, - .flags = USB_MUX_FLAG_RESETS_IN_G3, - .i2c_addr_flags = ANX7491_I2C_ADDR3_FLAGS, - .driver = &anx7451_usb_mux_driver, - .board_set = &board_c1_anx7451_mux_set, + .i2c_addr_flags = ANX7483_I2C_ADDR0_FLAGS, + .driver = &anx7483_usb_retimer_driver, + .next_mux = &usbc1_sbu_mux, }; struct usb_mux usb_muxes[] = { @@ -198,34 +182,50 @@ struct usb_mux usb_muxes[] = { }; BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == CONFIG_USB_PD_PORT_MAX_COUNT); -/* TODO: SBU flip on DB with fusb */ /* TODO: HPD signal on PS8818 DB */ -/* TODO: A1 retimer enable and reset on PS8811 DB */ /* - * USB C0 port SBU mux use standalone FSUSB42UMX - * chip and it needs a board specific driver. - * Overall, it will use chained mux framework. + * USB C0 (general) and C1 (just ANX DB) use IOEX pins to + * indicate flipped polarity to a protection switch. */ -static int fsusb42umx_set_mux(const struct usb_mux *me, mux_state_t mux_state, - bool *ack_required) +static int ioex_set_flip(const struct usb_mux *me, mux_state_t mux_state, + bool *ack_required) { /* This driver does not use host command ACKs */ *ack_required = false; - if (mux_state & USB_PD_MUX_POLARITY_INVERTED) - ioex_set_level(IOEX_USB_C0_SBU_FLIP, 1); - else - ioex_set_level(IOEX_USB_C0_SBU_FLIP, 0); + if (me->usb_port == USBC_PORT_C0) { + if (mux_state & USB_PD_MUX_POLARITY_INVERTED) + ioex_set_level(IOEX_USB_C0_SBU_FLIP, 1); + else + ioex_set_level(IOEX_USB_C0_SBU_FLIP, 0); + } else { + if (mux_state & USB_PD_MUX_POLARITY_INVERTED) + ioex_set_level(IOEX_USB_C1_SBU_FLIP, 1); + else + ioex_set_level(IOEX_USB_C1_SBU_FLIP, 0); + } return EC_SUCCESS; } static void setup_mux(void) { - /* TODO: Fill in C1 mux based on CBI */ - CPRINTSUSB("C1: Setting ANX7451 mux"); - usb_muxes[USBC_PORT_C1].next_mux = &usbc1_anx7451; + uint32_t val; + + if (cros_cbi_get_fw_config(FW_IO_DB, &val) != 0) + CPRINTSUSB("Error finding FW_DB_IO in CBI FW_CONFIG"); + /* Val will have our dts default on error, so continue setup */ + + if (val == FW_IO_DB_PS8811_PS8818) { + CPRINTSUSB("C1: Setting PS8818 mux"); + usb_muxes[USBC_PORT_C1].next_mux = &usbc1_ps8818; + } else if (val == FW_IO_DB_NONE_ANX7483) { + CPRINTSUSB("C1: Setting ANX7483 mux"); + usb_muxes[USBC_PORT_C1].next_mux = &usbc1_anx7483; + } else { + CPRINTSUSB("Unexpected DB_IO board: %d", val); + } } DECLARE_HOOK(HOOK_INIT, setup_mux, HOOK_PRIO_INIT_I2C); @@ -540,91 +540,3 @@ void board_hibernate(void) if ((ret != EC_SUCCESS) && (ret != EC_ERROR_UNIMPLEMENTED)) cprints(CC_SYSTEM, "Failed to send battery sleep command"); } - -__overridable enum ec_error_list -board_a1_ps8811_retimer_init(const struct usb_mux *me) -{ - return EC_SUCCESS; -} - -static int baseboard_a1_ps8811_retimer_init(const struct usb_mux *me) -{ - int rv; - int tries = 2; - - do { - int val; - - rv = ps8811_i2c_read(me, PS8811_REG_PAGE1, - PS8811_REG1_USB_BEQ_LEVEL, &val); - } while (rv && --tries); - - if (rv) { - CPRINTSUSB("A1: PS8811 retimer not detected!"); - return rv; - } - CPRINTSUSB("A1: PS8811 retimer detected"); - rv = board_a1_ps8811_retimer_init(me); - if (rv) - CPRINTSUSB("A1: Error during PS8811 setup rv:%d", rv); - return rv; -} - -/* - * PS8811 is just a type-A USB retimer, reusing mux structure for - * convenience. - */ -const struct usb_mux usba1_ps8811 = { - .usb_port = USBA_PORT_A1, - .i2c_port = I2C_PORT_TCPC1, - .i2c_addr_flags = PS8811_I2C_ADDR_FLAGS3, - .board_init = &baseboard_a1_ps8811_retimer_init, -}; - -__overridable enum ec_error_list -board_a1_anx7491_retimer_init(const struct usb_mux *me) -{ - return EC_SUCCESS; -} - -static int baseboard_a1_anx7491_retimer_init(const struct usb_mux *me) -{ - int rv; - int tries = 2; - - do { - int val; - - rv = i2c_read8(me->i2c_port, me->i2c_addr_flags, 0, &val); - } while (rv && --tries); - if (rv) { - CPRINTSUSB("A1: ANX7491 retimer not detected!"); - return rv; - } - CPRINTSUSB("A1: ANX7491 retimer detected"); - rv = board_a1_anx7491_retimer_init(me); - if (rv) - CPRINTSUSB("A1: Error during ANX7491 setup rv:%d", rv); - return rv; -} - -/* - * ANX7491 is just a type-A USB retimer, reusing mux structure for - * convenience. - */ -const struct usb_mux usba1_anx7491 = { - .usb_port = USBA_PORT_A1, - .i2c_port = I2C_PORT_TCPC1, - .i2c_addr_flags = ANX7491_I2C_ADDR0_FLAGS, - .board_init = &baseboard_a1_anx7491_retimer_init, -}; - -void baseboard_a1_retimer_setup(void) -{ - struct usb_mux a1_retimer; - - /* TODO: Support PS8811 retimer through CBI */ - a1_retimer = usba1_anx7491; - a1_retimer.board_init(&a1_retimer); -} -DECLARE_DEFERRED(baseboard_a1_retimer_setup); |