diff options
| author | Devesh Jhunjhunwala <deveshj@codeaurora.org> | 2016-06-29 17:48:12 -0700 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-07-08 11:52:36 -0700 |
| commit | 154574cfc68dc28ca6a04b5bcf58c77adc67f73c (patch) | |
| tree | 0b6c2de69de77e209db61f1fd492225baab24c6d | |
| parent | 69feba98b2050d93ae0de0e359125fa5a31dd4de (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>
| -rw-r--r-- | Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt | 8 | ||||
| -rw-r--r-- | drivers/leds/leds-qpnp-flash-v2.c | 63 | ||||
| -rw-r--r-- | include/linux/leds-qpnp-flash-v2.h | 5 |
3 files changed, 58 insertions, 18 deletions
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt index ce2cec5582f3..f1a8c77c8387 100644 --- a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt +++ b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt @@ -36,6 +36,8 @@ serve as an overall switch. 10ms resolution. This is not required for switch node. Optional properties inside child node: +- qcom,current-ma : operational current intensity for LED in mA. Accepted values are a + positive integer in the range of 0 to qcom,max-current inclusive. - qcom,ires-ua : Integer type to specify current resolution. Accepted values should be 12500, 10000, 7500, and 5000. Unit is uA. - qcom,hdrm-voltage-mv : Integer type specifying headroom voltage. Values are from 125mV to 500mV @@ -69,6 +71,7 @@ Example: qcom,default-led-trigger = "flash0_trigger"; qcom,id = <0>; + qcom,current-ma = <1000>; qcom,duration-ms = <1280>; qcom,ires-ua = <12500>; qcom,hdrm-voltage-mv = <325>; @@ -82,6 +85,7 @@ Example: qcom,default-led-trigger = "flash1_trigger"; qcom,id = <1>; + qcom,current-ma = <1000>; qcom,duration-ms = <1280>; qcom,ires-ua = <12500>; qcom,hdrm-voltage-mv = <325>; @@ -95,6 +99,7 @@ Example: qcom,default-led-trigger = "flash2_trigger"; qcom,id = <2>; + qcom,current-ma = <500>; qcom,duration-ms = <1280>; qcom,ires-ua = <12500>; qcom,hdrm-voltage-mv = <325>; @@ -111,6 +116,7 @@ Example: qcom,default-led-trigger = "torch0_trigger"; qcom,id = <0>; + qcom,current-ma = <300>; qcom,ires-ua = <12500>; qcom,hdrm-voltage-mv = <325>; qcom,hdrm-vol-hi-lo-win-mv = <100>; @@ -123,6 +129,7 @@ Example: qcom,default-led-trigger = "torch1_trigger"; qcom,id = <1>; + qcom,current-ma = <300>; qcom,ires-ua = <12500>; qcom,hdrm-voltage-mv = <325>; qcom,hdrm-vol-hi-lo-win-mv = <100>; @@ -135,6 +142,7 @@ Example: qcom,default-led-trigger = "torch2_trigger"; qcom,id = <2>; + qcom,current-ma = <300>; qcom,ires-ua = <12500>; qcom,hdrm-voltage-mv = <325>; qcom,hdrm-vol-hi-lo-win-mv = <100>; 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) { diff --git a/include/linux/leds-qpnp-flash-v2.h b/include/linux/leds-qpnp-flash-v2.h index 353466f6c108..ae36a163ed21 100644 --- a/include/linux/leds-qpnp-flash-v2.h +++ b/include/linux/leds-qpnp-flash-v2.h @@ -26,13 +26,14 @@ struct flash_node_data { struct pinctrl_state *gpio_state_active; struct pinctrl_state *gpio_state_suspend; int ires_ua; - u16 prgm_current; + int max_current; + int current_ma; u8 duration; u8 id; u8 type; u8 ires; u8 hdrm_val; - u8 brightness; + u8 current_reg_val; bool led_on; }; |
