aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/wm831x-core.c11
-rw-r--r--drivers/mfd/wm831x-i2c.c8
-rw-r--r--drivers/mfd/wm831x-spi.c8
-rw-r--r--include/linux/mfd/wm831x/core.h3
-rw-r--r--include/linux/mfd/wm831x/pdata.h3
5 files changed, 33 insertions, 0 deletions
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 9338f8dcbb83..e758c89ac5bb 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -25,6 +25,7 @@
25#include <linux/mfd/wm831x/irq.h> 25#include <linux/mfd/wm831x/irq.h>
26#include <linux/mfd/wm831x/auxadc.h> 26#include <linux/mfd/wm831x/auxadc.h>
27#include <linux/mfd/wm831x/otp.h> 27#include <linux/mfd/wm831x/otp.h>
28#include <linux/mfd/wm831x/pmu.h>
28#include <linux/mfd/wm831x/regulator.h> 29#include <linux/mfd/wm831x/regulator.h>
29 30
30/* Current settings - values are 2*2^(reg_val/4) microamps. These are 31/* Current settings - values are 2*2^(reg_val/4) microamps. These are
@@ -1621,6 +1622,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1621 mutex_init(&wm831x->io_lock); 1622 mutex_init(&wm831x->io_lock);
1622 mutex_init(&wm831x->key_lock); 1623 mutex_init(&wm831x->key_lock);
1623 dev_set_drvdata(wm831x->dev, wm831x); 1624 dev_set_drvdata(wm831x->dev, wm831x);
1625 wm831x->soft_shutdown = pdata->soft_shutdown;
1624 1626
1625 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID); 1627 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
1626 if (ret < 0) { 1628 if (ret < 0) {
@@ -1922,6 +1924,15 @@ int wm831x_device_suspend(struct wm831x *wm831x)
1922 return 0; 1924 return 0;
1923} 1925}
1924 1926
1927void wm831x_device_shutdown(struct wm831x *wm831x)
1928{
1929 if (wm831x->soft_shutdown) {
1930 dev_info(wm831x->dev, "Initiating shutdown...\n");
1931 wm831x_set_bits(wm831x, WM831X_POWER_STATE, WM831X_CHIP_ON, 0);
1932 }
1933}
1934EXPORT_SYMBOL_GPL(wm831x_device_shutdown);
1935
1925MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC"); 1936MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC");
1926MODULE_LICENSE("GPL"); 1937MODULE_LICENSE("GPL");
1927MODULE_AUTHOR("Mark Brown"); 1938MODULE_AUTHOR("Mark Brown");
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
index 3ec6085d5fc0..ac8da1d439da 100644
--- a/drivers/mfd/wm831x-i2c.c
+++ b/drivers/mfd/wm831x-i2c.c
@@ -65,6 +65,13 @@ static int wm831x_i2c_suspend(struct device *dev)
65 return wm831x_device_suspend(wm831x); 65 return wm831x_device_suspend(wm831x);
66} 66}
67 67
68static void wm831x_i2c_shutdown(struct i2c_client *i2c)
69{
70 struct wm831x *wm831x = i2c_get_clientdata(i2c);
71
72 wm831x_device_shutdown(wm831x);
73}
74
68static const struct i2c_device_id wm831x_i2c_id[] = { 75static const struct i2c_device_id wm831x_i2c_id[] = {
69 { "wm8310", WM8310 }, 76 { "wm8310", WM8310 },
70 { "wm8311", WM8311 }, 77 { "wm8311", WM8311 },
@@ -89,6 +96,7 @@ static struct i2c_driver wm831x_i2c_driver = {
89 }, 96 },
90 .probe = wm831x_i2c_probe, 97 .probe = wm831x_i2c_probe,
91 .remove = wm831x_i2c_remove, 98 .remove = wm831x_i2c_remove,
99 .shutdown = wm831x_i2c_shutdown,
92 .id_table = wm831x_i2c_id, 100 .id_table = wm831x_i2c_id,
93}; 101};
94 102
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 5ea60cd860fc..8d6a9a969dbc 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -68,6 +68,13 @@ static int wm831x_spi_suspend(struct device *dev)
68 return wm831x_device_suspend(wm831x); 68 return wm831x_device_suspend(wm831x);
69} 69}
70 70
71static void wm831x_spi_shutdown(struct spi_device *spi)
72{
73 struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
74
75 wm831x_device_shutdown(wm831x);
76}
77
71static const struct dev_pm_ops wm831x_spi_pm = { 78static const struct dev_pm_ops wm831x_spi_pm = {
72 .freeze = wm831x_spi_suspend, 79 .freeze = wm831x_spi_suspend,
73 .suspend = wm831x_spi_suspend, 80 .suspend = wm831x_spi_suspend,
@@ -95,6 +102,7 @@ static struct spi_driver wm831x_spi_driver = {
95 .id_table = wm831x_spi_ids, 102 .id_table = wm831x_spi_ids,
96 .probe = wm831x_spi_probe, 103 .probe = wm831x_spi_probe,
97 .remove = __devexit_p(wm831x_spi_remove), 104 .remove = __devexit_p(wm831x_spi_remove),
105 .shutdown = wm831x_spi_shutdown,
98}; 106};
99 107
100static int __init wm831x_spi_init(void) 108static int __init wm831x_spi_init(void)
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index 44acdb25681b..ed8fe0d04097 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -371,6 +371,8 @@ struct wm831x {
371 int irq_masks_cur[WM831X_NUM_IRQ_REGS]; /* Currently active value */ 371 int irq_masks_cur[WM831X_NUM_IRQ_REGS]; /* Currently active value */
372 int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */ 372 int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */
373 373
374 bool soft_shutdown;
375
374 /* Chip revision based flags */ 376 /* Chip revision based flags */
375 unsigned has_gpio_ena:1; /* Has GPIO enable bit */ 377 unsigned has_gpio_ena:1; /* Has GPIO enable bit */
376 unsigned has_cs_sts:1; /* Has current sink status bit */ 378 unsigned has_cs_sts:1; /* Has current sink status bit */
@@ -409,6 +411,7 @@ int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
409int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq); 411int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq);
410void wm831x_device_exit(struct wm831x *wm831x); 412void wm831x_device_exit(struct wm831x *wm831x);
411int wm831x_device_suspend(struct wm831x *wm831x); 413int wm831x_device_suspend(struct wm831x *wm831x);
414void wm831x_device_shutdown(struct wm831x *wm831x);
412int wm831x_irq_init(struct wm831x *wm831x, int irq); 415int wm831x_irq_init(struct wm831x *wm831x, int irq);
413void wm831x_irq_exit(struct wm831x *wm831x); 416void wm831x_irq_exit(struct wm831x *wm831x);
414void wm831x_auxadc_init(struct wm831x *wm831x); 417void wm831x_auxadc_init(struct wm831x *wm831x);
diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h
index 0ba24599fe51..1d7a3f7b3b5d 100644
--- a/include/linux/mfd/wm831x/pdata.h
+++ b/include/linux/mfd/wm831x/pdata.h
@@ -123,6 +123,9 @@ struct wm831x_pdata {
123 /** Disable the touchscreen */ 123 /** Disable the touchscreen */
124 bool disable_touch; 124 bool disable_touch;
125 125
126 /** The driver should initiate a power off sequence during shutdown */
127 bool soft_shutdown;
128
126 int irq_base; 129 int irq_base;
127 int gpio_base; 130 int gpio_base;
128 int gpio_defaults[WM831X_GPIO_NUM]; 131 int gpio_defaults[WM831X_GPIO_NUM];