aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86
diff options
context:
space:
mode:
authorAceLan Kao <acelan.kao@canonical.com>2011-10-04 04:25:44 -0400
committerMatthew Garrett <mjg@redhat.com>2011-10-24 10:52:37 -0400
commit2d8b90be4f1cadd9921312e2983459f568d29cd1 (patch)
tree6ae5de2592ebad0021f4e2ec0212019462bac9d9 /drivers/platform/x86
parentbd038080c70b70a5b31c48af774fada36eacc834 (diff)
dell-laptop: support Synaptics/Alps touchpad led
This patch supports Dell laptop with Synaptics and Alps touchpad chip that with LED to indicate the functionality of touchpad is disabled or enabled. The command for touchpad LED is 0x97, and the data 1 means turn on the touchpad LED, 2 means turn it off. BTW, I add dell_quirks to white list those machines that supports this behavior, so that the code won't affect those who don't have a touchpad LED machine. We can easily to turn it on/off by echo 1 > /sys/class/leds/dell-laptop::touchpad/brightness echo 0 > /sys/class/leds/dell-laptop::touchpad/brightness Signed-off-by: AceLan Kao <acelan.kao@canonical.com> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r--drivers/platform/x86/dell-laptop.c84
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..a43cfd906c6d 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
63struct quirk_entry {
64 u8 touchpad_led;
65};
66
67static struct quirk_entry *quirks;
68
69static struct quirk_entry quirk_dell_vostro_v130 = {
70 .touchpad_led = 1,
71};
72
73static int dmi_matched(const struct dmi_system_id *dmi)
74{
75 quirks = dmi->driver_data;
76 return 1;
77}
78
63static int da_command_address; 79static int da_command_address;
64static int da_command_code; 80static int da_command_code;
65static int da_num_tokens; 81static int da_num_tokens;
@@ -149,6 +165,27 @@ static struct dmi_system_id __devinitdata dell_blacklist[] = {
149 {} 165 {}
150}; 166};
151 167
168static 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
152static struct calling_interface_buffer *buffer; 189static struct calling_interface_buffer *buffer;
153static struct page *bufferpage; 190static struct page *bufferpage;
154static DEFINE_MUTEX(buffer_mutex); 191static 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
592static void touchpad_led_on()
593{
594 int command = 0x97;
595 char data = 1;
596 i8042_command(&data, command | 1 << 12);
597}
598
599static void touchpad_led_off()
600{
601 int command = 0x97;
602 char data = 2;
603 i8042_command(&data, command | 1 << 12);
604}
605
606static 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
615static struct led_classdev touchpad_led = {
616 .name = "dell-laptop::touchpad",
617 .brightness_set = touchpad_led_set,
618};
619
620static int __devinit touchpad_led_init(struct device *dev)
621{
622 return led_classdev_register(dev, &touchpad_led);
623}
624
625static void touchpad_led_exit(void)
626{
627 led_classdev_unregister(&touchpad_led);
628}
629
555static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str, 630static 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:
692static void __exit dell_exit(void) 774static 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);