diff options
| -rw-r--r-- | drivers/mfd/wm831x-core.c | 11 | ||||
| -rw-r--r-- | drivers/mfd/wm831x-i2c.c | 8 | ||||
| -rw-r--r-- | drivers/mfd/wm831x-spi.c | 8 | ||||
| -rw-r--r-- | include/linux/mfd/wm831x/core.h | 3 | ||||
| -rw-r--r-- | include/linux/mfd/wm831x/pdata.h | 3 |
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 | ||
| 1927 | void 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 | } | ||
| 1934 | EXPORT_SYMBOL_GPL(wm831x_device_shutdown); | ||
| 1935 | |||
| 1925 | MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC"); | 1936 | MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC"); |
| 1926 | MODULE_LICENSE("GPL"); | 1937 | MODULE_LICENSE("GPL"); |
| 1927 | MODULE_AUTHOR("Mark Brown"); | 1938 | MODULE_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 | ||
| 68 | static 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 | |||
| 68 | static const struct i2c_device_id wm831x_i2c_id[] = { | 75 | static 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 | ||
| 71 | static 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 | |||
| 71 | static const struct dev_pm_ops wm831x_spi_pm = { | 78 | static 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 | ||
| 100 | static int __init wm831x_spi_init(void) | 108 | static 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, | |||
| 409 | int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq); | 411 | int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq); |
| 410 | void wm831x_device_exit(struct wm831x *wm831x); | 412 | void wm831x_device_exit(struct wm831x *wm831x); |
| 411 | int wm831x_device_suspend(struct wm831x *wm831x); | 413 | int wm831x_device_suspend(struct wm831x *wm831x); |
| 414 | void wm831x_device_shutdown(struct wm831x *wm831x); | ||
| 412 | int wm831x_irq_init(struct wm831x *wm831x, int irq); | 415 | int wm831x_irq_init(struct wm831x *wm831x, int irq); |
| 413 | void wm831x_irq_exit(struct wm831x *wm831x); | 416 | void wm831x_irq_exit(struct wm831x *wm831x); |
| 414 | void wm831x_auxadc_init(struct wm831x *wm831x); | 417 | void 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]; |
