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