diff --git a/drivers/leds/leds-qti-flash.c b/drivers/leds/leds-qti-flash.c index 6dec71bd306f..bbb9633106d1 100644 --- a/drivers/leds/leds-qti-flash.c +++ b/drivers/leds/leds-qti-flash.c @@ -346,13 +346,18 @@ static int qti_flash_lmh_mitigation_config(struct qti_flash_led *led, u8 val = enable ? FLASH_LED_LMH_MITIGATION_SW_EN : 0; int rc; + if (enable == led->trigger_lmh) + return 0; + rc = qti_flash_led_write(led, FLASH_LED_MITIGATION_SW, &val, 1); - if (rc < 0) + if (rc < 0) { pr_err("Failed to %s LMH mitigation, rc=%d\n", enable ? "enable" : "disable", rc); - else + } else { pr_debug("%s LMH mitigation\n", enable ? "enabled" : "disabled"); + led->trigger_lmh = enable; + } return rc; } @@ -383,15 +388,6 @@ static int qti_flash_led_strobe(struct qti_flash_led *led, HRTIMER_MODE_REL); } - if (led->trigger_lmh) { - rc = qti_flash_lmh_mitigation_config(led, true); - if (rc < 0) - goto error; - - /* Wait for LMH mitigation to take effect */ - udelay(500); - } - rc = qti_flash_led_masked_write(led, FLASH_EN_LED_CTRL, mask, value); if (rc < 0) @@ -411,8 +407,6 @@ static int qti_flash_led_strobe(struct qti_flash_led *led, rc = qti_flash_lmh_mitigation_config(led, false); if (rc < 0) goto error; - - led->trigger_lmh = false; } rc = qti_flash_led_module_control(led, enable); @@ -680,10 +674,13 @@ static void qti_flash_led_brightness_set(struct led_classdev *led_cdev, } } +#define FLASH_LMH_TRIGGER_LIMIT_MA 1000 + static int qti_flash_switch_enable(struct flash_switch_data *snode) { struct qti_flash_led *led = snode->led; - int rc = 0, i; + int rc = 0, total_curr_ma = 0, i; + enum flash_led_type type = FLASH_LED_TYPE_UNKNOWN; u8 led_en = 0; /* If symmetry enabled switch, then turn ON all its LEDs */ @@ -706,9 +703,32 @@ static int qti_flash_switch_enable(struct flash_switch_data *snode) !led->fnode[i].configured) continue; + /* + * For flash, LMH mitigation needs to be enabled + * if total current used is greater than or + * equal to 1A. + */ + + type = led->fnode[i].type; + if (type == FLASH_LED_TYPE_FLASH) + total_curr_ma += led->fnode[i].user_current_ma; + led_en |= (1 << led->fnode[i].id); } + if (total_curr_ma >= FLASH_LMH_TRIGGER_LIMIT_MA) { + rc = qti_flash_lmh_mitigation_config(led, true); + if (rc < 0) + return rc; + + /* Wait for lmh mitigation to take effect */ + udelay(500); + } else if (led->trigger_lmh) { + rc = qti_flash_lmh_mitigation_config(led, false); + if (rc < 0) + return rc; + } + return qti_flash_led_strobe(led, snode, snode->led_mask, led_en); } @@ -957,19 +977,6 @@ static int qti_flash_led_calc_max_avail_current( voltage_hdrm_mv = qti_flash_led_get_voltage_headroom(led); vflash_vdip = VDIP_THRESH_DEFAULT_UV; - if (!led->trigger_lmh) { - rc = qti_flash_lmh_mitigation_config(led, true); - if (rc < 0) - return rc; - - /* Wait for lmh mitigation to take effect */ - udelay(100); - - led->trigger_lmh = true; - return qti_flash_led_calc_max_avail_current(led, - max_current_ma); - } - ibatt_safe_ua = DIV_ROUND_CLOSEST((ocv_uv - (vflash_vdip + VFLASH_DIP_MARGIN_UV)) * UCONV, rbatt_uohm); @@ -1051,7 +1058,6 @@ static int qti_flash_led_get_max_avail_current( return 0; } - led->trigger_lmh = false; rc = qti_flash_led_calc_max_avail_current(led, max_current_ma); if (rc < 0) { pr_err("Failed to calculate max avail current, rc=%d\n", rc);