leds: qti-flash: Disable flash LED when brightness is set to 0

Disable the flash LED channel when a brightness of 0 is set.

As flash/torch devices can be enabled and disabled using switch as well
as from sysfs, reset the state of flash/torch devices when they are
disabled instead of doing it in switch disable.

Change-Id: If8ffb22d8c72a94325a1e9237778b810a152a293
Signed-off-by: Shyam Kumar Thella <sthella@codeaurora.org>
This commit is contained in:
Shyam Kumar Thella 2020-05-15 12:13:28 +05:30 committed by David Collins
parent 1581b111c3
commit b8d85a03a6

View File

@ -162,7 +162,8 @@ struct flash_switch_data {
* @revision : Revision of the flash LED module
* @subtype : Peripheral subtype of the flash LED module
* @max_channels : Maximum number of channels supported by flash module
* @ref_count : Reference count used to enable/disable flash LED
* @chan_en_map : Bit map of individual channel enable
* @module_en : Flag used to enable/disable flash LED module
* @trigger_lmh : Flag to enable lmh mitigation
*/
struct qti_flash_led {
@ -184,7 +185,8 @@ struct qti_flash_led {
u8 revision;
u8 subtype;
u8 max_channels;
u8 ref_count;
u8 chan_en_map;
bool module_en;
bool trigger_lmh;
};
@ -289,25 +291,24 @@ static int qti_flash_led_module_control(struct qti_flash_led *led,
u8 val;
if (enable) {
if (!led->ref_count) {
if (!led->module_en && led->chan_en_map) {
val = FLASH_MODULE_ENABLE;
rc = qti_flash_led_write(led, FLASH_ENABLE_CONTROL,
&val, 1);
if (rc < 0)
return rc;
led->module_en = true;
}
led->ref_count++;
} else {
if (led->ref_count)
led->ref_count--;
if (!led->ref_count) {
if (led->module_en && !led->chan_en_map) {
val = FLASH_MODULE_DISABLE;
rc = qti_flash_led_write(led, FLASH_ENABLE_CONTROL,
&val, 1);
if (rc < 0)
return rc;
led->module_en = false;
}
}
@ -318,12 +319,16 @@ static int qti_flash_led_strobe(struct qti_flash_led *led,
struct flash_switch_data *snode,
u8 mask, u8 value)
{
int rc;
int rc, i;
bool enable = mask & value;
spin_lock(&led->lock);
if (enable) {
for (i = 0; i < led->max_channels; i++)
if ((mask & BIT(i)) && (value & BIT(i)))
led->chan_en_map |= BIT(i);
rc = qti_flash_led_module_control(led, enable);
if (rc < 0)
goto error;
@ -341,6 +346,11 @@ static int qti_flash_led_strobe(struct qti_flash_led *led,
if (rc < 0)
goto error;
} else {
for (i = 0; i < led->max_channels; i++)
if ((led->chan_en_map & BIT(i)) &&
(mask & BIT(i)) && !(value & BIT(i)))
led->chan_en_map &= ~(BIT(i));
rc = qti_flash_led_masked_write(led, FLASH_EN_LED_CTRL,
mask, value);
if (rc < 0)
@ -411,6 +421,9 @@ static int qti_flash_led_disable(struct flash_node_data *fnode)
struct qti_flash_led *led = fnode->led;
int rc;
if (!fnode->configured)
return -EINVAL;
spin_lock(&led->lock);
if ((fnode->strobe_sel == HW_STROBE) &&
gpio_is_valid(led->hw_strobe_gpio[fnode->id]))
@ -427,6 +440,7 @@ static int qti_flash_led_disable(struct flash_node_data *fnode)
if (rc < 0)
goto out;
fnode->configured = false;
fnode->current_ma = 0;
out:
@ -454,11 +468,19 @@ static void qti_flash_led_brightness_set(struct led_classdev *led_cdev,
fnode = container_of(fdev, struct flash_node_data, fdev);
led = fnode->led;
if (brightness <= 0) {
if (!brightness) {
rc = qti_flash_led_disable(fnode);
if (rc < 0)
if (rc < 0) {
pr_err("Failed to set brightness %d to LED\n",
brightness);
return;
}
rc = qti_flash_led_strobe(fnode->led, NULL,
FLASH_LED_ENABLE(fnode->id), 0);
if (rc < 0)
pr_err("Failed to destrobe LED, rc=%d\n", rc);
return;
}
@ -596,7 +618,6 @@ static int qti_flash_switch_disable(struct flash_switch_data *snode)
}
led_dis |= (1 << led->fnode[i].id);
led->fnode[i].configured = false;
}
snode->on_time_ms = 0;