xref: /linux/drivers/platform/x86/hp/hp-wmi.c (revision 9d588a1140b9ae211581a7a154d0b806d8cd8238)
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(&current_ctgp_state,
1628 					       &current_ppab_state,
1629 					       &current_dstate,
1630 					       &current_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