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 /* */ 31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 32 33 34 #include <sound/driver.h> 35 #include <linux/init.h> 36 #include <linux/delay.h> 37 #include <linux/slab.h> 38 #include <sound/core.h> 39 #include "hda_codec.h" 40 #include "hda_local.h" 41 42 43 /* amp values */ 44 #define AMP_VAL_IDX_SHIFT 19 45 #define AMP_VAL_IDX_MASK (0x0f<<19) 46 47 #define NUM_CONTROL_ALLOC 32 48 #define NUM_VERB_ALLOC 32 49 50 /* Pin Widget NID */ 51 #define VT1708_HP_NID 0x13 52 #define VT1708_DIGOUT_NID 0x14 53 #define VT1708_DIGIN_NID 0x16 54 55 #define VT1709_HP_DAC_NID 0x28 56 #define VT1709_DIGOUT_NID 0x13 57 #define VT1709_DIGIN_NID 0x17 58 59 #define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b) 60 #define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713) 61 #define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717) 62 63 64 enum { 65 VIA_CTL_WIDGET_VOL, 66 VIA_CTL_WIDGET_MUTE, 67 }; 68 69 enum { 70 AUTO_SEQ_FRONT, 71 AUTO_SEQ_SURROUND, 72 AUTO_SEQ_CENLFE, 73 AUTO_SEQ_SIDE 74 }; 75 76 static struct snd_kcontrol_new vt1708_control_templates[] = { 77 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 78 HDA_CODEC_MUTE(NULL, 0, 0, 0), 79 }; 80 81 82 struct via_spec { 83 /* codec parameterization */ 84 struct snd_kcontrol_new *mixers[3]; 85 unsigned int num_mixers; 86 87 struct hda_verb *init_verbs; 88 89 char *stream_name_analog; 90 struct hda_pcm_stream *stream_analog_playback; 91 struct hda_pcm_stream *stream_analog_capture; 92 93 char *stream_name_digital; 94 struct hda_pcm_stream *stream_digital_playback; 95 struct hda_pcm_stream *stream_digital_capture; 96 97 /* playback */ 98 struct hda_multi_out multiout; 99 100 /* capture */ 101 unsigned int num_adc_nids; 102 hda_nid_t *adc_nids; 103 hda_nid_t dig_in_nid; 104 105 /* capture source */ 106 const struct hda_input_mux *input_mux; 107 unsigned int cur_mux[3]; 108 109 /* PCM information */ 110 struct hda_pcm pcm_rec[2]; 111 112 /* dynamic controls, init_verbs and input_mux */ 113 struct auto_pin_cfg autocfg; 114 unsigned int num_kctl_alloc, num_kctl_used; 115 struct snd_kcontrol_new *kctl_alloc; 116 struct hda_input_mux private_imux; 117 hda_nid_t private_dac_nids[4]; 118 119 #ifdef CONFIG_SND_HDA_POWER_SAVE 120 struct hda_loopback_check loopback; 121 #endif 122 }; 123 124 static hda_nid_t vt1708_adc_nids[2] = { 125 /* ADC1-2 */ 126 0x15, 0x27 127 }; 128 129 static hda_nid_t vt1709_adc_nids[3] = { 130 /* ADC1-2 */ 131 0x14, 0x15, 0x16 132 }; 133 134 /* add dynamic controls */ 135 static int via_add_control(struct via_spec *spec, int type, const char *name, 136 unsigned long val) 137 { 138 struct snd_kcontrol_new *knew; 139 140 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 141 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 142 143 /* array + terminator */ 144 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); 145 if (!knew) 146 return -ENOMEM; 147 if (spec->kctl_alloc) { 148 memcpy(knew, spec->kctl_alloc, 149 sizeof(*knew) * spec->num_kctl_alloc); 150 kfree(spec->kctl_alloc); 151 } 152 spec->kctl_alloc = knew; 153 spec->num_kctl_alloc = num; 154 } 155 156 knew = &spec->kctl_alloc[spec->num_kctl_used]; 157 *knew = vt1708_control_templates[type]; 158 knew->name = kstrdup(name, GFP_KERNEL); 159 160 if (!knew->name) 161 return -ENOMEM; 162 knew->private_value = val; 163 spec->num_kctl_used++; 164 return 0; 165 } 166 167 /* create input playback/capture controls for the given pin */ 168 static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin, 169 const char *ctlname, int idx, int mix_nid) 170 { 171 char name[32]; 172 int err; 173 174 sprintf(name, "%s Playback Volume", ctlname); 175 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 176 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 177 if (err < 0) 178 return err; 179 sprintf(name, "%s Playback Switch", ctlname); 180 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 181 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 182 if (err < 0) 183 return err; 184 return 0; 185 } 186 187 static void via_auto_set_output_and_unmute(struct hda_codec *codec, 188 hda_nid_t nid, int pin_type, 189 int dac_idx) 190 { 191 /* set as output */ 192 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 193 pin_type); 194 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 195 AMP_OUT_UNMUTE); 196 } 197 198 199 static void via_auto_init_multi_out(struct hda_codec *codec) 200 { 201 struct via_spec *spec = codec->spec; 202 int i; 203 204 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 205 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 206 if (nid) 207 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 208 } 209 } 210 211 static void via_auto_init_hp_out(struct hda_codec *codec) 212 { 213 struct via_spec *spec = codec->spec; 214 hda_nid_t pin; 215 216 pin = spec->autocfg.hp_pins[0]; 217 if (pin) /* connect to front */ 218 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 219 } 220 221 static void via_auto_init_analog_input(struct hda_codec *codec) 222 { 223 struct via_spec *spec = codec->spec; 224 int i; 225 226 for (i = 0; i < AUTO_PIN_LAST; i++) { 227 hda_nid_t nid = spec->autocfg.input_pins[i]; 228 229 snd_hda_codec_write(codec, nid, 0, 230 AC_VERB_SET_PIN_WIDGET_CONTROL, 231 (i <= AUTO_PIN_FRONT_MIC ? 232 PIN_VREF50 : PIN_IN)); 233 234 } 235 } 236 /* 237 * input MUX handling 238 */ 239 static int via_mux_enum_info(struct snd_kcontrol *kcontrol, 240 struct snd_ctl_elem_info *uinfo) 241 { 242 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 243 struct via_spec *spec = codec->spec; 244 return snd_hda_input_mux_info(spec->input_mux, uinfo); 245 } 246 247 static int via_mux_enum_get(struct snd_kcontrol *kcontrol, 248 struct snd_ctl_elem_value *ucontrol) 249 { 250 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 251 struct via_spec *spec = codec->spec; 252 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 253 254 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 255 return 0; 256 } 257 258 static int via_mux_enum_put(struct snd_kcontrol *kcontrol, 259 struct snd_ctl_elem_value *ucontrol) 260 { 261 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 262 struct via_spec *spec = codec->spec; 263 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 264 unsigned int vendor_id = codec->vendor_id; 265 266 /* AIW0 lydia 060801 add for correct sw0 input select */ 267 if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0)) 268 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 269 0x18, &spec->cur_mux[adc_idx]); 270 else if ((IS_VT1709_10CH_VENDORID(vendor_id) || 271 IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0) ) 272 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 273 0x19, &spec->cur_mux[adc_idx]); 274 else 275 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 276 spec->adc_nids[adc_idx], 277 &spec->cur_mux[adc_idx]); 278 } 279 280 /* capture mixer elements */ 281 static struct snd_kcontrol_new vt1708_capture_mixer[] = { 282 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 283 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT), 284 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT), 285 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT), 286 { 287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 288 /* The multiple "Capture Source" controls confuse alsamixer 289 * So call somewhat different.. 290 * FIXME: the controls appear in the "playback" view! 291 */ 292 /* .name = "Capture Source", */ 293 .name = "Input Source", 294 .count = 1, 295 .info = via_mux_enum_info, 296 .get = via_mux_enum_get, 297 .put = via_mux_enum_put, 298 }, 299 { } /* end */ 300 }; 301 /* 302 * generic initialization of ADC, input mixers and output mixers 303 */ 304 static struct hda_verb vt1708_volume_init_verbs[] = { 305 /* 306 * Unmute ADC0-1 and set the default input to mic-in 307 */ 308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 309 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 310 311 312 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 313 * mixer widget 314 */ 315 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 316 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* master */ 317 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 318 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 319 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 320 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 321 322 /* 323 * Set up output mixers (0x19 - 0x1b) 324 */ 325 /* set vol=0 to output mixers */ 326 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 327 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 328 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 329 330 /* Setup default input to PW4 */ 331 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1}, 332 /* Set mic as default input of sw0 */ 333 {0x18, AC_VERB_SET_CONNECT_SEL, 0x2}, 334 /* PW9 Output enable */ 335 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 336 }; 337 338 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo, 339 struct hda_codec *codec, 340 struct snd_pcm_substream *substream) 341 { 342 struct via_spec *spec = codec->spec; 343 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); 344 } 345 346 static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 347 struct hda_codec *codec, 348 unsigned int stream_tag, 349 unsigned int format, 350 struct snd_pcm_substream *substream) 351 { 352 struct via_spec *spec = codec->spec; 353 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 354 stream_tag, format, substream); 355 } 356 357 static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 358 struct hda_codec *codec, 359 struct snd_pcm_substream *substream) 360 { 361 struct via_spec *spec = codec->spec; 362 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 363 } 364 365 /* 366 * Digital out 367 */ 368 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 369 struct hda_codec *codec, 370 struct snd_pcm_substream *substream) 371 { 372 struct via_spec *spec = codec->spec; 373 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 374 } 375 376 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 377 struct hda_codec *codec, 378 struct snd_pcm_substream *substream) 379 { 380 struct via_spec *spec = codec->spec; 381 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 382 } 383 384 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 385 struct hda_codec *codec, 386 unsigned int stream_tag, 387 unsigned int format, 388 struct snd_pcm_substream *substream) 389 { 390 struct via_spec *spec = codec->spec; 391 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 392 stream_tag, format, substream); 393 } 394 395 /* 396 * Analog capture 397 */ 398 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 399 struct hda_codec *codec, 400 unsigned int stream_tag, 401 unsigned int format, 402 struct snd_pcm_substream *substream) 403 { 404 struct via_spec *spec = codec->spec; 405 406 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 407 stream_tag, 0, format); 408 return 0; 409 } 410 411 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 412 struct hda_codec *codec, 413 struct snd_pcm_substream *substream) 414 { 415 struct via_spec *spec = codec->spec; 416 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 417 0, 0, 0); 418 return 0; 419 } 420 421 static struct hda_pcm_stream vt1708_pcm_analog_playback = { 422 .substreams = 1, 423 .channels_min = 2, 424 .channels_max = 8, 425 .nid = 0x10, /* NID to query formats and rates */ 426 .ops = { 427 .open = via_playback_pcm_open, 428 .prepare = via_playback_pcm_prepare, 429 .cleanup = via_playback_pcm_cleanup 430 }, 431 }; 432 433 static struct hda_pcm_stream vt1708_pcm_analog_capture = { 434 .substreams = 2, 435 .channels_min = 2, 436 .channels_max = 2, 437 .nid = 0x15, /* NID to query formats and rates */ 438 .ops = { 439 .prepare = via_capture_pcm_prepare, 440 .cleanup = via_capture_pcm_cleanup 441 }, 442 }; 443 444 static struct hda_pcm_stream vt1708_pcm_digital_playback = { 445 .substreams = 1, 446 .channels_min = 2, 447 .channels_max = 2, 448 /* NID is set in via_build_pcms */ 449 .ops = { 450 .open = via_dig_playback_pcm_open, 451 .close = via_dig_playback_pcm_close, 452 .prepare = via_dig_playback_pcm_prepare 453 }, 454 }; 455 456 static struct hda_pcm_stream vt1708_pcm_digital_capture = { 457 .substreams = 1, 458 .channels_min = 2, 459 .channels_max = 2, 460 }; 461 462 static int via_build_controls(struct hda_codec *codec) 463 { 464 struct via_spec *spec = codec->spec; 465 int err; 466 int i; 467 468 for (i = 0; i < spec->num_mixers; i++) { 469 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 470 if (err < 0) 471 return err; 472 } 473 474 if (spec->multiout.dig_out_nid) { 475 err = snd_hda_create_spdif_out_ctls(codec, 476 spec->multiout.dig_out_nid); 477 if (err < 0) 478 return err; 479 } 480 if (spec->dig_in_nid) { 481 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 482 if (err < 0) 483 return err; 484 } 485 return 0; 486 } 487 488 static int via_build_pcms(struct hda_codec *codec) 489 { 490 struct via_spec *spec = codec->spec; 491 struct hda_pcm *info = spec->pcm_rec; 492 493 codec->num_pcms = 1; 494 codec->pcm_info = info; 495 496 info->name = spec->stream_name_analog; 497 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 498 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 499 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 500 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 501 502 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 503 spec->multiout.max_channels; 504 505 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 506 codec->num_pcms++; 507 info++; 508 info->name = spec->stream_name_digital; 509 if (spec->multiout.dig_out_nid) { 510 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 511 *(spec->stream_digital_playback); 512 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 513 spec->multiout.dig_out_nid; 514 } 515 if (spec->dig_in_nid) { 516 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 517 *(spec->stream_digital_capture); 518 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 519 spec->dig_in_nid; 520 } 521 } 522 523 return 0; 524 } 525 526 static void via_free(struct hda_codec *codec) 527 { 528 struct via_spec *spec = codec->spec; 529 unsigned int i; 530 531 if (!spec) 532 return; 533 534 if (spec->kctl_alloc) { 535 for (i = 0; i < spec->num_kctl_used; i++) 536 kfree(spec->kctl_alloc[i].name); 537 kfree(spec->kctl_alloc); 538 } 539 540 kfree(codec->spec); 541 } 542 543 static int via_init(struct hda_codec *codec) 544 { 545 struct via_spec *spec = codec->spec; 546 snd_hda_sequence_write(codec, spec->init_verbs); 547 return 0; 548 } 549 550 #ifdef CONFIG_SND_HDA_POWER_SAVE 551 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) 552 { 553 struct via_spec *spec = codec->spec; 554 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 555 } 556 #endif 557 558 /* 559 */ 560 static struct hda_codec_ops via_patch_ops = { 561 .build_controls = via_build_controls, 562 .build_pcms = via_build_pcms, 563 .init = via_init, 564 .free = via_free, 565 #ifdef CONFIG_SND_HDA_POWER_SAVE 566 .check_power_status = via_check_power_status, 567 #endif 568 }; 569 570 /* fill in the dac_nids table from the parsed pin configuration */ 571 static int vt1708_auto_fill_dac_nids(struct via_spec *spec, 572 const struct auto_pin_cfg *cfg) 573 { 574 int i; 575 hda_nid_t nid; 576 577 spec->multiout.num_dacs = cfg->line_outs; 578 579 spec->multiout.dac_nids = spec->private_dac_nids; 580 581 for(i = 0; i < 4; i++) { 582 nid = cfg->line_out_pins[i]; 583 if (nid) { 584 /* config dac list */ 585 switch (i) { 586 case AUTO_SEQ_FRONT: 587 spec->multiout.dac_nids[i] = 0x10; 588 break; 589 case AUTO_SEQ_CENLFE: 590 spec->multiout.dac_nids[i] = 0x12; 591 break; 592 case AUTO_SEQ_SURROUND: 593 spec->multiout.dac_nids[i] = 0x13; 594 break; 595 case AUTO_SEQ_SIDE: 596 spec->multiout.dac_nids[i] = 0x11; 597 break; 598 } 599 } 600 } 601 602 return 0; 603 } 604 605 /* add playback controls from the parsed DAC table */ 606 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, 607 const struct auto_pin_cfg *cfg) 608 { 609 char name[32]; 610 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 611 hda_nid_t nid, nid_vol = 0; 612 int i, err; 613 614 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 615 nid = cfg->line_out_pins[i]; 616 617 if (!nid) 618 continue; 619 620 if (i != AUTO_SEQ_FRONT) 621 nid_vol = 0x1b - i + 1; 622 623 if (i == AUTO_SEQ_CENLFE) { 624 /* Center/LFE */ 625 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 626 "Center Playback Volume", 627 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT)); 628 if (err < 0) 629 return err; 630 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 631 "LFE Playback Volume", 632 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT)); 633 if (err < 0) 634 return err; 635 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 636 "Center Playback Switch", 637 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT)); 638 if (err < 0) 639 return err; 640 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 641 "LFE Playback Switch", 642 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT)); 643 if (err < 0) 644 return err; 645 } else if (i == AUTO_SEQ_FRONT){ 646 /* add control to mixer index 0 */ 647 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 648 "Master Front Playback Volume", 649 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT)); 650 if (err < 0) 651 return err; 652 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 653 "Master Front Playback Switch", 654 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT)); 655 if (err < 0) 656 return err; 657 658 /* add control to PW3 */ 659 sprintf(name, "%s Playback Volume", chname[i]); 660 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 661 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 662 if (err < 0) 663 return err; 664 sprintf(name, "%s Playback Switch", chname[i]); 665 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 666 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 667 if (err < 0) 668 return err; 669 } else { 670 sprintf(name, "%s Playback Volume", chname[i]); 671 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 672 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT)); 673 if (err < 0) 674 return err; 675 sprintf(name, "%s Playback Switch", chname[i]); 676 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 677 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT)); 678 if (err < 0) 679 return err; 680 } 681 } 682 683 return 0; 684 } 685 686 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 687 { 688 int err; 689 690 if (!pin) 691 return 0; 692 693 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */ 694 695 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 696 "Headphone Playback Volume", 697 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 698 if (err < 0) 699 return err; 700 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 701 "Headphone Playback Switch", 702 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 703 if (err < 0) 704 return err; 705 706 return 0; 707 } 708 709 /* create playback/capture controls for input pins */ 710 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec, 711 const struct auto_pin_cfg *cfg) 712 { 713 static char *labels[] = { 714 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 715 }; 716 struct hda_input_mux *imux = &spec->private_imux; 717 int i, err, idx = 0; 718 719 /* for internal loopback recording select */ 720 imux->items[imux->num_items].label = "Stereo Mixer"; 721 imux->items[imux->num_items].index = idx; 722 imux->num_items++; 723 724 for (i = 0; i < AUTO_PIN_LAST; i++) { 725 if (!cfg->input_pins[i]) 726 continue; 727 728 switch (cfg->input_pins[i]) { 729 case 0x1d: /* Mic */ 730 idx = 2; 731 break; 732 733 case 0x1e: /* Line In */ 734 idx = 3; 735 break; 736 737 case 0x21: /* Front Mic */ 738 idx = 4; 739 break; 740 741 case 0x24: /* CD */ 742 idx = 1; 743 break; 744 } 745 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 746 idx, 0x17); 747 if (err < 0) 748 return err; 749 imux->items[imux->num_items].label = labels[i]; 750 imux->items[imux->num_items].index = idx; 751 imux->num_items++; 752 } 753 return 0; 754 } 755 756 #ifdef CONFIG_SND_HDA_POWER_SAVE 757 static struct hda_amp_list vt1708_loopbacks[] = { 758 { 0x17, HDA_INPUT, 1 }, 759 { 0x17, HDA_INPUT, 2 }, 760 { 0x17, HDA_INPUT, 3 }, 761 { 0x17, HDA_INPUT, 4 }, 762 { } /* end */ 763 }; 764 #endif 765 766 static int vt1708_parse_auto_config(struct hda_codec *codec) 767 { 768 struct via_spec *spec = codec->spec; 769 int err; 770 771 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 772 if (err < 0) 773 return err; 774 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg); 775 if (err < 0) 776 return err; 777 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 778 return 0; /* can't find valid BIOS pin config */ 779 780 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg); 781 if (err < 0) 782 return err; 783 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 784 if (err < 0) 785 return err; 786 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg); 787 if (err < 0) 788 return err; 789 790 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 791 792 if (spec->autocfg.dig_out_pin) 793 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; 794 if (spec->autocfg.dig_in_pin) 795 spec->dig_in_nid = VT1708_DIGIN_NID; 796 797 if (spec->kctl_alloc) 798 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 799 800 spec->init_verbs = vt1708_volume_init_verbs; 801 802 spec->input_mux = &spec->private_imux; 803 804 return 1; 805 } 806 807 /* init callback for auto-configuration model -- overriding the default init */ 808 static int via_auto_init(struct hda_codec *codec) 809 { 810 via_init(codec); 811 via_auto_init_multi_out(codec); 812 via_auto_init_hp_out(codec); 813 via_auto_init_analog_input(codec); 814 return 0; 815 } 816 817 static int patch_vt1708(struct hda_codec *codec) 818 { 819 struct via_spec *spec; 820 int err; 821 822 /* create a codec specific record */ 823 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 824 if (spec == NULL) 825 return -ENOMEM; 826 827 codec->spec = spec; 828 829 /* automatic parse from the BIOS config */ 830 err = vt1708_parse_auto_config(codec); 831 if (err < 0) { 832 via_free(codec); 833 return err; 834 } else if (!err) { 835 printk(KERN_INFO "hda_codec: Cannot set up configuration " 836 "from BIOS. Using genenic mode...\n"); 837 } 838 839 840 spec->stream_name_analog = "VT1708 Analog"; 841 spec->stream_analog_playback = &vt1708_pcm_analog_playback; 842 spec->stream_analog_capture = &vt1708_pcm_analog_capture; 843 844 spec->stream_name_digital = "VT1708 Digital"; 845 spec->stream_digital_playback = &vt1708_pcm_digital_playback; 846 spec->stream_digital_capture = &vt1708_pcm_digital_capture; 847 848 849 if (!spec->adc_nids && spec->input_mux) { 850 spec->adc_nids = vt1708_adc_nids; 851 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids); 852 spec->mixers[spec->num_mixers] = vt1708_capture_mixer; 853 spec->num_mixers++; 854 } 855 856 codec->patch_ops = via_patch_ops; 857 858 codec->patch_ops.init = via_auto_init; 859 #ifdef CONFIG_SND_HDA_POWER_SAVE 860 spec->loopback.amplist = vt1708_loopbacks; 861 #endif 862 863 return 0; 864 } 865 866 /* capture mixer elements */ 867 static struct snd_kcontrol_new vt1709_capture_mixer[] = { 868 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT), 869 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT), 870 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT), 871 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT), 872 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT), 873 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT), 874 { 875 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 876 /* The multiple "Capture Source" controls confuse alsamixer 877 * So call somewhat different.. 878 * FIXME: the controls appear in the "playback" view! 879 */ 880 /* .name = "Capture Source", */ 881 .name = "Input Source", 882 .count = 1, 883 .info = via_mux_enum_info, 884 .get = via_mux_enum_get, 885 .put = via_mux_enum_put, 886 }, 887 { } /* end */ 888 }; 889 890 /* 891 * generic initialization of ADC, input mixers and output mixers 892 */ 893 static struct hda_verb vt1709_10ch_volume_init_verbs[] = { 894 /* 895 * Unmute ADC0-2 and set the default input to mic-in 896 */ 897 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 898 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 899 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 900 901 902 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 903 * mixer widget 904 */ 905 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 906 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* unmute master */ 907 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 908 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 909 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 910 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 911 912 /* 913 * Set up output selector (0x1a, 0x1b, 0x29) 914 */ 915 /* set vol=0 to output mixers */ 916 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 917 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 918 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 919 920 /* 921 * Unmute PW3 and PW4 922 */ 923 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 924 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 925 926 /* Set input of PW4 as AOW4 */ 927 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1}, 928 /* Set mic as default input of sw0 */ 929 {0x19, AC_VERB_SET_CONNECT_SEL, 0x2}, 930 /* PW9 Output enable */ 931 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 932 { } 933 }; 934 935 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { 936 .substreams = 1, 937 .channels_min = 2, 938 .channels_max = 10, 939 .nid = 0x10, /* NID to query formats and rates */ 940 .ops = { 941 .open = via_playback_pcm_open, 942 .prepare = via_playback_pcm_prepare, 943 .cleanup = via_playback_pcm_cleanup 944 }, 945 }; 946 947 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { 948 .substreams = 1, 949 .channels_min = 2, 950 .channels_max = 6, 951 .nid = 0x10, /* NID to query formats and rates */ 952 .ops = { 953 .open = via_playback_pcm_open, 954 .prepare = via_playback_pcm_prepare, 955 .cleanup = via_playback_pcm_cleanup 956 }, 957 }; 958 959 static struct hda_pcm_stream vt1709_pcm_analog_capture = { 960 .substreams = 2, 961 .channels_min = 2, 962 .channels_max = 2, 963 .nid = 0x14, /* NID to query formats and rates */ 964 .ops = { 965 .prepare = via_capture_pcm_prepare, 966 .cleanup = via_capture_pcm_cleanup 967 }, 968 }; 969 970 static struct hda_pcm_stream vt1709_pcm_digital_playback = { 971 .substreams = 1, 972 .channels_min = 2, 973 .channels_max = 2, 974 /* NID is set in via_build_pcms */ 975 .ops = { 976 .open = via_dig_playback_pcm_open, 977 .close = via_dig_playback_pcm_close 978 }, 979 }; 980 981 static struct hda_pcm_stream vt1709_pcm_digital_capture = { 982 .substreams = 1, 983 .channels_min = 2, 984 .channels_max = 2, 985 }; 986 987 static int vt1709_auto_fill_dac_nids(struct via_spec *spec, 988 const struct auto_pin_cfg *cfg) 989 { 990 int i; 991 hda_nid_t nid; 992 993 if (cfg->line_outs == 4) /* 10 channels */ 994 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */ 995 else if (cfg->line_outs == 3) /* 6 channels */ 996 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */ 997 998 spec->multiout.dac_nids = spec->private_dac_nids; 999 1000 if (cfg->line_outs == 4) { /* 10 channels */ 1001 for (i = 0; i < cfg->line_outs; i++) { 1002 nid = cfg->line_out_pins[i]; 1003 if (nid) { 1004 /* config dac list */ 1005 switch (i) { 1006 case AUTO_SEQ_FRONT: 1007 /* AOW0 */ 1008 spec->multiout.dac_nids[i] = 0x10; 1009 break; 1010 case AUTO_SEQ_CENLFE: 1011 /* AOW2 */ 1012 spec->multiout.dac_nids[i] = 0x12; 1013 break; 1014 case AUTO_SEQ_SURROUND: 1015 /* AOW3 */ 1016 spec->multiout.dac_nids[i] = 0x27; 1017 break; 1018 case AUTO_SEQ_SIDE: 1019 /* AOW1 */ 1020 spec->multiout.dac_nids[i] = 0x11; 1021 break; 1022 default: 1023 break; 1024 } 1025 } 1026 } 1027 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ 1028 1029 } else if (cfg->line_outs == 3) { /* 6 channels */ 1030 for(i = 0; i < cfg->line_outs; i++) { 1031 nid = cfg->line_out_pins[i]; 1032 if (nid) { 1033 /* config dac list */ 1034 switch(i) { 1035 case AUTO_SEQ_FRONT: 1036 /* AOW0 */ 1037 spec->multiout.dac_nids[i] = 0x10; 1038 break; 1039 case AUTO_SEQ_CENLFE: 1040 /* AOW2 */ 1041 spec->multiout.dac_nids[i] = 0x12; 1042 break; 1043 case AUTO_SEQ_SURROUND: 1044 /* AOW1 */ 1045 spec->multiout.dac_nids[i] = 0x11; 1046 break; 1047 default: 1048 break; 1049 } 1050 } 1051 } 1052 } 1053 1054 return 0; 1055 } 1056 1057 /* add playback controls from the parsed DAC table */ 1058 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec, 1059 const struct auto_pin_cfg *cfg) 1060 { 1061 char name[32]; 1062 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 1063 hda_nid_t nid = 0; 1064 int i, err; 1065 1066 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 1067 nid = cfg->line_out_pins[i]; 1068 1069 if (!nid) 1070 continue; 1071 1072 if (i == AUTO_SEQ_CENLFE) { 1073 /* Center/LFE */ 1074 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1075 "Center Playback Volume", 1076 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT)); 1077 if (err < 0) 1078 return err; 1079 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1080 "LFE Playback Volume", 1081 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT)); 1082 if (err < 0) 1083 return err; 1084 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1085 "Center Playback Switch", 1086 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT)); 1087 if (err < 0) 1088 return err; 1089 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1090 "LFE Playback Switch", 1091 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT)); 1092 if (err < 0) 1093 return err; 1094 } else if (i == AUTO_SEQ_FRONT){ 1095 /* add control to mixer index 0 */ 1096 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1097 "Master Front Playback Volume", 1098 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT)); 1099 if (err < 0) 1100 return err; 1101 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1102 "Master Front Playback Switch", 1103 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT)); 1104 if (err < 0) 1105 return err; 1106 1107 /* add control to PW3 */ 1108 sprintf(name, "%s Playback Volume", chname[i]); 1109 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1110 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 1111 if (err < 0) 1112 return err; 1113 sprintf(name, "%s Playback Switch", chname[i]); 1114 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1115 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 1116 if (err < 0) 1117 return err; 1118 } else if (i == AUTO_SEQ_SURROUND) { 1119 sprintf(name, "%s Playback Volume", chname[i]); 1120 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1121 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT)); 1122 if (err < 0) 1123 return err; 1124 sprintf(name, "%s Playback Switch", chname[i]); 1125 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1126 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT)); 1127 if (err < 0) 1128 return err; 1129 } else if (i == AUTO_SEQ_SIDE) { 1130 sprintf(name, "%s Playback Volume", chname[i]); 1131 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1132 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT)); 1133 if (err < 0) 1134 return err; 1135 sprintf(name, "%s Playback Switch", chname[i]); 1136 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 1137 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT)); 1138 if (err < 0) 1139 return err; 1140 } 1141 } 1142 1143 return 0; 1144 } 1145 1146 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 1147 { 1148 int err; 1149 1150 if (!pin) 1151 return 0; 1152 1153 if (spec->multiout.num_dacs == 5) /* 10 channels */ 1154 spec->multiout.hp_nid = VT1709_HP_DAC_NID; 1155 else if (spec->multiout.num_dacs == 3) /* 6 channels */ 1156 spec->multiout.hp_nid = 0; 1157 1158 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1159 "Headphone Playback Volume", 1160 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 1161 if (err < 0) 1162 return err; 1163 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 1164 "Headphone Playback Switch", 1165 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 1166 if (err < 0) 1167 return err; 1168 1169 return 0; 1170 } 1171 1172 /* create playback/capture controls for input pins */ 1173 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec, 1174 const struct auto_pin_cfg *cfg) 1175 { 1176 static char *labels[] = { 1177 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 1178 }; 1179 struct hda_input_mux *imux = &spec->private_imux; 1180 int i, err, idx = 0; 1181 1182 /* for internal loopback recording select */ 1183 imux->items[imux->num_items].label = "Stereo Mixer"; 1184 imux->items[imux->num_items].index = idx; 1185 imux->num_items++; 1186 1187 for (i = 0; i < AUTO_PIN_LAST; i++) { 1188 if (!cfg->input_pins[i]) 1189 continue; 1190 1191 switch (cfg->input_pins[i]) { 1192 case 0x1d: /* Mic */ 1193 idx = 2; 1194 break; 1195 1196 case 0x1e: /* Line In */ 1197 idx = 3; 1198 break; 1199 1200 case 0x21: /* Front Mic */ 1201 idx = 4; 1202 break; 1203 1204 case 0x23: /* CD */ 1205 idx = 1; 1206 break; 1207 } 1208 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 1209 idx, 0x18); 1210 if (err < 0) 1211 return err; 1212 imux->items[imux->num_items].label = labels[i]; 1213 imux->items[imux->num_items].index = idx; 1214 imux->num_items++; 1215 } 1216 return 0; 1217 } 1218 1219 static int vt1709_parse_auto_config(struct hda_codec *codec) 1220 { 1221 struct via_spec *spec = codec->spec; 1222 int err; 1223 1224 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 1225 if (err < 0) 1226 return err; 1227 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg); 1228 if (err < 0) 1229 return err; 1230 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 1231 return 0; /* can't find valid BIOS pin config */ 1232 1233 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg); 1234 if (err < 0) 1235 return err; 1236 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 1237 if (err < 0) 1238 return err; 1239 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg); 1240 if (err < 0) 1241 return err; 1242 1243 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 1244 1245 if (spec->autocfg.dig_out_pin) 1246 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID; 1247 if (spec->autocfg.dig_in_pin) 1248 spec->dig_in_nid = VT1709_DIGIN_NID; 1249 1250 if (spec->kctl_alloc) 1251 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1252 1253 spec->input_mux = &spec->private_imux; 1254 1255 return 1; 1256 } 1257 1258 #ifdef CONFIG_SND_HDA_POWER_SAVE 1259 static struct hda_amp_list vt1709_loopbacks[] = { 1260 { 0x18, HDA_INPUT, 1 }, 1261 { 0x18, HDA_INPUT, 2 }, 1262 { 0x18, HDA_INPUT, 3 }, 1263 { 0x18, HDA_INPUT, 4 }, 1264 { } /* end */ 1265 }; 1266 #endif 1267 1268 static int patch_vt1709_10ch(struct hda_codec *codec) 1269 { 1270 struct via_spec *spec; 1271 int err; 1272 1273 /* create a codec specific record */ 1274 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1275 if (spec == NULL) 1276 return -ENOMEM; 1277 1278 codec->spec = spec; 1279 1280 err = vt1709_parse_auto_config(codec); 1281 if (err < 0) { 1282 via_free(codec); 1283 return err; 1284 } else if (!err) { 1285 printk(KERN_INFO "hda_codec: Cannot set up configuration. " 1286 "Using genenic mode...\n"); 1287 } 1288 1289 spec->init_verbs = vt1709_10ch_volume_init_verbs; 1290 1291 spec->stream_name_analog = "VT1709 Analog"; 1292 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback; 1293 spec->stream_analog_capture = &vt1709_pcm_analog_capture; 1294 1295 spec->stream_name_digital = "VT1709 Digital"; 1296 spec->stream_digital_playback = &vt1709_pcm_digital_playback; 1297 spec->stream_digital_capture = &vt1709_pcm_digital_capture; 1298 1299 1300 if (!spec->adc_nids && spec->input_mux) { 1301 spec->adc_nids = vt1709_adc_nids; 1302 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); 1303 spec->mixers[spec->num_mixers] = vt1709_capture_mixer; 1304 spec->num_mixers++; 1305 } 1306 1307 codec->patch_ops = via_patch_ops; 1308 1309 codec->patch_ops.init = via_auto_init; 1310 #ifdef CONFIG_SND_HDA_POWER_SAVE 1311 spec->loopback.amplist = vt1709_loopbacks; 1312 #endif 1313 1314 return 0; 1315 } 1316 /* 1317 * generic initialization of ADC, input mixers and output mixers 1318 */ 1319 static struct hda_verb vt1709_6ch_volume_init_verbs[] = { 1320 /* 1321 * Unmute ADC0-2 and set the default input to mic-in 1322 */ 1323 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1324 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1325 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1326 1327 1328 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1329 * mixer widget 1330 */ 1331 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 1332 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1333 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1334 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 1335 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 1336 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 1337 1338 /* 1339 * Set up output selector (0x1a, 0x1b, 0x29) 1340 */ 1341 /* set vol=0 to output mixers */ 1342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1343 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1344 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1345 1346 /* 1347 * Unmute PW3 and PW4 1348 */ 1349 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1350 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1351 1352 /* Set input of PW4 as MW0 */ 1353 {0x20, AC_VERB_SET_CONNECT_SEL, 0}, 1354 /* Set mic as default input of sw0 */ 1355 {0x19, AC_VERB_SET_CONNECT_SEL, 0x2}, 1356 /* PW9 Output enable */ 1357 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1358 { } 1359 }; 1360 1361 static int patch_vt1709_6ch(struct hda_codec *codec) 1362 { 1363 struct via_spec *spec; 1364 int err; 1365 1366 /* create a codec specific record */ 1367 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 1368 if (spec == NULL) 1369 return -ENOMEM; 1370 1371 codec->spec = spec; 1372 1373 err = vt1709_parse_auto_config(codec); 1374 if (err < 0) { 1375 via_free(codec); 1376 return err; 1377 } else if (!err) { 1378 printk(KERN_INFO "hda_codec: Cannot set up configuration. " 1379 "Using genenic mode...\n"); 1380 } 1381 1382 spec->init_verbs = vt1709_6ch_volume_init_verbs; 1383 1384 spec->stream_name_analog = "VT1709 Analog"; 1385 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback; 1386 spec->stream_analog_capture = &vt1709_pcm_analog_capture; 1387 1388 spec->stream_name_digital = "VT1709 Digital"; 1389 spec->stream_digital_playback = &vt1709_pcm_digital_playback; 1390 spec->stream_digital_capture = &vt1709_pcm_digital_capture; 1391 1392 1393 if (!spec->adc_nids && spec->input_mux) { 1394 spec->adc_nids = vt1709_adc_nids; 1395 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); 1396 spec->mixers[spec->num_mixers] = vt1709_capture_mixer; 1397 spec->num_mixers++; 1398 } 1399 1400 codec->patch_ops = via_patch_ops; 1401 1402 codec->patch_ops.init = via_auto_init; 1403 #ifdef CONFIG_SND_HDA_POWER_SAVE 1404 spec->loopback.amplist = vt1709_loopbacks; 1405 #endif 1406 1407 return 0; 1408 } 1409 1410 /* 1411 * patch entries 1412 */ 1413 struct hda_codec_preset snd_hda_preset_via[] = { 1414 { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708}, 1415 { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708}, 1416 { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708}, 1417 { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708}, 1418 { .id = 0x1106E710, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch}, 1419 { .id = 0x1106E711, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch}, 1420 { .id = 0x1106E712, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch}, 1421 { .id = 0x1106E713, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch}, 1422 { .id = 0x1106E714, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch}, 1423 { .id = 0x1106E715, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch}, 1424 { .id = 0x1106E716, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch}, 1425 { .id = 0x1106E717, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch}, 1426 {} /* terminator */ 1427 }; 1428