aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ac97
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ac97')
-rw-r--r--sound/pci/ac97/ac97_patch.c103
1 files changed, 99 insertions, 4 deletions
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 43455fc07b77..3eac0f86266c 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -3277,16 +3277,111 @@ static int patch_vt1616(struct snd_ac97 * ac97)
3277/* 3277/*
3278 * VT1617A codec 3278 * VT1617A codec
3279 */ 3279 */
3280static int patch_vt1617a(struct snd_ac97 * ac97) 3280
3281/*
3282 * unfortunately, the vt1617a stashes the twiddlers required for
3283 * nooding the i/o jacks on 2 different regs. * thameans that we cant
3284 * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
3285 * are own funcs.
3286 *
3287 * NB: this is absolutely and utterly different from the vt1618. dunno
3288 * about the 1616.
3289 */
3290
3291/* copied from ac97_surround_jack_mode_info() */
3292static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol,
3293 struct snd_ctl_elem_info *uinfo)
3281{ 3294{
3282 /* bring analog power consumption to normal, like WinXP driver 3295 /* ordering in this list reflects vt1617a docs for Reg 20 and
3283 * for EPIA SP 3296 * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
3297 * is SM51EN *AND* it's Bit14, not Bit15 so the table is very
3298 * counter-intuitive */
3299
3300 static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3",
3301 "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
3302 "LineIn Mic2", "LineIn Mic2 Mic1",
3303 "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
3304 return ac97_enum_text_info(kcontrol, uinfo, texts, 8);
3305}
3306
3307static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
3308 struct snd_ctl_elem_value *ucontrol)
3309{
3310 ushort usSM51, usMS;
3311
3312 struct snd_ac97 *pac97;
3313
3314 pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
3315
3316 /* grab our desirec bits, then mash them together in a manner
3317 * consistent with Table 6 on page 17 in the 1617a docs */
3318
3319 usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
3320 usMS = snd_ac97_read(pac97, 0x20) >> 8;
3321
3322 ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS;
3323
3324 return 0;
3325}
3326
3327static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol,
3328 struct snd_ctl_elem_value *ucontrol)
3329{
3330 ushort usSM51, usMS, usReg;
3331
3332 struct snd_ac97 *pac97;
3333
3334 pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
3335
3336 usSM51 = ucontrol->value.enumerated.item[0] >> 1;
3337 usMS = ucontrol->value.enumerated.item[0] & 1;
3338
3339 /* push our values into the register - consider that things will be left
3340 * in a funky state if the write fails */
3341
3342 usReg = snd_ac97_read(pac97, 0x7a);
3343 snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14));
3344 usReg = snd_ac97_read(pac97, 0x20);
3345 snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8));
3346
3347 return 0;
3348}
3349
3350static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
3351
3352 AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
3353 /*
3354 * These are used to enable/disable surround sound on motherboards
3355 * that have 3 bidirectional analog jacks
3356 */
3357 {
3358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3359 .name = "Smart 5.1 Select",
3360 .info = snd_ac97_vt1617a_smart51_info,
3361 .get = snd_ac97_vt1617a_smart51_get,
3362 .put = snd_ac97_vt1617a_smart51_put,
3363 },
3364};
3365
3366int patch_vt1617a(struct snd_ac97 * ac97)
3367{
3368 int err = 0;
3369
3370 /* we choose to not fail out at this point, but we tell the
3371 caller when we return */
3372
3373 err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0],
3374 ARRAY_SIZE(snd_ac97_controls_vt1617a));
3375
3376 /* bring analog power consumption to normal by turning off the
3377 * headphone amplifier, like WinXP driver for EPIA SP
3284 */ 3378 */
3285 snd_ac97_write_cache(ac97, 0x5c, 0x20); 3379 snd_ac97_write_cache(ac97, 0x5c, 0x20);
3286 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ 3380 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
3287 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; 3381 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
3288 ac97->build_ops = &patch_vt1616_ops; 3382 ac97->build_ops = &patch_vt1616_ops;
3289 return 0; 3383
3384 return err;
3290} 3385}
3291 3386
3292/* 3387/*