aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86')
-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