1 /* 2 * HD audio interface patch for AD1981HD, AD1983, AD1986A, AD1988 3 * 4 * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de> 5 * 6 * This driver is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This driver is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 #include <sound/driver.h> 22 #include <linux/init.h> 23 #include <linux/delay.h> 24 #include <linux/slab.h> 25 #include <linux/pci.h> 26 #include <sound/core.h> 27 #include "hda_codec.h" 28 #include "hda_local.h" 29 30 struct ad198x_spec { 31 struct snd_kcontrol_new *mixers[5]; 32 int num_mixers; 33 34 const struct hda_verb *init_verbs[5]; /* initialization verbs 35 * don't forget NULL termination! 36 */ 37 unsigned int num_init_verbs; 38 39 /* playback */ 40 struct hda_multi_out multiout; /* playback set-up 41 * max_channels, dacs must be set 42 * dig_out_nid and hp_nid are optional 43 */ 44 unsigned int cur_eapd; 45 46 /* capture */ 47 unsigned int num_adc_nids; 48 hda_nid_t *adc_nids; 49 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 50 51 /* capture source */ 52 const struct hda_input_mux *input_mux; 53 hda_nid_t *capsrc_nids; 54 unsigned int cur_mux[3]; 55 56 /* channel model */ 57 const struct hda_channel_mode *channel_mode; 58 int num_channel_mode; 59 60 /* PCM information */ 61 struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ 62 63 struct semaphore amp_mutex; /* PCM volume/mute control mutex */ 64 unsigned int spdif_route; 65 66 /* dynamic controls, init_verbs and input_mux */ 67 struct auto_pin_cfg autocfg; 68 unsigned int num_kctl_alloc, num_kctl_used; 69 struct snd_kcontrol_new *kctl_alloc; 70 struct hda_input_mux private_imux; 71 hda_nid_t private_dac_nids[4]; 72 }; 73 74 /* 75 * input MUX handling (common part) 76 */ 77 static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 78 { 79 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 80 struct ad198x_spec *spec = codec->spec; 81 82 return snd_hda_input_mux_info(spec->input_mux, uinfo); 83 } 84 85 static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 86 { 87 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 88 struct ad198x_spec *spec = codec->spec; 89 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 90 91 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 92 return 0; 93 } 94 95 static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 96 { 97 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 98 struct ad198x_spec *spec = codec->spec; 99 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 100 101 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 102 spec->capsrc_nids[adc_idx], 103 &spec->cur_mux[adc_idx]); 104 } 105 106 /* 107 * initialization (common callbacks) 108 */ 109 static int ad198x_init(struct hda_codec *codec) 110 { 111 struct ad198x_spec *spec = codec->spec; 112 int i; 113 114 for (i = 0; i < spec->num_init_verbs; i++) 115 snd_hda_sequence_write(codec, spec->init_verbs[i]); 116 return 0; 117 } 118 119 static int ad198x_build_controls(struct hda_codec *codec) 120 { 121 struct ad198x_spec *spec = codec->spec; 122 unsigned int i; 123 int err; 124 125 for (i = 0; i < spec->num_mixers; i++) { 126 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 127 if (err < 0) 128 return err; 129 } 130 if (spec->multiout.dig_out_nid) { 131 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 132 if (err < 0) 133 return err; 134 } 135 if (spec->dig_in_nid) { 136 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 137 if (err < 0) 138 return err; 139 } 140 return 0; 141 } 142 143 /* 144 * Analog playback callbacks 145 */ 146 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo, 147 struct hda_codec *codec, 148 struct snd_pcm_substream *substream) 149 { 150 struct ad198x_spec *spec = codec->spec; 151 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); 152 } 153 154 static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 155 struct hda_codec *codec, 156 unsigned int stream_tag, 157 unsigned int format, 158 struct snd_pcm_substream *substream) 159 { 160 struct ad198x_spec *spec = codec->spec; 161 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, 162 format, substream); 163 } 164 165 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 166 struct hda_codec *codec, 167 struct snd_pcm_substream *substream) 168 { 169 struct ad198x_spec *spec = codec->spec; 170 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 171 } 172 173 /* 174 * Digital out 175 */ 176 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 177 struct hda_codec *codec, 178 struct snd_pcm_substream *substream) 179 { 180 struct ad198x_spec *spec = codec->spec; 181 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 182 } 183 184 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 185 struct hda_codec *codec, 186 struct snd_pcm_substream *substream) 187 { 188 struct ad198x_spec *spec = codec->spec; 189 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 190 } 191 192 /* 193 * Analog capture 194 */ 195 static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 196 struct hda_codec *codec, 197 unsigned int stream_tag, 198 unsigned int format, 199 struct snd_pcm_substream *substream) 200 { 201 struct ad198x_spec *spec = codec->spec; 202 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 203 stream_tag, 0, format); 204 return 0; 205 } 206 207 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 208 struct hda_codec *codec, 209 struct snd_pcm_substream *substream) 210 { 211 struct ad198x_spec *spec = codec->spec; 212 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 213 0, 0, 0); 214 return 0; 215 } 216 217 218 /* 219 */ 220 static struct hda_pcm_stream ad198x_pcm_analog_playback = { 221 .substreams = 1, 222 .channels_min = 2, 223 .channels_max = 6, /* changed later */ 224 .nid = 0, /* fill later */ 225 .ops = { 226 .open = ad198x_playback_pcm_open, 227 .prepare = ad198x_playback_pcm_prepare, 228 .cleanup = ad198x_playback_pcm_cleanup 229 }, 230 }; 231 232 static struct hda_pcm_stream ad198x_pcm_analog_capture = { 233 .substreams = 1, 234 .channels_min = 2, 235 .channels_max = 2, 236 .nid = 0, /* fill later */ 237 .ops = { 238 .prepare = ad198x_capture_pcm_prepare, 239 .cleanup = ad198x_capture_pcm_cleanup 240 }, 241 }; 242 243 static struct hda_pcm_stream ad198x_pcm_digital_playback = { 244 .substreams = 1, 245 .channels_min = 2, 246 .channels_max = 2, 247 .nid = 0, /* fill later */ 248 .ops = { 249 .open = ad198x_dig_playback_pcm_open, 250 .close = ad198x_dig_playback_pcm_close 251 }, 252 }; 253 254 static struct hda_pcm_stream ad198x_pcm_digital_capture = { 255 .substreams = 1, 256 .channels_min = 2, 257 .channels_max = 2, 258 /* NID is set in alc_build_pcms */ 259 }; 260 261 static int ad198x_build_pcms(struct hda_codec *codec) 262 { 263 struct ad198x_spec *spec = codec->spec; 264 struct hda_pcm *info = spec->pcm_rec; 265 266 codec->num_pcms = 1; 267 codec->pcm_info = info; 268 269 info->name = "AD198x Analog"; 270 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback; 271 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels; 272 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 273 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture; 274 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; 275 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 276 277 if (spec->multiout.dig_out_nid) { 278 info++; 279 codec->num_pcms++; 280 info->name = "AD198x Digital"; 281 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; 282 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 283 if (spec->dig_in_nid) { 284 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture; 285 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 286 } 287 } 288 289 return 0; 290 } 291 292 static void ad198x_free(struct hda_codec *codec) 293 { 294 struct ad198x_spec *spec = codec->spec; 295 unsigned int i; 296 297 if (spec->kctl_alloc) { 298 for (i = 0; i < spec->num_kctl_used; i++) 299 kfree(spec->kctl_alloc[i].name); 300 kfree(spec->kctl_alloc); 301 } 302 kfree(codec->spec); 303 } 304 305 #ifdef CONFIG_PM 306 static int ad198x_resume(struct hda_codec *codec) 307 { 308 struct ad198x_spec *spec = codec->spec; 309 int i; 310 311 ad198x_init(codec); 312 for (i = 0; i < spec->num_mixers; i++) 313 snd_hda_resume_ctls(codec, spec->mixers[i]); 314 if (spec->multiout.dig_out_nid) 315 snd_hda_resume_spdif_out(codec); 316 if (spec->dig_in_nid) 317 snd_hda_resume_spdif_in(codec); 318 return 0; 319 } 320 #endif 321 322 static struct hda_codec_ops ad198x_patch_ops = { 323 .build_controls = ad198x_build_controls, 324 .build_pcms = ad198x_build_pcms, 325 .init = ad198x_init, 326 .free = ad198x_free, 327 #ifdef CONFIG_PM 328 .resume = ad198x_resume, 329 #endif 330 }; 331 332 333 /* 334 * AD1986A specific 335 */ 336 337 #define AD1986A_SPDIF_OUT 0x02 338 #define AD1986A_FRONT_DAC 0x03 339 #define AD1986A_SURR_DAC 0x04 340 #define AD1986A_CLFE_DAC 0x05 341 #define AD1986A_ADC 0x06 342 343 static hda_nid_t ad1986a_dac_nids[3] = { 344 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC 345 }; 346 static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; 347 348 static struct hda_input_mux ad1986a_capture_source = { 349 .num_items = 7, 350 .items = { 351 { "Mic", 0x0 }, 352 { "CD", 0x1 }, 353 { "Aux", 0x3 }, 354 { "Line", 0x4 }, 355 { "Mix", 0x5 }, 356 { "Mono", 0x6 }, 357 { "Phone", 0x7 }, 358 }, 359 }; 360 361 /* 362 * PCM control 363 * 364 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity 365 */ 366 367 #define ad1986a_pcm_amp_vol_info snd_hda_mixer_amp_volume_info 368 369 static int ad1986a_pcm_amp_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 370 { 371 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 372 struct ad198x_spec *ad = codec->spec; 373 374 down(&ad->amp_mutex); 375 snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); 376 up(&ad->amp_mutex); 377 return 0; 378 } 379 380 static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 381 { 382 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 383 struct ad198x_spec *ad = codec->spec; 384 int i, change = 0; 385 386 down(&ad->amp_mutex); 387 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { 388 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); 389 change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); 390 } 391 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); 392 up(&ad->amp_mutex); 393 return change; 394 } 395 396 #define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_switch_info 397 398 static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 399 { 400 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 401 struct ad198x_spec *ad = codec->spec; 402 403 down(&ad->amp_mutex); 404 snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); 405 up(&ad->amp_mutex); 406 return 0; 407 } 408 409 static int ad1986a_pcm_amp_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 410 { 411 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 412 struct ad198x_spec *ad = codec->spec; 413 int i, change = 0; 414 415 down(&ad->amp_mutex); 416 for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { 417 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); 418 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 419 } 420 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); 421 up(&ad->amp_mutex); 422 return change; 423 } 424 425 /* 426 * mixers 427 */ 428 static struct snd_kcontrol_new ad1986a_mixers[] = { 429 { 430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 431 .name = "PCM Playback Volume", 432 .info = ad1986a_pcm_amp_vol_info, 433 .get = ad1986a_pcm_amp_vol_get, 434 .put = ad1986a_pcm_amp_vol_put, 435 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT) 436 }, 437 { 438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 439 .name = "PCM Playback Switch", 440 .info = ad1986a_pcm_amp_sw_info, 441 .get = ad1986a_pcm_amp_sw_get, 442 .put = ad1986a_pcm_amp_sw_put, 443 .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT) 444 }, 445 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 446 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 447 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 448 HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 449 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT), 450 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT), 451 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT), 452 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT), 453 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT), 454 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 455 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), 456 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), 457 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), 458 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), 459 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), 460 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 462 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 463 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT), 464 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT), 465 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 466 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), 467 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 468 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 469 { 470 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 471 .name = "Capture Source", 472 .info = ad198x_mux_enum_info, 473 .get = ad198x_mux_enum_get, 474 .put = ad198x_mux_enum_put, 475 }, 476 HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT), 477 { } /* end */ 478 }; 479 480 /* 481 * initialization verbs 482 */ 483 static struct hda_verb ad1986a_init_verbs[] = { 484 /* Front, Surround, CLFE DAC; mute as default */ 485 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 486 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 487 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 488 /* Downmix - off */ 489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 490 /* HP, Line-Out, Surround, CLFE selectors */ 491 {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0}, 492 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, 493 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, 494 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 495 /* Mono selector */ 496 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0}, 497 /* Mic selector: Mic 1/2 pin */ 498 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0}, 499 /* Line-in selector: Line-in */ 500 {0x10, AC_VERB_SET_CONNECT_SEL, 0x0}, 501 /* Mic 1/2 swap */ 502 {0x11, AC_VERB_SET_CONNECT_SEL, 0x0}, 503 /* Record selector: mic */ 504 {0x12, AC_VERB_SET_CONNECT_SEL, 0x0}, 505 /* Mic, Phone, CD, Aux, Line-In amp; mute as default */ 506 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 507 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 508 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 509 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 510 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 511 /* PC beep */ 512 {0x18, AC_VERB_SET_CONNECT_SEL, 0x0}, 513 /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */ 514 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 515 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 516 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 517 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 518 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 519 /* HP Pin */ 520 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 521 /* Front, Surround, CLFE Pins */ 522 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 523 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 524 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 525 /* Mono Pin */ 526 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 527 /* Mic Pin */ 528 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 529 /* Line, Aux, CD, Beep-In Pin */ 530 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 531 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 532 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 533 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 534 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 535 { } /* end */ 536 }; 537 538 539 static int patch_ad1986a(struct hda_codec *codec) 540 { 541 struct ad198x_spec *spec; 542 543 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 544 if (spec == NULL) 545 return -ENOMEM; 546 547 init_MUTEX(&spec->amp_mutex); 548 codec->spec = spec; 549 550 spec->multiout.max_channels = 6; 551 spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids); 552 spec->multiout.dac_nids = ad1986a_dac_nids; 553 spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; 554 spec->num_adc_nids = 1; 555 spec->adc_nids = ad1986a_adc_nids; 556 spec->capsrc_nids = ad1986a_adc_nids; 557 spec->input_mux = &ad1986a_capture_source; 558 spec->num_mixers = 1; 559 spec->mixers[0] = ad1986a_mixers; 560 spec->num_init_verbs = 1; 561 spec->init_verbs[0] = ad1986a_init_verbs; 562 563 codec->patch_ops = ad198x_patch_ops; 564 565 return 0; 566 } 567 568 /* 569 * AD1983 specific 570 */ 571 572 #define AD1983_SPDIF_OUT 0x02 573 #define AD1983_DAC 0x03 574 #define AD1983_ADC 0x04 575 576 static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; 577 static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; 578 579 static struct hda_input_mux ad1983_capture_source = { 580 .num_items = 4, 581 .items = { 582 { "Mic", 0x0 }, 583 { "Line", 0x1 }, 584 { "Mix", 0x2 }, 585 { "Mix Mono", 0x3 }, 586 }, 587 }; 588 589 /* 590 * SPDIF playback route 591 */ 592 static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 593 { 594 static char *texts[] = { "PCM", "ADC" }; 595 596 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 597 uinfo->count = 1; 598 uinfo->value.enumerated.items = 2; 599 if (uinfo->value.enumerated.item > 1) 600 uinfo->value.enumerated.item = 1; 601 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 602 return 0; 603 } 604 605 static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 606 { 607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 608 struct ad198x_spec *spec = codec->spec; 609 610 ucontrol->value.enumerated.item[0] = spec->spdif_route; 611 return 0; 612 } 613 614 static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 615 { 616 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 617 struct ad198x_spec *spec = codec->spec; 618 619 if (spec->spdif_route != ucontrol->value.enumerated.item[0]) { 620 spec->spdif_route = ucontrol->value.enumerated.item[0]; 621 snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0, 622 AC_VERB_SET_CONNECT_SEL, spec->spdif_route); 623 return 1; 624 } 625 return 0; 626 } 627 628 static struct snd_kcontrol_new ad1983_mixers[] = { 629 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), 630 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), 631 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), 632 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT), 633 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT), 634 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT), 635 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 636 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 638 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 639 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), 640 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), 641 HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT), 642 HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT), 643 HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT), 644 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 645 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 646 { 647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 648 .name = "Capture Source", 649 .info = ad198x_mux_enum_info, 650 .get = ad198x_mux_enum_get, 651 .put = ad198x_mux_enum_put, 652 }, 653 { 654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 655 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", 656 .info = ad1983_spdif_route_info, 657 .get = ad1983_spdif_route_get, 658 .put = ad1983_spdif_route_put, 659 }, 660 { } /* end */ 661 }; 662 663 static struct hda_verb ad1983_init_verbs[] = { 664 /* Front, HP, Mono; mute as default */ 665 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 666 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 667 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 668 /* Beep, PCM, Mic, Line-In: mute */ 669 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 670 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 671 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 672 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 673 /* Front, HP selectors; from Mix */ 674 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 675 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01}, 676 /* Mono selector; from Mix */ 677 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03}, 678 /* Mic selector; Mic */ 679 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, 680 /* Line-in selector: Line-in */ 681 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 682 /* Mic boost: 0dB */ 683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 684 /* Record selector: mic */ 685 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, 686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 687 /* SPDIF route: PCM */ 688 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, 689 /* Front Pin */ 690 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 691 /* HP Pin */ 692 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 693 /* Mono Pin */ 694 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 695 /* Mic Pin */ 696 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 697 /* Line Pin */ 698 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 699 { } /* end */ 700 }; 701 702 703 static int patch_ad1983(struct hda_codec *codec) 704 { 705 struct ad198x_spec *spec; 706 707 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 708 if (spec == NULL) 709 return -ENOMEM; 710 711 init_MUTEX(&spec->amp_mutex); 712 codec->spec = spec; 713 714 spec->multiout.max_channels = 2; 715 spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids); 716 spec->multiout.dac_nids = ad1983_dac_nids; 717 spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; 718 spec->num_adc_nids = 1; 719 spec->adc_nids = ad1983_adc_nids; 720 spec->capsrc_nids = ad1983_adc_nids; 721 spec->input_mux = &ad1983_capture_source; 722 spec->num_mixers = 1; 723 spec->mixers[0] = ad1983_mixers; 724 spec->num_init_verbs = 1; 725 spec->init_verbs[0] = ad1983_init_verbs; 726 spec->spdif_route = 0; 727 728 codec->patch_ops = ad198x_patch_ops; 729 730 return 0; 731 } 732 733 734 /* 735 * AD1981 HD specific 736 */ 737 738 #define AD1981_SPDIF_OUT 0x02 739 #define AD1981_DAC 0x03 740 #define AD1981_ADC 0x04 741 742 static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; 743 static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; 744 745 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ 746 static struct hda_input_mux ad1981_capture_source = { 747 .num_items = 7, 748 .items = { 749 { "Front Mic", 0x0 }, 750 { "Line", 0x1 }, 751 { "Mix", 0x2 }, 752 { "Mix Mono", 0x3 }, 753 { "CD", 0x4 }, 754 { "Mic", 0x6 }, 755 { "Aux", 0x7 }, 756 }, 757 }; 758 759 static struct snd_kcontrol_new ad1981_mixers[] = { 760 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), 761 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), 762 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), 763 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT), 764 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT), 765 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT), 766 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 767 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 768 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 769 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 770 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), 771 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), 772 HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 773 HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 774 HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 775 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 776 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 777 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 778 HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 779 HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT), 780 HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT), 781 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT), 782 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 783 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 784 { 785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 786 .name = "Capture Source", 787 .info = ad198x_mux_enum_info, 788 .get = ad198x_mux_enum_get, 789 .put = ad198x_mux_enum_put, 790 }, 791 /* identical with AD1983 */ 792 { 793 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 794 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", 795 .info = ad1983_spdif_route_info, 796 .get = ad1983_spdif_route_get, 797 .put = ad1983_spdif_route_put, 798 }, 799 { } /* end */ 800 }; 801 802 static struct hda_verb ad1981_init_verbs[] = { 803 /* Front, HP, Mono; mute as default */ 804 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 805 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 806 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 807 /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */ 808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 809 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 810 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 811 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 812 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 813 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 814 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 815 /* Front, HP selectors; from Mix */ 816 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 817 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01}, 818 /* Mono selector; from Mix */ 819 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03}, 820 /* Mic Mixer; select Front Mic */ 821 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 822 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 823 /* Mic boost: 0dB */ 824 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 825 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 826 /* Record selector: Front mic */ 827 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, 828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 829 /* SPDIF route: PCM */ 830 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, 831 /* Front Pin */ 832 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 833 /* HP Pin */ 834 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 835 /* Mono Pin */ 836 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 837 /* Front & Rear Mic Pins */ 838 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 839 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 840 /* Line Pin */ 841 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 842 /* Digital Beep */ 843 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 844 /* Line-Out as Input: disabled */ 845 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 846 { } /* end */ 847 }; 848 849 static int patch_ad1981(struct hda_codec *codec) 850 { 851 struct ad198x_spec *spec; 852 853 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 854 if (spec == NULL) 855 return -ENOMEM; 856 857 init_MUTEX(&spec->amp_mutex); 858 codec->spec = spec; 859 860 spec->multiout.max_channels = 2; 861 spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids); 862 spec->multiout.dac_nids = ad1981_dac_nids; 863 spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; 864 spec->num_adc_nids = 1; 865 spec->adc_nids = ad1981_adc_nids; 866 spec->capsrc_nids = ad1981_adc_nids; 867 spec->input_mux = &ad1981_capture_source; 868 spec->num_mixers = 1; 869 spec->mixers[0] = ad1981_mixers; 870 spec->num_init_verbs = 1; 871 spec->init_verbs[0] = ad1981_init_verbs; 872 spec->spdif_route = 0; 873 874 codec->patch_ops = ad198x_patch_ops; 875 876 return 0; 877 } 878 879 880 /* 881 * AD1988 882 * 883 * Output pins and routes 884 * 885 * Pin Mix Sel DAC (*) 886 * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06 887 * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06 888 * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a 889 * port-D 0x12 (mute/hp) <- 0x29 <- 04 890 * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a 891 * port-F 0x16 (mute) <- 0x2a <- 06 892 * port-G 0x24 (mute) <- 0x27 <- 05 893 * port-H 0x25 (mute) <- 0x28 <- 0a 894 * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06 895 * 896 * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah 897 * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug. 898 * 899 * Input pins and routes 900 * 901 * pin boost mix input # / adc input # 902 * port-A 0x11 -> 0x38 -> mix 2, ADC 0 903 * port-B 0x14 -> 0x39 -> mix 0, ADC 1 904 * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2 905 * port-D 0x12 -> 0x3d -> mix 3, ADC 8 906 * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4 907 * port-F 0x16 -> 0x3b -> mix 5, ADC 3 908 * port-G 0x24 -> N/A -> 33:1 - mix 1, 34:1 - mix 4, ADC 6 909 * port-H 0x25 -> N/A -> 33:2 - mix 1, 34:2 - mix 4, ADC 7 910 * 911 * 912 * DAC assignment 913 * 6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03 914 * 3stack - front/surr/CLFE/opt DACs - 04/05/0a/03 915 * 916 * Inputs of Analog Mix (0x20) 917 * 0:Port-B (front mic) 918 * 1:Port-C/G/H (line-in) 919 * 2:Port-A 920 * 3:Port-D (line-in/2) 921 * 4:Port-E/G/H (mic-in) 922 * 5:Port-F (mic2-in) 923 * 6:CD 924 * 7:Beep 925 * 926 * ADC selection 927 * 0:Port-A 928 * 1:Port-B (front mic-in) 929 * 2:Port-C (line-in) 930 * 3:Port-F (mic2-in) 931 * 4:Port-E (mic-in) 932 * 5:CD 933 * 6:Port-G 934 * 7:Port-H 935 * 8:Port-D (line-in/2) 936 * 9:Mix 937 * 938 * Proposed pin assignments by the datasheet 939 * 940 * 6-stack 941 * Port-A front headphone 942 * B front mic-in 943 * C rear line-in 944 * D rear front-out 945 * E rear mic-in 946 * F rear surround 947 * G rear CLFE 948 * H rear side 949 * 950 * 3-stack 951 * Port-A front headphone 952 * B front mic 953 * C rear line-in/surround 954 * D rear front-out 955 * E rear mic-in/CLFE 956 * 957 * laptop 958 * Port-A headphone 959 * B mic-in 960 * C docking station 961 * D internal speaker (with EAPD) 962 * E/F quad mic array 963 */ 964 965 966 /* models */ 967 enum { 968 AD1988_6STACK, 969 AD1988_6STACK_DIG, 970 AD1988_3STACK, 971 AD1988_3STACK_DIG, 972 AD1988_LAPTOP, 973 AD1988_LAPTOP_DIG, 974 AD1988_AUTO, 975 AD1988_MODEL_LAST, 976 }; 977 978 /* reivision id to check workarounds */ 979 #define AD1988A_REV2 0x100200 980 981 982 /* 983 * mixers 984 */ 985 986 static hda_nid_t ad1988_6stack_dac_nids[4] = { 987 0x04, 0x06, 0x05, 0x0a 988 }; 989 990 static hda_nid_t ad1988_3stack_dac_nids[3] = { 991 0x04, 0x05, 0x0a 992 }; 993 994 /* for AD1988A revision-2, DAC2-4 are swapped */ 995 static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { 996 0x04, 0x05, 0x0a, 0x06 997 }; 998 999 static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { 1000 0x04, 0x0a, 0x06 1001 }; 1002 1003 static hda_nid_t ad1988_adc_nids[3] = { 1004 0x08, 0x09, 0x0f 1005 }; 1006 1007 static hda_nid_t ad1988_capsrc_nids[3] = { 1008 0x0c, 0x0d, 0x0e 1009 }; 1010 1011 #define AD1988_SPDIF_OUT 0x02 1012 #define AD1988_SPDIF_IN 0x07 1013 1014 static struct hda_input_mux ad1988_6stack_capture_source = { 1015 .num_items = 5, 1016 .items = { 1017 { "Front Mic", 0x0 }, 1018 { "Line", 0x1 }, 1019 { "Mic", 0x4 }, 1020 { "CD", 0x5 }, 1021 { "Mix", 0x9 }, 1022 }, 1023 }; 1024 1025 static struct hda_input_mux ad1988_laptop_capture_source = { 1026 .num_items = 3, 1027 .items = { 1028 { "Mic/Line", 0x0 }, 1029 { "CD", 0x5 }, 1030 { "Mix", 0x9 }, 1031 }, 1032 }; 1033 1034 /* 1035 */ 1036 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, 1037 struct snd_ctl_elem_info *uinfo) 1038 { 1039 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1040 struct ad198x_spec *spec = codec->spec; 1041 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 1042 spec->num_channel_mode); 1043 } 1044 1045 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, 1046 struct snd_ctl_elem_value *ucontrol) 1047 { 1048 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1049 struct ad198x_spec *spec = codec->spec; 1050 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 1051 spec->num_channel_mode, spec->multiout.max_channels); 1052 } 1053 1054 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, 1055 struct snd_ctl_elem_value *ucontrol) 1056 { 1057 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1058 struct ad198x_spec *spec = codec->spec; 1059 return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 1060 spec->num_channel_mode, &spec->multiout.max_channels); 1061 } 1062 1063 /* 1064 * EAPD control 1065 */ 1066 static int ad1988_eapd_info(struct snd_kcontrol *kcontrol, 1067 struct snd_ctl_elem_info *uinfo) 1068 { 1069 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1070 uinfo->count = 1; 1071 uinfo->value.integer.min = 0; 1072 uinfo->value.integer.max = 1; 1073 return 0; 1074 } 1075 1076 static int ad1988_eapd_get(struct snd_kcontrol *kcontrol, 1077 struct snd_ctl_elem_value *ucontrol) 1078 { 1079 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1080 struct ad198x_spec *spec = codec->spec; 1081 ucontrol->value.enumerated.item[0] = ! spec->cur_eapd; 1082 return 0; 1083 } 1084 1085 static int ad1988_eapd_put(struct snd_kcontrol *kcontrol, 1086 struct snd_ctl_elem_value *ucontrol) 1087 { 1088 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1089 struct ad198x_spec *spec = codec->spec; 1090 unsigned int eapd; 1091 eapd = ! ucontrol->value.enumerated.item[0]; 1092 if (eapd == spec->cur_eapd && ! codec->in_resume) 1093 return 0; 1094 spec->cur_eapd = eapd; 1095 snd_hda_codec_write(codec, 0x12 /* port-D */, 1096 0, AC_VERB_SET_EAPD_BTLENABLE, 1097 eapd ? 0x02 : 0x00); 1098 return 0; 1099 } 1100 1101 /* 6-stack mode */ 1102 static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { 1103 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 1104 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), 1105 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 1106 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), 1107 HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 1108 }; 1109 1110 static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { 1111 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 1112 HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT), 1113 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 1114 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT), 1115 HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT), 1116 }; 1117 1118 static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { 1119 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 1120 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), 1121 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), 1122 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT), 1123 HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT), 1124 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), 1125 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 1126 1127 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), 1128 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), 1129 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT), 1130 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT), 1131 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), 1132 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), 1133 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT), 1134 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT), 1135 1136 HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT), 1137 HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT), 1138 1139 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 1140 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 1141 1142 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 1143 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 1144 1145 { } /* end */ 1146 }; 1147 1148 /* 3-stack mode */ 1149 static struct snd_kcontrol_new ad1988_3stack_mixers1[] = { 1150 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 1151 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 1152 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 1153 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), 1154 }; 1155 1156 static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { 1157 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 1158 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 1159 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT), 1160 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT), 1161 }; 1162 1163 static struct snd_kcontrol_new ad1988_3stack_mixers2[] = { 1164 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 1165 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), 1166 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), 1167 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT), 1168 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), 1169 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 1170 1171 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), 1172 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), 1173 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT), 1174 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT), 1175 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), 1176 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), 1177 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT), 1178 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT), 1179 1180 HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT), 1181 HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT), 1182 1183 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 1184 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 1185 1186 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 1187 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 1188 { 1189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1190 .name = "Channel Mode", 1191 .info = ad198x_ch_mode_info, 1192 .get = ad198x_ch_mode_get, 1193 .put = ad198x_ch_mode_put, 1194 }, 1195 1196 { } /* end */ 1197 }; 1198 1199 /* laptop mode */ 1200 static struct snd_kcontrol_new ad1988_laptop_mixers[] = { 1201 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 1202 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), 1203 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 1204 1205 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), 1206 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), 1207 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT), 1208 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT), 1209 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), 1210 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), 1211 1212 HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT), 1213 HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT), 1214 1215 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 1216 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 1217 1218 HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT), 1219 1220 { 1221 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1222 .name = "External Amplifier", 1223 .info = ad1988_eapd_info, 1224 .get = ad1988_eapd_get, 1225 .put = ad1988_eapd_put, 1226 }, 1227 1228 { } /* end */ 1229 }; 1230 1231 /* capture */ 1232 static struct snd_kcontrol_new ad1988_capture_mixers[] = { 1233 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 1234 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 1235 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 1236 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 1237 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT), 1238 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT), 1239 { 1240 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1241 /* The multiple "Capture Source" controls confuse alsamixer 1242 * So call somewhat different.. 1243 * FIXME: the controls appear in the "playback" view! 1244 */ 1245 /* .name = "Capture Source", */ 1246 .name = "Input Source", 1247 .count = 3, 1248 .info = ad198x_mux_enum_info, 1249 .get = ad198x_mux_enum_get, 1250 .put = ad198x_mux_enum_put, 1251 }, 1252 { } /* end */ 1253 }; 1254 1255 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol, 1256 struct snd_ctl_elem_info *uinfo) 1257 { 1258 static char *texts[] = { 1259 "PCM", "ADC1", "ADC2", "ADC3" 1260 }; 1261 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1262 uinfo->count = 1; 1263 uinfo->value.enumerated.items = 4; 1264 if (uinfo->value.enumerated.item >= 4) 1265 uinfo->value.enumerated.item = 3; 1266 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 1267 return 0; 1268 } 1269 1270 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol, 1271 struct snd_ctl_elem_value *ucontrol) 1272 { 1273 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1274 unsigned int sel; 1275 1276 sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); 1277 if (sel > 0) { 1278 sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0); 1279 if (sel <= 3) 1280 sel++; 1281 else 1282 sel = 0; 1283 } 1284 ucontrol->value.enumerated.item[0] = sel; 1285 return 0; 1286 } 1287 1288 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, 1289 struct snd_ctl_elem_value *ucontrol) 1290 { 1291 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1292 unsigned int sel; 1293 int change; 1294 1295 sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); 1296 if (! ucontrol->value.enumerated.item[0]) { 1297 change = sel != 0; 1298 if (change) 1299 snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0); 1300 } else { 1301 change = sel == 0; 1302 if (change) 1303 snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1); 1304 sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1; 1305 change |= sel == ucontrol->value.enumerated.item[0]; 1306 if (change) 1307 snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1308 ucontrol->value.enumerated.item[0] - 1); 1309 } 1310 return change; 1311 } 1312 1313 static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { 1314 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 1315 { 1316 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1317 .name = "IEC958 Playback Source", 1318 .info = ad1988_spdif_playback_source_info, 1319 .get = ad1988_spdif_playback_source_get, 1320 .put = ad1988_spdif_playback_source_put, 1321 }, 1322 { } /* end */ 1323 }; 1324 1325 static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { 1326 HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT), 1327 { } /* end */ 1328 }; 1329 1330 1331 /* 1332 * initialization verbs 1333 */ 1334 1335 /* 1336 * for 6-stack (+dig) 1337 */ 1338 static struct hda_verb ad1988_6stack_init_verbs[] = { 1339 /* Front, Surround, CLFE, side DAC; unmute as default */ 1340 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1341 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1342 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1343 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1344 /* Port-A front headphon path */ 1345 {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */ 1346 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1347 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1348 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1349 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1350 /* Port-D line-out path */ 1351 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1352 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1353 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1354 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1355 /* Port-F surround path */ 1356 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1357 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1358 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1359 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1360 /* Port-G CLFE path */ 1361 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1362 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1363 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1364 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1365 /* Port-H side path */ 1366 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1367 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1368 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1369 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1370 /* Mono out path */ 1371 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ 1372 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1373 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1374 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1375 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ 1376 /* Port-B front mic-in path */ 1377 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1378 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1379 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1380 /* Port-C line-in path */ 1381 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1383 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1384 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, 1385 /* Port-E mic-in path */ 1386 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1387 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1388 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1389 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, 1390 1391 { } 1392 }; 1393 1394 static struct hda_verb ad1988_capture_init_verbs[] = { 1395 /* mute analog mix */ 1396 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1397 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1398 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1399 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1400 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1401 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 1402 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1403 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1404 /* select ADCs - front-mic */ 1405 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 1406 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, 1407 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 1408 /* ADCs; muted */ 1409 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1410 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1411 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1412 1413 { } 1414 }; 1415 1416 static struct hda_verb ad1988_spdif_init_verbs[] = { 1417 /* SPDIF out sel */ 1418 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ 1419 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ 1420 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1421 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1422 /* SPDIF out pin */ 1423 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 1424 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x17}, /* 0dB */ 1425 1426 { } 1427 }; 1428 1429 /* 1430 * verbs for 3stack (+dig) 1431 */ 1432 static struct hda_verb ad1988_3stack_ch2_init[] = { 1433 /* set port-C to line-in */ 1434 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1435 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1436 /* set port-E to mic-in */ 1437 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1438 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1439 { } /* end */ 1440 }; 1441 1442 static struct hda_verb ad1988_3stack_ch6_init[] = { 1443 /* set port-C to surround out */ 1444 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1445 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1446 /* set port-E to CLFE out */ 1447 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1448 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1449 { } /* end */ 1450 }; 1451 1452 static struct hda_channel_mode ad1988_3stack_modes[2] = { 1453 { 2, ad1988_3stack_ch2_init }, 1454 { 6, ad1988_3stack_ch6_init }, 1455 }; 1456 1457 static struct hda_verb ad1988_3stack_init_verbs[] = { 1458 /* Front, Surround, CLFE, side DAC; unmute as default */ 1459 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1460 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1461 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1462 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1463 /* Port-A front headphon path */ 1464 {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */ 1465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1466 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1467 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1468 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1469 /* Port-D line-out path */ 1470 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1471 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1472 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1473 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1474 /* Mono out path */ 1475 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ 1476 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1477 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1478 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1479 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ 1480 /* Port-B front mic-in path */ 1481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1482 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1483 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1484 /* Port-C line-in/surround path - 6ch mode as default */ 1485 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1486 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1487 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1488 {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */ 1489 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, 1490 /* Port-E mic-in/CLFE path - 6ch mode as default */ 1491 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1492 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1493 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1494 {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */ 1495 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, 1496 /* mute analog mix */ 1497 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1498 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1499 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1500 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1501 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1502 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 1503 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1504 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1505 /* select ADCs - front-mic */ 1506 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 1507 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, 1508 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 1509 /* ADCs; muted */ 1510 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1511 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1512 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1513 { } 1514 }; 1515 1516 /* 1517 * verbs for laptop mode (+dig) 1518 */ 1519 static struct hda_verb ad1988_laptop_hp_on[] = { 1520 /* unmute port-A and mute port-D */ 1521 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1522 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1523 { } /* end */ 1524 }; 1525 static struct hda_verb ad1988_laptop_hp_off[] = { 1526 /* mute port-A and unmute port-D */ 1527 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1528 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1529 { } /* end */ 1530 }; 1531 1532 #define AD1988_HP_EVENT 0x01 1533 1534 static struct hda_verb ad1988_laptop_init_verbs[] = { 1535 /* Front, Surround, CLFE, side DAC; unmute as default */ 1536 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1537 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1538 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1539 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1540 /* Port-A front headphon path */ 1541 {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */ 1542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1543 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1544 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1545 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1546 /* unsolicited event for pin-sense */ 1547 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT }, 1548 /* Port-D line-out path + EAPD */ 1549 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1550 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1551 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1552 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1553 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */ 1554 /* Mono out path */ 1555 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ 1556 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1557 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1558 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1559 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ 1560 /* Port-B mic-in path */ 1561 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1562 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1563 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1564 /* Port-C docking station - try to output */ 1565 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1566 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1567 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1568 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, 1569 /* mute analog mix */ 1570 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1571 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1572 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1573 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1574 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1575 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 1576 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1577 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1578 /* select ADCs - mic */ 1579 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 1580 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, 1581 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 1582 /* ADCs; muted */ 1583 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1584 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1585 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1586 { } 1587 }; 1588 1589 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res) 1590 { 1591 if ((res >> 26) != AD1988_HP_EVENT) 1592 return; 1593 if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31)) 1594 snd_hda_sequence_write(codec, ad1988_laptop_hp_on); 1595 else 1596 snd_hda_sequence_write(codec, ad1988_laptop_hp_off); 1597 } 1598 1599 1600 /* 1601 * Automatic parse of I/O pins from the BIOS configuration 1602 */ 1603 1604 #define NUM_CONTROL_ALLOC 32 1605 #define NUM_VERB_ALLOC 32 1606 1607 enum { 1608 AD_CTL_WIDGET_VOL, 1609 AD_CTL_WIDGET_MUTE, 1610 AD_CTL_BIND_MUTE, 1611 }; 1612 static struct snd_kcontrol_new ad1988_control_templates[] = { 1613 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 1614 HDA_CODEC_MUTE(NULL, 0, 0, 0), 1615 HDA_BIND_MUTE(NULL, 0, 0, 0), 1616 }; 1617 1618 /* add dynamic controls */ 1619 static int add_control(struct ad198x_spec *spec, int type, const char *name, 1620 unsigned long val) 1621 { 1622 struct snd_kcontrol_new *knew; 1623 1624 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 1625 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 1626 1627 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ 1628 if (! knew) 1629 return -ENOMEM; 1630 if (spec->kctl_alloc) { 1631 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); 1632 kfree(spec->kctl_alloc); 1633 } 1634 spec->kctl_alloc = knew; 1635 spec->num_kctl_alloc = num; 1636 } 1637 1638 knew = &spec->kctl_alloc[spec->num_kctl_used]; 1639 *knew = ad1988_control_templates[type]; 1640 knew->name = kstrdup(name, GFP_KERNEL); 1641 if (! knew->name) 1642 return -ENOMEM; 1643 knew->private_value = val; 1644 spec->num_kctl_used++; 1645 return 0; 1646 } 1647 1648 #define AD1988_PIN_CD_NID 0x18 1649 #define AD1988_PIN_BEEP_NID 0x10 1650 1651 static hda_nid_t ad1988_mixer_nids[8] = { 1652 /* A B C D E F G H */ 1653 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28 1654 }; 1655 1656 static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) 1657 { 1658 static hda_nid_t idx_to_dac[8] = { 1659 /* A B C D E F G H */ 1660 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a 1661 }; 1662 static hda_nid_t idx_to_dac_rev2[8] = { 1663 /* A B C D E F G H */ 1664 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 1665 }; 1666 if (codec->revision_id == AD1988A_REV2) 1667 return idx_to_dac_rev2[idx]; 1668 else 1669 return idx_to_dac[idx]; 1670 } 1671 1672 static hda_nid_t ad1988_boost_nids[8] = { 1673 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0 1674 }; 1675 1676 static int ad1988_pin_idx(hda_nid_t nid) 1677 { 1678 static hda_nid_t ad1988_io_pins[8] = { 1679 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25 1680 }; 1681 int i; 1682 for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++) 1683 if (ad1988_io_pins[i] == nid) 1684 return i; 1685 return 0; /* should be -1 */ 1686 } 1687 1688 static int ad1988_pin_to_loopback_idx(hda_nid_t nid) 1689 { 1690 static int loopback_idx[8] = { 1691 2, 0, 1, 3, 4, 5, 1, 4 1692 }; 1693 switch (nid) { 1694 case AD1988_PIN_CD_NID: 1695 return 6; 1696 default: 1697 return loopback_idx[ad1988_pin_idx(nid)]; 1698 } 1699 } 1700 1701 static int ad1988_pin_to_adc_idx(hda_nid_t nid) 1702 { 1703 static int adc_idx[8] = { 1704 0, 1, 2, 8, 4, 3, 6, 7 1705 }; 1706 switch (nid) { 1707 case AD1988_PIN_CD_NID: 1708 return 5; 1709 default: 1710 return adc_idx[ad1988_pin_idx(nid)]; 1711 } 1712 } 1713 1714 /* fill in the dac_nids table from the parsed pin configuration */ 1715 static int ad1988_auto_fill_dac_nids(struct hda_codec *codec, 1716 const struct auto_pin_cfg *cfg) 1717 { 1718 struct ad198x_spec *spec = codec->spec; 1719 int i, idx; 1720 1721 spec->multiout.dac_nids = spec->private_dac_nids; 1722 1723 /* check the pins hardwired to audio widget */ 1724 for (i = 0; i < cfg->line_outs; i++) { 1725 idx = ad1988_pin_idx(cfg->line_out_pins[i]); 1726 spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx); 1727 } 1728 spec->multiout.num_dacs = cfg->line_outs; 1729 return 0; 1730 } 1731 1732 /* add playback controls from the parsed DAC table */ 1733 static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec, 1734 const struct auto_pin_cfg *cfg) 1735 { 1736 char name[32]; 1737 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; 1738 hda_nid_t nid; 1739 int i, err; 1740 1741 for (i = 0; i < cfg->line_outs; i++) { 1742 hda_nid_t dac = spec->multiout.dac_nids[i]; 1743 if (! dac) 1744 continue; 1745 nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])]; 1746 if (i == 2) { 1747 /* Center/LFE */ 1748 err = add_control(spec, AD_CTL_WIDGET_VOL, 1749 "Center Playback Volume", 1750 HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT)); 1751 if (err < 0) 1752 return err; 1753 err = add_control(spec, AD_CTL_WIDGET_VOL, 1754 "LFE Playback Volume", 1755 HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT)); 1756 if (err < 0) 1757 return err; 1758 err = add_control(spec, AD_CTL_BIND_MUTE, 1759 "Center Playback Switch", 1760 HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT)); 1761 if (err < 0) 1762 return err; 1763 err = add_control(spec, AD_CTL_BIND_MUTE, 1764 "LFE Playback Switch", 1765 HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT)); 1766 if (err < 0) 1767 return err; 1768 } else { 1769 sprintf(name, "%s Playback Volume", chname[i]); 1770 err = add_control(spec, AD_CTL_WIDGET_VOL, name, 1771 HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT)); 1772 if (err < 0) 1773 return err; 1774 sprintf(name, "%s Playback Switch", chname[i]); 1775 err = add_control(spec, AD_CTL_BIND_MUTE, name, 1776 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 1777 if (err < 0) 1778 return err; 1779 } 1780 } 1781 return 0; 1782 } 1783 1784 /* add playback controls for speaker and HP outputs */ 1785 static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 1786 const char *pfx) 1787 { 1788 struct ad198x_spec *spec = codec->spec; 1789 hda_nid_t nid; 1790 int idx, err; 1791 char name[32]; 1792 1793 if (! pin) 1794 return 0; 1795 1796 idx = ad1988_pin_idx(pin); 1797 nid = ad1988_idx_to_dac(codec, idx); 1798 if (! spec->multiout.dac_nids[0]) { 1799 /* use this as the primary output */ 1800 spec->multiout.dac_nids[0] = nid; 1801 if (! spec->multiout.num_dacs) 1802 spec->multiout.num_dacs = 1; 1803 } else 1804 /* specify the DAC as the extra output */ 1805 spec->multiout.hp_nid = nid; 1806 /* control HP volume/switch on the output mixer amp */ 1807 sprintf(name, "%s Playback Volume", pfx); 1808 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, 1809 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) 1810 return err; 1811 nid = ad1988_mixer_nids[idx]; 1812 sprintf(name, "%s Playback Switch", pfx); 1813 if ((err = add_control(spec, AD_CTL_BIND_MUTE, name, 1814 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) 1815 return err; 1816 return 0; 1817 } 1818 1819 /* create input playback/capture controls for the given pin */ 1820 static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin, 1821 const char *ctlname, int boost) 1822 { 1823 char name[32]; 1824 int err, idx; 1825 1826 sprintf(name, "%s Playback Volume", ctlname); 1827 idx = ad1988_pin_to_loopback_idx(pin); 1828 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, 1829 HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0) 1830 return err; 1831 sprintf(name, "%s Playback Switch", ctlname); 1832 if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name, 1833 HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0) 1834 return err; 1835 if (boost) { 1836 hda_nid_t bnid; 1837 idx = ad1988_pin_idx(pin); 1838 bnid = ad1988_boost_nids[idx]; 1839 if (bnid) { 1840 sprintf(name, "%s Boost", ctlname); 1841 return add_control(spec, AD_CTL_WIDGET_VOL, name, 1842 HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT)); 1843 1844 } 1845 } 1846 return 0; 1847 } 1848 1849 /* create playback/capture controls for input pins */ 1850 static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec, 1851 const struct auto_pin_cfg *cfg) 1852 { 1853 struct hda_input_mux *imux = &spec->private_imux; 1854 int i, err; 1855 1856 for (i = 0; i < AUTO_PIN_LAST; i++) { 1857 err = new_analog_input(spec, cfg->input_pins[i], 1858 auto_pin_cfg_labels[i], 1859 i <= AUTO_PIN_FRONT_MIC); 1860 if (err < 0) 1861 return err; 1862 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 1863 imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]); 1864 imux->num_items++; 1865 } 1866 imux->items[imux->num_items].label = "Mix"; 1867 imux->items[imux->num_items].index = 9; 1868 imux->num_items++; 1869 1870 if ((err = add_control(spec, AD_CTL_WIDGET_VOL, 1871 "Analog Mix Playback Volume", 1872 HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0) 1873 return err; 1874 if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, 1875 "Analog Mix Playback Switch", 1876 HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0) 1877 return err; 1878 1879 return 0; 1880 } 1881 1882 static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec, 1883 hda_nid_t nid, int pin_type, 1884 int dac_idx) 1885 { 1886 /* set as output */ 1887 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); 1888 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 1889 switch (nid) { 1890 case 0x11: /* port-A - DAC 04 */ 1891 snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01); 1892 break; 1893 case 0x14: /* port-B - DAC 06 */ 1894 snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02); 1895 break; 1896 case 0x15: /* port-C - DAC 05 */ 1897 snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00); 1898 break; 1899 case 0x17: /* port-E - DAC 0a */ 1900 snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01); 1901 break; 1902 case 0x13: /* mono - DAC 04 */ 1903 snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01); 1904 break; 1905 } 1906 } 1907 1908 static void ad1988_auto_init_multi_out(struct hda_codec *codec) 1909 { 1910 struct ad198x_spec *spec = codec->spec; 1911 int i; 1912 1913 for (i = 0; i < spec->autocfg.line_outs; i++) { 1914 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 1915 ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 1916 } 1917 } 1918 1919 static void ad1988_auto_init_extra_out(struct hda_codec *codec) 1920 { 1921 struct ad198x_spec *spec = codec->spec; 1922 hda_nid_t pin; 1923 1924 pin = spec->autocfg.speaker_pin; 1925 if (pin) /* connect to front */ 1926 ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 1927 pin = spec->autocfg.hp_pin; 1928 if (pin) /* connect to front */ 1929 ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 1930 } 1931 1932 static void ad1988_auto_init_analog_input(struct hda_codec *codec) 1933 { 1934 struct ad198x_spec *spec = codec->spec; 1935 int i, idx; 1936 1937 for (i = 0; i < AUTO_PIN_LAST; i++) { 1938 hda_nid_t nid = spec->autocfg.input_pins[i]; 1939 if (! nid) 1940 continue; 1941 switch (nid) { 1942 case 0x15: /* port-C */ 1943 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0); 1944 break; 1945 case 0x17: /* port-E */ 1946 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0); 1947 break; 1948 } 1949 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1950 i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); 1951 if (nid != AD1988_PIN_CD_NID) 1952 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1953 AMP_OUT_MUTE); 1954 idx = ad1988_pin_idx(nid); 1955 if (ad1988_boost_nids[idx]) 1956 snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0, 1957 AC_VERB_SET_AMP_GAIN_MUTE, 1958 AMP_OUT_ZERO); 1959 } 1960 } 1961 1962 /* parse the BIOS configuration and set up the alc_spec */ 1963 /* return 1 if successful, 0 if the proper config is not found, or a negative error code */ 1964 static int ad1988_parse_auto_config(struct hda_codec *codec) 1965 { 1966 struct ad198x_spec *spec = codec->spec; 1967 int err; 1968 1969 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) 1970 return err; 1971 if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) 1972 return err; 1973 if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && 1974 ! spec->autocfg.hp_pin) 1975 return 0; /* can't find valid BIOS pin config */ 1976 if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || 1977 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin, 1978 "Speaker")) < 0 || 1979 (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin, 1980 "Headphone")) < 0 || 1981 (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) 1982 return err; 1983 1984 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 1985 1986 if (spec->autocfg.dig_out_pin) 1987 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 1988 if (spec->autocfg.dig_in_pin) 1989 spec->dig_in_nid = AD1988_SPDIF_IN; 1990 1991 if (spec->kctl_alloc) 1992 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1993 1994 spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs; 1995 1996 spec->input_mux = &spec->private_imux; 1997 1998 return 1; 1999 } 2000 2001 /* init callback for auto-configuration model -- overriding the default init */ 2002 static int ad1988_auto_init(struct hda_codec *codec) 2003 { 2004 ad198x_init(codec); 2005 ad1988_auto_init_multi_out(codec); 2006 ad1988_auto_init_extra_out(codec); 2007 ad1988_auto_init_analog_input(codec); 2008 return 0; 2009 } 2010 2011 2012 /* 2013 */ 2014 2015 static struct hda_board_config ad1988_cfg_tbl[] = { 2016 { .modelname = "6stack", .config = AD1988_6STACK }, 2017 { .modelname = "6stack-dig", .config = AD1988_6STACK_DIG }, 2018 { .modelname = "3stack", .config = AD1988_3STACK }, 2019 { .modelname = "3stack-dig", .config = AD1988_3STACK_DIG }, 2020 { .modelname = "laptop", .config = AD1988_LAPTOP }, 2021 { .modelname = "laptop-dig", .config = AD1988_LAPTOP_DIG }, 2022 { .modelname = "auto", .config = AD1988_AUTO }, 2023 {} 2024 }; 2025 2026 static int patch_ad1988(struct hda_codec *codec) 2027 { 2028 struct ad198x_spec *spec; 2029 int board_config; 2030 2031 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2032 if (spec == NULL) 2033 return -ENOMEM; 2034 2035 init_MUTEX(&spec->amp_mutex); 2036 codec->spec = spec; 2037 2038 if (codec->revision_id == AD1988A_REV2) 2039 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); 2040 2041 board_config = snd_hda_check_board_config(codec, ad1988_cfg_tbl); 2042 if (board_config < 0 || board_config >= AD1988_MODEL_LAST) { 2043 printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n"); 2044 board_config = AD1988_AUTO; 2045 } 2046 2047 if (board_config == AD1988_AUTO) { 2048 /* automatic parse from the BIOS config */ 2049 int err = ad1988_parse_auto_config(codec); 2050 if (err < 0) { 2051 ad198x_free(codec); 2052 return err; 2053 } else if (! err) { 2054 printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS. Using 6-stack mode...\n"); 2055 board_config = AD1988_6STACK; 2056 } 2057 } 2058 2059 switch (board_config) { 2060 case AD1988_6STACK: 2061 case AD1988_6STACK_DIG: 2062 spec->multiout.max_channels = 8; 2063 spec->multiout.num_dacs = 4; 2064 if (codec->revision_id == AD1988A_REV2) 2065 spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2; 2066 else 2067 spec->multiout.dac_nids = ad1988_6stack_dac_nids; 2068 spec->input_mux = &ad1988_6stack_capture_source; 2069 spec->num_mixers = 2; 2070 if (codec->revision_id == AD1988A_REV2) 2071 spec->mixers[0] = ad1988_6stack_mixers1_rev2; 2072 else 2073 spec->mixers[0] = ad1988_6stack_mixers1; 2074 spec->mixers[1] = ad1988_6stack_mixers2; 2075 spec->num_init_verbs = 1; 2076 spec->init_verbs[0] = ad1988_6stack_init_verbs; 2077 if (board_config == AD1988_6STACK_DIG) { 2078 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 2079 spec->dig_in_nid = AD1988_SPDIF_IN; 2080 } 2081 break; 2082 case AD1988_3STACK: 2083 case AD1988_3STACK_DIG: 2084 spec->multiout.max_channels = 6; 2085 spec->multiout.num_dacs = 3; 2086 if (codec->revision_id == AD1988A_REV2) 2087 spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2; 2088 else 2089 spec->multiout.dac_nids = ad1988_3stack_dac_nids; 2090 spec->input_mux = &ad1988_6stack_capture_source; 2091 spec->channel_mode = ad1988_3stack_modes; 2092 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes); 2093 spec->num_mixers = 2; 2094 if (codec->revision_id == AD1988A_REV2) 2095 spec->mixers[0] = ad1988_3stack_mixers1_rev2; 2096 else 2097 spec->mixers[0] = ad1988_3stack_mixers1; 2098 spec->mixers[1] = ad1988_3stack_mixers2; 2099 spec->num_init_verbs = 1; 2100 spec->init_verbs[0] = ad1988_3stack_init_verbs; 2101 if (board_config == AD1988_3STACK_DIG) 2102 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 2103 break; 2104 case AD1988_LAPTOP: 2105 case AD1988_LAPTOP_DIG: 2106 spec->multiout.max_channels = 2; 2107 spec->multiout.num_dacs = 1; 2108 spec->multiout.dac_nids = ad1988_3stack_dac_nids; 2109 spec->input_mux = &ad1988_laptop_capture_source; 2110 spec->num_mixers = 1; 2111 spec->mixers[0] = ad1988_laptop_mixers; 2112 spec->num_init_verbs = 1; 2113 spec->init_verbs[0] = ad1988_laptop_init_verbs; 2114 if (board_config == AD1988_LAPTOP_DIG) 2115 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 2116 break; 2117 } 2118 2119 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); 2120 spec->adc_nids = ad1988_adc_nids; 2121 spec->capsrc_nids = ad1988_capsrc_nids; 2122 spec->mixers[spec->num_mixers++] = ad1988_capture_mixers; 2123 spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs; 2124 if (spec->multiout.dig_out_nid) { 2125 spec->mixers[spec->num_mixers++] = ad1988_spdif_out_mixers; 2126 spec->init_verbs[spec->num_init_verbs++] = ad1988_spdif_init_verbs; 2127 } 2128 if (spec->dig_in_nid) 2129 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers; 2130 2131 codec->patch_ops = ad198x_patch_ops; 2132 switch (board_config) { 2133 case AD1988_AUTO: 2134 codec->patch_ops.init = ad1988_auto_init; 2135 break; 2136 case AD1988_LAPTOP: 2137 case AD1988_LAPTOP_DIG: 2138 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event; 2139 break; 2140 } 2141 2142 return 0; 2143 } 2144 2145 2146 /* 2147 * patch entries 2148 */ 2149 struct hda_codec_preset snd_hda_preset_analog[] = { 2150 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, 2151 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, 2152 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, 2153 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, 2154 {} /* terminator */ 2155 }; 2156