diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-07-12 06:47:59 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-07-13 11:38:22 -0400 |
commit | c7ebf932e5afa9caf8720435519b857b5d6e63bc (patch) | |
tree | 6ddfd65bd572b2680782480a4d521095d7af40de /sound/soc/codecs/wm8994.c | |
parent | b30ead5f391d34c6011e6affe88eb21bb0b9f9dd (diff) |
ASoC: Use WM8994 FLL lock interrupt
If we have interrupts then wait for the FLL lock interrupt rather than
using dead reckoning when waiting for the FLL to start.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r-- | sound/soc/codecs/wm8994.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index d2dcaa29c7ca..f89ae47f3c32 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -1635,6 +1635,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
1635 | int reg_offset, ret; | 1635 | int reg_offset, ret; |
1636 | struct fll_div fll; | 1636 | struct fll_div fll; |
1637 | u16 reg, aif1, aif2; | 1637 | u16 reg, aif1, aif2; |
1638 | unsigned long timeout; | ||
1638 | 1639 | ||
1639 | aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) | 1640 | aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) |
1640 | & WM8994_AIF1CLK_ENA; | 1641 | & WM8994_AIF1CLK_ENA; |
@@ -1726,7 +1727,15 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
1726 | WM8994_FLL1_ENA | WM8994_FLL1_FRAC, | 1727 | WM8994_FLL1_ENA | WM8994_FLL1_FRAC, |
1727 | reg); | 1728 | reg); |
1728 | 1729 | ||
1729 | msleep(5); | 1730 | if (wm8994->fll_locked_irq) { |
1731 | timeout = wait_for_completion_timeout(&wm8994->fll_locked[id], | ||
1732 | msecs_to_jiffies(10)); | ||
1733 | if (timeout == 0) | ||
1734 | dev_warn(codec->dev, | ||
1735 | "Timed out waiting for FLL lock\n"); | ||
1736 | } else { | ||
1737 | msleep(5); | ||
1738 | } | ||
1730 | } | 1739 | } |
1731 | 1740 | ||
1732 | wm8994->fll[id].in = freq_in; | 1741 | wm8994->fll[id].in = freq_in; |
@@ -1744,6 +1753,14 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
1744 | return 0; | 1753 | return 0; |
1745 | } | 1754 | } |
1746 | 1755 | ||
1756 | static irqreturn_t wm8994_fll_locked_irq(int irq, void *data) | ||
1757 | { | ||
1758 | struct completion *completion = data; | ||
1759 | |||
1760 | complete(completion); | ||
1761 | |||
1762 | return IRQ_HANDLED; | ||
1763 | } | ||
1747 | 1764 | ||
1748 | static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 }; | 1765 | static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 }; |
1749 | 1766 | ||
@@ -2879,6 +2896,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
2879 | wm8994->pdata = dev_get_platdata(codec->dev->parent); | 2896 | wm8994->pdata = dev_get_platdata(codec->dev->parent); |
2880 | wm8994->codec = codec; | 2897 | wm8994->codec = codec; |
2881 | 2898 | ||
2899 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | ||
2900 | init_completion(&wm8994->fll_locked[i]); | ||
2901 | |||
2882 | if (wm8994->pdata && wm8994->pdata->micdet_irq) | 2902 | if (wm8994->pdata && wm8994->pdata->micdet_irq) |
2883 | wm8994->micdet_irq = wm8994->pdata->micdet_irq; | 2903 | wm8994->micdet_irq = wm8994->pdata->micdet_irq; |
2884 | else if (wm8994->pdata && wm8994->pdata->irq_base) | 2904 | else if (wm8994->pdata && wm8994->pdata->irq_base) |
@@ -2994,6 +3014,16 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
2994 | } | 3014 | } |
2995 | } | 3015 | } |
2996 | 3016 | ||
3017 | wm8994->fll_locked_irq = true; | ||
3018 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) { | ||
3019 | ret = wm8994_request_irq(codec->control_data, | ||
3020 | WM8994_IRQ_FLL1_LOCK + i, | ||
3021 | wm8994_fll_locked_irq, "FLL lock", | ||
3022 | &wm8994->fll_locked[i]); | ||
3023 | if (ret != 0) | ||
3024 | wm8994->fll_locked_irq = false; | ||
3025 | } | ||
3026 | |||
2997 | /* Remember if AIFnLRCLK is configured as a GPIO. This should be | 3027 | /* Remember if AIFnLRCLK is configured as a GPIO. This should be |
2998 | * configured on init - if a system wants to do this dynamically | 3028 | * configured on init - if a system wants to do this dynamically |
2999 | * at runtime we can deal with that then. | 3029 | * at runtime we can deal with that then. |
@@ -3179,6 +3209,9 @@ err_irq: | |||
3179 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); | 3209 | wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); |
3180 | if (wm8994->micdet_irq) | 3210 | if (wm8994->micdet_irq) |
3181 | free_irq(wm8994->micdet_irq, wm8994); | 3211 | free_irq(wm8994->micdet_irq, wm8994); |
3212 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | ||
3213 | wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i, | ||
3214 | &wm8994->fll_locked[i]); | ||
3182 | wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3215 | wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, |
3183 | &wm8994->hubs); | 3216 | &wm8994->hubs); |
3184 | err: | 3217 | err: |
@@ -3190,11 +3223,16 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) | |||
3190 | { | 3223 | { |
3191 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 3224 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
3192 | struct wm8994 *control = codec->control_data; | 3225 | struct wm8994 *control = codec->control_data; |
3226 | int i; | ||
3193 | 3227 | ||
3194 | wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); | 3228 | wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); |
3195 | 3229 | ||
3196 | pm_runtime_disable(codec->dev); | 3230 | pm_runtime_disable(codec->dev); |
3197 | 3231 | ||
3232 | for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) | ||
3233 | wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i, | ||
3234 | &wm8994->fll_locked[i]); | ||
3235 | |||
3198 | wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3236 | wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, |
3199 | &wm8994->hubs); | 3237 | &wm8994->hubs); |
3200 | 3238 | ||