aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8994.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r--sound/soc/codecs/wm8994.c153
1 files changed, 133 insertions, 20 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 83014a7c2e1..fa0a48066aa 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -56,7 +56,7 @@ static int wm8994_retune_mobile_base[] = {
56static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) 56static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
57{ 57{
58 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 58 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
59 struct wm8994 *control = wm8994->control_data; 59 struct wm8994 *control = codec->control_data;
60 60
61 switch (reg) { 61 switch (reg) {
62 case WM8994_GPIO_1: 62 case WM8994_GPIO_1:
@@ -195,10 +195,6 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
195 aif + 1, rate); 195 aif + 1, rate);
196 } 196 }
197 197
198 if (rate && rate < 3000000)
199 dev_warn(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n",
200 aif + 1, rate);
201
202 wm8994->aifclk[aif] = rate; 198 wm8994->aifclk[aif] = rate;
203 199
204 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset, 200 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
@@ -1146,13 +1142,33 @@ SND_SOC_DAPM_PGA_E("Late DAC2L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1146 late_enable_ev, SND_SOC_DAPM_PRE_PMU), 1142 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1147SND_SOC_DAPM_PGA_E("Late DAC2R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, 1143SND_SOC_DAPM_PGA_E("Late DAC2R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1148 late_enable_ev, SND_SOC_DAPM_PRE_PMU), 1144 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1145SND_SOC_DAPM_PGA_E("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0,
1146 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1147
1148SND_SOC_DAPM_MIXER_E("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
1149 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer),
1150 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1151SND_SOC_DAPM_MIXER_E("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
1152 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer),
1153 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1154SND_SOC_DAPM_MUX_E("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux,
1155 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1156SND_SOC_DAPM_MUX_E("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux,
1157 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1149 1158
1150SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) 1159SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)
1151}; 1160};
1152 1161
1153static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { 1162static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
1154SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), 1163SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
1155SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0) 1164SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
1165SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
1166SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
1167 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
1168SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
1169 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
1170SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1171SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1156}; 1172};
1157 1173
1158static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = { 1174static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = {
@@ -1266,7 +1282,7 @@ SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
1266SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), 1282SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
1267 1283
1268SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), 1284SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
1269SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), 1285SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
1270 1286
1271SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), 1287SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
1272 1288
@@ -1282,14 +1298,6 @@ SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
1282SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0), 1298SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
1283SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), 1299SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
1284 1300
1285SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1286SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1287
1288SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
1289 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
1290SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
1291 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
1292
1293SND_SOC_DAPM_POST("Debug log", post_ev), 1301SND_SOC_DAPM_POST("Debug log", post_ev),
1294}; 1302};
1295 1303
@@ -1624,6 +1632,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1624 int reg_offset, ret; 1632 int reg_offset, ret;
1625 struct fll_div fll; 1633 struct fll_div fll;
1626 u16 reg, aif1, aif2; 1634 u16 reg, aif1, aif2;
1635 unsigned long timeout;
1627 1636
1628 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) 1637 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
1629 & WM8994_AIF1CLK_ENA; 1638 & WM8994_AIF1CLK_ENA;
@@ -1705,6 +1714,9 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1705 (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | 1714 (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
1706 (src - 1)); 1715 (src - 1));
1707 1716
1717 /* Clear any pending completion from a previous failure */
1718 try_wait_for_completion(&wm8994->fll_locked[id]);
1719
1708 /* Enable (with fractional mode if required) */ 1720 /* Enable (with fractional mode if required) */
1709 if (freq_out) { 1721 if (freq_out) {
1710 if (fll.k) 1722 if (fll.k)
@@ -1715,7 +1727,15 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1715 WM8994_FLL1_ENA | WM8994_FLL1_FRAC, 1727 WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
1716 reg); 1728 reg);
1717 1729
1718 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 }
1719 } 1739 }
1720 1740
1721 wm8994->fll[id].in = freq_in; 1741 wm8994->fll[id].in = freq_in;
@@ -1733,6 +1753,14 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1733 return 0; 1753 return 0;
1734} 1754}
1735 1755
1756static 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}
1736 1764
1737static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 }; 1765static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
1738 1766
@@ -2272,6 +2300,33 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
2272 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); 2300 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
2273} 2301}
2274 2302
2303static void wm8994_aif_shutdown(struct snd_pcm_substream *substream,
2304 struct snd_soc_dai *dai)
2305{
2306 struct snd_soc_codec *codec = dai->codec;
2307 int rate_reg = 0;
2308
2309 switch (dai->id) {
2310 case 1:
2311 rate_reg = WM8994_AIF1_RATE;
2312 break;
2313 case 2:
2314 rate_reg = WM8994_AIF2_RATE;
2315 break;
2316 default:
2317 break;
2318 }
2319
2320 /* If the DAI is idle then configure the divider tree for the
2321 * lowest output rate to save a little power if the clock is
2322 * still active (eg, because it is system clock).
2323 */
2324 if (rate_reg && !dai->playback_active && !dai->capture_active)
2325 snd_soc_update_bits(codec, rate_reg,
2326 WM8994_AIF1_SR_MASK |
2327 WM8994_AIF1CLK_RATE_MASK, 0x9);
2328}
2329
2275static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) 2330static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
2276{ 2331{
2277 struct snd_soc_codec *codec = codec_dai->codec; 2332 struct snd_soc_codec *codec = codec_dai->codec;
@@ -2338,6 +2393,7 @@ static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
2338 .set_sysclk = wm8994_set_dai_sysclk, 2393 .set_sysclk = wm8994_set_dai_sysclk,
2339 .set_fmt = wm8994_set_dai_fmt, 2394 .set_fmt = wm8994_set_dai_fmt,
2340 .hw_params = wm8994_hw_params, 2395 .hw_params = wm8994_hw_params,
2396 .shutdown = wm8994_aif_shutdown,
2341 .digital_mute = wm8994_aif_mute, 2397 .digital_mute = wm8994_aif_mute,
2342 .set_pll = wm8994_set_fll, 2398 .set_pll = wm8994_set_fll,
2343 .set_tristate = wm8994_set_tristate, 2399 .set_tristate = wm8994_set_tristate,
@@ -2347,6 +2403,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
2347 .set_sysclk = wm8994_set_dai_sysclk, 2403 .set_sysclk = wm8994_set_dai_sysclk,
2348 .set_fmt = wm8994_set_dai_fmt, 2404 .set_fmt = wm8994_set_dai_fmt,
2349 .hw_params = wm8994_hw_params, 2405 .hw_params = wm8994_hw_params,
2406 .shutdown = wm8994_aif_shutdown,
2350 .digital_mute = wm8994_aif_mute, 2407 .digital_mute = wm8994_aif_mute,
2351 .set_pll = wm8994_set_fll, 2408 .set_pll = wm8994_set_fll,
2352 .set_tristate = wm8994_set_tristate, 2409 .set_tristate = wm8994_set_tristate,
@@ -2850,6 +2907,15 @@ out:
2850 return IRQ_HANDLED; 2907 return IRQ_HANDLED;
2851} 2908}
2852 2909
2910static irqreturn_t wm8994_fifo_error(int irq, void *data)
2911{
2912 struct snd_soc_codec *codec = data;
2913
2914 dev_err(codec->dev, "FIFO error\n");
2915
2916 return IRQ_HANDLED;
2917}
2918
2853static int wm8994_codec_probe(struct snd_soc_codec *codec) 2919static int wm8994_codec_probe(struct snd_soc_codec *codec)
2854{ 2920{
2855 struct wm8994 *control; 2921 struct wm8994 *control;
@@ -2868,6 +2934,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2868 wm8994->pdata = dev_get_platdata(codec->dev->parent); 2934 wm8994->pdata = dev_get_platdata(codec->dev->parent);
2869 wm8994->codec = codec; 2935 wm8994->codec = codec;
2870 2936
2937 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
2938 init_completion(&wm8994->fll_locked[i]);
2939
2871 if (wm8994->pdata && wm8994->pdata->micdet_irq) 2940 if (wm8994->pdata && wm8994->pdata->micdet_irq)
2872 wm8994->micdet_irq = wm8994->pdata->micdet_irq; 2941 wm8994->micdet_irq = wm8994->pdata->micdet_irq;
2873 else if (wm8994->pdata && wm8994->pdata->irq_base) 2942 else if (wm8994->pdata && wm8994->pdata->irq_base)
@@ -2906,11 +2975,13 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2906 wm8994->hubs.dcs_codes = -5; 2975 wm8994->hubs.dcs_codes = -5;
2907 wm8994->hubs.hp_startup_mode = 1; 2976 wm8994->hubs.hp_startup_mode = 1;
2908 wm8994->hubs.dcs_readback_mode = 1; 2977 wm8994->hubs.dcs_readback_mode = 1;
2978 wm8994->hubs.series_startup = 1;
2909 break; 2979 break;
2910 default: 2980 default:
2911 wm8994->hubs.dcs_readback_mode = 1; 2981 wm8994->hubs.dcs_readback_mode = 1;
2912 break; 2982 break;
2913 } 2983 }
2984 break;
2914 2985
2915 case WM8958: 2986 case WM8958:
2916 wm8994->hubs.dcs_readback_mode = 1; 2987 wm8994->hubs.dcs_readback_mode = 1;
@@ -2920,6 +2991,15 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2920 break; 2991 break;
2921 } 2992 }
2922 2993
2994 wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR,
2995 wm8994_fifo_error, "FIFO error", codec);
2996
2997 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
2998 wm_hubs_dcs_done, "DC servo done",
2999 &wm8994->hubs);
3000 if (ret == 0)
3001 wm8994->hubs.dcs_done_irq = true;
3002
2923 switch (control->type) { 3003 switch (control->type) {
2924 case WM8994: 3004 case WM8994:
2925 if (wm8994->micdet_irq) { 3005 if (wm8994->micdet_irq) {
@@ -2976,6 +3056,16 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2976 } 3056 }
2977 } 3057 }
2978 3058
3059 wm8994->fll_locked_irq = true;
3060 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) {
3061 ret = wm8994_request_irq(codec->control_data,
3062 WM8994_IRQ_FLL1_LOCK + i,
3063 wm8994_fll_locked_irq, "FLL lock",
3064 &wm8994->fll_locked[i]);
3065 if (ret != 0)
3066 wm8994->fll_locked_irq = false;
3067 }
3068
2979 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3069 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
2980 * configured on init - if a system wants to do this dynamically 3070 * configured on init - if a system wants to do this dynamically
2981 * at runtime we can deal with that then. 3071 * at runtime we can deal with that then.
@@ -3051,10 +3141,18 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3051 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT, 3141 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
3052 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT); 3142 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
3053 3143
3054 /* Unconditionally enable AIF1 ADC TDM mode; it only affects 3144 /* Unconditionally enable AIF1 ADC TDM mode on chips which can
3055 * behaviour on idle TDM clock cycles. */ 3145 * use this; it only affects behaviour on idle TDM clock
3056 snd_soc_update_bits(codec, WM8994_AIF1_CONTROL_1, 3146 * cycles. */
3057 WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM); 3147 switch (control->type) {
3148 case WM8994:
3149 case WM8958:
3150 snd_soc_update_bits(codec, WM8994_AIF1_CONTROL_1,
3151 WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM);
3152 break;
3153 default:
3154 break;
3155 }
3058 3156
3059 wm8994_update_class_w(codec); 3157 wm8994_update_class_w(codec);
3060 3158
@@ -3153,6 +3251,12 @@ err_irq:
3153 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); 3251 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
3154 if (wm8994->micdet_irq) 3252 if (wm8994->micdet_irq)
3155 free_irq(wm8994->micdet_irq, wm8994); 3253 free_irq(wm8994->micdet_irq, wm8994);
3254 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
3255 wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i,
3256 &wm8994->fll_locked[i]);
3257 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
3258 &wm8994->hubs);
3259 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
3156err: 3260err:
3157 kfree(wm8994); 3261 kfree(wm8994);
3158 return ret; 3262 return ret;
@@ -3162,11 +3266,20 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3162{ 3266{
3163 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3267 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3164 struct wm8994 *control = codec->control_data; 3268 struct wm8994 *control = codec->control_data;
3269 int i;
3165 3270
3166 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); 3271 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3167 3272
3168 pm_runtime_disable(codec->dev); 3273 pm_runtime_disable(codec->dev);
3169 3274
3275 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
3276 wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i,
3277 &wm8994->fll_locked[i]);
3278
3279 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
3280 &wm8994->hubs);
3281 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
3282
3170 switch (control->type) { 3283 switch (control->type) {
3171 case WM8994: 3284 case WM8994:
3172 if (wm8994->micdet_irq) 3285 if (wm8994->micdet_irq)