diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 16:07:32 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 16:07:32 -0700 |
commit | ea541686d8454efac4f2b5c0767affb12d4b6a52 (patch) | |
tree | ef0812fcc3e07c067042add6388146b3485c793e /drivers/leds/ledtrig-backlight.c | |
parent | 0d876c6a96e2cabf8632e8066b617d9c2dec9518 (diff) | |
parent | 601a1b92ed3ce0025f7bec6fc591cceaef8d9d69 (diff) |
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/acpi: Fix merge fallout from acpi_driver_data change
leds: Simplify logic in leds-ams-delta
leds: Fix trigger registration race
leds: Fix leds-class.c comment
leds: Add driver for HP harddisk protection LEDs
leds: leds-pca955x - Mark pca955x_led_set() static
leds: Remove uneeded leds-cm-x270 driver
leds: Remove uneeded strlen calls
leds: Add leds-wrap default-trigger
leds: Make default trigger fields const
leds: Add backlight LED trigger
leds: da903x: Add support for LEDs found on DA9030/DA9034
Diffstat (limited to 'drivers/leds/ledtrig-backlight.c')
-rw-r--r-- | drivers/leds/ledtrig-backlight.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/drivers/leds/ledtrig-backlight.c b/drivers/leds/ledtrig-backlight.c new file mode 100644 index 00000000000..d3dfcfb417b --- /dev/null +++ b/drivers/leds/ledtrig-backlight.c @@ -0,0 +1,110 @@ +/* + * Backlight emulation LED trigger + * + * Copyright 2008 (C) Rodolfo Giometti <giometti@linux.it> + * Copyright 2008 (C) Eurotech S.p.A. <info@eurotech.it> + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/fb.h> +#include <linux/leds.h> +#include "leds.h" + +#define BLANK 1 +#define UNBLANK 0 + +struct bl_trig_notifier { + struct led_classdev *led; + int brightness; + int old_status; + struct notifier_block notifier; +}; + +static int fb_notifier_callback(struct notifier_block *p, + unsigned long event, void *data) +{ + struct bl_trig_notifier *n = container_of(p, + struct bl_trig_notifier, notifier); + struct led_classdev *led = n->led; + struct fb_event *fb_event = data; + int *blank = fb_event->data; + + switch (event) { + case FB_EVENT_BLANK : + if (*blank && n->old_status == UNBLANK) { + n->brightness = led->brightness; + led_set_brightness(led, LED_OFF); + n->old_status = BLANK; + } else if (!*blank && n->old_status == BLANK) { + led_set_brightness(led, n->brightness); + n->old_status = UNBLANK; + } + break; + } + + return 0; +} + +static void bl_trig_activate(struct led_classdev *led) +{ + int ret; + + struct bl_trig_notifier *n; + + n = kzalloc(sizeof(struct bl_trig_notifier), GFP_KERNEL); + led->trigger_data = n; + if (!n) { + dev_err(led->dev, "unable to allocate backlight trigger\n"); + return; + } + + n->led = led; + n->brightness = led->brightness; + n->old_status = UNBLANK; + n->notifier.notifier_call = fb_notifier_callback; + + ret = fb_register_client(&n->notifier); + if (ret) + dev_err(led->dev, "unable to register backlight trigger\n"); +} + +static void bl_trig_deactivate(struct led_classdev *led) +{ + struct bl_trig_notifier *n = + (struct bl_trig_notifier *) led->trigger_data; + + if (n) { + fb_unregister_client(&n->notifier); + kfree(n); + } +} + +static struct led_trigger bl_led_trigger = { + .name = "backlight", + .activate = bl_trig_activate, + .deactivate = bl_trig_deactivate +}; + +static int __init bl_trig_init(void) +{ + return led_trigger_register(&bl_led_trigger); +} + +static void __exit bl_trig_exit(void) +{ + led_trigger_unregister(&bl_led_trigger); +} + +module_init(bl_trig_init); +module_exit(bl_trig_exit); + +MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); +MODULE_DESCRIPTION("Backlight emulation LED trigger"); +MODULE_LICENSE("GPL v2"); |