aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/eeepc-laptop.c
diff options
context:
space:
mode:
authorCorentin Chary <corentincj@iksaif.net>2009-12-03 02:44:52 -0500
committerLen Brown <len.brown@intel.com>2009-12-09 15:54:30 -0500
commit3c0eb510697dbbb53674c72544350624a04ab5b4 (patch)
tree83f5c09da8363e5c10f662f54970e618c0427ffb /drivers/platform/x86/eeepc-laptop.c
parentedf624522757adec8ceb83a4b97747eba645c454 (diff)
eeepc-laptop: add touchpad led
This led can be found on Eeepc 1005 series. Signed-off-by: Corentin Chary <corentincj@iksaif.net> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/platform/x86/eeepc-laptop.c')
-rw-r--r--drivers/platform/x86/eeepc-laptop.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 2c65a3772968..91304342f8b6 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -34,6 +34,7 @@
34#include <linux/rfkill.h> 34#include <linux/rfkill.h>
35#include <linux/pci.h> 35#include <linux/pci.h>
36#include <linux/pci_hotplug.h> 36#include <linux/pci_hotplug.h>
37#include <linux/leds.h>
37 38
38#define EEEPC_LAPTOP_VERSION "0.1" 39#define EEEPC_LAPTOP_VERSION "0.1"
39 40
@@ -507,6 +508,39 @@ static struct attribute_group platform_attribute_group = {
507}; 508};
508 509
509/* 510/*
511 * LEDs
512 */
513/*
514 * These functions actually update the LED's, and are called from a
515 * workqueue. By doing this as separate work rather than when the LED
516 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
517 * potentially bad time, such as a timer interrupt.
518 */
519static int tpd_led_wk;
520
521static void tpd_led_update(struct work_struct *ignored)
522{
523 int value = tpd_led_wk;
524 set_acpi(CM_ASL_TPD, value);
525}
526
527static struct workqueue_struct *led_workqueue;
528static DECLARE_WORK(tpd_led_work, tpd_led_update);
529
530static void tpd_led_set(struct led_classdev *led_cdev,
531 enum led_brightness value)
532{
533 tpd_led_wk = (value > 0) ? 1 : 0;
534 queue_work(led_workqueue, &tpd_led_work);
535}
536
537static struct led_classdev tpd_led = {
538 .name = "eeepc::touchpad",
539 .brightness_set = tpd_led_set,
540 .max_brightness = 1
541};
542
543/*
510 * Hotkey functions 544 * Hotkey functions
511 */ 545 */
512static struct key_entry *eepc_get_entry_by_scancode(int code) 546static struct key_entry *eepc_get_entry_by_scancode(int code)
@@ -1034,6 +1068,14 @@ static void eeepc_hwmon_exit(void)
1034 eeepc_hwmon_device = NULL; 1068 eeepc_hwmon_device = NULL;
1035} 1069}
1036 1070
1071static void eeepc_led_exit(void)
1072{
1073 if (led_workqueue)
1074 destroy_workqueue(led_workqueue);
1075 if (tpd_led.dev)
1076 led_classdev_unregister(&tpd_led);
1077}
1078
1037static int eeepc_new_rfkill(struct rfkill **rfkill, 1079static int eeepc_new_rfkill(struct rfkill **rfkill,
1038 const char *name, struct device *dev, 1080 const char *name, struct device *dev,
1039 enum rfkill_type type, int cm) 1081 enum rfkill_type type, int cm)
@@ -1190,6 +1232,24 @@ static int eeepc_input_init(struct device *dev)
1190 return 0; 1232 return 0;
1191} 1233}
1192 1234
1235static int eeepc_led_init(struct device *dev)
1236{
1237 int rv;
1238
1239 if (get_acpi(CM_ASL_TPD) == -ENODEV)
1240 return 0;
1241
1242 rv = led_classdev_register(dev, &tpd_led);
1243 if (rv)
1244 return rv;
1245
1246 led_workqueue = create_singlethread_workqueue("led_workqueue");
1247 if (!led_workqueue)
1248 return -ENOMEM;
1249
1250 return 0;
1251}
1252
1193static int __devinit eeepc_hotk_add(struct acpi_device *device) 1253static int __devinit eeepc_hotk_add(struct acpi_device *device)
1194{ 1254{
1195 struct device *dev; 1255 struct device *dev;
@@ -1248,6 +1308,10 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device)
1248 if (result) 1308 if (result)
1249 goto fail_hwmon; 1309 goto fail_hwmon;
1250 1310
1311 result = eeepc_led_init(dev);
1312 if (result)
1313 goto fail_led;
1314
1251 result = eeepc_rfkill_init(dev); 1315 result = eeepc_rfkill_init(dev);
1252 if (result) 1316 if (result)
1253 goto fail_rfkill; 1317 goto fail_rfkill;
@@ -1255,6 +1319,8 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device)
1255 return 0; 1319 return 0;
1256 1320
1257fail_rfkill: 1321fail_rfkill:
1322 eeepc_led_exit();
1323fail_led:
1258 eeepc_hwmon_exit(); 1324 eeepc_hwmon_exit();
1259fail_hwmon: 1325fail_hwmon:
1260 eeepc_input_exit(); 1326 eeepc_input_exit();
@@ -1284,6 +1350,7 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
1284 eeepc_rfkill_exit(); 1350 eeepc_rfkill_exit();
1285 eeepc_input_exit(); 1351 eeepc_input_exit();
1286 eeepc_hwmon_exit(); 1352 eeepc_hwmon_exit();
1353 eeepc_led_exit();
1287 sysfs_remove_group(&platform_device->dev.kobj, 1354 sysfs_remove_group(&platform_device->dev.kobj,
1288 &platform_attribute_group); 1355 &platform_attribute_group);
1289 platform_device_unregister(platform_device); 1356 platform_device_unregister(platform_device);