[ALSA] cmipci: reorganize set_dac_channels()
Clemens Ladisch [Mon, 17 Sep 2007 07:39:51 +0000 (09:39 +0200)]
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>

sound/pci/cmipci.c

index c51ea0e..b4f74ae 100644 (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)
 {
        if (channels > 2) {
-               if (! cm->can_multi_ch)
+               if (!cm->can_multi_ch || !rec->ch)
                        return -EINVAL;
                if (rec->fmt != 0x03) /* stereo 16bit only */
                        return -EINVAL;
+       }
 
+       if (cm->can_multi_ch) {
                spin_lock_irq(&cm->reg_lock);
-               snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
-               snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
-               if (channels > 4) {
-                       snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
-                       snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
+               if (channels > 2) {
+                       snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
+                       snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
                } else {
-                       snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
-                       snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
+                       snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
+                       snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
                }
-               if (channels >= 6) {
+               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);
-                       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_CHFORMAT, CM_CHB3D);
                        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_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;
 }