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