xref: /openbmc/linux/drivers/platform/x86/hp/hp-wmi.c (revision 18afb028)
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/rfkill.h>
28 #include <linux/string.h>
29 #include <linux/dmi.h>
30 
31 MODULE_AUTHOR("Matthew Garrett <mjg59@srcf.ucam.org>");
32 MODULE_DESCRIPTION("HP laptop WMI hotkeys driver");
33 MODULE_LICENSE("GPL");
34 
35 MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C");
36 MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
37 
38 #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
39 #define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4"
40 #define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95
41 #define zero_if_sup(tmp) (zero_insize_support?0:sizeof(tmp)) // use when zero insize is required
42 
43 /* DMI board names of devices that should use the omen specific path for
44  * thermal profiles.
45  * This was obtained by taking a look in the windows omen command center
46  * app and parsing a json file that they use to figure out what capabilities
47  * the device should have.
48  * A device is considered an omen if the DisplayName in that list contains
49  * "OMEN", and it can use the thermal profile stuff if the "Feature" array
50  * contains "PerformanceControl".
51  */
52 static const char * const omen_thermal_profile_boards[] = {
53 	"84DA", "84DB", "84DC", "8574", "8575", "860A", "87B5", "8572", "8573",
54 	"8600", "8601", "8602", "8605", "8606", "8607", "8746", "8747", "8749",
55 	"874A", "8603", "8604", "8748", "886B", "886C", "878A", "878B", "878C",
56 	"88C8", "88CB", "8786", "8787", "8788", "88D1", "88D2", "88F4", "88FD",
57 	"88F5", "88F6", "88F7", "88FE", "88FF", "8900", "8901", "8902", "8912",
58 	"8917", "8918", "8949", "894A", "89EB"
59 };
60 
61 /* DMI Board names of Omen laptops that are specifically set to be thermal
62  * profile version 0 by the Omen Command Center app, regardless of what
63  * the get system design information WMI call returns
64  */
65 static const char *const omen_thermal_profile_force_v0_boards[] = {
66 	"8607", "8746", "8747", "8749", "874A", "8748"
67 };
68 
69 /* DMI Board names of Victus laptops */
70 static const char * const victus_thermal_profile_boards[] = {
71 	"8A25"
72 };
73 
74 enum hp_wmi_radio {
75 	HPWMI_WIFI	= 0x0,
76 	HPWMI_BLUETOOTH	= 0x1,
77 	HPWMI_WWAN	= 0x2,
78 	HPWMI_GPS	= 0x3,
79 };
80 
81 enum hp_wmi_event_ids {
82 	HPWMI_DOCK_EVENT		= 0x01,
83 	HPWMI_PARK_HDD			= 0x02,
84 	HPWMI_SMART_ADAPTER		= 0x03,
85 	HPWMI_BEZEL_BUTTON		= 0x04,
86 	HPWMI_WIRELESS			= 0x05,
87 	HPWMI_CPU_BATTERY_THROTTLE	= 0x06,
88 	HPWMI_LOCK_SWITCH		= 0x07,
89 	HPWMI_LID_SWITCH		= 0x08,
90 	HPWMI_SCREEN_ROTATION		= 0x09,
91 	HPWMI_COOLSENSE_SYSTEM_MOBILE	= 0x0A,
92 	HPWMI_COOLSENSE_SYSTEM_HOT	= 0x0B,
93 	HPWMI_PROXIMITY_SENSOR		= 0x0C,
94 	HPWMI_BACKLIT_KB_BRIGHTNESS	= 0x0D,
95 	HPWMI_PEAKSHIFT_PERIOD		= 0x0F,
96 	HPWMI_BATTERY_CHARGE_PERIOD	= 0x10,
97 	HPWMI_SANITIZATION_MODE		= 0x17,
98 	HPWMI_CAMERA_TOGGLE		= 0x1A,
99 	HPWMI_OMEN_KEY			= 0x1D,
100 	HPWMI_SMART_EXPERIENCE_APP	= 0x21,
101 };
102 
103 /*
104  * struct bios_args buffer is dynamically allocated.  New WMI command types
105  * were introduced that exceeds 128-byte data size.  Changes to handle
106  * the data size allocation scheme were kept in hp_wmi_perform_qurey function.
107  */
108 struct bios_args {
109 	u32 signature;
110 	u32 command;
111 	u32 commandtype;
112 	u32 datasize;
113 	u8 data[];
114 };
115 
116 enum hp_wmi_commandtype {
117 	HPWMI_DISPLAY_QUERY		= 0x01,
118 	HPWMI_HDDTEMP_QUERY		= 0x02,
119 	HPWMI_ALS_QUERY			= 0x03,
120 	HPWMI_HARDWARE_QUERY		= 0x04,
121 	HPWMI_WIRELESS_QUERY		= 0x05,
122 	HPWMI_BATTERY_QUERY		= 0x07,
123 	HPWMI_BIOS_QUERY		= 0x09,
124 	HPWMI_FEATURE_QUERY		= 0x0b,
125 	HPWMI_HOTKEY_QUERY		= 0x0c,
126 	HPWMI_FEATURE2_QUERY		= 0x0d,
127 	HPWMI_WIRELESS2_QUERY		= 0x1b,
128 	HPWMI_POSTCODEERROR_QUERY	= 0x2a,
129 	HPWMI_SYSTEM_DEVICE_MODE	= 0x40,
130 	HPWMI_THERMAL_PROFILE_QUERY	= 0x4c,
131 };
132 
133 enum hp_wmi_gm_commandtype {
134 	HPWMI_FAN_SPEED_GET_QUERY = 0x11,
135 	HPWMI_SET_PERFORMANCE_MODE = 0x1A,
136 	HPWMI_FAN_SPEED_MAX_GET_QUERY = 0x26,
137 	HPWMI_FAN_SPEED_MAX_SET_QUERY = 0x27,
138 	HPWMI_GET_SYSTEM_DESIGN_DATA = 0x28,
139 };
140 
141 enum hp_wmi_command {
142 	HPWMI_READ	= 0x01,
143 	HPWMI_WRITE	= 0x02,
144 	HPWMI_ODM	= 0x03,
145 	HPWMI_GM	= 0x20008,
146 };
147 
148 enum hp_wmi_hardware_mask {
149 	HPWMI_DOCK_MASK		= 0x01,
150 	HPWMI_TABLET_MASK	= 0x04,
151 };
152 
153 struct bios_return {
154 	u32 sigpass;
155 	u32 return_code;
156 };
157 
158 enum hp_return_value {
159 	HPWMI_RET_WRONG_SIGNATURE	= 0x02,
160 	HPWMI_RET_UNKNOWN_COMMAND	= 0x03,
161 	HPWMI_RET_UNKNOWN_CMDTYPE	= 0x04,
162 	HPWMI_RET_INVALID_PARAMETERS	= 0x05,
163 };
164 
165 enum hp_wireless2_bits {
166 	HPWMI_POWER_STATE	= 0x01,
167 	HPWMI_POWER_SOFT	= 0x02,
168 	HPWMI_POWER_BIOS	= 0x04,
169 	HPWMI_POWER_HARD	= 0x08,
170 	HPWMI_POWER_FW_OR_HW	= HPWMI_POWER_BIOS | HPWMI_POWER_HARD,
171 };
172 
173 enum hp_thermal_profile_omen_v0 {
174 	HP_OMEN_V0_THERMAL_PROFILE_DEFAULT     = 0x00,
175 	HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE = 0x01,
176 	HP_OMEN_V0_THERMAL_PROFILE_COOL        = 0x02,
177 };
178 
179 enum hp_thermal_profile_omen_v1 {
180 	HP_OMEN_V1_THERMAL_PROFILE_DEFAULT	= 0x30,
181 	HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE	= 0x31,
182 	HP_OMEN_V1_THERMAL_PROFILE_COOL		= 0x50,
183 };
184 
185 enum hp_thermal_profile_victus {
186 	HP_VICTUS_THERMAL_PROFILE_DEFAULT		= 0x00,
187 	HP_VICTUS_THERMAL_PROFILE_PERFORMANCE		= 0x01,
188 	HP_VICTUS_THERMAL_PROFILE_QUIET			= 0x03,
189 };
190 
191 enum hp_thermal_profile {
192 	HP_THERMAL_PROFILE_PERFORMANCE	= 0x00,
193 	HP_THERMAL_PROFILE_DEFAULT		= 0x01,
194 	HP_THERMAL_PROFILE_COOL			= 0x02,
195 	HP_THERMAL_PROFILE_QUIET		= 0x03,
196 };
197 
198 #define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW)
199 #define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT)
200 
201 struct bios_rfkill2_device_state {
202 	u8 radio_type;
203 	u8 bus_type;
204 	u16 vendor_id;
205 	u16 product_id;
206 	u16 subsys_vendor_id;
207 	u16 subsys_product_id;
208 	u8 rfkill_id;
209 	u8 power;
210 	u8 unknown[4];
211 };
212 
213 /* 7 devices fit into the 128 byte buffer */
214 #define HPWMI_MAX_RFKILL2_DEVICES	7
215 
216 struct bios_rfkill2_state {
217 	u8 unknown[7];
218 	u8 count;
219 	u8 pad[8];
220 	struct bios_rfkill2_device_state device[HPWMI_MAX_RFKILL2_DEVICES];
221 };
222 
223 static const struct key_entry hp_wmi_keymap[] = {
224 	{ KE_KEY, 0x02,    { KEY_BRIGHTNESSUP } },
225 	{ KE_KEY, 0x03,    { KEY_BRIGHTNESSDOWN } },
226 	{ KE_KEY, 0x270,   { KEY_MICMUTE } },
227 	{ KE_KEY, 0x20e6,  { KEY_PROG1 } },
228 	{ KE_KEY, 0x20e8,  { KEY_MEDIA } },
229 	{ KE_KEY, 0x2142,  { KEY_MEDIA } },
230 	{ KE_KEY, 0x213b,  { KEY_INFO } },
231 	{ KE_KEY, 0x2169,  { KEY_ROTATE_DISPLAY } },
232 	{ KE_KEY, 0x216a,  { KEY_SETUP } },
233 	{ KE_IGNORE, 0x21a4,  }, /* Win Lock On */
234 	{ KE_IGNORE, 0x121a4, }, /* Win Lock Off */
235 	{ KE_KEY, 0x21a5,  { KEY_PROG2 } }, /* HP Omen Key */
236 	{ KE_KEY, 0x21a7,  { KEY_FN_ESC } },
237 	{ KE_KEY, 0x21a8,  { KEY_PROG2 } }, /* HP Envy x360 programmable key */
238 	{ KE_KEY, 0x21a9,  { KEY_TOUCHPAD_OFF } },
239 	{ KE_KEY, 0x121a9, { KEY_TOUCHPAD_ON } },
240 	{ KE_KEY, 0x231b,  { KEY_HELP } },
241 	{ KE_END, 0 }
242 };
243 
244 static struct input_dev *hp_wmi_input_dev;
245 static struct input_dev *camera_shutter_input_dev;
246 static struct platform_device *hp_wmi_platform_dev;
247 static struct platform_profile_handler platform_profile_handler;
248 static bool platform_profile_support;
249 static bool zero_insize_support;
250 
251 static struct rfkill *wifi_rfkill;
252 static struct rfkill *bluetooth_rfkill;
253 static struct rfkill *wwan_rfkill;
254 
255 struct rfkill2_device {
256 	u8 id;
257 	int num;
258 	struct rfkill *rfkill;
259 };
260 
261 static int rfkill2_count;
262 static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
263 
264 /*
265  * Chassis Types values were obtained from SMBIOS reference
266  * specification version 3.00. A complete list of system enclosures
267  * and chassis types is available on Table 17.
268  */
269 static const char * const tablet_chassis_types[] = {
270 	"30", /* Tablet*/
271 	"31", /* Convertible */
272 	"32"  /* Detachable */
273 };
274 
275 #define DEVICE_MODE_TABLET	0x06
276 
277 /* map output size to the corresponding WMI method id */
278 static inline int encode_outsize_for_pvsz(int outsize)
279 {
280 	if (outsize > 4096)
281 		return -EINVAL;
282 	if (outsize > 1024)
283 		return 5;
284 	if (outsize > 128)
285 		return 4;
286 	if (outsize > 4)
287 		return 3;
288 	if (outsize > 0)
289 		return 2;
290 	return 1;
291 }
292 
293 /*
294  * hp_wmi_perform_query
295  *
296  * query:	The commandtype (enum hp_wmi_commandtype)
297  * write:	The command (enum hp_wmi_command)
298  * buffer:	Buffer used as input and/or output
299  * insize:	Size of input buffer
300  * outsize:	Size of output buffer
301  *
302  * returns zero on success
303  *         an HP WMI query specific error code (which is positive)
304  *         -EINVAL if the query was not successful at all
305  *         -EINVAL if the output buffer size exceeds buffersize
306  *
307  * Note: The buffersize must at least be the maximum of the input and output
308  *       size. E.g. Battery info query is defined to have 1 byte input
309  *       and 128 byte output. The caller would do:
310  *       buffer = kzalloc(128, GFP_KERNEL);
311  *       ret = hp_wmi_perform_query(HPWMI_BATTERY_QUERY, HPWMI_READ, buffer, 1, 128)
312  */
313 static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
314 				void *buffer, int insize, int outsize)
315 {
316 	struct acpi_buffer input, output = { ACPI_ALLOCATE_BUFFER, NULL };
317 	struct bios_return *bios_return;
318 	union acpi_object *obj = NULL;
319 	struct bios_args *args = NULL;
320 	int mid, actual_insize, actual_outsize;
321 	size_t bios_args_size;
322 	int ret;
323 
324 	mid = encode_outsize_for_pvsz(outsize);
325 	if (WARN_ON(mid < 0))
326 		return mid;
327 
328 	actual_insize = max(insize, 128);
329 	bios_args_size = struct_size(args, data, actual_insize);
330 	args = kmalloc(bios_args_size, GFP_KERNEL);
331 	if (!args)
332 		return -ENOMEM;
333 
334 	input.length = bios_args_size;
335 	input.pointer = args;
336 
337 	args->signature = 0x55434553;
338 	args->command = command;
339 	args->commandtype = query;
340 	args->datasize = insize;
341 	memcpy(args->data, buffer, flex_array_size(args, data, insize));
342 
343 	ret = wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
344 	if (ret)
345 		goto out_free;
346 
347 	obj = output.pointer;
348 	if (!obj) {
349 		ret = -EINVAL;
350 		goto out_free;
351 	}
352 
353 	if (obj->type != ACPI_TYPE_BUFFER) {
354 		pr_warn("query 0x%x returned an invalid object 0x%x\n", query, ret);
355 		ret = -EINVAL;
356 		goto out_free;
357 	}
358 
359 	bios_return = (struct bios_return *)obj->buffer.pointer;
360 	ret = bios_return->return_code;
361 
362 	if (ret) {
363 		if (ret != HPWMI_RET_UNKNOWN_COMMAND &&
364 		    ret != HPWMI_RET_UNKNOWN_CMDTYPE)
365 			pr_warn("query 0x%x returned error 0x%x\n", query, ret);
366 		goto out_free;
367 	}
368 
369 	/* Ignore output data of zero size */
370 	if (!outsize)
371 		goto out_free;
372 
373 	actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return)));
374 	memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize);
375 	memset(buffer + actual_outsize, 0, outsize - actual_outsize);
376 
377 out_free:
378 	kfree(obj);
379 	kfree(args);
380 	return ret;
381 }
382 
383 static int hp_wmi_get_fan_speed(int fan)
384 {
385 	u8 fsh, fsl;
386 	char fan_data[4] = { fan, 0, 0, 0 };
387 
388 	int ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_GET_QUERY, HPWMI_GM,
389 				       &fan_data, sizeof(char),
390 				       sizeof(fan_data));
391 
392 	if (ret != 0)
393 		return -EINVAL;
394 
395 	fsh = fan_data[2];
396 	fsl = fan_data[3];
397 
398 	return (fsh << 8) | fsl;
399 }
400 
401 static int hp_wmi_read_int(int query)
402 {
403 	int val = 0, ret;
404 
405 	ret = hp_wmi_perform_query(query, HPWMI_READ, &val,
406 				   zero_if_sup(val), sizeof(val));
407 
408 	if (ret)
409 		return ret < 0 ? ret : -EINVAL;
410 
411 	return val;
412 }
413 
414 static int hp_wmi_get_dock_state(void)
415 {
416 	int state = hp_wmi_read_int(HPWMI_HARDWARE_QUERY);
417 
418 	if (state < 0)
419 		return state;
420 
421 	return !!(state & HPWMI_DOCK_MASK);
422 }
423 
424 static int hp_wmi_get_tablet_mode(void)
425 {
426 	char system_device_mode[4] = { 0 };
427 	const char *chassis_type;
428 	bool tablet_found;
429 	int ret;
430 
431 	chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
432 	if (!chassis_type)
433 		return -ENODEV;
434 
435 	tablet_found = match_string(tablet_chassis_types,
436 				    ARRAY_SIZE(tablet_chassis_types),
437 				    chassis_type) >= 0;
438 	if (!tablet_found)
439 		return -ENODEV;
440 
441 	ret = hp_wmi_perform_query(HPWMI_SYSTEM_DEVICE_MODE, HPWMI_READ,
442 				   system_device_mode, zero_if_sup(system_device_mode),
443 				   sizeof(system_device_mode));
444 	if (ret < 0)
445 		return ret;
446 
447 	return system_device_mode[0] == DEVICE_MODE_TABLET;
448 }
449 
450 static int omen_thermal_profile_set(int mode)
451 {
452 	char buffer[2] = {0, mode};
453 	int ret;
454 
455 	ret = hp_wmi_perform_query(HPWMI_SET_PERFORMANCE_MODE, HPWMI_GM,
456 				   &buffer, sizeof(buffer), 0);
457 
458 	if (ret)
459 		return ret < 0 ? ret : -EINVAL;
460 
461 	return mode;
462 }
463 
464 static bool is_omen_thermal_profile(void)
465 {
466 	const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
467 
468 	if (!board_name)
469 		return false;
470 
471 	return match_string(omen_thermal_profile_boards,
472 			    ARRAY_SIZE(omen_thermal_profile_boards),
473 			    board_name) >= 0;
474 }
475 
476 static int omen_get_thermal_policy_version(void)
477 {
478 	unsigned char buffer[8] = { 0 };
479 	int ret;
480 
481 	const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
482 
483 	if (board_name) {
484 		int matches = match_string(omen_thermal_profile_force_v0_boards,
485 			ARRAY_SIZE(omen_thermal_profile_force_v0_boards),
486 			board_name);
487 		if (matches >= 0)
488 			return 0;
489 	}
490 
491 	ret = hp_wmi_perform_query(HPWMI_GET_SYSTEM_DESIGN_DATA, HPWMI_GM,
492 				   &buffer, sizeof(buffer), sizeof(buffer));
493 
494 	if (ret)
495 		return ret < 0 ? ret : -EINVAL;
496 
497 	return buffer[3];
498 }
499 
500 static int omen_thermal_profile_get(void)
501 {
502 	u8 data;
503 
504 	int ret = ec_read(HP_OMEN_EC_THERMAL_PROFILE_OFFSET, &data);
505 
506 	if (ret)
507 		return ret;
508 
509 	return data;
510 }
511 
512 static int hp_wmi_fan_speed_max_set(int enabled)
513 {
514 	int ret;
515 
516 	ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_SET_QUERY, HPWMI_GM,
517 				   &enabled, sizeof(enabled), 0);
518 
519 	if (ret)
520 		return ret < 0 ? ret : -EINVAL;
521 
522 	return enabled;
523 }
524 
525 static int hp_wmi_fan_speed_max_get(void)
526 {
527 	int val = 0, ret;
528 
529 	ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_GET_QUERY, HPWMI_GM,
530 				   &val, zero_if_sup(val), sizeof(val));
531 
532 	if (ret)
533 		return ret < 0 ? ret : -EINVAL;
534 
535 	return val;
536 }
537 
538 static int __init hp_wmi_bios_2008_later(void)
539 {
540 	int state = 0;
541 	int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, HPWMI_READ, &state,
542 				       zero_if_sup(state), sizeof(state));
543 	if (!ret)
544 		return 1;
545 
546 	return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO;
547 }
548 
549 static int __init hp_wmi_bios_2009_later(void)
550 {
551 	u8 state[128];
552 	int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state,
553 				       zero_if_sup(state), sizeof(state));
554 	if (!ret)
555 		return 1;
556 
557 	return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO;
558 }
559 
560 static int __init hp_wmi_enable_hotkeys(void)
561 {
562 	int value = 0x6e;
563 	int ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, HPWMI_WRITE, &value,
564 				       sizeof(value), 0);
565 
566 	return ret <= 0 ? ret : -EINVAL;
567 }
568 
569 static int hp_wmi_set_block(void *data, bool blocked)
570 {
571 	enum hp_wmi_radio r = (long)data;
572 	int query = BIT(r + 8) | ((!blocked) << r);
573 	int ret;
574 
575 	ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE,
576 				   &query, sizeof(query), 0);
577 
578 	return ret <= 0 ? ret : -EINVAL;
579 }
580 
581 static const struct rfkill_ops hp_wmi_rfkill_ops = {
582 	.set_block = hp_wmi_set_block,
583 };
584 
585 static bool hp_wmi_get_sw_state(enum hp_wmi_radio r)
586 {
587 	int mask = 0x200 << (r * 8);
588 
589 	int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
590 
591 	/* TBD: Pass error */
592 	WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY");
593 
594 	return !(wireless & mask);
595 }
596 
597 static bool hp_wmi_get_hw_state(enum hp_wmi_radio r)
598 {
599 	int mask = 0x800 << (r * 8);
600 
601 	int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
602 
603 	/* TBD: Pass error */
604 	WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY");
605 
606 	return !(wireless & mask);
607 }
608 
609 static int hp_wmi_rfkill2_set_block(void *data, bool blocked)
610 {
611 	int rfkill_id = (int)(long)data;
612 	char buffer[4] = { 0x01, 0x00, rfkill_id, !blocked };
613 	int ret;
614 
615 	ret = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_WRITE,
616 				   buffer, sizeof(buffer), 0);
617 
618 	return ret <= 0 ? ret : -EINVAL;
619 }
620 
621 static const struct rfkill_ops hp_wmi_rfkill2_ops = {
622 	.set_block = hp_wmi_rfkill2_set_block,
623 };
624 
625 static int hp_wmi_rfkill2_refresh(void)
626 {
627 	struct bios_rfkill2_state state;
628 	int err, i;
629 
630 	err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
631 				   zero_if_sup(state), sizeof(state));
632 	if (err)
633 		return err;
634 
635 	for (i = 0; i < rfkill2_count; i++) {
636 		int num = rfkill2[i].num;
637 		struct bios_rfkill2_device_state *devstate;
638 
639 		devstate = &state.device[num];
640 
641 		if (num >= state.count ||
642 		    devstate->rfkill_id != rfkill2[i].id) {
643 			pr_warn("power configuration of the wireless devices unexpectedly changed\n");
644 			continue;
645 		}
646 
647 		rfkill_set_states(rfkill2[i].rfkill,
648 				  IS_SWBLOCKED(devstate->power),
649 				  IS_HWBLOCKED(devstate->power));
650 	}
651 
652 	return 0;
653 }
654 
655 static ssize_t display_show(struct device *dev, struct device_attribute *attr,
656 			    char *buf)
657 {
658 	int value = hp_wmi_read_int(HPWMI_DISPLAY_QUERY);
659 
660 	if (value < 0)
661 		return value;
662 	return sprintf(buf, "%d\n", value);
663 }
664 
665 static ssize_t hddtemp_show(struct device *dev, struct device_attribute *attr,
666 			    char *buf)
667 {
668 	int value = hp_wmi_read_int(HPWMI_HDDTEMP_QUERY);
669 
670 	if (value < 0)
671 		return value;
672 	return sprintf(buf, "%d\n", value);
673 }
674 
675 static ssize_t als_show(struct device *dev, struct device_attribute *attr,
676 			char *buf)
677 {
678 	int value = hp_wmi_read_int(HPWMI_ALS_QUERY);
679 
680 	if (value < 0)
681 		return value;
682 	return sprintf(buf, "%d\n", value);
683 }
684 
685 static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
686 			 char *buf)
687 {
688 	int value = hp_wmi_get_dock_state();
689 
690 	if (value < 0)
691 		return value;
692 	return sprintf(buf, "%d\n", value);
693 }
694 
695 static ssize_t tablet_show(struct device *dev, struct device_attribute *attr,
696 			   char *buf)
697 {
698 	int value = hp_wmi_get_tablet_mode();
699 
700 	if (value < 0)
701 		return value;
702 	return sprintf(buf, "%d\n", value);
703 }
704 
705 static ssize_t postcode_show(struct device *dev, struct device_attribute *attr,
706 			     char *buf)
707 {
708 	/* Get the POST error code of previous boot failure. */
709 	int value = hp_wmi_read_int(HPWMI_POSTCODEERROR_QUERY);
710 
711 	if (value < 0)
712 		return value;
713 	return sprintf(buf, "0x%x\n", value);
714 }
715 
716 static ssize_t als_store(struct device *dev, struct device_attribute *attr,
717 			 const char *buf, size_t count)
718 {
719 	u32 tmp;
720 	int ret;
721 
722 	ret = kstrtou32(buf, 10, &tmp);
723 	if (ret)
724 		return ret;
725 
726 	ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp,
727 				       sizeof(tmp), 0);
728 	if (ret)
729 		return ret < 0 ? ret : -EINVAL;
730 
731 	return count;
732 }
733 
734 static ssize_t postcode_store(struct device *dev, struct device_attribute *attr,
735 			      const char *buf, size_t count)
736 {
737 	u32 tmp = 1;
738 	bool clear;
739 	int ret;
740 
741 	ret = kstrtobool(buf, &clear);
742 	if (ret)
743 		return ret;
744 
745 	if (clear == false)
746 		return -EINVAL;
747 
748 	/* Clear the POST error code. It is kept until cleared. */
749 	ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, HPWMI_WRITE, &tmp,
750 				       sizeof(tmp), 0);
751 	if (ret)
752 		return ret < 0 ? ret : -EINVAL;
753 
754 	return count;
755 }
756 
757 static int camera_shutter_input_setup(void)
758 {
759 	int err;
760 
761 	camera_shutter_input_dev = input_allocate_device();
762 	if (!camera_shutter_input_dev)
763 		return -ENOMEM;
764 
765 	camera_shutter_input_dev->name = "HP WMI camera shutter";
766 	camera_shutter_input_dev->phys = "wmi/input1";
767 	camera_shutter_input_dev->id.bustype = BUS_HOST;
768 
769 	__set_bit(EV_SW, camera_shutter_input_dev->evbit);
770 	__set_bit(SW_CAMERA_LENS_COVER, camera_shutter_input_dev->swbit);
771 
772 	err = input_register_device(camera_shutter_input_dev);
773 	if (err)
774 		goto err_free_dev;
775 
776 	return 0;
777 
778  err_free_dev:
779 	input_free_device(camera_shutter_input_dev);
780 	camera_shutter_input_dev = NULL;
781 	return err;
782 }
783 
784 static DEVICE_ATTR_RO(display);
785 static DEVICE_ATTR_RO(hddtemp);
786 static DEVICE_ATTR_RW(als);
787 static DEVICE_ATTR_RO(dock);
788 static DEVICE_ATTR_RO(tablet);
789 static DEVICE_ATTR_RW(postcode);
790 
791 static struct attribute *hp_wmi_attrs[] = {
792 	&dev_attr_display.attr,
793 	&dev_attr_hddtemp.attr,
794 	&dev_attr_als.attr,
795 	&dev_attr_dock.attr,
796 	&dev_attr_tablet.attr,
797 	&dev_attr_postcode.attr,
798 	NULL,
799 };
800 ATTRIBUTE_GROUPS(hp_wmi);
801 
802 static void hp_wmi_notify(u32 value, void *context)
803 {
804 	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
805 	u32 event_id, event_data;
806 	union acpi_object *obj;
807 	acpi_status status;
808 	u32 *location;
809 	int key_code;
810 
811 	status = wmi_get_event_data(value, &response);
812 	if (status != AE_OK) {
813 		pr_info("bad event status 0x%x\n", status);
814 		return;
815 	}
816 
817 	obj = (union acpi_object *)response.pointer;
818 
819 	if (!obj)
820 		return;
821 	if (obj->type != ACPI_TYPE_BUFFER) {
822 		pr_info("Unknown response received %d\n", obj->type);
823 		kfree(obj);
824 		return;
825 	}
826 
827 	/*
828 	 * Depending on ACPI version the concatenation of id and event data
829 	 * inside _WED function will result in a 8 or 16 byte buffer.
830 	 */
831 	location = (u32 *)obj->buffer.pointer;
832 	if (obj->buffer.length == 8) {
833 		event_id = *location;
834 		event_data = *(location + 1);
835 	} else if (obj->buffer.length == 16) {
836 		event_id = *location;
837 		event_data = *(location + 2);
838 	} else {
839 		pr_info("Unknown buffer length %d\n", obj->buffer.length);
840 		kfree(obj);
841 		return;
842 	}
843 	kfree(obj);
844 
845 	switch (event_id) {
846 	case HPWMI_DOCK_EVENT:
847 		if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
848 			input_report_switch(hp_wmi_input_dev, SW_DOCK,
849 					    hp_wmi_get_dock_state());
850 		if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
851 			input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
852 					    hp_wmi_get_tablet_mode());
853 		input_sync(hp_wmi_input_dev);
854 		break;
855 	case HPWMI_PARK_HDD:
856 		break;
857 	case HPWMI_SMART_ADAPTER:
858 		break;
859 	case HPWMI_BEZEL_BUTTON:
860 		key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY);
861 		if (key_code < 0)
862 			break;
863 
864 		if (!sparse_keymap_report_event(hp_wmi_input_dev,
865 						key_code, 1, true))
866 			pr_info("Unknown key code - 0x%x\n", key_code);
867 		break;
868 	case HPWMI_OMEN_KEY:
869 		if (event_data) /* Only should be true for HP Omen */
870 			key_code = event_data;
871 		else
872 			key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY);
873 
874 		if (!sparse_keymap_report_event(hp_wmi_input_dev,
875 						key_code, 1, true))
876 			pr_info("Unknown key code - 0x%x\n", key_code);
877 		break;
878 	case HPWMI_WIRELESS:
879 		if (rfkill2_count) {
880 			hp_wmi_rfkill2_refresh();
881 			break;
882 		}
883 
884 		if (wifi_rfkill)
885 			rfkill_set_states(wifi_rfkill,
886 					  hp_wmi_get_sw_state(HPWMI_WIFI),
887 					  hp_wmi_get_hw_state(HPWMI_WIFI));
888 		if (bluetooth_rfkill)
889 			rfkill_set_states(bluetooth_rfkill,
890 					  hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
891 					  hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
892 		if (wwan_rfkill)
893 			rfkill_set_states(wwan_rfkill,
894 					  hp_wmi_get_sw_state(HPWMI_WWAN),
895 					  hp_wmi_get_hw_state(HPWMI_WWAN));
896 		break;
897 	case HPWMI_CPU_BATTERY_THROTTLE:
898 		pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n");
899 		break;
900 	case HPWMI_LOCK_SWITCH:
901 		break;
902 	case HPWMI_LID_SWITCH:
903 		break;
904 	case HPWMI_SCREEN_ROTATION:
905 		break;
906 	case HPWMI_COOLSENSE_SYSTEM_MOBILE:
907 		break;
908 	case HPWMI_COOLSENSE_SYSTEM_HOT:
909 		break;
910 	case HPWMI_PROXIMITY_SENSOR:
911 		break;
912 	case HPWMI_BACKLIT_KB_BRIGHTNESS:
913 		break;
914 	case HPWMI_PEAKSHIFT_PERIOD:
915 		break;
916 	case HPWMI_BATTERY_CHARGE_PERIOD:
917 		break;
918 	case HPWMI_SANITIZATION_MODE:
919 		break;
920 	case HPWMI_CAMERA_TOGGLE:
921 		if (!camera_shutter_input_dev)
922 			if (camera_shutter_input_setup()) {
923 				pr_err("Failed to setup camera shutter input device\n");
924 				break;
925 			}
926 		if (event_data == 0xff)
927 			input_report_switch(camera_shutter_input_dev, SW_CAMERA_LENS_COVER, 1);
928 		else if (event_data == 0xfe)
929 			input_report_switch(camera_shutter_input_dev, SW_CAMERA_LENS_COVER, 0);
930 		else
931 			pr_warn("Unknown camera shutter state - 0x%x\n", event_data);
932 		input_sync(camera_shutter_input_dev);
933 		break;
934 	case HPWMI_SMART_EXPERIENCE_APP:
935 		break;
936 	default:
937 		pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
938 		break;
939 	}
940 }
941 
942 static int __init hp_wmi_input_setup(void)
943 {
944 	acpi_status status;
945 	int err, val;
946 
947 	hp_wmi_input_dev = input_allocate_device();
948 	if (!hp_wmi_input_dev)
949 		return -ENOMEM;
950 
951 	hp_wmi_input_dev->name = "HP WMI hotkeys";
952 	hp_wmi_input_dev->phys = "wmi/input0";
953 	hp_wmi_input_dev->id.bustype = BUS_HOST;
954 
955 	__set_bit(EV_SW, hp_wmi_input_dev->evbit);
956 
957 	/* Dock */
958 	val = hp_wmi_get_dock_state();
959 	if (!(val < 0)) {
960 		__set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
961 		input_report_switch(hp_wmi_input_dev, SW_DOCK, val);
962 	}
963 
964 	/* Tablet mode */
965 	val = hp_wmi_get_tablet_mode();
966 	if (!(val < 0)) {
967 		__set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
968 		input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
969 	}
970 
971 	err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
972 	if (err)
973 		goto err_free_dev;
974 
975 	/* Set initial hardware state */
976 	input_sync(hp_wmi_input_dev);
977 
978 	if (!hp_wmi_bios_2009_later() && hp_wmi_bios_2008_later())
979 		hp_wmi_enable_hotkeys();
980 
981 	status = wmi_install_notify_handler(HPWMI_EVENT_GUID, hp_wmi_notify, NULL);
982 	if (ACPI_FAILURE(status)) {
983 		err = -EIO;
984 		goto err_free_dev;
985 	}
986 
987 	err = input_register_device(hp_wmi_input_dev);
988 	if (err)
989 		goto err_uninstall_notifier;
990 
991 	return 0;
992 
993  err_uninstall_notifier:
994 	wmi_remove_notify_handler(HPWMI_EVENT_GUID);
995  err_free_dev:
996 	input_free_device(hp_wmi_input_dev);
997 	return err;
998 }
999 
1000 static void hp_wmi_input_destroy(void)
1001 {
1002 	wmi_remove_notify_handler(HPWMI_EVENT_GUID);
1003 	input_unregister_device(hp_wmi_input_dev);
1004 }
1005 
1006 static int __init hp_wmi_rfkill_setup(struct platform_device *device)
1007 {
1008 	int err, wireless;
1009 
1010 	wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
1011 	if (wireless < 0)
1012 		return wireless;
1013 
1014 	err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE, &wireless,
1015 				   sizeof(wireless), 0);
1016 	if (err)
1017 		return err;
1018 
1019 	if (wireless & 0x1) {
1020 		wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
1021 					   RFKILL_TYPE_WLAN,
1022 					   &hp_wmi_rfkill_ops,
1023 					   (void *) HPWMI_WIFI);
1024 		if (!wifi_rfkill)
1025 			return -ENOMEM;
1026 		rfkill_init_sw_state(wifi_rfkill,
1027 				     hp_wmi_get_sw_state(HPWMI_WIFI));
1028 		rfkill_set_hw_state(wifi_rfkill,
1029 				    hp_wmi_get_hw_state(HPWMI_WIFI));
1030 		err = rfkill_register(wifi_rfkill);
1031 		if (err)
1032 			goto register_wifi_error;
1033 	}
1034 
1035 	if (wireless & 0x2) {
1036 		bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
1037 						RFKILL_TYPE_BLUETOOTH,
1038 						&hp_wmi_rfkill_ops,
1039 						(void *) HPWMI_BLUETOOTH);
1040 		if (!bluetooth_rfkill) {
1041 			err = -ENOMEM;
1042 			goto register_bluetooth_error;
1043 		}
1044 		rfkill_init_sw_state(bluetooth_rfkill,
1045 				     hp_wmi_get_sw_state(HPWMI_BLUETOOTH));
1046 		rfkill_set_hw_state(bluetooth_rfkill,
1047 				    hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
1048 		err = rfkill_register(bluetooth_rfkill);
1049 		if (err)
1050 			goto register_bluetooth_error;
1051 	}
1052 
1053 	if (wireless & 0x4) {
1054 		wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
1055 					   RFKILL_TYPE_WWAN,
1056 					   &hp_wmi_rfkill_ops,
1057 					   (void *) HPWMI_WWAN);
1058 		if (!wwan_rfkill) {
1059 			err = -ENOMEM;
1060 			goto register_wwan_error;
1061 		}
1062 		rfkill_init_sw_state(wwan_rfkill,
1063 				     hp_wmi_get_sw_state(HPWMI_WWAN));
1064 		rfkill_set_hw_state(wwan_rfkill,
1065 				    hp_wmi_get_hw_state(HPWMI_WWAN));
1066 		err = rfkill_register(wwan_rfkill);
1067 		if (err)
1068 			goto register_wwan_error;
1069 	}
1070 
1071 	return 0;
1072 
1073 register_wwan_error:
1074 	rfkill_destroy(wwan_rfkill);
1075 	wwan_rfkill = NULL;
1076 	if (bluetooth_rfkill)
1077 		rfkill_unregister(bluetooth_rfkill);
1078 register_bluetooth_error:
1079 	rfkill_destroy(bluetooth_rfkill);
1080 	bluetooth_rfkill = NULL;
1081 	if (wifi_rfkill)
1082 		rfkill_unregister(wifi_rfkill);
1083 register_wifi_error:
1084 	rfkill_destroy(wifi_rfkill);
1085 	wifi_rfkill = NULL;
1086 	return err;
1087 }
1088 
1089 static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
1090 {
1091 	struct bios_rfkill2_state state;
1092 	int err, i;
1093 
1094 	err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
1095 				   zero_if_sup(state), sizeof(state));
1096 	if (err)
1097 		return err < 0 ? err : -EINVAL;
1098 
1099 	if (state.count > HPWMI_MAX_RFKILL2_DEVICES) {
1100 		pr_warn("unable to parse 0x1b query output\n");
1101 		return -EINVAL;
1102 	}
1103 
1104 	for (i = 0; i < state.count; i++) {
1105 		struct rfkill *rfkill;
1106 		enum rfkill_type type;
1107 		char *name;
1108 
1109 		switch (state.device[i].radio_type) {
1110 		case HPWMI_WIFI:
1111 			type = RFKILL_TYPE_WLAN;
1112 			name = "hp-wifi";
1113 			break;
1114 		case HPWMI_BLUETOOTH:
1115 			type = RFKILL_TYPE_BLUETOOTH;
1116 			name = "hp-bluetooth";
1117 			break;
1118 		case HPWMI_WWAN:
1119 			type = RFKILL_TYPE_WWAN;
1120 			name = "hp-wwan";
1121 			break;
1122 		case HPWMI_GPS:
1123 			type = RFKILL_TYPE_GPS;
1124 			name = "hp-gps";
1125 			break;
1126 		default:
1127 			pr_warn("unknown device type 0x%x\n",
1128 				state.device[i].radio_type);
1129 			continue;
1130 		}
1131 
1132 		if (!state.device[i].vendor_id) {
1133 			pr_warn("zero device %d while %d reported\n",
1134 				i, state.count);
1135 			continue;
1136 		}
1137 
1138 		rfkill = rfkill_alloc(name, &device->dev, type,
1139 				      &hp_wmi_rfkill2_ops, (void *)(long)i);
1140 		if (!rfkill) {
1141 			err = -ENOMEM;
1142 			goto fail;
1143 		}
1144 
1145 		rfkill2[rfkill2_count].id = state.device[i].rfkill_id;
1146 		rfkill2[rfkill2_count].num = i;
1147 		rfkill2[rfkill2_count].rfkill = rfkill;
1148 
1149 		rfkill_init_sw_state(rfkill,
1150 				     IS_SWBLOCKED(state.device[i].power));
1151 		rfkill_set_hw_state(rfkill,
1152 				    IS_HWBLOCKED(state.device[i].power));
1153 
1154 		if (!(state.device[i].power & HPWMI_POWER_BIOS))
1155 			pr_info("device %s blocked by BIOS\n", name);
1156 
1157 		err = rfkill_register(rfkill);
1158 		if (err) {
1159 			rfkill_destroy(rfkill);
1160 			goto fail;
1161 		}
1162 
1163 		rfkill2_count++;
1164 	}
1165 
1166 	return 0;
1167 fail:
1168 	for (; rfkill2_count > 0; rfkill2_count--) {
1169 		rfkill_unregister(rfkill2[rfkill2_count - 1].rfkill);
1170 		rfkill_destroy(rfkill2[rfkill2_count - 1].rfkill);
1171 	}
1172 	return err;
1173 }
1174 
1175 static int platform_profile_omen_get(struct platform_profile_handler *pprof,
1176 				     enum platform_profile_option *profile)
1177 {
1178 	int tp;
1179 
1180 	tp = omen_thermal_profile_get();
1181 	if (tp < 0)
1182 		return tp;
1183 
1184 	switch (tp) {
1185 	case HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE:
1186 	case HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE:
1187 		*profile = PLATFORM_PROFILE_PERFORMANCE;
1188 		break;
1189 	case HP_OMEN_V0_THERMAL_PROFILE_DEFAULT:
1190 	case HP_OMEN_V1_THERMAL_PROFILE_DEFAULT:
1191 		*profile = PLATFORM_PROFILE_BALANCED;
1192 		break;
1193 	case HP_OMEN_V0_THERMAL_PROFILE_COOL:
1194 	case HP_OMEN_V1_THERMAL_PROFILE_COOL:
1195 		*profile = PLATFORM_PROFILE_COOL;
1196 		break;
1197 	default:
1198 		return -EINVAL;
1199 	}
1200 
1201 	return 0;
1202 }
1203 
1204 static int platform_profile_omen_set(struct platform_profile_handler *pprof,
1205 				     enum platform_profile_option profile)
1206 {
1207 	int err, tp, tp_version;
1208 
1209 	tp_version = omen_get_thermal_policy_version();
1210 
1211 	if (tp_version < 0 || tp_version > 1)
1212 		return -EOPNOTSUPP;
1213 
1214 	switch (profile) {
1215 	case PLATFORM_PROFILE_PERFORMANCE:
1216 		if (tp_version == 0)
1217 			tp = HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE;
1218 		else
1219 			tp = HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE;
1220 		break;
1221 	case PLATFORM_PROFILE_BALANCED:
1222 		if (tp_version == 0)
1223 			tp = HP_OMEN_V0_THERMAL_PROFILE_DEFAULT;
1224 		else
1225 			tp = HP_OMEN_V1_THERMAL_PROFILE_DEFAULT;
1226 		break;
1227 	case PLATFORM_PROFILE_COOL:
1228 		if (tp_version == 0)
1229 			tp = HP_OMEN_V0_THERMAL_PROFILE_COOL;
1230 		else
1231 			tp = HP_OMEN_V1_THERMAL_PROFILE_COOL;
1232 		break;
1233 	default:
1234 		return -EOPNOTSUPP;
1235 	}
1236 
1237 	err = omen_thermal_profile_set(tp);
1238 	if (err < 0)
1239 		return err;
1240 
1241 	return 0;
1242 }
1243 
1244 static int thermal_profile_get(void)
1245 {
1246 	return hp_wmi_read_int(HPWMI_THERMAL_PROFILE_QUERY);
1247 }
1248 
1249 static int thermal_profile_set(int thermal_profile)
1250 {
1251 	return hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &thermal_profile,
1252 							   sizeof(thermal_profile), 0);
1253 }
1254 
1255 static int hp_wmi_platform_profile_get(struct platform_profile_handler *pprof,
1256 					enum platform_profile_option *profile)
1257 {
1258 	int tp;
1259 
1260 	tp = thermal_profile_get();
1261 	if (tp < 0)
1262 		return tp;
1263 
1264 	switch (tp) {
1265 	case HP_THERMAL_PROFILE_PERFORMANCE:
1266 		*profile =  PLATFORM_PROFILE_PERFORMANCE;
1267 		break;
1268 	case HP_THERMAL_PROFILE_DEFAULT:
1269 		*profile =  PLATFORM_PROFILE_BALANCED;
1270 		break;
1271 	case HP_THERMAL_PROFILE_COOL:
1272 		*profile =  PLATFORM_PROFILE_COOL;
1273 		break;
1274 	case HP_THERMAL_PROFILE_QUIET:
1275 		*profile = PLATFORM_PROFILE_QUIET;
1276 		break;
1277 	default:
1278 		return -EINVAL;
1279 	}
1280 
1281 	return 0;
1282 }
1283 
1284 static int hp_wmi_platform_profile_set(struct platform_profile_handler *pprof,
1285 					enum platform_profile_option profile)
1286 {
1287 	int err, tp;
1288 
1289 	switch (profile) {
1290 	case PLATFORM_PROFILE_PERFORMANCE:
1291 		tp =  HP_THERMAL_PROFILE_PERFORMANCE;
1292 		break;
1293 	case PLATFORM_PROFILE_BALANCED:
1294 		tp =  HP_THERMAL_PROFILE_DEFAULT;
1295 		break;
1296 	case PLATFORM_PROFILE_COOL:
1297 		tp =  HP_THERMAL_PROFILE_COOL;
1298 		break;
1299 	case PLATFORM_PROFILE_QUIET:
1300 		tp = HP_THERMAL_PROFILE_QUIET;
1301 		break;
1302 	default:
1303 		return -EOPNOTSUPP;
1304 	}
1305 
1306 	err = thermal_profile_set(tp);
1307 	if (err)
1308 		return err;
1309 
1310 	return 0;
1311 }
1312 
1313 static bool is_victus_thermal_profile(void)
1314 {
1315 	const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
1316 
1317 	if (!board_name)
1318 		return false;
1319 
1320 	return match_string(victus_thermal_profile_boards,
1321 			    ARRAY_SIZE(victus_thermal_profile_boards),
1322 			    board_name) >= 0;
1323 }
1324 
1325 static int platform_profile_victus_get(struct platform_profile_handler *pprof,
1326 				     enum platform_profile_option *profile)
1327 {
1328 	int tp;
1329 
1330 	tp = omen_thermal_profile_get();
1331 	if (tp < 0)
1332 		return tp;
1333 
1334 	switch (tp) {
1335 	case HP_VICTUS_THERMAL_PROFILE_PERFORMANCE:
1336 		*profile = PLATFORM_PROFILE_PERFORMANCE;
1337 		break;
1338 	case HP_VICTUS_THERMAL_PROFILE_DEFAULT:
1339 		*profile = PLATFORM_PROFILE_BALANCED;
1340 		break;
1341 	case HP_VICTUS_THERMAL_PROFILE_QUIET:
1342 		*profile = PLATFORM_PROFILE_QUIET;
1343 		break;
1344 	default:
1345 		return -EOPNOTSUPP;
1346 	}
1347 
1348 	return 0;
1349 }
1350 
1351 static int platform_profile_victus_set(struct platform_profile_handler *pprof,
1352 				     enum platform_profile_option profile)
1353 {
1354 	int err, tp;
1355 
1356 	switch (profile) {
1357 	case PLATFORM_PROFILE_PERFORMANCE:
1358 		tp = HP_VICTUS_THERMAL_PROFILE_PERFORMANCE;
1359 		break;
1360 	case PLATFORM_PROFILE_BALANCED:
1361 		tp = HP_VICTUS_THERMAL_PROFILE_DEFAULT;
1362 		break;
1363 	case PLATFORM_PROFILE_QUIET:
1364 		tp = HP_VICTUS_THERMAL_PROFILE_QUIET;
1365 		break;
1366 	default:
1367 		return -EOPNOTSUPP;
1368 	}
1369 
1370 	err = omen_thermal_profile_set(tp);
1371 	if (err < 0)
1372 		return err;
1373 
1374 	return 0;
1375 }
1376 
1377 static int thermal_profile_setup(void)
1378 {
1379 	int err, tp;
1380 
1381 	if (is_omen_thermal_profile()) {
1382 		tp = omen_thermal_profile_get();
1383 		if (tp < 0)
1384 			return tp;
1385 
1386 		/*
1387 		 * call thermal profile write command to ensure that the
1388 		 * firmware correctly sets the OEM variables
1389 		 */
1390 
1391 		err = omen_thermal_profile_set(tp);
1392 		if (err < 0)
1393 			return err;
1394 
1395 		platform_profile_handler.profile_get = platform_profile_omen_get;
1396 		platform_profile_handler.profile_set = platform_profile_omen_set;
1397 
1398 		set_bit(PLATFORM_PROFILE_COOL, platform_profile_handler.choices);
1399 	} else if (is_victus_thermal_profile()) {
1400 		tp = omen_thermal_profile_get();
1401 		if (tp < 0)
1402 			return tp;
1403 
1404 		/*
1405 		 * call thermal profile write command to ensure that the
1406 		 * firmware correctly sets the OEM variables
1407 		 */
1408 		err = omen_thermal_profile_set(tp);
1409 		if (err < 0)
1410 			return err;
1411 
1412 		platform_profile_handler.profile_get = platform_profile_victus_get;
1413 		platform_profile_handler.profile_set = platform_profile_victus_set;
1414 
1415 		set_bit(PLATFORM_PROFILE_QUIET, platform_profile_handler.choices);
1416 	} else {
1417 		tp = thermal_profile_get();
1418 
1419 		if (tp < 0)
1420 			return tp;
1421 
1422 		/*
1423 		 * call thermal profile write command to ensure that the
1424 		 * firmware correctly sets the OEM variables for the DPTF
1425 		 */
1426 		err = thermal_profile_set(tp);
1427 		if (err)
1428 			return err;
1429 
1430 		platform_profile_handler.profile_get = hp_wmi_platform_profile_get;
1431 		platform_profile_handler.profile_set = hp_wmi_platform_profile_set;
1432 
1433 		set_bit(PLATFORM_PROFILE_QUIET, platform_profile_handler.choices);
1434 		set_bit(PLATFORM_PROFILE_COOL, platform_profile_handler.choices);
1435 	}
1436 
1437 	set_bit(PLATFORM_PROFILE_BALANCED, platform_profile_handler.choices);
1438 	set_bit(PLATFORM_PROFILE_PERFORMANCE, platform_profile_handler.choices);
1439 
1440 	err = platform_profile_register(&platform_profile_handler);
1441 	if (err)
1442 		return err;
1443 
1444 	platform_profile_support = true;
1445 
1446 	return 0;
1447 }
1448 
1449 static int hp_wmi_hwmon_init(void);
1450 
1451 static int __init hp_wmi_bios_setup(struct platform_device *device)
1452 {
1453 	int err;
1454 	/* clear detected rfkill devices */
1455 	wifi_rfkill = NULL;
1456 	bluetooth_rfkill = NULL;
1457 	wwan_rfkill = NULL;
1458 	rfkill2_count = 0;
1459 
1460 	/*
1461 	 * In pre-2009 BIOS, command 1Bh return 0x4 to indicate that
1462 	 * BIOS no longer controls the power for the wireless
1463 	 * devices. All features supported by this command will no
1464 	 * longer be supported.
1465 	 */
1466 	if (!hp_wmi_bios_2009_later()) {
1467 		if (hp_wmi_rfkill_setup(device))
1468 			hp_wmi_rfkill2_setup(device);
1469 	}
1470 
1471 	err = hp_wmi_hwmon_init();
1472 
1473 	if (err < 0)
1474 		return err;
1475 
1476 	thermal_profile_setup();
1477 
1478 	return 0;
1479 }
1480 
1481 static int __exit hp_wmi_bios_remove(struct platform_device *device)
1482 {
1483 	int i;
1484 
1485 	for (i = 0; i < rfkill2_count; i++) {
1486 		rfkill_unregister(rfkill2[i].rfkill);
1487 		rfkill_destroy(rfkill2[i].rfkill);
1488 	}
1489 
1490 	if (wifi_rfkill) {
1491 		rfkill_unregister(wifi_rfkill);
1492 		rfkill_destroy(wifi_rfkill);
1493 	}
1494 	if (bluetooth_rfkill) {
1495 		rfkill_unregister(bluetooth_rfkill);
1496 		rfkill_destroy(bluetooth_rfkill);
1497 	}
1498 	if (wwan_rfkill) {
1499 		rfkill_unregister(wwan_rfkill);
1500 		rfkill_destroy(wwan_rfkill);
1501 	}
1502 
1503 	if (platform_profile_support)
1504 		platform_profile_remove();
1505 
1506 	return 0;
1507 }
1508 
1509 static int hp_wmi_resume_handler(struct device *device)
1510 {
1511 	/*
1512 	 * Hardware state may have changed while suspended, so trigger
1513 	 * input events for the current state. As this is a switch,
1514 	 * the input layer will only actually pass it on if the state
1515 	 * changed.
1516 	 */
1517 	if (hp_wmi_input_dev) {
1518 		if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
1519 			input_report_switch(hp_wmi_input_dev, SW_DOCK,
1520 					    hp_wmi_get_dock_state());
1521 		if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
1522 			input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
1523 					    hp_wmi_get_tablet_mode());
1524 		input_sync(hp_wmi_input_dev);
1525 	}
1526 
1527 	if (rfkill2_count)
1528 		hp_wmi_rfkill2_refresh();
1529 
1530 	if (wifi_rfkill)
1531 		rfkill_set_states(wifi_rfkill,
1532 				  hp_wmi_get_sw_state(HPWMI_WIFI),
1533 				  hp_wmi_get_hw_state(HPWMI_WIFI));
1534 	if (bluetooth_rfkill)
1535 		rfkill_set_states(bluetooth_rfkill,
1536 				  hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
1537 				  hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
1538 	if (wwan_rfkill)
1539 		rfkill_set_states(wwan_rfkill,
1540 				  hp_wmi_get_sw_state(HPWMI_WWAN),
1541 				  hp_wmi_get_hw_state(HPWMI_WWAN));
1542 
1543 	return 0;
1544 }
1545 
1546 static const struct dev_pm_ops hp_wmi_pm_ops = {
1547 	.resume  = hp_wmi_resume_handler,
1548 	.restore  = hp_wmi_resume_handler,
1549 };
1550 
1551 /*
1552  * hp_wmi_bios_remove() lives in .exit.text. For drivers registered via
1553  * module_platform_driver_probe() this is ok because they cannot get unbound at
1554  * runtime. So mark the driver struct with __refdata to prevent modpost
1555  * triggering a section mismatch warning.
1556  */
1557 static struct platform_driver hp_wmi_driver __refdata = {
1558 	.driver = {
1559 		.name = "hp-wmi",
1560 		.pm = &hp_wmi_pm_ops,
1561 		.dev_groups = hp_wmi_groups,
1562 	},
1563 	.remove = __exit_p(hp_wmi_bios_remove),
1564 };
1565 
1566 static umode_t hp_wmi_hwmon_is_visible(const void *data,
1567 				       enum hwmon_sensor_types type,
1568 				       u32 attr, int channel)
1569 {
1570 	switch (type) {
1571 	case hwmon_pwm:
1572 		return 0644;
1573 	case hwmon_fan:
1574 		if (hp_wmi_get_fan_speed(channel) >= 0)
1575 			return 0444;
1576 		break;
1577 	default:
1578 		return 0;
1579 	}
1580 
1581 	return 0;
1582 }
1583 
1584 static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
1585 			     u32 attr, int channel, long *val)
1586 {
1587 	int ret;
1588 
1589 	switch (type) {
1590 	case hwmon_fan:
1591 		ret = hp_wmi_get_fan_speed(channel);
1592 
1593 		if (ret < 0)
1594 			return ret;
1595 		*val = ret;
1596 		return 0;
1597 	case hwmon_pwm:
1598 		switch (hp_wmi_fan_speed_max_get()) {
1599 		case 0:
1600 			/* 0 is automatic fan, which is 2 for hwmon */
1601 			*val = 2;
1602 			return 0;
1603 		case 1:
1604 			/* 1 is max fan, which is 0
1605 			 * (no fan speed control) for hwmon
1606 			 */
1607 			*val = 0;
1608 			return 0;
1609 		default:
1610 			/* shouldn't happen */
1611 			return -ENODATA;
1612 		}
1613 	default:
1614 		return -EINVAL;
1615 	}
1616 }
1617 
1618 static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
1619 			      u32 attr, int channel, long val)
1620 {
1621 	switch (type) {
1622 	case hwmon_pwm:
1623 		switch (val) {
1624 		case 0:
1625 			/* 0 is no fan speed control (max), which is 1 for us */
1626 			return hp_wmi_fan_speed_max_set(1);
1627 		case 2:
1628 			/* 2 is automatic speed control, which is 0 for us */
1629 			return hp_wmi_fan_speed_max_set(0);
1630 		default:
1631 			/* we don't support manual fan speed control */
1632 			return -EINVAL;
1633 		}
1634 	default:
1635 		return -EOPNOTSUPP;
1636 	}
1637 }
1638 
1639 static const struct hwmon_channel_info * const info[] = {
1640 	HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT, HWMON_F_INPUT),
1641 	HWMON_CHANNEL_INFO(pwm, HWMON_PWM_ENABLE),
1642 	NULL
1643 };
1644 
1645 static const struct hwmon_ops ops = {
1646 	.is_visible = hp_wmi_hwmon_is_visible,
1647 	.read = hp_wmi_hwmon_read,
1648 	.write = hp_wmi_hwmon_write,
1649 };
1650 
1651 static const struct hwmon_chip_info chip_info = {
1652 	.ops = &ops,
1653 	.info = info,
1654 };
1655 
1656 static int hp_wmi_hwmon_init(void)
1657 {
1658 	struct device *dev = &hp_wmi_platform_dev->dev;
1659 	struct device *hwmon;
1660 
1661 	hwmon = devm_hwmon_device_register_with_info(dev, "hp", &hp_wmi_driver,
1662 						     &chip_info, NULL);
1663 
1664 	if (IS_ERR(hwmon)) {
1665 		dev_err(dev, "Could not register hp hwmon device\n");
1666 		return PTR_ERR(hwmon);
1667 	}
1668 
1669 	return 0;
1670 }
1671 
1672 static int __init hp_wmi_init(void)
1673 {
1674 	int event_capable = wmi_has_guid(HPWMI_EVENT_GUID);
1675 	int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID);
1676 	int err, tmp = 0;
1677 
1678 	if (!bios_capable && !event_capable)
1679 		return -ENODEV;
1680 
1681 	if (hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, HPWMI_READ, &tmp,
1682 				 sizeof(tmp), sizeof(tmp)) == HPWMI_RET_INVALID_PARAMETERS)
1683 		zero_insize_support = true;
1684 
1685 	if (event_capable) {
1686 		err = hp_wmi_input_setup();
1687 		if (err)
1688 			return err;
1689 	}
1690 
1691 	if (bios_capable) {
1692 		hp_wmi_platform_dev =
1693 			platform_device_register_simple("hp-wmi", PLATFORM_DEVID_NONE, NULL, 0);
1694 		if (IS_ERR(hp_wmi_platform_dev)) {
1695 			err = PTR_ERR(hp_wmi_platform_dev);
1696 			goto err_destroy_input;
1697 		}
1698 
1699 		err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
1700 		if (err)
1701 			goto err_unregister_device;
1702 	}
1703 
1704 	return 0;
1705 
1706 err_unregister_device:
1707 	platform_device_unregister(hp_wmi_platform_dev);
1708 err_destroy_input:
1709 	if (event_capable)
1710 		hp_wmi_input_destroy();
1711 
1712 	return err;
1713 }
1714 module_init(hp_wmi_init);
1715 
1716 static void __exit hp_wmi_exit(void)
1717 {
1718 	if (wmi_has_guid(HPWMI_EVENT_GUID))
1719 		hp_wmi_input_destroy();
1720 
1721 	if (camera_shutter_input_dev)
1722 		input_unregister_device(camera_shutter_input_dev);
1723 
1724 	if (hp_wmi_platform_dev) {
1725 		platform_device_unregister(hp_wmi_platform_dev);
1726 		platform_driver_unregister(&hp_wmi_driver);
1727 	}
1728 }
1729 module_exit(hp_wmi_exit);
1730