[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 <perex@suse.cz>
This commit is contained in:
parent
12aa757905
commit
5a25c5cfd4
|
@ -269,9 +269,10 @@ struct snd_ymfpci_pcm {
|
||||||
enum snd_ymfpci_pcm_type type;
|
enum snd_ymfpci_pcm_type type;
|
||||||
struct snd_pcm_substream *substream;
|
struct snd_pcm_substream *substream;
|
||||||
struct snd_ymfpci_voice *voices[2]; /* playback only */
|
struct snd_ymfpci_voice *voices[2]; /* playback only */
|
||||||
unsigned int running: 1;
|
unsigned int running: 1,
|
||||||
unsigned int output_front: 1;
|
output_front: 1,
|
||||||
unsigned int output_rear: 1;
|
output_rear: 1,
|
||||||
|
swap_rear: 1;
|
||||||
unsigned int update_pcm_vol;
|
unsigned int update_pcm_vol;
|
||||||
u32 period_size; /* cached from runtime->period_size */
|
u32 period_size; /* cached from runtime->period_size */
|
||||||
u32 buffer_size; /* cached from runtime->buffer_size */
|
u32 buffer_size; /* cached from runtime->buffer_size */
|
||||||
|
@ -344,6 +345,7 @@ struct snd_ymfpci {
|
||||||
struct snd_kcontrol *spdif_pcm_ctl;
|
struct snd_kcontrol *spdif_pcm_ctl;
|
||||||
int mode_dup4ch;
|
int mode_dup4ch;
|
||||||
int rear_opened;
|
int rear_opened;
|
||||||
|
int rear_swap;
|
||||||
int spdif_opened;
|
int spdif_opened;
|
||||||
struct {
|
struct {
|
||||||
u16 left;
|
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_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_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_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);
|
int snd_ymfpci_timer(struct snd_ymfpci *chip, int device);
|
||||||
|
|
||||||
#endif /* __SOUND_YMFPCI_H */
|
#endif /* __SOUND_YMFPCI_H */
|
||||||
|
|
|
@ -49,6 +49,7 @@ static long mpu_port[SNDRV_CARDS];
|
||||||
static long joystick_port[SNDRV_CARDS];
|
static long joystick_port[SNDRV_CARDS];
|
||||||
#endif
|
#endif
|
||||||
static int rear_switch[SNDRV_CARDS];
|
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_param_array(index, int, NULL, 0444);
|
||||||
MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard.");
|
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
|
#endif
|
||||||
module_param_array(rear_switch, bool, NULL, 0444);
|
module_param_array(rear_switch, bool, NULL, 0444);
|
||||||
MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch");
|
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[] = {
|
static struct pci_device_id snd_ymfpci_ids[] = {
|
||||||
{ 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */
|
{ 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);
|
snd_card_free(card);
|
||||||
return err;
|
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);
|
snd_card_free(card);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -536,19 +536,30 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ypcm->output_rear) {
|
if (ypcm->output_rear) {
|
||||||
/* The SPDIF out channels seem to be swapped, so we have
|
if (!ypcm->swap_rear) {
|
||||||
* to swap them here, too. The rear analog out channels
|
if (use_left) {
|
||||||
* will be wrong, but otherwise AC3 would not work.
|
bank->eff2_gain =
|
||||||
*/
|
bank->eff2_gain_end = vol_left;
|
||||||
if (use_left) {
|
}
|
||||||
bank->eff3_gain =
|
if (use_right) {
|
||||||
bank->eff3_gain_end = vol_left;
|
bank->eff3_gain =
|
||||||
}
|
bank->eff3_gain_end = vol_right;
|
||||||
if (use_right) {
|
}
|
||||||
bank->eff2_gain =
|
} else {
|
||||||
bank->eff2_gain_end = vol_right;
|
/* 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 = runtime->private_data;
|
||||||
ypcm->output_front = 1;
|
ypcm->output_front = 1;
|
||||||
ypcm->output_rear = chip->mode_dup4ch ? 1 : 0;
|
ypcm->output_rear = chip->mode_dup4ch ? 1 : 0;
|
||||||
|
ypcm->swap_rear = chip->rear_swap;
|
||||||
spin_lock_irq(&chip->reg_lock);
|
spin_lock_irq(&chip->reg_lock);
|
||||||
if (ypcm->output_rear) {
|
if (ypcm->output_rear) {
|
||||||
ymfpci_open_extension(chip);
|
ymfpci_open_extension(chip);
|
||||||
|
@ -1738,7 +1750,7 @@ static void snd_ymfpci_mixer_free_ac97(struct snd_ac97 *ac97)
|
||||||
chip->ac97 = NULL;
|
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_ac97_template ac97;
|
||||||
struct snd_kcontrol *kctl;
|
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,
|
.read = snd_ymfpci_codec_read,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
chip->rear_swap = rear_swap;
|
||||||
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
|
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0)
|
||||||
return err;
|
return err;
|
||||||
chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus;
|
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;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chip->rear_swap = 1;
|
||||||
if ((err = snd_ymfpci_ac3_init(chip)) < 0) {
|
if ((err = snd_ymfpci_ac3_init(chip)) < 0) {
|
||||||
snd_ymfpci_free(chip);
|
snd_ymfpci_free(chip);
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Reference in a new issue