1/* 2 * Universal Interface for Intel High Definition Audio Codec 3 * 4 * HD audio interface patch for VIA VT17xx/VT18xx/VT20xx codec 5 * 6 * (C) 2006-2009 VIA Technology, Inc. 7 * (C) 2006-2008 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/* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */ 33/* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */ 34/* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */ 35/* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */ 36/* 2008-04-09 Lydia Wang Add Independent HP feature */ 37/* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */ 38/* 2009-02-16 Logan Li Add support for VT1718S */ 39/* 2009-03-13 Logan Li Add support for VT1716S */ 40/* 2009-04-14 Lydai Wang Add support for VT1828S and VT2020 */ 41/* 2009-07-08 Lydia Wang Add support for VT2002P */ 42/* 2009-07-21 Lydia Wang Add support for VT1812 */ 43/* 2009-09-19 Lydia Wang Add support for VT1818S */ 44/* */ 45/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 46 47 48#include <linux/init.h> 49#include <linux/delay.h> 50#include <linux/slab.h> 51#include <sound/core.h> 52#include <sound/asoundef.h> 53#include "hda_codec.h" 54#include "hda_local.h" 55 56#define NID_MAPPING (-1) 57 58/* amp values */ 59#define AMP_VAL_IDX_SHIFT 19 60#define AMP_VAL_IDX_MASK (0x0f<<19) 61 62/* Pin Widget NID */ 63#define VT1708_HP_NID 0x13 64#define VT1708_DIGOUT_NID 0x14 65#define VT1708_DIGIN_NID 0x16 66#define VT1708_DIGIN_PIN 0x26 67#define VT1708_HP_PIN_NID 0x20 68#define VT1708_CD_PIN_NID 0x24 69 70#define VT1709_HP_DAC_NID 0x28 71#define VT1709_DIGOUT_NID 0x13 72#define VT1709_DIGIN_NID 0x17 73#define VT1709_DIGIN_PIN 0x25 74 75#define VT1708B_HP_NID 0x25 76#define VT1708B_DIGOUT_NID 0x12 77#define VT1708B_DIGIN_NID 0x15 78#define VT1708B_DIGIN_PIN 0x21 79 80#define VT1708S_HP_NID 0x25 81#define VT1708S_DIGOUT_NID 0x12 82 83#define VT1702_HP_NID 0x17 84#define VT1702_DIGOUT_NID 0x11 85 86enum VIA_HDA_CODEC { 87 UNKNOWN = -1, 88 VT1708, 89 VT1709_10CH, 90 VT1709_6CH, 91 VT1708B_8CH, 92 VT1708B_4CH, 93 VT1708S, 94 VT1708BCE, 95 VT1702, 96 VT1718S, 97 VT1716S, 98 VT2002P, 99 VT1812, 100 CODEC_TYPES, 101}; 102 103struct via_spec { 104 /* codec parameterization */ 105 struct snd_kcontrol_new *mixers[6]; 106 unsigned int num_mixers; 107 108 struct hda_verb *init_verbs[5]; 109 unsigned int num_iverbs; 110 111 char *stream_name_analog; 112 struct hda_pcm_stream *stream_analog_playback; 113 struct hda_pcm_stream *stream_analog_capture; 114 115 char *stream_name_digital; 116 struct hda_pcm_stream *stream_digital_playback; 117 struct hda_pcm_stream *stream_digital_capture; 118 119 /* playback */ 120 struct hda_multi_out multiout; 121 hda_nid_t slave_dig_outs[2]; 122 123 /* capture */ 124 unsigned int num_adc_nids; 125 hda_nid_t *adc_nids; 126 hda_nid_t mux_nids[3]; 127 hda_nid_t dig_in_nid; 128 hda_nid_t dig_in_pin; 129 130 /* capture source */ 131 const struct hda_input_mux *input_mux; 132 unsigned int cur_mux[3]; 133 134 /* PCM information */ 135 struct hda_pcm pcm_rec[3]; 136 137 /* dynamic controls, init_verbs and input_mux */ 138 struct auto_pin_cfg autocfg; 139 struct snd_array kctls; 140 struct hda_input_mux private_imux[2]; 141 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 142 143 /* HP mode source */ 144 const struct hda_input_mux *hp_mux; 145 unsigned int hp_independent_mode; 146 unsigned int hp_independent_mode_index; 147 unsigned int smart51_enabled; 148 unsigned int dmic_enabled; 149 enum VIA_HDA_CODEC codec_type; 150 151 /* work to check hp jack state */ 152 struct hda_codec *codec; 153 struct delayed_work vt1708_hp_work; 154 int vt1708_jack_detectect; 155 int vt1708_hp_present; 156#ifdef CONFIG_SND_HDA_POWER_SAVE 157 struct hda_loopback_check loopback; 158#endif 159}; 160 161static struct via_spec * via_new_spec(struct hda_codec *codec) 162{ 163 struct via_spec *spec; 164 165 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 166 if (spec == NULL) 167 return NULL; 168 169 codec->spec = spec; 170 spec->codec = codec; 171 return spec; 172} 173 174static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) 175{ 176 u32 vendor_id = codec->vendor_id; 177 u16 ven_id = vendor_id >> 16; 178 u16 dev_id = vendor_id & 0xffff; 179 enum VIA_HDA_CODEC codec_type; 180 181 /* get codec type */ 182 if (ven_id != 0x1106) 183 codec_type = UNKNOWN; 184 else if (dev_id >= 0x1708 && dev_id <= 0x170b) 185 codec_type = VT1708; 186 else if (dev_id >= 0xe710 && dev_id <= 0xe713) 187 codec_type = VT1709_10CH; 188 else if (dev_id >= 0xe714 && dev_id <= 0xe717) 189 codec_type = VT1709_6CH; 190 else if (dev_id >= 0xe720 && dev_id <= 0xe723) { 191 codec_type = VT1708B_8CH; 192 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7) 193 codec_type = VT1708BCE; 194 } else if (dev_id >= 0xe724 && dev_id <= 0xe727) 195 codec_type = VT1708B_4CH; 196 else if ((dev_id & 0xfff) == 0x397 197 && (dev_id >> 12) < 8) 198 codec_type = VT1708S; 199 else if ((dev_id & 0xfff) == 0x398 200 && (dev_id >> 12) < 8) 201 codec_type = VT1702; 202 else if ((dev_id & 0xfff) == 0x428 203 && (dev_id >> 12) < 8) 204 codec_type = VT1718S; 205 else if (dev_id == 0x0433 || dev_id == 0xa721) 206 codec_type = VT1716S; 207 else if (dev_id == 0x0441 || dev_id == 0x4441) 208 codec_type = VT1718S; 209 else if (dev_id == 0x0438 || dev_id == 0x4438) 210 codec_type = VT2002P; 211 else if (dev_id == 0x0448) 212 codec_type = VT1812; 213 else if (dev_id == 0x0440) 214 codec_type = VT1708S; 215 else 216 codec_type = UNKNOWN; 217 return codec_type; 218}; 219 220#define VIA_HP_EVENT 0x01 221#define VIA_GPIO_EVENT 0x02 222#define VIA_JACK_EVENT 0x04 223#define VIA_MONO_EVENT 0x08 224#define VIA_SPEAKER_EVENT 0x10 225#define VIA_BIND_HP_EVENT 0x20 226 227enum { 228 VIA_CTL_WIDGET_VOL, 229 VIA_CTL_WIDGET_MUTE, 230 VIA_CTL_WIDGET_ANALOG_MUTE, 231 VIA_CTL_WIDGET_BIND_PIN_MUTE, 232}; 233 234enum { 235 AUTO_SEQ_FRONT = 0, 236 AUTO_SEQ_SURROUND, 237 AUTO_SEQ_CENLFE, 238 AUTO_SEQ_SIDE 239}; 240 241static void analog_low_current_mode(struct hda_codec *codec, int stream_idle); 242static void set_jack_power_state(struct hda_codec *codec); 243static int is_aa_path_mute(struct hda_codec *codec); 244 245static void vt1708_start_hp_work(struct via_spec *spec) 246{ 247 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) 248 return; 249 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 250 !spec->vt1708_jack_detectect); 251 if (!delayed_work_pending(&spec->vt1708_hp_work)) 252 schedule_delayed_work(&spec->vt1708_hp_work, 253 msecs_to_jiffies(100)); 254} 255 256static void vt1708_stop_hp_work(struct via_spec *spec) 257{ 258 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) 259 return; 260 if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1 261 && !is_aa_path_mute(spec->codec)) 262 return; 263 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 264 !spec->vt1708_jack_detectect); 265 cancel_delayed_work(&spec->vt1708_hp_work); 266 flush_scheduled_work(); 267} 268 269 270static int analog_input_switch_put(struct snd_kcontrol *kcontrol, 271 struct snd_ctl_elem_value *ucontrol) 272{ 273 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 274 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 275 276 set_jack_power_state(codec); 277 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); 278 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { 279 if (is_aa_path_mute(codec)) 280 vt1708_start_hp_work(codec->spec); 281 else 282 vt1708_stop_hp_work(codec->spec); 283 } 284 return change; 285} 286 287/* modify .put = snd_hda_mixer_amp_switch_put */ 288#define ANALOG_INPUT_MUTE \ 289 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 290 .name = NULL, \ 291 .index = 0, \ 292 .info = snd_hda_mixer_amp_switch_info, \ 293 .get = snd_hda_mixer_amp_switch_get, \ 294 .put = analog_input_switch_put, \ 295 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } 296 297static void via_hp_bind_automute(struct hda_codec *codec); 298 299static int bind_pin_switch_put(struct snd_kcontrol *kcontrol, 300 struct snd_ctl_elem_value *ucontrol) 301{ 302 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 303 struct via_spec *spec = codec->spec; 304 int i; 305 int change = 0; 306 307 long *valp = ucontrol->value.integer.value; 308 int lmute, rmute; 309 if (strstr(kcontrol->id.name, "Switch") == NULL) { 310 snd_printd("Invalid control!\n"); 311 return change; 312 } 313 change = snd_hda_mixer_amp_switch_put(kcontrol, 314 ucontrol); 315 /* Get mute value */ 316 lmute = *valp ? 0 : HDA_AMP_MUTE; 317 valp++; 318 rmute = *valp ? 0 : HDA_AMP_MUTE; 319 320 /* Set hp pins */ 321 if (!spec->hp_independent_mode) { 322 for (i = 0; i < spec->autocfg.hp_outs; i++) { 323 snd_hda_codec_amp_update( 324 codec, spec->autocfg.hp_pins[i], 325 0, HDA_OUTPUT, 0, HDA_AMP_MUTE, 326 lmute); 327 snd_hda_codec_amp_update( 328 codec, spec->autocfg.hp_pins[i], 329 1, HDA_OUTPUT, 0, HDA_AMP_MUTE, 330 rmute); 331 } 332 } 333 334 if (!lmute && !rmute) { 335 /* Line Outs */ 336 for (i = 0; i < spec->autocfg.line_outs; i++) 337 snd_hda_codec_amp_stereo( 338 codec, spec->autocfg.line_out_pins[i], 339 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0); 340 /* Speakers */ 341 for (i = 0; i < spec->autocfg.speaker_outs; i++) 342 snd_hda_codec_amp_stereo( 343 codec, spec->autocfg.speaker_pins[i], 344 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0); 345 /* unmute */ 346 via_hp_bind_automute(codec); 347 348 } else { 349 if (lmute) { 350 /* Mute all left channels */ 351 for (i = 1; i < spec->autocfg.line_outs; i++) 352 snd_hda_codec_amp_update( 353 codec, 354 spec->autocfg.line_out_pins[i], 355 0, HDA_OUTPUT, 0, HDA_AMP_MUTE, 356 lmute); 357 for (i = 0; i < spec->autocfg.speaker_outs; i++) 358 snd_hda_codec_amp_update( 359 codec, 360 spec->autocfg.speaker_pins[i], 361 0, HDA_OUTPUT, 0, HDA_AMP_MUTE, 362 lmute); 363 } 364 if (rmute) { 365 /* mute all right channels */ 366 for (i = 1; i < spec->autocfg.line_outs; i++) 367 snd_hda_codec_amp_update( 368 codec, 369 spec->autocfg.line_out_pins[i], 370 1, HDA_OUTPUT, 0, HDA_AMP_MUTE, 371 rmute); 372 for (i = 0; i < spec->autocfg.speaker_outs; i++) 373 snd_hda_codec_amp_update( 374 codec, 375 spec->autocfg.speaker_pins[i], 376 1, HDA_OUTPUT, 0, HDA_AMP_MUTE, 377 rmute); 378 } 379 } 380 return change; 381} 382 383#define BIND_PIN_MUTE \ 384 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 385 .name = NULL, \ 386 .index = 0, \ 387 .info = snd_hda_mixer_amp_switch_info, \ 388 .get = snd_hda_mixer_amp_switch_get, \ 389 .put = bind_pin_switch_put, \ 390 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } 391 392static struct snd_kcontrol_new via_control_templates[] = { 393 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 394 HDA_CODEC_MUTE(NULL, 0, 0, 0), 395 ANALOG_INPUT_MUTE, 396 BIND_PIN_MUTE, 397}; 398 399static hda_nid_t vt1708_adc_nids[2] = { 400 /* ADC1-2 */ 401 0x15, 0x27 402}; 403 404static hda_nid_t vt1709_adc_nids[3] = { 405 /* ADC1-2 */ 406 0x14, 0x15, 0x16 407}; 408 409static hda_nid_t vt1708B_adc_nids[2] = { 410 /* ADC1-2 */ 411 0x13, 0x14 412}; 413 414static hda_nid_t vt1708S_adc_nids[2] = { 415 /* ADC1-2 */ 416 0x13, 0x14 417}; 418 419static hda_nid_t vt1702_adc_nids[3] = { 420 /* ADC1-2 */ 421 0x12, 0x20, 0x1F 422}; 423 424static hda_nid_t vt1718S_adc_nids[2] = { 425 /* ADC1-2 */ 426 0x10, 0x11 427}; 428 429static hda_nid_t vt1716S_adc_nids[2] = { 430 /* ADC1-2 */ 431 0x13, 0x14 432}; 433 434static hda_nid_t vt2002P_adc_nids[2] = { 435 /* ADC1-2 */ 436 0x10, 0x11 437}; 438 439static hda_nid_t vt1812_adc_nids[2] = { 440 /* ADC1-2 */ 441 0x10, 0x11 442}; 443 444 445/* add dynamic controls */ 446static int via_add_control(struct via_spec *spec, int type, const char *name, 447 unsigned long val) 448{ 449 struct snd_kcontrol_new *knew; 450 451 snd_array_init(&spec->kctls, sizeof(*knew), 32); 452 knew = snd_array_new(&spec->kctls); 453 if (!knew) 454 return -ENOMEM; 455 *knew = via_control_templates[type]; 456 knew->name = kstrdup(name, GFP_KERNEL); 457 if (!knew->name) 458 return -ENOMEM; 459 if (get_amp_nid_(val)) 460 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 461 knew->private_value = val; 462 return 0; 463} 464 465static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, 466 struct snd_kcontrol_new *tmpl) 467{ 468 struct snd_kcontrol_new *knew; 469 470 snd_array_init(&spec->kctls, sizeof(*knew), 32); 471 knew = snd_array_new(&spec->kctls); 472 if (!knew) 473 return NULL; 474 *knew = *tmpl; 475 knew->name = kstrdup(tmpl->name, GFP_KERNEL); 476 if (!knew->name) 477 return NULL; 478 return knew; 479} 480 481static void via_free_kctls(struct hda_codec *codec) 482{ 483 struct via_spec *spec = codec->spec; 484 485 if (spec->kctls.list) { 486 struct snd_kcontrol_new *kctl = spec->kctls.list; 487 int i; 488 for (i = 0; i < spec->kctls.used; i++) 489 kfree(kctl[i].name); 490 } 491 snd_array_free(&spec->kctls); 492} 493 494/* create input playback/capture controls for the given pin */ 495static int via_new_analog_input(struct via_spec *spec, const char *ctlname, 496 int idx, int mix_nid) 497{ 498 char name[32]; 499 int err; 500 501 sprintf(name, "%s Playback Volume", ctlname); 502 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 503 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 504 if (err < 0) 505 return err; 506 sprintf(name, "%s Playback Switch", ctlname); 507 err = via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, 508 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 509 if (err < 0) 510 return err; 511 return 0; 512} 513 514static void via_auto_set_output_and_unmute(struct hda_codec *codec, 515 hda_nid_t nid, int pin_type, 516 int dac_idx) 517{ 518 /* set as output */ 519 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 520 pin_type); 521 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 522 AMP_OUT_UNMUTE); 523 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 524 snd_hda_codec_write(codec, nid, 0, 525 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 526} 527 528 529static void via_auto_init_multi_out(struct hda_codec *codec) 530{ 531 struct via_spec *spec = codec->spec; 532 int i; 533 534 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 535 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 536 if (nid) 537 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 538 } 539} 540 541static void via_auto_init_hp_out(struct hda_codec *codec) 542{ 543 struct via_spec *spec = codec->spec; 544 hda_nid_t pin; 545 int i; 546 547 for (i = 0; i < spec->autocfg.hp_outs; i++) { 548 pin = spec->autocfg.hp_pins[i]; 549 if (pin) /* connect to front */ 550 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 551 } 552} 553 554static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin); 555 556static void via_auto_init_analog_input(struct hda_codec *codec) 557{ 558 struct via_spec *spec = codec->spec; 559 unsigned int ctl; 560 int i; 561 562 for (i = 0; i < AUTO_PIN_LAST; i++) { 563 hda_nid_t nid = spec->autocfg.input_pins[i]; 564 if (!nid) 565 continue; 566 567 if (spec->smart51_enabled && is_smart51_pins(spec, nid)) 568 ctl = PIN_OUT; 569 else if (i <= AUTO_PIN_FRONT_MIC) 570 ctl = PIN_VREF50; 571 else 572 ctl = PIN_IN; 573 snd_hda_codec_write(codec, nid, 0, 574 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl); 575 } 576} 577 578static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, 579 unsigned int *affected_parm) 580{ 581 unsigned parm; 582 unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid); 583 unsigned no_presence = (def_conf & AC_DEFCFG_MISC) 584 >> AC_DEFCFG_MISC_SHIFT 585 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */ 586 unsigned present = snd_hda_jack_detect(codec, nid); 587 struct via_spec *spec = codec->spec; 588 if ((spec->smart51_enabled && is_smart51_pins(spec, nid)) 589 || ((no_presence || present) 590 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) { 591 *affected_parm = AC_PWRST_D0; /* if it's connected */ 592 parm = AC_PWRST_D0; 593 } else 594 parm = AC_PWRST_D3; 595 596 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); 597} 598 599static void set_jack_power_state(struct hda_codec *codec) 600{ 601 struct via_spec *spec = codec->spec; 602 int imux_is_smixer; 603 unsigned int parm; 604 605 if (spec->codec_type == VT1702) { 606 imux_is_smixer = snd_hda_codec_read( 607 codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; 608 /* inputs */ 609 /* PW 1/2/5 (14h/15h/18h) */ 610 parm = AC_PWRST_D3; 611 set_pin_power_state(codec, 0x14, &parm); 612 set_pin_power_state(codec, 0x15, &parm); 613 set_pin_power_state(codec, 0x18, &parm); 614 if (imux_is_smixer) 615 parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */ 616 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ 617 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, 618 parm); 619 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, 620 parm); 621 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, 622 parm); 623 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, 624 parm); 625 626 /* outputs */ 627 /* PW 3/4 (16h/17h) */ 628 parm = AC_PWRST_D3; 629 set_pin_power_state(codec, 0x16, &parm); 630 set_pin_power_state(codec, 0x17, &parm); 631 /* MW0 (1ah), AOW 0/1 (10h/1dh) */ 632 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, 633 imux_is_smixer ? AC_PWRST_D0 : parm); 634 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, 635 parm); 636 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, 637 parm); 638 } else if (spec->codec_type == VT1708B_8CH 639 || spec->codec_type == VT1708B_4CH 640 || spec->codec_type == VT1708S) { 641 /* SW0 (17h) = stereo mixer */ 642 int is_8ch = spec->codec_type != VT1708B_4CH; 643 imux_is_smixer = snd_hda_codec_read( 644 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) 645 == ((spec->codec_type == VT1708S) ? 5 : 0); 646 /* inputs */ 647 /* PW 1/2/5 (1ah/1bh/1eh) */ 648 parm = AC_PWRST_D3; 649 set_pin_power_state(codec, 0x1a, &parm); 650 set_pin_power_state(codec, 0x1b, &parm); 651 set_pin_power_state(codec, 0x1e, &parm); 652 if (imux_is_smixer) 653 parm = AC_PWRST_D0; 654 /* SW0 (17h), AIW 0/1 (13h/14h) */ 655 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, 656 parm); 657 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, 658 parm); 659 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, 660 parm); 661 662 /* outputs */ 663 /* PW0 (19h), SW1 (18h), AOW1 (11h) */ 664 parm = AC_PWRST_D3; 665 set_pin_power_state(codec, 0x19, &parm); 666 if (spec->smart51_enabled) 667 parm = AC_PWRST_D0; 668 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, 669 parm); 670 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, 671 parm); 672 673 /* PW6 (22h), SW2 (26h), AOW2 (24h) */ 674 if (is_8ch) { 675 parm = AC_PWRST_D3; 676 set_pin_power_state(codec, 0x22, &parm); 677 if (spec->smart51_enabled) 678 parm = AC_PWRST_D0; 679 snd_hda_codec_write(codec, 0x26, 0, 680 AC_VERB_SET_POWER_STATE, parm); 681 snd_hda_codec_write(codec, 0x24, 0, 682 AC_VERB_SET_POWER_STATE, parm); 683 } 684 685 /* PW 3/4/7 (1ch/1dh/23h) */ 686 parm = AC_PWRST_D3; 687 /* force to D0 for internal Speaker */ 688 set_pin_power_state(codec, 0x1c, &parm); 689 set_pin_power_state(codec, 0x1d, &parm); 690 if (is_8ch) 691 set_pin_power_state(codec, 0x23, &parm); 692 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ 693 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, 694 imux_is_smixer ? AC_PWRST_D0 : parm); 695 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, 696 parm); 697 if (is_8ch) { 698 snd_hda_codec_write(codec, 0x25, 0, 699 AC_VERB_SET_POWER_STATE, parm); 700 snd_hda_codec_write(codec, 0x27, 0, 701 AC_VERB_SET_POWER_STATE, parm); 702 } 703 } else if (spec->codec_type == VT1718S) { 704 /* MUX6 (1eh) = stereo mixer */ 705 imux_is_smixer = snd_hda_codec_read( 706 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; 707 /* inputs */ 708 /* PW 5/6/7 (29h/2ah/2bh) */ 709 parm = AC_PWRST_D3; 710 set_pin_power_state(codec, 0x29, &parm); 711 set_pin_power_state(codec, 0x2a, &parm); 712 set_pin_power_state(codec, 0x2b, &parm); 713 if (imux_is_smixer) 714 parm = AC_PWRST_D0; 715 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ 716 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, 717 parm); 718 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, 719 parm); 720 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, 721 parm); 722 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, 723 parm); 724 725 /* outputs */ 726 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ 727 parm = AC_PWRST_D3; 728 set_pin_power_state(codec, 0x27, &parm); 729 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, 730 parm); 731 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, 732 parm); 733 734 /* PW2 (26h), AOW2 (ah) */ 735 parm = AC_PWRST_D3; 736 set_pin_power_state(codec, 0x26, &parm); 737 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, 738 parm); 739 740 /* PW0/1 (24h/25h) */ 741 parm = AC_PWRST_D3; 742 set_pin_power_state(codec, 0x24, &parm); 743 set_pin_power_state(codec, 0x25, &parm); 744 if (!spec->hp_independent_mode) /* check for redirected HP */ 745 set_pin_power_state(codec, 0x28, &parm); 746 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, 747 parm); 748 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, 749 parm); 750 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ 751 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, 752 imux_is_smixer ? AC_PWRST_D0 : parm); 753 if (spec->hp_independent_mode) { 754 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ 755 parm = AC_PWRST_D3; 756 set_pin_power_state(codec, 0x28, &parm); 757 snd_hda_codec_write(codec, 0x1b, 0, 758 AC_VERB_SET_POWER_STATE, parm); 759 snd_hda_codec_write(codec, 0x34, 0, 760 AC_VERB_SET_POWER_STATE, parm); 761 snd_hda_codec_write(codec, 0xc, 0, 762 AC_VERB_SET_POWER_STATE, parm); 763 } 764 } else if (spec->codec_type == VT1716S) { 765 unsigned int mono_out, present; 766 /* SW0 (17h) = stereo mixer */ 767 imux_is_smixer = snd_hda_codec_read( 768 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; 769 /* inputs */ 770 /* PW 1/2/5 (1ah/1bh/1eh) */ 771 parm = AC_PWRST_D3; 772 set_pin_power_state(codec, 0x1a, &parm); 773 set_pin_power_state(codec, 0x1b, &parm); 774 set_pin_power_state(codec, 0x1e, &parm); 775 if (imux_is_smixer) 776 parm = AC_PWRST_D0; 777 /* SW0 (17h), AIW0(13h) */ 778 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, 779 parm); 780 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, 781 parm); 782 783 parm = AC_PWRST_D3; 784 set_pin_power_state(codec, 0x1e, &parm); 785 /* PW11 (22h) */ 786 if (spec->dmic_enabled) 787 set_pin_power_state(codec, 0x22, &parm); 788 else 789 snd_hda_codec_write( 790 codec, 0x22, 0, 791 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 792 793 /* SW2(26h), AIW1(14h) */ 794 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, 795 parm); 796 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, 797 parm); 798 799 /* outputs */ 800 /* PW0 (19h), SW1 (18h), AOW1 (11h) */ 801 parm = AC_PWRST_D3; 802 set_pin_power_state(codec, 0x19, &parm); 803 /* Smart 5.1 PW2(1bh) */ 804 if (spec->smart51_enabled) 805 set_pin_power_state(codec, 0x1b, &parm); 806 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, 807 parm); 808 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, 809 parm); 810 811 /* PW7 (23h), SW3 (27h), AOW3 (25h) */ 812 parm = AC_PWRST_D3; 813 set_pin_power_state(codec, 0x23, &parm); 814 /* Smart 5.1 PW1(1ah) */ 815 if (spec->smart51_enabled) 816 set_pin_power_state(codec, 0x1a, &parm); 817 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, 818 parm); 819 820 /* Smart 5.1 PW5(1eh) */ 821 if (spec->smart51_enabled) 822 set_pin_power_state(codec, 0x1e, &parm); 823 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, 824 parm); 825 826 /* Mono out */ 827 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ 828 present = snd_hda_jack_detect(codec, 0x1c); 829 if (present) 830 mono_out = 0; 831 else { 832 present = snd_hda_jack_detect(codec, 0x1d); 833 if (!spec->hp_independent_mode && present) 834 mono_out = 0; 835 else 836 mono_out = 1; 837 } 838 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; 839 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, 840 parm); 841 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, 842 parm); 843 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, 844 parm); 845 846 /* PW 3/4 (1ch/1dh) */ 847 parm = AC_PWRST_D3; 848 set_pin_power_state(codec, 0x1c, &parm); 849 set_pin_power_state(codec, 0x1d, &parm); 850 /* HP Independent Mode, power on AOW3 */ 851 if (spec->hp_independent_mode) 852 snd_hda_codec_write(codec, 0x25, 0, 853 AC_VERB_SET_POWER_STATE, parm); 854 855 /* force to D0 for internal Speaker */ 856 /* MW0 (16h), AOW0 (10h) */ 857 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, 858 imux_is_smixer ? AC_PWRST_D0 : parm); 859 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, 860 mono_out ? AC_PWRST_D0 : parm); 861 } else if (spec->codec_type == VT2002P) { 862 unsigned int present; 863 /* MUX9 (1eh) = stereo mixer */ 864 imux_is_smixer = snd_hda_codec_read( 865 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; 866 /* inputs */ 867 /* PW 5/6/7 (29h/2ah/2bh) */ 868 parm = AC_PWRST_D3; 869 set_pin_power_state(codec, 0x29, &parm); 870 set_pin_power_state(codec, 0x2a, &parm); 871 set_pin_power_state(codec, 0x2b, &parm); 872 if (imux_is_smixer) 873 parm = AC_PWRST_D0; 874 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ 875 snd_hda_codec_write(codec, 0x1e, 0, 876 AC_VERB_SET_POWER_STATE, parm); 877 snd_hda_codec_write(codec, 0x1f, 0, 878 AC_VERB_SET_POWER_STATE, parm); 879 snd_hda_codec_write(codec, 0x10, 0, 880 AC_VERB_SET_POWER_STATE, parm); 881 snd_hda_codec_write(codec, 0x11, 0, 882 AC_VERB_SET_POWER_STATE, parm); 883 884 /* outputs */ 885 /* AOW0 (8h)*/ 886 snd_hda_codec_write(codec, 0x8, 0, 887 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 888 889 /* PW4 (26h), MW4 (1ch), MUX4(37h) */ 890 parm = AC_PWRST_D3; 891 set_pin_power_state(codec, 0x26, &parm); 892 snd_hda_codec_write(codec, 0x1c, 0, 893 AC_VERB_SET_POWER_STATE, parm); 894 snd_hda_codec_write(codec, 0x37, 895 0, AC_VERB_SET_POWER_STATE, parm); 896 897 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ 898 parm = AC_PWRST_D3; 899 set_pin_power_state(codec, 0x25, &parm); 900 snd_hda_codec_write(codec, 0x19, 0, 901 AC_VERB_SET_POWER_STATE, parm); 902 snd_hda_codec_write(codec, 0x35, 0, 903 AC_VERB_SET_POWER_STATE, parm); 904 if (spec->hp_independent_mode) { 905 snd_hda_codec_write(codec, 0x9, 0, 906 AC_VERB_SET_POWER_STATE, parm); 907 } 908 909 /* Class-D */ 910 /* PW0 (24h), MW0(18h), MUX0(34h) */ 911 present = snd_hda_jack_detect(codec, 0x25); 912 parm = AC_PWRST_D3; 913 set_pin_power_state(codec, 0x24, &parm); 914 if (present) { 915 snd_hda_codec_write( 916 codec, 0x18, 0, 917 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 918 snd_hda_codec_write( 919 codec, 0x34, 0, 920 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 921 } else { 922 snd_hda_codec_write( 923 codec, 0x18, 0, 924 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 925 snd_hda_codec_write( 926 codec, 0x34, 0, 927 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 928 } 929 930 /* Mono Out */ 931 /* PW15 (31h), MW8(17h), MUX8(3bh) */ 932 present = snd_hda_jack_detect(codec, 0x26); 933 parm = AC_PWRST_D3; 934 set_pin_power_state(codec, 0x31, &parm); 935 if (present) { 936 snd_hda_codec_write( 937 codec, 0x17, 0, 938 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 939 snd_hda_codec_write( 940 codec, 0x3b, 0, 941 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 942 } else { 943 snd_hda_codec_write( 944 codec, 0x17, 0, 945 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 946 snd_hda_codec_write( 947 codec, 0x3b, 0, 948 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 949 } 950 951 /* MW9 (21h) */ 952 if (imux_is_smixer || !is_aa_path_mute(codec)) 953 snd_hda_codec_write( 954 codec, 0x21, 0, 955 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 956 else 957 snd_hda_codec_write( 958 codec, 0x21, 0, 959 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 960 } else if (spec->codec_type == VT1812) { 961 unsigned int present; 962 /* MUX10 (1eh) = stereo mixer */ 963 imux_is_smixer = snd_hda_codec_read( 964 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; 965 /* inputs */ 966 /* PW 5/6/7 (29h/2ah/2bh) */ 967 parm = AC_PWRST_D3; 968 set_pin_power_state(codec, 0x29, &parm); 969 set_pin_power_state(codec, 0x2a, &parm); 970 set_pin_power_state(codec, 0x2b, &parm); 971 if (imux_is_smixer) 972 parm = AC_PWRST_D0; 973 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ 974 snd_hda_codec_write(codec, 0x1e, 0, 975 AC_VERB_SET_POWER_STATE, parm); 976 snd_hda_codec_write(codec, 0x1f, 0, 977 AC_VERB_SET_POWER_STATE, parm); 978 snd_hda_codec_write(codec, 0x10, 0, 979 AC_VERB_SET_POWER_STATE, parm); 980 snd_hda_codec_write(codec, 0x11, 0, 981 AC_VERB_SET_POWER_STATE, parm); 982 983 /* outputs */ 984 /* AOW0 (8h)*/ 985 snd_hda_codec_write(codec, 0x8, 0, 986 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 987 988 /* PW4 (28h), MW4 (18h), MUX4(38h) */ 989 parm = AC_PWRST_D3; 990 set_pin_power_state(codec, 0x28, &parm); 991 snd_hda_codec_write(codec, 0x18, 0, 992 AC_VERB_SET_POWER_STATE, parm); 993 snd_hda_codec_write(codec, 0x38, 0, 994 AC_VERB_SET_POWER_STATE, parm); 995 996 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ 997 parm = AC_PWRST_D3; 998 set_pin_power_state(codec, 0x25, &parm); 999 snd_hda_codec_write(codec, 0x15, 0, 1000 AC_VERB_SET_POWER_STATE, parm); 1001 snd_hda_codec_write(codec, 0x35, 0, 1002 AC_VERB_SET_POWER_STATE, parm); 1003 if (spec->hp_independent_mode) { 1004 snd_hda_codec_write(codec, 0x9, 0, 1005 AC_VERB_SET_POWER_STATE, parm); 1006 } 1007 1008 /* Internal Speaker */ 1009 /* PW0 (24h), MW0(14h), MUX0(34h) */ 1010 present = snd_hda_jack_detect(codec, 0x25); 1011 parm = AC_PWRST_D3; 1012 set_pin_power_state(codec, 0x24, &parm); 1013 if (present) { 1014 snd_hda_codec_write(codec, 0x14, 0, 1015 AC_VERB_SET_POWER_STATE, 1016 AC_PWRST_D3); 1017 snd_hda_codec_write(codec, 0x34, 0, 1018 AC_VERB_SET_POWER_STATE, 1019 AC_PWRST_D3); 1020 } else { 1021 snd_hda_codec_write(codec, 0x14, 0, 1022 AC_VERB_SET_POWER_STATE, 1023 AC_PWRST_D0); 1024 snd_hda_codec_write(codec, 0x34, 0, 1025 AC_VERB_SET_POWER_STATE, 1026 AC_PWRST_D0); 1027 } 1028 /* Mono Out */ 1029 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */ 1030 present = snd_hda_jack_detect(codec, 0x28); 1031 parm = AC_PWRST_D3; 1032 set_pin_power_state(codec, 0x31, &parm); 1033 if (present) { 1034 snd_hda_codec_write(codec, 0x1c, 0, 1035 AC_VERB_SET_POWER_STATE, 1036 AC_PWRST_D3); 1037 snd_hda_codec_write(codec, 0x3c, 0, 1038 AC_VERB_SET_POWER_STATE, 1039 AC_PWRST_D3); 1040 snd_hda_codec_write(codec, 0x3e, 0, 1041 AC_VERB_SET_POWER_STATE, 1042 AC_PWRST_D3); 1043 } else { 1044 snd_hda_codec_write(codec, 0x1c, 0, 1045 AC_VERB_SET_POWER_STATE, 1046 AC_PWRST_D0); 1047 snd_hda_codec_write(codec, 0x3c, 0, 1048 AC_VERB_SET_POWER_STATE, 1049 AC_PWRST_D0); 1050 snd_hda_codec_write(codec, 0x3e, 0, 1051 AC_VERB_SET_POWER_STATE, 1052 AC_PWRST_D0); 1053 } 1054 1055 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ 1056 parm = AC_PWRST_D3; 1057 set_pin_power_state(codec, 0x33, &parm); 1058 snd_hda_codec_write(codec, 0x1d, 0, 1059 AC_VERB_SET_POWER_STATE, parm); 1060 snd_hda_codec_write(codec, 0x3d, 0, 1061 AC_VERB_SET_POWER_STATE, parm); 1062 1063 /* MW9 (21h) */ 1064 if (imux_is_smixer || !is_aa_path_mute(codec)) 1065 snd_hda_codec_write( 1066 codec, 0x21, 0, 1067 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 1068 else 1069 snd_hda_codec_write( 1070 codec, 0x21, 0, 1071 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 1072 } 1073} 1074 1075/* 1076 * input MUX handling 1077 */ 1078static int via_mux_enum_info(struct snd_kcontrol *kcontrol, 1079 struct snd_ctl_elem_info *uinfo) 1080{ 1081 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1082 struct via_spec *spec = codec->spec; 1083 return snd_hda_input_mux_info(spec->input_mux, uinfo); 1084} 1085 1086static int via_mux_enum_get(struct snd_kcontrol *kcontrol, 1087 struct snd_ctl_elem_value *ucontrol) 1088{ 1089 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1090 struct via_spec *spec = codec->spec; 1091 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 1092 1093 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 1094 return 0; 1095} 1096 1097static int via_mux_enum_put(struct snd_kcontrol *kcontrol, 1098 struct snd_ctl_elem_value *ucontrol) 1099{ 1100 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1101 struct via_spec *spec = codec->spec; 1102 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 1103 1104 if (!spec->mux_nids[adc_idx]) 1105 return -EINVAL; 1106 /* switch to D0 beofre change index */ 1107 if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0, 1108 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0) 1109 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, 1110 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 1111 /* update jack power state */ 1112 set_jack_power_state(codec); 1113 1114 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 1115 spec->mux_nids[adc_idx], 1116 &spec->cur_mux[adc_idx]); 1117} 1118 1119static int via_independent_hp_info(struct snd_kcontrol *kcontrol, 1120 struct snd_ctl_elem_info *uinfo) 1121{ 1122 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1123 struct via_spec *spec = codec->spec; 1124 return snd_hda_input_mux_info(spec->hp_mux, uinfo); 1125} 1126 1127static int via_independent_hp_get(struct snd_kcontrol *kcontrol, 1128 struct snd_ctl_elem_value *ucontrol) 1129{ 1130 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1131 hda_nid_t nid = kcontrol->private_value; 1132 unsigned int pinsel; 1133 1134 /* use !! to translate conn sel 2 for VT1718S */ 1135 pinsel = !!snd_hda_codec_read(codec, nid, 0, 1136 AC_VERB_GET_CONNECT_SEL, 1137 0x00); 1138 ucontrol->value.enumerated.item[0] = pinsel; 1139 1140 return 0; 1141} 1142 1143static void activate_ctl(struct hda_codec *codec, const char *name, int active) 1144{ 1145 struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name); 1146 if (ctl) { 1147 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 1148 ctl->vd[0].access |= active 1149 ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE; 1150 snd_ctl_notify(codec->bus->card, 1151 SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id); 1152 } 1153} 1154 1155static hda_nid_t side_mute_channel(struct via_spec *spec) 1156{ 1157 switch (spec->codec_type) { 1158 case VT1708: return 0x1b; 1159 case VT1709_10CH: return 0x29; 1160 case VT1708B_8CH: /* fall thru */ 1161 case VT1708S: return 0x27; 1162 default: return 0; 1163 } 1164} 1165 1166static int update_side_mute_status(struct hda_codec *codec) 1167{ 1168 /* mute side channel */ 1169 struct via_spec *spec = codec->spec; 1170 unsigned int parm = spec->hp_independent_mode 1171 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; 1172 hda_nid_t sw3 = side_mute_channel(spec); 1173 1174 if (sw3) 1175 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1176 parm); 1177 return 0; 1178} 1179 1180static int via_independent_hp_put(struct snd_kcontrol *kcontrol, 1181 struct snd_ctl_elem_value *ucontrol) 1182{ 1183 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1184 struct via_spec *spec = codec->spec; 1185 hda_nid_t nid = kcontrol->private_value; 1186 unsigned int pinsel = ucontrol->value.enumerated.item[0]; 1187 /* Get Independent Mode index of headphone pin widget */ 1188 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel 1189 ? 1 : 0; 1190 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); 1191 1192 if (spec->multiout.hp_nid && spec->multiout.hp_nid 1193 != spec->multiout.dac_nids[HDA_FRONT]) 1194 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid, 1195 0, 0, 0); 1196 1197 update_side_mute_status(codec); 1198 /* update HP volume/swtich active state */ 1199 if (spec->codec_type == VT1708S 1200 || spec->codec_type == VT1702 1201 || spec->codec_type == VT1718S 1202 || spec->codec_type == VT1716S 1203 || spec->codec_type == VT2002P 1204 || spec->codec_type == VT1812) { 1205 activate_ctl(codec, "Headphone Playback Volume", 1206 spec->hp_independent_mode); 1207 activate_ctl(codec, "Headphone Playback Switch", 1208 spec->hp_independent_mode); 1209 } 1210 return 0; 1211} 1212 1213static struct snd_kcontrol_new via_hp_mixer[2] = { 1214 { 1215 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1216 .name = "Independent HP", 1217 .info = via_independent_hp_info, 1218 .get = via_independent_hp_get, 1219 .put = via_independent_hp_put, 1220 }, 1221 { 1222 .iface = NID_MAPPING, 1223 .name = "Independent HP", 1224 }, 1225}; 1226 1227static int via_hp_build(struct hda_codec *codec) 1228{ 1229 struct via_spec *spec = codec->spec; 1230 struct snd_kcontrol_new *knew; 1231 hda_nid_t nid; 1232 int nums; 1233 hda_nid_t conn[HDA_MAX_CONNECTIONS]; 1234 1235 switch (spec->codec_type) { 1236 case VT1718S: 1237 nid = 0x34; 1238 break; 1239 case VT2002P: 1240 nid = 0x35; 1241 break; 1242 case VT1812: 1243 nid = 0x3d; 1244 break; 1245 default: 1246 nid = spec->autocfg.hp_pins[0]; 1247 break; 1248 } 1249 1250 nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); 1251 if (nums <= 1) 1252 return 0; 1253 1254 knew = via_clone_control(spec, &via_hp_mixer[0]); 1255 if (knew == NULL) 1256 return -ENOMEM; 1257 1258 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; 1259 knew->private_value = nid; 1260 1261 knew = via_clone_control(spec, &via_hp_mixer[1]); 1262 if (knew == NULL) 1263 return -ENOMEM; 1264 knew->subdevice = side_mute_channel(spec); 1265 1266 return 0; 1267} 1268 1269static void notify_aa_path_ctls(struct hda_codec *codec) 1270{ 1271 int i; 1272 struct snd_ctl_elem_id id; 1273 const char *labels[] = {"Mic", "Front Mic", "Line"}; 1274 1275 memset(&id, 0, sizeof(id)); 1276 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1277 for (i = 0; i < ARRAY_SIZE(labels); i++) { 1278 sprintf(id.name, "%s Playback Volume", labels[i]); 1279 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE, 1280 &id); 1281 } 1282} 1283 1284static void mute_aa_path(struct hda_codec *codec, int mute) 1285{ 1286 struct via_spec *spec = codec->spec; 1287 hda_nid_t nid_mixer; 1288 int start_idx; 1289 int end_idx; 1290 int i; 1291 /* get nid of MW0 and start & end index */ 1292 switch (spec->codec_type) { 1293 case VT1708: 1294 nid_mixer = 0x17; 1295 start_idx = 2; 1296 end_idx = 4; 1297 break; 1298 case VT1709_10CH: 1299 case VT1709_6CH: 1300 nid_mixer = 0x18; 1301 start_idx = 2; 1302 end_idx = 4; 1303 break; 1304 case VT1708B_8CH: 1305 case VT1708B_4CH: 1306 case VT1708S: 1307 case VT1716S: 1308 nid_mixer = 0x16; 1309 start_idx = 2; 1310 end_idx = 4; 1311 break; 1312 default: 1313 return; 1314 } 1315 /* check AA path's mute status */ 1316 for (i = start_idx; i <= end_idx; i++) { 1317 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE; 1318 snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i, 1319 HDA_AMP_MUTE, val); 1320 } 1321} 1322static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin) 1323{ 1324 int res = 0; 1325 int index; 1326 for (index = AUTO_PIN_MIC; index < AUTO_PIN_FRONT_LINE; index++) { 1327 if (pin == spec->autocfg.input_pins[index]) { 1328 res = 1; 1329 break; 1330 } 1331 } 1332 return res; 1333} 1334 1335static int via_smart51_info(struct snd_kcontrol *kcontrol, 1336 struct snd_ctl_elem_info *uinfo) 1337{ 1338 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1339 uinfo->count = 1; 1340 uinfo->value.integer.min = 0; 1341 uinfo->value.integer.max = 1; 1342 return 0; 1343} 1344 1345static int via_smart51_get(struct snd_kcontrol *kcontrol, 1346 struct snd_ctl_elem_value *ucontrol) 1347{ 1348 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1349 struct via_spec *spec = codec->spec; 1350 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE }; 1351 int on = 1; 1352 int i; 1353 1354 for (i = 0; i < ARRAY_SIZE(index); i++) { 1355 hda_nid_t nid = spec->autocfg.input_pins[index[i]]; 1356 if (nid) { 1357 int ctl = 1358 snd_hda_codec_read(codec, nid, 0, 1359 AC_VERB_GET_PIN_WIDGET_CONTROL, 1360 0); 1361 if (i == AUTO_PIN_FRONT_MIC 1362 && spec->hp_independent_mode 1363 && spec->codec_type != VT1718S) 1364 continue; /* ignore FMic for independent HP */ 1365 if (ctl & AC_PINCTL_IN_EN 1366 && !(ctl & AC_PINCTL_OUT_EN)) 1367 on = 0; 1368 } 1369 } 1370 *ucontrol->value.integer.value = on; 1371 return 0; 1372} 1373 1374static int via_smart51_put(struct snd_kcontrol *kcontrol, 1375 struct snd_ctl_elem_value *ucontrol) 1376{ 1377 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1378 struct via_spec *spec = codec->spec; 1379 int out_in = *ucontrol->value.integer.value 1380 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN; 1381 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE }; 1382 int i; 1383 1384 for (i = 0; i < ARRAY_SIZE(index); i++) { 1385 hda_nid_t nid = spec->autocfg.input_pins[index[i]]; 1386 if (i == AUTO_PIN_FRONT_MIC 1387 && spec->hp_independent_mode 1388 && spec->codec_type != VT1718S) 1389 continue; /* don't retask FMic for independent HP */ 1390 if (nid) { 1391 unsigned int parm = snd_hda_codec_read( 1392 codec, nid, 0, 1393 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 1394 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); 1395 parm |= out_in; 1396 snd_hda_codec_write(codec, nid, 0, 1397 AC_VERB_SET_PIN_WIDGET_CONTROL, 1398 parm); 1399 if (out_in == AC_PINCTL_OUT_EN) { 1400 mute_aa_path(codec, 1); 1401 notify_aa_path_ctls(codec); 1402 } 1403 if (spec->codec_type == VT1718S) 1404 snd_hda_codec_amp_stereo( 1405 codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE, 1406 HDA_AMP_UNMUTE); 1407 } 1408 if (i == AUTO_PIN_FRONT_MIC) { 1409 if (spec->codec_type == VT1708S 1410 || spec->codec_type == VT1716S) { 1411 /* input = index 1 (AOW3) */ 1412 snd_hda_codec_write( 1413 codec, nid, 0, 1414 AC_VERB_SET_CONNECT_SEL, 1); 1415 snd_hda_codec_amp_stereo( 1416 codec, nid, HDA_OUTPUT, 1417 0, HDA_AMP_MUTE, HDA_AMP_UNMUTE); 1418 } 1419 } 1420 } 1421 spec->smart51_enabled = *ucontrol->value.integer.value; 1422 set_jack_power_state(codec); 1423 return 1; 1424} 1425 1426static struct snd_kcontrol_new via_smart51_mixer[2] = { 1427 { 1428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1429 .name = "Smart 5.1", 1430 .count = 1, 1431 .info = via_smart51_info, 1432 .get = via_smart51_get, 1433 .put = via_smart51_put, 1434 }, 1435 { 1436 .iface = NID_MAPPING, 1437 .name = "Smart 5.1", 1438 } 1439}; 1440 1441static int via_smart51_build(struct via_spec *spec) 1442{ 1443 struct snd_kcontrol_new *knew; 1444 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE }; 1445 hda_nid_t nid; 1446 int i; 1447 1448 knew = via_clone_control(spec, &via_smart51_mixer[0]); 1449 if (knew == NULL) 1450 return -ENOMEM; 1451 1452 for (i = 0; i < ARRAY_SIZE(index); i++) { 1453 nid = spec->autocfg.input_pins[index[i]]; 1454 if (nid) { 1455 knew = via_clone_control(spec, &via_smart51_mixer[1]); 1456 if (knew == NULL) 1457 return -ENOMEM; 1458 knew->subdevice = nid; 1459 } 1460 } 1461 1462 return 0; 1463} 1464 1465/* capture mixer elements */ 1466static struct snd_kcontrol_new vt1708_capture_mixer[] = { 1467 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 1468 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT), 1469 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT), 1470 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT), 1471 { 1472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1473 /* The multiple "Capture Source" controls confuse alsamixer 1474 * So call somewhat different.. 1475 */ 1476 /* .name = "Capture Source", */ 1477 .name = "Input Source", 1478 .count = 1, 1479 .info = via_mux_enum_info, 1480 .get = via_mux_enum_get, 1481 .put = via_mux_enum_put, 1482 }, 1483 { } /* end */ 1484}; 1485 1486/* check AA path's mute statue */ 1487static int is_aa_path_mute(struct hda_codec *codec) 1488{ 1489 int mute = 1; 1490 hda_nid_t nid_mixer; 1491 int start_idx; 1492 int end_idx; 1493 int i; 1494 struct via_spec *spec = codec->spec; 1495 /* get nid of MW0 and start & end index */ 1496 switch (spec->codec_type) { 1497 case VT1708B_8CH: 1498 case VT1708B_4CH: 1499 case VT1708S: 1500 case VT1716S: 1501 nid_mixer = 0x16; 1502 start_idx = 2; 1503 end_idx = 4; 1504 break; 1505 case VT1702: 1506 nid_mixer = 0x1a; 1507 start_idx = 1; 1508 end_idx = 3; 1509 break; 1510 case VT1718S: 1511 nid_mixer = 0x21; 1512 start_idx = 1; 1513 end_idx = 3; 1514 break; 1515 case VT2002P: 1516 case VT1812: 1517 nid_mixer = 0x21; 1518 start_idx = 0; 1519 end_idx = 2; 1520 break; 1521 default: 1522 return 0; 1523 } 1524 /* check AA path's mute status */ 1525 for (i = start_idx; i <= end_idx; i++) { 1526 unsigned int con_list = snd_hda_codec_read( 1527 codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4); 1528 int shift = 8 * (i % 4); 1529 hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift; 1530 unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin); 1531 if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) { 1532 /* check mute status while the pin is connected */ 1533 int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0, 1534 HDA_INPUT, i) >> 7; 1535 int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1, 1536 HDA_INPUT, i) >> 7; 1537 if (!mute_l || !mute_r) { 1538 mute = 0; 1539 break; 1540 } 1541 } 1542 } 1543 return mute; 1544} 1545 1546/* enter/exit analog low-current mode */ 1547static void analog_low_current_mode(struct hda_codec *codec, int stream_idle) 1548{ 1549 struct via_spec *spec = codec->spec; 1550 static int saved_stream_idle = 1; /* saved stream idle status */ 1551 int enable = is_aa_path_mute(codec); 1552 unsigned int verb = 0; 1553 unsigned int parm = 0; 1554 1555 if (stream_idle == -1) /* stream status did not change */ 1556 enable = enable && saved_stream_idle; 1557 else { 1558 enable = enable && stream_idle; 1559 saved_stream_idle = stream_idle; 1560 } 1561 1562 /* decide low current mode's verb & parameter */ 1563 switch (spec->codec_type) { 1564 case VT1708B_8CH: 1565 case VT1708B_4CH: 1566 verb = 0xf70; 1567 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */ 1568 break; 1569 case VT1708S: 1570 case VT1718S: 1571 case VT1716S: 1572 verb = 0xf73; 1573 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */ 1574 break; 1575 case VT1702: 1576 verb = 0xf73; 1577 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */ 1578 break; 1579 case VT2002P: 1580 case VT1812: 1581 verb = 0xf93; 1582 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */ 1583 break; 1584 default: 1585 return; /* other codecs are not supported */ 1586 } 1587 /* send verb */ 1588 snd_hda_codec_write(codec, codec->afg, 0, verb, parm); 1589} 1590 1591/* 1592 * generic initialization of ADC, input mixers and output mixers 1593 */ 1594static struct hda_verb vt1708_volume_init_verbs[] = { 1595 /* 1596 * Unmute ADC0-1 and set the default input to mic-in 1597 */ 1598 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1599 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1600 1601 1602 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 1603 * mixer widget 1604 */ 1605 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 1606 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1607 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1608 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 1609 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 1610 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 1611 1612 /* 1613 * Set up output mixers (0x19 - 0x1b) 1614 */ 1615 /* set vol=0 to output mixers */ 1616 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1617 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1618 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1619 1620 /* Setup default input MW0 to PW4 */ 1621 {0x20, AC_VERB_SET_CONNECT_SEL, 0}, 1622 /* PW9 Output enable */ 1623 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1624 { } 1625}; 1626 1627static int via_playback_pcm_open(struct hda_pcm_stream *hinfo, 1628 struct hda_codec *codec, 1629 struct snd_pcm_substream *substream) 1630{ 1631 struct via_spec *spec = codec->spec; 1632 int idle = substream->pstr->substream_opened == 1 1633 && substream->ref_count == 0; 1634 analog_low_current_mode(codec, idle); 1635 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 1636 hinfo); 1637} 1638 1639static void playback_multi_pcm_prep_0(struct hda_codec *codec, 1640 unsigned int stream_tag, 1641 unsigned int format, 1642 struct snd_pcm_substream *substream) 1643{ 1644 struct via_spec *spec = codec->spec; 1645 struct hda_multi_out *mout = &spec->multiout; 1646 hda_nid_t *nids = mout->dac_nids; 1647 int chs = substream->runtime->channels; 1648 int i; 1649 1650 mutex_lock(&codec->spdif_mutex); 1651 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { 1652 if (chs == 2 && 1653 snd_hda_is_supported_format(codec, mout->dig_out_nid, 1654 format) && 1655 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { 1656 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 1657 /* turn off SPDIF once; otherwise the IEC958 bits won't 1658 * be updated */ 1659 if (codec->spdif_ctls & AC_DIG1_ENABLE) 1660 snd_hda_codec_write(codec, mout->dig_out_nid, 0, 1661 AC_VERB_SET_DIGI_CONVERT_1, 1662 codec->spdif_ctls & 1663 ~AC_DIG1_ENABLE & 0xff); 1664 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 1665 stream_tag, 0, format); 1666 /* turn on again (if needed) */ 1667 if (codec->spdif_ctls & AC_DIG1_ENABLE) 1668 snd_hda_codec_write(codec, mout->dig_out_nid, 0, 1669 AC_VERB_SET_DIGI_CONVERT_1, 1670 codec->spdif_ctls & 0xff); 1671 } else { 1672 mout->dig_out_used = 0; 1673 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 1674 0, 0, 0); 1675 } 1676 } 1677 mutex_unlock(&codec->spdif_mutex); 1678 1679 /* front */ 1680 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 1681 0, format); 1682 1683 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] 1684 && !spec->hp_independent_mode) 1685 /* headphone out will just decode front left/right (stereo) */ 1686 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 1687 0, format); 1688 1689 /* extra outputs copied from front */ 1690 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) 1691 if (mout->extra_out_nid[i]) 1692 snd_hda_codec_setup_stream(codec, 1693 mout->extra_out_nid[i], 1694 stream_tag, 0, format); 1695 1696 /* surrounds */ 1697 for (i = 1; i < mout->num_dacs; i++) { 1698 if (chs >= (i + 1) * 2) /* independent out */ 1699 snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 1700 i * 2, format); 1701 else /* copy front */ 1702 snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 1703 0, format); 1704 } 1705} 1706 1707static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, 1708 struct hda_codec *codec, 1709 unsigned int stream_tag, 1710 unsigned int format, 1711 struct snd_pcm_substream *substream) 1712{ 1713 struct via_spec *spec = codec->spec; 1714 struct hda_multi_out *mout = &spec->multiout; 1715 hda_nid_t *nids = mout->dac_nids; 1716 1717 if (substream->number == 0) 1718 playback_multi_pcm_prep_0(codec, stream_tag, format, 1719 substream); 1720 else { 1721 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && 1722 spec->hp_independent_mode) 1723 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1724 stream_tag, 0, format); 1725 } 1726 vt1708_start_hp_work(spec); 1727 return 0; 1728} 1729 1730static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo, 1731 struct hda_codec *codec, 1732 struct snd_pcm_substream *substream) 1733{ 1734 struct via_spec *spec = codec->spec; 1735 struct hda_multi_out *mout = &spec->multiout; 1736 hda_nid_t *nids = mout->dac_nids; 1737 int i; 1738 1739 if (substream->number == 0) { 1740 for (i = 0; i < mout->num_dacs; i++) 1741 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); 1742 1743 if (mout->hp_nid && !spec->hp_independent_mode) 1744 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1745 0, 0, 0); 1746 1747 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) 1748 if (mout->extra_out_nid[i]) 1749 snd_hda_codec_setup_stream(codec, 1750 mout->extra_out_nid[i], 1751 0, 0, 0); 1752 mutex_lock(&codec->spdif_mutex); 1753 if (mout->dig_out_nid && 1754 mout->dig_out_used == HDA_DIG_ANALOG_DUP) { 1755 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 1756 0, 0, 0); 1757 mout->dig_out_used = 0; 1758 } 1759 mutex_unlock(&codec->spdif_mutex); 1760 } else { 1761 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && 1762 spec->hp_independent_mode) 1763 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1764 0, 0, 0); 1765 } 1766 vt1708_stop_hp_work(spec); 1767 return 0; 1768} 1769 1770/* 1771 * Digital out 1772 */ 1773static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 1774 struct hda_codec *codec, 1775 struct snd_pcm_substream *substream) 1776{ 1777 struct via_spec *spec = codec->spec; 1778 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 1779} 1780 1781static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 1782 struct hda_codec *codec, 1783 struct snd_pcm_substream *substream) 1784{ 1785 struct via_spec *spec = codec->spec; 1786 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 1787} 1788 1789static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 1790 struct hda_codec *codec, 1791 unsigned int stream_tag, 1792 unsigned int format, 1793 struct snd_pcm_substream *substream) 1794{ 1795 struct via_spec *spec = codec->spec; 1796 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 1797 stream_tag, format, substream); 1798} 1799 1800static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 1801 struct hda_codec *codec, 1802 struct snd_pcm_substream *substream) 1803{ 1804 struct via_spec *spec = codec->spec; 1805 snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 1806 return 0; 1807} 1808 1809/* 1810 * Analog capture 1811 */ 1812static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 1813 struct hda_codec *codec, 1814 unsigned int stream_tag, 1815 unsigned int format, 1816 struct snd_pcm_substream *substream) 1817{ 1818 struct via_spec *spec = codec->spec; 1819 1820 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 1821 stream_tag, 0, format); 1822 return 0; 1823} 1824 1825static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 1826 struct hda_codec *codec, 1827 struct snd_pcm_substream *substream) 1828{ 1829 struct via_spec *spec = codec->spec; 1830 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); 1831 return 0; 1832} 1833 1834static struct hda_pcm_stream vt1708_pcm_analog_playback = { 1835 .substreams = 2, 1836 .channels_min = 2, 1837 .channels_max = 8, 1838 .nid = 0x10, /* NID to query formats and rates */ 1839 .ops = { 1840 .open = via_playback_pcm_open, 1841 .prepare = via_playback_multi_pcm_prepare, 1842 .cleanup = via_playback_multi_pcm_cleanup 1843 }, 1844}; 1845 1846static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { 1847 .substreams = 2, 1848 .channels_min = 2, 1849 .channels_max = 8, 1850 .nid = 0x10, /* NID to query formats and rates */ 1851 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1852 .ops = { 1853 .open = via_playback_pcm_open, 1854 .prepare = via_playback_multi_pcm_prepare, 1855 .cleanup = via_playback_multi_pcm_cleanup 1856 }, 1857}; 1858 1859static struct hda_pcm_stream vt1708_pcm_analog_capture = { 1860 .substreams = 2, 1861 .channels_min = 2, 1862 .channels_max = 2, 1863 .nid = 0x15, /* NID to query formats and rates */ 1864 .ops = { 1865 .prepare = via_capture_pcm_prepare, 1866 .cleanup = via_capture_pcm_cleanup 1867 }, 1868}; 1869 1870static struct hda_pcm_stream vt1708_pcm_digital_playback = { 1871 .substreams = 1, 1872 .channels_min = 2, 1873 .channels_max = 2, 1874 /* NID is set in via_build_pcms */ 1875 .ops = { 1876 .open = via_dig_playback_pcm_open, 1877 .close = via_dig_playback_pcm_close, 1878 .prepare = via_dig_playback_pcm_prepare, 1879 .cleanup = via_dig_playback_pcm_cleanup 1880 }, 1881}; 1882 1883static struct hda_pcm_stream vt1708_pcm_digital_capture = { 1884 .substreams = 1, 1885 .channels_min = 2, 1886 .channels_max = 2, 1887}; 1888 1889static int via_build_controls(struct hda_codec *codec) 1890{ 1891 struct via_spec *spec = codec->spec; 1892 struct snd_kcontrol *kctl; 1893 struct snd_kcontrol_new *knew; 1894 int err, i; 1895 1896 for (i = 0; i < spec->num_mixers; i++) { 1897 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1898 if (err < 0) 1899 return err; 1900 } 1901 1902 if (spec->multiout.dig_out_nid) { 1903 err = snd_hda_create_spdif_out_ctls(codec, 1904 spec->multiout.dig_out_nid); 1905 if (err < 0) 1906 return err; 1907 err = snd_hda_create_spdif_share_sw(codec, 1908 &spec->multiout); 1909 if (err < 0) 1910 return err; 1911 spec->multiout.share_spdif = 1; 1912 } 1913 if (spec->dig_in_nid) { 1914 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 1915 if (err < 0) 1916 return err; 1917 } 1918 1919 /* assign Capture Source enums to NID */ 1920 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 1921 for (i = 0; kctl && i < kctl->count; i++) { 1922 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]); 1923 if (err < 0) 1924 return err; 1925 } 1926 1927 /* other nid->control mapping */ 1928 for (i = 0; i < spec->num_mixers; i++) { 1929 for (knew = spec->mixers[i]; knew->name; knew++) { 1930 if (knew->iface != NID_MAPPING) 1931 continue; 1932 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 1933 if (kctl == NULL) 1934 continue; 1935 err = snd_hda_add_nid(codec, kctl, 0, 1936 knew->subdevice); 1937 } 1938 } 1939 1940 /* init power states */ 1941 set_jack_power_state(codec); 1942 analog_low_current_mode(codec, 1); 1943 1944 via_free_kctls(codec); /* no longer needed */ 1945 return 0; 1946} 1947 1948static int via_build_pcms(struct hda_codec *codec) 1949{ 1950 struct via_spec *spec = codec->spec; 1951 struct hda_pcm *info = spec->pcm_rec; 1952 1953 codec->num_pcms = 1; 1954 codec->pcm_info = info; 1955 1956 info->name = spec->stream_name_analog; 1957 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 1958 *(spec->stream_analog_playback); 1959 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 1960 spec->multiout.dac_nids[0]; 1961 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 1962 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 1963 1964 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 1965 spec->multiout.max_channels; 1966 1967 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 1968 codec->num_pcms++; 1969 info++; 1970 info->name = spec->stream_name_digital; 1971 info->pcm_type = HDA_PCM_TYPE_SPDIF; 1972 if (spec->multiout.dig_out_nid) { 1973 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 1974 *(spec->stream_digital_playback); 1975 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 1976 spec->multiout.dig_out_nid; 1977 } 1978 if (spec->dig_in_nid) { 1979 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 1980 *(spec->stream_digital_capture); 1981 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 1982 spec->dig_in_nid; 1983 } 1984 } 1985 1986 return 0; 1987} 1988 1989static void via_free(struct hda_codec *codec) 1990{ 1991 struct via_spec *spec = codec->spec; 1992 1993 if (!spec) 1994 return; 1995 1996 via_free_kctls(codec); 1997 vt1708_stop_hp_work(spec); 1998 kfree(codec->spec); 1999} 2000 2001/* mute internal speaker if HP is plugged */ 2002static void via_hp_automute(struct hda_codec *codec) 2003{ 2004 unsigned int present = 0; 2005 struct via_spec *spec = codec->spec; 2006 2007 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 2008 2009 if (!spec->hp_independent_mode) { 2010 struct snd_ctl_elem_id id; 2011 /* auto mute */ 2012 snd_hda_codec_amp_stereo( 2013 codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0, 2014 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 2015 /* notify change */ 2016 memset(&id, 0, sizeof(id)); 2017 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2018 strcpy(id.name, "Front Playback Switch"); 2019 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE, 2020 &id); 2021 } 2022} 2023 2024/* mute mono out if HP or Line out is plugged */ 2025static void via_mono_automute(struct hda_codec *codec) 2026{ 2027 unsigned int hp_present, lineout_present; 2028 struct via_spec *spec = codec->spec; 2029 2030 if (spec->codec_type != VT1716S) 2031 return; 2032 2033 lineout_present = snd_hda_jack_detect(codec, 2034 spec->autocfg.line_out_pins[0]); 2035 2036 /* Mute Mono Out if Line Out is plugged */ 2037 if (lineout_present) { 2038 snd_hda_codec_amp_stereo( 2039 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE); 2040 return; 2041 } 2042 2043 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 2044 2045 if (!spec->hp_independent_mode) 2046 snd_hda_codec_amp_stereo( 2047 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, 2048 hp_present ? HDA_AMP_MUTE : 0); 2049} 2050 2051static void via_gpio_control(struct hda_codec *codec) 2052{ 2053 unsigned int gpio_data; 2054 unsigned int vol_counter; 2055 unsigned int vol; 2056 unsigned int master_vol; 2057 2058 struct via_spec *spec = codec->spec; 2059 2060 gpio_data = snd_hda_codec_read(codec, codec->afg, 0, 2061 AC_VERB_GET_GPIO_DATA, 0) & 0x03; 2062 2063 vol_counter = (snd_hda_codec_read(codec, codec->afg, 0, 2064 0xF84, 0) & 0x3F0000) >> 16; 2065 2066 vol = vol_counter & 0x1F; 2067 master_vol = snd_hda_codec_read(codec, 0x1A, 0, 2068 AC_VERB_GET_AMP_GAIN_MUTE, 2069 AC_AMP_GET_INPUT); 2070 2071 if (gpio_data == 0x02) { 2072 /* unmute line out */ 2073 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0], 2074 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0); 2075 2076 if (vol_counter & 0x20) { 2077 /* decrease volume */ 2078 if (vol > master_vol) 2079 vol = master_vol; 2080 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 2081 0, HDA_AMP_VOLMASK, 2082 master_vol-vol); 2083 } else { 2084 /* increase volume */ 2085 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0, 2086 HDA_AMP_VOLMASK, 2087 ((master_vol+vol) > 0x2A) ? 0x2A : 2088 (master_vol+vol)); 2089 } 2090 } else if (!(gpio_data & 0x02)) { 2091 /* mute line out */ 2092 snd_hda_codec_amp_stereo(codec, 2093 spec->autocfg.line_out_pins[0], 2094 HDA_OUTPUT, 0, HDA_AMP_MUTE, 2095 HDA_AMP_MUTE); 2096 } 2097} 2098 2099/* mute Internal-Speaker if HP is plugged */ 2100static void via_speaker_automute(struct hda_codec *codec) 2101{ 2102 unsigned int hp_present; 2103 struct via_spec *spec = codec->spec; 2104 2105 if (spec->codec_type != VT2002P && spec->codec_type != VT1812) 2106 return; 2107 2108 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 2109 2110 if (!spec->hp_independent_mode) { 2111 struct snd_ctl_elem_id id; 2112 snd_hda_codec_amp_stereo( 2113 codec, spec->autocfg.speaker_pins[0], HDA_OUTPUT, 0, 2114 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0); 2115 /* notify change */ 2116 memset(&id, 0, sizeof(id)); 2117 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2118 strcpy(id.name, "Speaker Playback Switch"); 2119 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE, 2120 &id); 2121 } 2122} 2123 2124/* mute line-out and internal speaker if HP is plugged */ 2125static void via_hp_bind_automute(struct hda_codec *codec) 2126{ 2127 /* use long instead of int below just to avoid an internal compiler 2128 * error with gcc 4.0.x 2129 */ 2130 unsigned long hp_present, present = 0; 2131 struct via_spec *spec = codec->spec; 2132 int i; 2133 2134 if (!spec->autocfg.hp_pins[0] || !spec->autocfg.line_out_pins[0]) 2135 return; 2136 2137 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 2138 2139 present = snd_hda_jack_detect(codec, spec->autocfg.line_out_pins[0]); 2140 2141 if (!spec->hp_independent_mode) { 2142 /* Mute Line-Outs */ 2143 for (i = 0; i < spec->autocfg.line_outs; i++) 2144 snd_hda_codec_amp_stereo( 2145 codec, spec->autocfg.line_out_pins[i], 2146 HDA_OUTPUT, 0, 2147 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0); 2148 if (hp_present) 2149 present = hp_present; 2150 } 2151 /* Speakers */ 2152 for (i = 0; i < spec->autocfg.speaker_outs; i++) 2153 snd_hda_codec_amp_stereo( 2154 codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0, 2155 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 2156} 2157 2158 2159/* unsolicited event for jack sensing */ 2160static void via_unsol_event(struct hda_codec *codec, 2161 unsigned int res) 2162{ 2163 res >>= 26; 2164 if (res & VIA_HP_EVENT) 2165 via_hp_automute(codec); 2166 if (res & VIA_GPIO_EVENT) 2167 via_gpio_control(codec); 2168 if (res & VIA_JACK_EVENT) 2169 set_jack_power_state(codec); 2170 if (res & VIA_MONO_EVENT) 2171 via_mono_automute(codec); 2172 if (res & VIA_SPEAKER_EVENT) 2173 via_speaker_automute(codec); 2174 if (res & VIA_BIND_HP_EVENT) 2175 via_hp_bind_automute(codec); 2176} 2177 2178static int via_init(struct hda_codec *codec) 2179{ 2180 struct via_spec *spec = codec->spec; 2181 int i; 2182 for (i = 0; i < spec->num_iverbs; i++) 2183 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2184 2185 spec->codec_type = get_codec_type(codec); 2186 if (spec->codec_type == VT1708BCE) 2187 spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost 2188 same */ 2189 /* Lydia Add for EAPD enable */ 2190 if (!spec->dig_in_nid) { /* No Digital In connection */ 2191 if (spec->dig_in_pin) { 2192 snd_hda_codec_write(codec, spec->dig_in_pin, 0, 2193 AC_VERB_SET_PIN_WIDGET_CONTROL, 2194 PIN_OUT); 2195 snd_hda_codec_write(codec, spec->dig_in_pin, 0, 2196 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 2197 } 2198 } else /* enable SPDIF-input pin */ 2199 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0, 2200 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); 2201 2202 /* assign slave outs */ 2203 if (spec->slave_dig_outs[0]) 2204 codec->slave_dig_outs = spec->slave_dig_outs; 2205 2206 return 0; 2207} 2208 2209#ifdef SND_HDA_NEEDS_RESUME 2210static int via_suspend(struct hda_codec *codec, pm_message_t state) 2211{ 2212 struct via_spec *spec = codec->spec; 2213 vt1708_stop_hp_work(spec); 2214 return 0; 2215} 2216#endif 2217 2218#ifdef CONFIG_SND_HDA_POWER_SAVE 2219static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2220{ 2221 struct via_spec *spec = codec->spec; 2222 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 2223} 2224#endif 2225 2226/* 2227 */ 2228static struct hda_codec_ops via_patch_ops = { 2229 .build_controls = via_build_controls, 2230 .build_pcms = via_build_pcms, 2231 .init = via_init, 2232 .free = via_free, 2233#ifdef SND_HDA_NEEDS_RESUME 2234 .suspend = via_suspend, 2235#endif 2236#ifdef CONFIG_SND_HDA_POWER_SAVE 2237 .check_power_status = via_check_power_status, 2238#endif 2239}; 2240 2241/* fill in the dac_nids table from the parsed pin configuration */ 2242static int vt1708_auto_fill_dac_nids(struct via_spec *spec, 2243 const struct auto_pin_cfg *cfg) 2244{ 2245 int i; 2246 hda_nid_t nid; 2247 2248 spec->multiout.num_dacs = cfg->line_outs; 2249 2250 spec->multiout.dac_nids = spec->private_dac_nids; 2251 2252 for (i = 0; i < 4; i++) { 2253 nid = cfg->line_out_pins[i]; 2254 if (nid) { 2255 /* config dac list */ 2256 switch (i) { 2257 case AUTO_SEQ_FRONT: 2258 spec->multiout.dac_nids[i] = 0x10; 2259 break; 2260 case AUTO_SEQ_CENLFE: 2261 spec->multiout.dac_nids[i] = 0x12; 2262 break; 2263 case AUTO_SEQ_SURROUND: 2264 spec->multiout.dac_nids[i] = 0x11; 2265 break; 2266 case AUTO_SEQ_SIDE: 2267 spec->multiout.dac_nids[i] = 0x13; 2268 break; 2269 } 2270 } 2271 } 2272 2273 return 0; 2274} 2275 2276/* add playback controls from the parsed DAC table */ 2277static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, 2278 const struct auto_pin_cfg *cfg) 2279{ 2280 char name[32]; 2281 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 2282 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b}; 2283 int i, err; 2284 2285 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 2286 nid = cfg->line_out_pins[i]; 2287 2288 if (!nid) 2289 continue; 2290 2291 nid_vol = nid_vols[i]; 2292 2293 if (i == AUTO_SEQ_CENLFE) { 2294 /* Center/LFE */ 2295 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2296 "Center Playback Volume", 2297 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 2298 HDA_OUTPUT)); 2299 if (err < 0) 2300 return err; 2301 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2302 "LFE Playback Volume", 2303 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 2304 HDA_OUTPUT)); 2305 if (err < 0) 2306 return err; 2307 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2308 "Center Playback Switch", 2309 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 2310 HDA_OUTPUT)); 2311 if (err < 0) 2312 return err; 2313 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2314 "LFE Playback Switch", 2315 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 2316 HDA_OUTPUT)); 2317 if (err < 0) 2318 return err; 2319 } else if (i == AUTO_SEQ_FRONT) { 2320 /* add control to mixer index 0 */ 2321 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2322 "Master Front Playback Volume", 2323 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 2324 HDA_INPUT)); 2325 if (err < 0) 2326 return err; 2327 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2328 "Master Front Playback Switch", 2329 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 2330 HDA_INPUT)); 2331 if (err < 0) 2332 return err; 2333 2334 /* add control to PW3 */ 2335 sprintf(name, "%s Playback Volume", chname[i]); 2336 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2337 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 2338 HDA_OUTPUT)); 2339 if (err < 0) 2340 return err; 2341 sprintf(name, "%s Playback Switch", chname[i]); 2342 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 2343 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 2344 HDA_OUTPUT)); 2345 if (err < 0) 2346 return err; 2347 } else { 2348 sprintf(name, "%s Playback Volume", chname[i]); 2349 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2350 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 2351 HDA_OUTPUT)); 2352 if (err < 0) 2353 return err; 2354 sprintf(name, "%s Playback Switch", chname[i]); 2355 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 2356 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 2357 HDA_OUTPUT)); 2358 if (err < 0) 2359 return err; 2360 } 2361 } 2362 2363 return 0; 2364} 2365 2366static void create_hp_imux(struct via_spec *spec) 2367{ 2368 int i; 2369 struct hda_input_mux *imux = &spec->private_imux[1]; 2370 static const char *texts[] = { "OFF", "ON", NULL}; 2371 2372 /* for hp mode select */ 2373 i = 0; 2374 while (texts[i] != NULL) { 2375 imux->items[imux->num_items].label = texts[i]; 2376 imux->items[imux->num_items].index = i; 2377 imux->num_items++; 2378 i++; 2379 } 2380 2381 spec->hp_mux = &spec->private_imux[1]; 2382} 2383 2384static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 2385{ 2386 int err; 2387 2388 if (!pin) 2389 return 0; 2390 2391 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */ 2392 spec->hp_independent_mode_index = 1; 2393 2394 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2395 "Headphone Playback Volume", 2396 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 2397 if (err < 0) 2398 return err; 2399 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2400 "Headphone Playback Switch", 2401 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 2402 if (err < 0) 2403 return err; 2404 2405 create_hp_imux(spec); 2406 2407 return 0; 2408} 2409 2410/* create playback/capture controls for input pins */ 2411static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec, 2412 const struct auto_pin_cfg *cfg) 2413{ 2414 static char *labels[] = { 2415 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 2416 }; 2417 struct hda_input_mux *imux = &spec->private_imux[0]; 2418 int i, err, idx = 0; 2419 2420 /* for internal loopback recording select */ 2421 imux->items[imux->num_items].label = "Stereo Mixer"; 2422 imux->items[imux->num_items].index = idx; 2423 imux->num_items++; 2424 2425 for (i = 0; i < AUTO_PIN_LAST; i++) { 2426 if (!cfg->input_pins[i]) 2427 continue; 2428 2429 switch (cfg->input_pins[i]) { 2430 case 0x1d: /* Mic */ 2431 idx = 2; 2432 break; 2433 2434 case 0x1e: /* Line In */ 2435 idx = 3; 2436 break; 2437 2438 case 0x21: /* Front Mic */ 2439 idx = 4; 2440 break; 2441 2442 case 0x24: /* CD */ 2443 idx = 1; 2444 break; 2445 } 2446 err = via_new_analog_input(spec, labels[i], idx, 0x17); 2447 if (err < 0) 2448 return err; 2449 imux->items[imux->num_items].label = labels[i]; 2450 imux->items[imux->num_items].index = idx; 2451 imux->num_items++; 2452 } 2453 return 0; 2454} 2455 2456#ifdef CONFIG_SND_HDA_POWER_SAVE 2457static struct hda_amp_list vt1708_loopbacks[] = { 2458 { 0x17, HDA_INPUT, 1 }, 2459 { 0x17, HDA_INPUT, 2 }, 2460 { 0x17, HDA_INPUT, 3 }, 2461 { 0x17, HDA_INPUT, 4 }, 2462 { } /* end */ 2463}; 2464#endif 2465 2466static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid) 2467{ 2468 unsigned int def_conf; 2469 unsigned char seqassoc; 2470 2471 def_conf = snd_hda_codec_get_pincfg(codec, nid); 2472 seqassoc = (unsigned char) get_defcfg_association(def_conf); 2473 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf); 2474 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE 2475 && (seqassoc == 0xf0 || seqassoc == 0xff)) { 2476 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30)); 2477 snd_hda_codec_set_pincfg(codec, nid, def_conf); 2478 } 2479 2480 return; 2481} 2482 2483static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol, 2484 struct snd_ctl_elem_value *ucontrol) 2485{ 2486 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2487 struct via_spec *spec = codec->spec; 2488 2489 if (spec->codec_type != VT1708) 2490 return 0; 2491 spec->vt1708_jack_detectect = 2492 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1); 2493 ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect; 2494 return 0; 2495} 2496 2497static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol, 2498 struct snd_ctl_elem_value *ucontrol) 2499{ 2500 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2501 struct via_spec *spec = codec->spec; 2502 int change; 2503 2504 if (spec->codec_type != VT1708) 2505 return 0; 2506 spec->vt1708_jack_detectect = ucontrol->value.integer.value[0]; 2507 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8)) 2508 == !spec->vt1708_jack_detectect; 2509 if (spec->vt1708_jack_detectect) { 2510 mute_aa_path(codec, 1); 2511 notify_aa_path_ctls(codec); 2512 } 2513 return change; 2514} 2515 2516static struct snd_kcontrol_new vt1708_jack_detectect[] = { 2517 { 2518 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2519 .name = "Jack Detect", 2520 .count = 1, 2521 .info = snd_ctl_boolean_mono_info, 2522 .get = vt1708_jack_detectect_get, 2523 .put = vt1708_jack_detectect_put, 2524 }, 2525 {} /* end */ 2526}; 2527 2528static int vt1708_parse_auto_config(struct hda_codec *codec) 2529{ 2530 struct via_spec *spec = codec->spec; 2531 int err; 2532 2533 /* Add HP and CD pin config connect bit re-config action */ 2534 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID); 2535 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID); 2536 2537 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 2538 if (err < 0) 2539 return err; 2540 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg); 2541 if (err < 0) 2542 return err; 2543 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 2544 return 0; /* can't find valid BIOS pin config */ 2545 2546 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg); 2547 if (err < 0) 2548 return err; 2549 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 2550 if (err < 0) 2551 return err; 2552 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg); 2553 if (err < 0) 2554 return err; 2555 /* add jack detect on/off control */ 2556 err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect); 2557 if (err < 0) 2558 return err; 2559 2560 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 2561 2562 if (spec->autocfg.dig_outs) 2563 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; 2564 spec->dig_in_pin = VT1708_DIGIN_PIN; 2565 if (spec->autocfg.dig_in_pin) 2566 spec->dig_in_nid = VT1708_DIGIN_NID; 2567 2568 if (spec->kctls.list) 2569 spec->mixers[spec->num_mixers++] = spec->kctls.list; 2570 2571 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs; 2572 2573 spec->input_mux = &spec->private_imux[0]; 2574 2575 if (spec->hp_mux) 2576 via_hp_build(codec); 2577 2578 via_smart51_build(spec); 2579 return 1; 2580} 2581 2582/* init callback for auto-configuration model -- overriding the default init */ 2583static int via_auto_init(struct hda_codec *codec) 2584{ 2585 struct via_spec *spec = codec->spec; 2586 2587 via_init(codec); 2588 via_auto_init_multi_out(codec); 2589 via_auto_init_hp_out(codec); 2590 via_auto_init_analog_input(codec); 2591 if (spec->codec_type == VT2002P || spec->codec_type == VT1812) { 2592 via_hp_bind_automute(codec); 2593 } else { 2594 via_hp_automute(codec); 2595 via_speaker_automute(codec); 2596 } 2597 2598 return 0; 2599} 2600 2601static void vt1708_update_hp_jack_state(struct work_struct *work) 2602{ 2603 struct via_spec *spec = container_of(work, struct via_spec, 2604 vt1708_hp_work.work); 2605 if (spec->codec_type != VT1708) 2606 return; 2607 /* if jack state toggled */ 2608 if (spec->vt1708_hp_present 2609 != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) { 2610 spec->vt1708_hp_present ^= 1; 2611 via_hp_automute(spec->codec); 2612 } 2613 vt1708_start_hp_work(spec); 2614} 2615 2616static int get_mux_nids(struct hda_codec *codec) 2617{ 2618 struct via_spec *spec = codec->spec; 2619 hda_nid_t nid, conn[8]; 2620 unsigned int type; 2621 int i, n; 2622 2623 for (i = 0; i < spec->num_adc_nids; i++) { 2624 nid = spec->adc_nids[i]; 2625 while (nid) { 2626 type = get_wcaps_type(get_wcaps(codec, nid)); 2627 if (type == AC_WID_PIN) 2628 break; 2629 n = snd_hda_get_connections(codec, nid, conn, 2630 ARRAY_SIZE(conn)); 2631 if (n <= 0) 2632 break; 2633 if (n > 1) { 2634 spec->mux_nids[i] = nid; 2635 break; 2636 } 2637 nid = conn[0]; 2638 } 2639 } 2640 return 0; 2641} 2642 2643static int patch_vt1708(struct hda_codec *codec) 2644{ 2645 struct via_spec *spec; 2646 int err; 2647 2648 /* create a codec specific record */ 2649 spec = via_new_spec(codec); 2650 if (spec == NULL) 2651 return -ENOMEM; 2652 2653 /* automatic parse from the BIOS config */ 2654 err = vt1708_parse_auto_config(codec); 2655 if (err < 0) { 2656 via_free(codec); 2657 return err; 2658 } else if (!err) { 2659 printk(KERN_INFO "hda_codec: Cannot set up configuration " 2660 "from BIOS. Using genenic mode...\n"); 2661 } 2662 2663 2664 spec->stream_name_analog = "VT1708 Analog"; 2665 spec->stream_analog_playback = &vt1708_pcm_analog_playback; 2666 /* disable 32bit format on VT1708 */ 2667 if (codec->vendor_id == 0x11061708) 2668 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback; 2669 spec->stream_analog_capture = &vt1708_pcm_analog_capture; 2670 2671 spec->stream_name_digital = "VT1708 Digital"; 2672 spec->stream_digital_playback = &vt1708_pcm_digital_playback; 2673 spec->stream_digital_capture = &vt1708_pcm_digital_capture; 2674 2675 2676 if (!spec->adc_nids && spec->input_mux) { 2677 spec->adc_nids = vt1708_adc_nids; 2678 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids); 2679 get_mux_nids(codec); 2680 spec->mixers[spec->num_mixers] = vt1708_capture_mixer; 2681 spec->num_mixers++; 2682 } 2683 2684 codec->patch_ops = via_patch_ops; 2685 2686 codec->patch_ops.init = via_auto_init; 2687#ifdef CONFIG_SND_HDA_POWER_SAVE 2688 spec->loopback.amplist = vt1708_loopbacks; 2689#endif 2690 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); 2691 return 0; 2692} 2693 2694/* capture mixer elements */ 2695static struct snd_kcontrol_new vt1709_capture_mixer[] = { 2696 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT), 2697 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT), 2698 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT), 2699 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT), 2700 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT), 2701 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT), 2702 { 2703 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2704 /* The multiple "Capture Source" controls confuse alsamixer 2705 * So call somewhat different.. 2706 */ 2707 /* .name = "Capture Source", */ 2708 .name = "Input Source", 2709 .count = 1, 2710 .info = via_mux_enum_info, 2711 .get = via_mux_enum_get, 2712 .put = via_mux_enum_put, 2713 }, 2714 { } /* end */ 2715}; 2716 2717static struct hda_verb vt1709_uniwill_init_verbs[] = { 2718 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 2719 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 2720 { } 2721}; 2722 2723/* 2724 * generic initialization of ADC, input mixers and output mixers 2725 */ 2726static struct hda_verb vt1709_10ch_volume_init_verbs[] = { 2727 /* 2728 * Unmute ADC0-2 and set the default input to mic-in 2729 */ 2730 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2731 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2732 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2733 2734 2735 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 2736 * mixer widget 2737 */ 2738 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 2739 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2740 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2741 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 2742 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 2743 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 2744 2745 /* 2746 * Set up output selector (0x1a, 0x1b, 0x29) 2747 */ 2748 /* set vol=0 to output mixers */ 2749 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2750 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2751 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2752 2753 /* 2754 * Unmute PW3 and PW4 2755 */ 2756 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2757 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2758 2759 /* Set input of PW4 as MW0 */ 2760 {0x20, AC_VERB_SET_CONNECT_SEL, 0}, 2761 /* PW9 Output enable */ 2762 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 2763 { } 2764}; 2765 2766static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { 2767 .substreams = 1, 2768 .channels_min = 2, 2769 .channels_max = 10, 2770 .nid = 0x10, /* NID to query formats and rates */ 2771 .ops = { 2772 .open = via_playback_pcm_open, 2773 .prepare = via_playback_multi_pcm_prepare, 2774 .cleanup = via_playback_multi_pcm_cleanup, 2775 }, 2776}; 2777 2778static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { 2779 .substreams = 1, 2780 .channels_min = 2, 2781 .channels_max = 6, 2782 .nid = 0x10, /* NID to query formats and rates */ 2783 .ops = { 2784 .open = via_playback_pcm_open, 2785 .prepare = via_playback_multi_pcm_prepare, 2786 .cleanup = via_playback_multi_pcm_cleanup, 2787 }, 2788}; 2789 2790static struct hda_pcm_stream vt1709_pcm_analog_capture = { 2791 .substreams = 2, 2792 .channels_min = 2, 2793 .channels_max = 2, 2794 .nid = 0x14, /* NID to query formats and rates */ 2795 .ops = { 2796 .prepare = via_capture_pcm_prepare, 2797 .cleanup = via_capture_pcm_cleanup 2798 }, 2799}; 2800 2801static struct hda_pcm_stream vt1709_pcm_digital_playback = { 2802 .substreams = 1, 2803 .channels_min = 2, 2804 .channels_max = 2, 2805 /* NID is set in via_build_pcms */ 2806 .ops = { 2807 .open = via_dig_playback_pcm_open, 2808 .close = via_dig_playback_pcm_close 2809 }, 2810}; 2811 2812static struct hda_pcm_stream vt1709_pcm_digital_capture = { 2813 .substreams = 1, 2814 .channels_min = 2, 2815 .channels_max = 2, 2816}; 2817 2818static int vt1709_auto_fill_dac_nids(struct via_spec *spec, 2819 const struct auto_pin_cfg *cfg) 2820{ 2821 int i; 2822 hda_nid_t nid; 2823 2824 if (cfg->line_outs == 4) /* 10 channels */ 2825 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */ 2826 else if (cfg->line_outs == 3) /* 6 channels */ 2827 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */ 2828 2829 spec->multiout.dac_nids = spec->private_dac_nids; 2830 2831 if (cfg->line_outs == 4) { /* 10 channels */ 2832 for (i = 0; i < cfg->line_outs; i++) { 2833 nid = cfg->line_out_pins[i]; 2834 if (nid) { 2835 /* config dac list */ 2836 switch (i) { 2837 case AUTO_SEQ_FRONT: 2838 /* AOW0 */ 2839 spec->multiout.dac_nids[i] = 0x10; 2840 break; 2841 case AUTO_SEQ_CENLFE: 2842 /* AOW2 */ 2843 spec->multiout.dac_nids[i] = 0x12; 2844 break; 2845 case AUTO_SEQ_SURROUND: 2846 /* AOW3 */ 2847 spec->multiout.dac_nids[i] = 0x11; 2848 break; 2849 case AUTO_SEQ_SIDE: 2850 /* AOW1 */ 2851 spec->multiout.dac_nids[i] = 0x27; 2852 break; 2853 default: 2854 break; 2855 } 2856 } 2857 } 2858 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ 2859 2860 } else if (cfg->line_outs == 3) { /* 6 channels */ 2861 for (i = 0; i < cfg->line_outs; i++) { 2862 nid = cfg->line_out_pins[i]; 2863 if (nid) { 2864 /* config dac list */ 2865 switch (i) { 2866 case AUTO_SEQ_FRONT: 2867 /* AOW0 */ 2868 spec->multiout.dac_nids[i] = 0x10; 2869 break; 2870 case AUTO_SEQ_CENLFE: 2871 /* AOW2 */ 2872 spec->multiout.dac_nids[i] = 0x12; 2873 break; 2874 case AUTO_SEQ_SURROUND: 2875 /* AOW1 */ 2876 spec->multiout.dac_nids[i] = 0x11; 2877 break; 2878 default: 2879 break; 2880 } 2881 } 2882 } 2883 } 2884 2885 return 0; 2886} 2887 2888/* add playback controls from the parsed DAC table */ 2889static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec, 2890 const struct auto_pin_cfg *cfg) 2891{ 2892 char name[32]; 2893 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 2894 hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29}; 2895 int i, err; 2896 2897 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 2898 nid = cfg->line_out_pins[i]; 2899 2900 if (!nid) 2901 continue; 2902 2903 nid_vol = nid_vols[i]; 2904 2905 if (i == AUTO_SEQ_CENLFE) { 2906 /* Center/LFE */ 2907 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2908 "Center Playback Volume", 2909 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 2910 HDA_OUTPUT)); 2911 if (err < 0) 2912 return err; 2913 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2914 "LFE Playback Volume", 2915 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 2916 HDA_OUTPUT)); 2917 if (err < 0) 2918 return err; 2919 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2920 "Center Playback Switch", 2921 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 2922 HDA_OUTPUT)); 2923 if (err < 0) 2924 return err; 2925 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2926 "LFE Playback Switch", 2927 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 2928 HDA_OUTPUT)); 2929 if (err < 0) 2930 return err; 2931 } else if (i == AUTO_SEQ_FRONT) { 2932 /* ADD control to mixer index 0 */ 2933 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2934 "Master Front Playback Volume", 2935 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 2936 HDA_INPUT)); 2937 if (err < 0) 2938 return err; 2939 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2940 "Master Front Playback Switch", 2941 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 2942 HDA_INPUT)); 2943 if (err < 0) 2944 return err; 2945 2946 /* add control to PW3 */ 2947 sprintf(name, "%s Playback Volume", chname[i]); 2948 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2949 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 2950 HDA_OUTPUT)); 2951 if (err < 0) 2952 return err; 2953 sprintf(name, "%s Playback Switch", chname[i]); 2954 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 2955 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 2956 HDA_OUTPUT)); 2957 if (err < 0) 2958 return err; 2959 } else if (i == AUTO_SEQ_SURROUND) { 2960 sprintf(name, "%s Playback Volume", chname[i]); 2961 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2962 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 2963 HDA_OUTPUT)); 2964 if (err < 0) 2965 return err; 2966 sprintf(name, "%s Playback Switch", chname[i]); 2967 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 2968 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 2969 HDA_OUTPUT)); 2970 if (err < 0) 2971 return err; 2972 } else if (i == AUTO_SEQ_SIDE) { 2973 sprintf(name, "%s Playback Volume", chname[i]); 2974 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2975 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 2976 HDA_OUTPUT)); 2977 if (err < 0) 2978 return err; 2979 sprintf(name, "%s Playback Switch", chname[i]); 2980 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 2981 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 2982 HDA_OUTPUT)); 2983 if (err < 0) 2984 return err; 2985 } 2986 } 2987 2988 return 0; 2989} 2990 2991static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 2992{ 2993 int err; 2994 2995 if (!pin) 2996 return 0; 2997 2998 if (spec->multiout.num_dacs == 5) /* 10 channels */ 2999 spec->multiout.hp_nid = VT1709_HP_DAC_NID; 3000 else if (spec->multiout.num_dacs == 3) /* 6 channels */ 3001 spec->multiout.hp_nid = 0; 3002 spec->hp_independent_mode_index = 1; 3003 3004 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3005 "Headphone Playback Volume", 3006 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3007 if (err < 0) 3008 return err; 3009 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 3010 "Headphone Playback Switch", 3011 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3012 if (err < 0) 3013 return err; 3014 3015 return 0; 3016} 3017 3018/* create playback/capture controls for input pins */ 3019static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec, 3020 const struct auto_pin_cfg *cfg) 3021{ 3022 static char *labels[] = { 3023 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 3024 }; 3025 struct hda_input_mux *imux = &spec->private_imux[0]; 3026 int i, err, idx = 0; 3027 3028 /* for internal loopback recording select */ 3029 imux->items[imux->num_items].label = "Stereo Mixer"; 3030 imux->items[imux->num_items].index = idx; 3031 imux->num_items++; 3032 3033 for (i = 0; i < AUTO_PIN_LAST; i++) { 3034 if (!cfg->input_pins[i]) 3035 continue; 3036 3037 switch (cfg->input_pins[i]) { 3038 case 0x1d: /* Mic */ 3039 idx = 2; 3040 break; 3041 3042 case 0x1e: /* Line In */ 3043 idx = 3; 3044 break; 3045 3046 case 0x21: /* Front Mic */ 3047 idx = 4; 3048 break; 3049 3050 case 0x23: /* CD */ 3051 idx = 1; 3052 break; 3053 } 3054 err = via_new_analog_input(spec, labels[i], idx, 0x18); 3055 if (err < 0) 3056 return err; 3057 imux->items[imux->num_items].label = labels[i]; 3058 imux->items[imux->num_items].index = idx; 3059 imux->num_items++; 3060 } 3061 return 0; 3062} 3063 3064static int vt1709_parse_auto_config(struct hda_codec *codec) 3065{ 3066 struct via_spec *spec = codec->spec; 3067 int err; 3068 3069 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 3070 if (err < 0) 3071 return err; 3072 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg); 3073 if (err < 0) 3074 return err; 3075 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 3076 return 0; /* can't find valid BIOS pin config */ 3077 3078 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg); 3079 if (err < 0) 3080 return err; 3081 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 3082 if (err < 0) 3083 return err; 3084 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg); 3085 if (err < 0) 3086 return err; 3087 3088 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3089 3090 if (spec->autocfg.dig_outs) 3091 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID; 3092 spec->dig_in_pin = VT1709_DIGIN_PIN; 3093 if (spec->autocfg.dig_in_pin) 3094 spec->dig_in_nid = VT1709_DIGIN_NID; 3095 3096 if (spec->kctls.list) 3097 spec->mixers[spec->num_mixers++] = spec->kctls.list; 3098 3099 spec->input_mux = &spec->private_imux[0]; 3100 3101 if (spec->hp_mux) 3102 via_hp_build(codec); 3103 3104 via_smart51_build(spec); 3105 return 1; 3106} 3107 3108#ifdef CONFIG_SND_HDA_POWER_SAVE 3109static struct hda_amp_list vt1709_loopbacks[] = { 3110 { 0x18, HDA_INPUT, 1 }, 3111 { 0x18, HDA_INPUT, 2 }, 3112 { 0x18, HDA_INPUT, 3 }, 3113 { 0x18, HDA_INPUT, 4 }, 3114 { } /* end */ 3115}; 3116#endif 3117 3118static int patch_vt1709_10ch(struct hda_codec *codec) 3119{ 3120 struct via_spec *spec; 3121 int err; 3122 3123 /* create a codec specific record */ 3124 spec = via_new_spec(codec); 3125 if (spec == NULL) 3126 return -ENOMEM; 3127 3128 err = vt1709_parse_auto_config(codec); 3129 if (err < 0) { 3130 via_free(codec); 3131 return err; 3132 } else if (!err) { 3133 printk(KERN_INFO "hda_codec: Cannot set up configuration. " 3134 "Using genenic mode...\n"); 3135 } 3136 3137 spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs; 3138 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs; 3139 3140 spec->stream_name_analog = "VT1709 Analog"; 3141 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback; 3142 spec->stream_analog_capture = &vt1709_pcm_analog_capture; 3143 3144 spec->stream_name_digital = "VT1709 Digital"; 3145 spec->stream_digital_playback = &vt1709_pcm_digital_playback; 3146 spec->stream_digital_capture = &vt1709_pcm_digital_capture; 3147 3148 3149 if (!spec->adc_nids && spec->input_mux) { 3150 spec->adc_nids = vt1709_adc_nids; 3151 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); 3152 get_mux_nids(codec); 3153 spec->mixers[spec->num_mixers] = vt1709_capture_mixer; 3154 spec->num_mixers++; 3155 } 3156 3157 codec->patch_ops = via_patch_ops; 3158 3159 codec->patch_ops.init = via_auto_init; 3160 codec->patch_ops.unsol_event = via_unsol_event; 3161#ifdef CONFIG_SND_HDA_POWER_SAVE 3162 spec->loopback.amplist = vt1709_loopbacks; 3163#endif 3164 3165 return 0; 3166} 3167/* 3168 * generic initialization of ADC, input mixers and output mixers 3169 */ 3170static struct hda_verb vt1709_6ch_volume_init_verbs[] = { 3171 /* 3172 * Unmute ADC0-2 and set the default input to mic-in 3173 */ 3174 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3176 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3177 3178 3179 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 3180 * mixer widget 3181 */ 3182 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 3183 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3184 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3185 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 3186 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 3187 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 3188 3189 /* 3190 * Set up output selector (0x1a, 0x1b, 0x29) 3191 */ 3192 /* set vol=0 to output mixers */ 3193 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3194 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3195 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3196 3197 /* 3198 * Unmute PW3 and PW4 3199 */ 3200 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3201 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3202 3203 /* Set input of PW4 as MW0 */ 3204 {0x20, AC_VERB_SET_CONNECT_SEL, 0}, 3205 /* PW9 Output enable */ 3206 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3207 { } 3208}; 3209 3210static int patch_vt1709_6ch(struct hda_codec *codec) 3211{ 3212 struct via_spec *spec; 3213 int err; 3214 3215 /* create a codec specific record */ 3216 spec = via_new_spec(codec); 3217 if (spec == NULL) 3218 return -ENOMEM; 3219 3220 err = vt1709_parse_auto_config(codec); 3221 if (err < 0) { 3222 via_free(codec); 3223 return err; 3224 } else if (!err) { 3225 printk(KERN_INFO "hda_codec: Cannot set up configuration. " 3226 "Using genenic mode...\n"); 3227 } 3228 3229 spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs; 3230 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs; 3231 3232 spec->stream_name_analog = "VT1709 Analog"; 3233 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback; 3234 spec->stream_analog_capture = &vt1709_pcm_analog_capture; 3235 3236 spec->stream_name_digital = "VT1709 Digital"; 3237 spec->stream_digital_playback = &vt1709_pcm_digital_playback; 3238 spec->stream_digital_capture = &vt1709_pcm_digital_capture; 3239 3240 3241 if (!spec->adc_nids && spec->input_mux) { 3242 spec->adc_nids = vt1709_adc_nids; 3243 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); 3244 get_mux_nids(codec); 3245 spec->mixers[spec->num_mixers] = vt1709_capture_mixer; 3246 spec->num_mixers++; 3247 } 3248 3249 codec->patch_ops = via_patch_ops; 3250 3251 codec->patch_ops.init = via_auto_init; 3252 codec->patch_ops.unsol_event = via_unsol_event; 3253#ifdef CONFIG_SND_HDA_POWER_SAVE 3254 spec->loopback.amplist = vt1709_loopbacks; 3255#endif 3256 return 0; 3257} 3258 3259/* capture mixer elements */ 3260static struct snd_kcontrol_new vt1708B_capture_mixer[] = { 3261 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 3262 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 3263 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 3264 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT), 3265 { 3266 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3267 /* The multiple "Capture Source" controls confuse alsamixer 3268 * So call somewhat different.. 3269 */ 3270 /* .name = "Capture Source", */ 3271 .name = "Input Source", 3272 .count = 1, 3273 .info = via_mux_enum_info, 3274 .get = via_mux_enum_get, 3275 .put = via_mux_enum_put, 3276 }, 3277 { } /* end */ 3278}; 3279/* 3280 * generic initialization of ADC, input mixers and output mixers 3281 */ 3282static struct hda_verb vt1708B_8ch_volume_init_verbs[] = { 3283 /* 3284 * Unmute ADC0-1 and set the default input to mic-in 3285 */ 3286 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3287 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3288 3289 3290 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 3291 * mixer widget 3292 */ 3293 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 3294 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3295 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3296 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 3297 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 3298 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 3299 3300 /* 3301 * Set up output mixers 3302 */ 3303 /* set vol=0 to output mixers */ 3304 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3305 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3306 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3307 3308 /* Setup default input to PW4 */ 3309 {0x1d, AC_VERB_SET_CONNECT_SEL, 0}, 3310 /* PW9 Output enable */ 3311 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3312 /* PW10 Input enable */ 3313 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3314 { } 3315}; 3316 3317static struct hda_verb vt1708B_4ch_volume_init_verbs[] = { 3318 /* 3319 * Unmute ADC0-1 and set the default input to mic-in 3320 */ 3321 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3322 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3323 3324 3325 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 3326 * mixer widget 3327 */ 3328 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 3329 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3330 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3331 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 3332 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 3333 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 3334 3335 /* 3336 * Set up output mixers 3337 */ 3338 /* set vol=0 to output mixers */ 3339 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3340 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3341 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3342 3343 /* Setup default input of PW4 to MW0 */ 3344 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0}, 3345 /* PW9 Output enable */ 3346 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3347 /* PW10 Input enable */ 3348 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 3349 { } 3350}; 3351 3352static struct hda_verb vt1708B_uniwill_init_verbs[] = { 3353 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 3354 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 3355 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3356 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3357 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3358 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3359 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3360 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3361 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3362 { } 3363}; 3364 3365static int via_pcm_open_close(struct hda_pcm_stream *hinfo, 3366 struct hda_codec *codec, 3367 struct snd_pcm_substream *substream) 3368{ 3369 int idle = substream->pstr->substream_opened == 1 3370 && substream->ref_count == 0; 3371 3372 analog_low_current_mode(codec, idle); 3373 return 0; 3374} 3375 3376static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { 3377 .substreams = 2, 3378 .channels_min = 2, 3379 .channels_max = 8, 3380 .nid = 0x10, /* NID to query formats and rates */ 3381 .ops = { 3382 .open = via_playback_pcm_open, 3383 .prepare = via_playback_multi_pcm_prepare, 3384 .cleanup = via_playback_multi_pcm_cleanup, 3385 .close = via_pcm_open_close 3386 }, 3387}; 3388 3389static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { 3390 .substreams = 2, 3391 .channels_min = 2, 3392 .channels_max = 4, 3393 .nid = 0x10, /* NID to query formats and rates */ 3394 .ops = { 3395 .open = via_playback_pcm_open, 3396 .prepare = via_playback_multi_pcm_prepare, 3397 .cleanup = via_playback_multi_pcm_cleanup 3398 }, 3399}; 3400 3401static struct hda_pcm_stream vt1708B_pcm_analog_capture = { 3402 .substreams = 2, 3403 .channels_min = 2, 3404 .channels_max = 2, 3405 .nid = 0x13, /* NID to query formats and rates */ 3406 .ops = { 3407 .open = via_pcm_open_close, 3408 .prepare = via_capture_pcm_prepare, 3409 .cleanup = via_capture_pcm_cleanup, 3410 .close = via_pcm_open_close 3411 }, 3412}; 3413 3414static struct hda_pcm_stream vt1708B_pcm_digital_playback = { 3415 .substreams = 1, 3416 .channels_min = 2, 3417 .channels_max = 2, 3418 /* NID is set in via_build_pcms */ 3419 .ops = { 3420 .open = via_dig_playback_pcm_open, 3421 .close = via_dig_playback_pcm_close, 3422 .prepare = via_dig_playback_pcm_prepare, 3423 .cleanup = via_dig_playback_pcm_cleanup 3424 }, 3425}; 3426 3427static struct hda_pcm_stream vt1708B_pcm_digital_capture = { 3428 .substreams = 1, 3429 .channels_min = 2, 3430 .channels_max = 2, 3431}; 3432 3433/* fill in the dac_nids table from the parsed pin configuration */ 3434static int vt1708B_auto_fill_dac_nids(struct via_spec *spec, 3435 const struct auto_pin_cfg *cfg) 3436{ 3437 int i; 3438 hda_nid_t nid; 3439 3440 spec->multiout.num_dacs = cfg->line_outs; 3441 3442 spec->multiout.dac_nids = spec->private_dac_nids; 3443 3444 for (i = 0; i < 4; i++) { 3445 nid = cfg->line_out_pins[i]; 3446 if (nid) { 3447 /* config dac list */ 3448 switch (i) { 3449 case AUTO_SEQ_FRONT: 3450 spec->multiout.dac_nids[i] = 0x10; 3451 break; 3452 case AUTO_SEQ_CENLFE: 3453 spec->multiout.dac_nids[i] = 0x24; 3454 break; 3455 case AUTO_SEQ_SURROUND: 3456 spec->multiout.dac_nids[i] = 0x11; 3457 break; 3458 case AUTO_SEQ_SIDE: 3459 spec->multiout.dac_nids[i] = 0x25; 3460 break; 3461 } 3462 } 3463 } 3464 3465 return 0; 3466} 3467 3468/* add playback controls from the parsed DAC table */ 3469static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec, 3470 const struct auto_pin_cfg *cfg) 3471{ 3472 char name[32]; 3473 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 3474 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27}; 3475 hda_nid_t nid, nid_vol = 0; 3476 int i, err; 3477 3478 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 3479 nid = cfg->line_out_pins[i]; 3480 3481 if (!nid) 3482 continue; 3483 3484 nid_vol = nid_vols[i]; 3485 3486 if (i == AUTO_SEQ_CENLFE) { 3487 /* Center/LFE */ 3488 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3489 "Center Playback Volume", 3490 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 3491 HDA_OUTPUT)); 3492 if (err < 0) 3493 return err; 3494 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3495 "LFE Playback Volume", 3496 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 3497 HDA_OUTPUT)); 3498 if (err < 0) 3499 return err; 3500 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 3501 "Center Playback Switch", 3502 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 3503 HDA_OUTPUT)); 3504 if (err < 0) 3505 return err; 3506 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 3507 "LFE Playback Switch", 3508 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 3509 HDA_OUTPUT)); 3510 if (err < 0) 3511 return err; 3512 } else if (i == AUTO_SEQ_FRONT) { 3513 /* add control to mixer index 0 */ 3514 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3515 "Master Front Playback Volume", 3516 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 3517 HDA_INPUT)); 3518 if (err < 0) 3519 return err; 3520 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 3521 "Master Front Playback Switch", 3522 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 3523 HDA_INPUT)); 3524 if (err < 0) 3525 return err; 3526 3527 /* add control to PW3 */ 3528 sprintf(name, "%s Playback Volume", chname[i]); 3529 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 3530 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 3531 HDA_OUTPUT)); 3532 if (err < 0) 3533 return err; 3534 sprintf(name, "%s Playback Switch", chname[i]); 3535 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 3536 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 3537 HDA_OUTPUT)); 3538 if (err < 0) 3539 return err; 3540 } else { 3541 sprintf(name, "%s Playback Volume", chname[i]); 3542 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 3543 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 3544 HDA_OUTPUT)); 3545 if (err < 0) 3546 return err; 3547 sprintf(name, "%s Playback Switch", chname[i]); 3548 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 3549 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 3550 HDA_OUTPUT)); 3551 if (err < 0) 3552 return err; 3553 } 3554 } 3555 3556 return 0; 3557} 3558 3559static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 3560{ 3561 int err; 3562 3563 if (!pin) 3564 return 0; 3565 3566 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */ 3567 spec->hp_independent_mode_index = 1; 3568 3569 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3570 "Headphone Playback Volume", 3571 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3572 if (err < 0) 3573 return err; 3574 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 3575 "Headphone Playback Switch", 3576 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 3577 if (err < 0) 3578 return err; 3579 3580 create_hp_imux(spec); 3581 3582 return 0; 3583} 3584 3585/* create playback/capture controls for input pins */ 3586static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec, 3587 const struct auto_pin_cfg *cfg) 3588{ 3589 static char *labels[] = { 3590 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 3591 }; 3592 struct hda_input_mux *imux = &spec->private_imux[0]; 3593 int i, err, idx = 0; 3594 3595 /* for internal loopback recording select */ 3596 imux->items[imux->num_items].label = "Stereo Mixer"; 3597 imux->items[imux->num_items].index = idx; 3598 imux->num_items++; 3599 3600 for (i = 0; i < AUTO_PIN_LAST; i++) { 3601 if (!cfg->input_pins[i]) 3602 continue; 3603 3604 switch (cfg->input_pins[i]) { 3605 case 0x1a: /* Mic */ 3606 idx = 2; 3607 break; 3608 3609 case 0x1b: /* Line In */ 3610 idx = 3; 3611 break; 3612 3613 case 0x1e: /* Front Mic */ 3614 idx = 4; 3615 break; 3616 3617 case 0x1f: /* CD */ 3618 idx = 1; 3619 break; 3620 } 3621 err = via_new_analog_input(spec, labels[i], idx, 0x16); 3622 if (err < 0) 3623 return err; 3624 imux->items[imux->num_items].label = labels[i]; 3625 imux->items[imux->num_items].index = idx; 3626 imux->num_items++; 3627 } 3628 return 0; 3629} 3630 3631static int vt1708B_parse_auto_config(struct hda_codec *codec) 3632{ 3633 struct via_spec *spec = codec->spec; 3634 int err; 3635 3636 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 3637 if (err < 0) 3638 return err; 3639 err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg); 3640 if (err < 0) 3641 return err; 3642 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 3643 return 0; /* can't find valid BIOS pin config */ 3644 3645 err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg); 3646 if (err < 0) 3647 return err; 3648 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 3649 if (err < 0) 3650 return err; 3651 err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg); 3652 if (err < 0) 3653 return err; 3654 3655 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3656 3657 if (spec->autocfg.dig_outs) 3658 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID; 3659 spec->dig_in_pin = VT1708B_DIGIN_PIN; 3660 if (spec->autocfg.dig_in_pin) 3661 spec->dig_in_nid = VT1708B_DIGIN_NID; 3662 3663 if (spec->kctls.list) 3664 spec->mixers[spec->num_mixers++] = spec->kctls.list; 3665 3666 spec->input_mux = &spec->private_imux[0]; 3667 3668 if (spec->hp_mux) 3669 via_hp_build(codec); 3670 3671 via_smart51_build(spec); 3672 return 1; 3673} 3674 3675#ifdef CONFIG_SND_HDA_POWER_SAVE 3676static struct hda_amp_list vt1708B_loopbacks[] = { 3677 { 0x16, HDA_INPUT, 1 }, 3678 { 0x16, HDA_INPUT, 2 }, 3679 { 0x16, HDA_INPUT, 3 }, 3680 { 0x16, HDA_INPUT, 4 }, 3681 { } /* end */ 3682}; 3683#endif 3684static int patch_vt1708S(struct hda_codec *codec); 3685static int patch_vt1708B_8ch(struct hda_codec *codec) 3686{ 3687 struct via_spec *spec; 3688 int err; 3689 3690 if (get_codec_type(codec) == VT1708BCE) 3691 return patch_vt1708S(codec); 3692 /* create a codec specific record */ 3693 spec = via_new_spec(codec); 3694 if (spec == NULL) 3695 return -ENOMEM; 3696 3697 /* automatic parse from the BIOS config */ 3698 err = vt1708B_parse_auto_config(codec); 3699 if (err < 0) { 3700 via_free(codec); 3701 return err; 3702 } else if (!err) { 3703 printk(KERN_INFO "hda_codec: Cannot set up configuration " 3704 "from BIOS. Using genenic mode...\n"); 3705 } 3706 3707 spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs; 3708 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs; 3709 3710 spec->stream_name_analog = "VT1708B Analog"; 3711 spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback; 3712 spec->stream_analog_capture = &vt1708B_pcm_analog_capture; 3713 3714 spec->stream_name_digital = "VT1708B Digital"; 3715 spec->stream_digital_playback = &vt1708B_pcm_digital_playback; 3716 spec->stream_digital_capture = &vt1708B_pcm_digital_capture; 3717 3718 if (!spec->adc_nids && spec->input_mux) { 3719 spec->adc_nids = vt1708B_adc_nids; 3720 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); 3721 get_mux_nids(codec); 3722 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; 3723 spec->num_mixers++; 3724 } 3725 3726 codec->patch_ops = via_patch_ops; 3727 3728 codec->patch_ops.init = via_auto_init; 3729 codec->patch_ops.unsol_event = via_unsol_event; 3730#ifdef CONFIG_SND_HDA_POWER_SAVE 3731 spec->loopback.amplist = vt1708B_loopbacks; 3732#endif 3733 3734 return 0; 3735} 3736 3737static int patch_vt1708B_4ch(struct hda_codec *codec) 3738{ 3739 struct via_spec *spec; 3740 int err; 3741 3742 /* create a codec specific record */ 3743 spec = via_new_spec(codec); 3744 if (spec == NULL) 3745 return -ENOMEM; 3746 3747 /* automatic parse from the BIOS config */ 3748 err = vt1708B_parse_auto_config(codec); 3749 if (err < 0) { 3750 via_free(codec); 3751 return err; 3752 } else if (!err) { 3753 printk(KERN_INFO "hda_codec: Cannot set up configuration " 3754 "from BIOS. Using genenic mode...\n"); 3755 } 3756 3757 spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs; 3758 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs; 3759 3760 spec->stream_name_analog = "VT1708B Analog"; 3761 spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback; 3762 spec->stream_analog_capture = &vt1708B_pcm_analog_capture; 3763 3764 spec->stream_name_digital = "VT1708B Digital"; 3765 spec->stream_digital_playback = &vt1708B_pcm_digital_playback; 3766 spec->stream_digital_capture = &vt1708B_pcm_digital_capture; 3767 3768 if (!spec->adc_nids && spec->input_mux) { 3769 spec->adc_nids = vt1708B_adc_nids; 3770 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); 3771 get_mux_nids(codec); 3772 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; 3773 spec->num_mixers++; 3774 } 3775 3776 codec->patch_ops = via_patch_ops; 3777 3778 codec->patch_ops.init = via_auto_init; 3779 codec->patch_ops.unsol_event = via_unsol_event; 3780#ifdef CONFIG_SND_HDA_POWER_SAVE 3781 spec->loopback.amplist = vt1708B_loopbacks; 3782#endif 3783 3784 return 0; 3785} 3786 3787/* Patch for VT1708S */ 3788 3789/* capture mixer elements */ 3790static struct snd_kcontrol_new vt1708S_capture_mixer[] = { 3791 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 3792 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 3793 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 3794 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT), 3795 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT), 3796 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0, 3797 HDA_INPUT), 3798 { 3799 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3800 /* The multiple "Capture Source" controls confuse alsamixer 3801 * So call somewhat different.. 3802 */ 3803 /* .name = "Capture Source", */ 3804 .name = "Input Source", 3805 .count = 1, 3806 .info = via_mux_enum_info, 3807 .get = via_mux_enum_get, 3808 .put = via_mux_enum_put, 3809 }, 3810 { } /* end */ 3811}; 3812 3813static struct hda_verb vt1708S_volume_init_verbs[] = { 3814 /* Unmute ADC0-1 and set the default input to mic-in */ 3815 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3816 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3817 3818 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the 3819 * analog-loopback mixer widget */ 3820 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 3821 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3822 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3823 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 3824 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 3825 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 3826 3827 /* Setup default input of PW4 to MW0 */ 3828 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0}, 3829 /* PW9, PW10 Output enable */ 3830 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3831 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3832 /* Enable Mic Boost Volume backdoor */ 3833 {0x1, 0xf98, 0x1}, 3834 /* don't bybass mixer */ 3835 {0x1, 0xf88, 0xc0}, 3836 { } 3837}; 3838 3839static struct hda_verb vt1708S_uniwill_init_verbs[] = { 3840 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 3841 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 3842 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3843 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3844 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3845 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3846 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3847 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3848 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 3849 { } 3850}; 3851 3852static struct hda_pcm_stream vt1708S_pcm_analog_playback = { 3853 .substreams = 2, 3854 .channels_min = 2, 3855 .channels_max = 8, 3856 .nid = 0x10, /* NID to query formats and rates */ 3857 .ops = { 3858 .open = via_playback_pcm_open, 3859 .prepare = via_playback_multi_pcm_prepare, 3860 .cleanup = via_playback_multi_pcm_cleanup, 3861 .close = via_pcm_open_close 3862 }, 3863}; 3864 3865static struct hda_pcm_stream vt1708S_pcm_analog_capture = { 3866 .substreams = 2, 3867 .channels_min = 2, 3868 .channels_max = 2, 3869 .nid = 0x13, /* NID to query formats and rates */ 3870 .ops = { 3871 .open = via_pcm_open_close, 3872 .prepare = via_capture_pcm_prepare, 3873 .cleanup = via_capture_pcm_cleanup, 3874 .close = via_pcm_open_close 3875 }, 3876}; 3877 3878static struct hda_pcm_stream vt1708S_pcm_digital_playback = { 3879 .substreams = 1, 3880 .channels_min = 2, 3881 .channels_max = 2, 3882 /* NID is set in via_build_pcms */ 3883 .ops = { 3884 .open = via_dig_playback_pcm_open, 3885 .close = via_dig_playback_pcm_close, 3886 .prepare = via_dig_playback_pcm_prepare, 3887 .cleanup = via_dig_playback_pcm_cleanup 3888 }, 3889}; 3890 3891/* fill in the dac_nids table from the parsed pin configuration */ 3892static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, 3893 const struct auto_pin_cfg *cfg) 3894{ 3895 int i; 3896 hda_nid_t nid; 3897 3898 spec->multiout.num_dacs = cfg->line_outs; 3899 3900 spec->multiout.dac_nids = spec->private_dac_nids; 3901 3902 for (i = 0; i < 4; i++) { 3903 nid = cfg->line_out_pins[i]; 3904 if (nid) { 3905 /* config dac list */ 3906 switch (i) { 3907 case AUTO_SEQ_FRONT: 3908 spec->multiout.dac_nids[i] = 0x10; 3909 break; 3910 case AUTO_SEQ_CENLFE: 3911 spec->multiout.dac_nids[i] = 0x24; 3912 break; 3913 case AUTO_SEQ_SURROUND: 3914 spec->multiout.dac_nids[i] = 0x11; 3915 break; 3916 case AUTO_SEQ_SIDE: 3917 spec->multiout.dac_nids[i] = 0x25; 3918 break; 3919 } 3920 } 3921 } 3922 3923 /* for Smart 5.1, line/mic inputs double as output pins */ 3924 if (cfg->line_outs == 1) { 3925 spec->multiout.num_dacs = 3; 3926 spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11; 3927 spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24; 3928 } 3929 3930 return 0; 3931} 3932 3933/* add playback controls from the parsed DAC table */ 3934static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, 3935 const struct auto_pin_cfg *cfg) 3936{ 3937 char name[32]; 3938 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 3939 hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25}; 3940 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27}; 3941 hda_nid_t nid, nid_vol, nid_mute; 3942 int i, err; 3943 3944 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 3945 nid = cfg->line_out_pins[i]; 3946 3947 /* for Smart 5.1, there are always at least six channels */ 3948 if (!nid && i > AUTO_SEQ_CENLFE) 3949 continue; 3950 3951 nid_vol = nid_vols[i]; 3952 nid_mute = nid_mutes[i]; 3953 3954 if (i == AUTO_SEQ_CENLFE) { 3955 /* Center/LFE */ 3956 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3957 "Center Playback Volume", 3958 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 3959 HDA_OUTPUT)); 3960 if (err < 0) 3961 return err; 3962 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3963 "LFE Playback Volume", 3964 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 3965 HDA_OUTPUT)); 3966 if (err < 0) 3967 return err; 3968 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 3969 "Center Playback Switch", 3970 HDA_COMPOSE_AMP_VAL(nid_mute, 3971 1, 0, 3972 HDA_OUTPUT)); 3973 if (err < 0) 3974 return err; 3975 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 3976 "LFE Playback Switch", 3977 HDA_COMPOSE_AMP_VAL(nid_mute, 3978 2, 0, 3979 HDA_OUTPUT)); 3980 if (err < 0) 3981 return err; 3982 } else if (i == AUTO_SEQ_FRONT) { 3983 /* add control to mixer index 0 */ 3984 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3985 "Master Front Playback Volume", 3986 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, 3987 HDA_INPUT)); 3988 if (err < 0) 3989 return err; 3990 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 3991 "Master Front Playback Switch", 3992 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, 3993 HDA_INPUT)); 3994 if (err < 0) 3995 return err; 3996 3997 /* Front */ 3998 sprintf(name, "%s Playback Volume", chname[i]); 3999 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 4000 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 4001 HDA_OUTPUT)); 4002 if (err < 0) 4003 return err; 4004 sprintf(name, "%s Playback Switch", chname[i]); 4005 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 4006 HDA_COMPOSE_AMP_VAL(nid_mute, 4007 3, 0, 4008 HDA_OUTPUT)); 4009 if (err < 0) 4010 return err; 4011 } else { 4012 sprintf(name, "%s Playback Volume", chname[i]); 4013 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 4014 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 4015 HDA_OUTPUT)); 4016 if (err < 0) 4017 return err; 4018 sprintf(name, "%s Playback Switch", chname[i]); 4019 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 4020 HDA_COMPOSE_AMP_VAL(nid_mute, 4021 3, 0, 4022 HDA_OUTPUT)); 4023 if (err < 0) 4024 return err; 4025 } 4026 } 4027 4028 return 0; 4029} 4030 4031static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 4032{ 4033 int err; 4034 4035 if (!pin) 4036 return 0; 4037 4038 spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */ 4039 spec->hp_independent_mode_index = 1; 4040 4041 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 4042 "Headphone Playback Volume", 4043 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT)); 4044 if (err < 0) 4045 return err; 4046 4047 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 4048 "Headphone Playback Switch", 4049 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 4050 if (err < 0) 4051 return err; 4052 4053 create_hp_imux(spec); 4054 4055 return 0; 4056} 4057 4058/* create playback/capture controls for input pins */ 4059static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec, 4060 const struct auto_pin_cfg *cfg) 4061{ 4062 static char *labels[] = { 4063 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 4064 }; 4065 struct hda_input_mux *imux = &spec->private_imux[0]; 4066 int i, err, idx = 0; 4067 4068 /* for internal loopback recording select */ 4069 imux->items[imux->num_items].label = "Stereo Mixer"; 4070 imux->items[imux->num_items].index = 5; 4071 imux->num_items++; 4072 4073 for (i = 0; i < AUTO_PIN_LAST; i++) { 4074 if (!cfg->input_pins[i]) 4075 continue; 4076 4077 switch (cfg->input_pins[i]) { 4078 case 0x1a: /* Mic */ 4079 idx = 2; 4080 break; 4081 4082 case 0x1b: /* Line In */ 4083 idx = 3; 4084 break; 4085 4086 case 0x1e: /* Front Mic */ 4087 idx = 4; 4088 break; 4089 4090 case 0x1f: /* CD */ 4091 idx = 1; 4092 break; 4093 } 4094 err = via_new_analog_input(spec, labels[i], idx, 0x16); 4095 if (err < 0) 4096 return err; 4097 imux->items[imux->num_items].label = labels[i]; 4098 imux->items[imux->num_items].index = idx-1; 4099 imux->num_items++; 4100 } 4101 return 0; 4102} 4103 4104/* fill out digital output widgets; one for master and one for slave outputs */ 4105static void fill_dig_outs(struct hda_codec *codec) 4106{ 4107 struct via_spec *spec = codec->spec; 4108 int i; 4109 4110 for (i = 0; i < spec->autocfg.dig_outs; i++) { 4111 hda_nid_t nid; 4112 int conn; 4113 4114 nid = spec->autocfg.dig_out_pins[i]; 4115 if (!nid) 4116 continue; 4117 conn = snd_hda_get_connections(codec, nid, &nid, 1); 4118 if (conn < 1) 4119 continue; 4120 if (!spec->multiout.dig_out_nid) 4121 spec->multiout.dig_out_nid = nid; 4122 else { 4123 spec->slave_dig_outs[0] = nid; 4124 break; /* at most two dig outs */ 4125 } 4126 } 4127} 4128 4129static int vt1708S_parse_auto_config(struct hda_codec *codec) 4130{ 4131 struct via_spec *spec = codec->spec; 4132 int err; 4133 4134 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 4135 if (err < 0) 4136 return err; 4137 err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg); 4138 if (err < 0) 4139 return err; 4140 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 4141 return 0; /* can't find valid BIOS pin config */ 4142 4143 err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg); 4144 if (err < 0) 4145 return err; 4146 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 4147 if (err < 0) 4148 return err; 4149 err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg); 4150 if (err < 0) 4151 return err; 4152 4153 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 4154 4155 fill_dig_outs(codec); 4156 4157 if (spec->kctls.list) 4158 spec->mixers[spec->num_mixers++] = spec->kctls.list; 4159 4160 spec->input_mux = &spec->private_imux[0]; 4161 4162 if (spec->hp_mux) 4163 via_hp_build(codec); 4164 4165 via_smart51_build(spec); 4166 return 1; 4167} 4168 4169#ifdef CONFIG_SND_HDA_POWER_SAVE 4170static struct hda_amp_list vt1708S_loopbacks[] = { 4171 { 0x16, HDA_INPUT, 1 }, 4172 { 0x16, HDA_INPUT, 2 }, 4173 { 0x16, HDA_INPUT, 3 }, 4174 { 0x16, HDA_INPUT, 4 }, 4175 { } /* end */ 4176}; 4177#endif 4178 4179static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin, 4180 int offset, int num_steps, int step_size) 4181{ 4182 snd_hda_override_amp_caps(codec, pin, HDA_INPUT, 4183 (offset << AC_AMPCAP_OFFSET_SHIFT) | 4184 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) | 4185 (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) | 4186 (0 << AC_AMPCAP_MUTE_SHIFT)); 4187} 4188 4189static int patch_vt1708S(struct hda_codec *codec) 4190{ 4191 struct via_spec *spec; 4192 int err; 4193 4194 /* create a codec specific record */ 4195 spec = via_new_spec(codec); 4196 if (spec == NULL) 4197 return -ENOMEM; 4198 4199 /* automatic parse from the BIOS config */ 4200 err = vt1708S_parse_auto_config(codec); 4201 if (err < 0) { 4202 via_free(codec); 4203 return err; 4204 } else if (!err) { 4205 printk(KERN_INFO "hda_codec: Cannot set up configuration " 4206 "from BIOS. Using genenic mode...\n"); 4207 } 4208 4209 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; 4210 spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs; 4211 4212 if (codec->vendor_id == 0x11060440) 4213 spec->stream_name_analog = "VT1818S Analog"; 4214 else 4215 spec->stream_name_analog = "VT1708S Analog"; 4216 spec->stream_analog_playback = &vt1708S_pcm_analog_playback; 4217 spec->stream_analog_capture = &vt1708S_pcm_analog_capture; 4218 4219 if (codec->vendor_id == 0x11060440) 4220 spec->stream_name_digital = "VT1818S Digital"; 4221 else 4222 spec->stream_name_digital = "VT1708S Digital"; 4223 spec->stream_digital_playback = &vt1708S_pcm_digital_playback; 4224 4225 if (!spec->adc_nids && spec->input_mux) { 4226 spec->adc_nids = vt1708S_adc_nids; 4227 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids); 4228 get_mux_nids(codec); 4229 override_mic_boost(codec, 0x1a, 0, 3, 40); 4230 override_mic_boost(codec, 0x1e, 0, 3, 40); 4231 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer; 4232 spec->num_mixers++; 4233 } 4234 4235 codec->patch_ops = via_patch_ops; 4236 4237 codec->patch_ops.init = via_auto_init; 4238 codec->patch_ops.unsol_event = via_unsol_event; 4239#ifdef CONFIG_SND_HDA_POWER_SAVE 4240 spec->loopback.amplist = vt1708S_loopbacks; 4241#endif 4242 4243 /* correct names for VT1708BCE */ 4244 if (get_codec_type(codec) == VT1708BCE) { 4245 kfree(codec->chip_name); 4246 codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL); 4247 snprintf(codec->bus->card->mixername, 4248 sizeof(codec->bus->card->mixername), 4249 "%s %s", codec->vendor_name, codec->chip_name); 4250 spec->stream_name_analog = "VT1708BCE Analog"; 4251 spec->stream_name_digital = "VT1708BCE Digital"; 4252 } 4253 return 0; 4254} 4255 4256/* Patch for VT1702 */ 4257 4258/* capture mixer elements */ 4259static struct snd_kcontrol_new vt1702_capture_mixer[] = { 4260 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT), 4261 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT), 4262 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT), 4263 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT), 4264 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT), 4265 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT), 4266 HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0, 4267 HDA_INPUT), 4268 { 4269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4270 /* The multiple "Capture Source" controls confuse alsamixer 4271 * So call somewhat different.. 4272 */ 4273 /* .name = "Capture Source", */ 4274 .name = "Input Source", 4275 .count = 1, 4276 .info = via_mux_enum_info, 4277 .get = via_mux_enum_get, 4278 .put = via_mux_enum_put, 4279 }, 4280 { } /* end */ 4281}; 4282 4283static struct hda_verb vt1702_volume_init_verbs[] = { 4284 /* 4285 * Unmute ADC0-1 and set the default input to mic-in 4286 */ 4287 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4288 {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4289 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4290 4291 4292 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4293 * mixer widget 4294 */ 4295 /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */ 4296 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4297 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4298 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 4299 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 4300 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4301 4302 /* Setup default input of PW4 to MW0 */ 4303 {0x17, AC_VERB_SET_CONNECT_SEL, 0x1}, 4304 /* PW6 PW7 Output enable */ 4305 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4306 {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4307 /* mixer enable */ 4308 {0x1, 0xF88, 0x3}, 4309 /* GPIO 0~2 */ 4310 {0x1, 0xF82, 0x3F}, 4311 { } 4312}; 4313 4314static struct hda_verb vt1702_uniwill_init_verbs[] = { 4315 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, 4316 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 4317 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4318 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4319 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4320 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4321 { } 4322}; 4323 4324static struct hda_pcm_stream vt1702_pcm_analog_playback = { 4325 .substreams = 2, 4326 .channels_min = 2, 4327 .channels_max = 2, 4328 .nid = 0x10, /* NID to query formats and rates */ 4329 .ops = { 4330 .open = via_playback_pcm_open, 4331 .prepare = via_playback_multi_pcm_prepare, 4332 .cleanup = via_playback_multi_pcm_cleanup, 4333 .close = via_pcm_open_close 4334 }, 4335}; 4336 4337static struct hda_pcm_stream vt1702_pcm_analog_capture = { 4338 .substreams = 3, 4339 .channels_min = 2, 4340 .channels_max = 2, 4341 .nid = 0x12, /* NID to query formats and rates */ 4342 .ops = { 4343 .open = via_pcm_open_close, 4344 .prepare = via_capture_pcm_prepare, 4345 .cleanup = via_capture_pcm_cleanup, 4346 .close = via_pcm_open_close 4347 }, 4348}; 4349 4350static struct hda_pcm_stream vt1702_pcm_digital_playback = { 4351 .substreams = 2, 4352 .channels_min = 2, 4353 .channels_max = 2, 4354 /* NID is set in via_build_pcms */ 4355 .ops = { 4356 .open = via_dig_playback_pcm_open, 4357 .close = via_dig_playback_pcm_close, 4358 .prepare = via_dig_playback_pcm_prepare, 4359 .cleanup = via_dig_playback_pcm_cleanup 4360 }, 4361}; 4362 4363/* fill in the dac_nids table from the parsed pin configuration */ 4364static int vt1702_auto_fill_dac_nids(struct via_spec *spec, 4365 const struct auto_pin_cfg *cfg) 4366{ 4367 spec->multiout.num_dacs = 1; 4368 spec->multiout.dac_nids = spec->private_dac_nids; 4369 4370 if (cfg->line_out_pins[0]) { 4371 /* config dac list */ 4372 spec->multiout.dac_nids[0] = 0x10; 4373 } 4374 4375 return 0; 4376} 4377 4378/* add playback controls from the parsed DAC table */ 4379static int vt1702_auto_create_line_out_ctls(struct via_spec *spec, 4380 const struct auto_pin_cfg *cfg) 4381{ 4382 int err; 4383 4384 if (!cfg->line_out_pins[0]) 4385 return -1; 4386 4387 /* add control to mixer index 0 */ 4388 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 4389 "Master Front Playback Volume", 4390 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT)); 4391 if (err < 0) 4392 return err; 4393 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 4394 "Master Front Playback Switch", 4395 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT)); 4396 if (err < 0) 4397 return err; 4398 4399 /* Front */ 4400 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 4401 "Front Playback Volume", 4402 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT)); 4403 if (err < 0) 4404 return err; 4405 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 4406 "Front Playback Switch", 4407 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT)); 4408 if (err < 0) 4409 return err; 4410 4411 return 0; 4412} 4413 4414static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 4415{ 4416 int err, i; 4417 struct hda_input_mux *imux; 4418 static const char *texts[] = { "ON", "OFF", NULL}; 4419 if (!pin) 4420 return 0; 4421 spec->multiout.hp_nid = 0x1D; 4422 spec->hp_independent_mode_index = 0; 4423 4424 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 4425 "Headphone Playback Volume", 4426 HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT)); 4427 if (err < 0) 4428 return err; 4429 4430 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 4431 "Headphone Playback Switch", 4432 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 4433 if (err < 0) 4434 return err; 4435 4436 imux = &spec->private_imux[1]; 4437 4438 /* for hp mode select */ 4439 i = 0; 4440 while (texts[i] != NULL) { 4441 imux->items[imux->num_items].label = texts[i]; 4442 imux->items[imux->num_items].index = i; 4443 imux->num_items++; 4444 i++; 4445 } 4446 4447 spec->hp_mux = &spec->private_imux[1]; 4448 return 0; 4449} 4450 4451/* create playback/capture controls for input pins */ 4452static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec, 4453 const struct auto_pin_cfg *cfg) 4454{ 4455 static char *labels[] = { 4456 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 4457 }; 4458 struct hda_input_mux *imux = &spec->private_imux[0]; 4459 int i, err, idx = 0; 4460 4461 /* for internal loopback recording select */ 4462 imux->items[imux->num_items].label = "Stereo Mixer"; 4463 imux->items[imux->num_items].index = 3; 4464 imux->num_items++; 4465 4466 for (i = 0; i < AUTO_PIN_LAST; i++) { 4467 if (!cfg->input_pins[i]) 4468 continue; 4469 4470 switch (cfg->input_pins[i]) { 4471 case 0x14: /* Mic */ 4472 idx = 1; 4473 break; 4474 4475 case 0x15: /* Line In */ 4476 idx = 2; 4477 break; 4478 4479 case 0x18: /* Front Mic */ 4480 idx = 3; 4481 break; 4482 } 4483 err = via_new_analog_input(spec, labels[i], idx, 0x1A); 4484 if (err < 0) 4485 return err; 4486 imux->items[imux->num_items].label = labels[i]; 4487 imux->items[imux->num_items].index = idx-1; 4488 imux->num_items++; 4489 } 4490 return 0; 4491} 4492 4493static int vt1702_parse_auto_config(struct hda_codec *codec) 4494{ 4495 struct via_spec *spec = codec->spec; 4496 int err; 4497 4498 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 4499 if (err < 0) 4500 return err; 4501 err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg); 4502 if (err < 0) 4503 return err; 4504 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 4505 return 0; /* can't find valid BIOS pin config */ 4506 4507 err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg); 4508 if (err < 0) 4509 return err; 4510 err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 4511 if (err < 0) 4512 return err; 4513 /* limit AA path volume to 0 dB */ 4514 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT, 4515 (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 4516 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 4517 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) | 4518 (1 << AC_AMPCAP_MUTE_SHIFT)); 4519 err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg); 4520 if (err < 0) 4521 return err; 4522 4523 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 4524 4525 fill_dig_outs(codec); 4526 4527 if (spec->kctls.list) 4528 spec->mixers[spec->num_mixers++] = spec->kctls.list; 4529 4530 spec->input_mux = &spec->private_imux[0]; 4531 4532 if (spec->hp_mux) 4533 via_hp_build(codec); 4534 4535 return 1; 4536} 4537 4538#ifdef CONFIG_SND_HDA_POWER_SAVE 4539static struct hda_amp_list vt1702_loopbacks[] = { 4540 { 0x1A, HDA_INPUT, 1 }, 4541 { 0x1A, HDA_INPUT, 2 }, 4542 { 0x1A, HDA_INPUT, 3 }, 4543 { 0x1A, HDA_INPUT, 4 }, 4544 { } /* end */ 4545}; 4546#endif 4547 4548static int patch_vt1702(struct hda_codec *codec) 4549{ 4550 struct via_spec *spec; 4551 int err; 4552 4553 /* create a codec specific record */ 4554 spec = via_new_spec(codec); 4555 if (spec == NULL) 4556 return -ENOMEM; 4557 4558 /* automatic parse from the BIOS config */ 4559 err = vt1702_parse_auto_config(codec); 4560 if (err < 0) { 4561 via_free(codec); 4562 return err; 4563 } else if (!err) { 4564 printk(KERN_INFO "hda_codec: Cannot set up configuration " 4565 "from BIOS. Using genenic mode...\n"); 4566 } 4567 4568 spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs; 4569 spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs; 4570 4571 spec->stream_name_analog = "VT1702 Analog"; 4572 spec->stream_analog_playback = &vt1702_pcm_analog_playback; 4573 spec->stream_analog_capture = &vt1702_pcm_analog_capture; 4574 4575 spec->stream_name_digital = "VT1702 Digital"; 4576 spec->stream_digital_playback = &vt1702_pcm_digital_playback; 4577 4578 if (!spec->adc_nids && spec->input_mux) { 4579 spec->adc_nids = vt1702_adc_nids; 4580 spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids); 4581 get_mux_nids(codec); 4582 spec->mixers[spec->num_mixers] = vt1702_capture_mixer; 4583 spec->num_mixers++; 4584 } 4585 4586 codec->patch_ops = via_patch_ops; 4587 4588 codec->patch_ops.init = via_auto_init; 4589 codec->patch_ops.unsol_event = via_unsol_event; 4590#ifdef CONFIG_SND_HDA_POWER_SAVE 4591 spec->loopback.amplist = vt1702_loopbacks; 4592#endif 4593 4594 return 0; 4595} 4596 4597/* Patch for VT1718S */ 4598 4599/* capture mixer elements */ 4600static struct snd_kcontrol_new vt1718S_capture_mixer[] = { 4601 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), 4602 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), 4603 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), 4604 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT), 4605 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT), 4606 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0, 4607 HDA_INPUT), 4608 { 4609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4610 /* The multiple "Capture Source" controls confuse alsamixer 4611 * So call somewhat different.. 4612 */ 4613 .name = "Input Source", 4614 .count = 2, 4615 .info = via_mux_enum_info, 4616 .get = via_mux_enum_get, 4617 .put = via_mux_enum_put, 4618 }, 4619 { } /* end */ 4620}; 4621 4622static struct hda_verb vt1718S_volume_init_verbs[] = { 4623 /* 4624 * Unmute ADC0-1 and set the default input to mic-in 4625 */ 4626 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4627 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4628 4629 4630 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 4631 * mixer widget 4632 */ 4633 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 4634 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4635 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4636 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4637 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4638 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 4639 4640 /* Setup default input of Front HP to MW9 */ 4641 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1}, 4642 /* PW9 PW10 Output enable */ 4643 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, 4644 {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, 4645 /* PW11 Input enable */ 4646 {0x2f, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_IN_EN}, 4647 /* Enable Boost Volume backdoor */ 4648 {0x1, 0xf88, 0x8}, 4649 /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */ 4650 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4651 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4653 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4654 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4655 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4656 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4657 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4658 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4659 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4660 /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */ 4661 {0x34, AC_VERB_SET_CONNECT_SEL, 0x2}, 4662 {0x35, AC_VERB_SET_CONNECT_SEL, 0x1}, 4663 /* Unmute MW4's index 0 */ 4664 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4665 { } 4666}; 4667 4668 4669static struct hda_verb vt1718S_uniwill_init_verbs[] = { 4670 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE, 4671 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 4672 {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4673 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4674 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4675 {0x27, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4676 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4677 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4678 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 4679 { } 4680}; 4681 4682static struct hda_pcm_stream vt1718S_pcm_analog_playback = { 4683 .substreams = 2, 4684 .channels_min = 2, 4685 .channels_max = 10, 4686 .nid = 0x8, /* NID to query formats and rates */ 4687 .ops = { 4688 .open = via_playback_pcm_open, 4689 .prepare = via_playback_multi_pcm_prepare, 4690 .cleanup = via_playback_multi_pcm_cleanup, 4691 .close = via_pcm_open_close, 4692 }, 4693}; 4694 4695static struct hda_pcm_stream vt1718S_pcm_analog_capture = { 4696 .substreams = 2, 4697 .channels_min = 2, 4698 .channels_max = 2, 4699 .nid = 0x10, /* NID to query formats and rates */ 4700 .ops = { 4701 .open = via_pcm_open_close, 4702 .prepare = via_capture_pcm_prepare, 4703 .cleanup = via_capture_pcm_cleanup, 4704 .close = via_pcm_open_close, 4705 }, 4706}; 4707 4708static struct hda_pcm_stream vt1718S_pcm_digital_playback = { 4709 .substreams = 2, 4710 .channels_min = 2, 4711 .channels_max = 2, 4712 /* NID is set in via_build_pcms */ 4713 .ops = { 4714 .open = via_dig_playback_pcm_open, 4715 .close = via_dig_playback_pcm_close, 4716 .prepare = via_dig_playback_pcm_prepare, 4717 .cleanup = via_dig_playback_pcm_cleanup 4718 }, 4719}; 4720 4721static struct hda_pcm_stream vt1718S_pcm_digital_capture = { 4722 .substreams = 1, 4723 .channels_min = 2, 4724 .channels_max = 2, 4725}; 4726 4727/* fill in the dac_nids table from the parsed pin configuration */ 4728static int vt1718S_auto_fill_dac_nids(struct via_spec *spec, 4729 const struct auto_pin_cfg *cfg) 4730{ 4731 int i; 4732 hda_nid_t nid; 4733 4734 spec->multiout.num_dacs = cfg->line_outs; 4735 4736 spec->multiout.dac_nids = spec->private_dac_nids; 4737 4738 for (i = 0; i < 4; i++) { 4739 nid = cfg->line_out_pins[i]; 4740 if (nid) { 4741 /* config dac list */ 4742 switch (i) { 4743 case AUTO_SEQ_FRONT: 4744 spec->multiout.dac_nids[i] = 0x8; 4745 break; 4746 case AUTO_SEQ_CENLFE: 4747 spec->multiout.dac_nids[i] = 0xa; 4748 break; 4749 case AUTO_SEQ_SURROUND: 4750 spec->multiout.dac_nids[i] = 0x9; 4751 break; 4752 case AUTO_SEQ_SIDE: 4753 spec->multiout.dac_nids[i] = 0xb; 4754 break; 4755 } 4756 } 4757 } 4758 4759 return 0; 4760} 4761 4762/* add playback controls from the parsed DAC table */ 4763static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec, 4764 const struct auto_pin_cfg *cfg) 4765{ 4766 char name[32]; 4767 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 4768 hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb}; 4769 hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27}; 4770 hda_nid_t nid, nid_vol, nid_mute = 0; 4771 int i, err; 4772 4773 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 4774 nid = cfg->line_out_pins[i]; 4775 4776 if (!nid) 4777 continue; 4778 nid_vol = nid_vols[i]; 4779 nid_mute = nid_mutes[i]; 4780 4781 if (i == AUTO_SEQ_CENLFE) { 4782 /* Center/LFE */ 4783 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 4784 "Center Playback Volume", 4785 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, 4786 HDA_OUTPUT)); 4787 if (err < 0) 4788 return err; 4789 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 4790 "LFE Playback Volume", 4791 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, 4792 HDA_OUTPUT)); 4793 if (err < 0) 4794 return err; 4795 err = via_add_control( 4796 spec, VIA_CTL_WIDGET_MUTE, 4797 "Center Playback Switch", 4798 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0, 4799 HDA_OUTPUT)); 4800 if (err < 0) 4801 return err; 4802 err = via_add_control( 4803 spec, VIA_CTL_WIDGET_MUTE, 4804 "LFE Playback Switch", 4805 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0, 4806 HDA_OUTPUT)); 4807 if (err < 0) 4808 return err; 4809 } else if (i == AUTO_SEQ_FRONT) { 4810 /* Front */ 4811 sprintf(name, "%s Playback Volume", chname[i]); 4812 err = via_add_control( 4813 spec, VIA_CTL_WIDGET_VOL, name, 4814 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT)); 4815 if (err < 0) 4816 return err; 4817 sprintf(name, "%s Playback Switch", chname[i]); 4818 err = via_add_control( 4819 spec, VIA_CTL_WIDGET_MUTE, name, 4820 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0, 4821 HDA_OUTPUT)); 4822 if (err < 0) 4823 return err; 4824 } else { 4825 sprintf(name, "%s Playback Volume", chname[i]); 4826 err = via_add_control( 4827 spec, VIA_CTL_WIDGET_VOL, name, 4828 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT)); 4829 if (err < 0) 4830 return err; 4831 sprintf(name, "%s Playback Switch", chname[i]); 4832 err = via_add_control( 4833 spec, VIA_CTL_WIDGET_MUTE, name, 4834 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0, 4835 HDA_OUTPUT)); 4836 if (err < 0) 4837 return err; 4838 } 4839 } 4840 return 0; 4841} 4842 4843static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 4844{ 4845 int err; 4846 4847 if (!pin) 4848 return 0; 4849 4850 spec->multiout.hp_nid = 0xc; /* AOW4 */ 4851 spec->hp_independent_mode_index = 1; 4852 4853 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 4854 "Headphone Playback Volume", 4855 HDA_COMPOSE_AMP_VAL(0xc, 3, 0, HDA_OUTPUT)); 4856 if (err < 0) 4857 return err; 4858 4859 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 4860 "Headphone Playback Switch", 4861 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 4862 if (err < 0) 4863 return err; 4864 4865 create_hp_imux(spec); 4866 return 0; 4867} 4868 4869/* create playback/capture controls for input pins */ 4870static int vt1718S_auto_create_analog_input_ctls(struct via_spec *spec, 4871 const struct auto_pin_cfg *cfg) 4872{ 4873 static char *labels[] = { 4874 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 4875 }; 4876 struct hda_input_mux *imux = &spec->private_imux[0]; 4877 int i, err, idx = 0; 4878 4879 /* for internal loopback recording select */ 4880 imux->items[imux->num_items].label = "Stereo Mixer"; 4881 imux->items[imux->num_items].index = 5; 4882 imux->num_items++; 4883 4884 for (i = 0; i < AUTO_PIN_LAST; i++) { 4885 if (!cfg->input_pins[i]) 4886 continue; 4887 4888 switch (cfg->input_pins[i]) { 4889 case 0x2b: /* Mic */ 4890 idx = 1; 4891 break; 4892 4893 case 0x2a: /* Line In */ 4894 idx = 2; 4895 break; 4896 4897 case 0x29: /* Front Mic */ 4898 idx = 3; 4899 break; 4900 4901 case 0x2c: /* CD */ 4902 idx = 0; 4903 break; 4904 } 4905 err = via_new_analog_input(spec, labels[i], idx, 0x21); 4906 if (err < 0) 4907 return err; 4908 imux->items[imux->num_items].label = labels[i]; 4909 imux->items[imux->num_items].index = idx; 4910 imux->num_items++; 4911 } 4912 return 0; 4913} 4914 4915static int vt1718S_parse_auto_config(struct hda_codec *codec) 4916{ 4917 struct via_spec *spec = codec->spec; 4918 int err; 4919 4920 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 4921 4922 if (err < 0) 4923 return err; 4924 err = vt1718S_auto_fill_dac_nids(spec, &spec->autocfg); 4925 if (err < 0) 4926 return err; 4927 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 4928 return 0; /* can't find valid BIOS pin config */ 4929 4930 err = vt1718S_auto_create_multi_out_ctls(spec, &spec->autocfg); 4931 if (err < 0) 4932 return err; 4933 err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 4934 if (err < 0) 4935 return err; 4936 err = vt1718S_auto_create_analog_input_ctls(spec, &spec->autocfg); 4937 if (err < 0) 4938 return err; 4939 4940 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 4941 4942 fill_dig_outs(codec); 4943 4944 if (spec->autocfg.dig_in_pin && codec->vendor_id == 0x11060428) 4945 spec->dig_in_nid = 0x13; 4946 4947 if (spec->kctls.list) 4948 spec->mixers[spec->num_mixers++] = spec->kctls.list; 4949 4950 spec->input_mux = &spec->private_imux[0]; 4951 4952 if (spec->hp_mux) 4953 via_hp_build(codec); 4954 4955 via_smart51_build(spec); 4956 4957 return 1; 4958} 4959 4960#ifdef CONFIG_SND_HDA_POWER_SAVE 4961static struct hda_amp_list vt1718S_loopbacks[] = { 4962 { 0x21, HDA_INPUT, 1 }, 4963 { 0x21, HDA_INPUT, 2 }, 4964 { 0x21, HDA_INPUT, 3 }, 4965 { 0x21, HDA_INPUT, 4 }, 4966 { } /* end */ 4967}; 4968#endif 4969 4970static int patch_vt1718S(struct hda_codec *codec) 4971{ 4972 struct via_spec *spec; 4973 int err; 4974 4975 /* create a codec specific record */ 4976 spec = via_new_spec(codec); 4977 if (spec == NULL) 4978 return -ENOMEM; 4979 4980 /* automatic parse from the BIOS config */ 4981 err = vt1718S_parse_auto_config(codec); 4982 if (err < 0) { 4983 via_free(codec); 4984 return err; 4985 } else if (!err) { 4986 printk(KERN_INFO "hda_codec: Cannot set up configuration " 4987 "from BIOS. Using genenic mode...\n"); 4988 } 4989 4990 spec->init_verbs[spec->num_iverbs++] = vt1718S_volume_init_verbs; 4991 spec->init_verbs[spec->num_iverbs++] = vt1718S_uniwill_init_verbs; 4992 4993 if (codec->vendor_id == 0x11060441) 4994 spec->stream_name_analog = "VT2020 Analog"; 4995 else if (codec->vendor_id == 0x11064441) 4996 spec->stream_name_analog = "VT1828S Analog"; 4997 else 4998 spec->stream_name_analog = "VT1718S Analog"; 4999 spec->stream_analog_playback = &vt1718S_pcm_analog_playback; 5000 spec->stream_analog_capture = &vt1718S_pcm_analog_capture; 5001 5002 if (codec->vendor_id == 0x11060441) 5003 spec->stream_name_digital = "VT2020 Digital"; 5004 else if (codec->vendor_id == 0x11064441) 5005 spec->stream_name_digital = "VT1828S Digital"; 5006 else 5007 spec->stream_name_digital = "VT1718S Digital"; 5008 spec->stream_digital_playback = &vt1718S_pcm_digital_playback; 5009 if (codec->vendor_id == 0x11060428 || codec->vendor_id == 0x11060441) 5010 spec->stream_digital_capture = &vt1718S_pcm_digital_capture; 5011 5012 if (!spec->adc_nids && spec->input_mux) { 5013 spec->adc_nids = vt1718S_adc_nids; 5014 spec->num_adc_nids = ARRAY_SIZE(vt1718S_adc_nids); 5015 get_mux_nids(codec); 5016 override_mic_boost(codec, 0x2b, 0, 3, 40); 5017 override_mic_boost(codec, 0x29, 0, 3, 40); 5018 spec->mixers[spec->num_mixers] = vt1718S_capture_mixer; 5019 spec->num_mixers++; 5020 } 5021 5022 codec->patch_ops = via_patch_ops; 5023 5024 codec->patch_ops.init = via_auto_init; 5025 codec->patch_ops.unsol_event = via_unsol_event; 5026 5027#ifdef CONFIG_SND_HDA_POWER_SAVE 5028 spec->loopback.amplist = vt1718S_loopbacks; 5029#endif 5030 5031 return 0; 5032} 5033 5034/* Patch for VT1716S */ 5035 5036static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol, 5037 struct snd_ctl_elem_info *uinfo) 5038{ 5039 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 5040 uinfo->count = 1; 5041 uinfo->value.integer.min = 0; 5042 uinfo->value.integer.max = 1; 5043 return 0; 5044} 5045 5046static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol, 5047 struct snd_ctl_elem_value *ucontrol) 5048{ 5049 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5050 int index = 0; 5051 5052 index = snd_hda_codec_read(codec, 0x26, 0, 5053 AC_VERB_GET_CONNECT_SEL, 0); 5054 if (index != -1) 5055 *ucontrol->value.integer.value = index; 5056 5057 return 0; 5058} 5059 5060static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol, 5061 struct snd_ctl_elem_value *ucontrol) 5062{ 5063 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5064 struct via_spec *spec = codec->spec; 5065 int index = *ucontrol->value.integer.value; 5066 5067 snd_hda_codec_write(codec, 0x26, 0, 5068 AC_VERB_SET_CONNECT_SEL, index); 5069 spec->dmic_enabled = index; 5070 set_jack_power_state(codec); 5071 5072 return 1; 5073} 5074 5075/* capture mixer elements */ 5076static struct snd_kcontrol_new vt1716S_capture_mixer[] = { 5077 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 5078 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 5079 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 5080 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT), 5081 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT), 5082 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0, 5083 HDA_INPUT), 5084 { 5085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5086 .name = "Input Source", 5087 .count = 1, 5088 .info = via_mux_enum_info, 5089 .get = via_mux_enum_get, 5090 .put = via_mux_enum_put, 5091 }, 5092 { } /* end */ 5093}; 5094 5095static struct snd_kcontrol_new vt1716s_dmic_mixer[] = { 5096 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT), 5097 { 5098 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5099 .name = "Digital Mic Capture Switch", 5100 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26, 5101 .count = 1, 5102 .info = vt1716s_dmic_info, 5103 .get = vt1716s_dmic_get, 5104 .put = vt1716s_dmic_put, 5105 }, 5106 {} /* end */ 5107}; 5108 5109 5110/* mono-out mixer elements */ 5111static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = { 5112 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT), 5113 { } /* end */ 5114}; 5115 5116static struct hda_verb vt1716S_volume_init_verbs[] = { 5117 /* 5118 * Unmute ADC0-1 and set the default input to mic-in 5119 */ 5120 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5121 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5122 5123 5124 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5125 * mixer widget 5126 */ 5127 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 5128 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5129 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5130 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5131 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5132 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5133 5134 /* MUX Indices: Stereo Mixer = 5 */ 5135 {0x17, AC_VERB_SET_CONNECT_SEL, 0x5}, 5136 5137 /* Setup default input of PW4 to MW0 */ 5138 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0}, 5139 5140 /* Setup default input of SW1 as MW0 */ 5141 {0x18, AC_VERB_SET_CONNECT_SEL, 0x1}, 5142 5143 /* Setup default input of SW4 as AOW0 */ 5144 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1}, 5145 5146 /* PW9 PW10 Output enable */ 5147 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5148 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5149 5150 /* Unmute SW1, PW12 */ 5151 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5152 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5153 /* PW12 Output enable */ 5154 {0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5155 /* Enable Boost Volume backdoor */ 5156 {0x1, 0xf8a, 0x80}, 5157 /* don't bybass mixer */ 5158 {0x1, 0xf88, 0xc0}, 5159 /* Enable mono output */ 5160 {0x1, 0xf90, 0x08}, 5161 { } 5162}; 5163 5164 5165static struct hda_verb vt1716S_uniwill_init_verbs[] = { 5166 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 5167 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, 5168 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5169 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5170 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5171 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 5172 AC_USRSP_EN | VIA_MONO_EVENT | VIA_JACK_EVENT}, 5173 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5174 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5175 { } 5176}; 5177 5178static struct hda_pcm_stream vt1716S_pcm_analog_playback = { 5179 .substreams = 2, 5180 .channels_min = 2, 5181 .channels_max = 6, 5182 .nid = 0x10, /* NID to query formats and rates */ 5183 .ops = { 5184 .open = via_playback_pcm_open, 5185 .prepare = via_playback_multi_pcm_prepare, 5186 .cleanup = via_playback_multi_pcm_cleanup, 5187 .close = via_pcm_open_close, 5188 }, 5189}; 5190 5191static struct hda_pcm_stream vt1716S_pcm_analog_capture = { 5192 .substreams = 2, 5193 .channels_min = 2, 5194 .channels_max = 2, 5195 .nid = 0x13, /* NID to query formats and rates */ 5196 .ops = { 5197 .open = via_pcm_open_close, 5198 .prepare = via_capture_pcm_prepare, 5199 .cleanup = via_capture_pcm_cleanup, 5200 .close = via_pcm_open_close, 5201 }, 5202}; 5203 5204static struct hda_pcm_stream vt1716S_pcm_digital_playback = { 5205 .substreams = 2, 5206 .channels_min = 2, 5207 .channels_max = 2, 5208 /* NID is set in via_build_pcms */ 5209 .ops = { 5210 .open = via_dig_playback_pcm_open, 5211 .close = via_dig_playback_pcm_close, 5212 .prepare = via_dig_playback_pcm_prepare, 5213 .cleanup = via_dig_playback_pcm_cleanup 5214 }, 5215}; 5216 5217/* fill in the dac_nids table from the parsed pin configuration */ 5218static int vt1716S_auto_fill_dac_nids(struct via_spec *spec, 5219 const struct auto_pin_cfg *cfg) 5220{ int i; 5221 hda_nid_t nid; 5222 5223 spec->multiout.num_dacs = cfg->line_outs; 5224 5225 spec->multiout.dac_nids = spec->private_dac_nids; 5226 5227 for (i = 0; i < 3; i++) { 5228 nid = cfg->line_out_pins[i]; 5229 if (nid) { 5230 /* config dac list */ 5231 switch (i) { 5232 case AUTO_SEQ_FRONT: 5233 spec->multiout.dac_nids[i] = 0x10; 5234 break; 5235 case AUTO_SEQ_CENLFE: 5236 spec->multiout.dac_nids[i] = 0x25; 5237 break; 5238 case AUTO_SEQ_SURROUND: 5239 spec->multiout.dac_nids[i] = 0x11; 5240 break; 5241 } 5242 } 5243 } 5244 5245 return 0; 5246} 5247 5248/* add playback controls from the parsed DAC table */ 5249static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec, 5250 const struct auto_pin_cfg *cfg) 5251{ 5252 char name[32]; 5253 static const char *chname[3] = { "Front", "Surround", "C/LFE" }; 5254 hda_nid_t nid_vols[] = {0x10, 0x11, 0x25}; 5255 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27}; 5256 hda_nid_t nid, nid_vol, nid_mute; 5257 int i, err; 5258 5259 for (i = 0; i <= AUTO_SEQ_CENLFE; i++) { 5260 nid = cfg->line_out_pins[i]; 5261 5262 if (!nid) 5263 continue; 5264 5265 nid_vol = nid_vols[i]; 5266 nid_mute = nid_mutes[i]; 5267 5268 if (i == AUTO_SEQ_CENLFE) { 5269 err = via_add_control( 5270 spec, VIA_CTL_WIDGET_VOL, 5271 "Center Playback Volume", 5272 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT)); 5273 if (err < 0) 5274 return err; 5275 err = via_add_control( 5276 spec, VIA_CTL_WIDGET_VOL, 5277 "LFE Playback Volume", 5278 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT)); 5279 if (err < 0) 5280 return err; 5281 err = via_add_control( 5282 spec, VIA_CTL_WIDGET_MUTE, 5283 "Center Playback Switch", 5284 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0, 5285 HDA_OUTPUT)); 5286 if (err < 0) 5287 return err; 5288 err = via_add_control( 5289 spec, VIA_CTL_WIDGET_MUTE, 5290 "LFE Playback Switch", 5291 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0, 5292 HDA_OUTPUT)); 5293 if (err < 0) 5294 return err; 5295 } else if (i == AUTO_SEQ_FRONT) { 5296 5297 err = via_add_control( 5298 spec, VIA_CTL_WIDGET_VOL, 5299 "Master Front Playback Volume", 5300 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT)); 5301 if (err < 0) 5302 return err; 5303 err = via_add_control( 5304 spec, VIA_CTL_WIDGET_MUTE, 5305 "Master Front Playback Switch", 5306 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT)); 5307 if (err < 0) 5308 return err; 5309 5310 sprintf(name, "%s Playback Volume", chname[i]); 5311 err = via_add_control( 5312 spec, VIA_CTL_WIDGET_VOL, name, 5313 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT)); 5314 if (err < 0) 5315 return err; 5316 sprintf(name, "%s Playback Switch", chname[i]); 5317 err = via_add_control( 5318 spec, VIA_CTL_WIDGET_MUTE, name, 5319 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0, 5320 HDA_OUTPUT)); 5321 if (err < 0) 5322 return err; 5323 } else { 5324 sprintf(name, "%s Playback Volume", chname[i]); 5325 err = via_add_control( 5326 spec, VIA_CTL_WIDGET_VOL, name, 5327 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT)); 5328 if (err < 0) 5329 return err; 5330 sprintf(name, "%s Playback Switch", chname[i]); 5331 err = via_add_control( 5332 spec, VIA_CTL_WIDGET_MUTE, name, 5333 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0, 5334 HDA_OUTPUT)); 5335 if (err < 0) 5336 return err; 5337 } 5338 } 5339 return 0; 5340} 5341 5342static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 5343{ 5344 int err; 5345 5346 if (!pin) 5347 return 0; 5348 5349 spec->multiout.hp_nid = 0x25; /* AOW3 */ 5350 spec->hp_independent_mode_index = 1; 5351 5352 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 5353 "Headphone Playback Volume", 5354 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT)); 5355 if (err < 0) 5356 return err; 5357 5358 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 5359 "Headphone Playback Switch", 5360 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 5361 if (err < 0) 5362 return err; 5363 5364 create_hp_imux(spec); 5365 return 0; 5366} 5367 5368/* create playback/capture controls for input pins */ 5369static int vt1716S_auto_create_analog_input_ctls(struct via_spec *spec, 5370 const struct auto_pin_cfg *cfg) 5371{ 5372 static char *labels[] = { 5373 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 5374 }; 5375 struct hda_input_mux *imux = &spec->private_imux[0]; 5376 int i, err, idx = 0; 5377 5378 /* for internal loopback recording select */ 5379 imux->items[imux->num_items].label = "Stereo Mixer"; 5380 imux->items[imux->num_items].index = 5; 5381 imux->num_items++; 5382 5383 for (i = 0; i < AUTO_PIN_LAST; i++) { 5384 if (!cfg->input_pins[i]) 5385 continue; 5386 5387 switch (cfg->input_pins[i]) { 5388 case 0x1a: /* Mic */ 5389 idx = 2; 5390 break; 5391 5392 case 0x1b: /* Line In */ 5393 idx = 3; 5394 break; 5395 5396 case 0x1e: /* Front Mic */ 5397 idx = 4; 5398 break; 5399 5400 case 0x1f: /* CD */ 5401 idx = 1; 5402 break; 5403 } 5404 err = via_new_analog_input(spec, labels[i], idx, 0x16); 5405 if (err < 0) 5406 return err; 5407 imux->items[imux->num_items].label = labels[i]; 5408 imux->items[imux->num_items].index = idx-1; 5409 imux->num_items++; 5410 } 5411 return 0; 5412} 5413 5414static int vt1716S_parse_auto_config(struct hda_codec *codec) 5415{ 5416 struct via_spec *spec = codec->spec; 5417 int err; 5418 5419 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 5420 if (err < 0) 5421 return err; 5422 err = vt1716S_auto_fill_dac_nids(spec, &spec->autocfg); 5423 if (err < 0) 5424 return err; 5425 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 5426 return 0; /* can't find valid BIOS pin config */ 5427 5428 err = vt1716S_auto_create_multi_out_ctls(spec, &spec->autocfg); 5429 if (err < 0) 5430 return err; 5431 err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 5432 if (err < 0) 5433 return err; 5434 err = vt1716S_auto_create_analog_input_ctls(spec, &spec->autocfg); 5435 if (err < 0) 5436 return err; 5437 5438 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5439 5440 fill_dig_outs(codec); 5441 5442 if (spec->kctls.list) 5443 spec->mixers[spec->num_mixers++] = spec->kctls.list; 5444 5445 spec->input_mux = &spec->private_imux[0]; 5446 5447 if (spec->hp_mux) 5448 via_hp_build(codec); 5449 5450 via_smart51_build(spec); 5451 5452 return 1; 5453} 5454 5455#ifdef CONFIG_SND_HDA_POWER_SAVE 5456static struct hda_amp_list vt1716S_loopbacks[] = { 5457 { 0x16, HDA_INPUT, 1 }, 5458 { 0x16, HDA_INPUT, 2 }, 5459 { 0x16, HDA_INPUT, 3 }, 5460 { 0x16, HDA_INPUT, 4 }, 5461 { } /* end */ 5462}; 5463#endif 5464 5465static int patch_vt1716S(struct hda_codec *codec) 5466{ 5467 struct via_spec *spec; 5468 int err; 5469 5470 /* create a codec specific record */ 5471 spec = via_new_spec(codec); 5472 if (spec == NULL) 5473 return -ENOMEM; 5474 5475 /* automatic parse from the BIOS config */ 5476 err = vt1716S_parse_auto_config(codec); 5477 if (err < 0) { 5478 via_free(codec); 5479 return err; 5480 } else if (!err) { 5481 printk(KERN_INFO "hda_codec: Cannot set up configuration " 5482 "from BIOS. Using genenic mode...\n"); 5483 } 5484 5485 spec->init_verbs[spec->num_iverbs++] = vt1716S_volume_init_verbs; 5486 spec->init_verbs[spec->num_iverbs++] = vt1716S_uniwill_init_verbs; 5487 5488 spec->stream_name_analog = "VT1716S Analog"; 5489 spec->stream_analog_playback = &vt1716S_pcm_analog_playback; 5490 spec->stream_analog_capture = &vt1716S_pcm_analog_capture; 5491 5492 spec->stream_name_digital = "VT1716S Digital"; 5493 spec->stream_digital_playback = &vt1716S_pcm_digital_playback; 5494 5495 if (!spec->adc_nids && spec->input_mux) { 5496 spec->adc_nids = vt1716S_adc_nids; 5497 spec->num_adc_nids = ARRAY_SIZE(vt1716S_adc_nids); 5498 get_mux_nids(codec); 5499 override_mic_boost(codec, 0x1a, 0, 3, 40); 5500 override_mic_boost(codec, 0x1e, 0, 3, 40); 5501 spec->mixers[spec->num_mixers] = vt1716S_capture_mixer; 5502 spec->num_mixers++; 5503 } 5504 5505 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer; 5506 spec->num_mixers++; 5507 5508 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer; 5509 5510 codec->patch_ops = via_patch_ops; 5511 5512 codec->patch_ops.init = via_auto_init; 5513 codec->patch_ops.unsol_event = via_unsol_event; 5514 5515#ifdef CONFIG_SND_HDA_POWER_SAVE 5516 spec->loopback.amplist = vt1716S_loopbacks; 5517#endif 5518 5519 return 0; 5520} 5521 5522/* for vt2002P */ 5523 5524/* capture mixer elements */ 5525static struct snd_kcontrol_new vt2002P_capture_mixer[] = { 5526 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), 5527 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), 5528 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), 5529 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT), 5530 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT), 5531 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0, 5532 HDA_INPUT), 5533 { 5534 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5535 /* The multiple "Capture Source" controls confuse alsamixer 5536 * So call somewhat different.. 5537 */ 5538 /* .name = "Capture Source", */ 5539 .name = "Input Source", 5540 .count = 2, 5541 .info = via_mux_enum_info, 5542 .get = via_mux_enum_get, 5543 .put = via_mux_enum_put, 5544 }, 5545 { } /* end */ 5546}; 5547 5548static struct hda_verb vt2002P_volume_init_verbs[] = { 5549 /* 5550 * Unmute ADC0-1 and set the default input to mic-in 5551 */ 5552 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5553 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5554 5555 5556 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5557 * mixer widget 5558 */ 5559 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 5560 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5561 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5562 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5563 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5564 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5565 5566 /* MUX Indices: Mic = 0 */ 5567 {0x1e, AC_VERB_SET_CONNECT_SEL, 0}, 5568 {0x1f, AC_VERB_SET_CONNECT_SEL, 0}, 5569 5570 /* PW9 Output enable */ 5571 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, 5572 5573 /* Enable Boost Volume backdoor */ 5574 {0x1, 0xfb9, 0x24}, 5575 5576 /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */ 5577 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5578 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5579 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5580 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5581 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5582 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5583 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5584 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5585 5586 /* set MUX0/1/4/8 = 0 (AOW0) */ 5587 {0x34, AC_VERB_SET_CONNECT_SEL, 0}, 5588 {0x35, AC_VERB_SET_CONNECT_SEL, 0}, 5589 {0x37, AC_VERB_SET_CONNECT_SEL, 0}, 5590 {0x3b, AC_VERB_SET_CONNECT_SEL, 0}, 5591 5592 /* set PW0 index=0 (MW0) */ 5593 {0x24, AC_VERB_SET_CONNECT_SEL, 0}, 5594 5595 /* Enable AOW0 to MW9 */ 5596 {0x1, 0xfb8, 0x88}, 5597 { } 5598}; 5599 5600 5601static struct hda_verb vt2002P_uniwill_init_verbs[] = { 5602 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, 5603 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, 5604 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, 5605 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, 5606 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5607 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5608 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5609 { } 5610}; 5611 5612static struct hda_pcm_stream vt2002P_pcm_analog_playback = { 5613 .substreams = 2, 5614 .channels_min = 2, 5615 .channels_max = 2, 5616 .nid = 0x8, /* NID to query formats and rates */ 5617 .ops = { 5618 .open = via_playback_pcm_open, 5619 .prepare = via_playback_multi_pcm_prepare, 5620 .cleanup = via_playback_multi_pcm_cleanup, 5621 .close = via_pcm_open_close, 5622 }, 5623}; 5624 5625static struct hda_pcm_stream vt2002P_pcm_analog_capture = { 5626 .substreams = 2, 5627 .channels_min = 2, 5628 .channels_max = 2, 5629 .nid = 0x10, /* NID to query formats and rates */ 5630 .ops = { 5631 .open = via_pcm_open_close, 5632 .prepare = via_capture_pcm_prepare, 5633 .cleanup = via_capture_pcm_cleanup, 5634 .close = via_pcm_open_close, 5635 }, 5636}; 5637 5638static struct hda_pcm_stream vt2002P_pcm_digital_playback = { 5639 .substreams = 1, 5640 .channels_min = 2, 5641 .channels_max = 2, 5642 /* NID is set in via_build_pcms */ 5643 .ops = { 5644 .open = via_dig_playback_pcm_open, 5645 .close = via_dig_playback_pcm_close, 5646 .prepare = via_dig_playback_pcm_prepare, 5647 .cleanup = via_dig_playback_pcm_cleanup 5648 }, 5649}; 5650 5651/* fill in the dac_nids table from the parsed pin configuration */ 5652static int vt2002P_auto_fill_dac_nids(struct via_spec *spec, 5653 const struct auto_pin_cfg *cfg) 5654{ 5655 spec->multiout.num_dacs = 1; 5656 spec->multiout.dac_nids = spec->private_dac_nids; 5657 if (cfg->line_out_pins[0]) 5658 spec->multiout.dac_nids[0] = 0x8; 5659 return 0; 5660} 5661 5662/* add playback controls from the parsed DAC table */ 5663static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec, 5664 const struct auto_pin_cfg *cfg) 5665{ 5666 int err; 5667 5668 if (!cfg->line_out_pins[0]) 5669 return -1; 5670 5671 5672 /* Line-Out: PortE */ 5673 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 5674 "Master Front Playback Volume", 5675 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT)); 5676 if (err < 0) 5677 return err; 5678 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, 5679 "Master Front Playback Switch", 5680 HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT)); 5681 if (err < 0) 5682 return err; 5683 5684 return 0; 5685} 5686 5687static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 5688{ 5689 int err; 5690 5691 if (!pin) 5692 return 0; 5693 5694 spec->multiout.hp_nid = 0x9; 5695 spec->hp_independent_mode_index = 1; 5696 5697 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 5698 "Headphone Playback Volume", 5699 HDA_COMPOSE_AMP_VAL( 5700 spec->multiout.hp_nid, 3, 0, HDA_OUTPUT)); 5701 if (err < 0) 5702 return err; 5703 5704 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 5705 "Headphone Playback Switch", 5706 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT)); 5707 if (err < 0) 5708 return err; 5709 5710 create_hp_imux(spec); 5711 return 0; 5712} 5713 5714/* create playback/capture controls for input pins */ 5715static int vt2002P_auto_create_analog_input_ctls(struct via_spec *spec, 5716 const struct auto_pin_cfg *cfg) 5717{ 5718 static char *labels[] = { 5719 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 5720 }; 5721 struct hda_input_mux *imux = &spec->private_imux[0]; 5722 int i, err, idx = 0; 5723 5724 for (i = 0; i < AUTO_PIN_LAST; i++) { 5725 if (!cfg->input_pins[i]) 5726 continue; 5727 5728 switch (cfg->input_pins[i]) { 5729 case 0x2b: /* Mic */ 5730 idx = 0; 5731 break; 5732 5733 case 0x2a: /* Line In */ 5734 idx = 1; 5735 break; 5736 5737 case 0x29: /* Front Mic */ 5738 idx = 2; 5739 break; 5740 } 5741 err = via_new_analog_input(spec, labels[i], idx, 0x21); 5742 if (err < 0) 5743 return err; 5744 imux->items[imux->num_items].label = labels[i]; 5745 imux->items[imux->num_items].index = idx; 5746 imux->num_items++; 5747 } 5748 5749 /* build volume/mute control of loopback */ 5750 err = via_new_analog_input(spec, "Stereo Mixer", 3, 0x21); 5751 if (err < 0) 5752 return err; 5753 5754 /* for internal loopback recording select */ 5755 imux->items[imux->num_items].label = "Stereo Mixer"; 5756 imux->items[imux->num_items].index = 3; 5757 imux->num_items++; 5758 5759 /* for digital mic select */ 5760 imux->items[imux->num_items].label = "Digital Mic"; 5761 imux->items[imux->num_items].index = 4; 5762 imux->num_items++; 5763 5764 return 0; 5765} 5766 5767static int vt2002P_parse_auto_config(struct hda_codec *codec) 5768{ 5769 struct via_spec *spec = codec->spec; 5770 int err; 5771 5772 5773 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 5774 if (err < 0) 5775 return err; 5776 5777 err = vt2002P_auto_fill_dac_nids(spec, &spec->autocfg); 5778 if (err < 0) 5779 return err; 5780 5781 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 5782 return 0; /* can't find valid BIOS pin config */ 5783 5784 err = vt2002P_auto_create_multi_out_ctls(spec, &spec->autocfg); 5785 if (err < 0) 5786 return err; 5787 err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 5788 if (err < 0) 5789 return err; 5790 err = vt2002P_auto_create_analog_input_ctls(spec, &spec->autocfg); 5791 if (err < 0) 5792 return err; 5793 5794 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5795 5796 fill_dig_outs(codec); 5797 5798 if (spec->kctls.list) 5799 spec->mixers[spec->num_mixers++] = spec->kctls.list; 5800 5801 spec->input_mux = &spec->private_imux[0]; 5802 5803 if (spec->hp_mux) 5804 via_hp_build(codec); 5805 5806 return 1; 5807} 5808 5809#ifdef CONFIG_SND_HDA_POWER_SAVE 5810static struct hda_amp_list vt2002P_loopbacks[] = { 5811 { 0x21, HDA_INPUT, 0 }, 5812 { 0x21, HDA_INPUT, 1 }, 5813 { 0x21, HDA_INPUT, 2 }, 5814 { } /* end */ 5815}; 5816#endif 5817 5818 5819/* patch for vt2002P */ 5820static int patch_vt2002P(struct hda_codec *codec) 5821{ 5822 struct via_spec *spec; 5823 int err; 5824 5825 /* create a codec specific record */ 5826 spec = via_new_spec(codec); 5827 if (spec == NULL) 5828 return -ENOMEM; 5829 5830 /* automatic parse from the BIOS config */ 5831 err = vt2002P_parse_auto_config(codec); 5832 if (err < 0) { 5833 via_free(codec); 5834 return err; 5835 } else if (!err) { 5836 printk(KERN_INFO "hda_codec: Cannot set up configuration " 5837 "from BIOS. Using genenic mode...\n"); 5838 } 5839 5840 spec->init_verbs[spec->num_iverbs++] = vt2002P_volume_init_verbs; 5841 spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs; 5842 5843 spec->stream_name_analog = "VT2002P Analog"; 5844 spec->stream_analog_playback = &vt2002P_pcm_analog_playback; 5845 spec->stream_analog_capture = &vt2002P_pcm_analog_capture; 5846 5847 spec->stream_name_digital = "VT2002P Digital"; 5848 spec->stream_digital_playback = &vt2002P_pcm_digital_playback; 5849 5850 if (!spec->adc_nids && spec->input_mux) { 5851 spec->adc_nids = vt2002P_adc_nids; 5852 spec->num_adc_nids = ARRAY_SIZE(vt2002P_adc_nids); 5853 get_mux_nids(codec); 5854 override_mic_boost(codec, 0x2b, 0, 3, 40); 5855 override_mic_boost(codec, 0x29, 0, 3, 40); 5856 spec->mixers[spec->num_mixers] = vt2002P_capture_mixer; 5857 spec->num_mixers++; 5858 } 5859 5860 codec->patch_ops = via_patch_ops; 5861 5862 codec->patch_ops.init = via_auto_init; 5863 codec->patch_ops.unsol_event = via_unsol_event; 5864 5865#ifdef CONFIG_SND_HDA_POWER_SAVE 5866 spec->loopback.amplist = vt2002P_loopbacks; 5867#endif 5868 5869 return 0; 5870} 5871 5872/* for vt1812 */ 5873 5874/* capture mixer elements */ 5875static struct snd_kcontrol_new vt1812_capture_mixer[] = { 5876 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), 5877 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), 5878 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), 5879 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT), 5880 HDA_CODEC_MUTE("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT), 5881 HDA_CODEC_MUTE("Front Mic Boost Capture Volume", 0x29, 0x0, 5882 HDA_INPUT), 5883 { 5884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5885 /* The multiple "Capture Source" controls confuse alsamixer 5886 * So call somewhat different.. 5887 */ 5888 .name = "Input Source", 5889 .count = 2, 5890 .info = via_mux_enum_info, 5891 .get = via_mux_enum_get, 5892 .put = via_mux_enum_put, 5893 }, 5894 { } /* end */ 5895}; 5896 5897static struct hda_verb vt1812_volume_init_verbs[] = { 5898 /* 5899 * Unmute ADC0-1 and set the default input to mic-in 5900 */ 5901 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5902 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5903 5904 5905 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 5906 * mixer widget 5907 */ 5908 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ 5909 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5910 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5911 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5912 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5913 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5914 5915 /* MUX Indices: Mic = 0 */ 5916 {0x1e, AC_VERB_SET_CONNECT_SEL, 0}, 5917 {0x1f, AC_VERB_SET_CONNECT_SEL, 0}, 5918 5919 /* PW9 Output enable */ 5920 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, 5921 5922 /* Enable Boost Volume backdoor */ 5923 {0x1, 0xfb9, 0x24}, 5924 5925 /* MW0/1/4/13/15: un-mute index 0 (MUXx), un-mute index 1 (MW9) */ 5926 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5927 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5928 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5929 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5930 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5931 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5932 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5933 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5934 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5935 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 5936 5937 /* set MUX0/1/4/13/15 = 0 (AOW0) */ 5938 {0x34, AC_VERB_SET_CONNECT_SEL, 0}, 5939 {0x35, AC_VERB_SET_CONNECT_SEL, 0}, 5940 {0x38, AC_VERB_SET_CONNECT_SEL, 0}, 5941 {0x3c, AC_VERB_SET_CONNECT_SEL, 0}, 5942 {0x3d, AC_VERB_SET_CONNECT_SEL, 0}, 5943 5944 /* Enable AOW0 to MW9 */ 5945 {0x1, 0xfb8, 0xa8}, 5946 { } 5947}; 5948 5949 5950static struct hda_verb vt1812_uniwill_init_verbs[] = { 5951 {0x33, AC_VERB_SET_UNSOLICITED_ENABLE, 5952 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, 5953 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT }, 5954 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE, 5955 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, 5956 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5957 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5958 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, 5959 { } 5960}; 5961 5962static struct hda_pcm_stream vt1812_pcm_analog_playback = { 5963 .substreams = 2, 5964 .channels_min = 2, 5965 .channels_max = 2, 5966 .nid = 0x8, /* NID to query formats and rates */ 5967 .ops = { 5968 .open = via_playback_pcm_open, 5969 .prepare = via_playback_multi_pcm_prepare, 5970 .cleanup = via_playback_multi_pcm_cleanup, 5971 .close = via_pcm_open_close, 5972 }, 5973}; 5974 5975static struct hda_pcm_stream vt1812_pcm_analog_capture = { 5976 .substreams = 2, 5977 .channels_min = 2, 5978 .channels_max = 2, 5979 .nid = 0x10, /* NID to query formats and rates */ 5980 .ops = { 5981 .open = via_pcm_open_close, 5982 .prepare = via_capture_pcm_prepare, 5983 .cleanup = via_capture_pcm_cleanup, 5984 .close = via_pcm_open_close, 5985 }, 5986}; 5987 5988static struct hda_pcm_stream vt1812_pcm_digital_playback = { 5989 .substreams = 1, 5990 .channels_min = 2, 5991 .channels_max = 2, 5992 /* NID is set in via_build_pcms */ 5993 .ops = { 5994 .open = via_dig_playback_pcm_open, 5995 .close = via_dig_playback_pcm_close, 5996 .prepare = via_dig_playback_pcm_prepare, 5997 .cleanup = via_dig_playback_pcm_cleanup 5998 }, 5999}; 6000/* fill in the dac_nids table from the parsed pin configuration */ 6001static int vt1812_auto_fill_dac_nids(struct via_spec *spec, 6002 const struct auto_pin_cfg *cfg) 6003{ 6004 spec->multiout.num_dacs = 1; 6005 spec->multiout.dac_nids = spec->private_dac_nids; 6006 if (cfg->line_out_pins[0]) 6007 spec->multiout.dac_nids[0] = 0x8; 6008 return 0; 6009} 6010 6011 6012/* add playback controls from the parsed DAC table */ 6013static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec, 6014 const struct auto_pin_cfg *cfg) 6015{ 6016 int err; 6017 6018 if (!cfg->line_out_pins[0]) 6019 return -1; 6020 6021 /* Line-Out: PortE */ 6022 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 6023 "Front Playback Volume", 6024 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT)); 6025 if (err < 0) 6026 return err; 6027 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, 6028 "Front Playback Switch", 6029 HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT)); 6030 if (err < 0) 6031 return err; 6032 6033 return 0; 6034} 6035 6036static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 6037{ 6038 int err; 6039 6040 if (!pin) 6041 return 0; 6042 6043 spec->multiout.hp_nid = 0x9; 6044 spec->hp_independent_mode_index = 1; 6045 6046 6047 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 6048 "Headphone Playback Volume", 6049 HDA_COMPOSE_AMP_VAL( 6050 spec->multiout.hp_nid, 3, 0, HDA_OUTPUT)); 6051 if (err < 0) 6052 return err; 6053 6054 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 6055 "Headphone Playback Switch", 6056 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 6057 if (err < 0) 6058 return err; 6059 6060 create_hp_imux(spec); 6061 return 0; 6062} 6063 6064/* create playback/capture controls for input pins */ 6065static int vt1812_auto_create_analog_input_ctls(struct via_spec *spec, 6066 const struct auto_pin_cfg *cfg) 6067{ 6068 static char *labels[] = { 6069 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL 6070 }; 6071 struct hda_input_mux *imux = &spec->private_imux[0]; 6072 int i, err, idx = 0; 6073 6074 for (i = 0; i < AUTO_PIN_LAST; i++) { 6075 if (!cfg->input_pins[i]) 6076 continue; 6077 6078 switch (cfg->input_pins[i]) { 6079 case 0x2b: /* Mic */ 6080 idx = 0; 6081 break; 6082 6083 case 0x2a: /* Line In */ 6084 idx = 1; 6085 break; 6086 6087 case 0x29: /* Front Mic */ 6088 idx = 2; 6089 break; 6090 } 6091 err = via_new_analog_input(spec, labels[i], idx, 0x21); 6092 if (err < 0) 6093 return err; 6094 imux->items[imux->num_items].label = labels[i]; 6095 imux->items[imux->num_items].index = idx; 6096 imux->num_items++; 6097 } 6098 /* build volume/mute control of loopback */ 6099 err = via_new_analog_input(spec, "Stereo Mixer", 5, 0x21); 6100 if (err < 0) 6101 return err; 6102 6103 /* for internal loopback recording select */ 6104 imux->items[imux->num_items].label = "Stereo Mixer"; 6105 imux->items[imux->num_items].index = 5; 6106 imux->num_items++; 6107 6108 /* for digital mic select */ 6109 imux->items[imux->num_items].label = "Digital Mic"; 6110 imux->items[imux->num_items].index = 6; 6111 imux->num_items++; 6112 6113 return 0; 6114} 6115 6116static int vt1812_parse_auto_config(struct hda_codec *codec) 6117{ 6118 struct via_spec *spec = codec->spec; 6119 int err; 6120 6121 6122 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 6123 if (err < 0) 6124 return err; 6125 fill_dig_outs(codec); 6126 err = vt1812_auto_fill_dac_nids(spec, &spec->autocfg); 6127 if (err < 0) 6128 return err; 6129 6130 if (!spec->autocfg.line_outs && !spec->autocfg.hp_outs) 6131 return 0; /* can't find valid BIOS pin config */ 6132 6133 err = vt1812_auto_create_multi_out_ctls(spec, &spec->autocfg); 6134 if (err < 0) 6135 return err; 6136 err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 6137 if (err < 0) 6138 return err; 6139 err = vt1812_auto_create_analog_input_ctls(spec, &spec->autocfg); 6140 if (err < 0) 6141 return err; 6142 6143 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 6144 6145 fill_dig_outs(codec); 6146 6147 if (spec->kctls.list) 6148 spec->mixers[spec->num_mixers++] = spec->kctls.list; 6149 6150 spec->input_mux = &spec->private_imux[0]; 6151 6152 if (spec->hp_mux) 6153 via_hp_build(codec); 6154 6155 return 1; 6156} 6157 6158#ifdef CONFIG_SND_HDA_POWER_SAVE 6159static struct hda_amp_list vt1812_loopbacks[] = { 6160 { 0x21, HDA_INPUT, 0 }, 6161 { 0x21, HDA_INPUT, 1 }, 6162 { 0x21, HDA_INPUT, 2 }, 6163 { } /* end */ 6164}; 6165#endif 6166 6167 6168/* patch for vt1812 */ 6169static int patch_vt1812(struct hda_codec *codec) 6170{ 6171 struct via_spec *spec; 6172 int err; 6173 6174 /* create a codec specific record */ 6175 spec = via_new_spec(codec); 6176 if (spec == NULL) 6177 return -ENOMEM; 6178 6179 /* automatic parse from the BIOS config */ 6180 err = vt1812_parse_auto_config(codec); 6181 if (err < 0) { 6182 via_free(codec); 6183 return err; 6184 } else if (!err) { 6185 printk(KERN_INFO "hda_codec: Cannot set up configuration " 6186 "from BIOS. Using genenic mode...\n"); 6187 } 6188 6189 6190 spec->init_verbs[spec->num_iverbs++] = vt1812_volume_init_verbs; 6191 spec->init_verbs[spec->num_iverbs++] = vt1812_uniwill_init_verbs; 6192 6193 spec->stream_name_analog = "VT1812 Analog"; 6194 spec->stream_analog_playback = &vt1812_pcm_analog_playback; 6195 spec->stream_analog_capture = &vt1812_pcm_analog_capture; 6196 6197 spec->stream_name_digital = "VT1812 Digital"; 6198 spec->stream_digital_playback = &vt1812_pcm_digital_playback; 6199 6200 6201 if (!spec->adc_nids && spec->input_mux) { 6202 spec->adc_nids = vt1812_adc_nids; 6203 spec->num_adc_nids = ARRAY_SIZE(vt1812_adc_nids); 6204 get_mux_nids(codec); 6205 override_mic_boost(codec, 0x2b, 0, 3, 40); 6206 override_mic_boost(codec, 0x29, 0, 3, 40); 6207 spec->mixers[spec->num_mixers] = vt1812_capture_mixer; 6208 spec->num_mixers++; 6209 } 6210 6211 codec->patch_ops = via_patch_ops; 6212 6213 codec->patch_ops.init = via_auto_init; 6214 codec->patch_ops.unsol_event = via_unsol_event; 6215 6216#ifdef CONFIG_SND_HDA_POWER_SAVE 6217 spec->loopback.amplist = vt1812_loopbacks; 6218#endif 6219 6220 return 0; 6221} 6222 6223/* 6224 * patch entries 6225 */ 6226static struct hda_codec_preset snd_hda_preset_via[] = { 6227 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708}, 6228 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708}, 6229 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708}, 6230 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708}, 6231 { .id = 0x1106e710, .name = "VT1709 10-Ch", 6232 .patch = patch_vt1709_10ch}, 6233 { .id = 0x1106e711, .name = "VT1709 10-Ch", 6234 .patch = patch_vt1709_10ch}, 6235 { .id = 0x1106e712, .name = "VT1709 10-Ch", 6236 .patch = patch_vt1709_10ch}, 6237 { .id = 0x1106e713, .name = "VT1709 10-Ch", 6238 .patch = patch_vt1709_10ch}, 6239 { .id = 0x1106e714, .name = "VT1709 6-Ch", 6240 .patch = patch_vt1709_6ch}, 6241 { .id = 0x1106e715, .name = "VT1709 6-Ch", 6242 .patch = patch_vt1709_6ch}, 6243 { .id = 0x1106e716, .name = "VT1709 6-Ch", 6244 .patch = patch_vt1709_6ch}, 6245 { .id = 0x1106e717, .name = "VT1709 6-Ch", 6246 .patch = patch_vt1709_6ch}, 6247 { .id = 0x1106e720, .name = "VT1708B 8-Ch", 6248 .patch = patch_vt1708B_8ch}, 6249 { .id = 0x1106e721, .name = "VT1708B 8-Ch", 6250 .patch = patch_vt1708B_8ch}, 6251 { .id = 0x1106e722, .name = "VT1708B 8-Ch", 6252 .patch = patch_vt1708B_8ch}, 6253 { .id = 0x1106e723, .name = "VT1708B 8-Ch", 6254 .patch = patch_vt1708B_8ch}, 6255 { .id = 0x1106e724, .name = "VT1708B 4-Ch", 6256 .patch = patch_vt1708B_4ch}, 6257 { .id = 0x1106e725, .name = "VT1708B 4-Ch", 6258 .patch = patch_vt1708B_4ch}, 6259 { .id = 0x1106e726, .name = "VT1708B 4-Ch", 6260 .patch = patch_vt1708B_4ch}, 6261 { .id = 0x1106e727, .name = "VT1708B 4-Ch", 6262 .patch = patch_vt1708B_4ch}, 6263 { .id = 0x11060397, .name = "VT1708S", 6264 .patch = patch_vt1708S}, 6265 { .id = 0x11061397, .name = "VT1708S", 6266 .patch = patch_vt1708S}, 6267 { .id = 0x11062397, .name = "VT1708S", 6268 .patch = patch_vt1708S}, 6269 { .id = 0x11063397, .name = "VT1708S", 6270 .patch = patch_vt1708S}, 6271 { .id = 0x11064397, .name = "VT1708S", 6272 .patch = patch_vt1708S}, 6273 { .id = 0x11065397, .name = "VT1708S", 6274 .patch = patch_vt1708S}, 6275 { .id = 0x11066397, .name = "VT1708S", 6276 .patch = patch_vt1708S}, 6277 { .id = 0x11067397, .name = "VT1708S", 6278 .patch = patch_vt1708S}, 6279 { .id = 0x11060398, .name = "VT1702", 6280 .patch = patch_vt1702}, 6281 { .id = 0x11061398, .name = "VT1702", 6282 .patch = patch_vt1702}, 6283 { .id = 0x11062398, .name = "VT1702", 6284 .patch = patch_vt1702}, 6285 { .id = 0x11063398, .name = "VT1702", 6286 .patch = patch_vt1702}, 6287 { .id = 0x11064398, .name = "VT1702", 6288 .patch = patch_vt1702}, 6289 { .id = 0x11065398, .name = "VT1702", 6290 .patch = patch_vt1702}, 6291 { .id = 0x11066398, .name = "VT1702", 6292 .patch = patch_vt1702}, 6293 { .id = 0x11067398, .name = "VT1702", 6294 .patch = patch_vt1702}, 6295 { .id = 0x11060428, .name = "VT1718S", 6296 .patch = patch_vt1718S}, 6297 { .id = 0x11064428, .name = "VT1718S", 6298 .patch = patch_vt1718S}, 6299 { .id = 0x11060441, .name = "VT2020", 6300 .patch = patch_vt1718S}, 6301 { .id = 0x11064441, .name = "VT1828S", 6302 .patch = patch_vt1718S}, 6303 { .id = 0x11060433, .name = "VT1716S", 6304 .patch = patch_vt1716S}, 6305 { .id = 0x1106a721, .name = "VT1716S", 6306 .patch = patch_vt1716S}, 6307 { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P}, 6308 { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P}, 6309 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812}, 6310 { .id = 0x11060440, .name = "VT1818S", 6311 .patch = patch_vt1708S}, 6312 {} /* terminator */ 6313}; 6314 6315MODULE_ALIAS("snd-hda-codec-id:1106*"); 6316 6317static struct hda_codec_preset_list via_list = { 6318 .preset = snd_hda_preset_via, 6319 .owner = THIS_MODULE, 6320}; 6321 6322MODULE_LICENSE("GPL"); 6323MODULE_DESCRIPTION("VIA HD-audio codec"); 6324 6325static int __init patch_via_init(void) 6326{ 6327 return snd_hda_add_codec_preset(&via_list); 6328} 6329 6330static void __exit patch_via_exit(void) 6331{ 6332 snd_hda_delete_codec_preset(&via_list); 6333} 6334 6335module_init(patch_via_init) 6336module_exit(patch_via_exit) 6337