The TP-LOCK-LED would bright while TP-disablement.
You can implement 97 command services routing of P/S2 device.
Code like below:
out 0x64,0x97 ;set 0x97 to command port;0x64 is command port
out 0x60,0x01 ;set 0x01 to data port then make LED bright;0x60 is data port
out 0x60,0x02 ;set 0x02 to data port then make LED dark

Before you send the action to the port, you must make sure the Input buffer
is empty (port 0x64).

Signed-off-by: AceLan Kao <[email protected]>
---
 drivers/platform/x86/dell-laptop.c |  105 +++++++++++++++++++++++++++++++++---
 1 files changed, 98 insertions(+), 7 deletions(-)

diff --git a/drivers/platform/x86/dell-laptop.c 
b/drivers/platform/x86/dell-laptop.c
index d3841de..65efa74 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -65,19 +65,14 @@ static int da_command_code;
 static int da_num_tokens;
 static struct calling_interface_token *da_tokens;
 
-static struct platform_driver platform_driver = {
-       .driver = {
-               .name = "dell-laptop",
-               .owner = THIS_MODULE,
-       }
-};
-
 static struct platform_device *platform_device;
 static struct backlight_device *dell_backlight_device;
 static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
 
+static struct delayed_work dell_touchpadled_update_work;
+static int touchpad_led_status;
 static const struct dmi_system_id __initdata dell_device_table[] = {
        {
                .ident = "Dell laptop",
@@ -572,6 +567,45 @@ static const struct backlight_ops dell_ops = {
        .update_status  = dell_send_intensity,
 };
 
+static void dell_touchpadled_on(void)
+{
+       while (inb(0x64) & 0x02)
+               udelay(100);
+       outb(0x97 , 0x64);
+
+       while (inb(0x64) & 0x02)
+               udelay(100);
+       outb(1, 0x60);
+
+       touchpad_led_status = 1;
+}
+
+static void dell_touchpadled_off(void)
+{
+       while (inb(0x64) & 0x02)
+               udelay(100);
+       outb(0x97 , 0x64);
+
+       while (inb(0x64) & 0x02)
+               udelay(100);
+       outb(2, 0x60);
+
+       touchpad_led_status = 0;
+}
+
+/*
+ * Called for each KEY_F22 key press event.
+ */
+static void dell_touchpadled_update(struct work_struct *work)
+{
+       touchpad_led_status = 1 - touchpad_led_status;
+
+       if (touchpad_led_status == 1)
+               dell_touchpadled_on();
+       else
+               dell_touchpadled_off();
+}
+
 static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,
                              struct serio *port)
 {
@@ -589,6 +623,10 @@ static bool dell_laptop_i8042_filter(unsigned char data, 
unsigned char str,
                        schedule_delayed_work(&dell_rfkill_work,
                                              round_jiffies_relative(HZ));
                        break;
+               case 0x1E:      /* F22 */
+                       schedule_delayed_work(&dell_touchpadled_update_work,
+                                             0);
+                       break;
                }
                extended = false;
        }
@@ -596,11 +634,64 @@ static bool dell_laptop_i8042_filter(unsigned char data, 
unsigned char str,
        return false;
 }
 
+static void restore_touchpad_led(void)
+{
+       /*
+        * We don't want to change the value of touchpad_led_status while
+        * resuming, so we modify the value here and it'll be changed back
+        * in the work queue
+        */
+       touchpad_led_status = 1 - touchpad_led_status;
+       /* The delay is needed to wait the chip wake up */
+       schedule_delayed_work(&dell_touchpadled_update_work, 1000);
+}
+
+static int __devinit dell_laptop_probe(struct platform_device *device)
+{
+       INIT_DELAYED_WORK(&dell_touchpadled_update_work,
+                         dell_touchpadled_update);
+       return 0;
+}
+
+static int dell_laptop_remove(struct platform_device *device)
+{
+       return 0;
+}
+
+static int dell_laptop_suspend(struct device *dev)
+{
+       return 0;
+}
+
+static int dell_laptop_resume(struct device *dev)
+{
+       restore_touchpad_led();
+       return 0;
+}
+
+static const struct dev_pm_ops dell_laptop_pm_ops = {
+       .suspend = dell_laptop_suspend,
+       .resume  = dell_laptop_resume,
+       .restore = dell_laptop_resume,
+};
+
+static struct platform_driver platform_driver = {
+       .driver = {
+               .name = "dell-laptop",
+               .owner = THIS_MODULE,
+               .pm    = &dell_laptop_pm_ops,
+       },
+       .probe  = dell_laptop_probe,
+       .remove = dell_laptop_remove,
+};
+
 static int __init dell_init(void)
 {
        int max_intensity = 0;
        int ret;
 
+       touchpad_led_status = 0;
+
        if (!dmi_check_system(dell_device_table))
                return -ENODEV;
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" 
in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to