[ALSA] cmipci: reorganize set_dac_channels()

By reorganizing the code that sets the CHB3DxC bits we can not only
simplify this code but also fix the bug where the CHB3D8C bit was not
reset when playing a stereo stream after a 7.1 stream.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
This commit is contained in:
Clemens Ladisch 2007-09-17 09:39:51 +02:00 committed by Jaroslav Kysela
parent 35add1c295
commit 8ffbc01e2c

View file

@ -738,48 +738,37 @@ static struct snd_pcm_hw_constraint_list hw_constraints_channels_8 = {
static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int channels) static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int channels)
{ {
if (channels > 2) { if (channels > 2) {
if (! cm->can_multi_ch) if (!cm->can_multi_ch || !rec->ch)
return -EINVAL; return -EINVAL;
if (rec->fmt != 0x03) /* stereo 16bit only */ if (rec->fmt != 0x03) /* stereo 16bit only */
return -EINVAL; return -EINVAL;
}
if (cm->can_multi_ch) {
spin_lock_irq(&cm->reg_lock); spin_lock_irq(&cm->reg_lock);
snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG); if (channels > 2) {
snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC); snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
if (channels > 4) { snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
} else { } else {
snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
}
if (channels >= 6) {
snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
} else {
snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
}
if (cm->chip_version == 68) {
if (channels == 8) {
snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
} else {
snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
}
}
spin_unlock_irq(&cm->reg_lock);
} else {
if (cm->can_multi_ch) {
spin_lock_irq(&cm->reg_lock);
snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG); snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D); snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
}
if (channels == 8)
snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
else
snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
if (channels == 6) {
snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
} else {
snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C); snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C); snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
spin_unlock_irq(&cm->reg_lock);
} }
if (channels == 4)
snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
else
snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
spin_unlock_irq(&cm->reg_lock);
} }
return 0; return 0;
} }