Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 177497
b: refs/heads/master
c: 3c0eb51
h: refs/heads/master
i:
  177495: 1c6bb0e
v: v3
  • Loading branch information
Corentin Chary authored and Len Brown committed Dec 9, 2009
1 parent c47884d commit bb870d7
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: edf624522757adec8ceb83a4b97747eba645c454
refs/heads/master: 3c0eb510697dbbb53674c72544350624a04ab5b4
2 changes: 2 additions & 0 deletions trunk/drivers/platform/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ config EEEPC_LAPTOP
depends on HOTPLUG_PCI
select BACKLIGHT_CLASS_DEVICE
select HWMON
select LEDS_CLASS
select NEW_LEDS
---help---
This driver supports the Fn-Fx keys on Eee PC laptops.

Expand Down
67 changes: 67 additions & 0 deletions trunk/drivers/platform/x86/eeepc-laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <linux/rfkill.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
#include <linux/leds.h>

#define EEEPC_LAPTOP_VERSION "0.1"

Expand Down Expand Up @@ -506,6 +507,39 @@ static struct attribute_group platform_attribute_group = {
.attrs = platform_attributes
};

/*
* LEDs
*/
/*
* These functions actually update the LED's, and are called from a
* workqueue. By doing this as separate work rather than when the LED
* subsystem asks, we avoid messing with the Asus ACPI stuff during a
* potentially bad time, such as a timer interrupt.
*/
static int tpd_led_wk;

static void tpd_led_update(struct work_struct *ignored)
{
int value = tpd_led_wk;
set_acpi(CM_ASL_TPD, value);
}

static struct workqueue_struct *led_workqueue;
static DECLARE_WORK(tpd_led_work, tpd_led_update);

static void tpd_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
tpd_led_wk = (value > 0) ? 1 : 0;
queue_work(led_workqueue, &tpd_led_work);
}

static struct led_classdev tpd_led = {
.name = "eeepc::touchpad",
.brightness_set = tpd_led_set,
.max_brightness = 1
};

/*
* Hotkey functions
*/
Expand Down Expand Up @@ -1034,6 +1068,14 @@ static void eeepc_hwmon_exit(void)
eeepc_hwmon_device = NULL;
}

static void eeepc_led_exit(void)
{
if (led_workqueue)
destroy_workqueue(led_workqueue);
if (tpd_led.dev)
led_classdev_unregister(&tpd_led);
}

static int eeepc_new_rfkill(struct rfkill **rfkill,
const char *name, struct device *dev,
enum rfkill_type type, int cm)
Expand Down Expand Up @@ -1190,6 +1232,24 @@ static int eeepc_input_init(struct device *dev)
return 0;
}

static int eeepc_led_init(struct device *dev)
{
int rv;

if (get_acpi(CM_ASL_TPD) == -ENODEV)
return 0;

rv = led_classdev_register(dev, &tpd_led);
if (rv)
return rv;

led_workqueue = create_singlethread_workqueue("led_workqueue");
if (!led_workqueue)
return -ENOMEM;

return 0;
}

static int __devinit eeepc_hotk_add(struct acpi_device *device)
{
struct device *dev;
Expand Down Expand Up @@ -1248,13 +1308,19 @@ static int __devinit eeepc_hotk_add(struct acpi_device *device)
if (result)
goto fail_hwmon;

result = eeepc_led_init(dev);
if (result)
goto fail_led;

result = eeepc_rfkill_init(dev);
if (result)
goto fail_rfkill;

return 0;

fail_rfkill:
eeepc_led_exit();
fail_led:
eeepc_hwmon_exit();
fail_hwmon:
eeepc_input_exit();
Expand Down Expand Up @@ -1284,6 +1350,7 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
eeepc_rfkill_exit();
eeepc_input_exit();
eeepc_hwmon_exit();
eeepc_led_exit();
sysfs_remove_group(&platform_device->dev.kobj,
&platform_attribute_group);
platform_device_unregister(platform_device);
Expand Down

0 comments on commit bb870d7

Please sign in to comment.