diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-06-06 12:21:38 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-06-25 08:51:24 -0400 |
commit | db8e8a9dc97224b016461e596721ebbcfed9c08d (patch) | |
tree | af2e2e04b968f6871dd753f3a4177c4d6bc50ab4 | |
parent | d0ea6d270bd9f1883f716f92e7837152a4146cf7 (diff) |
ALSA: hda - Remove the obsoleted static quirk codes from patch_cmedia.c
The static quirk code has been disabled for a while and it seems
working fine, so it's time to actually get rid of it.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 624 |
1 files changed, 9 insertions, 615 deletions
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 061ea5965dd5..ed3d133ffbb6 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -31,550 +31,11 @@ | |||
31 | #include "hda_jack.h" | 31 | #include "hda_jack.h" |
32 | #include "hda_generic.h" | 32 | #include "hda_generic.h" |
33 | 33 | ||
34 | #undef ENABLE_CMI_STATIC_QUIRKS | ||
35 | |||
36 | #ifdef ENABLE_CMI_STATIC_QUIRKS | ||
37 | #define NUM_PINS 11 | ||
38 | |||
39 | |||
40 | /* board config type */ | ||
41 | enum { | ||
42 | CMI_MINIMAL, /* back 3-jack */ | ||
43 | CMI_MIN_FP, /* back 3-jack + front-panel 2-jack */ | ||
44 | CMI_FULL, /* back 6-jack + front-panel 2-jack */ | ||
45 | CMI_FULL_DIG, /* back 6-jack + front-panel 2-jack + digital I/O */ | ||
46 | CMI_ALLOUT, /* back 5-jack + front-panel 2-jack + digital out */ | ||
47 | CMI_AUTO, /* let driver guess it */ | ||
48 | CMI_MODELS | ||
49 | }; | ||
50 | #endif /* ENABLE_CMI_STATIC_QUIRKS */ | ||
51 | |||
52 | struct cmi_spec { | 34 | struct cmi_spec { |
53 | struct hda_gen_spec gen; | 35 | struct hda_gen_spec gen; |
54 | |||
55 | #ifdef ENABLE_CMI_STATIC_QUIRKS | ||
56 | /* below are only for static models */ | ||
57 | |||
58 | int board_config; | ||
59 | unsigned int no_line_in: 1; /* no line-in (5-jack) */ | ||
60 | unsigned int front_panel: 1; /* has front-panel 2-jack */ | ||
61 | |||
62 | /* playback */ | ||
63 | struct hda_multi_out multiout; | ||
64 | hda_nid_t dac_nids[AUTO_CFG_MAX_OUTS]; /* NID for each DAC */ | ||
65 | int num_dacs; | ||
66 | |||
67 | /* capture */ | ||
68 | const hda_nid_t *adc_nids; | ||
69 | hda_nid_t dig_in_nid; | ||
70 | |||
71 | /* capture source */ | ||
72 | const struct hda_input_mux *input_mux; | ||
73 | unsigned int cur_mux[2]; | ||
74 | |||
75 | /* channel mode */ | ||
76 | int num_channel_modes; | ||
77 | const struct hda_channel_mode *channel_modes; | ||
78 | |||
79 | struct hda_pcm pcm_rec[2]; /* PCM information */ | ||
80 | |||
81 | /* pin default configuration */ | ||
82 | hda_nid_t pin_nid[NUM_PINS]; | ||
83 | unsigned int def_conf[NUM_PINS]; | ||
84 | unsigned int pin_def_confs; | ||
85 | |||
86 | /* multichannel pins */ | ||
87 | struct hda_verb multi_init[9]; /* 2 verbs for each pin + terminator */ | ||
88 | #endif /* ENABLE_CMI_STATIC_QUIRKS */ | ||
89 | }; | ||
90 | |||
91 | #ifdef ENABLE_CMI_STATIC_QUIRKS | ||
92 | /* | ||
93 | * input MUX | ||
94 | */ | ||
95 | static int cmi_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
96 | { | ||
97 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
98 | struct cmi_spec *spec = codec->spec; | ||
99 | return snd_hda_input_mux_info(spec->input_mux, uinfo); | ||
100 | } | ||
101 | |||
102 | static int cmi_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
103 | { | ||
104 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
105 | struct cmi_spec *spec = codec->spec; | ||
106 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
107 | |||
108 | ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static int cmi_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
113 | { | ||
114 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
115 | struct cmi_spec *spec = codec->spec; | ||
116 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
117 | |||
118 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
119 | spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * shared line-in, mic for surrounds | ||
124 | */ | ||
125 | |||
126 | /* 3-stack / 2 channel */ | ||
127 | static const struct hda_verb cmi9880_ch2_init[] = { | ||
128 | /* set line-in PIN for input */ | ||
129 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
130 | /* set mic PIN for input, also enable vref */ | ||
131 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
132 | /* route front PCM (DAC1) to HP */ | ||
133 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
134 | {} | ||
135 | }; | ||
136 | |||
137 | /* 3-stack / 6 channel */ | ||
138 | static const struct hda_verb cmi9880_ch6_init[] = { | ||
139 | /* set line-in PIN for output */ | ||
140 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
141 | /* set mic PIN for output */ | ||
142 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
143 | /* route front PCM (DAC1) to HP */ | ||
144 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
145 | {} | ||
146 | }; | ||
147 | |||
148 | /* 3-stack+front / 8 channel */ | ||
149 | static const struct hda_verb cmi9880_ch8_init[] = { | ||
150 | /* set line-in PIN for output */ | ||
151 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
152 | /* set mic PIN for output */ | ||
153 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
154 | /* route rear-surround PCM (DAC4) to HP */ | ||
155 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x03 }, | ||
156 | {} | ||
157 | }; | ||
158 | |||
159 | static const struct hda_channel_mode cmi9880_channel_modes[3] = { | ||
160 | { 2, cmi9880_ch2_init }, | ||
161 | { 6, cmi9880_ch6_init }, | ||
162 | { 8, cmi9880_ch8_init }, | ||
163 | }; | ||
164 | |||
165 | static int cmi_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
166 | { | ||
167 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
168 | struct cmi_spec *spec = codec->spec; | ||
169 | return snd_hda_ch_mode_info(codec, uinfo, spec->channel_modes, | ||
170 | spec->num_channel_modes); | ||
171 | } | ||
172 | |||
173 | static int cmi_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
174 | { | ||
175 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
176 | struct cmi_spec *spec = codec->spec; | ||
177 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_modes, | ||
178 | spec->num_channel_modes, spec->multiout.max_channels); | ||
179 | } | ||
180 | |||
181 | static int cmi_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
182 | { | ||
183 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
184 | struct cmi_spec *spec = codec->spec; | ||
185 | return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_modes, | ||
186 | spec->num_channel_modes, &spec->multiout.max_channels); | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | */ | ||
191 | static const struct snd_kcontrol_new cmi9880_basic_mixer[] = { | ||
192 | /* CMI9880 has no playback volumes! */ | ||
193 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */ | ||
194 | HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT), | ||
195 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), | ||
196 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), | ||
197 | HDA_CODEC_MUTE("Side Playback Switch", 0x06, 0x0, HDA_OUTPUT), | ||
198 | { | ||
199 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
200 | /* The multiple "Capture Source" controls confuse alsamixer | ||
201 | * So call somewhat different.. | ||
202 | */ | ||
203 | /* .name = "Capture Source", */ | ||
204 | .name = "Input Source", | ||
205 | .count = 2, | ||
206 | .info = cmi_mux_enum_info, | ||
207 | .get = cmi_mux_enum_get, | ||
208 | .put = cmi_mux_enum_put, | ||
209 | }, | ||
210 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0, HDA_INPUT), | ||
211 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0, HDA_INPUT), | ||
212 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0, HDA_INPUT), | ||
213 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0, HDA_INPUT), | ||
214 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x23, 0, HDA_OUTPUT), | ||
215 | HDA_CODEC_MUTE("Beep Playback Switch", 0x23, 0, HDA_OUTPUT), | ||
216 | { } /* end */ | ||
217 | }; | 36 | }; |
218 | 37 | ||
219 | /* | 38 | /* |
220 | * shared I/O pins | ||
221 | */ | ||
222 | static const struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = { | ||
223 | { | ||
224 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
225 | .name = "Channel Mode", | ||
226 | .info = cmi_ch_mode_info, | ||
227 | .get = cmi_ch_mode_get, | ||
228 | .put = cmi_ch_mode_put, | ||
229 | }, | ||
230 | { } /* end */ | ||
231 | }; | ||
232 | |||
233 | /* AUD-in selections: | ||
234 | * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20 | ||
235 | */ | ||
236 | static const struct hda_input_mux cmi9880_basic_mux = { | ||
237 | .num_items = 4, | ||
238 | .items = { | ||
239 | { "Front Mic", 0x5 }, | ||
240 | { "Rear Mic", 0x2 }, | ||
241 | { "Line", 0x1 }, | ||
242 | { "CD", 0x7 }, | ||
243 | } | ||
244 | }; | ||
245 | |||
246 | static const struct hda_input_mux cmi9880_no_line_mux = { | ||
247 | .num_items = 3, | ||
248 | .items = { | ||
249 | { "Front Mic", 0x5 }, | ||
250 | { "Rear Mic", 0x2 }, | ||
251 | { "CD", 0x7 }, | ||
252 | } | ||
253 | }; | ||
254 | |||
255 | /* front, rear, clfe, rear_surr */ | ||
256 | static const hda_nid_t cmi9880_dac_nids[4] = { | ||
257 | 0x03, 0x04, 0x05, 0x06 | ||
258 | }; | ||
259 | /* ADC0, ADC1 */ | ||
260 | static const hda_nid_t cmi9880_adc_nids[2] = { | ||
261 | 0x08, 0x09 | ||
262 | }; | ||
263 | |||
264 | #define CMI_DIG_OUT_NID 0x07 | ||
265 | #define CMI_DIG_IN_NID 0x0a | ||
266 | |||
267 | /* | ||
268 | */ | ||
269 | static const struct hda_verb cmi9880_basic_init[] = { | ||
270 | /* port-D for line out (rear panel) */ | ||
271 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
272 | /* port-E for HP out (front panel) */ | ||
273 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
274 | /* route front PCM to HP */ | ||
275 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
276 | /* port-A for surround (rear panel) */ | ||
277 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
278 | /* port-G for CLFE (rear panel) */ | ||
279 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
280 | { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
281 | /* port-H for side (rear panel) */ | ||
282 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
283 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
284 | /* port-C for line-in (rear panel) */ | ||
285 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
286 | /* port-B for mic-in (rear panel) with vref */ | ||
287 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
288 | /* port-F for mic-in (front panel) with vref */ | ||
289 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
290 | /* CD-in */ | ||
291 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
292 | /* route front mic to ADC1/2 */ | ||
293 | { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 }, | ||
294 | { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 }, | ||
295 | {} /* terminator */ | ||
296 | }; | ||
297 | |||
298 | static const struct hda_verb cmi9880_allout_init[] = { | ||
299 | /* port-D for line out (rear panel) */ | ||
300 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
301 | /* port-E for HP out (front panel) */ | ||
302 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
303 | /* route front PCM to HP */ | ||
304 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
305 | /* port-A for side (rear panel) */ | ||
306 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
307 | /* port-G for CLFE (rear panel) */ | ||
308 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
309 | { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
310 | /* port-H for side (rear panel) */ | ||
311 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
312 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
313 | /* port-C for surround (rear panel) */ | ||
314 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
315 | /* port-B for mic-in (rear panel) with vref */ | ||
316 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
317 | /* port-F for mic-in (front panel) with vref */ | ||
318 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
319 | /* CD-in */ | ||
320 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
321 | /* route front mic to ADC1/2 */ | ||
322 | { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 }, | ||
323 | { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 }, | ||
324 | {} /* terminator */ | ||
325 | }; | ||
326 | |||
327 | /* | ||
328 | */ | ||
329 | static int cmi9880_build_controls(struct hda_codec *codec) | ||
330 | { | ||
331 | struct cmi_spec *spec = codec->spec; | ||
332 | struct snd_kcontrol *kctl; | ||
333 | int i, err; | ||
334 | |||
335 | err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer); | ||
336 | if (err < 0) | ||
337 | return err; | ||
338 | if (spec->channel_modes) { | ||
339 | err = snd_hda_add_new_ctls(codec, cmi9880_ch_mode_mixer); | ||
340 | if (err < 0) | ||
341 | return err; | ||
342 | } | ||
343 | if (spec->multiout.dig_out_nid) { | ||
344 | err = snd_hda_create_spdif_out_ctls(codec, | ||
345 | spec->multiout.dig_out_nid, | ||
346 | spec->multiout.dig_out_nid); | ||
347 | if (err < 0) | ||
348 | return err; | ||
349 | err = snd_hda_create_spdif_share_sw(codec, | ||
350 | &spec->multiout); | ||
351 | if (err < 0) | ||
352 | return err; | ||
353 | spec->multiout.share_spdif = 1; | ||
354 | } | ||
355 | if (spec->dig_in_nid) { | ||
356 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | ||
357 | if (err < 0) | ||
358 | return err; | ||
359 | } | ||
360 | |||
361 | /* assign Capture Source enums to NID */ | ||
362 | kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); | ||
363 | for (i = 0; kctl && i < kctl->count; i++) { | ||
364 | err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]); | ||
365 | if (err < 0) | ||
366 | return err; | ||
367 | } | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static int cmi9880_init(struct hda_codec *codec) | ||
372 | { | ||
373 | struct cmi_spec *spec = codec->spec; | ||
374 | if (spec->board_config == CMI_ALLOUT) | ||
375 | snd_hda_sequence_write(codec, cmi9880_allout_init); | ||
376 | else | ||
377 | snd_hda_sequence_write(codec, cmi9880_basic_init); | ||
378 | if (spec->board_config == CMI_AUTO) | ||
379 | snd_hda_sequence_write(codec, spec->multi_init); | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | /* | ||
384 | * Analog playback callbacks | ||
385 | */ | ||
386 | static int cmi9880_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
387 | struct hda_codec *codec, | ||
388 | struct snd_pcm_substream *substream) | ||
389 | { | ||
390 | struct cmi_spec *spec = codec->spec; | ||
391 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
392 | hinfo); | ||
393 | } | ||
394 | |||
395 | static int cmi9880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
396 | struct hda_codec *codec, | ||
397 | unsigned int stream_tag, | ||
398 | unsigned int format, | ||
399 | struct snd_pcm_substream *substream) | ||
400 | { | ||
401 | struct cmi_spec *spec = codec->spec; | ||
402 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, | ||
403 | format, substream); | ||
404 | } | ||
405 | |||
406 | static int cmi9880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
407 | struct hda_codec *codec, | ||
408 | struct snd_pcm_substream *substream) | ||
409 | { | ||
410 | struct cmi_spec *spec = codec->spec; | ||
411 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * Digital out | ||
416 | */ | ||
417 | static int cmi9880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
418 | struct hda_codec *codec, | ||
419 | struct snd_pcm_substream *substream) | ||
420 | { | ||
421 | struct cmi_spec *spec = codec->spec; | ||
422 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | ||
423 | } | ||
424 | |||
425 | static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
426 | struct hda_codec *codec, | ||
427 | struct snd_pcm_substream *substream) | ||
428 | { | ||
429 | struct cmi_spec *spec = codec->spec; | ||
430 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | ||
431 | } | ||
432 | |||
433 | static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
434 | struct hda_codec *codec, | ||
435 | unsigned int stream_tag, | ||
436 | unsigned int format, | ||
437 | struct snd_pcm_substream *substream) | ||
438 | { | ||
439 | struct cmi_spec *spec = codec->spec; | ||
440 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
441 | format, substream); | ||
442 | } | ||
443 | |||
444 | /* | ||
445 | * Analog capture | ||
446 | */ | ||
447 | static int cmi9880_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
448 | struct hda_codec *codec, | ||
449 | unsigned int stream_tag, | ||
450 | unsigned int format, | ||
451 | struct snd_pcm_substream *substream) | ||
452 | { | ||
453 | struct cmi_spec *spec = codec->spec; | ||
454 | |||
455 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], | ||
456 | stream_tag, 0, format); | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
461 | struct hda_codec *codec, | ||
462 | struct snd_pcm_substream *substream) | ||
463 | { | ||
464 | struct cmi_spec *spec = codec->spec; | ||
465 | |||
466 | snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); | ||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | |||
471 | /* | ||
472 | */ | ||
473 | static const struct hda_pcm_stream cmi9880_pcm_analog_playback = { | ||
474 | .substreams = 1, | ||
475 | .channels_min = 2, | ||
476 | .channels_max = 8, | ||
477 | .nid = 0x03, /* NID to query formats and rates */ | ||
478 | .ops = { | ||
479 | .open = cmi9880_playback_pcm_open, | ||
480 | .prepare = cmi9880_playback_pcm_prepare, | ||
481 | .cleanup = cmi9880_playback_pcm_cleanup | ||
482 | }, | ||
483 | }; | ||
484 | |||
485 | static const struct hda_pcm_stream cmi9880_pcm_analog_capture = { | ||
486 | .substreams = 2, | ||
487 | .channels_min = 2, | ||
488 | .channels_max = 2, | ||
489 | .nid = 0x08, /* NID to query formats and rates */ | ||
490 | .ops = { | ||
491 | .prepare = cmi9880_capture_pcm_prepare, | ||
492 | .cleanup = cmi9880_capture_pcm_cleanup | ||
493 | }, | ||
494 | }; | ||
495 | |||
496 | static const struct hda_pcm_stream cmi9880_pcm_digital_playback = { | ||
497 | .substreams = 1, | ||
498 | .channels_min = 2, | ||
499 | .channels_max = 2, | ||
500 | /* NID is set in cmi9880_build_pcms */ | ||
501 | .ops = { | ||
502 | .open = cmi9880_dig_playback_pcm_open, | ||
503 | .close = cmi9880_dig_playback_pcm_close, | ||
504 | .prepare = cmi9880_dig_playback_pcm_prepare | ||
505 | }, | ||
506 | }; | ||
507 | |||
508 | static const struct hda_pcm_stream cmi9880_pcm_digital_capture = { | ||
509 | .substreams = 1, | ||
510 | .channels_min = 2, | ||
511 | .channels_max = 2, | ||
512 | /* NID is set in cmi9880_build_pcms */ | ||
513 | }; | ||
514 | |||
515 | static int cmi9880_build_pcms(struct hda_codec *codec) | ||
516 | { | ||
517 | struct cmi_spec *spec = codec->spec; | ||
518 | struct hda_pcm *info = spec->pcm_rec; | ||
519 | |||
520 | codec->num_pcms = 1; | ||
521 | codec->pcm_info = info; | ||
522 | |||
523 | info->name = "CMI9880"; | ||
524 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_analog_playback; | ||
525 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = cmi9880_pcm_analog_capture; | ||
526 | |||
527 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | ||
528 | codec->num_pcms++; | ||
529 | info++; | ||
530 | info->name = "CMI9880 Digital"; | ||
531 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
532 | if (spec->multiout.dig_out_nid) { | ||
533 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_digital_playback; | ||
534 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; | ||
535 | } | ||
536 | if (spec->dig_in_nid) { | ||
537 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = cmi9880_pcm_digital_capture; | ||
538 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; | ||
539 | } | ||
540 | } | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static void cmi9880_free(struct hda_codec *codec) | ||
546 | { | ||
547 | kfree(codec->spec); | ||
548 | } | ||
549 | |||
550 | /* | ||
551 | */ | ||
552 | |||
553 | static const char * const cmi9880_models[CMI_MODELS] = { | ||
554 | [CMI_MINIMAL] = "minimal", | ||
555 | [CMI_MIN_FP] = "min_fp", | ||
556 | [CMI_FULL] = "full", | ||
557 | [CMI_FULL_DIG] = "full_dig", | ||
558 | [CMI_ALLOUT] = "allout", | ||
559 | [CMI_AUTO] = "auto", | ||
560 | }; | ||
561 | |||
562 | static const struct snd_pci_quirk cmi9880_cfg_tbl[] = { | ||
563 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG), | ||
564 | SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL), | ||
565 | SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG), | ||
566 | {} /* terminator */ | ||
567 | }; | ||
568 | |||
569 | static const struct hda_codec_ops cmi9880_patch_ops = { | ||
570 | .build_controls = cmi9880_build_controls, | ||
571 | .build_pcms = cmi9880_build_pcms, | ||
572 | .init = cmi9880_init, | ||
573 | .free = cmi9880_free, | ||
574 | }; | ||
575 | #endif /* ENABLE_CMI_STATIC_QUIRKS */ | ||
576 | |||
577 | /* | ||
578 | * stuff for auto-parser | 39 | * stuff for auto-parser |
579 | */ | 40 | */ |
580 | static const struct hda_codec_ops cmi_auto_patch_ops = { | 41 | static const struct hda_codec_ops cmi_auto_patch_ops = { |
@@ -585,12 +46,18 @@ static const struct hda_codec_ops cmi_auto_patch_ops = { | |||
585 | .unsol_event = snd_hda_jack_unsol_event, | 46 | .unsol_event = snd_hda_jack_unsol_event, |
586 | }; | 47 | }; |
587 | 48 | ||
588 | static int cmi_parse_auto_config(struct hda_codec *codec) | 49 | static int patch_cmi9880(struct hda_codec *codec) |
589 | { | 50 | { |
590 | struct cmi_spec *spec = codec->spec; | 51 | struct cmi_spec *spec; |
591 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 52 | struct auto_pin_cfg *cfg; |
592 | int err; | 53 | int err; |
593 | 54 | ||
55 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
56 | if (spec == NULL) | ||
57 | return -ENOMEM; | ||
58 | |||
59 | codec->spec = spec; | ||
60 | cfg = &spec->gen.autocfg; | ||
594 | snd_hda_gen_spec_init(&spec->gen); | 61 | snd_hda_gen_spec_init(&spec->gen); |
595 | 62 | ||
596 | err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); | 63 | err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); |
@@ -608,79 +75,6 @@ static int cmi_parse_auto_config(struct hda_codec *codec) | |||
608 | return err; | 75 | return err; |
609 | } | 76 | } |
610 | 77 | ||
611 | |||
612 | static int patch_cmi9880(struct hda_codec *codec) | ||
613 | { | ||
614 | struct cmi_spec *spec; | ||
615 | |||
616 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
617 | if (spec == NULL) | ||
618 | return -ENOMEM; | ||
619 | |||
620 | codec->spec = spec; | ||
621 | #ifdef ENABLE_CMI_STATIC_QUIRKS | ||
622 | spec->board_config = snd_hda_check_board_config(codec, CMI_MODELS, | ||
623 | cmi9880_models, | ||
624 | cmi9880_cfg_tbl); | ||
625 | if (spec->board_config < 0) { | ||
626 | codec_dbg(codec, "%s: BIOS auto-probing.\n", | ||
627 | codec->chip_name); | ||
628 | spec->board_config = CMI_AUTO; /* try everything */ | ||
629 | } | ||
630 | |||
631 | if (spec->board_config == CMI_AUTO) | ||
632 | return cmi_parse_auto_config(codec); | ||
633 | |||
634 | /* copy default DAC NIDs */ | ||
635 | memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids)); | ||
636 | spec->num_dacs = 4; | ||
637 | |||
638 | switch (spec->board_config) { | ||
639 | case CMI_MINIMAL: | ||
640 | case CMI_MIN_FP: | ||
641 | spec->channel_modes = cmi9880_channel_modes; | ||
642 | if (spec->board_config == CMI_MINIMAL) | ||
643 | spec->num_channel_modes = 2; | ||
644 | else { | ||
645 | spec->front_panel = 1; | ||
646 | spec->num_channel_modes = 3; | ||
647 | } | ||
648 | spec->multiout.max_channels = cmi9880_channel_modes[0].channels; | ||
649 | spec->input_mux = &cmi9880_basic_mux; | ||
650 | break; | ||
651 | case CMI_FULL: | ||
652 | case CMI_FULL_DIG: | ||
653 | spec->front_panel = 1; | ||
654 | spec->multiout.max_channels = 8; | ||
655 | spec->input_mux = &cmi9880_basic_mux; | ||
656 | if (spec->board_config == CMI_FULL_DIG) { | ||
657 | spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; | ||
658 | spec->dig_in_nid = CMI_DIG_IN_NID; | ||
659 | } | ||
660 | break; | ||
661 | case CMI_ALLOUT: | ||
662 | default: | ||
663 | spec->front_panel = 1; | ||
664 | spec->multiout.max_channels = 8; | ||
665 | spec->no_line_in = 1; | ||
666 | spec->input_mux = &cmi9880_no_line_mux; | ||
667 | spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; | ||
668 | break; | ||
669 | } | ||
670 | |||
671 | spec->multiout.num_dacs = spec->num_dacs; | ||
672 | spec->multiout.dac_nids = spec->dac_nids; | ||
673 | |||
674 | spec->adc_nids = cmi9880_adc_nids; | ||
675 | |||
676 | codec->patch_ops = cmi9880_patch_ops; | ||
677 | |||
678 | return 0; | ||
679 | #else | ||
680 | return cmi_parse_auto_config(codec); | ||
681 | #endif | ||
682 | } | ||
683 | |||
684 | /* | 78 | /* |
685 | * patch entries | 79 | * patch entries |
686 | */ | 80 | */ |