summaryrefslogtreecommitdiff
path: root/drivers/leds/leds-qpnp-flash-v2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds/leds-qpnp-flash-v2.c')
-rw-r--r--drivers/leds/leds-qpnp-flash-v2.c62
1 files changed, 47 insertions, 15 deletions
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index b4ec36fd3cdf..c90633b16fad 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -319,7 +319,7 @@ static inline int get_current_reg_code(int target_curr_ma, int ires_ua)
if (!ires_ua || !target_curr_ma || (target_curr_ma < (ires_ua / 1000)))
return 0;
- return DIV_ROUND_UP(target_curr_ma * 1000, ires_ua) - 1;
+ return DIV_ROUND_CLOSEST(target_curr_ma * 1000, ires_ua) - 1;
}
static int qpnp_flash_led_read(struct qpnp_flash_led *led, u16 addr, u8 *data)
@@ -391,7 +391,7 @@ led_brightness qpnp_flash_led_brightness_get(struct led_classdev *led_cdev)
static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
{
int rc, i, addr_offset;
- u8 val = 0, mask;
+ u8 val = 0, mask, strobe_mask = 0, strobe_ctrl;
for (i = 0; i < led->num_fnodes; i++) {
addr_offset = led->fnode[i].id;
@@ -402,6 +402,51 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
return rc;
val |= 0x1 << led->fnode[i].id;
+
+ if (led->fnode[i].strobe_sel == HW_STROBE) {
+ if (led->fnode[i].id == LED3)
+ strobe_mask |= LED3_FLASH_ONCE_ONLY_BIT;
+ else
+ strobe_mask |= LED1N2_FLASH_ONCE_ONLY_BIT;
+ }
+
+ if (led->fnode[i].id == LED3 &&
+ led->fnode[i].strobe_sel == LPG_STROBE)
+ strobe_mask |= LED3_FLASH_ONCE_ONLY_BIT;
+ /*
+ * As per the hardware recommendation, to use LED2/LED3 in HW
+ * strobe mode, LED1 should be set to HW strobe mode as well.
+ */
+ if (led->fnode[i].strobe_sel == HW_STROBE &&
+ (led->fnode[i].id == LED2 || led->fnode[i].id == LED3)) {
+ mask = FLASH_HW_STROBE_MASK;
+ addr_offset = led->fnode[LED1].id;
+ /*
+ * HW_STROBE: enable, TRIGGER: level,
+ * POLARITY: active high
+ */
+ strobe_ctrl = BIT(2) | BIT(0);
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_STROBE_CTRL(
+ led->base + addr_offset),
+ mask, strobe_ctrl);
+ if (rc < 0)
+ return rc;
+ }
+ }
+
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_MULTI_STROBE_CTRL(led->base),
+ strobe_mask, 0);
+ if (rc < 0)
+ return rc;
+
+ if (led->fnode[LED3].strobe_sel == LPG_STROBE) {
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_LPG_INPUT_CTRL(led->base),
+ LPG_INPUT_SEL_BIT, LPG_INPUT_SEL_BIT);
+ if (rc < 0)
+ return rc;
}
rc = qpnp_flash_led_write(led,
@@ -595,19 +640,6 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
return rc;
}
- if (led->fnode[LED3].strobe_sel == LPG_STROBE) {
- rc = qpnp_flash_led_masked_write(led,
- FLASH_LED_REG_MULTI_STROBE_CTRL(led->base),
- LED3_FLASH_ONCE_ONLY_BIT, 0);
- if (rc < 0)
- return rc;
-
- rc = qpnp_flash_led_masked_write(led,
- FLASH_LED_REG_LPG_INPUT_CTRL(led->base),
- LPG_INPUT_SEL_BIT, LPG_INPUT_SEL_BIT);
- if (rc < 0)
- return rc;
- }
return 0;
}