chrome-platform.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/5] USB Type-C alternate mode priorities
@ 2025-08-25 14:57 Andrei Kuchynski
  2025-08-25 14:57 ` [PATCH v2 1/5] usb: typec: Add alt_mode_override field to port property Andrei Kuchynski
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Andrei Kuchynski @ 2025-08-25 14:57 UTC (permalink / raw)
  To: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
	Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform
  Cc: Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
	Christian A. Ehrhardt, Venkat Jayaraman, linux-kernel,
	Andrei Kuchynski

This patch series introduces a mechanism for setting USB Type-C alternate
mode priorities. It allows the user to specify their preferred order for
mode selection, such as USB4, Thunderbolt, or DisplayPort.

A new sysfs attribute named 'priority' is exposed to provide user-space
control over the mode selection process.

This series was tested on a Android OS device running kernel 6.16.

Changes in v2:
- The priority variable is now a member of the typec_altmode struct
- typec_altmode2port is used to obtain the typec_port struct pointer
- Default priorities are now set based on the order of registration
- The mode_control capability is enabled by default
- The mode_selection_state struct will be introduced in a separate series
- svid will be used instead of the typec_mode_type enum

Andrei Kuchynski (5):
  usb: typec: Add alt_mode_override field to port property
  platform/chrome: cros_ec_typec: Set alt_mode_override flag
  usb: typec: ucsi: Set alt_mode_override flag
  usb: typec: Implement alternate mode priority handling
  usb: typec: Expose alternate mode priority via sysfs

 Documentation/ABI/testing/sysfs-class-typec | 11 ++++++
 drivers/platform/chrome/cros_ec_typec.c     |  1 +
 drivers/usb/typec/Makefile                  |  2 +-
 drivers/usb/typec/class.c                   | 41 +++++++++++++++++++--
 drivers/usb/typec/class.h                   |  2 +
 drivers/usb/typec/mode_selection.c          | 38 +++++++++++++++++++
 drivers/usb/typec/mode_selection.h          |  6 +++
 drivers/usb/typec/ucsi/ucsi.c               |  2 +
 include/linux/usb/typec.h                   |  1 +
 include/linux/usb/typec_altmode.h           |  1 +
 10 files changed, 100 insertions(+), 5 deletions(-)
 create mode 100644 drivers/usb/typec/mode_selection.c
 create mode 100644 drivers/usb/typec/mode_selection.h

-- 
2.51.0.rc2.233.g662b1ed5c5-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/5] usb: typec: Add alt_mode_override field to port property
  2025-08-25 14:57 [PATCH v2 0/5] USB Type-C alternate mode priorities Andrei Kuchynski
@ 2025-08-25 14:57 ` Andrei Kuchynski
  2025-08-25 14:57 ` [PATCH v2 2/5] platform/chrome: cros_ec_typec: Set alt_mode_override flag Andrei Kuchynski
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andrei Kuchynski @ 2025-08-25 14:57 UTC (permalink / raw)
  To: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
	Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform
  Cc: Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
	Christian A. Ehrhardt, Venkat Jayaraman, linux-kernel,
	Andrei Kuchynski

This new field in the port properties dictates whether the Platform Policy
Manager (PPM) allows the OS Policy Manager (OPM) to change the currently
active, negotiated alternate mode.

Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
---
 drivers/usb/typec/class.c | 9 ++++++---
 drivers/usb/typec/class.h | 2 ++
 include/linux/usb/typec.h | 1 +
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 67a533e35150..9f86605ce125 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -457,11 +457,13 @@ static umode_t typec_altmode_attr_is_visible(struct kobject *kobj,
 					     struct attribute *attr, int n)
 {
 	struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj));
+	struct typec_port *port = typec_altmode2port(adev);
 
 	if (attr == &dev_attr_active.attr)
-		if (!is_typec_port(adev->dev.parent) &&
-		    (!adev->ops || !adev->ops->activate))
-			return 0444;
+		if (!is_typec_port(adev->dev.parent)) {
+			if (!port->mode_control || !adev->ops || !adev->ops->activate)
+				return 0444;
+		}
 
 	return attr->mode;
 }
@@ -2681,6 +2683,7 @@ struct typec_port *typec_register_port(struct device *parent,
 	}
 
 	port->pd = cap->pd;
+	port->mode_control = !cap->no_mode_control;
 
 	ret = device_add(&port->dev);
 	if (ret) {
diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h
index db2fe96c48ff..c53a04b9dc75 100644
--- a/drivers/usb/typec/class.h
+++ b/drivers/usb/typec/class.h
@@ -80,6 +80,8 @@ struct typec_port {
 	 */
 	struct device			*usb2_dev;
 	struct device			*usb3_dev;
+
+	bool				mode_control;
 };
 
 #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev)
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 252af3f77039..cbc94282e45e 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -304,6 +304,7 @@ struct typec_capability {
 	enum typec_accessory	accessory[TYPEC_MAX_ACCESSORY];
 	unsigned int		orientation_aware:1;
 	u8			usb_capability;
+	bool			no_mode_control;
 
 	struct fwnode_handle	*fwnode;
 	void			*driver_data;
-- 
2.51.0.rc2.233.g662b1ed5c5-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/5] platform/chrome: cros_ec_typec: Set alt_mode_override flag
  2025-08-25 14:57 [PATCH v2 0/5] USB Type-C alternate mode priorities Andrei Kuchynski
  2025-08-25 14:57 ` [PATCH v2 1/5] usb: typec: Add alt_mode_override field to port property Andrei Kuchynski
@ 2025-08-25 14:57 ` Andrei Kuchynski
  2025-08-25 14:57 ` [PATCH v2 3/5] usb: typec: ucsi: " Andrei Kuchynski
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andrei Kuchynski @ 2025-08-25 14:57 UTC (permalink / raw)
  To: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
	Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform
  Cc: Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
	Christian A. Ehrhardt, Venkat Jayaraman, linux-kernel,
	Andrei Kuchynski

This flag specifies that the Embedded Controller (EC) must receive explicit
approval from the Application Processor (AP) before initiating Type-C
alternate modes or USB4 mode.

Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
---
 drivers/platform/chrome/cros_ec_typec.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index b712bcff6fb2..c0806c562bb9 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -491,6 +491,7 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
 
 		cap->driver_data = cros_port;
 		cap->ops = &cros_typec_usb_mode_ops;
+		cap->no_mode_control = !typec->ap_driven_altmode;
 
 		cros_port->port = typec_register_port(dev, cap);
 		if (IS_ERR(cros_port->port)) {
-- 
2.51.0.rc2.233.g662b1ed5c5-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/5] usb: typec: ucsi: Set alt_mode_override flag
  2025-08-25 14:57 [PATCH v2 0/5] USB Type-C alternate mode priorities Andrei Kuchynski
  2025-08-25 14:57 ` [PATCH v2 1/5] usb: typec: Add alt_mode_override field to port property Andrei Kuchynski
  2025-08-25 14:57 ` [PATCH v2 2/5] platform/chrome: cros_ec_typec: Set alt_mode_override flag Andrei Kuchynski
@ 2025-08-25 14:57 ` Andrei Kuchynski
  2025-08-25 14:57 ` [PATCH v2 4/5] usb: typec: Implement alternate mode priority handling Andrei Kuchynski
  2025-08-25 14:57 ` [PATCH v2 5/5] usb: typec: Expose alternate mode priority via sysfs Andrei Kuchynski
  4 siblings, 0 replies; 6+ messages in thread
From: Andrei Kuchynski @ 2025-08-25 14:57 UTC (permalink / raw)
  To: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
	Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform
  Cc: Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
	Christian A. Ehrhardt, Venkat Jayaraman, linux-kernel,
	Andrei Kuchynski

This flag indicates that the PPM allows the OPM to change the currently
negotiated alternate mode using the SET_NEW_CAM command.

Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
---
 drivers/usb/typec/ucsi/ucsi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 0d6b0cf5a7cd..85a6b7fc6d93 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -1632,6 +1632,8 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con)
 
 	cap->driver_data = con;
 	cap->ops = &ucsi_ops;
+	cap->no_mode_control =
+		!(con->ucsi->cap.features & UCSI_CAP_ALT_MODE_OVERRIDE);
 
 	if (ucsi->ops->update_connector)
 		ucsi->ops->update_connector(con);
-- 
2.51.0.rc2.233.g662b1ed5c5-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 4/5] usb: typec: Implement alternate mode priority handling
  2025-08-25 14:57 [PATCH v2 0/5] USB Type-C alternate mode priorities Andrei Kuchynski
                   ` (2 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH v2 3/5] usb: typec: ucsi: " Andrei Kuchynski
@ 2025-08-25 14:57 ` Andrei Kuchynski
  2025-08-25 14:57 ` [PATCH v2 5/5] usb: typec: Expose alternate mode priority via sysfs Andrei Kuchynski
  4 siblings, 0 replies; 6+ messages in thread
From: Andrei Kuchynski @ 2025-08-25 14:57 UTC (permalink / raw)
  To: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
	Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform
  Cc: Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
	Christian A. Ehrhardt, Venkat Jayaraman, linux-kernel,
	Andrei Kuchynski

This patch introduces APIs to manage the priority of USB Type-C alternate
modes. These APIs allow for setting and retrieving a priority number for
each mode. If a new priority value conflicts with an existing mode's
priority, the priorities of the conflicting mode and all subsequent modes
are automatically incremented to ensure uniqueness.

Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
---
 drivers/usb/typec/Makefile         |  2 +-
 drivers/usb/typec/mode_selection.c | 38 ++++++++++++++++++++++++++++++
 drivers/usb/typec/mode_selection.h |  6 +++++
 include/linux/usb/typec_altmode.h  |  1 +
 4 files changed, 46 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/typec/mode_selection.c
 create mode 100644 drivers/usb/typec/mode_selection.h

diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
index 7a368fea61bc..8a6a1c663eb6 100644
--- a/drivers/usb/typec/Makefile
+++ b/drivers/usb/typec/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_TYPEC)		+= typec.o
-typec-y				:= class.o mux.o bus.o pd.o retimer.o
+typec-y				:= class.o mux.o bus.o pd.o retimer.o mode_selection.o
 typec-$(CONFIG_ACPI)		+= port-mapper.o
 obj-$(CONFIG_TYPEC)		+= altmodes/
 obj-$(CONFIG_TYPEC_TCPM)	+= tcpm/
diff --git a/drivers/usb/typec/mode_selection.c b/drivers/usb/typec/mode_selection.c
new file mode 100644
index 000000000000..2179bf25f5d4
--- /dev/null
+++ b/drivers/usb/typec/mode_selection.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2025 Google LLC.
+ */
+
+#include "mode_selection.h"
+#include "class.h"
+#include "bus.h"
+
+static int increment_duplicated_priority(struct device *dev, void *data)
+{
+	struct typec_altmode **alt_target = (struct typec_altmode **)data;
+
+	if (is_typec_altmode(dev)) {
+		struct typec_altmode *alt = to_typec_altmode(dev);
+
+		if (alt != *alt_target && alt->priority == (*alt_target)->priority) {
+			alt->priority++;
+			*alt_target = alt;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+void typec_mode_set_priority(struct typec_altmode *alt,
+		const unsigned int priority)
+{
+	struct typec_port *port = to_typec_port(alt->dev.parent);
+	int res = 1;
+
+	alt->priority = priority;
+
+	while (res)
+		res = device_for_each_child(&port->dev, &alt,
+				increment_duplicated_priority);
+}
diff --git a/drivers/usb/typec/mode_selection.h b/drivers/usb/typec/mode_selection.h
new file mode 100644
index 000000000000..cbf5a37e6404
--- /dev/null
+++ b/drivers/usb/typec/mode_selection.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/usb/typec_altmode.h>
+
+void typec_mode_set_priority(struct typec_altmode *alt,
+		const unsigned int priority);
diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
index b3c0866ea70f..571c6e00b54f 100644
--- a/include/linux/usb/typec_altmode.h
+++ b/include/linux/usb/typec_altmode.h
@@ -28,6 +28,7 @@ struct typec_altmode {
 	int				mode;
 	u32				vdo;
 	unsigned int			active:1;
+	unsigned int			priority;
 
 	char				*desc;
 	const struct typec_altmode_ops	*ops;
-- 
2.51.0.rc2.233.g662b1ed5c5-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 5/5] usb: typec: Expose alternate mode priority via sysfs
  2025-08-25 14:57 [PATCH v2 0/5] USB Type-C alternate mode priorities Andrei Kuchynski
                   ` (3 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH v2 4/5] usb: typec: Implement alternate mode priority handling Andrei Kuchynski
@ 2025-08-25 14:57 ` Andrei Kuchynski
  4 siblings, 0 replies; 6+ messages in thread
From: Andrei Kuchynski @ 2025-08-25 14:57 UTC (permalink / raw)
  To: Heikki Krogerus, Abhishek Pandit-Subedi, Benson Leung,
	Jameson Thies, Tzung-Bi Shih, linux-usb, chrome-platform
  Cc: Guenter Roeck, Greg Kroah-Hartman, Dmitry Baryshkov,
	Christian A. Ehrhardt, Venkat Jayaraman, linux-kernel,
	Andrei Kuchynski

This patch introduces a priority sysfs attribute to the USB Type-C
alternate mode port interface. This new attribute allows user-space to
configure the numeric priority of alternate modes managing their preferred
order of operation.

Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
---
 Documentation/ABI/testing/sysfs-class-typec | 11 +++++++
 drivers/usb/typec/class.c                   | 32 ++++++++++++++++++++-
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/ABI/testing/sysfs-class-typec
index 38e101c17a00..dab3e4e727b6 100644
--- a/Documentation/ABI/testing/sysfs-class-typec
+++ b/Documentation/ABI/testing/sysfs-class-typec
@@ -162,6 +162,17 @@ Description:	Lists the supported USB Modes. The default USB mode that is used
 		- usb3 (USB 3.2)
 		- usb4 (USB4)
 
+		What:		/sys/class/typec/<port>/<alt-mode>/priority
+Date:		July 2025
+Contact:	Andrei Kuchynski <akuchynski@chromium.org>
+Description:
+		Displays and allows setting the priority for a specific alt-mode.
+		When read, it shows the current integer priority value. Lower numerical
+		values indicate higher priority (0 is the highest priority).
+		If the new value is already in use by another mode, the priority of the
+		conflicting mode and any subsequent modes will be incremented until they
+		are all unique.
+
 USB Type-C partner devices (eg. /sys/class/typec/port0-partner/)
 
 What:		/sys/class/typec/<port>-partner/accessory_mode
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 9f86605ce125..aaab2e1e98b4 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -19,6 +19,7 @@
 #include "bus.h"
 #include "class.h"
 #include "pd.h"
+#include "mode_selection.h"
 
 static DEFINE_IDA(typec_index_ida);
 
@@ -445,11 +446,34 @@ svid_show(struct device *dev, struct device_attribute *attr, char *buf)
 }
 static DEVICE_ATTR_RO(svid);
 
+static ssize_t priority_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t size)
+{
+	unsigned int val;
+	int err = kstrtouint(buf, 10, &val);
+
+	if (!err) {
+		typec_mode_set_priority(to_typec_altmode(dev), val);
+		return size;
+	}
+
+	return err;
+}
+
+static ssize_t priority_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%u\n", to_typec_altmode(dev)->priority);
+}
+static DEVICE_ATTR_RW(priority);
+
 static struct attribute *typec_altmode_attrs[] = {
 	&dev_attr_active.attr,
 	&dev_attr_mode.attr,
 	&dev_attr_svid.attr,
 	&dev_attr_vdo.attr,
+	&dev_attr_priority.attr,
 	NULL
 };
 
@@ -459,11 +483,15 @@ static umode_t typec_altmode_attr_is_visible(struct kobject *kobj,
 	struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj));
 	struct typec_port *port = typec_altmode2port(adev);
 
-	if (attr == &dev_attr_active.attr)
+	if (attr == &dev_attr_active.attr) {
 		if (!is_typec_port(adev->dev.parent)) {
 			if (!port->mode_control || !adev->ops || !adev->ops->activate)
 				return 0444;
 		}
+	} else if (attr == &dev_attr_priority.attr) {
+		if (!is_typec_port(adev->dev.parent) || !port->mode_control)
+			return 0;
+	}
 
 	return attr->mode;
 }
@@ -2491,6 +2519,8 @@ typec_port_register_altmode(struct typec_port *port,
 		to_altmode(adev)->retimer = retimer;
 	}
 
+	typec_mode_set_priority(adev, 0);
+
 	return adev;
 }
 EXPORT_SYMBOL_GPL(typec_port_register_altmode);
-- 
2.51.0.rc2.233.g662b1ed5c5-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-08-25 14:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-25 14:57 [PATCH v2 0/5] USB Type-C alternate mode priorities Andrei Kuchynski
2025-08-25 14:57 ` [PATCH v2 1/5] usb: typec: Add alt_mode_override field to port property Andrei Kuchynski
2025-08-25 14:57 ` [PATCH v2 2/5] platform/chrome: cros_ec_typec: Set alt_mode_override flag Andrei Kuchynski
2025-08-25 14:57 ` [PATCH v2 3/5] usb: typec: ucsi: " Andrei Kuchynski
2025-08-25 14:57 ` [PATCH v2 4/5] usb: typec: Implement alternate mode priority handling Andrei Kuchynski
2025-08-25 14:57 ` [PATCH v2 5/5] usb: typec: Expose alternate mode priority via sysfs Andrei Kuchynski

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).