From patchwork Thu Dec 9 13:41:50 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janusz Krzysztofik X-Patchwork-Id: 394312 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oB9Dh4SX030796 for ; Thu, 9 Dec 2010 13:43:04 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752216Ab0LINmn (ORCPT ); Thu, 9 Dec 2010 08:42:43 -0500 Received: from d1.icnet.pl ([212.160.220.21]:52054 "EHLO d1.icnet.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751197Ab0LINml (ORCPT ); Thu, 9 Dec 2010 08:42:41 -0500 Received: from 87-205-12-81.ip.netia.com.pl ([87.205.12.81] helo=vclass.intranet) by d1.icnet.pl with asmtp (TLS-1.0:DHE_RSA_AES_128_CBC_SHA:16) (Exim 4.34) id 1PQglX-0002dN-Oi; Thu, 09 Dec 2010 14:42:36 +0100 To: Richard Purdie Subject: [RESEND #2] [PATCH v2] LEDS: Add output invertion option to backlight trigger Cc: "linux-fbdev@vger.kernel.org" , linux-kernel@vger.kernel.org, "linux-omap@vger.kernel.org" Content-Disposition: inline From: Janusz Krzysztofik Organization: Tele-Info-System, Poznan, PL Date: Thu, 9 Dec 2010 14:41:50 +0100 MIME-Version: 1.0 Message-Id: <201012091441.51846.jkrzyszt@tis.icnet.pl> X-SA-Exim-Scanned: No (on d1.icnet); SAEximRunCond expanded to false Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Thu, 09 Dec 2010 13:43:05 +0000 (UTC) diff -upr linux-2.6.36-rc5.orig/drivers/leds/ledtrig-backlight.c linux-2.6.36-rc5/drivers/leds/ledtrig-backlight.c --- linux-2.6.36-rc5.orig/drivers/leds/ledtrig-backlight.c 2010-09-24 15:35:13.000000000 +0200 +++ linux-2.6.36-rc5/drivers/leds/ledtrig-backlight.c 2010-10-03 15:59:49.000000000 +0200 @@ -26,6 +26,7 @@ struct bl_trig_notifier { int brightness; int old_status; struct notifier_block notifier; + unsigned invert; }; static int fb_notifier_callback(struct notifier_block *p, @@ -36,23 +37,63 @@ static int fb_notifier_callback(struct n struct led_classdev *led = n->led; struct fb_event *fb_event = data; int *blank = fb_event->data; + int new_status = *blank ? BLANK : UNBLANK; switch (event) { case FB_EVENT_BLANK : - if (*blank && n->old_status == UNBLANK) { + if (new_status == n->old_status) + break; + + if ((n->old_status == UNBLANK) ^ n->invert) { n->brightness = led->brightness; led_set_brightness(led, LED_OFF); - n->old_status = BLANK; - } else if (!*blank && n->old_status == BLANK) { + } else { led_set_brightness(led, n->brightness); - n->old_status = UNBLANK; } + + n->old_status = new_status; + break; } return 0; } +static ssize_t bl_trig_invert_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led = dev_get_drvdata(dev); + struct bl_trig_notifier *n = led->trigger_data; + + return sprintf(buf, "%s\n", n->invert ? "yes" : "no"); +} + +static ssize_t bl_trig_invert_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t num) +{ + struct led_classdev *led = dev_get_drvdata(dev); + struct bl_trig_notifier *n = led->trigger_data; + unsigned invert; + int ret; + + ret = sscanf(buf, "%u", &invert); + if (ret < 1) { + dev_err(dev, "invalid value\n"); + return -EINVAL; + } + + n->invert = !!invert; + + /* After inverting, we need to update the LED. */ + if ((n->old_status == BLANK) ^ n->invert) + led_set_brightness(led, LED_OFF); + else + led_set_brightness(led, n->brightness); + + return num; +} +static DEVICE_ATTR(invert, 0644, bl_trig_invert_show, bl_trig_invert_store); + static void bl_trig_activate(struct led_classdev *led) { int ret; @@ -66,6 +107,10 @@ static void bl_trig_activate(struct led_ return; } + ret = device_create_file(led->dev, &dev_attr_invert); + if (ret) + goto err_invert; + n->led = led; n->brightness = led->brightness; n->old_status = UNBLANK; @@ -74,6 +119,12 @@ static void bl_trig_activate(struct led_ ret = fb_register_client(&n->notifier); if (ret) dev_err(led->dev, "unable to register backlight trigger\n"); + + return; + +err_invert: + led->trigger_data = NULL; + kfree(n); } static void bl_trig_deactivate(struct led_classdev *led) @@ -82,6 +133,7 @@ static void bl_trig_deactivate(struct le (struct bl_trig_notifier *) led->trigger_data; if (n) { + device_remove_file(led->dev, &dev_attr_invert); fb_unregister_client(&n->notifier); kfree(n); }