blob: 78b623572b526426f1004a9846abaa9707d30a8d [file] [log] [blame]
Arun Murthy1668f812012-02-29 21:54:25 +05301/*
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>
Rajanikanth H.Va12810a2012-10-31 15:40:33 +000024#include <linux/of.h>
25#include <linux/mfd/core.h>
Arun Murthy1668f812012-02-29 21:54:25 +053026#include <linux/mfd/abx500.h>
27#include <linux/mfd/abx500/ux500_chargalg.h>
28#include <linux/mfd/abx500/ab8500-bm.h>
29
30/* Watchdog kick interval */
31#define CHG_WD_INTERVAL (6 * HZ)
32
33/* End-of-charge criteria counter */
34#define EOC_COND_CNT 10
35
Arun Murthy1668f812012-02-29 21:54:25 +053036#define to_abx500_chargalg_device_info(x) container_of((x), \
37 struct abx500_chargalg, chargalg_psy);
38
39enum abx500_chargers {
40 NO_CHG,
41 AC_CHG,
42 USB_CHG,
43};
44
45struct abx500_chargalg_charger_info {
46 enum abx500_chargers conn_chg;
47 enum abx500_chargers prev_conn_chg;
48 enum abx500_chargers online_chg;
49 enum abx500_chargers prev_online_chg;
50 enum abx500_chargers charger_type;
51 bool usb_chg_ok;
52 bool ac_chg_ok;
53 int usb_volt;
54 int usb_curr;
55 int ac_volt;
56 int ac_curr;
57 int usb_vset;
58 int usb_iset;
59 int ac_vset;
60 int ac_iset;
61};
62
63struct abx500_chargalg_suspension_status {
64 bool suspended_change;
65 bool ac_suspended;
66 bool usb_suspended;
67};
68
69struct abx500_chargalg_battery_data {
70 int temp;
71 int volt;
72 int avg_curr;
73 int inst_curr;
74 int percent;
75};
76
77enum abx500_chargalg_states {
78 STATE_HANDHELD_INIT,
79 STATE_HANDHELD,
80 STATE_CHG_NOT_OK_INIT,
81 STATE_CHG_NOT_OK,
82 STATE_HW_TEMP_PROTECT_INIT,
83 STATE_HW_TEMP_PROTECT,
84 STATE_NORMAL_INIT,
85 STATE_NORMAL,
86 STATE_WAIT_FOR_RECHARGE_INIT,
87 STATE_WAIT_FOR_RECHARGE,
88 STATE_MAINTENANCE_A_INIT,
89 STATE_MAINTENANCE_A,
90 STATE_MAINTENANCE_B_INIT,
91 STATE_MAINTENANCE_B,
92 STATE_TEMP_UNDEROVER_INIT,
93 STATE_TEMP_UNDEROVER,
94 STATE_TEMP_LOWHIGH_INIT,
95 STATE_TEMP_LOWHIGH,
96 STATE_SUSPENDED_INIT,
97 STATE_SUSPENDED,
98 STATE_OVV_PROTECT_INIT,
99 STATE_OVV_PROTECT,
100 STATE_SAFETY_TIMER_EXPIRED_INIT,
101 STATE_SAFETY_TIMER_EXPIRED,
102 STATE_BATT_REMOVED_INIT,
103 STATE_BATT_REMOVED,
104 STATE_WD_EXPIRED_INIT,
105 STATE_WD_EXPIRED,
106};
107
108static const char *states[] = {
109 "HANDHELD_INIT",
110 "HANDHELD",
111 "CHG_NOT_OK_INIT",
112 "CHG_NOT_OK",
113 "HW_TEMP_PROTECT_INIT",
114 "HW_TEMP_PROTECT",
115 "NORMAL_INIT",
116 "NORMAL",
117 "WAIT_FOR_RECHARGE_INIT",
118 "WAIT_FOR_RECHARGE",
119 "MAINTENANCE_A_INIT",
120 "MAINTENANCE_A",
121 "MAINTENANCE_B_INIT",
122 "MAINTENANCE_B",
123 "TEMP_UNDEROVER_INIT",
124 "TEMP_UNDEROVER",
125 "TEMP_LOWHIGH_INIT",
126 "TEMP_LOWHIGH",
127 "SUSPENDED_INIT",
128 "SUSPENDED",
129 "OVV_PROTECT_INIT",
130 "OVV_PROTECT",
131 "SAFETY_TIMER_EXPIRED_INIT",
132 "SAFETY_TIMER_EXPIRED",
133 "BATT_REMOVED_INIT",
134 "BATT_REMOVED",
135 "WD_EXPIRED_INIT",
136 "WD_EXPIRED",
137};
138
139struct abx500_chargalg_events {
140 bool batt_unknown;
141 bool mainextchnotok;
142 bool batt_ovv;
143 bool batt_rem;
144 bool btemp_underover;
145 bool btemp_lowhigh;
146 bool main_thermal_prot;
147 bool usb_thermal_prot;
148 bool main_ovv;
149 bool vbus_ovv;
150 bool usbchargernotok;
151 bool safety_timer_expired;
152 bool maintenance_timer_expired;
153 bool ac_wd_expired;
154 bool usb_wd_expired;
155 bool ac_cv_active;
156 bool usb_cv_active;
157 bool vbus_collapsed;
158};
159
160/**
161 * struct abx500_charge_curr_maximization - Charger maximization parameters
162 * @original_iset: the non optimized/maximised charger current
163 * @current_iset: the charging current used at this moment
164 * @test_delta_i: the delta between the current we want to charge and the
165 current that is really going into the battery
166 * @condition_cnt: number of iterations needed before a new charger current
167 is set
168 * @max_current: maximum charger current
169 * @wait_cnt: to avoid too fast current step down in case of charger
170 * voltage collapse, we insert this delay between step
171 * down
172 * @level: tells in how many steps the charging current has been
173 increased
174 */
175struct abx500_charge_curr_maximization {
176 int original_iset;
177 int current_iset;
178 int test_delta_i;
179 int condition_cnt;
180 int max_current;
181 int wait_cnt;
182 u8 level;
183};
184
185enum maxim_ret {
186 MAXIM_RET_NOACTION,
187 MAXIM_RET_CHANGE,
188 MAXIM_RET_IBAT_TOO_HIGH,
189};
190
191/**
192 * struct abx500_chargalg - abx500 Charging algorithm device information
193 * @dev: pointer to the structure device
194 * @charge_status: battery operating status
195 * @eoc_cnt: counter used to determine end-of_charge
Arun Murthy1668f812012-02-29 21:54:25 +0530196 * @maintenance_chg: indicate if maintenance charge is active
197 * @t_hyst_norm temperature hysteresis when the temperature has been
198 * over or under normal limits
199 * @t_hyst_lowhigh temperature hysteresis when the temperature has been
200 * over or under the high or low limits
201 * @charge_state: current state of the charging algorithm
202 * @ccm charging current maximization parameters
203 * @chg_info: information about connected charger types
204 * @batt_data: data of the battery
205 * @susp_status: current charger suspension status
Lee Jonesb0284de2012-11-30 10:09:42 +0000206 * @bm: Platform specific battery management information
Arun Murthy1668f812012-02-29 21:54:25 +0530207 * @chargalg_psy: structure that holds the battery properties exposed by
208 * the charging algorithm
209 * @events: structure for information about events triggered
210 * @chargalg_wq: work queue for running the charging algorithm
211 * @chargalg_periodic_work: work to run the charging algorithm periodically
212 * @chargalg_wd_work: work to kick the charger watchdog periodically
213 * @chargalg_work: work to run the charging algorithm instantly
214 * @safety_timer: charging safety timer
215 * @maintenance_timer: maintenance charging timer
216 * @chargalg_kobject: structure of type kobject
217 */
218struct abx500_chargalg {
219 struct device *dev;
220 int charge_status;
221 int eoc_cnt;
Arun Murthy1668f812012-02-29 21:54:25 +0530222 bool maintenance_chg;
223 int t_hyst_norm;
224 int t_hyst_lowhigh;
225 enum abx500_chargalg_states charge_state;
226 struct abx500_charge_curr_maximization ccm;
227 struct abx500_chargalg_charger_info chg_info;
228 struct abx500_chargalg_battery_data batt_data;
229 struct abx500_chargalg_suspension_status susp_status;
Lee Jonesb0284de2012-11-30 10:09:42 +0000230 struct abx500_bm_data *bm;
Arun Murthy1668f812012-02-29 21:54:25 +0530231 struct power_supply chargalg_psy;
232 struct ux500_charger *ac_chg;
233 struct ux500_charger *usb_chg;
234 struct abx500_chargalg_events events;
235 struct workqueue_struct *chargalg_wq;
236 struct delayed_work chargalg_periodic_work;
237 struct delayed_work chargalg_wd_work;
238 struct work_struct chargalg_work;
239 struct timer_list safety_timer;
240 struct timer_list maintenance_timer;
241 struct kobject chargalg_kobject;
242};
243
244/* Main battery properties */
245static enum power_supply_property abx500_chargalg_props[] = {
246 POWER_SUPPLY_PROP_STATUS,
247 POWER_SUPPLY_PROP_HEALTH,
248};
249
250/**
251 * abx500_chargalg_safety_timer_expired() - Expiration of the safety timer
252 * @data: pointer to the abx500_chargalg structure
253 *
254 * This function gets called when the safety timer for the charger
255 * expires
256 */
257static void abx500_chargalg_safety_timer_expired(unsigned long data)
258{
259 struct abx500_chargalg *di = (struct abx500_chargalg *) data;
260 dev_err(di->dev, "Safety timer expired\n");
261 di->events.safety_timer_expired = true;
262
263 /* Trigger execution of the algorithm instantly */
264 queue_work(di->chargalg_wq, &di->chargalg_work);
265}
266
267/**
268 * abx500_chargalg_maintenance_timer_expired() - Expiration of
269 * the maintenance timer
270 * @i: pointer to the abx500_chargalg structure
271 *
272 * This function gets called when the maintenence timer
273 * expires
274 */
275static void abx500_chargalg_maintenance_timer_expired(unsigned long data)
276{
277
278 struct abx500_chargalg *di = (struct abx500_chargalg *) data;
279 dev_dbg(di->dev, "Maintenance timer expired\n");
280 di->events.maintenance_timer_expired = true;
281
282 /* Trigger execution of the algorithm instantly */
283 queue_work(di->chargalg_wq, &di->chargalg_work);
284}
285
286/**
287 * abx500_chargalg_state_to() - Change charge state
288 * @di: pointer to the abx500_chargalg structure
289 *
290 * This function gets called when a charge state change should occur
291 */
292static void abx500_chargalg_state_to(struct abx500_chargalg *di,
293 enum abx500_chargalg_states state)
294{
295 dev_dbg(di->dev,
296 "State changed: %s (From state: [%d] %s =to=> [%d] %s )\n",
297 di->charge_state == state ? "NO" : "YES",
298 di->charge_state,
299 states[di->charge_state],
300 state,
301 states[state]);
302
303 di->charge_state = state;
304}
305
306/**
307 * abx500_chargalg_check_charger_connection() - Check charger connection change
308 * @di: pointer to the abx500_chargalg structure
309 *
310 * This function will check if there is a change in the charger connection
311 * and change charge state accordingly. AC has precedence over USB.
312 */
313static int abx500_chargalg_check_charger_connection(struct abx500_chargalg *di)
314{
315 if (di->chg_info.conn_chg != di->chg_info.prev_conn_chg ||
316 di->susp_status.suspended_change) {
317 /*
318 * Charger state changed or suspension
319 * has changed since last update
320 */
321 if ((di->chg_info.conn_chg & AC_CHG) &&
322 !di->susp_status.ac_suspended) {
323 dev_dbg(di->dev, "Charging source is AC\n");
324 if (di->chg_info.charger_type != AC_CHG) {
325 di->chg_info.charger_type = AC_CHG;
326 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
327 }
328 } else if ((di->chg_info.conn_chg & USB_CHG) &&
329 !di->susp_status.usb_suspended) {
330 dev_dbg(di->dev, "Charging source is USB\n");
331 di->chg_info.charger_type = USB_CHG;
332 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
333 } else if (di->chg_info.conn_chg &&
334 (di->susp_status.ac_suspended ||
335 di->susp_status.usb_suspended)) {
336 dev_dbg(di->dev, "Charging is suspended\n");
337 di->chg_info.charger_type = NO_CHG;
338 abx500_chargalg_state_to(di, STATE_SUSPENDED_INIT);
339 } else {
340 dev_dbg(di->dev, "Charging source is OFF\n");
341 di->chg_info.charger_type = NO_CHG;
342 abx500_chargalg_state_to(di, STATE_HANDHELD_INIT);
343 }
344 di->chg_info.prev_conn_chg = di->chg_info.conn_chg;
345 di->susp_status.suspended_change = false;
346 }
347 return di->chg_info.conn_chg;
348}
349
350/**
351 * abx500_chargalg_start_safety_timer() - Start charging safety timer
352 * @di: pointer to the abx500_chargalg structure
353 *
354 * The safety timer is used to avoid overcharging of old or bad batteries.
355 * There are different timers for AC and USB
356 */
357static void abx500_chargalg_start_safety_timer(struct abx500_chargalg *di)
358{
359 unsigned long timer_expiration = 0;
360
361 switch (di->chg_info.charger_type) {
362 case AC_CHG:
363 timer_expiration =
364 round_jiffies(jiffies +
Lee Jonesb0284de2012-11-30 10:09:42 +0000365 (di->bm->main_safety_tmr_h * 3600 * HZ));
Arun Murthy1668f812012-02-29 21:54:25 +0530366 break;
367
368 case USB_CHG:
369 timer_expiration =
370 round_jiffies(jiffies +
Lee Jonesb0284de2012-11-30 10:09:42 +0000371 (di->bm->usb_safety_tmr_h * 3600 * HZ));
Arun Murthy1668f812012-02-29 21:54:25 +0530372 break;
373
374 default:
375 dev_err(di->dev, "Unknown charger to charge from\n");
376 break;
377 }
378
379 di->events.safety_timer_expired = false;
380 di->safety_timer.expires = timer_expiration;
381 if (!timer_pending(&di->safety_timer))
382 add_timer(&di->safety_timer);
383 else
384 mod_timer(&di->safety_timer, timer_expiration);
385}
386
387/**
388 * abx500_chargalg_stop_safety_timer() - Stop charging safety timer
389 * @di: pointer to the abx500_chargalg structure
390 *
391 * The safety timer is stopped whenever the NORMAL state is exited
392 */
393static void abx500_chargalg_stop_safety_timer(struct abx500_chargalg *di)
394{
395 di->events.safety_timer_expired = false;
396 del_timer(&di->safety_timer);
397}
398
399/**
400 * abx500_chargalg_start_maintenance_timer() - Start charging maintenance timer
401 * @di: pointer to the abx500_chargalg structure
402 * @duration: duration of ther maintenance timer in hours
403 *
404 * The maintenance timer is used to maintain the charge in the battery once
405 * the battery is considered full. These timers are chosen to match the
406 * discharge curve of the battery
407 */
408static void abx500_chargalg_start_maintenance_timer(struct abx500_chargalg *di,
409 int duration)
410{
411 unsigned long timer_expiration;
412
413 /* Convert from hours to jiffies */
414 timer_expiration = round_jiffies(jiffies + (duration * 3600 * HZ));
415
416 di->events.maintenance_timer_expired = false;
417 di->maintenance_timer.expires = timer_expiration;
418 if (!timer_pending(&di->maintenance_timer))
419 add_timer(&di->maintenance_timer);
420 else
421 mod_timer(&di->maintenance_timer, timer_expiration);
422}
423
424/**
425 * abx500_chargalg_stop_maintenance_timer() - Stop maintenance timer
426 * @di: pointer to the abx500_chargalg structure
427 *
428 * The maintenance timer is stopped whenever maintenance ends or when another
429 * state is entered
430 */
431static void abx500_chargalg_stop_maintenance_timer(struct abx500_chargalg *di)
432{
433 di->events.maintenance_timer_expired = false;
434 del_timer(&di->maintenance_timer);
435}
436
437/**
438 * abx500_chargalg_kick_watchdog() - Kick charger watchdog
439 * @di: pointer to the abx500_chargalg structure
440 *
441 * The charger watchdog have to be kicked periodically whenever the charger is
442 * on, else the ABB will reset the system
443 */
444static int abx500_chargalg_kick_watchdog(struct abx500_chargalg *di)
445{
446 /* Check if charger exists and kick watchdog if charging */
447 if (di->ac_chg && di->ac_chg->ops.kick_wd &&
448 di->chg_info.online_chg & AC_CHG)
449 return di->ac_chg->ops.kick_wd(di->ac_chg);
450 else if (di->usb_chg && di->usb_chg->ops.kick_wd &&
451 di->chg_info.online_chg & USB_CHG)
452 return di->usb_chg->ops.kick_wd(di->usb_chg);
453
454 return -ENXIO;
455}
456
457/**
458 * abx500_chargalg_ac_en() - Turn on/off the AC charger
459 * @di: pointer to the abx500_chargalg structure
460 * @enable: charger on/off
461 * @vset: requested charger output voltage
462 * @iset: requested charger output current
463 *
464 * The AC charger will be turned on/off with the requested charge voltage and
465 * current
466 */
467static int abx500_chargalg_ac_en(struct abx500_chargalg *di, int enable,
468 int vset, int iset)
469{
470 if (!di->ac_chg || !di->ac_chg->ops.enable)
471 return -ENXIO;
472
473 /* Select maximum of what both the charger and the battery supports */
474 if (di->ac_chg->max_out_volt)
475 vset = min(vset, di->ac_chg->max_out_volt);
476 if (di->ac_chg->max_out_curr)
477 iset = min(iset, di->ac_chg->max_out_curr);
478
479 di->chg_info.ac_iset = iset;
480 di->chg_info.ac_vset = vset;
481
482 return di->ac_chg->ops.enable(di->ac_chg, enable, vset, iset);
483}
484
485/**
486 * abx500_chargalg_usb_en() - Turn on/off the USB charger
487 * @di: pointer to the abx500_chargalg structure
488 * @enable: charger on/off
489 * @vset: requested charger output voltage
490 * @iset: requested charger output current
491 *
492 * The USB charger will be turned on/off with the requested charge voltage and
493 * current
494 */
495static int abx500_chargalg_usb_en(struct abx500_chargalg *di, int enable,
496 int vset, int iset)
497{
498 if (!di->usb_chg || !di->usb_chg->ops.enable)
499 return -ENXIO;
500
501 /* Select maximum of what both the charger and the battery supports */
502 if (di->usb_chg->max_out_volt)
503 vset = min(vset, di->usb_chg->max_out_volt);
504 if (di->usb_chg->max_out_curr)
505 iset = min(iset, di->usb_chg->max_out_curr);
506
507 di->chg_info.usb_iset = iset;
508 di->chg_info.usb_vset = vset;
509
510 return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset);
511}
512
513/**
514 * abx500_chargalg_update_chg_curr() - Update charger current
515 * @di: pointer to the abx500_chargalg structure
516 * @iset: requested charger output current
517 *
518 * The charger output current will be updated for the charger
519 * that is currently in use
520 */
521static int abx500_chargalg_update_chg_curr(struct abx500_chargalg *di,
522 int iset)
523{
524 /* Check if charger exists and update current if charging */
525 if (di->ac_chg && di->ac_chg->ops.update_curr &&
526 di->chg_info.charger_type & AC_CHG) {
527 /*
528 * Select maximum of what both the charger
529 * and the battery supports
530 */
531 if (di->ac_chg->max_out_curr)
532 iset = min(iset, di->ac_chg->max_out_curr);
533
534 di->chg_info.ac_iset = iset;
535
536 return di->ac_chg->ops.update_curr(di->ac_chg, iset);
537 } else if (di->usb_chg && di->usb_chg->ops.update_curr &&
538 di->chg_info.charger_type & USB_CHG) {
539 /*
540 * Select maximum of what both the charger
541 * and the battery supports
542 */
543 if (di->usb_chg->max_out_curr)
544 iset = min(iset, di->usb_chg->max_out_curr);
545
546 di->chg_info.usb_iset = iset;
547
548 return di->usb_chg->ops.update_curr(di->usb_chg, iset);
549 }
550
551 return -ENXIO;
552}
553
554/**
555 * abx500_chargalg_stop_charging() - Stop charging
556 * @di: pointer to the abx500_chargalg structure
557 *
558 * This function is called from any state where charging should be stopped.
559 * All charging is disabled and all status parameters and timers are changed
560 * accordingly
561 */
562static void abx500_chargalg_stop_charging(struct abx500_chargalg *di)
563{
564 abx500_chargalg_ac_en(di, false, 0, 0);
565 abx500_chargalg_usb_en(di, false, 0, 0);
566 abx500_chargalg_stop_safety_timer(di);
567 abx500_chargalg_stop_maintenance_timer(di);
568 di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
569 di->maintenance_chg = false;
570 cancel_delayed_work(&di->chargalg_wd_work);
571 power_supply_changed(&di->chargalg_psy);
572}
573
574/**
575 * abx500_chargalg_hold_charging() - Pauses charging
576 * @di: pointer to the abx500_chargalg structure
577 *
578 * This function is called in the case where maintenance charging has been
579 * disabled and instead a battery voltage mode is entered to check when the
580 * battery voltage has reached a certain recharge voltage
581 */
582static void abx500_chargalg_hold_charging(struct abx500_chargalg *di)
583{
584 abx500_chargalg_ac_en(di, false, 0, 0);
585 abx500_chargalg_usb_en(di, false, 0, 0);
586 abx500_chargalg_stop_safety_timer(di);
587 abx500_chargalg_stop_maintenance_timer(di);
588 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
589 di->maintenance_chg = false;
590 cancel_delayed_work(&di->chargalg_wd_work);
591 power_supply_changed(&di->chargalg_psy);
592}
593
594/**
595 * abx500_chargalg_start_charging() - Start the charger
596 * @di: pointer to the abx500_chargalg structure
597 * @vset: requested charger output voltage
598 * @iset: requested charger output current
599 *
600 * A charger will be enabled depending on the requested charger type that was
601 * detected previously.
602 */
603static void abx500_chargalg_start_charging(struct abx500_chargalg *di,
604 int vset, int iset)
605{
606 switch (di->chg_info.charger_type) {
607 case AC_CHG:
608 dev_dbg(di->dev,
609 "AC parameters: Vset %d, Ich %d\n", vset, iset);
610 abx500_chargalg_usb_en(di, false, 0, 0);
611 abx500_chargalg_ac_en(di, true, vset, iset);
612 break;
613
614 case USB_CHG:
615 dev_dbg(di->dev,
616 "USB parameters: Vset %d, Ich %d\n", vset, iset);
617 abx500_chargalg_ac_en(di, false, 0, 0);
618 abx500_chargalg_usb_en(di, true, vset, iset);
619 break;
620
621 default:
622 dev_err(di->dev, "Unknown charger to charge from\n");
623 break;
624 }
625}
626
627/**
628 * abx500_chargalg_check_temp() - Check battery temperature ranges
629 * @di: pointer to the abx500_chargalg structure
630 *
631 * The battery temperature is checked against the predefined limits and the
632 * charge state is changed accordingly
633 */
634static void abx500_chargalg_check_temp(struct abx500_chargalg *di)
635{
Lee Jonesb0284de2012-11-30 10:09:42 +0000636 if (di->batt_data.temp > (di->bm->temp_low + di->t_hyst_norm) &&
637 di->batt_data.temp < (di->bm->temp_high - di->t_hyst_norm)) {
Arun Murthy1668f812012-02-29 21:54:25 +0530638 /* Temp OK! */
639 di->events.btemp_underover = false;
640 di->events.btemp_lowhigh = false;
641 di->t_hyst_norm = 0;
642 di->t_hyst_lowhigh = 0;
643 } else {
Lee Jonesb0284de2012-11-30 10:09:42 +0000644 if (((di->batt_data.temp >= di->bm->temp_high) &&
Arun Murthy1668f812012-02-29 21:54:25 +0530645 (di->batt_data.temp <
Lee Jonesb0284de2012-11-30 10:09:42 +0000646 (di->bm->temp_over - di->t_hyst_lowhigh))) ||
Arun Murthy1668f812012-02-29 21:54:25 +0530647 ((di->batt_data.temp >
Lee Jonesb0284de2012-11-30 10:09:42 +0000648 (di->bm->temp_under + di->t_hyst_lowhigh)) &&
649 (di->batt_data.temp <= di->bm->temp_low))) {
Arun Murthy1668f812012-02-29 21:54:25 +0530650 /* TEMP minor!!!!! */
651 di->events.btemp_underover = false;
652 di->events.btemp_lowhigh = true;
Lee Jonesb0284de2012-11-30 10:09:42 +0000653 di->t_hyst_norm = di->bm->temp_hysteresis;
Arun Murthy1668f812012-02-29 21:54:25 +0530654 di->t_hyst_lowhigh = 0;
Lee Jonesb0284de2012-11-30 10:09:42 +0000655 } else if (di->batt_data.temp <= di->bm->temp_under ||
656 di->batt_data.temp >= di->bm->temp_over) {
Arun Murthy1668f812012-02-29 21:54:25 +0530657 /* TEMP major!!!!! */
658 di->events.btemp_underover = true;
659 di->events.btemp_lowhigh = false;
660 di->t_hyst_norm = 0;
Lee Jonesb0284de2012-11-30 10:09:42 +0000661 di->t_hyst_lowhigh = di->bm->temp_hysteresis;
Arun Murthy1668f812012-02-29 21:54:25 +0530662 } else {
663 /* Within hysteresis */
664 dev_dbg(di->dev, "Within hysteresis limit temp: %d "
665 "hyst_lowhigh %d, hyst normal %d\n",
666 di->batt_data.temp, di->t_hyst_lowhigh,
667 di->t_hyst_norm);
668 }
669 }
670}
671
672/**
673 * abx500_chargalg_check_charger_voltage() - Check charger voltage
674 * @di: pointer to the abx500_chargalg structure
675 *
676 * Charger voltage is checked against maximum limit
677 */
678static void abx500_chargalg_check_charger_voltage(struct abx500_chargalg *di)
679{
Lee Jonesb0284de2012-11-30 10:09:42 +0000680 if (di->chg_info.usb_volt > di->bm->chg_params->usb_volt_max)
Arun Murthy1668f812012-02-29 21:54:25 +0530681 di->chg_info.usb_chg_ok = false;
682 else
683 di->chg_info.usb_chg_ok = true;
684
Lee Jonesb0284de2012-11-30 10:09:42 +0000685 if (di->chg_info.ac_volt > di->bm->chg_params->ac_volt_max)
Arun Murthy1668f812012-02-29 21:54:25 +0530686 di->chg_info.ac_chg_ok = false;
687 else
688 di->chg_info.ac_chg_ok = true;
689
690}
691
692/**
693 * abx500_chargalg_end_of_charge() - Check if end-of-charge criteria is fulfilled
694 * @di: pointer to the abx500_chargalg structure
695 *
696 * End-of-charge criteria is fulfilled when the battery voltage is above a
697 * certain limit and the battery current is below a certain limit for a
698 * predefined number of consecutive seconds. If true, the battery is full
699 */
700static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di)
701{
702 if (di->charge_status == POWER_SUPPLY_STATUS_CHARGING &&
703 di->charge_state == STATE_NORMAL &&
704 !di->maintenance_chg && (di->batt_data.volt >=
Lee Jonesb0284de2012-11-30 10:09:42 +0000705 di->bm->bat_type[di->bm->batt_id].termination_vol ||
Arun Murthy1668f812012-02-29 21:54:25 +0530706 di->events.usb_cv_active || di->events.ac_cv_active) &&
707 di->batt_data.avg_curr <
Lee Jonesb0284de2012-11-30 10:09:42 +0000708 di->bm->bat_type[di->bm->batt_id].termination_curr &&
Arun Murthy1668f812012-02-29 21:54:25 +0530709 di->batt_data.avg_curr > 0) {
710 if (++di->eoc_cnt >= EOC_COND_CNT) {
711 di->eoc_cnt = 0;
712 di->charge_status = POWER_SUPPLY_STATUS_FULL;
713 di->maintenance_chg = true;
714 dev_dbg(di->dev, "EOC reached!\n");
715 power_supply_changed(&di->chargalg_psy);
716 } else {
717 dev_dbg(di->dev,
718 " EOC limit reached for the %d"
719 " time, out of %d before EOC\n",
720 di->eoc_cnt,
721 EOC_COND_CNT);
722 }
723 } else {
724 di->eoc_cnt = 0;
725 }
726}
727
728static void init_maxim_chg_curr(struct abx500_chargalg *di)
729{
730 di->ccm.original_iset =
Lee Jonesb0284de2012-11-30 10:09:42 +0000731 di->bm->bat_type[di->bm->batt_id].normal_cur_lvl;
Arun Murthy1668f812012-02-29 21:54:25 +0530732 di->ccm.current_iset =
Lee Jonesb0284de2012-11-30 10:09:42 +0000733 di->bm->bat_type[di->bm->batt_id].normal_cur_lvl;
734 di->ccm.test_delta_i = di->bm->maxi->charger_curr_step;
735 di->ccm.max_current = di->bm->maxi->chg_curr;
736 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
Arun Murthy1668f812012-02-29 21:54:25 +0530737 di->ccm.level = 0;
738}
739
740/**
741 * abx500_chargalg_chg_curr_maxim - increases the charger current to
742 * compensate for the system load
743 * @di pointer to the abx500_chargalg structure
744 *
745 * This maximization function is used to raise the charger current to get the
746 * battery current as close to the optimal value as possible. The battery
747 * current during charging is affected by the system load
748 */
749static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
750{
751 int delta_i;
752
Lee Jonesb0284de2012-11-30 10:09:42 +0000753 if (!di->bm->maxi->ena_maxi)
Arun Murthy1668f812012-02-29 21:54:25 +0530754 return MAXIM_RET_NOACTION;
755
756 delta_i = di->ccm.original_iset - di->batt_data.inst_curr;
757
758 if (di->events.vbus_collapsed) {
759 dev_dbg(di->dev, "Charger voltage has collapsed %d\n",
760 di->ccm.wait_cnt);
761 if (di->ccm.wait_cnt == 0) {
762 dev_dbg(di->dev, "lowering current\n");
763 di->ccm.wait_cnt++;
Lee Jonesb0284de2012-11-30 10:09:42 +0000764 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
Arun Murthy1668f812012-02-29 21:54:25 +0530765 di->ccm.max_current =
766 di->ccm.current_iset - di->ccm.test_delta_i;
767 di->ccm.current_iset = di->ccm.max_current;
768 di->ccm.level--;
769 return MAXIM_RET_CHANGE;
770 } else {
771 dev_dbg(di->dev, "waiting\n");
772 /* Let's go in here twice before lowering curr again */
773 di->ccm.wait_cnt = (di->ccm.wait_cnt + 1) % 3;
774 return MAXIM_RET_NOACTION;
775 }
776 }
777
778 di->ccm.wait_cnt = 0;
779
780 if ((di->batt_data.inst_curr > di->ccm.original_iset)) {
781 dev_dbg(di->dev, " Maximization Ibat (%dmA) too high"
782 " (limit %dmA) (current iset: %dmA)!\n",
783 di->batt_data.inst_curr, di->ccm.original_iset,
784 di->ccm.current_iset);
785
786 if (di->ccm.current_iset == di->ccm.original_iset)
787 return MAXIM_RET_NOACTION;
788
Lee Jonesb0284de2012-11-30 10:09:42 +0000789 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
Arun Murthy1668f812012-02-29 21:54:25 +0530790 di->ccm.current_iset = di->ccm.original_iset;
791 di->ccm.level = 0;
792
793 return MAXIM_RET_IBAT_TOO_HIGH;
794 }
795
796 if (delta_i > di->ccm.test_delta_i &&
797 (di->ccm.current_iset + di->ccm.test_delta_i) <
798 di->ccm.max_current) {
799 if (di->ccm.condition_cnt-- == 0) {
800 /* Increse the iset with cco.test_delta_i */
Lee Jonesb0284de2012-11-30 10:09:42 +0000801 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
Arun Murthy1668f812012-02-29 21:54:25 +0530802 di->ccm.current_iset += di->ccm.test_delta_i;
803 di->ccm.level++;
804 dev_dbg(di->dev, " Maximization needed, increase"
805 " with %d mA to %dmA (Optimal ibat: %d)"
806 " Level %d\n",
807 di->ccm.test_delta_i,
808 di->ccm.current_iset,
809 di->ccm.original_iset,
810 di->ccm.level);
811 return MAXIM_RET_CHANGE;
812 } else {
813 return MAXIM_RET_NOACTION;
814 }
815 } else {
Lee Jonesb0284de2012-11-30 10:09:42 +0000816 di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
Arun Murthy1668f812012-02-29 21:54:25 +0530817 return MAXIM_RET_NOACTION;
818 }
819}
820
821static void handle_maxim_chg_curr(struct abx500_chargalg *di)
822{
823 enum maxim_ret ret;
824 int result;
825
826 ret = abx500_chargalg_chg_curr_maxim(di);
827 switch (ret) {
828 case MAXIM_RET_CHANGE:
829 result = abx500_chargalg_update_chg_curr(di,
830 di->ccm.current_iset);
831 if (result)
832 dev_err(di->dev, "failed to set chg curr\n");
833 break;
834 case MAXIM_RET_IBAT_TOO_HIGH:
835 result = abx500_chargalg_update_chg_curr(di,
Lee Jonesb0284de2012-11-30 10:09:42 +0000836 di->bm->bat_type[di->bm->batt_id].normal_cur_lvl);
Arun Murthy1668f812012-02-29 21:54:25 +0530837 if (result)
838 dev_err(di->dev, "failed to set chg curr\n");
839 break;
840
841 case MAXIM_RET_NOACTION:
842 default:
843 /* Do nothing..*/
844 break;
845 }
846}
847
848static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data)
849{
850 struct power_supply *psy;
851 struct power_supply *ext;
852 struct abx500_chargalg *di;
853 union power_supply_propval ret;
854 int i, j;
855 bool psy_found = false;
Marcus Cooperea402402013-01-11 13:12:54 +0000856 bool capacity_updated = false;
Arun Murthy1668f812012-02-29 21:54:25 +0530857
858 psy = (struct power_supply *)data;
859 ext = dev_get_drvdata(dev);
860 di = to_abx500_chargalg_device_info(psy);
861 /* For all psy where the driver name appears in any supplied_to */
862 for (i = 0; i < ext->num_supplicants; i++) {
863 if (!strcmp(ext->supplied_to[i], psy->name))
864 psy_found = true;
865 }
866 if (!psy_found)
867 return 0;
868
Marcus Cooperea402402013-01-11 13:12:54 +0000869 /*
870 * If external is not registering 'POWER_SUPPLY_PROP_CAPACITY' to its
871 * property because of handling that sysfs entry on its own, this is
872 * the place to get the battery capacity.
873 */
874 if (!ext->get_property(ext, POWER_SUPPLY_PROP_CAPACITY, &ret)) {
875 di->batt_data.percent = ret.intval;
876 capacity_updated = true;
877 }
878
Arun Murthy1668f812012-02-29 21:54:25 +0530879 /* Go through all properties for the psy */
880 for (j = 0; j < ext->num_properties; j++) {
881 enum power_supply_property prop;
882 prop = ext->properties[j];
883
884 /* Initialize chargers if not already done */
885 if (!di->ac_chg &&
886 ext->type == POWER_SUPPLY_TYPE_MAINS)
887 di->ac_chg = psy_to_ux500_charger(ext);
888 else if (!di->usb_chg &&
889 ext->type == POWER_SUPPLY_TYPE_USB)
890 di->usb_chg = psy_to_ux500_charger(ext);
891
892 if (ext->get_property(ext, prop, &ret))
893 continue;
894 switch (prop) {
895 case POWER_SUPPLY_PROP_PRESENT:
896 switch (ext->type) {
897 case POWER_SUPPLY_TYPE_BATTERY:
898 /* Battery present */
899 if (ret.intval)
900 di->events.batt_rem = false;
901 /* Battery removed */
902 else
903 di->events.batt_rem = true;
904 break;
905 case POWER_SUPPLY_TYPE_MAINS:
906 /* AC disconnected */
907 if (!ret.intval &&
908 (di->chg_info.conn_chg & AC_CHG)) {
909 di->chg_info.prev_conn_chg =
910 di->chg_info.conn_chg;
911 di->chg_info.conn_chg &= ~AC_CHG;
912 }
913 /* AC connected */
914 else if (ret.intval &&
915 !(di->chg_info.conn_chg & AC_CHG)) {
916 di->chg_info.prev_conn_chg =
917 di->chg_info.conn_chg;
918 di->chg_info.conn_chg |= AC_CHG;
919 }
920 break;
921 case POWER_SUPPLY_TYPE_USB:
922 /* USB disconnected */
923 if (!ret.intval &&
924 (di->chg_info.conn_chg & USB_CHG)) {
925 di->chg_info.prev_conn_chg =
926 di->chg_info.conn_chg;
927 di->chg_info.conn_chg &= ~USB_CHG;
928 }
929 /* USB connected */
930 else if (ret.intval &&
931 !(di->chg_info.conn_chg & USB_CHG)) {
932 di->chg_info.prev_conn_chg =
933 di->chg_info.conn_chg;
934 di->chg_info.conn_chg |= USB_CHG;
935 }
936 break;
937 default:
938 break;
939 }
940 break;
941
942 case POWER_SUPPLY_PROP_ONLINE:
943 switch (ext->type) {
944 case POWER_SUPPLY_TYPE_BATTERY:
945 break;
946 case POWER_SUPPLY_TYPE_MAINS:
947 /* AC offline */
948 if (!ret.intval &&
949 (di->chg_info.online_chg & AC_CHG)) {
950 di->chg_info.prev_online_chg =
951 di->chg_info.online_chg;
952 di->chg_info.online_chg &= ~AC_CHG;
953 }
954 /* AC online */
955 else if (ret.intval &&
956 !(di->chg_info.online_chg & AC_CHG)) {
957 di->chg_info.prev_online_chg =
958 di->chg_info.online_chg;
959 di->chg_info.online_chg |= AC_CHG;
960 queue_delayed_work(di->chargalg_wq,
961 &di->chargalg_wd_work, 0);
962 }
963 break;
964 case POWER_SUPPLY_TYPE_USB:
965 /* USB offline */
966 if (!ret.intval &&
967 (di->chg_info.online_chg & USB_CHG)) {
968 di->chg_info.prev_online_chg =
969 di->chg_info.online_chg;
970 di->chg_info.online_chg &= ~USB_CHG;
971 }
972 /* USB online */
973 else if (ret.intval &&
974 !(di->chg_info.online_chg & USB_CHG)) {
975 di->chg_info.prev_online_chg =
976 di->chg_info.online_chg;
977 di->chg_info.online_chg |= USB_CHG;
978 queue_delayed_work(di->chargalg_wq,
979 &di->chargalg_wd_work, 0);
980 }
981 break;
982 default:
983 break;
984 }
985 break;
986
987 case POWER_SUPPLY_PROP_HEALTH:
988 switch (ext->type) {
989 case POWER_SUPPLY_TYPE_BATTERY:
990 break;
991 case POWER_SUPPLY_TYPE_MAINS:
992 switch (ret.intval) {
993 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
994 di->events.mainextchnotok = true;
995 di->events.main_thermal_prot = false;
996 di->events.main_ovv = false;
997 di->events.ac_wd_expired = false;
998 break;
999 case POWER_SUPPLY_HEALTH_DEAD:
1000 di->events.ac_wd_expired = true;
1001 di->events.mainextchnotok = false;
1002 di->events.main_ovv = false;
1003 di->events.main_thermal_prot = false;
1004 break;
1005 case POWER_SUPPLY_HEALTH_COLD:
1006 case POWER_SUPPLY_HEALTH_OVERHEAT:
1007 di->events.main_thermal_prot = true;
1008 di->events.mainextchnotok = false;
1009 di->events.main_ovv = false;
1010 di->events.ac_wd_expired = false;
1011 break;
1012 case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
1013 di->events.main_ovv = true;
1014 di->events.mainextchnotok = false;
1015 di->events.main_thermal_prot = false;
1016 di->events.ac_wd_expired = false;
1017 break;
1018 case POWER_SUPPLY_HEALTH_GOOD:
1019 di->events.main_thermal_prot = false;
1020 di->events.mainextchnotok = false;
1021 di->events.main_ovv = false;
1022 di->events.ac_wd_expired = false;
1023 break;
1024 default:
1025 break;
1026 }
1027 break;
1028
1029 case POWER_SUPPLY_TYPE_USB:
1030 switch (ret.intval) {
1031 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
1032 di->events.usbchargernotok = true;
1033 di->events.usb_thermal_prot = false;
1034 di->events.vbus_ovv = false;
1035 di->events.usb_wd_expired = false;
1036 break;
1037 case POWER_SUPPLY_HEALTH_DEAD:
1038 di->events.usb_wd_expired = true;
1039 di->events.usbchargernotok = false;
1040 di->events.usb_thermal_prot = false;
1041 di->events.vbus_ovv = false;
1042 break;
1043 case POWER_SUPPLY_HEALTH_COLD:
1044 case POWER_SUPPLY_HEALTH_OVERHEAT:
1045 di->events.usb_thermal_prot = true;
1046 di->events.usbchargernotok = false;
1047 di->events.vbus_ovv = false;
1048 di->events.usb_wd_expired = false;
1049 break;
1050 case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
1051 di->events.vbus_ovv = true;
1052 di->events.usbchargernotok = false;
1053 di->events.usb_thermal_prot = false;
1054 di->events.usb_wd_expired = false;
1055 break;
1056 case POWER_SUPPLY_HEALTH_GOOD:
1057 di->events.usbchargernotok = false;
1058 di->events.usb_thermal_prot = false;
1059 di->events.vbus_ovv = false;
1060 di->events.usb_wd_expired = false;
1061 break;
1062 default:
1063 break;
1064 }
1065 default:
1066 break;
1067 }
1068 break;
1069
1070 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1071 switch (ext->type) {
1072 case POWER_SUPPLY_TYPE_BATTERY:
1073 di->batt_data.volt = ret.intval / 1000;
1074 break;
1075 case POWER_SUPPLY_TYPE_MAINS:
1076 di->chg_info.ac_volt = ret.intval / 1000;
1077 break;
1078 case POWER_SUPPLY_TYPE_USB:
1079 di->chg_info.usb_volt = ret.intval / 1000;
1080 break;
1081 default:
1082 break;
1083 }
1084 break;
1085
1086 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
1087 switch (ext->type) {
1088 case POWER_SUPPLY_TYPE_MAINS:
1089 /* AVG is used to indicate when we are
1090 * in CV mode */
1091 if (ret.intval)
1092 di->events.ac_cv_active = true;
1093 else
1094 di->events.ac_cv_active = false;
1095
1096 break;
1097 case POWER_SUPPLY_TYPE_USB:
1098 /* AVG is used to indicate when we are
1099 * in CV mode */
1100 if (ret.intval)
1101 di->events.usb_cv_active = true;
1102 else
1103 di->events.usb_cv_active = false;
1104
1105 break;
1106 default:
1107 break;
1108 }
1109 break;
1110
1111 case POWER_SUPPLY_PROP_TECHNOLOGY:
1112 switch (ext->type) {
1113 case POWER_SUPPLY_TYPE_BATTERY:
1114 if (ret.intval)
1115 di->events.batt_unknown = false;
1116 else
1117 di->events.batt_unknown = true;
1118
1119 break;
1120 default:
1121 break;
1122 }
1123 break;
1124
1125 case POWER_SUPPLY_PROP_TEMP:
1126 di->batt_data.temp = ret.intval / 10;
1127 break;
1128
1129 case POWER_SUPPLY_PROP_CURRENT_NOW:
1130 switch (ext->type) {
1131 case POWER_SUPPLY_TYPE_MAINS:
1132 di->chg_info.ac_curr =
1133 ret.intval / 1000;
1134 break;
1135 case POWER_SUPPLY_TYPE_USB:
1136 di->chg_info.usb_curr =
1137 ret.intval / 1000;
1138 break;
1139 case POWER_SUPPLY_TYPE_BATTERY:
1140 di->batt_data.inst_curr = ret.intval / 1000;
1141 break;
1142 default:
1143 break;
1144 }
1145 break;
1146
1147 case POWER_SUPPLY_PROP_CURRENT_AVG:
1148 switch (ext->type) {
1149 case POWER_SUPPLY_TYPE_BATTERY:
1150 di->batt_data.avg_curr = ret.intval / 1000;
1151 break;
1152 case POWER_SUPPLY_TYPE_USB:
1153 if (ret.intval)
1154 di->events.vbus_collapsed = true;
1155 else
1156 di->events.vbus_collapsed = false;
1157 break;
1158 default:
1159 break;
1160 }
1161 break;
1162 case POWER_SUPPLY_PROP_CAPACITY:
Marcus Cooperea402402013-01-11 13:12:54 +00001163 if (!capacity_updated)
1164 di->batt_data.percent = ret.intval;
Arun Murthy1668f812012-02-29 21:54:25 +05301165 break;
1166 default:
1167 break;
1168 }
1169 }
1170 return 0;
1171}
1172
1173/**
1174 * abx500_chargalg_external_power_changed() - callback for power supply changes
1175 * @psy: pointer to the structure power_supply
1176 *
1177 * This function is the entry point of the pointer external_power_changed
1178 * of the structure power_supply.
1179 * This function gets executed when there is a change in any external power
1180 * supply that this driver needs to be notified of.
1181 */
1182static void abx500_chargalg_external_power_changed(struct power_supply *psy)
1183{
1184 struct abx500_chargalg *di = to_abx500_chargalg_device_info(psy);
1185
1186 /*
1187 * Trigger execution of the algorithm instantly and read
1188 * all power_supply properties there instead
1189 */
1190 queue_work(di->chargalg_wq, &di->chargalg_work);
1191}
1192
1193/**
1194 * abx500_chargalg_algorithm() - Main function for the algorithm
1195 * @di: pointer to the abx500_chargalg structure
1196 *
1197 * This is the main control function for the charging algorithm.
1198 * It is called periodically or when something happens that will
1199 * trigger a state change
1200 */
1201static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
1202{
1203 int charger_status;
1204
1205 /* Collect data from all power_supply class devices */
1206 class_for_each_device(power_supply_class, NULL,
1207 &di->chargalg_psy, abx500_chargalg_get_ext_psy_data);
1208
1209 abx500_chargalg_end_of_charge(di);
1210 abx500_chargalg_check_temp(di);
1211 abx500_chargalg_check_charger_voltage(di);
1212
1213 charger_status = abx500_chargalg_check_charger_connection(di);
1214 /*
1215 * First check if we have a charger connected.
1216 * Also we don't allow charging of unknown batteries if configured
1217 * this way
1218 */
1219 if (!charger_status ||
Lee Jonesb0284de2012-11-30 10:09:42 +00001220 (di->events.batt_unknown && !di->bm->chg_unknown_bat)) {
Arun Murthy1668f812012-02-29 21:54:25 +05301221 if (di->charge_state != STATE_HANDHELD) {
1222 di->events.safety_timer_expired = false;
1223 abx500_chargalg_state_to(di, STATE_HANDHELD_INIT);
1224 }
1225 }
1226
1227 /* If suspended, we should not continue checking the flags */
1228 else if (di->charge_state == STATE_SUSPENDED_INIT ||
1229 di->charge_state == STATE_SUSPENDED) {
1230 /* We don't do anything here, just don,t continue */
1231 }
1232
1233 /* Safety timer expiration */
1234 else if (di->events.safety_timer_expired) {
1235 if (di->charge_state != STATE_SAFETY_TIMER_EXPIRED)
1236 abx500_chargalg_state_to(di,
1237 STATE_SAFETY_TIMER_EXPIRED_INIT);
1238 }
1239 /*
1240 * Check if any interrupts has occured
1241 * that will prevent us from charging
1242 */
1243
1244 /* Battery removed */
1245 else if (di->events.batt_rem) {
1246 if (di->charge_state != STATE_BATT_REMOVED)
1247 abx500_chargalg_state_to(di, STATE_BATT_REMOVED_INIT);
1248 }
1249 /* Main or USB charger not ok. */
1250 else if (di->events.mainextchnotok || di->events.usbchargernotok) {
1251 /*
1252 * If vbus_collapsed is set, we have to lower the charger
1253 * current, which is done in the normal state below
1254 */
1255 if (di->charge_state != STATE_CHG_NOT_OK &&
1256 !di->events.vbus_collapsed)
1257 abx500_chargalg_state_to(di, STATE_CHG_NOT_OK_INIT);
1258 }
1259 /* VBUS, Main or VBAT OVV. */
1260 else if (di->events.vbus_ovv ||
1261 di->events.main_ovv ||
1262 di->events.batt_ovv ||
1263 !di->chg_info.usb_chg_ok ||
1264 !di->chg_info.ac_chg_ok) {
1265 if (di->charge_state != STATE_OVV_PROTECT)
1266 abx500_chargalg_state_to(di, STATE_OVV_PROTECT_INIT);
1267 }
1268 /* USB Thermal, stop charging */
1269 else if (di->events.main_thermal_prot ||
1270 di->events.usb_thermal_prot) {
1271 if (di->charge_state != STATE_HW_TEMP_PROTECT)
1272 abx500_chargalg_state_to(di,
1273 STATE_HW_TEMP_PROTECT_INIT);
1274 }
1275 /* Battery temp over/under */
1276 else if (di->events.btemp_underover) {
1277 if (di->charge_state != STATE_TEMP_UNDEROVER)
1278 abx500_chargalg_state_to(di,
1279 STATE_TEMP_UNDEROVER_INIT);
1280 }
1281 /* Watchdog expired */
1282 else if (di->events.ac_wd_expired ||
1283 di->events.usb_wd_expired) {
1284 if (di->charge_state != STATE_WD_EXPIRED)
1285 abx500_chargalg_state_to(di, STATE_WD_EXPIRED_INIT);
1286 }
1287 /* Battery temp high/low */
1288 else if (di->events.btemp_lowhigh) {
1289 if (di->charge_state != STATE_TEMP_LOWHIGH)
1290 abx500_chargalg_state_to(di, STATE_TEMP_LOWHIGH_INIT);
1291 }
1292
1293 dev_dbg(di->dev,
1294 "[CHARGALG] Vb %d Ib_avg %d Ib_inst %d Tb %d Cap %d Maint %d "
1295 "State %s Active_chg %d Chg_status %d AC %d USB %d "
1296 "AC_online %d USB_online %d AC_CV %d USB_CV %d AC_I %d "
1297 "USB_I %d AC_Vset %d AC_Iset %d USB_Vset %d USB_Iset %d\n",
1298 di->batt_data.volt,
1299 di->batt_data.avg_curr,
1300 di->batt_data.inst_curr,
1301 di->batt_data.temp,
1302 di->batt_data.percent,
1303 di->maintenance_chg,
1304 states[di->charge_state],
1305 di->chg_info.charger_type,
1306 di->charge_status,
1307 di->chg_info.conn_chg & AC_CHG,
1308 di->chg_info.conn_chg & USB_CHG,
1309 di->chg_info.online_chg & AC_CHG,
1310 di->chg_info.online_chg & USB_CHG,
1311 di->events.ac_cv_active,
1312 di->events.usb_cv_active,
1313 di->chg_info.ac_curr,
1314 di->chg_info.usb_curr,
1315 di->chg_info.ac_vset,
1316 di->chg_info.ac_iset,
1317 di->chg_info.usb_vset,
1318 di->chg_info.usb_iset);
1319
1320 switch (di->charge_state) {
1321 case STATE_HANDHELD_INIT:
1322 abx500_chargalg_stop_charging(di);
1323 di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
1324 abx500_chargalg_state_to(di, STATE_HANDHELD);
1325 /* Intentional fallthrough */
1326
1327 case STATE_HANDHELD:
1328 break;
1329
1330 case STATE_SUSPENDED_INIT:
1331 if (di->susp_status.ac_suspended)
1332 abx500_chargalg_ac_en(di, false, 0, 0);
1333 if (di->susp_status.usb_suspended)
1334 abx500_chargalg_usb_en(di, false, 0, 0);
1335 abx500_chargalg_stop_safety_timer(di);
1336 abx500_chargalg_stop_maintenance_timer(di);
1337 di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1338 di->maintenance_chg = false;
1339 abx500_chargalg_state_to(di, STATE_SUSPENDED);
1340 power_supply_changed(&di->chargalg_psy);
1341 /* Intentional fallthrough */
1342
1343 case STATE_SUSPENDED:
1344 /* CHARGING is suspended */
1345 break;
1346
1347 case STATE_BATT_REMOVED_INIT:
1348 abx500_chargalg_stop_charging(di);
1349 abx500_chargalg_state_to(di, STATE_BATT_REMOVED);
1350 /* Intentional fallthrough */
1351
1352 case STATE_BATT_REMOVED:
1353 if (!di->events.batt_rem)
1354 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1355 break;
1356
1357 case STATE_HW_TEMP_PROTECT_INIT:
1358 abx500_chargalg_stop_charging(di);
1359 abx500_chargalg_state_to(di, STATE_HW_TEMP_PROTECT);
1360 /* Intentional fallthrough */
1361
1362 case STATE_HW_TEMP_PROTECT:
1363 if (!di->events.main_thermal_prot &&
1364 !di->events.usb_thermal_prot)
1365 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1366 break;
1367
1368 case STATE_OVV_PROTECT_INIT:
1369 abx500_chargalg_stop_charging(di);
1370 abx500_chargalg_state_to(di, STATE_OVV_PROTECT);
1371 /* Intentional fallthrough */
1372
1373 case STATE_OVV_PROTECT:
1374 if (!di->events.vbus_ovv &&
1375 !di->events.main_ovv &&
1376 !di->events.batt_ovv &&
1377 di->chg_info.usb_chg_ok &&
1378 di->chg_info.ac_chg_ok)
1379 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1380 break;
1381
1382 case STATE_CHG_NOT_OK_INIT:
1383 abx500_chargalg_stop_charging(di);
1384 abx500_chargalg_state_to(di, STATE_CHG_NOT_OK);
1385 /* Intentional fallthrough */
1386
1387 case STATE_CHG_NOT_OK:
1388 if (!di->events.mainextchnotok &&
1389 !di->events.usbchargernotok)
1390 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1391 break;
1392
1393 case STATE_SAFETY_TIMER_EXPIRED_INIT:
1394 abx500_chargalg_stop_charging(di);
1395 abx500_chargalg_state_to(di, STATE_SAFETY_TIMER_EXPIRED);
1396 /* Intentional fallthrough */
1397
1398 case STATE_SAFETY_TIMER_EXPIRED:
1399 /* We exit this state when charger is removed */
1400 break;
1401
1402 case STATE_NORMAL_INIT:
1403 abx500_chargalg_start_charging(di,
Lee Jonesb0284de2012-11-30 10:09:42 +00001404 di->bm->bat_type[di->bm->batt_id].normal_vol_lvl,
1405 di->bm->bat_type[di->bm->batt_id].normal_cur_lvl);
Arun Murthy1668f812012-02-29 21:54:25 +05301406 abx500_chargalg_state_to(di, STATE_NORMAL);
1407 abx500_chargalg_start_safety_timer(di);
1408 abx500_chargalg_stop_maintenance_timer(di);
1409 init_maxim_chg_curr(di);
1410 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
1411 di->eoc_cnt = 0;
1412 di->maintenance_chg = false;
1413 power_supply_changed(&di->chargalg_psy);
1414
1415 break;
1416
1417 case STATE_NORMAL:
1418 handle_maxim_chg_curr(di);
1419 if (di->charge_status == POWER_SUPPLY_STATUS_FULL &&
1420 di->maintenance_chg) {
Lee Jonesb0284de2012-11-30 10:09:42 +00001421 if (di->bm->no_maintenance)
Arun Murthy1668f812012-02-29 21:54:25 +05301422 abx500_chargalg_state_to(di,
1423 STATE_WAIT_FOR_RECHARGE_INIT);
1424 else
1425 abx500_chargalg_state_to(di,
1426 STATE_MAINTENANCE_A_INIT);
1427 }
1428 break;
1429
1430 /* This state will be used when the maintenance state is disabled */
1431 case STATE_WAIT_FOR_RECHARGE_INIT:
1432 abx500_chargalg_hold_charging(di);
1433 abx500_chargalg_state_to(di, STATE_WAIT_FOR_RECHARGE);
Arun Murthy1668f812012-02-29 21:54:25 +05301434 /* Intentional fallthrough */
1435
1436 case STATE_WAIT_FOR_RECHARGE:
Marcus Cooperea402402013-01-11 13:12:54 +00001437 if (di->batt_data.percent <=
1438 di->bm->bat_type[di->bm->batt_id].
1439 recharge_cap)
1440 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
Arun Murthy1668f812012-02-29 21:54:25 +05301441 break;
1442
1443 case STATE_MAINTENANCE_A_INIT:
1444 abx500_chargalg_stop_safety_timer(di);
1445 abx500_chargalg_start_maintenance_timer(di,
Lee Jonesb0284de2012-11-30 10:09:42 +00001446 di->bm->bat_type[
1447 di->bm->batt_id].maint_a_chg_timer_h);
Arun Murthy1668f812012-02-29 21:54:25 +05301448 abx500_chargalg_start_charging(di,
Lee Jonesb0284de2012-11-30 10:09:42 +00001449 di->bm->bat_type[
1450 di->bm->batt_id].maint_a_vol_lvl,
1451 di->bm->bat_type[
1452 di->bm->batt_id].maint_a_cur_lvl);
Arun Murthy1668f812012-02-29 21:54:25 +05301453 abx500_chargalg_state_to(di, STATE_MAINTENANCE_A);
1454 power_supply_changed(&di->chargalg_psy);
1455 /* Intentional fallthrough*/
1456
1457 case STATE_MAINTENANCE_A:
1458 if (di->events.maintenance_timer_expired) {
1459 abx500_chargalg_stop_maintenance_timer(di);
1460 abx500_chargalg_state_to(di, STATE_MAINTENANCE_B_INIT);
1461 }
1462 break;
1463
1464 case STATE_MAINTENANCE_B_INIT:
1465 abx500_chargalg_start_maintenance_timer(di,
Lee Jonesb0284de2012-11-30 10:09:42 +00001466 di->bm->bat_type[
1467 di->bm->batt_id].maint_b_chg_timer_h);
Arun Murthy1668f812012-02-29 21:54:25 +05301468 abx500_chargalg_start_charging(di,
Lee Jonesb0284de2012-11-30 10:09:42 +00001469 di->bm->bat_type[
1470 di->bm->batt_id].maint_b_vol_lvl,
1471 di->bm->bat_type[
1472 di->bm->batt_id].maint_b_cur_lvl);
Arun Murthy1668f812012-02-29 21:54:25 +05301473 abx500_chargalg_state_to(di, STATE_MAINTENANCE_B);
1474 power_supply_changed(&di->chargalg_psy);
1475 /* Intentional fallthrough*/
1476
1477 case STATE_MAINTENANCE_B:
1478 if (di->events.maintenance_timer_expired) {
1479 abx500_chargalg_stop_maintenance_timer(di);
1480 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1481 }
1482 break;
1483
1484 case STATE_TEMP_LOWHIGH_INIT:
1485 abx500_chargalg_start_charging(di,
Lee Jonesb0284de2012-11-30 10:09:42 +00001486 di->bm->bat_type[
1487 di->bm->batt_id].low_high_vol_lvl,
1488 di->bm->bat_type[
1489 di->bm->batt_id].low_high_cur_lvl);
Arun Murthy1668f812012-02-29 21:54:25 +05301490 abx500_chargalg_stop_maintenance_timer(di);
1491 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
1492 abx500_chargalg_state_to(di, STATE_TEMP_LOWHIGH);
1493 power_supply_changed(&di->chargalg_psy);
1494 /* Intentional fallthrough */
1495
1496 case STATE_TEMP_LOWHIGH:
1497 if (!di->events.btemp_lowhigh)
1498 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1499 break;
1500
1501 case STATE_WD_EXPIRED_INIT:
1502 abx500_chargalg_stop_charging(di);
1503 abx500_chargalg_state_to(di, STATE_WD_EXPIRED);
1504 /* Intentional fallthrough */
1505
1506 case STATE_WD_EXPIRED:
1507 if (!di->events.ac_wd_expired &&
1508 !di->events.usb_wd_expired)
1509 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1510 break;
1511
1512 case STATE_TEMP_UNDEROVER_INIT:
1513 abx500_chargalg_stop_charging(di);
1514 abx500_chargalg_state_to(di, STATE_TEMP_UNDEROVER);
1515 /* Intentional fallthrough */
1516
1517 case STATE_TEMP_UNDEROVER:
1518 if (!di->events.btemp_underover)
1519 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1520 break;
1521 }
1522
1523 /* Start charging directly if the new state is a charge state */
1524 if (di->charge_state == STATE_NORMAL_INIT ||
1525 di->charge_state == STATE_MAINTENANCE_A_INIT ||
1526 di->charge_state == STATE_MAINTENANCE_B_INIT)
1527 queue_work(di->chargalg_wq, &di->chargalg_work);
1528}
1529
1530/**
1531 * abx500_chargalg_periodic_work() - Periodic work for the algorithm
1532 * @work: pointer to the work_struct structure
1533 *
1534 * Work queue function for the charging algorithm
1535 */
1536static void abx500_chargalg_periodic_work(struct work_struct *work)
1537{
1538 struct abx500_chargalg *di = container_of(work,
1539 struct abx500_chargalg, chargalg_periodic_work.work);
1540
1541 abx500_chargalg_algorithm(di);
1542
1543 /*
1544 * If a charger is connected then the battery has to be monitored
1545 * frequently, else the work can be delayed.
1546 */
1547 if (di->chg_info.conn_chg)
1548 queue_delayed_work(di->chargalg_wq,
1549 &di->chargalg_periodic_work,
Lee Jonesb0284de2012-11-30 10:09:42 +00001550 di->bm->interval_charging * HZ);
Arun Murthy1668f812012-02-29 21:54:25 +05301551 else
1552 queue_delayed_work(di->chargalg_wq,
1553 &di->chargalg_periodic_work,
Lee Jonesb0284de2012-11-30 10:09:42 +00001554 di->bm->interval_not_charging * HZ);
Arun Murthy1668f812012-02-29 21:54:25 +05301555}
1556
1557/**
1558 * abx500_chargalg_wd_work() - periodic work to kick the charger watchdog
1559 * @work: pointer to the work_struct structure
1560 *
1561 * Work queue function for kicking the charger watchdog
1562 */
1563static void abx500_chargalg_wd_work(struct work_struct *work)
1564{
1565 int ret;
1566 struct abx500_chargalg *di = container_of(work,
1567 struct abx500_chargalg, chargalg_wd_work.work);
1568
1569 dev_dbg(di->dev, "abx500_chargalg_wd_work\n");
1570
1571 ret = abx500_chargalg_kick_watchdog(di);
1572 if (ret < 0)
1573 dev_err(di->dev, "failed to kick watchdog\n");
1574
1575 queue_delayed_work(di->chargalg_wq,
1576 &di->chargalg_wd_work, CHG_WD_INTERVAL);
1577}
1578
1579/**
1580 * abx500_chargalg_work() - Work to run the charging algorithm instantly
1581 * @work: pointer to the work_struct structure
1582 *
1583 * Work queue function for calling the charging algorithm
1584 */
1585static void abx500_chargalg_work(struct work_struct *work)
1586{
1587 struct abx500_chargalg *di = container_of(work,
1588 struct abx500_chargalg, chargalg_work);
1589
1590 abx500_chargalg_algorithm(di);
1591}
1592
1593/**
1594 * abx500_chargalg_get_property() - get the chargalg properties
1595 * @psy: pointer to the power_supply structure
1596 * @psp: pointer to the power_supply_property structure
1597 * @val: pointer to the power_supply_propval union
1598 *
1599 * This function gets called when an application tries to get the
1600 * chargalg properties by reading the sysfs files.
1601 * status: charging/discharging/full/unknown
1602 * health: health of the battery
1603 * Returns error code in case of failure else 0 on success
1604 */
1605static int abx500_chargalg_get_property(struct power_supply *psy,
1606 enum power_supply_property psp,
1607 union power_supply_propval *val)
1608{
1609 struct abx500_chargalg *di;
1610
1611 di = to_abx500_chargalg_device_info(psy);
1612
1613 switch (psp) {
1614 case POWER_SUPPLY_PROP_STATUS:
1615 val->intval = di->charge_status;
1616 break;
1617 case POWER_SUPPLY_PROP_HEALTH:
1618 if (di->events.batt_ovv) {
1619 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1620 } else if (di->events.btemp_underover) {
Lee Jonesb0284de2012-11-30 10:09:42 +00001621 if (di->batt_data.temp <= di->bm->temp_under)
Arun Murthy1668f812012-02-29 21:54:25 +05301622 val->intval = POWER_SUPPLY_HEALTH_COLD;
1623 else
1624 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
1625 } else {
1626 val->intval = POWER_SUPPLY_HEALTH_GOOD;
1627 }
1628 break;
1629 default:
1630 return -EINVAL;
1631 }
1632 return 0;
1633}
1634
1635/* Exposure to the sysfs interface */
1636
1637/**
1638 * abx500_chargalg_sysfs_charger() - sysfs store operations
1639 * @kobj: pointer to the struct kobject
1640 * @attr: pointer to the struct attribute
1641 * @buf: buffer that holds the parameter passed from userspace
1642 * @length: length of the parameter passed
1643 *
1644 * Returns length of the buffer(input taken from user space) on success
1645 * else error code on failure
1646 * The operation to be performed on passing the parameters from the user space.
1647 */
1648static ssize_t abx500_chargalg_sysfs_charger(struct kobject *kobj,
1649 struct attribute *attr, const char *buf, size_t length)
1650{
1651 struct abx500_chargalg *di = container_of(kobj,
1652 struct abx500_chargalg, chargalg_kobject);
1653 long int param;
1654 int ac_usb;
1655 int ret;
1656 char entry = *attr->name;
1657
1658 switch (entry) {
1659 case 'c':
1660 ret = strict_strtol(buf, 10, &param);
1661 if (ret < 0)
1662 return ret;
1663
1664 ac_usb = param;
1665 switch (ac_usb) {
1666 case 0:
1667 /* Disable charging */
1668 di->susp_status.ac_suspended = true;
1669 di->susp_status.usb_suspended = true;
1670 di->susp_status.suspended_change = true;
1671 /* Trigger a state change */
1672 queue_work(di->chargalg_wq,
1673 &di->chargalg_work);
1674 break;
1675 case 1:
1676 /* Enable AC Charging */
1677 di->susp_status.ac_suspended = false;
1678 di->susp_status.suspended_change = true;
1679 /* Trigger a state change */
1680 queue_work(di->chargalg_wq,
1681 &di->chargalg_work);
1682 break;
1683 case 2:
1684 /* Enable USB charging */
1685 di->susp_status.usb_suspended = false;
1686 di->susp_status.suspended_change = true;
1687 /* Trigger a state change */
1688 queue_work(di->chargalg_wq,
1689 &di->chargalg_work);
1690 break;
1691 default:
1692 dev_info(di->dev, "Wrong input\n"
1693 "Enter 0. Disable AC/USB Charging\n"
1694 "1. Enable AC charging\n"
1695 "2. Enable USB Charging\n");
1696 };
1697 break;
1698 };
1699 return strlen(buf);
1700}
1701
1702static struct attribute abx500_chargalg_en_charger = \
1703{
1704 .name = "chargalg",
1705 .mode = S_IWUGO,
1706};
1707
1708static struct attribute *abx500_chargalg_chg[] = {
1709 &abx500_chargalg_en_charger,
1710 NULL
1711};
1712
Anton Vorontsov64eb9b02012-03-14 04:43:11 +04001713static const struct sysfs_ops abx500_chargalg_sysfs_ops = {
Arun Murthy1668f812012-02-29 21:54:25 +05301714 .store = abx500_chargalg_sysfs_charger,
1715};
1716
1717static struct kobj_type abx500_chargalg_ktype = {
1718 .sysfs_ops = &abx500_chargalg_sysfs_ops,
1719 .default_attrs = abx500_chargalg_chg,
1720};
1721
1722/**
1723 * abx500_chargalg_sysfs_exit() - de-init of sysfs entry
1724 * @di: pointer to the struct abx500_chargalg
1725 *
1726 * This function removes the entry in sysfs.
1727 */
1728static void abx500_chargalg_sysfs_exit(struct abx500_chargalg *di)
1729{
1730 kobject_del(&di->chargalg_kobject);
1731}
1732
1733/**
1734 * abx500_chargalg_sysfs_init() - init of sysfs entry
1735 * @di: pointer to the struct abx500_chargalg
1736 *
1737 * This function adds an entry in sysfs.
1738 * Returns error code in case of failure else 0(on success)
1739 */
1740static int abx500_chargalg_sysfs_init(struct abx500_chargalg *di)
1741{
1742 int ret = 0;
1743
1744 ret = kobject_init_and_add(&di->chargalg_kobject,
1745 &abx500_chargalg_ktype,
1746 NULL, "abx500_chargalg");
1747 if (ret < 0)
1748 dev_err(di->dev, "failed to create sysfs entry\n");
1749
1750 return ret;
1751}
1752/* Exposure to the sysfs interface <<END>> */
1753
1754#if defined(CONFIG_PM)
1755static int abx500_chargalg_resume(struct platform_device *pdev)
1756{
1757 struct abx500_chargalg *di = platform_get_drvdata(pdev);
1758
1759 /* Kick charger watchdog if charging (any charger online) */
1760 if (di->chg_info.online_chg)
1761 queue_delayed_work(di->chargalg_wq, &di->chargalg_wd_work, 0);
1762
1763 /*
1764 * Run the charging algorithm directly to be sure we don't
1765 * do it too seldom
1766 */
1767 queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
1768
1769 return 0;
1770}
1771
1772static int abx500_chargalg_suspend(struct platform_device *pdev,
1773 pm_message_t state)
1774{
1775 struct abx500_chargalg *di = platform_get_drvdata(pdev);
1776
1777 if (di->chg_info.online_chg)
1778 cancel_delayed_work_sync(&di->chargalg_wd_work);
1779
1780 cancel_delayed_work_sync(&di->chargalg_periodic_work);
1781
1782 return 0;
1783}
1784#else
1785#define abx500_chargalg_suspend NULL
1786#define abx500_chargalg_resume NULL
1787#endif
1788
Bill Pemberton415ec692012-11-19 13:26:07 -05001789static int abx500_chargalg_remove(struct platform_device *pdev)
Arun Murthy1668f812012-02-29 21:54:25 +05301790{
1791 struct abx500_chargalg *di = platform_get_drvdata(pdev);
1792
1793 /* sysfs interface to enable/disbale charging from user space */
1794 abx500_chargalg_sysfs_exit(di);
1795
1796 /* Delete the work queue */
1797 destroy_workqueue(di->chargalg_wq);
1798
1799 flush_scheduled_work();
1800 power_supply_unregister(&di->chargalg_psy);
1801 platform_set_drvdata(pdev, NULL);
Arun Murthy1668f812012-02-29 21:54:25 +05301802
1803 return 0;
1804}
1805
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001806static char *supply_interface[] = {
1807 "ab8500_fg",
1808};
1809
Bill Pembertonc8afa642012-11-19 13:22:23 -05001810static int abx500_chargalg_probe(struct platform_device *pdev)
Arun Murthy1668f812012-02-29 21:54:25 +05301811{
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001812 struct device_node *np = pdev->dev.of_node;
Lee Jonesbdc56b42012-11-30 10:57:14 +00001813 struct abx500_bm_data *plat = pdev->dev.platform_data;
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001814 struct abx500_chargalg *di;
Arun Murthy1668f812012-02-29 21:54:25 +05301815 int ret = 0;
1816
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001817 di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
1818 if (!di) {
1819 dev_err(&pdev->dev, "%s no mem for ab8500_chargalg\n", __func__);
Arun Murthy1668f812012-02-29 21:54:25 +05301820 return -ENOMEM;
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001821 }
Lee Jonesbdc56b42012-11-30 10:57:14 +00001822
1823 if (!plat) {
1824 dev_err(&pdev->dev, "no battery management data supplied\n");
1825 return -EINVAL;
1826 }
1827 di->bm = plat;
1828
1829 if (np) {
1830 ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm);
1831 if (ret) {
1832 dev_err(&pdev->dev, "failed to get battery information\n");
1833 return ret;
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001834 }
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001835 }
Arun Murthy1668f812012-02-29 21:54:25 +05301836
1837 /* get device struct */
1838 di->dev = &pdev->dev;
Arun Murthy1668f812012-02-29 21:54:25 +05301839
1840 /* chargalg supply */
1841 di->chargalg_psy.name = "abx500_chargalg";
1842 di->chargalg_psy.type = POWER_SUPPLY_TYPE_BATTERY;
1843 di->chargalg_psy.properties = abx500_chargalg_props;
1844 di->chargalg_psy.num_properties = ARRAY_SIZE(abx500_chargalg_props);
1845 di->chargalg_psy.get_property = abx500_chargalg_get_property;
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001846 di->chargalg_psy.supplied_to = supply_interface;
1847 di->chargalg_psy.num_supplicants = ARRAY_SIZE(supply_interface),
Arun Murthy1668f812012-02-29 21:54:25 +05301848 di->chargalg_psy.external_power_changed =
1849 abx500_chargalg_external_power_changed;
1850
1851 /* Initilialize safety timer */
1852 init_timer(&di->safety_timer);
1853 di->safety_timer.function = abx500_chargalg_safety_timer_expired;
1854 di->safety_timer.data = (unsigned long) di;
1855
1856 /* Initilialize maintenance timer */
1857 init_timer(&di->maintenance_timer);
1858 di->maintenance_timer.function =
1859 abx500_chargalg_maintenance_timer_expired;
1860 di->maintenance_timer.data = (unsigned long) di;
1861
1862 /* Create a work queue for the chargalg */
1863 di->chargalg_wq =
1864 create_singlethread_workqueue("abx500_chargalg_wq");
1865 if (di->chargalg_wq == NULL) {
1866 dev_err(di->dev, "failed to create work queue\n");
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001867 return -ENOMEM;
Arun Murthy1668f812012-02-29 21:54:25 +05301868 }
1869
1870 /* Init work for chargalg */
Tejun Heo203b42f2012-08-21 13:18:23 -07001871 INIT_DEFERRABLE_WORK(&di->chargalg_periodic_work,
Arun Murthy1668f812012-02-29 21:54:25 +05301872 abx500_chargalg_periodic_work);
Tejun Heo203b42f2012-08-21 13:18:23 -07001873 INIT_DEFERRABLE_WORK(&di->chargalg_wd_work,
Arun Murthy1668f812012-02-29 21:54:25 +05301874 abx500_chargalg_wd_work);
1875
1876 /* Init work for chargalg */
1877 INIT_WORK(&di->chargalg_work, abx500_chargalg_work);
1878
1879 /* To detect charger at startup */
1880 di->chg_info.prev_conn_chg = -1;
1881
1882 /* Register chargalg power supply class */
1883 ret = power_supply_register(di->dev, &di->chargalg_psy);
1884 if (ret) {
1885 dev_err(di->dev, "failed to register chargalg psy\n");
1886 goto free_chargalg_wq;
1887 }
1888
1889 platform_set_drvdata(pdev, di);
1890
1891 /* sysfs interface to enable/disable charging from user space */
1892 ret = abx500_chargalg_sysfs_init(di);
1893 if (ret) {
1894 dev_err(di->dev, "failed to create sysfs entry\n");
1895 goto free_psy;
1896 }
1897
1898 /* Run the charging algorithm */
1899 queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0);
1900
1901 dev_info(di->dev, "probe success\n");
1902 return ret;
1903
1904free_psy:
1905 power_supply_unregister(&di->chargalg_psy);
1906free_chargalg_wq:
1907 destroy_workqueue(di->chargalg_wq);
Arun Murthy1668f812012-02-29 21:54:25 +05301908 return ret;
1909}
1910
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001911static const struct of_device_id ab8500_chargalg_match[] = {
1912 { .compatible = "stericsson,ab8500-chargalg", },
1913 { },
1914};
1915
Arun Murthy1668f812012-02-29 21:54:25 +05301916static struct platform_driver abx500_chargalg_driver = {
1917 .probe = abx500_chargalg_probe,
Bill Pemberton28ea73f2012-11-19 13:20:40 -05001918 .remove = abx500_chargalg_remove,
Arun Murthy1668f812012-02-29 21:54:25 +05301919 .suspend = abx500_chargalg_suspend,
1920 .resume = abx500_chargalg_resume,
1921 .driver = {
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001922 .name = "ab8500-chargalg",
Arun Murthy1668f812012-02-29 21:54:25 +05301923 .owner = THIS_MODULE,
Rajanikanth H.Va12810a2012-10-31 15:40:33 +00001924 .of_match_table = ab8500_chargalg_match,
Arun Murthy1668f812012-02-29 21:54:25 +05301925 },
1926};
1927
1928static int __init abx500_chargalg_init(void)
1929{
1930 return platform_driver_register(&abx500_chargalg_driver);
1931}
1932
1933static void __exit abx500_chargalg_exit(void)
1934{
1935 platform_driver_unregister(&abx500_chargalg_driver);
1936}
1937
1938module_init(abx500_chargalg_init);
1939module_exit(abx500_chargalg_exit);
1940
1941MODULE_LICENSE("GPL v2");
1942MODULE_AUTHOR("Johan Palsson, Karl Komierowski");
1943MODULE_ALIAS("platform:abx500-chargalg");
1944MODULE_DESCRIPTION("abx500 battery charging algorithm");