1
2
3
4
5
6
7
8
9
10
11
12
13
14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/types.h>
21#include <linux/input.h>
22#include <linux/input/sparse-keymap.h>
23#include <linux/platform_device.h>
24#include <linux/platform_profile.h>
25#include <linux/hwmon.h>
26#include <linux/acpi.h>
27#include <linux/rfkill.h>
28#include <linux/string.h>
29#include <linux/dmi.h>
30
31MODULE_AUTHOR("Matthew Garrett <mjg59@srcf.ucam.org>");
32MODULE_DESCRIPTION("HP laptop WMI hotkeys driver");
33MODULE_LICENSE("GPL");
34
35MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C");
36MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
37
38static int enable_tablet_mode_sw = -1;
39module_param(enable_tablet_mode_sw, int, 0444);
40MODULE_PARM_DESC(enable_tablet_mode_sw, "Enable SW_TABLET_MODE reporting (-1=auto, 0=no, 1=yes)");
41
42#define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
43#define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4"
44#define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95
45
46
47
48
49
50
51
52
53
54
55static const char * const omen_thermal_profile_boards[] = {
56 "84DA", "84DB", "84DC", "8574", "8575", "860A", "87B5", "8572", "8573",
57 "8600", "8601", "8602", "8605", "8606", "8607", "8746", "8747", "8749",
58 "874A", "8603", "8604", "8748", "886B", "886C", "878A", "878B", "878C",
59 "88C8", "88CB", "8786", "8787", "8788", "88D1", "88D2", "88F4", "88FD",
60 "88F5", "88F6", "88F7", "88FE", "88FF", "8900", "8901", "8902", "8912",
61 "8917", "8918", "8949", "894A", "89EB"
62};
63
64enum hp_wmi_radio {
65 HPWMI_WIFI = 0x0,
66 HPWMI_BLUETOOTH = 0x1,
67 HPWMI_WWAN = 0x2,
68 HPWMI_GPS = 0x3,
69};
70
71enum hp_wmi_event_ids {
72 HPWMI_DOCK_EVENT = 0x01,
73 HPWMI_PARK_HDD = 0x02,
74 HPWMI_SMART_ADAPTER = 0x03,
75 HPWMI_BEZEL_BUTTON = 0x04,
76 HPWMI_WIRELESS = 0x05,
77 HPWMI_CPU_BATTERY_THROTTLE = 0x06,
78 HPWMI_LOCK_SWITCH = 0x07,
79 HPWMI_LID_SWITCH = 0x08,
80 HPWMI_SCREEN_ROTATION = 0x09,
81 HPWMI_COOLSENSE_SYSTEM_MOBILE = 0x0A,
82 HPWMI_COOLSENSE_SYSTEM_HOT = 0x0B,
83 HPWMI_PROXIMITY_SENSOR = 0x0C,
84 HPWMI_BACKLIT_KB_BRIGHTNESS = 0x0D,
85 HPWMI_PEAKSHIFT_PERIOD = 0x0F,
86 HPWMI_BATTERY_CHARGE_PERIOD = 0x10,
87};
88
89struct bios_args {
90 u32 signature;
91 u32 command;
92 u32 commandtype;
93 u32 datasize;
94 u8 data[128];
95};
96
97enum hp_wmi_commandtype {
98 HPWMI_DISPLAY_QUERY = 0x01,
99 HPWMI_HDDTEMP_QUERY = 0x02,
100 HPWMI_ALS_QUERY = 0x03,
101 HPWMI_HARDWARE_QUERY = 0x04,
102 HPWMI_WIRELESS_QUERY = 0x05,
103 HPWMI_BATTERY_QUERY = 0x07,
104 HPWMI_BIOS_QUERY = 0x09,
105 HPWMI_FEATURE_QUERY = 0x0b,
106 HPWMI_HOTKEY_QUERY = 0x0c,
107 HPWMI_FEATURE2_QUERY = 0x0d,
108 HPWMI_WIRELESS2_QUERY = 0x1b,
109 HPWMI_POSTCODEERROR_QUERY = 0x2a,
110 HPWMI_THERMAL_PROFILE_QUERY = 0x4c,
111};
112
113enum hp_wmi_gm_commandtype {
114 HPWMI_FAN_SPEED_GET_QUERY = 0x11,
115 HPWMI_SET_PERFORMANCE_MODE = 0x1A,
116 HPWMI_FAN_SPEED_MAX_GET_QUERY = 0x26,
117 HPWMI_FAN_SPEED_MAX_SET_QUERY = 0x27,
118};
119
120enum hp_wmi_command {
121 HPWMI_READ = 0x01,
122 HPWMI_WRITE = 0x02,
123 HPWMI_ODM = 0x03,
124 HPWMI_GM = 0x20008,
125};
126
127enum hp_wmi_hardware_mask {
128 HPWMI_DOCK_MASK = 0x01,
129 HPWMI_TABLET_MASK = 0x04,
130};
131
132struct bios_return {
133 u32 sigpass;
134 u32 return_code;
135};
136
137enum hp_return_value {
138 HPWMI_RET_WRONG_SIGNATURE = 0x02,
139 HPWMI_RET_UNKNOWN_COMMAND = 0x03,
140 HPWMI_RET_UNKNOWN_CMDTYPE = 0x04,
141 HPWMI_RET_INVALID_PARAMETERS = 0x05,
142};
143
144enum hp_wireless2_bits {
145 HPWMI_POWER_STATE = 0x01,
146 HPWMI_POWER_SOFT = 0x02,
147 HPWMI_POWER_BIOS = 0x04,
148 HPWMI_POWER_HARD = 0x08,
149 HPWMI_POWER_FW_OR_HW = HPWMI_POWER_BIOS | HPWMI_POWER_HARD,
150};
151
152enum hp_thermal_profile_omen {
153 HP_OMEN_THERMAL_PROFILE_DEFAULT = 0x00,
154 HP_OMEN_THERMAL_PROFILE_PERFORMANCE = 0x01,
155 HP_OMEN_THERMAL_PROFILE_COOL = 0x02,
156};
157
158enum hp_thermal_profile {
159 HP_THERMAL_PROFILE_PERFORMANCE = 0x00,
160 HP_THERMAL_PROFILE_DEFAULT = 0x01,
161 HP_THERMAL_PROFILE_COOL = 0x02
162};
163
164#define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW)
165#define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT)
166
167struct bios_rfkill2_device_state {
168 u8 radio_type;
169 u8 bus_type;
170 u16 vendor_id;
171 u16 product_id;
172 u16 subsys_vendor_id;
173 u16 subsys_product_id;
174 u8 rfkill_id;
175 u8 power;
176 u8 unknown[4];
177};
178
179
180#define HPWMI_MAX_RFKILL2_DEVICES 7
181
182struct bios_rfkill2_state {
183 u8 unknown[7];
184 u8 count;
185 u8 pad[8];
186 struct bios_rfkill2_device_state device[HPWMI_MAX_RFKILL2_DEVICES];
187};
188
189static const struct key_entry hp_wmi_keymap[] = {
190 { KE_KEY, 0x02, { KEY_BRIGHTNESSUP } },
191 { KE_KEY, 0x03, { KEY_BRIGHTNESSDOWN } },
192 { KE_KEY, 0x20e6, { KEY_PROG1 } },
193 { KE_KEY, 0x20e8, { KEY_MEDIA } },
194 { KE_KEY, 0x2142, { KEY_MEDIA } },
195 { KE_KEY, 0x213b, { KEY_INFO } },
196 { KE_KEY, 0x2169, { KEY_ROTATE_DISPLAY } },
197 { KE_KEY, 0x216a, { KEY_SETUP } },
198 { KE_KEY, 0x231b, { KEY_HELP } },
199 { KE_END, 0 }
200};
201
202static struct input_dev *hp_wmi_input_dev;
203static struct platform_device *hp_wmi_platform_dev;
204static struct platform_profile_handler platform_profile_handler;
205static bool platform_profile_support;
206
207static struct rfkill *wifi_rfkill;
208static struct rfkill *bluetooth_rfkill;
209static struct rfkill *wwan_rfkill;
210
211struct rfkill2_device {
212 u8 id;
213 int num;
214 struct rfkill *rfkill;
215};
216
217static int rfkill2_count;
218static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
219
220
221static inline int encode_outsize_for_pvsz(int outsize)
222{
223 if (outsize > 4096)
224 return -EINVAL;
225 if (outsize > 1024)
226 return 5;
227 if (outsize > 128)
228 return 4;
229 if (outsize > 4)
230 return 3;
231 if (outsize > 0)
232 return 2;
233 return 1;
234}
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
257 void *buffer, int insize, int outsize)
258{
259 int mid;
260 struct bios_return *bios_return;
261 int actual_outsize;
262 union acpi_object *obj;
263 struct bios_args args = {
264 .signature = 0x55434553,
265 .command = command,
266 .commandtype = query,
267 .datasize = insize,
268 .data = { 0 },
269 };
270 struct acpi_buffer input = { sizeof(struct bios_args), &args };
271 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
272 int ret = 0;
273
274 mid = encode_outsize_for_pvsz(outsize);
275 if (WARN_ON(mid < 0))
276 return mid;
277
278 if (WARN_ON(insize > sizeof(args.data)))
279 return -EINVAL;
280 memcpy(&args.data[0], buffer, insize);
281
282 wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
283
284 obj = output.pointer;
285
286 if (!obj)
287 return -EINVAL;
288
289 if (obj->type != ACPI_TYPE_BUFFER) {
290 ret = -EINVAL;
291 goto out_free;
292 }
293
294 bios_return = (struct bios_return *)obj->buffer.pointer;
295 ret = bios_return->return_code;
296
297 if (ret) {
298 if (ret != HPWMI_RET_UNKNOWN_COMMAND &&
299 ret != HPWMI_RET_UNKNOWN_CMDTYPE)
300 pr_warn("query 0x%x returned error 0x%x\n", query, ret);
301 goto out_free;
302 }
303
304
305 if (!outsize)
306 goto out_free;
307
308 actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return)));
309 memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize);
310 memset(buffer + actual_outsize, 0, outsize - actual_outsize);
311
312out_free:
313 kfree(obj);
314 return ret;
315}
316
317static int hp_wmi_get_fan_speed(int fan)
318{
319 u8 fsh, fsl;
320 char fan_data[4] = { fan, 0, 0, 0 };
321
322 int ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_GET_QUERY, HPWMI_GM,
323 &fan_data, sizeof(fan_data),
324 sizeof(fan_data));
325
326 if (ret != 0)
327 return -EINVAL;
328
329 fsh = fan_data[2];
330 fsl = fan_data[3];
331
332 return (fsh << 8) | fsl;
333}
334
335static int hp_wmi_read_int(int query)
336{
337 int val = 0, ret;
338
339 ret = hp_wmi_perform_query(query, HPWMI_READ, &val,
340 sizeof(val), sizeof(val));
341
342 if (ret)
343 return ret < 0 ? ret : -EINVAL;
344
345 return val;
346}
347
348static int hp_wmi_hw_state(int mask)
349{
350 int state = hp_wmi_read_int(HPWMI_HARDWARE_QUERY);
351
352 if (state < 0)
353 return state;
354
355 return !!(state & mask);
356}
357
358static int omen_thermal_profile_set(int mode)
359{
360 char buffer[2] = {0, mode};
361 int ret;
362
363 if (mode < 0 || mode > 2)
364 return -EINVAL;
365
366 ret = hp_wmi_perform_query(HPWMI_SET_PERFORMANCE_MODE, HPWMI_GM,
367 &buffer, sizeof(buffer), sizeof(buffer));
368
369 if (ret)
370 return ret < 0 ? ret : -EINVAL;
371
372 return mode;
373}
374
375static bool is_omen_thermal_profile(void)
376{
377 const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
378
379 if (!board_name)
380 return false;
381
382 return match_string(omen_thermal_profile_boards,
383 ARRAY_SIZE(omen_thermal_profile_boards),
384 board_name) >= 0;
385}
386
387static int omen_thermal_profile_get(void)
388{
389 u8 data;
390
391 int ret = ec_read(HP_OMEN_EC_THERMAL_PROFILE_OFFSET, &data);
392
393 if (ret)
394 return ret;
395
396 return data;
397}
398
399static int hp_wmi_fan_speed_max_set(int enabled)
400{
401 int ret;
402
403 ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_SET_QUERY, HPWMI_GM,
404 &enabled, sizeof(enabled), sizeof(enabled));
405
406 if (ret)
407 return ret < 0 ? ret : -EINVAL;
408
409 return enabled;
410}
411
412static int hp_wmi_fan_speed_max_get(void)
413{
414 int val = 0, ret;
415
416 ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_GET_QUERY, HPWMI_GM,
417 &val, sizeof(val), sizeof(val));
418
419 if (ret)
420 return ret < 0 ? ret : -EINVAL;
421
422 return val;
423}
424
425static int __init hp_wmi_bios_2008_later(void)
426{
427 int state = 0;
428 int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, HPWMI_READ, &state,
429 sizeof(state), sizeof(state));
430 if (!ret)
431 return 1;
432
433 return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO;
434}
435
436static int __init hp_wmi_bios_2009_later(void)
437{
438 u8 state[128];
439 int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state,
440 sizeof(state), sizeof(state));
441 if (!ret)
442 return 1;
443
444 return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO;
445}
446
447static int __init hp_wmi_enable_hotkeys(void)
448{
449 int value = 0x6e;
450 int ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, HPWMI_WRITE, &value,
451 sizeof(value), 0);
452
453 return ret <= 0 ? ret : -EINVAL;
454}
455
456static int hp_wmi_set_block(void *data, bool blocked)
457{
458 enum hp_wmi_radio r = (enum hp_wmi_radio) data;
459 int query = BIT(r + 8) | ((!blocked) << r);
460 int ret;
461
462 ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE,
463 &query, sizeof(query), 0);
464
465 return ret <= 0 ? ret : -EINVAL;
466}
467
468static const struct rfkill_ops hp_wmi_rfkill_ops = {
469 .set_block = hp_wmi_set_block,
470};
471
472static bool hp_wmi_get_sw_state(enum hp_wmi_radio r)
473{
474 int mask = 0x200 << (r * 8);
475
476 int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
477
478
479 WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY");
480
481 return !(wireless & mask);
482}
483
484static bool hp_wmi_get_hw_state(enum hp_wmi_radio r)
485{
486 int mask = 0x800 << (r * 8);
487
488 int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
489
490
491 WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY");
492
493 return !(wireless & mask);
494}
495
496static int hp_wmi_rfkill2_set_block(void *data, bool blocked)
497{
498 int rfkill_id = (int)(long)data;
499 char buffer[4] = { 0x01, 0x00, rfkill_id, !blocked };
500 int ret;
501
502 ret = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_WRITE,
503 buffer, sizeof(buffer), 0);
504
505 return ret <= 0 ? ret : -EINVAL;
506}
507
508static const struct rfkill_ops hp_wmi_rfkill2_ops = {
509 .set_block = hp_wmi_rfkill2_set_block,
510};
511
512static int hp_wmi_rfkill2_refresh(void)
513{
514 struct bios_rfkill2_state state;
515 int err, i;
516
517 err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
518 sizeof(state), sizeof(state));
519 if (err)
520 return err;
521
522 for (i = 0; i < rfkill2_count; i++) {
523 int num = rfkill2[i].num;
524 struct bios_rfkill2_device_state *devstate;
525 devstate = &state.device[num];
526
527 if (num >= state.count ||
528 devstate->rfkill_id != rfkill2[i].id) {
529 pr_warn("power configuration of the wireless devices unexpectedly changed\n");
530 continue;
531 }
532
533 rfkill_set_states(rfkill2[i].rfkill,
534 IS_SWBLOCKED(devstate->power),
535 IS_HWBLOCKED(devstate->power));
536 }
537
538 return 0;
539}
540
541static ssize_t display_show(struct device *dev, struct device_attribute *attr,
542 char *buf)
543{
544 int value = hp_wmi_read_int(HPWMI_DISPLAY_QUERY);
545 if (value < 0)
546 return value;
547 return sprintf(buf, "%d\n", value);
548}
549
550static ssize_t hddtemp_show(struct device *dev, struct device_attribute *attr,
551 char *buf)
552{
553 int value = hp_wmi_read_int(HPWMI_HDDTEMP_QUERY);
554 if (value < 0)
555 return value;
556 return sprintf(buf, "%d\n", value);
557}
558
559static ssize_t als_show(struct device *dev, struct device_attribute *attr,
560 char *buf)
561{
562 int value = hp_wmi_read_int(HPWMI_ALS_QUERY);
563 if (value < 0)
564 return value;
565 return sprintf(buf, "%d\n", value);
566}
567
568static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
569 char *buf)
570{
571 int value = hp_wmi_hw_state(HPWMI_DOCK_MASK);
572 if (value < 0)
573 return value;
574 return sprintf(buf, "%d\n", value);
575}
576
577static ssize_t tablet_show(struct device *dev, struct device_attribute *attr,
578 char *buf)
579{
580 int value = hp_wmi_hw_state(HPWMI_TABLET_MASK);
581 if (value < 0)
582 return value;
583 return sprintf(buf, "%d\n", value);
584}
585
586static ssize_t postcode_show(struct device *dev, struct device_attribute *attr,
587 char *buf)
588{
589
590 int value = hp_wmi_read_int(HPWMI_POSTCODEERROR_QUERY);
591 if (value < 0)
592 return value;
593 return sprintf(buf, "0x%x\n", value);
594}
595
596static ssize_t als_store(struct device *dev, struct device_attribute *attr,
597 const char *buf, size_t count)
598{
599 u32 tmp;
600 int ret;
601
602 ret = kstrtou32(buf, 10, &tmp);
603 if (ret)
604 return ret;
605
606 ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp,
607 sizeof(tmp), sizeof(tmp));
608 if (ret)
609 return ret < 0 ? ret : -EINVAL;
610
611 return count;
612}
613
614static ssize_t postcode_store(struct device *dev, struct device_attribute *attr,
615 const char *buf, size_t count)
616{
617 u32 tmp = 1;
618 bool clear;
619 int ret;
620
621 ret = kstrtobool(buf, &clear);
622 if (ret)
623 return ret;
624
625 if (clear == false)
626 return -EINVAL;
627
628
629 ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, HPWMI_WRITE, &tmp,
630 sizeof(tmp), sizeof(tmp));
631 if (ret)
632 return ret < 0 ? ret : -EINVAL;
633
634 return count;
635}
636
637static DEVICE_ATTR_RO(display);
638static DEVICE_ATTR_RO(hddtemp);
639static DEVICE_ATTR_RW(als);
640static DEVICE_ATTR_RO(dock);
641static DEVICE_ATTR_RO(tablet);
642static DEVICE_ATTR_RW(postcode);
643
644static struct attribute *hp_wmi_attrs[] = {
645 &dev_attr_display.attr,
646 &dev_attr_hddtemp.attr,
647 &dev_attr_als.attr,
648 &dev_attr_dock.attr,
649 &dev_attr_tablet.attr,
650 &dev_attr_postcode.attr,
651 NULL,
652};
653ATTRIBUTE_GROUPS(hp_wmi);
654
655static void hp_wmi_notify(u32 value, void *context)
656{
657 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
658 u32 event_id, event_data;
659 union acpi_object *obj;
660 acpi_status status;
661 u32 *location;
662 int key_code;
663
664 status = wmi_get_event_data(value, &response);
665 if (status != AE_OK) {
666 pr_info("bad event status 0x%x\n", status);
667 return;
668 }
669
670 obj = (union acpi_object *)response.pointer;
671
672 if (!obj)
673 return;
674 if (obj->type != ACPI_TYPE_BUFFER) {
675 pr_info("Unknown response received %d\n", obj->type);
676 kfree(obj);
677 return;
678 }
679
680
681
682
683
684 location = (u32 *)obj->buffer.pointer;
685 if (obj->buffer.length == 8) {
686 event_id = *location;
687 event_data = *(location + 1);
688 } else if (obj->buffer.length == 16) {
689 event_id = *location;
690 event_data = *(location + 2);
691 } else {
692 pr_info("Unknown buffer length %d\n", obj->buffer.length);
693 kfree(obj);
694 return;
695 }
696 kfree(obj);
697
698 switch (event_id) {
699 case HPWMI_DOCK_EVENT:
700 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
701 input_report_switch(hp_wmi_input_dev, SW_DOCK,
702 hp_wmi_hw_state(HPWMI_DOCK_MASK));
703 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
704 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
705 hp_wmi_hw_state(HPWMI_TABLET_MASK));
706 input_sync(hp_wmi_input_dev);
707 break;
708 case HPWMI_PARK_HDD:
709 break;
710 case HPWMI_SMART_ADAPTER:
711 break;
712 case HPWMI_BEZEL_BUTTON:
713 key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY);
714 if (key_code < 0)
715 break;
716
717 if (!sparse_keymap_report_event(hp_wmi_input_dev,
718 key_code, 1, true))
719 pr_info("Unknown key code - 0x%x\n", key_code);
720 break;
721 case HPWMI_WIRELESS:
722 if (rfkill2_count) {
723 hp_wmi_rfkill2_refresh();
724 break;
725 }
726
727 if (wifi_rfkill)
728 rfkill_set_states(wifi_rfkill,
729 hp_wmi_get_sw_state(HPWMI_WIFI),
730 hp_wmi_get_hw_state(HPWMI_WIFI));
731 if (bluetooth_rfkill)
732 rfkill_set_states(bluetooth_rfkill,
733 hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
734 hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
735 if (wwan_rfkill)
736 rfkill_set_states(wwan_rfkill,
737 hp_wmi_get_sw_state(HPWMI_WWAN),
738 hp_wmi_get_hw_state(HPWMI_WWAN));
739 break;
740 case HPWMI_CPU_BATTERY_THROTTLE:
741 pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n");
742 break;
743 case HPWMI_LOCK_SWITCH:
744 break;
745 case HPWMI_LID_SWITCH:
746 break;
747 case HPWMI_SCREEN_ROTATION:
748 break;
749 case HPWMI_COOLSENSE_SYSTEM_MOBILE:
750 break;
751 case HPWMI_COOLSENSE_SYSTEM_HOT:
752 break;
753 case HPWMI_PROXIMITY_SENSOR:
754 break;
755 case HPWMI_BACKLIT_KB_BRIGHTNESS:
756 break;
757 case HPWMI_PEAKSHIFT_PERIOD:
758 break;
759 case HPWMI_BATTERY_CHARGE_PERIOD:
760 break;
761 default:
762 pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
763 break;
764 }
765}
766
767static int __init hp_wmi_input_setup(void)
768{
769 acpi_status status;
770 int err, val;
771
772 hp_wmi_input_dev = input_allocate_device();
773 if (!hp_wmi_input_dev)
774 return -ENOMEM;
775
776 hp_wmi_input_dev->name = "HP WMI hotkeys";
777 hp_wmi_input_dev->phys = "wmi/input0";
778 hp_wmi_input_dev->id.bustype = BUS_HOST;
779
780 __set_bit(EV_SW, hp_wmi_input_dev->evbit);
781
782
783 val = hp_wmi_hw_state(HPWMI_DOCK_MASK);
784 if (!(val < 0)) {
785 __set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
786 input_report_switch(hp_wmi_input_dev, SW_DOCK, val);
787 }
788
789
790 if (enable_tablet_mode_sw > 0) {
791 val = hp_wmi_hw_state(HPWMI_TABLET_MASK);
792 if (val >= 0) {
793 __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
794 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
795 }
796 }
797
798 err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
799 if (err)
800 goto err_free_dev;
801
802
803 input_sync(hp_wmi_input_dev);
804
805 if (!hp_wmi_bios_2009_later() && hp_wmi_bios_2008_later())
806 hp_wmi_enable_hotkeys();
807
808 status = wmi_install_notify_handler(HPWMI_EVENT_GUID, hp_wmi_notify, NULL);
809 if (ACPI_FAILURE(status)) {
810 err = -EIO;
811 goto err_free_dev;
812 }
813
814 err = input_register_device(hp_wmi_input_dev);
815 if (err)
816 goto err_uninstall_notifier;
817
818 return 0;
819
820 err_uninstall_notifier:
821 wmi_remove_notify_handler(HPWMI_EVENT_GUID);
822 err_free_dev:
823 input_free_device(hp_wmi_input_dev);
824 return err;
825}
826
827static void hp_wmi_input_destroy(void)
828{
829 wmi_remove_notify_handler(HPWMI_EVENT_GUID);
830 input_unregister_device(hp_wmi_input_dev);
831}
832
833static int __init hp_wmi_rfkill_setup(struct platform_device *device)
834{
835 int err, wireless;
836
837 wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
838 if (wireless < 0)
839 return wireless;
840
841 err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE, &wireless,
842 sizeof(wireless), 0);
843 if (err)
844 return err;
845
846 if (wireless & 0x1) {
847 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
848 RFKILL_TYPE_WLAN,
849 &hp_wmi_rfkill_ops,
850 (void *) HPWMI_WIFI);
851 if (!wifi_rfkill)
852 return -ENOMEM;
853 rfkill_init_sw_state(wifi_rfkill,
854 hp_wmi_get_sw_state(HPWMI_WIFI));
855 rfkill_set_hw_state(wifi_rfkill,
856 hp_wmi_get_hw_state(HPWMI_WIFI));
857 err = rfkill_register(wifi_rfkill);
858 if (err)
859 goto register_wifi_error;
860 }
861
862 if (wireless & 0x2) {
863 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
864 RFKILL_TYPE_BLUETOOTH,
865 &hp_wmi_rfkill_ops,
866 (void *) HPWMI_BLUETOOTH);
867 if (!bluetooth_rfkill) {
868 err = -ENOMEM;
869 goto register_bluetooth_error;
870 }
871 rfkill_init_sw_state(bluetooth_rfkill,
872 hp_wmi_get_sw_state(HPWMI_BLUETOOTH));
873 rfkill_set_hw_state(bluetooth_rfkill,
874 hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
875 err = rfkill_register(bluetooth_rfkill);
876 if (err)
877 goto register_bluetooth_error;
878 }
879
880 if (wireless & 0x4) {
881 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
882 RFKILL_TYPE_WWAN,
883 &hp_wmi_rfkill_ops,
884 (void *) HPWMI_WWAN);
885 if (!wwan_rfkill) {
886 err = -ENOMEM;
887 goto register_wwan_error;
888 }
889 rfkill_init_sw_state(wwan_rfkill,
890 hp_wmi_get_sw_state(HPWMI_WWAN));
891 rfkill_set_hw_state(wwan_rfkill,
892 hp_wmi_get_hw_state(HPWMI_WWAN));
893 err = rfkill_register(wwan_rfkill);
894 if (err)
895 goto register_wwan_error;
896 }
897
898 return 0;
899
900register_wwan_error:
901 rfkill_destroy(wwan_rfkill);
902 wwan_rfkill = NULL;
903 if (bluetooth_rfkill)
904 rfkill_unregister(bluetooth_rfkill);
905register_bluetooth_error:
906 rfkill_destroy(bluetooth_rfkill);
907 bluetooth_rfkill = NULL;
908 if (wifi_rfkill)
909 rfkill_unregister(wifi_rfkill);
910register_wifi_error:
911 rfkill_destroy(wifi_rfkill);
912 wifi_rfkill = NULL;
913 return err;
914}
915
916static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
917{
918 struct bios_rfkill2_state state;
919 int err, i;
920
921 err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
922 sizeof(state), sizeof(state));
923 if (err)
924 return err < 0 ? err : -EINVAL;
925
926 if (state.count > HPWMI_MAX_RFKILL2_DEVICES) {
927 pr_warn("unable to parse 0x1b query output\n");
928 return -EINVAL;
929 }
930
931 for (i = 0; i < state.count; i++) {
932 struct rfkill *rfkill;
933 enum rfkill_type type;
934 char *name;
935 switch (state.device[i].radio_type) {
936 case HPWMI_WIFI:
937 type = RFKILL_TYPE_WLAN;
938 name = "hp-wifi";
939 break;
940 case HPWMI_BLUETOOTH:
941 type = RFKILL_TYPE_BLUETOOTH;
942 name = "hp-bluetooth";
943 break;
944 case HPWMI_WWAN:
945 type = RFKILL_TYPE_WWAN;
946 name = "hp-wwan";
947 break;
948 case HPWMI_GPS:
949 type = RFKILL_TYPE_GPS;
950 name = "hp-gps";
951 break;
952 default:
953 pr_warn("unknown device type 0x%x\n",
954 state.device[i].radio_type);
955 continue;
956 }
957
958 if (!state.device[i].vendor_id) {
959 pr_warn("zero device %d while %d reported\n",
960 i, state.count);
961 continue;
962 }
963
964 rfkill = rfkill_alloc(name, &device->dev, type,
965 &hp_wmi_rfkill2_ops, (void *)(long)i);
966 if (!rfkill) {
967 err = -ENOMEM;
968 goto fail;
969 }
970
971 rfkill2[rfkill2_count].id = state.device[i].rfkill_id;
972 rfkill2[rfkill2_count].num = i;
973 rfkill2[rfkill2_count].rfkill = rfkill;
974
975 rfkill_init_sw_state(rfkill,
976 IS_SWBLOCKED(state.device[i].power));
977 rfkill_set_hw_state(rfkill,
978 IS_HWBLOCKED(state.device[i].power));
979
980 if (!(state.device[i].power & HPWMI_POWER_BIOS))
981 pr_info("device %s blocked by BIOS\n", name);
982
983 err = rfkill_register(rfkill);
984 if (err) {
985 rfkill_destroy(rfkill);
986 goto fail;
987 }
988
989 rfkill2_count++;
990 }
991
992 return 0;
993fail:
994 for (; rfkill2_count > 0; rfkill2_count--) {
995 rfkill_unregister(rfkill2[rfkill2_count - 1].rfkill);
996 rfkill_destroy(rfkill2[rfkill2_count - 1].rfkill);
997 }
998 return err;
999}
1000
1001static int platform_profile_omen_get(struct platform_profile_handler *pprof,
1002 enum platform_profile_option *profile)
1003{
1004 int tp;
1005
1006 tp = omen_thermal_profile_get();
1007 if (tp < 0)
1008 return tp;
1009
1010 switch (tp) {
1011 case HP_OMEN_THERMAL_PROFILE_PERFORMANCE:
1012 *profile = PLATFORM_PROFILE_PERFORMANCE;
1013 break;
1014 case HP_OMEN_THERMAL_PROFILE_DEFAULT:
1015 *profile = PLATFORM_PROFILE_BALANCED;
1016 break;
1017 case HP_OMEN_THERMAL_PROFILE_COOL:
1018 *profile = PLATFORM_PROFILE_COOL;
1019 break;
1020 default:
1021 return -EINVAL;
1022 }
1023
1024 return 0;
1025}
1026
1027static int platform_profile_omen_set(struct platform_profile_handler *pprof,
1028 enum platform_profile_option profile)
1029{
1030 int err, tp;
1031
1032 switch (profile) {
1033 case PLATFORM_PROFILE_PERFORMANCE:
1034 tp = HP_OMEN_THERMAL_PROFILE_PERFORMANCE;
1035 break;
1036 case PLATFORM_PROFILE_BALANCED:
1037 tp = HP_OMEN_THERMAL_PROFILE_DEFAULT;
1038 break;
1039 case PLATFORM_PROFILE_COOL:
1040 tp = HP_OMEN_THERMAL_PROFILE_COOL;
1041 break;
1042 default:
1043 return -EOPNOTSUPP;
1044 }
1045
1046 err = omen_thermal_profile_set(tp);
1047 if (err < 0)
1048 return err;
1049
1050 return 0;
1051}
1052
1053static int thermal_profile_get(void)
1054{
1055 return hp_wmi_read_int(HPWMI_THERMAL_PROFILE_QUERY);
1056}
1057
1058static int thermal_profile_set(int thermal_profile)
1059{
1060 return hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &thermal_profile,
1061 sizeof(thermal_profile), 0);
1062}
1063
1064static int hp_wmi_platform_profile_get(struct platform_profile_handler *pprof,
1065 enum platform_profile_option *profile)
1066{
1067 int tp;
1068
1069 tp = thermal_profile_get();
1070 if (tp < 0)
1071 return tp;
1072
1073 switch (tp) {
1074 case HP_THERMAL_PROFILE_PERFORMANCE:
1075 *profile = PLATFORM_PROFILE_PERFORMANCE;
1076 break;
1077 case HP_THERMAL_PROFILE_DEFAULT:
1078 *profile = PLATFORM_PROFILE_BALANCED;
1079 break;
1080 case HP_THERMAL_PROFILE_COOL:
1081 *profile = PLATFORM_PROFILE_COOL;
1082 break;
1083 default:
1084 return -EINVAL;
1085 }
1086
1087 return 0;
1088}
1089
1090static int hp_wmi_platform_profile_set(struct platform_profile_handler *pprof,
1091 enum platform_profile_option profile)
1092{
1093 int err, tp;
1094
1095 switch (profile) {
1096 case PLATFORM_PROFILE_PERFORMANCE:
1097 tp = HP_THERMAL_PROFILE_PERFORMANCE;
1098 break;
1099 case PLATFORM_PROFILE_BALANCED:
1100 tp = HP_THERMAL_PROFILE_DEFAULT;
1101 break;
1102 case PLATFORM_PROFILE_COOL:
1103 tp = HP_THERMAL_PROFILE_COOL;
1104 break;
1105 default:
1106 return -EOPNOTSUPP;
1107 }
1108
1109 err = thermal_profile_set(tp);
1110 if (err)
1111 return err;
1112
1113 return 0;
1114}
1115
1116static int thermal_profile_setup(void)
1117{
1118 int err, tp;
1119
1120 if (is_omen_thermal_profile()) {
1121 tp = omen_thermal_profile_get();
1122 if (tp < 0)
1123 return tp;
1124
1125
1126
1127
1128
1129
1130 err = omen_thermal_profile_set(tp);
1131 if (err < 0)
1132 return err;
1133
1134 platform_profile_handler.profile_get = platform_profile_omen_get;
1135 platform_profile_handler.profile_set = platform_profile_omen_set;
1136 } else {
1137 tp = thermal_profile_get();
1138
1139 if (tp < 0)
1140 return tp;
1141
1142
1143
1144
1145
1146 err = thermal_profile_set(tp);
1147 if (err)
1148 return err;
1149
1150 platform_profile_handler.profile_get = hp_wmi_platform_profile_get;
1151 platform_profile_handler.profile_set = hp_wmi_platform_profile_set;
1152 }
1153
1154 set_bit(PLATFORM_PROFILE_COOL, platform_profile_handler.choices);
1155 set_bit(PLATFORM_PROFILE_BALANCED, platform_profile_handler.choices);
1156 set_bit(PLATFORM_PROFILE_PERFORMANCE, platform_profile_handler.choices);
1157
1158 err = platform_profile_register(&platform_profile_handler);
1159 if (err)
1160 return err;
1161
1162 platform_profile_support = true;
1163
1164 return 0;
1165}
1166
1167static int hp_wmi_hwmon_init(void);
1168
1169static int __init hp_wmi_bios_setup(struct platform_device *device)
1170{
1171 int err;
1172
1173 wifi_rfkill = NULL;
1174 bluetooth_rfkill = NULL;
1175 wwan_rfkill = NULL;
1176 rfkill2_count = 0;
1177
1178 if (hp_wmi_rfkill_setup(device))
1179 hp_wmi_rfkill2_setup(device);
1180
1181 err = hp_wmi_hwmon_init();
1182
1183 if (err < 0)
1184 return err;
1185
1186 thermal_profile_setup();
1187
1188 return 0;
1189}
1190
1191static int __exit hp_wmi_bios_remove(struct platform_device *device)
1192{
1193 int i;
1194
1195 for (i = 0; i < rfkill2_count; i++) {
1196 rfkill_unregister(rfkill2[i].rfkill);
1197 rfkill_destroy(rfkill2[i].rfkill);
1198 }
1199
1200 if (wifi_rfkill) {
1201 rfkill_unregister(wifi_rfkill);
1202 rfkill_destroy(wifi_rfkill);
1203 }
1204 if (bluetooth_rfkill) {
1205 rfkill_unregister(bluetooth_rfkill);
1206 rfkill_destroy(bluetooth_rfkill);
1207 }
1208 if (wwan_rfkill) {
1209 rfkill_unregister(wwan_rfkill);
1210 rfkill_destroy(wwan_rfkill);
1211 }
1212
1213 if (platform_profile_support)
1214 platform_profile_remove();
1215
1216 return 0;
1217}
1218
1219static int hp_wmi_resume_handler(struct device *device)
1220{
1221
1222
1223
1224
1225
1226
1227 if (hp_wmi_input_dev) {
1228 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
1229 input_report_switch(hp_wmi_input_dev, SW_DOCK,
1230 hp_wmi_hw_state(HPWMI_DOCK_MASK));
1231 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
1232 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
1233 hp_wmi_hw_state(HPWMI_TABLET_MASK));
1234 input_sync(hp_wmi_input_dev);
1235 }
1236
1237 if (rfkill2_count)
1238 hp_wmi_rfkill2_refresh();
1239
1240 if (wifi_rfkill)
1241 rfkill_set_states(wifi_rfkill,
1242 hp_wmi_get_sw_state(HPWMI_WIFI),
1243 hp_wmi_get_hw_state(HPWMI_WIFI));
1244 if (bluetooth_rfkill)
1245 rfkill_set_states(bluetooth_rfkill,
1246 hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
1247 hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
1248 if (wwan_rfkill)
1249 rfkill_set_states(wwan_rfkill,
1250 hp_wmi_get_sw_state(HPWMI_WWAN),
1251 hp_wmi_get_hw_state(HPWMI_WWAN));
1252
1253 return 0;
1254}
1255
1256static const struct dev_pm_ops hp_wmi_pm_ops = {
1257 .resume = hp_wmi_resume_handler,
1258 .restore = hp_wmi_resume_handler,
1259};
1260
1261static struct platform_driver hp_wmi_driver = {
1262 .driver = {
1263 .name = "hp-wmi",
1264 .pm = &hp_wmi_pm_ops,
1265 .dev_groups = hp_wmi_groups,
1266 },
1267 .remove = __exit_p(hp_wmi_bios_remove),
1268};
1269
1270static umode_t hp_wmi_hwmon_is_visible(const void *data,
1271 enum hwmon_sensor_types type,
1272 u32 attr, int channel)
1273{
1274 switch (type) {
1275 case hwmon_pwm:
1276 return 0644;
1277 case hwmon_fan:
1278 if (hp_wmi_get_fan_speed(channel) >= 0)
1279 return 0444;
1280 break;
1281 default:
1282 return 0;
1283 }
1284
1285 return 0;
1286}
1287
1288static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
1289 u32 attr, int channel, long *val)
1290{
1291 int ret;
1292
1293 switch (type) {
1294 case hwmon_fan:
1295 ret = hp_wmi_get_fan_speed(channel);
1296
1297 if (ret < 0)
1298 return ret;
1299 *val = ret;
1300 return 0;
1301 case hwmon_pwm:
1302 switch (hp_wmi_fan_speed_max_get()) {
1303 case 0:
1304
1305 *val = 2;
1306 return 0;
1307 case 1:
1308
1309
1310
1311 *val = 0;
1312 return 0;
1313 default:
1314
1315 return -ENODATA;
1316 }
1317 default:
1318 return -EINVAL;
1319 }
1320}
1321
1322static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
1323 u32 attr, int channel, long val)
1324{
1325 switch (type) {
1326 case hwmon_pwm:
1327 switch (val) {
1328 case 0:
1329
1330 return hp_wmi_fan_speed_max_set(1);
1331 case 2:
1332
1333 return hp_wmi_fan_speed_max_set(0);
1334 default:
1335
1336 return -EINVAL;
1337 }
1338 default:
1339 return -EOPNOTSUPP;
1340 }
1341}
1342
1343static const struct hwmon_channel_info *info[] = {
1344 HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT, HWMON_F_INPUT),
1345 HWMON_CHANNEL_INFO(pwm, HWMON_PWM_ENABLE),
1346 NULL
1347};
1348
1349static const struct hwmon_ops ops = {
1350 .is_visible = hp_wmi_hwmon_is_visible,
1351 .read = hp_wmi_hwmon_read,
1352 .write = hp_wmi_hwmon_write,
1353};
1354
1355static const struct hwmon_chip_info chip_info = {
1356 .ops = &ops,
1357 .info = info,
1358};
1359
1360static int hp_wmi_hwmon_init(void)
1361{
1362 struct device *dev = &hp_wmi_platform_dev->dev;
1363 struct device *hwmon;
1364
1365 hwmon = devm_hwmon_device_register_with_info(dev, "hp", &hp_wmi_driver,
1366 &chip_info, NULL);
1367
1368 if (IS_ERR(hwmon)) {
1369 dev_err(dev, "Could not register hp hwmon device\n");
1370 return PTR_ERR(hwmon);
1371 }
1372
1373 return 0;
1374}
1375
1376static int __init hp_wmi_init(void)
1377{
1378 int event_capable = wmi_has_guid(HPWMI_EVENT_GUID);
1379 int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID);
1380 int err;
1381
1382 if (!bios_capable && !event_capable)
1383 return -ENODEV;
1384
1385 if (event_capable) {
1386 err = hp_wmi_input_setup();
1387 if (err)
1388 return err;
1389 }
1390
1391 if (bios_capable) {
1392 hp_wmi_platform_dev =
1393 platform_device_register_simple("hp-wmi", -1, NULL, 0);
1394 if (IS_ERR(hp_wmi_platform_dev)) {
1395 err = PTR_ERR(hp_wmi_platform_dev);
1396 goto err_destroy_input;
1397 }
1398
1399 err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
1400 if (err)
1401 goto err_unregister_device;
1402 }
1403
1404 return 0;
1405
1406err_unregister_device:
1407 platform_device_unregister(hp_wmi_platform_dev);
1408err_destroy_input:
1409 if (event_capable)
1410 hp_wmi_input_destroy();
1411
1412 return err;
1413}
1414module_init(hp_wmi_init);
1415
1416static void __exit hp_wmi_exit(void)
1417{
1418 if (wmi_has_guid(HPWMI_EVENT_GUID))
1419 hp_wmi_input_destroy();
1420
1421 if (hp_wmi_platform_dev) {
1422 platform_device_unregister(hp_wmi_platform_dev);
1423 platform_driver_unregister(&hp_wmi_driver);
1424 }
1425}
1426module_exit(hp_wmi_exit);
1427