diff options
Diffstat (limited to 'drivers/platform/x86/dell-laptop.c')
-rw-r--r-- | drivers/platform/x86/dell-laptop.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index f31fa4efa725..d93e962f2610 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -60,6 +60,22 @@ struct calling_interface_structure { | |||
60 | struct calling_interface_token tokens[]; | 60 | struct calling_interface_token tokens[]; |
61 | } __packed; | 61 | } __packed; |
62 | 62 | ||
63 | struct quirk_entry { | ||
64 | u8 touchpad_led; | ||
65 | }; | ||
66 | |||
67 | static struct quirk_entry *quirks; | ||
68 | |||
69 | static struct quirk_entry quirk_dell_vostro_v130 = { | ||
70 | .touchpad_led = 1, | ||
71 | }; | ||
72 | |||
73 | static int dmi_matched(const struct dmi_system_id *dmi) | ||
74 | { | ||
75 | quirks = dmi->driver_data; | ||
76 | return 1; | ||
77 | } | ||
78 | |||
63 | static int da_command_address; | 79 | static int da_command_address; |
64 | static int da_command_code; | 80 | static int da_command_code; |
65 | static int da_num_tokens; | 81 | static int da_num_tokens; |
@@ -149,6 +165,27 @@ static struct dmi_system_id __devinitdata dell_blacklist[] = { | |||
149 | {} | 165 | {} |
150 | }; | 166 | }; |
151 | 167 | ||
168 | static struct dmi_system_id __devinitdata dell_quirks[] = { | ||
169 | { | ||
170 | .callback = dmi_matched, | ||
171 | .ident = "Dell Vostro V130", | ||
172 | .matches = { | ||
173 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
174 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V130"), | ||
175 | }, | ||
176 | .driver_data = &quirk_dell_vostro_v130, | ||
177 | }, | ||
178 | { | ||
179 | .callback = dmi_matched, | ||
180 | .ident = "Dell Vostro V131", | ||
181 | .matches = { | ||
182 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
183 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"), | ||
184 | }, | ||
185 | .driver_data = &quirk_dell_vostro_v130, | ||
186 | }, | ||
187 | }; | ||
188 | |||
152 | static struct calling_interface_buffer *buffer; | 189 | static struct calling_interface_buffer *buffer; |
153 | static struct page *bufferpage; | 190 | static struct page *bufferpage; |
154 | static DEFINE_MUTEX(buffer_mutex); | 191 | static DEFINE_MUTEX(buffer_mutex); |
@@ -552,6 +589,44 @@ static const struct backlight_ops dell_ops = { | |||
552 | .update_status = dell_send_intensity, | 589 | .update_status = dell_send_intensity, |
553 | }; | 590 | }; |
554 | 591 | ||
592 | static void touchpad_led_on(void) | ||
593 | { | ||
594 | int command = 0x97; | ||
595 | char data = 1; | ||
596 | i8042_command(&data, command | 1 << 12); | ||
597 | } | ||
598 | |||
599 | static void touchpad_led_off(void) | ||
600 | { | ||
601 | int command = 0x97; | ||
602 | char data = 2; | ||
603 | i8042_command(&data, command | 1 << 12); | ||
604 | } | ||
605 | |||
606 | static void touchpad_led_set(struct led_classdev *led_cdev, | ||
607 | enum led_brightness value) | ||
608 | { | ||
609 | if (value > 0) | ||
610 | touchpad_led_on(); | ||
611 | else | ||
612 | touchpad_led_off(); | ||
613 | } | ||
614 | |||
615 | static struct led_classdev touchpad_led = { | ||
616 | .name = "dell-laptop::touchpad", | ||
617 | .brightness_set = touchpad_led_set, | ||
618 | }; | ||
619 | |||
620 | static int __devinit touchpad_led_init(struct device *dev) | ||
621 | { | ||
622 | return led_classdev_register(dev, &touchpad_led); | ||
623 | } | ||
624 | |||
625 | static void touchpad_led_exit(void) | ||
626 | { | ||
627 | led_classdev_unregister(&touchpad_led); | ||
628 | } | ||
629 | |||
555 | static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str, | 630 | static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str, |
556 | struct serio *port) | 631 | struct serio *port) |
557 | { | 632 | { |
@@ -584,6 +659,10 @@ static int __init dell_init(void) | |||
584 | if (!dmi_check_system(dell_device_table)) | 659 | if (!dmi_check_system(dell_device_table)) |
585 | return -ENODEV; | 660 | return -ENODEV; |
586 | 661 | ||
662 | quirks = NULL; | ||
663 | /* find if this machine support other functions */ | ||
664 | dmi_check_system(dell_quirks); | ||
665 | |||
587 | dmi_walk(find_tokens, NULL); | 666 | dmi_walk(find_tokens, NULL); |
588 | 667 | ||
589 | if (!da_tokens) { | 668 | if (!da_tokens) { |
@@ -626,6 +705,9 @@ static int __init dell_init(void) | |||
626 | goto fail_filter; | 705 | goto fail_filter; |
627 | } | 706 | } |
628 | 707 | ||
708 | if (quirks && quirks->touchpad_led) | ||
709 | touchpad_led_init(&platform_device->dev); | ||
710 | |||
629 | dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); | 711 | dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); |
630 | if (dell_laptop_dir != NULL) | 712 | if (dell_laptop_dir != NULL) |
631 | debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, | 713 | debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, |
@@ -692,6 +774,8 @@ fail_platform_driver: | |||
692 | static void __exit dell_exit(void) | 774 | static void __exit dell_exit(void) |
693 | { | 775 | { |
694 | debugfs_remove_recursive(dell_laptop_dir); | 776 | debugfs_remove_recursive(dell_laptop_dir); |
777 | if (quirks && quirks->touchpad_led) | ||
778 | touchpad_led_exit(); | ||
695 | i8042_remove_filter(dell_laptop_i8042_filter); | 779 | i8042_remove_filter(dell_laptop_i8042_filter); |
696 | cancel_delayed_work_sync(&dell_rfkill_work); | 780 | cancel_delayed_work_sync(&dell_rfkill_work); |
697 | backlight_device_unregister(dell_backlight_device); | 781 | backlight_device_unregister(dell_backlight_device); |