Merge tag 'usb-serial-5.12-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / drivers / platform / x86 / hp-wmi.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * HP WMI hotkeys
4  *
5  * Copyright (C) 2008 Red Hat <mjg@redhat.com>
6  * Copyright (C) 2010, 2011 Anssi Hannula <anssi.hannula@iki.fi>
7  *
8  * Portions based on wistron_btns.c:
9  * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
10  * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
11  * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
12  */
13
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16 #include <linux/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/acpi.h>
25 #include <linux/rfkill.h>
26 #include <linux/string.h>
27
28 MODULE_AUTHOR("Matthew Garrett <mjg59@srcf.ucam.org>");
29 MODULE_DESCRIPTION("HP laptop WMI hotkeys driver");
30 MODULE_LICENSE("GPL");
31
32 MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C");
33 MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
34
35 static int enable_tablet_mode_sw = -1;
36 module_param(enable_tablet_mode_sw, int, 0444);
37 MODULE_PARM_DESC(enable_tablet_mode_sw, "Enable SW_TABLET_MODE reporting (-1=auto, 0=no, 1=yes)");
38
39 #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
40 #define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4"
41
42 enum hp_wmi_radio {
43         HPWMI_WIFI      = 0x0,
44         HPWMI_BLUETOOTH = 0x1,
45         HPWMI_WWAN      = 0x2,
46         HPWMI_GPS       = 0x3,
47 };
48
49 enum hp_wmi_event_ids {
50         HPWMI_DOCK_EVENT                = 0x01,
51         HPWMI_PARK_HDD                  = 0x02,
52         HPWMI_SMART_ADAPTER             = 0x03,
53         HPWMI_BEZEL_BUTTON              = 0x04,
54         HPWMI_WIRELESS                  = 0x05,
55         HPWMI_CPU_BATTERY_THROTTLE      = 0x06,
56         HPWMI_LOCK_SWITCH               = 0x07,
57         HPWMI_LID_SWITCH                = 0x08,
58         HPWMI_SCREEN_ROTATION           = 0x09,
59         HPWMI_COOLSENSE_SYSTEM_MOBILE   = 0x0A,
60         HPWMI_COOLSENSE_SYSTEM_HOT      = 0x0B,
61         HPWMI_PROXIMITY_SENSOR          = 0x0C,
62         HPWMI_BACKLIT_KB_BRIGHTNESS     = 0x0D,
63         HPWMI_PEAKSHIFT_PERIOD          = 0x0F,
64         HPWMI_BATTERY_CHARGE_PERIOD     = 0x10,
65 };
66
67 struct bios_args {
68         u32 signature;
69         u32 command;
70         u32 commandtype;
71         u32 datasize;
72         u8 data[128];
73 };
74
75 enum hp_wmi_commandtype {
76         HPWMI_DISPLAY_QUERY             = 0x01,
77         HPWMI_HDDTEMP_QUERY             = 0x02,
78         HPWMI_ALS_QUERY                 = 0x03,
79         HPWMI_HARDWARE_QUERY            = 0x04,
80         HPWMI_WIRELESS_QUERY            = 0x05,
81         HPWMI_BATTERY_QUERY             = 0x07,
82         HPWMI_BIOS_QUERY                = 0x09,
83         HPWMI_FEATURE_QUERY             = 0x0b,
84         HPWMI_HOTKEY_QUERY              = 0x0c,
85         HPWMI_FEATURE2_QUERY            = 0x0d,
86         HPWMI_WIRELESS2_QUERY           = 0x1b,
87         HPWMI_POSTCODEERROR_QUERY       = 0x2a,
88         HPWMI_THERMAL_POLICY_QUERY      = 0x4c,
89 };
90
91 enum hp_wmi_command {
92         HPWMI_READ      = 0x01,
93         HPWMI_WRITE     = 0x02,
94         HPWMI_ODM       = 0x03,
95 };
96
97 enum hp_wmi_hardware_mask {
98         HPWMI_DOCK_MASK         = 0x01,
99         HPWMI_TABLET_MASK       = 0x04,
100 };
101
102 struct bios_return {
103         u32 sigpass;
104         u32 return_code;
105 };
106
107 enum hp_return_value {
108         HPWMI_RET_WRONG_SIGNATURE       = 0x02,
109         HPWMI_RET_UNKNOWN_COMMAND       = 0x03,
110         HPWMI_RET_UNKNOWN_CMDTYPE       = 0x04,
111         HPWMI_RET_INVALID_PARAMETERS    = 0x05,
112 };
113
114 enum hp_wireless2_bits {
115         HPWMI_POWER_STATE       = 0x01,
116         HPWMI_POWER_SOFT        = 0x02,
117         HPWMI_POWER_BIOS        = 0x04,
118         HPWMI_POWER_HARD        = 0x08,
119         HPWMI_POWER_FW_OR_HW    = HPWMI_POWER_BIOS | HPWMI_POWER_HARD,
120 };
121
122 #define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW)
123 #define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT)
124
125 struct bios_rfkill2_device_state {
126         u8 radio_type;
127         u8 bus_type;
128         u16 vendor_id;
129         u16 product_id;
130         u16 subsys_vendor_id;
131         u16 subsys_product_id;
132         u8 rfkill_id;
133         u8 power;
134         u8 unknown[4];
135 };
136
137 /* 7 devices fit into the 128 byte buffer */
138 #define HPWMI_MAX_RFKILL2_DEVICES       7
139
140 struct bios_rfkill2_state {
141         u8 unknown[7];
142         u8 count;
143         u8 pad[8];
144         struct bios_rfkill2_device_state device[HPWMI_MAX_RFKILL2_DEVICES];
145 };
146
147 static const struct key_entry hp_wmi_keymap[] = {
148         { KE_KEY, 0x02,   { KEY_BRIGHTNESSUP } },
149         { KE_KEY, 0x03,   { KEY_BRIGHTNESSDOWN } },
150         { KE_KEY, 0x20e6, { KEY_PROG1 } },
151         { KE_KEY, 0x20e8, { KEY_MEDIA } },
152         { KE_KEY, 0x2142, { KEY_MEDIA } },
153         { KE_KEY, 0x213b, { KEY_INFO } },
154         { KE_KEY, 0x2169, { KEY_ROTATE_DISPLAY } },
155         { KE_KEY, 0x216a, { KEY_SETUP } },
156         { KE_KEY, 0x231b, { KEY_HELP } },
157         { KE_END, 0 }
158 };
159
160 static struct input_dev *hp_wmi_input_dev;
161 static struct platform_device *hp_wmi_platform_dev;
162
163 static struct rfkill *wifi_rfkill;
164 static struct rfkill *bluetooth_rfkill;
165 static struct rfkill *wwan_rfkill;
166
167 struct rfkill2_device {
168         u8 id;
169         int num;
170         struct rfkill *rfkill;
171 };
172
173 static int rfkill2_count;
174 static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
175
176 /* map output size to the corresponding WMI method id */
177 static inline int encode_outsize_for_pvsz(int outsize)
178 {
179         if (outsize > 4096)
180                 return -EINVAL;
181         if (outsize > 1024)
182                 return 5;
183         if (outsize > 128)
184                 return 4;
185         if (outsize > 4)
186                 return 3;
187         if (outsize > 0)
188                 return 2;
189         return 1;
190 }
191
192 /*
193  * hp_wmi_perform_query
194  *
195  * query:       The commandtype (enum hp_wmi_commandtype)
196  * write:       The command (enum hp_wmi_command)
197  * buffer:      Buffer used as input and/or output
198  * insize:      Size of input buffer
199  * outsize:     Size of output buffer
200  *
201  * returns zero on success
202  *         an HP WMI query specific error code (which is positive)
203  *         -EINVAL if the query was not successful at all
204  *         -EINVAL if the output buffer size exceeds buffersize
205  *
206  * Note: The buffersize must at least be the maximum of the input and output
207  *       size. E.g. Battery info query is defined to have 1 byte input
208  *       and 128 byte output. The caller would do:
209  *       buffer = kzalloc(128, GFP_KERNEL);
210  *       ret = hp_wmi_perform_query(HPWMI_BATTERY_QUERY, HPWMI_READ, buffer, 1, 128)
211  */
212 static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
213                                 void *buffer, int insize, int outsize)
214 {
215         int mid;
216         struct bios_return *bios_return;
217         int actual_outsize;
218         union acpi_object *obj;
219         struct bios_args args = {
220                 .signature = 0x55434553,
221                 .command = command,
222                 .commandtype = query,
223                 .datasize = insize,
224                 .data = { 0 },
225         };
226         struct acpi_buffer input = { sizeof(struct bios_args), &args };
227         struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
228         int ret = 0;
229
230         mid = encode_outsize_for_pvsz(outsize);
231         if (WARN_ON(mid < 0))
232                 return mid;
233
234         if (WARN_ON(insize > sizeof(args.data)))
235                 return -EINVAL;
236         memcpy(&args.data[0], buffer, insize);
237
238         wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
239
240         obj = output.pointer;
241
242         if (!obj)
243                 return -EINVAL;
244
245         if (obj->type != ACPI_TYPE_BUFFER) {
246                 ret = -EINVAL;
247                 goto out_free;
248         }
249
250         bios_return = (struct bios_return *)obj->buffer.pointer;
251         ret = bios_return->return_code;
252
253         if (ret) {
254                 if (ret != HPWMI_RET_UNKNOWN_COMMAND &&
255                     ret != HPWMI_RET_UNKNOWN_CMDTYPE)
256                         pr_warn("query 0x%x returned error 0x%x\n", query, ret);
257                 goto out_free;
258         }
259
260         /* Ignore output data of zero size */
261         if (!outsize)
262                 goto out_free;
263
264         actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return)));
265         memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize);
266         memset(buffer + actual_outsize, 0, outsize - actual_outsize);
267
268 out_free:
269         kfree(obj);
270         return ret;
271 }
272
273 static int hp_wmi_read_int(int query)
274 {
275         int val = 0, ret;
276
277         ret = hp_wmi_perform_query(query, HPWMI_READ, &val,
278                                    sizeof(val), sizeof(val));
279
280         if (ret)
281                 return ret < 0 ? ret : -EINVAL;
282
283         return val;
284 }
285
286 static int hp_wmi_hw_state(int mask)
287 {
288         int state = hp_wmi_read_int(HPWMI_HARDWARE_QUERY);
289
290         if (state < 0)
291                 return state;
292
293         return !!(state & mask);
294 }
295
296 static int __init hp_wmi_bios_2008_later(void)
297 {
298         int state = 0;
299         int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, HPWMI_READ, &state,
300                                        sizeof(state), sizeof(state));
301         if (!ret)
302                 return 1;
303
304         return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO;
305 }
306
307 static int __init hp_wmi_bios_2009_later(void)
308 {
309         u8 state[128];
310         int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state,
311                                        sizeof(state), sizeof(state));
312         if (!ret)
313                 return 1;
314
315         return (ret == HPWMI_RET_UNKNOWN_CMDTYPE) ? 0 : -ENXIO;
316 }
317
318 static int __init hp_wmi_enable_hotkeys(void)
319 {
320         int value = 0x6e;
321         int ret = hp_wmi_perform_query(HPWMI_BIOS_QUERY, HPWMI_WRITE, &value,
322                                        sizeof(value), 0);
323
324         return ret <= 0 ? ret : -EINVAL;
325 }
326
327 static int hp_wmi_set_block(void *data, bool blocked)
328 {
329         enum hp_wmi_radio r = (enum hp_wmi_radio) data;
330         int query = BIT(r + 8) | ((!blocked) << r);
331         int ret;
332
333         ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE,
334                                    &query, sizeof(query), 0);
335
336         return ret <= 0 ? ret : -EINVAL;
337 }
338
339 static const struct rfkill_ops hp_wmi_rfkill_ops = {
340         .set_block = hp_wmi_set_block,
341 };
342
343 static bool hp_wmi_get_sw_state(enum hp_wmi_radio r)
344 {
345         int mask = 0x200 << (r * 8);
346
347         int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
348
349         /* TBD: Pass error */
350         WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY");
351
352         return !(wireless & mask);
353 }
354
355 static bool hp_wmi_get_hw_state(enum hp_wmi_radio r)
356 {
357         int mask = 0x800 << (r * 8);
358
359         int wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
360
361         /* TBD: Pass error */
362         WARN_ONCE(wireless < 0, "error executing HPWMI_WIRELESS_QUERY");
363
364         return !(wireless & mask);
365 }
366
367 static int hp_wmi_rfkill2_set_block(void *data, bool blocked)
368 {
369         int rfkill_id = (int)(long)data;
370         char buffer[4] = { 0x01, 0x00, rfkill_id, !blocked };
371         int ret;
372
373         ret = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_WRITE,
374                                    buffer, sizeof(buffer), 0);
375
376         return ret <= 0 ? ret : -EINVAL;
377 }
378
379 static const struct rfkill_ops hp_wmi_rfkill2_ops = {
380         .set_block = hp_wmi_rfkill2_set_block,
381 };
382
383 static int hp_wmi_rfkill2_refresh(void)
384 {
385         struct bios_rfkill2_state state;
386         int err, i;
387
388         err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
389                                    sizeof(state), sizeof(state));
390         if (err)
391                 return err;
392
393         for (i = 0; i < rfkill2_count; i++) {
394                 int num = rfkill2[i].num;
395                 struct bios_rfkill2_device_state *devstate;
396                 devstate = &state.device[num];
397
398                 if (num >= state.count ||
399                     devstate->rfkill_id != rfkill2[i].id) {
400                         pr_warn("power configuration of the wireless devices unexpectedly changed\n");
401                         continue;
402                 }
403
404                 rfkill_set_states(rfkill2[i].rfkill,
405                                   IS_SWBLOCKED(devstate->power),
406                                   IS_HWBLOCKED(devstate->power));
407         }
408
409         return 0;
410 }
411
412 static ssize_t display_show(struct device *dev, struct device_attribute *attr,
413                             char *buf)
414 {
415         int value = hp_wmi_read_int(HPWMI_DISPLAY_QUERY);
416         if (value < 0)
417                 return value;
418         return sprintf(buf, "%d\n", value);
419 }
420
421 static ssize_t hddtemp_show(struct device *dev, struct device_attribute *attr,
422                             char *buf)
423 {
424         int value = hp_wmi_read_int(HPWMI_HDDTEMP_QUERY);
425         if (value < 0)
426                 return value;
427         return sprintf(buf, "%d\n", value);
428 }
429
430 static ssize_t als_show(struct device *dev, struct device_attribute *attr,
431                         char *buf)
432 {
433         int value = hp_wmi_read_int(HPWMI_ALS_QUERY);
434         if (value < 0)
435                 return value;
436         return sprintf(buf, "%d\n", value);
437 }
438
439 static ssize_t dock_show(struct device *dev, struct device_attribute *attr,
440                          char *buf)
441 {
442         int value = hp_wmi_hw_state(HPWMI_DOCK_MASK);
443         if (value < 0)
444                 return value;
445         return sprintf(buf, "%d\n", value);
446 }
447
448 static ssize_t tablet_show(struct device *dev, struct device_attribute *attr,
449                            char *buf)
450 {
451         int value = hp_wmi_hw_state(HPWMI_TABLET_MASK);
452         if (value < 0)
453                 return value;
454         return sprintf(buf, "%d\n", value);
455 }
456
457 static ssize_t postcode_show(struct device *dev, struct device_attribute *attr,
458                              char *buf)
459 {
460         /* Get the POST error code of previous boot failure. */
461         int value = hp_wmi_read_int(HPWMI_POSTCODEERROR_QUERY);
462         if (value < 0)
463                 return value;
464         return sprintf(buf, "0x%x\n", value);
465 }
466
467 static ssize_t als_store(struct device *dev, struct device_attribute *attr,
468                          const char *buf, size_t count)
469 {
470         u32 tmp;
471         int ret;
472
473         ret = kstrtou32(buf, 10, &tmp);
474         if (ret)
475                 return ret;
476
477         ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp,
478                                        sizeof(tmp), sizeof(tmp));
479         if (ret)
480                 return ret < 0 ? ret : -EINVAL;
481
482         return count;
483 }
484
485 static ssize_t postcode_store(struct device *dev, struct device_attribute *attr,
486                               const char *buf, size_t count)
487 {
488         u32 tmp = 1;
489         bool clear;
490         int ret;
491
492         ret = kstrtobool(buf, &clear);
493         if (ret)
494                 return ret;
495
496         if (clear == false)
497                 return -EINVAL;
498
499         /* Clear the POST error code. It is kept until until cleared. */
500         ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, HPWMI_WRITE, &tmp,
501                                        sizeof(tmp), sizeof(tmp));
502         if (ret)
503                 return ret < 0 ? ret : -EINVAL;
504
505         return count;
506 }
507
508 static DEVICE_ATTR_RO(display);
509 static DEVICE_ATTR_RO(hddtemp);
510 static DEVICE_ATTR_RW(als);
511 static DEVICE_ATTR_RO(dock);
512 static DEVICE_ATTR_RO(tablet);
513 static DEVICE_ATTR_RW(postcode);
514
515 static struct attribute *hp_wmi_attrs[] = {
516         &dev_attr_display.attr,
517         &dev_attr_hddtemp.attr,
518         &dev_attr_als.attr,
519         &dev_attr_dock.attr,
520         &dev_attr_tablet.attr,
521         &dev_attr_postcode.attr,
522         NULL,
523 };
524 ATTRIBUTE_GROUPS(hp_wmi);
525
526 static void hp_wmi_notify(u32 value, void *context)
527 {
528         struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
529         u32 event_id, event_data;
530         union acpi_object *obj;
531         acpi_status status;
532         u32 *location;
533         int key_code;
534
535         status = wmi_get_event_data(value, &response);
536         if (status != AE_OK) {
537                 pr_info("bad event status 0x%x\n", status);
538                 return;
539         }
540
541         obj = (union acpi_object *)response.pointer;
542
543         if (!obj)
544                 return;
545         if (obj->type != ACPI_TYPE_BUFFER) {
546                 pr_info("Unknown response received %d\n", obj->type);
547                 kfree(obj);
548                 return;
549         }
550
551         /*
552          * Depending on ACPI version the concatenation of id and event data
553          * inside _WED function will result in a 8 or 16 byte buffer.
554          */
555         location = (u32 *)obj->buffer.pointer;
556         if (obj->buffer.length == 8) {
557                 event_id = *location;
558                 event_data = *(location + 1);
559         } else if (obj->buffer.length == 16) {
560                 event_id = *location;
561                 event_data = *(location + 2);
562         } else {
563                 pr_info("Unknown buffer length %d\n", obj->buffer.length);
564                 kfree(obj);
565                 return;
566         }
567         kfree(obj);
568
569         switch (event_id) {
570         case HPWMI_DOCK_EVENT:
571                 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
572                         input_report_switch(hp_wmi_input_dev, SW_DOCK,
573                                             hp_wmi_hw_state(HPWMI_DOCK_MASK));
574                 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
575                         input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
576                                             hp_wmi_hw_state(HPWMI_TABLET_MASK));
577                 input_sync(hp_wmi_input_dev);
578                 break;
579         case HPWMI_PARK_HDD:
580                 break;
581         case HPWMI_SMART_ADAPTER:
582                 break;
583         case HPWMI_BEZEL_BUTTON:
584                 key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY);
585                 if (key_code < 0)
586                         break;
587
588                 if (!sparse_keymap_report_event(hp_wmi_input_dev,
589                                                 key_code, 1, true))
590                         pr_info("Unknown key code - 0x%x\n", key_code);
591                 break;
592         case HPWMI_WIRELESS:
593                 if (rfkill2_count) {
594                         hp_wmi_rfkill2_refresh();
595                         break;
596                 }
597
598                 if (wifi_rfkill)
599                         rfkill_set_states(wifi_rfkill,
600                                           hp_wmi_get_sw_state(HPWMI_WIFI),
601                                           hp_wmi_get_hw_state(HPWMI_WIFI));
602                 if (bluetooth_rfkill)
603                         rfkill_set_states(bluetooth_rfkill,
604                                           hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
605                                           hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
606                 if (wwan_rfkill)
607                         rfkill_set_states(wwan_rfkill,
608                                           hp_wmi_get_sw_state(HPWMI_WWAN),
609                                           hp_wmi_get_hw_state(HPWMI_WWAN));
610                 break;
611         case HPWMI_CPU_BATTERY_THROTTLE:
612                 pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n");
613                 break;
614         case HPWMI_LOCK_SWITCH:
615                 break;
616         case HPWMI_LID_SWITCH:
617                 break;
618         case HPWMI_SCREEN_ROTATION:
619                 break;
620         case HPWMI_COOLSENSE_SYSTEM_MOBILE:
621                 break;
622         case HPWMI_COOLSENSE_SYSTEM_HOT:
623                 break;
624         case HPWMI_PROXIMITY_SENSOR:
625                 break;
626         case HPWMI_BACKLIT_KB_BRIGHTNESS:
627                 break;
628         case HPWMI_PEAKSHIFT_PERIOD:
629                 break;
630         case HPWMI_BATTERY_CHARGE_PERIOD:
631                 break;
632         default:
633                 pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
634                 break;
635         }
636 }
637
638 static int __init hp_wmi_input_setup(void)
639 {
640         acpi_status status;
641         int err, val;
642
643         hp_wmi_input_dev = input_allocate_device();
644         if (!hp_wmi_input_dev)
645                 return -ENOMEM;
646
647         hp_wmi_input_dev->name = "HP WMI hotkeys";
648         hp_wmi_input_dev->phys = "wmi/input0";
649         hp_wmi_input_dev->id.bustype = BUS_HOST;
650
651         __set_bit(EV_SW, hp_wmi_input_dev->evbit);
652
653         /* Dock */
654         val = hp_wmi_hw_state(HPWMI_DOCK_MASK);
655         if (!(val < 0)) {
656                 __set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
657                 input_report_switch(hp_wmi_input_dev, SW_DOCK, val);
658         }
659
660         /* Tablet mode */
661         if (enable_tablet_mode_sw > 0) {
662                 val = hp_wmi_hw_state(HPWMI_TABLET_MASK);
663                 if (val >= 0) {
664                         __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
665                         input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
666                 }
667         }
668
669         err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
670         if (err)
671                 goto err_free_dev;
672
673         /* Set initial hardware state */
674         input_sync(hp_wmi_input_dev);
675
676         if (!hp_wmi_bios_2009_later() && hp_wmi_bios_2008_later())
677                 hp_wmi_enable_hotkeys();
678
679         status = wmi_install_notify_handler(HPWMI_EVENT_GUID, hp_wmi_notify, NULL);
680         if (ACPI_FAILURE(status)) {
681                 err = -EIO;
682                 goto err_free_dev;
683         }
684
685         err = input_register_device(hp_wmi_input_dev);
686         if (err)
687                 goto err_uninstall_notifier;
688
689         return 0;
690
691  err_uninstall_notifier:
692         wmi_remove_notify_handler(HPWMI_EVENT_GUID);
693  err_free_dev:
694         input_free_device(hp_wmi_input_dev);
695         return err;
696 }
697
698 static void hp_wmi_input_destroy(void)
699 {
700         wmi_remove_notify_handler(HPWMI_EVENT_GUID);
701         input_unregister_device(hp_wmi_input_dev);
702 }
703
704 static int __init hp_wmi_rfkill_setup(struct platform_device *device)
705 {
706         int err, wireless;
707
708         wireless = hp_wmi_read_int(HPWMI_WIRELESS_QUERY);
709         if (wireless < 0)
710                 return wireless;
711
712         err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, HPWMI_WRITE, &wireless,
713                                    sizeof(wireless), 0);
714         if (err)
715                 return err;
716
717         if (wireless & 0x1) {
718                 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
719                                            RFKILL_TYPE_WLAN,
720                                            &hp_wmi_rfkill_ops,
721                                            (void *) HPWMI_WIFI);
722                 if (!wifi_rfkill)
723                         return -ENOMEM;
724                 rfkill_init_sw_state(wifi_rfkill,
725                                      hp_wmi_get_sw_state(HPWMI_WIFI));
726                 rfkill_set_hw_state(wifi_rfkill,
727                                     hp_wmi_get_hw_state(HPWMI_WIFI));
728                 err = rfkill_register(wifi_rfkill);
729                 if (err)
730                         goto register_wifi_error;
731         }
732
733         if (wireless & 0x2) {
734                 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
735                                                 RFKILL_TYPE_BLUETOOTH,
736                                                 &hp_wmi_rfkill_ops,
737                                                 (void *) HPWMI_BLUETOOTH);
738                 if (!bluetooth_rfkill) {
739                         err = -ENOMEM;
740                         goto register_bluetooth_error;
741                 }
742                 rfkill_init_sw_state(bluetooth_rfkill,
743                                      hp_wmi_get_sw_state(HPWMI_BLUETOOTH));
744                 rfkill_set_hw_state(bluetooth_rfkill,
745                                     hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
746                 err = rfkill_register(bluetooth_rfkill);
747                 if (err)
748                         goto register_bluetooth_error;
749         }
750
751         if (wireless & 0x4) {
752                 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
753                                            RFKILL_TYPE_WWAN,
754                                            &hp_wmi_rfkill_ops,
755                                            (void *) HPWMI_WWAN);
756                 if (!wwan_rfkill) {
757                         err = -ENOMEM;
758                         goto register_wwan_error;
759                 }
760                 rfkill_init_sw_state(wwan_rfkill,
761                                      hp_wmi_get_sw_state(HPWMI_WWAN));
762                 rfkill_set_hw_state(wwan_rfkill,
763                                     hp_wmi_get_hw_state(HPWMI_WWAN));
764                 err = rfkill_register(wwan_rfkill);
765                 if (err)
766                         goto register_wwan_error;
767         }
768
769         return 0;
770
771 register_wwan_error:
772         rfkill_destroy(wwan_rfkill);
773         wwan_rfkill = NULL;
774         if (bluetooth_rfkill)
775                 rfkill_unregister(bluetooth_rfkill);
776 register_bluetooth_error:
777         rfkill_destroy(bluetooth_rfkill);
778         bluetooth_rfkill = NULL;
779         if (wifi_rfkill)
780                 rfkill_unregister(wifi_rfkill);
781 register_wifi_error:
782         rfkill_destroy(wifi_rfkill);
783         wifi_rfkill = NULL;
784         return err;
785 }
786
787 static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
788 {
789         struct bios_rfkill2_state state;
790         int err, i;
791
792         err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
793                                    sizeof(state), sizeof(state));
794         if (err)
795                 return err < 0 ? err : -EINVAL;
796
797         if (state.count > HPWMI_MAX_RFKILL2_DEVICES) {
798                 pr_warn("unable to parse 0x1b query output\n");
799                 return -EINVAL;
800         }
801
802         for (i = 0; i < state.count; i++) {
803                 struct rfkill *rfkill;
804                 enum rfkill_type type;
805                 char *name;
806                 switch (state.device[i].radio_type) {
807                 case HPWMI_WIFI:
808                         type = RFKILL_TYPE_WLAN;
809                         name = "hp-wifi";
810                         break;
811                 case HPWMI_BLUETOOTH:
812                         type = RFKILL_TYPE_BLUETOOTH;
813                         name = "hp-bluetooth";
814                         break;
815                 case HPWMI_WWAN:
816                         type = RFKILL_TYPE_WWAN;
817                         name = "hp-wwan";
818                         break;
819                 case HPWMI_GPS:
820                         type = RFKILL_TYPE_GPS;
821                         name = "hp-gps";
822                         break;
823                 default:
824                         pr_warn("unknown device type 0x%x\n",
825                                 state.device[i].radio_type);
826                         continue;
827                 }
828
829                 if (!state.device[i].vendor_id) {
830                         pr_warn("zero device %d while %d reported\n",
831                                 i, state.count);
832                         continue;
833                 }
834
835                 rfkill = rfkill_alloc(name, &device->dev, type,
836                                       &hp_wmi_rfkill2_ops, (void *)(long)i);
837                 if (!rfkill) {
838                         err = -ENOMEM;
839                         goto fail;
840                 }
841
842                 rfkill2[rfkill2_count].id = state.device[i].rfkill_id;
843                 rfkill2[rfkill2_count].num = i;
844                 rfkill2[rfkill2_count].rfkill = rfkill;
845
846                 rfkill_init_sw_state(rfkill,
847                                      IS_SWBLOCKED(state.device[i].power));
848                 rfkill_set_hw_state(rfkill,
849                                     IS_HWBLOCKED(state.device[i].power));
850
851                 if (!(state.device[i].power & HPWMI_POWER_BIOS))
852                         pr_info("device %s blocked by BIOS\n", name);
853
854                 err = rfkill_register(rfkill);
855                 if (err) {
856                         rfkill_destroy(rfkill);
857                         goto fail;
858                 }
859
860                 rfkill2_count++;
861         }
862
863         return 0;
864 fail:
865         for (; rfkill2_count > 0; rfkill2_count--) {
866                 rfkill_unregister(rfkill2[rfkill2_count - 1].rfkill);
867                 rfkill_destroy(rfkill2[rfkill2_count - 1].rfkill);
868         }
869         return err;
870 }
871
872 static int thermal_policy_setup(struct platform_device *device)
873 {
874         int err, tp;
875
876         tp = hp_wmi_read_int(HPWMI_THERMAL_POLICY_QUERY);
877         if (tp < 0)
878                 return tp;
879
880         /*
881          * call thermal policy write command to ensure that the firmware correctly
882          * sets the OEM variables for the DPTF
883          */
884         err = hp_wmi_perform_query(HPWMI_THERMAL_POLICY_QUERY, HPWMI_WRITE, &tp,
885                                                            sizeof(tp), 0);
886         if (err)
887                 return err;
888
889         return 0;
890 }
891
892 static int __init hp_wmi_bios_setup(struct platform_device *device)
893 {
894         /* clear detected rfkill devices */
895         wifi_rfkill = NULL;
896         bluetooth_rfkill = NULL;
897         wwan_rfkill = NULL;
898         rfkill2_count = 0;
899
900         if (hp_wmi_rfkill_setup(device))
901                 hp_wmi_rfkill2_setup(device);
902
903         thermal_policy_setup(device);
904
905         return 0;
906 }
907
908 static int __exit hp_wmi_bios_remove(struct platform_device *device)
909 {
910         int i;
911
912         for (i = 0; i < rfkill2_count; i++) {
913                 rfkill_unregister(rfkill2[i].rfkill);
914                 rfkill_destroy(rfkill2[i].rfkill);
915         }
916
917         if (wifi_rfkill) {
918                 rfkill_unregister(wifi_rfkill);
919                 rfkill_destroy(wifi_rfkill);
920         }
921         if (bluetooth_rfkill) {
922                 rfkill_unregister(bluetooth_rfkill);
923                 rfkill_destroy(bluetooth_rfkill);
924         }
925         if (wwan_rfkill) {
926                 rfkill_unregister(wwan_rfkill);
927                 rfkill_destroy(wwan_rfkill);
928         }
929
930         return 0;
931 }
932
933 static int hp_wmi_resume_handler(struct device *device)
934 {
935         /*
936          * Hardware state may have changed while suspended, so trigger
937          * input events for the current state. As this is a switch,
938          * the input layer will only actually pass it on if the state
939          * changed.
940          */
941         if (hp_wmi_input_dev) {
942                 if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
943                         input_report_switch(hp_wmi_input_dev, SW_DOCK,
944                                             hp_wmi_hw_state(HPWMI_DOCK_MASK));
945                 if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
946                         input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
947                                             hp_wmi_hw_state(HPWMI_TABLET_MASK));
948                 input_sync(hp_wmi_input_dev);
949         }
950
951         if (rfkill2_count)
952                 hp_wmi_rfkill2_refresh();
953
954         if (wifi_rfkill)
955                 rfkill_set_states(wifi_rfkill,
956                                   hp_wmi_get_sw_state(HPWMI_WIFI),
957                                   hp_wmi_get_hw_state(HPWMI_WIFI));
958         if (bluetooth_rfkill)
959                 rfkill_set_states(bluetooth_rfkill,
960                                   hp_wmi_get_sw_state(HPWMI_BLUETOOTH),
961                                   hp_wmi_get_hw_state(HPWMI_BLUETOOTH));
962         if (wwan_rfkill)
963                 rfkill_set_states(wwan_rfkill,
964                                   hp_wmi_get_sw_state(HPWMI_WWAN),
965                                   hp_wmi_get_hw_state(HPWMI_WWAN));
966
967         return 0;
968 }
969
970 static const struct dev_pm_ops hp_wmi_pm_ops = {
971         .resume  = hp_wmi_resume_handler,
972         .restore  = hp_wmi_resume_handler,
973 };
974
975 static struct platform_driver hp_wmi_driver = {
976         .driver = {
977                 .name = "hp-wmi",
978                 .pm = &hp_wmi_pm_ops,
979                 .dev_groups = hp_wmi_groups,
980         },
981         .remove = __exit_p(hp_wmi_bios_remove),
982 };
983
984 static int __init hp_wmi_init(void)
985 {
986         int event_capable = wmi_has_guid(HPWMI_EVENT_GUID);
987         int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID);
988         int err;
989
990         if (!bios_capable && !event_capable)
991                 return -ENODEV;
992
993         if (event_capable) {
994                 err = hp_wmi_input_setup();
995                 if (err)
996                         return err;
997         }
998
999         if (bios_capable) {
1000                 hp_wmi_platform_dev =
1001                         platform_device_register_simple("hp-wmi", -1, NULL, 0);
1002                 if (IS_ERR(hp_wmi_platform_dev)) {
1003                         err = PTR_ERR(hp_wmi_platform_dev);
1004                         goto err_destroy_input;
1005                 }
1006
1007                 err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
1008                 if (err)
1009                         goto err_unregister_device;
1010         }
1011
1012         return 0;
1013
1014 err_unregister_device:
1015         platform_device_unregister(hp_wmi_platform_dev);
1016 err_destroy_input:
1017         if (event_capable)
1018                 hp_wmi_input_destroy();
1019
1020         return err;
1021 }
1022 module_init(hp_wmi_init);
1023
1024 static void __exit hp_wmi_exit(void)
1025 {
1026         if (wmi_has_guid(HPWMI_EVENT_GUID))
1027                 hp_wmi_input_destroy();
1028
1029         if (hp_wmi_platform_dev) {
1030                 platform_device_unregister(hp_wmi_platform_dev);
1031                 platform_driver_unregister(&hp_wmi_driver);
1032         }
1033 }
1034 module_exit(hp_wmi_exit);