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

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