From 4cf19d6cd0e3d431ee1765dfa35c9873a9724e74 Mon Sep 17 00:00:00 2001 From: Kalle Komierowski Date: Fri, 1 Apr 2011 14:35:09 +0200 Subject: power: ab8500_bm: Removal of maintenance charging This patch makes it possible to remove the maintenance A and B charging states and replaces them with a state that restarts the charging when the battery voltage level dropped below a certain level. The maintenance charging can now be turned of by setting a flag in the board configuration. ST-Ericsson Linux Next: - ST-Ericsson ID: CR333019 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: Ie5e8ab20a3b57a1028d544371b10ffbb1fd77660 Signed-off-by: Kalle Komierowski Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/19916 Reviewed-by: Johan GARDSMARK Reviewed-by: Johan PALSSON Reviewed-by: Jonas ABERG Tested-by: Karl KOMIEROWSKI --- arch/arm/mach-ux500/board-mop500-bm.c | 7 +++++ drivers/power/ab8500_chargalg.c | 55 +++++++++++++++++++++++++++++++++-- drivers/power/ab8500_fg.c | 3 +- include/linux/mfd/ab8500/bm.h | 7 +++++ 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-ux500/board-mop500-bm.c b/arch/arm/mach-ux500/board-mop500-bm.c index 945964f3300..66ced8e088e 100644 --- a/arch/arm/mach-ux500/board-mop500-bm.c +++ b/arch/arm/mach-ux500/board-mop500-bm.c @@ -160,6 +160,7 @@ static const struct battery_type bat_type[] = { .nominal_voltage = 3700, .termination_vol = 4050, .termination_curr = 200, + .recharge_vol = 3990, .normal_cur_lvl = 400, .normal_vol_lvl = 4100, .maint_a_cur_lvl = 400, @@ -186,6 +187,7 @@ static const struct battery_type bat_type[] = { .nominal_voltage = 3600, .termination_vol = 4150, .termination_curr = 80, + .recharge_vol = 4130, .normal_cur_lvl = 700, .normal_vol_lvl = 4200, .maint_a_cur_lvl = 600, @@ -211,6 +213,7 @@ static const struct battery_type bat_type[] = { .nominal_voltage = 3600, .termination_vol = 4150, .termination_curr = 80, + .recharge_vol = 4130, .normal_cur_lvl = 700, .normal_vol_lvl = 4200, .maint_a_cur_lvl = 600, @@ -241,6 +244,7 @@ static const struct battery_type bat_type[] = { .nominal_voltage = 3700, .termination_vol = 4150, .termination_curr = 100, + .recharge_vol = 4130, .normal_cur_lvl = 700, .normal_vol_lvl = 4200, .maint_a_cur_lvl = 600, @@ -265,6 +269,7 @@ static const struct battery_type bat_type[] = { .nominal_voltage = 3700, .termination_vol = 4150, .termination_curr = 100, + .recharge_vol = 4130, .normal_cur_lvl = 700, .normal_vol_lvl = 4200, .maint_a_cur_lvl = 600, @@ -289,6 +294,7 @@ static const struct battery_type bat_type[] = { .nominal_voltage = 3700, .termination_vol = 4150, .termination_curr = 100, + .recharge_vol = 4130, .normal_cur_lvl = 700, .normal_vol_lvl = 4200, .maint_a_cur_lvl = 600, @@ -390,6 +396,7 @@ struct ab8500_bm_data ab8500_bm_data = { .usb_safety_tmr_h = 4, .bkup_bat_v = BUP_VCH_SEL_2P6V, .bkup_bat_i = BUP_ICH_SEL_150UA, + .no_maintenance = false, #ifdef CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL .adc_therm = ADC_THERM_BATCTRL, #else diff --git a/drivers/power/ab8500_chargalg.c b/drivers/power/ab8500_chargalg.c index 788d81aa7cd..cb56c67475c 100644 --- a/drivers/power/ab8500_chargalg.c +++ b/drivers/power/ab8500_chargalg.c @@ -30,6 +30,9 @@ /* End-of-charge criteria counter */ #define EOC_COND_CNT 10 +/* Recharge criteria counter */ +#define RCH_COND_CNT 3 + #define to_ab8500_chargalg_device_info(x) container_of((x), \ struct ab8500_chargalg, chargalg_psy); @@ -80,6 +83,8 @@ enum ab8500_chargalg_states { STATE_HW_TEMP_PROTECT, STATE_NORMAL_INIT, STATE_NORMAL, + STATE_WAIT_FOR_RECHARGE_INIT, + STATE_WAIT_FOR_RECHARGE, STATE_MAINTENANCE_A_INIT, STATE_MAINTENANCE_A, STATE_MAINTENANCE_B_INIT, @@ -109,6 +114,8 @@ static const char *states[] = { "HW_TEMP_PROTECT", "NORMAL_INIT", "NORMAL", + "WAIT_FOR_RECHARGE_INIT", + "WAIT_FOR_RECHARGE", "MAINTENANCE_A_INIT", "MAINTENANCE_A", "MAINTENANCE_B_INIT", @@ -186,6 +193,7 @@ enum maxim_ret { * @dev: pointer to the structure device * @charge_status: battery operating status * @eoc_cnt: counter used to determine end-of_charge + * @rch_cnt: counter used to determine start of recharge * @maintenance_chg: indicate if maintenance charge is active * @t_hyst_norm temperature hysteresis when the temperature has been * over or under normal limits @@ -214,6 +222,7 @@ struct ab8500_chargalg { struct device *dev; int charge_status; int eoc_cnt; + int rch_cnt; bool maintenance_chg; int t_hyst_norm; int t_hyst_lowhigh; @@ -568,6 +577,26 @@ static void ab8500_chargalg_stop_charging(struct ab8500_chargalg *di) power_supply_changed(&di->chargalg_psy); } +/** + * ab8500_chargalg_hold_charging() - Pauses charging + * @di: pointer to the ab8500_chargalg structure + * + * This function is called in the case where maintenance charging has been + * disabled and instead a battery voltage mode is entered to check when the + * battery voltage has reached a certain recharge voltage + */ +static void ab8500_chargalg_hold_charging(struct ab8500_chargalg *di) +{ + ab8500_chargalg_ac_en(di, false, 0, 0); + ab8500_chargalg_usb_en(di, false, 0, 0); + ab8500_chargalg_stop_safety_timer(di); + ab8500_chargalg_stop_maintenance_timer(di); + di->charge_status = POWER_SUPPLY_STATUS_CHARGING; + di->maintenance_chg = false; + cancel_delayed_work(&di->chargalg_wd_work); + power_supply_changed(&di->chargalg_psy); +} + /** * ab8500_chargalg_start_charging() - Start the charger * @di: pointer to the ab8500_chargalg structure @@ -1384,11 +1413,31 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di) case STATE_NORMAL: handle_maxim_chg_curr(di); - if (di->charge_status == POWER_SUPPLY_STATUS_FULL && - di->maintenance_chg) - ab8500_chargalg_state_to(di, STATE_MAINTENANCE_A_INIT); + di->maintenance_chg) { + if (di->bat->no_maintenance) + ab8500_chargalg_state_to(di, + STATE_WAIT_FOR_RECHARGE_INIT); + else + ab8500_chargalg_state_to(di, + STATE_MAINTENANCE_A_INIT); + } + break; + /* This state will be used when the maintenance state is disabled */ + case STATE_WAIT_FOR_RECHARGE_INIT: + ab8500_chargalg_hold_charging(di); + ab8500_chargalg_state_to(di, STATE_WAIT_FOR_RECHARGE); + di->rch_cnt = RCH_COND_CNT; + /* Intentional fallthrough */ + + case STATE_WAIT_FOR_RECHARGE: + if (di->batt_data.volt <= + di->bat->bat_type[di->bat->batt_id].recharge_vol) { + if (di->rch_cnt-- == 0) + ab8500_chargalg_state_to(di, STATE_NORMAL_INIT); + } else + di->rch_cnt = RCH_COND_CNT; break; case STATE_MAINTENANCE_A_INIT: diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index a42ce95d48f..8af5216b90b 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -590,8 +590,7 @@ static void ab8500_fg_acc_cur_work(struct work_struct *work) mutex_unlock(&di->cc_lock); - queue_work(di->fg_wq, - &di->fg_work); + queue_work(di->fg_wq, &di->fg_work); return; exit: diff --git a/include/linux/mfd/ab8500/bm.h b/include/linux/mfd/ab8500/bm.h index 068b63a93ce..2ca4d8779cb 100644 --- a/include/linux/mfd/ab8500/bm.h +++ b/include/linux/mfd/ab8500/bm.h @@ -312,6 +312,10 @@ struct ab8500_maxim_parameters { * @charge_full_design: Maximum battery capacity in mAh * @nominal_voltage: Nominal voltage of the battery in mV * @termination_vol: max voltage upto which battery can be charged + * @termination_curr battery charging termination current in mA + * @recharge_vol battery voltage limit that will trigger a new + * full charging cycle in the case where maintenan- + * -ce charging has been disabled * @normal_cur_lvl: charger current in normal state in mA * @normal_vol_lvl: charger voltage in normal state in mV * @maint_a_cur_lvl: charger current in maintenance A state in mA @@ -336,6 +340,7 @@ struct battery_type { int nominal_voltage; int termination_vol; int termination_curr; + int recharge_vol; int normal_cur_lvl; int normal_vol_lvl; int maint_a_cur_lvl; @@ -393,6 +398,7 @@ struct ab8500_bm_charger_parameters { * @usb_safety_tmr_h safety timer for usb charger * @bkup_bat_v voltage which we charge the backup battery with * @bkup_bat_i current which we charge the backup battery with + * @no_maintenance indicates that maintenance charging is disabled * @adc_therm placement of thermistor, batctrl or battemp adc * @chg_unknown_bat flag to enable charging of unknown batteries * @enable_overshoot flag to enable VBAT overshoot control @@ -417,6 +423,7 @@ struct ab8500_bm_data { int usb_safety_tmr_h; int bkup_bat_v; int bkup_bat_i; + bool no_maintenance; bool chg_unknown_bat; bool enable_overshoot; enum adc_therm adc_therm; -- cgit v1.2.3