1 /* 2 * Copyright (c) by Jaroslav Kysela <perex@suse.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 <sound/driver.h> 27 #include <linux/delay.h> 28 #include <linux/init.h> 29 #include <linux/slab.h> 30 #include <sound/core.h> 31 #include <sound/pcm.h> 32 #include <sound/control.h> 33 #include <sound/ac97_codec.h> 34 #include "ac97_patch.h" 35 #include "ac97_id.h" 36 #include "ac97_local.h" 37 38 /* 39 * Chip specific initialization 40 */ 41 42 static int patch_build_controls(ac97_t * ac97, const snd_kcontrol_new_t *controls, int count) 43 { 44 int idx, err; 45 46 for (idx = 0; idx < count; idx++) 47 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&controls[idx], ac97))) < 0) 48 return err; 49 return 0; 50 } 51 52 /* set to the page, update bits and restore the page */ 53 static int ac97_update_bits_page(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value, unsigned short page) 54 { 55 unsigned short page_save; 56 int ret; 57 58 down(&ac97->page_mutex); 59 page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; 60 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); 61 ret = snd_ac97_update_bits(ac97, reg, mask, value); 62 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); 63 up(&ac97->page_mutex); /* unlock paging */ 64 return ret; 65 } 66 67 /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */ 68 69 /* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */ 70 static int snd_ac97_ymf753_info_speaker(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 71 { 72 static char *texts[3] = { 73 "Standard", "Small", "Smaller" 74 }; 75 76 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 77 uinfo->count = 1; 78 uinfo->value.enumerated.items = 3; 79 if (uinfo->value.enumerated.item > 2) 80 uinfo->value.enumerated.item = 2; 81 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 82 return 0; 83 } 84 85 static int snd_ac97_ymf753_get_speaker(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 86 { 87 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 88 unsigned short val; 89 90 val = ac97->regs[AC97_YMF753_3D_MODE_SEL]; 91 val = (val >> 10) & 3; 92 if (val > 0) /* 0 = invalid */ 93 val--; 94 ucontrol->value.enumerated.item[0] = val; 95 return 0; 96 } 97 98 static int snd_ac97_ymf753_put_speaker(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 99 { 100 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 101 unsigned short val; 102 103 if (ucontrol->value.enumerated.item[0] > 2) 104 return -EINVAL; 105 val = (ucontrol->value.enumerated.item[0] + 1) << 10; 106 return snd_ac97_update(ac97, AC97_YMF753_3D_MODE_SEL, val); 107 } 108 109 static const snd_kcontrol_new_t snd_ac97_ymf753_controls_speaker = 110 { 111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 112 .name = "3D Control - Speaker", 113 .info = snd_ac97_ymf753_info_speaker, 114 .get = snd_ac97_ymf753_get_speaker, 115 .put = snd_ac97_ymf753_put_speaker, 116 }; 117 118 /* It is possible to indicate to the Yamaha YMF753 the source to direct to the S/PDIF output. */ 119 static int snd_ac97_ymf753_spdif_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 120 { 121 static char *texts[2] = { "AC-Link", "A/D Converter" }; 122 123 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 124 uinfo->count = 1; 125 uinfo->value.enumerated.items = 2; 126 if (uinfo->value.enumerated.item > 1) 127 uinfo->value.enumerated.item = 1; 128 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 129 return 0; 130 } 131 132 static int snd_ac97_ymf753_spdif_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 133 { 134 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 135 unsigned short val; 136 137 val = ac97->regs[AC97_YMF753_DIT_CTRL2]; 138 ucontrol->value.enumerated.item[0] = (val >> 1) & 1; 139 return 0; 140 } 141 142 static int snd_ac97_ymf753_spdif_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 143 { 144 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 145 unsigned short val; 146 147 if (ucontrol->value.enumerated.item[0] > 1) 148 return -EINVAL; 149 val = ucontrol->value.enumerated.item[0] << 1; 150 return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0002, val); 151 } 152 153 /* The AC'97 spec states that the S/PDIF signal is to be output at pin 48. 154 The YMF753 will output the S/PDIF signal to pin 43, 47 (EAPD), or 48. 155 By default, no output pin is selected, and the S/PDIF signal is not output. 156 There is also a bit to mute S/PDIF output in a vendor-specific register. */ 157 static int snd_ac97_ymf753_spdif_output_pin_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 158 { 159 static char *texts[3] = { "Disabled", "Pin 43", "Pin 48" }; 160 161 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 162 uinfo->count = 1; 163 uinfo->value.enumerated.items = 3; 164 if (uinfo->value.enumerated.item > 2) 165 uinfo->value.enumerated.item = 2; 166 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 167 return 0; 168 } 169 170 static int snd_ac97_ymf753_spdif_output_pin_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 171 { 172 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 173 unsigned short val; 174 175 val = ac97->regs[AC97_YMF753_DIT_CTRL2]; 176 ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0; 177 return 0; 178 } 179 180 static int snd_ac97_ymf753_spdif_output_pin_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 181 { 182 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 183 unsigned short val; 184 185 if (ucontrol->value.enumerated.item[0] > 2) 186 return -EINVAL; 187 val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 : 188 (ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0; 189 return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0028, val); 190 /* The following can be used to direct S/PDIF output to pin 47 (EAPD). 191 snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */ 192 } 193 194 static const snd_kcontrol_new_t snd_ac97_ymf753_controls_spdif[3] = { 195 { 196 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 197 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 198 .info = snd_ac97_ymf753_spdif_source_info, 199 .get = snd_ac97_ymf753_spdif_source_get, 200 .put = snd_ac97_ymf753_spdif_source_put, 201 }, 202 { 203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 204 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Output Pin", 205 .info = snd_ac97_ymf753_spdif_output_pin_info, 206 .get = snd_ac97_ymf753_spdif_output_pin_get, 207 .put = snd_ac97_ymf753_spdif_output_pin_put, 208 }, 209 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",NONE,NONE) "Mute", AC97_YMF753_DIT_CTRL2, 2, 1, 1) 210 }; 211 212 static int patch_yamaha_ymf753_3d(ac97_t * ac97) 213 { 214 snd_kcontrol_t *kctl; 215 int err; 216 217 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0) 218 return err; 219 strcpy(kctl->id.name, "3D Control - Wide"); 220 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0); 221 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); 222 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_ymf753_controls_speaker, ac97))) < 0) 223 return err; 224 snd_ac97_write_cache(ac97, AC97_YMF753_3D_MODE_SEL, 0x0c00); 225 return 0; 226 } 227 228 static int patch_yamaha_ymf753_post_spdif(ac97_t * ac97) 229 { 230 int err; 231 232 if ((err = patch_build_controls(ac97, snd_ac97_ymf753_controls_spdif, ARRAY_SIZE(snd_ac97_ymf753_controls_spdif))) < 0) 233 return err; 234 return 0; 235 } 236 237 static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { 238 .build_3d = patch_yamaha_ymf753_3d, 239 .build_post_spdif = patch_yamaha_ymf753_post_spdif 240 }; 241 242 int patch_yamaha_ymf753(ac97_t * ac97) 243 { 244 /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com. 245 This chip has nonstandard and extended behaviour with regard to its S/PDIF output. 246 The AC'97 spec states that the S/PDIF signal is to be output at pin 48. 247 The YMF753 will ouput the S/PDIF signal to pin 43, 47 (EAPD), or 48. 248 By default, no output pin is selected, and the S/PDIF signal is not output. 249 There is also a bit to mute S/PDIF output in a vendor-specific register. 250 */ 251 ac97->build_ops = &patch_yamaha_ymf753_ops; 252 ac97->caps |= AC97_BC_BASS_TREBLE; 253 ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */ 254 return 0; 255 } 256 257 /* 258 * May 2, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com> 259 * removed broken wolfson00 patch. 260 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. 261 */ 262 263 int patch_wolfson03(ac97_t * ac97) 264 { 265 /* This is known to work for the ViewSonic ViewPad 1000 266 Randolph Bentson <bentson@holmsjoen.com> */ 267 268 // WM9703/9707/9708/9717 269 snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); 270 snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0x8000); 271 return 0; 272 } 273 274 int patch_wolfson04(ac97_t * ac97) 275 { 276 // WM9704M/9704Q 277 // set front and rear mixer volume 278 snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); 279 snd_ac97_write_cache(ac97, AC97_WM9704_RMIXER_VOL, 0x0808); 280 281 // patch for DVD noise 282 snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200); 283 284 // init vol 285 snd_ac97_write_cache(ac97, AC97_WM9704_RPCM_VOL, 0x0808); 286 287 // set rear surround volume 288 snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000); 289 return 0; 290 } 291 292 int patch_wolfson05(ac97_t * ac97) 293 { 294 // WM9705, WM9710 295 // set front mixer volume 296 snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); 297 return 0; 298 } 299 300 int patch_wolfson11(ac97_t * ac97) 301 { 302 // WM9711, WM9712 303 // set out3 volume 304 snd_ac97_write_cache(ac97, AC97_WM9711_OUT3VOL, 0x0808); 305 return 0; 306 } 307 308 static const char* wm9713_mic_mixer[] = {"Stereo", "Mic1", "Mic2", "Mute"}; 309 static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; 310 static const char* wm9713_rec_src_l[] = {"Mic1", "Mic2", "Line L", "Mono In", "HP Mix L", "Spk Mix", "Mono Mix", "Zh"}; 311 static const char* wm9713_rec_src_r[] = {"Mic1", "Mic2", "Line R", "Mono In", "HP Mix R", "Spk Mix", "Mono Mix", "Zh"}; 312 313 static const struct ac97_enum wm9713_enum[] = { 314 AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), 315 AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), 316 AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), 317 AC97_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src_l), 318 AC97_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src_r), 319 }; 320 321 static const snd_kcontrol_new_t wm13_snd_ac97_controls_line_in[] = { 322 AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), 323 AC97_SINGLE("Line In to Headphone Mute", AC97_PC_BEEP, 15, 1, 1), 324 AC97_SINGLE("Line In to Speaker Mute", AC97_PC_BEEP, 14, 1, 1), 325 AC97_SINGLE("Line In to Mono Mute", AC97_PC_BEEP, 13, 1, 1), 326 }; 327 328 static const snd_kcontrol_new_t wm13_snd_ac97_controls_dac[] = { 329 AC97_DOUBLE("DAC Volume", AC97_PHONE, 8, 0, 31, 1), 330 AC97_SINGLE("DAC to Headphone Mute", AC97_PHONE, 15, 1, 1), 331 AC97_SINGLE("DAC to Speaker Mute", AC97_PHONE, 14, 1, 1), 332 AC97_SINGLE("DAC to Mono Mute", AC97_PHONE, 13, 1, 1), 333 }; 334 335 static const snd_kcontrol_new_t wm13_snd_ac97_controls_mic[] = { 336 AC97_SINGLE("MICA Volume", AC97_MIC, 8, 31, 1), 337 AC97_SINGLE("MICB Volume", AC97_MIC, 0, 31, 1), 338 AC97_SINGLE("MICA to Mono Mute", AC97_LINE, 7, 1, 1), 339 AC97_SINGLE("MICB to Mono Mute", AC97_LINE, 6, 1, 1), 340 AC97_SINGLE("MIC Boost (+20dB)", AC97_LINE, 5, 1, 1), 341 AC97_ENUM("MIC Headphone Routing", wm9713_enum[0]), 342 AC97_SINGLE("MIC Headphone Mixer Volume", AC97_LINE, 0, 7, 1) 343 }; 344 345 static const snd_kcontrol_new_t wm13_snd_ac97_controls_adc[] = { 346 AC97_SINGLE("ADC Mute", AC97_CD, 15, 1, 1), 347 AC97_DOUBLE("Gain Step Size (1.5dB/0.75dB)", AC97_CD, 14, 6, 1, 1), 348 AC97_DOUBLE("ADC Volume",AC97_CD, 8, 0, 15, 0), 349 AC97_SINGLE("ADC Zero Cross", AC97_CD, 7, 1, 1), 350 }; 351 352 static const snd_kcontrol_new_t wm13_snd_ac97_controls_recsel[] = { 353 AC97_ENUM("Record to Headphone Path", wm9713_enum[1]), 354 AC97_SINGLE("Record to Headphone Volume", AC97_VIDEO, 11, 7, 0), 355 AC97_ENUM("Record to Mono Path", wm9713_enum[2]), 356 AC97_SINGLE("Record to Mono Boost (+20dB)", AC97_VIDEO, 8, 1, 0), 357 AC97_SINGLE("Record ADC Boost (+20dB)", AC97_VIDEO, 6, 1, 0), 358 AC97_ENUM("Record Select Left", wm9713_enum[3]), 359 AC97_ENUM("Record Select Right", wm9713_enum[4]), 360 }; 361 362 static int patch_wolfson_wm9713_specific(ac97_t * ac97) 363 { 364 int err, i; 365 366 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_line_in); i++) { 367 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_line_in[i], ac97))) < 0) 368 return err; 369 } 370 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); 371 372 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_dac); i++) { 373 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_dac[i], ac97))) < 0) 374 return err; 375 } 376 snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808); 377 378 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_mic); i++) { 379 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_mic[i], ac97))) < 0) 380 return err; 381 } 382 snd_ac97_write_cache(ac97, AC97_MIC, 0x0808); 383 snd_ac97_write_cache(ac97, AC97_LINE, 0x00da); 384 385 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_adc); i++) { 386 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_adc[i], ac97))) < 0) 387 return err; 388 } 389 snd_ac97_write_cache(ac97, AC97_CD, 0x0808); 390 391 for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_recsel); i++) { 392 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_recsel[i], ac97))) < 0) 393 return err; 394 } 395 snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612); 396 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0); 397 398 return 0; 399 } 400 401 #ifdef CONFIG_PM 402 static void patch_wolfson_wm9713_suspend (ac97_t * ac97) 403 { 404 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xfeff); 405 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xffff); 406 } 407 408 static void patch_wolfson_wm9713_resume (ac97_t * ac97) 409 { 410 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); 411 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); 412 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0); 413 } 414 #endif 415 416 static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { 417 .build_specific = patch_wolfson_wm9713_specific, 418 #ifdef CONFIG_PM 419 .suspend = patch_wolfson_wm9713_suspend, 420 .resume = patch_wolfson_wm9713_resume 421 #endif 422 }; 423 424 int patch_wolfson13(ac97_t * ac97) 425 { 426 ac97->build_ops = &patch_wolfson_wm9713_ops; 427 428 ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE | 429 AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD; 430 431 snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); 432 snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); 433 snd_ac97_write_cache(ac97, AC97_POWERDOWN, 0x0); 434 435 return 0; 436 } 437 438 /* 439 * Tritech codec 440 */ 441 int patch_tritech_tr28028(ac97_t * ac97) 442 { 443 snd_ac97_write_cache(ac97, 0x26, 0x0300); 444 snd_ac97_write_cache(ac97, 0x26, 0x0000); 445 snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000); 446 snd_ac97_write_cache(ac97, AC97_SPDIF, 0x0000); 447 return 0; 448 } 449 450 /* 451 * Sigmatel STAC97xx codecs 452 */ 453 static int patch_sigmatel_stac9700_3d(ac97_t * ac97) 454 { 455 snd_kcontrol_t *kctl; 456 int err; 457 458 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0) 459 return err; 460 strcpy(kctl->id.name, "3D Control Sigmatel - Depth"); 461 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0); 462 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); 463 return 0; 464 } 465 466 static int patch_sigmatel_stac9708_3d(ac97_t * ac97) 467 { 468 snd_kcontrol_t *kctl; 469 int err; 470 471 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0) 472 return err; 473 strcpy(kctl->id.name, "3D Control Sigmatel - Depth"); 474 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 0, 3, 0); 475 if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0) 476 return err; 477 strcpy(kctl->id.name, "3D Control Sigmatel - Rear Depth"); 478 kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0); 479 snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000); 480 return 0; 481 } 482 483 static const snd_kcontrol_new_t snd_ac97_sigmatel_4speaker = 484 AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch", AC97_SIGMATEL_DAC2INVERT, 2, 1, 0); 485 486 static const snd_kcontrol_new_t snd_ac97_sigmatel_phaseinvert = 487 AC97_SINGLE("Sigmatel Surround Phase Inversion Playback Switch", AC97_SIGMATEL_DAC2INVERT, 3, 1, 0); 488 489 static const snd_kcontrol_new_t snd_ac97_sigmatel_controls[] = { 490 AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0), 491 AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 0, 1, 0) 492 }; 493 494 static int patch_sigmatel_stac97xx_specific(ac97_t * ac97) 495 { 496 int err; 497 498 snd_ac97_write_cache(ac97, AC97_SIGMATEL_ANALOG, snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) & ~0x0003); 499 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 1)) 500 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[0], 1)) < 0) 501 return err; 502 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_ANALOG, 0)) 503 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_controls[1], 1)) < 0) 504 return err; 505 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 2)) 506 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_4speaker, 1)) < 0) 507 return err; 508 if (snd_ac97_try_bit(ac97, AC97_SIGMATEL_DAC2INVERT, 3)) 509 if ((err = patch_build_controls(ac97, &snd_ac97_sigmatel_phaseinvert, 1)) < 0) 510 return err; 511 return 0; 512 } 513 514 static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { 515 .build_3d = patch_sigmatel_stac9700_3d, 516 .build_specific = patch_sigmatel_stac97xx_specific 517 }; 518 519 int patch_sigmatel_stac9700(ac97_t * ac97) 520 { 521 ac97->build_ops = &patch_sigmatel_stac9700_ops; 522 return 0; 523 } 524 525 static int snd_ac97_stac9708_put_bias(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 526 { 527 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 528 int err; 529 530 down(&ac97->page_mutex); 531 snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba); 532 err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010, 533 (ucontrol->value.integer.value[0] & 1) << 4); 534 snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0); 535 up(&ac97->page_mutex); 536 return err; 537 } 538 539 static const snd_kcontrol_new_t snd_ac97_stac9708_bias_control = { 540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 541 .name = "Sigmatel Output Bias Switch", 542 .info = snd_ac97_info_volsw, 543 .get = snd_ac97_get_volsw, 544 .put = snd_ac97_stac9708_put_bias, 545 .private_value = AC97_SINGLE_VALUE(AC97_SIGMATEL_BIAS2, 4, 1, 0), 546 }; 547 548 static int patch_sigmatel_stac9708_specific(ac97_t *ac97) 549 { 550 int err; 551 552 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback"); 553 if ((err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1)) < 0) 554 return err; 555 return patch_sigmatel_stac97xx_specific(ac97); 556 } 557 558 static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { 559 .build_3d = patch_sigmatel_stac9708_3d, 560 .build_specific = patch_sigmatel_stac9708_specific 561 }; 562 563 int patch_sigmatel_stac9708(ac97_t * ac97) 564 { 565 unsigned int codec72, codec6c; 566 567 ac97->build_ops = &patch_sigmatel_stac9708_ops; 568 ac97->caps |= 0x10; /* HP (sigmatel surround) support */ 569 570 codec72 = snd_ac97_read(ac97, AC97_SIGMATEL_BIAS2) & 0x8000; 571 codec6c = snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG); 572 573 if ((codec72==0) && (codec6c==0)) { 574 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba); 575 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1000); 576 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba); 577 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0007); 578 } else if ((codec72==0x8000) && (codec6c==0)) { 579 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba); 580 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x1001); 581 snd_ac97_write_cache(ac97, AC97_SIGMATEL_DAC2INVERT, 0x0008); 582 } else if ((codec72==0x8000) && (codec6c==0x0080)) { 583 /* nothing */ 584 } 585 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000); 586 return 0; 587 } 588 589 int patch_sigmatel_stac9721(ac97_t * ac97) 590 { 591 ac97->build_ops = &patch_sigmatel_stac9700_ops; 592 if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) { 593 // patch for SigmaTel 594 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba); 595 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x4000); 596 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba); 597 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002); 598 } 599 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000); 600 return 0; 601 } 602 603 int patch_sigmatel_stac9744(ac97_t * ac97) 604 { 605 // patch for SigmaTel 606 ac97->build_ops = &patch_sigmatel_stac9700_ops; 607 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba); 608 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000); /* is this correct? --jk */ 609 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba); 610 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002); 611 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000); 612 return 0; 613 } 614 615 int patch_sigmatel_stac9756(ac97_t * ac97) 616 { 617 // patch for SigmaTel 618 ac97->build_ops = &patch_sigmatel_stac9700_ops; 619 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC1, 0xabba); 620 snd_ac97_write_cache(ac97, AC97_SIGMATEL_CIC2, 0x0000); /* is this correct? --jk */ 621 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS1, 0xabba); 622 snd_ac97_write_cache(ac97, AC97_SIGMATEL_BIAS2, 0x0002); 623 snd_ac97_write_cache(ac97, AC97_SIGMATEL_MULTICHN, 0x0000); 624 return 0; 625 } 626 627 static int snd_ac97_stac9758_output_jack_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 628 { 629 static char *texts[5] = { "Input/Disabled", "Front Output", 630 "Rear Output", "Center/LFE Output", "Mixer Output" }; 631 632 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 633 uinfo->count = 1; 634 uinfo->value.enumerated.items = 5; 635 if (uinfo->value.enumerated.item > 4) 636 uinfo->value.enumerated.item = 4; 637 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 638 return 0; 639 } 640 641 static int snd_ac97_stac9758_output_jack_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol) 642 { 643 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 644 int shift = kcontrol->private_value; 645 unsigned short val; 646 647 val = ac97->regs[AC97_SIGMATEL_OUTSEL] >> shift; 648 if (!(val & 4)) 649 ucontrol->value.enumerated.item[0] = 0; 650 else 651 ucontrol->value.enumerated.item[0] = 1 + (val & 3); 652 return 0; 653 } 654 655 static int snd_ac97_stac9758_output_jack_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 656 { 657 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 658 int shift = kcontrol->private_value; 659 unsigned short val; 660 661 if (ucontrol->value.enumerated.item[0] > 4) 662 return -EINVAL; 663 if (ucontrol->value.enumerated.item[0] == 0) 664 val = 0; 665 else 666 val = 4 | (ucontrol->value.enumerated.item[0] - 1); 667 return ac97_update_bits_page(ac97, AC97_SIGMATEL_OUTSEL, 668 7 << shift, val << shift, 0); 669 } 670 671 static int snd_ac97_stac9758_input_jack_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 672 { 673 static char *texts[7] = { "Mic2 Jack", "Mic1 Jack", "Line In Jack", 674 "Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" }; 675 676 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 677 uinfo->count = 1; 678 uinfo->value.enumerated.items = 7; 679 if (uinfo->value.enumerated.item > 6) 680 uinfo->value.enumerated.item = 6; 681 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 682 return 0; 683 } 684 685 static int snd_ac97_stac9758_input_jack_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol) 686 { 687 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 688 int shift = kcontrol->private_value; 689 unsigned short val; 690 691 val = ac97->regs[AC97_SIGMATEL_INSEL]; 692 ucontrol->value.enumerated.item[0] = (val >> shift) & 7; 693 return 0; 694 } 695 696 static int snd_ac97_stac9758_input_jack_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 697 { 698 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 699 int shift = kcontrol->private_value; 700 701 return ac97_update_bits_page(ac97, AC97_SIGMATEL_INSEL, 7 << shift, 702 ucontrol->value.enumerated.item[0] << shift, 0); 703 } 704 705 static int snd_ac97_stac9758_phonesel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 706 { 707 static char *texts[3] = { "None", "Front Jack", "Rear Jack" }; 708 709 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 710 uinfo->count = 1; 711 uinfo->value.enumerated.items = 3; 712 if (uinfo->value.enumerated.item > 2) 713 uinfo->value.enumerated.item = 2; 714 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 715 return 0; 716 } 717 718 static int snd_ac97_stac9758_phonesel_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol) 719 { 720 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 721 722 ucontrol->value.enumerated.item[0] = ac97->regs[AC97_SIGMATEL_IOMISC] & 3; 723 return 0; 724 } 725 726 static int snd_ac97_stac9758_phonesel_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 727 { 728 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 729 730 return ac97_update_bits_page(ac97, AC97_SIGMATEL_IOMISC, 3, 731 ucontrol->value.enumerated.item[0], 0); 732 } 733 734 #define STAC9758_OUTPUT_JACK(xname, shift) \ 735 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 736 .info = snd_ac97_stac9758_output_jack_info, \ 737 .get = snd_ac97_stac9758_output_jack_get, \ 738 .put = snd_ac97_stac9758_output_jack_put, \ 739 .private_value = shift } 740 #define STAC9758_INPUT_JACK(xname, shift) \ 741 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 742 .info = snd_ac97_stac9758_input_jack_info, \ 743 .get = snd_ac97_stac9758_input_jack_get, \ 744 .put = snd_ac97_stac9758_input_jack_put, \ 745 .private_value = shift } 746 static const snd_kcontrol_new_t snd_ac97_sigmatel_stac9758_controls[] = { 747 STAC9758_OUTPUT_JACK("Mic1 Jack", 1), 748 STAC9758_OUTPUT_JACK("LineIn Jack", 4), 749 STAC9758_OUTPUT_JACK("Front Jack", 7), 750 STAC9758_OUTPUT_JACK("Rear Jack", 10), 751 STAC9758_OUTPUT_JACK("Center/LFE Jack", 13), 752 STAC9758_INPUT_JACK("Mic Input Source", 0), 753 STAC9758_INPUT_JACK("Line Input Source", 8), 754 { 755 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 756 .name = "Headphone Amp", 757 .info = snd_ac97_stac9758_phonesel_info, 758 .get = snd_ac97_stac9758_phonesel_get, 759 .put = snd_ac97_stac9758_phonesel_put 760 }, 761 AC97_SINGLE("Exchange Center/LFE", AC97_SIGMATEL_IOMISC, 4, 1, 0), 762 AC97_SINGLE("Headphone +3dB Boost", AC97_SIGMATEL_IOMISC, 8, 1, 0) 763 }; 764 765 static int patch_sigmatel_stac9758_specific(ac97_t *ac97) 766 { 767 int err; 768 769 err = patch_sigmatel_stac97xx_specific(ac97); 770 if (err < 0) 771 return err; 772 err = patch_build_controls(ac97, snd_ac97_sigmatel_stac9758_controls, 773 ARRAY_SIZE(snd_ac97_sigmatel_stac9758_controls)); 774 if (err < 0) 775 return err; 776 /* DAC-A direct */ 777 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Front Playback"); 778 /* DAC-A to Mix = PCM */ 779 /* DAC-B direct = Surround */ 780 /* DAC-B to Mix */ 781 snd_ac97_rename_vol_ctl(ac97, "Video Playback", "Surround Mix Playback"); 782 /* DAC-C direct = Center/LFE */ 783 784 return 0; 785 } 786 787 static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { 788 .build_3d = patch_sigmatel_stac9700_3d, 789 .build_specific = patch_sigmatel_stac9758_specific 790 }; 791 792 int patch_sigmatel_stac9758(ac97_t * ac97) 793 { 794 static unsigned short regs[4] = { 795 AC97_SIGMATEL_OUTSEL, 796 AC97_SIGMATEL_IOMISC, 797 AC97_SIGMATEL_INSEL, 798 AC97_SIGMATEL_VARIOUS 799 }; 800 static unsigned short def_regs[4] = { 801 /* OUTSEL */ 0xd794, /* CL:CL, SR:SR, LO:MX, LI:DS, MI:DS */ 802 /* IOMISC */ 0x2001, 803 /* INSEL */ 0x0201, /* LI:LI, MI:M1 */ 804 /* VARIOUS */ 0x0040 805 }; 806 static unsigned short m675_regs[4] = { 807 /* OUTSEL */ 0xfc70, /* CL:MX, SR:MX, LO:DS, LI:MX, MI:DS */ 808 /* IOMISC */ 0x2102, /* HP amp on */ 809 /* INSEL */ 0x0203, /* LI:LI, MI:FR */ 810 /* VARIOUS */ 0x0041 /* stereo mic */ 811 }; 812 unsigned short *pregs = def_regs; 813 int i; 814 815 /* Gateway M675 notebook */ 816 if (ac97->pci && 817 ac97->subsystem_vendor == 0x107b && 818 ac97->subsystem_device == 0x0601) 819 pregs = m675_regs; 820 821 // patch for SigmaTel 822 ac97->build_ops = &patch_sigmatel_stac9758_ops; 823 /* FIXME: assume only page 0 for writing cache */ 824 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR); 825 for (i = 0; i < 4; i++) 826 snd_ac97_write_cache(ac97, regs[i], pregs[i]); 827 828 ac97->flags |= AC97_STEREO_MUTES; 829 return 0; 830 } 831 832 /* 833 * Cirrus Logic CS42xx codecs 834 */ 835 static const snd_kcontrol_new_t snd_ac97_cirrus_controls_spdif[2] = { 836 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CSR_SPDIF, 15, 1, 0), 837 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA", AC97_CSR_ACMODE, 0, 3, 0) 838 }; 839 840 static int patch_cirrus_build_spdif(ac97_t * ac97) 841 { 842 int err; 843 844 /* con mask, pro mask, default */ 845 if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0) 846 return err; 847 /* switch, spsa */ 848 if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[0], 1)) < 0) 849 return err; 850 switch (ac97->id & AC97_ID_CS_MASK) { 851 case AC97_ID_CS4205: 852 if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[1], 1)) < 0) 853 return err; 854 break; 855 } 856 /* set default PCM S/PDIF params */ 857 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */ 858 snd_ac97_write_cache(ac97, AC97_CSR_SPDIF, 0x0a20); 859 return 0; 860 } 861 862 static struct snd_ac97_build_ops patch_cirrus_ops = { 863 .build_spdif = patch_cirrus_build_spdif 864 }; 865 866 int patch_cirrus_spdif(ac97_t * ac97) 867 { 868 /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers. 869 WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh* 870 - sp/dif EA ID is not set, but sp/dif is always present. 871 - enable/disable is spdif register bit 15. 872 - sp/dif control register is 0x68. differs from AC97: 873 - valid is bit 14 (vs 15) 874 - no DRS 875 - only 44.1/48k [00 = 48, 01=44,1] (AC97 is 00=44.1, 10=48) 876 - sp/dif ssource select is in 0x5e bits 0,1. 877 */ 878 879 ac97->build_ops = &patch_cirrus_ops; 880 ac97->flags |= AC97_CS_SPDIF; 881 ac97->rates[AC97_RATES_SPDIF] &= ~SNDRV_PCM_RATE_32000; 882 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ 883 snd_ac97_write_cache(ac97, AC97_CSR_ACMODE, 0x0080); 884 return 0; 885 } 886 887 int patch_cirrus_cs4299(ac97_t * ac97) 888 { 889 /* force the detection of PC Beep */ 890 ac97->flags |= AC97_HAS_PC_BEEP; 891 892 return patch_cirrus_spdif(ac97); 893 } 894 895 /* 896 * Conexant codecs 897 */ 898 static const snd_kcontrol_new_t snd_ac97_conexant_controls_spdif[1] = { 899 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CXR_AUDIO_MISC, 3, 1, 0), 900 }; 901 902 static int patch_conexant_build_spdif(ac97_t * ac97) 903 { 904 int err; 905 906 /* con mask, pro mask, default */ 907 if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0) 908 return err; 909 /* switch */ 910 if ((err = patch_build_controls(ac97, &snd_ac97_conexant_controls_spdif[0], 1)) < 0) 911 return err; 912 /* set default PCM S/PDIF params */ 913 /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */ 914 snd_ac97_write_cache(ac97, AC97_CXR_AUDIO_MISC, 915 snd_ac97_read(ac97, AC97_CXR_AUDIO_MISC) & ~(AC97_CXR_SPDIFEN|AC97_CXR_COPYRGT|AC97_CXR_SPDIF_MASK)); 916 return 0; 917 } 918 919 static struct snd_ac97_build_ops patch_conexant_ops = { 920 .build_spdif = patch_conexant_build_spdif 921 }; 922 923 int patch_conexant(ac97_t * ac97) 924 { 925 ac97->build_ops = &patch_conexant_ops; 926 ac97->flags |= AC97_CX_SPDIF; 927 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ 928 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ 929 return 0; 930 } 931 932 /* 933 * Analog Device AD18xx, AD19xx codecs 934 */ 935 #ifdef CONFIG_PM 936 static void ad18xx_resume(ac97_t *ac97) 937 { 938 static unsigned short setup_regs[] = { 939 AC97_AD_MISC, AC97_AD_SERIAL_CFG, AC97_AD_JACK_SPDIF, 940 }; 941 int i, codec; 942 943 for (i = 0; i < (int)ARRAY_SIZE(setup_regs); i++) { 944 unsigned short reg = setup_regs[i]; 945 if (test_bit(reg, ac97->reg_accessed)) { 946 snd_ac97_write(ac97, reg, ac97->regs[reg]); 947 snd_ac97_read(ac97, reg); 948 } 949 } 950 951 if (! (ac97->flags & AC97_AD_MULTI)) 952 /* normal restore */ 953 snd_ac97_restore_status(ac97); 954 else { 955 /* restore the AD18xx codec configurations */ 956 for (codec = 0; codec < 3; codec++) { 957 if (! ac97->spec.ad18xx.id[codec]) 958 continue; 959 /* select single codec */ 960 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 961 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]); 962 ac97->bus->ops->write(ac97, AC97_AD_CODEC_CFG, ac97->spec.ad18xx.codec_cfg[codec]); 963 } 964 /* select all codecs */ 965 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000); 966 967 /* restore status */ 968 for (i = 2; i < 0x7c ; i += 2) { 969 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID) 970 continue; 971 if (test_bit(i, ac97->reg_accessed)) { 972 /* handle multi codecs for AD18xx */ 973 if (i == AC97_PCM) { 974 for (codec = 0; codec < 3; codec++) { 975 if (! ac97->spec.ad18xx.id[codec]) 976 continue; 977 /* select single codec */ 978 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 979 ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]); 980 /* update PCM bits */ 981 ac97->bus->ops->write(ac97, AC97_PCM, ac97->spec.ad18xx.pcmreg[codec]); 982 } 983 /* select all codecs */ 984 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000); 985 continue; 986 } else if (i == AC97_AD_TEST || 987 i == AC97_AD_CODEC_CFG || 988 i == AC97_AD_SERIAL_CFG) 989 continue; /* ignore */ 990 } 991 snd_ac97_write(ac97, i, ac97->regs[i]); 992 snd_ac97_read(ac97, i); 993 } 994 } 995 996 snd_ac97_restore_iec958(ac97); 997 } 998 #endif 999 1000 int patch_ad1819(ac97_t * ac97) 1001 { 1002 unsigned short scfg; 1003 1004 // patch for Analog Devices 1005 scfg = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG); 1006 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x7000); /* select all codecs */ 1007 return 0; 1008 } 1009 1010 static unsigned short patch_ad1881_unchained(ac97_t * ac97, int idx, unsigned short mask) 1011 { 1012 unsigned short val; 1013 1014 // test for unchained codec 1015 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, mask); 1016 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000); /* ID0C, ID1C, SDIE = off */ 1017 val = snd_ac97_read(ac97, AC97_VENDOR_ID2); 1018 if ((val & 0xff40) != 0x5340) 1019 return 0; 1020 ac97->spec.ad18xx.unchained[idx] = mask; 1021 ac97->spec.ad18xx.id[idx] = val; 1022 ac97->spec.ad18xx.codec_cfg[idx] = 0x0000; 1023 return mask; 1024 } 1025 1026 static int patch_ad1881_chained1(ac97_t * ac97, int idx, unsigned short codec_bits) 1027 { 1028 static int cfg_bits[3] = { 1<<12, 1<<14, 1<<13 }; 1029 unsigned short val; 1030 1031 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, cfg_bits[idx]); 1032 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0004); // SDIE 1033 val = snd_ac97_read(ac97, AC97_VENDOR_ID2); 1034 if ((val & 0xff40) != 0x5340) 1035 return 0; 1036 if (codec_bits) 1037 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, codec_bits); 1038 ac97->spec.ad18xx.chained[idx] = cfg_bits[idx]; 1039 ac97->spec.ad18xx.id[idx] = val; 1040 ac97->spec.ad18xx.codec_cfg[idx] = codec_bits ? codec_bits : 0x0004; 1041 return 1; 1042 } 1043 1044 static void patch_ad1881_chained(ac97_t * ac97, int unchained_idx, int cidx1, int cidx2) 1045 { 1046 // already detected? 1047 if (ac97->spec.ad18xx.unchained[cidx1] || ac97->spec.ad18xx.chained[cidx1]) 1048 cidx1 = -1; 1049 if (ac97->spec.ad18xx.unchained[cidx2] || ac97->spec.ad18xx.chained[cidx2]) 1050 cidx2 = -1; 1051 if (cidx1 < 0 && cidx2 < 0) 1052 return; 1053 // test for chained codecs 1054 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 1055 ac97->spec.ad18xx.unchained[unchained_idx]); 1056 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0002); // ID1C 1057 ac97->spec.ad18xx.codec_cfg[unchained_idx] = 0x0002; 1058 if (cidx1 >= 0) { 1059 if (patch_ad1881_chained1(ac97, cidx1, 0x0006)) // SDIE | ID1C 1060 patch_ad1881_chained1(ac97, cidx2, 0); 1061 else if (patch_ad1881_chained1(ac97, cidx2, 0x0006)) // SDIE | ID1C 1062 patch_ad1881_chained1(ac97, cidx1, 0); 1063 } else if (cidx2 >= 0) { 1064 patch_ad1881_chained1(ac97, cidx2, 0); 1065 } 1066 } 1067 1068 static struct snd_ac97_build_ops patch_ad1881_build_ops = { 1069 #ifdef CONFIG_PM 1070 .resume = ad18xx_resume 1071 #endif 1072 }; 1073 1074 int patch_ad1881(ac97_t * ac97) 1075 { 1076 static const char cfg_idxs[3][2] = { 1077 {2, 1}, 1078 {0, 2}, 1079 {0, 1} 1080 }; 1081 1082 // patch for Analog Devices 1083 unsigned short codecs[3]; 1084 unsigned short val; 1085 int idx, num; 1086 1087 val = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG); 1088 snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, val); 1089 codecs[0] = patch_ad1881_unchained(ac97, 0, (1<<12)); 1090 codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14)); 1091 codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13)); 1092 1093 snd_runtime_check(codecs[0] | codecs[1] | codecs[2], goto __end); 1094 1095 for (idx = 0; idx < 3; idx++) 1096 if (ac97->spec.ad18xx.unchained[idx]) 1097 patch_ad1881_chained(ac97, idx, cfg_idxs[idx][0], cfg_idxs[idx][1]); 1098 1099 if (ac97->spec.ad18xx.id[1]) { 1100 ac97->flags |= AC97_AD_MULTI; 1101 ac97->scaps |= AC97_SCAP_SURROUND_DAC; 1102 } 1103 if (ac97->spec.ad18xx.id[2]) { 1104 ac97->flags |= AC97_AD_MULTI; 1105 ac97->scaps |= AC97_SCAP_CENTER_LFE_DAC; 1106 } 1107 1108 __end: 1109 /* select all codecs */ 1110 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000); 1111 /* check if only one codec is present */ 1112 for (idx = num = 0; idx < 3; idx++) 1113 if (ac97->spec.ad18xx.id[idx]) 1114 num++; 1115 if (num == 1) { 1116 /* ok, deselect all ID bits */ 1117 snd_ac97_write_cache(ac97, AC97_AD_CODEC_CFG, 0x0000); 1118 ac97->spec.ad18xx.codec_cfg[0] = 1119 ac97->spec.ad18xx.codec_cfg[1] = 1120 ac97->spec.ad18xx.codec_cfg[2] = 0x0000; 1121 } 1122 /* required for AD1886/AD1885 combination */ 1123 ac97->ext_id = snd_ac97_read(ac97, AC97_EXTENDED_ID); 1124 if (ac97->spec.ad18xx.id[0]) { 1125 ac97->id &= 0xffff0000; 1126 ac97->id |= ac97->spec.ad18xx.id[0]; 1127 } 1128 ac97->build_ops = &patch_ad1881_build_ops; 1129 return 0; 1130 } 1131 1132 static const snd_kcontrol_new_t snd_ac97_controls_ad1885[] = { 1133 AC97_SINGLE("Digital Mono Direct", AC97_AD_MISC, 11, 1, 0), 1134 /* AC97_SINGLE("Digital Audio Mode", AC97_AD_MISC, 12, 1, 0), */ /* seems problematic */ 1135 AC97_SINGLE("Low Power Mixer", AC97_AD_MISC, 14, 1, 0), 1136 AC97_SINGLE("Zero Fill DAC", AC97_AD_MISC, 15, 1, 0), 1137 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 9, 1, 1), /* inverted */ 1138 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 8, 1, 1), /* inverted */ 1139 }; 1140 1141 static int patch_ad1885_specific(ac97_t * ac97) 1142 { 1143 int err; 1144 1145 if ((err = patch_build_controls(ac97, snd_ac97_controls_ad1885, ARRAY_SIZE(snd_ac97_controls_ad1885))) < 0) 1146 return err; 1147 return 0; 1148 } 1149 1150 static struct snd_ac97_build_ops patch_ad1885_build_ops = { 1151 .build_specific = &patch_ad1885_specific, 1152 #ifdef CONFIG_PM 1153 .resume = ad18xx_resume 1154 #endif 1155 }; 1156 1157 int patch_ad1885(ac97_t * ac97) 1158 { 1159 patch_ad1881(ac97); 1160 /* This is required to deal with the Intel D815EEAL2 */ 1161 /* i.e. Line out is actually headphone out from codec */ 1162 1163 /* set default */ 1164 snd_ac97_write_cache(ac97, AC97_AD_MISC, 0x0404); 1165 1166 ac97->build_ops = &patch_ad1885_build_ops; 1167 return 0; 1168 } 1169 1170 int patch_ad1886(ac97_t * ac97) 1171 { 1172 patch_ad1881(ac97); 1173 /* Presario700 workaround */ 1174 /* for Jack Sense/SPDIF Register misetting causing */ 1175 snd_ac97_write_cache(ac97, AC97_AD_JACK_SPDIF, 0x0010); 1176 return 0; 1177 } 1178 1179 /* MISC bits */ 1180 #define AC97_AD198X_MBC 0x0003 /* mic boost */ 1181 #define AC97_AD198X_MBC_20 0x0000 /* +20dB */ 1182 #define AC97_AD198X_MBC_10 0x0001 /* +10dB */ 1183 #define AC97_AD198X_MBC_30 0x0002 /* +30dB */ 1184 #define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */ 1185 #define AC97_AD198X_VREFH 0x0008 /* 2.25V, 3.7V */ 1186 #define AC97_AD198X_VREF_0 0x000c /* 0V */ 1187 #define AC97_AD198X_SRU 0x0010 /* sample rate unlock */ 1188 #define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */ 1189 #define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */ 1190 #define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */ 1191 #define AC97_AD198X_DMIX0 0x0100 /* downmix mode: 0 = 6-to-4, 1 = 6-to-2 downmix */ 1192 #define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */ 1193 #define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */ 1194 #define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */ 1195 #define AC97_AD198X_LODIS 0x1000 /* LINE_OUT disable */ 1196 #define AC97_AD198X_MSPLT 0x2000 /* mute split */ 1197 #define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */ 1198 #define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */ 1199 1200 1201 static int snd_ac97_ad198x_spdif_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 1202 { 1203 static char *texts[2] = { "AC-Link", "A/D Converter" }; 1204 1205 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1206 uinfo->count = 1; 1207 uinfo->value.enumerated.items = 2; 1208 if (uinfo->value.enumerated.item > 1) 1209 uinfo->value.enumerated.item = 1; 1210 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 1211 return 0; 1212 } 1213 1214 static int snd_ac97_ad198x_spdif_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1215 { 1216 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1217 unsigned short val; 1218 1219 val = ac97->regs[AC97_AD_SERIAL_CFG]; 1220 ucontrol->value.enumerated.item[0] = (val >> 2) & 1; 1221 return 0; 1222 } 1223 1224 static int snd_ac97_ad198x_spdif_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1225 { 1226 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1227 unsigned short val; 1228 1229 if (ucontrol->value.enumerated.item[0] > 1) 1230 return -EINVAL; 1231 val = ucontrol->value.enumerated.item[0] << 2; 1232 return snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x0004, val); 1233 } 1234 1235 static const snd_kcontrol_new_t snd_ac97_ad198x_spdif_source = { 1236 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1237 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1238 .info = snd_ac97_ad198x_spdif_source_info, 1239 .get = snd_ac97_ad198x_spdif_source_get, 1240 .put = snd_ac97_ad198x_spdif_source_put, 1241 }; 1242 1243 static int patch_ad198x_post_spdif(ac97_t * ac97) 1244 { 1245 return patch_build_controls(ac97, &snd_ac97_ad198x_spdif_source, 1); 1246 } 1247 1248 static const snd_kcontrol_new_t snd_ac97_ad1981x_jack_sense[] = { 1249 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 11, 1, 0), 1250 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0), 1251 }; 1252 1253 static int patch_ad1981a_specific(ac97_t * ac97) 1254 { 1255 return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense, 1256 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); 1257 } 1258 1259 static struct snd_ac97_build_ops patch_ad1981a_build_ops = { 1260 .build_post_spdif = patch_ad198x_post_spdif, 1261 .build_specific = patch_ad1981a_specific, 1262 #ifdef CONFIG_PM 1263 .resume = ad18xx_resume 1264 #endif 1265 }; 1266 1267 static void check_ad1981_hp_jack_sense(ac97_t *ac97) 1268 { 1269 u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device; 1270 switch (subid) { 1271 case 0x103c0890: /* HP nc6000 */ 1272 case 0x103c006d: /* HP nx9105 */ 1273 case 0x17340088: /* FSC Scenic-W */ 1274 /* enable headphone jack sense */ 1275 snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); 1276 break; 1277 } 1278 } 1279 1280 int patch_ad1981a(ac97_t *ac97) 1281 { 1282 patch_ad1881(ac97); 1283 ac97->build_ops = &patch_ad1981a_build_ops; 1284 snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT); 1285 ac97->flags |= AC97_STEREO_MUTES; 1286 check_ad1981_hp_jack_sense(ac97); 1287 return 0; 1288 } 1289 1290 static const snd_kcontrol_new_t snd_ac97_ad198x_2cmic = 1291 AC97_SINGLE("Stereo Mic", AC97_AD_MISC, 6, 1, 0); 1292 1293 static int patch_ad1981b_specific(ac97_t *ac97) 1294 { 1295 int err; 1296 1297 if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0) 1298 return err; 1299 return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense, 1300 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); 1301 } 1302 1303 static struct snd_ac97_build_ops patch_ad1981b_build_ops = { 1304 .build_post_spdif = patch_ad198x_post_spdif, 1305 .build_specific = patch_ad1981b_specific, 1306 #ifdef CONFIG_PM 1307 .resume = ad18xx_resume 1308 #endif 1309 }; 1310 1311 int patch_ad1981b(ac97_t *ac97) 1312 { 1313 patch_ad1881(ac97); 1314 ac97->build_ops = &patch_ad1981b_build_ops; 1315 snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT); 1316 ac97->flags |= AC97_STEREO_MUTES; 1317 check_ad1981_hp_jack_sense(ac97); 1318 return 0; 1319 } 1320 1321 static int snd_ac97_ad1888_lohpsel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 1322 { 1323 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1324 uinfo->count = 1; 1325 uinfo->value.integer.min = 0; 1326 uinfo->value.integer.max = 1; 1327 return 0; 1328 } 1329 1330 static int snd_ac97_ad1888_lohpsel_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol) 1331 { 1332 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1333 unsigned short val; 1334 1335 val = ac97->regs[AC97_AD_MISC]; 1336 ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL); 1337 return 0; 1338 } 1339 1340 static int snd_ac97_ad1888_lohpsel_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 1341 { 1342 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1343 unsigned short val; 1344 1345 val = !ucontrol->value.integer.value[0] 1346 ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0; 1347 return snd_ac97_update_bits(ac97, AC97_AD_MISC, 1348 AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val); 1349 } 1350 1351 static int snd_ac97_ad1888_downmix_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 1352 { 1353 static char *texts[3] = {"Off", "6 -> 4", "6 -> 2"}; 1354 1355 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1356 uinfo->count = 1; 1357 uinfo->value.enumerated.items = 3; 1358 if (uinfo->value.enumerated.item > 2) 1359 uinfo->value.enumerated.item = 2; 1360 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 1361 return 0; 1362 } 1363 1364 static int snd_ac97_ad1888_downmix_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol) 1365 { 1366 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1367 unsigned short val; 1368 1369 val = ac97->regs[AC97_AD_MISC]; 1370 if (!(val & AC97_AD198X_DMIX1)) 1371 ucontrol->value.enumerated.item[0] = 0; 1372 else 1373 ucontrol->value.enumerated.item[0] = 1 + ((val >> 8) & 1); 1374 return 0; 1375 } 1376 1377 static int snd_ac97_ad1888_downmix_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 1378 { 1379 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1380 unsigned short val; 1381 1382 if (ucontrol->value.enumerated.item[0] > 2) 1383 return -EINVAL; 1384 if (ucontrol->value.enumerated.item[0] == 0) 1385 val = 0; 1386 else 1387 val = AC97_AD198X_DMIX1 | 1388 ((ucontrol->value.enumerated.item[0] - 1) << 8); 1389 return snd_ac97_update_bits(ac97, AC97_AD_MISC, 1390 AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val); 1391 } 1392 1393 static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = { 1394 { 1395 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1396 .name = "Exchange Front/Surround", 1397 .info = snd_ac97_ad1888_lohpsel_info, 1398 .get = snd_ac97_ad1888_lohpsel_get, 1399 .put = snd_ac97_ad1888_lohpsel_put 1400 }, 1401 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0), 1402 { 1403 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1404 .name = "Downmix", 1405 .info = snd_ac97_ad1888_downmix_info, 1406 .get = snd_ac97_ad1888_downmix_get, 1407 .put = snd_ac97_ad1888_downmix_put 1408 }, 1409 AC97_SINGLE("Surround Jack as Input", AC97_AD_MISC, 12, 1, 0), 1410 AC97_SINGLE("Center/LFE Jack as Input", AC97_AD_MISC, 11, 1, 0), 1411 }; 1412 1413 static int patch_ad1888_specific(ac97_t *ac97) 1414 { 1415 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */ 1416 snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Master Surround Playback"); 1417 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback"); 1418 return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls)); 1419 } 1420 1421 static struct snd_ac97_build_ops patch_ad1888_build_ops = { 1422 .build_post_spdif = patch_ad198x_post_spdif, 1423 .build_specific = patch_ad1888_specific, 1424 #ifdef CONFIG_PM 1425 .resume = ad18xx_resume 1426 #endif 1427 }; 1428 1429 int patch_ad1888(ac97_t * ac97) 1430 { 1431 unsigned short misc; 1432 1433 patch_ad1881(ac97); 1434 ac97->build_ops = &patch_ad1888_build_ops; 1435 /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */ 1436 /* it seems that most vendors connect line-out connector to headphone out of AC'97 */ 1437 /* AD-compatible mode */ 1438 /* Stereo mutes enabled */ 1439 misc = snd_ac97_read(ac97, AC97_AD_MISC); 1440 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc | 1441 AC97_AD198X_LOSEL | 1442 AC97_AD198X_HPSEL | 1443 AC97_AD198X_MSPLT | 1444 AC97_AD198X_AC97NC); 1445 ac97->flags |= AC97_STEREO_MUTES; 1446 return 0; 1447 } 1448 1449 static int patch_ad1980_specific(ac97_t *ac97) 1450 { 1451 int err; 1452 1453 if ((err = patch_ad1888_specific(ac97)) < 0) 1454 return err; 1455 return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1); 1456 } 1457 1458 static struct snd_ac97_build_ops patch_ad1980_build_ops = { 1459 .build_post_spdif = patch_ad198x_post_spdif, 1460 .build_specific = patch_ad1980_specific, 1461 #ifdef CONFIG_PM 1462 .resume = ad18xx_resume 1463 #endif 1464 }; 1465 1466 int patch_ad1980(ac97_t * ac97) 1467 { 1468 patch_ad1888(ac97); 1469 ac97->build_ops = &patch_ad1980_build_ops; 1470 return 0; 1471 } 1472 1473 static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = { 1474 AC97_SINGLE("Center/LFE Jack as Mic", AC97_AD_SERIAL_CFG, 9, 1, 0), 1475 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0) 1476 }; 1477 1478 static int patch_ad1985_specific(ac97_t *ac97) 1479 { 1480 int err; 1481 1482 if ((err = patch_ad1980_specific(ac97)) < 0) 1483 return err; 1484 return patch_build_controls(ac97, snd_ac97_ad1985_controls, ARRAY_SIZE(snd_ac97_ad1985_controls)); 1485 } 1486 1487 static struct snd_ac97_build_ops patch_ad1985_build_ops = { 1488 .build_post_spdif = patch_ad198x_post_spdif, 1489 .build_specific = patch_ad1985_specific, 1490 #ifdef CONFIG_PM 1491 .resume = ad18xx_resume 1492 #endif 1493 }; 1494 1495 int patch_ad1985(ac97_t * ac97) 1496 { 1497 unsigned short misc; 1498 1499 patch_ad1881(ac97); 1500 ac97->build_ops = &patch_ad1985_build_ops; 1501 misc = snd_ac97_read(ac97, AC97_AD_MISC); 1502 /* switch front/surround line-out/hp-out */ 1503 /* center/LFE, mic in 3.75V mode */ 1504 /* AD-compatible mode */ 1505 /* Stereo mutes enabled */ 1506 /* in accordance with ADI driver: misc | 0x5c28 */ 1507 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc | 1508 AC97_AD198X_VREFH | 1509 AC97_AD198X_LOSEL | 1510 AC97_AD198X_HPSEL | 1511 AC97_AD198X_CLDIS | 1512 AC97_AD198X_LODIS | 1513 AC97_AD198X_MSPLT | 1514 AC97_AD198X_AC97NC); 1515 ac97->flags |= AC97_STEREO_MUTES; 1516 /* on AD1985 rev. 3, AC'97 revision bits are zero */ 1517 ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23; 1518 return 0; 1519 } 1520 1521 /* 1522 * realtek ALC65x/850 codecs 1523 */ 1524 static int snd_ac97_alc650_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) 1525 { 1526 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1527 ucontrol->value.integer.value[0] = (ac97->regs[AC97_ALC650_MULTICH] >> 10) & 1; 1528 return 0; 1529 } 1530 1531 static int snd_ac97_alc650_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) 1532 { 1533 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1534 int change, val; 1535 val = !!(snd_ac97_read(ac97, AC97_ALC650_MULTICH) & (1 << 10)); 1536 change = (ucontrol->value.integer.value[0] != val); 1537 if (change) { 1538 /* disable/enable vref */ 1539 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, 1540 ucontrol->value.integer.value[0] ? (1 << 12) : 0); 1541 /* turn on/off center-on-mic */ 1542 snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10, 1543 ucontrol->value.integer.value[0] ? (1 << 10) : 0); 1544 /* GPIO0 high for mic */ 1545 snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100, 1546 ucontrol->value.integer.value[0] ? 0 : 0x100); 1547 } 1548 return change; 1549 } 1550 1551 static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = { 1552 AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0), 1553 AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0), 1554 AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH, 2, 1, 0), 1555 AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH, 3, 1, 0), 1556 /* 4: Analog Input To Surround */ 1557 /* 5: Analog Input To Center/LFE */ 1558 /* 6: Independent Master Volume Right */ 1559 /* 7: Independent Master Volume Left */ 1560 /* 8: reserved */ 1561 AC97_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0), 1562 /* 10: mic, see below */ 1563 /* 11-13: in IEC958 controls */ 1564 AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0), 1565 #if 0 /* always set in patch_alc650 */ 1566 AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0), 1567 AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0), 1568 AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL, 15, 1, 1), 1569 AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL, 8, 0, 31, 1), 1570 AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL, 15, 1, 1), 1571 AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL, 8, 0, 31, 1), 1572 #endif 1573 { 1574 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1575 .name = "Mic As Center/LFE", 1576 .info = snd_ac97_info_volsw, 1577 .get = snd_ac97_alc650_mic_get, 1578 .put = snd_ac97_alc650_mic_put, 1579 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ 1580 }, 1581 }; 1582 1583 static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = { 1584 AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0), 1585 AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0), 1586 /* disable this controls since it doesn't work as expected */ 1587 /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */ 1588 }; 1589 1590 static int patch_alc650_specific(ac97_t * ac97) 1591 { 1592 int err; 1593 1594 if ((err = patch_build_controls(ac97, snd_ac97_controls_alc650, ARRAY_SIZE(snd_ac97_controls_alc650))) < 0) 1595 return err; 1596 if (ac97->ext_id & AC97_EI_SPDIF) { 1597 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc650, ARRAY_SIZE(snd_ac97_spdif_controls_alc650))) < 0) 1598 return err; 1599 } 1600 return 0; 1601 } 1602 1603 static struct snd_ac97_build_ops patch_alc650_ops = { 1604 .build_specific = patch_alc650_specific 1605 }; 1606 1607 int patch_alc650(ac97_t * ac97) 1608 { 1609 unsigned short val; 1610 1611 ac97->build_ops = &patch_alc650_ops; 1612 1613 /* determine the revision */ 1614 val = snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f; 1615 if (val < 3) 1616 ac97->id = 0x414c4720; /* Old version */ 1617 else if (val < 0x10) 1618 ac97->id = 0x414c4721; /* D version */ 1619 else if (val < 0x20) 1620 ac97->id = 0x414c4722; /* E version */ 1621 else if (val < 0x30) 1622 ac97->id = 0x414c4723; /* F version */ 1623 1624 /* revision E or F */ 1625 /* FIXME: what about revision D ? */ 1626 ac97->spec.dev_flags = (ac97->id == 0x414c4722 || 1627 ac97->id == 0x414c4723); 1628 1629 /* enable AC97_ALC650_GPIO_SETUP, AC97_ALC650_CLOCK for R/W */ 1630 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS, 1631 snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x8000); 1632 1633 /* Enable SPDIF-IN only on Rev.E and above */ 1634 val = snd_ac97_read(ac97, AC97_ALC650_CLOCK); 1635 /* SPDIF IN with pin 47 */ 1636 if (ac97->spec.dev_flags) 1637 val |= 0x03; /* enable */ 1638 else 1639 val &= ~0x03; /* disable */ 1640 snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK, val); 1641 1642 /* set default: slot 3,4,7,8,6,9 1643 spdif-in monitor off, analog-spdif off, spdif-in off 1644 center on mic off, surround on line-in off 1645 downmix off, duplicate front off 1646 */ 1647 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 0); 1648 1649 /* set GPIO0 for mic bias */ 1650 /* GPIO0 pin output, no interrupt, high */ 1651 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_SETUP, 1652 snd_ac97_read(ac97, AC97_ALC650_GPIO_SETUP) | 0x01); 1653 snd_ac97_write_cache(ac97, AC97_ALC650_GPIO_STATUS, 1654 (snd_ac97_read(ac97, AC97_ALC650_GPIO_STATUS) | 0x100) & ~0x10); 1655 1656 /* full DAC volume */ 1657 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808); 1658 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808); 1659 return 0; 1660 } 1661 1662 static int snd_ac97_alc655_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) 1663 { 1664 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1665 ucontrol->value.integer.value[0] = (ac97->regs[AC97_ALC650_MULTICH] >> 10) & 1; 1666 return 0; 1667 } 1668 1669 static int snd_ac97_alc655_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) 1670 { 1671 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1672 1673 /* misc control; vrefout disable */ 1674 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, 1675 ucontrol->value.integer.value[0] ? (1 << 12) : 0); 1676 return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10, 1677 ucontrol->value.integer.value[0] ? (1 << 10) : 0, 1678 0); 1679 } 1680 1681 1682 static const snd_kcontrol_new_t snd_ac97_controls_alc655[] = { 1683 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0), 1684 AC97_PAGE_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0, 0), 1685 { 1686 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1687 .name = "Mic As Center/LFE", 1688 .info = snd_ac97_info_volsw, 1689 .get = snd_ac97_alc655_mic_get, 1690 .put = snd_ac97_alc655_mic_put, 1691 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ 1692 }, 1693 }; 1694 1695 static int alc655_iec958_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 1696 { 1697 static char *texts_655[3] = { "PCM", "Analog In", "IEC958 In" }; 1698 static char *texts_658[4] = { "PCM", "Analog1 In", "Analog2 In", "IEC958 In" }; 1699 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1700 1701 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1702 uinfo->count = 1; 1703 uinfo->value.enumerated.items = ac97->spec.dev_flags ? 4 : 3; 1704 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1705 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 1706 strcpy(uinfo->value.enumerated.name, 1707 ac97->spec.dev_flags ? 1708 texts_658[uinfo->value.enumerated.item] : 1709 texts_655[uinfo->value.enumerated.item]); 1710 return 0; 1711 } 1712 1713 static int alc655_iec958_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 1714 { 1715 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1716 unsigned short val; 1717 1718 val = ac97->regs[AC97_ALC650_MULTICH]; 1719 val = (val >> 12) & 3; 1720 if (ac97->spec.dev_flags && val == 3) 1721 val = 0; 1722 ucontrol->value.enumerated.item[0] = val; 1723 return 0; 1724 } 1725 1726 static int alc655_iec958_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 1727 { 1728 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1729 1730 return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 3 << 12, 1731 (unsigned short)ucontrol->value.enumerated.item[0] << 12, 1732 0); 1733 } 1734 1735 static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = { 1736 AC97_PAGE_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0, 0), 1737 /* disable this controls since it doesn't work as expected */ 1738 /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */ 1739 { 1740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1741 .name = "IEC958 Playback Route", 1742 .info = alc655_iec958_route_info, 1743 .get = alc655_iec958_route_get, 1744 .put = alc655_iec958_route_put, 1745 }, 1746 }; 1747 1748 static int patch_alc655_specific(ac97_t * ac97) 1749 { 1750 int err; 1751 1752 if ((err = patch_build_controls(ac97, snd_ac97_controls_alc655, ARRAY_SIZE(snd_ac97_controls_alc655))) < 0) 1753 return err; 1754 if (ac97->ext_id & AC97_EI_SPDIF) { 1755 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0) 1756 return err; 1757 } 1758 return 0; 1759 } 1760 1761 static struct snd_ac97_build_ops patch_alc655_ops = { 1762 .build_specific = patch_alc655_specific 1763 }; 1764 1765 int patch_alc655(ac97_t * ac97) 1766 { 1767 unsigned int val; 1768 1769 ac97->spec.dev_flags = (ac97->id == 0x414c4780); /* ALC658 */ 1770 1771 ac97->build_ops = &patch_alc655_ops; 1772 1773 /* assume only page 0 for writing cache */ 1774 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR); 1775 1776 /* adjust default values */ 1777 val = snd_ac97_read(ac97, 0x7a); /* misc control */ 1778 if (ac97->id == 0x414c4780) /* ALC658 */ 1779 val &= ~(1 << 1); /* Pin 47 is spdif input pin */ 1780 else /* ALC655 */ 1781 val |= (1 << 1); /* Pin 47 is spdif input pin */ 1782 val &= ~(1 << 12); /* vref enable */ 1783 snd_ac97_write_cache(ac97, 0x7a, val); 1784 /* set default: spdif-in enabled, 1785 spdif-in monitor off, spdif-in PCM off 1786 center on mic off, surround on line-in off 1787 duplicate front off 1788 */ 1789 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15); 1790 1791 /* full DAC volume */ 1792 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808); 1793 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808); 1794 return 0; 1795 } 1796 1797 1798 #define AC97_ALC850_JACK_SELECT 0x76 1799 #define AC97_ALC850_MISC1 0x7a 1800 1801 static int ac97_alc850_surround_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) 1802 { 1803 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1804 ucontrol->value.integer.value[0] = ((ac97->regs[AC97_ALC850_JACK_SELECT] >> 12) & 7) == 2; 1805 return 0; 1806 } 1807 1808 static int ac97_alc850_surround_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) 1809 { 1810 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1811 1812 /* SURR 1kOhm (bit4), Amp (bit5) */ 1813 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5), 1814 ucontrol->value.integer.value[0] ? (1<<5) : (1<<4)); 1815 /* LINE-IN = 0, SURROUND = 2 */ 1816 return snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12, 1817 ucontrol->value.integer.value[0] ? (2<<12) : (0<<12)); 1818 } 1819 1820 static int ac97_alc850_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) 1821 { 1822 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1823 ucontrol->value.integer.value[0] = ((ac97->regs[AC97_ALC850_JACK_SELECT] >> 4) & 7) == 2; 1824 return 0; 1825 } 1826 1827 static int ac97_alc850_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) 1828 { 1829 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1830 1831 /* Vref disable (bit12), 1kOhm (bit13) */ 1832 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13), 1833 ucontrol->value.integer.value[0] ? (1<<12) : (1<<13)); 1834 /* MIC-IN = 1, CENTER-LFE = 2 */ 1835 return snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4, 1836 ucontrol->value.integer.value[0] ? (2<<4) : (1<<4)); 1837 } 1838 1839 static const snd_kcontrol_new_t snd_ac97_controls_alc850[] = { 1840 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0), 1841 { 1842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1843 .name = "Line-In As Surround", 1844 .info = snd_ac97_info_volsw, 1845 .get = ac97_alc850_surround_get, 1846 .put = ac97_alc850_surround_put, 1847 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ 1848 }, 1849 { 1850 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1851 .name = "Mic As Center/LFE", 1852 .info = snd_ac97_info_volsw, 1853 .get = ac97_alc850_mic_get, 1854 .put = ac97_alc850_mic_put, 1855 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ 1856 }, 1857 1858 }; 1859 1860 static int patch_alc850_specific(ac97_t *ac97) 1861 { 1862 int err; 1863 1864 if ((err = patch_build_controls(ac97, snd_ac97_controls_alc850, ARRAY_SIZE(snd_ac97_controls_alc850))) < 0) 1865 return err; 1866 if (ac97->ext_id & AC97_EI_SPDIF) { 1867 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0) 1868 return err; 1869 } 1870 return 0; 1871 } 1872 1873 static struct snd_ac97_build_ops patch_alc850_ops = { 1874 .build_specific = patch_alc850_specific 1875 }; 1876 1877 int patch_alc850(ac97_t *ac97) 1878 { 1879 ac97->build_ops = &patch_alc850_ops; 1880 1881 ac97->spec.dev_flags = 0; /* for IEC958 playback route - ALC655 compatible */ 1882 1883 /* assume only page 0 for writing cache */ 1884 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR); 1885 1886 /* adjust default values */ 1887 /* set default: spdif-in enabled, 1888 spdif-in monitor off, spdif-in PCM off 1889 center on mic off, surround on line-in off 1890 duplicate front off 1891 */ 1892 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15); 1893 /* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off 1894 * Front Amp: on, Vref: enable, Center 1kOhm: on, Mix: on 1895 */ 1896 snd_ac97_write_cache(ac97, 0x7a, (1<<1)|(1<<4)|(0<<5)|(1<<6)| 1897 (1<<7)|(0<<12)|(1<<13)|(0<<14)); 1898 /* detection UIO2,3: all path floating, UIO3: MIC, Vref2: disable, 1899 * UIO1: FRONT, Vref3: disable, UIO3: LINE, Front-Mic: mute 1900 */ 1901 snd_ac97_write_cache(ac97, 0x76, (0<<0)|(0<<2)|(1<<4)|(1<<7)|(2<<8)| 1902 (1<<11)|(0<<12)|(1<<15)); 1903 1904 /* full DAC volume */ 1905 snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808); 1906 snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808); 1907 return 0; 1908 } 1909 1910 1911 /* 1912 * C-Media CM97xx codecs 1913 */ 1914 static const snd_kcontrol_new_t snd_ac97_cm9738_controls[] = { 1915 AC97_SINGLE("Line-In As Surround", AC97_CM9738_VENDOR_CTRL, 10, 1, 0), 1916 AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL, 13, 1, 0), 1917 }; 1918 1919 static int patch_cm9738_specific(ac97_t * ac97) 1920 { 1921 return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls)); 1922 } 1923 1924 static struct snd_ac97_build_ops patch_cm9738_ops = { 1925 .build_specific = patch_cm9738_specific 1926 }; 1927 1928 int patch_cm9738(ac97_t * ac97) 1929 { 1930 ac97->build_ops = &patch_cm9738_ops; 1931 /* FIXME: can anyone confirm below? */ 1932 /* CM9738 has no PCM volume although the register reacts */ 1933 ac97->flags |= AC97_HAS_NO_PCM_VOL; 1934 snd_ac97_write_cache(ac97, AC97_PCM, 0x8000); 1935 1936 return 0; 1937 } 1938 1939 static int snd_ac97_cmedia_spdif_playback_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 1940 { 1941 static char *texts[] = { "Analog", "Digital" }; 1942 1943 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1944 uinfo->count = 1; 1945 uinfo->value.enumerated.items = 2; 1946 if (uinfo->value.enumerated.item > 1) 1947 uinfo->value.enumerated.item = 1; 1948 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 1949 return 0; 1950 } 1951 1952 static int snd_ac97_cmedia_spdif_playback_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1953 { 1954 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1955 unsigned short val; 1956 1957 val = ac97->regs[AC97_CM9739_SPDIF_CTRL]; 1958 ucontrol->value.enumerated.item[0] = (val >> 1) & 0x01; 1959 return 0; 1960 } 1961 1962 static int snd_ac97_cmedia_spdif_playback_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1963 { 1964 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1965 1966 return snd_ac97_update_bits(ac97, AC97_CM9739_SPDIF_CTRL, 1967 0x01 << 1, 1968 (ucontrol->value.enumerated.item[0] & 0x01) << 1); 1969 } 1970 1971 static const snd_kcontrol_new_t snd_ac97_cm9739_controls_spdif[] = { 1972 /* BIT 0: SPDI_EN - always true */ 1973 { /* BIT 1: SPDIFS */ 1974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1975 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1976 .info = snd_ac97_cmedia_spdif_playback_source_info, 1977 .get = snd_ac97_cmedia_spdif_playback_source_get, 1978 .put = snd_ac97_cmedia_spdif_playback_source_put, 1979 }, 1980 /* BIT 2: IG_SPIV */ 1981 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9739_SPDIF_CTRL, 2, 1, 0), 1982 /* BIT 3: SPI2F */ 1983 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9739_SPDIF_CTRL, 3, 1, 0), 1984 /* BIT 4: SPI2SDI */ 1985 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9739_SPDIF_CTRL, 4, 1, 0), 1986 /* BIT 8: SPD32 - 32bit SPDIF - not supported yet */ 1987 }; 1988 1989 static int snd_ac97_cm9739_center_mic_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1990 { 1991 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 1992 if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x1000) 1993 ucontrol->value.integer.value[0] = 1; 1994 else 1995 ucontrol->value.integer.value[0] = 0; 1996 return 0; 1997 } 1998 1999 static int snd_ac97_cm9739_center_mic_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 2000 { 2001 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 2002 return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000, 2003 ucontrol->value.integer.value[0] ? 2004 0x1000 : 0x2000); 2005 } 2006 2007 static const snd_kcontrol_new_t snd_ac97_cm9739_controls[] = { 2008 AC97_SINGLE("Line-In As Surround", AC97_CM9739_MULTI_CHAN, 10, 1, 0), 2009 { 2010 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2011 .name = "Mic As Center/LFE", 2012 .info = snd_ac97_info_volsw, 2013 .get = snd_ac97_cm9739_center_mic_get, 2014 .put = snd_ac97_cm9739_center_mic_put, 2015 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ 2016 }, 2017 }; 2018 2019 static int patch_cm9739_specific(ac97_t * ac97) 2020 { 2021 return patch_build_controls(ac97, snd_ac97_cm9739_controls, ARRAY_SIZE(snd_ac97_cm9739_controls)); 2022 } 2023 2024 static int patch_cm9739_post_spdif(ac97_t * ac97) 2025 { 2026 return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif)); 2027 } 2028 2029 static struct snd_ac97_build_ops patch_cm9739_ops = { 2030 .build_specific = patch_cm9739_specific, 2031 .build_post_spdif = patch_cm9739_post_spdif 2032 }; 2033 2034 int patch_cm9739(ac97_t * ac97) 2035 { 2036 unsigned short val; 2037 2038 ac97->build_ops = &patch_cm9739_ops; 2039 2040 /* CM9739/A has no Master and PCM volume although the register reacts */ 2041 ac97->flags |= AC97_HAS_NO_MASTER_VOL | AC97_HAS_NO_PCM_VOL; 2042 snd_ac97_write_cache(ac97, AC97_MASTER, 0x8000); 2043 snd_ac97_write_cache(ac97, AC97_PCM, 0x8000); 2044 2045 /* check spdif */ 2046 val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS); 2047 if (val & AC97_EA_SPCV) { 2048 /* enable spdif in */ 2049 snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL, 2050 snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) | 0x01); 2051 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ 2052 } else { 2053 ac97->ext_id &= ~AC97_EI_SPDIF; /* disable extended-id */ 2054 ac97->rates[AC97_RATES_SPDIF] = 0; 2055 } 2056 2057 /* set-up multi channel */ 2058 /* bit 14: 0 = SPDIF, 1 = EAPD */ 2059 /* bit 13: enable internal vref output for mic */ 2060 /* bit 12: disable center/lfe (swithable) */ 2061 /* bit 10: disable surround/line (switchable) */ 2062 /* bit 9: mix 2 surround off */ 2063 /* bit 4: undocumented; 0 mutes the CM9739A, which defaults to 1 */ 2064 /* bit 3: undocumented; surround? */ 2065 /* bit 0: dB */ 2066 val = snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) & (1 << 4); 2067 val |= (1 << 3); 2068 val |= (1 << 13); 2069 if (! (ac97->ext_id & AC97_EI_SPDIF)) 2070 val |= (1 << 14); 2071 snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN, val); 2072 2073 /* FIXME: set up GPIO */ 2074 snd_ac97_write_cache(ac97, 0x70, 0x0100); 2075 snd_ac97_write_cache(ac97, 0x72, 0x0020); 2076 /* Special exception for ASUS W1000/CMI9739. It does not have an SPDIF in. */ 2077 if (ac97->pci && 2078 ac97->subsystem_vendor == 0x1043 && 2079 ac97->subsystem_device == 0x1843) { 2080 snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL, 2081 snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) & ~0x01); 2082 snd_ac97_write_cache(ac97, AC97_CM9739_MULTI_CHAN, 2083 snd_ac97_read(ac97, AC97_CM9739_MULTI_CHAN) | (1 << 14)); 2084 } 2085 2086 return 0; 2087 } 2088 2089 #define AC97_CM9761_MULTI_CHAN 0x64 2090 #define AC97_CM9761_FUNC 0x66 2091 #define AC97_CM9761_SPDIF_CTRL 0x6c 2092 2093 static int snd_ac97_cm9761_linein_rear_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 2094 { 2095 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 2096 if (ac97->regs[AC97_CM9761_MULTI_CHAN] & 0x0400) 2097 ucontrol->value.integer.value[0] = 1; 2098 else 2099 ucontrol->value.integer.value[0] = 0; 2100 return 0; 2101 } 2102 2103 static int snd_ac97_cm9761_linein_rear_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 2104 { 2105 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 2106 unsigned short vals[2][2] = { 2107 { 0x0008, 0x0400 }, /* off, on */ 2108 { 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */ 2109 }; 2110 return snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x0408, 2111 vals[ac97->spec.dev_flags][!!ucontrol->value.integer.value[0]]); 2112 } 2113 2114 static int snd_ac97_cm9761_center_mic_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 2115 { 2116 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 2117 if (ac97->regs[AC97_CM9761_MULTI_CHAN] & 0x1000) 2118 ucontrol->value.integer.value[0] = 1; 2119 else 2120 ucontrol->value.integer.value[0] = 0; 2121 if (ac97->spec.dev_flags) /* 9761-82 rev.B */ 2122 ucontrol->value.integer.value[0] = !ucontrol->value.integer.value[0]; 2123 return 0; 2124 } 2125 2126 static int snd_ac97_cm9761_center_mic_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 2127 { 2128 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 2129 unsigned short vals[2][2] = { 2130 { 0x2000, 0x1880 }, /* off, on */ 2131 { 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */ 2132 }; 2133 return snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3880, 2134 vals[ac97->spec.dev_flags][!!ucontrol->value.integer.value[0]]); 2135 } 2136 2137 static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = { 2138 { 2139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2140 .name = "Line-In As Surround", 2141 .info = snd_ac97_info_volsw, 2142 .get = snd_ac97_cm9761_linein_rear_get, 2143 .put = snd_ac97_cm9761_linein_rear_put, 2144 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ 2145 }, 2146 { 2147 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2148 .name = "Mic As Center/LFE", 2149 .info = snd_ac97_info_volsw, 2150 .get = snd_ac97_cm9761_center_mic_get, 2151 .put = snd_ac97_cm9761_center_mic_put, 2152 .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ 2153 }, 2154 }; 2155 2156 static int cm9761_spdif_out_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 2157 { 2158 static char *texts[] = { "AC-Link", "ADC", "SPDIF-In" }; 2159 2160 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2161 uinfo->count = 1; 2162 uinfo->value.enumerated.items = 3; 2163 if (uinfo->value.enumerated.item > 2) 2164 uinfo->value.enumerated.item = 2; 2165 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 2166 return 0; 2167 } 2168 2169 static int cm9761_spdif_out_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 2170 { 2171 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 2172 2173 if (ac97->regs[AC97_CM9761_FUNC] & 0x1) 2174 ucontrol->value.enumerated.item[0] = 2; /* SPDIF-loopback */ 2175 else if (ac97->regs[AC97_CM9761_SPDIF_CTRL] & 0x2) 2176 ucontrol->value.enumerated.item[0] = 1; /* ADC loopback */ 2177 else 2178 ucontrol->value.enumerated.item[0] = 0; /* AC-link */ 2179 return 0; 2180 } 2181 2182 static int cm9761_spdif_out_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 2183 { 2184 ac97_t *ac97 = snd_kcontrol_chip(kcontrol); 2185 2186 if (ucontrol->value.enumerated.item[0] == 2) 2187 return snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0x1); 2188 snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0); 2189 return snd_ac97_update_bits(ac97, AC97_CM9761_SPDIF_CTRL, 0x2, 2190 ucontrol->value.enumerated.item[0] == 1 ? 0x2 : 0); 2191 } 2192 2193 static const char *cm9761_dac_clock[] = { "AC-Link", "SPDIF-In", "Both" }; 2194 static const struct ac97_enum cm9761_dac_clock_enum = 2195 AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock); 2196 2197 static const snd_kcontrol_new_t snd_ac97_cm9761_controls_spdif[] = { 2198 { /* BIT 1: SPDIFS */ 2199 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2200 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 2201 .info = cm9761_spdif_out_source_info, 2202 .get = cm9761_spdif_out_source_get, 2203 .put = cm9761_spdif_out_source_put, 2204 }, 2205 /* BIT 2: IG_SPIV */ 2206 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9761_SPDIF_CTRL, 2, 1, 0), 2207 /* BIT 3: SPI2F */ 2208 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9761_SPDIF_CTRL, 3, 1, 0), 2209 /* BIT 4: SPI2SDI */ 2210 AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9761_SPDIF_CTRL, 4, 1, 0), 2211 /* BIT 9-10: DAC_CTL */ 2212 AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum), 2213 }; 2214 2215 static int patch_cm9761_post_spdif(ac97_t * ac97) 2216 { 2217 return patch_build_controls(ac97, snd_ac97_cm9761_controls_spdif, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif)); 2218 } 2219 2220 static int patch_cm9761_specific(ac97_t * ac97) 2221 { 2222 return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls)); 2223 } 2224 2225 static struct snd_ac97_build_ops patch_cm9761_ops = { 2226 .build_specific = patch_cm9761_specific, 2227 .build_post_spdif = patch_cm9761_post_spdif 2228 }; 2229 2230 int patch_cm9761(ac97_t *ac97) 2231 { 2232 unsigned short val; 2233 2234 /* CM9761 has no PCM volume although the register reacts */ 2235 /* Master volume seems to have _some_ influence on the analog 2236 * input sounds 2237 */ 2238 ac97->flags |= /*AC97_HAS_NO_MASTER_VOL |*/ AC97_HAS_NO_PCM_VOL; 2239 snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808); 2240 snd_ac97_write_cache(ac97, AC97_PCM, 0x8808); 2241 2242 ac97->spec.dev_flags = 0; /* 1 = model 82 revision B */ 2243 if (ac97->id == AC97_ID_CM9761_82) { 2244 unsigned short tmp; 2245 /* check page 1, reg 0x60 */ 2246 val = snd_ac97_read(ac97, AC97_INT_PAGING); 2247 snd_ac97_write_cache(ac97, AC97_INT_PAGING, (val & ~0x0f) | 0x01); 2248 tmp = snd_ac97_read(ac97, 0x60); 2249 ac97->spec.dev_flags = tmp & 1; /* revision B? */ 2250 snd_ac97_write_cache(ac97, AC97_INT_PAGING, val); 2251 } 2252 2253 ac97->build_ops = &patch_cm9761_ops; 2254 2255 /* enable spdif */ 2256 /* force the SPDIF bit in ext_id - codec doesn't set this bit! */ 2257 ac97->ext_id |= AC97_EI_SPDIF; 2258 /* to be sure: we overwrite the ext status bits */ 2259 snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, 0x05c0); 2260 /* Don't set 0x0200 here. This results in the silent analog output */ 2261 snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0001); /* enable spdif-in */ 2262 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ 2263 2264 /* set-up multi channel */ 2265 /* bit 15: pc master beep off 2266 * bit 14: pin47 = EAPD/SPDIF 2267 * bit 13: vref ctl [= cm9739] 2268 * bit 12: CLFE control (reverted on rev B) 2269 * bit 11: Mic/center share (reverted on rev B) 2270 * bit 10: suddound/line share 2271 * bit 9: Analog-in mix -> surround 2272 * bit 8: Analog-in mix -> CLFE 2273 * bit 7: Mic/LFE share (mic/center/lfe) 2274 * bit 5: vref select (9761A) 2275 * bit 4: front control 2276 * bit 3: surround control (revereted with rev B) 2277 * bit 2: front mic 2278 * bit 1: stereo mic 2279 * bit 0: mic boost level (0=20dB, 1=30dB) 2280 */ 2281 2282 #if 0 2283 if (ac97->spec.dev_flags) 2284 val = 0x0214; 2285 else 2286 val = 0x321c; 2287 #endif 2288 val = snd_ac97_read(ac97, AC97_CM9761_MULTI_CHAN); 2289 val |= (1 << 4); /* front on */ 2290 snd_ac97_write_cache(ac97, AC97_CM9761_MULTI_CHAN, val); 2291 2292 /* FIXME: set up GPIO */ 2293 snd_ac97_write_cache(ac97, 0x70, 0x0100); 2294 snd_ac97_write_cache(ac97, 0x72, 0x0020); 2295 2296 return 0; 2297 } 2298 2299 #define AC97_CM9780_SIDE 0x60 2300 #define AC97_CM9780_JACK 0x62 2301 #define AC97_CM9780_MIXER 0x64 2302 #define AC97_CM9780_MULTI_CHAN 0x66 2303 #define AC97_CM9780_SPDIF 0x6c 2304 2305 static const char *cm9780_ch_select[] = { "Front", "Side", "Center/LFE", "Rear" }; 2306 static const struct ac97_enum cm9780_ch_select_enum = 2307 AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select); 2308 static const snd_kcontrol_new_t cm9780_controls[] = { 2309 AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE, 15, 7, 1, 1), 2310 AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE, 8, 0, 31, 0), 2311 AC97_ENUM("Side Playback Route", cm9780_ch_select_enum), 2312 }; 2313 2314 static int patch_cm9780_specific(ac97_t *ac97) 2315 { 2316 return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls)); 2317 } 2318 2319 static struct snd_ac97_build_ops patch_cm9780_ops = { 2320 .build_specific = patch_cm9780_specific, 2321 .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ 2322 }; 2323 2324 int patch_cm9780(ac97_t *ac97) 2325 { 2326 unsigned short val; 2327 2328 ac97->build_ops = &patch_cm9780_ops; 2329 2330 /* enable spdif */ 2331 if (ac97->ext_id & AC97_EI_SPDIF) { 2332 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ 2333 val = snd_ac97_read(ac97, AC97_CM9780_SPDIF); 2334 val |= 0x1; /* SPDI_EN */ 2335 snd_ac97_write_cache(ac97, AC97_CM9780_SPDIF, val); 2336 } 2337 2338 return 0; 2339 } 2340 2341 /* 2342 * VIA VT1616 codec 2343 */ 2344 static const snd_kcontrol_new_t snd_ac97_controls_vt1616[] = { 2345 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0), 2346 AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0), 2347 AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0), 2348 AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0), 2349 }; 2350 2351 static int patch_vt1616_specific(ac97_t * ac97) 2352 { 2353 int err; 2354 2355 if (snd_ac97_try_bit(ac97, 0x5a, 9)) 2356 if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[0], 1)) < 0) 2357 return err; 2358 if ((err = patch_build_controls(ac97, &snd_ac97_controls_vt1616[1], ARRAY_SIZE(snd_ac97_controls_vt1616) - 1)) < 0) 2359 return err; 2360 return 0; 2361 } 2362 2363 static struct snd_ac97_build_ops patch_vt1616_ops = { 2364 .build_specific = patch_vt1616_specific 2365 }; 2366 2367 int patch_vt1616(ac97_t * ac97) 2368 { 2369 ac97->build_ops = &patch_vt1616_ops; 2370 return 0; 2371 } 2372 2373 static const snd_kcontrol_new_t snd_ac97_controls_it2646[] = { 2374 AC97_SINGLE("Line-In As Surround", 0x76, 9, 1, 0), 2375 AC97_SINGLE("Mic As Center/LFE", 0x76, 10, 1, 0), 2376 }; 2377 2378 static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = { 2379 AC97_SINGLE("IEC958 Capture Switch", 0x76, 11, 1, 0), 2380 AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0), 2381 AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0), 2382 }; 2383 2384 static int patch_it2646_specific(ac97_t * ac97) 2385 { 2386 int err; 2387 if ((err = patch_build_controls(ac97, snd_ac97_controls_it2646, ARRAY_SIZE(snd_ac97_controls_it2646))) < 0) 2388 return err; 2389 if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_it2646, ARRAY_SIZE(snd_ac97_spdif_controls_it2646))) < 0) 2390 return err; 2391 return 0; 2392 } 2393 2394 static struct snd_ac97_build_ops patch_it2646_ops = { 2395 .build_specific = patch_it2646_specific 2396 }; 2397 2398 int patch_it2646(ac97_t * ac97) 2399 { 2400 ac97->build_ops = &patch_it2646_ops; 2401 /* full DAC volume */ 2402 snd_ac97_write_cache(ac97, 0x5E, 0x0808); 2403 snd_ac97_write_cache(ac97, 0x7A, 0x0808); 2404 return 0; 2405 } 2406 2407 /* Si3036/8 specific registers */ 2408 #define AC97_SI3036_CHIP_ID 0x5a 2409 2410 int mpatch_si3036(ac97_t * ac97) 2411 { 2412 //printk("mpatch_si3036: chip id = %x\n", snd_ac97_read(ac97, 0x5a)); 2413 snd_ac97_write_cache(ac97, 0x5c, 0xf210 ); 2414 snd_ac97_write_cache(ac97, 0x68, 0); 2415 return 0; 2416 } 2417