diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mfd/wm831x-core.c | 47 |
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 | ||
1660 | static 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 | |||
1657 | static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg, | 1696 | static 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 | ||
1770 | static 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 | |||
1731 | static const struct i2c_device_id wm831x_i2c_id[] = { | 1777 | static 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 | ||