diff options
| author | Charles Keepax <ckeepax@opensource.wolfsonmicro.com> | 2015-04-07 06:34:50 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2015-04-07 07:36:19 -0400 |
| commit | 7e5ee1c33e9ce4e4be0a6b8955c760e9a41a9e84 (patch) | |
| tree | 8ae7f4d7d8567f94d8f063609dfe09d26882f6d8 | |
| parent | 45ad3e67f663af3f7988552165e8b8ebddde0ac7 (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>
| -rw-r--r-- | sound/soc/codecs/wm8804.c | 26 |
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 | ||
| 66 | static int txsrc_get(struct snd_kcontrol *kcontrol, | 69 | static 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 | ||
| 185 | static int wm8804_reset(struct wm8804_priv *wm8804) | 188 | static 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, |
