GIT 34da06002d0cd18ef002a4657f6c7cd6565d3c79 git://git.o-hand.com/linux-rpurdie-leds#for-mm commit Author: Márton Németh Date: Wed Oct 31 15:09:05 2007 +0100 leds: hw acceleration for Clevo mail LED driver Add support for hardware accelerated LED blinking for the mail LED commonly found on Clevo notebooks. Signed-off-by: Márton Németh Signed-off-by: Richard Purdie commit da88037b9c3903f459eb84aafe6111ab89558b94 Author: Márton Németh Date: Wed Oct 31 15:07:12 2007 +0100 leds: Add support for hardware accelerated LED flashing Extends the leds subsystem with a blink_set() callback function which can be optionally implemented by a LED driver. If implemented, the driver can use the hardware acceleration for blinking a LED. Signed-off-by: Márton Németh Signed-off-by: Richard Purdie commit 98f369071601aa2aa0bbf741f16bd0b4eb830217 Author: Richard Purdie Date: Wed Oct 31 15:00:07 2007 +0100 leds: Standardise LED naming scheme As discussed on LKML some notion of 'function' is needed in LED naming. This patch adds this to the documentation and standardises existing LED drivers. Signed-off-by: Richard Purdie commit c4d84893eff6f091bb42aa95104bc54d1cddfa8e Author: Márton Németh Date: Wed Oct 31 11:46:41 2007 +0100 leds: Add clevo notebook LED driver The driver supports the mail LED commonly found on different Clevo notebooks. The driver access the LED through the i8042 hardware which is handled by the input subsystem. Signed-off-by: Márton Németh Signed-off-by: Richard Purdie Documentation/leds-class.txt | 29 ++++- drivers/hwmon/applesmc.c | 2 +- drivers/input/misc/wistron_btns.c | 4 +- drivers/leds/Kconfig | 32 +++++- drivers/leds/Makefile | 1 + drivers/leds/leds-ams-delta.c | 12 +- drivers/leds/leds-clevo-mail.c | 219 +++++++++++++++++++++++++++++++++++++ drivers/leds/leds-corgi.c | 4 +- drivers/leds/leds-locomo.c | 4 +- drivers/leds/leds-net48xx.c | 2 +- drivers/leds/leds-spitz.c | 8 +- drivers/leds/leds-tosa.c | 4 +- drivers/leds/leds-wrap.c | 4 +- drivers/leds/ledtrig-timer.c | 41 ++++++- drivers/misc/asus-laptop.c | 2 +- drivers/net/wireless/b43/leds.c | 8 +- include/linux/leds.h | 5 + 17 files changed, 344 insertions(+), 37 deletions(-) diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt index 8c35c04..b4fbdb5 100644 --- a/Documentation/leds-class.txt +++ b/Documentation/leds-class.txt @@ -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 ). 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 ================== diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 86c66c3..0c94770 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -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, }; diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index b438d99..72176f3 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -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, }; diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index ec568fa..922c3df 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -114,6 +114,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 +154,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" diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index a60de1b..e433e2f 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -19,6 +19,7 @@ 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 # LED Triggers obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o diff --git a/drivers/leds/leds-ams-delta.c b/drivers/leds/leds-ams-delta.c index 599878c..9e30774 100644 --- a/drivers/leds/leds-ams-delta.c +++ b/drivers/leds/leds-ams-delta.c @@ -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, diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c new file mode 100644 index 0000000..6c3d33b --- /dev/null +++ b/drivers/leds/leds-clevo-mail.c @@ -0,0 +1,219 @@ + +#include + +#include +#include +#include + +#include +#include + +#include + +#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 "); +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); diff --git a/drivers/leds/leds-corgi.c b/drivers/leds/leds-corgi.c index cf1dcd7..e45f6c4 100644 --- a/drivers/leds/leds-corgi.c +++ b/drivers/leds/leds-corgi.c @@ -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, }; diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c index bfac499..2cec39b 100644 --- a/drivers/leds/leds-locomo.c +++ b/drivers/leds/leds-locomo.c @@ -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, }; diff --git a/drivers/leds/leds-net48xx.c b/drivers/leds/leds-net48xx.c index 45ba3d4..0543604 100644 --- a/drivers/leds/leds-net48xx.c +++ b/drivers/leds/leds-net48xx.c @@ -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, }; diff --git a/drivers/leds/leds-spitz.c b/drivers/leds/leds-spitz.c index 126d09c..93e1012 100644 --- a/drivers/leds/leds-spitz.c +++ b/drivers/leds/leds-spitz.c @@ -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) diff --git a/drivers/leds/leds-tosa.c b/drivers/leds/leds-tosa.c index fb2416a..9e0a188 100644 --- a/drivers/leds/leds-tosa.c +++ b/drivers/leds/leds-tosa.c @@ -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, }; diff --git a/drivers/leds/leds-wrap.c b/drivers/leds/leds-wrap.c index 27fb2d8..5770cc3 100644 --- a/drivers/leds/leds-wrap.c +++ b/drivers/leds/leds-wrap.c @@ -43,12 +43,12 @@ static void wrap_extra_led_set(struct led_classdev *led_cdev, } 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, }; diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index ed9ff02..82c55d6 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c @@ -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: diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index 7dce318..2673e18 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c @@ -240,7 +240,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, \ } diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 19e5885..6158e0b 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c @@ -144,12 +144,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); @@ -159,7 +159,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); @@ -167,7 +167,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); diff --git a/include/linux/leds.h b/include/linux/leds.h index b4130ff..4cb5927 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -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 */