forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/platform/x86/asus-wmi.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Asus PC WMI hotkey driver
34 *
....@@ -8,20 +9,6 @@
89 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
910 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
1011 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
11
- *
12
- * This program is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License as published by
14
- * the Free Software Foundation; either version 2 of the License, or
15
- * (at your option) any later version.
16
- *
17
- * This program is distributed in the hope that it will be useful,
18
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- * GNU General Public License for more details.
21
- *
22
- * You should have received a copy of the GNU General Public License
23
- * along with this program; if not, write to the Free Software
24
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2512 */
2613
2714 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -39,14 +26,18 @@
3926 #include <linux/rfkill.h>
4027 #include <linux/pci.h>
4128 #include <linux/pci_hotplug.h>
29
+#include <linux/power_supply.h>
4230 #include <linux/hwmon.h>
4331 #include <linux/hwmon-sysfs.h>
4432 #include <linux/debugfs.h>
4533 #include <linux/seq_file.h>
34
+#include <linux/platform_data/x86/asus-wmi.h>
4635 #include <linux/platform_device.h>
47
-#include <linux/thermal.h>
4836 #include <linux/acpi.h>
4937 #include <linux/dmi.h>
38
+#include <linux/units.h>
39
+
40
+#include <acpi/battery.h>
5041 #include <acpi/video.h>
5142
5243 #include "asus-wmi.h"
....@@ -65,102 +56,50 @@
6556 #define NOTIFY_BRNUP_MAX 0x1f
6657 #define NOTIFY_BRNDOWN_MIN 0x20
6758 #define NOTIFY_BRNDOWN_MAX 0x2e
59
+#define NOTIFY_FNLOCK_TOGGLE 0x4e
60
+#define NOTIFY_KBD_DOCK_CHANGE 0x75
6861 #define NOTIFY_KBD_BRTUP 0xc4
6962 #define NOTIFY_KBD_BRTDWN 0xc5
7063 #define NOTIFY_KBD_BRTTOGGLE 0xc7
64
+#define NOTIFY_KBD_FBM 0x99
65
+#define NOTIFY_KBD_TTP 0xae
7166
72
-/* WMI Methods */
73
-#define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */
74
-#define ASUS_WMI_METHODID_SFBD 0x44424653 /* Set First Boot Device */
75
-#define ASUS_WMI_METHODID_GLCD 0x44434C47 /* Get LCD status */
76
-#define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */
77
-#define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */
78
-#define ASUS_WMI_METHODID_SPLV 0x4C425053 /* Set Panel Light Value */
79
-#define ASUS_WMI_METHODID_AGFN 0x4E464741 /* FaN? */
80
-#define ASUS_WMI_METHODID_SFUN 0x4E554653 /* FUNCtionalities */
81
-#define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */
82
-#define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */
83
-#define ASUS_WMI_METHODID_DEVP 0x50564544 /* DEVice Policy */
84
-#define ASUS_WMI_METHODID_OSVR 0x5256534F /* OS VeRsion */
85
-#define ASUS_WMI_METHODID_DSTS 0x53544344 /* Device STatuS */
86
-#define ASUS_WMI_METHODID_DSTS2 0x53545344 /* Device STatuS #2*/
87
-#define ASUS_WMI_METHODID_BSTS 0x53545342 /* Bios STatuS ? */
88
-#define ASUS_WMI_METHODID_DEVS 0x53564544 /* DEVice Set */
89
-#define ASUS_WMI_METHODID_CFVS 0x53564643 /* CPU Frequency Volt Set */
90
-#define ASUS_WMI_METHODID_KBFT 0x5446424B /* KeyBoard FilTer */
91
-#define ASUS_WMI_METHODID_INIT 0x54494E49 /* INITialize */
92
-#define ASUS_WMI_METHODID_HKEY 0x59454B48 /* Hot KEY ?? */
93
-
94
-#define ASUS_WMI_UNSUPPORTED_METHOD 0xFFFFFFFE
95
-
96
-/* Wireless */
97
-#define ASUS_WMI_DEVID_HW_SWITCH 0x00010001
98
-#define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002
99
-#define ASUS_WMI_DEVID_CWAP 0x00010003
100
-#define ASUS_WMI_DEVID_WLAN 0x00010011
101
-#define ASUS_WMI_DEVID_WLAN_LED 0x00010012
102
-#define ASUS_WMI_DEVID_BLUETOOTH 0x00010013
103
-#define ASUS_WMI_DEVID_GPS 0x00010015
104
-#define ASUS_WMI_DEVID_WIMAX 0x00010017
105
-#define ASUS_WMI_DEVID_WWAN3G 0x00010019
106
-#define ASUS_WMI_DEVID_UWB 0x00010021
107
-
108
-/* Leds */
109
-/* 0x000200XX and 0x000400XX */
110
-#define ASUS_WMI_DEVID_LED1 0x00020011
111
-#define ASUS_WMI_DEVID_LED2 0x00020012
112
-#define ASUS_WMI_DEVID_LED3 0x00020013
113
-#define ASUS_WMI_DEVID_LED4 0x00020014
114
-#define ASUS_WMI_DEVID_LED5 0x00020015
115
-#define ASUS_WMI_DEVID_LED6 0x00020016
116
-
117
-/* Backlight and Brightness */
118
-#define ASUS_WMI_DEVID_ALS_ENABLE 0x00050001 /* Ambient Light Sensor */
119
-#define ASUS_WMI_DEVID_BACKLIGHT 0x00050011
120
-#define ASUS_WMI_DEVID_BRIGHTNESS 0x00050012
121
-#define ASUS_WMI_DEVID_KBD_BACKLIGHT 0x00050021
122
-#define ASUS_WMI_DEVID_LIGHT_SENSOR 0x00050022 /* ?? */
123
-#define ASUS_WMI_DEVID_LIGHTBAR 0x00050025
124
-
125
-/* Misc */
126
-#define ASUS_WMI_DEVID_CAMERA 0x00060013
127
-
128
-/* Storage */
129
-#define ASUS_WMI_DEVID_CARDREADER 0x00080013
130
-
131
-/* Input */
132
-#define ASUS_WMI_DEVID_TOUCHPAD 0x00100011
133
-#define ASUS_WMI_DEVID_TOUCHPAD_LED 0x00100012
134
-
135
-/* Fan, Thermal */
136
-#define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011
137
-#define ASUS_WMI_DEVID_FAN_CTRL 0x00110012
138
-
139
-/* Power */
140
-#define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012
141
-
142
-/* Deep S3 / Resume on LID open */
143
-#define ASUS_WMI_DEVID_LID_RESUME 0x00120031
144
-
145
-/* DSTS masks */
146
-#define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
147
-#define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
148
-#define ASUS_WMI_DSTS_PRESENCE_BIT 0x00010000
149
-#define ASUS_WMI_DSTS_USER_BIT 0x00020000
150
-#define ASUS_WMI_DSTS_BIOS_BIT 0x00040000
151
-#define ASUS_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF
152
-#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00
153
-#define ASUS_WMI_DSTS_LIGHTBAR_MASK 0x0000000F
67
+#define ASUS_WMI_FNLOCK_BIOS_DISABLED BIT(0)
15468
15569 #define ASUS_FAN_DESC "cpu_fan"
15670 #define ASUS_FAN_MFUN 0x13
15771 #define ASUS_FAN_SFUN_READ 0x06
15872 #define ASUS_FAN_SFUN_WRITE 0x07
73
+
74
+/* Based on standard hwmon pwmX_enable values */
75
+#define ASUS_FAN_CTRL_FULLSPEED 0
15976 #define ASUS_FAN_CTRL_MANUAL 1
16077 #define ASUS_FAN_CTRL_AUTO 2
16178
79
+#define ASUS_FAN_BOOST_MODE_NORMAL 0
80
+#define ASUS_FAN_BOOST_MODE_OVERBOOST 1
81
+#define ASUS_FAN_BOOST_MODE_OVERBOOST_MASK 0x01
82
+#define ASUS_FAN_BOOST_MODE_SILENT 2
83
+#define ASUS_FAN_BOOST_MODE_SILENT_MASK 0x02
84
+#define ASUS_FAN_BOOST_MODES_MASK 0x03
85
+
86
+#define ASUS_THROTTLE_THERMAL_POLICY_DEFAULT 0
87
+#define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST 1
88
+#define ASUS_THROTTLE_THERMAL_POLICY_SILENT 2
89
+
16290 #define USB_INTEL_XUSB2PR 0xD0
16391 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
92
+
93
+#define ASUS_ACPI_UID_ASUSWMI "ASUSWMI"
94
+#define ASUS_ACPI_UID_ATK "ATK"
95
+
96
+#define WMI_EVENT_QUEUE_SIZE 0x10
97
+#define WMI_EVENT_QUEUE_END 0x1
98
+#define WMI_EVENT_MASK 0xFFFF
99
+/* The WMI hotkey event value is always the same. */
100
+#define WMI_EVENT_VALUE_ATK 0xFF
101
+
102
+#define WMI_EVENT_MASK 0xFFFF
164103
165104 static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
166105
....@@ -177,6 +116,9 @@
177116 struct bios_args {
178117 u32 arg0;
179118 u32 arg1;
119
+ u32 arg2; /* At least TUF Gaming series uses 3 dword input buffer. */
120
+ u32 arg4;
121
+ u32 arg5;
180122 } __packed;
181123
182124 /*
....@@ -192,7 +134,7 @@
192134 } __packed;
193135
194136 /* struct used for calling fan read and write methods */
195
-struct fan_args {
137
+struct agfn_fan_args {
196138 struct agfn_args agfn; /* common fields */
197139 u8 fan; /* fan number: 0: set auto mode 1: 1st fan */
198140 u32 speed; /* read: RPM/100 - write: 0-255 */
....@@ -220,10 +162,17 @@
220162 u32 dev_id;
221163 };
222164
165
+enum fan_type {
166
+ FAN_TYPE_NONE = 0,
167
+ FAN_TYPE_AGFN, /* deprecated on newer platforms */
168
+ FAN_TYPE_SPEC83, /* starting in Spec 8.3, use CPU_FAN_CTRL */
169
+};
170
+
223171 struct asus_wmi {
224172 int dsts_id;
225173 int spec;
226174 int sfun;
175
+ bool wmi_event_queue;
227176
228177 struct input_dev *inputdev;
229178 struct backlight_device *backlight_device;
....@@ -239,7 +188,6 @@
239188 int lightbar_led_wk;
240189 struct workqueue_struct *led_workqueue;
241190 struct work_struct tpd_led_work;
242
- struct work_struct kbd_led_work;
243191 struct work_struct wlan_led_work;
244192 struct work_struct lightbar_led_work;
245193
....@@ -250,64 +198,42 @@
250198 struct asus_rfkill gps;
251199 struct asus_rfkill uwb;
252200
253
- bool asus_hwmon_fan_manual_mode;
254
- int asus_hwmon_num_fans;
255
- int asus_hwmon_pwm;
201
+ enum fan_type fan_type;
202
+ int fan_pwm_mode;
203
+ int agfn_pwm;
256204
257
- struct hotplug_slot *hotplug_slot;
205
+ bool fan_boost_mode_available;
206
+ u8 fan_boost_mode_mask;
207
+ u8 fan_boost_mode;
208
+
209
+ bool throttle_thermal_policy_available;
210
+ u8 throttle_thermal_policy_mode;
211
+
212
+ // The RSOC controls the maximum charging percentage.
213
+ bool battery_rsoc_available;
214
+
215
+ struct hotplug_slot hotplug_slot;
258216 struct mutex hotplug_lock;
259217 struct mutex wmi_lock;
260218 struct workqueue_struct *hotplug_workqueue;
261219 struct work_struct hotplug_work;
220
+
221
+ bool fnlock_locked;
262222
263223 struct asus_wmi_debug debug;
264224
265225 struct asus_wmi_driver *driver;
266226 };
267227
268
-static int asus_wmi_input_init(struct asus_wmi *asus)
269
-{
270
- int err;
228
+/* WMI ************************************************************************/
271229
272
- asus->inputdev = input_allocate_device();
273
- if (!asus->inputdev)
274
- return -ENOMEM;
275
-
276
- asus->inputdev->name = asus->driver->input_name;
277
- asus->inputdev->phys = asus->driver->input_phys;
278
- asus->inputdev->id.bustype = BUS_HOST;
279
- asus->inputdev->dev.parent = &asus->platform_device->dev;
280
- set_bit(EV_REP, asus->inputdev->evbit);
281
-
282
- err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
283
- if (err)
284
- goto err_free_dev;
285
-
286
- err = input_register_device(asus->inputdev);
287
- if (err)
288
- goto err_free_dev;
289
-
290
- return 0;
291
-
292
-err_free_dev:
293
- input_free_device(asus->inputdev);
294
- return err;
295
-}
296
-
297
-static void asus_wmi_input_exit(struct asus_wmi *asus)
298
-{
299
- if (asus->inputdev)
300
- input_unregister_device(asus->inputdev);
301
-
302
- asus->inputdev = NULL;
303
-}
304
-
305
-static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
306
- u32 *retval)
230
+static int asus_wmi_evaluate_method3(u32 method_id,
231
+ u32 arg0, u32 arg1, u32 arg2, u32 *retval)
307232 {
308233 struct bios_args args = {
309234 .arg0 = arg0,
310235 .arg1 = arg1,
236
+ .arg2 = arg2,
311237 };
312238 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
313239 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
....@@ -319,7 +245,7 @@
319245 &input, &output);
320246
321247 if (ACPI_FAILURE(status))
322
- goto exit;
248
+ return -EIO;
323249
324250 obj = (union acpi_object *)output.pointer;
325251 if (obj && obj->type == ACPI_TYPE_INTEGER)
....@@ -330,33 +256,34 @@
330256
331257 kfree(obj);
332258
333
-exit:
334
- if (ACPI_FAILURE(status))
335
- return -EIO;
336
-
337259 if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
338260 return -ENODEV;
339261
340262 return 0;
341263 }
342264
265
+int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval)
266
+{
267
+ return asus_wmi_evaluate_method3(method_id, arg0, arg1, 0, retval);
268
+}
269
+EXPORT_SYMBOL_GPL(asus_wmi_evaluate_method);
270
+
343271 static int asus_wmi_evaluate_method_agfn(const struct acpi_buffer args)
344272 {
345273 struct acpi_buffer input;
346274 u64 phys_addr;
347275 u32 retval;
348
- u32 status = -1;
276
+ u32 status;
349277
350278 /*
351279 * Copy to dma capable address otherwise memory corruption occurs as
352280 * bios has to be able to access it.
353281 */
354
- input.pointer = kzalloc(args.length, GFP_DMA | GFP_KERNEL);
282
+ input.pointer = kmemdup(args.pointer, args.length, GFP_DMA | GFP_KERNEL);
355283 input.length = args.length;
356284 if (!input.pointer)
357285 return -ENOMEM;
358286 phys_addr = virt_to_phys(input.pointer);
359
- memcpy(input.pointer, args.pointer, args.length);
360287
361288 status = asus_wmi_evaluate_method(ASUS_WMI_METHODID_AGFN,
362289 phys_addr, 0, &retval);
....@@ -390,7 +317,6 @@
390317 int err;
391318
392319 err = asus_wmi_get_devstate(asus, dev_id, &retval);
393
-
394320 if (err < 0)
395321 return err;
396322
....@@ -411,9 +337,161 @@
411337 ASUS_WMI_DSTS_STATUS_BIT);
412338 }
413339
414
-/*
415
- * LEDs
416
- */
340
+static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
341
+{
342
+ u32 retval;
343
+ int status = asus_wmi_get_devstate(asus, dev_id, &retval);
344
+
345
+ return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT);
346
+}
347
+
348
+/* Input **********************************************************************/
349
+
350
+static int asus_wmi_input_init(struct asus_wmi *asus)
351
+{
352
+ int err, result;
353
+
354
+ asus->inputdev = input_allocate_device();
355
+ if (!asus->inputdev)
356
+ return -ENOMEM;
357
+
358
+ asus->inputdev->name = asus->driver->input_name;
359
+ asus->inputdev->phys = asus->driver->input_phys;
360
+ asus->inputdev->id.bustype = BUS_HOST;
361
+ asus->inputdev->dev.parent = &asus->platform_device->dev;
362
+ set_bit(EV_REP, asus->inputdev->evbit);
363
+
364
+ err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
365
+ if (err)
366
+ goto err_free_dev;
367
+
368
+ if (asus->driver->quirks->use_kbd_dock_devid) {
369
+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_KBD_DOCK);
370
+ if (result >= 0) {
371
+ input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
372
+ input_report_switch(asus->inputdev, SW_TABLET_MODE, !result);
373
+ } else if (result != -ENODEV) {
374
+ pr_err("Error checking for keyboard-dock: %d\n", result);
375
+ }
376
+ }
377
+
378
+ err = input_register_device(asus->inputdev);
379
+ if (err)
380
+ goto err_free_dev;
381
+
382
+ return 0;
383
+
384
+err_free_dev:
385
+ input_free_device(asus->inputdev);
386
+ return err;
387
+}
388
+
389
+static void asus_wmi_input_exit(struct asus_wmi *asus)
390
+{
391
+ if (asus->inputdev)
392
+ input_unregister_device(asus->inputdev);
393
+
394
+ asus->inputdev = NULL;
395
+}
396
+
397
+/* Battery ********************************************************************/
398
+
399
+/* The battery maximum charging percentage */
400
+static int charge_end_threshold;
401
+
402
+static ssize_t charge_control_end_threshold_store(struct device *dev,
403
+ struct device_attribute *attr,
404
+ const char *buf, size_t count)
405
+{
406
+ int value, ret, rv;
407
+
408
+ ret = kstrtouint(buf, 10, &value);
409
+ if (ret)
410
+ return ret;
411
+
412
+ if (value < 0 || value > 100)
413
+ return -EINVAL;
414
+
415
+ ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_RSOC, value, &rv);
416
+ if (ret)
417
+ return ret;
418
+
419
+ if (rv != 1)
420
+ return -EIO;
421
+
422
+ /* There isn't any method in the DSDT to read the threshold, so we
423
+ * save the threshold.
424
+ */
425
+ charge_end_threshold = value;
426
+ return count;
427
+}
428
+
429
+static ssize_t charge_control_end_threshold_show(struct device *device,
430
+ struct device_attribute *attr,
431
+ char *buf)
432
+{
433
+ return sprintf(buf, "%d\n", charge_end_threshold);
434
+}
435
+
436
+static DEVICE_ATTR_RW(charge_control_end_threshold);
437
+
438
+static int asus_wmi_battery_add(struct power_supply *battery)
439
+{
440
+ /* The WMI method does not provide a way to specific a battery, so we
441
+ * just assume it is the first battery.
442
+ * Note: On some newer ASUS laptops (Zenbook UM431DA), the primary/first
443
+ * battery is named BATT.
444
+ */
445
+ if (strcmp(battery->desc->name, "BAT0") != 0 &&
446
+ strcmp(battery->desc->name, "BAT1") != 0 &&
447
+ strcmp(battery->desc->name, "BATC") != 0 &&
448
+ strcmp(battery->desc->name, "BATT") != 0)
449
+ return -ENODEV;
450
+
451
+ if (device_create_file(&battery->dev,
452
+ &dev_attr_charge_control_end_threshold))
453
+ return -ENODEV;
454
+
455
+ /* The charge threshold is only reset when the system is power cycled,
456
+ * and we can't get the current threshold so let set it to 100% when
457
+ * a battery is added.
458
+ */
459
+ asus_wmi_set_devstate(ASUS_WMI_DEVID_RSOC, 100, NULL);
460
+ charge_end_threshold = 100;
461
+
462
+ return 0;
463
+}
464
+
465
+static int asus_wmi_battery_remove(struct power_supply *battery)
466
+{
467
+ device_remove_file(&battery->dev,
468
+ &dev_attr_charge_control_end_threshold);
469
+ return 0;
470
+}
471
+
472
+static struct acpi_battery_hook battery_hook = {
473
+ .add_battery = asus_wmi_battery_add,
474
+ .remove_battery = asus_wmi_battery_remove,
475
+ .name = "ASUS Battery Extension",
476
+};
477
+
478
+static void asus_wmi_battery_init(struct asus_wmi *asus)
479
+{
480
+ asus->battery_rsoc_available = false;
481
+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_RSOC)) {
482
+ asus->battery_rsoc_available = true;
483
+ battery_hook_register(&battery_hook);
484
+ }
485
+}
486
+
487
+static void asus_wmi_battery_exit(struct asus_wmi *asus)
488
+{
489
+ if (asus->battery_rsoc_available)
490
+ battery_hook_unregister(&battery_hook);
491
+}
492
+
493
+/* LEDs ***********************************************************************/
494
+
417495 /*
418496 * These functions actually update the LED's, and are called from a
419497 * workqueue. By doing this as separate work rather than when the LED
....@@ -456,16 +534,12 @@
456534 return read_tpd_led_state(asus);
457535 }
458536
459
-static void kbd_led_update(struct work_struct *work)
537
+static void kbd_led_update(struct asus_wmi *asus)
460538 {
461539 int ctrl_param = 0;
462
- struct asus_wmi *asus;
463
-
464
- asus = container_of(work, struct asus_wmi, kbd_led_work);
465540
466541 ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
467542 asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
468
- led_classdev_notify_brightness_hw_changed(&asus->kbd_led, asus->kbd_led_wk);
469543 }
470544
471545 static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
....@@ -485,15 +559,14 @@
485559 if (retval == 0x8000)
486560 retval = 0;
487561
488
- if (retval >= 0) {
489
- if (level)
490
- *level = retval & 0x7F;
491
- if (env)
492
- *env = (retval >> 8) & 0x7F;
493
- retval = 0;
494
- }
562
+ if (retval < 0)
563
+ return retval;
495564
496
- return retval;
565
+ if (level)
566
+ *level = retval & 0x7F;
567
+ if (env)
568
+ *env = (retval >> 8) & 0x7F;
569
+ return 0;
497570 }
498571
499572 static void do_kbd_led_set(struct led_classdev *led_cdev, int value)
....@@ -504,19 +577,26 @@
504577 asus = container_of(led_cdev, struct asus_wmi, kbd_led);
505578 max_level = asus->kbd_led.max_brightness;
506579
507
- if (value > max_level)
508
- value = max_level;
509
- else if (value < 0)
510
- value = 0;
511
-
512
- asus->kbd_led_wk = value;
513
- queue_work(asus->led_workqueue, &asus->kbd_led_work);
580
+ asus->kbd_led_wk = clamp_val(value, 0, max_level);
581
+ kbd_led_update(asus);
514582 }
515583
516584 static void kbd_led_set(struct led_classdev *led_cdev,
517585 enum led_brightness value)
518586 {
587
+ /* Prevent disabling keyboard backlight on module unregister */
588
+ if (led_cdev->flags & LED_UNREGISTERING)
589
+ return;
590
+
519591 do_kbd_led_set(led_cdev, value);
592
+}
593
+
594
+static void kbd_led_set_by_kbd(struct asus_wmi *asus, enum led_brightness value)
595
+{
596
+ struct led_classdev *led_cdev = &asus->kbd_led;
597
+
598
+ do_kbd_led_set(led_cdev, value);
599
+ led_classdev_notify_brightness_hw_changed(led_cdev, asus->kbd_led_wk);
520600 }
521601
522602 static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
....@@ -527,7 +607,6 @@
527607 asus = container_of(led_cdev, struct asus_wmi, kbd_led);
528608
529609 retval = kbd_led_read(asus, &value, NULL);
530
-
531610 if (retval < 0)
532611 return retval;
533612
....@@ -541,15 +620,6 @@
541620 asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, &result);
542621
543622 return result & ASUS_WMI_DSTS_UNKNOWN_BIT;
544
-}
545
-
546
-static int wlan_led_presence(struct asus_wmi *asus)
547
-{
548
- u32 result;
549
-
550
- asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, &result);
551
-
552
- return result & ASUS_WMI_DSTS_PRESENCE_BIT;
553623 }
554624
555625 static void wlan_led_update(struct work_struct *work)
....@@ -618,25 +688,13 @@
618688 return result & ASUS_WMI_DSTS_LIGHTBAR_MASK;
619689 }
620690
621
-static int lightbar_led_presence(struct asus_wmi *asus)
622
-{
623
- u32 result;
624
-
625
- asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_LIGHTBAR, &result);
626
-
627
- return result & ASUS_WMI_DSTS_PRESENCE_BIT;
628
-}
629
-
630691 static void asus_wmi_led_exit(struct asus_wmi *asus)
631692 {
632
- if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
633
- led_classdev_unregister(&asus->kbd_led);
634
- if (!IS_ERR_OR_NULL(asus->tpd_led.dev))
635
- led_classdev_unregister(&asus->tpd_led);
636
- if (!IS_ERR_OR_NULL(asus->wlan_led.dev))
637
- led_classdev_unregister(&asus->wlan_led);
638
- if (!IS_ERR_OR_NULL(asus->lightbar_led.dev))
639
- led_classdev_unregister(&asus->lightbar_led);
693
+ led_classdev_unregister(&asus->kbd_led);
694
+ led_classdev_unregister(&asus->tpd_led);
695
+ led_classdev_unregister(&asus->wlan_led);
696
+ led_classdev_unregister(&asus->lightbar_led);
697
+
640698 if (asus->led_workqueue)
641699 destroy_workqueue(asus->led_workqueue);
642700 }
....@@ -663,10 +721,7 @@
663721 goto error;
664722 }
665723
666
- led_val = kbd_led_read(asus, NULL, NULL);
667
- if (led_val >= 0) {
668
- INIT_WORK(&asus->kbd_led_work, kbd_led_update);
669
-
724
+ if (!kbd_led_read(asus, &led_val, NULL)) {
670725 asus->kbd_led_wk = led_val;
671726 asus->kbd_led.name = "asus::kbd_backlight";
672727 asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
....@@ -680,7 +735,8 @@
680735 goto error;
681736 }
682737
683
- if (wlan_led_presence(asus) && (asus->driver->quirks->wapf > 0)) {
738
+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_WIRELESS_LED)
739
+ && (asus->driver->quirks->wapf > 0)) {
684740 INIT_WORK(&asus->wlan_led_work, wlan_led_update);
685741
686742 asus->wlan_led.name = "asus::wlan";
....@@ -697,7 +753,7 @@
697753 goto error;
698754 }
699755
700
- if (lightbar_led_presence(asus)) {
756
+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_LIGHTBAR)) {
701757 INIT_WORK(&asus->lightbar_led_work, lightbar_led_update);
702758
703759 asus->lightbar_led.name = "asus::lightbar";
....@@ -716,6 +772,7 @@
716772 return rv;
717773 }
718774
775
+/* RF *************************************************************************/
719776
720777 /*
721778 * PCI hotplug (for wlan rfkill)
....@@ -747,7 +804,7 @@
747804 if (asus->wlan.rfkill)
748805 rfkill_set_sw_state(asus->wlan.rfkill, blocked);
749806
750
- if (asus->hotplug_slot) {
807
+ if (asus->hotplug_slot.ops) {
751808 bus = pci_find_bus(0, 1);
752809 if (!bus) {
753810 pr_warn("Unable to find PCI bus 1?\n");
....@@ -819,15 +876,13 @@
819876 acpi_handle handle;
820877
821878 status = acpi_get_handle(NULL, node, &handle);
822
-
823
- if (ACPI_SUCCESS(status)) {
824
- status = acpi_install_notify_handler(handle,
825
- ACPI_SYSTEM_NOTIFY,
826
- asus_rfkill_notify, asus);
827
- if (ACPI_FAILURE(status))
828
- pr_warn("Failed to register notify on %s\n", node);
829
- } else
879
+ if (ACPI_FAILURE(status))
830880 return -ENODEV;
881
+
882
+ status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
883
+ asus_rfkill_notify, asus);
884
+ if (ACPI_FAILURE(status))
885
+ pr_warn("Failed to register notify on %s\n", node);
831886
832887 return 0;
833888 }
....@@ -838,21 +893,20 @@
838893 acpi_handle handle;
839894
840895 status = acpi_get_handle(NULL, node, &handle);
896
+ if (ACPI_FAILURE(status))
897
+ return;
841898
842
- if (ACPI_SUCCESS(status)) {
843
- status = acpi_remove_notify_handler(handle,
844
- ACPI_SYSTEM_NOTIFY,
845
- asus_rfkill_notify);
846
- if (ACPI_FAILURE(status))
847
- pr_err("Error removing rfkill notify handler %s\n",
848
- node);
849
- }
899
+ status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
900
+ asus_rfkill_notify);
901
+ if (ACPI_FAILURE(status))
902
+ pr_err("Error removing rfkill notify handler %s\n", node);
850903 }
851904
852905 static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
853906 u8 *value)
854907 {
855
- struct asus_wmi *asus = hotplug_slot->private;
908
+ struct asus_wmi *asus = container_of(hotplug_slot,
909
+ struct asus_wmi, hotplug_slot);
856910 int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
857911
858912 if (result < 0)
....@@ -862,8 +916,7 @@
862916 return 0;
863917 }
864918
865
-static struct hotplug_slot_ops asus_hotplug_slot_ops = {
866
- .owner = THIS_MODULE,
919
+static const struct hotplug_slot_ops asus_hotplug_slot_ops = {
867920 .get_adapter_status = asus_get_adapter_status,
868921 .get_power_status = asus_get_adapter_status,
869922 };
....@@ -893,21 +946,9 @@
893946
894947 INIT_WORK(&asus->hotplug_work, asus_hotplug_work);
895948
896
- asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
897
- if (!asus->hotplug_slot)
898
- goto error_slot;
949
+ asus->hotplug_slot.ops = &asus_hotplug_slot_ops;
899950
900
- asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
901
- GFP_KERNEL);
902
- if (!asus->hotplug_slot->info)
903
- goto error_info;
904
-
905
- asus->hotplug_slot->private = asus;
906
- asus->hotplug_slot->ops = &asus_hotplug_slot_ops;
907
- asus_get_adapter_status(asus->hotplug_slot,
908
- &asus->hotplug_slot->info->adapter_status);
909
-
910
- ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi");
951
+ ret = pci_hp_register(&asus->hotplug_slot, bus, 0, "asus-wifi");
911952 if (ret) {
912953 pr_err("Unable to register hotplug slot - %d\n", ret);
913954 goto error_register;
....@@ -916,11 +957,7 @@
916957 return 0;
917958
918959 error_register:
919
- kfree(asus->hotplug_slot->info);
920
-error_info:
921
- kfree(asus->hotplug_slot);
922
- asus->hotplug_slot = NULL;
923
-error_slot:
960
+ asus->hotplug_slot.ops = NULL;
924961 destroy_workqueue(asus->hotplug_workqueue);
925962 error_workqueue:
926963 return ret;
....@@ -1048,11 +1085,8 @@
10481085 * asus_unregister_rfkill_notifier()
10491086 */
10501087 asus_rfkill_hotplug(asus);
1051
- if (asus->hotplug_slot) {
1052
- pci_hp_deregister(asus->hotplug_slot);
1053
- kfree(asus->hotplug_slot->info);
1054
- kfree(asus->hotplug_slot);
1055
- }
1088
+ if (asus->hotplug_slot.ops)
1089
+ pci_hp_deregister(&asus->hotplug_slot);
10561090 if (asus->hotplug_workqueue)
10571091 destroy_workqueue(asus->hotplug_workqueue);
10581092
....@@ -1157,6 +1191,8 @@
11571191 return result;
11581192 }
11591193
1194
+/* Quirks *********************************************************************/
1195
+
11601196 static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
11611197 {
11621198 struct pci_dev *xhci_pdev;
....@@ -1176,6 +1212,8 @@
11761212 pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
11771213 cpu_to_le32(ports_available));
11781214
1215
+ pci_dev_put(xhci_pdev);
1216
+
11791217 pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n",
11801218 orig_ports_available, ports_available);
11811219 }
....@@ -1189,13 +1227,12 @@
11891227 asus_wmi_set_devstate(ASUS_WMI_DEVID_ALS_ENABLE, 1, NULL);
11901228 }
11911229
1192
-/*
1193
- * Hwmon device
1194
- */
1195
-static int asus_hwmon_agfn_fan_speed_read(struct asus_wmi *asus, int fan,
1230
+/* Hwmon device ***************************************************************/
1231
+
1232
+static int asus_agfn_fan_speed_read(struct asus_wmi *asus, int fan,
11961233 int *speed)
11971234 {
1198
- struct fan_args args = {
1235
+ struct agfn_fan_args args = {
11991236 .agfn.len = sizeof(args),
12001237 .agfn.mfun = ASUS_FAN_MFUN,
12011238 .agfn.sfun = ASUS_FAN_SFUN_READ,
....@@ -1219,10 +1256,10 @@
12191256 return 0;
12201257 }
12211258
1222
-static int asus_hwmon_agfn_fan_speed_write(struct asus_wmi *asus, int fan,
1259
+static int asus_agfn_fan_speed_write(struct asus_wmi *asus, int fan,
12231260 int *speed)
12241261 {
1225
- struct fan_args args = {
1262
+ struct agfn_fan_args args = {
12261263 .agfn.len = sizeof(args),
12271264 .agfn.mfun = ASUS_FAN_MFUN,
12281265 .agfn.sfun = ASUS_FAN_SFUN_WRITE,
....@@ -1242,7 +1279,7 @@
12421279 return -ENXIO;
12431280
12441281 if (speed && fan == 1)
1245
- asus->asus_hwmon_pwm = *speed;
1282
+ asus->agfn_pwm = *speed;
12461283
12471284 return 0;
12481285 }
....@@ -1251,77 +1288,60 @@
12511288 * Check if we can read the speed of one fan. If true we assume we can also
12521289 * control it.
12531290 */
1254
-static int asus_hwmon_get_fan_number(struct asus_wmi *asus, int *num_fans)
1291
+static bool asus_wmi_has_agfn_fan(struct asus_wmi *asus)
12551292 {
12561293 int status;
1257
- int speed = 0;
1294
+ int speed;
1295
+ u32 value;
12581296
1259
- *num_fans = 0;
1297
+ status = asus_agfn_fan_speed_read(asus, 1, &speed);
1298
+ if (status != 0)
1299
+ return false;
12601300
1261
- status = asus_hwmon_agfn_fan_speed_read(asus, 1, &speed);
1262
- if (!status)
1263
- *num_fans = 1;
1301
+ status = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value);
1302
+ if (status != 0)
1303
+ return false;
12641304
1265
- return 0;
1305
+ /*
1306
+ * We need to find a better way, probably using sfun,
1307
+ * bits or spec ...
1308
+ * Currently we disable it if:
1309
+ * - ASUS_WMI_UNSUPPORTED_METHOD is returned
1310
+ * - reverved bits are non-zero
1311
+ * - sfun and presence bit are not set
1312
+ */
1313
+ return !(value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
1314
+ || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)));
12661315 }
12671316
1268
-static int asus_hwmon_fan_set_auto(struct asus_wmi *asus)
1317
+static int asus_fan_set_auto(struct asus_wmi *asus)
12691318 {
12701319 int status;
1320
+ u32 retval;
12711321
1272
- status = asus_hwmon_agfn_fan_speed_write(asus, 0, NULL);
1273
- if (status)
1322
+ switch (asus->fan_type) {
1323
+ case FAN_TYPE_SPEC83:
1324
+ status = asus_wmi_set_devstate(ASUS_WMI_DEVID_CPU_FAN_CTRL,
1325
+ 0, &retval);
1326
+ if (status)
1327
+ return status;
1328
+
1329
+ if (retval != 1)
1330
+ return -EIO;
1331
+ break;
1332
+
1333
+ case FAN_TYPE_AGFN:
1334
+ status = asus_agfn_fan_speed_write(asus, 0, NULL);
1335
+ if (status)
1336
+ return -ENXIO;
1337
+ break;
1338
+
1339
+ default:
12741340 return -ENXIO;
1341
+ }
12751342
1276
- asus->asus_hwmon_fan_manual_mode = false;
12771343
12781344 return 0;
1279
-}
1280
-
1281
-static int asus_hwmon_fan_rpm_show(struct device *dev, int fan)
1282
-{
1283
- struct asus_wmi *asus = dev_get_drvdata(dev);
1284
- int value;
1285
- int ret;
1286
-
1287
- /* no speed readable on manual mode */
1288
- if (asus->asus_hwmon_fan_manual_mode)
1289
- return -ENXIO;
1290
-
1291
- ret = asus_hwmon_agfn_fan_speed_read(asus, fan+1, &value);
1292
- if (ret) {
1293
- pr_warn("reading fan speed failed: %d\n", ret);
1294
- return -ENXIO;
1295
- }
1296
-
1297
- return value;
1298
-}
1299
-
1300
-static void asus_hwmon_pwm_show(struct asus_wmi *asus, int fan, int *value)
1301
-{
1302
- int err;
1303
-
1304
- if (asus->asus_hwmon_pwm >= 0) {
1305
- *value = asus->asus_hwmon_pwm;
1306
- return;
1307
- }
1308
-
1309
- err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, value);
1310
- if (err < 0)
1311
- return;
1312
-
1313
- *value &= 0xFF;
1314
-
1315
- if (*value == 1) /* Low Speed */
1316
- *value = 85;
1317
- else if (*value == 2)
1318
- *value = 170;
1319
- else if (*value == 3)
1320
- *value = 255;
1321
- else if (*value) {
1322
- pr_err("Unknown fan speed %#x\n", *value);
1323
- *value = -1;
1324
- }
13251345 }
13261346
13271347 static ssize_t pwm1_show(struct device *dev,
....@@ -1329,9 +1349,33 @@
13291349 char *buf)
13301350 {
13311351 struct asus_wmi *asus = dev_get_drvdata(dev);
1352
+ int err;
13321353 int value;
13331354
1334
- asus_hwmon_pwm_show(asus, 0, &value);
1355
+ /* If we already set a value then just return it */
1356
+ if (asus->agfn_pwm >= 0)
1357
+ return sprintf(buf, "%d\n", asus->agfn_pwm);
1358
+
1359
+ /*
1360
+ * If we haven't set already set a value through the AGFN interface,
1361
+ * we read a current value through the (now-deprecated) FAN_CTRL device.
1362
+ */
1363
+ err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value);
1364
+ if (err < 0)
1365
+ return err;
1366
+
1367
+ value &= 0xFF;
1368
+
1369
+ if (value == 1) /* Low Speed */
1370
+ value = 85;
1371
+ else if (value == 2)
1372
+ value = 170;
1373
+ else if (value == 3)
1374
+ value = 255;
1375
+ else if (value) {
1376
+ pr_err("Unknown fan speed %#x\n", value);
1377
+ value = -1;
1378
+ }
13351379
13361380 return sprintf(buf, "%d\n", value);
13371381 }
....@@ -1345,17 +1389,16 @@
13451389 int ret;
13461390
13471391 ret = kstrtouint(buf, 10, &value);
1348
-
13491392 if (ret)
13501393 return ret;
13511394
13521395 value = clamp(value, 0, 255);
13531396
1354
- state = asus_hwmon_agfn_fan_speed_write(asus, 1, &value);
1397
+ state = asus_agfn_fan_speed_write(asus, 1, &value);
13551398 if (state)
13561399 pr_warn("Setting fan speed failed: %d\n", state);
13571400 else
1358
- asus->asus_hwmon_fan_manual_mode = true;
1401
+ asus->fan_pwm_mode = ASUS_FAN_CTRL_MANUAL;
13591402
13601403 return count;
13611404 }
....@@ -1364,10 +1407,37 @@
13641407 struct device_attribute *attr,
13651408 char *buf)
13661409 {
1367
- int value = asus_hwmon_fan_rpm_show(dev, 0);
1410
+ struct asus_wmi *asus = dev_get_drvdata(dev);
1411
+ int value;
1412
+ int ret;
1413
+
1414
+ switch (asus->fan_type) {
1415
+ case FAN_TYPE_SPEC83:
1416
+ ret = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_CPU_FAN_CTRL,
1417
+ &value);
1418
+ if (ret < 0)
1419
+ return ret;
1420
+
1421
+ value &= 0xffff;
1422
+ break;
1423
+
1424
+ case FAN_TYPE_AGFN:
1425
+ /* no speed readable on manual mode */
1426
+ if (asus->fan_pwm_mode == ASUS_FAN_CTRL_MANUAL)
1427
+ return -ENXIO;
1428
+
1429
+ ret = asus_agfn_fan_speed_read(asus, 1, &value);
1430
+ if (ret) {
1431
+ pr_warn("reading fan speed failed: %d\n", ret);
1432
+ return -ENXIO;
1433
+ }
1434
+ break;
1435
+
1436
+ default:
1437
+ return -ENXIO;
1438
+ }
13681439
13691440 return sprintf(buf, "%d\n", value < 0 ? -1 : value*100);
1370
-
13711441 }
13721442
13731443 static ssize_t pwm1_enable_show(struct device *dev,
....@@ -1376,10 +1446,16 @@
13761446 {
13771447 struct asus_wmi *asus = dev_get_drvdata(dev);
13781448
1379
- if (asus->asus_hwmon_fan_manual_mode)
1380
- return sprintf(buf, "%d\n", ASUS_FAN_CTRL_MANUAL);
1381
-
1382
- return sprintf(buf, "%d\n", ASUS_FAN_CTRL_AUTO);
1449
+ /*
1450
+ * Just read back the cached pwm mode.
1451
+ *
1452
+ * For the CPU_FAN device, the spec indicates that we should be
1453
+ * able to read the device status and consult bit 19 to see if we
1454
+ * are in Full On or Automatic mode. However, this does not work
1455
+ * in practice on X532FL at least (the bit is always 0) and there's
1456
+ * also nothing in the DSDT to indicate that this behaviour exists.
1457
+ */
1458
+ return sprintf(buf, "%d\n", asus->fan_pwm_mode);
13831459 }
13841460
13851461 static ssize_t pwm1_enable_store(struct device *dev,
....@@ -1389,21 +1465,50 @@
13891465 struct asus_wmi *asus = dev_get_drvdata(dev);
13901466 int status = 0;
13911467 int state;
1468
+ int value;
13921469 int ret;
1470
+ u32 retval;
13931471
13941472 ret = kstrtouint(buf, 10, &state);
1395
-
13961473 if (ret)
13971474 return ret;
13981475
1399
- if (state == ASUS_FAN_CTRL_MANUAL)
1400
- asus->asus_hwmon_fan_manual_mode = true;
1401
- else
1402
- status = asus_hwmon_fan_set_auto(asus);
1476
+ if (asus->fan_type == FAN_TYPE_SPEC83) {
1477
+ switch (state) { /* standard documented hwmon values */
1478
+ case ASUS_FAN_CTRL_FULLSPEED:
1479
+ value = 1;
1480
+ break;
1481
+ case ASUS_FAN_CTRL_AUTO:
1482
+ value = 0;
1483
+ break;
1484
+ default:
1485
+ return -EINVAL;
1486
+ }
14031487
1404
- if (status)
1405
- return status;
1488
+ ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_CPU_FAN_CTRL,
1489
+ value, &retval);
1490
+ if (ret)
1491
+ return ret;
14061492
1493
+ if (retval != 1)
1494
+ return -EIO;
1495
+ } else if (asus->fan_type == FAN_TYPE_AGFN) {
1496
+ switch (state) {
1497
+ case ASUS_FAN_CTRL_MANUAL:
1498
+ break;
1499
+
1500
+ case ASUS_FAN_CTRL_AUTO:
1501
+ status = asus_fan_set_auto(asus);
1502
+ if (status)
1503
+ return status;
1504
+ break;
1505
+
1506
+ default:
1507
+ return -EINVAL;
1508
+ }
1509
+ }
1510
+
1511
+ asus->fan_pwm_mode = state;
14071512 return count;
14081513 }
14091514
....@@ -1423,13 +1528,11 @@
14231528 int err;
14241529
14251530 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, &value);
1426
-
14271531 if (err < 0)
14281532 return err;
14291533
1430
- value = DECI_KELVIN_TO_CELSIUS((value & 0xFFFF)) * 1000;
1431
-
1432
- return sprintf(buf, "%d\n", value);
1534
+ return sprintf(buf, "%ld\n",
1535
+ deci_kelvin_to_millicelsius(value & 0xFFFF));
14331536 }
14341537
14351538 /* Fan1 */
....@@ -1455,58 +1558,34 @@
14551558 struct attribute *attr, int idx)
14561559 {
14571560 struct device *dev = container_of(kobj, struct device, kobj);
1458
- struct platform_device *pdev = to_platform_device(dev->parent);
1459
- struct asus_wmi *asus = platform_get_drvdata(pdev);
1460
- int dev_id = -1;
1461
- int fan_attr = -1;
1561
+ struct asus_wmi *asus = dev_get_drvdata(dev->parent);
14621562 u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
1463
- bool ok = true;
14641563
1465
- if (attr == &dev_attr_pwm1.attr)
1466
- dev_id = ASUS_WMI_DEVID_FAN_CTRL;
1467
- else if (attr == &dev_attr_temp1_input.attr)
1468
- dev_id = ASUS_WMI_DEVID_THERMAL_CTRL;
1469
-
1470
-
1471
- if (attr == &dev_attr_fan1_input.attr
1564
+ if (attr == &dev_attr_pwm1.attr) {
1565
+ if (asus->fan_type != FAN_TYPE_AGFN)
1566
+ return 0;
1567
+ } else if (attr == &dev_attr_fan1_input.attr
14721568 || attr == &dev_attr_fan1_label.attr
1473
- || attr == &dev_attr_pwm1.attr
14741569 || attr == &dev_attr_pwm1_enable.attr) {
1475
- fan_attr = 1;
1476
- }
1570
+ if (asus->fan_type == FAN_TYPE_NONE)
1571
+ return 0;
1572
+ } else if (attr == &dev_attr_temp1_input.attr) {
1573
+ int err = asus_wmi_get_devstate(asus,
1574
+ ASUS_WMI_DEVID_THERMAL_CTRL,
1575
+ &value);
14771576
1478
- if (dev_id != -1) {
1479
- int err = asus_wmi_get_devstate(asus, dev_id, &value);
1480
-
1481
- if (err < 0 && fan_attr == -1)
1577
+ if (err < 0)
14821578 return 0; /* can't return negative here */
1483
- }
14841579
1485
- if (dev_id == ASUS_WMI_DEVID_FAN_CTRL) {
14861580 /*
1487
- * We need to find a better way, probably using sfun,
1488
- * bits or spec ...
1489
- * Currently we disable it if:
1490
- * - ASUS_WMI_UNSUPPORTED_METHOD is returned
1491
- * - reverved bits are non-zero
1492
- * - sfun and presence bit are not set
1581
+ * If the temperature value in deci-Kelvin is near the absolute
1582
+ * zero temperature, something is clearly wrong
14931583 */
1494
- if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
1495
- || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)))
1496
- ok = false;
1497
- else
1498
- ok = fan_attr <= asus->asus_hwmon_num_fans;
1499
- } else if (dev_id == ASUS_WMI_DEVID_THERMAL_CTRL) {
1500
- /* If value is zero, something is clearly wrong */
1501
- if (!value)
1502
- ok = false;
1503
- } else if (fan_attr <= asus->asus_hwmon_num_fans && fan_attr != -1) {
1504
- ok = true;
1505
- } else {
1506
- ok = false;
1584
+ if (value == 0 || value == 1)
1585
+ return 0;
15071586 }
15081587
1509
- return ok ? attr->mode : 0;
1588
+ return attr->mode;
15101589 }
15111590
15121591 static const struct attribute_group hwmon_attribute_group = {
....@@ -1517,11 +1596,12 @@
15171596
15181597 static int asus_wmi_hwmon_init(struct asus_wmi *asus)
15191598 {
1599
+ struct device *dev = &asus->platform_device->dev;
15201600 struct device *hwmon;
15211601
1522
- hwmon = hwmon_device_register_with_groups(&asus->platform_device->dev,
1523
- "asus", asus,
1524
- hwmon_attribute_groups);
1602
+ hwmon = devm_hwmon_device_register_with_groups(dev, "asus", asus,
1603
+ hwmon_attribute_groups);
1604
+
15251605 if (IS_ERR(hwmon)) {
15261606 pr_err("Could not register asus hwmon device\n");
15271607 return PTR_ERR(hwmon);
....@@ -1529,12 +1609,246 @@
15291609 return 0;
15301610 }
15311611
1532
-/*
1533
- * Backlight
1534
- */
1612
+static int asus_wmi_fan_init(struct asus_wmi *asus)
1613
+{
1614
+ asus->fan_type = FAN_TYPE_NONE;
1615
+ asus->agfn_pwm = -1;
1616
+
1617
+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CPU_FAN_CTRL))
1618
+ asus->fan_type = FAN_TYPE_SPEC83;
1619
+ else if (asus_wmi_has_agfn_fan(asus))
1620
+ asus->fan_type = FAN_TYPE_AGFN;
1621
+
1622
+ if (asus->fan_type == FAN_TYPE_NONE)
1623
+ return -ENODEV;
1624
+
1625
+ asus_fan_set_auto(asus);
1626
+ asus->fan_pwm_mode = ASUS_FAN_CTRL_AUTO;
1627
+ return 0;
1628
+}
1629
+
1630
+/* Fan mode *******************************************************************/
1631
+
1632
+static int fan_boost_mode_check_present(struct asus_wmi *asus)
1633
+{
1634
+ u32 result;
1635
+ int err;
1636
+
1637
+ asus->fan_boost_mode_available = false;
1638
+
1639
+ err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_BOOST_MODE,
1640
+ &result);
1641
+ if (err) {
1642
+ if (err == -ENODEV)
1643
+ return 0;
1644
+ else
1645
+ return err;
1646
+ }
1647
+
1648
+ if ((result & ASUS_WMI_DSTS_PRESENCE_BIT) &&
1649
+ (result & ASUS_FAN_BOOST_MODES_MASK)) {
1650
+ asus->fan_boost_mode_available = true;
1651
+ asus->fan_boost_mode_mask = result & ASUS_FAN_BOOST_MODES_MASK;
1652
+ }
1653
+
1654
+ return 0;
1655
+}
1656
+
1657
+static int fan_boost_mode_write(struct asus_wmi *asus)
1658
+{
1659
+ int err;
1660
+ u8 value;
1661
+ u32 retval;
1662
+
1663
+ value = asus->fan_boost_mode;
1664
+
1665
+ pr_info("Set fan boost mode: %u\n", value);
1666
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_FAN_BOOST_MODE, value,
1667
+ &retval);
1668
+ if (err) {
1669
+ pr_warn("Failed to set fan boost mode: %d\n", err);
1670
+ return err;
1671
+ }
1672
+
1673
+ if (retval != 1) {
1674
+ pr_warn("Failed to set fan boost mode (retval): 0x%x\n",
1675
+ retval);
1676
+ return -EIO;
1677
+ }
1678
+
1679
+ return 0;
1680
+}
1681
+
1682
+static int fan_boost_mode_switch_next(struct asus_wmi *asus)
1683
+{
1684
+ u8 mask = asus->fan_boost_mode_mask;
1685
+
1686
+ if (asus->fan_boost_mode == ASUS_FAN_BOOST_MODE_NORMAL) {
1687
+ if (mask & ASUS_FAN_BOOST_MODE_OVERBOOST_MASK)
1688
+ asus->fan_boost_mode = ASUS_FAN_BOOST_MODE_OVERBOOST;
1689
+ else if (mask & ASUS_FAN_BOOST_MODE_SILENT_MASK)
1690
+ asus->fan_boost_mode = ASUS_FAN_BOOST_MODE_SILENT;
1691
+ } else if (asus->fan_boost_mode == ASUS_FAN_BOOST_MODE_OVERBOOST) {
1692
+ if (mask & ASUS_FAN_BOOST_MODE_SILENT_MASK)
1693
+ asus->fan_boost_mode = ASUS_FAN_BOOST_MODE_SILENT;
1694
+ else
1695
+ asus->fan_boost_mode = ASUS_FAN_BOOST_MODE_NORMAL;
1696
+ } else {
1697
+ asus->fan_boost_mode = ASUS_FAN_BOOST_MODE_NORMAL;
1698
+ }
1699
+
1700
+ return fan_boost_mode_write(asus);
1701
+}
1702
+
1703
+static ssize_t fan_boost_mode_show(struct device *dev,
1704
+ struct device_attribute *attr, char *buf)
1705
+{
1706
+ struct asus_wmi *asus = dev_get_drvdata(dev);
1707
+
1708
+ return scnprintf(buf, PAGE_SIZE, "%d\n", asus->fan_boost_mode);
1709
+}
1710
+
1711
+static ssize_t fan_boost_mode_store(struct device *dev,
1712
+ struct device_attribute *attr,
1713
+ const char *buf, size_t count)
1714
+{
1715
+ int result;
1716
+ u8 new_mode;
1717
+ struct asus_wmi *asus = dev_get_drvdata(dev);
1718
+ u8 mask = asus->fan_boost_mode_mask;
1719
+
1720
+ result = kstrtou8(buf, 10, &new_mode);
1721
+ if (result < 0) {
1722
+ pr_warn("Trying to store invalid value\n");
1723
+ return result;
1724
+ }
1725
+
1726
+ if (new_mode == ASUS_FAN_BOOST_MODE_OVERBOOST) {
1727
+ if (!(mask & ASUS_FAN_BOOST_MODE_OVERBOOST_MASK))
1728
+ return -EINVAL;
1729
+ } else if (new_mode == ASUS_FAN_BOOST_MODE_SILENT) {
1730
+ if (!(mask & ASUS_FAN_BOOST_MODE_SILENT_MASK))
1731
+ return -EINVAL;
1732
+ } else if (new_mode != ASUS_FAN_BOOST_MODE_NORMAL) {
1733
+ return -EINVAL;
1734
+ }
1735
+
1736
+ asus->fan_boost_mode = new_mode;
1737
+ fan_boost_mode_write(asus);
1738
+
1739
+ return count;
1740
+}
1741
+
1742
+// Fan boost mode: 0 - normal, 1 - overboost, 2 - silent
1743
+static DEVICE_ATTR_RW(fan_boost_mode);
1744
+
1745
+/* Throttle thermal policy ****************************************************/
1746
+
1747
+static int throttle_thermal_policy_check_present(struct asus_wmi *asus)
1748
+{
1749
+ u32 result;
1750
+ int err;
1751
+
1752
+ asus->throttle_thermal_policy_available = false;
1753
+
1754
+ err = asus_wmi_get_devstate(asus,
1755
+ ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY,
1756
+ &result);
1757
+ if (err) {
1758
+ if (err == -ENODEV)
1759
+ return 0;
1760
+ return err;
1761
+ }
1762
+
1763
+ if (result & ASUS_WMI_DSTS_PRESENCE_BIT)
1764
+ asus->throttle_thermal_policy_available = true;
1765
+
1766
+ return 0;
1767
+}
1768
+
1769
+static int throttle_thermal_policy_write(struct asus_wmi *asus)
1770
+{
1771
+ int err;
1772
+ u8 value;
1773
+ u32 retval;
1774
+
1775
+ value = asus->throttle_thermal_policy_mode;
1776
+
1777
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY,
1778
+ value, &retval);
1779
+ if (err) {
1780
+ pr_warn("Failed to set throttle thermal policy: %d\n", err);
1781
+ return err;
1782
+ }
1783
+
1784
+ if (retval != 1) {
1785
+ pr_warn("Failed to set throttle thermal policy (retval): 0x%x\n",
1786
+ retval);
1787
+ return -EIO;
1788
+ }
1789
+
1790
+ return 0;
1791
+}
1792
+
1793
+static int throttle_thermal_policy_set_default(struct asus_wmi *asus)
1794
+{
1795
+ if (!asus->throttle_thermal_policy_available)
1796
+ return 0;
1797
+
1798
+ asus->throttle_thermal_policy_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
1799
+ return throttle_thermal_policy_write(asus);
1800
+}
1801
+
1802
+static int throttle_thermal_policy_switch_next(struct asus_wmi *asus)
1803
+{
1804
+ u8 new_mode = asus->throttle_thermal_policy_mode + 1;
1805
+
1806
+ if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
1807
+ new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
1808
+
1809
+ asus->throttle_thermal_policy_mode = new_mode;
1810
+ return throttle_thermal_policy_write(asus);
1811
+}
1812
+
1813
+static ssize_t throttle_thermal_policy_show(struct device *dev,
1814
+ struct device_attribute *attr, char *buf)
1815
+{
1816
+ struct asus_wmi *asus = dev_get_drvdata(dev);
1817
+ u8 mode = asus->throttle_thermal_policy_mode;
1818
+
1819
+ return scnprintf(buf, PAGE_SIZE, "%d\n", mode);
1820
+}
1821
+
1822
+static ssize_t throttle_thermal_policy_store(struct device *dev,
1823
+ struct device_attribute *attr,
1824
+ const char *buf, size_t count)
1825
+{
1826
+ int result;
1827
+ u8 new_mode;
1828
+ struct asus_wmi *asus = dev_get_drvdata(dev);
1829
+
1830
+ result = kstrtou8(buf, 10, &new_mode);
1831
+ if (result < 0)
1832
+ return result;
1833
+
1834
+ if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
1835
+ return -EINVAL;
1836
+
1837
+ asus->throttle_thermal_policy_mode = new_mode;
1838
+ throttle_thermal_policy_write(asus);
1839
+
1840
+ return count;
1841
+}
1842
+
1843
+// Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
1844
+static DEVICE_ATTR_RW(throttle_thermal_policy);
1845
+
1846
+/* Backlight ******************************************************************/
1847
+
15351848 static int read_backlight_power(struct asus_wmi *asus)
15361849 {
15371850 int ret;
1851
+
15381852 if (asus->driver->quirks->store_backlight_power)
15391853 ret = !asus->driver->panel_power;
15401854 else
....@@ -1553,7 +1867,6 @@
15531867 int err;
15541868
15551869 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
1556
-
15571870 if (err < 0)
15581871 return err;
15591872
....@@ -1573,7 +1886,6 @@
15731886 int err;
15741887
15751888 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
1576
-
15771889 if (err < 0)
15781890 return err;
15791891
....@@ -1663,7 +1975,6 @@
16631975 return max;
16641976
16651977 power = read_backlight_power(asus);
1666
-
16671978 if (power == -ENODEV)
16681979 power = FB_BLANK_UNBLANK;
16691980 else if (power < 0)
....@@ -1713,108 +2024,200 @@
17132024 return 0;
17142025 }
17152026
1716
-static void asus_wmi_notify(u32 value, void *context)
2027
+/* Fn-lock ********************************************************************/
2028
+
2029
+static bool asus_wmi_has_fnlock_key(struct asus_wmi *asus)
17172030 {
1718
- struct asus_wmi *asus = context;
2031
+ u32 result;
2032
+
2033
+ asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FNLOCK, &result);
2034
+
2035
+ return (result & ASUS_WMI_DSTS_PRESENCE_BIT) &&
2036
+ !(result & ASUS_WMI_FNLOCK_BIOS_DISABLED);
2037
+}
2038
+
2039
+static void asus_wmi_fnlock_update(struct asus_wmi *asus)
2040
+{
2041
+ int mode = asus->fnlock_locked;
2042
+
2043
+ asus_wmi_set_devstate(ASUS_WMI_DEVID_FNLOCK, mode, NULL);
2044
+}
2045
+
2046
+/* WMI events *****************************************************************/
2047
+
2048
+static int asus_wmi_get_event_code(u32 value)
2049
+{
17192050 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
17202051 union acpi_object *obj;
17212052 acpi_status status;
17222053 int code;
1723
- int orig_code;
1724
- unsigned int key_value = 1;
1725
- bool autorelease = 1;
17262054
17272055 status = wmi_get_event_data(value, &response);
1728
- if (status != AE_OK) {
1729
- pr_err("bad event status 0x%x\n", status);
1730
- return;
2056
+ if (ACPI_FAILURE(status)) {
2057
+ pr_warn("Failed to get WMI notify code: %s\n",
2058
+ acpi_format_exception(status));
2059
+ return -EIO;
17312060 }
17322061
17332062 obj = (union acpi_object *)response.pointer;
17342063
1735
- if (!obj || obj->type != ACPI_TYPE_INTEGER)
1736
- goto exit;
2064
+ if (obj && obj->type == ACPI_TYPE_INTEGER)
2065
+ code = (int)(obj->integer.value & WMI_EVENT_MASK);
2066
+ else
2067
+ code = -EIO;
17372068
1738
- code = obj->integer.value;
2069
+ kfree(obj);
2070
+ return code;
2071
+}
2072
+
2073
+static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
2074
+{
2075
+ unsigned int key_value = 1;
2076
+ bool autorelease = 1;
2077
+ int result, orig_code;
2078
+
17392079 orig_code = code;
17402080
17412081 if (asus->driver->key_filter) {
17422082 asus->driver->key_filter(asus->driver, &code, &key_value,
17432083 &autorelease);
17442084 if (code == ASUS_WMI_KEY_IGNORE)
1745
- goto exit;
2085
+ return;
17462086 }
17472087
17482088 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
17492089 code = ASUS_WMI_BRN_UP;
1750
- else if (code >= NOTIFY_BRNDOWN_MIN &&
1751
- code <= NOTIFY_BRNDOWN_MAX)
2090
+ else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
17522091 code = ASUS_WMI_BRN_DOWN;
17532092
17542093 if (code == ASUS_WMI_BRN_DOWN || code == ASUS_WMI_BRN_UP) {
17552094 if (acpi_video_get_backlight_type() == acpi_backlight_vendor) {
17562095 asus_wmi_backlight_notify(asus, orig_code);
1757
- goto exit;
2096
+ return;
17582097 }
17592098 }
17602099
17612100 if (code == NOTIFY_KBD_BRTUP) {
1762
- do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk + 1);
1763
- goto exit;
2101
+ kbd_led_set_by_kbd(asus, asus->kbd_led_wk + 1);
2102
+ return;
17642103 }
17652104 if (code == NOTIFY_KBD_BRTDWN) {
1766
- do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk - 1);
1767
- goto exit;
2105
+ kbd_led_set_by_kbd(asus, asus->kbd_led_wk - 1);
2106
+ return;
17682107 }
17692108 if (code == NOTIFY_KBD_BRTTOGGLE) {
17702109 if (asus->kbd_led_wk == asus->kbd_led.max_brightness)
1771
- do_kbd_led_set(&asus->kbd_led, 0);
2110
+ kbd_led_set_by_kbd(asus, 0);
17722111 else
1773
- do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk + 1);
1774
- goto exit;
2112
+ kbd_led_set_by_kbd(asus, asus->kbd_led_wk + 1);
2113
+ return;
17752114 }
17762115
1777
- if (is_display_toggle(code) &&
1778
- asus->driver->quirks->no_display_toggle)
1779
- goto exit;
2116
+ if (code == NOTIFY_FNLOCK_TOGGLE) {
2117
+ asus->fnlock_locked = !asus->fnlock_locked;
2118
+ asus_wmi_fnlock_update(asus);
2119
+ return;
2120
+ }
2121
+
2122
+ if (asus->driver->quirks->use_kbd_dock_devid && code == NOTIFY_KBD_DOCK_CHANGE) {
2123
+ result = asus_wmi_get_devstate_simple(asus,
2124
+ ASUS_WMI_DEVID_KBD_DOCK);
2125
+ if (result >= 0) {
2126
+ input_report_switch(asus->inputdev, SW_TABLET_MODE,
2127
+ !result);
2128
+ input_sync(asus->inputdev);
2129
+ }
2130
+ return;
2131
+ }
2132
+
2133
+ if (asus->fan_boost_mode_available && code == NOTIFY_KBD_FBM) {
2134
+ fan_boost_mode_switch_next(asus);
2135
+ return;
2136
+ }
2137
+
2138
+ if (asus->throttle_thermal_policy_available && code == NOTIFY_KBD_TTP) {
2139
+ throttle_thermal_policy_switch_next(asus);
2140
+ return;
2141
+ }
2142
+
2143
+ if (is_display_toggle(code) && asus->driver->quirks->no_display_toggle)
2144
+ return;
17802145
17812146 if (!sparse_keymap_report_event(asus->inputdev, code,
17822147 key_value, autorelease))
17832148 pr_info("Unknown key %x pressed\n", code);
1784
-
1785
-exit:
1786
- kfree(obj);
17872149 }
17882150
1789
-/*
1790
- * Sys helpers
1791
- */
1792
-static int parse_arg(const char *buf, unsigned long count, int *val)
2151
+static void asus_wmi_notify(u32 value, void *context)
17932152 {
1794
- if (!count)
1795
- return 0;
1796
- if (sscanf(buf, "%i", val) != 1)
1797
- return -EINVAL;
1798
- return count;
2153
+ struct asus_wmi *asus = context;
2154
+ int code;
2155
+ int i;
2156
+
2157
+ for (i = 0; i < WMI_EVENT_QUEUE_SIZE + 1; i++) {
2158
+ code = asus_wmi_get_event_code(value);
2159
+ if (code < 0) {
2160
+ pr_warn("Failed to get notify code: %d\n", code);
2161
+ return;
2162
+ }
2163
+
2164
+ if (code == WMI_EVENT_QUEUE_END || code == WMI_EVENT_MASK)
2165
+ return;
2166
+
2167
+ asus_wmi_handle_event_code(code, asus);
2168
+
2169
+ /*
2170
+ * Double check that queue is present:
2171
+ * ATK (with queue) uses 0xff, ASUSWMI (without) 0xd2.
2172
+ */
2173
+ if (!asus->wmi_event_queue || value != WMI_EVENT_VALUE_ATK)
2174
+ return;
2175
+ }
2176
+
2177
+ pr_warn("Failed to process event queue, last code: 0x%x\n", code);
17992178 }
2179
+
2180
+static int asus_wmi_notify_queue_flush(struct asus_wmi *asus)
2181
+{
2182
+ int code;
2183
+ int i;
2184
+
2185
+ for (i = 0; i < WMI_EVENT_QUEUE_SIZE + 1; i++) {
2186
+ code = asus_wmi_get_event_code(WMI_EVENT_VALUE_ATK);
2187
+ if (code < 0) {
2188
+ pr_warn("Failed to get event during flush: %d\n", code);
2189
+ return code;
2190
+ }
2191
+
2192
+ if (code == WMI_EVENT_QUEUE_END || code == WMI_EVENT_MASK)
2193
+ return 0;
2194
+ }
2195
+
2196
+ pr_warn("Failed to flush event queue\n");
2197
+ return -EIO;
2198
+}
2199
+
2200
+/* Sysfs **********************************************************************/
18002201
18012202 static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid,
18022203 const char *buf, size_t count)
18032204 {
18042205 u32 retval;
1805
- int rv, err, value;
2206
+ int err, value;
18062207
18072208 value = asus_wmi_get_devstate_simple(asus, devid);
18082209 if (value < 0)
18092210 return value;
18102211
1811
- rv = parse_arg(buf, count, &value);
1812
- err = asus_wmi_set_devstate(devid, value, &retval);
2212
+ err = kstrtoint(buf, 0, &value);
2213
+ if (err)
2214
+ return err;
18132215
2216
+ err = asus_wmi_set_devstate(devid, value, &retval);
18142217 if (err < 0)
18152218 return err;
18162219
1817
- return rv;
2220
+ return count;
18182221 }
18192222
18202223 static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf)
....@@ -1863,8 +2266,10 @@
18632266 {
18642267 int value, rv;
18652268
1866
- if (!count || sscanf(buf, "%i", &value) != 1)
1867
- return -EINVAL;
2269
+ rv = kstrtoint(buf, 0, &value);
2270
+ if (rv)
2271
+ return rv;
2272
+
18682273 if (value < 0 || value > 2)
18692274 return -EINVAL;
18702275
....@@ -1884,6 +2289,8 @@
18842289 &dev_attr_touchpad.attr,
18852290 &dev_attr_lid_resume.attr,
18862291 &dev_attr_als_enable.attr,
2292
+ &dev_attr_fan_boost_mode.attr,
2293
+ &dev_attr_throttle_thermal_policy.attr,
18872294 NULL
18882295 };
18892296
....@@ -1905,6 +2312,10 @@
19052312 devid = ASUS_WMI_DEVID_LID_RESUME;
19062313 else if (attr == &dev_attr_als_enable.attr)
19072314 devid = ASUS_WMI_DEVID_ALS_ENABLE;
2315
+ else if (attr == &dev_attr_fan_boost_mode.attr)
2316
+ ok = asus->fan_boost_mode_available;
2317
+ else if (attr == &dev_attr_throttle_thermal_policy.attr)
2318
+ ok = asus->throttle_thermal_policy_available;
19082319
19092320 if (devid != -1)
19102321 ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
....@@ -1927,11 +2338,12 @@
19272338 return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
19282339 }
19292340
1930
-/*
1931
- * Platform device
1932
- */
2341
+/* Platform device ************************************************************/
2342
+
19332343 static int asus_wmi_platform_init(struct asus_wmi *asus)
19342344 {
2345
+ struct device *dev = &asus->platform_device->dev;
2346
+ char *wmi_uid;
19352347 int rv;
19362348
19372349 /* INIT enable hotkeys on some models */
....@@ -1961,11 +2373,41 @@
19612373 * Note, on most Eeepc, there is no way to check if a method exist
19622374 * or note, while on notebooks, they returns 0xFFFFFFFE on failure,
19632375 * but once again, SPEC may probably be used for that kind of things.
2376
+ *
2377
+ * Additionally at least TUF Gaming series laptops return nothing for
2378
+ * unknown methods, so the detection in this way is not possible.
2379
+ *
2380
+ * There is strong indication that only ACPI WMI devices that have _UID
2381
+ * equal to "ASUSWMI" use DCTS whereas those with "ATK" use DSTS.
19642382 */
1965
- if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL))
2383
+ wmi_uid = wmi_get_acpi_device_uid(ASUS_WMI_MGMT_GUID);
2384
+ if (!wmi_uid)
2385
+ return -ENODEV;
2386
+
2387
+ if (!strcmp(wmi_uid, ASUS_ACPI_UID_ASUSWMI)) {
2388
+ dev_info(dev, "Detected ASUSWMI, use DCTS\n");
2389
+ asus->dsts_id = ASUS_WMI_METHODID_DCTS;
2390
+ } else {
2391
+ dev_info(dev, "Detected %s, not ASUSWMI, use DSTS\n", wmi_uid);
19662392 asus->dsts_id = ASUS_WMI_METHODID_DSTS;
1967
- else
1968
- asus->dsts_id = ASUS_WMI_METHODID_DSTS2;
2393
+ }
2394
+
2395
+ /*
2396
+ * Some devices can have multiple event codes stored in a queue before
2397
+ * the module load if it was unloaded intermittently after calling
2398
+ * the INIT method (enables event handling). The WMI notify handler is
2399
+ * expected to retrieve all event codes until a retrieved code equals
2400
+ * queue end marker (One or Ones). Old codes are flushed from the queue
2401
+ * upon module load. Not enabling this when it should be has minimal
2402
+ * visible impact so fall back if anything goes wrong.
2403
+ */
2404
+ wmi_uid = wmi_get_acpi_device_uid(asus->driver->event_guid);
2405
+ if (wmi_uid && !strcmp(wmi_uid, ASUS_ACPI_UID_ATK)) {
2406
+ dev_info(dev, "Detected ATK, enable event queue\n");
2407
+
2408
+ if (!asus_wmi_notify_queue_flush(asus))
2409
+ asus->wmi_event_queue = true;
2410
+ }
19692411
19702412 /* CWAP allow to define the behavior of the Fn+F2 key,
19712413 * this method doesn't seems to be present on Eee PCs */
....@@ -1973,17 +2415,11 @@
19732415 asus_wmi_set_devstate(ASUS_WMI_DEVID_CWAP,
19742416 asus->driver->quirks->wapf, NULL);
19752417
1976
- return asus_wmi_sysfs_init(asus->platform_device);
2418
+ return 0;
19772419 }
19782420
1979
-static void asus_wmi_platform_exit(struct asus_wmi *asus)
1980
-{
1981
- asus_wmi_sysfs_exit(asus->platform_device);
1982
-}
2421
+/* debugfs ********************************************************************/
19832422
1984
-/*
1985
- * debugfs
1986
- */
19872423 struct asus_wmi_debugfs_node {
19882424 struct asus_wmi *asus;
19892425 char *name;
....@@ -1997,7 +2433,6 @@
19972433 u32 retval = -1;
19982434
19992435 err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
2000
-
20012436 if (err < 0)
20022437 return err;
20032438
....@@ -2014,7 +2449,6 @@
20142449
20152450 err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
20162451 &retval);
2017
-
20182452 if (err < 0)
20192453 return err;
20202454
....@@ -2084,74 +2518,33 @@
20842518 debugfs_remove_recursive(asus->debug.root);
20852519 }
20862520
2087
-static int asus_wmi_debugfs_init(struct asus_wmi *asus)
2521
+static void asus_wmi_debugfs_init(struct asus_wmi *asus)
20882522 {
2089
- struct dentry *dent;
20902523 int i;
20912524
20922525 asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
2093
- if (!asus->debug.root) {
2094
- pr_err("failed to create debugfs directory\n");
2095
- goto error_debugfs;
2096
- }
20972526
2098
- dent = debugfs_create_x32("method_id", S_IRUGO | S_IWUSR,
2099
- asus->debug.root, &asus->debug.method_id);
2100
- if (!dent)
2101
- goto error_debugfs;
2527
+ debugfs_create_x32("method_id", S_IRUGO | S_IWUSR, asus->debug.root,
2528
+ &asus->debug.method_id);
21022529
2103
- dent = debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR,
2104
- asus->debug.root, &asus->debug.dev_id);
2105
- if (!dent)
2106
- goto error_debugfs;
2530
+ debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR, asus->debug.root,
2531
+ &asus->debug.dev_id);
21072532
2108
- dent = debugfs_create_x32("ctrl_param", S_IRUGO | S_IWUSR,
2109
- asus->debug.root, &asus->debug.ctrl_param);
2110
- if (!dent)
2111
- goto error_debugfs;
2533
+ debugfs_create_x32("ctrl_param", S_IRUGO | S_IWUSR, asus->debug.root,
2534
+ &asus->debug.ctrl_param);
21122535
21132536 for (i = 0; i < ARRAY_SIZE(asus_wmi_debug_files); i++) {
21142537 struct asus_wmi_debugfs_node *node = &asus_wmi_debug_files[i];
21152538
21162539 node->asus = asus;
2117
- dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
2118
- asus->debug.root, node,
2119
- &asus_wmi_debugfs_io_ops);
2120
- if (!dent) {
2121
- pr_err("failed to create debug file: %s\n", node->name);
2122
- goto error_debugfs;
2123
- }
2540
+ debugfs_create_file(node->name, S_IFREG | S_IRUGO,
2541
+ asus->debug.root, node,
2542
+ &asus_wmi_debugfs_io_ops);
21242543 }
2125
-
2126
- return 0;
2127
-
2128
-error_debugfs:
2129
- asus_wmi_debugfs_exit(asus);
2130
- return -ENOMEM;
21312544 }
21322545
2133
-static int asus_wmi_fan_init(struct asus_wmi *asus)
2134
-{
2135
- int status;
2546
+/* Init / exit ****************************************************************/
21362547
2137
- asus->asus_hwmon_pwm = -1;
2138
- asus->asus_hwmon_num_fans = -1;
2139
- asus->asus_hwmon_fan_manual_mode = false;
2140
-
2141
- status = asus_hwmon_get_fan_number(asus, &asus->asus_hwmon_num_fans);
2142
- if (status) {
2143
- asus->asus_hwmon_num_fans = 0;
2144
- pr_warn("Could not determine number of fans: %d\n", status);
2145
- return -ENXIO;
2146
- }
2147
-
2148
- pr_info("Number of fans: %d\n", asus->asus_hwmon_num_fans);
2149
- return 0;
2150
-}
2151
-
2152
-/*
2153
- * WMI Driver
2154
- */
21552548 static int asus_wmi_add(struct platform_device *pdev)
21562549 {
21572550 struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
....@@ -2178,12 +2571,25 @@
21782571 if (err)
21792572 goto fail_platform;
21802573
2574
+ err = fan_boost_mode_check_present(asus);
2575
+ if (err)
2576
+ goto fail_fan_boost_mode;
2577
+
2578
+ err = throttle_thermal_policy_check_present(asus);
2579
+ if (err)
2580
+ goto fail_throttle_thermal_policy;
2581
+ else
2582
+ throttle_thermal_policy_set_default(asus);
2583
+
2584
+ err = asus_wmi_sysfs_init(asus->platform_device);
2585
+ if (err)
2586
+ goto fail_sysfs;
2587
+
21812588 err = asus_wmi_input_init(asus);
21822589 if (err)
21832590 goto fail_input;
21842591
21852592 err = asus_wmi_fan_init(asus); /* probably no problems on error */
2186
- asus_hwmon_fan_set_auto(asus);
21872593
21882594 err = asus_wmi_hwmon_init(asus);
21892595 if (err)
....@@ -2228,6 +2634,11 @@
22282634 } else if (asus->driver->quirks->wmi_backlight_set_devstate)
22292635 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT, 2, NULL);
22302636
2637
+ if (asus_wmi_has_fnlock_key(asus)) {
2638
+ asus->fnlock_locked = true;
2639
+ asus_wmi_fnlock_update(asus);
2640
+ }
2641
+
22312642 status = wmi_install_notify_handler(asus->driver->event_guid,
22322643 asus_wmi_notify, asus);
22332644 if (ACPI_FAILURE(status)) {
....@@ -2236,14 +2647,12 @@
22362647 goto fail_wmi_handler;
22372648 }
22382649
2239
- err = asus_wmi_debugfs_init(asus);
2240
- if (err)
2241
- goto fail_debugfs;
2650
+ asus_wmi_battery_init(asus);
2651
+
2652
+ asus_wmi_debugfs_init(asus);
22422653
22432654 return 0;
22442655
2245
-fail_debugfs:
2246
- wmi_remove_notify_handler(asus->driver->event_guid);
22472656 fail_wmi_handler:
22482657 asus_wmi_backlight_exit(asus);
22492658 fail_backlight:
....@@ -2254,7 +2663,10 @@
22542663 fail_hwmon:
22552664 asus_wmi_input_exit(asus);
22562665 fail_input:
2257
- asus_wmi_platform_exit(asus);
2666
+ asus_wmi_sysfs_exit(asus->platform_device);
2667
+fail_sysfs:
2668
+fail_throttle_thermal_policy:
2669
+fail_fan_boost_mode:
22582670 fail_platform:
22592671 kfree(asus);
22602672 return err;
....@@ -2271,16 +2683,16 @@
22712683 asus_wmi_led_exit(asus);
22722684 asus_wmi_rfkill_exit(asus);
22732685 asus_wmi_debugfs_exit(asus);
2274
- asus_wmi_platform_exit(asus);
2275
- asus_hwmon_fan_set_auto(asus);
2686
+ asus_wmi_sysfs_exit(asus->platform_device);
2687
+ asus_fan_set_auto(asus);
2688
+ asus_wmi_battery_exit(asus);
22762689
22772690 kfree(asus);
22782691 return 0;
22792692 }
22802693
2281
-/*
2282
- * Platform driver - hibernate/resume callbacks
2283
- */
2694
+/* Platform driver - hibernate/resume callbacks *******************************/
2695
+
22842696 static int asus_hotk_thaw(struct device *device)
22852697 {
22862698 struct asus_wmi *asus = dev_get_drvdata(device);
....@@ -2305,8 +2717,10 @@
23052717 struct asus_wmi *asus = dev_get_drvdata(device);
23062718
23072719 if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
2308
- queue_work(asus->led_workqueue, &asus->kbd_led_work);
2720
+ kbd_led_update(asus);
23092721
2722
+ if (asus_wmi_has_fnlock_key(asus))
2723
+ asus_wmi_fnlock_update(asus);
23102724 return 0;
23112725 }
23122726
....@@ -2341,8 +2755,10 @@
23412755 rfkill_set_sw_state(asus->uwb.rfkill, bl);
23422756 }
23432757 if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
2344
- queue_work(asus->led_workqueue, &asus->kbd_led_work);
2758
+ kbd_led_update(asus);
23452759
2760
+ if (asus_wmi_has_fnlock_key(asus))
2761
+ asus_wmi_fnlock_update(asus);
23462762 return 0;
23472763 }
23482764
....@@ -2352,6 +2768,8 @@
23522768 .resume = asus_hotk_resume,
23532769 };
23542770
2771
+/* Registration ***************************************************************/
2772
+
23552773 static int asus_wmi_probe(struct platform_device *pdev)
23562774 {
23572775 struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
....@@ -2359,12 +2777,12 @@
23592777 int ret;
23602778
23612779 if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
2362
- pr_warn("Management GUID not found\n");
2780
+ pr_warn("ASUS Management GUID not found\n");
23632781 return -ENODEV;
23642782 }
23652783
23662784 if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) {
2367
- pr_warn("Event GUID not found\n");
2785
+ pr_warn("ASUS Event GUID not found\n");
23682786 return -ENODEV;
23692787 }
23702788
....@@ -2414,11 +2832,6 @@
24142832
24152833 static int __init asus_wmi_init(void)
24162834 {
2417
- if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
2418
- pr_info("Asus Management GUID not found\n");
2419
- return -ENODEV;
2420
- }
2421
-
24222835 pr_info("ASUS WMI generic driver loaded\n");
24232836 return 0;
24242837 }