]> Git Repo - linux.git/blob - drivers/platform/x86/hp/hp-wmi.c
dma-mapping: don't return errors from dma_set_max_seg_size
[linux.git] / drivers / platform / x86 / hp / hp-wmi.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * HP WMI hotkeys
4  *
5  * Copyright (C) 2008 Red Hat <[email protected]>
6  * Copyright (C) 2010, 2011 Anssi Hannula <[email protected]>
7  *
8  * Portions based on wistron_btns.c:
9  * Copyright (C) 2005 Miloslav Trmac <[email protected]>
10  * Copyright (C) 2005 Bernhard Rosenkraenzer <[email protected]>
11  * Copyright (C) 2005 Dmitry Torokhov <[email protected]>
12  */
13
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/slab.h>
20 #include <linux/types.h>
21 #include <linux/input.h>
22 #include <linux/input/sparse-keymap.h>
23 #include <linux/platform_device.h>
24 #include <linux/platform_profile.h>
25 #include <linux/hwmon.h>
26 #include <linux/acpi.h>
27 #include <linux/mutex.h>
28 #include <linux/cleanup.h>
29 #include <linux/power_supply.h>
30 #include <linux/rfkill.h>
31 #include <linux/string.h>
32 #include <linux/dmi.h>
33
34 MODULE_AUTHOR("Matthew Garrett <[email protected]>");
35 MODULE_DESCRIPTION("HP laptop WMI driver");
36 MODULE_LICENSE("GPL");
37
38 MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C");
39 MODULE_ALIAS("wmi:5FB7F034-2C63-45E9-BE91-3D44E2C707E4");
40
41 #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
42 #define HPWMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4"
43
44 #define HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET 0x62
45 #define HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET 0x63
46 #define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95
47
48 #define ACPI_AC_CLASS "ac_adapter"
49
50 #define zero_if_sup(tmp) (zero_insize_support?0:sizeof(tmp)) // use when zero insize is required
51
52 /* DMI board names of devices that should use the omen specific path for
53  * thermal profiles.
54  * This was obtained by taking a look in the windows omen command center
55  * app and parsing a json file that they use to figure out what capabilities
56  * the device should have.
57  * A device is considered an omen if the DisplayName in that list contains
58  * "OMEN", and it can use the thermal profile stuff if the "Feature" array
59  * contains "PerformanceControl".
60  */
61 static const char * const omen_thermal_profile_boards[] = {
62         "84DA", "84DB", "84DC", "8574", "8575", "860A", "87B5", "8572", "8573",
63         "8600", "8601", "8602", "8605", "8606", "8607", "8746", "8747", "8749",
64         "874A", "8603", "8604", "8748", "886B", "886C", "878A", "878B", "878C",
65         "88C8", "88CB", "8786", "8787", "8788", "88D1", "88D2", "88F4", "88FD",
66         "88F5", "88F6", "88F7", "88FE", "88FF", "8900", "8901", "8902", "8912",
67         "8917", "8918", "8949", "894A", "89EB", "8BAD", "8A42"
68 };
69
70 /* DMI Board names of Omen laptops that are specifically set to be thermal
71  * profile version 0 by the Omen Command Center app, regardless of what
72  * the get system design information WMI call returns
73  */
74 static const char * const omen_thermal_profile_force_v0_boards[] = {
75         "8607", "8746", "8747", "8749", "874A", "8748"
76 };
77
78 /* DMI board names of Omen laptops that have a thermal profile timer which will
79  * cause the embedded controller to set the thermal profile back to
80  * "balanced" when reaching zero.
81  */
82 static const char * const omen_timed_thermal_profile_boards[] = {
83         "8BAD", "8A42"
84 };
85
86 /* DMI Board names of Victus laptops */
87 static const char * const victus_thermal_profile_boards[] = {
88         "8A25"
89 };
90
91 enum hp_wmi_radio {
92         HPWMI_WIFI      = 0x0,
93         HPWMI_BLUETOOTH = 0x1,
94         HPWMI_WWAN      = 0x2,
95         HPWMI_GPS       = 0x3,
96 };
97
98 enum hp_wmi_event_ids {
99         HPWMI_DOCK_EVENT                = 0x01,
100         HPWMI_PARK_HDD                  = 0x02,
101         HPWMI_SMART_ADAPTER             = 0x03,
102         HPWMI_BEZEL_BUTTON              = 0x04,
103         HPWMI_WIRELESS                  = 0x05,
104         HPWMI_CPU_BATTERY_THROTTLE      = 0x06,
105         HPWMI_LOCK_SWITCH               = 0x07,
106         HPWMI_LID_SWITCH                = 0x08,
107         HPWMI_SCREEN_ROTATION           = 0x09,
108         HPWMI_COOLSENSE_SYSTEM_MOBILE   = 0x0A,
109         HPWMI_COOLSENSE_SYSTEM_HOT      = 0x0B,
110         HPWMI_PROXIMITY_SENSOR          = 0x0C,
111         HPWMI_BACKLIT_KB_BRIGHTNESS     = 0x0D,
112         HPWMI_PEAKSHIFT_PERIOD          = 0x0F,
113         HPWMI_BATTERY_CHARGE_PERIOD     = 0x10,
114         HPWMI_SANITIZATION_MODE         = 0x17,
115         HPWMI_CAMERA_TOGGLE             = 0x1A,
116         HPWMI_OMEN_KEY                  = 0x1D,
117         HPWMI_SMART_EXPERIENCE_APP      = 0x21,
118 };
119
120 /*
121  * struct bios_args buffer is dynamically allocated.  New WMI command types
122  * were introduced that exceeds 128-byte data size.  Changes to handle
123  * the data size allocation scheme were kept in hp_wmi_perform_qurey function.
124  */
125 struct bios_args {
126         u32 signature;
127         u32 command;
128         u32 commandtype;
129         u32 datasize;
130         u8 data[];
131 };
132
133 enum hp_wmi_commandtype {
134         HPWMI_DISPLAY_QUERY             = 0x01,
135         HPWMI_HDDTEMP_QUERY             = 0x02,
136         HPWMI_ALS_QUERY                 = 0x03,
137         HPWMI_HARDWARE_QUERY            = 0x04,
138         HPWMI_WIRELESS_QUERY            = 0x05,
139         HPWMI_BATTERY_QUERY             = 0x07,
140         HPWMI_BIOS_QUERY                = 0x09,
141         HPWMI_FEATURE_QUERY             = 0x0b,
142         HPWMI_HOTKEY_QUERY              = 0x0c,
143         HPWMI_FEATURE2_QUERY            = 0x0d,
144         HPWMI_WIRELESS2_QUERY           = 0x1b,
145         HPWMI_POSTCODEERROR_QUERY       = 0x2a,
146         HPWMI_SYSTEM_DEVICE_MODE        = 0x40,
147         HPWMI_THERMAL_PROFILE_QUERY     = 0x4c,
148 };
149
150 enum hp_wmi_gm_commandtype {
151         HPWMI_FAN_SPEED_GET_QUERY = 0x11,
152         HPWMI_SET_PERFORMANCE_MODE = 0x1A,
153         HPWMI_FAN_SPEED_MAX_GET_QUERY = 0x26,
154         HPWMI_FAN_SPEED_MAX_SET_QUERY = 0x27,
155         HPWMI_GET_SYSTEM_DESIGN_DATA = 0x28,
156 };
157
158 enum hp_wmi_command {
159         HPWMI_READ      = 0x01,
160         HPWMI_WRITE     = 0x02,
161         HPWMI_ODM       = 0x03,
162         HPWMI_GM        = 0x20008,
163 };
164
165 enum hp_wmi_hardware_mask {
166         HPWMI_DOCK_MASK         = 0x01,
167         HPWMI_TABLET_MASK       = 0x04,
168 };
169
170 struct bios_return {
171         u32 sigpass;
172         u32 return_code;
173 };
174
175 enum hp_return_value {
176         HPWMI_RET_WRONG_SIGNATURE       = 0x02,
177         HPWMI_RET_UNKNOWN_COMMAND       = 0x03,
178         HPWMI_RET_UNKNOWN_CMDTYPE       = 0x04,
179         HPWMI_RET_INVALID_PARAMETERS    = 0x05,
180 };
181
182 enum hp_wireless2_bits {
183         HPWMI_POWER_STATE       = 0x01,
184         HPWMI_POWER_SOFT        = 0x02,
185         HPWMI_POWER_BIOS        = 0x04,
186         HPWMI_POWER_HARD        = 0x08,
187         HPWMI_POWER_FW_OR_HW    = HPWMI_POWER_BIOS | HPWMI_POWER_HARD,
188 };
189
190 enum hp_thermal_profile_omen_v0 {
191         HP_OMEN_V0_THERMAL_PROFILE_DEFAULT     = 0x00,
192         HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE = 0x01,
193         HP_OMEN_V0_THERMAL_PROFILE_COOL        = 0x02,
194 };
195
196 enum hp_thermal_profile_omen_v1 {
197         HP_OMEN_V1_THERMAL_PROFILE_DEFAULT      = 0x30,
198         HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE  = 0x31,
199         HP_OMEN_V1_THERMAL_PROFILE_COOL         = 0x50,
200 };
201
202 enum hp_thermal_profile_omen_flags {
203         HP_OMEN_EC_FLAGS_TURBO          = 0x04,
204         HP_OMEN_EC_FLAGS_NOTIMER        = 0x02,
205         HP_OMEN_EC_FLAGS_JUSTSET        = 0x01,
206 };
207
208 enum hp_thermal_profile_victus {
209         HP_VICTUS_THERMAL_PROFILE_DEFAULT               = 0x00,
210         HP_VICTUS_THERMAL_PROFILE_PERFORMANCE           = 0x01,
211         HP_VICTUS_THERMAL_PROFILE_QUIET                 = 0x03,
212 };
213
214 enum hp_thermal_profile {
215         HP_THERMAL_PROFILE_PERFORMANCE  = 0x00,
216         HP_THERMAL_PROFILE_DEFAULT              = 0x01,
217         HP_THERMAL_PROFILE_COOL                 = 0x02,
218         HP_THERMAL_PROFILE_QUIET                = 0x03,
219 };
220
221 #define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW)
222 #define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT)
223
224 struct bios_rfkill2_device_state {
225         u8 radio_type;
226         u8 bus_type;
227         u16 vendor_id;
228         u16 product_id;
229         u16 subsys_vendor_id;
230         u16 subsys_product_id;
231         u8 rfkill_id;
232         u8 power;
233         u8 unknown[4];
234 };
235
236 /* 7 devices fit into the 128 byte buffer */
237 #define HPWMI_MAX_RFKILL2_DEVICES       7
238
239 struct bios_rfkill2_state {
240         u8 unknown[7];
241         u8 count;
242         u8 pad[8];
243         struct bios_rfkill2_device_state device[HPWMI_MAX_RFKILL2_DEVICES];
244 };
245
246 static const struct key_entry hp_wmi_keymap[] = {
247         { KE_KEY, 0x02,    { KEY_BRIGHTNESSUP } },
248         { KE_KEY, 0x03,    { KEY_BRIGHTNESSDOWN } },
249         { KE_KEY, 0x270,   { KEY_MICMUTE } },
250         { KE_KEY, 0x20e6,  { KEY_PROG1 } },
251         { KE_KEY, 0x20e8,  { KEY_MEDIA } },
252         { KE_KEY, 0x2142,  { KEY_MEDIA } },
253         { KE_KEY, 0x213b,  { KEY_INFO } },
254         { KE_KEY, 0x2169,  { KEY_ROTATE_DISPLAY } },
255         { KE_KEY, 0x216a,  { KEY_SETUP } },
256         { KE_IGNORE, 0x21a4,  }, /* Win Lock On */
257         { KE_IGNORE, 0x121a4, }, /* Win Lock Off */
258         { KE_KEY, 0x21a5,  { KEY_PROG2 } }, /* HP Omen Key */
259         { KE_KEY, 0x21a7,  { KEY_FN_ESC } },
260         { KE_KEY, 0x21a8,  { KEY_PROG2 } }, /* HP Envy x360 programmable key */
261         { KE_KEY, 0x21a9,  { KEY_TOUCHPAD_OFF } },
262         { KE_KEY, 0x121a9, { KEY_TOUCHPAD_ON } },
263         { KE_KEY, 0x231b,  { KEY_HELP } },
264         { KE_END, 0 }
265 };
266
267 /*
268  * Mutex for the active_platform_profile variable,
269  * see omen_powersource_event.
270  */
271 static DEFINE_MUTEX(active_platform_profile_lock);
272
273 static struct input_dev *hp_wmi_input_dev;
274 static struct input_dev *camera_shutter_input_dev;
275 static struct platform_device *hp_wmi_platform_dev;
276 static struct platform_profile_handler platform_profile_handler;
277 static struct notifier_block platform_power_source_nb;
278 static enum platform_profile_option active_platform_profile;
279 static bool platform_profile_support;
280 static bool zero_insize_support;
281
282 static struct rfkill *wifi_rfkill;
283 static struct rfkill *bluetooth_rfkill;
284 static struct rfkill *wwan_rfkill;
285
286 struct rfkill2_device {
287         u8 id;
288         int num;
289         struct rfkill *rfkill;
290 };
291
292 static int rfkill2_count;
293 static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
294
295 /*
296  * Chassis Types values were obtained from SMBIOS reference
297  * specification version 3.00. A complete list of system enclosures
298  * and chassis types is available on Table 17.
299  */
300 static const char * const tablet_chassis_types[] = {
301         "30", /* Tablet*/
302         "31", /* Convertible */
303         "32"  /* Detachable */
304 };
305
306 #define DEVICE_MODE_TABLET      0x06
307
308 /* map output size to the corresponding WMI method id */
309 static inline int encode_outsize_for_pvsz(int outsize)
310 {
311         if (outsize > 4096)
312                 return -EINVAL;
313         if (outsize > 1024)
314                 return 5;
315         if (outsize > 128)
316                 return 4;
317         if (outsize > 4)
318                 return 3;
319         if (outsize > 0)
320                 return 2;
321         return 1;
322 }
323
324 /*
325  * hp_wmi_perform_query
326  *
327  * query:       The commandtype (enum hp_wmi_commandtype)
328  * write:       The command (enum hp_wmi_command)
329  * buffer:      Buffer used as input and/or output
330  * insize:      Size of input buffer
331  * outsize:     Size of output buffer
332  *
333  * returns zero on success
334  *         an HP WMI query specific error code (which is positive)
335  *         -EINVAL if the query was not successful at all
336  *         -EINVAL if the output buffer size exceeds buffersize
337  *
338  * Note: The buffersize must at least be the maximum of the input and output
339  *       size. E.g. Battery info query is defined to have 1 byte input
340  *       and 128 byte output. The caller would do:
341  *       buffer = kzalloc(128, GFP_KERNEL);
342  *       ret = hp_wmi_perform_query(HPWMI_BATTERY_QUERY, HPWMI_READ, buffer, 1, 128)
343  */
344 static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
345                                 void *buffer, int insize, int outsize)
346 {
347         struct acpi_buffer input, output = { ACPI_ALLOCATE_BUFFER, NULL };
348         struct bios_return *bios_return;
349         union acpi_object *obj = NULL;
350         struct bios_args *args = NULL;
351         int mid, actual_insize, actual_outsize;
352         size_t bios_args_size;
353         int ret;
354
355         mid = encode_outsize_for_pvsz(outsize);
356         if (WARN_ON(mid < 0))
357                 return mid;
358
359         actual_insize = max(insize, 128);
360         bios_args_size = struct_size(args, data, actual_insize);
361         args = kmalloc(bios_args_size, GFP_KERNEL);
362         if (!args)
363                 return -ENOMEM;
364
365         input.length = bios_args_size;
366         input.pointer = args;
367
368         args->signature = 0x55434553;
369         args->command = command;
370         args->commandtype = query;
371         args->datasize = insize;
372         memcpy(args->data, buffer, flex_array_size(args, data, insize));
373
374         ret = wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
375         if (ret)
376                 goto out_free;
377
378         obj = output.pointer;
379         if (!obj) {
380                 ret = -EINVAL;
381                 goto out_free;
382         }
383
384         if (obj->type != ACPI_TYPE_BUFFER) {
385                 pr_warn("query 0x%x returned an invalid object 0x%x\n", query, ret);
386                 ret = -EINVAL;
387                 goto out_free;
388         }
389
390         bios_return = (struct bios_return *)obj->buffer.pointer;
391         ret = bios_return->return_code;
392
393         if (ret) {
394                 if (ret != HPWMI_RET_UNKNOWN_COMMAND &&
395                     ret != HPWMI_RET_UNKNOWN_CMDTYPE)
396                         pr_warn("query 0x%x returned error 0x%x\n", query, ret);
397                 goto out_free;
398         }
399
400         /* Ignore output data of zero size */
401         if (!outsize)
402                 goto out_free;
403
404         actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return)));
405         memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize);
406         memset(buffer + actual_outsize, 0, outsize - actual_outsize);
407
408 out_free:
409         kfree(obj);
410         kfree(args);
411         return ret;
412 }
413
414 static int hp_wmi_get_fan_speed(int fan)
415 {
416         u8 fsh, fsl;
417         char fan_data[4] = { fan, 0, 0, 0 };
418
419         int ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_GET_QUERY, HPWMI_GM,
420                                        &fan_data, sizeof(char),
421                                        sizeof(fan_data));
422
423         if (ret != 0)
424                 return -EINVAL;
425
426         fsh = fan_data[2];
427         fsl = fan_data[3];
428
429         return (fsh << 8) | fsl;
430 }
431
432 static int hp_wmi_read_int(int query)
433 {
434         int val = 0, ret;
435
436         ret = hp_wmi_perform_query(query, HPWMI_READ, &val,
437                                    zero_if_sup(val), sizeof(val));
438
439         if (ret)
440                 return ret < 0 ? ret : -EINVAL;
441
442         return val;
443 }
444
445 static int hp_wmi_get_dock_state(void)
446 {
447         int state = hp_wmi_read_int(HPWMI_HARDWARE_QUERY);
448
449         if (state < 0)
450                 return state;
451
452         return !!(state & HPWMI_DOCK_MASK);
453 }
454
455 static int hp_wmi_get_tablet_mode(void)
456 {
457         char system_device_mode[4] = { 0 };
458         const char *chassis_type;
459         bool tablet_found;
460         int ret;
461
462         chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
463         if (!chassis_type)
464                 return -ENODEV;
465
466         tablet_found = match_string(tablet_chassis_types,
467                                     ARRAY_SIZE(tablet_chassis_types),
468                                     chassis_type) >= 0;
469         if (!tablet_found)
470                 return -ENODEV;
471
472         ret = hp_wmi_perform_query(HPWMI_SYSTEM_DEVICE_MODE, HPWMI_READ,
473                                    system_device_mode, zero_if_sup(system_device_mode),
474                                    sizeof(system_device_mode));
475         if (ret < 0)
476                 return ret;
477
478         return system_device_mode[0] == DEVICE_MODE_TABLET;
479 }
480
481 static int omen_thermal_profile_set(int mode)
482 {
483         /* The Omen Control Center actively sets the first byte of the buffer to
484          * 255, so let's mimic this behaviour to be as close as possible to
485          * the original software.
486          */
487         char buffer[2] = {-1, mode};
488         int ret;
489
490         ret = hp_wmi_perform_query(HPWMI_SET_PERFORMANCE_MODE, HPWMI_GM,
491                                    &buffer, sizeof(buffer), 0);
492
493         if (ret)
494                 return ret < 0 ? ret : -EINVAL;
495
496         return mode;
497 }
498
499 static bool is_omen_thermal_profile(void)
500 {
501         const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
502
503         if (!board_name)
504                 return false;
505
506         return match_string(omen_thermal_profile_boards,
507                             ARRAY_SIZE(omen_thermal_profile_boards),
508                             board_name) >= 0;
509 }
510
511 static int omen_get_thermal_policy_version(void)
512 {
513         unsigned char buffer[8] = { 0 };
514         int ret;
515
516         const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
517
518         if (board_name) {
519                 int matches = match_string(omen_thermal_profile_force_v0_boards,
520                         ARRAY_SIZE(omen_thermal_profile_force_v0_boards),
521                         board_name);
522                 if (matches >= 0)
523                         return 0;
524         }
525
526         ret = hp_wmi_perform_query(HPWMI_GET_SYSTEM_DESIGN_DATA, HPWMI_GM,
527                                    &buffer, sizeof(buffer), sizeof(buffer));
528
529         if (ret)
530                 return ret < 0 ? ret : -EINVAL;
531
532         return buffer[3];
533 }
534
535 static int omen_thermal_profile_get(void)
536 {
537         u8 data;
538
539         int ret = ec_read(HP_OMEN_EC_THERMAL_PROFILE_OFFSET, &data);
540
541         if (ret)
542                 return ret;
543
544         return data;
545 }
546
547 static int hp_wmi_fan_speed_max_set(int enabled)
548 {
549         int ret;
550
551         ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_SET_QUERY, HPWMI_GM,
552                                    &enabled, sizeof(enabled), 0);
553
554         if (ret)
555                 return ret < 0 ? ret : -EINVAL;
556
557         return enabled;
558 }
559
560 static int hp_wmi_fan_speed_max_get(void)
561 {
562         int val = 0, ret;
563
564         ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_GET_QUERY, HPWMI_GM,
565                                    &val, zero_if_sup(val), sizeof(val));
566
567         if (ret)
568                 return ret < 0 ? ret : -EINVAL;
569
570         return val;
571 }
572
573 static int __init hp_wmi_bios_2008_later(void)
574 {
575         int state = 0;
576         int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, HPWMI_READ, &state,
577                                        zero_if_sup(state), sizeof(state));
578         if (!ret)
579                 return 1;
580
581         return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO;
582 }
583
584 static int __init hp_wmi_bios_2009_later(void)
585 {
586         u8 state[128];
587         int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state,
588                                        zero_if_sup(state), sizeof(state));
589         if (!ret)
590                 return 1;
591
592         return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO;
593 }
594
595 static int __init hp_wmi_enable_hotkeys(void)
596 {
597         int value = 0x6e;
598         int ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, HPWMI_WRITE, &value,
599                                        sizeof(value), 0);
600
601         return ret <= 0 ? ret : -EINVAL;
602 }
603
604 static int hp_wmi_set_block(void *data, bool blocked)
605 {
606         enum hp_wmi_radio r = (long)data;
607         int query = BIT(r + 8) | ((!blocked) << r);
608         int ret;
609
610         ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE,
611                                    &query, sizeof(query), 0);
612
613         return ret <= 0 ? ret : -EINVAL;
614 }
615
616 static const struct rfkill_ops hp_wmi_rfkill_ops = {
617         .set_block = hp_wmi_set_block,
618 };
619
620 static bool hp_wmi_get_sw_state(enum hp_wmi_radio r)
621 {
622         int mask = 0x200 << (r * 8);
623
624         int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
625
626         /* TBD: Pass error */
627         WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY");
628
629         return !(wireless & mask);
630 }
631
632 static bool hp_wmi_get_hw_state(enum hp_wmi_radio r)
633 {
634         int mask = 0x800 << (r * 8);
635
636         int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
637
638         /* TBD: Pass error */
639         WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY");
640
641         return !(wireless & mask);
642 }
643
644 static int hp_wmi_rfkill2_set_block(void *data, bool blocked)
645 {
646         int rfkill_id = (int)(long)data;
647         char buffer[4] = { 0x01, 0x00, rfkill_id, !blocked };
648         int ret;
649
650         ret = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_WRITE,
651                                    buffer, sizeof(buffer), 0);
652
653         return ret <= 0 ? ret : -EINVAL;
654 }
655
656 static const struct rfkill_ops hp_wmi_rfkill2_ops = {
657         .set_block = hp_wmi_rfkill2_set_block,
658 };
659
660 static int hp_wmi_rfkill2_refresh(void)
661 {
662         struct bios_rfkill2_state state;
663         int err, i;
664
665         err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
666                                    zero_if_sup(state), sizeof(state));
667         if (err)
668                 return err;
669
670         for (i = 0; i < rfkill2_count; i++) {
671                 int num = rfkill2[i].num;
672                 struct bios_rfkill2_device_state *devstate;
673
674                 devstate = &state.device[num];
675
676                 if (num >= state.count ||
677                     devstate->rfkill_id != rfkill2[i].id) {
678                         pr_warn("power configuration of the wireless devices unexpectedly changed\n");
679                         continue;
680                 }
681
682                 rfkill_set_states(rfkill2[i].rfkill,
683                                   IS_SWBLOCKED(devstate->power),
684                                   IS_HWBLOCKED(devstate->power));
685         }
686
687         return 0;
688 }
689
690 static ssize_t display_show(struct device *dev, struct device_attribute *attr,
691                             char *buf)
692 {
693         int value = hp_wmi_read_int(HPWMI_DISPLAY_QUERY);
694
695         if (value < 0)
696                 return value;
697         return sysfs_emit(buf, "%d\n", value);
698 }
699
700 static ssize_t hddtemp_show(struct device *dev, struct device_attribute *attr,
701                             char *buf)
702 {
703         int value = hp_wmi_read_int(HPWMI_HDDTEMP_QUERY);
704
705         if (value < 0)
706                 return value;
707         return sysfs_emit(buf, "%d\n", value);
708 }
709
710 static ssize_t als_show(struct device *dev, struct device_attribute *attr,
711                         char *buf)
712 {
713         int value = hp_wmi_read_int(HPWMI_ALS_QUERY);
714
715         if (value < 0)
716                 return value;
717         return sysfs_emit(buf, "%d\n", value);
718 }
719
720 static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
721                          char *buf)
722 {
723         int value = hp_wmi_get_dock_state();
724
725         if (value < 0)
726                 return value;
727         return sysfs_emit(buf, "%d\n", value);
728 }
729
730 static ssize_t tablet_show(struct device *dev, struct device_attribute *attr,
731                            char *buf)
732 {
733         int value = hp_wmi_get_tablet_mode();
734
735         if (value < 0)
736                 return value;
737         return sysfs_emit(buf, "%d\n", value);
738 }
739
740 static ssize_t postcode_show(struct device *dev, struct device_attribute *attr,
741                              char *buf)
742 {
743         /* Get the POST error code of previous boot failure. */
744         int value = hp_wmi_read_int(HPWMI_POSTCODEERROR_QUERY);
745
746         if (value < 0)
747                 return value;
748         return sysfs_emit(buf, "0x%x\n", value);
749 }
750
751 static ssize_t als_store(struct device *dev, struct device_attribute *attr,
752                          const char *buf, size_t count)
753 {
754         u32 tmp;
755         int ret;
756
757         ret = kstrtou32(buf, 10, &tmp);
758         if (ret)
759                 return ret;
760
761         ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp,
762                                        sizeof(tmp), 0);
763         if (ret)
764                 return ret < 0 ? ret : -EINVAL;
765
766         return count;
767 }
768
769 static ssize_t postcode_store(struct device *dev, struct device_attribute *attr,
770                               const char *buf, size_t count)
771 {
772         u32 tmp = 1;
773         bool clear;
774         int ret;
775
776         ret = kstrtobool(buf, &clear);
777         if (ret)
778                 return ret;
779
780         if (clear == false)
781                 return -EINVAL;
782
783         /* Clear the POST error code. It is kept until cleared. */
784         ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, HPWMI_WRITE, &tmp,
785                                        sizeof(tmp), 0);
786         if (ret)
787                 return ret < 0 ? ret : -EINVAL;
788
789         return count;
790 }
791
792 static int camera_shutter_input_setup(void)
793 {
794         int err;
795
796         camera_shutter_input_dev = input_allocate_device();
797         if (!camera_shutter_input_dev)
798                 return -ENOMEM;
799
800         camera_shutter_input_dev->name = "HP WMI camera shutter";
801         camera_shutter_input_dev->phys = "wmi/input1";
802         camera_shutter_input_dev->id.bustype = BUS_HOST;
803
804         __set_bit(EV_SW, camera_shutter_input_dev->evbit);
805         __set_bit(SW_CAMERA_LENS_COVER, camera_shutter_input_dev->swbit);
806
807         err = input_register_device(camera_shutter_input_dev);
808         if (err)
809                 goto err_free_dev;
810
811         return 0;
812
813  err_free_dev:
814         input_free_device(camera_shutter_input_dev);
815         camera_shutter_input_dev = NULL;
816         return err;
817 }
818
819 static DEVICE_ATTR_RO(display);
820 static DEVICE_ATTR_RO(hddtemp);
821 static DEVICE_ATTR_RW(als);
822 static DEVICE_ATTR_RO(dock);
823 static DEVICE_ATTR_RO(tablet);
824 static DEVICE_ATTR_RW(postcode);
825
826 static struct attribute *hp_wmi_attrs[] = {
827         &dev_attr_display.attr,
828         &dev_attr_hddtemp.attr,
829         &dev_attr_als.attr,
830         &dev_attr_dock.attr,
831         &dev_attr_tablet.attr,
832         &dev_attr_postcode.attr,
833         NULL,
834 };
835 ATTRIBUTE_GROUPS(hp_wmi);
836
837 static void hp_wmi_notify(u32 value, void *context)
838 {
839         struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
840         u32 event_id, event_data;
841         union acpi_object *obj;
842         acpi_status status;
843         u32 *location;
844         int key_code;
845
846         status = wmi_get_event_data(value, &response);
847         if (status != AE_OK) {
848                 pr_info("bad event status 0x%x\n", status);
849                 return;
850         }
851
852         obj = (union acpi_object *)response.pointer;
853
854         if (!obj)
855                 return;
856         if (obj->type != ACPI_TYPE_BUFFER) {
857                 pr_info("Unknown response received %d\n", obj->type);
858                 kfree(obj);
859                 return;
860         }
861
862         /*
863          * Depending on ACPI version the concatenation of id and event data
864          * inside _WED function will result in a 8 or 16 byte buffer.
865          */
866         location = (u32 *)obj->buffer.pointer;
867         if (obj->buffer.length == 8) {
868                 event_id = *location;
869                 event_data = *(location + 1);
870         } else if (obj->buffer.length == 16) {
871                 event_id = *location;
872                 event_data = *(location + 2);
873         } else {
874                 pr_info("Unknown buffer length %d\n", obj->buffer.length);
875                 kfree(obj);
876                 return;
877         }
878         kfree(obj);
879
880         switch (event_id) {
881         case HPWMI_DOCK_EVENT:
882                 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
883                         input_report_switch(hp_wmi_input_dev, SW_DOCK,
884                                             hp_wmi_get_dock_state());
885                 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
886                         input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
887                                             hp_wmi_get_tablet_mode());
888                 input_sync(hp_wmi_input_dev);
889                 break;
890         case HPWMI_PARK_HDD:
891                 break;
892         case HPWMI_SMART_ADAPTER:
893                 break;
894         case HPWMI_BEZEL_BUTTON:
895                 key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY);
896                 if (key_code < 0)
897                         break;
898
899                 if (!sparse_keymap_report_event(hp_wmi_input_dev,
900                                                 key_code, 1, true))
901                         pr_info("Unknown key code - 0x%x\n", key_code);
902                 break;
903         case HPWMI_OMEN_KEY:
904                 if (event_data) /* Only should be true for HP Omen */
905                         key_code = event_data;
906                 else
907                         key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY);
908
909                 if (!sparse_keymap_report_event(hp_wmi_input_dev,
910                                                 key_code, 1, true))
911                         pr_info("Unknown key code - 0x%x\n", key_code);
912                 break;
913         case HPWMI_WIRELESS:
914                 if (rfkill2_count) {
915                         hp_wmi_rfkill2_refresh();
916                         break;
917                 }
918
919                 if (wifi_rfkill)
920                         rfkill_set_states(wifi_rfkill,
921                                           hp_wmi_get_sw_state(HPWMI_WIFI),
922                                           hp_wmi_get_hw_state(HPWMI_WIFI));
923                 if (bluetooth_rfkill)
924                         rfkill_set_states(bluetooth_rfkill,
925                                           hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
926                                           hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
927                 if (wwan_rfkill)
928                         rfkill_set_states(wwan_rfkill,
929                                           hp_wmi_get_sw_state(HPWMI_WWAN),
930                                           hp_wmi_get_hw_state(HPWMI_WWAN));
931                 break;
932         case HPWMI_CPU_BATTERY_THROTTLE:
933                 pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n");
934                 break;
935         case HPWMI_LOCK_SWITCH:
936                 break;
937         case HPWMI_LID_SWITCH:
938                 break;
939         case HPWMI_SCREEN_ROTATION:
940                 break;
941         case HPWMI_COOLSENSE_SYSTEM_MOBILE:
942                 break;
943         case HPWMI_COOLSENSE_SYSTEM_HOT:
944                 break;
945         case HPWMI_PROXIMITY_SENSOR:
946                 break;
947         case HPWMI_BACKLIT_KB_BRIGHTNESS:
948                 break;
949         case HPWMI_PEAKSHIFT_PERIOD:
950                 break;
951         case HPWMI_BATTERY_CHARGE_PERIOD:
952                 break;
953         case HPWMI_SANITIZATION_MODE:
954                 break;
955         case HPWMI_CAMERA_TOGGLE:
956                 if (!camera_shutter_input_dev)
957                         if (camera_shutter_input_setup()) {
958                                 pr_err("Failed to setup camera shutter input device\n");
959                                 break;
960                         }
961                 if (event_data == 0xff)
962                         input_report_switch(camera_shutter_input_dev, SW_CAMERA_LENS_COVER, 1);
963                 else if (event_data == 0xfe)
964                         input_report_switch(camera_shutter_input_dev, SW_CAMERA_LENS_COVER, 0);
965                 else
966                         pr_warn("Unknown camera shutter state - 0x%x\n", event_data);
967                 input_sync(camera_shutter_input_dev);
968                 break;
969         case HPWMI_SMART_EXPERIENCE_APP:
970                 break;
971         default:
972                 pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
973                 break;
974         }
975 }
976
977 static int __init hp_wmi_input_setup(void)
978 {
979         acpi_status status;
980         int err, val;
981
982         hp_wmi_input_dev = input_allocate_device();
983         if (!hp_wmi_input_dev)
984                 return -ENOMEM;
985
986         hp_wmi_input_dev->name = "HP WMI hotkeys";
987         hp_wmi_input_dev->phys = "wmi/input0";
988         hp_wmi_input_dev->id.bustype = BUS_HOST;
989
990         __set_bit(EV_SW, hp_wmi_input_dev->evbit);
991
992         /* Dock */
993         val = hp_wmi_get_dock_state();
994         if (!(val < 0)) {
995                 __set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
996                 input_report_switch(hp_wmi_input_dev, SW_DOCK, val);
997         }
998
999         /* Tablet mode */
1000         val = hp_wmi_get_tablet_mode();
1001         if (!(val < 0)) {
1002                 __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
1003                 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
1004         }
1005
1006         err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
1007         if (err)
1008                 goto err_free_dev;
1009
1010         /* Set initial hardware state */
1011         input_sync(hp_wmi_input_dev);
1012
1013         if (!hp_wmi_bios_2009_later() && hp_wmi_bios_2008_later())
1014                 hp_wmi_enable_hotkeys();
1015
1016         status = wmi_install_notify_handler(HPWMI_EVENT_GUID, hp_wmi_notify, NULL);
1017         if (ACPI_FAILURE(status)) {
1018                 err = -EIO;
1019                 goto err_free_dev;
1020         }
1021
1022         err = input_register_device(hp_wmi_input_dev);
1023         if (err)
1024                 goto err_uninstall_notifier;
1025
1026         return 0;
1027
1028  err_uninstall_notifier:
1029         wmi_remove_notify_handler(HPWMI_EVENT_GUID);
1030  err_free_dev:
1031         input_free_device(hp_wmi_input_dev);
1032         return err;
1033 }
1034
1035 static void hp_wmi_input_destroy(void)
1036 {
1037         wmi_remove_notify_handler(HPWMI_EVENT_GUID);
1038         input_unregister_device(hp_wmi_input_dev);
1039 }
1040
1041 static int __init hp_wmi_rfkill_setup(struct platform_device *device)
1042 {
1043         int err, wireless;
1044
1045         wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
1046         if (wireless < 0)
1047                 return wireless;
1048
1049         err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE, &wireless,
1050                                    sizeof(wireless), 0);
1051         if (err)
1052                 return err;
1053
1054         if (wireless & 0x1) {
1055                 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
1056                                            RFKILL_TYPE_WLAN,
1057                                            &hp_wmi_rfkill_ops,
1058                                            (void *) HPWMI_WIFI);
1059                 if (!wifi_rfkill)
1060                         return -ENOMEM;
1061                 rfkill_init_sw_state(wifi_rfkill,
1062                                      hp_wmi_get_sw_state(HPWMI_WIFI));
1063                 rfkill_set_hw_state(wifi_rfkill,
1064                                     hp_wmi_get_hw_state(HPWMI_WIFI));
1065                 err = rfkill_register(wifi_rfkill);
1066                 if (err)
1067                         goto register_wifi_error;
1068         }
1069
1070         if (wireless & 0x2) {
1071                 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
1072                                                 RFKILL_TYPE_BLUETOOTH,
1073                                                 &hp_wmi_rfkill_ops,
1074                                                 (void *) HPWMI_BLUETOOTH);
1075                 if (!bluetooth_rfkill) {
1076                         err = -ENOMEM;
1077                         goto register_bluetooth_error;
1078                 }
1079                 rfkill_init_sw_state(bluetooth_rfkill,
1080                                      hp_wmi_get_sw_state(HPWMI_BLUETOOTH));
1081                 rfkill_set_hw_state(bluetooth_rfkill,
1082                                     hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
1083                 err = rfkill_register(bluetooth_rfkill);
1084                 if (err)
1085                         goto register_bluetooth_error;
1086         }
1087
1088         if (wireless & 0x4) {
1089                 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
1090                                            RFKILL_TYPE_WWAN,
1091                                            &hp_wmi_rfkill_ops,
1092                                            (void *) HPWMI_WWAN);
1093                 if (!wwan_rfkill) {
1094                         err = -ENOMEM;
1095                         goto register_wwan_error;
1096                 }
1097                 rfkill_init_sw_state(wwan_rfkill,
1098                                      hp_wmi_get_sw_state(HPWMI_WWAN));
1099                 rfkill_set_hw_state(wwan_rfkill,
1100                                     hp_wmi_get_hw_state(HPWMI_WWAN));
1101                 err = rfkill_register(wwan_rfkill);
1102                 if (err)
1103                         goto register_wwan_error;
1104         }
1105
1106         return 0;
1107
1108 register_wwan_error:
1109         rfkill_destroy(wwan_rfkill);
1110         wwan_rfkill = NULL;
1111         if (bluetooth_rfkill)
1112                 rfkill_unregister(bluetooth_rfkill);
1113 register_bluetooth_error:
1114         rfkill_destroy(bluetooth_rfkill);
1115         bluetooth_rfkill = NULL;
1116         if (wifi_rfkill)
1117                 rfkill_unregister(wifi_rfkill);
1118 register_wifi_error:
1119         rfkill_destroy(wifi_rfkill);
1120         wifi_rfkill = NULL;
1121         return err;
1122 }
1123
1124 static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
1125 {
1126         struct bios_rfkill2_state state;
1127         int err, i;
1128
1129         err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
1130                                    zero_if_sup(state), sizeof(state));
1131         if (err)
1132                 return err < 0 ? err : -EINVAL;
1133
1134         if (state.count > HPWMI_MAX_RFKILL2_DEVICES) {
1135                 pr_warn("unable to parse 0x1b query output\n");
1136                 return -EINVAL;
1137         }
1138
1139         for (i = 0; i < state.count; i++) {
1140                 struct rfkill *rfkill;
1141                 enum rfkill_type type;
1142                 char *name;
1143
1144                 switch (state.device[i].radio_type) {
1145                 case HPWMI_WIFI:
1146                         type = RFKILL_TYPE_WLAN;
1147                         name = "hp-wifi";
1148                         break;
1149                 case HPWMI_BLUETOOTH:
1150                         type = RFKILL_TYPE_BLUETOOTH;
1151                         name = "hp-bluetooth";
1152                         break;
1153                 case HPWMI_WWAN:
1154                         type = RFKILL_TYPE_WWAN;
1155                         name = "hp-wwan";
1156                         break;
1157                 case HPWMI_GPS:
1158                         type = RFKILL_TYPE_GPS;
1159                         name = "hp-gps";
1160                         break;
1161                 default:
1162                         pr_warn("unknown device type 0x%x\n",
1163                                 state.device[i].radio_type);
1164                         continue;
1165                 }
1166
1167                 if (!state.device[i].vendor_id) {
1168                         pr_warn("zero device %d while %d reported\n",
1169                                 i, state.count);
1170                         continue;
1171                 }
1172
1173                 rfkill = rfkill_alloc(name, &device->dev, type,
1174                                       &hp_wmi_rfkill2_ops, (void *)(long)i);
1175                 if (!rfkill) {
1176                         err = -ENOMEM;
1177                         goto fail;
1178                 }
1179
1180                 rfkill2[rfkill2_count].id = state.device[i].rfkill_id;
1181                 rfkill2[rfkill2_count].num = i;
1182                 rfkill2[rfkill2_count].rfkill = rfkill;
1183
1184                 rfkill_init_sw_state(rfkill,
1185                                      IS_SWBLOCKED(state.device[i].power));
1186                 rfkill_set_hw_state(rfkill,
1187                                     IS_HWBLOCKED(state.device[i].power));
1188
1189                 if (!(state.device[i].power & HPWMI_POWER_BIOS))
1190                         pr_info("device %s blocked by BIOS\n", name);
1191
1192                 err = rfkill_register(rfkill);
1193                 if (err) {
1194                         rfkill_destroy(rfkill);
1195                         goto fail;
1196                 }
1197
1198                 rfkill2_count++;
1199         }
1200
1201         return 0;
1202 fail:
1203         for (; rfkill2_count > 0; rfkill2_count--) {
1204                 rfkill_unregister(rfkill2[rfkill2_count - 1].rfkill);
1205                 rfkill_destroy(rfkill2[rfkill2_count - 1].rfkill);
1206         }
1207         return err;
1208 }
1209
1210 static int platform_profile_omen_get_ec(enum platform_profile_option *profile)
1211 {
1212         int tp;
1213
1214         tp = omen_thermal_profile_get();
1215         if (tp < 0)
1216                 return tp;
1217
1218         switch (tp) {
1219         case HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE:
1220         case HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE:
1221                 *profile = PLATFORM_PROFILE_PERFORMANCE;
1222                 break;
1223         case HP_OMEN_V0_THERMAL_PROFILE_DEFAULT:
1224         case HP_OMEN_V1_THERMAL_PROFILE_DEFAULT:
1225                 *profile = PLATFORM_PROFILE_BALANCED;
1226                 break;
1227         case HP_OMEN_V0_THERMAL_PROFILE_COOL:
1228         case HP_OMEN_V1_THERMAL_PROFILE_COOL:
1229                 *profile = PLATFORM_PROFILE_COOL;
1230                 break;
1231         default:
1232                 return -EINVAL;
1233         }
1234
1235         return 0;
1236 }
1237
1238 static int platform_profile_omen_get(struct platform_profile_handler *pprof,
1239                                      enum platform_profile_option *profile)
1240 {
1241         /*
1242          * We directly return the stored platform profile, as the embedded
1243          * controller will not accept switching to the performance option when
1244          * the conditions are not met (e.g. the laptop is not plugged in).
1245          *
1246          * If we directly return what the EC reports, the platform profile will
1247          * immediately "switch back" to normal mode, which is against the
1248          * expected behaviour from a userspace point of view, as described in
1249          * the Platform Profile Section page of the kernel documentation.
1250          *
1251          * See also omen_powersource_event.
1252          */
1253         guard(mutex)(&active_platform_profile_lock);
1254         *profile = active_platform_profile;
1255
1256         return 0;
1257 }
1258
1259 static bool has_omen_thermal_profile_ec_timer(void)
1260 {
1261         const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
1262
1263         if (!board_name)
1264                 return false;
1265
1266         return match_string(omen_timed_thermal_profile_boards,
1267                             ARRAY_SIZE(omen_timed_thermal_profile_boards),
1268                             board_name) >= 0;
1269 }
1270
1271 inline int omen_thermal_profile_ec_flags_set(enum hp_thermal_profile_omen_flags flags)
1272 {
1273         return ec_write(HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET, flags);
1274 }
1275
1276 inline int omen_thermal_profile_ec_timer_set(u8 value)
1277 {
1278         return ec_write(HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET, value);
1279 }
1280
1281 static int platform_profile_omen_set_ec(enum platform_profile_option profile)
1282 {
1283         int err, tp, tp_version;
1284         enum hp_thermal_profile_omen_flags flags = 0;
1285
1286         tp_version = omen_get_thermal_policy_version();
1287
1288         if (tp_version < 0 || tp_version > 1)
1289                 return -EOPNOTSUPP;
1290
1291         switch (profile) {
1292         case PLATFORM_PROFILE_PERFORMANCE:
1293                 if (tp_version == 0)
1294                         tp = HP_OMEN_V0_THERMAL_PROFILE_PERFORMANCE;
1295                 else
1296                         tp = HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE;
1297                 break;
1298         case PLATFORM_PROFILE_BALANCED:
1299                 if (tp_version == 0)
1300                         tp = HP_OMEN_V0_THERMAL_PROFILE_DEFAULT;
1301                 else
1302                         tp = HP_OMEN_V1_THERMAL_PROFILE_DEFAULT;
1303                 break;
1304         case PLATFORM_PROFILE_COOL:
1305                 if (tp_version == 0)
1306                         tp = HP_OMEN_V0_THERMAL_PROFILE_COOL;
1307                 else
1308                         tp = HP_OMEN_V1_THERMAL_PROFILE_COOL;
1309                 break;
1310         default:
1311                 return -EOPNOTSUPP;
1312         }
1313
1314         err = omen_thermal_profile_set(tp);
1315         if (err < 0)
1316                 return err;
1317
1318         if (has_omen_thermal_profile_ec_timer()) {
1319                 err = omen_thermal_profile_ec_timer_set(0);
1320                 if (err < 0)
1321                         return err;
1322
1323                 if (profile == PLATFORM_PROFILE_PERFORMANCE)
1324                         flags = HP_OMEN_EC_FLAGS_NOTIMER |
1325                                 HP_OMEN_EC_FLAGS_TURBO;
1326
1327                 err = omen_thermal_profile_ec_flags_set(flags);
1328                 if (err < 0)
1329                         return err;
1330         }
1331
1332         return 0;
1333 }
1334
1335 static int platform_profile_omen_set(struct platform_profile_handler *pprof,
1336                                      enum platform_profile_option profile)
1337 {
1338         int err;
1339
1340         guard(mutex)(&active_platform_profile_lock);
1341
1342         err = platform_profile_omen_set_ec(profile);
1343         if (err < 0)
1344                 return err;
1345
1346         active_platform_profile = profile;
1347
1348         return 0;
1349 }
1350
1351 static int thermal_profile_get(void)
1352 {
1353         return hp_wmi_read_int(HPWMI_THERMAL_PROFILE_QUERY);
1354 }
1355
1356 static int thermal_profile_set(int thermal_profile)
1357 {
1358         return hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &thermal_profile,
1359                                                            sizeof(thermal_profile), 0);
1360 }
1361
1362 static int hp_wmi_platform_profile_get(struct platform_profile_handler *pprof,
1363                                         enum platform_profile_option *profile)
1364 {
1365         int tp;
1366
1367         tp = thermal_profile_get();
1368         if (tp < 0)
1369                 return tp;
1370
1371         switch (tp) {
1372         case HP_THERMAL_PROFILE_PERFORMANCE:
1373                 *profile =  PLATFORM_PROFILE_PERFORMANCE;
1374                 break;
1375         case HP_THERMAL_PROFILE_DEFAULT:
1376                 *profile =  PLATFORM_PROFILE_BALANCED;
1377                 break;
1378         case HP_THERMAL_PROFILE_COOL:
1379                 *profile =  PLATFORM_PROFILE_COOL;
1380                 break;
1381         case HP_THERMAL_PROFILE_QUIET:
1382                 *profile = PLATFORM_PROFILE_QUIET;
1383                 break;
1384         default:
1385                 return -EINVAL;
1386         }
1387
1388         return 0;
1389 }
1390
1391 static int hp_wmi_platform_profile_set(struct platform_profile_handler *pprof,
1392                                         enum platform_profile_option profile)
1393 {
1394         int err, tp;
1395
1396         switch (profile) {
1397         case PLATFORM_PROFILE_PERFORMANCE:
1398                 tp =  HP_THERMAL_PROFILE_PERFORMANCE;
1399                 break;
1400         case PLATFORM_PROFILE_BALANCED:
1401                 tp =  HP_THERMAL_PROFILE_DEFAULT;
1402                 break;
1403         case PLATFORM_PROFILE_COOL:
1404                 tp =  HP_THERMAL_PROFILE_COOL;
1405                 break;
1406         case PLATFORM_PROFILE_QUIET:
1407                 tp = HP_THERMAL_PROFILE_QUIET;
1408                 break;
1409         default:
1410                 return -EOPNOTSUPP;
1411         }
1412
1413         err = thermal_profile_set(tp);
1414         if (err)
1415                 return err;
1416
1417         return 0;
1418 }
1419
1420 static bool is_victus_thermal_profile(void)
1421 {
1422         const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
1423
1424         if (!board_name)
1425                 return false;
1426
1427         return match_string(victus_thermal_profile_boards,
1428                             ARRAY_SIZE(victus_thermal_profile_boards),
1429                             board_name) >= 0;
1430 }
1431
1432 static int platform_profile_victus_get_ec(enum platform_profile_option *profile)
1433 {
1434         int tp;
1435
1436         tp = omen_thermal_profile_get();
1437         if (tp < 0)
1438                 return tp;
1439
1440         switch (tp) {
1441         case HP_VICTUS_THERMAL_PROFILE_PERFORMANCE:
1442                 *profile = PLATFORM_PROFILE_PERFORMANCE;
1443                 break;
1444         case HP_VICTUS_THERMAL_PROFILE_DEFAULT:
1445                 *profile = PLATFORM_PROFILE_BALANCED;
1446                 break;
1447         case HP_VICTUS_THERMAL_PROFILE_QUIET:
1448                 *profile = PLATFORM_PROFILE_QUIET;
1449                 break;
1450         default:
1451                 return -EOPNOTSUPP;
1452         }
1453
1454         return 0;
1455 }
1456
1457 static int platform_profile_victus_get(struct platform_profile_handler *pprof,
1458                                        enum platform_profile_option *profile)
1459 {
1460         /* Same behaviour as platform_profile_omen_get */
1461         return platform_profile_omen_get(pprof, profile);
1462 }
1463
1464 static int platform_profile_victus_set_ec(enum platform_profile_option profile)
1465 {
1466         int err, tp;
1467
1468         switch (profile) {
1469         case PLATFORM_PROFILE_PERFORMANCE:
1470                 tp = HP_VICTUS_THERMAL_PROFILE_PERFORMANCE;
1471                 break;
1472         case PLATFORM_PROFILE_BALANCED:
1473                 tp = HP_VICTUS_THERMAL_PROFILE_DEFAULT;
1474                 break;
1475         case PLATFORM_PROFILE_QUIET:
1476                 tp = HP_VICTUS_THERMAL_PROFILE_QUIET;
1477                 break;
1478         default:
1479                 return -EOPNOTSUPP;
1480         }
1481
1482         err = omen_thermal_profile_set(tp);
1483         if (err < 0)
1484                 return err;
1485
1486         return 0;
1487 }
1488
1489 static int platform_profile_victus_set(struct platform_profile_handler *pprof,
1490                                        enum platform_profile_option profile)
1491 {
1492         int err;
1493
1494         guard(mutex)(&active_platform_profile_lock);
1495
1496         err = platform_profile_victus_set_ec(profile);
1497         if (err < 0)
1498                 return err;
1499
1500         active_platform_profile = profile;
1501
1502         return 0;
1503 }
1504
1505 static int omen_powersource_event(struct notifier_block *nb,
1506                                   unsigned long value,
1507                                   void *data)
1508 {
1509         struct acpi_bus_event *event_entry = data;
1510         enum platform_profile_option actual_profile;
1511         int err;
1512
1513         if (strcmp(event_entry->device_class, ACPI_AC_CLASS) != 0)
1514                 return NOTIFY_DONE;
1515
1516         pr_debug("Received power source device event\n");
1517
1518         guard(mutex)(&active_platform_profile_lock);
1519
1520         /*
1521          * This handler can only be called on Omen and Victus models, so
1522          * there's no need to call is_victus_thermal_profile() here.
1523          */
1524         if (is_omen_thermal_profile())
1525                 err = platform_profile_omen_get_ec(&actual_profile);
1526         else
1527                 err = platform_profile_victus_get_ec(&actual_profile);
1528
1529         if (err < 0) {
1530                 /*
1531                  * Although we failed to get the current platform profile, we
1532                  * still want the other event consumers to process it.
1533                  */
1534                 pr_warn("Failed to read current platform profile (%d)\n", err);
1535                 return NOTIFY_DONE;
1536         }
1537
1538         /*
1539          * If we're back on AC and that the user-chosen power profile is
1540          * different from what the EC reports, we restore the user-chosen
1541          * one.
1542          */
1543         if (power_supply_is_system_supplied() <= 0 ||
1544             active_platform_profile == actual_profile) {
1545                 pr_debug("Platform profile update skipped, conditions unmet\n");
1546                 return NOTIFY_DONE;
1547         }
1548
1549         if (is_omen_thermal_profile())
1550                 err = platform_profile_omen_set_ec(active_platform_profile);
1551         else
1552                 err = platform_profile_victus_set_ec(active_platform_profile);
1553
1554         if (err < 0) {
1555                 pr_warn("Failed to restore platform profile (%d)\n", err);
1556                 return NOTIFY_DONE;
1557         }
1558
1559         return NOTIFY_OK;
1560 }
1561
1562 static int omen_register_powersource_event_handler(void)
1563 {
1564         int err;
1565
1566         platform_power_source_nb.notifier_call = omen_powersource_event;
1567         err = register_acpi_notifier(&platform_power_source_nb);
1568
1569         if (err < 0) {
1570                 pr_warn("Failed to install ACPI power source notify handler\n");
1571                 return err;
1572         }
1573
1574         return 0;
1575 }
1576
1577 static inline void omen_unregister_powersource_event_handler(void)
1578 {
1579         unregister_acpi_notifier(&platform_power_source_nb);
1580 }
1581
1582 static int thermal_profile_setup(void)
1583 {
1584         int err, tp;
1585
1586         if (is_omen_thermal_profile()) {
1587                 err = platform_profile_omen_get_ec(&active_platform_profile);
1588                 if (err < 0)
1589                         return err;
1590
1591                 /*
1592                  * call thermal profile write command to ensure that the
1593                  * firmware correctly sets the OEM variables
1594                  */
1595                 err = platform_profile_omen_set_ec(active_platform_profile);
1596                 if (err < 0)
1597                         return err;
1598
1599                 platform_profile_handler.profile_get = platform_profile_omen_get;
1600                 platform_profile_handler.profile_set = platform_profile_omen_set;
1601
1602                 set_bit(PLATFORM_PROFILE_COOL, platform_profile_handler.choices);
1603         } else if (is_victus_thermal_profile()) {
1604                 err = platform_profile_victus_get_ec(&active_platform_profile);
1605                 if (err < 0)
1606                         return err;
1607
1608                 /*
1609                  * call thermal profile write command to ensure that the
1610                  * firmware correctly sets the OEM variables
1611                  */
1612                 err = platform_profile_victus_set_ec(active_platform_profile);
1613                 if (err < 0)
1614                         return err;
1615
1616                 platform_profile_handler.profile_get = platform_profile_victus_get;
1617                 platform_profile_handler.profile_set = platform_profile_victus_set;
1618
1619                 set_bit(PLATFORM_PROFILE_QUIET, platform_profile_handler.choices);
1620         } else {
1621                 tp = thermal_profile_get();
1622
1623                 if (tp < 0)
1624                         return tp;
1625
1626                 /*
1627                  * call thermal profile write command to ensure that the
1628                  * firmware correctly sets the OEM variables for the DPTF
1629                  */
1630                 err = thermal_profile_set(tp);
1631                 if (err)
1632                         return err;
1633
1634                 platform_profile_handler.profile_get = hp_wmi_platform_profile_get;
1635                 platform_profile_handler.profile_set = hp_wmi_platform_profile_set;
1636
1637                 set_bit(PLATFORM_PROFILE_QUIET, platform_profile_handler.choices);
1638                 set_bit(PLATFORM_PROFILE_COOL, platform_profile_handler.choices);
1639         }
1640
1641         set_bit(PLATFORM_PROFILE_BALANCED, platform_profile_handler.choices);
1642         set_bit(PLATFORM_PROFILE_PERFORMANCE, platform_profile_handler.choices);
1643
1644         err = platform_profile_register(&platform_profile_handler);
1645         if (err)
1646                 return err;
1647
1648         platform_profile_support = true;
1649
1650         return 0;
1651 }
1652
1653 static int hp_wmi_hwmon_init(void);
1654
1655 static int __init hp_wmi_bios_setup(struct platform_device *device)
1656 {
1657         int err;
1658         /* clear detected rfkill devices */
1659         wifi_rfkill = NULL;
1660         bluetooth_rfkill = NULL;
1661         wwan_rfkill = NULL;
1662         rfkill2_count = 0;
1663
1664         /*
1665          * In pre-2009 BIOS, command 1Bh return 0x4 to indicate that
1666          * BIOS no longer controls the power for the wireless
1667          * devices. All features supported by this command will no
1668          * longer be supported.
1669          */
1670         if (!hp_wmi_bios_2009_later()) {
1671                 if (hp_wmi_rfkill_setup(device))
1672                         hp_wmi_rfkill2_setup(device);
1673         }
1674
1675         err = hp_wmi_hwmon_init();
1676
1677         if (err < 0)
1678                 return err;
1679
1680         thermal_profile_setup();
1681
1682         return 0;
1683 }
1684
1685 static void __exit hp_wmi_bios_remove(struct platform_device *device)
1686 {
1687         int i;
1688
1689         for (i = 0; i < rfkill2_count; i++) {
1690                 rfkill_unregister(rfkill2[i].rfkill);
1691                 rfkill_destroy(rfkill2[i].rfkill);
1692         }
1693
1694         if (wifi_rfkill) {
1695                 rfkill_unregister(wifi_rfkill);
1696                 rfkill_destroy(wifi_rfkill);
1697         }
1698         if (bluetooth_rfkill) {
1699                 rfkill_unregister(bluetooth_rfkill);
1700                 rfkill_destroy(bluetooth_rfkill);
1701         }
1702         if (wwan_rfkill) {
1703                 rfkill_unregister(wwan_rfkill);
1704                 rfkill_destroy(wwan_rfkill);
1705         }
1706
1707         if (platform_profile_support)
1708                 platform_profile_remove();
1709 }
1710
1711 static int hp_wmi_resume_handler(struct device *device)
1712 {
1713         /*
1714          * Hardware state may have changed while suspended, so trigger
1715          * input events for the current state. As this is a switch,
1716          * the input layer will only actually pass it on if the state
1717          * changed.
1718          */
1719         if (hp_wmi_input_dev) {
1720                 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
1721                         input_report_switch(hp_wmi_input_dev, SW_DOCK,
1722                                             hp_wmi_get_dock_state());
1723                 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
1724                         input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
1725                                             hp_wmi_get_tablet_mode());
1726                 input_sync(hp_wmi_input_dev);
1727         }
1728
1729         if (rfkill2_count)
1730                 hp_wmi_rfkill2_refresh();
1731
1732         if (wifi_rfkill)
1733                 rfkill_set_states(wifi_rfkill,
1734                                   hp_wmi_get_sw_state(HPWMI_WIFI),
1735                                   hp_wmi_get_hw_state(HPWMI_WIFI));
1736         if (bluetooth_rfkill)
1737                 rfkill_set_states(bluetooth_rfkill,
1738                                   hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
1739                                   hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
1740         if (wwan_rfkill)
1741                 rfkill_set_states(wwan_rfkill,
1742                                   hp_wmi_get_sw_state(HPWMI_WWAN),
1743                                   hp_wmi_get_hw_state(HPWMI_WWAN));
1744
1745         return 0;
1746 }
1747
1748 static const struct dev_pm_ops hp_wmi_pm_ops = {
1749         .resume  = hp_wmi_resume_handler,
1750         .restore  = hp_wmi_resume_handler,
1751 };
1752
1753 /*
1754  * hp_wmi_bios_remove() lives in .exit.text. For drivers registered via
1755  * module_platform_driver_probe() this is ok because they cannot get unbound at
1756  * runtime. So mark the driver struct with __refdata to prevent modpost
1757  * triggering a section mismatch warning.
1758  */
1759 static struct platform_driver hp_wmi_driver __refdata = {
1760         .driver = {
1761                 .name = "hp-wmi",
1762                 .pm = &hp_wmi_pm_ops,
1763                 .dev_groups = hp_wmi_groups,
1764         },
1765         .remove_new = __exit_p(hp_wmi_bios_remove),
1766 };
1767
1768 static umode_t hp_wmi_hwmon_is_visible(const void *data,
1769                                        enum hwmon_sensor_types type,
1770                                        u32 attr, int channel)
1771 {
1772         switch (type) {
1773         case hwmon_pwm:
1774                 return 0644;
1775         case hwmon_fan:
1776                 if (hp_wmi_get_fan_speed(channel) >= 0)
1777                         return 0444;
1778                 break;
1779         default:
1780                 return 0;
1781         }
1782
1783         return 0;
1784 }
1785
1786 static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
1787                              u32 attr, int channel, long *val)
1788 {
1789         int ret;
1790
1791         switch (type) {
1792         case hwmon_fan:
1793                 ret = hp_wmi_get_fan_speed(channel);
1794
1795                 if (ret < 0)
1796                         return ret;
1797                 *val = ret;
1798                 return 0;
1799         case hwmon_pwm:
1800                 switch (hp_wmi_fan_speed_max_get()) {
1801                 case 0:
1802                         /* 0 is automatic fan, which is 2 for hwmon */
1803                         *val = 2;
1804                         return 0;
1805                 case 1:
1806                         /* 1 is max fan, which is 0
1807                          * (no fan speed control) for hwmon
1808                          */
1809                         *val = 0;
1810                         return 0;
1811                 default:
1812                         /* shouldn't happen */
1813                         return -ENODATA;
1814                 }
1815         default:
1816                 return -EINVAL;
1817         }
1818 }
1819
1820 static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
1821                               u32 attr, int channel, long val)
1822 {
1823         switch (type) {
1824         case hwmon_pwm:
1825                 switch (val) {
1826                 case 0:
1827                         /* 0 is no fan speed control (max), which is 1 for us */
1828                         return hp_wmi_fan_speed_max_set(1);
1829                 case 2:
1830                         /* 2 is automatic speed control, which is 0 for us */
1831                         return hp_wmi_fan_speed_max_set(0);
1832                 default:
1833                         /* we don't support manual fan speed control */
1834                         return -EINVAL;
1835                 }
1836         default:
1837                 return -EOPNOTSUPP;
1838         }
1839 }
1840
1841 static const struct hwmon_channel_info * const info[] = {
1842         HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT, HWMON_F_INPUT),
1843         HWMON_CHANNEL_INFO(pwm, HWMON_PWM_ENABLE),
1844         NULL
1845 };
1846
1847 static const struct hwmon_ops ops = {
1848         .is_visible = hp_wmi_hwmon_is_visible,
1849         .read = hp_wmi_hwmon_read,
1850         .write = hp_wmi_hwmon_write,
1851 };
1852
1853 static const struct hwmon_chip_info chip_info = {
1854         .ops = &ops,
1855         .info = info,
1856 };
1857
1858 static int hp_wmi_hwmon_init(void)
1859 {
1860         struct device *dev = &hp_wmi_platform_dev->dev;
1861         struct device *hwmon;
1862
1863         hwmon = devm_hwmon_device_register_with_info(dev, "hp", &hp_wmi_driver,
1864                                                      &chip_info, NULL);
1865
1866         if (IS_ERR(hwmon)) {
1867                 dev_err(dev, "Could not register hp hwmon device\n");
1868                 return PTR_ERR(hwmon);
1869         }
1870
1871         return 0;
1872 }
1873
1874 static int __init hp_wmi_init(void)
1875 {
1876         int event_capable = wmi_has_guid(HPWMI_EVENT_GUID);
1877         int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID);
1878         int err, tmp = 0;
1879
1880         if (!bios_capable && !event_capable)
1881                 return -ENODEV;
1882
1883         if (hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, HPWMI_READ, &tmp,
1884                                  sizeof(tmp), sizeof(tmp)) == HPWMI_RET_INVALID_PARAMETERS)
1885                 zero_insize_support = true;
1886
1887         if (event_capable) {
1888                 err = hp_wmi_input_setup();
1889                 if (err)
1890                         return err;
1891         }
1892
1893         if (bios_capable) {
1894                 hp_wmi_platform_dev =
1895                         platform_device_register_simple("hp-wmi", PLATFORM_DEVID_NONE, NULL, 0);
1896                 if (IS_ERR(hp_wmi_platform_dev)) {
1897                         err = PTR_ERR(hp_wmi_platform_dev);
1898                         goto err_destroy_input;
1899                 }
1900
1901                 err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
1902                 if (err)
1903                         goto err_unregister_device;
1904         }
1905
1906         if (is_omen_thermal_profile() || is_victus_thermal_profile()) {
1907                 err = omen_register_powersource_event_handler();
1908                 if (err)
1909                         goto err_unregister_device;
1910         }
1911
1912         return 0;
1913
1914 err_unregister_device:
1915         platform_device_unregister(hp_wmi_platform_dev);
1916 err_destroy_input:
1917         if (event_capable)
1918                 hp_wmi_input_destroy();
1919
1920         return err;
1921 }
1922 module_init(hp_wmi_init);
1923
1924 static void __exit hp_wmi_exit(void)
1925 {
1926         if (is_omen_thermal_profile() || is_victus_thermal_profile())
1927                 omen_unregister_powersource_event_handler();
1928
1929         if (wmi_has_guid(HPWMI_EVENT_GUID))
1930                 hp_wmi_input_destroy();
1931
1932         if (camera_shutter_input_dev)
1933                 input_unregister_device(camera_shutter_input_dev);
1934
1935         if (hp_wmi_platform_dev) {
1936                 platform_device_unregister(hp_wmi_platform_dev);
1937                 platform_driver_unregister(&hp_wmi_driver);
1938         }
1939 }
1940 module_exit(hp_wmi_exit);
This page took 0.157826 seconds and 4 git commands to generate.