]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Takashi Iwai <tiwai@suse.de> |
2 | Subject: ALSA: hda - update Analaog Device codec support | |
3 | Patch-mainline: 2.6.28-rc1 | |
4 | References: | |
5 | ||
6 | - Fix AD1988 output noises | |
7 | - Slave HDMI support on AD1989 | |
8 | - Added the support for AD1882A | |
9 | ||
10 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | |
11 | ||
12 | --- | |
13 | --- | |
14 | Documentation/sound/alsa/ALSA-Configuration.txt | 2 | |
15 | sound/pci/hda/patch_analog.c | 89 +++++++++++++++++++----- | |
16 | 2 files changed, 72 insertions(+), 19 deletions(-) | |
17 | ||
18 | --- a/Documentation/sound/alsa/ALSA-Configuration.txt | |
19 | +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |
20 | @@ -929,7 +929,7 @@ Prior to version 0.9.0rc4 options had a | |
21 | allout 5-jack in back, 2-jack in front, SPDIF out | |
22 | auto auto-config reading BIOS (default) | |
23 | ||
24 | - AD1882 | |
25 | + AD1882 / AD1882A | |
26 | 3stack 3-stack mode (default) | |
27 | 6stack 6-stack mode | |
28 | ||
29 | --- a/sound/pci/hda/patch_analog.c | |
30 | +++ b/sound/pci/hda/patch_analog.c | |
31 | @@ -1869,9 +1869,14 @@ static hda_nid_t ad1988_capsrc_nids[3] = | |
32 | 0x0c, 0x0d, 0x0e | |
33 | }; | |
34 | ||
35 | -#define AD1988_SPDIF_OUT 0x02 | |
36 | +#define AD1988_SPDIF_OUT 0x02 | |
37 | +#define AD1988_SPDIF_OUT_HDMI 0x0b | |
38 | #define AD1988_SPDIF_IN 0x07 | |
39 | ||
40 | +static hda_nid_t ad1989b_slave_dig_outs[2] = { | |
41 | + AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI | |
42 | +}; | |
43 | + | |
44 | static struct hda_input_mux ad1988_6stack_capture_source = { | |
45 | .num_items = 5, | |
46 | .items = { | |
47 | @@ -2186,6 +2191,7 @@ static struct snd_kcontrol_new ad1988_sp | |
48 | ||
49 | static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { | |
50 | HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | |
51 | + HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT), | |
52 | { } /* end */ | |
53 | }; | |
54 | ||
55 | @@ -2250,6 +2256,8 @@ static struct hda_verb ad1988_6stack_ini | |
56 | {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, | |
57 | /* Analog CD Input */ | |
58 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | |
59 | + /* Analog Mix output amp */ | |
60 | + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ | |
61 | ||
62 | { } | |
63 | }; | |
64 | @@ -2383,6 +2391,8 @@ static struct hda_verb ad1988_3stack_ini | |
65 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | |
66 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | |
67 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | |
68 | + /* Analog Mix output amp */ | |
69 | + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ | |
70 | { } | |
71 | }; | |
72 | ||
73 | @@ -2456,6 +2466,8 @@ static struct hda_verb ad1988_laptop_ini | |
74 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | |
75 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | |
76 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | |
77 | + /* Analog Mix output amp */ | |
78 | + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ | |
79 | { } | |
80 | }; | |
81 | ||
82 | @@ -3023,6 +3035,7 @@ static int patch_ad1988(struct hda_codec | |
83 | ad1989_spdif_out_mixers; | |
84 | spec->init_verbs[spec->num_init_verbs++] = | |
85 | ad1989_spdif_init_verbs; | |
86 | + codec->slave_dig_outs = ad1989b_slave_dig_outs; | |
87 | } else { | |
88 | spec->mixers[spec->num_mixers++] = | |
89 | ad1988_spdif_out_mixers; | |
90 | @@ -3963,7 +3976,7 @@ static int patch_ad1884a(struct hda_code | |
91 | ||
92 | ||
93 | /* | |
94 | - * AD1882 | |
95 | + * AD1882 / AD1882A | |
96 | * | |
97 | * port-A - front hp-out | |
98 | * port-B - front mic-in | |
99 | @@ -4000,6 +4013,18 @@ static struct hda_input_mux ad1882_captu | |
100 | }, | |
101 | }; | |
102 | ||
103 | +/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */ | |
104 | +static struct hda_input_mux ad1882a_capture_source = { | |
105 | + .num_items = 5, | |
106 | + .items = { | |
107 | + { "Front Mic", 0x1 }, | |
108 | + { "Mic", 0x4}, | |
109 | + { "Line", 0x2 }, | |
110 | + { "Digital Mic", 0x06 }, | |
111 | + { "Mix", 0x7 }, | |
112 | + }, | |
113 | +}; | |
114 | + | |
115 | static struct snd_kcontrol_new ad1882_base_mixers[] = { | |
116 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | |
117 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | |
118 | @@ -4009,16 +4034,7 @@ static struct snd_kcontrol_new ad1882_ba | |
119 | HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), | |
120 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), | |
121 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), | |
122 | - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), | |
123 | - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), | |
124 | - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | |
125 | - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), | |
126 | - HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT), | |
127 | - HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT), | |
128 | - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), | |
129 | - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), | |
130 | - HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT), | |
131 | - HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT), | |
132 | + | |
133 | HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), | |
134 | HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), | |
135 | HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), | |
136 | @@ -4051,6 +4067,35 @@ static struct snd_kcontrol_new ad1882_ba | |
137 | { } /* end */ | |
138 | }; | |
139 | ||
140 | +static struct snd_kcontrol_new ad1882_loopback_mixers[] = { | |
141 | + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), | |
142 | + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), | |
143 | + HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | |
144 | + HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), | |
145 | + HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT), | |
146 | + HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT), | |
147 | + HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), | |
148 | + HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), | |
149 | + HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT), | |
150 | + HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT), | |
151 | + { } /* end */ | |
152 | +}; | |
153 | + | |
154 | +static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { | |
155 | + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), | |
156 | + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), | |
157 | + HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), | |
158 | + HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT), | |
159 | + HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT), | |
160 | + HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT), | |
161 | + HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), | |
162 | + HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), | |
163 | + HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT), | |
164 | + HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT), | |
165 | + HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT), | |
166 | + { } /* end */ | |
167 | +}; | |
168 | + | |
169 | static struct snd_kcontrol_new ad1882_3stack_mixers[] = { | |
170 | HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), | |
171 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), | |
172 | @@ -4220,9 +4265,16 @@ static int patch_ad1882(struct hda_codec | |
173 | spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); | |
174 | spec->adc_nids = ad1882_adc_nids; | |
175 | spec->capsrc_nids = ad1882_capsrc_nids; | |
176 | - spec->input_mux = &ad1882_capture_source; | |
177 | - spec->num_mixers = 1; | |
178 | + if (codec->vendor_id == 0x11d1882) | |
179 | + spec->input_mux = &ad1882_capture_source; | |
180 | + else | |
181 | + spec->input_mux = &ad1882a_capture_source; | |
182 | + spec->num_mixers = 2; | |
183 | spec->mixers[0] = ad1882_base_mixers; | |
184 | + if (codec->vendor_id == 0x11d1882) | |
185 | + spec->mixers[1] = ad1882_loopback_mixers; | |
186 | + else | |
187 | + spec->mixers[1] = ad1882a_loopback_mixers; | |
188 | spec->num_init_verbs = 1; | |
189 | spec->init_verbs[0] = ad1882_init_verbs; | |
190 | spec->spdif_route = 0; | |
191 | @@ -4239,8 +4291,8 @@ static int patch_ad1882(struct hda_codec | |
192 | switch (board_config) { | |
193 | default: | |
194 | case AD1882_3STACK: | |
195 | - spec->num_mixers = 2; | |
196 | - spec->mixers[1] = ad1882_3stack_mixers; | |
197 | + spec->num_mixers = 3; | |
198 | + spec->mixers[2] = ad1882_3stack_mixers; | |
199 | spec->channel_mode = ad1882_modes; | |
200 | spec->num_channel_mode = ARRAY_SIZE(ad1882_modes); | |
201 | spec->need_dac_fix = 1; | |
202 | @@ -4248,8 +4300,8 @@ static int patch_ad1882(struct hda_codec | |
203 | spec->multiout.num_dacs = 1; | |
204 | break; | |
205 | case AD1882_6STACK: | |
206 | - spec->num_mixers = 2; | |
207 | - spec->mixers[1] = ad1882_6stack_mixers; | |
208 | + spec->num_mixers = 3; | |
209 | + spec->mixers[2] = ad1882_6stack_mixers; | |
210 | break; | |
211 | } | |
212 | return 0; | |
213 | @@ -4272,6 +4324,7 @@ struct hda_codec_preset snd_hda_preset_a | |
214 | { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, | |
215 | { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, | |
216 | { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, | |
217 | + { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 }, | |
218 | { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 }, | |
219 | { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, | |
220 | {} /* terminator */ |