summaryrefslogtreecommitdiff
path: root/sys/i386/isa/sound/pas2_card.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/isa/sound/pas2_card.c')
-rw-r--r--sys/i386/isa/sound/pas2_card.c456
1 files changed, 205 insertions, 251 deletions
diff --git a/sys/i386/isa/sound/pas2_card.c b/sys/i386/isa/sound/pas2_card.c
index 1bfd73fcc404..79acf57d45f5 100644
--- a/sys/i386/isa/sound/pas2_card.c
+++ b/sys/i386/isa/sound/pas2_card.c
@@ -1,11 +1,10 @@
-#define _PAS2_CARD_C_
/*
* sound/pas2_card.c
- *
+ *
* Detection routine for the Pro Audio Spectrum cards.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -13,7 +12,7 @@
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -25,15 +24,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
+ *
*/
+#include <i386/isa/sound/sound_config.h>
-#include "sound_config.h"
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PAS)
+#if defined(CONFIG_PAS)
+#define _PAS2_CARD_C_
#define DEFINE_TRANSLATIONS
-#include "pas.h"
+#include <i386/isa/sound/pas_hw.h>
/*
* The Address Translation code is used to convert I/O register addresses to
@@ -44,12 +43,14 @@ int translat_code;
static int pas_intr_mask = 0;
static int pas_irq = 0;
-static char pas_model;
+sound_os_info *pas_osp;
+
+char pas_model;
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()
+ * pas_read() and pas_write() are equivalents of inb and outb
*/
/*
* These routines perform the I/O address translation required
@@ -57,89 +58,72 @@ static char *pas_model_names[] =
/*
* to support other than the default base address
*/
+extern void mix_write(u_char data, int ioaddr);
-unsigned char
-pas_read (int ioaddr)
+u_char
+pas_read(int ioaddr)
{
- return INB (ioaddr ^ translat_code);
+ return inb(ioaddr ^ translat_code);
}
void
-pas_write (unsigned char data, int ioaddr)
+pas_write(u_char data, int ioaddr)
{
- OUTB (data, ioaddr ^ translat_code);
+ outb(ioaddr ^ translat_code, data);
}
void
-pas2_msg (char *foo)
+pas2_msg(char *foo)
{
- printk (" PAS2: %s.\n", foo);
+ printf(" PAS2: %s.\n", foo);
}
/******************* Begin of the Interrupt Handler ********************/
void
-pasintr (int unused)
+pasintr(int irq)
{
- int status;
+ int status;
- status = pas_read (INTERRUPT_STATUS);
- pas_write (status, INTERRUPT_STATUS); /*
- * Clear interrupt
- */
+ status = pas_read(INTERRUPT_STATUS);
+ pas_write(status, INTERRUPT_STATUS); /* Clear interrupt */
- if (status & I_S_PCM_SAMPLE_BUFFER_IRQ)
- {
-#ifndef EXCLUDE_AUDIO
- pas_pcm_interrupt (status, 1);
-#endif
- status &= ~I_S_PCM_SAMPLE_BUFFER_IRQ;
- }
- if (status & I_S_MIDI_IRQ)
- {
-#ifndef EXCLUDE_MIDI
-#ifdef EXCLUDE_PRO_MIDI
- pas_midi_interrupt ();
+ if (status & I_S_PCM_SAMPLE_BUFFER_IRQ) {
+#ifdef CONFIG_AUDIO
+ pas_pcm_interrupt(status, 1);
#endif
+ status &= ~I_S_PCM_SAMPLE_BUFFER_IRQ;
+ }
+ if (status & I_S_MIDI_IRQ) {
+#ifdef CONFIG_MIDI
+ pas_midi_interrupt();
#endif
- status &= ~I_S_MIDI_IRQ;
- }
-
+ status &= ~I_S_MIDI_IRQ;
+ }
}
int
-pas_set_intr (int mask)
+pas_set_intr(int mask)
{
- int err;
-
- if (!mask)
- return 0;
+ if (!mask)
+ return 0;
- if (!pas_intr_mask)
- {
- if ((err = snd_set_irq_handler (pas_irq, pasintr)) < 0)
- return err;
- }
- pas_intr_mask |= mask;
+ pas_intr_mask |= mask;
- pas_write (pas_intr_mask, INTERRUPT_MASK);
- return 0;
+ pas_write(pas_intr_mask, INTERRUPT_MASK);
+ return 0;
}
int
-pas_remove_intr (int mask)
+pas_remove_intr(int mask)
{
- if (!mask)
- return 0;
+ if (!mask)
+ return 0;
- pas_intr_mask &= ~mask;
- pas_write (pas_intr_mask, INTERRUPT_MASK);
+ pas_intr_mask &= ~mask;
+ pas_write(pas_intr_mask, INTERRUPT_MASK);
- if (!pas_intr_mask)
- {
- snd_release_irq (pas_irq);
- }
- return 0;
+ return 0;
}
/******************* End of the Interrupt handler **********************/
@@ -147,261 +131,231 @@ pas_remove_intr (int mask)
/******************* Begin of the Initialization Code ******************/
int
-config_pas_hw (struct address_info *hw_config)
+config_pas_hw(struct address_info * hw_config)
{
- char ok = 1;
- unsigned int_ptrs; /* scsi/sound interrupt pointers */
+ char ok = 1;
+ u_int int_ptrs; /* scsi/sound interrupt pointers */
- pas_irq = hw_config->irq;
+ pas_irq = hw_config->irq;
- pas_write (0x00, INTERRUPT_MASK);
+ pas_write(0x00, INTERRUPT_MASK);
- pas_write (0x36, SAMPLE_COUNTER_CONTROL); /*
- * Local timer control *
- * register
- */
+ pas_write(0x36, SAMPLE_COUNTER_CONTROL); /* Local timer control *
+ * register */
- pas_write (0x36, SAMPLE_RATE_TIMER); /*
- * Sample rate timer (16 bit)
- */
- pas_write (0, SAMPLE_RATE_TIMER);
+ pas_write(0x36, SAMPLE_RATE_TIMER); /* Sample rate timer (16 bit) */
+ pas_write(0, SAMPLE_RATE_TIMER);
- pas_write (0x74, SAMPLE_COUNTER_CONTROL); /*
- * Local timer control *
- * register
- */
+ pas_write(0x74, SAMPLE_COUNTER_CONTROL); /* Local timer control *
+ * register */
- pas_write (0x74, SAMPLE_BUFFER_COUNTER); /*
- * Sample count register (16
- * * bit)
- */
- pas_write (0, SAMPLE_BUFFER_COUNTER);
+ pas_write(0x74, SAMPLE_BUFFER_COUNTER); /* Sample count register (16 *
+ * bit) */
+ pas_write(0, SAMPLE_BUFFER_COUNTER);
- pas_write (F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER | F_F_MIXER_UNMUTE | 1, FILTER_FREQUENCY);
- pas_write (P_C_PCM_DMA_ENABLE | P_C_PCM_MONO | P_C_PCM_DAC_MODE | P_C_MIXER_CROSS_L_TO_L | P_C_MIXER_CROSS_R_TO_R, PCM_CONTROL);
- pas_write (S_M_PCM_RESET | S_M_FM_RESET | S_M_SB_RESET | S_M_MIXER_RESET /*
- * |
- * S_M_OPL3_DUAL_MONO
- */ , SERIAL_MIXER);
+ pas_write(F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER | F_F_MIXER_UNMUTE | 1, FILTER_FREQUENCY);
+ pas_write(P_C_PCM_DMA_ENABLE | P_C_PCM_MONO | P_C_PCM_DAC_MODE | P_C_MIXER_CROSS_L_TO_L | P_C_MIXER_CROSS_R_TO_R, PCM_CONTROL);
+ pas_write(S_M_PCM_RESET | S_M_FM_RESET | S_M_SB_RESET | S_M_MIXER_RESET /* | S_M_OPL3_DUAL_MONO */ , SERIAL_MIXER);
- pas_write (I_C_1_BOOT_RESET_ENABLE, IO_CONFIGURATION_1);
+ pas_write(I_C_1_BOOT_RESET_ENABLE
+#ifdef PAS_JOYSTICK_ENABLE
+ | I_C_1_JOYSTICK_ENABLE
+#endif
+ ,IO_CONFIGURATION_1);
- if (pas_irq < 0 || pas_irq > 15)
- {
- printk ("PAS2: Invalid IRQ %d", pas_irq);
- ok = 0;
- }
- else
- {
- int_ptrs = pas_read (IO_CONFIGURATION_3);
- int_ptrs |= I_C_3_PCM_IRQ_translate[pas_irq] & 0xf;
- pas_write (int_ptrs, IO_CONFIGURATION_3);
- if (!I_C_3_PCM_IRQ_translate[pas_irq])
- {
- printk ("PAS2: Invalid IRQ %d", pas_irq);
- ok = 0;
+ if (pas_irq < 0 || pas_irq > 15) {
+ printf("PAS2: Invalid IRQ %d", pas_irq);
+ ok = 0;
+ } else {
+ int_ptrs = pas_read(IO_CONFIGURATION_3);
+ int_ptrs |= I_C_3_PCM_IRQ_translate[pas_irq] & 0xf;
+ pas_write(int_ptrs, IO_CONFIGURATION_3);
+ if (!I_C_3_PCM_IRQ_translate[pas_irq]) {
+ printf("PAS2: Invalid IRQ %d", pas_irq);
+ ok = 0;
+ } else {
+ if (snd_set_irq_handler(pas_irq, pasintr, hw_config->osp) < 0)
+ ok = 0;
+ }
}
- }
- if (hw_config->dma < 0 || hw_config->dma > 7)
- {
- printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
- ok = 0;
- }
- else
- {
- pas_write (I_C_2_PCM_DMA_translate[hw_config->dma], IO_CONFIGURATION_2);
- if (!I_C_2_PCM_DMA_translate[hw_config->dma])
- {
- printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
- ok = 0;
+ if (hw_config->dma < 0 || hw_config->dma > 7) {
+ printf("PAS2: Invalid DMA selection %d", hw_config->dma);
+ ok = 0;
+ } else {
+ pas_write(I_C_2_PCM_DMA_translate[hw_config->dma], IO_CONFIGURATION_2);
+ if (!I_C_2_PCM_DMA_translate[hw_config->dma]) {
+ printf("PAS2: Invalid DMA selection %d", hw_config->dma);
+ ok = 0;
+ } else {
+ if (0) {
+ printf("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);
- OUTB (0x60, 0xa9);
+ outb(0xa8, 0x05);
+ outb(0xa9, 0x60);
#endif
#ifdef BROKEN_BUS_CLOCK
- pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND | S_C_1_FM_EMULATE_CLOCK, SYSTEM_CONFIGURATION_1);
+ pas_write(S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND | S_C_1_FM_EMULATE_CLOCK, SYSTEM_CONFIGURATION_1);
#else
- /*
- * pas_write(S_C_1_PCS_ENABLE, SYSTEM_CONFIGURATION_1);
- */
- pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND, SYSTEM_CONFIGURATION_1);
+ /*
+ * pas_write(S_C_1_PCS_ENABLE, SYSTEM_CONFIGURATION_1);
+ */
+ pas_write(S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND, SYSTEM_CONFIGURATION_1);
#endif
- pas_write (0x18, SYSTEM_CONFIGURATION_3); /*
- * ???
- */
+ pas_write(0x18, SYSTEM_CONFIGURATION_3); /* ??? */
- pas_write (F_F_MIXER_UNMUTE | 0x01, FILTER_FREQUENCY); /*
- * Sets mute
- * off and *
- * selects
- * filter
- * rate * of
- * 17.897 kHz
- */
+ pas_write(F_F_MIXER_UNMUTE | 0x01, FILTER_FREQUENCY); /* Sets mute off and *
+ * selects filter rate *
+ * of 17.897 kHz */
+ pas_write(8, PRESCALE_DIVIDER);
- if (pas_model == PAS_16 || pas_model == PAS_16D)
- pas_write (8, PRESCALE_DIVIDER);
- else
- pas_write (0, PRESCALE_DIVIDER);
+ mix_write(P_M_MV508_ADDRESS | 5, PARALLEL_MIXER);
+ mix_write(5, PARALLEL_MIXER);
- pas_write (P_M_MV508_ADDRESS | 5, PARALLEL_MIXER);
- pas_write (5, PARALLEL_MIXER);
+#if defined(CONFIG_SB_EMULATION) && defined(CONFIG_SB)
-#if !defined(EXCLUDE_SB_EMULATION) || !defined(EXCLUDE_SB)
+ {
+ struct address_info *sb_config;
- {
- struct address_info *sb_config;
+ if ((sb_config = sound_getconf(SNDCARD_SB))) {
+ u_char irq_dma;
- if ((sb_config = sound_getconf (SNDCARD_SB)))
- {
- unsigned char irq_dma;
+ /*
+ * Turn on Sound Blaster compatibility
+ */
+ /*
+ * bit 1 = SB emulation
+ */
+ /*
+ * bit 0 = MPU401 emulation (CDPC only :-( )
+ */
+ pas_write(0x02, COMPATIBILITY_ENABLE);
- /*
- * Turn on Sound Blaster compatibility
- */
- /*
- * bit 1 = SB emulation
- */
- /*
- * bit 0 = MPU401 emulation (CDPC only :-( )
- */
- pas_write (0x02, COMPATIBILITY_ENABLE);
-
- /*
- * "Emulation address"
- */
- pas_write ((sb_config->io_base >> 4) & 0x0f, EMULATION_ADDRESS);
+ /*
+ * "Emulation address"
+ */
+ pas_write((sb_config->io_base >> 4) & 0x0f, EMULATION_ADDRESS);
- if (!E_C_SB_DMA_translate[sb_config->dma])
- printk ("\n\nPAS16 Warning: Invalid SB DMA %d\n\n",
- sb_config->dma);
+ if (!E_C_SB_DMA_translate[sb_config->dma])
+ printf("\n\nPAS16 Warning: Invalid SB DMA %d\n\n",
+ sb_config->dma);
- if (!E_C_SB_IRQ_translate[sb_config->irq])
- printk ("\n\nPAS16 Warning: Invalid SB IRQ %d\n\n",
- sb_config->irq);
+ if (!E_C_SB_IRQ_translate[sb_config->irq])
+ printf("\n\nPAS16 Warning: Invalid SB IRQ %d\n\n",
+ sb_config->irq);
- irq_dma = E_C_SB_DMA_translate[sb_config->dma] |
- E_C_SB_IRQ_translate[sb_config->irq];
+ irq_dma = E_C_SB_DMA_translate[sb_config->dma] |
+ E_C_SB_IRQ_translate[sb_config->irq];
- pas_write (irq_dma, EMULATION_CONFIGURATION);
- }
- }
+ pas_write(irq_dma, EMULATION_CONFIGURATION);
+ }
+ }
+#else
+ pas_write(0x00, COMPATIBILITY_ENABLE);
#endif
- if (!ok)
- pas2_msg ("Driver not enabled");
+ if (!ok)
+ pas2_msg("Driver not enabled");
- return ok;
+ return ok;
}
int
-detect_pas_hw (struct address_info *hw_config)
+detect_pas_hw(struct address_info * hw_config)
{
- unsigned char board_id, foo;
+ u_char board_id, foo;
- /*
- * WARNING: Setting an option like W:1 or so that disables warm boot reset
- * of the card will screw up this detect code something fierce. Adding code
- * to handle this means possibly interfering with other cards on the bus if
- * you have something on base port 0x388. SO be forewarned.
- */
+ /*
+ * WARNING: Setting an option like W:1 or so that disables warm boot
+ * reset of the card will screw up this detect code something fierce.
+ * Adding code to handle this means possibly interfering with other
+ * cards on the bus if you have something on base port 0x388. SO be
+ * forewarned.
+ */
- OUTB (0xBC, MASTER_DECODE); /*
- * Talk to first board
- */
- OUTB (hw_config->io_base >> 2, MASTER_DECODE); /*
- * Set base address
- */
- translat_code = PAS_DEFAULT_BASE ^ hw_config->io_base;
- pas_write (1, WAIT_STATE); /*
- * One wait-state
- */
+ outb(MASTER_DECODE, 0xBC); /* Talk to first board */
+ outb(MASTER_DECODE, hw_config->io_base >> 2); /* Set base address */
+ translat_code = PAS_DEFAULT_BASE ^ hw_config->io_base;
+ pas_write(1, WAIT_STATE); /* One wait-state */
- board_id = pas_read (INTERRUPT_MASK);
+ board_id = pas_read(INTERRUPT_MASK);
- if (board_id == 0xff)
- return 0;
+ if (board_id == 0xff)
+ return 0;
- /*
- * We probably have a PAS-series board, now check for a PAS2-series board
- * by trying to change the board revision bits. PAS2-series hardware won't
- * let you do this - the bits are read-only.
- */
+ /*
+ * We probably have a PAS-series board, now check for a PAS2-series
+ * board by trying to change the board revision bits. PAS2-series
+ * hardware won't let you do this - the bits are read-only.
+ */
- foo = board_id ^ 0xe0;
+ foo = board_id ^ 0xe0;
- pas_write (foo, INTERRUPT_MASK);
- foo = INB (INTERRUPT_MASK);
- pas_write (board_id, INTERRUPT_MASK);
+ pas_write(foo, INTERRUPT_MASK);
+ foo = inb(INTERRUPT_MASK);
+ pas_write(board_id, INTERRUPT_MASK);
- if (board_id != foo) /*
- * Not a PAS2
- */
- return 0;
+ if (board_id != foo) /* Not a PAS2 */
+ return 0;
- pas_model = O_M_1_to_card[pas_read (OPERATION_MODE_1) & 0x0f];
+ pas_model = pas_read(CHIP_REV);
- return pas_model;
+ return pas_model;
}
-long
-attach_pas_card (long mem_start, struct address_info *hw_config)
+void
+attach_pas_card(struct address_info * hw_config)
{
- pas_irq = hw_config->irq;
+ pas_irq = hw_config->irq;
+ pas_osp = hw_config->osp;
- if (detect_pas_hw (hw_config))
- {
+ if (detect_pas_hw(hw_config)) {
- if ((pas_model = O_M_1_to_card[pas_read (OPERATION_MODE_1) & 0x0f]))
- {
- printk (" <%s rev %d>", pas_model_names[(int) pas_model], pas_read (BOARD_REV_ID));
- }
+ if ((pas_model = pas_read(CHIP_REV))) {
+ char temp[100];
- if (config_pas_hw (hw_config))
- {
+ sprintf(temp,
+ "%s rev %d", pas_model_names[(int) pas_model],
+ pas_read(BOARD_REV_ID));
+ conf_printf(temp, hw_config);
+ }
+ if (config_pas_hw(hw_config)) {
-#ifndef EXCLUDE_AUDIO
- mem_start = pas_pcm_init (mem_start, hw_config);
+#ifdef CONFIG_AUDIO
+ pas_pcm_init(hw_config);
#endif
-#if !defined(EXCLUDE_SB_EMULATION) && !defined(EXCLUDE_SB)
+#if defined(CONFIG_SB_EMULATION) && defined(CONFIG_SB)
- sb_dsp_disable_midi (); /*
- * The SB emulation don't support *
- * midi
- */
+ sb_dsp_disable_midi(); /* The SB emulation don't
+ * support * midi */
#endif
-#ifndef EXCLUDE_YM3812
- enable_opl3_mode (0x388, 0x38a, 0);
-#endif
-#ifndef EXCLUDE_MIDI
-#ifdef EXCLUDE_PRO_MIDI
- mem_start = pas_midi_init (mem_start);
-#endif
+#ifdef CONFIG_MIDI
+ pas_midi_init();
#endif
-
- pas_init_mixer ();
+ pas_init_mixer();
+ }
}
- }
-
- return mem_start;
}
int
-probe_pas (struct address_info *hw_config)
+probe_pas(struct address_info * hw_config)
{
- return detect_pas_hw (hw_config);
+ pas_osp = hw_config->osp;
+ return detect_pas_hw(hw_config);
}
#endif