aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_analog.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_analog.c')
-rw-r--r--sound/pci/hda/patch_analog.c208
1 files changed, 192 insertions, 16 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 46780670162b..8dabab798689 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -46,6 +46,9 @@ struct ad198x_spec {
46 unsigned int cur_eapd; 46 unsigned int cur_eapd;
47 unsigned int need_dac_fix; 47 unsigned int need_dac_fix;
48 48
49 hda_nid_t *alt_dac_nid;
50 struct hda_pcm_stream *stream_analog_alt_playback;
51
49 /* capture */ 52 /* capture */
50 unsigned int num_adc_nids; 53 unsigned int num_adc_nids;
51 hda_nid_t *adc_nids; 54 hda_nid_t *adc_nids;
@@ -81,8 +84,8 @@ struct ad198x_spec {
81#endif 84#endif
82 /* for virtual master */ 85 /* for virtual master */
83 hda_nid_t vmaster_nid; 86 hda_nid_t vmaster_nid;
84 const char **slave_vols; 87 const char * const *slave_vols;
85 const char **slave_sws; 88 const char * const *slave_sws;
86}; 89};
87 90
88/* 91/*
@@ -130,7 +133,7 @@ static int ad198x_init(struct hda_codec *codec)
130 return 0; 133 return 0;
131} 134}
132 135
133static const char *ad_slave_vols[] = { 136static const char * const ad_slave_vols[] = {
134 "Front Playback Volume", 137 "Front Playback Volume",
135 "Surround Playback Volume", 138 "Surround Playback Volume",
136 "Center Playback Volume", 139 "Center Playback Volume",
@@ -143,7 +146,7 @@ static const char *ad_slave_vols[] = {
143 NULL 146 NULL
144}; 147};
145 148
146static const char *ad_slave_sws[] = { 149static const char * const ad_slave_sws[] = {
147 "Front Playback Switch", 150 "Front Playback Switch",
148 "Surround Playback Switch", 151 "Surround Playback Switch",
149 "Center Playback Switch", 152 "Center Playback Switch",
@@ -156,6 +159,25 @@ static const char *ad_slave_sws[] = {
156 NULL 159 NULL
157}; 160};
158 161
162static const char * const ad1988_6stack_fp_slave_vols[] = {
163 "Front Playback Volume",
164 "Surround Playback Volume",
165 "Center Playback Volume",
166 "LFE Playback Volume",
167 "Side Playback Volume",
168 "IEC958 Playback Volume",
169 NULL
170};
171
172static const char * const ad1988_6stack_fp_slave_sws[] = {
173 "Front Playback Switch",
174 "Surround Playback Switch",
175 "Center Playback Switch",
176 "LFE Playback Switch",
177 "Side Playback Switch",
178 "IEC958 Playback Switch",
179 NULL
180};
159static void ad198x_free_kctls(struct hda_codec *codec); 181static void ad198x_free_kctls(struct hda_codec *codec);
160 182
161#ifdef CONFIG_SND_HDA_INPUT_BEEP 183#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -309,6 +331,38 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
309 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 331 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
310} 332}
311 333
334static int ad198x_alt_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
335 struct hda_codec *codec,
336 unsigned int stream_tag,
337 unsigned int format,
338 struct snd_pcm_substream *substream)
339{
340 struct ad198x_spec *spec = codec->spec;
341 snd_hda_codec_setup_stream(codec, spec->alt_dac_nid[0], stream_tag,
342 0, format);
343 return 0;
344}
345
346static int ad198x_alt_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
347 struct hda_codec *codec,
348 struct snd_pcm_substream *substream)
349{
350 struct ad198x_spec *spec = codec->spec;
351 snd_hda_codec_cleanup_stream(codec, spec->alt_dac_nid[0]);
352 return 0;
353}
354
355static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = {
356 .substreams = 1,
357 .channels_min = 2,
358 .channels_max = 2,
359 /* NID is set in ad198x_build_pcms */
360 .ops = {
361 .prepare = ad198x_alt_playback_pcm_prepare,
362 .cleanup = ad198x_alt_playback_pcm_cleanup
363 },
364};
365
312/* 366/*
313 * Digital out 367 * Digital out
314 */ 368 */
@@ -446,6 +500,17 @@ static int ad198x_build_pcms(struct hda_codec *codec)
446 } 500 }
447 } 501 }
448 502
503 if (spec->alt_dac_nid && spec->stream_analog_alt_playback) {
504 codec->num_pcms++;
505 info = spec->pcm_rec + 2;
506 info->name = "AD198x Headphone";
507 info->pcm_type = HDA_PCM_TYPE_AUDIO;
508 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
509 *spec->stream_analog_alt_playback;
510 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
511 spec->alt_dac_nid[0];
512 }
513
449 return 0; 514 return 0;
450} 515}
451 516
@@ -1069,7 +1134,7 @@ enum {
1069 AD1986A_MODELS 1134 AD1986A_MODELS
1070}; 1135};
1071 1136
1072static const char *ad1986a_models[AD1986A_MODELS] = { 1137static const char * const ad1986a_models[AD1986A_MODELS] = {
1073 [AD1986A_6STACK] = "6stack", 1138 [AD1986A_6STACK] = "6stack",
1074 [AD1986A_3STACK] = "3stack", 1139 [AD1986A_3STACK] = "3stack",
1075 [AD1986A_LAPTOP] = "laptop", 1140 [AD1986A_LAPTOP] = "laptop",
@@ -1813,7 +1878,7 @@ enum {
1813 AD1981_MODELS 1878 AD1981_MODELS
1814}; 1879};
1815 1880
1816static const char *ad1981_models[AD1981_MODELS] = { 1881static const char * const ad1981_models[AD1981_MODELS] = {
1817 [AD1981_HP] = "hp", 1882 [AD1981_HP] = "hp",
1818 [AD1981_THINKPAD] = "thinkpad", 1883 [AD1981_THINKPAD] = "thinkpad",
1819 [AD1981_BASIC] = "basic", 1884 [AD1981_BASIC] = "basic",
@@ -2015,6 +2080,7 @@ static int patch_ad1981(struct hda_codec *codec)
2015enum { 2080enum {
2016 AD1988_6STACK, 2081 AD1988_6STACK,
2017 AD1988_6STACK_DIG, 2082 AD1988_6STACK_DIG,
2083 AD1988_6STACK_DIG_FP,
2018 AD1988_3STACK, 2084 AD1988_3STACK,
2019 AD1988_3STACK_DIG, 2085 AD1988_3STACK_DIG,
2020 AD1988_LAPTOP, 2086 AD1988_LAPTOP,
@@ -2047,6 +2113,10 @@ static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2047 0x04, 0x05, 0x0a, 0x06 2113 0x04, 0x05, 0x0a, 0x06
2048}; 2114};
2049 2115
2116static hda_nid_t ad1988_alt_dac_nid[1] = {
2117 0x03
2118};
2119
2050static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { 2120static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2051 0x04, 0x0a, 0x06 2121 0x04, 0x0a, 0x06
2052}; 2122};
@@ -2166,6 +2236,35 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2166 { } /* end */ 2236 { } /* end */
2167}; 2237};
2168 2238
2239static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = {
2240 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2241
2242 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2243 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2244 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2245 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2246 HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2247 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2248 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2249
2250 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2251 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2252 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2254 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2255 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2256 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2257 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2258
2259 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2260 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2261
2262 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2263 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2264
2265 { } /* end */
2266};
2267
2169/* 3-stack mode */ 2268/* 3-stack mode */
2170static struct snd_kcontrol_new ad1988_3stack_mixers1[] = { 2269static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2171 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 2270 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
@@ -2445,6 +2544,68 @@ static struct hda_verb ad1988_6stack_init_verbs[] = {
2445 { } 2544 { }
2446}; 2545};
2447 2546
2547static struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2548 /* Front, Surround, CLFE, side DAC; unmute as default */
2549 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2550 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2551 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2552 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2553 /* Headphone; unmute as default */
2554 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2555 /* Port-A front headphon path */
2556 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2557 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2558 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2559 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2560 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2561 /* Port-D line-out path */
2562 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2563 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2564 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2565 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2566 /* Port-F surround path */
2567 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2568 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2569 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2570 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2571 /* Port-G CLFE path */
2572 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2573 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2574 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2575 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2576 /* Port-H side path */
2577 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2578 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2579 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2580 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2581 /* Mono out path */
2582 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2583 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2584 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2585 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2586 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2587 /* Port-B front mic-in path */
2588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2590 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2591 /* Port-C line-in path */
2592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2593 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2594 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2595 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2596 /* Port-E mic-in path */
2597 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2598 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2599 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2600 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2601 /* Analog CD Input */
2602 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2603 /* Analog Mix output amp */
2604 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2605
2606 { }
2607};
2608
2448static struct hda_verb ad1988_capture_init_verbs[] = { 2609static struct hda_verb ad1988_capture_init_verbs[] = {
2449 /* mute analog mix */ 2610 /* mute analog mix */
2450 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2611 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -2792,7 +2953,9 @@ static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2792 const struct auto_pin_cfg *cfg) 2953 const struct auto_pin_cfg *cfg)
2793{ 2954{
2794 char name[32]; 2955 char name[32];
2795 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; 2956 static const char * const chname[4] = {
2957 "Front", "Surround", NULL /*CLFE*/, "Side"
2958 };
2796 hda_nid_t nid; 2959 hda_nid_t nid;
2797 int i, err; 2960 int i, err;
2798 2961
@@ -3074,13 +3237,13 @@ static int ad1988_auto_init(struct hda_codec *codec)
3074 return 0; 3237 return 0;
3075} 3238}
3076 3239
3077
3078/* 3240/*
3079 */ 3241 */
3080 3242
3081static const char *ad1988_models[AD1988_MODEL_LAST] = { 3243static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3082 [AD1988_6STACK] = "6stack", 3244 [AD1988_6STACK] = "6stack",
3083 [AD1988_6STACK_DIG] = "6stack-dig", 3245 [AD1988_6STACK_DIG] = "6stack-dig",
3246 [AD1988_6STACK_DIG_FP] = "6stack-dig-fp",
3084 [AD1988_3STACK] = "3stack", 3247 [AD1988_3STACK] = "3stack",
3085 [AD1988_3STACK_DIG] = "3stack-dig", 3248 [AD1988_3STACK_DIG] = "3stack-dig",
3086 [AD1988_LAPTOP] = "laptop", 3249 [AD1988_LAPTOP] = "laptop",
@@ -3140,6 +3303,7 @@ static int patch_ad1988(struct hda_codec *codec)
3140 switch (board_config) { 3303 switch (board_config) {
3141 case AD1988_6STACK: 3304 case AD1988_6STACK:
3142 case AD1988_6STACK_DIG: 3305 case AD1988_6STACK_DIG:
3306 case AD1988_6STACK_DIG_FP:
3143 spec->multiout.max_channels = 8; 3307 spec->multiout.max_channels = 8;
3144 spec->multiout.num_dacs = 4; 3308 spec->multiout.num_dacs = 4;
3145 if (is_rev2(codec)) 3309 if (is_rev2(codec))
@@ -3152,10 +3316,22 @@ static int patch_ad1988(struct hda_codec *codec)
3152 spec->mixers[0] = ad1988_6stack_mixers1_rev2; 3316 spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3153 else 3317 else
3154 spec->mixers[0] = ad1988_6stack_mixers1; 3318 spec->mixers[0] = ad1988_6stack_mixers1;
3155 spec->mixers[1] = ad1988_6stack_mixers2; 3319 if (board_config == AD1988_6STACK_DIG_FP) {
3320 spec->mixers[1] = ad1988_6stack_fp_mixers;
3321 spec->slave_vols = ad1988_6stack_fp_slave_vols;
3322 spec->slave_sws = ad1988_6stack_fp_slave_sws;
3323 spec->alt_dac_nid = ad1988_alt_dac_nid;
3324 spec->stream_analog_alt_playback =
3325 &ad198x_pcm_analog_alt_playback;
3326 } else
3327 spec->mixers[1] = ad1988_6stack_mixers2;
3156 spec->num_init_verbs = 1; 3328 spec->num_init_verbs = 1;
3157 spec->init_verbs[0] = ad1988_6stack_init_verbs; 3329 if (board_config == AD1988_6STACK_DIG_FP)
3158 if (board_config == AD1988_6STACK_DIG) { 3330 spec->init_verbs[0] = ad1988_6stack_fp_init_verbs;
3331 else
3332 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3333 if ((board_config == AD1988_6STACK_DIG) ||
3334 (board_config == AD1988_6STACK_DIG_FP)) {
3159 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 3335 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3160 spec->dig_in_nid = AD1988_SPDIF_IN; 3336 spec->dig_in_nid = AD1988_SPDIF_IN;
3161 } 3337 }
@@ -3399,7 +3575,7 @@ static struct hda_amp_list ad1884_loopbacks[] = {
3399}; 3575};
3400#endif 3576#endif
3401 3577
3402static const char *ad1884_slave_vols[] = { 3578static const char * const ad1884_slave_vols[] = {
3403 "PCM Playback Volume", 3579 "PCM Playback Volume",
3404 "Mic Playback Volume", 3580 "Mic Playback Volume",
3405 "Mono Playback Volume", 3581 "Mono Playback Volume",
@@ -3637,7 +3813,7 @@ enum {
3637 AD1984_MODELS 3813 AD1984_MODELS
3638}; 3814};
3639 3815
3640static const char *ad1984_models[AD1984_MODELS] = { 3816static const char * const ad1984_models[AD1984_MODELS] = {
3641 [AD1984_BASIC] = "basic", 3817 [AD1984_BASIC] = "basic",
3642 [AD1984_THINKPAD] = "thinkpad", 3818 [AD1984_THINKPAD] = "thinkpad",
3643 [AD1984_DELL_DESKTOP] = "dell_desktop", 3819 [AD1984_DELL_DESKTOP] = "dell_desktop",
@@ -4308,7 +4484,7 @@ enum {
4308 AD1884A_MODELS 4484 AD1884A_MODELS
4309}; 4485};
4310 4486
4311static const char *ad1884a_models[AD1884A_MODELS] = { 4487static const char * const ad1884a_models[AD1884A_MODELS] = {
4312 [AD1884A_DESKTOP] = "desktop", 4488 [AD1884A_DESKTOP] = "desktop",
4313 [AD1884A_LAPTOP] = "laptop", 4489 [AD1884A_LAPTOP] = "laptop",
4314 [AD1884A_MOBILE] = "mobile", 4490 [AD1884A_MOBILE] = "mobile",
@@ -4696,7 +4872,7 @@ enum {
4696 AD1882_MODELS 4872 AD1882_MODELS
4697}; 4873};
4698 4874
4699static const char *ad1882_models[AD1986A_MODELS] = { 4875static const char * const ad1882_models[AD1986A_MODELS] = {
4700 [AD1882_3STACK] = "3stack", 4876 [AD1882_3STACK] = "3stack",
4701 [AD1882_6STACK] = "6stack", 4877 [AD1882_6STACK] = "6stack",
4702}; 4878};