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