eeepc-wmi.c (084fca63128849c0961b3cfdb0cd0345e8f51ad8) eeepc-wmi.c (ba48fdb969d0404d54f6fa0266373afecbbd19d7)
1/*
2 * Eee PC WMI hotkey driver
3 *
4 * Copyright(C) 2010 Intel Corporation.
5 *
6 * Portions based on wistron_btns.c:
7 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
8 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>

--- 21 unchanged lines hidden (view full) ---

30#include <linux/init.h>
31#include <linux/types.h>
32#include <linux/slab.h>
33#include <linux/input.h>
34#include <linux/input/sparse-keymap.h>
35#include <linux/fb.h>
36#include <linux/backlight.h>
37#include <linux/leds.h>
1/*
2 * Eee PC WMI hotkey driver
3 *
4 * Copyright(C) 2010 Intel Corporation.
5 *
6 * Portions based on wistron_btns.c:
7 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
8 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>

--- 21 unchanged lines hidden (view full) ---

30#include <linux/init.h>
31#include <linux/types.h>
32#include <linux/slab.h>
33#include <linux/input.h>
34#include <linux/input/sparse-keymap.h>
35#include <linux/fb.h>
36#include <linux/backlight.h>
37#include <linux/leds.h>
38#include <linux/rfkill.h>
38#include <linux/platform_device.h>
39#include <acpi/acpi_bus.h>
40#include <acpi/acpi_drivers.h>
41
42#define EEEPC_WMI_FILE "eeepc-wmi"
43
44MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
45MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");

--- 11 unchanged lines hidden (view full) ---

57#define NOTIFY_BRNDOWN_MAX 0x2e
58
59#define EEEPC_WMI_METHODID_DEVS 0x53564544
60#define EEEPC_WMI_METHODID_DSTS 0x53544344
61#define EEEPC_WMI_METHODID_CFVS 0x53564643
62
63#define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012
64#define EEEPC_WMI_DEVID_TPDLED 0x00100011
39#include <linux/platform_device.h>
40#include <acpi/acpi_bus.h>
41#include <acpi/acpi_drivers.h>
42
43#define EEEPC_WMI_FILE "eeepc-wmi"
44
45MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
46MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");

--- 11 unchanged lines hidden (view full) ---

58#define NOTIFY_BRNDOWN_MAX 0x2e
59
60#define EEEPC_WMI_METHODID_DEVS 0x53564544
61#define EEEPC_WMI_METHODID_DSTS 0x53544344
62#define EEEPC_WMI_METHODID_CFVS 0x53564643
63
64#define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012
65#define EEEPC_WMI_DEVID_TPDLED 0x00100011
66#define EEEPC_WMI_DEVID_WLAN 0x00010011
67#define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013
68#define EEEPC_WMI_DEVID_WWAN3G 0x00010019
65
66static const struct key_entry eeepc_wmi_keymap[] = {
67 /* Sleep already handled via generic ACPI code */
68 { KE_KEY, 0x5d, { KEY_WLAN } },
69 { KE_KEY, 0x32, { KEY_MUTE } },
70 { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
71 { KE_KEY, 0x30, { KEY_VOLUMEUP } },
72 { KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },

--- 16 unchanged lines hidden (view full) ---

89 struct input_dev *inputdev;
90 struct backlight_device *backlight_device;
91 struct platform_device *platform_device;
92
93 struct led_classdev tpd_led;
94 int tpd_led_wk;
95 struct workqueue_struct *led_workqueue;
96 struct work_struct tpd_led_work;
69
70static const struct key_entry eeepc_wmi_keymap[] = {
71 /* Sleep already handled via generic ACPI code */
72 { KE_KEY, 0x5d, { KEY_WLAN } },
73 { KE_KEY, 0x32, { KEY_MUTE } },
74 { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
75 { KE_KEY, 0x30, { KEY_VOLUMEUP } },
76 { KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },

--- 16 unchanged lines hidden (view full) ---

93 struct input_dev *inputdev;
94 struct backlight_device *backlight_device;
95 struct platform_device *platform_device;
96
97 struct led_classdev tpd_led;
98 int tpd_led_wk;
99 struct workqueue_struct *led_workqueue;
100 struct work_struct tpd_led_work;
101
102 struct rfkill *wlan_rfkill;
103 struct rfkill *bluetooth_rfkill;
104 struct rfkill *wwan3g_rfkill;
97};
98
99/* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */
100static struct platform_device *platform_device;
101
102static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
103{
104 int err;

--- 170 unchanged lines hidden (view full) ---

275{
276 if (eeepc->tpd_led.dev)
277 led_classdev_unregister(&eeepc->tpd_led);
278 if (eeepc->led_workqueue)
279 destroy_workqueue(eeepc->led_workqueue);
280}
281
282/*
105};
106
107/* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */
108static struct platform_device *platform_device;
109
110static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
111{
112 int err;

--- 170 unchanged lines hidden (view full) ---

283{
284 if (eeepc->tpd_led.dev)
285 led_classdev_unregister(&eeepc->tpd_led);
286 if (eeepc->led_workqueue)
287 destroy_workqueue(eeepc->led_workqueue);
288}
289
290/*
291 * Rfkill devices
292 */
293static int eeepc_rfkill_set(void *data, bool blocked)
294{
295 int dev_id = (unsigned long)data;
296 u32 ctrl_param = !blocked;
297
298 return eeepc_wmi_set_devstate(dev_id, ctrl_param);
299}
300
301static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
302{
303 int dev_id = (unsigned long)data;
304 u32 ctrl_param;
305 acpi_status status;
306
307 status = eeepc_wmi_get_devstate(dev_id, &ctrl_param);
308
309 if (ACPI_FAILURE(status))
310 return ;
311
312 rfkill_set_sw_state(rfkill, !(ctrl_param & 0x1));
313}
314
315static const struct rfkill_ops eeepc_rfkill_ops = {
316 .set_block = eeepc_rfkill_set,
317 .query = eeepc_rfkill_query,
318};
319
320static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
321 struct rfkill **rfkill,
322 const char *name,
323 enum rfkill_type type, int dev_id)
324{
325 int result;
326 u32 ctrl_param;
327 acpi_status status;
328
329 status = eeepc_wmi_get_devstate(dev_id, &ctrl_param);
330
331 if (ACPI_FAILURE(status))
332 return -1;
333
334 /* If the device is present, DSTS will always set some bits
335 * 0x00070000 - 1110000000000000000 - device supported
336 * 0x00060000 - 1100000000000000000 - not supported
337 * 0x00020000 - 0100000000000000000 - device supported
338 * 0x00010000 - 0010000000000000000 - not supported / special mode ?
339 */
340 if (!ctrl_param || ctrl_param == 0x00060000)
341 return -ENODEV;
342
343 *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
344 &eeepc_rfkill_ops, (void *)(long)dev_id);
345
346 if (!*rfkill)
347 return -EINVAL;
348
349 rfkill_init_sw_state(*rfkill, !(ctrl_param & 0x1));
350 result = rfkill_register(*rfkill);
351 if (result) {
352 rfkill_destroy(*rfkill);
353 *rfkill = NULL;
354 return result;
355 }
356 return 0;
357}
358
359static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc)
360{
361 if (eeepc->wlan_rfkill) {
362 rfkill_unregister(eeepc->wlan_rfkill);
363 rfkill_destroy(eeepc->wlan_rfkill);
364 eeepc->wlan_rfkill = NULL;
365 }
366 if (eeepc->bluetooth_rfkill) {
367 rfkill_unregister(eeepc->bluetooth_rfkill);
368 rfkill_destroy(eeepc->bluetooth_rfkill);
369 eeepc->bluetooth_rfkill = NULL;
370 }
371 if (eeepc->wwan3g_rfkill) {
372 rfkill_unregister(eeepc->wwan3g_rfkill);
373 rfkill_destroy(eeepc->wwan3g_rfkill);
374 eeepc->wwan3g_rfkill = NULL;
375 }
376}
377
378static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
379{
380 int result = 0;
381
382 result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
383 "eeepc-wlan", RFKILL_TYPE_WLAN,
384 EEEPC_WMI_DEVID_WLAN);
385
386 if (result && result != -ENODEV)
387 goto exit;
388
389 result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
390 "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
391 EEEPC_WMI_DEVID_BLUETOOTH);
392
393 if (result && result != -ENODEV)
394 goto exit;
395
396 result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
397 "eeepc-wwan3g", RFKILL_TYPE_WWAN,
398 EEEPC_WMI_DEVID_WWAN3G);
399
400 if (result && result != -ENODEV)
401 goto exit;
402
403exit:
404 if (result && result != -ENODEV)
405 eeepc_wmi_rfkill_exit(eeepc);
406
407 if (result == -ENODEV)
408 result = 0;
409
410 return result;
411}
412
413/*
283 * Backlight
284 */
285static int read_brightness(struct backlight_device *bd)
286{
287 static u32 ctrl_param;
288 acpi_status status;
289
290 status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &ctrl_param);

--- 216 unchanged lines hidden (view full) ---

507 err = eeepc_wmi_input_init(eeepc);
508 if (err)
509 goto fail_input;
510
511 err = eeepc_wmi_led_init(eeepc);
512 if (err)
513 goto fail_leds;
514
414 * Backlight
415 */
416static int read_brightness(struct backlight_device *bd)
417{
418 static u32 ctrl_param;
419 acpi_status status;
420
421 status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &ctrl_param);

--- 216 unchanged lines hidden (view full) ---

638 err = eeepc_wmi_input_init(eeepc);
639 if (err)
640 goto fail_input;
641
642 err = eeepc_wmi_led_init(eeepc);
643 if (err)
644 goto fail_leds;
645
646 err = eeepc_wmi_rfkill_init(eeepc);
647 if (err)
648 goto fail_rfkill;
649
515 if (!acpi_video_backlight_support()) {
516 err = eeepc_wmi_backlight_init(eeepc);
517 if (err)
518 goto fail_backlight;
519 } else
520 pr_info("Backlight controlled by ACPI video driver\n");
521
522 status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,

--- 5 unchanged lines hidden (view full) ---

528 goto fail_wmi_handler;
529 }
530
531 return eeepc->platform_device;
532
533fail_wmi_handler:
534 eeepc_wmi_backlight_exit(eeepc);
535fail_backlight:
650 if (!acpi_video_backlight_support()) {
651 err = eeepc_wmi_backlight_init(eeepc);
652 if (err)
653 goto fail_backlight;
654 } else
655 pr_info("Backlight controlled by ACPI video driver\n");
656
657 status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,

--- 5 unchanged lines hidden (view full) ---

663 goto fail_wmi_handler;
664 }
665
666 return eeepc->platform_device;
667
668fail_wmi_handler:
669 eeepc_wmi_backlight_exit(eeepc);
670fail_backlight:
671 eeepc_wmi_rfkill_exit(eeepc);
672fail_rfkill:
536 eeepc_wmi_led_exit(eeepc);
537fail_leds:
538 eeepc_wmi_input_exit(eeepc);
539fail_input:
540 eeepc_wmi_platform_exit(eeepc);
541fail_platform:
542 kfree(eeepc);
543 return ERR_PTR(err);
544}
545
546static int eeepc_wmi_remove(struct platform_device *device)
547{
548 struct eeepc_wmi *eeepc;
549
550 eeepc = platform_get_drvdata(device);
551 wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
552 eeepc_wmi_backlight_exit(eeepc);
553 eeepc_wmi_input_exit(eeepc);
554 eeepc_wmi_led_exit(eeepc);
673 eeepc_wmi_led_exit(eeepc);
674fail_leds:
675 eeepc_wmi_input_exit(eeepc);
676fail_input:
677 eeepc_wmi_platform_exit(eeepc);
678fail_platform:
679 kfree(eeepc);
680 return ERR_PTR(err);
681}
682
683static int eeepc_wmi_remove(struct platform_device *device)
684{
685 struct eeepc_wmi *eeepc;
686
687 eeepc = platform_get_drvdata(device);
688 wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
689 eeepc_wmi_backlight_exit(eeepc);
690 eeepc_wmi_input_exit(eeepc);
691 eeepc_wmi_led_exit(eeepc);
692 eeepc_wmi_rfkill_exit(eeepc);
555 eeepc_wmi_platform_exit(eeepc);
556
557 kfree(eeepc);
558 return 0;
559}
560
561static struct platform_driver platform_driver = {
562 .driver = {

--- 43 unchanged lines hidden ---
693 eeepc_wmi_platform_exit(eeepc);
694
695 kfree(eeepc);
696 return 0;
697}
698
699static struct platform_driver platform_driver = {
700 .driver = {

--- 43 unchanged lines hidden ---