Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds
* 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds: leds: Add HP Jornada 6xx driver leds: Remove the now uneeded ixp4xx driver leds: Add power LED to the wrap driver leds: Fix led-gpio active_low default brightness leds: hw acceleration for Clevo mail LED driver leds: Add support for hardware accelerated LED flashing leds: Standardise LED naming scheme leds: Add clevo notebook LED driver
This commit is contained in:
Коммит
3d50337f62
|
@ -39,12 +39,33 @@ LED Device Naming
|
|||
|
||||
Is currently of the form:
|
||||
|
||||
"devicename:colour"
|
||||
"devicename:colour:function"
|
||||
|
||||
There have been calls for LED properties such as colour to be exported as
|
||||
individual led class attributes. As a solution which doesn't incur as much
|
||||
overhead, I suggest these become part of the device name. The naming scheme
|
||||
above leaves scope for further attributes should they be needed.
|
||||
above leaves scope for further attributes should they be needed. If sections
|
||||
of the name don't apply, just leave that section blank.
|
||||
|
||||
|
||||
Hardware accelerated blink of LEDs
|
||||
==================================
|
||||
|
||||
Some LEDs can be programmed to blink without any CPU interaction. To
|
||||
support this feature, a LED driver can optionally implement the
|
||||
blink_set() function (see <linux/leds.h>). If implemeted, triggers can
|
||||
attempt to use it before falling back to software timers. The blink_set()
|
||||
function should return 0 if the blink setting is supported, or -EINVAL
|
||||
otherwise, which means that LED blinking will be handled by software.
|
||||
|
||||
The blink_set() function should choose a user friendly blinking
|
||||
value if it is called with *delay_on==0 && *delay_off==0 parameters. In
|
||||
this case the driver should give back the chosen value through delay_on
|
||||
and delay_off parameters to the leds subsystem.
|
||||
|
||||
Any call to the brightness_set() callback function should cancel the
|
||||
previously programmed hardware blinking function so setting the brightness
|
||||
to 0 can also cancel the blinking of the LED.
|
||||
|
||||
|
||||
Known Issues
|
||||
|
@ -55,10 +76,6 @@ would cause nightmare dependency issues. I see this as a minor issue
|
|||
compared to the benefits the simple trigger functionality brings. The
|
||||
rest of the LED subsystem can be modular.
|
||||
|
||||
Some leds can be programmed to flash in hardware. As this isn't a generic
|
||||
LED device property, this should be exported as a device specific sysfs
|
||||
attribute rather than part of the class if this functionality is required.
|
||||
|
||||
|
||||
Future Development
|
||||
==================
|
||||
|
|
|
@ -71,11 +71,11 @@ static struct i2c_board_info __initdata dsmg600_i2c_board_info [] = {
|
|||
|
||||
static struct gpio_led dsmg600_led_pins[] = {
|
||||
{
|
||||
.name = "power",
|
||||
.name = "dsmg600:green:power",
|
||||
.gpio = DSMG600_LED_PWR_GPIO,
|
||||
},
|
||||
{
|
||||
.name = "wlan",
|
||||
.name = "dsmg600:green:wlan",
|
||||
.gpio = DSMG600_LED_WLAN_GPIO,
|
||||
.active_low = true,
|
||||
},
|
||||
|
|
|
@ -60,17 +60,17 @@ static struct i2c_board_info __initdata nas100d_i2c_board_info [] = {
|
|||
|
||||
static struct gpio_led nas100d_led_pins[] = {
|
||||
{
|
||||
.name = "wlan", /* green led */
|
||||
.name = "nas100d:green:wlan",
|
||||
.gpio = NAS100D_LED_WLAN_GPIO,
|
||||
.active_low = true,
|
||||
},
|
||||
{
|
||||
.name = "power", /* blue power led (off=flashing) */
|
||||
.name = "nas100d:blue:power", /* (off=flashing) */
|
||||
.gpio = NAS100D_LED_PWR_GPIO,
|
||||
.active_low = true,
|
||||
},
|
||||
{
|
||||
.name = "disk", /* yellow led */
|
||||
.name = "nas100d:yellow:disk",
|
||||
.gpio = NAS100D_LED_DISK_GPIO,
|
||||
.active_low = true,
|
||||
},
|
||||
|
|
|
@ -63,20 +63,20 @@ static struct i2c_board_info __initdata nslu2_i2c_board_info [] = {
|
|||
|
||||
static struct gpio_led nslu2_led_pins[] = {
|
||||
{
|
||||
.name = "ready", /* green led */
|
||||
.name = "nslu2:green:ready",
|
||||
.gpio = NSLU2_LED_GRN_GPIO,
|
||||
},
|
||||
{
|
||||
.name = "status", /* red led */
|
||||
.name = "nslu2:red:status",
|
||||
.gpio = NSLU2_LED_RED_GPIO,
|
||||
},
|
||||
{
|
||||
.name = "disk-1",
|
||||
.name = "nslu2:green:disk-1",
|
||||
.gpio = NSLU2_LED_DISK1_GPIO,
|
||||
.active_low = true,
|
||||
},
|
||||
{
|
||||
.name = "disk-2",
|
||||
.name = "nslu2:green:disk-2",
|
||||
.gpio = NSLU2_LED_DISK2_GPIO,
|
||||
.active_low = true,
|
||||
},
|
||||
|
|
|
@ -905,7 +905,7 @@ static ssize_t applesmc_key_at_index_store(struct device *dev,
|
|||
}
|
||||
|
||||
static struct led_classdev applesmc_backlight = {
|
||||
.name = "smc:kbd_backlight",
|
||||
.name = "smc::kbd_backlight",
|
||||
.default_trigger = "nand-disk",
|
||||
.brightness_set = applesmc_brightness_set,
|
||||
};
|
||||
|
|
|
@ -998,12 +998,12 @@ static void wistron_wifi_led_set(struct led_classdev *led_cdev,
|
|||
}
|
||||
|
||||
static struct led_classdev wistron_mail_led = {
|
||||
.name = "mail:green",
|
||||
.name = "wistron:green:mail",
|
||||
.brightness_set = wistron_mail_led_set,
|
||||
};
|
||||
|
||||
static struct led_classdev wistron_wifi_led = {
|
||||
.name = "wifi:red",
|
||||
.name = "wistron:red:wifi",
|
||||
.brightness_set = wistron_wifi_led_set,
|
||||
};
|
||||
|
||||
|
|
|
@ -39,15 +39,6 @@ config LEDS_SPITZ
|
|||
This option enables support for the LEDs on Sharp Zaurus
|
||||
SL-Cxx00 series (C1000, C3000, C3100).
|
||||
|
||||
config LEDS_IXP4XX
|
||||
tristate "LED Support for GPIO connected LEDs on IXP4XX processors"
|
||||
depends on LEDS_CLASS && ARCH_IXP4XX
|
||||
help
|
||||
This option enables support for the LEDs connected to GPIO
|
||||
outputs of the Intel IXP4XX processors. To be useful the
|
||||
particular board must have LEDs and they must be connected
|
||||
to the GPIO lines. If unsure, say Y.
|
||||
|
||||
config LEDS_TOSA
|
||||
tristate "LED Support for the Sharp SL-6000 series"
|
||||
depends on LEDS_CLASS && PXA_SHARPSL
|
||||
|
@ -100,6 +91,13 @@ config LEDS_COBALT_RAQ
|
|||
help
|
||||
This option enables support for the Cobalt Raq series LEDs.
|
||||
|
||||
config LEDS_HP6XX
|
||||
tristate "LED Support for the HP Jornada 6xx"
|
||||
depends on LEDS_CLASS && SH_HP6XX
|
||||
help
|
||||
This option enables led support for the handheld
|
||||
HP Jornada 620/660/680/690.
|
||||
|
||||
config LEDS_GPIO
|
||||
tristate "LED Support for GPIO connected LEDs"
|
||||
depends on LEDS_CLASS && GENERIC_GPIO
|
||||
|
@ -114,6 +112,32 @@ config LEDS_CM_X270
|
|||
help
|
||||
This option enables support for the CM-X270 LEDs.
|
||||
|
||||
config LEDS_CLEVO_MAIL
|
||||
tristate "Mail LED on Clevo notebook (EXPERIMENTAL)"
|
||||
depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI && EXPERIMENTAL
|
||||
help
|
||||
This driver makes the mail LED accessible from userspace
|
||||
programs through the leds subsystem. This LED have three
|
||||
known mode: off, blink at 0.5Hz and blink at 1Hz.
|
||||
|
||||
The driver supports two kinds of interface: using ledtrig-timer
|
||||
or through /sys/class/leds/clevo::mail/brightness. As this LED
|
||||
cannot change it's brightness it blinks instead. The brightness
|
||||
value 0 means off, 1..127 means blink at 0.5Hz and 128..255 means
|
||||
blink at 1Hz.
|
||||
|
||||
This module can drive the mail LED for the following notebooks:
|
||||
|
||||
Clevo D410J
|
||||
Clevo D410V
|
||||
Clevo D400V/D470V (not tested, but might work)
|
||||
Clevo M540N
|
||||
Clevo M5x0N (not tested, but might work)
|
||||
Positivo Mobile (Clevo M5x0V)
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called leds-clevo-mail.
|
||||
|
||||
comment "LED Triggers"
|
||||
|
||||
config LEDS_TRIGGERS
|
||||
|
@ -128,7 +152,11 @@ config LEDS_TRIGGER_TIMER
|
|||
depends on LEDS_TRIGGERS
|
||||
help
|
||||
This allows LEDs to be controlled by a programmable timer
|
||||
via sysfs. If unsure, say Y.
|
||||
via sysfs. Some LED hardware can be programmed to start
|
||||
blinking the LED without any further software interaction.
|
||||
For more details read Documentation/leds-class.txt.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config LEDS_TRIGGER_IDE_DISK
|
||||
bool "LED IDE Disk Trigger"
|
||||
|
|
|
@ -8,7 +8,6 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
|
|||
obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o
|
||||
obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
|
||||
obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o
|
||||
obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o
|
||||
obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o
|
||||
obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
|
||||
obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
|
||||
|
@ -19,6 +18,8 @@ obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o
|
|||
obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
|
||||
obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
|
||||
obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o
|
||||
obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
|
||||
obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
|
||||
|
||||
# LED Triggers
|
||||
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
|
||||
|
|
|
@ -37,42 +37,42 @@ static void ams_delta_led_set(struct led_classdev *led_cdev,
|
|||
static struct ams_delta_led ams_delta_leds[] = {
|
||||
{
|
||||
.cdev = {
|
||||
.name = "ams-delta:camera",
|
||||
.name = "ams-delta::camera",
|
||||
.brightness_set = ams_delta_led_set,
|
||||
},
|
||||
.bitmask = AMS_DELTA_LATCH1_LED_CAMERA,
|
||||
},
|
||||
{
|
||||
.cdev = {
|
||||
.name = "ams-delta:advert",
|
||||
.name = "ams-delta::advert",
|
||||
.brightness_set = ams_delta_led_set,
|
||||
},
|
||||
.bitmask = AMS_DELTA_LATCH1_LED_ADVERT,
|
||||
},
|
||||
{
|
||||
.cdev = {
|
||||
.name = "ams-delta:email",
|
||||
.name = "ams-delta::email",
|
||||
.brightness_set = ams_delta_led_set,
|
||||
},
|
||||
.bitmask = AMS_DELTA_LATCH1_LED_EMAIL,
|
||||
},
|
||||
{
|
||||
.cdev = {
|
||||
.name = "ams-delta:handsfree",
|
||||
.name = "ams-delta::handsfree",
|
||||
.brightness_set = ams_delta_led_set,
|
||||
},
|
||||
.bitmask = AMS_DELTA_LATCH1_LED_HANDSFREE,
|
||||
},
|
||||
{
|
||||
.cdev = {
|
||||
.name = "ams-delta:voicemail",
|
||||
.name = "ams-delta::voicemail",
|
||||
.brightness_set = ams_delta_led_set,
|
||||
},
|
||||
.bitmask = AMS_DELTA_LATCH1_LED_VOICEMAIL,
|
||||
},
|
||||
{
|
||||
.cdev = {
|
||||
.name = "ams-delta:voice",
|
||||
.name = "ams-delta::voice",
|
||||
.brightness_set = ams_delta_led_set,
|
||||
},
|
||||
.bitmask = AMS_DELTA_LATCH1_LED_VOICE,
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
#include <linux/i8042.h>
|
||||
|
||||
#define CLEVO_MAIL_LED_OFF 0x0084
|
||||
#define CLEVO_MAIL_LED_BLINK_1HZ 0x008A
|
||||
#define CLEVO_MAIL_LED_BLINK_0_5HZ 0x0083
|
||||
|
||||
MODULE_AUTHOR("Márton Németh <nm127@freemail.hu>");
|
||||
MODULE_DESCRIPTION("Clevo mail LED driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static unsigned int __initdata nodetect;
|
||||
module_param_named(nodetect, nodetect, bool, 0);
|
||||
MODULE_PARM_DESC(nodetect, "Skip DMI hardware detection");
|
||||
|
||||
static struct platform_device *pdev;
|
||||
|
||||
static int __init clevo_mail_led_dmi_callback(const struct dmi_system_id *id)
|
||||
{
|
||||
printk(KERN_INFO KBUILD_MODNAME ": '%s' found\n", id->ident);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* struct mail_led_whitelist - List of known good models
|
||||
*
|
||||
* Contains the known good models this driver is compatible with.
|
||||
* When adding a new model try to be as strict as possible. This
|
||||
* makes it possible to keep the false positives (the model is
|
||||
* detected as working, but in reality it is not) as low as
|
||||
* possible.
|
||||
*/
|
||||
static struct dmi_system_id __initdata mail_led_whitelist[] = {
|
||||
{
|
||||
.callback = clevo_mail_led_dmi_callback,
|
||||
.ident = "Clevo D410J",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "VIA"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "K8N800"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "VT8204B")
|
||||
}
|
||||
},
|
||||
{
|
||||
.callback = clevo_mail_led_dmi_callback,
|
||||
.ident = "Clevo M5x0N",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "M5x0N")
|
||||
}
|
||||
},
|
||||
{
|
||||
.callback = clevo_mail_led_dmi_callback,
|
||||
.ident = "Positivo Mobile",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "CLEVO Co. "),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "M5X0V "),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Positivo Mobile"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "VT6198")
|
||||
}
|
||||
},
|
||||
{
|
||||
.callback = clevo_mail_led_dmi_callback,
|
||||
.ident = "Clevo D410V",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Clevo, Co."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "D400V/D470V"),
|
||||
DMI_MATCH(DMI_BOARD_VERSION, "SS78B"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Rev. A1")
|
||||
}
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static void clevo_mail_led_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value == LED_OFF)
|
||||
i8042_command(NULL, CLEVO_MAIL_LED_OFF);
|
||||
else if (value <= LED_HALF)
|
||||
i8042_command(NULL, CLEVO_MAIL_LED_BLINK_0_5HZ);
|
||||
else
|
||||
i8042_command(NULL, CLEVO_MAIL_LED_BLINK_1HZ);
|
||||
|
||||
}
|
||||
|
||||
static int clevo_mail_led_blink(struct led_classdev *led_cdev,
|
||||
unsigned long* delay_on,
|
||||
unsigned long* delay_off)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
|
||||
if (*delay_on == 0 /* ms */ && *delay_off == 0 /* ms */) {
|
||||
/* Special case: the leds subsystem requested us to
|
||||
* chose one user friendly blinking of the LED, and
|
||||
* start it. Let's blink the led slowly (0.5Hz).
|
||||
*/
|
||||
*delay_on = 1000; /* ms */
|
||||
*delay_off = 1000; /* ms */
|
||||
i8042_command(NULL, CLEVO_MAIL_LED_BLINK_0_5HZ);
|
||||
status = 0;
|
||||
|
||||
} else if (*delay_on == 500 /* ms */ && *delay_off == 500 /* ms */) {
|
||||
/* blink the led with 1Hz */
|
||||
i8042_command(NULL, CLEVO_MAIL_LED_BLINK_1HZ);
|
||||
status = 0;
|
||||
|
||||
} else if (*delay_on == 1000 /* ms */ && *delay_off == 1000 /* ms */) {
|
||||
/* blink the led with 0.5Hz */
|
||||
i8042_command(NULL, CLEVO_MAIL_LED_BLINK_0_5HZ);
|
||||
status = 0;
|
||||
|
||||
} else {
|
||||
printk(KERN_DEBUG KBUILD_MODNAME
|
||||
": clevo_mail_led_blink(..., %lu, %lu),"
|
||||
" returning -EINVAL (unsupported)\n",
|
||||
*delay_on, *delay_off);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static struct led_classdev clevo_mail_led = {
|
||||
.name = "clevo::mail",
|
||||
.brightness_set = clevo_mail_led_set,
|
||||
.blink_set = clevo_mail_led_blink,
|
||||
};
|
||||
|
||||
static int __init clevo_mail_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
return led_classdev_register(&pdev->dev, &clevo_mail_led);
|
||||
}
|
||||
|
||||
static int clevo_mail_led_remove(struct platform_device *pdev)
|
||||
{
|
||||
led_classdev_unregister(&clevo_mail_led);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int clevo_mail_led_suspend(struct platform_device *dev,
|
||||
pm_message_t state)
|
||||
{
|
||||
led_classdev_suspend(&clevo_mail_led);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clevo_mail_led_resume(struct platform_device *dev)
|
||||
{
|
||||
led_classdev_resume(&clevo_mail_led);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define clevo_mail_led_suspend NULL
|
||||
#define clevo_mail_led_resume NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver clevo_mail_led_driver = {
|
||||
.probe = clevo_mail_led_probe,
|
||||
.remove = clevo_mail_led_remove,
|
||||
.suspend = clevo_mail_led_suspend,
|
||||
.resume = clevo_mail_led_resume,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init clevo_mail_led_init(void)
|
||||
{
|
||||
int error = 0;
|
||||
int count = 0;
|
||||
|
||||
/* Check with the help of DMI if we are running on supported hardware */
|
||||
if (!nodetect) {
|
||||
count = dmi_check_system(mail_led_whitelist);
|
||||
} else {
|
||||
count = 1;
|
||||
printk(KERN_ERR KBUILD_MODNAME ": Skipping DMI detection. "
|
||||
"If the driver works on your hardware please "
|
||||
"report model and the output of dmidecode in tracker "
|
||||
"at http://sourceforge.net/projects/clevo-mailled/\n");
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return -ENODEV;
|
||||
|
||||
pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0);
|
||||
if (!IS_ERR(pdev)) {
|
||||
error = platform_driver_probe(&clevo_mail_led_driver,
|
||||
clevo_mail_led_probe);
|
||||
if (error) {
|
||||
printk(KERN_ERR KBUILD_MODNAME
|
||||
": Can't probe platform driver\n");
|
||||
platform_device_unregister(pdev);
|
||||
}
|
||||
} else
|
||||
error = PTR_ERR(pdev);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static void __exit clevo_mail_led_exit(void)
|
||||
{
|
||||
platform_device_unregister(pdev);
|
||||
platform_driver_unregister(&clevo_mail_led_driver);
|
||||
|
||||
clevo_mail_led_set(NULL, LED_OFF);
|
||||
}
|
||||
|
||||
module_init(clevo_mail_led_init);
|
||||
module_exit(clevo_mail_led_exit);
|
|
@ -38,13 +38,13 @@ static void corgiled_green_set(struct led_classdev *led_cdev, enum led_brightnes
|
|||
}
|
||||
|
||||
static struct led_classdev corgi_amber_led = {
|
||||
.name = "corgi:amber",
|
||||
.name = "corgi:amber:charge",
|
||||
.default_trigger = "sharpsl-charge",
|
||||
.brightness_set = corgiled_amber_set,
|
||||
};
|
||||
|
||||
static struct led_classdev corgi_green_led = {
|
||||
.name = "corgi:green",
|
||||
.name = "corgi:green:mail",
|
||||
.default_trigger = "nand-disk",
|
||||
.brightness_set = corgiled_green_set,
|
||||
};
|
||||
|
|
|
@ -85,7 +85,7 @@ static int gpio_led_probe(struct platform_device *pdev)
|
|||
led_dat->can_sleep = gpio_cansleep(cur_led->gpio);
|
||||
led_dat->active_low = cur_led->active_low;
|
||||
led_dat->cdev.brightness_set = gpio_led_set;
|
||||
led_dat->cdev.brightness = cur_led->active_low ? LED_FULL : LED_OFF;
|
||||
led_dat->cdev.brightness = LED_OFF;
|
||||
|
||||
ret = gpio_request(led_dat->gpio, led_dat->cdev.name);
|
||||
if (ret < 0)
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* LED Triggers Core
|
||||
* For the HP Jornada 620/660/680/690 handhelds
|
||||
*
|
||||
* Copyright 2008 Kristoffer Ericson <kristoffer.ericson@gmail.com>
|
||||
* this driver is based on leds-spitz.c by Richard Purdie.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/leds.h>
|
||||
#include <asm/hd64461.h>
|
||||
#include <asm/hp6xx.h>
|
||||
|
||||
static void hp6xxled_green_set(struct led_classdev *led_cdev, enum led_brightness value)
|
||||
{
|
||||
u8 v8;
|
||||
|
||||
v8 = inb(PKDR);
|
||||
if (value)
|
||||
outb(v8 & (~PKDR_LED_GREEN), PKDR);
|
||||
else
|
||||
outb(v8 | PKDR_LED_GREEN, PKDR);
|
||||
}
|
||||
|
||||
static void hp6xxled_red_set(struct led_classdev *led_cdev, enum led_brightness value)
|
||||
{
|
||||
u16 v16;
|
||||
|
||||
v16 = inw(HD64461_GPBDR);
|
||||
if (value)
|
||||
outw(v16 & (~HD64461_GPBDR_LED_RED), HD64461_GPBDR);
|
||||
else
|
||||
outw(v16 | HD64461_GPBDR_LED_RED, HD64461_GPBDR);
|
||||
}
|
||||
|
||||
static struct led_classdev hp6xx_red_led = {
|
||||
.name = "hp6xx:red",
|
||||
.default_trigger = "hp6xx-charge",
|
||||
.brightness_set = hp6xxled_red_set,
|
||||
};
|
||||
|
||||
static struct led_classdev hp6xx_green_led = {
|
||||
.name = "hp6xx:green",
|
||||
.default_trigger = "ide-disk",
|
||||
.brightness_set = hp6xxled_green_set,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int hp6xxled_suspend(struct platform_device *dev, pm_message_t state)
|
||||
{
|
||||
led_classdev_suspend(&hp6xx_red_led);
|
||||
led_classdev_suspend(&hp6xx_green_led);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hp6xxled_resume(struct platform_device *dev)
|
||||
{
|
||||
led_classdev_resume(&hp6xx_red_led);
|
||||
led_classdev_resume(&hp6xx_green_led);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int hp6xxled_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &hp6xx_red_led);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &hp6xx_green_led);
|
||||
if (ret < 0)
|
||||
led_classdev_unregister(&hp6xx_red_led);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hp6xxled_remove(struct platform_device *pdev)
|
||||
{
|
||||
led_classdev_unregister(&hp6xx_red_led);
|
||||
led_classdev_unregister(&hp6xx_green_led);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver hp6xxled_driver = {
|
||||
.probe = hp6xxled_probe,
|
||||
.remove = hp6xxled_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = hp6xxled_suspend,
|
||||
.resume = hp6xxled_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = "hp6xx-led",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init hp6xxled_init(void)
|
||||
{
|
||||
return platform_driver_register(&hp6xxled_driver);
|
||||
}
|
||||
|
||||
static void __exit hp6xxled_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&hp6xxled_driver);
|
||||
}
|
||||
|
||||
module_init(hp6xxled_init);
|
||||
module_exit(hp6xxled_exit);
|
||||
|
||||
MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
|
||||
MODULE_DESCRIPTION("HP Jornada 6xx LED driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -1,214 +0,0 @@
|
|||
/*
|
||||
* IXP4XX GPIO driver LED driver
|
||||
*
|
||||
* Author: John Bowler <jbowler@acm.org>
|
||||
*
|
||||
* Copyright (c) 2006 John Bowler
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any
|
||||
* person obtaining a copy of this software and associated
|
||||
* documentation files (the "Software"), to deal in the
|
||||
* Software without restriction, including without
|
||||
* limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice
|
||||
* shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
* ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/leds.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
|
||||
extern spinlock_t gpio_lock;
|
||||
|
||||
/* Up to 16 gpio lines are possible. */
|
||||
#define GPIO_MAX 16
|
||||
static struct ixp4xxgpioled_device {
|
||||
struct led_classdev ancestor;
|
||||
int flags;
|
||||
} ixp4xxgpioled_devices[GPIO_MAX];
|
||||
|
||||
void ixp4xxgpioled_brightness_set(struct led_classdev *pled,
|
||||
enum led_brightness value)
|
||||
{
|
||||
const struct ixp4xxgpioled_device *const ixp4xx_dev =
|
||||
container_of(pled, struct ixp4xxgpioled_device, ancestor);
|
||||
const u32 gpio_pin = ixp4xx_dev - ixp4xxgpioled_devices;
|
||||
|
||||
if (gpio_pin < GPIO_MAX && ixp4xx_dev->ancestor.name != 0) {
|
||||
/* Set or clear the 'gpio_pin' bit according to the style
|
||||
* and the required setting (value > 0 == on)
|
||||
*/
|
||||
const int gpio_value =
|
||||
(value > 0) == (ixp4xx_dev->flags != IXP4XX_GPIO_LOW) ?
|
||||
IXP4XX_GPIO_HIGH : IXP4XX_GPIO_LOW;
|
||||
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&gpio_lock, flags);
|
||||
gpio_line_set(gpio_pin, gpio_value);
|
||||
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* LEDs are described in resources, the following iterates over the valid
|
||||
* LED resources.
|
||||
*/
|
||||
#define for_all_leds(i, pdev) \
|
||||
for (i=0; i<pdev->num_resources; ++i) \
|
||||
if (pdev->resource[i].start < GPIO_MAX && \
|
||||
pdev->resource[i].name != 0)
|
||||
|
||||
/* The following applies 'operation' to each LED from the given platform,
|
||||
* the function always returns 0 to allow tail call elimination.
|
||||
*/
|
||||
static int apply_to_all_leds(struct platform_device *pdev,
|
||||
void (*operation)(struct led_classdev *pled))
|
||||
{
|
||||
int i;
|
||||
|
||||
for_all_leds(i, pdev)
|
||||
operation(&ixp4xxgpioled_devices[pdev->resource[i].start].ancestor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ixp4xxgpioled_suspend(struct platform_device *pdev,
|
||||
pm_message_t state)
|
||||
{
|
||||
return apply_to_all_leds(pdev, led_classdev_suspend);
|
||||
}
|
||||
|
||||
static int ixp4xxgpioled_resume(struct platform_device *pdev)
|
||||
{
|
||||
return apply_to_all_leds(pdev, led_classdev_resume);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ixp4xxgpioled_remove_one_led(struct led_classdev *pled)
|
||||
{
|
||||
led_classdev_unregister(pled);
|
||||
pled->name = 0;
|
||||
}
|
||||
|
||||
static int ixp4xxgpioled_remove(struct platform_device *pdev)
|
||||
{
|
||||
return apply_to_all_leds(pdev, ixp4xxgpioled_remove_one_led);
|
||||
}
|
||||
|
||||
static int ixp4xxgpioled_probe(struct platform_device *pdev)
|
||||
{
|
||||
/* The board level has to tell the driver where the
|
||||
* LEDs are connected - there is no way to find out
|
||||
* electrically. It must also say whether the GPIO
|
||||
* lines are active high or active low.
|
||||
*
|
||||
* To do this read the num_resources (the number of
|
||||
* LEDs) and the struct resource (the data for each
|
||||
* LED). The name comes from the resource, and it
|
||||
* isn't copied.
|
||||
*/
|
||||
int i;
|
||||
|
||||
for_all_leds(i, pdev) {
|
||||
const u8 gpio_pin = pdev->resource[i].start;
|
||||
int rc;
|
||||
|
||||
if (ixp4xxgpioled_devices[gpio_pin].ancestor.name == 0) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&gpio_lock, flags);
|
||||
gpio_line_config(gpio_pin, IXP4XX_GPIO_OUT);
|
||||
/* The config can, apparently, reset the state,
|
||||
* I suspect the gpio line may be an input and
|
||||
* the config may cause the line to be latched,
|
||||
* so the setting depends on how the LED is
|
||||
* connected to the line (which affects how it
|
||||
* floats if not driven).
|
||||
*/
|
||||
gpio_line_set(gpio_pin, IXP4XX_GPIO_HIGH);
|
||||
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||
|
||||
ixp4xxgpioled_devices[gpio_pin].flags =
|
||||
pdev->resource[i].flags & IORESOURCE_BITS;
|
||||
|
||||
ixp4xxgpioled_devices[gpio_pin].ancestor.name =
|
||||
pdev->resource[i].name;
|
||||
|
||||
/* This is how a board manufacturer makes the LED
|
||||
* come on on reset - the GPIO line will be high, so
|
||||
* make the LED light when the line is low...
|
||||
*/
|
||||
if (ixp4xxgpioled_devices[gpio_pin].flags != IXP4XX_GPIO_LOW)
|
||||
ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 100;
|
||||
else
|
||||
ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 0;
|
||||
|
||||
ixp4xxgpioled_devices[gpio_pin].ancestor.flags = 0;
|
||||
|
||||
ixp4xxgpioled_devices[gpio_pin].ancestor.brightness_set =
|
||||
ixp4xxgpioled_brightness_set;
|
||||
|
||||
ixp4xxgpioled_devices[gpio_pin].ancestor.default_trigger = 0;
|
||||
}
|
||||
|
||||
rc = led_classdev_register(&pdev->dev,
|
||||
&ixp4xxgpioled_devices[gpio_pin].ancestor);
|
||||
if (rc < 0) {
|
||||
ixp4xxgpioled_devices[gpio_pin].ancestor.name = 0;
|
||||
ixp4xxgpioled_remove(pdev);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ixp4xxgpioled_driver = {
|
||||
.probe = ixp4xxgpioled_probe,
|
||||
.remove = ixp4xxgpioled_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = ixp4xxgpioled_suspend,
|
||||
.resume = ixp4xxgpioled_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.name = "IXP4XX-GPIO-LED",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ixp4xxgpioled_init(void)
|
||||
{
|
||||
return platform_driver_register(&ixp4xxgpioled_driver);
|
||||
}
|
||||
|
||||
static void __exit ixp4xxgpioled_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ixp4xxgpioled_driver);
|
||||
}
|
||||
|
||||
module_init(ixp4xxgpioled_init);
|
||||
module_exit(ixp4xxgpioled_exit);
|
||||
|
||||
MODULE_AUTHOR("John Bowler <jbowler@acm.org>");
|
||||
MODULE_DESCRIPTION("IXP4XX GPIO LED driver");
|
||||
MODULE_LICENSE("Dual MIT/GPL");
|
|
@ -43,13 +43,13 @@ static void locomoled_brightness_set1(struct led_classdev *led_cdev,
|
|||
}
|
||||
|
||||
static struct led_classdev locomo_led0 = {
|
||||
.name = "locomo:amber",
|
||||
.name = "locomo:amber:charge",
|
||||
.default_trigger = "sharpsl-charge",
|
||||
.brightness_set = locomoled_brightness_set0,
|
||||
};
|
||||
|
||||
static struct led_classdev locomo_led1 = {
|
||||
.name = "locomo:green",
|
||||
.name = "locomo:green:mail",
|
||||
.default_trigger = "nand-disk",
|
||||
.brightness_set = locomoled_brightness_set1,
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ static void net48xx_error_led_set(struct led_classdev *led_cdev,
|
|||
}
|
||||
|
||||
static struct led_classdev net48xx_error_led = {
|
||||
.name = "net48xx:error",
|
||||
.name = "net48xx::error",
|
||||
.brightness_set = net48xx_error_led_set,
|
||||
};
|
||||
|
||||
|
|
|
@ -38,13 +38,13 @@ static void spitzled_green_set(struct led_classdev *led_cdev, enum led_brightnes
|
|||
}
|
||||
|
||||
static struct led_classdev spitz_amber_led = {
|
||||
.name = "spitz:amber",
|
||||
.name = "spitz:amber:charge",
|
||||
.default_trigger = "sharpsl-charge",
|
||||
.brightness_set = spitzled_amber_set,
|
||||
};
|
||||
|
||||
static struct led_classdev spitz_green_led = {
|
||||
.name = "spitz:green",
|
||||
.name = "spitz:green:hddactivity",
|
||||
.default_trigger = "ide-disk",
|
||||
.brightness_set = spitzled_green_set,
|
||||
};
|
||||
|
@ -72,8 +72,10 @@ static int spitzled_probe(struct platform_device *pdev)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (machine_is_akita())
|
||||
if (machine_is_akita()) {
|
||||
spitz_green_led.name = "spitz:green:mail";
|
||||
spitz_green_led.default_trigger = "nand-disk";
|
||||
}
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &spitz_amber_led);
|
||||
if (ret < 0)
|
||||
|
|
|
@ -45,13 +45,13 @@ static void tosaled_green_set(struct led_classdev *led_cdev,
|
|||
}
|
||||
|
||||
static struct led_classdev tosa_amber_led = {
|
||||
.name = "tosa:amber",
|
||||
.name = "tosa:amber:charge",
|
||||
.default_trigger = "sharpsl-charge",
|
||||
.brightness_set = tosaled_amber_set,
|
||||
};
|
||||
|
||||
static struct led_classdev tosa_green_led = {
|
||||
.name = "tosa:green",
|
||||
.name = "tosa:green:mail",
|
||||
.default_trigger = "nand-disk",
|
||||
.brightness_set = tosaled_green_set,
|
||||
};
|
||||
|
|
|
@ -19,11 +19,21 @@
|
|||
#include <linux/scx200_gpio.h>
|
||||
|
||||
#define DRVNAME "wrap-led"
|
||||
#define WRAP_POWER_LED_GPIO 2
|
||||
#define WRAP_ERROR_LED_GPIO 3
|
||||
#define WRAP_EXTRA_LED_GPIO 18
|
||||
#define WRAP_EXTRA_LED_GPIO 18
|
||||
|
||||
static struct platform_device *pdev;
|
||||
|
||||
static void wrap_power_led_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
if (value)
|
||||
scx200_gpio_set_low(WRAP_POWER_LED_GPIO);
|
||||
else
|
||||
scx200_gpio_set_high(WRAP_POWER_LED_GPIO);
|
||||
}
|
||||
|
||||
static void wrap_error_led_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
|
@ -42,13 +52,18 @@ static void wrap_extra_led_set(struct led_classdev *led_cdev,
|
|||
scx200_gpio_set_high(WRAP_EXTRA_LED_GPIO);
|
||||
}
|
||||
|
||||
static struct led_classdev wrap_power_led = {
|
||||
.name = "wrap::power",
|
||||
.brightness_set = wrap_power_led_set,
|
||||
};
|
||||
|
||||
static struct led_classdev wrap_error_led = {
|
||||
.name = "wrap:error",
|
||||
.name = "wrap::error",
|
||||
.brightness_set = wrap_error_led_set,
|
||||
};
|
||||
|
||||
static struct led_classdev wrap_extra_led = {
|
||||
.name = "wrap:extra",
|
||||
.name = "wrap::extra",
|
||||
.brightness_set = wrap_extra_led_set,
|
||||
};
|
||||
|
||||
|
@ -56,6 +71,7 @@ static struct led_classdev wrap_extra_led = {
|
|||
static int wrap_led_suspend(struct platform_device *dev,
|
||||
pm_message_t state)
|
||||
{
|
||||
led_classdev_suspend(&wrap_power_led);
|
||||
led_classdev_suspend(&wrap_error_led);
|
||||
led_classdev_suspend(&wrap_extra_led);
|
||||
return 0;
|
||||
|
@ -63,6 +79,7 @@ static int wrap_led_suspend(struct platform_device *dev,
|
|||
|
||||
static int wrap_led_resume(struct platform_device *dev)
|
||||
{
|
||||
led_classdev_resume(&wrap_power_led);
|
||||
led_classdev_resume(&wrap_error_led);
|
||||
led_classdev_resume(&wrap_extra_led);
|
||||
return 0;
|
||||
|
@ -76,17 +93,31 @@ static int wrap_led_probe(struct platform_device *pdev)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &wrap_power_led);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &wrap_error_led);
|
||||
if (ret == 0) {
|
||||
ret = led_classdev_register(&pdev->dev, &wrap_extra_led);
|
||||
if (ret < 0)
|
||||
led_classdev_unregister(&wrap_error_led);
|
||||
}
|
||||
if (ret < 0)
|
||||
goto err1;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &wrap_extra_led);
|
||||
if (ret < 0)
|
||||
goto err2;
|
||||
|
||||
return ret;
|
||||
|
||||
err2:
|
||||
led_classdev_unregister(&wrap_error_led);
|
||||
err1:
|
||||
led_classdev_unregister(&wrap_power_led);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wrap_led_remove(struct platform_device *pdev)
|
||||
{
|
||||
led_classdev_unregister(&wrap_power_led);
|
||||
led_classdev_unregister(&wrap_error_led);
|
||||
led_classdev_unregister(&wrap_extra_led);
|
||||
return 0;
|
||||
|
|
|
@ -77,8 +77,21 @@ static ssize_t led_delay_on_store(struct device *dev,
|
|||
count++;
|
||||
|
||||
if (count == size) {
|
||||
timer_data->delay_on = state;
|
||||
mod_timer(&timer_data->timer, jiffies + 1);
|
||||
if (timer_data->delay_on != state) {
|
||||
/* the new value differs from the previous */
|
||||
timer_data->delay_on = state;
|
||||
|
||||
/* deactivate previous settings */
|
||||
del_timer_sync(&timer_data->timer);
|
||||
|
||||
/* try to activate hardware acceleration, if any */
|
||||
if (!led_cdev->blink_set ||
|
||||
led_cdev->blink_set(led_cdev,
|
||||
&timer_data->delay_on, &timer_data->delay_off)) {
|
||||
/* no hardware acceleration, blink via timer */
|
||||
mod_timer(&timer_data->timer, jiffies + 1);
|
||||
}
|
||||
}
|
||||
ret = count;
|
||||
}
|
||||
|
||||
|
@ -110,8 +123,21 @@ static ssize_t led_delay_off_store(struct device *dev,
|
|||
count++;
|
||||
|
||||
if (count == size) {
|
||||
timer_data->delay_off = state;
|
||||
mod_timer(&timer_data->timer, jiffies + 1);
|
||||
if (timer_data->delay_off != state) {
|
||||
/* the new value differs from the previous */
|
||||
timer_data->delay_off = state;
|
||||
|
||||
/* deactivate previous settings */
|
||||
del_timer_sync(&timer_data->timer);
|
||||
|
||||
/* try to activate hardware acceleration, if any */
|
||||
if (!led_cdev->blink_set ||
|
||||
led_cdev->blink_set(led_cdev,
|
||||
&timer_data->delay_on, &timer_data->delay_off)) {
|
||||
/* no hardware acceleration, blink via timer */
|
||||
mod_timer(&timer_data->timer, jiffies + 1);
|
||||
}
|
||||
}
|
||||
ret = count;
|
||||
}
|
||||
|
||||
|
@ -143,6 +169,13 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
|
|||
if (rc)
|
||||
goto err_out_delayon;
|
||||
|
||||
/* If there is hardware support for blinking, start one
|
||||
* user friendly blink rate chosen by the driver.
|
||||
*/
|
||||
if (led_cdev->blink_set)
|
||||
led_cdev->blink_set(led_cdev,
|
||||
&timer_data->delay_on, &timer_data->delay_off);
|
||||
|
||||
return;
|
||||
|
||||
err_out_delayon:
|
||||
|
|
|
@ -239,7 +239,7 @@ static struct workqueue_struct *led_workqueue;
|
|||
static int object##_led_wk; \
|
||||
static DECLARE_WORK(object##_led_work, object##_led_update); \
|
||||
static struct led_classdev object##_led = { \
|
||||
.name = "asus:" ledname, \
|
||||
.name = "asus::" ledname, \
|
||||
.brightness_set = object##_led_set, \
|
||||
}
|
||||
|
||||
|
|
|
@ -147,12 +147,12 @@ static void b43_map_led(struct b43_wldev *dev,
|
|||
case B43_LED_TRANSFER:
|
||||
case B43_LED_APTRANSFER:
|
||||
snprintf(name, sizeof(name),
|
||||
"b43-%s:tx", wiphy_name(hw->wiphy));
|
||||
"b43-%s::tx", wiphy_name(hw->wiphy));
|
||||
b43_register_led(dev, &dev->led_tx, name,
|
||||
ieee80211_get_tx_led_name(hw),
|
||||
led_index, activelow);
|
||||
snprintf(name, sizeof(name),
|
||||
"b43-%s:rx", wiphy_name(hw->wiphy));
|
||||
"b43-%s::rx", wiphy_name(hw->wiphy));
|
||||
b43_register_led(dev, &dev->led_rx, name,
|
||||
ieee80211_get_rx_led_name(hw),
|
||||
led_index, activelow);
|
||||
|
@ -162,7 +162,7 @@ static void b43_map_led(struct b43_wldev *dev,
|
|||
case B43_LED_RADIO_B:
|
||||
case B43_LED_MODE_BG:
|
||||
snprintf(name, sizeof(name),
|
||||
"b43-%s:radio", wiphy_name(hw->wiphy));
|
||||
"b43-%s::radio", wiphy_name(hw->wiphy));
|
||||
b43_register_led(dev, &dev->led_radio, name,
|
||||
b43_rfkill_led_name(dev),
|
||||
led_index, activelow);
|
||||
|
@ -173,7 +173,7 @@ static void b43_map_led(struct b43_wldev *dev,
|
|||
case B43_LED_WEIRD:
|
||||
case B43_LED_ASSOC:
|
||||
snprintf(name, sizeof(name),
|
||||
"b43-%s:assoc", wiphy_name(hw->wiphy));
|
||||
"b43-%s::assoc", wiphy_name(hw->wiphy));
|
||||
b43_register_led(dev, &dev->led_assoc, name,
|
||||
ieee80211_get_assoc_led_name(hw),
|
||||
led_index, activelow);
|
||||
|
|
|
@ -38,6 +38,11 @@ struct led_classdev {
|
|||
void (*brightness_set)(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness);
|
||||
|
||||
/* Activate hardware accelerated blink */
|
||||
int (*blink_set)(struct led_classdev *led_cdev,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off);
|
||||
|
||||
struct device *dev;
|
||||
struct list_head node; /* LED Device list */
|
||||
char *default_trigger; /* Trigger to use */
|
||||
|
|
Загрузка…
Ссылка в новой задаче