diff options
Diffstat (limited to 'sound/pci/hda/alc260_quirks.c')
-rw-r--r-- | sound/pci/hda/alc260_quirks.c | 1272 |
1 files changed, 1272 insertions, 0 deletions
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c new file mode 100644 index 00000000000..21ec2cb100b --- /dev/null +++ b/sound/pci/hda/alc260_quirks.c | |||
@@ -0,0 +1,1272 @@ | |||
1 | /* | ||
2 | * ALC260 quirk models | ||
3 | * included by patch_realtek.c | ||
4 | */ | ||
5 | |||
6 | /* ALC260 models */ | ||
7 | enum { | ||
8 | ALC260_AUTO, | ||
9 | ALC260_BASIC, | ||
10 | ALC260_HP, | ||
11 | ALC260_HP_DC7600, | ||
12 | ALC260_HP_3013, | ||
13 | ALC260_FUJITSU_S702X, | ||
14 | ALC260_ACER, | ||
15 | ALC260_WILL, | ||
16 | ALC260_REPLACER_672V, | ||
17 | ALC260_FAVORIT100, | ||
18 | #ifdef CONFIG_SND_DEBUG | ||
19 | ALC260_TEST, | ||
20 | #endif | ||
21 | ALC260_MODEL_LAST /* last tag */ | ||
22 | }; | ||
23 | |||
24 | static const hda_nid_t alc260_dac_nids[1] = { | ||
25 | /* front */ | ||
26 | 0x02, | ||
27 | }; | ||
28 | |||
29 | static const hda_nid_t alc260_adc_nids[1] = { | ||
30 | /* ADC0 */ | ||
31 | 0x04, | ||
32 | }; | ||
33 | |||
34 | static const hda_nid_t alc260_adc_nids_alt[1] = { | ||
35 | /* ADC1 */ | ||
36 | 0x05, | ||
37 | }; | ||
38 | |||
39 | /* NIDs used when simultaneous access to both ADCs makes sense. Note that | ||
40 | * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. | ||
41 | */ | ||
42 | static const hda_nid_t alc260_dual_adc_nids[2] = { | ||
43 | /* ADC0, ADC1 */ | ||
44 | 0x04, 0x05 | ||
45 | }; | ||
46 | |||
47 | #define ALC260_DIGOUT_NID 0x03 | ||
48 | #define ALC260_DIGIN_NID 0x06 | ||
49 | |||
50 | static const struct hda_input_mux alc260_capture_source = { | ||
51 | .num_items = 4, | ||
52 | .items = { | ||
53 | { "Mic", 0x0 }, | ||
54 | { "Front Mic", 0x1 }, | ||
55 | { "Line", 0x2 }, | ||
56 | { "CD", 0x4 }, | ||
57 | }, | ||
58 | }; | ||
59 | |||
60 | /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, | ||
61 | * headphone jack and the internal CD lines since these are the only pins at | ||
62 | * which audio can appear. For flexibility, also allow the option of | ||
63 | * recording the mixer output on the second ADC (ADC0 doesn't have a | ||
64 | * connection to the mixer output). | ||
65 | */ | ||
66 | static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = { | ||
67 | { | ||
68 | .num_items = 3, | ||
69 | .items = { | ||
70 | { "Mic/Line", 0x0 }, | ||
71 | { "CD", 0x4 }, | ||
72 | { "Headphone", 0x2 }, | ||
73 | }, | ||
74 | }, | ||
75 | { | ||
76 | .num_items = 4, | ||
77 | .items = { | ||
78 | { "Mic/Line", 0x0 }, | ||
79 | { "CD", 0x4 }, | ||
80 | { "Headphone", 0x2 }, | ||
81 | { "Mixer", 0x5 }, | ||
82 | }, | ||
83 | }, | ||
84 | |||
85 | }; | ||
86 | |||
87 | /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to | ||
88 | * the Fujitsu S702x, but jacks are marked differently. | ||
89 | */ | ||
90 | static const struct hda_input_mux alc260_acer_capture_sources[2] = { | ||
91 | { | ||
92 | .num_items = 4, | ||
93 | .items = { | ||
94 | { "Mic", 0x0 }, | ||
95 | { "Line", 0x2 }, | ||
96 | { "CD", 0x4 }, | ||
97 | { "Headphone", 0x5 }, | ||
98 | }, | ||
99 | }, | ||
100 | { | ||
101 | .num_items = 5, | ||
102 | .items = { | ||
103 | { "Mic", 0x0 }, | ||
104 | { "Line", 0x2 }, | ||
105 | { "CD", 0x4 }, | ||
106 | { "Headphone", 0x6 }, | ||
107 | { "Mixer", 0x5 }, | ||
108 | }, | ||
109 | }, | ||
110 | }; | ||
111 | |||
112 | /* Maxdata Favorit 100XS */ | ||
113 | static const struct hda_input_mux alc260_favorit100_capture_sources[2] = { | ||
114 | { | ||
115 | .num_items = 2, | ||
116 | .items = { | ||
117 | { "Line/Mic", 0x0 }, | ||
118 | { "CD", 0x4 }, | ||
119 | }, | ||
120 | }, | ||
121 | { | ||
122 | .num_items = 3, | ||
123 | .items = { | ||
124 | { "Line/Mic", 0x0 }, | ||
125 | { "CD", 0x4 }, | ||
126 | { "Mixer", 0x5 }, | ||
127 | }, | ||
128 | }, | ||
129 | }; | ||
130 | |||
131 | /* | ||
132 | * This is just place-holder, so there's something for alc_build_pcms to look | ||
133 | * at when it calculates the maximum number of channels. ALC260 has no mixer | ||
134 | * element which allows changing the channel mode, so the verb list is | ||
135 | * never used. | ||
136 | */ | ||
137 | static const struct hda_channel_mode alc260_modes[1] = { | ||
138 | { 2, NULL }, | ||
139 | }; | ||
140 | |||
141 | |||
142 | /* Mixer combinations | ||
143 | * | ||
144 | * basic: base_output + input + pc_beep + capture | ||
145 | * HP: base_output + input + capture_alt | ||
146 | * HP_3013: hp_3013 + input + capture | ||
147 | * fujitsu: fujitsu + capture | ||
148 | * acer: acer + capture | ||
149 | */ | ||
150 | |||
151 | static const struct snd_kcontrol_new alc260_base_output_mixer[] = { | ||
152 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
153 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | ||
154 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
155 | HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), | ||
156 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | ||
157 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | ||
158 | { } /* end */ | ||
159 | }; | ||
160 | |||
161 | static const struct snd_kcontrol_new alc260_input_mixer[] = { | ||
162 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
163 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
164 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
165 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
166 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
167 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
168 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), | ||
169 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), | ||
170 | { } /* end */ | ||
171 | }; | ||
172 | |||
173 | /* update HP, line and mono out pins according to the master switch */ | ||
174 | static void alc260_hp_master_update(struct hda_codec *codec) | ||
175 | { | ||
176 | update_speakers(codec); | ||
177 | } | ||
178 | |||
179 | static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, | ||
180 | struct snd_ctl_elem_value *ucontrol) | ||
181 | { | ||
182 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
183 | struct alc_spec *spec = codec->spec; | ||
184 | *ucontrol->value.integer.value = !spec->master_mute; | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, | ||
189 | struct snd_ctl_elem_value *ucontrol) | ||
190 | { | ||
191 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
192 | struct alc_spec *spec = codec->spec; | ||
193 | int val = !*ucontrol->value.integer.value; | ||
194 | |||
195 | if (val == spec->master_mute) | ||
196 | return 0; | ||
197 | spec->master_mute = val; | ||
198 | alc260_hp_master_update(codec); | ||
199 | return 1; | ||
200 | } | ||
201 | |||
202 | static const struct snd_kcontrol_new alc260_hp_output_mixer[] = { | ||
203 | { | ||
204 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
205 | .name = "Master Playback Switch", | ||
206 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, | ||
207 | .info = snd_ctl_boolean_mono_info, | ||
208 | .get = alc260_hp_master_sw_get, | ||
209 | .put = alc260_hp_master_sw_put, | ||
210 | }, | ||
211 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
212 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | ||
213 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
214 | HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), | ||
215 | HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, | ||
216 | HDA_OUTPUT), | ||
217 | HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), | ||
218 | { } /* end */ | ||
219 | }; | ||
220 | |||
221 | static const struct hda_verb alc260_hp_unsol_verbs[] = { | ||
222 | {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
223 | {}, | ||
224 | }; | ||
225 | |||
226 | static void alc260_hp_setup(struct hda_codec *codec) | ||
227 | { | ||
228 | struct alc_spec *spec = codec->spec; | ||
229 | |||
230 | spec->autocfg.hp_pins[0] = 0x0f; | ||
231 | spec->autocfg.speaker_pins[0] = 0x10; | ||
232 | spec->autocfg.speaker_pins[1] = 0x11; | ||
233 | spec->automute = 1; | ||
234 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
235 | } | ||
236 | |||
237 | static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = { | ||
238 | { | ||
239 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
240 | .name = "Master Playback Switch", | ||
241 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, | ||
242 | .info = snd_ctl_boolean_mono_info, | ||
243 | .get = alc260_hp_master_sw_get, | ||
244 | .put = alc260_hp_master_sw_put, | ||
245 | }, | ||
246 | HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
247 | HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), | ||
248 | HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), | ||
249 | HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), | ||
250 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
251 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
252 | HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | ||
253 | HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), | ||
254 | { } /* end */ | ||
255 | }; | ||
256 | |||
257 | static void alc260_hp_3013_setup(struct hda_codec *codec) | ||
258 | { | ||
259 | struct alc_spec *spec = codec->spec; | ||
260 | |||
261 | spec->autocfg.hp_pins[0] = 0x15; | ||
262 | spec->autocfg.speaker_pins[0] = 0x10; | ||
263 | spec->autocfg.speaker_pins[1] = 0x11; | ||
264 | spec->automute = 1; | ||
265 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
266 | } | ||
267 | |||
268 | static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = { | ||
269 | .ops = &snd_hda_bind_vol, | ||
270 | .values = { | ||
271 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), | ||
272 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), | ||
273 | HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), | ||
274 | 0 | ||
275 | }, | ||
276 | }; | ||
277 | |||
278 | static const struct hda_bind_ctls alc260_dc7600_bind_switch = { | ||
279 | .ops = &snd_hda_bind_sw, | ||
280 | .values = { | ||
281 | HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), | ||
282 | HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), | ||
283 | 0 | ||
284 | }, | ||
285 | }; | ||
286 | |||
287 | static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { | ||
288 | HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), | ||
289 | HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), | ||
290 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), | ||
291 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), | ||
292 | { } /* end */ | ||
293 | }; | ||
294 | |||
295 | static const struct hda_verb alc260_hp_3013_unsol_verbs[] = { | ||
296 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
297 | {}, | ||
298 | }; | ||
299 | |||
300 | static void alc260_hp_3012_setup(struct hda_codec *codec) | ||
301 | { | ||
302 | struct alc_spec *spec = codec->spec; | ||
303 | |||
304 | spec->autocfg.hp_pins[0] = 0x10; | ||
305 | spec->autocfg.speaker_pins[0] = 0x0f; | ||
306 | spec->autocfg.speaker_pins[1] = 0x11; | ||
307 | spec->autocfg.speaker_pins[2] = 0x15; | ||
308 | spec->automute = 1; | ||
309 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
310 | } | ||
311 | |||
312 | /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, | ||
313 | * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. | ||
314 | */ | ||
315 | static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = { | ||
316 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
317 | HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), | ||
318 | ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
319 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
320 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
321 | HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
322 | HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
323 | ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
324 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
325 | HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), | ||
326 | { } /* end */ | ||
327 | }; | ||
328 | |||
329 | /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current | ||
330 | * versions of the ALC260 don't act on requests to enable mic bias from NID | ||
331 | * 0x0f (used to drive the headphone jack in these laptops). The ALC260 | ||
332 | * datasheet doesn't mention this restriction. At this stage it's not clear | ||
333 | * whether this behaviour is intentional or is a hardware bug in chip | ||
334 | * revisions available in early 2006. Therefore for now allow the | ||
335 | * "Headphone Jack Mode" control to span all choices, but if it turns out | ||
336 | * that the lack of mic bias for this NID is intentional we could change the | ||
337 | * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. | ||
338 | * | ||
339 | * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 | ||
340 | * don't appear to make the mic bias available from the "line" jack, even | ||
341 | * though the NID used for this jack (0x14) can supply it. The theory is | ||
342 | * that perhaps Acer have included blocking capacitors between the ALC260 | ||
343 | * and the output jack. If this turns out to be the case for all such | ||
344 | * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT | ||
345 | * to ALC_PIN_DIR_INOUT_NOMICBIAS. | ||
346 | * | ||
347 | * The C20x Tablet series have a mono internal speaker which is controlled | ||
348 | * via the chip's Mono sum widget and pin complex, so include the necessary | ||
349 | * controls for such models. On models without a "mono speaker" the control | ||
350 | * won't do anything. | ||
351 | */ | ||
352 | static const struct snd_kcontrol_new alc260_acer_mixer[] = { | ||
353 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
354 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), | ||
355 | ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), | ||
356 | HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, | ||
357 | HDA_OUTPUT), | ||
358 | HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, | ||
359 | HDA_INPUT), | ||
360 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
361 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
362 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
363 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
364 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
365 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
366 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
367 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
368 | { } /* end */ | ||
369 | }; | ||
370 | |||
371 | /* Maxdata Favorit 100XS: one output and one input (0x12) jack | ||
372 | */ | ||
373 | static const struct snd_kcontrol_new alc260_favorit100_mixer[] = { | ||
374 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
375 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), | ||
376 | ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), | ||
377 | HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
378 | HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
379 | ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
380 | { } /* end */ | ||
381 | }; | ||
382 | |||
383 | /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, | ||
384 | * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. | ||
385 | */ | ||
386 | static const struct snd_kcontrol_new alc260_will_mixer[] = { | ||
387 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
388 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), | ||
389 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
390 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
391 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
392 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
393 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
394 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
395 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
396 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
397 | { } /* end */ | ||
398 | }; | ||
399 | |||
400 | /* Replacer 672V ALC260 pin usage: Mic jack = 0x12, | ||
401 | * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. | ||
402 | */ | ||
403 | static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { | ||
404 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
405 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), | ||
406 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
407 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
408 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
409 | HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), | ||
410 | HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), | ||
411 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
412 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
413 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
414 | { } /* end */ | ||
415 | }; | ||
416 | |||
417 | /* | ||
418 | * initialization verbs | ||
419 | */ | ||
420 | static const struct hda_verb alc260_init_verbs[] = { | ||
421 | /* Line In pin widget for input */ | ||
422 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
423 | /* CD pin widget for input */ | ||
424 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
425 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
426 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
427 | /* Mic2 (front panel) pin widget for input and vref at 80% */ | ||
428 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
429 | /* LINE-2 is used for line-out in rear */ | ||
430 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
431 | /* select line-out */ | ||
432 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
433 | /* LINE-OUT pin */ | ||
434 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
435 | /* enable HP */ | ||
436 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
437 | /* enable Mono */ | ||
438 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
439 | /* mute capture amp left and right */ | ||
440 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
441 | /* set connection select to line in (default select for this ADC) */ | ||
442 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
443 | /* mute capture amp left and right */ | ||
444 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
445 | /* set connection select to line in (default select for this ADC) */ | ||
446 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
447 | /* set vol=0 Line-Out mixer amp left and right */ | ||
448 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
449 | /* unmute pin widget amp left and right (no gain on this amp) */ | ||
450 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
451 | /* set vol=0 HP mixer amp left and right */ | ||
452 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
453 | /* unmute pin widget amp left and right (no gain on this amp) */ | ||
454 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
455 | /* set vol=0 Mono mixer amp left and right */ | ||
456 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
457 | /* unmute pin widget amp left and right (no gain on this amp) */ | ||
458 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
459 | /* unmute LINE-2 out pin */ | ||
460 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
461 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & | ||
462 | * Line In 2 = 0x03 | ||
463 | */ | ||
464 | /* mute analog inputs */ | ||
465 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
466 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
467 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
468 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
469 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
470 | /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ | ||
471 | /* mute Front out path */ | ||
472 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
473 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
474 | /* mute Headphone out path */ | ||
475 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
476 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
477 | /* mute Mono out path */ | ||
478 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
479 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
480 | { } | ||
481 | }; | ||
482 | |||
483 | #if 0 /* should be identical with alc260_init_verbs? */ | ||
484 | static const struct hda_verb alc260_hp_init_verbs[] = { | ||
485 | /* Headphone and output */ | ||
486 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
487 | /* mono output */ | ||
488 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
489 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
490 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
491 | /* Mic2 (front panel) pin widget for input and vref at 80% */ | ||
492 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
493 | /* Line In pin widget for input */ | ||
494 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
495 | /* Line-2 pin widget for output */ | ||
496 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
497 | /* CD pin widget for input */ | ||
498 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
499 | /* unmute amp left and right */ | ||
500 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, | ||
501 | /* set connection select to line in (default select for this ADC) */ | ||
502 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
503 | /* unmute Line-Out mixer amp left and right (volume = 0) */ | ||
504 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
505 | /* mute pin widget amp left and right (no gain on this amp) */ | ||
506 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | ||
507 | /* unmute HP mixer amp left and right (volume = 0) */ | ||
508 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
509 | /* mute pin widget amp left and right (no gain on this amp) */ | ||
510 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | ||
511 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & | ||
512 | * Line In 2 = 0x03 | ||
513 | */ | ||
514 | /* mute analog inputs */ | ||
515 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
516 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
517 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
518 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
519 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
520 | /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ | ||
521 | /* Unmute Front out path */ | ||
522 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
523 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
524 | /* Unmute Headphone out path */ | ||
525 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
526 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
527 | /* Unmute Mono out path */ | ||
528 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
529 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
530 | { } | ||
531 | }; | ||
532 | #endif | ||
533 | |||
534 | static const struct hda_verb alc260_hp_3013_init_verbs[] = { | ||
535 | /* Line out and output */ | ||
536 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
537 | /* mono output */ | ||
538 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
539 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
540 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
541 | /* Mic2 (front panel) pin widget for input and vref at 80% */ | ||
542 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
543 | /* Line In pin widget for input */ | ||
544 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
545 | /* Headphone pin widget for output */ | ||
546 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
547 | /* CD pin widget for input */ | ||
548 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
549 | /* unmute amp left and right */ | ||
550 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, | ||
551 | /* set connection select to line in (default select for this ADC) */ | ||
552 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
553 | /* unmute Line-Out mixer amp left and right (volume = 0) */ | ||
554 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
555 | /* mute pin widget amp left and right (no gain on this amp) */ | ||
556 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | ||
557 | /* unmute HP mixer amp left and right (volume = 0) */ | ||
558 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
559 | /* mute pin widget amp left and right (no gain on this amp) */ | ||
560 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | ||
561 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & | ||
562 | * Line In 2 = 0x03 | ||
563 | */ | ||
564 | /* mute analog inputs */ | ||
565 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
566 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
567 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
568 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
569 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
570 | /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ | ||
571 | /* Unmute Front out path */ | ||
572 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
573 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
574 | /* Unmute Headphone out path */ | ||
575 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
576 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
577 | /* Unmute Mono out path */ | ||
578 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
579 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
580 | { } | ||
581 | }; | ||
582 | |||
583 | /* Initialisation sequence for ALC260 as configured in Fujitsu S702x | ||
584 | * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD | ||
585 | * audio = 0x16, internal speaker = 0x10. | ||
586 | */ | ||
587 | static const struct hda_verb alc260_fujitsu_init_verbs[] = { | ||
588 | /* Disable all GPIOs */ | ||
589 | {0x01, AC_VERB_SET_GPIO_MASK, 0}, | ||
590 | /* Internal speaker is connected to headphone pin */ | ||
591 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
592 | /* Headphone/Line-out jack connects to Line1 pin; make it an output */ | ||
593 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
594 | /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ | ||
595 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
596 | /* Ensure all other unused pins are disabled and muted. */ | ||
597 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
598 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
599 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
600 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
601 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
602 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
603 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
604 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
605 | |||
606 | /* Disable digital (SPDIF) pins */ | ||
607 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
608 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
609 | |||
610 | /* Ensure Line1 pin widget takes its input from the OUT1 sum bus | ||
611 | * when acting as an output. | ||
612 | */ | ||
613 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
614 | |||
615 | /* Start with output sum widgets muted and their output gains at min */ | ||
616 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
617 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
618 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
619 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
620 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
621 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
622 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
623 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
624 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
625 | |||
626 | /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ | ||
627 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
628 | /* Unmute Line1 pin widget output buffer since it starts as an output. | ||
629 | * If the pin mode is changed by the user the pin mode control will | ||
630 | * take care of enabling the pin's input/output buffers as needed. | ||
631 | * Therefore there's no need to enable the input buffer at this | ||
632 | * stage. | ||
633 | */ | ||
634 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
635 | /* Unmute input buffer of pin widget used for Line-in (no equiv | ||
636 | * mixer ctrl) | ||
637 | */ | ||
638 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
639 | |||
640 | /* Mute capture amp left and right */ | ||
641 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
642 | /* Set ADC connection select to match default mixer setting - line | ||
643 | * in (on mic1 pin) | ||
644 | */ | ||
645 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
646 | |||
647 | /* Do the same for the second ADC: mute capture input amp and | ||
648 | * set ADC connection to line in (on mic1 pin) | ||
649 | */ | ||
650 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
651 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
652 | |||
653 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
654 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
655 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
656 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
657 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
658 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
659 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
660 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
661 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
662 | |||
663 | { } | ||
664 | }; | ||
665 | |||
666 | /* Initialisation sequence for ALC260 as configured in Acer TravelMate and | ||
667 | * similar laptops (adapted from Fujitsu init verbs). | ||
668 | */ | ||
669 | static const struct hda_verb alc260_acer_init_verbs[] = { | ||
670 | /* On TravelMate laptops, GPIO 0 enables the internal speaker and | ||
671 | * the headphone jack. Turn this on and rely on the standard mute | ||
672 | * methods whenever the user wants to turn these outputs off. | ||
673 | */ | ||
674 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
675 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
676 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
677 | /* Internal speaker/Headphone jack is connected to Line-out pin */ | ||
678 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
679 | /* Internal microphone/Mic jack is connected to Mic1 pin */ | ||
680 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | ||
681 | /* Line In jack is connected to Line1 pin */ | ||
682 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
683 | /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ | ||
684 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
685 | /* Ensure all other unused pins are disabled and muted. */ | ||
686 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
687 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
688 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
689 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
690 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
691 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
692 | /* Disable digital (SPDIF) pins */ | ||
693 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
694 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
695 | |||
696 | /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum | ||
697 | * bus when acting as outputs. | ||
698 | */ | ||
699 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, | ||
700 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
701 | |||
702 | /* Start with output sum widgets muted and their output gains at min */ | ||
703 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
704 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
705 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
706 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
707 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
708 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
709 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
710 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
711 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
712 | |||
713 | /* Unmute Line-out pin widget amp left and right | ||
714 | * (no equiv mixer ctrl) | ||
715 | */ | ||
716 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
717 | /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ | ||
718 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
719 | /* Unmute Mic1 and Line1 pin widget input buffers since they start as | ||
720 | * inputs. If the pin mode is changed by the user the pin mode control | ||
721 | * will take care of enabling the pin's input/output buffers as needed. | ||
722 | * Therefore there's no need to enable the input buffer at this | ||
723 | * stage. | ||
724 | */ | ||
725 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
726 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
727 | |||
728 | /* Mute capture amp left and right */ | ||
729 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
730 | /* Set ADC connection select to match default mixer setting - mic | ||
731 | * (on mic1 pin) | ||
732 | */ | ||
733 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
734 | |||
735 | /* Do similar with the second ADC: mute capture input amp and | ||
736 | * set ADC connection to mic to match ALSA's default state. | ||
737 | */ | ||
738 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
739 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
740 | |||
741 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
742 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
743 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
744 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
745 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
746 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
747 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
748 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
749 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
750 | |||
751 | { } | ||
752 | }; | ||
753 | |||
754 | /* Initialisation sequence for Maxdata Favorit 100XS | ||
755 | * (adapted from Acer init verbs). | ||
756 | */ | ||
757 | static const struct hda_verb alc260_favorit100_init_verbs[] = { | ||
758 | /* GPIO 0 enables the output jack. | ||
759 | * Turn this on and rely on the standard mute | ||
760 | * methods whenever the user wants to turn these outputs off. | ||
761 | */ | ||
762 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
763 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
764 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
765 | /* Line/Mic input jack is connected to Mic1 pin */ | ||
766 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | ||
767 | /* Ensure all other unused pins are disabled and muted. */ | ||
768 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
769 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
770 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
771 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
772 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
773 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
774 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
775 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
776 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
777 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
778 | /* Disable digital (SPDIF) pins */ | ||
779 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
780 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
781 | |||
782 | /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum | ||
783 | * bus when acting as outputs. | ||
784 | */ | ||
785 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, | ||
786 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
787 | |||
788 | /* Start with output sum widgets muted and their output gains at min */ | ||
789 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
790 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
791 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
792 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
793 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
794 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
795 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
796 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
797 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
798 | |||
799 | /* Unmute Line-out pin widget amp left and right | ||
800 | * (no equiv mixer ctrl) | ||
801 | */ | ||
802 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
803 | /* Unmute Mic1 and Line1 pin widget input buffers since they start as | ||
804 | * inputs. If the pin mode is changed by the user the pin mode control | ||
805 | * will take care of enabling the pin's input/output buffers as needed. | ||
806 | * Therefore there's no need to enable the input buffer at this | ||
807 | * stage. | ||
808 | */ | ||
809 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
810 | |||
811 | /* Mute capture amp left and right */ | ||
812 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
813 | /* Set ADC connection select to match default mixer setting - mic | ||
814 | * (on mic1 pin) | ||
815 | */ | ||
816 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
817 | |||
818 | /* Do similar with the second ADC: mute capture input amp and | ||
819 | * set ADC connection to mic to match ALSA's default state. | ||
820 | */ | ||
821 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
822 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
823 | |||
824 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
825 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
826 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
827 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
828 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
829 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
830 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
831 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
832 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
833 | |||
834 | { } | ||
835 | }; | ||
836 | |||
837 | static const struct hda_verb alc260_will_verbs[] = { | ||
838 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
839 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
840 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
841 | {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
842 | {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
843 | {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, | ||
844 | {} | ||
845 | }; | ||
846 | |||
847 | static const struct hda_verb alc260_replacer_672v_verbs[] = { | ||
848 | {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
849 | {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
850 | {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, | ||
851 | |||
852 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
853 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
854 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||
855 | |||
856 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
857 | {} | ||
858 | }; | ||
859 | |||
860 | /* toggle speaker-output according to the hp-jack state */ | ||
861 | static void alc260_replacer_672v_automute(struct hda_codec *codec) | ||
862 | { | ||
863 | unsigned int present; | ||
864 | |||
865 | /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ | ||
866 | present = snd_hda_jack_detect(codec, 0x0f); | ||
867 | if (present) { | ||
868 | snd_hda_codec_write_cache(codec, 0x01, 0, | ||
869 | AC_VERB_SET_GPIO_DATA, 1); | ||
870 | snd_hda_codec_write_cache(codec, 0x0f, 0, | ||
871 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
872 | PIN_HP); | ||
873 | } else { | ||
874 | snd_hda_codec_write_cache(codec, 0x01, 0, | ||
875 | AC_VERB_SET_GPIO_DATA, 0); | ||
876 | snd_hda_codec_write_cache(codec, 0x0f, 0, | ||
877 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
878 | PIN_OUT); | ||
879 | } | ||
880 | } | ||
881 | |||
882 | static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, | ||
883 | unsigned int res) | ||
884 | { | ||
885 | if ((res >> 26) == ALC_HP_EVENT) | ||
886 | alc260_replacer_672v_automute(codec); | ||
887 | } | ||
888 | |||
889 | static const struct hda_verb alc260_hp_dc7600_verbs[] = { | ||
890 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
891 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
892 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
893 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
894 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
895 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
896 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
897 | {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
898 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
899 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
900 | {} | ||
901 | }; | ||
902 | |||
903 | /* Test configuration for debugging, modelled after the ALC880 test | ||
904 | * configuration. | ||
905 | */ | ||
906 | #ifdef CONFIG_SND_DEBUG | ||
907 | static const hda_nid_t alc260_test_dac_nids[1] = { | ||
908 | 0x02, | ||
909 | }; | ||
910 | static const hda_nid_t alc260_test_adc_nids[2] = { | ||
911 | 0x04, 0x05, | ||
912 | }; | ||
913 | /* For testing the ALC260, each input MUX needs its own definition since | ||
914 | * the signal assignments are different. This assumes that the first ADC | ||
915 | * is NID 0x04. | ||
916 | */ | ||
917 | static const struct hda_input_mux alc260_test_capture_sources[2] = { | ||
918 | { | ||
919 | .num_items = 7, | ||
920 | .items = { | ||
921 | { "MIC1 pin", 0x0 }, | ||
922 | { "MIC2 pin", 0x1 }, | ||
923 | { "LINE1 pin", 0x2 }, | ||
924 | { "LINE2 pin", 0x3 }, | ||
925 | { "CD pin", 0x4 }, | ||
926 | { "LINE-OUT pin", 0x5 }, | ||
927 | { "HP-OUT pin", 0x6 }, | ||
928 | }, | ||
929 | }, | ||
930 | { | ||
931 | .num_items = 8, | ||
932 | .items = { | ||
933 | { "MIC1 pin", 0x0 }, | ||
934 | { "MIC2 pin", 0x1 }, | ||
935 | { "LINE1 pin", 0x2 }, | ||
936 | { "LINE2 pin", 0x3 }, | ||
937 | { "CD pin", 0x4 }, | ||
938 | { "Mixer", 0x5 }, | ||
939 | { "LINE-OUT pin", 0x6 }, | ||
940 | { "HP-OUT pin", 0x7 }, | ||
941 | }, | ||
942 | }, | ||
943 | }; | ||
944 | static const struct snd_kcontrol_new alc260_test_mixer[] = { | ||
945 | /* Output driver widgets */ | ||
946 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | ||
947 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | ||
948 | HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
949 | HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), | ||
950 | HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
951 | HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), | ||
952 | |||
953 | /* Modes for retasking pin widgets | ||
954 | * Note: the ALC260 doesn't seem to act on requests to enable mic | ||
955 | * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't | ||
956 | * mention this restriction. At this stage it's not clear whether | ||
957 | * this behaviour is intentional or is a hardware bug in chip | ||
958 | * revisions available at least up until early 2006. Therefore for | ||
959 | * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all | ||
960 | * choices, but if it turns out that the lack of mic bias for these | ||
961 | * NIDs is intentional we could change their modes from | ||
962 | * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. | ||
963 | */ | ||
964 | ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), | ||
965 | ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), | ||
966 | ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), | ||
967 | ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), | ||
968 | ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), | ||
969 | ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), | ||
970 | |||
971 | /* Loopback mixer controls */ | ||
972 | HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), | ||
973 | HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), | ||
974 | HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), | ||
975 | HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), | ||
976 | HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
977 | HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
978 | HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), | ||
979 | HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), | ||
980 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
981 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
982 | HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), | ||
983 | HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), | ||
984 | HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), | ||
985 | HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), | ||
986 | |||
987 | /* Controls for GPIO pins, assuming they are configured as outputs */ | ||
988 | ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), | ||
989 | ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), | ||
990 | ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), | ||
991 | ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), | ||
992 | |||
993 | /* Switches to allow the digital IO pins to be enabled. The datasheet | ||
994 | * is ambigious as to which NID is which; testing on laptops which | ||
995 | * make this output available should provide clarification. | ||
996 | */ | ||
997 | ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), | ||
998 | ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), | ||
999 | |||
1000 | /* A switch allowing EAPD to be enabled. Some laptops seem to use | ||
1001 | * this output to turn on an external amplifier. | ||
1002 | */ | ||
1003 | ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), | ||
1004 | ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), | ||
1005 | |||
1006 | { } /* end */ | ||
1007 | }; | ||
1008 | static const struct hda_verb alc260_test_init_verbs[] = { | ||
1009 | /* Enable all GPIOs as outputs with an initial value of 0 */ | ||
1010 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, | ||
1011 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||
1012 | {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, | ||
1013 | |||
1014 | /* Enable retasking pins as output, initially without power amp */ | ||
1015 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1016 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1017 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1018 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1019 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1020 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1021 | |||
1022 | /* Disable digital (SPDIF) pins initially, but users can enable | ||
1023 | * them via a mixer switch. In the case of SPDIF-out, this initverb | ||
1024 | * payload also sets the generation to 0, output to be in "consumer" | ||
1025 | * PCM format, copyright asserted, no pre-emphasis and no validity | ||
1026 | * control. | ||
1027 | */ | ||
1028 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
1029 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
1030 | |||
1031 | /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the | ||
1032 | * OUT1 sum bus when acting as an output. | ||
1033 | */ | ||
1034 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, | ||
1035 | {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, | ||
1036 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
1037 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, | ||
1038 | |||
1039 | /* Start with output sum widgets muted and their output gains at min */ | ||
1040 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1041 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1042 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1043 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1044 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1045 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1046 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1047 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1048 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1049 | |||
1050 | /* Unmute retasking pin widget output buffers since the default | ||
1051 | * state appears to be output. As the pin mode is changed by the | ||
1052 | * user the pin mode control will take care of enabling the pin's | ||
1053 | * input/output buffers as needed. | ||
1054 | */ | ||
1055 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1056 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1057 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1058 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1059 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1060 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1061 | /* Also unmute the mono-out pin widget */ | ||
1062 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1063 | |||
1064 | /* Mute capture amp left and right */ | ||
1065 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1066 | /* Set ADC connection select to match default mixer setting (mic1 | ||
1067 | * pin) | ||
1068 | */ | ||
1069 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1070 | |||
1071 | /* Do the same for the second ADC: mute capture input amp and | ||
1072 | * set ADC connection to mic1 pin | ||
1073 | */ | ||
1074 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1075 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1076 | |||
1077 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
1078 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
1079 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
1080 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
1081 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
1082 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
1083 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
1084 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
1085 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
1086 | |||
1087 | { } | ||
1088 | }; | ||
1089 | #endif | ||
1090 | |||
1091 | /* | ||
1092 | * ALC260 configurations | ||
1093 | */ | ||
1094 | static const char * const alc260_models[ALC260_MODEL_LAST] = { | ||
1095 | [ALC260_BASIC] = "basic", | ||
1096 | [ALC260_HP] = "hp", | ||
1097 | [ALC260_HP_3013] = "hp-3013", | ||
1098 | [ALC260_HP_DC7600] = "hp-dc7600", | ||
1099 | [ALC260_FUJITSU_S702X] = "fujitsu", | ||
1100 | [ALC260_ACER] = "acer", | ||
1101 | [ALC260_WILL] = "will", | ||
1102 | [ALC260_REPLACER_672V] = "replacer", | ||
1103 | [ALC260_FAVORIT100] = "favorit100", | ||
1104 | #ifdef CONFIG_SND_DEBUG | ||
1105 | [ALC260_TEST] = "test", | ||
1106 | #endif | ||
1107 | [ALC260_AUTO] = "auto", | ||
1108 | }; | ||
1109 | |||
1110 | static const struct snd_pci_quirk alc260_cfg_tbl[] = { | ||
1111 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), | ||
1112 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), | ||
1113 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), | ||
1114 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), | ||
1115 | SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), | ||
1116 | SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ | ||
1117 | SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), | ||
1118 | SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), | ||
1119 | SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), | ||
1120 | SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), | ||
1121 | SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), | ||
1122 | SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), | ||
1123 | SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), | ||
1124 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), | ||
1125 | SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), | ||
1126 | SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), | ||
1127 | SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), | ||
1128 | SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), | ||
1129 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), | ||
1130 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), | ||
1131 | {} | ||
1132 | }; | ||
1133 | |||
1134 | static const struct alc_config_preset alc260_presets[] = { | ||
1135 | [ALC260_BASIC] = { | ||
1136 | .mixers = { alc260_base_output_mixer, | ||
1137 | alc260_input_mixer }, | ||
1138 | .init_verbs = { alc260_init_verbs }, | ||
1139 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
1140 | .dac_nids = alc260_dac_nids, | ||
1141 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), | ||
1142 | .adc_nids = alc260_dual_adc_nids, | ||
1143 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
1144 | .channel_mode = alc260_modes, | ||
1145 | .input_mux = &alc260_capture_source, | ||
1146 | }, | ||
1147 | [ALC260_HP] = { | ||
1148 | .mixers = { alc260_hp_output_mixer, | ||
1149 | alc260_input_mixer }, | ||
1150 | .init_verbs = { alc260_init_verbs, | ||
1151 | alc260_hp_unsol_verbs }, | ||
1152 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
1153 | .dac_nids = alc260_dac_nids, | ||
1154 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), | ||
1155 | .adc_nids = alc260_adc_nids_alt, | ||
1156 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
1157 | .channel_mode = alc260_modes, | ||
1158 | .input_mux = &alc260_capture_source, | ||
1159 | .unsol_event = alc_sku_unsol_event, | ||
1160 | .setup = alc260_hp_setup, | ||
1161 | .init_hook = alc_inithook, | ||
1162 | }, | ||
1163 | [ALC260_HP_DC7600] = { | ||
1164 | .mixers = { alc260_hp_dc7600_mixer, | ||
1165 | alc260_input_mixer }, | ||
1166 | .init_verbs = { alc260_init_verbs, | ||
1167 | alc260_hp_dc7600_verbs }, | ||
1168 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
1169 | .dac_nids = alc260_dac_nids, | ||
1170 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), | ||
1171 | .adc_nids = alc260_adc_nids_alt, | ||
1172 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
1173 | .channel_mode = alc260_modes, | ||
1174 | .input_mux = &alc260_capture_source, | ||
1175 | .unsol_event = alc_sku_unsol_event, | ||
1176 | .setup = alc260_hp_3012_setup, | ||
1177 | .init_hook = alc_inithook, | ||
1178 | }, | ||
1179 | [ALC260_HP_3013] = { | ||
1180 | .mixers = { alc260_hp_3013_mixer, | ||
1181 | alc260_input_mixer }, | ||
1182 | .init_verbs = { alc260_hp_3013_init_verbs, | ||
1183 | alc260_hp_3013_unsol_verbs }, | ||
1184 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
1185 | .dac_nids = alc260_dac_nids, | ||
1186 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), | ||
1187 | .adc_nids = alc260_adc_nids_alt, | ||
1188 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
1189 | .channel_mode = alc260_modes, | ||
1190 | .input_mux = &alc260_capture_source, | ||
1191 | .unsol_event = alc_sku_unsol_event, | ||
1192 | .setup = alc260_hp_3013_setup, | ||
1193 | .init_hook = alc_inithook, | ||
1194 | }, | ||
1195 | [ALC260_FUJITSU_S702X] = { | ||
1196 | .mixers = { alc260_fujitsu_mixer }, | ||
1197 | .init_verbs = { alc260_fujitsu_init_verbs }, | ||
1198 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
1199 | .dac_nids = alc260_dac_nids, | ||
1200 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), | ||
1201 | .adc_nids = alc260_dual_adc_nids, | ||
1202 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
1203 | .channel_mode = alc260_modes, | ||
1204 | .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), | ||
1205 | .input_mux = alc260_fujitsu_capture_sources, | ||
1206 | }, | ||
1207 | [ALC260_ACER] = { | ||
1208 | .mixers = { alc260_acer_mixer }, | ||
1209 | .init_verbs = { alc260_acer_init_verbs }, | ||
1210 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
1211 | .dac_nids = alc260_dac_nids, | ||
1212 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), | ||
1213 | .adc_nids = alc260_dual_adc_nids, | ||
1214 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
1215 | .channel_mode = alc260_modes, | ||
1216 | .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), | ||
1217 | .input_mux = alc260_acer_capture_sources, | ||
1218 | }, | ||
1219 | [ALC260_FAVORIT100] = { | ||
1220 | .mixers = { alc260_favorit100_mixer }, | ||
1221 | .init_verbs = { alc260_favorit100_init_verbs }, | ||
1222 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
1223 | .dac_nids = alc260_dac_nids, | ||
1224 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), | ||
1225 | .adc_nids = alc260_dual_adc_nids, | ||
1226 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
1227 | .channel_mode = alc260_modes, | ||
1228 | .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), | ||
1229 | .input_mux = alc260_favorit100_capture_sources, | ||
1230 | }, | ||
1231 | [ALC260_WILL] = { | ||
1232 | .mixers = { alc260_will_mixer }, | ||
1233 | .init_verbs = { alc260_init_verbs, alc260_will_verbs }, | ||
1234 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
1235 | .dac_nids = alc260_dac_nids, | ||
1236 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), | ||
1237 | .adc_nids = alc260_adc_nids, | ||
1238 | .dig_out_nid = ALC260_DIGOUT_NID, | ||
1239 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
1240 | .channel_mode = alc260_modes, | ||
1241 | .input_mux = &alc260_capture_source, | ||
1242 | }, | ||
1243 | [ALC260_REPLACER_672V] = { | ||
1244 | .mixers = { alc260_replacer_672v_mixer }, | ||
1245 | .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, | ||
1246 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
1247 | .dac_nids = alc260_dac_nids, | ||
1248 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), | ||
1249 | .adc_nids = alc260_adc_nids, | ||
1250 | .dig_out_nid = ALC260_DIGOUT_NID, | ||
1251 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
1252 | .channel_mode = alc260_modes, | ||
1253 | .input_mux = &alc260_capture_source, | ||
1254 | .unsol_event = alc260_replacer_672v_unsol_event, | ||
1255 | .init_hook = alc260_replacer_672v_automute, | ||
1256 | }, | ||
1257 | #ifdef CONFIG_SND_DEBUG | ||
1258 | [ALC260_TEST] = { | ||
1259 | .mixers = { alc260_test_mixer }, | ||
1260 | .init_verbs = { alc260_test_init_verbs }, | ||
1261 | .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), | ||
1262 | .dac_nids = alc260_test_dac_nids, | ||
1263 | .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), | ||
1264 | .adc_nids = alc260_test_adc_nids, | ||
1265 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
1266 | .channel_mode = alc260_modes, | ||
1267 | .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), | ||
1268 | .input_mux = alc260_test_capture_sources, | ||
1269 | }, | ||
1270 | #endif | ||
1271 | }; | ||
1272 | |||