Loading drivers/leds/leds-qti-flash.c +66 −24 Original line number Diff line number Diff line Loading @@ -140,7 +140,8 @@ struct pmic_data { * @all_ramp_down_done_irq : IRQ number for all ramp down interrupt * @led_fault_irq : IRQ number for LED fault interrupt * @base : Base address of the flash LED 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 */ struct qti_flash_led { struct platform_device *pdev; Loading @@ -161,8 +162,9 @@ struct qti_flash_led { int ibatt_ocp_threshold_ua; int max_current; u16 base; u8 ref_count; u8 subtype; u8 chan_en_map; bool module_en; }; static const u32 flash_led_max_ires_values[MAX_IRES_LEVELS] = { Loading Loading @@ -313,7 +315,7 @@ 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); Loading @@ -330,18 +332,15 @@ static int qti_flash_led_module_control(struct qti_flash_led *led, return rc; } led->ref_count++; } else { if (led->ref_count) led->ref_count--; if (!led->ref_count) { led->module_en = true; } else 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; } return rc; Loading @@ -350,12 +349,17 @@ static int qti_flash_led_module_control(struct qti_flash_led *led, static int qti_flash_led_strobe(struct qti_flash_led *led, u8 mask, u8 value) { int rc; int rc, i; bool enable = mask & value; spin_lock(&led->lock); if (enable) { for (i = 0; i < led->data->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; Loading @@ -365,6 +369,11 @@ static int qti_flash_led_strobe(struct qti_flash_led *led, if (rc < 0) goto error; } else { for (i = 0; i < led->data->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) Loading Loading @@ -448,6 +457,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 0; spin_lock(&led->lock); if ((fnode->strobe_sel == HW_STROBE) && gpio_is_valid(led->hw_strobe_gpio[fnode->id])) Loading @@ -471,6 +483,7 @@ static int qti_flash_led_disable(struct flash_node_data *fnode) goto out; } fnode->configured = false; fnode->current_ma = 0; out: Loading Loading @@ -498,10 +511,15 @@ 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_strobe(fnode->led, FLASH_LED_ENABLE(fnode->id), 0); if (rc < 0) pr_err("Failed to destrobe LED, rc=%d\n", rc); rc = qti_flash_led_disable(fnode); if (rc < 0) pr_err("Failed to set brightness %d to LED\n", pr_err("Failed to disable %d LED\n", brightness); return; } Loading Loading @@ -622,6 +640,21 @@ static int qti_flash_switch_disable(struct flash_switch_data *snode) int rc = 0, i; u8 led_dis = 0; for (i = 0; i < led->num_fnodes; i++) { if (!(snode->led_mask & BIT(led->fnode[i].id)) || !led->fnode[i].configured) continue; led_dis |= BIT(led->fnode[i].id); } rc = qti_flash_led_strobe(led, led_dis, ~led_dis); if (rc < 0) { pr_err("Failed to destrobe LEDs under with switch, rc=%d\n", rc); return rc; } for (i = 0; i < led->num_fnodes; i++) { /* * Do not turn OFF flash/torch device if Loading @@ -639,11 +672,9 @@ static int qti_flash_switch_disable(struct flash_switch_data *snode) break; } led_dis |= (1 << led->fnode[i].id); led->fnode[i].configured = false; } return qti_flash_led_strobe(led, led_dis, ~led_dis); return rc; } static void qti_flash_led_switch_brightness_set( Loading Loading @@ -1020,14 +1051,25 @@ static int qti_flash_strobe_set(struct led_classdev_flash *fdev, if (fnode->enabled == state) return 0; if (state && !fnode->configured) return -EINVAL; mask = FLASH_LED_ENABLE(fnode->id); value = state ? FLASH_LED_ENABLE(fnode->id) : 0; rc = qti_flash_led_strobe(fnode->led, mask, value); if (!rc) { if (rc < 0) { pr_err("Failed to %s LED, rc=%d\n", state ? "strobe" : "desrobe", rc); return rc; } fnode->enabled = state; if (!state) fnode->configured = false; if (!state) { rc = qti_flash_led_disable(fnode); if (rc < 0) pr_err("Failed to disable LED %u\n", fnode->id); } return rc; Loading Loading
drivers/leds/leds-qti-flash.c +66 −24 Original line number Diff line number Diff line Loading @@ -140,7 +140,8 @@ struct pmic_data { * @all_ramp_down_done_irq : IRQ number for all ramp down interrupt * @led_fault_irq : IRQ number for LED fault interrupt * @base : Base address of the flash LED 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 */ struct qti_flash_led { struct platform_device *pdev; Loading @@ -161,8 +162,9 @@ struct qti_flash_led { int ibatt_ocp_threshold_ua; int max_current; u16 base; u8 ref_count; u8 subtype; u8 chan_en_map; bool module_en; }; static const u32 flash_led_max_ires_values[MAX_IRES_LEVELS] = { Loading Loading @@ -313,7 +315,7 @@ 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); Loading @@ -330,18 +332,15 @@ static int qti_flash_led_module_control(struct qti_flash_led *led, return rc; } led->ref_count++; } else { if (led->ref_count) led->ref_count--; if (!led->ref_count) { led->module_en = true; } else 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; } return rc; Loading @@ -350,12 +349,17 @@ static int qti_flash_led_module_control(struct qti_flash_led *led, static int qti_flash_led_strobe(struct qti_flash_led *led, u8 mask, u8 value) { int rc; int rc, i; bool enable = mask & value; spin_lock(&led->lock); if (enable) { for (i = 0; i < led->data->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; Loading @@ -365,6 +369,11 @@ static int qti_flash_led_strobe(struct qti_flash_led *led, if (rc < 0) goto error; } else { for (i = 0; i < led->data->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) Loading Loading @@ -448,6 +457,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 0; spin_lock(&led->lock); if ((fnode->strobe_sel == HW_STROBE) && gpio_is_valid(led->hw_strobe_gpio[fnode->id])) Loading @@ -471,6 +483,7 @@ static int qti_flash_led_disable(struct flash_node_data *fnode) goto out; } fnode->configured = false; fnode->current_ma = 0; out: Loading Loading @@ -498,10 +511,15 @@ 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_strobe(fnode->led, FLASH_LED_ENABLE(fnode->id), 0); if (rc < 0) pr_err("Failed to destrobe LED, rc=%d\n", rc); rc = qti_flash_led_disable(fnode); if (rc < 0) pr_err("Failed to set brightness %d to LED\n", pr_err("Failed to disable %d LED\n", brightness); return; } Loading Loading @@ -622,6 +640,21 @@ static int qti_flash_switch_disable(struct flash_switch_data *snode) int rc = 0, i; u8 led_dis = 0; for (i = 0; i < led->num_fnodes; i++) { if (!(snode->led_mask & BIT(led->fnode[i].id)) || !led->fnode[i].configured) continue; led_dis |= BIT(led->fnode[i].id); } rc = qti_flash_led_strobe(led, led_dis, ~led_dis); if (rc < 0) { pr_err("Failed to destrobe LEDs under with switch, rc=%d\n", rc); return rc; } for (i = 0; i < led->num_fnodes; i++) { /* * Do not turn OFF flash/torch device if Loading @@ -639,11 +672,9 @@ static int qti_flash_switch_disable(struct flash_switch_data *snode) break; } led_dis |= (1 << led->fnode[i].id); led->fnode[i].configured = false; } return qti_flash_led_strobe(led, led_dis, ~led_dis); return rc; } static void qti_flash_led_switch_brightness_set( Loading Loading @@ -1020,14 +1051,25 @@ static int qti_flash_strobe_set(struct led_classdev_flash *fdev, if (fnode->enabled == state) return 0; if (state && !fnode->configured) return -EINVAL; mask = FLASH_LED_ENABLE(fnode->id); value = state ? FLASH_LED_ENABLE(fnode->id) : 0; rc = qti_flash_led_strobe(fnode->led, mask, value); if (!rc) { if (rc < 0) { pr_err("Failed to %s LED, rc=%d\n", state ? "strobe" : "desrobe", rc); return rc; } fnode->enabled = state; if (!state) fnode->configured = false; if (!state) { rc = qti_flash_led_disable(fnode); if (rc < 0) pr_err("Failed to disable LED %u\n", fnode->id); } return rc; Loading