Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 58484
b: refs/heads/master
c: 389679d
h: refs/heads/master
v: v3
  • Loading branch information
Eric Piel authored and Dmitry Torokhov committed Jul 10, 2007
1 parent 0e34e4b commit 3b1063a
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a4da16d3838669d7fb096ea5d1e4917e5ca4dc16
refs/heads/master: 389679d8faa38bb6d069d9e1805f15e3cb9a6d7f
5 changes: 4 additions & 1 deletion trunk/drivers/input/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,12 @@ config INPUT_COBALT_BTNS
config INPUT_WISTRON_BTNS
tristate "x86 Wistron laptop button interface"
depends on X86 && !X86_64
select NEW_LEDS
select LEDS_CLASS
help
Say Y here for support of Winstron laptop button interface, used on
laptops of various brands, including Acer and Fujitsu-Siemens.
laptops of various brands, including Acer and Fujitsu-Siemens. If
available, mail and wifi leds will be controlable via /sys/class/leds.

To compile this driver as a module, choose M here: the module will
be called wistron_btns.
Expand Down
88 changes: 87 additions & 1 deletion trunk/drivers/input/misc/wistron_btns.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/leds.h>

/*
* Number of attempts to read data from queue per poll;
Expand All @@ -48,11 +49,12 @@
/* BIOS subsystem IDs */
#define WIFI 0x35
#define BLUETOOTH 0x34
#define MAIL_LED 0x31

MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
MODULE_DESCRIPTION("Wistron laptop button driver");
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.2");
MODULE_VERSION("0.3");

static int force; /* = 0; */
module_param(force, bool, 0);
Expand Down Expand Up @@ -253,6 +255,7 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
static const struct key_entry *keymap; /* = NULL; Current key map */
static int have_wifi;
static int have_bluetooth;
static int have_leds;

static int __init dmi_matched(struct dmi_system_id *dmi)
{
Expand All @@ -265,6 +268,8 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
else if (key->type == KE_BLUETOOTH)
have_bluetooth = 1;
}
have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED);

return 1;
}

Expand Down Expand Up @@ -1030,6 +1035,83 @@ static void report_switch(unsigned code, int value)
input_sync(input_dev);
}


/* led management */
static void wistron_mail_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0);
}

/* same as setting up wifi card, but for laptops on which the led is managed */
static void wistron_wifi_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
bios_set_state(WIFI, (value != LED_OFF) ? 1 : 0);
}

static struct led_classdev wistron_mail_led = {
.name = "mail:green",
.brightness_set = wistron_mail_led_set,
};

static struct led_classdev wistron_wifi_led = {
.name = "wifi:red",
.brightness_set = wistron_wifi_led_set,
};

static void __devinit wistron_led_init(struct device *parent)
{
if (have_leds & FE_WIFI_LED) {
u16 wifi = bios_get_default_setting(WIFI);
if (wifi & 1) {
wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF;
if (led_classdev_register(parent, &wistron_wifi_led))
have_leds &= ~FE_WIFI_LED;
else
bios_set_state(WIFI, wistron_wifi_led.brightness);

} else
have_leds &= ~FE_WIFI_LED;
}

if (have_leds & FE_MAIL_LED) {
/* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */
wistron_mail_led.brightness = LED_OFF;
if (led_classdev_register(parent, &wistron_mail_led))
have_leds &= ~FE_MAIL_LED;
else
bios_set_state(MAIL_LED, wistron_mail_led.brightness);
}
}

static void __devexit wistron_led_remove(void)
{
if (have_leds & FE_MAIL_LED)
led_classdev_unregister(&wistron_mail_led);

if (have_leds & FE_WIFI_LED)
led_classdev_unregister(&wistron_wifi_led);
}

static inline void wistron_led_suspend(void)
{
if (have_leds & FE_MAIL_LED)
led_classdev_suspend(&wistron_mail_led);

if (have_leds & FE_WIFI_LED)
led_classdev_suspend(&wistron_wifi_led);
}

static inline void wistron_led_resume(void)
{
if (have_leds & FE_MAIL_LED)
led_classdev_resume(&wistron_mail_led);

if (have_leds & FE_WIFI_LED)
led_classdev_resume(&wistron_wifi_led);
}

/* Driver core */

static int wifi_enabled;
Expand Down Expand Up @@ -1135,6 +1217,7 @@ static int __devinit wistron_probe(struct platform_device *dev)
bios_set_state(BLUETOOTH, bluetooth_enabled);
}

wistron_led_init(&dev->dev);
poll_bios(1); /* Flush stale event queue and arm timer */

return 0;
Expand All @@ -1143,6 +1226,7 @@ static int __devinit wistron_probe(struct platform_device *dev)
static int __devexit wistron_remove(struct platform_device *dev)
{
del_timer_sync(&poll_timer);
wistron_led_remove();
input_unregister_device(input_dev);
bios_detach();

Expand All @@ -1160,6 +1244,7 @@ static int wistron_suspend(struct platform_device *dev, pm_message_t state)
if (have_bluetooth)
bios_set_state(BLUETOOTH, 0);

wistron_led_suspend();
return 0;
}

Expand All @@ -1171,6 +1256,7 @@ static int wistron_resume(struct platform_device *dev)
if (have_bluetooth)
bios_set_state(BLUETOOTH, bluetooth_enabled);

wistron_led_resume();
poll_bios(1);

return 0;
Expand Down

0 comments on commit 3b1063a

Please sign in to comment.