Messages in this thread Patch in this message | | | Date | Sat, 7 Feb 98 18:51 GMT | From | (Alan Cox) | Subject | More sound stuff |
| |
This tidies up soundscape and v_midi. It also removes the use of sound_mem from the v_midi driver and simplifies it in the process.
Alan
--- v_midi.c.old Tue Jan 27 22:06:07 1998 +++ v_midi.c Sat Feb 7 19:25:36 1998 @@ -24,14 +24,14 @@ #include "v_midi.h" static vmidi_devc *v_devc[2] = { NULL, NULL}; -static int midi1,midi2; +static int midi1,midi2; +static void *midi_mem = NULL; #ifdef MODULE static struct address_info config; /* dummy */ -int -init_module(void) +int init_module(void) { printk("MIDI Loopback device driver\n"); if (!probe_v_midi(&config)) @@ -41,8 +41,7 @@ return 0; } -void -cleanup_module(void) +void cleanup_module(void) { unload_v_midi(&config); SOUND_LOCK_END; @@ -61,93 +60,87 @@ void (*midi_input_intr) (int dev, unsigned char data); -static int -v_midi_open (int dev, int mode, +static int v_midi_open (int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev) ) { - vmidi_devc *devc = midi_devs[dev]->devc; - unsigned long flags; + vmidi_devc *devc = midi_devs[dev]->devc; + unsigned long flags; - if (devc == NULL) - return -(ENXIO); + if (devc == NULL) + return -(ENXIO); - save_flags (flags); - cli (); - if (devc->opened) - { - restore_flags (flags); - return -(EBUSY); - } - devc->opened = 1; - restore_flags (flags); - - devc->intr_active = 1; - - if (mode & OPEN_READ) - { - devc->input_opened = 1; - devc->midi_input_intr = input; - } + save_flags (flags); + cli(); + if (devc->opened) + { + restore_flags (flags); + return -(EBUSY); + } + devc->opened = 1; + restore_flags (flags); + + devc->intr_active = 1; + + if (mode & OPEN_READ) + { + devc->input_opened = 1; + devc->midi_input_intr = input; + } - return 0; + return 0; } -static void -v_midi_close (int dev) +static void v_midi_close (int dev) { - vmidi_devc *devc = midi_devs[dev]->devc; - unsigned long flags; + vmidi_devc *devc = midi_devs[dev]->devc; + unsigned long flags; - if (devc == NULL) - return; + if (devc == NULL) + return; - save_flags (flags); - cli (); - devc->intr_active = 0; - devc->input_opened = 0; - devc->opened = 0; - restore_flags (flags); + save_flags (flags); + cli (); + devc->intr_active = 0; + devc->input_opened = 0; + devc->opened = 0; + restore_flags (flags); } -static int -v_midi_out (int dev, unsigned char midi_byte) +static int v_midi_out (int dev, unsigned char midi_byte) { - vmidi_devc *devc = midi_devs[dev]->devc; - vmidi_devc *pdevc = midi_devs[devc->pair_mididev]->devc; - - if (devc == NULL) - return -(ENXIO); + vmidi_devc *devc = midi_devs[dev]->devc; + vmidi_devc *pdevc = midi_devs[devc->pair_mididev]->devc; - if (pdevc->input_opened > 0){ - if (MIDIbuf_avail(pdevc->my_mididev) > 500) - return 0; - pdevc->midi_input_intr (pdevc->my_mididev, midi_byte); - } + if (devc == NULL) + return -(ENXIO); - return 1; + if (pdevc->input_opened > 0){ + if (MIDIbuf_avail(pdevc->my_mididev) > 500) + return 0; + pdevc->midi_input_intr (pdevc->my_mididev, midi_byte); + } + return 1; } -static int -v_midi_start_read (int dev) +static int v_midi_start_read (int dev) { - return 0; + return 0; } -static int -v_midi_end_read (int dev) +static int v_midi_end_read (int dev) { - vmidi_devc *devc = midi_devs[dev]->devc; - - if (devc == NULL) - return -(ENXIO); + vmidi_devc *devc = midi_devs[dev]->devc; + if (devc == NULL) + return -ENXIO; - devc->intr_active = 0; - return 0; + devc->intr_active = 0; + return 0; } /* why -EPERM and not -EINVAL?? */ + static int v_midi_ioctl (int dev, unsigned cmd, caddr_t arg) { return -EPERM; @@ -161,199 +154,143 @@ static struct midi_operations v_midi_operations = { - {"Loopback MIDI Port 1", 0, 0, SNDCARD_VMIDI}, - &std_midi_synth, - {0}, - v_midi_open, - v_midi_close, - v_midi_ioctl, - v_midi_out, - v_midi_start_read, - v_midi_end_read, - NULL, - NULL, - NULL, - NULL + {"Loopback MIDI Port 1", 0, 0, SNDCARD_VMIDI}, + &std_midi_synth, + {0}, + v_midi_open, + v_midi_close, + v_midi_ioctl, + v_midi_out, + v_midi_start_read, + v_midi_end_read, + NULL, + NULL, + NULL, + NULL }; static struct midi_operations v_midi_operations2 = { - {"Loopback MIDI Port 2", 0, 0, SNDCARD_VMIDI}, - &std_midi_synth, - {0}, - v_midi_open, - v_midi_close, - v_midi_ioctl, - v_midi_out, - v_midi_start_read, - v_midi_end_read, - NULL, - NULL, - NULL, - NULL + {"Loopback MIDI Port 2", 0, 0, SNDCARD_VMIDI}, + &std_midi_synth, + {0}, + v_midi_open, + v_midi_close, + v_midi_ioctl, + v_midi_out, + v_midi_start_read, + v_midi_end_read, + NULL, + NULL, + NULL, + NULL }; -void -attach_v_midi (struct address_info *hw_config) +/* + * We kmalloc just one of these - it makes life simpler and the code + * cleaner and the memory handling far more efficient + */ + +struct vmidi_memory { + /* Must be first */ + struct midi_operations m_ops[2]; + struct synth_operations s_ops[2]; + struct vmidi_devc v_ops[2]; +}; - /* printk("Attaching v_midi device.....\n"); */ - if (sound_nblocks >= (1024 - 6)){ - printk("Sound: Loop Back MIDI: not enough sound driver memory block table\n"); - return; - } - - midi1 = sound_alloc_mididev(); - if (midi1 == -1) - { - printk ("Sound: Too many midi devices detected\n"); - return; - } - midi_devs[midi1] = (struct midi_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc (sizeof (struct midi_operations))); - sound_mem_sizes[sound_nblocks] = sizeof (struct midi_operations); - - if (sound_nblocks < 1024) - sound_nblocks++;; - if (midi_devs[midi1] == NULL) - { - printk (KERN_WARNING "Loop Back MIDI: Failed to allocate memory\n"); - sound_unload_mididev(midi1); - return; - } - - midi2 = sound_alloc_mididev(); - if (midi2 == -1) - { - printk ("Sound: Too many midi devices detected\n"); - sound_unload_mididev(midi1); - return; - } - - midi_devs[midi2] = (struct midi_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc (sizeof (struct midi_operations))); - sound_mem_sizes[sound_nblocks] = sizeof (struct midi_operations); - - if (sound_nblocks < 1024) - sound_nblocks++;; - if (midi_devs[midi2] == NULL) - { - printk (KERN_WARNING "Loop Back MIDI: Failed to allocate memory\n"); - sound_unload_mididev(midi1); - sound_unload_mididev(midi2); - return; - } - - /* printk("VMIDI1: %d VMIDI2: %d\n",midi1,midi2); */ - - /* for MIDI-1 */ - v_devc[0] = (struct vmidi_devc *) (sound_mem_blocks[sound_nblocks] = vmalloc (sizeof (struct vmidi_devc))); - sound_mem_sizes[sound_nblocks] = sizeof (struct vmidi_devc); - - if (sound_nblocks < 1024) - sound_nblocks++;; - if (v_devc[0] == NULL) - { - printk (KERN_WARNING "Loop Back MIDI: Failed to allocate memory\n"); - sound_unload_mididev(midi1); - sound_unload_mididev(midi2); - return; - } - - memcpy ((char *) midi_devs[midi1], (char *) &v_midi_operations, - sizeof (struct midi_operations)); - - v_devc[0]->my_mididev = midi1; - v_devc[0]->pair_mididev = midi2; - v_devc[0]->opened = v_devc[0]->input_opened = 0; - v_devc[0]->intr_active = 0; - v_devc[0]->midi_input_intr = NULL; - - midi_devs[midi1]->devc = v_devc[0]; - - midi_devs[midi1]->converter = (struct synth_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc (sizeof (struct synth_operations))); - sound_mem_sizes[sound_nblocks] = sizeof (struct synth_operations); - - if (sound_nblocks < 1024) - sound_nblocks++;; - - if (midi_devs[midi1]->converter == NULL) - { - printk (KERN_WARNING "Loop Back MIDI: Failed to allocate memory\n"); - sound_unload_mididev(midi1); - sound_unload_mididev(midi2); - return; - } - - std_midi_synth.midi_dev = midi1; - memcpy ((char *) midi_devs[midi1]->converter, (char *) &std_midi_synth, - sizeof (struct synth_operations)); - - midi_devs[midi1]->converter->id = "V_MIDI 1"; - - /* for MIDI-2 */ - v_devc[1] = (struct vmidi_devc *) (sound_mem_blocks[sound_nblocks] = vmalloc (sizeof (struct vmidi_devc))); - sound_mem_sizes[sound_nblocks] = sizeof (struct vmidi_devc); - - if (sound_nblocks < 1024) - sound_nblocks++;; - if (v_devc[1] == NULL) - { - printk (KERN_WARNING "Loop Back MIDI: Failed to allocate memory\n"); - sound_unload_mididev(midi1); - sound_unload_mididev(midi2); - return; - } - - - memcpy ((char *) midi_devs[midi2], (char *) &v_midi_operations2, - sizeof (struct midi_operations)); - - v_devc[1]->my_mididev = midi2; - v_devc[1]->pair_mididev = midi1; - v_devc[1]->opened = v_devc[1]->input_opened = 0; - v_devc[1]->intr_active = 0; - v_devc[1]->midi_input_intr = NULL; - - midi_devs[midi2]->devc = v_devc[1]; - - - midi_devs[midi2]->converter = (struct synth_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc (sizeof (struct synth_operations))); - sound_mem_sizes[sound_nblocks] = sizeof (struct synth_operations); - - if (sound_nblocks < 1024) - sound_nblocks++;; - - if (midi_devs[midi2]->converter == NULL) - { - printk (KERN_WARNING "Loop Back MIDI: Failed to allocate memory\n"); - sound_unload_mididev(midi1); - sound_unload_mididev(midi2); - return; - } - - std_midi_synth.midi_dev = midi2; - memcpy ((char *) midi_devs[midi2]->converter, (char *) &std_midi_synth, - sizeof (struct synth_operations)); +void attach_v_midi (struct address_info *hw_config) +{ + struct vmidi_memory *m; + /* printk("Attaching v_midi device.....\n"); */ - midi_devs[midi2]->converter->id = "V_MIDI 2"; + midi1 = sound_alloc_mididev(); + if (midi1 == -1) + { + printk(KERN_ERR "v_midi: Too many midi devices detected\n"); + return; + } + + m=(struct vmidi_memory *)kmalloc(sizeof(struct vmidi_memory), GFP_KERNEL); + if (m == NULL) + { + printk(KERN_WARNING "Loopback MIDI: Failed to allocate memory\n"); + sound_unload_mididev(midi1); + return; + } + + midi_mem = m; + + midi_devs[midi1] = &m->m_ops[0]; + - sequencer_init(); - /* printk("Attached v_midi device\n"); */ + midi2 = sound_alloc_mididev(); + if (midi2 == -1) + { + printk (KERN_ERR "v_midi: Too many midi devices detected\n"); + kfree(m); + sound_unload_mididev(midi1); + return; + } + + midi_devs[midi2] = &m->m_ops[1]; + + /* printk("VMIDI1: %d VMIDI2: %d\n",midi1,midi2); */ + + /* for MIDI-1 */ + v_devc[0] = &m->v_ops[0]; + memcpy ((char *) midi_devs[midi1], (char *) &v_midi_operations, + sizeof (struct midi_operations)); + + v_devc[0]->my_mididev = midi1; + v_devc[0]->pair_mididev = midi2; + v_devc[0]->opened = v_devc[0]->input_opened = 0; + v_devc[0]->intr_active = 0; + v_devc[0]->midi_input_intr = NULL; + + midi_devs[midi1]->devc = v_devc[0]; + + midi_devs[midi1]->converter = &m->s_ops[0]; + std_midi_synth.midi_dev = midi1; + memcpy ((char *) midi_devs[midi1]->converter, (char *) &std_midi_synth, + sizeof (struct synth_operations)); + midi_devs[midi1]->converter->id = "V_MIDI 1"; + + /* for MIDI-2 */ + v_devc[1] = &m->v_ops[1]; + + memcpy ((char *) midi_devs[midi2], (char *) &v_midi_operations2, + sizeof (struct midi_operations)); + + v_devc[1]->my_mididev = midi2; + v_devc[1]->pair_mididev = midi1; + v_devc[1]->opened = v_devc[1]->input_opened = 0; + v_devc[1]->intr_active = 0; + v_devc[1]->midi_input_intr = NULL; + + midi_devs[midi2]->devc = v_devc[1]; + midi_devs[midi2]->converter = &m->s_ops[1]; + + std_midi_synth.midi_dev = midi2; + memcpy ((char *) midi_devs[midi2]->converter, (char *) &std_midi_synth, + sizeof (struct synth_operations)); + midi_devs[midi2]->converter->id = "V_MIDI 2"; + sequencer_init(); + /* printk("Attached v_midi device\n"); */ } -int -probe_v_midi(struct address_info *hw_config) +int probe_v_midi(struct address_info *hw_config) { return(1); /* always OK */ } -void -unload_v_midi(struct address_info *hw_config) +void unload_v_midi(struct address_info *hw_config) { - sound_unload_mididev(midi1); - sound_unload_mididev(midi2); -; + sound_unload_mididev(midi1); + sound_unload_mididev(midi2); + kfree(midi_mem); } #endif --- sscape.c.old Sat Feb 7 18:52:59 1998 +++ sscape.c Sat Feb 7 19:23:18 1998 @@ -3,6 +3,7 @@ * * Low level driver for Ensoniq SoundScape */ + /* * Copyright (C) by Hannu Savolainen 1993-1997 * @@ -10,9 +11,11 @@ * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. */ + /* * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) */ + #include <linux/config.h> #include <linux/module.h> @@ -26,66 +29,69 @@ /* * I/O ports */ -#define MIDI_DATA 0 -#define MIDI_CTRL 1 -#define HOST_CTRL 2 -#define TX_READY 0x02 -#define RX_READY 0x01 -#define HOST_DATA 3 -#define ODIE_ADDR 4 -#define ODIE_DATA 5 +#define MIDI_DATA 0 +#define MIDI_CTRL 1 +#define HOST_CTRL 2 +#define TX_READY 0x02 +#define RX_READY 0x01 +#define HOST_DATA 3 +#define ODIE_ADDR 4 +#define ODIE_DATA 5 /* * Indirect registers */ -#define GA_INTSTAT_REG 0 -#define GA_INTENA_REG 1 -#define GA_DMAA_REG 2 -#define GA_DMAB_REG 3 -#define GA_INTCFG_REG 4 -#define GA_DMACFG_REG 5 -#define GA_CDCFG_REG 6 -#define GA_SMCFGA_REG 7 -#define GA_SMCFGB_REG 8 -#define GA_HMCTL_REG 9 + +#define GA_INTSTAT_REG 0 +#define GA_INTENA_REG 1 +#define GA_DMAA_REG 2 +#define GA_DMAB_REG 3 +#define GA_INTCFG_REG 4 +#define GA_DMACFG_REG 5 +#define GA_CDCFG_REG 6 +#define GA_SMCFGA_REG 7 +#define GA_SMCFGB_REG 8 +#define GA_HMCTL_REG 9 /* * DMA channel identifiers (A and B) */ -#define SSCAPE_DMA_A 0 -#define SSCAPE_DMA_B 1 + +#define SSCAPE_DMA_A 0 +#define SSCAPE_DMA_B 1 #define PORT(name) (devc->base+name) /* * Host commands recognized by the OBP microcode */ -#define CMD_GEN_HOST_ACK 0x80 -#define CMD_GEN_MPU_ACK 0x81 -#define CMD_GET_BOARD_TYPE 0x82 -#define CMD_SET_CONTROL 0x88 /* Old firmware only */ -#define CMD_GET_CONTROL 0x89 /* Old firmware only */ -#define CTL_MASTER_VOL 0 -#define CTL_MIC_MODE 2 -#define CTL_SYNTH_VOL 4 -#define CTL_WAVE_VOL 7 + +#define CMD_GEN_HOST_ACK 0x80 +#define CMD_GEN_MPU_ACK 0x81 +#define CMD_GET_BOARD_TYPE 0x82 +#define CMD_SET_CONTROL 0x88 /* Old firmware only */ +#define CMD_GET_CONTROL 0x89 /* Old firmware only */ +#define CTL_MASTER_VOL 0 +#define CTL_MIC_MODE 2 +#define CTL_SYNTH_VOL 4 +#define CTL_WAVE_VOL 7 #define CMD_SET_EXTMIDI 0x8a #define CMD_GET_EXTMIDI 0x8b -#define CMD_SET_MT32 0x8c -#define CMD_GET_MT32 0x8d +#define CMD_SET_MT32 0x8c +#define CMD_GET_MT32 0x8d #define CMD_ACK 0x80 typedef struct sscape_info { - int base, irq, dma; - int ok; /* Properly detected */ - int failed; - int dma_allocated; - int codec_audiodev; - int opened; - int *osp; - int my_audiodev; + int base, irq, dma; + int ok; /* Properly detected */ + int failed; + int dma_allocated; + int codec_audiodev; + int opened; + int *osp; + int my_audiodev; } sscape_info; static struct sscape_info adev_info = { @@ -93,7 +99,7 @@ }; static struct sscape_info *devc = &adev_info; -static int sscape_mididev = -1; +static int sscape_mididev = -1; static struct wait_queue *sscape_sleeper = NULL; static volatile struct snd_wait sscape_sleep_flag = { @@ -101,104 +107,100 @@ }; /* Some older cards have assigned interrupt bits differently than new ones */ -static char valid_interrupts_old[] = -{9, 7, 5, 15}; +static char valid_interrupts_old[] = { + 9, 7, 5, 15 +}; -static char valid_interrupts_new[] = -{9, 5, 7, 10}; +static char valid_interrupts_new[] = { + 9, 5, 7, 10 +}; -static char *valid_interrupts = valid_interrupts_new; +static char *valid_interrupts = valid_interrupts_new; +/* + * See the bottom of the driver. This can be set by spea =0/1. + */ + #ifdef REVEAL_SPEA -static char old_hardware = 1; - +static char old_hardware = 1; #else -static char old_hardware = 0; - +static char old_hardware = 0; #endif static unsigned char sscape_read(struct sscape_info *devc, int reg) { - unsigned long flags; - unsigned char val; + unsigned long flags; + unsigned char val; save_flags(flags); cli(); - outb((reg), PORT(ODIE_ADDR)); + outb(reg, PORT(ODIE_ADDR)); val = inb(PORT(ODIE_DATA)); restore_flags(flags); return val; } -static void -sscape_write(struct sscape_info *devc, int reg, int data) +static void sscape_write(struct sscape_info *devc, int reg, int data) { - unsigned long flags; + unsigned long flags; save_flags(flags); cli(); - outb((reg), PORT(ODIE_ADDR)); - outb((data), PORT(ODIE_DATA)); + outb(reg, PORT(ODIE_ADDR)); + outb(data, PORT(ODIE_DATA)); restore_flags(flags); } -static void -host_open(struct sscape_info *devc) +static void host_open(struct sscape_info *devc) { outb((0x00), PORT(HOST_CTRL)); /* Put the board to the host mode */ } -static void -host_close(struct sscape_info *devc) +static void host_close(struct sscape_info *devc) { outb((0x03), PORT(HOST_CTRL)); /* Put the board to the MIDI mode */ } -static int -host_write(struct sscape_info *devc, unsigned char *data, int count) +static int host_write(struct sscape_info *devc, unsigned char *data, int count) { - unsigned long flags; - int i, timeout_val; + unsigned long flags; + int i, timeout_val; save_flags(flags); cli(); /* - * Send the command and data bytes + * Send the command and data bytes */ for (i = 0; i < count; i++) - { - for (timeout_val = 10000; timeout_val > 0; timeout_val--) - if (inb(PORT(HOST_CTRL)) & TX_READY) - break; + { + for (timeout_val = 10000; timeout_val > 0; timeout_val--) + if (inb(PORT(HOST_CTRL)) & TX_READY) + break; - if (timeout_val <= 0) - { + if (timeout_val <= 0) + { restore_flags(flags); return 0; - } - outb((data[i]), PORT(HOST_DATA)); - } - - + } + outb(data[i], PORT(HOST_DATA)); + } restore_flags(flags); - return 1; } -static int -host_read(struct sscape_info *devc) +static int host_read(struct sscape_info *devc) { - unsigned long flags; - int timeout_val; - unsigned char data; + unsigned long flags; + int timeout_val; + unsigned char data; save_flags(flags); cli(); /* - * Read a byte + * Read a byte */ for (timeout_val = 10000; timeout_val > 0; timeout_val--) @@ -206,22 +208,19 @@ break; if (timeout_val <= 0) - { - restore_flags(flags); - return -1; - } + { + restore_flags(flags); + return -1; + } data = inb(PORT(HOST_DATA)); - restore_flags(flags); - return data; } -static int -host_command2(struct sscape_info *devc, int cmd, int parm1) +static int host_command2(struct sscape_info *devc, int cmd, int parm1) { - unsigned char buf[10]; + unsigned char buf[10]; buf[0] = (unsigned char) (cmd & 0xff); buf[1] = (unsigned char) (parm1 & 0xff); @@ -229,61 +228,49 @@ return host_write(devc, buf, 2); } -static int -host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2) +static int host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2) { - unsigned char buf[10]; + unsigned char buf[10]; buf[0] = (unsigned char) (cmd & 0xff); buf[1] = (unsigned char) (parm1 & 0xff); buf[2] = (unsigned char) (parm2 & 0xff); - return host_write(devc, buf, 3); } -static void -set_mt32(struct sscape_info *devc, int value) +static void set_mt32(struct sscape_info *devc, int value) { host_open(devc); - host_command2(devc, CMD_SET_MT32, - value ? 1 : 0); + host_command2(devc, CMD_SET_MT32, value ? 1 : 0); if (host_read(devc) != CMD_ACK) - { - /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */ - } + { + /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */ + } host_close(devc); } -static void -set_control(struct sscape_info *devc, int ctrl, int value) +static void set_control(struct sscape_info *devc, int ctrl, int value) { host_open(devc); host_command3(devc, CMD_SET_CONTROL, ctrl, value); if (host_read(devc) != CMD_ACK) - { - /* printk( "SNDSCAPE: Setting control (%d) failed\n", ctrl); */ - } + { + /* printk( "SNDSCAPE: Setting control (%d) failed\n", ctrl); */ + } host_close(devc); } - - - - -static void -do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode) +static void do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode) { - unsigned char temp; + unsigned char temp; if (dma_chan != SSCAPE_DMA_A) - { - printk("SSCAPE: Tried to use DMA channel != A. Why?\n"); - return; - } + { + printk(KERN_WARNING "soundscape: Tried to use DMA channel != A. Why?\n"); + return; + } audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE; - DMAbuf_start_dma(devc->codec_audiodev, - buf, - blk_size, mode); + DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode); audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE; temp = devc->dma << 4; /* Setup DMA channel select bits */ @@ -296,49 +283,45 @@ sscape_write(devc, GA_DMAA_REG, temp); } -static int -verify_mpu(struct sscape_info *devc) +static int verify_mpu(struct sscape_info *devc) { /* - * The SoundScape board could be in three modes (MPU, 8250 and host). - * If the card is not in the MPU mode, enabling the MPU driver will - * cause infinite loop (the driver believes that there is always some - * received data in the buffer. - * - * Detect this by looking if there are more than 10 received MIDI bytes - * (0x00) in the buffer. + * The SoundScape board could be in three modes (MPU, 8250 and host). + * If the card is not in the MPU mode, enabling the MPU driver will + * cause infinite loop (the driver believes that there is always some + * received data in the buffer. + * + * Detect this by looking if there are more than 10 received MIDI bytes + * (0x00) in the buffer. */ - int i; + int i; for (i = 0; i < 10; i++) - { - if (inb(devc->base + HOST_CTRL) & 0x80) - return 1; - - if (inb(devc->base) != 0x00) - return 1; - } + { + if (inb(devc->base + HOST_CTRL) & 0x80) + return 1; - printk("SoundScape: The device is not in the MPU-401 mode\n"); + if (inb(devc->base) != 0x00) + return 1; + } + printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n"); return 0; } -static int -sscape_coproc_open(void *dev_info, int sub_device) +static int sscape_coproc_open(void *dev_info, int sub_device) { if (sub_device == COPR_MIDI) - { - set_mt32(devc, 0); - if (!verify_mpu(devc)) - return -EIO; - } + { + set_mt32(devc, 0); + if (!verify_mpu(devc)) + return -EIO; + } sscape_sleep_flag.opts = WK_NONE; return 0; } -static void -sscape_coproc_close(void *dev_info, int sub_device) +static void sscape_coproc_close(void *dev_info, int sub_device) { struct sscape_info *devc = dev_info; unsigned long flags; @@ -346,69 +329,67 @@ save_flags(flags); cli(); if (devc->dma_allocated) - { - sscape_write(devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */ - devc->dma_allocated = 0; - } + { + sscape_write(devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */ + devc->dma_allocated = 0; + } sscape_sleep_flag.opts = WK_NONE; restore_flags(flags); - return; } -static void -sscape_coproc_reset(void *dev_info) +static void sscape_coproc_reset(void *dev_info) { } -static int -sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag) +static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag) { - unsigned long flags; - unsigned char temp; - volatile int done, timeout_val; + unsigned long flags; + unsigned char temp; + volatile int done, timeout_val; static unsigned char codec_dma_bits = 0; if (flag & CPF_FIRST) - { - /* - * First block. Have to allocate DMA and to reset the board - * before continuing. - */ - - save_flags(flags); - cli(); - codec_dma_bits = sscape_read(devc, GA_CDCFG_REG); - - if (devc->dma_allocated == 0) - { - devc->dma_allocated = 1; - } - restore_flags(flags); + { + /* + * First block. Have to allocate DMA and to reset the board + * before continuing. + */ + + save_flags(flags); + cli(); + codec_dma_bits = sscape_read(devc, GA_CDCFG_REG); + + if (devc->dma_allocated == 0) + devc->dma_allocated = 1; - sscape_write(devc, GA_HMCTL_REG, + restore_flags(flags); + + sscape_write(devc, GA_HMCTL_REG, (temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f); /*Reset */ - for (timeout_val = 10000; timeout_val > 0; timeout_val--) - sscape_read(devc, GA_HMCTL_REG); /* Delay */ + for (timeout_val = 10000; timeout_val > 0; timeout_val--) + sscape_read(devc, GA_HMCTL_REG); /* Delay */ - /* Take board out of reset */ - sscape_write(devc, GA_HMCTL_REG, + /* Take board out of reset */ + sscape_write(devc, GA_HMCTL_REG, (temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80); - } + } /* * Transfer one code block using DMA */ if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL) - { - printk("SSCAPE: Error: DMA buffer not available\n"); - return 0; - } + { + printk(KERN_WARNING "soundscape: DMA buffer not available\n"); + return 0; + } memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size); save_flags(flags); cli(); -/******** INTERRUPTS DISABLED NOW ********/ + + /******** INTERRUPTS DISABLED NOW ********/ + do_dma(devc, SSCAPE_DMA_A, audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys, size, DMA_MODE_WRITE); @@ -416,160 +397,140 @@ /* * Wait until transfer completes. */ + sscape_sleep_flag.opts = WK_NONE; done = 0; timeout_val = 30; while (!done && timeout_val-- > 0) - { - int resid; - - { - unsigned long tlimit; - - if (HZ / 50) - current->timeout = tlimit = jiffies + (HZ / 50); - else - tlimit = (unsigned long) -1; - sscape_sleep_flag.opts = WK_SLEEP; - interruptible_sleep_on(&sscape_sleeper); - if (!(sscape_sleep_flag.opts & WK_WAKEUP)) - { - if (jiffies >= tlimit) - sscape_sleep_flag.opts |= WK_TIMEOUT; - } - sscape_sleep_flag.opts &= ~WK_SLEEP; - }; - clear_dma_ff(devc->dma); - if ((resid = get_dma_residue(devc->dma)) == 0) - { - done = 1; - } - } + { + int resid; + unsigned long tlimit; + current->timeout = tlimit = jiffies + (HZ / 50); + sscape_sleep_flag.opts = WK_SLEEP; + interruptible_sleep_on(&sscape_sleeper); + if (!(sscape_sleep_flag.opts & WK_WAKEUP)) + { + if (jiffies >= tlimit) + sscape_sleep_flag.opts |= WK_TIMEOUT; + } + sscape_sleep_flag.opts &= ~WK_SLEEP; + clear_dma_ff(devc->dma); + if ((resid = get_dma_residue(devc->dma)) == 0) + { + done = 1; + } + } restore_flags(flags); if (!done) return 0; if (flag & CPF_LAST) - { - /* - * Take the board out of reset - */ - outb((0x00), PORT(HOST_CTRL)); - outb((0x00), PORT(MIDI_CTRL)); - - temp = sscape_read(devc, GA_HMCTL_REG); - temp |= 0x40; - sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */ - - /* - * Wait until the ODB wakes up - */ - - save_flags(flags); - cli(); - done = 0; - timeout_val = 5 * HZ; - while (!done && timeout_val-- > 0) - { - unsigned char x; - - - { - unsigned long tlimit; - - if (1) - current->timeout = tlimit = jiffies + (1); - else - tlimit = (unsigned long) -1; - sscape_sleep_flag.opts = WK_SLEEP; - interruptible_sleep_on(&sscape_sleeper); - if (!(sscape_sleep_flag.opts & WK_WAKEUP)) - { - if (jiffies >= tlimit) - sscape_sleep_flag.opts |= WK_TIMEOUT; - } - sscape_sleep_flag.opts &= ~WK_SLEEP; - }; - x = inb(PORT(HOST_DATA)); - if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */ - { - DDB(printk("Soundscape: Acknowledge = %x\n", x)); - done = 1; - } - } - sscape_write(devc, GA_CDCFG_REG, codec_dma_bits); - - restore_flags(flags); - if (!done) - { - printk("SoundScape: The OBP didn't respond after code download\n"); - return 0; - } - save_flags(flags); - cli(); - done = 0; - timeout_val = 5 * HZ; - while (!done && timeout_val-- > 0) - { - - { - unsigned long tlimit; - - if (1) - current->timeout = tlimit = jiffies + (1); - else - tlimit = (unsigned long) -1; - sscape_sleep_flag.opts = WK_SLEEP; - interruptible_sleep_on(&sscape_sleeper); - if (!(sscape_sleep_flag.opts & WK_WAKEUP)) - { - if (jiffies >= tlimit) - sscape_sleep_flag.opts |= WK_TIMEOUT; - } - sscape_sleep_flag.opts &= ~WK_SLEEP; - }; - if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */ - done = 1; - } - restore_flags(flags); - if (!done) - { - printk("SoundScape: OBP Initialization failed.\n"); - return 0; - } - printk("SoundScape board initialized OK\n"); - set_control(devc, CTL_MASTER_VOL, 100); - set_control(devc, CTL_SYNTH_VOL, 100); + { + /* + * Take the board out of reset + */ + outb((0x00), PORT(HOST_CTRL)); + outb((0x00), PORT(MIDI_CTRL)); + + temp = sscape_read(devc, GA_HMCTL_REG); + temp |= 0x40; + sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */ + + /* + * Wait until the ODB wakes up + */ + + save_flags(flags); + cli(); + done = 0; + timeout_val = 5 * HZ; + while (!done && timeout_val-- > 0) + { + unsigned char x; + unsigned long tlimit; + + current->timeout = tlimit = jiffies + 1; + sscape_sleep_flag.opts = WK_SLEEP; + interruptible_sleep_on(&sscape_sleeper); + if (!(sscape_sleep_flag.opts & WK_WAKEUP)) + { + if (jiffies >= tlimit) + sscape_sleep_flag.opts |= WK_TIMEOUT; + } + sscape_sleep_flag.opts &= ~WK_SLEEP; + + x = inb(PORT(HOST_DATA)); + if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */ + { + DDB(printk("Soundscape: Acknowledge = %x\n", x)); + done = 1; + } + } + sscape_write(devc, GA_CDCFG_REG, codec_dma_bits); + + restore_flags(flags); + if (!done) + { + printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n"); + return 0; + } + save_flags(flags); + cli(); + done = 0; + timeout_val = 5 * HZ; + while (!done && timeout_val-- > 0) + { + unsigned long tlimit; + current->timeout = tlimit = jiffies + (1); + sscape_sleep_flag.opts = WK_SLEEP; + interruptible_sleep_on(&sscape_sleeper); + if (!(sscape_sleep_flag.opts & WK_WAKEUP)) + { + if (jiffies >= tlimit) + sscape_sleep_flag.opts |= WK_TIMEOUT; + } + sscape_sleep_flag.opts &= ~WK_SLEEP; + if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */ + done = 1; + } + restore_flags(flags); + if (!done) + { + printk(KERN_ERR "soundscape: OBP Initialization failed.\n"); + return 0; + } + printk(KERN_INFO "SoundScape board initialized OK\n"); + set_control(devc, CTL_MASTER_VOL, 100); + set_control(devc, CTL_SYNTH_VOL, 100); #ifdef SSCAPE_DEBUG3 - /* - * Temporary debugging aid. Print contents of the registers after - * downloading the code. - */ - { - int i; - - for (i = 0; i < 13; i++) - printk("I%d = %02x (new value)\n", i, sscape_read(devc, i)); - } + /* + * Temporary debugging aid. Print contents of the registers after + * downloading the code. + */ + { + int i; + + for (i = 0; i < 13; i++) + printk("I%d = %02x (new value)\n", i, sscape_read(devc, i)); + } #endif - } + } return 1; } -static int -download_boot_block(void *dev_info, copr_buffer * buf) +static int download_boot_block(void *dev_info, copr_buffer * buf) { if (buf->len <= 0 || buf->len > sizeof(buf->data)) return -EINVAL; if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags)) - { - printk("SSCAPE: Unable to load microcode block to the OBP.\n"); - return -EIO; - } + { + printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n"); + return -EIO; + } return 0; } @@ -578,25 +539,27 @@ copr_buffer *buf; int err; - switch (cmd) { - case SNDCTL_COPR_RESET: - sscape_coproc_reset(dev_info); - return 0; - - case SNDCTL_COPR_LOAD: - buf = (copr_buffer *) vmalloc(sizeof(copr_buffer)); - if (buf == NULL) - return -ENOSPC; - if (__copy_from_user(buf, arg, sizeof(copr_buffer))) { + switch (cmd) + { + case SNDCTL_COPR_RESET: + sscape_coproc_reset(dev_info); + return 0; + + case SNDCTL_COPR_LOAD: + buf = (copr_buffer *) vmalloc(sizeof(copr_buffer)); + if (buf == NULL) + return -ENOSPC; + if (copy_from_user(buf, arg, sizeof(copr_buffer))) + { + vfree(buf); + return -EFAULT; + } + err = download_boot_block(dev_info, buf); vfree(buf); - return -EFAULT; - } - err = download_boot_block(dev_info, buf); - vfree(buf); - return err; + return err; - default: - return -EINVAL; + default: + return -EINVAL; } } @@ -610,25 +573,23 @@ &adev_info }; -static int sscape_detected = 0; +static int sscape_detected = 0; -void -attach_sscape(struct address_info *hw_config) +void attach_sscape(struct address_info *hw_config) { - #ifndef SSCAPE_REGS /* - * Config register values for Spea/V7 Media FX and Ensoniq S-2000. - * These values are card - * dependent. If you have another SoundScape based card, you have to - * find the correct values. Do the following: - * - Compile this driver with SSCAPE_DEBUG1 defined. - * - Shut down and power off your machine. - * - Boot with DOS so that the SSINIT.EXE program is run. - * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed - * when detecting the SoundScape. - * - Modify the following list to use the values printed during boot. - * Undefine the SSCAPE_DEBUG1 + * Config register values for Spea/V7 Media FX and Ensoniq S-2000. + * These values are card + * dependent. If you have another SoundScape based card, you have to + * find the correct values. Do the following: + * - Compile this driver with SSCAPE_DEBUG1 defined. + * - Shut down and power off your machine. + * - Boot with DOS so that the SSINIT.EXE program is run. + * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed + * when detecting the SoundScape. + * - Modify the following list to use the values printed during boot. + * Undefine the SSCAPE_DEBUG1 */ #define SSCAPE_REGS { \ /* I0 */ 0x00, \ @@ -647,76 +608,78 @@ unsigned long flags; static unsigned char regs[10] = SSCAPE_REGS; - int i, irq_bits = 0xff; + int i, irq_bits = 0xff; if (sscape_detected != hw_config->io_base) return; request_region(devc->base + 2, 6, "SoundScape"); if (old_hardware) - { - valid_interrupts = valid_interrupts_old; - conf_printf("Ensoniq SoundScape (old)", hw_config); - } else + { + valid_interrupts = valid_interrupts_old; + conf_printf("Ensoniq SoundScape (old)", hw_config); + } + else conf_printf("Ensoniq SoundScape", hw_config); for (i = 0; i < sizeof(valid_interrupts); i++) + { if (hw_config->irq == valid_interrupts[i]) - { - irq_bits = i; - break; - } + { + irq_bits = i; + break; + } + } if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff)) - { - printk("Invalid IRQ%d\n", hw_config->irq); - return; - } + { + printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq); + return; + } save_flags(flags); cli(); for (i = 1; i < 10; i++) + { switch (i) - { - case 1: /* Host interrupt enable */ - sscape_write(devc, i, 0xf0); /* All interrupts enabled */ - break; - - case 2: /* DMA A status/trigger register */ - case 3: /* DMA B status/trigger register */ - sscape_write(devc, i, 0x20); /* DMA channel disabled */ - break; - - case 4: /* Host interrupt config reg */ - sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits); - break; - - case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */ - sscape_write(devc, i, (regs[i] & 0x3f) | - (sscape_read(devc, i) & 0xc0)); - break; - - case 6: /* CD-ROM config (WSS codec actually) */ - sscape_write(devc, i, regs[i]); - break; - - case 9: /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */ - sscape_write(devc, i, - (sscape_read(devc, i) & 0xf0) | 0x08); - break; - - default: - sscape_write(devc, i, regs[i]); - } + { + case 1: /* Host interrupt enable */ + sscape_write(devc, i, 0xf0); /* All interrupts enabled */ + break; + + case 2: /* DMA A status/trigger register */ + case 3: /* DMA B status/trigger register */ + sscape_write(devc, i, 0x20); /* DMA channel disabled */ + break; + + case 4: /* Host interrupt config reg */ + sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits); + break; + + case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */ + sscape_write(devc, i, (regs[i] & 0x3f) | (sscape_read(devc, i) & 0xc0)); + break; + + case 6: /* CD-ROM config (WSS codec actually) */ + sscape_write(devc, i, regs[i]); + break; + + case 9: /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */ + sscape_write(devc, i, (sscape_read(devc, i) & 0xf0) | 0x08); + break; + default: + sscape_write(devc, i, regs[i]); + } + } restore_flags(flags); #ifdef SSCAPE_DEBUG2 /* - * Temporary debugging aid. Print contents of the registers after - * changing them. + * Temporary debugging aid. Print contents of the registers after + * changing them. */ { - int i; + int i; for (i = 0; i < 13; i++) printk("I%d = %02x (new value)\n", i, sscape_read(devc, i)); @@ -726,31 +689,26 @@ #if defined(CONFIG_MIDI) && defined(CONFIG_MPU_EMU) if (probe_mpu401(hw_config)) hw_config->always_detect = 1; - { - hw_config->name = "SoundScape"; + hw_config->name = "SoundScape"; - hw_config->irq *= -1; /* Negative value signals IRQ sharing */ - attach_mpu401(hw_config); - hw_config->irq *= -1; /* Restore it */ - - if (hw_config->slots[1] != -1) /* The MPU driver installed itself */ - { - sscape_mididev = hw_config->slots[1]; - midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations; - } + hw_config->irq *= -1; /* Negative value signals IRQ sharing */ + attach_mpu401(hw_config); + hw_config->irq *= -1; /* Restore it */ + + if (hw_config->slots[1] != -1) /* The MPU driver installed itself */ + { + sscape_mididev = hw_config->slots[1]; + midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations; } #endif - sscape_write(devc, GA_INTENA_REG, 0x80); /* Master IRQ enable */ devc->ok = 1; devc->failed = 0; - } -static int -detect_ga(sscape_info * devc) +static int detect_ga(sscape_info * devc) { - unsigned char save; + unsigned char save; DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base)); @@ -758,54 +716,54 @@ return 0; /* - * First check that the address register of "ODIE" is - * there and that it has exactly 4 writable bits. - * First 4 bits + * First check that the address register of "ODIE" is + * there and that it has exactly 4 writable bits. + * First 4 bits */ + if ((save = inb(PORT(ODIE_ADDR))) & 0xf0) - { - DDB(printk("soundscape: Detect error A\n")); - return 0; - } + { + DDB(printk("soundscape: Detect error A\n")); + return 0; + } outb((0x00), PORT(ODIE_ADDR)); if (inb(PORT(ODIE_ADDR)) != 0x00) - { - DDB(printk("soundscape: Detect error B\n")); - return 0; - } + { + DDB(printk("soundscape: Detect error B\n")); + return 0; + } outb((0xff), PORT(ODIE_ADDR)); if (inb(PORT(ODIE_ADDR)) != 0x0f) - { - DDB(printk("soundscape: Detect error C\n")); - return 0; - } + { + DDB(printk("soundscape: Detect error C\n")); + return 0; + } outb((save), PORT(ODIE_ADDR)); /* - * Now verify that some indirect registers return zero on some bits. - * This may break the driver with some future revisions of "ODIE" but... + * Now verify that some indirect registers return zero on some bits. + * This may break the driver with some future revisions of "ODIE" but... */ if (sscape_read(devc, 0) & 0x0c) - { - DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0))); - return 0; - } + { + DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0))); + return 0; + } if (sscape_read(devc, 1) & 0x0f) - { - DDB(printk("soundscape: Detect error E\n")); - return 0; - } + { + DDB(printk("soundscape: Detect error E\n")); + return 0; + } if (sscape_read(devc, 5) & 0x0f) - { - DDB(printk("soundscape: Detect error F\n")); - return 0; - } + { + DDB(printk("soundscape: Detect error F\n")); + return 0; + } return 1; } -int -probe_sscape(struct address_info *hw_config) +int probe_sscape(struct address_info *hw_config) { if (sscape_detected != 0 && sscape_detected != hw_config->io_base) @@ -818,110 +776,110 @@ #ifdef SSCAPE_DEBUG1 /* - * Temporary debugging aid. Print contents of the registers before - * changing them. + * Temporary debugging aid. Print contents of the registers before + * changing them. */ { - int i; + int i; for (i = 0; i < 13; i++) printk("I%d = %02x (old value)\n", i, sscape_read(devc, i)); } #endif - - devc->failed = 1; if (!detect_ga(devc)) return 0; if (old_hardware) /* Check that it's really an old Spea/Reveal card. */ - { - unsigned char tmp; - int cc; - - if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0)) - { - sscape_write(devc, GA_HMCTL_REG, tmp | 0x80); - for (cc = 0; cc < 200000; ++cc) - inb(devc->base + ODIE_ADDR); - } - } - sscape_detected = hw_config->io_base; + { + unsigned char tmp; + int cc; + if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0)) + { + sscape_write(devc, GA_HMCTL_REG, tmp | 0x80); + for (cc = 0; cc < 200000; ++cc) + inb(devc->base + ODIE_ADDR); + } + } + sscape_detected = hw_config->io_base; return 1; } -int -probe_ss_ms_sound(struct address_info *hw_config) +int probe_ss_ms_sound(struct address_info *hw_config) { - int i, irq_bits = 0xff; - int ad_flags = 0; + int i, irq_bits = 0xff; + int ad_flags = 0; if (devc->failed) - { - printk("Soundscape: Card not detected\n"); + { + printk(KERN_ERR "soundscape: Card not detected\n"); return 0; - } + } if (devc->ok == 0) - { - printk("SoundScape: Invalid initialization order.\n"); - return 0; - } + { + printk(KERN_ERR "soundscape: Invalid initialization order.\n"); + return 0; + } for (i = 0; i < sizeof(valid_interrupts); i++) + { if (hw_config->irq == valid_interrupts[i]) - { - irq_bits = i; - break; - } + { + irq_bits = i; + break; + } + } if (hw_config->irq > 15 || irq_bits == 0xff) - { - printk("SoundScape: Invalid MSS IRQ%d\n", hw_config->irq); - return 0; - } + { + printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq); + return 0; + } if (old_hardware) ad_flags = 0x12345677; /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */ return ad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp); } -void -attach_ss_ms_sound(struct address_info *hw_config) +void attach_ss_ms_sound(struct address_info *hw_config) { /* - * This routine configures the SoundScape card for use with the - * Win Sound System driver. The AD1848 codec interface uses the CD-ROM - * config registers of the "ODIE". + * This routine configures the SoundScape card for use with the + * Win Sound System driver. The AD1848 codec interface uses the CD-ROM + * config registers of the "ODIE". */ - int i, irq_bits = 0xff; + int i, irq_bits = 0xff; hw_config->dma = devc->dma; /* Share the DMA with the ODIE/OPUS chip */ /* * Setup the DMA polarity. */ + sscape_write(devc, GA_DMACFG_REG, 0x50); /* - * Take the gate-array off of the DMA channel. + * Take the gate-array off of the DMA channel. */ + sscape_write(devc, GA_DMAB_REG, 0x20); /* - * Init the AD1848 (CD-ROM) config reg. + * Init the AD1848 (CD-ROM) config reg. */ for (i = 0; i < sizeof(valid_interrupts); i++) + { if (hw_config->irq == valid_interrupts[i]) - { - irq_bits = i; - break; - } - sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | - (irq_bits << 1)); + { + irq_bits = i; + break; + } + } + sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | (irq_bits << 1)); if (hw_config->irq == devc->irq) - printk("SoundScape: Warning! The WSS mode can't share IRQ with MIDI\n"); + printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n"); hw_config->slots[0] = ad1848_init("SoundScape", hw_config->io_base, hw_config->irq, @@ -931,21 +889,21 @@ devc->osp); if (hw_config->slots[0] != -1) /* The AD1848 driver installed itself */ - { - audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations; - devc->codec_audiodev = hw_config->slots[0]; - devc->my_audiodev = hw_config->slots[0]; - - /* Set proper routings here (what are they) */ - AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE); - } + { + audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations; + devc->codec_audiodev = hw_config->slots[0]; + devc->my_audiodev = hw_config->slots[0]; + + /* Set proper routings here (what are they) */ + AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE); + } #ifdef SSCAPE_DEBUG5 /* - * Temporary debugging aid. Print contents of the registers - * after the AD1848 device has been initialized. + * Temporary debugging aid. Print contents of the registers + * after the AD1848 device has been initialized. */ { - int i; + int i; for (i = 0; i < 13; i++) printk("I%d = %02x\n", i, sscape_read(devc, i)); @@ -954,8 +912,7 @@ } -void -unload_sscape(struct address_info *hw_config) +void unload_sscape(struct address_info *hw_config) { release_region(devc->base + 2, 6); #if defined(CONFIG_MPU_EMU) && defined(CONFIG_MIDI) @@ -963,8 +920,7 @@ #endif } -void -unload_ss_ms_sound(struct address_info *hw_config) +void unload_ss_ms_sound(struct address_info *hw_config) { ad1848_unload(hw_config->io_base, hw_config->irq, @@ -983,11 +939,14 @@ int mpu_irq = -1; int mpu_io = -1; +int spea = -1; + static int mss = 0; MODULE_PARM(dma, "i"); MODULE_PARM(irq, "i"); MODULE_PARM(io, "i"); +MODULE_PARM(spea, "i"); /* spea=0/1 set the old_hardware */ MODULE_PARM(mpu_irq, "i"); MODULE_PARM(mpu_io, "i"); MODULE_PARM(mss, "i"); @@ -995,18 +954,17 @@ struct address_info config; struct address_info mpu_config; -int -init_module(void) +int init_module(void) { - printk("Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n"); + printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n"); if (dma == -1 || irq == -1 || io == -1) { - printk("DMA, IRQ, and IO port must be specified.\n"); - return -EINVAL; + printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n"); + return -EINVAL; } if (mpu_irq == -1 && mpu_io != -1) { - printk("MPU_IRQ must be specified if MPU_IO is set.\n"); + printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n"); return -EINVAL; } config.irq = irq; @@ -1016,6 +974,12 @@ mpu_config.irq = mpu_irq; mpu_config.io_base = mpu_io; + if(spea != -1) + { + old_hardware = spea; + printk(KERN_INFO "Forcing %s hardware support.\n", + spea?"new":"old"); + } if (probe_sscape(&mpu_config) == 0) return -ENODEV; @@ -1029,8 +993,7 @@ return 0; } -void -cleanup_module(void) +void cleanup_module(void) { if (mss) unload_ss_ms_sound(&config); @@ -1039,5 +1002,4 @@ } #endif - #endif - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |