1 /* 2 * Universal Interface for Intel High Definition Audio Codec 3 * 4 * HD audio interface patch for VIA VT1708 codec 5 * 6 * Copyright (c) 2006 Lydia Wang <lydiawang@viatech.com> 7 * Takashi Iwai <tiwai@suse.de> 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 /* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */ 25 /* */ 26 /* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */ 27 /* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */ 28 /* 2006-08-02 Lydia Wang Add support to VT1709 codec */ 29 /* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */ 30 /* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */ 31 /* 2007-09-17 Lydia Wang Add VT1708B codec support */ 32 /* */ 33 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 34 35 36 #include <linux/init.h> 37 #include <linux/delay.h> 38 #include <linux/slab.h> 39 #include <sound/core.h> 40 #include "hda_codec.h" 41 #include "hda_local.h" 42 #include "hda_patch.h" 43 44 /* amp values */ 45 #define AMP_VAL_IDX_SHIFT 19 46 #define AMP_VAL_IDX_MASK (0x0f<<19) 47 48 #define NUM_CONTROL_ALLOC 32 49 #define NUM_VERB_ALLOC 32 50 51 /* Pin Widget NID */ 52 #define VT1708_HP_NID 0x13 53 #define VT1708_DIGOUT_NID 0x14 54 #define VT1708_DIGIN_NID 0x16 55 #define VT1708_DIGIN_PIN 0x26 56 57 #define VT1709_HP_DAC_NID 0x28 58 #define VT1709_DIGOUT_NID 0x13 59 #define VT1709_DIGIN_NID 0x17 60 #define VT1709_DIGIN_PIN 0x25 61 62 #define VT1708B_HP_NID 0x25 63 #define VT1708B_DIGOUT_NID 0x12 64 #define VT1708B_DIGIN_NID 0x15 65 #define VT1708B_DIGIN_PIN 0x21 66 67 #define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b) 68 #define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713) 69 #define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717) 70 #define IS_VT1708B_8CH_VENDORID(x) ((x) >= 0x1106e720 && (x) <= 0x1106e723) 71 #define IS_VT1708B_4CH_VENDORID(x) ((x) >= 0x1106e724 && (x) <= 0x1106e727) 72 73 74 enum { 75 VIA_CTL_WIDGET_VOL, 76 VIA_CTL_WIDGET_MUTE, 77 }; 78 79 enum { 80 AUTO_SEQ_FRONT, 81 AUTO_SEQ_SURROUND, 82 AUTO_SEQ_CENLFE, 83 AUTO_SEQ_SIDE 84 }; 85 86 static struct snd_kcontrol_new vt1708_control_templates[] = { 87 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 88 HDA_CODEC_MUTE(NULL, 0, 0, 0), 89 }; 90 91 92 struct via_spec { 93 /* codec parameterization */ 94 struct snd_kcontrol_new *mixers[3]; 95 unsigned int num_mixers; 96 97 struct hda_verb *init_verbs; 98 99 char *stream_name_analog; 100 struct hda_pcm_stream *stream_analog_playback; 101 struct hda_pcm_stream *stream_analog_capture; 102 103 char *stream_name_digital; 104 struct hda_pcm_stream *stream_digital_playback; 105 struct hda_pcm_stream *stream_digital_capture; 106 107 /* playback */ 108 struct hda_multi_out multiout; 109 110 /* capture */ 111 unsigned int num_adc_nids; 112 hda_nid_t *adc_nids; 113 hda_nid_t dig_in_nid; 114 115 /* capture source */ 116 const struct hda_input_mux *input_mux; 117 unsigned int cur_mux[3]; 118 119 /* PCM information */ 120 struct hda_pcm pcm_rec[2]; 121 122 /* dynamic controls, init_verbs and input_mux */ 123 struct auto_pin_cfg autocfg; 124 unsigned int num_kctl_alloc, num_kctl_used; 125 struct snd_kcontrol_new *kctl_alloc; 126 struct hda_input_mux private_imux; 127 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 128 129 #ifdef CONFIG_SND_HDA_POWER_SAVE 130 struct hda_loopback_check loopback; 131 #endif 132 }; 133 134 static hda_nid_t vt1708_adc_nids[2] = { 135 /* ADC1-2 */ 136 0x15, 0x27 137 }; 138 139 static hda_nid_t vt1709_adc_nids[3] = { 140 /* ADC1-2 */ 141 0x14, 0x15, 0x16 142 }; 143 144 static hda_nid_t vt1708B_adc_nids[2] = { 145 /* ADC1-2 */ 146 0x13, 0x14 147 }; 148 149 /* add dynamic controls */ 150 static int via_add_control(struct via_spec *spec, int type, const char *name, 151 unsigned long val) 152 { 153 struct snd_kcontrol_new *knew; 154 155 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 156 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 157 158 /* array + terminator */ 159 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); 160 if (!knew) 161 return -ENOMEM; 162 if (spec->kctl_alloc) { 163 memcpy(knew, spec->kctl_alloc, 164 sizeof(*knew) * spec->num_kctl_alloc); 165 kfree(spec->kctl_alloc); 166 } 167 spec->kctl_alloc = knew; 168 spec->num_kctl_alloc = num; 169 } 170 171 knew = &spec->kctl_alloc[spec->num_kctl_used]; 172 *knew = vt1708_control_templates[type]; 173 knew->name = kstrdup(name, GFP_KERNEL); 174 175 if (!knew->name) 176 return -ENOMEM; 177 knew->private_value = val; 178 spec->num_kctl_used++; 179 return 0; 180 } 181 182 /* create input playback/capture controls for the given pin */ 183 static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin, 184 const char *ctlname, int idx, int mix_nid) 185 { 186 char name[32]; 187 int err; 188 189 sprintf(name, "%s Playback Volume", ctlname); 190 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 191 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 192 if (err < 0) 193 return err; 194 sprintf(name, "%s Playback Switch", ctlname); 195 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 196 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 197 if (err < 0) 198 return err; 199 return 0; 200 } 201 202 static void via_auto_set_output_and_unmute(struct hda_codec *codec, 203 hda_nid_t nid, int pin_type, 204 int dac_idx) 205 { 206 /* set as output */ 207 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 208 pin_type); 209 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 210 AMP_OUT_UNMUTE); 211 } 212 213 214 static void via_auto_init_multi_out(struct hda_codec *codec) 215 { 216 struct via_spec *spec = codec->spec; 217 int i; 218 219 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 220 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 221 if (nid) 222 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 223 } 224 } 225 226 static void via_auto_init_hp_out(struct hda_codec *codec) 227 { 228 struct via_spec *spec = codec->spec; 229 hda_nid_t pin; 230 231 pin = spec->autocfg.hp_pins[0]; 232 if (pin) /* connect to front */ 233 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 234 } 235 236 static void via_auto_init_analog_input(struct hda_codec *codec) 237 { 238 struct via_spec *spec = codec->spec; 239 int i; 240 241 for (i = 0; i < AUTO_PIN_LAST; i++) { 242 hda_nid_t nid = spec->autocfg.input_pins[i]; 243 244 snd_hda_codec_write(codec, nid, 0, 245 AC_VERB_SET_PIN_WIDGET_CONTROL, 246 (i <= AUTO_PIN_FRONT_MIC ? 247 PIN_VREF50 : PIN_IN)); 248 249 } 250 } 251 /* 252 * input MUX handling 253 */ 254 static int via_mux_enum_info(struct snd_kcontrol *kcontrol, 255 struct snd_ctl_elem_info *uinfo) 256 { 257 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 258 struct via_spec *spec = codec->spec; 259 return snd_hda_input_mux_info(spec->input_mux, uinfo); 260 } 261 262 static int via_mux_enum_get(struct snd_kcontrol *kcontrol, 263 struct snd_ctl_elem_value *ucontrol) 264 { 265 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 266 struct via_spec *spec = codec->spec; 267 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 268 269 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 270 return 0; 271 } 272 273 static int via_mux_enum_put(struct snd_kcontrol *kcontrol, 274 struct snd_ctl_elem_value *ucontrol) 275 { 276 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 277 struct via_spec *spec = codec->spec; 278 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 279 unsigned int vendor_id = codec->vendor_id; 280 281 /* AIW0 lydia 060801 add for correct sw0 input select */ 282 if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0)) 283 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 284 0x18, &spec->cur_mux[adc_idx]); 285 else if ((IS_VT1709_10CH_VENDORID(vendor_id) || 286 IS_VT1709_6CH_VENDORID(vendor_id)) && adc_idx == 0) 287 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 288 0x19, &spec->cur_mux[adc_idx]); 289 else if ((IS_VT1708B_8CH_VENDORID(vendor_id) || 290 IS_VT1708B_4CH_VENDORID(vendor_id)) && adc_idx == 0) 291 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 292 0x17, &spec->cur_mux[adc_idx]); 293 else 294 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 295 spec->adc_nids[adc_idx], 296 &spec->cur_mux[adc_idx]); 297 } 298 299 /* capture mixer elements */ 300 static struct snd_kcontrol_new vt1708_capture_mixer[] = { 301 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 302 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT), 303 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT), 304 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT), 305 { 306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 307 /* The multiple "Capture Source" controls confuse alsamixer 308 * So call somewhat different.. 309 */ 310 /* .name = "Capture Source", */ 311 .name = "Input Source", 312 .count = 1, 313 .info = via_mux_enum_info, 314 .get = via_mux_enum_get, 315 .put = via_mux_enum_put, 316 }, 317 { } /* end */ 318 }; 319 /* 320 * generic initialization of ADC, input mixers and output mixers 321 */ 322 static struct hda_verb vt1708_volume_init_verbs[] = { 323 /* 324 * Unmute ADC0-1 and set the default input to mic-in 325 */ 326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 327 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 328 329 330 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 331 * mixer widget 332 */ 333 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 334 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 335 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 337 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 338 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 339 340 /* 341 * Set up output mixers (0x19 - 0x1b) 342 */ 343 /* set vol=0 to output mixers */ 344 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 345 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 346 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 347 348 /* Setup default input to PW4 */ 349 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1}, 350 /* PW9 Output enable */ 351 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 352 { } 353 }; 354 355 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo, 356 struct hda_codec *codec, 357 struct snd_pcm_substream *substream) 358 { 359 struct via_spec *spec = codec->spec; 360 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 361 hinfo); 362 } 363 364 static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 365 struct hda_codec *codec, 366 unsigned int stream_tag, 367 unsigned int format, 368 struct snd_pcm_substream *substream) 369 { 370 struct via_spec *spec = codec->spec; 371 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 372 stream_tag, format, substream); 373 } 374 375 static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 376 struct hda_codec *codec, 377 struct snd_pcm_substream *substream) 378 { 379 struct via_spec *spec = codec->spec; 380 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 381 } 382 383 /* 384 * Digital out 385 */ 386 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 387 struct hda_codec *codec, 388 struct snd_pcm_substream *substream) 389 { 390 struct via_spec *spec = codec->spec; 391 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 392 } 393 394 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 395 struct hda_codec *codec, 396 struct snd_pcm_substream *substream) 397 { 398 struct via_spec *spec = codec->spec; 399 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 400 } 401 402 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 403 struct hda_codec *codec, 404 unsigned int stream_tag, 405 unsigned int format, 406 struct snd_pcm_substream *substream) 407 { 408 struct via_spec *spec = codec->spec; 409 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 410 stream_tag, format, substream); 411 } 412 413 /* 414 * Analog capture 415 */ 416 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 417 struct hda_codec *codec, 418 unsigned int stream_tag, 419 unsigned int format, 420 struct snd_pcm_substream *substream) 421 { 422 struct via_spec *spec = codec->spec; 423 424 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 425 stream_tag, 0, format); 426 return 0; 427 } 428 429 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 430 struct hda_codec *codec, 431 struct snd_pcm_substream *substream) 432 { 433 struct via_spec *spec = codec->spec; 434 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); 435 return 0; 436 } 437 438 static struct hda_pcm_stream vt1708_pcm_analog_playback = { 439 .substreams = 1, 440 .channels_min = 2, 441 .channels_max = 8, 442 .nid = 0x10, /* NID to query formats and rates */ 443 .ops = { 444 .open = via_playback_pcm_open, 445 .prepare = via_playback_pcm_prepare, 446 .cleanup = via_playback_pcm_cleanup 447 }, 448 }; 449 450 static struct hda_pcm_stream vt1708_pcm_analog_capture = { 451 .substreams = 2, 452 .channels_min = 2, 453 .channels_max = 2, 454 .nid = 0x15, /* NID to query formats and rates */ 455 .ops = { 456 .prepare = via_capture_pcm_prepare, 457 .cleanup = via_capture_pcm_cleanup 458 }, 459 }; 460 461 static struct hda_pcm_stream vt1708_pcm_digital_playback = { 462 .substreams = 1, 463 .channels_min = 2, 464 .channels_max = 2, 465 /* NID is set in via_build_pcms */ 466 .ops = { 467 .open = via_dig_playback_pcm_open, 468 .close = via_dig_playback_pcm_close, 469 .prepare = via_dig_playback_pcm_prepare 470 }, 471 }; 472 473 static struct hda_pcm_stream vt1708_pcm_digital_capture = { 474 .substreams = 1, 475 .channels_min = 2, 476 .channels_max = 2, 477 }; 478 479 static int via_build_controls(struct hda_codec *codec) 480 { 481 struct via_spec *spec = codec->spec; 482 int err; 483 int i; 484 485 for (i = 0; i < spec->num_mixers; i++) { 486 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 487 if (err < 0) 488 return err; 489 } 490 491 if (spec->multiout.dig_out_nid) { 492 err = snd_hda_create_spdif_out_ctls(codec, 493 spec->multiout.dig_out_nid); 494 if (err < 0) 495 return err; 496 err = snd_hda_create_spdif_share_sw(codec, 497 &spec->multiout); 498 if (err < 0) 499 return err; 500 spec->multiout.share_spdif = 1; 501 } 502 if (spec->dig_in_nid) { 503 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 504 if (err < 0) 505 return err; 506 } 507 return 0; 508 } 509 510 static int via_build_pcms(struct hda_codec *codec) 511 { 512 struct via_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 = spec->stream_name_analog; 519 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 520 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 521 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 522 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 523 524 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 525 spec->multiout.max_channels; 526 527 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 528 codec->num_pcms++; 529 info++; 530 info->name = spec->stream_name_digital; 531 info->pcm_type = HDA_PCM_TYPE_SPDIF; 532 if (spec->multiout.dig_out_nid) { 533 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 534 *(spec->stream_digital_playback); 535 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 536 spec->multiout.dig_out_nid; 537 } 538 if (spec->dig_in_nid) { 539 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 540 *(spec->stream_digital_capture); 541 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 542 spec->dig_in_nid; 543 } 544 } 545 546 return 0; 547 } 548 549 static void via_free(struct hda_codec *codec) 550 { 551 struct via_spec *spec = codec->spec; 552 unsigned int i; 553 554 if (!spec) 555 return; 556 557 if (spec->kctl_alloc) { 558 for (i = 0; i < spec->num_kctl_used; i++) 559 kfree(spec->kctl_alloc[i].name); 560 kfree(spec->kctl_alloc); 561 } 562 563 kfree(codec->spec); 564 } 565 566 static int via_init(struct hda_codec *codec) 567 { 568 struct via_spec *spec = codec->spec; 569 snd_hda_sequence_write(codec, spec->init_verbs); 570 /* Lydia Add for EAPD enable */ 571 if (!spec->dig_in_nid) { /* No Digital In connection */ 572 if (IS_VT1708_VENDORID(codec->vendor_id)) { 573 snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0, 574 AC_VERB_SET_PIN_WIDGET_CONTROL, 575 PIN_OUT); 576 snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0, 577 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 578 } else if (IS_VT1709_10CH_VENDORID(codec->vendor_id) || 579 IS_VT1709_6CH_VENDORID(codec->vendor_id)) { 580 snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0, 581 AC_VERB_SET_PIN_WIDGET_CONTROL, 582 PIN_OUT); 583 snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0, 584 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 585 } else if (IS_VT1708B_8CH_VENDORID(codec->vendor_id) || 586 IS_VT1708B_4CH_VENDORID(codec->vendor_id)) { 587 snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0, 588 AC_VERB_SET_PIN_WIDGET_CONTROL, 589 PIN_OUT); 590 snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0, 591 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 592 } 593 } else /* enable SPDIF-input pin */ 594 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0, 595 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); 596 597 return 0; 598 } 599 600 #ifdef CONFIG_SND_HDA_POWER_SAVE 601 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) 602 { 603 struct via_spec *spec = codec->spec; 604 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 605 } 606 #endif 607 608 /* 609 */ 610 static struct hda_codec_ops via_patch_ops = { 611 .build_controls = via_build_controls, 612 .build_pcms = via_build_pcms, 613 .init = via_init, 614 .free = via_free, 615 #ifdef CONFIG_SND_HDA_POWER_SAVE 616 .check_power_status = via_check_power_status, 617 #endif 618 }; 619 620 /* fill in the dac_nids table from the parsed pin configuration */ 621 static int vt1708_auto_fill_dac_nids(struct via_spec *spec, 622 const struct auto_pin_cfg *cfg) 623 { 624 int i; 625 hda_nid_t nid; 626 627 spec->multiout.num_dacs = cfg->line_outs; 628 629 spec->multiout.dac_nids = spec->private_dac_nids; 630 631 for(i = 0; i < 4; i++) { 632 nid = cfg->line_out_pins[i]; 633 if (nid) { 634 /* config dac list */ 635 switch (i) { 636 case AUTO_SEQ_FRONT: 637 spec->multiout.dac_nids[i] = 0x10; 638 break; 639 case AUTO_SEQ_CENLFE: 640 spec->multiout.dac_nids[i] = 0x12; 641 break; 642 case AUTO_SEQ_SURROUND: 643 spec->multiout.dac_nids[i] = 0x13; 644 break; 645 case AUTO_SEQ_SIDE: 646 spec->multiout.dac_nids[i] = 0x11; 647 break; 648 } 649 } 650 } 651 652 return 0; 653 } 654 655 /* add playback controls from the parsed DAC table */ 656 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, 657 const struct auto_pin_cfg *cfg) 658 { 659 char name[32]; 660 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 661 hda_nid_t nid, nid_vol = 0; 662 int i, err; 663 664 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 665 nid = cfg->line_out_pins[i]; 666 667 if (!nid) 668 continue; 669 670 if (i != AUTO_SEQ_FRONT) 671 nid_vol = 0x1b - i + 1; 672 673 if (i == AUTO_SEQ_CENLFE) { 674 /* Center/LFE */ 675 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 676 "Center Playback Volume", 677 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 678 HDA_OUTPUT)); 679 if (err < 0) 680 return err; 681 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 682 "LFE Playback Volume", 683 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 684 HDA_OUTPUT)); 685 if (err < 0) 686 return err; 687 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 688 "Center Playback Switch", 689 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 690 HDA_OUTPUT)); 691 if (err < 0) 692 return err; 693 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 694 "LFE Playback Switch", 695 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 696 HDA_OUTPUT)); 697 if (err < 0) 698 return err; 699 } else if (i == AUTO_SEQ_FRONT){ 700 /* add control to mixer index 0 */ 701 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 702 "Master Front Playback Volume", 703 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, 704 HDA_INPUT)); 705 if (err < 0) 706 return err; 707 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 708 "Master Front Playback Switch", 709 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, 710 HDA_INPUT)); 711 if (err < 0) 712 return err; 713 714 /* add control to PW3 */ 715 sprintf(name, "%s Playback Volume", chname[i]); 716 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 717 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 718 HDA_OUTPUT)); 719 if (err < 0) 720 return err; 721 sprintf(name, "%s Playback Switch", chname[i]); 722 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 723 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 724 HDA_OUTPUT)); 725 if (err < 0) 726 return err; 727 } else { 728 sprintf(name, "%s Playback Volume", chname[i]); 729 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 730 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 731 HDA_OUTPUT)); 732 if (err < 0) 733 return err; 734 sprintf(name, "%s Playback Switch", chname[i]); 735 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 736 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 737 HDA_OUTPUT)); 738 if (err < 0) 739 return err; 740 } 741 } 742 743 return 0; 744 } 745 746 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 747 { 748 int err; 749 750 if (!pin) 751 return 0; 752 753 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */ 754 755 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 756 "Headphone Playback Volume", 757 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 758 if (err < 0) 759 return err; 760 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 761 "Headphone Playback Switch", 762 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 763 if (err < 0) 764 return err; 765 766 return 0; 767 } 768 769 /* create playback/capture controls for input pins */ 770 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec, 771 const struct auto_pin_cfg *cfg) 772 { 773 static char *labels[] = { 774 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 775 }; 776 struct hda_input_mux *imux = &spec->private_imux; 777 int i, err, idx = 0; 778 779 /* for internal loopback recording select */ 780 imux->items[imux->num_items].label = "Stereo Mixer"; 781 imux->items[imux->num_items].index = idx; 782 imux->num_items++; 783 784 for (i = 0; i < AUTO_PIN_LAST; i++) { 785 if (!cfg->input_pins[i]) 786 continue; 787 788 switch (cfg->input_pins[i]) { 789 case 0x1d: /* Mic */ 790 idx = 2; 791 break; 792 793 case 0x1e: /* Line In */ 794 idx = 3; 795 break; 796 797 case 0x21: /* Front Mic */ 798 idx = 4; 799 break; 800 801 case 0x24: /* CD */ 802 idx = 1; 803 break; 804 } 805 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 806 idx, 0x17); 807 if (err < 0) 808 return err; 809 imux->items[imux->num_items].label = labels[i]; 810 imux->items[imux->num_items].index = idx; 811 imux->num_items++; 812 } 813 return 0; 814 } 815 816 #ifdef CONFIG_SND_HDA_POWER_SAVE 817 static struct hda_amp_list vt1708_loopbacks[] = { 818 { 0x17, HDA_INPUT, 1 }, 819 { 0x17, HDA_INPUT, 2 }, 820 { 0x17, HDA_INPUT, 3 }, 821 { 0x17, HDA_INPUT, 4 }, 822 { } /* end */ 823 }; 824 #endif 825 826 static int vt1708_parse_auto_config(struct hda_codec *codec) 827 { 828 struct via_spec *spec = codec->spec; 829 int err; 830 831 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 832 if (err < 0) 833 return err; 834 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg); 835 if (err < 0) 836 return err; 837 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 838 return 0; /* can't find valid BIOS pin config */ 839 840 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg); 841 if (err < 0) 842 return err; 843 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 844 if (err < 0) 845 return err; 846 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg); 847 if (err < 0) 848 return err; 849 850 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 851 852 if (spec->autocfg.dig_out_pin) 853 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; 854 if (spec->autocfg.dig_in_pin) 855 spec->dig_in_nid = VT1708_DIGIN_NID; 856 857 if (spec->kctl_alloc) 858 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 859 860 spec->init_verbs = vt1708_volume_init_verbs; 861 862 spec->input_mux = &spec->private_imux; 863 864 return 1; 865 } 866 867 /* init callback for auto-configuration model -- overriding the default init */ 868 static int via_auto_init(struct hda_codec *codec) 869 { 870 via_init(codec); 871 via_auto_init_multi_out(codec); 872 via_auto_init_hp_out(codec); 873 via_auto_init_analog_input(codec); 874 return 0; 875 } 876 877 static int patch_vt1708(struct hda_codec *codec) 878 { 879 struct via_spec *spec; 880 int err; 881 882 /* create a codec specific record */ 883 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 884 if (spec == NULL) 885 return -ENOMEM; 886 887 codec->spec = spec; 888 889 /* automatic parse from the BIOS config */ 890 err = vt1708_parse_auto_config(codec); 891 if (err < 0) { 892 via_free(codec); 893 return err; 894 } else if (!err) { 895 printk(KERN_INFO "hda_codec: Cannot set up configuration " 896 "from BIOS. Using genenic mode...\n"); 897 } 898 899 900 spec->stream_name_analog = "VT1708 Analog"; 901 spec->stream_analog_playback = &vt1708_pcm_analog_playback; 902 spec->stream_analog_capture = &vt1708_pcm_analog_capture; 903 904 spec->stream_name_digital = "VT1708 Digital"; 905 spec->stream_digital_playback = &vt1708_pcm_digital_playback; 906 spec->stream_digital_capture = &vt1708_pcm_digital_capture; 907 908 909 if (!spec->adc_nids && spec->input_mux) { 910 spec->adc_nids = vt1708_adc_nids; 911 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids); 912 spec->mixers[spec->num_mixers] = vt1708_capture_mixer; 913 spec->num_mixers++; 914 } 915 916 codec->patch_ops = via_patch_ops; 917 918 codec->patch_ops.init = via_auto_init; 919 #ifdef CONFIG_SND_HDA_POWER_SAVE 920 spec->loopback.amplist = vt1708_loopbacks; 921 #endif 922 923 return 0; 924 } 925 926 /* capture mixer elements */ 927 static struct snd_kcontrol_new vt1709_capture_mixer[] = { 928 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT), 929 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT), 930 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT), 931 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT), 932 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT), 933 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT), 934 { 935 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 936 /* The multiple "Capture Source" controls confuse alsamixer 937 * So call somewhat different.. 938 */ 939 /* .name = "Capture Source", */ 940 .name = "Input Source", 941 .count = 1, 942 .info = via_mux_enum_info, 943 .get = via_mux_enum_get, 944 .put = via_mux_enum_put, 945 }, 946 { } /* end */ 947 }; 948 949 /* 950 * generic initialization of ADC, input mixers and output mixers 951 */ 952 static struct hda_verb vt1709_10ch_volume_init_verbs[] = { 953 /* 954 * Unmute ADC0-2 and set the default input to mic-in 955 */ 956 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 958 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 959 960 961 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 962 * mixer widget 963 */ 964 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 965 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 966 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 967 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 968 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 969 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 970 971 /* 972 * Set up output selector (0x1a, 0x1b, 0x29) 973 */ 974 /* set vol=0 to output mixers */ 975 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 976 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 977 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 978 979 /* 980 * Unmute PW3 and PW4 981 */ 982 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 983 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 984 985 /* Set input of PW4 as AOW4 */ 986 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1}, 987 /* PW9 Output enable */ 988 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 989 { } 990 }; 991 992 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { 993 .substreams = 1, 994 .channels_min = 2, 995 .channels_max = 10, 996 .nid = 0x10, /* NID to query formats and rates */ 997 .ops = { 998 .open = via_playback_pcm_open, 999 .prepare = via_playback_pcm_prepare, 1000 .cleanup = via_playback_pcm_cleanup 1001 }, 1002 }; 1003 1004 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { 1005 .substreams = 1, 1006 .channels_min = 2, 1007 .channels_max = 6, 1008 .nid = 0x10, /* NID to query formats and rates */ 1009 .ops = { 1010 .open = via_playback_pcm_open, 1011 .prepare = via_playback_pcm_prepare, 1012 .cleanup = via_playback_pcm_cleanup 1013 }, 1014 }; 1015 1016 static struct hda_pcm_stream vt1709_pcm_analog_capture = { 1017 .substreams = 2, 1018 .channels_min = 2, 1019 .channels_max = 2, 1020 .nid = 0x14, /* NID to query formats and rates */ 1021 .ops = { 1022 .prepare = via_capture_pcm_prepare, 1023 .cleanup = via_capture_pcm_cleanup 1024 }, 1025 }; 1026 1027 static struct hda_pcm_stream vt1709_pcm_digital_playback = { 1028 .substreams = 1, 1029 .channels_min = 2, 1030 .channels_max = 2, 1031 /* NID is set in via_build_pcms */ 1032 .ops = { 1033 .open = via_dig_playback_pcm_open, 1034 .close = via_dig_playback_pcm_close 1035 }, 1036 }; 1037 1038 static struct hda_pcm_stream vt1709_pcm_digital_capture = { 1039 .substreams = 1, 1040 .channels_min = 2, 1041 .channels_max = 2, 1042 }; 1043 1044 static int vt1709_auto_fill_dac_nids(struct via_spec *spec, 1045 const struct auto_pin_cfg *cfg) 1046 { 1047 int i; 1048 hda_nid_t nid; 1049 1050 if (cfg->line_outs == 4) /* 10 channels */ 1051 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */ 1052 else if (cfg->line_outs == 3) /* 6 channels */ 1053 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */ 1054 1055 spec->multiout.dac_nids = spec->private_dac_nids; 1056 1057 if (cfg->line_outs == 4) { /* 10 channels */ 1058 for (i = 0; i < cfg->line_outs; i++) { 1059 nid = cfg->line_out_pins[i]; 1060 if (nid) { 1061 /* config dac list */ 1062 switch (i) { 1063 case AUTO_SEQ_FRONT: 1064 /* AOW0 */ 1065 spec->multiout.dac_nids[i] = 0x10; 1066 break; 1067 case AUTO_SEQ_CENLFE: 1068 /* AOW2 */ 1069 spec->multiout.dac_nids[i] = 0x12; 1070 break; 1071 case AUTO_SEQ_SURROUND: 1072 /* AOW3 */ 1073 spec->multiout.dac_nids[i] = 0x27; 1074 break; 1075 case AUTO_SEQ_SIDE: 1076 /* AOW1 */ 1077 spec->multiout.dac_nids[i] = 0x11; 1078 break; 1079 default: 1080 break; 1081 } 1082 } 1083 } 1084 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ 1085 1086 } else if (cfg->line_outs == 3) { /* 6 channels */ 1087 for(i = 0; i < cfg->line_outs; i++) { 1088 nid = cfg->line_out_pins[i]; 1089 if (nid) { 1090 /* config dac list */ 1091 switch(i) { 1092 case AUTO_SEQ_FRONT: 1093 /* AOW0 */ 1094 spec->multiout.dac_nids[i] = 0x10; 1095 break; 1096 case AUTO_SEQ_CENLFE: 1097 /* AOW2 */ 1098 spec->multiout.dac_nids[i] = 0x12; 1099 break; 1100 case AUTO_SEQ_SURROUND: 1101 /* AOW1 */ 1102 spec->multiout.dac_nids[i] = 0x11; 1103 break; 1104 default: 1105 break; 1106 } 1107 } 1108 } 1109 } 1110 1111 return 0; 1112 } 1113 1114 /* add playback controls from the parsed DAC table */ 1115 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec, 1116 const struct auto_pin_cfg *cfg) 1117 { 1118 char name[32]; 1119 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 1120 hda_nid_t nid = 0; 1121 int i, err; 1122 1123 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 1124 nid = cfg->line_out_pins[i]; 1125 1126 if (!nid) 1127 continue; 1128 1129 if (i == AUTO_SEQ_CENLFE) { 1130 /* Center/LFE */ 1131 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1132 "Center Playback Volume", 1133 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, 1134 HDA_OUTPUT)); 1135 if (err < 0) 1136 return err; 1137 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1138 "LFE Playback Volume", 1139 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, 1140 HDA_OUTPUT)); 1141 if (err < 0) 1142 return err; 1143 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1144 "Center Playback Switch", 1145 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, 1146 HDA_OUTPUT)); 1147 if (err < 0) 1148 return err; 1149 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1150 "LFE Playback Switch", 1151 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, 1152 HDA_OUTPUT)); 1153 if (err < 0) 1154 return err; 1155 } else if (i == AUTO_SEQ_FRONT){ 1156 /* add control to mixer index 0 */ 1157 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1158 "Master Front Playback Volume", 1159 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, 1160 HDA_INPUT)); 1161 if (err < 0) 1162 return err; 1163 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1164 "Master Front Playback Switch", 1165 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, 1166 HDA_INPUT)); 1167 if (err < 0) 1168 return err; 1169 1170 /* add control to PW3 */ 1171 sprintf(name, "%s Playback Volume", chname[i]); 1172 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1173 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1174 HDA_OUTPUT)); 1175 if (err < 0) 1176 return err; 1177 sprintf(name, "%s Playback Switch", chname[i]); 1178 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1179 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1180 HDA_OUTPUT)); 1181 if (err < 0) 1182 return err; 1183 } else if (i == AUTO_SEQ_SURROUND) { 1184 sprintf(name, "%s Playback Volume", chname[i]); 1185 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1186 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, 1187 HDA_OUTPUT)); 1188 if (err < 0) 1189 return err; 1190 sprintf(name, "%s Playback Switch", chname[i]); 1191 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1192 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, 1193 HDA_OUTPUT)); 1194 if (err < 0) 1195 return err; 1196 } else if (i == AUTO_SEQ_SIDE) { 1197 sprintf(name, "%s Playback Volume", chname[i]); 1198 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1199 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, 1200 HDA_OUTPUT)); 1201 if (err < 0) 1202 return err; 1203 sprintf(name, "%s Playback Switch", chname[i]); 1204 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1205 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, 1206 HDA_OUTPUT)); 1207 if (err < 0) 1208 return err; 1209 } 1210 } 1211 1212 return 0; 1213 } 1214 1215 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 1216 { 1217 int err; 1218 1219 if (!pin) 1220 return 0; 1221 1222 if (spec->multiout.num_dacs == 5) /* 10 channels */ 1223 spec->multiout.hp_nid = VT1709_HP_DAC_NID; 1224 else if (spec->multiout.num_dacs == 3) /* 6 channels */ 1225 spec->multiout.hp_nid = 0; 1226 1227 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1228 "Headphone Playback Volume", 1229 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 1230 if (err < 0) 1231 return err; 1232 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1233 "Headphone Playback Switch", 1234 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 1235 if (err < 0) 1236 return err; 1237 1238 return 0; 1239 } 1240 1241 /* create playback/capture controls for input pins */ 1242 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec, 1243 const struct auto_pin_cfg *cfg) 1244 { 1245 static char *labels[] = { 1246 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 1247 }; 1248 struct hda_input_mux *imux = &spec->private_imux; 1249 int i, err, idx = 0; 1250 1251 /* for internal loopback recording select */ 1252 imux->items[imux->num_items].label = "Stereo Mixer"; 1253 imux->items[imux->num_items].index = idx; 1254 imux->num_items++; 1255 1256 for (i = 0; i < AUTO_PIN_LAST; i++) { 1257 if (!cfg->input_pins[i]) 1258 continue; 1259 1260 switch (cfg->input_pins[i]) { 1261 case 0x1d: /* Mic */ 1262 idx = 2; 1263 break; 1264 1265 case 0x1e: /* Line In */ 1266 idx = 3; 1267 break; 1268 1269 case 0x21: /* Front Mic */ 1270 idx = 4; 1271 break; 1272 1273 case 0x23: /* CD */ 1274 idx = 1; 1275 break; 1276 } 1277 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 1278 idx, 0x18); 1279 if (err < 0) 1280 return err; 1281 imux->items[imux->num_items].label = labels[i]; 1282 imux->items[imux->num_items].index = idx; 1283 imux->num_items++; 1284 } 1285 return 0; 1286 } 1287 1288 static int vt1709_parse_auto_config(struct hda_codec *codec) 1289 { 1290 struct via_spec *spec = codec->spec; 1291 int err; 1292 1293 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 1294 if (err < 0) 1295 return err; 1296 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg); 1297 if (err < 0) 1298 return err; 1299 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 1300 return 0; /* can't find valid BIOS pin config */ 1301 1302 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg); 1303 if (err < 0) 1304 return err; 1305 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 1306 if (err < 0) 1307 return err; 1308 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg); 1309 if (err < 0) 1310 return err; 1311 1312 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 1313 1314 if (spec->autocfg.dig_out_pin) 1315 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID; 1316 if (spec->autocfg.dig_in_pin) 1317 spec->dig_in_nid = VT1709_DIGIN_NID; 1318 1319 if (spec->kctl_alloc) 1320 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1321 1322 spec->input_mux = &spec->private_imux; 1323 1324 return 1; 1325 } 1326 1327 #ifdef CONFIG_SND_HDA_POWER_SAVE 1328 static struct hda_amp_list vt1709_loopbacks[] = { 1329 { 0x18, HDA_INPUT, 1 }, 1330 { 0x18, HDA_INPUT, 2 }, 1331 { 0x18, HDA_INPUT, 3 }, 1332 { 0x18, HDA_INPUT, 4 }, 1333 { } /* end */ 1334 }; 1335 #endif 1336 1337 static int patch_vt1709_10ch(struct hda_codec *codec) 1338 { 1339 struct via_spec *spec; 1340 int err; 1341 1342 /* create a codec specific record */ 1343 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1344 if (spec == NULL) 1345 return -ENOMEM; 1346 1347 codec->spec = spec; 1348 1349 err = vt1709_parse_auto_config(codec); 1350 if (err < 0) { 1351 via_free(codec); 1352 return err; 1353 } else if (!err) { 1354 printk(KERN_INFO "hda_codec: Cannot set up configuration. " 1355 "Using genenic mode...\n"); 1356 } 1357 1358 spec->init_verbs = vt1709_10ch_volume_init_verbs; 1359 1360 spec->stream_name_analog = "VT1709 Analog"; 1361 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback; 1362 spec->stream_analog_capture = &vt1709_pcm_analog_capture; 1363 1364 spec->stream_name_digital = "VT1709 Digital"; 1365 spec->stream_digital_playback = &vt1709_pcm_digital_playback; 1366 spec->stream_digital_capture = &vt1709_pcm_digital_capture; 1367 1368 1369 if (!spec->adc_nids && spec->input_mux) { 1370 spec->adc_nids = vt1709_adc_nids; 1371 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); 1372 spec->mixers[spec->num_mixers] = vt1709_capture_mixer; 1373 spec->num_mixers++; 1374 } 1375 1376 codec->patch_ops = via_patch_ops; 1377 1378 codec->patch_ops.init = via_auto_init; 1379 #ifdef CONFIG_SND_HDA_POWER_SAVE 1380 spec->loopback.amplist = vt1709_loopbacks; 1381 #endif 1382 1383 return 0; 1384 } 1385 /* 1386 * generic initialization of ADC, input mixers and output mixers 1387 */ 1388 static struct hda_verb vt1709_6ch_volume_init_verbs[] = { 1389 /* 1390 * Unmute ADC0-2 and set the default input to mic-in 1391 */ 1392 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1393 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1394 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1395 1396 1397 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1398 * mixer widget 1399 */ 1400 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 1401 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1402 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1403 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 1404 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 1405 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 1406 1407 /* 1408 * Set up output selector (0x1a, 0x1b, 0x29) 1409 */ 1410 /* set vol=0 to output mixers */ 1411 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1412 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1413 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1414 1415 /* 1416 * Unmute PW3 and PW4 1417 */ 1418 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1419 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1420 1421 /* Set input of PW4 as MW0 */ 1422 {0x20, AC_VERB_SET_CONNECT_SEL, 0}, 1423 /* PW9 Output enable */ 1424 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1425 { } 1426 }; 1427 1428 static int patch_vt1709_6ch(struct hda_codec *codec) 1429 { 1430 struct via_spec *spec; 1431 int err; 1432 1433 /* create a codec specific record */ 1434 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1435 if (spec == NULL) 1436 return -ENOMEM; 1437 1438 codec->spec = spec; 1439 1440 err = vt1709_parse_auto_config(codec); 1441 if (err < 0) { 1442 via_free(codec); 1443 return err; 1444 } else if (!err) { 1445 printk(KERN_INFO "hda_codec: Cannot set up configuration. " 1446 "Using genenic mode...\n"); 1447 } 1448 1449 spec->init_verbs = vt1709_6ch_volume_init_verbs; 1450 1451 spec->stream_name_analog = "VT1709 Analog"; 1452 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback; 1453 spec->stream_analog_capture = &vt1709_pcm_analog_capture; 1454 1455 spec->stream_name_digital = "VT1709 Digital"; 1456 spec->stream_digital_playback = &vt1709_pcm_digital_playback; 1457 spec->stream_digital_capture = &vt1709_pcm_digital_capture; 1458 1459 1460 if (!spec->adc_nids && spec->input_mux) { 1461 spec->adc_nids = vt1709_adc_nids; 1462 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); 1463 spec->mixers[spec->num_mixers] = vt1709_capture_mixer; 1464 spec->num_mixers++; 1465 } 1466 1467 codec->patch_ops = via_patch_ops; 1468 1469 codec->patch_ops.init = via_auto_init; 1470 #ifdef CONFIG_SND_HDA_POWER_SAVE 1471 spec->loopback.amplist = vt1709_loopbacks; 1472 #endif 1473 return 0; 1474 } 1475 1476 /* capture mixer elements */ 1477 static struct snd_kcontrol_new vt1708B_capture_mixer[] = { 1478 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 1479 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 1480 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 1481 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT), 1482 { 1483 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1484 /* The multiple "Capture Source" controls confuse alsamixer 1485 * So call somewhat different.. 1486 */ 1487 /* .name = "Capture Source", */ 1488 .name = "Input Source", 1489 .count = 1, 1490 .info = via_mux_enum_info, 1491 .get = via_mux_enum_get, 1492 .put = via_mux_enum_put, 1493 }, 1494 { } /* end */ 1495 }; 1496 /* 1497 * generic initialization of ADC, input mixers and output mixers 1498 */ 1499 static struct hda_verb vt1708B_8ch_volume_init_verbs[] = { 1500 /* 1501 * Unmute ADC0-1 and set the default input to mic-in 1502 */ 1503 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1504 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1505 1506 1507 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1508 * mixer widget 1509 */ 1510 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 1511 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1512 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1513 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 1514 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 1515 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 1516 1517 /* 1518 * Set up output mixers 1519 */ 1520 /* set vol=0 to output mixers */ 1521 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1522 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1523 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1524 1525 /* Setup default input to PW4 */ 1526 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, 1527 /* PW9 Output enable */ 1528 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1529 /* PW10 Input enable */ 1530 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 1531 { } 1532 }; 1533 1534 static struct hda_verb vt1708B_4ch_volume_init_verbs[] = { 1535 /* 1536 * Unmute ADC0-1 and set the default input to mic-in 1537 */ 1538 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1539 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1540 1541 1542 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1543 * mixer widget 1544 */ 1545 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 1546 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1547 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1548 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 1549 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 1550 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 1551 1552 /* 1553 * Set up output mixers 1554 */ 1555 /* set vol=0 to output mixers */ 1556 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1557 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1558 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1559 1560 /* Setup default input of PW4 to MW0 */ 1561 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0}, 1562 /* PW9 Output enable */ 1563 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1564 /* PW10 Input enable */ 1565 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 1566 { } 1567 }; 1568 1569 static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { 1570 .substreams = 1, 1571 .channels_min = 2, 1572 .channels_max = 8, 1573 .nid = 0x10, /* NID to query formats and rates */ 1574 .ops = { 1575 .open = via_playback_pcm_open, 1576 .prepare = via_playback_pcm_prepare, 1577 .cleanup = via_playback_pcm_cleanup 1578 }, 1579 }; 1580 1581 static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { 1582 .substreams = 1, 1583 .channels_min = 2, 1584 .channels_max = 4, 1585 .nid = 0x10, /* NID to query formats and rates */ 1586 .ops = { 1587 .open = via_playback_pcm_open, 1588 .prepare = via_playback_pcm_prepare, 1589 .cleanup = via_playback_pcm_cleanup 1590 }, 1591 }; 1592 1593 static struct hda_pcm_stream vt1708B_pcm_analog_capture = { 1594 .substreams = 2, 1595 .channels_min = 2, 1596 .channels_max = 2, 1597 .nid = 0x13, /* NID to query formats and rates */ 1598 .ops = { 1599 .prepare = via_capture_pcm_prepare, 1600 .cleanup = via_capture_pcm_cleanup 1601 }, 1602 }; 1603 1604 static struct hda_pcm_stream vt1708B_pcm_digital_playback = { 1605 .substreams = 1, 1606 .channels_min = 2, 1607 .channels_max = 2, 1608 /* NID is set in via_build_pcms */ 1609 .ops = { 1610 .open = via_dig_playback_pcm_open, 1611 .close = via_dig_playback_pcm_close, 1612 .prepare = via_dig_playback_pcm_prepare 1613 }, 1614 }; 1615 1616 static struct hda_pcm_stream vt1708B_pcm_digital_capture = { 1617 .substreams = 1, 1618 .channels_min = 2, 1619 .channels_max = 2, 1620 }; 1621 1622 /* fill in the dac_nids table from the parsed pin configuration */ 1623 static int vt1708B_auto_fill_dac_nids(struct via_spec *spec, 1624 const struct auto_pin_cfg *cfg) 1625 { 1626 int i; 1627 hda_nid_t nid; 1628 1629 spec->multiout.num_dacs = cfg->line_outs; 1630 1631 spec->multiout.dac_nids = spec->private_dac_nids; 1632 1633 for (i = 0; i < 4; i++) { 1634 nid = cfg->line_out_pins[i]; 1635 if (nid) { 1636 /* config dac list */ 1637 switch (i) { 1638 case AUTO_SEQ_FRONT: 1639 spec->multiout.dac_nids[i] = 0x10; 1640 break; 1641 case AUTO_SEQ_CENLFE: 1642 spec->multiout.dac_nids[i] = 0x24; 1643 break; 1644 case AUTO_SEQ_SURROUND: 1645 spec->multiout.dac_nids[i] = 0x25; 1646 break; 1647 case AUTO_SEQ_SIDE: 1648 spec->multiout.dac_nids[i] = 0x11; 1649 break; 1650 } 1651 } 1652 } 1653 1654 return 0; 1655 } 1656 1657 /* add playback controls from the parsed DAC table */ 1658 static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec, 1659 const struct auto_pin_cfg *cfg) 1660 { 1661 char name[32]; 1662 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 1663 hda_nid_t nid_vols[] = {0x16, 0x27, 0x26, 0x18}; 1664 hda_nid_t nid, nid_vol = 0; 1665 int i, err; 1666 1667 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 1668 nid = cfg->line_out_pins[i]; 1669 1670 if (!nid) 1671 continue; 1672 1673 nid_vol = nid_vols[i]; 1674 1675 if (i == AUTO_SEQ_CENLFE) { 1676 /* Center/LFE */ 1677 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1678 "Center Playback Volume", 1679 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 1680 HDA_OUTPUT)); 1681 if (err < 0) 1682 return err; 1683 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1684 "LFE Playback Volume", 1685 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 1686 HDA_OUTPUT)); 1687 if (err < 0) 1688 return err; 1689 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1690 "Center Playback Switch", 1691 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 1692 HDA_OUTPUT)); 1693 if (err < 0) 1694 return err; 1695 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1696 "LFE Playback Switch", 1697 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 1698 HDA_OUTPUT)); 1699 if (err < 0) 1700 return err; 1701 } else if (i == AUTO_SEQ_FRONT) { 1702 /* add control to mixer index 0 */ 1703 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1704 "Master Front Playback Volume", 1705 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1706 HDA_INPUT)); 1707 if (err < 0) 1708 return err; 1709 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1710 "Master Front Playback Switch", 1711 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1712 HDA_INPUT)); 1713 if (err < 0) 1714 return err; 1715 1716 /* add control to PW3 */ 1717 sprintf(name, "%s Playback Volume", chname[i]); 1718 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1719 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1720 HDA_OUTPUT)); 1721 if (err < 0) 1722 return err; 1723 sprintf(name, "%s Playback Switch", chname[i]); 1724 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1725 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1726 HDA_OUTPUT)); 1727 if (err < 0) 1728 return err; 1729 } else { 1730 sprintf(name, "%s Playback Volume", chname[i]); 1731 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1732 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1733 HDA_OUTPUT)); 1734 if (err < 0) 1735 return err; 1736 sprintf(name, "%s Playback Switch", chname[i]); 1737 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1738 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1739 HDA_OUTPUT)); 1740 if (err < 0) 1741 return err; 1742 } 1743 } 1744 1745 return 0; 1746 } 1747 1748 static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 1749 { 1750 int err; 1751 1752 if (!pin) 1753 return 0; 1754 1755 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */ 1756 1757 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1758 "Headphone Playback Volume", 1759 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 1760 if (err < 0) 1761 return err; 1762 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1763 "Headphone Playback Switch", 1764 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 1765 if (err < 0) 1766 return err; 1767 1768 return 0; 1769 } 1770 1771 /* create playback/capture controls for input pins */ 1772 static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec, 1773 const struct auto_pin_cfg *cfg) 1774 { 1775 static char *labels[] = { 1776 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 1777 }; 1778 struct hda_input_mux *imux = &spec->private_imux; 1779 int i, err, idx = 0; 1780 1781 /* for internal loopback recording select */ 1782 imux->items[imux->num_items].label = "Stereo Mixer"; 1783 imux->items[imux->num_items].index = idx; 1784 imux->num_items++; 1785 1786 for (i = 0; i < AUTO_PIN_LAST; i++) { 1787 if (!cfg->input_pins[i]) 1788 continue; 1789 1790 switch (cfg->input_pins[i]) { 1791 case 0x1a: /* Mic */ 1792 idx = 2; 1793 break; 1794 1795 case 0x1b: /* Line In */ 1796 idx = 3; 1797 break; 1798 1799 case 0x1e: /* Front Mic */ 1800 idx = 4; 1801 break; 1802 1803 case 0x1f: /* CD */ 1804 idx = 1; 1805 break; 1806 } 1807 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 1808 idx, 0x16); 1809 if (err < 0) 1810 return err; 1811 imux->items[imux->num_items].label = labels[i]; 1812 imux->items[imux->num_items].index = idx; 1813 imux->num_items++; 1814 } 1815 return 0; 1816 } 1817 1818 static int vt1708B_parse_auto_config(struct hda_codec *codec) 1819 { 1820 struct via_spec *spec = codec->spec; 1821 int err; 1822 1823 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 1824 if (err < 0) 1825 return err; 1826 err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg); 1827 if (err < 0) 1828 return err; 1829 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 1830 return 0; /* can't find valid BIOS pin config */ 1831 1832 err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg); 1833 if (err < 0) 1834 return err; 1835 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 1836 if (err < 0) 1837 return err; 1838 err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg); 1839 if (err < 0) 1840 return err; 1841 1842 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 1843 1844 if (spec->autocfg.dig_out_pin) 1845 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID; 1846 if (spec->autocfg.dig_in_pin) 1847 spec->dig_in_nid = VT1708B_DIGIN_NID; 1848 1849 if (spec->kctl_alloc) 1850 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1851 1852 spec->input_mux = &spec->private_imux; 1853 1854 return 1; 1855 } 1856 1857 #ifdef CONFIG_SND_HDA_POWER_SAVE 1858 static struct hda_amp_list vt1708B_loopbacks[] = { 1859 { 0x16, HDA_INPUT, 1 }, 1860 { 0x16, HDA_INPUT, 2 }, 1861 { 0x16, HDA_INPUT, 3 }, 1862 { 0x16, HDA_INPUT, 4 }, 1863 { } /* end */ 1864 }; 1865 #endif 1866 1867 static int patch_vt1708B_8ch(struct hda_codec *codec) 1868 { 1869 struct via_spec *spec; 1870 int err; 1871 1872 /* create a codec specific record */ 1873 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1874 if (spec == NULL) 1875 return -ENOMEM; 1876 1877 codec->spec = spec; 1878 1879 /* automatic parse from the BIOS config */ 1880 err = vt1708B_parse_auto_config(codec); 1881 if (err < 0) { 1882 via_free(codec); 1883 return err; 1884 } else if (!err) { 1885 printk(KERN_INFO "hda_codec: Cannot set up configuration " 1886 "from BIOS. Using genenic mode...\n"); 1887 } 1888 1889 spec->init_verbs = vt1708B_8ch_volume_init_verbs; 1890 1891 spec->stream_name_analog = "VT1708B Analog"; 1892 spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback; 1893 spec->stream_analog_capture = &vt1708B_pcm_analog_capture; 1894 1895 spec->stream_name_digital = "VT1708B Digital"; 1896 spec->stream_digital_playback = &vt1708B_pcm_digital_playback; 1897 spec->stream_digital_capture = &vt1708B_pcm_digital_capture; 1898 1899 if (!spec->adc_nids && spec->input_mux) { 1900 spec->adc_nids = vt1708B_adc_nids; 1901 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); 1902 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; 1903 spec->num_mixers++; 1904 } 1905 1906 codec->patch_ops = via_patch_ops; 1907 1908 codec->patch_ops.init = via_auto_init; 1909 #ifdef CONFIG_SND_HDA_POWER_SAVE 1910 spec->loopback.amplist = vt1708B_loopbacks; 1911 #endif 1912 1913 return 0; 1914 } 1915 1916 static int patch_vt1708B_4ch(struct hda_codec *codec) 1917 { 1918 struct via_spec *spec; 1919 int err; 1920 1921 /* create a codec specific record */ 1922 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1923 if (spec == NULL) 1924 return -ENOMEM; 1925 1926 codec->spec = spec; 1927 1928 /* automatic parse from the BIOS config */ 1929 err = vt1708B_parse_auto_config(codec); 1930 if (err < 0) { 1931 via_free(codec); 1932 return err; 1933 } else if (!err) { 1934 printk(KERN_INFO "hda_codec: Cannot set up configuration " 1935 "from BIOS. Using genenic mode...\n"); 1936 } 1937 1938 spec->init_verbs = vt1708B_4ch_volume_init_verbs; 1939 1940 spec->stream_name_analog = "VT1708B Analog"; 1941 spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback; 1942 spec->stream_analog_capture = &vt1708B_pcm_analog_capture; 1943 1944 spec->stream_name_digital = "VT1708B Digital"; 1945 spec->stream_digital_playback = &vt1708B_pcm_digital_playback; 1946 spec->stream_digital_capture = &vt1708B_pcm_digital_capture; 1947 1948 if (!spec->adc_nids && spec->input_mux) { 1949 spec->adc_nids = vt1708B_adc_nids; 1950 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); 1951 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; 1952 spec->num_mixers++; 1953 } 1954 1955 codec->patch_ops = via_patch_ops; 1956 1957 codec->patch_ops.init = via_auto_init; 1958 #ifdef CONFIG_SND_HDA_POWER_SAVE 1959 spec->loopback.amplist = vt1708B_loopbacks; 1960 #endif 1961 1962 return 0; 1963 } 1964 1965 /* 1966 * patch entries 1967 */ 1968 struct hda_codec_preset snd_hda_preset_via[] = { 1969 { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708}, 1970 { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708}, 1971 { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708}, 1972 { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708}, 1973 { .id = 0x1106E710, .name = "VIA VT1709 10-Ch", 1974 .patch = patch_vt1709_10ch}, 1975 { .id = 0x1106E711, .name = "VIA VT1709 10-Ch", 1976 .patch = patch_vt1709_10ch}, 1977 { .id = 0x1106E712, .name = "VIA VT1709 10-Ch", 1978 .patch = patch_vt1709_10ch}, 1979 { .id = 0x1106E713, .name = "VIA VT1709 10-Ch", 1980 .patch = patch_vt1709_10ch}, 1981 { .id = 0x1106E714, .name = "VIA VT1709 6-Ch", 1982 .patch = patch_vt1709_6ch}, 1983 { .id = 0x1106E715, .name = "VIA VT1709 6-Ch", 1984 .patch = patch_vt1709_6ch}, 1985 { .id = 0x1106E716, .name = "VIA VT1709 6-Ch", 1986 .patch = patch_vt1709_6ch}, 1987 { .id = 0x1106E717, .name = "VIA VT1709 6-Ch", 1988 .patch = patch_vt1709_6ch}, 1989 { .id = 0x1106E720, .name = "VIA VT1708B 8-Ch", 1990 .patch = patch_vt1708B_8ch}, 1991 { .id = 0x1106E721, .name = "VIA VT1708B 8-Ch", 1992 .patch = patch_vt1708B_8ch}, 1993 { .id = 0x1106E722, .name = "VIA VT1708B 8-Ch", 1994 .patch = patch_vt1708B_8ch}, 1995 { .id = 0x1106E723, .name = "VIA VT1708B 8-Ch", 1996 .patch = patch_vt1708B_8ch}, 1997 { .id = 0x1106E724, .name = "VIA VT1708B 4-Ch", 1998 .patch = patch_vt1708B_4ch}, 1999 { .id = 0x1106E725, .name = "VIA VT1708B 4-Ch", 2000 .patch = patch_vt1708B_4ch}, 2001 { .id = 0x1106E726, .name = "VIA VT1708B 4-Ch", 2002 .patch = patch_vt1708B_4ch}, 2003 { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch", 2004 .patch = patch_vt1708B_4ch}, 2005 {} /* terminator */ 2006 }; 2007