aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/wm831x-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/wm831x-core.c')
-rw-r--r--drivers/mfd/wm831x-core.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index da00ca9e0c71..1a968f34d679 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -1494,6 +1494,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1494 case WM8310: 1494 case WM8310:
1495 parent = WM8310; 1495 parent = WM8310;
1496 wm831x->num_gpio = 16; 1496 wm831x->num_gpio = 16;
1497 wm831x->charger_irq_wake = 1;
1497 if (rev > 0) { 1498 if (rev > 0) {
1498 wm831x->has_gpio_ena = 1; 1499 wm831x->has_gpio_ena = 1;
1499 wm831x->has_cs_sts = 1; 1500 wm831x->has_cs_sts = 1;
@@ -1505,6 +1506,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1505 case WM8311: 1506 case WM8311:
1506 parent = WM8311; 1507 parent = WM8311;
1507 wm831x->num_gpio = 16; 1508 wm831x->num_gpio = 16;
1509 wm831x->charger_irq_wake = 1;
1508 if (rev > 0) { 1510 if (rev > 0) {
1509 wm831x->has_gpio_ena = 1; 1511 wm831x->has_gpio_ena = 1;
1510 wm831x->has_cs_sts = 1; 1512 wm831x->has_cs_sts = 1;
@@ -1516,6 +1518,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1516 case WM8312: 1518 case WM8312:
1517 parent = WM8312; 1519 parent = WM8312;
1518 wm831x->num_gpio = 16; 1520 wm831x->num_gpio = 16;
1521 wm831x->charger_irq_wake = 1;
1519 if (rev > 0) { 1522 if (rev > 0) {
1520 wm831x->has_gpio_ena = 1; 1523 wm831x->has_gpio_ena = 1;
1521 wm831x->has_cs_sts = 1; 1524 wm831x->has_cs_sts = 1;
@@ -1654,6 +1657,42 @@ static void wm831x_device_exit(struct wm831x *wm831x)
1654 kfree(wm831x); 1657 kfree(wm831x);
1655} 1658}
1656 1659
1660static int wm831x_device_suspend(struct wm831x *wm831x)
1661{
1662 int reg, mask;
1663
1664 /* If the charger IRQs are a wake source then make sure we ack
1665 * them even if they're not actively being used (eg, no power
1666 * driver or no IRQ line wired up) then acknowledge the
1667 * interrupts otherwise suspend won't last very long.
1668 */
1669 if (wm831x->charger_irq_wake) {
1670 reg = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_2_MASK);
1671
1672 mask = WM831X_CHG_BATT_HOT_EINT |
1673 WM831X_CHG_BATT_COLD_EINT |
1674 WM831X_CHG_BATT_FAIL_EINT |
1675 WM831X_CHG_OV_EINT | WM831X_CHG_END_EINT |
1676 WM831X_CHG_TO_EINT | WM831X_CHG_MODE_EINT |
1677 WM831X_CHG_START_EINT;
1678
1679 /* If any of the interrupts are masked read the statuses */
1680 if (reg & mask)
1681 reg = wm831x_reg_read(wm831x,
1682 WM831X_INTERRUPT_STATUS_2);
1683
1684 if (reg & mask) {
1685 dev_info(wm831x->dev,
1686 "Acknowledging masked charger IRQs: %x\n",
1687 reg & mask);
1688 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_2,
1689 reg & mask);
1690 }
1691 }
1692
1693 return 0;
1694}
1695
1657static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg, 1696static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg,
1658 int bytes, void *dest) 1697 int bytes, void *dest)
1659{ 1698{
@@ -1728,6 +1767,13 @@ static int wm831x_i2c_remove(struct i2c_client *i2c)
1728 return 0; 1767 return 0;
1729} 1768}
1730 1769
1770static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
1771{
1772 struct wm831x *wm831x = i2c_get_clientdata(i2c);
1773
1774 return wm831x_device_suspend(wm831x);
1775}
1776
1731static const struct i2c_device_id wm831x_i2c_id[] = { 1777static const struct i2c_device_id wm831x_i2c_id[] = {
1732 { "wm8310", WM8310 }, 1778 { "wm8310", WM8310 },
1733 { "wm8311", WM8311 }, 1779 { "wm8311", WM8311 },
@@ -1745,6 +1791,7 @@ static struct i2c_driver wm831x_i2c_driver = {
1745 }, 1791 },
1746 .probe = wm831x_i2c_probe, 1792 .probe = wm831x_i2c_probe,
1747 .remove = wm831x_i2c_remove, 1793 .remove = wm831x_i2c_remove,
1794 .suspend = wm831x_i2c_suspend,
1748 .id_table = wm831x_i2c_id, 1795 .id_table = wm831x_i2c_id,
1749}; 1796};
1750 1797