diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2009-01-09 17:10:52 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-01-11 07:09:05 -0500 |
commit | 199f7978730a4bbd88038fd84212b30759579f1a (patch) | |
tree | ee3deea40e2db5a38967fce16cb55a3b6103d154 /sound/isa | |
parent | c59765042f53a79a7a65585042ff463b69cb248c (diff) |
ALSA: wss-lib: move AD1845 frequency setting into wss-lib
This is required to allow the sscape driver
to autodetect installed codec.
Also, do not create a timer if detected codec
has no hardware timer (e.g. AD1848).
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Cc: Rene Herman
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/isa')
-rw-r--r-- | sound/isa/sscape.c | 113 | ||||
-rw-r--r-- | sound/isa/wss/wss_lib.c | 40 |
2 files changed, 48 insertions, 105 deletions
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 48a16d865834..bc449166d18d 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c | |||
@@ -129,9 +129,6 @@ enum GA_REG { | |||
129 | #define DMA_8BIT 0x80 | 129 | #define DMA_8BIT 0x80 |
130 | 130 | ||
131 | 131 | ||
132 | #define AD1845_FREQ_SEL_MSB 0x16 | ||
133 | #define AD1845_FREQ_SEL_LSB 0x17 | ||
134 | |||
135 | enum card_type { | 132 | enum card_type { |
136 | SSCAPE, | 133 | SSCAPE, |
137 | SSCAPE_PNP, | 134 | SSCAPE_PNP, |
@@ -955,82 +952,6 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned l | |||
955 | 952 | ||
956 | 953 | ||
957 | /* | 954 | /* |
958 | * Override for the CS4231 playback format function. | ||
959 | * The AD1845 has much simpler format and rate selection. | ||
960 | */ | ||
961 | static void ad1845_playback_format(struct snd_wss *chip, | ||
962 | struct snd_pcm_hw_params *params, | ||
963 | unsigned char format) | ||
964 | { | ||
965 | unsigned long flags; | ||
966 | unsigned rate = params_rate(params); | ||
967 | |||
968 | /* | ||
969 | * The AD1845 can't handle sample frequencies | ||
970 | * outside of 4 kHZ to 50 kHZ | ||
971 | */ | ||
972 | if (rate > 50000) | ||
973 | rate = 50000; | ||
974 | else if (rate < 4000) | ||
975 | rate = 4000; | ||
976 | |||
977 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
978 | |||
979 | /* | ||
980 | * Program the AD1845 correctly for the playback stream. | ||
981 | * Note that we do NOT need to toggle the MCE bit because | ||
982 | * the PLAYBACK_ENABLE bit of the Interface Configuration | ||
983 | * register is set. | ||
984 | * | ||
985 | * NOTE: We seem to need to write to the MSB before the LSB | ||
986 | * to get the correct sample frequency. | ||
987 | */ | ||
988 | snd_wss_out(chip, CS4231_PLAYBK_FORMAT, (format & 0xf0)); | ||
989 | snd_wss_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8)); | ||
990 | snd_wss_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate); | ||
991 | |||
992 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
993 | } | ||
994 | |||
995 | /* | ||
996 | * Override for the CS4231 capture format function. | ||
997 | * The AD1845 has much simpler format and rate selection. | ||
998 | */ | ||
999 | static void ad1845_capture_format(struct snd_wss *chip, | ||
1000 | struct snd_pcm_hw_params *params, | ||
1001 | unsigned char format) | ||
1002 | { | ||
1003 | unsigned long flags; | ||
1004 | unsigned rate = params_rate(params); | ||
1005 | |||
1006 | /* | ||
1007 | * The AD1845 can't handle sample frequencies | ||
1008 | * outside of 4 kHZ to 50 kHZ | ||
1009 | */ | ||
1010 | if (rate > 50000) | ||
1011 | rate = 50000; | ||
1012 | else if (rate < 4000) | ||
1013 | rate = 4000; | ||
1014 | |||
1015 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1016 | |||
1017 | /* | ||
1018 | * Program the AD1845 correctly for the playback stream. | ||
1019 | * Note that we do NOT need to toggle the MCE bit because | ||
1020 | * the CAPTURE_ENABLE bit of the Interface Configuration | ||
1021 | * register is set. | ||
1022 | * | ||
1023 | * NOTE: We seem to need to write to the MSB before the LSB | ||
1024 | * to get the correct sample frequency. | ||
1025 | */ | ||
1026 | snd_wss_out(chip, CS4231_REC_FORMAT, (format & 0xf0)); | ||
1027 | snd_wss_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8)); | ||
1028 | snd_wss_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate); | ||
1029 | |||
1030 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1031 | } | ||
1032 | |||
1033 | /* | ||
1034 | * Create an AD1845 PCM subdevice on the SoundScape. The AD1845 | 955 | * Create an AD1845 PCM subdevice on the SoundScape. The AD1845 |
1035 | * is very much like a CS4231, with a few extra bits. We will | 956 | * is very much like a CS4231, with a few extra bits. We will |
1036 | * try to support at least some of the extra bits by overriding | 957 | * try to support at least some of the extra bits by overriding |
@@ -1055,11 +976,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, | |||
1055 | unsigned long flags; | 976 | unsigned long flags; |
1056 | struct snd_pcm *pcm; | 977 | struct snd_pcm *pcm; |
1057 | 978 | ||
1058 | #define AD1845_FREQ_SEL_ENABLE 0x08 | ||
1059 | |||
1060 | #define AD1845_PWR_DOWN_CTRL 0x1b | ||
1061 | #define AD1845_CRYS_CLOCK_SEL 0x1d | ||
1062 | |||
1063 | /* | 979 | /* |
1064 | * It turns out that the PLAYBACK_ENABLE bit is set | 980 | * It turns out that the PLAYBACK_ENABLE bit is set |
1065 | * by the lowlevel driver ... | 981 | * by the lowlevel driver ... |
@@ -1074,7 +990,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, | |||
1074 | */ | 990 | */ |
1075 | 991 | ||
1076 | if (sscape->type != SSCAPE_VIVO) { | 992 | if (sscape->type != SSCAPE_VIVO) { |
1077 | int val; | ||
1078 | /* | 993 | /* |
1079 | * The input clock frequency on the SoundScape must | 994 | * The input clock frequency on the SoundScape must |
1080 | * be 14.31818 MHz, because we must set this register | 995 | * be 14.31818 MHz, because we must set this register |
@@ -1082,22 +997,10 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, | |||
1082 | */ | 997 | */ |
1083 | snd_wss_mce_up(chip); | 998 | snd_wss_mce_up(chip); |
1084 | spin_lock_irqsave(&chip->reg_lock, flags); | 999 | spin_lock_irqsave(&chip->reg_lock, flags); |
1085 | snd_wss_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20); | 1000 | snd_wss_out(chip, AD1845_CLOCK, 0x20); |
1086 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1001 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1087 | snd_wss_mce_down(chip); | 1002 | snd_wss_mce_down(chip); |
1088 | 1003 | ||
1089 | /* | ||
1090 | * More custom configuration: | ||
1091 | * a) select "mode 2" and provide a current drive of 8mA | ||
1092 | * b) enable frequency selection (for capture/playback) | ||
1093 | */ | ||
1094 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1095 | snd_wss_out(chip, CS4231_MISC_INFO, | ||
1096 | CS4231_MODE2 | 0x10); | ||
1097 | val = snd_wss_in(chip, AD1845_PWR_DOWN_CTRL); | ||
1098 | snd_wss_out(chip, AD1845_PWR_DOWN_CTRL, | ||
1099 | val | AD1845_FREQ_SEL_ENABLE); | ||
1100 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1101 | } | 1004 | } |
1102 | 1005 | ||
1103 | err = snd_wss_pcm(chip, 0, &pcm); | 1006 | err = snd_wss_pcm(chip, 0, &pcm); |
@@ -1113,11 +1016,13 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, | |||
1113 | "for AD1845 chip\n"); | 1016 | "for AD1845 chip\n"); |
1114 | goto _error; | 1017 | goto _error; |
1115 | } | 1018 | } |
1116 | err = snd_wss_timer(chip, 0, NULL); | 1019 | if (chip->hardware != WSS_HW_AD1848) { |
1117 | if (err < 0) { | 1020 | err = snd_wss_timer(chip, 0, NULL); |
1118 | snd_printk(KERN_ERR "sscape: No timer device " | 1021 | if (err < 0) { |
1119 | "for AD1845 chip\n"); | 1022 | snd_printk(KERN_ERR "sscape: No timer device " |
1120 | goto _error; | 1023 | "for AD1845 chip\n"); |
1024 | goto _error; | ||
1025 | } | ||
1121 | } | 1026 | } |
1122 | 1027 | ||
1123 | if (sscape->type != SSCAPE_VIVO) { | 1028 | if (sscape->type != SSCAPE_VIVO) { |
@@ -1128,8 +1033,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, | |||
1128 | "MIDI mixer control\n"); | 1033 | "MIDI mixer control\n"); |
1129 | goto _error; | 1034 | goto _error; |
1130 | } | 1035 | } |
1131 | chip->set_playback_format = ad1845_playback_format; | ||
1132 | chip->set_capture_format = ad1845_capture_format; | ||
1133 | } | 1036 | } |
1134 | 1037 | ||
1135 | strcpy(card->driver, "SoundScape"); | 1038 | strcpy(card->driver, "SoundScape"); |
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 3d6c5f2838af..13299aebd077 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c | |||
@@ -646,6 +646,24 @@ static void snd_wss_playback_format(struct snd_wss *chip, | |||
646 | full_calib = 0; | 646 | full_calib = 0; |
647 | } | 647 | } |
648 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 648 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
649 | } else if (chip->hardware == WSS_HW_AD1845) { | ||
650 | unsigned rate = params_rate(params); | ||
651 | |||
652 | /* | ||
653 | * Program the AD1845 correctly for the playback stream. | ||
654 | * Note that we do NOT need to toggle the MCE bit because | ||
655 | * the PLAYBACK_ENABLE bit of the Interface Configuration | ||
656 | * register is set. | ||
657 | * | ||
658 | * NOTE: We seem to need to write to the MSB before the LSB | ||
659 | * to get the correct sample frequency. | ||
660 | */ | ||
661 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
662 | snd_wss_out(chip, CS4231_PLAYBK_FORMAT, (pdfr & 0xf0)); | ||
663 | snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff); | ||
664 | snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff); | ||
665 | full_calib = 0; | ||
666 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
649 | } | 667 | } |
650 | if (full_calib) { | 668 | if (full_calib) { |
651 | snd_wss_mce_up(chip); | 669 | snd_wss_mce_up(chip); |
@@ -690,6 +708,24 @@ static void snd_wss_capture_format(struct snd_wss *chip, | |||
690 | full_calib = 0; | 708 | full_calib = 0; |
691 | } | 709 | } |
692 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 710 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
711 | } else if (chip->hardware == WSS_HW_AD1845) { | ||
712 | unsigned rate = params_rate(params); | ||
713 | |||
714 | /* | ||
715 | * Program the AD1845 correctly for the capture stream. | ||
716 | * Note that we do NOT need to toggle the MCE bit because | ||
717 | * the PLAYBACK_ENABLE bit of the Interface Configuration | ||
718 | * register is set. | ||
719 | * | ||
720 | * NOTE: We seem to need to write to the MSB before the LSB | ||
721 | * to get the correct sample frequency. | ||
722 | */ | ||
723 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
724 | snd_wss_out(chip, CS4231_REC_FORMAT, (cdfr & 0xf0)); | ||
725 | snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff); | ||
726 | snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff); | ||
727 | full_calib = 0; | ||
728 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
693 | } | 729 | } |
694 | if (full_calib) { | 730 | if (full_calib) { |
695 | snd_wss_mce_up(chip); | 731 | snd_wss_mce_up(chip); |
@@ -1314,6 +1350,10 @@ static int snd_wss_probe(struct snd_wss *chip) | |||
1314 | chip->image[CS4231_ALT_FEATURE_2] = | 1350 | chip->image[CS4231_ALT_FEATURE_2] = |
1315 | chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01; | 1351 | chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01; |
1316 | } | 1352 | } |
1353 | /* enable fine grained frequency selection */ | ||
1354 | if (chip->hardware == WSS_HW_AD1845) | ||
1355 | chip->image[AD1845_PWR_DOWN] = 8; | ||
1356 | |||
1317 | ptr = (unsigned char *) &chip->image; | 1357 | ptr = (unsigned char *) &chip->image; |
1318 | regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32; | 1358 | regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32; |
1319 | snd_wss_mce_down(chip); | 1359 | snd_wss_mce_down(chip); |