mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Armin Wolf <W_Armin@gmx.de>
To: ilpo.jarvinen@linux.intel.com, hansg@kernel.org
Cc: platform-driver-x86@vger.kernel.org,
	linux-kernel@vger.kernel.org, wse@tuxedocomputers.com
Subject: [PATCH 4/7] platform/x86: uniwill-laptop: Add support for USB powershare
Date: Sat, 30 May 2026 19:08:10 +0200	[thread overview]
Message-ID: <20260530170813.10166-5-W_Armin@gmx.de> (raw)
In-Reply-To: <20260530170813.10166-1-W_Armin@gmx.de>

Some devices support a "USB powershare" feature where the system will
continue to provide power via the USB ports when hibernating or
powered off.

Add support for this feaure.

Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
 .../ABI/testing/sysfs-driver-uniwill-laptop   |  16 ++-
 .../admin-guide/laptops/uniwill-laptop.rst    |   7 ++
 drivers/platform/x86/uniwill/uniwill-acpi.c   | 100 ++++++++++++++++++
 3 files changed, 122 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-driver-uniwill-laptop b/Documentation/ABI/testing/sysfs-driver-uniwill-laptop
index 57272f906184..943f92c6b561 100644
--- a/Documentation/ABI/testing/sysfs-driver-uniwill-laptop
+++ b/Documentation/ABI/testing/sysfs-driver-uniwill-laptop
@@ -86,6 +86,20 @@ Contact:	Armin Wolf <W_Armin@gmx.de>
 Description:
 		Allows userspace applications to configure if the device should boot automatically
 		when being connected to a power source. Writing "1"/"0" into this file
-		enables/disables this functionality.
+		enables/disables this functionality. Enabling both AC auto boot and USB powershare
+		at the same time is not supported.
 
 		Reading this file returns the current status of the AC auto boot functionality.
+
+What:		/sys/bus/platform/devices/INOU0000:XX/usb_powershare_high
+Date:		March 2026
+KernelVersion:	7.1
+Contact:	Armin Wolf <W_Armin@gmx.de>
+Description:
+		Allows userspace applications to configure if the device should continue to provide
+		power via the USB ports when hibernating or powered off. Might also increase the
+		power budget available to USB ports on some devices. Writing "1"/"0" into this
+		file enables/disables this functionality. Enabling both USB powershare and AC auto
+		boot at the same time is not supported.
+
+		Reading this file returns the current status of the USB powershare functionality.
diff --git a/Documentation/admin-guide/laptops/uniwill-laptop.rst b/Documentation/admin-guide/laptops/uniwill-laptop.rst
index b6213fb1d3e0..be50b45b82ef 100644
--- a/Documentation/admin-guide/laptops/uniwill-laptop.rst
+++ b/Documentation/admin-guide/laptops/uniwill-laptop.rst
@@ -105,6 +105,13 @@ The ``uniwill-laptop`` driver allows the user to configure if the system should
 boot when being connected to a power source, see
 Documentation/ABI/testing/sysfs-driver-uniwill-laptop for details.
 
+USB Powershare
+--------------
+
+The ``uniwill-laptop`` driver allows the user to configure if the system should continue to
+provide power via the USB ports when hibernating or powered off, see
+Documentation/ABI/testing/sysfs-driver-uniwill-laptop for details.
+
 References
 ==========
 
diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c
index 897c6163de53..00140c0a67a0 100644
--- a/drivers/platform/x86/uniwill/uniwill-acpi.c
+++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
@@ -368,6 +368,7 @@
 #define UNIWILL_FEATURE_USB_C_POWER_PRIORITY	BIT(11)
 #define UNIWILL_FEATURE_KEYBOARD_BACKLIGHT	BIT(12)
 #define UNIWILL_FEATURE_AC_AUTO_BOOT		BIT(13)
+#define UNIWILL_FEATURE_USB_POWERSHARE		BIT(14)
 
 enum usb_c_power_priority_options {
 	USB_C_POWER_PRIORITY_CHARGING = 0,
@@ -393,6 +394,7 @@ struct uniwill_data {
 	bool last_fn_lock_state;
 	bool last_super_key_enable_state;
 	bool last_touchpad_toggle_enable_state;
+	bool last_usb_powershare_high_state;
 	struct mutex super_key_lock;	/* Protects the toggling of the super key lock state */
 	struct list_head batteries;
 	struct mutex led_lock;		/* Protects writes to the lightbar registers */
@@ -1181,6 +1183,70 @@ static ssize_t ac_auto_boot_show(struct device *dev, struct device_attribute *at
 
 static DEVICE_ATTR_RW(ac_auto_boot);
 
+static int uniwill_write_usb_powershare_high(struct uniwill_data *data, bool status)
+{
+	unsigned int value;
+
+	if (status)
+		value = TRIGGER_USB_CHARGING;
+	else
+		value = 0;
+
+	/*
+	 * Normaly this RMW-sequence could also trigger the super key toggle,
+	 * but the EC seems to take care that those bits are always read as 0.
+	 */
+	return regmap_update_bits(data->regmap, EC_ADDR_TRIGGER, TRIGGER_USB_CHARGING, value);
+}
+
+static ssize_t usb_powershare_high_store(struct device *dev, struct device_attribute *attr,
+					 const char *buf, size_t count)
+{
+	struct uniwill_data *data = dev_get_drvdata(dev);
+	bool enable;
+	int ret;
+
+	ret = kstrtobool(buf, &enable);
+	if (ret < 0)
+		return ret;
+
+	ret = uniwill_write_usb_powershare_high(data, enable);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static int uniwill_read_usb_powershare_high(struct uniwill_data *data, bool *status)
+{
+	unsigned int value;
+	int ret;
+
+	ret = regmap_read(data->regmap, EC_ADDR_TRIGGER, &value);
+	if (ret < 0)
+		return ret;
+
+	*status = !!(value & TRIGGER_USB_CHARGING);
+
+	return 0;
+}
+
+static ssize_t usb_powershare_high_show(struct device *dev, struct device_attribute *attr,
+					char *buf)
+{
+	struct uniwill_data *data = dev_get_drvdata(dev);
+	bool status;
+	int ret;
+
+	ret = uniwill_read_usb_powershare_high(data, &status);
+	if (ret < 0)
+		return ret;
+
+	return sysfs_emit(buf, "%d\n", status);
+}
+
+static DEVICE_ATTR_RW(usb_powershare_high);
+
 static struct attribute *uniwill_attrs[] = {
 	/* Keyboard-related */
 	&dev_attr_fn_lock.attr,
@@ -1193,6 +1259,7 @@ static struct attribute *uniwill_attrs[] = {
 	&dev_attr_ctgp_offset.attr,
 	&dev_attr_usb_c_power_priority.attr,
 	&dev_attr_ac_auto_boot.attr,
+	&dev_attr_usb_powershare_high.attr,
 	NULL
 };
 
@@ -1237,6 +1304,11 @@ static umode_t uniwill_attr_is_visible(struct kobject *kobj, struct attribute *a
 			return attr->mode;
 	}
 
+	if (attr == &dev_attr_usb_powershare_high.attr) {
+		if (uniwill_device_supports(data, UNIWILL_FEATURE_USB_POWERSHARE))
+			return attr->mode;
+	}
+
 	return 0;
 }
 
@@ -2382,6 +2454,18 @@ static int uniwill_suspend_kbd_led(struct uniwill_data *data)
 	return regmap_write(data->regmap, EC_ADDR_KBD_STATUS, regval);
 }
 
+static int uniwill_suspend_usb_powershare(struct uniwill_data *data)
+{
+	if (!uniwill_device_supports(data, UNIWILL_FEATURE_USB_POWERSHARE))
+		return 0;
+
+	/*
+	 * EC_ADDR_TRIGGER is marked as volatile, so we have to restore it
+	 * ourselves.
+	 */
+	return uniwill_read_usb_powershare_high(data, &data->last_usb_powershare_high_state);
+}
+
 static int uniwill_suspend_nvidia_ctgp(struct uniwill_data *data)
 {
 	if (!uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL))
@@ -2416,6 +2500,10 @@ static int uniwill_suspend(struct device *dev)
 	if (ret < 0)
 		return ret;
 
+	ret = uniwill_suspend_usb_powershare(data);
+	if (ret < 0)
+		return ret;
+
 	ret = uniwill_suspend_nvidia_ctgp(data);
 	if (ret < 0)
 		return ret;
@@ -2479,6 +2567,14 @@ static int uniwill_resume_kbd_led(struct uniwill_data *data)
 	return regmap_write_bits(data->regmap, EC_ADDR_TRIGGER, RGB_APPLY_COLOR, RGB_APPLY_COLOR);
 }
 
+static int uniwill_resume_usb_powershare(struct uniwill_data *data)
+{
+	if (!uniwill_device_supports(data, UNIWILL_FEATURE_USB_POWERSHARE))
+		return 0;
+
+	return uniwill_write_usb_powershare_high(data, data->last_usb_powershare_high_state);
+}
+
 static int uniwill_resume_nvidia_ctgp(struct uniwill_data *data)
 {
 	if (!uniwill_device_supports(data, UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL))
@@ -2527,6 +2623,10 @@ static int uniwill_resume(struct device *dev)
 	if (ret < 0)
 		return ret;
 
+	ret = uniwill_resume_usb_powershare(data);
+	if (ret < 0)
+		return ret;
+
 	ret = uniwill_resume_nvidia_ctgp(data);
 	if (ret < 0)
 		return ret;
-- 
2.39.5


  parent reply	other threads:[~2026-05-30 17:08 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-30 17:08 [PATCH 0/7] platform/x86: uniwill-laptop: Support additional features Armin Wolf
2026-05-30 17:08 ` [PATCH 1/7] platform/x86: uniwill-laptop: Add keyboard backlight support Armin Wolf
2026-07-08 19:11   ` Werner Sembach
2026-07-08 20:08     ` Armin Wolf
2026-07-08 20:15       ` Werner Sembach
2026-07-09  5:49         ` Armin Wolf
2026-07-09 13:23           ` Werner Sembach
2026-07-09 20:23             ` Armin Wolf
2026-05-30 17:08 ` [PATCH 2/7] platform/x86: uniwill-laptop: Handle screen-related events Armin Wolf
2026-05-30 17:08 ` [PATCH 3/7] platform/x86: uniwill-laptop: Add AC auto boot support Armin Wolf
2026-05-30 17:08 ` Armin Wolf [this message]
2026-05-30 17:08 ` [PATCH 5/7] platform/x86: uniwill-laptop: Add support for the MACHENIKE L16 Pro Armin Wolf
2026-05-30 17:08 ` [PATCH 6/7] platform/x86: uniwill-laptop: Add support for the AiStone X4SP4NAL Armin Wolf
2026-05-30 17:08 ` [PATCH 7/7] platform/x86: uniwill-laptop: Add lightbar support for LAPQC71A/B Armin Wolf
2026-07-08 20:08   ` Werner Sembach
2026-07-09  8:57     ` Ilpo Järvinen
2026-07-09 13:13       ` Werner Sembach
2026-07-09 13:45         ` Ilpo Järvinen
2026-07-09 14:06           ` Werner Sembach
2026-06-10 10:50 ` [PATCH 0/7] platform/x86: uniwill-laptop: Support additional features Ilpo Järvinen
2026-06-10 16:36   ` Armin Wolf
2026-06-11 13:21     ` Ilpo Järvinen
2026-06-11 15:00       ` Armin Wolf
2026-07-01 11:30 ` Ilpo Järvinen
2026-07-02 17:21   ` Armin Wolf

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=20260530170813.10166-5-W_Armin@gmx.de \
    --to=w_armin@gmx.de \
    --cc=hansg@kernel.org \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=wse@tuxedocomputers.com \
    /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