diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-08-03 11:59:36 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-09-06 12:08:30 -0400 |
commit | 833a493b7ed2eb8f9059338a0ebf06bebbb6ae93 (patch) | |
tree | 785dd0a6ad97fc13a100e409c8fd21e07872f64d | |
parent | 53775b0d0cb91ab217c9853efddc51597b58bbff (diff) |
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>
-rw-r--r-- | include/sound/ac97_codec.h | 3 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 24 |
2 files changed, 26 insertions, 1 deletions
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 @@ | |||
422 | */ | 422 | */ |
423 | 423 | ||
424 | struct snd_ac97; | 424 | struct snd_ac97; |
425 | struct snd_pcm_chmap; | ||
425 | 426 | ||
426 | struct snd_ac97_build_ops { | 427 | struct snd_ac97_build_ops { |
427 | int (*build_3d) (struct snd_ac97 *ac97); | 428 | int (*build_3d) (struct snd_ac97 *ac97); |
@@ -528,6 +529,8 @@ struct snd_ac97 { | |||
528 | struct delayed_work power_work; | 529 | struct delayed_work power_work; |
529 | #endif | 530 | #endif |
530 | struct device dev; | 531 | struct device dev; |
532 | |||
533 | struct snd_pcm_chmap *chmaps[2]; /* channel-maps (optional) */ | ||
531 | }; | 534 | }; |
532 | 535 | ||
533 | #define to_ac97_t(d) container_of(d, struct snd_ac97, dev) | 536 | #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) | |||
2595 | shared ? 0 : 0x100); | 2595 | shared ? 0 : 0x100); |
2596 | } | 2596 | } |
2597 | 2597 | ||
2598 | static int alc650_swap_surround_put(struct snd_kcontrol *kcontrol, | ||
2599 | struct snd_ctl_elem_value *ucontrol) | ||
2600 | { | ||
2601 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | ||
2602 | struct snd_pcm_chmap *map = ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK]; | ||
2603 | |||
2604 | if (map) { | ||
2605 | if (ucontrol->value.integer.value[0]) | ||
2606 | map->chmap = snd_pcm_std_chmaps; | ||
2607 | else | ||
2608 | map->chmap = snd_pcm_alt_chmaps; | ||
2609 | } | ||
2610 | return snd_ac97_put_volsw(kcontrol, ucontrol); | ||
2611 | } | ||
2612 | |||
2598 | static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = { | 2613 | static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = { |
2599 | AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0), | 2614 | AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0), |
2600 | AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0), | 2615 | 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[] = { | |||
2608 | /* 9: Line-In/Surround share */ | 2623 | /* 9: Line-In/Surround share */ |
2609 | /* 10: Mic/CLFE share */ | 2624 | /* 10: Mic/CLFE share */ |
2610 | /* 11-13: in IEC958 controls */ | 2625 | /* 11-13: in IEC958 controls */ |
2611 | AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0), | 2626 | { |
2627 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2628 | .name = "Swap Surround Slot", | ||
2629 | .info = snd_ac97_info_volsw, | ||
2630 | .get = snd_ac97_get_volsw, | ||
2631 | .put = alc650_swap_surround_put, | ||
2632 | .private_value = AC97_SINGLE_VALUE(AC97_ALC650_MULTICH, 14, 1, 0), | ||
2633 | }, | ||
2612 | #if 0 /* always set in patch_alc650 */ | 2634 | #if 0 /* always set in patch_alc650 */ |
2613 | AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0), | 2635 | AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0), |
2614 | AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0), | 2636 | AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0), |