leds: leds-gpio-flash: add led gpio flash driver

the flash led pins flash_en and flash_now are connected with msm gpios.
add led gpio flash driver for qrd board.

Change-Id: I057958f8756c8fc31ba1a5032cf096d7a7e27e17
Signed-off-by: Tingting Yang <tingting@codeaurora.org>
This commit is contained in:
Tingting Yang
2013-06-22 13:57:28 +08:00
parent f397327d70
commit d09bf67a5d
4 changed files with 249 additions and 0 deletions
@@ -0,0 +1,30 @@
Qualcomm GPIO Flash Leds
Qualcomm GPIO flash LEDs driver is used for
controlling flash LEDs that are connected with 2 GPIOs. The 2 GPIOs are name
flash_en and flash now.
The flash LEDs has torch mode and flash mode. The flash mode is used for camera.
The torch mode is used for torch.
Required properties for each node:
- compatible : should be "qcom,leds-gpio-flash"
- qcom,flash-en : the GPIO pin number of flash-en function
- qcom,flash-now : the GPIO pin number of flash-now function
- linux,name : name of the led that is used in led framework
- linux,default-trigger : name of the led trigger event
No other optional properties for it.
Example:
flashlight {
compatible = "leds-gpio-flash";
status = "okay";
qcom,flash-en = <&msmgpio 18 0>;
qcom,flash-now = <&msmgpio 19 0>;
linux,name = "flashlight";
linux,default-trigger = "flashlight-trigger";
};
+10
View File
@@ -300,6 +300,16 @@ config LEDS_QPNP
To compile this driver as a module, choose M here: the module will
be called leds-qpnp.
config LEDS_MSM_GPIO_FLASH
tristate "Support for GPIO Flash LEDs"
depends on GPIO_MSM_V3
help
This driver supports the leds functionality of GPIO Flash LED. It
includes flash mode and torch mode.
To compile this driver as a module, choose M here: the module will
be called leds-gpio-flash.
config LEDS_WM831X_STATUS
tristate "LED support for status LEDs on WM831x PMICs"
depends on LEDS_CLASS
+1
View File
@@ -54,6 +54,7 @@ obj-$(CONFIG_LEDS_PMIC_MPP) += leds-pmic-mpp.o
obj-$(CONFIG_LEDS_QCIBL) += leds-qci-backlight.o
obj-$(CONFIG_LEDS_MSM_PDM) += leds-msm-pdm.o
obj-$(CONFIG_LEDS_MSM_TRICOLOR) += leds-msm-tricolor.o
obj-$(CONFIG_LEDS_MSM_GPIO_FLASH) += leds-msm-gpio-flash.o
# LED SPI Drivers
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
+208
View File
@@ -0,0 +1,208 @@
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/printk.h>
#define LED_GPIO_FLASH_DRIVER_NAME "qcom,leds-gpio-flash"
#define LED_TRIGGER_DEFAULT "none"
struct led_gpio_flash_data {
int flash_en;
int flash_now;
int brightness;
struct led_classdev cdev;
};
static struct of_device_id led_gpio_flash_of_match[] = {
{.compatible = LED_GPIO_FLASH_DRIVER_NAME,},
{},
};
static void led_gpio_brightness_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
int rc = 0;
struct led_gpio_flash_data *flash_led =
container_of(led_cdev, struct led_gpio_flash_data, cdev);
int brightness = value;
int flash_en = 0, flash_now = 0;
if (brightness > LED_HALF) {
flash_en = 0;
flash_now = 1;
} else if (brightness > LED_OFF) {
flash_en = 1;
flash_now = 0;
} else {
flash_en = 0;
flash_now = 0;
}
rc = gpio_direction_output(flash_led->flash_en, flash_en);
if (rc) {
pr_err("%s: Failed to set gpio %d\n", __func__,
flash_led->flash_en);
goto err;
}
rc = gpio_direction_output(flash_led->flash_now, flash_now);
if (rc) {
pr_err("%s: Failed to set gpio %d\n", __func__,
flash_led->flash_now);
goto err;
}
flash_led->brightness = brightness;
err:
return;
}
static enum led_brightness led_gpio_brightness_get(struct led_classdev
*led_cdev)
{
struct led_gpio_flash_data *flash_led =
container_of(led_cdev, struct led_gpio_flash_data, cdev);
return flash_led->brightness;
}
int __devinit led_gpio_flash_probe(struct platform_device *pdev)
{
int rc = 0;
const char *temp_str;
struct led_gpio_flash_data *flash_led = NULL;
struct device_node *node = pdev->dev.of_node;
flash_led = devm_kzalloc(&pdev->dev, sizeof(struct led_gpio_flash_data),
GFP_KERNEL);
if (flash_led == NULL) {
dev_err(&pdev->dev, "%s:%d Unable to allocate memory\n",
__func__, __LINE__);
return -ENOMEM;
}
flash_led->cdev.default_trigger = LED_TRIGGER_DEFAULT;
rc = of_property_read_string(node, "linux,default-trigger", &temp_str);
if (!rc)
flash_led->cdev.default_trigger = temp_str;
flash_led->flash_en = of_get_named_gpio(node, "qcom,flash-en", 0);
if (flash_led->flash_en < 0) {
dev_err(&pdev->dev,
"Looking up %s property in node %s failed. rc = %d\n",
"flash-en", node->full_name, flash_led->flash_en);
goto error;
} else {
rc = gpio_request(flash_led->flash_en, "FLASH_EN");
if (rc) {
dev_err(&pdev->dev,
"%s: Failed to request gpio %d,rc = %d\n",
__func__, flash_led->flash_en, rc);
goto error;
}
}
flash_led->flash_now = of_get_named_gpio(node, "qcom,flash-now", 0);
if (flash_led->flash_now < 0) {
dev_err(&pdev->dev,
"Looking up %s property in node %s failed. rc = %d\n",
"flash-now", node->full_name, flash_led->flash_now);
goto error;
} else {
rc = gpio_request(flash_led->flash_now, "FLASH_NOW");
if (rc) {
dev_err(&pdev->dev,
"%s: Failed to request gpio %d,rc = %d\n",
__func__, flash_led->flash_now, rc);
goto error;
}
}
gpio_tlmm_config(GPIO_CFG(flash_led->flash_en, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
gpio_tlmm_config(GPIO_CFG(flash_led->flash_now, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
rc = of_property_read_string(node, "linux,name", &flash_led->cdev.name);
if (rc) {
dev_err(&pdev->dev, "%s: Failed to read linux name. rc = %d\n",
__func__, rc);
goto error;
}
platform_set_drvdata(pdev, flash_led);
flash_led->cdev.max_brightness = LED_FULL;
flash_led->cdev.brightness_set = led_gpio_brightness_set;
flash_led->cdev.brightness_get = led_gpio_brightness_get;
rc = led_classdev_register(&pdev->dev, &flash_led->cdev);
if (rc) {
dev_err(&pdev->dev, "%s: Failed to register led dev. rc = %d\n",
__func__, rc);
goto error;
}
return 0;
error:
devm_kfree(&pdev->dev, flash_led);
return rc;
}
int __devexit led_gpio_flash_remove(struct platform_device *pdev)
{
struct led_gpio_flash_data *flash_led =
(struct led_gpio_flash_data *)platform_get_drvdata(pdev);
led_classdev_unregister(&flash_led->cdev);
devm_kfree(&pdev->dev, flash_led);
return 0;
}
static struct platform_driver led_gpio_flash_driver = {
.probe = led_gpio_flash_probe,
.remove = __devexit_p(led_gpio_flash_remove),
.driver = {
.name = LED_GPIO_FLASH_DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = led_gpio_flash_of_match,
}
};
static int __init led_gpio_flash_init(void)
{
return platform_driver_register(&led_gpio_flash_driver);
}
static void __exit led_gpio_flash_exit(void)
{
return platform_driver_unregister(&led_gpio_flash_driver);
}
late_initcall(led_gpio_flash_init);
module_exit(led_gpio_flash_exit);
MODULE_DESCRIPTION("QCOM GPIO LEDs driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("leds:leds-msm-gpio-flash");