Loading drivers/leds/leds-qpnp-flash.c +188 −177 Original line number Diff line number Diff line Loading @@ -175,6 +175,7 @@ struct flash_node_data { u32 boost_voltage_max; u16 max_current; u16 prgm_current; u16 prgm_current2; u16 duration; u8 id; u8 type; Loading Loading @@ -251,7 +252,7 @@ struct qpnp_flash_led { static u8 qpnp_flash_led_ctrl_dbg_regs[] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x4F, 0x51, 0x52, 0x54, 0x55, 0x5A 0x4A, 0x4B, 0x4C, 0x4F, 0x51, 0x52, 0x54, 0x55, 0x5A, 0x5C, 0x5D, }; static int flash_led_dbgfs_file_open(struct qpnp_flash_led *led, Loading Loading @@ -897,8 +898,22 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, struct flash_node_data *flash_node) { union power_supply_propval psy_prop; int rc, i; int rc; u8 val, tmp; rc = spmi_ext_register_readl(led->spmi_dev->ctrl, led->spmi_dev->sid, FLASH_LED_STROBE_CTRL(led->base), &val, 1); if (rc) { dev_err(&led->spmi_dev->dev, "Unable to read strobe reg\n"); return -EINVAL; } tmp = (~flash_node->trigger) & val; if (!tmp) { if (flash_node->type == TORCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_UNLOCK_SECURE(led->base), FLASH_SECURE_MASK, FLASH_UNLOCK_SECURE); Loading @@ -916,29 +931,6 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, "Torch reg write failed\n"); return -EINVAL; } if (led->pdata->hdrm_sns_ch0_en) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); return rc; } } if (led->pdata->hdrm_sns_ch1_en) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); return rc; } } rc = qpnp_led_masked_write(led->spmi_dev, Loading @@ -946,7 +938,8 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, FLASH_MODULE_ENABLE_MASK, FLASH_LED_MODULE_CTRL_DEFAULT); if (rc) { dev_err(&led->spmi_dev->dev, "Module disable failed\n"); dev_err(&led->spmi_dev->dev, "Module disable failed\n"); return -EINVAL; } Loading @@ -972,9 +965,9 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, return -EINVAL; } } } if (!led->flash_node[0].flash_on && !led->flash_node[2].flash_on) { if (flash_node->trigger & FLASH_LED0_TRIGGER) { rc = qpnp_led_masked_write(led->spmi_dev, led->current_addr, FLASH_CURRENT_MASK, 0x00); Loading @@ -983,10 +976,10 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, "current register write failed\n"); return -EINVAL; } } if (!led->flash_node[1].flash_on && !led->flash_node[3].flash_on) { if (flash_node->trigger & FLASH_LED1_TRIGGER) { rc = qpnp_led_masked_write(led->spmi_dev, led->current2_addr, FLASH_CURRENT_MASK, 0x00); Loading @@ -997,8 +990,8 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, } } for (i = 0; i < led->num_leds; i++) led->flash_node[i].flash_on = false; if (flash_node->id == FLASH_LED_SWITCH) flash_node->trigger = 0; return 0; } Loading @@ -1018,6 +1011,7 @@ static void qpnp_flash_led_work(struct work_struct *work) union power_supply_propval psy_prop; int rc, brightness = flash_node->cdev.brightness; int max_curr_avail_ma = 0; int total_curr_ma = 0; int i; u8 val; Loading Loading @@ -1096,11 +1090,7 @@ static void qpnp_flash_led_work(struct work_struct *work) } } if (((led->flash_node[2].flash_on || led->flash_node[3].flash_on) && !led->flash_node[0].flash_on && !led->flash_node[1].flash_on) || flash_node->type == TORCH) { if (flash_node->type == TORCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_UNLOCK_SECURE(led->base), FLASH_SECURE_MASK, FLASH_UNLOCK_SECURE); Loading @@ -1118,15 +1108,11 @@ static void qpnp_flash_led_work(struct work_struct *work) "Torch reg write failed\n"); goto exit_flash_led_work; } if (led->flash_node[led->num_leds - 1].id == FLASH_LED_SWITCH) { flash_node->trigger = 0; if (led->flash_node[2].flash_on) flash_node->trigger |= FLASH_LED0_TRIGGER; val = (u8)(led->flash_node[2].prgm_current * if (flash_node->id == FLASH_LED_SWITCH) { val = (u8)(flash_node->prgm_current * FLASH_TORCH_MAX_LEVEL / led->flash_node[2].max_current); / flash_node->max_current); rc = qpnp_led_masked_write(led->spmi_dev, led->current_addr, FLASH_CURRENT_MASK, val); Loading @@ -1136,12 +1122,9 @@ static void qpnp_flash_led_work(struct work_struct *work) goto exit_flash_led_work; } if (led->flash_node[3].flash_on) flash_node->trigger |= FLASH_LED1_TRIGGER; val = (u8)(led->flash_node[3].prgm_current * val = (u8)(flash_node->prgm_current2 * FLASH_TORCH_MAX_LEVEL / led->flash_node[3].max_current); / flash_node->max_current); rc = qpnp_led_masked_write(led->spmi_dev, led->current2_addr, FLASH_CURRENT_MASK, val); Loading Loading @@ -1193,46 +1176,49 @@ static void qpnp_flash_led_work(struct work_struct *work) goto exit_flash_led_work; } if (led->pdata->hdrm_sns_ch0_en) { if (led->flash_node[2].flash_on) { if (led->pdata->hdrm_sns_ch0_en || led->pdata->hdrm_sns_ch1_en) { if (flash_node->id == FLASH_LED_SWITCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_ENABLE); flash_node->trigger & FLASH_LED0_TRIGGER ? FLASH_LED_HDRM_SNS_ENABLE : FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense enable failed\n"); goto exit_flash_led_work; } } else { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, flash_node->trigger & FLASH_LED1_TRIGGER ? FLASH_LED_HDRM_SNS_ENABLE : FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); "Headroom sense enable failed\n"); goto exit_flash_led_work; } } } if (led->pdata->hdrm_sns_ch1_en) { if (led->flash_node[3].flash_on) { } else if (flash_node->id == FLASH_LED_0) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_ENABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense enable failed\n"); "Headroom sense disable failed\n"); goto exit_flash_led_work; } } else { } else if (flash_node->id == FLASH_LED_1) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); FLASH_LED_HDRM_SNS_ENABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); Loading @@ -1243,22 +1229,19 @@ static void qpnp_flash_led_work(struct work_struct *work) rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_STROBE_CTRL(led->base), FLASH_STROBE_MASK, (flash_node->id == FLASH_LED_SWITCH ? FLASH_STROBE_MASK : flash_node->trigger), flash_node->trigger); if (rc) { dev_err(&led->spmi_dev->dev, "Strobe ctrl reg write failed\n"); "Strobe reg write failed\n"); goto exit_flash_led_work; } } else if (((led->flash_node[0].flash_on || led->flash_node[1].flash_on) && !led->flash_node[2].flash_on && !led->flash_node[3].flash_on) || flash_node->type == FLASH) { if (led->flash_node[0].flash_on) max_curr_avail_ma += led->flash_node[0].max_current; if (led->flash_node[1].flash_on) max_curr_avail_ma += led->flash_node[1].max_current; } else if (flash_node->type == FLASH) { if (flash_node->trigger & FLASH_LED0_TRIGGER) max_curr_avail_ma += flash_node->max_current; if (flash_node->trigger & FLASH_LED1_TRIGGER) max_curr_avail_ma += flash_node->max_current; psy_prop.intval = true; rc = led->battery_psy->set_property(led->battery_psy, Loading Loading @@ -1301,63 +1284,33 @@ static void qpnp_flash_led_work(struct work_struct *work) } } if (led->flash_node[led->num_leds - 1].id == FLASH_LED_SWITCH) { flash_node->trigger = 0; if (led->flash_node[0].flash_on && led->flash_node[1].flash_on) { if (max_curr_avail_ma < flash_node->prgm_current) { led->flash_node[0].prgm_current = led->flash_node[0].prgm_current * max_curr_avail_ma / flash_node->prgm_current; led->flash_node[1].prgm_current = led->flash_node[1].prgm_current * max_curr_avail_ma / flash_node->prgm_current; } flash_node->trigger = FLASH_LED0_TRIGGER | FLASH_LED1_TRIGGER; } else { if (led->flash_node[0].flash_on) flash_node->trigger |= FLASH_LED0_TRIGGER; if (flash_node->id == FLASH_LED_SWITCH) { if (flash_node->trigger & FLASH_LED0_TRIGGER) total_curr_ma += flash_node->prgm_current; else if (flash_node->trigger & FLASH_LED1_TRIGGER) total_curr_ma += flash_node->prgm_current2; led->flash_node[0].prgm_current = (max_curr_avail_ma < led->flash_node[0].prgm_current) ? max_curr_avail_ma : led->flash_node[0].prgm_current; if (max_curr_avail_ma < total_curr_ma) { flash_node->prgm_current *= max_curr_avail_ma / total_curr_ma; flash_node->prgm_current2 *= max_curr_avail_ma / total_curr_ma; } if (led->flash_node[1].flash_on) flash_node->trigger |= FLASH_LED1_TRIGGER; led->flash_node[1].prgm_current = (max_curr_avail_ma < led->flash_node[1].prgm_current) ? max_curr_avail_ma : led->flash_node[1].prgm_current; } val = (u8)(led->flash_node[0].prgm_current * FLASH_MAX_LEVEL / led->flash_node[0].max_current); val = (u8)(flash_node->prgm_current * FLASH_MAX_LEVEL / flash_node->max_current); rc = qpnp_led_masked_write(led->spmi_dev, led->current_addr, FLASH_CURRENT_MASK, val); led->current_addr, FLASH_CURRENT_MASK, val); if (rc) { dev_err(&led->spmi_dev->dev, "Current register write failed\n"); goto exit_flash_led_work; } val = (u8)(led->flash_node[1].prgm_current * FLASH_MAX_LEVEL / led->flash_node[1].max_current); val = (u8)(flash_node->prgm_current2 * FLASH_MAX_LEVEL / flash_node->max_current); rc = qpnp_led_masked_write(led->spmi_dev, led->current2_addr, FLASH_CURRENT_MASK, val); led->current2_addr, FLASH_CURRENT_MASK, val); if (rc) { dev_err(&led->spmi_dev->dev, "Current register write failed\n"); Loading Loading @@ -1433,46 +1386,49 @@ static void qpnp_flash_led_work(struct work_struct *work) FLASH_RAMP_UP_DELAY_US_MAX); } if (led->pdata->hdrm_sns_ch0_en) { if (led->flash_node[0].flash_on) { if (led->pdata->hdrm_sns_ch0_en || led->pdata->hdrm_sns_ch1_en) { if (flash_node->id == FLASH_LED_SWITCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_ENABLE); (flash_node->trigger & FLASH_LED0_TRIGGER ? FLASH_LED_HDRM_SNS_ENABLE : FLASH_LED_HDRM_SNS_DISABLE)); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense enable failed\n"); goto exit_flash_led_work; } } else { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); (flash_node->trigger & FLASH_LED1_TRIGGER ? FLASH_LED_HDRM_SNS_ENABLE : FLASH_LED_HDRM_SNS_DISABLE)); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); "Headroom sense enable failed\n"); goto exit_flash_led_work; } } } if (led->pdata->hdrm_sns_ch1_en) { if (led->flash_node[1].flash_on) { } else if (flash_node->id == FLASH_LED_0) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_ENABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense enable failed\n"); "Headroom sense disable failed\n"); goto exit_flash_led_work; } } else { } else if (flash_node->id == FLASH_LED_1) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); FLASH_LED_HDRM_SNS_ENABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); Loading @@ -1483,7 +1439,8 @@ static void qpnp_flash_led_work(struct work_struct *work) rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_STROBE_CTRL(led->base), FLASH_STROBE_MASK, (flash_node->id == FLASH_LED_SWITCH ? FLASH_STROBE_MASK : flash_node->trigger), flash_node->trigger); if (rc) { dev_err(&led->spmi_dev->dev, Loading Loading @@ -1520,14 +1477,45 @@ static void qpnp_flash_led_work(struct work_struct *work) turn_off: rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_STROBE_CTRL(led->base), flash_node->trigger, FLASH_LED_DISABLE); flash_node->id == FLASH_LED_SWITCH ? FLASH_STROBE_MASK : flash_node->trigger, FLASH_LED_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Strobe disable failed\n"); goto exit_flash_led_work; } usleep_range(FLASH_RAMP_DN_DELAY_US_MIN, FLASH_RAMP_DN_DELAY_US_MAX); exit_flash_hdrm_sns: if (led->pdata->hdrm_sns_ch0_en) { if (flash_node->id == FLASH_LED_0 || flash_node->id == FLASH_LED_SWITCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); goto exit_flash_hdrm_sns; } } } if (led->pdata->hdrm_sns_ch1_en) { if (flash_node->id == FLASH_LED_1 || flash_node->id == FLASH_LED_SWITCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); goto exit_flash_hdrm_sns; } } } exit_flash_led_work: rc = qpnp_flash_led_module_disable(led, flash_node); if (rc) { Loading Loading @@ -1568,19 +1556,42 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev, flash_node->cdev.brightness = value; if (led->flash_node[led->num_leds - 1].id == FLASH_LED_SWITCH) { if (flash_node->type == TORCH) led->flash_node[led->num_leds - 1].type = TORCH; else if (flash_node->type == FLASH) led->flash_node[led->num_leds - 1].type = FLASH; led->flash_node[led->num_leds - 1].max_current = flash_node->max_current; if (flash_node->id == FLASH_LED_0 || flash_node->id == FLASH_LED_1) { if (value < FLASH_LED_MIN_CURRENT_MA && value != 0) value = FLASH_LED_MIN_CURRENT_MA; flash_node->prgm_current = value; flash_node->flash_on = value ? true : false; if (value) led->flash_node[led->num_leds - 1].trigger |= (0x80 >> flash_node->id); else led->flash_node[led->num_leds - 1].trigger &= ~(0x80 >> flash_node->id); if (flash_node->id == FLASH_LED_0) led->flash_node[led->num_leds - 1]. prgm_current = flash_node->prgm_current; else if (flash_node->id == FLASH_LED_1) led->flash_node[led->num_leds - 1]. prgm_current2 = flash_node->prgm_current; return; } else if (flash_node->id == FLASH_LED_SWITCH) { if (led->flash_node[0].flash_on || led->flash_node[1].flash_on) flash_node->prgm_current = led->flash_node[0].prgm_current + led->flash_node[1].prgm_current; if (!value) { flash_node->prgm_current = 0; flash_node->prgm_current2 = 0; } } } else { if (value < FLASH_LED_MIN_CURRENT_MA && value != 0) Loading Loading
drivers/leds/leds-qpnp-flash.c +188 −177 Original line number Diff line number Diff line Loading @@ -175,6 +175,7 @@ struct flash_node_data { u32 boost_voltage_max; u16 max_current; u16 prgm_current; u16 prgm_current2; u16 duration; u8 id; u8 type; Loading Loading @@ -251,7 +252,7 @@ struct qpnp_flash_led { static u8 qpnp_flash_led_ctrl_dbg_regs[] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x4F, 0x51, 0x52, 0x54, 0x55, 0x5A 0x4A, 0x4B, 0x4C, 0x4F, 0x51, 0x52, 0x54, 0x55, 0x5A, 0x5C, 0x5D, }; static int flash_led_dbgfs_file_open(struct qpnp_flash_led *led, Loading Loading @@ -897,8 +898,22 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, struct flash_node_data *flash_node) { union power_supply_propval psy_prop; int rc, i; int rc; u8 val, tmp; rc = spmi_ext_register_readl(led->spmi_dev->ctrl, led->spmi_dev->sid, FLASH_LED_STROBE_CTRL(led->base), &val, 1); if (rc) { dev_err(&led->spmi_dev->dev, "Unable to read strobe reg\n"); return -EINVAL; } tmp = (~flash_node->trigger) & val; if (!tmp) { if (flash_node->type == TORCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_UNLOCK_SECURE(led->base), FLASH_SECURE_MASK, FLASH_UNLOCK_SECURE); Loading @@ -916,29 +931,6 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, "Torch reg write failed\n"); return -EINVAL; } if (led->pdata->hdrm_sns_ch0_en) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); return rc; } } if (led->pdata->hdrm_sns_ch1_en) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); return rc; } } rc = qpnp_led_masked_write(led->spmi_dev, Loading @@ -946,7 +938,8 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, FLASH_MODULE_ENABLE_MASK, FLASH_LED_MODULE_CTRL_DEFAULT); if (rc) { dev_err(&led->spmi_dev->dev, "Module disable failed\n"); dev_err(&led->spmi_dev->dev, "Module disable failed\n"); return -EINVAL; } Loading @@ -972,9 +965,9 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, return -EINVAL; } } } if (!led->flash_node[0].flash_on && !led->flash_node[2].flash_on) { if (flash_node->trigger & FLASH_LED0_TRIGGER) { rc = qpnp_led_masked_write(led->spmi_dev, led->current_addr, FLASH_CURRENT_MASK, 0x00); Loading @@ -983,10 +976,10 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, "current register write failed\n"); return -EINVAL; } } if (!led->flash_node[1].flash_on && !led->flash_node[3].flash_on) { if (flash_node->trigger & FLASH_LED1_TRIGGER) { rc = qpnp_led_masked_write(led->spmi_dev, led->current2_addr, FLASH_CURRENT_MASK, 0x00); Loading @@ -997,8 +990,8 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led, } } for (i = 0; i < led->num_leds; i++) led->flash_node[i].flash_on = false; if (flash_node->id == FLASH_LED_SWITCH) flash_node->trigger = 0; return 0; } Loading @@ -1018,6 +1011,7 @@ static void qpnp_flash_led_work(struct work_struct *work) union power_supply_propval psy_prop; int rc, brightness = flash_node->cdev.brightness; int max_curr_avail_ma = 0; int total_curr_ma = 0; int i; u8 val; Loading Loading @@ -1096,11 +1090,7 @@ static void qpnp_flash_led_work(struct work_struct *work) } } if (((led->flash_node[2].flash_on || led->flash_node[3].flash_on) && !led->flash_node[0].flash_on && !led->flash_node[1].flash_on) || flash_node->type == TORCH) { if (flash_node->type == TORCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_UNLOCK_SECURE(led->base), FLASH_SECURE_MASK, FLASH_UNLOCK_SECURE); Loading @@ -1118,15 +1108,11 @@ static void qpnp_flash_led_work(struct work_struct *work) "Torch reg write failed\n"); goto exit_flash_led_work; } if (led->flash_node[led->num_leds - 1].id == FLASH_LED_SWITCH) { flash_node->trigger = 0; if (led->flash_node[2].flash_on) flash_node->trigger |= FLASH_LED0_TRIGGER; val = (u8)(led->flash_node[2].prgm_current * if (flash_node->id == FLASH_LED_SWITCH) { val = (u8)(flash_node->prgm_current * FLASH_TORCH_MAX_LEVEL / led->flash_node[2].max_current); / flash_node->max_current); rc = qpnp_led_masked_write(led->spmi_dev, led->current_addr, FLASH_CURRENT_MASK, val); Loading @@ -1136,12 +1122,9 @@ static void qpnp_flash_led_work(struct work_struct *work) goto exit_flash_led_work; } if (led->flash_node[3].flash_on) flash_node->trigger |= FLASH_LED1_TRIGGER; val = (u8)(led->flash_node[3].prgm_current * val = (u8)(flash_node->prgm_current2 * FLASH_TORCH_MAX_LEVEL / led->flash_node[3].max_current); / flash_node->max_current); rc = qpnp_led_masked_write(led->spmi_dev, led->current2_addr, FLASH_CURRENT_MASK, val); Loading Loading @@ -1193,46 +1176,49 @@ static void qpnp_flash_led_work(struct work_struct *work) goto exit_flash_led_work; } if (led->pdata->hdrm_sns_ch0_en) { if (led->flash_node[2].flash_on) { if (led->pdata->hdrm_sns_ch0_en || led->pdata->hdrm_sns_ch1_en) { if (flash_node->id == FLASH_LED_SWITCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_ENABLE); flash_node->trigger & FLASH_LED0_TRIGGER ? FLASH_LED_HDRM_SNS_ENABLE : FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense enable failed\n"); goto exit_flash_led_work; } } else { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, flash_node->trigger & FLASH_LED1_TRIGGER ? FLASH_LED_HDRM_SNS_ENABLE : FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); "Headroom sense enable failed\n"); goto exit_flash_led_work; } } } if (led->pdata->hdrm_sns_ch1_en) { if (led->flash_node[3].flash_on) { } else if (flash_node->id == FLASH_LED_0) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_ENABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense enable failed\n"); "Headroom sense disable failed\n"); goto exit_flash_led_work; } } else { } else if (flash_node->id == FLASH_LED_1) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); FLASH_LED_HDRM_SNS_ENABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); Loading @@ -1243,22 +1229,19 @@ static void qpnp_flash_led_work(struct work_struct *work) rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_STROBE_CTRL(led->base), FLASH_STROBE_MASK, (flash_node->id == FLASH_LED_SWITCH ? FLASH_STROBE_MASK : flash_node->trigger), flash_node->trigger); if (rc) { dev_err(&led->spmi_dev->dev, "Strobe ctrl reg write failed\n"); "Strobe reg write failed\n"); goto exit_flash_led_work; } } else if (((led->flash_node[0].flash_on || led->flash_node[1].flash_on) && !led->flash_node[2].flash_on && !led->flash_node[3].flash_on) || flash_node->type == FLASH) { if (led->flash_node[0].flash_on) max_curr_avail_ma += led->flash_node[0].max_current; if (led->flash_node[1].flash_on) max_curr_avail_ma += led->flash_node[1].max_current; } else if (flash_node->type == FLASH) { if (flash_node->trigger & FLASH_LED0_TRIGGER) max_curr_avail_ma += flash_node->max_current; if (flash_node->trigger & FLASH_LED1_TRIGGER) max_curr_avail_ma += flash_node->max_current; psy_prop.intval = true; rc = led->battery_psy->set_property(led->battery_psy, Loading Loading @@ -1301,63 +1284,33 @@ static void qpnp_flash_led_work(struct work_struct *work) } } if (led->flash_node[led->num_leds - 1].id == FLASH_LED_SWITCH) { flash_node->trigger = 0; if (led->flash_node[0].flash_on && led->flash_node[1].flash_on) { if (max_curr_avail_ma < flash_node->prgm_current) { led->flash_node[0].prgm_current = led->flash_node[0].prgm_current * max_curr_avail_ma / flash_node->prgm_current; led->flash_node[1].prgm_current = led->flash_node[1].prgm_current * max_curr_avail_ma / flash_node->prgm_current; } flash_node->trigger = FLASH_LED0_TRIGGER | FLASH_LED1_TRIGGER; } else { if (led->flash_node[0].flash_on) flash_node->trigger |= FLASH_LED0_TRIGGER; if (flash_node->id == FLASH_LED_SWITCH) { if (flash_node->trigger & FLASH_LED0_TRIGGER) total_curr_ma += flash_node->prgm_current; else if (flash_node->trigger & FLASH_LED1_TRIGGER) total_curr_ma += flash_node->prgm_current2; led->flash_node[0].prgm_current = (max_curr_avail_ma < led->flash_node[0].prgm_current) ? max_curr_avail_ma : led->flash_node[0].prgm_current; if (max_curr_avail_ma < total_curr_ma) { flash_node->prgm_current *= max_curr_avail_ma / total_curr_ma; flash_node->prgm_current2 *= max_curr_avail_ma / total_curr_ma; } if (led->flash_node[1].flash_on) flash_node->trigger |= FLASH_LED1_TRIGGER; led->flash_node[1].prgm_current = (max_curr_avail_ma < led->flash_node[1].prgm_current) ? max_curr_avail_ma : led->flash_node[1].prgm_current; } val = (u8)(led->flash_node[0].prgm_current * FLASH_MAX_LEVEL / led->flash_node[0].max_current); val = (u8)(flash_node->prgm_current * FLASH_MAX_LEVEL / flash_node->max_current); rc = qpnp_led_masked_write(led->spmi_dev, led->current_addr, FLASH_CURRENT_MASK, val); led->current_addr, FLASH_CURRENT_MASK, val); if (rc) { dev_err(&led->spmi_dev->dev, "Current register write failed\n"); goto exit_flash_led_work; } val = (u8)(led->flash_node[1].prgm_current * FLASH_MAX_LEVEL / led->flash_node[1].max_current); val = (u8)(flash_node->prgm_current2 * FLASH_MAX_LEVEL / flash_node->max_current); rc = qpnp_led_masked_write(led->spmi_dev, led->current2_addr, FLASH_CURRENT_MASK, val); led->current2_addr, FLASH_CURRENT_MASK, val); if (rc) { dev_err(&led->spmi_dev->dev, "Current register write failed\n"); Loading Loading @@ -1433,46 +1386,49 @@ static void qpnp_flash_led_work(struct work_struct *work) FLASH_RAMP_UP_DELAY_US_MAX); } if (led->pdata->hdrm_sns_ch0_en) { if (led->flash_node[0].flash_on) { if (led->pdata->hdrm_sns_ch0_en || led->pdata->hdrm_sns_ch1_en) { if (flash_node->id == FLASH_LED_SWITCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_ENABLE); (flash_node->trigger & FLASH_LED0_TRIGGER ? FLASH_LED_HDRM_SNS_ENABLE : FLASH_LED_HDRM_SNS_DISABLE)); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense enable failed\n"); goto exit_flash_led_work; } } else { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); (flash_node->trigger & FLASH_LED1_TRIGGER ? FLASH_LED_HDRM_SNS_ENABLE : FLASH_LED_HDRM_SNS_DISABLE)); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); "Headroom sense enable failed\n"); goto exit_flash_led_work; } } } if (led->pdata->hdrm_sns_ch1_en) { if (led->flash_node[1].flash_on) { } else if (flash_node->id == FLASH_LED_0) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_ENABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense enable failed\n"); "Headroom sense disable failed\n"); goto exit_flash_led_work; } } else { } else if (flash_node->id == FLASH_LED_1) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); FLASH_LED_HDRM_SNS_ENABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); Loading @@ -1483,7 +1439,8 @@ static void qpnp_flash_led_work(struct work_struct *work) rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_STROBE_CTRL(led->base), FLASH_STROBE_MASK, (flash_node->id == FLASH_LED_SWITCH ? FLASH_STROBE_MASK : flash_node->trigger), flash_node->trigger); if (rc) { dev_err(&led->spmi_dev->dev, Loading Loading @@ -1520,14 +1477,45 @@ static void qpnp_flash_led_work(struct work_struct *work) turn_off: rc = qpnp_led_masked_write(led->spmi_dev, FLASH_LED_STROBE_CTRL(led->base), flash_node->trigger, FLASH_LED_DISABLE); flash_node->id == FLASH_LED_SWITCH ? FLASH_STROBE_MASK : flash_node->trigger, FLASH_LED_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Strobe disable failed\n"); goto exit_flash_led_work; } usleep_range(FLASH_RAMP_DN_DELAY_US_MIN, FLASH_RAMP_DN_DELAY_US_MAX); exit_flash_hdrm_sns: if (led->pdata->hdrm_sns_ch0_en) { if (flash_node->id == FLASH_LED_0 || flash_node->id == FLASH_LED_SWITCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL0(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); goto exit_flash_hdrm_sns; } } } if (led->pdata->hdrm_sns_ch1_en) { if (flash_node->id == FLASH_LED_1 || flash_node->id == FLASH_LED_SWITCH) { rc = qpnp_led_masked_write(led->spmi_dev, FLASH_HDRM_SNS_ENABLE_CTRL1(led->base), FLASH_LED_HDRM_SNS_ENABLE_MASK, FLASH_LED_HDRM_SNS_DISABLE); if (rc) { dev_err(&led->spmi_dev->dev, "Headroom sense disable failed\n"); goto exit_flash_hdrm_sns; } } } exit_flash_led_work: rc = qpnp_flash_led_module_disable(led, flash_node); if (rc) { Loading Loading @@ -1568,19 +1556,42 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev, flash_node->cdev.brightness = value; if (led->flash_node[led->num_leds - 1].id == FLASH_LED_SWITCH) { if (flash_node->type == TORCH) led->flash_node[led->num_leds - 1].type = TORCH; else if (flash_node->type == FLASH) led->flash_node[led->num_leds - 1].type = FLASH; led->flash_node[led->num_leds - 1].max_current = flash_node->max_current; if (flash_node->id == FLASH_LED_0 || flash_node->id == FLASH_LED_1) { if (value < FLASH_LED_MIN_CURRENT_MA && value != 0) value = FLASH_LED_MIN_CURRENT_MA; flash_node->prgm_current = value; flash_node->flash_on = value ? true : false; if (value) led->flash_node[led->num_leds - 1].trigger |= (0x80 >> flash_node->id); else led->flash_node[led->num_leds - 1].trigger &= ~(0x80 >> flash_node->id); if (flash_node->id == FLASH_LED_0) led->flash_node[led->num_leds - 1]. prgm_current = flash_node->prgm_current; else if (flash_node->id == FLASH_LED_1) led->flash_node[led->num_leds - 1]. prgm_current2 = flash_node->prgm_current; return; } else if (flash_node->id == FLASH_LED_SWITCH) { if (led->flash_node[0].flash_on || led->flash_node[1].flash_on) flash_node->prgm_current = led->flash_node[0].prgm_current + led->flash_node[1].prgm_current; if (!value) { flash_node->prgm_current = 0; flash_node->prgm_current2 = 0; } } } else { if (value < FLASH_LED_MIN_CURRENT_MA && value != 0) Loading