2 * Copyright (C) ST-Ericsson SA 2012
4 * Charging algorithm driver for abx500 variants
6 * License Terms: GNU General Public License v2
8 * Johan Palsson <johan.palsson@stericsson.com>
9 * Karl Komierowski <karl.komierowski@stericsson.com>
10 * Arun R Murthy <arun.murthy@stericsson.com>
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>
25 #include <linux/mfd/core.h>
26 #include <linux/mfd/abx500.h>
27 #include <linux/mfd/abx500/ux500_chargalg.h>
28 #include <linux/mfd/abx500/ab8500-bm.h>
30 /* Watchdog kick interval */
31 #define CHG_WD_INTERVAL (6 * HZ)
33 /* End-of-charge criteria counter */
34 #define EOC_COND_CNT 10
36 /* Recharge criteria counter */
37 #define RCH_COND_CNT 3
39 #define to_abx500_chargalg_device_info(x) container_of((x), \
40 struct abx500_chargalg, chargalg_psy);
42 enum abx500_chargers
{
48 struct abx500_chargalg_charger_info
{
49 enum abx500_chargers conn_chg
;
50 enum abx500_chargers prev_conn_chg
;
51 enum abx500_chargers online_chg
;
52 enum abx500_chargers prev_online_chg
;
53 enum abx500_chargers charger_type
;
66 struct abx500_chargalg_suspension_status
{
67 bool suspended_change
;
72 struct abx500_chargalg_battery_data
{
80 enum abx500_chargalg_states
{
83 STATE_CHG_NOT_OK_INIT
,
85 STATE_HW_TEMP_PROTECT_INIT
,
86 STATE_HW_TEMP_PROTECT
,
89 STATE_WAIT_FOR_RECHARGE_INIT
,
90 STATE_WAIT_FOR_RECHARGE
,
91 STATE_MAINTENANCE_A_INIT
,
93 STATE_MAINTENANCE_B_INIT
,
95 STATE_TEMP_UNDEROVER_INIT
,
97 STATE_TEMP_LOWHIGH_INIT
,
101 STATE_OVV_PROTECT_INIT
,
103 STATE_SAFETY_TIMER_EXPIRED_INIT
,
104 STATE_SAFETY_TIMER_EXPIRED
,
105 STATE_BATT_REMOVED_INIT
,
107 STATE_WD_EXPIRED_INIT
,
111 static const char *states
[] = {
116 "HW_TEMP_PROTECT_INIT",
120 "WAIT_FOR_RECHARGE_INIT",
122 "MAINTENANCE_A_INIT",
124 "MAINTENANCE_B_INIT",
126 "TEMP_UNDEROVER_INIT",
134 "SAFETY_TIMER_EXPIRED_INIT",
135 "SAFETY_TIMER_EXPIRED",
142 struct abx500_chargalg_events
{
147 bool btemp_underover
;
149 bool main_thermal_prot
;
150 bool usb_thermal_prot
;
153 bool usbchargernotok
;
154 bool safety_timer_expired
;
155 bool maintenance_timer_expired
;
164 * struct abx500_charge_curr_maximization - Charger maximization parameters
165 * @original_iset: the non optimized/maximised charger current
166 * @current_iset: the charging current used at this moment
167 * @test_delta_i: the delta between the current we want to charge and the
168 current that is really going into the battery
169 * @condition_cnt: number of iterations needed before a new charger current
171 * @max_current: maximum charger current
172 * @wait_cnt: to avoid too fast current step down in case of charger
173 * voltage collapse, we insert this delay between step
175 * @level: tells in how many steps the charging current has been
178 struct abx500_charge_curr_maximization
{
191 MAXIM_RET_IBAT_TOO_HIGH
,
195 * struct abx500_chargalg - abx500 Charging algorithm device information
196 * @dev: pointer to the structure device
197 * @charge_status: battery operating status
198 * @eoc_cnt: counter used to determine end-of_charge
199 * @rch_cnt: counter used to determine start of recharge
200 * @maintenance_chg: indicate if maintenance charge is active
201 * @t_hyst_norm temperature hysteresis when the temperature has been
202 * over or under normal limits
203 * @t_hyst_lowhigh temperature hysteresis when the temperature has been
204 * over or under the high or low limits
205 * @charge_state: current state of the charging algorithm
206 * @ccm charging current maximization parameters
207 * @chg_info: information about connected charger types
208 * @batt_data: data of the battery
209 * @susp_status: current charger suspension status
210 * @bat: pointer to the abx500_bm platform data
211 * @chargalg_psy: structure that holds the battery properties exposed by
212 * the charging algorithm
213 * @events: structure for information about events triggered
214 * @chargalg_wq: work queue for running the charging algorithm
215 * @chargalg_periodic_work: work to run the charging algorithm periodically
216 * @chargalg_wd_work: work to kick the charger watchdog periodically
217 * @chargalg_work: work to run the charging algorithm instantly
218 * @safety_timer: charging safety timer
219 * @maintenance_timer: maintenance charging timer
220 * @chargalg_kobject: structure of type kobject
222 struct abx500_chargalg
{
227 bool maintenance_chg
;
230 enum abx500_chargalg_states charge_state
;
231 struct abx500_charge_curr_maximization ccm
;
232 struct abx500_chargalg_charger_info chg_info
;
233 struct abx500_chargalg_battery_data batt_data
;
234 struct abx500_chargalg_suspension_status susp_status
;
235 struct abx500_bm_data
*bat
;
236 struct power_supply chargalg_psy
;
237 struct ux500_charger
*ac_chg
;
238 struct ux500_charger
*usb_chg
;
239 struct abx500_chargalg_events events
;
240 struct workqueue_struct
*chargalg_wq
;
241 struct delayed_work chargalg_periodic_work
;
242 struct delayed_work chargalg_wd_work
;
243 struct work_struct chargalg_work
;
244 struct timer_list safety_timer
;
245 struct timer_list maintenance_timer
;
246 struct kobject chargalg_kobject
;
249 /* Main battery properties */
250 static enum power_supply_property abx500_chargalg_props
[] = {
251 POWER_SUPPLY_PROP_STATUS
,
252 POWER_SUPPLY_PROP_HEALTH
,
256 * abx500_chargalg_safety_timer_expired() - Expiration of the safety timer
257 * @data: pointer to the abx500_chargalg structure
259 * This function gets called when the safety timer for the charger
262 static void abx500_chargalg_safety_timer_expired(unsigned long data
)
264 struct abx500_chargalg
*di
= (struct abx500_chargalg
*) data
;
265 dev_err(di
->dev
, "Safety timer expired\n");
266 di
->events
.safety_timer_expired
= true;
268 /* Trigger execution of the algorithm instantly */
269 queue_work(di
->chargalg_wq
, &di
->chargalg_work
);
273 * abx500_chargalg_maintenance_timer_expired() - Expiration of
274 * the maintenance timer
275 * @i: pointer to the abx500_chargalg structure
277 * This function gets called when the maintenence timer
280 static void abx500_chargalg_maintenance_timer_expired(unsigned long data
)
283 struct abx500_chargalg
*di
= (struct abx500_chargalg
*) data
;
284 dev_dbg(di
->dev
, "Maintenance timer expired\n");
285 di
->events
.maintenance_timer_expired
= true;
287 /* Trigger execution of the algorithm instantly */
288 queue_work(di
->chargalg_wq
, &di
->chargalg_work
);
292 * abx500_chargalg_state_to() - Change charge state
293 * @di: pointer to the abx500_chargalg structure
295 * This function gets called when a charge state change should occur
297 static void abx500_chargalg_state_to(struct abx500_chargalg
*di
,
298 enum abx500_chargalg_states state
)
301 "State changed: %s (From state: [%d] %s =to=> [%d] %s )\n",
302 di
->charge_state
== state
? "NO" : "YES",
304 states
[di
->charge_state
],
308 di
->charge_state
= state
;
312 * abx500_chargalg_check_charger_connection() - Check charger connection change
313 * @di: pointer to the abx500_chargalg structure
315 * This function will check if there is a change in the charger connection
316 * and change charge state accordingly. AC has precedence over USB.
318 static int abx500_chargalg_check_charger_connection(struct abx500_chargalg
*di
)
320 if (di
->chg_info
.conn_chg
!= di
->chg_info
.prev_conn_chg
||
321 di
->susp_status
.suspended_change
) {
323 * Charger state changed or suspension
324 * has changed since last update
326 if ((di
->chg_info
.conn_chg
& AC_CHG
) &&
327 !di
->susp_status
.ac_suspended
) {
328 dev_dbg(di
->dev
, "Charging source is AC\n");
329 if (di
->chg_info
.charger_type
!= AC_CHG
) {
330 di
->chg_info
.charger_type
= AC_CHG
;
331 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
333 } else if ((di
->chg_info
.conn_chg
& USB_CHG
) &&
334 !di
->susp_status
.usb_suspended
) {
335 dev_dbg(di
->dev
, "Charging source is USB\n");
336 di
->chg_info
.charger_type
= USB_CHG
;
337 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
338 } else if (di
->chg_info
.conn_chg
&&
339 (di
->susp_status
.ac_suspended
||
340 di
->susp_status
.usb_suspended
)) {
341 dev_dbg(di
->dev
, "Charging is suspended\n");
342 di
->chg_info
.charger_type
= NO_CHG
;
343 abx500_chargalg_state_to(di
, STATE_SUSPENDED_INIT
);
345 dev_dbg(di
->dev
, "Charging source is OFF\n");
346 di
->chg_info
.charger_type
= NO_CHG
;
347 abx500_chargalg_state_to(di
, STATE_HANDHELD_INIT
);
349 di
->chg_info
.prev_conn_chg
= di
->chg_info
.conn_chg
;
350 di
->susp_status
.suspended_change
= false;
352 return di
->chg_info
.conn_chg
;
356 * abx500_chargalg_start_safety_timer() - Start charging safety timer
357 * @di: pointer to the abx500_chargalg structure
359 * The safety timer is used to avoid overcharging of old or bad batteries.
360 * There are different timers for AC and USB
362 static void abx500_chargalg_start_safety_timer(struct abx500_chargalg
*di
)
364 unsigned long timer_expiration
= 0;
366 switch (di
->chg_info
.charger_type
) {
369 round_jiffies(jiffies
+
370 (di
->bat
->main_safety_tmr_h
* 3600 * HZ
));
375 round_jiffies(jiffies
+
376 (di
->bat
->usb_safety_tmr_h
* 3600 * HZ
));
380 dev_err(di
->dev
, "Unknown charger to charge from\n");
384 di
->events
.safety_timer_expired
= false;
385 di
->safety_timer
.expires
= timer_expiration
;
386 if (!timer_pending(&di
->safety_timer
))
387 add_timer(&di
->safety_timer
);
389 mod_timer(&di
->safety_timer
, timer_expiration
);
393 * abx500_chargalg_stop_safety_timer() - Stop charging safety timer
394 * @di: pointer to the abx500_chargalg structure
396 * The safety timer is stopped whenever the NORMAL state is exited
398 static void abx500_chargalg_stop_safety_timer(struct abx500_chargalg
*di
)
400 di
->events
.safety_timer_expired
= false;
401 del_timer(&di
->safety_timer
);
405 * abx500_chargalg_start_maintenance_timer() - Start charging maintenance timer
406 * @di: pointer to the abx500_chargalg structure
407 * @duration: duration of ther maintenance timer in hours
409 * The maintenance timer is used to maintain the charge in the battery once
410 * the battery is considered full. These timers are chosen to match the
411 * discharge curve of the battery
413 static void abx500_chargalg_start_maintenance_timer(struct abx500_chargalg
*di
,
416 unsigned long timer_expiration
;
418 /* Convert from hours to jiffies */
419 timer_expiration
= round_jiffies(jiffies
+ (duration
* 3600 * HZ
));
421 di
->events
.maintenance_timer_expired
= false;
422 di
->maintenance_timer
.expires
= timer_expiration
;
423 if (!timer_pending(&di
->maintenance_timer
))
424 add_timer(&di
->maintenance_timer
);
426 mod_timer(&di
->maintenance_timer
, timer_expiration
);
430 * abx500_chargalg_stop_maintenance_timer() - Stop maintenance timer
431 * @di: pointer to the abx500_chargalg structure
433 * The maintenance timer is stopped whenever maintenance ends or when another
436 static void abx500_chargalg_stop_maintenance_timer(struct abx500_chargalg
*di
)
438 di
->events
.maintenance_timer_expired
= false;
439 del_timer(&di
->maintenance_timer
);
443 * abx500_chargalg_kick_watchdog() - Kick charger watchdog
444 * @di: pointer to the abx500_chargalg structure
446 * The charger watchdog have to be kicked periodically whenever the charger is
447 * on, else the ABB will reset the system
449 static int abx500_chargalg_kick_watchdog(struct abx500_chargalg
*di
)
451 /* Check if charger exists and kick watchdog if charging */
452 if (di
->ac_chg
&& di
->ac_chg
->ops
.kick_wd
&&
453 di
->chg_info
.online_chg
& AC_CHG
)
454 return di
->ac_chg
->ops
.kick_wd(di
->ac_chg
);
455 else if (di
->usb_chg
&& di
->usb_chg
->ops
.kick_wd
&&
456 di
->chg_info
.online_chg
& USB_CHG
)
457 return di
->usb_chg
->ops
.kick_wd(di
->usb_chg
);
463 * abx500_chargalg_ac_en() - Turn on/off the AC charger
464 * @di: pointer to the abx500_chargalg structure
465 * @enable: charger on/off
466 * @vset: requested charger output voltage
467 * @iset: requested charger output current
469 * The AC charger will be turned on/off with the requested charge voltage and
472 static int abx500_chargalg_ac_en(struct abx500_chargalg
*di
, int enable
,
475 if (!di
->ac_chg
|| !di
->ac_chg
->ops
.enable
)
478 /* Select maximum of what both the charger and the battery supports */
479 if (di
->ac_chg
->max_out_volt
)
480 vset
= min(vset
, di
->ac_chg
->max_out_volt
);
481 if (di
->ac_chg
->max_out_curr
)
482 iset
= min(iset
, di
->ac_chg
->max_out_curr
);
484 di
->chg_info
.ac_iset
= iset
;
485 di
->chg_info
.ac_vset
= vset
;
487 return di
->ac_chg
->ops
.enable(di
->ac_chg
, enable
, vset
, iset
);
491 * abx500_chargalg_usb_en() - Turn on/off the USB charger
492 * @di: pointer to the abx500_chargalg structure
493 * @enable: charger on/off
494 * @vset: requested charger output voltage
495 * @iset: requested charger output current
497 * The USB charger will be turned on/off with the requested charge voltage and
500 static int abx500_chargalg_usb_en(struct abx500_chargalg
*di
, int enable
,
503 if (!di
->usb_chg
|| !di
->usb_chg
->ops
.enable
)
506 /* Select maximum of what both the charger and the battery supports */
507 if (di
->usb_chg
->max_out_volt
)
508 vset
= min(vset
, di
->usb_chg
->max_out_volt
);
509 if (di
->usb_chg
->max_out_curr
)
510 iset
= min(iset
, di
->usb_chg
->max_out_curr
);
512 di
->chg_info
.usb_iset
= iset
;
513 di
->chg_info
.usb_vset
= vset
;
515 return di
->usb_chg
->ops
.enable(di
->usb_chg
, enable
, vset
, iset
);
519 * abx500_chargalg_update_chg_curr() - Update charger current
520 * @di: pointer to the abx500_chargalg structure
521 * @iset: requested charger output current
523 * The charger output current will be updated for the charger
524 * that is currently in use
526 static int abx500_chargalg_update_chg_curr(struct abx500_chargalg
*di
,
529 /* Check if charger exists and update current if charging */
530 if (di
->ac_chg
&& di
->ac_chg
->ops
.update_curr
&&
531 di
->chg_info
.charger_type
& AC_CHG
) {
533 * Select maximum of what both the charger
534 * and the battery supports
536 if (di
->ac_chg
->max_out_curr
)
537 iset
= min(iset
, di
->ac_chg
->max_out_curr
);
539 di
->chg_info
.ac_iset
= iset
;
541 return di
->ac_chg
->ops
.update_curr(di
->ac_chg
, iset
);
542 } else if (di
->usb_chg
&& di
->usb_chg
->ops
.update_curr
&&
543 di
->chg_info
.charger_type
& USB_CHG
) {
545 * Select maximum of what both the charger
546 * and the battery supports
548 if (di
->usb_chg
->max_out_curr
)
549 iset
= min(iset
, di
->usb_chg
->max_out_curr
);
551 di
->chg_info
.usb_iset
= iset
;
553 return di
->usb_chg
->ops
.update_curr(di
->usb_chg
, iset
);
560 * abx500_chargalg_stop_charging() - Stop charging
561 * @di: pointer to the abx500_chargalg structure
563 * This function is called from any state where charging should be stopped.
564 * All charging is disabled and all status parameters and timers are changed
567 static void abx500_chargalg_stop_charging(struct abx500_chargalg
*di
)
569 abx500_chargalg_ac_en(di
, false, 0, 0);
570 abx500_chargalg_usb_en(di
, false, 0, 0);
571 abx500_chargalg_stop_safety_timer(di
);
572 abx500_chargalg_stop_maintenance_timer(di
);
573 di
->charge_status
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
574 di
->maintenance_chg
= false;
575 cancel_delayed_work(&di
->chargalg_wd_work
);
576 power_supply_changed(&di
->chargalg_psy
);
580 * abx500_chargalg_hold_charging() - Pauses charging
581 * @di: pointer to the abx500_chargalg structure
583 * This function is called in the case where maintenance charging has been
584 * disabled and instead a battery voltage mode is entered to check when the
585 * battery voltage has reached a certain recharge voltage
587 static void abx500_chargalg_hold_charging(struct abx500_chargalg
*di
)
589 abx500_chargalg_ac_en(di
, false, 0, 0);
590 abx500_chargalg_usb_en(di
, false, 0, 0);
591 abx500_chargalg_stop_safety_timer(di
);
592 abx500_chargalg_stop_maintenance_timer(di
);
593 di
->charge_status
= POWER_SUPPLY_STATUS_CHARGING
;
594 di
->maintenance_chg
= false;
595 cancel_delayed_work(&di
->chargalg_wd_work
);
596 power_supply_changed(&di
->chargalg_psy
);
600 * abx500_chargalg_start_charging() - Start the charger
601 * @di: pointer to the abx500_chargalg structure
602 * @vset: requested charger output voltage
603 * @iset: requested charger output current
605 * A charger will be enabled depending on the requested charger type that was
606 * detected previously.
608 static void abx500_chargalg_start_charging(struct abx500_chargalg
*di
,
611 switch (di
->chg_info
.charger_type
) {
614 "AC parameters: Vset %d, Ich %d\n", vset
, iset
);
615 abx500_chargalg_usb_en(di
, false, 0, 0);
616 abx500_chargalg_ac_en(di
, true, vset
, iset
);
621 "USB parameters: Vset %d, Ich %d\n", vset
, iset
);
622 abx500_chargalg_ac_en(di
, false, 0, 0);
623 abx500_chargalg_usb_en(di
, true, vset
, iset
);
627 dev_err(di
->dev
, "Unknown charger to charge from\n");
633 * abx500_chargalg_check_temp() - Check battery temperature ranges
634 * @di: pointer to the abx500_chargalg structure
636 * The battery temperature is checked against the predefined limits and the
637 * charge state is changed accordingly
639 static void abx500_chargalg_check_temp(struct abx500_chargalg
*di
)
641 if (di
->batt_data
.temp
> (di
->bat
->temp_low
+ di
->t_hyst_norm
) &&
642 di
->batt_data
.temp
< (di
->bat
->temp_high
- di
->t_hyst_norm
)) {
644 di
->events
.btemp_underover
= false;
645 di
->events
.btemp_lowhigh
= false;
647 di
->t_hyst_lowhigh
= 0;
649 if (((di
->batt_data
.temp
>= di
->bat
->temp_high
) &&
650 (di
->batt_data
.temp
<
651 (di
->bat
->temp_over
- di
->t_hyst_lowhigh
))) ||
652 ((di
->batt_data
.temp
>
653 (di
->bat
->temp_under
+ di
->t_hyst_lowhigh
)) &&
654 (di
->batt_data
.temp
<= di
->bat
->temp_low
))) {
655 /* TEMP minor!!!!! */
656 di
->events
.btemp_underover
= false;
657 di
->events
.btemp_lowhigh
= true;
658 di
->t_hyst_norm
= di
->bat
->temp_hysteresis
;
659 di
->t_hyst_lowhigh
= 0;
660 } else if (di
->batt_data
.temp
<= di
->bat
->temp_under
||
661 di
->batt_data
.temp
>= di
->bat
->temp_over
) {
662 /* TEMP major!!!!! */
663 di
->events
.btemp_underover
= true;
664 di
->events
.btemp_lowhigh
= false;
666 di
->t_hyst_lowhigh
= di
->bat
->temp_hysteresis
;
668 /* Within hysteresis */
669 dev_dbg(di
->dev
, "Within hysteresis limit temp: %d "
670 "hyst_lowhigh %d, hyst normal %d\n",
671 di
->batt_data
.temp
, di
->t_hyst_lowhigh
,
678 * abx500_chargalg_check_charger_voltage() - Check charger voltage
679 * @di: pointer to the abx500_chargalg structure
681 * Charger voltage is checked against maximum limit
683 static void abx500_chargalg_check_charger_voltage(struct abx500_chargalg
*di
)
685 if (di
->chg_info
.usb_volt
> di
->bat
->chg_params
->usb_volt_max
)
686 di
->chg_info
.usb_chg_ok
= false;
688 di
->chg_info
.usb_chg_ok
= true;
690 if (di
->chg_info
.ac_volt
> di
->bat
->chg_params
->ac_volt_max
)
691 di
->chg_info
.ac_chg_ok
= false;
693 di
->chg_info
.ac_chg_ok
= true;
698 * abx500_chargalg_end_of_charge() - Check if end-of-charge criteria is fulfilled
699 * @di: pointer to the abx500_chargalg structure
701 * End-of-charge criteria is fulfilled when the battery voltage is above a
702 * certain limit and the battery current is below a certain limit for a
703 * predefined number of consecutive seconds. If true, the battery is full
705 static void abx500_chargalg_end_of_charge(struct abx500_chargalg
*di
)
707 if (di
->charge_status
== POWER_SUPPLY_STATUS_CHARGING
&&
708 di
->charge_state
== STATE_NORMAL
&&
709 !di
->maintenance_chg
&& (di
->batt_data
.volt
>=
710 di
->bat
->bat_type
[di
->bat
->batt_id
].termination_vol
||
711 di
->events
.usb_cv_active
|| di
->events
.ac_cv_active
) &&
712 di
->batt_data
.avg_curr
<
713 di
->bat
->bat_type
[di
->bat
->batt_id
].termination_curr
&&
714 di
->batt_data
.avg_curr
> 0) {
715 if (++di
->eoc_cnt
>= EOC_COND_CNT
) {
717 di
->charge_status
= POWER_SUPPLY_STATUS_FULL
;
718 di
->maintenance_chg
= true;
719 dev_dbg(di
->dev
, "EOC reached!\n");
720 power_supply_changed(&di
->chargalg_psy
);
723 " EOC limit reached for the %d"
724 " time, out of %d before EOC\n",
733 static void init_maxim_chg_curr(struct abx500_chargalg
*di
)
735 di
->ccm
.original_iset
=
736 di
->bat
->bat_type
[di
->bat
->batt_id
].normal_cur_lvl
;
737 di
->ccm
.current_iset
=
738 di
->bat
->bat_type
[di
->bat
->batt_id
].normal_cur_lvl
;
739 di
->ccm
.test_delta_i
= di
->bat
->maxi
->charger_curr_step
;
740 di
->ccm
.max_current
= di
->bat
->maxi
->chg_curr
;
741 di
->ccm
.condition_cnt
= di
->bat
->maxi
->wait_cycles
;
746 * abx500_chargalg_chg_curr_maxim - increases the charger current to
747 * compensate for the system load
748 * @di pointer to the abx500_chargalg structure
750 * This maximization function is used to raise the charger current to get the
751 * battery current as close to the optimal value as possible. The battery
752 * current during charging is affected by the system load
754 static enum maxim_ret
abx500_chargalg_chg_curr_maxim(struct abx500_chargalg
*di
)
758 if (!di
->bat
->maxi
->ena_maxi
)
759 return MAXIM_RET_NOACTION
;
761 delta_i
= di
->ccm
.original_iset
- di
->batt_data
.inst_curr
;
763 if (di
->events
.vbus_collapsed
) {
764 dev_dbg(di
->dev
, "Charger voltage has collapsed %d\n",
766 if (di
->ccm
.wait_cnt
== 0) {
767 dev_dbg(di
->dev
, "lowering current\n");
769 di
->ccm
.condition_cnt
= di
->bat
->maxi
->wait_cycles
;
770 di
->ccm
.max_current
=
771 di
->ccm
.current_iset
- di
->ccm
.test_delta_i
;
772 di
->ccm
.current_iset
= di
->ccm
.max_current
;
774 return MAXIM_RET_CHANGE
;
776 dev_dbg(di
->dev
, "waiting\n");
777 /* Let's go in here twice before lowering curr again */
778 di
->ccm
.wait_cnt
= (di
->ccm
.wait_cnt
+ 1) % 3;
779 return MAXIM_RET_NOACTION
;
783 di
->ccm
.wait_cnt
= 0;
785 if ((di
->batt_data
.inst_curr
> di
->ccm
.original_iset
)) {
786 dev_dbg(di
->dev
, " Maximization Ibat (%dmA) too high"
787 " (limit %dmA) (current iset: %dmA)!\n",
788 di
->batt_data
.inst_curr
, di
->ccm
.original_iset
,
789 di
->ccm
.current_iset
);
791 if (di
->ccm
.current_iset
== di
->ccm
.original_iset
)
792 return MAXIM_RET_NOACTION
;
794 di
->ccm
.condition_cnt
= di
->bat
->maxi
->wait_cycles
;
795 di
->ccm
.current_iset
= di
->ccm
.original_iset
;
798 return MAXIM_RET_IBAT_TOO_HIGH
;
801 if (delta_i
> di
->ccm
.test_delta_i
&&
802 (di
->ccm
.current_iset
+ di
->ccm
.test_delta_i
) <
803 di
->ccm
.max_current
) {
804 if (di
->ccm
.condition_cnt
-- == 0) {
805 /* Increse the iset with cco.test_delta_i */
806 di
->ccm
.condition_cnt
= di
->bat
->maxi
->wait_cycles
;
807 di
->ccm
.current_iset
+= di
->ccm
.test_delta_i
;
809 dev_dbg(di
->dev
, " Maximization needed, increase"
810 " with %d mA to %dmA (Optimal ibat: %d)"
812 di
->ccm
.test_delta_i
,
813 di
->ccm
.current_iset
,
814 di
->ccm
.original_iset
,
816 return MAXIM_RET_CHANGE
;
818 return MAXIM_RET_NOACTION
;
821 di
->ccm
.condition_cnt
= di
->bat
->maxi
->wait_cycles
;
822 return MAXIM_RET_NOACTION
;
826 static void handle_maxim_chg_curr(struct abx500_chargalg
*di
)
831 ret
= abx500_chargalg_chg_curr_maxim(di
);
833 case MAXIM_RET_CHANGE
:
834 result
= abx500_chargalg_update_chg_curr(di
,
835 di
->ccm
.current_iset
);
837 dev_err(di
->dev
, "failed to set chg curr\n");
839 case MAXIM_RET_IBAT_TOO_HIGH
:
840 result
= abx500_chargalg_update_chg_curr(di
,
841 di
->bat
->bat_type
[di
->bat
->batt_id
].normal_cur_lvl
);
843 dev_err(di
->dev
, "failed to set chg curr\n");
846 case MAXIM_RET_NOACTION
:
853 static int abx500_chargalg_get_ext_psy_data(struct device
*dev
, void *data
)
855 struct power_supply
*psy
;
856 struct power_supply
*ext
;
857 struct abx500_chargalg
*di
;
858 union power_supply_propval ret
;
860 bool psy_found
= false;
862 psy
= (struct power_supply
*)data
;
863 ext
= dev_get_drvdata(dev
);
864 di
= to_abx500_chargalg_device_info(psy
);
865 /* For all psy where the driver name appears in any supplied_to */
866 for (i
= 0; i
< ext
->num_supplicants
; i
++) {
867 if (!strcmp(ext
->supplied_to
[i
], psy
->name
))
873 /* Go through all properties for the psy */
874 for (j
= 0; j
< ext
->num_properties
; j
++) {
875 enum power_supply_property prop
;
876 prop
= ext
->properties
[j
];
878 /* Initialize chargers if not already done */
880 ext
->type
== POWER_SUPPLY_TYPE_MAINS
)
881 di
->ac_chg
= psy_to_ux500_charger(ext
);
882 else if (!di
->usb_chg
&&
883 ext
->type
== POWER_SUPPLY_TYPE_USB
)
884 di
->usb_chg
= psy_to_ux500_charger(ext
);
886 if (ext
->get_property(ext
, prop
, &ret
))
889 case POWER_SUPPLY_PROP_PRESENT
:
891 case POWER_SUPPLY_TYPE_BATTERY
:
892 /* Battery present */
894 di
->events
.batt_rem
= false;
895 /* Battery removed */
897 di
->events
.batt_rem
= true;
899 case POWER_SUPPLY_TYPE_MAINS
:
900 /* AC disconnected */
902 (di
->chg_info
.conn_chg
& AC_CHG
)) {
903 di
->chg_info
.prev_conn_chg
=
904 di
->chg_info
.conn_chg
;
905 di
->chg_info
.conn_chg
&= ~AC_CHG
;
908 else if (ret
.intval
&&
909 !(di
->chg_info
.conn_chg
& AC_CHG
)) {
910 di
->chg_info
.prev_conn_chg
=
911 di
->chg_info
.conn_chg
;
912 di
->chg_info
.conn_chg
|= AC_CHG
;
915 case POWER_SUPPLY_TYPE_USB
:
916 /* USB disconnected */
918 (di
->chg_info
.conn_chg
& USB_CHG
)) {
919 di
->chg_info
.prev_conn_chg
=
920 di
->chg_info
.conn_chg
;
921 di
->chg_info
.conn_chg
&= ~USB_CHG
;
924 else if (ret
.intval
&&
925 !(di
->chg_info
.conn_chg
& USB_CHG
)) {
926 di
->chg_info
.prev_conn_chg
=
927 di
->chg_info
.conn_chg
;
928 di
->chg_info
.conn_chg
|= USB_CHG
;
936 case POWER_SUPPLY_PROP_ONLINE
:
938 case POWER_SUPPLY_TYPE_BATTERY
:
940 case POWER_SUPPLY_TYPE_MAINS
:
943 (di
->chg_info
.online_chg
& AC_CHG
)) {
944 di
->chg_info
.prev_online_chg
=
945 di
->chg_info
.online_chg
;
946 di
->chg_info
.online_chg
&= ~AC_CHG
;
949 else if (ret
.intval
&&
950 !(di
->chg_info
.online_chg
& AC_CHG
)) {
951 di
->chg_info
.prev_online_chg
=
952 di
->chg_info
.online_chg
;
953 di
->chg_info
.online_chg
|= AC_CHG
;
954 queue_delayed_work(di
->chargalg_wq
,
955 &di
->chargalg_wd_work
, 0);
958 case POWER_SUPPLY_TYPE_USB
:
961 (di
->chg_info
.online_chg
& USB_CHG
)) {
962 di
->chg_info
.prev_online_chg
=
963 di
->chg_info
.online_chg
;
964 di
->chg_info
.online_chg
&= ~USB_CHG
;
967 else if (ret
.intval
&&
968 !(di
->chg_info
.online_chg
& USB_CHG
)) {
969 di
->chg_info
.prev_online_chg
=
970 di
->chg_info
.online_chg
;
971 di
->chg_info
.online_chg
|= USB_CHG
;
972 queue_delayed_work(di
->chargalg_wq
,
973 &di
->chargalg_wd_work
, 0);
981 case POWER_SUPPLY_PROP_HEALTH
:
983 case POWER_SUPPLY_TYPE_BATTERY
:
985 case POWER_SUPPLY_TYPE_MAINS
:
986 switch (ret
.intval
) {
987 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
:
988 di
->events
.mainextchnotok
= true;
989 di
->events
.main_thermal_prot
= false;
990 di
->events
.main_ovv
= false;
991 di
->events
.ac_wd_expired
= false;
993 case POWER_SUPPLY_HEALTH_DEAD
:
994 di
->events
.ac_wd_expired
= true;
995 di
->events
.mainextchnotok
= false;
996 di
->events
.main_ovv
= false;
997 di
->events
.main_thermal_prot
= false;
999 case POWER_SUPPLY_HEALTH_COLD
:
1000 case POWER_SUPPLY_HEALTH_OVERHEAT
:
1001 di
->events
.main_thermal_prot
= true;
1002 di
->events
.mainextchnotok
= false;
1003 di
->events
.main_ovv
= false;
1004 di
->events
.ac_wd_expired
= false;
1006 case POWER_SUPPLY_HEALTH_OVERVOLTAGE
:
1007 di
->events
.main_ovv
= true;
1008 di
->events
.mainextchnotok
= false;
1009 di
->events
.main_thermal_prot
= false;
1010 di
->events
.ac_wd_expired
= false;
1012 case POWER_SUPPLY_HEALTH_GOOD
:
1013 di
->events
.main_thermal_prot
= false;
1014 di
->events
.mainextchnotok
= false;
1015 di
->events
.main_ovv
= false;
1016 di
->events
.ac_wd_expired
= false;
1023 case POWER_SUPPLY_TYPE_USB
:
1024 switch (ret
.intval
) {
1025 case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
:
1026 di
->events
.usbchargernotok
= true;
1027 di
->events
.usb_thermal_prot
= false;
1028 di
->events
.vbus_ovv
= false;
1029 di
->events
.usb_wd_expired
= false;
1031 case POWER_SUPPLY_HEALTH_DEAD
:
1032 di
->events
.usb_wd_expired
= true;
1033 di
->events
.usbchargernotok
= false;
1034 di
->events
.usb_thermal_prot
= false;
1035 di
->events
.vbus_ovv
= false;
1037 case POWER_SUPPLY_HEALTH_COLD
:
1038 case POWER_SUPPLY_HEALTH_OVERHEAT
:
1039 di
->events
.usb_thermal_prot
= true;
1040 di
->events
.usbchargernotok
= false;
1041 di
->events
.vbus_ovv
= false;
1042 di
->events
.usb_wd_expired
= false;
1044 case POWER_SUPPLY_HEALTH_OVERVOLTAGE
:
1045 di
->events
.vbus_ovv
= true;
1046 di
->events
.usbchargernotok
= false;
1047 di
->events
.usb_thermal_prot
= false;
1048 di
->events
.usb_wd_expired
= false;
1050 case POWER_SUPPLY_HEALTH_GOOD
:
1051 di
->events
.usbchargernotok
= false;
1052 di
->events
.usb_thermal_prot
= false;
1053 di
->events
.vbus_ovv
= false;
1054 di
->events
.usb_wd_expired
= false;
1064 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
1065 switch (ext
->type
) {
1066 case POWER_SUPPLY_TYPE_BATTERY
:
1067 di
->batt_data
.volt
= ret
.intval
/ 1000;
1069 case POWER_SUPPLY_TYPE_MAINS
:
1070 di
->chg_info
.ac_volt
= ret
.intval
/ 1000;
1072 case POWER_SUPPLY_TYPE_USB
:
1073 di
->chg_info
.usb_volt
= ret
.intval
/ 1000;
1080 case POWER_SUPPLY_PROP_VOLTAGE_AVG
:
1081 switch (ext
->type
) {
1082 case POWER_SUPPLY_TYPE_MAINS
:
1083 /* AVG is used to indicate when we are
1086 di
->events
.ac_cv_active
= true;
1088 di
->events
.ac_cv_active
= false;
1091 case POWER_SUPPLY_TYPE_USB
:
1092 /* AVG is used to indicate when we are
1095 di
->events
.usb_cv_active
= true;
1097 di
->events
.usb_cv_active
= false;
1105 case POWER_SUPPLY_PROP_TECHNOLOGY
:
1106 switch (ext
->type
) {
1107 case POWER_SUPPLY_TYPE_BATTERY
:
1109 di
->events
.batt_unknown
= false;
1111 di
->events
.batt_unknown
= true;
1119 case POWER_SUPPLY_PROP_TEMP
:
1120 di
->batt_data
.temp
= ret
.intval
/ 10;
1123 case POWER_SUPPLY_PROP_CURRENT_NOW
:
1124 switch (ext
->type
) {
1125 case POWER_SUPPLY_TYPE_MAINS
:
1126 di
->chg_info
.ac_curr
=
1129 case POWER_SUPPLY_TYPE_USB
:
1130 di
->chg_info
.usb_curr
=
1133 case POWER_SUPPLY_TYPE_BATTERY
:
1134 di
->batt_data
.inst_curr
= ret
.intval
/ 1000;
1141 case POWER_SUPPLY_PROP_CURRENT_AVG
:
1142 switch (ext
->type
) {
1143 case POWER_SUPPLY_TYPE_BATTERY
:
1144 di
->batt_data
.avg_curr
= ret
.intval
/ 1000;
1146 case POWER_SUPPLY_TYPE_USB
:
1148 di
->events
.vbus_collapsed
= true;
1150 di
->events
.vbus_collapsed
= false;
1156 case POWER_SUPPLY_PROP_CAPACITY
:
1157 di
->batt_data
.percent
= ret
.intval
;
1167 * abx500_chargalg_external_power_changed() - callback for power supply changes
1168 * @psy: pointer to the structure power_supply
1170 * This function is the entry point of the pointer external_power_changed
1171 * of the structure power_supply.
1172 * This function gets executed when there is a change in any external power
1173 * supply that this driver needs to be notified of.
1175 static void abx500_chargalg_external_power_changed(struct power_supply
*psy
)
1177 struct abx500_chargalg
*di
= to_abx500_chargalg_device_info(psy
);
1180 * Trigger execution of the algorithm instantly and read
1181 * all power_supply properties there instead
1183 queue_work(di
->chargalg_wq
, &di
->chargalg_work
);
1187 * abx500_chargalg_algorithm() - Main function for the algorithm
1188 * @di: pointer to the abx500_chargalg structure
1190 * This is the main control function for the charging algorithm.
1191 * It is called periodically or when something happens that will
1192 * trigger a state change
1194 static void abx500_chargalg_algorithm(struct abx500_chargalg
*di
)
1198 /* Collect data from all power_supply class devices */
1199 class_for_each_device(power_supply_class
, NULL
,
1200 &di
->chargalg_psy
, abx500_chargalg_get_ext_psy_data
);
1202 abx500_chargalg_end_of_charge(di
);
1203 abx500_chargalg_check_temp(di
);
1204 abx500_chargalg_check_charger_voltage(di
);
1206 charger_status
= abx500_chargalg_check_charger_connection(di
);
1208 * First check if we have a charger connected.
1209 * Also we don't allow charging of unknown batteries if configured
1212 if (!charger_status
||
1213 (di
->events
.batt_unknown
&& !di
->bat
->chg_unknown_bat
)) {
1214 if (di
->charge_state
!= STATE_HANDHELD
) {
1215 di
->events
.safety_timer_expired
= false;
1216 abx500_chargalg_state_to(di
, STATE_HANDHELD_INIT
);
1220 /* If suspended, we should not continue checking the flags */
1221 else if (di
->charge_state
== STATE_SUSPENDED_INIT
||
1222 di
->charge_state
== STATE_SUSPENDED
) {
1223 /* We don't do anything here, just don,t continue */
1226 /* Safety timer expiration */
1227 else if (di
->events
.safety_timer_expired
) {
1228 if (di
->charge_state
!= STATE_SAFETY_TIMER_EXPIRED
)
1229 abx500_chargalg_state_to(di
,
1230 STATE_SAFETY_TIMER_EXPIRED_INIT
);
1233 * Check if any interrupts has occured
1234 * that will prevent us from charging
1237 /* Battery removed */
1238 else if (di
->events
.batt_rem
) {
1239 if (di
->charge_state
!= STATE_BATT_REMOVED
)
1240 abx500_chargalg_state_to(di
, STATE_BATT_REMOVED_INIT
);
1242 /* Main or USB charger not ok. */
1243 else if (di
->events
.mainextchnotok
|| di
->events
.usbchargernotok
) {
1245 * If vbus_collapsed is set, we have to lower the charger
1246 * current, which is done in the normal state below
1248 if (di
->charge_state
!= STATE_CHG_NOT_OK
&&
1249 !di
->events
.vbus_collapsed
)
1250 abx500_chargalg_state_to(di
, STATE_CHG_NOT_OK_INIT
);
1252 /* VBUS, Main or VBAT OVV. */
1253 else if (di
->events
.vbus_ovv
||
1254 di
->events
.main_ovv
||
1255 di
->events
.batt_ovv
||
1256 !di
->chg_info
.usb_chg_ok
||
1257 !di
->chg_info
.ac_chg_ok
) {
1258 if (di
->charge_state
!= STATE_OVV_PROTECT
)
1259 abx500_chargalg_state_to(di
, STATE_OVV_PROTECT_INIT
);
1261 /* USB Thermal, stop charging */
1262 else if (di
->events
.main_thermal_prot
||
1263 di
->events
.usb_thermal_prot
) {
1264 if (di
->charge_state
!= STATE_HW_TEMP_PROTECT
)
1265 abx500_chargalg_state_to(di
,
1266 STATE_HW_TEMP_PROTECT_INIT
);
1268 /* Battery temp over/under */
1269 else if (di
->events
.btemp_underover
) {
1270 if (di
->charge_state
!= STATE_TEMP_UNDEROVER
)
1271 abx500_chargalg_state_to(di
,
1272 STATE_TEMP_UNDEROVER_INIT
);
1274 /* Watchdog expired */
1275 else if (di
->events
.ac_wd_expired
||
1276 di
->events
.usb_wd_expired
) {
1277 if (di
->charge_state
!= STATE_WD_EXPIRED
)
1278 abx500_chargalg_state_to(di
, STATE_WD_EXPIRED_INIT
);
1280 /* Battery temp high/low */
1281 else if (di
->events
.btemp_lowhigh
) {
1282 if (di
->charge_state
!= STATE_TEMP_LOWHIGH
)
1283 abx500_chargalg_state_to(di
, STATE_TEMP_LOWHIGH_INIT
);
1287 "[CHARGALG] Vb %d Ib_avg %d Ib_inst %d Tb %d Cap %d Maint %d "
1288 "State %s Active_chg %d Chg_status %d AC %d USB %d "
1289 "AC_online %d USB_online %d AC_CV %d USB_CV %d AC_I %d "
1290 "USB_I %d AC_Vset %d AC_Iset %d USB_Vset %d USB_Iset %d\n",
1292 di
->batt_data
.avg_curr
,
1293 di
->batt_data
.inst_curr
,
1295 di
->batt_data
.percent
,
1296 di
->maintenance_chg
,
1297 states
[di
->charge_state
],
1298 di
->chg_info
.charger_type
,
1300 di
->chg_info
.conn_chg
& AC_CHG
,
1301 di
->chg_info
.conn_chg
& USB_CHG
,
1302 di
->chg_info
.online_chg
& AC_CHG
,
1303 di
->chg_info
.online_chg
& USB_CHG
,
1304 di
->events
.ac_cv_active
,
1305 di
->events
.usb_cv_active
,
1306 di
->chg_info
.ac_curr
,
1307 di
->chg_info
.usb_curr
,
1308 di
->chg_info
.ac_vset
,
1309 di
->chg_info
.ac_iset
,
1310 di
->chg_info
.usb_vset
,
1311 di
->chg_info
.usb_iset
);
1313 switch (di
->charge_state
) {
1314 case STATE_HANDHELD_INIT
:
1315 abx500_chargalg_stop_charging(di
);
1316 di
->charge_status
= POWER_SUPPLY_STATUS_DISCHARGING
;
1317 abx500_chargalg_state_to(di
, STATE_HANDHELD
);
1318 /* Intentional fallthrough */
1320 case STATE_HANDHELD
:
1323 case STATE_SUSPENDED_INIT
:
1324 if (di
->susp_status
.ac_suspended
)
1325 abx500_chargalg_ac_en(di
, false, 0, 0);
1326 if (di
->susp_status
.usb_suspended
)
1327 abx500_chargalg_usb_en(di
, false, 0, 0);
1328 abx500_chargalg_stop_safety_timer(di
);
1329 abx500_chargalg_stop_maintenance_timer(di
);
1330 di
->charge_status
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
1331 di
->maintenance_chg
= false;
1332 abx500_chargalg_state_to(di
, STATE_SUSPENDED
);
1333 power_supply_changed(&di
->chargalg_psy
);
1334 /* Intentional fallthrough */
1336 case STATE_SUSPENDED
:
1337 /* CHARGING is suspended */
1340 case STATE_BATT_REMOVED_INIT
:
1341 abx500_chargalg_stop_charging(di
);
1342 abx500_chargalg_state_to(di
, STATE_BATT_REMOVED
);
1343 /* Intentional fallthrough */
1345 case STATE_BATT_REMOVED
:
1346 if (!di
->events
.batt_rem
)
1347 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
1350 case STATE_HW_TEMP_PROTECT_INIT
:
1351 abx500_chargalg_stop_charging(di
);
1352 abx500_chargalg_state_to(di
, STATE_HW_TEMP_PROTECT
);
1353 /* Intentional fallthrough */
1355 case STATE_HW_TEMP_PROTECT
:
1356 if (!di
->events
.main_thermal_prot
&&
1357 !di
->events
.usb_thermal_prot
)
1358 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
1361 case STATE_OVV_PROTECT_INIT
:
1362 abx500_chargalg_stop_charging(di
);
1363 abx500_chargalg_state_to(di
, STATE_OVV_PROTECT
);
1364 /* Intentional fallthrough */
1366 case STATE_OVV_PROTECT
:
1367 if (!di
->events
.vbus_ovv
&&
1368 !di
->events
.main_ovv
&&
1369 !di
->events
.batt_ovv
&&
1370 di
->chg_info
.usb_chg_ok
&&
1371 di
->chg_info
.ac_chg_ok
)
1372 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
1375 case STATE_CHG_NOT_OK_INIT
:
1376 abx500_chargalg_stop_charging(di
);
1377 abx500_chargalg_state_to(di
, STATE_CHG_NOT_OK
);
1378 /* Intentional fallthrough */
1380 case STATE_CHG_NOT_OK
:
1381 if (!di
->events
.mainextchnotok
&&
1382 !di
->events
.usbchargernotok
)
1383 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
1386 case STATE_SAFETY_TIMER_EXPIRED_INIT
:
1387 abx500_chargalg_stop_charging(di
);
1388 abx500_chargalg_state_to(di
, STATE_SAFETY_TIMER_EXPIRED
);
1389 /* Intentional fallthrough */
1391 case STATE_SAFETY_TIMER_EXPIRED
:
1392 /* We exit this state when charger is removed */
1395 case STATE_NORMAL_INIT
:
1396 abx500_chargalg_start_charging(di
,
1397 di
->bat
->bat_type
[di
->bat
->batt_id
].normal_vol_lvl
,
1398 di
->bat
->bat_type
[di
->bat
->batt_id
].normal_cur_lvl
);
1399 abx500_chargalg_state_to(di
, STATE_NORMAL
);
1400 abx500_chargalg_start_safety_timer(di
);
1401 abx500_chargalg_stop_maintenance_timer(di
);
1402 init_maxim_chg_curr(di
);
1403 di
->charge_status
= POWER_SUPPLY_STATUS_CHARGING
;
1405 di
->maintenance_chg
= false;
1406 power_supply_changed(&di
->chargalg_psy
);
1411 handle_maxim_chg_curr(di
);
1412 if (di
->charge_status
== POWER_SUPPLY_STATUS_FULL
&&
1413 di
->maintenance_chg
) {
1414 if (di
->bat
->no_maintenance
)
1415 abx500_chargalg_state_to(di
,
1416 STATE_WAIT_FOR_RECHARGE_INIT
);
1418 abx500_chargalg_state_to(di
,
1419 STATE_MAINTENANCE_A_INIT
);
1423 /* This state will be used when the maintenance state is disabled */
1424 case STATE_WAIT_FOR_RECHARGE_INIT
:
1425 abx500_chargalg_hold_charging(di
);
1426 abx500_chargalg_state_to(di
, STATE_WAIT_FOR_RECHARGE
);
1427 di
->rch_cnt
= RCH_COND_CNT
;
1428 /* Intentional fallthrough */
1430 case STATE_WAIT_FOR_RECHARGE
:
1431 if (di
->batt_data
.volt
<=
1432 di
->bat
->bat_type
[di
->bat
->batt_id
].recharge_vol
) {
1433 if (di
->rch_cnt
-- == 0)
1434 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
1436 di
->rch_cnt
= RCH_COND_CNT
;
1439 case STATE_MAINTENANCE_A_INIT
:
1440 abx500_chargalg_stop_safety_timer(di
);
1441 abx500_chargalg_start_maintenance_timer(di
,
1443 di
->bat
->batt_id
].maint_a_chg_timer_h
);
1444 abx500_chargalg_start_charging(di
,
1446 di
->bat
->batt_id
].maint_a_vol_lvl
,
1448 di
->bat
->batt_id
].maint_a_cur_lvl
);
1449 abx500_chargalg_state_to(di
, STATE_MAINTENANCE_A
);
1450 power_supply_changed(&di
->chargalg_psy
);
1451 /* Intentional fallthrough*/
1453 case STATE_MAINTENANCE_A
:
1454 if (di
->events
.maintenance_timer_expired
) {
1455 abx500_chargalg_stop_maintenance_timer(di
);
1456 abx500_chargalg_state_to(di
, STATE_MAINTENANCE_B_INIT
);
1460 case STATE_MAINTENANCE_B_INIT
:
1461 abx500_chargalg_start_maintenance_timer(di
,
1463 di
->bat
->batt_id
].maint_b_chg_timer_h
);
1464 abx500_chargalg_start_charging(di
,
1466 di
->bat
->batt_id
].maint_b_vol_lvl
,
1468 di
->bat
->batt_id
].maint_b_cur_lvl
);
1469 abx500_chargalg_state_to(di
, STATE_MAINTENANCE_B
);
1470 power_supply_changed(&di
->chargalg_psy
);
1471 /* Intentional fallthrough*/
1473 case STATE_MAINTENANCE_B
:
1474 if (di
->events
.maintenance_timer_expired
) {
1475 abx500_chargalg_stop_maintenance_timer(di
);
1476 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
1480 case STATE_TEMP_LOWHIGH_INIT
:
1481 abx500_chargalg_start_charging(di
,
1483 di
->bat
->batt_id
].low_high_vol_lvl
,
1485 di
->bat
->batt_id
].low_high_cur_lvl
);
1486 abx500_chargalg_stop_maintenance_timer(di
);
1487 di
->charge_status
= POWER_SUPPLY_STATUS_CHARGING
;
1488 abx500_chargalg_state_to(di
, STATE_TEMP_LOWHIGH
);
1489 power_supply_changed(&di
->chargalg_psy
);
1490 /* Intentional fallthrough */
1492 case STATE_TEMP_LOWHIGH
:
1493 if (!di
->events
.btemp_lowhigh
)
1494 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
1497 case STATE_WD_EXPIRED_INIT
:
1498 abx500_chargalg_stop_charging(di
);
1499 abx500_chargalg_state_to(di
, STATE_WD_EXPIRED
);
1500 /* Intentional fallthrough */
1502 case STATE_WD_EXPIRED
:
1503 if (!di
->events
.ac_wd_expired
&&
1504 !di
->events
.usb_wd_expired
)
1505 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
1508 case STATE_TEMP_UNDEROVER_INIT
:
1509 abx500_chargalg_stop_charging(di
);
1510 abx500_chargalg_state_to(di
, STATE_TEMP_UNDEROVER
);
1511 /* Intentional fallthrough */
1513 case STATE_TEMP_UNDEROVER
:
1514 if (!di
->events
.btemp_underover
)
1515 abx500_chargalg_state_to(di
, STATE_NORMAL_INIT
);
1519 /* Start charging directly if the new state is a charge state */
1520 if (di
->charge_state
== STATE_NORMAL_INIT
||
1521 di
->charge_state
== STATE_MAINTENANCE_A_INIT
||
1522 di
->charge_state
== STATE_MAINTENANCE_B_INIT
)
1523 queue_work(di
->chargalg_wq
, &di
->chargalg_work
);
1527 * abx500_chargalg_periodic_work() - Periodic work for the algorithm
1528 * @work: pointer to the work_struct structure
1530 * Work queue function for the charging algorithm
1532 static void abx500_chargalg_periodic_work(struct work_struct
*work
)
1534 struct abx500_chargalg
*di
= container_of(work
,
1535 struct abx500_chargalg
, chargalg_periodic_work
.work
);
1537 abx500_chargalg_algorithm(di
);
1540 * If a charger is connected then the battery has to be monitored
1541 * frequently, else the work can be delayed.
1543 if (di
->chg_info
.conn_chg
)
1544 queue_delayed_work(di
->chargalg_wq
,
1545 &di
->chargalg_periodic_work
,
1546 di
->bat
->interval_charging
* HZ
);
1548 queue_delayed_work(di
->chargalg_wq
,
1549 &di
->chargalg_periodic_work
,
1550 di
->bat
->interval_not_charging
* HZ
);
1554 * abx500_chargalg_wd_work() - periodic work to kick the charger watchdog
1555 * @work: pointer to the work_struct structure
1557 * Work queue function for kicking the charger watchdog
1559 static void abx500_chargalg_wd_work(struct work_struct
*work
)
1562 struct abx500_chargalg
*di
= container_of(work
,
1563 struct abx500_chargalg
, chargalg_wd_work
.work
);
1565 dev_dbg(di
->dev
, "abx500_chargalg_wd_work\n");
1567 ret
= abx500_chargalg_kick_watchdog(di
);
1569 dev_err(di
->dev
, "failed to kick watchdog\n");
1571 queue_delayed_work(di
->chargalg_wq
,
1572 &di
->chargalg_wd_work
, CHG_WD_INTERVAL
);
1576 * abx500_chargalg_work() - Work to run the charging algorithm instantly
1577 * @work: pointer to the work_struct structure
1579 * Work queue function for calling the charging algorithm
1581 static void abx500_chargalg_work(struct work_struct
*work
)
1583 struct abx500_chargalg
*di
= container_of(work
,
1584 struct abx500_chargalg
, chargalg_work
);
1586 abx500_chargalg_algorithm(di
);
1590 * abx500_chargalg_get_property() - get the chargalg properties
1591 * @psy: pointer to the power_supply structure
1592 * @psp: pointer to the power_supply_property structure
1593 * @val: pointer to the power_supply_propval union
1595 * This function gets called when an application tries to get the
1596 * chargalg properties by reading the sysfs files.
1597 * status: charging/discharging/full/unknown
1598 * health: health of the battery
1599 * Returns error code in case of failure else 0 on success
1601 static int abx500_chargalg_get_property(struct power_supply
*psy
,
1602 enum power_supply_property psp
,
1603 union power_supply_propval
*val
)
1605 struct abx500_chargalg
*di
;
1607 di
= to_abx500_chargalg_device_info(psy
);
1610 case POWER_SUPPLY_PROP_STATUS
:
1611 val
->intval
= di
->charge_status
;
1613 case POWER_SUPPLY_PROP_HEALTH
:
1614 if (di
->events
.batt_ovv
) {
1615 val
->intval
= POWER_SUPPLY_HEALTH_OVERVOLTAGE
;
1616 } else if (di
->events
.btemp_underover
) {
1617 if (di
->batt_data
.temp
<= di
->bat
->temp_under
)
1618 val
->intval
= POWER_SUPPLY_HEALTH_COLD
;
1620 val
->intval
= POWER_SUPPLY_HEALTH_OVERHEAT
;
1622 val
->intval
= POWER_SUPPLY_HEALTH_GOOD
;
1631 /* Exposure to the sysfs interface */
1634 * abx500_chargalg_sysfs_charger() - sysfs store operations
1635 * @kobj: pointer to the struct kobject
1636 * @attr: pointer to the struct attribute
1637 * @buf: buffer that holds the parameter passed from userspace
1638 * @length: length of the parameter passed
1640 * Returns length of the buffer(input taken from user space) on success
1641 * else error code on failure
1642 * The operation to be performed on passing the parameters from the user space.
1644 static ssize_t
abx500_chargalg_sysfs_charger(struct kobject
*kobj
,
1645 struct attribute
*attr
, const char *buf
, size_t length
)
1647 struct abx500_chargalg
*di
= container_of(kobj
,
1648 struct abx500_chargalg
, chargalg_kobject
);
1652 char entry
= *attr
->name
;
1656 ret
= strict_strtol(buf
, 10, ¶m
);
1663 /* Disable charging */
1664 di
->susp_status
.ac_suspended
= true;
1665 di
->susp_status
.usb_suspended
= true;
1666 di
->susp_status
.suspended_change
= true;
1667 /* Trigger a state change */
1668 queue_work(di
->chargalg_wq
,
1669 &di
->chargalg_work
);
1672 /* Enable AC Charging */
1673 di
->susp_status
.ac_suspended
= false;
1674 di
->susp_status
.suspended_change
= true;
1675 /* Trigger a state change */
1676 queue_work(di
->chargalg_wq
,
1677 &di
->chargalg_work
);
1680 /* Enable USB charging */
1681 di
->susp_status
.usb_suspended
= false;
1682 di
->susp_status
.suspended_change
= true;
1683 /* Trigger a state change */
1684 queue_work(di
->chargalg_wq
,
1685 &di
->chargalg_work
);
1688 dev_info(di
->dev
, "Wrong input\n"
1689 "Enter 0. Disable AC/USB Charging\n"
1690 "1. Enable AC charging\n"
1691 "2. Enable USB Charging\n");
1698 static struct attribute abx500_chargalg_en_charger
= \
1704 static struct attribute
*abx500_chargalg_chg
[] = {
1705 &abx500_chargalg_en_charger
,
1709 static const struct sysfs_ops abx500_chargalg_sysfs_ops
= {
1710 .store
= abx500_chargalg_sysfs_charger
,
1713 static struct kobj_type abx500_chargalg_ktype
= {
1714 .sysfs_ops
= &abx500_chargalg_sysfs_ops
,
1715 .default_attrs
= abx500_chargalg_chg
,
1719 * abx500_chargalg_sysfs_exit() - de-init of sysfs entry
1720 * @di: pointer to the struct abx500_chargalg
1722 * This function removes the entry in sysfs.
1724 static void abx500_chargalg_sysfs_exit(struct abx500_chargalg
*di
)
1726 kobject_del(&di
->chargalg_kobject
);
1730 * abx500_chargalg_sysfs_init() - init of sysfs entry
1731 * @di: pointer to the struct abx500_chargalg
1733 * This function adds an entry in sysfs.
1734 * Returns error code in case of failure else 0(on success)
1736 static int abx500_chargalg_sysfs_init(struct abx500_chargalg
*di
)
1740 ret
= kobject_init_and_add(&di
->chargalg_kobject
,
1741 &abx500_chargalg_ktype
,
1742 NULL
, "abx500_chargalg");
1744 dev_err(di
->dev
, "failed to create sysfs entry\n");
1748 /* Exposure to the sysfs interface <<END>> */
1750 #if defined(CONFIG_PM)
1751 static int abx500_chargalg_resume(struct platform_device
*pdev
)
1753 struct abx500_chargalg
*di
= platform_get_drvdata(pdev
);
1755 /* Kick charger watchdog if charging (any charger online) */
1756 if (di
->chg_info
.online_chg
)
1757 queue_delayed_work(di
->chargalg_wq
, &di
->chargalg_wd_work
, 0);
1760 * Run the charging algorithm directly to be sure we don't
1763 queue_delayed_work(di
->chargalg_wq
, &di
->chargalg_periodic_work
, 0);
1768 static int abx500_chargalg_suspend(struct platform_device
*pdev
,
1771 struct abx500_chargalg
*di
= platform_get_drvdata(pdev
);
1773 if (di
->chg_info
.online_chg
)
1774 cancel_delayed_work_sync(&di
->chargalg_wd_work
);
1776 cancel_delayed_work_sync(&di
->chargalg_periodic_work
);
1781 #define abx500_chargalg_suspend NULL
1782 #define abx500_chargalg_resume NULL
1785 static int abx500_chargalg_remove(struct platform_device
*pdev
)
1787 struct abx500_chargalg
*di
= platform_get_drvdata(pdev
);
1789 /* sysfs interface to enable/disbale charging from user space */
1790 abx500_chargalg_sysfs_exit(di
);
1792 /* Delete the work queue */
1793 destroy_workqueue(di
->chargalg_wq
);
1795 flush_scheduled_work();
1796 power_supply_unregister(&di
->chargalg_psy
);
1797 platform_set_drvdata(pdev
, NULL
);
1802 static char *supply_interface
[] = {
1806 static int abx500_chargalg_probe(struct platform_device
*pdev
)
1808 struct device_node
*np
= pdev
->dev
.of_node
;
1809 struct abx500_chargalg
*di
;
1812 di
= devm_kzalloc(&pdev
->dev
, sizeof(*di
), GFP_KERNEL
);
1814 dev_err(&pdev
->dev
, "%s no mem for ab8500_chargalg\n", __func__
);
1817 di
->bat
= pdev
->mfd_cell
->platform_data
;
1820 ret
= bmdevs_of_probe(&pdev
->dev
, np
, &di
->bat
);
1823 "failed to get battery information\n");
1827 dev_err(&pdev
->dev
, "missing dt node for ab8500_chargalg\n");
1831 dev_info(&pdev
->dev
, "falling back to legacy platform data\n");
1834 /* get device struct */
1835 di
->dev
= &pdev
->dev
;
1837 /* chargalg supply */
1838 di
->chargalg_psy
.name
= "abx500_chargalg";
1839 di
->chargalg_psy
.type
= POWER_SUPPLY_TYPE_BATTERY
;
1840 di
->chargalg_psy
.properties
= abx500_chargalg_props
;
1841 di
->chargalg_psy
.num_properties
= ARRAY_SIZE(abx500_chargalg_props
);
1842 di
->chargalg_psy
.get_property
= abx500_chargalg_get_property
;
1843 di
->chargalg_psy
.supplied_to
= supply_interface
;
1844 di
->chargalg_psy
.num_supplicants
= ARRAY_SIZE(supply_interface
),
1845 di
->chargalg_psy
.external_power_changed
=
1846 abx500_chargalg_external_power_changed
;
1848 /* Initilialize safety timer */
1849 init_timer(&di
->safety_timer
);
1850 di
->safety_timer
.function
= abx500_chargalg_safety_timer_expired
;
1851 di
->safety_timer
.data
= (unsigned long) di
;
1853 /* Initilialize maintenance timer */
1854 init_timer(&di
->maintenance_timer
);
1855 di
->maintenance_timer
.function
=
1856 abx500_chargalg_maintenance_timer_expired
;
1857 di
->maintenance_timer
.data
= (unsigned long) di
;
1859 /* Create a work queue for the chargalg */
1861 create_singlethread_workqueue("abx500_chargalg_wq");
1862 if (di
->chargalg_wq
== NULL
) {
1863 dev_err(di
->dev
, "failed to create work queue\n");
1867 /* Init work for chargalg */
1868 INIT_DEFERRABLE_WORK(&di
->chargalg_periodic_work
,
1869 abx500_chargalg_periodic_work
);
1870 INIT_DEFERRABLE_WORK(&di
->chargalg_wd_work
,
1871 abx500_chargalg_wd_work
);
1873 /* Init work for chargalg */
1874 INIT_WORK(&di
->chargalg_work
, abx500_chargalg_work
);
1876 /* To detect charger at startup */
1877 di
->chg_info
.prev_conn_chg
= -1;
1879 /* Register chargalg power supply class */
1880 ret
= power_supply_register(di
->dev
, &di
->chargalg_psy
);
1882 dev_err(di
->dev
, "failed to register chargalg psy\n");
1883 goto free_chargalg_wq
;
1886 platform_set_drvdata(pdev
, di
);
1888 /* sysfs interface to enable/disable charging from user space */
1889 ret
= abx500_chargalg_sysfs_init(di
);
1891 dev_err(di
->dev
, "failed to create sysfs entry\n");
1895 /* Run the charging algorithm */
1896 queue_delayed_work(di
->chargalg_wq
, &di
->chargalg_periodic_work
, 0);
1898 dev_info(di
->dev
, "probe success\n");
1902 power_supply_unregister(&di
->chargalg_psy
);
1904 destroy_workqueue(di
->chargalg_wq
);
1908 static const struct of_device_id ab8500_chargalg_match
[] = {
1909 { .compatible
= "stericsson,ab8500-chargalg", },
1913 static struct platform_driver abx500_chargalg_driver
= {
1914 .probe
= abx500_chargalg_probe
,
1915 .remove
= abx500_chargalg_remove
,
1916 .suspend
= abx500_chargalg_suspend
,
1917 .resume
= abx500_chargalg_resume
,
1919 .name
= "ab8500-chargalg",
1920 .owner
= THIS_MODULE
,
1921 .of_match_table
= ab8500_chargalg_match
,
1925 static int __init
abx500_chargalg_init(void)
1927 return platform_driver_register(&abx500_chargalg_driver
);
1930 static void __exit
abx500_chargalg_exit(void)
1932 platform_driver_unregister(&abx500_chargalg_driver
);
1935 module_init(abx500_chargalg_init
);
1936 module_exit(abx500_chargalg_exit
);
1938 MODULE_LICENSE("GPL v2");
1939 MODULE_AUTHOR("Johan Palsson, Karl Komierowski");
1940 MODULE_ALIAS("platform:abx500-chargalg");
1941 MODULE_DESCRIPTION("abx500 battery charging algorithm");