From patchwork Mon Sep 22 15:21:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacek Anaszewski X-Patchwork-Id: 4948451 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B838DBEEA5 for ; Mon, 22 Sep 2014 15:21:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6D5622011B for ; Mon, 22 Sep 2014 15:21:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6C46D20176 for ; Mon, 22 Sep 2014 15:21:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754138AbaIVPV1 (ORCPT ); Mon, 22 Sep 2014 11:21:27 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:40425 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754112AbaIVPVZ (ORCPT ); Mon, 22 Sep 2014 11:21:25 -0400 Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NCB00H236NMKCB0@mailout4.samsung.com>; Tue, 23 Sep 2014 00:21:22 +0900 (KST) X-AuditID: cbfee61b-f79d76d0000024d6-a0-54203e713078 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 4A.D3.09430.17E30245; Tue, 23 Sep 2014 00:21:21 +0900 (KST) Received: from AMDC2362.DIGITAL.local ([106.120.53.23]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NCB0058D6N8I680@mmp2.samsung.com>; Tue, 23 Sep 2014 00:21:21 +0900 (KST) From: Jacek Anaszewski To: linux-leds@vger.kernel.org, linux-media@vger.kernel.org Cc: kyungmin.park@samsung.com, b.zolnierkie@samsung.com, Jacek Anaszewski , Bryan Wu , Richard Purdie Subject: [PATCH/RFC v6 2/3] leds: add API for setting torch brightness Date: Mon, 22 Sep 2014 17:21:05 +0200 Message-id: <1411399266-16375-3-git-send-email-j.anaszewski@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1411399266-16375-1-git-send-email-j.anaszewski@samsung.com> References: <1411399266-16375-1-git-send-email-j.anaszewski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjluLIzCtJLcpLzFFi42I5/e+xoG6hnUKIwfkz1hYbZ6xntTi6cyKT Re/V54wWZ5vesFtsfbOO0aJnw1ZWi927nrI6sHvsnHWX3WPP/B+sHn1bVjF6fN4kF8ASxWWT kpqTWZZapG+XwJXR8PcFc8F9hYrfE3YzNTC2S3cxcnJICJhIfGybzgJhi0lcuLeerYuRi0NI YDqjxP7l61ghnHYmie2/G5lBqtgEDCV+vnjNBGKLCFhLzDoE0s3FwSywmlHiztavrCAJYQE3 iR+nnrF3MXJwsAioSjx7lgES5hXwkPhz+CcjSFhCQEFiziQbkDCngKfEhI0bGEFsIaCSuycf M09g5F3AyLCKUTS1ILmgOCk910ivODG3uDQvXS85P3cTIziUnknvYFzVYHGIUYCDUYmH90eL fIgQa2JZcWXuIUYJDmYlEd4gaYUQId6UxMqq1KL8+KLSnNTiQ4zSHCxK4rwHW60DhQTSE0tS s1NTC1KLYLJMHJxSDYxTTc5OqT2lny8W9FWgdbKaN7Oy6NlHO+T3FcWoui7+JD2ttb/sdZeq HNOOh6/rM24dWv3IbZfFQW3unOkqsVJVi7pEa/9/UC9alHBzbXXkxBN9M1rrN9b6Lt0ctYnv wOTj6ff+euzfvc1d7lpJrc9c/r/y9hdF29OWJNnNW3pRe61MwYe35QFKLMUZiYZazEXFiQD2 4NabIQIAAA== Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch prepares ground for addition of LED Flash Class extension to the LED subsystem. Since turning the torch on must have guaranteed immediate effect the brightness_set op can't be used for it. Drivers must schedule a work queue task in this op to be compatible with led-triggers, which call brightess_set from timer irqs. In order to address this limitation a torch_brightness_set op and led_set_torch_brightness API is introduced. Setting brightness sysfs attribute will result in calling brightness_set op for LED Class devices and torch_brightness_set op for LED Flash Class devices, whereas triggers will still call brightness op in both cases. Signed-off-by: Jacek Anaszewski Acked-by: Kyungmin Park Cc: Bryan Wu Cc: Richard Purdie --- drivers/leds/led-class.c | 9 +++++++-- drivers/leds/led-core.c | 14 ++++++++++++++ include/linux/leds.h | 21 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index a39ca8f..5a11a07 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -54,9 +54,14 @@ static ssize_t brightness_store(struct device *dev, if (state == LED_OFF) led_trigger_remove(led_cdev); - __led_set_brightness(led_cdev, state); - ret = size; + if (led_cdev->flags & LED_DEV_CAP_TORCH) + ret = led_set_torch_brightness(led_cdev, state); + else + __led_set_brightness(led_cdev, state); + + if (!ret) + ret = size; unlock: mutex_unlock(&led_cdev->led_access); return ret; diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index cca86ab..c6d8288 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -143,6 +143,20 @@ int led_update_brightness(struct led_classdev *led_cdev) } EXPORT_SYMBOL(led_update_brightness); +int led_set_torch_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + int ret = 0; + + led_cdev->brightness = min(brightness, led_cdev->max_brightness); + + if (!(led_cdev->flags & LED_SUSPENDED)) + ret = led_cdev->torch_brightness_set(led_cdev, + led_cdev->brightness); + return ret; +} +EXPORT_SYMBOL_GPL(led_set_torch_brightness); + /* Caller must ensure led_cdev->led_access held */ void led_sysfs_disable(struct led_classdev *led_cdev) { diff --git a/include/linux/leds.h b/include/linux/leds.h index 44c8a98..bc2a570 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -44,11 +44,21 @@ struct led_classdev { #define LED_BLINK_ONESHOT_STOP (1 << 18) #define LED_BLINK_INVERT (1 << 19) #define LED_SYSFS_DISABLE (1 << 20) +#define LED_DEV_CAP_TORCH (1 << 21) /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ void (*brightness_set)(struct led_classdev *led_cdev, enum led_brightness brightness); + /* + * Set LED brightness immediately - it is required for flash led + * devices as they require setting torch brightness to have immediate + * effect. brightness_set op cannot be used for this purpose because + * the led drivers schedule a work queue task in it to allow for + * being called from led-triggers, i.e. from the timer irq context. + */ + int (*torch_brightness_set)(struct led_classdev *led_cdev, + enum led_brightness brightness); /* Get LED brightness level */ enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); @@ -157,6 +167,17 @@ extern void led_set_brightness(struct led_classdev *led_cdev, extern int led_update_brightness(struct led_classdev *led_cdev); /** + * led_set_torch_brightness - set torch LED brightness + * @led_cdev: the LED to set + * @brightness: the brightness to set it to + * + * Returns: 0 on success or negative error value on failure + * + * Set a torch LED's brightness. + */ +extern int led_set_torch_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness); +/** * led_sysfs_disable - disable LED sysfs interface * @led_cdev: the LED to set *