diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-04-12 08:57:31 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-04-12 08:57:31 -0400 |
commit | 5cbad7d39ad229c68a724e5e139fd845b93766b2 (patch) | |
tree | 4090a6b3ab23e093547f9e5841131ea821c456f6 /sound | |
parent | 3c307826258dc2daafc13c429d32b74fef407ba4 (diff) | |
parent | da445afe357ae656f6baddd8fd58b01e923f1fc6 (diff) |
Merge remote-tracking branch 'asoc/topic/wm8994' into asoc-next
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/wm8994.c | 68 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.h | 3 |
2 files changed, 55 insertions, 16 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index c9bd445c4976..14094f558e03 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -2209,7 +2209,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2209 | vmid_reference(codec); | 2209 | vmid_reference(codec); |
2210 | break; | 2210 | break; |
2211 | case WM8958: | 2211 | case WM8958: |
2212 | if (wm8994->revision < 1) | 2212 | if (control->revision < 1) |
2213 | vmid_reference(codec); | 2213 | vmid_reference(codec); |
2214 | break; | 2214 | break; |
2215 | default: | 2215 | default: |
@@ -2244,7 +2244,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2244 | vmid_dereference(codec); | 2244 | vmid_dereference(codec); |
2245 | break; | 2245 | break; |
2246 | case WM8958: | 2246 | case WM8958: |
2247 | if (wm8994->revision < 1) | 2247 | if (control->revision < 1) |
2248 | vmid_dereference(codec); | 2248 | vmid_dereference(codec); |
2249 | break; | 2249 | break; |
2250 | default: | 2250 | default: |
@@ -2268,10 +2268,26 @@ out: | |||
2268 | */ | 2268 | */ |
2269 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { | 2269 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { |
2270 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); | 2270 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); |
2271 | |||
2272 | wm8994->aifdiv[0] = snd_soc_read(codec, WM8994_AIF1_RATE) | ||
2273 | & WM8994_AIF1CLK_RATE_MASK; | ||
2274 | wm8994->aifdiv[1] = snd_soc_read(codec, WM8994_AIF2_RATE) | ||
2275 | & WM8994_AIF1CLK_RATE_MASK; | ||
2276 | |||
2271 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | 2277 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, |
2272 | WM8994_AIF1CLK_RATE_MASK, 0x1); | 2278 | WM8994_AIF1CLK_RATE_MASK, 0x1); |
2273 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | 2279 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, |
2274 | WM8994_AIF2CLK_RATE_MASK, 0x1); | 2280 | WM8994_AIF2CLK_RATE_MASK, 0x1); |
2281 | } else if (wm8994->aifdiv[0]) { | ||
2282 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | ||
2283 | WM8994_AIF1CLK_RATE_MASK, | ||
2284 | wm8994->aifdiv[0]); | ||
2285 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | ||
2286 | WM8994_AIF2CLK_RATE_MASK, | ||
2287 | wm8994->aifdiv[1]); | ||
2288 | |||
2289 | wm8994->aifdiv[0] = 0; | ||
2290 | wm8994->aifdiv[1] = 0; | ||
2275 | } | 2291 | } |
2276 | 2292 | ||
2277 | return 0; | 2293 | return 0; |
@@ -2368,10 +2384,26 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2368 | */ | 2384 | */ |
2369 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { | 2385 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { |
2370 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); | 2386 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); |
2387 | |||
2388 | wm8994->aifdiv[0] = snd_soc_read(codec, WM8994_AIF1_RATE) | ||
2389 | & WM8994_AIF1CLK_RATE_MASK; | ||
2390 | wm8994->aifdiv[1] = snd_soc_read(codec, WM8994_AIF2_RATE) | ||
2391 | & WM8994_AIF1CLK_RATE_MASK; | ||
2392 | |||
2371 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | 2393 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, |
2372 | WM8994_AIF1CLK_RATE_MASK, 0x1); | 2394 | WM8994_AIF1CLK_RATE_MASK, 0x1); |
2373 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | 2395 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, |
2374 | WM8994_AIF2CLK_RATE_MASK, 0x1); | 2396 | WM8994_AIF2CLK_RATE_MASK, 0x1); |
2397 | } else if (wm8994->aifdiv[0]) { | ||
2398 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | ||
2399 | WM8994_AIF1CLK_RATE_MASK, | ||
2400 | wm8994->aifdiv[0]); | ||
2401 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | ||
2402 | WM8994_AIF2CLK_RATE_MASK, | ||
2403 | wm8994->aifdiv[1]); | ||
2404 | |||
2405 | wm8994->aifdiv[0] = 0; | ||
2406 | wm8994->aifdiv[1] = 0; | ||
2375 | } | 2407 | } |
2376 | 2408 | ||
2377 | return 0; | 2409 | return 0; |
@@ -2411,7 +2443,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
2411 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 2443 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
2412 | switch (control->type) { | 2444 | switch (control->type) { |
2413 | case WM8958: | 2445 | case WM8958: |
2414 | if (wm8994->revision == 0) { | 2446 | if (control->revision == 0) { |
2415 | /* Optimise performance for rev A */ | 2447 | /* Optimise performance for rev A */ |
2416 | snd_soc_update_bits(codec, | 2448 | snd_soc_update_bits(codec, |
2417 | WM8958_CHARGE_PUMP_2, | 2449 | WM8958_CHARGE_PUMP_2, |
@@ -2656,6 +2688,8 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
2656 | { | 2688 | { |
2657 | struct snd_soc_codec *codec = dai->codec; | 2689 | struct snd_soc_codec *codec = dai->codec; |
2658 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2690 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2691 | struct wm8994 *control = wm8994->wm8994; | ||
2692 | struct wm8994_pdata *pdata = &control->pdata; | ||
2659 | int aif1_reg; | 2693 | int aif1_reg; |
2660 | int aif2_reg; | 2694 | int aif2_reg; |
2661 | int bclk_reg; | 2695 | int bclk_reg; |
@@ -2723,7 +2757,14 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
2723 | } | 2757 | } |
2724 | 2758 | ||
2725 | wm8994->channels[id] = params_channels(params); | 2759 | wm8994->channels[id] = params_channels(params); |
2726 | switch (params_channels(params)) { | 2760 | if (pdata->max_channels_clocked[id] && |
2761 | wm8994->channels[id] > pdata->max_channels_clocked[id]) { | ||
2762 | dev_dbg(dai->dev, "Constraining channels to %d from %d\n", | ||
2763 | pdata->max_channels_clocked[id], wm8994->channels[id]); | ||
2764 | wm8994->channels[id] = pdata->max_channels_clocked[id]; | ||
2765 | } | ||
2766 | |||
2767 | switch (wm8994->channels[id]) { | ||
2727 | case 1: | 2768 | case 1: |
2728 | case 2: | 2769 | case 2: |
2729 | bclk_rate *= 2; | 2770 | bclk_rate *= 2; |
@@ -2745,7 +2786,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
2745 | dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", | 2786 | dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", |
2746 | dai->id, wm8994->aifclk[id], bclk_rate); | 2787 | dai->id, wm8994->aifclk[id], bclk_rate); |
2747 | 2788 | ||
2748 | if (params_channels(params) == 1 && | 2789 | if (wm8994->channels[id] == 1 && |
2749 | (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18) | 2790 | (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18) |
2750 | aif2 |= WM8994_AIF1_MONO; | 2791 | aif2 |= WM8994_AIF1_MONO; |
2751 | 2792 | ||
@@ -3053,7 +3094,7 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec) | |||
3053 | int i, ret; | 3094 | int i, ret; |
3054 | unsigned int val, mask; | 3095 | unsigned int val, mask; |
3055 | 3096 | ||
3056 | if (wm8994->revision < 4) { | 3097 | if (control->revision < 4) { |
3057 | /* force a HW read */ | 3098 | /* force a HW read */ |
3058 | ret = regmap_read(control->regmap, | 3099 | ret = regmap_read(control->regmap, |
3059 | WM8994_POWER_MANAGEMENT_5, &val); | 3100 | WM8994_POWER_MANAGEMENT_5, &val); |
@@ -3870,7 +3911,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3870 | codec->dapm.idle_bias_off = 1; | 3911 | codec->dapm.idle_bias_off = 1; |
3871 | 3912 | ||
3872 | /* Set revision-specific configuration */ | 3913 | /* Set revision-specific configuration */ |
3873 | wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); | ||
3874 | switch (control->type) { | 3914 | switch (control->type) { |
3875 | case WM8994: | 3915 | case WM8994: |
3876 | /* Single ended line outputs should have VMID on. */ | 3916 | /* Single ended line outputs should have VMID on. */ |
@@ -3878,7 +3918,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3878 | !control->pdata.lineout2_diff) | 3918 | !control->pdata.lineout2_diff) |
3879 | codec->dapm.idle_bias_off = 0; | 3919 | codec->dapm.idle_bias_off = 0; |
3880 | 3920 | ||
3881 | switch (wm8994->revision) { | 3921 | switch (control->revision) { |
3882 | case 2: | 3922 | case 2: |
3883 | case 3: | 3923 | case 3: |
3884 | wm8994->hubs.dcs_codes_l = -5; | 3924 | wm8994->hubs.dcs_codes_l = -5; |
@@ -3897,7 +3937,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3897 | wm8994->hubs.dcs_readback_mode = 1; | 3937 | wm8994->hubs.dcs_readback_mode = 1; |
3898 | wm8994->hubs.hp_startup_mode = 1; | 3938 | wm8994->hubs.hp_startup_mode = 1; |
3899 | 3939 | ||
3900 | switch (wm8994->revision) { | 3940 | switch (control->revision) { |
3901 | case 0: | 3941 | case 0: |
3902 | break; | 3942 | break; |
3903 | default: | 3943 | default: |
@@ -4000,7 +4040,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4000 | 4040 | ||
4001 | switch (control->type) { | 4041 | switch (control->type) { |
4002 | case WM1811: | 4042 | case WM1811: |
4003 | if (control->cust_id > 1 || wm8994->revision > 1) { | 4043 | if (control->cust_id > 1 || control->revision > 1) { |
4004 | ret = wm8994_request_irq(wm8994->wm8994, | 4044 | ret = wm8994_request_irq(wm8994->wm8994, |
4005 | WM8994_IRQ_GPIO(6), | 4045 | WM8994_IRQ_GPIO(6), |
4006 | wm1811_jackdet_irq, "JACKDET", | 4046 | wm1811_jackdet_irq, "JACKDET", |
@@ -4114,7 +4154,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4114 | case WM8994: | 4154 | case WM8994: |
4115 | snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, | 4155 | snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, |
4116 | ARRAY_SIZE(wm8994_specific_dapm_widgets)); | 4156 | ARRAY_SIZE(wm8994_specific_dapm_widgets)); |
4117 | if (wm8994->revision < 4) { | 4157 | if (control->revision < 4) { |
4118 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, | 4158 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, |
4119 | ARRAY_SIZE(wm8994_lateclk_revd_widgets)); | 4159 | ARRAY_SIZE(wm8994_lateclk_revd_widgets)); |
4120 | snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, | 4160 | snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, |
@@ -4135,7 +4175,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4135 | ARRAY_SIZE(wm8958_snd_controls)); | 4175 | ARRAY_SIZE(wm8958_snd_controls)); |
4136 | snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, | 4176 | snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, |
4137 | ARRAY_SIZE(wm8958_dapm_widgets)); | 4177 | ARRAY_SIZE(wm8958_dapm_widgets)); |
4138 | if (wm8994->revision < 1) { | 4178 | if (control->revision < 1) { |
4139 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, | 4179 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, |
4140 | ARRAY_SIZE(wm8994_lateclk_revd_widgets)); | 4180 | ARRAY_SIZE(wm8994_lateclk_revd_widgets)); |
4141 | snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, | 4181 | snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, |
@@ -4174,7 +4214,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4174 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, | 4214 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, |
4175 | ARRAY_SIZE(wm8994_intercon)); | 4215 | ARRAY_SIZE(wm8994_intercon)); |
4176 | 4216 | ||
4177 | if (wm8994->revision < 4) { | 4217 | if (control->revision < 4) { |
4178 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, | 4218 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, |
4179 | ARRAY_SIZE(wm8994_revd_intercon)); | 4219 | ARRAY_SIZE(wm8994_revd_intercon)); |
4180 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, | 4220 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, |
@@ -4185,7 +4225,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4185 | } | 4225 | } |
4186 | break; | 4226 | break; |
4187 | case WM8958: | 4227 | case WM8958: |
4188 | if (wm8994->revision < 1) { | 4228 | if (control->revision < 1) { |
4189 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, | 4229 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, |
4190 | ARRAY_SIZE(wm8994_intercon)); | 4230 | ARRAY_SIZE(wm8994_intercon)); |
4191 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, | 4231 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, |
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 45f192702024..55ddf4d57d9b 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h | |||
@@ -79,6 +79,7 @@ struct wm8994_priv { | |||
79 | int sysclk_rate[2]; | 79 | int sysclk_rate[2]; |
80 | int mclk[2]; | 80 | int mclk[2]; |
81 | int aifclk[2]; | 81 | int aifclk[2]; |
82 | int aifdiv[2]; | ||
82 | int channels[2]; | 83 | int channels[2]; |
83 | struct wm8994_fll_config fll[2], fll_suspend[2]; | 84 | struct wm8994_fll_config fll[2], fll_suspend[2]; |
84 | struct completion fll_locked[2]; | 85 | struct completion fll_locked[2]; |
@@ -146,8 +147,6 @@ struct wm8994_priv { | |||
146 | wm1811_mic_id_cb mic_id_cb; | 147 | wm1811_mic_id_cb mic_id_cb; |
147 | void *mic_id_cb_data; | 148 | void *mic_id_cb_data; |
148 | 149 | ||
149 | int revision; | ||
150 | |||
151 | unsigned int aif1clk_enable:1; | 150 | unsigned int aif1clk_enable:1; |
152 | unsigned int aif2clk_enable:1; | 151 | unsigned int aif2clk_enable:1; |
153 | 152 | ||