1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 4 * Universal interface for Audio Codec '97 5 * 6 * For more details look to AC '97 component specification revision 2.2 7 * by Intel Corporation (http://developer.intel.com) and to datasheets 8 * for specific codecs. 9 */ 10 11 #include "ac97_local.h" 12 #include "ac97_patch.h" 13 14 /* 15 * Forward declarations 16 */ 17 18 static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, 19 const char *name); 20 static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, 21 const unsigned int *tlv, 22 const char * const *followers); 23 24 /* 25 * Chip specific initialization 26 */ 27 28 static int patch_build_controls(struct snd_ac97 * ac97, const struct snd_kcontrol_new *controls, int count) 29 { 30 int idx, err; 31 32 for (idx = 0; idx < count; idx++) { 33 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&controls[idx], ac97)); 34 if (err < 0) 35 return err; 36 } 37 return 0; 38 } 39 40 /* replace with a new TLV */ 41 static void reset_tlv(struct snd_ac97 *ac97, const char *name, 42 const unsigned int *tlv) 43 { 44 struct snd_kcontrol *kctl; 45 46 kctl = snd_ctl_find_id_mixer(ac97->bus->card, name); 47 if (kctl && kctl->tlv.p) 48 kctl->tlv.p = tlv; 49 } 50 51 /* set to the page, update bits and restore the page */ 52 static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value, unsigned short page) 53 { 54 unsigned short page_save; 55 int ret; 56 57 mutex_lock(&ac97->page_mutex); 58 page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; 59 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); 60 ret = snd_ac97_update_bits(ac97, reg, mask, value); 61 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); 62 mutex_unlock(&ac97->page_mutex); /* unlock paging */ 63 return ret; 64 } 65 66 /* 67 * shared line-in/mic controls 68 */ 69 static int ac97_surround_jack_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 70 { 71 static const char * const texts[] = { "Shared", "Independent" }; 72 73 return snd_ctl_enum_info(uinfo, 1, 2, texts); 74 } 75 76 static int ac97_surround_jack_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 77 { 78 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 79 80 ucontrol->value.enumerated.item[0] = ac97->indep_surround; 81 return 0; 82 } 83 84 static int ac97_surround_jack_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 85 { 86 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 87 unsigned char indep = !!ucontrol->value.enumerated.item[0]; 88 89 if (indep != ac97->indep_surround) { 90 ac97->indep_surround = indep; 91 if (ac97->build_ops->update_jacks) 92 ac97->build_ops->update_jacks(ac97); 93 return 1; 94 } 95 return 0; 96 } 97 98 static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 99 { 100 static const char * const texts[] = { "2ch", "4ch", "6ch", "8ch" }; 101 102 return snd_ctl_enum_info(uinfo, 1, kcontrol->private_value, texts); 103 } 104 105 static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 106 { 107 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 108 109 ucontrol->value.enumerated.item[0] = ac97->channel_mode; 110 return 0; 111 } 112 113 static int ac97_channel_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 114 { 115 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 116 unsigned char mode = ucontrol->value.enumerated.item[0]; 117 118 if (mode >= kcontrol->private_value) 119 return -EINVAL; 120 121 if (mode != ac97->channel_mode) { 122 ac97->channel_mode = mode; 123 if (ac97->build_ops->update_jacks) 124 ac97->build_ops->update_jacks(ac97); 125 return 1; 126 } 127 return 0; 128 } 129 130 #define AC97_SURROUND_JACK_MODE_CTL \ 131 { \ 132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 133 .name = "Surround Jack Mode", \ 134 .info = ac97_surround_jack_mode_info, \ 135 .get = ac97_surround_jack_mode_get, \ 136 .put = ac97_surround_jack_mode_put, \ 137 } 138 /* 6ch */ 139 #define AC97_CHANNEL_MODE_CTL \ 140 { \ 141 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 142 .name = "Channel Mode", \ 143 .info = ac97_channel_mode_info, \ 144 .get = ac97_channel_mode_get, \ 145 .put = ac97_channel_mode_put, \ 146 .private_value = 3, \ 147 } 148 /* 4ch */ 149 #define AC97_CHANNEL_MODE_4CH_CTL \ 150 { \ 151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 152 .name = "Channel Mode", \ 153 .info = ac97_channel_mode_info, \ 154 .get = ac97_channel_mode_get, \ 155 .put = ac97_channel_mode_put, \ 156 .private_value = 2, \ 157 } 158 /* 8ch */ 159 #define AC97_CHANNEL_MODE_8CH_CTL \ 160 { \ 161 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 162 .name = "Channel Mode", \ 163 .info = ac97_channel_mode_info, \ 164 .get = ac97_channel_mode_get, \ 165 .put = ac97_channel_mode_put, \ 166 .private_value = 4, \ 167 } 168 169 static inline int is_surround_on(struct snd_ac97 *ac97) 170 { 171 return ac97->channel_mode >= 1; 172 } 173 174 static inline int is_clfe_on(struct snd_ac97 *ac97) 175 { 176 return ac97->channel_mode >= 2; 177 } 178 179 /* system has shared jacks with surround out enabled */ 180 static inline int is_shared_surrout(struct snd_ac97 *ac97) 181 { 182 return !ac97->indep_surround && is_surround_on(ac97); 183 } 184 185 /* system has shared jacks with center/lfe out enabled */ 186 static inline int is_shared_clfeout(struct snd_ac97 *ac97) 187 { 188 return !ac97->indep_surround && is_clfe_on(ac97); 189 } 190 191 /* system has shared jacks with line in enabled */ 192 static inline int is_shared_linein(struct snd_ac97 *ac97) 193 { 194 return !ac97->indep_surround && !is_surround_on(ac97); 195 } 196 197 /* system has shared jacks with mic in enabled */ 198 static inline int is_shared_micin(struct snd_ac97 *ac97) 199 { 200 return !ac97->indep_surround && !is_clfe_on(ac97); 201 } 202 203 static inline int alc850_is_aux_back_surround(struct snd_ac97 *ac97) 204 { 205 return is_surround_on(ac97); 206 } 207 208 /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */ 209 /* Modified for YMF743 by Keita Maehara <maehara@debian.org> */ 210 211 /* It is possible to indicate to the Yamaha YMF7x3 the type of 212 speakers being used. */ 213 214 static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol, 215 struct snd_ctl_elem_info *uinfo) 216 { 217 static const char * const texts[3] = { 218 "Standard", "Small", "Smaller" 219 }; 220 221 return snd_ctl_enum_info(uinfo, 1, 3, texts); 222 } 223 224 static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol, 225 struct snd_ctl_elem_value *ucontrol) 226 { 227 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 228 unsigned short val; 229 230 val = ac97->regs[AC97_YMF7X3_3D_MODE_SEL]; 231 val = (val >> 10) & 3; 232 if (val > 0) /* 0 = invalid */ 233 val--; 234 ucontrol->value.enumerated.item[0] = val; 235 return 0; 236 } 237 238 static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol *kcontrol, 239 struct snd_ctl_elem_value *ucontrol) 240 { 241 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 242 unsigned short val; 243 244 if (ucontrol->value.enumerated.item[0] > 2) 245 return -EINVAL; 246 val = (ucontrol->value.enumerated.item[0] + 1) << 10; 247 return snd_ac97_update(ac97, AC97_YMF7X3_3D_MODE_SEL, val); 248 } 249 250 static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker = 251 { 252 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 253 .name = "3D Control - Speaker", 254 .info = snd_ac97_ymf7x3_info_speaker, 255 .get = snd_ac97_ymf7x3_get_speaker, 256 .put = snd_ac97_ymf7x3_put_speaker, 257 }; 258 259 /* It is possible to indicate to the Yamaha YMF7x3 the source to 260 direct to the S/PDIF output. */ 261 static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol, 262 struct snd_ctl_elem_info *uinfo) 263 { 264 static const char * const texts[2] = { "AC-Link", "A/D Converter" }; 265 266 return snd_ctl_enum_info(uinfo, 1, 2, texts); 267 } 268 269 static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol, 270 struct snd_ctl_elem_value *ucontrol) 271 { 272 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 273 unsigned short val; 274 275 val = ac97->regs[AC97_YMF7X3_DIT_CTRL]; 276 ucontrol->value.enumerated.item[0] = (val >> 1) & 1; 277 return 0; 278 } 279 280 static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol *kcontrol, 281 struct snd_ctl_elem_value *ucontrol) 282 { 283 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 284 unsigned short val; 285 286 if (ucontrol->value.enumerated.item[0] > 1) 287 return -EINVAL; 288 val = ucontrol->value.enumerated.item[0] << 1; 289 return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0002, val); 290 } 291 292 static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97) 293 { 294 struct snd_kcontrol *kctl; 295 int err; 296 297 kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97); 298 err = snd_ctl_add(ac97->bus->card, kctl); 299 if (err < 0) 300 return err; 301 strcpy(kctl->id.name, "3D Control - Wide"); 302 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0); 303 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); 304 err = snd_ctl_add(ac97->bus->card, 305 snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker, 306 ac97)); 307 if (err < 0) 308 return err; 309 snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00); 310 return 0; 311 } 312 313 static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif[3] = 314 { 315 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), 316 AC97_YMF7X3_DIT_CTRL, 0, 1, 0), 317 { 318 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 319 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Source", 320 .info = snd_ac97_ymf7x3_spdif_source_info, 321 .get = snd_ac97_ymf7x3_spdif_source_get, 322 .put = snd_ac97_ymf7x3_spdif_source_put, 323 }, 324 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute", 325 AC97_YMF7X3_DIT_CTRL, 2, 1, 1) 326 }; 327 328 static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97) 329 { 330 int err; 331 332 err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3); 333 if (err < 0) 334 return err; 335 err = patch_build_controls(ac97, 336 snd_ac97_yamaha_ymf743_controls_spdif, 3); 337 if (err < 0) 338 return err; 339 /* set default PCM S/PDIF params */ 340 /* PCM audio,no copyright,no preemphasis,PCM coder,original */ 341 snd_ac97_write_cache(ac97, AC97_YMF7X3_DIT_CTRL, 0xa201); 342 return 0; 343 } 344 345 static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops = { 346 .build_spdif = patch_yamaha_ymf743_build_spdif, 347 .build_3d = patch_yamaha_ymf7x3_3d, 348 }; 349 350 static int patch_yamaha_ymf743(struct snd_ac97 *ac97) 351 { 352 ac97->build_ops = &patch_yamaha_ymf743_ops; 353 ac97->caps |= AC97_BC_BASS_TREBLE; 354 ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */ 355 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ 356 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ 357 return 0; 358 } 359 360 /* The AC'97 spec states that the S/PDIF signal is to be output at pin 48. 361 The YMF753 will output the S/PDIF signal to pin 43, 47 (EAPD), or 48. 362 By default, no output pin is selected, and the S/PDIF signal is not output. 363 There is also a bit to mute S/PDIF output in a vendor-specific register. */ 364 static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 365 { 366 static const char * const texts[3] = { "Disabled", "Pin 43", "Pin 48" }; 367 368 return snd_ctl_enum_info(uinfo, 1, 3, texts); 369 } 370 371 static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 372 { 373 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 374 unsigned short val; 375 376 val = ac97->regs[AC97_YMF7X3_DIT_CTRL]; 377 ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0; 378 return 0; 379 } 380 381 static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 382 { 383 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 384 unsigned short val; 385 386 if (ucontrol->value.enumerated.item[0] > 2) 387 return -EINVAL; 388 val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 : 389 (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0; 390 return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0028, val); 391 /* The following can be used to direct S/PDIF output to pin 47 (EAPD). 392 snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */ 393 } 394 395 static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = { 396 { 397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 398 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 399 .info = snd_ac97_ymf7x3_spdif_source_info, 400 .get = snd_ac97_ymf7x3_spdif_source_get, 401 .put = snd_ac97_ymf7x3_spdif_source_put, 402 }, 403 { 404 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 405 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Output Pin", 406 .info = snd_ac97_ymf753_spdif_output_pin_info, 407 .get = snd_ac97_ymf753_spdif_output_pin_get, 408 .put = snd_ac97_ymf753_spdif_output_pin_put, 409 }, 410 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute", 411 AC97_YMF7X3_DIT_CTRL, 2, 1, 1) 412 }; 413 414 static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97) 415 { 416 int err; 417 418 err = patch_build_controls(ac97, snd_ac97_ymf753_controls_spdif, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif)); 419 if (err < 0) 420 return err; 421 return 0; 422 } 423 424 static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { 425 .build_3d = patch_yamaha_ymf7x3_3d, 426 .build_post_spdif = patch_yamaha_ymf753_post_spdif 427 }; 428 429 static int patch_yamaha_ymf753(struct snd_ac97 * ac97) 430 { 431 /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com. 432 This chip has nonstandard and extended behaviour with regard to its S/PDIF output. 433 The AC'97 spec states that the S/PDIF signal is to be output at pin 48. 434 The YMF753 will ouput the S/PDIF signal to pin 43, 47 (EAPD), or 48. 435 By default, no output pin is selected, and the S/PDIF signal is not output. 436 There is also a bit to mute S/PDIF output in a vendor-specific register. 437 */ 438 ac97->build_ops = &patch_yamaha_ymf753_ops; 439 ac97->caps |= AC97_BC_BASS_TREBLE; 440 ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */ 441 return 0; 442 } 443 444 /* 445 * May 2, 2003 Liam Girdwood <lrg@slimlogic.co.uk> 446 * removed broken wolfson00 patch. 447 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. 448 */ 449 450 static const struct snd_kcontrol_new wm97xx_snd_ac97_controls[] = { 451 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1), 452 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1), 453 }; 454 455 static int patch_wolfson_wm9703_specific(struct snd_ac97 * ac97) 456 { 457 /* This is known to work for the ViewSonic ViewPad 1000 458 * Randolph Bentson <bentson@holmsjoen.com> 459 * WM9703/9707/9708/9717 460 */ 461 int err, i; 462 463 for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) { 464 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97)); 465 if (err < 0) 466 return err; 467 } 468 snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); 469 return 0; 470 } 471 472 static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { 473 .build_specific = patch_wolfson_wm9703_specific, 474 }; 475 476 static int patch_wolfson03(struct snd_ac97 * ac97) 477 { 478 ac97->build_ops = &patch_wolfson_wm9703_ops; 479 return 0; 480 } 481 482 static const struct snd_kcontrol_new wm9704_snd_ac97_controls[] = { 483 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1), 484 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1), 485 AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL, 8, 0, 31, 1), 486 AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL, 15, 1, 1), 487 AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL, 8, 0, 31, 1), 488 AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1), 489 }; 490 491 static int patch_wolfson_wm9704_specific(struct snd_ac97 * ac97) 492 { 493 int err, i; 494 for (i = 0; i < ARRAY_SIZE(wm9704_snd_ac97_controls); i++) { 495 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9704_snd_ac97_controls[i], ac97)); 496 if (err < 0) 497 return err; 498 } 499 /* patch for DVD noise */ 500 snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200); 501 return 0; 502 } 503 504 static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { 505 .build_specific = patch_wolfson_wm9704_specific, 506 }; 507 508 static int patch_wolfson04(struct snd_ac97 * ac97) 509 { 510 /* WM9704M/9704Q */ 511 ac97->build_ops = &patch_wolfson_wm9704_ops; 512 return 0; 513 } 514 515 static int patch_wolfson05(struct snd_ac97 * ac97) 516 { 517 /* WM9705, WM9710 */ 518 ac97->build_ops = &patch_wolfson_wm9703_ops; 519 #ifdef CONFIG_TOUCHSCREEN_WM9705 520 /* WM9705 touchscreen uses AUX and VIDEO for touch */ 521 ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX; 522 #endif 523 return 0; 524 } 525 526 static const char* wm9711_alc_select[] = {"None", "Left", "Right", "Stereo"}; 527 static const char* wm9711_alc_mix[] = {"Stereo", "Right", "Left", "None"}; 528 static const char* wm9711_out3_src[] = {"Left", "VREF", "Left + Right", "Mono"}; 529 static const char* wm9711_out3_lrsrc[] = {"Master Mix", "Headphone Mix"}; 530 static const char* wm9711_rec_adc[] = {"Stereo", "Left", "Right", "Mute"}; 531 static const char* wm9711_base[] = {"Linear Control", "Adaptive Boost"}; 532 static const char* wm9711_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; 533 static const char* wm9711_mic[] = {"Mic 1", "Differential", "Mic 2", "Stereo"}; 534 static const char* wm9711_rec_sel[] = 535 {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"}; 536 static const char* wm9711_ng_type[] = {"Constant Gain", "Mute"}; 537 538 static const struct ac97_enum wm9711_enum[] = { 539 AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9711_alc_select), 540 AC97_ENUM_SINGLE(AC97_VIDEO, 10, 4, wm9711_alc_mix), 541 AC97_ENUM_SINGLE(AC97_AUX, 9, 4, wm9711_out3_src), 542 AC97_ENUM_SINGLE(AC97_AUX, 8, 2, wm9711_out3_lrsrc), 543 AC97_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9711_rec_adc), 544 AC97_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9711_base), 545 AC97_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9711_rec_gain), 546 AC97_ENUM_SINGLE(AC97_MIC, 5, 4, wm9711_mic), 547 AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, wm9711_rec_sel), 548 AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9711_ng_type), 549 }; 550 551 static const struct snd_kcontrol_new wm9711_snd_ac97_controls[] = { 552 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), 553 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), 554 AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0), 555 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), 556 AC97_ENUM("ALC Function", wm9711_enum[0]), 557 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 1), 558 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1), 559 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), 560 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), 561 AC97_ENUM("ALC NG Type", wm9711_enum[9]), 562 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1), 563 564 AC97_SINGLE("Side Tone Switch", AC97_VIDEO, 15, 1, 1), 565 AC97_SINGLE("Side Tone Volume", AC97_VIDEO, 12, 7, 1), 566 AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]), 567 AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1), 568 569 AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), 570 AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 0), 571 AC97_ENUM("Out3 Mux", wm9711_enum[2]), 572 AC97_ENUM("Out3 LR Mux", wm9711_enum[3]), 573 AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), 574 575 AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP, 15, 1, 1), 576 AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP, 12, 7, 1), 577 AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP, 11, 1, 1), 578 AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP, 8, 7, 1), 579 AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP, 7, 1, 1), 580 AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP, 4, 7, 1), 581 582 AC97_SINGLE("Aux to Headphone Switch", AC97_CD, 15, 1, 1), 583 AC97_SINGLE("Aux to Headphone Volume", AC97_CD, 12, 7, 1), 584 AC97_SINGLE("Aux to Side Tone Switch", AC97_CD, 11, 1, 1), 585 AC97_SINGLE("Aux to Side Tone Volume", AC97_CD, 8, 7, 1), 586 AC97_SINGLE("Aux to Phone Switch", AC97_CD, 7, 1, 1), 587 AC97_SINGLE("Aux to Phone Volume", AC97_CD, 4, 7, 1), 588 589 AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE, 15, 1, 1), 590 AC97_SINGLE("Phone to Master Switch", AC97_PHONE, 14, 1, 1), 591 592 AC97_SINGLE("Line to Headphone Switch", AC97_LINE, 15, 1, 1), 593 AC97_SINGLE("Line to Master Switch", AC97_LINE, 14, 1, 1), 594 AC97_SINGLE("Line to Phone Switch", AC97_LINE, 13, 1, 1), 595 596 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM, 15, 1, 1), 597 AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM, 14, 1, 1), 598 AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM, 13, 1, 1), 599 600 AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0), 601 AC97_ENUM("Capture to Phone Mux", wm9711_enum[4]), 602 AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1), 603 AC97_ENUM("Capture Select", wm9711_enum[8]), 604 605 AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), 606 AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), 607 608 AC97_ENUM("Bass Control", wm9711_enum[5]), 609 AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1), 610 AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1), 611 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), 612 613 AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1), 614 AC97_ENUM("Capture Volume Steps", wm9711_enum[6]), 615 AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), 616 AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), 617 618 AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1), 619 AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1), 620 AC97_ENUM("Mic Select Source", wm9711_enum[7]), 621 AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), 622 AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), 623 AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), 624 625 AC97_SINGLE("Master Left Inv Switch", AC97_MASTER, 6, 1, 0), 626 AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0), 627 AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0), 628 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0), 629 }; 630 631 static int patch_wolfson_wm9711_specific(struct snd_ac97 * ac97) 632 { 633 int err, i; 634 635 for (i = 0; i < ARRAY_SIZE(wm9711_snd_ac97_controls); i++) { 636 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9711_snd_ac97_controls[i], ac97)); 637 if (err < 0) 638 return err; 639 } 640 snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x0808); 641 snd_ac97_write_cache(ac97, AC97_PCI_SVID, 0x0808); 642 snd_ac97_write_cache(ac97, AC97_VIDEO, 0x0808); 643 snd_ac97_write_cache(ac97, AC97_AUX, 0x0808); 644 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); 645 snd_ac97_write_cache(ac97, AC97_CD, 0x0000); 646 return 0; 647 } 648 649 static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { 650 .build_specific = patch_wolfson_wm9711_specific, 651 }; 652 653 static int patch_wolfson11(struct snd_ac97 * ac97) 654 { 655 /* WM9711, WM9712 */ 656 ac97->build_ops = &patch_wolfson_wm9711_ops; 657 658 ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_MIC | 659 AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD; 660 661 return 0; 662 } 663 664 static const char* wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"}; 665 static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; 666 static const char* wm9713_rec_src[] = 667 {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix", 668 "Mono Mix", "Zh"}; 669 static const char* wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; 670 static const char* wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"}; 671 static const char* wm9713_mono_pga[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"}; 672 static const char* wm9713_spk_pga[] = 673 {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"}; 674 static const char* wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone Mix", "NC"}; 675 static const char* wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "NC"}; 676 static const char* wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "NC"}; 677 static const char* wm9713_dac_inv[] = 678 {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R", 679 "Headphone Mix Mono", "NC", "Vmid"}; 680 static const char* wm9713_base[] = {"Linear Control", "Adaptive Boost"}; 681 static const char* wm9713_ng_type[] = {"Constant Gain", "Mute"}; 682 683 static const struct ac97_enum wm9713_enum[] = { 684 AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), 685 AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), 686 AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), 687 AC97_ENUM_DOUBLE(AC97_VIDEO, 3, 0, 8, wm9713_rec_src), 688 AC97_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain), 689 AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select), 690 AC97_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga), 691 AC97_ENUM_DOUBLE(AC97_REC_GAIN, 11, 8, 8, wm9713_spk_pga), 692 AC97_ENUM_DOUBLE(AC97_REC_GAIN, 6, 4, 4, wm9713_hp_pga), 693 AC97_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga), 694 AC97_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga), 695 AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC, 13, 10, 8, wm9713_dac_inv), 696 AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_base), 697 AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type), 698 }; 699 700 static const struct snd_kcontrol_new wm13_snd_ac97_controls[] = { 701 AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), 702 AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP, 15, 1, 1), 703 AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP, 14, 1, 1), 704 AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP, 13, 1, 1), 705 706 AC97_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1), 707 AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE, 15, 1, 1), 708 AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE, 14, 1, 1), 709 AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE, 13, 1, 1), 710 711 AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), 712 AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), 713 AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE, 7, 1, 1), 714 AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE, 6, 1, 1), 715 AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0), 716 AC97_ENUM("Mic to Headphone Mux", wm9713_enum[0]), 717 AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1), 718 719 AC97_SINGLE("Capture Switch", AC97_CD, 15, 1, 1), 720 AC97_ENUM("Capture Volume Steps", wm9713_enum[4]), 721 AC97_DOUBLE("Capture Volume", AC97_CD, 8, 0, 15, 0), 722 AC97_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0), 723 724 AC97_ENUM("Capture to Headphone Mux", wm9713_enum[1]), 725 AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1), 726 AC97_ENUM("Capture to Mono Mux", wm9713_enum[2]), 727 AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0), 728 AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), 729 AC97_ENUM("Capture Select", wm9713_enum[3]), 730 731 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), 732 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), 733 AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0), 734 AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), 735 AC97_ENUM("ALC Function", wm9713_enum[5]), 736 AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0), 737 AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0), 738 AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), 739 AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), 740 AC97_ENUM("ALC NG Type", wm9713_enum[13]), 741 AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0), 742 743 AC97_DOUBLE("Master ZC Switch", AC97_MASTER, 14, 6, 1, 0), 744 AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0), 745 AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO, 14, 6, 1, 0), 746 AC97_SINGLE("Master Right Switch", AC97_MASTER, 7, 1, 1), 747 AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE, 7, 1, 1), 748 AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO, 7, 1, 1), 749 750 AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE, 15, 1, 1), 751 AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE, 14, 1, 1), 752 AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE, 8, 31, 1), 753 AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1), 754 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0), 755 AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1), 756 757 AC97_SINGLE("Beep to Headphone Switch", AC97_AUX, 15, 1, 1), 758 AC97_SINGLE("Beep to Headphone Volume", AC97_AUX, 12, 7, 1), 759 AC97_SINGLE("Beep to Master Switch", AC97_AUX, 11, 1, 1), 760 AC97_SINGLE("Beep to Master Volume", AC97_AUX, 8, 7, 1), 761 AC97_SINGLE("Beep to Mono Switch", AC97_AUX, 7, 1, 1), 762 AC97_SINGLE("Beep to Mono Volume", AC97_AUX, 4, 7, 1), 763 764 AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1), 765 AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1), 766 AC97_SINGLE("Voice to Master Switch", AC97_PCM, 11, 1, 1), 767 AC97_SINGLE("Voice to Master Volume", AC97_PCM, 8, 7, 1), 768 AC97_SINGLE("Voice to Mono Switch", AC97_PCM, 7, 1, 1), 769 AC97_SINGLE("Voice to Mono Volume", AC97_PCM, 4, 7, 1), 770 771 AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL, 15, 1, 1), 772 AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL, 12, 7, 1), 773 AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL, 11, 1, 1), 774 AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL, 8, 7, 1), 775 AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL, 7, 1, 1), 776 AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL, 4, 7, 1), 777 778 AC97_ENUM("Mono Input Mux", wm9713_enum[6]), 779 AC97_ENUM("Master Input Mux", wm9713_enum[7]), 780 AC97_ENUM("Headphone Input Mux", wm9713_enum[8]), 781 AC97_ENUM("Out 3 Input Mux", wm9713_enum[9]), 782 AC97_ENUM("Out 4 Input Mux", wm9713_enum[10]), 783 784 AC97_ENUM("Bass Control", wm9713_enum[12]), 785 AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1), 786 AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1), 787 AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0), 788 AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1), 789 AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1), 790 }; 791 792 static const struct snd_kcontrol_new wm13_snd_ac97_controls_3d[] = { 793 AC97_ENUM("Inv Input Mux", wm9713_enum[11]), 794 AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0), 795 AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0), 796 AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), 797 }; 798 799 static int patch_wolfson_wm9713_3d (struct snd_ac97 * ac97) 800 { 801 int err, i; 802 803 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_3d); i++) { 804 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_3d[i], ac97)); 805 if (err < 0) 806 return err; 807 } 808 return 0; 809 } 810 811 static int patch_wolfson_wm9713_specific(struct snd_ac97 * ac97) 812 { 813 int err, i; 814 815 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls); i++) { 816 err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls[i], ac97)); 817 if (err < 0) 818 return err; 819 } 820 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); 821 snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808); 822 snd_ac97_write_cache(ac97, AC97_MIC, 0x0808); 823 snd_ac97_write_cache(ac97, AC97_LINE, 0x00da); 824 snd_ac97_write_cache(ac97, AC97_CD, 0x0808); 825 snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612); 826 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0); 827 return 0; 828 } 829 830 #ifdef CONFIG_PM 831 static void patch_wolfson_wm9713_suspend (struct snd_ac97 * ac97) 832 { 833 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xfeff); 834 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xffff); 835 } 836 837 static void patch_wolfson_wm9713_resume (struct snd_ac97 * ac97) 838 { 839 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); 840 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); 841 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0); 842 } 843 #endif 844 845 static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { 846 .build_specific = patch_wolfson_wm9713_specific, 847 .build_3d = patch_wolfson_wm9713_3d, 848 #ifdef CONFIG_PM 849 .suspend = patch_wolfson_wm9713_suspend, 850 .resume = patch_wolfson_wm9713_resume 851 #endif 852 }; 853 854 static int patch_wolfson13(struct snd_ac97 * ac97) 855 { 856 /* WM9713, WM9714 */ 857 ac97->build_ops = &patch_wolfson_wm9713_ops; 858 859 ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE | 860 AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD | AC97_HAS_NO_TONE | 861 AC97_HAS_NO_STD_PCM; 862 ac97->scaps &= ~AC97_SCAP_MODEM; 863 864 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); 865 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); 866 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0); 867 868 return 0; 869 } 870 871 /* 872 * Tritech codec 873 */ 874 static int patch_tritech_tr28028(struct snd_ac97 * ac97) 875 { 876 snd_ac97_write_cache(ac97, 0x26, 0x0300); 877 snd_ac97_write_cache(ac97, 0x26, 0x0000); 878 snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000); 879 snd_ac97_write_cache(ac97, AC97_SPDIF, 0x0000); 880 return 0; 881 } 882 883 /* 884 * Sigmatel STAC97xx codecs 885 */ 886 static int patch_sigmatel_stac9700_3d(struct snd_ac97 * ac97) 887 { 888 struct snd_kcontrol *kctl; 889 int err; 890 891 err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97)); 892 if (err < 0) 893 return err; 894 strcpy(kctl->id.name, "3D Control Sigmatel - Depth"); 895 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0); 896 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); 897 return 0; 898 } 899 900 static int patch_sigmatel_stac9708_3d(struct snd_ac97 * ac97) 901 { 902 struct snd_kcontrol *kctl; 903 int err; 904 905 kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97); 906 err = snd_ctl_add(ac97->bus->card, kctl); 907 if (err < 0) 908 return err; 909 strcpy(kctl->id.name, "3D Control Sigmatel - Depth"); 910 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 0, 3, 0); 911 kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97); 912 err = snd_ctl_add(ac97->bus->card, kctl); 913 if (err < 0) 914 return err; 915 strcpy(kctl->id.name, "3D Control Sigmatel - Rear Depth"); 916 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0); 917 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); 918 return 0; 919 } 920 921 static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker = 922 AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch", 923 AC97_SIGMATEL_DAC2INVERT, 2, 1, 0); 924 925 /* "Sigmatel " removed due to excessive name length: */ 926 static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert = 927 AC97_SINGLE("Surround Phase Inversion Playback Switch", 928 AC97_SIGMATEL_DAC2INVERT, 3, 1, 0); 929 930 static const struct snd_kcontrol_new snd_ac97_sigmatel_controls[] = { 931 AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0), 932 AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 0, 1, 0) 933 }; 934 935 static int patch_sigmatel_stac97xx_specific(struct snd_ac97 * ac97) 936 { 937 int err; 938 939 snd_ac97_write_cache(ac97, AC97_SIGMATEL_ANALOG, snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) & ~0x0003); 940 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 1)) { 941 err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[0], 1); 942 if (err < 0) 943 return err; 944 } 945 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 0)) { 946 err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[1], 1); 947 if (err < 0) 948 return err; 949 } 950 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 2)) { 951 err = patch_build_controls(ac97, &snd_ac97_sigmatel_4speaker, 1); 952 if (err < 0) 953 return err; 954 } 955 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 3)) { 956 err = patch_build_controls(ac97, &snd_ac97_sigmatel_phaseinvert, 1); 957 if (err < 0) 958 return err; 959 } 960 return 0; 961 } 962 963 static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { 964 .build_3d = patch_sigmatel_stac9700_3d, 965 .build_specific = patch_sigmatel_stac97xx_specific 966 }; 967 968 static int patch_sigmatel_stac9700(struct snd_ac97 * ac97) 969 { 970 ac97->build_ops = &patch_sigmatel_stac9700_ops; 971 return 0; 972 } 973 974 static int snd_ac97_stac9708_put_bias(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 975 { 976 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 977 int err; 978 979 mutex_lock(&ac97->page_mutex); 980 snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba); 981 err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010, 982 (ucontrol->value.integer.value[0] & 1) << 4); 983 snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0); 984 mutex_unlock(&ac97->page_mutex); 985 return err; 986 } 987 988 static const struct snd_kcontrol_new snd_ac97_stac9708_bias_control = { 989 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 990 .name = "Sigmatel Output Bias Switch", 991 .info = snd_ac97_info_volsw, 992 .get = snd_ac97_get_volsw, 993 .put = snd_ac97_stac9708_put_bias, 994 .private_value = AC97_SINGLE_VALUE(AC97_SIGMATEL_BIAS2, 4, 1, 0), 995 }; 996 997 static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97) 998 { 999 int err; 1000 1001 /* the register bit is writable, but the function is not implemented: */ 1002 snd_ac97_remove_ctl(ac97, "PCM Out Path & Mute", NULL); 1003 1004 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback"); 1005 err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1); 1006 if (err < 0) 1007 return err; 1008 return patch_sigmatel_stac97xx_specific(ac97); 1009 } 1010 1011 static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { 1012 .build_3d = patch_sigmatel_stac9708_3d, 1013 .build_specific = patch_sigmatel_stac9708_specific 1014 }; 1015 1016 static int patch_sigmatel_stac9708(struct snd_ac97 * ac97) 1017 { 1018 unsigned int codec72, codec6c; 1019 1020 ac97->build_ops = &patch_sigmatel_stac9708_ops; 1021 ac97->caps |= 0x10; /* HP (sigmatel surround) support */ 1022 1023 codec72 = snd_ac97_read(ac97, AC97_SIGMATEL_BIAS2) & 0x8000; 1024 codec6c = snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG); 1025 1026 if ((codec72==0) && (codec6c==0)) { 1027 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba); 1028 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1000); 1029 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba); 1030 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0007); 1031 } else if ((codec72==0x8000) && (codec6c==0)) { 1032 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba); 1033 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1001); 1034 snd_ac97_write_cache(ac97, AC97_SIGMATEL_DAC2INVERT, 0x0008); 1035 } else if ((codec72==0x8000) && (codec6c==0x0080)) { 1036 /* nothing */ 1037 } 1038 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000); 1039 return 0; 1040 } 1041 1042 static int patch_sigmatel_stac9721(struct snd_ac97 * ac97) 1043 { 1044 ac97->build_ops = &patch_sigmatel_stac9700_ops; 1045 if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) { 1046 // patch for SigmaTel 1047 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba); 1048 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x4000); 1049 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba); 1050 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002); 1051 } 1052 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000); 1053 return 0; 1054 } 1055 1056 static int patch_sigmatel_stac9744(struct snd_ac97 * ac97) 1057 { 1058 // patch for SigmaTel 1059 ac97->build_ops = &patch_sigmatel_stac9700_ops; 1060 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba); 1061 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000); /* is this correct? --jk */ 1062 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba); 1063 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002); 1064 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000); 1065 return 0; 1066 } 1067 1068 static int patch_sigmatel_stac9756(struct snd_ac97 * ac97) 1069 { 1070 // patch for SigmaTel 1071 ac97->build_ops = &patch_sigmatel_stac9700_ops; 1072 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba); 1073 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000); /* is this correct? --jk */ 1074 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba); 1075 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002); 1076 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000); 1077 return 0; 1078 } 1079 1080 static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1081 { 1082 static const char * const texts[5] = { 1083 "Input/Disabled", "Front Output", 1084 "Rear Output", "Center/LFE Output", "Mixer Output" }; 1085 1086 return snd_ctl_enum_info(uinfo, 1, 5, texts); 1087 } 1088 1089 static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1090 { 1091 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1092 int shift = kcontrol->private_value; 1093 unsigned short val; 1094 1095 val = ac97->regs[AC97_SIGMATEL_OUTSEL] >> shift; 1096 if (!(val & 4)) 1097 ucontrol->value.enumerated.item[0] = 0; 1098 else 1099 ucontrol->value.enumerated.item[0] = 1 + (val & 3); 1100 return 0; 1101 } 1102 1103 static int snd_ac97_stac9758_output_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1104 { 1105 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1106 int shift = kcontrol->private_value; 1107 unsigned short val; 1108 1109 if (ucontrol->value.enumerated.item[0] > 4) 1110 return -EINVAL; 1111 if (ucontrol->value.enumerated.item[0] == 0) 1112 val = 0; 1113 else 1114 val = 4 | (ucontrol->value.enumerated.item[0] - 1); 1115 return ac97_update_bits_page(ac97, AC97_SIGMATEL_OUTSEL, 1116 7 << shift, val << shift, 0); 1117 } 1118 1119 static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1120 { 1121 static const char * const texts[7] = { 1122 "Mic2 Jack", "Mic1 Jack", "Line In Jack", 1123 "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" }; 1124 1125 return snd_ctl_enum_info(uinfo, 1, 7, texts); 1126 } 1127 1128 static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1129 { 1130 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1131 int shift = kcontrol->private_value; 1132 unsigned short val; 1133 1134 val = ac97->regs[AC97_SIGMATEL_INSEL]; 1135 ucontrol->value.enumerated.item[0] = (val >> shift) & 7; 1136 return 0; 1137 } 1138 1139 static int snd_ac97_stac9758_input_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1140 { 1141 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1142 int shift = kcontrol->private_value; 1143 1144 return ac97_update_bits_page(ac97, AC97_SIGMATEL_INSEL, 7 << shift, 1145 ucontrol->value.enumerated.item[0] << shift, 0); 1146 } 1147 1148 static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1149 { 1150 static const char * const texts[3] = { 1151 "None", "Front Jack", "Rear Jack" 1152 }; 1153 1154 return snd_ctl_enum_info(uinfo, 1, 3, texts); 1155 } 1156 1157 static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1158 { 1159 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1160 1161 ucontrol->value.enumerated.item[0] = ac97->regs[AC97_SIGMATEL_IOMISC] & 3; 1162 return 0; 1163 } 1164 1165 static int snd_ac97_stac9758_phonesel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1166 { 1167 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1168 1169 return ac97_update_bits_page(ac97, AC97_SIGMATEL_IOMISC, 3, 1170 ucontrol->value.enumerated.item[0], 0); 1171 } 1172 1173 #define STAC9758_OUTPUT_JACK(xname, shift) \ 1174 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 1175 .info = snd_ac97_stac9758_output_jack_info, \ 1176 .get = snd_ac97_stac9758_output_jack_get, \ 1177 .put = snd_ac97_stac9758_output_jack_put, \ 1178 .private_value = shift } 1179 #define STAC9758_INPUT_JACK(xname, shift) \ 1180 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 1181 .info = snd_ac97_stac9758_input_jack_info, \ 1182 .get = snd_ac97_stac9758_input_jack_get, \ 1183 .put = snd_ac97_stac9758_input_jack_put, \ 1184 .private_value = shift } 1185 static const struct snd_kcontrol_new snd_ac97_sigmatel_stac9758_controls[] = { 1186 STAC9758_OUTPUT_JACK("Mic1 Jack", 1), 1187 STAC9758_OUTPUT_JACK("LineIn Jack", 4), 1188 STAC9758_OUTPUT_JACK("Front Jack", 7), 1189 STAC9758_OUTPUT_JACK("Rear Jack", 10), 1190 STAC9758_OUTPUT_JACK("Center/LFE Jack", 13), 1191 STAC9758_INPUT_JACK("Mic Input Source", 0), 1192 STAC9758_INPUT_JACK("Line Input Source", 8), 1193 { 1194 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1195 .name = "Headphone Amp", 1196 .info = snd_ac97_stac9758_phonesel_info, 1197 .get = snd_ac97_stac9758_phonesel_get, 1198 .put = snd_ac97_stac9758_phonesel_put 1199 }, 1200 AC97_SINGLE("Exchange Center/LFE", AC97_SIGMATEL_IOMISC, 4, 1, 0), 1201 AC97_SINGLE("Headphone +3dB Boost", AC97_SIGMATEL_IOMISC, 8, 1, 0) 1202 }; 1203 1204 static int patch_sigmatel_stac9758_specific(struct snd_ac97 *ac97) 1205 { 1206 int err; 1207 1208 err = patch_sigmatel_stac97xx_specific(ac97); 1209 if (err < 0) 1210 return err; 1211 err = patch_build_controls(ac97, snd_ac97_sigmatel_stac9758_controls, 1212 ARRAY_SIZE(snd_ac97_sigmatel_stac9758_controls)); 1213 if (err < 0) 1214 return err; 1215 /* DAC-A direct */ 1216 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Front Playback"); 1217 /* DAC-A to Mix = PCM */ 1218 /* DAC-B direct = Surround */ 1219 /* DAC-B to Mix */ 1220 snd_ac97_rename_vol_ctl(ac97, "Video Playback", "Surround Mix Playback"); 1221 /* DAC-C direct = Center/LFE */ 1222 1223 return 0; 1224 } 1225 1226 static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { 1227 .build_3d = patch_sigmatel_stac9700_3d, 1228 .build_specific = patch_sigmatel_stac9758_specific 1229 }; 1230 1231 static int patch_sigmatel_stac9758(struct snd_ac97 * ac97) 1232 { 1233 static const unsigned short regs[4] = { 1234 AC97_SIGMATEL_OUTSEL, 1235 AC97_SIGMATEL_IOMISC, 1236 AC97_SIGMATEL_INSEL, 1237 AC97_SIGMATEL_VARIOUS 1238 }; 1239 static const unsigned short def_regs[4] = { 1240 /* OUTSEL */ 0xd794, /* CL:CL, SR:SR, LO:MX, LI:DS, MI:DS */ 1241 /* IOMISC */ 0x2001, 1242 /* INSEL */ 0x0201, /* LI:LI, MI:M1 */ 1243 /* VARIOUS */ 0x0040 1244 }; 1245 static const unsigned short m675_regs[4] = { 1246 /* OUTSEL */ 0xfc70, /* CL:MX, SR:MX, LO:DS, LI:MX, MI:DS */ 1247 /* IOMISC */ 0x2102, /* HP amp on */ 1248 /* INSEL */ 0x0203, /* LI:LI, MI:FR */ 1249 /* VARIOUS */ 0x0041 /* stereo mic */ 1250 }; 1251 const unsigned short *pregs = def_regs; 1252 int i; 1253 1254 /* Gateway M675 notebook */ 1255 if (ac97->pci && 1256 ac97->subsystem_vendor == 0x107b && 1257 ac97->subsystem_device == 0x0601) 1258 pregs = m675_regs; 1259 1260 // patch for SigmaTel 1261 ac97->build_ops = &patch_sigmatel_stac9758_ops; 1262 /* FIXME: assume only page 0 for writing cache */ 1263 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR); 1264 for (i = 0; i < 4; i++) 1265 snd_ac97_write_cache(ac97, regs[i], pregs[i]); 1266 1267 ac97->flags |= AC97_STEREO_MUTES; 1268 return 0; 1269 } 1270 1271 /* 1272 * Cirrus Logic CS42xx codecs 1273 */ 1274 static const struct snd_kcontrol_new snd_ac97_cirrus_controls_spdif[2] = { 1275 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CSR_SPDIF, 15, 1, 0), 1276 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA", AC97_CSR_ACMODE, 0, 3, 0) 1277 }; 1278 1279 static int patch_cirrus_build_spdif(struct snd_ac97 * ac97) 1280 { 1281 int err; 1282 1283 /* con mask, pro mask, default */ 1284 err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3); 1285 if (err < 0) 1286 return err; 1287 /* switch, spsa */ 1288 err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[0], 1); 1289 if (err < 0) 1290 return err; 1291 switch (ac97->id & AC97_ID_CS_MASK) { 1292 case AC97_ID_CS4205: 1293 err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[1], 1); 1294 if (err < 0) 1295 return err; 1296 break; 1297 } 1298 /* set default PCM S/PDIF params */ 1299 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */ 1300 snd_ac97_write_cache(ac97, AC97_CSR_SPDIF, 0x0a20); 1301 return 0; 1302 } 1303 1304 static const struct snd_ac97_build_ops patch_cirrus_ops = { 1305 .build_spdif = patch_cirrus_build_spdif 1306 }; 1307 1308 static int patch_cirrus_spdif(struct snd_ac97 * ac97) 1309 { 1310 /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers. 1311 WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh* 1312 - sp/dif EA ID is not set, but sp/dif is always present. 1313 - enable/disable is spdif register bit 15. 1314 - sp/dif control register is 0x68. differs from AC97: 1315 - valid is bit 14 (vs 15) 1316 - no DRS 1317 - only 44.1/48k [00 = 48, 01=44,1] (AC97 is 00=44.1, 10=48) 1318 - sp/dif ssource select is in 0x5e bits 0,1. 1319 */ 1320 1321 ac97->build_ops = &patch_cirrus_ops; 1322 ac97->flags |= AC97_CS_SPDIF; 1323 ac97->rates[AC97_RATES_SPDIF] &= ~SNDRV_PCM_RATE_32000; 1324 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ 1325 snd_ac97_write_cache(ac97, AC97_CSR_ACMODE, 0x0080); 1326 return 0; 1327 } 1328 1329 static int patch_cirrus_cs4299(struct snd_ac97 * ac97) 1330 { 1331 /* force the detection of PC Beep */ 1332 ac97->flags |= AC97_HAS_PC_BEEP; 1333 1334 return patch_cirrus_spdif(ac97); 1335 } 1336 1337 /* 1338 * Conexant codecs 1339 */ 1340 static const struct snd_kcontrol_new snd_ac97_conexant_controls_spdif[1] = { 1341 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CXR_AUDIO_MISC, 3, 1, 0), 1342 }; 1343 1344 static int patch_conexant_build_spdif(struct snd_ac97 * ac97) 1345 { 1346 int err; 1347 1348 /* con mask, pro mask, default */ 1349 err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3); 1350 if (err < 0) 1351 return err; 1352 /* switch */ 1353 err = patch_build_controls(ac97, &snd_ac97_conexant_controls_spdif[0], 1); 1354 if (err < 0) 1355 return err; 1356 /* set default PCM S/PDIF params */ 1357 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */ 1358 snd_ac97_write_cache(ac97, AC97_CXR_AUDIO_MISC, 1359 snd_ac97_read(ac97, AC97_CXR_AUDIO_MISC) & ~(AC97_CXR_SPDIFEN|AC97_CXR_COPYRGT|AC97_CXR_SPDIF_MASK)); 1360 return 0; 1361 } 1362 1363 static const struct snd_ac97_build_ops patch_conexant_ops = { 1364 .build_spdif = patch_conexant_build_spdif 1365 }; 1366 1367 static int patch_conexant(struct snd_ac97 * ac97) 1368 { 1369 ac97->build_ops = &patch_conexant_ops; 1370 ac97->flags |= AC97_CX_SPDIF; 1371 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ 1372 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ 1373 return 0; 1374 } 1375 1376 static int patch_cx20551(struct snd_ac97 *ac97) 1377 { 1378 snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01); 1379 return 0; 1380 } 1381 1382 /* 1383 * Analog Devices AD18xx, AD19xx codecs 1384 */ 1385 #ifdef CONFIG_PM 1386 static void ad18xx_resume(struct snd_ac97 *ac97) 1387 { 1388 static const unsigned short setup_regs[] = { 1389 AC97_AD_MISC, AC97_AD_SERIAL_CFG, AC97_AD_JACK_SPDIF, 1390 }; 1391 int i, codec; 1392 1393 for (i = 0; i < (int)ARRAY_SIZE(setup_regs); i++) { 1394 unsigned short reg = setup_regs[i]; 1395 if (test_bit(reg, ac97->reg_accessed)) { 1396 snd_ac97_write(ac97, reg, ac97->regs[reg]); 1397 snd_ac97_read(ac97, reg); 1398 } 1399 } 1400 1401 if (! (ac97->flags & AC97_AD_MULTI)) 1402 /* normal restore */ 1403 snd_ac97_restore_status(ac97); 1404 else { 1405 /* restore the AD18xx codec configurations */ 1406 for (codec = 0; codec < 3; codec++) { 1407 if (! ac97->spec.ad18xx.id[codec]) 1408 continue; 1409 /* select single codec */ 1410 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 1411 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]); 1412 ac97->bus->ops->write(ac97, AC97_AD_CODEC_CFG, ac97->spec.ad18xx.codec_cfg[codec]); 1413 } 1414 /* select all codecs */ 1415 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000); 1416 1417 /* restore status */ 1418 for (i = 2; i < 0x7c ; i += 2) { 1419 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID) 1420 continue; 1421 if (test_bit(i, ac97->reg_accessed)) { 1422 /* handle multi codecs for AD18xx */ 1423 if (i == AC97_PCM) { 1424 for (codec = 0; codec < 3; codec++) { 1425 if (! ac97->spec.ad18xx.id[codec]) 1426 continue; 1427 /* select single codec */ 1428 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 1429 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]); 1430 /* update PCM bits */ 1431 ac97->bus->ops->write(ac97, AC97_PCM, ac97->spec.ad18xx.pcmreg[codec]); 1432 } 1433 /* select all codecs */ 1434 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000); 1435 continue; 1436 } else if (i == AC97_AD_TEST || 1437 i == AC97_AD_CODEC_CFG || 1438 i == AC97_AD_SERIAL_CFG) 1439 continue; /* ignore */ 1440 } 1441 snd_ac97_write(ac97, i, ac97->regs[i]); 1442 snd_ac97_read(ac97, i); 1443 } 1444 } 1445 1446 snd_ac97_restore_iec958(ac97); 1447 } 1448 1449 static void ad1888_resume(struct snd_ac97 *ac97) 1450 { 1451 ad18xx_resume(ac97); 1452 snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x8080); 1453 } 1454 1455 #endif 1456 1457 static const struct snd_ac97_res_table ad1819_restbl[] = { 1458 { AC97_PHONE, 0x9f1f }, 1459 { AC97_MIC, 0x9f1f }, 1460 { AC97_LINE, 0x9f1f }, 1461 { AC97_CD, 0x9f1f }, 1462 { AC97_VIDEO, 0x9f1f }, 1463 { AC97_AUX, 0x9f1f }, 1464 { AC97_PCM, 0x9f1f }, 1465 { } /* terminator */ 1466 }; 1467 1468 static int patch_ad1819(struct snd_ac97 * ac97) 1469 { 1470 unsigned short scfg; 1471 1472 // patch for Analog Devices 1473 scfg = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG); 1474 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x7000); /* select all codecs */ 1475 ac97->res_table = ad1819_restbl; 1476 return 0; 1477 } 1478 1479 static unsigned short patch_ad1881_unchained(struct snd_ac97 * ac97, int idx, unsigned short mask) 1480 { 1481 unsigned short val; 1482 1483 // test for unchained codec 1484 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, mask); 1485 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000); /* ID0C, ID1C, SDIE = off */ 1486 val = snd_ac97_read(ac97, AC97_VENDOR_ID2); 1487 if ((val & 0xff40) != 0x5340) 1488 return 0; 1489 ac97->spec.ad18xx.unchained[idx] = mask; 1490 ac97->spec.ad18xx.id[idx] = val; 1491 ac97->spec.ad18xx.codec_cfg[idx] = 0x0000; 1492 return mask; 1493 } 1494 1495 static int patch_ad1881_chained1(struct snd_ac97 * ac97, int idx, unsigned short codec_bits) 1496 { 1497 static const int cfg_bits[3] = { 1<<12, 1<<14, 1<<13 }; 1498 unsigned short val; 1499 1500 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, cfg_bits[idx]); 1501 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0004); // SDIE 1502 val = snd_ac97_read(ac97, AC97_VENDOR_ID2); 1503 if ((val & 0xff40) != 0x5340) 1504 return 0; 1505 if (codec_bits) 1506 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, codec_bits); 1507 ac97->spec.ad18xx.chained[idx] = cfg_bits[idx]; 1508 ac97->spec.ad18xx.id[idx] = val; 1509 ac97->spec.ad18xx.codec_cfg[idx] = codec_bits ? codec_bits : 0x0004; 1510 return 1; 1511 } 1512 1513 static void patch_ad1881_chained(struct snd_ac97 * ac97, int unchained_idx, int cidx1, int cidx2) 1514 { 1515 // already detected? 1516 if (ac97->spec.ad18xx.unchained[cidx1] || ac97->spec.ad18xx.chained[cidx1]) 1517 cidx1 = -1; 1518 if (ac97->spec.ad18xx.unchained[cidx2] || ac97->spec.ad18xx.chained[cidx2]) 1519 cidx2 = -1; 1520 if (cidx1 < 0 && cidx2 < 0) 1521 return; 1522 // test for chained codecs 1523 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 1524 ac97->spec.ad18xx.unchained[unchained_idx]); 1525 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0002); // ID1C 1526 ac97->spec.ad18xx.codec_cfg[unchained_idx] = 0x0002; 1527 if (cidx1 >= 0) { 1528 if (cidx2 < 0) 1529 patch_ad1881_chained1(ac97, cidx1, 0); 1530 else if (patch_ad1881_chained1(ac97, cidx1, 0x0006)) // SDIE | ID1C 1531 patch_ad1881_chained1(ac97, cidx2, 0); 1532 else if (patch_ad1881_chained1(ac97, cidx2, 0x0006)) // SDIE | ID1C 1533 patch_ad1881_chained1(ac97, cidx1, 0); 1534 } else if (cidx2 >= 0) { 1535 patch_ad1881_chained1(ac97, cidx2, 0); 1536 } 1537 } 1538 1539 static const struct snd_ac97_build_ops patch_ad1881_build_ops = { 1540 #ifdef CONFIG_PM 1541 .resume = ad18xx_resume 1542 #endif 1543 }; 1544 1545 static int patch_ad1881(struct snd_ac97 * ac97) 1546 { 1547 static const char cfg_idxs[3][2] = { 1548 {2, 1}, 1549 {0, 2}, 1550 {0, 1} 1551 }; 1552 1553 // patch for Analog Devices 1554 unsigned short codecs[3]; 1555 unsigned short val; 1556 int idx, num; 1557 1558 val = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG); 1559 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, val); 1560 codecs[0] = patch_ad1881_unchained(ac97, 0, (1<<12)); 1561 codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14)); 1562 codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13)); 1563 1564 if (! (codecs[0] || codecs[1] || codecs[2])) 1565 goto __end; 1566 1567 for (idx = 0; idx < 3; idx++) 1568 if (ac97->spec.ad18xx.unchained[idx]) 1569 patch_ad1881_chained(ac97, idx, cfg_idxs[idx][0], cfg_idxs[idx][1]); 1570 1571 if (ac97->spec.ad18xx.id[1]) { 1572 ac97->flags |= AC97_AD_MULTI; 1573 ac97->scaps |= AC97_SCAP_SURROUND_DAC; 1574 } 1575 if (ac97->spec.ad18xx.id[2]) { 1576 ac97->flags |= AC97_AD_MULTI; 1577 ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC; 1578 } 1579 1580 __end: 1581 /* select all codecs */ 1582 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000); 1583 /* check if only one codec is present */ 1584 for (idx = num = 0; idx < 3; idx++) 1585 if (ac97->spec.ad18xx.id[idx]) 1586 num++; 1587 if (num == 1) { 1588 /* ok, deselect all ID bits */ 1589 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000); 1590 ac97->spec.ad18xx.codec_cfg[0] = 1591 ac97->spec.ad18xx.codec_cfg[1] = 1592 ac97->spec.ad18xx.codec_cfg[2] = 0x0000; 1593 } 1594 /* required for AD1886/AD1885 combination */ 1595 ac97->ext_id = snd_ac97_read(ac97, AC97_EXTENDED_ID); 1596 if (ac97->spec.ad18xx.id[0]) { 1597 ac97->id &= 0xffff0000; 1598 ac97->id |= ac97->spec.ad18xx.id[0]; 1599 } 1600 ac97->build_ops = &patch_ad1881_build_ops; 1601 return 0; 1602 } 1603 1604 static const struct snd_kcontrol_new snd_ac97_controls_ad1885[] = { 1605 AC97_SINGLE("Digital Mono Direct", AC97_AD_MISC, 11, 1, 0), 1606 /* AC97_SINGLE("Digital Audio Mode", AC97_AD_MISC, 12, 1, 0), */ /* seems problematic */ 1607 AC97_SINGLE("Low Power Mixer", AC97_AD_MISC, 14, 1, 0), 1608 AC97_SINGLE("Zero Fill DAC", AC97_AD_MISC, 15, 1, 0), 1609 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 9, 1, 1), /* inverted */ 1610 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 8, 1, 1), /* inverted */ 1611 }; 1612 1613 static const DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0); 1614 1615 static int patch_ad1885_specific(struct snd_ac97 * ac97) 1616 { 1617 int err; 1618 1619 err = patch_build_controls(ac97, snd_ac97_controls_ad1885, ARRAY_SIZE(snd_ac97_controls_ad1885)); 1620 if (err < 0) 1621 return err; 1622 reset_tlv(ac97, "Headphone Playback Volume", 1623 db_scale_6bit_6db_max); 1624 return 0; 1625 } 1626 1627 static const struct snd_ac97_build_ops patch_ad1885_build_ops = { 1628 .build_specific = &patch_ad1885_specific, 1629 #ifdef CONFIG_PM 1630 .resume = ad18xx_resume 1631 #endif 1632 }; 1633 1634 static int patch_ad1885(struct snd_ac97 * ac97) 1635 { 1636 patch_ad1881(ac97); 1637 /* This is required to deal with the Intel D815EEAL2 */ 1638 /* i.e. Line out is actually headphone out from codec */ 1639 1640 /* set default */ 1641 snd_ac97_write_cache(ac97, AC97_AD_MISC, 0x0404); 1642 1643 ac97->build_ops = &patch_ad1885_build_ops; 1644 return 0; 1645 } 1646 1647 static int patch_ad1886_specific(struct snd_ac97 * ac97) 1648 { 1649 reset_tlv(ac97, "Headphone Playback Volume", 1650 db_scale_6bit_6db_max); 1651 return 0; 1652 } 1653 1654 static const struct snd_ac97_build_ops patch_ad1886_build_ops = { 1655 .build_specific = &patch_ad1886_specific, 1656 #ifdef CONFIG_PM 1657 .resume = ad18xx_resume 1658 #endif 1659 }; 1660 1661 static int patch_ad1886(struct snd_ac97 * ac97) 1662 { 1663 patch_ad1881(ac97); 1664 /* Presario700 workaround */ 1665 /* for Jack Sense/SPDIF Register misetting causing */ 1666 snd_ac97_write_cache(ac97, AC97_AD_JACK_SPDIF, 0x0010); 1667 ac97->build_ops = &patch_ad1886_build_ops; 1668 return 0; 1669 } 1670 1671 /* MISC bits (AD1888/AD1980/AD1985 register 0x76) */ 1672 #define AC97_AD198X_MBC 0x0003 /* mic boost */ 1673 #define AC97_AD198X_MBC_20 0x0000 /* +20dB */ 1674 #define AC97_AD198X_MBC_10 0x0001 /* +10dB */ 1675 #define AC97_AD198X_MBC_30 0x0002 /* +30dB */ 1676 #define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */ 1677 #define AC97_AD198X_VREFH 0x0008 /* 0=2.25V, 1=3.7V */ 1678 #define AC97_AD198X_VREF_0 0x000c /* 0V (AD1985 only) */ 1679 #define AC97_AD198X_VREF_MASK (AC97_AD198X_VREFH | AC97_AD198X_VREFD) 1680 #define AC97_AD198X_VREF_SHIFT 2 1681 #define AC97_AD198X_SRU 0x0010 /* sample rate unlock */ 1682 #define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */ 1683 #define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */ 1684 #define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */ 1685 #define AC97_AD198X_DMIX0 0x0100 /* downmix mode: */ 1686 /* 0 = 6-to-4, 1 = 6-to-2 downmix */ 1687 #define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */ 1688 #define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */ 1689 #define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */ 1690 #define AC97_AD198X_LODIS 0x1000 /* LINE_OUT disable */ 1691 #define AC97_AD198X_MSPLT 0x2000 /* mute split */ 1692 #define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */ 1693 #define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */ 1694 1695 /* MISC 1 bits (AD1986 register 0x76) */ 1696 #define AC97_AD1986_MBC 0x0003 /* mic boost */ 1697 #define AC97_AD1986_MBC_20 0x0000 /* +20dB */ 1698 #define AC97_AD1986_MBC_10 0x0001 /* +10dB */ 1699 #define AC97_AD1986_MBC_30 0x0002 /* +30dB */ 1700 #define AC97_AD1986_LISEL0 0x0004 /* LINE_IN select bit 0 */ 1701 #define AC97_AD1986_LISEL1 0x0008 /* LINE_IN select bit 1 */ 1702 #define AC97_AD1986_LISEL_MASK (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0) 1703 #define AC97_AD1986_LISEL_LI 0x0000 /* LINE_IN pins as LINE_IN source */ 1704 #define AC97_AD1986_LISEL_SURR 0x0004 /* SURROUND pins as LINE_IN source */ 1705 #define AC97_AD1986_LISEL_MIC 0x0008 /* MIC_1/2 pins as LINE_IN source */ 1706 #define AC97_AD1986_SRU 0x0010 /* sample rate unlock */ 1707 #define AC97_AD1986_SOSEL 0x0020 /* SURROUND_OUT amplifiers input sel */ 1708 #define AC97_AD1986_2MIC 0x0040 /* 2-channel mic select */ 1709 #define AC97_AD1986_SPRD 0x0080 /* SPREAD enable */ 1710 #define AC97_AD1986_DMIX0 0x0100 /* downmix mode: */ 1711 /* 0 = 6-to-4, 1 = 6-to-2 downmix */ 1712 #define AC97_AD1986_DMIX1 0x0200 /* downmix mode: 1 = enabled */ 1713 #define AC97_AD1986_CLDIS 0x0800 /* center/lfe disable */ 1714 #define AC97_AD1986_SODIS 0x1000 /* SURROUND_OUT disable */ 1715 #define AC97_AD1986_MSPLT 0x2000 /* mute split (read only 1) */ 1716 #define AC97_AD1986_AC97NC 0x4000 /* AC97 no compatible mode (r/o 1) */ 1717 #define AC97_AD1986_DACZ 0x8000 /* DAC zero-fill mode */ 1718 1719 /* MISC 2 bits (AD1986 register 0x70) */ 1720 #define AC97_AD_MISC2 0x70 /* Misc Control Bits 2 (AD1986) */ 1721 1722 #define AC97_AD1986_CVREF0 0x0004 /* C/LFE VREF_OUT 2.25V */ 1723 #define AC97_AD1986_CVREF1 0x0008 /* C/LFE VREF_OUT 0V */ 1724 #define AC97_AD1986_CVREF2 0x0010 /* C/LFE VREF_OUT 3.7V */ 1725 #define AC97_AD1986_CVREF_MASK \ 1726 (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0) 1727 #define AC97_AD1986_JSMAP 0x0020 /* Jack Sense Mapping 1 = alternate */ 1728 #define AC97_AD1986_MMDIS 0x0080 /* Mono Mute Disable */ 1729 #define AC97_AD1986_MVREF0 0x0400 /* MIC VREF_OUT 2.25V */ 1730 #define AC97_AD1986_MVREF1 0x0800 /* MIC VREF_OUT 0V */ 1731 #define AC97_AD1986_MVREF2 0x1000 /* MIC VREF_OUT 3.7V */ 1732 #define AC97_AD1986_MVREF_MASK \ 1733 (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0) 1734 1735 /* MISC 3 bits (AD1986 register 0x7a) */ 1736 #define AC97_AD_MISC3 0x7a /* Misc Control Bits 3 (AD1986) */ 1737 1738 #define AC97_AD1986_MMIX 0x0004 /* Mic Mix, left/right */ 1739 #define AC97_AD1986_GPO 0x0008 /* General Purpose Out */ 1740 #define AC97_AD1986_LOHPEN 0x0010 /* LINE_OUT headphone drive */ 1741 #define AC97_AD1986_LVREF0 0x0100 /* LINE_OUT VREF_OUT 2.25V */ 1742 #define AC97_AD1986_LVREF1 0x0200 /* LINE_OUT VREF_OUT 0V */ 1743 #define AC97_AD1986_LVREF2 0x0400 /* LINE_OUT VREF_OUT 3.7V */ 1744 #define AC97_AD1986_LVREF_MASK \ 1745 (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0) 1746 #define AC97_AD1986_JSINVA 0x0800 /* Jack Sense Invert SENSE_A */ 1747 #define AC97_AD1986_LOSEL 0x1000 /* LINE_OUT amplifiers input select */ 1748 #define AC97_AD1986_HPSEL0 0x2000 /* Headphone amplifiers */ 1749 /* input select Surround DACs */ 1750 #define AC97_AD1986_HPSEL1 0x4000 /* Headphone amplifiers input */ 1751 /* select C/LFE DACs */ 1752 #define AC97_AD1986_JSINVB 0x8000 /* Jack Sense Invert SENSE_B */ 1753 1754 /* Serial Config bits (AD1986 register 0x74) (incomplete) */ 1755 #define AC97_AD1986_OMS0 0x0100 /* Optional Mic Selector bit 0 */ 1756 #define AC97_AD1986_OMS1 0x0200 /* Optional Mic Selector bit 1 */ 1757 #define AC97_AD1986_OMS2 0x0400 /* Optional Mic Selector bit 2 */ 1758 #define AC97_AD1986_OMS_MASK \ 1759 (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0) 1760 #define AC97_AD1986_OMS_M 0x0000 /* MIC_1/2 pins are MIC sources */ 1761 #define AC97_AD1986_OMS_L 0x0100 /* LINE_IN pins are MIC sources */ 1762 #define AC97_AD1986_OMS_C 0x0200 /* Center/LFE pins are MCI sources */ 1763 #define AC97_AD1986_OMS_MC 0x0400 /* Mix of MIC and C/LFE pins */ 1764 /* are MIC sources */ 1765 #define AC97_AD1986_OMS_ML 0x0500 /* MIX of MIC and LINE_IN pins */ 1766 /* are MIC sources */ 1767 #define AC97_AD1986_OMS_LC 0x0600 /* MIX of LINE_IN and C/LFE pins */ 1768 /* are MIC sources */ 1769 #define AC97_AD1986_OMS_MLC 0x0700 /* MIX of MIC, LINE_IN, C/LFE pins */ 1770 /* are MIC sources */ 1771 1772 1773 static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1774 { 1775 static const char * const texts[2] = { "AC-Link", "A/D Converter" }; 1776 1777 return snd_ctl_enum_info(uinfo, 1, 2, texts); 1778 } 1779 1780 static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1781 { 1782 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1783 unsigned short val; 1784 1785 val = ac97->regs[AC97_AD_SERIAL_CFG]; 1786 ucontrol->value.enumerated.item[0] = (val >> 2) & 1; 1787 return 0; 1788 } 1789 1790 static int snd_ac97_ad198x_spdif_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1791 { 1792 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1793 unsigned short val; 1794 1795 if (ucontrol->value.enumerated.item[0] > 1) 1796 return -EINVAL; 1797 val = ucontrol->value.enumerated.item[0] << 2; 1798 return snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x0004, val); 1799 } 1800 1801 static const struct snd_kcontrol_new snd_ac97_ad198x_spdif_source = { 1802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1803 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1804 .info = snd_ac97_ad198x_spdif_source_info, 1805 .get = snd_ac97_ad198x_spdif_source_get, 1806 .put = snd_ac97_ad198x_spdif_source_put, 1807 }; 1808 1809 static int patch_ad198x_post_spdif(struct snd_ac97 * ac97) 1810 { 1811 return patch_build_controls(ac97, &snd_ac97_ad198x_spdif_source, 1); 1812 } 1813 1814 static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense[] = { 1815 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 11, 1, 0), 1816 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0), 1817 }; 1818 1819 /* deny list to avoid HP/Line jack-sense controls 1820 * (SS vendor << 16 | device) 1821 */ 1822 static const unsigned int ad1981_jacks_denylist[] = { 1823 0x10140523, /* Thinkpad R40 */ 1824 0x10140534, /* Thinkpad X31 */ 1825 0x10140537, /* Thinkpad T41p */ 1826 0x1014053e, /* Thinkpad R40e */ 1827 0x10140554, /* Thinkpad T42p/R50p */ 1828 0x10140567, /* Thinkpad T43p 2668-G7U */ 1829 0x10140581, /* Thinkpad X41-2527 */ 1830 0x10280160, /* Dell Dimension 2400 */ 1831 0x104380b0, /* Asus A7V8X-MX */ 1832 0x11790241, /* Toshiba Satellite A-15 S127 */ 1833 0x1179ff10, /* Toshiba P500 */ 1834 0x144dc01a, /* Samsung NP-X20C004/SEG */ 1835 0 /* end */ 1836 }; 1837 1838 static int check_list(struct snd_ac97 *ac97, const unsigned int *list) 1839 { 1840 u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device; 1841 for (; *list; list++) 1842 if (*list == subid) 1843 return 1; 1844 return 0; 1845 } 1846 1847 static int patch_ad1981a_specific(struct snd_ac97 * ac97) 1848 { 1849 if (check_list(ac97, ad1981_jacks_denylist)) 1850 return 0; 1851 return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense, 1852 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); 1853 } 1854 1855 static const struct snd_ac97_build_ops patch_ad1981a_build_ops = { 1856 .build_post_spdif = patch_ad198x_post_spdif, 1857 .build_specific = patch_ad1981a_specific, 1858 #ifdef CONFIG_PM 1859 .resume = ad18xx_resume 1860 #endif 1861 }; 1862 1863 /* allow list to enable HP jack-sense bits 1864 * (SS vendor << 16 | device) 1865 */ 1866 static const unsigned int ad1981_jacks_allowlist[] = { 1867 0x0e11005a, /* HP nc4000/4010 */ 1868 0x103c0890, /* HP nc6000 */ 1869 0x103c0938, /* HP nc4220 */ 1870 0x103c099c, /* HP nx6110 */ 1871 0x103c0944, /* HP nc6220 */ 1872 0x103c0934, /* HP nc8220 */ 1873 0x103c006d, /* HP nx9105 */ 1874 0x103c300d, /* HP Compaq dc5100 SFF(PT003AW) */ 1875 0x17340088, /* FSC Scenic-W */ 1876 0 /* end */ 1877 }; 1878 1879 static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97) 1880 { 1881 if (check_list(ac97, ad1981_jacks_allowlist)) 1882 /* enable headphone jack sense */ 1883 snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); 1884 } 1885 1886 static int patch_ad1981a(struct snd_ac97 *ac97) 1887 { 1888 patch_ad1881(ac97); 1889 ac97->build_ops = &patch_ad1981a_build_ops; 1890 snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT); 1891 ac97->flags |= AC97_STEREO_MUTES; 1892 check_ad1981_hp_jack_sense(ac97); 1893 return 0; 1894 } 1895 1896 static const struct snd_kcontrol_new snd_ac97_ad198x_2cmic = 1897 AC97_SINGLE("Stereo Mic", AC97_AD_MISC, 6, 1, 0); 1898 1899 static int patch_ad1981b_specific(struct snd_ac97 *ac97) 1900 { 1901 int err; 1902 1903 err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1); 1904 if (err < 0) 1905 return err; 1906 if (check_list(ac97, ad1981_jacks_denylist)) 1907 return 0; 1908 return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense, 1909 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); 1910 } 1911 1912 static const struct snd_ac97_build_ops patch_ad1981b_build_ops = { 1913 .build_post_spdif = patch_ad198x_post_spdif, 1914 .build_specific = patch_ad1981b_specific, 1915 #ifdef CONFIG_PM 1916 .resume = ad18xx_resume 1917 #endif 1918 }; 1919 1920 static int patch_ad1981b(struct snd_ac97 *ac97) 1921 { 1922 patch_ad1881(ac97); 1923 ac97->build_ops = &patch_ad1981b_build_ops; 1924 snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT); 1925 ac97->flags |= AC97_STEREO_MUTES; 1926 check_ad1981_hp_jack_sense(ac97); 1927 return 0; 1928 } 1929 1930 #define snd_ac97_ad1888_lohpsel_info snd_ctl_boolean_mono_info 1931 1932 static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1933 { 1934 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1935 unsigned short val; 1936 1937 val = ac97->regs[AC97_AD_MISC]; 1938 ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL); 1939 if (ac97->spec.ad18xx.lo_as_master) 1940 ucontrol->value.integer.value[0] = 1941 !ucontrol->value.integer.value[0]; 1942 return 0; 1943 } 1944 1945 static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1946 { 1947 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1948 unsigned short val; 1949 1950 val = !ucontrol->value.integer.value[0]; 1951 if (ac97->spec.ad18xx.lo_as_master) 1952 val = !val; 1953 val = val ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0; 1954 return snd_ac97_update_bits(ac97, AC97_AD_MISC, 1955 AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val); 1956 } 1957 1958 static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1959 { 1960 static const char * const texts[3] = {"Off", "6 -> 4", "6 -> 2"}; 1961 1962 return snd_ctl_enum_info(uinfo, 1, 3, texts); 1963 } 1964 1965 static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1966 { 1967 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1968 unsigned short val; 1969 1970 val = ac97->regs[AC97_AD_MISC]; 1971 if (!(val & AC97_AD198X_DMIX1)) 1972 ucontrol->value.enumerated.item[0] = 0; 1973 else 1974 ucontrol->value.enumerated.item[0] = 1 + ((val >> 8) & 1); 1975 return 0; 1976 } 1977 1978 static int snd_ac97_ad1888_downmix_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1979 { 1980 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 1981 unsigned short val; 1982 1983 if (ucontrol->value.enumerated.item[0] > 2) 1984 return -EINVAL; 1985 if (ucontrol->value.enumerated.item[0] == 0) 1986 val = 0; 1987 else 1988 val = AC97_AD198X_DMIX1 | 1989 ((ucontrol->value.enumerated.item[0] - 1) << 8); 1990 return snd_ac97_update_bits(ac97, AC97_AD_MISC, 1991 AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val); 1992 } 1993 1994 static void ad1888_update_jacks(struct snd_ac97 *ac97) 1995 { 1996 unsigned short val = 0; 1997 /* clear LODIS if shared jack is to be used for Surround out */ 1998 if (!ac97->spec.ad18xx.lo_as_master && is_shared_linein(ac97)) 1999 val |= (1 << 12); 2000 /* clear CLDIS if shared jack is to be used for C/LFE out */ 2001 if (is_shared_micin(ac97)) 2002 val |= (1 << 11); 2003 /* shared Line-In */ 2004 snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val); 2005 } 2006 2007 static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = { 2008 { 2009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2010 .name = "Exchange Front/Surround", 2011 .info = snd_ac97_ad1888_lohpsel_info, 2012 .get = snd_ac97_ad1888_lohpsel_get, 2013 .put = snd_ac97_ad1888_lohpsel_put 2014 }, 2015 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, AC97_AD_VREFD_SHIFT, 1, 1), 2016 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 2017 AC97_AD_HPFD_SHIFT, 1, 1), 2018 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0), 2019 { 2020 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2021 .name = "Downmix", 2022 .info = snd_ac97_ad1888_downmix_info, 2023 .get = snd_ac97_ad1888_downmix_get, 2024 .put = snd_ac97_ad1888_downmix_put 2025 }, 2026 AC97_SURROUND_JACK_MODE_CTL, 2027 AC97_CHANNEL_MODE_CTL, 2028 2029 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0), 2030 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0), 2031 }; 2032 2033 static int patch_ad1888_specific(struct snd_ac97 *ac97) 2034 { 2035 if (!ac97->spec.ad18xx.lo_as_master) { 2036 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */ 2037 snd_ac97_rename_vol_ctl(ac97, "Master Playback", 2038 "Master Surround Playback"); 2039 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", 2040 "Master Playback"); 2041 } 2042 return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls)); 2043 } 2044 2045 static const struct snd_ac97_build_ops patch_ad1888_build_ops = { 2046 .build_post_spdif = patch_ad198x_post_spdif, 2047 .build_specific = patch_ad1888_specific, 2048 #ifdef CONFIG_PM 2049 .resume = ad1888_resume, 2050 #endif 2051 .update_jacks = ad1888_update_jacks, 2052 }; 2053 2054 static int patch_ad1888(struct snd_ac97 * ac97) 2055 { 2056 unsigned short misc; 2057 2058 patch_ad1881(ac97); 2059 ac97->build_ops = &patch_ad1888_build_ops; 2060 2061 /* 2062 * LO can be used as a real line-out on some devices, 2063 * and we need to revert the front/surround mixer switches 2064 */ 2065 if (ac97->subsystem_vendor == 0x1043 && 2066 ac97->subsystem_device == 0x1193) /* ASUS A9T laptop */ 2067 ac97->spec.ad18xx.lo_as_master = 1; 2068 2069 misc = snd_ac97_read(ac97, AC97_AD_MISC); 2070 /* AD-compatible mode */ 2071 /* Stereo mutes enabled */ 2072 misc |= AC97_AD198X_MSPLT | AC97_AD198X_AC97NC; 2073 if (!ac97->spec.ad18xx.lo_as_master) 2074 /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */ 2075 /* it seems that most vendors connect line-out connector to 2076 * headphone out of AC'97 2077 */ 2078 misc |= AC97_AD198X_LOSEL | AC97_AD198X_HPSEL; 2079 2080 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc); 2081 ac97->flags |= AC97_STEREO_MUTES; 2082 return 0; 2083 } 2084 2085 static int patch_ad1980_specific(struct snd_ac97 *ac97) 2086 { 2087 int err; 2088 2089 err = patch_ad1888_specific(ac97); 2090 if (err < 0) 2091 return err; 2092 return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1); 2093 } 2094 2095 static const struct snd_ac97_build_ops patch_ad1980_build_ops = { 2096 .build_post_spdif = patch_ad198x_post_spdif, 2097 .build_specific = patch_ad1980_specific, 2098 #ifdef CONFIG_PM 2099 .resume = ad18xx_resume, 2100 #endif 2101 .update_jacks = ad1888_update_jacks, 2102 }; 2103 2104 static int patch_ad1980(struct snd_ac97 * ac97) 2105 { 2106 patch_ad1888(ac97); 2107 ac97->build_ops = &patch_ad1980_build_ops; 2108 return 0; 2109 } 2110 2111 static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol, 2112 struct snd_ctl_elem_info *uinfo) 2113 { 2114 static const char * const texts[4] = { 2115 "High-Z", "3.7 V", "2.25 V", "0 V" 2116 }; 2117 2118 return snd_ctl_enum_info(uinfo, 1, 4, texts); 2119 } 2120 2121 static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol, 2122 struct snd_ctl_elem_value *ucontrol) 2123 { 2124 static const int reg2ctrl[4] = {2, 0, 1, 3}; 2125 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2126 unsigned short val; 2127 val = (ac97->regs[AC97_AD_MISC] & AC97_AD198X_VREF_MASK) 2128 >> AC97_AD198X_VREF_SHIFT; 2129 ucontrol->value.enumerated.item[0] = reg2ctrl[val]; 2130 return 0; 2131 } 2132 2133 static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol *kcontrol, 2134 struct snd_ctl_elem_value *ucontrol) 2135 { 2136 static const int ctrl2reg[4] = {1, 2, 0, 3}; 2137 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2138 unsigned short val; 2139 2140 if (ucontrol->value.enumerated.item[0] > 3) 2141 return -EINVAL; 2142 val = ctrl2reg[ucontrol->value.enumerated.item[0]] 2143 << AC97_AD198X_VREF_SHIFT; 2144 return snd_ac97_update_bits(ac97, AC97_AD_MISC, 2145 AC97_AD198X_VREF_MASK, val); 2146 } 2147 2148 static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = { 2149 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0), 2150 { 2151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2152 .name = "Exchange Front/Surround", 2153 .info = snd_ac97_ad1888_lohpsel_info, 2154 .get = snd_ac97_ad1888_lohpsel_get, 2155 .put = snd_ac97_ad1888_lohpsel_put 2156 }, 2157 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1), 2158 AC97_SINGLE("Spread Front to Surround and Center/LFE", 2159 AC97_AD_MISC, 7, 1, 0), 2160 { 2161 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2162 .name = "Downmix", 2163 .info = snd_ac97_ad1888_downmix_info, 2164 .get = snd_ac97_ad1888_downmix_get, 2165 .put = snd_ac97_ad1888_downmix_put 2166 }, 2167 { 2168 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2169 .name = "V_REFOUT", 2170 .info = snd_ac97_ad1985_vrefout_info, 2171 .get = snd_ac97_ad1985_vrefout_get, 2172 .put = snd_ac97_ad1985_vrefout_put 2173 }, 2174 AC97_SURROUND_JACK_MODE_CTL, 2175 AC97_CHANNEL_MODE_CTL, 2176 2177 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0), 2178 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0), 2179 }; 2180 2181 static void ad1985_update_jacks(struct snd_ac97 *ac97) 2182 { 2183 ad1888_update_jacks(ac97); 2184 /* clear OMS if shared jack is to be used for C/LFE out */ 2185 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9, 2186 is_shared_micin(ac97) ? 1 << 9 : 0); 2187 } 2188 2189 static int patch_ad1985_specific(struct snd_ac97 *ac97) 2190 { 2191 int err; 2192 2193 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */ 2194 snd_ac97_rename_vol_ctl(ac97, "Master Playback", 2195 "Master Surround Playback"); 2196 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback"); 2197 2198 err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1); 2199 if (err < 0) 2200 return err; 2201 2202 return patch_build_controls(ac97, snd_ac97_ad1985_controls, 2203 ARRAY_SIZE(snd_ac97_ad1985_controls)); 2204 } 2205 2206 static const struct snd_ac97_build_ops patch_ad1985_build_ops = { 2207 .build_post_spdif = patch_ad198x_post_spdif, 2208 .build_specific = patch_ad1985_specific, 2209 #ifdef CONFIG_PM 2210 .resume = ad18xx_resume, 2211 #endif 2212 .update_jacks = ad1985_update_jacks, 2213 }; 2214 2215 static int patch_ad1985(struct snd_ac97 * ac97) 2216 { 2217 unsigned short misc; 2218 2219 patch_ad1881(ac97); 2220 ac97->build_ops = &patch_ad1985_build_ops; 2221 misc = snd_ac97_read(ac97, AC97_AD_MISC); 2222 /* switch front/surround line-out/hp-out */ 2223 /* AD-compatible mode */ 2224 /* Stereo mutes enabled */ 2225 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc | 2226 AC97_AD198X_LOSEL | 2227 AC97_AD198X_HPSEL | 2228 AC97_AD198X_MSPLT | 2229 AC97_AD198X_AC97NC); 2230 ac97->flags |= AC97_STEREO_MUTES; 2231 2232 /* update current jack configuration */ 2233 ad1985_update_jacks(ac97); 2234 2235 /* on AD1985 rev. 3, AC'97 revision bits are zero */ 2236 ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23; 2237 return 0; 2238 } 2239 2240 #define snd_ac97_ad1986_bool_info snd_ctl_boolean_mono_info 2241 2242 static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol, 2243 struct snd_ctl_elem_value *ucontrol) 2244 { 2245 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2246 unsigned short val; 2247 2248 val = ac97->regs[AC97_AD_MISC3]; 2249 ucontrol->value.integer.value[0] = (val & AC97_AD1986_LOSEL) != 0; 2250 return 0; 2251 } 2252 2253 static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol *kcontrol, 2254 struct snd_ctl_elem_value *ucontrol) 2255 { 2256 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2257 int ret0; 2258 int ret1; 2259 int sprd = (ac97->regs[AC97_AD_MISC] & AC97_AD1986_SPRD) != 0; 2260 2261 ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC3, AC97_AD1986_LOSEL, 2262 ucontrol->value.integer.value[0] != 0 2263 ? AC97_AD1986_LOSEL : 0); 2264 if (ret0 < 0) 2265 return ret0; 2266 2267 /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */ 2268 ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL, 2269 (ucontrol->value.integer.value[0] != 0 2270 || sprd) 2271 ? AC97_AD1986_SOSEL : 0); 2272 if (ret1 < 0) 2273 return ret1; 2274 2275 return (ret0 > 0 || ret1 > 0) ? 1 : 0; 2276 } 2277 2278 static int snd_ac97_ad1986_spread_get(struct snd_kcontrol *kcontrol, 2279 struct snd_ctl_elem_value *ucontrol) 2280 { 2281 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2282 unsigned short val; 2283 2284 val = ac97->regs[AC97_AD_MISC]; 2285 ucontrol->value.integer.value[0] = (val & AC97_AD1986_SPRD) != 0; 2286 return 0; 2287 } 2288 2289 static int snd_ac97_ad1986_spread_put(struct snd_kcontrol *kcontrol, 2290 struct snd_ctl_elem_value *ucontrol) 2291 { 2292 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2293 int ret0; 2294 int ret1; 2295 int sprd = (ac97->regs[AC97_AD_MISC3] & AC97_AD1986_LOSEL) != 0; 2296 2297 ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SPRD, 2298 ucontrol->value.integer.value[0] != 0 2299 ? AC97_AD1986_SPRD : 0); 2300 if (ret0 < 0) 2301 return ret0; 2302 2303 /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */ 2304 ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL, 2305 (ucontrol->value.integer.value[0] != 0 2306 || sprd) 2307 ? AC97_AD1986_SOSEL : 0); 2308 if (ret1 < 0) 2309 return ret1; 2310 2311 return (ret0 > 0 || ret1 > 0) ? 1 : 0; 2312 } 2313 2314 static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol *kcontrol, 2315 struct snd_ctl_elem_value *ucontrol) 2316 { 2317 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2318 2319 ucontrol->value.integer.value[0] = ac97->spec.ad18xx.swap_mic_linein; 2320 return 0; 2321 } 2322 2323 static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol *kcontrol, 2324 struct snd_ctl_elem_value *ucontrol) 2325 { 2326 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2327 unsigned char swap = ucontrol->value.integer.value[0] != 0; 2328 2329 if (swap != ac97->spec.ad18xx.swap_mic_linein) { 2330 ac97->spec.ad18xx.swap_mic_linein = swap; 2331 if (ac97->build_ops->update_jacks) 2332 ac97->build_ops->update_jacks(ac97); 2333 return 1; 2334 } 2335 return 0; 2336 } 2337 2338 static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol *kcontrol, 2339 struct snd_ctl_elem_value *ucontrol) 2340 { 2341 /* Use MIC_1/2 V_REFOUT as the "get" value */ 2342 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2343 unsigned short val; 2344 unsigned short reg = ac97->regs[AC97_AD_MISC2]; 2345 if ((reg & AC97_AD1986_MVREF0) != 0) 2346 val = 2; 2347 else if ((reg & AC97_AD1986_MVREF1) != 0) 2348 val = 3; 2349 else if ((reg & AC97_AD1986_MVREF2) != 0) 2350 val = 1; 2351 else 2352 val = 0; 2353 ucontrol->value.enumerated.item[0] = val; 2354 return 0; 2355 } 2356 2357 static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol *kcontrol, 2358 struct snd_ctl_elem_value *ucontrol) 2359 { 2360 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2361 unsigned short cval; 2362 unsigned short lval; 2363 unsigned short mval; 2364 int cret; 2365 int lret; 2366 int mret; 2367 2368 switch (ucontrol->value.enumerated.item[0]) 2369 { 2370 case 0: /* High-Z */ 2371 cval = 0; 2372 lval = 0; 2373 mval = 0; 2374 break; 2375 case 1: /* 3.7 V */ 2376 cval = AC97_AD1986_CVREF2; 2377 lval = AC97_AD1986_LVREF2; 2378 mval = AC97_AD1986_MVREF2; 2379 break; 2380 case 2: /* 2.25 V */ 2381 cval = AC97_AD1986_CVREF0; 2382 lval = AC97_AD1986_LVREF0; 2383 mval = AC97_AD1986_MVREF0; 2384 break; 2385 case 3: /* 0 V */ 2386 cval = AC97_AD1986_CVREF1; 2387 lval = AC97_AD1986_LVREF1; 2388 mval = AC97_AD1986_MVREF1; 2389 break; 2390 default: 2391 return -EINVAL; 2392 } 2393 2394 cret = snd_ac97_update_bits(ac97, AC97_AD_MISC2, 2395 AC97_AD1986_CVREF_MASK, cval); 2396 if (cret < 0) 2397 return cret; 2398 lret = snd_ac97_update_bits(ac97, AC97_AD_MISC3, 2399 AC97_AD1986_LVREF_MASK, lval); 2400 if (lret < 0) 2401 return lret; 2402 mret = snd_ac97_update_bits(ac97, AC97_AD_MISC2, 2403 AC97_AD1986_MVREF_MASK, mval); 2404 if (mret < 0) 2405 return mret; 2406 2407 return (cret > 0 || lret > 0 || mret > 0) ? 1 : 0; 2408 } 2409 2410 static const struct snd_kcontrol_new snd_ac97_ad1986_controls[] = { 2411 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0), 2412 { 2413 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2414 .name = "Exchange Front/Surround", 2415 .info = snd_ac97_ad1986_bool_info, 2416 .get = snd_ac97_ad1986_lososel_get, 2417 .put = snd_ac97_ad1986_lososel_put 2418 }, 2419 { 2420 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2421 .name = "Exchange Mic/Line In", 2422 .info = snd_ac97_ad1986_bool_info, 2423 .get = snd_ac97_ad1986_miclisel_get, 2424 .put = snd_ac97_ad1986_miclisel_put 2425 }, 2426 { 2427 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2428 .name = "Spread Front to Surround and Center/LFE", 2429 .info = snd_ac97_ad1986_bool_info, 2430 .get = snd_ac97_ad1986_spread_get, 2431 .put = snd_ac97_ad1986_spread_put 2432 }, 2433 { 2434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2435 .name = "Downmix", 2436 .info = snd_ac97_ad1888_downmix_info, 2437 .get = snd_ac97_ad1888_downmix_get, 2438 .put = snd_ac97_ad1888_downmix_put 2439 }, 2440 { 2441 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2442 .name = "V_REFOUT", 2443 .info = snd_ac97_ad1985_vrefout_info, 2444 .get = snd_ac97_ad1986_vrefout_get, 2445 .put = snd_ac97_ad1986_vrefout_put 2446 }, 2447 AC97_SURROUND_JACK_MODE_CTL, 2448 AC97_CHANNEL_MODE_CTL, 2449 2450 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0), 2451 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0) 2452 }; 2453 2454 static void ad1986_update_jacks(struct snd_ac97 *ac97) 2455 { 2456 unsigned short misc_val = 0; 2457 unsigned short ser_val; 2458 2459 /* disable SURROUND and CENTER/LFE if not surround mode */ 2460 if (!is_surround_on(ac97)) 2461 misc_val |= AC97_AD1986_SODIS; 2462 if (!is_clfe_on(ac97)) 2463 misc_val |= AC97_AD1986_CLDIS; 2464 2465 /* select line input (default=LINE_IN, SURROUND or MIC_1/2) */ 2466 if (is_shared_linein(ac97)) 2467 misc_val |= AC97_AD1986_LISEL_SURR; 2468 else if (ac97->spec.ad18xx.swap_mic_linein != 0) 2469 misc_val |= AC97_AD1986_LISEL_MIC; 2470 snd_ac97_update_bits(ac97, AC97_AD_MISC, 2471 AC97_AD1986_SODIS | AC97_AD1986_CLDIS | 2472 AC97_AD1986_LISEL_MASK, 2473 misc_val); 2474 2475 /* select microphone input (MIC_1/2, Center/LFE or LINE_IN) */ 2476 if (is_shared_micin(ac97)) 2477 ser_val = AC97_AD1986_OMS_C; 2478 else if (ac97->spec.ad18xx.swap_mic_linein != 0) 2479 ser_val = AC97_AD1986_OMS_L; 2480 else 2481 ser_val = AC97_AD1986_OMS_M; 2482 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 2483 AC97_AD1986_OMS_MASK, 2484 ser_val); 2485 } 2486 2487 static int patch_ad1986_specific(struct snd_ac97 *ac97) 2488 { 2489 int err; 2490 2491 err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1); 2492 if (err < 0) 2493 return err; 2494 2495 return patch_build_controls(ac97, snd_ac97_ad1986_controls, 2496 ARRAY_SIZE(snd_ac97_ad1985_controls)); 2497 } 2498 2499 static const struct snd_ac97_build_ops patch_ad1986_build_ops = { 2500 .build_post_spdif = patch_ad198x_post_spdif, 2501 .build_specific = patch_ad1986_specific, 2502 #ifdef CONFIG_PM 2503 .resume = ad18xx_resume, 2504 #endif 2505 .update_jacks = ad1986_update_jacks, 2506 }; 2507 2508 static int patch_ad1986(struct snd_ac97 * ac97) 2509 { 2510 patch_ad1881(ac97); 2511 ac97->build_ops = &patch_ad1986_build_ops; 2512 ac97->flags |= AC97_STEREO_MUTES; 2513 2514 /* update current jack configuration */ 2515 ad1986_update_jacks(ac97); 2516 2517 return 0; 2518 } 2519 2520 /* 2521 * realtek ALC203: use mono-out for pin 37 2522 */ 2523 static int patch_alc203(struct snd_ac97 *ac97) 2524 { 2525 snd_ac97_update_bits(ac97, 0x7a, 0x400, 0x400); 2526 return 0; 2527 } 2528 2529 /* 2530 * realtek ALC65x/850 codecs 2531 */ 2532 static void alc650_update_jacks(struct snd_ac97 *ac97) 2533 { 2534 int shared; 2535 2536 /* shared Line-In / Surround Out */ 2537 shared = is_shared_surrout(ac97); 2538 snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9, 2539 shared ? (1 << 9) : 0); 2540 /* update shared Mic In / Center/LFE Out */ 2541 shared = is_shared_clfeout(ac97); 2542 /* disable/enable vref */ 2543 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, 2544 shared ? (1 << 12) : 0); 2545 /* turn on/off center-on-mic */ 2546 snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10, 2547 shared ? (1 << 10) : 0); 2548 /* GPIO0 high for mic */ 2549 snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100, 2550 shared ? 0 : 0x100); 2551 } 2552 2553 static int alc650_swap_surround_put(struct snd_kcontrol *kcontrol, 2554 struct snd_ctl_elem_value *ucontrol) 2555 { 2556 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2557 struct snd_pcm_chmap *map = ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK]; 2558 2559 if (map) { 2560 if (ucontrol->value.integer.value[0]) 2561 map->chmap = snd_pcm_std_chmaps; 2562 else 2563 map->chmap = snd_pcm_alt_chmaps; 2564 } 2565 return snd_ac97_put_volsw(kcontrol, ucontrol); 2566 } 2567 2568 static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = { 2569 AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0), 2570 AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0), 2571 AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH, 2, 1, 0), 2572 AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH, 3, 1, 0), 2573 /* 4: Analog Input To Surround */ 2574 /* 5: Analog Input To Center/LFE */ 2575 /* 6: Independent Master Volume Right */ 2576 /* 7: Independent Master Volume Left */ 2577 /* 8: reserved */ 2578 /* 9: Line-In/Surround share */ 2579 /* 10: Mic/CLFE share */ 2580 /* 11-13: in IEC958 controls */ 2581 { 2582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2583 .name = "Swap Surround Slot", 2584 .info = snd_ac97_info_volsw, 2585 .get = snd_ac97_get_volsw, 2586 .put = alc650_swap_surround_put, 2587 .private_value = AC97_SINGLE_VALUE(AC97_ALC650_MULTICH, 14, 1, 0), 2588 }, 2589 #if 0 /* always set in patch_alc650 */ 2590 AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0), 2591 AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0), 2592 AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL, 15, 1, 1), 2593 AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL, 8, 0, 31, 1), 2594 AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL, 15, 1, 1), 2595 AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL, 8, 0, 31, 1), 2596 #endif 2597 AC97_SURROUND_JACK_MODE_CTL, 2598 AC97_CHANNEL_MODE_CTL, 2599 }; 2600 2601 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc650[] = { 2602 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0), 2603 AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0), 2604 /* disable this controls since it doesn't work as expected */ 2605 /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */ 2606 }; 2607 2608 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0); 2609 2610 static int patch_alc650_specific(struct snd_ac97 * ac97) 2611 { 2612 int err; 2613 2614 err = patch_build_controls(ac97, snd_ac97_controls_alc650, ARRAY_SIZE(snd_ac97_controls_alc650)); 2615 if (err < 0) 2616 return err; 2617 if (ac97->ext_id & AC97_EI_SPDIF) { 2618 err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc650, ARRAY_SIZE(snd_ac97_spdif_controls_alc650)); 2619 if (err < 0) 2620 return err; 2621 } 2622 if (ac97->id != AC97_ID_ALC650F) 2623 reset_tlv(ac97, "Master Playback Volume", 2624 db_scale_5bit_3db_max); 2625 return 0; 2626 } 2627 2628 static const struct snd_ac97_build_ops patch_alc650_ops = { 2629 .build_specific = patch_alc650_specific, 2630 .update_jacks = alc650_update_jacks 2631 }; 2632 2633 static int patch_alc650(struct snd_ac97 * ac97) 2634 { 2635 unsigned short val; 2636 2637 ac97->build_ops = &patch_alc650_ops; 2638 2639 /* determine the revision */ 2640 val = snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f; 2641 if (val < 3) 2642 ac97->id = 0x414c4720; /* Old version */ 2643 else if (val < 0x10) 2644 ac97->id = 0x414c4721; /* D version */ 2645 else if (val < 0x20) 2646 ac97->id = 0x414c4722; /* E version */ 2647 else if (val < 0x30) 2648 ac97->id = 0x414c4723; /* F version */ 2649 2650 /* revision E or F */ 2651 /* FIXME: what about revision D ? */ 2652 ac97->spec.dev_flags = (ac97->id == 0x414c4722 || 2653 ac97->id == 0x414c4723); 2654 2655 /* enable AC97_ALC650_GPIO_SETUP, AC97_ALC650_CLOCK for R/W */ 2656 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS, 2657 snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x8000); 2658 2659 /* Enable SPDIF-IN only on Rev.E and above */ 2660 val = snd_ac97_read(ac97, AC97_ALC650_CLOCK); 2661 /* SPDIF IN with pin 47 */ 2662 if (ac97->spec.dev_flags && 2663 /* ASUS A6KM requires EAPD */ 2664 ! (ac97->subsystem_vendor == 0x1043 && 2665 ac97->subsystem_device == 0x1103)) 2666 val |= 0x03; /* enable */ 2667 else 2668 val &= ~0x03; /* disable */ 2669 snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK, val); 2670 2671 /* set default: slot 3,4,7,8,6,9 2672 spdif-in monitor off, analog-spdif off, spdif-in off 2673 center on mic off, surround on line-in off 2674 downmix off, duplicate front off 2675 */ 2676 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 0); 2677 2678 /* set GPIO0 for mic bias */ 2679 /* GPIO0 pin output, no interrupt, high */ 2680 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_SETUP, 2681 snd_ac97_read(ac97, AC97_ALC650_GPIO_SETUP) | 0x01); 2682 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS, 2683 (snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x100) & ~0x10); 2684 2685 /* full DAC volume */ 2686 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808); 2687 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808); 2688 return 0; 2689 } 2690 2691 static void alc655_update_jacks(struct snd_ac97 *ac97) 2692 { 2693 int shared; 2694 2695 /* shared Line-In / Surround Out */ 2696 shared = is_shared_surrout(ac97); 2697 ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 9, 2698 shared ? (1 << 9) : 0, 0); 2699 /* update shared Mic In / Center/LFE Out */ 2700 shared = is_shared_clfeout(ac97); 2701 /* misc control; vrefout disable */ 2702 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, 2703 shared ? (1 << 12) : 0); 2704 ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10, 2705 shared ? (1 << 10) : 0, 0); 2706 } 2707 2708 static const struct snd_kcontrol_new snd_ac97_controls_alc655[] = { 2709 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0), 2710 AC97_SURROUND_JACK_MODE_CTL, 2711 AC97_CHANNEL_MODE_CTL, 2712 }; 2713 2714 static int alc655_iec958_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 2715 { 2716 static const char * const texts_655[3] = { 2717 "PCM", "Analog In", "IEC958 In" 2718 }; 2719 static const char * const texts_658[4] = { 2720 "PCM", "Analog1 In", "Analog2 In", "IEC958 In" 2721 }; 2722 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2723 2724 if (ac97->spec.dev_flags) 2725 return snd_ctl_enum_info(uinfo, 1, 4, texts_658); 2726 else 2727 return snd_ctl_enum_info(uinfo, 1, 3, texts_655); 2728 } 2729 2730 static int alc655_iec958_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 2731 { 2732 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2733 unsigned short val; 2734 2735 val = ac97->regs[AC97_ALC650_MULTICH]; 2736 val = (val >> 12) & 3; 2737 if (ac97->spec.dev_flags && val == 3) 2738 val = 0; 2739 ucontrol->value.enumerated.item[0] = val; 2740 return 0; 2741 } 2742 2743 static int alc655_iec958_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 2744 { 2745 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 2746 2747 return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 3 << 12, 2748 (unsigned short)ucontrol->value.enumerated.item[0] << 12, 2749 0); 2750 } 2751 2752 static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc655[] = { 2753 AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0, 0), 2754 /* disable this controls since it doesn't work as expected */ 2755 /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */ 2756 { 2757 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2758 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 2759 .info = alc655_iec958_route_info, 2760 .get = alc655_iec958_route_get, 2761 .put = alc655_iec958_route_put, 2762 }, 2763 }; 2764 2765 static int patch_alc655_specific(struct snd_ac97 * ac97) 2766 { 2767 int err; 2768 2769 err = patch_build_controls(ac97, snd_ac97_controls_alc655, ARRAY_SIZE(snd_ac97_controls_alc655)); 2770 if (err < 0) 2771 return err; 2772 if (ac97->ext_id & AC97_EI_SPDIF) { 2773 err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655)); 2774 if (err < 0) 2775 return err; 2776 } 2777 return 0; 2778 } 2779 2780 static const struct snd_ac97_build_ops patch_alc655_ops = { 2781 .build_specific = patch_alc655_specific, 2782 .update_jacks = alc655_update_jacks 2783 }; 2784 2785 static int patch_alc655(struct snd_ac97 * ac97) 2786 { 2787 unsigned int val; 2788 2789 if (ac97->id == AC97_ID_ALC658) { 2790 ac97->spec.dev_flags = 1; /* ALC658 */ 2791 if ((snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f) == 2) { 2792 ac97->id = AC97_ID_ALC658D; 2793 ac97->spec.dev_flags = 2; 2794 } 2795 } 2796 2797 ac97->build_ops = &patch_alc655_ops; 2798 2799 /* assume only page 0 for writing cache */ 2800 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR); 2801 2802 /* adjust default values */ 2803 val = snd_ac97_read(ac97, 0x7a); /* misc control */ 2804 if (ac97->spec.dev_flags) /* ALC658 */ 2805 val &= ~(1 << 1); /* Pin 47 is spdif input pin */ 2806 else { /* ALC655 */ 2807 if (ac97->subsystem_vendor == 0x1462 && 2808 (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */ 2809 ac97->subsystem_device == 0x0161 || /* LG K1 Express */ 2810 ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */ 2811 ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */ 2812 ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */ 2813 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ 2814 else 2815 val |= (1 << 1); /* Pin 47 is spdif input pin */ 2816 /* this seems missing on some hardwares */ 2817 ac97->ext_id |= AC97_EI_SPDIF; 2818 } 2819 val &= ~(1 << 12); /* vref enable */ 2820 snd_ac97_write_cache(ac97, 0x7a, val); 2821 /* set default: spdif-in enabled, 2822 spdif-in monitor off, spdif-in PCM off 2823 center on mic off, surround on line-in off 2824 duplicate front off 2825 */ 2826 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15); 2827 2828 /* full DAC volume */ 2829 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808); 2830 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808); 2831 2832 /* update undocumented bit... */ 2833 if (ac97->id == AC97_ID_ALC658D) 2834 snd_ac97_update_bits(ac97, 0x74, 0x0800, 0x0800); 2835 2836 return 0; 2837 } 2838 2839 2840 #define AC97_ALC850_JACK_SELECT 0x76 2841 #define AC97_ALC850_MISC1 0x7a 2842 #define AC97_ALC850_MULTICH 0x6a 2843 2844 static void alc850_update_jacks(struct snd_ac97 *ac97) 2845 { 2846 int shared; 2847 int aux_is_back_surround; 2848 2849 /* shared Line-In / Surround Out */ 2850 shared = is_shared_surrout(ac97); 2851 /* SURR 1kOhm (bit4), Amp (bit5) */ 2852 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5), 2853 shared ? (1<<5) : (1<<4)); 2854 /* LINE-IN = 0, SURROUND = 2 */ 2855 snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12, 2856 shared ? (2<<12) : (0<<12)); 2857 /* update shared Mic In / Center/LFE Out */ 2858 shared = is_shared_clfeout(ac97); 2859 /* Vref disable (bit12), 1kOhm (bit13) */ 2860 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13), 2861 shared ? (1<<12) : (1<<13)); 2862 /* MIC-IN = 1, CENTER-LFE = 5 */ 2863 snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4, 2864 shared ? (5<<4) : (1<<4)); 2865 2866 aux_is_back_surround = alc850_is_aux_back_surround(ac97); 2867 /* Aux is Back Surround */ 2868 snd_ac97_update_bits(ac97, AC97_ALC850_MULTICH, 1 << 10, 2869 aux_is_back_surround ? (1<<10) : (0<<10)); 2870 } 2871 2872 static const struct snd_kcontrol_new snd_ac97_controls_alc850[] = { 2873 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0), 2874 AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT, 15, 1, 1), 2875 AC97_SURROUND_JACK_MODE_CTL, 2876 AC97_CHANNEL_MODE_8CH_CTL, 2877 }; 2878 2879 static int patch_alc850_specific(struct snd_ac97 *ac97) 2880 { 2881 int err; 2882 2883 err = patch_build_controls(ac97, snd_ac97_controls_alc850, ARRAY_SIZE(snd_ac97_controls_alc850)); 2884 if (err < 0) 2885 return err; 2886 if (ac97->ext_id & AC97_EI_SPDIF) { 2887 err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655)); 2888 if (err < 0) 2889 return err; 2890 } 2891 return 0; 2892 } 2893 2894 static const struct snd_ac97_build_ops patch_alc850_ops = { 2895 .build_specific = patch_alc850_specific, 2896 .update_jacks = alc850_update_jacks 2897 }; 2898 2899 static int patch_alc850(struct snd_ac97 *ac97) 2900 { 2901 ac97->build_ops = &patch_alc850_ops; 2902 2903 ac97->spec.dev_flags = 0; /* for IEC958 playback route - ALC655 compatible */ 2904 ac97->flags |= AC97_HAS_8CH; 2905 2906 /* assume only page 0 for writing cache */ 2907 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR); 2908 2909 /* adjust default values */ 2910 /* set default: spdif-in enabled, 2911 spdif-in monitor off, spdif-in PCM off 2912 center on mic off, surround on line-in off 2913 duplicate front off 2914 NB default bit 10=0 = Aux is Capture, not Back Surround 2915 */ 2916 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15); 2917 /* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off 2918 * Front Amp: on, Vref: enable, Center 1kOhm: on, Mix: on 2919 */ 2920 snd_ac97_write_cache(ac97, 0x7a, (1<<1)|(1<<4)|(0<<5)|(1<<6)| 2921 (1<<7)|(0<<12)|(1<<13)|(0<<14)); 2922 /* detection UIO2,3: all path floating, UIO3: MIC, Vref2: disable, 2923 * UIO1: FRONT, Vref3: disable, UIO3: LINE, Front-Mic: mute 2924 */ 2925 snd_ac97_write_cache(ac97, 0x76, (0<<0)|(0<<2)|(1<<4)|(1<<7)|(2<<8)| 2926 (1<<11)|(0<<12)|(1<<15)); 2927 2928 /* full DAC volume */ 2929 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808); 2930 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808); 2931 return 0; 2932 } 2933 2934 static int patch_aztech_azf3328_specific(struct snd_ac97 *ac97) 2935 { 2936 struct snd_kcontrol *kctl_3d_center = 2937 snd_ac97_find_mixer_ctl(ac97, "3D Control - Center"); 2938 struct snd_kcontrol *kctl_3d_depth = 2939 snd_ac97_find_mixer_ctl(ac97, "3D Control - Depth"); 2940 2941 /* 2942 * 3D register is different from AC97 standard layout 2943 * (also do some renaming, to resemble Windows driver naming) 2944 */ 2945 if (kctl_3d_center) { 2946 kctl_3d_center->private_value = 2947 AC97_SINGLE_VALUE(AC97_3D_CONTROL, 1, 0x07, 0); 2948 snd_ac97_rename_vol_ctl(ac97, 2949 "3D Control - Center", "3D Control - Width" 2950 ); 2951 } 2952 if (kctl_3d_depth) 2953 kctl_3d_depth->private_value = 2954 AC97_SINGLE_VALUE(AC97_3D_CONTROL, 8, 0x03, 0); 2955 2956 /* Aztech Windows driver calls the 2957 equivalent control "Modem Playback", thus rename it: */ 2958 snd_ac97_rename_vol_ctl(ac97, 2959 "Master Mono Playback", "Modem Playback" 2960 ); 2961 snd_ac97_rename_vol_ctl(ac97, 2962 "Headphone Playback", "FM Synth Playback" 2963 ); 2964 2965 return 0; 2966 } 2967 2968 static const struct snd_ac97_build_ops patch_aztech_azf3328_ops = { 2969 .build_specific = patch_aztech_azf3328_specific 2970 }; 2971 2972 static int patch_aztech_azf3328(struct snd_ac97 *ac97) 2973 { 2974 ac97->build_ops = &patch_aztech_azf3328_ops; 2975 return 0; 2976 } 2977 2978 /* 2979 * C-Media CM97xx codecs 2980 */ 2981 static void cm9738_update_jacks(struct snd_ac97 *ac97) 2982 { 2983 /* shared Line-In / Surround Out */ 2984 snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10, 2985 is_shared_surrout(ac97) ? (1 << 10) : 0); 2986 } 2987 2988 static const struct snd_kcontrol_new snd_ac97_cm9738_controls[] = { 2989 AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL, 13, 1, 0), 2990 AC97_SURROUND_JACK_MODE_CTL, 2991 AC97_CHANNEL_MODE_4CH_CTL, 2992 }; 2993 2994 static int patch_cm9738_specific(struct snd_ac97 * ac97) 2995 { 2996 return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls)); 2997 } 2998 2999 static const struct snd_ac97_build_ops patch_cm9738_ops = { 3000 .build_specific = patch_cm9738_specific, 3001 .update_jacks = cm9738_update_jacks 3002 }; 3003 3004 static int patch_cm9738(struct snd_ac97 * ac97) 3005 { 3006 ac97->build_ops = &patch_cm9738_ops; 3007 /* FIXME: can anyone confirm below? */ 3008 /* CM9738 has no PCM volume although the register reacts */ 3009 ac97->flags |= AC97_HAS_NO_PCM_VOL; 3010 snd_ac97_write_cache(ac97, AC97_PCM, 0x8000); 3011 3012 return 0; 3013 } 3014 3015 static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 3016 { 3017 static const char * const texts[] = { "Analog", "Digital" }; 3018 3019 return snd_ctl_enum_info(uinfo, 1, 2, texts); 3020 } 3021 3022 static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3023 { 3024 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 3025 unsigned short val; 3026 3027 val = ac97->regs[AC97_CM9739_SPDIF_CTRL]; 3028 ucontrol->value.enumerated.item[0] = (val >> 1) & 0x01; 3029 return 0; 3030 } 3031 3032 static int snd_ac97_cmedia_spdif_playback_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3033 { 3034 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 3035 3036 return snd_ac97_update_bits(ac97, AC97_CM9739_SPDIF_CTRL, 3037 0x01 << 1, 3038 (ucontrol->value.enumerated.item[0] & 0x01) << 1); 3039 } 3040 3041 static const struct snd_kcontrol_new snd_ac97_cm9739_controls_spdif[] = { 3042 /* BIT 0: SPDI_EN - always true */ 3043 { /* BIT 1: SPDIFS */ 3044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3045 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 3046 .info = snd_ac97_cmedia_spdif_playback_source_info, 3047 .get = snd_ac97_cmedia_spdif_playback_source_get, 3048 .put = snd_ac97_cmedia_spdif_playback_source_put, 3049 }, 3050 /* BIT 2: IG_SPIV */ 3051 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9739_SPDIF_CTRL, 2, 1, 0), 3052 /* BIT 3: SPI2F */ 3053 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9739_SPDIF_CTRL, 3, 1, 0), 3054 /* BIT 4: SPI2SDI */ 3055 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9739_SPDIF_CTRL, 4, 1, 0), 3056 /* BIT 8: SPD32 - 32bit SPDIF - not supported yet */ 3057 }; 3058 3059 static void cm9739_update_jacks(struct snd_ac97 *ac97) 3060 { 3061 /* shared Line-In / Surround Out */ 3062 snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10, 3063 is_shared_surrout(ac97) ? (1 << 10) : 0); 3064 /* shared Mic In / Center/LFE Out **/ 3065 snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000, 3066 is_shared_clfeout(ac97) ? 0x1000 : 0x2000); 3067 } 3068 3069 static const struct snd_kcontrol_new snd_ac97_cm9739_controls[] = { 3070 AC97_SURROUND_JACK_MODE_CTL, 3071 AC97_CHANNEL_MODE_CTL, 3072 }; 3073 3074 static int patch_cm9739_specific(struct snd_ac97 * ac97) 3075 { 3076 return patch_build_controls(ac97, snd_ac97_cm9739_controls, ARRAY_SIZE(snd_ac97_cm9739_controls)); 3077 } 3078 3079 static int patch_cm9739_post_spdif(struct snd_ac97 * ac97) 3080 { 3081 return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif)); 3082 } 3083 3084 static const struct snd_ac97_build_ops patch_cm9739_ops = { 3085 .build_specific = patch_cm9739_specific, 3086 .build_post_spdif = patch_cm9739_post_spdif, 3087 .update_jacks = cm9739_update_jacks 3088 }; 3089 3090 static int patch_cm9739(struct snd_ac97 * ac97) 3091 { 3092 unsigned short val; 3093 3094 ac97->build_ops = &patch_cm9739_ops; 3095 3096 /* CM9739/A has no Master and PCM volume although the register reacts */ 3097 ac97->flags |= AC97_HAS_NO_MASTER_VOL | AC97_HAS_NO_PCM_VOL; 3098 snd_ac97_write_cache(ac97, AC97_MASTER, 0x8000); 3099 snd_ac97_write_cache(ac97, AC97_PCM, 0x8000); 3100 3101 /* check spdif */ 3102 val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS); 3103 if (val & AC97_EA_SPCV) { 3104 /* enable spdif in */ 3105 snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL, 3106 snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) | 0x01); 3107 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ 3108 } else { 3109 ac97->ext_id &= ~AC97_EI_SPDIF; /* disable extended-id */ 3110 ac97->rates[AC97_RATES_SPDIF] = 0; 3111 } 3112 3113 /* set-up multi channel */ 3114 /* bit 14: 0 = SPDIF, 1 = EAPD */ 3115 /* bit 13: enable internal vref output for mic */ 3116 /* bit 12: disable center/lfe (switchable) */ 3117 /* bit 10: disable surround/line (switchable) */ 3118 /* bit 9: mix 2 surround off */ 3119 /* bit 4: undocumented; 0 mutes the CM9739A, which defaults to 1 */ 3120 /* bit 3: undocumented; surround? */ 3121 /* bit 0: dB */ 3122 val = snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) & (1 << 4); 3123 val |= (1 << 3); 3124 val |= (1 << 13); 3125 if (! (ac97->ext_id & AC97_EI_SPDIF)) 3126 val |= (1 << 14); 3127 snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN, val); 3128 3129 /* FIXME: set up GPIO */ 3130 snd_ac97_write_cache(ac97, 0x70, 0x0100); 3131 snd_ac97_write_cache(ac97, 0x72, 0x0020); 3132 /* Special exception for ASUS W1000/CMI9739. It does not have an SPDIF in. */ 3133 if (ac97->pci && 3134 ac97->subsystem_vendor == 0x1043 && 3135 ac97->subsystem_device == 0x1843) { 3136 snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL, 3137 snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) & ~0x01); 3138 snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN, 3139 snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) | (1 << 14)); 3140 } 3141 3142 return 0; 3143 } 3144 3145 #define AC97_CM9761_MULTI_CHAN 0x64 3146 #define AC97_CM9761_FUNC 0x66 3147 #define AC97_CM9761_SPDIF_CTRL 0x6c 3148 3149 static void cm9761_update_jacks(struct snd_ac97 *ac97) 3150 { 3151 /* FIXME: check the bits for each model 3152 * model 83 is confirmed to work 3153 */ 3154 static const unsigned short surr_on[3][2] = { 3155 { 0x0008, 0x0000 }, /* 9761-78 & 82 */ 3156 { 0x0000, 0x0008 }, /* 9761-82 rev.B */ 3157 { 0x0000, 0x0008 }, /* 9761-83 */ 3158 }; 3159 static const unsigned short clfe_on[3][2] = { 3160 { 0x0000, 0x1000 }, /* 9761-78 & 82 */ 3161 { 0x1000, 0x0000 }, /* 9761-82 rev.B */ 3162 { 0x0000, 0x1000 }, /* 9761-83 */ 3163 }; 3164 static const unsigned short surr_shared[3][2] = { 3165 { 0x0000, 0x0400 }, /* 9761-78 & 82 */ 3166 { 0x0000, 0x0400 }, /* 9761-82 rev.B */ 3167 { 0x0000, 0x0400 }, /* 9761-83 */ 3168 }; 3169 static const unsigned short clfe_shared[3][2] = { 3170 { 0x2000, 0x0880 }, /* 9761-78 & 82 */ 3171 { 0x0000, 0x2880 }, /* 9761-82 rev.B */ 3172 { 0x2000, 0x0800 }, /* 9761-83 */ 3173 }; 3174 unsigned short val = 0; 3175 3176 val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)]; 3177 val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)]; 3178 val |= surr_shared[ac97->spec.dev_flags][is_shared_surrout(ac97)]; 3179 val |= clfe_shared[ac97->spec.dev_flags][is_shared_clfeout(ac97)]; 3180 3181 snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val); 3182 } 3183 3184 static const struct snd_kcontrol_new snd_ac97_cm9761_controls[] = { 3185 AC97_SURROUND_JACK_MODE_CTL, 3186 AC97_CHANNEL_MODE_CTL, 3187 }; 3188 3189 static int cm9761_spdif_out_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 3190 { 3191 static const char * const texts[] = { "AC-Link", "ADC", "SPDIF-In" }; 3192 3193 return snd_ctl_enum_info(uinfo, 1, 3, texts); 3194 } 3195 3196 static int cm9761_spdif_out_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3197 { 3198 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 3199 3200 if (ac97->regs[AC97_CM9761_FUNC] & 0x1) 3201 ucontrol->value.enumerated.item[0] = 2; /* SPDIF-loopback */ 3202 else if (ac97->regs[AC97_CM9761_SPDIF_CTRL] & 0x2) 3203 ucontrol->value.enumerated.item[0] = 1; /* ADC loopback */ 3204 else 3205 ucontrol->value.enumerated.item[0] = 0; /* AC-link */ 3206 return 0; 3207 } 3208 3209 static int cm9761_spdif_out_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 3210 { 3211 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 3212 3213 if (ucontrol->value.enumerated.item[0] == 2) 3214 return snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0x1); 3215 snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0); 3216 return snd_ac97_update_bits(ac97, AC97_CM9761_SPDIF_CTRL, 0x2, 3217 ucontrol->value.enumerated.item[0] == 1 ? 0x2 : 0); 3218 } 3219 3220 static const char * const cm9761_dac_clock[] = { 3221 "AC-Link", "SPDIF-In", "Both" 3222 }; 3223 static const struct ac97_enum cm9761_dac_clock_enum = 3224 AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock); 3225 3226 static const struct snd_kcontrol_new snd_ac97_cm9761_controls_spdif[] = { 3227 { /* BIT 1: SPDIFS */ 3228 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3229 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 3230 .info = cm9761_spdif_out_source_info, 3231 .get = cm9761_spdif_out_source_get, 3232 .put = cm9761_spdif_out_source_put, 3233 }, 3234 /* BIT 2: IG_SPIV */ 3235 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9761_SPDIF_CTRL, 2, 1, 0), 3236 /* BIT 3: SPI2F */ 3237 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9761_SPDIF_CTRL, 3, 1, 0), 3238 /* BIT 4: SPI2SDI */ 3239 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9761_SPDIF_CTRL, 4, 1, 0), 3240 /* BIT 9-10: DAC_CTL */ 3241 AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum), 3242 }; 3243 3244 static int patch_cm9761_post_spdif(struct snd_ac97 * ac97) 3245 { 3246 return patch_build_controls(ac97, snd_ac97_cm9761_controls_spdif, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif)); 3247 } 3248 3249 static int patch_cm9761_specific(struct snd_ac97 * ac97) 3250 { 3251 return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls)); 3252 } 3253 3254 static const struct snd_ac97_build_ops patch_cm9761_ops = { 3255 .build_specific = patch_cm9761_specific, 3256 .build_post_spdif = patch_cm9761_post_spdif, 3257 .update_jacks = cm9761_update_jacks 3258 }; 3259 3260 static int patch_cm9761(struct snd_ac97 *ac97) 3261 { 3262 unsigned short val; 3263 3264 /* CM9761 has no PCM volume although the register reacts */ 3265 /* Master volume seems to have _some_ influence on the analog 3266 * input sounds 3267 */ 3268 ac97->flags |= /*AC97_HAS_NO_MASTER_VOL |*/ AC97_HAS_NO_PCM_VOL; 3269 snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808); 3270 snd_ac97_write_cache(ac97, AC97_PCM, 0x8808); 3271 3272 ac97->spec.dev_flags = 0; /* 1 = model 82 revision B, 2 = model 83 */ 3273 if (ac97->id == AC97_ID_CM9761_82) { 3274 unsigned short tmp; 3275 /* check page 1, reg 0x60 */ 3276 val = snd_ac97_read(ac97, AC97_INT_PAGING); 3277 snd_ac97_write_cache(ac97, AC97_INT_PAGING, (val & ~0x0f) | 0x01); 3278 tmp = snd_ac97_read(ac97, 0x60); 3279 ac97->spec.dev_flags = tmp & 1; /* revision B? */ 3280 snd_ac97_write_cache(ac97, AC97_INT_PAGING, val); 3281 } else if (ac97->id == AC97_ID_CM9761_83) 3282 ac97->spec.dev_flags = 2; 3283 3284 ac97->build_ops = &patch_cm9761_ops; 3285 3286 /* enable spdif */ 3287 /* force the SPDIF bit in ext_id - codec doesn't set this bit! */ 3288 ac97->ext_id |= AC97_EI_SPDIF; 3289 /* to be sure: we overwrite the ext status bits */ 3290 snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, 0x05c0); 3291 /* Don't set 0x0200 here. This results in the silent analog output */ 3292 snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0001); /* enable spdif-in */ 3293 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ 3294 3295 /* set-up multi channel */ 3296 /* bit 15: pc master beep off 3297 * bit 14: pin47 = EAPD/SPDIF 3298 * bit 13: vref ctl [= cm9739] 3299 * bit 12: CLFE control (reverted on rev B) 3300 * bit 11: Mic/center share (reverted on rev B) 3301 * bit 10: suddound/line share 3302 * bit 9: Analog-in mix -> surround 3303 * bit 8: Analog-in mix -> CLFE 3304 * bit 7: Mic/LFE share (mic/center/lfe) 3305 * bit 5: vref select (9761A) 3306 * bit 4: front control 3307 * bit 3: surround control (revereted with rev B) 3308 * bit 2: front mic 3309 * bit 1: stereo mic 3310 * bit 0: mic boost level (0=20dB, 1=30dB) 3311 */ 3312 3313 #if 0 3314 if (ac97->spec.dev_flags) 3315 val = 0x0214; 3316 else 3317 val = 0x321c; 3318 #endif 3319 val = snd_ac97_read(ac97, AC97_CM9761_MULTI_CHAN); 3320 val |= (1 << 4); /* front on */ 3321 snd_ac97_write_cache(ac97, AC97_CM9761_MULTI_CHAN, val); 3322 3323 /* FIXME: set up GPIO */ 3324 snd_ac97_write_cache(ac97, 0x70, 0x0100); 3325 snd_ac97_write_cache(ac97, 0x72, 0x0020); 3326 3327 return 0; 3328 } 3329 3330 #define AC97_CM9780_SIDE 0x60 3331 #define AC97_CM9780_JACK 0x62 3332 #define AC97_CM9780_MIXER 0x64 3333 #define AC97_CM9780_MULTI_CHAN 0x66 3334 #define AC97_CM9780_SPDIF 0x6c 3335 3336 static const char * const cm9780_ch_select[] = { 3337 "Front", "Side", "Center/LFE", "Rear" 3338 }; 3339 static const struct ac97_enum cm9780_ch_select_enum = 3340 AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select); 3341 static const struct snd_kcontrol_new cm9780_controls[] = { 3342 AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE, 15, 7, 1, 1), 3343 AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE, 8, 0, 31, 0), 3344 AC97_ENUM("Side Playback Route", cm9780_ch_select_enum), 3345 }; 3346 3347 static int patch_cm9780_specific(struct snd_ac97 *ac97) 3348 { 3349 return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls)); 3350 } 3351 3352 static const struct snd_ac97_build_ops patch_cm9780_ops = { 3353 .build_specific = patch_cm9780_specific, 3354 .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ 3355 }; 3356 3357 static int patch_cm9780(struct snd_ac97 *ac97) 3358 { 3359 unsigned short val; 3360 3361 ac97->build_ops = &patch_cm9780_ops; 3362 3363 /* enable spdif */ 3364 if (ac97->ext_id & AC97_EI_SPDIF) { 3365 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ 3366 val = snd_ac97_read(ac97, AC97_CM9780_SPDIF); 3367 val |= 0x1; /* SPDI_EN */ 3368 snd_ac97_write_cache(ac97, AC97_CM9780_SPDIF, val); 3369 } 3370 3371 return 0; 3372 } 3373 3374 /* 3375 * VIA VT1613 codec 3376 */ 3377 static const struct snd_kcontrol_new snd_ac97_controls_vt1613[] = { 3378 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0), 3379 }; 3380 3381 static int patch_vt1613_specific(struct snd_ac97 *ac97) 3382 { 3383 return patch_build_controls(ac97, &snd_ac97_controls_vt1613[0], 3384 ARRAY_SIZE(snd_ac97_controls_vt1613)); 3385 }; 3386 3387 static const struct snd_ac97_build_ops patch_vt1613_ops = { 3388 .build_specific = patch_vt1613_specific 3389 }; 3390 3391 static int patch_vt1613(struct snd_ac97 *ac97) 3392 { 3393 ac97->build_ops = &patch_vt1613_ops; 3394 3395 ac97->flags |= AC97_HAS_NO_VIDEO; 3396 ac97->caps |= AC97_BC_HEADPHONE; 3397 3398 return 0; 3399 } 3400 3401 /* 3402 * VIA VT1616 codec 3403 */ 3404 static const struct snd_kcontrol_new snd_ac97_controls_vt1616[] = { 3405 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0), 3406 AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0), 3407 AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0), 3408 AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0), 3409 }; 3410 3411 static const char * const follower_vols_vt1616[] = { 3412 "Front Playback Volume", 3413 "Surround Playback Volume", 3414 "Center Playback Volume", 3415 "LFE Playback Volume", 3416 NULL 3417 }; 3418 3419 static const char * const follower_sws_vt1616[] = { 3420 "Front Playback Switch", 3421 "Surround Playback Switch", 3422 "Center Playback Switch", 3423 "LFE Playback Switch", 3424 NULL 3425 }; 3426 3427 /* find a mixer control element with the given name */ 3428 static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97, 3429 const char *name) 3430 { 3431 return snd_ctl_find_id_mixer(ac97->bus->card, name); 3432 } 3433 3434 /* create a virtual master control and add followers */ 3435 static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, 3436 const unsigned int *tlv, 3437 const char * const *followers) 3438 { 3439 struct snd_kcontrol *kctl; 3440 int err; 3441 3442 kctl = snd_ctl_make_virtual_master(name, tlv); 3443 if (!kctl) 3444 return -ENOMEM; 3445 err = snd_ctl_add(ac97->bus->card, kctl); 3446 if (err < 0) 3447 return err; 3448 3449 return snd_ctl_add_followers(ac97->bus->card, kctl, followers); 3450 } 3451 3452 static int patch_vt1616_specific(struct snd_ac97 * ac97) 3453 { 3454 struct snd_kcontrol *kctl; 3455 int err; 3456 3457 if (snd_ac97_try_bit(ac97, 0x5a, 9)) { 3458 err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[0], 1); 3459 if (err < 0) 3460 return err; 3461 } 3462 err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1); 3463 if (err < 0) 3464 return err; 3465 3466 /* There is already a misnamed master switch. Rename it. */ 3467 kctl = snd_ac97_find_mixer_ctl(ac97, "Master Playback Volume"); 3468 if (!kctl) 3469 return -EINVAL; 3470 3471 snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Front Playback"); 3472 3473 err = snd_ac97_add_vmaster(ac97, "Master Playback Volume", 3474 kctl->tlv.p, follower_vols_vt1616); 3475 if (err < 0) 3476 return err; 3477 3478 err = snd_ac97_add_vmaster(ac97, "Master Playback Switch", 3479 NULL, follower_sws_vt1616); 3480 if (err < 0) 3481 return err; 3482 3483 return 0; 3484 } 3485 3486 static const struct snd_ac97_build_ops patch_vt1616_ops = { 3487 .build_specific = patch_vt1616_specific 3488 }; 3489 3490 static int patch_vt1616(struct snd_ac97 * ac97) 3491 { 3492 ac97->build_ops = &patch_vt1616_ops; 3493 return 0; 3494 } 3495 3496 /* 3497 * VT1617A codec 3498 */ 3499 3500 /* 3501 * unfortunately, the vt1617a stashes the twiddlers required for 3502 * noodling the i/o jacks on 2 different regs. that means that we can't 3503 * use the easy way provided by AC97_ENUM_DOUBLE() we have to write 3504 * are own funcs. 3505 * 3506 * NB: this is absolutely and utterly different from the vt1618. dunno 3507 * about the 1616. 3508 */ 3509 3510 /* copied from ac97_surround_jack_mode_info() */ 3511 static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol, 3512 struct snd_ctl_elem_info *uinfo) 3513 { 3514 /* ordering in this list reflects vt1617a docs for Reg 20 and 3515 * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51 3516 * is SM51EN *AND* it's Bit14, not Bit15 so the table is very 3517 * counter-intuitive */ 3518 3519 static const char * const texts[] = {"LineIn Mic1", "LineIn Mic1 Mic3", 3520 "Surr LFE/C Mic3", "LineIn LFE/C Mic3", 3521 "LineIn Mic2", "LineIn Mic2 Mic1", 3522 "Surr LFE Mic1", "Surr LFE Mic1 Mic2"}; 3523 3524 return snd_ctl_enum_info(uinfo, 1, 8, texts); 3525 } 3526 3527 static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol, 3528 struct snd_ctl_elem_value *ucontrol) 3529 { 3530 ushort usSM51, usMS; 3531 3532 struct snd_ac97 *pac97; 3533 3534 pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ 3535 3536 /* grab our desired bits, then mash them together in a manner 3537 * consistent with Table 6 on page 17 in the 1617a docs */ 3538 3539 usSM51 = snd_ac97_read(pac97, 0x7a) >> 14; 3540 usMS = snd_ac97_read(pac97, 0x20) >> 8; 3541 3542 ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS; 3543 3544 return 0; 3545 } 3546 3547 static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol, 3548 struct snd_ctl_elem_value *ucontrol) 3549 { 3550 ushort usSM51, usMS, usReg; 3551 3552 struct snd_ac97 *pac97; 3553 3554 pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ 3555 3556 usSM51 = ucontrol->value.enumerated.item[0] >> 1; 3557 usMS = ucontrol->value.enumerated.item[0] & 1; 3558 3559 /* push our values into the register - consider that things will be left 3560 * in a funky state if the write fails */ 3561 3562 usReg = snd_ac97_read(pac97, 0x7a); 3563 snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14)); 3564 usReg = snd_ac97_read(pac97, 0x20); 3565 snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8)); 3566 3567 return 0; 3568 } 3569 3570 static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = { 3571 3572 AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0), 3573 /* 3574 * These are used to enable/disable surround sound on motherboards 3575 * that have 3 bidirectional analog jacks 3576 */ 3577 { 3578 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3579 .name = "Smart 5.1 Select", 3580 .info = snd_ac97_vt1617a_smart51_info, 3581 .get = snd_ac97_vt1617a_smart51_get, 3582 .put = snd_ac97_vt1617a_smart51_put, 3583 }, 3584 }; 3585 3586 static int patch_vt1617a(struct snd_ac97 * ac97) 3587 { 3588 int err = 0; 3589 int val; 3590 3591 /* we choose to not fail out at this point, but we tell the 3592 caller when we return */ 3593 3594 err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0], 3595 ARRAY_SIZE(snd_ac97_controls_vt1617a)); 3596 3597 /* bring analog power consumption to normal by turning off the 3598 * headphone amplifier, like WinXP driver for EPIA SP 3599 */ 3600 /* We need to check the bit before writing it. 3601 * On some (many?) hardwares, setting bit actually clears it! 3602 */ 3603 val = snd_ac97_read(ac97, 0x5c); 3604 if (!(val & 0x20)) 3605 snd_ac97_write_cache(ac97, 0x5c, 0x20); 3606 3607 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ 3608 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; 3609 ac97->build_ops = &patch_vt1616_ops; 3610 3611 return err; 3612 } 3613 3614 /* VIA VT1618 8 CHANNEL AC97 CODEC 3615 * 3616 * VIA implements 'Smart 5.1' completely differently on the 1618 than 3617 * it does on the 1617a. awesome! They seem to have sourced this 3618 * particular revision of the technology from somebody else, it's 3619 * called Universal Audio Jack and it shows up on some other folk's chips 3620 * as well. 3621 * 3622 * ordering in this list reflects vt1618 docs for Reg 60h and 3623 * the block diagram, DACs are as follows: 3624 * 3625 * OUT_O -> Front, 3626 * OUT_1 -> Surround, 3627 * OUT_2 -> C/LFE 3628 * 3629 * Unlike the 1617a, each OUT has a consistent set of mappings 3630 * for all bitpatterns other than 00: 3631 * 3632 * 01 Unmixed Output 3633 * 10 Line In 3634 * 11 Mic In 3635 * 3636 * Special Case of 00: 3637 * 3638 * OUT_0 Mixed Output 3639 * OUT_1 Reserved 3640 * OUT_2 Reserved 3641 * 3642 * I have no idea what the hell Reserved does, but on an MSI 3643 * CN700T, i have to set it to get 5.1 output - YMMV, bad 3644 * shit may happen. 3645 * 3646 * If other chips use Universal Audio Jack, then this code might be applicable 3647 * to them. 3648 */ 3649 3650 struct vt1618_uaj_item { 3651 unsigned short mask; 3652 unsigned short shift; 3653 const char * const items[4]; 3654 }; 3655 3656 /* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */ 3657 3658 static const struct vt1618_uaj_item vt1618_uaj[3] = { 3659 { 3660 /* speaker jack */ 3661 .mask = 0x03, 3662 .shift = 0, 3663 .items = { 3664 "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In" 3665 } 3666 }, 3667 { 3668 /* line jack */ 3669 .mask = 0x0c, 3670 .shift = 2, 3671 .items = { 3672 "Surround Out", "DAC Unmixed Out", "Line In", "Mic In" 3673 } 3674 }, 3675 { 3676 /* mic jack */ 3677 .mask = 0x30, 3678 .shift = 4, 3679 .items = { 3680 "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In" 3681 }, 3682 }, 3683 }; 3684 3685 static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol, 3686 struct snd_ctl_elem_info *uinfo) 3687 { 3688 return snd_ctl_enum_info(uinfo, 1, 4, 3689 vt1618_uaj[kcontrol->private_value].items); 3690 } 3691 3692 /* All of the vt1618 Universal Audio Jack twiddlers are on 3693 * Vendor Defined Register 0x60, page 0. The bits, and thus 3694 * the mask, are the only thing that changes 3695 */ 3696 static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol *kcontrol, 3697 struct snd_ctl_elem_value *ucontrol) 3698 { 3699 unsigned short datpag, uaj; 3700 struct snd_ac97 *pac97 = snd_kcontrol_chip(kcontrol); 3701 3702 mutex_lock(&pac97->page_mutex); 3703 3704 datpag = snd_ac97_read(pac97, AC97_INT_PAGING) & AC97_PAGE_MASK; 3705 snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, 0); 3706 3707 uaj = snd_ac97_read(pac97, 0x60) & 3708 vt1618_uaj[kcontrol->private_value].mask; 3709 3710 snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, datpag); 3711 mutex_unlock(&pac97->page_mutex); 3712 3713 ucontrol->value.enumerated.item[0] = uaj >> 3714 vt1618_uaj[kcontrol->private_value].shift; 3715 3716 return 0; 3717 } 3718 3719 static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol *kcontrol, 3720 struct snd_ctl_elem_value *ucontrol) 3721 { 3722 return ac97_update_bits_page(snd_kcontrol_chip(kcontrol), 0x60, 3723 vt1618_uaj[kcontrol->private_value].mask, 3724 ucontrol->value.enumerated.item[0]<< 3725 vt1618_uaj[kcontrol->private_value].shift, 3726 0); 3727 } 3728 3729 /* config aux in jack - not found on 3 jack motherboards or soundcards */ 3730 3731 static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol, 3732 struct snd_ctl_elem_info *uinfo) 3733 { 3734 static const char * const txt_aux[] = {"Aux In", "Back Surr Out"}; 3735 3736 return snd_ctl_enum_info(uinfo, 1, 2, txt_aux); 3737 } 3738 3739 static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol, 3740 struct snd_ctl_elem_value *ucontrol) 3741 { 3742 ucontrol->value.enumerated.item[0] = 3743 (snd_ac97_read(snd_kcontrol_chip(kcontrol), 0x5c) & 0x0008)>>3; 3744 return 0; 3745 } 3746 3747 static int snd_ac97_vt1618_aux_put(struct snd_kcontrol *kcontrol, 3748 struct snd_ctl_elem_value *ucontrol) 3749 { 3750 /* toggle surround rear dac power */ 3751 3752 snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x5c, 0x0008, 3753 ucontrol->value.enumerated.item[0] << 3); 3754 3755 /* toggle aux in surround rear out jack */ 3756 3757 return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x76, 0x0008, 3758 ucontrol->value.enumerated.item[0] << 3); 3759 } 3760 3761 static const struct snd_kcontrol_new snd_ac97_controls_vt1618[] = { 3762 AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0), 3763 AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0), 3764 AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1), 3765 AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1), 3766 AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1), 3767 AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1), 3768 { 3769 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3770 .name = "Speaker Jack Mode", 3771 .info = snd_ac97_vt1618_UAJ_info, 3772 .get = snd_ac97_vt1618_UAJ_get, 3773 .put = snd_ac97_vt1618_UAJ_put, 3774 .private_value = 0 3775 }, 3776 { 3777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3778 .name = "Line Jack Mode", 3779 .info = snd_ac97_vt1618_UAJ_info, 3780 .get = snd_ac97_vt1618_UAJ_get, 3781 .put = snd_ac97_vt1618_UAJ_put, 3782 .private_value = 1 3783 }, 3784 { 3785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3786 .name = "Mic Jack Mode", 3787 .info = snd_ac97_vt1618_UAJ_info, 3788 .get = snd_ac97_vt1618_UAJ_get, 3789 .put = snd_ac97_vt1618_UAJ_put, 3790 .private_value = 2 3791 }, 3792 { 3793 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3794 .name = "Aux Jack Mode", 3795 .info = snd_ac97_vt1618_aux_info, 3796 .get = snd_ac97_vt1618_aux_get, 3797 .put = snd_ac97_vt1618_aux_put, 3798 } 3799 }; 3800 3801 static int patch_vt1618(struct snd_ac97 *ac97) 3802 { 3803 return patch_build_controls(ac97, snd_ac97_controls_vt1618, 3804 ARRAY_SIZE(snd_ac97_controls_vt1618)); 3805 } 3806 3807 /* 3808 */ 3809 static void it2646_update_jacks(struct snd_ac97 *ac97) 3810 { 3811 /* shared Line-In / Surround Out */ 3812 snd_ac97_update_bits(ac97, 0x76, 1 << 9, 3813 is_shared_surrout(ac97) ? (1<<9) : 0); 3814 /* shared Mic / Center/LFE Out */ 3815 snd_ac97_update_bits(ac97, 0x76, 1 << 10, 3816 is_shared_clfeout(ac97) ? (1<<10) : 0); 3817 } 3818 3819 static const struct snd_kcontrol_new snd_ac97_controls_it2646[] = { 3820 AC97_SURROUND_JACK_MODE_CTL, 3821 AC97_CHANNEL_MODE_CTL, 3822 }; 3823 3824 static const struct snd_kcontrol_new snd_ac97_spdif_controls_it2646[] = { 3825 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0x76, 11, 1, 0), 3826 AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0), 3827 AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0), 3828 }; 3829 3830 static int patch_it2646_specific(struct snd_ac97 * ac97) 3831 { 3832 int err; 3833 err = patch_build_controls(ac97, snd_ac97_controls_it2646, ARRAY_SIZE(snd_ac97_controls_it2646)); 3834 if (err < 0) 3835 return err; 3836 err = patch_build_controls(ac97, snd_ac97_spdif_controls_it2646, ARRAY_SIZE(snd_ac97_spdif_controls_it2646)); 3837 if (err < 0) 3838 return err; 3839 return 0; 3840 } 3841 3842 static const struct snd_ac97_build_ops patch_it2646_ops = { 3843 .build_specific = patch_it2646_specific, 3844 .update_jacks = it2646_update_jacks 3845 }; 3846 3847 static int patch_it2646(struct snd_ac97 * ac97) 3848 { 3849 ac97->build_ops = &patch_it2646_ops; 3850 /* full DAC volume */ 3851 snd_ac97_write_cache(ac97, 0x5E, 0x0808); 3852 snd_ac97_write_cache(ac97, 0x7A, 0x0808); 3853 return 0; 3854 } 3855 3856 /* 3857 * Si3036 codec 3858 */ 3859 3860 #define AC97_SI3036_CHIP_ID 0x5a 3861 #define AC97_SI3036_LINE_CFG 0x5c 3862 3863 static const struct snd_kcontrol_new snd_ac97_controls_si3036[] = { 3864 AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1) 3865 }; 3866 3867 static int patch_si3036_specific(struct snd_ac97 * ac97) 3868 { 3869 int idx, err; 3870 for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_si3036); idx++) { 3871 err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_si3036[idx], ac97)); 3872 if (err < 0) 3873 return err; 3874 } 3875 return 0; 3876 } 3877 3878 static const struct snd_ac97_build_ops patch_si3036_ops = { 3879 .build_specific = patch_si3036_specific, 3880 }; 3881 3882 static int mpatch_si3036(struct snd_ac97 * ac97) 3883 { 3884 ac97->build_ops = &patch_si3036_ops; 3885 snd_ac97_write_cache(ac97, 0x5c, 0xf210 ); 3886 snd_ac97_write_cache(ac97, 0x68, 0); 3887 return 0; 3888 } 3889 3890 /* 3891 * LM 4550 Codec 3892 * 3893 * We use a static resolution table since LM4550 codec cannot be 3894 * properly autoprobed to determine the resolution via 3895 * check_volume_resolution(). 3896 */ 3897 3898 static const struct snd_ac97_res_table lm4550_restbl[] = { 3899 { AC97_MASTER, 0x1f1f }, 3900 { AC97_HEADPHONE, 0x1f1f }, 3901 { AC97_MASTER_MONO, 0x001f }, 3902 { AC97_PC_BEEP, 0x001f }, /* LSB is ignored */ 3903 { AC97_PHONE, 0x001f }, 3904 { AC97_MIC, 0x001f }, 3905 { AC97_LINE, 0x1f1f }, 3906 { AC97_CD, 0x1f1f }, 3907 { AC97_VIDEO, 0x1f1f }, 3908 { AC97_AUX, 0x1f1f }, 3909 { AC97_PCM, 0x1f1f }, 3910 { AC97_REC_GAIN, 0x0f0f }, 3911 { } /* terminator */ 3912 }; 3913 3914 static int patch_lm4550(struct snd_ac97 *ac97) 3915 { 3916 ac97->res_table = lm4550_restbl; 3917 return 0; 3918 } 3919
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.