ALSA: ac97: Implement channel map workaround for ALC650
ALC650 has a channel swap option between surround and CLFE channels, so we need to tweak the channel maps dynamically depending on the register bit. Now struct snd_ac97 can contain chmap pointers for playback and capture. The driver may store these and let ac97 driver changing the channel mapping dynamically. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Родитель
53775b0d0c
Коммит
833a493b7e
|
@ -422,6 +422,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct snd_ac97;
|
struct snd_ac97;
|
||||||
|
struct snd_pcm_chmap;
|
||||||
|
|
||||||
struct snd_ac97_build_ops {
|
struct snd_ac97_build_ops {
|
||||||
int (*build_3d) (struct snd_ac97 *ac97);
|
int (*build_3d) (struct snd_ac97 *ac97);
|
||||||
|
@ -528,6 +529,8 @@ struct snd_ac97 {
|
||||||
struct delayed_work power_work;
|
struct delayed_work power_work;
|
||||||
#endif
|
#endif
|
||||||
struct device dev;
|
struct device dev;
|
||||||
|
|
||||||
|
struct snd_pcm_chmap *chmaps[2]; /* channel-maps (optional) */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define to_ac97_t(d) container_of(d, struct snd_ac97, dev)
|
#define to_ac97_t(d) container_of(d, struct snd_ac97, dev)
|
||||||
|
|
|
@ -2595,6 +2595,21 @@ static void alc650_update_jacks(struct snd_ac97 *ac97)
|
||||||
shared ? 0 : 0x100);
|
shared ? 0 : 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int alc650_swap_surround_put(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
|
||||||
|
struct snd_pcm_chmap *map = ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK];
|
||||||
|
|
||||||
|
if (map) {
|
||||||
|
if (ucontrol->value.integer.value[0])
|
||||||
|
map->chmap = snd_pcm_std_chmaps;
|
||||||
|
else
|
||||||
|
map->chmap = snd_pcm_alt_chmaps;
|
||||||
|
}
|
||||||
|
return snd_ac97_put_volsw(kcontrol, ucontrol);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
|
static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
|
||||||
AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
|
AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
|
||||||
AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
|
AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
|
||||||
|
@ -2608,7 +2623,14 @@ static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
|
||||||
/* 9: Line-In/Surround share */
|
/* 9: Line-In/Surround share */
|
||||||
/* 10: Mic/CLFE share */
|
/* 10: Mic/CLFE share */
|
||||||
/* 11-13: in IEC958 controls */
|
/* 11-13: in IEC958 controls */
|
||||||
AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0),
|
{
|
||||||
|
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||||
|
.name = "Swap Surround Slot",
|
||||||
|
.info = snd_ac97_info_volsw,
|
||||||
|
.get = snd_ac97_get_volsw,
|
||||||
|
.put = alc650_swap_surround_put,
|
||||||
|
.private_value = AC97_SINGLE_VALUE(AC97_ALC650_MULTICH, 14, 1, 0),
|
||||||
|
},
|
||||||
#if 0 /* always set in patch_alc650 */
|
#if 0 /* always set in patch_alc650 */
|
||||||
AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
|
AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
|
||||||
AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
|
AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
|
||||||
|
|
Загрузка…
Ссылка в новой задаче