Re: [PATCH v6 2/2] usb: typec: Add support for Parade PS8830 Type-C Retimer

Stephan Gerhold
2025-02-18T09:27:05Z

On Tue, Feb 18, 2025 at 08:54:47AM +0100, Johan Hovold wrote:
> On Fri, Feb 14, 2025 at 09:52:33AM +0100, Johan Hovold wrote:
> > On Thu, Feb 06, 2025 at 11:28:28AM +0200, Abel Vesa wrote:
> > > The Parade PS8830 is a USB4, DisplayPort and Thunderbolt 4 retimer,
> > > controlled over I2C. It usually sits between a USB/DisplayPort PHY
> > > and the Type-C connector, and provides orientation and altmode handling.
> [...]
> > > + /* skip resetting if already configured */
> > > + if (regmap_test_bits(retimer->regmap, REG_USB_PORT_CONN_STATUS_0,
> > > + CONN_STATUS_0_CONNECTION_PRESENT) == 1)
> > > + return gpiod_direction_output(retimer->reset_gpio, 0);
> >
> > I'm still a little concerned about this. Won't you end up with i2c
> > timeout errors in the logs if the device is held in reset before probe?
>
> You should be able to use i2c_smbus_read_byte() to avoid logging errors
> when the boot firmware has *not* enabled the device.
>

FWIW, regmap_test_bits() doesn't seem to print any errors either, so I
don't think switching to i2c_smbus_read_byte() is necessary.

Since I was curious, I tried booting the X1E80100 with
1. One PS8830 instance left as-is
2. One PS8830 instance changed to invalid I2C address
3. One PS8830 instance changed to have reset pin asserted via pinctrl

There are no errors whatsoever, even for the one with invalid I2C
address. In other words, the slightly more concerning part is that the
driver doesn't check that any of the regmap reads/writes actually
succeed.

The diff I used for testing is below. (1) prints "skipping reset", (2)
and (3) print "continuing reset".

Thanks,
Stephan

diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
index fee694a364ea..1f8d61239723 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
+++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
@@ -1010,9 +1010,9 @@ &i2c1 {

status = "okay";

- typec-mux@8 {
+ typec-mux@42 {
compatible = "parade,ps8830";
- reg = <0x08>;
+ reg = <0x42>;

clocks = <&rpmhcc RPMH_RF_CLK5>;

@@ -1673,6 +1673,7 @@ rtmr1_default: rtmr1-reset-n-active-state {
function = "gpio";
drive-strength = <2>;
bias-disable;
+ output-low;
};

rtmr2_default: rtmr2-reset-n-active-state {
diff --git a/drivers/usb/typec/mux/ps883x.c b/drivers/usb/typec/mux/ps883x.c
index 10e407ab6b7f..04ed35d14fd6 100644
--- a/drivers/usb/typec/mux/ps883x.c
+++ b/drivers/usb/typec/mux/ps883x.c
@@ -370,8 +370,12 @@ static int ps883x_retimer_probe(struct i2c_client *client)

/* skip resetting if already configured */
if (regmap_test_bits(retimer->regmap, REG_USB_PORT_CONN_STATUS_0,
- CONN_STATUS_0_CONNECTION_PRESENT) == 1)
+ CONN_STATUS_0_CONNECTION_PRESENT) == 1) {
+ dev_info(dev, "skipping reset\n");
return gpiod_direction_output(retimer->reset_gpio, 0);
+ } else {
+ dev_info(dev, "continuing reset\n");
+ }

gpiod_direction_output(retimer->reset_gpio, 1);