On Tue, Sep 10, 2019 at 12:15 PM Kristian Klausen <kristian@xxxxxxxxxx> wrote: > > On 09.09.2019 19.31, Kristian Klausen wrote: > > At the same time use the official naming for the knobs. > > > > Tested on a Zenbook UX430UNR. > > All three pushed to my review and testing queue, thanks! > > Signed-off-by: Kristian Klausen <kristian@xxxxxxxxxx> > > --- > > drivers/platform/x86/asus-wmi.c | 147 +++++++++++++++++++++----------- > > 1 file changed, 98 insertions(+), 49 deletions(-) > > > > diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c > > index 92c149dc2e6e..4dad22c0384b 100644 > > --- a/drivers/platform/x86/asus-wmi.c > > +++ b/drivers/platform/x86/asus-wmi.c > > @@ -26,6 +26,7 @@ > > #include <linux/rfkill.h> > > #include <linux/pci.h> > > #include <linux/pci_hotplug.h> > > +#include <linux/power_supply.h> > > #include <linux/hwmon.h> > > #include <linux/hwmon-sysfs.h> > > #include <linux/debugfs.h> > > @@ -36,6 +37,7 @@ > > #include <linux/acpi.h> > > #include <linux/dmi.h> > > #include <acpi/video.h> > > +#include <acpi/battery.h> > > > > #include "asus-wmi.h" > > > > @@ -195,7 +197,8 @@ struct asus_wmi { > > u8 fan_boost_mode_mask; > > u8 fan_boost_mode; > > > > - int charge_threshold; > > + // The RSOC controls the maximum charging percentage. > > + bool battery_rsoc_available; > > > > struct hotplug_slot hotplug_slot; > > struct mutex hotplug_lock; > > @@ -369,6 +372,97 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id) > > return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT); > > } > > > > +/* Battery ********************************************************************/ > > + > > +/* The battery maximum charging percentage */ > > +static int charge_end_threshold; > > + > > +static ssize_t charge_control_end_threshold_store(struct device *dev, > > + struct device_attribute *attr, > > + const char *buf, size_t count) > > +{ > > + int value, ret, rv; > > + > > + ret = kstrtouint(buf, 10, &value); > > + if (ret) > > + return ret; > > + > > + if (value < 0 || value > 100) > > + return -EINVAL; > > + > > + ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_RSOC, value, &rv); > > + if(ret) > A space is required here, I forgot to run ./scripts/checkpatch.pl before > submitting the patch series. > > + return ret; > > + > > + if (rv != 1) > > + return -EIO; > > + > > + /* There isn't any method in the DSDT to read the threshold, so we > > + * save the threshold. > > + */ > > + charge_end_threshold = value; > > + return count; > > +} > > + > > +static ssize_t charge_control_end_threshold_show(struct device *device, > > + struct device_attribute *attr, > > + char *buf) > > +{ > > + return sprintf(buf, "%d\n", charge_end_threshold); > > +} > > + > > +static DEVICE_ATTR_RW(charge_control_end_threshold); > > + > > +static int asus_wmi_battery_add(struct power_supply *battery) > > +{ > > + /* The WMI method does not provide a way to specific a battery, so we > > + * just assume it is the first battery. > > + */ > > + if (!strcmp(battery->desc->name, "BAT0") == 0) > > + return -ENODEV; > > + > > + if (device_create_file(&battery->dev, > > + &dev_attr_charge_control_end_threshold)) > > + return -ENODEV; > > + > > + /* 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% when > > + * a battery is added. > > + */ > > + asus_wmi_set_devstate(ASUS_WMI_DEVID_RSOC, 100, NULL); > > + charge_end_threshold = 100; > > + > > + return 0; > > +} > > + > > +static int asus_wmi_battery_remove(struct power_supply *battery) > > +{ > > + device_remove_file(&battery->dev, > > + &dev_attr_charge_control_end_threshold); > > + return 0; > > +} > > + > > +static struct acpi_battery_hook battery_hook = { > > + .add_battery = asus_wmi_battery_add, > > + .remove_battery = asus_wmi_battery_remove, > > + .name = "ASUS Battery Extension", > > +}; > > + > > +static void asus_wmi_battery_init(struct asus_wmi *asus) > > +{ > > + asus->battery_rsoc_available = false; > > + if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_RSOC)) { > > + asus->battery_rsoc_available = true; > > + battery_hook_register(&battery_hook); > > + } > > +} > > + > > +static void asus_wmi_battery_exit(struct asus_wmi *asus) > > +{ > > + if (asus->battery_rsoc_available) > > + battery_hook_unregister(&battery_hook); > > +} > > + > > /* LEDs ***********************************************************************/ > > > > /* > > @@ -2052,45 +2146,6 @@ 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 (ret) > > - return ret; > > - > > - if (value < 0 || value > 100) > > - return -EINVAL; > > - > > - ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_RSOC, value, &rv); > > - if (ret) > > - return ret; > > - > > - 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, > > @@ -2099,7 +2154,6 @@ 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 > > }; > > > > @@ -2123,8 +2177,6 @@ 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_DEVID_RSOC; > > > > if (devid != -1) > > ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); > > @@ -2450,13 +2502,9 @@ static int asus_wmi_add(struct platform_device *pdev) > > goto fail_wmi_handler; > > } > > > > + asus_wmi_battery_init(asus); > > + > > 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_DEVID_RSOC, 100, NULL); > > - asus->charge_threshold = 100; > > > > return 0; > > > > @@ -2491,6 +2539,7 @@ static int asus_wmi_remove(struct platform_device *device) > > asus_wmi_debugfs_exit(asus); > > asus_wmi_sysfs_exit(asus->platform_device); > > asus_fan_set_auto(asus); > > + asus_wmi_battery_exit(asus); > > > > kfree(asus); > > return 0; > -- With Best Regards, Andy Shevchenko