summaryrefslogtreecommitdiffstats
path: root/drivers/sound
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sound')
-rw-r--r--drivers/sound/Config.in12
-rw-r--r--drivers/sound/Defines12
-rw-r--r--drivers/sound/Makefile56
-rw-r--r--drivers/sound/ad1848.c98
-rw-r--r--drivers/sound/ad1848_mixer.h28
-rw-r--r--drivers/sound/adlib_card.c15
-rw-r--r--drivers/sound/audio.c23
-rw-r--r--drivers/sound/cs4232.c2
-rw-r--r--drivers/sound/dev_table.c7
-rw-r--r--drivers/sound/dev_table.h7
-rw-r--r--drivers/sound/dmabuf.c21
-rw-r--r--drivers/sound/dmasound.c5704
-rw-r--r--drivers/sound/gus_card.c43
-rw-r--r--drivers/sound/gus_wave.c63
-rw-r--r--drivers/sound/local.h.master2
-rw-r--r--drivers/sound/mad16.c942
-rw-r--r--drivers/sound/maui.c8
-rw-r--r--drivers/sound/midibuf.c1
-rw-r--r--drivers/sound/opl3sa.c295
-rw-r--r--drivers/sound/os.h3
-rw-r--r--drivers/sound/pas2_card.c13
-rw-r--r--drivers/sound/pss.c409
-rw-r--r--drivers/sound/sb.h2
-rw-r--r--drivers/sound/sb_audio.c706
-rw-r--r--drivers/sound/sb_card.c51
-rw-r--r--drivers/sound/sb_common.c84
-rw-r--r--drivers/sound/sb_midi.c116
-rw-r--r--drivers/sound/sb_mixer.c478
-rw-r--r--drivers/sound/sb_mixer.h42
-rw-r--r--drivers/sound/sequencer.c79
-rw-r--r--drivers/sound/softoss.c1183
-rw-r--r--drivers/sound/softoss_rs.c177
-rw-r--r--drivers/sound/sound_calls.h18
-rw-r--r--drivers/sound/sound_firmware.c12
-rw-r--r--drivers/sound/sound_syms.c24
-rw-r--r--drivers/sound/soundcard.c75
-rw-r--r--drivers/sound/trix.c433
-rw-r--r--drivers/sound/uart401.c21
-rw-r--r--drivers/sound/uart6850.c2
-rw-r--r--drivers/sound/vidc.c81
-rw-r--r--drivers/sound/vidc.h68
-rw-r--r--drivers/sound/vidc_audio.c320
-rw-r--r--drivers/sound/vidc_fill.S184
-rw-r--r--drivers/sound/vidc_mixer.c149
-rw-r--r--drivers/sound/vidc_synth.c89
45 files changed, 6552 insertions, 5606 deletions
diff --git a/drivers/sound/Config.in b/drivers/sound/Config.in
index d4678da82..8f1d2bec7 100644
--- a/drivers/sound/Config.in
+++ b/drivers/sound/Config.in
@@ -2,12 +2,11 @@ dep_tristate 'ProAudioSpectrum 16 support' CONFIG_PAS $CONFIG_SOUND
if [ "$CONFIG_PAS" = "y" ]; then
int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' CONFIG_PAS_IRQ 10
int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' CONFIG_PAS_DMA 3
+ bool 'Enable PAS16 joystick port' CONFIG_PAS_JOYSTICK
fi
dep_tristate '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SB $CONFIG_SOUND
if [ "$CONFIG_SB" = "y" ]; then
- bool 'Is the card a Soundman Games ?' CONFIG_SM_GAMES
- bool 'Are you using the IBM Mwave "emulation" of SB ?' CONFIG_SB_MWAVE
hex 'I/O base for SB Check from manual of the card' CONFIG_SB_BASE 220
int 'Sound Blaster IRQ Check from manual of the card' CONFIG_SB_IRQ 7
int 'Sound Blaster DMA 0, 1 or 3' CONFIG_SB_DMA 1
@@ -43,7 +42,7 @@ if [ "$CONFIG_MPU401" = "y" ]; then
int 'MPU401 IRQ Check from manual of the card' CONFIG_MPU_IRQ 9
fi
-dep_tristate 'PSS (ECHO-ADI2111) support' CONFIG_PSS $CONFIG_SOUND
+dep_tristate 'PSS (AD1848, ADSP-2115, ESC614) support' CONFIG_PSS $CONFIG_SOUND
if [ "$CONFIG_PSS" = "y" ]; then
hex 'PSS I/O base 220 or 240' CONFIG_PSS_BASE 220
hex 'PSS audio I/O base 530, 604, E80 or F40' CONFIG_PSS_MSS_BASE 530
@@ -56,6 +55,9 @@ if [ "$CONFIG_PSS" = "y" ]; then
string ' Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE
fi
fi
+if [ "$CONFIG_PSS" = "m" ] || [ "$CONFIG_PSS" = "y" ]; then
+ bool ' Enable PSS mixer (Beethoven ADSP-16 and other compatibile)' CONFIG_PSS_MIXER
+fi
dep_tristate 'Microsoft Sound System support' CONFIG_MSS $CONFIG_SOUND
if [ "$CONFIG_MSS" = "y" ]; then
@@ -92,6 +94,7 @@ if [ "$CONFIG_TRIX" = "y" ]; then
fi
dep_tristate 'Support for OPTi MAD16 and/or Mozart based cards' CONFIG_MAD16 $CONFIG_SOUND
+dep_tristate 'Support MIDI in older MAD16 based cards (requires SB)' CONFIG_MAD16_OLDCARD $CONFIG_MAD16
if [ "$CONFIG_MAD16" = "y" ]; then
hex 'MAD16 audio I/O base 530, 604, E80 or F40' CONFIG_MAD16_BASE 530
int 'MAD16 audio IRQ 7, 9, 10 or 11' CONFIG_MAD16_IRQ 11
@@ -213,3 +216,6 @@ if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
fi
fi
+if [ "$CONFIG_ARM" = "y" ]; then
+ bool 'VIDC 16-bit sound' CONFIG_VIDC_SOUND
+fi
diff --git a/drivers/sound/Defines b/drivers/sound/Defines
index 6b9ef6bb6..b2aef2dfb 100644
--- a/drivers/sound/Defines
+++ b/drivers/sound/Defines
@@ -231,6 +231,12 @@ CONFIG_SEQUENCER=y
endif
endif
+ifdef CONFIG_VIDC_SOUND
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
ifdef CONFIG_PAS
ifneq ($(CONFIG_AUDIO),Y)
CONFIG_AUDIO=y
@@ -309,6 +315,12 @@ CONFIG_AUDIO=y
endif
endif
+ifdef CONFIG_VIDC_SOUND
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
ifdef CONFIG_PAS
ifneq ($(CONFIG_MIDI),Y)
CONFIG_MIDI=y
diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile
index 6b09e336b..1f71965f2 100644
--- a/drivers/sound/Makefile
+++ b/drivers/sound/Makefile
@@ -117,6 +117,22 @@ else
endif
endif
+ifeq ($(CONFIG_MPU401),y)
+LX_OBJS += mpu401.o
+else
+ ifeq ($(CONFIG_MPU401),m)
+ MX_OBJS += mpu401.o
+ else
+ ifeq ($(CONFIG_MPU_EMU),y)
+ LX_OBJS += mpu401.o
+ else
+ ifeq ($(CONFIG_MPU_EMU),m)
+ MX_OBJS += mpu401.o
+ endif
+ endif
+ endif
+endif
+
ifeq ($(CONFIG_UART401),y)
LX_OBJS += uart401.o
else
@@ -143,31 +159,9 @@ endif
ifeq ($(CONFIG_SSCAPE),y)
L_OBJS += sscape.o
-LX_OBJS += ad1848.o
-CONFIG_MPU401 = y
else
ifeq ($(CONFIG_SSCAPE),m)
M_OBJS += sscape.o
- MX_OBJS += ad1848.o
- ifneq ($(CONFIG_MPU401),y)
- CONFIG_MPU401 = m
- endif
- endif
-endif
-
-ifeq ($(CONFIG_MPU401),y)
-LX_OBJS += mpu401.o
-else
- ifeq ($(CONFIG_MPU401),m)
- MX_OBJS += mpu401.o
- else
- ifeq ($(CONFIG_MPU_EMU),y)
- LX_OBJS += mpu401.o
- else
- ifeq ($(CONFIG_MPU_EMU),m)
- MX_OBJS += mpu401.o
- endif
- endif
endif
endif
@@ -230,27 +224,31 @@ else
endif
endif
+ifeq ($(CONFIG_VIDC_SOUND),y)
+ L_OBJS += vidc.o vidc_audio.o vidc_mixer.o vidc_synth.o vidc_fill.o
+endif
+
include $(TOPDIR)/Rules.make
softoss2.o: softoss.o softoss_rs.o
- ld -r -o softoss2.o softoss.o softoss_rs.o
+ $(LD) -r -o softoss2.o softoss.o softoss_rs.o
pas2.o: pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
- ld -r -o pas2.o pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
+ $(LD) -r -o pas2.o pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
sb.o: sb_audio.o sb_card.o sb_common.o sb_midi.o sb_mixer.o
- ld -r -o sb.o sb_audio.o sb_card.o sb_common.o sb_midi.o sb_mixer.o
+ $(LD) -r -o sb.o sb_audio.o sb_card.o sb_common.o sb_midi.o sb_mixer.o
lowlevel/lowlevel.o:
cd lowlevel; make
-sound.o: soundcard.o dev_table.o audio.o dmabuf.o sequencer.o sys_timer.o sound_timer.o lowlevel/lowlevel.o midi_synth.o midibuf.o sound_firmware.o
- ld -r -o sound.o soundcard.o dev_table.o audio.o dmabuf.o \
+sound.o: soundcard.o dev_table.o audio.o dmabuf.o sequencer.o sys_timer.o sound_timer.o lowlevel/lowlevel.o midi_synth.o midibuf.o sound_firmware.o sound_syms.o
+ $(LD) -r -o sound.o soundcard.o dev_table.o audio.o dmabuf.o \
sequencer.o sys_timer.o sound_timer.o lowlevel/lowlevel.o \
- midi_synth.o midibuf.o sound_firmware.o
+ midi_synth.o midibuf.o sound_firmware.o sound_syms.o
gus.o: gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
- ld -r -o gus.o gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
+ $(LD) -r -o gus.o gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
# Firmware files that need translation
#
diff --git a/drivers/sound/ad1848.c b/drivers/sound/ad1848.c
index d839ed208..2bf9f2c52 100644
--- a/drivers/sound/ad1848.c
+++ b/drivers/sound/ad1848.c
@@ -12,16 +12,16 @@
*
* CS4232 is a PnP audio chip which contains a CS4231A (and SB, MPU).
* CS4232A is an improved version of CS4232.
- */
-
-/*
+ *
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
- */
-/*
+ *
+ *
* Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
* general sleep/wakeup clean up.
* Alan Cox : reformatted. Fixed SMP bugs. Moved to kernel alloc/free
@@ -84,7 +84,6 @@ typedef struct
int irq_ok;
mixer_ents *mix_devices;
int mixer_output_port;
- int c930_password_port;
} ad1848_info;
typedef struct ad1848_port_info
@@ -561,6 +560,12 @@ static int ad1848_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
val = devc->mixer_output_port;
return put_user(val, (int *)arg);
}
+ if (cmd == SOUND_MIXER_PRIVATE2)
+ {
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ return(ad1848_control(AD1848_MIXER_REROUTE, val));
+ }
if (((cmd >> 8) & 0xff) == 'M')
{
if (_SIOC_DIR(cmd) & _SIOC_WRITE)
@@ -1409,7 +1414,6 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp)
devc->chip_name = devc->name = "AD1848";
devc->model = MD_1848; /* AD1848 or CS4248 */
devc->levels = NULL;
- devc->c930_password_port = 0;
devc->debug_flag = 0;
/*
@@ -1789,11 +1793,15 @@ int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capt
if (request_irq(devc->irq, adintr, 0, devc->name, (void *)my_dev) < 0)
{
printk(KERN_WARNING "ad1848: Unable to allocate IRQ\n");
+ /* Don't free it either then.. */
+ devc->irq = 0;
}
if (devc->model != MD_1848 && devc->model != MD_C930)
{
+#ifndef __SMP__
int x;
unsigned char tmp = ad_read(devc, 16);
+#endif
devc->timer_ticks = 0;
@@ -1843,16 +1851,15 @@ int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capt
{
audio_devs[my_dev]->mixer_dev = e;
}
- MOD_INC_USE_COUNT;
return my_dev;
}
-void ad1848_control(int cmd, int arg)
+int ad1848_control(int cmd, int arg)
{
ad1848_info *devc;
if (nr_ad1848_devs < 1)
- return;
+ return -ENODEV;
devc = &adev_info[nr_ad1848_devs - 1];
@@ -1860,7 +1867,7 @@ void ad1848_control(int cmd, int arg)
{
case AD1848_SET_XTAL: /* Change clock frequency of AD1845 (only ) */
if (devc->model != MD_1845)
- return;
+ return -EINVAL;
ad_enter_MCE(devc);
ad_write(devc, 29, (ad_read(devc, 29) & 0x1f) | (arg << 5));
ad_leave_MCE(devc);
@@ -1871,32 +1878,37 @@ void ad1848_control(int cmd, int arg)
int o = (arg >> 8) & 0xff;
int n = arg & 0xff;
+ if (o < 0 || o >= SOUND_MIXER_NRDEVICES)
+ return -EINVAL;
+
+ if (!(devc->supported_devices & (1 << o)) &&
+ !(devc->supported_rec_devices & (1 << o)))
+ return -EINVAL;
+
if (n == SOUND_MIXER_NONE)
{ /* Just hide this control */
ad1848_mixer_set(devc, o, 0); /* Shut up it */
devc->supported_devices &= ~(1 << o);
devc->supported_rec_devices &= ~(1 << o);
- return;
+ break;
}
- /* Make the mixer control identified by o to appear as n */
- if (o < 0 || o > SOUND_MIXER_NRDEVICES)
- return;
- if (n < 0 || n > SOUND_MIXER_NRDEVICES)
- return;
- if (!(devc->supported_devices & (1 << o)))
- return; /* Not supported */
+ /* Make the mixer control identified by o to appear as n */
+ if (n < 0 || n >= SOUND_MIXER_NRDEVICES)
+ return -EINVAL;
devc->mixer_reroute[n] = o; /* Rename the control */
- devc->supported_devices &= ~(1 << o);
- devc->supported_devices |= (1 << n);
+ if (devc->supported_devices & (1 << o))
+ devc->supported_devices |= (1 << n);
if (devc->supported_rec_devices & (1 << o))
devc->supported_rec_devices |= (1 << n);
+
+ devc->supported_devices &= ~(1 << o);
devc->supported_rec_devices &= ~(1 << o);
}
break;
}
- return;
+ return 0;
}
void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int share_dma)
@@ -1932,7 +1944,6 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int
}
else
printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base);
- MOD_DEC_USE_COUNT;
}
void adintr(int irq, void *dev_id, struct pt_regs *dummy)
@@ -1965,37 +1976,22 @@ interrupt_again: /* Jump back here if int status doesn't reset */
save_flags(flags);
cli();
- alt_stat = 0;
-
- if (devc->c930_password_port)
- outb((0xe4), devc->c930_password_port); /* Password */
+ /* 0xe0e is C930 address port
+ * 0xe0f is C930 data port
+ */
outb(11, 0xe0e);
c930_stat = inb(0xe0f);
+ outb((~c930_stat), 0xe0f);
- if (c930_stat & 0x04)
- alt_stat |= 0x10; /* Playback intr */
- if (c930_stat & 0x08)
- alt_stat |= 0x20; /* Playback intr */
restore_flags(flags);
- } else if (devc->model != MD_1848)
- alt_stat = ad_read(devc, 24);
-
- /* Acknowledge the intr before proceeding */
- if (devc->model == MD_C930)
- { /* 82C930 has interrupt status register in MAD16 register MC11 */
- unsigned long flags;
-
- save_flags(flags);
- cli();
- if (devc->c930_password_port)
- outb((0xe4), devc->c930_password_port); /* Password */
- outb((11), 0xe0e);
- outb((~c930_stat), 0xe0f);
- restore_flags(flags);
+ alt_stat = (c930_stat << 2) & 0x30;
}
else if (devc->model != MD_1848)
+ {
+ alt_stat = ad_read(devc, 24);
ad_write(devc, 24, ad_read(devc, 24) & ~alt_stat); /* Selective ack */
+ }
if (devc->open_mode & OPEN_READ && devc->audio_mode & PCM_ENABLE_INPUT && alt_stat & 0x20)
{
@@ -2550,11 +2546,10 @@ static int loaded = 0;
struct address_info hw_config;
-
int init_module(void)
{
printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n");
- if(io!=-1)
+ if(io != -1)
{
if(irq == -1 || dma == -1)
{
@@ -2581,12 +2576,5 @@ void cleanup_module(void)
if(loaded)
unload_ms_sound(&hw_config);
}
-
-#else
-
-void export_ad1848_syms(void)
-{
-}
-
#endif
#endif
diff --git a/drivers/sound/ad1848_mixer.h b/drivers/sound/ad1848_mixer.h
index f6ea1c006..0cf54e710 100644
--- a/drivers/sound/ad1848_mixer.h
+++ b/drivers/sound/ad1848_mixer.h
@@ -1,6 +1,6 @@
/*
* sound/ad1848_mixer.h
- *
+ *
* Definitions for the mixer of AD1848 and compatible codecs.
*/
@@ -77,7 +77,7 @@ typedef mixer_ent mixer_ents[2];
*/
#define MIX_ENT(name, reg_l, pola_l, pos_l, len_l, reg_r, pola_r, pos_r, len_r, mute_bit) \
- {{reg_l, pola_l, pos_l, len_l}, {reg_r, pola_r, pos_r, len_r, mute_bit}}
+ {{reg_l, pola_l, pos_l, len_l, mute_bit}, {reg_r, pola_r, pos_r, len_r, mute_bit}}
static mixer_ents ad1848_mix_devices[32] = {
MIX_ENT(SOUND_MIXER_VOLUME, 27, 1, 0, 4, 29, 1, 0, 4, 8),
@@ -88,13 +88,13 @@ MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7),
MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7),
MIX_ENT(SOUND_MIXER_MIC, 0, 0, 5, 1, 1, 0, 5, 1, 8),
-MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7),
+MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7),
MIX_ENT(SOUND_MIXER_IMIX, 13, 1, 2, 6, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8),
MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8),
-MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7),
+MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7),
MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5, 7),
MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5, 7)
};
@@ -108,13 +108,13 @@ MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7),
MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7),
MIX_ENT(SOUND_MIXER_MIC, 0, 0, 5, 1, 1, 0, 5, 1, 8),
-MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7),
+MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5, 7),
MIX_ENT(SOUND_MIXER_IMIX, 16, 1, 0, 5, 17, 1, 0, 5, 8),
MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8),
MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8),
-MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7),
+MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5, 7),
MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5, 7),
MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5, 7)
};
@@ -125,21 +125,21 @@ MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5, 7)
* MIC is level of mic monitoring direct to output. Same for CD, LINE, etc.
*/
static mixer_ents c930_mix_devices[32] = {
-MIX_ENT(SOUND_MIXER_VOLUME, 22, 1, 0, 5, 23, 1, 0, 5, 7),
+MIX_ENT(SOUND_MIXER_VOLUME, 22, 1, 1, 5, 23, 1, 1, 5, 7),
MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0, 8),
-MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5, 7),
-MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6, 7),
-MIX_ENT(SOUND_MIXER_SPEAKER, 22, 1, 0, 5, 23, 1, 0, 5, 8),
+MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 1, 4, 5, 1, 1, 4, 7),
+MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 5, 7, 1, 0, 5, 7),
+MIX_ENT(SOUND_MIXER_SPEAKER, 22, 1, 1, 5, 23, 1, 1, 5, 7),
MIX_ENT(SOUND_MIXER_LINE, 18, 1, 1, 4, 19, 1, 1, 4, 7),
-MIX_ENT(SOUND_MIXER_MIC, 20, 1, 0, 4, 21, 1, 0, 4, 8),
-MIX_ENT(SOUND_MIXER_CD, 2, 1, 1, 4, 3, 1, 1, 4, 7),
-MIX_ENT(SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0, 8),
+MIX_ENT(SOUND_MIXER_MIC, 20, 1, 1, 4, 21, 1, 1, 4, 7),
+MIX_ENT(SOUND_MIXER_CD, 2, 1, 1, 4, 3, 1, 1, 4, 7),
+MIX_ENT(SOUND_MIXER_IMIX, 0, 0, 0, 0, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0, 8),
MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4, 8),
MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0, 8),
-MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 1, 4, 3, 1, 1, 4, 7),
+MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 1, 4, 3, 1, 1, 4, 7),
MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 1, 4, 5, 1, 1, 4, 7),
MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 1, 4, 19, 1, 1, 4, 7)
};
diff --git a/drivers/sound/adlib_card.c b/drivers/sound/adlib_card.c
index 6d7dbb7b3..b9b16cd8e 100644
--- a/drivers/sound/adlib_card.c
+++ b/drivers/sound/adlib_card.c
@@ -2,19 +2,17 @@
* sound/adlib_card.c
*
* Detection routine for the AdLib card.
- */
-
-/*
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
-#include <linux/config.h>
-#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/module.h>
#include "sound_config.h"
#include "soundmodule.h"
@@ -28,7 +26,8 @@ void attach_adlib_card(struct address_info *hw_config)
int probe_adlib(struct address_info *hw_config)
{
- if (check_region(hw_config->io_base, 4)) {
+ if (check_region(hw_config->io_base, 4))
+ {
DDB(printk("opl3.c: I/O port %x already in use\n", hw_config->io_base));
return 0;
}
@@ -46,12 +45,14 @@ void unload_adlib(struct address_info *hw_config)
int io = -1;
MODULE_PARM(io, "i");
+EXPORT_NO_SYMBOLS;
+
struct address_info cfg;
int init_module(void)
{
if (io == -1) {
- printk("adlib: must specify I/O address.\n");
+ printk(KERN_ERR "adlib: must specify I/O address.\n");
return -EINVAL;
}
cfg.io_base = io;
diff --git a/drivers/sound/audio.c b/drivers/sound/audio.c
index 9c9ccf095..905bd83e7 100644
--- a/drivers/sound/audio.c
+++ b/drivers/sound/audio.c
@@ -21,6 +21,7 @@
#include <linux/config.h>
#include <linux/stddef.h>
+#include <linux/kmod.h>
#include "sound_config.h"
@@ -164,8 +165,6 @@ void audio_release(int dev, struct file *file)
DMAbuf_release(dev, mode);
}
-#if defined(NO_INLINE_ASM) || !defined(i386)
-
static void translate_bytes(const unsigned char *table, unsigned char *buff, int n)
{
unsigned long i;
@@ -177,24 +176,6 @@ static void translate_bytes(const unsigned char *table, unsigned char *buff, int
buff[i] = table[buff[i]];
}
-#else
-extern inline void
-translate_bytes(const void *table, void *buff, int n)
-{
- if (n > 0)
- {
- __asm__("cld\n"
- "1:\tlodsb\n\t"
- "xlatb\n\t"
- "stosb\n\t"
- "loop 1b\n\t":
- : "b"((long) table), "c"(n), "D"((long) buff), "S"((long) buff)
- : "bx", "cx", "di", "si", "ax");
- }
-}
-
-#endif
-
int audio_write(int dev, struct file *file, const char *buf, int count)
{
int c, p, l, buf_size;
@@ -827,8 +808,10 @@ int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
DMAbuf_launch_output(dev, dmap_out);
}
audio_devs[dev]->enable_bits = bits;
+#if 0
if (changed && audio_devs[dev]->d->trigger)
audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
+#endif
restore_flags(flags);
/* Falls through... */
diff --git a/drivers/sound/cs4232.c b/drivers/sound/cs4232.c
index fdb5b738c..571a3372b 100644
--- a/drivers/sound/cs4232.c
+++ b/drivers/sound/cs4232.c
@@ -301,6 +301,8 @@ MODULE_PARM(irq,"i");
MODULE_PARM(dma,"i");
MODULE_PARM(dma2,"i");
+EXPORT_NO_SYMBOLS;
+
struct address_info cfg;
/*
diff --git a/drivers/sound/dev_table.c b/drivers/sound/dev_table.c
index 7f3957bfd..155cf529d 100644
--- a/drivers/sound/dev_table.c
+++ b/drivers/sound/dev_table.c
@@ -18,7 +18,6 @@
#define _DEV_TABLE_C_
#include "sound_config.h"
-int sb_be_quiet = 0;
int softoss_dev = 0;
int sound_started = 0;
int sndtable_get_cardcount(void);
@@ -148,6 +147,9 @@ void sound_unload_drivers(void)
}
}
+ for (i=0;i<num_audiodevs;i++)
+ DMAbuf_deinit(i);
+
if (trace_init)
printk(KERN_DEBUG "Sound unload complete\n");
}
@@ -418,13 +420,11 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
return -(EBUSY);
}
d = (struct audio_driver *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_driver)));
- sound_mem_sizes[sound_nblocks] = sizeof(struct audio_driver);
if (sound_nblocks < 1024)
sound_nblocks++;
op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_operations)));
- sound_mem_sizes[sound_nblocks] = sizeof(struct audio_operations);
if (sound_nblocks < 1024)
sound_nblocks++;
@@ -490,7 +490,6 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
until you unload sound! */
op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct mixer_operations)));
- sound_mem_sizes[sound_nblocks] = sizeof(struct mixer_operations);
if (sound_nblocks < 1024)
sound_nblocks++;
diff --git a/drivers/sound/dev_table.h b/drivers/sound/dev_table.h
index 878cb2971..b6e273d40 100644
--- a/drivers/sound/dev_table.h
+++ b/drivers/sound/dev_table.h
@@ -23,6 +23,7 @@
*/
#define SNDCARD_DESKPROXL 27 /* Compaq Deskpro XL */
+#define SNDCARD_VIDC 28 /* ARMs VIDC */
#define SNDCARD_SBPNP 29
#define SNDCARD_OPL3SA1 38
#define SNDCARD_OPL3SA1_SB 39
@@ -464,6 +465,9 @@ struct driver_info sound_drivers[] =
#if defined(CONFIG_VMIDI) && defined(CONFIG_MIDI) && !defined(CONFIG_VMIDI_MODULE)
{"VMIDI", 0, SNDCARD_VMIDI,"Loopback MIDI Device", attach_v_midi, probe_v_midi, unload_v_midi},
#endif
+#ifdef CONFIG_VIDC_SOUND
+ {"VIDC", 0, SNDCARD_VIDC, "ARM VIDC 16-bit D/A", attach_vidc, probe_vidc, unload_vidc },
+#endif
{NULL, 0, 0, "*?*", NULL, NULL, NULL}
};
@@ -612,6 +616,9 @@ struct card_info snd_installed_cards[] =
{SNDCARD_VMIDI, {0, 0, 0, -1}, SND_DEFAULT_ENABLE},
#endif
+#ifdef CONFIG_VIDC_SOUND
+ { SNDCARD_VIDC, {0, 0, 0, 0}, SND_DEFAULT_ENABLE },
+#endif
{0, {0}, 0}
};
diff --git a/drivers/sound/dmabuf.c b/drivers/sound/dmabuf.c
index db6a02d05..5066cfe5a 100644
--- a/drivers/sound/dmabuf.c
+++ b/drivers/sound/dmabuf.c
@@ -104,7 +104,7 @@ static int sound_alloc_dmap(struct dma_buffparms *dmap)
dmap->raw_buf_phys = virt_to_bus(start_addr);
for (i = MAP_NR(start_addr); i <= MAP_NR(end_addr); i++)
- set_bit(PG_reserved, &mem_map[i].flags);
+ set_bit(PG_reserved, &mem_map[i].flags);;
return 0;
}
@@ -115,6 +115,8 @@ static void sound_free_dmap(struct dma_buffparms *dmap)
if (dmap->raw_buf == NULL)
return;
+ if (dmap->mapping_flags & DMA_MAP_MAPPED)
+ return; /* Don't free mmapped buffer. Will use it next time */
for (sz = 0, size = PAGE_SIZE; size < dmap->buffsize; sz++, size <<= 1);
start_addr = (unsigned long) dmap->raw_buf;
@@ -125,8 +127,6 @@ static void sound_free_dmap(struct dma_buffparms *dmap)
free_pages((unsigned long) dmap->raw_buf, sz);
dmap->raw_buf = NULL;
- /* Remember the buffer is deleted so we dont Oops later */
- dmap->fragment_size = 0;
}
@@ -206,7 +206,6 @@ static void close_dmap(struct audio_operations *adev, struct dma_buffparms *dmap
dmap->dma_mode = DMODE_NONE;
dmap->flags &= ~DMA_BUSY;
disable_dma(dmap->dma);
- sound_free_dmap(dmap);
}
@@ -1212,4 +1211,18 @@ unsigned int DMAbuf_poll(struct file * file, int dev, poll_table *wait)
return poll_input(file, dev, wait) | poll_output(file, dev, wait);
}
+void DMAbuf_deinit(int dev)
+{
+ struct audio_operations *adev = audio_devs[dev];
+ /* This routine is called when driver is being unloaded */
+ if (!adev)
+ return;
+#ifdef RUNTIME_DMA_ALLOC
+ sound_free_dmap(adev->dmap_out);
+
+ if (adev->flags & DMA_DUPLEX)
+ sound_free_dmap(adev->dmap_in);
+#endif
+}
+
#endif
diff --git a/drivers/sound/dmasound.c b/drivers/sound/dmasound.c
index 0d4c73c1f..7805bed43 100644
--- a/drivers/sound/dmasound.c
+++ b/drivers/sound/dmasound.c
@@ -3,76 +3,76 @@
/*
- OSS/Free compatible Atari TT/Falcon and Amiga DMA sound driver for Linux/m68k
+OSS/Free compatible Atari TT/Falcon and Amiga DMA sound driver for Linux/m68k
- (c) 1995 by Michael Schlueter & Michael Marte
+(c) 1995 by Michael Schlueter & Michael Marte
- Michael Schlueter (michael@duck.syd.de) did the basic structure of the VFS
- interface and the u-law to signed byte conversion.
+Michael Schlueter (michael@duck.syd.de) did the basic structure of the VFS
+interface and the u-law to signed byte conversion.
- Michael Marte (marte@informatik.uni-muenchen.de) did the sound queue,
- /dev/mixer, /dev/sndstat and complemented the VFS interface. He would like
- to thank:
- Michael Schlueter for initial ideas and documentation on the MFP and
- the DMA sound hardware.
- Therapy? for their CD 'Troublegum' which really made me rock.
+Michael Marte (marte@informatik.uni-muenchen.de) did the sound queue,
+/dev/mixer, /dev/sndstat and complemented the VFS interface. He would like
+to thank:
+Michael Schlueter for initial ideas and documentation on the MFP and
+the DMA sound hardware.
+Therapy? for their CD 'Troublegum' which really made me rock.
- /dev/sndstat is based on code by Hannu Savolainen, the author of the
- VoxWare family of drivers.
+/dev/sndstat is based on code by Hannu Savolainen, the author of the
+VoxWare family of drivers.
- This file is subject to the terms and conditions of the GNU General Public
- License. See the file COPYING in the main directory of this archive
- for more details.
+This file is subject to the terms and conditions of the GNU General Public
+License. See the file COPYING in the main directory of this archive
+for more details.
- History:
- 1995/8/25 first release
+History:
+1995/8/25 first release
- 1995/9/02 ++roman: fixed atari_stram_alloc() call, the timer programming
- and several race conditions
+1995/9/02 ++roman: fixed atari_stram_alloc() call, the timer programming
+ and several race conditions
- 1995/9/14 ++roman: After some discussion with Michael Schlueter, revised
- the interrupt disabling
- Slightly speeded up U8->S8 translation by using long
- operations where possible
- Added 4:3 interpolation for /dev/audio
+1995/9/14 ++roman: After some discussion with Michael Schlueter, revised
+ the interrupt disabling
+ Slightly speeded up U8->S8 translation by using long
+ operations where possible
+ Added 4:3 interpolation for /dev/audio
- 1995/9/20 ++TeSche: Fixed a bug in sq_write and changed /dev/audio
- converting to play at 12517Hz instead of 6258Hz.
+1995/9/20 ++TeSche: Fixed a bug in sq_write and changed /dev/audio
+ converting to play at 12517Hz instead of 6258Hz.
- 1995/9/23 ++TeSche: Changed sq_interrupt() and sq_play() to pre-program
- the DMA for another frame while there's still one
- running. This allows the IRQ response to be
- arbitrarily delayed and playing will still continue.
+1995/9/23 ++TeSche: Changed sq_interrupt() and sq_play() to pre-program
+ the DMA for another frame while there's still one
+ running. This allows the IRQ response to be
+ arbitrarily delayed and playing will still continue.
- 1995/10/14 ++Guenther_Kelleter@ac3.maus.de, ++TeSche: better support for
- Falcon audio (the Falcon doesn't raise an IRQ at the
- end of a frame, but at the beginning instead!). uses
- 'if (codec_dma)' in lots of places to simply switch
- between Falcon and TT code.
+1995/10/14 ++Guenther_Kelleter@ac3.maus.de, ++TeSche: better support for
+ Falcon audio (the Falcon doesn't raise an IRQ at the
+ end of a frame, but at the beginning instead!). uses
+ 'if (codec_dma)' in lots of places to simply switch
+ between Falcon and TT code.
- 1995/11/06 ++TeSche: started introducing a hardware abstraction scheme
- (may perhaps also serve for Amigas?), can now play
- samples at almost all frequencies by means of a more
- generalized expand routine, takes a good deal of care
- to cut data only at sample sizes, buffer size is now
- a kernel runtime option, implemented fsync() & several
- minor improvements
- ++Guenther: useful hints and bug fixes, cross-checked it for
- Falcons
+1995/11/06 ++TeSche: started introducing a hardware abstraction scheme
+ (may perhaps also serve for Amigas?), can now play
+ samples at almost all frequencies by means of a more
+ generalized expand routine, takes a good deal of care
+ to cut data only at sample sizes, buffer size is now
+ a kernel runtime option, implemented fsync() & several
+ minor improvements
+ ++Guenther: useful hints and bug fixes, cross-checked it for
+ Falcons
- 1996/3/9 ++geert: support added for Amiga, A-law, 16-bit little endian.
- Unification to drivers/sound/dmasound.c.
+1996/3/9 ++geert: support added for Amiga, A-law, 16-bit little endian.
+ Unification to drivers/sound/dmasound.c.
- 1996/4/6 ++Martin Mitchell: updated to 1.3 kernel.
+1996/4/6 ++Martin Mitchell: updated to 1.3 kernel.
- 1996/6/13 ++topi: fixed things that were broken (mainly the amiga
- 14-bit routines), /dev/sndstat shows now the real
- hardware frequency, the lowpass filter is disabled
- by default now.
+1996/6/13 ++topi: fixed things that were broken (mainly the amiga
+ 14-bit routines), /dev/sndstat shows now the real
+ hardware frequency, the lowpass filter is disabled
+ by default now.
- 1996/9/25 ++geert: modularization
+1996/9/25 ++geert: modularization
- */
+*/
#include <linux/module.h>
@@ -94,55 +94,54 @@
#ifdef CONFIG_ATARI
#include <asm/atarihw.h>
#include <asm/atariints.h>
-#endif /* CONFIG_ATARI */
+#include <asm/atari_stram.h>
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
#include <asm/amigahw.h>
#include <asm/amigaints.h>
-#endif /* CONFIG_AMIGA */
+#endif /* CONFIG_AMIGA */
#include "dmasound.h"
#include <linux/soundcard.h>
#ifdef MODULE
-static int chrdev_registered = 0;
-static int irq_installed = 0;
-
-#endif /* MODULE */
-static char **sound_buffers = NULL;
+static int chrdev_registered = 0;
+static int irq_installed = 0;
+#endif /* MODULE */
+static char **sound_buffers = NULL;
#ifdef CONFIG_ATARI
-extern void atari_microwire_cmd(int cmd);
-
-#endif /* CONFIG_ATARI */
+extern void atari_microwire_cmd(int cmd);
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
/*
- * The minimum period for audio depends on htotal (for OCS/ECS/AGA)
- * (Imported from arch/m68k/amiga/amisound.c)
+ * The minimum period for audio depends on htotal (for OCS/ECS/AGA)
+ * (Imported from arch/m68k/amiga/amisound.c)
*/
extern volatile u_short amiga_audio_min_period;
/*
- * amiga_mksound() should be able to restore the period after beeping
- * (Imported from arch/m68k/amiga/amisound.c)
+ * amiga_mksound() should be able to restore the period after beeping
+ * (Imported from arch/m68k/amiga/amisound.c)
*/
-extern u_short amiga_audio_period;
+extern u_short amiga_audio_period;
/*
- * Audio DMA masks
+ * Audio DMA masks
*/
#define AMI_AUDIO_OFF (DMAF_AUD0 | DMAF_AUD1 | DMAF_AUD2 | DMAF_AUD3)
#define AMI_AUDIO_8 (DMAF_SETCLR | DMAF_MASTER | DMAF_AUD0 | DMAF_AUD1)
#define AMI_AUDIO_14 (AMI_AUDIO_8 | DMAF_AUD2 | DMAF_AUD3)
-#endif /* CONFIG_AMIGA */
+#endif /* CONFIG_AMIGA */
/*** Some declarations *******************************************************/
@@ -157,7 +156,7 @@ extern u_short amiga_audio_period;
#define MIN_BUFSIZE 4
#define MAX_BUFSIZE 128 /* Limit for Amiga */
-static int catchRadius = 0, numBufs = 4, bufSize = 32;
+static int catchRadius = 0, numBufs = 4, bufSize = 32;
#define arraysize(x) (sizeof(x)/sizeof(*(x)))
@@ -177,78 +176,76 @@ static int catchRadius = 0, numBufs = 4, bufSize = 32;
/* 8 bit mu-law */
-static char ulaw2dma8[] =
-{
- -126, -122, -118, -114, -110, -106, -102, -98,
- -94, -90, -86, -82, -78, -74, -70, -66,
- -63, -61, -59, -57, -55, -53, -51, -49,
- -47, -45, -43, -41, -39, -37, -35, -33,
- -31, -30, -29, -28, -27, -26, -25, -24,
- -23, -22, -21, -20, -19, -18, -17, -16,
- -16, -15, -15, -14, -14, -13, -13, -12,
- -12, -11, -11, -10, -10, -9, -9, -8,
- -8, -8, -7, -7, -7, -7, -6, -6,
- -6, -6, -5, -5, -5, -5, -4, -4,
- -4, -4, -4, -4, -3, -3, -3, -3,
- -3, -3, -3, -3, -2, -2, -2, -2,
- -2, -2, -2, -2, -2, -2, -2, -2,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 0,
- 125, 121, 117, 113, 109, 105, 101, 97,
- 93, 89, 85, 81, 77, 73, 69, 65,
- 62, 60, 58, 56, 54, 52, 50, 48,
- 46, 44, 42, 40, 38, 36, 34, 32,
- 30, 29, 28, 27, 26, 25, 24, 23,
- 22, 21, 20, 19, 18, 17, 16, 15,
- 15, 14, 14, 13, 13, 12, 12, 11,
- 11, 10, 10, 9, 9, 8, 8, 7,
- 7, 7, 6, 6, 6, 6, 5, 5,
- 5, 5, 4, 4, 4, 4, 3, 3,
- 3, 3, 3, 3, 2, 2, 2, 2,
- 2, 2, 2, 2, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
+static char ulaw2dma8[] = {
+ -126, -122, -118, -114, -110, -106, -102, -98,
+ -94, -90, -86, -82, -78, -74, -70, -66,
+ -63, -61, -59, -57, -55, -53, -51, -49,
+ -47, -45, -43, -41, -39, -37, -35, -33,
+ -31, -30, -29, -28, -27, -26, -25, -24,
+ -23, -22, -21, -20, -19, -18, -17, -16,
+ -16, -15, -15, -14, -14, -13, -13, -12,
+ -12, -11, -11, -10, -10, -9, -9, -8,
+ -8, -8, -7, -7, -7, -7, -6, -6,
+ -6, -6, -5, -5, -5, -5, -4, -4,
+ -4, -4, -4, -4, -3, -3, -3, -3,
+ -3, -3, -3, -3, -2, -2, -2, -2,
+ -2, -2, -2, -2, -2, -2, -2, -2,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 0,
+ 125, 121, 117, 113, 109, 105, 101, 97,
+ 93, 89, 85, 81, 77, 73, 69, 65,
+ 62, 60, 58, 56, 54, 52, 50, 48,
+ 46, 44, 42, 40, 38, 36, 34, 32,
+ 30, 29, 28, 27, 26, 25, 24, 23,
+ 22, 21, 20, 19, 18, 17, 16, 15,
+ 15, 14, 14, 13, 13, 12, 12, 11,
+ 11, 10, 10, 9, 9, 8, 8, 7,
+ 7, 7, 6, 6, 6, 6, 5, 5,
+ 5, 5, 4, 4, 4, 4, 3, 3,
+ 3, 3, 3, 3, 2, 2, 2, 2,
+ 2, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
};
/* 8 bit A-law */
-static char alaw2dma8[] =
-{
- -22, -21, -24, -23, -18, -17, -20, -19,
- -30, -29, -32, -31, -26, -25, -28, -27,
- -11, -11, -12, -12, -9, -9, -10, -10,
- -15, -15, -16, -16, -13, -13, -14, -14,
- -86, -82, -94, -90, -70, -66, -78, -74,
- -118, -114, -126, -122, -102, -98, -110, -106,
- -43, -41, -47, -45, -35, -33, -39, -37,
- -59, -57, -63, -61, -51, -49, -55, -53,
- -2, -2, -2, -2, -2, -2, -2, -2,
- -2, -2, -2, -2, -2, -2, -2, -2,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -6, -6, -6, -6, -5, -5, -5, -5,
- -8, -8, -8, -8, -7, -7, -7, -7,
- -3, -3, -3, -3, -3, -3, -3, -3,
- -4, -4, -4, -4, -4, -4, -4, -4,
- 21, 20, 23, 22, 17, 16, 19, 18,
- 29, 28, 31, 30, 25, 24, 27, 26,
- 10, 10, 11, 11, 8, 8, 9, 9,
- 14, 14, 15, 15, 12, 12, 13, 13,
- 86, 82, 94, 90, 70, 66, 78, 74,
- 118, 114, 126, 122, 102, 98, 110, 106,
- 43, 41, 47, 45, 35, 33, 39, 37,
- 59, 57, 63, 61, 51, 49, 55, 53,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 5, 5, 5, 5, 4, 4, 4, 4,
- 7, 7, 7, 7, 6, 6, 6, 6,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3
+static char alaw2dma8[] = {
+ -22, -21, -24, -23, -18, -17, -20, -19,
+ -30, -29, -32, -31, -26, -25, -28, -27,
+ -11, -11, -12, -12, -9, -9, -10, -10,
+ -15, -15, -16, -16, -13, -13, -14, -14,
+ -86, -82, -94, -90, -70, -66, -78, -74,
+ -118, -114, -126, -122, -102, -98, -110, -106,
+ -43, -41, -47, -45, -35, -33, -39, -37,
+ -59, -57, -63, -61, -51, -49, -55, -53,
+ -2, -2, -2, -2, -2, -2, -2, -2,
+ -2, -2, -2, -2, -2, -2, -2, -2,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -6, -6, -6, -6, -5, -5, -5, -5,
+ -8, -8, -8, -8, -7, -7, -7, -7,
+ -3, -3, -3, -3, -3, -3, -3, -3,
+ -4, -4, -4, -4, -4, -4, -4, -4,
+ 21, 20, 23, 22, 17, 16, 19, 18,
+ 29, 28, 31, 30, 25, 24, 27, 26,
+ 10, 10, 11, 11, 8, 8, 9, 9,
+ 14, 14, 15, 15, 12, 12, 13, 13,
+ 86, 82, 94, 90, 70, 66, 78, 74,
+ 118, 114, 126, 122, 102, 98, 110, 106,
+ 43, 41, 47, 45, 35, 33, 39, 37,
+ 59, 57, 63, 61, 51, 49, 55, 53,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 5, 5, 5, 4, 4, 4, 4,
+ 7, 7, 7, 7, 6, 6, 6, 6,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3
};
@@ -256,403 +253,381 @@ static char alaw2dma8[] =
/* 16 bit mu-law */
-static char ulaw2dma16[] =
-{
- -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
- -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
- -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
- -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
- -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
- -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
- -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
- -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
- -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
- -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
- -876, -844, -812, -780, -748, -716, -684, -652,
- -620, -588, -556, -524, -492, -460, -428, -396,
- -372, -356, -340, -324, -308, -292, -276, -260,
- -244, -228, -212, -196, -180, -164, -148, -132,
- -120, -112, -104, -96, -88, -80, -72, -64,
- -56, -48, -40, -32, -24, -16, -8, 0,
- 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
- 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
- 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
- 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
- 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
- 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
- 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
- 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
- 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
- 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
- 876, 844, 812, 780, 748, 716, 684, 652,
- 620, 588, 556, 524, 492, 460, 428, 396,
- 372, 356, 340, 324, 308, 292, 276, 260,
- 244, 228, 212, 196, 180, 164, 148, 132,
- 120, 112, 104, 96, 88, 80, 72, 64,
- 56, 48, 40, 32, 24, 16, 8, 0,
+static char ulaw2dma16[] = {
+ -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
+ -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
+ -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
+ -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
+ -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
+ -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
+ -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
+ -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
+ -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
+ -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
+ -876, -844, -812, -780, -748, -716, -684, -652,
+ -620, -588, -556, -524, -492, -460, -428, -396,
+ -372, -356, -340, -324, -308, -292, -276, -260,
+ -244, -228, -212, -196, -180, -164, -148, -132,
+ -120, -112, -104, -96, -88, -80, -72, -64,
+ -56, -48, -40, -32, -24, -16, -8, 0,
+ 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
+ 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
+ 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
+ 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
+ 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
+ 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
+ 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
+ 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
+ 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
+ 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
+ 876, 844, 812, 780, 748, 716, 684, 652,
+ 620, 588, 556, 524, 492, 460, 428, 396,
+ 372, 356, 340, 324, 308, 292, 276, 260,
+ 244, 228, 212, 196, 180, 164, 148, 132,
+ 120, 112, 104, 96, 88, 80, 72, 64,
+ 56, 48, 40, 32, 24, 16, 8, 0,
};
/* 16 bit A-law */
-static char alaw2dma16[] =
-{
- -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
- -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
- -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
- -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
- -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
- -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
- -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
- -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
- -344, -328, -376, -360, -280, -264, -312, -296,
- -472, -456, -504, -488, -408, -392, -440, -424,
- -88, -72, -120, -104, -24, -8, -56, -40,
- -216, -200, -248, -232, -152, -136, -184, -168,
- -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
- -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
- -688, -656, -752, -720, -560, -528, -624, -592,
- -944, -912, -1008, -976, -816, -784, -880, -848,
- 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
- 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
- 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
- 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
- 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
- 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
- 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
- 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
- 344, 328, 376, 360, 280, 264, 312, 296,
- 472, 456, 504, 488, 408, 392, 440, 424,
- 88, 72, 120, 104, 24, 8, 56, 40,
- 216, 200, 248, 232, 152, 136, 184, 168,
- 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
- 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
- 688, 656, 752, 720, 560, 528, 624, 592,
- 944, 912, 1008, 976, 816, 784, 880, 848,
+static char alaw2dma16[] = {
+ -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
+ -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
+ -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
+ -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
+ -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
+ -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
+ -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
+ -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
+ -344, -328, -376, -360, -280, -264, -312, -296,
+ -472, -456, -504, -488, -408, -392, -440, -424,
+ -88, -72, -120, -104, -24, -8, -56, -40,
+ -216, -200, -248, -232, -152, -136, -184, -168,
+ -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
+ -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
+ -688, -656, -752, -720, -560, -528, -624, -592,
+ -944, -912, -1008, -976, -816, -784, -880, -848,
+ 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
+ 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
+ 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
+ 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
+ 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
+ 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
+ 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
+ 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
+ 344, 328, 376, 360, 280, 264, 312, 296,
+ 472, 456, 504, 488, 408, 392, 440, 424,
+ 88, 72, 120, 104, 24, 8, 56, 40,
+ 216, 200, 248, 232, 152, 136, 184, 168,
+ 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
+ 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
+ 688, 656, 752, 720, 560, 528, 624, 592,
+ 944, 912, 1008, 976, 816, 784, 880, 848,
};
-
-#endif /* HAS_16BIT_TABLES */
+#endif /* HAS_16BIT_TABLES */
#ifdef HAS_14BIT_TABLES
/* 14 bit mu-law (LSB) */
-static char alaw2dma14l[] =
-{
- 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 49, 17, 49, 17, 49, 17, 49, 17,
- 49, 17, 49, 17, 49, 17, 49, 17,
- 41, 57, 9, 25, 41, 57, 9, 25,
- 41, 57, 9, 25, 41, 57, 9, 25,
- 37, 45, 53, 61, 5, 13, 21, 29,
- 37, 45, 53, 61, 5, 13, 21, 29,
- 35, 39, 43, 47, 51, 55, 59, 63,
- 3, 7, 11, 15, 19, 23, 27, 31,
- 34, 36, 38, 40, 42, 44, 46, 48,
- 50, 52, 54, 56, 58, 60, 62, 0,
- 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 63, 63, 63,
- 15, 47, 15, 47, 15, 47, 15, 47,
- 15, 47, 15, 47, 15, 47, 15, 47,
- 23, 7, 55, 39, 23, 7, 55, 39,
- 23, 7, 55, 39, 23, 7, 55, 39,
- 27, 19, 11, 3, 59, 51, 43, 35,
- 27, 19, 11, 3, 59, 51, 43, 35,
- 29, 25, 21, 17, 13, 9, 5, 1,
- 61, 57, 53, 49, 45, 41, 37, 33,
- 30, 28, 26, 24, 22, 20, 18, 16,
- 14, 12, 10, 8, 6, 4, 2, 0
+static char alaw2dma14l[] = {
+ 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 49, 17, 49, 17, 49, 17, 49, 17,
+ 49, 17, 49, 17, 49, 17, 49, 17,
+ 41, 57, 9, 25, 41, 57, 9, 25,
+ 41, 57, 9, 25, 41, 57, 9, 25,
+ 37, 45, 53, 61, 5, 13, 21, 29,
+ 37, 45, 53, 61, 5, 13, 21, 29,
+ 35, 39, 43, 47, 51, 55, 59, 63,
+ 3, 7, 11, 15, 19, 23, 27, 31,
+ 34, 36, 38, 40, 42, 44, 46, 48,
+ 50, 52, 54, 56, 58, 60, 62, 0,
+ 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31,
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ 15, 47, 15, 47, 15, 47, 15, 47,
+ 15, 47, 15, 47, 15, 47, 15, 47,
+ 23, 7, 55, 39, 23, 7, 55, 39,
+ 23, 7, 55, 39, 23, 7, 55, 39,
+ 27, 19, 11, 3, 59, 51, 43, 35,
+ 27, 19, 11, 3, 59, 51, 43, 35,
+ 29, 25, 21, 17, 13, 9, 5, 1,
+ 61, 57, 53, 49, 45, 41, 37, 33,
+ 30, 28, 26, 24, 22, 20, 18, 16,
+ 14, 12, 10, 8, 6, 4, 2, 0
};
/* 14 bit A-law (LSB) */
-static char alaw2dma14l[] =
-{
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 16, 48, 16, 48, 16, 48, 16, 48,
- 16, 48, 16, 48, 16, 48, 16, 48,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 42, 46, 34, 38, 58, 62, 50, 54,
- 10, 14, 2, 6, 26, 30, 18, 22,
- 42, 46, 34, 38, 58, 62, 50, 54,
- 10, 14, 2, 6, 26, 30, 18, 22,
- 40, 56, 8, 24, 40, 56, 8, 24,
- 40, 56, 8, 24, 40, 56, 8, 24,
- 20, 28, 4, 12, 52, 60, 36, 44,
- 20, 28, 4, 12, 52, 60, 36, 44,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 48, 16, 48, 16, 48, 16, 48, 16,
- 48, 16, 48, 16, 48, 16, 48, 16,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 22, 18, 30, 26, 6, 2, 14, 10,
- 54, 50, 62, 58, 38, 34, 46, 42,
- 22, 18, 30, 26, 6, 2, 14, 10,
- 54, 50, 62, 58, 38, 34, 46, 42,
- 24, 8, 56, 40, 24, 8, 56, 40,
- 24, 8, 56, 40, 24, 8, 56, 40,
- 44, 36, 60, 52, 12, 4, 28, 20,
- 44, 36, 60, 52, 12, 4, 28, 20
+static char alaw2dma14l[] = {
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 16, 48, 16, 48, 16, 48, 16, 48,
+ 16, 48, 16, 48, 16, 48, 16, 48,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 42, 46, 34, 38, 58, 62, 50, 54,
+ 10, 14, 2, 6, 26, 30, 18, 22,
+ 42, 46, 34, 38, 58, 62, 50, 54,
+ 10, 14, 2, 6, 26, 30, 18, 22,
+ 40, 56, 8, 24, 40, 56, 8, 24,
+ 40, 56, 8, 24, 40, 56, 8, 24,
+ 20, 28, 4, 12, 52, 60, 36, 44,
+ 20, 28, 4, 12, 52, 60, 36, 44,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 48, 16, 48, 16, 48, 16, 48, 16,
+ 48, 16, 48, 16, 48, 16, 48, 16,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 22, 18, 30, 26, 6, 2, 14, 10,
+ 54, 50, 62, 58, 38, 34, 46, 42,
+ 22, 18, 30, 26, 6, 2, 14, 10,
+ 54, 50, 62, 58, 38, 34, 46, 42,
+ 24, 8, 56, 40, 24, 8, 56, 40,
+ 24, 8, 56, 40, 24, 8, 56, 40,
+ 44, 36, 60, 52, 12, 4, 28, 20,
+ 44, 36, 60, 52, 12, 4, 28, 20
};
-
-#endif /* HAS_14BIT_TABLES */
+#endif /* HAS_14BIT_TABLES */
/*** Translations ************************************************************/
#ifdef CONFIG_ATARI
-static long ata_ct_law(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_s8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_u8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_s16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_u16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_s16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ct_u16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_law(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_s8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_u8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_s16be(const u_char * userPtr, unsigned long userCount,
+static long ata_ct_law(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ct_s8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ct_u8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ct_s16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ct_u16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ct_s16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ct_u16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ctx_law(const u_char *userPtr, unsigned long userCount,
u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_u16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_s16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ata_ctx_u16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-
-#endif /* CONFIG_ATARI */
+static long ata_ctx_s8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ctx_u8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ctx_s16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ctx_u16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ctx_s16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ata_ctx_u16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
-static long ami_ct_law(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_s8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_u8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_s16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_u16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_s16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-static long ami_ct_u16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft);
-
-#endif /* CONFIG_AMIGA */
+static long ami_ct_law(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ami_ct_s8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ami_ct_u8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ami_ct_s16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ami_ct_u16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ami_ct_s16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+static long ami_ct_u16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft);
+#endif /* CONFIG_AMIGA */
/*** Machine definitions *****************************************************/
-typedef struct
- {
- int type;
- void *(*dma_alloc) (unsigned int, int);
- void (*dma_free) (void *, unsigned int);
- int (*irqinit) (void);
+typedef struct {
+ int type;
+ void *(*dma_alloc)(unsigned int, int);
+ void (*dma_free)(void *, unsigned int);
+ int (*irqinit)(void);
#ifdef MODULE
- void (*irqcleanup) (void);
-#endif /* MODULE */
- void (*init) (void);
- void (*silence) (void);
- int (*setFormat) (int);
- int (*setVolume) (int);
- int (*setBass) (int);
- int (*setTreble) (int);
- void (*play) (void);
- }
-MACHINE;
+ void (*irqcleanup)(void);
+#endif /* MODULE */
+ void (*init)(void);
+ void (*silence)(void);
+ int (*setFormat)(int);
+ int (*setVolume)(int);
+ int (*setBass)(int);
+ int (*setTreble)(int);
+ int (*setGain)(int);
+ void (*play)(void);
+} MACHINE;
/*** Low level stuff *********************************************************/
-typedef struct
- {
- int format; /* AFMT_* */
- int stereo; /* 0 = mono, 1 = stereo */
- int size; /* 8/16 bit */
- int speed; /* speed */
- }
-SETTINGS;
-
-typedef struct
- {
- long (*ct_ulaw) (const u_char *, unsigned long, u_char *, long *, long);
- long (*ct_alaw) (const u_char *, unsigned long, u_char *, long *, long);
- long (*ct_s8) (const u_char *, unsigned long, u_char *, long *, long);
- long (*ct_u8) (const u_char *, unsigned long, u_char *, long *, long);
- long (*ct_s16be) (const u_char *, unsigned long, u_char *, long *, long);
- long (*ct_u16be) (const u_char *, unsigned long, u_char *, long *, long);
- long (*ct_s16le) (const u_char *, unsigned long, u_char *, long *, long);
- long (*ct_u16le) (const u_char *, unsigned long, u_char *, long *, long);
- }
-TRANS;
-
-struct sound_settings
- {
- MACHINE mach; /* machine dependent things */
- SETTINGS hard; /* hardware settings */
- SETTINGS soft; /* software settings */
- SETTINGS dsp; /* /dev/dsp default settings */
- TRANS *trans; /* supported translations */
- int volume_left; /* volume (range is machine dependent) */
- int volume_right;
- int bass; /* tone (range is machine dependent) */
- int treble;
- int minDev; /* minor device number currently open */
+typedef struct {
+ int format; /* AFMT_* */
+ int stereo; /* 0 = mono, 1 = stereo */
+ int size; /* 8/16 bit*/
+ int speed; /* speed */
+} SETTINGS;
+
+typedef struct {
+ long (*ct_ulaw)(const u_char *, unsigned long, u_char *, long *, long);
+ long (*ct_alaw)(const u_char *, unsigned long, u_char *, long *, long);
+ long (*ct_s8)(const u_char *, unsigned long, u_char *, long *, long);
+ long (*ct_u8)(const u_char *, unsigned long, u_char *, long *, long);
+ long (*ct_s16be)(const u_char *, unsigned long, u_char *, long *, long);
+ long (*ct_u16be)(const u_char *, unsigned long, u_char *, long *, long);
+ long (*ct_s16le)(const u_char *, unsigned long, u_char *, long *, long);
+ long (*ct_u16le)(const u_char *, unsigned long, u_char *, long *, long);
+} TRANS;
+
+struct sound_settings {
+ MACHINE mach; /* machine dependent things */
+ SETTINGS hard; /* hardware settings */
+ SETTINGS soft; /* software settings */
+ SETTINGS dsp; /* /dev/dsp default settings */
+ TRANS *trans; /* supported translations */
+ int volume_left; /* volume (range is machine dependent) */
+ int volume_right;
+ int bass; /* tone (range is machine dependent) */
+ int treble;
+ int gain;
+ int minDev; /* minor device number currently open */
#ifdef CONFIG_ATARI
- int bal; /* balance factor for expanding (not volume!) */
- u_long data; /* data for expanding */
-#endif /* CONFIG_ATARI */
- };
+ int bal; /* balance factor for expanding (not volume!) */
+ u_long data; /* data for expanding */
+#endif /* CONFIG_ATARI */
+};
static struct sound_settings sound;
#ifdef CONFIG_ATARI
-static void *AtaAlloc(unsigned int size, int flags);
-static void AtaFree(void *, unsigned int size);
-static int AtaIrqInit(void);
-
+static void *AtaAlloc(unsigned int size, int flags);
+static void AtaFree(void *, unsigned int size);
+static int AtaIrqInit(void);
#ifdef MODULE
-static void AtaIrqCleanUp(void);
-
-#endif /* MODULE */
-static int AtaSetBass(int bass);
-static int AtaSetTreble(int treble);
-static void TTSilence(void);
-static void TTInit(void);
-static int TTSetFormat(int format);
-static int TTSetVolume(int volume);
-static void FalconSilence(void);
-static void FalconInit(void);
-static int FalconSetFormat(int format);
-static int FalconSetVolume(int volume);
-static void ata_sq_play_next_frame(int index);
-static void AtaPlay(void);
-static void ata_sq_interrupt(int irq, void *dummy, struct pt_regs *fp);
-
-#endif /* CONFIG_ATARI */
+static void AtaIrqCleanUp(void);
+#endif /* MODULE */
+static int AtaSetBass(int bass);
+static int AtaSetTreble(int treble);
+static void TTSilence(void);
+static void TTInit(void);
+static int TTSetFormat(int format);
+static int TTSetVolume(int volume);
+static int TTSetGain(int gain);
+static void FalconSilence(void);
+static void FalconInit(void);
+static int FalconSetFormat(int format);
+static int FalconSetVolume(int volume);
+static void ata_sq_play_next_frame(int index);
+static void AtaPlay(void);
+static void ata_sq_interrupt(int irq, void *dummy, struct pt_regs *fp);
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
-static void *AmiAlloc(unsigned int size, int flags);
-static void AmiFree(void *, unsigned int);
-static int AmiIrqInit(void);
-
+static void *AmiAlloc(unsigned int size, int flags);
+static void AmiFree(void *, unsigned int);
+static int AmiIrqInit(void);
#ifdef MODULE
-static void AmiIrqCleanUp(void);
-
-#endif /* MODULE */
-static void AmiSilence(void);
-static void AmiInit(void);
-static int AmiSetFormat(int format);
-static int AmiSetVolume(int volume);
-static int AmiSetTreble(int treble);
-static void ami_sq_play_next_frame(int index);
-static void AmiPlay(void);
-static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp);
-
-#endif /* CONFIG_AMIGA */
+static void AmiIrqCleanUp(void);
+#endif /* MODULE */
+static void AmiSilence(void);
+static void AmiInit(void);
+static int AmiSetFormat(int format);
+static int AmiSetVolume(int volume);
+static int AmiSetTreble(int treble);
+static void ami_sq_play_next_frame(int index);
+static void AmiPlay(void);
+static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp);
+#endif /* CONFIG_AMIGA */
/*** Mid level stuff *********************************************************/
-static void sound_silence(void);
-static void sound_init(void);
-static int sound_set_format(int format);
-static int sound_set_speed(int speed);
-static int sound_set_stereo(int stereo);
-static int sound_set_volume(int volume);
-
+static void sound_silence(void);
+static void sound_init(void);
+static int sound_set_format(int format);
+static int sound_set_speed(int speed);
+static int sound_set_stereo(int stereo);
+static int sound_set_volume(int volume);
#ifdef CONFIG_ATARI
-static int sound_set_bass(int bass);
-
-#endif /* CONFIG_ATARI */
-static int sound_set_treble(int treble);
-static long sound_copy_translate(const u_char * userPtr,
- unsigned long userCount,
- u_char frame[], long *frameUsed,
- long frameLeft);
+static int sound_set_bass(int bass);
+#endif /* CONFIG_ATARI */
+static int sound_set_treble(int treble);
+static long sound_copy_translate(const u_char *userPtr,
+ unsigned long userCount,
+ u_char frame[], long *frameUsed,
+ long frameLeft);
/*
* /dev/mixer abstraction
*/
-struct sound_mixer
- {
- int busy;
- };
+struct sound_mixer {
+ int busy;
+};
static struct sound_mixer mixer;
-static void mixer_init(void);
-static int mixer_open(int open_mode);
-static int mixer_release(void);
-static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg);
+static void mixer_init(void);
+static int mixer_open(int open_mode);
+static int mixer_release(void);
+static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg);
/*
* Sound queue stuff, the heart of the driver
*/
-struct sound_queue
- {
- int max_count, block_size;
- char **buffers;
-
- /* it shouldn't be necessary to declare any of these volatile */
- int front, rear, count;
- int rear_size;
- /*
- * The use of the playing field depends on the hardware
- *
- * Atari: The number of frames that are loaded/playing
- *
- * Amiga: Bit 0 is set: a frame is loaded
- * Bit 1 is set: a frame is playing
- */
- int playing;
- struct wait_queue *write_queue, *open_queue, *sync_queue;
- int open_mode;
- int busy, syncing;
+struct sound_queue {
+ int max_count, block_size;
+ char **buffers;
+
+ /* it shouldn't be necessary to declare any of these volatile */
+ int front, rear, count;
+ int rear_size;
+ /*
+ * The use of the playing field depends on the hardware
+ *
+ * Atari: The number of frames that are loaded/playing
+ *
+ * Amiga: Bit 0 is set: a frame is loaded
+ * Bit 1 is set: a frame is playing
+ */
+ int playing;
+ struct wait_queue *write_queue, *open_queue, *sync_queue;
+ int open_mode;
+ int busy, syncing;
#ifdef CONFIG_ATARI
- int ignore_int; /* ++TeSche: used for Falcon */
-#endif /* CONFIG_ATARI */
+ int ignore_int; /* ++TeSche: used for Falcon */
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
- int block_size_half, block_size_quarter;
-#endif /* CONFIG_AMIGA */
- };
+ int block_size_half, block_size_quarter;
+#endif /* CONFIG_AMIGA */
+};
static struct sound_queue sq;
@@ -666,72 +641,69 @@ static struct sound_queue sq;
interruptible_sleep_on(&queue);
#define WAKE_UP(queue) (wake_up_interruptible(&queue))
-static void sq_init(int numBufs, int bufSize, char **buffers);
-static void sq_play(void);
-static long sq_write(const char *src, unsigned long uLeft);
-static int sq_open(int open_mode);
-static void sq_reset(void);
-static int sq_sync(void);
-static int sq_release(void);
+static void sq_init(int numBufs, int bufSize, char **buffers);
+static void sq_play(void);
+static long sq_write(const char *src, unsigned long uLeft);
+static int sq_open(int open_mode);
+static void sq_reset(void);
+static int sq_sync(void);
+static int sq_release(void);
/*
* /dev/sndstat
*/
-struct sound_state
- {
- int busy;
- char buf[512];
- int len, ptr;
- };
+struct sound_state {
+ int busy;
+ char buf[512];
+ int len, ptr;
+};
static struct sound_state state;
-static void state_init(void);
-static int state_open(int open_mode);
-static int state_release(void);
-static long state_read(char *dest, unsigned long count);
+static void state_init(void);
+static int state_open(int open_mode);
+static int state_release(void);
+static long state_read(char *dest, unsigned long count);
/*** High level stuff ********************************************************/
-static int sound_open(struct inode *inode, struct file *file);
-static int sound_fsync(struct inode *inode, struct file *filp);
-static void sound_release(struct inode *inode, struct file *file);
-static long long sound_lseek(struct inode *inode, struct file *file,
- long long offset, int orig);
-static long sound_read(struct inode *inode, struct file *file, char *buf,
- unsigned long count);
-static long sound_write(struct inode *inode, struct file *file,
- const char *buf, unsigned long count);
-static inline int
-ioctl_return(int *addr, int value)
+static int sound_open(struct inode *inode, struct file *file);
+static int sound_fsync(struct file *filp, struct dentry *dentry);
+static int sound_release(struct inode *inode, struct file *file);
+static long long sound_lseek(struct file *file, long long offset, int orig);
+static ssize_t sound_read(struct file *file, char *buf, size_t count,
+ loff_t *ppos);
+static ssize_t sound_write(struct file *file, const char *buf, size_t count,
+ loff_t *ppos);
+static inline int ioctl_return(int *addr, int value)
{
- if (value < 0)
- return (value);
+ if (value < 0)
+ return(value);
- return put_user(value, addr);
+ return put_user(value, addr);
}
-static int unknown_minor_dev(char *fname, int dev);
-static int sound_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg);
+static int unknown_minor_dev(char *fname, int dev);
+static int sound_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg);
/*** Config & Setup **********************************************************/
-void soundcard_init(void);
-void dmasound_setup(char *str, int *ints);
-void sound_setup(char *str, int *ints); /* ++Martin: stub for now */
+void soundcard_init(void);
+void dmasound_setup(char *str, int *ints);
+void sound_setup(char *str, int *ints); /* ++Martin: stub for now */
/*** Translations ************************************************************/
/* ++TeSche: radically changed for new expanding purposes...
-
+ *
* These two routines now deal with copying/expanding/translating the samples
* from user space into our buffer at the right frequency. They take care about
* how much data there's actually to read, how much buffer space there is and
@@ -755,1014 +727,849 @@ void sound_setup(char *str, int *ints); /* ++Martin: stub for now */
*/
#ifdef CONFIG_ATARI
-static long
-ata_ct_law(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
-{
- char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
- long count, used;
- u_char *p = &frame[*frameUsed];
-
- count = min(userCount, frameLeft);
- if (sound.soft.stereo)
- count &= ~1;
- used = count;
- while (count > 0)
- {
- u_char data;
-
- get_user(data, userPtr++);
- *p++ = table[data];
- count--;
- }
- *frameUsed += used;
- return (used);
-}
-
-
-static long
-ata_ct_s8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
-{
- long count, used;
- void *p = &frame[*frameUsed];
-
- count = min(userCount, frameLeft);
- if (sound.soft.stereo)
- count &= ~1;
- used = count;
- copy_from_user(p, userPtr, count);
- *frameUsed += used;
- return (used);
-}
-
-
-static long
-ata_ct_u8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
-{
- long count, used;
-
- if (!sound.soft.stereo)
- {
- u_char *p = &frame[*frameUsed];
-
- count = min(userCount, frameLeft);
- used = count;
- while (count > 0)
- {
- u_char data;
-
- get_user(data, userPtr++);
- *p++ = data ^ 0x80;
- count--;
- }
- } else
- {
- u_short *p = (u_short *) & frame[*frameUsed];
-
- count = min(userCount, frameLeft) >> 1;
- used = count * 2;
- while (count > 0)
- {
- u_short data;
-
- get_user(data, ((u_short *) userPtr)++);
- *p++ = data ^ 0x8080;
- count--;
- }
- }
- *frameUsed += used;
- return (used);
-}
-
-
-static long
-ata_ct_s16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
-{
- long count, used;
- u_long data;
-
- if (!sound.soft.stereo)
- {
- u_short *p = (u_short *) & frame[*frameUsed];
-
- count = min(userCount, frameLeft) >> 1;
- used = count * 2;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- *p++ = data;
- *p++ = data;
- count--;
- }
- *frameUsed += used * 2;
- } else
- {
- void *p = (u_short *) & frame[*frameUsed];
-
- count = min(userCount, frameLeft) & ~3;
- used = count;
- copy_from_user(p, userPtr, count);
- *frameUsed += used;
- }
- return (used);
-}
-
-
-static long
-ata_ct_u16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
-{
- long count, used;
- u_long data;
-
- if (!sound.soft.stereo)
- {
- u_short *p = (u_short *) & frame[*frameUsed];
-
- count = min(userCount, frameLeft) >> 1;
- used = count * 2;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- data ^= 0x8000;
- *p++ = data;
- *p++ = data;
- count--;
- }
- *frameUsed += used * 2;
- } else
- {
- u_long *p = (u_long *) & frame[*frameUsed];
-
- count = min(userCount, frameLeft) >> 2;
- used = count * 4;
- while (count > 0)
- {
- get_user(data, ((u_int *) userPtr)++);
- *p++ = data ^ 0x80008000;
- count--;
- }
- *frameUsed += used;
- }
- return (used);
-}
-
-
-static long
-ata_ct_s16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
-{
- long count, used;
- u_long data;
-
- count = frameLeft;
- if (!sound.soft.stereo)
- {
- u_short *p = (u_short *) & frame[*frameUsed];
-
- count = min(userCount, frameLeft) >> 1;
- used = count * 2;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- data = le2be16(data);
- *p++ = data;
- *p++ = data;
- count--;
- }
- *frameUsed += used * 2;
- } else
- {
- u_long *p = (u_long *) & frame[*frameUsed];
-
- count = min(userCount, frameLeft) >> 2;
- used = count * 4;
- while (count > 0)
- {
- get_user(data, ((u_int *) userPtr)++);
- data = le2be16dbl(data);
- *p++ = data;
- count--;
- }
- *frameUsed += used;
- }
- return (used);
-}
-
-
-static long
-ata_ct_u16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
-{
- long count, used;
- u_long data;
-
- count = frameLeft;
- if (!sound.soft.stereo)
- {
- u_short *p = (u_short *) & frame[*frameUsed];
-
- count = min(userCount, frameLeft) >> 1;
- used = count * 2;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- data = le2be16(data) ^ 0x8000;
- *p++ = data;
- *p++ = data;
- }
- *frameUsed += used * 2;
- } else
- {
- u_long *p = (u_long *) & frame[*frameUsed];
-
- count = min(userCount, frameLeft) >> 2;
- used = count;
- while (count > 0)
- {
- get_user(data, ((u_int *) userPtr)++);
- data = le2be16dbl(data) ^ 0x80008000;
- *p++ = data;
- count--;
- }
- *frameUsed += used;
- }
- return (used);
-}
-
-
-static long
-ata_ctx_law(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
-{
- char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
-
- /* this should help gcc to stuff everything into registers */
- u_long data = sound.data;
- long bal = sound.bal;
- long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
- long used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!sound.soft.stereo)
- {
- u_char *p = &frame[*frameUsed];
-
- while (frameLeft)
- {
- u_char c;
-
- if (bal < 0)
- {
- if (!userCount)
- break;
- get_user(c, userPtr++);
- data = table[c];
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- } else
- {
- u_short *p = (u_short *) & frame[*frameUsed];
-
- while (frameLeft >= 2)
- {
- u_char c;
-
- if (bal < 0)
- {
- if (userCount < 2)
- break;
- get_user(c, userPtr++);
- data = table[c] << 8;
- get_user(c, userPtr++);
- data |= table[c];
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 2;
- bal -= sSpeed;
- }
- }
- sound.bal = bal;
- sound.data = data;
- used -= userCount;
- *frameUsed += usedf - frameLeft;
- return (used);
-}
-
-
-static long
-ata_ctx_s8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ata_ct_law(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- /* this should help gcc to stuff everything into registers */
- u_long data = sound.data;
- long bal = sound.bal;
- long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
- long used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!sound.soft.stereo)
- {
- u_char *p = &frame[*frameUsed];
-
- while (frameLeft)
- {
- if (bal < 0)
- {
- if (!userCount)
- break;
- get_user(data, userPtr++);
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- } else
- {
- u_short *p = (u_short *) & frame[*frameUsed];
+ char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
+ long count, used;
+ u_char *p = &frame[*frameUsed];
- while (frameLeft >= 2)
- {
- if (bal < 0)
- {
- if (userCount < 2)
- break;
- get_user(data, ((u_short *) userPtr)++);
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 2;
- bal -= sSpeed;
- }
- }
- sound.bal = bal;
- sound.data = data;
- used -= userCount;
- *frameUsed += usedf - frameLeft;
- return (used);
+ count = min(userCount, frameLeft);
+ if (sound.soft.stereo)
+ count &= ~1;
+ used = count;
+ while (count > 0) {
+ u_char data;
+ get_user(data, userPtr++);
+ *p++ = table[data];
+ count--;
+ }
+ *frameUsed += used;
+ return(used);
}
-static long
-ata_ctx_u8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ata_ct_s8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- /* this should help gcc to stuff everything into registers */
- u_long data = sound.data;
- long bal = sound.bal;
- long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
- long used, usedf;
+ long count, used;
+ void *p = &frame[*frameUsed];
- used = userCount;
- usedf = frameLeft;
- if (!sound.soft.stereo)
- {
- u_char *p = &frame[*frameUsed];
-
- while (frameLeft)
- {
- if (bal < 0)
- {
- if (!userCount)
- break;
- get_user(data, userPtr++);
- data ^= 0x80;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- } else
- {
- u_short *p = (u_short *) & frame[*frameUsed];
-
- while (frameLeft >= 2)
- {
- if (bal < 0)
- {
- if (userCount < 2)
- break;
- get_user(data, ((u_short *) userPtr)++);
- data ^= 0x8080;
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 2;
- bal -= sSpeed;
- }
- }
- sound.bal = bal;
- sound.data = data;
- used -= userCount;
- *frameUsed += usedf - frameLeft;
- return (used);
+ count = min(userCount, frameLeft);
+ if (sound.soft.stereo)
+ count &= ~1;
+ used = count;
+ copy_from_user(p, userPtr, count);
+ *frameUsed += used;
+ return(used);
}
-static long
-ata_ctx_s16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ata_ct_u8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- /* this should help gcc to stuff everything into registers */
- u_long data = sound.data;
- long bal = sound.bal;
- long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
- long used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!sound.soft.stereo)
- {
- u_short *p = (u_short *) & frame[*frameUsed];
+ long count, used;
- while (frameLeft >= 4)
- {
- if (bal < 0)
- {
- if (userCount < 2)
- break;
- get_user(data, ((u_short *) userPtr)++);
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- } else
- {
- u_long *p = (u_long *) & frame[*frameUsed];
-
- while (frameLeft >= 4)
- {
- if (bal < 0)
- {
- if (userCount < 4)
- break;
- get_user(data, ((u_int *) userPtr)++);
- userCount -= 4;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- }
- sound.bal = bal;
- sound.data = data;
- used -= userCount;
- *frameUsed += usedf - frameLeft;
- return (used);
-}
-
-
-static long
-ata_ctx_u16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
-{
- /* this should help gcc to stuff everything into registers */
- u_long data = sound.data;
- long bal = sound.bal;
- long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
- long used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!sound.soft.stereo)
- {
- u_short *p = (u_short *) & frame[*frameUsed];
-
- while (frameLeft >= 4)
- {
- if (bal < 0)
- {
- if (userCount < 2)
- break;
- get_user(data, ((u_short *) userPtr)++);
- data ^= 0x8000;
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- } else
- {
- u_long *p = (u_long *) & frame[*frameUsed];
-
- while (frameLeft >= 4)
- {
- if (bal < 0)
- {
- if (userCount < 4)
- break;
- get_user(data, ((u_int *) userPtr)++);
- data ^= 0x80008000;
- userCount -= 4;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- }
- sound.bal = bal;
- sound.data = data;
- used -= userCount;
- *frameUsed += usedf - frameLeft;
- return (used);
+ if (!sound.soft.stereo) {
+ u_char *p = &frame[*frameUsed];
+ count = min(userCount, frameLeft);
+ used = count;
+ while (count > 0) {
+ u_char data;
+ get_user(data, userPtr++);
+ *p++ = data ^ 0x80;
+ count--;
+ }
+ } else {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ count = min(userCount, frameLeft)>>1;
+ used = count*2;
+ while (count > 0) {
+ u_short data;
+ get_user(data, ((u_short *)userPtr)++);
+ *p++ = data ^ 0x8080;
+ count--;
+ }
+ }
+ *frameUsed += used;
+ return(used);
}
-static long
-ata_ctx_s16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ata_ct_s16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- /* this should help gcc to stuff everything into registers */
- u_long data = sound.data;
- long bal = sound.bal;
- long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
- long used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!sound.soft.stereo)
- {
- u_short *p = (u_short *) & frame[*frameUsed];
-
- while (frameLeft >= 4)
- {
- if (bal < 0)
- {
- if (userCount < 2)
- break;
- get_user(data, ((u_short *) userPtr)++);
- data = le2be16(data);
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- } else
- {
- u_long *p = (u_long *) & frame[*frameUsed];
+ long count, used;
+ u_long data;
- while (frameLeft >= 4)
- {
- if (bal < 0)
- {
- if (userCount < 4)
- break;
- get_user(data, ((u_int *) userPtr)++);
- data = le2be16dbl(data);
- userCount -= 4;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- }
- sound.bal = bal;
- sound.data = data;
- used -= userCount;
- *frameUsed += usedf - frameLeft;
- return (used);
+ if (!sound.soft.stereo) {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ count = min(userCount, frameLeft)>>1;
+ used = count*2;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ *p++ = data;
+ *p++ = data;
+ count--;
+ }
+ *frameUsed += used*2;
+ } else {
+ void *p = (u_short *)&frame[*frameUsed];
+ count = min(userCount, frameLeft) & ~3;
+ used = count;
+ copy_from_user(p, userPtr, count);
+ *frameUsed += used;
+ }
+ return(used);
}
-static long
-ata_ctx_u16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ata_ct_u16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- /* this should help gcc to stuff everything into registers */
- u_long data = sound.data;
- long bal = sound.bal;
- long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
- long used, usedf;
-
- used = userCount;
- usedf = frameLeft;
- if (!sound.soft.stereo)
- {
- u_short *p = (u_short *) & frame[*frameUsed];
-
- while (frameLeft >= 4)
- {
- if (bal < 0)
- {
- if (userCount < 2)
- break;
- get_user(data, ((u_short *) userPtr)++);
- data = le2be16(data) ^ 0x8000;
- userCount -= 2;
- bal += hSpeed;
- }
- *p++ = data;
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- } else
- {
- u_long *p = (u_long *) & frame[*frameUsed];
+ long count, used;
+ u_long data;
- while (frameLeft >= 4)
- {
- if (bal < 0)
- {
- if (userCount < 4)
- break;
- get_user(data, ((u_int *) userPtr)++);
- data = le2be16dbl(data) ^ 0x80008000;
- userCount -= 4;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft -= 4;
- bal -= sSpeed;
- }
- }
- sound.bal = bal;
- sound.data = data;
- used -= userCount;
- *frameUsed += usedf - frameLeft;
- return (used);
+ if (!sound.soft.stereo) {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ count = min(userCount, frameLeft)>>1;
+ used = count*2;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ data ^= 0x8000;
+ *p++ = data;
+ *p++ = data;
+ count--;
+ }
+ *frameUsed += used*2;
+ } else {
+ u_long *p = (u_long *)&frame[*frameUsed];
+ count = min(userCount, frameLeft)>>2;
+ used = count*4;
+ while (count > 0) {
+ get_user(data, ((u_int *)userPtr)++);
+ *p++ = data ^ 0x80008000;
+ count--;
+ }
+ *frameUsed += used;
+ }
+ return(used);
}
-#endif /* CONFIG_ATARI */
-#ifdef CONFIG_AMIGA
-static long
-ami_ct_law(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ata_ct_s16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
- long count, used;
-
- if (!sound.soft.stereo)
- {
- u_char *p = &frame[*frameUsed];
-
- count = min(userCount, frameLeft) & ~1;
- used = count;
- while (count > 0)
- {
- u_char data;
+ long count, used;
+ u_long data;
- get_user(data, userPtr++);
- *p++ = table[data];
- count--;
- }
- } else
- {
- u_char *left = &frame[*frameUsed >> 1];
- u_char *right = left + sq.block_size_half;
-
- count = min(userCount, frameLeft) >> 1 & ~1;
- used = count * 2;
- while (count > 0)
- {
- u_char data;
-
- get_user(data, userPtr++);
- *left++ = table[data];
- get_user(data, userPtr++);
- *right++ = table[data];
- count--;
- }
- }
+ count = frameLeft;
+ if (!sound.soft.stereo) {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ count = min(userCount, frameLeft)>>1;
+ used = count*2;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ data = le2be16(data);
+ *p++ = data;
+ *p++ = data;
+ count--;
+ }
+ *frameUsed += used*2;
+ } else {
+ u_long *p = (u_long *)&frame[*frameUsed];
+ count = min(userCount, frameLeft)>>2;
+ used = count*4;
+ while (count > 0) {
+ get_user(data, ((u_int *)userPtr)++);
+ data = le2be16dbl(data);
+ *p++ = data;
+ count--;
+ }
*frameUsed += used;
- return (used);
+ }
+ return(used);
}
-static long
-ami_ct_s8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ata_ct_u16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- long count, used;
+ long count, used;
+ u_long data;
- if (!sound.soft.stereo)
- {
- void *p = &frame[*frameUsed];
-
- count = min(userCount, frameLeft) & ~1;
- used = count;
- copy_from_user(p, userPtr, count);
- } else
- {
- u_char *left = &frame[*frameUsed >> 1];
- u_char *right = left + sq.block_size_half;
-
- count = min(userCount, frameLeft) >> 1 & ~1;
- used = count * 2;
- while (count > 0)
- {
- get_user(*left++, userPtr++);
- get_user(*right++, userPtr++);
- count--;
- }
- }
+ count = frameLeft;
+ if (!sound.soft.stereo) {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ count = min(userCount, frameLeft)>>1;
+ used = count*2;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ data = le2be16(data) ^ 0x8000;
+ *p++ = data;
+ *p++ = data;
+ }
+ *frameUsed += used*2;
+ } else {
+ u_long *p = (u_long *)&frame[*frameUsed];
+ count = min(userCount, frameLeft)>>2;
+ used = count;
+ while (count > 0) {
+ get_user(data, ((u_int *)userPtr)++);
+ data = le2be16dbl(data) ^ 0x80008000;
+ *p++ = data;
+ count--;
+ }
*frameUsed += used;
- return (used);
+ }
+ return(used);
+}
+
+
+static long ata_ctx_law(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
+{
+ char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
+ /* this should help gcc to stuff everything into registers */
+ u_long data = sound.data;
+ long bal = sound.bal;
+ long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
+ long used, usedf;
+
+ used = userCount;
+ usedf = frameLeft;
+ if (!sound.soft.stereo) {
+ u_char *p = &frame[*frameUsed];
+ while (frameLeft) {
+ u_char c;
+ if (bal < 0) {
+ if (!userCount)
+ break;
+ get_user(c, userPtr++);
+ data = table[c];
+ userCount--;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft--;
+ bal -= sSpeed;
+ }
+ } else {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ while (frameLeft >= 2) {
+ u_char c;
+ if (bal < 0) {
+ if (userCount < 2)
+ break;
+ get_user(c, userPtr++);
+ data = table[c] << 8;
+ get_user(c, userPtr++);
+ data |= table[c];
+ userCount -= 2;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft -= 2;
+ bal -= sSpeed;
+ }
+ }
+ sound.bal = bal;
+ sound.data = data;
+ used -= userCount;
+ *frameUsed += usedf-frameLeft;
+ return(used);
+}
+
+
+static long ata_ctx_s8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
+{
+ /* this should help gcc to stuff everything into registers */
+ u_long data = sound.data;
+ long bal = sound.bal;
+ long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
+ long used, usedf;
+
+ used = userCount;
+ usedf = frameLeft;
+ if (!sound.soft.stereo) {
+ u_char *p = &frame[*frameUsed];
+ while (frameLeft) {
+ if (bal < 0) {
+ if (!userCount)
+ break;
+ get_user(data, userPtr++);
+ userCount--;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft--;
+ bal -= sSpeed;
+ }
+ } else {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ while (frameLeft >= 2) {
+ if (bal < 0) {
+ if (userCount < 2)
+ break;
+ get_user(data, ((u_short *)userPtr)++);
+ userCount -= 2;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft -= 2;
+ bal -= sSpeed;
+ }
+ }
+ sound.bal = bal;
+ sound.data = data;
+ used -= userCount;
+ *frameUsed += usedf-frameLeft;
+ return(used);
+}
+
+
+static long ata_ctx_u8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
+{
+ /* this should help gcc to stuff everything into registers */
+ u_long data = sound.data;
+ long bal = sound.bal;
+ long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
+ long used, usedf;
+
+ used = userCount;
+ usedf = frameLeft;
+ if (!sound.soft.stereo) {
+ u_char *p = &frame[*frameUsed];
+ while (frameLeft) {
+ if (bal < 0) {
+ if (!userCount)
+ break;
+ get_user(data, userPtr++);
+ data ^= 0x80;
+ userCount--;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft--;
+ bal -= sSpeed;
+ }
+ } else {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ while (frameLeft >= 2) {
+ if (bal < 0) {
+ if (userCount < 2)
+ break;
+ get_user(data, ((u_short *)userPtr)++);
+ data ^= 0x8080;
+ userCount -= 2;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft -= 2;
+ bal -= sSpeed;
+ }
+ }
+ sound.bal = bal;
+ sound.data = data;
+ used -= userCount;
+ *frameUsed += usedf-frameLeft;
+ return(used);
+}
+
+
+static long ata_ctx_s16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
+{
+ /* this should help gcc to stuff everything into registers */
+ u_long data = sound.data;
+ long bal = sound.bal;
+ long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
+ long used, usedf;
+
+ used = userCount;
+ usedf = frameLeft;
+ if (!sound.soft.stereo) {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ while (frameLeft >= 4) {
+ if (bal < 0) {
+ if (userCount < 2)
+ break;
+ get_user(data, ((u_short *)userPtr)++);
+ userCount -= 2;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ *p++ = data;
+ frameLeft -= 4;
+ bal -= sSpeed;
+ }
+ } else {
+ u_long *p = (u_long *)&frame[*frameUsed];
+ while (frameLeft >= 4) {
+ if (bal < 0) {
+ if (userCount < 4)
+ break;
+ get_user(data, ((u_int *)userPtr)++);
+ userCount -= 4;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft -= 4;
+ bal -= sSpeed;
+ }
+ }
+ sound.bal = bal;
+ sound.data = data;
+ used -= userCount;
+ *frameUsed += usedf-frameLeft;
+ return(used);
+}
+
+
+static long ata_ctx_u16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
+{
+ /* this should help gcc to stuff everything into registers */
+ u_long data = sound.data;
+ long bal = sound.bal;
+ long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
+ long used, usedf;
+
+ used = userCount;
+ usedf = frameLeft;
+ if (!sound.soft.stereo) {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ while (frameLeft >= 4) {
+ if (bal < 0) {
+ if (userCount < 2)
+ break;
+ get_user(data, ((u_short *)userPtr)++);
+ data ^= 0x8000;
+ userCount -= 2;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ *p++ = data;
+ frameLeft -= 4;
+ bal -= sSpeed;
+ }
+ } else {
+ u_long *p = (u_long *)&frame[*frameUsed];
+ while (frameLeft >= 4) {
+ if (bal < 0) {
+ if (userCount < 4)
+ break;
+ get_user(data, ((u_int *)userPtr)++);
+ data ^= 0x80008000;
+ userCount -= 4;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft -= 4;
+ bal -= sSpeed;
+ }
+ }
+ sound.bal = bal;
+ sound.data = data;
+ used -= userCount;
+ *frameUsed += usedf-frameLeft;
+ return(used);
+}
+
+
+static long ata_ctx_s16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
+{
+ /* this should help gcc to stuff everything into registers */
+ u_long data = sound.data;
+ long bal = sound.bal;
+ long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
+ long used, usedf;
+
+ used = userCount;
+ usedf = frameLeft;
+ if (!sound.soft.stereo) {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ while (frameLeft >= 4) {
+ if (bal < 0) {
+ if (userCount < 2)
+ break;
+ get_user(data, ((u_short *)userPtr)++);
+ data = le2be16(data);
+ userCount -= 2;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ *p++ = data;
+ frameLeft -= 4;
+ bal -= sSpeed;
+ }
+ } else {
+ u_long *p = (u_long *)&frame[*frameUsed];
+ while (frameLeft >= 4) {
+ if (bal < 0) {
+ if (userCount < 4)
+ break;
+ get_user(data, ((u_int *)userPtr)++);
+ data = le2be16dbl(data);
+ userCount -= 4;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft -= 4;
+ bal -= sSpeed;
+ }
+ }
+ sound.bal = bal;
+ sound.data = data;
+ used -= userCount;
+ *frameUsed += usedf-frameLeft;
+ return(used);
+}
+
+
+static long ata_ctx_u16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
+{
+ /* this should help gcc to stuff everything into registers */
+ u_long data = sound.data;
+ long bal = sound.bal;
+ long hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
+ long used, usedf;
+
+ used = userCount;
+ usedf = frameLeft;
+ if (!sound.soft.stereo) {
+ u_short *p = (u_short *)&frame[*frameUsed];
+ while (frameLeft >= 4) {
+ if (bal < 0) {
+ if (userCount < 2)
+ break;
+ get_user(data, ((u_short *)userPtr)++);
+ data = le2be16(data) ^ 0x8000;
+ userCount -= 2;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ *p++ = data;
+ frameLeft -= 4;
+ bal -= sSpeed;
+ }
+ } else {
+ u_long *p = (u_long *)&frame[*frameUsed];
+ while (frameLeft >= 4) {
+ if (bal < 0) {
+ if (userCount < 4)
+ break;
+ get_user(data, ((u_int *)userPtr)++);
+ data = le2be16dbl(data) ^ 0x80008000;
+ userCount -= 4;
+ bal += hSpeed;
+ }
+ *p++ = data;
+ frameLeft -= 4;
+ bal -= sSpeed;
+ }
+ }
+ sound.bal = bal;
+ sound.data = data;
+ used -= userCount;
+ *frameUsed += usedf-frameLeft;
+ return(used);
}
+#endif /* CONFIG_ATARI */
-static long
-ami_ct_u8(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+#ifdef CONFIG_AMIGA
+static long ami_ct_law(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- long count, used;
-
- if (!sound.soft.stereo)
- {
- char *p = &frame[*frameUsed];
-
- count = min(userCount, frameLeft) & ~1;
- used = count;
- while (count > 0)
- {
- u_char data;
-
- get_user(data, userPtr++);
- *p++ = data ^ 0x80;
- count--;
- }
- } else
- {
- u_char *left = &frame[*frameUsed >> 1];
- u_char *right = left + sq.block_size_half;
+ char *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma8 : alaw2dma8;
+ long count, used;
- count = min(userCount, frameLeft) >> 1 & ~1;
- used = count * 2;
- while (count > 0)
- {
- u_char data;
-
- get_user(data, userPtr++);
- *left++ = data ^ 0x80;
- get_user(data, userPtr++);
- *right++ = data ^ 0x80;
- count--;
- }
- }
- *frameUsed += used;
- return (used);
+ if (!sound.soft.stereo) {
+ u_char *p = &frame[*frameUsed];
+ count = min(userCount, frameLeft) & ~1;
+ used = count;
+ while (count > 0) {
+ u_char data;
+ get_user(data, userPtr++);
+ *p++ = table[data];
+ count--;
+ }
+ } else {
+ u_char *left = &frame[*frameUsed>>1];
+ u_char *right = left+sq.block_size_half;
+ count = min(userCount, frameLeft)>>1 & ~1;
+ used = count*2;
+ while (count > 0) {
+ u_char data;
+ get_user(data, userPtr++);
+ *left++ = table[data];
+ get_user(data, userPtr++);
+ *right++ = table[data];
+ count--;
+ }
+ }
+ *frameUsed += used;
+ return(used);
}
-static long
-ami_ct_s16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ami_ct_s8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- long count, used;
- u_long data;
+ long count, used;
- if (!sound.soft.stereo)
- {
- u_char *high = &frame[*frameUsed >> 1];
- u_char *low = high + sq.block_size_half;
-
- count = min(userCount, frameLeft) >> 1 & ~1;
- used = count * 2;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- *high++ = data >> 8;
- *low++ = (data >> 2) & 0x3f;
- count--;
- }
- } else
- {
- u_char *lefth = &frame[*frameUsed >> 2];
- u_char *leftl = lefth + sq.block_size_quarter;
- u_char *righth = lefth + sq.block_size_half;
- u_char *rightl = righth + sq.block_size_quarter;
-
- count = min(userCount, frameLeft) >> 2 & ~1;
- used = count * 4;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- *lefth++ = data >> 8;
- *leftl++ = (data >> 2) & 0x3f;
- get_user(data, ((u_short *) userPtr)++);
- *righth++ = data >> 8;
- *rightl++ = (data >> 2) & 0x3f;
- count--;
- }
- }
- *frameUsed += used;
- return (used);
+ if (!sound.soft.stereo) {
+ void *p = &frame[*frameUsed];
+ count = min(userCount, frameLeft) & ~1;
+ used = count;
+ copy_from_user(p, userPtr, count);
+ } else {
+ u_char *left = &frame[*frameUsed>>1];
+ u_char *right = left+sq.block_size_half;
+ count = min(userCount, frameLeft)>>1 & ~1;
+ used = count*2;
+ while (count > 0) {
+ get_user(*left++, userPtr++);
+ get_user(*right++, userPtr++);
+ count--;
+ }
+ }
+ *frameUsed += used;
+ return(used);
}
-static long
-ami_ct_u16be(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ami_ct_u8(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- long count, used;
- u_long data;
+ long count, used;
- if (!sound.soft.stereo)
- {
- u_char *high = &frame[*frameUsed >> 1];
- u_char *low = high + sq.block_size_half;
-
- count = min(userCount, frameLeft) >> 1 & ~1;
- used = count * 2;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- data ^= 0x8000;
- *high++ = data >> 8;
- *low++ = (data >> 2) & 0x3f;
- count--;
- }
- } else
- {
- u_char *lefth = &frame[*frameUsed >> 2];
- u_char *leftl = lefth + sq.block_size_quarter;
- u_char *righth = lefth + sq.block_size_half;
- u_char *rightl = righth + sq.block_size_quarter;
-
- count = min(userCount, frameLeft) >> 2 & ~1;
- used = count * 4;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- data ^= 0x8000;
- *lefth++ = data >> 8;
- *leftl++ = (data >> 2) & 0x3f;
- get_user(data, ((u_short *) userPtr)++);
- data ^= 0x8000;
- *righth++ = data >> 8;
- *rightl++ = (data >> 2) & 0x3f;
- count--;
- }
- }
- *frameUsed += used;
- return (used);
+ if (!sound.soft.stereo) {
+ char *p = &frame[*frameUsed];
+ count = min(userCount, frameLeft) & ~1;
+ used = count;
+ while (count > 0) {
+ u_char data;
+ get_user(data, userPtr++);
+ *p++ = data ^ 0x80;
+ count--;
+ }
+ } else {
+ u_char *left = &frame[*frameUsed>>1];
+ u_char *right = left+sq.block_size_half;
+ count = min(userCount, frameLeft)>>1 & ~1;
+ used = count*2;
+ while (count > 0) {
+ u_char data;
+ get_user(data, userPtr++);
+ *left++ = data ^ 0x80;
+ get_user(data, userPtr++);
+ *right++ = data ^ 0x80;
+ count--;
+ }
+ }
+ *frameUsed += used;
+ return(used);
+}
+
+
+static long ami_ct_s16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
+{
+ long count, used;
+ u_long data;
+
+ if (!sound.soft.stereo) {
+ u_char *high = &frame[*frameUsed>>1];
+ u_char *low = high+sq.block_size_half;
+ count = min(userCount, frameLeft)>>1 & ~1;
+ used = count*2;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ *high++ = data>>8;
+ *low++ = (data>>2) & 0x3f;
+ count--;
+ }
+ } else {
+ u_char *lefth = &frame[*frameUsed>>2];
+ u_char *leftl = lefth+sq.block_size_quarter;
+ u_char *righth = lefth+sq.block_size_half;
+ u_char *rightl = righth+sq.block_size_quarter;
+ count = min(userCount, frameLeft)>>2 & ~1;
+ used = count*4;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ *lefth++ = data>>8;
+ *leftl++ = (data>>2) & 0x3f;
+ get_user(data, ((u_short *)userPtr)++);
+ *righth++ = data>>8;
+ *rightl++ = (data>>2) & 0x3f;
+ count--;
+ }
+ }
+ *frameUsed += used;
+ return(used);
+}
+
+
+static long ami_ct_u16be(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
+{
+ long count, used;
+ u_long data;
+
+ if (!sound.soft.stereo) {
+ u_char *high = &frame[*frameUsed>>1];
+ u_char *low = high+sq.block_size_half;
+ count = min(userCount, frameLeft)>>1 & ~1;
+ used = count*2;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ data ^= 0x8000;
+ *high++ = data>>8;
+ *low++ = (data>>2) & 0x3f;
+ count--;
+ }
+ } else {
+ u_char *lefth = &frame[*frameUsed>>2];
+ u_char *leftl = lefth+sq.block_size_quarter;
+ u_char *righth = lefth+sq.block_size_half;
+ u_char *rightl = righth+sq.block_size_quarter;
+ count = min(userCount, frameLeft)>>2 & ~1;
+ used = count*4;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ data ^= 0x8000;
+ *lefth++ = data>>8;
+ *leftl++ = (data>>2) & 0x3f;
+ get_user(data, ((u_short *)userPtr)++);
+ data ^= 0x8000;
+ *righth++ = data>>8;
+ *rightl++ = (data>>2) & 0x3f;
+ count--;
+ }
+ }
+ *frameUsed += used;
+ return(used);
}
-static long
-ami_ct_s16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ami_ct_s16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- long count, used;
- u_long data;
-
- if (!sound.soft.stereo)
- {
- u_char *high = &frame[*frameUsed >> 1];
- u_char *low = high + sq.block_size_half;
+ long count, used;
+ u_long data;
- count = min(userCount, frameLeft) >> 1 & ~1;
- used = count * 2;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- data = le2be16(data);
- *high++ = data >> 8;
- *low++ = (data >> 2) & 0x3f;
- count--;
- }
- } else
- {
- u_char *lefth = &frame[*frameUsed >> 2];
- u_char *leftl = lefth + sq.block_size_quarter;
- u_char *righth = lefth + sq.block_size_half;
- u_char *rightl = righth + sq.block_size_quarter;
-
- count = min(userCount, frameLeft) >> 2 & ~1;
- used = count * 4;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- data = le2be16(data);
- *lefth++ = data >> 8;
- *leftl++ = (data >> 2) & 0x3f;
- get_user(data, ((u_short *) userPtr)++);
- data = le2be16(data);
- *righth++ = data >> 8;
- *rightl++ = (data >> 2) & 0x3f;
- count--;
- }
- }
- *frameUsed += used;
- return (used);
+ if (!sound.soft.stereo) {
+ u_char *high = &frame[*frameUsed>>1];
+ u_char *low = high+sq.block_size_half;
+ count = min(userCount, frameLeft)>>1 & ~1;
+ used = count*2;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ data = le2be16(data);
+ *high++ = data>>8;
+ *low++ = (data>>2) & 0x3f;
+ count--;
+ }
+ } else {
+ u_char *lefth = &frame[*frameUsed>>2];
+ u_char *leftl = lefth+sq.block_size_quarter;
+ u_char *righth = lefth+sq.block_size_half;
+ u_char *rightl = righth+sq.block_size_quarter;
+ count = min(userCount, frameLeft)>>2 & ~1;
+ used = count*4;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ data = le2be16(data);
+ *lefth++ = data>>8;
+ *leftl++ = (data>>2) & 0x3f;
+ get_user(data, ((u_short *)userPtr)++);
+ data = le2be16(data);
+ *righth++ = data>>8;
+ *rightl++ = (data>>2) & 0x3f;
+ count--;
+ }
+ }
+ *frameUsed += used;
+ return(used);
}
-static long
-ami_ct_u16le(const u_char * userPtr, unsigned long userCount,
- u_char frame[], long *frameUsed, long frameLeft)
+static long ami_ct_u16le(const u_char *userPtr, unsigned long userCount,
+ u_char frame[], long *frameUsed, long frameLeft)
{
- long count, used;
- u_long data;
-
- if (!sound.soft.stereo)
- {
- u_char *high = &frame[*frameUsed >> 1];
- u_char *low = high + sq.block_size_half;
+ long count, used;
+ u_long data;
- count = min(userCount, frameLeft) >> 1 & ~1;
- used = count * 2;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- data = le2be16(data) ^ 0x8000;
- *high++ = data >> 8;
- *low++ = (data >> 2) & 0x3f;
- count--;
- }
- } else
- {
- u_char *lefth = &frame[*frameUsed >> 2];
- u_char *leftl = lefth + sq.block_size_quarter;
- u_char *righth = lefth + sq.block_size_half;
- u_char *rightl = righth + sq.block_size_quarter;
-
- count = min(userCount, frameLeft) >> 2 & ~1;
- used = count * 4;
- while (count > 0)
- {
- get_user(data, ((u_short *) userPtr)++);
- data = le2be16(data) ^ 0x8000;
- *lefth++ = data >> 8;
- *leftl++ = (data >> 2) & 0x3f;
- get_user(data, ((u_short *) userPtr)++);
- data = le2be16(data) ^ 0x8000;
- *righth++ = data >> 8;
- *rightl++ = (data >> 2) & 0x3f;
- count--;
- }
- }
- *frameUsed += used;
- return (used);
+ if (!sound.soft.stereo) {
+ u_char *high = &frame[*frameUsed>>1];
+ u_char *low = high+sq.block_size_half;
+ count = min(userCount, frameLeft)>>1 & ~1;
+ used = count*2;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ data = le2be16(data) ^ 0x8000;
+ *high++ = data>>8;
+ *low++ = (data>>2) & 0x3f;
+ count--;
+ }
+ } else {
+ u_char *lefth = &frame[*frameUsed>>2];
+ u_char *leftl = lefth+sq.block_size_quarter;
+ u_char *righth = lefth+sq.block_size_half;
+ u_char *rightl = righth+sq.block_size_quarter;
+ count = min(userCount, frameLeft)>>2 & ~1;
+ used = count*4;
+ while (count > 0) {
+ get_user(data, ((u_short *)userPtr)++);
+ data = le2be16(data) ^ 0x8000;
+ *lefth++ = data>>8;
+ *leftl++ = (data>>2) & 0x3f;
+ get_user(data, ((u_short *)userPtr)++);
+ data = le2be16(data) ^ 0x8000;
+ *righth++ = data>>8;
+ *rightl++ = (data>>2) & 0x3f;
+ count--;
+ }
+ }
+ *frameUsed += used;
+ return(used);
}
-#endif /* CONFIG_AMIGA */
+#endif /* CONFIG_AMIGA */
#ifdef CONFIG_ATARI
-static TRANS transTTNormal =
-{
- ata_ct_law, ata_ct_law, ata_ct_s8, ata_ct_u8, NULL, NULL, NULL, NULL
+static TRANS transTTNormal = {
+ ata_ct_law, ata_ct_law, ata_ct_s8, ata_ct_u8, NULL, NULL, NULL, NULL
};
-static TRANS transTTExpanding =
-{
- ata_ctx_law, ata_ctx_law, ata_ctx_s8, ata_ctx_u8, NULL, NULL, NULL, NULL
+static TRANS transTTExpanding = {
+ ata_ctx_law, ata_ctx_law, ata_ctx_s8, ata_ctx_u8, NULL, NULL, NULL, NULL
};
-static TRANS transFalconNormal =
-{
-ata_ct_law, ata_ct_law, ata_ct_s8, ata_ct_u8, ata_ct_s16be, ata_ct_u16be,
- ata_ct_s16le, ata_ct_u16le
+static TRANS transFalconNormal = {
+ ata_ct_law, ata_ct_law, ata_ct_s8, ata_ct_u8, ata_ct_s16be, ata_ct_u16be,
+ ata_ct_s16le, ata_ct_u16le
};
-static TRANS transFalconExpanding =
-{
- ata_ctx_law, ata_ctx_law, ata_ctx_s8, ata_ctx_u8, ata_ctx_s16be,
- ata_ctx_u16be, ata_ctx_s16le, ata_ctx_u16le
+static TRANS transFalconExpanding = {
+ ata_ctx_law, ata_ctx_law, ata_ctx_s8, ata_ctx_u8, ata_ctx_s16be,
+ ata_ctx_u16be, ata_ctx_s16le, ata_ctx_u16le
};
-
-#endif /* CONFIG_ATARI */
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
-static TRANS transAmiga =
-{
-ami_ct_law, ami_ct_law, ami_ct_s8, ami_ct_u8, ami_ct_s16be, ami_ct_u16be,
- ami_ct_s16le, ami_ct_u16le
+static TRANS transAmiga = {
+ ami_ct_law, ami_ct_law, ami_ct_s8, ami_ct_u8, ami_ct_s16be, ami_ct_u16be,
+ ami_ct_s16le, ami_ct_u16le
};
-
-#endif /* CONFIG_AMIGA */
+#endif /* CONFIG_AMIGA */
/*** Low level stuff *********************************************************/
@@ -1774,68 +1581,44 @@ ami_ct_law, ami_ct_law, ami_ct_s8, ami_ct_u8, ami_ct_s16be, ami_ct_u16be,
* Atari (TT/Falcon)
*/
-static void *
-AtaAlloc(unsigned int size, int flags)
-{
- int order;
- unsigned int a_size;
-
- order = 0;
- a_size = PAGE_SIZE;
- while (a_size < size)
- {
- order++;
- a_size <<= 1;
- }
- return (void *) __get_dma_pages(flags, order);
-}
-
-static void
-AtaFree(void *obj, unsigned int size)
-{
- int order;
- unsigned int a_size;
-
- order = 0;
- a_size = PAGE_SIZE;
- while (a_size < size)
- {
- order++;
- a_size <<= 1;
- }
- free_pages((unsigned long) obj, order);
-}
-
-static int
-AtaIrqInit(void)
-{
- /* Set up timer A. Timer A
- will receive a signal upon end of playing from the sound
- hardware. Furthermore Timer A is able to count events
- and will cause an interrupt after a programmed number
- of events. So all we need to keep the music playing is
- to provide the sound hardware with new data upon
- an interrupt from timer A. */
- mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */
- mfp.tim_dt_a = 1; /* Cause interrupt after first event. */
- mfp.tim_ct_a = 8; /* Turn on event counting. */
- /* Register interrupt handler. */
- request_irq(IRQ_MFP_TIMA, ata_sq_interrupt, IRQ_TYPE_SLOW,
- "DMA sound", ata_sq_interrupt);
- mfp.int_en_a |= 0x20; /* Turn interrupt on. */
- mfp.int_mk_a |= 0x20;
- return (1);
+static void *AtaAlloc(unsigned int size, int flags)
+{
+ return( atari_stram_alloc( size, NULL, "dmasound" ));
+}
+
+static void AtaFree(void *obj, unsigned int size)
+{
+ atari_stram_free( obj );
+}
+
+static int AtaIrqInit(void)
+{
+ /* Set up timer A. Timer A
+ will receive a signal upon end of playing from the sound
+ hardware. Furthermore Timer A is able to count events
+ and will cause an interrupt after a programmed number
+ of events. So all we need to keep the music playing is
+ to provide the sound hardware with new data upon
+ an interrupt from timer A. */
+ mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */
+ mfp.tim_dt_a = 1; /* Cause interrupt after first event. */
+ mfp.tim_ct_a = 8; /* Turn on event counting. */
+ /* Register interrupt handler. */
+ request_irq(IRQ_MFP_TIMA, ata_sq_interrupt, IRQ_TYPE_SLOW,
+ "DMA sound", ata_sq_interrupt);
+ mfp.int_en_a |= 0x20; /* Turn interrupt on. */
+ mfp.int_mk_a |= 0x20;
+ return(1);
}
#ifdef MODULE
-static void
-AtaIrqCleanUp(void)
+static void AtaIrqCleanUp(void)
{
- mfp.tim_ct_a = 0; /* stop timer */
- mfp.int_en_a &= ~0x20; /* turn interrupt off */
- free_irq(IRQ_MFP_TIMA, ata_sq_interrupt);
+ mfp.tim_ct_a = 0; /* stop timer */
+ mfp.int_en_a &= ~0x20; /* turn interrupt off */
+ free_irq(IRQ_MFP_TIMA, ata_sq_interrupt);
}
-#endif /* MODULE */
+#endif /* MODULE */
#define TONE_VOXWARE_TO_DB(v) \
@@ -1843,21 +1626,19 @@ AtaIrqCleanUp(void)
#define TONE_DB_TO_VOXWARE(v) (((v) * 25 + ((v) > 0 ? 5 : -5)) / 6 + 50)
-static int
-AtaSetBass(int bass)
+static int AtaSetBass(int bass)
{
- sound.bass = TONE_VOXWARE_TO_DB(bass);
- atari_microwire_cmd(MW_LM1992_BASS(sound.bass));
- return (TONE_DB_TO_VOXWARE(sound.bass));
+ sound.bass = TONE_VOXWARE_TO_DB(bass);
+ atari_microwire_cmd(MW_LM1992_BASS(sound.bass));
+ return(TONE_DB_TO_VOXWARE(sound.bass));
}
-static int
-AtaSetTreble(int treble)
+static int AtaSetTreble(int treble)
{
- sound.treble = TONE_VOXWARE_TO_DB(treble);
- atari_microwire_cmd(MW_LM1992_TREBLE(sound.treble));
- return (TONE_DB_TO_VOXWARE(sound.treble));
+ sound.treble = TONE_VOXWARE_TO_DB(treble);
+ atari_microwire_cmd(MW_LM1992_TREBLE(sound.treble));
+ return(TONE_DB_TO_VOXWARE(sound.treble));
}
@@ -1867,117 +1648,116 @@ AtaSetTreble(int treble)
*/
-static void
-TTSilence(void)
+static void TTSilence(void)
{
- tt_dmasnd.ctrl = DMASND_CTRL_OFF;
- atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
+ tt_dmasnd.ctrl = DMASND_CTRL_OFF;
+ atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
}
-static void
-TTInit(void)
+static void TTInit(void)
{
- int mode, i, idx;
- const int freq[4] =
- {50066, 25033, 12517, 6258};
-
- /* search a frequency that fits into the allowed error range */
+ int mode, i, idx;
+ const int freq[4] = {50066, 25033, 12517, 6258};
- idx = -1;
- for (i = 0; i < arraysize(freq); i++)
- /* this isn't as much useful for a TT than for a Falcon, but
- * then it doesn't hurt very much to implement it for a TT too.
- */
- if ((100 * abs(sound.soft.speed - freq[i]) / freq[i]) < catchRadius)
- idx = i;
- if (idx > -1)
- {
- sound.soft.speed = freq[idx];
- sound.trans = &transTTNormal;
- } else
- sound.trans = &transTTExpanding;
-
- TTSilence();
- sound.hard = sound.soft;
-
- if (sound.hard.speed > 50066)
- {
- /* we would need to squeeze the sound, but we won't do that */
- sound.hard.speed = 50066;
- mode = DMASND_MODE_50KHZ;
- sound.trans = &transTTNormal;
- } else if (sound.hard.speed > 25033)
- {
- sound.hard.speed = 50066;
- mode = DMASND_MODE_50KHZ;
- } else if (sound.hard.speed > 12517)
- {
- sound.hard.speed = 25033;
- mode = DMASND_MODE_25KHZ;
- } else if (sound.hard.speed > 6258)
- {
- sound.hard.speed = 12517;
- mode = DMASND_MODE_12KHZ;
- } else
- {
- sound.hard.speed = 6258;
- mode = DMASND_MODE_6KHZ;
- }
+ /* search a frequency that fits into the allowed error range */
- tt_dmasnd.mode = (sound.hard.stereo ?
- DMASND_MODE_STEREO : DMASND_MODE_MONO) |
- DMASND_MODE_8BIT | mode;
+ idx = -1;
+ for (i = 0; i < arraysize(freq); i++)
+ /* this isn't as much useful for a TT than for a Falcon, but
+ * then it doesn't hurt very much to implement it for a TT too.
+ */
+ if ((100 * abs(sound.soft.speed - freq[i]) / freq[i]) < catchRadius)
+ idx = i;
+ if (idx > -1) {
+ sound.soft.speed = freq[idx];
+ sound.trans = &transTTNormal;
+ } else
+ sound.trans = &transTTExpanding;
+
+ TTSilence();
+ sound.hard = sound.soft;
+
+ if (sound.hard.speed > 50066) {
+ /* we would need to squeeze the sound, but we won't do that */
+ sound.hard.speed = 50066;
+ mode = DMASND_MODE_50KHZ;
+ sound.trans = &transTTNormal;
+ } else if (sound.hard.speed > 25033) {
+ sound.hard.speed = 50066;
+ mode = DMASND_MODE_50KHZ;
+ } else if (sound.hard.speed > 12517) {
+ sound.hard.speed = 25033;
+ mode = DMASND_MODE_25KHZ;
+ } else if (sound.hard.speed > 6258) {
+ sound.hard.speed = 12517;
+ mode = DMASND_MODE_12KHZ;
+ } else {
+ sound.hard.speed = 6258;
+ mode = DMASND_MODE_6KHZ;
+ }
+
+ tt_dmasnd.mode = (sound.hard.stereo ?
+ DMASND_MODE_STEREO : DMASND_MODE_MONO) |
+ DMASND_MODE_8BIT | mode;
+
+ sound.bal = -sound.soft.speed;
+}
+
+
+static int TTSetFormat(int format)
+{
+ /* TT sound DMA supports only 8bit modes */
+
+ switch (format) {
+ case AFMT_QUERY:
+ return(sound.soft.format);
+ case AFMT_MU_LAW:
+ case AFMT_A_LAW:
+ case AFMT_S8:
+ case AFMT_U8:
+ break;
+ default:
+ format = AFMT_S8;
+ }
+
+ sound.soft.format = format;
+ sound.soft.size = 8;
+ if (sound.minDev == SND_DEV_DSP) {
+ sound.dsp.format = format;
+ sound.dsp.size = 8;
+ }
+ TTInit();
- sound.bal = -sound.soft.speed;
+ return(format);
}
-static int
-TTSetFormat(int format)
-{
- /* TT sound DMA supports only 8bit modes */
-
- switch (format)
- {
- case AFMT_QUERY:
- return (sound.soft.format);
- case AFMT_MU_LAW:
- case AFMT_A_LAW:
- case AFMT_S8:
- case AFMT_U8:
- break;
- default:
- format = AFMT_S8;
- }
+#define VOLUME_VOXWARE_TO_DB(v) \
+ (((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
+#define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
- sound.soft.format = format;
- sound.soft.size = 8;
- if (sound.minDev == SND_DEV_DSP)
- {
- sound.dsp.format = format;
- sound.dsp.size = 8;
- }
- TTInit();
- return (format);
+static int TTSetVolume(int volume)
+{
+ sound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
+ atari_microwire_cmd(MW_LM1992_BALLEFT(sound.volume_left));
+ sound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
+ atari_microwire_cmd(MW_LM1992_BALRIGHT(sound.volume_right));
+ return(VOLUME_DB_TO_VOXWARE(sound.volume_left) |
+ (VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8));
}
-#define VOLUME_VOXWARE_TO_DB(v) \
- (((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
-#define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
-
+#define GAIN_VOXWARE_TO_DB(v) \
+ (((v) < 0) ? -80 : ((v) > 100) ? 0 : ((v) * 4) / 5 - 80)
+#define GAIN_DB_TO_VOXWARE(v) ((((v) + 80) * 5 + 1) / 4)
-static int
-TTSetVolume(int volume)
+static int TTSetGain(int gain)
{
- sound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
- atari_microwire_cmd(MW_LM1992_BALLEFT(sound.volume_left));
- sound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
- atari_microwire_cmd(MW_LM1992_BALRIGHT(sound.volume_right));
- return (VOLUME_DB_TO_VOXWARE(sound.volume_left) |
- (VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8));
+ sound.gain = GAIN_VOXWARE_TO_DB(gain);
+ atari_microwire_cmd(MW_LM1992_VOLUME(sound.gain));
+ return GAIN_DB_TO_VOXWARE(sound.gain);
}
@@ -1987,151 +1767,135 @@ TTSetVolume(int volume)
*/
-static void
-FalconSilence(void)
+static void FalconSilence(void)
{
- /* stop playback, set sample rate 50kHz for PSG sound */
- tt_dmasnd.ctrl = DMASND_CTRL_OFF;
- tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
- tt_dmasnd.int_div = 0; /* STE compatible divider */
- tt_dmasnd.int_ctrl = 0x0;
- tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
- tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
- tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
- tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
+ /* stop playback, set sample rate 50kHz for PSG sound */
+ tt_dmasnd.ctrl = DMASND_CTRL_OFF;
+ tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
+ tt_dmasnd.int_div = 0; /* STE compatible divider */
+ tt_dmasnd.int_ctrl = 0x0;
+ tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
+ tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
+ tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
+ tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
}
-static void
-FalconInit(void)
+static void FalconInit(void)
{
- int divider, i, idx;
- const int freq[8] =
- {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
+ int divider, i, idx;
+ const int freq[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
- /* search a frequency that fits into the allowed error range */
+ /* search a frequency that fits into the allowed error range */
- idx = -1;
- for (i = 0; i < arraysize(freq); i++)
- /* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
- * be playable without expanding, but that now a kernel runtime
- * option
- */
- if ((100 * abs(sound.soft.speed - freq[i]) / freq[i]) < catchRadius)
- idx = i;
- if (idx > -1)
- {
- sound.soft.speed = freq[idx];
- sound.trans = &transFalconNormal;
- } else
- sound.trans = &transFalconExpanding;
-
- FalconSilence();
- sound.hard = sound.soft;
-
- if (sound.hard.size == 16)
- {
- /* the Falcon can play 16bit samples only in stereo */
- sound.hard.stereo = 1;
- }
- if (sound.hard.speed > 49170)
- {
- /* we would need to squeeze the sound, but we won't do that */
- sound.hard.speed = 49170;
- divider = 1;
- sound.trans = &transFalconNormal;
- } else if (sound.hard.speed > 32780)
- {
- sound.hard.speed = 49170;
- divider = 1;
- } else if (sound.hard.speed > 24585)
- {
- sound.hard.speed = 32780;
- divider = 2;
- } else if (sound.hard.speed > 19668)
- {
- sound.hard.speed = 24585;
- divider = 3;
- } else if (sound.hard.speed > 16390)
- {
- sound.hard.speed = 19668;
- divider = 4;
- } else if (sound.hard.speed > 12292)
- {
- sound.hard.speed = 16390;
- divider = 5;
- } else if (sound.hard.speed > 9834)
- {
- sound.hard.speed = 12292;
- divider = 7;
- } else if (sound.hard.speed > 8195)
- {
- sound.hard.speed = 9834;
- divider = 9;
- } else
- {
- sound.hard.speed = 8195;
- divider = 11;
- }
- tt_dmasnd.int_div = divider;
-
- /* Setup Falcon sound DMA for playback */
- tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
- tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
- tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
- tt_dmasnd.cbar_dst = 0x0000;
- tt_dmasnd.rec_track_select = 0;
- tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
- tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
-
- tt_dmasnd.mode = (sound.hard.stereo ?
- DMASND_MODE_STEREO : DMASND_MODE_MONO) |
- ((sound.hard.size == 8) ?
- DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
- DMASND_MODE_6KHZ;
-
- sound.bal = -sound.soft.speed;
-}
-
-
-static int
-FalconSetFormat(int format)
-{
- int size;
-
- /* Falcon sound DMA supports 8bit and 16bit modes */
-
- switch (format)
- {
- case AFMT_QUERY:
- return (sound.soft.format);
- case AFMT_MU_LAW:
- case AFMT_A_LAW:
- case AFMT_U8:
- case AFMT_S8:
- size = 8;
- break;
- case AFMT_S16_BE:
- case AFMT_U16_BE:
- case AFMT_S16_LE:
- case AFMT_U16_LE:
- size = 16;
- break;
- default: /* :-) */
- size = 8;
- format = AFMT_S8;
- }
-
- sound.soft.format = format;
- sound.soft.size = size;
- if (sound.minDev == SND_DEV_DSP)
- {
- sound.dsp.format = format;
- sound.dsp.size = sound.soft.size;
- }
- FalconInit();
-
- return (format);
+ idx = -1;
+ for (i = 0; i < arraysize(freq); i++)
+ /* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
+ * be playable without expanding, but that now a kernel runtime
+ * option
+ */
+ if ((100 * abs(sound.soft.speed - freq[i]) / freq[i]) < catchRadius)
+ idx = i;
+ if (idx > -1) {
+ sound.soft.speed = freq[idx];
+ sound.trans = &transFalconNormal;
+ } else
+ sound.trans = &transFalconExpanding;
+
+ FalconSilence();
+ sound.hard = sound.soft;
+
+ if (sound.hard.size == 16) {
+ /* the Falcon can play 16bit samples only in stereo */
+ sound.hard.stereo = 1;
+ }
+
+ if (sound.hard.speed > 49170) {
+ /* we would need to squeeze the sound, but we won't do that */
+ sound.hard.speed = 49170;
+ divider = 1;
+ sound.trans = &transFalconNormal;
+ } else if (sound.hard.speed > 32780) {
+ sound.hard.speed = 49170;
+ divider = 1;
+ } else if (sound.hard.speed > 24585) {
+ sound.hard.speed = 32780;
+ divider = 2;
+ } else if (sound.hard.speed > 19668) {
+ sound.hard.speed = 24585;
+ divider = 3;
+ } else if (sound.hard.speed > 16390) {
+ sound.hard.speed = 19668;
+ divider = 4;
+ } else if (sound.hard.speed > 12292) {
+ sound.hard.speed = 16390;
+ divider = 5;
+ } else if (sound.hard.speed > 9834) {
+ sound.hard.speed = 12292;
+ divider = 7;
+ } else if (sound.hard.speed > 8195) {
+ sound.hard.speed = 9834;
+ divider = 9;
+ } else {
+ sound.hard.speed = 8195;
+ divider = 11;
+ }
+ tt_dmasnd.int_div = divider;
+
+ /* Setup Falcon sound DMA for playback */
+ tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
+ tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
+ tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
+ tt_dmasnd.cbar_dst = 0x0000;
+ tt_dmasnd.rec_track_select = 0;
+ tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
+ tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
+
+ tt_dmasnd.mode = (sound.hard.stereo ?
+ DMASND_MODE_STEREO : DMASND_MODE_MONO) |
+ ((sound.hard.size == 8) ?
+ DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
+ DMASND_MODE_6KHZ;
+
+ sound.bal = -sound.soft.speed;
+}
+
+
+static int FalconSetFormat(int format)
+{
+ int size;
+ /* Falcon sound DMA supports 8bit and 16bit modes */
+
+ switch (format) {
+ case AFMT_QUERY:
+ return(sound.soft.format);
+ case AFMT_MU_LAW:
+ case AFMT_A_LAW:
+ case AFMT_U8:
+ case AFMT_S8:
+ size = 8;
+ break;
+ case AFMT_S16_BE:
+ case AFMT_U16_BE:
+ case AFMT_S16_LE:
+ case AFMT_U16_LE:
+ size = 16;
+ break;
+ default: /* :-) */
+ size = 8;
+ format = AFMT_S8;
+ }
+
+ sound.soft.format = format;
+ sound.soft.size = size;
+ if (sound.minDev == SND_DEV_DSP) {
+ sound.dsp.format = format;
+ sound.dsp.size = sound.soft.size;
+ }
+
+ FalconInit();
+
+ return(format);
}
@@ -2143,181 +1907,168 @@ FalconSetFormat(int format)
#define VOLUME_ATT_TO_VOXWARE(v) (100 - (v) * 20 / 3)
-static int
-FalconSetVolume(int volume)
+static int FalconSetVolume(int volume)
{
- sound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
- sound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
- tt_dmasnd.output_atten = sound.volume_left << 8 | sound.volume_right << 4;
- return (VOLUME_ATT_TO_VOXWARE(sound.volume_left) |
- VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8);
+ sound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
+ sound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
+ tt_dmasnd.output_atten = sound.volume_left << 8 | sound.volume_right << 4;
+ return(VOLUME_ATT_TO_VOXWARE(sound.volume_left) |
+ VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8);
}
-static void
-ata_sq_play_next_frame(int index)
+static void ata_sq_play_next_frame(int index)
{
- char *start, *end;
+ char *start, *end;
- /* used by AtaPlay() if all doubts whether there really is something
- * to be played are already wiped out.
- */
- start = sq_block_address(sq.front);
- end = start + ((sq.count == index) ? sq.rear_size : sq.block_size);
- /* end might not be a legal virtual address. */
- DMASNDSetEnd(VTOP(end - 1) + 1);
- DMASNDSetBase(VTOP(start));
+ /* used by AtaPlay() if all doubts whether there really is something
+ * to be played are already wiped out.
+ */
+ start = sq_block_address(sq.front);
+ end = start+((sq.count == index) ? sq.rear_size : sq.block_size);
+ /* end might not be a legal virtual address. */
+ DMASNDSetEnd(VTOP(end - 1) + 1);
+ DMASNDSetBase(VTOP(start));
/* Since only an even number of samples per frame can
- be played, we might lose one byte here. (TO DO) */
- sq.front = (sq.front + 1) % sq.max_count;
- sq.playing++;
- tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
-}
-
-
-static void
-AtaPlay(void)
-{
- /* ++TeSche: Note that sq.playing is no longer just a flag but holds
- * the number of frames the DMA is currently programmed for instead,
- * may be 0, 1 (currently being played) or 2 (pre-programmed).
- *
- * Changes done to sq.count and sq.playing are a bit more subtle again
- * so now I must admit I also prefer disabling the irq here rather
- * than considering all possible situations. But the point is that
- * disabling the irq doesn't have any bad influence on this version of
- * the driver as we benefit from having pre-programmed the DMA
- * wherever possible: There's no need to reload the DMA at the exact
- * time of an interrupt but only at some time while the pre-programmed
- * frame is playing!
- */
- atari_disable_irq(IRQ_MFP_TIMA);
-
- if (sq.playing == 2 || /* DMA is 'full' */
- sq.count <= 0)
- { /* nothing to do */
- atari_enable_irq(IRQ_MFP_TIMA);
- return;
- }
- if (sq.playing == 0)
- {
- /* looks like there's nothing 'in' the DMA yet, so try
- * to put two frames into it (at least one is available).
- */
- if (sq.count == 1 && sq.rear_size < sq.block_size && !sq.syncing)
- {
- /* hmmm, the only existing frame is not
- * yet filled and we're not syncing?
- */
- atari_enable_irq(IRQ_MFP_TIMA);
- return;
- }
- ata_sq_play_next_frame(1);
- if (sq.count == 1)
- {
- /* no more frames */
- atari_enable_irq(IRQ_MFP_TIMA);
- return;
- }
- if (sq.count == 2 && sq.rear_size < sq.block_size && !sq.syncing)
- {
- /* hmmm, there were two frames, but the second
- * one is not yet filled and we're not syncing?
- */
- atari_enable_irq(IRQ_MFP_TIMA);
- return;
- }
- ata_sq_play_next_frame(2);
- } else
- {
- /* there's already a frame being played so we may only stuff
- * one new into the DMA, but even if this may be the last
- * frame existing the previous one is still on sq.count.
- */
- if (sq.count == 2 && sq.rear_size < sq.block_size && !sq.syncing)
- {
- /* hmmm, the only existing frame is not
- * yet filled and we're not syncing?
- */
- atari_enable_irq(IRQ_MFP_TIMA);
- return;
- }
- ata_sq_play_next_frame(2);
- }
+ be played, we might lose one byte here. (TO DO) */
+ sq.front = (sq.front+1) % sq.max_count;
+ sq.playing++;
+ tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
+}
+
+
+static void AtaPlay(void)
+{
+ /* ++TeSche: Note that sq.playing is no longer just a flag but holds
+ * the number of frames the DMA is currently programmed for instead,
+ * may be 0, 1 (currently being played) or 2 (pre-programmed).
+ *
+ * Changes done to sq.count and sq.playing are a bit more subtle again
+ * so now I must admit I also prefer disabling the irq here rather
+ * than considering all possible situations. But the point is that
+ * disabling the irq doesn't have any bad influence on this version of
+ * the driver as we benefit from having pre-programmed the DMA
+ * wherever possible: There's no need to reload the DMA at the exact
+ * time of an interrupt but only at some time while the pre-programmed
+ * frame is playing!
+ */
+ atari_disable_irq(IRQ_MFP_TIMA);
+
+ if (sq.playing == 2 || /* DMA is 'full' */
+ sq.count <= 0) { /* nothing to do */
atari_enable_irq(IRQ_MFP_TIMA);
+ return;
+ }
+
+ if (sq.playing == 0) {
+ /* looks like there's nothing 'in' the DMA yet, so try
+ * to put two frames into it (at least one is available).
+ */
+ if (sq.count == 1 && sq.rear_size < sq.block_size && !sq.syncing) {
+ /* hmmm, the only existing frame is not
+ * yet filled and we're not syncing?
+ */
+ atari_enable_irq(IRQ_MFP_TIMA);
+ return;
+ }
+ ata_sq_play_next_frame(1);
+ if (sq.count == 1) {
+ /* no more frames */
+ atari_enable_irq(IRQ_MFP_TIMA);
+ return;
+ }
+ if (sq.count == 2 && sq.rear_size < sq.block_size && !sq.syncing) {
+ /* hmmm, there were two frames, but the second
+ * one is not yet filled and we're not syncing?
+ */
+ atari_enable_irq(IRQ_MFP_TIMA);
+ return;
+ }
+ ata_sq_play_next_frame(2);
+ } else {
+ /* there's already a frame being played so we may only stuff
+ * one new into the DMA, but even if this may be the last
+ * frame existing the previous one is still on sq.count.
+ */
+ if (sq.count == 2 && sq.rear_size < sq.block_size && !sq.syncing) {
+ /* hmmm, the only existing frame is not
+ * yet filled and we're not syncing?
+ */
+ atari_enable_irq(IRQ_MFP_TIMA);
+ return;
+ }
+ ata_sq_play_next_frame(2);
+ }
+ atari_enable_irq(IRQ_MFP_TIMA);
}
-static void
-ata_sq_interrupt(int irq, void *dummy, struct pt_regs *fp)
+static void ata_sq_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
#if 0
- /* ++TeSche: if you should want to test this... */
- static int cnt = 0;
-
- if (sq.playing == 2)
- if (++cnt == 10)
- {
- /* simulate losing an interrupt */
- cnt = 0;
- return;
- }
+ /* ++TeSche: if you should want to test this... */
+ static int cnt = 0;
+ if (sq.playing == 2)
+ if (++cnt == 10) {
+ /* simulate losing an interrupt */
+ cnt = 0;
+ return;
+ }
#endif
- if (sq.ignore_int && (sound.mach.type == DMASND_FALCON))
- {
- /* ++TeSche: Falcon only: ignore first irq because it comes
- * immediately after starting a frame. after that, irqs come
- * (almost) like on the TT.
- */
- sq.ignore_int = 0;
- return;
- }
- if (!sq.playing)
- {
- /* playing was interrupted and sq_reset() has already cleared
- * the sq variables, so better don't do anything here.
- */
- WAKE_UP(sq.sync_queue);
- return;
- }
- /* Probably ;) one frame is finished. Well, in fact it may be that a
- * pre-programmed one is also finished because there has been a long
- * delay in interrupt delivery and we've completely lost one, but
- * there's no way to detect such a situation. In such a case the last
- * frame will be played more than once and the situation will recover
- * as soon as the irq gets through.
+ if (sq.ignore_int && (sound.mach.type == DMASND_FALCON)) {
+ /* ++TeSche: Falcon only: ignore first irq because it comes
+ * immediately after starting a frame. after that, irqs come
+ * (almost) like on the TT.
*/
- sq.count--;
- sq.playing--;
+ sq.ignore_int = 0;
+ return;
+ }
- if (!sq.playing)
- {
- tt_dmasnd.ctrl = DMASND_CTRL_OFF;
- sq.ignore_int = 1;
- }
- WAKE_UP(sq.write_queue);
+ if (!sq.playing) {
+ /* playing was interrupted and sq_reset() has already cleared
+ * the sq variables, so better don't do anything here.
+ */
+ WAKE_UP(sq.sync_queue);
+ return;
+ }
+
+ /* Probably ;) one frame is finished. Well, in fact it may be that a
+ * pre-programmed one is also finished because there has been a long
+ * delay in interrupt delivery and we've completely lost one, but
+ * there's no way to detect such a situation. In such a case the last
+ * frame will be played more than once and the situation will recover
+ * as soon as the irq gets through.
+ */
+ sq.count--;
+ sq.playing--;
+
+ if (!sq.playing) {
+ tt_dmasnd.ctrl = DMASND_CTRL_OFF;
+ sq.ignore_int = 1;
+ }
+
+ WAKE_UP(sq.write_queue);
/* At least one block of the queue is free now
- so wake up a writing process blocked because
- of a full queue. */
-
- if ((sq.playing != 1) || (sq.count != 1))
- /* We must be a bit carefully here: sq.count indicates the
- * number of buffers used and not the number of frames to
- * be played. If sq.count==1 and sq.playing==1 that means
- * the only remaining frame was already programmed earlier
- * (and is currently running) so we mustn't call AtaPlay()
- * here, otherwise we'll play one frame too much.
- */
- AtaPlay();
+ so wake up a writing process blocked because
+ of a full queue. */
+
+ if ((sq.playing != 1) || (sq.count != 1))
+ /* We must be a bit carefully here: sq.count indicates the
+ * number of buffers used and not the number of frames to
+ * be played. If sq.count==1 and sq.playing==1 that means
+ * the only remaining frame was already programmed earlier
+ * (and is currently running) so we mustn't call AtaPlay()
+ * here, otherwise we'll play one frame too much.
+ */
+ AtaPlay();
- if (!sq.playing)
- WAKE_UP(sq.sync_queue);
+ if (!sq.playing) WAKE_UP(sq.sync_queue);
/* We are not playing after AtaPlay(), so there
- is nothing to play any more. Wake up a process
- waiting for audio output to drain. */
+ is nothing to play any more. Wake up a process
+ waiting for audio output to drain. */
}
-#endif /* CONFIG_ATARI */
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
@@ -2327,120 +2078,109 @@ ata_sq_interrupt(int irq, void *dummy, struct pt_regs *fp)
*/
-static void *
-AmiAlloc(unsigned int size, int flags)
+static void *AmiAlloc(unsigned int size, int flags)
{
- return (amiga_chip_alloc((long) size));
+ return(amiga_chip_alloc((long)size));
}
-static void
-AmiFree(void *obj, unsigned int size)
+static void AmiFree(void *obj, unsigned int size)
{
- amiga_chip_free(obj);
+ amiga_chip_free (obj);
}
-static int
-AmiIrqInit(void)
+static int AmiIrqInit(void)
{
- /* turn off DMA for audio channels */
- custom.dmacon = AMI_AUDIO_OFF;
+ /* turn off DMA for audio channels */
+ custom.dmacon = AMI_AUDIO_OFF;
- /* Register interrupt handler. */
- if (request_irq(IRQ_AMIGA_AUD0, ami_sq_interrupt, 0,
- "DMA sound", ami_sq_interrupt))
- return (0);
- return (1);
+ /* Register interrupt handler. */
+ if (request_irq(IRQ_AMIGA_AUD0, ami_sq_interrupt, 0,
+ "DMA sound", ami_sq_interrupt))
+ return(0);
+ return(1);
}
#ifdef MODULE
-static void
-AmiIrqCleanUp(void)
+static void AmiIrqCleanUp(void)
{
- /* turn off DMA for audio channels */
- custom.dmacon = AMI_AUDIO_OFF;
- /* release the interrupt */
- free_irq(IRQ_AMIGA_AUD0, ami_sq_interrupt);
+ /* turn off DMA for audio channels */
+ custom.dmacon = AMI_AUDIO_OFF;
+ /* release the interrupt */
+ free_irq(IRQ_AMIGA_AUD0, ami_sq_interrupt);
}
-#endif /* MODULE */
+#endif /* MODULE */
-static void
-AmiSilence(void)
+static void AmiSilence(void)
{
- /* turn off DMA for audio channels */
- custom.dmacon = AMI_AUDIO_OFF;
+ /* turn off DMA for audio channels */
+ custom.dmacon = AMI_AUDIO_OFF;
}
-static void
-AmiInit(void)
+static void AmiInit(void)
{
- int period, i;
+ int period, i;
- AmiSilence();
+ AmiSilence();
- if (sound.soft.speed)
- period = amiga_colorclock / sound.soft.speed - 1;
- else
- period = amiga_audio_min_period;
- sound.hard = sound.soft;
- sound.trans = &transAmiga;
+ if (sound.soft.speed)
+ period = amiga_colorclock/sound.soft.speed-1;
+ else
+ period = amiga_audio_min_period;
+ sound.hard = sound.soft;
+ sound.trans = &transAmiga;
- if (period < amiga_audio_min_period)
- {
- /* we would need to squeeze the sound, but we won't do that */
- period = amiga_audio_min_period;
- } else if (period > 65535)
- {
- period = 65535;
- }
- sound.hard.speed = amiga_colorclock / (period + 1);
+ if (period < amiga_audio_min_period) {
+ /* we would need to squeeze the sound, but we won't do that */
+ period = amiga_audio_min_period;
+ } else if (period > 65535) {
+ period = 65535;
+ }
+ sound.hard.speed = amiga_colorclock/(period+1);
- for (i = 0; i < 4; i++)
- custom.aud[i].audper = period;
- amiga_audio_period = period;
+ for (i = 0; i < 4; i++)
+ custom.aud[i].audper = period;
+ amiga_audio_period = period;
- AmiSetTreble(50); /* recommended for newer amiga models */
+ AmiSetTreble(50); /* recommended for newer amiga models */
}
-static int
-AmiSetFormat(int format)
+static int AmiSetFormat(int format)
{
- int size;
+ int size;
- /* Amiga sound DMA supports 8bit and 16bit (pseudo 14 bit) modes */
+ /* Amiga sound DMA supports 8bit and 16bit (pseudo 14 bit) modes */
- switch (format)
- {
- case AFMT_QUERY:
- return (sound.soft.format);
- case AFMT_MU_LAW:
- case AFMT_A_LAW:
- case AFMT_U8:
- case AFMT_S8:
- size = 8;
- break;
- case AFMT_S16_BE:
- case AFMT_U16_BE:
- case AFMT_S16_LE:
- case AFMT_U16_LE:
- size = 16;
- break;
- default: /* :-) */
- size = 8;
- format = AFMT_S8;
- }
+ switch (format) {
+ case AFMT_QUERY:
+ return(sound.soft.format);
+ case AFMT_MU_LAW:
+ case AFMT_A_LAW:
+ case AFMT_U8:
+ case AFMT_S8:
+ size = 8;
+ break;
+ case AFMT_S16_BE:
+ case AFMT_U16_BE:
+ case AFMT_S16_LE:
+ case AFMT_U16_LE:
+ size = 16;
+ break;
+ default: /* :-) */
+ size = 8;
+ format = AFMT_S8;
+ }
- sound.soft.format = format;
- sound.soft.size = size;
- if (sound.minDev == SND_DEV_DSP)
- {
- sound.dsp.format = format;
- sound.dsp.size = sound.soft.size;
- }
- AmiInit();
+ sound.soft.format = format;
+ sound.soft.size = size;
+ if (sound.minDev == SND_DEV_DSP) {
+ sound.dsp.format = format;
+ sound.dsp.size = sound.soft.size;
+ }
+ AmiInit();
- return (format);
+ return(format);
}
@@ -2448,26 +2188,24 @@ AmiSetFormat(int format)
(((v) < 0) ? 0 : ((v) > 100) ? 64 : ((v) * 64)/100)
#define VOLUME_AMI_TO_VOXWARE(v) ((v)*100/64)
-static int
-AmiSetVolume(int volume)
+static int AmiSetVolume(int volume)
{
- sound.volume_left = VOLUME_VOXWARE_TO_AMI(volume & 0xff);
- custom.aud[0].audvol = sound.volume_left;
- sound.volume_right = VOLUME_VOXWARE_TO_AMI((volume & 0xff00) >> 8);
- custom.aud[1].audvol = sound.volume_right;
- return (VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
- (VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8));
+ sound.volume_left = VOLUME_VOXWARE_TO_AMI(volume & 0xff);
+ custom.aud[0].audvol = sound.volume_left;
+ sound.volume_right = VOLUME_VOXWARE_TO_AMI((volume & 0xff00) >> 8);
+ custom.aud[1].audvol = sound.volume_right;
+ return(VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
+ (VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8));
}
-static int
-AmiSetTreble(int treble)
+static int AmiSetTreble(int treble)
{
- sound.treble = treble;
- if (treble < 50)
- ciaa.pra &= ~0x02;
- else
- ciaa.pra |= 0x02;
- return (treble);
+ sound.treble = treble;
+ if (treble < 50)
+ ciaa.pra &= ~0x02;
+ else
+ ciaa.pra |= 0x02;
+ return(treble);
}
@@ -2476,302 +2214,286 @@ AmiSetTreble(int treble)
#define AMI_PLAY_MASK 3
-static void
-ami_sq_play_next_frame(int index)
+static void ami_sq_play_next_frame(int index)
+{
+ u_char *start, *ch0, *ch1, *ch2, *ch3;
+ u_long size;
+
+ /* used by AmiPlay() if all doubts whether there really is something
+ * to be played are already wiped out.
+ */
+ start = sq_block_address(sq.front);
+ size = (sq.count == index ? sq.rear_size : sq.block_size)>>1;
+
+ if (sound.hard.stereo) {
+ ch0 = start;
+ ch1 = start+sq.block_size_half;
+ size >>= 1;
+ } else {
+ ch0 = start;
+ ch1 = start;
+ }
+ if (sound.hard.size == 8) {
+ custom.aud[0].audlc = (u_short *)ZTWO_PADDR(ch0);
+ custom.aud[0].audlen = size;
+ custom.aud[1].audlc = (u_short *)ZTWO_PADDR(ch1);
+ custom.aud[1].audlen = size;
+ custom.dmacon = AMI_AUDIO_8;
+ } else {
+ size >>= 1;
+ custom.aud[0].audlc = (u_short *)ZTWO_PADDR(ch0);
+ custom.aud[0].audlen = size;
+ custom.aud[1].audlc = (u_short *)ZTWO_PADDR(ch1);
+ custom.aud[1].audlen = size;
+ if (sound.volume_left == 64 && sound.volume_right == 64) {
+ /* We can play pseudo 14-bit only with the maximum volume */
+ ch3 = ch0+sq.block_size_quarter;
+ ch2 = ch1+sq.block_size_quarter;
+ custom.aud[2].audvol = 1; /* we are being affected by the beeps */
+ custom.aud[3].audvol = 1; /* restoring volume here helps a bit */
+ custom.aud[2].audlc = (u_short *)ZTWO_PADDR(ch2);
+ custom.aud[2].audlen = size;
+ custom.aud[3].audlc = (u_short *)ZTWO_PADDR(ch3);
+ custom.aud[3].audlen = size;
+ custom.dmacon = AMI_AUDIO_14;
+ } else
+ custom.dmacon = AMI_AUDIO_8;
+ }
+ sq.front = (sq.front+1) % sq.max_count;
+ sq.playing |= AMI_PLAY_LOADED;
+}
+
+
+static void AmiPlay(void)
{
- u_char *start, *ch0, *ch1, *ch2, *ch3;
- u_long size;
+ int minframes = 1;
- /* used by AmiPlay() if all doubts whether there really is something
- * to be played are already wiped out.
- */
- start = sq_block_address(sq.front);
- size = (sq.count == index ? sq.rear_size : sq.block_size) >> 1;
-
- if (sound.hard.stereo)
- {
- ch0 = start;
- ch1 = start + sq.block_size_half;
- size >>= 1;
- } else
- {
- ch0 = start;
- ch1 = start;
- }
- if (sound.hard.size == 8)
- {
- custom.aud[0].audlc = (u_short *) ZTWO_PADDR(ch0);
- custom.aud[0].audlen = size;
- custom.aud[1].audlc = (u_short *) ZTWO_PADDR(ch1);
- custom.aud[1].audlen = size;
- custom.dmacon = AMI_AUDIO_8;
- } else
- {
- size >>= 1;
- custom.aud[0].audlc = (u_short *) ZTWO_PADDR(ch0);
- custom.aud[0].audlen = size;
- custom.aud[1].audlc = (u_short *) ZTWO_PADDR(ch1);
- custom.aud[1].audlen = size;
- if (sound.volume_left == 64 && sound.volume_right == 64)
- {
- /* We can play pseudo 14-bit only with the maximum volume */
- ch3 = ch0 + sq.block_size_quarter;
- ch2 = ch1 + sq.block_size_quarter;
- custom.aud[2].audvol = 1; /* we are being affected by the beeps */
- custom.aud[3].audvol = 1; /* restoring volume here helps a bit */
- custom.aud[2].audlc = (u_short *) ZTWO_PADDR(ch2);
- custom.aud[2].audlen = size;
- custom.aud[3].audlc = (u_short *) ZTWO_PADDR(ch3);
- custom.aud[3].audlen = size;
- custom.dmacon = AMI_AUDIO_14;
- } else
- custom.dmacon = AMI_AUDIO_8;
- }
- sq.front = (sq.front + 1) % sq.max_count;
- sq.playing |= AMI_PLAY_LOADED;
-}
-
-
-static void
-AmiPlay(void)
-{
- int minframes = 1;
-
- custom.intena = IF_AUD0;
-
- if (sq.playing & AMI_PLAY_LOADED)
- {
- /* There's already a frame loaded */
- custom.intena = IF_SETCLR | IF_AUD0;
- return;
- }
- if (sq.playing & AMI_PLAY_PLAYING)
- /* Increase threshold: frame 1 is already being played */
- minframes = 2;
-
- if (sq.count < minframes)
- {
- /* Nothing to do */
- custom.intena = IF_SETCLR | IF_AUD0;
- return;
- }
- if (sq.count <= minframes && sq.rear_size < sq.block_size && !sq.syncing)
- {
- /* hmmm, the only existing frame is not
- * yet filled and we're not syncing?
- */
- custom.intena = IF_SETCLR | IF_AUD0;
- return;
- }
- ami_sq_play_next_frame(minframes);
+ custom.intena = IF_AUD0;
+ if (sq.playing & AMI_PLAY_LOADED) {
+ /* There's already a frame loaded */
custom.intena = IF_SETCLR | IF_AUD0;
+ return;
+ }
+
+ if (sq.playing & AMI_PLAY_PLAYING)
+ /* Increase threshold: frame 1 is already being played */
+ minframes = 2;
+
+ if (sq.count < minframes) {
+ /* Nothing to do */
+ custom.intena = IF_SETCLR | IF_AUD0;
+ return;
+ }
+
+ if (sq.count <= minframes && sq.rear_size < sq.block_size && !sq.syncing) {
+ /* hmmm, the only existing frame is not
+ * yet filled and we're not syncing?
+ */
+ custom.intena = IF_SETCLR | IF_AUD0;
+ return;
+ }
+
+ ami_sq_play_next_frame(minframes);
+
+ custom.intena = IF_SETCLR | IF_AUD0;
}
-static void
-ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp)
+static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
- int minframes = 1;
+ int minframes = 1;
+
+ if (!sq.playing) {
+ /* Playing was interrupted and sq_reset() has already cleared
+ * the sq variables, so better don't do anything here.
+ */
+ WAKE_UP(sq.sync_queue);
+ return;
+ }
+
+ if (sq.playing & AMI_PLAY_PLAYING) {
+ /* We've just finished a frame */
+ sq.count--;
+ WAKE_UP(sq.write_queue);
+ }
- if (!sq.playing)
- {
- /* Playing was interrupted and sq_reset() has already cleared
- * the sq variables, so better don't do anything here.
- */
- WAKE_UP(sq.sync_queue);
- return;
- }
- if (sq.playing & AMI_PLAY_PLAYING)
- {
- /* We've just finished a frame */
- sq.count--;
- WAKE_UP(sq.write_queue);
- }
- if (sq.playing & AMI_PLAY_LOADED)
- /* Increase threshold: frame 1 is already being played */
- minframes = 2;
+ if (sq.playing & AMI_PLAY_LOADED)
+ /* Increase threshold: frame 1 is already being played */
+ minframes = 2;
- /* Shift the flags */
- sq.playing = (sq.playing << 1) & AMI_PLAY_MASK;
+ /* Shift the flags */
+ sq.playing = (sq.playing<<1) & AMI_PLAY_MASK;
- if (!sq.playing)
- /* No frame is playing, disable audio DMA */
- custom.dmacon = AMI_AUDIO_OFF;
+ if (!sq.playing)
+ /* No frame is playing, disable audio DMA */
+ custom.dmacon = AMI_AUDIO_OFF;
- if (sq.count >= minframes)
- /* Try to play the next frame */
- AmiPlay();
+ if (sq.count >= minframes)
+ /* Try to play the next frame */
+ AmiPlay();
- if (!sq.playing)
- /* Nothing to play anymore.
- Wake up a process waiting for audio output to drain. */
- WAKE_UP(sq.sync_queue);
+ if (!sq.playing)
+ /* Nothing to play anymore.
+ Wake up a process waiting for audio output to drain. */
+ WAKE_UP(sq.sync_queue);
}
-#endif /* CONFIG_AMIGA */
+#endif /* CONFIG_AMIGA */
/*** Machine definitions *****************************************************/
#ifdef CONFIG_ATARI
-static MACHINE machTT =
-{
- DMASND_TT, AtaAlloc, AtaFree, AtaIrqInit,
+static MACHINE machTT = {
+ DMASND_TT, AtaAlloc, AtaFree, AtaIrqInit,
#ifdef MODULE
- AtaIrqCleanUp,
-#endif /* MODULE */
- TTInit, TTSilence, TTSetFormat, TTSetVolume, AtaSetBass, AtaSetTreble,
- AtaPlay
+ AtaIrqCleanUp,
+#endif /* MODULE */
+ TTInit, TTSilence, TTSetFormat, TTSetVolume, AtaSetBass, AtaSetTreble,
+ TTSetGain,
+ AtaPlay
};
-static MACHINE machFalcon =
-{
- DMASND_FALCON, AtaAlloc, AtaFree, AtaIrqInit,
+static MACHINE machFalcon = {
+ DMASND_FALCON, AtaAlloc, AtaFree, AtaIrqInit,
#ifdef MODULE
- AtaIrqCleanUp,
-#endif /* MODULE */
- FalconInit, FalconSilence, FalconSetFormat, FalconSetVolume, AtaSetBass,
- AtaSetTreble, AtaPlay
+ AtaIrqCleanUp,
+#endif /* MODULE */
+ FalconInit, FalconSilence, FalconSetFormat, FalconSetVolume, AtaSetBass,
+ AtaSetTreble, NULL, AtaPlay
};
-
-#endif /* CONFIG_ATARI */
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
-static MACHINE machAmiga =
-{
- DMASND_AMIGA, AmiAlloc, AmiFree, AmiIrqInit,
+static MACHINE machAmiga = {
+ DMASND_AMIGA, AmiAlloc, AmiFree, AmiIrqInit,
#ifdef MODULE
- AmiIrqCleanUp,
-#endif /* MODULE */
- AmiInit, AmiSilence, AmiSetFormat, AmiSetVolume, NULL, AmiSetTreble,
- AmiPlay
+ AmiIrqCleanUp,
+#endif /* MODULE */
+ AmiInit, AmiSilence, AmiSetFormat, AmiSetVolume, NULL, AmiSetTreble,
+ NULL,
+ AmiPlay
};
-
-#endif /* CONFIG_AMIGA */
+#endif /* CONFIG_AMIGA */
/*** Mid level stuff *********************************************************/
-static void
-sound_silence(void)
+static void sound_silence(void)
{
- /* update hardware settings one more */
- (*sound.mach.init) ();
+ /* update hardware settings one more */
+ (*sound.mach.init)();
- (*sound.mach.silence) ();
+ (*sound.mach.silence)();
}
-static void
-sound_init(void)
+static void sound_init(void)
{
- (*sound.mach.init) ();
+ (*sound.mach.init)();
}
-static int
-sound_set_format(int format)
+static int sound_set_format(int format)
{
- return (*sound.mach.setFormat) (format);
+ return(*sound.mach.setFormat)(format);
}
-static int
-sound_set_speed(int speed)
+static int sound_set_speed(int speed)
{
- if (speed < 0)
- return (sound.soft.speed);
+ if (speed < 0)
+ return(sound.soft.speed);
- sound.soft.speed = speed;
- (*sound.mach.init) ();
- if (sound.minDev == SND_DEV_DSP)
- sound.dsp.speed = sound.soft.speed;
+ sound.soft.speed = speed;
+ (*sound.mach.init)();
+ if (sound.minDev == SND_DEV_DSP)
+ sound.dsp.speed = sound.soft.speed;
- return (sound.soft.speed);
+ return(sound.soft.speed);
}
-static int
-sound_set_stereo(int stereo)
+static int sound_set_stereo(int stereo)
{
- if (stereo < 0)
- return (sound.soft.stereo);
+ if (stereo < 0)
+ return(sound.soft.stereo);
- stereo = !!stereo; /* should be 0 or 1 now */
+ stereo = !!stereo; /* should be 0 or 1 now */
- sound.soft.stereo = stereo;
- if (sound.minDev == SND_DEV_DSP)
- sound.dsp.stereo = stereo;
- (*sound.mach.init) ();
+ sound.soft.stereo = stereo;
+ if (sound.minDev == SND_DEV_DSP)
+ sound.dsp.stereo = stereo;
+ (*sound.mach.init)();
- return (stereo);
+ return(stereo);
}
-static int
-sound_set_volume(int volume)
+static int sound_set_volume(int volume)
{
- return (*sound.mach.setVolume) (volume);
+ return(*sound.mach.setVolume)(volume);
}
#ifdef CONFIG_ATARI
-static int
-sound_set_bass(int bass)
-{
- return (sound.mach.setBass ? (*sound.mach.setBass) (bass) : 50);
-}
-#endif /* CONFIG_ATARI */
-
-
-static int
-sound_set_treble(int treble)
-{
- return (sound.mach.setTreble ? (*sound.mach.setTreble) (treble) : 50);
-}
-
-
-static long
-sound_copy_translate(const u_char * userPtr,
- unsigned long userCount,
- u_char frame[], long *frameUsed,
- long frameLeft)
-{
- long (*ct_func) (const u_char *, unsigned long, u_char *, long *, long) = NULL;
-
- switch (sound.soft.format)
- {
- case AFMT_MU_LAW:
- ct_func = sound.trans->ct_ulaw;
- break;
- case AFMT_A_LAW:
- ct_func = sound.trans->ct_alaw;
- break;
- case AFMT_S8:
- ct_func = sound.trans->ct_s8;
- break;
- case AFMT_U8:
- ct_func = sound.trans->ct_u8;
- break;
- case AFMT_S16_BE:
- ct_func = sound.trans->ct_s16be;
- break;
- case AFMT_U16_BE:
- ct_func = sound.trans->ct_u16be;
- break;
- case AFMT_S16_LE:
- ct_func = sound.trans->ct_s16le;
- break;
- case AFMT_U16_LE:
- ct_func = sound.trans->ct_u16le;
- break;
- }
- if (ct_func)
- return (ct_func(userPtr, userCount, frame, frameUsed, frameLeft));
- else
- return (0);
+static int sound_set_bass(int bass)
+{
+ return(sound.mach.setBass ? (*sound.mach.setBass)(bass) : 50);
+}
+
+static int sound_set_gain(int gain)
+{
+ return sound.mach.setGain ? sound.mach.setGain(gain) : 100;
+}
+#endif /* CONFIG_ATARI */
+
+
+static int sound_set_treble(int treble)
+{
+ return(sound.mach.setTreble ? (*sound.mach.setTreble)(treble) : 50);
+}
+
+
+static long sound_copy_translate(const u_char *userPtr,
+ unsigned long userCount,
+ u_char frame[], long *frameUsed,
+ long frameLeft)
+{
+ long (*ct_func)(const u_char *, unsigned long, u_char *, long *, long) = NULL;
+
+ switch (sound.soft.format) {
+ case AFMT_MU_LAW:
+ ct_func = sound.trans->ct_ulaw;
+ break;
+ case AFMT_A_LAW:
+ ct_func = sound.trans->ct_alaw;
+ break;
+ case AFMT_S8:
+ ct_func = sound.trans->ct_s8;
+ break;
+ case AFMT_U8:
+ ct_func = sound.trans->ct_u8;
+ break;
+ case AFMT_S16_BE:
+ ct_func = sound.trans->ct_s16be;
+ break;
+ case AFMT_U16_BE:
+ ct_func = sound.trans->ct_u16be;
+ break;
+ case AFMT_S16_LE:
+ ct_func = sound.trans->ct_s16le;
+ break;
+ case AFMT_U16_LE:
+ ct_func = sound.trans->ct_u16le;
+ break;
+ }
+ if (ct_func)
+ return(ct_func(userPtr, userCount, frame, frameUsed, frameLeft));
+ else
+ return(0);
}
@@ -2785,215 +2507,203 @@ sound_copy_translate(const u_char * userPtr,
#define RECLEVEL_GAIN_TO_VOXWARE(v) (((v) * 20 + 2) / 3)
-static void
-mixer_init(void)
+static void mixer_init(void)
{
- mixer.busy = 0;
- sound.treble = 0;
- sound.bass = 0;
- switch (sound.mach.type)
- {
+ mixer.busy = 0;
+ sound.treble = 0;
+ sound.bass = 0;
+ switch (sound.mach.type) {
#ifdef CONFIG_ATARI
- case DMASND_TT:
- atari_microwire_cmd(MW_LM1992_VOLUME(0));
- sound.volume_left = 0;
- atari_microwire_cmd(MW_LM1992_BALLEFT(0));
- sound.volume_right = 0;
- atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
- atari_microwire_cmd(MW_LM1992_TREBLE(0));
- atari_microwire_cmd(MW_LM1992_BASS(0));
- break;
- case DMASND_FALCON:
- sound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
- sound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
- break;
-#endif /* CONFIG_ATARI */
+ case DMASND_TT:
+ atari_microwire_cmd(MW_LM1992_VOLUME(0));
+ sound.volume_left = 0;
+ atari_microwire_cmd(MW_LM1992_BALLEFT(0));
+ sound.volume_right = 0;
+ atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
+ atari_microwire_cmd(MW_LM1992_TREBLE(0));
+ atari_microwire_cmd(MW_LM1992_BASS(0));
+ break;
+ case DMASND_FALCON:
+ sound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
+ sound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
+ break;
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
- case DMASND_AMIGA:
- sound.volume_left = 64;
- sound.volume_right = 64;
- custom.aud[0].audvol = sound.volume_left;
- custom.aud[3].audvol = 1; /* For pseudo 14bit */
- custom.aud[1].audvol = sound.volume_right;
- custom.aud[2].audvol = 1; /* For pseudo 14bit */
- sound.treble = 50;
- break;
-#endif /* CONFIG_AMIGA */
- }
+ case DMASND_AMIGA:
+ sound.volume_left = 64;
+ sound.volume_right = 64;
+ custom.aud[0].audvol = sound.volume_left;
+ custom.aud[3].audvol = 1; /* For pseudo 14bit */
+ custom.aud[1].audvol = sound.volume_right;
+ custom.aud[2].audvol = 1; /* For pseudo 14bit */
+ sound.treble = 50;
+ break;
+#endif /* CONFIG_AMIGA */
+ }
}
-static int
-mixer_open(int open_mode)
+static int mixer_open(int open_mode)
{
- if (mixer.busy)
- return (-EBUSY);
- mixer.busy = 1;
- return (0);
+ if (mixer.busy)
+ return(-EBUSY);
+ mixer.busy = 1;
+ return(0);
}
-static int
-mixer_release(void)
+static int mixer_release(void)
{
- mixer.busy = 0;
- return (0);
+ mixer.busy = 0;
+ return(0);
}
-static int
-mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg)
+static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg)
{
- int data;
-
- switch (sound.mach.type)
- {
+ int data;
+ switch (sound.mach.type) {
#ifdef CONFIG_ATARI
- case DMASND_FALCON:
- switch (cmd)
+ case DMASND_FALCON:
+ switch (cmd) {
+ case SOUND_MIXER_READ_DEVMASK:
+ return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER));
+ case SOUND_MIXER_READ_RECMASK:
+ return(IOCTL_OUT(arg, SOUND_MASK_MIC));
+ case SOUND_MIXER_READ_STEREODEVS:
+ return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC));
+ case SOUND_MIXER_READ_CAPS:
+ return(IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT));
+ case SOUND_MIXER_READ_VOLUME:
+ return(IOCTL_OUT(arg,
+ VOLUME_ATT_TO_VOXWARE(sound.volume_left) |
+ VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8));
+ case SOUND_MIXER_WRITE_MIC:
+ IOCTL_IN(arg, data);
+ tt_dmasnd.input_gain =
+ RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
+ RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
+ /* fall thru, return set value */
+ case SOUND_MIXER_READ_MIC:
+ return(IOCTL_OUT(arg,
+ RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
+ RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8));
+ case SOUND_MIXER_READ_SPEAKER:
{
- case SOUND_MIXER_READ_DEVMASK:
- return (IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER));
- case SOUND_MIXER_READ_RECMASK:
- return (IOCTL_OUT(arg, SOUND_MASK_MIC));
- case SOUND_MIXER_READ_STEREODEVS:
- return (IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC));
- case SOUND_MIXER_READ_CAPS:
- return (IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT));
- case SOUND_MIXER_READ_VOLUME:
- return (IOCTL_OUT(arg,
- VOLUME_ATT_TO_VOXWARE(sound.volume_left) |
- VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8));
- case SOUND_MIXER_WRITE_MIC:
- IOCTL_IN(arg, data);
- tt_dmasnd.input_gain =
- RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
- RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
- /* fall thru, return set value */
- case SOUND_MIXER_READ_MIC:
- return (IOCTL_OUT(arg,
- RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
- RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8));
- case SOUND_MIXER_READ_SPEAKER:
- {
- int porta;
-
- cli();
- sound_ym.rd_data_reg_sel = 14;
- porta = sound_ym.rd_data_reg_sel;
- sti();
- return (IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
- }
- case SOUND_MIXER_WRITE_VOLUME:
- IOCTL_IN(arg, data);
- return (IOCTL_OUT(arg, sound_set_volume(data)));
- case SOUND_MIXER_WRITE_SPEAKER:
- {
- int porta;
-
- IOCTL_IN(arg, data);
- cli();
- sound_ym.rd_data_reg_sel = 14;
- porta = (sound_ym.rd_data_reg_sel & ~0x40) |
- (data < 50 ? 0x40 : 0);
- sound_ym.wd_data = porta;
- sti();
- return (IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
- }
+ int porta;
+ cli();
+ sound_ym.rd_data_reg_sel = 14;
+ porta = sound_ym.rd_data_reg_sel;
+ sti();
+ return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
}
- break;
-
- case DMASND_TT:
- switch (cmd)
+ case SOUND_MIXER_WRITE_VOLUME:
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_volume(data)));
+ case SOUND_MIXER_WRITE_SPEAKER:
{
- case SOUND_MIXER_READ_DEVMASK:
- return (IOCTL_OUT(arg,
- SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
- ((atari_mch_cookie >> 16) == ATARI_MCH_TT ?
- SOUND_MASK_SPEAKER : 0)));
- case SOUND_MIXER_READ_RECMASK:
- return (IOCTL_OUT(arg, 0));
- case SOUND_MIXER_READ_STEREODEVS:
- return (IOCTL_OUT(arg, SOUND_MASK_VOLUME));
- case SOUND_MIXER_READ_VOLUME:
- return (IOCTL_OUT(arg,
- VOLUME_DB_TO_VOXWARE(sound.volume_left) |
- (VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8)));
- case SOUND_MIXER_READ_BASS:
- return (IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.bass)));
- case SOUND_MIXER_READ_TREBLE:
- return (IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.treble)));
- case SOUND_MIXER_READ_SPEAKER:
- {
- int porta;
-
- if ((atari_mch_cookie >> 16) == ATARI_MCH_TT)
- {
- cli();
- sound_ym.rd_data_reg_sel = 14;
- porta = sound_ym.rd_data_reg_sel;
- sti();
- return (IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
- } else
- return (-EINVAL);
- }
- case SOUND_MIXER_WRITE_VOLUME:
- IOCTL_IN(arg, data);
- return (IOCTL_OUT(arg, sound_set_volume(data)));
- case SOUND_MIXER_WRITE_BASS:
- IOCTL_IN(arg, data);
- return (IOCTL_OUT(arg, sound_set_bass(data)));
- case SOUND_MIXER_WRITE_TREBLE:
- IOCTL_IN(arg, data);
- return (IOCTL_OUT(arg, sound_set_treble(data)));
- case SOUND_MIXER_WRITE_SPEAKER:
- if ((atari_mch_cookie >> 16) == ATARI_MCH_TT)
- {
- int porta;
-
- IOCTL_IN(arg, data);
- cli();
- sound_ym.rd_data_reg_sel = 14;
- porta = (sound_ym.rd_data_reg_sel & ~0x40) |
- (data < 50 ? 0x40 : 0);
- sound_ym.wd_data = porta;
- sti();
- return (IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
- } else
- return (-EINVAL);
+ int porta;
+ IOCTL_IN(arg, data);
+ cli();
+ sound_ym.rd_data_reg_sel = 14;
+ porta = (sound_ym.rd_data_reg_sel & ~0x40) |
+ (data < 50 ? 0x40 : 0);
+ sound_ym.wd_data = porta;
+ sti();
+ return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
}
- break;
-#endif /* CONFIG_ATARI */
-
-#ifdef CONFIG_AMIGA
- case DMASND_AMIGA:
- switch (cmd)
+ }
+ break;
+
+ case DMASND_TT:
+ switch (cmd) {
+ case SOUND_MIXER_READ_DEVMASK:
+ return(IOCTL_OUT(arg,
+ SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
+ (MACH_IS_TT ? SOUND_MASK_SPEAKER : 0)));
+ case SOUND_MIXER_READ_RECMASK:
+ return(IOCTL_OUT(arg, 0));
+ case SOUND_MIXER_READ_STEREODEVS:
+ return(IOCTL_OUT(arg, SOUND_MASK_VOLUME));
+ case SOUND_MIXER_READ_VOLUME:
+ return(IOCTL_OUT(arg,
+ VOLUME_DB_TO_VOXWARE(sound.volume_left) |
+ (VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8)));
+ case SOUND_MIXER_READ_BASS:
+ return(IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.bass)));
+ case SOUND_MIXER_READ_TREBLE:
+ return(IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.treble)));
+ case SOUND_MIXER_READ_OGAIN:
+ return(IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(sound.gain)));
+ case SOUND_MIXER_READ_SPEAKER:
{
- case SOUND_MIXER_READ_DEVMASK:
- return (IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_TREBLE));
- case SOUND_MIXER_READ_RECMASK:
- return (IOCTL_OUT(arg, 0));
- case SOUND_MIXER_READ_STEREODEVS:
- return (IOCTL_OUT(arg, SOUND_MASK_VOLUME));
- case SOUND_MIXER_READ_VOLUME:
- return (IOCTL_OUT(arg,
- VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
- VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8));
- case SOUND_MIXER_WRITE_VOLUME:
- IOCTL_IN(arg, data);
- return (IOCTL_OUT(arg, sound_set_volume(data)));
- case SOUND_MIXER_READ_TREBLE:
- return (IOCTL_OUT(arg, sound.treble));
- case SOUND_MIXER_WRITE_TREBLE:
- IOCTL_IN(arg, data);
- return (IOCTL_OUT(arg, sound_set_treble(data)));
+ int porta;
+ if (MACH_IS_TT) {
+ cli();
+ sound_ym.rd_data_reg_sel = 14;
+ porta = sound_ym.rd_data_reg_sel;
+ sti();
+ return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
+ } else
+ return(-EINVAL);
}
- break;
-#endif /* CONFIG_AMIGA */
- }
+ case SOUND_MIXER_WRITE_VOLUME:
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_volume(data)));
+ case SOUND_MIXER_WRITE_BASS:
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_bass(data)));
+ case SOUND_MIXER_WRITE_TREBLE:
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_treble(data)));
+ case SOUND_MIXER_WRITE_OGAIN:
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_gain(data)));
+ case SOUND_MIXER_WRITE_SPEAKER:
+ if (MACH_IS_TT) {
+ int porta;
+ IOCTL_IN(arg, data);
+ cli();
+ sound_ym.rd_data_reg_sel = 14;
+ porta = (sound_ym.rd_data_reg_sel & ~0x40) |
+ (data < 50 ? 0x40 : 0);
+ sound_ym.wd_data = porta;
+ sti();
+ return(IOCTL_OUT(arg, porta & 0x40 ? 0 : 100));
+ } else
+ return(-EINVAL);
+ }
+ break;
+#endif /* CONFIG_ATARI */
- return (-EINVAL);
+#ifdef CONFIG_AMIGA
+ case DMASND_AMIGA:
+ switch (cmd) {
+ case SOUND_MIXER_READ_DEVMASK:
+ return(IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_TREBLE));
+ case SOUND_MIXER_READ_RECMASK:
+ return(IOCTL_OUT(arg, 0));
+ case SOUND_MIXER_READ_STEREODEVS:
+ return(IOCTL_OUT(arg, SOUND_MASK_VOLUME));
+ case SOUND_MIXER_READ_VOLUME:
+ return(IOCTL_OUT(arg,
+ VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
+ VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8));
+ case SOUND_MIXER_WRITE_VOLUME:
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_volume(data)));
+ case SOUND_MIXER_READ_TREBLE:
+ return(IOCTL_OUT(arg, sound.treble));
+ case SOUND_MIXER_WRITE_TREBLE:
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_treble(data)));
+ }
+ break;
+#endif /* CONFIG_AMIGA */
+ }
+
+ return(-EINVAL);
}
@@ -3003,216 +2713,198 @@ mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
*/
-static void
-sq_init(int numBufs, int bufSize, char **buffers)
+static void sq_init(int numBufs, int bufSize, char **buffers)
{
- sq.max_count = numBufs;
- sq.block_size = bufSize;
- sq.buffers = buffers;
+ sq.max_count = numBufs;
+ sq.block_size = bufSize;
+ sq.buffers = buffers;
- sq.front = sq.count = 0;
- sq.rear = -1;
- sq.write_queue = sq.open_queue = sq.sync_queue = 0;
- sq.busy = 0;
- sq.syncing = 0;
+ sq.front = sq.count = 0;
+ sq.rear = -1;
+ sq.write_queue = sq.open_queue = sq.sync_queue = 0;
+ sq.busy = 0;
+ sq.syncing = 0;
- sq.playing = 0;
+ sq.playing = 0;
#ifdef CONFIG_ATARI
- sq.ignore_int = 0;
-#endif /* CONFIG_ATARI */
+ sq.ignore_int = 0;
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
- sq.block_size_half = sq.block_size >> 1;
- sq.block_size_quarter = sq.block_size_half >> 1;
-#endif /* CONFIG_AMIGA */
-
- sound_silence();
-
- /* whatever you like as startup mode for /dev/dsp,
- * (/dev/audio hasn't got a startup mode). note that
- * once changed a new open() will *not* restore these!
- */
- sound.dsp.format = AFMT_S8;
- sound.dsp.stereo = 0;
- sound.dsp.size = 8;
-
- /* set minimum rate possible without expanding */
- switch (sound.mach.type)
- {
+ sq.block_size_half = sq.block_size>>1;
+ sq.block_size_quarter = sq.block_size_half>>1;
+#endif /* CONFIG_AMIGA */
+
+ sound_silence();
+
+ /* whatever you like as startup mode for /dev/dsp,
+ * (/dev/audio hasn't got a startup mode). note that
+ * once changed a new open() will *not* restore these!
+ */
+ sound.dsp.format = AFMT_S8;
+ sound.dsp.stereo = 0;
+ sound.dsp.size = 8;
+
+ /* set minimum rate possible without expanding */
+ switch (sound.mach.type) {
#ifdef CONFIG_ATARI
- case DMASND_TT:
- sound.dsp.speed = 6258;
- break;
- case DMASND_FALCON:
- sound.dsp.speed = 8195;
- break;
-#endif /* CONFIG_ATARI */
+ case DMASND_TT:
+ sound.dsp.speed = 6258;
+ break;
+ case DMASND_FALCON:
+ sound.dsp.speed = 8195;
+ break;
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
- case DMASND_AMIGA:
- sound.dsp.speed = 8000;
- break;
-#endif /* CONFIG_AMIGA */
- }
+ case DMASND_AMIGA:
+ sound.dsp.speed = 8000;
+ break;
+#endif /* CONFIG_AMIGA */
+ }
- /* before the first open to /dev/dsp this wouldn't be set */
- sound.soft = sound.dsp;
- sound.hard = sound.dsp;
+ /* before the first open to /dev/dsp this wouldn't be set */
+ sound.soft = sound.dsp;
+ sound.hard = sound.dsp;
}
-static void
-sq_play(void)
+static void sq_play(void)
{
- (*sound.mach.play) ();
+ (*sound.mach.play)();
}
/* ++TeSche: radically changed this one too */
-static long
-sq_write(const char *src, unsigned long uLeft)
-{
- long uWritten = 0;
- u_char *dest;
- long uUsed, bUsed, bLeft;
-
- /* ++TeSche: Is something like this necessary?
- * Hey, that's an honest question! Or does any other part of the
- * filesystem already checks this situation? I really don't know.
- */
- if (uLeft == 0)
- return (0);
+static long sq_write(const char *src, unsigned long uLeft)
+{
+ long uWritten = 0;
+ u_char *dest;
+ long uUsed, bUsed, bLeft;
+
+ /* ++TeSche: Is something like this necessary?
+ * Hey, that's an honest question! Or does any other part of the
+ * filesystem already checks this situation? I really don't know.
+ */
+ if (uLeft == 0)
+ return(0);
+
+ /* The interrupt doesn't start to play the last, incomplete frame.
+ * Thus we can append to it without disabling the interrupts! (Note
+ * also that sq.rear isn't affected by the interrupt.)
+ */
+
+ if (sq.count > 0 && (bLeft = sq.block_size-sq.rear_size) > 0) {
+ dest = sq_block_address(sq.rear);
+ bUsed = sq.rear_size;
+ uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
+ src += uUsed;
+ uWritten += uUsed;
+ uLeft -= uUsed;
+ sq.rear_size = bUsed;
+ }
+
+ do {
+ while (sq.count == sq.max_count) {
+ sq_play();
+ if (NON_BLOCKING(sq.open_mode))
+ return(uWritten > 0 ? uWritten : -EAGAIN);
+ SLEEP(sq.write_queue, ONE_SECOND);
+ if (SIGNAL_RECEIVED)
+ return(uWritten > 0 ? uWritten : -EINTR);
+ }
- /* The interrupt doesn't start to play the last, incomplete frame.
- * Thus we can append to it without disabling the interrupts! (Note
- * also that sq.rear isn't affected by the interrupt.)
+ /* Here, we can avoid disabling the interrupt by first
+ * copying and translating the data, and then updating
+ * the sq variables. Until this is done, the interrupt
+ * won't see the new frame and we can work on it
+ * undisturbed.
*/
- if (sq.count > 0 && (bLeft = sq.block_size - sq.rear_size) > 0)
- {
- dest = sq_block_address(sq.rear);
- bUsed = sq.rear_size;
- uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
- src += uUsed;
- uWritten += uUsed;
- uLeft -= uUsed;
- sq.rear_size = bUsed;
- }
- do
- {
- while (sq.count == sq.max_count)
- {
- sq_play();
- if (NON_BLOCKING(sq.open_mode))
- return (uWritten > 0 ? uWritten : -EAGAIN);
- SLEEP(sq.write_queue, ONE_SECOND);
- if (SIGNAL_RECEIVED)
- return (uWritten > 0 ? uWritten : -EINTR);
- }
-
- /* Here, we can avoid disabling the interrupt by first
- * copying and translating the data, and then updating
- * the sq variables. Until this is done, the interrupt
- * won't see the new frame and we can work on it
- * undisturbed.
- */
-
- dest = sq_block_address((sq.rear + 1) % sq.max_count);
- bUsed = 0;
- bLeft = sq.block_size;
- uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
- src += uUsed;
- uWritten += uUsed;
- uLeft -= uUsed;
- if (bUsed)
- {
- sq.rear = (sq.rear + 1) % sq.max_count;
- sq.rear_size = bUsed;
- sq.count++;
- }
- }
- while (bUsed); /* uUsed may have been 0 */
+ dest = sq_block_address((sq.rear+1) % sq.max_count);
+ bUsed = 0;
+ bLeft = sq.block_size;
+ uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
+ src += uUsed;
+ uWritten += uUsed;
+ uLeft -= uUsed;
+ if (bUsed) {
+ sq.rear = (sq.rear+1) % sq.max_count;
+ sq.rear_size = bUsed;
+ sq.count++;
+ }
+ } while (bUsed); /* uUsed may have been 0 */
- sq_play();
+ sq_play();
- return (uWritten);
+ return(uWritten);
}
-static int
-sq_open(int open_mode)
+static int sq_open(int open_mode)
{
- if (sq.busy)
- {
- if (NON_BLOCKING(open_mode))
- return (-EBUSY);
- while (sq.busy)
- {
- SLEEP(sq.open_queue, ONE_SECOND);
- if (SIGNAL_RECEIVED)
- return (-EINTR);
- }
- }
- sq.open_mode = open_mode;
- sq.busy = 1;
+ if (sq.busy) {
+ if (NON_BLOCKING(open_mode))
+ return(-EBUSY);
+ while (sq.busy) {
+ SLEEP(sq.open_queue, ONE_SECOND);
+ if (SIGNAL_RECEIVED)
+ return(-EINTR);
+ }
+ }
+ sq.open_mode = open_mode;
+ sq.busy = 1;
#ifdef CONFIG_ATARI
- sq.ignore_int = 1;
-#endif /* CONFIG_ATARI */
- return (0);
+ sq.ignore_int = 1;
+#endif /* CONFIG_ATARI */
+ return(0);
}
-static void
-sq_reset(void)
+static void sq_reset(void)
{
- sound_silence();
- sq.playing = 0;
- sq.count = 0;
- sq.front = (sq.rear + 1) % sq.max_count;
+ sound_silence();
+ sq.playing = 0;
+ sq.count = 0;
+ sq.front = (sq.rear+1) % sq.max_count;
}
-static int
-sq_sync(void)
+static int sq_sync(void)
{
- int rc = 0;
+ int rc = 0;
- sq.syncing = 1;
- sq_play(); /* there may be an incomplete frame waiting */
+ sq.syncing = 1;
+ sq_play(); /* there may be an incomplete frame waiting */
- while (sq.playing)
- {
- SLEEP(sq.sync_queue, ONE_SECOND);
- if (SIGNAL_RECEIVED)
- {
- /* While waiting for audio output to drain, an interrupt occurred.
- Stop audio output immediately and clear the queue. */
- sq_reset();
- rc = -EINTR;
- break;
- }
- }
+ while (sq.playing) {
+ SLEEP(sq.sync_queue, ONE_SECOND);
+ if (SIGNAL_RECEIVED) {
+ /* While waiting for audio output to drain, an interrupt occurred.
+ Stop audio output immediately and clear the queue. */
+ sq_reset();
+ rc = -EINTR;
+ break;
+ }
+ }
- sq.syncing = 0;
- return (rc);
+ sq.syncing = 0;
+ return(rc);
}
-static int
-sq_release(void)
+static int sq_release(void)
{
- int rc = 0;
-
- if (sq.busy)
- {
- rc = sq_sync();
- sq.busy = 0;
- WAKE_UP(sq.open_queue);
- /* Wake up a process waiting for the queue being released.
- Note: There may be several processes waiting for a call to open()
- returning. */
- }
- return (rc);
+ int rc = 0;
+ if (sq.busy) {
+ rc = sq_sync();
+ sq.busy = 0;
+ WAKE_UP(sq.open_queue);
+ /* Wake up a process waiting for the queue being released.
+ Note: There may be several processes waiting for a call to open()
+ returning. */
+ }
+ return(rc);
}
@@ -3222,136 +2914,128 @@ sq_release(void)
*/
-static void
-state_init(void)
+static void state_init(void)
{
- state.busy = 0;
+ state.busy = 0;
}
/* state.buf should not overflow! */
-static int
-state_open(int open_mode)
+static int state_open(int open_mode)
{
- char *buffer = state.buf, *mach = "";
- int len = 0;
+ char *buffer = state.buf, *mach = "";
+ int len = 0;
- if (state.busy)
- return (-EBUSY);
+ if (state.busy)
+ return(-EBUSY);
- state.ptr = 0;
- state.busy = 1;
+ state.ptr = 0;
+ state.busy = 1;
- switch (sound.mach.type)
- {
+ switch (sound.mach.type) {
#ifdef CONFIG_ATARI
- case DMASND_TT:
- case DMASND_FALCON:
- mach = "Atari ";
- break;
-#endif /* CONFIG_ATARI */
+ case DMASND_TT:
+ case DMASND_FALCON:
+ mach = "Atari ";
+ break;
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
- case DMASND_AMIGA:
- mach = "Amiga ";
- break;
-#endif /* CONFIG_AMIGA */
- }
- len += sprintf(buffer + len, "%sDMA sound driver:\n", mach);
-
- len += sprintf(buffer + len, "\tsound.format = 0x%x", sound.soft.format);
- switch (sound.soft.format)
- {
- case AFMT_MU_LAW:
- len += sprintf(buffer + len, " (mu-law)");
- break;
- case AFMT_A_LAW:
- len += sprintf(buffer + len, " (A-law)");
- break;
- case AFMT_U8:
- len += sprintf(buffer + len, " (unsigned 8 bit)");
- break;
- case AFMT_S8:
- len += sprintf(buffer + len, " (signed 8 bit)");
- break;
- case AFMT_S16_BE:
- len += sprintf(buffer + len, " (signed 16 bit big)");
- break;
- case AFMT_U16_BE:
- len += sprintf(buffer + len, " (unsigned 16 bit big)");
- break;
- case AFMT_S16_LE:
- len += sprintf(buffer + len, " (signed 16 bit little)");
- break;
- case AFMT_U16_LE:
- len += sprintf(buffer + len, " (unsigned 16 bit little)");
- break;
- }
- len += sprintf(buffer + len, "\n");
- len += sprintf(buffer + len, "\tsound.speed = %dHz (phys. %dHz)\n",
- sound.soft.speed, sound.hard.speed);
- len += sprintf(buffer + len, "\tsound.stereo = 0x%x (%s)\n",
- sound.soft.stereo, sound.soft.stereo ? "stereo" : "mono");
- switch (sound.mach.type)
- {
+ case DMASND_AMIGA:
+ mach = "Amiga ";
+ break;
+#endif /* CONFIG_AMIGA */
+ }
+ len += sprintf(buffer+len, "%sDMA sound driver:\n", mach);
+
+ len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.soft.format);
+ switch (sound.soft.format) {
+ case AFMT_MU_LAW:
+ len += sprintf(buffer+len, " (mu-law)");
+ break;
+ case AFMT_A_LAW:
+ len += sprintf(buffer+len, " (A-law)");
+ break;
+ case AFMT_U8:
+ len += sprintf(buffer+len, " (unsigned 8 bit)");
+ break;
+ case AFMT_S8:
+ len += sprintf(buffer+len, " (signed 8 bit)");
+ break;
+ case AFMT_S16_BE:
+ len += sprintf(buffer+len, " (signed 16 bit big)");
+ break;
+ case AFMT_U16_BE:
+ len += sprintf(buffer+len, " (unsigned 16 bit big)");
+ break;
+ case AFMT_S16_LE:
+ len += sprintf(buffer+len, " (signed 16 bit little)");
+ break;
+ case AFMT_U16_LE:
+ len += sprintf(buffer+len, " (unsigned 16 bit little)");
+ break;
+ }
+ len += sprintf(buffer+len, "\n");
+ len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n",
+ sound.soft.speed, sound.hard.speed);
+ len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
+ sound.soft.stereo, sound.soft.stereo ? "stereo" : "mono");
+ switch (sound.mach.type) {
#ifdef CONFIG_ATARI
- case DMASND_TT:
- len += sprintf(buffer + len, "\tsound.volume_left = %ddB [-40...0]\n",
- sound.volume_left);
- len += sprintf(buffer + len, "\tsound.volume_right = %ddB [-40...0]\n",
- sound.volume_right);
- len += sprintf(buffer + len, "\tsound.bass = %ddB [-12...+12]\n",
- sound.bass);
- len += sprintf(buffer + len, "\tsound.treble = %ddB [-12...+12]\n",
- sound.treble);
- break;
- case DMASND_FALCON:
- len += sprintf(buffer + len, "\tsound.volume_left = %ddB [-22.5...0]\n",
- sound.volume_left);
- len += sprintf(buffer + len, "\tsound.volume_right = %ddB [-22.5...0]\n",
- sound.volume_right);
- break;
-#endif /* CONFIG_ATARI */
+ case DMASND_TT:
+ len += sprintf(buffer+len, "\tsound.volume_left = %ddB [-40...0]\n",
+ sound.volume_left);
+ len += sprintf(buffer+len, "\tsound.volume_right = %ddB [-40...0]\n",
+ sound.volume_right);
+ len += sprintf(buffer+len, "\tsound.bass = %ddB [-12...+12]\n",
+ sound.bass);
+ len += sprintf(buffer+len, "\tsound.treble = %ddB [-12...+12]\n",
+ sound.treble);
+ break;
+ case DMASND_FALCON:
+ len += sprintf(buffer+len, "\tsound.volume_left = %ddB [-22.5...0]\n",
+ sound.volume_left);
+ len += sprintf(buffer+len, "\tsound.volume_right = %ddB [-22.5...0]\n",
+ sound.volume_right);
+ break;
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
- case DMASND_AMIGA:
- len += sprintf(buffer + len, "\tsound.volume_left = %d [0...64]\n",
- sound.volume_left);
- len += sprintf(buffer + len, "\tsound.volume_right = %d [0...64]\n",
- sound.volume_right);
- break;
-#endif /* CONFIG_AMIGA */
- }
- len += sprintf(buffer + len, "\tsq.block_size = %d sq.max_count = %d\n",
- sq.block_size, sq.max_count);
- len += sprintf(buffer + len, "\tsq.count = %d sq.rear_size = %d\n", sq.count,
- sq.rear_size);
- len += sprintf(buffer + len, "\tsq.playing = %d sq.syncing = %d\n",
- sq.playing, sq.syncing);
- state.len = len;
- return (0);
+ case DMASND_AMIGA:
+ len += sprintf(buffer+len, "\tsound.volume_left = %d [0...64]\n",
+ sound.volume_left);
+ len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n",
+ sound.volume_right);
+ break;
+#endif /* CONFIG_AMIGA */
+ }
+ len += sprintf(buffer+len, "\tsq.block_size = %d sq.max_count = %d\n",
+ sq.block_size, sq.max_count);
+ len += sprintf(buffer+len, "\tsq.count = %d sq.rear_size = %d\n", sq.count,
+ sq.rear_size);
+ len += sprintf(buffer+len, "\tsq.playing = %d sq.syncing = %d\n",
+ sq.playing, sq.syncing);
+ state.len = len;
+ return(0);
}
-static int
-state_release(void)
+static int state_release(void)
{
- state.busy = 0;
- return (0);
+ state.busy = 0;
+ return(0);
}
-static long
-state_read(char *dest, unsigned long count)
+static long state_read(char *dest, unsigned long count)
{
- int n = state.len - state.ptr;
-
- if (n > count)
- n = count;
- if (n <= 0)
- return (0);
- copy_to_user(dest, &state.buf[state.ptr], n);
- state.ptr += n;
- return (n);
+ int n = state.len-state.ptr;
+ if (n > count)
+ n = count;
+ if (n <= 0)
+ return(0);
+ copy_to_user(dest, &state.buf[state.ptr], n);
+ state.ptr += n;
+ return(n);
}
@@ -3359,241 +3043,232 @@ state_read(char *dest, unsigned long count)
/*** High level stuff ********************************************************/
-static int
-sound_open(struct inode *inode, struct file *file)
-{
- int dev = MINOR(inode->i_rdev) & 0x0f;
- int rc = 0;
-
- switch (dev)
- {
- case SND_DEV_STATUS:
- rc = state_open(file->f_flags);
- break;
- case SND_DEV_CTL:
- rc = mixer_open(file->f_flags);
- break;
- case SND_DEV_DSP:
- case SND_DEV_AUDIO:
- rc = sq_open(file->f_flags);
- if (rc == 0)
- {
- sound.minDev = dev;
- sound.soft = sound.dsp;
- sound.hard = sound.dsp;
- sound_init();
- if (dev == SND_DEV_AUDIO)
- {
- sound_set_speed(8000);
- sound_set_stereo(0);
- sound_set_format(AFMT_MU_LAW);
- }
- }
- break;
- default:
- rc = -ENXIO;
- }
+static int sound_open(struct inode *inode, struct file *file)
+{
+ int dev = MINOR(inode->i_rdev) & 0x0f;
+ int rc = 0;
+
+ switch (dev) {
+ case SND_DEV_STATUS:
+ rc = state_open(file->f_flags);
+ break;
+ case SND_DEV_CTL:
+ rc = mixer_open(file->f_flags);
+ break;
+ case SND_DEV_DSP:
+ case SND_DEV_AUDIO:
+ rc = sq_open(file->f_flags);
+ if (rc == 0) {
+ sound.minDev = dev;
+ sound.soft = sound.dsp;
+ sound.hard = sound.dsp;
+ sound_init();
+ if (dev == SND_DEV_AUDIO) {
+ sound_set_speed(8000);
+ sound_set_stereo(0);
+ sound_set_format(AFMT_MU_LAW);
+ }
+ }
+ break;
+ default:
+ rc = -ENXIO;
+ }
#ifdef MODULE
- if (rc >= 0)
- MOD_INC_USE_COUNT;
+ if (rc >= 0)
+ MOD_INC_USE_COUNT;
#endif
- return (rc);
-}
-
-
-static int
-sound_fsync(struct inode *inode, struct file *filp)
-{
- int dev = MINOR(inode->i_rdev) & 0x0f;
-
- switch (dev)
- {
- case SND_DEV_STATUS:
- case SND_DEV_CTL:
- return (0);
- case SND_DEV_DSP:
- case SND_DEV_AUDIO:
- return (sq_sync());
- default:
- return (unknown_minor_dev("sound_fsync", dev));
- }
-}
-
-
-static void
-sound_release(struct inode *inode, struct file *file)
-{
- int dev = MINOR(inode->i_rdev);
-
- switch (dev & 0x0f)
- {
- case SND_DEV_STATUS:
- state_release();
- break;
- case SND_DEV_CTL:
- mixer_release();
- break;
- case SND_DEV_DSP:
- case SND_DEV_AUDIO:
- sq_release();
- sound.soft = sound.dsp;
- sound.hard = sound.dsp;
- sound_silence();
- break;
- default:
- unknown_minor_dev("sound_release", dev);
- return;
- }
+ return(rc);
+}
+
+
+static int sound_fsync(struct file *filp, struct dentry *dentry)
+{
+ int dev = MINOR(dentry->d_inode->i_rdev) & 0x0f;
+
+ switch (dev) {
+ case SND_DEV_STATUS:
+ case SND_DEV_CTL:
+ return(0);
+ case SND_DEV_DSP:
+ case SND_DEV_AUDIO:
+ return(sq_sync());
+ default:
+ return(unknown_minor_dev("sound_fsync", dev));
+ }
+}
+
+
+static int sound_release(struct inode *inode, struct file *file)
+{
+ int dev = MINOR(inode->i_rdev);
+
+ switch (dev & 0x0f) {
+ case SND_DEV_STATUS:
+ state_release();
+ break;
+ case SND_DEV_CTL:
+ mixer_release();
+ break;
+ case SND_DEV_DSP:
+ case SND_DEV_AUDIO:
+ sq_release();
+ sound.soft = sound.dsp;
+ sound.hard = sound.dsp;
+ sound_silence();
+ break;
+ default:
+ return unknown_minor_dev("sound_release", dev);
+ }
#ifdef MODULE
- MOD_DEC_USE_COUNT;
+ MOD_DEC_USE_COUNT;
#endif
+ return 0;
}
-static long long
-sound_lseek(struct inode *inode, struct file *file,
- long long offset, int orig)
+static long long sound_lseek(struct file *file, long long offset, int orig)
{
- return -ESPIPE;
+ return -ESPIPE;
}
-static ssize_t sound_read(struct file *file, char *buf, szie_t count, loff_t *ppos)
+static ssize_t sound_read(struct file *file, char *buf, size_t count,
+ loff_t *ppos)
{
- int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+ struct inode *inode = file->f_dentry->d_inode;
+ int dev = MINOR(inode->i_rdev);
- switch (dev & 0x0f)
- {
- case SND_DEV_STATUS:
- return (state_read(buf, count));
- case SND_DEV_CTL:
- case SND_DEV_DSP:
- case SND_DEV_AUDIO:
- return (-EPERM);
- default:
- return (unknown_minor_dev("sound_read", dev));
- }
+ switch (dev & 0x0f) {
+ case SND_DEV_STATUS:
+ return(state_read(buf, count));
+ case SND_DEV_CTL:
+ case SND_DEV_DSP:
+ case SND_DEV_AUDIO:
+ return(-EPERM);
+ default:
+ return(unknown_minor_dev("sound_read", dev));
+ }
}
-static ssize_t sound_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+static ssize_t sound_write(struct file *file, const char *buf, size_t count,
+ loff_t *ppos)
{
- int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+ struct inode *inode = file->f_dentry->d_inode;
+ int dev = MINOR(inode->i_rdev);
- switch (dev & 0x0f)
- {
- case SND_DEV_STATUS:
- case SND_DEV_CTL:
- return (-EPERM);
- case SND_DEV_DSP:
- case SND_DEV_AUDIO:
- return (sq_write(buf, count));
- default:
- return (unknown_minor_dev("sound_write", dev));
- }
+ switch (dev & 0x0f) {
+ case SND_DEV_STATUS:
+ case SND_DEV_CTL:
+ return(-EPERM);
+ case SND_DEV_DSP:
+ case SND_DEV_AUDIO:
+ return(sq_write(buf, count));
+ default:
+ return(unknown_minor_dev("sound_write", dev));
+ }
}
static int unknown_minor_dev(char *fname, int dev)
{
- /* printk("%s: Unknown minor device %d\n", fname, dev); */
- return (-ENXIO);
-}
-
-
-static int sound_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg)
-{
- int dev = MINOR(inode->i_rdev);
- u_long fmt;
- int data;
-
- switch (dev & 0x0f)
- {
- case SND_DEV_STATUS:
- return (-EPERM);
- case SND_DEV_CTL:
- return (mixer_ioctl(inode, file, cmd, arg));
- case SND_DEV_AUDIO:
- case SND_DEV_DSP:
- switch (cmd)
- {
- case SNDCTL_DSP_RESET:
- sq_reset();
- return (0);
- case SNDCTL_DSP_POST:
- case SNDCTL_DSP_SYNC:
- return (sound_fsync(inode, file));
-
- /* ++TeSche: before changing any of these it's probably wise to
- * wait until sound playing has settled down
- */
- case SNDCTL_DSP_SPEED:
- sound_fsync(inode, file);
- IOCTL_IN(arg, data);
- return (IOCTL_OUT(arg, sound_set_speed(data)));
- case SNDCTL_DSP_STEREO:
- sound_fsync(inode, file);
- IOCTL_IN(arg, data);
- return (IOCTL_OUT(arg, sound_set_stereo(data)));
- case SOUND_PCM_WRITE_CHANNELS:
- sound_fsync(inode, file);
- IOCTL_IN(arg, data);
- return (IOCTL_OUT(arg, sound_set_stereo(data - 1) + 1));
- case SNDCTL_DSP_SETFMT:
- sound_fsync(inode, file);
- IOCTL_IN(arg, data);
- return (IOCTL_OUT(arg, sound_set_format(data)));
- case SNDCTL_DSP_GETFMTS:
- fmt = 0;
- if (sound.trans)
- {
- if (sound.trans->ct_ulaw)
- fmt |= AFMT_MU_LAW;
- if (sound.trans->ct_alaw)
- fmt |= AFMT_A_LAW;
- if (sound.trans->ct_s8)
- fmt |= AFMT_S8;
- if (sound.trans->ct_u8)
- fmt |= AFMT_U8;
- if (sound.trans->ct_s16be)
- fmt |= AFMT_S16_BE;
- if (sound.trans->ct_u16be)
- fmt |= AFMT_U16_BE;
- if (sound.trans->ct_s16le)
- fmt |= AFMT_S16_LE;
- if (sound.trans->ct_u16le)
- fmt |= AFMT_U16_LE;
- }
- return (IOCTL_OUT(arg, fmt));
- case SNDCTL_DSP_GETBLKSIZE:
- return (IOCTL_OUT(arg, 10240));
- case SNDCTL_DSP_SUBDIVIDE:
- case SNDCTL_DSP_SETFRAGMENT:
- break;
- default:
- return (mixer_ioctl(inode, file, cmd, arg));
- }
- break;
+ /* printk("%s: Unknown minor device %d\n", fname, dev); */
+ return(-ENXIO);
+}
+
+
+static int sound_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg)
+{
+ int dev = MINOR(inode->i_rdev);
+ u_long fmt;
+ int data;
+
+ switch (dev & 0x0f) {
+ case SND_DEV_STATUS:
+ return(-EPERM);
+ case SND_DEV_CTL:
+ return(mixer_ioctl(inode, file, cmd, arg));
+ case SND_DEV_AUDIO:
+ case SND_DEV_DSP:
+ switch (cmd) {
+ case SNDCTL_DSP_RESET:
+ sq_reset();
+ return(0);
+ case SNDCTL_DSP_POST:
+ case SNDCTL_DSP_SYNC:
+ return(sound_fsync(file, file->f_dentry));
+
+ /* ++TeSche: before changing any of these it's probably wise to
+ * wait until sound playing has settled down
+ */
+ case SNDCTL_DSP_SPEED:
+ sound_fsync(file, file->f_dentry);
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_speed(data)));
+ case SNDCTL_DSP_STEREO:
+ sound_fsync(file, file->f_dentry);
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_stereo(data)));
+ case SOUND_PCM_WRITE_CHANNELS:
+ sound_fsync(file, file->f_dentry);
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_stereo(data-1)+1));
+ case SNDCTL_DSP_SETFMT:
+ sound_fsync(file, file->f_dentry);
+ IOCTL_IN(arg, data);
+ return(IOCTL_OUT(arg, sound_set_format(data)));
+ case SNDCTL_DSP_GETFMTS:
+ fmt = 0;
+ if (sound.trans) {
+ if (sound.trans->ct_ulaw)
+ fmt |= AFMT_MU_LAW;
+ if (sound.trans->ct_alaw)
+ fmt |= AFMT_A_LAW;
+ if (sound.trans->ct_s8)
+ fmt |= AFMT_S8;
+ if (sound.trans->ct_u8)
+ fmt |= AFMT_U8;
+ if (sound.trans->ct_s16be)
+ fmt |= AFMT_S16_BE;
+ if (sound.trans->ct_u16be)
+ fmt |= AFMT_U16_BE;
+ if (sound.trans->ct_s16le)
+ fmt |= AFMT_S16_LE;
+ if (sound.trans->ct_u16le)
+ fmt |= AFMT_U16_LE;
+ }
+ return(IOCTL_OUT(arg, fmt));
+ case SNDCTL_DSP_GETBLKSIZE:
+ return(IOCTL_OUT(arg, 10240));
+ case SNDCTL_DSP_SUBDIVIDE:
+ case SNDCTL_DSP_SETFRAGMENT:
+ break;
default:
- return (unknown_minor_dev("sound_ioctl", dev));
- }
- return (-EINVAL);
+ return(mixer_ioctl(inode, file, cmd, arg));
+ }
+ break;
+
+ default:
+ return(unknown_minor_dev("sound_ioctl", dev));
+ }
+ return(-EINVAL);
}
static struct file_operations sound_fops =
{
- sound_lseek,
- sound_read,
- sound_write,
- NULL,
- NULL, /* select */
- sound_ioctl,
- NULL,
- sound_open,
- sound_release,
- sound_fsync
+ sound_lseek,
+ sound_read,
+ sound_write,
+ NULL,
+ NULL, /* select */
+ sound_ioctl,
+ NULL,
+ sound_open,
+ sound_release,
+ sound_fsync
};
@@ -3601,186 +3276,171 @@ static struct file_operations sound_fops =
/*** Config & Setup **********************************************************/
-void
-soundcard_init(void)
+void soundcard_init(void)
{
- int has_sound = 0;
- int i;
+ int has_sound = 0;
+ int i;
- switch (m68k_machtype)
- {
+ switch (m68k_machtype) {
#ifdef CONFIG_ATARI
- case MACH_ATARI:
- if (ATARIHW_PRESENT(PCM_8BIT))
- {
- if (ATARIHW_PRESENT(CODEC))
- sound.mach = machFalcon;
- else if (ATARIHW_PRESENT(MICROWIRE))
- sound.mach = machTT;
- else
- break;
- if ((mfp.int_en_a & mfp.int_mk_a & 0x20) == 0)
- has_sound = 1;
- else
- printk(KERN_ERR "DMA sound driver: Timer A interrupt already in use\n");
- }
- break;
-
-#endif /* CONFIG_ATARI */
+ case MACH_ATARI:
+ if (ATARIHW_PRESENT(PCM_8BIT)) {
+ if (ATARIHW_PRESENT(CODEC))
+ sound.mach = machFalcon;
+ else if (ATARIHW_PRESENT(MICROWIRE))
+ sound.mach = machTT;
+ else
+ break;
+ if ((mfp.int_en_a & mfp.int_mk_a & 0x20) == 0)
+ has_sound = 1;
+ else
+ printk("DMA sound driver: Timer A interrupt already in use\n");
+ }
+ break;
+
+#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
- case MACH_AMIGA:
- if (AMIGAHW_PRESENT(AMI_AUDIO))
- {
- sound.mach = machAmiga;
- has_sound = 1;
- }
- break;
-#endif /* CONFIG_AMIGA */
- }
- if (!has_sound)
- return;
-
- /* Set up sound queue, /dev/audio and /dev/dsp. */
- sound_buffers = kmalloc(numBufs * sizeof(char *), GFP_KERNEL);
+ case MACH_AMIGA:
+ if (AMIGAHW_PRESENT(AMI_AUDIO)) {
+ sound.mach = machAmiga;
+ has_sound = 1;
+ }
+ break;
+#endif /* CONFIG_AMIGA */
+ }
+ if (!has_sound)
+ return;
- if (!sound_buffers)
- {
+ /* Set up sound queue, /dev/audio and /dev/dsp. */
+ sound_buffers = kmalloc (numBufs * sizeof(char *), GFP_KERNEL);
+ if (!sound_buffers) {
out_of_memory:
- printk(KERN_ERR "DMA sound driver: Not enough buffer memory, driver disabled!\n");
- return;
- }
- for (i = 0; i < numBufs; i++)
- {
- sound_buffers[i] = sound.mach.dma_alloc(bufSize << 10, GFP_KERNEL);
- if (!sound_buffers[i])
- {
- while (i--)
- sound.mach.dma_free(sound_buffers[i], bufSize << 10);
- kfree(sound_buffers);
- sound_buffers = 0;
- goto out_of_memory;
- }
- }
+ printk("DMA sound driver: Not enough buffer memory, driver disabled!\n");
+ return;
+ }
+ for (i = 0; i < numBufs; i++) {
+ sound_buffers[i] = sound.mach.dma_alloc (bufSize << 10, GFP_KERNEL);
+ if (!sound_buffers[i]) {
+ while (i--)
+ sound.mach.dma_free (sound_buffers[i], bufSize << 10);
+ kfree (sound_buffers);
+ sound_buffers = 0;
+ goto out_of_memory;
+ }
+ }
#ifndef MODULE
- /* Register driver with the VFS. */
- register_chrdev(SOUND_MAJOR, "sound", &sound_fops);
+ /* Register driver with the VFS. */
+ register_chrdev(SOUND_MAJOR, "sound", &sound_fops);
#endif
- sq_init(numBufs, bufSize << 10, sound_buffers);
+ sq_init(numBufs, bufSize << 10, sound_buffers);
- /* Set up /dev/sndstat. */
- state_init();
+ /* Set up /dev/sndstat. */
+ state_init();
- /* Set up /dev/mixer. */
- mixer_init();
+ /* Set up /dev/mixer. */
+ mixer_init();
- if (!sound.mach.irqinit())
- {
- printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
- return;
- }
+ if (!sound.mach.irqinit()) {
+ printk("DMA sound driver: Interrupt initialization failed\n");
+ return;
+ }
#ifdef MODULE
- irq_installed = 1;
+ irq_installed = 1;
#endif
- printk(KERN_INFO "DMA sound driver installed, using %d buffers of %dk.\n", numBufs,
- bufSize);
+ printk("DMA sound driver installed, using %d buffers of %dk.\n", numBufs,
+ bufSize);
- return;
+ return;
}
void sound_setup(char *str, int *ints)
{
- /* ++Martin: stub, could possibly be merged with soundcard.c et al later */
+ /* ++Martin: stub, could possibly be merged with soundcard.c et al later */
}
#define MAXARGS 8 /* Should be sufficient for now */
-void
-dmasound_setup(char *str, int *ints)
-{
- /* check the bootstrap parameter for "dmasound=" */
-
- switch (ints[0])
- {
- case 3:
- if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
- printk(KERN_WARNING "dmasound_setup: illegal catch radius, using default = %d\n", catchRadius);
- else
- catchRadius = ints[3];
- /* fall through */
- case 2:
- if (ints[1] < MIN_BUFFERS)
- printk(KERN_WARNING "dmasound_setup: illegal number of buffers, using default = %d\n", numBufs);
- else
- numBufs = ints[1];
- if (ints[2] < MIN_BUFSIZE || ints[2] > MAX_BUFSIZE)
- printk(KERN_WARNING "dmasound_setup: illegal buffer size, using default = %d\n", bufSize);
- else
- bufSize = ints[2];
- break;
- case 0:
- break;
- default:
- printk(KERN_WARNING "dmasound_setup: illegal number of arguments\n");
- }
+void dmasound_setup(char *str, int *ints)
+{
+ /* check the bootstrap parameter for "dmasound=" */
+
+ switch (ints[0]) {
+ case 3:
+ if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
+ printk("dmasound_setup: illegal catch radius, using default = %d\n", catchRadius);
+ else
+ catchRadius = ints[3];
+ /* fall through */
+ case 2:
+ if (ints[1] < MIN_BUFFERS)
+ printk("dmasound_setup: illegal number of buffers, using default = %d\n", numBufs);
+ else
+ numBufs = ints[1];
+ if (ints[2] < MIN_BUFSIZE || ints[2] > MAX_BUFSIZE)
+ printk("dmasound_setup: illegal buffer size, using default = %d\n", bufSize);
+ else
+ bufSize = ints[2];
+ break;
+ case 0:
+ break;
+ default:
+ printk("dmasound_setup: illegal number of arguments\n");
+ }
}
#ifdef MODULE
-static int dmasound[MAXARGS] = {
- 0
-};
+static int dmasound[MAXARGS] = { 0 };
int init_module(void)
{
- int err, i = 0;
- int ints[MAXARGS + 1];
+ int err, i = 0;
+ int ints[MAXARGS+1];
- while (i < MAXARGS && dmasound[i])
- ints[i + 1] = dmasound[i++];
- ints[0] = i;
+ while (i < MAXARGS && dmasound[i])
+ ints[i + 1] = dmasound[i++];
+ ints[0] = i;
- if (i)
- dmasound_setup("dmasound=", ints);
+ if (i)
+ dmasound_setup("dmasound=", ints);
- err = register_chrdev(SOUND_MAJOR, "sound", &sound_fops);
- if (err)
- {
- printk(KERN_ERR "dmasound: driver already loaded/included in kernel\n");
- return err;
- }
- chrdev_registered = 1;
- soundcard_init();
+ err = register_chrdev(SOUND_MAJOR, "sound", &sound_fops);
+ if (err) {
+ printk("dmasound: driver already loaded/included in kernel\n");
+ return err;
+ }
+ chrdev_registered = 1;
+ soundcard_init();
- return 0;
+ return 0;
}
void cleanup_module(void)
{
- int i;
+ int i;
- if (MOD_IN_USE)
- return;
+ if (MOD_IN_USE)
+ return;
- if (chrdev_registered)
- unregister_chrdev(SOUND_MAJOR, "sound");
+ if (chrdev_registered)
+ unregister_chrdev(SOUND_MAJOR, "sound");
- if (irq_installed)
- {
- sound_silence();
- sound.mach.irqcleanup();
- }
- if (sound_buffers)
- {
- for (i = 0; i < numBufs; i++)
- sound.mach.dma_free(sound_buffers[i], bufSize << 10);
- kfree(sound_buffers);
- }
+ if (irq_installed) {
+ sound_silence();
+ sound.mach.irqcleanup();
+ }
+
+ if (sound_buffers) {
+ for (i = 0; i < numBufs; i++)
+ sound.mach.dma_free(sound_buffers[i], bufSize << 10);
+ kfree(sound_buffers);
+ }
}
-#endif /* MODULE */
+#endif /* MODULE */
diff --git a/drivers/sound/gus_card.c b/drivers/sound/gus_card.c
index 92e6dbab6..62d10257d 100644
--- a/drivers/sound/gus_card.c
+++ b/drivers/sound/gus_card.c
@@ -3,6 +3,7 @@
*
* Detection routine for the Gravis Ultrasound.
*/
+
/*
* Copyright (C) by Hannu Savolainen 1993-1997
*
@@ -10,6 +11,15 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+/*
+ * Frank van de Pol : Fixed GUS MAX interrupt handling, enabled simultanious
+ * usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
+ *
+ * Status:
+ * Tested...
+ */
+
+
#include <linux/config.h>
#include <linux/module.h>
@@ -23,14 +33,19 @@
void gusintr(int irq, void *dev_id, struct pt_regs *dummy);
int gus_base = 0, gus_irq = 0, gus_dma = 0;
+int gus_no_wave_dma = 0;
extern int gus_wave_volume;
extern int gus_pcm_volume;
extern int have_gus_max;
int gus_pnp_flag = 0;
+#ifdef CONFIG_GUS16
+static int db16 = 0; /* Has a Gus16 AD1848 on it */
+#endif
void attach_gus_card(struct address_info *hw_config)
{
- snd_set_irq_handler(hw_config->irq, gusintr, "Gravis Ultrasound", hw_config->osp, hw_config);
+ if(request_irq(hw_config->irq, gusintr, 0, "Gravis Ultrasound", hw_config)<0)
+ printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq);
gus_wave_init(hw_config);
@@ -38,10 +53,10 @@ void attach_gus_card(struct address_info *hw_config)
request_region(hw_config->io_base + 0x100, 12, "GUS"); /* 0x10c-> is MAX */
if (sound_alloc_dma(hw_config->dma, "GUS"))
- printk("gus_card.c: Can't allocate DMA channel\n");
+ printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma);
if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
if (sound_alloc_dma(hw_config->dma2, "GUS(2)"))
- printk("gus_card.c: Can't allocate DMA channel 2\n");
+ printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma2);
#if defined(CONFIG_MIDI)
gus_midi_init(hw_config);
#endif
@@ -101,7 +116,7 @@ void unload_gus(struct address_info *hw_config)
release_region(hw_config->io_base, 16);
release_region(hw_config->io_base + 0x100, 12); /* 0x10c-> is MAX */
- snd_release_irq(hw_config->irq, hw_config);
+ free_irq(hw_config->irq, hw_config);
sound_free_dma(hw_config->dma);
@@ -119,6 +134,10 @@ void gusintr(int irq, void *dev_id, struct pt_regs *dummy)
#ifdef CONFIG_GUSMAX
if (have_gus_max)
+ adintr(irq, (void *)hw_config->slots[1], NULL);
+#endif
+#ifdef CONFIG_GUS16
+ if (db16)
adintr(irq, (void *)hw_config->slots[3], NULL);
#endif
@@ -191,6 +210,8 @@ void unload_gus_db16(struct address_info *hw_config)
}
#endif
+
+
#ifdef MODULE
static struct address_info config;
@@ -206,7 +227,10 @@ int dma = -1;
int dma16 = -1; /* Set this for modules that need it */
int type = 0; /* 1 for PnP */
int gus16 = 0;
-static int db16 = 0; /* Has a Gus16 AD1848 on it */
+#ifdef CONFIG_GUSMAX
+static int no_wave_dma = 0;/* Set if no dma is to be used for the
+ wave table (GF1 chip) */
+#endif
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
@@ -214,7 +238,12 @@ MODULE_PARM(dma, "i");
MODULE_PARM(dma16, "i");
MODULE_PARM(type, "i");
MODULE_PARM(gus16, "i");
+#ifdef CONFIG_GUSMAX
+MODULE_PARM(no_wave_dma, "i");
+#endif
+#ifdef CONFIG_GUS16
MODULE_PARM(db16, "i");
+#endif
int init_module(void)
{
@@ -230,6 +259,10 @@ int init_module(void)
config.dma = dma;
config.dma2 = dma16;
config.card_subtype = type;
+
+#ifdef CONFIG_GUSMAX
+ gus_no_wave_dma = no_wave_dma;
+#endif
#if defined(CONFIG_GUS16)
if (probe_gus_db16(&config) && gus16)
diff --git a/drivers/sound/gus_wave.c b/drivers/sound/gus_wave.c
index 7b202f3ef..6dc52aef6 100644
--- a/drivers/sound/gus_wave.c
+++ b/drivers/sound/gus_wave.c
@@ -11,11 +11,14 @@
* for more info.
*/
/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * Frank van de Pol : Fixed GUS MAX interrupt handling. Enabled simultanious
+ * usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
*/
+
+
#include <linux/config.h>
-
#define GUSPNP_AUTODETECT
#include "sound_config.h"
@@ -70,10 +73,11 @@ struct voice_info
};
static struct voice_alloc_info *voice_alloc;
-
+static struct address_info *gus_hw_config;
extern int gus_base;
extern int gus_irq, gus_dma;
extern int gus_pnp_flag;
+extern int gus_no_wave_dma;
static int gus_dma2 = -1;
static int dual_dma_mode = 0;
static long gus_mem_size = 0;
@@ -833,7 +837,7 @@ static void gus_initialize(void)
gus_select_voice(0); /* This disables writes to IRQ/DMA reg */
- gusintr(gus_irq, NULL, NULL); /* Serve pending interrupts */
+ gusintr(gus_irq, (void *)gus_hw_config, NULL); /* Serve pending interrupts */
inb(u_Status); /* Touch the status register */
@@ -859,26 +863,26 @@ static void pnp_mem_init(void)
int bank_sizes[4];
int i, j, bits = -1, nbanks = 0;
-/*
- * This routine determines what kind of RAM is installed in each of the four
- * SIMM banks and configures the DRAM address decode logic accordingly.
- */
+ /*
+ * This routine determines what kind of RAM is installed in each of the four
+ * SIMM banks and configures the DRAM address decode logic accordingly.
+ */
-/*
- * Place the chip into enhanced mode
- */
+ /*
+ * Place the chip into enhanced mode
+ */
gus_write8(0x19, gus_read8(0x19) | 0x01);
gus_write8(0x53, gus_look8(0x53) & ~0x02); /* Select DRAM I/O access */
-/*
- * Set memory configuration to 4 DRAM banks of 4M in each (16M total).
- */
+ /*
+ * Set memory configuration to 4 DRAM banks of 4M in each (16M total).
+ */
gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | 0x000c);
-/*
- * Perform the DRAM size detection for each bank individually.
- */
+ /*
+ * Perform the DRAM size detection for each bank individually.
+ */
for (bank = 0; bank < 4; bank++)
{
int size = 0;
@@ -1649,22 +1653,26 @@ static int guswave_open(int dev, int mode)
voice_alloc->timestamp = 0;
- if ((err = DMAbuf_open_dma(gus_devnum)) < 0)
- {
- /* printk( "GUS: Loading samples without DMA\n"); */
- gus_no_dma = 1; /* Upload samples using PIO */
+ if (gus_no_wave_dma) {
+ gus_no_dma = 1;
+ } else {
+ if ((err = DMAbuf_open_dma(gus_devnum)) < 0)
+ {
+ /* printk( "GUS: Loading samples without DMA\n"); */
+ gus_no_dma = 1; /* Upload samples using PIO */
+ }
+ else
+ gus_no_dma = 0;
}
- else
- gus_no_dma = 0;
init_waitqueue(&dram_sleeper);
gus_busy = 1;
active_device = GUS_DEV_WAVE;
- gusintr(gus_irq, NULL, NULL); /* Serve pending interrupts */
+ gusintr(gus_irq, (void *)gus_hw_config, NULL); /* Serve pending interrupts */
gus_initialize();
gus_reset();
- gusintr(gus_irq, NULL, NULL); /* Serve pending interrupts */
+ gusintr(gus_irq, (void *)gus_hw_config, NULL); /* Serve pending interrupts */
return 0;
}
@@ -2953,6 +2961,7 @@ void gus_wave_init(struct address_info *hw_config)
gus_irq = irq;
gus_dma = dma;
gus_dma2 = dma2;
+ gus_hw_config = hw_config;
if (gus_dma2 == -1)
gus_dma2 = dma;
@@ -3114,8 +3123,8 @@ void gus_wave_init(struct address_info *hw_config)
reset_sample_memory();
gus_initialize();
-
- if (gus_mem_size > 0)
+
+ if ((gus_mem_size > 0) & !gus_no_wave_dma)
{
if ((dev = sound_alloc_audiodev()) != -1)
{
diff --git a/drivers/sound/local.h.master b/drivers/sound/local.h.master
index b333f0ce0..65d8c0259 100644
--- a/drivers/sound/local.h.master
+++ b/drivers/sound/local.h.master
@@ -42,7 +42,7 @@
defined(CONFIG_MSS_MODULE) || defined(CONFIG_SSCAPE_MODULE) || \
defined(CONFIG_TRIX_MODULE) || defined(CONFIG_MAD16_MODULE) || \
defined(CONFIG_CS4232_MODULE) || defined(CONFIG_OPL3SA1_MODULE) || \
- defined(CONFIG_SOFTOSS_MODULE)
+ defined(CONFIG_SOFTOSS_MODULE) || defined(CONFIG_VIDC_SOUND)
# define CONFIG_AUDIO
#endif
diff --git a/drivers/sound/mad16.c b/drivers/sound/mad16.c
index 4870ec799..30f366964 100644
--- a/drivers/sound/mad16.c
+++ b/drivers/sound/mad16.c
@@ -56,6 +56,10 @@
* CD-ROM DMA (Mitsumi or IDE): 0x00=DMA5, 0x01=DMA6, 0x02=DMA7 or 0x03=disabled
*
* For use with sbpcd, address 0x340, set MAD16_CDSEL to 0x03 or 0x23.
+ *
+ * Changes
+ *
+ * Alan Cox Clean up, added module selections.
*/
#include "sound_config.h"
@@ -118,48 +122,47 @@ static int c931_detected; /* minor diferences from C930 */
#define DDB(x)
#endif
-static unsigned char
-mad_read(int port)
+static unsigned char mad_read(int port)
{
- unsigned long flags;
- unsigned char tmp;
+ unsigned long flags;
+ unsigned char tmp;
save_flags(flags);
cli();
switch (board_type) /* Output password */
- {
- case C928:
- case MOZART:
- outb((0xE2), PASSWD_REG);
- break;
-
- case C929:
- outb((0xE3), PASSWD_REG);
- break;
-
- case C930:
- /* outb(( 0xE4), PASSWD_REG); */
- break;
-
- case C924:
- outb((0xE5), PASSWD_REG);
- break;
- }
+ {
+ case C928:
+ case MOZART:
+ outb((0xE2), PASSWD_REG);
+ break;
+
+ case C929:
+ outb((0xE3), PASSWD_REG);
+ break;
+
+ case C930:
+ /* outb(( 0xE4), PASSWD_REG); */
+ break;
+
+ case C924:
+ outb((0xE5), PASSWD_REG);
+ break;
+ }
if (board_type == C930)
- {
- outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
- tmp = inb(0xe0f); /* Read from data reg */
- } else
+ {
+ outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
+ tmp = inb(0xe0f); /* Read from data reg */
+ }
+ else
tmp = inb(port);
restore_flags(flags);
return tmp;
}
-static void
-mad_write(int port, int value)
+static void mad_write(int port, int value)
{
unsigned long flags;
@@ -167,65 +170,65 @@ mad_write(int port, int value)
cli();
switch (board_type) /* Output password */
- {
- case C928:
- case MOZART:
- outb((0xE2), PASSWD_REG);
- break;
-
- case C929:
- outb((0xE3), PASSWD_REG);
- break;
-
- case C930:
- /* outb(( 0xE4), PASSWD_REG); */
- break;
-
- case C924:
- outb((0xE5), PASSWD_REG);
- break;
- }
+ {
+ case C928:
+ case MOZART:
+ outb((0xE2), PASSWD_REG);
+ break;
+
+ case C929:
+ outb((0xE3), PASSWD_REG);
+ break;
+
+ case C930:
+ /* outb(( 0xE4), PASSWD_REG); */
+ break;
+
+ case C924:
+ outb((0xE5), PASSWD_REG);
+ break;
+ }
if (board_type == C930)
- {
- outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
- outb(((unsigned char) (value & 0xff)), 0xe0f);
- } else
+ {
+ outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
+ outb(((unsigned char) (value & 0xff)), 0xe0f);
+ }
+ else
outb(((unsigned char) (value & 0xff)), port);
restore_flags(flags);
}
-static int
-detect_c930(void)
+static int detect_c930(void)
{
unsigned char tmp = mad_read(MC1_PORT);
if ((tmp & 0x06) != 0x06)
- {
- DDB(printk("Wrong C930 signature (%x)\n", tmp));
- /* return 0; */
- }
+ {
+ DDB(printk("Wrong C930 signature (%x)\n", tmp));
+ /* return 0; */
+ }
mad_write(MC1_PORT, 0);
if (mad_read(MC1_PORT) != 0x06)
- {
- DDB(printk("Wrong C930 signature2 (%x)\n", tmp));
- /* return 0; */
- }
+ {
+ DDB(printk("Wrong C930 signature2 (%x)\n", tmp));
+ /* return 0; */
+ }
mad_write(MC1_PORT, tmp); /* Restore bits */
mad_write(MC7_PORT, 0);
if ((tmp = mad_read(MC7_PORT)) != 0)
- {
- DDB(printk("MC7 not writable (%x)\n", tmp));
- return 0;
- }
+ {
+ DDB(printk("MC7 not writable (%x)\n", tmp));
+ return 0;
+ }
mad_write(MC7_PORT, 0xcb);
if ((tmp = mad_read(MC7_PORT)) != 0xcb)
- {
- DDB(printk("MC7 not writable2 (%x)\n", tmp));
- return 0;
- }
+ {
+ DDB(printk("MC7 not writable2 (%x)\n", tmp));
+ return 0;
+ }
tmp = mad_read(MC0_PORT+18);
if (tmp == 0xff)
@@ -262,113 +265,109 @@ detect_c930(void)
* the PnP bios will not recognize the chip on the next
* warm boot and may assignd different resources to other
* PnP/PCI cards.
- */
+ */
mad_write(MC0_PORT+17, 0x04);
return 1;
}
-static int
-detect_mad16(void)
+static int detect_mad16(void)
{
- unsigned char tmp, tmp2;
- int i;
+ unsigned char tmp, tmp2;
+ int i;
+
+ /*
+ * Check that reading a register doesn't return bus float (0xff)
+ * when the card is accessed using password. This may fail in case
+ * the card is in low power mode. Normally at least the power saving mode
+ * bit should be 0.
+ */
-/*
- * Check that reading a register doesn't return bus float (0xff)
- * when the card is accessed using password. This may fail in case
- * the card is in low power mode. Normally at least the power saving mode
- * bit should be 0.
- */
if ((tmp = mad_read(MC1_PORT)) == 0xff)
- {
- DDB(printk("MC1_PORT returned 0xff\n"));
- return 0;
- }
+ {
+ DDB(printk("MC1_PORT returned 0xff\n"));
+ return 0;
+ }
for (i = 0xf8d; i <= 0xf98; i++)
DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i)));
if (board_type == C930)
return detect_c930();
-/*
- * Now check that the gate is closed on first I/O after writing
- * the password. (This is how a MAD16 compatible card works).
- */
+
+ /*
+ * Now check that the gate is closed on first I/O after writing
+ * the password. (This is how a MAD16 compatible card works).
+ */
if ((tmp2 = inb(MC1_PORT)) == tmp) /* It didn't close */
- {
- DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
- return 0;
- }
+ {
+ DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
+ return 0;
+ }
mad_write(MC1_PORT, tmp ^ 0x80); /* Toggle a bit */
if ((tmp2 = mad_read(MC1_PORT)) != (tmp ^ 0x80)) /* Compare the bit */
- {
- mad_write(MC1_PORT, tmp); /* Restore */
- DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
- return 0;
- }
+ {
+ mad_write(MC1_PORT, tmp); /* Restore */
+ DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
+ return 0;
+ }
mad_write(MC1_PORT, tmp); /* Restore */
return 1; /* Bingo */
-
}
-static int
-wss_init(struct address_info *hw_config)
+static int wss_init(struct address_info *hw_config)
{
- int ad_flags = 0;
+ int ad_flags = 0;
-/*
- * Verify the WSS parameters
- */
+ /*
+ * Verify the WSS parameters
+ */
if (check_region(hw_config->io_base, 8))
- {
- printk("MSS: I/O port conflict\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "MSS: I/O port conflict\n");
+ return 0;
+ }
if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
return 0;
/*
- * Check if the IO port returns valid signature. The original MS Sound
- * system returns 0x04 while some cards (AudioTrix Pro for example)
- * return 0x00.
+ * Check if the IO port returns valid signature. The original MS Sound
+ * system returns 0x04 while some cards (AudioTrix Pro for example)
+ * return 0x00.
*/
if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 &&
(inb(hw_config->io_base + 3) & 0x3f) != 0x00)
- {
- DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3)));
- return 0;
- }
+ {
+ DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3)));
+ return 0;
+ }
if (hw_config->irq > 11)
- {
- printk("MSS: Bad IRQ %d\n", hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq);
+ return 0;
+ }
if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
- {
- printk("MSS: Bad DMA %d\n", hw_config->dma);
- return 0;
- }
+ {
+ printk(KERN_ERR "MSS: Bad DMA %d\n", hw_config->dma);
+ return 0;
+ }
/*
- * Check that DMA0 is not in use with a 8 bit board.
+ * Check that DMA0 is not in use with a 8 bit board.
*/
if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)
- {
- printk("MSS: Can't use DMA0 with a 8 bit card/slot\n");
- return 0;
- }
+ {
+ printk("MSS: Can't use DMA0 with a 8 bit card/slot\n");
+ return 0;
+ }
if (hw_config->irq > 7 && hw_config->irq != 9 && inb(hw_config->io_base + 3) & 0x80)
- {
- printk("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
- }
+ printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
return 1;
}
-static int
-init_c930(struct address_info *hw_config)
+static int init_c930(struct address_info *hw_config)
{
- unsigned char cfg = 0;
+ unsigned char cfg = 0;
#ifdef MAD16_CONF
cfg |= (0x0f & MAD16_CONF);
@@ -384,24 +383,23 @@ init_c930(struct address_info *hw_config)
}
switch (hw_config->io_base)
- {
- case 0x530:
- cfg |= 0x00;
- break;
- case 0xe80:
- cfg |= 0x10;
- break;
- case 0xf40:
- cfg |= 0x20;
- break;
- case 0x604:
- cfg |= 0x30;
- break;
-
- default:
- printk("MAD16: Invalid codec port %x\n", hw_config->io_base);
- return 0;
- }
+ {
+ case 0x530:
+ cfg |= 0x00;
+ break;
+ case 0xe80:
+ cfg |= 0x10;
+ break;
+ case 0xf40:
+ cfg |= 0x20;
+ break;
+ case 0x604:
+ cfg |= 0x30;
+ break;
+ default:
+ printk(KERN_ERR "MAD16: Invalid codec port %x\n", hw_config->io_base);
+ return 0;
+ }
mad_write(MC1_PORT, cfg);
/* MC2 is CD configuration. Don't touch it. */
@@ -423,94 +421,98 @@ init_c930(struct address_info *hw_config)
return wss_init(hw_config);
}
-static int
-chip_detect(void)
+static int chip_detect(void)
{
- int i;
+ int i;
-/*
- * Then try to detect with the old password
- */
+ /*
+ * Then try to detect with the old password
+ */
board_type = C924;
DDB(printk("Detect using password = 0xE5\n"));
if (!detect_mad16()) /* No luck. Try different model */
- {
- board_type = C928;
-
- DDB(printk("Detect using password = 0xE2\n"));
-
- if (!detect_mad16())
- {
- board_type = C929;
-
- DDB(printk("Detect using password = 0xE3\n"));
-
- if (!detect_mad16())
- {
- if (inb(PASSWD_REG) != 0xff)
- return 0;
-
-/*
- * First relocate MC# registers to 0xe0e/0xe0f, disable password
- */
-
- outb((0xE4), PASSWD_REG);
- outb((0x80), PASSWD_REG);
-
- board_type = C930;
-
- DDB(printk("Detect using password = 0xE4\n"));
-
- for (i = 0xf8d; i <= 0xf93; i++)
- DDB(printk("port %03x = %02x\n", i, mad_read(i)));
-
- if (!detect_mad16())
- return 0;
-
- DDB(printk("mad16.c: 82C930 detected\n"));
- } else
- {
- DDB(printk("mad16.c: 82C929 detected\n"));
- }
- } else
- {
- unsigned char model;
-
- if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03)
- {
- DDB(printk("mad16.c: Mozart detected\n"));
- board_type = MOZART;
- } else
- {
- DDB(printk("mad16.c: 82C928 detected???\n"));
- board_type = C928;
- }
- }
- }
+ {
+ board_type = C928;
+
+ DDB(printk("Detect using password = 0xE2\n"));
+
+ if (!detect_mad16())
+ {
+ board_type = C929;
+
+ DDB(printk("Detect using password = 0xE3\n"));
+
+ if (!detect_mad16())
+ {
+ if (inb(PASSWD_REG) != 0xff)
+ return 0;
+
+ /*
+ * First relocate MC# registers to 0xe0e/0xe0f, disable password
+ */
+
+ outb((0xE4), PASSWD_REG);
+ outb((0x80), PASSWD_REG);
+
+ board_type = C930;
+
+ DDB(printk("Detect using password = 0xE4\n"));
+
+ for (i = 0xf8d; i <= 0xf93; i++)
+ DDB(printk("port %03x = %02x\n", i, mad_read(i)));
+
+ if (!detect_mad16())
+ return 0;
+
+ DDB(printk("mad16.c: 82C930 detected\n"));
+ }
+ else
+ {
+ DDB(printk("mad16.c: 82C929 detected\n"));
+ }
+ }
+ else
+ {
+ unsigned char model;
+
+ if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03)
+ {
+ DDB(printk("mad16.c: Mozart detected\n"));
+ board_type = MOZART;
+ }
+ else
+ {
+ DDB(printk("mad16.c: 82C928 detected???\n"));
+ board_type = C928;
+ }
+ }
+ }
return 1;
}
-int
-probe_mad16(struct address_info *hw_config)
+int probe_mad16(struct address_info *hw_config)
{
- int i;
- static int valid_ports[] =
- {0x530, 0xe80, 0xf40, 0x604};
- unsigned char tmp;
- unsigned char cs4231_mode = 0;
+ int i;
+ static int valid_ports[] =
+ {
+ 0x530, 0xe80, 0xf40, 0x604
+ };
+ unsigned char tmp;
+ unsigned char cs4231_mode = 0;
- int ad_flags = 0;
+ int ad_flags = 0;
if (already_initialized)
return 0;
mad16_osp = hw_config->osp;
-/*
- * Check that all ports return 0xff (bus float) when no password
- * is written to the password register.
- */
+
+ /*
+ * Check that all ports return 0xff (bus float) when no password
+ * is written to the password register.
+ */
DDB(printk("--- Detecting MAD16 / Mozart ---\n"));
if (!chip_detect())
@@ -530,25 +532,25 @@ probe_mad16(struct address_info *hw_config)
tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80; /* Enable WSS, Disable SB */
for (i = 0; i < 5; i++)
- {
- if (i > 3) /* Not a valid port */
- {
- printk("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
- return 0;
- }
- if (valid_ports[i] == hw_config->io_base)
- {
- tmp |= i << 4; /* WSS port select bits */
- break;
- }
- }
+ {
+ if (i > 3) /* Not a valid port */
+ {
+ printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
+ return 0;
+ }
+ if (valid_ports[i] == hw_config->io_base)
+ {
+ tmp |= i << 4; /* WSS port select bits */
+ break;
+ }
+ }
-/*
- * Set optional CD-ROM and joystick settings.
- */
+ /*
+ * Set optional CD-ROM and joystick settings.
+ */
-#ifdef MAD16_CONF
tmp &= ~0x0f;
+#if defined(MAD16_CONF)
tmp |= ((MAD16_CONF) & 0x0f); /* CD-ROM and joystick bits */
#endif
mad_write(MC1_PORT, tmp);
@@ -567,11 +569,11 @@ probe_mad16(struct address_info *hw_config)
mad_write(MC3_PORT, 0xf0); /* Disable SB */
if (board_type == C924) /* Specific C924 init values */
- {
- mad_write(MC4_PORT, 0xA0);
- mad_write(MC5_PORT, 0x05);
- mad_write(MC6_PORT, 0x03);
- }
+ {
+ mad_write(MC4_PORT, 0xA0);
+ mad_write(MC5_PORT, 0x05);
+ mad_write(MC6_PORT, 0x03);
+ }
if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
return 0;
@@ -579,15 +581,16 @@ probe_mad16(struct address_info *hw_config)
cs4231_mode = 0x02; /* CS4248/CS4231 sync delay switch */
if (board_type == C929)
- {
- mad_write(MC4_PORT, 0xa2);
- mad_write(MC5_PORT, 0xA5 | cs4231_mode);
- mad_write(MC6_PORT, 0x03); /* Disable MPU401 */
- } else
- {
- mad_write(MC4_PORT, 0x02);
- mad_write(MC5_PORT, 0x30 | cs4231_mode);
- }
+ {
+ mad_write(MC4_PORT, 0xa2);
+ mad_write(MC5_PORT, 0xA5 | cs4231_mode);
+ mad_write(MC6_PORT, 0x03); /* Disable MPU401 */
+ }
+ else
+ {
+ mad_write(MC4_PORT, 0x02);
+ mad_write(MC5_PORT, 0x30 | cs4231_mode);
+ }
for (i = 0xf8d; i <= 0xf93; i++)
DDB(printk("port %03x after init = %02x\n", i, mad_read(i)));
@@ -597,24 +600,21 @@ probe_mad16(struct address_info *hw_config)
return 1;
}
-void
-attach_mad16(struct address_info *hw_config)
+void attach_mad16(struct address_info *hw_config)
{
- static char interrupt_bits[12] =
- {
+ static char interrupt_bits[12] = {
-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
};
- char bits;
+ char bits;
- static char dma_bits[4] =
- {
+ static char dma_bits[4] = {
1, 2, 0, 3
};
- int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
- int ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2;
- unsigned char dma2_bit = 0;
+ int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
+ int ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2;
+ unsigned char dma2_bit = 0;
already_initialized = 1;
@@ -622,8 +622,9 @@ attach_mad16(struct address_info *hw_config)
return;
/*
- * Set the IRQ and DMA addresses.
+ * Set the IRQ and DMA addresses.
*/
+
if (board_type == C930)
interrupt_bits[5] = 0x28; /* Also IRQ5 is possible on C930 */
@@ -633,35 +634,35 @@ attach_mad16(struct address_info *hw_config)
outb((bits | 0x40), config_port);
if ((inb(version_port) & 0x40) == 0)
- printk("[IRQ Conflict?]");
+ printk(KERN_ERR "[IRQ Conflict?]\n");
-/*
- * Handle the capture DMA channel
- */
+ /*
+ * Handle the capture DMA channel
+ */
if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
- {
- if (!((dma == 0 && dma2 == 1) ||
+ {
+ if (!((dma == 0 && dma2 == 1) ||
(dma == 1 && dma2 == 0) ||
(dma == 3 && dma2 == 0)))
- { /* Unsupported combination. Try to swap channels */
- int tmp = dma;
-
- dma = dma2;
- dma2 = tmp;
- }
- if ((dma == 0 && dma2 == 1) ||
- (dma == 1 && dma2 == 0) ||
- (dma == 3 && dma2 == 0))
- {
- dma2_bit = 0x04; /* Enable capture DMA */
- } else
- {
- printk("MAD16: Invalid capture DMA\n");
- dma2 = dma;
- }
- } else
- dma2 = dma;
+ { /* Unsupported combination. Try to swap channels */
+ int tmp = dma;
+
+ dma = dma2;
+ dma2 = tmp;
+ }
+ if ((dma == 0 && dma2 == 1) || (dma == 1 && dma2 == 0) ||
+ (dma == 3 && dma2 == 0))
+ {
+ dma2_bit = 0x04; /* Enable capture DMA */
+ }
+ else
+ {
+ printk("MAD16: Invalid capture DMA\n");
+ dma2 = dma;
+ }
+ }
+ else dma2 = dma;
outb((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */
@@ -673,24 +674,23 @@ attach_mad16(struct address_info *hw_config)
request_region(hw_config->io_base, 4, "MAD16 WSS config");
}
-void
-attach_mad16_mpu(struct address_info *hw_config)
+void attach_mad16_mpu(struct address_info *hw_config)
{
if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
- {
-#if defined(CONFIG_MIDI)
+ {
+#if defined(CONFIG_MIDI) && defined(CONFIG_MAD16_OLDCARD)
- if (mad_read(MC1_PORT) & 0x20)
- hw_config->io_base = 0x240;
- else
- hw_config->io_base = 0x220;
+ if (mad_read(MC1_PORT) & 0x20)
+ hw_config->io_base = 0x240;
+ else
+ hw_config->io_base = 0x220;
- hw_config->name = "Mad16/Mozart";
- sb_dsp_init(hw_config);
+ hw_config->name = "Mad16/Mozart";
+ sb_dsp_init(hw_config);
#endif
- return;
- }
+ return;
+ }
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
if (!already_initialized)
return;
@@ -701,68 +701,67 @@ attach_mad16_mpu(struct address_info *hw_config)
#endif
}
-int
-probe_mad16_mpu(struct address_info *hw_config)
+int probe_mad16_mpu(struct address_info *hw_config)
{
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
- static int mpu_attached = 0;
- static int valid_ports[] =
- {0x330, 0x320, 0x310, 0x300};
- static short valid_irqs[] =
- {9, 10, 5, 7};
- unsigned char tmp;
-
- int i; /* A variable with secret power */
+ static int mpu_attached = 0;
+ static int valid_ports[] = {
+ 0x330, 0x320, 0x310, 0x300
+ };
+
+ static short valid_irqs[] = {9, 10, 5, 7};
+ unsigned char tmp;
+ int i; /* A variable with secret power */
if (!already_initialized) /* The MSS port must be initialized first */
return 0;
- if (mpu_attached) /* Don't let them call this twice */
+ if (mpu_attached) /* Don't let them call this twice */
return 0;
mpu_attached = 1;
if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
- {
-
-#if defined(CONFIG_MIDI)
- unsigned char tmp;
-
- tmp = mad_read(MC3_PORT);
-
- /*
- * MAD16 SB base is defined by the WSS base. It cannot be changed
- * alone.
- * Ignore configured I/O base. Use the active setting.
- */
-
- if (mad_read(MC1_PORT) & 0x20)
- hw_config->io_base = 0x240;
- else
- hw_config->io_base = 0x220;
-
- switch (hw_config->irq)
- {
- case 5:
- tmp = (tmp & 0x3f) | 0x80;
- break;
- case 7:
- tmp = (tmp & 0x3f);
- break;
- case 11:
- tmp = (tmp & 0x3f) | 0x40;
- break;
- default:
- printk("mad16/Mozart: Invalid MIDI IRQ\n");
- return 0;
- }
-
- mad_write(MC3_PORT, tmp | 0x04);
- hw_config->driver_use_1 = SB_MIDI_ONLY;
- return sb_dsp_detect(hw_config);
+ {
+
+#if defined(CONFIG_MIDI) && defined(CONFIG_MAD16_OLDCARD)
+ unsigned char tmp;
+
+ tmp = mad_read(MC3_PORT);
+
+ /*
+ * MAD16 SB base is defined by the WSS base. It cannot be changed
+ * alone.
+ * Ignore configured I/O base. Use the active setting.
+ */
+
+ if (mad_read(MC1_PORT) & 0x20)
+ hw_config->io_base = 0x240;
+ else
+ hw_config->io_base = 0x220;
+
+ switch (hw_config->irq)
+ {
+ case 5:
+ tmp = (tmp & 0x3f) | 0x80;
+ break;
+ case 7:
+ tmp = (tmp & 0x3f);
+ break;
+ case 11:
+ tmp = (tmp & 0x3f) | 0x40;
+ break;
+ default:
+ printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n");
+ return 0;
+ }
+
+ mad_write(MC3_PORT, tmp | 0x04);
+ hw_config->driver_use_1 = SB_MIDI_ONLY;
+ return sb_dsp_detect(hw_config);
#else
- return 0;
+ return 0;
#endif
- }
+ }
tmp = mad_read(MC6_PORT) & 0x83;
tmp |= 0x80; /* MPU-401 enable */
@@ -771,36 +770,36 @@ probe_mad16_mpu(struct address_info *hw_config)
*/
for (i = 0; i < 5; i++)
- {
- if (i > 3) /* Out of array bounds */
- {
- printk("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
- return 0;
- }
- if (valid_ports[i] == hw_config->io_base)
- {
- tmp |= i << 5;
- break;
- }
- }
+ {
+ if (i > 3) /* Out of array bounds */
+ {
+ printk(KERN_ERR "MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
+ return 0;
+ }
+ if (valid_ports[i] == hw_config->io_base)
+ {
+ tmp |= i << 5;
+ break;
+ }
+ }
/*
* Set the MPU IRQ bits
*/
for (i = 0; i < 5; i++)
- {
- if (i > 3) /* Out of array bounds */
- {
- printk("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
- return 0;
- }
- if (valid_irqs[i] == hw_config->irq)
- {
- tmp |= i << 3;
- break;
- }
- }
+ {
+ if (i > 3) /* Out of array bounds */
+ {
+ printk(KERN_ERR "MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
+ return 0;
+ }
+ if (valid_irqs[i] == hw_config->irq)
+ {
+ tmp |= i << 3;
+ break;
+ }
+ }
mad_write(MC6_PORT, tmp); /* Write MPU401 config */
return probe_uart401(hw_config);
@@ -809,13 +808,12 @@ probe_mad16_mpu(struct address_info *hw_config)
#endif
}
-void
-unload_mad16(struct address_info *hw_config)
+void unload_mad16(struct address_info *hw_config)
{
ad1848_unload(hw_config->io_base + 4,
- hw_config->irq,
- hw_config->dma,
- hw_config->dma2, 0);
+ hw_config->irq,
+ hw_config->dma,
+ hw_config->dma2, 0);
release_region(hw_config->io_base, 4);
sound_unload_audiodev(hw_config->slots[0]);
@@ -824,12 +822,12 @@ unload_mad16(struct address_info *hw_config)
void
unload_mad16_mpu(struct address_info *hw_config)
{
-#if defined(CONFIG_MIDI)
+#if defined(CONFIG_MIDI) && defined(CONFIG_MAD16_OLDCARD)
if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
- {
- sb_dsp_unload(hw_config);
- return;
- }
+ {
+ sb_dsp_unload(hw_config);
+ return;
+ }
#endif
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
@@ -839,6 +837,8 @@ unload_mad16_mpu(struct address_info *hw_config)
#ifdef MODULE
+int mpu_io = 0;
+int mpu_irq = 0;
int io = -1;
int dma = -1;
int dma16 = -1; /* Set this for modules that need it */
@@ -851,6 +851,8 @@ int cddma = 3;
int opl4 = 0;
int joystick = 0;
+MODULE_PARM(mpu_io, "i");
+MODULE_PARM(mpu_irq, "i");
MODULE_PARM(io,"i");
MODULE_PARM(dma,"i");
MODULE_PARM(dma16,"i");
@@ -862,17 +864,18 @@ MODULE_PARM(cddma,"i");
MODULE_PARM(opl4,"i");
MODULE_PARM(joystick,"i");
+EXPORT_NO_SYMBOLS;
-static int found_mpu;
+static int found_mpu;
-static int dma_map[2][8] =
+static int dma_map[2][8] =
{
{0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
{0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
};
-static int irq_map[16] =
+static int irq_map[16] =
{
0x00, -1, -1, 0x0A,
-1, 0x04, -1, 0x08,
@@ -881,80 +884,83 @@ static int irq_map[16] =
};
struct address_info config;
+struct address_info config_mpu;
-int
-init_module(void)
+int init_module(void)
{
- int dmatype = 0;
+ int dmatype = 0;
- printk("MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+ printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
if (io == -1 || dma == -1 || irq == -1)
- {
- printk("I/O, DMA and irq are mandatory\n");
- return -EINVAL;
- }
- printk("CDROM ");
+ {
+ printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
+ return -EINVAL;
+ }
+ printk(KERN_INFO "CDROM ");
switch (cdtype)
- {
- case 0x00:
- printk("Disabled");
- cdirq = 0;
- break;
- case 0x02:
- printk("Sony CDU31A");
- dmatype = 2;
- break;
- case 0x04:
- printk("Mitsumi");
- dmatype = 1;
- break;
- case 0x06:
- printk("Panasonic Lasermate");
- dmatype = 2;
- break;
- case 0x08:
- printk("Secondary IDE");
- dmatype = 1;
- break;
- case 0x0A:
- printk("Primary IDE");
- dmatype = 1;
- break;
- default:
- printk("\nInvalid CDROM type\n");
- return -EINVAL;
- }
+ {
+ case 0x00:
+ printk("Disabled");
+ cdirq = 0;
+ break;
+ case 0x02:
+ printk("Sony CDU31A");
+ dmatype = 2;
+ break;
+ case 0x04:
+ printk("Mitsumi");
+ dmatype = 1;
+ break;
+ case 0x06:
+ printk("Panasonic Lasermate");
+ dmatype = 2;
+ break;
+ case 0x08:
+ printk("Secondary IDE");
+ dmatype = 1;
+ break;
+ case 0x0A:
+ printk("Primary IDE");
+ dmatype = 1;
+ break;
+ default:
+ printk("\n");
+ printk(KERN_ERR "Invalid CDROM type\n");
+ return -EINVAL;
+ }
if (dmatype)
- {
- if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1)
- {
- printk("\nInvalid CDROM DMA\n");
- return -EINVAL;
- }
- if (cddma)
- printk(", DMA %d", cddma);
- else
- printk(", no DMA");
- }
+ {
+ if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1)
+ {
+ printk("\n");
+ printk(KERN_ERR "Invalid CDROM DMA\n");
+ return -EINVAL;
+ }
+ if (cddma)
+ printk(", DMA %d", cddma);
+ else
+ printk(", no DMA");
+ }
if (cdtype && !cdirq)
printk(", no IRQ");
else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1)
- {
+ {
printk(", invalid IRQ (disabling)");
cdirq = 0;
- } else
- printk(", IRQ %d", cdirq);
+ }
+ else printk(", IRQ %d", cdirq);
- printk(".\nJoystick port ");
+ printk(".\n");
+ printk(KERN_INFO "Joystick port ");
if (joystick == 1)
printk("enabled.\n");
else
- {
- joystick = 0;
- printk("disabled.\n");
- }
+ {
+ joystick = 0;
+ printk("disabled.\n");
+ }
/*
* Build the config words
@@ -967,26 +973,26 @@ init_module(void)
mad16_cdsel |= dma_map[dmatype][cddma];
if (cdtype < 0x08)
- {
- switch (cdport)
- {
- case 0x340:
- mad16_cdsel |= 0x00;
- break;
- case 0x330:
- mad16_cdsel |= 0x40;
- break;
- case 0x360:
- mad16_cdsel |= 0x80;
- break;
- case 0x320:
- mad16_cdsel |= 0xC0;
- break;
- default:
- printk("Unknown CDROM I/O base %d\n", cdport);
- return -EINVAL;
- }
- }
+ {
+ switch (cdport)
+ {
+ case 0x340:
+ mad16_cdsel |= 0x00;
+ break;
+ case 0x330:
+ mad16_cdsel |= 0x40;
+ break;
+ case 0x360:
+ mad16_cdsel |= 0x80;
+ break;
+ case 0x320:
+ mad16_cdsel |= 0xC0;
+ break;
+ default:
+ printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport);
+ return -EINVAL;
+ }
+ }
mad16_cdsel |= irq_map[cdirq];
config.io_base = io;
@@ -996,19 +1002,21 @@ init_module(void)
if (!probe_mad16(&config))
return -ENODEV;
- found_mpu = probe_mad16_mpu(&config);
+
+ config_mpu.io_base = mpu_io;
+ config_mpu.irq = mpu_irq;
+ found_mpu = probe_mad16_mpu(&config_mpu);
attach_mad16(&config);
if (found_mpu)
- attach_mad16_mpu(&config);
+ attach_mad16_mpu(&config_mpu);
SOUND_LOCK;
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
if (found_mpu)
unload_mad16_mpu(&config);
diff --git a/drivers/sound/maui.c b/drivers/sound/maui.c
index a7d37039c..4d2076273 100644
--- a/drivers/sound/maui.c
+++ b/drivers/sound/maui.c
@@ -20,6 +20,7 @@
#include <linux/config.h>
#include <linux/module.h>
+#include <asm/init.h>
#define USE_SEQ_MACROS
#define USE_SIMPLE_MACROS
@@ -452,6 +453,11 @@ void unload_maui(struct address_info *hw_config)
#ifdef MODULE
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
+
+EXPORT_NO_SYMBOLS;
+
int io = -1;
int irq = -1;
@@ -489,7 +495,7 @@ int init_module(void)
void cleanup_module(void)
{
if (fw_load && maui_os)
- kfree(maui_os);
+ vfree(maui_os);
unload_maui(&cfg);
SOUND_LOCK_END;
}
diff --git a/drivers/sound/midibuf.c b/drivers/sound/midibuf.c
index 09dea3a34..50d595d2f 100644
--- a/drivers/sound/midibuf.c
+++ b/drivers/sound/midibuf.c
@@ -15,6 +15,7 @@
*/
#include <linux/config.h>
#include <linux/stddef.h>
+#include <linux/kmod.h>
#define MIDIBUF_C
diff --git a/drivers/sound/opl3sa.c b/drivers/sound/opl3sa.c
index 39adf4357..86fe07f10 100644
--- a/drivers/sound/opl3sa.c
+++ b/drivers/sound/opl3sa.c
@@ -3,14 +3,21 @@
*
* Low level driver for Yamaha YMF701B aka OPL3-SA chip
*
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
+ *
+ * Changes:
+ * Alan Cox Modularisation
+ *
+ * FIXME:
+ * Check for install of mpu etc is wrong, should check result of the mss stuff
*/
+
#include <linux/config.h>
#undef SB_OK
@@ -18,22 +25,21 @@
#include "sound_config.h"
#ifdef SB_OK
#include "sb.h"
-static int sb_initialized = 0;
+static int sb_initialized = 0;
#endif
#ifdef CONFIG_OPL3SA1
-static int kilroy_was_here = 0; /* Don't detect twice */
-static int mpu_initialized = 0;
+static int kilroy_was_here = 0; /* Don't detect twice */
+static int mpu_initialized = 0;
-static int *opl3sa_osp = NULL;
+static int *opl3sa_osp = NULL;
-static unsigned char
-opl3sa_read(int addr)
+static unsigned char opl3sa_read(int addr)
{
- unsigned long flags;
- unsigned char tmp;
+ unsigned long flags;
+ unsigned char tmp;
save_flags(flags);
cli();
@@ -45,10 +51,9 @@ opl3sa_read(int addr)
return tmp;
}
-static void
-opl3sa_write(int addr, int data)
+static void opl3sa_write(int addr, int data)
{
- unsigned long flags;
+ unsigned long flags;
save_flags(flags);
cli();
@@ -58,31 +63,32 @@ opl3sa_write(int addr, int data)
restore_flags(flags);
}
-static int
-opl3sa_detect(void)
+static int opl3sa_detect(void)
{
- int tmp;
+ int tmp;
if (((tmp = opl3sa_read(0x01)) & 0xc4) != 0x04)
- {
- DDB(printk("OPL3-SA detect error 1 (%x)\n", opl3sa_read(0x01)));
- /* return 0; */
- }
-/*
- * Check that the password feature has any effect
- */
+ {
+ DDB(printk("OPL3-SA detect error 1 (%x)\n", opl3sa_read(0x01)));
+ /* return 0; */
+ }
+
+ /*
+ * Check that the password feature has any effect
+ */
+
if (inb(0xf87) == tmp)
- {
- DDB(printk("OPL3-SA detect failed 2 (%x/%x)\n", tmp, inb(0xf87)));
- return 0;
- }
+ {
+ DDB(printk("OPL3-SA detect failed 2 (%x/%x)\n", tmp, inb(0xf87)));
+ return 0;
+ }
tmp = (opl3sa_read(0x04) & 0xe0) >> 5;
if (tmp != 0 && tmp != 1)
- {
- DDB(printk("OPL3-SA detect failed 3 (%d)\n", tmp));
- return 0;
- }
+ {
+ DDB(printk("OPL3-SA detect failed 3 (%d)\n", tmp));
+ return 0;
+ }
DDB(printk("OPL3-SA mode %x detected\n", tmp));
opl3sa_write(0x01, 0x00); /* Disable MSS */
@@ -97,49 +103,50 @@ opl3sa_detect(void)
* OPL3-SA
*/
-int
-probe_opl3sa_wss(struct address_info *hw_config)
+int probe_opl3sa_wss(struct address_info *hw_config)
{
- int ret;
- unsigned char tmp = 0x24; /* WSS enable */
+ int ret;
+ unsigned char tmp = 0x24; /* WSS enable */
if (check_region(0xf86, 2)) /* Control port is busy */
return 0;
/*
- * Check if the IO port returns valid signature. The original MS Sound
- * system returns 0x04 while some cards (OPL3-SA for example)
- * return 0x00.
+ * Check if the IO port returns valid signature. The original MS Sound
+ * system returns 0x04 while some cards (OPL3-SA for example)
+ * return 0x00.
*/
+
if (check_region(hw_config->io_base, 8))
- {
- printk("OPL3-SA: MSS I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
+ {
+ printk(KERN_ERR "OPL3-SA: MSS I/O port conflict (%x)\n", hw_config->io_base);
+ return 0;
+ }
opl3sa_osp = hw_config->osp;
if (!opl3sa_detect())
- {
- printk("OSS: OPL3-SA chip not found\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "OSS: OPL3-SA chip not found\n");
+ return 0;
+ }
+
switch (hw_config->io_base)
- {
- case 0x530:
- tmp |= 0x00;
- break;
- case 0xe80:
- tmp |= 0x08;
- break;
- case 0xf40:
- tmp |= 0x10;
- break;
- case 0x604:
- tmp |= 0x18;
- break;
- default:
- printk("OSS: Unsupported OPL3-SA/WSS base %x\n", hw_config->io_base);
+ {
+ case 0x530:
+ tmp |= 0x00;
+ break;
+ case 0xe80:
+ tmp |= 0x08;
+ break;
+ case 0xf40:
+ tmp |= 0x10;
+ break;
+ case 0x604:
+ tmp |= 0x18;
+ break;
+ default:
+ printk(KERN_ERR "OSS: Unsupported OPL3-SA/WSS base %x\n", hw_config->io_base);
return 0;
- }
+ }
opl3sa_write(0x01, tmp); /* WSS setup register */
kilroy_was_here = 1;
@@ -151,23 +158,21 @@ probe_opl3sa_wss(struct address_info *hw_config)
return ret;
}
-void
-attach_opl3sa_wss(struct address_info *hw_config)
+void attach_opl3sa_wss(struct address_info *hw_config)
{
- int nm = num_mixers;
+ int nm = num_mixers;
attach_ms_sound(hw_config);
if (num_mixers > nm) /* A mixer was installed */
- {
- AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
- AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);
- AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
- }
+ {
+ AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
+ AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);
+ AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
+ }
}
-void
-attach_opl3sa_mpu(struct address_info *hw_config)
+void attach_opl3sa_mpu(struct address_info *hw_config)
{
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
hw_config->name = "OPL3-SA (MPU401)";
@@ -175,55 +180,54 @@ attach_opl3sa_mpu(struct address_info *hw_config)
#endif
}
-int
-probe_opl3sa_mpu(struct address_info *hw_config)
+int probe_opl3sa_mpu(struct address_info *hw_config)
{
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
- unsigned char conf;
- static char irq_bits[] =
- {-1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4};
+ unsigned char conf;
+ static char irq_bits[] = {
+ -1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4
+ };
if (!kilroy_was_here)
- {
- return 0; /* OPL3-SA has not been detected earlier */
- }
+ return 0; /* OPL3-SA has not been detected earlier */
+
if (mpu_initialized)
- {
- DDB(printk("OPL3-SA: MPU mode already initialized\n"));
- return 0;
- }
+ {
+ DDB(printk("OPL3-SA: MPU mode already initialized\n"));
+ return 0;
+ }
if (check_region(hw_config->io_base, 4))
- {
- printk("OPL3-SA: MPU I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
+ {
+ printk(KERN_ERR "OPL3-SA: MPU I/O port conflict (%x)\n", hw_config->io_base);
+ return 0;
+ }
if (hw_config->irq > 10)
- {
- printk("OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
+ return 0;
+ }
if (irq_bits[hw_config->irq] == -1)
- {
- printk("OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
+ return 0;
+ }
switch (hw_config->io_base)
- {
- case 0x330:
- conf = 0x00;
- break;
- case 0x332:
- conf = 0x20;
- break;
- case 0x334:
- conf = 0x40;
- break;
- case 0x300:
- conf = 0x60;
- break;
- default:
- return 0; /* Invalid port */
- }
+ {
+ case 0x330:
+ conf = 0x00;
+ break;
+ case 0x332:
+ conf = 0x20;
+ break;
+ case 0x334:
+ conf = 0x40;
+ break;
+ case 0x300:
+ conf = 0x60;
+ break;
+ default:
+ return 0; /* Invalid port */
+ }
conf |= 0x83; /* MPU & OPL3 (synth) & game port enable */
conf |= irq_bits[hw_config->irq] << 2;
@@ -238,10 +242,9 @@ probe_opl3sa_mpu(struct address_info *hw_config)
#endif
}
-void
-unload_opl3sa_wss(struct address_info *hw_config)
+void unload_opl3sa_wss(struct address_info *hw_config)
{
- int dma2 = hw_config->dma2;
+ int dma2 = hw_config->dma2;
if (dma2 == -1)
dma2 = hw_config->dma;
@@ -256,16 +259,15 @@ unload_opl3sa_wss(struct address_info *hw_config)
0);
}
-void
-unload_opl3sa_mpu(struct address_info *hw_config)
+void unload_opl3sa_mpu(struct address_info *hw_config)
{
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
unload_uart401(hw_config);
#endif
}
+
#ifdef SB_OK
-void
-unload_opl3sa_sb(struct address_info *hw_config)
+void unload_opl3sa_sb(struct address_info *hw_config)
{
#ifdef CONFIG_SBDSP
sb_dsp_unload(hw_config);
@@ -273,5 +275,60 @@ unload_opl3sa_sb(struct address_info *hw_config)
}
#endif
+#ifdef MODULE
+int io = -1;
+int irq = -1;
+int dma = -1;
+int dma2 = -1;
+
+int mpu_io = -1;
+int mpu_irq = -1;
+
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
+MODULE_PARM(dma,"i");
+MODULE_PARM(dma2,"i");
+MODULE_PARM(mpu_io,"i");
+MODULE_PARM(mpu_irq,"i");
+
+struct address_info cfg;
+struct address_info mpu_cfg;
+
+int init_module(void)
+{
+ if (io == -1 || irq == -1 || dma == -1)
+ {
+ printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n");
+ return -EINVAL;
+ }
+ cfg.io_base = io;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.dma2 = dma2;
+
+ mpu_cfg.io_base = mpu_io;
+ mpu_cfg.irq = mpu_irq;
+
+ if (probe_opl3sa_wss(&cfg) == 0)
+ return -ENODEV;
+
+ found_mpu=probe_opl3_mpu(&mpu_cfg);
+
+ attach_opl3sa_wss(&cfg);
+ if(found_mpu)
+ attach_opl3sa_mpu(&mpu_cfg);
+ SOUND_LOCK;
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ if(found_mpu)
+ unload_opl3sa_mpu(&mpu_cfg);
+ unload_opl3sa(&cfg);
+ SOUND_LOCK_END;
+}
+
+#endif
#endif
diff --git a/drivers/sound/os.h b/drivers/sound/os.h
index 5bd4a27eb..31fcc81f7 100644
--- a/drivers/sound/os.h
+++ b/drivers/sound/os.h
@@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/fs.h>
#include <asm/dma.h>
+#include <asm/io.h>
#include <asm/param.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
@@ -32,7 +33,6 @@
#include <asm/uaccess.h>
#include <linux/poll.h>
#include <linux/pci.h>
-#include <linux/bios32.h>
#endif
#include <linux/wrapper.h>
@@ -52,7 +52,6 @@ extern void reprogram_timer(void);
#define USE_AUTOINIT_DMA
extern caddr_t sound_mem_blocks[1024];
-extern int sound_mem_sizes[1024];
extern int sound_nblocks;
#undef PSEUDO_DMA_AUTOINIT
diff --git a/drivers/sound/pas2_card.c b/drivers/sound/pas2_card.c
index e00108b0b..8eb29e729 100644
--- a/drivers/sound/pas2_card.c
+++ b/drivers/sound/pas2_card.c
@@ -37,6 +37,11 @@ int translate_code = 0;
static int pas_intr_mask = 0;
static int pas_irq = 0;
static int pas_sb_base = 0;
+#ifndef CONFIG_PAS_JOYSTICK
+static int joystick = 0;
+#else
+static int joystick = 1;
+#endif
char pas_model = 0;
@@ -142,9 +147,7 @@ static int config_pas_hw(struct address_info *hw_config)
*/ , 0xB88);
pas_write(0x80
-#ifdef PAS_JOYSTICK_ENABLE
- | 0x40
-#endif
+ | joystick?0x40:0
,0xF388);
if (pas_irq < 0 || pas_irq > 15)
@@ -164,7 +167,7 @@ static int config_pas_hw(struct address_info *hw_config)
}
else
{
- if (request_irq(pas_irq, pasintr, 0, "PAS16", NULL) < 0)
+ if (request_irq(pas_irq, pasintr, 0, "PAS16",NULL) < 0)
ok = 0;
}
}
@@ -380,6 +383,8 @@ MODULE_PARM(sb_irq,"i");
MODULE_PARM(sb_dma,"i");
MODULE_PARM(sb_dma16,"i");
+MODULE_PARM(joystick,"i");
+
struct address_info config;
struct address_info sbhw_config;
diff --git a/drivers/sound/pss.c b/drivers/sound/pss.c
index 7a0a2e66e..9b00aa43a 100644
--- a/drivers/sound/pss.c
+++ b/drivers/sound/pss.c
@@ -2,18 +2,29 @@
* sound/pss.c
*
* The low level driver for the Personal Sound System (ECHO ESC614).
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
- */
-/*
+ *
+ *
* Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
* Alan Cox modularisation, clean up.
+ *
+ * 98-02-21: Vladimir Michl <vladimir.michl@upol.cz>
+ * Added mixer device for Beethoven ADSP-16 (master volume,
+ * bass, treble, synth), only for speakers.
+ * Fixed bug in pss_write (exchange parameters)
+ * Fixed config port of SB
+ * Requested two regions for PSS (PSS mixer, PSS config)
+ * Modified pss_download_boot
+ * To probe_pss_mss added test for initialize AD1848
*/
+
+
#include <linux/config.h>
#include <linux/module.h>
@@ -39,7 +50,7 @@
*/
#define CONF_PSS 0x10
#define CONF_WSS 0x12
-#define CONF_SB 0x13
+#define CONF_SB 0x14
#define CONF_CDROM 0x16
#define CONF_MIDI 0x18
@@ -53,6 +64,20 @@
#define PSS_WRITE_EMPTY 0x8000
#define PSS_READ_FULL 0x4000
+/*
+ * WSS registers
+ */
+#define WSS_INDEX 4
+#define WSS_DATA 5
+
+/*
+ * WSS status bits
+ */
+#define WSS_INITIALIZING 0x80
+#define WSS_AUTOCALIBRATION 0x20
+
+#define NO_WSS_MIXER -1
+
#include "coproc.h"
#ifdef CONFIG_PSS_HAVE_BOOT
@@ -62,23 +87,32 @@ static unsigned char *pss_synth = NULL;
static int pss_synthLen = 0;
#endif
-typedef struct pss_confdata
-{
- int base;
- int irq;
- int dma;
- int *osp;
-}
-
-pss_confdata;
-
+unsigned char pss_mixer = 1;
+
+typedef struct pss_mixerdata {
+ unsigned int volume_l;
+ unsigned int volume_r;
+ unsigned int bass;
+ unsigned int treble;
+ unsigned int synth;
+} pss_mixerdata;
+
+typedef struct pss_confdata {
+ int base;
+ int irq;
+ int dma;
+ int *osp;
+ pss_mixerdata mixer;
+ int ad_mixer_dev;
+} pss_confdata;
+
static pss_confdata pss_data;
static pss_confdata *devc = &pss_data;
static int pss_initialized = 0;
static int nonstandard_microcode = 0;
-static void pss_write(int data)
+static void pss_write(pss_confdata *devc, int data)
{
int i, limit;
@@ -92,14 +126,14 @@ static void pss_write(int data)
*/
for (i = 0; i < 5000000 && jiffies < limit; i++)
- {
- if (inw(devc->base + PSS_STATUS) & PSS_WRITE_EMPTY)
- {
- outw(devc->base + PSS_DATA, data);
- return;
- }
- }
- printk(KERN_ERR "PSS: DSP Command (%04x) Timeout.\n", data);
+ {
+ if (inw(REG(PSS_STATUS)) & PSS_WRITE_EMPTY)
+ {
+ outw(data, REG(PSS_DATA));
+ return;
+ }
+ }
+ printk(KERN_WARNING "PSS: DSP Command (%04x) Timeout.\n", data);
}
int probe_pss(struct address_info *hw_config)
@@ -116,7 +150,7 @@ int probe_pss(struct address_info *hw_config)
if (devc->base != 0x230 && devc->base != 0x250) /* Some cards use these */
return 0;
- if (check_region(devc->base, 16)) {
+ if (check_region(devc->base, 0x19 /*16*/)) {
printk(KERN_ERR "PSS: I/O port conflict\n");
return 0;
}
@@ -249,7 +283,7 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size
pss_reset_dsp(devc);
}
count = 1;
- while (1)
+ while ((flags&CPF_LAST) || count<size )
{
int j;
@@ -267,12 +301,22 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size
break;
else
{
- printk("\nPSS: Download timeout problems, byte %d=%d\n", count, size);
+ printk("\n");
+ printk(KERN_ERR "PSS: Download timeout problems, byte %d=%d\n", count, size);
return 0;
}
}
/*_____ Send the next byte */
- outw(*block++, REG(PSS_DATA));
+ if (count >= size)
+ {
+ /* If not data in block send 0xffff */
+ outw (0xffff, REG (PSS_DATA));
+ }
+ else
+ {
+ /*_____ Send the next byte */
+ outw (*block++, REG (PSS_DATA));
+ };
count++;
}
@@ -309,6 +353,237 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size
return 1;
}
+/* Mixer */
+static void set_master_volume(pss_confdata *devc, int left, int right)
+{
+ static unsigned char log_scale[101] = {
+ 0xdb, 0xe0, 0xe3, 0xe5, 0xe7, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee,
+ 0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3,
+ 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7,
+ 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9,
+ 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb,
+ 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
+ 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
+ 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
+ 0xfe, 0xfe, 0xff, 0xff, 0xff
+ };
+ pss_write(devc, 0x0010);
+ pss_write(devc, log_scale[left] | 0x0000);
+ pss_write(devc, 0x0010);
+ pss_write(devc, log_scale[right] | 0x0100);
+}
+
+static void set_synth_volume(pss_confdata *devc, int volume)
+{
+ /* Should use:
+ int vol = (int)(0x8000/100.0 * (float)volume);
+
+ Fixme: integerise the above cleanly
+ */
+ int vol = (0x8000/(100L*volume));
+ pss_write(devc, 0x0080);
+ pss_write(devc, vol);
+ pss_write(devc, 0x0081);
+ pss_write(devc, vol);
+}
+
+static void set_bass(pss_confdata *devc, int level)
+{
+ /* Should use
+ int vol = (int)((0xfd - 0xf0)/100.0 * (float)level) + 0xf0;
+
+ Fixme: integerise cleanly
+ */
+ int vol = (int)((0xfd - 0xf0)/100L * level) + 0xf0;
+ pss_write(devc, 0x0010);
+ pss_write(devc, vol | 0x0200);
+};
+
+static void set_treble(pss_confdata *devc, int level)
+{
+ /* Should use
+ int vol = (int)((0xfd - 0xf0)/100.0 * (float)level) + 0xf0;
+
+ Fixme: integerise properly
+ */
+
+ int vol = ((0xfd - 0xf0)/100L * level) + 0xf0;
+ pss_write(devc, 0x0010);
+ pss_write(devc, vol | 0x0300);
+};
+
+static void pss_mixer_reset(pss_confdata *devc)
+{
+ set_master_volume(devc, 23, 23);
+ set_bass(devc, 50);
+ set_treble(devc, 50);
+ set_synth_volume(devc, 30);
+ pss_write (devc, 0x0010);
+ pss_write (devc, 0x0800 | 0xce); /* Stereo */
+
+ if(pss_mixer)
+ {
+ devc->mixer.volume_l = devc->mixer.volume_r = 23;
+ devc->mixer.bass = 50;
+ devc->mixer.treble = 50;
+ devc->mixer.synth = 30;
+ }
+}
+
+static void arg_to_volume_mono(unsigned int volume, int *aleft)
+{
+ int left;
+
+ left = volume & 0x00ff;
+ if (left > 100)
+ left = 100;
+ *aleft = left;
+}
+
+static void arg_to_volume_stereo(unsigned int volume, int *aleft, int *aright)
+{
+ arg_to_volume_mono(volume, aleft);
+ arg_to_volume_mono(volume >> 8, aright);
+}
+
+static int ret_vol_mono(int left)
+{
+ return ((left << 8) | left);
+}
+
+static int ret_vol_stereo(int left, int right)
+{
+ return ((right << 8) | left);
+}
+
+static int call_ad_mixer(pss_confdata *devc,unsigned int cmd, caddr_t arg)
+{
+ if (devc->ad_mixer_dev != NO_WSS_MIXER)
+ return mixer_devs[devc->ad_mixer_dev]->ioctl(devc->ad_mixer_dev, cmd, arg);
+ else
+ return -EINVAL;
+}
+
+static int pss_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
+{
+ pss_confdata *devc = mixer_devs[dev]->devc;
+ int cmdf = cmd & 0xff;
+
+ if ((cmdf != SOUND_MIXER_VOLUME) && (cmdf != SOUND_MIXER_BASS) &&
+ (cmdf != SOUND_MIXER_TREBLE) && (cmdf != SOUND_MIXER_SYNTH) &&
+ (cmdf != SOUND_MIXER_DEVMASK) && (cmdf != SOUND_MIXER_STEREODEVS) &&
+ (cmdf != SOUND_MIXER_RECMASK) && (cmdf != SOUND_MIXER_CAPS) &&
+ (cmdf != SOUND_MIXER_RECSRC))
+ {
+ return call_ad_mixer(devc, cmd, arg);
+ }
+
+ if (((cmd >> 8) & 0xff) != 'M')
+ return -EINVAL;
+
+ if (_SIOC_DIR (cmd) & _SIOC_WRITE)
+ {
+ switch (cmdf)
+ {
+ case SOUND_MIXER_RECSRC:
+ if (devc->ad_mixer_dev != NO_WSS_MIXER)
+ return call_ad_mixer(devc, cmd, arg);
+ else
+ {
+ if (*(int *)arg != 0)
+ return -EINVAL;
+ return 0;
+ }
+ case SOUND_MIXER_VOLUME:
+ arg_to_volume_stereo(*(unsigned int *)arg, &devc->mixer.volume_l,
+ &devc->mixer.volume_r);
+ set_master_volume(devc, devc->mixer.volume_l,
+ devc->mixer.volume_r);
+ return ret_vol_stereo(devc->mixer.volume_l,
+ devc->mixer.volume_r);
+
+ case SOUND_MIXER_BASS:
+ arg_to_volume_mono(*(unsigned int *)arg,
+ &devc->mixer.bass);
+ set_bass(devc, devc->mixer.bass);
+ return ret_vol_mono(devc->mixer.bass);
+
+ case SOUND_MIXER_TREBLE:
+ arg_to_volume_mono(*(unsigned int *)arg,
+ &devc->mixer.treble);
+ set_treble(devc, devc->mixer.treble);
+ return ret_vol_mono(devc->mixer.treble);
+
+ case SOUND_MIXER_SYNTH:
+ arg_to_volume_mono(*(unsigned int *)arg,
+ &devc->mixer.synth);
+ set_synth_volume(devc, devc->mixer.synth);
+ return ret_vol_mono(devc->mixer.synth);
+
+ default:
+ return -EINVAL;
+ }
+ }
+ else
+ {
+ /*
+ * Return parameters
+ */
+ switch (cmdf)
+ {
+
+ case SOUND_MIXER_DEVMASK:
+ if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
+ *(int *)arg = 0; /* no mixer devices */
+ return (*(int *)arg |= SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH);
+
+ case SOUND_MIXER_STEREODEVS:
+ if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
+ *(int *)arg = 0; /* no stereo devices */
+ return (*(int *)arg |= SOUND_MASK_VOLUME);
+
+ case SOUND_MIXER_RECMASK:
+ if (devc->ad_mixer_dev != NO_WSS_MIXER)
+ return call_ad_mixer(devc, cmd, arg);
+ else
+ return (*(int *)arg = 0); /* no record devices */
+
+ case SOUND_MIXER_CAPS:
+ if (devc->ad_mixer_dev != NO_WSS_MIXER)
+ return call_ad_mixer(devc, cmd, arg);
+ else
+ return (*(int *)arg = SOUND_CAP_EXCL_INPUT);
+
+ case SOUND_MIXER_RECSRC:
+ if (devc->ad_mixer_dev != NO_WSS_MIXER)
+ return call_ad_mixer(devc, cmd, arg);
+ else
+ return (*(int *)arg = 0); /* no record source */
+
+ case SOUND_MIXER_VOLUME:
+ return (*(int *)arg = ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r));
+
+ case SOUND_MIXER_BASS:
+ return (*(int *)arg = ret_vol_mono(devc->mixer.bass));
+
+ case SOUND_MIXER_TREBLE:
+ return (*(int *)arg = ret_vol_mono(devc->mixer.treble));
+
+ case SOUND_MIXER_SYNTH:
+ return (*(int *)arg = ret_vol_mono(devc->mixer.synth));
+ default:
+ return -EINVAL;
+ }
+ }
+}
+
+static struct mixer_operations pss_mixer_operations =
+{
+ "SOUNDPORT",
+ "PSS-AD1848",
+ pss_mixer_ioctl
+};
+
void attach_pss(struct address_info *hw_config)
{
unsigned short id;
@@ -318,10 +593,14 @@ void attach_pss(struct address_info *hw_config)
devc->irq = hw_config->irq;
devc->dma = hw_config->dma;
devc->osp = hw_config->osp;
+ devc->ad_mixer_dev = NO_WSS_MIXER;
if (!probe_pss(hw_config))
return;
+ request_region(hw_config->io_base, 0x10, "PSS mixer, SB emulation");
+ request_region(hw_config->io_base + 0x10, 0x9, "PSS config");
+
id = inw(REG(PSS_ID)) & 0x00ff;
/*
@@ -356,21 +635,6 @@ void attach_pss(struct address_info *hw_config)
conf_printf(tmp, hw_config);
}
-static void pss_init_speaker(void)
-{
-/* Don't ask what are these commands. I really don't know */
- pss_write(0x0010);
- pss_write(0x0000 | 252); /* Left master volume */
- pss_write(0x0010);
- pss_write(0x0100 | 252); /* Right master volume */
- pss_write(0x0010);
- pss_write(0x0200 | 246); /* Bass */
- pss_write(0x0010);
- pss_write(0x0300 | 246); /* Treble */
- pss_write(0x0010);
- pss_write(0x0800 | 0x00ce); /* Stereo switch? */
-}
-
int probe_pss_mpu(struct address_info *hw_config)
{
int timeout;
@@ -380,17 +644,17 @@ int probe_pss_mpu(struct address_info *hw_config)
if (check_region(hw_config->io_base, 2))
{
- printk("PSS: MPU I/O port conflict\n");
+ printk(KERN_ERR "PSS: MPU I/O port conflict\n");
return 0;
}
if (!set_io_base(devc, CONF_MIDI, hw_config->io_base))
{
- printk("PSS: MIDI base could not be set.\n");
+ printk(KERN_ERR "PSS: MIDI base could not be set.\n");
return 0;
}
if (!set_irq(devc, CONF_MIDI, hw_config->irq))
{
- printk("PSS: MIDI IRQ allocation error.\n");
+ printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n");
return 0;
}
if (!pss_synthLen)
@@ -403,7 +667,6 @@ int probe_pss_mpu(struct address_info *hw_config)
printk(KERN_ERR "PSS: Unable to load MIDI synth microcode to DSP.\n");
return 0;
}
- pss_init_speaker();
/*
* Finally wait until the DSP algorithm has initialized itself and
@@ -709,28 +972,51 @@ int probe_pss_mss(struct address_info *hw_config)
* downloaded to the ADSP2115 spends some time initializing the card.
* Let's try to wait until it finishes this task.
*/
- for (timeout = 0;
- timeout < 100000 && (inb(hw_config->io_base + 3) & 0x3f) != 0x04;
- timeout++);
+ for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) & WSS_INITIALIZING); timeout++);
+
+ outb((0x0b), hw_config->io_base + WSS_INDEX); /* Required by some cards */
- outb((0x0b), hw_config->io_base + 4); /* Required by some cards */
+ for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) && (timeout < 100000); timeout++);
- for (timeout = 0;
- timeout < 100000;
- timeout++);
return probe_ms_sound(hw_config);
}
void attach_pss_mss(struct address_info *hw_config)
{
+ int my_mix = -999; /* gcc shut up */
+
+ devc->ad_mixer_dev = NO_WSS_MIXER;
+ if (pss_mixer)
+ {
+ if ((my_mix = sound_install_mixer (MIXER_DRIVER_VERSION,
+ "PSS-SPEAKERS and AD1848 (through MSS audio codec)",
+ &pss_mixer_operations,
+ sizeof (struct mixer_operations),
+ devc)) < 0)
+ {
+ printk(KERN_ERR "Could not install PSS mixer\n");
+ return;
+ }
+ }
+ pss_mixer_reset(devc);
attach_ms_sound(hw_config); /* Slot 0 */
- if (hw_config->slots[0] != -1) /* The MSS driver installed itself */
+ if (hw_config->slots[0] != -1)
+ {
+ /* The MSS driver installed itself */
audio_devs[hw_config->slots[0]]->coproc = &pss_coproc_operations;
+ if (pss_mixer && (num_mixers == (my_mix + 2)))
+ {
+ /* The MSS mixer installed */
+ devc->ad_mixer_dev = audio_devs[hw_config->slots[0]]->mixer_dev;
+ }
+ }
}
void unload_pss(struct address_info *hw_config)
{
+ release_region(hw_config->io_base, 0x10);
+ release_region(hw_config->io_base+0x10, 0x9);
}
void unload_pss_mpu(struct address_info *hw_config)
@@ -761,11 +1047,21 @@ struct address_info cfgmpu = { 0 /* mpu_io */, 0 /* mpu_irq */, 0, -1 };
struct address_info cfgmss = { 0 /* mss_io */, 0 /* mss_irq */, 0 /* mss_dma */, -1 };
MODULE_PARM(pss_io, "i");
+MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
MODULE_PARM(mss_io, "i");
+MODULE_PARM_DESC(mss_io, "Set WSS (audio) i/o base (0x530, 0x604, 0xE80, 0xF40, or other. Address must end in 0 or 4 and must be from 0x100 to 0xFF4)");
MODULE_PARM(mss_irq, "i");
+MODULE_PARM_DESC(mss_irq, "Set WSS (audio) IRQ (3, 5, 7, 9, 10, 11, 12)");
MODULE_PARM(mss_dma, "i");
+MODULE_PARM_DESC(mss_dma, "Set WSS (audio) DMA (0, 1, 3)");
MODULE_PARM(mpu_io, "i");
+MODULE_PARM_DESC(mpu_io, "Set MIDI i/o base (0x330 or other. Address must be on 4 location boundaries and must be from 0x100 to 0xFFC)");
MODULE_PARM(mpu_irq, "i");
+MODULE_PARM_DESC(mpu_irq, "Set MIDI IRQ (3, 5, 7, 9, 10, 11, 12)");
+MODULE_PARM(pss_mixer, "b");
+MODULE_PARM_DESC(pss_mixer, "Enable (1) or disable (0) PSS mixer (controlling of output volume, bass, treble synth volume). The mixer is not available on all PSS cards.");
+MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl");
+MODULE_DESCRIPTION("Module for PSS sound cards (based on AD1848, ADSP-2115 and ESC614). This module includes control of output amplifier and synth volume of the Beethoven ADSP-16 card (this may work with other PSS cards).\n");
static int fw_load = 0;
static int pssmpu = 0, pssmss = 0;
@@ -816,7 +1112,7 @@ int init_module(void)
void cleanup_module(void)
{
if (fw_load && pss_synth)
- kfree(pss_synth);
+ vfree(pss_synth);
if (pssmss)
unload_pss_mss(&cfgmss);
if (pssmpu)
@@ -825,5 +1121,4 @@ void cleanup_module(void)
SOUND_LOCK_END;
}
#endif
-
#endif
diff --git a/drivers/sound/sb.h b/drivers/sound/sb.h
index 431645165..4567d3f5b 100644
--- a/drivers/sound/sb.h
+++ b/drivers/sound/sb.h
@@ -47,6 +47,8 @@
#define MDL_ES1868MIDI 14 /* MIDI port of ESS1868 */
#define MDL_AEDSP 15 /* Audio Excel DSP 16 */
+#define SUBMDL_ALS007 42 /* ALS-007 differs from SB16 only in mixer */
+ /* register assignment */
/*
* Config flags
*/
diff --git a/drivers/sound/sb_audio.c b/drivers/sound/sb_audio.c
index bf3a8dbef..f9465cfe5 100644
--- a/drivers/sound/sb_audio.c
+++ b/drivers/sound/sb_audio.c
@@ -2,17 +2,22 @@
* sound/sb_audio.c
*
* Audio routines for Sound Blaster compatible cards.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
+ *
+ * Changes
+ * Alan Cox : Formatting and clean ups
+ *
+ * Status
+ * Mostly working. mmap bug still present (swaps channels)
*/
-#include <linux/config.h>
-
+#include <linux/config.h>
#include "sound_config.h"
#if defined(CONFIG_SBDSP) || defined(MODULE)
@@ -20,67 +25,84 @@
#include "sb_mixer.h"
#include "sb.h"
-static int
-sb_audio_open(int dev, int mode)
+static int sb_audio_open(int dev, int mode)
{
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long flags;
+ sb_devc *devc = audio_devs[dev]->devc;
+ unsigned long flags;
if (devc == NULL)
- {
- printk("SB: Incomplete initialization\n");
+ {
+ printk(KERN_ERR "SB: Incomplete initialization\n");
return -ENXIO;
- }
+ }
if (devc->caps & SB_NO_RECORDING && mode & OPEN_READ)
- {
- printk("Notice: Recording is not possible with /dev/dsp%d\n", dev);
- if (mode == OPEN_READ)
- return -EPERM;
- }
+ {
+ if (mode == OPEN_READ)
+ return -EPERM;
+ }
save_flags(flags);
cli();
if (devc->opened)
- {
+ {
restore_flags(flags);
return -EBUSY;
- }
+ }
if (devc->dma16 != -1 && devc->dma16 != devc->dma8)
- {
- if (sound_open_dma(devc->dma16, "Sound Blaster 16 bit"))
- {
- restore_flags(flags);
- return -EBUSY;
- }
- }
+ {
+ if (sound_open_dma(devc->dma16, "Sound Blaster 16 bit"))
+ {
+ restore_flags(flags);
+ return -EBUSY;
+ }
+ }
devc->opened = mode;
restore_flags(flags);
devc->irq_mode = IMODE_NONE;
sb_dsp_reset(devc);
+ /* The ALS007 seems to require that the DSP be removed from the output */
+ /* in order for recording to be activated properly. This is done by */
+ /* setting the appropriate bits of the output control register 4ch to */
+ /* zero. This code assumes that the output control registers are not */
+ /* used anywhere else and therefore the DSP bits are *always* ON for */
+ /* output and OFF for sampling. */
+
+ if (devc->submodel == SUBMDL_ALS007)
+ {
+ if (mode & OPEN_READ)
+ sb_setmixer(devc,ALS007_OUTPUT_CTRL2,
+ sb_getmixer(devc,ALS007_OUTPUT_CTRL2) & 0xf9);
+ else
+ sb_setmixer(devc,ALS007_OUTPUT_CTRL2,
+ sb_getmixer(devc,ALS007_OUTPUT_CTRL2) | 0x06);
+ }
return 0;
}
-static void
-sb_audio_close(int dev)
+static void sb_audio_close(int dev)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
- audio_devs[dev]->dmap_in->dma =
- audio_devs[dev]->dmap_out->dma =
- devc->dma8;
+ audio_devs[dev]->dmap_in->dma = audio_devs[dev]->dmap_out->dma = devc->dma8;
if (devc->dma16 != -1 && devc->dma16 != devc->dma8)
sound_close_dma(devc->dma16);
+ /* For ALS007, turn DSP output back on if closing the device for read */
+
+ if ((devc->submodel == SUBMDL_ALS007) && (devc->opened & OPEN_READ))
+ {
+ sb_setmixer(devc,ALS007_OUTPUT_CTRL2,
+ sb_getmixer(devc,ALS007_OUTPUT_CTRL2) | 0x06);
+ }
devc->opened = 0;
}
-static void
-sb_set_output_parms(int dev, unsigned long buf, int nr_bytes,
+static void sb_set_output_parms(int dev, unsigned long buf, int nr_bytes,
int intrflag)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
devc->trg_buf = buf;
devc->trg_bytes = nr_bytes;
@@ -88,10 +110,9 @@ sb_set_output_parms(int dev, unsigned long buf, int nr_bytes,
devc->irq_mode = IMODE_OUTPUT;
}
-static void
-sb_set_input_parms(int dev, unsigned long buf, int count, int intrflag)
+static void sb_set_input_parms(int dev, unsigned long buf, int count, int intrflag)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
devc->trg_buf = buf;
devc->trg_bytes = count;
@@ -103,13 +124,11 @@ sb_set_input_parms(int dev, unsigned long buf, int count, int intrflag)
* SB1.x compatible routines
*/
-static void
-sb1_audio_output_block(int dev, unsigned long buf, int nr_bytes,
- int intrflag)
+static void sb1_audio_output_block(int dev, unsigned long buf, int nr_bytes, int intrflag)
{
- unsigned long flags;
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
+ unsigned long flags;
+ int count = nr_bytes;
+ sb_devc *devc = audio_devs[dev]->devc;
/* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
@@ -122,21 +141,21 @@ sb1_audio_output_block(int dev, unsigned long buf, int nr_bytes,
save_flags(flags);
cli();
if (sb_dsp_command(devc, 0x14)) /* 8 bit DAC using DMA */
- {
- sb_dsp_command(devc, (unsigned char) (count & 0xff));
- sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
- } else
- printk("SB: Unable to start DAC\n");
+ {
+ sb_dsp_command(devc, (unsigned char) (count & 0xff));
+ sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
+ }
+ else
+ printk(KERN_WARNING "soundblaster: Unable to start DAC\n");
restore_flags(flags);
devc->intr_active = 1;
}
-static void
-sb1_audio_start_input(int dev, unsigned long buf, int nr_bytes, int intrflag)
+static void sb1_audio_start_input(int dev, unsigned long buf, int nr_bytes, int intrflag)
{
- unsigned long flags;
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
+ unsigned long flags;
+ int count = nr_bytes;
+ sb_devc *devc = audio_devs[dev]->devc;
/*
* Start a DMA input to the buffer pointed by dmaqtail
@@ -153,49 +172,47 @@ sb1_audio_start_input(int dev, unsigned long buf, int nr_bytes, int intrflag)
save_flags(flags);
cli();
if (sb_dsp_command(devc, 0x24)) /* 8 bit ADC using DMA */
- {
- sb_dsp_command(devc, (unsigned char) (count & 0xff));
- sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
- } else
- printk("SB Error: Unable to start ADC\n");
+ {
+ sb_dsp_command(devc, (unsigned char) (count & 0xff));
+ sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
+ }
+ else
+ printk(KERN_ERR "soundblaster: Unable to start ADC\n");
restore_flags(flags);
devc->intr_active = 1;
}
-static void
-sb1_audio_trigger(int dev, int bits)
+static void sb1_audio_trigger(int dev, int bits)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
bits &= devc->irq_mode;
if (!bits)
sb_dsp_command(devc, 0xd0); /* Halt DMA */
else
- {
- switch (devc->irq_mode)
- {
- case IMODE_INPUT:
- sb1_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
-
- case IMODE_OUTPUT:
- sb1_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
- }
- }
+ {
+ switch (devc->irq_mode)
+ {
+ case IMODE_INPUT:
+ sb1_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
+ devc->trg_intrflag);
+ break;
+ case IMODE_OUTPUT:
+ sb1_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
+ devc->trg_intrflag);
+ break;
+ }
+ }
devc->trigger_bits = bits;
}
-static int
-sb1_audio_prepare_for_input(int dev, int bsize, int bcount)
+static int sb1_audio_prepare_for_input(int dev, int bsize, int bcount)
{
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long flags;
+ sb_devc *devc = audio_devs[dev]->devc;
+ unsigned long flags;
save_flags(flags);
cli();
@@ -208,11 +225,10 @@ sb1_audio_prepare_for_input(int dev, int bsize, int bcount)
return 0;
}
-static int
-sb1_audio_prepare_for_output(int dev, int bsize, int bcount)
+static int sb1_audio_prepare_for_output(int dev, int bsize, int bcount)
{
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long flags;
+ sb_devc *devc = audio_devs[dev]->devc;
+ unsigned long flags;
save_flags(flags);
cli();
@@ -224,55 +240,48 @@ sb1_audio_prepare_for_output(int dev, int bsize, int bcount)
return 0;
}
-static int
-sb1_audio_set_speed(int dev, int speed)
+static int sb1_audio_set_speed(int dev, int speed)
{
- int max_speed = 23000;
- sb_devc *devc = audio_devs[dev]->devc;
- int tmp;
+ int max_speed = 23000;
+ sb_devc *devc = audio_devs[dev]->devc;
+ int tmp;
if (devc->opened & OPEN_READ)
max_speed = 13000;
if (speed > 0)
- {
- if (speed < 4000)
- speed = 4000;
-
- if (speed > max_speed)
- speed = max_speed;
+ {
+ if (speed < 4000)
+ speed = 4000;
- devc->tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff;
+ if (speed > max_speed)
+ speed = max_speed;
- tmp = 256 - devc->tconst;
- speed = (1000000 + tmp / 2) / tmp;
+ devc->tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff;
+ tmp = 256 - devc->tconst;
+ speed = (1000000 + tmp / 2) / tmp;
- devc->speed = speed;
- }
+ devc->speed = speed;
+ }
return devc->speed;
}
-static short
-sb1_audio_set_channels(int dev, short channels)
+static short sb1_audio_set_channels(int dev, short channels)
{
- sb_devc *devc = audio_devs[dev]->devc;
-
+ sb_devc *devc = audio_devs[dev]->devc;
return devc->channels = 1;
}
-static unsigned int
-sb1_audio_set_bits(int dev, unsigned int bits)
+static unsigned int sb1_audio_set_bits(int dev, unsigned int bits)
{
sb_devc *devc = audio_devs[dev]->devc;
-
return devc->bits = 8;
}
-static void
-sb1_audio_halt_xfer(int dev)
+static void sb1_audio_halt_xfer(int dev)
{
- unsigned long flags;
- sb_devc *devc = audio_devs[dev]->devc;
+ unsigned long flags;
+ sb_devc *devc = audio_devs[dev]->devc;
save_flags(flags);
cli();
@@ -284,14 +293,13 @@ sb1_audio_halt_xfer(int dev)
* SB 2.0 and SB 2.01 compatible routines
*/
-static void
-sb20_audio_output_block(int dev, unsigned long buf, int nr_bytes,
+static void sb20_audio_output_block(int dev, unsigned long buf, int nr_bytes,
int intrflag)
{
- unsigned long flags;
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned char cmd;
+ unsigned long flags;
+ int count = nr_bytes;
+ sb_devc *devc = audio_devs[dev]->devc;
+ unsigned char cmd;
/* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
@@ -304,31 +312,30 @@ sb20_audio_output_block(int dev, unsigned long buf, int nr_bytes,
save_flags(flags);
cli();
if (sb_dsp_command(devc, 0x48)) /* DSP Block size */
- {
- sb_dsp_command(devc, (unsigned char) (count & 0xff));
- sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
-
- if (devc->speed * devc->channels <= 23000)
- cmd = 0x1c; /* 8 bit PCM output */
- else
- cmd = 0x90; /* 8 bit high speed PCM output (SB2.01/Pro) */
+ {
+ sb_dsp_command(devc, (unsigned char) (count & 0xff));
+ sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
- if (!sb_dsp_command(devc, cmd))
- printk("SB: Unable to start DAC\n");
+ if (devc->speed * devc->channels <= 23000)
+ cmd = 0x1c; /* 8 bit PCM output */
+ else
+ cmd = 0x90; /* 8 bit high speed PCM output (SB2.01/Pro) */
- } else
- printk("SB: Unable to start DAC\n");
+ if (!sb_dsp_command(devc, cmd))
+ printk(KERN_ERR "soundblaster: Unable to start DAC\n");
+ }
+ else
+ printk(KERN_ERR "soundblaster: Unable to start DAC\n");
restore_flags(flags);
devc->intr_active = 1;
}
-static void
-sb20_audio_start_input(int dev, unsigned long buf, int nr_bytes, int intrflag)
+static void sb20_audio_start_input(int dev, unsigned long buf, int nr_bytes, int intrflag)
{
- unsigned long flags;
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned char cmd;
+ unsigned long flags;
+ int count = nr_bytes;
+ sb_devc *devc = audio_devs[dev]->devc;
+ unsigned char cmd;
/*
* Start a DMA input to the buffer pointed by dmaqtail
@@ -345,49 +352,46 @@ sb20_audio_start_input(int dev, unsigned long buf, int nr_bytes, int intrflag)
save_flags(flags);
cli();
if (sb_dsp_command(devc, 0x48)) /* DSP Block size */
- {
- sb_dsp_command(devc, (unsigned char) (count & 0xff));
- sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
-
- if (devc->speed * devc->channels <= (devc->major == 3 ? 23000 : 13000))
- cmd = 0x2c; /* 8 bit PCM input */
- else
- cmd = 0x98; /* 8 bit high speed PCM input (SB2.01/Pro) */
-
- if (!sb_dsp_command(devc, cmd))
- printk("SB: Unable to start ADC\n");
- } else
- printk("SB Error: Unable to start ADC\n");
- restore_flags(flags);
+ {
+ sb_dsp_command(devc, (unsigned char) (count & 0xff));
+ sb_dsp_command(devc, (unsigned char) ((count >> 8) & 0xff));
+ if (devc->speed * devc->channels <= (devc->major == 3 ? 23000 : 13000))
+ cmd = 0x2c; /* 8 bit PCM input */
+ else
+ cmd = 0x98; /* 8 bit high speed PCM input (SB2.01/Pro) */
+
+ if (!sb_dsp_command(devc, cmd))
+ printk(KERN_ERR "soundblaster: Unable to start ADC\n");
+ }
+ else
+ printk(KERN_ERR "soundblaster: Unable to start ADC\n");
+ restore_flags(flags);
devc->intr_active = 1;
}
-static void
-sb20_audio_trigger(int dev, int bits)
+static void sb20_audio_trigger(int dev, int bits)
{
- sb_devc *devc = audio_devs[dev]->devc;
-
+ sb_devc *devc = audio_devs[dev]->devc;
bits &= devc->irq_mode;
if (!bits)
sb_dsp_command(devc, 0xd0); /* Halt DMA */
else
- {
- switch (devc->irq_mode)
- {
- case IMODE_INPUT:
- sb20_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
- break;
+ {
+ switch (devc->irq_mode)
+ {
+ case IMODE_INPUT:
+ sb20_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
+ devc->trg_intrflag);
+ break;
- case IMODE_OUTPUT:
- sb20_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
- devc->trg_intrflag);
+ case IMODE_OUTPUT:
+ sb20_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
+ devc->trg_intrflag);
break;
- }
- }
-
+ }
+ }
devc->trigger_bits = bits;
}
@@ -395,32 +399,26 @@ sb20_audio_trigger(int dev, int bits)
* SB2.01 specific speed setup
*/
-static int
-sb201_audio_set_speed(int dev, int speed)
+static int sb201_audio_set_speed(int dev, int speed)
{
- sb_devc *devc = audio_devs[dev]->devc;
- int tmp;
- int s = speed * devc->channels;
+ sb_devc *devc = audio_devs[dev]->devc;
+ int tmp;
+ int s = speed * devc->channels;
if (speed > 0)
- {
- if (speed < 4000)
- speed = 4000;
-
- if (speed > 44100)
- speed = 44100;
-
- if (devc->opened & OPEN_READ && speed > 15000)
- speed = 15000;
-
- devc->tconst = ((65536 - ((256000000 + s / 2) /
- s)) >> 8) & 0xff;
-
- tmp = 256 - devc->tconst;
- speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
+ {
+ if (speed < 4000)
+ speed = 4000;
+ if (speed > 44100)
+ speed = 44100;
+ if (devc->opened & OPEN_READ && speed > 15000)
+ speed = 15000;
+ devc->tconst = ((65536 - ((256000000 + s / 2) / s)) >> 8) & 0xff;
+ tmp = 256 - devc->tconst;
+ speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
- devc->speed = speed;
- }
+ devc->speed = speed;
+ }
return devc->speed;
}
@@ -428,17 +426,15 @@ sb201_audio_set_speed(int dev, int speed)
* SB Pro specific routines
*/
-static int
-sbpro_audio_prepare_for_input(int dev, int bsize, int bcount)
+static int sbpro_audio_prepare_for_input(int dev, int bsize, int bcount)
{ /* For SB Pro and Jazz16 */
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long flags;
- unsigned char bits = 0;
+ sb_devc *devc = audio_devs[dev]->devc;
+ unsigned long flags;
+ unsigned char bits = 0;
if (devc->dma16 >= 0 && devc->dma16 != devc->dma8)
- audio_devs[dev]->dmap_out->dma =
- audio_devs[dev]->dmap_in->dma =
- devc->bits == 16 ? devc->dma16 : devc->dma8;
+ audio_devs[dev]->dmap_out->dma = audio_devs[dev]->dmap_in->dma =
+ devc->bits == 16 ? devc->dma16 : devc->dma8;
if (devc->model == MDL_JAZZ || devc->model == MDL_SMW)
if (devc->bits == AFMT_S16_LE)
@@ -459,18 +455,15 @@ sbpro_audio_prepare_for_input(int dev, int bsize, int bcount)
return 0;
}
-static int
-sbpro_audio_prepare_for_output(int dev, int bsize, int bcount)
+static int sbpro_audio_prepare_for_output(int dev, int bsize, int bcount)
{ /* For SB Pro and Jazz16 */
- sb_devc *devc = audio_devs[dev]->devc;
- unsigned long flags;
- unsigned char tmp;
- unsigned char bits = 0;
+ sb_devc *devc = audio_devs[dev]->devc;
+ unsigned long flags;
+ unsigned char tmp;
+ unsigned char bits = 0;
if (devc->dma16 >= 0 && devc->dma16 != devc->dma8)
- audio_devs[dev]->dmap_out->dma =
- audio_devs[dev]->dmap_in->dma =
- devc->bits == 16 ? devc->dma16 : devc->dma8;
+ audio_devs[dev]->dmap_out->dma = audio_devs[dev]->dmap_in->dma = devc->bits == 16 ? devc->dma16 : devc->dma8;
if (devc->model == MDL_SBPRO)
sb_mixer_set_stereo(devc, devc->channels == 2);
@@ -481,92 +474,83 @@ sbpro_audio_prepare_for_output(int dev, int bsize, int bcount)
sb_dsp_command(devc, DSP_CMD_SPKON);
if (devc->model == MDL_JAZZ || devc->model == MDL_SMW)
- {
- if (devc->bits == AFMT_S16_LE)
- bits = 0x04; /* 16 bit mode */
-
- if (devc->channels == 1)
- sb_dsp_command(devc, 0xa0 | bits); /* Mono output */
- else
- sb_dsp_command(devc, 0xa8 | bits); /* Stereo output */
- } else
- {
- tmp = sb_getmixer(devc, 0x0e);
- if (devc->channels == 1)
- tmp &= ~0x02;
- else
- tmp |= 0x02;
- sb_setmixer(devc, 0x0e, tmp);
- }
+ {
+ if (devc->bits == AFMT_S16_LE)
+ bits = 0x04; /* 16 bit mode */
+
+ if (devc->channels == 1)
+ sb_dsp_command(devc, 0xa0 | bits); /* Mono output */
+ else
+ sb_dsp_command(devc, 0xa8 | bits); /* Stereo output */
+ }
+ else
+ {
+ tmp = sb_getmixer(devc, 0x0e);
+ if (devc->channels == 1)
+ tmp &= ~0x02;
+ else
+ tmp |= 0x02;
+ sb_setmixer(devc, 0x0e, tmp);
+ }
restore_flags(flags);
devc->trigger_bits = 0;
return 0;
}
-static int
-sbpro_audio_set_speed(int dev, int speed)
+static int sbpro_audio_set_speed(int dev, int speed)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
if (speed > 0)
- {
- if (speed < 4000)
- speed = 4000;
-
- if (speed > 44100)
- speed = 44100;
-
- if (devc->channels > 1 && speed > 22050)
- speed = 22050;
-
- sb201_audio_set_speed(dev, speed);
- }
+ {
+ if (speed < 4000)
+ speed = 4000;
+ if (speed > 44100)
+ speed = 44100;
+ if (devc->channels > 1 && speed > 22050)
+ speed = 22050;
+ sb201_audio_set_speed(dev, speed);
+ }
return devc->speed;
}
-static short
-sbpro_audio_set_channels(int dev, short channels)
+static short sbpro_audio_set_channels(int dev, short channels)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
if (channels == 1 || channels == 2)
+ {
if (channels != devc->channels)
- {
- devc->channels = channels;
- if (devc->model == MDL_SBPRO && devc->channels == 2)
- {
- if (devc->speed > 22050)
- printk("OSS: Application error. Wrong ioctl call order.\n");
- sbpro_audio_set_speed(dev, devc->speed);
- }
- }
+ {
+ devc->channels = channels;
+ if (devc->model == MDL_SBPRO && devc->channels == 2)
+ sbpro_audio_set_speed(dev, devc->speed);
+ }
+ }
return devc->channels;
}
-static int
-jazz16_audio_set_speed(int dev, int speed)
+static int jazz16_audio_set_speed(int dev, int speed)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
if (speed > 0)
- {
- int tmp;
- int s = speed * devc->channels;
-
- if (speed < 5000)
- speed = 4000;
+ {
+ int tmp;
+ int s = speed * devc->channels;
- if (speed > 44100)
- speed = 44100;
+ if (speed < 5000)
+ speed = 5000;
+ if (speed > 44100)
+ speed = 44100;
- devc->tconst = ((65536 - ((256000000 + s / 2) /
- s)) >> 8) & 0xff;
+ devc->tconst = ((65536 - ((256000000 + s / 2) / s)) >> 8) & 0xff;
- tmp = 256 - devc->tconst;
- speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
+ tmp = 256 - devc->tconst;
+ speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
- devc->speed = speed;
- }
+ devc->speed = speed;
+ }
return devc->speed;
}
@@ -574,124 +558,123 @@ jazz16_audio_set_speed(int dev, int speed)
* ESS specific routines
*/
-static int
-ess_audio_set_speed(int dev, int speed)
+static int ess_audio_set_speed(int dev, int speed)
{
- sb_devc *devc = audio_devs[dev]->devc;
- int divider;
+ sb_devc *devc = audio_devs[dev]->devc;
+ int divider;
if (speed > 0)
- {
- if (speed < 5000)
- speed = 4000;
-
- if (speed > 48000)
- speed = 48000;
-
- if (speed > 22000)
- {
- divider = (795500 + speed / 2) / speed;
- speed = (795500 + divider / 2) / divider;
- } else
- {
- divider = (397700 + speed / 2) / speed;
- speed = (397700 + divider / 2) / divider;
- }
-
- devc->speed = speed;
- }
+ {
+ if (speed < 5000)
+ speed = 5000;
+ if (speed > 48000)
+ speed = 48000;
+
+ if (speed > 22000)
+ {
+ divider = (795500 + speed / 2) / speed;
+ speed = (795500 + divider / 2) / divider;
+ }
+ else
+ {
+ divider = (397700 + speed / 2) / speed;
+ speed = (397700 + divider / 2) / divider;
+ }
+ devc->speed = speed;
+ }
return devc->speed;
}
-static void
-ess_speed(sb_devc * devc)
+static void ess_speed(sb_devc * devc)
{
- int divider;
- unsigned char bits = 0;
- int speed = devc->speed;
+ int divider;
+ unsigned char bits = 0;
+ int speed = devc->speed;
if (speed < 4000)
speed = 4000;
else if (speed > 48000)
speed = 48000;
-
+
if (speed > 22000)
- {
- bits = 0x80;
- divider = 256 - (795500 + speed / 2) / speed;
- } else
- {
- divider = 128 - (397700 + speed / 2) / speed;
- }
+ {
+ bits = 0x80;
+ divider = 256 - (795500 + speed / 2) / speed;
+ }
+ else
+ {
+ divider = 128 - (397700 + speed / 2) / speed;
+ }
bits |= (unsigned char) divider;
ess_write(devc, 0xa1, bits);
-/*
- * Set filter divider register
- */
+ /*
+ * Set filter divider register
+ */
speed = (speed * 9) / 20; /* Set filter roll-off to 90% of speed/2 */
divider = 256 - 7160000 / (speed * 82);
ess_write(devc, 0xa2, divider);
-
return;
}
-static int
-ess_audio_prepare_for_input(int dev, int bsize, int bcount)
+static int ess_audio_prepare_for_input(int dev, int bsize, int bcount)
{
- sb_devc *devc = audio_devs[dev]->devc;
-
+ sb_devc *devc = audio_devs[dev]->devc;
ess_speed(devc);
sb_dsp_command(devc, DSP_CMD_SPKOFF);
ess_write(devc, 0xb8, 0x0e); /* Auto init DMA mode */
- ess_write(devc, 0xa8, (ess_read(devc, 0xa8) & ~0x03) |
- (3 - devc->channels)); /* Mono/stereo */
+ ess_write(devc, 0xa8, (ess_read(devc, 0xa8) & ~0x03) | (3 - devc->channels)); /* Mono/stereo */
ess_write(devc, 0xb9, 2); /* Demand mode (4 bytes/DMA request) */
if (devc->channels == 1)
- {
- if (devc->bits == AFMT_U8)
- { /* 8 bit mono */
- ess_write(devc, 0xb7, 0x51);
- ess_write(devc, 0xb7, 0xd0);
- } else
- { /* 16 bit mono */
- ess_write(devc, 0xb7, 0x71);
- ess_write(devc, 0xb7, 0xf4);
- }
- } else
- { /* Stereo */
- if (devc->bits == AFMT_U8)
- { /* 8 bit stereo */
- ess_write(devc, 0xb7, 0x51);
- ess_write(devc, 0xb7, 0x98);
- } else
- { /* 16 bit stereo */
- ess_write(devc, 0xb7, 0x71);
- ess_write(devc, 0xb7, 0xbc);
- }
- }
-
+ {
+ if (devc->bits == AFMT_U8)
+ {
+ /* 8 bit mono */
+ ess_write(devc, 0xb7, 0x51);
+ ess_write(devc, 0xb7, 0xd0);
+ }
+ else
+ {
+ /* 16 bit mono */
+ ess_write(devc, 0xb7, 0x71);
+ ess_write(devc, 0xb7, 0xf4);
+ }
+ }
+ else
+ {
+ /* Stereo */
+ if (devc->bits == AFMT_U8)
+ {
+ /* 8 bit stereo */
+ ess_write(devc, 0xb7, 0x51);
+ ess_write(devc, 0xb7, 0x98);
+ }
+ else
+ {
+ /* 16 bit stereo */
+ ess_write(devc, 0xb7, 0x71);
+ ess_write(devc, 0xb7, 0xbc);
+ }
+ }
ess_write(devc, 0xb1, (ess_read(devc, 0xb1) & 0x0f) | 0x50);
ess_write(devc, 0xb2, (ess_read(devc, 0xb2) & 0x0f) | 0x50);
-
devc->trigger_bits = 0;
return 0;
}
static int ess_audio_prepare_for_output(int dev, int bsize, int bcount)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
sb_dsp_reset(devc);
ess_speed(devc);
ess_write(devc, 0xb8, 4); /* Auto init DMA mode */
- ess_write(devc, 0xa8, (ess_read(devc, 0xa8) & ~0x03) |
- (3 - devc->channels)); /* Mono/stereo */
+ ess_write(devc, 0xa8, (ess_read(devc, 0xa8) & ~0x03) | (3 - devc->channels)); /* Mono/stereo */
ess_write(devc, 0xb9, 2); /* Demand mode (4 bytes/request) */
if (devc->channels == 1)
@@ -701,7 +684,8 @@ static int ess_audio_prepare_for_output(int dev, int bsize, int bcount)
ess_write(devc, 0xb6, 0x80);
ess_write(devc, 0xb7, 0x51);
ess_write(devc, 0xb7, 0xd0);
- } else
+ }
+ else
{ /* 16 bit mono */
ess_write(devc, 0xb6, 0x00);
ess_write(devc, 0xb7, 0x71);
@@ -733,11 +717,11 @@ static int ess_audio_prepare_for_output(int dev, int bsize, int bcount)
}
static void ess_audio_output_block(int dev, unsigned long buf, int nr_bytes,
- int intrflag)
+ int intrflag)
{
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- short c = -nr_bytes;
+ int count = nr_bytes;
+ sb_devc *devc = audio_devs[dev]->devc;
+ short c = -nr_bytes;
/* DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE); */
@@ -756,9 +740,9 @@ static void ess_audio_output_block(int dev, unsigned long buf, int nr_bytes,
static void ess_audio_start_input(int dev, unsigned long buf, int nr_bytes, int intrflag)
{
- int count = nr_bytes;
- sb_devc *devc = audio_devs[dev]->devc;
- short c = -nr_bytes;
+ int count = nr_bytes;
+ sb_devc *devc = audio_devs[dev]->devc;
+ short c = -nr_bytes;
/*
* Start a DMA input to the buffer pointed by dmaqtail
@@ -781,7 +765,7 @@ static void ess_audio_start_input(int dev, unsigned long buf, int nr_bytes, int
static void ess_audio_trigger(int dev, int bits)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
bits &= devc->irq_mode;
@@ -812,7 +796,7 @@ static void ess_audio_trigger(int dev, int bits)
static int sb16_audio_set_speed(int dev, int speed)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
if (speed > 0)
{
@@ -829,7 +813,7 @@ static int sb16_audio_set_speed(int dev, int speed)
static unsigned int sb16_audio_set_bits(int dev, unsigned int bits)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
if (bits != 0)
{
@@ -844,7 +828,7 @@ static unsigned int sb16_audio_set_bits(int dev, unsigned int bits)
static int sb16_audio_prepare_for_input(int dev, int bsize, int bcount)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
audio_devs[dev]->dmap_out->dma =
audio_devs[dev]->dmap_in->dma =
@@ -856,11 +840,10 @@ static int sb16_audio_prepare_for_input(int dev, int bsize, int bcount)
static int sb16_audio_prepare_for_output(int dev, int bsize, int bcount)
{
- sb_devc *devc = audio_devs[dev]->devc;
+ sb_devc *devc = audio_devs[dev]->devc;
- audio_devs[dev]->dmap_out->dma =
- audio_devs[dev]->dmap_in->dma =
- devc->bits == AFMT_S16_LE ? devc->dma16 : devc->dma8;
+ audio_devs[dev]->dmap_out->dma = audio_devs[dev]->dmap_in->dma =
+ devc->bits == AFMT_S16_LE ? devc->dma16 : devc->dma8;
devc->trigger_bits = 0;
return 0;
@@ -1098,8 +1081,8 @@ static struct audio_driver ess_audio_driver = /* ESS ES688/1688 */
void sb_audio_init(sb_devc * devc, char *name)
{
- int audio_flags = 0;
- int format_mask = AFMT_U8;
+ int audio_flags = 0;
+ int format_mask = AFMT_U8;
struct audio_driver *driver = &sb1_audio_driver;
@@ -1151,14 +1134,9 @@ void sb_audio_init(sb_devc * devc, char *name)
}
if ((devc->my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
- name,
- driver,
- sizeof(struct audio_driver),
- audio_flags,
- format_mask,
- devc,
- devc->dma8,
- devc->dma8)) < 0)
+ name,driver, sizeof(struct audio_driver),
+ audio_flags, format_mask, devc,
+ devc->dma8, devc->dma8)) < 0)
{
printk(KERN_ERR "sb: unable to install audio.\n");
return;
diff --git a/drivers/sound/sb_card.c b/drivers/sound/sb_card.c
index 941422c3f..ddf863372 100644
--- a/drivers/sound/sb_card.c
+++ b/drivers/sound/sb_card.c
@@ -2,18 +2,18 @@
* sound/sb_card.c
*
* Detection routine for the Sound Blaster cards.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+
#include <linux/config.h>
#include <linux/module.h>
-
#include "sound_config.h"
#include "soundmodule.h"
@@ -22,31 +22,30 @@
#include "sb_mixer.h"
#include "sb.h"
-void
-attach_sb_card(struct address_info *hw_config)
+void attach_sb_card(struct address_info *hw_config)
{
#if defined(CONFIG_AUDIO) || defined(CONFIG_MIDI)
sb_dsp_init(hw_config);
#endif
}
-int
-probe_sb(struct address_info *hw_config)
+int probe_sb(struct address_info *hw_config)
{
if (check_region(hw_config->io_base, 16))
{
- printk("\n\nsb_card.c: I/O port %x is already in use\n\n", hw_config->io_base);
+ printk(KERN_ERR "sb_card: I/O port %x is already in use\n\n", hw_config->io_base);
return 0;
}
return sb_dsp_detect(hw_config);
}
-void
-unload_sb(struct address_info *hw_config)
+void unload_sb(struct address_info *hw_config)
{
sb_dsp_unload(hw_config);
}
+int sb_be_quiet=0;
+
#ifdef MODULE
static struct address_info config;
@@ -58,18 +57,17 @@ static struct address_info config_mpu;
* to the 8bit channel.
*/
-int mpu_io = 0;
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma16 = -1; /* Set this for modules that need it */
-int type = 0; /* Can set this to a specific card type */
-int mad16 = 0; /* Set mad16=1 to load this as support for mad16 */
-int trix = 0; /* Set trix=1 to load this as support for trix */
-int pas2 = 0; /* Set pas2=1 to load this as support for pas2 */
-int sm_games = 0; /* Mixer - see sb_mixer.c */
-int acer = 0; /* Do acer notebook init */
-int mwave_bug = 0; /* Using the dreadful mwave sb emulation */
+int mpu_io = 0;
+int io = -1;
+int irq = -1;
+int dma = -1;
+int dma16 = -1; /* Set this for modules that need it */
+int type = 0; /* Can set this to a specific card type */
+int mad16 = 0; /* Set mad16=1 to load this as support for mad16 */
+int trix = 0; /* Set trix=1 to load this as support for trix */
+int pas2 = 0; /* Set pas2=1 to load this as support for pas2 */
+int sm_games = 0; /* Mixer - see sb_mixer.c */
+int acer = 0; /* Do acer notebook init */
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
@@ -81,7 +79,6 @@ MODULE_PARM(mad16, "i");
MODULE_PARM(trix, "i");
MODULE_PARM(pas2, "i");
MODULE_PARM(sm_games, "i");
-MODULE_PARM(mwave_bug, "i");
static int sbmpu = 0;
@@ -124,7 +121,7 @@ int init_module(void)
void cleanup_module(void)
{
if (smw_free)
- kfree(smw_free);
+ vfree(smw_free);
if (!mad16 && !trix && !pas2)
unload_sb(&config);
if (sbmpu)
@@ -144,11 +141,6 @@ int acer = 1;
#else
int acer = 0;
#endif
-#ifdef CONFIG_SB_MWAVE
-int mwave_bug = 1;
-#else
-int mwave_bug = 0;
-#endif
#endif
#endif
@@ -159,3 +151,4 @@ EXPORT_SYMBOL(sb_dsp_disable_midi);
EXPORT_SYMBOL(attach_sb_card);
EXPORT_SYMBOL(probe_sb);
EXPORT_SYMBOL(unload_sb);
+EXPORT_SYMBOL(sb_be_quiet);
diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c
index fcdcfcf2c..d82c9379f 100644
--- a/drivers/sound/sb_common.c
+++ b/drivers/sound/sb_common.c
@@ -2,17 +2,18 @@
* sound/sb_common.c
*
* Common routines for Sound Blaster compatible cards.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+
#include <linux/config.h>
#include <linux/delay.h>
-
+#include <asm/init.h>
#include "sound_config.h"
#include "sound_firmware.h"
@@ -28,9 +29,11 @@
static sb_devc *detected_devc = NULL; /* For communication from probe to init */
static sb_devc *last_devc = NULL; /* For MPU401 initialization */
+
static unsigned char jazz_irq_bits[] = {
0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6
};
+
static unsigned char jazz_dma_bits[] = {
0, 1, 0, 2, 0, 3, 0, 4
};
@@ -39,7 +42,7 @@ static unsigned char jazz_dma_bits[] = {
* Jazz16 chipset specific control variables
*/
-static int jazz16_base = 0; /* Not detected */
+static int jazz16_base = 0; /* Not detected */
static unsigned char jazz16_bits = 0; /* I/O relocation bits */
/*
@@ -57,10 +60,11 @@ static int smw_ucodeLen = 0;
int sb_dsp_command(sb_devc * devc, unsigned char val)
{
- int i;
- unsigned long limit;
+ int i;
+ unsigned long limit;
limit = jiffies + HZ / 10; /* Timeout */
+
/*
* Note! the i<500000 is an emergency exit. The sb_dsp_command() is sometimes
* called while interrupts are disabled. This means that the timer is
@@ -69,7 +73,7 @@ int sb_dsp_command(sb_devc * devc, unsigned char val)
* loops.
*/
- for (i = 0; i < 500000 && jiffies < limit; i++)
+ for (i = 0; i < 500000 && (limit-jiffies)>0; i++)
{
if ((inb(DSP_STATUS) & 0x80) == 0)
{
@@ -77,20 +81,19 @@ int sb_dsp_command(sb_devc * devc, unsigned char val)
return 1;
}
}
-
- printk(KERN_WARNING "Sound Blaster: DSP Command(%x) Timeout.\n", val);
+ printk(KERN_WARNING "soundblaster: DSP Command(%x) Timeout.\n", val);
return 0;
}
static int sb_dsp_get_byte(sb_devc * devc)
{
- int i;
+ int i;
for (i = 1000; i; i--)
+ {
if (inb(DSP_DATA_AVAIL) & 0x80)
- {
return inb(DSP_READ);
- }
+ }
return 0xffff;
}
@@ -107,7 +110,6 @@ int ess_write(sb_devc * devc, unsigned char reg, unsigned char data)
int ess_read(sb_devc * devc, unsigned char reg)
{
/* Read a byte from an extended mode register of ES1688 */
-
if (!sb_dsp_command(devc, 0xc0)) /* Read register command */
return -1;
@@ -239,7 +241,7 @@ static int sb16_set_dma_hw(sb_devc * devc)
if (devc->dma8 != 0 && devc->dma8 != 1 && devc->dma8 != 3)
{
- printk(KERN_ERR "SB16: Invalid 8 bit DMA (%d)\n", devc->dma8);
+ printk(KERN_ERR "sb16: Invalid 8 bit DMA (%d)\n", devc->dma8);
return 0;
}
bits = (1 << devc->dma8);
@@ -355,14 +357,12 @@ static int init_Jazz16(sb_devc * devc, struct address_info *hw_config)
/*
* OK so far. Now configure the IRQ and DMA channel used by the card.
*/
- if (hw_config->irq < 1 || hw_config->irq > 15 ||
- jazz_irq_bits[hw_config->irq] == 0)
+ if (hw_config->irq < 1 || hw_config->irq > 15 || jazz_irq_bits[hw_config->irq] == 0)
{
printk(KERN_ERR "Jazz16: Invalid interrupt (IRQ%d)\n", hw_config->irq);
return 0;
}
- if (hw_config->dma < 0 || hw_config->dma > 3 ||
- jazz_dma_bits[hw_config->dma] == 0)
+ if (hw_config->dma < 0 || hw_config->dma > 3 || jazz_dma_bits[hw_config->dma] == 0)
{
printk(KERN_ERR "Jazz16: Invalid 8 bit DMA (DMA%d)\n", hw_config->dma);
return 0;
@@ -372,8 +372,7 @@ static int init_Jazz16(sb_devc * devc, struct address_info *hw_config)
printk(KERN_ERR "Jazz16: No 16 bit DMA channel defined\n");
return 0;
}
- if (hw_config->dma2 < 5 || hw_config->dma2 > 7 ||
- jazz_dma_bits[hw_config->dma2] == 0)
+ if (hw_config->dma2 < 5 || hw_config->dma2 > 7 || jazz_dma_bits[hw_config->dma2] == 0)
{
printk(KERN_ERR "Jazz16: Invalid 16 bit DMA (DMA%d)\n", hw_config->dma2);
return 0;
@@ -384,7 +383,7 @@ static int init_Jazz16(sb_devc * devc, struct address_info *hw_config)
return 0;
if (!sb_dsp_command(devc, jazz_dma_bits[hw_config->dma] |
- (jazz_dma_bits[hw_config->dma2] << 4)))
+ (jazz_dma_bits[hw_config->dma2] << 4)))
return 0;
if (!sb_dsp_command(devc, jazz_irq_bits[hw_config->irq]))
@@ -683,11 +682,7 @@ int sb_dsp_detect(struct address_info *hw_config)
*/
- detected_devc = (sb_devc *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(sb_devc)));
- sound_mem_sizes[sound_nblocks] = sizeof(sb_devc);
- if (sound_nblocks < 1024)
- sound_nblocks++;;
-
+ detected_devc = (sb_devc *)kmalloc(sizeof(sb_devc), GFP_KERNEL);
if (detected_devc == NULL)
{
printk(KERN_ERR "sb: Can't allocate memory for device information\n");
@@ -703,8 +698,8 @@ void sb_dsp_init(struct address_info *hw_config)
sb_devc *devc;
char name[100];
extern int sb_be_quiet;
- extern int mwave_bug;
-
+ int mixer3c, mixer4c;
+
/*
* Check if we had detected a SB device earlier
*/
@@ -769,7 +764,7 @@ void sb_dsp_init(struct address_info *hw_config)
/* Skip IRQ detection if SMP (doesn't work) */
devc->irq_ok = 1;
#else
- if ((devc->major == 4 && devc->minor <= 11 ) || mwave_bug ) /* Won't work */
+ if (devc->major == 4 && devc->minor <= 11 ) /* Won't work */
devc->irq_ok = 1;
else
{
@@ -819,7 +814,23 @@ void sb_dsp_init(struct address_info *hw_config)
case 4:
devc->model = hw_config->card_subtype = MDL_SB16;
- if (hw_config->name == NULL)
+ /*
+ * The ALS007 seems to return DSP version 4.2. In addition it has 2
+ * output control registers (at 0x3c and 0x4c). Both of these should
+ * be !=0 after a reset which forms the basis of the ALS007 test
+ * since a "standard" SoundBlaster does not have a register at 0x4c.
+ */
+ mixer3c = sb_getmixer(devc,0x3c);
+ mixer4c = sb_getmixer(devc,0x4c);
+ if ((devc->minor == 2) && (mixer3c != 0) && (mixer4c != 0))
+ {
+ sb_setmixer(devc,0x3c,0x1f); /* Enable all inputs */
+ sb_setmixer(devc,0x4c,0x1f);
+ devc->submodel = SUBMDL_ALS007;
+ if (hw_config->name == NULL)
+ hw_config->name = "Sound Blaster (ALS-007)";
+ }
+ else if (hw_config->name == NULL)
hw_config->name = "Sound Blaster 16";
if (hw_config->dma2 == -1)
@@ -885,15 +896,15 @@ void sb_dsp_init(struct address_info *hw_config)
printk(KERN_WARNING "SB: Can't allocate 8 bit DMA channel %d\n", devc->dma8);
}
if (devc->dma16 >= 0 && devc->dma16 != devc->dma8)
+ {
if (sound_alloc_dma(devc->dma16, "SoundBlaster16"))
- {
- printk(KERN_WARNING "SB: Can't allocate 16 bit DMA channel %d\n", devc->dma16);
- }
+ printk(KERN_WARNING "soundblaster: Can't allocate 16 bit DMA channel %d\n", devc->dma16);
+ }
sb_audio_init(devc, name);
}
else
{
- MDB(printk("sb: No audio devices found.\n"));
+ MDB(printk("soundblaster: No audio devices found.\n"));
}
}
@@ -932,6 +943,8 @@ void sb_dsp_unload(struct address_info *hw_config)
}
else
release_region(hw_config->io_base, 16);
+ if(detected_devc)
+ kfree(detected_devc);
}
/*
@@ -940,7 +953,7 @@ void sb_dsp_unload(struct address_info *hw_config)
void sb_setmixer(sb_devc * devc, unsigned int port, unsigned int value)
{
- unsigned long flags;
+ unsigned long flags;
save_flags(flags);
cli();
@@ -1318,5 +1331,4 @@ void attach_sbmpu(struct address_info *hw_config)
{
}
#endif
-
#endif
diff --git a/drivers/sound/sb_midi.c b/drivers/sound/sb_midi.c
index b08f8d43f..f7c1c85a2 100644
--- a/drivers/sound/sb_midi.c
+++ b/drivers/sound/sb_midi.c
@@ -2,17 +2,16 @@
* sound/sb_dsp.c
*
* The low level driver for the Sound Blaster DS chips.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
-#include <linux/config.h>
-
+#include <linux/config.h>
#include "sound_config.h"
#ifdef CONFIG_SBDSP
@@ -30,14 +29,13 @@
*/
-static int
-sb_midi_open(int dev, int mode,
+static int sb_midi_open(int dev, int mode,
void (*input) (int dev, unsigned char data),
void (*output) (int dev)
)
{
- sb_devc *devc = midi_devs[dev]->devc;
- unsigned long flags;
+ sb_devc *devc = midi_devs[dev]->devc;
+ unsigned long flags;
if (devc == NULL)
return -ENXIO;
@@ -45,10 +43,10 @@ sb_midi_open(int dev, int mode,
save_flags(flags);
cli();
if (devc->opened)
- {
- restore_flags(flags);
- return -EBUSY;
- }
+ {
+ restore_flags(flags);
+ return -EBUSY;
+ }
devc->opened = 1;
restore_flags(flags);
@@ -58,25 +56,24 @@ sb_midi_open(int dev, int mode,
sb_dsp_reset(devc);
if (!sb_dsp_command(devc, 0x35)) /* Start MIDI UART mode */
- {
+ {
devc->opened = 0;
return -EIO;
- }
+ }
devc->intr_active = 1;
if (mode & OPEN_READ)
- {
- devc->input_opened = 1;
- devc->midi_input_intr = input;
- }
+ {
+ devc->input_opened = 1;
+ devc->midi_input_intr = input;
+ }
return 0;
}
-static void
-sb_midi_close(int dev)
+static void sb_midi_close(int dev)
{
- sb_devc *devc = midi_devs[dev]->devc;
- unsigned long flags;
+ sb_devc *devc = midi_devs[dev]->devc;
+ unsigned long flags;
if (devc == NULL)
return;
@@ -90,10 +87,9 @@ sb_midi_close(int dev)
restore_flags(flags);
}
-static int
-sb_midi_out(int dev, unsigned char midi_byte)
+static int sb_midi_out(int dev, unsigned char midi_byte)
{
- sb_devc *devc = midi_devs[dev]->devc;
+ sb_devc *devc = midi_devs[dev]->devc;
if (devc == NULL)
return 1;
@@ -102,23 +98,21 @@ sb_midi_out(int dev, unsigned char midi_byte)
return 1;
if (!sb_dsp_command(devc, midi_byte))
- {
- devc->midi_broken = 1;
- return 1;
- }
+ {
+ devc->midi_broken = 1;
+ return 1;
+ }
return 1;
}
-static int
-sb_midi_start_read(int dev)
+static int sb_midi_start_read(int dev)
{
return 0;
}
-static int
-sb_midi_end_read(int dev)
+static int sb_midi_end_read(int dev)
{
- sb_devc *devc = midi_devs[dev]->devc;
+ sb_devc *devc = midi_devs[dev]->devc;
if (devc == NULL)
return -ENXIO;
@@ -128,14 +122,12 @@ sb_midi_end_read(int dev)
return 0;
}
-/* why -EPERM and not -EINVAL?? */
static int sb_midi_ioctl(int dev, unsigned cmd, caddr_t arg)
{
- return -EPERM;
+ return -EINVAL;
}
-void
-sb_midi_interrupt(sb_devc * devc)
+void sb_midi_interrupt(sb_devc * devc)
{
unsigned long flags;
unsigned char data;
@@ -159,7 +151,9 @@ sb_midi_interrupt(sb_devc * devc)
static struct midi_operations sb_midi_operations =
{
- {"Sound Blaster", 0, 0, SNDCARD_SB},
+ {
+ "Sound Blaster", 0, 0, SNDCARD_SB
+ },
&std_midi_synth,
{0},
sb_midi_open,
@@ -174,10 +168,9 @@ static struct midi_operations sb_midi_operations =
NULL
};
-void
-sb_dsp_midi_init(sb_devc * devc)
+void sb_dsp_midi_init(sb_devc * devc)
{
- int dev;
+ int dev;
if (devc->model < 2) /* No MIDI support for SB 1.x */
return;
@@ -185,45 +178,34 @@ sb_dsp_midi_init(sb_devc * devc)
dev = sound_alloc_mididev();
if (dev == -1)
- {
- printk("Sound: Too many midi devices detected\n");
- return;
- }
+ {
+ printk("Sound: Too many midi devices detected\n");
+ return;
+ }
std_midi_synth.midi_dev = dev;
devc->my_mididev = dev;
-
std_midi_synth.midi_dev = devc->my_mididev = dev;
-
-
- midi_devs[dev] = (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++;;
+ midi_devs[dev] = (struct midi_operations *)kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
if (midi_devs[dev] == NULL)
- {
- printk(KERN_WARNING "sb MIDI: Failed to allocate memory\n");
- sound_unload_mididev(dev);
+ {
+ printk(KERN_WARNING "soundblaster: Failed to allocate MIDI memory.\n");
+ sound_unload_mididev(dev);
return;
- }
+ }
memcpy((char *) midi_devs[dev], (char *) &sb_midi_operations,
sizeof(struct midi_operations));
midi_devs[dev]->devc = devc;
- midi_devs[dev]->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++;;
-
+ midi_devs[dev]->converter = (struct synth_operations *)kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
if (midi_devs[dev]->converter == NULL)
- {
- printk(KERN_WARNING "sb MIDI: Failed to allocate memory\n");
+ {
+ printk(KERN_WARNING "soundblaster: Failed to allocate MIDI memory.\n");
+ kfree(midi_devs[dev]);
sound_unload_mididev(dev);
return;
- }
+ }
memcpy((char *) midi_devs[dev]->converter, (char *) &std_midi_synth,
sizeof(struct synth_operations));
diff --git a/drivers/sound/sb_mixer.c b/drivers/sound/sb_mixer.c
index 2d494a0dd..5f06807ce 100644
--- a/drivers/sound/sb_mixer.c
+++ b/drivers/sound/sb_mixer.c
@@ -10,13 +10,12 @@
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* 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/config.h>
#include "sound_config.h"
#if defined(CONFIG_SBDSP) || defined(MODULE)
@@ -29,25 +28,22 @@ static int sbmixnum = 1;
static void sb_mixer_reset(sb_devc * devc);
-void
-sb_mixer_set_stereo(sb_devc * devc, int mode)
+void sb_mixer_set_stereo(sb_devc * devc, int mode)
{
sb_setmixer(devc, OUT_FILTER, ((sb_getmixer(devc, OUT_FILTER) & ~STEREO_DAC)
| (mode ? STEREO_DAC : MONO_DAC)));
}
-static int
-detect_mixer(sb_devc * devc)
+static int detect_mixer(sb_devc * devc)
{
/* Just trust the mixer is there */
return 1;
}
-static void
-change_bits(sb_devc * devc, unsigned char *regval, int dev, int chn, int newval)
+static void change_bits(sb_devc * devc, unsigned char *regval, int dev, int chn, int newval)
{
- unsigned char mask;
- int shift;
+ unsigned char mask;
+ int shift;
mask = (1 << (*devc->iomap)[dev][chn].nbits) - 1;
newval = (int) ((newval * mask) + 50) / 100; /* Scale */
@@ -58,19 +54,16 @@ change_bits(sb_devc * devc, unsigned char *regval, int dev, int chn, int newval)
*regval |= (newval & mask) << shift; /* Set the new value */
}
-static int
-sb_mixer_get(sb_devc * devc, int dev)
+static int sb_mixer_get(sb_devc * devc, int dev)
{
if (!((1 << dev) & devc->supported_devices))
return -EINVAL;
-
return devc->levels[dev];
}
-void
-smw_mixer_init(sb_devc * devc)
+void smw_mixer_init(sb_devc * devc)
{
- int i;
+ int i;
sb_setmixer(devc, 0x00, 0x18); /* Mute unused (Telephone) line */
sb_setmixer(devc, 0x10, 0x38); /* Config register 2 */
@@ -81,18 +74,15 @@ smw_mixer_init(sb_devc * devc)
devc->supported_devices |= (1 << i);
devc->supported_rec_devices = devc->supported_devices &
- ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_PCM |
- SOUND_MASK_VOLUME);
-
+ ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_PCM | SOUND_MASK_VOLUME);
sb_mixer_reset(devc);
}
-static int
-smw_mixer_set(sb_devc * devc, int dev, int value)
+static int smw_mixer_set(sb_devc * devc, int dev, int value)
{
- int left = value & 0x000000ff;
- int right = (value & 0x0000ff00) >> 8;
- int reg, val;
+ int left = value & 0x000000ff;
+ int right = (value & 0x0000ff00) >> 8;
+ int reg, val;
if (left > 100)
left = 100;
@@ -106,46 +96,45 @@ smw_mixer_set(sb_devc * devc, int dev, int value)
return -EINVAL;
switch (dev)
- {
- case SOUND_MIXER_VOLUME:
- sb_setmixer(devc, 0x0b, 96 - (96 * left / 100)); /* 96=mute, 0=max */
- sb_setmixer(devc, 0x0c, 96 - (96 * right / 100));
- break;
-
- case SOUND_MIXER_BASS:
- case SOUND_MIXER_TREBLE:
- devc->levels[dev] = left | (right << 8);
-
- /* Set left bass and treble values */
- val = ((devc->levels[SOUND_MIXER_TREBLE] & 0xff) * 16 / (unsigned) 100) << 4;
- val |= ((devc->levels[SOUND_MIXER_BASS] & 0xff) * 16 / (unsigned) 100) & 0x0f;
- sb_setmixer(devc, 0x0d, val);
-
- /* Set right bass and treble values */
- val = (((devc->levels[SOUND_MIXER_TREBLE] >> 8) & 0xff) * 16 / (unsigned) 100) << 4;
- val |= (((devc->levels[SOUND_MIXER_BASS] >> 8) & 0xff) * 16 / (unsigned) 100) & 0x0f;
- sb_setmixer(devc, 0x0e, val);
- break;
-
- default:
- reg = smw_mix_regs[dev];
- if (reg == 0)
- return -EINVAL;
- sb_setmixer(devc, reg, (24 - (24 * left / 100)) | 0x20); /* 24=mute, 0=max */
- sb_setmixer(devc, reg + 1, (24 - (24 * right / 100)) | 0x40);
- }
+ {
+ case SOUND_MIXER_VOLUME:
+ sb_setmixer(devc, 0x0b, 96 - (96 * left / 100)); /* 96=mute, 0=max */
+ sb_setmixer(devc, 0x0c, 96 - (96 * right / 100));
+ break;
+
+ case SOUND_MIXER_BASS:
+ case SOUND_MIXER_TREBLE:
+ devc->levels[dev] = left | (right << 8);
+ /* Set left bass and treble values */
+ val = ((devc->levels[SOUND_MIXER_TREBLE] & 0xff) * 16 / (unsigned) 100) << 4;
+ val |= ((devc->levels[SOUND_MIXER_BASS] & 0xff) * 16 / (unsigned) 100) & 0x0f;
+ sb_setmixer(devc, 0x0d, val);
+
+ /* Set right bass and treble values */
+ val = (((devc->levels[SOUND_MIXER_TREBLE] >> 8) & 0xff) * 16 / (unsigned) 100) << 4;
+ val |= (((devc->levels[SOUND_MIXER_BASS] >> 8) & 0xff) * 16 / (unsigned) 100) & 0x0f;
+ sb_setmixer(devc, 0x0e, val);
+
+ break;
+
+ default:
+ reg = smw_mix_regs[dev];
+ if (reg == 0)
+ return -EINVAL;
+ sb_setmixer(devc, reg, (24 - (24 * left / 100)) | 0x20); /* 24=mute, 0=max */
+ sb_setmixer(devc, reg + 1, (24 - (24 * right / 100)) | 0x40);
+ }
devc->levels[dev] = left | (right << 8);
return left | (right << 8);
}
-static int
-sb_mixer_set(sb_devc * devc, int dev, int value)
+static int sb_mixer_set(sb_devc * devc, int dev, int value)
{
- int left = value & 0x000000ff;
- int right = (value & 0x0000ff00) >> 8;
+ int left = value & 0x000000ff;
+ int right = (value & 0x0000ff00) >> 8;
- int regoffs;
+ int regoffs;
unsigned char val;
if (devc->model == MDL_SMW)
@@ -177,21 +166,21 @@ sb_mixer_set(sb_devc * devc, int dev, int value)
if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs) /*
* Change register
*/
- {
- sb_setmixer(devc, regoffs, val); /*
+ {
+ sb_setmixer(devc, regoffs, val); /*
* Save the old one
*/
- regoffs = (*devc->iomap)[dev][RIGHT_CHN].regno;
+ regoffs = (*devc->iomap)[dev][RIGHT_CHN].regno;
- if (regoffs == 0)
- return left | (left << 8); /*
+ if (regoffs == 0)
+ return left | (left << 8); /*
* Just left channel present
*/
- val = sb_getmixer(devc, regoffs); /*
- * Read the new one
+ val = sb_getmixer(devc, regoffs); /*
+ * Read the new one
*/
- }
+ }
change_bits(devc, &val, dev, RIGHT_CHN, right);
sb_setmixer(devc, regoffs, val);
@@ -200,86 +189,107 @@ sb_mixer_set(sb_devc * devc, int dev, int value)
return left | (right << 8);
}
-static void
-set_recsrc(sb_devc * devc, int src)
+static void set_recsrc(sb_devc * devc, int src)
{
sb_setmixer(devc, RECORD_SRC, (sb_getmixer(devc, RECORD_SRC) & ~7) | (src & 0x7));
}
-static int
-set_recmask(sb_devc * devc, int mask)
+static int set_recmask(sb_devc * devc, int mask)
{
- int devmask, i;
- unsigned char regimageL, regimageR;
+ int devmask, i;
+ unsigned char regimageL, regimageR;
devmask = mask & devc->supported_rec_devices;
switch (devc->model)
- {
- case MDL_SBPRO:
- case MDL_ESS:
- case MDL_JAZZ:
- case MDL_SMW:
-
- if (devmask != SOUND_MASK_MIC &&
- devmask != SOUND_MASK_LINE &&
- devmask != SOUND_MASK_CD)
- { /*
- * More than one devices selected. Drop the *
+ {
+ case MDL_SBPRO:
+ case MDL_ESS:
+ case MDL_JAZZ:
+ case MDL_SMW:
+
+ if (devmask != SOUND_MASK_MIC &&
+ devmask != SOUND_MASK_LINE &&
+ devmask != SOUND_MASK_CD)
+ {
+ /*
+ * More than one device selected. Drop the
* previous selection
*/
- devmask &= ~devc->recmask;
- }
- if (devmask != SOUND_MASK_MIC &&
- devmask != SOUND_MASK_LINE &&
- devmask != SOUND_MASK_CD)
- { /*
- * More than one devices selected. Default to
- * * mic
+ devmask &= ~devc->recmask;
+ }
+ if (devmask != SOUND_MASK_MIC &&
+ devmask != SOUND_MASK_LINE &&
+ devmask != SOUND_MASK_CD)
+ {
+ /*
+ * More than one device selected. Default to
+ * mic
*/
- devmask = SOUND_MASK_MIC;
- }
- if (devmask ^ devc->recmask) /*
- * Input source changed
- */
- {
- switch (devmask)
- {
-
- case SOUND_MASK_MIC:
- set_recsrc(devc, SRC__MIC);
- break;
-
- case SOUND_MASK_LINE:
- set_recsrc(devc, SRC__LINE);
- break;
-
- case SOUND_MASK_CD:
- set_recsrc(devc, SRC__CD);
- break;
-
- default:
- set_recsrc(devc, SRC__MIC);
- }
- }
- break;
-
- case MDL_SB16:
- if (!devmask)
- devmask = SOUND_MASK_MIC;
-
- regimageL = regimageR = 0;
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- if ((1 << i) & devmask)
- {
- regimageL |= sb16_recmasks_L[i];
- regimageR |= sb16_recmasks_R[i];
- }
- sb_setmixer(devc, SB16_IMASK_L, regimageL);
- sb_setmixer(devc, SB16_IMASK_R, regimageR);
- break;
- }
-
+ devmask = SOUND_MASK_MIC;
+ }
+ if (devmask ^ devc->recmask) /*
+ * Input source changed
+ */
+ {
+ switch (devmask)
+ {
+ case SOUND_MASK_MIC:
+ set_recsrc(devc, SRC__MIC);
+ break;
+
+ case SOUND_MASK_LINE:
+ set_recsrc(devc, SRC__LINE);
+ break;
+
+ case SOUND_MASK_CD:
+ set_recsrc(devc, SRC__CD);
+ break;
+
+ default:
+ set_recsrc(devc, SRC__MIC);
+ }
+ }
+ break;
+
+ case MDL_SB16:
+ if (!devmask)
+ devmask = SOUND_MASK_MIC;
+
+ if (devc->submodel == SUBMDL_ALS007)
+ {
+ switch (devmask)
+ {
+ case SOUND_MASK_LINE:
+ sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_LINE);
+ break;
+ case SOUND_MASK_CD:
+ sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_CD);
+ break;
+ case SOUND_MASK_SYNTH:
+ sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_SYNTH);
+ break;
+ default: /* Also takes care of SOUND_MASK_MIC case */
+ sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_MIC);
+ break;
+ }
+ }
+ else
+ {
+ regimageL = regimageR = 0;
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ {
+ if ((1 << i) & devmask)
+ {
+ regimageL |= sb16_recmasks_L[i];
+ regimageR |= sb16_recmasks_R[i];
+ }
+ sb_setmixer (devc, SB16_IMASK_L, regimageL);
+ sb_setmixer (devc, SB16_IMASK_R, regimageR);
+ }
+ }
+ break;
+ }
devc->recmask = devmask;
return devc->recmask;
}
@@ -292,52 +302,57 @@ static int sb_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
/*
* Use ioctl(fd, SOUND_MIXER_PRIVATE1, &mode) to turn AGC off (0) or on (1).
*/
- if (cmd == SOUND_MIXER_PRIVATE1 && devc->model == MDL_SB16) {
+ if (cmd == SOUND_MIXER_PRIVATE1 && devc->model == MDL_SB16)
+ {
if (get_user(val, (int *)arg))
return -EFAULT;
sb_setmixer(devc, 0x43, (~val) & 0x01);
return 0;
}
- if (((cmd >> 8) & 0xff) == 'M') {
- if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
+ if (((cmd >> 8) & 0xff) == 'M')
+ {
+ if (_SIOC_DIR(cmd) & _SIOC_WRITE)
+ {
if (get_user(val, (int *)arg))
return -EFAULT;
- switch (cmd & 0xff) {
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ ret = set_recmask(devc, val);
+ break;
+
+ default:
+ ret = sb_mixer_set(devc, cmd & 0xff, val);
+ }
+ }
+ else switch (cmd & 0xff)
+ {
case SOUND_MIXER_RECSRC:
- ret = set_recmask(devc, val);
+ ret = devc->recmask;
break;
-
- default:
- ret = sb_mixer_set(devc, cmd & 0xff, val);
- }
- } else
- switch (cmd & 0xff) {
- case SOUND_MIXER_RECSRC:
- ret = devc->recmask;
- break;
- case SOUND_MIXER_DEVMASK:
- ret = devc->supported_devices;
- break;
+ case SOUND_MIXER_DEVMASK:
+ ret = devc->supported_devices;
+ break;
- case SOUND_MIXER_STEREODEVS:
- ret = devc->supported_devices;
- if (devc->model != MDL_JAZZ && devc->model != MDL_SMW)
- ret &= ~(SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_IMIX);
- break;
+ case SOUND_MIXER_STEREODEVS:
+ ret = devc->supported_devices;
+ if (devc->model != MDL_JAZZ && devc->model != MDL_SMW)
+ ret &= ~(SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_IMIX);
+ break;
- case SOUND_MIXER_RECMASK:
- ret = devc->supported_rec_devices;
- break;
+ case SOUND_MIXER_RECMASK:
+ ret = devc->supported_rec_devices;
+ break;
- case SOUND_MIXER_CAPS:
- ret = devc->mixer_caps;
- break;
+ case SOUND_MIXER_CAPS:
+ ret = devc->mixer_caps;
+ break;
- default:
- ret = sb_mixer_get(devc, cmd & 0xff);
- break;
- }
+ default:
+ ret = sb_mixer_get(devc, cmd & 0xff);
+ break;
+ }
return put_user(ret, (int *)arg);
} else
return -EINVAL;
@@ -350,12 +365,18 @@ static struct mixer_operations sb_mixer_operations =
sb_mixer_ioctl
};
-static void
-sb_mixer_reset(sb_devc * devc)
+static struct mixer_operations als007_mixer_operations =
{
- char name[32];
- int i;
- extern int sm_games;
+ "ALS007",
+ "Avance ALS-007",
+ sb_mixer_ioctl
+};
+
+static void sb_mixer_reset(sb_devc * devc)
+{
+ char name[32];
+ int i;
+ extern int sm_games;
sprintf(name, "SB_%d", devc->sbmixnum);
@@ -366,15 +387,13 @@ sb_mixer_reset(sb_devc * devc)
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
sb_mixer_set(devc, i, devc->levels[i]);
-
set_recmask(devc, SOUND_MASK_MIC);
}
-int
-sb_mixer_init(sb_devc * devc)
+int sb_mixer_init(sb_devc * devc)
{
- int mixer_type = 0;
- int m;
+ int mixer_type = 0;
+ int m;
devc->sbmixnum = sbmixnum++;
devc->levels = NULL;
@@ -385,64 +404,69 @@ sb_mixer_init(sb_devc * devc)
return 0; /* No mixer. Why? */
switch (devc->model)
- {
- case MDL_SBPRO:
- case MDL_AZTECH:
- case MDL_JAZZ:
- devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
- devc->supported_devices = SBPRO_MIXER_DEVICES;
- devc->supported_rec_devices = SBPRO_RECORDING_DEVICES;
- devc->iomap = &sbpro_mix;
- break;
-
- case MDL_ESS:
- devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
- devc->supported_devices = ES688_MIXER_DEVICES;
- devc->supported_rec_devices = ES688_RECORDING_DEVICES;
- devc->iomap = &es688_mix;
- break;
-
- case MDL_SMW:
- devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
- devc->supported_devices = 0;
- devc->supported_rec_devices = 0;
- devc->iomap = &sbpro_mix;
- smw_mixer_init(devc);
- break;
-
- case MDL_SB16:
- devc->mixer_caps = 0;
- devc->supported_devices = SB16_MIXER_DEVICES;
- devc->supported_rec_devices = SB16_RECORDING_DEVICES;
- devc->iomap = &sb16_mix;
- break;
-
- default:
- printk("SB Warning: Unsupported mixer type %d\n", devc->model);
- return 0;
- }
+ {
+ case MDL_SBPRO:
+ case MDL_AZTECH:
+ case MDL_JAZZ:
+ devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
+ devc->supported_devices = SBPRO_MIXER_DEVICES;
+ devc->supported_rec_devices = SBPRO_RECORDING_DEVICES;
+ devc->iomap = &sbpro_mix;
+ break;
+
+ case MDL_ESS:
+ devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
+ devc->supported_devices = ES688_MIXER_DEVICES;
+ devc->supported_rec_devices = ES688_RECORDING_DEVICES;
+ devc->iomap = &es688_mix;
+ break;
+
+ case MDL_SMW:
+ devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
+ devc->supported_devices = 0;
+ devc->supported_rec_devices = 0;
+ devc->iomap = &sbpro_mix;
+ smw_mixer_init(devc);
+ break;
+
+ case MDL_SB16:
+ devc->mixer_caps = 0;
+ devc->supported_rec_devices = SB16_RECORDING_DEVICES;
+ if (devc->submodel != SUBMDL_ALS007)
+ {
+ devc->supported_devices = SB16_MIXER_DEVICES;
+ devc->iomap = &sb16_mix;
+ }
+ else
+ {
+ devc->supported_devices = ALS007_MIXER_DEVICES;
+ devc->iomap = &als007_mix;
+ }
+ break;
+
+ default:
+ printk(KERN_WARNING "sb_mixer: Unsupported mixer type %d\n", devc->model);
+ return 0;
+ }
m = sound_alloc_mixerdev();
if (m == -1)
return 0;
-
- mixer_devs[m] = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct mixer_operations)));
- sound_mem_sizes[sound_nblocks] = sizeof(struct mixer_operations);
-
- if (sound_nblocks < 1024)
- sound_nblocks++;;
+ mixer_devs[m] = (struct mixer_operations *)kmalloc(sizeof(struct mixer_operations), GFP_KERNEL);
if (mixer_devs[m] == NULL)
- {
- printk(KERN_ERR "sb_mixer: Can't allocate memory\n");
- sound_unload_mixerdev(m);
- return 0;
- }
- memcpy((char *) mixer_devs[m], (char *) &sb_mixer_operations,
- sizeof(struct mixer_operations));
+ {
+ printk(KERN_ERR "sb_mixer: Can't allocate memory\n");
+ sound_unload_mixerdev(m);
+ return 0;
+ }
- mixer_devs[m]->devc = devc;
+ if (devc->submodel != SUBMDL_ALS007)
+ memcpy ((char *) mixer_devs[m], (char *) &sb_mixer_operations, sizeof (struct mixer_operations));
+ else
+ memcpy ((char *) mixer_devs[m], (char *) &als007_mixer_operations, sizeof (struct mixer_operations));
+ mixer_devs[m]->devc = devc;
devc->my_mixerdev = m;
sb_mixer_reset(devc);
return 1;
diff --git a/drivers/sound/sb_mixer.h b/drivers/sound/sb_mixer.h
index 2f68a62f3..f92f02e7d 100644
--- a/drivers/sound/sb_mixer.h
+++ b/drivers/sound/sb_mixer.h
@@ -49,6 +49,13 @@
SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | \
SOUND_MASK_IMIX)
+/* These are the only devices that are working at the moment. Others could
+ * be added once they are identified and a method is found to control them.
+ */
+#define ALS007_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | \
+ SOUND_MASK_PCM | SOUND_MASK_MIC | \
+ SOUND_MASK_CD | \
+ SOUND_MASK_VOLUME)
/*
* Mixer registers
*
@@ -97,6 +104,13 @@
#define LEFT_CHN 0
#define RIGHT_CHN 1
+/*
+ * Mixer registers of ALS007
+ */
+#define ALS007_RECORD_SRC 0x6c
+#define ALS007_OUTPUT_CTRL1 0x3c
+#define ALS007_OUTPUT_CTRL2 0x4c
+
#define MIX_ENT(name, reg_l, bit_l, len_l, reg_r, bit_r, len_r) \
{{reg_l, bit_l, len_l}, {reg_r, bit_r, len_r}}
@@ -173,6 +187,25 @@ MIX_ENT(SOUND_MIXER_IGAIN, 0x3f, 7, 2, 0x40, 7, 2),
MIX_ENT(SOUND_MIXER_OGAIN, 0x41, 7, 2, 0x42, 7, 2)
};
+static mixer_tab als007_mix =
+{
+MIX_ENT(SOUND_MIXER_VOLUME, 0x62, 7, 4, 0x62, 3, 4),
+MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_SYNTH, 0x66, 7, 4, 0x66, 3, 4),
+MIX_ENT(SOUND_MIXER_PCM, 0x64, 7, 4, 0x64, 3, 4),
+MIX_ENT(SOUND_MIXER_SPEAKER, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE, 0x6e, 7, 4, 0x6e, 3, 4),
+MIX_ENT(SOUND_MIXER_MIC, 0x6a, 6, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_CD, 0x68, 7, 4, 0x68, 3, 4),
+MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0), /* Obsolete. Use IGAIN */
+MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0)
+};
+
+
/* SM_GAMES Master volume is lower and PCM & FM volumes
higher than with SB Pro. This improves the
sound quality */
@@ -284,5 +317,14 @@ static char smw_mix_regs[] = /* Left mixer registers */
#define SRC__CD 3 /* Select CD recording source */
#define SRC__LINE 7 /* Use Line-in for recording source */
+/*
+ * Recording sources for ALS-007
+ */
+
+#define ALS007_MIC 4
+#define ALS007_LINE 6
+#define ALS007_CD 2
+#define ALS007_SYNTH 7
+
#endif
#endif
diff --git a/drivers/sound/sequencer.c b/drivers/sound/sequencer.c
index 22d30569f..e65995937 100644
--- a/drivers/sound/sequencer.c
+++ b/drivers/sound/sequencer.c
@@ -16,6 +16,10 @@
*/
#include <linux/config.h>
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
#define SEQUENCER_C
#include "sound_config.h"
@@ -478,7 +482,7 @@ static void seq_chn_voice_event(unsigned char *event_rec)
parm = 64;
}
}
-
+
switch (cmd)
{
case MIDI_NOTEON:
@@ -950,7 +954,7 @@ static void setup_mode2(void)
synth_devs[max_synthdev++] = midi_devs[dev]->converter;
}
}
-
+
for (dev = 0; dev < max_synthdev; dev++)
{
int chn;
@@ -993,15 +997,20 @@ int sequencer_open(int dev, struct file *file)
return -ENXIO;
}
if (dev) /* Patch manager device (obsolete) */
- return -ENXIO;
+ return -ENXIO;
+
+#ifdef CONFIG_KMOD
+ if(synth_devs[dev] == NULL)
+ request_module("synth0");
+#endif
if (mode == OPEN_READ)
{
if (!num_midis)
{
- /*printk("Sequencer: No MIDI devices. Input not possible\n");*/
- sequencer_busy = 0;
- return -ENXIO;
+ /*printk("Sequencer: No MIDI devices. Input not possible\n");*/
+ sequencer_busy = 0;
+ return -ENXIO;
}
}
save_flags(flags);
@@ -1033,8 +1042,8 @@ int sequencer_open(int dev, struct file *file)
for (i = 0; i < num_sound_timers; i++)
if (sound_timer_devs[i] && sound_timer_devs[i]->priority > best)
{
- tmr_no = i;
- best = sound_timer_devs[i]->priority;
+ tmr_no = i;
+ best = sound_timer_devs[i]->priority;
}
if (tmr_no == -1) /* Should not be */
tmr_no = 0;
@@ -1066,7 +1075,7 @@ int sequencer_open(int dev, struct file *file)
{
if (synth_devs[i]==NULL)
continue;
-
+
if ((tmp = synth_devs[i]->open(i, mode)) < 0)
{
printk(KERN_WARNING "Sequencer: Warning! Cannot open synth device #%d (%d)\n", i, tmp);
@@ -1096,7 +1105,7 @@ int sequencer_open(int dev, struct file *file)
/*
* Initialize midi input devices
*/
-
+
for (i = 0; i < max_mididev; i++)
if (!midi_opened[i])
{
@@ -1140,7 +1149,7 @@ void seq_drain_midi_queues(void)
/*
* Let's have a delay
*/
-
+
if (n) {
current->timeout = jiffies + HZ / 10;
interruptible_sleep_on(&seq_sleeper);
@@ -1173,7 +1182,7 @@ void sequencer_release(int dev, struct file *file)
/* Extra delay */
}
}
-
+
if (mode != OPEN_READ)
seq_drain_midi_queues(); /*
* Ensure the output queues are empty
@@ -1201,7 +1210,7 @@ void sequencer_release(int dev, struct file *file)
for (i = 0; i < max_mididev; i++)
{
if (midi_opened[i])
- midi_devs[i]->close(i);
+ midi_devs[i]->close(i);
}
if (seq_mode == SEQ_2)
@@ -1329,7 +1338,7 @@ static void seq_reset(void)
save_flags(flags);
cli();
-
+
if (waitqueue_active(&seq_sleeper)) {
/* printk( "Sequencer Warning: Unexpected sleeping process - Waking up\n"); */
wake_up(&seq_sleeper);
@@ -1368,7 +1377,7 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
orig_dev = dev = dev >> 4;
- switch (cmd)
+ switch (cmd)
{
case SNDCTL_TMR_TIMEBASE:
case SNDCTL_TMR_TEMPO:
@@ -1380,13 +1389,13 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
if (seq_mode != SEQ_2)
return -EINVAL;
return tmr->ioctl(tmr_no, cmd, arg);
-
+
case SNDCTL_TMR_SELECT:
if (seq_mode != SEQ_2)
return -EINVAL;
if (get_user(pending_timer, (int *)arg))
return -EFAULT;
- if (pending_timer < 0 || pending_timer >= num_sound_timers || sound_timer_devs[pending_timer] == NULL)
+ if (pending_timer < 0 || pending_timer >= num_sound_timers || sound_timer_devs[pending_timer] == NULL)
{
pending_timer = -1;
return -EINVAL;
@@ -1397,14 +1406,14 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
case SNDCTL_SEQ_PANIC:
seq_panic();
return -EINVAL;
-
+
case SNDCTL_SEQ_SYNC:
if (mode == OPEN_READ)
return 0;
while (qlen > 0 && !signal_pending(current))
seq_sync();
return qlen ? -EINTR : 0;
-
+
case SNDCTL_SEQ_RESET:
seq_reset();
return 0;
@@ -1414,8 +1423,8 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
return -EFAULT;
if (midi_dev < 0 || midi_dev >= max_mididev)
return -ENXIO;
-
- if (!midi_opened[midi_dev] &&
+
+ if (!midi_opened[midi_dev] &&
(err = midi_devs[midi_dev]->open(midi_dev, mode, sequencer_midi_input,
sequencer_midi_output)) < 0)
return err;
@@ -1427,13 +1436,13 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
return 0;
val = iqlen;
break;
-
+
case SNDCTL_SEQ_GETOUTCOUNT:
if (mode == OPEN_READ)
return 0;
val = SEQ_MAX_QUEUE - qlen;
break;
-
+
case SNDCTL_SEQ_GETTIME:
if (seq_mode == SEQ_2)
return tmr->ioctl(tmr_no, cmd, arg);
@@ -1442,14 +1451,14 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
else
val = jiffies - seq_time;
break;
-
+
case SNDCTL_SEQ_CTRLRATE:
/*
* If *arg == 0, just return the current rate
*/
if (seq_mode == SEQ_2)
return tmr->ioctl(tmr_no, cmd, arg);
-
+
if (get_user(val, (int *)arg))
return -EFAULT;
if (val != 0)
@@ -1504,7 +1513,7 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
if (!(synth_open_mask & (1 << dev)) && !orig_dev)
return -EBUSY;
return synth_devs[dev]->ioctl(dev, cmd, arg);
-
+
/* Like SYNTH_INFO but returns ID in the name field */
case SNDCTL_SYNTH_ID:
if (get_user(dev, (int *)(&(((struct synth_info *)arg)->device))))
@@ -1517,7 +1526,7 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
strncpy(inf.name, synth_devs[dev]->id, sizeof(inf.name));
inf.device = dev;
return copy_to_user(arg, &inf, sizeof(inf))?-EFAULT:0;
-
+
case SNDCTL_SEQ_OUTOFBAND:
if (copy_from_user(&event_rec, arg, sizeof(event_rec)))
return -EFAULT;
@@ -1526,7 +1535,7 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
play_event(event_rec.arr);
restore_flags(flags);
return 0;
-
+
case SNDCTL_MIDI_INFO:
if (get_user(dev, (int *)(&(((struct synth_info *)arg)->device))))
return -EFAULT;
@@ -1534,7 +1543,7 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
return -ENXIO;
midi_devs[dev]->info.device = dev;
return copy_to_user(arg, &midi_devs[dev]->info, sizeof(struct synth_info))?-EFAULT:0;
-
+
case SNDCTL_SEQ_THRESHOLD:
if (get_user(val, (int *)arg))
return -EFAULT;
@@ -1544,7 +1553,7 @@ int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
val = SEQ_MAX_QUEUE - 1;
output_threshold = val;
return 0;
-
+
case SNDCTL_MIDI_PRETIME:
if (get_user(val, (int *)arg))
return -EFAULT;
@@ -1584,7 +1593,7 @@ unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait)
/* output */
poll_wait(file, &seq_sleeper, wait);
- if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
+ if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
mask |= POLLOUT | POLLWRNORM;
restore_flags(flags);
return mask;
@@ -1665,8 +1674,8 @@ unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
*/
while (bend > 2399)
{
- multiplier *= 4;
- bend -= 2400;
+ multiplier *= 4;
+ bend -= 2400;
}
semitones = bend / 100;
@@ -1693,8 +1702,8 @@ void sequencer_init(void)
queue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * EV_SZ);
if (queue == NULL)
{
- printk(KERN_ERR "sequencer: Can't allocate memory for sequencer output queue\n");
- return;
+ printk(KERN_ERR "sequencer: Can't allocate memory for sequencer output queue\n");
+ return;
}
iqueue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * IEV_SZ);
if (iqueue == NULL)
diff --git a/drivers/sound/softoss.c b/drivers/sound/softoss.c
index 43c3a7ec3..630668853 100644
--- a/drivers/sound/softoss.c
+++ b/drivers/sound/softoss.c
@@ -2,15 +2,15 @@
* sound/softoss.c
*
* Software based MIDI synthsesizer driver.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* 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>
@@ -35,14 +35,15 @@
#include "softoss.h"
#include <linux/ultrasound.h>
-int softsynth_disabled = 0;
+int softsynth_disabled = 0;
static volatile int intr_pending = 0;
#ifdef POLLED_MODE
-static struct timer_list poll_timer =
-{NULL, NULL, 0, 0, softsyn_poll};
+static struct timer_list poll_timer = {
+ NULL, NULL, 0, 0, softsyn_poll
+};
#else
#endif
@@ -101,11 +102,14 @@ extern int *sound_osp;
static volatile int is_running = 0;
static int softsynth_loaded = 0;
-static struct synth_info softsyn_info =
-{"SoftOSS", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 0, 16, 0, MAX_PATCH};
+static struct synth_info softsyn_info = {
+ "SoftOSS", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 0, 16, 0, MAX_PATCH
+};
+
+static struct softsyn_devc sdev_info = {
+ 0
+};
-static struct softsyn_devc sdev_info =
-{0};
softsyn_devc *devc = &sdev_info; /* used in softoss_rs.c */
static struct voice_alloc_info *voice_alloc;
@@ -118,10 +122,9 @@ static volatile int tmr_running = 0;
static int voice_limit = 24;
-static void
-set_max_voices(int nr)
+static void set_max_voices(int nr)
{
- int i;
+ int i;
if (nr < 4)
nr = 4;
@@ -134,19 +137,18 @@ set_max_voices(int nr)
for (i = 31; i > 0; i--)
if (nr & (1 << i))
- {
- devc->afterscale = i + 1;
- return;
- }
+ {
+ devc->afterscale = i + 1;
+ return;
+ }
}
-static void
-update_vibrato(int voice)
+static void update_vibrato(int voice)
{
- voice_info *v = &softoss_voices[voice];
+ voice_info *v = &softoss_voices[voice];
#ifdef HANDLE_LFO
- int x;
+ int x;
x = vibrato_table[v->vibrato_phase >> 8];
v->vibrato_phase = (v->vibrato_phase + v->vibrato_step) & 0x7fff;
@@ -161,11 +163,10 @@ update_vibrato(int voice)
}
#ifdef HANDLE_LFO
-static void
-update_tremolo(int voice)
+static void update_tremolo(int voice)
{
- voice_info *v = &softoss_voices[voice];
- int x;
+ voice_info *v = &softoss_voices[voice];
+ int x;
x = tremolo_table[v->tremolo_phase >> 8];
v->tremolo_phase = (v->tremolo_phase + v->tremolo_step) & 0x7fff;
@@ -174,11 +175,10 @@ update_tremolo(int voice)
}
#endif
-static void
-start_vibrato(int voice)
+static void start_vibrato(int voice)
{
- voice_info *v = &softoss_voices[voice];
- int rate;
+ voice_info *v = &softoss_voices[voice];
+ int rate;
if (!v->vibrato_depth)
return;
@@ -189,11 +189,10 @@ start_vibrato(int voice)
devc->vibratomap |= (1 << voice); /* Enable vibrato */
}
-static void
-start_tremolo(int voice)
+static void start_tremolo(int voice)
{
- voice_info *v = &softoss_voices[voice];
- int rate;
+ voice_info *v = &softoss_voices[voice];
+ int rate;
if (!v->tremolo_depth)
return;
@@ -204,43 +203,43 @@ start_tremolo(int voice)
devc->tremolomap |= (1 << voice); /* Enable tremolo */
}
-static void
-update_volume(int voice)
+static void update_volume(int voice)
{
- voice_info *v = &softoss_voices[voice];
- unsigned int vol;
+ voice_info *v = &softoss_voices[voice];
+ unsigned int vol;
-/*
- * Compute plain volume
- */
+ /*
+ * Compute plain volume
+ */
vol = (v->velocity * v->expression_vol * v->main_vol) >> 12;
#ifdef HANDLE_LFO
-/*
- * Handle LFO
- */
+ /*
+ * Handle LFO
+ */
if (devc->tremolomap & (1 << voice))
- {
- int t;
+ {
+ int t;
- t = 32768 - v->tremolo_level;
- vol = (vol * t) >> 15;
- update_tremolo(voice);
- }
+ t = 32768 - v->tremolo_level;
+ vol = (vol * t) >> 15;
+ update_tremolo(voice);
+ }
#endif
-/*
- * Envelope
- */
+ /*
+ * Envelope
+ */
+
if (v->mode & WAVE_ENVELOPES && !v->percussive_voice)
vol = (vol * (v->envelope_vol >> 16)) >> 19;
else
vol >>= 4;
-/*
- * Handle panning
- */
+ /*
+ * Handle panning
+ */
if (v->panning < 0) /* Pan left */
v->rightvol = (vol * (128 + v->panning)) / 128;
@@ -253,45 +252,47 @@ update_volume(int voice)
v->leftvol = vol;
}
-static void
-step_envelope(int voice, int do_release, int velocity)
+static void step_envelope(int voice, int do_release, int velocity)
{
- voice_info *v = &softoss_voices[voice];
- int r, rate, time, dif;
- unsigned int vol;
- unsigned long flags;
+ voice_info *v = &softoss_voices[voice];
+ int r, rate, time, dif;
+ unsigned int vol;
+ unsigned long flags;
save_flags(flags);
cli();
if (!voice_active[voice] || v->sample == NULL)
- {
- restore_flags(flags);
- return;
- }
+ {
+ restore_flags(flags);
+ return;
+ }
if (!do_release)
+ {
if (v->mode & WAVE_SUSTAIN_ON && v->envelope_phase == 2)
- { /* Stop envelope until note off */
- v->envelope_volstep = 0;
- v->envelope_time = 0x7fffffff;
- if (v->mode & WAVE_VIBRATO)
- start_vibrato(voice);
- if (v->mode & WAVE_TREMOLO)
- start_tremolo(voice);
- restore_flags(flags);
- return;
- }
+ {
+ /* Stop envelope until note off */
+ v->envelope_volstep = 0;
+ v->envelope_time = 0x7fffffff;
+ if (v->mode & WAVE_VIBRATO)
+ start_vibrato(voice);
+ if (v->mode & WAVE_TREMOLO)
+ start_tremolo(voice);
+ restore_flags(flags);
+ return;
+ }
+ }
if (do_release)
v->envelope_phase = 3;
else
v->envelope_phase++;
if (v->envelope_phase >= 5) /* Finished */
- {
- init_voice(devc, voice);
- restore_flags(flags);
- return;
- }
+ {
+ init_voice(devc, voice);
+ restore_flags(flags);
+ return;
+ }
vol = v->envelope_target = v->sample->env_offset[v->envelope_phase] << 22;
@@ -308,72 +309,69 @@ step_envelope(int voice, int do_release, int velocity)
if (dif < 0)
dif *= -1;
if (dif < rate * 2) /* Too close */
- {
- step_envelope(voice, 0, 60);
- restore_flags(flags);
- return;
- }
+ {
+ step_envelope(voice, 0, 60);
+ restore_flags(flags);
+ return;
+ }
+
if (vol > v->envelope_vol)
- {
- v->envelope_volstep = rate;
- time = (vol - v->envelope_vol) / rate;
- } else
- {
- v->envelope_volstep = -rate;
- time = (v->envelope_vol - vol) / rate;
- }
+ {
+ v->envelope_volstep = rate;
+ time = (vol - v->envelope_vol) / rate;
+ }
+ else
+ {
+ v->envelope_volstep = -rate;
+ time = (v->envelope_vol - vol) / rate;
+ }
time--;
if (time <= 0)
time = 1;
-
v->envelope_time = time;
-
-
restore_flags(flags);
}
-static void
-step_envelope_lfo(int voice)
+static void step_envelope_lfo(int voice)
{
- voice_info *v = &softoss_voices[voice];
+ voice_info *v = &softoss_voices[voice];
-/*
- * Update pitch (vibrato) LFO
- */
+ /*
+ * Update pitch (vibrato) LFO
+ */
if (devc->vibratomap & (1 << voice))
update_vibrato(voice);
-/*
- * Update envelope
- */
+ /*
+ * Update envelope
+ */
if (v->mode & WAVE_ENVELOPES)
- {
- v->envelope_vol += v->envelope_volstep;
- /* Overshoot protection */
- if (v->envelope_vol < 0)
- {
- v->envelope_vol = v->envelope_target;
- v->envelope_volstep = 0;
- }
- if (v->envelope_time-- <= 0)
- {
- v->envelope_vol = v->envelope_target;
- step_envelope(voice, 0, 60);
- }
- }
+ {
+ v->envelope_vol += v->envelope_volstep;
+ /* Overshoot protection */
+ if (v->envelope_vol < 0)
+ {
+ v->envelope_vol = v->envelope_target;
+ v->envelope_volstep = 0;
+ }
+ if (v->envelope_time-- <= 0)
+ {
+ v->envelope_vol = v->envelope_target;
+ step_envelope(voice, 0, 60);
+ }
+ }
}
-static void
-compute_step(int voice)
+static void compute_step(int voice)
{
- voice_info *v = &softoss_voices[voice];
+ voice_info *v = &softoss_voices[voice];
/*
- * Since the pitch bender may have been set before playing the note, we
- * have to calculate the bending now.
+ * Since the pitch bender may have been set before playing the note, we
+ * have to calculate the bending now.
*/
v->current_freq = compute_finetune(v->orig_freq,
@@ -386,11 +384,10 @@ compute_step(int voice)
v->step *= -1; /* Reversed playback */
}
-static void
-init_voice(softsyn_devc * devc, int voice)
+static void init_voice(softsyn_devc * devc, int voice)
{
- voice_info *v = &softoss_voices[voice];
- unsigned long flags;
+ voice_info *v = &softoss_voices[voice];
+ unsigned long flags;
save_flags(flags);
cli();
@@ -433,18 +430,17 @@ init_voice(softsyn_devc * devc, int voice)
restore_flags(flags);
}
-static void
-reset_samples(softsyn_devc * devc)
+static void reset_samples(softsyn_devc * devc)
{
- int i;
+ int i;
for (i = 0; i < MAX_VOICE; i++)
voice_active[i] = 0;
for (i = 0; i < devc->maxvoice; i++)
- {
- init_voice(devc, i);
- softoss_voices[i].instr = 0;
- }
+ {
+ init_voice(devc, i);
+ softoss_voices[i].instr = 0;
+ }
devc->ram_used = 0;
@@ -452,20 +448,18 @@ reset_samples(softsyn_devc * devc)
devc->programs[i] = NO_SAMPLE;
for (i = 0; i < devc->nrsamples; i++)
- {
- vfree(devc->samples[i]);
- vfree(devc->wave[i]);
- devc->samples[i] = NULL;
- devc->wave[i] = NULL;
- }
-
+ {
+ vfree(devc->samples[i]);
+ vfree(devc->wave[i]);
+ devc->samples[i] = NULL;
+ devc->wave[i] = NULL;
+ }
devc->nrsamples = 0;
}
-static void
-init_engine(softsyn_devc * devc)
+static void init_engine(softsyn_devc * devc)
{
- int i, fz, srate, sz = devc->channels;
+ int i, fz, srate, sz = devc->channels;
set_max_voices(devc->default_max_voices);
voice_alloc->timestamp = 0;
@@ -480,16 +474,15 @@ init_engine(softsyn_devc * devc)
devc->usecs_per_frag = (1000000 * fz) / devc->speed;
for (i = 0; i < devc->maxvoice; i++)
- {
- init_voice(devc, i);
- softoss_voices[i].instr = 0;
- }
-
+ {
+ init_voice(devc, i);
+ softoss_voices[i].instr = 0;
+ }
devc->engine_state = ES_STOPPED;
-/*
- * Initialize delay
- */
+ /*
+ * Initialize delay
+ */
for (i = 0; i < DELAY_SIZE; i++)
left_delay[i] = right_delay[i] = 0;
@@ -502,34 +495,35 @@ init_engine(softsyn_devc * devc)
devc->delay_size = DELAY_SIZE;
}
-void
-softsyn_control_loop(void)
+void softsyn_control_loop(void)
{
- int voice;
+ int voice;
-/*
- * Recompute envlope, LFO, etc.
- */
+ /*
+ * Recompute envlope, LFO, etc.
+ */
for (voice = 0; voice < devc->maxvoice; voice++)
+ {
if (voice_active[voice])
- {
- update_volume(voice);
- step_envelope_lfo(voice);
- } else
+ {
+ update_volume(voice);
+ step_envelope_lfo(voice);
+ }
+ else
voice_alloc->map[voice] = 0;
+ }
}
-static void start_engine(softsyn_devc * devc);
+static void start_engine(softsyn_devc * devc);
-static void
-do_resample(int dummy)
+static void do_resample(int dummy)
{
struct dma_buffparms *dmap = audio_devs[devc->audiodev]->dmap_out;
struct voice_info *vinfo;
unsigned long flags, jif;
- int voice, loops;
- short *buf;
+ int voice, loops;
+ short *buf;
if (softsynth_disabled)
return;
@@ -538,68 +532,70 @@ do_resample(int dummy)
cli();
if (is_running)
- {
- printk("SoftOSS: Playback overrun\n");
- restore_flags(flags);
- return;
- }
+ {
+ printk(KERN_WARNING "SoftOSS: Playback overrun\n");
+ restore_flags(flags);
+ return;
+ }
jif = jiffies;
if (jif == last_resample_jiffies)
- {
- if (resample_counter++ > 50)
- {
- for (voice = 0; voice < devc->maxvoice; voice++)
- init_voice(devc, voice);
- voice_limit--;
- resample_counter = 0;
- printk("SoftOSS: CPU overload. Limiting # of voices to %d\n", voice_limit);
-
- if (voice_limit < 10)
- {
- voice_limit = 10;
- devc->speed = (devc->speed * 2) / 3;
-
- printk("SoftOSS: Dropping sampling rate and stopping the device.\n");
- softsynth_disabled = 1;
- }
- }
- } else
- {
- last_resample_jiffies = jif;
- resample_counter = 0;
- }
+ {
+ if (resample_counter++ > 50)
+ {
+ for (voice = 0; voice < devc->maxvoice; voice++)
+ init_voice(devc, voice);
+ voice_limit--;
+ resample_counter = 0;
+ printk(KERN_WARNING "SoftOSS: CPU overload. Limiting # of voices to %d\n", voice_limit);
+
+ if (voice_limit < 10)
+ {
+ voice_limit = 10;
+ devc->speed = (devc->speed * 2) / 3;
+
+ printk(KERN_WARNING "SoftOSS: Dropping sampling rate and stopping the device.\n");
+ softsynth_disabled = 1;
+ }
+ }
+ }
+ else
+ {
+ last_resample_jiffies = jif;
+ resample_counter = 0;
+ }
/* is_running = 1; */
if (dmap->qlen > devc->max_playahead)
- {
- printk("SoftOSS: audio buffers full\n");
- is_running = 0;
- restore_flags(flags);
- return;
- }
-/*
- * First verify that all active voices are valid (do this just once per block).
- */
+ {
+ printk(KERN_WARNING "SoftOSS: audio buffers full\n");
+ is_running = 0;
+ restore_flags(flags);
+ return;
+ }
+ /*
+ * First verify that all active voices are valid (do this just once per block).
+ */
+
for (voice = 0; voice < devc->maxvoice; voice++)
+ {
if (voice_active[voice])
- {
- int ptr;
-
- vinfo = &softoss_voices[voice];
- ptr = vinfo->ptr >> 9;
-
- if (vinfo->wave == NULL ||
- ptr < 0 ||
- ptr > vinfo->sample->len)
- init_voice(devc, voice);
- else if (!(vinfo->mode & WAVE_LOOPING) &&
- (vinfo->ptr + vinfo->step) > vinfo->endloop)
+ {
+ int ptr;
+
+ vinfo = &softoss_voices[voice];
+ ptr = vinfo->ptr >> 9;
+
+ if (vinfo->wave == NULL || ptr < 0 || ptr > vinfo->sample->len)
+ init_voice(devc, voice);
+ else if (!(vinfo->mode & WAVE_LOOPING) && (vinfo->ptr + vinfo->step) > vinfo->endloop)
voice_active[voice] = 0;
- }
-/*
- * Start the resampling process
- */
+ }
+ }
+
+ /*
+ * Start the resampling process
+ */
loops = devc->samples_per_fragment;
buf = (short *) (dmap->raw_buf + (dmap->qtail * dmap->fragment_size));
@@ -613,54 +609,51 @@ do_resample(int dummy)
devc->usecs += devc->usecs_per_frag;
if (tmr_running)
- {
- sound_timer_interrupt();
- }
-/*
- * Execute timer
- */
+ sound_timer_interrupt();
+ /*
+ * Execute timer
+ */
if (!tmr_running)
+ {
if (devc->usecs >= devc->next_event_usecs)
- {
- devc->next_event_usecs = ~0;
- sequencer_timer(0);
- }
+ {
+ devc->next_event_usecs = ~0;
+ sequencer_timer(0);
+ }
+ }
+
is_running = 0;
restore_flags(flags);
}
-static void
-delayed_resample(int dummy)
+static void delayed_resample(int dummy)
{
struct dma_buffparms *dmap = audio_devs[devc->audiodev]->dmap_out;
- int n = 0;
+ int n = 0;
if (is_running)
return;
- while (devc->engine_state != ES_STOPPED &&
- dmap->qlen < devc->max_playahead && n++ < 2)
+ while (devc->engine_state != ES_STOPPED && dmap->qlen < devc->max_playahead && n++ < 2)
do_resample(0);
intr_pending = 0;
}
#ifdef POLLED_MODE
-static void
-softsyn_poll(unsigned long dummy)
+static void softsyn_poll(unsigned long dummy)
{
delayed_resample(0);
if (devc->engine_state != ES_STOPPED)
-
- {
- poll_timer.expires = (1) + jiffies;
+ {
+ poll_timer.expires = jiffies+1;
add_timer(&poll_timer);
- };
+ }
}
+
#else
-static void
-softsyn_callback(int dev, int parm)
+static void softsyn_callback(int dev, int parm)
{
delayed_resample(0);
}
@@ -686,13 +679,14 @@ static void start_engine(softsyn_devc * devc)
devc->control_rate = 64;
devc->control_counter = 0;
- if (devc->engine_state == ES_STOPPED) {
+ if (devc->engine_state == ES_STOPPED)
+ {
n = trig = 0;
fs = get_fs();
set_fs(get_ds());
dma_ioctl(devc->audiodev, SNDCTL_DSP_SETTRIGGER, (caddr_t)&trig);
#ifdef POLLED_MODE
- poll_timer.expires = (1) + jiffies;
+ poll_timer.expires = jiffies+1;
add_timer(&poll_timer);
/* Start polling */
#else
@@ -711,13 +705,11 @@ static void start_engine(softsyn_devc * devc)
}
}
-static void
-stop_engine(softsyn_devc * devc)
+static void stop_engine(softsyn_devc * devc)
{
}
-static void
-request_engine(softsyn_devc * devc, int ticks)
+static void request_engine(softsyn_devc * devc, int ticks)
{
if (ticks < 0) /* Relative time */
devc->next_event_usecs = devc->usecs - ticks * (1000000 / HZ);
@@ -728,74 +720,72 @@ request_engine(softsyn_devc * devc, int ticks)
/*
* Softsync hook serves mode1 (timing) calls made by sequencer.c
*/
-static int
-softsynth_hook(int cmd, int parm1, int parm2, unsigned long parm3)
+
+static int softsynth_hook(int cmd, int parm1, int parm2, unsigned long parm3)
{
switch (cmd)
- {
- case SSYN_START:
- start_engine(devc);
- break;
+ {
+ case SSYN_START:
+ start_engine(devc);
+ break;
- case SSYN_STOP:
- stop_engine(devc);
- break;
+ case SSYN_STOP:
+ stop_engine(devc);
+ break;
- case SSYN_REQUEST:
- request_engine(devc, parm1);
- break;
+ case SSYN_REQUEST:
+ request_engine(devc, parm1);
+ break;
- case SSYN_GETTIME:
- return devc->usecs / (1000000 / HZ);
- break;
-
- default:
- printk("SoftOSS: Unknown request %d\n", cmd);
- }
+ case SSYN_GETTIME:
+ return devc->usecs / (1000000 / HZ);
+ break;
+ default:
+ printk(KERN_WARNING "SoftOSS: Unknown request %d\n", cmd);
+ }
return 0;
}
static int softsyn_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- switch (cmd) {
-
- case SNDCTL_SYNTH_INFO:
- softsyn_info.nr_voices = devc->maxvoice;
- if (__copy_to_user(arg, &softsyn_info, sizeof(softsyn_info)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- stop_engine(devc);
- reset_samples(devc);
- return 0;
+ switch (cmd)
+ {
+ case SNDCTL_SYNTH_INFO:
+ softsyn_info.nr_voices = devc->maxvoice;
+ if (copy_to_user(arg, &softsyn_info, sizeof(softsyn_info)))
+ return -EFAULT;
+ return 0;
+
+ case SNDCTL_SEQ_RESETSAMPLES:
+ stop_engine(devc);
+ reset_samples(devc);
+ return 0;
- case SNDCTL_SYNTH_MEMAVL:
- return devc->ram_size - devc->ram_used;
+ case SNDCTL_SYNTH_MEMAVL:
+ return devc->ram_size - devc->ram_used;
- default:
- return -EINVAL;
+ default:
+ return -EINVAL;
}
}
-static int
-softsyn_kill_note(int devno, int voice, int note, int velocity)
+static int softsyn_kill_note(int devno, int voice, int note, int velocity)
{
if (voice < 0 || voice > devc->maxvoice)
return 0;
voice_alloc->map[voice] = 0xffff; /* Releasing */
if (softoss_voices[voice].sustain_mode & 1) /* Sustain controller on */
- {
- softoss_voices[voice].sustain_mode = 3; /* Note off pending */
- return 0;
- }
+ {
+ softoss_voices[voice].sustain_mode = 3; /* Note off pending */
+ return 0;
+ }
if (velocity > 127 || softoss_voices[voice].mode & WAVE_FAST_RELEASE)
- {
- init_voice(devc, voice); /* Mark it inactive */
- return 0;
- }
+ {
+ init_voice(devc, voice); /* Mark it inactive */
+ return 0;
+ }
if (softoss_voices[voice].mode & WAVE_ENVELOPES)
step_envelope(voice, 1, velocity); /* Enter sustain phase */
else
@@ -803,29 +793,26 @@ softsyn_kill_note(int devno, int voice, int note, int velocity)
return 0;
}
-static int
-softsyn_set_instr(int dev, int voice, int instr)
+static int softsyn_set_instr(int dev, int voice, int instr)
{
if (voice < 0 || voice > devc->maxvoice)
return 0;
if (instr < 0 || instr > MAX_PATCH)
- {
- printk("SoftOSS: Invalid instrument number %d\n", instr);
- return 0;
- }
+ {
+ printk(KERN_ERR "SoftOSS: Invalid instrument number %d\n", instr);
+ return 0;
+ }
softoss_voices[voice].instr = instr;
-
return 0;
}
-static int
-softsyn_start_note(int dev, int voice, int note, int volume)
+static int softsyn_start_note(int dev, int voice, int note, int volume)
{
- int instr = 0;
- int best_sample, best_delta, delta_freq, selected;
- unsigned long note_freq, freq, base_note, flags;
- voice_info *v = &softoss_voices[voice];
+ int instr = 0;
+ int best_sample, best_delta, delta_freq, selected;
+ unsigned long note_freq, freq, base_note, flags;
+ voice_info *v = &softoss_voices[voice];
struct patch_info *sample;
@@ -839,32 +826,32 @@ softsyn_start_note(int dev, int voice, int note, int volume)
cli();
if (note == 255)
- { /* Just volume update */
- v->velocity = volume;
- if (voice_active[voice])
- update_volume(voice);
- restore_flags(flags);
- return 0;
- }
+ { /* Just volume update */
+ v->velocity = volume;
+ if (voice_active[voice])
+ update_volume(voice);
+ restore_flags(flags);
+ return 0;
+ }
voice_active[voice] = 0; /* Stop the voice for a while */
devc->vibratomap &= ~(1 << voice);
devc->tremolomap &= ~(1 << voice);
instr = v->instr;
if (instr < 0 || instr > MAX_PATCH || devc->programs[instr] == NO_SAMPLE)
- {
- printk("SoftOSS: Undefined MIDI instrument %d\n", instr);
- restore_flags(flags);
- return 0;
- }
+ {
+ printk(KERN_WARNING "SoftOSS: Undefined MIDI instrument %d\n", instr);
+ restore_flags(flags);
+ return 0;
+ }
instr = devc->programs[instr];
if (instr < 0 || instr >= devc->nrsamples)
- {
- printk("SoftOSS: Corrupted MIDI instrument %d (%d)\n", v->instr, instr);
- restore_flags(flags);
- return 0;
- }
+ {
+ printk(KERN_WARNING "SoftOSS: Corrupted MIDI instrument %d (%d)\n", v->instr, instr);
+ restore_flags(flags);
+ return 0;
+ }
note_freq = note_to_freq(note);
selected = -1;
@@ -873,25 +860,26 @@ softsyn_start_note(int dev, int voice, int note, int volume)
best_delta = 1000000;
while (instr != NO_SAMPLE && instr >= 0 && selected == -1)
- {
- delta_freq = note_freq - devc->samples[instr]->base_note;
-
- if (delta_freq < 0)
- delta_freq = -delta_freq;
- if (delta_freq < best_delta)
- {
- best_sample = instr;
- best_delta = delta_freq;
- }
- if (devc->samples[instr]->low_note <= note_freq &&
- note_freq <= devc->samples[instr]->high_note)
- selected = instr;
- else
- instr = devc->samples[instr]->key; /* Link to next sample */
-
- if (instr < 0 || instr >= devc->nrsamples)
- instr = NO_SAMPLE;
- }
+ {
+ delta_freq = note_freq - devc->samples[instr]->base_note;
+
+ if (delta_freq < 0)
+ delta_freq = -delta_freq;
+ if (delta_freq < best_delta)
+ {
+ best_sample = instr;
+ best_delta = delta_freq;
+ }
+ if (devc->samples[instr]->low_note <= note_freq &&
+ note_freq <= devc->samples[instr]->high_note)
+ {
+ selected = instr;
+ }
+ else instr = devc->samples[instr]->key; /* Link to next sample */
+
+ if (instr < 0 || instr >= devc->nrsamples)
+ instr = NO_SAMPLE;
+ }
if (selected == -1)
instr = best_sample;
@@ -899,37 +887,33 @@ softsyn_start_note(int dev, int voice, int note, int volume)
instr = selected;
if (instr < 0 || instr == NO_SAMPLE || instr > devc->nrsamples)
- {
- printk("SoftOSS: Unresolved MIDI instrument %d\n", v->instr);
- restore_flags(flags);
- return 0;
- }
+ {
+ printk(KERN_WARNING "SoftOSS: Unresolved MIDI instrument %d\n", v->instr);
+ restore_flags(flags);
+ return 0;
+ }
sample = devc->samples[instr];
v->sample = sample;
if (v->percussive_voice) /* No key tracking */
- {
v->orig_freq = sample->base_freq; /* Fixed pitch */
- } else
- {
- base_note = sample->base_note / 100;
- note_freq /= 100;
+ else
+ {
+ base_note = sample->base_note / 100;
+ note_freq /= 100;
- freq = sample->base_freq * note_freq / base_note;
- v->orig_freq = freq;
- }
+ freq = sample->base_freq * note_freq / base_note;
+ v->orig_freq = freq;
+ }
if (!(sample->mode & WAVE_LOOPING))
- {
- sample->loop_end = sample->len;
- }
- v->wave = devc->wave[instr];
+ sample->loop_end = sample->len;
+ v->wave = devc->wave[instr];
if (volume < 0)
volume = 0;
else if (volume > 127)
volume = 127;
-
v->ptr = 0;
v->startloop = sample->loop_start * 512;
v->startbackloop = 0;
@@ -954,40 +938,39 @@ softsyn_start_note(int dev, int voice, int note, int volume)
if (!(v->mode & WAVE_LOOPING))
v->mode &= ~(WAVE_BIDIR_LOOP | WAVE_LOOP_BACK);
else if (v->mode & WAVE_LOOP_BACK)
- {
- v->ptr = sample->len;
- v->startbackloop = v->startloop;
- }
+ {
+ v->ptr = sample->len;
+ v->startbackloop = v->startloop;
+ }
if (v->mode & WAVE_VIBRATO)
- {
- v->vibrato_rate = sample->vibrato_rate;
- v->vibrato_depth = sample->vibrato_depth;
- }
+ {
+ v->vibrato_rate = sample->vibrato_rate;
+ v->vibrato_depth = sample->vibrato_depth;
+ }
if (v->mode & WAVE_TREMOLO)
- {
- v->tremolo_rate = sample->tremolo_rate;
- v->tremolo_depth = sample->tremolo_depth;
- }
+ {
+ v->tremolo_rate = sample->tremolo_rate;
+ v->tremolo_depth = sample->tremolo_depth;
+ }
if (v->mode & WAVE_ENVELOPES)
- {
- v->envelope_phase = -1;
- v->envelope_vol = 0;
- step_envelope(voice, 0, 60);
- }
+ {
+ v->envelope_phase = -1;
+ v->envelope_vol = 0;
+ step_envelope(voice, 0, 60);
+ }
update_volume(voice);
compute_step(voice);
voice_active[voice] = 1; /* Mark it active */
-
restore_flags(flags);
return 0;
}
static int softsyn_open(int synthdev, int mode)
{
- int err;
- extern int softoss_dev;
- int frags = 0x7fff0007; /* fragment size of 128 bytes */
+ int err;
+ extern int softoss_dev;
+ int frags = 0x7fff0007; /* fragment size of 128 bytes */
mm_segment_t fs;
if (devc->audio_opened) /* Already opened */
@@ -1007,10 +990,10 @@ static int softsyn_open(int synthdev, int mode)
devc->audiodev = softoss_dev;
if (!(audio_devs[devc->audiodev]->format_mask & AFMT_S16_LE))
- {
- printk("SoftOSS: The audio device doesn't support 16 bits\n");
- return -ENXIO;
- }
+ {
+/* printk(KERN_ERR "SoftOSS: The audio device doesn't support 16 bits\n"); */
+ return -ENXIO;
+ }
if ((err = audio_open((devc->audiodev << 4) | SND_DEV_DSP16, &devc->finfo)) < 0)
return err;
@@ -1023,7 +1006,6 @@ static int softsyn_open(int synthdev, int mode)
DDB(printk("SoftOSS: Using audio dev %d, speed %d, bits %d, channels %d\n", devc->audiodev, devc->speed, devc->bits, devc->channels));
-
fs = get_fs();
set_fs(get_ds());
dma_ioctl(devc->audiodev, SNDCTL_DSP_SETFRAGMENT, (caddr_t) & frags);
@@ -1031,11 +1013,11 @@ static int softsyn_open(int synthdev, int mode)
set_fs(fs);
if (devc->bits != 16 || devc->channels != 2)
- {
- audio_release((devc->audiodev << 4) | SND_DEV_DSP16, &devc->finfo);
- printk("SoftOSS: A 16 bit stereo soundcard is required\n");
- return 0;
- }
+ {
+ audio_release((devc->audiodev << 4) | SND_DEV_DSP16, &devc->finfo);
+/* printk("SoftOSS: A 16 bit stereo soundcard is required\n");*/
+ return -EINVAL;
+ }
if (devc->max_playahead >= audio_devs[devc->audiodev]->dmap_out->nbufs)
devc->max_playahead = audio_devs[devc->audiodev]->dmap_out->nbufs;
@@ -1064,12 +1046,11 @@ static void softsyn_close(int synthdev)
devc->audio_opened = 0;
}
-static void
-softsyn_hw_control(int dev, unsigned char *event_rec)
+static void softsyn_hw_control(int dev, unsigned char *event_rec)
{
- int voice, cmd;
- unsigned short p1, p2;
- unsigned int plong;
+ int voice, cmd;
+ unsigned short p1, p2;
+ unsigned int plong;
cmd = event_rec[2];
voice = event_rec[3];
@@ -1078,48 +1059,47 @@ softsyn_hw_control(int dev, unsigned char *event_rec)
plong = *(unsigned int *) &event_rec[4];
switch (cmd)
- {
-
- case _GUS_NUMVOICES:
- set_max_voices(p1);
- break;
+ {
+ case _GUS_NUMVOICES:
+ set_max_voices(p1);
+ break;
- default:;
- }
+ default:;
+ }
}
-static int
-softsyn_load_patch(int dev, int format, const char *addr,
+static int softsyn_load_patch(int dev, int format, const char *addr,
int offs, int count, int pmgr_flag)
{
struct patch_info *patch = NULL;
- int i, p, instr;
- long sizeof_patch;
- int memlen, adj;
+ int i, p, instr;
+ long sizeof_patch;
+ int memlen, adj;
unsigned short data;
- short *wave = NULL;
+ short *wave = NULL;
sizeof_patch = (long) &patch->data[0] - (long) patch; /* Header size */
if (format != GUS_PATCH)
- {
- printk("SoftOSS: Invalid patch format (key) 0x%x\n", format);
- return -EINVAL;
- }
+ {
+/* printk(KERN_ERR "SoftOSS: Invalid patch format (key) 0x%x\n", format);*/
+ return -EINVAL;
+ }
if (count < sizeof_patch)
- {
- printk("SoftOSS: Patch header too short\n");
- return -EINVAL;
- }
+ {
+/* printk(KERN_ERR "SoftOSS: Patch header too short\n");*/
+ return -EINVAL;
+ }
count -= sizeof_patch;
if (devc->nrsamples >= MAX_SAMPLE)
- {
- printk("SoftOSS: Sample table full\n");
- return -ENOSPC;
- }
+ {
+/* printk(KERN_ERR "SoftOSS: Sample table full\n");*/
+ return -ENOBUFS;
+ }
+
/*
* Copy the header from user space but ignore the first bytes which have
* been transferred already.
@@ -1128,54 +1108,55 @@ softsyn_load_patch(int dev, int format, const char *addr,
patch = vmalloc(sizeof(*patch));
if (patch == NULL)
- {
- printk("SoftOSS: Out of memory\n");
- return -ENOSPC;
- }
- copy_from_user(&((char *) patch)[offs], &(addr)[offs], sizeof_patch - offs);
+ {
+/* printk(KERN_ERR "SoftOSS: Out of memory\n");*/
+ return -ENOMEM;
+ }
+ if(copy_from_user(&((char *) patch)[offs], &(addr)[offs], sizeof_patch - offs))
+ return -EFAULT;
if (patch->mode & WAVE_ROM)
- {
- vfree(patch);
- return -EINVAL;
- }
+ {
+ vfree(patch);
+ return -EINVAL;
+ }
instr = patch->instr_no;
if (instr < 0 || instr > MAX_PATCH)
- {
- printk("SoftOSS: Invalid patch number %d\n", instr);
- vfree(patch);
- return -EINVAL;
- }
+ {
+/* printk(KERN_ERR "SoftOSS: Invalid patch number %d\n", instr);*/
+ vfree(patch);
+ return -EINVAL;
+ }
if (count < patch->len)
- {
- printk("SoftOSS: Patch record too short (%d<%d)\n", count, (int) patch->len);
- patch->len = count;
- }
+ {
+/* printk(KERN_ERR "SoftOSS: Patch record too short (%d<%d)\n", count, (int) patch->len);*/
+ patch->len = count;
+ }
if (patch->len <= 0 || patch->len > (devc->ram_size - devc->ram_used))
- {
- printk("SoftOSS: Invalid sample length %d\n", (int) patch->len);
- vfree(patch);
- return -EINVAL;
- }
+ {
+/* printk(KERN_ERR "SoftOSS: Invalid sample length %d\n", (int) patch->len); */
+ vfree(patch);
+ return -EINVAL;
+ }
if (patch->mode & WAVE_LOOPING)
- {
- if (patch->loop_start < 0 || patch->loop_start >= patch->len)
- {
- printk("SoftOSS: Invalid loop start %d\n", patch->loop_start);
- vfree(patch);
- return -EINVAL;
- }
- if (patch->loop_end < patch->loop_start || patch->loop_end > patch->len)
- {
- printk("SoftOSS: Invalid loop start or end point (%d, %d)\n", patch->loop_start, patch->loop_end);
- vfree(patch);
- return -EINVAL;
- }
- }
-/*
- * Next load the wave data to memory
- */
+ {
+ if (patch->loop_start < 0 || patch->loop_start >= patch->len)
+ {
+/* printk(KERN_ERR "SoftOSS: Invalid loop start %d\n", patch->loop_start);*/
+ vfree(patch);
+ return -EINVAL;
+ }
+ if (patch->loop_end < patch->loop_start || patch->loop_end > patch->len)
+ {
+/* printk(KERN_ERR "SoftOSS: Invalid loop start or end point (%d, %d)\n", patch->loop_start, patch->loop_end);*/
+ vfree(patch);
+ return -EINVAL;
+ }
+ }
+ /*
+ * Next load the wave data to memory
+ */
memlen = patch->len;
adj = 1;
@@ -1188,48 +1169,47 @@ softsyn_load_patch(int dev, int format, const char *addr,
wave = vmalloc(memlen);
if (wave == NULL)
- {
- printk("SoftOSS: Can't allocate %d bytes of mem for a sample\n", memlen);
- vfree(patch);
- return -ENOSPC;
- }
+ {
+/* printk(KERN_ERR "SoftOSS: Can't allocate %d bytes of mem for a sample\n", memlen);*/
+ vfree(patch);
+ return -ENOMEM;
+ }
p = 0;
for (i = 0; i < memlen / 2; i++) /* Handle words */
- {
- unsigned char tmp;
-
- data = 0;
-
- if (patch->mode & WAVE_16_BITS)
- {
- get_user(*(unsigned char *) &tmp, (unsigned char *) &((addr)[sizeof_patch + p++])); /* Get lsb */
- data = tmp;
- get_user(*(unsigned char *) &tmp, (unsigned char *) &((addr)[sizeof_patch + p++])); /* Get msb */
- if (patch->mode & WAVE_UNSIGNED)
- tmp ^= 0x80; /* Convert to signed */
- data |= (tmp << 8);
- } else
- {
- get_user(*(unsigned char *) &tmp, (unsigned char *) &((addr)[sizeof_patch + p++]));
- if (patch->mode & WAVE_UNSIGNED)
- tmp ^= 0x80; /* Convert to signed */
+ {
+ unsigned char tmp;
+ data = 0;
+ if (patch->mode & WAVE_16_BITS)
+ {
+ get_user(*(unsigned char *) &tmp, (unsigned char *) &((addr)[sizeof_patch + p++])); /* Get lsb */
+ data = tmp;
+ get_user(*(unsigned char *) &tmp, (unsigned char *) &((addr)[sizeof_patch + p++])); /* Get msb */
+ if (patch->mode & WAVE_UNSIGNED)
+ tmp ^= 0x80; /* Convert to signed */
+ data |= (tmp << 8);
+ }
+ else
+ {
+ get_user(*(unsigned char *) &tmp, (unsigned char *) &((addr)[sizeof_patch + p++]));
+ if (patch->mode & WAVE_UNSIGNED)
+ tmp ^= 0x80; /* Convert to signed */
data = (tmp << 8); /* Convert to 16 bits */
- }
-
- wave[i] = (short) data;
- }
+ }
+ wave[i] = (short) data;
+ }
devc->ram_used += patch->len;
-/*
- * Convert pointers to 16 bit indexes
- */
+
+ /*
+ * Convert pointers to 16 bit indexes
+ */
patch->len /= adj;
patch->loop_start /= adj;
patch->loop_end /= adj;
-/*
- * Finally link the loaded patch to the chain
- */
+ /*
+ * Finally link the loaded patch to the chain
+ */
patch->key = devc->programs[instr];
devc->programs[instr] = devc->nrsamples;
@@ -1239,8 +1219,7 @@ softsyn_load_patch(int dev, int format, const char *addr,
return 0;
}
-static void
-softsyn_panning(int dev, int voice, int pan)
+static void softsyn_panning(int dev, int voice, int pan)
{
if (voice < 0 || voice > devc->maxvoice)
return;
@@ -1255,13 +1234,11 @@ softsyn_panning(int dev, int voice, int pan)
update_volume(voice);
}
-static void
-softsyn_volume_method(int dev, int mode)
+static void softsyn_volume_method(int dev, int mode)
{
}
-static void
-softsyn_aftertouch(int dev, int voice, int pressure)
+static void softsyn_aftertouch(int dev, int voice, int pressure)
{
if (voice < 0 || voice > devc->maxvoice)
return;
@@ -1270,10 +1247,9 @@ softsyn_aftertouch(int dev, int voice, int pressure)
update_volume(voice);
}
-static void
-softsyn_controller(int dev, int voice, int ctrl_num, int value)
+static void softsyn_controller(int dev, int voice, int ctrl_num, int value)
{
- unsigned long flags;
+ unsigned long flags;
if (voice < 0 || voice > devc->maxvoice)
return;
@@ -1281,48 +1257,46 @@ softsyn_controller(int dev, int voice, int ctrl_num, int value)
cli();
switch (ctrl_num)
- {
- case CTRL_PITCH_BENDER:
- softoss_voices[voice].bender = value;
-
- if (voice_active[voice])
- compute_step(voice); /* Update pitch */
- break;
-
-
- case CTRL_PITCH_BENDER_RANGE:
- softoss_voices[voice].bender_range = value;
- break;
- case CTL_EXPRESSION:
- value /= 128;
- case CTRL_EXPRESSION:
- softoss_voices[voice].expression_vol = value;
- if (voice_active[voice])
- update_volume(voice);
- break;
-
- case CTL_PAN:
- softsyn_panning(dev, voice, (value * 2) - 128);
- break;
-
- case CTL_MAIN_VOLUME:
- value = (value * 100) / 16383;
-
- case CTRL_MAIN_VOLUME:
- softoss_voices[voice].main_vol = value;
- if (voice_active[voice])
- update_volume(voice);
- break;
-
- default:
- break;
- }
-
+ {
+ case CTRL_PITCH_BENDER:
+ softoss_voices[voice].bender = value;
+ if (voice_active[voice])
+ compute_step(voice); /* Update pitch */
+ break;
+
+
+ case CTRL_PITCH_BENDER_RANGE:
+ softoss_voices[voice].bender_range = value;
+ break;
+
+ case CTL_EXPRESSION:
+ value /= 128;
+ case CTRL_EXPRESSION:
+ softoss_voices[voice].expression_vol = value;
+ if (voice_active[voice])
+ update_volume(voice);
+ break;
+
+ case CTL_PAN:
+ softsyn_panning(dev, voice, (value * 2) - 128);
+ break;
+
+ case CTL_MAIN_VOLUME:
+ value = (value * 100) / 16383;
+
+ case CTRL_MAIN_VOLUME:
+ softoss_voices[voice].main_vol = value;
+ if (voice_active[voice])
+ update_volume(voice);
+ break;
+
+ default:
+ break;
+ }
restore_flags(flags);
}
-static void
-softsyn_bender(int dev, int voice, int value)
+static void softsyn_bender(int dev, int voice, int value)
{
if (voice < 0 || voice > devc->maxvoice)
return;
@@ -1332,46 +1306,46 @@ softsyn_bender(int dev, int voice, int value)
compute_step(voice); /* Update pitch */
}
-static int
-softsyn_alloc_voice(int dev, int chn, int note, struct voice_alloc_info *alloc)
+static int softsyn_alloc_voice(int dev, int chn, int note, struct voice_alloc_info *alloc)
{
- int i, p, best = -1, best_time = 0x7fffffff;
+ int i, p, best = -1, best_time = 0x7fffffff;
p = alloc->ptr;
+
/*
- * First look for a completely stopped voice
+ * First look for a completely stopped voice
*/
for (i = 0; i < alloc->max_voice; i++)
- {
- if (alloc->map[p] == 0)
- {
- alloc->ptr = p;
- voice_active[p] = 0;
- return p;
- }
- if (alloc->alloc_times[p] < best_time)
- {
- best = p;
- best_time = alloc->alloc_times[p];
- }
- p = (p + 1) % alloc->max_voice;
- }
+ {
+ if (alloc->map[p] == 0)
+ {
+ alloc->ptr = p;
+ voice_active[p] = 0;
+ return p;
+ }
+ if (alloc->alloc_times[p] < best_time)
+ {
+ best = p;
+ best_time = alloc->alloc_times[p];
+ }
+ p = (p + 1) % alloc->max_voice;
+ }
/*
- * Then look for a releasing voice
+ * Then look for a releasing voice
*/
for (i = 0; i < alloc->max_voice; i++)
- {
- if (alloc->map[p] == 0xffff)
- {
- alloc->ptr = p;
- voice_active[p] = 0;
- return p;
- }
- p = (p + 1) % alloc->max_voice;
- }
+ {
+ if (alloc->map[p] == 0xffff)
+ {
+ alloc->ptr = p;
+ voice_active[p] = 0;
+ return p;
+ }
+ p = (p + 1) % alloc->max_voice;
+ }
if (best >= 0)
p = best;
@@ -1381,23 +1355,20 @@ softsyn_alloc_voice(int dev, int chn, int note, struct voice_alloc_info *alloc)
return p;
}
-static void
-softsyn_setup_voice(int dev, int voice, int chn)
+static void softsyn_setup_voice(int dev, int voice, int chn)
{
- unsigned long flags;
+ unsigned long flags;
- struct channel_info *info =
- &synth_devs[dev]->chn_info[chn];
+ struct channel_info *info = &synth_devs[dev]->chn_info[chn];
save_flags(flags);
cli();
+
/* init_voice(devc, voice); */
softsyn_set_instr(dev, voice, info->pgm_num);
- softoss_voices[voice].expression_vol =
- info->controllers[CTL_EXPRESSION]; /* Just MSB */
- softoss_voices[voice].main_vol =
- (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
+ softoss_voices[voice].expression_vol = info->controllers[CTL_EXPRESSION]; /* Just MSB */
+ softoss_voices[voice].main_vol = (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
softsyn_panning(dev, voice, (info->controllers[CTL_PAN] * 2) - 128);
softoss_voices[voice].bender = 0; /* info->bender_value; */
softoss_voices[voice].bender_range = info->bender_range;
@@ -1407,11 +1378,10 @@ softsyn_setup_voice(int dev, int voice, int chn)
restore_flags(flags);
}
-static void
-softsyn_reset(int devno)
+static void softsyn_reset(int devno)
{
- int i;
- unsigned long flags;
+ int i;
+ unsigned long flags;
save_flags(flags);
cli();
@@ -1450,23 +1420,20 @@ static struct synth_operations softsyn_operations =
* Timer stuff (for /dev/music).
*/
-static unsigned int
-soft_tmr_start(int dev, unsigned int usecs)
+static unsigned int soft_tmr_start(int dev, unsigned int usecs)
{
tmr_running = 1;
start_engine(devc);
return devc->usecs_per_frag;
}
-static void
-soft_tmr_disable(int dev)
+static void soft_tmr_disable(int dev)
{
stop_engine(devc);
tmr_running = 0;
}
-static void
-soft_tmr_restart(int dev)
+static void soft_tmr_restart(int dev)
{
tmr_running = 1;
}
@@ -1480,10 +1447,9 @@ static struct sound_lowlev_timer soft_tmr =
soft_tmr_restart
};
-int
-probe_softsyn(struct address_info *hw_config)
+int probe_softsyn(struct address_info *hw_config)
{
- int i;
+ int i;
if (softsynth_loaded)
return 0;
@@ -1492,10 +1458,10 @@ probe_softsyn(struct address_info *hw_config)
devc->ram_used = 0;
devc->nrsamples = 0;
for (i = 0; i < MAX_PATCH; i++)
- {
- devc->programs[i] = NO_SAMPLE;
- devc->wave[i] = NULL;
- }
+ {
+ devc->programs[i] = NO_SAMPLE;
+ devc->wave[i] = NULL;
+ }
devc->maxvoice = DEFAULT_VOICES;
@@ -1516,15 +1482,12 @@ probe_softsyn(struct address_info *hw_config)
#else
devc->default_max_voices = 32;
#endif
-
softsynth_loaded = 1;
return 1;
}
-void
-attach_softsyn_card(struct address_info *hw_config)
+void attach_softsyn_card(struct address_info *hw_config)
{
-
voice_alloc = &softsyn_operations.alloc;
synth_devs[devc->synthdev = num_synths++] = &softsyn_operations;
sequencer_init();
@@ -1536,14 +1499,10 @@ attach_softsyn_card(struct address_info *hw_config)
#endif
}
-void
-unload_softsyn(struct address_info *hw_config)
+void unload_softsyn(struct address_info *hw_config)
{
if (!softsynth_loaded)
return;
-#ifndef POLLED_MODE
-#endif
-
softsynthp = NULL;
softsynth_loaded = 0;
reset_samples(devc);
@@ -1553,10 +1512,9 @@ unload_softsyn(struct address_info *hw_config)
static struct address_info config;
-int
-init_module(void)
+int init_module(void)
{
- printk("SoftOSS driver Copyright (C) by Hannu Savolainen 1993-1997\n");
+ printk(KERN_INFO "SoftOSS driver Copyright (C) by Hannu Savolainen 1993-1997\n");
if (!probe_softsyn(&config))
return -ENODEV;
attach_softsyn_card(&config);
@@ -1564,8 +1522,7 @@ init_module(void)
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
unload_softsyn(&config);
sound_unload_synthdev(devc->synthdev);
diff --git a/drivers/sound/softoss_rs.c b/drivers/sound/softoss_rs.c
index f8dac8ed5..17ebb8b59 100644
--- a/drivers/sound/softoss_rs.c
+++ b/drivers/sound/softoss_rs.c
@@ -5,8 +5,8 @@
* Software based MIDI synthsesizer driver, the actual mixing loop.
* Keep the loop as simple as possible to make it easier to rewrite this
* routine in assembly.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -21,10 +21,9 @@
#if defined(CONFIG_SOFTOSS) || defined(MODULE)
#include "softoss.h"
-void
-softsynth_resample_loop(short *buf, int loops)
+void softsynth_resample_loop(short *buf, int loops)
{
- int iloop, voice;
+ int iloop, voice;
volatile voice_info *v;
#ifdef OSS_BIG_ENDIAN
@@ -33,104 +32,102 @@ softsynth_resample_loop(short *buf, int loops)
#endif
for (iloop = 0; iloop < loops; iloop++)
- { /* Mix one sample */
-
- int accum, left = 0, right = 0;
- int ix, position;
-
- for (voice = 0; voice < devc->maxvoice; voice++)
- if (voice_active[voice])
- { /* Compute voice */
-
- v = &softoss_voices[voice];
+ { /* Mix one sample */
+ int accum, left = 0, right = 0;
+ int ix, position;
+
+ for (voice = 0; voice < devc->maxvoice; voice++)
+ {
+ if (voice_active[voice])
+ { /* Compute voice */
+ v = &softoss_voices[voice];
#ifdef SOFTOSS_TEST
- ix = iloop << 3;
- position = v->ptr;
+ ix = iloop << 3;
+ position = v->ptr;
#else
- ix = (position = v->ptr) >> 9;
+ ix = (position = v->ptr) >> 9;
#endif
- /* Interpolation (resolution of 512 steps) */
- {
- int fract = v->ptr & 0x1f; /* 9 bits */
-
- /* This method works with less arithmetic operations */
- register int v1 = v->wave[ix];
-
- accum = v1 + ((((v->wave[ix + 1] - v1)) * (fract)) >> 9);
- }
-
- left += (accum * v->leftvol);
- right += (accum * v->rightvol);
-
- /* Update sample pointer */
-
- position += v->step;
- if (position <= v->endloop)
- v->ptr = position;
- else if (v->mode & WAVE_LOOPING)
- {
- if (v->mode & WAVE_BIDIR_LOOP)
- {
- v->mode ^= WAVE_LOOP_BACK; /* Turn around */
- v->step *= -1;
- } else
- {
- position -= v->looplen;
- v->ptr = position;
- }
- }
- /* else leave the voice looping the current sample */
-
- if (v->mode & WAVE_LOOP_BACK && position < v->startloop)
- {
- if (v->mode & WAVE_BIDIR_LOOP)
- {
- v->mode ^= WAVE_LOOP_BACK; /* Turn around */
- v->step *= -1;
- } else
- {
- position += v->looplen;
- v->ptr = position;
- }
- }
- } /* Compute voice */
+ /* Interpolation (resolution of 512 steps) */
+ {
+ int fract = v->ptr & 0x1f; /* 9 bits */
+
+ /* This method works with less arithmetic operations */
+ register int v1 = v->wave[ix];
+ accum = v1 + ((((v->wave[ix + 1] - v1)) * (fract)) >> 9);
+ }
+
+ left += (accum * v->leftvol);
+ right += (accum * v->rightvol);
+
+ /* Update sample pointer */
+ position += v->step;
+ if (position <= v->endloop)
+ v->ptr = position;
+ else if (v->mode & WAVE_LOOPING)
+ {
+ if (v->mode & WAVE_BIDIR_LOOP)
+ { v->mode ^= WAVE_LOOP_BACK; /* Turn around */
+ v->step *= -1;
+ }
+ else
+ {
+ position -= v->looplen;
+ v->ptr = position;
+ }
+ }
+ /* else leave the voice looping the current sample */
+
+ if (v->mode & WAVE_LOOP_BACK && position < v->startloop)
+ {
+ if (v->mode & WAVE_BIDIR_LOOP)
+ { v->mode ^= WAVE_LOOP_BACK; /* Turn around */
+ v->step *= -1;
+ }
+ else
+ {
+ position += v->looplen;
+ v->ptr = position;
+ }
+ }
+ } /* Compute voice */
+ }
#if 1 /* Delay */
- left += left_delay[delayp];
- right += right_delay[delayp];
+ left += left_delay[delayp];
+ right += right_delay[delayp];
- left_delay[delayp] = right >> 2;
- right_delay[delayp] = left >> 2;
- delayp = (delayp + 1) % devc->delay_size;
+ left_delay[delayp] = right >> 2;
+ right_delay[delayp] = left >> 2;
+ delayp = (delayp + 1) % devc->delay_size;
#endif
#define AFTERSCALE devc->afterscale;
- left >>= AFTERSCALE;
- right >>= AFTERSCALE;
+ left >>= AFTERSCALE;
+ right >>= AFTERSCALE;
- if (left > 32767)
- left = 32767;
- if (left < -32768)
- left = -32768;
- if (right > 32767)
- right = 32767;
- if (right < -32768)
- right = -32768;
+ if (left > 32767)
+ left = 32767;
+ if (left < -32768)
+ left = -32768;
+ if (right > 32767)
+ right = 32767;
+ if (right < -32768)
+ right = -32768;
#ifdef OSS_BIG_ENDIAN
- *cbuf++ = left & 0xff;
- *cbuf++ = (left >> 8) & 0xff;
- *cbuf++ = right & 0xff;
- *cbuf++ = (right >> 8) & 0xff;
+ *cbuf++ = left & 0xff;
+ *cbuf++ = (left >> 8) & 0xff;
+ *cbuf++ = right & 0xff;
+ *cbuf++ = (right >> 8) & 0xff;
#else
- *buf++ = left;
- *buf++ = right;
+ *buf++ = left;
+ *buf++ = right;
#endif
- if (devc->control_counter++ >= devc->control_rate)
- {
- devc->control_counter = 0;
- softsyn_control_loop();
- }
- } /* Mix one sample */
+ if (devc->control_counter++ >= devc->control_rate)
+ {
+ devc->control_counter = 0;
+ softsyn_control_loop();
+ }
+ } /* Mix one sample */
}
#endif
diff --git a/drivers/sound/sound_calls.h b/drivers/sound/sound_calls.h
index 416737f65..2a95950e5 100644
--- a/drivers/sound/sound_calls.h
+++ b/drivers/sound/sound_calls.h
@@ -11,6 +11,7 @@ int DMAbuf_start_output(int dev, int buff_no, int l);
int DMAbuf_move_wrpointer(int dev, int l);
/* int DMAbuf_ioctl(int dev, unsigned int cmd, caddr_t arg, int local); */
void DMAbuf_init(int dev, int dma1, int dma2);
+void DMAbuf_deinit(int dev);
int DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode);
int DMAbuf_open_dma (int dev);
void DMAbuf_close_dma (int dev);
@@ -83,15 +84,8 @@ void MIDIbuf_init(void);
/* From soundcard.c */
void request_sound_timer (int count);
void sound_stop_timer(void);
-/* These two are about to die.. */
-int snd_set_irq_handler (int interrupt_level, void(*iproc)(int, void*, struct pt_regs *), char *name, int *osp, void *dev_id);
-void snd_release_irq(int vect, void *ptr);
-void sound_dma_malloc(int dev);
-void sound_dma_free(int dev);
void conf_printf(char *name, struct address_info *hw_config);
void conf_printf2(char *name, int base, int irq, int dma, int dma2);
-int ioctl_in(caddr_t arg);
-int ioctl_out(caddr_t arg, int result);
/* From opl3.c */
int opl3_detect (int ioaddr, int *osp);
@@ -187,7 +181,7 @@ int ad1848_detect (int io_base, int *flags, int *osp);
#define AD_F_CS4231 0x0001 /* Returned if a CS4232 (or compatible) detected */
#define AD_F_CS4248 0x0001 /* Returned if a CS4248 (or compatible) detected */
-void ad1848_control(int cmd, int arg);
+int ad1848_control(int cmd, int arg);
#define AD1848_SET_XTAL 1
#define AD1848_MIXER_REROUTE 2
#define AD1848_REROUTE(oldctl, newctl) \
@@ -196,9 +190,6 @@ void ad1848_control(int cmd, int arg);
void adintr(int irq, void *dev_id, struct pt_regs * dummy);
void attach_ms_sound(struct address_info * hw_config);
int probe_ms_sound(struct address_info *hw_config);
-void attach_pnp_ad1848(struct address_info * hw_config);
-int probe_pnp_ad1848(struct address_info *hw_config);
-void unload_pnp_ad1848(struct address_info *hw_info);
/* From pss.c */
int probe_pss (struct address_info *hw_config);
@@ -235,7 +226,6 @@ void attach_mad16 (struct address_info *hw_config);
int probe_mad16 (struct address_info *hw_config);
void attach_mad16_mpu (struct address_info *hw_config);
int probe_mad16_mpu (struct address_info *hw_config);
-int mad16_sb_dsp_detect (struct address_info *hw_config);
/* Unload routines from various source files*/
void unload_pss(struct address_info *hw_info);
@@ -278,3 +268,7 @@ void attach_v_midi (struct address_info *hw_config);
int probe_v_midi (struct address_info *hw_config);
void unload_v_midi (struct address_info *hw_config);
+/* From vidc.c */
+void attach_vidc(struct address_info *hw_config);
+int probe_vidc(struct address_info *hw_config);
+void unload_vidc(struct address_info *hw_config);
diff --git a/drivers/sound/sound_firmware.c b/drivers/sound/sound_firmware.c
index cc566e497..97ce9d657 100644
--- a/drivers/sound/sound_firmware.c
+++ b/drivers/sound/sound_firmware.c
@@ -1,3 +1,4 @@
+#include "os.h"
#define __KERNEL_SYSCALLS__
#include <linux/fs.h>
#include <linux/mm.h>
@@ -19,14 +20,14 @@ static int do_mod_firmware_load(const char *fn, char **fp)
return 0;
}
l = lseek(fd, 0L, 2);
- if (l <= 0 || l > 65535)
+ if (l <= 0 || l > 131072)
{
printk(KERN_INFO "Invalid firmware '%s'\n", fn);
sys_close(fd);
- return 0;
+ return 0;
}
lseek(fd, 0L, 0);
- dp = kmalloc(l, GFP_KERNEL);
+ dp = vmalloc(l);
if (dp == NULL)
{
printk(KERN_INFO "Out of memory loading '%s'.\n", fn);
@@ -36,7 +37,7 @@ static int do_mod_firmware_load(const char *fn, char **fp)
if (read(fd, dp, l) != l)
{
printk(KERN_INFO "Failed to read '%s'.\n", fn);
- kfree(dp);
+ vfree(dp);
sys_close(fd);
return 0;
}
@@ -45,7 +46,7 @@ static int do_mod_firmware_load(const char *fn, char **fp)
return (int) l;
}
-int mod_firmware_load(const char *fn, char **fp)
+int mod_firmware_load(const char *fn, char **fp)
{
int r;
mm_segment_t fs = get_fs();
@@ -55,3 +56,4 @@ int mod_firmware_load(const char *fn, char **fp)
set_fs(fs);
return r;
}
+
diff --git a/drivers/sound/sound_syms.c b/drivers/sound/sound_syms.c
index 648a769a4..2758660d5 100644
--- a/drivers/sound/sound_syms.c
+++ b/drivers/sound/sound_syms.c
@@ -1,6 +1,6 @@
/*
- * The sound core exports the following symbols to the rest of
- * modulespace.
+ * The sound core exports the following symbols to the rest of
+ * modulespace.
*
* (C) Copyright 1997 Alan Cox, Licensed under the GNU GPL
*/
@@ -9,6 +9,8 @@
#include "sound_config.h"
#define _MIDI_SYNTH_C_
#include "midi_synth.h"
+#define _SEQUENCER_C_
+#include "tuning.h"
#include <linux/notifier.h>
#include "sound_firmware.h"
@@ -31,16 +33,13 @@ EXPORT_SYMBOL(sound_install_audiodrv);
EXPORT_SYMBOL(sound_install_mixer);
EXPORT_SYMBOL(sound_alloc_dma);
EXPORT_SYMBOL(sound_free_dma);
-EXPORT_SYMBOL(snd_set_irq_handler);
-EXPORT_SYMBOL(snd_release_irq);
+EXPORT_SYMBOL(sound_open_dma);
+EXPORT_SYMBOL(sound_close_dma);
EXPORT_SYMBOL(sound_alloc_audiodev);
EXPORT_SYMBOL(sound_alloc_mididev);
EXPORT_SYMBOL(sound_alloc_mixerdev);
EXPORT_SYMBOL(sound_alloc_timerdev);
EXPORT_SYMBOL(sound_alloc_synthdev);
-EXPORT_SYMBOL(sound_mem_blocks);
-EXPORT_SYMBOL(sound_mem_sizes);
-EXPORT_SYMBOL(sound_nblocks);
EXPORT_SYMBOL(sound_unload_audiodev);
EXPORT_SYMBOL(sound_unload_mididev);
EXPORT_SYMBOL(sound_unload_mixerdev);
@@ -90,3 +89,14 @@ EXPORT_SYMBOL(midi_synth_send_sysex);
EXPORT_SYMBOL(midi_synth_bender);
EXPORT_SYMBOL(midi_synth_load_patch);
+/* Firmware */
+
+EXPORT_SYMBOL(mod_firmware_load);
+
+/* Tuning */
+
+EXPORT_SYMBOL(cent_tuning);
+EXPORT_SYMBOL(semitone_tuning);
+
+MODULE_DESCRIPTION("Sound subsystem");
+MODULE_AUTHOR("Hannu Savolainen, et al.");
diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c
index fe3622a73..42ea158cc 100644
--- a/drivers/sound/soundcard.c
+++ b/drivers/sound/soundcard.c
@@ -16,8 +16,8 @@
* Stefan Reinauer : integrated /proc/sound (equals to /dev/sndstat,
* which should disappear in the near future)
*/
-#include <linux/config.h>
+#include <linux/config.h>
#include "sound_config.h"
#include <linux/types.h>
@@ -28,6 +28,7 @@
#include <linux/stddef.h>
#include <linux/kmod.h>
#ifdef __KERNEL__
+#include <asm/dma.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <linux/wait.h>
@@ -48,6 +49,13 @@
#define modular 0
#endif
+/*
+ * This ought to be moved into include/asm/dma.h
+ */
+#ifndef valid_dma
+#define valid_dma(n) ((n) >= 0 && (n) < MAX_DMA_CHANNELS && (n) != 4)
+#endif
+
static int chrdev_registered = 0;
static int sound_major = SOUND_MAJOR;
@@ -57,12 +65,11 @@ static int is_unloading = 0;
* Table for permanently allocated memory (used when unloading the module)
*/
caddr_t sound_mem_blocks[1024];
-int sound_mem_sizes[1024];
int sound_nblocks = 0;
static int soundcard_configured = 0;
-static char dma_alloc_map[8] =
+static char dma_alloc_map[MAX_DMA_CHANNELS] =
{0};
#define DMA_MAP_UNAVAIL 0
@@ -788,31 +795,9 @@ soundcard_init(void)
}
-static unsigned int irqs = 0;
-
-#ifdef MODULE
-static void
-free_all_irqs(void)
-{
- int i;
-
- for (i = 0; i < 31; i++)
- {
- if (irqs & (1ul << i))
- {
- printk(KERN_WARNING "Sound warning: IRQ%d was left allocated - fixed.\n", i);
- snd_release_irq(i, NULL);
- }
- }
- irqs = 0;
-}
-
-char kernel_version[] = UTS_RELEASE;
-
-#endif
-
-static int sound[20] =
-{0};
+static int sound[20] = {
+ 0
+};
int init_module(void)
{
@@ -876,10 +861,9 @@ void cleanup_module(void)
}
#endif
sound_unload_drivers();
- free_all_irqs(); /* If something was left allocated by accident */
sequencer_unload();
- for (i = 0; i < 8; i++)
+ for (i = 0; i < MAX_DMA_CHANNELS; i++)
{
if (dma_alloc_map[i] != DMA_MAP_UNAVAIL)
{
@@ -895,35 +879,6 @@ void cleanup_module(void)
}
#endif
-int snd_set_irq_handler(int interrupt_level, void (*iproc) (int, void *, struct pt_regs *), char *name, int *osp, void *dev_id)
-{
- int retcode;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- retcode = request_irq(interrupt_level, iproc, 0, name, dev_id);
-
- if (retcode < 0)
- {
- printk(KERN_ERR "Sound: IRQ%d already in use\n", interrupt_level);
- }
- else
- irqs |= (1ul << interrupt_level);
-
- restore_flags(flags);
- return retcode;
-}
-
-void snd_release_irq(int vect, void *dev_id)
-{
- if (!(irqs & (1ul << vect)))
- return;
-
- irqs &= ~(1ul << vect);
- free_irq(vect, dev_id);
-}
-
int sound_alloc_dma(int chn, char *deviceID)
{
int err;
@@ -940,7 +895,7 @@ int sound_open_dma(int chn, char *deviceID)
{
unsigned long flags;
- if (chn < 0 || chn > 7 || chn == 4)
+ if (!valid_dma(chn))
{
printk(KERN_ERR "sound_open_dma: Invalid DMA channel %d\n", chn);
return 1;
diff --git a/drivers/sound/trix.c b/drivers/sound/trix.c
index 9b34c4422..1c5820fcd 100644
--- a/drivers/sound/trix.c
+++ b/drivers/sound/trix.c
@@ -3,14 +3,18 @@
*
* Low level driver for the MediaTrix AudioTrix Pro
* (MT-0002-PC Control Chip)
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
+ *
+ * Changes
+ * Alan Cox Modularisation, cleanup.
*/
+
#include <linux/config.h>
#include <linux/module.h>
@@ -35,30 +39,27 @@ static int trix_boot_len = 0;
#endif
-static int kilroy_was_here = 0; /* Don't detect twice */
-static int sb_initialized = 0;
-static int mpu_initialized = 0;
+static int kilroy_was_here = 0; /* Don't detect twice */
+static int sb_initialized = 0;
+static int mpu_initialized = 0;
-static int *trix_osp = NULL;
+static int *trix_osp = NULL;
-static unsigned char
-trix_read(int addr)
+static unsigned char trix_read(int addr)
{
outb(((unsigned char) addr), 0x390); /* MT-0002-PC ASIC address */
return inb(0x391); /* MT-0002-PC ASIC data */
}
-static void
-trix_write(int addr, int data)
+static void trix_write(int addr, int data)
{
outb(((unsigned char) addr), 0x390); /* MT-0002-PC ASIC address */
outb(((unsigned char) data), 0x391); /* MT-0002-PC ASIC data */
}
-static void
-download_boot(int base)
+static void download_boot(int base)
{
- int i = 0, n = trix_boot_len;
+ int i = 0, n = trix_boot_len;
if (trix_boot_len == 0)
return;
@@ -83,24 +84,23 @@ download_boot(int base)
}
-static int
-trix_set_wss_port(struct address_info *hw_config)
+static int trix_set_wss_port(struct address_info *hw_config)
{
unsigned char addr_bits;
if (check_region(0x390, 2))
- {
- printk(KERN_ERR "AudioTrix: Config port I/O conflict\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "AudioTrix: Config port I/O conflict\n");
+ return 0;
+ }
if (kilroy_was_here) /* Already initialized */
return 0;
if (trix_read(0x15) != 0x71) /* No ASIC signature */
- {
- MDB(printk("No AudioTrix ASIC signature found\n"));
- return 0;
- }
+ {
+ MDB(printk(KERN_ERR "No AudioTrix ASIC signature found\n"));
+ return 0;
+ }
kilroy_was_here = 1;
/*
@@ -111,26 +111,26 @@ trix_set_wss_port(struct address_info *hw_config)
trix_write(0x14, 0);
/*
- * Configure the ASIC to place the codec to the proper I/O location
+ * Configure the ASIC to place the codec to the proper I/O location
*/
switch (hw_config->io_base)
- {
- case 0x530:
- addr_bits = 0;
- break;
- case 0x604:
- addr_bits = 1;
- break;
- case 0xE80:
- addr_bits = 2;
- break;
- case 0xF40:
- addr_bits = 3;
- break;
- default:
- return 0;
- }
+ {
+ case 0x530:
+ addr_bits = 0;
+ break;
+ case 0x604:
+ addr_bits = 1;
+ break;
+ case 0xE80:
+ addr_bits = 2;
+ break;
+ case 0xF40:
+ addr_bits = 3;
+ break;
+ default:
+ return 0;
+ }
trix_write(0x19, (trix_read(0x19) & 0x03) | addr_bits);
return 1;
@@ -141,120 +141,123 @@ trix_set_wss_port(struct address_info *hw_config)
* AudioTrix Pro
*/
-int
-probe_trix_wss(struct address_info *hw_config)
+int probe_trix_wss(struct address_info *hw_config)
{
- int ret;
+ int ret;
/*
- * Check if the IO port returns valid signature. The original MS Sound
- * system returns 0x04 while some cards (AudioTrix Pro for example)
- * return 0x00.
+ * Check if the IO port returns valid signature. The original MS Sound
+ * system returns 0x04 while some cards (AudioTrix Pro for example)
+ * return 0x00.
*/
if (check_region(hw_config->io_base, 8))
- {
- printk("AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
+ {
+ printk(KERN_ERR "AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base);
+ return 0;
+ }
trix_osp = hw_config->osp;
if (!trix_set_wss_port(hw_config))
return 0;
if ((inb(hw_config->io_base + 3) & 0x3f) != 0x00)
- {
- MDB(printk("No MSS signature detected on port 0x%x\n", hw_config->io_base));
- return 0;
- }
+ {
+ MDB(printk(KERN_ERR "No MSS signature detected on port 0x%x\n", hw_config->io_base));
+ return 0;
+ }
if (hw_config->irq > 11)
- {
- printk("AudioTrix: Bad WSS IRQ %d\n", hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "AudioTrix: Bad WSS IRQ %d\n", hw_config->irq);
+ return 0;
+ }
if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
- {
- printk("AudioTrix: Bad WSS DMA %d\n", hw_config->dma);
- return 0;
- }
+ {
+ printk(KERN_ERR "AudioTrix: Bad WSS DMA %d\n", hw_config->dma);
+ return 0;
+ }
if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
if (hw_config->dma2 != 0 && hw_config->dma2 != 1 && hw_config->dma2 != 3)
- {
- printk("AudioTrix: Bad capture DMA %d\n", hw_config->dma2);
+ {
+ printk(KERN_ERR "AudioTrix: Bad capture DMA %d\n", hw_config->dma2);
return 0;
- }
+ }
/*
- * Check that DMA0 is not in use with a 8 bit board.
+ * Check that DMA0 is not in use with a 8 bit board.
*/
if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)
- {
- printk("AudioTrix: Can't use DMA0 with a 8 bit card slot\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "AudioTrix: Can't use DMA0 with a 8 bit card slot\n");
+ return 0;
+ }
if (hw_config->irq > 7 && hw_config->irq != 9 && inb(hw_config->io_base + 3) & 0x80)
- {
- printk("AudioTrix: Can't use IRQ%d with a 8 bit card slot\n", hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "AudioTrix: Can't use IRQ%d with a 8 bit card slot\n", hw_config->irq);
+ return 0;
+ }
ret = ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp);
if (ret)
- {
+ {
#ifdef TRIX_ENABLE_JOYSTICK
- trix_write(0x15, 0x80);
+ trix_write(0x15, 0x80);
#endif
- request_region(0x390, 2, "AudioTrix");
- }
+ request_region(0x390, 2, "AudioTrix");
+ }
return ret;
}
void
attach_trix_wss(struct address_info *hw_config)
{
- static unsigned char interrupt_bits[12] =
- {0, 0, 0, 0, 0, 0, 0, 0x08, 0, 0x10, 0x18, 0x20};
- char bits;
+ static unsigned char interrupt_bits[12] = {
+ 0, 0, 0, 0, 0, 0, 0, 0x08, 0, 0x10, 0x18, 0x20
+ };
+ char bits;
- static unsigned char dma_bits[4] =
- {1, 2, 0, 3};
+ static unsigned char dma_bits[4] = {
+ 1, 2, 0, 3
+ };
- int config_port = hw_config->io_base + 0;
- int dma1 = hw_config->dma, dma2 = hw_config->dma2;
- int old_num_mixers = num_mixers;
+ int config_port = hw_config->io_base + 0;
+ int dma1 = hw_config->dma, dma2 = hw_config->dma2;
+ int old_num_mixers = num_mixers;
trix_osp = hw_config->osp;
if (!kilroy_was_here)
- {
- DDB(printk("AudioTrix: Attach called but not probed yet???\n"));
- return;
- }
+ {
+ DDB(printk("AudioTrix: Attach called but not probed yet???\n"));
+ return;
+ }
+
/*
- * Set the IRQ and DMA addresses.
+ * Set the IRQ and DMA addresses.
*/
bits = interrupt_bits[hw_config->irq];
if (bits == 0)
- {
- printk("AudioTrix: Bad IRQ (%d)\n", hw_config->irq);
- return;
- }
+ {
+ printk("AudioTrix: Bad IRQ (%d)\n", hw_config->irq);
+ return;
+ }
outb((bits | 0x40), config_port);
if (hw_config->dma2 == -1 || hw_config->dma2 == hw_config->dma)
- {
+ {
bits |= dma_bits[dma1];
dma2 = dma1;
- } else
- {
- unsigned char tmp;
+ }
+ else
+ {
+ unsigned char tmp;
- tmp = trix_read(0x13) & ~30;
- trix_write(0x13, tmp | 0x80 | (dma1 << 4));
+ tmp = trix_read(0x13) & ~30;
+ trix_write(0x13, tmp | 0x80 | (dma1 << 4));
- tmp = trix_read(0x14) & ~30;
- trix_write(0x14, tmp | 0x80 | (dma2 << 4));
- }
+ tmp = trix_read(0x14) & ~30;
+ trix_write(0x14, tmp | 0x80 | (dma2 << 4));
+ }
outb((bits), config_port); /* Write IRQ+DMA setup */
@@ -267,22 +270,22 @@ attach_trix_wss(struct address_info *hw_config)
request_region(hw_config->io_base, 4, "MSS config");
if (num_mixers > old_num_mixers) /* Mixer got installed */
- {
- AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE); /* Line in */
- AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
- AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_SYNTH); /* OPL4 */
- AD1848_REROUTE(SOUND_MIXER_SPEAKER, SOUND_MIXER_ALTPCM); /* SB */
- }
+ {
+ AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE); /* Line in */
+ AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
+ AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_SYNTH); /* OPL4 */
+ AD1848_REROUTE(SOUND_MIXER_SPEAKER, SOUND_MIXER_ALTPCM); /* SB */
+ }
}
-int
-probe_trix_sb(struct address_info *hw_config)
+int probe_trix_sb(struct address_info *hw_config)
{
- int tmp;
- unsigned char conf;
- static char irq_translate[] =
- {-1, -1, -1, 0, 1, 2, -1, 3};
+ int tmp;
+ unsigned char conf;
+ static char irq_translate[] = {
+ -1, -1, -1, 0, 1, 2, -1, 3
+ };
if (trix_boot_len == 0)
return 0; /* No boot code -> no fun */
@@ -294,10 +297,10 @@ probe_trix_sb(struct address_info *hw_config)
return 0;
if (check_region(hw_config->io_base, 16))
- {
- printk("AudioTrix: SB I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
+ {
+ printk(KERN_ERR "AudioTrix: SB I/O port conflict (%x)\n", hw_config->io_base);
+ return 0;
+ }
if ((hw_config->io_base & 0xffffff8f) != 0x200)
return 0;
@@ -329,11 +332,10 @@ probe_trix_sb(struct address_info *hw_config)
#endif
}
-void
-attach_trix_sb(struct address_info *hw_config)
+void attach_trix_sb(struct address_info *hw_config)
{
- extern int sb_be_quiet;
- int old_quiet;
+ extern int sb_be_quiet;
+ int old_quiet;
#ifdef CONFIG_SBDSP
hw_config->driver_use_1 = SB_NO_MIDI | SB_NO_MIXER | SB_NO_RECORDING;
@@ -348,8 +350,7 @@ attach_trix_sb(struct address_info *hw_config)
#endif
}
-void
-attach_trix_mpu(struct address_info *hw_config)
+void attach_trix_mpu(struct address_info *hw_config)
{
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
hw_config->name = "AudioTrix Pro";
@@ -357,78 +358,74 @@ attach_trix_mpu(struct address_info *hw_config)
#endif
}
-int
-probe_trix_mpu(struct address_info *hw_config)
+int probe_trix_mpu(struct address_info *hw_config)
{
#ifdef DO_MIDI
- unsigned char conf;
- static char irq_bits[] =
- {-1, -1, -1, 1, 2, 3, -1, 4, -1, 5};
+ unsigned char conf;
+ static char irq_bits[] = {
+ -1, -1, -1, 1, 2, 3, -1, 4, -1, 5
+ };
if (!kilroy_was_here)
- {
- DDB(printk("Trix: WSS and SB modes must be initialized before MPU\n"));
- return 0; /* AudioTrix Pro has not been detected earlier */
- }
+ {
+ DDB(printk("Trix: WSS and SB modes must be initialized before MPU\n"));
+ return 0; /* AudioTrix Pro has not been detected earlier */
+ }
if (!sb_initialized)
- {
- DDB(printk("Trix: SB mode must be initialized before MPU\n"));
- return 0;
- }
+ {
+ DDB(printk("Trix: SB mode must be initialized before MPU\n"));
+ return 0;
+ }
if (mpu_initialized)
- {
- DDB(printk("Trix: MPU mode already initialized\n"));
- return 0;
- }
+ {
+ DDB(printk("Trix: MPU mode already initialized\n"));
+ return 0;
+ }
if (check_region(hw_config->io_base, 4))
- {
- printk("AudioTrix: MPU I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
+ {
+ printk(KERN_ERR "AudioTrix: MPU I/O port conflict (%x)\n", hw_config->io_base);
+ return 0;
+ }
if (hw_config->irq > 9)
- {
- printk("AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
+ return 0;
+ }
if (irq_bits[hw_config->irq] == -1)
- {
- printk("AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
+ return 0;
+ }
switch (hw_config->io_base)
- {
- case 0x330:
- conf = 0x00;
- break;
- case 0x370:
- conf = 0x04;
- break;
- case 0x3b0:
- conf = 0x08;
- break;
- case 0x3f0:
- conf = 0x0c;
- break;
- default:
- return 0; /* Invalid port */
- }
+ {
+ case 0x330:
+ conf = 0x00;
+ break;
+ case 0x370:
+ conf = 0x04;
+ break;
+ case 0x3b0:
+ conf = 0x08;
+ break;
+ case 0x3f0:
+ conf = 0x0c;
+ break;
+ default:
+ return 0; /* Invalid port */
+ }
conf |= irq_bits[hw_config->irq] << 4;
-
trix_write(0x19, (trix_read(0x19) & 0x83) | conf);
-
mpu_initialized = 1;
-
return probe_uart401(hw_config);
#else
return 0;
#endif
}
-void
-unload_trix_wss(struct address_info *hw_config)
+void unload_trix_wss(struct address_info *hw_config)
{
- int dma2 = hw_config->dma2;
+ int dma2 = hw_config->dma2;
if (dma2 == -1)
dma2 = hw_config->dma;
@@ -444,15 +441,14 @@ unload_trix_wss(struct address_info *hw_config)
sound_unload_audiodev(hw_config->slots[0]);
}
-void
-unload_trix_mpu(struct address_info *hw_config)
+void unload_trix_mpu(struct address_info *hw_config)
{
#ifdef DO_MIDI
unload_uart401(hw_config);
#endif
}
-void
-unload_trix_sb(struct address_info *hw_config)
+
+void unload_trix_sb(struct address_info *hw_config)
{
#ifdef CONFIG_SBDSP
sb_dsp_unload(hw_config);
@@ -473,6 +469,18 @@ int sb_irq = -1;
int mpu_io = -1;
int mpu_irq = -1;
+EXPORT_NO_SYMBOLS;
+
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
+MODULE_PARM(dma,"i");
+MODULE_PARM(dma2,"i");
+MODULE_PARM(sb_io,"i");
+MODULE_PARM(sb_dma,"i");
+MODULE_PARM(sb_irq,"i");
+MODULE_PARM(mpu_io,"i");
+MODULE_PARM(mpu_irq,"i");
+
struct address_info config;
struct address_info sb_config;
struct address_info mpu_config;
@@ -482,16 +490,15 @@ static int sb = 0;
static int fw_load;
-int
-init_module(void)
+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(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
- return -EINVAL;
- }
+ {
+ printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
+ return -EINVAL;
+ }
config.io_base = io;
config.irq = irq;
config.dma = dma;
@@ -505,21 +512,21 @@ init_module(void)
mpu_config.irq = mpu_irq;
if (sb_io != -1 && (sb_irq == -1 || sb_dma == -1))
- {
- printk(KERN_INFO "CONFIG_SB_IRQ and CONFIG_SB_DMA must be specified if SB_IO is set.\n");
- return -EINVAL;
- }
+ {
+ printk(KERN_INFO "CONFIG_SB_IRQ and CONFIG_SB_DMA must be specified if SB_IO is set.\n");
+ return -EINVAL;
+ }
if (mpu_io != -1 && mpu_irq == -1)
- {
- printk(KERN_INFO "CONFIG_MPU_IRQ must be specified if MPU_IO is set.\n");
- return -EINVAL;
- }
+ {
+ printk(KERN_INFO "CONFIG_MPU_IRQ must be specified if MPU_IO is set.\n");
+ return -EINVAL;
+ }
if (!trix_boot)
- {
- fw_load = 1;
- trix_boot_len = mod_firmware_load("/etc/sound/trxpro.bin",
+ {
+ fw_load = 1;
+ trix_boot_len = mod_firmware_load("/etc/sound/trxpro.bin",
(char **) &trix_boot);
- }
+ }
if (!probe_trix_wss(&config))
return -ENODEV;
attach_trix_wss(&config);
@@ -530,26 +537,26 @@ init_module(void)
*/
if (sb_io != -1)
- {
- sb = probe_trix_sb(&sb_config);
- if (sb)
- attach_trix_sb(&sb_config);
- }
+ {
+ sb = probe_trix_sb(&sb_config);
+ if (sb)
+ attach_trix_sb(&sb_config);
+ }
+
if (mpu_io != -1)
- {
- mpu = probe_trix_mpu(&mpu_config);
- if (mpu)
- attach_trix_mpu(&mpu_config);
- }
+ {
+ mpu = probe_trix_mpu(&mpu_config);
+ if (mpu)
+ attach_trix_mpu(&mpu_config);
+ }
SOUND_LOCK;
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
if (fw_load && trix_boot)
- kfree(trix_boot);
+ vfree(trix_boot);
if (sb)
unload_trix_sb(&sb_config);
if (mpu)
diff --git a/drivers/sound/uart401.c b/drivers/sound/uart401.c
index 2e7ed2a27..4d8857e56 100644
--- a/drivers/sound/uart401.c
+++ b/drivers/sound/uart401.c
@@ -12,7 +12,8 @@
*
* Changes:
* Alan Cox Reformatted, removed sound_mem usage, use normal Linux
- * interrupt allocation.
+ * interrupt allocation. Protect against bogus unload
+ * Fixed to allow IRQ > 15
*
* Status:
* Untested
@@ -244,6 +245,7 @@ void attach_uart401(struct address_info *hw_config)
uart401_devc *devc;
char *name = "MPU-401 (UART) MIDI";
+
if (hw_config->name)
name = hw_config->name;
@@ -269,12 +271,6 @@ void attach_uart401(struct address_info *hw_config)
else
devc->share_irq = 0;
- if (devc->irq < 1 || devc->irq > 15)
- {
- kfree(devc);
- return;
- }
-
if (!devc->share_irq)
{
if (request_irq(devc->irq, uart401intr, 0, "MPU-401 UART", devc) < 0)
@@ -345,6 +341,7 @@ static int reset_uart401(uart401_devc * devc)
for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
devc->input_byte = 0;
uart401_cmd(devc, MPU_RESET);
+
/*
* Wait at least 25 msec. This method is not accurate so let's make the
* loop bit longer. Cannot sleep since this is called during boot.
@@ -387,6 +384,8 @@ int probe_uart401(struct address_info *hw_config)
DDB(printk("Entered probe_uart401()\n"));
+ /* Default to "not found" */
+ hw_config->slots[4] = -1;
detected_devc = NULL;
if (check_region(hw_config->io_base, 4))
@@ -415,6 +414,14 @@ int probe_uart401(struct address_info *hw_config)
void unload_uart401(struct address_info *hw_config)
{
uart401_devc *devc;
+ int n=hw_config->slots[4];
+
+ /* Not set up */
+ if(n==-1 || midi_devs[n]==NULL)
+ return;
+
+ /* Not allocated (erm ??) */
+
devc = midi_devs[hw_config->slots[4]]->devc;
if (devc == NULL)
return;
diff --git a/drivers/sound/uart6850.c b/drivers/sound/uart6850.c
index b26e75a89..75b02ff94 100644
--- a/drivers/sound/uart6850.c
+++ b/drivers/sound/uart6850.c
@@ -325,6 +325,8 @@ int irq = -1;
MODULE_PARM(io,"i");
MODULE_PARM(irq,"i");
+EXPORT_NO_SYMBOLS;
+
struct address_info cfg;
int init_module(void)
diff --git a/drivers/sound/vidc.c b/drivers/sound/vidc.c
new file mode 100644
index 000000000..c33ed9beb
--- /dev/null
+++ b/drivers/sound/vidc.c
@@ -0,0 +1,81 @@
+/*
+ * drivers/sound/vidc.c
+ *
+ * Detection routine for the VIDC.
+ *
+ * Copyright (C) 1997 by Russell King <rmk@arm.uk.linux.org>
+ */
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include "sound_config.h"
+#include "vidc.h"
+
+int vidc_busy;
+
+void vidc_update_filler(int bits, int channels)
+{
+ int filltype;
+
+ filltype = bits + channels;
+ switch (filltype)
+ {
+ default:
+ case 9:
+ vidc_filler = vidc_fill_1x8;
+ break;
+ case 10:
+ vidc_filler = vidc_fill_2x8;
+ break;
+ case 17:
+ vidc_filler = vidc_fill_1x16;
+ break;
+ case 18:
+ vidc_filler = vidc_fill_2x16;
+ break;
+ }
+}
+
+void attach_vidc(struct address_info *hw_config)
+{
+ char name[32];
+ int i;
+
+ sprintf(name, "VIDC %d-bit sound", hw_config->card_subtype);
+ conf_printf(name, hw_config);
+
+ for (i = 0; i < 2; i++)
+ {
+ dma_buf[i] = get_free_page(GFP_KERNEL);
+ dma_pbuf[i] = virt_to_phys(dma_buf[i]);
+ }
+
+ if (sound_alloc_dma(hw_config->dma, "VIDCsound"))
+ {
+ printk(KERN_ERR "VIDCsound: can't allocate virtual DMA channel\n");
+ return;
+ }
+ if (request_irq(hw_config->irq, vidc_sound_dma_irq, 0, "VIDCsound", NULL))
+ {
+ printk(KERN_ERR "VIDCsound: can't allocate DMA interrupt\n");
+ return;
+ }
+ vidc_synth_init(hw_config);
+ vidc_audio_init(hw_config);
+ vidc_mixer_init(hw_config);
+}
+
+int probe_vidc(struct address_info *hw_config)
+{
+ hw_config->irq = IRQ_DMAS0;
+ hw_config->dma = DMA_VIRTUAL_SOUND;
+ hw_config->dma2 = -1;
+ hw_config->card_subtype = 16;
+ return 1;
+}
+
+void unload_vidc(struct address_info *hw_config)
+{
+ free_irq(hw_config->irq, NULL);
+ sound_free_dma(hw_config->dma);
+}
diff --git a/drivers/sound/vidc.h b/drivers/sound/vidc.h
new file mode 100644
index 000000000..33625f392
--- /dev/null
+++ b/drivers/sound/vidc.h
@@ -0,0 +1,68 @@
+/*
+ * drivers/sound/vidc.h
+ *
+ * VIDC sound function prototypes
+ *
+ * Copyright (C) 1997 Russell King <rmk@arm.uk.linux.org>
+ */
+
+/* vidc.c */
+
+extern int vidc_busy;
+
+/* vidc_fill.S */
+
+/*
+ * Filler routines for different channels and sample sizes
+ */
+
+extern unsigned long vidc_fill_1x8(unsigned long ibuf, unsigned long iend,
+ unsigned long obuf, int mask);
+extern unsigned long vidc_fill_2x8(unsigned long ibuf, unsigned long iend,
+ unsigned long obuf, int mask);
+extern unsigned long vidc_fill_1x16(unsigned long ibuf, unsigned long iend,
+ unsigned long obuf, int mask);
+extern unsigned long vidc_fill_2x16(unsigned long ibuf, unsigned long iend,
+ unsigned long obuf, int mask);
+
+/*
+ * DMA Interrupt handler
+ */
+
+extern void vidc_sound_dma_irq(int irqnr, void *ref, struct pt_regs *regs);
+
+/*
+ * Filler routine pointer
+ */
+
+extern unsigned long (*vidc_filler) (unsigned long ibuf, unsigned long iend,
+ unsigned long obuf, int mask);
+
+/*
+ * Virtual DMA buffer exhausted
+ */
+
+extern void (*dma_interrupt) (void);
+
+/*
+ * Virtual DMA buffer addresses
+ */
+
+extern unsigned long dma_start, dma_count, dma_bufsize;
+extern unsigned long dma_buf[2], dma_pbuf[2];
+
+/* vidc_audio.c */
+
+extern void vidc_audio_init(struct address_info *hw_config);
+extern int vidc_audio_get_volume(void);
+extern int vidc_audio_set_volume(int vol);
+
+/* vidc_mixer.c */
+
+extern void vidc_mixer_init(struct address_info *hw_config);
+
+/* vidc_synth.c */
+
+extern void vidc_synth_init(struct address_info *hw_config);
+extern int vidc_synth_get_volume(void);
+extern int vidc_synth_set_volume(int vol);
diff --git a/drivers/sound/vidc_audio.c b/drivers/sound/vidc_audio.c
new file mode 100644
index 000000000..a59a077f3
--- /dev/null
+++ b/drivers/sound/vidc_audio.c
@@ -0,0 +1,320 @@
+/*
+ * drivers/sound/vidc_audio.c
+ *
+ * Audio routines for the VIDC
+ *
+ * Copyright (C) 1997 Russell King <rmk@arm.uk.linux.org>
+ */
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include "sound_config.h"
+#include "vidc.h"
+
+/*
+ * VIDC sound
+ *
+ * When using SERIAL SOUND mode (external DAC), the number of physical
+ * channels is fixed at 2. Therefore, the sample rate = vidc sample rate.
+ */
+
+static int vidc_adev;
+
+static int vidc_audio_volume;
+static int vidc_audio_rate;
+static char vidc_audio_bits;
+static char vidc_audio_channels;
+
+extern void vidc_update_filler(int bits, int channels);
+
+int vidc_audio_get_volume(void)
+{
+ return vidc_audio_volume;
+}
+
+int vidc_audio_set_volume(int newvol)
+{
+ vidc_audio_volume = newvol;
+ return vidc_audio_volume;
+}
+
+static int vidc_audio_set_bits(int bits)
+{
+ switch (bits)
+ {
+ case AFMT_QUERY:
+ break;
+ case AFMT_U8:
+ case AFMT_S16_LE:
+ vidc_audio_bits = bits;
+ vidc_update_filler(vidc_audio_bits, vidc_audio_channels);
+ break;
+ default:
+ vidc_audio_bits = 16;
+ vidc_update_filler(vidc_audio_bits, vidc_audio_channels);
+ break;
+ }
+ return vidc_audio_bits;
+}
+
+static int vidc_audio_set_rate(int rate)
+{
+ if (rate)
+ {
+ int newsize, new2size;
+
+ vidc_audio_rate = ((500000 / rate) + 1) >> 1;
+ if (vidc_audio_rate < 3)
+ vidc_audio_rate = 3;
+ if (vidc_audio_rate > 255)
+ vidc_audio_rate = 255;
+ outl((vidc_audio_rate - 2) | 0xb0000000, VIDC_BASE);
+ outl(0xb1000003, VIDC_BASE);
+ newsize = (10000 / vidc_audio_rate) & ~3;
+ if (newsize < 208)
+ newsize = 208;
+ if (newsize > 4096)
+ newsize = 4096;
+ for (new2size = 128; new2size < newsize; new2size <<= 1);
+ if (new2size - newsize > newsize - (new2size >> 1))
+ new2size >>= 1;
+ dma_bufsize = new2size;
+ }
+ return 250000 / vidc_audio_rate;
+}
+
+static int vidc_audio_set_channels(int channels)
+{
+ switch (channels)
+ {
+ case 0:
+ break;
+ case 1:
+ case 2:
+ vidc_audio_channels = channels;
+ vidc_update_filler(vidc_audio_bits, vidc_audio_channels);
+ break;
+ default:
+ vidc_audio_channels = 2;
+ vidc_update_filler(vidc_audio_bits, vidc_audio_channels);
+ break;
+ }
+ return vidc_audio_channels;
+}
+
+/*
+ * Open the device
+ *
+ * dev - device
+ * mode - mode to open device (logical OR of OPEN_READ and OPEN_WRITE)
+ *
+ * Called when opening the DMAbuf (dmabuf.c:259)
+ */
+
+static int vidc_audio_open(int dev, int mode)
+{
+ if (vidc_busy)
+ return -EBUSY;
+
+ if ((mode & OPEN_READ) && (!mode & OPEN_WRITE))
+ {
+ /* This audio device doesn't have recording capability */
+ return -EIO;
+ }
+ vidc_busy = 1;
+ return 0;
+}
+
+/*
+ * Close the device
+ *
+ * dev - device
+ *
+ * Called when closing the DMAbuf (dmabuf.c:477)
+ * after halt_xfer
+ */
+
+static void vidc_audio_close(int dev)
+{
+ vidc_busy = 0;
+}
+
+static int vidc_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
+{
+ int ret;
+
+ switch (cmd)
+ {
+ case SOUND_PCM_WRITE_RATE:
+ if (get_user(ret, (int *) arg))
+ return -EFAULT;
+ ret = vidc_audio_set_rate(ret);
+ break;
+
+ case SOUND_PCM_READ_RATE:
+ ret = vidc_audio_set_rate(0);
+ break;
+
+ case SNDCTL_DSP_STEREO:
+ if (get_user(ret, (int *) arg))
+ return -EFAULT;
+ ret = vidc_audio_set_channels(ret + 1) - 1;
+ break;
+
+ case SOUND_PCM_WRITE_CHANNELS:
+ if (get_user(ret, (int *) arg))
+ return -EFAULT;
+ ret = vidc_audio_set_channels(ret);
+ break;
+
+ case SOUND_PCM_READ_CHANNELS:
+ ret = vidc_audio_set_channels(0);
+ break;
+
+ case SNDCTL_DSP_SETFMT:
+ if (get_user(ret, (int *) arg))
+ return -EFAULT;
+ ret = vidc_audio_set_bits(ret);
+ break;
+
+ case SOUND_PCM_READ_BITS:
+ ret = vidc_audio_set_bits(0);
+ break;
+
+ case SOUND_PCM_WRITE_FILTER:
+ case SOUND_PCM_READ_FILTER:
+ return -EINVAL;
+
+ default:
+ return -EINVAL;
+ }
+ return put_user(ret, (int *) arg);
+}
+
+/*
+ * Output a block via DMA to sound device
+ *
+ * dev - device number
+ * buf - physical address of buffer
+ * total_count - total byte count in buffer
+ * intrflag - set if this has been called from an interrupt (via DMAbuf_outputintr)
+ * restart_dma - set if DMA needs to be re-initialised
+ *
+ * Called when:
+ * 1. Starting output (dmabuf.c:1327)
+ * 2. (dmabuf.c:1504)
+ * 3. A new buffer needs to be sent to the device (dmabuf.c:1579)
+ */
+
+static void vidc_audio_dma_interrupt(void)
+{
+ DMAbuf_outputintr(vidc_adev, 1);
+}
+
+static void vidc_audio_output_block(int dev, unsigned long buf, int total_count,
+ int intrflag)
+{
+ dma_start = buf;
+ dma_count = total_count;
+
+ if (!intrflag)
+ {
+ dma_interrupt = vidc_audio_dma_interrupt;
+ vidc_sound_dma_irq(0, NULL, NULL);
+ outb(DMA_CR_D | DMA_CR_E, IOMD_SD0CR);
+ }
+}
+
+static void vidc_audio_start_input(int dev, unsigned long buf, int count,
+ int intrflag)
+{
+}
+
+static int vidc_audio_prepare_for_input(int dev, int bsize, int bcount)
+{
+ return -EINVAL;
+}
+
+/*
+ * Prepare for outputting samples to `dev'
+ *
+ * Each buffer that will be passed will be `bsize' bytes long,
+ * with a total of `bcount' buffers.
+ *
+ * Called when:
+ * 1. A trigger enables audio output (dmabuf.c:978)
+ * 2. We get a write buffer without dma_mode setup (dmabuf.c:1152)
+ * 3. We restart a transfer (dmabuf.c:1324)
+ */
+
+static int vidc_audio_prepare_for_output(int dev, int bsize, int bcount)
+{
+ return 0;
+}
+
+static void vidc_audio_reset(int dev)
+{
+}
+
+/*
+ * Halt a DMA transfer to `dev'
+ *
+ * Called when:
+ * 1. We close the DMAbuf (dmabuf.c:476)
+ * 2. We run out of output buffers to output to the device. (dmabuf.c:1456)
+ * 3. We run out of output buffers and we're closing down. (dmabuf.c:1546)
+ * 4. We run out of input buffers in AUTOMODE. (dmabuf.c:1651)
+ */
+
+static void vidc_audio_halt_xfer(int dev)
+{
+ dma_count = 0;
+}
+
+static int vidc_audio_local_qlen(int dev)
+{
+ return dma_count != 0;
+}
+
+static struct audio_driver vidc_audio_driver =
+{
+ vidc_audio_open, /* open */
+ vidc_audio_close, /* close */
+ vidc_audio_output_block, /* output_block */
+ vidc_audio_start_input, /* start_input */
+ vidc_audio_ioctl, /* ioctl */
+ vidc_audio_prepare_for_input, /* prepare_for_input */
+ vidc_audio_prepare_for_output, /* prepare_for_output */
+ vidc_audio_reset, /* reset */
+ vidc_audio_halt_xfer, /* halt_xfer */
+ vidc_audio_local_qlen, /*+local_qlen */
+ NULL, /*+copy_from_user */
+ NULL, /*+halt_input */
+ NULL, /*+halt_output */
+ NULL, /*+trigger */
+ NULL, /*+set_speed */
+ NULL, /*+set_bits */
+ NULL, /*+set_channels */
+};
+
+static struct audio_operations vidc_audio_operations =
+{
+ "VIDCsound",
+ 0,
+ AFMT_U8 | AFMT_S16_LE,
+ NULL,
+ &vidc_audio_driver
+};
+
+void vidc_audio_init(struct address_info *hw_config)
+{
+ vidc_audio_volume = 100 | (100 << 8);
+ if ((vidc_adev = sound_alloc_audiodev())!=-1)
+ {
+ audio_devs[vidc_adev] = &vidc_audio_operations;
+ audio_devs[vidc_adev]->min_fragment = 10; /* 1024 bytes => 64 buffers */
+ audio_devs[vidc_adev]->mixer_dev = num_mixers;
+ audio_devs[vidc_adev]->flags |= 0;
+ }
+ else printk(KERN_ERR "VIDCsound: Too many PCM devices available\n");
+}
diff --git a/drivers/sound/vidc_fill.S b/drivers/sound/vidc_fill.S
new file mode 100644
index 000000000..841fe5b96
--- /dev/null
+++ b/drivers/sound/vidc_fill.S
@@ -0,0 +1,184 @@
+/*
+ * sound/vidc_fill.S
+ *
+ * Filler routines for DMA buffers
+ *
+ * Copyright (C) 1997 Russell King
+ */
+#define __ASSEMBLY__
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+ .text
+
+ENTRY(vidc_fill_1x8)
+ mov ip, #0xff00
+1: cmp r0, r1
+ bge SYMBOL_NAME(vidc_clear)
+ ldrb r4, [r0], #1
+ and r4, ip, r4, lsl #8
+ orr r4, r4, r4, lsl #16
+ str r4, [r2], #4
+ cmp r2, r3
+ blt 1b
+ mov pc, lr
+
+ENTRY(vidc_fill_2x8)
+ mov ip, #0xff00
+1: cmp r0, r1
+ bge SYMBOL_NAME(vidc_clear)
+ ldr r4, [r0], #2
+ and r5, r4, ip
+ and r4, ip, r4, lsl #8
+ orr r4, r4, r5, lsl #16
+ orr r4, r4, r4, lsr #8
+ str r4, [r2], #4
+ cmp r2, r3
+ blt 1b
+ mov pc, lr
+
+ENTRY(vidc_fill_1x16)
+ mov ip, #0xff00
+ orr ip, ip, ip, lsr #8
+1: cmp r0, r1
+ bge SYMBOL_NAME(vidc_clear)
+ ldr r5, [r0], #2
+ and r4, r5, ip
+ orr r4, r4, r4, lsl #16
+ str r4, [r2], #4
+ cmp r0, r1
+ addlt r0, r0, #2
+ andlt r4, r5, ip, lsl #16
+ orrlt r4, r4, r4, lsr #16
+ strlt r4, [r2], #4
+ cmp r2, r3
+ blt 1b
+ mov pc, lr
+
+ENTRY(vidc_fill_2x16)
+ mov ip, #0xff00
+ orr ip, ip, ip, lsr #8
+1: cmp r0, r1
+ bge SYMBOL_NAME(vidc_clear)
+ ldr r4, [r0], #4
+ str r4, [r2], #4
+ cmp r0, r1
+ ldrlt r4, [r0], #4
+ strlt r4, [r2], #4
+ cmp r2, r3
+ blt 1b
+ mov pc, lr
+
+ENTRY(vidc_fill_noaudio)
+ mov r0, #0
+ mov r1, #0
+2: mov r4, #0
+ mov r5, #0
+1: cmp r2, r3
+ stmltia r2!, {r0, r1, r4, r5}
+ blt 1b
+ mov pc, lr
+
+ENTRY(vidc_clear)
+ mov r0, #0
+ mov r1, #0
+ tst r2, #4
+ str r0, [r2], #4
+ tst r2, #8
+ stmia r2!, {r0, r1}
+ b 2b
+
+/*
+ * Call filler routines with:
+ * r0 = phys address
+ * r1 = phys end
+ * r2 = buffer
+ * Returns:
+ * r0 = new buffer address
+ * r2 = new buffer finish
+ * r4 = corrupted
+ * r5 = corrupted
+ * ip = corrupted
+ */
+
+ENTRY(vidc_sound_dma_irq)
+ stmfd sp!, {r4 - r9, lr}
+ ldr r9, =SYMBOL_NAME(dma_start)
+ ldmia r9, {r0, r1, r2, r3, r4, r5}
+ teq r1, #0
+ adreq r4, SYMBOL_NAME(vidc_fill_noaudio)
+ moveq r8, #1 << 31
+ movne r8, #0
+ mov ip, #IOMD_BASE & 0xff000000
+ orr ip, ip, #IOMD_BASE & 0x00ff0000
+ ldrb r7, [ip, #IOMD_SD0ST]
+ tst r7, #DMA_ST_OFL @ Check for overrun
+ eorne r7, r7, #DMA_ST_AB
+ tst r7, #DMA_ST_AB
+ moveq r2, r3 @ DMAing A, update B
+ add r3, r2, r5 @ End of DMA buffer
+ add r1, r1, r0 @ End of virtual DMA buffer
+ mov lr, pc
+ mov pc, r4 @ Call fill routine
+ sub r1, r1, r0 @ Remaining length
+ stmia r9, {r0, r1}
+ mov r0, #0
+ tst r2, #4 @ Round buffer up to 4 words
+ strne r0, [r2], #4
+ tst r2, #8
+ strne r0, [r2], #4
+ strne r0, [r2], #4
+ sub r2, r2, #16
+ mov r2, r2, lsl #20
+ movs r2, r2, lsr #20
+ orreq r2, r2, #1 << 30 @ Set L bit
+ orr r2, r2, r8
+ ldmdb r9, {r3, r4, r5}
+ tst r7, #DMA_ST_AB
+ mov ip, #IOMD_BASE & 0xff000000
+ orr ip, ip, #IOMD_BASE & 0x00ff0000
+ streq r4, [ip, #IOMD_SD0CURB]
+ strne r5, [ip, #IOMD_SD0CURA]
+ streq r2, [ip, #IOMD_SD0ENDB]
+ strne r2, [ip, #IOMD_SD0ENDA]
+ ldr r6, [ip, #IOMD_SD0ST]
+ tst r6, #DMA_ST_OFL
+ bne 1f
+ tst r7, #DMA_ST_AB
+ strne r4, [ip, #IOMD_SD0CURB]
+ streq r5, [ip, #IOMD_SD0CURA]
+ strne r2, [ip, #IOMD_SD0ENDB]
+ streq r2, [ip, #IOMD_SD0ENDA]
+1: teq r8, #0
+ mov r0, #0x10
+ strneb r0, [ip, #IOMD_SD0CR]
+ teqeq r1, #0
+ ldmfd sp!, {r4 - r9, lr}
+ moveq pc, r3 @ Call interrupt routine
+ mov pc, lr
+
+ .data
+ .globl SYMBOL_NAME(dma_interrupt)
+SYMBOL_NAME(dma_interrupt):
+ .long 0
+ .globl SYMBOL_NAME(dma_pbuf)
+SYMBOL_NAME(dma_pbuf):
+ .long 0
+ .long 0
+ .globl SYMBOL_NAME(dma_start)
+SYMBOL_NAME(dma_start):
+ .long 0
+ .globl SYMBOL_NAME(dma_count)
+SYMBOL_NAME(dma_count):
+ .long 0
+ .globl SYMBOL_NAME(dma_buf)
+SYMBOL_NAME(dma_buf):
+ .long 0
+ .long 0
+ .globl SYMBOL_NAME(vidc_filler)
+SYMBOL_NAME(vidc_filler):
+ .long SYMBOL_NAME(vidc_fill_noaudio)
+ .globl SYMBOL_NAME(dma_bufsize)
+SYMBOL_NAME(dma_bufsize):
+ .long 0x1000
diff --git a/drivers/sound/vidc_mixer.c b/drivers/sound/vidc_mixer.c
new file mode 100644
index 000000000..1bdb1e88e
--- /dev/null
+++ b/drivers/sound/vidc_mixer.c
@@ -0,0 +1,149 @@
+/*
+ * drivers/sound/vidc_mixer.c
+ *
+ * Mixer routines for VIDC
+ *
+ * Copyright (C) 1997 Russell King <rmk@arm.uk.linux.org>
+ */
+
+#include "sound_config.h"
+#include "vidc.h"
+
+int vidc_volume;
+
+static int vidc_get_volume(void)
+{
+ return vidc_volume;
+}
+
+static int vidc_set_volume(int newvol)
+{
+ vidc_volume = newvol;
+/* printk ("vidc_set_volume: %X\n", newvol); */
+ return newvol;
+}
+
+static int vidc_default_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+{
+ int ret;
+
+ switch (cmd)
+ {
+ case SOUND_MIXER_READ_VOLUME:
+ ret = vidc_get_volume();
+ break;
+
+ case SOUND_MIXER_WRITE_VOLUME:
+ if (get_user(ret, (int *) arg))
+ return -EINVAL;
+ ret = vidc_set_volume(ret);
+ break;
+
+ case SOUND_MIXER_READ_BASS:
+ case SOUND_MIXER_WRITE_BASS:
+ case SOUND_MIXER_READ_TREBLE:
+ case SOUND_MIXER_WRITE_TREBLE:
+ ret = 50;
+ break;
+
+ case SOUND_MIXER_READ_SYNTH:
+ ret = vidc_synth_get_volume();
+ break;
+
+ case SOUND_MIXER_WRITE_SYNTH:
+ if (get_user(ret, (int *) arg))
+ return -EINVAL;
+ ret = vidc_synth_set_volume(ret);
+ break;
+
+ case SOUND_MIXER_READ_PCM:
+ ret = vidc_audio_get_volume();
+ break;
+
+ case SOUND_MIXER_WRITE_PCM:
+ if (get_user(ret, (int *) arg))
+ return -EINVAL;
+ ret = vidc_audio_set_volume(ret);
+ break;
+
+ case SOUND_MIXER_READ_SPEAKER:
+ ret = 100;
+ break;
+
+ case SOUND_MIXER_WRITE_SPEAKER:
+ ret = 100;
+ break;
+
+ case SOUND_MIXER_READ_LINE:
+ case SOUND_MIXER_WRITE_LINE:
+ case SOUND_MIXER_READ_MIC:
+ case SOUND_MIXER_WRITE_MIC:
+ ret = 0;
+ break;
+
+ case SOUND_MIXER_READ_CD:
+ case SOUND_MIXER_WRITE_CD:
+ ret = 100 | (100 << 8);
+ break;
+
+ case SOUND_MIXER_READ_IMIX:
+ case SOUND_MIXER_WRITE_IMIX:
+ case SOUND_MIXER_READ_ALTPCM:
+ case SOUND_MIXER_WRITE_ALTPCM:
+ case SOUND_MIXER_READ_LINE1:
+ case SOUND_MIXER_WRITE_LINE1:
+ case SOUND_MIXER_READ_LINE2:
+ case SOUND_MIXER_WRITE_LINE2:
+ case SOUND_MIXER_READ_LINE3:
+ case SOUND_MIXER_WRITE_LINE3:
+ ret = 0;
+ break;
+
+ case SOUND_MIXER_READ_RECSRC:
+ ret = 0;
+ break;
+
+ case SOUND_MIXER_WRITE_RECSRC:
+ return -EINVAL;
+ break;
+
+ case SOUND_MIXER_READ_DEVMASK:
+ ret = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH;
+ break;
+
+ case SOUND_MIXER_READ_RECMASK:
+ ret = 0;
+ break;
+
+ case SOUND_MIXER_READ_STEREODEVS:
+ ret = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH;
+ break;
+
+ case SOUND_MIXER_READ_CAPS:
+ ret = 0;
+ break;
+
+ case SOUND_MIXER_READ_MUTE:
+ return -EINVAL;
+ break;
+
+ default:
+ return -EINVAL;
+ break;
+ }
+ return put_user(ret, (int *) arg);
+}
+
+static struct mixer_operations vidc_mixer_operations = {
+ "VIDC",
+ "VIDCsound",
+ vidc_default_mixer_ioctl /* ioctl */
+};
+
+void vidc_mixer_init(struct address_info *hw_config)
+{
+ int vidc_mixer = sound_alloc_mixerdev();
+ vidc_volume = 100 | (100 << 8);
+ if (num_mixers < MAX_MIXER_DEV)
+ mixer_devs[vidc_mixer] = &vidc_mixer_operations;
+}
diff --git a/drivers/sound/vidc_synth.c b/drivers/sound/vidc_synth.c
new file mode 100644
index 000000000..7e6797e8e
--- /dev/null
+++ b/drivers/sound/vidc_synth.c
@@ -0,0 +1,89 @@
+/*
+ * drivers/sound/vidc_synth.c
+ *
+ * Synthesizer routines for the VIDC
+ *
+ * Copyright (C) 1997 Russell King <rmk@arm.uk.linux.org>
+ */
+
+#include "sound_config.h"
+#include "vidc.h"
+
+static struct synth_info vidc_info =
+{
+ "VIDCsound", /* name */
+ 0, /* device */
+ SYNTH_TYPE_SAMPLE, /* synth_type */
+ 0, /* synth_subtype */
+ 0, /* perc_mode */
+ 16, /* nr_voices */
+ 0, /* nr_drums */
+ 0, /* instr_bank_size */
+ 0, /* capabilities */
+};
+
+int vidc_sdev;
+int vidc_synth_volume;
+
+static int vidc_synth_open(int dev, int mode)
+{
+ if (vidc_busy)
+ return -EBUSY;
+
+ vidc_busy = 1;
+ return 0;
+}
+
+static void vidc_synth_close(int dev)
+{
+ vidc_busy = 0;
+}
+
+
+static struct synth_operations vidc_synth_operations =
+{
+ &vidc_info, /* info */
+ 0, /* midi_dev */
+ SYNTH_TYPE_SAMPLE, /* synth_type */
+ /*SAMPLE_TYPE_XXX */ 0,
+ /* SAMPLE_TYPE GUS *//* synth_subtype */
+ vidc_synth_open, /* open */
+ vidc_synth_close, /* close */
+ NULL, /* ioctl */
+ NULL, /* kill_note */
+ NULL, /* start_note */
+ NULL, /* set_instr */
+ NULL, /* reset */
+ NULL, /* hw_control */
+ NULL, /* load_patch */
+ NULL, /* aftertouch */
+ NULL, /* controller */
+ NULL, /* panning */
+ NULL, /* volume_method */
+ NULL, /* patchmgr */
+ NULL, /* bender */
+ NULL, /* alloc */
+ NULL, /* setup_voice */
+ NULL, /* send_sysex */
+ /* alloc */
+ /* chn_info[16] */
+};
+
+int vidc_synth_get_volume(void)
+{
+ return vidc_synth_volume;
+}
+
+int vidc_synth_set_volume(int newvol)
+{
+ return vidc_synth_volume = newvol;
+}
+
+void vidc_synth_init(struct address_info *hw_config)
+{
+ vidc_synth_volume = 100 | (100 << 8);
+ if ((vidc_sdev=sound_alloc_synthdev())!=-1)
+ synth_devs[vidc_sdev] = &vidc_synth_operations;
+ else
+ printk(KERN_ERR "VIDCsound: Too many synthesizers\n");
+}