Lines Matching +full:full +full:- +full:ohms

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"
61 * struct ab8500_fg_interrupts - ab8500 fg interrupts
156 * struct ab8500_fg - ab8500 FG device information
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()
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()
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()
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()
471 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, 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()
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()
665 * Full scale input voltage is 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()
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()
881 dev_dbg(di->dev, "%s Vbat: %d, Cap: %d per mille", in ab8500_fg_volt_to_capacity()
888 * ab8500_fg_uncomp_volt_to_capacity() - Uncompensated voltage based capacity
896 di->vbat = ab8500_fg_bat_voltage(di); in ab8500_fg_uncomp_volt_to_capacity()
897 return ab8500_fg_volt_to_capacity(di, di->vbat); in ab8500_fg_uncomp_volt_to_capacity()
901 * ab8500_fg_battery_resistance() - Returns the battery inner resistance
913 tbl = di->bm->bat_type[di->bm->batt_id].batres_tbl; in ab8500_fg_battery_resistance()
914 tbl_size = di->bm->bat_type[di->bm->batt_id].n_batres_tbl_elements; in ab8500_fg_battery_resistance()
917 if (di->bat_temp / 10 > tbl[i].temp) in ab8500_fg_battery_resistance()
925 tbl[i-1].temp, in ab8500_fg_battery_resistance()
926 tbl[i-1].resist, in ab8500_fg_battery_resistance()
927 di->bat_temp / 10); in ab8500_fg_battery_resistance()
931 resist = tbl[tbl_size - 1].resist; in ab8500_fg_battery_resistance()
934 dev_dbg(di->dev, "%s Temp: %d battery internal resistance: %d" in ab8500_fg_battery_resistance()
936 __func__, di->bat_temp, resist, di->bm->fg_res / 10, in ab8500_fg_battery_resistance()
937 (di->bm->fg_res / 10) + resist); in ab8500_fg_battery_resistance()
940 resist += di->bm->fg_res / 10; in ab8500_fg_battery_resistance()
946 * ab8500_fg_load_comp_volt_to_capacity() - Load compensated voltage based capacity
966 ab8500_fg_inst_curr_finalize(di, &di->inst_curr); in ab8500_fg_load_comp_volt_to_capacity()
968 di->vbat = vbat / i; in ab8500_fg_load_comp_volt_to_capacity()
971 /* Use Ohms law to get the load compensated voltage */ in ab8500_fg_load_comp_volt_to_capacity()
972 vbat_comp = di->vbat - (di->inst_curr * res) / 1000; in ab8500_fg_load_comp_volt_to_capacity()
974 dev_dbg(di->dev, "%s Measured Vbat: %dmV,Compensated Vbat %dmV, " in ab8500_fg_load_comp_volt_to_capacity()
976 __func__, di->vbat, vbat_comp, res, di->inst_curr, i); in ab8500_fg_load_comp_volt_to_capacity()
982 * ab8500_fg_convert_mah_to_permille() - Capacity in mAh to permille
990 return (cap_mah * 1000) / di->bat_cap.max_mah_design; in ab8500_fg_convert_mah_to_permille()
994 * ab8500_fg_convert_permille_to_mah() - Capacity in permille to mAh
1002 return cap_pm * di->bat_cap.max_mah_design / 1000; in ab8500_fg_convert_permille_to_mah()
1006 * ab8500_fg_convert_mah_to_uwh() - Capacity in mAh to uWh
1017 div_res = ((u64) cap_mah) * ((u64) di->vbat_nom); in ab8500_fg_convert_mah_to_uwh()
1028 * ab8500_fg_calc_cap_charging() - Calculate remaining capacity while charging
1036 dev_dbg(di->dev, "%s cap_mah %d accu_charge %d\n", in ab8500_fg_calc_cap_charging()
1038 di->bat_cap.mah, in ab8500_fg_calc_cap_charging()
1039 di->accu_charge); in ab8500_fg_calc_cap_charging()
1042 if (di->bat_cap.mah + di->accu_charge > 0) in ab8500_fg_calc_cap_charging()
1043 di->bat_cap.mah += di->accu_charge; in ab8500_fg_calc_cap_charging()
1045 di->bat_cap.mah = 0; in ab8500_fg_calc_cap_charging()
1048 * reports that it's full. in ab8500_fg_calc_cap_charging()
1050 if (di->bat_cap.mah >= di->bat_cap.max_mah_design || in ab8500_fg_calc_cap_charging()
1051 di->flags.force_full) { in ab8500_fg_calc_cap_charging()
1052 di->bat_cap.mah = di->bat_cap.max_mah_design; in ab8500_fg_calc_cap_charging()
1055 ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); in ab8500_fg_calc_cap_charging()
1056 di->bat_cap.permille = in ab8500_fg_calc_cap_charging()
1057 ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_charging()
1060 di->vbat = ab8500_fg_bat_voltage(di); in ab8500_fg_calc_cap_charging()
1061 di->inst_curr = ab8500_fg_inst_curr_blocking(di); in ab8500_fg_calc_cap_charging()
1063 return di->bat_cap.mah; in ab8500_fg_calc_cap_charging()
1067 * ab8500_fg_calc_cap_discharge_voltage() - Capacity in discharge with voltage
1086 di->bat_cap.mah = ab8500_fg_add_cap_sample(di, mah); in ab8500_fg_calc_cap_discharge_voltage()
1087 di->bat_cap.permille = in ab8500_fg_calc_cap_discharge_voltage()
1088 ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_voltage()
1090 return di->bat_cap.mah; in ab8500_fg_calc_cap_discharge_voltage()
1094 * ab8500_fg_calc_cap_discharge_fg() - Capacity in discharge with FG
1105 dev_dbg(di->dev, "%s cap_mah %d accu_charge %d\n", in ab8500_fg_calc_cap_discharge_fg()
1107 di->bat_cap.mah, in ab8500_fg_calc_cap_discharge_fg()
1108 di->accu_charge); in ab8500_fg_calc_cap_discharge_fg()
1111 if (di->bat_cap.mah + di->accu_charge > 0) in ab8500_fg_calc_cap_discharge_fg()
1112 di->bat_cap.mah += di->accu_charge; in ab8500_fg_calc_cap_discharge_fg()
1114 di->bat_cap.mah = 0; in ab8500_fg_calc_cap_discharge_fg()
1116 if (di->bat_cap.mah >= di->bat_cap.max_mah_design) in ab8500_fg_calc_cap_discharge_fg()
1117 di->bat_cap.mah = di->bat_cap.max_mah_design; in ab8500_fg_calc_cap_discharge_fg()
1123 permille = ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1127 di->bat_cap.permille = permille_volt; in ab8500_fg_calc_cap_discharge_fg()
1128 di->bat_cap.mah = ab8500_fg_convert_permille_to_mah(di, in ab8500_fg_calc_cap_discharge_fg()
1129 di->bat_cap.permille); in ab8500_fg_calc_cap_discharge_fg()
1131 dev_dbg(di->dev, "%s voltage based: perm %d perm_volt %d\n", 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()
1138 ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1139 di->bat_cap.permille = in ab8500_fg_calc_cap_discharge_fg()
1140 ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); in ab8500_fg_calc_cap_discharge_fg()
1143 return di->bat_cap.mah; in ab8500_fg_calc_cap_discharge_fg()
1147 * ab8500_fg_capacity_level() - Get the battery capacity level
1156 percent = DIV_ROUND_CLOSEST(di->bat_cap.permille, 10); in ab8500_fg_capacity_level()
1158 if (percent <= di->bm->cap_levels->critical || in ab8500_fg_capacity_level()
1159 di->flags.low_bat) in ab8500_fg_capacity_level()
1161 else if (percent <= di->bm->cap_levels->low) in ab8500_fg_capacity_level()
1163 else if (percent <= di->bm->cap_levels->normal) in ab8500_fg_capacity_level()
1165 else if (percent <= di->bm->cap_levels->high) in ab8500_fg_capacity_level()
1174 * ab8500_fg_calculate_scaled_capacity() - Capacity scaling
1183 struct ab8500_fg_cap_scaling *cs = &di->bat_cap.cap_scale; in ab8500_fg_calculate_scaled_capacity()
1184 int capacity = di->bat_cap.prev_percent; in ab8500_fg_calculate_scaled_capacity()
1186 if (!cs->enable) in ab8500_fg_calculate_scaled_capacity()
1193 if (di->flags.fully_charged) { in ab8500_fg_calculate_scaled_capacity()
1194 cs->cap_to_scale[0] = 100; in ab8500_fg_calculate_scaled_capacity()
1195 cs->cap_to_scale[1] = in ab8500_fg_calculate_scaled_capacity()
1196 max(capacity, di->bm->fg_params->maint_thres); in ab8500_fg_calculate_scaled_capacity()
1197 dev_dbg(di->dev, "Scale cap with %d/%d\n", in ab8500_fg_calculate_scaled_capacity()
1198 cs->cap_to_scale[0], cs->cap_to_scale[1]); in ab8500_fg_calculate_scaled_capacity()
1202 if ((cs->cap_to_scale[0] != cs->cap_to_scale[1]) in ab8500_fg_calculate_scaled_capacity()
1203 && (cs->cap_to_scale[1] > 0)) in ab8500_fg_calculate_scaled_capacity()
1205 DIV_ROUND_CLOSEST(di->bat_cap.prev_percent * in ab8500_fg_calculate_scaled_capacity()
1206 cs->cap_to_scale[0], in ab8500_fg_calculate_scaled_capacity()
1207 cs->cap_to_scale[1])); in ab8500_fg_calculate_scaled_capacity()
1209 if (di->flags.charging) { in ab8500_fg_calculate_scaled_capacity()
1210 if (capacity < cs->disable_cap_level) { in ab8500_fg_calculate_scaled_capacity()
1211 cs->disable_cap_level = capacity; in ab8500_fg_calculate_scaled_capacity()
1212 dev_dbg(di->dev, "Cap to stop scale lowered %d%%\n", in ab8500_fg_calculate_scaled_capacity()
1213 cs->disable_cap_level); in ab8500_fg_calculate_scaled_capacity()
1214 } else if (!di->flags.fully_charged) { in ab8500_fg_calculate_scaled_capacity()
1215 if (di->bat_cap.prev_percent >= in ab8500_fg_calculate_scaled_capacity()
1216 cs->disable_cap_level) { in ab8500_fg_calculate_scaled_capacity()
1217 dev_dbg(di->dev, "Disabling scaled capacity\n"); in ab8500_fg_calculate_scaled_capacity()
1218 cs->enable = false; in ab8500_fg_calculate_scaled_capacity()
1219 capacity = di->bat_cap.prev_percent; in ab8500_fg_calculate_scaled_capacity()
1221 dev_dbg(di->dev, in ab8500_fg_calculate_scaled_capacity()
1223 cs->disable_cap_level); in ab8500_fg_calculate_scaled_capacity()
1224 capacity = cs->disable_cap_level; in ab8500_fg_calculate_scaled_capacity()
1233 * ab8500_fg_update_cap_scalers() - Capacity scaling
1236 * To be called when state change from charge<->discharge to update
1241 struct ab8500_fg_cap_scaling *cs = &di->bat_cap.cap_scale; in ab8500_fg_update_cap_scalers()
1243 if (!cs->enable) in ab8500_fg_update_cap_scalers()
1245 if (di->flags.charging) { in ab8500_fg_update_cap_scalers()
1246 di->bat_cap.cap_scale.disable_cap_level = in ab8500_fg_update_cap_scalers()
1247 di->bat_cap.cap_scale.scaled_cap; in ab8500_fg_update_cap_scalers()
1248 dev_dbg(di->dev, "Cap to stop scale at charge %d%%\n", in ab8500_fg_update_cap_scalers()
1249 di->bat_cap.cap_scale.disable_cap_level); in ab8500_fg_update_cap_scalers()
1251 if (cs->scaled_cap != 100) { in ab8500_fg_update_cap_scalers()
1252 cs->cap_to_scale[0] = cs->scaled_cap; in ab8500_fg_update_cap_scalers()
1253 cs->cap_to_scale[1] = di->bat_cap.prev_percent; in ab8500_fg_update_cap_scalers()
1255 cs->cap_to_scale[0] = 100; in ab8500_fg_update_cap_scalers()
1256 cs->cap_to_scale[1] = in ab8500_fg_update_cap_scalers()
1257 max(di->bat_cap.prev_percent, in ab8500_fg_update_cap_scalers()
1258 di->bm->fg_params->maint_thres); in ab8500_fg_update_cap_scalers()
1261 dev_dbg(di->dev, "Cap to scale at discharge %d/%d\n", in ab8500_fg_update_cap_scalers()
1262 cs->cap_to_scale[0], cs->cap_to_scale[1]); in ab8500_fg_update_cap_scalers()
1267 * ab8500_fg_check_capacity_limits() - Check if capacity has changed
1277 int percent = DIV_ROUND_CLOSEST(di->bat_cap.permille, 10); in ab8500_fg_check_capacity_limits()
1279 di->bat_cap.level = ab8500_fg_capacity_level(di); in ab8500_fg_check_capacity_limits()
1281 if (di->bat_cap.level != di->bat_cap.prev_level) { in ab8500_fg_check_capacity_limits()
1286 if (!(!di->flags.charging && di->bat_cap.level > in ab8500_fg_check_capacity_limits()
1287 di->bat_cap.prev_level) || init) { in ab8500_fg_check_capacity_limits()
1288 dev_dbg(di->dev, "level changed from %d to %d\n", in ab8500_fg_check_capacity_limits()
1289 di->bat_cap.prev_level, in ab8500_fg_check_capacity_limits()
1290 di->bat_cap.level); in ab8500_fg_check_capacity_limits()
1291 di->bat_cap.prev_level = di->bat_cap.level; in ab8500_fg_check_capacity_limits()
1294 dev_dbg(di->dev, "level not allowed to go up " in ab8500_fg_check_capacity_limits()
1296 di->bat_cap.prev_level, in ab8500_fg_check_capacity_limits()
1297 di->bat_cap.level); in ab8500_fg_check_capacity_limits()
1305 if (di->flags.low_bat) { in ab8500_fg_check_capacity_limits()
1306 dev_dbg(di->dev, "Battery low, set capacity to 0\n"); in ab8500_fg_check_capacity_limits()
1307 di->bat_cap.prev_percent = 0; in ab8500_fg_check_capacity_limits()
1308 di->bat_cap.permille = 0; in ab8500_fg_check_capacity_limits()
1310 di->bat_cap.prev_mah = 0; in ab8500_fg_check_capacity_limits()
1311 di->bat_cap.mah = 0; in ab8500_fg_check_capacity_limits()
1313 } else if (di->flags.fully_charged) { in ab8500_fg_check_capacity_limits()
1318 if (di->flags.force_full) { in ab8500_fg_check_capacity_limits()
1319 di->bat_cap.prev_percent = percent; in ab8500_fg_check_capacity_limits()
1320 di->bat_cap.prev_mah = di->bat_cap.mah; in ab8500_fg_check_capacity_limits()
1324 if (!di->bat_cap.cap_scale.enable && in ab8500_fg_check_capacity_limits()
1325 di->bm->capacity_scaling) { in ab8500_fg_check_capacity_limits()
1326 di->bat_cap.cap_scale.enable = true; in ab8500_fg_check_capacity_limits()
1327 di->bat_cap.cap_scale.cap_to_scale[0] = 100; in ab8500_fg_check_capacity_limits()
1328 di->bat_cap.cap_scale.cap_to_scale[1] = in ab8500_fg_check_capacity_limits()
1329 di->bat_cap.prev_percent; in ab8500_fg_check_capacity_limits()
1330 di->bat_cap.cap_scale.disable_cap_level = 100; in ab8500_fg_check_capacity_limits()
1332 } else if (di->bat_cap.prev_percent != percent) { in ab8500_fg_check_capacity_limits()
1333 dev_dbg(di->dev, in ab8500_fg_check_capacity_limits()
1334 "battery reported 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 } else if (di->bat_cap.prev_percent != percent) { in ab8500_fg_check_capacity_limits()
1349 di->bat_cap.prev_percent = 1; in ab8500_fg_check_capacity_limits()
1353 } else if (!(!di->flags.charging && in ab8500_fg_check_capacity_limits()
1354 percent > di->bat_cap.prev_percent) || init) { in ab8500_fg_check_capacity_limits()
1359 dev_dbg(di->dev, in ab8500_fg_check_capacity_limits()
1361 di->bat_cap.prev_percent, in ab8500_fg_check_capacity_limits()
1363 di->bat_cap.permille); in ab8500_fg_check_capacity_limits()
1364 di->bat_cap.prev_percent = percent; in ab8500_fg_check_capacity_limits()
1365 di->bat_cap.prev_mah = di->bat_cap.mah; in ab8500_fg_check_capacity_limits()
1369 dev_dbg(di->dev, "capacity not allowed to go up since " in ab8500_fg_check_capacity_limits()
1371 di->bat_cap.prev_percent, in ab8500_fg_check_capacity_limits()
1373 di->bat_cap.permille); in ab8500_fg_check_capacity_limits()
1378 if (di->bm->capacity_scaling) { in ab8500_fg_check_capacity_limits()
1379 di->bat_cap.cap_scale.scaled_cap = in ab8500_fg_check_capacity_limits()
1382 dev_info(di->dev, "capacity=%d (%d)\n", in ab8500_fg_check_capacity_limits()
1383 di->bat_cap.prev_percent, in ab8500_fg_check_capacity_limits()
1384 di->bat_cap.cap_scale.scaled_cap); in ab8500_fg_check_capacity_limits()
1386 power_supply_changed(di->fg_psy); in ab8500_fg_check_capacity_limits()
1387 if (di->flags.fully_charged && di->flags.force_full) { in ab8500_fg_check_capacity_limits()
1388 dev_dbg(di->dev, "Battery full, notifying.\n"); in ab8500_fg_check_capacity_limits()
1389 di->flags.force_full = false; in ab8500_fg_check_capacity_limits()
1390 sysfs_notify(&di->fg_kobject, NULL, "charge_full"); in ab8500_fg_check_capacity_limits()
1392 sysfs_notify(&di->fg_kobject, NULL, "charge_now"); in ab8500_fg_check_capacity_limits()
1399 dev_dbg(di->dev, "Charge state from %d [%s] to %d [%s]\n", in ab8500_fg_charge_state_to()
1400 di->charge_state, in ab8500_fg_charge_state_to()
1401 charge_state[di->charge_state], in ab8500_fg_charge_state_to()
1405 di->charge_state = new_state; in ab8500_fg_charge_state_to()
1411 dev_dbg(di->dev, "Discharge state from %d [%s] to %d [%s]\n", in ab8500_fg_discharge_state_to()
1412 di->discharge_state, in ab8500_fg_discharge_state_to()
1413 discharge_state[di->discharge_state], in ab8500_fg_discharge_state_to()
1417 di->discharge_state = new_state; in ab8500_fg_discharge_state_to()
1421 * ab8500_fg_algorithm_charging() - FG algorithm for when charging
1432 if (di->discharge_state != AB8500_FG_DISCHARGE_INIT_RECOVERY) in ab8500_fg_algorithm_charging()
1436 switch (di->charge_state) { in ab8500_fg_algorithm_charging()
1438 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_charging()
1439 di->bm->fg_params->accu_charging); in ab8500_fg_algorithm_charging()
1450 mutex_lock(&di->cc_lock); in ab8500_fg_algorithm_charging()
1451 if (!di->flags.conv_done && !di->flags.force_full) { in ab8500_fg_algorithm_charging()
1453 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_charging()
1454 dev_dbg(di->dev, "%s CC conv not done\n", in ab8500_fg_algorithm_charging()
1459 di->flags.conv_done = false; in ab8500_fg_algorithm_charging()
1460 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_charging()
1479 cap = di->bat_cap.user_mah; in force_capacity()
1480 if (cap > di->bat_cap.max_mah_design) { in force_capacity()
1481 dev_dbg(di->dev, "Remaining cap %d can't be bigger than total" in force_capacity()
1482 " %d\n", cap, di->bat_cap.max_mah_design); in force_capacity()
1483 cap = di->bat_cap.max_mah_design; in force_capacity()
1485 ab8500_fg_fill_cap_sample(di, di->bat_cap.user_mah); in force_capacity()
1486 di->bat_cap.permille = ab8500_fg_convert_mah_to_permille(di, cap); in force_capacity()
1487 di->bat_cap.mah = cap; in force_capacity()
1496 cap = di->bat_cap.user_mah; in check_sysfs_capacity()
1499 di->bat_cap.user_mah); in check_sysfs_capacity()
1501 lower = di->bat_cap.permille - di->bm->fg_params->user_cap_limit * 10; in check_sysfs_capacity()
1502 upper = di->bat_cap.permille + di->bm->fg_params->user_cap_limit * 10; in check_sysfs_capacity()
1506 /* 1000 is permille, -> 100 percent */ in check_sysfs_capacity()
1510 dev_dbg(di->dev, "Capacity limits:" in check_sysfs_capacity()
1512 lower, cap_permille, upper, cap, di->bat_cap.mah); in check_sysfs_capacity()
1516 dev_dbg(di->dev, "OK! Using users cap %d uAh now\n", cap); in check_sysfs_capacity()
1520 dev_dbg(di->dev, "Capacity from user out of limits, ignoring"); in check_sysfs_capacity()
1525 * ab8500_fg_algorithm_discharging() - FG algorithm for when discharging
1535 if (di->charge_state != AB8500_FG_CHARGE_INIT) in ab8500_fg_algorithm_discharging()
1538 switch (di->discharge_state) { in ab8500_fg_algorithm_discharging()
1541 di->init_cnt = 0; in ab8500_fg_algorithm_discharging()
1542 di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer); in ab8500_fg_algorithm_discharging()
1555 sleep_time = di->bm->fg_params->init_timer; in ab8500_fg_algorithm_discharging()
1558 if (di->init_cnt > di->bm->fg_params->init_discard_time) { in ab8500_fg_algorithm_discharging()
1564 di->init_cnt += sleep_time; in ab8500_fg_algorithm_discharging()
1565 if (di->init_cnt > di->bm->fg_params->init_total_time) in ab8500_fg_algorithm_discharging()
1572 di->recovery_cnt = 0; in ab8500_fg_algorithm_discharging()
1573 di->recovery_needed = true; in ab8500_fg_algorithm_discharging()
1580 sleep_time = di->bm->fg_params->recovery_sleep_timer; in ab8500_fg_algorithm_discharging()
1588 di->inst_curr = ab8500_fg_inst_curr_blocking(di); in ab8500_fg_algorithm_discharging()
1590 if (ab8500_fg_is_low_curr(di, di->inst_curr)) { in ab8500_fg_algorithm_discharging()
1591 if (di->recovery_cnt > in ab8500_fg_algorithm_discharging()
1592 di->bm->fg_params->recovery_total_time) { in ab8500_fg_algorithm_discharging()
1593 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1594 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1598 di->recovery_needed = false; in ab8500_fg_algorithm_discharging()
1600 queue_delayed_work(di->fg_wq, in ab8500_fg_algorithm_discharging()
1601 &di->fg_periodic_work, in ab8500_fg_algorithm_discharging()
1604 di->recovery_cnt += sleep_time; in ab8500_fg_algorithm_discharging()
1606 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1607 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1615 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1616 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1623 di->inst_curr = ab8500_fg_inst_curr_blocking(di); in ab8500_fg_algorithm_discharging()
1625 if (ab8500_fg_is_low_curr(di, di->inst_curr)) { in ab8500_fg_algorithm_discharging()
1627 if (di->high_curr_mode) { in ab8500_fg_algorithm_discharging()
1628 di->high_curr_mode = false; in ab8500_fg_algorithm_discharging()
1629 di->high_curr_cnt = 0; in ab8500_fg_algorithm_discharging()
1632 if (di->recovery_needed) { in ab8500_fg_algorithm_discharging()
1636 queue_delayed_work(di->fg_wq, in ab8500_fg_algorithm_discharging()
1637 &di->fg_periodic_work, 0); in ab8500_fg_algorithm_discharging()
1644 mutex_lock(&di->cc_lock); in ab8500_fg_algorithm_discharging()
1645 if (!di->flags.conv_done) { in ab8500_fg_algorithm_discharging()
1647 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_discharging()
1648 dev_dbg(di->dev, "%s CC conv not done\n", in ab8500_fg_algorithm_discharging()
1653 di->flags.conv_done = false; in ab8500_fg_algorithm_discharging()
1654 mutex_unlock(&di->cc_lock); in ab8500_fg_algorithm_discharging()
1657 if (!di->high_curr_mode) { in ab8500_fg_algorithm_discharging()
1658 di->high_curr_mode = true; in ab8500_fg_algorithm_discharging()
1659 di->high_curr_cnt = 0; in ab8500_fg_algorithm_discharging()
1662 di->high_curr_cnt += in ab8500_fg_algorithm_discharging()
1663 di->bm->fg_params->accu_high_curr; in ab8500_fg_algorithm_discharging()
1664 if (di->high_curr_cnt > in ab8500_fg_algorithm_discharging()
1665 di->bm->fg_params->high_curr_time) in ab8500_fg_algorithm_discharging()
1666 di->recovery_needed = true; in ab8500_fg_algorithm_discharging()
1678 di->fg_samples = SEC_TO_SAMPLE( in ab8500_fg_algorithm_discharging()
1679 di->bm->fg_params->accu_high_curr); in ab8500_fg_algorithm_discharging()
1694 * ab8500_fg_algorithm_calibrate() - Internal columb counter offset calibration
1702 switch (di->calib_state) { in ab8500_fg_algorithm_calibrate()
1704 dev_dbg(di->dev, "Calibration ongoing...\n"); in ab8500_fg_algorithm_calibrate()
1706 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_algorithm_calibrate()
1712 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_algorithm_calibrate()
1717 di->calib_state = AB8500_FG_CALIB_WAIT; in ab8500_fg_algorithm_calibrate()
1720 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_algorithm_calibrate()
1725 di->flags.calibrate = false; in ab8500_fg_algorithm_calibrate()
1726 dev_dbg(di->dev, "Calibration done...\n"); in ab8500_fg_algorithm_calibrate()
1727 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_algorithm_calibrate()
1730 dev_dbg(di->dev, "Calibration WFI\n"); in ab8500_fg_algorithm_calibrate()
1738 dev_err(di->dev, "failed to calibrate the CC\n"); in ab8500_fg_algorithm_calibrate()
1739 di->flags.calibrate = false; in ab8500_fg_algorithm_calibrate()
1740 di->calib_state = AB8500_FG_CALIB_INIT; in ab8500_fg_algorithm_calibrate()
1741 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_algorithm_calibrate()
1745 * ab8500_fg_algorithm() - Entry point for the FG algorithm
1752 if (di->flags.calibrate) in ab8500_fg_algorithm()
1755 if (di->flags.charging) in ab8500_fg_algorithm()
1761 dev_dbg(di->dev, "[FG_DATA] %d %d %d %d %d %d %d %d %d %d " in ab8500_fg_algorithm()
1763 di->bat_cap.max_mah_design, in ab8500_fg_algorithm()
1764 di->bat_cap.max_mah, in ab8500_fg_algorithm()
1765 di->bat_cap.mah, in ab8500_fg_algorithm()
1766 di->bat_cap.permille, in ab8500_fg_algorithm()
1767 di->bat_cap.level, in ab8500_fg_algorithm()
1768 di->bat_cap.prev_mah, in ab8500_fg_algorithm()
1769 di->bat_cap.prev_percent, in ab8500_fg_algorithm()
1770 di->bat_cap.prev_level, in ab8500_fg_algorithm()
1771 di->vbat, in ab8500_fg_algorithm()
1772 di->inst_curr, in ab8500_fg_algorithm()
1773 di->avg_curr, in ab8500_fg_algorithm()
1774 di->accu_charge, in ab8500_fg_algorithm()
1775 di->flags.charging, in ab8500_fg_algorithm()
1776 di->charge_state, in ab8500_fg_algorithm()
1777 di->discharge_state, in ab8500_fg_algorithm()
1778 di->high_curr_mode, in ab8500_fg_algorithm()
1779 di->recovery_needed); in ab8500_fg_algorithm()
1783 * ab8500_fg_periodic_work() - Run the FG state machine periodically
1793 if (di->init_capacity) { in ab8500_fg_periodic_work()
1797 di->init_capacity = false; in ab8500_fg_periodic_work()
1799 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_periodic_work()
1800 } else if (di->flags.user_cap) { in ab8500_fg_periodic_work()
1803 if (di->flags.charging) in ab8500_fg_periodic_work()
1810 di->flags.user_cap = false; in ab8500_fg_periodic_work()
1811 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_periodic_work()
1818 * ab8500_fg_check_hw_failure_work() - Check OVV_BAT condition
1832 * If we have had a battery over-voltage situation, in ab8500_fg_check_hw_failure_work()
1833 * check ovv-bit to see if it should be reset. in ab8500_fg_check_hw_failure_work()
1835 ret = abx500_get_register_interruptible(di->dev, in ab8500_fg_check_hw_failure_work()
1839 dev_err(di->dev, "%s ab8500 read failed\n", __func__); in ab8500_fg_check_hw_failure_work()
1843 if (!di->flags.bat_ovv) { in ab8500_fg_check_hw_failure_work()
1844 dev_dbg(di->dev, "Battery OVV\n"); in ab8500_fg_check_hw_failure_work()
1845 di->flags.bat_ovv = true; in ab8500_fg_check_hw_failure_work()
1846 power_supply_changed(di->fg_psy); in ab8500_fg_check_hw_failure_work()
1849 queue_delayed_work(di->fg_wq, &di->fg_check_hw_failure_work, in ab8500_fg_check_hw_failure_work()
1852 dev_dbg(di->dev, "Battery recovered from OVV\n"); in ab8500_fg_check_hw_failure_work()
1853 di->flags.bat_ovv = false; in ab8500_fg_check_hw_failure_work()
1854 power_supply_changed(di->fg_psy); in ab8500_fg_check_hw_failure_work()
1859 * ab8500_fg_low_bat_work() - Check LOW_BAT condition
1874 if (vbat < di->bm->fg_params->lowbat_threshold) { in ab8500_fg_low_bat_work()
1876 if (di->low_bat_cnt < 1) { in ab8500_fg_low_bat_work()
1877 di->flags.low_bat = true; in ab8500_fg_low_bat_work()
1878 dev_warn(di->dev, "Shut down pending...\n"); in ab8500_fg_low_bat_work()
1881 * Else we need to re-schedule this check to be able to detect in ab8500_fg_low_bat_work()
1885 di->low_bat_cnt--; in ab8500_fg_low_bat_work()
1886 dev_warn(di->dev, "Battery voltage still LOW\n"); in ab8500_fg_low_bat_work()
1887 queue_delayed_work(di->fg_wq, &di->fg_low_bat_work, in ab8500_fg_low_bat_work()
1891 di->flags.low_bat_delay = false; in ab8500_fg_low_bat_work()
1892 di->low_bat_cnt = 10; in ab8500_fg_low_bat_work()
1893 dev_warn(di->dev, "Battery voltage OK again\n"); in ab8500_fg_low_bat_work()
1901 * ab8500_fg_battok_calc - calculate the bit pattern corresponding
1907 * valid return values are 0-14. (0-BATT_OK_MAX_NR_INCREMENTS)
1917 return (target - BATT_OK_MIN) / BATT_OK_INCREMENT; in ab8500_fg_battok_calc()
1921 * ab8500_fg_battok_init_hw_register - init battok levels
1936 sel0 = di->bm->fg_params->battok_falling_th_sel0; in ab8500_fg_battok_init_hw_register()
1937 sel1 = di->bm->fg_params->battok_raising_th_sel1; in ab8500_fg_battok_init_hw_register()
1945 dev_warn(di->dev, "Invalid voltage step:%d, using %d %d\n", in ab8500_fg_battok_init_hw_register()
1951 dev_warn(di->dev, "Invalid voltage step:%d, using %d %d\n", in ab8500_fg_battok_init_hw_register()
1956 dev_dbg(di->dev, "using: %x %d %d\n", new_val, cbp_sel0, cbp_sel1); in ab8500_fg_battok_init_hw_register()
1957 ret = abx500_set_register_interruptible(di->dev, AB8500_SYS_CTRL2_BLOCK, in ab8500_fg_battok_init_hw_register()
1963 * ab8500_fg_instant_work() - Run the FG state machine instantly
1976 * ab8500_fg_cc_data_end_handler() - end of data conversion isr.
1985 if (!di->nbr_cceoc_irq_cnt) { in ab8500_fg_cc_data_end_handler()
1986 di->nbr_cceoc_irq_cnt++; in ab8500_fg_cc_data_end_handler()
1987 complete(&di->ab8500_fg_started); in ab8500_fg_cc_data_end_handler()
1989 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_cc_data_end_handler()
1990 complete(&di->ab8500_fg_complete); in ab8500_fg_cc_data_end_handler()
1996 * ab8500_fg_cc_int_calib_handler () - end of calibration isr.
2005 di->calib_state = AB8500_FG_CALIB_END; in ab8500_fg_cc_int_calib_handler()
2006 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_cc_int_calib_handler()
2011 * ab8500_fg_cc_convend_handler() - isr to get battery avg current.
2021 queue_work(di->fg_wq, &di->fg_acc_cur_work); in ab8500_fg_cc_convend_handler()
2027 * ab8500_fg_batt_ovv_handler() - Battery OVV occured
2037 dev_dbg(di->dev, "Battery OVV\n"); in ab8500_fg_batt_ovv_handler()
2040 queue_delayed_work(di->fg_wq, &di->fg_check_hw_failure_work, 0); in ab8500_fg_batt_ovv_handler()
2046 * ab8500_fg_lowbatf_handler() - Battery voltage is below LOW threshold
2057 if (!di->flags.low_bat_delay) { in ab8500_fg_lowbatf_handler()
2058 dev_warn(di->dev, "Battery voltage is below LOW threshold\n"); in ab8500_fg_lowbatf_handler()
2059 di->flags.low_bat_delay = true; in ab8500_fg_lowbatf_handler()
2064 queue_delayed_work(di->fg_wq, &di->fg_low_bat_work, in ab8500_fg_lowbatf_handler()
2071 * ab8500_fg_get_property() - get the fg properties
2081 * charge_full_design: capacity where battery is considered full
2103 if (di->flags.bat_ovv) in ab8500_fg_get_property()
2104 val->intval = BATT_OVV_VALUE * 1000; in ab8500_fg_get_property()
2106 val->intval = di->vbat * 1000; in ab8500_fg_get_property()
2109 val->intval = di->inst_curr * 1000; in ab8500_fg_get_property()
2112 val->intval = di->avg_curr * 1000; in ab8500_fg_get_property()
2115 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2116 di->bat_cap.max_mah_design); in ab8500_fg_get_property()
2119 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2120 di->bat_cap.max_mah); in ab8500_fg_get_property()
2123 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2124 di->flags.batt_id_received) in ab8500_fg_get_property()
2125 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2126 di->bat_cap.max_mah); in ab8500_fg_get_property()
2128 val->intval = ab8500_fg_convert_mah_to_uwh(di, in ab8500_fg_get_property()
2129 di->bat_cap.prev_mah); in ab8500_fg_get_property()
2132 val->intval = di->bat_cap.max_mah_design; in ab8500_fg_get_property()
2135 val->intval = di->bat_cap.max_mah; in ab8500_fg_get_property()
2138 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2139 di->flags.batt_id_received) in ab8500_fg_get_property()
2140 val->intval = di->bat_cap.max_mah; in ab8500_fg_get_property()
2142 val->intval = di->bat_cap.prev_mah; in ab8500_fg_get_property()
2145 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2146 di->flags.batt_id_received) in ab8500_fg_get_property()
2147 val->intval = 100; in ab8500_fg_get_property()
2149 val->intval = di->bat_cap.prev_percent; in ab8500_fg_get_property()
2152 if (di->flags.batt_unknown && !di->bm->chg_unknown_bat && in ab8500_fg_get_property()
2153 di->flags.batt_id_received) in ab8500_fg_get_property()
2154 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; in ab8500_fg_get_property()
2156 val->intval = di->bat_cap.prev_level; in ab8500_fg_get_property()
2159 return -EINVAL; in ab8500_fg_get_property()
2168 const char **supplicants = (const char **)ext->supplied_to; in ab8500_fg_get_ext_psy_data()
2180 j = match_string(supplicants, ext->num_supplicants, psy->desc->name); in ab8500_fg_get_ext_psy_data()
2185 for (j = 0; j < ext->desc->num_properties; j++) { in ab8500_fg_get_ext_psy_data()
2187 prop = ext->desc->properties[j]; in ab8500_fg_get_ext_psy_data()
2194 switch (ext->desc->type) { in ab8500_fg_get_ext_psy_data()
2200 if (!di->flags.charging) in ab8500_fg_get_ext_psy_data()
2202 di->flags.charging = false; in ab8500_fg_get_ext_psy_data()
2203 di->flags.fully_charged = false; in ab8500_fg_get_ext_psy_data()
2204 if (di->bm->capacity_scaling) in ab8500_fg_get_ext_psy_data()
2206 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_get_ext_psy_data()
2209 if (di->flags.fully_charged) in ab8500_fg_get_ext_psy_data()
2211 di->flags.fully_charged = true; in ab8500_fg_get_ext_psy_data()
2212 di->flags.force_full = true; in ab8500_fg_get_ext_psy_data()
2214 di->bat_cap.max_mah = di->bat_cap.mah; in ab8500_fg_get_ext_psy_data()
2215 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_get_ext_psy_data()
2218 if (di->flags.charging && in ab8500_fg_get_ext_psy_data()
2219 !di->flags.fully_charged) in ab8500_fg_get_ext_psy_data()
2221 di->flags.charging = true; in ab8500_fg_get_ext_psy_data()
2222 di->flags.fully_charged = false; in ab8500_fg_get_ext_psy_data()
2223 if (di->bm->capacity_scaling) in ab8500_fg_get_ext_psy_data()
2225 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_get_ext_psy_data()
2234 switch (ext->desc->type) { in ab8500_fg_get_ext_psy_data()
2236 if (!di->flags.batt_id_received && in ab8500_fg_get_ext_psy_data()
2237 di->bm->batt_id != BATTERY_UNKNOWN) { in ab8500_fg_get_ext_psy_data()
2240 b = &(di->bm->bat_type[di->bm->batt_id]); in ab8500_fg_get_ext_psy_data()
2242 di->flags.batt_id_received = true; in ab8500_fg_get_ext_psy_data()
2244 di->bat_cap.max_mah_design = in ab8500_fg_get_ext_psy_data()
2246 b->charge_full_design; in ab8500_fg_get_ext_psy_data()
2248 di->bat_cap.max_mah = in ab8500_fg_get_ext_psy_data()
2249 di->bat_cap.max_mah_design; in ab8500_fg_get_ext_psy_data()
2251 di->vbat_nom = b->nominal_voltage; in ab8500_fg_get_ext_psy_data()
2255 di->flags.batt_unknown = false; in ab8500_fg_get_ext_psy_data()
2257 di->flags.batt_unknown = true; in ab8500_fg_get_ext_psy_data()
2264 switch (ext->desc->type) { in ab8500_fg_get_ext_psy_data()
2266 if (di->flags.batt_id_received) in ab8500_fg_get_ext_psy_data()
2267 di->bat_temp = ret.intval; in ab8500_fg_get_ext_psy_data()
2281 * ab8500_fg_init_hw_registers() - Set up FG related registers
2291 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_init_hw_registers()
2297 dev_err(di->dev, "failed to set BATT_OVV\n"); in ab8500_fg_init_hw_registers()
2302 ret = abx500_mask_and_set_register_interruptible(di->dev, in ab8500_fg_init_hw_registers()
2308 dev_err(di->dev, "failed to enable BATT_OVV\n"); in ab8500_fg_init_hw_registers()
2313 ret = abx500_set_register_interruptible(di->dev, in ab8500_fg_init_hw_registers()
2317 di->bm->fg_params->lowbat_threshold) << 1 | in ab8500_fg_init_hw_registers()
2320 dev_err(di->dev, "%s write failed\n", __func__); in ab8500_fg_init_hw_registers()
2327 dev_err(di->dev, "BattOk init write failed.\n"); in ab8500_fg_init_hw_registers()
2331 if (is_ab8505(di->parent)) { in ab8500_fg_init_hw_registers()
2332 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2333 AB8505_RTC_PCUT_MAX_TIME_REG, di->bm->fg_params->pcut_max_time); in ab8500_fg_init_hw_registers()
2336 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_MAX_TIME_REG\n", __func__); in ab8500_fg_init_hw_registers()
2340 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2341 AB8505_RTC_PCUT_FLAG_TIME_REG, di->bm->fg_params->pcut_flag_time); in ab8500_fg_init_hw_registers()
2344 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_FLAG_TIME_REG\n", __func__); in ab8500_fg_init_hw_registers()
2348 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2349 AB8505_RTC_PCUT_RESTART_REG, di->bm->fg_params->pcut_max_restart); in ab8500_fg_init_hw_registers()
2352 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_RESTART_REG\n", __func__); in ab8500_fg_init_hw_registers()
2356 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2357 AB8505_RTC_PCUT_DEBOUNCE_REG, di->bm->fg_params->pcut_debounce_time); in ab8500_fg_init_hw_registers()
2360 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_DEBOUNCE_REG\n", __func__); in ab8500_fg_init_hw_registers()
2364 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8500_fg_init_hw_registers()
2365 AB8505_RTC_PCUT_CTL_STATUS_REG, di->bm->fg_params->pcut_enable); in ab8500_fg_init_hw_registers()
2368 dev_err(di->dev, "%s write failed AB8505_RTC_PCUT_CTL_STATUS_REG\n", __func__); in ab8500_fg_init_hw_registers()
2377 * ab8500_fg_external_power_changed() - callback for power supply changes
2390 di->fg_psy, ab8500_fg_get_ext_psy_data); in ab8500_fg_external_power_changed()
2394 * ab8500_fg_reinit_work() - work to reset the FG algorithm
2406 if (!di->flags.calibrate) { in ab8500_fg_reinit_work()
2407 dev_dbg(di->dev, "Resetting FG state machine to init.\n"); in ab8500_fg_reinit_work()
2412 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_reinit_work()
2415 dev_err(di->dev, "Residual offset calibration ongoing " in ab8500_fg_reinit_work()
2418 queue_delayed_work(di->fg_wq, &di->fg_reinit_work, in ab8500_fg_reinit_work()
2433 return sprintf(buf, "%d\n", di->bat_cap.max_mah); in charge_full_show()
2446 di->bat_cap.max_mah = (int) charge_full; in charge_full_store()
2452 return sprintf(buf, "%d\n", di->bat_cap.prev_mah); in charge_now_show()
2465 di->bat_cap.user_mah = (int) charge_now; in charge_now_store()
2466 di->flags.user_cap = true; in charge_now_store()
2467 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in charge_now_store()
2486 if (!entry->show) in ab8500_fg_show()
2487 return -EIO; in ab8500_fg_show()
2489 return entry->show(di, buf); in ab8500_fg_show()
2501 if (!entry->store) in ab8500_fg_store()
2502 return -EIO; in ab8500_fg_store()
2504 return entry->store(di, buf, count); in ab8500_fg_store()
2524 * ab8500_fg_sysfs_exit() - de-init of sysfs entry
2531 kobject_del(&di->fg_kobject); in ab8500_fg_sysfs_exit()
2535 * ab8500_fg_sysfs_init() - init of sysfs entry
2545 ret = kobject_init_and_add(&di->fg_kobject, in ab8500_fg_sysfs_init()
2549 dev_err(di->dev, "failed to create sysfs entry\n"); in ab8500_fg_sysfs_init()
2563 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_flagtime_read()
2590 dev_err(dev, "Incorrect parameter, echo 0 (1.98s) - 127 (15.625ms) for flagtime\n"); in ab8505_powercut_flagtime_write()
2594 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_flagtime_write()
2613 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_maxtime_read()
2641 dev_err(dev, "Incorrect parameter, echo 0 (0.0s) - 127 (1.98s) for maxtime\n"); in ab8505_powercut_maxtime_write()
2645 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_maxtime_write()
2664 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_restart_read()
2691 dev_err(dev, "Incorrect parameter, echo 0 - 15 for number of restart\n"); in ab8505_powercut_restart_write()
2695 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_restart_write()
2715 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_timer_read()
2738 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_restart_counter_read()
2761 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_read()
2790 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_write()
2810 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_flag_read()
2833 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_debounce_read()
2864 ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_debounce_write()
2883 ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, in ab8505_powercut_enable_status_read()
2920 if (is_ab8505(di->parent)) { in ab8500_fg_sysfs_psy_create_attrs()
2922 if (device_create_file(&di->fg_psy->dev, in ab8500_fg_sysfs_psy_create_attrs()
2928 dev_err(&di->fg_psy->dev, "Failed creating sysfs psy attrs for ab8505.\n"); in ab8500_fg_sysfs_psy_create_attrs()
2929 while (i--) in ab8500_fg_sysfs_psy_create_attrs()
2930 device_remove_file(&di->fg_psy->dev, in ab8500_fg_sysfs_psy_create_attrs()
2933 return -EIO; in ab8500_fg_sysfs_psy_create_attrs()
2940 if (is_ab8505(di->parent)) { in ab8500_fg_sysfs_psy_remove_attrs()
2942 (void)device_remove_file(&di->fg_psy->dev, in ab8500_fg_sysfs_psy_remove_attrs()
2957 if (!di->flags.charging) { in ab8500_fg_resume()
2959 queue_work(di->fg_wq, &di->fg_work); in ab8500_fg_resume()
2969 flush_delayed_work(&di->fg_periodic_work); in ab8500_fg_suspend()
2970 flush_work(&di->fg_work); in ab8500_fg_suspend()
2971 flush_work(&di->fg_acc_cur_work); in ab8500_fg_suspend()
2972 flush_delayed_work(&di->fg_reinit_work); in ab8500_fg_suspend()
2973 flush_delayed_work(&di->fg_low_bat_work); in ab8500_fg_suspend()
2974 flush_delayed_work(&di->fg_check_hw_failure_work); in ab8500_fg_suspend()
2980 if (di->flags.fg_enabled && !di->flags.charging) in ab8500_fg_suspend()
3015 di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM); in ab8500_fg_bind()
3016 if (di->fg_wq == NULL) { in ab8500_fg_bind()
3018 return -ENOMEM; in ab8500_fg_bind()
3024 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); in ab8500_fg_bind()
3040 destroy_workqueue(di->fg_wq); in ab8500_fg_unbind()
3051 struct device *dev = &pdev->dev; in ab8500_fg_probe()
3059 return -ENOMEM; in ab8500_fg_probe()
3061 di->bm = &ab8500_bm_data; in ab8500_fg_probe()
3063 mutex_init(&di->cc_lock); in ab8500_fg_probe()
3066 di->dev = dev; in ab8500_fg_probe()
3067 di->parent = dev_get_drvdata(pdev->dev.parent); in ab8500_fg_probe()
3069 di->main_bat_v = devm_iio_channel_get(dev, "main_bat_v"); in ab8500_fg_probe()
3070 if (IS_ERR(di->main_bat_v)) { in ab8500_fg_probe()
3071 ret = dev_err_probe(dev, PTR_ERR(di->main_bat_v), in ab8500_fg_probe()
3080 di->bat_cap.max_mah_design = MILLI_TO_MICRO * in ab8500_fg_probe()
3081 di->bm->bat_type[di->bm->batt_id].charge_full_design; in ab8500_fg_probe()
3083 di->bat_cap.max_mah = di->bat_cap.max_mah_design; in ab8500_fg_probe()
3085 di->vbat_nom = di->bm->bat_type[di->bm->batt_id].nominal_voltage; in ab8500_fg_probe()
3087 di->init_capacity = true; in ab8500_fg_probe()
3093 INIT_WORK(&di->fg_work, ab8500_fg_instant_work); in ab8500_fg_probe()
3096 INIT_WORK(&di->fg_acc_cur_work, ab8500_fg_acc_cur_work); in ab8500_fg_probe()
3099 INIT_DEFERRABLE_WORK(&di->fg_reinit_work, in ab8500_fg_probe()
3103 INIT_DEFERRABLE_WORK(&di->fg_periodic_work, in ab8500_fg_probe()
3107 INIT_DEFERRABLE_WORK(&di->fg_low_bat_work, in ab8500_fg_probe()
3111 INIT_DEFERRABLE_WORK(&di->fg_check_hw_failure_work, in ab8500_fg_probe()
3115 di->flags.low_bat = false; in ab8500_fg_probe()
3118 di->low_bat_cnt = 10; in ab8500_fg_probe()
3128 di->flags.batt_unknown = true; in ab8500_fg_probe()
3129 di->flags.batt_id_received = false; in ab8500_fg_probe()
3132 di->fg_psy = devm_power_supply_register(dev, &ab8500_fg_desc, &psy_cfg); in ab8500_fg_probe()
3133 if (IS_ERR(di->fg_psy)) { in ab8500_fg_probe()
3135 return PTR_ERR(di->fg_psy); in ab8500_fg_probe()
3138 di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer); in ab8500_fg_probe()
3144 init_completion(&di->ab8500_fg_started); in ab8500_fg_probe()
3145 init_completion(&di->ab8500_fg_complete); in ab8500_fg_probe()
3167 di->irq = platform_get_irq_byname(pdev, "CCEOC"); in ab8500_fg_probe()
3168 disable_irq(di->irq); in ab8500_fg_probe()
3169 di->nbr_cceoc_irq_cnt = 0; in ab8500_fg_probe()
3187 di->flags.calibrate = true; in ab8500_fg_probe()
3188 di->calib_state = AB8500_FG_CALIB_INIT; in ab8500_fg_probe()
3191 di->bat_temp = 210; in ab8500_fg_probe()
3193 list_add_tail(&di->node, &ab8500_fg_list); in ab8500_fg_probe()
3203 component_del(&pdev->dev, &ab8500_fg_component_ops); in ab8500_fg_remove()
3204 list_del(&di->node); in ab8500_fg_remove()
3214 { .compatible = "stericsson,ab8500-fg", },
3223 .name = "ab8500-fg",
3230 MODULE_ALIAS("platform:ab8500-fg");