aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-09-27 17:08:40 -0400
committerTakashi Iwai <tiwai@suse.de>2009-09-28 05:31:36 -0400
commitf0968e3f7a8ea30728d2580d3043a30ea9994ec6 (patch)
tree4e9adca4a7b7b33e8497eeb5c21935f0538f7624
parent4f272341c7a42a71586523f196b242bccde3be8c (diff)
ALSA: sscape: add supoort for SPEA Media FX/Reveal SC-600
Move code from the OSS sscape driver in order to support old Soundscape OEM models. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/isa/Kconfig6
-rw-r--r--sound/isa/sscape.c116
2 files changed, 86 insertions, 36 deletions
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 51a7e3777e17..b90fc164a79c 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -377,10 +377,12 @@ config SND_SSCAPE
377 select SND_WSS_LIB 377 select SND_WSS_LIB
378 help 378 help
379 Say Y here to include support for Ensoniq SoundScape 379 Say Y here to include support for Ensoniq SoundScape
380 soundcards. 380 and Ensoniq OEM soundcards.
381 381
382 The PCM audio is supported on SoundScape Classic, Elite, PnP 382 The PCM audio is supported on SoundScape Classic, Elite, PnP
383 and VIVO cards. The MIDI support is very experimental. 383 and VIVO cards. The supported OEM cards are SPEA Media FX and
384 Reveal SC-600.
385 The MIDI support is very experimental.
384 386
385 To compile this driver as a module, choose M here: the module 387 To compile this driver as a module, choose M here: the module
386 will be called snd-sscape. 388 will be called snd-sscape.
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 66187122377c..b11c35f6aefe 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -127,7 +127,8 @@ enum GA_REG {
127 127
128 128
129enum card_type { 129enum card_type {
130 SSCAPE, 130 MEDIA_FX, /* Sequoia S-1000 */
131 SSCAPE, /* Sequoia S-2000 */
131 SSCAPE_PNP, 132 SSCAPE_PNP,
132 SSCAPE_VIVO, 133 SSCAPE_VIVO,
133}; 134};
@@ -784,20 +785,25 @@ static struct snd_kcontrol_new midi_mixer_ctl = {
784 * These IRQs are encoded as bit patterns so that they can be 785 * These IRQs are encoded as bit patterns so that they can be
785 * written to the control registers. 786 * written to the control registers.
786 */ 787 */
787static unsigned __devinit get_irq_config(int irq) 788static unsigned __devinit get_irq_config(int sscape_type, int irq)
788{ 789{
789 static const int valid_irq[] = { 9, 5, 7, 10 }; 790 static const int valid_irq[] = { 9, 5, 7, 10 };
791 static const int old_irq[] = { 9, 7, 5, 15 };
790 unsigned cfg; 792 unsigned cfg;
791 793
792 for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg) { 794 if (sscape_type == MEDIA_FX) {
793 if (irq == valid_irq[cfg]) 795 for (cfg = 0; cfg < ARRAY_SIZE(old_irq); ++cfg)
794 return cfg; 796 if (irq == old_irq[cfg])
795 } /* for */ 797 return cfg;
798 } else {
799 for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg)
800 if (irq == valid_irq[cfg])
801 return cfg;
802 }
796 803
797 return INVALID_IRQ; 804 return INVALID_IRQ;
798} 805}
799 806
800
801/* 807/*
802 * Perform certain arcane port-checks to see whether there 808 * Perform certain arcane port-checks to see whether there
803 * is a SoundScape board lurking behind the given ports. 809 * is a SoundScape board lurking behind the given ports.
@@ -842,11 +848,39 @@ static int __devinit detect_sscape(struct soundscape *s, long wss_io)
842 if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e) 848 if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e)
843 goto _done; 849 goto _done;
844 850
845 d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; 851 if (s->ic_type == IC_OPUS)
846 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0); 852 activate_ad1845_unsafe(s->io_base);
847 853
848 if (s->type == SSCAPE_VIVO) 854 if (s->type == SSCAPE_VIVO)
849 wss_io += 4; 855 wss_io += 4;
856
857 d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f;
858 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);
859
860 /* wait for WSS codec */
861 for (d = 0; d < 500; d++) {
862 if ((inb(wss_io) & 0x80) == 0)
863 break;
864 spin_unlock_irqrestore(&s->lock, flags);
865 msleep(1);
866 spin_lock_irqsave(&s->lock, flags);
867 }
868 snd_printd(KERN_INFO "init delay = %d ms\n", d);
869
870 if ((inb(wss_io) & 0x80) != 0)
871 goto _done;
872
873 if (inb(wss_io + 2) == 0xff)
874 goto _done;
875
876 d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f;
877 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d);
878
879 if ((inb(wss_io) & 0x80) != 0)
880 s->type = MEDIA_FX;
881
882 d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f;
883 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);
850 /* wait for WSS codec */ 884 /* wait for WSS codec */
851 for (d = 0; d < 500; d++) { 885 for (d = 0; d < 500; d++) {
852 if ((inb(wss_io) & 0x80) == 0) 886 if ((inb(wss_io) & 0x80) == 0)
@@ -954,9 +988,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
954 if (sscape->type == SSCAPE_VIVO) 988 if (sscape->type == SSCAPE_VIVO)
955 port += 4; 989 port += 4;
956 990
957 if (dma1 == dma2)
958 dma2 = -1;
959
960 err = snd_wss_create(card, port, -1, irq, dma1, dma2, 991 err = snd_wss_create(card, port, -1, irq, dma1, dma2,
961 WSS_HW_DETECT, WSS_HWSHARE_DMA1, &chip); 992 WSS_HW_DETECT, WSS_HWSHARE_DMA1, &chip);
962 if (!err) { 993 if (!err) {
@@ -1051,21 +1082,7 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
1051 struct resource *wss_res; 1082 struct resource *wss_res;
1052 unsigned long flags; 1083 unsigned long flags;
1053 int err; 1084 int err;
1054 1085 const char *name;
1055 /*
1056 * Check that the user didn't pass us garbage data ...
1057 */
1058 irq_cfg = get_irq_config(irq[dev]);
1059 if (irq_cfg == INVALID_IRQ) {
1060 snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]);
1061 return -ENXIO;
1062 }
1063
1064 mpu_irq_cfg = get_irq_config(mpu_irq[dev]);
1065 if (mpu_irq_cfg == INVALID_IRQ) {
1066 printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
1067 return -ENXIO;
1068 }
1069 1086
1070 /* 1087 /*
1071 * Grab IO ports that we will need to probe so that we 1088 * Grab IO ports that we will need to probe so that we
@@ -1109,8 +1126,41 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
1109 goto _release_dma; 1126 goto _release_dma;
1110 } 1127 }
1111 1128
1112 printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", 1129 switch (sscape->type) {
1113 sscape->io_base, irq[dev], dma[dev]); 1130 case MEDIA_FX:
1131 name = "MediaFX/SoundFX";
1132 break;
1133 case SSCAPE:
1134 name = "Soundscape";
1135 break;
1136 case SSCAPE_PNP:
1137 name = "Soundscape PnP";
1138 break;
1139 case SSCAPE_VIVO:
1140 name = "Soundscape VIVO";
1141 break;
1142 default:
1143 name = "unknown Soundscape";
1144 break;
1145 }
1146
1147 printk(KERN_INFO "sscape: %s card detected at 0x%x, using IRQ %d, DMA %d\n",
1148 name, sscape->io_base, irq[dev], dma[dev]);
1149
1150 /*
1151 * Check that the user didn't pass us garbage data ...
1152 */
1153 irq_cfg = get_irq_config(sscape->type, irq[dev]);
1154 if (irq_cfg == INVALID_IRQ) {
1155 snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]);
1156 return -ENXIO;
1157 }
1158
1159 mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]);
1160 if (mpu_irq_cfg == INVALID_IRQ) {
1161 printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
1162 return -ENXIO;
1163 }
1114 1164
1115 if (sscape->type != SSCAPE_VIVO) { 1165 if (sscape->type != SSCAPE_VIVO) {
1116 /* 1166 /*
@@ -1141,8 +1191,6 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
1141 */ 1191 */
1142 spin_lock_irqsave(&sscape->lock, flags); 1192 spin_lock_irqsave(&sscape->lock, flags);
1143 1193
1144 activate_ad1845_unsafe(sscape->io_base);
1145
1146 sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x00); /* disable */ 1194 sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x00); /* disable */
1147 sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e); 1195 sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e);
1148 sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00); 1196 sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00);
@@ -1151,12 +1199,12 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
1151 * Enable and configure the DMA channels ... 1199 * Enable and configure the DMA channels ...
1152 */ 1200 */
1153 sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50); 1201 sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50);
1154 dma_cfg = (sscape->ic_type == IC_ODIE ? 0x70 : 0x40); 1202 dma_cfg = (sscape->ic_type == IC_OPUS ? 0x40 : 0x70);
1155 sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg); 1203 sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg);
1156 sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20); 1204 sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20);
1157 1205
1158 sscape_write_unsafe(sscape->io_base, 1206 mpu_irq_cfg |= mpu_irq_cfg << 2;
1159 GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); 1207 sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | mpu_irq_cfg);
1160 sscape_write_unsafe(sscape->io_base, 1208 sscape_write_unsafe(sscape->io_base,
1161 GA_CDCFG_REG, 0x09 | DMA_8BIT 1209 GA_CDCFG_REG, 0x09 | DMA_8BIT
1162 | (dma[dev] << 4) | (irq_cfg << 1)); 1210 | (dma[dev] << 4) | (irq_cfg << 1));