All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.