[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241030142833.v2.3.I439cffc7bf76d94f5850eb85980f1197c4f9154c@changeid>
Date: Wed, 30 Oct 2024 14:28:34 -0700
From: Abhishek Pandit-Subedi <abhishekpandit@...omium.org>
To: heikki.krogerus@...ux.intel.com,
tzungbi@...nel.org,
linux-usb@...r.kernel.org,
chrome-platform@...ts.linux.dev
Cc: dmitry.baryshkov@...aro.org,
jthies@...gle.com,
akuchynski@...gle.com,
pmalani@...omium.org,
Abhishek Pandit-Subedi <abhishekpandit@...omium.org>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
linux-kernel@...r.kernel.org
Subject: [PATCH v2 3/7] usb: typec: Auto enter control for alternate modes
Add controls for whether an alternate mode is automatically entered when
a partner connects. The auto_enter control is only available on ports
and applies immediately after a partner connects. The default behavior
is to enable auto enter and drivers must explicitly disable it.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@...omium.org>
---
(no changes since v1)
Documentation/ABI/testing/sysfs-bus-typec | 9 +++++++
drivers/usb/typec/altmodes/displayport.c | 6 +++--
drivers/usb/typec/altmodes/thunderbolt.c | 3 ++-
drivers/usb/typec/class.c | 31 +++++++++++++++++++++++
include/linux/usb/typec.h | 2 ++
include/linux/usb/typec_altmode.h | 2 ++
6 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-bus-typec b/Documentation/ABI/testing/sysfs-bus-typec
index 205d9c91e2e1..f09d05727b82 100644
--- a/Documentation/ABI/testing/sysfs-bus-typec
+++ b/Documentation/ABI/testing/sysfs-bus-typec
@@ -12,6 +12,15 @@ Description:
Valid values are boolean.
+What: /sys/bus/typec/devices/.../auto_enter
+Date: September 2024
+Contact: Heikki Krogerus <heikki.krogerus@...ux.intel.com>
+Description:
+ Controls whether a mode will be automatically entered when a partner is
+ connected.
+
+ This field is only valid and displayed on a port. Valid values are boolean.
+
What: /sys/bus/typec/devices/.../description
Date: July 2018
Contact: Heikki Krogerus <heikki.krogerus@...ux.intel.com>
diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c
index 2f03190a9873..62263f1d3a72 100644
--- a/drivers/usb/typec/altmodes/displayport.c
+++ b/drivers/usb/typec/altmodes/displayport.c
@@ -767,8 +767,10 @@ int dp_altmode_probe(struct typec_altmode *alt)
if (plug)
typec_altmode_set_drvdata(plug, dp);
- dp->state = plug ? DP_STATE_ENTER_PRIME : DP_STATE_ENTER;
- schedule_work(&dp->work);
+ if (port->auto_enter) {
+ dp->state = plug ? DP_STATE_ENTER_PRIME : DP_STATE_ENTER;
+ schedule_work(&dp->work);
+ }
return 0;
}
diff --git a/drivers/usb/typec/altmodes/thunderbolt.c b/drivers/usb/typec/altmodes/thunderbolt.c
index 8380b22d26a7..181892bf1225 100644
--- a/drivers/usb/typec/altmodes/thunderbolt.c
+++ b/drivers/usb/typec/altmodes/thunderbolt.c
@@ -212,6 +212,7 @@ static const struct typec_altmode_ops tbt_altmode_ops = {
static int tbt_altmode_probe(struct typec_altmode *alt)
{
+ const struct typec_altmode *port = typec_altmode_get_partner(alt);
struct tbt_altmode *tbt;
tbt = devm_kzalloc(&alt->dev, sizeof(*tbt), GFP_KERNEL);
@@ -226,7 +227,7 @@ static int tbt_altmode_probe(struct typec_altmode *alt)
typec_altmode_set_drvdata(alt, tbt);
typec_altmode_set_ops(alt, &tbt_altmode_ops);
- if (tbt_ready(alt)) {
+ if (port->auto_enter && tbt_ready(alt)) {
if (tbt->plug[TYPEC_PLUG_SOP_PP])
tbt->state = TBT_STATE_SOP_PP_ENTER;
else if (tbt->plug[TYPEC_PLUG_SOP_P])
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 85494b9f7502..e74f835c6859 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -403,6 +403,31 @@ static ssize_t active_store(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RW(active);
+static ssize_t
+auto_enter_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct typec_altmode *alt = to_typec_altmode(dev);
+
+ return sprintf(buf, "%s\n", alt->auto_enter ? "yes" : "no");
+}
+
+static ssize_t auto_enter_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct typec_altmode *adev = to_typec_altmode(dev);
+ bool auto_enter;
+ int ret;
+
+ ret = kstrtobool(buf, &auto_enter);
+ if (ret)
+ return ret;
+
+ adev->auto_enter = auto_enter;
+
+ return size;
+}
+static DEVICE_ATTR_RW(auto_enter);
+
static ssize_t
supported_roles_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -446,6 +471,7 @@ static DEVICE_ATTR_RO(svid);
static struct attribute *typec_altmode_attrs[] = {
&dev_attr_active.attr,
+ &dev_attr_auto_enter.attr,
&dev_attr_mode.attr,
&dev_attr_svid.attr,
&dev_attr_vdo.attr,
@@ -461,6 +487,10 @@ static umode_t typec_altmode_attr_is_visible(struct kobject *kobj,
if (!adev->ops || !adev->ops->activate)
return 0444;
+ if (attr == &dev_attr_auto_enter.attr)
+ if (!is_typec_port(adev->dev.parent))
+ return 0;
+
return attr->mode;
}
@@ -564,6 +594,7 @@ typec_register_altmode(struct device *parent,
if (is_port) {
alt->attrs[3] = &dev_attr_supported_roles.attr;
alt->adev.active = true; /* Enabled by default */
+ alt->adev.auto_enter = !desc->no_auto_enter;
}
sprintf(alt->group_name, "mode%d", desc->mode);
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index d616b8807000..5336b7c92ca4 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -139,6 +139,7 @@ int typec_cable_set_identity(struct typec_cable *cable);
* @svid: Standard or Vendor ID
* @mode: Index of the Mode
* @vdo: VDO returned by Discover Modes USB PD command
+ * @no_auto_enter: Only for ports. Disables auto enter which is default behavior.
* @roles: Only for ports. DRP if the mode is available in both roles
*
* Description of an Alternate Mode which a connector, cable plug or partner
@@ -148,6 +149,7 @@ struct typec_altmode_desc {
u16 svid;
u8 mode;
u32 vdo;
+ bool no_auto_enter;
/* Only used with ports */
enum typec_port_data roles;
};
diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
index b3c0866ea70f..ab7c3ebe4926 100644
--- a/include/linux/usb/typec_altmode.h
+++ b/include/linux/usb/typec_altmode.h
@@ -18,6 +18,7 @@ struct typec_altmode_ops;
* @mode: Index of the Mode
* @vdo: VDO returned by Discover Modes USB PD command
* @active: Tells has the mode been entered or not
+ * @auto_enter: Tells whether to auto-enter mode (only valid for port mode).
* @desc: Optional human readable description of the mode
* @ops: Operations vector from the driver
* @cable_ops: Cable operations vector from the driver.
@@ -28,6 +29,7 @@ struct typec_altmode {
int mode;
u32 vdo;
unsigned int active:1;
+ unsigned int auto_enter:1;
char *desc;
const struct typec_altmode_ops *ops;
--
2.47.0.163.g1226f6d8fa-goog
Powered by blists - more mailing lists