Loading drivers/leds/leds-qpnp-flash-v2.c +68 −3 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <linux/log2.h> #include "leds.h" #define FLASH_LED_REG_PERPH_SUBTYPE(base) (base + 0x05) #define FLASH_LED_REG_LED_STATUS1(base) (base + 0x08) #define FLASH_LED_REG_LED_STATUS2(base) (base + 0x09) Loading Loading @@ -133,6 +135,9 @@ #define FLASH_LED_REG_CURRENT_DERATE_EN(base) (base + 0x76) #define FLASH_LED_CURRENT_DERATE_EN_MASK GENMASK(2, 0) #define FLASH_LED_REG_CHICKEN_BITS(base) (base + 0x87) #define FLASH_LED_EN_ITAR_FLY_BIT BIT(0) #define VPH_DROOP_DEBOUNCE_US_TO_VAL(val_us) (val_us / 8) #define VPH_DROOP_HYST_MV_TO_VAL(val_mv) (val_mv / 25) #define VPH_DROOP_THRESH_VAL_TO_UV(val) ((val + 25) * 100000) Loading Loading @@ -196,6 +201,13 @@ /* notifier call chain for flash-led irqs */ static ATOMIC_NOTIFIER_HEAD(irq_notifier_list); enum flash_led_subtype { PMI8998_FLASH_SUBTYPE = 3, PM660L_FLASH_SUBTYPE = 3, PM6150L_FLASH_SUBTYPE, PMI632_FLASH_SUBTYPE, }; enum flash_charger_mitigation { FLASH_DISABLE_CHARGER_MITIGATION, FLASH_HW_CHARGER_MITIGATION_BY_ILED_THRSHLD, Loading Loading @@ -331,6 +343,7 @@ struct qpnp_flash_led { u16 base; bool trigger_lmh; bool trigger_chgr; bool torch_current_update; }; static int thermal_derate_slow_table[] = { Loading Loading @@ -702,6 +715,27 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led) if (rc < 0) return rc; rc = qpnp_flash_led_read(led, FLASH_LED_REG_PERPH_SUBTYPE(led->base), &val); if (rc < 0) return rc; /* * Updating torch current on-the-fly is possible * from PM6150L onwards. */ if (val >= PM6150L_FLASH_SUBTYPE) { rc = qpnp_flash_led_masked_read(led, FLASH_LED_REG_CHICKEN_BITS(led->base), FLASH_LED_EN_ITAR_FLY_BIT, &val); if (rc < 0) return rc; led->torch_current_update = !!val; } if (led->pdata->led1n2_iclamp_low_ma) { val = get_current_reg_code(led->pdata->led1n2_iclamp_low_ma, led->fnode[LED1].ires_ua); Loading Loading @@ -1580,14 +1614,29 @@ static int qpnp_flash_led_module_enable(struct flash_switch_data *snode) static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) { struct qpnp_flash_led *led = dev_get_drvdata(&snode->pdev->dev); struct flash_node_data fnode; int rc, i, addr_offset; u8 val, mask; bool torch_current_update = false; if (snode->enabled == on) { if (on && led->torch_current_update) { for (i = 0; i < led->num_fnodes; i++) { fnode = led->fnode[i]; if (snode->led_mask & BIT(fnode.id) && fnode.led_on) { torch_current_update = (fnode.type == FLASH_LED_TYPE_TORCH); } } } if (!torch_current_update) { pr_debug("Switch node is already %s!\n", on ? "enabled" : "disabled"); return 0; } } if (!on) { rc = qpnp_flash_led_switch_disable(snode); Loading Loading @@ -1615,6 +1664,22 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) if (rc < 0) return rc; if (torch_current_update) { for (i = 0; i < led->num_fnodes; i++) { if (snode->led_mask & BIT(led->fnode[i].id) && led->fnode[i].led_on) { addr_offset = led->fnode[i].id; rc = qpnp_flash_led_masked_write(led, FLASH_LED_REG_TGR_CURRENT(led->base + addr_offset), FLASH_LED_CURRENT_MASK, led->fnode[i].current_reg_val); if (rc < 0) return rc; } } return 0; } val = 0; for (i = 0; i < led->num_fnodes; i++) { if (!led->fnode[i].led_on || Loading Loading
drivers/leds/leds-qpnp-flash-v2.c +68 −3 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <linux/log2.h> #include "leds.h" #define FLASH_LED_REG_PERPH_SUBTYPE(base) (base + 0x05) #define FLASH_LED_REG_LED_STATUS1(base) (base + 0x08) #define FLASH_LED_REG_LED_STATUS2(base) (base + 0x09) Loading Loading @@ -133,6 +135,9 @@ #define FLASH_LED_REG_CURRENT_DERATE_EN(base) (base + 0x76) #define FLASH_LED_CURRENT_DERATE_EN_MASK GENMASK(2, 0) #define FLASH_LED_REG_CHICKEN_BITS(base) (base + 0x87) #define FLASH_LED_EN_ITAR_FLY_BIT BIT(0) #define VPH_DROOP_DEBOUNCE_US_TO_VAL(val_us) (val_us / 8) #define VPH_DROOP_HYST_MV_TO_VAL(val_mv) (val_mv / 25) #define VPH_DROOP_THRESH_VAL_TO_UV(val) ((val + 25) * 100000) Loading Loading @@ -196,6 +201,13 @@ /* notifier call chain for flash-led irqs */ static ATOMIC_NOTIFIER_HEAD(irq_notifier_list); enum flash_led_subtype { PMI8998_FLASH_SUBTYPE = 3, PM660L_FLASH_SUBTYPE = 3, PM6150L_FLASH_SUBTYPE, PMI632_FLASH_SUBTYPE, }; enum flash_charger_mitigation { FLASH_DISABLE_CHARGER_MITIGATION, FLASH_HW_CHARGER_MITIGATION_BY_ILED_THRSHLD, Loading Loading @@ -331,6 +343,7 @@ struct qpnp_flash_led { u16 base; bool trigger_lmh; bool trigger_chgr; bool torch_current_update; }; static int thermal_derate_slow_table[] = { Loading Loading @@ -702,6 +715,27 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led) if (rc < 0) return rc; rc = qpnp_flash_led_read(led, FLASH_LED_REG_PERPH_SUBTYPE(led->base), &val); if (rc < 0) return rc; /* * Updating torch current on-the-fly is possible * from PM6150L onwards. */ if (val >= PM6150L_FLASH_SUBTYPE) { rc = qpnp_flash_led_masked_read(led, FLASH_LED_REG_CHICKEN_BITS(led->base), FLASH_LED_EN_ITAR_FLY_BIT, &val); if (rc < 0) return rc; led->torch_current_update = !!val; } if (led->pdata->led1n2_iclamp_low_ma) { val = get_current_reg_code(led->pdata->led1n2_iclamp_low_ma, led->fnode[LED1].ires_ua); Loading Loading @@ -1580,14 +1614,29 @@ static int qpnp_flash_led_module_enable(struct flash_switch_data *snode) static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) { struct qpnp_flash_led *led = dev_get_drvdata(&snode->pdev->dev); struct flash_node_data fnode; int rc, i, addr_offset; u8 val, mask; bool torch_current_update = false; if (snode->enabled == on) { if (on && led->torch_current_update) { for (i = 0; i < led->num_fnodes; i++) { fnode = led->fnode[i]; if (snode->led_mask & BIT(fnode.id) && fnode.led_on) { torch_current_update = (fnode.type == FLASH_LED_TYPE_TORCH); } } } if (!torch_current_update) { pr_debug("Switch node is already %s!\n", on ? "enabled" : "disabled"); return 0; } } if (!on) { rc = qpnp_flash_led_switch_disable(snode); Loading Loading @@ -1615,6 +1664,22 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) if (rc < 0) return rc; if (torch_current_update) { for (i = 0; i < led->num_fnodes; i++) { if (snode->led_mask & BIT(led->fnode[i].id) && led->fnode[i].led_on) { addr_offset = led->fnode[i].id; rc = qpnp_flash_led_masked_write(led, FLASH_LED_REG_TGR_CURRENT(led->base + addr_offset), FLASH_LED_CURRENT_MASK, led->fnode[i].current_reg_val); if (rc < 0) return rc; } } return 0; } val = 0; for (i = 0; i < led->num_fnodes; i++) { if (!led->fnode[i].led_on || Loading