PAS2 fixes

Alan Cox (alan@lxorguk.ukuu.org.uk)
Wed, 7 Jan 98 00:45 GMT


Can folks with pas2 cards try the diff attached. It tidies up the error cases
and formatting and also includes the missing module parms for newer modutils

It expects to be loaded with

insmod pas2 io=pas_io irq=pas_irq dma=pas_dma dma16=pas_dma16 sb_io= sb_irq= sb_dma= sb_dma16=...

Thats a fair mouthful and its sort of expected that tools like Red Hat
sndconfig will be handling it in distributions or folks will stick them
in conf.modules but it does mean a happier world for distributions and
folks who dont build kernels.

Anyway let me know if this diff works ..

--- pas2_card.c.old Sat Jan 3 15:14:58 1998
+++ pas2_card.c Wed Jan 7 01:12:30 1998
@@ -11,14 +11,22 @@

#if defined(CONFIG_PAS) || defined(MODULE)

-static unsigned char dma_bits[] =
-{4, 1, 2, 3, 0, 5, 6, 7};
-static unsigned char irq_bits[] =
-{0, 0, 1, 2, 3, 4, 5, 6, 0, 1, 7, 8, 9, 0, 10, 11};
-static unsigned char sb_irq_bits[] =
-{0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x08, 0x28, 0x30, 0x38, 0, 0};
-static unsigned char sb_dma_bits[] =
-{0x00, 0x40, 0x80, 0xC0, 0, 0, 0, 0};
+static unsigned char dma_bits[] = {
+ 4, 1, 2, 3, 0, 5, 6, 7
+};
+
+static unsigned char irq_bits[] = {
+ 0, 0, 1, 2, 3, 4, 5, 6, 0, 1, 7, 8, 9, 0, 10, 11
+};
+
+static unsigned char sb_irq_bits[] = {
+ 0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20,
+ 0x00, 0x08, 0x28, 0x30, 0x38, 0, 0
+};
+
+static unsigned char sb_dma_bits[] = {
+ 0x00, 0x40, 0x80, 0xC0, 0, 0, 0, 0
+};

/*
* The Address Translation code is used to convert I/O register addresses to
@@ -32,32 +40,35 @@


char pas_model = 0;
-static char *pas_model_names[] =
-{"", "Pro AudioSpectrum+", "CDPC", "Pro AudioSpectrum 16", "Pro AudioSpectrum 16D"};
+static char *pas_model_names[] = {
+ "",
+ "Pro AudioSpectrum+",
+ "CDPC",
+ "Pro AudioSpectrum 16",
+ "Pro AudioSpectrum 16D"
+};

/*
* pas_read() and pas_write() are equivalents of inb and outb
* These routines perform the I/O address translation required
* to support other than the default base address
*/
+
extern void mix_write(unsigned char data, int ioaddr);

-unsigned char
-pas_read(int ioaddr)
+unsigned charpas_read(int ioaddr)
{
return inb(ioaddr ^ translate_code);
}

-void
-pas_write(unsigned char data, int ioaddr)
+void pas_write(unsigned char data, int ioaddr)
{
outb((data), ioaddr ^ translate_code);
}

/******************* Begin of the Interrupt Handler ********************/

-static void
-pasintr(int irq, void *dev_id, struct pt_regs *dummy)
+static void pasintr(int irq, void *dev_id, struct pt_regs *dummy)
{
int status;

@@ -65,23 +76,22 @@
pas_write(status, 0x0B89); /* Clear interrupt */

if (status & 0x08)
- {
+ {
#ifdef CONFIG_AUDIO
pas_pcm_interrupt(status, 1);
#endif
status &= ~0x08;
- }
+ }
if (status & 0x10)
- {
+ {
#if defined(CONFIG_MIDI)
pas_midi_interrupt();
#endif
status &= ~0x10;
- }
+ }
}

-int
-pas_set_intr(int mask)
+int pas_set_intr(int mask)
{
if (!mask)
return 0;
@@ -92,8 +102,7 @@
return 0;
}

-int
-pas_remove_intr(int mask)
+int pas_remove_intr(int mask)
{
if (!mask)
return 0;
@@ -110,8 +119,7 @@

extern struct address_info sbhw_config;

-static int
-config_pas_hw(struct address_info *hw_config)
+static int config_pas_hw(struct address_info *hw_config)
{
char ok = 1;
unsigned int_ptrs; /* scsi/sound interrupt pointers */
@@ -129,8 +137,8 @@
pas_write(0x80 | 0x40 | 0x20 | 1, 0x0B8A);
pas_write(0x80 | 0x20 | 0x10 | 0x08 | 0x01, 0xF8A);
pas_write(0x01 | 0x02 | 0x04 | 0x10 /*
- * |
- * 0x80
+ * |
+ * 0x80
*/ , 0xB88);

pas_write(0x80
@@ -140,49 +148,53 @@
,0xF388);

if (pas_irq < 0 || pas_irq > 15)
- {
- printk("PAS16: Invalid IRQ %d", pas_irq);
- ok = 0;
- } else
- {
- int_ptrs = pas_read(0xF38A);
- int_ptrs |= irq_bits[pas_irq] & 0xf;
- pas_write(int_ptrs, 0xF38A);
- if (!irq_bits[pas_irq])
- {
- printk("PAS16: Invalid IRQ %d", pas_irq);
- ok = 0;
- } else
- {
- if (snd_set_irq_handler(pas_irq, pasintr, "PAS16", hw_config->osp) < 0)
- ok = 0;
- }
- }
+ {
+ printk(KERN_ERR "PAS16: Invalid IRQ %d", pas_irq);
+ ok = 0;
+ }
+ else
+ {
+ int_ptrs = pas_read(0xF38A);
+ int_ptrs |= irq_bits[pas_irq] & 0xf;
+ pas_write(int_ptrs, 0xF38A);
+ if (!irq_bits[pas_irq])
+ {
+ printk(KERN_ERR "PAS16: Invalid IRQ %d", pas_irq);
+ ok = 0;
+ }
+ else
+ {
+ if (snd_set_irq_handler(pas_irq, pasintr, "PAS16", hw_config->osp) < 0)
+ ok = 0;
+ }
+ }

if (hw_config->dma < 0 || hw_config->dma > 7)
- {
- printk("PAS16: Invalid DMA selection %d", hw_config->dma);
- ok = 0;
- } else
- {
- pas_write(dma_bits[hw_config->dma], 0xF389);
- if (!dma_bits[hw_config->dma])
- {
- printk("PAS16: Invalid DMA selection %d", hw_config->dma);
- ok = 0;
- } else
- {
- if (sound_alloc_dma(hw_config->dma, "PAS16"))
- {
- printk("pas2_card.c: Can't allocate DMA channel\n");
- ok = 0;
- }
- }
- }
+ {
+ printk(KERN_ERR "PAS16: Invalid DMA selection %d", hw_config->dma);
+ ok = 0;
+ }
+ else
+ {
+ pas_write(dma_bits[hw_config->dma], 0xF389);
+ if (!dma_bits[hw_config->dma])
+ {
+ printk(KERN_ERR "PAS16: Invalid DMA selection %d", hw_config->dma);
+ ok = 0;
+ }
+ else
+ {
+ if (sound_alloc_dma(hw_config->dma, "PAS16"))
+ {
+ printk(KERN_ERR "pas2_card.c: Can't allocate DMA channel\n");
+ ok = 0;
+ }
+ }
+ }

/*
- * This fixes the timing problems of the PAS due to the Symphony chipset
- * as per Media Vision. Only define this if your PAS doesn't work correctly.
+ * This fixes the timing problems of the PAS due to the Symphony chipset
+ * as per Media Vision. Only define this if your PAS doesn't work correctly.
*/
#ifdef SYMPHONY_PAS
outb((0x05), 0xa8);
@@ -215,33 +227,36 @@
sb_config = &sbhw_config;
if (sb_config->io_base)
#endif
- {
- unsigned char irq_dma;
-
- /*
- * Turn on Sound Blaster compatibility
- * bit 1 = SB emulation
- * bit 0 = MPU401 emulation (CDPC only :-( )
- */
- pas_write(0x02, 0xF788);
-
- /*
- * "Emulation address"
- */
- pas_write((sb_config->io_base >> 4) & 0x0f, 0xF789);
- pas_sb_base = sb_config->io_base;
-
- if (!sb_dma_bits[sb_config->dma])
- printk("\n\nPAS16 Warning: Invalid SB DMA %d\n\n", sb_config->dma);
-
- if (!sb_irq_bits[sb_config->irq])
- printk("\n\nPAS16 Warning: Invalid SB IRQ %d\n\n", sb_config->irq);
-
- irq_dma = sb_dma_bits[sb_config->dma] |
- sb_irq_bits[sb_config->irq];
+ {
+ unsigned char irq_dma;

- pas_write(irq_dma, 0xFB8A);
- } else
+ /*
+ * Turn on Sound Blaster compatibility
+ * bit 1 = SB emulation
+ * bit 0 = MPU401 emulation (CDPC only :-( )
+ */
+
+ pas_write(0x02, 0xF788);
+
+ /*
+ * "Emulation address"
+ */
+
+ pas_write((sb_config->io_base >> 4) & 0x0f, 0xF789);
+ pas_sb_base = sb_config->io_base;
+
+ if (!sb_dma_bits[sb_config->dma])
+ printk(KERN_ERR "PAS16 Warning: Invalid SB DMA %d\n\n", sb_config->dma);
+
+ if (!sb_irq_bits[sb_config->irq])
+ printk(KERN_ERR "PAS16 Warning: Invalid SB IRQ %d\n\n", sb_config->irq);
+
+ irq_dma = sb_dma_bits[sb_config->dma] |
+ sb_irq_bits[sb_config->irq];
+
+ pas_write(irq_dma, 0xFB8A);
+ }
+ else
pas_write(0x00, 0xF788);
}
#else
@@ -249,13 +264,12 @@
#endif

if (!ok)
- printk("PAS16: Driver not enabled\n");
+ printk(KERN_WARNING "PAS16: Driver not enabled\n");

return ok;
}

-static int
-detect_pas_hw(struct address_info *hw_config)
+static int detect_pas_hw(struct address_info *hw_config)
{
unsigned char board_id, foo;

@@ -296,40 +310,39 @@
return pas_model;
}

-void
-attach_pas_card(struct address_info *hw_config)
+void attach_pas_card(struct address_info *hw_config)
{
pas_irq = hw_config->irq;

if (detect_pas_hw(hw_config))
- {
+ {

- if ((pas_model = pas_read(0xFF88)))
- {
- char temp[100];
+ if ((pas_model = pas_read(0xFF88)))
+ {
+ char temp[100];

- sprintf(temp,
+ sprintf(temp,
"%s rev %d", pas_model_names[(int) pas_model],
pas_read(0x2789));
- conf_printf(temp, hw_config);
- }
- if (config_pas_hw(hw_config))
- {
+ conf_printf(temp, hw_config);
+ }
+ if (config_pas_hw(hw_config))
+ {
#ifdef CONFIG_AUDIO
- pas_pcm_init(hw_config);
+ pas_pcm_init(hw_config);
#endif

#if !defined(DISABLE_SB_EMULATION) && (defined(CONFIG_SB) || defined(CONFIG_SB_MODULE))

- sb_dsp_disable_midi(pas_sb_base); /* No MIDI capability */
+ sb_dsp_disable_midi(pas_sb_base); /* No MIDI capability */
#endif

#if defined(CONFIG_MIDI)
- pas_midi_init();
+ pas_midi_init();
#endif
- pas_init_mixer();
- }
- }
+ pas_init_mixer();
+ }
+ }
}

int
@@ -357,18 +370,28 @@
int sb_dma = -1;
int sb_dma16 = -1;

+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
+MODULE_PARM(dma,"i");
+MODULE_PARM(dma16,"i");
+
+MODULE_PARM(sb_io,"i");
+MODULE_PARM(sb_irq,"i");
+MODULE_PARM(sb_dma,"i");
+MODULE_PARM(sb_dma16,"i");
+
struct address_info config;
struct address_info sbhw_config;

int init_module(void)
{
- printk("MediaTrix audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+ printk(KERN_INFO "MediaTrix audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");

if (io == -1 || dma == -1 || irq == -1)
- {
- printk("I/O, IRQ, DMA and type are mandatory\n");
+ {
+ printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
return -EINVAL;
- }
+ }
config.io_base = io;
config.irq = irq;
config.dma = dma;
@@ -386,8 +409,7 @@
return 0;
}

-void
-cleanup_module(void)
+void cleanup_module(void)
{
unload_pas(&config);
SOUND_LOCK_END;