1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * HP WMI hotkeys
4 *
5 * Copyright (C) 2008 Red Hat <mjg@redhat.com>
6 * Copyright (C) 2010, 2011 Anssi Hannula <anssi.hannula@iki.fi>
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/kernel.h>
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/slab.h>
20 #include <linux/types.h>
21 #include <linux/input.h>
22 #include <linux/input/sparse-keymap.h>
23 #include <linux/platform_device.h>
24 #include <linux/platform_profile.h>
25 #include <linux/hwmon.h>
26 #include <linux/acpi.h>
27 #include <linux/mutex.h>
28 #include <linux/cleanup.h>
29 #include <linux/power_supply.h>
30 #include <linux/rfkill.h>
31 #include <linux/string.h>
32 #include <linux/dmi.h>
33
34 MODULE_AUTHOR("Matthew Garrett <mjg59@srcf.ucam.org>");
35 MODULE_DESCRIPTION("HP laptop WMI driver");
36 MODULE_LICENSE("GPL");
37
38 MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C");
39 MODULE_ALIAS("wmi:5FB7F034-2C63-45E9-BE91-3D44E2C707E4");
40
41 #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
42 #define HPWMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4"
43
44 #define HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET 0x62
45 #define HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET 0x63
46 #define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95
47
48 #define HP_FAN_SPEED_AUTOMATIC 0x00
49 #define HP_POWER_LIMIT_DEFAULT 0x00
50 #define HP_POWER_LIMIT_NO_CHANGE 0xFF
51
52 #define ACPI_AC_CLASS "ac_adapter"
53
54 #define zero_if_sup(tmp) (zero_insize_support?0:sizeof(tmp)) // use when zero insize is required
55
56 /* DMI board names of devices that should use the omen specific path for
57 * thermal profiles.
58 * This was obtained by taking a look in the windows omen command center
59 * app and parsing a json file that they use to figure out what capabilities
60 * the device should have.
61 * A device is considered an omen if the DisplayName in that list contains
62 * "OMEN", and it can use the thermal profile stuff if the "Feature" array
63 * contains "PerformanceControl".
64 */
65 static const char * const omen_thermal_profile_boards[] = {
66 "84DA", "84DB", "84DC", "8574", "8575", "860A", "87B5", "8572", "8573",
67 "8600", "8601", "8602", "8605", "8606", "8607", "8746", "8747", "8749",
68 "874A", "8603", "8604", "8748", "886B", "886C", "878A", "878B", "878C",
69 "88C8", "88CB", "8786", "8787", "8788", "88D1", "88D2", "88F4", "88FD",
70 "88F5", "88F6", "88F7", "88FE", "88FF", "8900", "8901", "8902", "8912",
71 "8917", "8918", "8949", "894A", "89EB", "8BAD", "8A42", "8A15"
72 };
73
74 /* DMI Board names of Omen laptops that are specifically set to be thermal
75 * profile version 0 by the Omen Command Center app, regardless of what
76 * the get system design information WMI call returns
77 */
78 static const char * const omen_thermal_profile_force_v0_boards[] = {
79 "8607", "8746", "8747", "8749", "874A", "8748"
80 };
81
82 /* DMI board names of Omen laptops that have a thermal profile timer which will
83 * cause the embedded controller to set the thermal profile back to
84 * "balanced" when reaching zero.
85 */
86 static const char * const omen_timed_thermal_profile_boards[] = {
87 "8BAD", "8A42", "8A15"
88 };
89
90 /* DMI Board names of Victus 16-d1xxx laptops */
91 static const char * const victus_thermal_profile_boards[] = {
92 "8A25"
93 };
94
95 /* DMI Board names of Victus 16-r1000 and Victus 16-s1000 laptops */
96 static const char * const victus_s_thermal_profile_boards[] = {
97 "8C99", "8C9C"
98 };
99
100 enum hp_wmi_radio {
101 HPWMI_WIFI = 0x0,
102 HPWMI_BLUETOOTH = 0x1,
103 HPWMI_WWAN = 0x2,
104 HPWMI_GPS = 0x3,
105 };
106
107 enum hp_wmi_event_ids {
108 HPWMI_DOCK_EVENT = 0x01,
109 HPWMI_PARK_HDD = 0x02,
110 HPWMI_SMART_ADAPTER = 0x03,
111 HPWMI_BEZEL_BUTTON = 0x04,
112 HPWMI_WIRELESS = 0x05,
113 HPWMI_CPU_BATTERY_THROTTLE = 0x06,
114 HPWMI_LOCK_SWITCH = 0x07,
115 HPWMI_LID_SWITCH = 0x08,
116 HPWMI_SCREEN_ROTATION = 0x09,
117 HPWMI_COOLSENSE_SYSTEM_MOBILE = 0x0A,
118 HPWMI_COOLSENSE_SYSTEM_HOT = 0x0B,
119 HPWMI_PROXIMITY_SENSOR = 0x0C,
120 HPWMI_BACKLIT_KB_BRIGHTNESS = 0x0D,
121 HPWMI_PEAKSHIFT_PERIOD = 0x0F,
122 HPWMI_BATTERY_CHARGE_PERIOD = 0x10,
123 HPWMI_SANITIZATION_MODE = 0x17,
124 HPWMI_CAMERA_TOGGLE = 0x1A,
125 HPWMI_FN_P_HOTKEY = 0x1B,
126 HPWMI_OMEN_KEY = 0x1D,
127 HPWMI_SMART_EXPERIENCE_APP = 0x21,
128 };
129
130 /*
131 * struct bios_args buffer is dynamically allocated. New WMI command types
132 * were introduced that exceeds 128-byte data size. Changes to handle
133 * the data size allocation scheme were kept in hp_wmi_perform_qurey function.
134 */
135 struct bios_args {
136 u32 signature;
137 u32 command;
138 u32 commandtype;
139 u32 datasize;
140 u8 data[];
141 };
142
143 enum hp_wmi_commandtype {
144 HPWMI_DISPLAY_QUERY = 0x01,
145 HPWMI_HDDTEMP_QUERY = 0x02,
146 HPWMI_ALS_QUERY = 0x03,
147 HPWMI_HARDWARE_QUERY = 0x04,
148 HPWMI_WIRELESS_QUERY = 0x05,
149 HPWMI_BATTERY_QUERY = 0x07,
150 HPWMI_BIOS_QUERY = 0x09,
151 HPWMI_FEATURE_QUERY = 0x0b,
152 HPWMI_HOTKEY_QUERY = 0x0c,
153 HPWMI_FEATURE2_QUERY = 0x0d,
154 HPWMI_WIRELESS2_QUERY = 0x1b,
155 HPWMI_POSTCODEERROR_QUERY = 0x2a,
156 HPWMI_SYSTEM_DEVICE_MODE = 0x40,
157 HPWMI_THERMAL_PROFILE_QUERY = 0x4c,
158 };
159
160 struct victus_power_limits {
161 u8 pl1;
162 u8 pl2;
163 u8 pl4;
164 u8 cpu_gpu_concurrent_limit;
165 };
166
167 struct victus_gpu_power_modes {
168 u8 ctgp_enable;
169 u8 ppab_enable;
170 u8 dstate;
171 u8 gpu_slowdown_temp;
172 };
173
174 enum hp_wmi_gm_commandtype {
175 HPWMI_FAN_SPEED_GET_QUERY = 0x11,
176 HPWMI_SET_PERFORMANCE_MODE = 0x1A,
177 HPWMI_FAN_SPEED_MAX_GET_QUERY = 0x26,
178 HPWMI_FAN_SPEED_MAX_SET_QUERY = 0x27,
179 HPWMI_GET_SYSTEM_DESIGN_DATA = 0x28,
180 HPWMI_FAN_COUNT_GET_QUERY = 0x10,
181 HPWMI_GET_GPU_THERMAL_MODES_QUERY = 0x21,
182 HPWMI_SET_GPU_THERMAL_MODES_QUERY = 0x22,
183 HPWMI_SET_POWER_LIMITS_QUERY = 0x29,
184 HPWMI_VICTUS_S_FAN_SPEED_GET_QUERY = 0x2D,
185 HPWMI_FAN_SPEED_SET_QUERY = 0x2E,
186 };
187
188 enum hp_wmi_command {
189 HPWMI_READ = 0x01,
190 HPWMI_WRITE = 0x02,
191 HPWMI_ODM = 0x03,
192 HPWMI_GM = 0x20008,
193 };
194
195 enum hp_wmi_hardware_mask {
196 HPWMI_DOCK_MASK = 0x01,
197 HPWMI_TABLET_MASK = 0x04,
198 };
199
200 struct bios_return {
201 u32 sigpass;
202 u32 return_code;
203 };
204
205 enum hp_return_value {
206 HPWMI_RET_WRONG_SIGNATURE = 0x02,
207 HPWMI_RET_UNKNOWN_COMMAND = 0x03,
208 HPWMI_RET_UNKNOWN_CMDTYPE = 0x04,
209 HPWMI_RET_INVALID_PARAMETERS = 0x05,
210 };
211
212 enum hp_wireless2_bits {
213 HPWMI_POWER_STATE = 0x01,
214 HPWMI_POWER_SOFT = 0x02,
215 HPWMI_POWER_BIOS = 0x04,
216 HPWMI_POWER_HARD = 0x08,
217 HPWMI_POWER_FW_OR_HW = HPWMI_POWER_BIOS | HPWMI_POWER_HARD,
218 };
219
220 enum hp_thermal_profile_omen_v0 {
221 HP_OMEN_V0_THERMAL_PROFILE_DEFAULT = 0x00,
222 HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE = 0x01,
223 HP_OMEN_V0_THERMAL_PROFILE_COOL = 0x02,
224 };
225
226 enum hp_thermal_profile_omen_v1 {
227 HP_OMEN_V1_THERMAL_PROFILE_DEFAULT = 0x30,
228 HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE = 0x31,
229 HP_OMEN_V1_THERMAL_PROFILE_COOL = 0x50,
230 };
231
232 enum hp_thermal_profile_omen_flags {
233 HP_OMEN_EC_FLAGS_TURBO = 0x04,
234 HP_OMEN_EC_FLAGS_NOTIMER = 0x02,
235 HP_OMEN_EC_FLAGS_JUSTSET = 0x01,
236 };
237
238 enum hp_thermal_profile_victus {
239 HP_VICTUS_THERMAL_PROFILE_DEFAULT = 0x00,
240 HP_VICTUS_THERMAL_PROFILE_PERFORMANCE = 0x01,
241 HP_VICTUS_THERMAL_PROFILE_QUIET = 0x03,
242 };
243
244 enum hp_thermal_profile_victus_s {
245 HP_VICTUS_S_THERMAL_PROFILE_DEFAULT = 0x00,
246 HP_VICTUS_S_THERMAL_PROFILE_PERFORMANCE = 0x01,
247 };
248
249 enum hp_thermal_profile {
250 HP_THERMAL_PROFILE_PERFORMANCE = 0x00,
251 HP_THERMAL_PROFILE_DEFAULT = 0x01,
252 HP_THERMAL_PROFILE_COOL = 0x02,
253 HP_THERMAL_PROFILE_QUIET = 0x03,
254 };
255
256 #define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW)
257 #define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT)
258
259 struct bios_rfkill2_device_state {
260 u8 radio_type;
261 u8 bus_type;
262 u16 vendor_id;
263 u16 product_id;
264 u16 subsys_vendor_id;
265 u16 subsys_product_id;
266 u8 rfkill_id;
267 u8 power;
268 u8 unknown[4];
269 };
270
271 /* 7 devices fit into the 128 byte buffer */
272 #define HPWMI_MAX_RFKILL2_DEVICES 7
273
274 struct bios_rfkill2_state {
275 u8 unknown[7];
276 u8 count;
277 u8 pad[8];
278 struct bios_rfkill2_device_state device[HPWMI_MAX_RFKILL2_DEVICES];
279 };
280
281 static const struct key_entry hp_wmi_keymap[] = {
282 { KE_KEY, 0x02, { KEY_BRIGHTNESSUP } },
283 { KE_KEY, 0x03, { KEY_BRIGHTNESSDOWN } },
284 { KE_KEY, 0x270, { KEY_MICMUTE } },
285 { KE_KEY, 0x20e6, { KEY_PROG1 } },
286 { KE_KEY, 0x20e8, { KEY_MEDIA } },
287 { KE_KEY, 0x2142, { KEY_MEDIA } },
288 { KE_KEY, 0x213b, { KEY_INFO } },
289 { KE_KEY, 0x2169, { KEY_ROTATE_DISPLAY } },
290 { KE_KEY, 0x216a, { KEY_SETUP } },
291 { KE_IGNORE, 0x21a4, }, /* Win Lock On */
292 { KE_IGNORE, 0x121a4, }, /* Win Lock Off */
293 { KE_KEY, 0x21a5, { KEY_PROG2 } }, /* HP Omen Key */
294 { KE_KEY, 0x21a7, { KEY_FN_ESC } },
295 { KE_KEY, 0x21a8, { KEY_PROG2 } }, /* HP Envy x360 programmable key */
296 { KE_KEY, 0x21a9, { KEY_TOUCHPAD_OFF } },
297 { KE_KEY, 0x121a9, { KEY_TOUCHPAD_ON } },
298 { KE_KEY, 0x231b, { KEY_HELP } },
299 { KE_END, 0 }
300 };
301
302 /*
303 * Mutex for the active_platform_profile variable,
304 * see omen_powersource_event.
305 */
306 static DEFINE_MUTEX(active_platform_profile_lock);
307
308 static struct input_dev *hp_wmi_input_dev;
309 static struct input_dev *camera_shutter_input_dev;
310 static struct platform_device *hp_wmi_platform_dev;
311 static struct device *platform_profile_device;
312 static struct notifier_block platform_power_source_nb;
313 static enum platform_profile_option active_platform_profile;
314 static bool platform_profile_support;
315 static bool zero_insize_support;
316
317 static struct rfkill *wifi_rfkill;
318 static struct rfkill *bluetooth_rfkill;
319 static struct rfkill *wwan_rfkill;
320
321 struct rfkill2_device {
322 u8 id;
323 int num;
324 struct rfkill *rfkill;
325 };
326
327 static int rfkill2_count;
328 static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
329
330 /*
331 * Chassis Types values were obtained from SMBIOS reference
332 * specification version 3.00. A complete list of system enclosures
333 * and chassis types is available on Table 17.
334 */
335 static const char * const tablet_chassis_types[] = {
336 "30", /* Tablet*/
337 "31", /* Convertible */
338 "32" /* Detachable */
339 };
340
341 #define DEVICE_MODE_TABLET 0x06
342
343 /* map output size to the corresponding WMI method id */
encode_outsize_for_pvsz(int outsize)344 static inline int encode_outsize_for_pvsz(int outsize)
345 {
346 if (outsize > 4096)
347 return -EINVAL;
348 if (outsize > 1024)
349 return 5;
350 if (outsize > 128)
351 return 4;
352 if (outsize > 4)
353 return 3;
354 if (outsize > 0)
355 return 2;
356 return 1;
357 }
358
359 /*
360 * hp_wmi_perform_query
361 *
362 * query: The commandtype (enum hp_wmi_commandtype)
363 * write: The command (enum hp_wmi_command)
364 * buffer: Buffer used as input and/or output
365 * insize: Size of input buffer
366 * outsize: Size of output buffer
367 *
368 * returns zero on success
369 * an HP WMI query specific error code (which is positive)
370 * -EINVAL if the query was not successful at all
371 * -EINVAL if the output buffer size exceeds buffersize
372 *
373 * Note: The buffersize must at least be the maximum of the input and output
374 * size. E.g. Battery info query is defined to have 1 byte input
375 * and 128 byte output. The caller would do:
376 * buffer = kzalloc(128, GFP_KERNEL);
377 * ret = hp_wmi_perform_query(HPWMI_BATTERY_QUERY, HPWMI_READ, buffer, 1, 128)
378 */
hp_wmi_perform_query(int query,enum hp_wmi_command command,void * buffer,int insize,int outsize)379 static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
380 void *buffer, int insize, int outsize)
381 {
382 struct acpi_buffer input, output = { ACPI_ALLOCATE_BUFFER, NULL };
383 struct bios_return *bios_return;
384 union acpi_object *obj = NULL;
385 struct bios_args *args = NULL;
386 int mid, actual_insize, actual_outsize;
387 size_t bios_args_size;
388 int ret;
389
390 mid = encode_outsize_for_pvsz(outsize);
391 if (WARN_ON(mid < 0))
392 return mid;
393
394 actual_insize = max(insize, 128);
395 bios_args_size = struct_size(args, data, actual_insize);
396 args = kmalloc(bios_args_size, GFP_KERNEL);
397 if (!args)
398 return -ENOMEM;
399
400 input.length = bios_args_size;
401 input.pointer = args;
402
403 args->signature = 0x55434553;
404 args->command = command;
405 args->commandtype = query;
406 args->datasize = insize;
407 memcpy(args->data, buffer, flex_array_size(args, data, insize));
408
409 ret = wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
410 if (ret)
411 goto out_free;
412
413 obj = output.pointer;
414 if (!obj) {
415 ret = -EINVAL;
416 goto out_free;
417 }
418
419 if (obj->type != ACPI_TYPE_BUFFER) {
420 pr_warn("query 0x%x returned an invalid object 0x%x\n", query, ret);
421 ret = -EINVAL;
422 goto out_free;
423 }
424
425 bios_return = (struct bios_return *)obj->buffer.pointer;
426 ret = bios_return->return_code;
427
428 if (ret) {
429 if (ret != HPWMI_RET_UNKNOWN_COMMAND &&
430 ret != HPWMI_RET_UNKNOWN_CMDTYPE)
431 pr_warn("query 0x%x returned error 0x%x\n", query, ret);
432 goto out_free;
433 }
434
435 /* Ignore output data of zero size */
436 if (!outsize)
437 goto out_free;
438
439 actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return)));
440 memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize);
441 memset(buffer + actual_outsize, 0, outsize - actual_outsize);
442
443 out_free:
444 kfree(obj);
445 kfree(args);
446 return ret;
447 }
448
449 /*
450 * Calling this hp_wmi_get_fan_count_userdefine_trigger function also enables
451 * and/or maintains the laptop in user defined thermal and fan states, instead
452 * of using a fallback state. After a 120 seconds timeout however, the laptop
453 * goes back to its fallback state.
454 */
hp_wmi_get_fan_count_userdefine_trigger(void)455 static int hp_wmi_get_fan_count_userdefine_trigger(void)
456 {
457 u8 fan_data[4] = {};
458 int ret;
459
460 ret = hp_wmi_perform_query(HPWMI_FAN_COUNT_GET_QUERY, HPWMI_GM,
461 &fan_data, sizeof(u8),
462 sizeof(fan_data));
463 if (ret != 0)
464 return -EINVAL;
465
466 return fan_data[0]; /* Others bytes aren't providing fan count */
467 }
468
hp_wmi_get_fan_speed(int fan)469 static int hp_wmi_get_fan_speed(int fan)
470 {
471 u8 fsh, fsl;
472 char fan_data[4] = { fan, 0, 0, 0 };
473
474 int ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_GET_QUERY, HPWMI_GM,
475 &fan_data, sizeof(char),
476 sizeof(fan_data));
477
478 if (ret != 0)
479 return -EINVAL;
480
481 fsh = fan_data[2];
482 fsl = fan_data[3];
483
484 return (fsh << 8) | fsl;
485 }
486
hp_wmi_get_fan_speed_victus_s(int fan)487 static int hp_wmi_get_fan_speed_victus_s(int fan)
488 {
489 u8 fan_data[128] = {};
490 int ret;
491
492 if (fan < 0 || fan >= sizeof(fan_data))
493 return -EINVAL;
494
495 ret = hp_wmi_perform_query(HPWMI_VICTUS_S_FAN_SPEED_GET_QUERY,
496 HPWMI_GM, &fan_data, sizeof(u8),
497 sizeof(fan_data));
498 if (ret != 0)
499 return -EINVAL;
500
501 return fan_data[fan] * 100;
502 }
503
hp_wmi_read_int(int query)504 static int hp_wmi_read_int(int query)
505 {
506 int val = 0, ret;
507
508 ret = hp_wmi_perform_query(query, HPWMI_READ, &val,
509 zero_if_sup(val), sizeof(val));
510
511 if (ret)
512 return ret < 0 ? ret : -EINVAL;
513
514 return val;
515 }
516
hp_wmi_get_dock_state(void)517 static int hp_wmi_get_dock_state(void)
518 {
519 int state = hp_wmi_read_int(HPWMI_HARDWARE_QUERY);
520
521 if (state < 0)
522 return state;
523
524 return !!(state & HPWMI_DOCK_MASK);
525 }
526
hp_wmi_get_tablet_mode(void)527 static int hp_wmi_get_tablet_mode(void)
528 {
529 char system_device_mode[4] = { 0 };
530 const char *chassis_type;
531 bool tablet_found;
532 int ret;
533
534 chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
535 if (!chassis_type)
536 return -ENODEV;
537
538 tablet_found = match_string(tablet_chassis_types,
539 ARRAY_SIZE(tablet_chassis_types),
540 chassis_type) >= 0;
541 if (!tablet_found)
542 return -ENODEV;
543
544 ret = hp_wmi_perform_query(HPWMI_SYSTEM_DEVICE_MODE, HPWMI_READ,
545 system_device_mode, zero_if_sup(system_device_mode),
546 sizeof(system_device_mode));
547 if (ret < 0)
548 return ret;
549
550 return system_device_mode[0] == DEVICE_MODE_TABLET;
551 }
552
omen_thermal_profile_set(int mode)553 static int omen_thermal_profile_set(int mode)
554 {
555 /* The Omen Control Center actively sets the first byte of the buffer to
556 * 255, so let's mimic this behaviour to be as close as possible to
557 * the original software.
558 */
559 char buffer[2] = {-1, mode};
560 int ret;
561
562 ret = hp_wmi_perform_query(HPWMI_SET_PERFORMANCE_MODE, HPWMI_GM,
563 &buffer, sizeof(buffer), 0);
564
565 if (ret)
566 return ret < 0 ? ret : -EINVAL;
567
568 return mode;
569 }
570
is_omen_thermal_profile(void)571 static bool is_omen_thermal_profile(void)
572 {
573 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
574
575 if (!board_name)
576 return false;
577
578 return match_string(omen_thermal_profile_boards,
579 ARRAY_SIZE(omen_thermal_profile_boards),
580 board_name) >= 0;
581 }
582
omen_get_thermal_policy_version(void)583 static int omen_get_thermal_policy_version(void)
584 {
585 unsigned char buffer[8] = { 0 };
586 int ret;
587
588 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
589
590 if (board_name) {
591 int matches = match_string(omen_thermal_profile_force_v0_boards,
592 ARRAY_SIZE(omen_thermal_profile_force_v0_boards),
593 board_name);
594 if (matches >= 0)
595 return 0;
596 }
597
598 ret = hp_wmi_perform_query(HPWMI_GET_SYSTEM_DESIGN_DATA, HPWMI_GM,
599 &buffer, sizeof(buffer), sizeof(buffer));
600
601 if (ret)
602 return ret < 0 ? ret : -EINVAL;
603
604 return buffer[3];
605 }
606
omen_thermal_profile_get(void)607 static int omen_thermal_profile_get(void)
608 {
609 u8 data;
610
611 int ret = ec_read(HP_OMEN_EC_THERMAL_PROFILE_OFFSET, &data);
612
613 if (ret)
614 return ret;
615
616 return data;
617 }
618
hp_wmi_fan_speed_max_set(int enabled)619 static int hp_wmi_fan_speed_max_set(int enabled)
620 {
621 int ret;
622
623 ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_SET_QUERY, HPWMI_GM,
624 &enabled, sizeof(enabled), 0);
625
626 if (ret)
627 return ret < 0 ? ret : -EINVAL;
628
629 return enabled;
630 }
631
hp_wmi_fan_speed_reset(void)632 static int hp_wmi_fan_speed_reset(void)
633 {
634 u8 fan_speed[2] = { HP_FAN_SPEED_AUTOMATIC, HP_FAN_SPEED_AUTOMATIC };
635 int ret;
636
637 ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_SET_QUERY, HPWMI_GM,
638 &fan_speed, sizeof(fan_speed), 0);
639
640 return ret;
641 }
642
hp_wmi_fan_speed_max_reset(void)643 static int hp_wmi_fan_speed_max_reset(void)
644 {
645 int ret;
646
647 ret = hp_wmi_fan_speed_max_set(0);
648 if (ret)
649 return ret;
650
651 /* Disabling max fan speed on Victus s1xxx laptops needs a 2nd step: */
652 ret = hp_wmi_fan_speed_reset();
653 return ret;
654 }
655
hp_wmi_fan_speed_max_get(void)656 static int hp_wmi_fan_speed_max_get(void)
657 {
658 int val = 0, ret;
659
660 ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_GET_QUERY, HPWMI_GM,
661 &val, zero_if_sup(val), sizeof(val));
662
663 if (ret)
664 return ret < 0 ? ret : -EINVAL;
665
666 return val;
667 }
668
hp_wmi_bios_2008_later(void)669 static int __init hp_wmi_bios_2008_later(void)
670 {
671 int state = 0;
672 int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, HPWMI_READ, &state,
673 zero_if_sup(state), sizeof(state));
674 if (!ret)
675 return 1;
676
677 return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO;
678 }
679
hp_wmi_bios_2009_later(void)680 static int __init hp_wmi_bios_2009_later(void)
681 {
682 u8 state[128];
683 int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state,
684 zero_if_sup(state), sizeof(state));
685 if (!ret)
686 return 1;
687
688 return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO;
689 }
690
hp_wmi_enable_hotkeys(void)691 static int __init hp_wmi_enable_hotkeys(void)
692 {
693 int value = 0x6e;
694 int ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, HPWMI_WRITE, &value,
695 sizeof(value), 0);
696
697 return ret <= 0 ? ret : -EINVAL;
698 }
699
hp_wmi_set_block(void * data,bool blocked)700 static int hp_wmi_set_block(void *data, bool blocked)
701 {
702 enum hp_wmi_radio r = (long)data;
703 int query = BIT(r + 8) | ((!blocked) << r);
704 int ret;
705
706 ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE,
707 &query, sizeof(query), 0);
708
709 return ret <= 0 ? ret : -EINVAL;
710 }
711
712 static const struct rfkill_ops hp_wmi_rfkill_ops = {
713 .set_block = hp_wmi_set_block,
714 };
715
hp_wmi_get_sw_state(enum hp_wmi_radio r)716 static bool hp_wmi_get_sw_state(enum hp_wmi_radio r)
717 {
718 int mask = 0x200 << (r * 8);
719
720 int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
721
722 /* TBD: Pass error */
723 WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY");
724
725 return !(wireless & mask);
726 }
727
hp_wmi_get_hw_state(enum hp_wmi_radio r)728 static bool hp_wmi_get_hw_state(enum hp_wmi_radio r)
729 {
730 int mask = 0x800 << (r * 8);
731
732 int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
733
734 /* TBD: Pass error */
735 WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY");
736
737 return !(wireless & mask);
738 }
739
hp_wmi_rfkill2_set_block(void * data,bool blocked)740 static int hp_wmi_rfkill2_set_block(void *data, bool blocked)
741 {
742 int rfkill_id = (int)(long)data;
743 char buffer[4] = { 0x01, 0x00, rfkill_id, !blocked };
744 int ret;
745
746 ret = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_WRITE,
747 buffer, sizeof(buffer), 0);
748
749 return ret <= 0 ? ret : -EINVAL;
750 }
751
752 static const struct rfkill_ops hp_wmi_rfkill2_ops = {
753 .set_block = hp_wmi_rfkill2_set_block,
754 };
755
hp_wmi_rfkill2_refresh(void)756 static int hp_wmi_rfkill2_refresh(void)
757 {
758 struct bios_rfkill2_state state;
759 int err, i;
760
761 err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
762 zero_if_sup(state), sizeof(state));
763 if (err)
764 return err;
765
766 for (i = 0; i < rfkill2_count; i++) {
767 int num = rfkill2[i].num;
768 struct bios_rfkill2_device_state *devstate;
769
770 devstate = &state.device[num];
771
772 if (num >= state.count ||
773 devstate->rfkill_id != rfkill2[i].id) {
774 pr_warn("power configuration of the wireless devices unexpectedly changed\n");
775 continue;
776 }
777
778 rfkill_set_states(rfkill2[i].rfkill,
779 IS_SWBLOCKED(devstate->power),
780 IS_HWBLOCKED(devstate->power));
781 }
782
783 return 0;
784 }
785
display_show(struct device * dev,struct device_attribute * attr,char * buf)786 static ssize_t display_show(struct device *dev, struct device_attribute *attr,
787 char *buf)
788 {
789 int value = hp_wmi_read_int(HPWMI_DISPLAY_QUERY);
790
791 if (value < 0)
792 return value;
793 return sysfs_emit(buf, "%d\n", value);
794 }
795
hddtemp_show(struct device * dev,struct device_attribute * attr,char * buf)796 static ssize_t hddtemp_show(struct device *dev, struct device_attribute *attr,
797 char *buf)
798 {
799 int value = hp_wmi_read_int(HPWMI_HDDTEMP_QUERY);
800
801 if (value < 0)
802 return value;
803 return sysfs_emit(buf, "%d\n", value);
804 }
805
als_show(struct device * dev,struct device_attribute * attr,char * buf)806 static ssize_t als_show(struct device *dev, struct device_attribute *attr,
807 char *buf)
808 {
809 int value = hp_wmi_read_int(HPWMI_ALS_QUERY);
810
811 if (value < 0)
812 return value;
813 return sysfs_emit(buf, "%d\n", value);
814 }
815
dock_show(struct device * dev,struct device_attribute * attr,char * buf)816 static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
817 char *buf)
818 {
819 int value = hp_wmi_get_dock_state();
820
821 if (value < 0)
822 return value;
823 return sysfs_emit(buf, "%d\n", value);
824 }
825
tablet_show(struct device * dev,struct device_attribute * attr,char * buf)826 static ssize_t tablet_show(struct device *dev, struct device_attribute *attr,
827 char *buf)
828 {
829 int value = hp_wmi_get_tablet_mode();
830
831 if (value < 0)
832 return value;
833 return sysfs_emit(buf, "%d\n", value);
834 }
835
postcode_show(struct device * dev,struct device_attribute * attr,char * buf)836 static ssize_t postcode_show(struct device *dev, struct device_attribute *attr,
837 char *buf)
838 {
839 /* Get the POST error code of previous boot failure. */
840 int value = hp_wmi_read_int(HPWMI_POSTCODEERROR_QUERY);
841
842 if (value < 0)
843 return value;
844 return sysfs_emit(buf, "0x%x\n", value);
845 }
846
als_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)847 static ssize_t als_store(struct device *dev, struct device_attribute *attr,
848 const char *buf, size_t count)
849 {
850 u32 tmp;
851 int ret;
852
853 ret = kstrtou32(buf, 10, &tmp);
854 if (ret)
855 return ret;
856
857 ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp,
858 sizeof(tmp), 0);
859 if (ret)
860 return ret < 0 ? ret : -EINVAL;
861
862 return count;
863 }
864
postcode_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)865 static ssize_t postcode_store(struct device *dev, struct device_attribute *attr,
866 const char *buf, size_t count)
867 {
868 u32 tmp = 1;
869 bool clear;
870 int ret;
871
872 ret = kstrtobool(buf, &clear);
873 if (ret)
874 return ret;
875
876 if (clear == false)
877 return -EINVAL;
878
879 /* Clear the POST error code. It is kept until cleared. */
880 ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, HPWMI_WRITE, &tmp,
881 sizeof(tmp), 0);
882 if (ret)
883 return ret < 0 ? ret : -EINVAL;
884
885 return count;
886 }
887
camera_shutter_input_setup(void)888 static int camera_shutter_input_setup(void)
889 {
890 int err;
891
892 camera_shutter_input_dev = input_allocate_device();
893 if (!camera_shutter_input_dev)
894 return -ENOMEM;
895
896 camera_shutter_input_dev->name = "HP WMI camera shutter";
897 camera_shutter_input_dev->phys = "wmi/input1";
898 camera_shutter_input_dev->id.bustype = BUS_HOST;
899
900 __set_bit(EV_SW, camera_shutter_input_dev->evbit);
901 __set_bit(SW_CAMERA_LENS_COVER, camera_shutter_input_dev->swbit);
902
903 err = input_register_device(camera_shutter_input_dev);
904 if (err)
905 goto err_free_dev;
906
907 return 0;
908
909 err_free_dev:
910 input_free_device(camera_shutter_input_dev);
911 camera_shutter_input_dev = NULL;
912 return err;
913 }
914
915 static DEVICE_ATTR_RO(display);
916 static DEVICE_ATTR_RO(hddtemp);
917 static DEVICE_ATTR_RW(als);
918 static DEVICE_ATTR_RO(dock);
919 static DEVICE_ATTR_RO(tablet);
920 static DEVICE_ATTR_RW(postcode);
921
922 static struct attribute *hp_wmi_attrs[] = {
923 &dev_attr_display.attr,
924 &dev_attr_hddtemp.attr,
925 &dev_attr_als.attr,
926 &dev_attr_dock.attr,
927 &dev_attr_tablet.attr,
928 &dev_attr_postcode.attr,
929 NULL,
930 };
931 ATTRIBUTE_GROUPS(hp_wmi);
932
hp_wmi_notify(union acpi_object * obj,void * context)933 static void hp_wmi_notify(union acpi_object *obj, void *context)
934 {
935 u32 event_id, event_data;
936 u32 *location;
937 int key_code;
938
939 if (!obj)
940 return;
941 if (obj->type != ACPI_TYPE_BUFFER) {
942 pr_info("Unknown response received %d\n", obj->type);
943 return;
944 }
945
946 /*
947 * Depending on ACPI version the concatenation of id and event data
948 * inside _WED function will result in a 8 or 16 byte buffer.
949 */
950 location = (u32 *)obj->buffer.pointer;
951 if (obj->buffer.length == 8) {
952 event_id = *location;
953 event_data = *(location + 1);
954 } else if (obj->buffer.length == 16) {
955 event_id = *location;
956 event_data = *(location + 2);
957 } else {
958 pr_info("Unknown buffer length %d\n", obj->buffer.length);
959 return;
960 }
961
962 switch (event_id) {
963 case HPWMI_DOCK_EVENT:
964 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
965 input_report_switch(hp_wmi_input_dev, SW_DOCK,
966 hp_wmi_get_dock_state());
967 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
968 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
969 hp_wmi_get_tablet_mode());
970 input_sync(hp_wmi_input_dev);
971 break;
972 case HPWMI_PARK_HDD:
973 break;
974 case HPWMI_SMART_ADAPTER:
975 break;
976 case HPWMI_BEZEL_BUTTON:
977 key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY);
978 if (key_code < 0)
979 break;
980
981 if (!sparse_keymap_report_event(hp_wmi_input_dev,
982 key_code, 1, true))
983 pr_info("Unknown key code - 0x%x\n", key_code);
984 break;
985 case HPWMI_FN_P_HOTKEY:
986 platform_profile_cycle();
987 break;
988 case HPWMI_OMEN_KEY:
989 if (event_data) /* Only should be true for HP Omen */
990 key_code = event_data;
991 else
992 key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY);
993
994 if (!sparse_keymap_report_event(hp_wmi_input_dev,
995 key_code, 1, true))
996 pr_info("Unknown key code - 0x%x\n", key_code);
997 break;
998 case HPWMI_WIRELESS:
999 if (rfkill2_count) {
1000 hp_wmi_rfkill2_refresh();
1001 break;
1002 }
1003
1004 if (wifi_rfkill)
1005 rfkill_set_states(wifi_rfkill,
1006 hp_wmi_get_sw_state(HPWMI_WIFI),
1007 hp_wmi_get_hw_state(HPWMI_WIFI));
1008 if (bluetooth_rfkill)
1009 rfkill_set_states(bluetooth_rfkill,
1010 hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
1011 hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
1012 if (wwan_rfkill)
1013 rfkill_set_states(wwan_rfkill,
1014 hp_wmi_get_sw_state(HPWMI_WWAN),
1015 hp_wmi_get_hw_state(HPWMI_WWAN));
1016 break;
1017 case HPWMI_CPU_BATTERY_THROTTLE:
1018 pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n");
1019 break;
1020 case HPWMI_LOCK_SWITCH:
1021 break;
1022 case HPWMI_LID_SWITCH:
1023 break;
1024 case HPWMI_SCREEN_ROTATION:
1025 break;
1026 case HPWMI_COOLSENSE_SYSTEM_MOBILE:
1027 break;
1028 case HPWMI_COOLSENSE_SYSTEM_HOT:
1029 break;
1030 case HPWMI_PROXIMITY_SENSOR:
1031 break;
1032 case HPWMI_BACKLIT_KB_BRIGHTNESS:
1033 break;
1034 case HPWMI_PEAKSHIFT_PERIOD:
1035 break;
1036 case HPWMI_BATTERY_CHARGE_PERIOD:
1037 break;
1038 case HPWMI_SANITIZATION_MODE:
1039 break;
1040 case HPWMI_CAMERA_TOGGLE:
1041 if (!camera_shutter_input_dev)
1042 if (camera_shutter_input_setup()) {
1043 pr_err("Failed to setup camera shutter input device\n");
1044 break;
1045 }
1046 if (event_data == 0xff)
1047 input_report_switch(camera_shutter_input_dev, SW_CAMERA_LENS_COVER, 1);
1048 else if (event_data == 0xfe)
1049 input_report_switch(camera_shutter_input_dev, SW_CAMERA_LENS_COVER, 0);
1050 else
1051 pr_warn("Unknown camera shutter state - 0x%x\n", event_data);
1052 input_sync(camera_shutter_input_dev);
1053 break;
1054 case HPWMI_SMART_EXPERIENCE_APP:
1055 break;
1056 default:
1057 pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
1058 break;
1059 }
1060 }
1061
hp_wmi_input_setup(void)1062 static int __init hp_wmi_input_setup(void)
1063 {
1064 acpi_status status;
1065 int err, val;
1066
1067 hp_wmi_input_dev = input_allocate_device();
1068 if (!hp_wmi_input_dev)
1069 return -ENOMEM;
1070
1071 hp_wmi_input_dev->name = "HP WMI hotkeys";
1072 hp_wmi_input_dev->phys = "wmi/input0";
1073 hp_wmi_input_dev->id.bustype = BUS_HOST;
1074
1075 __set_bit(EV_SW, hp_wmi_input_dev->evbit);
1076
1077 /* Dock */
1078 val = hp_wmi_get_dock_state();
1079 if (!(val < 0)) {
1080 __set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
1081 input_report_switch(hp_wmi_input_dev, SW_DOCK, val);
1082 }
1083
1084 /* Tablet mode */
1085 val = hp_wmi_get_tablet_mode();
1086 if (!(val < 0)) {
1087 __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
1088 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
1089 }
1090
1091 err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
1092 if (err)
1093 goto err_free_dev;
1094
1095 /* Set initial hardware state */
1096 input_sync(hp_wmi_input_dev);
1097
1098 if (!hp_wmi_bios_2009_later() && hp_wmi_bios_2008_later())
1099 hp_wmi_enable_hotkeys();
1100
1101 status = wmi_install_notify_handler(HPWMI_EVENT_GUID, hp_wmi_notify, NULL);
1102 if (ACPI_FAILURE(status)) {
1103 err = -EIO;
1104 goto err_free_dev;
1105 }
1106
1107 err = input_register_device(hp_wmi_input_dev);
1108 if (err)
1109 goto err_uninstall_notifier;
1110
1111 return 0;
1112
1113 err_uninstall_notifier:
1114 wmi_remove_notify_handler(HPWMI_EVENT_GUID);
1115 err_free_dev:
1116 input_free_device(hp_wmi_input_dev);
1117 return err;
1118 }
1119
hp_wmi_input_destroy(void)1120 static void hp_wmi_input_destroy(void)
1121 {
1122 wmi_remove_notify_handler(HPWMI_EVENT_GUID);
1123 input_unregister_device(hp_wmi_input_dev);
1124 }
1125
hp_wmi_rfkill_setup(struct platform_device * device)1126 static int __init hp_wmi_rfkill_setup(struct platform_device *device)
1127 {
1128 int err, wireless;
1129
1130 wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
1131 if (wireless < 0)
1132 return wireless;
1133
1134 err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE, &wireless,
1135 sizeof(wireless), 0);
1136 if (err)
1137 return err;
1138
1139 if (wireless & 0x1) {
1140 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
1141 RFKILL_TYPE_WLAN,
1142 &hp_wmi_rfkill_ops,
1143 (void *) HPWMI_WIFI);
1144 if (!wifi_rfkill)
1145 return -ENOMEM;
1146 rfkill_init_sw_state(wifi_rfkill,
1147 hp_wmi_get_sw_state(HPWMI_WIFI));
1148 rfkill_set_hw_state(wifi_rfkill,
1149 hp_wmi_get_hw_state(HPWMI_WIFI));
1150 err = rfkill_register(wifi_rfkill);
1151 if (err)
1152 goto register_wifi_error;
1153 }
1154
1155 if (wireless & 0x2) {
1156 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
1157 RFKILL_TYPE_BLUETOOTH,
1158 &hp_wmi_rfkill_ops,
1159 (void *) HPWMI_BLUETOOTH);
1160 if (!bluetooth_rfkill) {
1161 err = -ENOMEM;
1162 goto register_bluetooth_error;
1163 }
1164 rfkill_init_sw_state(bluetooth_rfkill,
1165 hp_wmi_get_sw_state(HPWMI_BLUETOOTH));
1166 rfkill_set_hw_state(bluetooth_rfkill,
1167 hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
1168 err = rfkill_register(bluetooth_rfkill);
1169 if (err)
1170 goto register_bluetooth_error;
1171 }
1172
1173 if (wireless & 0x4) {
1174 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
1175 RFKILL_TYPE_WWAN,
1176 &hp_wmi_rfkill_ops,
1177 (void *) HPWMI_WWAN);
1178 if (!wwan_rfkill) {
1179 err = -ENOMEM;
1180 goto register_wwan_error;
1181 }
1182 rfkill_init_sw_state(wwan_rfkill,
1183 hp_wmi_get_sw_state(HPWMI_WWAN));
1184 rfkill_set_hw_state(wwan_rfkill,
1185 hp_wmi_get_hw_state(HPWMI_WWAN));
1186 err = rfkill_register(wwan_rfkill);
1187 if (err)
1188 goto register_wwan_error;
1189 }
1190
1191 return 0;
1192
1193 register_wwan_error:
1194 rfkill_destroy(wwan_rfkill);
1195 wwan_rfkill = NULL;
1196 if (bluetooth_rfkill)
1197 rfkill_unregister(bluetooth_rfkill);
1198 register_bluetooth_error:
1199 rfkill_destroy(bluetooth_rfkill);
1200 bluetooth_rfkill = NULL;
1201 if (wifi_rfkill)
1202 rfkill_unregister(wifi_rfkill);
1203 register_wifi_error:
1204 rfkill_destroy(wifi_rfkill);
1205 wifi_rfkill = NULL;
1206 return err;
1207 }
1208
hp_wmi_rfkill2_setup(struct platform_device * device)1209 static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
1210 {
1211 struct bios_rfkill2_state state;
1212 int err, i;
1213
1214 err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
1215 zero_if_sup(state), sizeof(state));
1216 if (err)
1217 return err < 0 ? err : -EINVAL;
1218
1219 if (state.count > HPWMI_MAX_RFKILL2_DEVICES) {
1220 pr_warn("unable to parse 0x1b query output\n");
1221 return -EINVAL;
1222 }
1223
1224 for (i = 0; i < state.count; i++) {
1225 struct rfkill *rfkill;
1226 enum rfkill_type type;
1227 char *name;
1228
1229 switch (state.device[i].radio_type) {
1230 case HPWMI_WIFI:
1231 type = RFKILL_TYPE_WLAN;
1232 name = "hp-wifi";
1233 break;
1234 case HPWMI_BLUETOOTH:
1235 type = RFKILL_TYPE_BLUETOOTH;
1236 name = "hp-bluetooth";
1237 break;
1238 case HPWMI_WWAN:
1239 type = RFKILL_TYPE_WWAN;
1240 name = "hp-wwan";
1241 break;
1242 case HPWMI_GPS:
1243 type = RFKILL_TYPE_GPS;
1244 name = "hp-gps";
1245 break;
1246 default:
1247 pr_warn("unknown device type 0x%x\n",
1248 state.device[i].radio_type);
1249 continue;
1250 }
1251
1252 if (!state.device[i].vendor_id) {
1253 pr_warn("zero device %d while %d reported\n",
1254 i, state.count);
1255 continue;
1256 }
1257
1258 rfkill = rfkill_alloc(name, &device->dev, type,
1259 &hp_wmi_rfkill2_ops, (void *)(long)i);
1260 if (!rfkill) {
1261 err = -ENOMEM;
1262 goto fail;
1263 }
1264
1265 rfkill2[rfkill2_count].id = state.device[i].rfkill_id;
1266 rfkill2[rfkill2_count].num = i;
1267 rfkill2[rfkill2_count].rfkill = rfkill;
1268
1269 rfkill_init_sw_state(rfkill,
1270 IS_SWBLOCKED(state.device[i].power));
1271 rfkill_set_hw_state(rfkill,
1272 IS_HWBLOCKED(state.device[i].power));
1273
1274 if (!(state.device[i].power & HPWMI_POWER_BIOS))
1275 pr_info("device %s blocked by BIOS\n", name);
1276
1277 err = rfkill_register(rfkill);
1278 if (err) {
1279 rfkill_destroy(rfkill);
1280 goto fail;
1281 }
1282
1283 rfkill2_count++;
1284 }
1285
1286 return 0;
1287 fail:
1288 for (; rfkill2_count > 0; rfkill2_count--) {
1289 rfkill_unregister(rfkill2[rfkill2_count - 1].rfkill);
1290 rfkill_destroy(rfkill2[rfkill2_count - 1].rfkill);
1291 }
1292 return err;
1293 }
1294
platform_profile_omen_get_ec(enum platform_profile_option * profile)1295 static int platform_profile_omen_get_ec(enum platform_profile_option *profile)
1296 {
1297 int tp;
1298
1299 tp = omen_thermal_profile_get();
1300 if (tp < 0)
1301 return tp;
1302
1303 switch (tp) {
1304 case HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE:
1305 case HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE:
1306 *profile = PLATFORM_PROFILE_PERFORMANCE;
1307 break;
1308 case HP_OMEN_V0_THERMAL_PROFILE_DEFAULT:
1309 case HP_OMEN_V1_THERMAL_PROFILE_DEFAULT:
1310 *profile = PLATFORM_PROFILE_BALANCED;
1311 break;
1312 case HP_OMEN_V0_THERMAL_PROFILE_COOL:
1313 case HP_OMEN_V1_THERMAL_PROFILE_COOL:
1314 *profile = PLATFORM_PROFILE_COOL;
1315 break;
1316 default:
1317 return -EINVAL;
1318 }
1319
1320 return 0;
1321 }
1322
platform_profile_omen_get(struct device * dev,enum platform_profile_option * profile)1323 static int platform_profile_omen_get(struct device *dev,
1324 enum platform_profile_option *profile)
1325 {
1326 /*
1327 * We directly return the stored platform profile, as the embedded
1328 * controller will not accept switching to the performance option when
1329 * the conditions are not met (e.g. the laptop is not plugged in).
1330 *
1331 * If we directly return what the EC reports, the platform profile will
1332 * immediately "switch back" to normal mode, which is against the
1333 * expected behaviour from a userspace point of view, as described in
1334 * the Platform Profile Section page of the kernel documentation.
1335 *
1336 * See also omen_powersource_event.
1337 */
1338 guard(mutex)(&active_platform_profile_lock);
1339 *profile = active_platform_profile;
1340
1341 return 0;
1342 }
1343
has_omen_thermal_profile_ec_timer(void)1344 static bool has_omen_thermal_profile_ec_timer(void)
1345 {
1346 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
1347
1348 if (!board_name)
1349 return false;
1350
1351 return match_string(omen_timed_thermal_profile_boards,
1352 ARRAY_SIZE(omen_timed_thermal_profile_boards),
1353 board_name) >= 0;
1354 }
1355
omen_thermal_profile_ec_flags_set(enum hp_thermal_profile_omen_flags flags)1356 inline int omen_thermal_profile_ec_flags_set(enum hp_thermal_profile_omen_flags flags)
1357 {
1358 return ec_write(HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET, flags);
1359 }
1360
omen_thermal_profile_ec_timer_set(u8 value)1361 inline int omen_thermal_profile_ec_timer_set(u8 value)
1362 {
1363 return ec_write(HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET, value);
1364 }
1365
platform_profile_omen_set_ec(enum platform_profile_option profile)1366 static int platform_profile_omen_set_ec(enum platform_profile_option profile)
1367 {
1368 int err, tp, tp_version;
1369 enum hp_thermal_profile_omen_flags flags = 0;
1370
1371 tp_version = omen_get_thermal_policy_version();
1372
1373 if (tp_version < 0 || tp_version > 1)
1374 return -EOPNOTSUPP;
1375
1376 switch (profile) {
1377 case PLATFORM_PROFILE_PERFORMANCE:
1378 if (tp_version == 0)
1379 tp = HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE;
1380 else
1381 tp = HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE;
1382 break;
1383 case PLATFORM_PROFILE_BALANCED:
1384 if (tp_version == 0)
1385 tp = HP_OMEN_V0_THERMAL_PROFILE_DEFAULT;
1386 else
1387 tp = HP_OMEN_V1_THERMAL_PROFILE_DEFAULT;
1388 break;
1389 case PLATFORM_PROFILE_COOL:
1390 if (tp_version == 0)
1391 tp = HP_OMEN_V0_THERMAL_PROFILE_COOL;
1392 else
1393 tp = HP_OMEN_V1_THERMAL_PROFILE_COOL;
1394 break;
1395 default:
1396 return -EOPNOTSUPP;
1397 }
1398
1399 err = omen_thermal_profile_set(tp);
1400 if (err < 0)
1401 return err;
1402
1403 if (has_omen_thermal_profile_ec_timer()) {
1404 err = omen_thermal_profile_ec_timer_set(0);
1405 if (err < 0)
1406 return err;
1407
1408 if (profile == PLATFORM_PROFILE_PERFORMANCE)
1409 flags = HP_OMEN_EC_FLAGS_NOTIMER |
1410 HP_OMEN_EC_FLAGS_TURBO;
1411
1412 err = omen_thermal_profile_ec_flags_set(flags);
1413 if (err < 0)
1414 return err;
1415 }
1416
1417 return 0;
1418 }
1419
platform_profile_omen_set(struct device * dev,enum platform_profile_option profile)1420 static int platform_profile_omen_set(struct device *dev,
1421 enum platform_profile_option profile)
1422 {
1423 int err;
1424
1425 guard(mutex)(&active_platform_profile_lock);
1426
1427 err = platform_profile_omen_set_ec(profile);
1428 if (err < 0)
1429 return err;
1430
1431 active_platform_profile = profile;
1432
1433 return 0;
1434 }
1435
thermal_profile_get(void)1436 static int thermal_profile_get(void)
1437 {
1438 return hp_wmi_read_int(HPWMI_THERMAL_PROFILE_QUERY);
1439 }
1440
thermal_profile_set(int thermal_profile)1441 static int thermal_profile_set(int thermal_profile)
1442 {
1443 return hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &thermal_profile,
1444 sizeof(thermal_profile), 0);
1445 }
1446
hp_wmi_platform_profile_get(struct device * dev,enum platform_profile_option * profile)1447 static int hp_wmi_platform_profile_get(struct device *dev,
1448 enum platform_profile_option *profile)
1449 {
1450 int tp;
1451
1452 tp = thermal_profile_get();
1453 if (tp < 0)
1454 return tp;
1455
1456 switch (tp) {
1457 case HP_THERMAL_PROFILE_PERFORMANCE:
1458 *profile = PLATFORM_PROFILE_PERFORMANCE;
1459 break;
1460 case HP_THERMAL_PROFILE_DEFAULT:
1461 *profile = PLATFORM_PROFILE_BALANCED;
1462 break;
1463 case HP_THERMAL_PROFILE_COOL:
1464 *profile = PLATFORM_PROFILE_COOL;
1465 break;
1466 case HP_THERMAL_PROFILE_QUIET:
1467 *profile = PLATFORM_PROFILE_QUIET;
1468 break;
1469 default:
1470 return -EINVAL;
1471 }
1472
1473 return 0;
1474 }
1475
hp_wmi_platform_profile_set(struct device * dev,enum platform_profile_option profile)1476 static int hp_wmi_platform_profile_set(struct device *dev,
1477 enum platform_profile_option profile)
1478 {
1479 int err, tp;
1480
1481 switch (profile) {
1482 case PLATFORM_PROFILE_PERFORMANCE:
1483 tp = HP_THERMAL_PROFILE_PERFORMANCE;
1484 break;
1485 case PLATFORM_PROFILE_BALANCED:
1486 tp = HP_THERMAL_PROFILE_DEFAULT;
1487 break;
1488 case PLATFORM_PROFILE_COOL:
1489 tp = HP_THERMAL_PROFILE_COOL;
1490 break;
1491 case PLATFORM_PROFILE_QUIET:
1492 tp = HP_THERMAL_PROFILE_QUIET;
1493 break;
1494 default:
1495 return -EOPNOTSUPP;
1496 }
1497
1498 err = thermal_profile_set(tp);
1499 if (err)
1500 return err;
1501
1502 return 0;
1503 }
1504
is_victus_thermal_profile(void)1505 static bool is_victus_thermal_profile(void)
1506 {
1507 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
1508
1509 if (!board_name)
1510 return false;
1511
1512 return match_string(victus_thermal_profile_boards,
1513 ARRAY_SIZE(victus_thermal_profile_boards),
1514 board_name) >= 0;
1515 }
1516
platform_profile_victus_get_ec(enum platform_profile_option * profile)1517 static int platform_profile_victus_get_ec(enum platform_profile_option *profile)
1518 {
1519 int tp;
1520
1521 tp = omen_thermal_profile_get();
1522 if (tp < 0)
1523 return tp;
1524
1525 switch (tp) {
1526 case HP_VICTUS_THERMAL_PROFILE_PERFORMANCE:
1527 *profile = PLATFORM_PROFILE_PERFORMANCE;
1528 break;
1529 case HP_VICTUS_THERMAL_PROFILE_DEFAULT:
1530 *profile = PLATFORM_PROFILE_BALANCED;
1531 break;
1532 case HP_VICTUS_THERMAL_PROFILE_QUIET:
1533 *profile = PLATFORM_PROFILE_QUIET;
1534 break;
1535 default:
1536 return -EOPNOTSUPP;
1537 }
1538
1539 return 0;
1540 }
1541
platform_profile_victus_get(struct device * dev,enum platform_profile_option * profile)1542 static int platform_profile_victus_get(struct device *dev,
1543 enum platform_profile_option *profile)
1544 {
1545 /* Same behaviour as platform_profile_omen_get */
1546 return platform_profile_omen_get(dev, profile);
1547 }
1548
platform_profile_victus_set_ec(enum platform_profile_option profile)1549 static int platform_profile_victus_set_ec(enum platform_profile_option profile)
1550 {
1551 int err, tp;
1552
1553 switch (profile) {
1554 case PLATFORM_PROFILE_PERFORMANCE:
1555 tp = HP_VICTUS_THERMAL_PROFILE_PERFORMANCE;
1556 break;
1557 case PLATFORM_PROFILE_BALANCED:
1558 tp = HP_VICTUS_THERMAL_PROFILE_DEFAULT;
1559 break;
1560 case PLATFORM_PROFILE_QUIET:
1561 tp = HP_VICTUS_THERMAL_PROFILE_QUIET;
1562 break;
1563 default:
1564 return -EOPNOTSUPP;
1565 }
1566
1567 err = omen_thermal_profile_set(tp);
1568 if (err < 0)
1569 return err;
1570
1571 return 0;
1572 }
1573
is_victus_s_thermal_profile(void)1574 static bool is_victus_s_thermal_profile(void)
1575 {
1576 const char *board_name;
1577
1578 board_name = dmi_get_system_info(DMI_BOARD_NAME);
1579 if (!board_name)
1580 return false;
1581
1582 return match_string(victus_s_thermal_profile_boards,
1583 ARRAY_SIZE(victus_s_thermal_profile_boards),
1584 board_name) >= 0;
1585 }
1586
victus_s_gpu_thermal_profile_get(bool * ctgp_enable,bool * ppab_enable,u8 * dstate,u8 * gpu_slowdown_temp)1587 static int victus_s_gpu_thermal_profile_get(bool *ctgp_enable,
1588 bool *ppab_enable,
1589 u8 *dstate,
1590 u8 *gpu_slowdown_temp)
1591 {
1592 struct victus_gpu_power_modes gpu_power_modes;
1593 int ret;
1594
1595 ret = hp_wmi_perform_query(HPWMI_GET_GPU_THERMAL_MODES_QUERY, HPWMI_GM,
1596 &gpu_power_modes, sizeof(gpu_power_modes),
1597 sizeof(gpu_power_modes));
1598 if (ret == 0) {
1599 *ctgp_enable = gpu_power_modes.ctgp_enable ? true : false;
1600 *ppab_enable = gpu_power_modes.ppab_enable ? true : false;
1601 *dstate = gpu_power_modes.dstate;
1602 *gpu_slowdown_temp = gpu_power_modes.gpu_slowdown_temp;
1603 }
1604
1605 return ret;
1606 }
1607
victus_s_gpu_thermal_profile_set(bool ctgp_enable,bool ppab_enable,u8 dstate)1608 static int victus_s_gpu_thermal_profile_set(bool ctgp_enable,
1609 bool ppab_enable,
1610 u8 dstate)
1611 {
1612 struct victus_gpu_power_modes gpu_power_modes;
1613 int ret;
1614
1615 bool current_ctgp_state, current_ppab_state;
1616 u8 current_dstate, current_gpu_slowdown_temp;
1617
1618 /* Retrieving GPU slowdown temperature, in order to keep it unchanged */
1619 ret = victus_s_gpu_thermal_profile_get(¤t_ctgp_state,
1620 ¤t_ppab_state,
1621 ¤t_dstate,
1622 ¤t_gpu_slowdown_temp);
1623 if (ret < 0) {
1624 pr_warn("GPU modes not updated, unable to get slowdown temp\n");
1625 return ret;
1626 }
1627
1628 gpu_power_modes.ctgp_enable = ctgp_enable ? 0x01 : 0x00;
1629 gpu_power_modes.ppab_enable = ppab_enable ? 0x01 : 0x00;
1630 gpu_power_modes.dstate = dstate;
1631 gpu_power_modes.gpu_slowdown_temp = current_gpu_slowdown_temp;
1632
1633
1634 ret = hp_wmi_perform_query(HPWMI_SET_GPU_THERMAL_MODES_QUERY, HPWMI_GM,
1635 &gpu_power_modes, sizeof(gpu_power_modes), 0);
1636
1637 return ret;
1638 }
1639
1640 /* Note: HP_POWER_LIMIT_DEFAULT can be used to restore default PL1 and PL2 */
victus_s_set_cpu_pl1_pl2(u8 pl1,u8 pl2)1641 static int victus_s_set_cpu_pl1_pl2(u8 pl1, u8 pl2)
1642 {
1643 struct victus_power_limits power_limits;
1644 int ret;
1645
1646 /* We need to know both PL1 and PL2 values in order to check them */
1647 if (pl1 == HP_POWER_LIMIT_NO_CHANGE || pl2 == HP_POWER_LIMIT_NO_CHANGE)
1648 return -EINVAL;
1649
1650 /* PL2 is not supposed to be lower than PL1 */
1651 if (pl2 < pl1)
1652 return -EINVAL;
1653
1654 power_limits.pl1 = pl1;
1655 power_limits.pl2 = pl2;
1656 power_limits.pl4 = HP_POWER_LIMIT_NO_CHANGE;
1657 power_limits.cpu_gpu_concurrent_limit = HP_POWER_LIMIT_NO_CHANGE;
1658
1659 ret = hp_wmi_perform_query(HPWMI_SET_POWER_LIMITS_QUERY, HPWMI_GM,
1660 &power_limits, sizeof(power_limits), 0);
1661
1662 return ret;
1663 }
1664
platform_profile_victus_s_set_ec(enum platform_profile_option profile)1665 static int platform_profile_victus_s_set_ec(enum platform_profile_option profile)
1666 {
1667 bool gpu_ctgp_enable, gpu_ppab_enable;
1668 u8 gpu_dstate; /* Test shows 1 = 100%, 2 = 50%, 3 = 25%, 4 = 12.5% */
1669 int err, tp;
1670
1671 switch (profile) {
1672 case PLATFORM_PROFILE_PERFORMANCE:
1673 tp = HP_VICTUS_S_THERMAL_PROFILE_PERFORMANCE;
1674 gpu_ctgp_enable = true;
1675 gpu_ppab_enable = true;
1676 gpu_dstate = 1;
1677 break;
1678 case PLATFORM_PROFILE_BALANCED:
1679 tp = HP_VICTUS_S_THERMAL_PROFILE_DEFAULT;
1680 gpu_ctgp_enable = false;
1681 gpu_ppab_enable = true;
1682 gpu_dstate = 1;
1683 break;
1684 case PLATFORM_PROFILE_LOW_POWER:
1685 tp = HP_VICTUS_S_THERMAL_PROFILE_DEFAULT;
1686 gpu_ctgp_enable = false;
1687 gpu_ppab_enable = false;
1688 gpu_dstate = 1;
1689 break;
1690 default:
1691 return -EOPNOTSUPP;
1692 }
1693
1694 hp_wmi_get_fan_count_userdefine_trigger();
1695
1696 err = omen_thermal_profile_set(tp);
1697 if (err < 0) {
1698 pr_err("Failed to set platform profile %d: %d\n", profile, err);
1699 return err;
1700 }
1701
1702 err = victus_s_gpu_thermal_profile_set(gpu_ctgp_enable,
1703 gpu_ppab_enable,
1704 gpu_dstate);
1705 if (err < 0) {
1706 pr_err("Failed to set GPU profile %d: %d\n", profile, err);
1707 return err;
1708 }
1709
1710 return 0;
1711 }
1712
platform_profile_victus_s_set(struct device * dev,enum platform_profile_option profile)1713 static int platform_profile_victus_s_set(struct device *dev,
1714 enum platform_profile_option profile)
1715 {
1716 int err;
1717
1718 guard(mutex)(&active_platform_profile_lock);
1719
1720 err = platform_profile_victus_s_set_ec(profile);
1721 if (err < 0)
1722 return err;
1723
1724 active_platform_profile = profile;
1725
1726 return 0;
1727 }
1728
platform_profile_victus_set(struct device * dev,enum platform_profile_option profile)1729 static int platform_profile_victus_set(struct device *dev,
1730 enum platform_profile_option profile)
1731 {
1732 int err;
1733
1734 guard(mutex)(&active_platform_profile_lock);
1735
1736 err = platform_profile_victus_set_ec(profile);
1737 if (err < 0)
1738 return err;
1739
1740 active_platform_profile = profile;
1741
1742 return 0;
1743 }
1744
hp_wmi_platform_profile_probe(void * drvdata,unsigned long * choices)1745 static int hp_wmi_platform_profile_probe(void *drvdata, unsigned long *choices)
1746 {
1747 if (is_omen_thermal_profile()) {
1748 set_bit(PLATFORM_PROFILE_COOL, choices);
1749 } else if (is_victus_thermal_profile()) {
1750 set_bit(PLATFORM_PROFILE_QUIET, choices);
1751 } else if (is_victus_s_thermal_profile()) {
1752 /* Adding an equivalent to HP Omen software ECO mode: */
1753 set_bit(PLATFORM_PROFILE_LOW_POWER, choices);
1754 } else {
1755 set_bit(PLATFORM_PROFILE_QUIET, choices);
1756 set_bit(PLATFORM_PROFILE_COOL, choices);
1757 }
1758
1759 set_bit(PLATFORM_PROFILE_BALANCED, choices);
1760 set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);
1761
1762 return 0;
1763 }
1764
omen_powersource_event(struct notifier_block * nb,unsigned long value,void * data)1765 static int omen_powersource_event(struct notifier_block *nb,
1766 unsigned long value,
1767 void *data)
1768 {
1769 struct acpi_bus_event *event_entry = data;
1770 enum platform_profile_option actual_profile;
1771 int err;
1772
1773 if (strcmp(event_entry->device_class, ACPI_AC_CLASS) != 0)
1774 return NOTIFY_DONE;
1775
1776 pr_debug("Received power source device event\n");
1777
1778 guard(mutex)(&active_platform_profile_lock);
1779
1780 /*
1781 * This handler can only be called on Omen and Victus models, so
1782 * there's no need to call is_victus_thermal_profile() here.
1783 */
1784 if (is_omen_thermal_profile())
1785 err = platform_profile_omen_get_ec(&actual_profile);
1786 else
1787 err = platform_profile_victus_get_ec(&actual_profile);
1788
1789 if (err < 0) {
1790 /*
1791 * Although we failed to get the current platform profile, we
1792 * still want the other event consumers to process it.
1793 */
1794 pr_warn("Failed to read current platform profile (%d)\n", err);
1795 return NOTIFY_DONE;
1796 }
1797
1798 /*
1799 * If we're back on AC and that the user-chosen power profile is
1800 * different from what the EC reports, we restore the user-chosen
1801 * one.
1802 */
1803 if (power_supply_is_system_supplied() <= 0 ||
1804 active_platform_profile == actual_profile) {
1805 pr_debug("Platform profile update skipped, conditions unmet\n");
1806 return NOTIFY_DONE;
1807 }
1808
1809 if (is_omen_thermal_profile())
1810 err = platform_profile_omen_set_ec(active_platform_profile);
1811 else
1812 err = platform_profile_victus_set_ec(active_platform_profile);
1813
1814 if (err < 0) {
1815 pr_warn("Failed to restore platform profile (%d)\n", err);
1816 return NOTIFY_DONE;
1817 }
1818
1819 return NOTIFY_OK;
1820 }
1821
victus_s_powersource_event(struct notifier_block * nb,unsigned long value,void * data)1822 static int victus_s_powersource_event(struct notifier_block *nb,
1823 unsigned long value,
1824 void *data)
1825 {
1826 struct acpi_bus_event *event_entry = data;
1827 int err;
1828
1829 if (strcmp(event_entry->device_class, ACPI_AC_CLASS) != 0)
1830 return NOTIFY_DONE;
1831
1832 pr_debug("Received power source device event\n");
1833
1834 /*
1835 * Switching to battery power source while Performance mode is active
1836 * needs manual triggering of CPU power limits. Same goes when switching
1837 * to AC power source while Performance mode is active. Other modes
1838 * however are automatically behaving without any manual action.
1839 * Seen on HP 16-s1034nf (board 8C9C) with F.11 and F.13 BIOS versions.
1840 */
1841
1842 if (active_platform_profile == PLATFORM_PROFILE_PERFORMANCE) {
1843 pr_debug("Triggering CPU PL1/PL2 actualization\n");
1844 err = victus_s_set_cpu_pl1_pl2(HP_POWER_LIMIT_DEFAULT,
1845 HP_POWER_LIMIT_DEFAULT);
1846 if (err)
1847 pr_warn("Failed to actualize power limits: %d\n", err);
1848
1849 return NOTIFY_DONE;
1850 }
1851
1852 return NOTIFY_OK;
1853 }
1854
omen_register_powersource_event_handler(void)1855 static int omen_register_powersource_event_handler(void)
1856 {
1857 int err;
1858
1859 platform_power_source_nb.notifier_call = omen_powersource_event;
1860 err = register_acpi_notifier(&platform_power_source_nb);
1861
1862 if (err < 0) {
1863 pr_warn("Failed to install ACPI power source notify handler\n");
1864 return err;
1865 }
1866
1867 return 0;
1868 }
1869
victus_s_register_powersource_event_handler(void)1870 static int victus_s_register_powersource_event_handler(void)
1871 {
1872 int err;
1873
1874 platform_power_source_nb.notifier_call = victus_s_powersource_event;
1875 err = register_acpi_notifier(&platform_power_source_nb);
1876 if (err < 0) {
1877 pr_warn("Failed to install ACPI power source notify handler\n");
1878 return err;
1879 }
1880
1881 return 0;
1882 }
1883
omen_unregister_powersource_event_handler(void)1884 static inline void omen_unregister_powersource_event_handler(void)
1885 {
1886 unregister_acpi_notifier(&platform_power_source_nb);
1887 }
1888
victus_s_unregister_powersource_event_handler(void)1889 static inline void victus_s_unregister_powersource_event_handler(void)
1890 {
1891 unregister_acpi_notifier(&platform_power_source_nb);
1892 }
1893
1894 static const struct platform_profile_ops platform_profile_omen_ops = {
1895 .probe = hp_wmi_platform_profile_probe,
1896 .profile_get = platform_profile_omen_get,
1897 .profile_set = platform_profile_omen_set,
1898 };
1899
1900 static const struct platform_profile_ops platform_profile_victus_ops = {
1901 .probe = hp_wmi_platform_profile_probe,
1902 .profile_get = platform_profile_victus_get,
1903 .profile_set = platform_profile_victus_set,
1904 };
1905
1906 static const struct platform_profile_ops platform_profile_victus_s_ops = {
1907 .probe = hp_wmi_platform_profile_probe,
1908 .profile_get = platform_profile_omen_get,
1909 .profile_set = platform_profile_victus_s_set,
1910 };
1911
1912 static const struct platform_profile_ops hp_wmi_platform_profile_ops = {
1913 .probe = hp_wmi_platform_profile_probe,
1914 .profile_get = hp_wmi_platform_profile_get,
1915 .profile_set = hp_wmi_platform_profile_set,
1916 };
1917
thermal_profile_setup(struct platform_device * device)1918 static int thermal_profile_setup(struct platform_device *device)
1919 {
1920 const struct platform_profile_ops *ops;
1921 int err, tp;
1922
1923 if (is_omen_thermal_profile()) {
1924 err = platform_profile_omen_get_ec(&active_platform_profile);
1925 if (err < 0)
1926 return err;
1927
1928 /*
1929 * call thermal profile write command to ensure that the
1930 * firmware correctly sets the OEM variables
1931 */
1932 err = platform_profile_omen_set_ec(active_platform_profile);
1933 if (err < 0)
1934 return err;
1935
1936 ops = &platform_profile_omen_ops;
1937 } else if (is_victus_thermal_profile()) {
1938 err = platform_profile_victus_get_ec(&active_platform_profile);
1939 if (err < 0)
1940 return err;
1941
1942 /*
1943 * call thermal profile write command to ensure that the
1944 * firmware correctly sets the OEM variables
1945 */
1946 err = platform_profile_victus_set_ec(active_platform_profile);
1947 if (err < 0)
1948 return err;
1949
1950 ops = &platform_profile_victus_ops;
1951 } else if (is_victus_s_thermal_profile()) {
1952 /*
1953 * Being unable to retrieve laptop's current thermal profile,
1954 * during this setup, we set it to Balanced by default.
1955 */
1956 active_platform_profile = PLATFORM_PROFILE_BALANCED;
1957
1958 err = platform_profile_victus_s_set_ec(active_platform_profile);
1959 if (err < 0)
1960 return err;
1961
1962 ops = &platform_profile_victus_s_ops;
1963 } else {
1964 tp = thermal_profile_get();
1965
1966 if (tp < 0)
1967 return tp;
1968
1969 /*
1970 * call thermal profile write command to ensure that the
1971 * firmware correctly sets the OEM variables for the DPTF
1972 */
1973 err = thermal_profile_set(tp);
1974 if (err)
1975 return err;
1976
1977 ops = &hp_wmi_platform_profile_ops;
1978 }
1979
1980 platform_profile_device = devm_platform_profile_register(&device->dev, "hp-wmi",
1981 NULL, ops);
1982 if (IS_ERR(platform_profile_device))
1983 return PTR_ERR(platform_profile_device);
1984
1985 pr_info("Registered as platform profile handler\n");
1986 platform_profile_support = true;
1987
1988 return 0;
1989 }
1990
1991 static int hp_wmi_hwmon_init(void);
1992
hp_wmi_bios_setup(struct platform_device * device)1993 static int __init hp_wmi_bios_setup(struct platform_device *device)
1994 {
1995 int err;
1996 /* clear detected rfkill devices */
1997 wifi_rfkill = NULL;
1998 bluetooth_rfkill = NULL;
1999 wwan_rfkill = NULL;
2000 rfkill2_count = 0;
2001
2002 /*
2003 * In pre-2009 BIOS, command 1Bh return 0x4 to indicate that
2004 * BIOS no longer controls the power for the wireless
2005 * devices. All features supported by this command will no
2006 * longer be supported.
2007 */
2008 if (!hp_wmi_bios_2009_later()) {
2009 if (hp_wmi_rfkill_setup(device))
2010 hp_wmi_rfkill2_setup(device);
2011 }
2012
2013 err = hp_wmi_hwmon_init();
2014
2015 if (err < 0)
2016 return err;
2017
2018 thermal_profile_setup(device);
2019
2020 return 0;
2021 }
2022
hp_wmi_bios_remove(struct platform_device * device)2023 static void __exit hp_wmi_bios_remove(struct platform_device *device)
2024 {
2025 int i;
2026
2027 for (i = 0; i < rfkill2_count; i++) {
2028 rfkill_unregister(rfkill2[i].rfkill);
2029 rfkill_destroy(rfkill2[i].rfkill);
2030 }
2031
2032 if (wifi_rfkill) {
2033 rfkill_unregister(wifi_rfkill);
2034 rfkill_destroy(wifi_rfkill);
2035 }
2036 if (bluetooth_rfkill) {
2037 rfkill_unregister(bluetooth_rfkill);
2038 rfkill_destroy(bluetooth_rfkill);
2039 }
2040 if (wwan_rfkill) {
2041 rfkill_unregister(wwan_rfkill);
2042 rfkill_destroy(wwan_rfkill);
2043 }
2044 }
2045
hp_wmi_resume_handler(struct device * device)2046 static int hp_wmi_resume_handler(struct device *device)
2047 {
2048 /*
2049 * Hardware state may have changed while suspended, so trigger
2050 * input events for the current state. As this is a switch,
2051 * the input layer will only actually pass it on if the state
2052 * changed.
2053 */
2054 if (hp_wmi_input_dev) {
2055 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
2056 input_report_switch(hp_wmi_input_dev, SW_DOCK,
2057 hp_wmi_get_dock_state());
2058 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
2059 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
2060 hp_wmi_get_tablet_mode());
2061 input_sync(hp_wmi_input_dev);
2062 }
2063
2064 if (rfkill2_count)
2065 hp_wmi_rfkill2_refresh();
2066
2067 if (wifi_rfkill)
2068 rfkill_set_states(wifi_rfkill,
2069 hp_wmi_get_sw_state(HPWMI_WIFI),
2070 hp_wmi_get_hw_state(HPWMI_WIFI));
2071 if (bluetooth_rfkill)
2072 rfkill_set_states(bluetooth_rfkill,
2073 hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
2074 hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
2075 if (wwan_rfkill)
2076 rfkill_set_states(wwan_rfkill,
2077 hp_wmi_get_sw_state(HPWMI_WWAN),
2078 hp_wmi_get_hw_state(HPWMI_WWAN));
2079
2080 return 0;
2081 }
2082
2083 static const struct dev_pm_ops hp_wmi_pm_ops = {
2084 .resume = hp_wmi_resume_handler,
2085 .restore = hp_wmi_resume_handler,
2086 };
2087
2088 /*
2089 * hp_wmi_bios_remove() lives in .exit.text. For drivers registered via
2090 * module_platform_driver_probe() this is ok because they cannot get unbound at
2091 * runtime. So mark the driver struct with __refdata to prevent modpost
2092 * triggering a section mismatch warning.
2093 */
2094 static struct platform_driver hp_wmi_driver __refdata = {
2095 .driver = {
2096 .name = "hp-wmi",
2097 .pm = &hp_wmi_pm_ops,
2098 .dev_groups = hp_wmi_groups,
2099 },
2100 .remove = __exit_p(hp_wmi_bios_remove),
2101 };
2102
hp_wmi_hwmon_is_visible(const void * data,enum hwmon_sensor_types type,u32 attr,int channel)2103 static umode_t hp_wmi_hwmon_is_visible(const void *data,
2104 enum hwmon_sensor_types type,
2105 u32 attr, int channel)
2106 {
2107 switch (type) {
2108 case hwmon_pwm:
2109 return 0644;
2110 case hwmon_fan:
2111 if (is_victus_s_thermal_profile()) {
2112 if (hp_wmi_get_fan_speed_victus_s(channel) >= 0)
2113 return 0444;
2114 } else {
2115 if (hp_wmi_get_fan_speed(channel) >= 0)
2116 return 0444;
2117 }
2118 break;
2119 default:
2120 return 0;
2121 }
2122
2123 return 0;
2124 }
2125
hp_wmi_hwmon_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)2126 static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
2127 u32 attr, int channel, long *val)
2128 {
2129 int ret;
2130
2131 switch (type) {
2132 case hwmon_fan:
2133 if (is_victus_s_thermal_profile())
2134 ret = hp_wmi_get_fan_speed_victus_s(channel);
2135 else
2136 ret = hp_wmi_get_fan_speed(channel);
2137 if (ret < 0)
2138 return ret;
2139 *val = ret;
2140 return 0;
2141 case hwmon_pwm:
2142 switch (hp_wmi_fan_speed_max_get()) {
2143 case 0:
2144 /* 0 is automatic fan, which is 2 for hwmon */
2145 *val = 2;
2146 return 0;
2147 case 1:
2148 /* 1 is max fan, which is 0
2149 * (no fan speed control) for hwmon
2150 */
2151 *val = 0;
2152 return 0;
2153 default:
2154 /* shouldn't happen */
2155 return -ENODATA;
2156 }
2157 default:
2158 return -EINVAL;
2159 }
2160 }
2161
hp_wmi_hwmon_write(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long val)2162 static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
2163 u32 attr, int channel, long val)
2164 {
2165 switch (type) {
2166 case hwmon_pwm:
2167 switch (val) {
2168 case 0:
2169 if (is_victus_s_thermal_profile())
2170 hp_wmi_get_fan_count_userdefine_trigger();
2171 /* 0 is no fan speed control (max), which is 1 for us */
2172 return hp_wmi_fan_speed_max_set(1);
2173 case 2:
2174 /* 2 is automatic speed control, which is 0 for us */
2175 if (is_victus_s_thermal_profile()) {
2176 hp_wmi_get_fan_count_userdefine_trigger();
2177 return hp_wmi_fan_speed_max_reset();
2178 } else
2179 return hp_wmi_fan_speed_max_set(0);
2180 default:
2181 /* we don't support manual fan speed control */
2182 return -EINVAL;
2183 }
2184 default:
2185 return -EOPNOTSUPP;
2186 }
2187 }
2188
2189 static const struct hwmon_channel_info * const info[] = {
2190 HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT, HWMON_F_INPUT),
2191 HWMON_CHANNEL_INFO(pwm, HWMON_PWM_ENABLE),
2192 NULL
2193 };
2194
2195 static const struct hwmon_ops ops = {
2196 .is_visible = hp_wmi_hwmon_is_visible,
2197 .read = hp_wmi_hwmon_read,
2198 .write = hp_wmi_hwmon_write,
2199 };
2200
2201 static const struct hwmon_chip_info chip_info = {
2202 .ops = &ops,
2203 .info = info,
2204 };
2205
hp_wmi_hwmon_init(void)2206 static int hp_wmi_hwmon_init(void)
2207 {
2208 struct device *dev = &hp_wmi_platform_dev->dev;
2209 struct device *hwmon;
2210
2211 hwmon = devm_hwmon_device_register_with_info(dev, "hp", &hp_wmi_driver,
2212 &chip_info, NULL);
2213
2214 if (IS_ERR(hwmon)) {
2215 dev_err(dev, "Could not register hp hwmon device\n");
2216 return PTR_ERR(hwmon);
2217 }
2218
2219 return 0;
2220 }
2221
hp_wmi_init(void)2222 static int __init hp_wmi_init(void)
2223 {
2224 int event_capable = wmi_has_guid(HPWMI_EVENT_GUID);
2225 int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID);
2226 int err, tmp = 0;
2227
2228 if (!bios_capable && !event_capable)
2229 return -ENODEV;
2230
2231 if (hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, HPWMI_READ, &tmp,
2232 sizeof(tmp), sizeof(tmp)) == HPWMI_RET_INVALID_PARAMETERS)
2233 zero_insize_support = true;
2234
2235 if (event_capable) {
2236 err = hp_wmi_input_setup();
2237 if (err)
2238 return err;
2239 }
2240
2241 if (bios_capable) {
2242 hp_wmi_platform_dev =
2243 platform_device_register_simple("hp-wmi", PLATFORM_DEVID_NONE, NULL, 0);
2244 if (IS_ERR(hp_wmi_platform_dev)) {
2245 err = PTR_ERR(hp_wmi_platform_dev);
2246 goto err_destroy_input;
2247 }
2248
2249 err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
2250 if (err)
2251 goto err_unregister_device;
2252 }
2253
2254 if (is_omen_thermal_profile() || is_victus_thermal_profile()) {
2255 err = omen_register_powersource_event_handler();
2256 if (err)
2257 goto err_unregister_device;
2258 } else if (is_victus_s_thermal_profile()) {
2259 err = victus_s_register_powersource_event_handler();
2260 if (err)
2261 goto err_unregister_device;
2262 }
2263
2264 return 0;
2265
2266 err_unregister_device:
2267 platform_device_unregister(hp_wmi_platform_dev);
2268 err_destroy_input:
2269 if (event_capable)
2270 hp_wmi_input_destroy();
2271
2272 return err;
2273 }
2274 module_init(hp_wmi_init);
2275
hp_wmi_exit(void)2276 static void __exit hp_wmi_exit(void)
2277 {
2278 if (is_omen_thermal_profile() || is_victus_thermal_profile())
2279 omen_unregister_powersource_event_handler();
2280
2281 if (is_victus_s_thermal_profile())
2282 victus_s_unregister_powersource_event_handler();
2283
2284 if (wmi_has_guid(HPWMI_EVENT_GUID))
2285 hp_wmi_input_destroy();
2286
2287 if (camera_shutter_input_dev)
2288 input_unregister_device(camera_shutter_input_dev);
2289
2290 if (hp_wmi_platform_dev) {
2291 platform_device_unregister(hp_wmi_platform_dev);
2292 platform_driver_unregister(&hp_wmi_driver);
2293 }
2294 }
2295 module_exit(hp_wmi_exit);
2296