From 5a25c5cfd4f61f514decca3c4106210fb168ce19 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 18 Jan 2006 08:02:24 +0100 Subject: [ALSA] ymfpci - make rear channel swap optional Modules: YMFPCI driver Added rear_swap module option / kernel parameter to configure the rear channel swapping. Default value is enable to make the AC3 passthrough working, but analog only users might revert the previous behaviour. Signed-off-by: Jaroslav Kysela --- include/sound/ymfpci.h | 10 ++++++---- sound/pci/ymfpci/ymfpci.c | 5 ++++- sound/pci/ymfpci/ymfpci_main.c | 42 ++++++++++++++++++++++++++++-------------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h index d567bfdbf513a..d41cda97e952d 100644 --- a/include/sound/ymfpci.h +++ b/include/sound/ymfpci.h @@ -269,9 +269,10 @@ struct snd_ymfpci_pcm { enum snd_ymfpci_pcm_type type; struct snd_pcm_substream *substream; struct snd_ymfpci_voice *voices[2]; /* playback only */ - unsigned int running: 1; - unsigned int output_front: 1; - unsigned int output_rear: 1; + unsigned int running: 1, + output_front: 1, + output_rear: 1, + swap_rear: 1; unsigned int update_pcm_vol; u32 period_size; /* cached from runtime->period_size */ u32 buffer_size; /* cached from runtime->buffer_size */ @@ -344,6 +345,7 @@ struct snd_ymfpci { struct snd_kcontrol *spdif_pcm_ctl; int mode_dup4ch; int rear_opened; + int rear_swap; int spdif_opened; struct { u16 left; @@ -376,7 +378,7 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); -int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch); +int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap); int snd_ymfpci_timer(struct snd_ymfpci *chip, int device); #endif /* __SOUND_YMFPCI_H */ diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index dab9b83103418..db57ce939fa8f 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -49,6 +49,7 @@ static long mpu_port[SNDRV_CARDS]; static long joystick_port[SNDRV_CARDS]; #endif static int rear_switch[SNDRV_CARDS]; +static int rear_swap[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 }; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard."); @@ -66,6 +67,8 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address"); #endif module_param_array(rear_switch, bool, NULL, 0444); MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); +module_param_array(rear_swap, bool, NULL, 0444); +MODULE_PARM_DESC(rear_swap, "Swap rear channels (must be enabled for correct IEC958 (S/PDIF)) output"); static struct pci_device_id snd_ymfpci_ids[] = { { 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */ @@ -295,7 +298,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, snd_card_free(card); return err; } - if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) { + if ((err = snd_ymfpci_mixer(chip, rear_switch[dev], rear_swap[dev])) < 0) { snd_card_free(card); return err; } diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 30ee53adb4941..8ac5ab50b5c76 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -536,19 +536,30 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int } } if (ypcm->output_rear) { - /* The SPDIF out channels seem to be swapped, so we have - * to swap them here, too. The rear analog out channels - * will be wrong, but otherwise AC3 would not work. - */ - if (use_left) { - bank->eff3_gain = - bank->eff3_gain_end = vol_left; - } - if (use_right) { - bank->eff2_gain = - bank->eff2_gain_end = vol_right; - } - } + if (!ypcm->swap_rear) { + if (use_left) { + bank->eff2_gain = + bank->eff2_gain_end = vol_left; + } + if (use_right) { + bank->eff3_gain = + bank->eff3_gain_end = vol_right; + } + } else { + /* The SPDIF out channels seem to be swapped, so we have + * to swap them here, too. The rear analog out channels + * will be wrong, but otherwise AC3 would not work. + */ + if (use_left) { + bank->eff3_gain = + bank->eff3_gain_end = vol_left; + } + if (use_right) { + bank->eff2_gain = + bank->eff2_gain_end = vol_right; + } + } + } } } @@ -898,6 +909,7 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream) ypcm = runtime->private_data; ypcm->output_front = 1; ypcm->output_rear = chip->mode_dup4ch ? 1 : 0; + ypcm->swap_rear = chip->rear_swap; spin_lock_irq(&chip->reg_lock); if (ypcm->output_rear) { ymfpci_open_extension(chip); @@ -1738,7 +1750,7 @@ static void snd_ymfpci_mixer_free_ac97(struct snd_ac97 *ac97) chip->ac97 = NULL; } -int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) +int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap) { struct snd_ac97_template ac97; struct snd_kcontrol *kctl; @@ -1750,6 +1762,7 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) .read = snd_ymfpci_codec_read, }; + chip->rear_swap = rear_swap; if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0) return err; chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus; @@ -2297,6 +2310,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card, return -EIO; } + chip->rear_swap = 1; if ((err = snd_ymfpci_ac3_init(chip)) < 0) { snd_ymfpci_free(chip); return err; -- cgit 1.2.3-korg