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