aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.wolfsonmicro.com>2015-04-07 06:34:50 -0400
committerMark Brown <broonie@kernel.org>2015-04-07 07:36:19 -0400
commit7e5ee1c33e9ce4e4be0a6b8955c760e9a41a9e84 (patch)
tree8ae7f4d7d8567f94d8f063609dfe09d26882f6d8 /sound
parent45ad3e67f663af3f7988552165e8b8ebddde0ac7 (diff)
ASoC: wm8804: Add support for hardware reset line
It is best to use the physical reset if it is available. This patch adds support for a GPIO controlled physical reset for the chip. Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/wm8804.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index f44da83f50dc..cc168c4a4be0 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/gpio/consumer.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18#include <linux/of_device.h> 19#include <linux/of_device.h>
@@ -61,6 +62,8 @@ struct wm8804_priv {
61 struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES]; 62 struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
62 struct notifier_block disable_nb[WM8804_NUM_SUPPLIES]; 63 struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
63 int mclk_div; 64 int mclk_div;
65
66 struct gpio_desc *reset;
64}; 67};
65 68
66static int txsrc_get(struct snd_kcontrol *kcontrol, 69static int txsrc_get(struct snd_kcontrol *kcontrol,
@@ -182,7 +185,7 @@ static bool wm8804_volatile(struct device *dev, unsigned int reg)
182 } 185 }
183} 186}
184 187
185static int wm8804_reset(struct wm8804_priv *wm8804) 188static int wm8804_soft_reset(struct wm8804_priv *wm8804)
186{ 189{
187 return regmap_write(wm8804->regmap, WM8804_RST_DEVID1, 0x0); 190 return regmap_write(wm8804->regmap, WM8804_RST_DEVID1, 0x0);
188} 191}
@@ -586,6 +589,14 @@ int wm8804_probe(struct device *dev, struct regmap *regmap)
586 589
587 wm8804->regmap = regmap; 590 wm8804->regmap = regmap;
588 591
592 wm8804->reset = devm_gpiod_get_optional(dev, "wlf,reset",
593 GPIOD_OUT_LOW);
594 if (IS_ERR(wm8804->reset)) {
595 ret = PTR_ERR(wm8804->reset);
596 dev_err(dev, "Failed to get reset line: %d\n", ret);
597 return ret;
598 }
599
589 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) 600 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++)
590 wm8804->supplies[i].supply = wm8804_supply_names[i]; 601 wm8804->supplies[i].supply = wm8804_supply_names[i];
591 602
@@ -620,6 +631,9 @@ int wm8804_probe(struct device *dev, struct regmap *regmap)
620 return ret; 631 return ret;
621 } 632 }
622 633
634 if (wm8804->reset)
635 gpiod_set_value_cansleep(wm8804->reset, 1);
636
623 ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1); 637 ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1);
624 if (ret < 0) { 638 if (ret < 0) {
625 dev_err(dev, "Failed to read device ID: %d\n", ret); 639 dev_err(dev, "Failed to read device ID: %d\n", ret);
@@ -648,10 +662,12 @@ int wm8804_probe(struct device *dev, struct regmap *regmap)
648 } 662 }
649 dev_info(dev, "revision %c\n", id1 + 'A'); 663 dev_info(dev, "revision %c\n", id1 + 'A');
650 664
651 ret = wm8804_reset(wm8804); 665 if (!wm8804->reset) {
652 if (ret < 0) { 666 ret = wm8804_soft_reset(wm8804);
653 dev_err(dev, "Failed to issue reset: %d\n", ret); 667 if (ret < 0) {
654 goto err_reg_enable; 668 dev_err(dev, "Failed to issue reset: %d\n", ret);
669 goto err_reg_enable;
670 }
655 } 671 }
656 672
657 ret = snd_soc_register_codec(dev, &soc_codec_dev_wm8804, 673 ret = snd_soc_register_codec(dev, &soc_codec_dev_wm8804,