mirror of
https://github.com/joel16/android_kernel_sony_msm8994.git
synced 2025-02-18 20:38:46 +00:00
Leds: Add op sequece for GPIO Led driver.
Pinctrl is used for gpio control. Remove old gpio dependency and pinctrl support in driver. The control logic of different flash driver IC may be different for flash mode and torch mode. So adding sequence config in dtsi to make sure this driver can be used for different driver IC. Signed-off-by: Kui Wang <kuiw@codeaurora.org> Change-Id: I5036cd80bd3520faf62d76714471a8bcff7b5421
This commit is contained in:
parent
19c9d7620c
commit
ddab8f2697
@ -15,6 +15,11 @@ Required properties for each node:
|
||||
- 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
|
||||
- qcom,op-seq : GPIO config name
|
||||
- qcom,torch-seq-val: GPIO config value for torch mode
|
||||
- qcom,flash-seq-val: GPIO config value for flash mode
|
||||
- pinctrl-names : pinctrl name
|
||||
- pinctrl-0 : default gpio stats
|
||||
|
||||
No other optional properties for it.
|
||||
|
||||
@ -23,8 +28,13 @@ Example:
|
||||
flashlight {
|
||||
compatible = "leds-gpio-flash";
|
||||
status = "okay";
|
||||
pinctrl-names = "flash_default";
|
||||
pinctrl-0 = <&flash_default>;
|
||||
qcom,flash-en = <&msmgpio 18 0>;
|
||||
qcom,flash-now = <&msmgpio 19 0>;
|
||||
qcom,op-seq = "flash_en", "flash_now";
|
||||
qcom,torch-seq-val = <1, 0>;
|
||||
qcom,flash-seq-val = <0, 1>;
|
||||
linux,name = "flashlight";
|
||||
linux,default-trigger = "flashlight-trigger";
|
||||
};
|
||||
|
@ -11,11 +11,40 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
&tlmm_pinmux {
|
||||
OCP8110_pins {
|
||||
qcom,pins = <&gp 31>, <&gp 32>;
|
||||
qcom,num-grp-pins = <2>;
|
||||
qcom,pin-func = <0>;
|
||||
label = "OCP8110_pins";
|
||||
OCP8110_default: en_default {
|
||||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&soc {
|
||||
flash_OCP8110:flashlight {
|
||||
compatible = "qcom,leds-gpio-flash";
|
||||
status = "okay";
|
||||
pinctrl-names = "flash_default";
|
||||
pinctrl-0 = <&OCP8110_default>;
|
||||
qcom,flash-en = <&msm_gpio 31 0>;
|
||||
qcom,flash-now = <&msm_gpio 32 0>;
|
||||
qcom,op-seq = "flash_en", "flash_now";
|
||||
qcom,torch-seq-val = <1 0>;
|
||||
qcom,flash-seq-val = <1 1>;
|
||||
linux,name = "flashlight";
|
||||
linux,default-trigger = "flashlight-trigger";
|
||||
};
|
||||
|
||||
led_flash0: qcom,camera-led-flash {
|
||||
cell-index = <0>;
|
||||
compatible = "qcom,camera-led-flash";
|
||||
qcom,flash-type = <3>;
|
||||
qcom,flash-source = <&flash_OCP8110>;
|
||||
qcom,torch-source = <&flash_OCP8110>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -110,6 +139,7 @@
|
||||
qcom,mount-angle = <90>;
|
||||
qcom,actuator-src = <&actuator0>;
|
||||
qcom,eeprom-src = <&eeprom0>;
|
||||
qcom,led-flash-src = <&led_flash0>;
|
||||
cam_vdig-supply = <&pm8916_l2>;
|
||||
cam_vana-supply = <&pm8916_l17>;
|
||||
cam_vio-supply = <&pm8916_l6>;
|
||||
|
@ -319,7 +319,6 @@ config LEDS_QPNP_WLED
|
||||
|
||||
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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2014, 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
|
||||
@ -20,15 +20,43 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
/* #define CONFIG_GPIO_FLASH_DEBUG */
|
||||
#undef CDBG
|
||||
#ifdef CONFIG_GPIO_FLASH_DEBUG
|
||||
#define CDBG(fmt, args...) pr_err(fmt, ##args)
|
||||
#else
|
||||
#define CDBG(fmt, args...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define LED_GPIO_FLASH_DRIVER_NAME "qcom,leds-gpio-flash"
|
||||
#define LED_TRIGGER_DEFAULT "none"
|
||||
|
||||
#define GPIO_OUT_LOW (0 << 1)
|
||||
#define GPIO_OUT_HIGH (1 << 1)
|
||||
|
||||
enum msm_flash_seq_type_t {
|
||||
FLASH_EN,
|
||||
FLASH_NOW,
|
||||
};
|
||||
|
||||
struct msm_flash_ctrl_seq {
|
||||
enum msm_flash_seq_type_t seq_type;
|
||||
uint8_t flash_on_val;
|
||||
uint8_t torch_on_val;
|
||||
uint8_t flash_off_val;
|
||||
};
|
||||
|
||||
struct led_gpio_flash_data {
|
||||
int flash_en;
|
||||
int flash_now;
|
||||
int brightness;
|
||||
struct led_classdev cdev;
|
||||
struct pinctrl *pinctrl;
|
||||
struct pinctrl_state *gpio_state_default;
|
||||
struct msm_flash_ctrl_seq ctrl_seq[2];
|
||||
};
|
||||
|
||||
static struct of_device_id led_gpio_flash_of_match[] = {
|
||||
@ -47,15 +75,20 @@ static void led_gpio_brightness_set(struct led_classdev *led_cdev,
|
||||
int flash_en = 0, flash_now = 0;
|
||||
|
||||
if (brightness > LED_HALF) {
|
||||
flash_en = 0;
|
||||
flash_now = 1;
|
||||
flash_en =
|
||||
flash_led->ctrl_seq[FLASH_EN].flash_on_val;
|
||||
flash_now =
|
||||
flash_led->ctrl_seq[FLASH_NOW].flash_on_val;
|
||||
} else if (brightness > LED_OFF) {
|
||||
flash_en = 1;
|
||||
flash_now = 0;
|
||||
flash_en =
|
||||
flash_led->ctrl_seq[FLASH_EN].torch_on_val;
|
||||
flash_now =
|
||||
flash_led->ctrl_seq[FLASH_NOW].torch_on_val;
|
||||
} else {
|
||||
flash_en = 0;
|
||||
flash_now = 0;
|
||||
}
|
||||
CDBG("%s:flash_en=%d, flash_now=%d\n", __func__, flash_en, flash_now);
|
||||
|
||||
rc = gpio_direction_output(flash_led->flash_en, flash_en);
|
||||
if (rc) {
|
||||
@ -69,7 +102,6 @@ static void led_gpio_brightness_set(struct led_classdev *led_cdev,
|
||||
flash_led->flash_now);
|
||||
goto err;
|
||||
}
|
||||
|
||||
flash_led->brightness = brightness;
|
||||
err:
|
||||
return;
|
||||
@ -89,7 +121,10 @@ int led_gpio_flash_probe(struct platform_device *pdev)
|
||||
const char *temp_str;
|
||||
struct led_gpio_flash_data *flash_led = NULL;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
|
||||
const char *seq_name = NULL;
|
||||
uint32_t array_flash_seq[2];
|
||||
uint32_t array_torch_seq[2];
|
||||
int i = 0;
|
||||
flash_led = devm_kzalloc(&pdev->dev, sizeof(struct led_gpio_flash_data),
|
||||
GFP_KERNEL);
|
||||
if (flash_led == NULL) {
|
||||
@ -103,8 +138,25 @@ int led_gpio_flash_probe(struct platform_device *pdev)
|
||||
if (!rc)
|
||||
flash_led->cdev.default_trigger = temp_str;
|
||||
|
||||
flash_led->flash_en = of_get_named_gpio(node, "qcom,flash-en", 0);
|
||||
flash_led->pinctrl = devm_pinctrl_get(&pdev->dev);
|
||||
if (IS_ERR(flash_led->pinctrl)) {
|
||||
pr_err("%s:failed to get pinctrl\n", __func__);
|
||||
return PTR_ERR(flash_led->pinctrl);
|
||||
}
|
||||
|
||||
flash_led->gpio_state_default = pinctrl_lookup_state(flash_led->pinctrl,
|
||||
"flash_default");
|
||||
if (IS_ERR(flash_led->gpio_state_default)) {
|
||||
pr_err("%s:can not get active pinstate\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = pinctrl_select_state(flash_led->pinctrl,
|
||||
flash_led->gpio_state_default);
|
||||
if (rc)
|
||||
pr_err("%s:set state failed!\n", __func__);
|
||||
|
||||
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",
|
||||
@ -133,18 +185,10 @@ int led_gpio_flash_probe(struct platform_device *pdev)
|
||||
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",
|
||||
@ -152,6 +196,74 @@ int led_gpio_flash_probe(struct platform_device *pdev)
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(node, "qcom,flash-seq-val",
|
||||
array_flash_seq, 2);
|
||||
|
||||
if (rc < 0) {
|
||||
pr_err("%s get flash op seq failed %d\n",
|
||||
__func__, __LINE__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(node, "qcom,torch-seq-val",
|
||||
array_torch_seq, 2);
|
||||
|
||||
if (rc < 0) {
|
||||
pr_err("%s get torch op seq failed %d\n",
|
||||
__func__, __LINE__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
rc = of_property_read_string_index(node,
|
||||
"qcom,op-seq", i,
|
||||
&seq_name);
|
||||
CDBG("%s seq_name[%d] = %s\n", __func__, i,
|
||||
seq_name);
|
||||
if (rc < 0)
|
||||
dev_err(&pdev->dev, "%s failed %d\n",
|
||||
__func__, __LINE__);
|
||||
|
||||
if (!strcmp(seq_name, "flash_en")) {
|
||||
flash_led->ctrl_seq[FLASH_EN].seq_type =
|
||||
FLASH_EN;
|
||||
CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
|
||||
i, flash_led->ctrl_seq[FLASH_EN].seq_type);
|
||||
if (array_flash_seq[i] == 0)
|
||||
flash_led->ctrl_seq[FLASH_EN].flash_on_val =
|
||||
GPIO_OUT_LOW;
|
||||
else
|
||||
flash_led->ctrl_seq[FLASH_EN].flash_on_val =
|
||||
GPIO_OUT_HIGH;
|
||||
|
||||
if (array_torch_seq[i] == 0)
|
||||
flash_led->ctrl_seq[FLASH_EN].torch_on_val =
|
||||
GPIO_OUT_LOW;
|
||||
else
|
||||
flash_led->ctrl_seq[FLASH_EN].torch_on_val =
|
||||
GPIO_OUT_HIGH;
|
||||
} else if (!strcmp(seq_name, "flash_now")) {
|
||||
flash_led->ctrl_seq[FLASH_NOW].seq_type =
|
||||
FLASH_NOW;
|
||||
CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
|
||||
i, flash_led->ctrl_seq[i].seq_type);
|
||||
if (array_flash_seq[i] == 0)
|
||||
flash_led->ctrl_seq[FLASH_NOW].flash_on_val =
|
||||
GPIO_OUT_LOW;
|
||||
else
|
||||
flash_led->ctrl_seq[FLASH_NOW].flash_on_val =
|
||||
GPIO_OUT_HIGH;
|
||||
|
||||
if (array_torch_seq[i] == 0)
|
||||
flash_led->ctrl_seq[FLASH_NOW].torch_on_val =
|
||||
GPIO_OUT_LOW;
|
||||
else
|
||||
flash_led->ctrl_seq[FLASH_NOW].torch_on_val =
|
||||
GPIO_OUT_HIGH;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, flash_led);
|
||||
flash_led->cdev.max_brightness = LED_FULL;
|
||||
flash_led->cdev.brightness_set = led_gpio_brightness_set;
|
||||
@ -163,9 +275,12 @@ int led_gpio_flash_probe(struct platform_device *pdev)
|
||||
__func__, rc);
|
||||
goto error;
|
||||
}
|
||||
pr_err("%s:probe successfully!\n", __func__);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (IS_ERR(flash_led->pinctrl))
|
||||
devm_pinctrl_put(flash_led->pinctrl);
|
||||
devm_kfree(&pdev->dev, flash_led);
|
||||
return rc;
|
||||
}
|
||||
@ -174,7 +289,8 @@ int led_gpio_flash_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct led_gpio_flash_data *flash_led =
|
||||
(struct led_gpio_flash_data *)platform_get_drvdata(pdev);
|
||||
|
||||
if (IS_ERR(flash_led->pinctrl))
|
||||
devm_pinctrl_put(flash_led->pinctrl);
|
||||
led_classdev_unregister(&flash_led->cdev);
|
||||
devm_kfree(&pdev->dev, flash_led);
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user