aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorMaxim Mikityanskiy <maxtram95@gmail.com>2012-07-06 04:08:00 -0400
committerMatthew Garrett <mjg@redhat.com>2012-08-20 12:44:34 -0400
commit07a4a4fc83dd95bc7eb842cf9510ddcb45691a88 (patch)
tree397058b8ca8aa36411e61f30c1773aaa77bc743c /drivers/platform
parent296f9fe05d916e3d791dcd166aa41c1dadca4735 (diff)
ideapad: add Lenovo IdeaPad Z570 support (part 2)
The patch adds support for Lenovo IdeaPad Z570 laptop. It makes all special keys working, adds possibility to control fan like Windows does, controls Touchpad Disabled LED, toggles touchpad state via keyboard controller and corrects touchpad behavior on resume from suspend. It is new, modified version of patch. Now it does not depend on psmouse and does not need patching of input subsystem. Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com> This is part 2 for touchpad toggle Signed-off-by: Ike Panhc <ike.pan@canonical.com> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/Kconfig1
-rw-r--r--drivers/platform/x86/ideapad-laptop.c35
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 637074d89790..c86bae828c28 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -289,6 +289,7 @@ config IDEAPAD_LAPTOP
289 tristate "Lenovo IdeaPad Laptop Extras" 289 tristate "Lenovo IdeaPad Laptop Extras"
290 depends on ACPI 290 depends on ACPI
291 depends on RFKILL && INPUT 291 depends on RFKILL && INPUT
292 depends on SERIO_I8042
292 select INPUT_SPARSEKMAP 293 select INPUT_SPARSEKMAP
293 help 294 help
294 This is a driver for the rfkill switches on Lenovo IdeaPad netbooks. 295 This is a driver for the rfkill switches on Lenovo IdeaPad netbooks.
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 2396242e8418..7bc1b6c60e56 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -36,6 +36,7 @@
36#include <linux/fb.h> 36#include <linux/fb.h>
37#include <linux/debugfs.h> 37#include <linux/debugfs.h>
38#include <linux/seq_file.h> 38#include <linux/seq_file.h>
39#include <linux/i8042.h>
39 40
40#define IDEAPAD_RFKILL_DEV_NUM (3) 41#define IDEAPAD_RFKILL_DEV_NUM (3)
41 42
@@ -526,6 +527,8 @@ static const struct key_entry ideapad_keymap[] = {
526 { KE_KEY, 17, { KEY_PROG2 } }, 527 { KE_KEY, 17, { KEY_PROG2 } },
527 { KE_KEY, 64, { KEY_PROG3 } }, 528 { KE_KEY, 64, { KEY_PROG3 } },
528 { KE_KEY, 65, { KEY_PROG4 } }, 529 { KE_KEY, 65, { KEY_PROG4 } },
530 { KE_KEY, 66, { KEY_TOUCHPAD_OFF } },
531 { KE_KEY, 67, { KEY_TOUCHPAD_ON } },
529 { KE_END, 0 }, 532 { KE_END, 0 },
530}; 533};
531 534
@@ -718,6 +721,24 @@ static const struct acpi_device_id ideapad_device_ids[] = {
718}; 721};
719MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); 722MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
720 723
724static void ideapad_sync_touchpad_state(struct acpi_device *adevice)
725{
726 struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
727 unsigned long value;
728
729 /* Without reading from EC touchpad LED doesn't switch state */
730 if (!read_ec_data(adevice->handle, VPCCMD_R_TOUCHPAD, &value)) {
731 /* Some IdeaPads don't really turn off touchpad - they only
732 * switch the LED state. We (de)activate KBC AUX port to turn
733 * touchpad off and on. We send KEY_TOUCHPAD_OFF and
734 * KEY_TOUCHPAD_ON to not to get out of sync with LED */
735 unsigned char param;
736 i8042_command(&param, value ? I8042_CMD_AUX_ENABLE :
737 I8042_CMD_AUX_DISABLE);
738 ideapad_input_report(priv, value ? 67 : 66);
739 }
740}
741
721static int __devinit ideapad_acpi_add(struct acpi_device *adevice) 742static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
722{ 743{
723 int ret, i; 744 int ret, i;
@@ -754,6 +775,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
754 priv->rfk[i] = NULL; 775 priv->rfk[i] = NULL;
755 } 776 }
756 ideapad_sync_rfk_state(priv); 777 ideapad_sync_rfk_state(priv);
778 ideapad_sync_touchpad_state(adevice);
757 779
758 if (!acpi_video_backlight_support()) { 780 if (!acpi_video_backlight_support()) {
759 ret = ideapad_backlight_init(priv); 781 ret = ideapad_backlight_init(priv);
@@ -817,6 +839,9 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
817 case 6: 839 case 6:
818 ideapad_input_report(priv, vpc_bit); 840 ideapad_input_report(priv, vpc_bit);
819 break; 841 break;
842 case 5:
843 ideapad_sync_touchpad_state(adevice);
844 break;
820 case 4: 845 case 4:
821 ideapad_backlight_notify_brightness(priv); 846 ideapad_backlight_notify_brightness(priv);
822 break; 847 break;
@@ -836,6 +861,15 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
836 } 861 }
837} 862}
838 863
864static int ideapad_acpi_resume(struct device *device)
865{
866 ideapad_sync_rfk_state(ideapad_priv);
867 ideapad_sync_touchpad_state(to_acpi_device(device));
868 return 0;
869}
870
871static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume);
872
839static struct acpi_driver ideapad_acpi_driver = { 873static struct acpi_driver ideapad_acpi_driver = {
840 .name = "ideapad_acpi", 874 .name = "ideapad_acpi",
841 .class = "IdeaPad", 875 .class = "IdeaPad",
@@ -843,6 +877,7 @@ static struct acpi_driver ideapad_acpi_driver = {
843 .ops.add = ideapad_acpi_add, 877 .ops.add = ideapad_acpi_add,
844 .ops.remove = ideapad_acpi_remove, 878 .ops.remove = ideapad_acpi_remove,
845 .ops.notify = ideapad_acpi_notify, 879 .ops.notify = ideapad_acpi_notify,
880 .drv.pm = &ideapad_pm,
846 .owner = THIS_MODULE, 881 .owner = THIS_MODULE,
847}; 882};
848 883