diff mbox series

platform/x86: asus-wmi: Add support for charge threshold

Message ID 20190805192305.9692-1-kristian@klausen.dk (mailing list archive)
State Accepted, archived
Headers show
Series platform/x86: asus-wmi: Add support for charge threshold | expand

Commit Message

Kristian Klausen Aug. 5, 2019, 7:23 p.m. UTC
Most newer ASUS laptops supports limiting the battery charge level, which
help prolonging the battery life.

Tested on a Zenbook UX430UNR.

Signed-off-by: Kristian Klausen <kristian@klausen.dk>
---
I'm not sure what to call it, is charge threshold good enough or do you
have any better ideas?

 drivers/platform/x86/asus-wmi.c            | 48 ++++++++++++++++++++++
 include/linux/platform_data/x86/asus-wmi.h |  1 +
 2 files changed, 49 insertions(+)

Comments

Daniel Drake Aug. 8, 2019, 8:13 a.m. UTC | #1
On Tue, Aug 6, 2019 at 3:23 AM Kristian Klausen <kristian@klausen.dk> wrote:
>
> Most newer ASUS laptops supports limiting the battery charge level, which
> help prolonging the battery life.
>
> Tested on a Zenbook UX430UNR.
>
> Signed-off-by: Kristian Klausen <kristian@klausen.dk>
> ---
> I'm not sure what to call it, is charge threshold good enough or do you
> have any better ideas?

The spec calls it "Maximum Charging Percentage". I think something
along those lines would be clearer.

It would be good to have a one line explanatory comment against where
you introduce the variable, so that it's clear from glancing at the
code (not just the commit message) what this functionality actually
is.

Also you need a Documentation/ entry for this new file where you can
describe it a little more verbosely.

The 0x00120057 device is officially called "Relative state of charge",
not sure if you want to somehow follow a similar naming scheme there,
I don't have a real preference.

>  /* Misc */
>  #define ASUS_WMI_DEVID_CAMERA          0x00060013
> +#define ASUS_WMI_CHARGE_THRESHOLD      0x00120057

Please keep the devices ordered numerically by their ID

Thanks
Daniel
Kristian Klausen Aug. 8, 2019, 8:06 p.m. UTC | #2
On 08.08.2019 10.13, Daniel Drake wrote:
> On Tue, Aug 6, 2019 at 3:23 AM Kristian Klausen <kristian@klausen.dk> wrote:
>> Most newer ASUS laptops supports limiting the battery charge level, which
>> help prolonging the battery life.
>>
>> Tested on a Zenbook UX430UNR.
>>
>> Signed-off-by: Kristian Klausen <kristian@klausen.dk>
>> ---
>> I'm not sure what to call it, is charge threshold good enough or do you
>> have any better ideas?
> The spec calls it "Maximum Charging Percentage". I think something
> along those lines would be clearer.
I just sent a V2 patch.
I'm using "maximum charging percentage" in the documentation/commit 
message, but the knob is still named "charge_threshold".
> It would be good to have a one line explanatory comment against where
> you introduce the variable, so that it's clear from glancing at the
> code (not just the commit message) what this functionality actually
> is.documentation
Ack
> Also you need a Documentation/ entry for this new file where you can
> describe it a little more verbosely.
Ack
> The 0x00120057 device is officially called "Relative state of charge",
> not sure if you want to somehow follow a similar naming scheme there,
> I don't have a real preference.
The same name is used in ASUS online documentation. I change it.
https://www.asus.com/us/support/FAQ/1032726/
The current name also seems to lack DEVID.
>>   /* Misc */
>>   #define ASUS_WMI_DEVID_CAMERA          0x00060013
>> +#define ASUS_WMI_CHARGE_THRESHOLD      0x00120057
> Please keep the devices ordered numerically by their ID
Ack

Kristian
diff mbox series

Patch

diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 34dfbed65332..22ae350e0a96 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -195,6 +195,8 @@  struct asus_wmi {
 	u8 fan_boost_mode_mask;
 	u8 fan_boost_mode;
 
+	int charge_threshold;
+
 	struct hotplug_slot hotplug_slot;
 	struct mutex hotplug_lock;
 	struct mutex wmi_lock;
@@ -2075,6 +2077,43 @@  static ssize_t cpufv_store(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR_WO(cpufv);
 
+
+static ssize_t charge_threshold_store(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	struct asus_wmi *asus = dev_get_drvdata(dev);
+	int value, ret, rv;
+
+	ret = kstrtouint(buf, 10, &value);
+
+	if (!count || ret != 0)
+		return -EINVAL;
+	if (value < 0 || value > 100)
+		return -EINVAL;
+
+	asus_wmi_set_devstate(ASUS_WMI_CHARGE_THRESHOLD, value, &rv);
+
+	if (rv != 1)
+		return -EIO;
+
+	/* There isn't any method in the DSDT to read the threshold, so we
+	 * save the threshold.
+	 */
+	asus->charge_threshold = value;
+	return count;
+}
+
+static ssize_t charge_threshold_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct asus_wmi *asus = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", asus->charge_threshold);
+}
+
+static DEVICE_ATTR_RW(charge_threshold);
+
 static struct attribute *platform_attributes[] = {
 	&dev_attr_cpufv.attr,
 	&dev_attr_camera.attr,
@@ -2083,6 +2122,7 @@  static struct attribute *platform_attributes[] = {
 	&dev_attr_lid_resume.attr,
 	&dev_attr_als_enable.attr,
 	&dev_attr_fan_boost_mode.attr,
+	&dev_attr_charge_threshold.attr,
 	NULL
 };
 
@@ -2106,6 +2146,8 @@  static umode_t asus_sysfs_is_visible(struct kobject *kobj,
 		devid = ASUS_WMI_DEVID_ALS_ENABLE;
 	else if (attr == &dev_attr_fan_boost_mode.attr)
 		ok = asus->fan_boost_mode_available;
+	else if (attr == &dev_attr_charge_threshold.attr)
+		devid = ASUS_WMI_CHARGE_THRESHOLD;
 
 	if (devid != -1)
 		ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
@@ -2434,6 +2476,12 @@  static int asus_wmi_add(struct platform_device *pdev)
 	}
 
 	asus_wmi_debugfs_init(asus);
+	/* The charge threshold is only reset when the system is power cycled,
+	 * and we can't get the current threshold so let set it to 100% on
+	 * module load.
+	 */
+	asus_wmi_set_devstate(ASUS_WMI_CHARGE_THRESHOLD, 100, NULL);
+	asus->charge_threshold = 100;
 
 	return 0;
 
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
index 409e16064f4b..53934ef38d98 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -61,6 +61,7 @@ 
 
 /* Misc */
 #define ASUS_WMI_DEVID_CAMERA		0x00060013
+#define ASUS_WMI_CHARGE_THRESHOLD	0x00120057
 
 /* Storage */
 #define ASUS_WMI_DEVID_CARDREADER	0x00080013