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