diff options
| author | Arun Murthy <arun.murthy@stericsson.com> | 2012-02-29 11:24:25 -0500 |
|---|---|---|
| committer | Anton Vorontsov <anton.vorontsov@linaro.org> | 2012-03-26 12:41:02 -0400 |
| commit | 1668f81159fb72eda2114a9c73a64ffee045cb01 (patch) | |
| tree | c93f2386110dd43f57d27343bec461f75fd31321 | |
| parent | ed1a230f96eb4610f1f4296b8c3c067389ddf540 (diff) | |
abx500-chargalg: Add abx500 charging algorithm
This is a charging algorithm driver for abx500 variants. It is the central
entity for battery driver and is responsible for charging and monitoring
the battery driver. It is a hardware independant driver and also monitors
other abx500 power supply devices.
Signed-off-by: Arun Murthy <arun.murthy@stericsson.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
| -rw-r--r-- | drivers/power/abx500_chargalg.c | 1921 | ||||
| -rw-r--r-- | include/linux/mfd/abx500.h | 273 | ||||
| -rw-r--r-- | include/linux/mfd/abx500/ux500_chargalg.h | 38 |
3 files changed, 2232 insertions, 0 deletions
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c new file mode 100644 index 000000000000..fbb6a1fe97e4 --- /dev/null +++ b/drivers/power/abx500_chargalg.c | |||
| @@ -0,0 +1,1921 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2012 | ||
| 3 | * | ||
| 4 | * Charging algorithm driver for abx500 variants | ||
| 5 | * | ||
| 6 | * License Terms: GNU General Public License v2 | ||
| 7 | * Authors: | ||
| 8 | * Johan Palsson <johan.palsson@stericsson.com> | ||
| 9 | * Karl Komierowski <karl.komierowski@stericsson.com> | ||
| 10 | * Arun R Murthy <arun.murthy@stericsson.com> | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/slab.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/power_supply.h> | ||
| 21 | #include <linux/completion.h> | ||
| 22 | #include <linux/workqueue.h> | ||
| 23 | #include <linux/kobject.h> | ||
| 24 | #include <linux/mfd/abx500.h> | ||
| 25 | #include <linux/mfd/abx500/ux500_chargalg.h> | ||
| 26 | #include <linux/mfd/abx500/ab8500-bm.h> | ||
| 27 | |||
| 28 | /* Watchdog kick interval */ | ||
| 29 | #define CHG_WD_INTERVAL (6 * HZ) | ||
| 30 | |||
| 31 | /* End-of-charge criteria counter */ | ||
| 32 | #define EOC_COND_CNT 10 | ||
| 33 | |||
| 34 | /* Recharge criteria counter */ | ||
| 35 | #define RCH_COND_CNT 3 | ||
| 36 | |||
| 37 | #define to_abx500_chargalg_device_info(x) container_of((x), \ | ||
| 38 | struct abx500_chargalg, chargalg_psy); | ||
| 39 | |||
| 40 | enum abx500_chargers { | ||
| 41 | NO_CHG, | ||
| 42 | AC_CHG, | ||
| 43 | USB_CHG, | ||
| 44 | }; | ||
| 45 | |||
| 46 | struct abx500_chargalg_charger_info { | ||
| 47 | enum abx500_chargers conn_chg; | ||
| 48 | enum abx500_chargers prev_conn_chg; | ||
| 49 | enum abx500_chargers online_chg; | ||
| 50 | enum abx500_chargers prev_online_chg; | ||
| 51 | enum abx500_chargers charger_type; | ||
| 52 | bool usb_chg_ok; | ||
| 53 | bool ac_chg_ok; | ||
| 54 | int usb_volt; | ||
| 55 | int usb_curr; | ||
| 56 | int ac_volt; | ||
| 57 | int ac_curr; | ||
| 58 | int usb_vset; | ||
| 59 | int usb_iset; | ||
| 60 | int ac_vset; | ||
| 61 | int ac_iset; | ||
| 62 | }; | ||
| 63 | |||
| 64 | struct abx500_chargalg_suspension_status { | ||
| 65 | bool suspended_change; | ||
| 66 | bool ac_suspended; | ||
| 67 | bool usb_suspended; | ||
| 68 | }; | ||
| 69 | |||
| 70 | struct abx500_chargalg_battery_data { | ||
| 71 | int temp; | ||
| 72 | int volt; | ||
| 73 | int avg_curr; | ||
| 74 | int inst_curr; | ||
| 75 | int percent; | ||
| 76 | }; | ||
| 77 | |||
| 78 | enum abx500_chargalg_states { | ||
| 79 | STATE_HANDHELD_INIT, | ||
| 80 | STATE_HANDHELD, | ||
| 81 | STATE_CHG_NOT_OK_INIT, | ||
| 82 | STATE_CHG_NOT_OK, | ||
| 83 | STATE_HW_TEMP_PROTECT_INIT, | ||
| 84 | STATE_HW_TEMP_PROTECT, | ||
| 85 | STATE_NORMAL_INIT, | ||
| 86 | STATE_NORMAL, | ||
| 87 | STATE_WAIT_FOR_RECHARGE_INIT, | ||
| 88 | STATE_WAIT_FOR_RECHARGE, | ||
| 89 | STATE_MAINTENANCE_A_INIT, | ||
| 90 | STATE_MAINTENANCE_A, | ||
| 91 | STATE_MAINTENANCE_B_INIT, | ||
| 92 | STATE_MAINTENANCE_B, | ||
| 93 | STATE_TEMP_UNDEROVER_INIT, | ||
| 94 | STATE_TEMP_UNDEROVER, | ||
| 95 | STATE_TEMP_LOWHIGH_INIT, | ||
| 96 | STATE_TEMP_LOWHIGH, | ||
| 97 | STATE_SUSPENDED_INIT, | ||
| 98 | STATE_SUSPENDED, | ||
| 99 | STATE_OVV_PROTECT_INIT, | ||
| 100 | STATE_OVV_PROTECT, | ||
| 101 | STATE_SAFETY_TIMER_EXPIRED_INIT, | ||
| 102 | STATE_SAFETY_TIMER_EXPIRED, | ||
| 103 | STATE_BATT_REMOVED_INIT, | ||
| 104 | STATE_BATT_REMOVED, | ||
| 105 | STATE_WD_EXPIRED_INIT, | ||
| 106 | STATE_WD_EXPIRED, | ||
| 107 | }; | ||
| 108 | |||
| 109 | static const char *states[] = { | ||
| 110 | "HANDHELD_INIT", | ||
| 111 | "HANDHELD", | ||
| 112 | "CHG_NOT_OK_INIT", | ||
| 113 | "CHG_NOT_OK", | ||
| 114 | "HW_TEMP_PROTECT_INIT", | ||
| 115 | "HW_TEMP_PROTECT", | ||
| 116 | "NORMAL_INIT", | ||
| 117 | "NORMAL", | ||
| 118 | "WAIT_FOR_RECHARGE_INIT", | ||
| 119 | "WAIT_FOR_RECHARGE", | ||
| 120 | "MAINTENANCE_A_INIT", | ||
| 121 | "MAINTENANCE_A", | ||
| 122 | "MAINTENANCE_B_INIT", | ||
| 123 | "MAINTENANCE_B", | ||
| 124 | "TEMP_UNDEROVER_INIT", | ||
| 125 | "TEMP_UNDEROVER", | ||
| 126 | "TEMP_LOWHIGH_INIT", | ||
| 127 | "TEMP_LOWHIGH", | ||
| 128 | "SUSPENDED_INIT", | ||
| 129 | "SUSPENDED", | ||
| 130 | "OVV_PROTECT_INIT", | ||
| 131 | "OVV_PROTECT", | ||
| 132 | "SAFETY_TIMER_EXPIRED_INIT", | ||
| 133 | "SAFETY_TIMER_EXPIRED", | ||
| 134 | "BATT_REMOVED_INIT", | ||
| 135 | "BATT_REMOVED", | ||
| 136 | "WD_EXPIRED_INIT", | ||
| 137 | "WD_EXPIRED", | ||
| 138 | }; | ||
| 139 | |||
| 140 | struct abx500_chargalg_events { | ||
| 141 | bool batt_unknown; | ||
| 142 | bool mainextchnotok; | ||
| 143 | bool batt_ovv; | ||
| 144 | bool batt_rem; | ||
| 145 | bool btemp_underover; | ||
| 146 | bool btemp_lowhigh; | ||
| 147 | bool main_thermal_prot; | ||
| 148 | bool usb_thermal_prot; | ||
| 149 | bool main_ovv; | ||
| 150 | bool vbus_ovv; | ||
| 151 | bool usbchargernotok; | ||
| 152 | bool safety_timer_expired; | ||
| 153 | bool maintenance_timer_expired; | ||
| 154 | bool ac_wd_expired; | ||
| 155 | bool usb_wd_expired; | ||
| 156 | bool ac_cv_active; | ||
| 157 | bool usb_cv_active; | ||
| 158 | bool vbus_collapsed; | ||
| 159 | }; | ||
| 160 | |||
| 161 | /** | ||
| 162 | * struct abx500_charge_curr_maximization - Charger maximization parameters | ||
| 163 | * @original_iset: the non optimized/maximised charger current | ||
| 164 | * @current_iset: the charging current used at this moment | ||
| 165 | * @test_delta_i: the delta between the current we want to charge and the | ||
| 166 | current that is really going into the battery | ||
| 167 | * @condition_cnt: number of iterations needed before a new charger current | ||
| 168 | is set | ||
| 169 | * @max_current: maximum charger current | ||
| 170 | * @wait_cnt: to avoid too fast current step down in case of charger | ||
| 171 | * voltage collapse, we insert this delay between step | ||
| 172 | * down | ||
| 173 | * @level: tells in how many steps the charging current has been | ||
| 174 | increased | ||
| 175 | */ | ||
| 176 | struct abx500_charge_curr_maximization { | ||
| 177 | int original_iset; | ||
| 178 | int current_iset; | ||
| 179 | int test_delta_i; | ||
| 180 | int condition_cnt; | ||
| 181 | int max_current; | ||
| 182 | int wait_cnt; | ||
| 183 | u8 level; | ||
| 184 | }; | ||
| 185 | |||
| 186 | enum maxim_ret { | ||
| 187 | MAXIM_RET_NOACTION, | ||
| 188 | MAXIM_RET_CHANGE, | ||
| 189 | MAXIM_RET_IBAT_TOO_HIGH, | ||
| 190 | }; | ||
| 191 | |||
| 192 | /** | ||
| 193 | * struct abx500_chargalg - abx500 Charging algorithm device information | ||
| 194 | * @dev: pointer to the structure device | ||
