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