aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/ab8500_charger.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power/ab8500_charger.c')
-rw-r--r--drivers/power/ab8500_charger.c105
1 files changed, 103 insertions, 2 deletions
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index dcd3c6feca97..3eb23cf9ff47 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -52,6 +52,7 @@
52#define VBUS_DET_DBNC100 0x02 52#define VBUS_DET_DBNC100 0x02
53#define VBUS_DET_DBNC1 0x01 53#define VBUS_DET_DBNC1 0x01
54#define OTP_ENABLE_WD 0x01 54#define OTP_ENABLE_WD 0x01
55#define DROP_COUNT_RESET 0x01
55 56
56#define MAIN_CH_INPUT_CURR_SHIFT 4 57#define MAIN_CH_INPUT_CURR_SHIFT 4
57#define VBUS_IN_CURR_LIM_SHIFT 4 58#define VBUS_IN_CURR_LIM_SHIFT 4
@@ -1678,6 +1679,105 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger,
1678} 1679}
1679 1680
1680/** 1681/**
1682 * ab8500_charger_usb_check_enable() - enable usb charging
1683 * @charger: pointer to the ux500_charger structure
1684 * @vset: charging voltage
1685 * @iset: charger output current
1686 *
1687 * Check if the VBUS charger has been disconnected and reconnected without
1688 * AB8500 rising an interrupt. Returns 0 on success.
1689 */
1690static int ab8500_charger_usb_check_enable(struct ux500_charger *charger,
1691 int vset, int iset)
1692{
1693 u8 usbch_ctrl1 = 0;
1694 int ret = 0;
1695
1696 struct ab8500_charger *di = to_ab8500_charger_usb_device_info(charger);
1697
1698 if (!di->usb.charger_connected)
1699 return ret;
1700
1701 ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
1702 AB8500_USBCH_CTRL1_REG, &usbch_ctrl1);
1703 if (ret < 0) {
1704 dev_err(di->dev, "ab8500 read failed %d\n", __LINE__);
1705 return ret;
1706 }
1707 dev_dbg(di->dev, "USB charger ctrl: 0x%02x\n", usbch_ctrl1);
1708
1709 if (!(usbch_ctrl1 & USB_CH_ENA)) {
1710 dev_info(di->dev, "Charging has been disabled abnormally and will be re-enabled\n");
1711
1712 ret = abx500_mask_and_set_register_interruptible(di->dev,
1713 AB8500_CHARGER, AB8500_CHARGER_CTRL,
1714 DROP_COUNT_RESET, DROP_COUNT_RESET);
1715 if (ret < 0) {
1716 dev_err(di->dev, "ab8500 write failed %d\n", __LINE__);
1717 return ret;
1718 }
1719
1720 ret = ab8500_charger_usb_en(&di->usb_chg, true, vset, iset);
1721 if (ret < 0) {
1722 dev_err(di->dev, "Failed to enable VBUS charger %d\n",
1723 __LINE__);
1724 return ret;
1725 }
1726 }
1727 return ret;
1728}
1729
1730/**
1731 * ab8500_charger_ac_check_enable() - enable usb charging
1732 * @charger: pointer to the ux500_charger structure
1733 * @vset: charging voltage
1734 * @iset: charger output current
1735 *
1736 * Check if the AC charger has been disconnected and reconnected without
1737 * AB8500 rising an interrupt. Returns 0 on success.
1738 */
1739static int ab8500_charger_ac_check_enable(struct ux500_charger *charger,
1740 int vset, int iset)
1741{
1742 u8 mainch_ctrl1 = 0;
1743 int ret = 0;
1744
1745 struct ab8500_charger *di = to_ab8500_charger_ac_device_info(charger);
1746
1747 if (!di->ac.charger_connected)
1748 return ret;
1749
1750 ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER,
1751 AB8500_MCH_CTRL1, &mainch_ctrl1);
1752 if (ret < 0) {
1753 dev_err(di->dev, "ab8500 read failed %d\n", __LINE__);
1754 return ret;
1755 }
1756 dev_dbg(di->dev, "AC charger ctrl: 0x%02x\n", mainch_ctrl1);
1757
1758 if (!(mainch_ctrl1 & MAIN_CH_ENA)) {
1759 dev_info(di->dev, "Charging has been disabled abnormally and will be re-enabled\n");
1760
1761 ret = abx500_mask_and_set_register_interruptible(di->dev,
1762 AB8500_CHARGER, AB8500_CHARGER_CTRL,
1763 DROP_COUNT_RESET, DROP_COUNT_RESET);
1764
1765 if (ret < 0) {
1766 dev_err(di->dev, "ab8500 write failed %d\n", __LINE__);
1767 return ret;
1768 }
1769
1770 ret = ab8500_charger_ac_en(&di->usb_chg, true, vset, iset);
1771 if (ret < 0) {
1772 dev_err(di->dev, "failed to enable AC charger %d\n",
1773 __LINE__);
1774 return ret;
1775 }
1776 }
1777 return ret;
1778}
1779
1780/**
1681 * ab8500_charger_watchdog_kick() - kick charger watchdog 1781 * ab8500_charger_watchdog_kick() - kick charger watchdog
1682 * @di: pointer to the ab8500_charger structure 1782 * @di: pointer to the ab8500_charger structure
1683 * 1783 *
@@ -1734,8 +1834,7 @@ static int ab8500_charger_update_charger_current(struct ux500_charger *charger,
1734 1834
1735 /* Reset the main and usb drop input current measurement counter */ 1835 /* Reset the main and usb drop input current measurement counter */
1736 ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, 1836 ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER,
1737 AB8500_CHARGER_CTRL, 1837 AB8500_CHARGER_CTRL, DROP_COUNT_RESET);
1738 0x1);
1739 if (ret) { 1838 if (ret) {
1740 dev_err(di->dev, "%s write failed\n", __func__); 1839 dev_err(di->dev, "%s write failed\n", __func__);
1741 return ret; 1840 return ret;
@@ -3221,6 +3320,7 @@ static int ab8500_charger_probe(struct platform_device *pdev)
3221 di->ac_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), 3320 di->ac_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface),
3222 /* ux500_charger sub-class */ 3321 /* ux500_charger sub-class */
3223 di->ac_chg.ops.enable = &ab8500_charger_ac_en; 3322 di->ac_chg.ops.enable = &ab8500_charger_ac_en;
3323 di->ac_chg.ops.check_enable = &ab8500_charger_ac_check_enable;
3224 di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; 3324 di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick;
3225 di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current; 3325 di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current;
3226 di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ 3326 di->ac_chg.max_out_volt = ab8500_charger_voltage_map[
@@ -3242,6 +3342,7 @@ static int ab8500_charger_probe(struct platform_device *pdev)
3242 di->usb_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface), 3342 di->usb_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface),
3243 /* ux500_charger sub-class */ 3343 /* ux500_charger sub-class */
3244 di->usb_chg.ops.enable = &ab8500_charger_usb_en; 3344 di->usb_chg.ops.enable = &ab8500_charger_usb_en;
3345 di->usb_chg.ops.check_enable = &ab8500_charger_usb_check_enable;
3245 di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; 3346 di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick;
3246 di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current; 3347 di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current;
3247 di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ 3348 di->usb_chg.max_out_volt = ab8500_charger_voltage_map[