Loading drivers/leds/leds-qpnp-flash-v2.c +38 −22 Original line number Diff line number Diff line Loading @@ -731,7 +731,8 @@ static int qpnp_flash_led_get_voltage_headroom(struct qpnp_flash_led *led) #define FLASH_VDIP_MARGIN 50000 #define BOB_EFFICIENCY 900LL #define VIN_FLASH_MIN_UV 3300000LL static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led, int *max_current) { int ocv_uv = 0, rbatt_uohm = 0, ibat_now = 0, voltage_hdrm_mv = 0; int rc = 0; Loading @@ -747,8 +748,10 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) } /* If no battery is connected, return max possible flash current */ if (!rbatt_uohm) return FLASH_LED_MAX_TOTAL_CURRENT_MA; if (!rbatt_uohm) { *max_current = FLASH_LED_MAX_TOTAL_CURRENT_MA; return 0; } rc = get_property_from_fg(led, POWER_SUPPLY_PROP_VOLTAGE_OCV, &ocv_uv); if (rc < 0) { Loading Loading @@ -785,7 +788,7 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) /* Wait for LMH mitigation to take effect */ udelay(100); return qpnp_flash_led_calc_max_current(led); return qpnp_flash_led_calc_max_current(led, max_current); } /* Loading Loading @@ -825,13 +828,14 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) avail_flash_ua = div64_s64(avail_flash_power_fw, vin_flash_uv * MCONV); pr_debug("avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n", avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, led->trigger_lmh); return min(FLASH_LED_MAX_TOTAL_CURRENT_MA, *max_current = min(FLASH_LED_MAX_TOTAL_CURRENT_MA, (int)(div64_s64(avail_flash_ua, MCONV))); return 0; } static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led) static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led, int *thermal_current_lim) { int thermal_current_lim = 0; int rc; u8 thermal_thrsh1, thermal_thrsh2, thermal_thrsh3, otst_status; Loading Loading @@ -888,7 +892,7 @@ static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led) /* Look up current limit based on THERMAL_OTST status */ if (otst_status) thermal_current_lim = *thermal_current_lim = led->pdata->thermal_derate_current[otst_status >> 1]; /* Restore THERMAL_THRESHx registers to original values */ Loading @@ -913,23 +917,36 @@ static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led) if (rc < 0) return rc; return thermal_current_lim; return 0; } static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led) static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led, int *max_avail_current) { int max_avail_current, thermal_current_lim = 0; int thermal_current_lim = 0, rc; led->trigger_lmh = false; max_avail_current = qpnp_flash_led_calc_max_current(led); if (led->pdata->thermal_derate_en) thermal_current_lim = qpnp_flash_led_calc_thermal_current_lim(led); rc = qpnp_flash_led_calc_max_current(led, max_avail_current); if (rc < 0) { pr_err("Couldn't calculate max_avail_current, rc=%d\n", rc); return rc; } if (led->pdata->thermal_derate_en) { rc = qpnp_flash_led_calc_thermal_current_lim(led, &thermal_current_lim); if (rc < 0) { pr_err("Couldn't calculate thermal_current_lim, rc=%d\n", rc); return rc; } } if (thermal_current_lim) max_avail_current = min(max_avail_current, thermal_current_lim); *max_avail_current = min(*max_avail_current, thermal_current_lim); return max_avail_current; return 0; } static void qpnp_flash_led_aggregate_max_current(struct flash_node_data *fnode) Loading Loading @@ -1237,12 +1254,11 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options, } if (options & QUERY_MAX_CURRENT) { rc = qpnp_flash_led_get_max_avail_current(led); rc = qpnp_flash_led_get_max_avail_current(led, max_current); if (rc < 0) { pr_err("query max current failed, rc=%d\n", rc); return rc; } *max_current = rc; } return 0; Loading Loading @@ -1291,7 +1307,7 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev, static ssize_t qpnp_flash_led_max_current_show(struct device *dev, struct device_attribute *attr, char *buf) { int rc; int rc, max_current = 0; struct flash_switch_data *snode; struct qpnp_flash_led *led; struct led_classdev *led_cdev = dev_get_drvdata(dev); Loading @@ -1299,11 +1315,11 @@ static ssize_t qpnp_flash_led_max_current_show(struct device *dev, snode = container_of(led_cdev, struct flash_switch_data, cdev); led = dev_get_drvdata(&snode->pdev->dev); rc = qpnp_flash_led_get_max_avail_current(led); rc = qpnp_flash_led_get_max_avail_current(led, &max_current); if (rc < 0) pr_err("query max current failed, rc=%d\n", rc); return snprintf(buf, PAGE_SIZE, "%d\n", rc); return snprintf(buf, PAGE_SIZE, "%d\n", max_current); } /* sysfs attributes exported by flash_led */ Loading Loading
drivers/leds/leds-qpnp-flash-v2.c +38 −22 Original line number Diff line number Diff line Loading @@ -731,7 +731,8 @@ static int qpnp_flash_led_get_voltage_headroom(struct qpnp_flash_led *led) #define FLASH_VDIP_MARGIN 50000 #define BOB_EFFICIENCY 900LL #define VIN_FLASH_MIN_UV 3300000LL static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led, int *max_current) { int ocv_uv = 0, rbatt_uohm = 0, ibat_now = 0, voltage_hdrm_mv = 0; int rc = 0; Loading @@ -747,8 +748,10 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) } /* If no battery is connected, return max possible flash current */ if (!rbatt_uohm) return FLASH_LED_MAX_TOTAL_CURRENT_MA; if (!rbatt_uohm) { *max_current = FLASH_LED_MAX_TOTAL_CURRENT_MA; return 0; } rc = get_property_from_fg(led, POWER_SUPPLY_PROP_VOLTAGE_OCV, &ocv_uv); if (rc < 0) { Loading Loading @@ -785,7 +788,7 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) /* Wait for LMH mitigation to take effect */ udelay(100); return qpnp_flash_led_calc_max_current(led); return qpnp_flash_led_calc_max_current(led, max_current); } /* Loading Loading @@ -825,13 +828,14 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) avail_flash_ua = div64_s64(avail_flash_power_fw, vin_flash_uv * MCONV); pr_debug("avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n", avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, led->trigger_lmh); return min(FLASH_LED_MAX_TOTAL_CURRENT_MA, *max_current = min(FLASH_LED_MAX_TOTAL_CURRENT_MA, (int)(div64_s64(avail_flash_ua, MCONV))); return 0; } static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led) static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led, int *thermal_current_lim) { int thermal_current_lim = 0; int rc; u8 thermal_thrsh1, thermal_thrsh2, thermal_thrsh3, otst_status; Loading Loading @@ -888,7 +892,7 @@ static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led) /* Look up current limit based on THERMAL_OTST status */ if (otst_status) thermal_current_lim = *thermal_current_lim = led->pdata->thermal_derate_current[otst_status >> 1]; /* Restore THERMAL_THRESHx registers to original values */ Loading @@ -913,23 +917,36 @@ static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led) if (rc < 0) return rc; return thermal_current_lim; return 0; } static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led) static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led, int *max_avail_current) { int max_avail_current, thermal_current_lim = 0; int thermal_current_lim = 0, rc; led->trigger_lmh = false; max_avail_current = qpnp_flash_led_calc_max_current(led); if (led->pdata->thermal_derate_en) thermal_current_lim = qpnp_flash_led_calc_thermal_current_lim(led); rc = qpnp_flash_led_calc_max_current(led, max_avail_current); if (rc < 0) { pr_err("Couldn't calculate max_avail_current, rc=%d\n", rc); return rc; } if (led->pdata->thermal_derate_en) { rc = qpnp_flash_led_calc_thermal_current_lim(led, &thermal_current_lim); if (rc < 0) { pr_err("Couldn't calculate thermal_current_lim, rc=%d\n", rc); return rc; } } if (thermal_current_lim) max_avail_current = min(max_avail_current, thermal_current_lim); *max_avail_current = min(*max_avail_current, thermal_current_lim); return max_avail_current; return 0; } static void qpnp_flash_led_aggregate_max_current(struct flash_node_data *fnode) Loading Loading @@ -1237,12 +1254,11 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options, } if (options & QUERY_MAX_CURRENT) { rc = qpnp_flash_led_get_max_avail_current(led); rc = qpnp_flash_led_get_max_avail_current(led, max_current); if (rc < 0) { pr_err("query max current failed, rc=%d\n", rc); return rc; } *max_current = rc; } return 0; Loading Loading @@ -1291,7 +1307,7 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev, static ssize_t qpnp_flash_led_max_current_show(struct device *dev, struct device_attribute *attr, char *buf) { int rc; int rc, max_current = 0; struct flash_switch_data *snode; struct qpnp_flash_led *led; struct led_classdev *led_cdev = dev_get_drvdata(dev); Loading @@ -1299,11 +1315,11 @@ static ssize_t qpnp_flash_led_max_current_show(struct device *dev, snode = container_of(led_cdev, struct flash_switch_data, cdev); led = dev_get_drvdata(&snode->pdev->dev); rc = qpnp_flash_led_get_max_avail_current(led); rc = qpnp_flash_led_get_max_avail_current(led, &max_current); if (rc < 0) pr_err("query max current failed, rc=%d\n", rc); return snprintf(buf, PAGE_SIZE, "%d\n", rc); return snprintf(buf, PAGE_SIZE, "%d\n", max_current); } /* sysfs attributes exported by flash_led */ Loading