diff options
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | driver/tcpm/ps8xxx.c | 81 | ||||
-rw-r--r-- | driver/tcpm/ps8xxx.h | 5 | ||||
-rw-r--r-- | include/config.h | 1 | ||||
-rw-r--r-- | include/driver/tcpm/ps8xxx_public.h | 1 | ||||
-rw-r--r-- | zephyr/Kconfig.tcpm | 21 | ||||
-rw-r--r-- | zephyr/shim/include/config_chip.h | 10 |
7 files changed, 112 insertions, 8 deletions
diff --git a/driver/build.mk b/driver/build.mk index 81955294eb..feef1ccc6c 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -165,6 +165,7 @@ endif driver-$(CONFIG_USB_PD_TCPM_ANX74XX)+=tcpm/anx74xx.o driver-$(CONFIG_USB_PD_TCPM_ANX7688)+=tcpm/anx7688.o driver-$(CONFIG_USB_PD_TCPM_ANX7447)+=tcpm/anx7447.o +driver-$(CONFIG_USB_PD_TCPM_PS8745)+=tcpm/ps8xxx.o driver-$(CONFIG_USB_PD_TCPM_PS8751)+=tcpm/ps8xxx.o driver-$(CONFIG_USB_PD_TCPM_PS8755)+=tcpm/ps8xxx.o driver-$(CONFIG_USB_PD_TCPM_PS8705)+=tcpm/ps8xxx.o diff --git a/driver/tcpm/ps8xxx.c b/driver/tcpm/ps8xxx.c index 0ffd69364a..9c51fbc910 100644 --- a/driver/tcpm/ps8xxx.c +++ b/driver/tcpm/ps8xxx.c @@ -8,6 +8,7 @@ * * Supported TCPCs: * - PS8705 + * - PS8745 * - PS8751 * - PS8755 * - PS8805 @@ -24,6 +25,7 @@ #include "usb_pd.h" #if !defined(CONFIG_USB_PD_TCPM_PS8705) && \ + !defined(CONFIG_USB_PD_TCPM_PS8745) && \ !defined(CONFIG_USB_PD_TCPM_PS8751) && \ !defined(CONFIG_USB_PD_TCPM_PS8755) && \ !defined(CONFIG_USB_PD_TCPM_PS8805) && \ @@ -165,13 +167,13 @@ static int ps8751_dci_disable(int port) } #endif /* CONFIG_USB_PD_TCPM_PS8751 */ -#ifdef CONFIG_USB_PD_TCPM_PS8815 +#if defined(CONFIG_USB_PD_TCPM_PS8815) || defined(CONFIG_USB_PD_TCPM_PS8745) static int ps8815_dci_disable(int port) { - /* DCI is disabled on the ps8815 */ + /* DCI is disabled on the ps8815 and ps8745 */ return EC_SUCCESS; } -#endif /* CONFIG_USB_PD_TCPM_PS8815 */ +#endif /* CONFIG_USB_PD_TCPM_PS8815 || CONFIG_USB_PD_TCPM_PS8745 */ #ifdef CONFIG_USB_PD_TCPM_PS8805 static int ps8805_gpio_mask[] = { @@ -250,6 +252,9 @@ static struct ps8xxx_variant_map variant_map[] = { [REG_FW_VER] = 0x82, } }, #endif +#ifdef CONFIG_USB_PD_TCPM_PS8745 + { PS8745_PRODUCT_ID, ps8815_dci_disable, { [REG_FW_VER] = 0x82 } }, +#endif #ifdef CONFIG_USB_PD_TCPM_PS8751 { PS8751_PRODUCT_ID, ps8751_dci_disable, @@ -341,6 +346,8 @@ __overridable uint16_t board_get_ps8xxx_product_id(int port) return 0; } else if (IS_ENABLED(CONFIG_USB_PD_TCPM_PS8705)) { return PS8705_PRODUCT_ID; + } else if (IS_ENABLED(CONFIG_USB_PD_TCPM_PS8745)) { + return PS8745_PRODUCT_ID; } else if (IS_ENABLED(CONFIG_USB_PD_TCPM_PS8751)) { return PS8751_PRODUCT_ID; } else if (IS_ENABLED(CONFIG_USB_PD_TCPM_PS8755)) { @@ -480,12 +487,13 @@ static int ps8xxx_tcpc_drp_toggle(int port) int opposite_pull; /* - * Workaround for PS8805/PS8815, which can't restart Connection + * Workaround for PS8805/PS8815/PS8745, which can't restart Connection * Detection if the partner already presents pull. Now starts with * the opposite pull. Check b/149570002. */ if (product_id[port] == PS8805_PRODUCT_ID || - product_id[port] == PS8815_PRODUCT_ID) { + product_id[port] == PS8815_PRODUCT_ID || + product_id[port] == PS8745_PRODUCT_ID) { if (ps8815_disable_rp_detect[port]) { CPRINTS("TCPC%d: rearm Rp disable detect on connect", port); @@ -587,6 +595,44 @@ static int ps8815_make_device_id(int port, int *id) } #endif +#ifdef CONFIG_USB_PD_TCPM_PS8745_FORCE_ID +/* + * Some PS8745 firmwares report the same product/device ID and chip rev as + * PS8815-A2. This function probes vendor-specific registers to determine + * whether the device is a PS8815 or PS8745 and updates the IDs pointed to by + * the parameters to be the correct IDs for the detected chip. + * + * See b/236761058 and the PS8xxx TCPC Family Chip Revision Guide (v0.2) + */ +static int ps8745_make_device_id(int port, uint16_t *pid, uint16_t *did) +{ + int status; + int val; + + status = tcpc_addr_read( + port, + PS8751_P3_TO_P0_FLAGS(tcpc_config[port].i2c_info.addr_flags), + PS8815_P0_REG_ID, &val); + if (status != EC_SUCCESS) + return status; + + if (*pid == PS8815_PRODUCT_ID && (val & BIT(1)) != 0) { + /* PS8815 with this bit set is actually PS8745 */ + *pid = PS8745_PRODUCT_ID; + } + + if (*pid == PS8745_PRODUCT_ID && *did == 0x0003) { + /* + * Some versions report the correct product ID but the + * device ID is still for PS8815-A2. + */ + *did = 0x0006; + } + + return EC_SUCCESS; +} +#endif + /* * The ps8815 can take up to 50ms (FW_INIT_DELAY_MS) to fully wake up * from sleep/low power mode - specially when it contains an application @@ -654,6 +700,20 @@ static int ps8xxx_get_chip_info(int port, int live, chip_info->product_id = product_id[port]; } +#ifdef CONFIG_USB_PD_TCPM_PS8745_FORCE_ID + /* device ID 3 is PS8815 and might be misreported */ + if (chip_info->product_id == PS8815_PRODUCT_ID || + chip_info->device_id == 0x0003) { + uint16_t pid = chip_info->product_id; + uint16_t did = chip_info->device_id; + + rv = ps8745_make_device_id(port, &pid, &did); + chip_info->product_id = pid; + chip_info->device_id = did; + if (rv != EC_SUCCESS) + return rv; + } +#endif #ifdef CONFIG_USB_PD_TCPM_PS8805_FORCE_DID if (chip_info->product_id == PS8805_PRODUCT_ID && chip_info->device_id == 0x0001) { @@ -702,12 +762,13 @@ static int ps8xxx_get_chip_info(int port, int live, static int ps8xxx_enter_low_power_mode(int port) { /* - * PS8751/PS8815 has the auto sleep function that enters + * PS8751/PS8815/PS8745 has the auto sleep function that enters * low power mode on its own in ~2 seconds. Other chips * don't have it. Stub it out for PS8751/PS8815. */ if (product_id[port] == PS8751_PRODUCT_ID || - product_id[port] == PS8815_PRODUCT_ID) + product_id[port] == PS8815_PRODUCT_ID || + product_id[port] == PS8745_PRODUCT_ID) return EC_SUCCESS; return tcpci_enter_low_power_mode(port); @@ -823,7 +884,10 @@ static int ps8xxx_tcpm_init(int port) status = ps8815_disable_rp_detect_workaround_check(port); if (status != EC_SUCCESS) return status; + } + if (IS_ENABLED(CONFIG_USB_PD_TCPM_PS8745) || + IS_ENABLED(CONFIG_USB_PD_TCPM_PS8815)) { /* * NOTE(b/183127346): Enable FRS sequence: * @@ -973,7 +1037,8 @@ const struct tcpm_drv ps8xxx_tcpm_drv = { .enter_low_power_mode = ps8xxx_enter_low_power_mode, #endif .set_bist_test_mode = tcpci_set_bist_test_mode, -#if defined(CONFIG_USB_PD_FRS) && defined(CONFIG_USB_PD_TCPM_PS8815) +#if defined(CONFIG_USB_PD_FRS) && (defined(CONFIG_USB_PD_TCPM_PS8815) || \ + defined(CONFIG_USB_PD_TCPM_PS8745)) .set_frs_enable = ps8815_tcpc_fast_role_swap_enable, #endif }; diff --git a/driver/tcpm/ps8xxx.h b/driver/tcpm/ps8xxx.h index 571b2d4ccb..82772e4a5e 100644 --- a/driver/tcpm/ps8xxx.h +++ b/driver/tcpm/ps8xxx.h @@ -99,6 +99,11 @@ * bit 7-4: 1010b is A3 chip, 0000b is A2 chip */ #define PS8805_P0_REG_CHIP_REVISION 0x62 +/* + * PS8815 register to differentiate with PS8745: bit 1 = 0 is a PS8815-A2, + * 1 is a PS8745-A2. + */ +#define PS8815_P0_REG_ID 0x2C /* * PS8805 GPIO control register. Note the device I2C address of 0x1A is diff --git a/include/config.h b/include/config.h index d22bb985cc..0d73dbe03a 100644 --- a/include/config.h +++ b/include/config.h @@ -4811,6 +4811,7 @@ * to provide the product id per port. */ #undef CONFIG_USB_PD_TCPM_MULTI_PS8XXX +#undef CONFIG_USB_PD_TCPM_PS8745 #undef CONFIG_USB_PD_TCPM_PS8751 #undef CONFIG_USB_PD_TCPM_PS8755 #undef CONFIG_USB_PD_TCPM_PS8705 diff --git a/include/driver/tcpm/ps8xxx_public.h b/include/driver/tcpm/ps8xxx_public.h index 0c0e7951c5..05823a7b42 100644 --- a/include/driver/tcpm/ps8xxx_public.h +++ b/include/driver/tcpm/ps8xxx_public.h @@ -56,6 +56,7 @@ struct usb_mux; * 8705, 8755 and 8805. */ #define PS8705_PRODUCT_ID 0x8705 +#define PS8745_PRODUCT_ID 0x8745 #define PS8751_PRODUCT_ID 0x8751 #define PS8755_PRODUCT_ID 0x8755 #define PS8805_PRODUCT_ID 0x8805 diff --git a/zephyr/Kconfig.tcpm b/zephyr/Kconfig.tcpm index 6aeb7cf3bb..ebd6e3b49a 100644 --- a/zephyr/Kconfig.tcpm +++ b/zephyr/Kconfig.tcpm @@ -156,12 +156,33 @@ config PLATFORM_EC_USB_PD_TCPM_MULTI_PS8XXX Supported return values are: PS8705_PRODUCT_ID + PS8745_PRODUCT_ID PS8751_PRODUCT_ID PS8755_PRODUCT_ID PS8805_PRODUCT_ID PS8815_PRODUCT_ID endif # PLATFORM_EC_USB_PD_TCPM_PS8XXX +config PLATFORM_EC_USB_PD_TCPM_PS8745 + bool "Parade PS8745 USB-C Gen 2 Type-C Port Controller" + select PLATFORM_EC_USB_PD_TCPM_PS8XXX + help + The Parade Technologies PS8815 is an active retiming/redriving + (respectively for USB 3.1 Gen 2 / DisplayPort 1.4a HBR3) integrated + with a USB Type-C Port Controller (TCPC) for USB Type-C Host and + DisplayPort applications. It supports Power Delivery and the + DisplayPort Alt Mode. + +if PLATFORM_EC_USB_PD_TCPM_PS8745 +config PLATFORM_EC_USB_PD_TCPM_PS8745_FORCE_ID + bool "Disambiguate PS8745 and PS8815" + default y + help + Some firmware versions of the PS8745 report incorrect product and device + IDs. Enable this option to check vendor-specific registers and force the + correct device and product IDs. +endif # PLATFORM_EC_USB_PD_TCPM_PS8745 + config PLATFORM_EC_USB_PD_TCPM_PS8751 bool "Parade PS8751 USB-C Gen 2 Type-C Port Controller" select PLATFORM_EC_USB_PD_TCPM_PS8XXX diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h index deb6340dd5..f2864dddb3 100644 --- a/zephyr/shim/include/config_chip.h +++ b/zephyr/shim/include/config_chip.h @@ -1307,6 +1307,16 @@ extern struct jump_data mock_jump_data; #define CONFIG_USB_PD_TCPM_NCT38XX #endif +#undef CONFIG_USB_PD_TCPM_PS8745 +#ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8745 +#define CONFIG_USB_PD_TCPM_PS8745 +#endif + +#undef CONFIG_USB_PD_TCPM_PS8745_FORCE_ID +#ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8745_FORCE_ID +#define CONFIG_USB_PD_TCPM_PS8745_FORCE_ID +#endif + #undef CONFIG_USB_PD_TCPM_PS8751 #ifdef CONFIG_PLATFORM_EC_USB_PD_TCPM_PS8751 #define CONFIG_USB_PD_TCPM_PS8751 |