public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Won Chung <wonchung@google.com>
To: Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"Rafael J . Wysocki" <rafael@kernel.org>,
	Benson Leung <bleung@chromium.org>,
	Prashant Malani <pmalani@chromium.org>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Won Chung <wonchung@google.com>
Subject: [PATCH v2] usb:typec: Add sysfs support for Type C connector's physical location
Date: Tue,  1 Mar 2022 02:26:25 +0000	[thread overview]
Message-ID: <20220301022625.469446-1-wonchung@google.com> (raw)

When ACPI table includes _PLD field for a Type C connector, share _PLD
values in its sysfs. _PLD stands for physical location of device.

Currently without connector's location information, when there are
multiple Type C ports, it is hard to distinguish which connector
corresponds to which physical port at which location. For example, when
there are two Type C connectors, it is hard to find out which connector
corresponds to the Type C port on the left panel versus the Type C port
on the right panel. With location information provided, we can determine
which specific device at which location is doing what.

_PLD output includes much more fields, but only generic fields are added
and exposed to sysfs, so that non-ACPI devices can also support it in
the future. The minimal generic fields needed for locating a port are
the following.
- panel
- vertical_position
- horizontal_position
- dock
- lid

Signed-off-by: Won Chung <wonchung@google.com>
---

Changes in v2:
- Use string for location.
- Clarify get_pld() with naming and return type.

 Documentation/ABI/testing/sysfs-class-typec |  35 ++++++
 drivers/usb/typec/class.c                   | 113 ++++++++++++++++++++
 drivers/usb/typec/class.h                   |   3 +
 3 files changed, 151 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/ABI/testing/sysfs-class-typec
index 75088ecad202..4497a5aeb063 100644
--- a/Documentation/ABI/testing/sysfs-class-typec
+++ b/Documentation/ABI/testing/sysfs-class-typec
@@ -141,6 +141,41 @@ Description:
 		- "reverse": CC2 orientation
 		- "unknown": Orientation cannot be determined.
 
+What:		/sys/class/typec/<port>/location/panel
+Date:		March 2022
+Contact:	Won Chung <wonchung@google.com>
+Description:
+		Describes which panel surface of the system’s housing the
+		port resides on.
+
+What:		/sys/class/typec/<port>/location/vertical_position
+Date:		March 2022
+Contact:	Won Chung <wonchung@google.com>
+Description:
+		Describes vertical position of the port on the panel surface.
+		Valid values: upper, center, lower
+
+What:		/sys/class/typec/<port>/location/horizontal_position
+Date:		March 2022
+Contact:	Won Chung <wonchung@google.com>
+Description:
+		Describes horizontal position of the port on the panel surface.
+		Valid values: left, center, right
+
+What:		/sys/class/typec/<port>/location/dock
+Date:		March 2022
+Contact:	Won Chung <wonchung@google.com>
+Description:
+		Set as "yes" if the port resides in a docking station or a port
+		replicator, otherwise set as "no".
+
+What:		/sys/class/typec/<port>/location/lid
+Date:		March 2022
+Contact:	Won Chung <wonchung@google.com>
+Description:
+		Set as "yes" if the port resides on the lid of laptop system,
+		otherwise set as "no".
+
 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 45a6f0c807cb..5a52cb6728ec 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -1579,8 +1579,101 @@ static const struct attribute_group typec_group = {
 	.attrs = typec_attrs,
 };
 
+static const char * const typec_location_panel[] = {
+	"top",
+	"bottom",
+	"left",
+	"right",
+	"front",
+	"back",
+	"unknown",
+};
+
+static const char * const typec_location_vertical_position[] = {
+	"upper", "center", "lower"
+};
+
+static const char * const typec_location_horizontal_position[] = {
+	"left", "center", "right"
+};
+
+static ssize_t panel_show(struct device *dev, struct device_attribute *attr,
+	char *buf)
+{
+	struct typec_port *port = to_typec_port(dev);
+
+	if (port->pld)
+		return sprintf(buf, "%s\n",
+			typec_location_panel[port->pld->panel]);
+	return 0;
+};
+static DEVICE_ATTR_RO(panel);
+
+static ssize_t vertical_position_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct typec_port *port = to_typec_port(dev);
+
+	if (port->pld)
+		return sprintf(buf, "%s\n",
+			typec_location_vertical_position[
+				port->pld->vertical_position]);
+	return 0;
+};
+static DEVICE_ATTR_RO(vertical_position);
+
+static ssize_t horizontal_position_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct typec_port *port = to_typec_port(dev);
+
+	if (port->pld)
+		return sprintf(buf, "%s\n",
+			typec_location_horizontal_position[
+				port->pld->horizontal_position]);
+	return 0;
+};
+static DEVICE_ATTR_RO(horizontal_position);
+
+static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
+	char *buf)
+{
+	struct typec_port *port = to_typec_port(dev);
+
+	if (port->pld)
+		return sprintf(buf, "%s\n", port->pld->dock ? "yes" : "no");
+	return 0;
+};
+static DEVICE_ATTR_RO(dock);
+
+static ssize_t lid_show(struct device *dev, struct device_attribute *attr,
+	char *buf)
+{
+	struct typec_port *port = to_typec_port(dev);
+
+	if (port->pld)
+		return sprintf(buf, "%s\n", port->pld->lid ? "yes" : "no");
+	return 0;
+};
+static DEVICE_ATTR_RO(lid);
+
+static struct attribute *typec_location_attrs[] = {
+	&dev_attr_panel.attr,
+	&dev_attr_vertical_position.attr,
+	&dev_attr_horizontal_position.attr,
+	&dev_attr_dock.attr,
+	&dev_attr_lid.attr,
+	NULL,
+};
+
+static const struct attribute_group typec_location_group = {
+	.name = "location",
+	.attrs = typec_location_attrs,
+};
+
 static const struct attribute_group *typec_groups[] = {
 	&typec_group,
+	&typec_location_group,
 	NULL
 };
 
@@ -1614,6 +1707,24 @@ const struct device_type typec_port_dev_type = {
 	.release = typec_release,
 };
 
+static struct acpi_pld_info *get_acpi_pld_info(struct device *dev)
+{
+#if defined(CONFIG_ACPI)
+	struct acpi_pld_info *pld;
+	acpi_status status;
+
+	if (!has_acpi_companion(dev))
+		return NULL;
+
+	status = acpi_get_physical_device_location(ACPI_HANDLE(dev), &pld);
+	if (ACPI_FAILURE(status))
+		return NULL;
+	return pld;
+#else
+	return NULL;
+#endif
+}
+
 /* --------------------------------------- */
 /* Driver callbacks to report role updates */
 
@@ -2073,6 +2184,8 @@ struct typec_port *typec_register_port(struct device *parent,
 		return ERR_PTR(ret);
 	}
 
+	port->pld = get_acpi_pld_info(&port->dev);
+
 	ret = device_add(&port->dev);
 	if (ret) {
 		dev_err(parent, "failed to register port (%d)\n", ret);
diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h
index 0f1bd6d19d67..1b52633400c8 100644
--- a/drivers/usb/typec/class.h
+++ b/drivers/usb/typec/class.h
@@ -3,6 +3,7 @@
 #ifndef __USB_TYPEC_CLASS__
 #define __USB_TYPEC_CLASS__
 
+#include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/usb/typec.h>
 
@@ -54,6 +55,8 @@ struct typec_port {
 
 	const struct typec_capability	*cap;
 	const struct typec_operations   *ops;
+
+	struct acpi_pld_info		*pld;
 };
 
 #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev)
-- 
2.35.1.574.g5d30c73bfb-goog


             reply	other threads:[~2022-03-01  2:26 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-01  2:26 Won Chung [this message]
2022-03-01  9:33 ` [PATCH v2] usb:typec: Add sysfs support for Type C connector's physical location Heikki Krogerus
2022-03-01 18:57   ` Won Chung
2022-03-01 19:11     ` Rafael J. Wysocki
2022-03-02 11:21       ` Heikki Krogerus
2022-03-03 17:54         ` Won Chung

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220301022625.469446-1-wonchung@google.com \
    --to=wonchung@google.com \
    --cc=bleung@chromium.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=pmalani@chromium.org \
    --cc=rafael@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox