26
26
#include <linux/rfkill.h>
27
27
#include <linux/pci.h>
28
28
#include <linux/pci_hotplug.h>
29
+ #include <linux/power_supply.h>
29
30
#include <linux/hwmon.h>
30
31
#include <linux/hwmon-sysfs.h>
31
32
#include <linux/debugfs.h>
35
36
#include <linux/thermal.h>
36
37
#include <linux/acpi.h>
37
38
#include <linux/dmi.h>
39
+
40
+ #include <acpi/battery.h>
38
41
#include <acpi/video.h>
39
42
40
43
#include "asus-wmi.h"
@@ -195,7 +198,8 @@ struct asus_wmi {
195
198
u8 fan_boost_mode_mask ;
196
199
u8 fan_boost_mode ;
197
200
198
- int charge_threshold ;
201
+ // The RSOC controls the maximum charging percentage.
202
+ bool battery_rsoc_available ;
199
203
200
204
struct hotplug_slot hotplug_slot ;
201
205
struct mutex hotplug_lock ;
@@ -369,6 +373,97 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
369
373
return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT );
370
374
}
371
375
376
+ /* Battery ********************************************************************/
377
+
378
+ /* The battery maximum charging percentage */
379
+ static int charge_end_threshold ;
380
+
381
+ static ssize_t charge_control_end_threshold_store (struct device * dev ,
382
+ struct device_attribute * attr ,
383
+ const char * buf , size_t count )
384
+ {
385
+ int value , ret , rv ;
386
+
387
+ ret = kstrtouint (buf , 10 , & value );
388
+ if (ret )
389
+ return ret ;
390
+
391
+ if (value < 0 || value > 100 )
392
+ return - EINVAL ;
393
+
394
+ ret = asus_wmi_set_devstate (ASUS_WMI_DEVID_RSOC , value , & rv );
395
+ if (ret )
396
+ return ret ;
397
+
398
+ if (rv != 1 )
399
+ return - EIO ;
400
+
401
+ /* There isn't any method in the DSDT to read the threshold, so we
402
+ * save the threshold.
403
+ */
404
+ charge_end_threshold = value ;
405
+ return count ;
406
+ }
407
+
408
+ static ssize_t charge_control_end_threshold_show (struct device * device ,
409
+ struct device_attribute * attr ,
410
+ char * buf )
411
+ {
412
+ return sprintf (buf , "%d\n" , charge_end_threshold );
413
+ }
414
+
415
+ static DEVICE_ATTR_RW (charge_control_end_threshold );
416
+
417
+ static int asus_wmi_battery_add (struct power_supply * battery )
418
+ {
419
+ /* The WMI method does not provide a way to specific a battery, so we
420
+ * just assume it is the first battery.
421
+ */
422
+ if (strcmp (battery -> desc -> name , "BAT0" ) != 0 )
423
+ return - ENODEV ;
424
+
425
+ if (device_create_file (& battery -> dev ,
426
+ & dev_attr_charge_control_end_threshold ))
427
+ return - ENODEV ;
428
+
429
+ /* The charge threshold is only reset when the system is power cycled,
430
+ * and we can't get the current threshold so let set it to 100% when
431
+ * a battery is added.
432
+ */
433
+ asus_wmi_set_devstate (ASUS_WMI_DEVID_RSOC , 100 , NULL );
434
+ charge_end_threshold = 100 ;
435
+
436
+ return 0 ;
437
+ }
438
+
439
+ static int asus_wmi_battery_remove (struct power_supply * battery )
440
+ {
441
+ device_remove_file (& battery -> dev ,
442
+ & dev_attr_charge_control_end_threshold );
443
+ return 0 ;
444
+ }
445
+
446
+ static struct acpi_battery_hook battery_hook = {
447
+ .add_battery = asus_wmi_battery_add ,
448
+ .remove_battery = asus_wmi_battery_remove ,
449
+ .name = "ASUS Battery Extension" ,
450
+ };
451
+
452
+ static void asus_wmi_battery_init (struct asus_wmi * asus )
453
+ {
454
+ asus -> battery_rsoc_available = false;
455
+ if (asus_wmi_dev_is_present (asus , ASUS_WMI_DEVID_RSOC )) {
456
+ asus -> battery_rsoc_available = true;
457
+ battery_hook_register (& battery_hook );
458
+ }
459
+ }
460
+
461
+ static void asus_wmi_battery_exit (struct asus_wmi * asus )
462
+ {
463
+ if (asus -> battery_rsoc_available )
464
+ battery_hook_unregister (& battery_hook );
465
+ }
466
+
372
467
/* LEDs ***********************************************************************/
373
468
374
469
/*
@@ -2052,45 +2147,6 @@ static ssize_t cpufv_store(struct device *dev, struct device_attribute *attr,
2052
2147
2053
2148
static DEVICE_ATTR_WO (cpufv );
2054
2149
2055
-
2056
- static ssize_t charge_threshold_store (struct device * dev ,
2057
- struct device_attribute * attr ,
2058
- const char * buf , size_t count )
2059
- {
2060
- struct asus_wmi * asus = dev_get_drvdata (dev );
2061
- int value , ret , rv ;
2062
-
2063
- ret = kstrtouint (buf , 10 , & value );
2064
- if (ret )
2065
- return ret ;
2066
-
2067
- if (value < 0 || value > 100 )
2068
- return - EINVAL ;
2069
-
2070
- ret = asus_wmi_set_devstate (ASUS_WMI_DEVID_RSOC , value , & rv );
2071
- if (ret )
2072
- return ret ;
2073
-
2074
- if (rv != 1 )
2075
- return - EIO ;
2076
-
2077
- /* There isn't any method in the DSDT to read the threshold, so we
2078
- * save the threshold.
2079
- */
2080
- asus -> charge_threshold = value ;
2081
- return count ;
2082
- }
2083
-
2084
- static ssize_t charge_threshold_show (struct device * dev ,
2085
- struct device_attribute * attr , char * buf )
2086
- {
2087
- struct asus_wmi * asus = dev_get_drvdata (dev );
2088
-
2089
- return sprintf (buf , "%d\n" , asus -> charge_threshold );
2090
- }
2091
-
2092
- static DEVICE_ATTR_RW (charge_threshold );
2093
-
2094
2150
static struct attribute * platform_attributes [] = {
2095
2151
& dev_attr_cpufv .attr ,
2096
2152
& dev_attr_camera .attr ,
@@ -2099,7 +2155,6 @@ static struct attribute *platform_attributes[] = {
2099
2155
& dev_attr_lid_resume .attr ,
2100
2156
& dev_attr_als_enable .attr ,
2101
2157
& dev_attr_fan_boost_mode .attr ,
2102
- & dev_attr_charge_threshold .attr ,
2103
2158
NULL
2104
2159
};
2105
2160
@@ -2123,8 +2178,6 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
2123
2178
devid = ASUS_WMI_DEVID_ALS_ENABLE ;
2124
2179
else if (attr == & dev_attr_fan_boost_mode .attr )
2125
2180
ok = asus -> fan_boost_mode_available ;
2126
- else if (attr == & dev_attr_charge_threshold .attr )
2127
- devid = ASUS_WMI_DEVID_RSOC ;
2128
2181
2129
2182
if (devid != -1 )
2130
2183
ok = !(asus_wmi_get_devstate_simple (asus , devid ) < 0 );
@@ -2450,13 +2503,9 @@ static int asus_wmi_add(struct platform_device *pdev)
2450
2503
goto fail_wmi_handler ;
2451
2504
}
2452
2505
2506
+ asus_wmi_battery_init (asus );
2507
+
2453
2508
asus_wmi_debugfs_init (asus );
2454
- /* The charge threshold is only reset when the system is power cycled,
2455
- * and we can't get the current threshold so let set it to 100% on
2456
- * module load.
2457
- */
2458
- asus_wmi_set_devstate (ASUS_WMI_DEVID_RSOC , 100 , NULL );
2459
- asus -> charge_threshold = 100 ;
2460
2509
2461
2510
return 0 ;
2462
2511
@@ -2491,6 +2540,7 @@ static int asus_wmi_remove(struct platform_device *device)
2491
2540
asus_wmi_debugfs_exit (asus );
2492
2541
asus_wmi_sysfs_exit (asus -> platform_device );
2493
2542
asus_fan_set_auto (asus );
2543
+ asus_wmi_battery_exit (asus );
2494
2544
2495
2545
kfree (asus );
2496
2546
return 0 ;
0 commit comments