aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-09-15 12:54:53 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2011-10-24 08:09:13 -0400
commit5da721c87aee3d94cfc48384073c2ec51a0b9a3b (patch)
tree8204a041df21dd6364728d9915af3a142a88ad1b /drivers/mfd
parentf09ee0451a44a4e913a7c3cec3805508f7de6c54 (diff)
mfd: Support software initiated shutdown of WM831x PMICs
In systems where there is no hardware signal from the processor to the PMIC to initiate the final power off sequence we must initiate the shutdown with a register write to the PMIC. Support such systems in the driver. Since this may prevent a full shutdown of the system platform data is used to enable the feature. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/wm831x-core.c11
-rw-r--r--drivers/mfd/wm831x-i2c.c8
-rw-r--r--drivers/mfd/wm831x-spi.c8
3 files changed, 27 insertions, 0 deletions
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 282e76ab678f..099b6104d150 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -24,6 +24,7 @@
24#include <linux/mfd/wm831x/irq.h> 24#include <linux/mfd/wm831x/irq.h>
25#include <linux/mfd/wm831x/auxadc.h> 25#include <linux/mfd/wm831x/auxadc.h>
26#include <linux/mfd/wm831x/otp.h> 26#include <linux/mfd/wm831x/otp.h>
27#include <linux/mfd/wm831x/pmu.h>
27#include <linux/mfd/wm831x/regulator.h> 28#include <linux/mfd/wm831x/regulator.h>
28 29
29/* Current settings - values are 2*2^(reg_val/4) microamps. These are 30/* Current settings - values are 2*2^(reg_val/4) microamps. These are
@@ -1305,6 +1306,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1305 mutex_init(&wm831x->io_lock); 1306 mutex_init(&wm831x->io_lock);
1306 mutex_init(&wm831x->key_lock); 1307 mutex_init(&wm831x->key_lock);
1307 dev_set_drvdata(wm831x->dev, wm831x); 1308 dev_set_drvdata(wm831x->dev, wm831x);
1309 wm831x->soft_shutdown = pdata->soft_shutdown;
1308 1310
1309 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID); 1311 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
1310 if (ret < 0) { 1312 if (ret < 0) {
@@ -1604,6 +1606,15 @@ int wm831x_device_suspend(struct wm831x *wm831x)
1604 return 0; 1606 return 0;
1605} 1607}
1606 1608
1609void wm831x_device_shutdown(struct wm831x *wm831x)
1610{
1611 if (wm831x->soft_shutdown) {
1612 dev_info(wm831x->dev, "Initiating shutdown...\n");
1613 wm831x_set_bits(wm831x, WM831X_POWER_STATE, WM831X_CHIP_ON, 0);
1614 }
1615}
1616EXPORT_SYMBOL_GPL(wm831x_device_shutdown);
1617
1607MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC"); 1618MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC");
1608MODULE_LICENSE("GPL"); 1619MODULE_LICENSE("GPL");
1609MODULE_AUTHOR("Mark Brown"); 1620MODULE_AUTHOR("Mark Brown");
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
index a06cbc739716..3ff8c13db2a8 100644
--- a/drivers/mfd/wm831x-i2c.c
+++ b/drivers/mfd/wm831x-i2c.c
@@ -109,6 +109,13 @@ static int wm831x_i2c_suspend(struct device *dev)
109 return wm831x_device_suspend(wm831x); 109 return wm831x_device_suspend(wm831x);
110} 110}
111 111
112static void wm831x_i2c_shutdown(struct i2c_client *i2c)
113{
114 struct wm831x *wm831x = i2c_get_clientdata(i2c);
115
116 wm831x_device_shutdown(wm831x);
117}
118
112static const struct i2c_device_id wm831x_i2c_id[] = { 119static const struct i2c_device_id wm831x_i2c_id[] = {
113 { "wm8310", WM8310 }, 120 { "wm8310", WM8310 },
114 { "wm8311", WM8311 }, 121 { "wm8311", WM8311 },
@@ -133,6 +140,7 @@ static struct i2c_driver wm831x_i2c_driver = {
133 }, 140 },
134 .probe = wm831x_i2c_probe, 141 .probe = wm831x_i2c_probe,
135 .remove = wm831x_i2c_remove, 142 .remove = wm831x_i2c_remove,
143 .shutdown = wm831x_i2c_shutdown,
136 .id_table = wm831x_i2c_id, 144 .id_table = wm831x_i2c_id,
137}; 145};
138 146
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index eed8e4f7a5a1..8e8138ba0267 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -121,6 +121,13 @@ static int wm831x_spi_suspend(struct device *dev)
121 return wm831x_device_suspend(wm831x); 121 return wm831x_device_suspend(wm831x);
122} 122}
123 123
124static void wm831x_spi_shutdown(struct spi_device *spi)
125{
126 struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
127
128 wm831x_device_shutdown(wm831x);
129}
130
124static const struct dev_pm_ops wm831x_spi_pm = { 131static const struct dev_pm_ops wm831x_spi_pm = {
125 .freeze = wm831x_spi_suspend, 132 .freeze = wm831x_spi_suspend,
126 .suspend = wm831x_spi_suspend, 133 .suspend = wm831x_spi_suspend,
@@ -146,6 +153,7 @@ static struct spi_driver wm8311_spi_driver = {
146 }, 153 },
147 .probe = wm831x_spi_probe, 154 .probe = wm831x_spi_probe,
148 .remove = __devexit_p(wm831x_spi_remove), 155 .remove = __devexit_p(wm831x_spi_remove),
156 .shutdown = wm831x_spi_shutdown,
149}; 157};
150 158
151static struct spi_driver wm8312_spi_driver = { 159static struct spi_driver wm8312_spi_driver = {