aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-12-26 09:52:54 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-12-26 09:52:54 -0500
commit7f50548abb5454bd82c25aae15f0a3bf6a530f46 (patch)
tree175b5d695437151f0f9f778ad8eb7f274468842f /sound/oss
parentb3172f222ab5afdc91ea058bd11c42cf169728f3 (diff)
parent6b7b284958d47b77d06745b36bc7f36dab769d9b (diff)
Merge commit 'v2.6.33-rc2' into for-2.6.33
Diffstat (limited to 'sound/oss')
-rw-r--r--sound/oss/Kconfig14
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/audio.c2
-rw-r--r--sound/oss/dmasound/dmasound_core.c4
-rw-r--r--sound/oss/dmasound/dmasound_paula.c2
-rw-r--r--sound/oss/hex2hex.c2
-rw-r--r--sound/oss/midi_synth.c2
-rw-r--r--sound/oss/mpu401.c2
-rw-r--r--sound/oss/pss.c6
-rw-r--r--sound/oss/sb_common.c4
-rw-r--r--sound/oss/sb_ess.c2
-rw-r--r--sound/oss/sh_dac_audio.c3
-rw-r--r--sound/oss/sscape.c1480
13 files changed, 14 insertions, 1510 deletions
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index bcf2a0698d54..a513651fa149 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -1,5 +1,3 @@
1# drivers/sound/Config.in
2#
3# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net> 1# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
4# More hacking for modularisation. 2# More hacking for modularisation.
5# 3#
@@ -287,18 +285,6 @@ config SOUND_DMAP
287 285
288 Say Y unless you have 16MB or more RAM or a PCI sound card. 286 Say Y unless you have 16MB or more RAM or a PCI sound card.
289 287
290config SOUND_SSCAPE
291 tristate "Ensoniq SoundScape support"
292 help
293 Answer Y if you have a sound card based on the Ensoniq SoundScape
294 chipset. Such cards are being manufactured at least by Ensoniq, Spea
295 and Reveal (Reveal makes also other cards).
296
297 If you compile the driver into the kernel, you have to add
298 "sscape=<io>,<irq>,<dma>,<mpuio>,<mpuirq>" to the kernel command
299 line.
300
301
302config SOUND_VMIDI 288config SOUND_VMIDI
303 tristate "Loopback MIDI device support" 289 tristate "Loopback MIDI device support"
304 help 290 help
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index e0ae4d4d6a5c..567b8a74178a 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -13,7 +13,6 @@ obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o
13obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o 13obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o
14obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o 14obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
15obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o 15obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o
16obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o
17obj-$(CONFIG_SOUND_MSS) += ad1848.o 16obj-$(CONFIG_SOUND_MSS) += ad1848.o
18obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o 17obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o
19obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o 18obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o
diff --git a/sound/oss/audio.c b/sound/oss/audio.c
index b69c05b7ea7b..7df48a25c4ee 100644
--- a/sound/oss/audio.c
+++ b/sound/oss/audio.c
@@ -838,7 +838,7 @@ static int dma_ioctl(int dev, unsigned int cmd, void __user *arg)
838 if ((err = audio_devs[dev]->d->prepare_for_input(dev, 838 if ((err = audio_devs[dev]->d->prepare_for_input(dev,
839 dmap_in->fragment_size, dmap_in->nbufs)) < 0) { 839 dmap_in->fragment_size, dmap_in->nbufs)) < 0) {
840 spin_unlock_irqrestore(&dmap_in->lock,flags); 840 spin_unlock_irqrestore(&dmap_in->lock,flags);
841 return -err; 841 return err;
842 } 842 }
843 dmap_in->dma_mode = DMODE_INPUT; 843 dmap_in->dma_mode = DMODE_INPUT;
844 audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT; 844 audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT;
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index 793b7f478433..3f3c3f71db4b 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -219,7 +219,9 @@ static int shared_resources_initialised;
219 * Mid level stuff 219 * Mid level stuff
220 */ 220 */
221 221
222struct sound_settings dmasound = { .lock = SPIN_LOCK_UNLOCKED }; 222struct sound_settings dmasound = {
223 .lock = __SPIN_LOCK_UNLOCKED(dmasound.lock)
224};
223 225
224static inline void sound_silence(void) 226static inline void sound_silence(void)
225{ 227{
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
index 06e9e88e4c05..bb14e4c67e89 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -657,7 +657,7 @@ static int AmiStateInfo(char *buffer, size_t space)
657 len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n", 657 len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n",
658 dmasound.volume_right); 658 dmasound.volume_right);
659 if (len >= space) { 659 if (len >= space) {
660 printk(KERN_ERR "dmasound_paula: overlowed state buffer alloc.\n") ; 660 printk(KERN_ERR "dmasound_paula: overflowed state buffer alloc.\n") ;
661 len = space ; 661 len = space ;
662 } 662 }
663 return len; 663 return len;
diff --git a/sound/oss/hex2hex.c b/sound/oss/hex2hex.c
index 5460faae98c9..041ef5c52bc2 100644
--- a/sound/oss/hex2hex.c
+++ b/sound/oss/hex2hex.c
@@ -12,7 +12,7 @@
12#define MAX_SIZE (256*1024) 12#define MAX_SIZE (256*1024)
13unsigned char buf[MAX_SIZE]; 13unsigned char buf[MAX_SIZE];
14 14
15int loadhex(FILE *inf, unsigned char *buf) 15static int loadhex(FILE *inf, unsigned char *buf)
16{ 16{
17 int l=0, c, i; 17 int l=0, c, i;
18 18
diff --git a/sound/oss/midi_synth.c b/sound/oss/midi_synth.c
index 9e450988ed36..3bc7104c5379 100644
--- a/sound/oss/midi_synth.c
+++ b/sound/oss/midi_synth.c
@@ -426,7 +426,7 @@ midi_synth_open(int dev, int mode)
426 int err; 426 int err;
427 struct midi_input_info *inc; 427 struct midi_input_info *inc;
428 428
429 if (orig_dev < 0 || orig_dev > num_midis || midi_devs[orig_dev] == NULL) 429 if (orig_dev < 0 || orig_dev >= num_midis || midi_devs[orig_dev] == NULL)
430 return -ENXIO; 430 return -ENXIO;
431 431
432 midi2synth[orig_dev] = dev; 432 midi2synth[orig_dev] = dev;
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c
index 734b8f9e2f78..0af9d24feb8f 100644
--- a/sound/oss/mpu401.c
+++ b/sound/oss/mpu401.c
@@ -770,7 +770,7 @@ static int mpu_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
770 770
771 midi_dev = synth_devs[dev]->midi_dev; 771 midi_dev = synth_devs[dev]->midi_dev;
772 772
773 if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev] == NULL) 773 if (midi_dev < 0 || midi_dev >= num_midis || midi_devs[midi_dev] == NULL)
774 return -ENXIO; 774 return -ENXIO;
775 775
776 devc = &dev_conf[midi_dev]; 776 devc = &dev_conf[midi_dev];
diff --git a/sound/oss/pss.c b/sound/oss/pss.c
index 83f5ee236b12..e19dd5dcc2de 100644
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -269,7 +269,7 @@ static int pss_reset_dsp(pss_confdata * devc)
269 unsigned long i, limit = jiffies + HZ/10; 269 unsigned long i, limit = jiffies + HZ/10;
270 270
271 outw(0x2000, REG(PSS_CONTROL)); 271 outw(0x2000, REG(PSS_CONTROL));
272 for (i = 0; i < 32768 && (limit-jiffies >= 0); i++) 272 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
273 inw(REG(PSS_CONTROL)); 273 inw(REG(PSS_CONTROL));
274 outw(0x0000, REG(PSS_CONTROL)); 274 outw(0x0000, REG(PSS_CONTROL));
275 return 1; 275 return 1;
@@ -369,11 +369,11 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size
369 outw(0, REG(PSS_DATA)); 369 outw(0, REG(PSS_DATA));
370 370
371 limit = jiffies + HZ/10; 371 limit = jiffies + HZ/10;
372 for (i = 0; i < 32768 && (limit - jiffies >= 0); i++) 372 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
373 val = inw(REG(PSS_STATUS)); 373 val = inw(REG(PSS_STATUS));
374 374
375 limit = jiffies + HZ/10; 375 limit = jiffies + HZ/10;
376 for (i = 0; i < 32768 && (limit-jiffies >= 0); i++) 376 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
377 { 377 {
378 val = inw(REG(PSS_STATUS)); 378 val = inw(REG(PSS_STATUS));
379 if (val & 0x4000) 379 if (val & 0x4000)
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c
index 77d0e5efda76..ce4db49291f7 100644
--- a/sound/oss/sb_common.c
+++ b/sound/oss/sb_common.c
@@ -157,7 +157,7 @@ static void sb_intr (sb_devc *devc)
157 break; 157 break;
158 158
159 default: 159 default:
160 /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */ 160 /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
161 ; 161 ;
162 } 162 }
163 } 163 }
@@ -177,7 +177,7 @@ static void sb_intr (sb_devc *devc)
177 break; 177 break;
178 178
179 default: 179 default:
180 /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */ 180 /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
181 ; 181 ;
182 } 182 }
183 } 183 }
diff --git a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c
index 180e95c87e3e..51a3d381a59e 100644
--- a/sound/oss/sb_ess.c
+++ b/sound/oss/sb_ess.c
@@ -782,7 +782,7 @@ printk(KERN_INFO "FKS: ess_handle_channel %s irq_mode=%d\n", channel, irq_mode);
782 break; 782 break;
783 783
784 default:; 784 default:;
785 /* printk(KERN_WARN "ESS: Unexpected interrupt\n"); */ 785 /* printk(KERN_WARNING "ESS: Unexpected interrupt\n"); */
786 } 786 }
787} 787}
788 788
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index b2ed8757542a..4153752507e3 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -164,9 +164,6 @@ static ssize_t dac_audio_write(struct file *file, const char *buf, size_t count,
164 int free; 164 int free;
165 int nbytes; 165 int nbytes;
166 166
167 if (count < 0)
168 return -EINVAL;
169
170 if (!count) { 167 if (!count) {
171 dac_audio_sync(); 168 dac_audio_sync();
172 return 0; 169 return 0;
diff --git a/sound/oss/sscape.c b/sound/oss/sscape.c
deleted file mode 100644
index 30c36d1f35d7..000000000000
--- a/sound/oss/sscape.c
+++ /dev/null
@@ -1,1480 +0,0 @@
1/*
2 * sound/oss/sscape.c
3 *
4 * Low level driver for Ensoniq SoundScape
5 *
6 *
7 * Copyright (C) by Hannu Savolainen 1993-1997
8 *
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
11 * for more info.
12 *
13 *
14 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
15 * Sergey Smitienko : ensoniq p'n'p support
16 * Christoph Hellwig : adapted to module_init/module_exit
17 * Bartlomiej Zolnierkiewicz : added __init to attach_sscape()
18 * Chris Rankin : Specify that this module owns the coprocessor
19 * Arnaldo C. de Melo : added missing restore_flags in sscape_pnp_upload_file
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24
25#include "sound_config.h"
26#include "sound_firmware.h"
27
28#include <linux/types.h>
29#include <linux/errno.h>
30#include <linux/signal.h>
31#include <linux/fcntl.h>
32#include <linux/ctype.h>
33#include <linux/stddef.h>
34#include <linux/kmod.h>
35#include <asm/dma.h>
36#include <asm/io.h>
37#include <linux/wait.h>
38#include <linux/slab.h>
39#include <linux/ioport.h>
40#include <linux/delay.h>
41#include <linux/proc_fs.h>
42#include <linux/mm.h>
43#include <linux/spinlock.h>
44
45#include "coproc.h"
46
47#include "ad1848.h"
48#include "mpu401.h"
49
50/*
51 * I/O ports
52 */
53#define MIDI_DATA 0
54#define MIDI_CTRL 1
55#define HOST_CTRL 2
56#define TX_READY 0x02
57#define RX_READY 0x01
58#define HOST_DATA 3
59#define ODIE_ADDR 4
60#define ODIE_DATA 5
61
62/*
63 * Indirect registers
64 */
65
66#define GA_INTSTAT_REG 0
67#define GA_INTENA_REG 1
68#define GA_DMAA_REG 2
69#define GA_DMAB_REG 3
70#define GA_INTCFG_REG 4
71#define GA_DMACFG_REG 5
72#define GA_CDCFG_REG 6
73#define GA_SMCFGA_REG 7
74#define GA_SMCFGB_REG 8
75#define GA_HMCTL_REG 9
76
77/*
78 * DMA channel identifiers (A and B)
79 */
80
81#define SSCAPE_DMA_A 0
82#define SSCAPE_DMA_B 1
83
84#define PORT(name) (devc->base+name)
85
86/*
87 * Host commands recognized by the OBP microcode
88 */
89
90#define CMD_GEN_HOST_ACK 0x80
91#define CMD_GEN_MPU_ACK 0x81
92#define CMD_GET_BOARD_TYPE 0x82
93#define CMD_SET_CONTROL 0x88 /* Old firmware only */
94#define CMD_GET_CONTROL 0x89 /* Old firmware only */
95#define CTL_MASTER_VOL 0
96#define CTL_MIC_MODE 2
97#define CTL_SYNTH_VOL 4
98#define CTL_WAVE_VOL 7
99#define CMD_SET_EXTMIDI 0x8a
100#define CMD_GET_EXTMIDI 0x8b
101#define CMD_SET_MT32 0x8c
102#define CMD_GET_MT32 0x8d
103
104#define CMD_ACK 0x80
105
106#define IC_ODIE 1
107#define IC_OPUS 2
108
109typedef struct sscape_info
110{
111 int base, irq, dma;
112
113 int codec, codec_irq; /* required to setup pnp cards*/
114 int codec_type;
115 int ic_type;
116 char* raw_buf;
117 unsigned long raw_buf_phys;
118 int buffsize; /* -------------------------- */
119 spinlock_t lock;
120 int ok; /* Properly detected */
121 int failed;
122 int dma_allocated;
123 int codec_audiodev;
124 int opened;
125 int *osp;
126 int my_audiodev;
127} sscape_info;
128
129static struct sscape_info adev_info = {
130 0
131};
132
133static struct sscape_info *devc = &adev_info;
134static int sscape_mididev = -1;
135
136/* Some older cards have assigned interrupt bits differently than new ones */
137static char valid_interrupts_old[] = {
138 9, 7, 5, 15
139};
140
141static char valid_interrupts_new[] = {
142 9, 5, 7, 10
143};
144
145static char *valid_interrupts = valid_interrupts_new;
146
147/*
148 * See the bottom of the driver. This can be set by spea =0/1.
149 */
150
151#ifdef REVEAL_SPEA
152static char old_hardware = 1;
153#else
154static char old_hardware;
155#endif
156
157static void sleep(unsigned howlong)
158{
159 current->state = TASK_INTERRUPTIBLE;
160 schedule_timeout(howlong);
161}
162
163static unsigned char sscape_read(struct sscape_info *devc, int reg)
164{
165 unsigned long flags;
166 unsigned char val;
167
168 spin_lock_irqsave(&devc->lock,flags);
169 outb(reg, PORT(ODIE_ADDR));
170 val = inb(PORT(ODIE_DATA));
171 spin_unlock_irqrestore(&devc->lock,flags);
172 return val;
173}
174
175static void __sscape_write(int reg, int data)
176{
177 outb(reg, PORT(ODIE_ADDR));
178 outb(data, PORT(ODIE_DATA));
179}
180
181static void sscape_write(struct sscape_info *devc, int reg, int data)
182{
183 unsigned long flags;
184
185 spin_lock_irqsave(&devc->lock,flags);
186 __sscape_write(reg, data);
187 spin_unlock_irqrestore(&devc->lock,flags);
188}
189
190static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg)
191{
192 unsigned char res;
193 unsigned long flags;
194
195 spin_lock_irqsave(&devc->lock,flags);
196 outb( reg, devc -> codec);
197 res = inb (devc -> codec + 1);
198 spin_unlock_irqrestore(&devc->lock,flags);
199 return res;
200
201}
202
203static void sscape_pnp_write_codec(sscape_info* devc, unsigned char reg, unsigned char data)
204{
205 unsigned long flags;
206
207 spin_lock_irqsave(&devc->lock,flags);
208 outb( reg, devc -> codec);
209 outb( data, devc -> codec + 1);
210 spin_unlock_irqrestore(&devc->lock,flags);
211}
212
213static void host_open(struct sscape_info *devc)
214{
215 outb((0x00), PORT(HOST_CTRL)); /* Put the board to the host mode */
216}
217
218static void host_close(struct sscape_info *devc)
219{
220 outb((0x03), PORT(HOST_CTRL)); /* Put the board to the MIDI mode */
221}
222
223static int host_write(struct sscape_info *devc, unsigned char *data, int count)
224{
225 unsigned long flags;
226 int i, timeout_val;
227
228 spin_lock_irqsave(&devc->lock,flags);
229 /*
230 * Send the command and data bytes
231 */
232
233 for (i = 0; i < count; i++)
234 {
235 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
236 if (inb(PORT(HOST_CTRL)) & TX_READY)
237 break;
238
239 if (timeout_val <= 0)
240 {
241 spin_unlock_irqrestore(&devc->lock,flags);
242 return 0;
243 }
244 outb(data[i], PORT(HOST_DATA));
245 }
246 spin_unlock_irqrestore(&devc->lock,flags);
247 return 1;
248}
249
250static int host_read(struct sscape_info *devc)
251{
252 unsigned long flags;
253 int timeout_val;
254 unsigned char data;
255
256 spin_lock_irqsave(&devc->lock,flags);
257 /*
258 * Read a byte
259 */
260
261 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
262 if (inb(PORT(HOST_CTRL)) & RX_READY)
263 break;
264
265 if (timeout_val <= 0)
266 {
267 spin_unlock_irqrestore(&devc->lock,flags);
268 return -1;
269 }
270 data = inb(PORT(HOST_DATA));
271 spin_unlock_irqrestore(&devc->lock,flags);
272 return data;
273}
274
275#if 0 /* unused */
276static int host_command1(struct sscape_info *devc, int cmd)
277{
278 unsigned char buf[10];
279 buf[0] = (unsigned char) (cmd & 0xff);
280 return host_write(devc, buf, 1);
281}
282#endif /* unused */
283
284
285static int host_command2(struct sscape_info *devc, int cmd, int parm1)
286{
287 unsigned char buf[10];
288
289 buf[0] = (unsigned char) (cmd & 0xff);
290 buf[1] = (unsigned char) (parm1 & 0xff);
291
292 return host_write(devc, buf, 2);
293}
294
295static int host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2)
296{
297 unsigned char buf[10];
298
299 buf[0] = (unsigned char) (cmd & 0xff);
300 buf[1] = (unsigned char) (parm1 & 0xff);
301 buf[2] = (unsigned char) (parm2 & 0xff);
302 return host_write(devc, buf, 3);
303}
304
305static void set_mt32(struct sscape_info *devc, int value)
306{
307 host_open(devc);
308 host_command2(devc, CMD_SET_MT32, value ? 1 : 0);
309 if (host_read(devc) != CMD_ACK)
310 {
311 /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
312 }
313 host_close(devc);
314}
315
316static void set_control(struct sscape_info *devc, int ctrl, int value)
317{
318 host_open(devc);
319 host_command3(devc, CMD_SET_CONTROL, ctrl, value);
320 if (host_read(devc) != CMD_ACK)
321 {
322 /* printk( "SNDSCAPE: Setting control (%d) failed\n", ctrl); */
323 }
324 host_close(devc);
325}
326
327static void do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
328{
329 unsigned char temp;
330
331 if (dma_chan != SSCAPE_DMA_A)
332 {
333 printk(KERN_WARNING "soundscape: Tried to use DMA channel != A. Why?\n");
334 return;
335 }
336 audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE;
337 DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode);
338 audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE;
339
340 temp = devc->dma << 4; /* Setup DMA channel select bits */
341 if (devc->dma <= 3)
342 temp |= 0x80; /* 8 bit DMA channel */
343
344 temp |= 1; /* Trigger DMA */
345 sscape_write(devc, GA_DMAA_REG, temp);
346 temp &= 0xfe; /* Clear DMA trigger */
347 sscape_write(devc, GA_DMAA_REG, temp);
348}
349
350static int verify_mpu(struct sscape_info *devc)
351{
352 /*
353 * The SoundScape board could be in three modes (MPU, 8250 and host).
354 * If the card is not in the MPU mode, enabling the MPU driver will
355 * cause infinite loop (the driver believes that there is always some
356 * received data in the buffer.
357 *
358 * Detect this by looking if there are more than 10 received MIDI bytes
359 * (0x00) in the buffer.
360 */
361
362 int i;
363
364 for (i = 0; i < 10; i++)
365 {
366 if (inb(devc->base + HOST_CTRL) & 0x80)
367 return 1;
368
369 if (inb(devc->base) != 0x00)
370 return 1;
371 }
372 printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n");
373 return 0;
374}
375
376static int sscape_coproc_open(void *dev_info, int sub_device)
377{
378 if (sub_device == COPR_MIDI)
379 {
380 set_mt32(devc, 0);
381 if (!verify_mpu(devc))
382 return -EIO;
383 }
384 return 0;
385}
386
387static void sscape_coproc_close(void *dev_info, int sub_device)
388{
389 struct sscape_info *devc = dev_info;
390 unsigned long flags;
391
392 spin_lock_irqsave(&devc->lock,flags);
393 if (devc->dma_allocated)
394 {
395 __sscape_write(GA_DMAA_REG, 0x20); /* DMA channel disabled */
396 devc->dma_allocated = 0;
397 }
398 spin_unlock_irqrestore(&devc->lock,flags);
399 return;
400}
401
402static void sscape_coproc_reset(void *dev_info)
403{
404}
405
406static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
407{
408 unsigned long flags;
409 unsigned char temp;
410 volatile int done, timeout_val;
411 static unsigned char codec_dma_bits;
412
413 if (flag & CPF_FIRST)
414 {
415 /*
416 * First block. Have to allocate DMA and to reset the board
417 * before continuing.
418 */
419
420 spin_lock_irqsave(&devc->lock,flags);
421 codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
422
423 if (devc->dma_allocated == 0)
424 devc->dma_allocated = 1;
425
426 spin_unlock_irqrestore(&devc->lock,flags);
427
428 sscape_write(devc, GA_HMCTL_REG,
429 (temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f); /*Reset */
430
431 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
432 sscape_read(devc, GA_HMCTL_REG); /* Delay */
433
434 /* Take board out of reset */
435 sscape_write(devc, GA_HMCTL_REG,
436 (temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
437 }
438 /*
439 * Transfer one code block using DMA
440 */
441 if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
442 {
443 printk(KERN_WARNING "soundscape: DMA buffer not available\n");
444 return 0;
445 }
446 memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
447
448 spin_lock_irqsave(&devc->lock,flags);
449
450 /******** INTERRUPTS DISABLED NOW ********/
451
452 do_dma(devc, SSCAPE_DMA_A,
453 audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
454 size, DMA_MODE_WRITE);
455
456 /*
457 * Wait until transfer completes.
458 */
459
460 done = 0;
461 timeout_val = 30;
462 while (!done && timeout_val-- > 0)
463 {
464 int resid;
465
466 if (HZ / 50)
467 sleep(HZ / 50);
468 clear_dma_ff(devc->dma);
469 if ((resid = get_dma_residue(devc->dma)) == 0)
470 done = 1;
471 }
472
473 spin_unlock_irqrestore(&devc->lock,flags);
474 if (!done)
475 return 0;
476
477 if (flag & CPF_LAST)
478 {
479 /*
480 * Take the board out of reset
481 */
482 outb((0x00), PORT(HOST_CTRL));
483 outb((0x00), PORT(MIDI_CTRL));
484
485 temp = sscape_read(devc, GA_HMCTL_REG);
486 temp |= 0x40;
487 sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */
488
489 /*
490 * Wait until the ODB wakes up
491 */
492 spin_lock_irqsave(&devc->lock,flags);
493 done = 0;
494 timeout_val = 5 * HZ;
495 while (!done && timeout_val-- > 0)
496 {
497 unsigned char x;
498
499 sleep(1);
500 x = inb(PORT(HOST_DATA));
501 if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */
502 {
503 DDB(printk("Soundscape: Acknowledge = %x\n", x));
504 done = 1;
505 }
506 }
507 sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
508
509 spin_unlock_irqrestore(&devc->lock,flags);
510 if (!done)
511 {
512 printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
513 return 0;
514 }
515 spin_lock_irqsave(&devc->lock,flags);
516 done = 0;
517 timeout_val = 5 * HZ;
518 while (!done && timeout_val-- > 0)
519 {
520 sleep(1);
521 if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */
522 done = 1;
523 }
524 spin_unlock_irqrestore(&devc->lock,flags);
525 if (!done)
526 {
527 printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
528 return 0;
529 }
530 printk(KERN_INFO "SoundScape board initialized OK\n");
531 set_control(devc, CTL_MASTER_VOL, 100);
532 set_control(devc, CTL_SYNTH_VOL, 100);
533
534#ifdef SSCAPE_DEBUG3
535 /*
536 * Temporary debugging aid. Print contents of the registers after
537 * downloading the code.
538 */
539 {
540 int i;
541
542 for (i = 0; i < 13; i++)
543 printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
544 }
545#endif
546
547 }
548 return 1;
549}
550
551static int download_boot_block(void *dev_info, copr_buffer * buf)
552{
553 if (buf->len <= 0 || buf->len > sizeof(buf->data))
554 return -EINVAL;
555
556 if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags))
557 {
558 printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n");
559 return -EIO;
560 }
561 return 0;
562}
563
564static int sscape_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, int local)
565{
566 copr_buffer *buf;
567 int err;
568
569 switch (cmd)
570 {
571 case SNDCTL_COPR_RESET:
572 sscape_coproc_reset(dev_info);
573 return 0;
574
575 case SNDCTL_COPR_LOAD:
576 buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
577 if (buf == NULL)
578 return -ENOSPC;
579 if (copy_from_user(buf, arg, sizeof(copr_buffer)))
580 {
581 vfree(buf);
582 return -EFAULT;
583 }
584 err = download_boot_block(dev_info, buf);
585 vfree(buf);
586 return err;
587
588 default:
589 return -EINVAL;
590 }
591}
592
593static coproc_operations sscape_coproc_operations =
594{
595 "SoundScape M68K",
596 THIS_MODULE,
597 sscape_coproc_open,
598 sscape_coproc_close,
599 sscape_coproc_ioctl,
600 sscape_coproc_reset,
601 &adev_info
602};
603
604static struct resource *sscape_ports;
605static int sscape_is_pnp;
606
607static void __init attach_sscape(struct address_info *hw_config)
608{
609#ifndef SSCAPE_REGS
610 /*
611 * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
612 * These values are card
613 * dependent. If you have another SoundScape based card, you have to
614 * find the correct values. Do the following:
615 * - Compile this driver with SSCAPE_DEBUG1 defined.
616 * - Shut down and power off your machine.
617 * - Boot with DOS so that the SSINIT.EXE program is run.
618 * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
619 * when detecting the SoundScape.
620 * - Modify the following list to use the values printed during boot.
621 * Undefine the SSCAPE_DEBUG1
622 */
623#define SSCAPE_REGS { \
624/* I0 */ 0x00, \
625/* I1 */ 0xf0, /* Note! Ignored. Set always to 0xf0 */ \
626/* I2 */ 0x20, /* Note! Ignored. Set always to 0x20 */ \
627/* I3 */ 0x20, /* Note! Ignored. Set always to 0x20 */ \
628/* I4 */ 0xf5, /* Ignored */ \
629/* I5 */ 0x10, \
630/* I6 */ 0x00, \
631/* I7 */ 0x2e, /* I7 MEM config A. Likely to vary between models */ \
632/* I8 */ 0x00, /* I8 MEM config B. Likely to vary between models */ \
633/* I9 */ 0x40 /* Ignored */ \
634 }
635#endif
636
637 unsigned long flags;
638 static unsigned char regs[10] = SSCAPE_REGS;
639
640 int i, irq_bits = 0xff;
641
642 if (old_hardware)
643 {
644 valid_interrupts = valid_interrupts_old;
645 conf_printf("Ensoniq SoundScape (old)", hw_config);
646 }
647 else
648 conf_printf("Ensoniq SoundScape", hw_config);
649
650 for (i = 0; i < 4; i++)
651 {
652 if (hw_config->irq == valid_interrupts[i])
653 {
654 irq_bits = i;
655 break;
656 }
657 }
658 if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
659 {
660 printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
661 release_region(devc->base, 2);
662 release_region(devc->base + 2, 6);
663 if (sscape_is_pnp)
664 release_region(devc->codec, 2);
665 return;
666 }
667
668 if (!sscape_is_pnp) {
669
670 spin_lock_irqsave(&devc->lock,flags);
671 /* Host interrupt enable */
672 sscape_write(devc, 1, 0xf0); /* All interrupts enabled */
673 /* DMA A status/trigger register */
674 sscape_write(devc, 2, 0x20); /* DMA channel disabled */
675 /* DMA B status/trigger register */
676 sscape_write(devc, 3, 0x20); /* DMA channel disabled */
677 /* Host interrupt config reg */
678 sscape_write(devc, 4, 0xf0 | (irq_bits << 2) | irq_bits);
679 /* Don't destroy CD-ROM DMA config bits (0xc0) */
680 sscape_write(devc, 5, (regs[5] & 0x3f) | (sscape_read(devc, 5) & 0xc0));
681 /* CD-ROM config (WSS codec actually) */
682 sscape_write(devc, 6, regs[6]);
683 sscape_write(devc, 7, regs[7]);
684 sscape_write(devc, 8, regs[8]);
685 /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
686 sscape_write(devc, 9, (sscape_read(devc, 9) & 0xf0) | 0x08);
687 spin_unlock_irqrestore(&devc->lock,flags);
688 }
689#ifdef SSCAPE_DEBUG2
690 /*
691 * Temporary debugging aid. Print contents of the registers after
692 * changing them.
693 */
694 {
695 int i;
696
697 for (i = 0; i < 13; i++)
698 printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
699 }
700#endif
701
702 if (probe_mpu401(hw_config, sscape_ports))
703 hw_config->always_detect = 1;
704 hw_config->name = "SoundScape";
705
706 hw_config->irq *= -1; /* Negative value signals IRQ sharing */
707 attach_mpu401(hw_config, THIS_MODULE);
708 hw_config->irq *= -1; /* Restore it */
709
710 if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
711 {
712 sscape_mididev = hw_config->slots[1];
713 midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
714 }
715 sscape_write(devc, GA_INTENA_REG, 0x80); /* Master IRQ enable */
716 devc->ok = 1;
717 devc->failed = 0;
718}
719
720static int detect_ga(sscape_info * devc)
721{
722 unsigned char save;
723
724 DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));
725
726 /*
727 * First check that the address register of "ODIE" is
728 * there and that it has exactly 4 writable bits.
729 * First 4 bits
730 */
731
732 if ((save = inb(PORT(ODIE_ADDR))) & 0xf0)
733 {
734 DDB(printk("soundscape: Detect error A\n"));
735 return 0;
736 }
737 outb((0x00), PORT(ODIE_ADDR));
738 if (inb(PORT(ODIE_ADDR)) != 0x00)
739 {
740 DDB(printk("soundscape: Detect error B\n"));
741 return 0;
742 }
743 outb((0xff), PORT(ODIE_ADDR));
744 if (inb(PORT(ODIE_ADDR)) != 0x0f)
745 {
746 DDB(printk("soundscape: Detect error C\n"));
747 return 0;
748 }
749 outb((save), PORT(ODIE_ADDR));
750
751 /*
752 * Now verify that some indirect registers return zero on some bits.
753 * This may break the driver with some future revisions of "ODIE" but...
754 */
755
756 if (sscape_read(devc, 0) & 0x0c)
757 {
758 DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0)));
759 return 0;
760 }
761 if (sscape_read(devc, 1) & 0x0f)
762 {
763 DDB(printk("soundscape: Detect error E\n"));
764 return 0;
765 }
766 if (sscape_read(devc, 5) & 0x0f)
767 {
768 DDB(printk("soundscape: Detect error F\n"));
769 return 0;
770 }
771 return 1;
772}
773
774static int sscape_read_host_ctrl(sscape_info* devc)
775{
776 return host_read(devc);
777}
778
779static void sscape_write_host_ctrl2(sscape_info *devc, int a, int b)
780{
781 host_command2(devc, a, b);
782}
783
784static int sscape_alloc_dma(sscape_info *devc)
785{
786 char *start_addr, *end_addr;
787 int dma_pagesize;
788 int sz, size;
789 struct page *page;
790
791 if (devc->raw_buf != NULL) return 0; /* Already done */
792 dma_pagesize = (devc->dma < 4) ? (64 * 1024) : (128 * 1024);
793 devc->raw_buf = NULL;
794 devc->buffsize = 8192*4;
795 if (devc->buffsize > dma_pagesize) devc->buffsize = dma_pagesize;
796 start_addr = NULL;
797 /*
798 * Now loop until we get a free buffer. Try to get smaller buffer if
799 * it fails. Don't accept smaller than 8k buffer for performance
800 * reasons.
801 */
802 while (start_addr == NULL && devc->buffsize > PAGE_SIZE) {
803 for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
804 devc->buffsize = PAGE_SIZE * (1 << sz);
805 start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA, sz);
806 if (start_addr == NULL) devc->buffsize /= 2;
807 }
808
809 if (start_addr == NULL) {
810 printk(KERN_ERR "sscape pnp init error: Couldn't allocate DMA buffer\n");
811 return 0;
812 } else {
813 /* make some checks */
814 end_addr = start_addr + devc->buffsize - 1;
815 /* now check if it fits into the same dma-pagesize */
816
817 if (((long) start_addr & ~(dma_pagesize - 1)) != ((long) end_addr & ~(dma_pagesize - 1))
818 || end_addr >= (char *) (MAX_DMA_ADDRESS)) {
819 printk(KERN_ERR "sscape pnp: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, devc->buffsize);
820 return 0;
821 }
822 }
823 devc->raw_buf = start_addr;
824 devc->raw_buf_phys = virt_to_bus(start_addr);
825
826 for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
827 SetPageReserved(page);
828 return 1;
829}
830
831static void sscape_free_dma(sscape_info *devc)
832{
833 int sz, size;
834 unsigned long start_addr, end_addr;
835 struct page *page;
836
837 if (devc->raw_buf == NULL) return;
838 for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
839 start_addr = (unsigned long) devc->raw_buf;
840 end_addr = start_addr + devc->buffsize;
841
842 for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
843 ClearPageReserved(page);
844
845 free_pages((unsigned long) devc->raw_buf, sz);
846 devc->raw_buf = NULL;
847}
848
849/* Intel version !!!!!!!!! */
850
851static int sscape_start_dma(int chan, unsigned long physaddr, int count, int dma_mode)
852{
853 unsigned long flags;
854
855 flags = claim_dma_lock();
856 disable_dma(chan);
857 clear_dma_ff(chan);
858 set_dma_mode(chan, dma_mode);
859 set_dma_addr(chan, physaddr);
860 set_dma_count(chan, count);
861 enable_dma(chan);
862 release_dma_lock(flags);
863 return 0;
864}
865
866static void sscape_pnp_start_dma(sscape_info* devc, int arg )
867{
868 int reg;
869 if (arg == 0) reg = 2;
870 else reg = 3;
871
872 sscape_write(devc, reg, sscape_read( devc, reg) | 0x01);
873 sscape_write(devc, reg, sscape_read( devc, reg) & 0xFE);
874}
875
876static int sscape_pnp_wait_dma (sscape_info* devc, int arg )
877{
878 int reg;
879 unsigned long i;
880 unsigned char d;
881
882 if (arg == 0) reg = 2;
883 else reg = 3;
884
885 sleep ( 1 );
886 i = 0;
887 do {
888 d = sscape_read(devc, reg) & 1;
889 if ( d == 1) break;
890 i++;
891 } while (i < 500000);
892 d = sscape_read(devc, reg) & 1;
893 return d;
894}
895
896static int sscape_pnp_alloc_dma(sscape_info* devc)
897{
898 /* printk(KERN_INFO "sscape: requesting dma\n"); */
899 if (request_dma(devc -> dma, "sscape")) return 0;
900 /* printk(KERN_INFO "sscape: dma channel allocated\n"); */
901 if (!sscape_alloc_dma(devc)) {
902 free_dma(devc -> dma);
903 return 0;
904 };
905 return 1;
906}
907
908static void sscape_pnp_free_dma(sscape_info* devc)
909{
910 sscape_free_dma( devc);
911 free_dma(devc -> dma );
912 /* printk(KERN_INFO "sscape: dma released\n"); */
913}
914
915static int sscape_pnp_upload_file(sscape_info* devc, char* fn)
916{
917 int done = 0;
918 int timeout_val;
919 char* data,*dt;
920 int len,l;
921 unsigned long flags;
922
923 sscape_write( devc, 9, sscape_read(devc, 9 ) & 0x3F );
924 sscape_write( devc, 2, (devc -> dma << 4) | 0x80 );
925 sscape_write( devc, 3, 0x20 );
926 sscape_write( devc, 9, sscape_read( devc, 9 ) | 0x80 );
927
928 len = mod_firmware_load(fn, &data);
929 if (len == 0) {
930 printk(KERN_ERR "sscape: file not found: %s\n", fn);
931 return 0;
932 }
933 dt = data;
934 spin_lock_irqsave(&devc->lock,flags);
935 while ( len > 0 ) {
936 if (len > devc -> buffsize) l = devc->buffsize;
937 else l = len;
938 len -= l;
939 memcpy(devc->raw_buf, dt, l); dt += l;
940 sscape_start_dma(devc->dma, devc->raw_buf_phys, l, 0x48);
941 sscape_pnp_start_dma ( devc, 0 );
942 if (sscape_pnp_wait_dma ( devc, 0 ) == 0) {
943 spin_unlock_irqrestore(&devc->lock,flags);
944 return 0;
945 }
946 }
947
948 spin_unlock_irqrestore(&devc->lock,flags);
949 vfree(data);
950
951 outb(0, devc -> base + 2);
952 outb(0, devc -> base);
953
954 sscape_write ( devc, 9, sscape_read( devc, 9 ) | 0x40);
955
956 timeout_val = 5 * HZ;
957 while (!done && timeout_val-- > 0)
958 {
959 unsigned char x;
960 sleep(1);
961 x = inb( devc -> base + 3);
962 if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */
963 {
964 //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
965 done = 1;
966 }
967 }
968 timeout_val = 5 * HZ;
969 done = 0;
970 while (!done && timeout_val-- > 0)
971 {
972 unsigned char x;
973 sleep(1);
974 x = inb( devc -> base + 3);
975 if (x == 0xfe) /* OBP startup acknowledge */
976 {
977 //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
978 done = 1;
979 }
980 }
981
982 if ( !done ) printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
983
984 sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
985 sscape_write( devc, 3, (devc -> dma << 4) + 0x80);
986 return 1;
987}
988
989static void __init sscape_pnp_init_hw(sscape_info* devc)
990{
991 unsigned char midi_irq = 0, sb_irq = 0;
992 unsigned i;
993 static char code_file_name[23] = "/sndscape/sndscape.cox";
994
995 int sscape_joystic_enable = 0x7f;
996 int sscape_mic_enable = 0;
997 int sscape_ext_midi = 0;
998
999 if ( !sscape_pnp_alloc_dma(devc) ) {
1000 printk(KERN_ERR "sscape: faild to allocate dma\n");
1001 return;
1002 }
1003
1004 for (i = 0; i < 4; i++) {
1005 if ( devc -> irq == valid_interrupts[i] )
1006 midi_irq = i;
1007 if ( devc -> codec_irq == valid_interrupts[i] )
1008 sb_irq = i;
1009 }
1010
1011 sscape_write( devc, 5, 0x50);
1012 sscape_write( devc, 7, 0x2e);
1013 sscape_write( devc, 8, 0x00);
1014
1015 sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
1016 sscape_write( devc, 3, ( devc -> dma << 4) | 0x80);
1017
1018 sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);
1019
1020 i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0);
1021 if (sscape_joystic_enable) i |= 8;
1022
1023 sscape_write (devc, 9, i);
1024 sscape_write (devc, 6, 0x80);
1025 sscape_write (devc, 1, 0x80);
1026
1027 if (devc -> codec_type == 2) {
1028 sscape_pnp_write_codec( devc, 0x0C, 0x50);
1029 sscape_pnp_write_codec( devc, 0x10, sscape_pnp_read_codec( devc, 0x10) & 0x3F);
1030 sscape_pnp_write_codec( devc, 0x11, sscape_pnp_read_codec( devc, 0x11) | 0xC0);
1031 sscape_pnp_write_codec( devc, 29, 0x20);
1032 }
1033
1034 if (sscape_pnp_upload_file(devc, "/sndscape/scope.cod") == 0 ) {
1035 printk(KERN_ERR "sscape: faild to upload file /sndscape/scope.cod\n");
1036 sscape_pnp_free_dma(devc);
1037 return;
1038 }
1039
1040 i = sscape_read_host_ctrl( devc );
1041
1042 if ( (i & 0x0F) > 7 ) {
1043 printk(KERN_ERR "sscape: scope.cod faild\n");
1044 sscape_pnp_free_dma(devc);
1045 return;
1046 }
1047 if ( i & 0x10 ) sscape_write( devc, 7, 0x2F);
1048 code_file_name[21] = (char) ( i & 0x0F) + 0x30;
1049 if (sscape_pnp_upload_file( devc, code_file_name) == 0) {
1050 printk(KERN_ERR "sscape: faild to upload file %s\n", code_file_name);
1051 sscape_pnp_free_dma(devc);
1052 return;
1053 }
1054
1055 if (devc->ic_type != IC_ODIE) {
1056 sscape_pnp_write_codec( devc, 10, (sscape_pnp_read_codec(devc, 10) & 0x7f) |
1057 ( sscape_mic_enable == 0 ? 0x00 : 0x80) );
1058 }
1059 sscape_write_host_ctrl2( devc, 0x84, 0x64 ); /* MIDI volume */
1060 sscape_write_host_ctrl2( devc, 0x86, 0x64 ); /* MIDI volume?? */
1061 sscape_write_host_ctrl2( devc, 0x8A, sscape_ext_midi);
1062
1063 sscape_pnp_write_codec ( devc, 6, 0x3f ); //WAV_VOL
1064 sscape_pnp_write_codec ( devc, 7, 0x3f ); //WAV_VOL
1065 sscape_pnp_write_codec ( devc, 2, 0x1F ); //WD_CDXVOLL
1066 sscape_pnp_write_codec ( devc, 3, 0x1F ); //WD_CDXVOLR
1067
1068 if (devc -> codec_type == 1) {
1069 sscape_pnp_write_codec ( devc, 4, 0x1F );
1070 sscape_pnp_write_codec ( devc, 5, 0x1F );
1071 sscape_write_host_ctrl2( devc, 0x88, sscape_mic_enable);
1072 } else {
1073 int t;
1074 sscape_pnp_write_codec ( devc, 0x10, 0x1F << 1);
1075 sscape_pnp_write_codec ( devc, 0x11, 0xC0 | (0x1F << 1));
1076
1077 t = sscape_pnp_read_codec( devc, 0x00) & 0xDF;
1078 if ( (sscape_mic_enable == 0)) t |= 0;
1079 else t |= 0x20;
1080 sscape_pnp_write_codec ( devc, 0x00, t);
1081 t = sscape_pnp_read_codec( devc, 0x01) & 0xDF;
1082 if ( (sscape_mic_enable == 0) ) t |= 0;
1083 else t |= 0x20;
1084 sscape_pnp_write_codec ( devc, 0x01, t);
1085 sscape_pnp_write_codec ( devc, 0x40 | 29 , 0x20);
1086 outb(0, devc -> codec);
1087 }
1088 if (devc -> ic_type == IC_OPUS ) {
1089 int i = sscape_read( devc, 9 );
1090 sscape_write( devc, 9, i | 3 );
1091 sscape_write( devc, 3, 0x40);
1092
1093 if (request_region(0x228, 1, "sscape setup junk")) {
1094 outb(0, 0x228);
1095 release_region(0x228,1);
1096 }
1097 sscape_write( devc, 3, (devc -> dma << 4) | 0x80);
1098 sscape_write( devc, 9, i );
1099 }
1100
1101 host_close ( devc );
1102 sscape_pnp_free_dma(devc);
1103}
1104
1105static int __init detect_sscape_pnp(sscape_info* devc)
1106{
1107 long i, irq_bits = 0xff;
1108 unsigned int d;
1109
1110 DDB(printk("Entered detect_sscape_pnp(%x)\n", devc->base));
1111
1112 if (!request_region(devc->codec, 2, "sscape codec")) {
1113 printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->codec);
1114 return 0;
1115 }
1116
1117 if ((inb(devc->base + 2) & 0x78) != 0)
1118 goto fail;
1119
1120 d = inb ( devc -> base + 4) & 0xF0;
1121 if (d & 0x80)
1122 goto fail;
1123
1124 if (d == 0) {
1125 devc->codec_type = 1;
1126 devc->ic_type = IC_ODIE;
1127 } else if ( (d & 0x60) != 0) {
1128 devc->codec_type = 2;
1129 devc->ic_type = IC_OPUS;
1130 } else if ( (d & 0x40) != 0) { /* WTF? */
1131 devc->codec_type = 2;
1132 devc->ic_type = IC_ODIE;
1133 } else
1134 goto fail;
1135
1136 sscape_is_pnp = 1;
1137
1138 outb(0xFA, devc -> base+4);
1139 if ((inb( devc -> base+4) & 0x9F) != 0x0A)
1140 goto fail;
1141 outb(0xFE, devc -> base+4);
1142 if ( (inb(devc -> base+4) & 0x9F) != 0x0E)
1143 goto fail;
1144 if ( (inb(devc -> base+5) & 0x9F) != 0x0E)
1145 goto fail;
1146
1147 if (devc->codec_type == 2) {
1148 if (devc->codec != devc->base + 8) {
1149 printk("soundscape warning: incorrect codec port specified\n");
1150 goto fail;
1151 }
1152 d = 0x10 | (sscape_read(devc, 9) & 0xCF);
1153 sscape_write(devc, 9, d);
1154 sscape_write(devc, 6, 0x80);
1155 } else {
1156 //todo: check codec is not base + 8
1157 }
1158
1159 d = (sscape_read(devc, 9) & 0x3F) | 0xC0;
1160 sscape_write(devc, 9, d);
1161
1162 for (i = 0; i < 550000; i++)
1163 if ( !(inb(devc -> codec) & 0x80) ) break;
1164
1165 d = inb(devc -> codec);
1166 if (d & 0x80)
1167 goto fail;
1168 if ( inb(devc -> codec + 2) == 0xFF)
1169 goto fail;
1170
1171 sscape_write(devc, 9, sscape_read(devc, 9) & 0x3F );
1172
1173 d = inb(devc -> codec) & 0x80;
1174 if ( d == 0) {
1175 printk(KERN_INFO "soundscape: hardware detected\n");
1176 valid_interrupts = valid_interrupts_new;
1177 } else {
1178 printk(KERN_INFO "soundscape: board looks like media fx\n");
1179 valid_interrupts = valid_interrupts_old;
1180 old_hardware = 1;
1181 }
1182
1183 sscape_write( devc, 9, 0xC0 | (sscape_read(devc, 9) & 0x3F) );
1184
1185 for (i = 0; i < 550000; i++)
1186 if ( !(inb(devc -> codec) & 0x80))
1187 break;
1188
1189 sscape_pnp_init_hw(devc);
1190
1191 for (i = 0; i < 4; i++)
1192 {
1193 if (devc->codec_irq == valid_interrupts[i]) {
1194 irq_bits = i;
1195 break;
1196 }
1197 }
1198 sscape_write(devc, GA_INTENA_REG, 0x00);
1199 sscape_write(devc, GA_DMACFG_REG, 0x50);
1200 sscape_write(devc, GA_DMAA_REG, 0x70);
1201 sscape_write(devc, GA_DMAB_REG, 0x20);
1202 sscape_write(devc, GA_INTCFG_REG, 0xf0);
1203 sscape_write(devc, GA_CDCFG_REG, 0x89 | (devc->dma << 4) | (irq_bits << 1));
1204
1205 sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 0) | 0x20);
1206 sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 1) | 0x20);
1207
1208 return 1;
1209fail:
1210 release_region(devc->codec, 2);
1211 return 0;
1212}
1213
1214static int __init probe_sscape(struct address_info *hw_config)
1215{
1216 devc->base = hw_config->io_base;
1217 devc->irq = hw_config->irq;
1218 devc->dma = hw_config->dma;
1219 devc->osp = hw_config->osp;
1220
1221#ifdef SSCAPE_DEBUG1
1222 /*
1223 * Temporary debugging aid. Print contents of the registers before
1224 * changing them.
1225 */
1226 {
1227 int i;
1228
1229 for (i = 0; i < 13; i++)
1230 printk("I%d = %02x (old value)\n", i, sscape_read(devc, i));
1231 }
1232#endif
1233 devc->failed = 1;
1234
1235 sscape_ports = request_region(devc->base, 2, "mpu401");
1236 if (!sscape_ports)
1237 return 0;
1238
1239 if (!request_region(devc->base + 2, 6, "SoundScape")) {
1240 release_region(devc->base, 2);
1241 return 0;
1242 }
1243
1244 if (!detect_ga(devc)) {
1245 if (detect_sscape_pnp(devc))
1246 return 1;
1247 release_region(devc->base, 2);
1248 release_region(devc->base + 2, 6);
1249 return 0;
1250 }
1251
1252 if (old_hardware) /* Check that it's really an old Spea/Reveal card. */
1253 {
1254 unsigned char tmp;
1255 int cc;
1256
1257 if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0))
1258 {
1259 sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
1260 for (cc = 0; cc < 200000; ++cc)
1261 inb(devc->base + ODIE_ADDR);
1262 }
1263 }
1264 return 1;
1265}
1266
1267static int __init init_ss_ms_sound(struct address_info *hw_config)
1268{
1269 int i, irq_bits = 0xff;
1270 int ad_flags = 0;
1271 struct resource *ports;
1272
1273 if (devc->failed)
1274 {
1275 printk(KERN_ERR "soundscape: Card not detected\n");
1276 return 0;
1277 }
1278 if (devc->ok == 0)
1279 {
1280 printk(KERN_ERR "soundscape: Invalid initialization order.\n");
1281 return 0;
1282 }
1283 for (i = 0; i < 4; i++)
1284 {
1285 if (hw_config->irq == valid_interrupts[i])
1286 {
1287 irq_bits = i;
1288 break;
1289 }
1290 }
1291 if (irq_bits == 0xff) {
1292 printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq);
1293 return 0;
1294 }
1295
1296 if (old_hardware)
1297 ad_flags = 0x12345677; /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
1298 else if (sscape_is_pnp)
1299 ad_flags = 0x87654321; /* Tell that we have a soundscape pnp with 1845 chip */
1300
1301 ports = request_region(hw_config->io_base, 4, "ad1848");
1302 if (!ports) {
1303 printk(KERN_ERR "soundscape: ports busy\n");
1304 return 0;
1305 }
1306
1307 if (!ad1848_detect(ports, &ad_flags, hw_config->osp)) {
1308 release_region(hw_config->io_base, 4);
1309 return 0;
1310 }
1311
1312 if (!sscape_is_pnp) /*pnp is already setup*/
1313 {
1314 /*
1315 * Setup the DMA polarity.
1316 */
1317 sscape_write(devc, GA_DMACFG_REG, 0x50);
1318
1319 /*
1320 * Take the gate-array off of the DMA channel.
1321 */
1322 sscape_write(devc, GA_DMAB_REG, 0x20);
1323
1324 /*
1325 * Init the AD1848 (CD-ROM) config reg.
1326 */
1327 sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | (irq_bits << 1));
1328 }
1329
1330 if (hw_config->irq == devc->irq)
1331 printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n");
1332
1333 hw_config->slots[0] = ad1848_init(
1334 sscape_is_pnp ? "SoundScape" : "SoundScape PNP",
1335 ports,
1336 hw_config->irq,
1337 hw_config->dma,
1338 hw_config->dma,
1339 0,
1340 devc->osp,
1341 THIS_MODULE);
1342
1343
1344 if (hw_config->slots[0] != -1) /* The AD1848 driver installed itself */
1345 {
1346 audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
1347 devc->codec_audiodev = hw_config->slots[0];
1348 devc->my_audiodev = hw_config->slots[0];
1349
1350 /* Set proper routings here (what are they) */
1351 AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
1352 }
1353
1354#ifdef SSCAPE_DEBUG5
1355 /*
1356 * Temporary debugging aid. Print contents of the registers
1357 * after the AD1848 device has been initialized.
1358 */
1359 {
1360 int i;
1361
1362 for (i = 0; i < 13; i++)
1363 printk("I%d = %02x\n", i, sscape_read(devc, i));
1364 }
1365#endif
1366 return 1;
1367}
1368
1369static void __exit unload_sscape(struct address_info *hw_config)
1370{
1371 release_region(devc->base + 2, 6);
1372 unload_mpu401(hw_config);
1373 if (sscape_is_pnp)
1374 release_region(devc->codec, 2);
1375}
1376
1377static void __exit unload_ss_ms_sound(struct address_info *hw_config)
1378{
1379 ad1848_unload(hw_config->io_base,
1380 hw_config->irq,
1381 devc->dma,
1382 devc->dma,
1383 0);
1384 sound_unload_audiodev(hw_config->slots[0]);
1385}
1386
1387static struct address_info cfg;
1388static struct address_info cfg_mpu;
1389
1390static int __initdata spea = -1;
1391static int mss = 0;
1392static int __initdata dma = -1;
1393static int __initdata irq = -1;
1394static int __initdata io = -1;
1395static int __initdata mpu_irq = -1;
1396static int __initdata mpu_io = -1;
1397
1398module_param(dma, int, 0);
1399module_param(irq, int, 0);
1400module_param(io, int, 0);
1401module_param(spea, int, 0); /* spea=0/1 set the old_hardware */
1402module_param(mpu_irq, int, 0);
1403module_param(mpu_io, int, 0);
1404module_param(mss, int, 0);
1405
1406static int __init init_sscape(void)
1407{
1408 printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
1409
1410 cfg.irq = irq;
1411 cfg.dma = dma;
1412 cfg.io_base = io;
1413
1414 cfg_mpu.irq = mpu_irq;
1415 cfg_mpu.io_base = mpu_io;
1416 /* WEH - Try to get right dma channel */
1417 cfg_mpu.dma = dma;
1418
1419 devc->codec = cfg.io_base;
1420 devc->codec_irq = cfg.irq;
1421 devc->codec_type = 0;
1422 devc->ic_type = 0;
1423 devc->raw_buf = NULL;
1424 spin_lock_init(&devc->lock);
1425
1426 if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
1427 printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
1428 return -EINVAL;
1429 }
1430
1431 if (cfg_mpu.irq == -1 && cfg_mpu.io_base != -1) {
1432 printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n");
1433 return -EINVAL;
1434 }
1435
1436 if(spea != -1) {
1437 old_hardware = spea;
1438 printk(KERN_INFO "Forcing %s hardware support.\n",
1439 spea?"new":"old");
1440 }
1441 if (probe_sscape(&cfg_mpu) == 0)
1442 return -ENODEV;
1443
1444 attach_sscape(&cfg_mpu);
1445
1446 mss = init_ss_ms_sound(&cfg);
1447
1448 return 0;
1449}
1450
1451static void __exit cleanup_sscape(void)
1452{
1453 if (mss)
1454 unload_ss_ms_sound(&cfg);
1455 unload_sscape(&cfg_mpu);
1456}
1457
1458module_init(init_sscape);
1459module_exit(cleanup_sscape);
1460
1461#ifndef MODULE
1462static int __init setup_sscape(char *str)
1463{
1464 /* io, irq, dma, mpu_io, mpu_irq */
1465 int ints[6];
1466
1467 str = get_options(str, ARRAY_SIZE(ints), ints);
1468
1469 io = ints[1];
1470 irq = ints[2];
1471 dma = ints[3];
1472 mpu_io = ints[4];
1473 mpu_irq = ints[5];
1474
1475 return 1;
1476}
1477
1478__setup("sscape=", setup_sscape);
1479#endif
1480MODULE_LICENSE("GPL");