Re: [PATCH 2/2] usb: typec: add support for PTN36502 redriver

2023-10-20 Thread Luca Weiss
On Fri Oct 20, 2023 at 9:18 AM CEST, Neil Armstrong wrote:
> On 20/10/2023 08:13, Luca Weiss wrote:
> > On Tue Oct 17, 2023 at 10:34 AM CEST, Heikki Krogerus wrote:
> >> Hi,
> >>
> >> On Fri, Oct 13, 2023 at 04:24:48PM +0200, Luca Weiss wrote:
> >>> Add a driver for the NXP PTN36502 Type-C USB 3.1 Gen 1 and DisplayPort
> >>> v1.2 combo redriver.
> >>>
> >>> Signed-off-by: Luca Weiss 
> >>
> >> Looks OK to me, but couple of nitpicks below. With those fixed:
> >>
> >> Reviewed-by: Heikki Krogerus 
> >>
> >>> ---
> >>>   drivers/usb/typec/mux/Kconfig|  10 +
> >>>   drivers/usb/typec/mux/Makefile   |   1 +
> >>>   drivers/usb/typec/mux/ptn36502.c | 421 
> >>> +++
> >>>   3 files changed, 432 insertions(+)
> >>>

[snip]

> >>> +#define PTN36502_CHIP_ID_REG 0x00
> >>> +#define PTN36502_CHIP_ID 0x02
> >>> +
> >>> +#define PTN36502_CHIP_REVISION_REG   0x01
> >>> +#define PTN36502_CHIP_REVISION_BASE(val) FIELD_GET(GENMASK(7, 
> >>> 4), (val))
> >>> +#define PTN36502_CHIP_REVISION_METAL(val)
> >>> FIELD_GET(GENMASK(3, 0), (val))
> >>> +
> >>> +#define PTN36502_DP_LINK_CTRL_REG0x06
> >>> +#define PTN36502_DP_LINK_CTRL_LANES_2(2 << 2)
> >>> +#define PTN36502_DP_LINK_CTRL_LANES_4(3 << 2)
> >>> +#define PTN36502_DP_LINK_CTRL_LINK_RATE_5_4GBPS  (2 << 0)
> >>> +
> >>> +/* Registers for lane 0 (0x07) to lane 3 (0x0a) have the same layout */
> >>> +#define PTN36502_DP_LANE_CTRL_REG(n) (0x07 + (n))
> >>> +#define PTN36502_DP_LANE_CTRL_RX_GAIN_3DB(2<<4)
> >>> +#define PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD  (2<<2)
> >>> +#define PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_3_5DB (1<<0)
> >>> +
> >>> +#define PTN36502_MODE_CTRL1_REG  0x0b
> >>> +#define PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE  (1<<5)
> >>> +#define PTN36502_MODE_CTRL1_AUX_CROSSBAR_SW_ON   (1<<3)
> >>> +#define PTN36502_MODE_CTRL1_MODE_OFF (0<<0)
> >>> +#define PTN36502_MODE_CTRL1_MODE_USB_ONLY(1<<0)
> >>> +#define PTN36502_MODE_CTRL1_MODE_USB_DP  (2<<0)
> >>> +#define PTN36502_MODE_CTRL1_MODE_DP  (3<<0)
> >>> +
> >>> +#define PTN36502_DEVICE_CTRL_REG 0x0d
> >>> +#define PTN36502_DEVICE_CTRL_AUX_MONITORING_EN   (1<<7)
> >>
> >> You have couple of different styles here. Please try to always use
> >> BIT() and GENMASK() macros when possible. At the very least put spaces
> >> around << and >>.
> > 
> > Hi Heikki,
> > 
> > I was wondering when writing that whether GENMASK was actually proper
> > use for values you write to registers, when not actually used as a
> > bitmask.
> > 
> > Since the datasheet refers to e.g. with TX_SWING_800MVPPD (2<<2) that
> > you write a '2' to the correct bits of this register. But when using
> > BIT(3) kind of hides this relationship if someone refers back to the
> > datasheet. Or same with "3<<2" -> GENMASK(3, 2) or whatever.
>
> The proper way is to define the MASK for the field GENMASK(3, 2) and then
> use FIELD_PREP(GENMASK(3, 2), 2) to write 2 in this field.
>
> You could replace with:
> #define PTN36502_DP_LANE_CTRL_TX_SWING_MASK   GENMASK(3, 2)
> #define PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD   (2)
>
> and in the code
> lane_ctrl_val = FIELD_PREP(PTN36502_DP_LANE_CTRL_RX_GAIN_MASK,
>  PTN36502_DP_LANE_CTRL_RX_GAIN_3DB) |
>   FIELD_PREP(PTN36502_DP_LANE_CTRL_TX_SWING_MASK,
>  PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD) |
>   FIELD_PREP(PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_MASK,
>  PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_3_5DB);
>
> It's a little more verbose but it's much clearer and defines stuff correctly,
> no confusion possible.

Thanks for the advise, I'll update for v2!

Regards
Luca


Re: [PATCH 2/2] usb: typec: add support for PTN36502 redriver

2023-10-20 Thread Neil Armstrong

On 20/10/2023 08:13, Luca Weiss wrote:

On Tue Oct 17, 2023 at 10:34 AM CEST, Heikki Krogerus wrote:

Hi,

On Fri, Oct 13, 2023 at 04:24:48PM +0200, Luca Weiss wrote:

Add a driver for the NXP PTN36502 Type-C USB 3.1 Gen 1 and DisplayPort
v1.2 combo redriver.

Signed-off-by: Luca Weiss 


Looks OK to me, but couple of nitpicks below. With those fixed:

Reviewed-by: Heikki Krogerus 


---
  drivers/usb/typec/mux/Kconfig|  10 +
  drivers/usb/typec/mux/Makefile   |   1 +
  drivers/usb/typec/mux/ptn36502.c | 421 +++
  3 files changed, 432 insertions(+)

diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig
index 65da61150ba7..816b9bd08355 100644
--- a/drivers/usb/typec/mux/Kconfig
+++ b/drivers/usb/typec/mux/Kconfig
@@ -46,4 +46,14 @@ config TYPEC_MUX_NB7VPQ904M
  Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C
  redriver chip found on some devices with a Type-C port.
  
+config TYPEC_MUX_PTN36502

+   tristate "NXP PTN36502 Type-C redriver driver"
+   depends on I2C
+   depends on DRM || DRM=n
+   select DRM_PANEL_BRIDGE if DRM
+   select REGMAP_I2C
+   help
+ Say Y or M if your system has a NXP PTN36502 Type-C redriver chip
+ found on some devices with a Type-C port.
+
  endmenu
diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile
index 76196096ef41..9d6a5557b0bd 100644
--- a/drivers/usb/typec/mux/Makefile
+++ b/drivers/usb/typec/mux/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_MUX_GPIO_SBU)+= gpio-sbu-mux.o
  obj-$(CONFIG_TYPEC_MUX_PI3USB30532)   += pi3usb30532.o
  obj-$(CONFIG_TYPEC_MUX_INTEL_PMC) += intel_pmc_mux.o
  obj-$(CONFIG_TYPEC_MUX_NB7VPQ904M)+= nb7vpq904m.o
+obj-$(CONFIG_TYPEC_MUX_PTN36502)   += ptn36502.o
diff --git a/drivers/usb/typec/mux/ptn36502.c b/drivers/usb/typec/mux/ptn36502.c
new file mode 100644
index ..91684a856f3a
--- /dev/null
+++ b/drivers/usb/typec/mux/ptn36502.c
@@ -0,0 +1,421 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NXP PTN36502 Type-C driver
+ *
+ * Copyright (C) 2023 Luca Weiss 
+ *
+ * Based on NB7VPQ904M driver:
+ * Copyright (C) 2023 Dmitry Baryshkov 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PTN36502_CHIP_ID_REG   0x00
+#define PTN36502_CHIP_ID   0x02
+
+#define PTN36502_CHIP_REVISION_REG 0x01
+#define PTN36502_CHIP_REVISION_BASE(val)   FIELD_GET(GENMASK(7, 
4), (val))
+#define PTN36502_CHIP_REVISION_METAL(val)  FIELD_GET(GENMASK(3, 
0), (val))
+
+#define PTN36502_DP_LINK_CTRL_REG  0x06
+#define PTN36502_DP_LINK_CTRL_LANES_2  (2 << 2)
+#define PTN36502_DP_LINK_CTRL_LANES_4  (3 << 2)
+#define PTN36502_DP_LINK_CTRL_LINK_RATE_5_4GBPS(2 << 0)
+
+/* Registers for lane 0 (0x07) to lane 3 (0x0a) have the same layout */
+#define PTN36502_DP_LANE_CTRL_REG(n)   (0x07 + (n))
+#define PTN36502_DP_LANE_CTRL_RX_GAIN_3DB  (2<<4)
+#define PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD(2<<2)
+#define PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_3_5DB   (1<<0)
+
+#define PTN36502_MODE_CTRL1_REG0x0b
+#define PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE(1<<5)
+#define PTN36502_MODE_CTRL1_AUX_CROSSBAR_SW_ON (1<<3)
+#define PTN36502_MODE_CTRL1_MODE_OFF   (0<<0)
+#define PTN36502_MODE_CTRL1_MODE_USB_ONLY  (1<<0)
+#define PTN36502_MODE_CTRL1_MODE_USB_DP(2<<0)
+#define PTN36502_MODE_CTRL1_MODE_DP(3<<0)
+
+#define PTN36502_DEVICE_CTRL_REG   0x0d
+#define PTN36502_DEVICE_CTRL_AUX_MONITORING_EN (1<<7)


You have couple of different styles here. Please try to always use
BIT() and GENMASK() macros when possible. At the very least put spaces
around << and >>.


Hi Heikki,

I was wondering when writing that whether GENMASK was actually proper
use for values you write to registers, when not actually used as a
bitmask.

Since the datasheet refers to e.g. with TX_SWING_800MVPPD (2<<2) that
you write a '2' to the correct bits of this register. But when using
BIT(3) kind of hides this relationship if someone refers back to the
datasheet. Or same with "3<<2" -> GENMASK(3, 2) or whatever.


The proper way is to define the MASK for the field GENMASK(3, 2) and then
use FIELD_PREP(GENMASK(3, 2), 2) to write 2 in this field.

You could replace with:
#define PTN36502_DP_LANE_CTRL_TX_SWING_MASK GENMASK(3, 2)
#define PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD (2)

and in the code
lane_ctrl_val = FIELD_PREP(PTN36502_DP_LANE_CTRL_RX_GAIN_MASK,
   PTN36502_DP_LANE_CTRL_RX_GAIN_3DB) |

Re: [PATCH 2/2] usb: typec: add support for PTN36502 redriver

2023-10-20 Thread Luca Weiss
On Tue Oct 17, 2023 at 10:34 AM CEST, Heikki Krogerus wrote:
> Hi,
>
> On Fri, Oct 13, 2023 at 04:24:48PM +0200, Luca Weiss wrote:
> > Add a driver for the NXP PTN36502 Type-C USB 3.1 Gen 1 and DisplayPort
> > v1.2 combo redriver.
> > 
> > Signed-off-by: Luca Weiss 
>
> Looks OK to me, but couple of nitpicks below. With those fixed:
>
> Reviewed-by: Heikki Krogerus 
>
> > ---
> >  drivers/usb/typec/mux/Kconfig|  10 +
> >  drivers/usb/typec/mux/Makefile   |   1 +
> >  drivers/usb/typec/mux/ptn36502.c | 421 
> > +++
> >  3 files changed, 432 insertions(+)
> > 
> > diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig
> > index 65da61150ba7..816b9bd08355 100644
> > --- a/drivers/usb/typec/mux/Kconfig
> > +++ b/drivers/usb/typec/mux/Kconfig
> > @@ -46,4 +46,14 @@ config TYPEC_MUX_NB7VPQ904M
> >   Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C
> >   redriver chip found on some devices with a Type-C port.
> >  
> > +config TYPEC_MUX_PTN36502
> > +   tristate "NXP PTN36502 Type-C redriver driver"
> > +   depends on I2C
> > +   depends on DRM || DRM=n
> > +   select DRM_PANEL_BRIDGE if DRM
> > +   select REGMAP_I2C
> > +   help
> > + Say Y or M if your system has a NXP PTN36502 Type-C redriver chip
> > + found on some devices with a Type-C port.
> > +
> >  endmenu
> > diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile
> > index 76196096ef41..9d6a5557b0bd 100644
> > --- a/drivers/usb/typec/mux/Makefile
> > +++ b/drivers/usb/typec/mux/Makefile
> > @@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_MUX_GPIO_SBU)+= gpio-sbu-mux.o
> >  obj-$(CONFIG_TYPEC_MUX_PI3USB30532)+= pi3usb30532.o
> >  obj-$(CONFIG_TYPEC_MUX_INTEL_PMC)  += intel_pmc_mux.o
> >  obj-$(CONFIG_TYPEC_MUX_NB7VPQ904M) += nb7vpq904m.o
> > +obj-$(CONFIG_TYPEC_MUX_PTN36502)   += ptn36502.o
> > diff --git a/drivers/usb/typec/mux/ptn36502.c 
> > b/drivers/usb/typec/mux/ptn36502.c
> > new file mode 100644
> > index ..91684a856f3a
> > --- /dev/null
> > +++ b/drivers/usb/typec/mux/ptn36502.c
> > @@ -0,0 +1,421 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * NXP PTN36502 Type-C driver
> > + *
> > + * Copyright (C) 2023 Luca Weiss 
> > + *
> > + * Based on NB7VPQ904M driver:
> > + * Copyright (C) 2023 Dmitry Baryshkov 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define PTN36502_CHIP_ID_REG   0x00
> > +#define PTN36502_CHIP_ID   0x02
> > +
> > +#define PTN36502_CHIP_REVISION_REG 0x01
> > +#define PTN36502_CHIP_REVISION_BASE(val)   FIELD_GET(GENMASK(7, 
> > 4), (val))
> > +#define PTN36502_CHIP_REVISION_METAL(val)  FIELD_GET(GENMASK(3, 
> > 0), (val))
> > +
> > +#define PTN36502_DP_LINK_CTRL_REG  0x06
> > +#define PTN36502_DP_LINK_CTRL_LANES_2  (2 << 2)
> > +#define PTN36502_DP_LINK_CTRL_LANES_4  (3 << 2)
> > +#define PTN36502_DP_LINK_CTRL_LINK_RATE_5_4GBPS(2 << 0)
> > +
> > +/* Registers for lane 0 (0x07) to lane 3 (0x0a) have the same layout */
> > +#define PTN36502_DP_LANE_CTRL_REG(n)   (0x07 + (n))
> > +#define PTN36502_DP_LANE_CTRL_RX_GAIN_3DB  (2<<4)
> > +#define PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD(2<<2)
> > +#define PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_3_5DB   (1<<0)
> > +
> > +#define PTN36502_MODE_CTRL1_REG0x0b
> > +#define PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE(1<<5)
> > +#define PTN36502_MODE_CTRL1_AUX_CROSSBAR_SW_ON (1<<3)
> > +#define PTN36502_MODE_CTRL1_MODE_OFF   (0<<0)
> > +#define PTN36502_MODE_CTRL1_MODE_USB_ONLY  (1<<0)
> > +#define PTN36502_MODE_CTRL1_MODE_USB_DP(2<<0)
> > +#define PTN36502_MODE_CTRL1_MODE_DP(3<<0)
> > +
> > +#define PTN36502_DEVICE_CTRL_REG   0x0d
> > +#define PTN36502_DEVICE_CTRL_AUX_MONITORING_EN (1<<7)
>
> You have couple of different styles here. Please try to always use
> BIT() and GENMASK() macros when possible. At the very least put spaces
> around << and >>.

Hi Heikki,

I was wondering when writing that whether GENMASK was actually proper
use for values you write to registers, when not actually used as a
bitmask.

Since the datasheet refers to e.g. with TX_SWING_800MVPPD (2<<2) that
you write a '2' to the correct bits of this register. But when using
BIT(3) kind of hides this relationship if someone refers back to the
datasheet. Or same with "3<<2" -> GENMASK(3, 2) or whatever.

Let me know what you think.

Regards
Luca

>
> > +struct ptn36502 {
> > +   struct i2c_client *client;
> > +   struct regulator *vdd18_supply;
> > +   struct regmap *regmap;
> > +   struct 

Re: [PATCH 2/2] usb: typec: add support for PTN36502 redriver

2023-10-17 Thread Heikki Krogerus
Hi,

On Fri, Oct 13, 2023 at 04:24:48PM +0200, Luca Weiss wrote:
> Add a driver for the NXP PTN36502 Type-C USB 3.1 Gen 1 and DisplayPort
> v1.2 combo redriver.
> 
> Signed-off-by: Luca Weiss 

Looks OK to me, but couple of nitpicks below. With those fixed:

Reviewed-by: Heikki Krogerus 

> ---
>  drivers/usb/typec/mux/Kconfig|  10 +
>  drivers/usb/typec/mux/Makefile   |   1 +
>  drivers/usb/typec/mux/ptn36502.c | 421 
> +++
>  3 files changed, 432 insertions(+)
> 
> diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig
> index 65da61150ba7..816b9bd08355 100644
> --- a/drivers/usb/typec/mux/Kconfig
> +++ b/drivers/usb/typec/mux/Kconfig
> @@ -46,4 +46,14 @@ config TYPEC_MUX_NB7VPQ904M
> Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C
> redriver chip found on some devices with a Type-C port.
>  
> +config TYPEC_MUX_PTN36502
> + tristate "NXP PTN36502 Type-C redriver driver"
> + depends on I2C
> + depends on DRM || DRM=n
> + select DRM_PANEL_BRIDGE if DRM
> + select REGMAP_I2C
> + help
> +   Say Y or M if your system has a NXP PTN36502 Type-C redriver chip
> +   found on some devices with a Type-C port.
> +
>  endmenu
> diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile
> index 76196096ef41..9d6a5557b0bd 100644
> --- a/drivers/usb/typec/mux/Makefile
> +++ b/drivers/usb/typec/mux/Makefile
> @@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_MUX_GPIO_SBU)  += gpio-sbu-mux.o
>  obj-$(CONFIG_TYPEC_MUX_PI3USB30532)  += pi3usb30532.o
>  obj-$(CONFIG_TYPEC_MUX_INTEL_PMC)+= intel_pmc_mux.o
>  obj-$(CONFIG_TYPEC_MUX_NB7VPQ904M)   += nb7vpq904m.o
> +obj-$(CONFIG_TYPEC_MUX_PTN36502) += ptn36502.o
> diff --git a/drivers/usb/typec/mux/ptn36502.c 
> b/drivers/usb/typec/mux/ptn36502.c
> new file mode 100644
> index ..91684a856f3a
> --- /dev/null
> +++ b/drivers/usb/typec/mux/ptn36502.c
> @@ -0,0 +1,421 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * NXP PTN36502 Type-C driver
> + *
> + * Copyright (C) 2023 Luca Weiss 
> + *
> + * Based on NB7VPQ904M driver:
> + * Copyright (C) 2023 Dmitry Baryshkov 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define PTN36502_CHIP_ID_REG 0x00
> +#define PTN36502_CHIP_ID 0x02
> +
> +#define PTN36502_CHIP_REVISION_REG   0x01
> +#define PTN36502_CHIP_REVISION_BASE(val) FIELD_GET(GENMASK(7, 
> 4), (val))
> +#define PTN36502_CHIP_REVISION_METAL(val)FIELD_GET(GENMASK(3, 
> 0), (val))
> +
> +#define PTN36502_DP_LINK_CTRL_REG0x06
> +#define PTN36502_DP_LINK_CTRL_LANES_2(2 << 2)
> +#define PTN36502_DP_LINK_CTRL_LANES_4(3 << 2)
> +#define PTN36502_DP_LINK_CTRL_LINK_RATE_5_4GBPS  (2 << 0)
> +
> +/* Registers for lane 0 (0x07) to lane 3 (0x0a) have the same layout */
> +#define PTN36502_DP_LANE_CTRL_REG(n) (0x07 + (n))
> +#define PTN36502_DP_LANE_CTRL_RX_GAIN_3DB(2<<4)
> +#define PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD  (2<<2)
> +#define PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_3_5DB (1<<0)
> +
> +#define PTN36502_MODE_CTRL1_REG  0x0b
> +#define PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE  (1<<5)
> +#define PTN36502_MODE_CTRL1_AUX_CROSSBAR_SW_ON   (1<<3)
> +#define PTN36502_MODE_CTRL1_MODE_OFF (0<<0)
> +#define PTN36502_MODE_CTRL1_MODE_USB_ONLY(1<<0)
> +#define PTN36502_MODE_CTRL1_MODE_USB_DP  (2<<0)
> +#define PTN36502_MODE_CTRL1_MODE_DP  (3<<0)
> +
> +#define PTN36502_DEVICE_CTRL_REG 0x0d
> +#define PTN36502_DEVICE_CTRL_AUX_MONITORING_EN   (1<<7)

You have couple of different styles here. Please try to always use
BIT() and GENMASK() macros when possible. At the very least put spaces
around << and >>.

> +struct ptn36502 {
> + struct i2c_client *client;
> + struct regulator *vdd18_supply;
> + struct regmap *regmap;
> + struct typec_switch_dev *sw;
> + struct typec_retimer *retimer;
> +
> + struct typec_switch *typec_switch;
> +
> + struct drm_bridge bridge;
> +
> + struct mutex lock; /* protect non-concurrent retimer & switch */
> +
> + enum typec_orientation orientation;
> + unsigned long mode;
> + unsigned int svid;
> +};
> +
> +static int ptn36502_set(struct ptn36502 *ptn)
> +{
> + bool reverse = (ptn->orientation == TYPEC_ORIENTATION_REVERSE);
> + unsigned int ctrl1_val = 0;
> + unsigned int lane_ctrl_val = 0;
> + unsigned int link_ctrl_val = 0;
> +
> + switch (ptn->mode) {
> + case TYPEC_STATE_SAFE:
> + /* Deep power saving state */
> + regmap_write(ptn->regmap, 

[PATCH 2/2] usb: typec: add support for PTN36502 redriver

2023-10-13 Thread Luca Weiss
Add a driver for the NXP PTN36502 Type-C USB 3.1 Gen 1 and DisplayPort
v1.2 combo redriver.

Signed-off-by: Luca Weiss 
---
 drivers/usb/typec/mux/Kconfig|  10 +
 drivers/usb/typec/mux/Makefile   |   1 +
 drivers/usb/typec/mux/ptn36502.c | 421 +++
 3 files changed, 432 insertions(+)

diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig
index 65da61150ba7..816b9bd08355 100644
--- a/drivers/usb/typec/mux/Kconfig
+++ b/drivers/usb/typec/mux/Kconfig
@@ -46,4 +46,14 @@ config TYPEC_MUX_NB7VPQ904M
  Say Y or M if your system has a On Semiconductor NB7VPQ904M Type-C
  redriver chip found on some devices with a Type-C port.
 
+config TYPEC_MUX_PTN36502
+   tristate "NXP PTN36502 Type-C redriver driver"
+   depends on I2C
+   depends on DRM || DRM=n
+   select DRM_PANEL_BRIDGE if DRM
+   select REGMAP_I2C
+   help
+ Say Y or M if your system has a NXP PTN36502 Type-C redriver chip
+ found on some devices with a Type-C port.
+
 endmenu
diff --git a/drivers/usb/typec/mux/Makefile b/drivers/usb/typec/mux/Makefile
index 76196096ef41..9d6a5557b0bd 100644
--- a/drivers/usb/typec/mux/Makefile
+++ b/drivers/usb/typec/mux/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_MUX_GPIO_SBU)+= gpio-sbu-mux.o
 obj-$(CONFIG_TYPEC_MUX_PI3USB30532)+= pi3usb30532.o
 obj-$(CONFIG_TYPEC_MUX_INTEL_PMC)  += intel_pmc_mux.o
 obj-$(CONFIG_TYPEC_MUX_NB7VPQ904M) += nb7vpq904m.o
+obj-$(CONFIG_TYPEC_MUX_PTN36502)   += ptn36502.o
diff --git a/drivers/usb/typec/mux/ptn36502.c b/drivers/usb/typec/mux/ptn36502.c
new file mode 100644
index ..91684a856f3a
--- /dev/null
+++ b/drivers/usb/typec/mux/ptn36502.c
@@ -0,0 +1,421 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NXP PTN36502 Type-C driver
+ *
+ * Copyright (C) 2023 Luca Weiss 
+ *
+ * Based on NB7VPQ904M driver:
+ * Copyright (C) 2023 Dmitry Baryshkov 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PTN36502_CHIP_ID_REG   0x00
+#define PTN36502_CHIP_ID   0x02
+
+#define PTN36502_CHIP_REVISION_REG 0x01
+#define PTN36502_CHIP_REVISION_BASE(val)   FIELD_GET(GENMASK(7, 
4), (val))
+#define PTN36502_CHIP_REVISION_METAL(val)  FIELD_GET(GENMASK(3, 
0), (val))
+
+#define PTN36502_DP_LINK_CTRL_REG  0x06
+#define PTN36502_DP_LINK_CTRL_LANES_2  (2 << 2)
+#define PTN36502_DP_LINK_CTRL_LANES_4  (3 << 2)
+#define PTN36502_DP_LINK_CTRL_LINK_RATE_5_4GBPS(2 << 0)
+
+/* Registers for lane 0 (0x07) to lane 3 (0x0a) have the same layout */
+#define PTN36502_DP_LANE_CTRL_REG(n)   (0x07 + (n))
+#define PTN36502_DP_LANE_CTRL_RX_GAIN_3DB  (2<<4)
+#define PTN36502_DP_LANE_CTRL_TX_SWING_800MVPPD(2<<2)
+#define PTN36502_DP_LANE_CTRL_PRE_EMPHASIS_3_5DB   (1<<0)
+
+#define PTN36502_MODE_CTRL1_REG0x0b
+#define PTN36502_MODE_CTRL1_PLUG_ORIENT_REVERSE(1<<5)
+#define PTN36502_MODE_CTRL1_AUX_CROSSBAR_SW_ON (1<<3)
+#define PTN36502_MODE_CTRL1_MODE_OFF   (0<<0)
+#define PTN36502_MODE_CTRL1_MODE_USB_ONLY  (1<<0)
+#define PTN36502_MODE_CTRL1_MODE_USB_DP(2<<0)
+#define PTN36502_MODE_CTRL1_MODE_DP(3<<0)
+
+#define PTN36502_DEVICE_CTRL_REG   0x0d
+#define PTN36502_DEVICE_CTRL_AUX_MONITORING_EN (1<<7)
+
+struct ptn36502 {
+   struct i2c_client *client;
+   struct regulator *vdd18_supply;
+   struct regmap *regmap;
+   struct typec_switch_dev *sw;
+   struct typec_retimer *retimer;
+
+   struct typec_switch *typec_switch;
+
+   struct drm_bridge bridge;
+
+   struct mutex lock; /* protect non-concurrent retimer & switch */
+
+   enum typec_orientation orientation;
+   unsigned long mode;
+   unsigned int svid;
+};
+
+static int ptn36502_set(struct ptn36502 *ptn)
+{
+   bool reverse = (ptn->orientation == TYPEC_ORIENTATION_REVERSE);
+   unsigned int ctrl1_val = 0;
+   unsigned int lane_ctrl_val = 0;
+   unsigned int link_ctrl_val = 0;
+
+   switch (ptn->mode) {
+   case TYPEC_STATE_SAFE:
+   /* Deep power saving state */
+   regmap_write(ptn->regmap, PTN36502_MODE_CTRL1_REG,
+PTN36502_MODE_CTRL1_MODE_OFF);
+   return 0;
+
+   case TYPEC_STATE_USB:
+   /*
+* Normal Orientation (CC1)
+* A -> USB RX
+* B -> USB TX
+* C -> X
+* D -> X
+* Flipped Orientation (CC2)
+* A -> X
+* B -> X
+* C -> USB TX
+* D -> USB RX
+*/