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