aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8994.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-05-24 05:35:53 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-10-04 06:59:46 -0400
commit81204c84ca46604a04ab3d43ccfa1e464e6b1303 (patch)
tree408e2360161557a17b81f2405a09c80966bf8e41 /sound/soc/codecs/wm8994.c
parentb1f43bf3a52b085b786adf0b719712df574955f9 (diff)
ASoC: Add WM1811 support
The WM1811 is mostly register compatible with the WM8994 and WM8958, providing a high performance audio hub CODEC in a small form factor suitable for ultra compact system designs. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r--sound/soc/codecs/wm8994.c83
1 files changed, 78 insertions, 5 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index e5372675123d..5e8d66d085f5 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -283,6 +283,7 @@ static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
283static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0); 283static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
284static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 284static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
285static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0); 285static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
286static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0);
286 287
287#define WM8994_DRC_SWITCH(xname, reg, shift) \ 288#define WM8994_DRC_SWITCH(xname, reg, shift) \
288{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 289{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -703,6 +704,13 @@ SOC_SINGLE_TLV("AIF2DAC Noise Gate Threshold Volume",
703 7, 1, ng_tlv), 704 7, 1, ng_tlv),
704}; 705};
705 706
707static const struct snd_kcontrol_new wm1811_snd_controls[] = {
708SOC_SINGLE_TLV("MIXINL IN1LP Boost Volume", WM8994_INPUT_MIXER_1, 7, 1, 0,
709 mixin_boost_tlv),
710SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0,
711 mixin_boost_tlv),
712};
713
706static int clk_sys_event(struct snd_soc_dapm_widget *w, 714static int clk_sys_event(struct snd_soc_dapm_widget *w,
707 struct snd_kcontrol *kcontrol, int event) 715 struct snd_kcontrol *kcontrol, int event)
708{ 716{
@@ -2053,6 +2061,15 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2053 WM8958_CP_DISCH); 2061 WM8958_CP_DISCH);
2054 } 2062 }
2055 break; 2063 break;
2064
2065 case WM1811:
2066 if (wm8994->revision < 2) {
2067 snd_soc_write(codec, 0x102, 0x3);
2068 snd_soc_write(codec, 0x5d, 0x7e);
2069 snd_soc_write(codec, 0x5e, 0x0);
2070 snd_soc_write(codec, 0x102, 0x0);
2071 }
2072 break;
2056 } 2073 }
2057 2074
2058 /* Discharge LINEOUT1 & 2 */ 2075 /* Discharge LINEOUT1 & 2 */
@@ -2168,10 +2185,18 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2168 2185
2169 /* The AIF2 format configuration needs to be mirrored to AIF3 2186 /* The AIF2 format configuration needs to be mirrored to AIF3
2170 * on WM8958 if it's in use so just do it all the time. */ 2187 * on WM8958 if it's in use so just do it all the time. */
2171 if (control->type == WM8958 && dai->id == 2) 2188 switch (control->type) {
2172 snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1, 2189 case WM1811:
2173 WM8994_AIF1_LRCLK_INV | 2190 case WM8958:
2174 WM8958_AIF3_FMT_MASK, aif1); 2191 if (dai->id == 2)
2192 snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1,
2193 WM8994_AIF1_LRCLK_INV |
2194 WM8958_AIF3_FMT_MASK, aif1);
2195 break;
2196
2197 default:
2198 break;
2199 }
2175 2200
2176 snd_soc_update_bits(codec, aif1_reg, 2201 snd_soc_update_bits(codec, aif1_reg,
2177 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV | 2202 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
@@ -2258,6 +2283,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
2258 break; 2283 break;
2259 case 3: 2284 case 3:
2260 switch (control->type) { 2285 switch (control->type) {
2286 case WM1811:
2261 case WM8958: 2287 case WM8958:
2262 aif1_reg = WM8958_AIF3_CONTROL_1; 2288 aif1_reg = WM8958_AIF3_CONTROL_1;
2263 break; 2289 break;
@@ -2384,6 +2410,7 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
2384 switch (dai->id) { 2410 switch (dai->id) {
2385 case 3: 2411 case 3:
2386 switch (control->type) { 2412 switch (control->type) {
2413 case WM1811:
2387 case WM8958: 2414 case WM8958:
2388 aif1_reg = WM8958_AIF3_CONTROL_1; 2415 aif1_reg = WM8958_AIF3_CONTROL_1;
2389 break; 2416 break;
@@ -2614,6 +2641,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
2614 case WM8994: 2641 case WM8994:
2615 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0); 2642 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
2616 break; 2643 break;
2644 case WM1811:
2617 case WM8958: 2645 case WM8958:
2618 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 2646 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2619 WM8958_MICD_ENA, 0); 2647 WM8958_MICD_ENA, 0);
@@ -2682,6 +2710,7 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2682 snd_soc_update_bits(codec, WM8994_MICBIAS, 2710 snd_soc_update_bits(codec, WM8994_MICBIAS,
2683 WM8994_MICD_ENA, WM8994_MICD_ENA); 2711 WM8994_MICD_ENA, WM8994_MICD_ENA);
2684 break; 2712 break;
2713 case WM1811:
2685 case WM8958: 2714 case WM8958:
2686 if (wm8994->jack_cb) 2715 if (wm8994->jack_cb)
2687 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 2716 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
@@ -2980,8 +3009,13 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2980 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3009 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2981 struct wm8994 *control = codec->control_data; 3010 struct wm8994 *control = codec->control_data;
2982 3011
2983 if (control->type != WM8958) 3012 switch (control->type) {
3013 case WM1811:
3014 case WM8958:
3015 break;
3016 default:
2984 return -EINVAL; 3017 return -EINVAL;
3018 }
2985 3019
2986 if (jack) { 3020 if (jack) {
2987 if (!cb) { 3021 if (!cb) {
@@ -3135,6 +3169,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3135 wm8994->hubs.dcs_readback_mode = 1; 3169 wm8994->hubs.dcs_readback_mode = 1;
3136 break; 3170 break;
3137 3171
3172 case WM1811:
3173 wm8994->hubs.dcs_readback_mode = 2;
3174 wm8994->hubs.no_series_update = 1;
3175
3176 switch (wm8994->revision) {
3177 case 0:
3178 case 1:
3179 wm8994->hubs.dcs_codes_l = -7;
3180 wm8994->hubs.dcs_codes_r = -4;
3181 break;
3182 default:
3183 break;
3184 }
3185
3186 snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1,
3187 WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN);
3188 break;
3189
3138 default: 3190 default:
3139 break; 3191 break;
3140 } 3192 }
@@ -3195,6 +3247,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3195 break; 3247 break;
3196 3248
3197 case WM8958: 3249 case WM8958:
3250 case WM1811:
3198 if (wm8994->micdet_irq) { 3251 if (wm8994->micdet_irq) {
3199 ret = request_threaded_irq(wm8994->micdet_irq, NULL, 3252 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
3200 wm8958_mic_irq, 3253 wm8958_mic_irq,
@@ -3357,6 +3410,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3357 ARRAY_SIZE(wm8994_dac_widgets)); 3410 ARRAY_SIZE(wm8994_dac_widgets));
3358 } 3411 }
3359 break; 3412 break;
3413
3414 case WM1811:
3415 snd_soc_add_controls(codec, wm8958_snd_controls,
3416 ARRAY_SIZE(wm8958_snd_controls));
3417 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3418 ARRAY_SIZE(wm8958_dapm_widgets));
3419 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3420 ARRAY_SIZE(wm8994_lateclk_widgets));
3421 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3422 ARRAY_SIZE(wm8994_adc_widgets));
3423 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3424 ARRAY_SIZE(wm8994_dac_widgets));
3425 break;
3360 } 3426 }
3361 3427
3362 3428
@@ -3393,6 +3459,12 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3393 3459
3394 wm8958_dsp2_init(codec); 3460 wm8958_dsp2_init(codec);
3395 break; 3461 break;
3462 case WM1811:
3463 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3464 ARRAY_SIZE(wm8994_lateclk_intercon));
3465 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
3466 ARRAY_SIZE(wm8958_intercon));
3467 break;
3396 } 3468 }
3397 3469
3398 return 0; 3470 return 0;
@@ -3448,6 +3520,7 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3448 wm8994); 3520 wm8994);
3449 break; 3521 break;
3450 3522
3523 case WM1811:
3451 case WM8958: 3524 case WM8958:
3452 if (wm8994->micdet_irq) 3525 if (wm8994->micdet_irq)
3453 free_irq(wm8994->micdet_irq, wm8994); 3526 free_irq(wm8994->micdet_irq, wm8994);