mirror of
https://github.com/S3NEO/android_kernel_samsung_msm8226.git
synced 2024-11-07 03:47:13 +00:00
[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: John Utz <john.utz@dmx.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
This commit is contained in:
parent
7f29673b2b
commit
e9024ccc2d
1 changed files with 99 additions and 4 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue