summaryrefslogtreecommitdiff
path: root/drivers/leds
diff options
context:
space:
mode:
authorChun Zhang <chunz@codeaurora.org>2013-08-09 11:54:23 -0700
committerStephen Boyd <sboyd@codeaurora.org>2013-09-04 17:19:41 -0700
commitfb3f90874aea383461541da62d1d65be5439fea6 (patch)
tree47f97d62fb102f63e0d1b9f4cbca13838256c67a /drivers/leds
parent4c62687de987f4d7c90fbf20d56ce7c0b78bbe79 (diff)
leds: leds-qpnp: Enable watchdog timer for flash torch mode
Flash LED raises module temperature when turned on. Current implementation disables timers in torch mode and this creates potential risk of module damage due to raised temperature. When flash LED is used as torch, watchdog timer should be enabled to allow hardware to turn LEDs off according to predefined duration. Change-Id: I3768a04abd59c12f6bd1c355a5e194b1fa5b2bc4 Signed-off-by: Chun Zhang <chunz@codeaurora.org>
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-qpnp.c120
1 files changed, 66 insertions, 54 deletions
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index fb3e02824d13..51b8af82a14a 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -92,8 +92,7 @@
#define FLASH_VREG_OK_FORCE(base) (base + 0x4F)
#define FLASH_ENABLE_CONTROL(base) (base + 0x46)
#define FLASH_LED_STROBE_CTRL(base) (base + 0x47)
-#define FLASH_LED_UNLOCK_SECURE(base) (base + 0xD0)
-#define FLASH_LED_TORCH(base) (base + 0xE4)
+#define FLASH_WATCHDOG_TMR(base) (base + 0x49)
#define FLASH_FAULT_DETECT(base) (base + 0x51)
#define FLASH_PERIPHERAL_SUBTYPE(base) (base + 0x05)
@@ -124,6 +123,7 @@
#define FLASH_ENABLE_LED_1 0xA0
#define FLASH_INIT_MASK 0xE0
#define FLASH_SELFCHECK_ENABLE 0x80
+#define FLASH_WATCHDOG_MASK 0x1F
#define FLASH_STROBE_SW 0xC0
#define FLASH_STROBE_HW 0x04
@@ -137,14 +137,9 @@
#define FLASH_CURRENT_TORCH 0x07
#define FLASH_DURATION_200ms 0x13
+#define TORCH_DURATION_12s 0x0A
#define FLASH_CLAMP_200mA 0x0F
-#define FLASH_TORCH_MASK 0x03
-#define FLASH_LED_TORCH_ENABLE 0x00
-#define FLASH_LED_TORCH_DISABLE 0x03
-#define FLASH_UNLOCK_SECURE 0xA5
-#define FLASH_SECURE_MASK 0xFF
-
#define FLASH_SUBTYPE_DUAL 0x01
#define FLASH_SUBTYPE_SINGLE 0x02
@@ -842,21 +837,24 @@ static int qpnp_flash_set(struct qpnp_led_data *led)
}
}
- rc = qpnp_led_masked_write(led,
- FLASH_LED_UNLOCK_SECURE(led->base),
- FLASH_SECURE_MASK, FLASH_UNLOCK_SECURE);
+ qpnp_led_masked_write(led, FLASH_MAX_CURR(led->base),
+ FLASH_CURRENT_MASK,
+ TORCH_MAX_LEVEL);
if (rc) {
dev_err(&led->spmi_dev->dev,
- "Secure reg write failed(%d)\n", rc);
+ "Max current reg write failed(%d)\n",
+ rc);
goto error_reg_write;
}
- rc = qpnp_led_masked_write(led,
- FLASH_LED_TORCH(led->base),
- FLASH_TORCH_MASK, FLASH_LED_TORCH_ENABLE);
+ qpnp_led_masked_write(led,
+ FLASH_LED_TMR_CTRL(led->base),
+ FLASH_TMR_MASK,
+ FLASH_TMR_WATCHDOG);
if (rc) {
dev_err(&led->spmi_dev->dev,
- "Torch reg write failed(%d)\n", rc);
+ "Timer control reg write failed(%d)\n",
+ rc);
goto error_reg_write;
}
@@ -881,9 +879,10 @@ static int qpnp_flash_set(struct qpnp_led_data *led)
goto error_reg_write;
}
- qpnp_led_masked_write(led, FLASH_MAX_CURR(led->base),
- FLASH_CURRENT_MASK,
- TORCH_MAX_LEVEL);
+ qpnp_led_masked_write(led,
+ FLASH_WATCHDOG_TMR(led->base),
+ FLASH_WATCHDOG_MASK,
+ led->flash_cfg->duration);
if (rc) {
dev_err(&led->spmi_dev->dev,
"Max current reg write failed(%d)\n",
@@ -921,6 +920,17 @@ static int qpnp_flash_set(struct qpnp_led_data *led)
goto error_flash_set;
}
+ qpnp_led_masked_write(led,
+ FLASH_LED_TMR_CTRL(led->base),
+ FLASH_TMR_MASK,
+ FLASH_TMR_SAFETY);
+ if (rc) {
+ dev_err(&led->spmi_dev->dev,
+ "Timer control reg write failed(%d)\n",
+ rc);
+ goto error_reg_write;
+ }
+
/* Set flash safety timer */
rc = qpnp_led_masked_write(led,
FLASH_SAFETY_TIMER(led->base),
@@ -1033,25 +1043,6 @@ static int qpnp_flash_set(struct qpnp_led_data *led)
}
if (led->flash_cfg->torch_enable) {
- rc = qpnp_led_masked_write(led,
- FLASH_LED_UNLOCK_SECURE(led->base),
- FLASH_SECURE_MASK, FLASH_UNLOCK_SECURE);
- if (rc) {
- dev_err(&led->spmi_dev->dev,
- "Secure reg write failed(%d)\n", rc);
- goto error_torch_set;
- }
-
- rc = qpnp_led_masked_write(led,
- FLASH_LED_TORCH(led->base),
- FLASH_TORCH_MASK,
- FLASH_LED_TORCH_DISABLE);
- if (rc) {
- dev_err(&led->spmi_dev->dev,
- "Torch reg write failed(%d)\n", rc);
- goto error_torch_set;
- }
-
if (led->flash_cfg->peripheral_subtype ==
FLASH_SUBTYPE_DUAL) {
rc = qpnp_torch_regulator_operate(led, false);
@@ -2612,23 +2603,52 @@ static int qpnp_get_config_flash(struct qpnp_led_data *led,
} else
led->flash_cfg->enable_module = FLASH_ENABLE_ALL;
led->flash_cfg->trigger_flash = FLASH_STROBE_SW;
- }
- rc = of_property_read_u32(node, "qcom,current", &val);
- if (!rc) {
- if (led->flash_cfg->torch_enable) {
+ rc = of_property_read_u32(node, "qcom,duration", &val);
+ if (!rc)
+ led->flash_cfg->duration = ((u8) val) - 2;
+ else if (rc == -EINVAL)
+ led->flash_cfg->duration = TORCH_DURATION_12s;
+ else {
+ if (led->flash_cfg->peripheral_subtype ==
+ FLASH_SUBTYPE_SINGLE)
+ goto error_get_flash_reg;
+ else if (led->flash_cfg->peripheral_subtype ==
+ FLASH_SUBTYPE_DUAL)
+ goto error_get_torch_reg;
+ }
+
+ rc = of_property_read_u32(node, "qcom,current", &val);
+ if (!rc)
led->flash_cfg->current_prgm = (val *
TORCH_MAX_LEVEL / led->max_current);
- return 0;
+ else {
+ if (led->flash_cfg->peripheral_subtype ==
+ FLASH_SUBTYPE_SINGLE)
+ goto error_get_flash_reg;
+ else if (led->flash_cfg->peripheral_subtype ==
+ FLASH_SUBTYPE_DUAL)
+ goto error_get_torch_reg;
+ goto error_get_torch_reg;
}
+
+ return 0;
+ } else {
+ rc = of_property_read_u32(node, "qcom,duration", &val);
+ if (!rc)
+ led->flash_cfg->duration = (((u8) val) - 10) / 10;
+ else if (rc == -EINVAL)
+ led->flash_cfg->duration = FLASH_DURATION_200ms;
else
+ goto error_get_flash_reg;
+
+ rc = of_property_read_u32(node, "qcom,current", &val);
+ if (!rc)
led->flash_cfg->current_prgm = (val *
FLASH_MAX_LEVEL / led->max_current);
- } else
- if (led->flash_cfg->torch_enable)
- goto error_get_torch_reg;
else
goto error_get_flash_reg;
+ }
rc = of_property_read_u32(node, "qcom,headroom", &val);
if (!rc)
@@ -2638,14 +2658,6 @@ static int qpnp_get_config_flash(struct qpnp_led_data *led,
else
goto error_get_flash_reg;
- rc = of_property_read_u32(node, "qcom,duration", &val);
- if (!rc)
- led->flash_cfg->duration = (((u8) val) - 10) / 10;
- else if (rc == -EINVAL)
- led->flash_cfg->duration = FLASH_DURATION_200ms;
- else
- goto error_get_flash_reg;
-
rc = of_property_read_u32(node, "qcom,clamp-curr", &val);
if (!rc)
led->flash_cfg->clamp_curr = (val *