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