summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2017-03-20 05:13:52 -0400
committerMark Brown <broonie@kernel.org>2017-03-20 07:24:05 -0400
commitb3bbef45e97526e8c56fd542d75e505776eecc01 (patch)
tree6c766b496c4d13b6b0f59f373ac878ef679f0723
parenta5de5b74a50113564a1e0850e2da96c37c35e55d (diff)
ASoC: wm8903: add regulator handling
The WM8903 has four different voltage inputs: AVDD, CPVDD, DBVDD and DCVDD. On the Qualcomm APQ8060 Dragonboard these are all supplied from proper regulators and thus need activating and binding. This is a quick-and-dirty solution just grabbing and enabling the regulator supplies on probe() and disabling them on remove() and the errorpath. More elaborate power management is likely possible. I assume the nVidia designs using this codec have some hard-wired always-on power and will be happy with using the dummy regulators for this. But someone from the nVidia camp should probably check whether they can bind these to proper regulators instead. We also amend the DT binding document. A small change like this does not warrant a separate patch for augmenting these. Cc: devicetree@vger.kernel.org Cc: Mark Brown <broonie@kernel.org> Cc: Liam Girdwood <lgirdwood@gmail.com> Cc: Stephen Warren <swarren@nvidia.com> Cc: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/sound/wm8903.txt13
-rw-r--r--sound/soc/codecs/wm8903.c31
2 files changed, 44 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/wm8903.txt b/Documentation/devicetree/bindings/sound/wm8903.txt
index 94ec32c194bb..afc51caf1137 100644
--- a/Documentation/devicetree/bindings/sound/wm8903.txt
+++ b/Documentation/devicetree/bindings/sound/wm8903.txt
@@ -28,6 +28,14 @@ Optional properties:
28 performed. If any entry has the value 0xffffffff, that GPIO's 28 performed. If any entry has the value 0xffffffff, that GPIO's
29 configuration will not be modified. 29 configuration will not be modified.
30 30
31 - AVDD-supply : Analog power supply regulator on the AVDD pin.
32
33 - CPVDD-supply : Charge pump supply regulator on the CPVDD pin.
34
35 - DBVDD-supply : Digital buffer supply regulator for the DBVDD pin.
36
37 - DCVDD-supply : Digital core supply regulator for the DCVDD pin.
38
31Pins on the device (for linking into audio routes): 39Pins on the device (for linking into audio routes):
32 40
33 * IN1L 41 * IN1L
@@ -54,6 +62,11 @@ codec: wm8903@1a {
54 reg = <0x1a>; 62 reg = <0x1a>;
55 interrupts = < 347 >; 63 interrupts = < 347 >;
56 64
65 AVDD-supply = <&fooreg_a>;
66 CPVDD-supply = <&fooreg_b>;
67 DBVDD-supply = <&fooreg_c>;
68 DCVDC-supply = <&fooreg_d>;
69
57 gpio-controller; 70 gpio-controller;
58 #gpio-cells = <2>; 71 #gpio-cells = <2>;
59 72
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 6e887c2c42b1..237eeb9a8b97 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -24,6 +24,7 @@
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/regmap.h> 26#include <linux/regmap.h>
27#include <linux/regulator/consumer.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
28#include <linux/irq.h> 29#include <linux/irq.h>
29#include <linux/mutex.h> 30#include <linux/mutex.h>
@@ -115,10 +116,19 @@ static const struct reg_default wm8903_reg_defaults[] = {
115 { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */ 116 { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */
116}; 117};
117 118
119#define WM8903_NUM_SUPPLIES 4
120static const char *wm8903_supply_names[WM8903_NUM_SUPPLIES] = {
121 "AVDD",
122 "CPVDD",
123 "DBVDD",
124 "DCVDD",
125};
126
118struct wm8903_priv { 127struct wm8903_priv {
119 struct wm8903_platform_data *pdata; 128 struct wm8903_platform_data *pdata;
120 struct device *dev; 129 struct device *dev;
121 struct regmap *regmap; 130 struct regmap *regmap;
131 struct regulator_bulk_data supplies[WM8903_NUM_SUPPLIES];
122 132
123 int sysclk; 133 int sysclk;
124 int irq; 134 int irq;
@@ -2030,6 +2040,23 @@ static int wm8903_i2c_probe(struct i2c_client *i2c,
2030 2040
2031 pdata = wm8903->pdata; 2041 pdata = wm8903->pdata;
2032 2042
2043 for (i = 0; i < ARRAY_SIZE(wm8903->supplies); i++)
2044 wm8903->supplies[i].supply = wm8903_supply_names[i];
2045
2046 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8903->supplies),
2047 wm8903->supplies);
2048 if (ret != 0) {
2049 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
2050 return ret;
2051 }
2052
2053 ret = regulator_bulk_enable(ARRAY_SIZE(wm8903->supplies),
2054 wm8903->supplies);
2055 if (ret != 0) {
2056 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
2057 return ret;
2058 }
2059
2033 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val); 2060 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val);
2034 if (ret != 0) { 2061 if (ret != 0) {
2035 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); 2062 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
@@ -2160,6 +2187,8 @@ static int wm8903_i2c_probe(struct i2c_client *i2c,
2160 2187
2161 return 0; 2188 return 0;
2162err: 2189err:
2190 regulator_bulk_disable(ARRAY_SIZE(wm8903->supplies),
2191 wm8903->supplies);
2163 return ret; 2192 return ret;
2164} 2193}
2165 2194
@@ -2167,6 +2196,8 @@ static int wm8903_i2c_remove(struct i2c_client *client)
2167{ 2196{
2168 struct wm8903_priv *wm8903 = i2c_get_clientdata(client); 2197 struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
2169 2198
2199 regulator_bulk_disable(ARRAY_SIZE(wm8903->supplies),
2200 wm8903->supplies);
2170 if (client->irq) 2201 if (client->irq)
2171 free_irq(client->irq, wm8903); 2202 free_irq(client->irq, wm8903);
2172 wm8903_free_gpio(wm8903); 2203 wm8903_free_gpio(wm8903);