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