Commit e9024ccc authored by John Utz's avatar John Utz Committed by Jaroslav Kysela

[ALSA] ac97 - Smart 5.1 for VIA 1617a codec

This patch provides a single 8 way enum called 'Smart 5.1 Select' with
some reasonable names for each enum that allows the user to choose
which of the 8 possible settings for vt1617a's version of what via
calls 'Smart 5.1'.
Signed-off-by: default avatarJohn Utz <john.utz@dmx.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent 7f29673b
......@@ -3277,16 +3277,111 @@ static int patch_vt1616(struct snd_ac97 * ac97)
/*
* VT1617A codec
*/
static int patch_vt1617a(struct snd_ac97 * ac97)
/*
* unfortunately, the vt1617a stashes the twiddlers required for
* nooding the i/o jacks on 2 different regs. * thameans that we cant
* use the easy way provided by AC97_ENUM_DOUBLE() we have to write
* are own funcs.
*
* NB: this is absolutely and utterly different from the vt1618. dunno
* about the 1616.
*/
/* copied from ac97_surround_jack_mode_info() */
static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
/* bring analog power consumption to normal, like WinXP driver
* for EPIA SP
/* ordering in this list reflects vt1617a docs for Reg 20 and
* 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
* is SM51EN *AND* it's Bit14, not Bit15 so the table is very
* counter-intuitive */
static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3",
"Surr LFE/C Mic3", "LineIn LFE/C Mic3",
"LineIn Mic2", "LineIn Mic2 Mic1",
"Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
return ac97_enum_text_info(kcontrol, uinfo, texts, 8);
}
static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ushort usSM51, usMS;
struct snd_ac97 *pac97;
pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
/* grab our desirec bits, then mash them together in a manner
* consistent with Table 6 on page 17 in the 1617a docs */
usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
usMS = snd_ac97_read(pac97, 0x20) >> 8;
ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS;
return 0;
}
static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ushort usSM51, usMS, usReg;
struct snd_ac97 *pac97;
pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
usSM51 = ucontrol->value.enumerated.item[0] >> 1;
usMS = ucontrol->value.enumerated.item[0] & 1;
/* push our values into the register - consider that things will be left
* in a funky state if the write fails */
usReg = snd_ac97_read(pac97, 0x7a);
snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14));
usReg = snd_ac97_read(pac97, 0x20);
snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8));
return 0;
}
static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
/*
* These are used to enable/disable surround sound on motherboards
* that have 3 bidirectional analog jacks
*/
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Smart 5.1 Select",
.info = snd_ac97_vt1617a_smart51_info,
.get = snd_ac97_vt1617a_smart51_get,
.put = snd_ac97_vt1617a_smart51_put,
},
};
int patch_vt1617a(struct snd_ac97 * ac97)
{
int err = 0;
/* we choose to not fail out at this point, but we tell the
caller when we return */
err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0],
ARRAY_SIZE(snd_ac97_controls_vt1617a));
/* bring analog power consumption to normal by turning off the
* headphone amplifier, like WinXP driver for EPIA SP
*/
snd_ac97_write_cache(ac97, 0x5c, 0x20);
ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
ac97->build_ops = &patch_vt1616_ops;
return 0;
return err;
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment