Lines Matching +full:charge +full:- +full:input +full:- +full:threshold +full:- +full:microvolt

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) ST-Ericsson AB 2012
5 * Main and Back-up battery management driver.
7 * Note: Backup battery management is required in case of Li-Ion battery and not
37 #include <linux/fixp-arith.h>
39 #include "ab8500-bm.h"
49 /* Currents higher than -500mA (dissipating) will make compensation unstable */
50 #define IGNORE_VBAT_HIGHCUR -500000
63 * struct ab8500_fg_interrupts - ab8500 fg interrupts
158 * struct ab8500_fg - ab8500 FG device information
168 * @accu_charge: Accumulated charge from the last conversion
180 * @charge_state: Current charge state
246 * ab8500_fg_get() - returns a reference to the primary AB8500 fuel gauge
350 return (u8) i - 1; in ab8500_volt_to_regval()
354 return (u8) ARRAY_SIZE(ab8500_fg_lowbat_voltage_map) - 1; in ab8500_volt_to_regval()
358 * ab8500_fg_is_low_curr() - Low or high current mode
362 * Low current mode if the current consumption is below a certain threshold
369 if (curr_ua > -di->bm->fg_params->high_curr_threshold_ua) in ab8500_fg_is_low_curr()
376 * ab8500_fg_add_cap_sample() - Add capacity to average filter
386 struct ab8500_fg_avg_cap *avg = &di->avg_cap; in ab8500_fg_add_cap_sample()
389 avg->sum += sample - avg->samples[avg->pos]; in ab8500_fg_add_cap_sample()
390 avg->samples[avg->pos] = sample; in ab8500_fg_add_cap_sample()
391 avg->time_stamps[avg->pos] = now; in ab8500_fg_add_cap_sample()
392 avg->pos++; in ab8500_fg_add_cap_sample()
394 if (avg->pos == NBR_AVG_SAMPLES) in ab8500_fg_add_cap_sample()
395 avg->pos = 0; in ab8500_fg_add_cap_sample()
397 if (avg->nbr_samples < NBR_AVG_SAMPLES) in ab8500_fg_add_cap_sample()
398 avg->nbr_samples++; in ab8500_fg_add_cap_sample()
404 } while (now - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]); in ab8500_fg_add_cap_sample()
406 avg->avg = avg->sum / avg->nbr_samples; in ab8500_fg_add_cap_sample()
408 return avg->avg; in ab8500_fg_add_cap_sample()
412 * ab8500_fg_clear_cap_samples() - Clear average filter
420 struct ab8500_fg_avg_cap *avg = &di->avg_cap; in ab8500_fg_clear_cap_samples()
422 avg->pos = 0; in ab8500_fg_clear_cap_samples()
423 avg->nbr_samples = 0; in ab8500_fg_clear_cap_samples()
424 avg->sum = 0; in ab8500_fg_clear_cap_samples()
425 avg->avg = 0; in ab8500_fg_clear_cap_samples()
428 avg->samples[i] = 0; in ab8500_fg_clear_cap_samples()
429 avg->time_stamps[i] = 0; in ab8500_fg_clear_cap_samples()
434 * ab8500_fg_fill_cap_sample() - Fill average filter
444 struct ab8500_fg_avg_cap *avg = &di->avg_cap; in ab8500_fg_fill_cap_sample()
449 avg->samples[i] = sample; in ab8500_fg_fill_cap_sample()
450 avg->time_stamps[i] = now; in ab8500_fg_fill_cap_sample()
453 avg->pos = 0; in ab8500_fg_fill_cap_sample()
454 avg->nbr_samples = NBR_AVG_SAMPLES; in ab8500_fg_fill_cap_sample()
455 avg->sum = sample * NBR_AVG_SAMPLES; in ab8500_fg_fill_cap_sample()
456 avg->avg = sample; in ab8500_fg_fill_cap_sample()
460 * ab8500_fg_coulomb_counter() - enable coulomb counter
470 mutex_lock(&di->cc_lock); in ab8500_fg_coulomb_counter()
474 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_coulomb_counter()
480 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_coulomb_counter()
482 di->fg_samples); in ab8500_fg_coulomb_counter()
487 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_coulomb_counter()
493 di->flags.fg_enabled = true; in ab8500_fg_coulomb_counter()
496 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_coulomb_counter()
502 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_coulomb_counter()
508 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_coulomb_counter()
513 di->flags.fg_enabled = false; in ab8500_fg_coulomb_counter()
516 dev_dbg(di->dev, " CC enabled: %d Samples: %d\n", in ab8500_fg_coulomb_counter()
517 enable, di->fg_samples); in ab8500_fg_coulomb_counter()
519 mutex_unlock(&di->cc_lock); in ab8500_fg_coulomb_counter()
523 dev_err(di->dev, "%s Enabling coulomb counter failed\n", __func__); in ab8500_fg_coulomb_counter()
524 mutex_unlock(&di->cc_lock); in ab8500_fg_coulomb_counter()
529 * ab8500_fg_inst_curr_start() - start battery instantaneous current
541 mutex_lock(&di->cc_lock); in ab8500_fg_inst_curr_start()
543 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_inst_curr_start()
544 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_inst_curr_start()
550 dev_dbg(di->dev, "%s Enable FG\n", __func__); in ab8500_fg_inst_curr_start()
551 di->turn_off_fg = true; in ab8500_fg_inst_curr_start()
554 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_inst_curr_start()
561 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_inst_curr_start()
567 di->turn_off_fg = false; in ab8500_fg_inst_curr_start()
571 reinit_completion(&di->ab8500_fg_started); in ab8500_fg_inst_curr_start()
572 reinit_completion(&di->ab8500_fg_complete); in ab8500_fg_inst_curr_start()
573 enable_irq(di->irq); in ab8500_fg_inst_curr_start()
578 mutex_unlock(&di->cc_lock); in ab8500_fg_inst_curr_start()
583 * ab8500_fg_inst_curr_started() - check if fg conversion has started
590 return completion_done(&di->ab8500_fg_started); in ab8500_fg_inst_curr_started()
594 * ab8500_fg_inst_curr_done() - check if fg conversion is done
601 return completion_done(&di->ab8500_fg_complete); in ab8500_fg_inst_curr_done()
605 * ab8500_fg_inst_curr_finalize() - battery instantaneous current
620 if (!completion_done(&di->ab8500_fg_complete)) { in ab8500_fg_inst_curr_finalize()
622 &di->ab8500_fg_complete, in ab8500_fg_inst_curr_finalize()
624 dev_dbg(di->dev, "Finalize time: %d ms\n", in ab8500_fg_inst_curr_finalize()
625 jiffies_to_msecs(INS_CURR_TIMEOUT - timeout)); in ab8500_fg_inst_curr_finalize()
627 ret = -ETIME; in ab8500_fg_inst_curr_finalize()
628 disable_irq(di->irq); in ab8500_fg_inst_curr_finalize()
629 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_inst_curr_finalize()
630 dev_err(di->dev, "completion timed out [%d]\n", in ab8500_fg_inst_curr_finalize()
636 disable_irq(di->irq); in ab8500_fg_inst_curr_finalize()
637 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_inst_curr_finalize()
639 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_inst_curr_finalize()
647 ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_inst_curr_finalize()
652 ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_inst_curr_finalize()
668 * Full scale input voltage is in ab8500_fg_inst_curr_finalize()
675 val = (val * QLSB_NANO_AMP_HOURS_X10 * 36 * 4) / di->bm->fg_res; in ab8500_fg_inst_curr_finalize()
677 if (di->turn_off_fg) { in ab8500_fg_inst_curr_finalize()
678 dev_dbg(di->dev, "%s Disable FG\n", __func__); in ab8500_fg_inst_curr_finalize()
681 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_inst_curr_finalize()
687 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_inst_curr_finalize()
692 mutex_unlock(&di->cc_lock); in ab8500_fg_inst_curr_finalize()
697 mutex_unlock(&di->cc_lock); in ab8500_fg_inst_curr_finalize()
702 * ab8500_fg_inst_curr_blocking() - battery instantaneous current
716 dev_err(di->dev, "Failed to initialize fg_inst\n"); in ab8500_fg_inst_curr_blocking()
721 if (!completion_done(&di->ab8500_fg_started)) { in ab8500_fg_inst_curr_blocking()
723 &di->ab8500_fg_started, in ab8500_fg_inst_curr_blocking()
725 dev_dbg(di->dev, "Start time: %d ms\n", in ab8500_fg_inst_curr_blocking()
726 jiffies_to_msecs(INS_CURR_TIMEOUT - timeout)); in ab8500_fg_inst_curr_blocking()
728 ret = -ETIME; in ab8500_fg_inst_curr_blocking()
729 dev_err(di->dev, "completion timed out [%d]\n", in ab8500_fg_inst_curr_blocking()
737 dev_err(di->dev, "Failed to finalize fg_inst\n"); in ab8500_fg_inst_curr_blocking()
741 dev_dbg(di->dev, "%s instant current: %d uA", __func__, curr_ua); in ab8500_fg_inst_curr_blocking()
744 disable_irq(di->irq); in ab8500_fg_inst_curr_blocking()
745 mutex_unlock(&di->cc_lock); in ab8500_fg_inst_curr_blocking()
750 * ab8500_fg_acc_cur_work() - average battery current
765 mutex_lock(&di->cc_lock); in ab8500_fg_acc_cur_work()
766 ret = abx500_set_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_acc_cur_work()
771 ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_acc_cur_work()
776 ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_acc_cur_work()
781 ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_acc_cur_work()
798 di->accu_charge = (val * QLSB_NANO_AMP_HOURS_X10) / in ab8500_fg_acc_cur_work()
799 (100 * di->bm->fg_res); in ab8500_fg_acc_cur_work()
806 di->avg_curr_ua = (val * QLSB_NANO_AMP_HOURS_X10 * 36) / in ab8500_fg_acc_cur_work()
807 (di->bm->fg_res * (di->fg_samples / 4)); in ab8500_fg_acc_cur_work()
809 di->flags.conv_done = true; in ab8500_fg_acc_cur_work()
811 mutex_unlock(&di->cc_lock); in ab8500_fg_acc_cur_work()
813 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_acc_cur_work()
815 dev_dbg(di->dev, "fg_res: %d, fg_samples: %d, gasg: %d, accu_charge: %d \n", in ab8500_fg_acc_cur_work()
816 di->bm->fg_res, di->fg_samples, val, di->accu_charge); in ab8500_fg_acc_cur_work()
819 dev_err(di->dev, in ab8500_fg_acc_cur_work()
821 mutex_unlock(&di->cc_lock); in ab8500_fg_acc_cur_work()
822 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_acc_cur_work()
826 * ab8500_fg_bat_voltage() - get battery voltage
836 ret = iio_read_channel_processed(di->main_bat_v, &vbat); in ab8500_fg_bat_voltage()
838 dev_err(di->dev, in ab8500_fg_bat_voltage()
851 * ab8500_fg_volt_to_capacity() - Voltage based capacity
853 * @voltage_uv: The voltage to convert to a capacity in microvolt
859 struct power_supply_battery_info *bi = di->bm->bi; in ab8500_fg_volt_to_capacity()
862 return power_supply_batinfo_ocv2cap(bi, voltage_uv, di->bat_temp) * 10; in ab8500_fg_volt_to_capacity()
866 * ab8500_fg_uncomp_volt_to_capacity() - Uncompensated voltage based capacity
874 di->vbat_uv = ab8500_fg_bat_voltage(di); in ab8500_fg_uncomp_volt_to_capacity()
875 return ab8500_fg_volt_to_capacity(di, di->vbat_uv); in ab8500_fg_uncomp_volt_to_capacity()
879 * ab8500_fg_battery_resistance() - Returns the battery inner resistance
889 struct power_supply_battery_info *bi = di->bm->bi; in ab8500_fg_battery_resistance()
894 * Determine the resistance at this voltage. First try VBAT-to-Ri else in ab8500_fg_battery_resistance()
899 resistance = power_supply_vbat2ri(bi, vbat_uncomp_uv, di->flags.charging); in ab8500_fg_battery_resistance()
903 resistance_percent = power_supply_temp2resist_simple(bi->resist_table, in ab8500_fg_battery_resistance()
904 bi->resist_table_size, in ab8500_fg_battery_resistance()
905 di->bat_temp / 10); in ab8500_fg_battery_resistance()
907 resistance = bi->factory_internal_resistance_uohm / 1000; in ab8500_fg_battery_resistance()
911 resistance = bi->factory_internal_resistance_uohm / 1000; in ab8500_fg_battery_resistance()
915 resistance += (di->line_impedance_uohm / 1000); in ab8500_fg_battery_resistance()
917 dev_dbg(di->dev, "%s Temp: %d battery internal resistance: %d" in ab8500_fg_battery_resistance()
919 __func__, di->bat_temp, resistance, di->bm->fg_res / 10, in ab8500_fg_battery_resistance()
920 (di->bm->fg_res / 10) + resistance); in ab8500_fg_battery_resistance()
923 resistance += di->bm->fg_res / 10; in ab8500_fg_battery_resistance()
929 * ab8500_load_comp_fg_bat_voltage() - get load compensated battery voltage
954 dev_err(di->dev, in ab8500_load_comp_fg_bat_voltage()
956 di->vbat_uv = vbat_uv / i; in ab8500_load_comp_fg_bat_voltage()
957 return di->vbat_uv; in ab8500_load_comp_fg_bat_voltage()
960 ab8500_fg_inst_curr_finalize(di, &di->inst_curr_ua); in ab8500_load_comp_fg_bat_voltage()
967 if (!always && di->inst_curr_ua < IGNORE_VBAT_HIGHCUR) in ab8500_load_comp_fg_bat_voltage()
968 return -EINVAL; in ab8500_load_comp_fg_bat_voltage()
974 vbat_uv = vbat_uv - (di->inst_curr_ua * rcomp) / 1000; in ab8500_load_comp_fg_bat_voltage()
977 di->vbat_uv = vbat_uv; in ab8500_load_comp_fg_bat_voltage()
983 * ab8500_fg_load_comp_volt_to_capacity() - Load compensated voltage based capacity
999 * ab8500_fg_convert_mah_to_permille() - Capacity in mAh to permille
1007 return (cap_mah * 1000) / di->bat_cap.max_mah_design; in ab8500_fg_convert_mah_to_permille()
1011 * ab8500_fg_convert_permille_to_mah() - Capacity in permille to mAh
1019 return cap_pm * di->bat_cap.max_mah_design / 1000; in ab8500_fg_convert_permille_to_mah()
1023 * ab8500_fg_convert_mah_to_uwh() - Capacity in mAh to uWh
1035 * Capacity is in milli ampere hours (10^-3)Ah in ab8500_fg_convert_mah_to_uwh()
1036 * Nominal voltage is in microvolts (10^-6)V in ab8500_fg_convert_mah_to_uwh()
1039 div_res = ((u64) cap_mah) * ((u64) di->vbat_nom_uv); in ab8500_fg_convert_mah_to_uwh()
1050 * ab8500_fg_calc_cap_charging() - Calculate remaining capacity while charging
1058 dev_dbg(di->dev, "%s cap_mah %d accu_charge %d\n", in ab8500_fg_calc_cap_charging()
1060 di->bat_cap.mah, in ab8500_fg_calc_cap_charging()
1061 di->accu_charge); in ab8500_fg_calc_cap_charging()
1064 if (di->bat_cap.mah + di->accu_charge > 0) in ab8500_fg_calc_cap_charging()
1065 di->bat_cap.mah += di->accu_charge; in ab8500_fg_calc_cap_charging()
1067 di->bat_cap.mah = 0; in ab8500_fg_calc_cap_charging()
1072 if (di->bat_cap.mah >= di->bat_cap.max_mah_design || in ab8500_fg_calc_cap_charging()
1073 di->flags.force_full) { in ab8500_fg_calc_cap_charging()
1074 di->bat_cap.mah = di->bat_cap.max_mah_design; in ab8500_fg_calc_cap_charging()
1077 ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); in ab8500_fg_calc_cap_charging()
1078 di->bat_cap.permille = in ab8500_fg_calc_cap_charging()
1079 ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_charging()
1082 di->vbat_uv = ab8500_fg_bat_voltage(di); in ab8500_fg_calc_cap_charging()
1083 di->inst_curr_ua = ab8500_fg_inst_curr_blocking(di); in ab8500_fg_calc_cap_charging()
1085 return di->bat_cap.mah; in ab8500_fg_calc_cap_charging()
1089 * ab8500_fg_calc_cap_discharge_voltage() - Capacity in discharge with voltage
1104 di->bat_cap.mah = ab8500_fg_add_cap_sample(di, mah); in ab8500_fg_calc_cap_discharge_voltage()
1105 di->bat_cap.permille = in ab8500_fg_calc_cap_discharge_voltage()
1106 ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_voltage()
1108 return di->bat_cap.mah; in ab8500_fg_calc_cap_discharge_voltage()
1112 * ab8500_fg_calc_cap_discharge_fg() - Capacity in discharge with FG
1123 dev_dbg(di->dev, "%s cap_mah %d accu_charge %d\n", in ab8500_fg_calc_cap_discharge_fg()
1125 di->bat_cap.mah, in ab8500_fg_calc_cap_discharge_fg()
1126 di->accu_charge); in ab8500_fg_calc_cap_discharge_fg()
1129 if (di->bat_cap.mah + di->accu_charge > 0) in ab8500_fg_calc_cap_discharge_fg()
1130 di->bat_cap.mah += di->accu_charge; in ab8500_fg_calc_cap_discharge_fg()
1132 di->bat_cap.mah = 0; in ab8500_fg_calc_cap_discharge_fg()
1134 if (di->bat_cap.mah >= di->bat_cap.max_mah_design) in ab8500_fg_calc_cap_discharge_fg()
1135 di->bat_cap.mah = di->bat_cap.max_mah_design; in ab8500_fg_calc_cap_discharge_fg()
1141 permille = ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1145 di->bat_cap.permille = permille_volt; in ab8500_fg_calc_cap_discharge_fg()
1146 di->bat_cap.mah = ab8500_fg_convert_permille_to_mah(di, in ab8500_fg_calc_cap_discharge_fg()
1147 di->bat_cap.permille); in ab8500_fg_calc_cap_discharge_fg()
1149 dev_dbg(di->dev, "%s voltage based: perm %d perm_volt %d\n", in ab8500_fg_calc_cap_discharge_fg()
1154 ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1156 ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1157 di->bat_cap.permille = in ab8500_fg_calc_cap_discharge_fg()
1158 ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1161 return di->bat_cap.mah; in ab8500_fg_calc_cap_discharge_fg()
1165 * ab8500_fg_capacity_level() - Get the battery capacity level
1174 percent = DIV_ROUND_CLOSEST(di->bat_cap.permille, 10); in ab8500_fg_capacity_level()
1176 if (percent <= di->bm->cap_levels->critical || in ab8500_fg_capacity_level()
1177 di->flags.low_bat) in ab8500_fg_capacity_level()
1179 else if (percent <= di->bm->cap_levels->low) in ab8500_fg_capacity_level()
1181 else if (percent <= di->bm->cap_levels->normal) in ab8500_fg_capacity_level()
1183 else if (percent <= di->bm->cap_levels->high) in ab8500_fg_capacity_level()
1192 * ab8500_fg_calculate_scaled_capacity() - Capacity scaling
1201 struct ab8500_fg_cap_scaling *cs = &di->bat_cap.cap_scale; in ab8500_fg_calculate_scaled_capacity()
1202 int capacity = di->bat_cap.prev_percent; in ab8500_fg_calculate_scaled_capacity()
1204 if (!cs->enable) in ab8500_fg_calculate_scaled_capacity()
1208 * As long as we are in fully charge mode scale the capacity in ab8500_fg_calculate_scaled_capacity()
1211 if (di->flags.fully_charged) { in ab8500_fg_calculate_scaled_capacity()
1212 cs->cap_to_scale[0] = 100; in ab8500_fg_calculate_scaled_capacity()
1213 cs->cap_to_scale[1] = in ab8500_fg_calculate_scaled_capacity()
1214 max(capacity, di->bm->fg_params->maint_thres); in ab8500_fg_calculate_scaled_capacity()
1215 dev_dbg(di->dev, "Scale cap with %d/%d\n", in ab8500_fg_calculate_scaled_capacity()
1216 cs->cap_to_scale[0], cs->cap_to_scale[1]); in ab8500_fg_calculate_scaled_capacity()
1220 if ((cs->cap_to_scale[0] != cs->cap_to_scale[1]) in ab8500_fg_calculate_scaled_capacity()
1221 && (cs->cap_to_scale[1] > 0)) in ab8500_fg_calculate_scaled_capacity()
1223 DIV_ROUND_CLOSEST(di->bat_cap.prev_percent * in ab8500_fg_calculate_scaled_capacity()
1224 cs->cap_to_scale[0], in ab8500_fg_calculate_scaled_capacity()
1225 cs->cap_to_scale[1])); in ab8500_fg_calculate_scaled_capacity()
1227 if (di->flags.charging) { in ab8500_fg_calculate_scaled_capacity()
1228 if (capacity < cs->disable_cap_level) { in ab8500_fg_calculate_scaled_capacity()
1229 cs->disable_cap_level = capacity; in ab8500_fg_calculate_scaled_capacity()
1230 dev_dbg(di->dev, "Cap to stop scale lowered %d%%\n", in ab8500_fg_calculate_scaled_capacity()
1231 cs->disable_cap_level); in ab8500_fg_calculate_scaled_capacity()
1232 } else if (!di->flags.fully_charged) { in ab8500_fg_calculate_scaled_capacity()
1233 if (di->bat_cap.prev_percent >= in ab8500_fg_calculate_scaled_capacity()
1234 cs->disable_cap_level) { in ab8500_fg_calculate_scaled_capacity()
1235 dev_dbg(di->dev, "Disabling scaled capacity\n"); in ab8500_fg_calculate_scaled_capacity()
1236 cs->enable = false; in ab8500_fg_calculate_scaled_capacity()
1237 capacity = di->bat_cap.prev_percent; in ab8500_fg_calculate_scaled_capacity()
1239 dev_dbg(di->dev, in ab8500_fg_calculate_scaled_capacity()
1241 cs->disable_cap_level); in ab8500_fg_calculate_scaled_capacity()
1242 capacity = cs->disable_cap_level; in ab8500_fg_calculate_scaled_capacity()
1251 * ab8500_fg_update_cap_scalers() - Capacity scaling
1254 * To be called when state change from charge<->discharge to update
1259 struct ab8500_fg_cap_scaling *cs = &di->bat_cap.cap_scale; in ab8500_fg_update_cap_scalers()
1261 if (!cs->enable) in ab8500_fg_update_cap_scalers()
1263 if (di->flags.charging) { in ab8500_fg_update_cap_scalers()
1264 di->bat_cap.cap_scale.disable_cap_level = in ab8500_fg_update_cap_scalers()
1265 di->bat_cap.cap_scale.scaled_cap; in ab8500_fg_update_cap_scalers()
1266 dev_dbg(di->dev, "Cap to stop scale at charge %d%%\n", in ab8500_fg_update_cap_scalers()
1267 di->bat_cap.cap_scale.disable_cap_level); in ab8500_fg_update_cap_scalers()
1269 if (cs->scaled_cap != 100) { in ab8500_fg_update_cap_scalers()
1270 cs->cap_to_scale[0] = cs->scaled_cap; in ab8500_fg_update_cap_scalers()
1271 cs->cap_to_scale[1] = di->bat_cap.prev_percent; in ab8500_fg_update_cap_scalers()
1273 cs->cap_to_scale[0] = 100; in ab8500_fg_update_cap_scalers()
1274 cs->cap_to_scale[1] = in ab8500_fg_update_cap_scalers()
1275 max(di->bat_cap.prev_percent, in ab8500_fg_update_cap_scalers()
1276 di->bm->fg_params->maint_thres); in ab8500_fg_update_cap_scalers()
1279 dev_dbg(di->dev, "Cap to scale at discharge %d/%d\n", in ab8500_fg_update_cap_scalers()
1280 cs->cap_to_scale[0], cs->cap_to_scale[1]); in ab8500_fg_update_cap_scalers()
1285 * ab8500_fg_check_capacity_limits() - Check if capacity has changed
1295 int percent = DIV_ROUND_CLOSEST(di->bat_cap.permille, 10); in ab8500_fg_check_capacity_limits()
1297 di->bat_cap.level = ab8500_fg_capacity_level(di); in ab8500_fg_check_capacity_limits()
1299 if (di->bat_cap.level != di->bat_cap.prev_level) { in ab8500_fg_check_capacity_limits()
1304 if (!(!di->flags.charging && di->bat_cap.level > in ab8500_fg_check_capacity_limits()
1305 di->bat_cap.prev_level) || init) { in ab8500_fg_check_capacity_limits()
1306 dev_dbg(di->dev, "level changed from %d to %d\n", in ab8500_fg_check_capacity_limits()
1307 di->bat_cap.prev_level, in ab8500_fg_check_capacity_limits()
1308 di->bat_cap.level); in ab8500_fg_check_capacity_limits()
1309 di->bat_cap.prev_level = di->bat_cap.level; in ab8500_fg_check_capacity_limits()
1312 dev_dbg(di->dev, "level not allowed to go up " in ab8500_fg_check_capacity_limits()
1314 di->bat_cap.prev_level, in ab8500_fg_check_capacity_limits()
1315 di->bat_cap.level); in ab8500_fg_check_capacity_limits()
1323 if (di->flags.low_bat) { in ab8500_fg_check_capacity_limits()
1324 dev_dbg(di->dev, "Battery low, set capacity to 0\n"); in ab8500_fg_check_capacity_limits()
1325 di->bat_cap.prev_percent = 0; in ab8500_fg_check_capacity_limits()
1326 di->bat_cap.permille = 0; in ab8500_fg_check_capacity_limits()
1328 di->bat_cap.prev_mah = 0; in ab8500_fg_check_capacity_limits()
1329 di->bat_cap.mah = 0; in ab8500_fg_check_capacity_limits()
1331 } else if (di->flags.fully_charged) { in ab8500_fg_check_capacity_limits()
1336 if (di->flags.force_full) { in ab8500_fg_check_capacity_limits()
1337 di->bat_cap.prev_percent = percent; in ab8500_fg_check_capacity_limits()
1338 di->bat_cap.prev_mah = di->bat_cap.mah; in ab8500_fg_check_capacity_limits()
1342 if (!di->bat_cap.cap_scale.enable && in ab8500_fg_check_capacity_limits()
1343 di->bm->capacity_scaling) { in ab8500_fg_check_capacity_limits()
1344 di->bat_cap.cap_scale.enable = true; in ab8500_fg_check_capacity_limits()
1345 di->bat_cap.cap_scale.cap_to_scale[0] = 100; in ab8500_fg_check_capacity_limits()
1346 di->bat_cap.cap_scale.cap_to_scale[1] = in ab8500_fg_check_capacity_limits()
1347 di->bat_cap.prev_percent; in ab8500_fg_check_capacity_limits()
1348 di->bat_cap.cap_scale.disable_cap_level = 100; in ab8500_fg_check_capacity_limits()
1350 } else if (di->bat_cap.prev_percent != percent) { in ab8500_fg_check_capacity_limits()
1351 dev_dbg(di->dev, in ab8500_fg_check_capacity_limits()
1355 di->bat_cap.prev_percent = percent; in ab8500_fg_check_capacity_limits()
1356 di->bat_cap.prev_mah = di->bat_cap.mah; in ab8500_fg_check_capacity_limits()
1360 } else if (di->bat_cap.prev_percent != percent) { in ab8500_fg_check_capacity_limits()
1367 di->bat_cap.prev_percent = 1; in ab8500_fg_check_capacity_limits()
1371 } else if (!(!di->flags.charging && in ab8500_fg_check_capacity_limits()
1372 percent > di->bat_cap.prev_percent) || init) { in ab8500_fg_check_capacity_limits()
1377 dev_dbg(di->dev, in ab8500_fg_check_capacity_limits()
1379 di->bat_cap.prev_percent, in ab8500_fg_check_capacity_limits()
1381 di->bat_cap.permille); in ab8500_fg_check_capacity_limits()
1382 di->bat_cap.prev_percent = percent; in ab8500_fg_check_capacity_limits()
1383 di->bat_cap.prev_mah = di->bat_cap.mah; in ab8500_fg_check_capacity_limits()
1387 dev_dbg(di->dev, "capacity not allowed to go up since " in ab8500_fg_check_capacity_limits()
1389 di->bat_cap.prev_percent, in ab8500_fg_check_capacity_limits()
1391 di->bat_cap.permille); in ab8500_fg_check_capacity_limits()
1396 if (di->bm->capacity_scaling) { in ab8500_fg_check_capacity_limits()
1397 di->bat_cap.cap_scale.scaled_cap = in ab8500_fg_check_capacity_limits()
1400 dev_info(di->dev, "capacity=%d (%d)\n", in ab8500_fg_check_capacity_limits()
1401 di->bat_cap.prev_percent, in ab8500_fg_check_capacity_limits()
1402 di->bat_cap.cap_scale.scaled_cap); in ab8500_fg_check_capacity_limits()
1404 power_supply_changed(di->fg_psy); in ab8500_fg_check_capacity_limits()
1405 if (di->flags.fully_charged && di->flags.force_full) { in ab8500_fg_check_capacity_limits()
1406 dev_dbg(di->dev, "Battery full, notifying.\n"); in ab8500_fg_check_capacity_limits()
1407 di->flags.force_full = false; in ab8500_fg_check_capacity_limits()
1408 sysfs_notify(&di->fg_kobject, NULL, "charge_full"); in ab8500_fg_check_capacity_limits()
1410 sysfs_notify(&di->fg_kobject, NULL, "charge_now"); in ab8500_fg_check_capacity_limits()
1417 dev_dbg(di->dev, "Charge state from %d [%s] to %d [%s]\n", in ab8500_fg_charge_state_to()
1418 di->charge_state, in ab8500_fg_charge_state_to()
1419 charge_state[di->charge_state], in ab8500_fg_charge_state_to()
1423 di->charge_state = new_state; in ab8500_fg_charge_state_to()
1429 dev_dbg(di->dev, "Discharge state from %d [%s] to %d [%s]\n", in ab8500_fg_discharge_state_to()
1430 di->discharge_state, in ab8500_fg_discharge_state_to()
1431 discharge_state[di->discharge_state], in ab8500_fg_discharge_state_to()
1435 di->discharge_state = new_state; in ab8500_fg_discharge_state_to()
1439 * ab8500_fg_algorithm_charging() - FG algorithm for when charging
1450 if (di->discharge_state != AB8500_FG_DISCHARGE_INIT_RECOVERY) in ab8500_fg_algorithm_charging()
1454 switch (di->charge_state) { in ab8500_fg_algorithm_charging()
1456 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_charging()
1457 di->bm->fg_params->accu_charging); in ab8500_fg_algorithm_charging()
1468 mutex_lock(&di->cc_lock); in ab8500_fg_algorithm_charging()
1469 if (!di->flags.conv_done && !di->flags.force_full) { in ab8500_fg_algorithm_charging()
1471 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_charging()
1472 dev_dbg(di->dev, "%s CC conv not done\n", in ab8500_fg_algorithm_charging()
1477 di->flags.conv_done = false; in ab8500_fg_algorithm_charging()
1478 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_charging()
1497 cap = di->bat_cap.user_mah; in force_capacity()
1498 if (cap > di->bat_cap.max_mah_design) { in force_capacity()
1499 dev_dbg(di->dev, "Remaining cap %d can't be bigger than total" in force_capacity()
1500 " %d\n", cap, di->bat_cap.max_mah_design); in force_capacity()
1501 cap = di->bat_cap.max_mah_design; in force_capacity()
1503 ab8500_fg_fill_cap_sample(di, di->bat_cap.user_mah); in force_capacity()
1504 di->bat_cap.permille = ab8500_fg_convert_mah_to_permille(di, cap); in force_capacity()
1505 di->bat_cap.mah = cap; in force_capacity()
1514 cap = di->bat_cap.user_mah; in check_sysfs_capacity()
1517 di->bat_cap.user_mah); in check_sysfs_capacity()
1519 lower = di->bat_cap.permille - di->bm->fg_params->user_cap_limit * 10; in check_sysfs_capacity()
1520 upper = di->bat_cap.permille + di->bm->fg_params->user_cap_limit * 10; in check_sysfs_capacity()
1524 /* 1000 is permille, -> 100 percent */ in check_sysfs_capacity()
1528 dev_dbg(di->dev, "Capacity limits:" in check_sysfs_capacity()
1530 lower, cap_permille, upper, cap, di->bat_cap.mah); in check_sysfs_capacity()
1534 dev_dbg(di->dev, "OK! Using users cap %d uAh now\n", cap); in check_sysfs_capacity()
1538 dev_dbg(di->dev, "Capacity from user out of limits, ignoring"); in check_sysfs_capacity()
1543 * ab8500_fg_algorithm_discharging() - FG algorithm for when discharging
1552 /* If we change to charge mode we should start with init */ in ab8500_fg_algorithm_discharging()
1553 if (di->charge_state != AB8500_FG_CHARGE_INIT) in ab8500_fg_algorithm_discharging()
1556 switch (di->discharge_state) { in ab8500_fg_algorithm_discharging()
1559 di->init_cnt = 0; in ab8500_fg_algorithm_discharging()
1560 di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer); in ab8500_fg_algorithm_discharging()
1573 sleep_time = di->bm->fg_params->init_timer; in ab8500_fg_algorithm_discharging()
1576 if (di->init_cnt > di->bm->fg_params->init_discard_time) { in ab8500_fg_algorithm_discharging()
1582 di->init_cnt += sleep_time; in ab8500_fg_algorithm_discharging()
1583 if (di->init_cnt > di->bm->fg_params->init_total_time) in ab8500_fg_algorithm_discharging()
1590 di->recovery_cnt = 0; in ab8500_fg_algorithm_discharging()
1591 di->recovery_needed = true; in ab8500_fg_algorithm_discharging()
1598 sleep_time = di->bm->fg_params->recovery_sleep_timer; in ab8500_fg_algorithm_discharging()
1606 di->inst_curr_ua = ab8500_fg_inst_curr_blocking(di); in ab8500_fg_algorithm_discharging()
1608 if (ab8500_fg_is_low_curr(di, di->inst_curr_ua)) { in ab8500_fg_algorithm_discharging()
1609 if (di->recovery_cnt > in ab8500_fg_algorithm_discharging()
1610 di->bm->fg_params->recovery_total_time) { in ab8500_fg_algorithm_discharging()
1611 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1612 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1616 di->recovery_needed = false; in ab8500_fg_algorithm_discharging()
1618 queue_delayed_work(di->fg_wq, in ab8500_fg_algorithm_discharging()
1619 &di->fg_periodic_work, in ab8500_fg_algorithm_discharging()
1622 di->recovery_cnt += sleep_time; in ab8500_fg_algorithm_discharging()
1624 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1625 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1633 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1634 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1641 di->inst_curr_ua = ab8500_fg_inst_curr_blocking(di); in ab8500_fg_algorithm_discharging()
1643 if (ab8500_fg_is_low_curr(di, di->inst_curr_ua)) { in ab8500_fg_algorithm_discharging()
1645 if (di->high_curr_mode) { in ab8500_fg_algorithm_discharging()
1646 di->high_curr_mode = false; in ab8500_fg_algorithm_discharging()
1647 di->high_curr_cnt = 0; in ab8500_fg_algorithm_discharging()
1650 if (di->recovery_needed) { in ab8500_fg_algorithm_discharging()
1654 queue_delayed_work(di->fg_wq, in ab8500_fg_algorithm_discharging()
1655 &di->fg_periodic_work, 0); in ab8500_fg_algorithm_discharging()
1662 mutex_lock(&di->cc_lock); in ab8500_fg_algorithm_discharging()
1663 if (!di->flags.conv_done) { in ab8500_fg_algorithm_discharging()
1665 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_discharging()
1666 dev_dbg(di->dev, "%s CC conv not done\n", in ab8500_fg_algorithm_discharging()
1671 di->flags.conv_done = false; in ab8500_fg_algorithm_discharging()
1672 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_discharging()
1675 if (!di->high_curr_mode) { in ab8500_fg_algorithm_discharging()
1676 di->high_curr_mode = true; in ab8500_fg_algorithm_discharging()
1677 di->high_curr_cnt = 0; in ab8500_fg_algorithm_discharging()
1680 di->high_curr_cnt += in ab8500_fg_algorithm_discharging()
1681 di->bm->fg_params->accu_high_curr; in ab8500_fg_algorithm_discharging()
1682 if (di->high_curr_cnt > in ab8500_fg_algorithm_discharging()
1683 di->bm->fg_params->high_curr_time) in ab8500_fg_algorithm_discharging()
1684 di->recovery_needed = true; in ab8500_fg_algorithm_discharging()
1696 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1697 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1712 * ab8500_fg_algorithm_calibrate() - Internal columb counter offset calibration
1720 switch (di->calib_state) { in ab8500_fg_algorithm_calibrate()
1722 dev_dbg(di->dev, "Calibration ongoing...\n"); in ab8500_fg_algorithm_calibrate()
1724 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_algorithm_calibrate()
1730 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_algorithm_calibrate()
1735 di->calib_state = AB8500_FG_CALIB_WAIT; in ab8500_fg_algorithm_calibrate()
1738 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_algorithm_calibrate()
1743 di->flags.calibrate = false; in ab8500_fg_algorithm_calibrate()
1744 dev_dbg(di->dev, "Calibration done...\n"); in ab8500_fg_algorithm_calibrate()
1745 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_algorithm_calibrate()
1748 dev_dbg(di->dev, "Calibration WFI\n"); in ab8500_fg_algorithm_calibrate()
1756 dev_err(di->dev, "failed to calibrate the CC\n"); in ab8500_fg_algorithm_calibrate()
1757 di->flags.calibrate = false; in ab8500_fg_algorithm_calibrate()
1758 di->calib_state = AB8500_FG_CALIB_INIT; in ab8500_fg_algorithm_calibrate()
1759 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_algorithm_calibrate()
1763 * ab8500_fg_algorithm() - Entry point for the FG algorithm
1770 if (di->flags.calibrate) in ab8500_fg_algorithm()
1773 if (di->flags.charging) in ab8500_fg_algorithm()
1779 dev_dbg(di->dev, "[FG_DATA] %d %d %d %d %d %d %d %d %d %d " in ab8500_fg_algorithm()
1781 di->bat_cap.max_mah_design, in ab8500_fg_algorithm()
1782 di->bat_cap.max_mah, in ab8500_fg_algorithm()
1783 di->bat_cap.mah, in ab8500_fg_algorithm()
1784 di->bat_cap.permille, in ab8500_fg_algorithm()
1785 di->bat_cap.level, in ab8500_fg_algorithm()
1786 di->bat_cap.prev_mah, in ab8500_fg_algorithm()
1787 di->bat_cap.prev_percent, in ab8500_fg_algorithm()
1788 di->bat_cap.prev_level, in ab8500_fg_algorithm()
1789 di->vbat_uv, in ab8500_fg_algorithm()
1790 di->inst_curr_ua, in ab8500_fg_algorithm()
1791 di->avg_curr_ua, in ab8500_fg_algorithm()
1792 di->accu_charge, in ab8500_fg_algorithm()
1793 di->flags.charging, in ab8500_fg_algorithm()
1794 di->charge_state, in ab8500_fg_algorithm()
1795 di->discharge_state, in ab8500_fg_algorithm()
1796 di->high_curr_mode, in ab8500_fg_algorithm()
1797 di->recovery_needed); in ab8500_fg_algorithm()
1801 * ab8500_fg_periodic_work() - Run the FG state machine periodically
1811 if (di->init_capacity) { in ab8500_fg_periodic_work()
1815 di->init_capacity = false; in ab8500_fg_periodic_work()
1817 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_periodic_work()
1818 } else if (di->flags.user_cap) { in ab8500_fg_periodic_work()
1821 if (di->flags.charging) in ab8500_fg_periodic_work()
1828 di->flags.user_cap = false; in ab8500_fg_periodic_work()
1829 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_periodic_work()
1836 * ab8500_fg_check_hw_failure_work() - Check OVV_BAT condition
1850 * If we have had a battery over-voltage situation, in ab8500_fg_check_hw_failure_work()
1851 * check ovv-bit to see if it should be reset. in ab8500_fg_check_hw_failure_work()
1853 ret = abx500_get_register_interruptible(di->dev, in ab8500_fg_check_hw_failure_work()
1857 dev_err(di->dev, "%s ab8500 read failed\n", __func__); in ab8500_fg_check_hw_failure_work()
1861 if (!di->flags.bat_ovv) { in ab8500_fg_check_hw_failure_work()
1862 dev_dbg(di->dev, "Battery OVV\n"); in ab8500_fg_check_hw_failure_work()
1863 di->flags.bat_ovv = true; in ab8500_fg_check_hw_failure_work()
1864 power_supply_changed(di->fg_psy); in ab8500_fg_check_hw_failure_work()
1867 queue_delayed_work(di->fg_wq, &di->fg_check_hw_failure_work, in ab8500_fg_check_hw_failure_work()
1870 dev_dbg(di->dev, "Battery recovered from OVV\n"); in ab8500_fg_check_hw_failure_work()
1871 di->flags.bat_ovv = false; in ab8500_fg_check_hw_failure_work()
1872 power_supply_changed(di->fg_psy); in ab8500_fg_check_hw_failure_work()
1877 * ab8500_fg_low_bat_work() - Check LOW_BAT condition
1892 if (vbat_uv < di->bm->fg_params->lowbat_threshold_uv) { in ab8500_fg_low_bat_work()
1894 if (di->low_bat_cnt < 1) { in ab8500_fg_low_bat_work()
1895 di->flags.low_bat = true; in ab8500_fg_low_bat_work()
1896 dev_warn(di->dev, "Shut down pending...\n"); in ab8500_fg_low_bat_work()
1899 * Else we need to re-schedule this check to be able to detect in ab8500_fg_low_bat_work()
1903 di->low_bat_cnt--; in ab8500_fg_low_bat_work()
1904 dev_warn(di->dev, "Battery voltage still LOW\n"); in ab8500_fg_low_bat_work()
1905 queue_delayed_work(di->fg_wq, &di->fg_low_bat_work, in ab8500_fg_low_bat_work()
1909 di->flags.low_bat_delay = false; in ab8500_fg_low_bat_work()
1910 di->low_bat_cnt = 10; in ab8500_fg_low_bat_work()
1911 dev_warn(di->dev, "Battery voltage OK again\n"); in ab8500_fg_low_bat_work()
1919 * ab8500_fg_battok_calc - calculate the bit pattern corresponding
1925 * valid return values are 0-14. (0-BATT_OK_MAX_NR_INCREMENTS)
1935 return (target - BATT_OK_MIN) / BATT_OK_INCREMENT; in ab8500_fg_battok_calc()
1939 * ab8500_fg_battok_init_hw_register - init battok levels
1954 sel0 = di->bm->fg_params->battok_falling_th_sel0; in ab8500_fg_battok_init_hw_register()
1955 sel1 = di->bm->fg_params->battok_raising_th_sel1; in ab8500_fg_battok_init_hw_register()
1963 dev_warn(di->dev, "Invalid voltage step:%d, using %d %d\n", in ab8500_fg_battok_init_hw_register()
1969 dev_warn(di->dev, "Invalid voltage step:%d, using %d %d\n", in ab8500_fg_battok_init_hw_register()
1974 dev_dbg(di->dev, "using: %x %d %d\n", new_val, cbp_sel0, cbp_sel1); in ab8500_fg_battok_init_hw_register()
1975 ret = abx500_set_register_interruptible(di->dev, AB8500_SYS_CTRL2_BLOCK, in ab8500_fg_battok_init_hw_register()
1981 * ab8500_fg_instant_work() - Run the FG state machine instantly
1994 * ab8500_fg_cc_data_end_handler() - end of data conversion isr.
2003 if (!di->nbr_cceoc_irq_cnt) { in ab8500_fg_cc_data_end_handler()
2004 di->nbr_cceoc_irq_cnt++; in ab8500_fg_cc_data_end_handler()
2005 complete(&di->ab8500_fg_started); in ab8500_fg_cc_data_end_handler()
2007 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_cc_data_end_handler()
2008 complete(&di->ab8500_fg_complete); in ab8500_fg_cc_data_end_handler()
2014 * ab8500_fg_cc_int_calib_handler () - end of calibration isr.
2023 di->calib_state = AB8500_FG_CALIB_END; in ab8500_fg_cc_int_calib_handler()
2024 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_cc_int_calib_handler()
2029 * ab8500_fg_cc_convend_handler() - isr to get battery avg current.
2039 queue_work(di->fg_wq, &di->fg_acc_cur_work); in ab8500_fg_cc_convend_handler()
2045 * ab8500_fg_batt_ovv_handler() - Battery OVV occured
2055 dev_dbg(di->dev, "Battery OVV\n"); in ab8500_fg_batt_ovv_handler()
2058 queue_delayed_work(di->fg_wq, &di->fg_check_hw_failure_work, 0); in ab8500_fg_batt_ovv_handler()
2064 * ab8500_fg_lowbatf_handler() - Battery voltage is below LOW threshold
2075 if (!di->flags.low_bat_delay) { in ab8500_fg_lowbatf_handler()
2076 dev_warn(di->dev, "Battery voltage is below LOW threshold\n"); in ab8500_fg_lowbatf_handler()
2077 di->flags.low_bat_delay = true; in ab8500_fg_lowbatf_handler()
2082 queue_delayed_work(di->fg_wq, &di->fg_low_bat_work, in ab8500_fg_lowbatf_handler()
2089 * ab8500_fg_get_property() - get the fg properties
2121 if (di->flags.bat_ovv) in ab8500_fg_get_property()
2122 val->intval = BATT_OVV_VALUE; in ab8500_fg_get_property()
2124 val->intval = di->vbat_uv; in ab8500_fg_get_property()
2127 val->intval = di->inst_curr_ua; in ab8500_fg_get_property()
2130 val->intval = di->avg_curr_ua; in ab8500_fg_get_property()
2133 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2134 di->bat_cap.max_mah_design); in ab8500_fg_get_property()
2137 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2138 di->bat_cap.max_mah); in ab8500_fg_get_property()
2141 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2142 di->flags.batt_id_received) in ab8500_fg_get_property()
2143 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2144 di->bat_cap.max_mah); in ab8500_fg_get_property()
2146 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2147 di->bat_cap.prev_mah); in ab8500_fg_get_property()
2150 val->intval = di->bat_cap.max_mah_design; in ab8500_fg_get_property()
2153 val->intval = di->bat_cap.max_mah; in ab8500_fg_get_property()
2156 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2157 di->flags.batt_id_received) in ab8500_fg_get_property()
2158 val->intval = di->bat_cap.max_mah; in ab8500_fg_get_property()
2160 val->intval = di->bat_cap.prev_mah; in ab8500_fg_get_property()
2163 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2164 di->flags.batt_id_received) in ab8500_fg_get_property()
2165 val->intval = 100; in ab8500_fg_get_property()
2167 val->intval = di->bat_cap.prev_percent; in ab8500_fg_get_property()
2170 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2171 di->flags.batt_id_received) in ab8500_fg_get_property()
2172 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; in ab8500_fg_get_property()
2174 val->intval = di->bat_cap.prev_level; in ab8500_fg_get_property()
2177 return -EINVAL; in ab8500_fg_get_property()
2186 const char **supplicants = (const char **)ext->supplied_to; in ab8500_fg_get_ext_psy_data()
2194 bi = di->bm->bi; in ab8500_fg_get_ext_psy_data()
2200 j = match_string(supplicants, ext->num_supplicants, psy->desc->name); in ab8500_fg_get_ext_psy_data()
2205 for (j = 0; j < ext->desc->num_properties; j++) { in ab8500_fg_get_ext_psy_data()
2207 prop = ext->desc->properties[j]; in ab8500_fg_get_ext_psy_data()
2214 switch (ext->desc->type) { in ab8500_fg_get_ext_psy_data()
2220 if (!di->flags.charging) in ab8500_fg_get_ext_psy_data()
2222 di->flags.charging = false; in ab8500_fg_get_ext_psy_data()
2223 di->flags.fully_charged = false; in ab8500_fg_get_ext_psy_data()
2224 if (di->bm->capacity_scaling) in ab8500_fg_get_ext_psy_data()
2226 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_get_ext_psy_data()
2229 if (di->flags.fully_charged) in ab8500_fg_get_ext_psy_data()
2231 di->flags.fully_charged = true; in ab8500_fg_get_ext_psy_data()
2232 di->flags.force_full = true; in ab8500_fg_get_ext_psy_data()
2234 di->bat_cap.max_mah = di->bat_cap.mah; in ab8500_fg_get_ext_psy_data()
2235 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_get_ext_psy_data()
2238 if (di->flags.charging && in ab8500_fg_get_ext_psy_data()
2239 !di->flags.fully_charged) in ab8500_fg_get_ext_psy_data()
2241 di->flags.charging = true; in ab8500_fg_get_ext_psy_data()
2242 di->flags.fully_charged = false; in ab8500_fg_get_ext_psy_data()
2243 if (di->bm->capacity_scaling) in ab8500_fg_get_ext_psy_data()
2245 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_get_ext_psy_data()
2254 switch (ext->desc->type) { in ab8500_fg_get_ext_psy_data()
2256 if (!di->flags.batt_id_received && in ab8500_fg_get_ext_psy_data()
2257 (bi && (bi->technology != in ab8500_fg_get_ext_psy_data()
2259 di->flags.batt_id_received = true; in ab8500_fg_get_ext_psy_data()
2261 di->bat_cap.max_mah_design = in ab8500_fg_get_ext_psy_data()
2262 di->bm->bi->charge_full_design_uah; in ab8500_fg_get_ext_psy_data()
2264 di->bat_cap.max_mah = in ab8500_fg_get_ext_psy_data()
2265 di->bat_cap.max_mah_design; in ab8500_fg_get_ext_psy_data()
2267 di->vbat_nom_uv = in ab8500_fg_get_ext_psy_data()
2268 di->bm->bi->voltage_max_design_uv; in ab8500_fg_get_ext_psy_data()
2272 di->flags.batt_unknown = false; in ab8500_fg_get_ext_psy_data()
2274 di->flags.batt_unknown = true; in ab8500_fg_get_ext_psy_data()
2281 switch (ext->desc->type) { in ab8500_fg_get_ext_psy_data()
2283 if (di->flags.batt_id_received) in ab8500_fg_get_ext_psy_data()
2284 di->bat_temp = ret.intval; in ab8500_fg_get_ext_psy_data()
2298 * ab8500_fg_init_hw_registers() - Set up FG related registers
2308 * Set VBAT OVV (overvoltage) threshold to 4.75V (typ) this is what in ab8500_fg_init_hw_registers()
2314 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_init_hw_registers()
2320 dev_err(di->dev, "failed to set BATT_OVV\n"); in ab8500_fg_init_hw_registers()
2325 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_init_hw_registers()
2331 dev_err(di->dev, "failed to enable BATT_OVV\n"); in ab8500_fg_init_hw_registers()
2336 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_init_hw_registers()
2340 di->bm->fg_params->lowbat_threshold_uv) << 1 | in ab8500_fg_init_hw_registers()
2343 dev_err(di->dev, "%s write failed\n", __func__); in ab8500_fg_init_hw_registers()
2347 /* Battery OK threshold */ in ab8500_fg_init_hw_registers()
2350 dev_err(di->dev, "BattOk init write failed.\n"); in ab8500_fg_init_hw_registers()
2354 if (is_ab8505(di->parent)) { in ab8500_fg_init_hw_registers()
2355 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2356 AB8505_RTC_PCUT_MAX_TIME_REG, di->bm->fg_params->pcut_max_time); in ab8500_fg_init_hw_registers()
2359 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_MAX_TIME_REG\n", __func__); in ab8500_fg_init_hw_registers()
2363 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2364 AB8505_RTC_PCUT_FLAG_TIME_REG, di->bm->fg_params->pcut_flag_time); in ab8500_fg_init_hw_registers()
2367 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_FLAG_TIME_REG\n", __func__); in ab8500_fg_init_hw_registers()
2371 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2372 AB8505_RTC_PCUT_RESTART_REG, di->bm->fg_params->pcut_max_restart); in ab8500_fg_init_hw_registers()
2375 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_RESTART_REG\n", __func__); in ab8500_fg_init_hw_registers()
2379 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2380 AB8505_RTC_PCUT_DEBOUNCE_REG, di->bm->fg_params->pcut_debounce_time); in ab8500_fg_init_hw_registers()
2383 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_DEBOUNCE_REG\n", __func__); in ab8500_fg_init_hw_registers()
2387 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2388 AB8505_RTC_PCUT_CTL_STATUS_REG, di->bm->fg_params->pcut_enable); in ab8500_fg_init_hw_registers()
2391 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_CTL_STATUS_REG\n", __func__); in ab8500_fg_init_hw_registers()
2400 * ab8500_fg_external_power_changed() - callback for power supply changes
2413 di->fg_psy, ab8500_fg_get_ext_psy_data); in ab8500_fg_external_power_changed()
2417 * ab8500_fg_reinit_work() - work to reset the FG algorithm
2429 if (!di->flags.calibrate) { in ab8500_fg_reinit_work()
2430 dev_dbg(di->dev, "Resetting FG state machine to init.\n"); in ab8500_fg_reinit_work()
2435 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_reinit_work()
2438 dev_err(di->dev, "Residual offset calibration ongoing " in ab8500_fg_reinit_work()
2441 queue_delayed_work(di->fg_wq, &di->fg_reinit_work, in ab8500_fg_reinit_work()
2456 return sprintf(buf, "%d\n", di->bat_cap.max_mah); in charge_full_show()
2469 di->bat_cap.max_mah = (int) charge_full; in charge_full_store()
2475 return sprintf(buf, "%d\n", di->bat_cap.prev_mah); in charge_now_show()
2488 di->bat_cap.user_mah = (int) charge_now; in charge_now_store()
2489 di->flags.user_cap = true; in charge_now_store()
2490 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in charge_now_store()
2509 if (!entry->show) in ab8500_fg_show()
2510 return -EIO; in ab8500_fg_show()
2512 return entry->show(di, buf); in ab8500_fg_show()
2524 if (!entry->store) in ab8500_fg_store()
2525 return -EIO; in ab8500_fg_store()
2527 return entry->store(di, buf, count); in ab8500_fg_store()
2548 * ab8500_fg_sysfs_exit() - de-init of sysfs entry
2555 kobject_del(&di->fg_kobject); in ab8500_fg_sysfs_exit()
2559 * ab8500_fg_sysfs_init() - init of sysfs entry
2569 ret = kobject_init_and_add(&di->fg_kobject, in ab8500_fg_sysfs_init()
2573 kobject_put(&di->fg_kobject); in ab8500_fg_sysfs_init()
2574 dev_err(di->dev, "failed to create sysfs entry\n"); in ab8500_fg_sysfs_init()
2589 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_flagtime_read()
2616 dev_err(dev, "Incorrect parameter, echo 0 (1.98s) - 127 (15.625ms) for flagtime\n"); in ab8505_powercut_flagtime_write()
2620 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_flagtime_write()
2639 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_maxtime_read()
2667 dev_err(dev, "Incorrect parameter, echo 0 (0.0s) - 127 (1.98s) for maxtime\n"); in ab8505_powercut_maxtime_write()
2671 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_maxtime_write()
2690 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_restart_read()
2717 dev_err(dev, "Incorrect parameter, echo 0 - 15 for number of restart\n"); in ab8505_powercut_restart_write()
2721 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_restart_write()
2741 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_timer_read()
2764 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_restart_counter_read()
2787 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_read()
2816 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_write()
2836 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_flag_read()
2859 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_debounce_read()
2890 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_debounce_write()
2909 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_enable_status_read()
2946 if (is_ab8505(di->parent)) { in ab8500_fg_sysfs_psy_create_attrs()
2948 if (device_create_file(&di->fg_psy->dev, in ab8500_fg_sysfs_psy_create_attrs()
2954 dev_err(&di->fg_psy->dev, "Failed creating sysfs psy attrs for ab8505.\n"); in ab8500_fg_sysfs_psy_create_attrs()
2955 while (i--) in ab8500_fg_sysfs_psy_create_attrs()
2956 device_remove_file(&di->fg_psy->dev, in ab8500_fg_sysfs_psy_create_attrs()
2959 return -EIO; in ab8500_fg_sysfs_psy_create_attrs()
2966 if (is_ab8505(di->parent)) { in ab8500_fg_sysfs_psy_remove_attrs()
2968 (void)device_remove_file(&di->fg_psy->dev, in ab8500_fg_sysfs_psy_remove_attrs()
2983 if (!di->flags.charging) { in ab8500_fg_resume()
2985 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_resume()
2995 flush_delayed_work(&di->fg_periodic_work); in ab8500_fg_suspend()
2996 flush_work(&di->fg_work); in ab8500_fg_suspend()
2997 flush_work(&di->fg_acc_cur_work); in ab8500_fg_suspend()
2998 flush_delayed_work(&di->fg_reinit_work); in ab8500_fg_suspend()
2999 flush_delayed_work(&di->fg_low_bat_work); in ab8500_fg_suspend()
3000 flush_delayed_work(&di->fg_check_hw_failure_work); in ab8500_fg_suspend()
3006 if (di->flags.fg_enabled && !di->flags.charging) in ab8500_fg_suspend()
3040 di->bat_cap.max_mah_design = di->bm->bi->charge_full_design_uah; in ab8500_fg_bind()
3041 di->bat_cap.max_mah = di->bat_cap.max_mah_design; in ab8500_fg_bind()
3042 di->vbat_nom_uv = di->bm->bi->voltage_max_design_uv; in ab8500_fg_bind()
3047 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_bind()
3063 flush_workqueue(di->fg_wq); in ab8500_fg_unbind()
3073 struct device *dev = &pdev->dev; in ab8500_fg_probe()
3081 return -ENOMEM; in ab8500_fg_probe()
3083 di->bm = &ab8500_bm_data; in ab8500_fg_probe()
3085 mutex_init(&di->cc_lock); in ab8500_fg_probe()
3088 di->dev = dev; in ab8500_fg_probe()
3089 di->parent = dev_get_drvdata(pdev->dev.parent); in ab8500_fg_probe()
3091 di->main_bat_v = devm_iio_channel_get(dev, "main_bat_v"); in ab8500_fg_probe()
3092 if (IS_ERR(di->main_bat_v)) { in ab8500_fg_probe()
3093 ret = dev_err_probe(dev, PTR_ERR(di->main_bat_v), in ab8500_fg_probe()
3098 if (!of_property_read_u32(dev->of_node, "line-impedance-micro-ohms", in ab8500_fg_probe()
3099 &di->line_impedance_uohm)) in ab8500_fg_probe()
3101 di->line_impedance_uohm); in ab8500_fg_probe()
3107 di->init_capacity = true; in ab8500_fg_probe()
3113 di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM); in ab8500_fg_probe()
3114 if (di->fg_wq == NULL) { in ab8500_fg_probe()
3116 return -ENOMEM; in ab8500_fg_probe()
3120 INIT_WORK(&di->fg_work, ab8500_fg_instant_work); in ab8500_fg_probe()
3123 INIT_WORK(&di->fg_acc_cur_work, ab8500_fg_acc_cur_work); in ab8500_fg_probe()
3126 INIT_DEFERRABLE_WORK(&di->fg_reinit_work, in ab8500_fg_probe()
3130 INIT_DEFERRABLE_WORK(&di->fg_periodic_work, in ab8500_fg_probe()
3134 INIT_DEFERRABLE_WORK(&di->fg_low_bat_work, in ab8500_fg_probe()
3138 INIT_DEFERRABLE_WORK(&di->fg_check_hw_failure_work, in ab8500_fg_probe()
3142 di->flags.low_bat = false; in ab8500_fg_probe()
3145 di->low_bat_cnt = 10; in ab8500_fg_probe()
3151 destroy_workqueue(di->fg_wq); in ab8500_fg_probe()
3156 di->flags.batt_unknown = true; in ab8500_fg_probe()
3157 di->flags.batt_id_received = false; in ab8500_fg_probe()
3160 di->fg_psy = devm_power_supply_register(dev, &ab8500_fg_desc, &psy_cfg); in ab8500_fg_probe()
3161 if (IS_ERR(di->fg_psy)) { in ab8500_fg_probe()
3163 destroy_workqueue(di->fg_wq); in ab8500_fg_probe()
3164 return PTR_ERR(di->fg_psy); in ab8500_fg_probe()
3167 di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer); in ab8500_fg_probe()
3173 init_completion(&di->ab8500_fg_started); in ab8500_fg_probe()
3174 init_completion(&di->ab8500_fg_complete); in ab8500_fg_probe()
3180 destroy_workqueue(di->fg_wq); in ab8500_fg_probe()
3192 destroy_workqueue(di->fg_wq); in ab8500_fg_probe()
3199 di->irq = platform_get_irq_byname(pdev, "CCEOC"); in ab8500_fg_probe()
3200 disable_irq(di->irq); in ab8500_fg_probe()
3201 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_probe()
3208 destroy_workqueue(di->fg_wq); in ab8500_fg_probe()
3216 destroy_workqueue(di->fg_wq); in ab8500_fg_probe()
3221 di->flags.calibrate = true; in ab8500_fg_probe()
3222 di->calib_state = AB8500_FG_CALIB_INIT; in ab8500_fg_probe()
3225 di->bat_temp = 210; in ab8500_fg_probe()
3227 list_add_tail(&di->node, &ab8500_fg_list); in ab8500_fg_probe()
3236 destroy_workqueue(di->fg_wq); in ab8500_fg_remove()
3237 component_del(&pdev->dev, &ab8500_fg_component_ops); in ab8500_fg_remove()
3238 list_del(&di->node); in ab8500_fg_remove()
3248 { .compatible = "stericsson,ab8500-fg", },
3257 .name = "ab8500-fg",
3264 MODULE_ALIAS("platform:ab8500-fg");