usb: typec: ps883x: Add USB4 mode and TBT3 altmode support

This chip can do some more than the driver currently describes. Add
support for configuring it for various flavors of TBT3/USB4 operation.

Reviewed-by: Jack Pham <jack.pham@oss.qualcomm.com>
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20251014-topic-ps883x_usb4-v1-3-e6adb1a4296e@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
pull/1354/merge
Konrad Dybcio 2025-10-14 18:06:47 +02:00 committed by Greg Kroah-Hartman
parent 6bebd9b777
commit 832c8d3fce
2 changed files with 30 additions and 0 deletions

View File

@ -14,15 +14,18 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/usb/pd.h>
#include <linux/usb/typec_altmode.h> #include <linux/usb/typec_altmode.h>
#include <linux/usb/typec_dp.h> #include <linux/usb/typec_dp.h>
#include <linux/usb/typec_mux.h> #include <linux/usb/typec_mux.h>
#include <linux/usb/typec_retimer.h> #include <linux/usb/typec_retimer.h>
#include <linux/usb/typec_tbt.h>
#define REG_USB_PORT_CONN_STATUS_0 0x00 #define REG_USB_PORT_CONN_STATUS_0 0x00
#define CONN_STATUS_0_CONNECTION_PRESENT BIT(0) #define CONN_STATUS_0_CONNECTION_PRESENT BIT(0)
#define CONN_STATUS_0_ORIENTATION_REVERSED BIT(1) #define CONN_STATUS_0_ORIENTATION_REVERSED BIT(1)
#define CONN_STATUS_0_ACTIVE_CABLE BIT(2)
#define CONN_STATUS_0_USB_3_1_CONNECTED BIT(5) #define CONN_STATUS_0_USB_3_1_CONNECTED BIT(5)
#define REG_USB_PORT_CONN_STATUS_1 0x01 #define REG_USB_PORT_CONN_STATUS_1 0x01
@ -34,6 +37,10 @@
#define REG_USB_PORT_CONN_STATUS_2 0x02 #define REG_USB_PORT_CONN_STATUS_2 0x02
#define CONN_STATUS_2_TBT_CONNECTED BIT(0)
#define CONN_STATUS_2_TBT_UNIDIR_LSRX_ACT_LT BIT(4)
#define CONN_STATUS_2_USB4_CONNECTED BIT(7)
struct ps883x_retimer { struct ps883x_retimer {
struct i2c_client *client; struct i2c_client *client;
struct gpio_desc *reset_gpio; struct gpio_desc *reset_gpio;
@ -95,6 +102,8 @@ static int ps883x_configure(struct ps883x_retimer *retimer, int cfg0,
static int ps883x_set(struct ps883x_retimer *retimer, struct typec_retimer_state *state) static int ps883x_set(struct ps883x_retimer *retimer, struct typec_retimer_state *state)
{ {
struct typec_thunderbolt_data *tb_data;
const struct enter_usb_data *eudo_data;
int cfg0 = CONN_STATUS_0_CONNECTION_PRESENT; int cfg0 = CONN_STATUS_0_CONNECTION_PRESENT;
int cfg1 = 0x00; int cfg1 = 0x00;
int cfg2 = 0x00; int cfg2 = 0x00;
@ -120,6 +129,18 @@ static int ps883x_set(struct ps883x_retimer *retimer, struct typec_retimer_state
break; break;
} }
break; break;
case USB_TYPEC_TBT_SID:
tb_data = state->data;
/* Unconditional */
cfg2 |= CONN_STATUS_2_TBT_CONNECTED;
if (tb_data->cable_mode & TBT_CABLE_ACTIVE_PASSIVE)
cfg0 |= CONN_STATUS_0_ACTIVE_CABLE;
if (tb_data->enter_vdo & TBT_ENTER_MODE_UNI_DIR_LSRX)
cfg2 |= CONN_STATUS_2_TBT_UNIDIR_LSRX_ACT_LT;
break;
default: default:
dev_err(&retimer->client->dev, "Got unsupported SID: 0x%x\n", dev_err(&retimer->client->dev, "Got unsupported SID: 0x%x\n",
state->alt->svid); state->alt->svid);
@ -135,6 +156,14 @@ static int ps883x_set(struct ps883x_retimer *retimer, struct typec_retimer_state
case TYPEC_MODE_USB3: case TYPEC_MODE_USB3:
cfg0 |= CONN_STATUS_0_USB_3_1_CONNECTED; cfg0 |= CONN_STATUS_0_USB_3_1_CONNECTED;
break; break;
case TYPEC_MODE_USB4:
eudo_data = state->data;
cfg2 |= CONN_STATUS_2_USB4_CONNECTED;
if (FIELD_GET(EUDO_CABLE_TYPE_MASK, eudo_data->eudo) != EUDO_CABLE_TYPE_PASSIVE)
cfg0 |= CONN_STATUS_0_ACTIVE_CABLE;
break;
default: default:
dev_err(&retimer->client->dev, "Got unsupported mode: %lu\n", dev_err(&retimer->client->dev, "Got unsupported mode: %lu\n",
state->mode); state->mode);

View File

@ -55,6 +55,7 @@ struct typec_thunderbolt_data {
/* TBT3 Device Enter Mode VDO bits */ /* TBT3 Device Enter Mode VDO bits */
#define TBT_ENTER_MODE_CABLE_SPEED(s) TBT_SET_CABLE_SPEED(s) #define TBT_ENTER_MODE_CABLE_SPEED(s) TBT_SET_CABLE_SPEED(s)
#define TBT_ENTER_MODE_UNI_DIR_LSRX BIT(23)
#define TBT_ENTER_MODE_ACTIVE_CABLE BIT(24) #define TBT_ENTER_MODE_ACTIVE_CABLE BIT(24)
#endif /* __USB_TYPEC_TBT_H */ #endif /* __USB_TYPEC_TBT_H */