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 <sound/driver.h> 25 #include <linux/init.h> 26 #include <linux/delay.h> 27 #include <linux/slab.h> 28 #include <linux/pci.h> 29 #include <sound/core.h> 30 #include "hda_codec.h" 31 #include "hda_local.h" 32 33 34 /* board config type */ 35 enum { 36 CMI_MINIMAL, /* back 3-jack */ 37 CMI_MIN_FP, /* back 3-jack + front-panel 2-jack */ 38 CMI_FULL, /* back 6-jack + front-panel 2-jack */ 39 CMI_FULL_DIG, /* back 6-jack + front-panel 2-jack + digital I/O */ 40 CMI_ALLOUT, /* back 5-jack + front-panel 2-jack + digital out */ 41 }; 42 43 struct cmi_spec { 44 int board_config; 45 unsigned int surr_switch: 1; /* switchable line,mic */ 46 unsigned int no_line_in: 1; /* no line-in (5-jack) */ 47 unsigned int front_panel: 1; /* has front-panel 2-jack */ 48 49 /* playback */ 50 struct hda_multi_out multiout; 51 52 /* capture */ 53 hda_nid_t *adc_nids; 54 hda_nid_t dig_in_nid; 55 56 /* capture source */ 57 const struct hda_input_mux *input_mux; 58 unsigned int cur_mux[2]; 59 60 /* channel mode */ 61 unsigned int num_ch_modes; 62 unsigned int cur_ch_mode; 63 const struct cmi_channel_mode *channel_modes; 64 65 struct hda_pcm pcm_rec[2]; /* PCM information */ 66 }; 67 68 /* 69 * input MUX 70 */ 71 static int cmi_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 72 { 73 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 74 struct cmi_spec *spec = codec->spec; 75 return snd_hda_input_mux_info(spec->input_mux, uinfo); 76 } 77 78 static int cmi_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 79 { 80 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 81 struct cmi_spec *spec = codec->spec; 82 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 83 84 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 85 return 0; 86 } 87 88 static int cmi_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 89 { 90 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 91 struct cmi_spec *spec = codec->spec; 92 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 93 94 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 95 spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); 96 } 97 98 /* 99 * shared line-in, mic for surrounds 100 */ 101 102 /* 3-stack / 2 channel */ 103 static struct hda_verb cmi9880_ch2_init[] = { 104 /* set line-in PIN for input */ 105 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 106 /* set mic PIN for input, also enable vref */ 107 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 108 /* route front PCM (DAC1) to HP */ 109 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 110 {} 111 }; 112 113 /* 3-stack / 6 channel */ 114 static struct hda_verb cmi9880_ch6_init[] = { 115 /* set line-in PIN for output */ 116 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 117 /* set mic PIN for output */ 118 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 119 /* route front PCM (DAC1) to HP */ 120 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 121 {} 122 }; 123 124 /* 3-stack+front / 8 channel */ 125 static struct hda_verb cmi9880_ch8_init[] = { 126 /* set line-in PIN for output */ 127 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 128 /* set mic PIN for output */ 129 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 130 /* route rear-surround PCM (DAC4) to HP */ 131 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x03 }, 132 {} 133 }; 134 135 struct cmi_channel_mode { 136 unsigned int channels; 137 const struct hda_verb *sequence; 138 }; 139 140 static struct cmi_channel_mode cmi9880_channel_modes[3] = { 141 { 2, cmi9880_ch2_init }, 142 { 6, cmi9880_ch6_init }, 143 { 8, cmi9880_ch8_init }, 144 }; 145 146 static int cmi_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 147 { 148 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 149 struct cmi_spec *spec = codec->spec; 150 151 snd_assert(spec->channel_modes, return -EINVAL); 152 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 153 uinfo->count = 1; 154 uinfo->value.enumerated.items = spec->num_ch_modes; 155 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 156 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 157 sprintf(uinfo->value.enumerated.name, "%dch", 158 spec->channel_modes[uinfo->value.enumerated.item].channels); 159 return 0; 160 } 161 162 static int cmi_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 163 { 164 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 165 struct cmi_spec *spec = codec->spec; 166 167 ucontrol->value.enumerated.item[0] = spec->cur_ch_mode; 168 return 0; 169 } 170 171 static int cmi_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 172 { 173 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 174 struct cmi_spec *spec = codec->spec; 175 176 snd_assert(spec->channel_modes, return -EINVAL); 177 if (ucontrol->value.enumerated.item[0] >= spec->num_ch_modes) 178 ucontrol->value.enumerated.item[0] = spec->num_ch_modes; 179 if (ucontrol->value.enumerated.item[0] == spec->cur_ch_mode && 180 ! codec->in_resume) 181 return 0; 182 183 spec->cur_ch_mode = ucontrol->value.enumerated.item[0]; 184 snd_hda_sequence_write(codec, spec->channel_modes[spec->cur_ch_mode].sequence); 185 spec->multiout.max_channels = spec->channel_modes[spec->cur_ch_mode].channels; 186 return 1; 187 } 188 189 /* 190 */ 191 static snd_kcontrol_new_t 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 * FIXME: the controls appear in the "playback" view! 203 */ 204 /* .name = "Capture Source", */ 205 .name = "Input Source", 206 .count = 2, 207 .info = cmi_mux_enum_info, 208 .get = cmi_mux_enum_get, 209 .put = cmi_mux_enum_put, 210 }, 211 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0, HDA_INPUT), 212 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0, HDA_INPUT), 213 HDA_CODEC_MUTE("Capture Switch", 0x08, 0, HDA_INPUT), 214 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0, HDA_INPUT), 215 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x23, 0, HDA_OUTPUT), 216 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x23, 0, HDA_OUTPUT), 217 { } /* end */ 218 }; 219 220 /* 221 * shared I/O pins 222 */ 223 static snd_kcontrol_new_t cmi9880_ch_mode_mixer[] = { 224 { 225 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 226 .name = "Channel Mode", 227 .info = cmi_ch_mode_info, 228 .get = cmi_ch_mode_get, 229 .put = cmi_ch_mode_put, 230 }, 231 { } /* end */ 232 }; 233 234 /* AUD-in selections: 235 * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20 236 */ 237 static struct hda_input_mux cmi9880_basic_mux = { 238 .num_items = 4, 239 .items = { 240 { "Front Mic", 0x5 }, 241 { "Rear Mic", 0x2 }, 242 { "Line", 0x1 }, 243 { "CD", 0x7 }, 244 } 245 }; 246 247 static struct hda_input_mux cmi9880_no_line_mux = { 248 .num_items = 3, 249 .items = { 250 { "Front Mic", 0x5 }, 251 { "Rear Mic", 0x2 }, 252 { "CD", 0x7 }, 253 } 254 }; 255 256 /* front, rear, clfe, rear_surr */ 257 static hda_nid_t cmi9880_dac_nids[4] = { 258 0x03, 0x04, 0x05, 0x06 259 }; 260 /* ADC0, ADC1 */ 261 static hda_nid_t cmi9880_adc_nids[2] = { 262 0x08, 0x09 263 }; 264 265 #define CMI_DIG_OUT_NID 0x07 266 #define CMI_DIG_IN_NID 0x0a 267 268 /* 269 */ 270 static struct hda_verb cmi9880_basic_init[] = { 271 /* port-D for line out (rear panel) */ 272 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 273 /* port-E for HP out (front panel) */ 274 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 275 /* route front PCM to HP */ 276 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 277 /* port-A for surround (rear panel) */ 278 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 279 /* port-G for CLFE (rear panel) */ 280 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 281 /* port-H for side (rear panel) */ 282 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 283 /* port-C for line-in (rear panel) */ 284 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 285 /* port-B for mic-in (rear panel) with vref */ 286 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 287 /* port-F for mic-in (front panel) with vref */ 288 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 289 /* CD-in */ 290 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 291 /* route front mic to ADC1/2 */ 292 { 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 }, 293 { 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 }, 294 {} /* terminator */ 295 }; 296 297 static struct hda_verb cmi9880_allout_init[] = { 298 /* port-D for line out (rear panel) */ 299 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 300 /* port-E for HP out (front panel) */ 301 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 302 /* route front PCM to HP */ 303 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 304 /* port-A for side (rear panel) */ 305 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 306 /* port-G for CLFE (rear panel) */ 307 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 308 /* port-C for surround (rear panel) */ 309 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 310 /* port-B for mic-in (rear panel) with vref */ 311 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 312 /* port-F for mic-in (front panel) with vref */ 313 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 314 /* CD-in */ 315 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 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 int err; 328 329 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer); 330 if (err < 0) 331 return err; 332 if (spec->surr_switch) { 333 err = snd_hda_add_new_ctls(codec, cmi9880_ch_mode_mixer); 334 if (err < 0) 335 return err; 336 } 337 if (spec->multiout.dig_out_nid) { 338 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 339 if (err < 0) 340 return err; 341 } 342 if (spec->dig_in_nid) { 343 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 344 if (err < 0) 345 return err; 346 } 347 return 0; 348 } 349 350 static int cmi9880_init(struct hda_codec *codec) 351 { 352 struct cmi_spec *spec = codec->spec; 353 if (spec->board_config == CMI_ALLOUT) 354 snd_hda_sequence_write(codec, cmi9880_allout_init); 355 else 356 snd_hda_sequence_write(codec, cmi9880_basic_init); 357 return 0; 358 } 359 360 #ifdef CONFIG_PM 361 /* 362 * resume 363 */ 364 static int cmi9880_resume(struct hda_codec *codec) 365 { 366 struct cmi_spec *spec = codec->spec; 367 368 cmi9880_init(codec); 369 snd_hda_resume_ctls(codec, cmi9880_basic_mixer); 370 if (spec->surr_switch) 371 snd_hda_resume_ctls(codec, cmi9880_ch_mode_mixer); 372 if (spec->multiout.dig_out_nid) 373 snd_hda_resume_spdif_out(codec); 374 if (spec->dig_in_nid) 375 snd_hda_resume_spdif_in(codec); 376 377 return 0; 378 } 379 #endif 380 381 /* 382 * Analog playback callbacks 383 */ 384 static int cmi9880_playback_pcm_open(struct hda_pcm_stream *hinfo, 385 struct hda_codec *codec, 386 snd_pcm_substream_t *substream) 387 { 388 struct cmi_spec *spec = codec->spec; 389 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); 390 } 391 392 static int cmi9880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 393 struct hda_codec *codec, 394 unsigned int stream_tag, 395 unsigned int format, 396 snd_pcm_substream_t *substream) 397 { 398 struct cmi_spec *spec = codec->spec; 399 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, 400 format, substream); 401 } 402 403 static int cmi9880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 404 struct hda_codec *codec, 405 snd_pcm_substream_t *substream) 406 { 407 struct cmi_spec *spec = codec->spec; 408 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 409 } 410 411 /* 412 * Digital out 413 */ 414 static int cmi9880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 415 struct hda_codec *codec, 416 snd_pcm_substream_t *substream) 417 { 418 struct cmi_spec *spec = codec->spec; 419 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 420 } 421 422 static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 423 struct hda_codec *codec, 424 snd_pcm_substream_t *substream) 425 { 426 struct cmi_spec *spec = codec->spec; 427 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 428 } 429 430 /* 431 * Analog capture 432 */ 433 static int cmi9880_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 434 struct hda_codec *codec, 435 unsigned int stream_tag, 436 unsigned int format, 437 snd_pcm_substream_t *substream) 438 { 439 struct cmi_spec *spec = codec->spec; 440 441 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 442 stream_tag, 0, format); 443 return 0; 444 } 445 446 static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 447 struct hda_codec *codec, 448 snd_pcm_substream_t *substream) 449 { 450 struct cmi_spec *spec = codec->spec; 451 452 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0); 453 return 0; 454 } 455 456 457 /* 458 */ 459 static struct hda_pcm_stream cmi9880_pcm_analog_playback = { 460 .substreams = 1, 461 .channels_min = 2, 462 .channels_max = 8, 463 .nid = 0x03, /* NID to query formats and rates */ 464 .ops = { 465 .open = cmi9880_playback_pcm_open, 466 .prepare = cmi9880_playback_pcm_prepare, 467 .cleanup = cmi9880_playback_pcm_cleanup 468 }, 469 }; 470 471 static struct hda_pcm_stream cmi9880_pcm_analog_capture = { 472 .substreams = 2, 473 .channels_min = 2, 474 .channels_max = 2, 475 .nid = 0x08, /* NID to query formats and rates */ 476 .ops = { 477 .prepare = cmi9880_capture_pcm_prepare, 478 .cleanup = cmi9880_capture_pcm_cleanup 479 }, 480 }; 481 482 static struct hda_pcm_stream cmi9880_pcm_digital_playback = { 483 .substreams = 1, 484 .channels_min = 2, 485 .channels_max = 2, 486 /* NID is set in cmi9880_build_pcms */ 487 .ops = { 488 .open = cmi9880_dig_playback_pcm_open, 489 .close = cmi9880_dig_playback_pcm_close 490 }, 491 }; 492 493 static struct hda_pcm_stream cmi9880_pcm_digital_capture = { 494 .substreams = 1, 495 .channels_min = 2, 496 .channels_max = 2, 497 /* NID is set in cmi9880_build_pcms */ 498 }; 499 500 static int cmi9880_build_pcms(struct hda_codec *codec) 501 { 502 struct cmi_spec *spec = codec->spec; 503 struct hda_pcm *info = spec->pcm_rec; 504 505 codec->num_pcms = 1; 506 codec->pcm_info = info; 507 508 info->name = "CMI9880"; 509 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_analog_playback; 510 info->stream[SNDRV_PCM_STREAM_CAPTURE] = cmi9880_pcm_analog_capture; 511 512 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 513 codec->num_pcms++; 514 info++; 515 info->name = "CMI9880 Digital"; 516 if (spec->multiout.dig_out_nid) { 517 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_digital_playback; 518 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 519 } 520 if (spec->dig_in_nid) { 521 info->stream[SNDRV_PCM_STREAM_CAPTURE] = cmi9880_pcm_digital_capture; 522 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 523 } 524 } 525 526 return 0; 527 } 528 529 static void cmi9880_free(struct hda_codec *codec) 530 { 531 kfree(codec->spec); 532 } 533 534 /* 535 */ 536 537 static struct hda_board_config cmi9880_cfg_tbl[] = { 538 { .modelname = "minimal", .config = CMI_MINIMAL }, 539 { .modelname = "min_fp", .config = CMI_MIN_FP }, 540 { .modelname = "full", .config = CMI_FULL }, 541 { .modelname = "full_dig", .config = CMI_FULL_DIG }, 542 { .modelname = "allout", .config = CMI_ALLOUT }, 543 {} /* terminator */ 544 }; 545 546 static struct hda_codec_ops cmi9880_patch_ops = { 547 .build_controls = cmi9880_build_controls, 548 .build_pcms = cmi9880_build_pcms, 549 .init = cmi9880_init, 550 .free = cmi9880_free, 551 #ifdef CONFIG_PM 552 .resume = cmi9880_resume, 553 #endif 554 }; 555 556 static int patch_cmi9880(struct hda_codec *codec) 557 { 558 struct cmi_spec *spec; 559 560 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 561 if (spec == NULL) 562 return -ENOMEM; 563 564 codec->spec = spec; 565 spec->board_config = snd_hda_check_board_config(codec, cmi9880_cfg_tbl); 566 if (spec->board_config < 0) { 567 snd_printd(KERN_INFO "hda_codec: Unknown model for CMI9880\n"); 568 spec->board_config = CMI_FULL_DIG; /* try everything */ 569 } 570 571 switch (spec->board_config) { 572 case CMI_MINIMAL: 573 case CMI_MIN_FP: 574 spec->surr_switch = 1; 575 if (spec->board_config == CMI_MINIMAL) 576 spec->num_ch_modes = 2; 577 else { 578 spec->front_panel = 1; 579 spec->num_ch_modes = 3; 580 } 581 spec->channel_modes = cmi9880_channel_modes; 582 spec->multiout.max_channels = cmi9880_channel_modes[0].channels; 583 spec->input_mux = &cmi9880_basic_mux; 584 break; 585 case CMI_FULL: 586 case CMI_FULL_DIG: 587 spec->front_panel = 1; 588 spec->multiout.max_channels = 8; 589 spec->input_mux = &cmi9880_basic_mux; 590 if (spec->board_config == CMI_FULL_DIG) { 591 spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; 592 spec->dig_in_nid = CMI_DIG_IN_NID; 593 } 594 break; 595 case CMI_ALLOUT: 596 spec->front_panel = 1; 597 spec->multiout.max_channels = 8; 598 spec->no_line_in = 1; 599 spec->input_mux = &cmi9880_no_line_mux; 600 spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; 601 break; 602 } 603 604 spec->multiout.num_dacs = 4; 605 spec->multiout.dac_nids = cmi9880_dac_nids; 606 607 spec->adc_nids = cmi9880_adc_nids; 608 609 codec->patch_ops = cmi9880_patch_ops; 610 611 return 0; 612 } 613 614 /* 615 * patch entries 616 */ 617 struct hda_codec_preset snd_hda_preset_cmedia[] = { 618 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, 619 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, 620 {} /* terminator */ 621 }; 622