X86 platform drivers
 help / color / mirror / Atom feed
From: "Barnabás Pőcze" <pobrn@protonmail.com>
To: platform-driver-x86@vger.kernel.org,
	Hans de Goede <hdegoede@redhat.com>,
	Mark Gross <mgross@linux.intel.com>,
	Ike Panhc <ike.pan@canonical.com>
Subject: [PATCH 22/24] platform/x86: ideapad-laptop: add "always on USB charging" control support
Date: Wed, 16 Dec 2020 01:40:45 +0000	[thread overview]
Message-ID: <20201216013857.360987-23-pobrn@protonmail.com> (raw)

Certain models have a so-called "always on USB charging" feature, which
enables USB charging even when the computer is turned off or suspended,
and which may be controlled/queried using the SALS/HALS ACPI methods.
Expose this functionality via a new device attribute (usb_charging).
Tested on: Lenovo YOGA 520-14IKB 80X8

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>

diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index a43574e65f61..5f7883e59f21 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -58,18 +58,22 @@ enum {
 };
 
 enum {
-	HALS_KBD_BL_SUPPORT_BIT  = 4,
-	HALS_KBD_BL_STATE_BIT    = 5,
-	HALS_FNLOCK_SUPPORT_BIT  = 9,
-	HALS_FNLOCK_STATE_BIT    = 10,
-	HALS_HOTKEYS_PRIMARY_BIT = 11,
+	HALS_KBD_BL_SUPPORT_BIT       = 4,
+	HALS_KBD_BL_STATE_BIT         = 5,
+	HALS_USB_CHARGING_SUPPORT_BIT = 6,
+	HALS_USB_CHARGING_STATE_BIT   = 7,
+	HALS_FNLOCK_SUPPORT_BIT       = 9,
+	HALS_FNLOCK_STATE_BIT         = 10,
+	HALS_HOTKEYS_PRIMARY_BIT      = 11,
 };
 
 enum {
-	SALS_KBD_BL_ON  = 0x8,
-	SALS_KBD_BL_OFF = 0x9,
-	SALS_FNLOCK_ON  = 0xe,
-	SALS_FNLOCK_OFF = 0xf,
+	SALS_KBD_BL_ON        = 0x8,
+	SALS_KBD_BL_OFF       = 0x9,
+	SALS_USB_CHARGING_ON  = 0xa,
+	SALS_USB_CHARGING_OFF = 0xb,
+	SALS_FNLOCK_ON        = 0xe,
+	SALS_FNLOCK_OFF       = 0xf,
 };
 
 enum {
@@ -118,6 +122,7 @@ struct ideapad_private {
 		bool fan_mode          : 1,
 		     conservation_mode : 1,
 		     fn_lock           : 1,
+		     usb_charging      : 1,
 		     hw_rfkill_switch  : 1;
 	} features;
 	struct {
@@ -581,12 +586,50 @@ static ssize_t fn_lock_store(struct device *dev,
 
 static DEVICE_ATTR_RW(fn_lock);
 
+static ssize_t usb_charging_show(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct ideapad_private *priv = dev_get_drvdata(dev);
+	unsigned long hals;
+	int err;
+
+	err = eval_hals(priv->adev->handle, &hals);
+	if (err)
+		return err;
+
+	return sysfs_emit(buf, "%u\n", test_bit(HALS_USB_CHARGING_STATE_BIT, &hals));
+}
+
+static ssize_t usb_charging_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	struct ideapad_private *priv = dev_get_drvdata(dev);
+	bool state;
+	int err;
+
+	err = kstrtobool(buf, &state);
+	if (err)
+		return err;
+
+	err = eval_sals(priv->adev->handle,
+			state ? SALS_USB_CHARGING_ON : SALS_USB_CHARGING_OFF);
+	if (err)
+		return err;
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(usb_charging);
+
 static struct attribute *ideapad_attributes[] = {
 	&dev_attr_camera_power.attr,
 	&dev_attr_fan_mode.attr,
 	&dev_attr_touchpad.attr,
 	&dev_attr_conservation_mode.attr,
 	&dev_attr_fn_lock.attr,
+	&dev_attr_usb_charging.attr,
 	NULL
 };
 
@@ -608,6 +651,8 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
 		supported = priv->features.conservation_mode;
 	else if (attr == &dev_attr_fn_lock.attr)
 		supported = priv->features.fn_lock;
+	else if (attr == &dev_attr_usb_charging.attr)
+		supported = priv->features.usb_charging;
 
 	return supported ? attr->mode : 0;
 }
@@ -1175,9 +1220,13 @@ static void ideapad_check_features(struct ideapad_private *priv)
 		priv->features.conservation_mode = true;
 
 	if (acpi_has_method(handle, "HALS") && acpi_has_method(handle, "SALS")) {
-		if (!eval_hals(handle, &val))
+		if (!eval_hals(handle, &val)) {
 			if (test_bit(HALS_FNLOCK_SUPPORT_BIT, &val))
 				priv->features.fn_lock = true;
+
+			if (test_bit(HALS_USB_CHARGING_SUPPORT_BIT, &val))
+				priv->features.usb_charging = true;
+		}
 	}
 }
 
-- 
2.29.2



                 reply	other threads:[~2020-12-16  1:42 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20201216013857.360987-23-pobrn@protonmail.com \
    --to=pobrn@protonmail.com \
    --cc=hdegoede@redhat.com \
    --cc=ike.pan@canonical.com \
    --cc=mgross@linux.intel.com \
    --cc=platform-driver-x86@vger.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