summaryrefslogtreecommitdiff
path: root/drivers/leds
diff options
context:
space:
mode:
authorDevesh Jhunjhunwala <deveshj@codeaurora.org>2016-06-29 17:48:12 -0700
committerKyle Yan <kyan@codeaurora.org>2016-07-08 11:52:36 -0700
commit154574cfc68dc28ca6a04b5bcf58c77adc67f73c (patch)
tree0b6c2de69de77e209db61f1fd492225baab24c6d /drivers/leds
parent69feba98b2050d93ae0de0e359125fa5a31dd4de (diff)
leds: qpnp-flash-v2: Add operational current property
Add the qcom,current-ma property to specify the operational current for the flash led. Also limit the minimum flash current to 25mA since currents below this value cause unstable flash operation. CRs-Fixed: 1033071 Change-Id: Ia133b6c0cf0c21484f61631f04cba0d1112c9d48 Signed-off-by: Devesh Jhunjhunwala <deveshj@codeaurora.org>
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-qpnp-flash-v2.c63
1 files changed, 47 insertions, 16 deletions
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index 89636557dec1..6f7ba0461800 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -38,8 +38,6 @@
#define FLASH_LED_MOD_CTRL_MASK 0x80
#define FLASH_LED_ISC_DELAY_MASK 0x03
-#define FLASH_LED_TYPE_FLASH 0
-#define FLASH_LED_TYPE_TORCH 1
#define FLASH_LED_HEADROOM_AUTO_MODE_ENABLED true
#define FLASH_LED_ISC_DELAY_SHIFT 6
#define FLASH_LED_ISC_DELAY_DEFAULT_US 3
@@ -60,6 +58,12 @@
#define FLASH_LED_MOD_ENABLE 0x80
#define FLASH_LED_DISABLE 0x00
#define FLASH_LED_SAFETY_TMR_DISABLED 0x13
+#define FLASH_LED_MIN_CURRENT_MA 25
+
+enum flash_led_type {
+ FLASH_LED_TYPE_FLASH,
+ FLASH_LED_TYPE_TORCH,
+};
/*
* Flash LED configuration read from device tree
@@ -141,13 +145,17 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
static void qpnp_flash_led_node_set(struct flash_node_data *fnode, int value)
{
- int prgm_current_ma;
+ int prgm_current_ma = value;
- prgm_current_ma = value < 0 ? 0 : value;
- prgm_current_ma = value > fnode->cdev.max_brightness ?
- fnode->cdev.max_brightness : value;
+ if (value <= 0)
+ prgm_current_ma = 0;
+ else if (value < FLASH_LED_MIN_CURRENT_MA)
+ prgm_current_ma = FLASH_LED_MIN_CURRENT_MA;
+
+ prgm_current_ma = min(prgm_current_ma, fnode->max_current);
+ fnode->current_ma = prgm_current_ma;
fnode->cdev.brightness = prgm_current_ma;
- fnode->brightness = prgm_current_ma * 1000 / fnode->ires_ua + 1;
+ fnode->current_reg_val = prgm_current_ma * 1000 / fnode->ires_ua + 1;
fnode->led_on = prgm_current_ma != 0;
}
@@ -182,7 +190,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
rc = qpnp_flash_led_masked_write(led,
FLASH_LED_REG_TGR_CURRENT(led->base + addr_offset),
- FLASH_LED_CURRENT_MASK, led->fnode[i].brightness);
+ FLASH_LED_CURRENT_MASK, led->fnode[i].current_reg_val);
if (rc)
return rc;
@@ -240,6 +248,7 @@ leds_turn_off:
FLASH_LED_CURRENT_MASK, 0);
if (rc)
return rc;
+
led->fnode[i].led_on = false;
if (led->fnode[i].pinctrl) {
@@ -305,14 +314,6 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
return rc;
}
- rc = of_property_read_u32(node, "qcom,max-current", &val);
- if (!rc) {
- fnode->cdev.max_brightness = val;
- } else {
- dev_err(&led->pdev->dev, "Unable to read max current\n");
- return rc;
- }
-
rc = of_property_read_string(node, "label", &temp_string);
if (!rc) {
if (!strcmp(temp_string, "flash"))
@@ -355,6 +356,36 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
return rc;
}
+ rc = of_property_read_u32(node, "qcom,max-current", &val);
+ if (!rc) {
+ if (val < FLASH_LED_MIN_CURRENT_MA)
+ val = FLASH_LED_MIN_CURRENT_MA;
+ fnode->max_current = val;
+ fnode->cdev.max_brightness = val;
+ } else {
+ dev_err(&led->pdev->dev,
+ "Unable to read max current, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32(node, "qcom,current-ma", &val);
+ if (!rc) {
+ if (val < FLASH_LED_MIN_CURRENT_MA ||
+ val > fnode->max_current)
+ dev_warn(&led->pdev->dev,
+ "Invalid operational current specified, capping it\n");
+ if (val < FLASH_LED_MIN_CURRENT_MA)
+ val = FLASH_LED_MIN_CURRENT_MA;
+ if (val > fnode->max_current)
+ val = fnode->max_current;
+ fnode->current_ma = val;
+ fnode->cdev.brightness = val;
+ } else if (rc != -EINVAL) {
+ dev_err(&led->pdev->dev,
+ "Unable to read operational current, rc=%d\n", rc);
+ return rc;
+ }
+
fnode->duration = FLASH_LED_SAFETY_TMR_DISABLED;
rc = of_property_read_u32(node, "qcom,duration-ms", &val);
if (!rc) {