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 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 } 362 363 static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 364 struct hda_codec *codec, 365 unsigned int stream_tag, 366 unsigned int format, 367 struct snd_pcm_substream *substream) 368 { 369 struct via_spec *spec = codec->spec; 370 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 371 stream_tag, format, substream); 372 } 373 374 static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 375 struct hda_codec *codec, 376 struct snd_pcm_substream *substream) 377 { 378 struct via_spec *spec = codec->spec; 379 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 380 } 381 382 /* 383 * Digital out 384 */ 385 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 386 struct hda_codec *codec, 387 struct snd_pcm_substream *substream) 388 { 389 struct via_spec *spec = codec->spec; 390 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 391 } 392 393 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 394 struct hda_codec *codec, 395 struct snd_pcm_substream *substream) 396 { 397 struct via_spec *spec = codec->spec; 398 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 399 } 400 401 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 402 struct hda_codec *codec, 403 unsigned int stream_tag, 404 unsigned int format, 405 struct snd_pcm_substream *substream) 406 { 407 struct via_spec *spec = codec->spec; 408 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 409 stream_tag, format, substream); 410 } 411 412 /* 413 * Analog capture 414 */ 415 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 416 struct hda_codec *codec, 417 unsigned int stream_tag, 418 unsigned int format, 419 struct snd_pcm_substream *substream) 420 { 421 struct via_spec *spec = codec->spec; 422 423 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 424 stream_tag, 0, format); 425 return 0; 426 } 427 428 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 429 struct hda_codec *codec, 430 struct snd_pcm_substream *substream) 431 { 432 struct via_spec *spec = codec->spec; 433 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 434 0, 0, 0); 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 } 497 if (spec->dig_in_nid) { 498 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 499 if (err < 0) 500 return err; 501 } 502 return 0; 503 } 504 505 static int via_build_pcms(struct hda_codec *codec) 506 { 507 struct via_spec *spec = codec->spec; 508 struct hda_pcm *info = spec->pcm_rec; 509 510 codec->num_pcms = 1; 511 codec->pcm_info = info; 512 513 info->name = spec->stream_name_analog; 514 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 515 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 516 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 517 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 518 519 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 520 spec->multiout.max_channels; 521 522 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 523 codec->num_pcms++; 524 info++; 525 info->name = spec->stream_name_digital; 526 if (spec->multiout.dig_out_nid) { 527 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 528 *(spec->stream_digital_playback); 529 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 530 spec->multiout.dig_out_nid; 531 } 532 if (spec->dig_in_nid) { 533 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 534 *(spec->stream_digital_capture); 535 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 536 spec->dig_in_nid; 537 } 538 } 539 540 return 0; 541 } 542 543 static void via_free(struct hda_codec *codec) 544 { 545 struct via_spec *spec = codec->spec; 546 unsigned int i; 547 548 if (!spec) 549 return; 550 551 if (spec->kctl_alloc) { 552 for (i = 0; i < spec->num_kctl_used; i++) 553 kfree(spec->kctl_alloc[i].name); 554 kfree(spec->kctl_alloc); 555 } 556 557 kfree(codec->spec); 558 } 559 560 static int via_init(struct hda_codec *codec) 561 { 562 struct via_spec *spec = codec->spec; 563 snd_hda_sequence_write(codec, spec->init_verbs); 564 /* Lydia Add for EAPD enable */ 565 if (!spec->dig_in_nid) { /* No Digital In connection */ 566 if (IS_VT1708_VENDORID(codec->vendor_id)) { 567 snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0, 568 AC_VERB_SET_PIN_WIDGET_CONTROL, 569 PIN_OUT); 570 snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0, 571 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 572 } else if (IS_VT1709_10CH_VENDORID(codec->vendor_id) || 573 IS_VT1709_6CH_VENDORID(codec->vendor_id)) { 574 snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0, 575 AC_VERB_SET_PIN_WIDGET_CONTROL, 576 PIN_OUT); 577 snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0, 578 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 579 } else if (IS_VT1708B_8CH_VENDORID(codec->vendor_id) || 580 IS_VT1708B_4CH_VENDORID(codec->vendor_id)) { 581 snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0, 582 AC_VERB_SET_PIN_WIDGET_CONTROL, 583 PIN_OUT); 584 snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0, 585 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 586 } 587 } else /* enable SPDIF-input pin */ 588 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0, 589 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); 590 591 return 0; 592 } 593 594 #ifdef CONFIG_SND_HDA_POWER_SAVE 595 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) 596 { 597 struct via_spec *spec = codec->spec; 598 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 599 } 600 #endif 601 602 /* 603 */ 604 static struct hda_codec_ops via_patch_ops = { 605 .build_controls = via_build_controls, 606 .build_pcms = via_build_pcms, 607 .init = via_init, 608 .free = via_free, 609 #ifdef CONFIG_SND_HDA_POWER_SAVE 610 .check_power_status = via_check_power_status, 611 #endif 612 }; 613 614 /* fill in the dac_nids table from the parsed pin configuration */ 615 static int vt1708_auto_fill_dac_nids(struct via_spec *spec, 616 const struct auto_pin_cfg *cfg) 617 { 618 int i; 619 hda_nid_t nid; 620 621 spec->multiout.num_dacs = cfg->line_outs; 622 623 spec->multiout.dac_nids = spec->private_dac_nids; 624 625 for(i = 0; i < 4; i++) { 626 nid = cfg->line_out_pins[i]; 627 if (nid) { 628 /* config dac list */ 629 switch (i) { 630 case AUTO_SEQ_FRONT: 631 spec->multiout.dac_nids[i] = 0x10; 632 break; 633 case AUTO_SEQ_CENLFE: 634 spec->multiout.dac_nids[i] = 0x12; 635 break; 636 case AUTO_SEQ_SURROUND: 637 spec->multiout.dac_nids[i] = 0x13; 638 break; 639 case AUTO_SEQ_SIDE: 640 spec->multiout.dac_nids[i] = 0x11; 641 break; 642 } 643 } 644 } 645 646 return 0; 647 } 648 649 /* add playback controls from the parsed DAC table */ 650 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, 651 const struct auto_pin_cfg *cfg) 652 { 653 char name[32]; 654 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 655 hda_nid_t nid, nid_vol = 0; 656 int i, err; 657 658 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 659 nid = cfg->line_out_pins[i]; 660 661 if (!nid) 662 continue; 663 664 if (i != AUTO_SEQ_FRONT) 665 nid_vol = 0x1b - i + 1; 666 667 if (i == AUTO_SEQ_CENLFE) { 668 /* Center/LFE */ 669 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 670 "Center Playback Volume", 671 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 672 HDA_OUTPUT)); 673 if (err < 0) 674 return err; 675 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 676 "LFE Playback Volume", 677 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 678 HDA_OUTPUT)); 679 if (err < 0) 680 return err; 681 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 682 "Center Playback Switch", 683 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 684 HDA_OUTPUT)); 685 if (err < 0) 686 return err; 687 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 688 "LFE Playback Switch", 689 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 690 HDA_OUTPUT)); 691 if (err < 0) 692 return err; 693 } else if (i == AUTO_SEQ_FRONT){ 694 /* add control to mixer index 0 */ 695 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 696 "Master Front Playback Volume", 697 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, 698 HDA_INPUT)); 699 if (err < 0) 700 return err; 701 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 702 "Master Front Playback Switch", 703 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, 704 HDA_INPUT)); 705 if (err < 0) 706 return err; 707 708 /* add control to PW3 */ 709 sprintf(name, "%s Playback Volume", chname[i]); 710 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 711 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 712 HDA_OUTPUT)); 713 if (err < 0) 714 return err; 715 sprintf(name, "%s Playback Switch", chname[i]); 716 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 717 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 718 HDA_OUTPUT)); 719 if (err < 0) 720 return err; 721 } else { 722 sprintf(name, "%s Playback Volume", chname[i]); 723 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 724 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 725 HDA_OUTPUT)); 726 if (err < 0) 727 return err; 728 sprintf(name, "%s Playback Switch", chname[i]); 729 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 730 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 731 HDA_OUTPUT)); 732 if (err < 0) 733 return err; 734 } 735 } 736 737 return 0; 738 } 739 740 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 741 { 742 int err; 743 744 if (!pin) 745 return 0; 746 747 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */ 748 749 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 750 "Headphone Playback Volume", 751 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 752 if (err < 0) 753 return err; 754 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 755 "Headphone Playback Switch", 756 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 757 if (err < 0) 758 return err; 759 760 return 0; 761 } 762 763 /* create playback/capture controls for input pins */ 764 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec, 765 const struct auto_pin_cfg *cfg) 766 { 767 static char *labels[] = { 768 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 769 }; 770 struct hda_input_mux *imux = &spec->private_imux; 771 int i, err, idx = 0; 772 773 /* for internal loopback recording select */ 774 imux->items[imux->num_items].label = "Stereo Mixer"; 775 imux->items[imux->num_items].index = idx; 776 imux->num_items++; 777 778 for (i = 0; i < AUTO_PIN_LAST; i++) { 779 if (!cfg->input_pins[i]) 780 continue; 781 782 switch (cfg->input_pins[i]) { 783 case 0x1d: /* Mic */ 784 idx = 2; 785 break; 786 787 case 0x1e: /* Line In */ 788 idx = 3; 789 break; 790 791 case 0x21: /* Front Mic */ 792 idx = 4; 793 break; 794 795 case 0x24: /* CD */ 796 idx = 1; 797 break; 798 } 799 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 800 idx, 0x17); 801 if (err < 0) 802 return err; 803 imux->items[imux->num_items].label = labels[i]; 804 imux->items[imux->num_items].index = idx; 805 imux->num_items++; 806 } 807 return 0; 808 } 809 810 #ifdef CONFIG_SND_HDA_POWER_SAVE 811 static struct hda_amp_list vt1708_loopbacks[] = { 812 { 0x17, HDA_INPUT, 1 }, 813 { 0x17, HDA_INPUT, 2 }, 814 { 0x17, HDA_INPUT, 3 }, 815 { 0x17, HDA_INPUT, 4 }, 816 { } /* end */ 817 }; 818 #endif 819 820 static int vt1708_parse_auto_config(struct hda_codec *codec) 821 { 822 struct via_spec *spec = codec->spec; 823 int err; 824 825 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 826 if (err < 0) 827 return err; 828 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg); 829 if (err < 0) 830 return err; 831 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 832 return 0; /* can't find valid BIOS pin config */ 833 834 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg); 835 if (err < 0) 836 return err; 837 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 838 if (err < 0) 839 return err; 840 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg); 841 if (err < 0) 842 return err; 843 844 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 845 846 if (spec->autocfg.dig_out_pin) 847 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; 848 if (spec->autocfg.dig_in_pin) 849 spec->dig_in_nid = VT1708_DIGIN_NID; 850 851 if (spec->kctl_alloc) 852 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 853 854 spec->init_verbs = vt1708_volume_init_verbs; 855 856 spec->input_mux = &spec->private_imux; 857 858 return 1; 859 } 860 861 /* init callback for auto-configuration model -- overriding the default init */ 862 static int via_auto_init(struct hda_codec *codec) 863 { 864 via_init(codec); 865 via_auto_init_multi_out(codec); 866 via_auto_init_hp_out(codec); 867 via_auto_init_analog_input(codec); 868 return 0; 869 } 870 871 static int patch_vt1708(struct hda_codec *codec) 872 { 873 struct via_spec *spec; 874 int err; 875 876 /* create a codec specific record */ 877 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 878 if (spec == NULL) 879 return -ENOMEM; 880 881 codec->spec = spec; 882 883 /* automatic parse from the BIOS config */ 884 err = vt1708_parse_auto_config(codec); 885 if (err < 0) { 886 via_free(codec); 887 return err; 888 } else if (!err) { 889 printk(KERN_INFO "hda_codec: Cannot set up configuration " 890 "from BIOS. Using genenic mode...\n"); 891 } 892 893 894 spec->stream_name_analog = "VT1708 Analog"; 895 spec->stream_analog_playback = &vt1708_pcm_analog_playback; 896 spec->stream_analog_capture = &vt1708_pcm_analog_capture; 897 898 spec->stream_name_digital = "VT1708 Digital"; 899 spec->stream_digital_playback = &vt1708_pcm_digital_playback; 900 spec->stream_digital_capture = &vt1708_pcm_digital_capture; 901 902 903 if (!spec->adc_nids && spec->input_mux) { 904 spec->adc_nids = vt1708_adc_nids; 905 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids); 906 spec->mixers[spec->num_mixers] = vt1708_capture_mixer; 907 spec->num_mixers++; 908 } 909 910 codec->patch_ops = via_patch_ops; 911 912 codec->patch_ops.init = via_auto_init; 913 #ifdef CONFIG_SND_HDA_POWER_SAVE 914 spec->loopback.amplist = vt1708_loopbacks; 915 #endif 916 917 return 0; 918 } 919 920 /* capture mixer elements */ 921 static struct snd_kcontrol_new vt1709_capture_mixer[] = { 922 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT), 923 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT), 924 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT), 925 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT), 926 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT), 927 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT), 928 { 929 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 930 /* The multiple "Capture Source" controls confuse alsamixer 931 * So call somewhat different.. 932 */ 933 /* .name = "Capture Source", */ 934 .name = "Input Source", 935 .count = 1, 936 .info = via_mux_enum_info, 937 .get = via_mux_enum_get, 938 .put = via_mux_enum_put, 939 }, 940 { } /* end */ 941 }; 942 943 /* 944 * generic initialization of ADC, input mixers and output mixers 945 */ 946 static struct hda_verb vt1709_10ch_volume_init_verbs[] = { 947 /* 948 * Unmute ADC0-2 and set the default input to mic-in 949 */ 950 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 951 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 952 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 953 954 955 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 956 * mixer widget 957 */ 958 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 959 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 960 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 961 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 962 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 963 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 964 965 /* 966 * Set up output selector (0x1a, 0x1b, 0x29) 967 */ 968 /* set vol=0 to output mixers */ 969 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 970 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 971 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 972 973 /* 974 * Unmute PW3 and PW4 975 */ 976 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 977 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 978 979 /* Set input of PW4 as AOW4 */ 980 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1}, 981 /* PW9 Output enable */ 982 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 983 { } 984 }; 985 986 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { 987 .substreams = 1, 988 .channels_min = 2, 989 .channels_max = 10, 990 .nid = 0x10, /* NID to query formats and rates */ 991 .ops = { 992 .open = via_playback_pcm_open, 993 .prepare = via_playback_pcm_prepare, 994 .cleanup = via_playback_pcm_cleanup 995 }, 996 }; 997 998 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { 999 .substreams = 1, 1000 .channels_min = 2, 1001 .channels_max = 6, 1002 .nid = 0x10, /* NID to query formats and rates */ 1003 .ops = { 1004 .open = via_playback_pcm_open, 1005 .prepare = via_playback_pcm_prepare, 1006 .cleanup = via_playback_pcm_cleanup 1007 }, 1008 }; 1009 1010 static struct hda_pcm_stream vt1709_pcm_analog_capture = { 1011 .substreams = 2, 1012 .channels_min = 2, 1013 .channels_max = 2, 1014 .nid = 0x14, /* NID to query formats and rates */ 1015 .ops = { 1016 .prepare = via_capture_pcm_prepare, 1017 .cleanup = via_capture_pcm_cleanup 1018 }, 1019 }; 1020 1021 static struct hda_pcm_stream vt1709_pcm_digital_playback = { 1022 .substreams = 1, 1023 .channels_min = 2, 1024 .channels_max = 2, 1025 /* NID is set in via_build_pcms */ 1026 .ops = { 1027 .open = via_dig_playback_pcm_open, 1028 .close = via_dig_playback_pcm_close 1029 }, 1030 }; 1031 1032 static struct hda_pcm_stream vt1709_pcm_digital_capture = { 1033 .substreams = 1, 1034 .channels_min = 2, 1035 .channels_max = 2, 1036 }; 1037 1038 static int vt1709_auto_fill_dac_nids(struct via_spec *spec, 1039 const struct auto_pin_cfg *cfg) 1040 { 1041 int i; 1042 hda_nid_t nid; 1043 1044 if (cfg->line_outs == 4) /* 10 channels */ 1045 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */ 1046 else if (cfg->line_outs == 3) /* 6 channels */ 1047 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */ 1048 1049 spec->multiout.dac_nids = spec->private_dac_nids; 1050 1051 if (cfg->line_outs == 4) { /* 10 channels */ 1052 for (i = 0; i < cfg->line_outs; i++) { 1053 nid = cfg->line_out_pins[i]; 1054 if (nid) { 1055 /* config dac list */ 1056 switch (i) { 1057 case AUTO_SEQ_FRONT: 1058 /* AOW0 */ 1059 spec->multiout.dac_nids[i] = 0x10; 1060 break; 1061 case AUTO_SEQ_CENLFE: 1062 /* AOW2 */ 1063 spec->multiout.dac_nids[i] = 0x12; 1064 break; 1065 case AUTO_SEQ_SURROUND: 1066 /* AOW3 */ 1067 spec->multiout.dac_nids[i] = 0x27; 1068 break; 1069 case AUTO_SEQ_SIDE: 1070 /* AOW1 */ 1071 spec->multiout.dac_nids[i] = 0x11; 1072 break; 1073 default: 1074 break; 1075 } 1076 } 1077 } 1078 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ 1079 1080 } else if (cfg->line_outs == 3) { /* 6 channels */ 1081 for(i = 0; i < cfg->line_outs; i++) { 1082 nid = cfg->line_out_pins[i]; 1083 if (nid) { 1084 /* config dac list */ 1085 switch(i) { 1086 case AUTO_SEQ_FRONT: 1087 /* AOW0 */ 1088 spec->multiout.dac_nids[i] = 0x10; 1089 break; 1090 case AUTO_SEQ_CENLFE: 1091 /* AOW2 */ 1092 spec->multiout.dac_nids[i] = 0x12; 1093 break; 1094 case AUTO_SEQ_SURROUND: 1095 /* AOW1 */ 1096 spec->multiout.dac_nids[i] = 0x11; 1097 break; 1098 default: 1099 break; 1100 } 1101 } 1102 } 1103 } 1104 1105 return 0; 1106 } 1107 1108 /* add playback controls from the parsed DAC table */ 1109 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec, 1110 const struct auto_pin_cfg *cfg) 1111 { 1112 char name[32]; 1113 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 1114 hda_nid_t nid = 0; 1115 int i, err; 1116 1117 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 1118 nid = cfg->line_out_pins[i]; 1119 1120 if (!nid) 1121 continue; 1122 1123 if (i == AUTO_SEQ_CENLFE) { 1124 /* Center/LFE */ 1125 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1126 "Center Playback Volume", 1127 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, 1128 HDA_OUTPUT)); 1129 if (err < 0) 1130 return err; 1131 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1132 "LFE Playback Volume", 1133 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, 1134 HDA_OUTPUT)); 1135 if (err < 0) 1136 return err; 1137 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1138 "Center Playback Switch", 1139 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, 1140 HDA_OUTPUT)); 1141 if (err < 0) 1142 return err; 1143 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1144 "LFE Playback Switch", 1145 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, 1146 HDA_OUTPUT)); 1147 if (err < 0) 1148 return err; 1149 } else if (i == AUTO_SEQ_FRONT){ 1150 /* add control to mixer index 0 */ 1151 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1152 "Master Front Playback Volume", 1153 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, 1154 HDA_INPUT)); 1155 if (err < 0) 1156 return err; 1157 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1158 "Master Front Playback Switch", 1159 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, 1160 HDA_INPUT)); 1161 if (err < 0) 1162 return err; 1163 1164 /* add control to PW3 */ 1165 sprintf(name, "%s Playback Volume", chname[i]); 1166 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1167 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1168 HDA_OUTPUT)); 1169 if (err < 0) 1170 return err; 1171 sprintf(name, "%s Playback Switch", chname[i]); 1172 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1173 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1174 HDA_OUTPUT)); 1175 if (err < 0) 1176 return err; 1177 } else if (i == AUTO_SEQ_SURROUND) { 1178 sprintf(name, "%s Playback Volume", chname[i]); 1179 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1180 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, 1181 HDA_OUTPUT)); 1182 if (err < 0) 1183 return err; 1184 sprintf(name, "%s Playback Switch", chname[i]); 1185 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1186 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, 1187 HDA_OUTPUT)); 1188 if (err < 0) 1189 return err; 1190 } else if (i == AUTO_SEQ_SIDE) { 1191 sprintf(name, "%s Playback Volume", chname[i]); 1192 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1193 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, 1194 HDA_OUTPUT)); 1195 if (err < 0) 1196 return err; 1197 sprintf(name, "%s Playback Switch", chname[i]); 1198 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1199 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, 1200 HDA_OUTPUT)); 1201 if (err < 0) 1202 return err; 1203 } 1204 } 1205 1206 return 0; 1207 } 1208 1209 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 1210 { 1211 int err; 1212 1213 if (!pin) 1214 return 0; 1215 1216 if (spec->multiout.num_dacs == 5) /* 10 channels */ 1217 spec->multiout.hp_nid = VT1709_HP_DAC_NID; 1218 else if (spec->multiout.num_dacs == 3) /* 6 channels */ 1219 spec->multiout.hp_nid = 0; 1220 1221 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1222 "Headphone Playback Volume", 1223 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 1224 if (err < 0) 1225 return err; 1226 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1227 "Headphone Playback Switch", 1228 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 1229 if (err < 0) 1230 return err; 1231 1232 return 0; 1233 } 1234 1235 /* create playback/capture controls for input pins */ 1236 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec, 1237 const struct auto_pin_cfg *cfg) 1238 { 1239 static char *labels[] = { 1240 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 1241 }; 1242 struct hda_input_mux *imux = &spec->private_imux; 1243 int i, err, idx = 0; 1244 1245 /* for internal loopback recording select */ 1246 imux->items[imux->num_items].label = "Stereo Mixer"; 1247 imux->items[imux->num_items].index = idx; 1248 imux->num_items++; 1249 1250 for (i = 0; i < AUTO_PIN_LAST; i++) { 1251 if (!cfg->input_pins[i]) 1252 continue; 1253 1254 switch (cfg->input_pins[i]) { 1255 case 0x1d: /* Mic */ 1256 idx = 2; 1257 break; 1258 1259 case 0x1e: /* Line In */ 1260 idx = 3; 1261 break; 1262 1263 case 0x21: /* Front Mic */ 1264 idx = 4; 1265 break; 1266 1267 case 0x23: /* CD */ 1268 idx = 1; 1269 break; 1270 } 1271 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 1272 idx, 0x18); 1273 if (err < 0) 1274 return err; 1275 imux->items[imux->num_items].label = labels[i]; 1276 imux->items[imux->num_items].index = idx; 1277 imux->num_items++; 1278 } 1279 return 0; 1280 } 1281 1282 static int vt1709_parse_auto_config(struct hda_codec *codec) 1283 { 1284 struct via_spec *spec = codec->spec; 1285 int err; 1286 1287 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 1288 if (err < 0) 1289 return err; 1290 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg); 1291 if (err < 0) 1292 return err; 1293 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 1294 return 0; /* can't find valid BIOS pin config */ 1295 1296 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg); 1297 if (err < 0) 1298 return err; 1299 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 1300 if (err < 0) 1301 return err; 1302 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg); 1303 if (err < 0) 1304 return err; 1305 1306 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 1307 1308 if (spec->autocfg.dig_out_pin) 1309 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID; 1310 if (spec->autocfg.dig_in_pin) 1311 spec->dig_in_nid = VT1709_DIGIN_NID; 1312 1313 if (spec->kctl_alloc) 1314 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1315 1316 spec->input_mux = &spec->private_imux; 1317 1318 return 1; 1319 } 1320 1321 #ifdef CONFIG_SND_HDA_POWER_SAVE 1322 static struct hda_amp_list vt1709_loopbacks[] = { 1323 { 0x18, HDA_INPUT, 1 }, 1324 { 0x18, HDA_INPUT, 2 }, 1325 { 0x18, HDA_INPUT, 3 }, 1326 { 0x18, HDA_INPUT, 4 }, 1327 { } /* end */ 1328 }; 1329 #endif 1330 1331 static int patch_vt1709_10ch(struct hda_codec *codec) 1332 { 1333 struct via_spec *spec; 1334 int err; 1335 1336 /* create a codec specific record */ 1337 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1338 if (spec == NULL) 1339 return -ENOMEM; 1340 1341 codec->spec = spec; 1342 1343 err = vt1709_parse_auto_config(codec); 1344 if (err < 0) { 1345 via_free(codec); 1346 return err; 1347 } else if (!err) { 1348 printk(KERN_INFO "hda_codec: Cannot set up configuration. " 1349 "Using genenic mode...\n"); 1350 } 1351 1352 spec->init_verbs = vt1709_10ch_volume_init_verbs; 1353 1354 spec->stream_name_analog = "VT1709 Analog"; 1355 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback; 1356 spec->stream_analog_capture = &vt1709_pcm_analog_capture; 1357 1358 spec->stream_name_digital = "VT1709 Digital"; 1359 spec->stream_digital_playback = &vt1709_pcm_digital_playback; 1360 spec->stream_digital_capture = &vt1709_pcm_digital_capture; 1361 1362 1363 if (!spec->adc_nids && spec->input_mux) { 1364 spec->adc_nids = vt1709_adc_nids; 1365 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); 1366 spec->mixers[spec->num_mixers] = vt1709_capture_mixer; 1367 spec->num_mixers++; 1368 } 1369 1370 codec->patch_ops = via_patch_ops; 1371 1372 codec->patch_ops.init = via_auto_init; 1373 #ifdef CONFIG_SND_HDA_POWER_SAVE 1374 spec->loopback.amplist = vt1709_loopbacks; 1375 #endif 1376 1377 return 0; 1378 } 1379 /* 1380 * generic initialization of ADC, input mixers and output mixers 1381 */ 1382 static struct hda_verb vt1709_6ch_volume_init_verbs[] = { 1383 /* 1384 * Unmute ADC0-2 and set the default input to mic-in 1385 */ 1386 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1387 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1388 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1389 1390 1391 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1392 * mixer widget 1393 */ 1394 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 1395 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1397 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 1398 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 1399 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 1400 1401 /* 1402 * Set up output selector (0x1a, 0x1b, 0x29) 1403 */ 1404 /* set vol=0 to output mixers */ 1405 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1406 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1407 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1408 1409 /* 1410 * Unmute PW3 and PW4 1411 */ 1412 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1413 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1414 1415 /* Set input of PW4 as MW0 */ 1416 {0x20, AC_VERB_SET_CONNECT_SEL, 0}, 1417 /* PW9 Output enable */ 1418 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1419 { } 1420 }; 1421 1422 static int patch_vt1709_6ch(struct hda_codec *codec) 1423 { 1424 struct via_spec *spec; 1425 int err; 1426 1427 /* create a codec specific record */ 1428 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1429 if (spec == NULL) 1430 return -ENOMEM; 1431 1432 codec->spec = spec; 1433 1434 err = vt1709_parse_auto_config(codec); 1435 if (err < 0) { 1436 via_free(codec); 1437 return err; 1438 } else if (!err) { 1439 printk(KERN_INFO "hda_codec: Cannot set up configuration. " 1440 "Using genenic mode...\n"); 1441 } 1442 1443 spec->init_verbs = vt1709_6ch_volume_init_verbs; 1444 1445 spec->stream_name_analog = "VT1709 Analog"; 1446 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback; 1447 spec->stream_analog_capture = &vt1709_pcm_analog_capture; 1448 1449 spec->stream_name_digital = "VT1709 Digital"; 1450 spec->stream_digital_playback = &vt1709_pcm_digital_playback; 1451 spec->stream_digital_capture = &vt1709_pcm_digital_capture; 1452 1453 1454 if (!spec->adc_nids && spec->input_mux) { 1455 spec->adc_nids = vt1709_adc_nids; 1456 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); 1457 spec->mixers[spec->num_mixers] = vt1709_capture_mixer; 1458 spec->num_mixers++; 1459 } 1460 1461 codec->patch_ops = via_patch_ops; 1462 1463 codec->patch_ops.init = via_auto_init; 1464 #ifdef CONFIG_SND_HDA_POWER_SAVE 1465 spec->loopback.amplist = vt1709_loopbacks; 1466 #endif 1467 return 0; 1468 } 1469 1470 /* capture mixer elements */ 1471 static struct snd_kcontrol_new vt1708B_capture_mixer[] = { 1472 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 1473 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 1474 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 1475 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT), 1476 { 1477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1478 /* The multiple "Capture Source" controls confuse alsamixer 1479 * So call somewhat different.. 1480 */ 1481 /* .name = "Capture Source", */ 1482 .name = "Input Source", 1483 .count = 1, 1484 .info = via_mux_enum_info, 1485 .get = via_mux_enum_get, 1486 .put = via_mux_enum_put, 1487 }, 1488 { } /* end */ 1489 }; 1490 /* 1491 * generic initialization of ADC, input mixers and output mixers 1492 */ 1493 static struct hda_verb vt1708B_8ch_volume_init_verbs[] = { 1494 /* 1495 * Unmute ADC0-1 and set the default input to mic-in 1496 */ 1497 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1499 1500 1501 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1502 * mixer widget 1503 */ 1504 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 1505 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1506 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1507 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 1508 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 1509 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 1510 1511 /* 1512 * Set up output mixers 1513 */ 1514 /* set vol=0 to output mixers */ 1515 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1516 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1517 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1518 1519 /* Setup default input to PW4 */ 1520 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, 1521 /* PW9 Output enable */ 1522 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1523 /* PW10 Input enable */ 1524 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 1525 { } 1526 }; 1527 1528 static struct hda_verb vt1708B_4ch_volume_init_verbs[] = { 1529 /* 1530 * Unmute ADC0-1 and set the default input to mic-in 1531 */ 1532 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1534 1535 1536 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1537 * mixer widget 1538 */ 1539 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 1540 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1541 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1542 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 1543 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 1544 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 1545 1546 /* 1547 * Set up output mixers 1548 */ 1549 /* set vol=0 to output mixers */ 1550 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1551 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1552 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1553 1554 /* Setup default input of PW4 to MW0 */ 1555 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0}, 1556 /* PW9 Output enable */ 1557 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1558 /* PW10 Input enable */ 1559 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 1560 { } 1561 }; 1562 1563 static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { 1564 .substreams = 1, 1565 .channels_min = 2, 1566 .channels_max = 8, 1567 .nid = 0x10, /* NID to query formats and rates */ 1568 .ops = { 1569 .open = via_playback_pcm_open, 1570 .prepare = via_playback_pcm_prepare, 1571 .cleanup = via_playback_pcm_cleanup 1572 }, 1573 }; 1574 1575 static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { 1576 .substreams = 1, 1577 .channels_min = 2, 1578 .channels_max = 4, 1579 .nid = 0x10, /* NID to query formats and rates */ 1580 .ops = { 1581 .open = via_playback_pcm_open, 1582 .prepare = via_playback_pcm_prepare, 1583 .cleanup = via_playback_pcm_cleanup 1584 }, 1585 }; 1586 1587 static struct hda_pcm_stream vt1708B_pcm_analog_capture = { 1588 .substreams = 2, 1589 .channels_min = 2, 1590 .channels_max = 2, 1591 .nid = 0x13, /* NID to query formats and rates */ 1592 .ops = { 1593 .prepare = via_capture_pcm_prepare, 1594 .cleanup = via_capture_pcm_cleanup 1595 }, 1596 }; 1597 1598 static struct hda_pcm_stream vt1708B_pcm_digital_playback = { 1599 .substreams = 1, 1600 .channels_min = 2, 1601 .channels_max = 2, 1602 /* NID is set in via_build_pcms */ 1603 .ops = { 1604 .open = via_dig_playback_pcm_open, 1605 .close = via_dig_playback_pcm_close, 1606 .prepare = via_dig_playback_pcm_prepare 1607 }, 1608 }; 1609 1610 static struct hda_pcm_stream vt1708B_pcm_digital_capture = { 1611 .substreams = 1, 1612 .channels_min = 2, 1613 .channels_max = 2, 1614 }; 1615 1616 /* fill in the dac_nids table from the parsed pin configuration */ 1617 static int vt1708B_auto_fill_dac_nids(struct via_spec *spec, 1618 const struct auto_pin_cfg *cfg) 1619 { 1620 int i; 1621 hda_nid_t nid; 1622 1623 spec->multiout.num_dacs = cfg->line_outs; 1624 1625 spec->multiout.dac_nids = spec->private_dac_nids; 1626 1627 for (i = 0; i < 4; i++) { 1628 nid = cfg->line_out_pins[i]; 1629 if (nid) { 1630 /* config dac list */ 1631 switch (i) { 1632 case AUTO_SEQ_FRONT: 1633 spec->multiout.dac_nids[i] = 0x10; 1634 break; 1635 case AUTO_SEQ_CENLFE: 1636 spec->multiout.dac_nids[i] = 0x24; 1637 break; 1638 case AUTO_SEQ_SURROUND: 1639 spec->multiout.dac_nids[i] = 0x25; 1640 break; 1641 case AUTO_SEQ_SIDE: 1642 spec->multiout.dac_nids[i] = 0x11; 1643 break; 1644 } 1645 } 1646 } 1647 1648 return 0; 1649 } 1650 1651 /* add playback controls from the parsed DAC table */ 1652 static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec, 1653 const struct auto_pin_cfg *cfg) 1654 { 1655 char name[32]; 1656 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 1657 hda_nid_t nid_vols[] = {0x16, 0x27, 0x26, 0x18}; 1658 hda_nid_t nid, nid_vol = 0; 1659 int i, err; 1660 1661 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 1662 nid = cfg->line_out_pins[i]; 1663 1664 if (!nid) 1665 continue; 1666 1667 nid_vol = nid_vols[i]; 1668 1669 if (i == AUTO_SEQ_CENLFE) { 1670 /* Center/LFE */ 1671 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1672 "Center Playback Volume", 1673 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 1674 HDA_OUTPUT)); 1675 if (err < 0) 1676 return err; 1677 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1678 "LFE Playback Volume", 1679 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 1680 HDA_OUTPUT)); 1681 if (err < 0) 1682 return err; 1683 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1684 "Center Playback Switch", 1685 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 1686 HDA_OUTPUT)); 1687 if (err < 0) 1688 return err; 1689 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1690 "LFE Playback Switch", 1691 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 1692 HDA_OUTPUT)); 1693 if (err < 0) 1694 return err; 1695 } else if (i == AUTO_SEQ_FRONT) { 1696 /* add control to mixer index 0 */ 1697 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1698 "Master Front Playback Volume", 1699 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1700 HDA_INPUT)); 1701 if (err < 0) 1702 return err; 1703 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1704 "Master Front Playback Switch", 1705 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1706 HDA_INPUT)); 1707 if (err < 0) 1708 return err; 1709 1710 /* add control to PW3 */ 1711 sprintf(name, "%s Playback Volume", chname[i]); 1712 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1713 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1714 HDA_OUTPUT)); 1715 if (err < 0) 1716 return err; 1717 sprintf(name, "%s Playback Switch", chname[i]); 1718 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1719 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1720 HDA_OUTPUT)); 1721 if (err < 0) 1722 return err; 1723 } else { 1724 sprintf(name, "%s Playback Volume", chname[i]); 1725 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1726 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1727 HDA_OUTPUT)); 1728 if (err < 0) 1729 return err; 1730 sprintf(name, "%s Playback Switch", chname[i]); 1731 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1732 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1733 HDA_OUTPUT)); 1734 if (err < 0) 1735 return err; 1736 } 1737 } 1738 1739 return 0; 1740 } 1741 1742 static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 1743 { 1744 int err; 1745 1746 if (!pin) 1747 return 0; 1748 1749 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */ 1750 1751 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1752 "Headphone Playback Volume", 1753 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 1754 if (err < 0) 1755 return err; 1756 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1757 "Headphone Playback Switch", 1758 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 1759 if (err < 0) 1760 return err; 1761 1762 return 0; 1763 } 1764 1765 /* create playback/capture controls for input pins */ 1766 static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec, 1767 const struct auto_pin_cfg *cfg) 1768 { 1769 static char *labels[] = { 1770 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 1771 }; 1772 struct hda_input_mux *imux = &spec->private_imux; 1773 int i, err, idx = 0; 1774 1775 /* for internal loopback recording select */ 1776 imux->items[imux->num_items].label = "Stereo Mixer"; 1777 imux->items[imux->num_items].index = idx; 1778 imux->num_items++; 1779 1780 for (i = 0; i < AUTO_PIN_LAST; i++) { 1781 if (!cfg->input_pins[i]) 1782 continue; 1783 1784 switch (cfg->input_pins[i]) { 1785 case 0x1a: /* Mic */ 1786 idx = 2; 1787 break; 1788 1789 case 0x1b: /* Line In */ 1790 idx = 3; 1791 break; 1792 1793 case 0x1e: /* Front Mic */ 1794 idx = 4; 1795 break; 1796 1797 case 0x1f: /* CD */ 1798 idx = 1; 1799 break; 1800 } 1801 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 1802 idx, 0x16); 1803 if (err < 0) 1804 return err; 1805 imux->items[imux->num_items].label = labels[i]; 1806 imux->items[imux->num_items].index = idx; 1807 imux->num_items++; 1808 } 1809 return 0; 1810 } 1811 1812 static int vt1708B_parse_auto_config(struct hda_codec *codec) 1813 { 1814 struct via_spec *spec = codec->spec; 1815 int err; 1816 1817 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 1818 if (err < 0) 1819 return err; 1820 err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg); 1821 if (err < 0) 1822 return err; 1823 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 1824 return 0; /* can't find valid BIOS pin config */ 1825 1826 err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg); 1827 if (err < 0) 1828 return err; 1829 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 1830 if (err < 0) 1831 return err; 1832 err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg); 1833 if (err < 0) 1834 return err; 1835 1836 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 1837 1838 if (spec->autocfg.dig_out_pin) 1839 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID; 1840 if (spec->autocfg.dig_in_pin) 1841 spec->dig_in_nid = VT1708B_DIGIN_NID; 1842 1843 if (spec->kctl_alloc) 1844 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1845 1846 spec->input_mux = &spec->private_imux; 1847 1848 return 1; 1849 } 1850 1851 #ifdef CONFIG_SND_HDA_POWER_SAVE 1852 static struct hda_amp_list vt1708B_loopbacks[] = { 1853 { 0x16, HDA_INPUT, 1 }, 1854 { 0x16, HDA_INPUT, 2 }, 1855 { 0x16, HDA_INPUT, 3 }, 1856 { 0x16, HDA_INPUT, 4 }, 1857 { } /* end */ 1858 }; 1859 #endif 1860 1861 static int patch_vt1708B_8ch(struct hda_codec *codec) 1862 { 1863 struct via_spec *spec; 1864 int err; 1865 1866 /* create a codec specific record */ 1867 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1868 if (spec == NULL) 1869 return -ENOMEM; 1870 1871 codec->spec = spec; 1872 1873 /* automatic parse from the BIOS config */ 1874 err = vt1708B_parse_auto_config(codec); 1875 if (err < 0) { 1876 via_free(codec); 1877 return err; 1878 } else if (!err) { 1879 printk(KERN_INFO "hda_codec: Cannot set up configuration " 1880 "from BIOS. Using genenic mode...\n"); 1881 } 1882 1883 spec->init_verbs = vt1708B_8ch_volume_init_verbs; 1884 1885 spec->stream_name_analog = "VT1708B Analog"; 1886 spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback; 1887 spec->stream_analog_capture = &vt1708B_pcm_analog_capture; 1888 1889 spec->stream_name_digital = "VT1708B Digital"; 1890 spec->stream_digital_playback = &vt1708B_pcm_digital_playback; 1891 spec->stream_digital_capture = &vt1708B_pcm_digital_capture; 1892 1893 if (!spec->adc_nids && spec->input_mux) { 1894 spec->adc_nids = vt1708B_adc_nids; 1895 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); 1896 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; 1897 spec->num_mixers++; 1898 } 1899 1900 codec->patch_ops = via_patch_ops; 1901 1902 codec->patch_ops.init = via_auto_init; 1903 #ifdef CONFIG_SND_HDA_POWER_SAVE 1904 spec->loopback.amplist = vt1708B_loopbacks; 1905 #endif 1906 1907 return 0; 1908 } 1909 1910 static int patch_vt1708B_4ch(struct hda_codec *codec) 1911 { 1912 struct via_spec *spec; 1913 int err; 1914 1915 /* create a codec specific record */ 1916 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1917 if (spec == NULL) 1918 return -ENOMEM; 1919 1920 codec->spec = spec; 1921 1922 /* automatic parse from the BIOS config */ 1923 err = vt1708B_parse_auto_config(codec); 1924 if (err < 0) { 1925 via_free(codec); 1926 return err; 1927 } else if (!err) { 1928 printk(KERN_INFO "hda_codec: Cannot set up configuration " 1929 "from BIOS. Using genenic mode...\n"); 1930 } 1931 1932 spec->init_verbs = vt1708B_4ch_volume_init_verbs; 1933 1934 spec->stream_name_analog = "VT1708B Analog"; 1935 spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback; 1936 spec->stream_analog_capture = &vt1708B_pcm_analog_capture; 1937 1938 spec->stream_name_digital = "VT1708B Digital"; 1939 spec->stream_digital_playback = &vt1708B_pcm_digital_playback; 1940 spec->stream_digital_capture = &vt1708B_pcm_digital_capture; 1941 1942 if (!spec->adc_nids && spec->input_mux) { 1943 spec->adc_nids = vt1708B_adc_nids; 1944 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); 1945 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; 1946 spec->num_mixers++; 1947 } 1948 1949 codec->patch_ops = via_patch_ops; 1950 1951 codec->patch_ops.init = via_auto_init; 1952 #ifdef CONFIG_SND_HDA_POWER_SAVE 1953 spec->loopback.amplist = vt1708B_loopbacks; 1954 #endif 1955 1956 return 0; 1957 } 1958 1959 /* 1960 * patch entries 1961 */ 1962 struct hda_codec_preset snd_hda_preset_via[] = { 1963 { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708}, 1964 { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708}, 1965 { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708}, 1966 { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708}, 1967 { .id = 0x1106E710, .name = "VIA VT1709 10-Ch", 1968 .patch = patch_vt1709_10ch}, 1969 { .id = 0x1106E711, .name = "VIA VT1709 10-Ch", 1970 .patch = patch_vt1709_10ch}, 1971 { .id = 0x1106E712, .name = "VIA VT1709 10-Ch", 1972 .patch = patch_vt1709_10ch}, 1973 { .id = 0x1106E713, .name = "VIA VT1709 10-Ch", 1974 .patch = patch_vt1709_10ch}, 1975 { .id = 0x1106E714, .name = "VIA VT1709 6-Ch", 1976 .patch = patch_vt1709_6ch}, 1977 { .id = 0x1106E715, .name = "VIA VT1709 6-Ch", 1978 .patch = patch_vt1709_6ch}, 1979 { .id = 0x1106E716, .name = "VIA VT1709 6-Ch", 1980 .patch = patch_vt1709_6ch}, 1981 { .id = 0x1106E717, .name = "VIA VT1709 6-Ch", 1982 .patch = patch_vt1709_6ch}, 1983 { .id = 0x1106E720, .name = "VIA VT1708B 8-Ch", 1984 .patch = patch_vt1708B_8ch}, 1985 { .id = 0x1106E721, .name = "VIA VT1708B 8-Ch", 1986 .patch = patch_vt1708B_8ch}, 1987 { .id = 0x1106E722, .name = "VIA VT1708B 8-Ch", 1988 .patch = patch_vt1708B_8ch}, 1989 { .id = 0x1106E723, .name = "VIA VT1708B 8-Ch", 1990 .patch = patch_vt1708B_8ch}, 1991 { .id = 0x1106E724, .name = "VIA VT1708B 4-Ch", 1992 .patch = patch_vt1708B_4ch}, 1993 { .id = 0x1106E725, .name = "VIA VT1708B 4-Ch", 1994 .patch = patch_vt1708B_4ch}, 1995 { .id = 0x1106E726, .name = "VIA VT1708B 4-Ch", 1996 .patch = patch_vt1708B_4ch}, 1997 { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch", 1998 .patch = patch_vt1708B_4ch}, 1999 {} /* terminator */ 2000 }; 2001