1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Asus PC WMI hotkey driver
4 *
5 * Copyright(C) 2010 Intel Corporation.
6 * Copyright(C) 2010-2011 Corentin Chary <corentin.chary@gmail.com>
7 *
8 * Portions based on wistron_btns.c:
9 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
10 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
11 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
12 */
13
14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16#include <linux/acpi.h>
17#include <linux/backlight.h>
18#include <linux/debugfs.h>
19#include <linux/delay.h>
20#include <linux/dmi.h>
21#include <linux/hwmon.h>
22#include <linux/hwmon-sysfs.h>
23#include <linux/init.h>
24#include <linux/input.h>
25#include <linux/input/sparse-keymap.h>
26#include <linux/kernel.h>
27#include <linux/leds.h>
28#include <linux/minmax.h>
29#include <linux/module.h>
30#include <linux/pci.h>
31#include <linux/pci_hotplug.h>
32#include <linux/platform_data/x86/asus-wmi.h>
33#include <linux/platform_device.h>
34#include <linux/platform_profile.h>
35#include <linux/power_supply.h>
36#include <linux/rfkill.h>
37#include <linux/seq_file.h>
38#include <linux/slab.h>
39#include <linux/types.h>
40#include <linux/units.h>
41
42#include <acpi/battery.h>
43#include <acpi/video.h>
44
45#include "asus-wmi.h"
46
47MODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>");
48MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
49MODULE_DESCRIPTION("Asus Generic WMI Driver");
50MODULE_LICENSE("GPL");
51
52static bool fnlock_default = true;
53module_param(fnlock_default, bool, 0444);
54
55#define to_asus_wmi_driver(pdrv) \
56 (container_of((pdrv), struct asus_wmi_driver, platform_driver))
57
58#define ASUS_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66"
59
60#define NOTIFY_BRNUP_MIN 0x11
61#define NOTIFY_BRNUP_MAX 0x1f
62#define NOTIFY_BRNDOWN_MIN 0x20
63#define NOTIFY_BRNDOWN_MAX 0x2e
64#define NOTIFY_FNLOCK_TOGGLE 0x4e
65#define NOTIFY_KBD_DOCK_CHANGE 0x75
66#define NOTIFY_KBD_BRTUP 0xc4
67#define NOTIFY_KBD_BRTDWN 0xc5
68#define NOTIFY_KBD_BRTTOGGLE 0xc7
69#define NOTIFY_KBD_FBM 0x99
70#define NOTIFY_KBD_TTP 0xae
71#define NOTIFY_LID_FLIP 0xfa
72#define NOTIFY_LID_FLIP_ROG 0xbd
73
74#define ASUS_WMI_FNLOCK_BIOS_DISABLED BIT(0)
75
76#define ASUS_MID_FAN_DESC "mid_fan"
77#define ASUS_GPU_FAN_DESC "gpu_fan"
78#define ASUS_FAN_DESC "cpu_fan"
79#define ASUS_FAN_MFUN 0x13
80#define ASUS_FAN_SFUN_READ 0x06
81#define ASUS_FAN_SFUN_WRITE 0x07
82
83/* Based on standard hwmon pwmX_enable values */
84#define ASUS_FAN_CTRL_FULLSPEED 0
85#define ASUS_FAN_CTRL_MANUAL 1
86#define ASUS_FAN_CTRL_AUTO 2
87
88#define ASUS_FAN_BOOST_MODE_NORMAL 0
89#define ASUS_FAN_BOOST_MODE_OVERBOOST 1
90#define ASUS_FAN_BOOST_MODE_OVERBOOST_MASK 0x01
91#define ASUS_FAN_BOOST_MODE_SILENT 2
92#define ASUS_FAN_BOOST_MODE_SILENT_MASK 0x02
93#define ASUS_FAN_BOOST_MODES_MASK 0x03
94
95#define ASUS_THROTTLE_THERMAL_POLICY_DEFAULT 0
96#define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST 1
97#define ASUS_THROTTLE_THERMAL_POLICY_SILENT 2
98
99#define ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO 0
100#define ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO 1
101#define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO 2
102
103#define PLATFORM_PROFILE_MAX 2
104
105#define USB_INTEL_XUSB2PR 0xD0
106#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
107
108#define ASUS_ACPI_UID_ASUSWMI "ASUSWMI"
109
110#define WMI_EVENT_MASK 0xFFFF
111
112#define FAN_CURVE_POINTS 8
113#define FAN_CURVE_BUF_LEN 32
114#define FAN_CURVE_DEV_CPU 0x00
115#define FAN_CURVE_DEV_GPU 0x01
116#define FAN_CURVE_DEV_MID 0x02
117/* Mask to determine if setting temperature or percentage */
118#define FAN_CURVE_PWM_MASK 0x04
119
120/* Limits for tunables available on ASUS ROG laptops */
121#define PPT_TOTAL_MIN 5
122#define PPT_TOTAL_MAX 250
123#define PPT_CPU_MIN 5
124#define PPT_CPU_MAX 130
125#define NVIDIA_BOOST_MIN 5
126#define NVIDIA_BOOST_MAX 25
127#define NVIDIA_TEMP_MIN 75
128#define NVIDIA_TEMP_MAX 87
129
130#define ASUS_SCREENPAD_BRIGHT_MIN 20
131#define ASUS_SCREENPAD_BRIGHT_MAX 255
132#define ASUS_SCREENPAD_BRIGHT_DEFAULT 60
133
134#define ASUS_MINI_LED_MODE_MASK 0x03
135/* Standard modes for devices with only on/off */
136#define ASUS_MINI_LED_OFF 0x00
137#define ASUS_MINI_LED_ON 0x01
138/* New mode on some devices, define here to clarify remapping later */
139#define ASUS_MINI_LED_STRONG_MODE 0x02
140/* New modes for devices with 3 mini-led mode types */
141#define ASUS_MINI_LED_2024_WEAK 0x00
142#define ASUS_MINI_LED_2024_STRONG 0x01
143#define ASUS_MINI_LED_2024_OFF 0x02
144
145#define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE"
146/*
147 * The period required to wait after screen off/on/s2idle.check in MS.
148 * Time here greatly impacts the wake behaviour. Used in suspend/wake.
149 */
150#define ASUS_USB0_PWR_EC0_CSEE_WAIT 600
151#define ASUS_USB0_PWR_EC0_CSEE_OFF 0xB7
152#define ASUS_USB0_PWR_EC0_CSEE_ON 0xB8
153
154static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
155
156static int throttle_thermal_policy_write(struct asus_wmi *);
157
158static const struct dmi_system_id asus_rog_ally_device[] = {
159 {
160 .matches = {
161 DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
162 },
163 },
164 {
165 .matches = {
166 DMI_MATCH(DMI_BOARD_NAME, "RC72L"),
167 },
168 },
169 { },
170};
171
172static bool ashs_present(void)
173{
174 int i = 0;
175 while (ashs_ids[i]) {
176 if (acpi_dev_found(hid: ashs_ids[i++]))
177 return true;
178 }
179 return false;
180}
181
182struct bios_args {
183 u32 arg0;
184 u32 arg1;
185 u32 arg2; /* At least TUF Gaming series uses 3 dword input buffer. */
186 u32 arg3;
187 u32 arg4; /* Some ROG laptops require a full 5 input args */
188 u32 arg5;
189} __packed;
190
191/*
192 * Struct that's used for all methods called via AGFN. Naming is
193 * identically to the AML code.
194 */
195struct agfn_args {
196 u16 mfun; /* probably "Multi-function" to be called */
197 u16 sfun; /* probably "Sub-function" to be called */
198 u16 len; /* size of the hole struct, including subfunction fields */
199 u8 stas; /* not used by now */
200 u8 err; /* zero on success */
201} __packed;
202
203/* struct used for calling fan read and write methods */
204struct agfn_fan_args {
205 struct agfn_args agfn; /* common fields */
206 u8 fan; /* fan number: 0: set auto mode 1: 1st fan */
207 u32 speed; /* read: RPM/100 - write: 0-255 */
208} __packed;
209
210/*
211 * <platform>/ - debugfs root directory
212 * dev_id - current dev_id
213 * ctrl_param - current ctrl_param
214 * method_id - current method_id
215 * devs - call DEVS(dev_id, ctrl_param) and print result
216 * dsts - call DSTS(dev_id) and print result
217 * call - call method_id(dev_id, ctrl_param) and print result
218 */
219struct asus_wmi_debug {
220 struct dentry *root;
221 u32 method_id;
222 u32 dev_id;
223 u32 ctrl_param;
224};
225
226struct asus_rfkill {
227 struct asus_wmi *asus;
228 struct rfkill *rfkill;
229 u32 dev_id;
230};
231
232enum fan_type {
233 FAN_TYPE_NONE = 0,
234 FAN_TYPE_AGFN, /* deprecated on newer platforms */
235 FAN_TYPE_SPEC83, /* starting in Spec 8.3, use CPU_FAN_CTRL */
236};
237
238struct fan_curve_data {
239 bool enabled;
240 u32 device_id;
241 u8 temps[FAN_CURVE_POINTS];
242 u8 percents[FAN_CURVE_POINTS];
243};
244
245struct asus_wmi {
246 int dsts_id;
247 int spec;
248 int sfun;
249
250 struct input_dev *inputdev;
251 struct backlight_device *backlight_device;
252 struct backlight_device *screenpad_backlight_device;
253 struct platform_device *platform_device;
254
255 struct led_classdev wlan_led;
256 int wlan_led_wk;
257 struct led_classdev tpd_led;
258 int tpd_led_wk;
259 struct led_classdev kbd_led;
260 int kbd_led_wk;
261 struct led_classdev lightbar_led;
262 int lightbar_led_wk;
263 struct led_classdev micmute_led;
264 struct led_classdev camera_led;
265 struct workqueue_struct *led_workqueue;
266 struct work_struct tpd_led_work;
267 struct work_struct wlan_led_work;
268 struct work_struct lightbar_led_work;
269
270 struct asus_rfkill wlan;
271 struct asus_rfkill bluetooth;
272 struct asus_rfkill wimax;
273 struct asus_rfkill wwan3g;
274 struct asus_rfkill gps;
275 struct asus_rfkill uwb;
276
277 int tablet_switch_event_code;
278 u32 tablet_switch_dev_id;
279 bool tablet_switch_inverted;
280
281 enum fan_type fan_type;
282 enum fan_type gpu_fan_type;
283 enum fan_type mid_fan_type;
284 int fan_pwm_mode;
285 int gpu_fan_pwm_mode;
286 int mid_fan_pwm_mode;
287 int agfn_pwm;
288
289 bool fan_boost_mode_available;
290 u8 fan_boost_mode_mask;
291 u8 fan_boost_mode;
292
293 bool egpu_enable_available;
294 bool dgpu_disable_available;
295 u32 gpu_mux_dev;
296
297 /* Tunables provided by ASUS for gaming laptops */
298 u32 ppt_pl2_sppt;
299 u32 ppt_pl1_spl;
300 u32 ppt_apu_sppt;
301 u32 ppt_platform_sppt;
302 u32 ppt_fppt;
303 u32 nv_dynamic_boost;
304 u32 nv_temp_target;
305
306 u32 kbd_rgb_dev;
307 bool kbd_rgb_state_available;
308 bool oobe_state_available;
309
310 u8 throttle_thermal_policy_mode;
311 u32 throttle_thermal_policy_dev;
312
313 bool cpu_fan_curve_available;
314 bool gpu_fan_curve_available;
315 bool mid_fan_curve_available;
316 struct fan_curve_data custom_fan_curves[3];
317
318 struct device *ppdev;
319 bool platform_profile_support;
320
321 // The RSOC controls the maximum charging percentage.
322 bool battery_rsoc_available;
323
324 bool panel_overdrive_available;
325 u32 mini_led_dev_id;
326
327 struct hotplug_slot hotplug_slot;
328 struct mutex hotplug_lock;
329 struct mutex wmi_lock;
330 struct workqueue_struct *hotplug_workqueue;
331 struct work_struct hotplug_work;
332
333 bool fnlock_locked;
334
335 struct asus_wmi_debug debug;
336
337 struct asus_wmi_driver *driver;
338};
339
340/* Global to allow setting externally without requiring driver data */
341static enum asus_ally_mcu_hack use_ally_mcu_hack = ASUS_WMI_ALLY_MCU_HACK_INIT;
342
343/* WMI ************************************************************************/
344
345static int asus_wmi_evaluate_method3(u32 method_id,
346 u32 arg0, u32 arg1, u32 arg2, u32 *retval)
347{
348 struct bios_args args = {
349 .arg0 = arg0,
350 .arg1 = arg1,
351 .arg2 = arg2,
352 };
353 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
354 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
355 acpi_status status;
356 union acpi_object *obj;
357 u32 tmp = 0;
358
359 status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, instance: 0, method_id,
360 in: &input, out: &output);
361
362 pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x\n",
363 __func__, method_id, arg0, arg1, arg2);
364 if (ACPI_FAILURE(status)) {
365 pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
366 __func__, method_id, arg0, -EIO);
367 return -EIO;
368 }
369
370 obj = (union acpi_object *)output.pointer;
371 if (obj && obj->type == ACPI_TYPE_INTEGER)
372 tmp = (u32) obj->integer.value;
373
374 pr_debug("Result: 0x%08x\n", tmp);
375 if (retval)
376 *retval = tmp;
377
378 kfree(objp: obj);
379
380 if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) {
381 pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
382 __func__, method_id, arg0, -ENODEV);
383 return -ENODEV;
384 }
385
386 return 0;
387}
388
389int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval)
390{
391 return asus_wmi_evaluate_method3(method_id, arg0, arg1, arg2: 0, retval);
392}
393EXPORT_SYMBOL_GPL(asus_wmi_evaluate_method);
394
395static int asus_wmi_evaluate_method5(u32 method_id,
396 u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4, u32 *retval)
397{
398 struct bios_args args = {
399 .arg0 = arg0,
400 .arg1 = arg1,
401 .arg2 = arg2,
402 .arg3 = arg3,
403 .arg4 = arg4,
404 };
405 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
406 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
407 acpi_status status;
408 union acpi_object *obj;
409 u32 tmp = 0;
410
411 status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, instance: 0, method_id,
412 in: &input, out: &output);
413
414 pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
415 __func__, method_id, arg0, arg1, arg2, arg3, arg4);
416 if (ACPI_FAILURE(status)) {
417 pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
418 __func__, method_id, arg0, -EIO);
419 return -EIO;
420 }
421
422 obj = (union acpi_object *)output.pointer;
423 if (obj && obj->type == ACPI_TYPE_INTEGER)
424 tmp = (u32) obj->integer.value;
425
426 pr_debug("Result: %x\n", tmp);
427 if (retval)
428 *retval = tmp;
429
430 kfree(objp: obj);
431
432 if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) {
433 pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
434 __func__, method_id, arg0, -ENODEV);
435 return -ENODEV;
436 }
437
438 return 0;
439}
440
441/*
442 * Returns as an error if the method output is not a buffer. Typically this
443 * means that the method called is unsupported.
444 */
445static int asus_wmi_evaluate_method_buf(u32 method_id,
446 u32 arg0, u32 arg1, u8 *ret_buffer, size_t size)
447{
448 struct bios_args args = {
449 .arg0 = arg0,
450 .arg1 = arg1,
451 .arg2 = 0,
452 };
453 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
454 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
455 acpi_status status;
456 union acpi_object *obj;
457 int err = 0;
458
459 status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, instance: 0, method_id,
460 in: &input, out: &output);
461
462 pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x\n",
463 __func__, method_id, arg0, arg1);
464 if (ACPI_FAILURE(status)) {
465 pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
466 __func__, method_id, arg0, -EIO);
467 return -EIO;
468 }
469
470 obj = (union acpi_object *)output.pointer;
471
472 switch (obj->type) {
473 case ACPI_TYPE_BUFFER:
474 if (obj->buffer.length > size) {
475 err = -ENOSPC;
476 break;
477 }
478 if (obj->buffer.length == 0) {
479 err = -ENODATA;
480 break;
481 }
482
483 memcpy(ret_buffer, obj->buffer.pointer, obj->buffer.length);
484 break;
485 case ACPI_TYPE_INTEGER:
486 err = (u32)obj->integer.value;
487
488 if (err == ASUS_WMI_UNSUPPORTED_METHOD)
489 err = -ENODEV;
490 /*
491 * At least one method returns a 0 with no buffer if no arg
492 * is provided, such as ASUS_WMI_DEVID_CPU_FAN_CURVE
493 */
494 if (err == 0)
495 err = -ENODATA;
496 break;
497 default:
498 err = -ENODATA;
499 break;
500 }
501
502 kfree(objp: obj);
503
504 if (err) {
505 pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
506 __func__, method_id, arg0, err);
507 return err;
508 }
509
510 return 0;
511}
512
513static int asus_wmi_evaluate_method_agfn(const struct acpi_buffer args)
514{
515 struct acpi_buffer input;
516 u64 phys_addr;
517 u32 retval;
518 u32 status;
519
520 /*
521 * Copy to dma capable address otherwise memory corruption occurs as
522 * bios has to be able to access it.
523 */
524 input.pointer = kmemdup(args.pointer, args.length, GFP_DMA | GFP_KERNEL);
525 input.length = args.length;
526 if (!input.pointer)
527 return -ENOMEM;
528 phys_addr = virt_to_phys(address: input.pointer);
529
530 status = asus_wmi_evaluate_method(ASUS_WMI_METHODID_AGFN,
531 phys_addr, 0, &retval);
532 if (!status)
533 memcpy(args.pointer, input.pointer, args.length);
534
535 kfree(objp: input.pointer);
536 if (status)
537 return -ENXIO;
538
539 return retval;
540}
541
542static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
543{
544 int err;
545
546 err = asus_wmi_evaluate_method(asus->dsts_id, dev_id, 0, retval);
547
548 if (err)
549 return err;
550
551 if (*retval == ~0)
552 return -ENODEV;
553
554 return 0;
555}
556
557int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
558 u32 *retval)
559{
560 return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id,
561 ctrl_param, retval);
562}
563
564/* Helper for special devices with magic return codes */
565static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
566 u32 dev_id, u32 mask)
567{
568 u32 retval = 0;
569 int err;
570
571 err = asus_wmi_get_devstate(asus, dev_id, retval: &retval);
572 if (err < 0)
573 return err;
574
575 if (!(retval & ASUS_WMI_DSTS_PRESENCE_BIT))
576 return -ENODEV;
577
578 if (mask == ASUS_WMI_DSTS_STATUS_BIT) {
579 if (retval & ASUS_WMI_DSTS_UNKNOWN_BIT)
580 return -ENODEV;
581 }
582
583 return retval & mask;
584}
585
586static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id)
587{
588 return asus_wmi_get_devstate_bits(asus, dev_id,
589 ASUS_WMI_DSTS_STATUS_BIT);
590}
591
592static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
593{
594 u32 retval;
595 int status = asus_wmi_get_devstate(asus, dev_id, retval: &retval);
596 pr_debug("%s called (0x%08x), retval: 0x%08x\n", __func__, dev_id, retval);
597
598 return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT);
599}
600
601/* Input **********************************************************************/
602static void asus_wmi_tablet_sw_report(struct asus_wmi *asus, bool value)
603{
604 input_report_switch(dev: asus->inputdev, SW_TABLET_MODE,
605 value: asus->tablet_switch_inverted ? !value : value);
606 input_sync(dev: asus->inputdev);
607}
608
609static void asus_wmi_tablet_sw_init(struct asus_wmi *asus, u32 dev_id, int event_code)
610{
611 struct device *dev = &asus->platform_device->dev;
612 int result;
613
614 result = asus_wmi_get_devstate_simple(asus, dev_id);
615 if (result >= 0) {
616 input_set_capability(dev: asus->inputdev, EV_SW, SW_TABLET_MODE);
617 asus_wmi_tablet_sw_report(asus, value: result);
618 asus->tablet_switch_dev_id = dev_id;
619 asus->tablet_switch_event_code = event_code;
620 } else if (result == -ENODEV) {
621 dev_err(dev, "This device has tablet-mode-switch quirk but got ENODEV checking it. This is a bug.");
622 } else {
623 dev_err(dev, "Error checking for tablet-mode-switch: %d\n", result);
624 }
625}
626
627static int asus_wmi_input_init(struct asus_wmi *asus)
628{
629 struct device *dev = &asus->platform_device->dev;
630 int err;
631
632 asus->inputdev = input_allocate_device();
633 if (!asus->inputdev)
634 return -ENOMEM;
635
636 asus->inputdev->name = asus->driver->input_name;
637 asus->inputdev->phys = asus->driver->input_phys;
638 asus->inputdev->id.bustype = BUS_HOST;
639 asus->inputdev->dev.parent = dev;
640 set_bit(EV_REP, addr: asus->inputdev->evbit);
641
642 err = sparse_keymap_setup(dev: asus->inputdev, keymap: asus->driver->keymap, NULL);
643 if (err)
644 goto err_free_dev;
645
646 switch (asus->driver->quirks->tablet_switch_mode) {
647 case asus_wmi_no_tablet_switch:
648 break;
649 case asus_wmi_kbd_dock_devid:
650 asus->tablet_switch_inverted = true;
651 asus_wmi_tablet_sw_init(asus, ASUS_WMI_DEVID_KBD_DOCK, NOTIFY_KBD_DOCK_CHANGE);
652 break;
653 case asus_wmi_lid_flip_devid:
654 asus_wmi_tablet_sw_init(asus, ASUS_WMI_DEVID_LID_FLIP, NOTIFY_LID_FLIP);
655 break;
656 case asus_wmi_lid_flip_rog_devid:
657 asus_wmi_tablet_sw_init(asus, ASUS_WMI_DEVID_LID_FLIP_ROG, NOTIFY_LID_FLIP_ROG);
658 break;
659 }
660
661 err = input_register_device(asus->inputdev);
662 if (err)
663 goto err_free_dev;
664
665 return 0;
666
667err_free_dev:
668 input_free_device(dev: asus->inputdev);
669 return err;
670}
671
672static void asus_wmi_input_exit(struct asus_wmi *asus)
673{
674 if (asus->inputdev)
675 input_unregister_device(asus->inputdev);
676
677 asus->inputdev = NULL;
678}
679
680/* Tablet mode ****************************************************************/
681
682static void asus_wmi_tablet_mode_get_state(struct asus_wmi *asus)
683{
684 int result;
685
686 if (!asus->tablet_switch_dev_id)
687 return;
688
689 result = asus_wmi_get_devstate_simple(asus, dev_id: asus->tablet_switch_dev_id);
690 if (result >= 0)
691 asus_wmi_tablet_sw_report(asus, value: result);
692}
693
694/* Charging mode, 1=Barrel, 2=USB ******************************************/
695static ssize_t charge_mode_show(struct device *dev,
696 struct device_attribute *attr, char *buf)
697{
698 struct asus_wmi *asus = dev_get_drvdata(dev);
699 int result, value;
700
701 result = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_CHARGE_MODE, retval: &value);
702 if (result < 0)
703 return result;
704
705 return sysfs_emit(buf, fmt: "%d\n", value & 0xff);
706}
707
708static DEVICE_ATTR_RO(charge_mode);
709
710/* dGPU ********************************************************************/
711static ssize_t dgpu_disable_show(struct device *dev,
712 struct device_attribute *attr, char *buf)
713{
714 struct asus_wmi *asus = dev_get_drvdata(dev);
715 int result;
716
717 result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_DGPU);
718 if (result < 0)
719 return result;
720
721 return sysfs_emit(buf, fmt: "%d\n", result);
722}
723
724/*
725 * A user may be required to store the value twice, typcial store first, then
726 * rescan PCI bus to activate power, then store a second time to save correctly.
727 * The reason for this is that an extra code path in the ACPI is enabled when
728 * the device and bus are powered.
729 */
730static ssize_t dgpu_disable_store(struct device *dev,
731 struct device_attribute *attr,
732 const char *buf, size_t count)
733{
734 int result, err;
735 u32 disable;
736
737 struct asus_wmi *asus = dev_get_drvdata(dev);
738
739 result = kstrtou32(s: buf, base: 10, res: &disable);
740 if (result)
741 return result;
742
743 if (disable > 1)
744 return -EINVAL;
745
746 if (asus->gpu_mux_dev) {
747 result = asus_wmi_get_devstate_simple(asus, dev_id: asus->gpu_mux_dev);
748 if (result < 0)
749 /* An error here may signal greater failure of GPU handling */
750 return result;
751 if (!result && disable) {
752 err = -ENODEV;
753 pr_warn("Can not disable dGPU when the MUX is in dGPU mode: %d\n", err);
754 return err;
755 }
756 }
757
758 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, ctrl_param: disable, retval: &result);
759 if (err) {
760 pr_warn("Failed to set dgpu disable: %d\n", err);
761 return err;
762 }
763
764 if (result > 1) {
765 pr_warn("Failed to set dgpu disable (result): 0x%x\n", result);
766 return -EIO;
767 }
768
769 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "dgpu_disable");
770
771 return count;
772}
773static DEVICE_ATTR_RW(dgpu_disable);
774
775/* eGPU ********************************************************************/
776static ssize_t egpu_enable_show(struct device *dev,
777 struct device_attribute *attr, char *buf)
778{
779 struct asus_wmi *asus = dev_get_drvdata(dev);
780 int result;
781
782 result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_EGPU);
783 if (result < 0)
784 return result;
785
786 return sysfs_emit(buf, fmt: "%d\n", result);
787}
788
789/* The ACPI call to enable the eGPU also disables the internal dGPU */
790static ssize_t egpu_enable_store(struct device *dev,
791 struct device_attribute *attr,
792 const char *buf, size_t count)
793{
794 int result, err;
795 u32 enable;
796
797 struct asus_wmi *asus = dev_get_drvdata(dev);
798
799 err = kstrtou32(s: buf, base: 10, res: &enable);
800 if (err)
801 return err;
802
803 if (enable > 1)
804 return -EINVAL;
805
806 err = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_EGPU_CONNECTED);
807 if (err < 0) {
808 pr_warn("Failed to get egpu connection status: %d\n", err);
809 return err;
810 }
811
812 if (asus->gpu_mux_dev) {
813 result = asus_wmi_get_devstate_simple(asus, dev_id: asus->gpu_mux_dev);
814 if (result < 0) {
815 /* An error here may signal greater failure of GPU handling */
816 pr_warn("Failed to get gpu mux status: %d\n", result);
817 return result;
818 }
819 if (!result && enable) {
820 err = -ENODEV;
821 pr_warn("Can not enable eGPU when the MUX is in dGPU mode: %d\n", err);
822 return err;
823 }
824 }
825
826 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, ctrl_param: enable, retval: &result);
827 if (err) {
828 pr_warn("Failed to set egpu state: %d\n", err);
829 return err;
830 }
831
832 if (result > 1) {
833 pr_warn("Failed to set egpu state (retval): 0x%x\n", result);
834 return -EIO;
835 }
836
837 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "egpu_enable");
838
839 return count;
840}
841static DEVICE_ATTR_RW(egpu_enable);
842
843/* Is eGPU connected? *********************************************************/
844static ssize_t egpu_connected_show(struct device *dev,
845 struct device_attribute *attr, char *buf)
846{
847 struct asus_wmi *asus = dev_get_drvdata(dev);
848 int result;
849
850 result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_EGPU_CONNECTED);
851 if (result < 0)
852 return result;
853
854 return sysfs_emit(buf, fmt: "%d\n", result);
855}
856
857static DEVICE_ATTR_RO(egpu_connected);
858
859/* gpu mux switch *************************************************************/
860static ssize_t gpu_mux_mode_show(struct device *dev,
861 struct device_attribute *attr, char *buf)
862{
863 struct asus_wmi *asus = dev_get_drvdata(dev);
864 int result;
865
866 result = asus_wmi_get_devstate_simple(asus, dev_id: asus->gpu_mux_dev);
867 if (result < 0)
868 return result;
869
870 return sysfs_emit(buf, fmt: "%d\n", result);
871}
872
873static ssize_t gpu_mux_mode_store(struct device *dev,
874 struct device_attribute *attr,
875 const char *buf, size_t count)
876{
877 struct asus_wmi *asus = dev_get_drvdata(dev);
878 int result, err;
879 u32 optimus;
880
881 err = kstrtou32(s: buf, base: 10, res: &optimus);
882 if (err)
883 return err;
884
885 if (optimus > 1)
886 return -EINVAL;
887
888 if (asus->dgpu_disable_available) {
889 result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_DGPU);
890 if (result < 0)
891 /* An error here may signal greater failure of GPU handling */
892 return result;
893 if (result && !optimus) {
894 err = -ENODEV;
895 pr_warn("Can not switch MUX to dGPU mode when dGPU is disabled: %d\n", err);
896 return err;
897 }
898 }
899
900 if (asus->egpu_enable_available) {
901 result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_EGPU);
902 if (result < 0)
903 /* An error here may signal greater failure of GPU handling */
904 return result;
905 if (result && !optimus) {
906 err = -ENODEV;
907 pr_warn("Can not switch MUX to dGPU mode when eGPU is enabled: %d\n", err);
908 return err;
909 }
910 }
911
912 err = asus_wmi_set_devstate(dev_id: asus->gpu_mux_dev, ctrl_param: optimus, retval: &result);
913 if (err) {
914 dev_err(dev, "Failed to set GPU MUX mode: %d\n", err);
915 return err;
916 }
917 /* !1 is considered a fail by ASUS */
918 if (result != 1) {
919 dev_warn(dev, "Failed to set GPU MUX mode (result): 0x%x\n", result);
920 return -EIO;
921 }
922
923 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "gpu_mux_mode");
924
925 return count;
926}
927static DEVICE_ATTR_RW(gpu_mux_mode);
928
929/* TUF Laptop Keyboard RGB Modes **********************************************/
930static ssize_t kbd_rgb_mode_store(struct device *dev,
931 struct device_attribute *attr,
932 const char *buf, size_t count)
933{
934 u32 cmd, mode, r, g, b, speed;
935 struct led_classdev *led;
936 struct asus_wmi *asus;
937 int err;
938
939 led = dev_get_drvdata(dev);
940 asus = container_of(led, struct asus_wmi, kbd_led);
941
942 if (sscanf(buf, "%d %d %d %d %d %d", &cmd, &mode, &r, &g, &b, &speed) != 6)
943 return -EINVAL;
944
945 /* B3 is set and B4 is save to BIOS */
946 switch (cmd) {
947 case 0:
948 cmd = 0xb3;
949 break;
950 case 1:
951 cmd = 0xb4;
952 break;
953 default:
954 return -EINVAL;
955 }
956
957 /* These are the known usable modes across all TUF/ROG */
958 if (mode >= 12 || mode == 9)
959 mode = 10;
960
961 switch (speed) {
962 case 0:
963 speed = 0xe1;
964 break;
965 case 1:
966 speed = 0xeb;
967 break;
968 case 2:
969 speed = 0xf5;
970 break;
971 default:
972 speed = 0xeb;
973 }
974
975 err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS, arg0: asus->kbd_rgb_dev,
976 arg1: cmd | (mode << 8) | (r << 16) | (g << 24), arg2: b | (speed << 8), NULL);
977 if (err)
978 return err;
979
980 return count;
981}
982static DEVICE_ATTR_WO(kbd_rgb_mode);
983
984static DEVICE_STRING_ATTR_RO(kbd_rgb_mode_index, 0444,
985 "cmd mode red green blue speed");
986
987static struct attribute *kbd_rgb_mode_attrs[] = {
988 &dev_attr_kbd_rgb_mode.attr,
989 &dev_attr_kbd_rgb_mode_index.attr.attr,
990 NULL,
991};
992
993static const struct attribute_group kbd_rgb_mode_group = {
994 .attrs = kbd_rgb_mode_attrs,
995};
996
997/* TUF Laptop Keyboard RGB State **********************************************/
998static ssize_t kbd_rgb_state_store(struct device *dev,
999 struct device_attribute *attr,
1000 const char *buf, size_t count)
1001{
1002 u32 flags, cmd, boot, awake, sleep, keyboard;
1003 int err;
1004
1005 if (sscanf(buf, "%d %d %d %d %d", &cmd, &boot, &awake, &sleep, &keyboard) != 5)
1006 return -EINVAL;
1007
1008 if (cmd)
1009 cmd = BIT(2);
1010
1011 flags = 0;
1012 if (boot)
1013 flags |= BIT(1);
1014 if (awake)
1015 flags |= BIT(3);
1016 if (sleep)
1017 flags |= BIT(5);
1018 if (keyboard)
1019 flags |= BIT(7);
1020
1021 /* 0xbd is the required default arg0 for the method. Nothing happens otherwise */
1022 err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS,
1023 ASUS_WMI_DEVID_TUF_RGB_STATE, arg1: 0xbd | cmd << 8 | (flags << 16), arg2: 0, NULL);
1024 if (err)
1025 return err;
1026
1027 return count;
1028}
1029static DEVICE_ATTR_WO(kbd_rgb_state);
1030
1031static DEVICE_STRING_ATTR_RO(kbd_rgb_state_index, 0444,
1032 "cmd boot awake sleep keyboard");
1033
1034static struct attribute *kbd_rgb_state_attrs[] = {
1035 &dev_attr_kbd_rgb_state.attr,
1036 &dev_attr_kbd_rgb_state_index.attr.attr,
1037 NULL,
1038};
1039
1040static const struct attribute_group kbd_rgb_state_group = {
1041 .attrs = kbd_rgb_state_attrs,
1042};
1043
1044static const struct attribute_group *kbd_rgb_mode_groups[] = {
1045 NULL,
1046 NULL,
1047 NULL,
1048};
1049
1050/* Tunable: PPT: Intel=PL1, AMD=SPPT *****************************************/
1051static ssize_t ppt_pl2_sppt_store(struct device *dev,
1052 struct device_attribute *attr,
1053 const char *buf, size_t count)
1054{
1055 struct asus_wmi *asus = dev_get_drvdata(dev);
1056 int result, err;
1057 u32 value;
1058
1059 result = kstrtou32(s: buf, base: 10, res: &value);
1060 if (result)
1061 return result;
1062
1063 if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX)
1064 return -EINVAL;
1065
1066 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_PL2_SPPT, ctrl_param: value, retval: &result);
1067 if (err) {
1068 pr_warn("Failed to set ppt_pl2_sppt: %d\n", err);
1069 return err;
1070 }
1071
1072 if (result > 1) {
1073 pr_warn("Failed to set ppt_pl2_sppt (result): 0x%x\n", result);
1074 return -EIO;
1075 }
1076
1077 asus->ppt_pl2_sppt = value;
1078 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "ppt_pl2_sppt");
1079
1080 return count;
1081}
1082
1083static ssize_t ppt_pl2_sppt_show(struct device *dev,
1084 struct device_attribute *attr,
1085 char *buf)
1086{
1087 struct asus_wmi *asus = dev_get_drvdata(dev);
1088
1089 return sysfs_emit(buf, fmt: "%u\n", asus->ppt_pl2_sppt);
1090}
1091static DEVICE_ATTR_RW(ppt_pl2_sppt);
1092
1093/* Tunable: PPT, Intel=PL1, AMD=SPL ******************************************/
1094static ssize_t ppt_pl1_spl_store(struct device *dev,
1095 struct device_attribute *attr,
1096 const char *buf, size_t count)
1097{
1098 struct asus_wmi *asus = dev_get_drvdata(dev);
1099 int result, err;
1100 u32 value;
1101
1102 result = kstrtou32(s: buf, base: 10, res: &value);
1103 if (result)
1104 return result;
1105
1106 if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX)
1107 return -EINVAL;
1108
1109 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_PL1_SPL, ctrl_param: value, retval: &result);
1110 if (err) {
1111 pr_warn("Failed to set ppt_pl1_spl: %d\n", err);
1112 return err;
1113 }
1114
1115 if (result > 1) {
1116 pr_warn("Failed to set ppt_pl1_spl (result): 0x%x\n", result);
1117 return -EIO;
1118 }
1119
1120 asus->ppt_pl1_spl = value;
1121 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "ppt_pl1_spl");
1122
1123 return count;
1124}
1125static ssize_t ppt_pl1_spl_show(struct device *dev,
1126 struct device_attribute *attr,
1127 char *buf)
1128{
1129 struct asus_wmi *asus = dev_get_drvdata(dev);
1130
1131 return sysfs_emit(buf, fmt: "%u\n", asus->ppt_pl1_spl);
1132}
1133static DEVICE_ATTR_RW(ppt_pl1_spl);
1134
1135/* Tunable: PPT APU FPPT ******************************************************/
1136static ssize_t ppt_fppt_store(struct device *dev,
1137 struct device_attribute *attr,
1138 const char *buf, size_t count)
1139{
1140 struct asus_wmi *asus = dev_get_drvdata(dev);
1141 int result, err;
1142 u32 value;
1143
1144 result = kstrtou32(s: buf, base: 10, res: &value);
1145 if (result)
1146 return result;
1147
1148 if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX)
1149 return -EINVAL;
1150
1151 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_FPPT, ctrl_param: value, retval: &result);
1152 if (err) {
1153 pr_warn("Failed to set ppt_fppt: %d\n", err);
1154 return err;
1155 }
1156
1157 if (result > 1) {
1158 pr_warn("Failed to set ppt_fppt (result): 0x%x\n", result);
1159 return -EIO;
1160 }
1161
1162 asus->ppt_fppt = value;
1163 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "ppt_fpu_sppt");
1164
1165 return count;
1166}
1167
1168static ssize_t ppt_fppt_show(struct device *dev,
1169 struct device_attribute *attr,
1170 char *buf)
1171{
1172 struct asus_wmi *asus = dev_get_drvdata(dev);
1173
1174 return sysfs_emit(buf, fmt: "%u\n", asus->ppt_fppt);
1175}
1176static DEVICE_ATTR_RW(ppt_fppt);
1177
1178/* Tunable: PPT APU SPPT *****************************************************/
1179static ssize_t ppt_apu_sppt_store(struct device *dev,
1180 struct device_attribute *attr,
1181 const char *buf, size_t count)
1182{
1183 struct asus_wmi *asus = dev_get_drvdata(dev);
1184 int result, err;
1185 u32 value;
1186
1187 result = kstrtou32(s: buf, base: 10, res: &value);
1188 if (result)
1189 return result;
1190
1191 if (value < PPT_CPU_MIN || value > PPT_CPU_MAX)
1192 return -EINVAL;
1193
1194 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_APU_SPPT, ctrl_param: value, retval: &result);
1195 if (err) {
1196 pr_warn("Failed to set ppt_apu_sppt: %d\n", err);
1197 return err;
1198 }
1199
1200 if (result > 1) {
1201 pr_warn("Failed to set ppt_apu_sppt (result): 0x%x\n", result);
1202 return -EIO;
1203 }
1204
1205 asus->ppt_apu_sppt = value;
1206 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "ppt_apu_sppt");
1207
1208 return count;
1209}
1210
1211static ssize_t ppt_apu_sppt_show(struct device *dev,
1212 struct device_attribute *attr,
1213 char *buf)
1214{
1215 struct asus_wmi *asus = dev_get_drvdata(dev);
1216
1217 return sysfs_emit(buf, fmt: "%u\n", asus->ppt_apu_sppt);
1218}
1219static DEVICE_ATTR_RW(ppt_apu_sppt);
1220
1221/* Tunable: PPT platform SPPT ************************************************/
1222static ssize_t ppt_platform_sppt_store(struct device *dev,
1223 struct device_attribute *attr,
1224 const char *buf, size_t count)
1225{
1226 struct asus_wmi *asus = dev_get_drvdata(dev);
1227 int result, err;
1228 u32 value;
1229
1230 result = kstrtou32(s: buf, base: 10, res: &value);
1231 if (result)
1232 return result;
1233
1234 if (value < PPT_CPU_MIN || value > PPT_CPU_MAX)
1235 return -EINVAL;
1236
1237 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_PLAT_SPPT, ctrl_param: value, retval: &result);
1238 if (err) {
1239 pr_warn("Failed to set ppt_platform_sppt: %d\n", err);
1240 return err;
1241 }
1242
1243 if (result > 1) {
1244 pr_warn("Failed to set ppt_platform_sppt (result): 0x%x\n", result);
1245 return -EIO;
1246 }
1247
1248 asus->ppt_platform_sppt = value;
1249 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "ppt_platform_sppt");
1250
1251 return count;
1252}
1253
1254static ssize_t ppt_platform_sppt_show(struct device *dev,
1255 struct device_attribute *attr,
1256 char *buf)
1257{
1258 struct asus_wmi *asus = dev_get_drvdata(dev);
1259
1260 return sysfs_emit(buf, fmt: "%u\n", asus->ppt_platform_sppt);
1261}
1262static DEVICE_ATTR_RW(ppt_platform_sppt);
1263
1264/* Tunable: NVIDIA dynamic boost *********************************************/
1265static ssize_t nv_dynamic_boost_store(struct device *dev,
1266 struct device_attribute *attr,
1267 const char *buf, size_t count)
1268{
1269 struct asus_wmi *asus = dev_get_drvdata(dev);
1270 int result, err;
1271 u32 value;
1272
1273 result = kstrtou32(s: buf, base: 10, res: &value);
1274 if (result)
1275 return result;
1276
1277 if (value < NVIDIA_BOOST_MIN || value > NVIDIA_BOOST_MAX)
1278 return -EINVAL;
1279
1280 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_NV_DYN_BOOST, ctrl_param: value, retval: &result);
1281 if (err) {
1282 pr_warn("Failed to set nv_dynamic_boost: %d\n", err);
1283 return err;
1284 }
1285
1286 if (result > 1) {
1287 pr_warn("Failed to set nv_dynamic_boost (result): 0x%x\n", result);
1288 return -EIO;
1289 }
1290
1291 asus->nv_dynamic_boost = value;
1292 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "nv_dynamic_boost");
1293
1294 return count;
1295}
1296
1297static ssize_t nv_dynamic_boost_show(struct device *dev,
1298 struct device_attribute *attr,
1299 char *buf)
1300{
1301 struct asus_wmi *asus = dev_get_drvdata(dev);
1302
1303 return sysfs_emit(buf, fmt: "%u\n", asus->nv_dynamic_boost);
1304}
1305static DEVICE_ATTR_RW(nv_dynamic_boost);
1306
1307/* Tunable: NVIDIA temperature target ****************************************/
1308static ssize_t nv_temp_target_store(struct device *dev,
1309 struct device_attribute *attr,
1310 const char *buf, size_t count)
1311{
1312 struct asus_wmi *asus = dev_get_drvdata(dev);
1313 int result, err;
1314 u32 value;
1315
1316 result = kstrtou32(s: buf, base: 10, res: &value);
1317 if (result)
1318 return result;
1319
1320 if (value < NVIDIA_TEMP_MIN || value > NVIDIA_TEMP_MAX)
1321 return -EINVAL;
1322
1323 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_NV_THERM_TARGET, ctrl_param: value, retval: &result);
1324 if (err) {
1325 pr_warn("Failed to set nv_temp_target: %d\n", err);
1326 return err;
1327 }
1328
1329 if (result > 1) {
1330 pr_warn("Failed to set nv_temp_target (result): 0x%x\n", result);
1331 return -EIO;
1332 }
1333
1334 asus->nv_temp_target = value;
1335 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "nv_temp_target");
1336
1337 return count;
1338}
1339
1340static ssize_t nv_temp_target_show(struct device *dev,
1341 struct device_attribute *attr,
1342 char *buf)
1343{
1344 struct asus_wmi *asus = dev_get_drvdata(dev);
1345
1346 return sysfs_emit(buf, fmt: "%u\n", asus->nv_temp_target);
1347}
1348static DEVICE_ATTR_RW(nv_temp_target);
1349
1350/* Ally MCU Powersave ********************************************************/
1351
1352/*
1353 * The HID driver needs to check MCU version and set this to false if the MCU FW
1354 * version is >= the minimum requirements. New FW do not need the hacks.
1355 */
1356void set_ally_mcu_hack(enum asus_ally_mcu_hack status)
1357{
1358 use_ally_mcu_hack = status;
1359 pr_debug("%s Ally MCU suspend quirk\n",
1360 status == ASUS_WMI_ALLY_MCU_HACK_ENABLED ? "Enabled" : "Disabled");
1361}
1362EXPORT_SYMBOL_NS_GPL(set_ally_mcu_hack, "ASUS_WMI");
1363
1364/*
1365 * mcu_powersave should be enabled always, as it is fixed in MCU FW versions:
1366 * - v313 for Ally X
1367 * - v319 for Ally 1
1368 * The HID driver checks MCU versions and so should set this if requirements match
1369 */
1370void set_ally_mcu_powersave(bool enabled)
1371{
1372 int result, err;
1373
1374 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MCU_POWERSAVE, ctrl_param: enabled, retval: &result);
1375 if (err) {
1376 pr_warn("Failed to set MCU powersave: %d\n", err);
1377 return;
1378 }
1379 if (result > 1) {
1380 pr_warn("Failed to set MCU powersave (result): 0x%x\n", result);
1381 return;
1382 }
1383
1384 pr_debug("%s MCU Powersave\n",
1385 enabled ? "Enabled" : "Disabled");
1386}
1387EXPORT_SYMBOL_NS_GPL(set_ally_mcu_powersave, "ASUS_WMI");
1388
1389static ssize_t mcu_powersave_show(struct device *dev,
1390 struct device_attribute *attr, char *buf)
1391{
1392 struct asus_wmi *asus = dev_get_drvdata(dev);
1393 int result;
1394
1395 result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_MCU_POWERSAVE);
1396 if (result < 0)
1397 return result;
1398
1399 return sysfs_emit(buf, fmt: "%d\n", result);
1400}
1401
1402static ssize_t mcu_powersave_store(struct device *dev,
1403 struct device_attribute *attr,
1404 const char *buf, size_t count)
1405{
1406 int result, err;
1407 u32 enable;
1408
1409 struct asus_wmi *asus = dev_get_drvdata(dev);
1410
1411 result = kstrtou32(s: buf, base: 10, res: &enable);
1412 if (result)
1413 return result;
1414
1415 if (enable > 1)
1416 return -EINVAL;
1417
1418 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MCU_POWERSAVE, ctrl_param: enable, retval: &result);
1419 if (err) {
1420 pr_warn("Failed to set MCU powersave: %d\n", err);
1421 return err;
1422 }
1423
1424 if (result > 1) {
1425 pr_warn("Failed to set MCU powersave (result): 0x%x\n", result);
1426 return -EIO;
1427 }
1428
1429 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "mcu_powersave");
1430
1431 return count;
1432}
1433static DEVICE_ATTR_RW(mcu_powersave);
1434
1435/* Battery ********************************************************************/
1436
1437/* The battery maximum charging percentage */
1438static int charge_end_threshold;
1439
1440static ssize_t charge_control_end_threshold_store(struct device *dev,
1441 struct device_attribute *attr,
1442 const char *buf, size_t count)
1443{
1444 int value, ret, rv;
1445
1446 ret = kstrtouint(s: buf, base: 10, res: &value);
1447 if (ret)
1448 return ret;
1449
1450 if (value < 0 || value > 100)
1451 return -EINVAL;
1452
1453 ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_RSOC, ctrl_param: value, retval: &rv);
1454 if (ret)
1455 return ret;
1456
1457 if (rv != 1)
1458 return -EIO;
1459
1460 /* There isn't any method in the DSDT to read the threshold, so we
1461 * save the threshold.
1462 */
1463 charge_end_threshold = value;
1464 return count;
1465}
1466
1467static ssize_t charge_control_end_threshold_show(struct device *device,
1468 struct device_attribute *attr,
1469 char *buf)
1470{
1471 return sysfs_emit(buf, fmt: "%d\n", charge_end_threshold);
1472}
1473
1474static DEVICE_ATTR_RW(charge_control_end_threshold);
1475
1476static int asus_wmi_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook)
1477{
1478 /* The WMI method does not provide a way to specific a battery, so we
1479 * just assume it is the first battery.
1480 * Note: On some newer ASUS laptops (Zenbook UM431DA), the primary/first
1481 * battery is named BATT.
1482 */
1483 if (strcmp(battery->desc->name, "BAT0") != 0 &&
1484 strcmp(battery->desc->name, "BAT1") != 0 &&
1485 strcmp(battery->desc->name, "BATC") != 0 &&
1486 strcmp(battery->desc->name, "BATT") != 0)
1487 return -ENODEV;
1488
1489 if (device_create_file(device: &battery->dev,
1490 entry: &dev_attr_charge_control_end_threshold))
1491 return -ENODEV;
1492
1493 /* The charge threshold is only reset when the system is power cycled,
1494 * and we can't get the current threshold so let set it to 100% when
1495 * a battery is added.
1496 */
1497 asus_wmi_set_devstate(ASUS_WMI_DEVID_RSOC, ctrl_param: 100, NULL);
1498 charge_end_threshold = 100;
1499
1500 return 0;
1501}
1502
1503static int asus_wmi_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook)
1504{
1505 device_remove_file(dev: &battery->dev,
1506 attr: &dev_attr_charge_control_end_threshold);
1507 return 0;
1508}
1509
1510static struct acpi_battery_hook battery_hook = {
1511 .add_battery = asus_wmi_battery_add,
1512 .remove_battery = asus_wmi_battery_remove,
1513 .name = "ASUS Battery Extension",
1514};
1515
1516static void asus_wmi_battery_init(struct asus_wmi *asus)
1517{
1518 asus->battery_rsoc_available = false;
1519 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_RSOC)) {
1520 asus->battery_rsoc_available = true;
1521 battery_hook_register(hook: &battery_hook);
1522 }
1523}
1524
1525static void asus_wmi_battery_exit(struct asus_wmi *asus)
1526{
1527 if (asus->battery_rsoc_available)
1528 battery_hook_unregister(hook: &battery_hook);
1529}
1530
1531/* LEDs ***********************************************************************/
1532
1533/*
1534 * These functions actually update the LED's, and are called from a
1535 * workqueue. By doing this as separate work rather than when the LED
1536 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
1537 * potentially bad time, such as a timer interrupt.
1538 */
1539static void tpd_led_update(struct work_struct *work)
1540{
1541 int ctrl_param;
1542 struct asus_wmi *asus;
1543
1544 asus = container_of(work, struct asus_wmi, tpd_led_work);
1545
1546 ctrl_param = asus->tpd_led_wk;
1547 asus_wmi_set_devstate(ASUS_WMI_DEVID_TOUCHPAD_LED, ctrl_param, NULL);
1548}
1549
1550static void tpd_led_set(struct led_classdev *led_cdev,
1551 enum led_brightness value)
1552{
1553 struct asus_wmi *asus;
1554
1555 asus = container_of(led_cdev, struct asus_wmi, tpd_led);
1556
1557 asus->tpd_led_wk = !!value;
1558 queue_work(wq: asus->led_workqueue, work: &asus->tpd_led_work);
1559}
1560
1561static int read_tpd_led_state(struct asus_wmi *asus)
1562{
1563 return asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_TOUCHPAD_LED);
1564}
1565
1566static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
1567{
1568 struct asus_wmi *asus;
1569
1570 asus = container_of(led_cdev, struct asus_wmi, tpd_led);
1571
1572 return read_tpd_led_state(asus);
1573}
1574
1575static void kbd_led_update(struct asus_wmi *asus)
1576{
1577 int ctrl_param = 0;
1578
1579 ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
1580 asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
1581}
1582
1583static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
1584{
1585 int retval;
1586
1587 /*
1588 * bits 0-2: level
1589 * bit 7: light on/off
1590 * bit 8-10: environment (0: dark, 1: normal, 2: light)
1591 * bit 17: status unknown
1592 */
1593 retval = asus_wmi_get_devstate_bits(asus, ASUS_WMI_DEVID_KBD_BACKLIGHT,
1594 mask: 0xFFFF);
1595
1596 /* Unknown status is considered as off */
1597 if (retval == 0x8000)
1598 retval = 0;
1599
1600 if (retval < 0)
1601 return retval;
1602
1603 if (level)
1604 *level = retval & 0x7F;
1605 if (env)
1606 *env = (retval >> 8) & 0x7F;
1607 return 0;
1608}
1609
1610static void do_kbd_led_set(struct led_classdev *led_cdev, int value)
1611{
1612 struct asus_wmi *asus;
1613 int max_level;
1614
1615 asus = container_of(led_cdev, struct asus_wmi, kbd_led);
1616 max_level = asus->kbd_led.max_brightness;
1617
1618 asus->kbd_led_wk = clamp_val(value, 0, max_level);
1619 kbd_led_update(asus);
1620}
1621
1622static void kbd_led_set(struct led_classdev *led_cdev,
1623 enum led_brightness value)
1624{
1625 /* Prevent disabling keyboard backlight on module unregister */
1626 if (led_cdev->flags & LED_UNREGISTERING)
1627 return;
1628
1629 do_kbd_led_set(led_cdev, value);
1630}
1631
1632static void kbd_led_set_by_kbd(struct asus_wmi *asus, enum led_brightness value)
1633{
1634 struct led_classdev *led_cdev = &asus->kbd_led;
1635
1636 do_kbd_led_set(led_cdev, value);
1637 led_classdev_notify_brightness_hw_changed(led_cdev, brightness: asus->kbd_led_wk);
1638}
1639
1640static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
1641{
1642 struct asus_wmi *asus;
1643 int retval, value;
1644
1645 asus = container_of(led_cdev, struct asus_wmi, kbd_led);
1646
1647 retval = kbd_led_read(asus, level: &value, NULL);
1648 if (retval < 0)
1649 return retval;
1650
1651 return value;
1652}
1653
1654static int wlan_led_unknown_state(struct asus_wmi *asus)
1655{
1656 u32 result;
1657
1658 asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, retval: &result);
1659
1660 return result & ASUS_WMI_DSTS_UNKNOWN_BIT;
1661}
1662
1663static void wlan_led_update(struct work_struct *work)
1664{
1665 int ctrl_param;
1666 struct asus_wmi *asus;
1667
1668 asus = container_of(work, struct asus_wmi, wlan_led_work);
1669
1670 ctrl_param = asus->wlan_led_wk;
1671 asus_wmi_set_devstate(ASUS_WMI_DEVID_WIRELESS_LED, ctrl_param, NULL);
1672}
1673
1674static void wlan_led_set(struct led_classdev *led_cdev,
1675 enum led_brightness value)
1676{
1677 struct asus_wmi *asus;
1678
1679 asus = container_of(led_cdev, struct asus_wmi, wlan_led);
1680
1681 asus->wlan_led_wk = !!value;
1682 queue_work(wq: asus->led_workqueue, work: &asus->wlan_led_work);
1683}
1684
1685static enum led_brightness wlan_led_get(struct led_classdev *led_cdev)
1686{
1687 struct asus_wmi *asus;
1688 u32 result;
1689
1690 asus = container_of(led_cdev, struct asus_wmi, wlan_led);
1691 asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, retval: &result);
1692
1693 return result & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
1694}
1695
1696static void lightbar_led_update(struct work_struct *work)
1697{
1698 struct asus_wmi *asus;
1699 int ctrl_param;
1700
1701 asus = container_of(work, struct asus_wmi, lightbar_led_work);
1702
1703 ctrl_param = asus->lightbar_led_wk;
1704 asus_wmi_set_devstate(ASUS_WMI_DEVID_LIGHTBAR, ctrl_param, NULL);
1705}
1706
1707static void lightbar_led_set(struct led_classdev *led_cdev,
1708 enum led_brightness value)
1709{
1710 struct asus_wmi *asus;
1711
1712 asus = container_of(led_cdev, struct asus_wmi, lightbar_led);
1713
1714 asus->lightbar_led_wk = !!value;
1715 queue_work(wq: asus->led_workqueue, work: &asus->lightbar_led_work);
1716}
1717
1718static enum led_brightness lightbar_led_get(struct led_classdev *led_cdev)
1719{
1720 struct asus_wmi *asus;
1721 u32 result;
1722
1723 asus = container_of(led_cdev, struct asus_wmi, lightbar_led);
1724 asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_LIGHTBAR, retval: &result);
1725
1726 return result & ASUS_WMI_DSTS_LIGHTBAR_MASK;
1727}
1728
1729static int micmute_led_set(struct led_classdev *led_cdev,
1730 enum led_brightness brightness)
1731{
1732 int state = brightness != LED_OFF;
1733 int err;
1734
1735 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MICMUTE_LED, ctrl_param: state, NULL);
1736 return err < 0 ? err : 0;
1737}
1738
1739static enum led_brightness camera_led_get(struct led_classdev *led_cdev)
1740{
1741 struct asus_wmi *asus;
1742 u32 result;
1743
1744 asus = container_of(led_cdev, struct asus_wmi, camera_led);
1745 asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_CAMERA_LED, retval: &result);
1746
1747 return result & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
1748}
1749
1750static int camera_led_set(struct led_classdev *led_cdev,
1751 enum led_brightness brightness)
1752{
1753 int state = brightness != LED_OFF;
1754 int err;
1755
1756 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_CAMERA_LED, ctrl_param: state, NULL);
1757 return err < 0 ? err : 0;
1758}
1759
1760static void asus_wmi_led_exit(struct asus_wmi *asus)
1761{
1762 led_classdev_unregister(led_cdev: &asus->kbd_led);
1763 led_classdev_unregister(led_cdev: &asus->tpd_led);
1764 led_classdev_unregister(led_cdev: &asus->wlan_led);
1765 led_classdev_unregister(led_cdev: &asus->lightbar_led);
1766 led_classdev_unregister(led_cdev: &asus->micmute_led);
1767 led_classdev_unregister(led_cdev: &asus->camera_led);
1768
1769 if (asus->led_workqueue)
1770 destroy_workqueue(wq: asus->led_workqueue);
1771}
1772
1773static int asus_wmi_led_init(struct asus_wmi *asus)
1774{
1775 int rv = 0, num_rgb_groups = 0, led_val;
1776
1777 if (asus->kbd_rgb_dev)
1778 kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_mode_group;
1779 if (asus->kbd_rgb_state_available)
1780 kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_state_group;
1781
1782 asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
1783 if (!asus->led_workqueue)
1784 return -ENOMEM;
1785
1786 if (read_tpd_led_state(asus) >= 0) {
1787 INIT_WORK(&asus->tpd_led_work, tpd_led_update);
1788
1789 asus->tpd_led.name = "asus::touchpad";
1790 asus->tpd_led.brightness_set = tpd_led_set;
1791 asus->tpd_led.brightness_get = tpd_led_get;
1792 asus->tpd_led.max_brightness = 1;
1793
1794 rv = led_classdev_register(parent: &asus->platform_device->dev,
1795 led_cdev: &asus->tpd_led);
1796 if (rv)
1797 goto error;
1798 }
1799
1800 if (!kbd_led_read(asus, level: &led_val, NULL) && !dmi_check_system(list: asus_use_hid_led_dmi_ids)) {
1801 pr_info("using asus-wmi for asus::kbd_backlight\n");
1802 asus->kbd_led_wk = led_val;
1803 asus->kbd_led.name = "asus::kbd_backlight";
1804 asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
1805 asus->kbd_led.brightness_set = kbd_led_set;
1806 asus->kbd_led.brightness_get = kbd_led_get;
1807 asus->kbd_led.max_brightness = 3;
1808
1809 if (num_rgb_groups != 0)
1810 asus->kbd_led.groups = kbd_rgb_mode_groups;
1811
1812 rv = led_classdev_register(parent: &asus->platform_device->dev,
1813 led_cdev: &asus->kbd_led);
1814 if (rv)
1815 goto error;
1816 }
1817
1818 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_WIRELESS_LED)
1819 && (asus->driver->quirks->wapf > 0)) {
1820 INIT_WORK(&asus->wlan_led_work, wlan_led_update);
1821
1822 asus->wlan_led.name = "asus::wlan";
1823 asus->wlan_led.brightness_set = wlan_led_set;
1824 if (!wlan_led_unknown_state(asus))
1825 asus->wlan_led.brightness_get = wlan_led_get;
1826 asus->wlan_led.flags = LED_CORE_SUSPENDRESUME;
1827 asus->wlan_led.max_brightness = 1;
1828 asus->wlan_led.default_trigger = "asus-wlan";
1829
1830 rv = led_classdev_register(parent: &asus->platform_device->dev,
1831 led_cdev: &asus->wlan_led);
1832 if (rv)
1833 goto error;
1834 }
1835
1836 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_LIGHTBAR)) {
1837 INIT_WORK(&asus->lightbar_led_work, lightbar_led_update);
1838
1839 asus->lightbar_led.name = "asus::lightbar";
1840 asus->lightbar_led.brightness_set = lightbar_led_set;
1841 asus->lightbar_led.brightness_get = lightbar_led_get;
1842 asus->lightbar_led.max_brightness = 1;
1843
1844 rv = led_classdev_register(parent: &asus->platform_device->dev,
1845 led_cdev: &asus->lightbar_led);
1846 }
1847
1848 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MICMUTE_LED)) {
1849 asus->micmute_led.name = "platform::micmute";
1850 asus->micmute_led.max_brightness = 1;
1851 asus->micmute_led.brightness_set_blocking = micmute_led_set;
1852 asus->micmute_led.default_trigger = "audio-micmute";
1853
1854 rv = led_classdev_register(parent: &asus->platform_device->dev,
1855 led_cdev: &asus->micmute_led);
1856 if (rv)
1857 goto error;
1858 }
1859
1860 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CAMERA_LED)) {
1861 asus->camera_led.name = "asus::camera";
1862 asus->camera_led.max_brightness = 1;
1863 asus->camera_led.brightness_get = camera_led_get;
1864 asus->camera_led.brightness_set_blocking = camera_led_set;
1865
1866 rv = led_classdev_register(parent: &asus->platform_device->dev,
1867 led_cdev: &asus->camera_led);
1868 if (rv)
1869 goto error;
1870 }
1871
1872 if (asus->oobe_state_available) {
1873 /*
1874 * Disable OOBE state, so that e.g. the keyboard backlight
1875 * works.
1876 */
1877 rv = asus_wmi_set_devstate(ASUS_WMI_DEVID_OOBE, ctrl_param: 1, NULL);
1878 if (rv)
1879 goto error;
1880 }
1881
1882error:
1883 if (rv)
1884 asus_wmi_led_exit(asus);
1885
1886 return rv;
1887}
1888
1889/* RF *************************************************************************/
1890
1891/*
1892 * PCI hotplug (for wlan rfkill)
1893 */
1894static bool asus_wlan_rfkill_blocked(struct asus_wmi *asus)
1895{
1896 int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
1897
1898 if (result < 0)
1899 return false;
1900 return !result;
1901}
1902
1903static void asus_rfkill_hotplug(struct asus_wmi *asus)
1904{
1905 struct pci_dev *dev;
1906 struct pci_bus *bus;
1907 bool blocked;
1908 bool absent;
1909 u32 l;
1910
1911 mutex_lock(&asus->wmi_lock);
1912 blocked = asus_wlan_rfkill_blocked(asus);
1913 mutex_unlock(lock: &asus->wmi_lock);
1914
1915 mutex_lock(&asus->hotplug_lock);
1916 pci_lock_rescan_remove();
1917
1918 if (asus->wlan.rfkill)
1919 rfkill_set_sw_state(rfkill: asus->wlan.rfkill, blocked);
1920
1921 if (asus->hotplug_slot.ops) {
1922 bus = pci_find_bus(domain: 0, busnr: 1);
1923 if (!bus) {
1924 pr_warn("Unable to find PCI bus 1?\n");
1925 goto out_unlock;
1926 }
1927
1928 if (pci_bus_read_config_dword(bus, devfn: 0, PCI_VENDOR_ID, val: &l)) {
1929 pr_err("Unable to read PCI config space?\n");
1930 goto out_unlock;
1931 }
1932 absent = (l == 0xffffffff);
1933
1934 if (blocked != absent) {
1935 pr_warn("BIOS says wireless lan is %s, but the pci device is %s\n",
1936 blocked ? "blocked" : "unblocked",
1937 absent ? "absent" : "present");
1938 pr_warn("skipped wireless hotplug as probably inappropriate for this model\n");
1939 goto out_unlock;
1940 }
1941
1942 if (!blocked) {
1943 dev = pci_get_slot(bus, devfn: 0);
1944 if (dev) {
1945 /* Device already present */
1946 pci_dev_put(dev);
1947 goto out_unlock;
1948 }
1949 dev = pci_scan_single_device(bus, devfn: 0);
1950 if (dev) {
1951 pci_bus_assign_resources(bus);
1952 pci_bus_add_device(dev);
1953 }
1954 } else {
1955 dev = pci_get_slot(bus, devfn: 0);
1956 if (dev) {
1957 pci_stop_and_remove_bus_device(dev);
1958 pci_dev_put(dev);
1959 }
1960 }
1961 }
1962
1963out_unlock:
1964 pci_unlock_rescan_remove();
1965 mutex_unlock(lock: &asus->hotplug_lock);
1966}
1967
1968static void asus_rfkill_notify(acpi_handle handle, u32 event, void *data)
1969{
1970 struct asus_wmi *asus = data;
1971
1972 if (event != ACPI_NOTIFY_BUS_CHECK)
1973 return;
1974
1975 /*
1976 * We can't call directly asus_rfkill_hotplug because most
1977 * of the time WMBC is still being executed and not reetrant.
1978 * There is currently no way to tell ACPICA that we want this
1979 * method to be serialized, we schedule a asus_rfkill_hotplug
1980 * call later, in a safer context.
1981 */
1982 queue_work(wq: asus->hotplug_workqueue, work: &asus->hotplug_work);
1983}
1984
1985static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node)
1986{
1987 acpi_status status;
1988 acpi_handle handle;
1989
1990 status = acpi_get_handle(NULL, pathname: node, ret_handle: &handle);
1991 if (ACPI_FAILURE(status))
1992 return -ENODEV;
1993
1994 status = acpi_install_notify_handler(device: handle, ACPI_SYSTEM_NOTIFY,
1995 handler: asus_rfkill_notify, context: asus);
1996 if (ACPI_FAILURE(status))
1997 pr_warn("Failed to register notify on %s\n", node);
1998
1999 return 0;
2000}
2001
2002static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node)
2003{
2004 acpi_status status = AE_OK;
2005 acpi_handle handle;
2006
2007 status = acpi_get_handle(NULL, pathname: node, ret_handle: &handle);
2008 if (ACPI_FAILURE(status))
2009 return;
2010
2011 status = acpi_remove_notify_handler(device: handle, ACPI_SYSTEM_NOTIFY,
2012 handler: asus_rfkill_notify);
2013 if (ACPI_FAILURE(status))
2014 pr_err("Error removing rfkill notify handler %s\n", node);
2015}
2016
2017static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
2018 u8 *value)
2019{
2020 struct asus_wmi *asus = container_of(hotplug_slot,
2021 struct asus_wmi, hotplug_slot);
2022 int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
2023
2024 if (result < 0)
2025 return result;
2026
2027 *value = !!result;
2028 return 0;
2029}
2030
2031static const struct hotplug_slot_ops asus_hotplug_slot_ops = {
2032 .get_adapter_status = asus_get_adapter_status,
2033 .get_power_status = asus_get_adapter_status,
2034};
2035
2036static void asus_hotplug_work(struct work_struct *work)
2037{
2038 struct asus_wmi *asus;
2039
2040 asus = container_of(work, struct asus_wmi, hotplug_work);
2041 asus_rfkill_hotplug(asus);
2042}
2043
2044static int asus_setup_pci_hotplug(struct asus_wmi *asus)
2045{
2046 int ret = -ENOMEM;
2047 struct pci_bus *bus = pci_find_bus(domain: 0, busnr: 1);
2048
2049 if (!bus) {
2050 pr_err("Unable to find wifi PCI bus\n");
2051 return -ENODEV;
2052 }
2053
2054 asus->hotplug_workqueue =
2055 create_singlethread_workqueue("hotplug_workqueue");
2056 if (!asus->hotplug_workqueue)
2057 goto error_workqueue;
2058
2059 INIT_WORK(&asus->hotplug_work, asus_hotplug_work);
2060
2061 asus->hotplug_slot.ops = &asus_hotplug_slot_ops;
2062
2063 ret = pci_hp_register(&asus->hotplug_slot, bus, 0, "asus-wifi");
2064 if (ret) {
2065 pr_err("Unable to register hotplug slot - %d\n", ret);
2066 goto error_register;
2067 }
2068
2069 return 0;
2070
2071error_register:
2072 asus->hotplug_slot.ops = NULL;
2073 destroy_workqueue(wq: asus->hotplug_workqueue);
2074error_workqueue:
2075 return ret;
2076}
2077
2078/*
2079 * Rfkill devices
2080 */
2081static int asus_rfkill_set(void *data, bool blocked)
2082{
2083 struct asus_rfkill *priv = data;
2084 u32 ctrl_param = !blocked;
2085 u32 dev_id = priv->dev_id;
2086
2087 /*
2088 * If the user bit is set, BIOS can't set and record the wlan status,
2089 * it will report the value read from id ASUS_WMI_DEVID_WLAN_LED
2090 * while we query the wlan status through WMI(ASUS_WMI_DEVID_WLAN).
2091 * So, we have to record wlan status in id ASUS_WMI_DEVID_WLAN_LED
2092 * while setting the wlan status through WMI.
2093 * This is also the behavior that windows app will do.
2094 */
2095 if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
2096 priv->asus->driver->wlan_ctrl_by_user)
2097 dev_id = ASUS_WMI_DEVID_WLAN_LED;
2098
2099 return asus_wmi_set_devstate(dev_id, ctrl_param, NULL);
2100}
2101
2102static void asus_rfkill_query(struct rfkill *rfkill, void *data)
2103{
2104 struct asus_rfkill *priv = data;
2105 int result;
2106
2107 result = asus_wmi_get_devstate_simple(asus: priv->asus, dev_id: priv->dev_id);
2108
2109 if (result < 0)
2110 return;
2111
2112 rfkill_set_sw_state(rfkill: priv->rfkill, blocked: !result);
2113}
2114
2115static int asus_rfkill_wlan_set(void *data, bool blocked)
2116{
2117 struct asus_rfkill *priv = data;
2118 struct asus_wmi *asus = priv->asus;
2119 int ret;
2120
2121 /*
2122 * This handler is enabled only if hotplug is enabled.
2123 * In this case, the asus_wmi_set_devstate() will
2124 * trigger a wmi notification and we need to wait
2125 * this call to finish before being able to call
2126 * any wmi method
2127 */
2128 mutex_lock(&asus->wmi_lock);
2129 ret = asus_rfkill_set(data, blocked);
2130 mutex_unlock(lock: &asus->wmi_lock);
2131 return ret;
2132}
2133
2134static const struct rfkill_ops asus_rfkill_wlan_ops = {
2135 .set_block = asus_rfkill_wlan_set,
2136 .query = asus_rfkill_query,
2137};
2138
2139static const struct rfkill_ops asus_rfkill_ops = {
2140 .set_block = asus_rfkill_set,
2141 .query = asus_rfkill_query,
2142};
2143
2144static int asus_new_rfkill(struct asus_wmi *asus,
2145 struct asus_rfkill *arfkill,
2146 const char *name, enum rfkill_type type, int dev_id)
2147{
2148 int result = asus_wmi_get_devstate_simple(asus, dev_id);
2149 struct rfkill **rfkill = &arfkill->rfkill;
2150
2151 if (result < 0)
2152 return result;
2153
2154 arfkill->dev_id = dev_id;
2155 arfkill->asus = asus;
2156
2157 if (dev_id == ASUS_WMI_DEVID_WLAN &&
2158 asus->driver->quirks->hotplug_wireless)
2159 *rfkill = rfkill_alloc(name, parent: &asus->platform_device->dev, type,
2160 ops: &asus_rfkill_wlan_ops, ops_data: arfkill);
2161 else
2162 *rfkill = rfkill_alloc(name, parent: &asus->platform_device->dev, type,
2163 ops: &asus_rfkill_ops, ops_data: arfkill);
2164
2165 if (!*rfkill)
2166 return -EINVAL;
2167
2168 if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
2169 (asus->driver->quirks->wapf > 0))
2170 rfkill_set_led_trigger_name(rfkill: *rfkill, name: "asus-wlan");
2171
2172 rfkill_init_sw_state(rfkill: *rfkill, blocked: !result);
2173 result = rfkill_register(rfkill: *rfkill);
2174 if (result) {
2175 rfkill_destroy(rfkill: *rfkill);
2176 *rfkill = NULL;
2177 return result;
2178 }
2179 return 0;
2180}
2181
2182static void asus_wmi_rfkill_exit(struct asus_wmi *asus)
2183{
2184 if (asus->driver->wlan_ctrl_by_user && ashs_present())
2185 return;
2186
2187 asus_unregister_rfkill_notifier(asus, node: "\\_SB.PCI0.P0P5");
2188 asus_unregister_rfkill_notifier(asus, node: "\\_SB.PCI0.P0P6");
2189 asus_unregister_rfkill_notifier(asus, node: "\\_SB.PCI0.P0P7");
2190 if (asus->wlan.rfkill) {
2191 rfkill_unregister(rfkill: asus->wlan.rfkill);
2192 rfkill_destroy(rfkill: asus->wlan.rfkill);
2193 asus->wlan.rfkill = NULL;
2194 }
2195 /*
2196 * Refresh pci hotplug in case the rfkill state was changed after
2197 * asus_unregister_rfkill_notifier()
2198 */
2199 asus_rfkill_hotplug(asus);
2200 if (asus->hotplug_slot.ops)
2201 pci_hp_deregister(slot: &asus->hotplug_slot);
2202 if (asus->hotplug_workqueue)
2203 destroy_workqueue(wq: asus->hotplug_workqueue);
2204
2205 if (asus->bluetooth.rfkill) {
2206 rfkill_unregister(rfkill: asus->bluetooth.rfkill);
2207 rfkill_destroy(rfkill: asus->bluetooth.rfkill);
2208 asus->bluetooth.rfkill = NULL;
2209 }
2210 if (asus->wimax.rfkill) {
2211 rfkill_unregister(rfkill: asus->wimax.rfkill);
2212 rfkill_destroy(rfkill: asus->wimax.rfkill);
2213 asus->wimax.rfkill = NULL;
2214 }
2215 if (asus->wwan3g.rfkill) {
2216 rfkill_unregister(rfkill: asus->wwan3g.rfkill);
2217 rfkill_destroy(rfkill: asus->wwan3g.rfkill);
2218 asus->wwan3g.rfkill = NULL;
2219 }
2220 if (asus->gps.rfkill) {
2221 rfkill_unregister(rfkill: asus->gps.rfkill);
2222 rfkill_destroy(rfkill: asus->gps.rfkill);
2223 asus->gps.rfkill = NULL;
2224 }
2225 if (asus->uwb.rfkill) {
2226 rfkill_unregister(rfkill: asus->uwb.rfkill);
2227 rfkill_destroy(rfkill: asus->uwb.rfkill);
2228 asus->uwb.rfkill = NULL;
2229 }
2230}
2231
2232static int asus_wmi_rfkill_init(struct asus_wmi *asus)
2233{
2234 int result = 0;
2235
2236 mutex_init(&asus->hotplug_lock);
2237 mutex_init(&asus->wmi_lock);
2238
2239 result = asus_new_rfkill(asus, arfkill: &asus->wlan, name: "asus-wlan",
2240 type: RFKILL_TYPE_WLAN, ASUS_WMI_DEVID_WLAN);
2241
2242 if (result && result != -ENODEV)
2243 goto exit;
2244
2245 result = asus_new_rfkill(asus, arfkill: &asus->bluetooth,
2246 name: "asus-bluetooth", type: RFKILL_TYPE_BLUETOOTH,
2247 ASUS_WMI_DEVID_BLUETOOTH);
2248
2249 if (result && result != -ENODEV)
2250 goto exit;
2251
2252 result = asus_new_rfkill(asus, arfkill: &asus->wimax, name: "asus-wimax",
2253 type: RFKILL_TYPE_WIMAX, ASUS_WMI_DEVID_WIMAX);
2254
2255 if (result && result != -ENODEV)
2256 goto exit;
2257
2258 result = asus_new_rfkill(asus, arfkill: &asus->wwan3g, name: "asus-wwan3g",
2259 type: RFKILL_TYPE_WWAN, ASUS_WMI_DEVID_WWAN3G);
2260
2261 if (result && result != -ENODEV)
2262 goto exit;
2263
2264 result = asus_new_rfkill(asus, arfkill: &asus->gps, name: "asus-gps",
2265 type: RFKILL_TYPE_GPS, ASUS_WMI_DEVID_GPS);
2266
2267 if (result && result != -ENODEV)
2268 goto exit;
2269
2270 result = asus_new_rfkill(asus, arfkill: &asus->uwb, name: "asus-uwb",
2271 type: RFKILL_TYPE_UWB, ASUS_WMI_DEVID_UWB);
2272
2273 if (result && result != -ENODEV)
2274 goto exit;
2275
2276 if (!asus->driver->quirks->hotplug_wireless)
2277 goto exit;
2278
2279 result = asus_setup_pci_hotplug(asus);
2280 /*
2281 * If we get -EBUSY then something else is handling the PCI hotplug -
2282 * don't fail in this case
2283 */
2284 if (result == -EBUSY)
2285 result = 0;
2286
2287 asus_register_rfkill_notifier(asus, node: "\\_SB.PCI0.P0P5");
2288 asus_register_rfkill_notifier(asus, node: "\\_SB.PCI0.P0P6");
2289 asus_register_rfkill_notifier(asus, node: "\\_SB.PCI0.P0P7");
2290 /*
2291 * Refresh pci hotplug in case the rfkill state was changed during
2292 * setup.
2293 */
2294 asus_rfkill_hotplug(asus);
2295
2296exit:
2297 if (result && result != -ENODEV)
2298 asus_wmi_rfkill_exit(asus);
2299
2300 if (result == -ENODEV)
2301 result = 0;
2302
2303 return result;
2304}
2305
2306/* Panel Overdrive ************************************************************/
2307static ssize_t panel_od_show(struct device *dev,
2308 struct device_attribute *attr, char *buf)
2309{
2310 struct asus_wmi *asus = dev_get_drvdata(dev);
2311 int result;
2312
2313 result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_PANEL_OD);
2314 if (result < 0)
2315 return result;
2316
2317 return sysfs_emit(buf, fmt: "%d\n", result);
2318}
2319
2320static ssize_t panel_od_store(struct device *dev,
2321 struct device_attribute *attr,
2322 const char *buf, size_t count)
2323{
2324 int result, err;
2325 u32 overdrive;
2326
2327 struct asus_wmi *asus = dev_get_drvdata(dev);
2328
2329 result = kstrtou32(s: buf, base: 10, res: &overdrive);
2330 if (result)
2331 return result;
2332
2333 if (overdrive > 1)
2334 return -EINVAL;
2335
2336 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PANEL_OD, ctrl_param: overdrive, retval: &result);
2337
2338 if (err) {
2339 pr_warn("Failed to set panel overdrive: %d\n", err);
2340 return err;
2341 }
2342
2343 if (result > 1) {
2344 pr_warn("Failed to set panel overdrive (result): 0x%x\n", result);
2345 return -EIO;
2346 }
2347
2348 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "panel_od");
2349
2350 return count;
2351}
2352static DEVICE_ATTR_RW(panel_od);
2353
2354/* Bootup sound ***************************************************************/
2355
2356static ssize_t boot_sound_show(struct device *dev,
2357 struct device_attribute *attr, char *buf)
2358{
2359 struct asus_wmi *asus = dev_get_drvdata(dev);
2360 int result;
2361
2362 result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_BOOT_SOUND);
2363 if (result < 0)
2364 return result;
2365
2366 return sysfs_emit(buf, fmt: "%d\n", result);
2367}
2368
2369static ssize_t boot_sound_store(struct device *dev,
2370 struct device_attribute *attr,
2371 const char *buf, size_t count)
2372{
2373 int result, err;
2374 u32 snd;
2375
2376 struct asus_wmi *asus = dev_get_drvdata(dev);
2377
2378 result = kstrtou32(s: buf, base: 10, res: &snd);
2379 if (result)
2380 return result;
2381
2382 if (snd > 1)
2383 return -EINVAL;
2384
2385 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BOOT_SOUND, ctrl_param: snd, retval: &result);
2386 if (err) {
2387 pr_warn("Failed to set boot sound: %d\n", err);
2388 return err;
2389 }
2390
2391 if (result > 1) {
2392 pr_warn("Failed to set panel boot sound (result): 0x%x\n", result);
2393 return -EIO;
2394 }
2395
2396 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "boot_sound");
2397
2398 return count;
2399}
2400static DEVICE_ATTR_RW(boot_sound);
2401
2402/* Mini-LED mode **************************************************************/
2403static ssize_t mini_led_mode_show(struct device *dev,
2404 struct device_attribute *attr, char *buf)
2405{
2406 struct asus_wmi *asus = dev_get_drvdata(dev);
2407 u32 value;
2408 int err;
2409
2410 err = asus_wmi_get_devstate(asus, dev_id: asus->mini_led_dev_id, retval: &value);
2411 if (err < 0)
2412 return err;
2413 value = value & ASUS_MINI_LED_MODE_MASK;
2414
2415 /*
2416 * Remap the mode values to match previous generation mini-led. The last gen
2417 * WMI 0 == off, while on this version WMI 2 ==off (flipped).
2418 */
2419 if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) {
2420 switch (value) {
2421 case ASUS_MINI_LED_2024_WEAK:
2422 value = ASUS_MINI_LED_ON;
2423 break;
2424 case ASUS_MINI_LED_2024_STRONG:
2425 value = ASUS_MINI_LED_STRONG_MODE;
2426 break;
2427 case ASUS_MINI_LED_2024_OFF:
2428 value = ASUS_MINI_LED_OFF;
2429 break;
2430 }
2431 }
2432
2433 return sysfs_emit(buf, fmt: "%d\n", value);
2434}
2435
2436static ssize_t mini_led_mode_store(struct device *dev,
2437 struct device_attribute *attr,
2438 const char *buf, size_t count)
2439{
2440 int result, err;
2441 u32 mode;
2442
2443 struct asus_wmi *asus = dev_get_drvdata(dev);
2444
2445 result = kstrtou32(s: buf, base: 10, res: &mode);
2446 if (result)
2447 return result;
2448
2449 if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE &&
2450 mode > ASUS_MINI_LED_ON)
2451 return -EINVAL;
2452 if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2 &&
2453 mode > ASUS_MINI_LED_STRONG_MODE)
2454 return -EINVAL;
2455
2456 /*
2457 * Remap the mode values so expected behaviour is the same as the last
2458 * generation of mini-LED with 0 == off, 1 == on.
2459 */
2460 if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) {
2461 switch (mode) {
2462 case ASUS_MINI_LED_OFF:
2463 mode = ASUS_MINI_LED_2024_OFF;
2464 break;
2465 case ASUS_MINI_LED_ON:
2466 mode = ASUS_MINI_LED_2024_WEAK;
2467 break;
2468 case ASUS_MINI_LED_STRONG_MODE:
2469 mode = ASUS_MINI_LED_2024_STRONG;
2470 break;
2471 }
2472 }
2473
2474 err = asus_wmi_set_devstate(dev_id: asus->mini_led_dev_id, ctrl_param: mode, retval: &result);
2475 if (err) {
2476 pr_warn("Failed to set mini-LED: %d\n", err);
2477 return err;
2478 }
2479
2480 if (result > 1) {
2481 pr_warn("Failed to set mini-LED mode (result): 0x%x\n", result);
2482 return -EIO;
2483 }
2484
2485 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL, attr: "mini_led_mode");
2486
2487 return count;
2488}
2489static DEVICE_ATTR_RW(mini_led_mode);
2490
2491static ssize_t available_mini_led_mode_show(struct device *dev,
2492 struct device_attribute *attr, char *buf)
2493{
2494 struct asus_wmi *asus = dev_get_drvdata(dev);
2495
2496 switch (asus->mini_led_dev_id) {
2497 case ASUS_WMI_DEVID_MINI_LED_MODE:
2498 return sysfs_emit(buf, fmt: "0 1\n");
2499 case ASUS_WMI_DEVID_MINI_LED_MODE2:
2500 return sysfs_emit(buf, fmt: "0 1 2\n");
2501 }
2502
2503 return sysfs_emit(buf, fmt: "0\n");
2504}
2505
2506static DEVICE_ATTR_RO(available_mini_led_mode);
2507
2508/* Quirks *********************************************************************/
2509
2510static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
2511{
2512 struct pci_dev *xhci_pdev;
2513 u32 orig_ports_available;
2514 u32 ports_available = asus->driver->quirks->xusb2pr;
2515
2516 xhci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
2517 PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI,
2518 NULL);
2519
2520 if (!xhci_pdev)
2521 return;
2522
2523 pci_read_config_dword(dev: xhci_pdev, USB_INTEL_XUSB2PR,
2524 val: &orig_ports_available);
2525
2526 pci_write_config_dword(dev: xhci_pdev, USB_INTEL_XUSB2PR,
2527 cpu_to_le32(ports_available));
2528
2529 pci_dev_put(dev: xhci_pdev);
2530
2531 pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n",
2532 orig_ports_available, ports_available);
2533}
2534
2535/*
2536 * Some devices dont support or have borcken get_als method
2537 * but still support set method.
2538 */
2539static void asus_wmi_set_als(void)
2540{
2541 asus_wmi_set_devstate(ASUS_WMI_DEVID_ALS_ENABLE, ctrl_param: 1, NULL);
2542}
2543
2544/* Hwmon device ***************************************************************/
2545
2546static int asus_agfn_fan_speed_read(struct asus_wmi *asus, int fan,
2547 int *speed)
2548{
2549 struct agfn_fan_args args = {
2550 .agfn.len = sizeof(args),
2551 .agfn.mfun = ASUS_FAN_MFUN,
2552 .agfn.sfun = ASUS_FAN_SFUN_READ,
2553 .fan = fan,
2554 .speed = 0,
2555 };
2556 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
2557 int status;
2558
2559 if (fan != 1)
2560 return -EINVAL;
2561
2562 status = asus_wmi_evaluate_method_agfn(args: input);
2563
2564 if (status || args.agfn.err)
2565 return -ENXIO;
2566
2567 if (speed)
2568 *speed = args.speed;
2569
2570 return 0;
2571}
2572
2573static int asus_agfn_fan_speed_write(struct asus_wmi *asus, int fan,
2574 int *speed)
2575{
2576 struct agfn_fan_args args = {
2577 .agfn.len = sizeof(args),
2578 .agfn.mfun = ASUS_FAN_MFUN,
2579 .agfn.sfun = ASUS_FAN_SFUN_WRITE,
2580 .fan = fan,
2581 .speed = speed ? *speed : 0,
2582 };
2583 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
2584 int status;
2585
2586 /* 1: for setting 1st fan's speed 0: setting auto mode */
2587 if (fan != 1 && fan != 0)
2588 return -EINVAL;
2589
2590 status = asus_wmi_evaluate_method_agfn(args: input);
2591
2592 if (status || args.agfn.err)
2593 return -ENXIO;
2594
2595 if (speed && fan == 1)
2596 asus->agfn_pwm = *speed;
2597
2598 return 0;
2599}
2600
2601/*
2602 * Check if we can read the speed of one fan. If true we assume we can also
2603 * control it.
2604 */
2605static bool asus_wmi_has_agfn_fan(struct asus_wmi *asus)
2606{
2607 int status;
2608 int speed;
2609 u32 value;
2610
2611 status = asus_agfn_fan_speed_read(asus, fan: 1, speed: &speed);
2612 if (status != 0)
2613 return false;
2614
2615 status = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, retval: &value);
2616 if (status != 0)
2617 return false;
2618
2619 /*
2620 * We need to find a better way, probably using sfun,
2621 * bits or spec ...
2622 * Currently we disable it if:
2623 * - ASUS_WMI_UNSUPPORTED_METHOD is returned
2624 * - reverved bits are non-zero
2625 * - sfun and presence bit are not set
2626 */
2627 return !(value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
2628 || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)));
2629}
2630
2631static int asus_fan_set_auto(struct asus_wmi *asus)
2632{
2633 int status;
2634 u32 retval;
2635
2636 switch (asus->fan_type) {
2637 case FAN_TYPE_SPEC83:
2638 status = asus_wmi_set_devstate(ASUS_WMI_DEVID_CPU_FAN_CTRL,
2639 ctrl_param: 0, retval: &retval);
2640 if (status)
2641 return status;
2642
2643 if (retval != 1)
2644 return -EIO;
2645 break;
2646
2647 case FAN_TYPE_AGFN:
2648 status = asus_agfn_fan_speed_write(asus, fan: 0, NULL);
2649 if (status)
2650 return -ENXIO;
2651 break;
2652
2653 default:
2654 return -ENXIO;
2655 }
2656
2657 /*
2658 * Modern models like the G713 also have GPU fan control (this is not AGFN)
2659 */
2660 if (asus->gpu_fan_type == FAN_TYPE_SPEC83) {
2661 status = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_FAN_CTRL,
2662 ctrl_param: 0, retval: &retval);
2663 if (status)
2664 return status;
2665
2666 if (retval != 1)
2667 return -EIO;
2668 }
2669
2670 return 0;
2671}
2672
2673static ssize_t pwm1_show(struct device *dev,
2674 struct device_attribute *attr,
2675 char *buf)
2676{
2677 struct asus_wmi *asus = dev_get_drvdata(dev);
2678 int err;
2679 int value;
2680
2681 /* If we already set a value then just return it */
2682 if (asus->agfn_pwm >= 0)
2683 return sysfs_emit(buf, fmt: "%d\n", asus->agfn_pwm);
2684
2685 /*
2686 * If we haven't set already set a value through the AGFN interface,
2687 * we read a current value through the (now-deprecated) FAN_CTRL device.
2688 */
2689 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, retval: &value);
2690 if (err < 0)
2691 return err;
2692
2693 value &= 0xFF;
2694
2695 if (value == 1) /* Low Speed */
2696 value = 85;
2697 else if (value == 2)
2698 value = 170;
2699 else if (value == 3)
2700 value = 255;
2701 else if (value) {
2702 pr_err("Unknown fan speed %#x\n", value);
2703 value = -1;
2704 }
2705
2706 return sysfs_emit(buf, fmt: "%d\n", value);
2707}
2708
2709static ssize_t pwm1_store(struct device *dev,
2710 struct device_attribute *attr,
2711 const char *buf, size_t count) {
2712 struct asus_wmi *asus = dev_get_drvdata(dev);
2713 int value;
2714 int state;
2715 int ret;
2716
2717 ret = kstrtouint(s: buf, base: 10, res: &value);
2718 if (ret)
2719 return ret;
2720
2721 value = clamp(value, 0, 255);
2722
2723 state = asus_agfn_fan_speed_write(asus, fan: 1, speed: &value);
2724 if (state)
2725 pr_warn("Setting fan speed failed: %d\n", state);
2726 else
2727 asus->fan_pwm_mode = ASUS_FAN_CTRL_MANUAL;
2728
2729 return count;
2730}
2731
2732static ssize_t fan1_input_show(struct device *dev,
2733 struct device_attribute *attr,
2734 char *buf)
2735{
2736 struct asus_wmi *asus = dev_get_drvdata(dev);
2737 int value;
2738 int ret;
2739
2740 switch (asus->fan_type) {
2741 case FAN_TYPE_SPEC83:
2742 ret = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_CPU_FAN_CTRL,
2743 retval: &value);
2744 if (ret < 0)
2745 return ret;
2746
2747 value &= 0xffff;
2748 break;
2749
2750 case FAN_TYPE_AGFN:
2751 /* no speed readable on manual mode */
2752 if (asus->fan_pwm_mode == ASUS_FAN_CTRL_MANUAL)
2753 return -ENXIO;
2754
2755 ret = asus_agfn_fan_speed_read(asus, fan: 1, speed: &value);
2756 if (ret) {
2757 pr_warn("reading fan speed failed: %d\n", ret);
2758 return -ENXIO;
2759 }
2760 break;
2761
2762 default:
2763 return -ENXIO;
2764 }
2765
2766 return sysfs_emit(buf, fmt: "%d\n", value < 0 ? -1 : value * 100);
2767}
2768
2769static ssize_t pwm1_enable_show(struct device *dev,
2770 struct device_attribute *attr,
2771 char *buf)
2772{
2773 struct asus_wmi *asus = dev_get_drvdata(dev);
2774
2775 /*
2776 * Just read back the cached pwm mode.
2777 *
2778 * For the CPU_FAN device, the spec indicates that we should be
2779 * able to read the device status and consult bit 19 to see if we
2780 * are in Full On or Automatic mode. However, this does not work
2781 * in practice on X532FL at least (the bit is always 0) and there's
2782 * also nothing in the DSDT to indicate that this behaviour exists.
2783 */
2784 return sysfs_emit(buf, fmt: "%d\n", asus->fan_pwm_mode);
2785}
2786
2787static ssize_t pwm1_enable_store(struct device *dev,
2788 struct device_attribute *attr,
2789 const char *buf, size_t count)
2790{
2791 struct asus_wmi *asus = dev_get_drvdata(dev);
2792 int status = 0;
2793 int state;
2794 int value;
2795 int ret;
2796 u32 retval;
2797
2798 ret = kstrtouint(s: buf, base: 10, res: &state);
2799 if (ret)
2800 return ret;
2801
2802 if (asus->fan_type == FAN_TYPE_SPEC83) {
2803 switch (state) { /* standard documented hwmon values */
2804 case ASUS_FAN_CTRL_FULLSPEED:
2805 value = 1;
2806 break;
2807 case ASUS_FAN_CTRL_AUTO:
2808 value = 0;
2809 break;
2810 default:
2811 return -EINVAL;
2812 }
2813
2814 ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_CPU_FAN_CTRL,
2815 ctrl_param: value, retval: &retval);
2816 if (ret)
2817 return ret;
2818
2819 if (retval != 1)
2820 return -EIO;
2821 } else if (asus->fan_type == FAN_TYPE_AGFN) {
2822 switch (state) {
2823 case ASUS_FAN_CTRL_MANUAL:
2824 break;
2825
2826 case ASUS_FAN_CTRL_AUTO:
2827 status = asus_fan_set_auto(asus);
2828 if (status)
2829 return status;
2830 break;
2831
2832 default:
2833 return -EINVAL;
2834 }
2835 }
2836
2837 asus->fan_pwm_mode = state;
2838
2839 /* Must set to disabled if mode is toggled */
2840 if (asus->cpu_fan_curve_available)
2841 asus->custom_fan_curves[FAN_CURVE_DEV_CPU].enabled = false;
2842 if (asus->gpu_fan_curve_available)
2843 asus->custom_fan_curves[FAN_CURVE_DEV_GPU].enabled = false;
2844 if (asus->mid_fan_curve_available)
2845 asus->custom_fan_curves[FAN_CURVE_DEV_MID].enabled = false;
2846
2847 return count;
2848}
2849
2850static ssize_t asus_hwmon_temp1(struct device *dev,
2851 struct device_attribute *attr,
2852 char *buf)
2853{
2854 struct asus_wmi *asus = dev_get_drvdata(dev);
2855 u32 value;
2856 int err;
2857
2858 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, retval: &value);
2859 if (err < 0)
2860 return err;
2861
2862 return sysfs_emit(buf, fmt: "%ld\n",
2863 deci_kelvin_to_millicelsius(t: value & 0xFFFF));
2864}
2865
2866/* GPU fan on modern ROG laptops */
2867static ssize_t fan2_input_show(struct device *dev,
2868 struct device_attribute *attr,
2869 char *buf)
2870{
2871 struct asus_wmi *asus = dev_get_drvdata(dev);
2872 int value;
2873 int ret;
2874
2875 ret = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_GPU_FAN_CTRL, retval: &value);
2876 if (ret < 0)
2877 return ret;
2878
2879 value &= 0xffff;
2880
2881 return sysfs_emit(buf, fmt: "%d\n", value * 100);
2882}
2883
2884/* Middle/Center fan on modern ROG laptops */
2885static ssize_t fan3_input_show(struct device *dev,
2886 struct device_attribute *attr,
2887 char *buf)
2888{
2889 struct asus_wmi *asus = dev_get_drvdata(dev);
2890 int value;
2891 int ret;
2892
2893 ret = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_MID_FAN_CTRL, retval: &value);
2894 if (ret < 0)
2895 return ret;
2896
2897 value &= 0xffff;
2898
2899 return sysfs_emit(buf, fmt: "%d\n", value * 100);
2900}
2901
2902static ssize_t pwm2_enable_show(struct device *dev,
2903 struct device_attribute *attr,
2904 char *buf)
2905{
2906 struct asus_wmi *asus = dev_get_drvdata(dev);
2907
2908 return sysfs_emit(buf, fmt: "%d\n", asus->gpu_fan_pwm_mode);
2909}
2910
2911static ssize_t pwm2_enable_store(struct device *dev,
2912 struct device_attribute *attr,
2913 const char *buf, size_t count)
2914{
2915 struct asus_wmi *asus = dev_get_drvdata(dev);
2916 int state;
2917 int value;
2918 int ret;
2919 u32 retval;
2920
2921 ret = kstrtouint(s: buf, base: 10, res: &state);
2922 if (ret)
2923 return ret;
2924
2925 switch (state) { /* standard documented hwmon values */
2926 case ASUS_FAN_CTRL_FULLSPEED:
2927 value = 1;
2928 break;
2929 case ASUS_FAN_CTRL_AUTO:
2930 value = 0;
2931 break;
2932 default:
2933 return -EINVAL;
2934 }
2935
2936 ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_FAN_CTRL,
2937 ctrl_param: value, retval: &retval);
2938 if (ret)
2939 return ret;
2940
2941 if (retval != 1)
2942 return -EIO;
2943
2944 asus->gpu_fan_pwm_mode = state;
2945 return count;
2946}
2947
2948static ssize_t pwm3_enable_show(struct device *dev,
2949 struct device_attribute *attr,
2950 char *buf)
2951{
2952 struct asus_wmi *asus = dev_get_drvdata(dev);
2953
2954 return sysfs_emit(buf, fmt: "%d\n", asus->mid_fan_pwm_mode);
2955}
2956
2957static ssize_t pwm3_enable_store(struct device *dev,
2958 struct device_attribute *attr,
2959 const char *buf, size_t count)
2960{
2961 struct asus_wmi *asus = dev_get_drvdata(dev);
2962 int state;
2963 int value;
2964 int ret;
2965 u32 retval;
2966
2967 ret = kstrtouint(s: buf, base: 10, res: &state);
2968 if (ret)
2969 return ret;
2970
2971 switch (state) { /* standard documented hwmon values */
2972 case ASUS_FAN_CTRL_FULLSPEED:
2973 value = 1;
2974 break;
2975 case ASUS_FAN_CTRL_AUTO:
2976 value = 0;
2977 break;
2978 default:
2979 return -EINVAL;
2980 }
2981
2982 ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_MID_FAN_CTRL,
2983 ctrl_param: value, retval: &retval);
2984 if (ret)
2985 return ret;
2986
2987 if (retval != 1)
2988 return -EIO;
2989
2990 asus->mid_fan_pwm_mode = state;
2991 return count;
2992}
2993
2994/* Fan1 */
2995static DEVICE_ATTR_RW(pwm1);
2996static DEVICE_ATTR_RW(pwm1_enable);
2997static DEVICE_ATTR_RO(fan1_input);
2998static DEVICE_STRING_ATTR_RO(fan1_label, 0444, ASUS_FAN_DESC);
2999
3000/* Fan2 - GPU fan */
3001static DEVICE_ATTR_RW(pwm2_enable);
3002static DEVICE_ATTR_RO(fan2_input);
3003static DEVICE_STRING_ATTR_RO(fan2_label, 0444, ASUS_GPU_FAN_DESC);
3004/* Fan3 - Middle/center fan */
3005static DEVICE_ATTR_RW(pwm3_enable);
3006static DEVICE_ATTR_RO(fan3_input);
3007static DEVICE_STRING_ATTR_RO(fan3_label, 0444, ASUS_MID_FAN_DESC);
3008
3009/* Temperature */
3010static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
3011
3012static struct attribute *hwmon_attributes[] = {
3013 &dev_attr_pwm1.attr,
3014 &dev_attr_pwm1_enable.attr,
3015 &dev_attr_pwm2_enable.attr,
3016 &dev_attr_pwm3_enable.attr,
3017 &dev_attr_fan1_input.attr,
3018 &dev_attr_fan1_label.attr.attr,
3019 &dev_attr_fan2_input.attr,
3020 &dev_attr_fan2_label.attr.attr,
3021 &dev_attr_fan3_input.attr,
3022 &dev_attr_fan3_label.attr.attr,
3023
3024 &dev_attr_temp1_input.attr,
3025 NULL
3026};
3027
3028static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
3029 struct attribute *attr, int idx)
3030{
3031 struct device *dev = kobj_to_dev(kobj);
3032 struct asus_wmi *asus = dev_get_drvdata(dev: dev->parent);
3033 u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
3034
3035 if (attr == &dev_attr_pwm1.attr) {
3036 if (asus->fan_type != FAN_TYPE_AGFN)
3037 return 0;
3038 } else if (attr == &dev_attr_fan1_input.attr
3039 || attr == &dev_attr_fan1_label.attr.attr
3040 || attr == &dev_attr_pwm1_enable.attr) {
3041 if (asus->fan_type == FAN_TYPE_NONE)
3042 return 0;
3043 } else if (attr == &dev_attr_fan2_input.attr
3044 || attr == &dev_attr_fan2_label.attr.attr
3045 || attr == &dev_attr_pwm2_enable.attr) {
3046 if (asus->gpu_fan_type == FAN_TYPE_NONE)
3047 return 0;
3048 } else if (attr == &dev_attr_fan3_input.attr
3049 || attr == &dev_attr_fan3_label.attr.attr
3050 || attr == &dev_attr_pwm3_enable.attr) {
3051 if (asus->mid_fan_type == FAN_TYPE_NONE)
3052 return 0;
3053 } else if (attr == &dev_attr_temp1_input.attr) {
3054 int err = asus_wmi_get_devstate(asus,
3055 ASUS_WMI_DEVID_THERMAL_CTRL,
3056 retval: &value);
3057
3058 if (err < 0)
3059 return 0; /* can't return negative here */
3060
3061 /*
3062 * If the temperature value in deci-Kelvin is near the absolute
3063 * zero temperature, something is clearly wrong
3064 */
3065 if (value == 0 || value == 1)
3066 return 0;
3067 }
3068
3069 return attr->mode;
3070}
3071
3072static const struct attribute_group hwmon_attribute_group = {
3073 .is_visible = asus_hwmon_sysfs_is_visible,
3074 .attrs = hwmon_attributes
3075};
3076__ATTRIBUTE_GROUPS(hwmon_attribute);
3077
3078static int asus_wmi_hwmon_init(struct asus_wmi *asus)
3079{
3080 struct device *dev = &asus->platform_device->dev;
3081 struct device *hwmon;
3082
3083 hwmon = devm_hwmon_device_register_with_groups(dev, name: "asus", drvdata: asus,
3084 groups: hwmon_attribute_groups);
3085
3086 if (IS_ERR(ptr: hwmon)) {
3087 pr_err("Could not register asus hwmon device\n");
3088 return PTR_ERR(ptr: hwmon);
3089 }
3090 return 0;
3091}
3092
3093static int asus_wmi_fan_init(struct asus_wmi *asus)
3094{
3095 asus->gpu_fan_type = FAN_TYPE_NONE;
3096 asus->mid_fan_type = FAN_TYPE_NONE;
3097 asus->fan_type = FAN_TYPE_NONE;
3098 asus->agfn_pwm = -1;
3099
3100 if (asus->driver->quirks->wmi_ignore_fan)
3101 asus->fan_type = FAN_TYPE_NONE;
3102 else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CPU_FAN_CTRL))
3103 asus->fan_type = FAN_TYPE_SPEC83;
3104 else if (asus_wmi_has_agfn_fan(asus))
3105 asus->fan_type = FAN_TYPE_AGFN;
3106
3107 /* Modern models like G713 also have GPU fan control */
3108 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_FAN_CTRL))
3109 asus->gpu_fan_type = FAN_TYPE_SPEC83;
3110
3111 /* Some models also have a center/middle fan */
3112 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MID_FAN_CTRL))
3113 asus->mid_fan_type = FAN_TYPE_SPEC83;
3114
3115 if (asus->fan_type == FAN_TYPE_NONE)
3116 return -ENODEV;
3117
3118 asus_fan_set_auto(asus);
3119 asus->fan_pwm_mode = ASUS_FAN_CTRL_AUTO;
3120 return 0;
3121}
3122
3123/* Fan mode *******************************************************************/
3124
3125static int fan_boost_mode_check_present(struct asus_wmi *asus)
3126{
3127 u32 result;
3128 int err;
3129
3130 asus->fan_boost_mode_available = false;
3131
3132 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_BOOST_MODE,
3133 retval: &result);
3134 if (err) {
3135 if (err == -ENODEV)
3136 return 0;
3137 else
3138 return err;
3139 }
3140
3141 if ((result & ASUS_WMI_DSTS_PRESENCE_BIT) &&
3142 (result & ASUS_FAN_BOOST_MODES_MASK)) {
3143 asus->fan_boost_mode_available = true;
3144 asus->fan_boost_mode_mask = result & ASUS_FAN_BOOST_MODES_MASK;
3145 }
3146
3147 return 0;
3148}
3149
3150static int fan_boost_mode_write(struct asus_wmi *asus)
3151{
3152 u32 retval;
3153 u8 value;
3154 int err;
3155
3156 value = asus->fan_boost_mode;
3157
3158 pr_info("Set fan boost mode: %u\n", value);
3159 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_FAN_BOOST_MODE, ctrl_param: value,
3160 retval: &retval);
3161
3162 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL,
3163 attr: "fan_boost_mode");
3164
3165 if (err) {
3166 pr_warn("Failed to set fan boost mode: %d\n", err);
3167 return err;
3168 }
3169
3170 if (retval != 1) {
3171 pr_warn("Failed to set fan boost mode (retval): 0x%x\n",
3172 retval);
3173 return -EIO;
3174 }
3175
3176 return 0;
3177}
3178
3179static int fan_boost_mode_switch_next(struct asus_wmi *asus)
3180{
3181 u8 mask = asus->fan_boost_mode_mask;
3182
3183 if (asus->fan_boost_mode == ASUS_FAN_BOOST_MODE_NORMAL) {
3184 if (mask & ASUS_FAN_BOOST_MODE_OVERBOOST_MASK)
3185 asus->fan_boost_mode = ASUS_FAN_BOOST_MODE_OVERBOOST;
3186 else if (mask & ASUS_FAN_BOOST_MODE_SILENT_MASK)
3187 asus->fan_boost_mode = ASUS_FAN_BOOST_MODE_SILENT;
3188 } else if (asus->fan_boost_mode == ASUS_FAN_BOOST_MODE_OVERBOOST) {
3189 if (mask & ASUS_FAN_BOOST_MODE_SILENT_MASK)
3190 asus->fan_boost_mode = ASUS_FAN_BOOST_MODE_SILENT;
3191 else
3192 asus->fan_boost_mode = ASUS_FAN_BOOST_MODE_NORMAL;
3193 } else {
3194 asus->fan_boost_mode = ASUS_FAN_BOOST_MODE_NORMAL;
3195 }
3196
3197 return fan_boost_mode_write(asus);
3198}
3199
3200static ssize_t fan_boost_mode_show(struct device *dev,
3201 struct device_attribute *attr, char *buf)
3202{
3203 struct asus_wmi *asus = dev_get_drvdata(dev);
3204
3205 return sysfs_emit(buf, fmt: "%d\n", asus->fan_boost_mode);
3206}
3207
3208static ssize_t fan_boost_mode_store(struct device *dev,
3209 struct device_attribute *attr,
3210 const char *buf, size_t count)
3211{
3212 struct asus_wmi *asus = dev_get_drvdata(dev);
3213 u8 mask = asus->fan_boost_mode_mask;
3214 u8 new_mode;
3215 int result;
3216
3217 result = kstrtou8(s: buf, base: 10, res: &new_mode);
3218 if (result < 0) {
3219 pr_warn("Trying to store invalid value\n");
3220 return result;
3221 }
3222
3223 if (new_mode == ASUS_FAN_BOOST_MODE_OVERBOOST) {
3224 if (!(mask & ASUS_FAN_BOOST_MODE_OVERBOOST_MASK))
3225 return -EINVAL;
3226 } else if (new_mode == ASUS_FAN_BOOST_MODE_SILENT) {
3227 if (!(mask & ASUS_FAN_BOOST_MODE_SILENT_MASK))
3228 return -EINVAL;
3229 } else if (new_mode != ASUS_FAN_BOOST_MODE_NORMAL) {
3230 return -EINVAL;
3231 }
3232
3233 asus->fan_boost_mode = new_mode;
3234 fan_boost_mode_write(asus);
3235
3236 return count;
3237}
3238
3239// Fan boost mode: 0 - normal, 1 - overboost, 2 - silent
3240static DEVICE_ATTR_RW(fan_boost_mode);
3241
3242/* Custom fan curves **********************************************************/
3243
3244static void fan_curve_copy_from_buf(struct fan_curve_data *data, u8 *buf)
3245{
3246 int i;
3247
3248 for (i = 0; i < FAN_CURVE_POINTS; i++) {
3249 data->temps[i] = buf[i];
3250 }
3251
3252 for (i = 0; i < FAN_CURVE_POINTS; i++) {
3253 data->percents[i] =
3254 255 * buf[i + FAN_CURVE_POINTS] / 100;
3255 }
3256}
3257
3258static int fan_curve_get_factory_default(struct asus_wmi *asus, u32 fan_dev)
3259{
3260 struct fan_curve_data *curves;
3261 u8 buf[FAN_CURVE_BUF_LEN];
3262 int err, fan_idx;
3263 u8 mode = 0;
3264
3265 if (asus->throttle_thermal_policy_dev)
3266 mode = asus->throttle_thermal_policy_mode;
3267 /* DEVID_<C/G>PU_FAN_CURVE is switched for OVERBOOST vs SILENT */
3268 if (mode == 2)
3269 mode = 1;
3270 else if (mode == 1)
3271 mode = 2;
3272
3273 err = asus_wmi_evaluate_method_buf(method_id: asus->dsts_id, arg0: fan_dev, arg1: mode, ret_buffer: buf,
3274 FAN_CURVE_BUF_LEN);
3275 if (err) {
3276 pr_warn("%s (0x%08x) failed: %d\n", __func__, fan_dev, err);
3277 return err;
3278 }
3279
3280 fan_idx = FAN_CURVE_DEV_CPU;
3281 if (fan_dev == ASUS_WMI_DEVID_GPU_FAN_CURVE)
3282 fan_idx = FAN_CURVE_DEV_GPU;
3283
3284 if (fan_dev == ASUS_WMI_DEVID_MID_FAN_CURVE)
3285 fan_idx = FAN_CURVE_DEV_MID;
3286
3287 curves = &asus->custom_fan_curves[fan_idx];
3288 curves->device_id = fan_dev;
3289
3290 fan_curve_copy_from_buf(data: curves, buf);
3291 return 0;
3292}
3293
3294/* Check if capability exists, and populate defaults */
3295static int fan_curve_check_present(struct asus_wmi *asus, bool *available,
3296 u32 fan_dev)
3297{
3298 int err;
3299
3300 *available = false;
3301
3302 if (asus->fan_type == FAN_TYPE_NONE)
3303 return 0;
3304
3305 err = fan_curve_get_factory_default(asus, fan_dev);
3306 if (err) {
3307 return 0;
3308 }
3309
3310 *available = true;
3311 return 0;
3312}
3313
3314/* Determine which fan the attribute is for if SENSOR_ATTR */
3315static struct fan_curve_data *fan_curve_attr_select(struct asus_wmi *asus,
3316 struct device_attribute *attr)
3317{
3318 int index = to_sensor_dev_attr(attr)->index;
3319
3320 return &asus->custom_fan_curves[index];
3321}
3322
3323/* Determine which fan the attribute is for if SENSOR_ATTR_2 */
3324static struct fan_curve_data *fan_curve_attr_2_select(struct asus_wmi *asus,
3325 struct device_attribute *attr)
3326{
3327 int nr = to_sensor_dev_attr_2(attr)->nr;
3328
3329 return &asus->custom_fan_curves[nr & ~FAN_CURVE_PWM_MASK];
3330}
3331
3332static ssize_t fan_curve_show(struct device *dev,
3333 struct device_attribute *attr, char *buf)
3334{
3335 struct sensor_device_attribute_2 *dev_attr = to_sensor_dev_attr_2(attr);
3336 struct asus_wmi *asus = dev_get_drvdata(dev);
3337 struct fan_curve_data *data;
3338 int value, pwm, index;
3339
3340 data = fan_curve_attr_2_select(asus, attr);
3341 pwm = dev_attr->nr & FAN_CURVE_PWM_MASK;
3342 index = dev_attr->index;
3343
3344 if (pwm)
3345 value = data->percents[index];
3346 else
3347 value = data->temps[index];
3348
3349 return sysfs_emit(buf, fmt: "%d\n", value);
3350}
3351
3352/*
3353 * "fan_dev" is the related WMI method such as ASUS_WMI_DEVID_CPU_FAN_CURVE.
3354 */
3355static int fan_curve_write(struct asus_wmi *asus,
3356 struct fan_curve_data *data)
3357{
3358 u32 arg1 = 0, arg2 = 0, arg3 = 0, arg4 = 0;
3359 u8 *percents = data->percents;
3360 u8 *temps = data->temps;
3361 int ret, i, shift = 0;
3362
3363 if (!data->enabled)
3364 return 0;
3365
3366 for (i = 0; i < FAN_CURVE_POINTS / 2; i++) {
3367 arg1 += (temps[i]) << shift;
3368 arg2 += (temps[i + 4]) << shift;
3369 /* Scale to percentage for device */
3370 arg3 += (100 * percents[i] / 255) << shift;
3371 arg4 += (100 * percents[i + 4] / 255) << shift;
3372 shift += 8;
3373 }
3374
3375 return asus_wmi_evaluate_method5(ASUS_WMI_METHODID_DEVS,
3376 arg0: data->device_id,
3377 arg1, arg2, arg3, arg4, retval: &ret);
3378}
3379
3380static ssize_t fan_curve_store(struct device *dev,
3381 struct device_attribute *attr, const char *buf,
3382 size_t count)
3383{
3384 struct sensor_device_attribute_2 *dev_attr = to_sensor_dev_attr_2(attr);
3385 struct asus_wmi *asus = dev_get_drvdata(dev);
3386 struct fan_curve_data *data;
3387 int err, pwm, index;
3388 u8 value;
3389
3390 data = fan_curve_attr_2_select(asus, attr);
3391 pwm = dev_attr->nr & FAN_CURVE_PWM_MASK;
3392 index = dev_attr->index;
3393
3394 err = kstrtou8(s: buf, base: 10, res: &value);
3395 if (err < 0)
3396 return err;
3397
3398 if (pwm)
3399 data->percents[index] = value;
3400 else
3401 data->temps[index] = value;
3402
3403 /*
3404 * Mark as disabled so the user has to explicitly enable to apply a
3405 * changed fan curve. This prevents potential lockups from writing out
3406 * many changes as one-write-per-change.
3407 */
3408 data->enabled = false;
3409
3410 return count;
3411}
3412
3413static ssize_t fan_curve_enable_show(struct device *dev,
3414 struct device_attribute *attr, char *buf)
3415{
3416 struct asus_wmi *asus = dev_get_drvdata(dev);
3417 struct fan_curve_data *data;
3418 int out = 2;
3419
3420 data = fan_curve_attr_select(asus, attr);
3421
3422 if (data->enabled)
3423 out = 1;
3424
3425 return sysfs_emit(buf, fmt: "%d\n", out);
3426}
3427
3428static ssize_t fan_curve_enable_store(struct device *dev,
3429 struct device_attribute *attr,
3430 const char *buf, size_t count)
3431{
3432 struct asus_wmi *asus = dev_get_drvdata(dev);
3433 struct fan_curve_data *data;
3434 int value, err;
3435
3436 data = fan_curve_attr_select(asus, attr);
3437
3438 err = kstrtoint(s: buf, base: 10, res: &value);
3439 if (err < 0)
3440 return err;
3441
3442 switch (value) {
3443 case 1:
3444 data->enabled = true;
3445 break;
3446 case 2:
3447 data->enabled = false;
3448 break;
3449 /*
3450 * Auto + reset the fan curve data to defaults. Make it an explicit
3451 * option so that users don't accidentally overwrite a set fan curve.
3452 */
3453 case 3:
3454 err = fan_curve_get_factory_default(asus, fan_dev: data->device_id);
3455 if (err)
3456 return err;
3457 data->enabled = false;
3458 break;
3459 default:
3460 return -EINVAL;
3461 }
3462
3463 if (data->enabled) {
3464 err = fan_curve_write(asus, data);
3465 if (err)
3466 return err;
3467 } else {
3468 /*
3469 * For machines with throttle this is the only way to reset fans
3470 * to default mode of operation (does not erase curve data).
3471 */
3472 if (asus->throttle_thermal_policy_dev) {
3473 err = throttle_thermal_policy_write(asus);
3474 if (err)
3475 return err;
3476 /* Similar is true for laptops with this fan */
3477 } else if (asus->fan_type == FAN_TYPE_SPEC83) {
3478 err = asus_fan_set_auto(asus);
3479 if (err)
3480 return err;
3481 } else {
3482 /* Safeguard against fautly ACPI tables */
3483 err = fan_curve_get_factory_default(asus, fan_dev: data->device_id);
3484 if (err)
3485 return err;
3486 err = fan_curve_write(asus, data);
3487 if (err)
3488 return err;
3489 }
3490 }
3491 return count;
3492}
3493
3494/* CPU */
3495static SENSOR_DEVICE_ATTR_RW(pwm1_enable, fan_curve_enable, FAN_CURVE_DEV_CPU);
3496static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point1_temp, fan_curve,
3497 FAN_CURVE_DEV_CPU, 0);
3498static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point2_temp, fan_curve,
3499 FAN_CURVE_DEV_CPU, 1);
3500static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point3_temp, fan_curve,
3501 FAN_CURVE_DEV_CPU, 2);
3502static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point4_temp, fan_curve,
3503 FAN_CURVE_DEV_CPU, 3);
3504static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point5_temp, fan_curve,
3505 FAN_CURVE_DEV_CPU, 4);
3506static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point6_temp, fan_curve,
3507 FAN_CURVE_DEV_CPU, 5);
3508static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point7_temp, fan_curve,
3509 FAN_CURVE_DEV_CPU, 6);
3510static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point8_temp, fan_curve,
3511 FAN_CURVE_DEV_CPU, 7);
3512
3513static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point1_pwm, fan_curve,
3514 FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 0);
3515static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point2_pwm, fan_curve,
3516 FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 1);
3517static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point3_pwm, fan_curve,
3518 FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 2);
3519static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point4_pwm, fan_curve,
3520 FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 3);
3521static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point5_pwm, fan_curve,
3522 FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 4);
3523static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point6_pwm, fan_curve,
3524 FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 5);
3525static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point7_pwm, fan_curve,
3526 FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 6);
3527static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point8_pwm, fan_curve,
3528 FAN_CURVE_DEV_CPU | FAN_CURVE_PWM_MASK, 7);
3529
3530/* GPU */
3531static SENSOR_DEVICE_ATTR_RW(pwm2_enable, fan_curve_enable, FAN_CURVE_DEV_GPU);
3532static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point1_temp, fan_curve,
3533 FAN_CURVE_DEV_GPU, 0);
3534static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point2_temp, fan_curve,
3535 FAN_CURVE_DEV_GPU, 1);
3536static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point3_temp, fan_curve,
3537 FAN_CURVE_DEV_GPU, 2);
3538static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point4_temp, fan_curve,
3539 FAN_CURVE_DEV_GPU, 3);
3540static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point5_temp, fan_curve,
3541 FAN_CURVE_DEV_GPU, 4);
3542static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point6_temp, fan_curve,
3543 FAN_CURVE_DEV_GPU, 5);
3544static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point7_temp, fan_curve,
3545 FAN_CURVE_DEV_GPU, 6);
3546static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point8_temp, fan_curve,
3547 FAN_CURVE_DEV_GPU, 7);
3548
3549static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point1_pwm, fan_curve,
3550 FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 0);
3551static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point2_pwm, fan_curve,
3552 FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 1);
3553static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point3_pwm, fan_curve,
3554 FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 2);
3555static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point4_pwm, fan_curve,
3556 FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 3);
3557static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point5_pwm, fan_curve,
3558 FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 4);
3559static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point6_pwm, fan_curve,
3560 FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 5);
3561static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point7_pwm, fan_curve,
3562 FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 6);
3563static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point8_pwm, fan_curve,
3564 FAN_CURVE_DEV_GPU | FAN_CURVE_PWM_MASK, 7);
3565
3566/* MID */
3567static SENSOR_DEVICE_ATTR_RW(pwm3_enable, fan_curve_enable, FAN_CURVE_DEV_MID);
3568static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point1_temp, fan_curve,
3569 FAN_CURVE_DEV_MID, 0);
3570static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point2_temp, fan_curve,
3571 FAN_CURVE_DEV_MID, 1);
3572static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point3_temp, fan_curve,
3573 FAN_CURVE_DEV_MID, 2);
3574static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point4_temp, fan_curve,
3575 FAN_CURVE_DEV_MID, 3);
3576static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point5_temp, fan_curve,
3577 FAN_CURVE_DEV_MID, 4);
3578static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point6_temp, fan_curve,
3579 FAN_CURVE_DEV_MID, 5);
3580static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point7_temp, fan_curve,
3581 FAN_CURVE_DEV_MID, 6);
3582static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point8_temp, fan_curve,
3583 FAN_CURVE_DEV_MID, 7);
3584
3585static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point1_pwm, fan_curve,
3586 FAN_CURVE_DEV_MID | FAN_CURVE_PWM_MASK, 0);
3587static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point2_pwm, fan_curve,
3588 FAN_CURVE_DEV_MID | FAN_CURVE_PWM_MASK, 1);
3589static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point3_pwm, fan_curve,
3590 FAN_CURVE_DEV_MID | FAN_CURVE_PWM_MASK, 2);
3591static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point4_pwm, fan_curve,
3592 FAN_CURVE_DEV_MID | FAN_CURVE_PWM_MASK, 3);
3593static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point5_pwm, fan_curve,
3594 FAN_CURVE_DEV_MID | FAN_CURVE_PWM_MASK, 4);
3595static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point6_pwm, fan_curve,
3596 FAN_CURVE_DEV_MID | FAN_CURVE_PWM_MASK, 5);
3597static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point7_pwm, fan_curve,
3598 FAN_CURVE_DEV_MID | FAN_CURVE_PWM_MASK, 6);
3599static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point8_pwm, fan_curve,
3600 FAN_CURVE_DEV_MID | FAN_CURVE_PWM_MASK, 7);
3601
3602static struct attribute *asus_fan_curve_attr[] = {
3603 /* CPU */
3604 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
3605 &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
3606 &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
3607 &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
3608 &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
3609 &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr,
3610 &sensor_dev_attr_pwm1_auto_point6_temp.dev_attr.attr,
3611 &sensor_dev_attr_pwm1_auto_point7_temp.dev_attr.attr,
3612 &sensor_dev_attr_pwm1_auto_point8_temp.dev_attr.attr,
3613 &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
3614 &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
3615 &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
3616 &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr,
3617 &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr,
3618 &sensor_dev_attr_pwm1_auto_point6_pwm.dev_attr.attr,
3619 &sensor_dev_attr_pwm1_auto_point7_pwm.dev_attr.attr,
3620 &sensor_dev_attr_pwm1_auto_point8_pwm.dev_attr.attr,
3621 /* GPU */
3622 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
3623 &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr,
3624 &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
3625 &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
3626 &sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr,
3627 &sensor_dev_attr_pwm2_auto_point5_temp.dev_attr.attr,
3628 &sensor_dev_attr_pwm2_auto_point6_temp.dev_attr.attr,
3629 &sensor_dev_attr_pwm2_auto_point7_temp.dev_attr.attr,
3630 &sensor_dev_attr_pwm2_auto_point8_temp.dev_attr.attr,
3631 &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
3632 &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
3633 &sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr,
3634 &sensor_dev_attr_pwm2_auto_point4_pwm.dev_attr.attr,
3635 &sensor_dev_attr_pwm2_auto_point5_pwm.dev_attr.attr,
3636 &sensor_dev_attr_pwm2_auto_point6_pwm.dev_attr.attr,
3637 &sensor_dev_attr_pwm2_auto_point7_pwm.dev_attr.attr,
3638 &sensor_dev_attr_pwm2_auto_point8_pwm.dev_attr.attr,
3639 /* MID */
3640 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
3641 &sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr,
3642 &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr,
3643 &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr,
3644 &sensor_dev_attr_pwm3_auto_point4_temp.dev_attr.attr,
3645 &sensor_dev_attr_pwm3_auto_point5_temp.dev_attr.attr,
3646 &sensor_dev_attr_pwm3_auto_point6_temp.dev_attr.attr,
3647 &sensor_dev_attr_pwm3_auto_point7_temp.dev_attr.attr,
3648 &sensor_dev_attr_pwm3_auto_point8_temp.dev_attr.attr,
3649 &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
3650 &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
3651 &sensor_dev_attr_pwm3_auto_point3_pwm.dev_attr.attr,
3652 &sensor_dev_attr_pwm3_auto_point4_pwm.dev_attr.attr,
3653 &sensor_dev_attr_pwm3_auto_point5_pwm.dev_attr.attr,
3654 &sensor_dev_attr_pwm3_auto_point6_pwm.dev_attr.attr,
3655 &sensor_dev_attr_pwm3_auto_point7_pwm.dev_attr.attr,
3656 &sensor_dev_attr_pwm3_auto_point8_pwm.dev_attr.attr,
3657 NULL
3658};
3659
3660static umode_t asus_fan_curve_is_visible(struct kobject *kobj,
3661 struct attribute *attr, int idx)
3662{
3663 struct device *dev = kobj_to_dev(kobj);
3664 struct asus_wmi *asus = dev_get_drvdata(dev: dev->parent);
3665
3666 /*
3667 * Check the char instead of casting attr as there are two attr types
3668 * involved here (attr1 and attr2)
3669 */
3670 if (asus->cpu_fan_curve_available && attr->name[3] == '1')
3671 return 0644;
3672
3673 if (asus->gpu_fan_curve_available && attr->name[3] == '2')
3674 return 0644;
3675
3676 if (asus->mid_fan_curve_available && attr->name[3] == '3')
3677 return 0644;
3678
3679 return 0;
3680}
3681
3682static const struct attribute_group asus_fan_curve_attr_group = {
3683 .is_visible = asus_fan_curve_is_visible,
3684 .attrs = asus_fan_curve_attr,
3685};
3686__ATTRIBUTE_GROUPS(asus_fan_curve_attr);
3687
3688/*
3689 * Must be initialised after throttle_thermal_policy_dev is set as
3690 * we check the status of throttle_thermal_policy_dev during init.
3691 */
3692static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)
3693{
3694 struct device *dev = &asus->platform_device->dev;
3695 struct device *hwmon;
3696 int err;
3697
3698 err = fan_curve_check_present(asus, available: &asus->cpu_fan_curve_available,
3699 ASUS_WMI_DEVID_CPU_FAN_CURVE);
3700 if (err) {
3701 pr_debug("%s, checked 0x%08x, failed: %d\n",
3702 __func__, ASUS_WMI_DEVID_CPU_FAN_CURVE, err);
3703 return err;
3704 }
3705
3706 err = fan_curve_check_present(asus, available: &asus->gpu_fan_curve_available,
3707 ASUS_WMI_DEVID_GPU_FAN_CURVE);
3708 if (err) {
3709 pr_debug("%s, checked 0x%08x, failed: %d\n",
3710 __func__, ASUS_WMI_DEVID_GPU_FAN_CURVE, err);
3711 return err;
3712 }
3713
3714 err = fan_curve_check_present(asus, available: &asus->mid_fan_curve_available,
3715 ASUS_WMI_DEVID_MID_FAN_CURVE);
3716 if (err) {
3717 pr_debug("%s, checked 0x%08x, failed: %d\n",
3718 __func__, ASUS_WMI_DEVID_MID_FAN_CURVE, err);
3719 return err;
3720 }
3721
3722 if (!asus->cpu_fan_curve_available
3723 && !asus->gpu_fan_curve_available
3724 && !asus->mid_fan_curve_available)
3725 return 0;
3726
3727 hwmon = devm_hwmon_device_register_with_groups(
3728 dev, name: "asus_custom_fan_curve", drvdata: asus, groups: asus_fan_curve_attr_groups);
3729
3730 if (IS_ERR(ptr: hwmon)) {
3731 dev_err(dev,
3732 "Could not register asus_custom_fan_curve device\n");
3733 return PTR_ERR(ptr: hwmon);
3734 }
3735
3736 return 0;
3737}
3738
3739/* Throttle thermal policy ****************************************************/
3740static int throttle_thermal_policy_write(struct asus_wmi *asus)
3741{
3742 u8 value;
3743 int err;
3744
3745 if (asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO) {
3746 switch (asus->throttle_thermal_policy_mode) {
3747 case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT:
3748 value = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO;
3749 break;
3750 case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST:
3751 value = ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO;
3752 break;
3753 case ASUS_THROTTLE_THERMAL_POLICY_SILENT:
3754 value = ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO;
3755 break;
3756 default:
3757 return -EINVAL;
3758 }
3759 } else {
3760 value = asus->throttle_thermal_policy_mode;
3761 }
3762
3763 /* Some machines do not return an error code as a result, so we ignore it */
3764 err = asus_wmi_set_devstate(dev_id: asus->throttle_thermal_policy_dev, ctrl_param: value, NULL);
3765
3766 sysfs_notify(kobj: &asus->platform_device->dev.kobj, NULL,
3767 attr: "throttle_thermal_policy");
3768
3769 if (err) {
3770 pr_warn("Failed to set throttle thermal policy: %d\n", err);
3771 return err;
3772 }
3773
3774 /* Must set to disabled if mode is toggled */
3775 if (asus->cpu_fan_curve_available)
3776 asus->custom_fan_curves[FAN_CURVE_DEV_CPU].enabled = false;
3777 if (asus->gpu_fan_curve_available)
3778 asus->custom_fan_curves[FAN_CURVE_DEV_GPU].enabled = false;
3779 if (asus->mid_fan_curve_available)
3780 asus->custom_fan_curves[FAN_CURVE_DEV_MID].enabled = false;
3781
3782 return 0;
3783}
3784
3785static int throttle_thermal_policy_set_default(struct asus_wmi *asus)
3786{
3787 if (!asus->throttle_thermal_policy_dev)
3788 return 0;
3789
3790 asus->throttle_thermal_policy_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
3791 return throttle_thermal_policy_write(asus);
3792}
3793
3794static ssize_t throttle_thermal_policy_show(struct device *dev,
3795 struct device_attribute *attr, char *buf)
3796{
3797 struct asus_wmi *asus = dev_get_drvdata(dev);
3798 u8 mode = asus->throttle_thermal_policy_mode;
3799
3800 return sysfs_emit(buf, fmt: "%d\n", mode);
3801}
3802
3803static ssize_t throttle_thermal_policy_store(struct device *dev,
3804 struct device_attribute *attr,
3805 const char *buf, size_t count)
3806{
3807 struct asus_wmi *asus = dev_get_drvdata(dev);
3808 u8 new_mode;
3809 int result;
3810 int err;
3811
3812 result = kstrtou8(s: buf, base: 10, res: &new_mode);
3813 if (result < 0)
3814 return result;
3815
3816 if (new_mode > PLATFORM_PROFILE_MAX)
3817 return -EINVAL;
3818
3819 asus->throttle_thermal_policy_mode = new_mode;
3820 err = throttle_thermal_policy_write(asus);
3821 if (err)
3822 return err;
3823
3824 /*
3825 * Ensure that platform_profile updates userspace with the change to ensure
3826 * that platform_profile and throttle_thermal_policy_mode are in sync.
3827 */
3828 platform_profile_notify(dev: asus->ppdev);
3829
3830 return count;
3831}
3832
3833/*
3834 * Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
3835 */
3836static DEVICE_ATTR_RW(throttle_thermal_policy);
3837
3838/* Platform profile ***********************************************************/
3839static int asus_wmi_platform_profile_get(struct device *dev,
3840 enum platform_profile_option *profile)
3841{
3842 struct asus_wmi *asus;
3843 int tp;
3844
3845 asus = dev_get_drvdata(dev);
3846 tp = asus->throttle_thermal_policy_mode;
3847
3848 switch (tp) {
3849 case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT:
3850 *profile = PLATFORM_PROFILE_BALANCED;
3851 break;
3852 case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST:
3853 *profile = PLATFORM_PROFILE_PERFORMANCE;
3854 break;
3855 case ASUS_THROTTLE_THERMAL_POLICY_SILENT:
3856 *profile = PLATFORM_PROFILE_QUIET;
3857 break;
3858 default:
3859 return -EINVAL;
3860 }
3861
3862 return 0;
3863}
3864
3865static int asus_wmi_platform_profile_set(struct device *dev,
3866 enum platform_profile_option profile)
3867{
3868 struct asus_wmi *asus;
3869 int tp;
3870
3871 asus = dev_get_drvdata(dev);
3872
3873 switch (profile) {
3874 case PLATFORM_PROFILE_PERFORMANCE:
3875 tp = ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST;
3876 break;
3877 case PLATFORM_PROFILE_BALANCED:
3878 tp = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
3879 break;
3880 case PLATFORM_PROFILE_QUIET:
3881 tp = ASUS_THROTTLE_THERMAL_POLICY_SILENT;
3882 break;
3883 default:
3884 return -EOPNOTSUPP;
3885 }
3886
3887 asus->throttle_thermal_policy_mode = tp;
3888 return throttle_thermal_policy_write(asus);
3889}
3890
3891static int asus_wmi_platform_profile_probe(void *drvdata, unsigned long *choices)
3892{
3893 set_bit(nr: PLATFORM_PROFILE_QUIET, addr: choices);
3894 set_bit(nr: PLATFORM_PROFILE_BALANCED, addr: choices);
3895 set_bit(nr: PLATFORM_PROFILE_PERFORMANCE, addr: choices);
3896
3897 return 0;
3898}
3899
3900static const struct platform_profile_ops asus_wmi_platform_profile_ops = {
3901 .probe = asus_wmi_platform_profile_probe,
3902 .profile_get = asus_wmi_platform_profile_get,
3903 .profile_set = asus_wmi_platform_profile_set,
3904};
3905
3906static int platform_profile_setup(struct asus_wmi *asus)
3907{
3908 struct device *dev = &asus->platform_device->dev;
3909 int err;
3910
3911 /*
3912 * Not an error if a component platform_profile relies on is unavailable
3913 * so early return, skipping the setup of platform_profile.
3914 */
3915 if (!asus->throttle_thermal_policy_dev)
3916 return 0;
3917
3918 /*
3919 * We need to set the default thermal profile during probe or otherwise
3920 * the system will often remain in silent mode, causing low performance.
3921 */
3922 err = throttle_thermal_policy_set_default(asus);
3923 if (err < 0) {
3924 pr_warn("Failed to set default thermal profile\n");
3925 return err;
3926 }
3927
3928 dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n");
3929
3930 asus->ppdev = devm_platform_profile_register(dev, name: "asus-wmi", drvdata: asus,
3931 ops: &asus_wmi_platform_profile_ops);
3932 if (IS_ERR(ptr: asus->ppdev)) {
3933 dev_err(dev, "Failed to register a platform_profile class device\n");
3934 return PTR_ERR(ptr: asus->ppdev);
3935 }
3936
3937 asus->platform_profile_support = true;
3938 return 0;
3939}
3940
3941/* Backlight ******************************************************************/
3942
3943static int read_backlight_power(struct asus_wmi *asus)
3944{
3945 int ret;
3946
3947 if (asus->driver->quirks->store_backlight_power)
3948 ret = !asus->driver->panel_power;
3949 else
3950 ret = asus_wmi_get_devstate_simple(asus,
3951 ASUS_WMI_DEVID_BACKLIGHT);
3952
3953 if (ret < 0)
3954 return ret;
3955
3956 return ret ? BACKLIGHT_POWER_ON : BACKLIGHT_POWER_OFF;
3957}
3958
3959static int read_brightness_max(struct asus_wmi *asus)
3960{
3961 u32 retval;
3962 int err;
3963
3964 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, retval: &retval);
3965 if (err < 0)
3966 return err;
3967
3968 retval = retval & ASUS_WMI_DSTS_MAX_BRIGTH_MASK;
3969 retval >>= 8;
3970
3971 if (!retval)
3972 return -ENODEV;
3973
3974 return retval;
3975}
3976
3977static int read_brightness(struct backlight_device *bd)
3978{
3979 struct asus_wmi *asus = bl_get_data(bl_dev: bd);
3980 u32 retval;
3981 int err;
3982
3983 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, retval: &retval);
3984 if (err < 0)
3985 return err;
3986
3987 return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
3988}
3989
3990static u32 get_scalar_command(struct backlight_device *bd)
3991{
3992 struct asus_wmi *asus = bl_get_data(bl_dev: bd);
3993 u32 ctrl_param = 0;
3994
3995 if ((asus->driver->brightness < bd->props.brightness) ||
3996 bd->props.brightness == bd->props.max_brightness)
3997 ctrl_param = 0x00008001;
3998 else if ((asus->driver->brightness > bd->props.brightness) ||
3999 bd->props.brightness == 0)
4000 ctrl_param = 0x00008000;
4001
4002 asus->driver->brightness = bd->props.brightness;
4003
4004 return ctrl_param;
4005}
4006
4007static int update_bl_status(struct backlight_device *bd)
4008{
4009 struct asus_wmi *asus = bl_get_data(bl_dev: bd);
4010 u32 ctrl_param;
4011 int power, err = 0;
4012
4013 power = read_backlight_power(asus);
4014 if (power != -ENODEV && bd->props.power != power) {
4015 ctrl_param = !!(bd->props.power == BACKLIGHT_POWER_ON);
4016 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT,
4017 ctrl_param, NULL);
4018 if (asus->driver->quirks->store_backlight_power)
4019 asus->driver->panel_power = bd->props.power;
4020
4021 /* When using scalar brightness, updating the brightness
4022 * will mess with the backlight power */
4023 if (asus->driver->quirks->scalar_panel_brightness)
4024 return err;
4025 }
4026
4027 if (asus->driver->quirks->scalar_panel_brightness)
4028 ctrl_param = get_scalar_command(bd);
4029 else
4030 ctrl_param = bd->props.brightness;
4031
4032 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS,
4033 ctrl_param, NULL);
4034
4035 return err;
4036}
4037
4038static const struct backlight_ops asus_wmi_bl_ops = {
4039 .get_brightness = read_brightness,
4040 .update_status = update_bl_status,
4041};
4042
4043static int asus_wmi_backlight_notify(struct asus_wmi *asus, int code)
4044{
4045 struct backlight_device *bd = asus->backlight_device;
4046 int old = bd->props.brightness;
4047 int new = old;
4048
4049 if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
4050 new = code - NOTIFY_BRNUP_MIN + 1;
4051 else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
4052 new = code - NOTIFY_BRNDOWN_MIN;
4053
4054 bd->props.brightness = new;
4055 backlight_update_status(bd);
4056 backlight_force_update(bd, reason: BACKLIGHT_UPDATE_HOTKEY);
4057
4058 return old;
4059}
4060
4061static int asus_wmi_backlight_init(struct asus_wmi *asus)
4062{
4063 struct backlight_device *bd;
4064 struct backlight_properties props;
4065 int max;
4066 int power;
4067
4068 max = read_brightness_max(asus);
4069 if (max < 0)
4070 return max;
4071
4072 power = read_backlight_power(asus);
4073 if (power == -ENODEV)
4074 power = BACKLIGHT_POWER_ON;
4075 else if (power < 0)
4076 return power;
4077
4078 memset(&props, 0, sizeof(struct backlight_properties));
4079 props.type = BACKLIGHT_PLATFORM;
4080 props.max_brightness = max;
4081 bd = backlight_device_register(name: asus->driver->name,
4082 dev: &asus->platform_device->dev, devdata: asus,
4083 ops: &asus_wmi_bl_ops, props: &props);
4084 if (IS_ERR(ptr: bd)) {
4085 pr_err("Could not register backlight device\n");
4086 return PTR_ERR(ptr: bd);
4087 }
4088
4089 asus->backlight_device = bd;
4090
4091 if (asus->driver->quirks->store_backlight_power)
4092 asus->driver->panel_power = power;
4093
4094 bd->props.brightness = read_brightness(bd);
4095 bd->props.power = power;
4096 backlight_update_status(bd);
4097
4098 asus->driver->brightness = bd->props.brightness;
4099
4100 return 0;
4101}
4102
4103static void asus_wmi_backlight_exit(struct asus_wmi *asus)
4104{
4105 backlight_device_unregister(bd: asus->backlight_device);
4106
4107 asus->backlight_device = NULL;
4108}
4109
4110static int is_display_toggle(int code)
4111{
4112 /* display toggle keys */
4113 if ((code >= 0x61 && code <= 0x67) ||
4114 (code >= 0x8c && code <= 0x93) ||
4115 (code >= 0xa0 && code <= 0xa7) ||
4116 (code >= 0xd0 && code <= 0xd5))
4117 return 1;
4118
4119 return 0;
4120}
4121
4122/* Screenpad backlight *******************************************************/
4123
4124static int read_screenpad_backlight_power(struct asus_wmi *asus)
4125{
4126 int ret;
4127
4128 ret = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_SCREENPAD_POWER);
4129 if (ret < 0)
4130 return ret;
4131 /* 1 == powered */
4132 return ret ? BACKLIGHT_POWER_ON : BACKLIGHT_POWER_OFF;
4133}
4134
4135static int read_screenpad_brightness(struct backlight_device *bd)
4136{
4137 struct asus_wmi *asus = bl_get_data(bl_dev: bd);
4138 u32 retval;
4139 int err;
4140
4141 err = read_screenpad_backlight_power(asus);
4142 if (err < 0)
4143 return err;
4144 /* The device brightness can only be read if powered, so return stored */
4145 if (err == BACKLIGHT_POWER_OFF)
4146 return asus->driver->screenpad_brightness - ASUS_SCREENPAD_BRIGHT_MIN;
4147
4148 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_SCREENPAD_LIGHT, retval: &retval);
4149 if (err < 0)
4150 return err;
4151
4152 return (retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK) - ASUS_SCREENPAD_BRIGHT_MIN;
4153}
4154
4155static int update_screenpad_bl_status(struct backlight_device *bd)
4156{
4157 struct asus_wmi *asus = bl_get_data(bl_dev: bd);
4158 int power, err = 0;
4159 u32 ctrl_param;
4160
4161 power = read_screenpad_backlight_power(asus);
4162 if (power < 0)
4163 return power;
4164
4165 if (bd->props.power != power) {
4166 if (power != BACKLIGHT_POWER_ON) {
4167 /* Only brightness > 0 can power it back on */
4168 ctrl_param = asus->driver->screenpad_brightness - ASUS_SCREENPAD_BRIGHT_MIN;
4169 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_SCREENPAD_LIGHT,
4170 ctrl_param, NULL);
4171 } else {
4172 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_SCREENPAD_POWER, ctrl_param: 0, NULL);
4173 }
4174 } else if (power == BACKLIGHT_POWER_ON) {
4175 /* Only set brightness if powered on or we get invalid/unsync state */
4176 ctrl_param = bd->props.brightness + ASUS_SCREENPAD_BRIGHT_MIN;
4177 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_SCREENPAD_LIGHT, ctrl_param, NULL);
4178 }
4179
4180 /* Ensure brightness is stored to turn back on with */
4181 if (err == 0)
4182 asus->driver->screenpad_brightness = bd->props.brightness + ASUS_SCREENPAD_BRIGHT_MIN;
4183
4184 return err;
4185}
4186
4187static const struct backlight_ops asus_screenpad_bl_ops = {
4188 .get_brightness = read_screenpad_brightness,
4189 .update_status = update_screenpad_bl_status,
4190 .options = BL_CORE_SUSPENDRESUME,
4191};
4192
4193static int asus_screenpad_init(struct asus_wmi *asus)
4194{
4195 struct backlight_device *bd;
4196 struct backlight_properties props;
4197 int err, power;
4198 int brightness = 0;
4199
4200 power = read_screenpad_backlight_power(asus);
4201 if (power < 0)
4202 return power;
4203
4204 if (power != BACKLIGHT_POWER_OFF) {
4205 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_SCREENPAD_LIGHT, retval: &brightness);
4206 if (err < 0)
4207 return err;
4208 }
4209 /* default to an acceptable min brightness on boot if too low */
4210 if (brightness < ASUS_SCREENPAD_BRIGHT_MIN)
4211 brightness = ASUS_SCREENPAD_BRIGHT_DEFAULT;
4212
4213 memset(&props, 0, sizeof(struct backlight_properties));
4214 props.type = BACKLIGHT_RAW; /* ensure this bd is last to be picked */
4215 props.max_brightness = ASUS_SCREENPAD_BRIGHT_MAX - ASUS_SCREENPAD_BRIGHT_MIN;
4216 bd = backlight_device_register(name: "asus_screenpad",
4217 dev: &asus->platform_device->dev, devdata: asus,
4218 ops: &asus_screenpad_bl_ops, props: &props);
4219 if (IS_ERR(ptr: bd)) {
4220 pr_err("Could not register backlight device\n");
4221 return PTR_ERR(ptr: bd);
4222 }
4223
4224 asus->screenpad_backlight_device = bd;
4225 asus->driver->screenpad_brightness = brightness;
4226 bd->props.brightness = brightness - ASUS_SCREENPAD_BRIGHT_MIN;
4227 bd->props.power = power;
4228 backlight_update_status(bd);
4229
4230 return 0;
4231}
4232
4233static void asus_screenpad_exit(struct asus_wmi *asus)
4234{
4235 backlight_device_unregister(bd: asus->screenpad_backlight_device);
4236
4237 asus->screenpad_backlight_device = NULL;
4238}
4239
4240/* Fn-lock ********************************************************************/
4241
4242static bool asus_wmi_has_fnlock_key(struct asus_wmi *asus)
4243{
4244 u32 result;
4245
4246 asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FNLOCK, retval: &result);
4247
4248 return (result & ASUS_WMI_DSTS_PRESENCE_BIT) &&
4249 !(result & ASUS_WMI_FNLOCK_BIOS_DISABLED);
4250}
4251
4252static void asus_wmi_fnlock_update(struct asus_wmi *asus)
4253{
4254 int mode = asus->fnlock_locked;
4255
4256 asus_wmi_set_devstate(ASUS_WMI_DEVID_FNLOCK, ctrl_param: mode, NULL);
4257}
4258
4259/* WMI events *****************************************************************/
4260
4261static int asus_wmi_get_event_code(union acpi_object *obj)
4262{
4263 int code;
4264
4265 if (obj && obj->type == ACPI_TYPE_INTEGER)
4266 code = (int)(obj->integer.value & WMI_EVENT_MASK);
4267 else
4268 code = -EIO;
4269
4270 return code;
4271}
4272
4273static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
4274{
4275 unsigned int key_value = 1;
4276 bool autorelease = 1;
4277
4278 if (asus->driver->key_filter) {
4279 asus->driver->key_filter(asus->driver, &code, &key_value,
4280 &autorelease);
4281 if (code == ASUS_WMI_KEY_IGNORE)
4282 return;
4283 }
4284
4285 if (acpi_video_get_backlight_type() == acpi_backlight_vendor &&
4286 code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNDOWN_MAX) {
4287 asus_wmi_backlight_notify(asus, code);
4288 return;
4289 }
4290
4291 if (code == NOTIFY_KBD_BRTUP) {
4292 kbd_led_set_by_kbd(asus, value: asus->kbd_led_wk + 1);
4293 return;
4294 }
4295 if (code == NOTIFY_KBD_BRTDWN) {
4296 kbd_led_set_by_kbd(asus, value: asus->kbd_led_wk - 1);
4297 return;
4298 }
4299 if (code == NOTIFY_KBD_BRTTOGGLE) {
4300 if (asus->kbd_led_wk == asus->kbd_led.max_brightness)
4301 kbd_led_set_by_kbd(asus, value: 0);
4302 else
4303 kbd_led_set_by_kbd(asus, value: asus->kbd_led_wk + 1);
4304 return;
4305 }
4306
4307 if (code == NOTIFY_FNLOCK_TOGGLE) {
4308 asus->fnlock_locked = !asus->fnlock_locked;
4309 asus_wmi_fnlock_update(asus);
4310 return;
4311 }
4312
4313 if (code == asus->tablet_switch_event_code) {
4314 asus_wmi_tablet_mode_get_state(asus);
4315 return;
4316 }
4317
4318 if (code == NOTIFY_KBD_FBM || code == NOTIFY_KBD_TTP) {
4319 if (asus->fan_boost_mode_available)
4320 fan_boost_mode_switch_next(asus);
4321 if (asus->throttle_thermal_policy_dev)
4322 platform_profile_cycle();
4323 return;
4324
4325 }
4326
4327 if (is_display_toggle(code) && asus->driver->quirks->no_display_toggle)
4328 return;
4329
4330 if (!sparse_keymap_report_event(dev: asus->inputdev, code,
4331 value: key_value, autorelease))
4332 pr_info("Unknown key code 0x%x\n", code);
4333}
4334
4335static void asus_wmi_notify(union acpi_object *obj, void *context)
4336{
4337 struct asus_wmi *asus = context;
4338 int code = asus_wmi_get_event_code(obj);
4339
4340 if (code < 0) {
4341 pr_warn("Failed to get notify code: %d\n", code);
4342 return;
4343 }
4344
4345 asus_wmi_handle_event_code(code, asus);
4346}
4347
4348/* Sysfs **********************************************************************/
4349
4350static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid,
4351 const char *buf, size_t count)
4352{
4353 u32 retval;
4354 int err, value;
4355
4356 value = asus_wmi_get_devstate_simple(asus, dev_id: devid);
4357 if (value < 0)
4358 return value;
4359
4360 err = kstrtoint(s: buf, base: 0, res: &value);
4361 if (err)
4362 return err;
4363
4364 err = asus_wmi_set_devstate(dev_id: devid, ctrl_param: value, retval: &retval);
4365 if (err < 0)
4366 return err;
4367
4368 return count;
4369}
4370
4371static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf)
4372{
4373 int value = asus_wmi_get_devstate_simple(asus, dev_id: devid);
4374
4375 if (value < 0)
4376 return value;
4377
4378 return sysfs_emit(buf, fmt: "%d\n", value);
4379}
4380
4381#define ASUS_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm) \
4382 static ssize_t show_##_name(struct device *dev, \
4383 struct device_attribute *attr, \
4384 char *buf) \
4385 { \
4386 struct asus_wmi *asus = dev_get_drvdata(dev); \
4387 \
4388 return show_sys_wmi(asus, _cm, buf); \
4389 } \
4390 static ssize_t store_##_name(struct device *dev, \
4391 struct device_attribute *attr, \
4392 const char *buf, size_t count) \
4393 { \
4394 struct asus_wmi *asus = dev_get_drvdata(dev); \
4395 \
4396 return store_sys_wmi(asus, _cm, buf, count); \
4397 } \
4398 static struct device_attribute dev_attr_##_name = { \
4399 .attr = { \
4400 .name = __stringify(_name), \
4401 .mode = _mode }, \
4402 .show = show_##_name, \
4403 .store = store_##_name, \
4404 }
4405
4406ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD);
4407ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA);
4408ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER);
4409ASUS_WMI_CREATE_DEVICE_ATTR(lid_resume, 0644, ASUS_WMI_DEVID_LID_RESUME);
4410ASUS_WMI_CREATE_DEVICE_ATTR(als_enable, 0644, ASUS_WMI_DEVID_ALS_ENABLE);
4411
4412static ssize_t cpufv_store(struct device *dev, struct device_attribute *attr,
4413 const char *buf, size_t count)
4414{
4415 int value, rv;
4416
4417 rv = kstrtoint(s: buf, base: 0, res: &value);
4418 if (rv)
4419 return rv;
4420
4421 if (value < 0 || value > 2)
4422 return -EINVAL;
4423
4424 rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL);
4425 if (rv < 0)
4426 return rv;
4427
4428 return count;
4429}
4430
4431static DEVICE_ATTR_WO(cpufv);
4432
4433static struct attribute *platform_attributes[] = {
4434 &dev_attr_cpufv.attr,
4435 &dev_attr_camera.attr,
4436 &dev_attr_cardr.attr,
4437 &dev_attr_touchpad.attr,
4438 &dev_attr_charge_mode.attr,
4439 &dev_attr_egpu_enable.attr,
4440 &dev_attr_egpu_connected.attr,
4441 &dev_attr_dgpu_disable.attr,
4442 &dev_attr_gpu_mux_mode.attr,
4443 &dev_attr_lid_resume.attr,
4444 &dev_attr_als_enable.attr,
4445 &dev_attr_fan_boost_mode.attr,
4446 &dev_attr_throttle_thermal_policy.attr,
4447 &dev_attr_ppt_pl2_sppt.attr,
4448 &dev_attr_ppt_pl1_spl.attr,
4449 &dev_attr_ppt_fppt.attr,
4450 &dev_attr_ppt_apu_sppt.attr,
4451 &dev_attr_ppt_platform_sppt.attr,
4452 &dev_attr_nv_dynamic_boost.attr,
4453 &dev_attr_nv_temp_target.attr,
4454 &dev_attr_mcu_powersave.attr,
4455 &dev_attr_boot_sound.attr,
4456 &dev_attr_panel_od.attr,
4457 &dev_attr_mini_led_mode.attr,
4458 &dev_attr_available_mini_led_mode.attr,
4459 NULL
4460};
4461
4462static umode_t asus_sysfs_is_visible(struct kobject *kobj,
4463 struct attribute *attr, int idx)
4464{
4465 struct device *dev = kobj_to_dev(kobj);
4466 struct asus_wmi *asus = dev_get_drvdata(dev);
4467 bool ok = true;
4468 int devid = -1;
4469
4470 if (attr == &dev_attr_camera.attr)
4471 devid = ASUS_WMI_DEVID_CAMERA;
4472 else if (attr == &dev_attr_cardr.attr)
4473 devid = ASUS_WMI_DEVID_CARDREADER;
4474 else if (attr == &dev_attr_touchpad.attr)
4475 devid = ASUS_WMI_DEVID_TOUCHPAD;
4476 else if (attr == &dev_attr_lid_resume.attr)
4477 devid = ASUS_WMI_DEVID_LID_RESUME;
4478 else if (attr == &dev_attr_als_enable.attr)
4479 devid = ASUS_WMI_DEVID_ALS_ENABLE;
4480 else if (attr == &dev_attr_charge_mode.attr)
4481 devid = ASUS_WMI_DEVID_CHARGE_MODE;
4482 else if (attr == &dev_attr_egpu_enable.attr)
4483 ok = asus->egpu_enable_available;
4484 else if (attr == &dev_attr_egpu_connected.attr)
4485 devid = ASUS_WMI_DEVID_EGPU_CONNECTED;
4486 else if (attr == &dev_attr_dgpu_disable.attr)
4487 ok = asus->dgpu_disable_available;
4488 else if (attr == &dev_attr_gpu_mux_mode.attr)
4489 ok = asus->gpu_mux_dev != 0;
4490 else if (attr == &dev_attr_fan_boost_mode.attr)
4491 ok = asus->fan_boost_mode_available;
4492 else if (attr == &dev_attr_throttle_thermal_policy.attr)
4493 ok = asus->throttle_thermal_policy_dev != 0;
4494 else if (attr == &dev_attr_ppt_pl2_sppt.attr)
4495 devid = ASUS_WMI_DEVID_PPT_PL2_SPPT;
4496 else if (attr == &dev_attr_ppt_pl1_spl.attr)
4497 devid = ASUS_WMI_DEVID_PPT_PL1_SPL;
4498 else if (attr == &dev_attr_ppt_fppt.attr)
4499 devid = ASUS_WMI_DEVID_PPT_FPPT;
4500 else if (attr == &dev_attr_ppt_apu_sppt.attr)
4501 devid = ASUS_WMI_DEVID_PPT_APU_SPPT;
4502 else if (attr == &dev_attr_ppt_platform_sppt.attr)
4503 devid = ASUS_WMI_DEVID_PPT_PLAT_SPPT;
4504 else if (attr == &dev_attr_nv_dynamic_boost.attr)
4505 devid = ASUS_WMI_DEVID_NV_DYN_BOOST;
4506 else if (attr == &dev_attr_nv_temp_target.attr)
4507 devid = ASUS_WMI_DEVID_NV_THERM_TARGET;
4508 else if (attr == &dev_attr_mcu_powersave.attr)
4509 devid = ASUS_WMI_DEVID_MCU_POWERSAVE;
4510 else if (attr == &dev_attr_boot_sound.attr)
4511 devid = ASUS_WMI_DEVID_BOOT_SOUND;
4512 else if (attr == &dev_attr_panel_od.attr)
4513 devid = ASUS_WMI_DEVID_PANEL_OD;
4514 else if (attr == &dev_attr_mini_led_mode.attr)
4515 ok = asus->mini_led_dev_id != 0;
4516 else if (attr == &dev_attr_available_mini_led_mode.attr)
4517 ok = asus->mini_led_dev_id != 0;
4518
4519 if (devid != -1) {
4520 ok = !(asus_wmi_get_devstate_simple(asus, dev_id: devid) < 0);
4521 pr_debug("%s called 0x%08x, ok: %x\n", __func__, devid, ok);
4522 }
4523
4524 return ok ? attr->mode : 0;
4525}
4526
4527static const struct attribute_group platform_attribute_group = {
4528 .is_visible = asus_sysfs_is_visible,
4529 .attrs = platform_attributes
4530};
4531
4532static void asus_wmi_sysfs_exit(struct platform_device *device)
4533{
4534 sysfs_remove_group(kobj: &device->dev.kobj, grp: &platform_attribute_group);
4535}
4536
4537static int asus_wmi_sysfs_init(struct platform_device *device)
4538{
4539 return sysfs_create_group(kobj: &device->dev.kobj, grp: &platform_attribute_group);
4540}
4541
4542/* Platform device ************************************************************/
4543
4544static int asus_wmi_platform_init(struct asus_wmi *asus)
4545{
4546 struct device *dev = &asus->platform_device->dev;
4547 char *wmi_uid;
4548 int rv;
4549
4550 /* INIT enable hotkeys on some models */
4551 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv))
4552 pr_info("Initialization: %#x\n", rv);
4553
4554 /* We don't know yet what to do with this version... */
4555 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) {
4556 pr_info("BIOS WMI version: %d.%d\n", rv >> 16, rv & 0xFF);
4557 asus->spec = rv;
4558 }
4559
4560 /*
4561 * The SFUN method probably allows the original driver to get the list
4562 * of features supported by a given model. For now, 0x0100 or 0x0800
4563 * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
4564 * The significance of others is yet to be found.
4565 */
4566 if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) {
4567 pr_info("SFUN value: %#x\n", rv);
4568 asus->sfun = rv;
4569 }
4570
4571 /*
4572 * Eee PC and Notebooks seems to have different method_id for DSTS,
4573 * but it may also be related to the BIOS's SPEC.
4574 * Note, on most Eeepc, there is no way to check if a method exist
4575 * or note, while on notebooks, they returns 0xFFFFFFFE on failure,
4576 * but once again, SPEC may probably be used for that kind of things.
4577 *
4578 * Additionally at least TUF Gaming series laptops return nothing for
4579 * unknown methods, so the detection in this way is not possible.
4580 *
4581 * There is strong indication that only ACPI WMI devices that have _UID
4582 * equal to "ASUSWMI" use DCTS whereas those with "ATK" use DSTS.
4583 */
4584 wmi_uid = wmi_get_acpi_device_uid(ASUS_WMI_MGMT_GUID);
4585 if (!wmi_uid)
4586 return -ENODEV;
4587
4588 if (!strcmp(wmi_uid, ASUS_ACPI_UID_ASUSWMI)) {
4589 dev_info(dev, "Detected ASUSWMI, use DCTS\n");
4590 asus->dsts_id = ASUS_WMI_METHODID_DCTS;
4591 } else {
4592 dev_info(dev, "Detected %s, not ASUSWMI, use DSTS\n", wmi_uid);
4593 asus->dsts_id = ASUS_WMI_METHODID_DSTS;
4594 }
4595
4596 /* CWAP allow to define the behavior of the Fn+F2 key,
4597 * this method doesn't seems to be present on Eee PCs */
4598 if (asus->driver->quirks->wapf >= 0)
4599 asus_wmi_set_devstate(ASUS_WMI_DEVID_CWAP,
4600 ctrl_param: asus->driver->quirks->wapf, NULL);
4601
4602 return 0;
4603}
4604
4605/* debugfs ********************************************************************/
4606
4607struct asus_wmi_debugfs_node {
4608 struct asus_wmi *asus;
4609 char *name;
4610 int (*show) (struct seq_file *m, void *data);
4611};
4612
4613static int show_dsts(struct seq_file *m, void *data)
4614{
4615 struct asus_wmi *asus = m->private;
4616 int err;
4617 u32 retval = -1;
4618
4619 err = asus_wmi_get_devstate(asus, dev_id: asus->debug.dev_id, retval: &retval);
4620 if (err < 0)
4621 return err;
4622
4623 seq_printf(m, fmt: "DSTS(%#x) = %#x\n", asus->debug.dev_id, retval);
4624
4625 return 0;
4626}
4627
4628static int show_devs(struct seq_file *m, void *data)
4629{
4630 struct asus_wmi *asus = m->private;
4631 int err;
4632 u32 retval = -1;
4633
4634 err = asus_wmi_set_devstate(dev_id: asus->debug.dev_id, ctrl_param: asus->debug.ctrl_param,
4635 retval: &retval);
4636 if (err < 0)
4637 return err;
4638
4639 seq_printf(m, fmt: "DEVS(%#x, %#x) = %#x\n", asus->debug.dev_id,
4640 asus->debug.ctrl_param, retval);
4641
4642 return 0;
4643}
4644
4645static int show_call(struct seq_file *m, void *data)
4646{
4647 struct asus_wmi *asus = m->private;
4648 struct bios_args args = {
4649 .arg0 = asus->debug.dev_id,
4650 .arg1 = asus->debug.ctrl_param,
4651 };
4652 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
4653 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
4654 union acpi_object *obj;
4655 acpi_status status;
4656
4657 status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
4658 instance: 0, method_id: asus->debug.method_id,
4659 in: &input, out: &output);
4660
4661 if (ACPI_FAILURE(status))
4662 return -EIO;
4663
4664 obj = (union acpi_object *)output.pointer;
4665 if (obj && obj->type == ACPI_TYPE_INTEGER)
4666 seq_printf(m, fmt: "%#x(%#x, %#x) = %#x\n", asus->debug.method_id,
4667 asus->debug.dev_id, asus->debug.ctrl_param,
4668 (u32) obj->integer.value);
4669 else
4670 seq_printf(m, fmt: "%#x(%#x, %#x) = t:%d\n", asus->debug.method_id,
4671 asus->debug.dev_id, asus->debug.ctrl_param,
4672 obj ? obj->type : -1);
4673
4674 kfree(objp: obj);
4675
4676 return 0;
4677}
4678
4679static struct asus_wmi_debugfs_node asus_wmi_debug_files[] = {
4680 {NULL, "devs", show_devs},
4681 {NULL, "dsts", show_dsts},
4682 {NULL, "call", show_call},
4683};
4684
4685static int asus_wmi_debugfs_open(struct inode *inode, struct file *file)
4686{
4687 struct asus_wmi_debugfs_node *node = inode->i_private;
4688
4689 return single_open(file, node->show, node->asus);
4690}
4691
4692static const struct file_operations asus_wmi_debugfs_io_ops = {
4693 .owner = THIS_MODULE,
4694 .open = asus_wmi_debugfs_open,
4695 .read = seq_read,
4696 .llseek = seq_lseek,
4697 .release = single_release,
4698};
4699
4700static void asus_wmi_debugfs_exit(struct asus_wmi *asus)
4701{
4702 debugfs_remove_recursive(dentry: asus->debug.root);
4703}
4704
4705static void asus_wmi_debugfs_init(struct asus_wmi *asus)
4706{
4707 int i;
4708
4709 asus->debug.root = debugfs_create_dir(name: asus->driver->name, NULL);
4710
4711 debugfs_create_x32(name: "method_id", S_IRUGO | S_IWUSR, parent: asus->debug.root,
4712 value: &asus->debug.method_id);
4713
4714 debugfs_create_x32(name: "dev_id", S_IRUGO | S_IWUSR, parent: asus->debug.root,
4715 value: &asus->debug.dev_id);
4716
4717 debugfs_create_x32(name: "ctrl_param", S_IRUGO | S_IWUSR, parent: asus->debug.root,
4718 value: &asus->debug.ctrl_param);
4719
4720 for (i = 0; i < ARRAY_SIZE(asus_wmi_debug_files); i++) {
4721 struct asus_wmi_debugfs_node *node = &asus_wmi_debug_files[i];
4722
4723 node->asus = asus;
4724 debugfs_create_file(node->name, S_IFREG | S_IRUGO,
4725 asus->debug.root, node,
4726 &asus_wmi_debugfs_io_ops);
4727 }
4728}
4729
4730/* Init / exit ****************************************************************/
4731
4732static int asus_wmi_add(struct platform_device *pdev)
4733{
4734 struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
4735 struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
4736 struct asus_wmi *asus;
4737 acpi_status status;
4738 int err;
4739 u32 result;
4740
4741 asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL);
4742 if (!asus)
4743 return -ENOMEM;
4744
4745 asus->driver = wdrv;
4746 asus->platform_device = pdev;
4747 wdrv->platform_device = pdev;
4748 platform_set_drvdata(pdev: asus->platform_device, data: asus);
4749
4750 if (wdrv->detect_quirks)
4751 wdrv->detect_quirks(asus->driver);
4752
4753 err = asus_wmi_platform_init(asus);
4754 if (err)
4755 goto fail_platform;
4756
4757 if (use_ally_mcu_hack == ASUS_WMI_ALLY_MCU_HACK_INIT) {
4758 if (acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
4759 && dmi_check_system(list: asus_rog_ally_device))
4760 use_ally_mcu_hack = ASUS_WMI_ALLY_MCU_HACK_ENABLED;
4761 if (dmi_match(f: DMI_BOARD_NAME, str: "RC71")) {
4762 /*
4763 * These steps ensure the device is in a valid good state, this is
4764 * especially important for the Ally 1 after a reboot.
4765 */
4766 acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE,
4767 ASUS_USB0_PWR_EC0_CSEE_ON);
4768 msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
4769 }
4770 }
4771
4772 /* ensure defaults for tunables */
4773 asus->ppt_pl2_sppt = 5;
4774 asus->ppt_pl1_spl = 5;
4775 asus->ppt_apu_sppt = 5;
4776 asus->ppt_platform_sppt = 5;
4777 asus->ppt_fppt = 5;
4778 asus->nv_dynamic_boost = 5;
4779 asus->nv_temp_target = 75;
4780
4781 asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
4782 asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
4783 asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE);
4784 asus->oobe_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_OOBE);
4785
4786 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE))
4787 asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE;
4788 else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE2))
4789 asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2;
4790
4791 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX))
4792 asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX;
4793 else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX_VIVO))
4794 asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX_VIVO;
4795
4796 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE))
4797 asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE;
4798 else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE2))
4799 asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE2;
4800
4801 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY))
4802 asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY;
4803 else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO))
4804 asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
4805
4806 err = fan_boost_mode_check_present(asus);
4807 if (err)
4808 goto fail_fan_boost_mode;
4809
4810 err = platform_profile_setup(asus);
4811 if (err)
4812 goto fail_platform_profile_setup;
4813
4814 err = asus_wmi_sysfs_init(device: asus->platform_device);
4815 if (err)
4816 goto fail_sysfs;
4817
4818 err = asus_wmi_input_init(asus);
4819 if (err)
4820 goto fail_input;
4821
4822 err = asus_wmi_fan_init(asus); /* probably no problems on error */
4823
4824 err = asus_wmi_hwmon_init(asus);
4825 if (err)
4826 goto fail_hwmon;
4827
4828 err = asus_wmi_custom_fan_curve_init(asus);
4829 if (err)
4830 goto fail_custom_fan_curve;
4831
4832 err = asus_wmi_led_init(asus);
4833 if (err)
4834 goto fail_leds;
4835
4836 asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, retval: &result);
4837 if ((result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) ==
4838 (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
4839 asus->driver->wlan_ctrl_by_user = 1;
4840
4841 if (!(asus->driver->wlan_ctrl_by_user && ashs_present())) {
4842 err = asus_wmi_rfkill_init(asus);
4843 if (err)
4844 goto fail_rfkill;
4845 }
4846
4847 if (asus->driver->quirks->wmi_force_als_set)
4848 asus_wmi_set_als();
4849
4850 if (asus->driver->quirks->xusb2pr)
4851 asus_wmi_set_xusb2pr(asus);
4852
4853 if (acpi_video_get_backlight_type() == acpi_backlight_vendor) {
4854 err = asus_wmi_backlight_init(asus);
4855 if (err && err != -ENODEV)
4856 goto fail_backlight;
4857 } else if (asus->driver->quirks->wmi_backlight_set_devstate)
4858 err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT, ctrl_param: 2, NULL);
4859
4860 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_SCREENPAD_LIGHT)) {
4861 err = asus_screenpad_init(asus);
4862 if (err && err != -ENODEV)
4863 goto fail_screenpad;
4864 }
4865
4866 if (asus_wmi_has_fnlock_key(asus)) {
4867 asus->fnlock_locked = fnlock_default;
4868 asus_wmi_fnlock_update(asus);
4869 }
4870
4871 status = wmi_install_notify_handler(guid: asus->driver->event_guid,
4872 handler: asus_wmi_notify, data: asus);
4873 if (ACPI_FAILURE(status)) {
4874 pr_err("Unable to register notify handler - %d\n", status);
4875 err = -ENODEV;
4876 goto fail_wmi_handler;
4877 }
4878
4879 if (asus->driver->i8042_filter) {
4880 err = i8042_install_filter(filter: asus->driver->i8042_filter, NULL);
4881 if (err)
4882 pr_warn("Unable to install key filter - %d\n", err);
4883 }
4884
4885 asus_wmi_battery_init(asus);
4886
4887 asus_wmi_debugfs_init(asus);
4888
4889 return 0;
4890
4891fail_wmi_handler:
4892 asus_wmi_backlight_exit(asus);
4893fail_backlight:
4894 asus_wmi_rfkill_exit(asus);
4895fail_screenpad:
4896 asus_screenpad_exit(asus);
4897fail_rfkill:
4898 asus_wmi_led_exit(asus);
4899fail_leds:
4900fail_hwmon:
4901 asus_wmi_input_exit(asus);
4902fail_input:
4903 asus_wmi_sysfs_exit(device: asus->platform_device);
4904fail_sysfs:
4905fail_custom_fan_curve:
4906fail_platform_profile_setup:
4907fail_fan_boost_mode:
4908fail_platform:
4909 kfree(objp: asus);
4910 return err;
4911}
4912
4913static void asus_wmi_remove(struct platform_device *device)
4914{
4915 struct asus_wmi *asus;
4916
4917 asus = platform_get_drvdata(pdev: device);
4918 if (asus->driver->i8042_filter)
4919 i8042_remove_filter(filter: asus->driver->i8042_filter);
4920 wmi_remove_notify_handler(guid: asus->driver->event_guid);
4921 asus_wmi_backlight_exit(asus);
4922 asus_screenpad_exit(asus);
4923 asus_wmi_input_exit(asus);
4924 asus_wmi_led_exit(asus);
4925 asus_wmi_rfkill_exit(asus);
4926 asus_wmi_debugfs_exit(asus);
4927 asus_wmi_sysfs_exit(device: asus->platform_device);
4928 asus_fan_set_auto(asus);
4929 throttle_thermal_policy_set_default(asus);
4930 asus_wmi_battery_exit(asus);
4931
4932 kfree(objp: asus);
4933}
4934
4935/* Platform driver - hibernate/resume callbacks *******************************/
4936
4937static int asus_hotk_thaw(struct device *device)
4938{
4939 struct asus_wmi *asus = dev_get_drvdata(dev: device);
4940
4941 if (asus->wlan.rfkill) {
4942 bool wlan;
4943
4944 /*
4945 * Work around bios bug - acpi _PTS turns off the wireless led
4946 * during suspend. Normally it restores it on resume, but
4947 * we should kick it ourselves in case hibernation is aborted.
4948 */
4949 wlan = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
4950 asus_wmi_set_devstate(ASUS_WMI_DEVID_WLAN, ctrl_param: wlan, NULL);
4951 }
4952
4953 return 0;
4954}
4955
4956static int asus_hotk_resume(struct device *device)
4957{
4958 struct asus_wmi *asus = dev_get_drvdata(dev: device);
4959
4960 if (!IS_ERR_OR_NULL(ptr: asus->kbd_led.dev))
4961 kbd_led_update(asus);
4962
4963 if (asus_wmi_has_fnlock_key(asus))
4964 asus_wmi_fnlock_update(asus);
4965
4966 asus_wmi_tablet_mode_get_state(asus);
4967
4968 return 0;
4969}
4970
4971static int asus_hotk_restore(struct device *device)
4972{
4973 struct asus_wmi *asus = dev_get_drvdata(dev: device);
4974 int bl;
4975
4976 /* Refresh both wlan rfkill state and pci hotplug */
4977 if (asus->wlan.rfkill)
4978 asus_rfkill_hotplug(asus);
4979
4980 if (asus->bluetooth.rfkill) {
4981 bl = !asus_wmi_get_devstate_simple(asus,
4982 ASUS_WMI_DEVID_BLUETOOTH);
4983 rfkill_set_sw_state(rfkill: asus->bluetooth.rfkill, blocked: bl);
4984 }
4985 if (asus->wimax.rfkill) {
4986 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WIMAX);
4987 rfkill_set_sw_state(rfkill: asus->wimax.rfkill, blocked: bl);
4988 }
4989 if (asus->wwan3g.rfkill) {
4990 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G);
4991 rfkill_set_sw_state(rfkill: asus->wwan3g.rfkill, blocked: bl);
4992 }
4993 if (asus->gps.rfkill) {
4994 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPS);
4995 rfkill_set_sw_state(rfkill: asus->gps.rfkill, blocked: bl);
4996 }
4997 if (asus->uwb.rfkill) {
4998 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_UWB);
4999 rfkill_set_sw_state(rfkill: asus->uwb.rfkill, blocked: bl);
5000 }
5001 if (!IS_ERR_OR_NULL(ptr: asus->kbd_led.dev))
5002 kbd_led_update(asus);
5003 if (asus->oobe_state_available) {
5004 /*
5005 * Disable OOBE state, so that e.g. the keyboard backlight
5006 * works.
5007 */
5008 asus_wmi_set_devstate(ASUS_WMI_DEVID_OOBE, ctrl_param: 1, NULL);
5009 }
5010
5011 if (asus_wmi_has_fnlock_key(asus))
5012 asus_wmi_fnlock_update(asus);
5013
5014 asus_wmi_tablet_mode_get_state(asus);
5015 return 0;
5016}
5017
5018static int asus_hotk_prepare(struct device *device)
5019{
5020 if (use_ally_mcu_hack == ASUS_WMI_ALLY_MCU_HACK_ENABLED) {
5021 acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE,
5022 ASUS_USB0_PWR_EC0_CSEE_OFF);
5023 msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
5024 }
5025 return 0;
5026}
5027
5028#if defined(CONFIG_SUSPEND)
5029static void asus_ally_s2idle_restore(void)
5030{
5031 if (use_ally_mcu_hack == ASUS_WMI_ALLY_MCU_HACK_ENABLED) {
5032 acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE,
5033 ASUS_USB0_PWR_EC0_CSEE_ON);
5034 msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
5035 }
5036}
5037
5038/* Use only for Ally devices due to the wake_on_ac */
5039static struct acpi_s2idle_dev_ops asus_ally_s2idle_dev_ops = {
5040 .restore = asus_ally_s2idle_restore,
5041};
5042
5043static void asus_s2idle_check_register(void)
5044{
5045 if (acpi_register_lps0_dev(arg: &asus_ally_s2idle_dev_ops))
5046 pr_warn("failed to register LPS0 sleep handler in asus-wmi\n");
5047}
5048
5049static void asus_s2idle_check_unregister(void)
5050{
5051 acpi_unregister_lps0_dev(arg: &asus_ally_s2idle_dev_ops);
5052}
5053#else
5054static void asus_s2idle_check_register(void) {}
5055static void asus_s2idle_check_unregister(void) {}
5056#endif /* CONFIG_SUSPEND */
5057
5058static const struct dev_pm_ops asus_pm_ops = {
5059 .thaw = asus_hotk_thaw,
5060 .restore = asus_hotk_restore,
5061 .resume = asus_hotk_resume,
5062 .prepare = asus_hotk_prepare,
5063};
5064
5065/* Registration ***************************************************************/
5066
5067static int asus_wmi_probe(struct platform_device *pdev)
5068{
5069 struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
5070 struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
5071 int ret;
5072
5073 if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
5074 pr_warn("ASUS Management GUID not found\n");
5075 return -ENODEV;
5076 }
5077
5078 if (wdrv->event_guid && !wmi_has_guid(guid: wdrv->event_guid)) {
5079 pr_warn("ASUS Event GUID not found\n");
5080 return -ENODEV;
5081 }
5082
5083 if (wdrv->probe) {
5084 ret = wdrv->probe(pdev);
5085 if (ret)
5086 return ret;
5087 }
5088
5089 asus_s2idle_check_register();
5090
5091 return asus_wmi_add(pdev);
5092}
5093
5094static bool used;
5095
5096int __init_or_module asus_wmi_register_driver(struct asus_wmi_driver *driver)
5097{
5098 struct platform_driver *platform_driver;
5099 struct platform_device *platform_device;
5100
5101 if (used)
5102 return -EBUSY;
5103
5104 platform_driver = &driver->platform_driver;
5105 platform_driver->remove = asus_wmi_remove;
5106 platform_driver->driver.owner = driver->owner;
5107 platform_driver->driver.name = driver->name;
5108 platform_driver->driver.pm = &asus_pm_ops;
5109
5110 platform_device = platform_create_bundle(platform_driver,
5111 asus_wmi_probe,
5112 NULL, 0, NULL, 0);
5113 if (IS_ERR(ptr: platform_device))
5114 return PTR_ERR(ptr: platform_device);
5115
5116 used = true;
5117 return 0;
5118}
5119EXPORT_SYMBOL_GPL(asus_wmi_register_driver);
5120
5121void asus_wmi_unregister_driver(struct asus_wmi_driver *driver)
5122{
5123 asus_s2idle_check_unregister();
5124
5125 platform_device_unregister(driver->platform_device);
5126 platform_driver_unregister(&driver->platform_driver);
5127 used = false;
5128}
5129EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver);
5130
5131static int __init asus_wmi_init(void)
5132{
5133 pr_info("ASUS WMI generic driver loaded\n");
5134 return 0;
5135}
5136
5137static void __exit asus_wmi_exit(void)
5138{
5139 pr_info("ASUS WMI generic driver unloaded\n");
5140}
5141
5142module_init(asus_wmi_init);
5143module_exit(asus_wmi_exit);
5144

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of linux/drivers/platform/x86/asus-wmi.c