aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/wss
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-03-23 19:36:21 -0400
committerTakashi Iwai <tiwai@suse.de>2009-03-23 19:36:21 -0400
commitd0807323345f1cd8ab578b09aab04d10862e9414 (patch)
tree0a1cca9055d4534590779f014199116c7c802d57 /sound/isa/wss
parentd7b6df5d1af11544401ca051aaf68b6e7f110c0e (diff)
parent453e37b37521b613f0927fcf53ccd93ad3a8b3ae (diff)
Merge branch 'topic/sscape-fix' into for-linus
Diffstat (limited to 'sound/isa/wss')
-rw-r--r--sound/isa/wss/wss_lib.c81
1 files changed, 53 insertions, 28 deletions
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index ac27832b2c6f..5d2ba1b749ab 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -181,25 +181,6 @@ static void snd_wss_wait(struct snd_wss *chip)
181 udelay(100); 181 udelay(100);
182} 182}
183 183
184static void snd_wss_outm(struct snd_wss *chip, unsigned char reg,
185 unsigned char mask, unsigned char value)
186{
187 unsigned char tmp = (chip->image[reg] & mask) | value;
188
189 snd_wss_wait(chip);
190#ifdef CONFIG_SND_DEBUG
191 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
192 snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
193#endif
194 chip->image[reg] = tmp;
195 if (!chip->calibrate_mute) {
196 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
197 wmb();
198 wss_outb(chip, CS4231P(REG), tmp);
199 mb();
200 }
201}
202
203static void snd_wss_dout(struct snd_wss *chip, unsigned char reg, 184static void snd_wss_dout(struct snd_wss *chip, unsigned char reg,
204 unsigned char value) 185 unsigned char value)
205{ 186{
@@ -597,7 +578,15 @@ static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute)
597 chip->image[CS4231_RIGHT_INPUT]); 578 chip->image[CS4231_RIGHT_INPUT]);
598 snd_wss_dout(chip, CS4231_LOOPBACK, 579 snd_wss_dout(chip, CS4231_LOOPBACK,
599 chip->image[CS4231_LOOPBACK]); 580 chip->image[CS4231_LOOPBACK]);
581 } else {
582 snd_wss_dout(chip, CS4231_LEFT_INPUT,
583 0);
584 snd_wss_dout(chip, CS4231_RIGHT_INPUT,
585 0);
586 snd_wss_dout(chip, CS4231_LOOPBACK,
587 0xfd);
600 } 588 }
589
601 snd_wss_dout(chip, CS4231_AUX1_LEFT_INPUT, 590 snd_wss_dout(chip, CS4231_AUX1_LEFT_INPUT,
602 mute | chip->image[CS4231_AUX1_LEFT_INPUT]); 591 mute | chip->image[CS4231_AUX1_LEFT_INPUT]);
603 snd_wss_dout(chip, CS4231_AUX1_RIGHT_INPUT, 592 snd_wss_dout(chip, CS4231_AUX1_RIGHT_INPUT,
@@ -640,7 +629,6 @@ static void snd_wss_playback_format(struct snd_wss *chip,
640 int full_calib = 1; 629 int full_calib = 1;
641 630
642 mutex_lock(&chip->mce_mutex); 631 mutex_lock(&chip->mce_mutex);
643 snd_wss_calibrate_mute(chip, 1);
644 if (chip->hardware == WSS_HW_CS4231A || 632 if (chip->hardware == WSS_HW_CS4231A ||
645 (chip->hardware & WSS_HW_CS4232_MASK)) { 633 (chip->hardware & WSS_HW_CS4232_MASK)) {
646 spin_lock_irqsave(&chip->reg_lock, flags); 634 spin_lock_irqsave(&chip->reg_lock, flags);
@@ -656,6 +644,24 @@ static void snd_wss_playback_format(struct snd_wss *chip,
656 full_calib = 0; 644 full_calib = 0;
657 } 645 }
658 spin_unlock_irqrestore(&chip->reg_lock, flags); 646 spin_unlock_irqrestore(&chip->reg_lock, flags);
647 } else if (chip->hardware == WSS_HW_AD1845) {
648 unsigned rate = params_rate(params);
649
650 /*
651 * Program the AD1845 correctly for the playback stream.
652 * Note that we do NOT need to toggle the MCE bit because
653 * the PLAYBACK_ENABLE bit of the Interface Configuration
654 * register is set.
655 *
656 * NOTE: We seem to need to write to the MSB before the LSB
657 * to get the correct sample frequency.
658 */
659 spin_lock_irqsave(&chip->reg_lock, flags);
660 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, (pdfr & 0xf0));
661 snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff);
662 snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff);
663 full_calib = 0;
664 spin_unlock_irqrestore(&chip->reg_lock, flags);
659 } 665 }
660 if (full_calib) { 666 if (full_calib) {
661 snd_wss_mce_up(chip); 667 snd_wss_mce_up(chip);
@@ -673,7 +679,6 @@ static void snd_wss_playback_format(struct snd_wss *chip,
673 udelay(100); /* this seems to help */ 679 udelay(100); /* this seems to help */
674 snd_wss_mce_down(chip); 680 snd_wss_mce_down(chip);
675 } 681 }
676 snd_wss_calibrate_mute(chip, 0);
677 mutex_unlock(&chip->mce_mutex); 682 mutex_unlock(&chip->mce_mutex);
678} 683}
679 684
@@ -685,7 +690,6 @@ static void snd_wss_capture_format(struct snd_wss *chip,
685 int full_calib = 1; 690 int full_calib = 1;
686 691
687 mutex_lock(&chip->mce_mutex); 692 mutex_lock(&chip->mce_mutex);
688 snd_wss_calibrate_mute(chip, 1);
689 if (chip->hardware == WSS_HW_CS4231A || 693 if (chip->hardware == WSS_HW_CS4231A ||
690 (chip->hardware & WSS_HW_CS4232_MASK)) { 694 (chip->hardware & WSS_HW_CS4232_MASK)) {
691 spin_lock_irqsave(&chip->reg_lock, flags); 695 spin_lock_irqsave(&chip->reg_lock, flags);
@@ -700,6 +704,24 @@ static void snd_wss_capture_format(struct snd_wss *chip,
700 full_calib = 0; 704 full_calib = 0;
701 } 705 }
702 spin_unlock_irqrestore(&chip->reg_lock, flags); 706 spin_unlock_irqrestore(&chip->reg_lock, flags);
707 } else if (chip->hardware == WSS_HW_AD1845) {
708 unsigned rate = params_rate(params);
709
710 /*
711 * Program the AD1845 correctly for the capture stream.
712 * Note that we do NOT need to toggle the MCE bit because
713 * the PLAYBACK_ENABLE bit of the Interface Configuration
714 * register is set.
715 *
716 * NOTE: We seem to need to write to the MSB before the LSB
717 * to get the correct sample frequency.
718 */
719 spin_lock_irqsave(&chip->reg_lock, flags);
720 snd_wss_out(chip, CS4231_REC_FORMAT, (cdfr & 0xf0));
721 snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff);
722 snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff);
723 full_calib = 0;
724 spin_unlock_irqrestore(&chip->reg_lock, flags);
703 } 725 }
704 if (full_calib) { 726 if (full_calib) {
705 snd_wss_mce_up(chip); 727 snd_wss_mce_up(chip);
@@ -724,7 +746,6 @@ static void snd_wss_capture_format(struct snd_wss *chip,
724 spin_unlock_irqrestore(&chip->reg_lock, flags); 746 spin_unlock_irqrestore(&chip->reg_lock, flags);
725 snd_wss_mce_down(chip); 747 snd_wss_mce_down(chip);
726 } 748 }
727 snd_wss_calibrate_mute(chip, 0);
728 mutex_unlock(&chip->mce_mutex); 749 mutex_unlock(&chip->mce_mutex);
729} 750}
730 751
@@ -781,6 +802,7 @@ static void snd_wss_init(struct snd_wss *chip)
781{ 802{
782 unsigned long flags; 803 unsigned long flags;
783 804
805 snd_wss_calibrate_mute(chip, 1);
784 snd_wss_mce_down(chip); 806 snd_wss_mce_down(chip);
785 807
786#ifdef SNDRV_DEBUG_MCE 808#ifdef SNDRV_DEBUG_MCE
@@ -804,6 +826,8 @@ static void snd_wss_init(struct snd_wss *chip)
804 826
805 snd_wss_mce_up(chip); 827 snd_wss_mce_up(chip);
806 spin_lock_irqsave(&chip->reg_lock, flags); 828 spin_lock_irqsave(&chip->reg_lock, flags);
829 chip->image[CS4231_IFACE_CTRL] &= ~CS4231_AUTOCALIB;
830 snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
807 snd_wss_out(chip, 831 snd_wss_out(chip,
808 CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]); 832 CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]);
809 spin_unlock_irqrestore(&chip->reg_lock, flags); 833 spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -837,6 +861,7 @@ static void snd_wss_init(struct snd_wss *chip)
837 chip->image[CS4231_REC_FORMAT]); 861 chip->image[CS4231_REC_FORMAT]);
838 spin_unlock_irqrestore(&chip->reg_lock, flags); 862 spin_unlock_irqrestore(&chip->reg_lock, flags);
839 snd_wss_mce_down(chip); 863 snd_wss_mce_down(chip);
864 snd_wss_calibrate_mute(chip, 0);
840 865
841#ifdef SNDRV_DEBUG_MCE 866#ifdef SNDRV_DEBUG_MCE
842 snd_printk(KERN_DEBUG "init: (5)\n"); 867 snd_printk(KERN_DEBUG "init: (5)\n");
@@ -895,8 +920,6 @@ static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
895 mutex_unlock(&chip->open_mutex); 920 mutex_unlock(&chip->open_mutex);
896 return; 921 return;
897 } 922 }
898 snd_wss_calibrate_mute(chip, 1);
899
900 /* disable IRQ */ 923 /* disable IRQ */
901 spin_lock_irqsave(&chip->reg_lock, flags); 924 spin_lock_irqsave(&chip->reg_lock, flags);
902 if (!(chip->hardware & WSS_HW_AD1848_MASK)) 925 if (!(chip->hardware & WSS_HW_AD1848_MASK))
@@ -929,8 +952,6 @@ static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
929 wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ 952 wss_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */
930 spin_unlock_irqrestore(&chip->reg_lock, flags); 953 spin_unlock_irqrestore(&chip->reg_lock, flags);
931 954
932 snd_wss_calibrate_mute(chip, 0);
933
934 chip->mode = 0; 955 chip->mode = 0;
935 mutex_unlock(&chip->open_mutex); 956 mutex_unlock(&chip->open_mutex);
936} 957}
@@ -1123,7 +1144,7 @@ irqreturn_t snd_wss_interrupt(int irq, void *dev_id)
1123 if (chip->hardware & WSS_HW_AD1848_MASK) 1144 if (chip->hardware & WSS_HW_AD1848_MASK)
1124 wss_outb(chip, CS4231P(STATUS), 0); 1145 wss_outb(chip, CS4231P(STATUS), 0);
1125 else 1146 else
1126 snd_wss_outm(chip, CS4231_IRQ_STATUS, status, 0); 1147 snd_wss_out(chip, CS4231_IRQ_STATUS, status);
1127 spin_unlock(&chip->reg_lock); 1148 spin_unlock(&chip->reg_lock);
1128 return IRQ_HANDLED; 1149 return IRQ_HANDLED;
1129} 1150}
@@ -1325,6 +1346,10 @@ static int snd_wss_probe(struct snd_wss *chip)
1325 chip->image[CS4231_ALT_FEATURE_2] = 1346 chip->image[CS4231_ALT_FEATURE_2] =
1326 chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01; 1347 chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01;
1327 } 1348 }
1349 /* enable fine grained frequency selection */
1350 if (chip->hardware == WSS_HW_AD1845)
1351 chip->image[AD1845_PWR_DOWN] = 8;
1352
1328 ptr = (unsigned char *) &chip->image; 1353 ptr = (unsigned char *) &chip->image;
1329 regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32; 1354 regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32;
1330 snd_wss_mce_down(chip); 1355 snd_wss_mce_down(chip);