* [PATCH v2 0/3] usb: typec: tipd: add TPS66993 support
@ 2026-07-02 19:05 Radhey Shyam Pandey
2026-07-02 19:05 ` [PATCH v2 1/3] dt-bindings: usb: ti,tps6598x: add TPS66993 compatible Radhey Shyam Pandey
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Radhey Shyam Pandey @ 2026-07-02 19:05 UTC (permalink / raw)
To: gregkh, robh, krzk+dt, conor+dt, heikki.krogerus
Cc: linux-usb, devicetree, linux-kernel, Radhey Shyam Pandey
This series adds support for the Texas Instruments TPS66993 USB
Type-C / USB PD controller to the tipd driver.
The TPS66993 is used on the AMD Versal AI Edge Gen 2 VEK385
Evaluation Kit as the USB PD DRP controller for the MMI USB
interface, handling CC signaling, connection detection, PD
negotiation, and power/data role swapping. Although the register
interface is largely shared with TPS6598x, the device is not
host-interface compatible and therefore needs its own
"ti,tps66993" compatible.
Changes in this series:
- Document the "ti,tps66993" compatible in the existing
ti,tps6598x binding.
- Introduce a read_power_status() callback in tipd_data so
variants can override how power status is obtained without
changing TPS6598x, CD321x, or TPS25750 behavior.
- Add TPS66993 support.
Changes for v2:
- Use specific device compatible string as suggested by Krzysztof.
- add TPS66993 driver support.
Depends on (submitted separately):
[PATCH v3 0/3] usb: typec: tipd: improve probe diagnostics and POWER_STATUS handling
https://lore.kernel.org/all/20260618074745.629638-1-radhey.shyam.pandey@amd.com
Radhey Shyam Pandey (3):
dt-bindings: usb: ti,tps6598x: add TPS66993 compatible
usb: typec: tipd: add read_power_status callback to tipd_data
usb: typec: tipd: add TPS66993 support
.../devicetree/bindings/usb/ti,tps6598x.yaml | 6 +-
drivers/usb/typec/tipd/core.c | 77 +++++++++++++++++--
2 files changed, 75 insertions(+), 8 deletions(-)
base-commit: 4f441960e691d37c880d2cc004de06bb5b6bd5e4
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v2 1/3] dt-bindings: usb: ti,tps6598x: add TPS66993 compatible 2026-07-02 19:05 [PATCH v2 0/3] usb: typec: tipd: add TPS66993 support Radhey Shyam Pandey @ 2026-07-02 19:05 ` Radhey Shyam Pandey 2026-07-03 7:12 ` Krzysztof Kozlowski 2026-07-02 19:05 ` [PATCH v2 2/3] usb: typec: tipd: add read_power_status callback to tipd_data Radhey Shyam Pandey 2026-07-02 19:05 ` [PATCH v2 3/3] usb: typec: tipd: add TPS66993 support Radhey Shyam Pandey 2 siblings, 1 reply; 8+ messages in thread From: Radhey Shyam Pandey @ 2026-07-02 19:05 UTC (permalink / raw) To: gregkh, robh, krzk+dt, conor+dt, heikki.krogerus Cc: linux-usb, devicetree, linux-kernel, Radhey Shyam Pandey Add a ti,tps66993 compatible to explicitly identify TPS66993 devices. The TPS66993 is not host-interface compatible with TPS6598x, so a distinct compatible is required. On the AMD/Xilinx VEK385 Evaluation Board, the Texas Instruments TPS66993 acts as the USB Type-C/USB PD DRP controller for the MMI USB interface, handling CC signaling, connection detection, PD negotiation and power/data role swapping. Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> --- Changes for v2: - Rename the compatible to match the exact device (ti,tps66993) and in commit mention the usage of TPS66993 chip on VEK385 Evaluation Board. --- Documentation/devicetree/bindings/usb/ti,tps6598x.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/ti,tps6598x.yaml b/Documentation/devicetree/bindings/usb/ti,tps6598x.yaml index 1745e28b3110..2c589e9e712e 100644 --- a/Documentation/devicetree/bindings/usb/ti,tps6598x.yaml +++ b/Documentation/devicetree/bindings/usb/ti,tps6598x.yaml @@ -4,13 +4,14 @@ $id: http://devicetree.org/schemas/usb/ti,tps6598x.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Texas Instruments 6598x Type-C Port Switch and Power Delivery controller +title: Texas Instruments Type-C port switch and USB Power Delivery controllers maintainers: - Bryan O'Donoghue <bryan.odonoghue@linaro.org> description: | - Texas Instruments 6598x Type-C Port Switch and Power Delivery controller + Texas Instruments 6598x and 66993 Type-C Port Switch and Power Delivery + controller. A variant of this controller known as Apple CD321x or Apple ACE is also present on hardware with Apple SoCs such as the M1. @@ -19,6 +20,7 @@ properties: compatible: enum: - ti,tps6598x + - ti,tps66993 - apple,cd321x - ti,tps25750 -- 2.43.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/3] dt-bindings: usb: ti,tps6598x: add TPS66993 compatible 2026-07-02 19:05 ` [PATCH v2 1/3] dt-bindings: usb: ti,tps6598x: add TPS66993 compatible Radhey Shyam Pandey @ 2026-07-03 7:12 ` Krzysztof Kozlowski 0 siblings, 0 replies; 8+ messages in thread From: Krzysztof Kozlowski @ 2026-07-03 7:12 UTC (permalink / raw) To: Radhey Shyam Pandey Cc: gregkh, robh, krzk+dt, conor+dt, heikki.krogerus, linux-usb, devicetree, linux-kernel On Fri, Jul 03, 2026 at 12:35:25AM +0530, Radhey Shyam Pandey wrote: > Add a ti,tps66993 compatible to explicitly identify TPS66993 devices. > The TPS66993 is not host-interface compatible with TPS6598x, so a distinct > compatible is required. > > On the AMD/Xilinx VEK385 Evaluation Board, the Texas Instruments TPS66993 > acts as the USB Type-C/USB PD DRP controller for the MMI USB interface, > handling CC signaling, connection detection, PD negotiation and power/data > role swapping. > > Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> > --- > Changes for v2: > - Rename the compatible to match the exact device (ti,tps66993) and in > commit mention the usage of TPS66993 chip on VEK385 Evaluation Board. Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Best regards, Krzysztof ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/3] usb: typec: tipd: add read_power_status callback to tipd_data 2026-07-02 19:05 [PATCH v2 0/3] usb: typec: tipd: add TPS66993 support Radhey Shyam Pandey 2026-07-02 19:05 ` [PATCH v2 1/3] dt-bindings: usb: ti,tps6598x: add TPS66993 compatible Radhey Shyam Pandey @ 2026-07-02 19:05 ` Radhey Shyam Pandey 2026-07-03 15:14 ` Heikki Krogerus 2026-07-02 19:05 ` [PATCH v2 3/3] usb: typec: tipd: add TPS66993 support Radhey Shyam Pandey 2 siblings, 1 reply; 8+ messages in thread From: Radhey Shyam Pandey @ 2026-07-02 19:05 UTC (permalink / raw) To: gregkh, robh, krzk+dt, conor+dt, heikki.krogerus Cc: linux-usb, devicetree, linux-kernel, Radhey Shyam Pandey Convert direct tps6598x_read_power_status() calls to use an indirect read_power_status callback through tipd_data. This allows variants (e.g. TPS66993) to provide their own power status reading logic while keeping existing behavior unchanged for TPS6598x, CD321x, and TPS25750. Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> --- Changes for v2: - New patch to add TPS66993 driver support. --- drivers/usb/typec/tipd/core.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index d5ee0af9058b..a6cb233a055d 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -159,6 +159,7 @@ struct tipd_data { int (*init)(struct tps6598x *tps); int (*switch_power_state)(struct tps6598x *tps, u8 target_state); bool (*read_data_status)(struct tps6598x *tps); + bool (*read_power_status)(struct tps6598x *tps); int (*reset)(struct tps6598x *tps); int (*connect)(struct tps6598x *tps, u32 status); }; @@ -897,7 +898,7 @@ static irqreturn_t cd321x_interrupt(int irq, void *data) goto err_unlock; if (event & APPLE_CD_REG_INT_POWER_STATUS_UPDATE) { - if (!tps6598x_read_power_status(tps)) + if (!tps->data->read_power_status(tps)) goto err_unlock; if (TPS_POWER_STATUS_PWROPMODE(tps->pwr_status) == TYPEC_PWR_MODE_PD) { if (tps6598x_read_partner_identity(tps)) { @@ -952,7 +953,7 @@ static irqreturn_t tps25750_interrupt(int irq, void *data) goto err_clear_ints; if (event[0] & TPS_REG_INT_POWER_STATUS_UPDATE) - if (!tps6598x_read_power_status(tps)) + if (!tps->data->read_power_status(tps)) goto err_clear_ints; if (event[0] & TPS_REG_INT_DATA_STATUS_UPDATE) @@ -1026,7 +1027,7 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) goto err_unlock; if ((event1[0] | event2[0]) & TPS_REG_INT_POWER_STATUS_UPDATE) - if (!tps6598x_read_power_status(tps)) + if (!tps->data->read_power_status(tps)) goto err_unlock; if ((event1[0] | event2[0]) & TPS_REG_INT_DATA_STATUS_UPDATE) @@ -1836,7 +1837,7 @@ static int tps6598x_probe(struct i2c_client *client) if (status & TPS_STATUS_PLUG_PRESENT) { ret = -EINVAL; - if (!tps6598x_read_power_status(tps)) + if (!tps->data->read_power_status(tps)) goto err_unregister_port; if (!tps->data->read_data_status(tps)) goto err_unregister_port; @@ -1978,6 +1979,7 @@ static const struct tipd_data cd321x_data = { .trace_status = trace_tps6598x_status, .init = cd321x_init, .read_data_status = cd321x_read_data_status, + .read_power_status = tps6598x_read_power_status, .reset = cd321x_reset, .switch_power_state = cd321x_switch_power_state, .connect = cd321x_connect, @@ -1997,6 +1999,7 @@ static const struct tipd_data tps6598x_data = { .apply_patch = tps6598x_apply_patch, .init = tps6598x_init, .read_data_status = tps6598x_read_data_status, + .read_power_status = tps6598x_read_power_status, .reset = tps6598x_reset, .connect = tps6598x_connect, }; @@ -2015,6 +2018,7 @@ static const struct tipd_data tps25750_data = { .apply_patch = tps25750_apply_patch, .init = tps25750_init, .read_data_status = tps6598x_read_data_status, + .read_power_status = tps6598x_read_power_status, .reset = tps25750_reset, .connect = tps6598x_connect, }; -- 2.43.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] usb: typec: tipd: add read_power_status callback to tipd_data 2026-07-02 19:05 ` [PATCH v2 2/3] usb: typec: tipd: add read_power_status callback to tipd_data Radhey Shyam Pandey @ 2026-07-03 15:14 ` Heikki Krogerus 0 siblings, 0 replies; 8+ messages in thread From: Heikki Krogerus @ 2026-07-03 15:14 UTC (permalink / raw) To: Radhey Shyam Pandey Cc: gregkh, robh, krzk+dt, conor+dt, linux-usb, devicetree, linux-kernel On Fri, Jul 03, 2026 at 12:35:26AM +0530, Radhey Shyam Pandey wrote: > Convert direct tps6598x_read_power_status() calls to use an indirect > read_power_status callback through tipd_data. This allows variants > (e.g. TPS66993) to provide their own power status reading logic while > keeping existing behavior unchanged for TPS6598x, CD321x, and TPS25750. > > Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > --- > Changes for v2: > - New patch to add TPS66993 driver support. > --- > drivers/usb/typec/tipd/core.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c > index d5ee0af9058b..a6cb233a055d 100644 > --- a/drivers/usb/typec/tipd/core.c > +++ b/drivers/usb/typec/tipd/core.c > @@ -159,6 +159,7 @@ struct tipd_data { > int (*init)(struct tps6598x *tps); > int (*switch_power_state)(struct tps6598x *tps, u8 target_state); > bool (*read_data_status)(struct tps6598x *tps); > + bool (*read_power_status)(struct tps6598x *tps); > int (*reset)(struct tps6598x *tps); > int (*connect)(struct tps6598x *tps, u32 status); > }; > @@ -897,7 +898,7 @@ static irqreturn_t cd321x_interrupt(int irq, void *data) > goto err_unlock; > > if (event & APPLE_CD_REG_INT_POWER_STATUS_UPDATE) { > - if (!tps6598x_read_power_status(tps)) > + if (!tps->data->read_power_status(tps)) > goto err_unlock; > if (TPS_POWER_STATUS_PWROPMODE(tps->pwr_status) == TYPEC_PWR_MODE_PD) { > if (tps6598x_read_partner_identity(tps)) { > @@ -952,7 +953,7 @@ static irqreturn_t tps25750_interrupt(int irq, void *data) > goto err_clear_ints; > > if (event[0] & TPS_REG_INT_POWER_STATUS_UPDATE) > - if (!tps6598x_read_power_status(tps)) > + if (!tps->data->read_power_status(tps)) > goto err_clear_ints; > > if (event[0] & TPS_REG_INT_DATA_STATUS_UPDATE) > @@ -1026,7 +1027,7 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) > goto err_unlock; > > if ((event1[0] | event2[0]) & TPS_REG_INT_POWER_STATUS_UPDATE) > - if (!tps6598x_read_power_status(tps)) > + if (!tps->data->read_power_status(tps)) > goto err_unlock; > > if ((event1[0] | event2[0]) & TPS_REG_INT_DATA_STATUS_UPDATE) > @@ -1836,7 +1837,7 @@ static int tps6598x_probe(struct i2c_client *client) > > if (status & TPS_STATUS_PLUG_PRESENT) { > ret = -EINVAL; > - if (!tps6598x_read_power_status(tps)) > + if (!tps->data->read_power_status(tps)) > goto err_unregister_port; > if (!tps->data->read_data_status(tps)) > goto err_unregister_port; > @@ -1978,6 +1979,7 @@ static const struct tipd_data cd321x_data = { > .trace_status = trace_tps6598x_status, > .init = cd321x_init, > .read_data_status = cd321x_read_data_status, > + .read_power_status = tps6598x_read_power_status, > .reset = cd321x_reset, > .switch_power_state = cd321x_switch_power_state, > .connect = cd321x_connect, > @@ -1997,6 +1999,7 @@ static const struct tipd_data tps6598x_data = { > .apply_patch = tps6598x_apply_patch, > .init = tps6598x_init, > .read_data_status = tps6598x_read_data_status, > + .read_power_status = tps6598x_read_power_status, > .reset = tps6598x_reset, > .connect = tps6598x_connect, > }; > @@ -2015,6 +2018,7 @@ static const struct tipd_data tps25750_data = { > .apply_patch = tps25750_apply_patch, > .init = tps25750_init, > .read_data_status = tps6598x_read_data_status, > + .read_power_status = tps6598x_read_power_status, > .reset = tps25750_reset, > .connect = tps6598x_connect, > }; > -- > 2.43.0 -- heikki ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 3/3] usb: typec: tipd: add TPS66993 support 2026-07-02 19:05 [PATCH v2 0/3] usb: typec: tipd: add TPS66993 support Radhey Shyam Pandey 2026-07-02 19:05 ` [PATCH v2 1/3] dt-bindings: usb: ti,tps6598x: add TPS66993 compatible Radhey Shyam Pandey 2026-07-02 19:05 ` [PATCH v2 2/3] usb: typec: tipd: add read_power_status callback to tipd_data Radhey Shyam Pandey @ 2026-07-02 19:05 ` Radhey Shyam Pandey 2026-07-03 15:17 ` Heikki Krogerus 2 siblings, 1 reply; 8+ messages in thread From: Radhey Shyam Pandey @ 2026-07-02 19:05 UTC (permalink / raw) To: gregkh, robh, krzk+dt, conor+dt, heikki.krogerus Cc: linux-usb, devicetree, linux-kernel, Radhey Shyam Pandey Derive power status from the STATUS register (0x1A) now that TPS66993 deprecates the Power_Status register (0x3F). Add support for the "APP1" mode string. TPS66993 controller is configured in polling mode and only type-c flip orientation feature is supported on AMD Versal AI Edge Gen 2 VEK385 Evaluation Kit. Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> --- Changes for v2: - New patch to add TPS66993 driver support. --- drivers/usb/typec/tipd/core.c | 65 +++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index a6cb233a055d..d2394d23a2dc 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -130,6 +130,7 @@ enum { TPS_MODE_BIST, TPS_MODE_DISC, TPS_MODE_PTCH, + TPS_MODE_APP1, }; static const char *const modes[] = { @@ -138,6 +139,7 @@ static const char *const modes[] = { [TPS_MODE_BIST] = "BIST", [TPS_MODE_DISC] = "DISC", [TPS_MODE_PTCH] = "PTCH", + [TPS_MODE_APP1] = "APP1", }; /* Unrecognized commands will be replaced with "!CMD" */ @@ -631,6 +633,35 @@ static bool tps6598x_read_power_status(struct tps6598x *tps) return true; } +/* + * TPS66993 deprecated Power_Status register (0x3F). BC1.2 is not supported + * and the remaining bits are redundant with STATUS register (0x1A). + * Synthesize pwr_status from the already-read STATUS register. + */ +static bool tps66993_read_power_status(struct tps6598x *tps) +{ + u16 pwr_status = 0; + + /* Same masks as TPS_POWER_STATUS_CONNECTION() / SOURCESINK() / PWROPMODE() in tps6598x.h */ + if (tps->status & TPS_STATUS_PLUG_PRESENT) + pwr_status |= FIELD_PREP(TPS_POWER_STATUS_CONNECTION_MASK, 1); + + /* SOURCESINK: 1=sink; STATUS.PortRole 1=source, opposite convention */ + if (!TPS_STATUS_TO_TYPEC_PORTROLE(tps->status)) + pwr_status |= FIELD_PREP(TPS_POWER_STATUS_SOURCESINK_MASK, 1); + + if (TPS_STATUS_VBUS_STATUS(tps->status) == TPS_STATUS_VBUS_STATUS_PD) + pwr_status |= FIELD_PREP(TPS_POWER_STATUS_TYPEC_CURRENT_MASK, + TPS_POWER_STATUS_TYPEC_CURRENT_PD); + + tps->pwr_status = pwr_status; + + if (tps->data->trace_power_status) + tps->data->trace_power_status(pwr_status); + + return true; +} + static void tps6598x_handle_plug_event(struct tps6598x *tps, u32 status) { int ret; @@ -1026,6 +1057,8 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) if (!tps6598x_read_status(tps, &status)) goto err_unlock; + tps->status = status; + if ((event1[0] | event2[0]) & TPS_REG_INT_POWER_STATUS_UPDATE) if (!tps->data->read_power_status(tps)) goto err_unlock; @@ -1034,9 +1067,15 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) if (!tps->data->read_data_status(tps)) goto err_unlock; - /* Handle plug insert or removal */ - if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT) + /* + * Refresh power status before connect - needed for TPS66993 which + * synthesizes pwr_status from STATUS and never gets POWER_STATUS_UPDATE. + */ + if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT) { + if (!tps->data->read_power_status(tps)) + goto err_unlock; tps6598x_handle_plug_event(tps, status); + } err_unlock: mutex_unlock(&tps->lock); @@ -1072,6 +1111,7 @@ static int tps6598x_check_mode(struct tps6598x *tps) switch (ret) { case TPS_MODE_APP: + case TPS_MODE_APP1: case TPS_MODE_PTCH: return ret; case TPS_MODE_BOOT: @@ -1810,6 +1850,8 @@ static int tps6598x_probe(struct i2c_client *client) goto err_clear_mask; } + tps->status = status; + /* * This fwnode has a "compatible" property, but is never populated as a * struct device. Instead we simply parse it to read the properties. @@ -2004,6 +2046,24 @@ static const struct tipd_data tps6598x_data = { .connect = tps6598x_connect, }; +static const struct tipd_data tps66993_data = { + .irq_handler = tps6598x_interrupt, + .irq_mask1 = TPS_REG_INT_DATA_STATUS_UPDATE | + TPS_REG_INT_PLUG_EVENT, + .tps_struct_size = sizeof(struct tps6598x), + .register_port = tps6598x_register_port, + .unregister_port = tps6598x_unregister_port, + .trace_data_status = trace_tps6598x_data_status, + .trace_power_status = trace_tps6598x_power_status, + .trace_status = trace_tps6598x_status, + .apply_patch = tps6598x_apply_patch, + .init = tps6598x_init, + .read_data_status = tps6598x_read_data_status, + .read_power_status = tps66993_read_power_status, + .reset = tps6598x_reset, + .connect = tps6598x_connect, +}; + static const struct tipd_data tps25750_data = { .irq_handler = tps25750_interrupt, .irq_mask1 = TPS_REG_INT_POWER_STATUS_UPDATE | @@ -2025,6 +2085,7 @@ static const struct tipd_data tps25750_data = { static const struct of_device_id tps6598x_of_match[] = { { .compatible = "ti,tps6598x", &tps6598x_data}, + { .compatible = "ti,tps66993", &tps66993_data}, { .compatible = "apple,cd321x", &cd321x_data}, { .compatible = "ti,tps25750", &tps25750_data}, {} -- 2.43.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 3/3] usb: typec: tipd: add TPS66993 support 2026-07-02 19:05 ` [PATCH v2 3/3] usb: typec: tipd: add TPS66993 support Radhey Shyam Pandey @ 2026-07-03 15:17 ` Heikki Krogerus 2026-07-08 17:34 ` Pandey, Radhey Shyam 0 siblings, 1 reply; 8+ messages in thread From: Heikki Krogerus @ 2026-07-03 15:17 UTC (permalink / raw) To: Radhey Shyam Pandey Cc: gregkh, robh, krzk+dt, conor+dt, linux-usb, devicetree, linux-kernel Hi Radhey, On Fri, Jul 03, 2026 at 12:35:27AM +0530, Radhey Shyam Pandey wrote: > Derive power status from the STATUS register (0x1A) now that TPS66993 > deprecates the Power_Status register (0x3F). Add support for the "APP1" > mode string. TPS66993 controller is configured in polling mode and only > type-c flip orientation feature is supported on AMD Versal AI Edge Gen 2 > VEK385 Evaluation Kit. > > Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> > --- > Changes for v2: > - New patch to add TPS66993 driver support. > --- > drivers/usb/typec/tipd/core.c | 65 +++++++++++++++++++++++++++++++++-- > 1 file changed, 63 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c > index a6cb233a055d..d2394d23a2dc 100644 > --- a/drivers/usb/typec/tipd/core.c > +++ b/drivers/usb/typec/tipd/core.c > @@ -130,6 +130,7 @@ enum { > TPS_MODE_BIST, > TPS_MODE_DISC, > TPS_MODE_PTCH, > + TPS_MODE_APP1, > }; > > static const char *const modes[] = { > @@ -138,6 +139,7 @@ static const char *const modes[] = { > [TPS_MODE_BIST] = "BIST", > [TPS_MODE_DISC] = "DISC", > [TPS_MODE_PTCH] = "PTCH", > + [TPS_MODE_APP1] = "APP1", > }; > > /* Unrecognized commands will be replaced with "!CMD" */ > @@ -631,6 +633,35 @@ static bool tps6598x_read_power_status(struct tps6598x *tps) > return true; > } > > +/* > + * TPS66993 deprecated Power_Status register (0x3F). BC1.2 is not supported > + * and the remaining bits are redundant with STATUS register (0x1A). > + * Synthesize pwr_status from the already-read STATUS register. > + */ > +static bool tps66993_read_power_status(struct tps6598x *tps) > +{ > + u16 pwr_status = 0; > + > + /* Same masks as TPS_POWER_STATUS_CONNECTION() / SOURCESINK() / PWROPMODE() in tps6598x.h */ > + if (tps->status & TPS_STATUS_PLUG_PRESENT) > + pwr_status |= FIELD_PREP(TPS_POWER_STATUS_CONNECTION_MASK, 1); > + > + /* SOURCESINK: 1=sink; STATUS.PortRole 1=source, opposite convention */ > + if (!TPS_STATUS_TO_TYPEC_PORTROLE(tps->status)) > + pwr_status |= FIELD_PREP(TPS_POWER_STATUS_SOURCESINK_MASK, 1); > + > + if (TPS_STATUS_VBUS_STATUS(tps->status) == TPS_STATUS_VBUS_STATUS_PD) > + pwr_status |= FIELD_PREP(TPS_POWER_STATUS_TYPEC_CURRENT_MASK, > + TPS_POWER_STATUS_TYPEC_CURRENT_PD); > + > + tps->pwr_status = pwr_status; > + > + if (tps->data->trace_power_status) > + tps->data->trace_power_status(pwr_status); Is the condition necesary? Is it possible to get here without that callback? Thanks, > + return true; > +} > + > static void tps6598x_handle_plug_event(struct tps6598x *tps, u32 status) > { > int ret; > @@ -1026,6 +1057,8 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) > if (!tps6598x_read_status(tps, &status)) > goto err_unlock; > > + tps->status = status; > + > if ((event1[0] | event2[0]) & TPS_REG_INT_POWER_STATUS_UPDATE) > if (!tps->data->read_power_status(tps)) > goto err_unlock; > @@ -1034,9 +1067,15 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) > if (!tps->data->read_data_status(tps)) > goto err_unlock; > > - /* Handle plug insert or removal */ > - if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT) > + /* > + * Refresh power status before connect - needed for TPS66993 which > + * synthesizes pwr_status from STATUS and never gets POWER_STATUS_UPDATE. > + */ > + if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT) { > + if (!tps->data->read_power_status(tps)) > + goto err_unlock; > tps6598x_handle_plug_event(tps, status); > + } > > err_unlock: > mutex_unlock(&tps->lock); > @@ -1072,6 +1111,7 @@ static int tps6598x_check_mode(struct tps6598x *tps) > > switch (ret) { > case TPS_MODE_APP: > + case TPS_MODE_APP1: > case TPS_MODE_PTCH: > return ret; > case TPS_MODE_BOOT: > @@ -1810,6 +1850,8 @@ static int tps6598x_probe(struct i2c_client *client) > goto err_clear_mask; > } > > + tps->status = status; > + > /* > * This fwnode has a "compatible" property, but is never populated as a > * struct device. Instead we simply parse it to read the properties. > @@ -2004,6 +2046,24 @@ static const struct tipd_data tps6598x_data = { > .connect = tps6598x_connect, > }; > > +static const struct tipd_data tps66993_data = { > + .irq_handler = tps6598x_interrupt, > + .irq_mask1 = TPS_REG_INT_DATA_STATUS_UPDATE | > + TPS_REG_INT_PLUG_EVENT, > + .tps_struct_size = sizeof(struct tps6598x), > + .register_port = tps6598x_register_port, > + .unregister_port = tps6598x_unregister_port, > + .trace_data_status = trace_tps6598x_data_status, > + .trace_power_status = trace_tps6598x_power_status, > + .trace_status = trace_tps6598x_status, > + .apply_patch = tps6598x_apply_patch, > + .init = tps6598x_init, > + .read_data_status = tps6598x_read_data_status, > + .read_power_status = tps66993_read_power_status, > + .reset = tps6598x_reset, > + .connect = tps6598x_connect, > +}; > + > static const struct tipd_data tps25750_data = { > .irq_handler = tps25750_interrupt, > .irq_mask1 = TPS_REG_INT_POWER_STATUS_UPDATE | > @@ -2025,6 +2085,7 @@ static const struct tipd_data tps25750_data = { > > static const struct of_device_id tps6598x_of_match[] = { > { .compatible = "ti,tps6598x", &tps6598x_data}, > + { .compatible = "ti,tps66993", &tps66993_data}, > { .compatible = "apple,cd321x", &cd321x_data}, > { .compatible = "ti,tps25750", &tps25750_data}, > {} > -- > 2.43.0 -- heikki ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 3/3] usb: typec: tipd: add TPS66993 support 2026-07-03 15:17 ` Heikki Krogerus @ 2026-07-08 17:34 ` Pandey, Radhey Shyam 0 siblings, 0 replies; 8+ messages in thread From: Pandey, Radhey Shyam @ 2026-07-08 17:34 UTC (permalink / raw) To: Heikki Krogerus, Radhey Shyam Pandey Cc: gregkh, robh, krzk+dt, conor+dt, linux-usb, devicetree, linux-kernel > Hi Radhey, > > On Fri, Jul 03, 2026 at 12:35:27AM +0530, Radhey Shyam Pandey wrote: >> Derive power status from the STATUS register (0x1A) now that TPS66993 >> deprecates the Power_Status register (0x3F). Add support for the "APP1" >> mode string. TPS66993 controller is configured in polling mode and only >> type-c flip orientation feature is supported on AMD Versal AI Edge Gen 2 >> VEK385 Evaluation Kit. >> >> Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> >> --- >> Changes for v2: >> - New patch to add TPS66993 driver support. >> --- >> drivers/usb/typec/tipd/core.c | 65 +++++++++++++++++++++++++++++++++-- >> 1 file changed, 63 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c >> index a6cb233a055d..d2394d23a2dc 100644 >> --- a/drivers/usb/typec/tipd/core.c >> +++ b/drivers/usb/typec/tipd/core.c >> @@ -130,6 +130,7 @@ enum { >> TPS_MODE_BIST, >> TPS_MODE_DISC, >> TPS_MODE_PTCH, >> + TPS_MODE_APP1, >> }; >> >> static const char *const modes[] = { >> @@ -138,6 +139,7 @@ static const char *const modes[] = { >> [TPS_MODE_BIST] = "BIST", >> [TPS_MODE_DISC] = "DISC", >> [TPS_MODE_PTCH] = "PTCH", >> + [TPS_MODE_APP1] = "APP1", >> }; >> >> /* Unrecognized commands will be replaced with "!CMD" */ >> @@ -631,6 +633,35 @@ static bool tps6598x_read_power_status(struct tps6598x *tps) >> return true; >> } >> >> +/* >> + * TPS66993 deprecated Power_Status register (0x3F). BC1.2 is not supported >> + * and the remaining bits are redundant with STATUS register (0x1A). >> + * Synthesize pwr_status from the already-read STATUS register. >> + */ >> +static bool tps66993_read_power_status(struct tps6598x *tps) >> +{ >> + u16 pwr_status = 0; >> + >> + /* Same masks as TPS_POWER_STATUS_CONNECTION() / SOURCESINK() / PWROPMODE() in tps6598x.h */ >> + if (tps->status & TPS_STATUS_PLUG_PRESENT) >> + pwr_status |= FIELD_PREP(TPS_POWER_STATUS_CONNECTION_MASK, 1); >> + >> + /* SOURCESINK: 1=sink; STATUS.PortRole 1=source, opposite convention */ >> + if (!TPS_STATUS_TO_TYPEC_PORTROLE(tps->status)) >> + pwr_status |= FIELD_PREP(TPS_POWER_STATUS_SOURCESINK_MASK, 1); >> + >> + if (TPS_STATUS_VBUS_STATUS(tps->status) == TPS_STATUS_VBUS_STATUS_PD) >> + pwr_status |= FIELD_PREP(TPS_POWER_STATUS_TYPEC_CURRENT_MASK, >> + TPS_POWER_STATUS_TYPEC_CURRENT_PD); >> + >> + tps->pwr_status = pwr_status; >> + >> + if (tps->data->trace_power_status) >> + tps->data->trace_power_status(pwr_status); > > Is the condition necesary? Is it possible to get here without that > callback? > Thanks for the review . Valid point will remove the if() and call trace_power_status() directly and spin out v3 soon. Thanks, Radhey> Thanks, > >> + return true; >> +} >> + >> static void tps6598x_handle_plug_event(struct tps6598x *tps, u32 status) >> { >> int ret; >> @@ -1026,6 +1057,8 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) >> if (!tps6598x_read_status(tps, &status)) >> goto err_unlock; >> >> + tps->status = status; >> + >> if ((event1[0] | event2[0]) & TPS_REG_INT_POWER_STATUS_UPDATE) >> if (!tps->data->read_power_status(tps)) >> goto err_unlock; >> @@ -1034,9 +1067,15 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) >> if (!tps->data->read_data_status(tps)) >> goto err_unlock; >> >> - /* Handle plug insert or removal */ >> - if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT) >> + /* >> + * Refresh power status before connect - needed for TPS66993 which >> + * synthesizes pwr_status from STATUS and never gets POWER_STATUS_UPDATE. >> + */ >> + if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT) { >> + if (!tps->data->read_power_status(tps)) >> + goto err_unlock; >> tps6598x_handle_plug_event(tps, status); >> + } >> >> err_unlock: >> mutex_unlock(&tps->lock); >> @@ -1072,6 +1111,7 @@ static int tps6598x_check_mode(struct tps6598x *tps) >> >> switch (ret) { >> case TPS_MODE_APP: >> + case TPS_MODE_APP1: >> case TPS_MODE_PTCH: >> return ret; >> case TPS_MODE_BOOT: >> @@ -1810,6 +1850,8 @@ static int tps6598x_probe(struct i2c_client *client) >> goto err_clear_mask; >> } >> >> + tps->status = status; >> + >> /* >> * This fwnode has a "compatible" property, but is never populated as a >> * struct device. Instead we simply parse it to read the properties. >> @@ -2004,6 +2046,24 @@ static const struct tipd_data tps6598x_data = { >> .connect = tps6598x_connect, >> }; >> >> +static const struct tipd_data tps66993_data = { >> + .irq_handler = tps6598x_interrupt, >> + .irq_mask1 = TPS_REG_INT_DATA_STATUS_UPDATE | >> + TPS_REG_INT_PLUG_EVENT, >> + .tps_struct_size = sizeof(struct tps6598x), >> + .register_port = tps6598x_register_port, >> + .unregister_port = tps6598x_unregister_port, >> + .trace_data_status = trace_tps6598x_data_status, >> + .trace_power_status = trace_tps6598x_power_status, >> + .trace_status = trace_tps6598x_status, >> + .apply_patch = tps6598x_apply_patch, >> + .init = tps6598x_init, >> + .read_data_status = tps6598x_read_data_status, >> + .read_power_status = tps66993_read_power_status, >> + .reset = tps6598x_reset, >> + .connect = tps6598x_connect, >> +}; >> + >> static const struct tipd_data tps25750_data = { >> .irq_handler = tps25750_interrupt, >> .irq_mask1 = TPS_REG_INT_POWER_STATUS_UPDATE | >> @@ -2025,6 +2085,7 @@ static const struct tipd_data tps25750_data = { >> >> static const struct of_device_id tps6598x_of_match[] = { >> { .compatible = "ti,tps6598x", &tps6598x_data}, >> + { .compatible = "ti,tps66993", &tps66993_data}, >> { .compatible = "apple,cd321x", &cd321x_data}, >> { .compatible = "ti,tps25750", &tps25750_data}, >> {} >> -- >> 2.43.0 > ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-07-08 17:34 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-02 19:05 [PATCH v2 0/3] usb: typec: tipd: add TPS66993 support Radhey Shyam Pandey 2026-07-02 19:05 ` [PATCH v2 1/3] dt-bindings: usb: ti,tps6598x: add TPS66993 compatible Radhey Shyam Pandey 2026-07-03 7:12 ` Krzysztof Kozlowski 2026-07-02 19:05 ` [PATCH v2 2/3] usb: typec: tipd: add read_power_status callback to tipd_data Radhey Shyam Pandey 2026-07-03 15:14 ` Heikki Krogerus 2026-07-02 19:05 ` [PATCH v2 3/3] usb: typec: tipd: add TPS66993 support Radhey Shyam Pandey 2026-07-03 15:17 ` Heikki Krogerus 2026-07-08 17:34 ` Pandey, Radhey Shyam
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox