patch-1.3.58 linux/drivers/sound/sb_dsp.c
Next file: linux/drivers/sound/sb_midi.c
Previous file: linux/drivers/sound/sb_card.c
Back to the patch index
Back to the overall index
- Lines: 1141
- Date:
Tue Jan 9 00:37:35 1996
- Orig file:
v1.3.57/linux/drivers/sound/sb_dsp.c
- Orig date:
Thu Nov 9 11:23:51 1995
diff -u --recursive --new-file v1.3.57/linux/drivers/sound/sb_dsp.c linux/drivers/sound/sb_dsp.c
@@ -35,23 +35,22 @@
#include "sound_config.h"
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
-
-#ifdef SM_WAVE
-#define JAZZ16
-#endif
+#if defined(CONFIG_SB)
#include "sb.h"
#include "sb_mixer.h"
#undef SB_TEST_IRQ
int sbc_base = 0;
-static int sbc_irq = 0;
+static int sbc_irq = 0, sbc_dma;
static int open_mode = 0; /* Read, write or both */
int Jazz16_detected = 0;
+int AudioDrive = 0; /* 1=ES1688 detected */
+static int ess_mpu_irq = 0;
int sb_no_recording = 0;
static int dsp_count = 0;
static int trigger_bits;
+static int mpu_base = 0, mpu_irq = 0;
/*
* The DSP channel can be used either for input or output. Variable
@@ -68,46 +67,32 @@
* initialization * */
static int midi_disabled = 0;
int sb_dsp_highspeed = 0;
-int sbc_major = 1, sbc_minor = 0; /*
-
-
- * * * * DSP version */
+int sbc_major = 1, sbc_minor = 0;
static int dsp_stereo = 0;
static int dsp_current_speed = DSP_DEFAULT_SPEED;
static int sb16 = 0;
static int irq_verified = 0;
int sb_midi_mode = NORMAL_MIDI;
-int sb_midi_busy = 0; /*
-
-
- * * * * 1 if the process has output
- * to * * MIDI */
+int sb_midi_busy = 0;
int sb_dsp_busy = 0;
-volatile int sb_irq_mode = IMODE_NONE; /*
-
-
- * * * * IMODE_INPUT, *
- * IMODE_OUTPUT * * or *
- * IMODE_NONE */
+volatile int sb_irq_mode = IMODE_NONE;
static volatile int irq_ok = 0;
static int dma8 = 1;
+static int dsp_16bit = 0;
-#ifdef JAZZ16
/* 16 bit support
*/
-static int dsp_16bit = 0;
-static int dma16 = 5;
+static int dma16 = 1;
static int dsp_set_bits (int arg);
static int initialize_ProSonic16 (void);
/* end of 16 bit support
*/
-#endif
int sb_duplex_midi = 0;
static int my_dev = 0;
@@ -116,11 +101,12 @@
static int dsp_speed (int);
static int dsp_set_stereo (int mode);
-int sb_dsp_command (unsigned char val);
static void sb_dsp_reset (int dev);
sound_os_info *sb_osp = NULL;
-#if !defined(EXCLUDE_MIDI) || !defined(EXCLUDE_AUDIO)
+static void ess_init (void);
+
+#if defined(CONFIG_MIDI) || defined(CONFIG_AUDIO)
/*
* Common code for the midi and pcm functions
@@ -154,58 +140,83 @@
}
printk ("SoundBlaster: DSP Command(%x) Timeout.\n", val);
- printk ("IRQ conflict???\n");
return 0;
}
+static int
+ess_write (unsigned char reg, unsigned char data)
+{
+ /* Write a byte to an extended mode register of ES1688 */
+
+ if (!sb_dsp_command (reg))
+ return 0;
+
+ return sb_dsp_command (data);
+}
+
+static int
+ess_read (unsigned char reg)
+{
+/* Read a byte from an extended mode register of ES1688 */
+
+ int i;
+
+ if (!sb_dsp_command (0xc0)) /* Read register command */
+ return -1;
+
+ if (!sb_dsp_command (reg))
+ return -1;
+
+ for (i = 1000; i; i--)
+ {
+ if (inb (DSP_DATA_AVAIL) & 0x80)
+ return inb (DSP_READ);
+ }
+
+ return -1;
+}
+
void
sbintr (int irq, struct pt_regs *dummy)
{
int status;
-#ifndef EXCLUDE_SBPRO
- if (sb16)
+ if (sb16 && !AudioDrive)
{
unsigned char src = sb_getmixer (IRQ_STAT); /* Interrupt source register */
-#ifndef EXCLUDE_SB16
if (src & 3)
sb16_dsp_interrupt (irq);
-#ifndef EXCLUDE_MIDI
+#ifdef CONFIG_MIDI
if (src & 4)
sb16midiintr (irq); /*
* SB MPU401 interrupt
*/
#endif
-#endif
-
if (!(src & 1))
return; /*
* Not a DSP interupt
*/
}
-#endif
status = inb (DSP_DATA_AVAIL); /*
* Clear interrupt
*/
-
if (sb_intr_active)
switch (sb_irq_mode)
{
case IMODE_OUTPUT:
- sb_intr_active = 0;
+ if (!AudioDrive)
+ sb_intr_active = 0;
DMAbuf_outputintr (my_dev, 1);
break;
case IMODE_INPUT:
- sb_intr_active = 0;
+ if (!AudioDrive)
+ sb_intr_active = 0;
DMAbuf_inputintr (my_dev);
- /*
- * A complete buffer has been input. Let's start new one
- */
break;
case IMODE_INIT:
@@ -214,7 +225,7 @@
break;
case IMODE_MIDI:
-#ifndef EXCLUDE_MIDI
+#ifdef CONFIG_MIDI
sb_midi_interrupt (irq);
#endif
break;
@@ -240,24 +251,31 @@
{
int loopc;
- outb (1, DSP_RESET);
- tenmicrosec ();
+ if (AudioDrive)
+ outb (3, DSP_RESET); /* Reset FIFO too */
+ else
+ outb (1, DSP_RESET);
+
+ tenmicrosec (sb_osp);
outb (0, DSP_RESET);
- tenmicrosec ();
- tenmicrosec ();
- tenmicrosec ();
+ tenmicrosec (sb_osp);
+ tenmicrosec (sb_osp);
+ tenmicrosec (sb_osp);
for (loopc = 0; loopc < 1000 && !(inb (DSP_DATA_AVAIL) & 0x80); loopc++);
if (inb (DSP_READ) != 0xAA)
return 0; /* Sorry */
+ if (AudioDrive)
+ sb_dsp_command (0xc6); /* Enable extended mode */
+
return 1;
}
#endif
-#ifndef EXCLUDE_AUDIO
+#ifdef CONFIG_AUDIO
static void
dsp_speaker (char state)
@@ -269,12 +287,45 @@
}
static int
+ess_speed (int speed)
+{
+ int rate;
+ unsigned char bits = 0;
+
+ if (speed < 4000)
+ speed = 4000;
+ else if (speed > 48000)
+ speed = 48000;
+
+ if (speed > 22000)
+ {
+ bits = 0x80;
+ rate = 256 - (795500 + speed / 2) / speed;
+ speed = 795500 / (256 - rate);
+ }
+ else
+ {
+ rate = 128 - (397700 + speed / 2) / speed;
+ speed = 397700 / (128 - rate);
+ }
+
+ bits |= (unsigned char) rate;
+ ess_write (0xa1, bits);
+
+ dsp_current_speed = speed;
+ return speed;
+}
+
+static int
dsp_speed (int speed)
{
unsigned char tconst;
unsigned long flags;
int max_speed = 44100;
+ if (AudioDrive)
+ return ess_speed (speed);
+
if (speed < 4000)
speed = 4000;
@@ -306,7 +357,7 @@
/*
* Max. stereo speed is 22050
*/
- if (dsp_stereo && speed > 22050 && Jazz16_detected == 0)
+ if (dsp_stereo && speed > 22050 && Jazz16_detected == 0 && AudioDrive == 0)
speed = 22050;
#endif
@@ -373,9 +424,6 @@
{
dsp_stereo = 0;
-#ifdef EXCLUDE_SBPRO
- return 0;
-#else
if (sbc_major < 3 || sb16)
return 0; /*
* Sorry no stereo
@@ -389,14 +437,30 @@
dsp_stereo = !!mode;
return dsp_stereo;
-#endif
}
+static unsigned long trg_buf;
+static int trg_bytes;
+static int trg_intrflag;
+static int trg_restart;
+
static void
-sb_dsp_output_block (int dev, unsigned long buf, int count,
+sb_dsp_output_block (int dev, unsigned long buf, int nr_bytes,
int intrflag, int restart_dma)
{
+ trg_buf = buf;
+ trg_bytes = nr_bytes;
+ trg_intrflag = intrflag;
+ trg_restart = restart_dma;
+ sb_irq_mode = IMODE_OUTPUT;
+}
+
+static void
+actually_output_block (int dev, unsigned long buf, int nr_bytes,
+ int intrflag, int restart_dma)
+{
unsigned long flags;
+ int count = nr_bytes;
if (!sb_irq_mode)
dsp_speaker (ON);
@@ -411,7 +475,17 @@
dsp_count = count;
sb_irq_mode = IMODE_OUTPUT;
- if (sb_dsp_highspeed)
+
+ if (AudioDrive)
+ {
+ int c = 0x10000 - count; /* ES1688 increments the count */
+
+ ess_write (0xa4, (unsigned char) (c & 0xff));
+ ess_write (0xa5, (unsigned char) ((c >> 8) & 0xff));
+
+ ess_write (0xb8, ess_read (0xb8) | 0x01); /* Go */
+ }
+ else if (sb_dsp_highspeed)
{
save_flags (flags);
cli ();
@@ -451,6 +525,17 @@
sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag,
int restart_dma)
{
+ trg_buf = buf;
+ trg_bytes = count;
+ trg_intrflag = intrflag;
+ trg_restart = restart_dma;
+ sb_irq_mode = IMODE_INPUT;
+}
+
+static void
+actually_start_input (int dev, unsigned long buf, int count, int intrflag,
+ int restart_dma)
+{
unsigned long flags;
if (sb_no_recording)
@@ -475,7 +560,17 @@
dsp_count = count;
sb_irq_mode = IMODE_INPUT;
- if (sb_dsp_highspeed)
+
+ if (AudioDrive)
+ {
+ int c = 0x10000 - count; /* ES1688 increments the count */
+
+ ess_write (0xa4, (unsigned char) (c & 0xff));
+ ess_write (0xa5, (unsigned char) ((c >> 8) & 0xff));
+
+ ess_write (0xb8, ess_read (0xb8) | 0x01); /* Go */
+ }
+ else if (sb_dsp_highspeed)
{
save_flags (flags);
cli ();
@@ -515,13 +610,24 @@
static void
sb_dsp_trigger (int dev, int bits)
{
- if (bits == trigger_bits)
- return;
if (!bits)
sb_dsp_command (0xd0); /* Halt DMA */
else if (bits & sb_irq_mode)
- sb_dsp_command (0xd4); /* Continue DMA */
+ {
+ switch (sb_irq_mode)
+ {
+ case IMODE_INPUT:
+ actually_start_input (my_dev, trg_buf, trg_bytes,
+ trg_intrflag, trg_restart);
+ break;
+
+ case IMODE_OUTPUT:
+ actually_output_block (my_dev, trg_buf, trg_bytes,
+ trg_intrflag, trg_restart);
+ break;
+ }
+ }
trigger_bits = bits;
}
@@ -542,30 +648,61 @@
* SB Pro
*/
{
-#ifdef JAZZ16
- /* Select correct dma channel
- * for 16/8 bit acccess
- */
- audio_devs[my_dev]->dmachan1 = dsp_16bit ? dma16 : dma8;
- if (dsp_stereo)
- sb_dsp_command (dsp_16bit ? 0xac : 0xa8);
- else
- sb_dsp_command (dsp_16bit ? 0xa4 : 0xa0);
-#else
- /* 8 bit only cards use this
- */
- if (dsp_stereo)
- sb_dsp_command (0xa8);
+ if (AudioDrive)
+ {
+
+ /* ess_init(); */
+ ess_write (0xb8, 0x0e); /* Auto init DMA mode */
+ ess_write (0xa8, (ess_read (0xa8) & ~0x04) |
+ (2 - dsp_stereo)); /* Mono/stereo */
+ ess_write (0xb9, 2); /* Demand mode (2 bytes/xfer) */
+
+ if (!dsp_stereo)
+ {
+ if (dsp_16bit == 0)
+ { /* 8 bit mono */
+ ess_write (0xb7, 0x51);
+ ess_write (0xb7, 0xd0);
+ }
+ else
+ { /* 16 bit mono */
+ ess_write (0xb7, 0x71);
+ ess_write (0xb7, 0xf4);
+ }
+ }
+ else
+ { /* Stereo */
+ if (!dsp_16bit)
+ { /* 8 bit stereo */
+ ess_write (0xb7, 0x51);
+ ess_write (0xb7, 0x98);
+ }
+ else
+ { /* 16 bit stereo */
+ ess_write (0xb7, 0x71);
+ ess_write (0xb7, 0xbc);
+ }
+ }
+
+ ess_write (0xb1, (ess_read (0xb1) & 0x0f) | 0x50);
+ ess_write (0xb2, (ess_read (0xb2) & 0x0f) | 0x50);
+ }
else
- sb_dsp_command (0xa0);
-#endif
- dsp_speed (dsp_current_speed); /*
- * Speed must be recalculated if
- * #channels * changes
- */
+ { /* !AudioDrive */
+
+ /* Select correct dma channel
+ * for 16/8 bit acccess
+ */
+ audio_devs[my_dev]->dmachan1 = dsp_16bit ? dma16 : dma8;
+ if (dsp_stereo)
+ sb_dsp_command (dsp_16bit ? 0xac : 0xa8);
+ else
+ sb_dsp_command (dsp_16bit ? 0xa4 : 0xa0);
+
+ dsp_speed (dsp_current_speed);
+ } /* !AudioDrive */
}
trigger_bits = 0;
- sb_dsp_command (0xd0); /* Halt DMA */
return 0;
}
@@ -573,34 +710,72 @@
sb_dsp_prepare_for_output (int dev, int bsize, int bcount)
{
dsp_cleanup ();
- dsp_speaker (ON);
+ dsp_speaker (OFF);
-#ifndef EXCLUDE_SBPRO
- if (sbc_major == 3) /*
- * SB Pro
- */
+ if (sbc_major == 3) /* SB Pro (at least ) */
{
-#ifdef JAZZ16
- /* 16 bit specific instructions
- */
- audio_devs[my_dev]->dmachan1 = dsp_16bit ? dma16 : dma8;
- if (Jazz16_detected != 2) /* SM Wave */
- sb_mixer_set_stereo (dsp_stereo);
- if (dsp_stereo)
- sb_dsp_command (dsp_16bit ? 0xac : 0xa8);
+
+ if (AudioDrive)
+ {
+
+ /* ess_init(); */
+ ess_write (0xb8, 4); /* Auto init DMA mode */
+ ess_write (0xa8, ess_read (0xa8) |
+ (2 - dsp_stereo)); /* Mono/stereo */
+ ess_write (0xb9, 2); /* Demand mode (2 bytes/xfer) */
+
+ if (!dsp_stereo)
+ {
+ if (dsp_16bit == 0)
+ { /* 8 bit mono */
+ ess_write (0xb6, 0x80);
+ ess_write (0xb7, 0x51);
+ ess_write (0xb7, 0xd0);
+ }
+ else
+ { /* 16 bit mono */
+ ess_write (0xb6, 0x00);
+ ess_write (0xb7, 0x71);
+ ess_write (0xb7, 0xf4);
+ }
+ }
+ else
+ { /* Stereo */
+ if (!dsp_16bit)
+ { /* 8 bit stereo */
+ ess_write (0xb6, 0x80);
+ ess_write (0xb7, 0x51);
+ ess_write (0xb7, 0x98);
+ }
+ else
+ { /* 16 bit stereo */
+ ess_write (0xb6, 0x00);
+ ess_write (0xb7, 0x71);
+ ess_write (0xb7, 0xbc);
+ }
+ }
+
+ ess_write (0xb1, (ess_read (0xb1) & 0x0f) | 0x50);
+ ess_write (0xb2, (ess_read (0xb2) & 0x0f) | 0x50);
+ }
else
- sb_dsp_command (dsp_16bit ? 0xa4 : 0xa0);
-#else
- sb_mixer_set_stereo (dsp_stereo);
-#endif
- dsp_speed (dsp_current_speed); /*
- * Speed must be recalculated if
- * #channels * changes
- */
+ { /* !AudioDrive */
+
+ /* 16 bit specific instructions (Jazz16)
+ */
+ audio_devs[my_dev]->dmachan1 = dsp_16bit ? dma16 : dma8;
+ if (Jazz16_detected != 2) /* SM Wave */
+ sb_mixer_set_stereo (dsp_stereo);
+ if (dsp_stereo)
+ sb_dsp_command (dsp_16bit ? 0xac : 0xa8);
+ else
+ sb_dsp_command (dsp_16bit ? 0xa4 : 0xa0);
+ } /* !AudioDrive */
+
}
-#endif
+
trigger_bits = 0;
- sb_dsp_command (0xd0); /* Halt DMA */
+ dsp_speaker (ON);
return 0;
}
@@ -653,11 +828,9 @@
/* Allocate 8 bit dma
*/
-#ifdef JAZZ16
audio_devs[my_dev]->dmachan1 = dma8;
-#endif
-#ifdef JAZZ16
- /* Allocate 16 bit dma
+
+ /* Allocate 16 bit dma (jazz16)
*/
if (Jazz16_detected != 0)
if (dma16 != dma8)
@@ -669,7 +842,6 @@
return -EBUSY;
}
}
-#endif
sb_irq_mode = IMODE_NONE;
@@ -682,7 +854,6 @@
static void
sb_dsp_close (int dev)
{
-#ifdef JAZZ16
/* Release 16 bit dma channel
*/
if (Jazz16_detected)
@@ -692,7 +863,6 @@
if (dma16 != dma8)
sound_close_dma (dma16);
}
-#endif
/* DMAbuf_close_dma (dev); */
sb_free_irq ();
@@ -704,14 +874,11 @@
open_mode = 0;
}
-#ifdef JAZZ16
-/* Function dsp_set_bits() only required for 16 bit cards
- */
static int
dsp_set_bits (int arg)
{
if (arg)
- if (Jazz16_detected == 0)
+ if (Jazz16_detected == 0 && AudioDrive == 0)
dsp_16bit = 0;
else
switch (arg)
@@ -725,11 +892,10 @@
default:
dsp_16bit = 0;
}
+
return dsp_16bit ? 16 : 8;
}
-#endif /* ifdef JAZZ16 */
-
static int
sb_dsp_ioctl (int dev, unsigned int cmd, ioctl_arg arg, int local)
{
@@ -737,7 +903,7 @@
{
case SOUND_PCM_WRITE_RATE:
if (local)
- return dsp_speed ((long) arg);
+ return dsp_speed ((int) arg);
return snd_ioctl_return ((int *) arg, dsp_speed (get_fs_long ((long *) arg)));
break;
@@ -749,7 +915,7 @@
case SOUND_PCM_WRITE_CHANNELS:
if (local)
- return dsp_set_stereo ((long) arg - 1) + 1;
+ return dsp_set_stereo ((int) arg - 1) + 1;
return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg) - 1) + 1);
break;
@@ -761,11 +927,10 @@
case SNDCTL_DSP_STEREO:
if (local)
- return dsp_set_stereo ((long) arg);
+ return dsp_set_stereo ((int) arg);
return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg)));
break;
-#ifdef JAZZ16
/* Word size specific cases here.
* SNDCTL_DSP_SETFMT=SOUND_PCM_WRITE_BITS
*/
@@ -780,14 +945,6 @@
return dsp_16bit ? 16 : 8;
return snd_ioctl_return ((int *) arg, dsp_16bit ? 16 : 8);
break;
-#else
- case SOUND_PCM_WRITE_BITS:
- case SOUND_PCM_READ_BITS:
- if (local)
- return 8;
- return snd_ioctl_return ((int *) arg, 8); /* Only 8 bits/sample supported */
- break;
-#endif /* ifdef JAZZ16 */
case SOUND_PCM_WRITE_FILTER:
case SOUND_PCM_READ_FILTER:
@@ -818,8 +975,6 @@
#endif
-#ifdef JAZZ16
-
/*
* Initialization of a Media Vision ProSonic 16 Soundcard.
* The function initializes a ProSonic 16 like PROS.EXE does for DOS. It sets
@@ -845,7 +1000,6 @@
return 0xffff;
}
-#ifdef SM_WAVE
/*
* Logitech Soundman Wave detection and initialization by Hannu Savolainen.
*
@@ -914,7 +1068,7 @@
outb ((control & 0xfe) | 2, mpu_base + 7); /* xxxxxxx0 resets the mc */
for (i = 0; i < 300; i++) /* Wait at least 1ms */
- tenmicrosec ();
+ tenmicrosec (sb_osp);
outb (control & 0xfc, mpu_base + 7); /* xxxxxx00 enables RAM */
@@ -923,7 +1077,7 @@
*/
smw_putmem (mp_base, 0, 0x00);
smw_putmem (mp_base, 1, 0xff);
- tenmicrosec ();
+ tenmicrosec (sb_osp);
if (smw_getmem (mp_base, 0) != 0x00 || smw_getmem (mp_base, 1) != 0xff)
{
@@ -995,8 +1149,6 @@
return 1;
}
-#endif
-
static int
initialize_ProSonic16 (void)
{
@@ -1005,23 +1157,9 @@
{0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6}, dma_translat[8] =
{0, 1, 0, 2, 0, 3, 0, 4};
- struct address_info *mpu_config;
-
- int mpu_base, mpu_irq;
-
- if ((mpu_config = sound_getconf (SNDCARD_MPU401)))
- {
- mpu_base = mpu_config->io_base;
- mpu_irq = mpu_config->irq;
- }
- else
- {
- mpu_base = mpu_irq = 0;
- }
-
outb (0xAF, 0x201); /* ProSonic/Jazz16 wakeup */
for (x = 0; x < 1000; ++x) /* wait 10 milliseconds */
- tenmicrosec ();
+ tenmicrosec (sb_osp);
outb (0x50, 0x201);
outb ((sbc_base & 0x70) | ((mpu_base & 0x30) >> 4), 0x201);
@@ -1036,18 +1174,15 @@
return 1;
if (sb_dsp_command (0xFB) && /* set DMA-channels and Interrupts */
- sb_dsp_command ((dma_translat[JAZZ_DMA16] << 4) | dma_translat[dma8]) &&
+ sb_dsp_command ((dma_translat[dma16] << 4) | dma_translat[dma8]) &&
sb_dsp_command ((int_translat[mpu_irq] << 4) | int_translat[sbc_irq]))
{
Jazz16_detected = 1;
- if (mpu_base == 0)
- printk ("Jazz16: No MPU401 devices configured - MIDI port not initialized\n");
-#ifdef SM_WAVE
if (mpu_base != 0)
if (initialize_smw (mpu_base))
Jazz16_detected = 2;
-#endif
+
sb_dsp_disable_midi ();
}
@@ -1056,37 +1191,29 @@
return 0; /* No SB or ProSonic16 detected */
}
-#endif /* ifdef JAZZ16 */
-
int
sb_dsp_detect (struct address_info *hw_config)
{
sbc_base = hw_config->io_base;
sbc_irq = hw_config->irq;
+ sbc_dma = hw_config->dma;
sb_osp = hw_config->osp;
if (sb_dsp_ok)
return 0; /*
* Already initialized
*/
- dma8 = hw_config->dma;
-
-#ifdef JAZZ16
- dma16 = JAZZ_DMA16;
+ dma8 = dma16 = hw_config->dma;
if (!initialize_ProSonic16 ())
return 0;
-#else
- if (!sb_reset_dsp ())
- return 0;
-#endif
return 1; /*
* Detected
*/
}
-#ifndef EXCLUDE_AUDIO
+#ifdef CONFIG_AUDIO
static struct audio_operations sb_dsp_operations =
{
"SoundBlaster",
@@ -1111,16 +1238,154 @@
#endif
+static void
+ess_init (void) /* ESS1688 Initialization */
+{
+ unsigned char cfg, irq_bits = 0, dma_bits = 0;
+
+ AudioDrive = 1;
+ midi_disabled = 1;
+
+ sb_reset_dsp (); /* Turn on extended mode */
+
+/*
+ * Set IRQ configuration register
+ */
+
+ cfg = 0x50; /* Enable only DMA counter interrupt */
+
+ switch (sbc_irq)
+ {
+ case 2:
+ case 9:
+ irq_bits = 0;
+ break;
+
+ case 5:
+ irq_bits = 1;
+ break;
+
+ case 7:
+ irq_bits = 2;
+ break;
+
+ case 10:
+ irq_bits = 3;
+ break;
+
+ default:
+ irq_bits = 0;
+ cfg = 0x10; /* Disable all interrupts */
+ printk ("\nESS1688: Invalid IRQ %d\n", sbc_irq);
+ }
+
+ if (!ess_write (0xb1, cfg | (irq_bits << 2)))
+ printk ("\nESS1688: Failed to write to IRQ config register\n");
+
+/*
+ * Set DMA configuration register
+ */
+
+ cfg = 0x50; /* Extended mode DMA ebable */
+
+ if (sbc_dma > 3 || sbc_dma < 0 || sbc_dma == 2)
+ {
+ dma_bits = 0;
+ cfg = 0x00; /* Disable all DMA */
+ printk ("\nESS1688: Invalid DMA %d\n", sbc_dma);
+ }
+ else
+ {
+ if (sbc_dma == 3)
+ dma_bits = 3;
+ else
+ dma_bits = sbc_dma + 1;
+ }
+
+ if (!ess_write (0xb2, cfg | (dma_bits << 2)))
+ printk ("\nESS1688: Failed to write to DMA config register\n");
+
+/*
+ * Enable joystick and OPL3
+ */
+
+ cfg = sb_getmixer (0x40);
+ sb_setmixer (0x40, cfg | 0x03);
+}
+
+void
+ess_midi_init (struct address_info *hw_config) /* called from sb16_midi.c */
+{
+ unsigned char cfg, tmp;
+
+ cfg = sb_getmixer (0x40) & 0x03;
+
+ tmp = (hw_config->io_base & 0x0f0) >> 4;
+
+ if (tmp > 3)
+ {
+ sb_setmixer (0x40, cfg);
+ return;
+ }
+
+ cfg |= tmp << 3;
+
+ tmp = 1; /* MPU enabled without interrupts */
+
+ switch (hw_config->irq)
+ {
+ case 9:
+ tmp = 0x4;
+ break;
+ case 5:
+ tmp = 0x5;
+ break;
+ case 7:
+ tmp = 0x6;
+ break;
+ case 10:
+ tmp = 0x7;
+ break;
+ }
+
+ cfg |= tmp << 5;
+
+ if (tmp != 1)
+ {
+ ess_mpu_irq = hw_config->irq;
+
+ if (snd_set_irq_handler (ess_mpu_irq, sbmidiintr, "ES1688 MIDI", sb_osp) < 0)
+ printk ("ES1688: Can't allocate IRQ%d\n", ess_mpu_irq);
+ }
+
+ sb_setmixer (0x40, cfg);
+}
+
+void
+Jazz16_midi_init (struct address_info *hw_config)
+{
+ mpu_base = hw_config->io_base;
+ mpu_irq = hw_config->irq;
+
+ initialize_ProSonic16 ();
+}
+
+void
+Jazz16_set_dma16 (int dma)
+{
+ dma16 = dma;
+
+ initialize_ProSonic16 ();
+}
+
long
sb_dsp_init (long mem_start, struct address_info *hw_config)
{
int i;
+ int ess_major = 0, ess_minor = 0;
-#ifndef EXCLUDE_SBPRO
int mixer_type = 0;
-#endif
-
sb_osp = hw_config->osp;
sbc_major = sbc_minor = 0;
sb_dsp_command (0xe1); /*
@@ -1158,7 +1423,6 @@
if (sbc_major == 3 && sbc_minor == 1)
{
- int ess_major = 0, ess_minor = 0;
/*
* Try to detect ESS chips.
@@ -1183,28 +1447,12 @@
}
}
}
-
- if (ess_major == 0x48 && (ess_minor & 0xf0) == 0x80)
- printk ("Hmm... Could this be an ESS488 based card (rev %d)\n",
- ess_minor & 0x0f);
- else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80)
- printk ("Hmm... Could this be an ESS688 based card (rev %d)\n",
- ess_minor & 0x0f);
}
if (snd_set_irq_handler (sbc_irq, sbintr, "SoundBlaster", sb_osp) < 0)
printk ("sb_dsp: Can't allocate IRQ\n");;
-#ifndef EXCLUDE_SBPRO
- if (sbc_major >= 3)
- mixer_type = sb_mixer_init (sbc_major);
-#else
- if (sbc_major >= 3)
- printk ("\n\n\n\nNOTE! SB Pro support is required with your soundcard!\n\n\n");
-#endif
-
-
-#ifndef EXCLUDE_AUDIO
+#ifdef CONFIG_AUDIO
if (sbc_major >= 3)
{
if (Jazz16_detected)
@@ -1228,6 +1476,20 @@
{
sprintf (sb_dsp_operations.name, "SoundBlaster 16 %d.%d", sbc_major, sbc_minor);
}
+ else if (ess_major != 0)
+ {
+ if (ess_major == 0x48 && (ess_minor & 0xf0) == 0x80)
+ sprintf (sb_dsp_operations.name, "ESS ES488 AudioDrive (rev %d)",
+ ess_minor & 0x0f);
+ else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80)
+ {
+ sprintf (sb_dsp_operations.name,
+ "ESS ES1688 AudioDrive (rev %d)",
+ ess_minor & 0x0f);
+ sb_dsp_operations.format_mask |= AFMT_S16_LE;
+ ess_init ();
+ }
+ }
else
{
sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", sbc_major, sbc_minor);
@@ -1238,23 +1500,26 @@
sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", sbc_major, sbc_minor);
}
- printk (" <%s>", sb_dsp_operations.name);
+ conf_printf (sb_dsp_operations.name, hw_config);
-#if !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SBPRO)
- if (!sb16) /*
- * There is a better driver for SB16
- */
-#endif
+ if (sbc_major >= 3)
+ mixer_type = sb_mixer_init (sbc_major);
+
+ if (!sb16)
if (num_audiodevs < MAX_AUDIO_DEV)
{
audio_devs[my_dev = num_audiodevs++] = &sb_dsp_operations;
+
+ if (AudioDrive)
+ audio_devs[my_dev]->flags |= DMA_AUTOMODE;
+
audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
dma8 = audio_devs[my_dev]->dmachan1 = hw_config->dma;
audio_devs[my_dev]->dmachan2 = -1;
- if (sound_alloc_dma (hw_config->dma, "soundblaster"))
+ if (sound_alloc_dma (hw_config->dma, "SoundBlaster"))
printk ("sb_dsp.c: Can't allocate DMA channel\n");
-#ifdef JAZZ16
- /* Allocate 16 bit dma
+
+ /* Allocate 16 bit dma (Jazz16)
*/
if (Jazz16_detected != 0)
if (dma16 != dma8)
@@ -1264,15 +1529,14 @@
printk ("Jazz16: Can't allocate 16 bit DMA channel\n");
}
}
-#endif
}
else
printk ("SB: Too many DSP devices available\n");
#else
- printk (" <SoundBlaster (configured without audio support)>");
+ conf_printf ("SoundBlaster (configured without audio support)", hw_config);
#endif
-#ifndef EXCLUDE_MIDI
+#ifdef CONFIG_MIDI
if (!midi_disabled && !sb16) /*
* Midi don't work in the SB emulation mode *
* of PAS, SB16 has better midi interface
@@ -1288,16 +1552,20 @@
sb_dsp_unload (void)
{
sound_free_dma (dma8);
-#ifdef JAZZ16
- /* Allocate 16 bit dma
+
+ /* Free 16 bit dma (Jazz16)
*/
if (Jazz16_detected != 0)
if (dma16 != dma8)
{
sound_free_dma (dma16);
}
-#endif
snd_release_irq (sbc_irq);
+
+ if (AudioDrive && ess_mpu_irq)
+ {
+ snd_release_irq (ess_mpu_irq);
+ }
}
void
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this