aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/abx500_chargalg.c
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2013-02-14 07:39:15 -0500
committerLee Jones <lee.jones@linaro.org>2013-03-06 23:35:46 -0500
commitdb43e6c473b57d4e7a55c4bd6edef71f40f13eae (patch)
tree0fbe4762c914ba15898cf8bcb9bd8e531fe8fc31 /drivers/power/abx500_chargalg.c
parent405fea1c6691eb8259f2ca879c9348a4cf5d898d (diff)
ab8500-bm: Add usb power path support
AB8540 supports power path function in USB charging mode for fast power up with dead and weak battery, and it could extend the battery age. When USB charging starts, if the Vbattrue is below than SW cut off voltage, power path and pre-charge should be enabled. If Vbattrue is higher than SW cut off voltage, power path and pre-charge should be disabled. This is to make sure full current to battery charge. At the end of charge, power path should be enable again to reduce charging the battery again. Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/power/abx500_chargalg.c')
-rw-r--r--drivers/power/abx500_chargalg.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
index a876976678ab..a9b8efdafb8f 100644
--- a/drivers/power/abx500_chargalg.c
+++ b/drivers/power/abx500_chargalg.c
@@ -34,6 +34,9 @@
34/* End-of-charge criteria counter */ 34/* End-of-charge criteria counter */
35#define EOC_COND_CNT 10 35#define EOC_COND_CNT 10
36 36
37/* Plus margin for the low battery threshold */
38#define BAT_PLUS_MARGIN (100)
39
37#define to_abx500_chargalg_device_info(x) container_of((x), \ 40#define to_abx500_chargalg_device_info(x) container_of((x), \
38 struct abx500_chargalg, chargalg_psy); 41 struct abx500_chargalg, chargalg_psy);
39 42
@@ -83,6 +86,7 @@ enum abx500_chargalg_states {
83 STATE_HW_TEMP_PROTECT_INIT, 86 STATE_HW_TEMP_PROTECT_INIT,
84 STATE_HW_TEMP_PROTECT, 87 STATE_HW_TEMP_PROTECT,
85 STATE_NORMAL_INIT, 88 STATE_NORMAL_INIT,
89 STATE_USB_PP_PRE_CHARGE,
86 STATE_NORMAL, 90 STATE_NORMAL,
87 STATE_WAIT_FOR_RECHARGE_INIT, 91 STATE_WAIT_FOR_RECHARGE_INIT,
88 STATE_WAIT_FOR_RECHARGE, 92 STATE_WAIT_FOR_RECHARGE,
@@ -114,6 +118,7 @@ static const char *states[] = {
114 "HW_TEMP_PROTECT_INIT", 118 "HW_TEMP_PROTECT_INIT",
115 "HW_TEMP_PROTECT", 119 "HW_TEMP_PROTECT",
116 "NORMAL_INIT", 120 "NORMAL_INIT",
121 "USB_PP_PRE_CHARGE",
117 "NORMAL", 122 "NORMAL",
118 "WAIT_FOR_RECHARGE_INIT", 123 "WAIT_FOR_RECHARGE_INIT",
119 "WAIT_FOR_RECHARGE", 124 "WAIT_FOR_RECHARGE",
@@ -560,6 +565,37 @@ static int abx500_chargalg_usb_en(struct abx500_chargalg *di, int enable,
560 return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset); 565 return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset);
561} 566}
562 567
568 /**
569 * ab8540_chargalg_usb_pp_en() - Enable/ disable USB power path
570 * @di: pointer to the abx500_chargalg structure
571 * @enable: power path enable/disable
572 *
573 * The USB power path will be enable/ disable
574 */
575static int ab8540_chargalg_usb_pp_en(struct abx500_chargalg *di, bool enable)
576{
577 if (!di->usb_chg || !di->usb_chg->ops.pp_enable)
578 return -ENXIO;
579
580 return di->usb_chg->ops.pp_enable(di->usb_chg, enable);
581}
582
583/**
584 * ab8540_chargalg_usb_pre_chg_en() - Enable/ disable USB pre-charge
585 * @di: pointer to the abx500_chargalg structure
586 * @enable: USB pre-charge enable/disable
587 *
588 * The USB USB pre-charge will be enable/ disable
589 */
590static int ab8540_chargalg_usb_pre_chg_en(struct abx500_chargalg *di,
591 bool enable)
592{
593 if (!di->usb_chg || !di->usb_chg->ops.pre_chg_enable)
594 return -ENXIO;
595
596 return di->usb_chg->ops.pre_chg_enable(di->usb_chg, enable);
597}
598
563/** 599/**
564 * abx500_chargalg_update_chg_curr() - Update charger current 600 * abx500_chargalg_update_chg_curr() - Update charger current
565 * @di: pointer to the abx500_chargalg structure 601 * @di: pointer to the abx500_chargalg structure
@@ -765,6 +801,9 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di)
765 di->batt_data.avg_curr > 0) { 801 di->batt_data.avg_curr > 0) {
766 if (++di->eoc_cnt >= EOC_COND_CNT) { 802 if (++di->eoc_cnt >= EOC_COND_CNT) {
767 di->eoc_cnt = 0; 803 di->eoc_cnt = 0;
804 if ((di->chg_info.charger_type & USB_CHG) &&
805 (di->usb_chg->power_path))
806 ab8540_chargalg_usb_pp_en(di, true);
768 di->charge_status = POWER_SUPPLY_STATUS_FULL; 807 di->charge_status = POWER_SUPPLY_STATUS_FULL;
769 di->maintenance_chg = true; 808 di->maintenance_chg = true;
770 dev_dbg(di->dev, "EOC reached!\n"); 809 dev_dbg(di->dev, "EOC reached!\n");
@@ -1465,6 +1504,22 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
1465 break; 1504 break;
1466 1505
1467 case STATE_NORMAL_INIT: 1506 case STATE_NORMAL_INIT:
1507 if ((di->chg_info.charger_type & USB_CHG) &&
1508 di->usb_chg->power_path) {
1509 if (di->batt_data.volt >
1510 (di->bm->fg_params->lowbat_threshold +
1511 BAT_PLUS_MARGIN)) {
1512 ab8540_chargalg_usb_pre_chg_en(di, false);
1513 ab8540_chargalg_usb_pp_en(di, false);
1514 } else {
1515 ab8540_chargalg_usb_pp_en(di, true);
1516 ab8540_chargalg_usb_pre_chg_en(di, true);
1517 abx500_chargalg_state_to(di,
1518 STATE_USB_PP_PRE_CHARGE);
1519 break;
1520 }
1521 }
1522
1468 abx500_chargalg_start_charging(di, 1523 abx500_chargalg_start_charging(di,
1469 di->bm->bat_type[di->bm->batt_id].normal_vol_lvl, 1524 di->bm->bat_type[di->bm->batt_id].normal_vol_lvl,
1470 di->bm->bat_type[di->bm->batt_id].normal_cur_lvl); 1525 di->bm->bat_type[di->bm->batt_id].normal_cur_lvl);
@@ -1479,6 +1534,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
1479 1534
1480 break; 1535 break;
1481 1536
1537 case STATE_USB_PP_PRE_CHARGE:
1538 if (di->batt_data.volt >
1539 (di->bm->fg_params->lowbat_threshold +
1540 BAT_PLUS_MARGIN))
1541 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1542 break;
1543
1482 case STATE_NORMAL: 1544 case STATE_NORMAL:
1483 handle_maxim_chg_curr(di); 1545 handle_maxim_chg_curr(di);
1484 if (di->charge_status == POWER_SUPPLY_STATUS_FULL && 1546 if (di->charge_status == POWER_SUPPLY_STATUS_FULL &&