Most newer ASUS laptops supports limiting the battery charge level, which help prolonging the battery life. Tested on a Zenbook UX430UNR.
Unified · Split
| @@ -195,6 +195,8 @@ struct asus_wmi { · 194 unmodified lines | |||
| 195 | u8 fan_boost_mode_mask; | 195 | u8 fan_boost_mode_mask; |
| 196 | u8 fan_boost_mode; | 196 | u8 fan_boost_mode; |
| 197 | 197 | ||
| 198 | int charge_threshold; | ||
| 199 | |||
| 198 | struct hotplug_slot hotplug_slot; | 200 | struct hotplug_slot hotplug_slot; |
| 199 | struct mutex hotplug_lock; | 201 | struct mutex hotplug_lock; |
| 200 | struct mutex wmi_lock; | 202 | struct mutex wmi_lock; |
| @@ -2075,6 +2077,43 @@ static ssize_t cpufv_store(struct device *dev, struct device_attribute *attr, · 1874 unmodified lines | |||
| 2075 | 2077 | ||
| 2076 | static DEVICE_ATTR_WO(cpufv); | 2078 | static DEVICE_ATTR_WO(cpufv); |
| 2077 | 2079 | ||
| 2080 | |||
| 2081 | static ssize_t charge_threshold_store(struct device *dev, | ||
| 2082 | struct device_attribute *attr, | ||
| 2083 | const char *buf, size_t count) | ||
| 2084 | { | ||
| 2085 | struct asus_wmi *asus = dev_get_drvdata(dev); | ||
| 2086 | int value, ret, rv; | ||
| 2087 | |||
| 2088 | ret = kstrtouint(buf, 10, &value); | ||
| 2089 | |||
| 2090 | if (!count || ret != 0) | ||
| 2091 | return -EINVAL; | ||
| 2092 | if (value < 0 || value > 100) | ||
| 2093 | return -EINVAL; | ||
| 2094 | |||
| 2095 | asus_wmi_set_devstate(ASUS_WMI_CHARGE_THRESHOLD, value, &rv); | ||
| 2096 | |||
| 2097 | if (rv != 1) | ||
| 2098 | return -EIO; | ||
| 2099 | |||
| 2100 | /* There isn't any method in the DSDT to read the threshold, so we | ||
| 2101 | * save the threshold. | ||
| 2102 | */ | ||
| 2103 | asus->charge_threshold = value; | ||
| 2104 | return count; | ||
| 2105 | } | ||
| 2106 | |||
| 2107 | static ssize_t charge_threshold_show(struct device *dev, | ||
| 2108 | struct device_attribute *attr, char *buf) | ||
| 2109 | { | ||
| 2110 | struct asus_wmi *asus = dev_get_drvdata(dev); | ||
| 2111 | |||
| 2112 | return sprintf(buf, "%d\n", asus->charge_threshold); | ||
| 2113 | } | ||
| 2114 | |||
| 2115 | static DEVICE_ATTR_RW(charge_threshold); | ||
| 2116 | |||
| 2078 | static struct attribute *platform_attributes[] = { | 2117 | static struct attribute *platform_attributes[] = { |
| 2079 | &dev_attr_cpufv.attr, | 2118 | &dev_attr_cpufv.attr, |
| 2080 | &dev_attr_camera.attr, | 2119 | &dev_attr_camera.attr, |
| @@ -2083,6 +2122,7 @@ static struct attribute *platform_attributes[] = { · 2 unmodified lines | |||
| 2083 | &dev_attr_lid_resume.attr, | 2122 | &dev_attr_lid_resume.attr, |
| 2084 | &dev_attr_als_enable.attr, | 2123 | &dev_attr_als_enable.attr, |
| 2085 | &dev_attr_fan_boost_mode.attr, | 2124 | &dev_attr_fan_boost_mode.attr, |
| 2125 | &dev_attr_charge_threshold.attr, | ||
| 2086 | NULL | 2126 | NULL |
| 2087 | }; | 2127 | }; |
| 2088 | 2128 | ||
| @@ -2106,6 +2146,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, · 17 unmodified lines | |||
| 2106 | devid = ASUS_WMI_DEVID_ALS_ENABLE; | 2146 | devid = ASUS_WMI_DEVID_ALS_ENABLE; |
| 2107 | else if (attr == &dev_attr_fan_boost_mode.attr) | 2147 | else if (attr == &dev_attr_fan_boost_mode.attr) |
| 2108 | ok = asus->fan_boost_mode_available; | 2148 | ok = asus->fan_boost_mode_available; |
| 2149 | else if (attr == &dev_attr_charge_threshold.attr) | ||
| 2150 | devid = ASUS_WMI_CHARGE_THRESHOLD; | ||
| 2109 | 2151 | ||
| 2110 | if (devid != -1) | 2152 | if (devid != -1) |
| 2111 | ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); | 2153 | ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); |
| @@ -2434,6 +2476,12 @@ static int asus_wmi_add(struct platform_device *pdev) · 322 unmodified lines | |||
| 2434 | } | 2476 | } |
| 2435 | 2477 | ||
| 2436 | asus_wmi_debugfs_init(asus); | 2478 | asus_wmi_debugfs_init(asus); |
| 2479 | /* The charge threshold is only reset when the system is power cycled, | ||
| 2480 | * and we can't get the current threshold so let set it to 100% on | ||
| 2481 | * module load. | ||
| 2482 | */ | ||
| 2483 | asus_wmi_set_devstate(ASUS_WMI_CHARGE_THRESHOLD, 100, NULL); | ||
| 2484 | asus->charge_threshold = 100; | ||
| 2437 | 2485 | ||
| 2438 | return 0; | 2486 | return 0; |
| 2439 | 2487 | ||
| @@ -61,6 +61,7 @@ · 60 unmodified lines | |||
| 61 | 61 | ||
| 62 | /* Misc */ | 62 | /* Misc */ |
| 63 | #define ASUS_WMI_DEVID_CAMERA 0x00060013 | 63 | #define ASUS_WMI_DEVID_CAMERA 0x00060013 |
| 64 | #define ASUS_WMI_CHARGE_THRESHOLD 0x00120057 | ||
| 64 | 65 | ||
| 65 | /* Storage */ | 66 | /* Storage */ |
| 66 | #define ASUS_WMI_DEVID_CARDREADER 0x00080013 | 67 | #define ASUS_WMI_DEVID_CARDREADER 0x00080013 |