diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-02-03 06:51:42 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-02-04 05:41:09 -0500 |
commit | b37e399bfc7fcb5b523e3e2e74686c8cc95c0cba (patch) | |
tree | ac502e0469dbd048699cf71e0e07a7dad3bd902b /sound/soc/codecs/wm8993.c | |
parent | 3bf6e4217e3c69438f6dc41a009664107eb27ab1 (diff) |
ASoC: Initial WM8993 regulator API hookup
At the minute the regulators are simply enabled for the entire
lifetime of the device.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/codecs/wm8993.c')
-rw-r--r-- | sound/soc/codecs/wm8993.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 3c9336cd4eeb..e97b3f45b24b 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/regulator/consumer.h> | ||
19 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
20 | #include <sound/core.h> | 21 | #include <sound/core.h> |
21 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
@@ -29,6 +30,16 @@ | |||
29 | #include "wm8993.h" | 30 | #include "wm8993.h" |
30 | #include "wm_hubs.h" | 31 | #include "wm_hubs.h" |
31 | 32 | ||
33 | #define WM8993_NUM_SUPPLIES 6 | ||
34 | static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = { | ||
35 | "DCVDD", | ||
36 | "DBVDD", | ||
37 | "AVDD1", | ||
38 | "AVDD2", | ||
39 | "CPVDD", | ||
40 | "SPKVDD", | ||
41 | }; | ||
42 | |||
32 | static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { | 43 | static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { |
33 | 0x8993, /* R0 - Software Reset */ | 44 | 0x8993, /* R0 - Software Reset */ |
34 | 0x0000, /* R1 - Power Management (1) */ | 45 | 0x0000, /* R1 - Power Management (1) */ |
@@ -215,6 +226,7 @@ static struct { | |||
215 | struct wm8993_priv { | 226 | struct wm8993_priv { |
216 | struct wm_hubs_data hubs_data; | 227 | struct wm_hubs_data hubs_data; |
217 | u16 reg_cache[WM8993_REGISTER_COUNT]; | 228 | u16 reg_cache[WM8993_REGISTER_COUNT]; |
229 | struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; | ||
218 | struct wm8993_platform_data pdata; | 230 | struct wm8993_platform_data pdata; |
219 | struct snd_soc_codec codec; | 231 | struct snd_soc_codec codec; |
220 | int master; | 232 | int master; |
@@ -1496,6 +1508,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1496 | struct snd_soc_codec *codec; | 1508 | struct snd_soc_codec *codec; |
1497 | unsigned int val; | 1509 | unsigned int val; |
1498 | int ret; | 1510 | int ret; |
1511 | int i; | ||
1499 | 1512 | ||
1500 | if (wm8993_codec) { | 1513 | if (wm8993_codec) { |
1501 | dev_err(&i2c->dev, "A WM8993 is already registered\n"); | 1514 | dev_err(&i2c->dev, "A WM8993 is already registered\n"); |
@@ -1543,16 +1556,33 @@ static int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1543 | 1556 | ||
1544 | codec->dev = &i2c->dev; | 1557 | codec->dev = &i2c->dev; |
1545 | 1558 | ||
1559 | for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) | ||
1560 | wm8993->supplies[i].supply = wm8993_supply_names[i]; | ||
1561 | |||
1562 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies), | ||
1563 | wm8993->supplies); | ||
1564 | if (ret != 0) { | ||
1565 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
1566 | goto err; | ||
1567 | } | ||
1568 | |||
1569 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), | ||
1570 | wm8993->supplies); | ||
1571 | if (ret != 0) { | ||
1572 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | ||
1573 | goto err_get; | ||
1574 | } | ||
1575 | |||
1546 | val = snd_soc_read(codec, WM8993_SOFTWARE_RESET); | 1576 | val = snd_soc_read(codec, WM8993_SOFTWARE_RESET); |
1547 | if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { | 1577 | if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { |
1548 | dev_err(codec->dev, "Invalid ID register value %x\n", val); | 1578 | dev_err(codec->dev, "Invalid ID register value %x\n", val); |
1549 | ret = -EINVAL; | 1579 | ret = -EINVAL; |
1550 | goto err; | 1580 | goto err_enable; |
1551 | } | 1581 | } |
1552 | 1582 | ||
1553 | ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff); | 1583 | ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff); |
1554 | if (ret != 0) | 1584 | if (ret != 0) |
1555 | goto err; | 1585 | goto err_enable; |
1556 | 1586 | ||
1557 | /* By default we're using the output mixers */ | 1587 | /* By default we're using the output mixers */ |
1558 | wm8993->class_w_users = 2; | 1588 | wm8993->class_w_users = 2; |
@@ -1582,7 +1612,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1582 | 1612 | ||
1583 | ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1613 | ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1584 | if (ret != 0) | 1614 | if (ret != 0) |
1585 | goto err; | 1615 | goto err_enable; |
1586 | 1616 | ||
1587 | wm8993_dai.dev = codec->dev; | 1617 | wm8993_dai.dev = codec->dev; |
1588 | 1618 | ||
@@ -1596,6 +1626,10 @@ static int wm8993_i2c_probe(struct i2c_client *i2c, | |||
1596 | 1626 | ||
1597 | err_bias: | 1627 | err_bias: |
1598 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1628 | wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1629 | err_enable: | ||
1630 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1631 | err_get: | ||
1632 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1599 | err: | 1633 | err: |
1600 | wm8993_codec = NULL; | 1634 | wm8993_codec = NULL; |
1601 | kfree(wm8993); | 1635 | kfree(wm8993); |
@@ -1610,6 +1644,7 @@ static int wm8993_i2c_remove(struct i2c_client *client) | |||
1610 | snd_soc_unregister_dai(&wm8993_dai); | 1644 | snd_soc_unregister_dai(&wm8993_dai); |
1611 | 1645 | ||
1612 | wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF); | 1646 | wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF); |
1647 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1613 | kfree(wm8993); | 1648 | kfree(wm8993); |
1614 | 1649 | ||
1615 | return 0; | 1650 | return 0; |