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