diff --git a/drivers/usb/typec/mux/ps883x.c b/drivers/usb/typec/mux/ps883x.c index 15aee1d613b1..2ec57cfe748a 100644 --- a/drivers/usb/typec/mux/ps883x.c +++ b/drivers/usb/typec/mux/ps883x.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,22 @@ #define CONN_STATUS_2_TBT_UNIDIR_LSRX_ACT_LT BIT(4) #define CONN_STATUS_2_USB4_CONNECTED BIT(7) +/* + * Platforms where the USB4 / DP-tunneling stack is not ready yet. Rejecting + * USB4 here lets the Type-C stack fall back to USB3 + DP Alt Mode instead of + * negotiating USB4 and then failing to drive DisplayPort. + * + * This is a temporary, kernel-contained quirk (not DT ABI). Drop the entries + * once the corresponding USB4 support is complete. + */ +static const char * const ps883x_disable_usb4_compats[] = { + "qcom,x1e80100", + "qcom,x1p42100", + "qcom,hamoa", + "qcom,purwa", + NULL, +}; + struct ps883x_retimer { struct i2c_client *client; struct gpio_desc *reset_gpio; @@ -63,8 +80,21 @@ struct ps883x_retimer { enum typec_orientation orientation; bool in_reset; + bool disable_usb4; }; +static bool ps883x_should_disable_usb4(void) +{ + const char * const *compat; + + for (compat = ps883x_disable_usb4_compats; *compat; compat++) { + if (of_machine_is_compatible(*compat)) + return true; + } + + return false; +} + static int ps883x_enable_vregs(struct ps883x_retimer *retimer) { struct device *dev = &retimer->client->dev; @@ -260,6 +290,9 @@ static int ps883x_set(struct ps883x_retimer *retimer, struct typec_retimer_state cfg0 |= CONN_STATUS_0_USB_3_1_CONNECTED; break; case TYPEC_MODE_USB4: + if (retimer->disable_usb4) + return -EOPNOTSUPP; + eudo_data = state->data; cfg2 |= CONN_STATUS_2_USB4_CONNECTED; @@ -389,6 +422,10 @@ static int ps883x_retimer_probe(struct i2c_client *client) retimer->client = client; + retimer->disable_usb4 = ps883x_should_disable_usb4(); + if (retimer->disable_usb4) + dev_info(dev, "USB4 disabled until platform USB4 support is complete\n"); + mutex_init(&retimer->lock); retimer->regmap = devm_regmap_init_i2c(client, &ps883x_retimer_regmap);