1/* 2 * Backlight emulation LED trigger 3 * 4 * Copyright 2008 (C) Rodolfo Giometti <giometti@linux.it> 5 * Copyright 2008 (C) Eurotech S.p.A. <info@eurotech.it> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 */ 12 13#include <linux/module.h> 14#include <linux/kernel.h> 15#include <linux/slab.h> 16#include <linux/init.h> 17#include <linux/fb.h> 18#include <linux/leds.h> 19#include "leds.h" 20 21#define BLANK 1 22#define UNBLANK 0 23 24struct bl_trig_notifier { 25 struct led_classdev *led; 26 int brightness; 27 int old_status; 28 struct notifier_block notifier; 29}; 30 31static int fb_notifier_callback(struct notifier_block *p, 32 unsigned long event, void *data) 33{ 34 struct bl_trig_notifier *n = container_of(p, 35 struct bl_trig_notifier, notifier); 36 struct led_classdev *led = n->led; 37 struct fb_event *fb_event = data; 38 int *blank = fb_event->data; 39 40 switch (event) { 41 case FB_EVENT_BLANK : 42 if (*blank && n->old_status == UNBLANK) { 43 n->brightness = led->brightness; 44 led_set_brightness(led, LED_OFF); 45 n->old_status = BLANK; 46 } else if (!*blank && n->old_status == BLANK) { 47 led_set_brightness(led, n->brightness); 48 n->old_status = UNBLANK; 49 } 50 break; 51 } 52 53 return 0; 54} 55 56static void bl_trig_activate(struct led_classdev *led) 57{ 58 int ret; 59 60 struct bl_trig_notifier *n; 61 62 n = kzalloc(sizeof(struct bl_trig_notifier), GFP_KERNEL); 63 led->trigger_data = n; 64 if (!n) { 65 dev_err(led->dev, "unable to allocate backlight trigger\n"); 66 return; 67 } 68 69 n->led = led; 70 n->brightness = led->brightness; 71 n->old_status = UNBLANK; 72 n->notifier.notifier_call = fb_notifier_callback; 73 74 ret = fb_register_client(&n->notifier); 75 if (ret) 76 dev_err(led->dev, "unable to register backlight trigger\n"); 77} 78 79static void bl_trig_deactivate(struct led_classdev *led) 80{ 81 struct bl_trig_notifier *n = 82 (struct bl_trig_notifier *) led->trigger_data; 83 84 if (n) { 85 fb_unregister_client(&n->notifier); 86 kfree(n); 87 } 88} 89 90static struct led_trigger bl_led_trigger = { 91 .name = "backlight", 92 .activate = bl_trig_activate, 93 .deactivate = bl_trig_deactivate 94}; 95 96static int __init bl_trig_init(void) 97{ 98 return led_trigger_register(&bl_led_trigger); 99} 100 101static void __exit bl_trig_exit(void) 102{ 103 led_trigger_unregister(&bl_led_trigger); 104} 105 106module_init(bl_trig_init); 107module_exit(bl_trig_exit); 108 109MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); 110MODULE_DESCRIPTION("Backlight emulation LED trigger"); 111MODULE_LICENSE("GPL v2"); 112