aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/cmipci.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2007-09-17 03:39:51 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 10:50:33 -0400
commit8ffbc01e2cb2e203df910468f236c7b4e7b36f25 (patch)
tree0a81b87cd1118460cfb0a6d0d4e172ba44d41e58 /sound/pci/cmipci.c
parent35add1c295c634fdbb1072189286e4eab3fd64fa (diff)
[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>
Diffstat (limited to 'sound/pci/cmipci.c')
-rw-r--r--sound/pci/cmipci.c49
1 files changed, 19 insertions, 30 deletions
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index c51ea0ef26f9..b4f74ae9c0b6 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -738,48 +738,37 @@ static struct snd_pcm_hw_constraint_list hw_constraints_channels_8 = {
738static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int channels) 738static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int channels)
739{ 739{
740 if (channels > 2) { 740 if (channels > 2) {
741 if (! cm->can_multi_ch) 741 if (!cm->can_multi_ch || !rec->ch)
742 return -EINVAL; 742 return -EINVAL;
743 if (rec->fmt != 0x03) /* stereo 16bit only */ 743 if (rec->fmt != 0x03) /* stereo 16bit only */
744 return -EINVAL; 744 return -EINVAL;
745 }
745 746
747 if (cm->can_multi_ch) {
746 spin_lock_irq(&cm->reg_lock); 748 spin_lock_irq(&cm->reg_lock);
747 snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG); 749 if (channels > 2) {
748 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC); 750 snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
749 if (channels > 4) { 751 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
750 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
751 snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
752 } else { 752 } else {
753 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C); 753 snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
754 snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D); 754 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
755 } 755 }
756 if (channels >= 6) { 756 if (channels == 8)
757 snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
758 else
759 snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
760 if (channels == 6) {
761 snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
757 snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C); 762 snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
758 snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
759 } else { 763 } else {
760 snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
761 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
762 }
763 if (cm->chip_version == 68) {
764 if (channels == 8) {
765 snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
766 } else {
767 snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
768 }
769 }
770 spin_unlock_irq(&cm->reg_lock);
771
772 } else {
773 if (cm->can_multi_ch) {
774 spin_lock_irq(&cm->reg_lock);
775 snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
776 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
777 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C); 764 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
778 snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C); 765 snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
779 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
780 snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
781 spin_unlock_irq(&cm->reg_lock);
782 } 766 }
767 if (channels == 4)
768 snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
769 else
770 snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
771 spin_unlock_irq(&cm->reg_lock);
783 } 772 }
784 return 0; 773 return 0;
785} 774}