From: Takashi Iwai Date: Fri, 3 Aug 2012 15:59:36 +0000 (+0200) Subject: ALSA: ac97: Implement channel map workaround for ALC650 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=833a493b7ed2eb8f9059338a0ebf06bebbb6ae93;p=linux-beck.git 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 --- diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h index 02cbb50225bb..4458b87649ff 100644 --- a/include/sound/ac97_codec.h +++ b/include/sound/ac97_codec.h @@ -422,6 +422,7 @@ */ struct snd_ac97; +struct snd_pcm_chmap; struct snd_ac97_build_ops { int (*build_3d) (struct snd_ac97 *ac97); @@ -528,6 +529,8 @@ struct snd_ac97 { struct delayed_work power_work; #endif struct device dev; + + struct snd_pcm_chmap *chmaps[2]; /* channel-maps (optional) */ }; #define to_ac97_t(d) container_of(d, struct snd_ac97, dev) diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index a872d0a82976..66a3bc95fb84 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -2595,6 +2595,21 @@ static void alc650_update_jacks(struct snd_ac97 *ac97) 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[] = { AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 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 */ /* 10: Mic/CLFE share */ /* 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 */ AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0), AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),