From 1a91cd330ab34d281c4c07732cd3bf9c7cfa3bdb Mon Sep 17 00:00:00 2001 From: Kiran Gunda Date: Tue, 27 Mar 2018 14:54:29 +0530 Subject: [PATCH 1/2] leds: qpnp-flash-v2: Add support for multi-strobe Multi-strobe option is used to enable/disable the LEDs back-to-back without disabling the module in the HW_STROBE mode. Hence, enable the multi-strobe option if the LED is configured in HW_STROBE mode. Change-Id: I3e16254c6dcb4c4ae0b295cd7eea4e8ee8e1c2c7 Signed-off-by: Kiran Gunda --- drivers/leds/leds-qpnp-flash-v2.c | 40 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c index b4ec36fd3cdf..a6739743efc2 100644 --- a/drivers/leds/leds-qpnp-flash-v2.c +++ b/drivers/leds/leds-qpnp-flash-v2.c @@ -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; for (i = 0; i < led->num_fnodes; i++) { addr_offset = led->fnode[i].id; @@ -402,6 +402,31 @@ 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; + } + + 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 +620,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; } From 2db4db75bf2d93688b877c027c2d910b6d9e58b9 Mon Sep 17 00:00:00 2001 From: Kiran Gunda Date: Tue, 27 Mar 2018 18:35:00 +0530 Subject: [PATCH 2/2] leds: qpnp-flash-v2: Fix HW_STROBE configuration As per the hardware recommendation, configure the LED1 to HW_STROBE mode when LED2 or LED3 is configured in HW_STROBE mode. This enables hardware strobe option working for LED2/3 channels. CRs-Fixed: 2213325 Change-Id: I1ceaa7477b8d0c18e03fbdea9d5347d0e75fc0f0 Signed-off-by: Kiran Gunda --- drivers/leds/leds-qpnp-flash-v2.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c index a6739743efc2..a58775953242 100644 --- a/drivers/leds/leds-qpnp-flash-v2.c +++ b/drivers/leds/leds-qpnp-flash-v2.c @@ -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, strobe_mask = 0; + u8 val = 0, mask, strobe_mask = 0, strobe_ctrl; for (i = 0; i < led->num_fnodes; i++) { addr_offset = led->fnode[i].id; @@ -413,6 +413,26 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led) 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,