* [PATCH RFC 0/2] drm: bridge: anx7625: implement Type-C support
@ 2025-11-26 9:41 Dmitry Baryshkov
2025-11-26 9:41 ` [PATCH RFC 1/2] dt-bindings: drm/bridge: anx7625: describe Type-C connector Dmitry Baryshkov
2025-11-26 9:41 ` [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support Dmitry Baryshkov
0 siblings, 2 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-11-26 9:41 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Xin Ji, Heikki Krogerus,
Greg Kroah-Hartman
Cc: dri-devel, devicetree, linux-usb, linux-arm-msm, linux-kernel
ANX7625 can be used to mux converted video stream with the USB signals
on a Type-C connector. Provide minimal Type-C support necessary for
ANX7625 to register the Type-C port device and properly respond to data
/ power role events from the Type-C partner.
Notes:
- I'm not 100% happy having Type-C code in the DRM subtree. Should I use
AUX device and to move Type-C-related code to drivers/usb/typec?
- Current code doesn't register a Type-C partner device. Would it be
okay or should it be registered?
- The code to change data / power roles from the device isn't a part of
the series, I'll include it once we settle on the first two items.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Dmitry Baryshkov (2):
dt-bindings: drm/bridge: anx7625: describe Type-C connector
drm: bridge: anx7625: implement minimal Type-C support
.../bindings/display/bridge/analogix,anx7625.yaml | 98 ++++++++++++-
drivers/gpu/drm/bridge/analogix/Kconfig | 1 +
drivers/gpu/drm/bridge/analogix/anx7625.c | 163 ++++++++++++++++++++-
drivers/gpu/drm/bridge/analogix/anx7625.h | 21 ++-
4 files changed, 272 insertions(+), 11 deletions(-)
---
base-commit: 92fd6e84175befa1775e5c0ab682938eca27c0b2
change-id: 20251126-anx7625-typec-07d455f423da
Best regards,
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH RFC 1/2] dt-bindings: drm/bridge: anx7625: describe Type-C connector
2025-11-26 9:41 [PATCH RFC 0/2] drm: bridge: anx7625: implement Type-C support Dmitry Baryshkov
@ 2025-11-26 9:41 ` Dmitry Baryshkov
2025-11-26 9:41 ` [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support Dmitry Baryshkov
1 sibling, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-11-26 9:41 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Xin Ji, Heikki Krogerus,
Greg Kroah-Hartman
Cc: dri-devel, devicetree, linux-usb, linux-arm-msm, linux-kernel
ANX7625 can be used to mux converted video stream with the USB signals
on a Type-C connector. Describe the optional connector subnode, make it
exclusive with the AUX bus and port@1 as it is impossible to have both
eDP panel and USB-C connector.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
.../bindings/display/bridge/analogix,anx7625.yaml | 98 +++++++++++++++++++++-
1 file changed, 97 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
index a1ed1004651b9a8c13474d8a3cda153a4ae6d210..6ad466952c02dbba0b1dd9b7de11e56514a438e1 100644
--- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
@@ -85,6 +85,11 @@ properties:
aux-bus:
$ref: /schemas/display/dp-aux-bus.yaml#
+ connector:
+ type: object
+ $ref: /schemas/connector/usb-connector.yaml#
+ unevaluatedProperties: false
+
ports:
$ref: /schemas/graph.yaml#/properties/ports
@@ -117,7 +122,6 @@ properties:
required:
- port@0
- - port@1
required:
- compatible
@@ -127,6 +131,28 @@ required:
- vdd33-supply
- ports
+allOf:
+ - if:
+ required:
+ - aux-bus
+ - connector
+ then:
+ false
+
+ - if:
+ required:
+ - connector
+ then:
+ properties:
+ ports:
+ properties:
+ port@1: false
+ else:
+ properties:
+ ports:
+ required:
+ - port@1
+
additionalProperties: false
examples:
@@ -185,3 +211,73 @@ examples:
};
};
};
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ encoder@58 {
+ compatible = "analogix,anx7625";
+ reg = <0x58>;
+ enable-gpios = <&pio 45 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&pio 73 GPIO_ACTIVE_HIGH>;
+ vdd10-supply = <&pp1000_mipibrdg>;
+ vdd18-supply = <&pp1800_mipibrdg>;
+ vdd33-supply = <&pp3300_mipibrdg>;
+ analogix,audio-enable;
+ analogix,lane0-swing = /bits/ 8 <0x14 0x54 0x64 0x74>;
+ analogix,lane1-swing = /bits/ 8 <0x14 0x54 0x64 0x74>;
+
+ connector {
+ compatible = "usb-c-connector";
+ power-role = "dual";
+ data-role = "dual";
+ vbus-supply = <&vbus_reg>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ endpoint {
+ remote-endpoint = <&usb_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ endpoint {
+ remote-endpoint = <&usb_ss>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ endpoint {
+ remote-endpoint = <&usb_sbu>;
+ };
+ };
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ endpoint {
+ remote-endpoint = <&mipi_dsi>;
+ bus-type = <7>;
+ data-lanes = <0 1 2 3>;
+ };
+ };
+ };
+ };
+ };
--
2.47.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support
2025-11-26 9:41 [PATCH RFC 0/2] drm: bridge: anx7625: implement Type-C support Dmitry Baryshkov
2025-11-26 9:41 ` [PATCH RFC 1/2] dt-bindings: drm/bridge: anx7625: describe Type-C connector Dmitry Baryshkov
@ 2025-11-26 9:41 ` Dmitry Baryshkov
2025-12-04 13:15 ` Heikki Krogerus
2025-12-12 13:17 ` Xin Ji
1 sibling, 2 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-11-26 9:41 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Xin Ji, Heikki Krogerus,
Greg Kroah-Hartman
Cc: dri-devel, devicetree, linux-usb, linux-arm-msm, linux-kernel
ANX7625 can be used as a USB-C controller, handling USB and DP data
streams. Provide minimal Type-C support necessary for ANX7625 to
register the Type-C port device and properly respond to data / power
role events from the Type-C partner.
While ANX7625 provides TCPCI interface, using it would circumvent the
on-chip running firmware. Analogix recommended using the higher-level
interface instead of TCPCI.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/bridge/analogix/Kconfig | 1 +
drivers/gpu/drm/bridge/analogix/anx7625.c | 163 ++++++++++++++++++++++++++++--
drivers/gpu/drm/bridge/analogix/anx7625.h | 21 +++-
3 files changed, 175 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig
index 4846b2e9be7c2a5da18f6a3cdec53ef5766455e0..f3448b0631fea42e7e7ab10368777a93ce33cee7 100644
--- a/drivers/gpu/drm/bridge/analogix/Kconfig
+++ b/drivers/gpu/drm/bridge/analogix/Kconfig
@@ -34,6 +34,7 @@ config DRM_ANALOGIX_ANX7625
tristate "Analogix Anx7625 MIPI to DP interface support"
depends on DRM
depends on OF
+ depends on TYPEC || !TYPEC
select DRM_DISPLAY_DP_HELPER
select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 6f3fdcb6afdb9d785bc4515300676cf3988c5807..a44405db739669dfd2907b0afd41293a7b173035 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -3,6 +3,7 @@
* Copyright(c) 2020, Analogix Semiconductor. All rights reserved.
*
*/
+#include <linux/cleanup.h>
#include <linux/gcd.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
@@ -15,6 +16,9 @@
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/types.h>
+#include <linux/usb.h>
+#include <linux/usb/pd.h>
+#include <linux/usb/role.h>
#include <linux/workqueue.h>
#include <linux/of_graph.h>
@@ -1325,7 +1329,7 @@ static int anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx)
static void anx7625_disable_pd_protocol(struct anx7625_data *ctx)
{
struct device *dev = ctx->dev;
- int ret, val;
+ int ret;
/* Reset main ocm */
ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40);
@@ -1339,6 +1343,11 @@ static void anx7625_disable_pd_protocol(struct anx7625_data *ctx)
DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n");
else
DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature succeeded.\n");
+}
+
+static void anx7625_configure_hpd(struct anx7625_data *ctx)
+{
+ int val;
/*
* Make sure the HPD GPIO already be configured after OCM release before
@@ -1369,7 +1378,9 @@ static int anx7625_ocm_loading_check(struct anx7625_data *ctx)
if ((ret & FLASH_LOAD_STA_CHK) != FLASH_LOAD_STA_CHK)
return -ENODEV;
- anx7625_disable_pd_protocol(ctx);
+ if (!ctx->typec_port)
+ anx7625_disable_pd_protocol(ctx);
+ anx7625_configure_hpd(ctx);
DRM_DEV_DEBUG_DRIVER(dev, "Firmware ver %02x%02x,",
anx7625_reg_read(ctx,
@@ -1472,6 +1483,115 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx)
DRM_DEV_DEBUG_DRIVER(dev, "Secure OCM version=%02x\n", ret);
}
+#if IS_REACHABLE(CONFIG_TYPEC)
+static void anx7625_typec_set_orientation(struct anx7625_data *ctx)
+{
+ u32 val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
+
+ if (val & (CC1_RP | CC1_RD))
+ typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_NORMAL);
+ else if (val & (CC2_RP | CC2_RD))
+ typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_REVERSE);
+ else
+ typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_NONE);
+}
+
+static void anx7625_typec_isr(struct anx7625_data *ctx,
+ unsigned int intr_vector,
+ unsigned int intr_status)
+{
+ if (intr_vector & CC_STATUS)
+ anx7625_typec_set_orientation(ctx);
+ if (intr_vector & DATA_ROLE_STATUS) {
+ usb_role_switch_set_role(ctx->role_sw,
+ (intr_status & DATA_ROLE_STATUS) ?
+ USB_ROLE_HOST : USB_ROLE_DEVICE);
+ typec_set_data_role(ctx->typec_port,
+ (intr_status & DATA_ROLE_STATUS) ?
+ TYPEC_HOST : TYPEC_DEVICE);
+ }
+ if (intr_vector & VBUS_STATUS)
+ typec_set_pwr_role(ctx->typec_port,
+ (intr_status & VBUS_STATUS) ?
+ TYPEC_SOURCE : TYPEC_SINK);
+ if (intr_vector & VCONN_STATUS)
+ typec_set_vconn_role(ctx->typec_port,
+ (intr_status & VCONN_STATUS) ?
+ TYPEC_SOURCE : TYPEC_SINK);
+}
+
+static int anx7625_typec_register(struct anx7625_data *ctx)
+{
+ struct typec_capability typec_cap = { };
+ struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;
+ u32 val;
+ int ret;
+
+ fwnode = device_get_named_child_node(ctx->dev, "connector");
+ if (!fwnode)
+ return 0;
+
+ ret = typec_get_fw_cap(&typec_cap, fwnode);
+ if (ret < 0)
+ return ret;
+
+ typec_cap.revision = 0x0120;
+ typec_cap.pd_revision = 0x0300;
+ typec_cap.usb_capability = USB_CAPABILITY_USB2 | USB_CAPABILITY_USB3;
+ typec_cap.orientation_aware = true;
+
+ typec_cap.driver_data = ctx;
+
+ ctx->typec_port = typec_register_port(ctx->dev, &typec_cap);
+ if (IS_ERR(ctx->typec_port))
+ return PTR_ERR(ctx->typec_port);
+
+ ctx->role_sw = fwnode_usb_role_switch_get(fwnode);
+ if (IS_ERR(ctx->role_sw)) {
+ typec_unregister_port(ctx->typec_port);
+ return PTR_ERR(ctx->role_sw);
+ }
+
+ val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
+ anx7625_typec_set_orientation(ctx);
+ usb_role_switch_set_role(ctx->role_sw,
+ (val & DATA_ROLE_STATUS) ?
+ USB_ROLE_HOST : USB_ROLE_DEVICE);
+ typec_set_data_role(ctx->typec_port,
+ (val & DATA_ROLE_STATUS) ?
+ TYPEC_HOST : TYPEC_DEVICE);
+ typec_set_pwr_role(ctx->typec_port,
+ (val & VBUS_STATUS) ?
+ TYPEC_SOURCE : TYPEC_SINK);
+ typec_set_vconn_role(ctx->typec_port,
+ (val & VCONN_STATUS) ?
+ TYPEC_SOURCE : TYPEC_SINK);
+
+ return 0;
+}
+
+static void anx7625_typec_unregister(struct anx7625_data *ctx)
+{
+ usb_role_switch_put(ctx->role_sw);
+ typec_unregister_port(ctx->typec_port);
+}
+#else
+static void anx7625_typec_isr(struct anx7625_data *ctx,
+ unsigned int intr_vector,
+ unsigned int intr_status)
+{
+}
+
+static int anx7625_typec_register(struct anx7625_data *ctx)
+{
+ return 0;
+}
+
+static void anx7625_typec_unregister(struct anx7625_data *ctx)
+{
+}
+#endif
+
static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx)
{
return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
@@ -1566,7 +1686,7 @@ static void dp_hpd_change_handler(struct anx7625_data *ctx, bool on)
}
}
-static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
+static int anx7625_intr_status(struct anx7625_data *ctx)
{
int intr_vector, status;
struct device *dev = ctx->dev;
@@ -1593,9 +1713,6 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
return status;
}
- if (!(intr_vector & HPD_STATUS_CHANGE))
- return -ENOENT;
-
status = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client,
SYSTEM_STSTUS);
if (status < 0) {
@@ -1604,6 +1721,12 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
}
DRM_DEV_DEBUG_DRIVER(dev, "0x7e:0x45=%x\n", status);
+
+ anx7625_typec_isr(ctx, intr_vector, status);
+
+ if (!(intr_vector & HPD_STATUS))
+ return -ENOENT;
+
dp_hpd_change_handler(ctx, status & HPD_STATUS);
return 0;
@@ -1622,7 +1745,7 @@ static void anx7625_work_func(struct work_struct *work)
return;
}
- event = anx7625_hpd_change_detect(ctx);
+ event = anx7625_intr_status(ctx);
mutex_unlock(&ctx->lock);
@@ -2741,11 +2864,29 @@ static int anx7625_i2c_probe(struct i2c_client *client)
}
if (!platform->pdata.low_power_mode) {
- anx7625_disable_pd_protocol(platform);
+ struct fwnode_handle *fwnode;
+
+ fwnode = device_get_named_child_node(dev, "connector");
+ if (fwnode)
+ fwnode_handle_put(fwnode);
+ else
+ anx7625_disable_pd_protocol(platform);
+
+ anx7625_configure_hpd(platform);
+
pm_runtime_get_sync(dev);
_anx7625_hpd_polling(platform, 5000 * 100);
}
+ if (platform->pdata.intp_irq)
+ anx7625_reg_write(platform, platform->i2c.rx_p0_client,
+ INTERFACE_CHANGE_INT_MASK, 0);
+
+ /* After getting runtime handle */
+ ret = anx7625_typec_register(platform);
+ if (ret)
+ goto pm_suspend;
+
/* Add work function */
if (platform->pdata.intp_irq) {
enable_irq(platform->pdata.intp_irq);
@@ -2759,6 +2900,10 @@ static int anx7625_i2c_probe(struct i2c_client *client)
return 0;
+pm_suspend:
+ if (!platform->pdata.low_power_mode)
+ pm_runtime_put_sync_suspend(&client->dev);
+
free_wq:
if (platform->workqueue)
destroy_workqueue(platform->workqueue);
@@ -2774,6 +2919,8 @@ static void anx7625_i2c_remove(struct i2c_client *client)
{
struct anx7625_data *platform = i2c_get_clientdata(client);
+ anx7625_typec_unregister(platform);
+
drm_bridge_remove(&platform->bridge);
if (platform->pdata.intp_irq)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h
index eb5580f1ab2f86b48b6f2df4fa4d6c3be603ad48..f9570cd6d22e55fd70a12c15960714cbb783d059 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.h
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.h
@@ -51,9 +51,21 @@
#define INTR_RECEIVED_MSG BIT(5)
#define SYSTEM_STSTUS 0x45
+#define INTERFACE_CHANGE_INT_MASK 0x43
#define INTERFACE_CHANGE_INT 0x44
-#define HPD_STATUS_CHANGE 0x80
-#define HPD_STATUS 0x80
+#define VCONN_STATUS BIT(2)
+#define VBUS_STATUS BIT(3)
+#define CC_STATUS BIT(4)
+#define DATA_ROLE_STATUS BIT(5)
+#define HPD_STATUS BIT(7)
+
+#define NEW_CC_STATUS 0x46
+#define CC1_RD BIT(0)
+#define CC1_RA BIT(1)
+#define CC1_RP (BIT(2) | BIT(3))
+#define CC2_RD BIT(4)
+#define CC2_RA BIT(5)
+#define CC2_RP (BIT(6) | BIT(7))
/******** END of I2C Address 0x58 ********/
@@ -447,9 +459,14 @@ struct anx7625_i2c_client {
struct i2c_client *tcpc_client;
};
+struct typec_port;
+struct usb_role_switch;
+
struct anx7625_data {
struct anx7625_platform_data pdata;
struct platform_device *audio_pdev;
+ struct typec_port *typec_port;
+ struct usb_role_switch *role_sw;
int hpd_status;
int hpd_high_cnt;
int dp_en;
--
2.47.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support
2025-11-26 9:41 ` [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support Dmitry Baryshkov
@ 2025-12-04 13:15 ` Heikki Krogerus
2025-12-06 3:31 ` Dmitry Baryshkov
2025-12-08 7:37 ` Xin Ji
2025-12-12 13:17 ` Xin Ji
1 sibling, 2 replies; 9+ messages in thread
From: Heikki Krogerus @ 2025-12-04 13:15 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Xin Ji, Greg Kroah-Hartman,
dri-devel, devicetree, linux-usb, linux-arm-msm, linux-kernel
Wed, Nov 26, 2025 at 11:41:57AM +0200, Dmitry Baryshkov kirjoitti:
> ANX7625 can be used as a USB-C controller, handling USB and DP data
> streams. Provide minimal Type-C support necessary for ANX7625 to
> register the Type-C port device and properly respond to data / power
> role events from the Type-C partner.
>
> While ANX7625 provides TCPCI interface, using it would circumvent the
> on-chip running firmware. Analogix recommended using the higher-level
> interface instead of TCPCI.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
FWIW:
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> ---
> drivers/gpu/drm/bridge/analogix/Kconfig | 1 +
> drivers/gpu/drm/bridge/analogix/anx7625.c | 163 ++++++++++++++++++++++++++++--
> drivers/gpu/drm/bridge/analogix/anx7625.h | 21 +++-
> 3 files changed, 175 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig
> index 4846b2e9be7c2a5da18f6a3cdec53ef5766455e0..f3448b0631fea42e7e7ab10368777a93ce33cee7 100644
> --- a/drivers/gpu/drm/bridge/analogix/Kconfig
> +++ b/drivers/gpu/drm/bridge/analogix/Kconfig
> @@ -34,6 +34,7 @@ config DRM_ANALOGIX_ANX7625
> tristate "Analogix Anx7625 MIPI to DP interface support"
> depends on DRM
> depends on OF
> + depends on TYPEC || !TYPEC
> select DRM_DISPLAY_DP_HELPER
> select DRM_DISPLAY_HDCP_HELPER
> select DRM_DISPLAY_HELPER
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
> index 6f3fdcb6afdb9d785bc4515300676cf3988c5807..a44405db739669dfd2907b0afd41293a7b173035 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> @@ -3,6 +3,7 @@
> * Copyright(c) 2020, Analogix Semiconductor. All rights reserved.
> *
> */
> +#include <linux/cleanup.h>
> #include <linux/gcd.h>
> #include <linux/gpio/consumer.h>
> #include <linux/i2c.h>
> @@ -15,6 +16,9 @@
> #include <linux/regulator/consumer.h>
> #include <linux/slab.h>
> #include <linux/types.h>
> +#include <linux/usb.h>
> +#include <linux/usb/pd.h>
> +#include <linux/usb/role.h>
> #include <linux/workqueue.h>
>
> #include <linux/of_graph.h>
> @@ -1325,7 +1329,7 @@ static int anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx)
> static void anx7625_disable_pd_protocol(struct anx7625_data *ctx)
> {
> struct device *dev = ctx->dev;
> - int ret, val;
> + int ret;
>
> /* Reset main ocm */
> ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40);
> @@ -1339,6 +1343,11 @@ static void anx7625_disable_pd_protocol(struct anx7625_data *ctx)
> DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n");
> else
> DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature succeeded.\n");
> +}
> +
> +static void anx7625_configure_hpd(struct anx7625_data *ctx)
> +{
> + int val;
>
> /*
> * Make sure the HPD GPIO already be configured after OCM release before
> @@ -1369,7 +1378,9 @@ static int anx7625_ocm_loading_check(struct anx7625_data *ctx)
> if ((ret & FLASH_LOAD_STA_CHK) != FLASH_LOAD_STA_CHK)
> return -ENODEV;
>
> - anx7625_disable_pd_protocol(ctx);
> + if (!ctx->typec_port)
> + anx7625_disable_pd_protocol(ctx);
> + anx7625_configure_hpd(ctx);
>
> DRM_DEV_DEBUG_DRIVER(dev, "Firmware ver %02x%02x,",
> anx7625_reg_read(ctx,
> @@ -1472,6 +1483,115 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx)
> DRM_DEV_DEBUG_DRIVER(dev, "Secure OCM version=%02x\n", ret);
> }
>
> +#if IS_REACHABLE(CONFIG_TYPEC)
> +static void anx7625_typec_set_orientation(struct anx7625_data *ctx)
> +{
> + u32 val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
> +
> + if (val & (CC1_RP | CC1_RD))
> + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_NORMAL);
> + else if (val & (CC2_RP | CC2_RD))
> + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_REVERSE);
> + else
> + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_NONE);
> +}
> +
> +static void anx7625_typec_isr(struct anx7625_data *ctx,
> + unsigned int intr_vector,
> + unsigned int intr_status)
> +{
> + if (intr_vector & CC_STATUS)
> + anx7625_typec_set_orientation(ctx);
> + if (intr_vector & DATA_ROLE_STATUS) {
> + usb_role_switch_set_role(ctx->role_sw,
> + (intr_status & DATA_ROLE_STATUS) ?
> + USB_ROLE_HOST : USB_ROLE_DEVICE);
> + typec_set_data_role(ctx->typec_port,
> + (intr_status & DATA_ROLE_STATUS) ?
> + TYPEC_HOST : TYPEC_DEVICE);
> + }
> + if (intr_vector & VBUS_STATUS)
> + typec_set_pwr_role(ctx->typec_port,
> + (intr_status & VBUS_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> + if (intr_vector & VCONN_STATUS)
> + typec_set_vconn_role(ctx->typec_port,
> + (intr_status & VCONN_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> +}
> +
> +static int anx7625_typec_register(struct anx7625_data *ctx)
> +{
> + struct typec_capability typec_cap = { };
> + struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;
> + u32 val;
> + int ret;
> +
> + fwnode = device_get_named_child_node(ctx->dev, "connector");
> + if (!fwnode)
> + return 0;
> +
> + ret = typec_get_fw_cap(&typec_cap, fwnode);
> + if (ret < 0)
> + return ret;
> +
> + typec_cap.revision = 0x0120;
> + typec_cap.pd_revision = 0x0300;
> + typec_cap.usb_capability = USB_CAPABILITY_USB2 | USB_CAPABILITY_USB3;
> + typec_cap.orientation_aware = true;
> +
> + typec_cap.driver_data = ctx;
> +
> + ctx->typec_port = typec_register_port(ctx->dev, &typec_cap);
> + if (IS_ERR(ctx->typec_port))
> + return PTR_ERR(ctx->typec_port);
> +
> + ctx->role_sw = fwnode_usb_role_switch_get(fwnode);
> + if (IS_ERR(ctx->role_sw)) {
> + typec_unregister_port(ctx->typec_port);
> + return PTR_ERR(ctx->role_sw);
> + }
> +
> + val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
> + anx7625_typec_set_orientation(ctx);
> + usb_role_switch_set_role(ctx->role_sw,
> + (val & DATA_ROLE_STATUS) ?
> + USB_ROLE_HOST : USB_ROLE_DEVICE);
> + typec_set_data_role(ctx->typec_port,
> + (val & DATA_ROLE_STATUS) ?
> + TYPEC_HOST : TYPEC_DEVICE);
> + typec_set_pwr_role(ctx->typec_port,
> + (val & VBUS_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> + typec_set_vconn_role(ctx->typec_port,
> + (val & VCONN_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> +
> + return 0;
> +}
> +
> +static void anx7625_typec_unregister(struct anx7625_data *ctx)
> +{
> + usb_role_switch_put(ctx->role_sw);
> + typec_unregister_port(ctx->typec_port);
> +}
> +#else
> +static void anx7625_typec_isr(struct anx7625_data *ctx,
> + unsigned int intr_vector,
> + unsigned int intr_status)
> +{
> +}
> +
> +static int anx7625_typec_register(struct anx7625_data *ctx)
> +{
> + return 0;
> +}
> +
> +static void anx7625_typec_unregister(struct anx7625_data *ctx)
> +{
> +}
> +#endif
> +
> static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx)
> {
> return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
> @@ -1566,7 +1686,7 @@ static void dp_hpd_change_handler(struct anx7625_data *ctx, bool on)
> }
> }
>
> -static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
> +static int anx7625_intr_status(struct anx7625_data *ctx)
> {
> int intr_vector, status;
> struct device *dev = ctx->dev;
> @@ -1593,9 +1713,6 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
> return status;
> }
>
> - if (!(intr_vector & HPD_STATUS_CHANGE))
> - return -ENOENT;
> -
> status = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client,
> SYSTEM_STSTUS);
> if (status < 0) {
> @@ -1604,6 +1721,12 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
> }
>
> DRM_DEV_DEBUG_DRIVER(dev, "0x7e:0x45=%x\n", status);
> +
> + anx7625_typec_isr(ctx, intr_vector, status);
> +
> + if (!(intr_vector & HPD_STATUS))
> + return -ENOENT;
> +
> dp_hpd_change_handler(ctx, status & HPD_STATUS);
>
> return 0;
> @@ -1622,7 +1745,7 @@ static void anx7625_work_func(struct work_struct *work)
> return;
> }
>
> - event = anx7625_hpd_change_detect(ctx);
> + event = anx7625_intr_status(ctx);
>
> mutex_unlock(&ctx->lock);
>
> @@ -2741,11 +2864,29 @@ static int anx7625_i2c_probe(struct i2c_client *client)
> }
>
> if (!platform->pdata.low_power_mode) {
> - anx7625_disable_pd_protocol(platform);
> + struct fwnode_handle *fwnode;
> +
> + fwnode = device_get_named_child_node(dev, "connector");
> + if (fwnode)
> + fwnode_handle_put(fwnode);
> + else
> + anx7625_disable_pd_protocol(platform);
> +
> + anx7625_configure_hpd(platform);
> +
> pm_runtime_get_sync(dev);
> _anx7625_hpd_polling(platform, 5000 * 100);
> }
>
> + if (platform->pdata.intp_irq)
> + anx7625_reg_write(platform, platform->i2c.rx_p0_client,
> + INTERFACE_CHANGE_INT_MASK, 0);
> +
> + /* After getting runtime handle */
> + ret = anx7625_typec_register(platform);
> + if (ret)
> + goto pm_suspend;
> +
> /* Add work function */
> if (platform->pdata.intp_irq) {
> enable_irq(platform->pdata.intp_irq);
> @@ -2759,6 +2900,10 @@ static int anx7625_i2c_probe(struct i2c_client *client)
>
> return 0;
>
> +pm_suspend:
> + if (!platform->pdata.low_power_mode)
> + pm_runtime_put_sync_suspend(&client->dev);
> +
> free_wq:
> if (platform->workqueue)
> destroy_workqueue(platform->workqueue);
> @@ -2774,6 +2919,8 @@ static void anx7625_i2c_remove(struct i2c_client *client)
> {
> struct anx7625_data *platform = i2c_get_clientdata(client);
>
> + anx7625_typec_unregister(platform);
> +
> drm_bridge_remove(&platform->bridge);
>
> if (platform->pdata.intp_irq)
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h
> index eb5580f1ab2f86b48b6f2df4fa4d6c3be603ad48..f9570cd6d22e55fd70a12c15960714cbb783d059 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.h
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h
> @@ -51,9 +51,21 @@
> #define INTR_RECEIVED_MSG BIT(5)
>
> #define SYSTEM_STSTUS 0x45
> +#define INTERFACE_CHANGE_INT_MASK 0x43
> #define INTERFACE_CHANGE_INT 0x44
> -#define HPD_STATUS_CHANGE 0x80
> -#define HPD_STATUS 0x80
> +#define VCONN_STATUS BIT(2)
> +#define VBUS_STATUS BIT(3)
> +#define CC_STATUS BIT(4)
> +#define DATA_ROLE_STATUS BIT(5)
> +#define HPD_STATUS BIT(7)
> +
> +#define NEW_CC_STATUS 0x46
> +#define CC1_RD BIT(0)
> +#define CC1_RA BIT(1)
> +#define CC1_RP (BIT(2) | BIT(3))
> +#define CC2_RD BIT(4)
> +#define CC2_RA BIT(5)
> +#define CC2_RP (BIT(6) | BIT(7))
>
> /******** END of I2C Address 0x58 ********/
>
> @@ -447,9 +459,14 @@ struct anx7625_i2c_client {
> struct i2c_client *tcpc_client;
> };
>
> +struct typec_port;
> +struct usb_role_switch;
> +
> struct anx7625_data {
> struct anx7625_platform_data pdata;
> struct platform_device *audio_pdev;
> + struct typec_port *typec_port;
> + struct usb_role_switch *role_sw;
> int hpd_status;
> int hpd_high_cnt;
> int dp_en;
>
> --
> 2.47.3
--
heikki
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support
2025-12-04 13:15 ` Heikki Krogerus
@ 2025-12-06 3:31 ` Dmitry Baryshkov
2025-12-08 7:37 ` Xin Ji
1 sibling, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-12-06 3:31 UTC (permalink / raw)
To: Heikki Krogerus
Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Xin Ji, Greg Kroah-Hartman,
dri-devel, devicetree, linux-usb, linux-arm-msm, linux-kernel
On Thu, Dec 04, 2025 at 03:15:08PM +0200, Heikki Krogerus wrote:
> Wed, Nov 26, 2025 at 11:41:57AM +0200, Dmitry Baryshkov kirjoitti:
> > ANX7625 can be used as a USB-C controller, handling USB and DP data
> > streams. Provide minimal Type-C support necessary for ANX7625 to
> > register the Type-C port device and properly respond to data / power
> > role events from the Type-C partner.
> >
> > While ANX7625 provides TCPCI interface, using it would circumvent the
> > on-chip running firmware. Analogix recommended using the higher-level
> > interface instead of TCPCI.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
>
> FWIW:
>
> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Thanks!
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support
2025-12-04 13:15 ` Heikki Krogerus
2025-12-06 3:31 ` Dmitry Baryshkov
@ 2025-12-08 7:37 ` Xin Ji
2025-12-09 22:51 ` Dmitry Baryshkov
1 sibling, 1 reply; 9+ messages in thread
From: Xin Ji @ 2025-12-08 7:37 UTC (permalink / raw)
To: Heikki Krogerus, Dmitry Baryshkov
Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Greg Kroah-Hartman,
dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
linux-usb@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Dmitry, I found there is another patch "Register USB Type-C mode switches" which provided by Pin-yen Lin <treapking@chromium.org>, but I didn't find it in the v6.18, is it obsolete?.
https://patchew.org/linux/20221124102056.393220-1-treapking@chromium.org/20221124102056.393220-6-treapking@chromium.org/
Thanks,
Xin
> ANX7625 can be used as a USB-C controller, handling USB and DP data
> streams. Provide minimal Type-C support necessary for ANX7625 to
> register the Type-C port device and properly respond to data / power
> role events from the Type-C partner.
>
> While ANX7625 provides TCPCI interface, using it would circumvent the
> on-chip running firmware. Analogix recommended using the higher-level
> interface instead of TCPCI.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
FWIW:
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> ---
> drivers/gpu/drm/bridge/analogix/Kconfig | 1 +
> drivers/gpu/drm/bridge/analogix/anx7625.c | 163
> ++++++++++++++++++++++++++++--
> drivers/gpu/drm/bridge/analogix/anx7625.h | 21 +++-
> 3 files changed, 175 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig
> b/drivers/gpu/drm/bridge/analogix/Kconfig
> index
> 4846b2e9be7c2a5da18f6a3cdec53ef5766455e0..f3448b0631fea42e7e7ab1036877
> 7a93ce33cee7 100644
> --- a/drivers/gpu/drm/bridge/analogix/Kconfig
> +++ b/drivers/gpu/drm/bridge/analogix/Kconfig
> @@ -34,6 +34,7 @@ config DRM_ANALOGIX_ANX7625
> tristate "Analogix Anx7625 MIPI to DP interface support"
> depends on DRM
> depends on OF
> + depends on TYPEC || !TYPEC
> select DRM_DISPLAY_DP_HELPER
> select DRM_DISPLAY_HDCP_HELPER
> select DRM_DISPLAY_HELPER
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c
> b/drivers/gpu/drm/bridge/analogix/anx7625.c
> index
> 6f3fdcb6afdb9d785bc4515300676cf3988c5807..a44405db739669dfd2907b0afd41
> 293a7b173035 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> @@ -3,6 +3,7 @@
> * Copyright(c) 2020, Analogix Semiconductor. All rights reserved.
> *
> */
> +#include <linux/cleanup.h>
> #include <linux/gcd.h>
> #include <linux/gpio/consumer.h>
> #include <linux/i2c.h>
> @@ -15,6 +16,9 @@
> #include <linux/regulator/consumer.h> #include <linux/slab.h>
> #include <linux/types.h>
> +#include <linux/usb.h>
> +#include <linux/usb/pd.h>
> +#include <linux/usb/role.h>
> #include <linux/workqueue.h>
>
> #include <linux/of_graph.h>
> @@ -1325,7 +1329,7 @@ static int
> anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx) static
> void anx7625_disable_pd_protocol(struct anx7625_data *ctx) {
> struct device *dev = ctx->dev;
> - int ret, val;
> + int ret;
>
> /* Reset main ocm */
> ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40); @@
> -1339,6 +1343,11 @@ static void anx7625_disable_pd_protocol(struct anx7625_data *ctx)
> DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n");
> else
> DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature succeeded.\n");
> +}
> +
> +static void anx7625_configure_hpd(struct anx7625_data *ctx) {
> + int val;
>
> /*
> * Make sure the HPD GPIO already be configured after OCM release
> before @@ -1369,7 +1378,9 @@ static int anx7625_ocm_loading_check(struct anx7625_data *ctx)
> if ((ret & FLASH_LOAD_STA_CHK) != FLASH_LOAD_STA_CHK)
> return -ENODEV;
>
> - anx7625_disable_pd_protocol(ctx);
> + if (!ctx->typec_port)
> + anx7625_disable_pd_protocol(ctx);
> + anx7625_configure_hpd(ctx);
>
> DRM_DEV_DEBUG_DRIVER(dev, "Firmware ver %02x%02x,",
> anx7625_reg_read(ctx,
> @@ -1472,6 +1483,115 @@ static void anx7625_start_dp_work(struct anx7625_data *ctx)
> DRM_DEV_DEBUG_DRIVER(dev, "Secure OCM version=%02x\n", ret); }
>
> +#if IS_REACHABLE(CONFIG_TYPEC)
> +static void anx7625_typec_set_orientation(struct anx7625_data *ctx) {
> + u32 val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client,
> +SYSTEM_STSTUS);
> +
> + if (val & (CC1_RP | CC1_RD))
> + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_NORMAL);
> + else if (val & (CC2_RP | CC2_RD))
> + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_REVERSE);
> + else
> + typec_set_orientation(ctx->typec_port, TYPEC_ORIENTATION_NONE); }
> +
> +static void anx7625_typec_isr(struct anx7625_data *ctx,
> + unsigned int intr_vector,
> + unsigned int intr_status)
> +{
> + if (intr_vector & CC_STATUS)
> + anx7625_typec_set_orientation(ctx);
> + if (intr_vector & DATA_ROLE_STATUS) {
> + usb_role_switch_set_role(ctx->role_sw,
> + (intr_status & DATA_ROLE_STATUS) ?
> + USB_ROLE_HOST : USB_ROLE_DEVICE);
> + typec_set_data_role(ctx->typec_port,
> + (intr_status & DATA_ROLE_STATUS) ?
> + TYPEC_HOST : TYPEC_DEVICE);
> + }
> + if (intr_vector & VBUS_STATUS)
> + typec_set_pwr_role(ctx->typec_port,
> + (intr_status & VBUS_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> + if (intr_vector & VCONN_STATUS)
> + typec_set_vconn_role(ctx->typec_port,
> + (intr_status & VCONN_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> +}
> +
> +static int anx7625_typec_register(struct anx7625_data *ctx) {
> + struct typec_capability typec_cap = { };
> + struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;
> + u32 val;
> + int ret;
> +
> + fwnode = device_get_named_child_node(ctx->dev, "connector");
> + if (!fwnode)
> + return 0;
> +
> + ret = typec_get_fw_cap(&typec_cap, fwnode);
> + if (ret < 0)
> + return ret;
> +
> + typec_cap.revision = 0x0120;
> + typec_cap.pd_revision = 0x0300;
> + typec_cap.usb_capability = USB_CAPABILITY_USB2 | USB_CAPABILITY_USB3;
> + typec_cap.orientation_aware = true;
> +
> + typec_cap.driver_data = ctx;
> +
> + ctx->typec_port = typec_register_port(ctx->dev, &typec_cap);
> + if (IS_ERR(ctx->typec_port))
> + return PTR_ERR(ctx->typec_port);
> +
> + ctx->role_sw = fwnode_usb_role_switch_get(fwnode);
> + if (IS_ERR(ctx->role_sw)) {
> + typec_unregister_port(ctx->typec_port);
> + return PTR_ERR(ctx->role_sw);
> + }
> +
> + val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
> + anx7625_typec_set_orientation(ctx);
> + usb_role_switch_set_role(ctx->role_sw,
> + (val & DATA_ROLE_STATUS) ?
> + USB_ROLE_HOST : USB_ROLE_DEVICE);
> + typec_set_data_role(ctx->typec_port,
> + (val & DATA_ROLE_STATUS) ?
> + TYPEC_HOST : TYPEC_DEVICE);
> + typec_set_pwr_role(ctx->typec_port,
> + (val & VBUS_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> + typec_set_vconn_role(ctx->typec_port,
> + (val & VCONN_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> +
> + return 0;
> +}
> +
> +static void anx7625_typec_unregister(struct anx7625_data *ctx) {
> + usb_role_switch_put(ctx->role_sw);
> + typec_unregister_port(ctx->typec_port);
> +}
> +#else
> +static void anx7625_typec_isr(struct anx7625_data *ctx,
> + unsigned int intr_vector,
> + unsigned int intr_status)
> +{
> +}
> +
> +static int anx7625_typec_register(struct anx7625_data *ctx) {
> + return 0;
> +}
> +
> +static void anx7625_typec_unregister(struct anx7625_data *ctx) { }
> +#endif
> +
> static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) {
> return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
> @@ -1566,7 +1686,7 @@ static void dp_hpd_change_handler(struct anx7625_data *ctx, bool on)
> }
> }
>
> -static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
> +static int anx7625_intr_status(struct anx7625_data *ctx)
> {
> int intr_vector, status;
> struct device *dev = ctx->dev;
> @@ -1593,9 +1713,6 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
> return status;
> }
>
> - if (!(intr_vector & HPD_STATUS_CHANGE))
> - return -ENOENT;
> -
> status = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client,
> SYSTEM_STSTUS);
> if (status < 0) {
> @@ -1604,6 +1721,12 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
> }
>
> DRM_DEV_DEBUG_DRIVER(dev, "0x7e:0x45=%x\n", status);
> +
> + anx7625_typec_isr(ctx, intr_vector, status);
> +
> + if (!(intr_vector & HPD_STATUS))
> + return -ENOENT;
> +
> dp_hpd_change_handler(ctx, status & HPD_STATUS);
>
> return 0;
> @@ -1622,7 +1745,7 @@ static void anx7625_work_func(struct work_struct *work)
> return;
> }
>
> - event = anx7625_hpd_change_detect(ctx);
> + event = anx7625_intr_status(ctx);
>
> mutex_unlock(&ctx->lock);
>
> @@ -2741,11 +2864,29 @@ static int anx7625_i2c_probe(struct i2c_client *client)
> }
>
> if (!platform->pdata.low_power_mode) {
> - anx7625_disable_pd_protocol(platform);
> + struct fwnode_handle *fwnode;
> +
> + fwnode = device_get_named_child_node(dev, "connector");
> + if (fwnode)
> + fwnode_handle_put(fwnode);
> + else
> + anx7625_disable_pd_protocol(platform);
> +
> + anx7625_configure_hpd(platform);
> +
> pm_runtime_get_sync(dev);
> _anx7625_hpd_polling(platform, 5000 * 100);
> }
>
> + if (platform->pdata.intp_irq)
> + anx7625_reg_write(platform, platform->i2c.rx_p0_client,
> + INTERFACE_CHANGE_INT_MASK, 0);
> +
> + /* After getting runtime handle */
> + ret = anx7625_typec_register(platform);
> + if (ret)
> + goto pm_suspend;
> +
> /* Add work function */
> if (platform->pdata.intp_irq) {
> enable_irq(platform->pdata.intp_irq);
> @@ -2759,6 +2900,10 @@ static int anx7625_i2c_probe(struct i2c_client
> *client)
>
> return 0;
>
> +pm_suspend:
> + if (!platform->pdata.low_power_mode)
> + pm_runtime_put_sync_suspend(&client->dev);
> +
> free_wq:
> if (platform->workqueue)
> destroy_workqueue(platform->workqueue);
> @@ -2774,6 +2919,8 @@ static void anx7625_i2c_remove(struct i2c_client
> *client) {
> struct anx7625_data *platform = i2c_get_clientdata(client);
>
> + anx7625_typec_unregister(platform);
> +
> drm_bridge_remove(&platform->bridge);
>
> if (platform->pdata.intp_irq)
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h
> b/drivers/gpu/drm/bridge/analogix/anx7625.h
> index
> eb5580f1ab2f86b48b6f2df4fa4d6c3be603ad48..f9570cd6d22e55fd70a12c159607
> 14cbb783d059 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.h
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h
> @@ -51,9 +51,21 @@
> #define INTR_RECEIVED_MSG BIT(5)
>
> #define SYSTEM_STSTUS 0x45
> +#define INTERFACE_CHANGE_INT_MASK 0x43
> #define INTERFACE_CHANGE_INT 0x44
> -#define HPD_STATUS_CHANGE 0x80
> -#define HPD_STATUS 0x80
> +#define VCONN_STATUS BIT(2)
> +#define VBUS_STATUS BIT(3)
> +#define CC_STATUS BIT(4)
> +#define DATA_ROLE_STATUS BIT(5)
> +#define HPD_STATUS BIT(7)
> +
> +#define NEW_CC_STATUS 0x46
> +#define CC1_RD BIT(0)
> +#define CC1_RA BIT(1)
> +#define CC1_RP (BIT(2) | BIT(3))
> +#define CC2_RD BIT(4)
> +#define CC2_RA BIT(5)
> +#define CC2_RP (BIT(6) | BIT(7))
>
> /******** END of I2C Address 0x58 ********/
>
> @@ -447,9 +459,14 @@ struct anx7625_i2c_client {
> struct i2c_client *tcpc_client;
> };
>
> +struct typec_port;
> +struct usb_role_switch;
> +
> struct anx7625_data {
> struct anx7625_platform_data pdata;
> struct platform_device *audio_pdev;
> + struct typec_port *typec_port;
> + struct usb_role_switch *role_sw;
> int hpd_status;
> int hpd_high_cnt;
> int dp_en;
>
> --
> 2.47.3
--
heikki
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support
2025-12-08 7:37 ` Xin Ji
@ 2025-12-09 22:51 ` Dmitry Baryshkov
2025-12-12 12:39 ` Xin Ji
0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-12-09 22:51 UTC (permalink / raw)
To: Xin Ji
Cc: Heikki Krogerus, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Greg Kroah-Hartman, dri-devel@lists.freedesktop.org,
devicetree@vger.kernel.org, linux-usb@vger.kernel.org,
linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org
On Mon, Dec 08, 2025 at 07:37:30AM +0000, Xin Ji wrote:
> Hi Dmitry, I found there is another patch "Register USB Type-C mode switches" which provided by Pin-yen Lin <treapking@chromium.org>, but I didn't find it in the v6.18, is it obsolete?.
It has been posted 2 years ago, it has not been reposted since that
time, it targets a very specific ChromeOS usecase. I can't call it
obsolete, but it wasn't merged.
> https://patchew.org/linux/20221124102056.393220-1-treapking@chromium.org/20221124102056.393220-6-treapking@chromium.org/
>
> Thanks,
> Xin
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support
2025-12-09 22:51 ` Dmitry Baryshkov
@ 2025-12-12 12:39 ` Xin Ji
0 siblings, 0 replies; 9+ messages in thread
From: Xin Ji @ 2025-12-12 12:39 UTC (permalink / raw)
To: Dmitry Baryshkov, Pin-yen Lin
Cc: Heikki Krogerus, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Greg Kroah-Hartman, dri-devel@lists.freedesktop.org,
devicetree@vger.kernel.org, linux-usb@vger.kernel.org,
linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org
>> Hi Dmitry, I found there is another patch "Register USB Type-C mode switches" which provided by Pin-yen Lin <treapking@chromium.org>, but I didn't find it in the v6.18, is it obsolete?.
>It has been posted 2 years ago, it has not been reposted since that time, it targets a very specific ChromeOS usecase. I can't call it obsolete, but it wasn't merged.
OK, thanks!
Xin
>> https://patchew.org/linux/20221124102056.393220-1-treapking@chromium.o
>> rg/20221124102056.393220-6-treapking@chromium.org/
>>
>> Thanks,
>> Xin
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support
2025-11-26 9:41 ` [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support Dmitry Baryshkov
2025-12-04 13:15 ` Heikki Krogerus
@ 2025-12-12 13:17 ` Xin Ji
1 sibling, 0 replies; 9+ messages in thread
From: Xin Ji @ 2025-12-12 13:17 UTC (permalink / raw)
To: Dmitry Baryshkov, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Heikki Krogerus, Greg Kroah-Hartman
Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
linux-usb@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Dmitry, thanks for your code, I've checked the patch, it seems OK for me, please add my r-b.
Reviewed-by: Xin Ji <xji@analogixsemi.com>
> Subject: [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C
> support
>
> ANX7625 can be used as a USB-C controller, handling USB and DP data streams.
> Provide minimal Type-C support necessary for ANX7625 to register the Type-C
> port device and properly respond to data / power role events from the Type-C
> partner.
>
> While ANX7625 provides TCPCI interface, using it would circumvent the on-chip
> running firmware. Analogix recommended using the higher-level interface instead
> of TCPCI.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/gpu/drm/bridge/analogix/Kconfig | 1 +
> drivers/gpu/drm/bridge/analogix/anx7625.c | 163
> ++++++++++++++++++++++++++++--
> drivers/gpu/drm/bridge/analogix/anx7625.h | 21 +++-
> 3 files changed, 175 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig
> b/drivers/gpu/drm/bridge/analogix/Kconfig
> index
> 4846b2e9be7c2a5da18f6a3cdec53ef5766455e0..f3448b0631fea42e7e7ab10368
> 777a93ce33cee7 100644
> --- a/drivers/gpu/drm/bridge/analogix/Kconfig
> +++ b/drivers/gpu/drm/bridge/analogix/Kconfig
> @@ -34,6 +34,7 @@ config DRM_ANALOGIX_ANX7625
> tristate "Analogix Anx7625 MIPI to DP interface support"
> depends on DRM
> depends on OF
> + depends on TYPEC || !TYPEC
> select DRM_DISPLAY_DP_HELPER
> select DRM_DISPLAY_HDCP_HELPER
> select DRM_DISPLAY_HELPER
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c
> b/drivers/gpu/drm/bridge/analogix/anx7625.c
> index
> 6f3fdcb6afdb9d785bc4515300676cf3988c5807..a44405db739669dfd2907b0afd4
> 1293a7b173035 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> @@ -3,6 +3,7 @@
> * Copyright(c) 2020, Analogix Semiconductor. All rights reserved.
> *
> */
> +#include <linux/cleanup.h>
> #include <linux/gcd.h>
> #include <linux/gpio/consumer.h>
> #include <linux/i2c.h>
> @@ -15,6 +16,9 @@
> #include <linux/regulator/consumer.h>
> #include <linux/slab.h>
> #include <linux/types.h>
> +#include <linux/usb.h>
> +#include <linux/usb/pd.h>
> +#include <linux/usb/role.h>
> #include <linux/workqueue.h>
>
> #include <linux/of_graph.h>
> @@ -1325,7 +1329,7 @@ static int
> anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx) static void
> anx7625_disable_pd_protocol(struct anx7625_data *ctx) {
> struct device *dev = ctx->dev;
> - int ret, val;
> + int ret;
>
> /* Reset main ocm */
> ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40); @@ -
> 1339,6 +1343,11 @@ static void anx7625_disable_pd_protocol(struct
> anx7625_data *ctx)
> DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n");
> else
> DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature
> succeeded.\n");
> +}
> +
> +static void anx7625_configure_hpd(struct anx7625_data *ctx) {
> + int val;
>
> /*
> * Make sure the HPD GPIO already be configured after OCM release
> before @@ -1369,7 +1378,9 @@ static int anx7625_ocm_loading_check(struct
> anx7625_data *ctx)
> if ((ret & FLASH_LOAD_STA_CHK) != FLASH_LOAD_STA_CHK)
> return -ENODEV;
>
> - anx7625_disable_pd_protocol(ctx);
> + if (!ctx->typec_port)
> + anx7625_disable_pd_protocol(ctx);
> + anx7625_configure_hpd(ctx);
>
> DRM_DEV_DEBUG_DRIVER(dev, "Firmware ver %02x%02x,",
> anx7625_reg_read(ctx,
> @@ -1472,6 +1483,115 @@ static void anx7625_start_dp_work(struct
> anx7625_data *ctx)
> DRM_DEV_DEBUG_DRIVER(dev, "Secure OCM version=%02x\n", ret); }
>
> +#if IS_REACHABLE(CONFIG_TYPEC)
> +static void anx7625_typec_set_orientation(struct anx7625_data *ctx) {
> + u32 val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client,
> SYSTEM_STSTUS);
> +
> + if (val & (CC1_RP | CC1_RD))
> + typec_set_orientation(ctx->typec_port,
> TYPEC_ORIENTATION_NORMAL);
> + else if (val & (CC2_RP | CC2_RD))
> + typec_set_orientation(ctx->typec_port,
> TYPEC_ORIENTATION_REVERSE);
> + else
> + typec_set_orientation(ctx->typec_port,
> TYPEC_ORIENTATION_NONE); }
> +
> +static void anx7625_typec_isr(struct anx7625_data *ctx,
> + unsigned int intr_vector,
> + unsigned int intr_status)
> +{
> + if (intr_vector & CC_STATUS)
> + anx7625_typec_set_orientation(ctx);
> + if (intr_vector & DATA_ROLE_STATUS) {
> + usb_role_switch_set_role(ctx->role_sw,
> + (intr_status & DATA_ROLE_STATUS) ?
> + USB_ROLE_HOST :
> USB_ROLE_DEVICE);
> + typec_set_data_role(ctx->typec_port,
> + (intr_status & DATA_ROLE_STATUS) ?
> + TYPEC_HOST : TYPEC_DEVICE);
> + }
> + if (intr_vector & VBUS_STATUS)
> + typec_set_pwr_role(ctx->typec_port,
> + (intr_status & VBUS_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> + if (intr_vector & VCONN_STATUS)
> + typec_set_vconn_role(ctx->typec_port,
> + (intr_status & VCONN_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> +}
> +
> +static int anx7625_typec_register(struct anx7625_data *ctx) {
> + struct typec_capability typec_cap = { };
> + struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;
> + u32 val;
> + int ret;
> +
> + fwnode = device_get_named_child_node(ctx->dev, "connector");
> + if (!fwnode)
> + return 0;
> +
> + ret = typec_get_fw_cap(&typec_cap, fwnode);
> + if (ret < 0)
> + return ret;
> +
> + typec_cap.revision = 0x0120;
> + typec_cap.pd_revision = 0x0300;
> + typec_cap.usb_capability = USB_CAPABILITY_USB2 |
> USB_CAPABILITY_USB3;
> + typec_cap.orientation_aware = true;
> +
> + typec_cap.driver_data = ctx;
> +
> + ctx->typec_port = typec_register_port(ctx->dev, &typec_cap);
> + if (IS_ERR(ctx->typec_port))
> + return PTR_ERR(ctx->typec_port);
> +
> + ctx->role_sw = fwnode_usb_role_switch_get(fwnode);
> + if (IS_ERR(ctx->role_sw)) {
> + typec_unregister_port(ctx->typec_port);
> + return PTR_ERR(ctx->role_sw);
> + }
> +
> + val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
> + anx7625_typec_set_orientation(ctx);
> + usb_role_switch_set_role(ctx->role_sw,
> + (val & DATA_ROLE_STATUS) ?
> + USB_ROLE_HOST : USB_ROLE_DEVICE);
> + typec_set_data_role(ctx->typec_port,
> + (val & DATA_ROLE_STATUS) ?
> + TYPEC_HOST : TYPEC_DEVICE);
> + typec_set_pwr_role(ctx->typec_port,
> + (val & VBUS_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> + typec_set_vconn_role(ctx->typec_port,
> + (val & VCONN_STATUS) ?
> + TYPEC_SOURCE : TYPEC_SINK);
> +
> + return 0;
> +}
> +
> +static void anx7625_typec_unregister(struct anx7625_data *ctx) {
> + usb_role_switch_put(ctx->role_sw);
> + typec_unregister_port(ctx->typec_port);
> +}
> +#else
> +static void anx7625_typec_isr(struct anx7625_data *ctx,
> + unsigned int intr_vector,
> + unsigned int intr_status)
> +{
> +}
> +
> +static int anx7625_typec_register(struct anx7625_data *ctx) {
> + return 0;
> +}
> +
> +static void anx7625_typec_unregister(struct anx7625_data *ctx) { }
> +#endif
> +
> static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) {
> return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS);
> @@ -1566,7 +1686,7 @@ static void dp_hpd_change_handler(struct
> anx7625_data *ctx, bool on)
> }
> }
>
> -static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
> +static int anx7625_intr_status(struct anx7625_data *ctx)
> {
> int intr_vector, status;
> struct device *dev = ctx->dev;
> @@ -1593,9 +1713,6 @@ static int anx7625_hpd_change_detect(struct
> anx7625_data *ctx)
> return status;
> }
>
> - if (!(intr_vector & HPD_STATUS_CHANGE))
> - return -ENOENT;
> -
> status = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client,
> SYSTEM_STSTUS);
> if (status < 0) {
> @@ -1604,6 +1721,12 @@ static int anx7625_hpd_change_detect(struct
> anx7625_data *ctx)
> }
>
> DRM_DEV_DEBUG_DRIVER(dev, "0x7e:0x45=%x\n", status);
> +
> + anx7625_typec_isr(ctx, intr_vector, status);
> +
> + if (!(intr_vector & HPD_STATUS))
> + return -ENOENT;
> +
> dp_hpd_change_handler(ctx, status & HPD_STATUS);
>
> return 0;
> @@ -1622,7 +1745,7 @@ static void anx7625_work_func(struct work_struct
> *work)
> return;
> }
>
> - event = anx7625_hpd_change_detect(ctx);
> + event = anx7625_intr_status(ctx);
>
> mutex_unlock(&ctx->lock);
>
> @@ -2741,11 +2864,29 @@ static int anx7625_i2c_probe(struct i2c_client
> *client)
> }
>
> if (!platform->pdata.low_power_mode) {
> - anx7625_disable_pd_protocol(platform);
> + struct fwnode_handle *fwnode;
> +
> + fwnode = device_get_named_child_node(dev, "connector");
> + if (fwnode)
> + fwnode_handle_put(fwnode);
> + else
> + anx7625_disable_pd_protocol(platform);
> +
> + anx7625_configure_hpd(platform);
> +
> pm_runtime_get_sync(dev);
> _anx7625_hpd_polling(platform, 5000 * 100);
> }
>
> + if (platform->pdata.intp_irq)
> + anx7625_reg_write(platform, platform->i2c.rx_p0_client,
> + INTERFACE_CHANGE_INT_MASK, 0);
> +
> + /* After getting runtime handle */
> + ret = anx7625_typec_register(platform);
> + if (ret)
> + goto pm_suspend;
> +
> /* Add work function */
> if (platform->pdata.intp_irq) {
> enable_irq(platform->pdata.intp_irq);
> @@ -2759,6 +2900,10 @@ static int anx7625_i2c_probe(struct i2c_client
> *client)
>
> return 0;
>
> +pm_suspend:
> + if (!platform->pdata.low_power_mode)
> + pm_runtime_put_sync_suspend(&client->dev);
> +
> free_wq:
> if (platform->workqueue)
> destroy_workqueue(platform->workqueue);
> @@ -2774,6 +2919,8 @@ static void anx7625_i2c_remove(struct i2c_client
> *client) {
> struct anx7625_data *platform = i2c_get_clientdata(client);
>
> + anx7625_typec_unregister(platform);
> +
> drm_bridge_remove(&platform->bridge);
>
> if (platform->pdata.intp_irq)
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h
> b/drivers/gpu/drm/bridge/analogix/anx7625.h
> index
> eb5580f1ab2f86b48b6f2df4fa4d6c3be603ad48..f9570cd6d22e55fd70a12c15960
> 714cbb783d059 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.h
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h
> @@ -51,9 +51,21 @@
> #define INTR_RECEIVED_MSG BIT(5)
>
> #define SYSTEM_STSTUS 0x45
> +#define INTERFACE_CHANGE_INT_MASK 0x43
> #define INTERFACE_CHANGE_INT 0x44
> -#define HPD_STATUS_CHANGE 0x80
> -#define HPD_STATUS 0x80
> +#define VCONN_STATUS BIT(2)
> +#define VBUS_STATUS BIT(3)
> +#define CC_STATUS BIT(4)
> +#define DATA_ROLE_STATUS BIT(5)
> +#define HPD_STATUS BIT(7)
> +
> +#define NEW_CC_STATUS 0x46
> +#define CC1_RD BIT(0)
> +#define CC1_RA BIT(1)
> +#define CC1_RP (BIT(2) | BIT(3))
> +#define CC2_RD BIT(4)
> +#define CC2_RA BIT(5)
> +#define CC2_RP (BIT(6) | BIT(7))
>
> /******** END of I2C Address 0x58 ********/
>
> @@ -447,9 +459,14 @@ struct anx7625_i2c_client {
> struct i2c_client *tcpc_client;
> };
>
> +struct typec_port;
> +struct usb_role_switch;
> +
> struct anx7625_data {
> struct anx7625_platform_data pdata;
> struct platform_device *audio_pdev;
> + struct typec_port *typec_port;
> + struct usb_role_switch *role_sw;
> int hpd_status;
> int hpd_high_cnt;
> int dp_en;
>
> --
> 2.47.3
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-12-12 13:17 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-26 9:41 [PATCH RFC 0/2] drm: bridge: anx7625: implement Type-C support Dmitry Baryshkov
2025-11-26 9:41 ` [PATCH RFC 1/2] dt-bindings: drm/bridge: anx7625: describe Type-C connector Dmitry Baryshkov
2025-11-26 9:41 ` [PATCH RFC 2/2] drm: bridge: anx7625: implement minimal Type-C support Dmitry Baryshkov
2025-12-04 13:15 ` Heikki Krogerus
2025-12-06 3:31 ` Dmitry Baryshkov
2025-12-08 7:37 ` Xin Ji
2025-12-09 22:51 ` Dmitry Baryshkov
2025-12-12 12:39 ` Xin Ji
2025-12-12 13:17 ` Xin Ji
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).