Lines Matching +full:avg +full:- +full:samples
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
34 #include <linux/mfd/abx500/ab8500-bm.h>
58 ((y1) + ((((y2) - (y1)) * ((x) - (x1))) / ((x2) - (x1))));
61 * struct ab8500_fg_interrupts - ab8500 fg interupts
107 int avg; member
108 int samples[NBR_AVG_SAMPLES]; member
156 * struct ab8500_fg - ab8500 FG device information
165 * @fg_samples: Number of samples used in the FG accumulation
243 * ab8500_fg_get() - returns a reference to the primary AB8500 fuel gauge
347 return (u8) i - 1; in ab8500_volt_to_regval()
351 return (u8) ARRAY_SIZE(ab8500_fg_lowbat_voltage_map) - 1; in ab8500_volt_to_regval()
355 * ab8500_fg_is_low_curr() - Low or high current mode
366 if (curr > -di->bm->fg_params->high_curr_threshold) in ab8500_fg_is_low_curr()
373 * ab8500_fg_add_cap_sample() - Add capacity to average filter
383 struct ab8500_fg_avg_cap *avg = &di->avg_cap; in ab8500_fg_add_cap_sample() local
386 avg->sum += sample - avg->samples[avg->pos]; in ab8500_fg_add_cap_sample()
387 avg->samples[avg->pos] = sample; in ab8500_fg_add_cap_sample()
388 avg->time_stamps[avg->pos] = now; in ab8500_fg_add_cap_sample()
389 avg->pos++; in ab8500_fg_add_cap_sample()
391 if (avg->pos == NBR_AVG_SAMPLES) in ab8500_fg_add_cap_sample()
392 avg->pos = 0; in ab8500_fg_add_cap_sample()
394 if (avg->nbr_samples < NBR_AVG_SAMPLES) in ab8500_fg_add_cap_sample()
395 avg->nbr_samples++; in ab8500_fg_add_cap_sample()
401 } while (now - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]); in ab8500_fg_add_cap_sample()
403 avg->avg = avg->sum / avg->nbr_samples; in ab8500_fg_add_cap_sample()
405 return avg->avg; in ab8500_fg_add_cap_sample()
409 * ab8500_fg_clear_cap_samples() - Clear average filter
417 struct ab8500_fg_avg_cap *avg = &di->avg_cap; in ab8500_fg_clear_cap_samples() local
419 avg->pos = 0; in ab8500_fg_clear_cap_samples()
420 avg->nbr_samples = 0; in ab8500_fg_clear_cap_samples()
421 avg->sum = 0; in ab8500_fg_clear_cap_samples()
422 avg->avg = 0; in ab8500_fg_clear_cap_samples()
425 avg->samples[i] = 0; in ab8500_fg_clear_cap_samples()
426 avg->time_stamps[i] = 0; in ab8500_fg_clear_cap_samples()
431 * ab8500_fg_fill_cap_sample() - Fill average filter
441 struct ab8500_fg_avg_cap *avg = &di->avg_cap; in ab8500_fg_fill_cap_sample() local
446 avg->samples[i] = sample; in ab8500_fg_fill_cap_sample()
447 avg->time_stamps[i] = now; in ab8500_fg_fill_cap_sample()
450 avg->pos = 0; in ab8500_fg_fill_cap_sample()
451 avg->nbr_samples = NBR_AVG_SAMPLES; in ab8500_fg_fill_cap_sample()
452 avg->sum = sample * NBR_AVG_SAMPLES; in ab8500_fg_fill_cap_sample()
453 avg->avg = sample; in ab8500_fg_fill_cap_sample()
457 * ab8500_fg_coulomb_counter() - enable coulomb counter
467 mutex_lock(&di->cc_lock); in ab8500_fg_coulomb_counter()
469 /* To be able to reprogram the number of samples, we have to in ab8500_fg_coulomb_counter()
471 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_coulomb_counter()
476 /* Program the samples */ in ab8500_fg_coulomb_counter()
477 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_coulomb_counter()
479 di->fg_samples); in ab8500_fg_coulomb_counter()
484 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_coulomb_counter()
490 di->flags.fg_enabled = true; in ab8500_fg_coulomb_counter()
493 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_coulomb_counter()
499 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_coulomb_counter()
505 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_coulomb_counter()
510 di->flags.fg_enabled = false; in ab8500_fg_coulomb_counter()
513 dev_dbg(di->dev, " CC enabled: %d Samples: %d\n", in ab8500_fg_coulomb_counter()
514 enable, di->fg_samples); in ab8500_fg_coulomb_counter()
516 mutex_unlock(&di->cc_lock); in ab8500_fg_coulomb_counter()
520 dev_err(di->dev, "%s Enabling coulomb counter failed\n", __func__); in ab8500_fg_coulomb_counter()
521 mutex_unlock(&di->cc_lock); in ab8500_fg_coulomb_counter()
526 * ab8500_fg_inst_curr_start() - start battery instantaneous current
538 mutex_lock(&di->cc_lock); in ab8500_fg_inst_curr_start()
540 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_inst_curr_start()
541 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_inst_curr_start()
547 dev_dbg(di->dev, "%s Enable FG\n", __func__); in ab8500_fg_inst_curr_start()
548 di->turn_off_fg = true; in ab8500_fg_inst_curr_start()
550 /* Program the samples */ in ab8500_fg_inst_curr_start()
551 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_inst_curr_start()
558 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_inst_curr_start()
564 di->turn_off_fg = false; in ab8500_fg_inst_curr_start()
568 reinit_completion(&di->ab8500_fg_started); in ab8500_fg_inst_curr_start()
569 reinit_completion(&di->ab8500_fg_complete); in ab8500_fg_inst_curr_start()
570 enable_irq(di->irq); in ab8500_fg_inst_curr_start()
575 mutex_unlock(&di->cc_lock); in ab8500_fg_inst_curr_start()
580 * ab8500_fg_inst_curr_started() - check if fg conversion has started
587 return completion_done(&di->ab8500_fg_started); in ab8500_fg_inst_curr_started()
591 * ab8500_fg_inst_curr_done() - check if fg conversion is done
598 return completion_done(&di->ab8500_fg_complete); in ab8500_fg_inst_curr_done()
602 * ab8500_fg_inst_curr_finalize() - battery instantaneous current
617 if (!completion_done(&di->ab8500_fg_complete)) { in ab8500_fg_inst_curr_finalize()
619 &di->ab8500_fg_complete, in ab8500_fg_inst_curr_finalize()
621 dev_dbg(di->dev, "Finalize time: %d ms\n", in ab8500_fg_inst_curr_finalize()
622 jiffies_to_msecs(INS_CURR_TIMEOUT - timeout)); in ab8500_fg_inst_curr_finalize()
624 ret = -ETIME; in ab8500_fg_inst_curr_finalize()
625 disable_irq(di->irq); in ab8500_fg_inst_curr_finalize()
626 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_inst_curr_finalize()
627 dev_err(di->dev, "completion timed out [%d]\n", in ab8500_fg_inst_curr_finalize()
633 disable_irq(di->irq); in ab8500_fg_inst_curr_finalize()
634 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_inst_curr_finalize()
636 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_inst_curr_finalize()
644 ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_inst_curr_finalize()
649 ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_inst_curr_finalize()
673 (1000 * di->bm->fg_res); in ab8500_fg_inst_curr_finalize()
675 if (di->turn_off_fg) { in ab8500_fg_inst_curr_finalize()
676 dev_dbg(di->dev, "%s Disable FG\n", __func__); in ab8500_fg_inst_curr_finalize()
679 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_inst_curr_finalize()
685 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_inst_curr_finalize()
690 mutex_unlock(&di->cc_lock); in ab8500_fg_inst_curr_finalize()
695 mutex_unlock(&di->cc_lock); in ab8500_fg_inst_curr_finalize()
700 * ab8500_fg_inst_curr_blocking() - battery instantaneous current
714 dev_err(di->dev, "Failed to initialize fg_inst\n"); in ab8500_fg_inst_curr_blocking()
719 if (!completion_done(&di->ab8500_fg_started)) { in ab8500_fg_inst_curr_blocking()
721 &di->ab8500_fg_started, in ab8500_fg_inst_curr_blocking()
723 dev_dbg(di->dev, "Start time: %d ms\n", in ab8500_fg_inst_curr_blocking()
724 jiffies_to_msecs(INS_CURR_TIMEOUT - timeout)); in ab8500_fg_inst_curr_blocking()
726 ret = -ETIME; in ab8500_fg_inst_curr_blocking()
727 dev_err(di->dev, "completion timed out [%d]\n", in ab8500_fg_inst_curr_blocking()
735 dev_err(di->dev, "Failed to finalize fg_inst\n"); in ab8500_fg_inst_curr_blocking()
739 dev_dbg(di->dev, "%s instant current: %d", __func__, res); in ab8500_fg_inst_curr_blocking()
742 disable_irq(di->irq); in ab8500_fg_inst_curr_blocking()
743 mutex_unlock(&di->cc_lock); in ab8500_fg_inst_curr_blocking()
748 * ab8500_fg_acc_cur_work() - average battery current
763 mutex_lock(&di->cc_lock); in ab8500_fg_acc_cur_work()
764 ret = abx500_set_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_acc_cur_work()
769 ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_acc_cur_work()
774 ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_acc_cur_work()
779 ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, in ab8500_fg_acc_cur_work()
796 di->accu_charge = (val * QLSB_NANO_AMP_HOURS_X10) / in ab8500_fg_acc_cur_work()
797 (100 * di->bm->fg_res); in ab8500_fg_acc_cur_work()
802 * time in hours (= samples / (3600 * 4)h) in ab8500_fg_acc_cur_work()
805 di->avg_curr = (val * QLSB_NANO_AMP_HOURS_X10 * 36) / in ab8500_fg_acc_cur_work()
806 (1000 * di->bm->fg_res * (di->fg_samples / 4)); in ab8500_fg_acc_cur_work()
808 di->flags.conv_done = true; in ab8500_fg_acc_cur_work()
810 mutex_unlock(&di->cc_lock); in ab8500_fg_acc_cur_work()
812 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_acc_cur_work()
814 dev_dbg(di->dev, "fg_res: %d, fg_samples: %d, gasg: %d, accu_charge: %d \n", in ab8500_fg_acc_cur_work()
815 di->bm->fg_res, di->fg_samples, val, di->accu_charge); in ab8500_fg_acc_cur_work()
818 dev_err(di->dev, in ab8500_fg_acc_cur_work()
820 mutex_unlock(&di->cc_lock); in ab8500_fg_acc_cur_work()
821 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_acc_cur_work()
825 * ab8500_fg_bat_voltage() - get battery voltage
835 ret = iio_read_channel_processed(di->main_bat_v, &vbat); in ab8500_fg_bat_voltage()
837 dev_err(di->dev, in ab8500_fg_bat_voltage()
848 * ab8500_fg_volt_to_capacity() - Voltage based capacity
860 tbl = di->bm->bat_type[di->bm->batt_id].v_to_cap_tbl, in ab8500_fg_volt_to_capacity()
861 tbl_size = di->bm->bat_type[di->bm->batt_id].n_v_cap_tbl_elements; in ab8500_fg_volt_to_capacity()
872 tbl[i-1].voltage, in ab8500_fg_volt_to_capacity()
873 tbl[i-1].capacity * 10); in ab8500_fg_volt_to_capacity()
880 dev_dbg(di->dev, "%s Vbat: %d, Cap: %d per mille", in ab8500_fg_volt_to_capacity()
887 * ab8500_fg_uncomp_volt_to_capacity() - Uncompensated voltage based capacity
895 di->vbat = ab8500_fg_bat_voltage(di); in ab8500_fg_uncomp_volt_to_capacity()
896 return ab8500_fg_volt_to_capacity(di, di->vbat); in ab8500_fg_uncomp_volt_to_capacity()
900 * ab8500_fg_battery_resistance() - Returns the battery inner resistance
912 tbl = di->bm->bat_type[di->bm->batt_id].batres_tbl; in ab8500_fg_battery_resistance()
913 tbl_size = di->bm->bat_type[di->bm->batt_id].n_batres_tbl_elements; in ab8500_fg_battery_resistance()
916 if (di->bat_temp / 10 > tbl[i].temp) in ab8500_fg_battery_resistance()
921 resist = interpolate(di->bat_temp / 10, in ab8500_fg_battery_resistance()
924 tbl[i-1].temp, in ab8500_fg_battery_resistance()
925 tbl[i-1].resist); in ab8500_fg_battery_resistance()
929 resist = tbl[tbl_size - 1].resist; in ab8500_fg_battery_resistance()
932 dev_dbg(di->dev, "%s Temp: %d battery internal resistance: %d" in ab8500_fg_battery_resistance()
934 __func__, di->bat_temp, resist, di->bm->fg_res / 10, in ab8500_fg_battery_resistance()
935 (di->bm->fg_res / 10) + resist); in ab8500_fg_battery_resistance()
938 resist += di->bm->fg_res / 10; in ab8500_fg_battery_resistance()
944 * ab8500_fg_load_comp_volt_to_capacity() - Load compensated voltage based capacity
964 ab8500_fg_inst_curr_finalize(di, &di->inst_curr); in ab8500_fg_load_comp_volt_to_capacity()
966 di->vbat = vbat / i; in ab8500_fg_load_comp_volt_to_capacity()
970 vbat_comp = di->vbat - (di->inst_curr * res) / 1000; in ab8500_fg_load_comp_volt_to_capacity()
972 dev_dbg(di->dev, "%s Measured Vbat: %dmV,Compensated Vbat %dmV, " in ab8500_fg_load_comp_volt_to_capacity()
973 "R: %dmOhm, Current: %dmA Vbat Samples: %d\n", in ab8500_fg_load_comp_volt_to_capacity()
974 __func__, di->vbat, vbat_comp, res, di->inst_curr, i); in ab8500_fg_load_comp_volt_to_capacity()
980 * ab8500_fg_convert_mah_to_permille() - Capacity in mAh to permille
988 return (cap_mah * 1000) / di->bat_cap.max_mah_design; in ab8500_fg_convert_mah_to_permille()
992 * ab8500_fg_convert_permille_to_mah() - Capacity in permille to mAh
1000 return cap_pm * di->bat_cap.max_mah_design / 1000; in ab8500_fg_convert_permille_to_mah()
1004 * ab8500_fg_convert_mah_to_uwh() - Capacity in mAh to uWh
1015 div_res = ((u64) cap_mah) * ((u64) di->vbat_nom); in ab8500_fg_convert_mah_to_uwh()
1026 * ab8500_fg_calc_cap_charging() - Calculate remaining capacity while charging
1034 dev_dbg(di->dev, "%s cap_mah %d accu_charge %d\n", in ab8500_fg_calc_cap_charging()
1036 di->bat_cap.mah, in ab8500_fg_calc_cap_charging()
1037 di->accu_charge); in ab8500_fg_calc_cap_charging()
1040 if (di->bat_cap.mah + di->accu_charge > 0) in ab8500_fg_calc_cap_charging()
1041 di->bat_cap.mah += di->accu_charge; in ab8500_fg_calc_cap_charging()
1043 di->bat_cap.mah = 0; in ab8500_fg_calc_cap_charging()
1048 if (di->bat_cap.mah >= di->bat_cap.max_mah_design || in ab8500_fg_calc_cap_charging()
1049 di->flags.force_full) { in ab8500_fg_calc_cap_charging()
1050 di->bat_cap.mah = di->bat_cap.max_mah_design; in ab8500_fg_calc_cap_charging()
1053 ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); in ab8500_fg_calc_cap_charging()
1054 di->bat_cap.permille = in ab8500_fg_calc_cap_charging()
1055 ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_charging()
1058 di->vbat = ab8500_fg_bat_voltage(di); in ab8500_fg_calc_cap_charging()
1059 di->inst_curr = ab8500_fg_inst_curr_blocking(di); in ab8500_fg_calc_cap_charging()
1061 return di->bat_cap.mah; in ab8500_fg_calc_cap_charging()
1065 * ab8500_fg_calc_cap_discharge_voltage() - Capacity in discharge with voltage
1084 di->bat_cap.mah = ab8500_fg_add_cap_sample(di, mah); in ab8500_fg_calc_cap_discharge_voltage()
1085 di->bat_cap.permille = in ab8500_fg_calc_cap_discharge_voltage()
1086 ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_voltage()
1088 return di->bat_cap.mah; in ab8500_fg_calc_cap_discharge_voltage()
1092 * ab8500_fg_calc_cap_discharge_fg() - Capacity in discharge with FG
1103 dev_dbg(di->dev, "%s cap_mah %d accu_charge %d\n", in ab8500_fg_calc_cap_discharge_fg()
1105 di->bat_cap.mah, in ab8500_fg_calc_cap_discharge_fg()
1106 di->accu_charge); in ab8500_fg_calc_cap_discharge_fg()
1109 if (di->bat_cap.mah + di->accu_charge > 0) in ab8500_fg_calc_cap_discharge_fg()
1110 di->bat_cap.mah += di->accu_charge; in ab8500_fg_calc_cap_discharge_fg()
1112 di->bat_cap.mah = 0; in ab8500_fg_calc_cap_discharge_fg()
1114 if (di->bat_cap.mah >= di->bat_cap.max_mah_design) in ab8500_fg_calc_cap_discharge_fg()
1115 di->bat_cap.mah = di->bat_cap.max_mah_design; in ab8500_fg_calc_cap_discharge_fg()
1121 permille = ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1125 di->bat_cap.permille = permille_volt; in ab8500_fg_calc_cap_discharge_fg()
1126 di->bat_cap.mah = ab8500_fg_convert_permille_to_mah(di, in ab8500_fg_calc_cap_discharge_fg()
1127 di->bat_cap.permille); in ab8500_fg_calc_cap_discharge_fg()
1129 dev_dbg(di->dev, "%s voltage based: perm %d perm_volt %d\n", in ab8500_fg_calc_cap_discharge_fg()
1134 ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1136 ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1137 di->bat_cap.permille = in ab8500_fg_calc_cap_discharge_fg()
1138 ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1141 return di->bat_cap.mah; in ab8500_fg_calc_cap_discharge_fg()
1145 * ab8500_fg_capacity_level() - Get the battery capacity level
1154 percent = DIV_ROUND_CLOSEST(di->bat_cap.permille, 10); in ab8500_fg_capacity_level()
1156 if (percent <= di->bm->cap_levels->critical || in ab8500_fg_capacity_level()
1157 di->flags.low_bat) in ab8500_fg_capacity_level()
1159 else if (percent <= di->bm->cap_levels->low) in ab8500_fg_capacity_level()
1161 else if (percent <= di->bm->cap_levels->normal) in ab8500_fg_capacity_level()
1163 else if (percent <= di->bm->cap_levels->high) in ab8500_fg_capacity_level()
1172 * ab8500_fg_calculate_scaled_capacity() - Capacity scaling
1181 struct ab8500_fg_cap_scaling *cs = &di->bat_cap.cap_scale; in ab8500_fg_calculate_scaled_capacity()
1182 int capacity = di->bat_cap.prev_percent; in ab8500_fg_calculate_scaled_capacity()
1184 if (!cs->enable) in ab8500_fg_calculate_scaled_capacity()
1191 if (di->flags.fully_charged) { in ab8500_fg_calculate_scaled_capacity()
1192 cs->cap_to_scale[0] = 100; in ab8500_fg_calculate_scaled_capacity()
1193 cs->cap_to_scale[1] = in ab8500_fg_calculate_scaled_capacity()
1194 max(capacity, di->bm->fg_params->maint_thres); in ab8500_fg_calculate_scaled_capacity()
1195 dev_dbg(di->dev, "Scale cap with %d/%d\n", in ab8500_fg_calculate_scaled_capacity()
1196 cs->cap_to_scale[0], cs->cap_to_scale[1]); in ab8500_fg_calculate_scaled_capacity()
1200 if ((cs->cap_to_scale[0] != cs->cap_to_scale[1]) in ab8500_fg_calculate_scaled_capacity()
1201 && (cs->cap_to_scale[1] > 0)) in ab8500_fg_calculate_scaled_capacity()
1203 DIV_ROUND_CLOSEST(di->bat_cap.prev_percent * in ab8500_fg_calculate_scaled_capacity()
1204 cs->cap_to_scale[0], in ab8500_fg_calculate_scaled_capacity()
1205 cs->cap_to_scale[1])); in ab8500_fg_calculate_scaled_capacity()
1207 if (di->flags.charging) { in ab8500_fg_calculate_scaled_capacity()
1208 if (capacity < cs->disable_cap_level) { in ab8500_fg_calculate_scaled_capacity()
1209 cs->disable_cap_level = capacity; in ab8500_fg_calculate_scaled_capacity()
1210 dev_dbg(di->dev, "Cap to stop scale lowered %d%%\n", in ab8500_fg_calculate_scaled_capacity()
1211 cs->disable_cap_level); in ab8500_fg_calculate_scaled_capacity()
1212 } else if (!di->flags.fully_charged) { in ab8500_fg_calculate_scaled_capacity()
1213 if (di->bat_cap.prev_percent >= in ab8500_fg_calculate_scaled_capacity()
1214 cs->disable_cap_level) { in ab8500_fg_calculate_scaled_capacity()
1215 dev_dbg(di->dev, "Disabling scaled capacity\n"); in ab8500_fg_calculate_scaled_capacity()
1216 cs->enable = false; in ab8500_fg_calculate_scaled_capacity()
1217 capacity = di->bat_cap.prev_percent; in ab8500_fg_calculate_scaled_capacity()
1219 dev_dbg(di->dev, in ab8500_fg_calculate_scaled_capacity()
1221 cs->disable_cap_level); in ab8500_fg_calculate_scaled_capacity()
1222 capacity = cs->disable_cap_level; in ab8500_fg_calculate_scaled_capacity()
1231 * ab8500_fg_update_cap_scalers() - Capacity scaling
1234 * To be called when state change from charge<->discharge to update
1239 struct ab8500_fg_cap_scaling *cs = &di->bat_cap.cap_scale; in ab8500_fg_update_cap_scalers()
1241 if (!cs->enable) in ab8500_fg_update_cap_scalers()
1243 if (di->flags.charging) { in ab8500_fg_update_cap_scalers()
1244 di->bat_cap.cap_scale.disable_cap_level = in ab8500_fg_update_cap_scalers()
1245 di->bat_cap.cap_scale.scaled_cap; in ab8500_fg_update_cap_scalers()
1246 dev_dbg(di->dev, "Cap to stop scale at charge %d%%\n", in ab8500_fg_update_cap_scalers()
1247 di->bat_cap.cap_scale.disable_cap_level); in ab8500_fg_update_cap_scalers()
1249 if (cs->scaled_cap != 100) { in ab8500_fg_update_cap_scalers()
1250 cs->cap_to_scale[0] = cs->scaled_cap; in ab8500_fg_update_cap_scalers()
1251 cs->cap_to_scale[1] = di->bat_cap.prev_percent; in ab8500_fg_update_cap_scalers()
1253 cs->cap_to_scale[0] = 100; in ab8500_fg_update_cap_scalers()
1254 cs->cap_to_scale[1] = in ab8500_fg_update_cap_scalers()
1255 max(di->bat_cap.prev_percent, in ab8500_fg_update_cap_scalers()
1256 di->bm->fg_params->maint_thres); in ab8500_fg_update_cap_scalers()
1259 dev_dbg(di->dev, "Cap to scale at discharge %d/%d\n", in ab8500_fg_update_cap_scalers()
1260 cs->cap_to_scale[0], cs->cap_to_scale[1]); in ab8500_fg_update_cap_scalers()
1265 * ab8500_fg_check_capacity_limits() - Check if capacity has changed
1275 int percent = DIV_ROUND_CLOSEST(di->bat_cap.permille, 10); in ab8500_fg_check_capacity_limits()
1277 di->bat_cap.level = ab8500_fg_capacity_level(di); in ab8500_fg_check_capacity_limits()
1279 if (di->bat_cap.level != di->bat_cap.prev_level) { in ab8500_fg_check_capacity_limits()
1284 if (!(!di->flags.charging && di->bat_cap.level > in ab8500_fg_check_capacity_limits()
1285 di->bat_cap.prev_level) || init) { in ab8500_fg_check_capacity_limits()
1286 dev_dbg(di->dev, "level changed from %d to %d\n", in ab8500_fg_check_capacity_limits()
1287 di->bat_cap.prev_level, in ab8500_fg_check_capacity_limits()
1288 di->bat_cap.level); in ab8500_fg_check_capacity_limits()
1289 di->bat_cap.prev_level = di->bat_cap.level; in ab8500_fg_check_capacity_limits()
1292 dev_dbg(di->dev, "level not allowed to go up " in ab8500_fg_check_capacity_limits()
1294 di->bat_cap.prev_level, in ab8500_fg_check_capacity_limits()
1295 di->bat_cap.level); in ab8500_fg_check_capacity_limits()
1303 if (di->flags.low_bat) { in ab8500_fg_check_capacity_limits()
1304 dev_dbg(di->dev, "Battery low, set capacity to 0\n"); in ab8500_fg_check_capacity_limits()
1305 di->bat_cap.prev_percent = 0; in ab8500_fg_check_capacity_limits()
1306 di->bat_cap.permille = 0; in ab8500_fg_check_capacity_limits()
1308 di->bat_cap.prev_mah = 0; in ab8500_fg_check_capacity_limits()
1309 di->bat_cap.mah = 0; in ab8500_fg_check_capacity_limits()
1311 } else if (di->flags.fully_charged) { in ab8500_fg_check_capacity_limits()
1316 if (di->flags.force_full) { in ab8500_fg_check_capacity_limits()
1317 di->bat_cap.prev_percent = percent; in ab8500_fg_check_capacity_limits()
1318 di->bat_cap.prev_mah = di->bat_cap.mah; in ab8500_fg_check_capacity_limits()
1322 if (!di->bat_cap.cap_scale.enable && in ab8500_fg_check_capacity_limits()
1323 di->bm->capacity_scaling) { in ab8500_fg_check_capacity_limits()
1324 di->bat_cap.cap_scale.enable = true; in ab8500_fg_check_capacity_limits()
1325 di->bat_cap.cap_scale.cap_to_scale[0] = 100; in ab8500_fg_check_capacity_limits()
1326 di->bat_cap.cap_scale.cap_to_scale[1] = in ab8500_fg_check_capacity_limits()
1327 di->bat_cap.prev_percent; in ab8500_fg_check_capacity_limits()
1328 di->bat_cap.cap_scale.disable_cap_level = 100; in ab8500_fg_check_capacity_limits()
1330 } else if (di->bat_cap.prev_percent != percent) { in ab8500_fg_check_capacity_limits()
1331 dev_dbg(di->dev, in ab8500_fg_check_capacity_limits()
1335 di->bat_cap.prev_percent = percent; in ab8500_fg_check_capacity_limits()
1336 di->bat_cap.prev_mah = di->bat_cap.mah; in ab8500_fg_check_capacity_limits()
1340 } else if (di->bat_cap.prev_percent != percent) { in ab8500_fg_check_capacity_limits()
1347 di->bat_cap.prev_percent = 1; in ab8500_fg_check_capacity_limits()
1351 } else if (!(!di->flags.charging && in ab8500_fg_check_capacity_limits()
1352 percent > di->bat_cap.prev_percent) || init) { in ab8500_fg_check_capacity_limits()
1357 dev_dbg(di->dev, in ab8500_fg_check_capacity_limits()
1359 di->bat_cap.prev_percent, in ab8500_fg_check_capacity_limits()
1361 di->bat_cap.permille); in ab8500_fg_check_capacity_limits()
1362 di->bat_cap.prev_percent = percent; in ab8500_fg_check_capacity_limits()
1363 di->bat_cap.prev_mah = di->bat_cap.mah; in ab8500_fg_check_capacity_limits()
1367 dev_dbg(di->dev, "capacity not allowed to go up since " in ab8500_fg_check_capacity_limits()
1369 di->bat_cap.prev_percent, in ab8500_fg_check_capacity_limits()
1371 di->bat_cap.permille); in ab8500_fg_check_capacity_limits()
1376 if (di->bm->capacity_scaling) { in ab8500_fg_check_capacity_limits()
1377 di->bat_cap.cap_scale.scaled_cap = in ab8500_fg_check_capacity_limits()
1380 dev_info(di->dev, "capacity=%d (%d)\n", in ab8500_fg_check_capacity_limits()
1381 di->bat_cap.prev_percent, in ab8500_fg_check_capacity_limits()
1382 di->bat_cap.cap_scale.scaled_cap); in ab8500_fg_check_capacity_limits()
1384 power_supply_changed(di->fg_psy); in ab8500_fg_check_capacity_limits()
1385 if (di->flags.fully_charged && di->flags.force_full) { in ab8500_fg_check_capacity_limits()
1386 dev_dbg(di->dev, "Battery full, notifying.\n"); in ab8500_fg_check_capacity_limits()
1387 di->flags.force_full = false; in ab8500_fg_check_capacity_limits()
1388 sysfs_notify(&di->fg_kobject, NULL, "charge_full"); in ab8500_fg_check_capacity_limits()
1390 sysfs_notify(&di->fg_kobject, NULL, "charge_now"); in ab8500_fg_check_capacity_limits()
1397 dev_dbg(di->dev, "Charge state from %d [%s] to %d [%s]\n", in ab8500_fg_charge_state_to()
1398 di->charge_state, in ab8500_fg_charge_state_to()
1399 charge_state[di->charge_state], in ab8500_fg_charge_state_to()
1403 di->charge_state = new_state; in ab8500_fg_charge_state_to()
1409 dev_dbg(di->dev, "Discharge state from %d [%s] to %d [%s]\n", in ab8500_fg_discharge_state_to()
1410 di->discharge_state, in ab8500_fg_discharge_state_to()
1411 discharge_state[di->discharge_state], in ab8500_fg_discharge_state_to()
1415 di->discharge_state = new_state; in ab8500_fg_discharge_state_to()
1419 * ab8500_fg_algorithm_charging() - FG algorithm for when charging
1430 if (di->discharge_state != AB8500_FG_DISCHARGE_INIT_RECOVERY) in ab8500_fg_algorithm_charging()
1434 switch (di->charge_state) { in ab8500_fg_algorithm_charging()
1436 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_charging()
1437 di->bm->fg_params->accu_charging); in ab8500_fg_algorithm_charging()
1448 mutex_lock(&di->cc_lock); in ab8500_fg_algorithm_charging()
1449 if (!di->flags.conv_done && !di->flags.force_full) { in ab8500_fg_algorithm_charging()
1451 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_charging()
1452 dev_dbg(di->dev, "%s CC conv not done\n", in ab8500_fg_algorithm_charging()
1457 di->flags.conv_done = false; in ab8500_fg_algorithm_charging()
1458 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_charging()
1477 cap = di->bat_cap.user_mah; in force_capacity()
1478 if (cap > di->bat_cap.max_mah_design) { in force_capacity()
1479 dev_dbg(di->dev, "Remaining cap %d can't be bigger than total" in force_capacity()
1480 " %d\n", cap, di->bat_cap.max_mah_design); in force_capacity()
1481 cap = di->bat_cap.max_mah_design; in force_capacity()
1483 ab8500_fg_fill_cap_sample(di, di->bat_cap.user_mah); in force_capacity()
1484 di->bat_cap.permille = ab8500_fg_convert_mah_to_permille(di, cap); in force_capacity()
1485 di->bat_cap.mah = cap; in force_capacity()
1494 cap = di->bat_cap.user_mah; in check_sysfs_capacity()
1497 di->bat_cap.user_mah); in check_sysfs_capacity()
1499 lower = di->bat_cap.permille - di->bm->fg_params->user_cap_limit * 10; in check_sysfs_capacity()
1500 upper = di->bat_cap.permille + di->bm->fg_params->user_cap_limit * 10; in check_sysfs_capacity()
1504 /* 1000 is permille, -> 100 percent */ in check_sysfs_capacity()
1508 dev_dbg(di->dev, "Capacity limits:" in check_sysfs_capacity()
1510 lower, cap_permille, upper, cap, di->bat_cap.mah); in check_sysfs_capacity()
1514 dev_dbg(di->dev, "OK! Using users cap %d uAh now\n", cap); in check_sysfs_capacity()
1518 dev_dbg(di->dev, "Capacity from user out of limits, ignoring"); in check_sysfs_capacity()
1523 * ab8500_fg_algorithm_discharging() - FG algorithm for when discharging
1533 if (di->charge_state != AB8500_FG_CHARGE_INIT) in ab8500_fg_algorithm_discharging()
1536 switch (di->discharge_state) { in ab8500_fg_algorithm_discharging()
1539 di->init_cnt = 0; in ab8500_fg_algorithm_discharging()
1540 di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer); in ab8500_fg_algorithm_discharging()
1548 * Discard a number of samples during startup. in ab8500_fg_algorithm_discharging()
1550 * samples to get an initial capacity. in ab8500_fg_algorithm_discharging()
1553 sleep_time = di->bm->fg_params->init_timer; in ab8500_fg_algorithm_discharging()
1556 if (di->init_cnt > di->bm->fg_params->init_discard_time) { in ab8500_fg_algorithm_discharging()
1562 di->init_cnt += sleep_time; in ab8500_fg_algorithm_discharging()
1563 if (di->init_cnt > di->bm->fg_params->init_total_time) in ab8500_fg_algorithm_discharging()
1570 di->recovery_cnt = 0; in ab8500_fg_algorithm_discharging()
1571 di->recovery_needed = true; in ab8500_fg_algorithm_discharging()
1578 sleep_time = di->bm->fg_params->recovery_sleep_timer; in ab8500_fg_algorithm_discharging()
1586 di->inst_curr = ab8500_fg_inst_curr_blocking(di); in ab8500_fg_algorithm_discharging()
1588 if (ab8500_fg_is_low_curr(di, di->inst_curr)) { in ab8500_fg_algorithm_discharging()
1589 if (di->recovery_cnt > in ab8500_fg_algorithm_discharging()
1590 di->bm->fg_params->recovery_total_time) { in ab8500_fg_algorithm_discharging()
1591 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1592 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1596 di->recovery_needed = false; in ab8500_fg_algorithm_discharging()
1598 queue_delayed_work(di->fg_wq, in ab8500_fg_algorithm_discharging()
1599 &di->fg_periodic_work, in ab8500_fg_algorithm_discharging()
1602 di->recovery_cnt += sleep_time; in ab8500_fg_algorithm_discharging()
1604 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1605 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1613 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1614 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1621 di->inst_curr = ab8500_fg_inst_curr_blocking(di); in ab8500_fg_algorithm_discharging()
1623 if (ab8500_fg_is_low_curr(di, di->inst_curr)) { in ab8500_fg_algorithm_discharging()
1625 if (di->high_curr_mode) { in ab8500_fg_algorithm_discharging()
1626 di->high_curr_mode = false; in ab8500_fg_algorithm_discharging()
1627 di->high_curr_cnt = 0; in ab8500_fg_algorithm_discharging()
1630 if (di->recovery_needed) { in ab8500_fg_algorithm_discharging()
1634 queue_delayed_work(di->fg_wq, in ab8500_fg_algorithm_discharging()
1635 &di->fg_periodic_work, 0); in ab8500_fg_algorithm_discharging()
1642 mutex_lock(&di->cc_lock); in ab8500_fg_algorithm_discharging()
1643 if (!di->flags.conv_done) { in ab8500_fg_algorithm_discharging()
1645 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_discharging()
1646 dev_dbg(di->dev, "%s CC conv not done\n", in ab8500_fg_algorithm_discharging()
1651 di->flags.conv_done = false; in ab8500_fg_algorithm_discharging()
1652 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_discharging()
1655 if (!di->high_curr_mode) { in ab8500_fg_algorithm_discharging()
1656 di->high_curr_mode = true; in ab8500_fg_algorithm_discharging()
1657 di->high_curr_cnt = 0; in ab8500_fg_algorithm_discharging()
1660 di->high_curr_cnt += in ab8500_fg_algorithm_discharging()
1661 di->bm->fg_params->accu_high_curr; in ab8500_fg_algorithm_discharging()
1662 if (di->high_curr_cnt > in ab8500_fg_algorithm_discharging()
1663 di->bm->fg_params->high_curr_time) in ab8500_fg_algorithm_discharging()
1664 di->recovery_needed = true; in ab8500_fg_algorithm_discharging()
1676 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1677 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1692 * ab8500_fg_algorithm_calibrate() - Internal columb counter offset calibration
1700 switch (di->calib_state) { in ab8500_fg_algorithm_calibrate()
1702 dev_dbg(di->dev, "Calibration ongoing...\n"); in ab8500_fg_algorithm_calibrate()
1704 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_algorithm_calibrate()
1710 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_algorithm_calibrate()
1715 di->calib_state = AB8500_FG_CALIB_WAIT; in ab8500_fg_algorithm_calibrate()
1718 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_algorithm_calibrate()
1723 di->flags.calibrate = false; in ab8500_fg_algorithm_calibrate()
1724 dev_dbg(di->dev, "Calibration done...\n"); in ab8500_fg_algorithm_calibrate()
1725 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_algorithm_calibrate()
1728 dev_dbg(di->dev, "Calibration WFI\n"); in ab8500_fg_algorithm_calibrate()
1735 dev_err(di->dev, "failed to calibrate the CC\n"); in ab8500_fg_algorithm_calibrate()
1736 di->flags.calibrate = false; in ab8500_fg_algorithm_calibrate()
1737 di->calib_state = AB8500_FG_CALIB_INIT; in ab8500_fg_algorithm_calibrate()
1738 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_algorithm_calibrate()
1742 * ab8500_fg_algorithm() - Entry point for the FG algorithm
1749 if (di->flags.calibrate) in ab8500_fg_algorithm()
1752 if (di->flags.charging) in ab8500_fg_algorithm()
1758 dev_dbg(di->dev, "[FG_DATA] %d %d %d %d %d %d %d %d %d %d " in ab8500_fg_algorithm()
1760 di->bat_cap.max_mah_design, in ab8500_fg_algorithm()
1761 di->bat_cap.max_mah, in ab8500_fg_algorithm()
1762 di->bat_cap.mah, in ab8500_fg_algorithm()
1763 di->bat_cap.permille, in ab8500_fg_algorithm()
1764 di->bat_cap.level, in ab8500_fg_algorithm()
1765 di->bat_cap.prev_mah, in ab8500_fg_algorithm()
1766 di->bat_cap.prev_percent, in ab8500_fg_algorithm()
1767 di->bat_cap.prev_level, in ab8500_fg_algorithm()
1768 di->vbat, in ab8500_fg_algorithm()
1769 di->inst_curr, in ab8500_fg_algorithm()
1770 di->avg_curr, in ab8500_fg_algorithm()
1771 di->accu_charge, in ab8500_fg_algorithm()
1772 di->flags.charging, in ab8500_fg_algorithm()
1773 di->charge_state, in ab8500_fg_algorithm()
1774 di->discharge_state, in ab8500_fg_algorithm()
1775 di->high_curr_mode, in ab8500_fg_algorithm()
1776 di->recovery_needed); in ab8500_fg_algorithm()
1780 * ab8500_fg_periodic_work() - Run the FG state machine periodically
1790 if (di->init_capacity) { in ab8500_fg_periodic_work()
1794 di->init_capacity = false; in ab8500_fg_periodic_work()
1796 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_periodic_work()
1797 } else if (di->flags.user_cap) { in ab8500_fg_periodic_work()
1800 if (di->flags.charging) in ab8500_fg_periodic_work()
1807 di->flags.user_cap = false; in ab8500_fg_periodic_work()
1808 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_periodic_work()
1815 * ab8500_fg_check_hw_failure_work() - Check OVV_BAT condition
1829 * If we have had a battery over-voltage situation, in ab8500_fg_check_hw_failure_work()
1830 * check ovv-bit to see if it should be reset. in ab8500_fg_check_hw_failure_work()
1832 ret = abx500_get_register_interruptible(di->dev, in ab8500_fg_check_hw_failure_work()
1836 dev_err(di->dev, "%s ab8500 read failed\n", __func__); in ab8500_fg_check_hw_failure_work()
1840 if (!di->flags.bat_ovv) { in ab8500_fg_check_hw_failure_work()
1841 dev_dbg(di->dev, "Battery OVV\n"); in ab8500_fg_check_hw_failure_work()
1842 di->flags.bat_ovv = true; in ab8500_fg_check_hw_failure_work()
1843 power_supply_changed(di->fg_psy); in ab8500_fg_check_hw_failure_work()
1846 queue_delayed_work(di->fg_wq, &di->fg_check_hw_failure_work, in ab8500_fg_check_hw_failure_work()
1849 dev_dbg(di->dev, "Battery recovered from OVV\n"); in ab8500_fg_check_hw_failure_work()
1850 di->flags.bat_ovv = false; in ab8500_fg_check_hw_failure_work()
1851 power_supply_changed(di->fg_psy); in ab8500_fg_check_hw_failure_work()
1856 * ab8500_fg_low_bat_work() - Check LOW_BAT condition
1871 if (vbat < di->bm->fg_params->lowbat_threshold) { in ab8500_fg_low_bat_work()
1873 if (di->low_bat_cnt < 1) { in ab8500_fg_low_bat_work()
1874 di->flags.low_bat = true; in ab8500_fg_low_bat_work()
1875 dev_warn(di->dev, "Shut down pending...\n"); in ab8500_fg_low_bat_work()
1878 * Else we need to re-schedule this check to be able to detect in ab8500_fg_low_bat_work()
1882 di->low_bat_cnt--; in ab8500_fg_low_bat_work()
1883 dev_warn(di->dev, "Battery voltage still LOW\n"); in ab8500_fg_low_bat_work()
1884 queue_delayed_work(di->fg_wq, &di->fg_low_bat_work, in ab8500_fg_low_bat_work()
1888 di->flags.low_bat_delay = false; in ab8500_fg_low_bat_work()
1889 di->low_bat_cnt = 10; in ab8500_fg_low_bat_work()
1890 dev_warn(di->dev, "Battery voltage OK again\n"); in ab8500_fg_low_bat_work()
1898 * ab8500_fg_battok_calc - calculate the bit pattern corresponding
1904 * valid return values are 0-14. (0-BATT_OK_MAX_NR_INCREMENTS)
1914 return (target - BATT_OK_MIN) / BATT_OK_INCREMENT; in ab8500_fg_battok_calc()
1918 * ab8500_fg_battok_init_hw_register - init battok levels
1933 sel0 = di->bm->fg_params->battok_falling_th_sel0; in ab8500_fg_battok_init_hw_register()
1934 sel1 = di->bm->fg_params->battok_raising_th_sel1; in ab8500_fg_battok_init_hw_register()
1942 dev_warn(di->dev, "Invalid voltage step:%d, using %d %d\n", in ab8500_fg_battok_init_hw_register()
1948 dev_warn(di->dev, "Invalid voltage step:%d, using %d %d\n", in ab8500_fg_battok_init_hw_register()
1953 dev_dbg(di->dev, "using: %x %d %d\n", new_val, cbp_sel0, cbp_sel1); in ab8500_fg_battok_init_hw_register()
1954 ret = abx500_set_register_interruptible(di->dev, AB8500_SYS_CTRL2_BLOCK, in ab8500_fg_battok_init_hw_register()
1960 * ab8500_fg_instant_work() - Run the FG state machine instantly
1973 * ab8500_fg_cc_data_end_handler() - end of data conversion isr.
1982 if (!di->nbr_cceoc_irq_cnt) { in ab8500_fg_cc_data_end_handler()
1983 di->nbr_cceoc_irq_cnt++; in ab8500_fg_cc_data_end_handler()
1984 complete(&di->ab8500_fg_started); in ab8500_fg_cc_data_end_handler()
1986 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_cc_data_end_handler()
1987 complete(&di->ab8500_fg_complete); in ab8500_fg_cc_data_end_handler()
1993 * ab8500_fg_cc_int_calib_handler () - end of calibration isr.
2002 di->calib_state = AB8500_FG_CALIB_END; in ab8500_fg_cc_int_calib_handler()
2003 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_cc_int_calib_handler()
2008 * ab8500_fg_cc_convend_handler() - isr to get battery avg current.
2018 queue_work(di->fg_wq, &di->fg_acc_cur_work); in ab8500_fg_cc_convend_handler()
2024 * ab8500_fg_batt_ovv_handler() - Battery OVV occured
2034 dev_dbg(di->dev, "Battery OVV\n"); in ab8500_fg_batt_ovv_handler()
2037 queue_delayed_work(di->fg_wq, &di->fg_check_hw_failure_work, 0); in ab8500_fg_batt_ovv_handler()
2043 * ab8500_fg_lowbatf_handler() - Battery voltage is below LOW threshold
2054 if (!di->flags.low_bat_delay) { in ab8500_fg_lowbatf_handler()
2055 dev_warn(di->dev, "Battery voltage is below LOW threshold\n"); in ab8500_fg_lowbatf_handler()
2056 di->flags.low_bat_delay = true; in ab8500_fg_lowbatf_handler()
2061 queue_delayed_work(di->fg_wq, &di->fg_low_bat_work, in ab8500_fg_lowbatf_handler()
2068 * ab8500_fg_get_property() - get the fg properties
2100 if (di->flags.bat_ovv) in ab8500_fg_get_property()
2101 val->intval = BATT_OVV_VALUE * 1000; in ab8500_fg_get_property()
2103 val->intval = di->vbat * 1000; in ab8500_fg_get_property()
2106 val->intval = di->inst_curr * 1000; in ab8500_fg_get_property()
2109 val->intval = di->avg_curr * 1000; in ab8500_fg_get_property()
2112 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2113 di->bat_cap.max_mah_design); in ab8500_fg_get_property()
2116 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2117 di->bat_cap.max_mah); in ab8500_fg_get_property()
2120 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2121 di->flags.batt_id_received) in ab8500_fg_get_property()
2122 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2123 di->bat_cap.max_mah); in ab8500_fg_get_property()
2125 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2126 di->bat_cap.prev_mah); in ab8500_fg_get_property()
2129 val->intval = di->bat_cap.max_mah_design; in ab8500_fg_get_property()
2132 val->intval = di->bat_cap.max_mah; in ab8500_fg_get_property()
2135 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2136 di->flags.batt_id_received) in ab8500_fg_get_property()
2137 val->intval = di->bat_cap.max_mah; in ab8500_fg_get_property()
2139 val->intval = di->bat_cap.prev_mah; in ab8500_fg_get_property()
2142 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2143 di->flags.batt_id_received) in ab8500_fg_get_property()
2144 val->intval = 100; in ab8500_fg_get_property()
2146 val->intval = di->bat_cap.prev_percent; in ab8500_fg_get_property()
2149 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2150 di->flags.batt_id_received) in ab8500_fg_get_property()
2151 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; in ab8500_fg_get_property()
2153 val->intval = di->bat_cap.prev_level; in ab8500_fg_get_property()
2156 return -EINVAL; in ab8500_fg_get_property()
2165 const char **supplicants = (const char **)ext->supplied_to; in ab8500_fg_get_ext_psy_data()
2177 j = match_string(supplicants, ext->num_supplicants, psy->desc->name); in ab8500_fg_get_ext_psy_data()
2182 for (j = 0; j < ext->desc->num_properties; j++) { in ab8500_fg_get_ext_psy_data()
2184 prop = ext->desc->properties[j]; in ab8500_fg_get_ext_psy_data()
2191 switch (ext->desc->type) { in ab8500_fg_get_ext_psy_data()
2197 if (!di->flags.charging) in ab8500_fg_get_ext_psy_data()
2199 di->flags.charging = false; in ab8500_fg_get_ext_psy_data()
2200 di->flags.fully_charged = false; in ab8500_fg_get_ext_psy_data()
2201 if (di->bm->capacity_scaling) in ab8500_fg_get_ext_psy_data()
2203 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_get_ext_psy_data()
2206 if (di->flags.fully_charged) in ab8500_fg_get_ext_psy_data()
2208 di->flags.fully_charged = true; in ab8500_fg_get_ext_psy_data()
2209 di->flags.force_full = true; in ab8500_fg_get_ext_psy_data()
2211 di->bat_cap.max_mah = di->bat_cap.mah; in ab8500_fg_get_ext_psy_data()
2212 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_get_ext_psy_data()
2215 if (di->flags.charging && in ab8500_fg_get_ext_psy_data()
2216 !di->flags.fully_charged) in ab8500_fg_get_ext_psy_data()
2218 di->flags.charging = true; in ab8500_fg_get_ext_psy_data()
2219 di->flags.fully_charged = false; in ab8500_fg_get_ext_psy_data()
2220 if (di->bm->capacity_scaling) in ab8500_fg_get_ext_psy_data()
2222 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_get_ext_psy_data()
2230 switch (ext->desc->type) { in ab8500_fg_get_ext_psy_data()
2232 if (!di->flags.batt_id_received && in ab8500_fg_get_ext_psy_data()
2233 di->bm->batt_id != BATTERY_UNKNOWN) { in ab8500_fg_get_ext_psy_data()
2236 b = &(di->bm->bat_type[di->bm->batt_id]); in ab8500_fg_get_ext_psy_data()
2238 di->flags.batt_id_received = true; in ab8500_fg_get_ext_psy_data()
2240 di->bat_cap.max_mah_design = in ab8500_fg_get_ext_psy_data()
2242 b->charge_full_design; in ab8500_fg_get_ext_psy_data()
2244 di->bat_cap.max_mah = in ab8500_fg_get_ext_psy_data()
2245 di->bat_cap.max_mah_design; in ab8500_fg_get_ext_psy_data()
2247 di->vbat_nom = b->nominal_voltage; in ab8500_fg_get_ext_psy_data()
2251 di->flags.batt_unknown = false; in ab8500_fg_get_ext_psy_data()
2253 di->flags.batt_unknown = true; in ab8500_fg_get_ext_psy_data()
2260 switch (ext->desc->type) { in ab8500_fg_get_ext_psy_data()
2262 if (di->flags.batt_id_received) in ab8500_fg_get_ext_psy_data()
2263 di->bat_temp = ret.intval; in ab8500_fg_get_ext_psy_data()
2277 * ab8500_fg_init_hw_registers() - Set up FG related registers
2287 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_init_hw_registers()
2293 dev_err(di->dev, "failed to set BATT_OVV\n"); in ab8500_fg_init_hw_registers()
2298 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_init_hw_registers()
2304 dev_err(di->dev, "failed to enable BATT_OVV\n"); in ab8500_fg_init_hw_registers()
2309 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_init_hw_registers()
2313 di->bm->fg_params->lowbat_threshold) << 1 | in ab8500_fg_init_hw_registers()
2316 dev_err(di->dev, "%s write failed\n", __func__); in ab8500_fg_init_hw_registers()
2323 dev_err(di->dev, "BattOk init write failed.\n"); in ab8500_fg_init_hw_registers()
2327 if (is_ab8505(di->parent)) { in ab8500_fg_init_hw_registers()
2328 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2329 AB8505_RTC_PCUT_MAX_TIME_REG, di->bm->fg_params->pcut_max_time); in ab8500_fg_init_hw_registers()
2332 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_MAX_TIME_REG\n", __func__); in ab8500_fg_init_hw_registers()
2336 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2337 AB8505_RTC_PCUT_FLAG_TIME_REG, di->bm->fg_params->pcut_flag_time); in ab8500_fg_init_hw_registers()
2340 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_FLAG_TIME_REG\n", __func__); in ab8500_fg_init_hw_registers()
2344 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2345 AB8505_RTC_PCUT_RESTART_REG, di->bm->fg_params->pcut_max_restart); in ab8500_fg_init_hw_registers()
2348 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_RESTART_REG\n", __func__); in ab8500_fg_init_hw_registers()
2352 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2353 AB8505_RTC_PCUT_DEBOUNCE_REG, di->bm->fg_params->pcut_debounce_time); in ab8500_fg_init_hw_registers()
2356 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_DEBOUNCE_REG\n", __func__); in ab8500_fg_init_hw_registers()
2360 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2361 AB8505_RTC_PCUT_CTL_STATUS_REG, di->bm->fg_params->pcut_enable); in ab8500_fg_init_hw_registers()
2364 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_CTL_STATUS_REG\n", __func__); in ab8500_fg_init_hw_registers()
2373 * ab8500_fg_external_power_changed() - callback for power supply changes
2386 di->fg_psy, ab8500_fg_get_ext_psy_data); in ab8500_fg_external_power_changed()
2390 * ab8500_fg_reinit_work() - work to reset the FG algorithm
2402 if (!di->flags.calibrate) { in ab8500_fg_reinit_work()
2403 dev_dbg(di->dev, "Resetting FG state machine to init.\n"); in ab8500_fg_reinit_work()
2408 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_reinit_work()
2411 dev_err(di->dev, "Residual offset calibration ongoing " in ab8500_fg_reinit_work()
2414 queue_delayed_work(di->fg_wq, &di->fg_reinit_work, in ab8500_fg_reinit_work()
2429 return sprintf(buf, "%d\n", di->bat_cap.max_mah); in charge_full_show()
2442 di->bat_cap.max_mah = (int) charge_full; in charge_full_store()
2448 return sprintf(buf, "%d\n", di->bat_cap.prev_mah); in charge_now_show()
2461 di->bat_cap.user_mah = (int) charge_now; in charge_now_store()
2462 di->flags.user_cap = true; in charge_now_store()
2463 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in charge_now_store()
2482 if (!entry->show) in ab8500_fg_show()
2483 return -EIO; in ab8500_fg_show()
2485 return entry->show(di, buf); in ab8500_fg_show()
2497 if (!entry->store) in ab8500_fg_store()
2498 return -EIO; in ab8500_fg_store()
2500 return entry->store(di, buf, count); in ab8500_fg_store()
2520 * ab8500_fg_sysfs_exit() - de-init of sysfs entry
2527 kobject_del(&di->fg_kobject); in ab8500_fg_sysfs_exit()
2531 * ab8500_fg_sysfs_init() - init of sysfs entry
2541 ret = kobject_init_and_add(&di->fg_kobject, in ab8500_fg_sysfs_init()
2545 dev_err(di->dev, "failed to create sysfs entry\n"); in ab8500_fg_sysfs_init()
2559 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_flagtime_read()
2586 dev_err(dev, "Incorrect parameter, echo 0 (1.98s) - 127 (15.625ms) for flagtime\n"); in ab8505_powercut_flagtime_write()
2590 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_flagtime_write()
2609 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_maxtime_read()
2637 dev_err(dev, "Incorrect parameter, echo 0 (0.0s) - 127 (1.98s) for maxtime\n"); in ab8505_powercut_maxtime_write()
2641 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_maxtime_write()
2660 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_restart_read()
2687 dev_err(dev, "Incorrect parameter, echo 0 - 15 for number of restart\n"); in ab8505_powercut_restart_write()
2691 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_restart_write()
2711 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_timer_read()
2734 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_restart_counter_read()
2757 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_read()
2786 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_write()
2806 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_flag_read()
2829 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_debounce_read()
2860 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_debounce_write()
2879 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_enable_status_read()
2916 if (is_ab8505(di->parent)) { in ab8500_fg_sysfs_psy_create_attrs()
2918 if (device_create_file(&di->fg_psy->dev, in ab8500_fg_sysfs_psy_create_attrs()
2924 dev_err(&di->fg_psy->dev, "Failed creating sysfs psy attrs for ab8505.\n"); in ab8500_fg_sysfs_psy_create_attrs()
2925 while (i--) in ab8500_fg_sysfs_psy_create_attrs()
2926 device_remove_file(&di->fg_psy->dev, in ab8500_fg_sysfs_psy_create_attrs()
2929 return -EIO; in ab8500_fg_sysfs_psy_create_attrs()
2936 if (is_ab8505(di->parent)) { in ab8500_fg_sysfs_psy_remove_attrs()
2938 (void)device_remove_file(&di->fg_psy->dev, in ab8500_fg_sysfs_psy_remove_attrs()
2954 if (!di->flags.charging) { in ab8500_fg_resume()
2956 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_resume()
2967 flush_delayed_work(&di->fg_periodic_work); in ab8500_fg_suspend()
2968 flush_work(&di->fg_work); in ab8500_fg_suspend()
2969 flush_work(&di->fg_acc_cur_work); in ab8500_fg_suspend()
2970 flush_delayed_work(&di->fg_reinit_work); in ab8500_fg_suspend()
2971 flush_delayed_work(&di->fg_low_bat_work); in ab8500_fg_suspend()
2972 flush_delayed_work(&di->fg_check_hw_failure_work); in ab8500_fg_suspend()
2978 if (di->flags.fg_enabled && !di->flags.charging) in ab8500_fg_suspend()
2993 list_del(&di->node); in ab8500_fg_remove()
2998 dev_err(di->dev, "failed to disable coulomb counter\n"); in ab8500_fg_remove()
3000 destroy_workqueue(di->fg_wq); in ab8500_fg_remove()
3005 power_supply_unregister(di->fg_psy); in ab8500_fg_remove()
3037 struct device_node *np = pdev->dev.of_node; in ab8500_fg_probe()
3038 struct abx500_bm_data *plat = pdev->dev.platform_data; in ab8500_fg_probe()
3044 di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); in ab8500_fg_probe()
3046 dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__); in ab8500_fg_probe()
3047 return -ENOMEM; in ab8500_fg_probe()
3051 dev_err(&pdev->dev, "no battery management data supplied\n"); in ab8500_fg_probe()
3052 return -EINVAL; in ab8500_fg_probe()
3054 di->bm = plat; in ab8500_fg_probe()
3057 ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm); in ab8500_fg_probe()
3059 dev_err(&pdev->dev, "failed to get battery information\n"); in ab8500_fg_probe()
3064 mutex_init(&di->cc_lock); in ab8500_fg_probe()
3067 di->dev = &pdev->dev; in ab8500_fg_probe()
3068 di->parent = dev_get_drvdata(pdev->dev.parent); in ab8500_fg_probe()
3070 di->main_bat_v = devm_iio_channel_get(&pdev->dev, "main_bat_v"); in ab8500_fg_probe()
3071 if (IS_ERR(di->main_bat_v)) { in ab8500_fg_probe()
3072 if (PTR_ERR(di->main_bat_v) == -ENODEV) in ab8500_fg_probe()
3073 return -EPROBE_DEFER; in ab8500_fg_probe()
3074 dev_err(&pdev->dev, "failed to get main battery ADC channel\n"); in ab8500_fg_probe()
3075 return PTR_ERR(di->main_bat_v); in ab8500_fg_probe()
3082 di->bat_cap.max_mah_design = MILLI_TO_MICRO * in ab8500_fg_probe()
3083 di->bm->bat_type[di->bm->batt_id].charge_full_design; in ab8500_fg_probe()
3085 di->bat_cap.max_mah = di->bat_cap.max_mah_design; in ab8500_fg_probe()
3087 di->vbat_nom = di->bm->bat_type[di->bm->batt_id].nominal_voltage; in ab8500_fg_probe()
3089 di->init_capacity = true; in ab8500_fg_probe()
3095 di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM); in ab8500_fg_probe()
3096 if (di->fg_wq == NULL) { in ab8500_fg_probe()
3097 dev_err(di->dev, "failed to create work queue\n"); in ab8500_fg_probe()
3098 return -ENOMEM; in ab8500_fg_probe()
3102 INIT_WORK(&di->fg_work, ab8500_fg_instant_work); in ab8500_fg_probe()
3105 INIT_WORK(&di->fg_acc_cur_work, ab8500_fg_acc_cur_work); in ab8500_fg_probe()
3108 INIT_DEFERRABLE_WORK(&di->fg_reinit_work, in ab8500_fg_probe()
3112 INIT_DEFERRABLE_WORK(&di->fg_periodic_work, in ab8500_fg_probe()
3116 INIT_DEFERRABLE_WORK(&di->fg_low_bat_work, in ab8500_fg_probe()
3120 INIT_DEFERRABLE_WORK(&di->fg_check_hw_failure_work, in ab8500_fg_probe()
3124 di->flags.low_bat = false; in ab8500_fg_probe()
3127 di->low_bat_cnt = 10; in ab8500_fg_probe()
3132 dev_err(di->dev, "failed to initialize registers\n"); in ab8500_fg_probe()
3137 di->flags.batt_unknown = true; in ab8500_fg_probe()
3138 di->flags.batt_id_received = false; in ab8500_fg_probe()
3141 di->fg_psy = power_supply_register(di->dev, &ab8500_fg_desc, &psy_cfg); in ab8500_fg_probe()
3142 if (IS_ERR(di->fg_psy)) { in ab8500_fg_probe()
3143 dev_err(di->dev, "failed to register FG psy\n"); in ab8500_fg_probe()
3144 ret = PTR_ERR(di->fg_psy); in ab8500_fg_probe()
3148 di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer); in ab8500_fg_probe()
3155 init_completion(&di->ab8500_fg_started); in ab8500_fg_probe()
3156 init_completion(&di->ab8500_fg_complete); in ab8500_fg_probe()
3171 dev_err(di->dev, "failed to request %s IRQ %d: %d\n", in ab8500_fg_probe()
3175 dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", in ab8500_fg_probe()
3191 dev_err(di->dev, "failed to request %s IRQ %d: %d\n", in ab8500_fg_probe()
3195 dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", in ab8500_fg_probe()
3198 di->irq = platform_get_irq_byname(pdev, "CCEOC"); in ab8500_fg_probe()
3199 disable_irq(di->irq); in ab8500_fg_probe()
3200 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_probe()
3206 dev_err(di->dev, "failed to create sysfs entry\n"); in ab8500_fg_probe()
3212 dev_err(di->dev, "failed to create FG psy\n"); in ab8500_fg_probe()
3218 di->flags.calibrate = true; in ab8500_fg_probe()
3219 di->calib_state = AB8500_FG_CALIB_INIT; in ab8500_fg_probe()
3222 di->bat_temp = 210; in ab8500_fg_probe()
3225 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_probe()
3227 list_add_tail(&di->node, &ab8500_fg_list); in ab8500_fg_probe()
3236 while (--i >= 0) { in ab8500_fg_probe()
3242 power_supply_unregister(di->fg_psy); in ab8500_fg_probe()
3244 destroy_workqueue(di->fg_wq); in ab8500_fg_probe()
3249 { .compatible = "stericsson,ab8500-fg", },
3259 .name = "ab8500-fg",
3279 MODULE_ALIAS("platform:ab8500-fg");