summaryrefslogtreecommitdiffstats
path: root/drivers/sound
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-03-17 22:05:47 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-03-17 22:05:47 +0000
commit27cfca1ec98e91261b1a5355d10a8996464b63af (patch)
tree8e895a53e372fa682b4c0a585b9377d67ed70d0e /drivers/sound
parent6a76fb7214c477ccf6582bd79c5b4ccc4f9c41b1 (diff)
Look Ma' what I found on my harddisk ...
o New faster syscalls for 2.1.x, too o Upgrade to 2.1.89. Don't try to run this. It's flaky as hell. But feel free to debug ...
Diffstat (limited to 'drivers/sound')
-rw-r--r--drivers/sound/.cvsignore1
-rw-r--r--drivers/sound/.objects99
-rw-r--r--drivers/sound/Config.in250
-rw-r--r--drivers/sound/Config.std69
-rw-r--r--drivers/sound/Defines395
-rw-r--r--drivers/sound/Makefile151
-rw-r--r--drivers/sound/README.C93162
-rw-r--r--drivers/sound/README.blurb (renamed from drivers/sound/.blurb)0
-rw-r--r--drivers/sound/Readme.cards114
-rw-r--r--drivers/sound/Readme.modules151
-rw-r--r--drivers/sound/ad1848.c2155
-rw-r--r--drivers/sound/adlib_card.c1
-rw-r--r--drivers/sound/audio.c1386
-rw-r--r--drivers/sound/bin2hex.c22
-rw-r--r--drivers/sound/configure.c1669
-rw-r--r--drivers/sound/cs4232.c392
-rw-r--r--drivers/sound/dev_table.c675
-rw-r--r--drivers/sound/dev_table.h425
-rw-r--r--drivers/sound/dmabuf.c1993
-rw-r--r--drivers/sound/gus_card.c111
-rw-r--r--drivers/sound/gus_midi.c181
-rw-r--r--drivers/sound/gus_vol.c39
-rw-r--r--drivers/sound/gus_wave.c3743
-rw-r--r--drivers/sound/hex2hex.c87
-rw-r--r--drivers/sound/hex2hex.h112
-rw-r--r--drivers/sound/ics2101.c158
-rw-r--r--drivers/sound/local.h.master124
-rw-r--r--drivers/sound/lowlevel/.cvsignore1
-rw-r--r--drivers/sound/lowlevel/Config.tmpl16
-rw-r--r--drivers/sound/lowlevel/Makefile7
-rw-r--r--drivers/sound/lowlevel/README.aedsp1631
-rw-r--r--drivers/sound/lowlevel/aci.c1
-rw-r--r--drivers/sound/lowlevel/aedsp16.c239
-rw-r--r--drivers/sound/lowlevel/awe_version.h11
-rw-r--r--drivers/sound/lowlevel/init.c2
-rw-r--r--drivers/sound/mad16.c64
-rw-r--r--drivers/sound/maui.c521
-rw-r--r--drivers/sound/midi_synth.c58
-rw-r--r--drivers/sound/midibuf.c533
-rw-r--r--drivers/sound/mpu401.c60
-rw-r--r--drivers/sound/opl3.c74
-rw-r--r--drivers/sound/os.h6
-rw-r--r--drivers/sound/pas2_card.c262
-rw-r--r--drivers/sound/pas2_midi.c8
-rw-r--r--drivers/sound/pas2_mixer.c206
-rw-r--r--drivers/sound/pas2_pcm.c87
-rw-r--r--drivers/sound/pss.c429
-rw-r--r--drivers/sound/sb.h2
-rw-r--r--drivers/sound/sb_audio.c21
-rw-r--r--drivers/sound/sb_card.c55
-rw-r--r--drivers/sound/sb_common.c1453
-rw-r--r--drivers/sound/sb_midi.c6
-rw-r--r--drivers/sound/sb_mixer.c116
-rw-r--r--drivers/sound/sb_mixer.h6
-rw-r--r--drivers/sound/sequencer.c2444
-rw-r--r--drivers/sound/softoss.c134
-rw-r--r--drivers/sound/softoss.h4
-rw-r--r--drivers/sound/sound_calls.h58
-rw-r--r--drivers/sound/sound_config.h54
-rw-r--r--drivers/sound/sound_firmware.c1
-rw-r--r--drivers/sound/sound_switch.c734
-rw-r--r--drivers/sound/sound_syms.c16
-rw-r--r--drivers/sound/sound_timer.c344
-rw-r--r--drivers/sound/soundcard.c844
-rw-r--r--drivers/sound/soundmodule.h18
-rw-r--r--drivers/sound/sscape.c1016
-rw-r--r--drivers/sound/sys_timer.c146
-rw-r--r--drivers/sound/trix.c9
-rw-r--r--drivers/sound/uart401.c12
-rw-r--r--drivers/sound/uart6850.c217
-rw-r--r--drivers/sound/v_midi.c296
-rw-r--r--drivers/sound/v_midi.h15
72 files changed, 11214 insertions, 13988 deletions
diff --git a/drivers/sound/.cvsignore b/drivers/sound/.cvsignore
index 7c1f51961..88fff7fc4 100644
--- a/drivers/sound/.cvsignore
+++ b/drivers/sound/.cvsignore
@@ -1,4 +1,5 @@
.depend
+.*.flags
.defines
local.h
configure
diff --git a/drivers/sound/.objects b/drivers/sound/.objects
deleted file mode 100644
index e7880fcc2..000000000
--- a/drivers/sound/.objects
+++ /dev/null
@@ -1,99 +0,0 @@
-OBJS=
-
-ifdef CONFIG_AD1848
- OBJS := $(OBJS) ad1848.o
-endif
-
-ifdef CONFIG_YM3812
- OBJS := $(OBJS) adlib_card.o
-endif
-
-ifdef CONFIG_AUDIO
- OBJS := $(OBJS) audio.o
-endif
-
-ifdef CONFIG_CS4232
- OBJS := $(OBJS) cs4232.o
-endif
-
-ifdef CONFIG_AUDIO
- OBJS := $(OBJS) dmabuf.o
-endif
-
-ifdef CONFIG_GUSHW
- OBJS := $(OBJS) gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
-endif
-
-ifdef CONFIG_MAD16
- OBJS := $(OBJS) mad16.o
-endif
-
-ifdef CONFIG_MAUI
- OBJS := $(OBJS) maui.o
-endif
-
-ifdef CONFIG_MIDI
- OBJS := $(OBJS) midi_synth.o midibuf.o
-endif
-
-ifdef CONFIG_MPU401
- OBJS := $(OBJS) mpu401.o
-else
- ifdef CONFIG_MPU_EMU
- OBJS := $(OBJS) mpu401.o
- endif
-endif
-
-ifdef CONFIG_YM3812
- OBJS := $(OBJS) opl3.o
-endif
-
-ifdef CONFIG_PAS
- OBJS := $(OBJS) pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
-endif
-
-ifdef CONFIG_PSS
- OBJS := $(OBJS) pss.o
-endif
-
-ifdef CONFIG_SBDSP
- OBJS := $(OBJS) sb_card.o sb_common.o sb_audio.o sb_mixer.o sb_midi.o
-endif
-
-ifdef CONFIG_SEQUENCER
- OBJS := $(OBJS) sequencer.o
-endif
-
-
-ifdef CONFIG_SEQUENCER
- OBJS := $(OBJS) sound_timer.o
-endif
-
-ifdef CONFIG_SSCAPEHW
- OBJS := $(OBJS) sscape.o
-endif
-
-ifdef CONFIG_TRIX
- OBJS := $(OBJS) trix.o
-endif
-
-ifdef CONFIG_SEQUENCER
- OBJS := $(OBJS) sys_timer.o
-endif
-
-ifdef CONFIG_UART6850
- OBJS := $(OBJS) uart6850.o
-endif
-
-ifdef CONFIG_UART401
- OBJS := $(OBJS) uart401.o
-endif
-
-ifdef CONFIG_OPL3SA1
- OBJS := $(OBJS) opl3sa.o
-endif
-
-ifdef CONFIG_SOFTOSS
- OBJS := $(OBJS) softoss.o softoss_rs.o
-endif
-
diff --git a/drivers/sound/Config.in b/drivers/sound/Config.in
index 80b8bd37e..7ef5f8dd4 100644
--- a/drivers/sound/Config.in
+++ b/drivers/sound/Config.in
@@ -1,150 +1,160 @@
dep_tristate 'ProAudioSpectrum 16 support' CONFIG_PAS $CONFIG_SOUND
-dep_tristate '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SB $CONFIG_SOUND
-dep_tristate 'Generic OPL2/OPL3 FM synthesizer support' CONFIG_ADLIB $CONFIG_SOUND
-dep_tristate 'Gravis Ultrasound support' CONFIG_GUS $CONFIG_SOUND
-if [ "$CONFIG_GUS" != "n" ]; then
- bool '16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16
- bool 'GUS MAX support' CONFIG_GUSMAX
-fi
-dep_tristate 'MPU-401 support (NOT for SB16)' CONFIG_MPU401 $CONFIG_SOUND
-dep_tristate 'PSS (ECHO-ADI2111) support' CONFIG_PSS $CONFIG_SOUND
-dep_tristate 'Microsoft Sound System support' CONFIG_MSS $CONFIG_SOUND
-dep_tristate 'Ensoniq SoundScape support' CONFIG_SSCAPE $CONFIG_SOUND
-dep_tristate 'MediaTrix AudioTrix Pro support' CONFIG_TRIX $CONFIG_SOUND
-dep_tristate 'Support for OPTi MAD16 and/or Mozart based cards' CONFIG_MAD16 $CONFIG_SOUND
-dep_tristate 'Support for Crystal CS4232 based (PnP) cards' CONFIG_CS4232 $CONFIG_SOUND
-dep_tristate 'Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_MAUI $CONFIG_SOUND
-dep_tristate 'Yamaha OPL3-SA1 audio controller' CONFIG_OPL3SA1 $CONFIG_SOUND
-dep_tristate 'SoftOSS software wave table engine' CONFIG_SOFTOSS $CONFIG_SOUND
-dep_tristate 'FM synthesizer (YM3812/OPL-3) support' CONFIG_YM3812 $CONFIG_SOUND
-
-if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then
- hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220
+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
fi
-if [ "$CONFIG_SB" = "y" -o "$CONFIG_SB" = "m" ]; then
- hex 'I/O base for SB Check from manual of the card' SBC_BASE 220
- int 'Sound Blaster IRQ Check from manual of the card' SBC_IRQ 7
- int 'Sound Blaster DMA 0, 1 or 3' SBC_DMA 1
- int 'Sound Blaster 16 bit DMA (SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' SB_DMA2 5
- hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' SB_MPU_BASE 330
+dep_tristate '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SB $CONFIG_SOUND
+if [ "$CONFIG_SB" = "y" ]; then
+ 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
+ int 'Sound Blaster 16 bit DMA (SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' CONFIG_SB_DMA2 5
+ hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' CONFIG_SB_MPU_BASE 330
comment 'MPU401 IRQ is only required with Jazz16, SM Wave and ESS1688.'
comment 'Enter -1 to the following question if you have something else such as SB16/32.'
- int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Check from manual of the card' SB_MPU_IRQ -1
+ int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Check from manual of the card' CONFIG_SB_MPU_IRQ -1
fi
-if [ "$CONFIG_PAS" = "y" -o "$CONFIG_PAS" = "m" ]; then
- int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' PAS_IRQ 10
- int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' PAS_DMA 3
-fi
+dep_tristate 'Generic OPL2/OPL3 FM synthesizer support' CONFIG_ADLIB $CONFIG_SOUND
-if [ "$CONFIG_GUS" = "y" -o "$CONFIG_GUS" = "m" ]; then
- hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' GUS_BASE 220
- int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' GUS_IRQ 15
- int 'GUS DMA 1, 3, 5, 6 or 7' GUS_DMA 6
- int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' GUS_DMA2 -1
+dep_tristate 'Gravis Ultrasound support' CONFIG_GUS $CONFIG_SOUND
+if [ "$CONFIG_GUS" != "n" ]; then
+ bool '16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16
+ bool 'GUS MAX support' CONFIG_GUSMAX
+ if [ "$CONFIG_GUS" = "y" ]; then
+ hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' CONFIG_GUS_BASE 220
+ int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' CONFIG_GUS_IRQ 15
+ int 'GUS DMA 1, 3, 5, 6 or 7' CONFIG_GUS_DMA 6
+ int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' CONFIG_GUS_DMA2 -1
+ if [ "$CONFIG_GUS16" = "y" ]; then
+ hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' CONFIG_GUS16_BASE 530
+ int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' CONFIG_GUS16_IRQ 7
+ int 'GUS DMA 0, 1 or 3' CONFIG_GUS16_DMA 3
+ fi
+ fi
fi
-if [ "$CONFIG_GUS16" = "y" ]; then
- hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' GUS16_BASE 530
- int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' GUS16_IRQ 7
- int 'GUS DMA 0, 1 or 3' GUS16_DMA 3
+dep_tristate 'MPU-401 support (NOT for SB16)' CONFIG_MPU401 $CONFIG_SOUND
+if [ "$CONFIG_MPU401" = "y" ]; then
+ hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330
+ int 'MPU401 IRQ Check from manual of the card' CONFIG_MPU_IRQ 9
fi
-if [ "$CONFIG_MPU401" = "y" -o "$CONFIG_MPU401" = "m" ]; then
- hex 'I/O base for MPU401 Check from manual of the card' MPU_BASE 330
- int 'MPU401 IRQ Check from manual of the card' MPU_IRQ 9
+dep_tristate 'PSS (ECHO-ADI2111) 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
+ int 'PSS audio IRQ 7, 9, 10 or 11' CONFIG_PSS_MSS_IRQ 11
+ int 'PSS audio DMA 0, 1 or 3' CONFIG_PSS_MSS_DMA 3
+ hex 'PSS MIDI I/O base ' CONFIG_PSS_MPU_BASE 330
+ int 'PSS MIDI IRQ 3, 4, 5, 7 or 9' CONFIG_PSS_MPU_IRQ 9
+ bool ' Have DSPxxx.LD firmware file' CONFIG_PSS_HAVE_BOOT
+ if [ "$CONFIG_PSS_HAVE_BOOT" = "y" ]; then
+ string ' Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE
+ fi
fi
-if [ "$CONFIG_MAUI" = "y" -o "$CONFIG_MAUI" = "M" ]; then
- comment 'ERROR! You have to use old sound configuration method with Maui.'
- hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' MAUI_BASE 330
- int 'Maui IRQ 5, 9, 12 or 15' MAUI_IRQ 9
+dep_tristate 'Microsoft Sound System support' CONFIG_MSS $CONFIG_SOUND
+if [ "$CONFIG_MSS" = "y" ]; then
+ hex 'MSS/WSS I/O base 530, 604, E80 or F40' CONFIG_MSS_BASE 530
+ int 'MSS/WSS IRQ 7, 9, 10 or 11' CONFIG_MSS_IRQ 11
+ int 'MSS/WSS DMA 0, 1 or 3' CONFIG_MSS_DMA 3
+ int 'MSS/WSS second DMA (if possible) 0, 1 or 3' CONFIG_MSS_DMA2 -1
fi
-if [ "$CONFIG_UART6850" = "y" -o "$CONFIG_UART6850" = "m" ]; then
- hex 'I/O base for UART 6850 MIDI port (Unknown)' U6850_BASE 0
- int 'UART6850 IRQ (Unknown)' U6850_IRQ -1
+dep_tristate 'Ensoniq SoundScape support' CONFIG_SSCAPE $CONFIG_SOUND
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+ hex 'SoundScape MIDI I/O base 320, 330, 340 or 350' CONFIG_SSCAPE_BASE 330
+ int 'SoundScape MIDI IRQ ' CONFIG_SSCAPE_IRQ 9
+ int 'SoundScape initialization DMA 0, 1 or 3' CONFIG_SSCAPE_DMA 3
+ hex 'SoundScape audio I/O base 534, 608, E84 or F44' CONFIG_SSCAPE_MSS_BASE 534
+ int 'SoundScape audio IRQ 7, 9, 10 or 11' CONFIG_SSCAPE_MSS_IRQ 11
fi
-if [ "$CONFIG_PSS" = "y" -o "$CONFIG_PSS" = "y" ]; then
- comment 'ERROR! You have to use old sound configuration method with PSS cards.'
- hex 'PSS I/O base 220 or 240' PSS_BASE 220
- hex 'PSS audio I/O base 530, 604, E80 or F40' PSS_MSS_BASE 530
- int 'PSS audio IRQ 7, 9, 10 or 11' PSS_MSS_IRQ 11
- int 'PSS audio DMA 0, 1 or 3' PSS_MSS_DMA 3
- hex 'PSS MIDI I/O base ' PSS_MPU_BASE 330
- int 'PSS MIDI IRQ 3, 4, 5, 7 or 9' PSS_MPU_IRQ 9
+dep_tristate 'MediaTrix AudioTrix Pro support' CONFIG_TRIX $CONFIG_SOUND
+if [ "$CONFIG_TRIX" = "y" ]; then
+ hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' CONFIG_TRIX_BASE 530
+ int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' CONFIG_TRIX_IRQ 11
+ int 'OPL3-SA1 audio DMA 0, 1 or 3' CONFIG_TRIX_DMA 0
+ int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' CONFIG_TRIX_DMA2 3
+ hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_TRIX_MPU_BASE 330
+ int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' CONFIG_TRIX_MPU_IRQ 9
+ hex 'OPL3-SA1 SB I/O base 220, 210, 230, 240, 250, 260 or 270' CONFIG_TRIX_SB_BASE 220
+ int 'OPL3-SA1 SB IRQ 3, 4, 5 or 7' CONFIG_TRIX_SB_IRQ 7
+ int 'OPL3-SA1 SB DMA 1 or 3' CONFIG_TRIX_SB_DMA 1
+ bool ' Have TRXPRO.HEX firmware file' CONFIG_TRIX_HAVE_BOOT
+ if [ "$CONFIG_TRIX_HAVE_BOOT" = "y" ]; then
+ string ' Full pathname of TRXPRO.HEX firmware file' CONFIG_TRIX_BOOT_FILE
+ fi
fi
-if [ "$CONFIG_MSS" = "y" -o "$CONFIG_MSS" = "m" ]; then
- hex 'MSS/WSS I/O base 530, 604, E80 or F40' MSS_BASE 530
- int 'MSS/WSS IRQ 7, 9, 10 or 11' MSS_IRQ 11
- int 'MSS/WSS DMA 0, 1 or 3' MSS_DMA 3
- int 'MSS/WSS second DMA (if possible) 0, 1 or 3' MSS_DMA2 -1
+dep_tristate 'Support for OPTi MAD16 and/or Mozart based cards' CONFIG_MAD16 $CONFIG_SOUND
+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
+ int 'MAD16 audio DMA 0, 1 or 3' CONFIG_MAD16_DMA 3
+ int 'MAD16 second (duplex) DMA 0, 1 or 3' CONFIG_MAD16_DMA2 0
+ hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' CONFIG_MAD16_MPU_BASE 330
+ int 'MAD16 MIDI IRQ 5, 7, 9 or 10' CONFIG_MAD16_MPU_IRQ 9
fi
-if [ "$CONFIG_SSCAPE" = "y" -o "$CONFIG_SSCAPE" = "m" ]; then
- hex 'SoundScape MIDI I/O base 320, 330, 340 or 350' SSCAPE_BASE 330
- int 'SoundScape MIDI IRQ ' SSCAPE_IRQ 9
- int 'SoundScape initialization DMA 0, 1 or 3' SSCAPE_DMA 3
- hex 'SoundScape audio I/O base 534, 608, E84 or F44' SSCAPE_MSS_BASE 534
- int 'SoundScape audio IRQ 7, 9, 10 or 11' SSCAPE_MSS_IRQ 11
+dep_tristate 'Support for Crystal CS4232 based (PnP) cards' CONFIG_CS4232 $CONFIG_SOUND
+if [ "$CONFIG_CS4232" = "y" ]; then
+ hex 'CS4232 audio I/O base 530, 604, E80 or F40' CONFIG_CS4232_BASE 530
+ int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_IRQ 11
+ int 'CS4232 audio DMA 0, 1 or 3' CONFIG_CS4232_DMA 0
+ int 'CS4232 second (duplex) DMA 0, 1 or 3' CONFIG_CS4232_DMA2 3
+ hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_CS4232_MPU_BASE 330
+ int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_MPU_IRQ 9
fi
-if [ "$CONFIG_TRIX" = "y" -o "$CONFIG_TRIX" = "m" ]; then
- comment 'ERROR! You have to use old sound configuration method with OPL3-SA1.'
- hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' TRIX_BASE 530
- int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' TRIX_IRQ 11
- int 'OPL3-SA1 audio DMA 0, 1 or 3' TRIX_DMA 0
- int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' TRIX_DMA2 3
- hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' TRIX_MPU_BASE 330
- int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' TRIX_MPU_IRQ 9
- hex 'OPL3-SA1 SB I/O base 220, 210, 230, 240, 250, 260 or 270' TRIX_SB_BASE 220
- int 'OPL3-SA1 SB IRQ 3, 4, 5 or 7' TRIX_SB_IRQ 7
- int 'OPL3-SA1 SB DMA 1 or 3' TRIX_SB_DMA 1
+dep_tristate 'Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_MAUI $CONFIG_SOUND
+if [ "$CONFIG_MAUI" = "y" ]; then
+ hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_MAUI_BASE 330
+ int 'Maui IRQ 5, 9, 12 or 15' CONFIG_MAUI_IRQ 9
+ bool ' Have OSWF.MOT firmware file' CONFIG_MAUI_HAVE_BOOT
+ if [ "$CONFIG_MAUI_HAVE_BOOT" = "y" ]; then
+ string ' Full pathname of OSWF.MOT firmware file' CONFIG_MAUI_BOOT_FILE
+ fi
fi
-if [ "$CONFIG_OPL3SA1" = "y" -o "$CONFIG_OPL3SA1" = "m" ]; then
- hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' OPL3SA1_BASE 530
- int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' OPL3SA1_IRQ 11
- int 'OPL3-SA1 audio DMA 0, 1 or 3' OPL3SA1_DMA 0
- int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' OPL3SA1_DMA2 3
- hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' OPL3SA1_MPU_BASE 330
- int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' OPL3SA1_MPU_IRQ 9
+dep_tristate 'Yamaha OPL3-SA1 audio controller' CONFIG_OPL3SA1 $CONFIG_SOUND
+if [ "$CONFIG_OPL3SA1" = "y" ]; then
+ hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' CONFIG_OPL3SA1_BASE 530
+ int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' CONFIG_OPL3SA1_IRQ 11
+ int 'OPL3-SA1 audio DMA 0, 1 or 3' CONFIG_OPL3SA1_DMA 0
+ int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA1_DMA2 3
+ hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_OPL3SA1_MPU_BASE 330
+ int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' CONFIG_OPL3SA1_MPU_IRQ 9
fi
-if [ "$CONFIG_CS4232" = "y" -o "$CONFIG_CS4232" = "m" ]; then
- hex 'CS4232 audio I/O base 530, 604, E80 or F40' CS4232_BASE 530
- int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CS4232_IRQ 11
- int 'CS4232 audio DMA 0, 1 or 3' CS4232_DMA 0
- int 'CS4232 second (duplex) DMA 0, 1 or 3' CS4232_DMA2 3
- hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CS4232_MPU_BASE 330
- int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CS4232_MPU_IRQ 9
+dep_tristate 'SoftOSS software wave table engine' CONFIG_SOFTOSS $CONFIG_SOUND
+if [ "$CONFIG_SOFTOSS" = "y" ]; then
+ int 'Sampling rate for SoftOSS 8000 to 48000' CONFIG_SOFTOSS_RATE 22050
+ int 'Max # of concurrent voices for SoftOSS 4 to 32' CONFIG_SOFTOSS_VOICES 32
fi
-if [ "$CONFIG_MAD16" = "y" -o "$CONFIG_MAD16" = "m" ]; then
- hex 'MAD16 audio I/O base 530, 604, E80 or F40' MAD16_BASE 530
- int 'MAD16 audio IRQ 7, 9, 10 or 11' MAD16_IRQ 11
- int 'MAD16 audio DMA 0, 1 or 3' MAD16_DMA 3
- int 'MAD16 second (duplex) DMA 0, 1 or 3' MAD16_DMA2 0
- hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' MAD16_MPU_BASE 330
- int 'MAD16 MIDI IRQ 5, 7, 9 or 10' MAD16_MPU_IRQ 9
-fi
+dep_tristate 'FM synthesizer (YM3812/OPL-3) support' CONFIG_YM3812 $CONFIG_SOUND
+dep_tristate 'Loopback MIDI device support' CONFIG_VMIDI $CONFIG_SOUND
-if [ "$CONFIG_SOFTOSS" = "y" -o "$CONFIG_SOFTOSS" = "m" ]; then
- int 'Sampling rate for SoftOSS 8000 to 48000' SOFTOSS_RATE 22050
- int 'Max # of concurrent voices for SoftOSS 4 to 32' SOFTOSS_VOICES 32
+dep_tristate '6850 UART support' CONFIG_UART6850 $CONFIG_SOUND
+if [ "$CONFIG_UART6850" = "y" ]; then
+ hex 'I/O base for UART 6850 MIDI port (Unknown)' CONFIG_U6850_BASE 0
+ int 'UART6850 IRQ (Unknown)' CONFIG_U6850_IRQ -1
fi
-#
-$MAKE -C drivers/sound kernelconfig || exit 1
+
bool 'Additional low level drivers' CONFIG_LOWLEVEL_SOUND
if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
dep_tristate 'ACI mixer (miroPCM12)' CONFIG_ACI_MIXER $CONFIG_SOUND
dep_tristate 'AWE32 synth' CONFIG_AWE32_SYNTH $CONFIG_SOUND
- bool 'Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16
+ dep_tristate 'Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16 $CONFIG_SOUND
+
+ if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then
+ hex ' I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220
+ fi
if [ "$CONFIG_AEDSP16" = "y" ]; then
comment 'SC-6600 Audio Cards have no jumper switches at all'
@@ -155,10 +165,10 @@ if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
if [ "$CONFIG_AEDSP16_SBPRO" = "y" ]; then
comment 'Audio Excel DSP 16 [Sound Blaster Pro]'
hex 'I/O base for Audio Excel DSP 16 220 or 240' \
- AEDSP16_BASE $SBC_BASE
+ CONFIG_AEDSP16_BASE $CONFIG_SB_BASE
int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' \
- AEDSP16_SBC_IRQ $SBC_IRQ
- int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_SBC_DMA $SBC_DMA
+ CONFIG_AEDSP16_SB_IRQ $CONFIG_SB_IRQ
+ int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_SB_DMA $CONFIG_SB_DMA
fi
fi
@@ -166,10 +176,10 @@ if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
bool 'Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS
if [ "$CONFIG_AEDSP16_MSS" = "y" ]; then
comment 'Audio Excel DSP 16 [Microsoft Sound System]'
- hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220
+ hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220
int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' \
- AEDSP16_MSS_IRQ $MSS_IRQ
- int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_MSS_DMA $MSS_DMA
+ CONFIG_AEDSP16_MSS_IRQ $CONFIG_MSS_IRQ
+ int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_MSS_DMA $CONFIG_MSS_DMA
fi
fi
@@ -179,12 +189,17 @@ if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
comment 'Audio Excel DSP 16 [MPU-401]'
if [ "$CONFIG_AEDSP16_SBPRO" != "y" \
-a "$CONFIG_AEDSP16_MSS" != "y" ]; then
- hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220
+ hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220
fi
int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' \
- AEDSP16_MPU_IRQ $MPU_IRQ
+ CONFIG_AEDSP16_MPU_IRQ $CONFIG_MPU_IRQ
fi
fi
+ fi
+
+ if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then
+ comment 'SC-6600 Audio Cards have no jumper switches at all'
+ bool 'SC-6600 based audio cards (new Audio Excel DSP 16)' CONFIG_SC6600
if [ "$CONFIG_SC6600" = "y" ]; then
comment 'SC-6600 specific configuration'
@@ -193,7 +208,6 @@ if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
CONFIG_SC6600_CDROM 4
hex 'SC-6600 CDROM Interface I/O Address' CONFIG_SC6600_CDROMBASE 0
fi
-
fi
fi
diff --git a/drivers/sound/Config.std b/drivers/sound/Config.std
deleted file mode 100644
index 310bf01bf..000000000
--- a/drivers/sound/Config.std
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Sound driver configuration
-#
-#--------
-# There is another confic script which is compatible with rest of
-# the kernel. It can be activated by running 'make mkscript' in this
-# directory. Please note that this is an _experimental_ feature which
-# doesn't work with all cards (PSS, SM Wave, AudioTriX Pro, Maui).
-#--------
-#
-$MAKE -C drivers/sound config || exit 1
-
-bool 'Additional low level drivers' CONFIG_LOWLEVEL_SOUND
-
-if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
- bool 'ACI mixer (miroPCM12)' CONFIG_ACI_MIXER
- bool 'AWE32 synth' CONFIG_AWE32_SYNTH
- bool 'Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16
-
- if [ "$CONFIG_AEDSP16" = "y" ]; then
- comment 'SC-6600 Audio Cards have no jumper switches at all'
- bool 'SC-6600 based audio cards (new Audio Excel DSP 16)' CONFIG_SC6600
-
- if [ "$CONFIG_SB" = "y" -a "$CONFIG_AEDSP16_MSS" != "y" ]; then
- bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO
- if [ "$CONFIG_AEDSP16_SBPRO" = "y" ]; then
- comment 'Audio Excel DSP 16 [Sound Blaster Pro]'
- hex 'I/O base for Audio Excel DSP 16 220 or 240' \
- AEDSP16_BASE $SBC_BASE
- int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' \
- AEDSP16_SBC_IRQ $SBC_IRQ
- int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_SBC_DMA $SBC_DMA
- fi
- fi
-
- if [ "$CONFIG_MSS" = "y" -a "$CONFIG_AEDSP16_SBPRO" != "y" ]; then
- bool 'Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS
- if [ "$CONFIG_AEDSP16_MSS" = "y" ]; then
- comment 'Audio Excel DSP 16 [Microsoft Sound System]'
- hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220
- int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' \
- AEDSP16_MSS_IRQ $MSS_IRQ
- int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_MSS_DMA $MSS_DMA
- fi
- fi
-
- if [ "$CONFIG_MPU401" = "y" ]; then
- bool 'Audio Excel DSP 16 (MPU401 emulation)' CONFIG_AEDSP16_MPU401
- if [ "$CONFIG_AEDSP16_MPU401" = "y" ]; then
- comment 'Audio Excel DSP 16 [MPU-401]'
- if [ "$CONFIG_AEDSP16_SBPRO" != "y" \
- -a "$CONFIG_AEDSP16_MSS" != "y" ]; then
- hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220
- fi
- int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' \
- AEDSP16_MPU_IRQ $MPU_IRQ
- fi
- fi
-
- if [ "$CONFIG_SC6600" = "y" ]; then
- comment 'SC-6600 specific configuration'
- bool 'Activate SC-6600 Joystick Interface' CONFIG_SC6600_JOY
- int 'SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?)' \
- CONFIG_SC6600_CDROM 4
- hex 'SC-6600 CDROM Interface I/O Address' CONFIG_SC6600_CDROMBASE 0
- fi
-
- fi
-fi
diff --git a/drivers/sound/Defines b/drivers/sound/Defines
new file mode 100644
index 000000000..6b9ef6bb6
--- /dev/null
+++ b/drivers/sound/Defines
@@ -0,0 +1,395 @@
+# This used to be a computer generated file, but it's not any more.
+# Edit all you need!
+
+ifdef CONFIG_PSS
+ifneq ($(CONFIG_MPU_EMU),Y)
+CONFIG_MPU_EMU=y
+endif
+endif
+
+ifdef CONFIG_SSCAPE
+ifneq ($(CONFIG_MPU_EMU),Y)
+CONFIG_MPU_EMU=y
+endif
+endif
+
+ifdef CONFIG_CS4232
+ifneq ($(CONFIG_MPU_EMU),Y)
+CONFIG_MPU_EMU=y
+endif
+endif
+
+ifdef CONFIG_MAUI
+ifneq ($(CONFIG_MPU_EMU),Y)
+CONFIG_MPU_EMU=y
+endif
+endif
+
+ifdef CONFIG_PSS
+ifneq ($(CONFIG_AD1848),Y)
+CONFIG_AD1848=y
+endif
+endif
+
+ifdef CONFIG_GUS16
+ifneq ($(CONFIG_AD1848),Y)
+CONFIG_AD1848=y
+endif
+endif
+
+ifdef CONFIG_GUSMAX
+ifneq ($(CONFIG_AD1848),Y)
+CONFIG_AD1848=y
+endif
+endif
+
+ifdef CONFIG_MSS
+ifneq ($(CONFIG_AD1848),Y)
+CONFIG_AD1848=y
+endif
+endif
+
+ifdef CONFIG_SSCAPE
+ifneq ($(CONFIG_AD1848),Y)
+CONFIG_AD1848=y
+endif
+endif
+
+ifdef CONFIG_TRIX
+ifneq ($(CONFIG_AD1848),Y)
+CONFIG_AD1848=y
+endif
+endif
+
+ifdef CONFIG_MAD16
+ifneq ($(CONFIG_AD1848),Y)
+CONFIG_AD1848=y
+endif
+endif
+
+ifdef CONFIG_CS4232
+ifneq ($(CONFIG_AD1848),Y)
+CONFIG_AD1848=y
+endif
+endif
+
+ifdef CONFIG_OPL3SA1
+ifneq ($(CONFIG_AD1848),Y)
+CONFIG_AD1848=y
+endif
+endif
+
+ifdef CONFIG_SB
+ifneq ($(CONFIG_SBDSP),Y)
+CONFIG_SBDSP=y
+endif
+endif
+
+ifdef CONFIG_TRIX
+ifneq ($(CONFIG_SBDSP),Y)
+CONFIG_SBDSP=y
+endif
+endif
+
+ifdef CONFIG_MAD16
+ifneq ($(CONFIG_SBDSP),Y)
+CONFIG_SBDSP=y
+endif
+endif
+
+
+
+ifdef CONFIG_SB
+ ifeq ($(CONFIG_SB),m)
+ ifneq ($(CONFIG_UART401),Y)
+ CONFIG_UART401=m
+ endif
+ else
+ ifneq ($(CONFIG_UART401),Y)
+ CONFIG_UART401=y
+ endif
+ endif
+endif
+
+ifdef CONFIG_TRIX
+ifneq ($(CONFIG_UART401),Y)
+CONFIG_UART401=y
+endif
+endif
+
+ifdef CONFIG_MAD16
+ifneq ($(CONFIG_UART401),Y)
+CONFIG_UART401=y
+endif
+endif
+
+ifdef CONFIG_OPL3SA1
+ifneq ($(CONFIG_UART401),Y)
+CONFIG_UART401=y
+endif
+endif
+
+ifdef CONFIG_PAS
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_SB
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_ADLIB
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_GUS
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_MPU401
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_PSS
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_GUS16
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_GUSMAX
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_MSS
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_SSCAPE
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_TRIX
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_MAD16
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_CS4232
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_MAUI
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_OPL3SA1
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_SOFTOSS
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_YM3812_AUTO
+ifneq ($(CONFIG_SEQUENCER),Y)
+CONFIG_SEQUENCER=y
+endif
+endif
+
+ifdef CONFIG_PAS
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_SB
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_GUS
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_PSS
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_GUS16
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_GUSMAX
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_MSS
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_SSCAPE
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_TRIX
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_MAD16
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_CS4232
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_OPL3SA1
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_SOFTOSS
+ifneq ($(CONFIG_AUDIO),Y)
+CONFIG_AUDIO=y
+endif
+endif
+
+ifdef CONFIG_PAS
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_SB
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_GUS
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_MPU401
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_PSS
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_GUS16
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_GUSMAX
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_SSCAPE
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_TRIX
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_MAD16
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_CS4232
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_MAUI
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_OPL3SA1
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
+ifdef CONFIG_SOFTOSS
+ifneq ($(CONFIG_MIDI),Y)
+CONFIG_MIDI=y
+endif
+endif
+
diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile
index fb81925b2..e8ec0b12d 100644
--- a/drivers/sound/Makefile
+++ b/drivers/sound/Makefile
@@ -24,21 +24,9 @@ ifeq ($(ARCH),m68k)
clean:
rm -f core *.o *.a *.s
- # dummy rule to keep 'make xconfig' happy
- mkscript:
-
-# More dummy targets for make [menu]config
-mkscript:
-kernelconfig:
-
else
-ifeq (.defines,$(wildcard .defines))
-include .defines
-#include .objects
-endif
-
-TARGET_OS=linux
+include Defines
ifndef TOPDIR
TOPDIR=/usr/src/linux
@@ -53,11 +41,11 @@ M_OBJS :=
L_OBJS :=
ifeq ($(CONFIG_SOUND),y)
- L_OBJS += soundcard.o dev_table.o sound_switch.o sequencer.o sys_timer.o sound_timer.o lowlevel/lowlevel.o midi_synth.o midibuf.o sound_firmware.o audio.o dmabuf.o
+ L_OBJS += soundcard.o dev_table.o sequencer.o sys_timer.o sound_timer.o lowlevel/lowlevel.o midi_synth.o midibuf.o sound_firmware.o audio.o dmabuf.o
else
ifeq ($(CONFIG_SOUND),m)
M_OBJS += sound.o
- MX_OBJS += sound_syms.o
+ MIX_OBJS += sound_syms.o
endif
endif
@@ -90,18 +78,26 @@ ifeq ($(CONFIG_GUS),y)
L_OBJS += gus.o
else
ifeq ($(CONFIG_GUS),m)
- M_OBJS += gus.o
+ M_OBJS += gus.o
+ endif
+ ifeq ($(CONFIG_GUSMAX),y)
+ ifneq ($(CONFIG_MSS),y)
+ CONFIG_MSS = m
+ endif
endif
endif
ifeq ($(CONFIG_SB),y)
L_OBJS += sb_audio.o sb_common.o sb_midi.o sb_mixer.o
-LX_OBJS += sb_card.o uart401.o
+LX_OBJS += sb_card.o
+CONFIG_UART401 = y
else
ifeq ($(CONFIG_SB),m)
M_OBJS += sb.o
- MX_OBJS += uart401.o
MIX_OBJS += sb_card.o
+ ifneq ($(CONFIG_UART401),y)
+ CONFIG_UART401 = m
+ endif
endif
endif
@@ -181,7 +177,8 @@ ifeq ($(CONFIG_MAD16),y)
L_OBJS += mad16.o
else
ifeq ($(CONFIG_MAD16),m)
- M_OBJS += mad16.o
+ M_OBJS += mad16.o sb.o uart401.o
+ MX_OBJS += sb_card.o ad1848.o
endif
endif
@@ -219,6 +216,14 @@ else
endif
endif
+ifeq ($(CONFIG_VMIDI),y)
+L_OBJS += v_midi.o
+else
+ ifeq ($(CONFIG_VMIDI),m)
+ M_OBJS += v_midi.o
+ endif
+endif
+
include $(TOPDIR)/Rules.make
softoss2.o: softoss.o softoss_rs.o
@@ -233,42 +238,88 @@ 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 sound_switch.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 sound_switch.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
+ 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
- rm 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
-kernelconfig: setup
- rm -f configure
- $(HOSTCC) -o configure configure.c
- ./configure fixedlocal > local.h
- ./configure fixeddefines > .defines
- @echo \#define SOUND_CONFIG_DATE \"`date`\" >> local.h
- @echo \#define SOUND_CONFIG_BY \"`whoami`\" >> local.h
-# @echo \#define SOUND_CONFIG_HOST \"`hostname`\" >> local.h 2>/dev/null
-# @echo \#define SOUND_CONFIG_DOMAIN \"`hostname -d`\" >> local.h 2>/dev/null
- @echo \#define SOUND_UNAME_A \"`uname -a`\" >> local.h
-
-configure: configure.c
- $(HOSTCC) -o configure configure.c
- @cat .blurb
-
-setup:
- @echo Compiling Sound Driver v $(VERSION) for Linux
-
-mkscript:
-
-config: configure
- @$(MAKE) setup
- @./configure > local.h
- @echo \#define SOUND_CONFIG_DATE \"`date`\" >> local.h
- @echo \#define SOUND_CONFIG_BY \"`whoami`\" >> local.h
-# @echo \#define SOUND_CONFIG_HOST \"`hostname`\" >> local.h 2>/dev/null
-# @echo \#define SOUND_CONFIG_DOMAIN \"`hostname -d`\" >> local.h 2>/dev/null
- @echo \#define SOUND_UNAME_A \"`uname -a`\" >> local.h
+# Firmware files that need translation
+#
+# The translated files are protected by a file that keeps track
+# of what name was used to build them. If the name changes, they
+# will be forced to be remade.
+
+bin2hex: bin2hex.c
+ $(HOSTCC) -o bin2hex bin2hex.c
+
+hex2hex: hex2hex.c
+ $(HOSTCC) -o hex2hex hex2hex.c
+ifeq ($(CONFIG_MAUI_HAVE_BOOT),y)
+
+CONFIG_MAUI_BOOT_FILE := $(patsubst "%", %, $(CONFIG_MAUI_BOOT_FILE))
+
+maui.o: maui_boot.h
+
+maui_boot.h: $(CONFIG_MAUI_BOOT_FILE) bin2hex
+ bin2hex maui_os < "$(CONFIG_MAUI_BOOT_FILE)" > $@
+ @ ( \
+ echo 'ifeq ($(strip $(CONFIG_MAUI_BOOT_FILE)),$$(strip $$(CONFIG_MAUI_BOOT_FILE)))'; \
+ echo 'FILES_BOOT_UP_TO_DATE += $@'; \
+ echo 'endif' \
+ ) > .$@.boot
+
+endif
+
+ifeq ($(CONFIG_PSS_HAVE_BOOT),y)
+
+CONFIG_PSS_BOOT_FILE := $(patsubst "%", %, $(CONFIG_PSS_BOOT_FILE))
+
+pss.o: pss_boot.h
+
+pss_boot.h: $(CONFIG_PSS_BOOT_FILE) bin2hex
+ bin2hex pss_synth < "$(CONFIG_PSS_BOOT_FILE)" > $@
+ @ ( \
+ echo 'ifeq ($(strip $(CONFIG_PSS_BOOT_FILE)),$$(strip $$(CONFIG_PSS_BOOT_FILE)))'; \
+ echo 'FILES_BOOT_UP_TO_DATE += $@'; \
+ echo 'endif' \
+ ) > .$@.boot
+
+endif
+
+ifeq ($(CONFIG_TRIX_HAVE_BOOT),y)
+
+CONFIG_TRIX_BOOT_FILE := $(patsubst "%", %, $(CONFIG_TRIX_BOOT_FILE))
+
+trix.o: trix_boot.h
+
+trix_boot.h: $(CONFIG_TRIX_BOOT_FILE) hex2hex
+ hex2hex trix_boot < "$(CONFIG_TRIX_BOOT_FILE)" > $@
+ @ ( \
+ echo 'ifeq ($(strip $(CONFIG_TRIX_BOOT_FILE)),$$(strip $$(CONFIG_TRIX_BOOT_FILE)))'; \
+ echo 'FILES_BOOT_UP_TO_DATE += $@'; \
+ echo 'endif' \
+ ) > .$@.boot
+
+endif
+
+# Find boot files whose source file names have changed and force rebuild.
+
+FILES_BOOT_UP_TO_DATE :=
+
+FILES_BOOT_EXIST := $(wildcard .*.boot)
+ifneq ($(FILES_BOOT_EXIST),)
+include $(FILES_BOOT_EXIST)
+endif
+
+FILES_BOOT_CHANGED := $(strip \
+ $(filter-out $(FILES_BOOT_UP_TO_DATE), \
+ maui_boot.h pss_boot.h trix_boot.h))
+
+ifneq ($(FILES_BOOT_CHANGED),)
+$(FILES_BOOT_CHANGED): dummy
+endif
endif
diff --git a/drivers/sound/README.C931 b/drivers/sound/README.C931
new file mode 100644
index 000000000..e6f72be7e
--- /dev/null
+++ b/drivers/sound/README.C931
@@ -0,0 +1,62 @@
+Support for the OPTI 82C931 chip
+--------------------------------
+
+The opti 82C931 is supported in it's non PnP mode.
+You do not need to set jumpers etc... The sound driver
+will check the card status and if it is required it will
+force the card into a mode that it can be programmed.
+
+To compile support for the OPTI 82C931 card you can use
+the regular Linux config menus (ie, "make xconfig").
+
+Sound card support should be enabled as a module (chose m).
+Enable (m) for these items:
+ 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support (CONFIG_SB)
+ Generic OPL2/OPL3 FM synthesizer support (CONFIG_ADLIB)
+ Microsoft Sound System support (CONFIG_MSS)
+ Support for OPTi MAD16 and/or Mozart based cards (CONFIG_MAD16)
+ FM synthesizer (YM3812/OPL-3) support (CONFIG_YM3812)
+
+The configuration menu may ask for addresses, irq lines or dma
+channels. If the card is used as a module the module loading
+options will override these values.
+
+Go on and compile your kernel and modules, install the modules.
+
+I use this configuration as part of /etc/conf.modules:
+
+options sb mad16=1
+options mad16 irq=10 dma=1 io=0x530 joystick=1 cdtype=0
+options opl3 io=0x388
+
+After installing everything and booting to a kernel that
+matches the modules you can load the sound driver:
+
+modprobe mad16
+modprobe opl3
+
+As a result these modules are loaded:
+Module Size Used by
+opl3 10416 0 (unused)
+mad16 6472 0
+sb 23544 0 [mad16]
+uart401 5796 0 [mad16 sb]
+ad1848 16532 1 [mad16]
+sound 82052 0 [opl3 mad16 sb uart401 ad1848]
+
+Known problems:
+1. The uart401 cannot be used. This is probably a problem which
+ was introduced when the sound driver was modularized.
+ Do not try to load uart401 with options (io=xxx, irq=yyy) because
+ it will try to initialize itself and fail.
+
+2. Cannot use the sound driver in Duplex mode. Until it is fixed
+ use only one DMA channel (0, 1 or 3) for mad16.
+
+3. Configuration of the cdrom adaptor on the sound card is not
+ tested and probably does not work.
+
+4. General problem with the modularized sound driver: If you
+ load part of the sound driver while a sound program is
+ running, stopping the program may result with a situation
+ where the "Used by" count becomes negative.
diff --git a/drivers/sound/.blurb b/drivers/sound/README.blurb
index 5203d3fbe..5203d3fbe 100644
--- a/drivers/sound/.blurb
+++ b/drivers/sound/README.blurb
diff --git a/drivers/sound/Readme.cards b/drivers/sound/Readme.cards
index dff774546..f8a9bf2ca 100644
--- a/drivers/sound/Readme.cards
+++ b/drivers/sound/Readme.cards
@@ -3,7 +3,7 @@ Configuring version 3.8 (for Linux) with some most common soundcards
This document describes configuring soundcards with freeware version of
Open Sound Systems (OSS/Free). Information about the commercial version
-(OSS/Linux) and it's configuration is available from
+(OSS/Linux) and its configuration is available from
http://www.opensound.com/linux.html. Information presented here is
not valid for OSS/Linux.
@@ -18,32 +18,8 @@ IMPORTANT! This document covers only cards that were "known" when
http://www.opensound.com/ossfree for info about
cards introduced recently.
- The following covers mainly the "old" configuration
- method (make config). Most of it is valid for the "new"
- configuration (make menuconfig/xconfig) too.
-
- Cards having some kind of loadable "microcode" such as
- PSS, SM Wave, AudioTrix Pro and Maui/Tropez must be
- configured using the old method. The new one will not
- work with them. The "old" method is used by default by
- "make config". "make xconfig" will always use the "new"
- method. "make menuconfig" will allow you to select which
- method to use. After you have used the "new" method once
- it will always be used when you use any of the config
- programs. To return back to the "old" method you should
- execute "cp Config.std Config.in" in linux/drivers/sound.
-
- The /etc/soundconf file (forget it if you don't know what
- this file does) contains settings that are used only by
- the "old" method. Don't ever think the "active" settings
- are stored there (they really are _NOT_ stored
- there). Don't try to edit /etc/soundconf or any other
- kernel or sound driver config files manually. The _only_
- proper ways to change the settings are make config or
- make menuconfig (the "old" method).
-
- When using make xconfig and/or make menuconfig, you should
- carefully check each sound configuration option (particularly
+ When configuring the sound driver, you should carefully
+ check each sound configuration option (particularly
"Support for /dev/dsp and /dev/audio"). The default values
offered by these programs are not necessarily valid.
@@ -91,7 +67,7 @@ to be the most common cause.
2. Trying to use a PnP (Plug & Play) card just like an ordinary soundcard
-------------------------------------------------------------------------
-Plug & Play is a protocol defined by Intel and Microsoft. It let's operating
+Plug & Play is a protocol defined by Intel and Microsoft. It lets operating
systems to easily identify and reconfigure I/O ports, IRQs and DMAs of ISA
cards. The problem with PnP cards is that the standard Linux doesn't currently
(versions 2.1.x and earlier) don't support PnP. This means that you will have
@@ -317,25 +293,26 @@ Yamaha OPL3-SA1
4Front Technologies SoftOSS
SoftOSS is a software based wave table emulation which works with
- any 16 bit stereo soundcard. Due to it's nature a fast CPU is
- required (P133 is minumum). Althoug SoftOSS doesn _not_ use MMX
+ any 16 bit stereo soundcard. Due to its nature a fast CPU is
+ required (P133 is minimum). Although SoftOSS does _not_ use MMX
instructions it has proven out that recent processors (which appear
to have MMX) perform significantly better with SoftOSS than earlier
ones. For example a P166MMX beats a PPro200. SoftOSS should not be used
on 486 or 386 machines.
- The amount of CPU load caused by SoftOSS can be controlled by
- selecting the SOFTOSS_RATE and SOFTOSS_VOICES parameters properly
- (they will be prompted by make config). It's recommended to set
- SOFTOSS_VOICES to 32. If you have a P166MMX or faster (PPro200 is
- not faster) you can set SOFTOSS_RATE to 44100 (kHz). However with
- slower systems it recommended to use sampling rates around 22050
- or even 16000 kHz. Selecting too high values for these parameters
- may hang your system when playing MIDI files with hight degree of
- polyphony (number of concurrently playing notes). It's also possible to
- decrease SOFTOSS_VOICES. This makes it possible to use higher sampling
- rates. However using fewer voices decreases playback quality more than
- decreasing the sampling rate.
+ The amount of CPU load caused by SoftOSS can be controlled by
+ selecting the CONFIG_SOFTOSS_RATE and CONFIG_SOFTOSS_VOICES
+ parameters properly (they will be prompted by make config). It's
+ recommended to set CONFIG_SOFTOSS_VOICES to 32. If you have a
+ P166MMX or faster (PPro200 is not faster) you can set
+ CONFIG_SOFTOSS_RATE to 44100 (kHz). However with slower systems it
+ recommended to use sampling rates around 22050 or even 16000 kHz.
+ Selecting too high values for these parameters may hang your
+ system when playing MIDI files with hight degree of polyphony
+ (number of concurrently playing notes). It's also possible to
+ decrease CONFIG_SOFTOSS_VOICES. This makes it possible to use
+ higher sampling rates. However using fewer voices decreases
+ playback quality more than decreasing the sampling rate.
SoftOSS keeps the samples loaded on system's RAM so large RAM is
required. SoftOSS should never be used on machines with less than 16M
@@ -354,7 +331,7 @@ Yamaha OPL3-SA1
*********************************************************************
IMPORTANT NOTICE! The original patch set distributed with Gravis
- Ultrasound card is not in public domain (even it's available from
+ Ultrasound card is not in public domain (even though it's available from
some ftp sites). You should contact Voice Crystal (www.voicecrystal.com)
if you like to use these patches with SoftOSS included in OSS/Free.
*********************************************************************
@@ -377,9 +354,6 @@ MediaTrix AudioTrix Pro
chips. The OPL4 mode is supported by a microcontroller running a
General MIDI emulator. There is also a SB 1.5 compatible playback mode.
- NOTE! You will have to use the "old" config script when configuring
- AudioTrix Pro.
-
Ensoniq SoundScape and compatibles
Ensoniq has designed a soundcard architecture based on the
OTTO synthesizer chip used in their professional MIDI synthesizers.
@@ -411,8 +385,8 @@ OPTi MAD16 and Mozart based cards
Audio Excel DSP16
Support for this card was written by Riccardo Faccetti
(riccardo@cdc8g5.cdc.polimi.it). The AEDSP16 driver included in
- the lowlevel/ directory. To use it you should use the "new" config
- script and to enable the "Additional low level drivers" option.
+ the lowlevel/ directory. To use it you should enable the
+ "Additional low level drivers" option.
Crystal CS4232 and CS4236 based cards such as AcerMagic S23, TB Tropez _Plus_ and
many PC motherboards (Compaq, HP, Intel, ...)
@@ -431,8 +405,6 @@ Turtle Beach Maui and Tropez "classic"
described in the Maui/Tropez User's manual.
There is now full initialization support too. The audio side of
the Tropez is based on the MAD16 chip (see above).
- NOTE! You will have to use the "old" config script when configuring
- Maui or Tropez.
NOTE! Tropez Plus is different card than Tropez "classic" and will not
work fully in Linux. You can get audio features working by configuring
the card as a CS4232 based card (above).
@@ -529,29 +501,20 @@ the kernel following instructions in the kernel README.
The sound driver configuration dialog
-------------------------------------
-All config information of the sound driver is written to file
-linux/drivers/sound/local.h. You may save the old version is this file and
-use it again in case you want to use the same config later. In this case
-just answer n to each question made by the sound config program and put
-the original local.h back before running "make dep".
-Don't do this if the version number of the sound driver has changed. In this
-case you have to enter the configuration information again.
-
If you already have the sound driver installed, consult printout of
"cat /dev/sndstat" when configuring the driver again. It gives the I/O,
IRQ and DMA settings you have used earlier.
-
-The sound config program (linux/drivers/sound/configure) starts by making
-some yes/no questions. Be careful when answering to these questions since
-answering y to a question may prevent some later ones from being asked. For
-example don't answer y to the first question (PAS16) if you don't really
-have a PAS16. Don't enable more cards than you really need since they
-just consume memory. Also some drivers (like MPU401) may conflict with your
-SCSI controller and prevent kernel from booting. If you card was in the list
-of supported cards (above), please look at the card specific config
-instructions (later in this file) before starting to configure. Some cards
-must be configured in way which is not obvious.
+Sound configuration starts by making some yes/no questions. Be careful
+when answering to these questions since answering y to a question may
+prevent some later ones from being asked. For example don't answer y to
+the first question (PAS16) if you don't really have a PAS16. Don't enable
+more cards than you really need since they just consume memory. Also
+some drivers (like MPU401) may conflict with your SCSI controller and
+prevent kernel from booting. If you card was in the list of supported
+cards (above), please look at the card specific config instructions
+(later in this file) before starting to configure. Some cards must be
+configured in way which is not obvious.
So here is the beginning of the config dialog. Answer 'y' or 'n' to these
questions. The default answer is shown so that (y/n) means 'y' by default and
@@ -688,9 +651,7 @@ card specific configuration information. Usually just a set of
I/O address, IRQ and DMA numbers are asked. With some cards the program
asks for some files to be used during initialization of the card. For example
many cards have a DSP chip or microprocessor which must be initialized by
-downloading a program (microcode) file to the card. In some cases this file
-is written to a .h file by the config program and then included to the driver
-during compile.
+downloading a program (microcode) file to the card.
Instructions for answering these questions are given in the next section.
@@ -1041,9 +1002,6 @@ specific section for instructions about configuring more than one MPU401 cards.
Logitech Soundman Wave
----------------------
-NOTE! You will have to use the "old" config script when configuring
- SM Wave.
-
Read the above MV Jazz specific instructions first.
The Logitech SoundMan Wave (don't confuse with the SM16 or SM Games) is
@@ -1168,9 +1126,9 @@ the ioctl() for activating the "solo" mode.
The following configuration parameters have worked fine for the PCM12
in Markus Kuhn's system, many other configurations might work, too:
-MAD16_BASE=0x530, MAD16_IRQ=11, MAD16_DMA=3, MAD16_DMA2=0,
-MAD16_MPU_BASE=0x330, MAD16_MPU_IRQ=10, DSP_BUFFSIZE=65536,
-SELECTED_SOUND_OPTIONS=0x00281000.
+CONFIG_MAD16_BASE=0x530, CONFIG_MAD16_IRQ=11, CONFIG_MAD16_DMA=3,
+CONFIG_MAD16_DMA2=0, CONFIG_MAD16_MPU_BASE=0x330, CONFIG_MAD16_MPU_IRQ=10,
+DSP_BUFFSIZE=65536, SELECTED_SOUND_OPTIONS=0x00281000.
The miroSOUND PCM1 pro and the PCM20 are very similar to the PCM12.
Perhaps the same ACI driver also works for these cards, however this
diff --git a/drivers/sound/Readme.modules b/drivers/sound/Readme.modules
index 778fbc3a0..aed47ee16 100644
--- a/drivers/sound/Readme.modules
+++ b/drivers/sound/Readme.modules
@@ -1,84 +1,71 @@
-Building a loadable sound driver
+Building a modular sound driver
================================
-Loadable module support in version 3.5 of the driver is mostly rewritten since
-the previous version (3.0.1). This means that some things have changed.
-
-To compile the sound driver as a loadable module you have to perform
-the following steps:
-
-1) Install modules-1.2.8.tar.gz package (or later if available).
-2a) Check that symbol remap_page_range is defined in linux/init/ksyms.c.
-Insert a line containing "X(remap_page_range)," if required. The driver will
-not load if this line is missing.
-2b) Recompile kernel with soundcard support disabled.
-3) Boot the new kernel.
-4) cd to the sound driver source directory (this directory). It's no
-longer required that the sound driver sources are installed in the
-kernel source tree (linux/drivers/sound). When installing a separately
-distributed sound driver you may install the sources for example to
-/usr/src/sound.
-5) Execute make in the sound driver source directory. Enter
-configuration parameters as described in Readme.cards. Then just wait until
-the driver is compiled OK.
-6) Copy sound.o to the directory where insmod expects to find it.
-("make install" copies it to /lib/modules/misc).
-7) Use command "insmod sound" to load the driver.
-
-8) The sound driver can be removed using command "rmmod sound".
-
-
-Parameters accepted by the loadable sound driver
-================================================
-
-Setting DMA buffer size
------------------------
-
-The driver allocates a DMA buffer (or two for full duplex devices)
-every time the audio device (/dev/dsp or /dev/audio) is opened
-and frees it when the device is closed. Size of this buffer is defined
-when the driver is configured (the last question). The buffer size
-can be redefined when loading the driver if required (note that this is
-an optional feature which is not normally required). The buffer size
-is redefined by adding dma_pagesize= parameter to the insmod command line.
-For example:
-
- insmod sound dma_buffsize=32768
-
-Minimum buffer size is 4096 and the maximum depends on the DMA channel.
-For 8 bit channels (0 to 3) the limit is 64k and for 16 bit ones (5 to 7)
-it's 128k. Driver selects a suitable buffer size automatically in case
-you try to specify an invalid size.
-
-Q: What is the right DMA buffer size?
-
-A: It depends on the sampling rate, machine speed and the load of the system.
-Large buffers are required on slow machines, when recording/playing CD-quality
-audio or when there are other processes running on the same system. Also
-recording to hard disk is likely to require large buffers.
-
-Very small buffers are sufficient when you are just playing 8kHz audio files
-on an empty P133 system. Using a 128k buffer just wastes 120k (or 250k)
-of valuable physical RAM memory.
-
-The right buffer size can be easily found by making some experiments
-with the dma_buffsize= parameter. I use usually 16k buffers on a DX4/100 system
-and 64k on an old 386 system.
-
-NOTE! DMA buffers are used only by /dev/audio# and /dev/dsp# devices.
- Other device files don't use them but there are two exceptions:
- GUS driver uses DMA buffers when loading samples to the card.
- Ensoniq SoundScape driver uses them when downloading the microcode
- file (sndscape.co[012]) to the card. Using large buffers doesn't
- increase performance in these cases.
-
-Debugging and tracing
----------------------
-
-Modularized sound driver doesn't display messages during initialization as
-the kernel compiled one does. This feature can be turned on by adding
-trace_init=1 to the insmod command line.
-
-For example:
-
- insmod sound trace_init=1
+ The following information is current as of linux-2.1.85. Check the other
+readme files, especially Readme.cards, for information not specific to
+making sound modular.
+
+ First, configure your kernel. This is an idea of what you should be
+setting in the sound section:
+
+<M> Sound card support
+
+<M> 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support
+
+ I have SoundBlaster. Select your card from the list.
+
+<M> Generic OPL2/OPL3 FM synthesizer support
+<M> FM synthesizer (YM3812/OPL-3) support
+
+ If you don't set these, you will probably find you can play .wav files
+but not .midi. As the help for them says, set them unless you know your
+card does not use one of these chips for FM support.
+
+ Once you are configured, make zlilo, modules, modules_install; reboot.
+Note that it is no longer necessary or possible to configure sound in the
+drivers/sound dir. Now one simply configures and makes one's kernel and
+modules in the usual way.
+
+ Then, add to your /etc/modules.conf or /etc/conf.modules something like:
+
+alias char-major-14 sb
+post-install sb modprobe "-k" "adlib_card"
+options sb io=0x220 irq=7 dma=1 dma16=5 mpu_io=0x330
+options adlib_card io=0x388 # FM synthetiser
+
+ The effect of this is that the sound driver and all necessary bits and
+pieces autoload on demand, assuming you use kerneld (a sound choice) and
+autoclean when not in use. Also, options for the device drivers are
+set. They will not work without them. Change as appropriate for your card.
+If you are not yet using the very cool kerneld, you will have to "modprobe
+-k sb" yourself to get things going. Eventually things may be fixed so
+that this kludgery is not necessary; for the time being, it seems to work
+well.
+
+ Replace 'sb' with the driver for your card, and give it the right
+options. To find the filename of the driver, look in
+/lib/modules/<kernel-version>/misc. Mine looks like:
+
+adlib_card.o # This is the generic OPLx driver
+opl3.o # The OPL3 driver
+sb.o # <<The SoundBlaster driver. Yours may differ.>>
+sound.o # The sound driver
+uart401.o # Used by sb, maybe other cards
+
+ Whichever card you have, try feeding it the options that would be the
+default if you were making the driver wired, not as modules. You can look
+at the init_module() code for the card to see what args are expected.
+
+ Note that at present there is no way to configure the io, irq and other
+parameters for the modular drivers as one does for the wired drivers.. One
+needs to pass the modules the necessary parameters as arguments, either
+with /etc/modules.conf or with command-line args to modprobe, e.g.
+
+modprobe -k sb io=0x220 irq=7 dma=1 dma16=5 mpu_io=0x330
+modprobe -k adlib_card io=0x388
+
+ recommend using /etc/modules.conf.
+
+ I'm afraid I know nothing about anything but my setup, being more of a
+text-mode guy anyway. If you have options for other cards or other helpful
+hints, send them to me, Jim Bray, jb@as220.org, http://as220.org/jb.
diff --git a/drivers/sound/ad1848.c b/drivers/sound/ad1848.c
index fc4de23e6..6fdec35ec 100644
--- a/drivers/sound/ad1848.c
+++ b/drivers/sound/ad1848.c
@@ -21,6 +21,9 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+/*
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ */
#include <linux/config.h>
#include <linux/module.h>
@@ -37,24 +40,24 @@
#include "ad1848_mixer.h"
typedef struct
- {
- int base;
- int irq;
- int dma1, dma2;
- int dual_dma; /* 1, when two DMA channels allocated */
- unsigned char MCE_bit;
- unsigned char saved_regs[16];
- int debug_flag;
-
- int audio_flags;
- int record_dev, playback_dev;
-
- int xfer_count;
- int audio_mode;
- int open_mode;
- int intr_active;
- char *chip_name, *name;
- int model;
+{
+ int base;
+ int irq;
+ int dma1, dma2;
+ int dual_dma; /* 1, when two DMA channels allocated */
+ unsigned char MCE_bit;
+ unsigned char saved_regs[16];
+ int debug_flag;
+
+ int audio_flags;
+ int record_dev, playback_dev;
+
+ int xfer_count;
+ int audio_mode;
+ int open_mode;
+ int intr_active;
+ char *chip_name, *name;
+ int model;
#define MD_1848 1
#define MD_4231 2
#define MD_4231A 3
@@ -63,44 +66,47 @@ typedef struct
#define MD_C930 6
#define MD_IWAVE 7
- /* Mixer parameters */
- int recmask;
- int supported_devices, orig_devices;
- int supported_rec_devices, orig_rec_devices;
- int *levels;
- short mixer_reroute[32];
- int dev_no;
- volatile unsigned long timer_ticks;
- int timer_running;
- int irq_ok;
- mixer_ents *mix_devices;
- int mixer_output_port;
- int c930_password_port;
- }
-ad1848_info;
+ /* Mixer parameters */
+ int recmask;
+ int supported_devices, orig_devices;
+ int supported_rec_devices, orig_rec_devices;
+ int *levels;
+ short mixer_reroute[32];
+ int dev_no;
+ volatile unsigned long timer_ticks;
+ int timer_running;
+ int irq_ok;
+ mixer_ents *mix_devices;
+ int mixer_output_port;
+ int c930_password_port;
+} ad1848_info;
typedef struct ad1848_port_info
- {
- int open_mode;
- int speed;
- unsigned char speed_bits;
- int channels;
- int audio_format;
- unsigned char format_bits;
- }
+{
+ int open_mode;
+ int speed;
+ unsigned char speed_bits;
+ int channels;
+ int audio_format;
+ unsigned char format_bits;
+}
ad1848_port_info;
-static int nr_ad1848_devs = 0;
-static volatile char irq2dev[17] =
-{-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1};
+static int nr_ad1848_devs = 0;
+int deskpro_xl = 0;
+
+static volatile char irq2dev[17] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
-static int timer_installed = -1;
+
+static int timer_installed = -1;
#endif
-static int ad_format_mask[8 /*devc->model */ ] =
+static int ad_format_mask[8 /*devc->model */ ] =
{
0,
AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW,
@@ -121,7 +127,6 @@ static ad1848_info adev_info[MAX_AUDIO_DEV];
static int ad1848_open(int dev, int mode);
static void ad1848_close(int dev);
-static int ad1848_ioctl(int dev, unsigned int cmd, caddr_t arg);
static void ad1848_output_block(int dev, unsigned long buf, int count, int intrflag);
static void ad1848_start_input(int dev, unsigned long buf, int count, int intrflag);
static int ad1848_prepare_for_output(int dev, int bsize, int bcount);
@@ -132,13 +137,12 @@ static void ad1848_halt_output(int dev);
static void ad1848_trigger(int dev, int bits);
#if (defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)) || defined(MODULE)
-static int ad1848_tmr_install(int dev);
-static void ad1848_tmr_reprogram(int dev);
+static int ad1848_tmr_install(int dev);
+static void ad1848_tmr_reprogram(int dev);
#endif
-static int
-ad_read(ad1848_info * devc, int reg)
+static int ad_read(ad1848_info * devc, int reg)
{
unsigned long flags;
int x;
@@ -157,8 +161,7 @@ ad_read(ad1848_info * devc, int reg)
return x;
}
-static void
-ad_write(ad1848_info * devc, int reg, int data)
+static void ad_write(ad1848_info * devc, int reg, int data)
{
unsigned long flags;
int timeout = 900000;
@@ -175,23 +178,22 @@ ad_write(ad1848_info * devc, int reg, int data)
restore_flags(flags);
}
-static void
-wait_for_calibration(ad1848_info * devc)
+static void wait_for_calibration(ad1848_info * devc)
{
int timeout = 0;
/*
- * Wait until the auto calibration process has finished.
- *
- * 1) Wait until the chip becomes ready (reads don't return 0x80).
- * 2) Wait until the ACI bit of I11 gets on and then off.
+ * Wait until the auto calibration process has finished.
+ *
+ * 1) Wait until the chip becomes ready (reads don't return 0x80).
+ * 2) Wait until the ACI bit of I11 gets on and then off.
*/
timeout = 100000;
while (timeout > 0 && inb(devc->base) == 0x80)
timeout--;
if (inb(devc->base) & 0x80)
- printk("ad1848: Auto calibration timed out(1).\n");
+ printk(KERN_WARNING "ad1848: Auto calibration timed out(1).\n");
timeout = 100;
while (timeout > 0 && !(ad_read(devc, 11) & 0x20))
@@ -204,36 +206,34 @@ wait_for_calibration(ad1848_info * devc)
timeout--;
if (ad_read(devc, 11) & 0x20)
if (devc->model != MD_1845)
- printk("ad1848: Auto calibration timed out(3).\n");
+ printk(KERN_WARNING "ad1848: Auto calibration timed out(3).\n");
}
-static void
-ad_mute(ad1848_info * devc)
+static void ad_mute(ad1848_info * devc)
{
- int i;
- unsigned char prev;
+ int i;
+ unsigned char prev;
/*
- * Save old register settings and mute output channels
+ * Save old register settings and mute output channels
*/
+
for (i = 6; i < 8; i++)
- {
- prev = devc->saved_regs[i] = ad_read(devc, i);
- }
+ {
+ prev = devc->saved_regs[i] = ad_read(devc, i);
+ }
}
-static void
-ad_unmute(ad1848_info * devc)
+static void ad_unmute(ad1848_info * devc)
{
}
-static void
-ad_enter_MCE(ad1848_info * devc)
+static void ad_enter_MCE(ad1848_info * devc)
{
- unsigned long flags;
- int timeout = 1000;
- unsigned short prev;
+ unsigned long flags;
+ int timeout = 1000;
+ unsigned short prev;
while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */
timeout--;
@@ -244,20 +244,19 @@ ad_enter_MCE(ad1848_info * devc)
devc->MCE_bit = 0x40;
prev = inb(io_Index_Addr(devc));
if (prev & 0x40)
- {
- restore_flags(flags);
- return;
- }
+ {
+ restore_flags(flags);
+ return;
+ }
outb((devc->MCE_bit), io_Index_Addr(devc));
restore_flags(flags);
}
-static void
-ad_leave_MCE(ad1848_info * devc)
+static void ad_leave_MCE(ad1848_info * devc)
{
- unsigned long flags;
- unsigned char prev, acal;
- int timeout = 1000;
+ unsigned long flags;
+ unsigned char prev, acal;
+ int timeout = 1000;
while (timeout > 0 && inb(devc->base) == 0x80) /*Are we initializing */
timeout--;
@@ -272,18 +271,17 @@ ad_leave_MCE(ad1848_info * devc)
outb((0x00), io_Index_Addr(devc)); /* Clear the MCE bit */
if ((prev & 0x40) == 0) /* Not in MCE mode */
- {
- restore_flags(flags);
- return;
- }
+ {
+ restore_flags(flags);
+ return;
+ }
outb((0x00), io_Index_Addr(devc)); /* Clear the MCE bit */
if (acal & 0x08) /* Auto calibration is enabled */
wait_for_calibration(devc);
restore_flags(flags);
}
-static int
-ad1848_set_recmask(ad1848_info * devc, int mask)
+static int ad1848_set_recmask(ad1848_info * devc, int mask)
{
unsigned char recdev;
int i, n;
@@ -292,12 +290,17 @@ ad1848_set_recmask(ad1848_info * devc, int mask)
/* Rename the mixer bits if necessary */
for (i = 0; i < 32; i++)
+ {
if (devc->mixer_reroute[i] != i)
+ {
if (mask & (1 << i))
- {
- mask &= ~(1 << i);
- mask |= (1 << devc->mixer_reroute[i]);
- }
+ {
+ mask &= ~(1 << i);
+ mask |= (1 << devc->mixer_reroute[i]);
+ }
+ }
+ }
+
n = 0;
for (i = 0; i < 32; i++) /* Count selected device bits */
if (mask & (1 << i))
@@ -306,41 +309,41 @@ ad1848_set_recmask(ad1848_info * devc, int mask)
if (n == 0)
mask = SOUND_MASK_MIC;
else if (n != 1) /* Too many devices selected */
- {
+ {
mask &= ~devc->recmask; /* Filter out active settings */
- n = 0;
- for (i = 0; i < 32; i++) /* Count selected device bits */
- if (mask & (1 << i))
- n++;
+ n = 0;
+ for (i = 0; i < 32; i++) /* Count selected device bits */
+ if (mask & (1 << i))
+ n++;
- if (n != 1)
- mask = SOUND_MASK_MIC;
- }
+ if (n != 1)
+ mask = SOUND_MASK_MIC;
+ }
switch (mask)
- {
- case SOUND_MASK_MIC:
- recdev = 2;
- break;
-
- case SOUND_MASK_LINE:
- case SOUND_MASK_LINE3:
- recdev = 0;
- break;
-
- case SOUND_MASK_CD:
- case SOUND_MASK_LINE1:
- recdev = 1;
- break;
-
- case SOUND_MASK_IMIX:
- recdev = 3;
- break;
-
- default:
- mask = SOUND_MASK_MIC;
- recdev = 2;
- }
+ {
+ case SOUND_MASK_MIC:
+ recdev = 2;
+ break;
+
+ case SOUND_MASK_LINE:
+ case SOUND_MASK_LINE3:
+ recdev = 0;
+ break;
+
+ case SOUND_MASK_CD:
+ case SOUND_MASK_LINE1:
+ recdev = 1;
+ break;
+
+ case SOUND_MASK_IMIX:
+ recdev = 3;
+ break;
+
+ default:
+ mask = SOUND_MASK_MIC;
+ recdev = 2;
+ }
recdev <<= 6;
ad_write(devc, 0, (ad_read(devc, 0) & 0x3f) | recdev);
@@ -348,24 +351,27 @@ ad1848_set_recmask(ad1848_info * devc, int mask)
/* Rename the mixer bits back if necessary */
for (i = 0; i < 32; i++)
+ {
if (devc->mixer_reroute[i] != i)
+ {
if (mask & (1 << devc->mixer_reroute[i]))
- {
- mask &= ~(1 << devc->mixer_reroute[i]);
- mask |= (1 << i);
- }
+ {
+ mask &= ~(1 << devc->mixer_reroute[i]);
+ mask |= (1 << i);
+ }
+ }
+ }
devc->recmask = mask;
return mask;
}
-static void
-change_bits(ad1848_info * devc, unsigned char *regval, int dev, int chn, int newval)
+static void change_bits(ad1848_info * devc, unsigned char *regval, int dev, int chn, int newval)
{
- unsigned char mask;
- int shift;
- int mute;
- int mutemask;
- int set_mute_bit;
+ unsigned char mask;
+ int shift;
+ int mute;
+ int mutemask;
+ int set_mute_bit;
set_mute_bit = (newval == 0);
@@ -376,22 +382,22 @@ change_bits(ad1848_info * devc, unsigned char *regval, int dev, int chn, int new
shift = devc->mix_devices[dev][chn].bitpos;
if (devc->mix_devices[dev][chn].mutepos == 8)
- { /* if there is no mute bit */
- mute = 0; /* No mute bit; do nothing special */
- mutemask = ~0; /* No mute bit; do nothing special */
- } else
- {
- mute = (set_mute_bit << devc->mix_devices[dev][chn].mutepos);
- mutemask = ~(1 << devc->mix_devices[dev][chn].mutepos);
- }
+ { /* if there is no mute bit */
+ mute = 0; /* No mute bit; do nothing special */
+ mutemask = ~0; /* No mute bit; do nothing special */
+ }
+ else
+ {
+ mute = (set_mute_bit << devc->mix_devices[dev][chn].mutepos);
+ mutemask = ~(1 << devc->mix_devices[dev][chn].mutepos);
+ }
newval = (int) ((newval * mask) + 50) / 100; /* Scale it */
*regval &= (~(mask << shift)) & (mutemask); /* Clear bits */
*regval |= ((newval & mask) << shift) | mute; /* Set new value */
}
-static int
-ad1848_mixer_get(ad1848_info * devc, int dev)
+static int ad1848_mixer_get(ad1848_info * devc, int dev)
{
if (!((1 << dev) & devc->supported_devices))
return -EINVAL;
@@ -401,15 +407,14 @@ ad1848_mixer_get(ad1848_info * devc, int dev)
return devc->levels[dev];
}
-static int
-ad1848_mixer_set(ad1848_info * devc, int dev, int value)
+static int ad1848_mixer_set(ad1848_info * devc, int dev, int value)
{
- int left = value & 0x000000ff;
- int right = (value & 0x0000ff00) >> 8;
- int retvol;
+ int left = value & 0x000000ff;
+ int right = (value & 0x0000ff00) >> 8;
+ int retvol;
- int regoffs;
- unsigned char val;
+ int regoffs;
+ unsigned char val;
if (dev > 31)
return -EINVAL;
@@ -443,7 +448,7 @@ ad1848_mixer_set(ad1848_info * devc, int dev, int value)
devc->levels[dev] = retvol;
/*
- * Set the left channel
+ * Set the left channel
*/
regoffs = devc->mix_devices[dev][LEFT_CHN].regno;
@@ -453,7 +458,7 @@ ad1848_mixer_set(ad1848_info * devc, int dev, int value)
devc->saved_regs[regoffs] = val;
/*
- * Set the right channel
+ * Set the right channel
*/
if (devc->mix_devices[dev][RIGHT_CHN].nbits == 0)
@@ -468,11 +473,10 @@ ad1848_mixer_set(ad1848_info * devc, int dev, int value)
return retvol;
}
-static void
-ad1848_mixer_reset(ad1848_info * devc)
+static void ad1848_mixer_reset(ad1848_info * devc)
{
- int i;
- char name[32];
+ int i;
+ char name[32];
devc->mix_devices = &(ad1848_mix_devices[0]);
@@ -482,30 +486,30 @@ ad1848_mixer_reset(ad1848_info * devc)
devc->mixer_reroute[i] = i;
switch (devc->model)
- {
- case MD_4231:
- case MD_4231A:
- case MD_1845:
- devc->supported_devices = MODE2_MIXER_DEVICES;
- break;
-
- case MD_C930:
- devc->supported_devices = C930_MIXER_DEVICES;
- devc->mix_devices = &(c930_mix_devices[0]);
- break;
-
- case MD_IWAVE:
- devc->supported_devices = MODE3_MIXER_DEVICES;
- devc->mix_devices = &(iwave_mix_devices[0]);
- break;
-
- case MD_4232:
- devc->supported_devices = MODE3_MIXER_DEVICES;
- break;
-
- default:
- devc->supported_devices = MODE1_MIXER_DEVICES;
- }
+ {
+ case MD_4231:
+ case MD_4231A:
+ case MD_1845:
+ devc->supported_devices = MODE2_MIXER_DEVICES;
+ break;
+
+ case MD_C930:
+ devc->supported_devices = C930_MIXER_DEVICES;
+ devc->mix_devices = &(c930_mix_devices[0]);
+ break;
+
+ case MD_IWAVE:
+ devc->supported_devices = MODE3_MIXER_DEVICES;
+ devc->mix_devices = &(iwave_mix_devices[0]);
+ break;
+
+ case MD_4232:
+ devc->supported_devices = MODE3_MIXER_DEVICES;
+ break;
+
+ default:
+ devc->supported_devices = MODE1_MIXER_DEVICES;
+ }
devc->supported_rec_devices = MODE1_REC_DEVICES;
devc->orig_devices = devc->supported_devices;
@@ -514,9 +518,13 @@ ad1848_mixer_reset(ad1848_info * devc)
devc->levels = load_mixer_volumes(name, default_mixer_levels, 1);
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ {
if (devc->supported_devices & (1 << i))
ad1848_mixer_set(devc, i, devc->levels[i]);
+ }
+
ad1848_set_recmask(devc, SOUND_MASK_MIC);
+
devc->mixer_output_port = devc->levels[31] | AUDIO_HEADPHONE | AUDIO_LINE_OUT;
if (devc->mixer_output_port & AUDIO_SPEAKER)
ad_write(devc, 26, ad_read(devc, 26) & ~0x40); /* Unmute mono out */
@@ -524,103 +532,109 @@ ad1848_mixer_reset(ad1848_info * devc)
ad_write(devc, 26, ad_read(devc, 26) | 0x40); /* Mute mono out */
}
-static int
-ad1848_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+static int ad1848_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- ad1848_info *devc = mixer_devs[dev]->devc;
-
- if (cmd == SOUND_MIXER_PRIVATE1)
- {
- int val;
-
- val = *(int *) arg;
+ ad1848_info *devc = mixer_devs[dev]->devc;
+ int val;
- if (val == 0xffff)
- return (*(int *) arg = devc->mixer_output_port);
-
- val &= (AUDIO_SPEAKER | AUDIO_HEADPHONE | AUDIO_LINE_OUT);
-
- devc->mixer_output_port = val;
- val |= AUDIO_HEADPHONE | AUDIO_LINE_OUT; /* Always on */
- devc->mixer_output_port = val;
+ if (cmd == SOUND_MIXER_PRIVATE1)
+ {
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
- if (val & AUDIO_SPEAKER)
- ad_write(devc, 26, ad_read(devc, 26) & ~0x40); /* Unmute mono out */
- else
- ad_write(devc, 26, ad_read(devc, 26) | 0x40); /* Mute mono out */
-
- return (*(int *) arg = devc->mixer_output_port);
- }
- if (((cmd >> 8) & 0xff) == 'M')
- {
- int val;
-
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- val = *(int *) arg;
- return (*(int *) arg = ad1848_set_recmask(devc, val));
- break;
-
- default:
- val = *(int *) arg;
- return (*(int *) arg = ad1848_mixer_set(devc, cmd & 0xff, val));
- } else
- switch (cmd & 0xff) /*
- * Return parameters
- */
- {
-
- case SOUND_MIXER_RECSRC:
- return (*(int *) arg = devc->recmask);
- break;
-
- case SOUND_MIXER_DEVMASK:
- return (*(int *) arg = devc->supported_devices);
- break;
-
- case SOUND_MIXER_STEREODEVS:
- if (devc->model == MD_C930)
- return (*(int *) arg = devc->supported_devices);
- else
- return (*(int *) arg = devc->supported_devices & ~(SOUND_MASK_SPEAKER | SOUND_MASK_IMIX));
- break;
-
- case SOUND_MIXER_RECMASK:
- return (*(int *) arg = devc->supported_rec_devices);
- break;
-
- case SOUND_MIXER_CAPS:
- return (*(int *) arg = SOUND_CAP_EXCL_INPUT);
- break;
-
- default:
- return (*(int *) arg = ad1848_mixer_get(devc, cmd & 0xff));
- }
- } else
+ if (val != 0xffff)
+ {
+ val &= (AUDIO_SPEAKER | AUDIO_HEADPHONE | AUDIO_LINE_OUT);
+ devc->mixer_output_port = val;
+ val |= AUDIO_HEADPHONE | AUDIO_LINE_OUT; /* Always on */
+ devc->mixer_output_port = val;
+ if (val & AUDIO_SPEAKER)
+ ad_write(devc, 26, ad_read(devc, 26) & ~0x40); /* Unmute mono out */
+ else
+ ad_write(devc, 26, ad_read(devc, 26) | 0x40); /* Mute mono out */
+ }
+ val = devc->mixer_output_port;
+ return put_user(val, (int *)arg);
+ }
+ if (((cmd >> 8) & 0xff) == 'M')
+ {
+ if (_SIOC_DIR(cmd) & _SIOC_WRITE)
+ {
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = ad1848_set_recmask(devc, val);
+ break;
+
+ default:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = ad1848_mixer_set(devc, cmd & 0xff, val);
+ break;
+ }
+ return put_user(val, (int *)arg);
+ }
+ else
+ {
+ switch (cmd & 0xff)
+ {
+ /*
+ * Return parameters
+ */
+
+ case SOUND_MIXER_RECSRC:
+ val = devc->recmask;
+ break;
+
+ case SOUND_MIXER_DEVMASK:
+ val = devc->supported_devices;
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ val = devc->supported_devices;
+ if (devc->model != MD_C930)
+ val &= ~(SOUND_MASK_SPEAKER | SOUND_MASK_IMIX);
+ break;
+
+ case SOUND_MIXER_RECMASK:
+ val = devc->supported_rec_devices;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ val=SOUND_CAP_EXCL_INPUT;
+ break;
+
+ default:
+ val = ad1848_mixer_get(devc, cmd & 0xff);
+ break;
+ }
+ return put_user(val, (int *)arg);
+ }
+ }
+ else
return -EINVAL;
}
-static int
-ad1848_set_speed(int dev, int arg)
+static int ad1848_set_speed(int dev, int arg)
{
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
+ ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
/*
- * The sampling speed is encoded in the least significant nibble of I8. The
- * LSB selects the clock source (0=24.576 MHz, 1=16.9344 MHz) and other
- * three bits select the divisor (indirectly):
- *
- * The available speeds are in the following table. Keep the speeds in
- * the increasing order.
+ * The sampling speed is encoded in the least significant nibble of I8. The
+ * LSB selects the clock source (0=24.576 MHz, 1=16.9344 MHz) and other
+ * three bits select the divisor (indirectly):
+ *
+ * The available speeds are in the following table. Keep the speeds in
+ * the increasing order.
*/
typedef struct
- {
- int speed;
- unsigned char bits;
- }
+ {
+ int speed;
+ unsigned char bits;
+ }
speed_struct;
static speed_struct speed_table[] =
@@ -642,7 +656,7 @@ ad1848_set_speed(int dev, int arg)
{48000, (6 << 1) | 0}
};
- int i, n, selected = -1;
+ int i, n, selected = -1;
n = sizeof(speed_table) / sizeof(speed_struct);
@@ -650,48 +664,49 @@ ad1848_set_speed(int dev, int arg)
return portc->speed;
if (devc->model == MD_1845) /* AD1845 has different timer than others */
- {
- if (arg < 4000)
- arg = 4000;
- if (arg > 50000)
- arg = 50000;
-
- portc->speed = arg;
- portc->speed_bits = speed_table[3].bits;
- return portc->speed;
- }
+ {
+ if (arg < 4000)
+ arg = 4000;
+ if (arg > 50000)
+ arg = 50000;
+
+ portc->speed = arg;
+ portc->speed_bits = speed_table[3].bits;
+ return portc->speed;
+ }
if (arg < speed_table[0].speed)
selected = 0;
if (arg > speed_table[n - 1].speed)
selected = n - 1;
for (i = 1 /*really */ ; selected == -1 && i < n; i++)
+ {
if (speed_table[i].speed == arg)
selected = i;
else if (speed_table[i].speed > arg)
- {
- int diff1, diff2;
+ {
+ int diff1, diff2;
- diff1 = arg - speed_table[i - 1].speed;
- diff2 = speed_table[i].speed - arg;
+ diff1 = arg - speed_table[i - 1].speed;
+ diff2 = speed_table[i].speed - arg;
- if (diff1 < diff2)
- selected = i - 1;
- else
- selected = i;
- }
+ if (diff1 < diff2)
+ selected = i - 1;
+ else
+ selected = i;
+ }
+ }
if (selected == -1)
- {
- printk("ad1848: Can't find speed???\n");
- selected = 3;
- }
+ {
+ printk(KERN_WARNING "ad1848: Can't find speed???\n");
+ selected = 3;
+ }
portc->speed = speed_table[selected].speed;
portc->speed_bits = speed_table[selected].bits;
return portc->speed;
}
-static short
-ad1848_set_channels(int dev, short arg)
+static short ad1848_set_channels(int dev, short arg)
{
ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
@@ -702,17 +717,16 @@ ad1848_set_channels(int dev, short arg)
return arg;
}
-static unsigned int
-ad1848_set_bits(int dev, unsigned int arg)
+static unsigned int ad1848_set_bits(int dev, unsigned int arg)
{
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
static struct format_tbl
- {
+ {
int format;
unsigned char bits;
- }
+ }
format2bits[] =
{
{
@@ -755,7 +769,7 @@ ad1848_set_bits(int dev, unsigned int arg)
AFMT_U16_BE, 0
}
};
- int i, n = sizeof(format2bits) / sizeof(struct format_tbl);
+ int i, n = sizeof(format2bits) / sizeof(struct format_tbl);
if (arg == 0)
return portc->audio_format;
@@ -767,12 +781,12 @@ ad1848_set_bits(int dev, unsigned int arg)
for (i = 0; i < n; i++)
if (format2bits[i].format == arg)
- {
- if ((portc->format_bits = format2bits[i].bits) == 0)
- return portc->audio_format = AFMT_U8; /* Was not supported */
+ {
+ if ((portc->format_bits = format2bits[i].bits) == 0)
+ return portc->audio_format = AFMT_U8; /* Was not supported */
- return arg;
- }
+ return arg;
+ }
/* Still hanging here. Something must be terribly wrong */
portc->format_bits = 0;
return portc->audio_format = AFMT_U8;
@@ -784,7 +798,7 @@ static struct audio_driver ad1848_audio_driver =
ad1848_close,
ad1848_output_block,
ad1848_start_input,
- ad1848_ioctl,
+ NULL,
ad1848_prepare_for_input,
ad1848_prepare_for_output,
ad1848_halt,
@@ -805,8 +819,7 @@ static struct mixer_operations ad1848_mixer_operations =
ad1848_mixer_ioctl
};
-static int
-ad1848_open(int dev, int mode)
+static int ad1848_open(int dev, int mode)
{
ad1848_info *devc = NULL;
ad1848_port_info *portc;
@@ -821,16 +834,16 @@ ad1848_open(int dev, int mode)
save_flags(flags);
cli();
if (portc->open_mode || (devc->open_mode & mode))
- {
- restore_flags(flags);
- return -EBUSY;
- }
+ {
+ restore_flags(flags);
+ return -EBUSY;
+ }
devc->dual_dma = 0;
if (audio_devs[dev]->flags & DMA_DUPLEX)
- {
- devc->dual_dma = 1;
- }
+ {
+ devc->dual_dma = 1;
+ }
devc->intr_active = 0;
devc->audio_mode = 0;
devc->open_mode |= mode;
@@ -850,8 +863,7 @@ ad1848_open(int dev, int mode)
return 0;
}
-static void
-ad1848_close(int dev)
+static void ad1848_close(int dev)
{
unsigned long flags;
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
@@ -873,14 +885,7 @@ ad1848_close(int dev)
restore_flags(flags);
}
-static int
-ad1848_ioctl(int dev, unsigned int cmd, caddr_t arg)
-{
- return -EINVAL;
-}
-
-static void
-ad1848_output_block(int dev, unsigned long buf, int count, int intrflag)
+static void ad1848_output_block(int dev, unsigned long buf, int count, int intrflag)
{
unsigned long flags, cnt;
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
@@ -889,13 +894,14 @@ ad1848_output_block(int dev, unsigned long buf, int count, int intrflag)
cnt = count;
if (portc->audio_format == AFMT_IMA_ADPCM)
- {
- cnt /= 4;
- } else
- {
- if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
- cnt >>= 1;
- }
+ {
+ cnt /= 4;
+ }
+ else
+ {
+ if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
+ cnt >>= 1;
+ }
if (portc->channels > 1)
cnt >>= 1;
cnt--;
@@ -903,13 +909,13 @@ ad1848_output_block(int dev, unsigned long buf, int count, int intrflag)
if (devc->audio_mode & PCM_ENABLE_OUTPUT && audio_devs[dev]->flags & DMA_AUTOMODE &&
intrflag &&
cnt == devc->xfer_count)
- {
- devc->audio_mode |= PCM_ENABLE_OUTPUT;
- devc->intr_active = 1;
- return; /*
- * Auto DMA mode on. No need to react
- */
- }
+ {
+ devc->audio_mode |= PCM_ENABLE_OUTPUT;
+ devc->intr_active = 1;
+ return; /*
+ * Auto DMA mode on. No need to react
+ */
+ }
save_flags(flags);
cli();
@@ -922,8 +928,7 @@ ad1848_output_block(int dev, unsigned long buf, int count, int intrflag)
restore_flags(flags);
}
-static void
-ad1848_start_input(int dev, unsigned long buf, int count, int intrflag)
+static void ad1848_start_input(int dev, unsigned long buf, int count, int intrflag)
{
unsigned long flags, cnt;
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
@@ -931,39 +936,41 @@ ad1848_start_input(int dev, unsigned long buf, int count, int intrflag)
cnt = count;
if (portc->audio_format == AFMT_IMA_ADPCM)
- {
- cnt /= 4;
- } else
- {
- if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
- cnt >>= 1;
- }
+ {
+ cnt /= 4;
+ }
+ else
+ {
+ if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
+ cnt >>= 1;
+ }
if (portc->channels > 1)
cnt >>= 1;
cnt--;
if (devc->audio_mode & PCM_ENABLE_INPUT && audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == devc->xfer_count)
- {
- devc->audio_mode |= PCM_ENABLE_INPUT;
- devc->intr_active = 1;
- return; /*
- * Auto DMA mode on. No need to react
- */
- }
+ intrflag &&
+ cnt == devc->xfer_count)
+ {
+ devc->audio_mode |= PCM_ENABLE_INPUT;
+ devc->intr_active = 1;
+ return; /*
+ * Auto DMA mode on. No need to react
+ */
+ }
save_flags(flags);
cli();
if (devc->model == MD_1848)
- {
+ {
ad_write(devc, 15, (unsigned char) (cnt & 0xff));
ad_write(devc, 14, (unsigned char) ((cnt >> 8) & 0xff));
- } else
- {
+ }
+ else
+ {
ad_write(devc, 31, (unsigned char) (cnt & 0xff));
ad_write(devc, 30, (unsigned char) ((cnt >> 8) & 0xff));
- }
+ }
ad_unmute(devc);
@@ -973,8 +980,7 @@ ad1848_start_input(int dev, unsigned long buf, int count, int intrflag)
restore_flags(flags);
}
-static int
-ad1848_prepare_for_output(int dev, int bsize, int bcount)
+static int ad1848_prepare_for_output(int dev, int bsize, int bcount)
{
int timeout;
unsigned char fs, old_fs, tmp = 0;
@@ -994,26 +1000,28 @@ ad1848_prepare_for_output(int dev, int bsize, int bcount)
ad_enter_MCE(devc); /* Enables changes to the format select reg */
if (devc->model == MD_1845) /* Use alternate speed select registers */
- {
- fs &= 0xf0; /* Mask off the rate select bits */
+ {
+ fs &= 0xf0; /* Mask off the rate select bits */
- ad_write(devc, 22, (portc->speed >> 8) & 0xff); /* Speed MSB */
- ad_write(devc, 23, portc->speed & 0xff); /* Speed LSB */
- }
+ ad_write(devc, 22, (portc->speed >> 8) & 0xff); /* Speed MSB */
+ ad_write(devc, 23, portc->speed & 0xff); /* Speed LSB */
+ }
old_fs = ad_read(devc, 8);
if (devc->model == MD_4232)
- {
- tmp = ad_read(devc, 16);
- ad_write(devc, 16, tmp | 0x30);
- }
+ {
+ tmp = ad_read(devc, 16);
+ ad_write(devc, 16, tmp | 0x30);
+ }
if (devc->model == MD_IWAVE)
ad_write(devc, 17, 0xc2); /* Disable variable frequency select */
ad_write(devc, 8, fs);
+
/*
* Write to I8 starts resynchronization. Wait until it completes.
*/
+
timeout = 0;
while (timeout < 100 && inb(devc->base) != 0x80)
timeout++;
@@ -1033,21 +1041,20 @@ ad1848_prepare_for_output(int dev, int bsize, int bcount)
#if (defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)) || defined(MODULE)
if (dev == timer_installed && devc->timer_running)
if ((fs & 0x01) != (old_fs & 0x01))
- {
- ad1848_tmr_reprogram(dev);
- }
+ {
+ ad1848_tmr_reprogram(dev);
+ }
#endif
ad1848_halt_output(dev);
return 0;
}
-static int
-ad1848_prepare_for_input(int dev, int bsize, int bcount)
+static int ad1848_prepare_for_input(int dev, int bsize, int bcount)
{
- int timeout;
- unsigned char fs, old_fs, tmp = 0;
- unsigned long flags;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
+ int timeout;
+ unsigned char fs, old_fs, tmp = 0;
+ unsigned long flags;
+ ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
if (devc->audio_mode)
@@ -1063,75 +1070,78 @@ ad1848_prepare_for_input(int dev, int bsize, int bcount)
ad_enter_MCE(devc); /* Enables changes to the format select reg */
if (devc->model == MD_1845) /* Use alternate speed select registers */
- {
- fs &= 0xf0; /* Mask off the rate select bits */
+ {
+ fs &= 0xf0; /* Mask off the rate select bits */
- ad_write(devc, 22, (portc->speed >> 8) & 0xff); /* Speed MSB */
- ad_write(devc, 23, portc->speed & 0xff); /* Speed LSB */
- }
+ ad_write(devc, 22, (portc->speed >> 8) & 0xff); /* Speed MSB */
+ ad_write(devc, 23, portc->speed & 0xff); /* Speed LSB */
+ }
if (devc->model == MD_4232)
- {
- tmp = ad_read(devc, 16);
- ad_write(devc, 16, tmp | 0x30);
- }
+ {
+ tmp = ad_read(devc, 16);
+ ad_write(devc, 16, tmp | 0x30);
+ }
if (devc->model == MD_IWAVE)
ad_write(devc, 17, 0xc2); /* Disable variable frequency select */
/*
* If mode >= 2 (CS4231), set I28. It's the capture format register.
*/
+
if (devc->model != MD_1848)
- {
- old_fs = ad_read(devc, 28);
- ad_write(devc, 28, fs);
-
- /*
- * Write to I28 starts resynchronization. Wait until it completes.
- */
- timeout = 0;
- while (timeout < 100 && inb(devc->base) != 0x80)
- timeout++;
-
- timeout = 0;
- while (timeout < 10000 && inb(devc->base) == 0x80)
- timeout++;
-
- if (devc->model != MD_1848 && devc->model != MD_1845)
- {
- /*
- * CS4231 compatible devices don't have separate sampling rate selection
- * register for recording an playback. The I8 register is shared so we have to
- * set the speed encoding bits of it too.
- */
- unsigned char tmp = portc->speed_bits | (ad_read(devc, 8) & 0xf0);
-
- ad_write(devc, 8, tmp);
- /*
- * Write to I8 starts resynchronization. Wait until it completes.
- */
- timeout = 0;
- while (timeout < 100 && inb(devc->base) != 0x80)
- timeout++;
-
- timeout = 0;
- while (timeout < 10000 && inb(devc->base) == 0x80)
- timeout++;
- }
- } else
- { /* For AD1848 set I8. */
-
- old_fs = ad_read(devc, 8);
- ad_write(devc, 8, fs);
- /*
- * Write to I8 starts resynchronization. Wait until it completes.
- */
- timeout = 0;
- while (timeout < 100 && inb(devc->base) != 0x80)
- timeout++;
- timeout = 0;
- while (timeout < 10000 && inb(devc->base) == 0x80)
- timeout++;
- }
+ {
+ old_fs = ad_read(devc, 28);
+ ad_write(devc, 28, fs);
+
+ /*
+ * Write to I28 starts resynchronization. Wait until it completes.
+ */
+
+ timeout = 0;
+ while (timeout < 100 && inb(devc->base) != 0x80)
+ timeout++;
+
+ timeout = 0;
+ while (timeout < 10000 && inb(devc->base) == 0x80)
+ timeout++;
+
+ if (devc->model != MD_1848 && devc->model != MD_1845)
+ {
+ /*
+ * CS4231 compatible devices don't have separate sampling rate selection
+ * register for recording an playback. The I8 register is shared so we have to
+ * set the speed encoding bits of it too.
+ */
+ unsigned char tmp = portc->speed_bits | (ad_read(devc, 8) & 0xf0);
+
+ ad_write(devc, 8, tmp);
+ /*
+ * Write to I8 starts resynchronization. Wait until it completes.
+ */
+ timeout = 0;
+ while (timeout < 100 && inb(devc->base) != 0x80)
+ timeout++;
+
+ timeout = 0;
+ while (timeout < 10000 && inb(devc->base) == 0x80)
+ timeout++;
+ }
+ }
+ else
+ { /* For AD1848 set I8. */
+
+ old_fs = ad_read(devc, 8);
+ ad_write(devc, 8, fs);
+ /*
+ * Write to I8 starts resynchronization. Wait until it completes.
+ */
+ timeout = 0;
+ while (timeout < 100 && inb(devc->base) != 0x80)
+ timeout++;
+ timeout = 0;
+ while (timeout < 10000 && inb(devc->base) == 0x80)
+ timeout++;
+ }
if (devc->model == MD_4232)
ad_write(devc, 16, tmp & ~0x30);
@@ -1144,19 +1154,20 @@ ad1848_prepare_for_input(int dev, int bsize, int bcount)
#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
if (dev == timer_installed && devc->timer_running)
+ {
if ((fs & 0x01) != (old_fs & 0x01))
- {
- ad1848_tmr_reprogram(dev);
- }
+ {
+ ad1848_tmr_reprogram(dev);
+ }
+ }
#endif
ad1848_halt_input(dev);
return 0;
}
-static void
-ad1848_halt(int dev)
+static void ad1848_halt(int dev)
{
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
+ ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
unsigned char bits = ad_read(devc, 9);
@@ -1169,8 +1180,7 @@ ad1848_halt(int dev)
devc->audio_mode = 0;
}
-static void
-ad1848_halt_input(int dev)
+static void ad1848_halt_input(int dev)
{
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
unsigned long flags;
@@ -1197,19 +1207,18 @@ ad1848_halt_input(int dev)
devc->audio_mode &= ~PCM_ENABLE_INPUT;
}
- outb((0), io_Status(devc)); /* Clear interrupt status */
- outb((0), io_Status(devc)); /* Clear interrupt status */
+ outb(0, io_Status(devc)); /* Clear interrupt status */
+ outb(0, io_Status(devc)); /* Clear interrupt status */
devc->audio_mode &= ~PCM_ENABLE_INPUT;
restore_flags(flags);
}
-static void
-ad1848_halt_output(int dev)
+static void ad1848_halt_output(int dev)
{
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
- unsigned long flags;
+ ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
+ unsigned long flags;
if (!(ad_read(devc, 9) & 0x01))
return; /* Playback not enabled */
@@ -1240,8 +1249,7 @@ ad1848_halt_output(int dev)
restore_flags(flags);
}
-static void
-ad1848_trigger(int dev, int state)
+static void ad1848_trigger(int dev, int state)
{
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
ad1848_port_info *portc = (ad1848_port_info *) audio_devs[dev]->portc;
@@ -1255,32 +1263,31 @@ ad1848_trigger(int dev, int state)
tmp = old = ad_read(devc, 9);
if (portc->open_mode & OPEN_READ)
- {
+ {
if (state & PCM_ENABLE_INPUT)
tmp |= 0x02;
else
tmp &= ~0x02;
- }
+ }
if (portc->open_mode & OPEN_WRITE)
- {
- if (state & PCM_ENABLE_OUTPUT)
- tmp |= 0x01;
- else
- tmp &= ~0x01;
- }
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ tmp |= 0x01;
+ else
+ tmp &= ~0x01;
+ }
/* ad_mute(devc); */
if (tmp != old)
- {
+ {
ad_write(devc, 9, tmp);
ad_unmute(devc);
- }
+ }
restore_flags(flags);
}
-static void
-ad1848_init_hw(ad1848_info * devc)
+static void ad1848_init_hw(ad1848_info * devc)
{
- int i;
+ int i;
/*
* Initial values for the indirect registers of CS4248/AD1848.
@@ -1304,40 +1311,40 @@ ad1848_init_hw(ad1848_info * devc)
ad_unmute(devc); /* Leave it unmuted now */
if (devc->model > MD_1848)
- {
- ad_write(devc, 12, ad_read(devc, 12) | 0x40); /* Mode2 = enabled */
-
- if (devc->model == MD_IWAVE)
- ad_write(devc, 12, 0x6c); /* Select codec mode 3 */
+ {
+ ad_write(devc, 12, ad_read(devc, 12) | 0x40); /* Mode2 = enabled */
- for (i = 16; i < 32; i++)
- ad_write(devc, i, init_values[i]);
+ if (devc->model == MD_IWAVE)
+ ad_write(devc, 12, 0x6c); /* Select codec mode 3 */
- if (devc->model == MD_IWAVE)
- ad_write(devc, 16, 0x30); /* Playback and capture counters enabled */
+ for (i = 16; i < 32; i++)
+ ad_write(devc, i, init_values[i]);
- }
+ if (devc->model == MD_IWAVE)
+ ad_write(devc, 16, 0x30); /* Playback and capture counters enabled */
+ }
if (devc->model > MD_1848)
- {
- if (devc->audio_flags & DMA_DUPLEX)
- ad_write(devc, 9, ad_read(devc, 9) & ~0x04); /* Dual DMA mode */
- else
- ad_write(devc, 9, ad_read(devc, 9) | 0x04); /* Single DMA mode */
+ {
+ if (devc->audio_flags & DMA_DUPLEX)
+ ad_write(devc, 9, ad_read(devc, 9) & ~0x04); /* Dual DMA mode */
+ else
+ ad_write(devc, 9, ad_read(devc, 9) | 0x04); /* Single DMA mode */
- if (devc->model == MD_1845)
- ad_write(devc, 27, ad_read(devc, 27) | 0x08); /* Alternate freq select enabled */
+ if (devc->model == MD_1845)
+ ad_write(devc, 27, ad_read(devc, 27) | 0x08); /* Alternate freq select enabled */
- if (devc->model == MD_IWAVE)
- { /* Some magic Interwave specific initialization */
- ad_write(devc, 12, 0x6c); /* Select codec mode 3 */
- ad_write(devc, 16, 0x30); /* Playback and capture counters enabled */
- ad_write(devc, 17, 0xc2); /* Alternate feature enable */
- }
- } else
- {
+ if (devc->model == MD_IWAVE)
+ { /* Some magic Interwave specific initialization */
+ ad_write(devc, 12, 0x6c); /* Select codec mode 3 */
+ ad_write(devc, 16, 0x30); /* Playback and capture counters enabled */
+ ad_write(devc, 17, 0xc2); /* Alternate feature enable */
+ }
+ }
+ else
+ {
devc->audio_flags &= ~DMA_DUPLEX;
ad_write(devc, 9, ad_read(devc, 9) | 0x04); /* Single DMA mode */
- }
+ }
outb((0), io_Status(devc)); /* Clear pending interrupts */
@@ -1351,45 +1358,43 @@ ad1848_init_hw(ad1848_info * devc)
ad1848_mixer_reset(devc);
}
-int
-ad1848_detect(int io_base, int *ad_flags, int *osp)
+int ad1848_detect(int io_base, int *ad_flags, int *osp)
{
+ unsigned char tmp;
+ ad1848_info *devc = &adev_info[nr_ad1848_devs];
+ unsigned char tmp1 = 0xff, tmp2 = 0xff;
+ int optiC930 = 0; /* OPTi 82C930 flag */
+ int interwave = 0;
+ int ad1847_flag = 0;
+ int cs4248_flag = 0;
- unsigned char tmp;
- ad1848_info *devc = &adev_info[nr_ad1848_devs];
- unsigned char tmp1 = 0xff, tmp2 = 0xff;
- int optiC930 = 0; /* OPTi 82C930 flag */
- int interwave = 0;
- int ad1847_flag = 0;
- int cs4248_flag = 0;
-
- int i;
+ int i;
DDB(printk("ad1848_detect(%x)\n", io_base));
if (ad_flags)
- {
- if (*ad_flags == 0x12345678)
- {
- interwave = 1;
- *ad_flags = 0;
- }
- if (*ad_flags == 0x12345677)
- {
- cs4248_flag = 1;
- *ad_flags = 0;
- }
- }
+ {
+ if (*ad_flags == 0x12345678)
+ {
+ interwave = 1;
+ *ad_flags = 0;
+ }
+ if (*ad_flags == 0x12345677)
+ {
+ cs4248_flag = 1;
+ *ad_flags = 0;
+ }
+ }
if (nr_ad1848_devs >= MAX_AUDIO_DEV)
- {
- printk("ad1848 - Too many audio devices\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "ad1848 - Too many audio devices\n");
+ return 0;
+ }
if (check_region(io_base, 4))
- {
- printk("ad1848.c: Port %x not free.\n", io_base);
- return 0;
- }
+ {
+ printk(KERN_ERR "ad1848.c: Port %x not free.\n", io_base);
+ return 0;
+ }
devc->base = io_base;
devc->irq_ok = 0;
devc->timer_running = 0;
@@ -1403,31 +1408,33 @@ ad1848_detect(int io_base, int *ad_flags, int *osp)
devc->debug_flag = 0;
/*
- * Check that the I/O address is in use.
- *
- * The bit 0x80 of the base I/O port is known to be 0 after the
- * chip has performed its power on initialization. Just assume
- * this has happened before the OS is starting.
- *
- * If the I/O address is unused, it typically returns 0xff.
+ * Check that the I/O address is in use.
+ *
+ * The bit 0x80 of the base I/O port is known to be 0 after the
+ * chip has performed its power on initialization. Just assume
+ * this has happened before the OS is starting.
+ *
+ * If the I/O address is unused, it typically returns 0xff.
*/
if (inb(devc->base) == 0xff)
- {
- DDB(printk("ad1848_detect: The base I/O address appears to be dead\n"));
- }
-/*
- * Wait for the device to stop initialization
- */
+ {
+ DDB(printk("ad1848_detect: The base I/O address appears to be dead\n"));
+ }
+
+ /*
+ * Wait for the device to stop initialization
+ */
+
DDB(printk("ad1848_detect() - step 0\n"));
for (i = 0; i < 10000000; i++)
- {
- unsigned char x = inb(devc->base);
+ {
+ unsigned char x = inb(devc->base);
- if (x == 0xff || !(x & 0x80))
- break;
- }
+ if (x == 0xff || !(x & 0x80))
+ break;
+ }
DDB(printk("ad1848_detect() - step A\n"));
@@ -1435,14 +1442,15 @@ ad1848_detect(int io_base, int *ad_flags, int *osp)
ad_leave_MCE(devc);
if ((inb(devc->base) & 0x80) != 0x00) /* Not a AD1848 */
- {
- DDB(printk("ad1848 detect error - step A (%02x)\n", (int) inb(devc->base)));
- return 0;
- }
+ {
+ DDB(printk("ad1848 detect error - step A (%02x)\n", (int) inb(devc->base)));
+ return 0;
+ }
+
/*
- * Test if it's possible to change contents of the indirect registers.
- * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only
- * so try to avoid using it.
+ * Test if it's possible to change contents of the indirect registers.
+ * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only
+ * so try to avoid using it.
*/
DDB(printk("ad1848_detect() - step B\n"));
@@ -1450,28 +1458,33 @@ ad1848_detect(int io_base, int *ad_flags, int *osp)
ad_write(devc, 1, 0x45); /* 0x55 with bit 0x10 clear */
if ((tmp1 = ad_read(devc, 0)) != 0xaa || (tmp2 = ad_read(devc, 1)) != 0x45)
+ {
if (tmp2 == 0x65) /* AD1847 has couple of bits hardcoded to 1 */
ad1847_flag = 1;
else
- {
- DDB(printk("ad1848 detect error - step B (%x/%x)\n", tmp1, tmp2));
- return 0;
- }
+ {
+ DDB(printk("ad1848 detect error - step B (%x/%x)\n", tmp1, tmp2));
+ return 0;
+ }
+ }
DDB(printk("ad1848_detect() - step C\n"));
ad_write(devc, 0, 0x45);
ad_write(devc, 1, 0xaa);
if ((tmp1 = ad_read(devc, 0)) != 0x45 || (tmp2 = ad_read(devc, 1)) != 0xaa)
+ {
if (tmp2 == 0x8a) /* AD1847 has few bits hardcoded to 1 */
ad1847_flag = 1;
else
- {
- DDB(printk("ad1848 detect error - step C (%x/%x)\n", tmp1, tmp2));
- return 0;
- }
+ {
+ DDB(printk("ad1848 detect error - step C (%x/%x)\n", tmp1, tmp2));
+ return 0;
+ }
+ }
+
/*
- * The indirect register I12 has some read only bits. Lets
- * try to change them.
+ * The indirect register I12 has some read only bits. Lets
+ * try to change them.
*/
DDB(printk("ad1848_detect() - step D\n"));
@@ -1479,43 +1492,47 @@ ad1848_detect(int io_base, int *ad_flags, int *osp)
ad_write(devc, 12, (~tmp) & 0x0f);
if ((tmp & 0x0f) != ((tmp1 = ad_read(devc, 12)) & 0x0f))
- {
- DDB(printk("ad1848 detect error - step D (%x)\n", tmp1));
- return 0;
- }
+ {
+ DDB(printk("ad1848 detect error - step D (%x)\n", tmp1));
+ return 0;
+ }
+
/*
- * NOTE! Last 4 bits of the reg I12 tell the chip revision.
- * 0x01=RevB and 0x0A=RevC.
+ * NOTE! Last 4 bits of the reg I12 tell the chip revision.
+ * 0x01=RevB and 0x0A=RevC.
*/
/*
- * The original AD1848/CS4248 has just 15 indirect registers. This means
- * that I0 and I16 should return the same value (etc.).
- * However this doesn't work with CS4248. Actually it seems to be impossible
- * to detect if the chip is a CS4231 or CS4248.
- * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test fails
- * with CS4231.
+ * The original AD1848/CS4248 has just 15 indirect registers. This means
+ * that I0 and I16 should return the same value (etc.).
+ * However this doesn't work with CS4248. Actually it seems to be impossible
+ * to detect if the chip is a CS4231 or CS4248.
+ * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test fails
+ * with CS4231.
*/
-/*
- * OPTi 82C930 has mode2 control bit in another place. This test will fail
- * with it. Accept this situation as a possible indication of this chip.
- */
+ /*
+ * OPTi 82C930 has mode2 control bit in another place. This test will fail
+ * with it. Accept this situation as a possible indication of this chip.
+ */
DDB(printk("ad1848_detect() - step F\n"));
ad_write(devc, 12, 0); /* Mode2=disabled */
for (i = 0; i < 16; i++)
+ {
if ((tmp1 = ad_read(devc, i)) != (tmp2 = ad_read(devc, i + 16)))
- {
- DDB(printk("ad1848 detect step F(%d/%x/%x) - OPTi chip???\n", i, tmp1, tmp2));
- if (!ad1847_flag)
- optiC930 = 1;
- break;
- }
+ {
+ DDB(printk("ad1848 detect step F(%d/%x/%x) - OPTi chip???\n", i, tmp1, tmp2));
+ if (!ad1847_flag)
+ optiC930 = 1;
+ break;
+ }
+ }
+
/*
- * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit (0x40).
- * The bit 0x80 is always 1 in CS4248 and CS4231.
+ * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit (0x40).
+ * The bit 0x80 is always 1 in CS4248 and CS4231.
*/
DDB(printk("ad1848_detect() - step G\n"));
@@ -1531,66 +1548,67 @@ ad1848_detect(int io_base, int *ad_flags, int *osp)
tmp1 = ad_read(devc, 12);
if (tmp1 & 0x80)
- {
- if (ad_flags)
- *ad_flags |= AD_F_CS4248;
+ {
+ if (ad_flags)
+ *ad_flags |= AD_F_CS4248;
- devc->chip_name = "CS4248"; /* Our best knowledge just now */
- }
+ devc->chip_name = "CS4248"; /* Our best knowledge just now */
+ }
if (optiC930 || (tmp1 & 0xc0) == (0x80 | 0x40))
- {
- /*
- * CS4231 detected - is it?
- *
- * Verify that setting I0 doesn't change I16.
- */
- DDB(printk("ad1848_detect() - step H\n"));
- ad_write(devc, 16, 0); /* Set I16 to known value */
-
- ad_write(devc, 0, 0x45);
- if ((tmp1 = ad_read(devc, 16)) != 0x45) /* No change -> CS4231? */
- {
-
- ad_write(devc, 0, 0xaa);
- if ((tmp1 = ad_read(devc, 16)) == 0xaa) /* Rotten bits? */
- {
- DDB(printk("ad1848 detect error - step H(%x)\n", tmp1));
- return 0;
- }
- /*
- * Verify that some bits of I25 are read only.
- */
-
- DDB(printk("ad1848_detect() - step I\n"));
- tmp1 = ad_read(devc, 25); /* Original bits */
- ad_write(devc, 25, ~tmp1); /* Invert all bits */
- if ((ad_read(devc, 25) & 0xe7) == (tmp1 & 0xe7))
- {
- int id, full_id;
-
- /*
- * It's at least CS4231
- */
- devc->chip_name = "CS4231";
-
- devc->model = MD_4231;
-
- /*
- * It could be an AD1845 or CS4231A as well.
- * CS4231 and AD1845 report the same revision info in I25
- * while the CS4231A reports different.
- */
-
- id = ad_read(devc, 25) & 0xe7;
- full_id = ad_read(devc, 25);
- if (id == 0x80) /* Device busy??? */
- id = ad_read(devc, 25) & 0xe7;
- if (id == 0x80) /* Device still busy??? */
- id = ad_read(devc, 25) & 0xe7;
- DDB(printk("ad1848_detect() - step J (%02x/%02x)\n", id, ad_read(devc, 25)));
-
- switch (id)
- {
+ {
+ /*
+ * CS4231 detected - is it?
+ *
+ * Verify that setting I0 doesn't change I16.
+ */
+
+ DDB(printk("ad1848_detect() - step H\n"));
+ ad_write(devc, 16, 0); /* Set I16 to known value */
+
+ ad_write(devc, 0, 0x45);
+ if ((tmp1 = ad_read(devc, 16)) != 0x45) /* No change -> CS4231? */
+ {
+ ad_write(devc, 0, 0xaa);
+ if ((tmp1 = ad_read(devc, 16)) == 0xaa) /* Rotten bits? */
+ {
+ DDB(printk("ad1848 detect error - step H(%x)\n", tmp1));
+ return 0;
+ }
+
+ /*
+ * Verify that some bits of I25 are read only.
+ */
+
+ DDB(printk("ad1848_detect() - step I\n"));
+ tmp1 = ad_read(devc, 25); /* Original bits */
+ ad_write(devc, 25, ~tmp1); /* Invert all bits */
+ if ((ad_read(devc, 25) & 0xe7) == (tmp1 & 0xe7))
+ {
+ int id, full_id;
+
+ /*
+ * It's at least CS4231
+ */
+
+ devc->chip_name = "CS4231";
+ devc->model = MD_4231;
+
+ /*
+ * It could be an AD1845 or CS4231A as well.
+ * CS4231 and AD1845 report the same revision info in I25
+ * while the CS4231A reports different.
+ */
+
+ id = ad_read(devc, 25) & 0xe7;
+ full_id = ad_read(devc, 25);
+ if (id == 0x80) /* Device busy??? */
+ id = ad_read(devc, 25) & 0xe7;
+ if (id == 0x80) /* Device still busy??? */
+ id = ad_read(devc, 25) & 0xe7;
+ DDB(printk("ad1848_detect() - step J (%02x/%02x)\n", id, ad_read(devc, 25)));
+
+ switch (id)
+ {
case 0xa0:
devc->chip_name = "CS4231A";
@@ -1628,25 +1646,26 @@ ad1848_detect(int io_base, int *ad_flags, int *osp)
*/
unsigned char tmp = ad_read(devc, 23);
-
ad_write(devc, 23, ~tmp);
+
if (interwave)
- {
- devc->model = MD_IWAVE;
- devc->chip_name = "IWave";
- } else if (ad_read(devc, 23) != tmp) /* AD1845 ? */
- {
- devc->chip_name = "AD1845";
- devc->model = MD_1845;
- } else if (cs4248_flag)
- {
- if (ad_flags)
+ {
+ devc->model = MD_IWAVE;
+ devc->chip_name = "IWave";
+ }
+ else if (ad_read(devc, 23) != tmp) /* AD1845 ? */
+ {
+ devc->chip_name = "AD1845";
+ devc->model = MD_1845;
+ }
+ else if (cs4248_flag)
+ {
+ if (ad_flags)
*ad_flags |= AD_F_CS4248;
-
- devc->chip_name = "CS4248";
- devc->model = MD_1848;
- ad_write(devc, 12, ad_read(devc, 12) & ~0x40); /* Mode2 off */
- }
+ devc->chip_name = "CS4248";
+ devc->model = MD_1848;
+ ad_write(devc, 12, ad_read(devc, 12) & ~0x40); /* Mode2 off */
+ }
ad_write(devc, 23, tmp); /* Restore */
}
break;
@@ -1654,27 +1673,27 @@ ad1848_detect(int io_base, int *ad_flags, int *osp)
default: /* Assume CS4231 or OPTi 82C930 */
DDB(printk("ad1848: I25 = %02x/%02x\n", ad_read(devc, 25), ad_read(devc, 25) & 0xe7));
if (optiC930)
- {
- devc->chip_name = "82C930";
- devc->model = MD_C930;
- } else
- {
- devc->model = MD_4231;
- }
-
- }
- }
- ad_write(devc, 25, tmp1); /* Restore bits */
-
- DDB(printk("ad1848_detect() - step K\n"));
- }
- }
+ {
+ devc->chip_name = "82C930";
+ devc->model = MD_C930;
+ }
+ else
+ {
+ devc->model = MD_4231;
+ }
+ }
+ }
+ ad_write(devc, 25, tmp1); /* Restore bits */
+
+ DDB(printk("ad1848_detect() - step K\n"));
+ }
+ }
DDB(printk("ad1848_detect() - step L\n"));
if (ad_flags)
- {
+ {
if (devc->model != MD_1848)
*ad_flags |= AD_F_CS4231;
- }
+ }
DDB(printk("ad1848_detect() - Detected OK\n"));
if (devc->model == MD_1848 && ad1847_flag)
@@ -1684,21 +1703,20 @@ ad1848_detect(int io_base, int *ad_flags, int *osp)
return 1;
}
-int
-ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capture, int share_dma, int *osp)
+int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capture, int share_dma, int *osp)
{
/*
- * NOTE! If irq < 0, there is another driver which has allocated the IRQ
- * so that this driver doesn't need to allocate/deallocate it.
- * The actually used IRQ is ABS(irq).
+ * NOTE! If irq < 0, there is another driver which has allocated the IRQ
+ * so that this driver doesn't need to allocate/deallocate it.
+ * The actually used IRQ is ABS(irq).
*/
- int my_dev;
- char dev_name[100];
- int e;
+ int my_dev;
+ char dev_name[100];
+ int e;
- ad1848_info *devc = &adev_info[nr_ad1848_devs];
+ ad1848_info *devc = &adev_info[nr_ad1848_devs];
ad1848_port_info *portc = NULL;
@@ -1721,19 +1739,19 @@ ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capture,
request_region(devc->base, 4, devc->name);
- conf_printf2(dev_name,
- devc->base, devc->irq, dma_playback, dma_capture);
+ conf_printf2(dev_name, devc->base, devc->irq, dma_playback, dma_capture);
if (devc->model == MD_1848 || devc->model == MD_C930)
devc->audio_flags |= DMA_HARDSTOP;
if (devc->model > MD_1848)
- {
- if (devc->dma1 == devc->dma2 || devc->dma2 == -1 || devc->dma1 == -1)
- devc->audio_flags &= ~DMA_DUPLEX;
- else
- devc->audio_flags |= DMA_DUPLEX;
- }
+ {
+ if (devc->dma1 == devc->dma2 || devc->dma2 == -1 || devc->dma1 == -1)
+ devc->audio_flags &= ~DMA_DUPLEX;
+ else
+ devc->audio_flags |= DMA_DUPLEX;
+ }
+
if ((my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
dev_name,
&ad1848_audio_driver,
@@ -1743,9 +1761,9 @@ ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capture,
devc,
dma_playback,
dma_capture)) < 0)
- {
- return -1;
- }
+ {
+ return -1;
+ }
portc = (ad1848_port_info *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(ad1848_port_info)));
sound_mem_sizes[sound_nblocks] = sizeof(ad1848_port_info);
if (sound_nblocks < 1024)
@@ -1758,37 +1776,38 @@ ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capture,
ad1848_init_hw(devc);
if (irq > 0)
- {
- irq2dev[irq] = devc->dev_no = my_dev;
- if (snd_set_irq_handler(devc->irq, adintr,
+ {
+ irq2dev[irq] = devc->dev_no = my_dev;
+ if (snd_set_irq_handler(devc->irq, adintr,
devc->name,
NULL) < 0)
- {
- printk(KERN_WARNING "ad1848: IRQ in use\n");
- }
- if (devc->model != MD_1848 && devc->model != MD_C930)
- {
- int x;
- unsigned char tmp = ad_read(devc, 16);
-
- devc->timer_ticks = 0;
-
- ad_write(devc, 21, 0x00); /* Timer MSB */
- ad_write(devc, 20, 0x10); /* Timer LSB */
-
- ad_write(devc, 16, tmp | 0x40); /* Enable timer */
- for (x = 0; x < 100000 && devc->timer_ticks == 0; x++);
- ad_write(devc, 16, tmp & ~0x40); /* Disable timer */
-
- if (devc->timer_ticks == 0)
- printk(KERN_WARNING "ad1848: Interrupt test failed (IRQ%d)\n", devc->irq);
- else
- {
- DDB(printk("Interrupt test OK\n"));
- devc->irq_ok = 1;
- }
- } else
- devc->irq_ok = 1; /* Couldn't test. assume it's OK */
+ {
+ printk(KERN_WARNING "ad1848: IRQ in use\n");
+ }
+ if (devc->model != MD_1848 && devc->model != MD_C930)
+ {
+ int x;
+ unsigned char tmp = ad_read(devc, 16);
+
+ devc->timer_ticks = 0;
+
+ ad_write(devc, 21, 0x00); /* Timer MSB */
+ ad_write(devc, 20, 0x10); /* Timer LSB */
+
+ ad_write(devc, 16, tmp | 0x40); /* Enable timer */
+ for (x = 0; x < 100000 && devc->timer_ticks == 0; x++);
+ ad_write(devc, 16, tmp & ~0x40); /* Disable timer */
+
+ if (devc->timer_ticks == 0)
+ printk(KERN_WARNING "ad1848: Interrupt test failed (IRQ%d)\n", devc->irq);
+ else
+ {
+ DDB(printk("Interrupt test OK\n"));
+ devc->irq_ok = 1;
+ }
+ }
+ else
+ devc->irq_ok = 1; /* Couldn't test. assume it's OK */
} else if (irq < 0)
irq2dev[-irq] = devc->dev_no = my_dev;
@@ -1799,22 +1818,22 @@ ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capture,
#endif
if (!share_dma)
- {
- if (sound_alloc_dma(dma_playback, devc->name))
- printk("ad1848.c: Can't allocate DMA%d\n", dma_playback);
-
- if (dma_capture != dma_playback)
- if (sound_alloc_dma(dma_capture, devc->name))
- printk("ad1848.c: Can't allocate DMA%d\n", dma_capture);
- }
+ {
+ if (sound_alloc_dma(dma_playback, devc->name))
+ printk(KERN_WARNING "ad1848.c: Can't allocate DMA%d\n", dma_playback);
+
+ if (dma_capture != dma_playback)
+ if (sound_alloc_dma(dma_capture, devc->name))
+ printk(KERN_WARNING "ad1848.c: Can't allocate DMA%d\n", dma_capture);
+ }
if ((e = sound_install_mixer(MIXER_DRIVER_VERSION,
dev_name,
&ad1848_mixer_operations,
sizeof(struct mixer_operations),
devc)) >= 0)
- {
- audio_devs[my_dev]->mixer_dev = e;
- }
+ {
+ audio_devs[my_dev]->mixer_dev = e;
+ }
MOD_INC_USE_COUNT;
return my_dev;
}
@@ -1829,76 +1848,79 @@ void ad1848_control(int cmd, int arg)
devc = &adev_info[nr_ad1848_devs - 1];
switch (cmd)
- {
- case AD1848_SET_XTAL: /* Change clock frequency of AD1845 (only ) */
- if (devc->model != MD_1845)
- return;
- ad_enter_MCE(devc);
- ad_write(devc, 29, (ad_read(devc, 29) & 0x1f) | (arg << 5));
- ad_leave_MCE(devc);
- break;
-
- case AD1848_MIXER_REROUTE:
- {
- int o = (arg >> 8) & 0xff;
- int n = arg & 0xff;
-
- 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;
- }
- /* 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 */
-
- devc->mixer_reroute[n] = o; /* Rename the control */
- 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_rec_devices &= ~(1 << o);
- }
- break;
- }
+ {
+ case AD1848_SET_XTAL: /* Change clock frequency of AD1845 (only ) */
+ if (devc->model != MD_1845)
+ return;
+ ad_enter_MCE(devc);
+ ad_write(devc, 29, (ad_read(devc, 29) & 0x1f) | (arg << 5));
+ ad_leave_MCE(devc);
+ break;
+
+ case AD1848_MIXER_REROUTE:
+ {
+ int o = (arg >> 8) & 0xff;
+ int n = arg & 0xff;
+
+ 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;
+ }
+ /* 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 */
+
+ devc->mixer_reroute[n] = o; /* Rename the control */
+ 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_rec_devices &= ~(1 << o);
+ }
+ break;
+ }
return;
}
-void
-ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int share_dma)
+void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int share_dma)
{
- int i, dev = 0;
- ad1848_info *devc = NULL;
+ int i, dev = 0;
+ ad1848_info *devc = NULL;
for (i = 0; devc == NULL && i < nr_ad1848_devs; i++)
+ {
if (adev_info[i].base == io_base)
- {
- devc = &adev_info[i];
- dev = devc->dev_no;
- }
+ {
+ devc = &adev_info[i];
+ dev = devc->dev_no;
+ }
+ }
+
if (devc != NULL)
- {
- release_region(devc->base, 4);
+ {
+ release_region(devc->base, 4);
- if (!share_dma)
- {
- if (irq > 0)
- snd_release_irq(devc->irq);
+ if (!share_dma)
+ {
+ if (irq > 0)
+ snd_release_irq(devc->irq);
- sound_free_dma(audio_devs[dev]->dmap_out->dma);
+ sound_free_dma(audio_devs[dev]->dmap_out->dma);
- if (audio_devs[dev]->dmap_in->dma != audio_devs[dev]->dmap_out->dma)
- sound_free_dma(audio_devs[dev]->dmap_in->dma);
- }
- } else
- printk("ad1848: Can't find device to be unloaded. Base=%x\n", io_base);
+ if (audio_devs[dev]->dmap_in->dma != audio_devs[dev]->dmap_out->dma)
+ sound_free_dma(audio_devs[dev]->dmap_in->dma);
+ }
+ }
+ else
+ printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base);
MOD_DEC_USE_COUNT;
}
@@ -1912,94 +1934,96 @@ void adintr(int irq, void *dev_id, struct pt_regs *dummy)
int cnt = 0;
if (irq < 0 || irq > 15)
- {
- dev = -1;
- } else
+ {
+ dev = -1;
+ }
+ else
dev = irq2dev[irq];
if (dev < 0 || dev >= num_audiodevs)
- {
- for (irq = 0; irq < 17; irq++)
- if (irq2dev[irq] != -1)
- break;
-
- if (irq > 15)
- {
- /* printk("ad1848.c: Bogus interrupt %d\n", irq); */
- return;
- }
- dev = irq2dev[irq];
- devc = (ad1848_info *) audio_devs[dev]->devc;
+ {
+ for (irq = 0; irq < 17; irq++)
+ if (irq2dev[irq] != -1)
+ break;
+
+ if (irq > 15)
+ {
+ /* printk("ad1848.c: Bogus interrupt %d\n", irq); */
+ return;
+ }
+ dev = irq2dev[irq];
+ devc = (ad1848_info *) audio_devs[dev]->devc;
} else
devc = (ad1848_info *) audio_devs[dev]->devc;
- interrupt_again: /* Jump back here if int status doesn't reset */
+interrupt_again: /* Jump back here if int status doesn't reset */
status = inb(io_Status(devc));
if (status == 0x80)
- printk("adintr: Why?\n");
+ printk(KERN_DEBUG "adintr: Why?\n");
if (devc->model == MD_1848)
outb((0), io_Status(devc)); /* Clear interrupt status */
if (status & 0x01)
- {
- if (devc->model == MD_C930)
- { /* 82C930 has interrupt status register in MAD16 register MC11 */
- unsigned long flags;
-
- save_flags(flags);
- cli();
-
- alt_stat = 0;
-
- if (devc->c930_password_port)
- outb((0xe4), devc->c930_password_port); /* Password */
- outb((11), 0xe0e);
- c930_stat = inb(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);
- } else if (devc->model != MD_1848)
- 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)
- {
- DMAbuf_inputintr(devc->record_dev);
- }
- if (devc->open_mode & OPEN_WRITE && devc->audio_mode & PCM_ENABLE_OUTPUT &&
+ {
+ if (devc->model == MD_C930)
+ { /* 82C930 has interrupt status register in MAD16 register MC11 */
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+
+ alt_stat = 0;
+
+ if (devc->c930_password_port)
+ outb((0xe4), devc->c930_password_port); /* Password */
+ outb(11, 0xe0e);
+ c930_stat = inb(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);
+ }
+ else if (devc->model != MD_1848)
+ 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)
+ {
+ DMAbuf_inputintr(devc->record_dev);
+ }
+ if (devc->open_mode & OPEN_WRITE && devc->audio_mode & PCM_ENABLE_OUTPUT &&
alt_stat & 0x10)
- {
- DMAbuf_outputintr(devc->playback_dev, 1);
- }
- if (devc->model != MD_1848 && alt_stat & 0x40) /* Timer interrupt */
- {
- devc->timer_ticks++;
+ {
+ DMAbuf_outputintr(devc->playback_dev, 1);
+ }
+ if (devc->model != MD_1848 && alt_stat & 0x40) /* Timer interrupt */
+ {
+ devc->timer_ticks++;
#if (defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)) || defined(MODULE)
- if (timer_installed == dev && devc->timer_running)
- sound_timer_interrupt();
+ if (timer_installed == dev && devc->timer_running)
+ sound_timer_interrupt();
#endif
- }
- }
+ }
+ }
/*
* Sometimes playback or capture interrupts occur while a timer interrupt
* is being handled. The interrupt will not be retriggered if we don't
@@ -2007,63 +2031,61 @@ void adintr(int irq, void *dev_id, struct pt_regs *dummy)
* the handler in this case.
*/
if (inb(io_Status(devc)) & 0x01 && cnt++ < 4)
- {
+ {
goto interrupt_again;
- }
+ }
}
-#ifdef DESKPROXL
/*
- * Very experimental initialization sequence for the integrated sound system
- * of Compaq Deskpro XL. Will be moved somewhere else in future.
+ * Experimental initialization sequence for the integrated sound system
+ * of Compaq Deskpro XL.
*/
-static int
-init_deskpro(struct address_info *hw_config)
+static int init_deskpro(struct address_info *hw_config)
{
unsigned char tmp;
if ((tmp = inb(0xc44)) == 0xff)
- {
- DDB(printk("init_deskpro: Dead port 0xc44\n"));
- return 0;
- }
+ {
+ DDB(printk("init_deskpro: Dead port 0xc44\n"));
+ return 0;
+ }
outb((tmp | 0x04), 0xc44); /* Select bank 1 */
if (inb(0xc44) != 0x04)
- {
- DDB(printk("init_deskpro: Invalid bank1 signature in port 0xc44\n"));
- return 0;
- }
-/*
- * OK. It looks like a Deskpro so let's proceed.
- */
+ {
+ DDB(printk("init_deskpro: Invalid bank1 signature in port 0xc44\n"));
+ return 0;
+ }
+ /*
+ * OK. It looks like a Deskpro so let's proceed.
+ */
-/*
- * I/O port 0xc44 Audio configuration register.
- *
- * bits 0xc0: Audio revision bits
- * 0x00 = Compaq Business Audio
- * 0x40 = MS Sound System Compatible (reset default)
- * 0x80 = Reserved
- * 0xc0 = Reserved
- * bit 0x20: No Wait State Enable
- * 0x00 = Disabled (reset default, DMA mode)
- * 0x20 = Enabled (programmed I/O mode)
- * bit 0x10: MS Sound System Decode Enable
- * 0x00 = Decoding disabled (reset default)
- * 0x10 = Decoding enabled
- * bit 0x08: FM Synthesis Decode Enable
- * 0x00 = Decoding Disabled (reset default)
- * 0x08 = Decoding enabled
- * bit 0x04 Bank select
- * 0x00 = Bank 0
- * 0x04 = Bank 1
- * bits 0x03 MSS Base address
- * 0x00 = 0x530 (reset default)
- * 0x01 = 0x604
- * 0x02 = 0xf40
- * 0x03 = 0xe80
- */
+ /*
+ * I/O port 0xc44 Audio configuration register.
+ *
+ * bits 0xc0: Audio revision bits
+ * 0x00 = Compaq Business Audio
+ * 0x40 = MS Sound System Compatible (reset default)
+ * 0x80 = Reserved
+ * 0xc0 = Reserved
+ * bit 0x20: No Wait State Enable
+ * 0x00 = Disabled (reset default, DMA mode)
+ * 0x20 = Enabled (programmed I/O mode)
+ * bit 0x10: MS Sound System Decode Enable
+ * 0x00 = Decoding disabled (reset default)
+ * 0x10 = Decoding enabled
+ * bit 0x08: FM Synthesis Decode Enable
+ * 0x00 = Decoding Disabled (reset default)
+ * 0x08 = Decoding enabled
+ * bit 0x04 Bank select
+ * 0x00 = Bank 0
+ * 0x04 = Bank 1
+ * bits 0x03 MSS Base address
+ * 0x00 = 0x530 (reset default)
+ * 0x01 = 0x604
+ * 0x02 = 0xf40
+ * 0x03 = 0xe80
+ */
#ifdef DEBUGXL
/* Debug printing */
@@ -2078,23 +2100,23 @@ init_deskpro(struct address_info *hw_config)
tmp = 0x58; /* MSS Mode, MSS&FM decode enabled */
switch (hw_config->io_base)
- {
- case 0x530:
- tmp |= 0x00;
- break;
- case 0x604:
- tmp |= 0x01;
- break;
- case 0xf40:
- tmp |= 0x02;
- break;
- case 0xe80:
- tmp |= 0x03;
- break;
- default:
- DDB(printk("init_deskpro: Invalid MSS port %x\n", hw_config->io_base));
- return 0;
- }
+ {
+ case 0x530:
+ tmp |= 0x00;
+ break;
+ case 0x604:
+ tmp |= 0x01;
+ break;
+ case 0xf40:
+ tmp |= 0x02;
+ break;
+ case 0xe80:
+ tmp |= 0x03;
+ break;
+ default:
+ DDB(printk("init_deskpro: Invalid MSS port %x\n", hw_config->io_base));
+ return 0;
+ }
outb((tmp & ~0x04), 0xc44); /* Write to bank=0 */
#ifdef DEBUGXL
@@ -2106,15 +2128,15 @@ init_deskpro(struct address_info *hw_config)
printk("%02x\n", inb(0xc44));
#endif
-/*
- * I/O port 0xc45 FM Address Decode/MSS ID Register.
- *
- * bank=0, bits 0xfe: FM synthesis Decode Compare bits 7:1 (default=0x88)
- * bank=0, bit 0x01: SBIC Power Control Bit
- * 0x00 = Powered up
- * 0x01 = Powered down
- * bank=1, bits 0xfc: MSS ID (default=0x40)
- */
+ /*
+ * I/O port 0xc45 FM Address Decode/MSS ID Register.
+ *
+ * bank=0, bits 0xfe: FM synthesis Decode Compare bits 7:1 (default=0x88)
+ * bank=0, bit 0x01: SBIC Power Control Bit
+ * 0x00 = Powered up
+ * 0x01 = Powered down
+ * bank=1, bits 0xfc: MSS ID (default=0x40)
+ */
#ifdef DEBUGXL
/* Debug printing */
@@ -2140,12 +2162,12 @@ init_deskpro(struct address_info *hw_config)
#endif
-/*
- * I/O port 0xc46 FM Address Decode/Address ASIC Revision Register.
- *
- * bank=0, bits 0xff: FM synthesis Decode Compare bits 15:8 (default=0x03)
- * bank=1, bits 0xff: Audio addressing ASIC id
- */
+ /*
+ * I/O port 0xc46 FM Address Decode/Address ASIC Revision Register.
+ *
+ * bank=0, bits 0xff: FM synthesis Decode Compare bits 15:8 (default=0x03)
+ * bank=1, bits 0xff: Audio addressing ASIC id
+ */
#ifdef DEBUGXL
/* Debug printing */
@@ -2170,12 +2192,12 @@ init_deskpro(struct address_info *hw_config)
printk("%02x\n", inb(0xc46));
#endif
-/*
- * I/O port 0xc47 FM Address Decode Register.
- *
- * bank=0, bits 0xff: Decode enable selection for various FM address bits
- * bank=1, bits 0xff: Reserved
- */
+ /*
+ * I/O port 0xc47 FM Address Decode Register.
+ *
+ * bank=0, bits 0xff: Decode enable selection for various FM address bits
+ * bank=1, bits 0xff: Reserved
+ */
#ifdef DEBUGXL
/* Debug printing */
@@ -2200,9 +2222,9 @@ init_deskpro(struct address_info *hw_config)
printk("%02x\n", inb(0xc47));
#endif
-/*
- * I/O port 0xc6f = Audio Disable Function Register
- */
+ /*
+ * I/O port 0xc6f = Audio Disable Function Register
+ */
#ifdef DEBUGXL
printk("Port 0xc6f (before) = %02x\n", inb(0xc6f));
@@ -2216,32 +2238,29 @@ init_deskpro(struct address_info *hw_config)
return 1;
}
-#endif
-int
-probe_ms_sound(struct address_info *hw_config)
+int probe_ms_sound(struct address_info *hw_config)
{
unsigned char tmp;
DDB(printk("Entered probe_ms_sound(%x, %d)\n", hw_config->io_base, hw_config->card_subtype));
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 (hw_config->card_subtype == 1) /* Has no IRQ/DMA registers */
- {
- /* check_opl3(0x388, hw_config); */
- return ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp);
- }
-#ifdef DESKPROXL
- if (hw_config->card_subtype == 2) /* Compaq Deskpro XL */
- {
- if (!init_deskpro(hw_config))
- return 0;
- }
-#endif
+ {
+ /* check_opl3(0x388, hw_config); */
+ return ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp);
+ }
+
+ if (deskpro_xl && hw_config->card_subtype == 2) /* Compaq Deskpro XL */
+ {
+ if (!init_deskpro(hw_config))
+ return 0;
+ }
/*
* Check if the IO port returns valid signature. The original MS Sound
@@ -2250,58 +2269,57 @@ probe_ms_sound(struct address_info *hw_config)
*/
if ((tmp = inb(hw_config->io_base + 3)) == 0xff) /* Bus float */
- {
+ {
int ret;
DDB(printk("I/O address is inactive (%x)\n", tmp));
if (!(ret = ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp)))
return 0;
return 1;
- }
+ }
DDB(printk("MSS signature = %x\n", tmp & 0x3f));
if ((tmp & 0x3f) != 0x04 &&
(tmp & 0x3f) != 0x0f &&
(tmp & 0x3f) != 0x00)
- {
- int ret;
+ {
+ int ret;
- MDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, (int) inb(hw_config->io_base + 3)));
- DDB(printk("Trying to detect codec anyway but IRQ/DMA may not work\n"));
- if (!(ret = ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp)))
- return 0;
+ MDB(printk(KERN_ERR "No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, (int) inb(hw_config->io_base + 3)));
+ DDB(printk("Trying to detect codec anyway but IRQ/DMA may not work\n"));
+ if (!(ret = ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp)))
+ return 0;
- hw_config->card_subtype = 1;
- return 1;
- }
+ hw_config->card_subtype = 1;
+ return 1;
+ }
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);
+ {
+ 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(KERN_ERR "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);
- return 0;
- }
+ {
+ printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
+ return 0;
+ }
return ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp);
}
-void
-attach_ms_sound(struct address_info *hw_config)
+void attach_ms_sound(struct address_info *hw_config)
{
static char interrupt_bits[12] =
{
@@ -2314,63 +2332,65 @@ attach_ms_sound(struct address_info *hw_config)
1, 2, 0, 3
};
- int config_port = hw_config->io_base + 0;
- int version_port = hw_config->io_base + 3;
- int dma = hw_config->dma;
- int dma2 = hw_config->dma2;
+ int config_port = hw_config->io_base + 0;
+ int version_port = hw_config->io_base + 3;
+ int dma = hw_config->dma;
+ int dma2 = hw_config->dma2;
if (hw_config->card_subtype == 1) /* Has no IRQ/DMA registers */
- {
- hw_config->slots[0] = ad1848_init("MS Sound System", hw_config->io_base + 4,
+ {
+ hw_config->slots[0] = ad1848_init("MS Sound System", hw_config->io_base + 4,
hw_config->irq,
hw_config->dma,
hw_config->dma2, 0, hw_config->osp);
- request_region(hw_config->io_base, 4, "WSS config");
- return;
- }
+ request_region(hw_config->io_base, 4, "WSS config");
+ return;
+ }
/*
- * Set the IRQ and DMA addresses.
+ * Set the IRQ and DMA addresses.
*/
bits = interrupt_bits[hw_config->irq];
if (bits == -1)
- {
- printk("MSS: Bad IRQ %d\n", hw_config->irq);
- return;
- }
+ {
+ printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq);
+ return;
+ }
outb((bits | 0x40), config_port);
if ((inb(version_port) & 0x40) == 0)
- printk("[MSS: IRQ Conflict?]");
+ printk(KERN_ERR "[MSS: IRQ Conflict?]\n");
/*
* Handle the capture DMA channel
*/
if (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("MSS: 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(KERN_WARNING "MSS: Invalid capture DMA\n");
+ dma2 = dma;
+ }
+ }
+ else
+ {
+ dma2 = dma;
+ }
hw_config->dma = dma;
hw_config->dma2 = dma2;
@@ -2385,8 +2405,7 @@ attach_ms_sound(struct address_info *hw_config)
request_region(hw_config->io_base, 4, "WSS config");
}
-void
-unload_ms_sound(struct address_info *hw_config)
+void unload_ms_sound(struct address_info *hw_config)
{
int mixer = audio_devs[hw_config->slots[0]]->mixer_dev;
ad1848_unload(hw_config->io_base + 4,
@@ -2397,18 +2416,17 @@ unload_ms_sound(struct address_info *hw_config)
sound_unload_mixerdev(mixer);
sound_unload_audiodev(hw_config->slots[0]);
release_region(hw_config->io_base, 4);
-
}
#if (defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)) || defined(MODULE)
+
/*
* Timer stuff (for /dev/music).
*/
static unsigned int current_interval = 0;
-static unsigned int
-ad1848_tmr_start(int dev, unsigned int usecs)
+static unsigned int ad1848_tmr_start(int dev, unsigned int usecs)
{
unsigned long flags;
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
@@ -2418,16 +2436,16 @@ ad1848_tmr_start(int dev, unsigned int usecs)
save_flags(flags);
cli();
-/*
- * Length of the timer interval (in nanoseconds) depends on the
- * selected crystal oscillator. Check this from bit 0x01 of I8.
- *
- * AD1845 has just one oscillator which has cycle time of 10.050 us
- * (when a 24.576 MHz xtal oscillator is used).
- *
- * Convert requested interval to nanoseconds before computing
- * the timer divider.
- */
+ /*
+ * Length of the timer interval (in nanoseconds) depends on the
+ * selected crystal oscillator. Check this from bit 0x01 of I8.
+ *
+ * AD1845 has just one oscillator which has cycle time of 10.050 us
+ * (when a 24.576 MHz xtal oscillator is used).
+ *
+ * Convert requested interval to nanoseconds before computing
+ * the timer divider.
+ */
if (devc->model == MD_1845)
xtal_nsecs = 10050;
@@ -2453,20 +2471,18 @@ ad1848_tmr_start(int dev, unsigned int usecs)
return current_interval = (divider * xtal_nsecs + 500) / 1000;
}
-static void
-ad1848_tmr_reprogram(int dev)
+static void ad1848_tmr_reprogram(int dev)
{
-/*
- * Audio driver has changed sampling rate so that a different xtal
- * oscillator was selected. We have to reprogram the timer rate.
- */
+ /*
+ * Audio driver has changed sampling rate so that a different xtal
+ * oscillator was selected. We have to reprogram the timer rate.
+ */
ad1848_tmr_start(dev, current_interval);
sound_timer_syncinterval(current_interval);
}
-static void
-ad1848_tmr_disable(int dev)
+static void ad1848_tmr_disable(int dev)
{
unsigned long flags;
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
@@ -2478,8 +2494,7 @@ ad1848_tmr_disable(int dev)
restore_flags(flags);
}
-static void
-ad1848_tmr_restart(int dev)
+static void ad1848_tmr_restart(int dev)
{
unsigned long flags;
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
@@ -2503,10 +2518,8 @@ static struct sound_lowlev_timer ad1848_tmr =
ad1848_tmr_restart
};
-static int
-ad1848_tmr_install(int dev)
+static int ad1848_tmr_install(int dev)
{
-
if (timer_installed != -1)
return 0; /* Don't install another timer */
@@ -2521,6 +2534,7 @@ ad1848_tmr_install(int dev)
EXPORT_SYMBOL(ad1848_detect);
EXPORT_SYMBOL(ad1848_init);
EXPORT_SYMBOL(ad1848_unload);
+EXPORT_SYMBOL(ad1848_control);
EXPORT_SYMBOL(adintr);
EXPORT_SYMBOL(probe_ms_sound);
EXPORT_SYMBOL(attach_ms_sound);
@@ -2533,6 +2547,7 @@ MODULE_PARM(irq, "i");
MODULE_PARM(dma, "i");
MODULE_PARM(dma2, "i");
MODULE_PARM(type, "i");
+MODULE_PARM(deskpro_xl, "i");
int io = -1;
int irq = -1;
@@ -2547,7 +2562,7 @@ struct address_info hw_config;
int init_module(void)
{
- printk("ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+ printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n");
if(io!=-1)
{
if(irq == -1 || dma == -1)
@@ -2569,21 +2584,17 @@ int init_module(void)
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
SOUND_LOCK_END;
if(loaded)
unload_ms_sound(&hw_config);
-/* unregister_symtab(&ad1848_syms); */
}
#else
-void
-export_ad1848_syms(void)
+void export_ad1848_syms(void)
{
- register_symtab(&ad1848_syms);
}
#endif
diff --git a/drivers/sound/adlib_card.c b/drivers/sound/adlib_card.c
index a8affde7e..6d7dbb7b3 100644
--- a/drivers/sound/adlib_card.c
+++ b/drivers/sound/adlib_card.c
@@ -28,7 +28,6 @@ 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)) {
DDB(printk("opl3.c: I/O port %x already in use\n", hw_config->io_base));
return 0;
diff --git a/drivers/sound/audio.c b/drivers/sound/audio.c
index 3ccdc5892..b27b1999a 100644
--- a/drivers/sound/audio.c
+++ b/drivers/sound/audio.c
@@ -11,62 +11,61 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
-#include <linux/config.h>
+/*
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * Thomas Sailer : moved several static variables into struct audio_operations
+ * (which is grossly misnamed btw.) because they have the same
+ * lifetime as the rest in there and dynamic allocation saves
+ * 12k or so
+ */
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kerneld.h>
#include "sound_config.h"
#if defined(CONFIG_AUDIO) || defined(MODULE)
-
#include "ulaw.h"
#include "coproc.h"
#define NEUTRAL8 0x80
#define NEUTRAL16 0x00
-static int audio_mode[MAX_AUDIO_DEV];
-static int dev_nblock[MAX_AUDIO_DEV]; /* 1 if in nonblocking mode */
-#define AM_NONE 0
-#define AM_WRITE OPEN_WRITE
-#define AM_READ OPEN_READ
int dma_ioctl(int dev, unsigned int cmd, caddr_t arg);
-
-static int local_format[MAX_AUDIO_DEV], audio_format[MAX_AUDIO_DEV];
-static int local_conversion[MAX_AUDIO_DEV];
-
-#define CNV_MU_LAW 0x00000001
-static int
-set_format(int dev, int fmt)
+static int set_format(int dev, int fmt)
{
if (fmt != AFMT_QUERY)
- {
- local_conversion[dev] = 0;
-
- if (!(audio_devs[dev]->format_mask & fmt)) /* Not supported */
- if (fmt == AFMT_MU_LAW)
- {
- fmt = AFMT_U8;
- local_conversion[dev] = CNV_MU_LAW;
- } else
- fmt = AFMT_U8; /* This is always supported */
-
- audio_format[dev] = audio_devs[dev]->d->set_bits(dev, fmt);
- local_format[dev] = fmt;
- } else
- return local_format[dev];
-
- return local_format[dev];
+ {
+ audio_devs[dev]->local_conversion = 0;
+
+ if (!(audio_devs[dev]->format_mask & fmt)) /* Not supported */
+ {
+ if (fmt == AFMT_MU_LAW)
+ {
+ fmt = AFMT_U8;
+ audio_devs[dev]->local_conversion = CNV_MU_LAW;
+ }
+ else
+ fmt = AFMT_U8; /* This is always supported */
+ }
+ audio_devs[dev]->audio_format = audio_devs[dev]->d->set_bits(dev, fmt);
+ audio_devs[dev]->local_format = fmt;
+ }
+ else
+ return audio_devs[dev]->local_format;
+
+ return audio_devs[dev]->local_format;
}
-int
-audio_open(int dev, struct fileinfo *file)
+int audio_open(int dev, struct file *file)
{
- int ret;
- int bits;
- int dev_type = dev & 0x0f;
- int mode = file->mode & O_ACCMODE;
+ int ret;
+ int bits;
+ int dev_type = dev & 0x0f;
+ int mode = translate_mode(file);
dev = dev >> 4;
@@ -82,31 +81,31 @@ audio_open(int dev, struct fileinfo *file)
return ret;
if (audio_devs[dev]->coproc)
+ {
if ((ret = audio_devs[dev]->coproc->
- open(audio_devs[dev]->coproc->devc, COPR_PCM)) < 0)
- {
- audio_release(dev, file);
- printk("Sound: Can't access coprocessor device\n");
-
- return ret;
- }
- local_conversion[dev] = 0;
+ open(audio_devs[dev]->coproc->devc, COPR_PCM)) < 0)
+ {
+ audio_release(dev, file);
+ printk(KERN_WARNING "Sound: Can't access coprocessor device\n");
+ return ret;
+ }
+ }
+
+ audio_devs[dev]->local_conversion = 0;
if (dev_type == SND_DEV_AUDIO)
- {
- set_format(dev, AFMT_MU_LAW);
- } else
+ set_format(dev, AFMT_MU_LAW);
+ else
set_format(dev, bits);
- audio_mode[dev] = AM_NONE;
- dev_nblock[dev] = 0;
+ audio_devs[dev]->audio_mode = AM_NONE;
+ audio_devs[dev]->dev_nblock = 0;
return ret;
}
-static void
-sync_output(int dev)
+static void sync_output(int dev)
{
int p, i;
int l;
@@ -117,44 +116,44 @@ sync_output(int dev)
dmap->flags |= DMA_POST;
/* Align the write pointer with fragment boundaries */
+
if ((l = dmap->user_counter % dmap->fragment_size) > 0)
- {
- int len;
- unsigned long offs = dmap->user_counter % dmap->bytes_in_use;
-
- len = dmap->fragment_size - l;
- memset(dmap->raw_buf + offs, dmap->neutral_byte, len);
- DMAbuf_move_wrpointer(dev, len);
- }
-/*
- * Clean all unused buffer fragments.
- */
+ {
+ int len;
+ unsigned long offs = dmap->user_counter % dmap->bytes_in_use;
+
+ len = dmap->fragment_size - l;
+ memset(dmap->raw_buf + offs, dmap->neutral_byte, len);
+ DMAbuf_move_wrpointer(dev, len);
+ }
+
+ /*
+ * Clean all unused buffer fragments.
+ */
p = dmap->qtail;
dmap->flags |= DMA_POST;
for (i = dmap->qlen + 1; i < dmap->nbufs; i++)
- {
- p = (p + 1) % dmap->nbufs;
- if (((dmap->raw_buf + p * dmap->fragment_size) + dmap->fragment_size) >
- (dmap->raw_buf + dmap->buffsize))
- printk("audio: Buffer error 2\n");
+ {
+ p = (p + 1) % dmap->nbufs;
+ if (((dmap->raw_buf + p * dmap->fragment_size) + dmap->fragment_size) >
+ (dmap->raw_buf + dmap->buffsize))
+ printk(KERN_ERR "audio: Buffer error 2\n");
- memset(dmap->raw_buf + p * dmap->fragment_size,
- dmap->neutral_byte,
- dmap->fragment_size);
- }
+ memset(dmap->raw_buf + p * dmap->fragment_size,
+ dmap->neutral_byte,
+ dmap->fragment_size);
+ }
dmap->flags |= DMA_DIRTY;
}
-void
-audio_release(int dev, struct fileinfo *file)
+void audio_release(int dev, struct file *file)
{
- int mode;
+ int mode = translate_mode(file);
dev = dev >> 4;
- mode = file->mode & O_ACCMODE;
audio_devs[dev]->dmap_out->closing = 1;
audio_devs[dev]->dmap_in->closing = 1;
@@ -167,8 +166,8 @@ audio_release(int dev, struct fileinfo *file)
}
#if defined(NO_INLINE_ASM) || !defined(i386)
-static void
-translate_bytes(const unsigned char *table, unsigned char *buff, int n)
+
+static void translate_bytes(const unsigned char *table, unsigned char *buff, int n)
{
unsigned long i;
@@ -184,25 +183,24 @@ 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"
+ {
+ __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 fileinfo *file, const char *buf, int count)
+int audio_write(int dev, struct file *file, const char *buf, int count)
{
- int c, p, l, buf_size;
- int err;
- char *dma_buf;
+ int c, p, l, buf_size;
+ int err;
+ char *dma_buf;
dev = dev >> 4;
@@ -213,66 +211,66 @@ audio_write(int dev, struct fileinfo *file, const char *buf, int count)
return -EPERM;
if (audio_devs[dev]->flags & DMA_DUPLEX)
- audio_mode[dev] |= AM_WRITE;
+ audio_devs[dev]->audio_mode |= AM_WRITE;
else
- audio_mode[dev] = AM_WRITE;
+ audio_devs[dev]->audio_mode = AM_WRITE;
if (!count) /* Flush output */
- {
+ {
sync_output(dev);
return 0;
- }
+ }
+
while (c)
- {
- if ((err = DMAbuf_getwrbuffer(dev, &dma_buf, &buf_size, dev_nblock[dev])) < 0)
- {
+ {
+ if ((err = DMAbuf_getwrbuffer(dev, &dma_buf, &buf_size, audio_devs[dev]->dev_nblock)) < 0)
+ {
/* Handle nonblocking mode */
- if (dev_nblock[dev] && err == -EAGAIN)
- return p; /* No more space. Return # of accepted bytes */
- return err;
- }
- l = c;
-
- if (l > buf_size)
- l = buf_size;
-
- if (!audio_devs[dev]->d->copy_user)
- {
- if ((dma_buf + l) >
+ if (audio_devs[dev]->dev_nblock && err == -EAGAIN)
+ return p; /* No more space. Return # of accepted bytes */
+ return err;
+ }
+ l = c;
+
+ if (l > buf_size)
+ l = buf_size;
+
+ if (!audio_devs[dev]->d->copy_user)
+ {
+ if ((dma_buf + l) >
(audio_devs[dev]->dmap_out->raw_buf + audio_devs[dev]->dmap_out->buffsize))
- {
- printk("audio: Buffer error 3 (%lx,%d), (%lx, %d)\n", (long) dma_buf, l, (long) audio_devs[dev]->dmap_out->raw_buf, (int) audio_devs[dev]->dmap_out->buffsize);
- return -EDOM;
- }
- if (dma_buf < audio_devs[dev]->dmap_out->raw_buf)
- {
- printk("audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf, (long) audio_devs[dev]->dmap_out->raw_buf);
- return -EDOM;
- }
- copy_from_user(dma_buf, &(buf)[p], l);
- } else
- audio_devs[dev]->d->copy_user(dev,
- dma_buf, 0, buf, p, l);
-
- if (local_conversion[dev] & CNV_MU_LAW)
- {
- /*
- * This just allows interrupts while the conversion is running
- */
- sti();
- translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l);
- }
- c -= l;
- p += l;
- DMAbuf_move_wrpointer(dev, l);
-
- }
+ {
+ printk(KERN_ERR "audio: Buffer error 3 (%lx,%d), (%lx, %d)\n", (long) dma_buf, l, (long) audio_devs[dev]->dmap_out->raw_buf, (int) audio_devs[dev]->dmap_out->buffsize);
+ return -EDOM;
+ }
+ if (dma_buf < audio_devs[dev]->dmap_out->raw_buf)
+ {
+ printk(KERN_ERR "audio: Buffer error 13 (%lx<%lx)\n", (long) dma_buf, (long) audio_devs[dev]->dmap_out->raw_buf);
+ return -EDOM;
+ }
+ if(copy_from_user(dma_buf, &(buf)[p], l))
+ return -EFAULT;
+ }
+ else audio_devs[dev]->d->copy_user(dev, dma_buf, 0, buf, p, l);
+
+ if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
+ {
+ /*
+ * This just allows interrupts while the conversion is running
+ */
+ sti();
+ translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l);
+ }
+ c -= l;
+ p += l;
+ DMAbuf_move_wrpointer(dev, l);
+
+ }
return count;
}
-int
-audio_read(int dev, struct fileinfo *file, char *buf, int count)
+int audio_read(int dev, struct file *file, char *buf, int count)
{
int c, p, l;
char *dmabuf;
@@ -285,252 +283,235 @@ audio_read(int dev, struct fileinfo *file, char *buf, int count)
if (!(audio_devs[dev]->open_mode & OPEN_READ))
return -EPERM;
- if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
- {
- sync_output(dev);
- }
+ if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ sync_output(dev);
+
if (audio_devs[dev]->flags & DMA_DUPLEX)
- audio_mode[dev] |= AM_READ;
+ audio_devs[dev]->audio_mode |= AM_READ;
else
- audio_mode[dev] = AM_READ;
+ audio_devs[dev]->audio_mode = AM_READ;
- while (c)
- {
- if ((buf_no = DMAbuf_getrdbuffer(dev, &dmabuf, &l,
- dev_nblock[dev])) < 0)
- {
- /* Nonblocking mode handling. Return current # of bytes */
+ while(c)
+ {
+ if ((buf_no = DMAbuf_getrdbuffer(dev, &dmabuf, &l,
+ audio_devs[dev]->dev_nblock)) < 0)
+ {
+ /*
+ * Nonblocking mode handling. Return current # of bytes
+ */
- if (dev_nblock[dev] && buf_no == -EAGAIN)
- return p;
+ if (audio_devs[dev]->dev_nblock && buf_no == -EAGAIN)
+ return p;
- if (p > 0) /* Avoid throwing away data */
+ if (p > 0) /* Avoid throwing away data */
return p; /* Return it instead */
- return buf_no;
- }
- if (l > c)
- l = c;
+ return buf_no;
+ }
+ if (l > c)
+ l = c;
- /*
- * Insert any local processing here.
- */
+ /*
+ * Insert any local processing here.
+ */
- if (local_conversion[dev] & CNV_MU_LAW)
- {
- /*
- * This just allows interrupts while the conversion is running
- */
- sti();
+ if (audio_devs[dev]->local_conversion & CNV_MU_LAW)
+ {
+ /*
+ * This just allows interrupts while the conversion is running
+ */
+ sti();
- translate_bytes(dsp_ulaw, (unsigned char *) dmabuf, l);
- }
- {
- char *fixit = dmabuf;
+ translate_bytes(dsp_ulaw, (unsigned char *) dmabuf, l);
+ }
+
+ {
+ char *fixit = dmabuf;
- copy_to_user(&(buf)[p], fixit, l);
- };
+ if(copy_to_user(&(buf)[p], fixit, l))
+ return -EFAULT;
+ };
- DMAbuf_rmchars(dev, buf_no, l);
+ DMAbuf_rmchars(dev, buf_no, l);
- p += l;
- c -= l;
- }
+ p += l;
+ c -= l;
+ }
return count - c;
}
-int
-audio_ioctl(int dev, struct fileinfo *file_must_not_be_used,
- unsigned int cmd, caddr_t arg)
+int audio_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
{
- int val;
-
- /* printk( "audio_ioctl(%x, %x)\n", (int)cmd, (int)arg); */
+ int val, count;
+ unsigned long flags;
+ struct dma_buffparms *dmap;
dev = dev >> 4;
- if (((cmd >> 8) & 0xff) == 'C')
- {
- if (audio_devs[dev]->coproc) /* Coprocessor ioctl */
- return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0);
- else
- printk("/dev/dsp%d: No coprocessor for this device\n", dev);
-
- return -ENXIO;
- } else
- switch (cmd)
- {
- case SNDCTL_DSP_SYNC:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return 0;
-
- if (audio_devs[dev]->dmap_out->fragment_size == 0)
- return 0;
- sync_output(dev);
- DMAbuf_sync(dev);
- DMAbuf_reset(dev);
- return 0;
- break;
-
- case SNDCTL_DSP_POST:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return 0;
- if (audio_devs[dev]->dmap_out->fragment_size == 0)
- return 0;
- audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
- sync_output(dev);
- dma_ioctl(dev, SNDCTL_DSP_POST, (caddr_t) 0);
- return 0;
- break;
-
- case SNDCTL_DSP_RESET:
- audio_mode[dev] = AM_NONE;
- DMAbuf_reset(dev);
- return 0;
- break;
-
- case SNDCTL_DSP_GETFMTS:
- return (*(int *) arg = audio_devs[dev]->format_mask);
- break;
-
- case SNDCTL_DSP_SETFMT:
- val = *(int *) arg;
- return (*(int *) arg = set_format(dev, val));
-
- case SNDCTL_DSP_GETISPACE:
- if (!(audio_devs[dev]->open_mode & OPEN_READ))
- return 0;
- if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
- return -EBUSY;
-
- {
- audio_buf_info info;
-
- int err = dma_ioctl(dev, cmd, (caddr_t) & info);
-
- if (err < 0)
- return err;
-
- memcpy((&((char *) arg)[0]), (char *) &info, sizeof(info));
- return 0;
- }
-
- case SNDCTL_DSP_GETOSPACE:
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EPERM;
- if ((audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
- return -EBUSY;
-
- {
- audio_buf_info info;
-
- int err = dma_ioctl(dev, cmd, (caddr_t) & info);
-
- if (err < 0)
- return err;
-
- memcpy((&((char *) arg)[0]), (char *) &info, sizeof(info));
- return 0;
- }
-
- case SNDCTL_DSP_NONBLOCK:
- dev_nblock[dev] = 1;
- return 0;
- break;
-
- case SNDCTL_DSP_GETCAPS:
- {
- int info = 1; /* Revision level of this ioctl() */
-
- if (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode == OPEN_READWRITE)
- info |= DSP_CAP_DUPLEX;
-
- if (audio_devs[dev]->coproc)
- info |= DSP_CAP_COPROC;
-
- if (audio_devs[dev]->d->local_qlen) /* Device has hidden buffers */
- info |= DSP_CAP_BATCH;
-
- if (audio_devs[dev]->d->trigger) /* Supports SETTRIGGER */
- info |= DSP_CAP_TRIGGER;
-
- info |= DSP_CAP_MMAP;
-
- memcpy((&((char *) arg)[0]), (char *) &info, sizeof(info));
- return 0;
- }
- break;
-
- case SOUND_PCM_WRITE_RATE:
- val = *(int *) arg;
- return (*(int *) arg = audio_devs[dev]->d->set_speed(dev, val));
-
- case SOUND_PCM_READ_RATE:
- return (*(int *) arg = audio_devs[dev]->d->set_speed(dev, 0));
-
- case SNDCTL_DSP_STEREO:
- {
- int n;
-
- n = *(int *) arg;
- if (n > 1)
- {
- printk("sound: SNDCTL_DSP_STEREO called with invalid argument %d\n", n);
- return -EINVAL;
- }
- if (n < 0)
- return -EINVAL;
-
- return (*(int *) arg = audio_devs[dev]->d->set_channels(dev, n + 1) - 1);
- }
-
- case SOUND_PCM_WRITE_CHANNELS:
- val = *(int *) arg;
- return (*(int *) arg = audio_devs[dev]->d->set_channels(dev, val));
-
- case SOUND_PCM_READ_CHANNELS:
- return (*(int *) arg = audio_devs[dev]->d->set_channels(dev, 0));
-
- case SOUND_PCM_READ_BITS:
- return (*(int *) arg = audio_devs[dev]->d->set_bits(dev, 0));
-
- case SNDCTL_DSP_SETDUPLEX:
- if (audio_devs[dev]->open_mode != OPEN_READWRITE)
- return -EPERM;
- if (audio_devs[dev]->flags & DMA_DUPLEX)
- return 0;
- else
- return -EIO;
- break;
-
- case SNDCTL_DSP_PROFILE:
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- audio_devs[dev]->dmap_out->applic_profile = *(int *) arg;
- if (audio_devs[dev]->open_mode & OPEN_READ)
- audio_devs[dev]->dmap_in->applic_profile = *(int *) arg;
- return 0;
- break;
-
- default:
- return dma_ioctl(dev, cmd, arg);
- }
+ if (_IOC_TYPE(cmd) == 'C') {
+ if (audio_devs[dev]->coproc) /* Coprocessor ioctl */
+ return audio_devs[dev]->coproc->ioctl(audio_devs[dev]->coproc->devc, cmd, arg, 0);
+ /* else
+ printk(KERN_DEBUG"/dev/dsp%d: No coprocessor for this device\n", dev); */
+ return -ENXIO;
+ }
+ else switch (cmd)
+ {
+ case SNDCTL_DSP_SYNC:
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return 0;
+ if (audio_devs[dev]->dmap_out->fragment_size == 0)
+ return 0;
+ sync_output(dev);
+ DMAbuf_sync(dev);
+ DMAbuf_reset(dev);
+ return 0;
+
+ case SNDCTL_DSP_POST:
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return 0;
+ if (audio_devs[dev]->dmap_out->fragment_size == 0)
+ return 0;
+ audio_devs[dev]->dmap_out->flags |= DMA_POST | DMA_DIRTY;
+ sync_output(dev);
+ dma_ioctl(dev, SNDCTL_DSP_POST, (caddr_t) 0);
+ return 0;
+
+ case SNDCTL_DSP_RESET:
+ audio_devs[dev]->audio_mode = AM_NONE;
+ DMAbuf_reset(dev);
+ return 0;
+
+ case SNDCTL_DSP_GETFMTS:
+ val = audio_devs[dev]->format_mask;
+ break;
+
+ case SNDCTL_DSP_SETFMT:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = set_format(dev, val);
+ break;
+
+ case SNDCTL_DSP_GETISPACE:
+ if (!(audio_devs[dev]->open_mode & OPEN_READ))
+ return 0;
+ if ((audio_devs[dev]->audio_mode & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ return -EBUSY;
+ return dma_ioctl(dev, cmd, arg);
+
+ case SNDCTL_DSP_GETOSPACE:
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return -EPERM;
+ if ((audio_devs[dev]->audio_mode & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ return -EBUSY;
+ return dma_ioctl(dev, cmd, arg);
+
+ case SNDCTL_DSP_NONBLOCK:
+ audio_devs[dev]->dev_nblock = 1;
+ return 0;
+
+ case SNDCTL_DSP_GETCAPS:
+ val = 1 | DSP_CAP_MMAP; /* Revision level of this ioctl() */
+ if (audio_devs[dev]->flags & DMA_DUPLEX &&
+ audio_devs[dev]->open_mode == OPEN_READWRITE)
+ val |= DSP_CAP_DUPLEX;
+ if (audio_devs[dev]->coproc)
+ val |= DSP_CAP_COPROC;
+ if (audio_devs[dev]->d->local_qlen) /* Device has hidden buffers */
+ val |= DSP_CAP_BATCH;
+ if (audio_devs[dev]->d->trigger) /* Supports SETTRIGGER */
+ val |= DSP_CAP_TRIGGER;
+ break;
+
+ case SOUND_PCM_WRITE_RATE:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = audio_devs[dev]->d->set_speed(dev, val);
+ break;
+
+ case SOUND_PCM_READ_RATE:
+ val = audio_devs[dev]->d->set_speed(dev, 0);
+ break;
+
+ case SNDCTL_DSP_STEREO:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val > 1 || val < 0)
+ return -EINVAL;
+ val = audio_devs[dev]->d->set_channels(dev, val + 1) - 1;
+ break;
+
+ case SOUND_PCM_WRITE_CHANNELS:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = audio_devs[dev]->d->set_channels(dev, val);
+ break;
+
+ case SOUND_PCM_READ_CHANNELS:
+ val = audio_devs[dev]->d->set_channels(dev, 0);
+ break;
+
+ case SOUND_PCM_READ_BITS:
+ val = audio_devs[dev]->d->set_bits(dev, 0);
+ break;
+
+ case SNDCTL_DSP_SETDUPLEX:
+ if (audio_devs[dev]->open_mode != OPEN_READWRITE)
+ return -EPERM;
+ return (audio_devs[dev]->flags & DMA_DUPLEX) ? 0 : -EIO;
+
+ case SNDCTL_DSP_PROFILE:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (audio_devs[dev]->open_mode & OPEN_WRITE)
+ audio_devs[dev]->dmap_out->applic_profile = val;
+ if (audio_devs[dev]->open_mode & OPEN_READ)
+ audio_devs[dev]->dmap_in->applic_profile = val;
+ return 0;
+
+ case SNDCTL_DSP_GETODELAY:
+ dmap = audio_devs[dev]->dmap_out;
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return -EINVAL;
+ if (!(dmap->flags & DMA_ALLOC_DONE))
+ {
+ val=0;
+ break;
+ }
+
+ save_flags (flags);
+ cli();
+ /* Compute number of bytes that have been played */
+ count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
+ if (count < dmap->fragment_size && dmap->qhead != 0)
+ count += dmap->bytes_in_use; /* Pointer wrap not handled yet */
+ count += dmap->byte_counter;
+
+ /* Substract current count from the number of bytes written by app */
+ count = dmap->user_counter - count;
+ if (count < 0)
+ count = 0;
+ restore_flags (flags);
+ val = count;
+ break;
+
+ default:
+ return dma_ioctl(dev, cmd, arg);
+ }
+ return put_user(val, (int *)arg);
}
-void
-audio_init_devices(void)
+void audio_init_devices(void)
{
/*
* NOTE! This routine could be called several times during boot.
*/
}
-
#endif
-void
-reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
+void reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
{
/*
* This routine breaks the physical device buffers to logical ones.
@@ -538,8 +519,8 @@ reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
struct audio_operations *dsp_dev = audio_devs[dev];
- unsigned i, n;
- unsigned sr, nc, sz, bsz;
+ unsigned i, n;
+ unsigned sr, nc, sz, bsz;
sr = dsp_dev->d->set_speed(dev, 0);
nc = dsp_dev->d->set_channels(dev, 0);
@@ -551,12 +532,13 @@ reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
dmap->neutral_byte = NEUTRAL16;
if (sr < 1 || nc < 1 || sz < 1)
- {
- printk("Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);
- sr = DSP_DEFAULT_SPEED;
- nc = 1;
- sz = 8;
- }
+ {
+/* printk(KERN_DEBUG "Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n", dev, sr, nc, sz);*/
+ sr = DSP_DEFAULT_SPEED;
+ nc = 1;
+ sz = 8;
+ }
+
sz = sr * nc * sz;
sz /= 8; /* #bits -> #bytes */
@@ -567,52 +549,54 @@ reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
dmap->needs_reorg = 0;
if (dmap->fragment_size == 0)
- { /* Compute the fragment size using the default algorithm */
-
- /*
- * Compute a buffer size for time not exceeding 1 second.
- * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
- * of sound (using the current speed, sample size and #channels).
- */
-
- bsz = dmap->buffsize;
- while (bsz > sz)
- bsz /= 2;
-
- if (bsz == dmap->buffsize)
- bsz /= 2; /* Needs at least 2 buffers */
-
-/*
- * Split the computed fragment to smaller parts. After 3.5a9
- * the default subdivision is 4 which should give better
- * results when recording.
- */
-
- if (dmap->subdivision == 0) /* Not already set */
- {
- dmap->subdivision = 4; /* Init to the default value */
-
- if ((bsz / dmap->subdivision) > 4096)
- dmap->subdivision *= 2;
- if ((bsz / dmap->subdivision) < 4096)
- dmap->subdivision = 1;
- }
- bsz /= dmap->subdivision;
-
- if (bsz < 16)
- bsz = 16; /* Just a sanity check */
-
- dmap->fragment_size = bsz;
- } else
- {
- /*
- * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
- * the buffer size computation has already been done.
- */
- if (dmap->fragment_size > (dmap->buffsize / 2))
- dmap->fragment_size = (dmap->buffsize / 2);
- bsz = dmap->fragment_size;
- }
+ {
+ /* Compute the fragment size using the default algorithm */
+
+ /*
+ * Compute a buffer size for time not exceeding 1 second.
+ * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
+ * of sound (using the current speed, sample size and #channels).
+ */
+
+ bsz = dmap->buffsize;
+ while (bsz > sz)
+ bsz /= 2;
+
+ if (bsz == dmap->buffsize)
+ bsz /= 2; /* Needs at least 2 buffers */
+
+ /*
+ * Split the computed fragment to smaller parts. After 3.5a9
+ * the default subdivision is 4 which should give better
+ * results when recording.
+ */
+
+ if (dmap->subdivision == 0) /* Not already set */
+ {
+ dmap->subdivision = 4; /* Init to the default value */
+
+ if ((bsz / dmap->subdivision) > 4096)
+ dmap->subdivision *= 2;
+ if ((bsz / dmap->subdivision) < 4096)
+ dmap->subdivision = 1;
+ }
+ bsz /= dmap->subdivision;
+
+ if (bsz < 16)
+ bsz = 16; /* Just a sanity check */
+
+ dmap->fragment_size = bsz;
+ }
+ else
+ {
+ /*
+ * The process has specified the buffer size with SNDCTL_DSP_SETFRAGMENT or
+ * the buffer size computation has already been done.
+ */
+ if (dmap->fragment_size > (dmap->buffsize / 2))
+ dmap->fragment_size = (dmap->buffsize / 2);
+ bsz = dmap->fragment_size;
+ }
if (audio_devs[dev]->min_fragment)
if (bsz < (1 << audio_devs[dev]->min_fragment))
@@ -632,42 +616,39 @@ reorganize_buffers(int dev, struct dma_buffparms *dmap, int recording)
n = dmap->max_fragments;
if (n < 2)
- {
- n = 2;
- bsz /= 2;
- }
+ {
+ n = 2;
+ bsz /= 2;
+ }
dmap->nbufs = n;
dmap->bytes_in_use = n * bsz;
dmap->fragment_size = bsz;
dmap->max_byte_counter = (dmap->data_rate * 60 * 60) +
- dmap->bytes_in_use; /* Approximately one hour */
+ dmap->bytes_in_use; /* Approximately one hour */
if (dmap->raw_buf)
- {
- memset(dmap->raw_buf,
- dmap->neutral_byte,
- dmap->bytes_in_use);
- }
+ {
+ memset(dmap->raw_buf, dmap->neutral_byte, dmap->bytes_in_use);
+ }
+
for (i = 0; i < dmap->nbufs; i++)
- {
- dmap->counts[i] = 0;
- }
+ {
+ dmap->counts[i] = 0;
+ }
dmap->flags |= DMA_ALLOC_DONE | DMA_EMPTY;
}
-static int
-dma_subdivide(int dev, struct dma_buffparms *dmap, caddr_t arg, int fact)
+static int dma_subdivide(int dev, struct dma_buffparms *dmap, int fact)
{
- if (fact == 0)
- {
- fact = dmap->subdivision;
- if (fact == 0)
- fact = 1;
- return (*(int *) arg = fact);
- }
- if (dmap->subdivision != 0 ||
- dmap->fragment_size) /* Too late to change */
+ if (fact == 0)
+ {
+ fact = dmap->subdivision;
+ if (fact == 0)
+ fact = 1;
+ return fact;
+ }
+ if (dmap->subdivision != 0 || dmap->fragment_size) /* Too late to change */
return -EINVAL;
if (fact > MAX_REALTIME_FACTOR)
@@ -677,13 +658,12 @@ dma_subdivide(int dev, struct dma_buffparms *dmap, caddr_t arg, int fact)
return -EINVAL;
dmap->subdivision = fact;
- return (*(int *) arg = fact);
+ return fact;
}
-static int
-dma_set_fragment(int dev, struct dma_buffparms *dmap, caddr_t arg, int fact)
+static int dma_set_fragment(int dev, struct dma_buffparms *dmap, int fact)
{
- int bytes, count;
+ int bytes, count;
if (fact == 0)
return -EIO;
@@ -730,315 +710,241 @@ dma_set_fragment(int dev, struct dma_buffparms *dmap, caddr_t arg, int fact)
dmap->fragment_size /= 2; /* Needs at least 2 buffers */
dmap->subdivision = 1; /* Disable SNDCTL_DSP_SUBDIVIDE */
- if (arg)
- return (*(int *) arg = bytes | ((count - 1) << 16));
- else
- return 0;
+ return bytes | ((count - 1) << 16);
}
-int
-dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
+int dma_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
-
struct dma_buffparms *dmap_out = audio_devs[dev]->dmap_out;
struct dma_buffparms *dmap_in = audio_devs[dev]->dmap_in;
-
- switch (cmd)
- {
-
- case SNDCTL_DSP_SUBDIVIDE:
- {
- int fact;
- int ret = 0;
-
- fact = *(int *) arg;
-
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- ret = dma_subdivide(dev, dmap_out, arg, fact);
- if (ret < 0)
- return ret;
-
- if (audio_devs[dev]->open_mode != OPEN_WRITE ||
- (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode & OPEN_READ))
- ret = dma_subdivide(dev, dmap_in, arg, fact);
-
- return ret;
- }
- break;
-
- case SNDCTL_DSP_GETISPACE:
- case SNDCTL_DSP_GETOSPACE:
- {
- struct dma_buffparms *dmap = dmap_out;
-
- audio_buf_info *info = (audio_buf_info *) arg;
-
- if (cmd == SNDCTL_DSP_GETISPACE &&
- !(audio_devs[dev]->open_mode & OPEN_READ))
- return -EINVAL;
-
- if (cmd == SNDCTL_DSP_GETOSPACE &&
- !(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
-
- if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
- dmap = dmap_in;
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- return -EINVAL;
-
- if (!(dmap->flags & DMA_ALLOC_DONE))
- reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
-
- info->fragstotal = dmap->nbufs;
-
- if (cmd == SNDCTL_DSP_GETISPACE)
- info->fragments = dmap->qlen;
- else
- {
- if (!DMAbuf_space_in_queue(dev))
- info->fragments = 0;
- else
- {
- info->fragments = DMAbuf_space_in_queue(dev);
- if (audio_devs[dev]->d->local_qlen)
- {
- int tmp = audio_devs[dev]->d->local_qlen(dev);
-
- if (tmp && info->fragments)
- tmp--; /*
- * This buffer has been counted twice
- */
- info->fragments -= tmp;
- }
- }
- }
-
- if (info->fragments < 0)
- info->fragments = 0;
- else if (info->fragments > dmap->nbufs)
- info->fragments = dmap->nbufs;
-
- info->fragsize = dmap->fragment_size;
- info->bytes = info->fragments * dmap->fragment_size;
-
- if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
- info->bytes -= dmap->counts[dmap->qhead];
- else
- {
- info->fragments = info->bytes / dmap->fragment_size;
- info->bytes -= dmap->user_counter % dmap->fragment_size;
- }
- }
- return 0;
-
- case SNDCTL_DSP_SETTRIGGER:
- {
- unsigned long flags;
-
- int bits;
- int changed;
-
- bits = *(int *) arg;
- bits &= audio_devs[dev]->open_mode;
-
- if (audio_devs[dev]->d->trigger == NULL)
- return -EINVAL;
-
- if (!(audio_devs[dev]->flags & DMA_DUPLEX))
- if ((bits & PCM_ENABLE_INPUT) && (bits & PCM_ENABLE_OUTPUT))
- {
- printk("Sound: Device doesn't have full duplex capability\n");
- return -EINVAL;
- }
- save_flags(flags);
- cli();
- changed = audio_devs[dev]->enable_bits ^ bits;
-
- if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go)
- {
- int err;
-
- reorganize_buffers(dev, dmap_in, 1);
-
- if ((err = audio_devs[dev]->d->prepare_for_input(dev,
- dmap_in->fragment_size, dmap_in->nbufs)) < 0)
- return -err;
-
- dmap_in->dma_mode = DMODE_INPUT;
- audio_devs[dev]->enable_bits = bits;
- DMAbuf_activate_recording(dev, dmap_in);
- }
- if ((changed & bits) & PCM_ENABLE_OUTPUT &&
- (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
- audio_devs[dev]->go)
- {
-
- if (!(dmap_out->flags & DMA_ALLOC_DONE))
- {
- reorganize_buffers(dev, dmap_out, 0);
- }
- dmap_out->dma_mode = DMODE_OUTPUT;
- ;
- audio_devs[dev]->enable_bits = bits;
- dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
- DMAbuf_launch_output(dev, dmap_out);
- ;
- }
- audio_devs[dev]->enable_bits = bits;
- if (changed && audio_devs[dev]->d->trigger)
- {
- audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
- }
- restore_flags(flags);
- }
- case SNDCTL_DSP_GETTRIGGER:
- return (*(int *) arg = audio_devs[dev]->enable_bits);
- break;
-
- case SNDCTL_DSP_SETSYNCRO:
-
- if (!audio_devs[dev]->d->trigger)
- return -EINVAL;
-
- audio_devs[dev]->d->trigger(dev, 0);
- audio_devs[dev]->go = 0;
- return 0;
- break;
-
- case SNDCTL_DSP_GETIPTR:
- {
- count_info info;
- unsigned long flags;
- struct dma_buffparms *dmap = dmap_in;
-
- if (!(audio_devs[dev]->open_mode & OPEN_READ))
- return -EINVAL;
-
- save_flags(flags);
- cli();
- info.bytes = dmap->byte_counter;
- info.ptr = DMAbuf_get_buffer_pointer(dev, dmap, DMODE_INPUT) & ~3;
- if (info.ptr < dmap->fragment_size && dmap->qtail != 0)
- info.bytes += dmap->bytes_in_use; /* Pointer wrap not handled yet */
-
- info.blocks = dmap->qlen;
- info.bytes += info.ptr;
- memcpy((&((char *) arg)[0]), (char *) &info, sizeof(info));
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- dmap->qlen = 0; /* Reset interrupt counter */
- restore_flags(flags);
- return 0;
- }
- break;
-
- case SNDCTL_DSP_GETOPTR:
- {
- count_info info;
- unsigned long flags;
- struct dma_buffparms *dmap = dmap_out;
-
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
-
- save_flags(flags);
- cli();
- info.bytes = dmap->byte_counter;
- info.ptr = DMAbuf_get_buffer_pointer(dev, dmap, DMODE_OUTPUT) & ~3;
- if (info.ptr < dmap->fragment_size && dmap->qhead != 0)
- info.bytes += dmap->bytes_in_use; /* Pointer wrap not handled yet */
- info.blocks = dmap->qlen;
- info.bytes += info.ptr;
- memcpy((&((char *) arg)[0]), (char *) &info, sizeof(info));
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- dmap->qlen = 0; /* Reset interrupt counter */
-
- restore_flags(flags);
- return 0;
- }
- break;
-
- case SNDCTL_DSP_GETODELAY:
- {
- int count;
- unsigned long flags;
- struct dma_buffparms *dmap = dmap_out;
-
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return -EINVAL;
- if (!(dmap->flags & DMA_ALLOC_DONE))
- return (*(int *) arg = 0);
-
- save_flags (flags);
- cli ();
- /* Compute number of bytes that have been played */
- count = DMAbuf_get_buffer_pointer (dev, dmap, DMODE_OUTPUT);
- if (count < dmap->fragment_size && dmap->qhead != 0)
- count += dmap->bytes_in_use; /* Pointer wrap not handled yet */
- count += dmap->byte_counter;
-
- /* Substract current count from the number of bytes written by app */
- count = dmap->user_counter - count;
- if (count < 0)
- count = 0;
- restore_flags (flags);
-
- return (*(int *) arg = count);
- }
- break;
-
- case SNDCTL_DSP_POST:
- ;
- if (audio_devs[dev]->dmap_out->qlen > 0)
- if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
- DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
- ;
- return 0;
- break;
-
- case SNDCTL_DSP_GETBLKSIZE:
- {
- int fragment_size;
- struct dma_buffparms *dmap = dmap_out;
-
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- reorganize_buffers(dev, dmap_out,
- (audio_devs[dev]->open_mode == OPEN_READ));
- if (audio_devs[dev]->open_mode != OPEN_WRITE ||
- (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode & OPEN_READ))
- reorganize_buffers(dev, dmap_in,
- (audio_devs[dev]->open_mode == OPEN_READ));
- if (audio_devs[dev]->open_mode == OPEN_READ)
- dmap = dmap_in;
- fragment_size = dmap->fragment_size;
- return (*(int *) arg = fragment_size);
- }
- break;
-
- case SNDCTL_DSP_SETFRAGMENT:
- {
- int fact;
- int ret;
-
- fact = *(int *) arg;
- ret = dma_set_fragment(dev, dmap_out, arg, fact);
- if (ret < 0)
- return ret;
-
- if (audio_devs[dev]->flags & DMA_DUPLEX &&
- audio_devs[dev]->open_mode & OPEN_READ)
- ret = dma_set_fragment(dev, dmap_in, arg, fact);
-
- return ret;
- }
- break;
-
- default:
- return audio_devs[dev]->d->ioctl(dev, cmd, arg);
- }
-
+ struct dma_buffparms *dmap;
+ audio_buf_info info;
+ count_info cinfo;
+ int fact, ret, changed, bits, count, err;
+ unsigned long flags;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_SUBDIVIDE:
+ ret = 0;
+ if (get_user(fact, (int *)arg))
+ return -EFAULT;
+ if (audio_devs[dev]->open_mode & OPEN_WRITE)
+ ret = dma_subdivide(dev, dmap_out, fact);
+ if (ret < 0)
+ return ret;
+ if (audio_devs[dev]->open_mode != OPEN_WRITE ||
+ (audio_devs[dev]->flags & DMA_DUPLEX &&
+ audio_devs[dev]->open_mode & OPEN_READ))
+ ret = dma_subdivide(dev, dmap_in, fact);
+ if (ret < 0)
+ return ret;
+ break;
+
+ case SNDCTL_DSP_GETISPACE:
+ case SNDCTL_DSP_GETOSPACE:
+ dmap = dmap_out;
+ if (cmd == SNDCTL_DSP_GETISPACE && !(audio_devs[dev]->open_mode & OPEN_READ))
+ return -EINVAL;
+ if (cmd == SNDCTL_DSP_GETOSPACE && !(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return -EINVAL;
+ if (cmd == SNDCTL_DSP_GETISPACE && audio_devs[dev]->flags & DMA_DUPLEX)
+ dmap = dmap_in;
+ if (dmap->mapping_flags & DMA_MAP_MAPPED)
+ return -EINVAL;
+ if (!(dmap->flags & DMA_ALLOC_DONE))
+ reorganize_buffers(dev, dmap, (cmd == SNDCTL_DSP_GETISPACE));
+ info.fragstotal = dmap->nbufs;
+ if (cmd == SNDCTL_DSP_GETISPACE)
+ info.fragments = dmap->qlen;
+ else
+ {
+ if (!DMAbuf_space_in_queue(dev))
+ info.fragments = 0;
+ else
+ {
+ info.fragments = DMAbuf_space_in_queue(dev);
+ if (audio_devs[dev]->d->local_qlen)
+ {
+ int tmp = audio_devs[dev]->d->local_qlen(dev);
+ if (tmp && info.fragments)
+ tmp--; /*
+ * This buffer has been counted twice
+ */
+ info.fragments -= tmp;
+ }
+ }
+ }
+ if (info.fragments < 0)
+ info.fragments = 0;
+ else if (info.fragments > dmap->nbufs)
+ info.fragments = dmap->nbufs;
+
+ info.fragsize = dmap->fragment_size;
+ info.bytes = info.fragments * dmap->fragment_size;
+
+ if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
+ info.bytes -= dmap->counts[dmap->qhead];
+ else
+ {
+ info.fragments = info.bytes / dmap->fragment_size;
+ info.bytes -= dmap->user_counter % dmap->fragment_size;
+ }
+ if (copy_to_user(arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+
+ case SNDCTL_DSP_SETTRIGGER:
+ if (get_user(bits, (int *)arg))
+ return -EFAULT;
+ bits &= audio_devs[dev]->open_mode;
+ if (audio_devs[dev]->d->trigger == NULL)
+ return -EINVAL;
+ if (!(audio_devs[dev]->flags & DMA_DUPLEX) && (bits & PCM_ENABLE_INPUT) &&
+ (bits & PCM_ENABLE_OUTPUT))
+ return -EINVAL;
+ save_flags(flags);
+ cli();
+ changed = audio_devs[dev]->enable_bits ^ bits;
+ if ((changed & bits) & PCM_ENABLE_INPUT && audio_devs[dev]->go)
+ {
+ reorganize_buffers(dev, dmap_in, 1);
+ if ((err = audio_devs[dev]->d->prepare_for_input(dev,
+ dmap_in->fragment_size, dmap_in->nbufs)) < 0)
+ return -err;
+ dmap_in->dma_mode = DMODE_INPUT;
+ audio_devs[dev]->enable_bits = bits;
+ DMAbuf_activate_recording(dev, dmap_in);
+ }
+ if ((changed & bits) & PCM_ENABLE_OUTPUT &&
+ (dmap_out->mapping_flags & DMA_MAP_MAPPED || dmap_out->qlen > 0) &&
+ audio_devs[dev]->go)
+ {
+ if (!(dmap_out->flags & DMA_ALLOC_DONE))
+ reorganize_buffers(dev, dmap_out, 0);
+ dmap_out->dma_mode = DMODE_OUTPUT;
+ audio_devs[dev]->enable_bits = bits;
+ dmap_out->counts[dmap_out->qhead] = dmap_out->fragment_size;
+ DMAbuf_launch_output(dev, dmap_out);
+ }
+ audio_devs[dev]->enable_bits = bits;
+ if (changed && audio_devs[dev]->d->trigger)
+ audio_devs[dev]->d->trigger(dev, bits * audio_devs[dev]->go);
+ restore_flags(flags);
+ /* Falls through... */
+
+ case SNDCTL_DSP_GETTRIGGER:
+ ret = audio_devs[dev]->enable_bits;
+ break;
+
+ case SNDCTL_DSP_SETSYNCRO:
+ if (!audio_devs[dev]->d->trigger)
+ return -EINVAL;
+ audio_devs[dev]->d->trigger(dev, 0);
+ audio_devs[dev]->go = 0;
+ return 0;
+
+ case SNDCTL_DSP_GETIPTR:
+ if (!(audio_devs[dev]->open_mode & OPEN_READ))
+ return -EINVAL;
+ save_flags(flags);
+ cli();
+ cinfo.bytes = dmap_in->byte_counter;
+ cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_in, DMODE_INPUT) & ~3;
+ if (cinfo.ptr < dmap_in->fragment_size && dmap_in->qtail != 0)
+ cinfo.bytes += dmap_in->bytes_in_use; /* Pointer wrap not handled yet */
+ cinfo.blocks = dmap_in->qlen;
+ cinfo.bytes += cinfo.ptr;
+ if (dmap_in->mapping_flags & DMA_MAP_MAPPED)
+ dmap_in->qlen = 0; /* Reset interrupt counter */
+ restore_flags(flags);
+ if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
+ return -EFAULT;
+ return 0;
+
+ case SNDCTL_DSP_GETOPTR:
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return -EINVAL;
+
+ save_flags(flags);
+ cli();
+ cinfo.bytes = dmap_out->byte_counter;
+ cinfo.ptr = DMAbuf_get_buffer_pointer(dev, dmap_out, DMODE_OUTPUT) & ~3;
+ if (cinfo.ptr < dmap_out->fragment_size && dmap_out->qhead != 0)
+ cinfo.bytes += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
+ cinfo.blocks = dmap_out->qlen;
+ cinfo.bytes += cinfo.ptr;
+ if (dmap_out->mapping_flags & DMA_MAP_MAPPED)
+ dmap_out->qlen = 0; /* Reset interrupt counter */
+ restore_flags(flags);
+ if (copy_to_user(arg, &cinfo, sizeof(cinfo)))
+ return -EFAULT;
+ return 0;
+
+ case SNDCTL_DSP_GETODELAY:
+ if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
+ return -EINVAL;
+ if (!(dmap_out->flags & DMA_ALLOC_DONE))
+ {
+ ret=0;
+ break;
+ }
+ save_flags(flags);
+ cli();
+ /* Compute number of bytes that have been played */
+ count = DMAbuf_get_buffer_pointer (dev, dmap_out, DMODE_OUTPUT);
+ if (count < dmap_out->fragment_size && dmap_out->qhead != 0)
+ count += dmap_out->bytes_in_use; /* Pointer wrap not handled yet */
+ count += dmap_out->byte_counter;
+ /* Substract current count from the number of bytes written by app */
+ count = dmap_out->user_counter - count;
+ if (count < 0)
+ count = 0;
+ restore_flags (flags);
+ ret = count;
+ break;
+
+ case SNDCTL_DSP_POST:
+ if (audio_devs[dev]->dmap_out->qlen > 0)
+ if (!(audio_devs[dev]->dmap_out->flags & DMA_ACTIVE))
+ DMAbuf_launch_output(dev, audio_devs[dev]->dmap_out);
+ return 0;
+
+ case SNDCTL_DSP_GETBLKSIZE:
+ dmap = dmap_out;
+ if (audio_devs[dev]->open_mode & OPEN_WRITE)
+ reorganize_buffers(dev, dmap_out, (audio_devs[dev]->open_mode == OPEN_READ));
+ if (audio_devs[dev]->open_mode == OPEN_READ ||
+ (audio_devs[dev]->flags & DMA_DUPLEX &&
+ audio_devs[dev]->open_mode & OPEN_READ))
+ reorganize_buffers(dev, dmap_in, (audio_devs[dev]->open_mode == OPEN_READ));
+ if (audio_devs[dev]->open_mode == OPEN_READ)
+ dmap = dmap_in;
+ ret = dmap->fragment_size;
+ break;
+
+ case SNDCTL_DSP_SETFRAGMENT:
+ ret = 0;
+ if (get_user(fact, (int *)arg))
+ return -EFAULT;
+ if (audio_devs[dev]->open_mode & OPEN_WRITE)
+ ret = dma_set_fragment(dev, dmap_out, fact);
+ if (ret < 0)
+ return ret;
+ if (audio_devs[dev]->open_mode == OPEN_READ ||
+ (audio_devs[dev]->flags & DMA_DUPLEX &&
+ audio_devs[dev]->open_mode & OPEN_READ))
+ ret = dma_set_fragment(dev, dmap_in, fact);
+ if (ret < 0)
+ return ret;
+ if (!arg) /* don't know what this is good for, but preserve old semantics */
+ return 0;
+ break;
+
+ default:
+ if (!audio_devs[dev]->d->ioctl)
+ return -EINVAL;
+ return audio_devs[dev]->d->ioctl(dev, cmd, arg);
+ }
+ return put_user(ret, (int *)arg);
}
diff --git a/drivers/sound/bin2hex.c b/drivers/sound/bin2hex.c
new file mode 100644
index 000000000..351dd24e0
--- /dev/null
+++ b/drivers/sound/bin2hex.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+int main( int argc, const char * argv [] )
+{
+ const char * varname = argv[1];
+ int i = 0;
+ int c;
+
+ printf( "/* automatically generated by bin2hex */\n" );
+ printf( "static unsigned char %s [] =\n{\n", varname );
+
+ while ( ( c = getchar( ) ) != EOF )
+ {
+ if ( i != 0 && i % 10 == 0 )
+ printf( "\n" );
+ printf( "0x%02lx,", c & 0xFFl );
+ i++;
+ }
+
+ printf( "};\n#define %sLen %d\n", varname, i );
+ return 0;
+}
diff --git a/drivers/sound/configure.c b/drivers/sound/configure.c
deleted file mode 100644
index e00ca26f5..000000000
--- a/drivers/sound/configure.c
+++ /dev/null
@@ -1,1669 +0,0 @@
-/*
- * PnP soundcard support is not included in this version.
- *
- * AESDP16 driver is now included in the lowlevel directory.
- */
-#define DISABLED_OPTIONS (B(OPT_SPNP)|B(OPT_AEDSP16)|B(OPT_UNUSED1)|B(OPT_UNUSED2)|B(OPT_UNUSED3)|B(OPT_UNUSED4)|B(OPT_UNUSED5)|B(OPT_UART6850))
-/*
- * sound/configure.c - Configuration program for the Linux Sound 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.
- */
-
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <string.h>
-
-#define B(x) (1 << (x))
-
-/*
- * Option numbers
- */
-
-#define OPT_PAS 0
-#define OPT_SB 1
-#define OPT_ADLIB 2
-#define OPT_LAST_MUTUAL 2
-
-#define OPT_GUS 3
-#define OPT_MPU401 4
-#define OPT_UART6850 5
-#define OPT_PSS 6
-#define OPT_GUS16 7
-#define OPT_GUSMAX 8
-#define OPT_MSS 9
-#define OPT_SSCAPE 10
-#define OPT_TRIX 11
-#define OPT_MAD16 12
-#define OPT_CS4232 13
-#define OPT_MAUI 14
-#define OPT_SPNP 15
-#define OPT_OPL3SA1 16
-#define OPT_SOFTOSS 17
-
-#define OPT_HIGHLEVEL 18 /* This must be same than the next one */
-#define OPT_UNUSED1 18
-#define OPT_UNUSED2 19
-#define OPT_AEDSP16 20
-#define OPT_UNUSED3 21
-#define OPT_UNUSED4 22
-#define OPT_UNUSED5 23
-#define OPT_YM3812_AUTO 24
-#define OPT_YM3812 25
-#define OPT_LAST 25 /* Last defined OPT number */
-
-#define DUMMY_OPTS (B(OPT_YM3812_AUTO))
-
-#define ANY_DEVS (B(OPT_SB)|B(OPT_PAS)|B(OPT_GUS)| \
- B(OPT_MPU401)|B(OPT_PSS)|B(OPT_GUS16)|B(OPT_GUSMAX)| \
- B(OPT_MSS)|B(OPT_SSCAPE)|B(OPT_UART6850)|B(OPT_TRIX)| \
- B(OPT_MAD16)|B(OPT_CS4232)|B(OPT_MAUI)|B(OPT_ADLIB)| \
- B(OPT_SPNP)|B(OPT_OPL3SA1)|B(OPT_SOFTOSS))
-#define MPU_DEVS (B(OPT_PSS)|\
- B(OPT_CS4232)|B(OPT_SPNP)|B(OPT_MAUI)|B(OPT_SSCAPE))
-#define UART401_DEVS (SBDSP_DEVS|B(OPT_TRIX)|B(OPT_MAD16)|B(OPT_SPNP)|\
- B(OPT_OPL3SA1))
-#define NON_AUDIO_CARDS (B(OPT_ADLIB)|B(OPT_MPU401)|B(OPT_UART6850)|B(OPT_MAUI))
-#define AUDIO_CARDS (ANY_DEVS & ~NON_AUDIO_CARDS)
-#define MIDI_CARDS (ANY_DEVS & ~(B(OPT_ADLIB)|B(OPT_MSS)))
-#define AD1848_DEVS (B(OPT_GUS16)|B(OPT_MSS)|B(OPT_PSS)|B(OPT_GUSMAX)|\
- B(OPT_SSCAPE)|B(OPT_TRIX)|B(OPT_MAD16)|B(OPT_CS4232)|\
- B(OPT_SPNP)|B(OPT_OPL3SA1))
-#define SBDSP_DEVS (B(OPT_SB)|B(OPT_SPNP)|B(OPT_MAD16)|B(OPT_TRIX))
-#define SEQUENCER_DEVS 0x7fffffff
-/*
- * Options that have been disabled for some reason (incompletely implemented
- * and/or tested). Don't remove from this list before looking at file
- * experimental.txt for further info.
- */
-
-typedef struct
- {
- unsigned long conditions;
- unsigned long exclusive_options;
- char macro[20];
- int verify;
- int alias;
- int default_answ;
- }
-
-hw_entry;
-
-
-/*
- * The rule table for the driver options. The first field defines a set of
- * options which must be selected before this entry can be selected. The
- * second field is a set of options which are not allowed with this one. If
- * the fourth field is zero, the option is selected without asking
- * confirmation from the user.
- *
- * With this version of the rule table it is possible to select just one type of
- * hardware.
- *
- * NOTE! Keep the following table and the questions array in sync with the
- * option numbering!
- */
-
-hw_entry hw_table[] =
-{
-/*
- * 0
- */
- {0, 0, "PAS", 1, 0, 0},
- {0, 0, "SB", 1, 0, 0},
- {0, B(OPT_PAS) | B(OPT_SB), "ADLIB", 1, 0, 0},
-
- {0, 0, "GUS", 1, 0, 0},
- {0, 0, "MPU401", 1, 0, 0},
- {0, 0, "UART6850", 1, 0, 0},
- {0, 0, "PSS", 1, 0, 0},
- {B(OPT_GUS), 0, "GUS16", 1, 0, 0},
- {B(OPT_GUS), B(OPT_GUS16), "GUSMAX", 1, 0, 0},
- {0, 0, "MSS", 1, 0, 0},
- {0, 0, "SSCAPE", 1, 0, 0},
- {0, 0, "TRIX", 1, 0, 0},
- {0, 0, "MAD16", 1, 0, 0},
- {0, 0, "CS4232", 1, 0, 0},
- {0, 0, "MAUI", 1, 0, 0},
- {0, 0, "SPNP", 1, 0, 0},
- {0, 0, "OPL3SA1", 1, 0, 0},
- {0, 0, "SOFTOSS", 1, 0, 0},
-
- {B(OPT_SB), B(OPT_PAS), "UNUSED1", 1, 0, 1},
- {B(OPT_SB) | B(OPT_UNUSED1), B(OPT_PAS), "UNUSED2", 1, 0, 1},
- {B(OPT_UNUSED1) | B(OPT_MSS) | B(OPT_MPU401), 0, "AEDSP16", 1, 0, 0},
- {AUDIO_CARDS, 0, "UNUSED3", 1, 0, 1},
- {B(OPT_MPU401) | B(OPT_MAUI), 0, "UNUSED4", 0, 0, 0},
- {MIDI_CARDS, 0, "UNUSED5", 1, 0, 1},
- {B(OPT_ADLIB), 0, "YM3812_AUTO", 0, OPT_YM3812, 0},
- {B(OPT_PSS) | B(OPT_SB) | B(OPT_PAS) | B(OPT_ADLIB) | B(OPT_MSS) | B(OPT_PSS), B(OPT_YM3812_AUTO), "YM3812", 1, 0, 1}
-};
-
-char *questions[] =
-{
- "ProAudioSpectrum 16 support",
- "100%% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support",
- "Generic OPL2/OPL3 FM synthesizer support",
- "Gravis Ultrasound support",
- "MPU-401 support (NOT for SB16)",
- "6850 UART Midi support",
- "PSS (ECHO-ADI2111) support",
- "16 bit sampling option of GUS (_NOT_ GUS MAX)",
- "GUS MAX support",
- "Microsoft Sound System support",
- "Ensoniq SoundScape support",
- "MediaTrix AudioTrix Pro support",
- "Support for OPTi MAD16 and/or Mozart based cards",
- "Support for Crystal CS4232 based (PnP) cards",
- "Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers",
- "Support for PnP sound cards (_EXPERIMENTAL_)",
- "Yamaha OPL3-SA1 audio controller",
- "SoftOSS software wave table engine",
-
- "*** Unused option 1 ***",
- "*** Unused option 2 ***",
- "Audio Excel DSP 16 initialization support",
- "*** Unused option 3 ***",
- "*** Unused option 4 ***",
- "*** Unused option 5 ***",
- "This should not be asked",
- "FM synthesizer (YM3812/OPL-3) support",
- "Is the sky really falling"
-};
-
-/* help text for each option */
-char *help[] =
-{
- "Enable this option only if you have a Pro Audio Spectrum 16,\n"
- "Pro Audio Studio 16, or Logitech SoundMan 16. Don't enable this if\n"
- "you have some other card made by MediaVision or Logitech as\n"
- "they are not PAS16 compatible.\n",
-
- "Enable this if you have an original Sound Blaster card made by\n"
- "Creative Labs or a 100%% hardware compatible clone. For an\n"
- "unknown card you may want to try this if it claims to be\n"
- "Sound Blaster compatible.\n",
-
- "Enable this option if your sound card has a Yamaha OPL2 or OPL3\n"
- "FM synthesizer chip.\n",
-
- "Enable this option for any type of Gravis Ultrasound card\n"
- "including the GUS or GUS MAX.\n",
-
-"The MPU401 interface is supported by almost all sound cards. However,\n"
- "some natively supported cards have their own driver for\n"
- "MPU401. Enabling the MPU401 option with these cards will cause a\n"
-"conflict. Also enabling MPU401 on a system that doesn't really have a\n"
- "MPU401 could cause some trouble. It's safe to enable this if you have a\n"
- "true MPU401 MIDI interface card.\n",
-
- "This option enables support for MIDI interfaces based on the 6850\n"
- "UART chip. This interface is rarely found on sound cards.\n",
-
-"Enable this option if you have an Orchid SW32, Cardinal DSP16 or other\n"
-"sound card based on the PSS chipset (AD1848 codec, ADSP-2115 DSP chip,\n"
- "and Echo ESC614 ASIC CHIP).\n",
-
-"Enable this if you have installed the 16-bit sampling daughtercard on\n"
- "your GUS card. Do not use if you have a GUS MAX as enabling this option\n"
- "disables GUS MAX support.\n",
-
- "Enable this option if you have a Gravis Ultrasound MAX sound\n"
- "card\n",
-
- "Enable this option if you have the original Windows Sound System\n"
- "card made by Microsoft or the Aztech SG 16 Pro or NX16 Pro.\n",
-
- "Enable this if you have a sound card based on the Ensoniq\n"
- "SoundScape chipset. Such cards are being manufactured by Ensoniq,\n"
- "Spea and Reveal (Reveal makes other cards as well).\n",
-
- "Enable this option if you have the AudioTrix Pro sound card\n"
- "manufactured by MediaTrix.\n",
-
- "Enable this if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi\n"
- "82C928 or 82C929) audio interface chip. These chips are currently\n"
- "quite common so it's possible that many no-name cards have one of\n"
- "them. In addition the MAD16 chip is used in some cards made by known\n"
-"manufacturers such as Turtle Beach (Tropez), Reveal (some models) and\n"
- "Diamond (latest ones).\n",
-
-"Enable this if you have a card based on the Crystal CS4232 chip set.\n",
-
- "Enable this option if you have a Turtle Beach Wave Front, Maui,\n"
- "or Tropez sound card.\n",
-
- "Use this option to enable experimental support for cards that\n"
- "use the Plug and Play protocol.\n",
-
- "Use this option with Yamaha OPL3-SA1 (YMF701) chip.\n",
-
-"SoftOSS is a virtual wave table engine by 4Front Technologies. It can\n"
- "be used together with any 16 bit stereo soundcard.\n"
-
- "Enable this option if your card is a Sound Blaster Pro or\n"
- "Sound Blaster 16. It also works with many Sound Blaster Pro clones.\n",
-
- "Enable this if you have a Sound Blaster 16, including the AWE32.\n",
-
- "Enable this if you have an Audio Excel DSP16 card. See the file\n"
- "Readme.aedsp16 for more information.\n",
-
- "This option enables the A/D and D/A converter (PCM) devices\n"
- "supported by almost all sound cards.\n",
-
- "This should not be asked",
-
- "This enables the dev/midixx devices and access to any MIDI ports\n"
- "using /dev/sequencer and /dev/music. This option also affects any\n"
- "MPU401 and/or General MIDI compatible devices.\n",
-
- "This should not be asked",
-
- "This enables the Yamaha FM synthesizer chip used on many sound\n"
- "cards.\n",
-
- "Is the sky really falling"
-};
-
-struct kludge
- {
- char *name;
- int mask;
- }
-extra_options[] =
-{
- {
- "MPU_EMU", MPU_DEVS
- }
- ,
- {
- "AD1848", AD1848_DEVS
- }
- ,
- {
- "SBDSP", SBDSP_DEVS
- }
- ,
- {
- "UART401", UART401_DEVS
- }
- ,
- {
- "GUSHW", B(OPT_GUS) | B(OPT_SPNP)
- }
- ,
- {
- "SSCAPEHW", B(OPT_SSCAPE) | B(OPT_SPNP)
- }
- ,
- {
- "SEQUENCER", SEQUENCER_DEVS
- }
- ,
- {
- "AUDIO", AUDIO_CARDS
- }
- ,
- {
- "MIDI", MIDI_CARDS
- }
- ,
- {
- NULL, 0
- }
-};
-
-char *oldconf = "/etc/soundconf";
-
-int old_config_used = 0;
-int def_size, sb_base = 0;
-
-unsigned long selected_options = 0;
-int sb_dma = 0;
-
-int dump_only = 0;
-
-void build_defines(void);
-
-#include "hex2hex.h"
-int bin2hex(char *path, char *target, char *varname);
-
-int
-can_select_option(int nr)
-{
-
- if (hw_table[nr].conditions)
- if (!(hw_table[nr].conditions & selected_options))
- return 0;
-
- if (hw_table[nr].exclusive_options)
- if (hw_table[nr].exclusive_options & selected_options)
- return 0;
-
- if (DISABLED_OPTIONS & B(nr))
- return 0;
-
- return 1;
-}
-
-int
-think_positively(char *prompt, int def_answ, char *help)
-{
- char answ[512];
- int len;
-
- response:
- fprintf(stderr, prompt);
- if (def_answ)
- fprintf(stderr, " [Y/n/?] ");
- else
- fprintf(stderr, " [N/y/?] ");
-
- if ((len = read(0, answ, sizeof(answ))) < 1)
- {
- fprintf(stderr, "\n\nERROR! Cannot read stdin\n");
-
- perror("stdin");
- printf("invalid_configuration__run_make_config_again\n");
- exit(-1);
- }
- if (len < 2) /*
- * There is an additional LF at the end
- */
- return def_answ;
-
- if (answ[0] == '?')
- { /* display help message */
- fprintf(stderr, "\n");
- fprintf(stderr, help);
- fprintf(stderr, "\n");
- goto response;
- }
- answ[len - 1] = 0;
-
- if (!strcmp(answ, "y") || !strcmp(answ, "Y"))
- return 1;
-
- return 0;
-}
-
-int
-ask_value(char *format, int default_answer)
-{
- char answ[512];
- int len, num;
-
- play_it_again_Sam:
-
- if ((len = read(0, answ, sizeof(answ))) < 1)
- {
- fprintf(stderr, "\n\nERROR! Cannot read stdin\n");
-
- perror("stdin");
- printf("invalid_configuration__run_make_config_again\n");
- exit(-1);
- }
- if (len < 2) /*
- * There is an additional LF at the end
- */
- return default_answer;
-
- answ[len - 1] = 0;
-
- if (sscanf(answ, format, &num) != 1)
- {
- fprintf(stderr, "Illegal format. Try again: ");
- goto play_it_again_Sam;
- }
- return num;
-}
-
-#define FMT_HEX 1
-#define FMT_INT 2
-
-void
-show_comment(int mask, char *txt)
-{
- int i;
-
- if (dump_only)
- {
-
- for (i = 0; i < OPT_LAST; i++)
- if (mask == B(i))
- {
- printf("\n\nif [ \"$CONFIG_%s\" = \"y\" ]; then\n",
- hw_table[i].macro);
- printf("comment '%s'\n", txt);
- printf("fi\n");
- }
- } else
- {
- if (!(mask & selected_options))
- return;
-
- fprintf(stderr, "%s\n", txt);
- }
-}
-
-void
-ask_int_choice(int mask, char *macro,
- char *question,
- int format,
- int defa,
- char *choices)
-{
- int num, i;
-
- if (dump_only)
- {
-
- for (i = 0; i < OPT_LAST; i++)
- if (mask == B(i))
- {
- unsigned int j;
-
- for (j = 0; j < strlen(choices); j++)
- if (choices[j] == '\'')
- choices[j] = '_';
-
- printf("\nif [ \"$CONFIG_%s\" = \"y\" ]; then\n",
- hw_table[i].macro);
- if (format == FMT_INT)
- printf("int '%s %s' %s %d\n", question, choices, macro, defa);
- else
- printf("hex '%s %s' %s %x\n", question, choices, macro, defa);
- printf("fi\n");
- }
- } else
- {
- if (!(mask & selected_options))
- return;
-
- fprintf(stderr, "\n%s\n", question);
- if (strcmp(choices, ""))
- fprintf(stderr, "Possible values are: %s\n", choices);
-
- if (format == FMT_INT)
- {
- if (defa == -1)
- fprintf(stderr, "\t(-1 disables this feature)\n");
- fprintf(stderr, "The default value is %d\n", defa);
- fprintf(stderr, "Enter the value: ");
- num = ask_value("%d", defa);
- if (num == -1)
- return;
- fprintf(stderr, "%s set to %d.\n", question, num);
- printf("#define %s %d\n", macro, num);
- } else
- {
- if (defa == 0)
- fprintf(stderr, "\t(0 disables this feature)\n");
- fprintf(stderr, "The default value is %x\n", defa);
- fprintf(stderr, "Enter the value: ");
- num = ask_value("%x", defa);
- if (num == 0)
- return;
- fprintf(stderr, "%s set to %x.\n", question, num);
- printf("#define %s 0x%x\n", macro, num);
- }
- }
-}
-
-void
-rebuild_file(char *line)
-{
- char *method, *next, *old, *var, *p;
-
- method = p = line;
-
- while (*p && *p != ' ')
- p++;
- *p++ = 0;
-
- old = p;
- while (*p && *p != ' ')
- p++;
- *p++ = 0;
-
- next = p;
- while (*p && *p != ' ')
- p++;
- *p++ = 0;
-
- var = p;
- while (*p && *p != ' ')
- p++;
- *p++ = 0;
-
- fprintf(stderr, "Rebuilding file `%s' (%s %s)\n", next, method, old);
-
- if (strcmp(method, "bin2hex") == 0)
- {
- if (!bin2hex(old, next, var))
- {
- fprintf(stderr, "Rebuild failed\n");
- exit(-1);
- }
- } else if (strcmp(method, "hex2hex") == 0)
- {
- if (!hex2hex(old, next, var))
- {
- fprintf(stderr, "Rebuild failed\n");
- exit(-1);
- }
- } else
- {
- fprintf(stderr, "Failed to build `%s' - unknown method %s\n",
- next, method);
- exit(-1);
- }
-}
-
-int
-use_old_config(char *filename)
-{
- char buf[1024];
- int i = 0;
-
- FILE *oldf;
-
- fprintf(stderr, "Copying old configuration from `%s'\n", filename);
-
- if ((oldf = fopen(filename, "r")) == NULL)
- {
- fprintf(stderr, "Couldn't open previous configuration file\n");
- perror(filename);
- return 0;
- }
- while (fgets(buf, 1024, oldf) != NULL)
- {
- char tmp[100];
-
- if (buf[0] != '#')
- {
- printf("%s", buf);
-
- strncpy(tmp, buf, 8);
- tmp[8] = 0;
-
- if (strcmp(tmp, "/*build ") == 0)
- rebuild_file(&buf[8]);
-
- continue;
- }
- strncpy(tmp, buf, 8);
- tmp[8] = 0;
-
- if (strcmp(tmp, "#define ") == 0)
- {
- char *id = &buf[8];
-
- i = 0;
- while (id[i] && id[i] != ' ' &&
- id[i] != '\t' && id[i] != '\n')
- i++;
-
- strncpy(tmp, id, i);
- tmp[i] = 0;
-
- if (strcmp(tmp, "SELECTED_SOUND_OPTIONS") == 0)
- continue;
-
- if (strcmp(tmp, "KERNEL_SOUNDCARD") == 0)
- continue;
-
- if (strcmp(tmp, "JAZZ_DMA16") == 0) /* Rename it (hack) */
- {
- printf("#define SB_DMA2 %s\n",
- &buf[18]);
- continue;
- }
- if (strcmp(tmp, "SB16_DMA") == 0) /* Rename it (hack) */
- {
- printf("#define SB_DMA2 %s\n",
- &buf[16]);
- continue;
- }
- tmp[8] = 0; /* Truncate the string */
- if (strcmp(tmp, "EXCLUDE_") == 0)
- continue; /* Skip excludes */
-
- strncpy(tmp, id, i);
- tmp[7] = 0; /* Truncate the string */
-
- if (strcmp(tmp, "CONFIG_") == 0)
- {
- strncpy(tmp, &id[7], i - 7);
- tmp[i - 7] = 0;
-
- for (i = 0; i <= OPT_LAST; i++)
- if (strcmp(hw_table[i].macro, tmp) == 0)
- {
- selected_options |= (1 << i);
- break;
- }
- continue;
- }
- printf("%s", buf);
- continue;
- }
- if (strcmp(tmp, "#undef ") == 0)
- {
- char *id = &buf[8];
-
- i = 0;
- while (id[i] && id[i] != ' ' &&
- id[i] != '\t' && id[i] != '\n')
- i++;
-
- strncpy(tmp, id, i);
- tmp[7] = 0; /* Truncate the string */
- if (strcmp(tmp, "CONFIG_") == 0)
- continue;
-
- strncpy(tmp, id, i);
-
- tmp[8] = 0; /* Truncate the string */
- if (strcmp(tmp, "EXCLUDE_") != 0)
- continue; /* Not a #undef EXCLUDE_ line */
- strncpy(tmp, &id[8], i - 8);
- tmp[i - 8] = 0;
-
- for (i = 0; i <= OPT_LAST; i++)
- if (strcmp(hw_table[i].macro, tmp) == 0)
- {
- selected_options |= (1 << i);
- break;
- }
- continue;
- }
- printf("%s", buf);
- }
- fclose(oldf);
-
- for (i = 0; i <= OPT_LAST; i++)
- if (!hw_table[i].alias)
- if (selected_options & B(i))
- printf("#define CONFIG_%s\n", hw_table[i].macro);
- else
- printf("#undef CONFIG_%s\n", hw_table[i].macro);
-
-
- printf("\n");
-
- i = 0;
-
- while (extra_options[i].name != NULL)
- {
- if (selected_options & extra_options[i].mask)
- printf("#define CONFIG_%s\n", extra_options[i].name);
- else
- printf("#undef CONFIG_%s\n", extra_options[i].name);
- i++;
- }
-
- printf("\n");
-
- printf("#define SELECTED_SOUND_OPTIONS\t0x%08x\n", selected_options);
- fprintf(stderr, "Old configuration copied.\n");
-
- build_defines();
- old_config_used = 1;
- return 1;
-}
-
-void
-build_defines(void)
-{
- FILE *optf;
- int i;
-
- if ((optf = fopen(".defines", "w")) == NULL)
- {
- perror(".defines");
- exit(-1);
- }
- for (i = 0; i <= OPT_LAST; i++)
- if (!hw_table[i].alias)
- if (selected_options & B(i))
- fprintf(optf, "CONFIG_%s=y\n", hw_table[i].macro);
-
-
- fprintf(optf, "\n");
-
- i = 0;
-
- while (extra_options[i].name != NULL)
- {
- if (selected_options & extra_options[i].mask)
- fprintf(optf, "CONFIG_%s=y\n", extra_options[i].name);
- i++;
- }
-
- fprintf(optf, "\n");
- fclose(optf);
-}
-
-void
-ask_parameters(void)
-{
- int num;
-
- build_defines();
- /*
- * IRQ and DMA settings
- */
-
- ask_int_choice(B(OPT_AEDSP16), "AEDSP16_BASE",
- "I/O base for Audio Excel DSP 16",
- FMT_HEX,
- 0x220,
- "220 or 240");
-
- ask_int_choice(B(OPT_SB), "SBC_BASE",
- "I/O base for SB",
- FMT_HEX,
- 0x220,
- "Check from manual of the card");
-
- ask_int_choice(B(OPT_SB), "SBC_IRQ",
- "Sound Blaster IRQ",
- FMT_INT,
- 7,
- "Check from manual of the card");
-
- ask_int_choice(B(OPT_SB), "SBC_DMA",
- "Sound Blaster DMA",
- FMT_INT,
- 1,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_SB), "SB_DMA2",
- "Sound Blaster 16 bit DMA (SB16, Jazz16, SMW)",
- FMT_INT,
- 5,
- "5, 6 or 7 (use 1 for 8 bit cards)");
-
- ask_int_choice(B(OPT_SB), "SB_MPU_BASE",
- "MPU401 I/O base of SB16, Jazz16 and ES1688",
- FMT_HEX,
- 0x330,
- "Check from manual of the card");
-
- show_comment(B(OPT_SB),
- "MPU401 IRQ is only required with Jazz16, SM Wave and ESS1688.");
- show_comment(B(OPT_SB),
- "Enter -1 to the following question if you have something else such as SB16/32.");
-
- ask_int_choice(B(OPT_SB), "SB_MPU_IRQ",
- "SB MPU401 IRQ (Jazz16, SM Wave and ES1688)",
- FMT_INT,
- -1,
- "Check from manual of the card");
-
- ask_int_choice(B(OPT_PAS), "PAS_IRQ",
- "PAS16 IRQ",
- FMT_INT,
- 10,
- "3, 4, 5, 7, 9, 10, 11, 12, 14 or 15");
-
- ask_int_choice(B(OPT_PAS), "PAS_DMA",
- "PAS16 DMA",
- FMT_INT,
- 3,
- "0, 1, 3, 5, 6 or 7");
-
- if (selected_options & B(OPT_PAS))
- {
- if (think_positively("Enable Joystick port on ProAudioSpectrum", 0,
- "Enable this option if you want to use the joystick port provided\n"
- "on the PAS sound card.\n"))
- printf("#define PAS_JOYSTICK_ENABLE\n");
-
- if (think_positively("Enable PAS16 bus clock option", 0,
- "The PAS16 can be noisy with some motherboards. There is a command\n"
- "line switch (:T?) in the DOS driver for PAS16 which solves this.\n"
- "Don't enable this feature unless you have problems and have to use\n"
- "this switch with DOS\n"))
- printf("#define BROKEN_BUS_CLOCK\n");
-
- if (think_positively("Disable SB mode of PAS16", 0,
- "You should disable SB emulation of PAS16 if you want to use\n"
- "Another SB compatible card in the same system\n"))
- printf("#define DISABLE_SB_EMULATION\n");
- }
- ask_int_choice(B(OPT_GUS), "GUS_BASE",
- "I/O base for GUS",
- FMT_HEX,
- 0x220,
- "210, 220, 230, 240, 250 or 260");
-
-
- ask_int_choice(B(OPT_GUS), "GUS_IRQ",
- "GUS IRQ",
- FMT_INT,
- 15,
- "3, 5, 7, 9, 11, 12 or 15");
-
- ask_int_choice(B(OPT_GUS), "GUS_DMA",
- "GUS DMA",
- FMT_INT,
- 6,
- "1, 3, 5, 6 or 7");
-
- ask_int_choice(B(OPT_GUS), "GUS_DMA2",
- "Second DMA channel for GUS",
- FMT_INT,
- -1,
- "1, 3, 5, 6 or 7");
-
- ask_int_choice(B(OPT_GUS16), "GUS16_BASE",
- "I/O base for the 16 bit daughtercard of GUS",
- FMT_HEX,
- 0x530,
- "530, 604, E80 or F40");
-
-
- ask_int_choice(B(OPT_GUS16), "GUS16_IRQ",
- "GUS 16 bit daughtercard IRQ",
- FMT_INT,
- 7,
- "3, 4, 5, 7, or 9");
-
- ask_int_choice(B(OPT_GUS16), "GUS16_DMA",
- "GUS DMA",
- FMT_INT,
- 3,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_MPU401), "MPU_BASE",
- "I/O base for MPU401",
- FMT_HEX,
- 0x330,
- "Check from manual of the card");
-
- ask_int_choice(B(OPT_MPU401), "MPU_IRQ",
- "MPU401 IRQ",
- FMT_INT,
- 9,
- "Check from manual of the card");
-
- if (dump_only)
- show_comment(B(OPT_MAUI),
- "ERROR! You have to use old sound configuration method with Maui.");
-
- ask_int_choice(B(OPT_MAUI), "MAUI_BASE",
- "I/O base for Maui",
- FMT_HEX,
- 0x330,
- "210, 230, 260, 290, 300, 320, 338 or 330");
-
- ask_int_choice(B(OPT_MAUI), "MAUI_IRQ",
- "Maui IRQ",
- FMT_INT,
- 9,
- "5, 9, 12 or 15");
-
- ask_int_choice(B(OPT_UART6850), "U6850_BASE",
- "I/O base for UART 6850 MIDI port",
- FMT_HEX,
- 0,
- "(Unknown)");
-
- ask_int_choice(B(OPT_UART6850), "U6850_IRQ",
- "UART6850 IRQ",
- FMT_INT,
- -1,
- "(Unknown)");
-
- if (dump_only)
- show_comment(B(OPT_PSS),
- "ERROR! You have to use old sound configuration method with PSS cards.");
-
- ask_int_choice(B(OPT_PSS), "PSS_BASE",
- "PSS I/O base",
- FMT_HEX,
- 0x220,
- "220 or 240");
-
- ask_int_choice(B(OPT_PSS), "PSS_MSS_BASE",
- "PSS audio I/O base",
- FMT_HEX,
- 0x530,
- "530, 604, E80 or F40");
-
- ask_int_choice(B(OPT_PSS), "PSS_MSS_IRQ",
- "PSS audio IRQ",
- FMT_INT,
- 11,
- "7, 9, 10 or 11");
-
- ask_int_choice(B(OPT_PSS), "PSS_MSS_DMA",
- "PSS audio DMA",
- FMT_INT,
- 3,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_PSS), "PSS_MPU_BASE",
- "PSS MIDI I/O base",
- FMT_HEX,
- 0x330,
- "");
-
- ask_int_choice(B(OPT_PSS), "PSS_MPU_IRQ",
- "PSS MIDI IRQ",
- FMT_INT,
- 9,
- "3, 4, 5, 7 or 9");
-
- ask_int_choice(B(OPT_MSS), "MSS_BASE",
- "MSS/WSS I/O base",
- FMT_HEX,
- 0x530,
- "530, 604, E80 or F40");
-
- ask_int_choice(B(OPT_MSS), "MSS_IRQ",
- "MSS/WSS IRQ",
- FMT_INT,
- 11,
- "7, 9, 10 or 11");
-
- ask_int_choice(B(OPT_MSS), "MSS_DMA",
- "MSS/WSS DMA",
- FMT_INT,
- 3,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_MSS), "MSS_DMA2",
- "MSS/WSS second DMA (if possible)",
- FMT_INT,
- -1,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_SSCAPE), "SSCAPE_BASE",
- "SoundScape MIDI I/O base",
- FMT_HEX,
- 0x330,
- "320, 330, 340 or 350");
-
- ask_int_choice(B(OPT_SSCAPE), "SSCAPE_IRQ",
- "SoundScape MIDI IRQ",
- FMT_INT,
- 9,
- "");
-
- ask_int_choice(B(OPT_SSCAPE), "SSCAPE_DMA",
- "SoundScape initialization DMA",
- FMT_INT,
- 3,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_SSCAPE), "SSCAPE_MSS_BASE",
- "SoundScape audio I/O base",
- FMT_HEX,
- 0x534,
- "534, 608, E84 or F44");
-
- ask_int_choice(B(OPT_SSCAPE), "SSCAPE_MSS_IRQ",
- "SoundScape audio IRQ",
- FMT_INT,
- 11,
- "7, 9, 10 or 11");
-
-
- if (selected_options & B(OPT_SSCAPE))
- {
- int reveal_spea;
-
- reveal_spea = think_positively(
- "Is your SoundScape card made/marketed by Reveal or Spea",
- 0,
- "Enable if you have a SoundScape card with the Reveal or\n"
- "Spea name on it.\n");
- if (reveal_spea)
- printf("#define REVEAL_SPEA\n");
-
- }
- if (dump_only)
- show_comment(B(OPT_TRIX),
- "ERROR! You have to use old sound configuration method with OPL3-SA1.");
-
- ask_int_choice(B(OPT_TRIX), "TRIX_BASE",
- "OPL3-SA1 audio I/O base",
- FMT_HEX,
- 0x530,
- "530, 604, E80 or F40");
-
- ask_int_choice(B(OPT_TRIX), "TRIX_IRQ",
- "OPL3-SA1 audio IRQ",
- FMT_INT,
- 11,
- "7, 9, 10 or 11");
-
- ask_int_choice(B(OPT_TRIX), "TRIX_DMA",
- "OPL3-SA1 audio DMA",
- FMT_INT,
- 0,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_TRIX), "TRIX_DMA2",
- "OPL3-SA1 second (duplex) DMA",
- FMT_INT,
- 3,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_TRIX), "TRIX_MPU_BASE",
- "OPL3-SA1 MIDI I/O base",
- FMT_HEX,
- 0x330,
- "330, 370, 3B0 or 3F0");
-
- ask_int_choice(B(OPT_TRIX), "TRIX_MPU_IRQ",
- "OPL3-SA1 MIDI IRQ",
- FMT_INT,
- 9,
- "3, 4, 5, 7 or 9");
-
- ask_int_choice(B(OPT_TRIX), "TRIX_SB_BASE",
- "OPL3-SA1 SB I/O base",
- FMT_HEX,
- 0x220,
- "220, 210, 230, 240, 250, 260 or 270");
-
- ask_int_choice(B(OPT_TRIX), "TRIX_SB_IRQ",
- "OPL3-SA1 SB IRQ",
- FMT_INT,
- 7,
- "3, 4, 5 or 7");
-
- ask_int_choice(B(OPT_TRIX), "TRIX_SB_DMA",
- "OPL3-SA1 SB DMA",
- FMT_INT,
- 1,
- "1 or 3");
-
-
- ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_BASE",
- "OPL3-SA1 audio I/O base",
- FMT_HEX,
- 0x530,
- "530, 604, E80 or F40");
-
- ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_IRQ",
- "OPL3-SA1 audio IRQ",
- FMT_INT,
- 11,
- "7, 9, 10 or 11");
-
- ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_DMA",
- "OPL3-SA1 audio DMA",
- FMT_INT,
- 0,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_DMA2",
- "OPL3-SA1 second (duplex) DMA",
- FMT_INT,
- 3,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_MPU_BASE",
- "OPL3-SA1 MIDI I/O base",
- FMT_HEX,
- 0x330,
- "330, 370, 3B0 or 3F0");
-
- ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_MPU_IRQ",
- "OPL3-SA1 MIDI IRQ",
- FMT_INT,
- 9,
- "3, 4, 5, 7 or 9");
-
- ask_int_choice(B(OPT_CS4232), "CS4232_BASE",
- "CS4232 audio I/O base",
- FMT_HEX,
- 0x534,
- "534, 608, E84 or F44");
-
- ask_int_choice(B(OPT_CS4232), "CS4232_IRQ",
- "CS4232 audio IRQ",
- FMT_INT,
- 11,
- "5, 7, 9, 11, 12 or 15");
-
- ask_int_choice(B(OPT_CS4232), "CS4232_DMA",
- "CS4232 audio DMA",
- FMT_INT,
- 0,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_CS4232), "CS4232_DMA2",
- "CS4232 second (duplex) DMA",
- FMT_INT,
- 3,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_CS4232), "CS4232_MPU_BASE",
- "CS4232 MIDI I/O base",
- FMT_HEX,
- 0x330,
- "330, 370, 3B0 or 3F0");
-
- ask_int_choice(B(OPT_CS4232), "CS4232_MPU_IRQ",
- "CS4232 MIDI IRQ",
- FMT_INT,
- 9,
- "5, 7, 9, 11, 12 or 15");
-
- ask_int_choice(B(OPT_MAD16), "MAD16_BASE",
- "MAD16 audio I/O base",
- FMT_HEX,
- 0x530,
- "530, 604, E80 or F40");
-
- ask_int_choice(B(OPT_MAD16), "MAD16_IRQ",
- "MAD16 audio IRQ",
- FMT_INT,
- 11,
- "7, 9, 10 or 11");
-
- ask_int_choice(B(OPT_MAD16), "MAD16_DMA",
- "MAD16 audio DMA",
- FMT_INT,
- 3,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_MAD16), "MAD16_DMA2",
- "MAD16 second (duplex) DMA",
- FMT_INT,
- 0,
- "0, 1 or 3");
-
- ask_int_choice(B(OPT_MAD16), "MAD16_MPU_BASE",
- "MAD16 MIDI I/O base",
- FMT_HEX,
- 0x330,
- "300, 310, 320 or 330 (0 disables)");
-
- ask_int_choice(B(OPT_MAD16), "MAD16_MPU_IRQ",
- "MAD16 MIDI IRQ",
- FMT_INT,
- 9,
- "5, 7, 9 or 10");
- ask_int_choice(B(OPT_SOFTOSS), "SOFTOSS_RATE",
- "Sampling rate for SoftOSS",
- FMT_INT,
- 22050,
- "8000 to 48000");
- ask_int_choice(B(OPT_SOFTOSS), "SOFTOSS_VOICES",
- "Max # of concurrent voices for SoftOSS",
- FMT_INT,
- 32,
- "4 to 32");
-}
-
-void
-dump_script(void)
-{
- int i;
-
- for (i = 0; i <= OPT_LAST; i++)
- if (!(DUMMY_OPTS & B(i)))
- if (!(DISABLED_OPTIONS & B(i)))
- {
- printf("bool '%s' CONFIG_%s\n", questions[i], hw_table[i].macro);
- }
-/*
- * Some "hardcoded" options
- */
-
- dump_only = 1;
- selected_options = 0;
- ask_parameters();
-
- printf("#\n$MAKE -C drivers/sound kernelconfig || exit 1\n");
-}
-
-void
-dump_fixed_local(void)
-{
- int i = 0;
-
- printf("/* Computer generated file. Please don't edit! */\n\n");
- printf("#define KERNEL_COMPATIBLE_CONFIG\n\n");
- printf("#define SELECTED_SOUND_OPTIONS\t0x%08x\n\n", selected_options);
-
- while (extra_options[i].name != NULL)
- {
- int n = 0, j;
-
- printf("#if ");
-
- for (j = 0; j < OPT_LAST; j++)
- if (!(DISABLED_OPTIONS & B(j)))
- if (extra_options[i].mask & B(j))
- {
- if (n)
- printf(" || ");
- if (!(n++ % 2))
- printf("\\\n ");
-
- printf("defined(CONFIG_%s)", hw_table[j].macro);
- }
- printf("\n");
- printf("#\tdefine CONFIG_%s\n", extra_options[i].name);
- printf("#endif\n\n");
- i++;
- }
-}
-
-void
-dump_fixed_defines(void)
-{
- int i = 0;
-
- printf("# Computer generated file. Please don't edit\n\n");
-
- while (extra_options[i].name != NULL)
- {
- int j;
-
- for (j = 0; j < OPT_LAST; j++)
- {
- if (!(DISABLED_OPTIONS & B(j)))
- {
- if (extra_options[i].mask & B(j))
- {
- printf("ifdef CONFIG_%s\n", hw_table[j].macro);
- printf ("ifneq ($(CONFIG_%s),Y)\n", extra_options[i].name);
- printf("CONFIG_%s=y\n", extra_options[i].name);
- printf("endif\n");
- printf("endif\n\n");
- }
- }
- }
- i++;
- }
-}
-
-int
-main(int argc, char *argv[])
-{
- int i, full_driver = 1;
- char old_config_file[200];
-
- if (getuid() != 0) /* Not root */
- {
- char *home;
-
- if ((home = getenv("HOME")) != NULL)
- {
- sprintf(old_config_file, "%s/.soundconf", home);
- oldconf = old_config_file;
- }
- }
- if (argc > 1)
- {
- if (strcmp(argv[1], "-o") == 0 &&
- use_old_config(oldconf))
- exit(0);
- else if (strcmp(argv[1], "script") == 0)
- {
- dump_script();
- exit(0);
- } else if (strcmp(argv[1], "fixedlocal") == 0)
- {
- dump_fixed_local();
- exit(0);
- } else if (strcmp(argv[1], "fixeddefines") == 0)
- {
- dump_fixed_defines();
- exit(0);
- }
- }
- fprintf(stderr, "\nConfiguring Sound Support\n\n");
-
- if (access(oldconf, R_OK) == 0)
- {
- char str[255];
-
- sprintf(str, "Old configuration exists in `%s'. Use it", oldconf);
- if (think_positively(str, 1,
- "Enable this option to load the previously saved configuration file\n"
- "for all of the sound driver parameters.\n"))
- if (use_old_config(oldconf))
- exit(0);
- }
- printf("/*\tGenerated by configure. Don't edit!!!!\t*/\n");
- printf("/*\tMaking changes to this file is not as simple as it may look.\t*/\n\n");
- printf("/*\tIf you change the CONFIG_ settings in local.h you\t*/\n");
- printf("/*\t_have_ to edit .defines too.\t*/\n\n");
-
- {
- /*
- * Partial driver
- */
-
- full_driver = 0;
-
- for (i = 0; i <= OPT_LAST; i++)
- if (can_select_option(i))
- {
- if (!(selected_options & B(i))) /*
- * Not selected yet
- */
- if (!hw_table[i].verify)
- {
- if (hw_table[i].alias)
- selected_options |= B(hw_table[i].alias);
- else
- selected_options |= B(i);
- } else
- {
- int def_answ = hw_table[i].default_answ;
-
- if (think_positively(questions[i], def_answ, help[i]))
- if (hw_table[i].alias)
- selected_options |= B(hw_table[i].alias);
- else
- selected_options |= B(i);
- }
- }
- }
-
- if (selected_options & B(OPT_SB))
- {
- if (think_positively(
- "Support for the SG NX Pro mixer", 0,
- "Enable this if you want to support the additional mixer functions\n"
- "provided on Sound Galaxy NX Pro sound cards.\n"))
- printf("#define __SGNXPRO__\n");
- }
- if (selected_options & B(OPT_SB))
- {
- if (think_positively("Support for the MV Jazz16 (ProSonic etc.)", 0,
- "Enable this if you have an MV Jazz16 or ProSonic sound card.\n"))
- {
- if (think_positively("Do you have SoundMan Wave", 0,
- "Enable this option of you have the Logitech SoundMan Wave sound card.\n"))
- {
- printf("#define SM_WAVE\n");
-
- midi0001_again:
- if (think_positively(
- "Do you have access to the MIDI0001.BIN file", 1,
- "The Logitech SoundMan Wave has a microcontroller which must be\n"
- "initialized before MIDI emulation works. This is possible only if the\n"
- "microcode file is compiled into the driver.\n"))
- {
- char path[512];
-
- fprintf(stderr,
- "Enter full name of the MIDI0001.BIN file (pwd is sound): ");
- scanf("%s", path);
- fprintf(stderr, "including microcode file %s\n", path);
-
- if (!bin2hex(path, "smw-midi0001.h", "smw_ucode"))
- {
- fprintf(stderr, "Couldn't open file %s\n",
- path);
- if (think_positively("Try again with correct path", 1,
- "The specified file could not be opened. Enter the correct path to the\n"
- "file.\n"))
- goto midi0001_again;
- } else
- {
- printf("#define SMW_MIDI0001_INCLUDED\n");
- printf("/*build bin2hex %s smw-midi0001.h smw_ucode */\n", path);
- }
- }
- }
- }
- }
- if (selected_options & B(OPT_SB))
- {
- if (think_positively("Do you have a Logitech SoundMan Games", 0,
- "The Logitech SoundMan Games supports 44 kHz in stereo while the\n"
- "standard SB Pro supports just 22 kHz stereo. You have the option of\n"
- "enabling SM Games mode. However, enable it only if you are sure that\n"
- "your card is an SM Games. Enabling this feature with a plain old SB\n"
- "Pro will cause troubles with stereo mode.\n\n"
- "DANGER! Read the above once again before answering 'y'\n"
- "Answer 'n' if you are unsure what to do!\n"))
- printf("#define SM_GAMES\n");
- }
- if (selected_options & B(OPT_AEDSP16))
- {
- int sel1 = 0;
-
- if (selected_options & B(OPT_SB))
- {
-
- if (think_positively(
- "Do you want support for the Audio Excel Sound Blaster Pro mode",
- 1,
- "Enable this option if you want the Audio Excel sound card to operate\n"
- "in Sound Blaster Pro mode.\n"))
- {
- printf("#define AEDSP16_SBPRO\n");
- sel1 = 1;
- }
- }
- if ((selected_options & B(OPT_MSS)) && (sel1 == 0))
- {
-
- if (think_positively(
- "Do you want support for the Audio Excel Microsoft Sound System mode",
- 1,
- "Enable this option if you want the Audio Excel sound card to operate\n"
- "in Microsoft Sound System mode.\n"))
- {
- printf("#define AEDSP16_MSS\n");
- sel1 = 1;
- }
- }
- if (sel1 == 0)
- {
- printf("invalid_configuration__run_make_config_again\n");
- fprintf(stderr, "ERROR!!!!!\nYou must select at least one mode when using Audio Excel!\n");
- exit(-1);
- }
- if (selected_options & B(OPT_MPU401))
- printf("#define AEDSP16_MPU401\n");
- }
- if (selected_options & B(OPT_PSS))
- {
- genld_again:
- if (think_positively("Do you wish to include an LD file", 1,
- "If you want to emulate the Sound Blaster card and you have a DSPxxx.LD\n"
- "file then you must include the LD in the kernel.\n"))
- {
- char path[512];
-
- fprintf(stderr,
- "Enter the path to your LD file (pwd is sound): ");
- scanf("%s", path);
- fprintf(stderr, "including LD file %s\n", path);
-
- if (!bin2hex(path, "synth-ld.h", "pss_synth"))
- {
- fprintf(stderr, "couldn't open `%s' as the LD file\n", path);
- if (think_positively("try again with correct path", 1,
- "The given LD file could not opened.\n"))
- goto genld_again;
- } else
- {
- printf("#define PSS_HAVE_LD\n");
- printf("/*build bin2hex %s synth-ld.h pss_synth */\n", path);
- }
- } else
- {
- FILE *sf = fopen("synth-ld.h", "w");
-
- fprintf(sf, "/* automatically generated by configure */\n");
- fprintf(sf, "unsigned char pss_synth[1];\n"
- "#define pss_synthLen 0\n");
- fclose(sf);
- }
- }
- if (selected_options & B(OPT_TRIX))
- {
- hex2hex_again:
-
- if (think_positively("Do you want to include TRXPRO.HEX in your kernel",
- 1,
- "The MediaTrix AudioTrix Pro has an on-board microcontroller which\n"
- "needs to be initialized by downloading the code from the file TRXPRO.HEX\n"
- "in the DOS driver directory. If you don't have the TRXPRO.HEX file handy\n"
- "you may skip this step. However, the SB and MPU-401 modes of AudioTrix\n"
- "Pro will not work without this file!\n"))
- {
- char path[512];
-
- fprintf(stderr,
- "Enter the path to your TRXPRO.HEX file (pwd is sound): ");
- scanf("%s", path);
- fprintf(stderr, "including HEX file `%s'\n", path);
-
- if (!hex2hex(path, "trix_boot.h", "trix_boot"))
- goto hex2hex_again;
- printf("/*build hex2hex %s trix_boot.h trix_boot */\n", path);
- printf("#define INCLUDE_TRIX_BOOT\n");
- }
- }
- if (selected_options & B(OPT_MSS))
- {
- if (think_positively("Support for builtin sound of Compaq Deskpro XL", 0,
- "Enable this if you have Compaq Deskpro XL.\n"))
- {
- printf("#define DESKPROXL\n");
- }
- }
- if (selected_options & B(OPT_MAUI))
- {
- oswf_again:
- if (think_positively(
- "Do you have access to the OSWF.MOT file", 1,
- "TB Maui and Tropez have a microcontroller which needs to be initialized\n"
- "prior use. OSWF.MOT is a file distributed with card's DOS/Windows drivers\n"
- "which is required during initialization\n"))
- {
- char path[512];
-
- fprintf(stderr,
- "Enter full name of the OSWF.MOT file (pwd is sound): ");
- scanf("%s", path);
- fprintf(stderr, "including microcode file %s\n", path);
-
- if (!bin2hex(path, "maui_boot.h", "maui_os"))
- {
- fprintf(stderr, "Couldn't open file %s\n",
- path);
- if (think_positively("Try again with correct path", 1,
- "The specified file could not be opened. Enter the correct path to the\n"
- "file.\n"))
- goto oswf_again;
- } else
- {
- printf("#define HAVE_MAUI_BOOT\n");
- printf("/*build bin2hex %s maui_boot.h maui_os */\n", path);
- }
- }
- }
- if (!(selected_options & ANY_DEVS))
- {
- printf("invalid_configuration__run_make_config_again\n");
- fprintf(stderr, "\n*** This combination is useless. Sound driver disabled!!! ***\n*** You need to enable support for at least one device ***\n\n");
- exit(0);
- }
- for (i = 0; i <= OPT_LAST; i++)
- if (!hw_table[i].alias)
- if (selected_options & B(i))
- printf("#define CONFIG_%s\n", hw_table[i].macro);
- else
- printf("#undef CONFIG_%s\n", hw_table[i].macro);
-
- printf("\n");
-
- i = 0;
-
- while (extra_options[i].name != NULL)
- {
- if (selected_options & extra_options[i].mask)
- printf("#define CONFIG_%s\n", extra_options[i].name);
- else
- printf("#undef CONFIG_%s\n", extra_options[i].name);
- i++;
- }
-
- printf("\n");
-
- ask_parameters();
-
- printf("#define SELECTED_SOUND_OPTIONS\t0x%08lx\n", selected_options);
- fprintf(stderr, "\nThe sound driver is now configured.\n");
-
- if (!old_config_used)
- {
- char str[255];
-
- sprintf(str, "Save copy of this configuration to `%s'", oldconf);
- if (think_positively(str, 1,
- "If you enable this option then the sound driver configuration is\n"
- "saved to a file. If you later need to recompile the kernel you have\n"
- "the option of using the saved configuration.\n"))
- {
- char cmd[200];
-
- sprintf(cmd, "cp local.h %s", oldconf);
-
- fclose(stdout);
- if (system(cmd) != 0)
- perror(cmd);
- }
- }
- exit(0);
-}
-
-int
-bin2hex(char *path, char *target, char *varname)
-{
- int fd;
- int count;
- char c;
- int i = 0;
-
- if ((fd = open(path, 0)) > 0)
- {
- FILE *sf = fopen(target, "w");
-
- fprintf(sf, "/* automatically generated by configure */\n");
- fprintf(sf, "static unsigned char %s[] = {\n", varname);
- while (1)
- {
- count = read(fd, &c, 1);
- if (count == 0)
- break;
- if (i != 0 && (i % 10) == 0)
- fprintf(sf, "\n");
- fprintf(sf, "0x%02lx,", c & 0xFFL);
- i++;
- }
- fprintf(sf, "};\n"
- "#define %sLen %d\n", varname, i);
- fclose(sf);
- close(fd);
- return 1;
- }
- return 0;
-}
diff --git a/drivers/sound/cs4232.c b/drivers/sound/cs4232.c
index eb2a5eb05..c8732dfe4 100644
--- a/drivers/sound/cs4232.c
+++ b/drivers/sound/cs4232.c
@@ -31,23 +31,22 @@
#define KEY_PORT 0x279 /* Same as LPT1 status port */
#define CSN_NUM 0x99 /* Just a random number */
-static void
-CS_OUT(unsigned char a)
+static void CS_OUT(unsigned char a)
{
- outb((a), KEY_PORT);
+ outb(a, KEY_PORT);
}
+
#define CS_OUT2(a, b) {CS_OUT(a);CS_OUT(b);}
#define CS_OUT3(a, b, c) {CS_OUT(a);CS_OUT(b);CS_OUT(c);}
-static int mpu_base = 0, mpu_irq = 0;
-static int mpu_detected = 0;
+static int mpu_base = 0, mpu_irq = 0;
+static int mpu_detected = 0;
-int
-probe_cs4232_mpu(struct address_info *hw_config)
+int probe_cs4232_mpu(struct address_info *hw_config)
{
-/*
- * Just write down the config values.
- */
+ /*
+ * Just write down the config values.
+ */
mpu_base = hw_config->io_base;
mpu_irq = hw_config->irq;
@@ -55,9 +54,9 @@ probe_cs4232_mpu(struct address_info *hw_config)
return 1;
}
-void
-attach_cs4232_mpu(struct address_info *hw_config)
+void attach_cs4232_mpu(struct address_info *hw_config)
{
+ /* Nothing needs doing */
}
static unsigned char crystal_key[] = /* A 32 byte magic key sequence */
@@ -68,190 +67,126 @@ static unsigned char crystal_key[] = /* A 32 byte magic key sequence */
0x09, 0x84, 0x42, 0xa1, 0xd0, 0x68, 0x34, 0x1a
};
-int
-probe_cs4232(struct address_info *hw_config)
+static void sleep(unsigned howlong)
{
- int i, n;
- int base = hw_config->io_base, irq = hw_config->irq;
- int dma1 = hw_config->dma, dma2 = hw_config->dma2;
+ current->state = TASK_INTERRUPTIBLE;
+ current->timeout = jiffies + howlong;
+ schedule();
+ current->timeout = 0;
+}
- static struct wait_queue *cs_sleeper = NULL;
- static volatile struct snd_wait cs_sleep_flag =
- {0};
+int probe_cs4232(struct address_info *hw_config)
+{
+ int i, n;
+ int base = hw_config->io_base, irq = hw_config->irq;
+ int dma1 = hw_config->dma, dma2 = hw_config->dma2;
-
-/*
- * Verify that the I/O port range is free.
- */
+ /*
+ * Verify that the I/O port range is free.
+ */
if (check_region(base, 4))
- {
- printk("cs4232.c: I/O port 0x%03x not free\n", base);
- return 0;
- }
+ {
+ printk(KERN_ERR "cs4232.c: I/O port 0x%03x not free\n", base);
+ return 0;
+ }
if (ad1848_detect(hw_config->io_base, NULL, hw_config->osp))
return 1; /* The card is already active */
-/*
- * This version of the driver doesn't use the PnP method when configuring
- * the card but a simplified method defined by Crystal. This means that
- * just one CS4232 compatible device can exist on the system. Also this
- * method conflicts with possible PnP support in the OS. For this reason
- * driver is just a temporary kludge.
- */
-
-/*
- * Repeat initialization few times since it doesn't always succeed in
- * first time.
- */
-
- for (n = 0; n < 4; n++)
- {
- cs_sleep_flag.opts = WK_NONE;
-/*
- * Wake up the card by sending a 32 byte Crystal key to the key port.
- */
- for (i = 0; i < 32; i++)
- CS_OUT(crystal_key[i]);
-
-
- {
- unsigned long tlimit;
-
- if (HZ / 10)
- current->timeout = tlimit = jiffies + (HZ / 10);
- else
- tlimit = (unsigned long) -1;
- cs_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&cs_sleeper);
- if (!(cs_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- cs_sleep_flag.opts |= WK_TIMEOUT;
- }
- cs_sleep_flag.opts &= ~WK_SLEEP;
- }; /* Delay */
+ /*
+ * This version of the driver doesn't use the PnP method when configuring
+ * the card but a simplified method defined by Crystal. This means that
+ * just one CS4232 compatible device can exist on the system. Also this
+ * method conflicts with possible PnP support in the OS. For this reason
+ * driver is just a temporary kludge.
+ */
-/*
- * Now set the CSN (Card Select Number).
- */
+ /*
+ * Repeat initialization few times since it doesn't always succeed in
+ * first time.
+ */
- CS_OUT2(0x06, CSN_NUM);
+ for (n = 0; n < 4; n++) {
+
+ /*
+ * Wake up the card by sending a 32 byte Crystal key to the key port.
+ */
+
+ for (i = 0; i < 32; i++)
+ CS_OUT(crystal_key[i]);
+ sleep(HZ / 10);
-/*
- * Then set some config bytes. First logical device 0
- */
+ /*
+ * Now set the CSN (Card Select Number).
+ */
- CS_OUT2(0x15, 0x00); /* Select logical device 0 (WSS/SB/FM) */
- CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff); /* WSS base */
+ CS_OUT2(0x06, CSN_NUM);
- if (check_region(0x388, 4)) /* Not free */
- CS_OUT3(0x48, 0x00, 0x00) /* FM base off */
- else
- CS_OUT3(0x48, 0x03, 0x88); /* FM base 0x388 */
+ /*
+ * Then set some config bytes. First logical device 0
+ */
- CS_OUT3(0x42, 0x00, 0x00); /* SB base off */
- CS_OUT2(0x22, irq); /* SB+WSS IRQ */
- CS_OUT2(0x2a, dma1); /* SB+WSS DMA */
+ CS_OUT2(0x15, 0x00); /* Select logical device 0 (WSS/SB/FM) */
+ CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff); /* WSS base */
- if (dma2 != -1)
- CS_OUT2(0x25, dma2) /* WSS DMA2 */
- else
- CS_OUT2(0x25, 4); /* No WSS DMA2 */
+ if (check_region(0x388, 4)) /* Not free */
+ CS_OUT3(0x48, 0x00, 0x00) /* FM base off */
+ else
+ CS_OUT3(0x48, 0x03, 0x88); /* FM base 0x388 */
- CS_OUT2(0x33, 0x01); /* Activate logical dev 0 */
+ CS_OUT3(0x42, 0x00, 0x00); /* SB base off */
+ CS_OUT2(0x22, irq); /* SB+WSS IRQ */
+ CS_OUT2(0x2a, dma1); /* SB+WSS DMA */
+ if (dma2 != -1)
+ CS_OUT2(0x25, dma2) /* WSS DMA2 */
+ else
+ CS_OUT2(0x25, 4); /* No WSS DMA2 */
- {
- unsigned long tlimit;
+ CS_OUT2(0x33, 0x01); /* Activate logical dev 0 */
- if (HZ / 10)
- current->timeout = tlimit = jiffies + (HZ / 10);
- else
- tlimit = (unsigned long) -1;
- cs_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&cs_sleeper);
- if (!(cs_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- cs_sleep_flag.opts |= WK_TIMEOUT;
- }
- cs_sleep_flag.opts &= ~WK_SLEEP;
- }; /* Delay */
+ sleep(HZ / 10);
-/*
- * Initialize logical device 3 (MPU)
- */
+ /*
+ * Initialize logical device 3 (MPU)
+ */
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
- if (mpu_base != 0 && mpu_irq != 0)
- {
- CS_OUT2(0x15, 0x03); /* Select logical device 3 (MPU) */
- CS_OUT3(0x47, (mpu_base >> 8) & 0xff, mpu_base & 0xff); /* MPU base */
- CS_OUT2(0x22, mpu_irq); /* MPU IRQ */
- CS_OUT2(0x33, 0x01); /* Activate logical dev 3 */
- }
+ if (mpu_base != 0 && mpu_irq != 0)
+ {
+ CS_OUT2(0x15, 0x03); /* Select logical device 3 (MPU) */
+ CS_OUT3(0x47, (mpu_base >> 8) & 0xff, mpu_base & 0xff); /* MPU base */
+ CS_OUT2(0x22, mpu_irq); /* MPU IRQ */
+ CS_OUT2(0x33, 0x01); /* Activate logical dev 3 */
+ }
#endif
-/*
- * Finally activate the chip
- */
- CS_OUT(0x79);
-
-
- {
- unsigned long tlimit;
-
- if (HZ / 5)
- current->timeout = tlimit = jiffies + (HZ / 5);
- else
- tlimit = (unsigned long) -1;
- cs_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&cs_sleeper);
- if (!(cs_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- cs_sleep_flag.opts |= WK_TIMEOUT;
- }
- cs_sleep_flag.opts &= ~WK_SLEEP;
- }; /* Delay */
-
-/*
- * Then try to detect the codec part of the chip
- */
-
- if (ad1848_detect(hw_config->io_base, NULL, hw_config->osp))
- return 1;
+ /*
+ * Finally activate the chip
+ */
+
+ CS_OUT(0x79);
+ sleep(HZ / 5);
- {
- unsigned long tlimit;
-
- if (HZ)
- current->timeout = tlimit = jiffies + (HZ);
- else
- tlimit = (unsigned long) -1;
- cs_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&cs_sleeper);
- if (!(cs_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- cs_sleep_flag.opts |= WK_TIMEOUT;
- }
- cs_sleep_flag.opts &= ~WK_SLEEP;
- }; /* Longer delay */
- }
+ /*
+ * Then try to detect the codec part of the chip
+ */
+ if (ad1848_detect(hw_config->io_base, NULL, hw_config->osp))
+ return 1;
+
+ sleep(HZ);
+ }
return 0;
}
-void
-attach_cs4232(struct address_info *hw_config)
+void attach_cs4232(struct address_info *hw_config)
{
- int base = hw_config->io_base, irq = hw_config->irq;
- int dma1 = hw_config->dma, dma2 = hw_config->dma2;
- int old_num_mixers = num_mixers;
+ int base = hw_config->io_base, irq = hw_config->irq;
+ int dma1 = hw_config->dma, dma2 = hw_config->dma2;
+ int old_num_mixers = num_mixers;
if (dma2 == -1)
dma2 = dma1;
@@ -264,45 +199,47 @@ attach_cs4232(struct address_info *hw_config)
hw_config->osp);
if (num_mixers > old_num_mixers)
- { /* Assume the mixer map is as suggested in the CS4232 databook */
- AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
- AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
- AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_SYNTH); /* FM synth */
- }
+ {
+ /* Assume the mixer map is as suggested in the CS4232 databook */
+ AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
+ AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
+ AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_SYNTH); /* FM synth */
+ }
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
if (mpu_base != 0 && mpu_irq != 0)
- {
- static struct address_info hw_config2 =
- {0}; /* Ensure it's initialized */
-
- hw_config2.io_base = mpu_base;
- hw_config2.irq = mpu_irq;
- hw_config2.dma = -1;
- hw_config2.dma2 = -1;
- hw_config2.always_detect = 0;
- hw_config2.name = NULL;
- hw_config2.driver_use_1 = 0;
- hw_config2.driver_use_2 = 0;
- hw_config2.card_subtype = 0;
-
- if (probe_uart401(&hw_config2))
- {
- mpu_detected = 1;
- attach_uart401(&hw_config2);
- } else
- {
- mpu_base = mpu_irq = 0;
- }
- hw_config->slots[1] = hw_config2.slots[1];
- }
+ {
+ static struct address_info hw_config2 = {
+ 0
+ }; /* Ensure it's initialized */
+
+ hw_config2.io_base = mpu_base;
+ hw_config2.irq = mpu_irq;
+ hw_config2.dma = -1;
+ hw_config2.dma2 = -1;
+ hw_config2.always_detect = 0;
+ hw_config2.name = NULL;
+ hw_config2.driver_use_1 = 0;
+ hw_config2.driver_use_2 = 0;
+ hw_config2.card_subtype = 0;
+
+ if (probe_uart401(&hw_config2))
+ {
+ mpu_detected = 1;
+ attach_uart401(&hw_config2);
+ }
+ else
+ {
+ mpu_base = mpu_irq = 0;
+ }
+ hw_config->slots[1] = hw_config2.slots[1];
+ }
#endif
}
-void
-unload_cs4232(struct address_info *hw_config)
+void unload_cs4232(struct address_info *hw_config)
{
- int base = hw_config->io_base, irq = hw_config->irq;
- int dma1 = hw_config->dma, dma2 = hw_config->dma2;
+ int base = hw_config->io_base, irq = hw_config->irq;
+ int dma1 = hw_config->dma, dma2 = hw_config->dma2;
if (dma2 == -1)
dma2 = dma1;
@@ -315,28 +252,29 @@ unload_cs4232(struct address_info *hw_config)
sound_unload_audiodev(hw_config->slots[0]);
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
if (mpu_base != 0 && mpu_irq != 0 && mpu_detected)
- {
- static struct address_info hw_config2 =
- {0}; /* Ensure it's initialized */
-
- hw_config2.io_base = mpu_base;
- hw_config2.irq = mpu_irq;
- hw_config2.dma = -1;
- hw_config2.dma2 = -1;
- hw_config2.always_detect = 0;
- hw_config2.name = NULL;
- hw_config2.driver_use_1 = 0;
- hw_config2.driver_use_2 = 0;
- hw_config2.card_subtype = 0;
- hw_config2.slots[1] = hw_config->slots[1];
-
- unload_uart401(&hw_config2);
- }
+ {
+ static struct address_info hw_config2 =
+ {
+ 0
+ }; /* Ensure it's initialized */
+
+ hw_config2.io_base = mpu_base;
+ hw_config2.irq = mpu_irq;
+ hw_config2.dma = -1;
+ hw_config2.dma2 = -1;
+ hw_config2.always_detect = 0;
+ hw_config2.name = NULL;
+ hw_config2.driver_use_1 = 0;
+ hw_config2.driver_use_2 = 0;
+ hw_config2.card_subtype = 0;
+ hw_config2.slots[1] = hw_config->slots[1];
+
+ unload_uart401(&hw_config2);
+ }
#endif
}
-void
-unload_cs4232_mpu(struct address_info *hw_config)
+void unload_cs4232_mpu(struct address_info *hw_config)
{
/* Not required. Handled by cs4232_unload */
}
@@ -348,21 +286,26 @@ int irq = -1;
int dma = -1;
int dma2 = -1;
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
+MODULE_PARM(dma,"i");
+MODULE_PARM(dma2,"i");
+
struct address_info cfg;
/*
- * Install a CS4232 based card. Need to have ad1848 and mpu401
- * loaded ready.
+ * Install a CS4232 based card. Need to have ad1848 and mpu401
+ * loaded ready.
*/
int
init_module(void)
{
if (io == -1 || irq == -1 || dma == -1 || dma2 == -1)
- {
- printk(KERN_ERR "cs4232: dma, dma2, irq and io must be set.\n");
- return -EINVAL;
- }
+ {
+ printk(KERN_ERR "cs4232: dma, dma2, irq and io must be set.\n");
+ return -EINVAL;
+ }
cfg.io_base = io;
cfg.irq = irq;
cfg.dma = dma;
@@ -379,13 +322,12 @@ init_module(void)
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
unload_cs4232_mpu(&cfg);
unload_cs4232(&cfg);
SOUND_LOCK_END;
}
-#endif
#endif
+#endif
diff --git a/drivers/sound/dev_table.c b/drivers/sound/dev_table.c
index 1a1f230c2..666d7765e 100644
--- a/drivers/sound/dev_table.c
+++ b/drivers/sound/dev_table.c
@@ -3,6 +3,7 @@
*
* Device call tables.
*/
+
/*
* Copyright (C) by Hannu Savolainen 1993-1997
*
@@ -10,22 +11,21 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+
#include <linux/config.h>
#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);
+int sb_be_quiet = 0;
+int softoss_dev = 0;
+int sound_started = 0;
+int sndtable_get_cardcount(void);
-int
-snd_find_driver(int type)
+int snd_find_driver(int type)
{
- int i, n = num_sound_drivers;
+ int i, n = num_sound_drivers;
for (i = 0; i < n; i++)
if (sound_drivers[i].card_type == type)
@@ -34,25 +34,23 @@ snd_find_driver(int type)
return -1;
}
-static void
-start_services(void)
+static void start_services(void)
{
- int soundcards_installed;
-
#ifdef FIXME
+ int soundcards_installed;
+
if (!(soundcards_installed = sndtable_get_cardcount()))
return; /* No cards detected */
#endif
#ifdef CONFIG_AUDIO
if (num_audiodevs) /* Audio devices present */
- {
- int dev;
-
- for (dev = 0; dev < num_audiodevs; dev++)
- {
- }
- audio_init_devices();
+ {
+ int dev;
+ for (dev = 0; dev < num_audiodevs; dev++)
+ {
+ }
+ audio_init_devices();
}
#endif
@@ -62,20 +60,17 @@ start_services(void)
static void
start_cards(void)
{
- int i, n = num_sound_cards;
- int drv;
+ int i, n = num_sound_cards;
+ int drv;
sound_started = 1;
if (trace_init)
- printk("Sound initialization started\n");
+ printk(KERN_DEBUG "Sound initialization started\n");
#ifdef CONFIG_LOWLEVEL_SOUND
{
- extern void sound_preinit_lowlevel_drivers(void);
-
-#ifdef FIXME
+ extern void sound_preinit_lowlevel_drivers(void);
sound_preinit_lowlevel_drivers();
-#endif
}
#endif
@@ -87,251 +82,244 @@ start_cards(void)
num_sound_cards = i + 1;
for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
+ {
if (snd_installed_cards[i].enabled)
- {
- snd_installed_cards[i].for_driver_use = NULL;
-
- if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) == -1)
- {
- snd_installed_cards[i].enabled = 0; /*
- * Mark as not detected
- */
- continue;
- }
- snd_installed_cards[i].config.card_subtype =
- sound_drivers[drv].card_subtype;
-
- if (sound_drivers[drv].probe(&snd_installed_cards[i].config))
- {
-
- sound_drivers[drv].attach(&snd_installed_cards[i].config);
-
- } else
- snd_installed_cards[i].enabled = 0; /*
+ {
+ snd_installed_cards[i].for_driver_use = NULL;
+
+ if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) == -1)
+ {
+ snd_installed_cards[i].enabled = 0; /*
+ * Mark as not detected
+ */
+ continue;
+ }
+ snd_installed_cards[i].config.card_subtype =
+ sound_drivers[drv].card_subtype;
+
+ if (sound_drivers[drv].probe(&snd_installed_cards[i].config))
+ sound_drivers[drv].attach(&snd_installed_cards[i].config);
+ else
+ snd_installed_cards[i].enabled = 0; /*
* Mark as not detected
*/
- }
+ }
+ }
#ifdef CONFIG_LOWLEVEL_SOUND
{
extern void sound_init_lowlevel_drivers(void);
-
sound_init_lowlevel_drivers();
}
#endif
-
if (trace_init)
- printk("Sound initialization complete\n");
+ printk(KERN_DEBUG "Sound initialization complete\n");
}
-void
-sndtable_init(void)
+void sndtable_init(void)
{
start_cards();
}
-void
-sound_unload_drivers(void)
+void sound_unload_drivers(void)
{
- int i, n = num_sound_cards;
- int drv;
+ int i, n = num_sound_cards;
+ int drv;
if (!sound_started)
return;
if (trace_init)
- printk("Sound unload started\n");
+ printk(KERN_DEBUG "Sound unload started\n");
for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
+ {
if (snd_installed_cards[i].enabled)
- {
- if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) != -1)
- {
- if (sound_drivers[drv].unload)
- {
- sound_drivers[drv].unload(&snd_installed_cards[i].config);
- snd_installed_cards[i].enabled = 0;
- }
- }
- }
+ {
+ if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) != -1)
+ {
+ if (sound_drivers[drv].unload)
+ {
+ sound_drivers[drv].unload(&snd_installed_cards[i].config);
+ snd_installed_cards[i].enabled = 0;
+ }
+ }
+ }
+ }
+
for (i=0;i<num_audiodevs;i++)
DMAbuf_deinit(i);
if (trace_init)
- printk("Sound unload complete\n");
+ printk(KERN_DEBUG "Sound unload complete\n");
}
-void
-sound_unload_driver(int type)
+void sound_unload_driver(int type)
{
- int i, drv = -1, n = num_sound_cards;
+ int i, drv = -1, n = num_sound_cards;
DEB(printk("unload driver %d: ", type));
for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
+ {
if (snd_installed_cards[i].card_type == type)
- {
- if (snd_installed_cards[i].enabled)
- {
- if ((drv = snd_find_driver(type)) != -1)
- {
- DEB(printk(" card %d", i));
- if (sound_drivers[drv].unload)
- {
- sound_drivers[drv].unload(&snd_installed_cards[i].config);
- snd_installed_cards[i].enabled = 0;
- }
- }
- }
- }
+ {
+ if (snd_installed_cards[i].enabled)
+ {
+ if ((drv = snd_find_driver(type)) != -1)
+ {
+ DEB(printk(" card %d", i));
+ if (sound_drivers[drv].unload)
+ {
+ sound_drivers[drv].unload(&snd_installed_cards[i].config);
+ snd_installed_cards[i].enabled = 0;
+ }
+ }
+ }
+ }
+ }
DEB(printk("\n"));
}
-int
-sndtable_probe(int unit, struct address_info *hw_config)
+int sndtable_probe(int unit, struct address_info *hw_config)
{
int sel = -1;
- DEB(printk("sndtable_probe(%d)\n", unit));
+ DEB(printk(KERN_DEBUG "sndtable_probe(%d)\n", unit));
if (!unit)
return 1;
if (sel == -1 && num_sound_cards < max_sound_cards)
- {
- int i;
-
- i = sel = (num_sound_cards++);
-
- snd_installed_cards[sel].card_type = unit;
- snd_installed_cards[sel].enabled = 1;
- }
+ {
+ int i;
+ i = sel = (num_sound_cards++);
+ snd_installed_cards[sel].card_type = unit;
+ snd_installed_cards[sel].enabled = 1;
+ }
if (sel != -1)
- {
- int drv;
-
- snd_installed_cards[sel].for_driver_use = NULL;
- snd_installed_cards[sel].config.io_base = hw_config->io_base;
- snd_installed_cards[sel].config.irq = hw_config->irq;
- snd_installed_cards[sel].config.dma = hw_config->dma;
- snd_installed_cards[sel].config.dma2 = hw_config->dma2;
- snd_installed_cards[sel].config.name = hw_config->name;
- snd_installed_cards[sel].config.always_detect = hw_config->always_detect;
- snd_installed_cards[sel].config.driver_use_1 = hw_config->driver_use_1;
- snd_installed_cards[sel].config.driver_use_2 = hw_config->driver_use_2;
- snd_installed_cards[sel].config.card_subtype = hw_config->card_subtype;
-
- if ((drv = snd_find_driver(snd_installed_cards[sel].card_type)) == -1)
- {
- snd_installed_cards[sel].enabled = 0;
- DEB(printk("Failed to find driver\n"));
- return 0;
- }
- DEB(printk("Driver name '%s'\n", sound_drivers[drv].name));
-
- hw_config->card_subtype =
- snd_installed_cards[sel].config.card_subtype =
- sound_drivers[drv].card_subtype;
-
- if (sound_drivers[drv].probe(hw_config))
- {
- DEB(printk("Hardware probed OK\n"));
- return 1;
- }
- DEB(printk("Failed to find hardware\n"));
- snd_installed_cards[sel].enabled = 0; /*
+ {
+ int drv;
+
+ snd_installed_cards[sel].for_driver_use = NULL;
+ snd_installed_cards[sel].config.io_base = hw_config->io_base;
+ snd_installed_cards[sel].config.irq = hw_config->irq;
+ snd_installed_cards[sel].config.dma = hw_config->dma;
+ snd_installed_cards[sel].config.dma2 = hw_config->dma2;
+ snd_installed_cards[sel].config.name = hw_config->name;
+ snd_installed_cards[sel].config.always_detect = hw_config->always_detect;
+ snd_installed_cards[sel].config.driver_use_1 = hw_config->driver_use_1;
+ snd_installed_cards[sel].config.driver_use_2 = hw_config->driver_use_2;
+ snd_installed_cards[sel].config.card_subtype = hw_config->card_subtype;
+
+ if ((drv = snd_find_driver(snd_installed_cards[sel].card_type)) == -1)
+ {
+ snd_installed_cards[sel].enabled = 0;
+ DEB(printk(KERN_DEBUG "Failed to find driver\n"));
+ return 0;
+ }
+ DEB(printk(KERN_DEBUG "Driver name '%s'\n", sound_drivers[drv].name));
+
+ hw_config->card_subtype = snd_installed_cards[sel].config.card_subtype = sound_drivers[drv].card_subtype;
+
+ if (sound_drivers[drv].probe(hw_config))
+ {
+ DEB(printk(KERN_DEBUG "Hardware probed OK\n"));
+ return 1;
+ }
+ DEB(printk("Failed to find hardware\n"));
+ snd_installed_cards[sel].enabled = 0; /*
* Mark as not detected
*/
- return 0;
- }
+ return 0;
+ }
return 0;
}
-int
-sndtable_init_card(int unit, struct address_info *hw_config)
+int sndtable_init_card(int unit, struct address_info *hw_config)
{
- int i, n = num_sound_cards;
+ int i, n = num_sound_cards;
DEB(printk("sndtable_init_card(%d) entered\n", unit));
if (!unit)
- {
- sndtable_init();
- return 1;
- }
+ {
+ sndtable_init();
+ return 1;
+ }
for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
+ {
if (snd_installed_cards[i].card_type == unit)
- {
- int drv;
-
- snd_installed_cards[i].config.io_base = hw_config->io_base;
- snd_installed_cards[i].config.irq = hw_config->irq;
- snd_installed_cards[i].config.dma = hw_config->dma;
- snd_installed_cards[i].config.dma2 = hw_config->dma2;
- snd_installed_cards[i].config.name = hw_config->name;
- snd_installed_cards[i].config.always_detect = hw_config->always_detect;
- snd_installed_cards[i].config.driver_use_1 = hw_config->driver_use_1;
- snd_installed_cards[i].config.driver_use_2 = hw_config->driver_use_2;
- snd_installed_cards[i].config.card_subtype = hw_config->card_subtype;
-
- if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) == -1)
- snd_installed_cards[i].enabled = 0; /*
+ {
+ int drv;
+
+ snd_installed_cards[i].config.io_base = hw_config->io_base;
+ snd_installed_cards[i].config.irq = hw_config->irq;
+ snd_installed_cards[i].config.dma = hw_config->dma;
+ snd_installed_cards[i].config.dma2 = hw_config->dma2;
+ snd_installed_cards[i].config.name = hw_config->name;
+ snd_installed_cards[i].config.always_detect = hw_config->always_detect;
+ snd_installed_cards[i].config.driver_use_1 = hw_config->driver_use_1;
+ snd_installed_cards[i].config.driver_use_2 = hw_config->driver_use_2;
+ snd_installed_cards[i].config.card_subtype = hw_config->card_subtype;
+
+ if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) == -1)
+ snd_installed_cards[i].enabled = 0; /*
* Mark as not detected
*/
- else
- {
-
- DEB(printk("Located card - calling attach routine\n"));
- sound_drivers[drv].attach(hw_config);
-
- DEB(printk("attach routine finished\n"));
- }
- start_services();
- return 1;
- }
+ else
+ {
+ DEB(printk(KERN_DEBUG "Located card - calling attach routine\n"));
+ sound_drivers[drv].attach(hw_config);
+
+ DEB(printk("attach routine finished\n"));
+ }
+ start_services();
+ return 1;
+ }
+ }
DEB(printk("sndtable_init_card: No card defined with type=%d, num cards: %d\n", unit, num_sound_cards));
return 0;
}
-int
-sndtable_get_cardcount(void)
+int sndtable_get_cardcount(void)
{
return num_audiodevs + num_mixers + num_synths + num_midis;
}
-int
-sndtable_identify_card(char *name)
+int sndtable_identify_card(char *name)
{
- int i, n = num_sound_drivers;
+ int i, n = num_sound_drivers;
if (name == NULL)
return 0;
for (i = 0; i < n; i++)
+ {
if (sound_drivers[i].driver_id != NULL)
- {
- char *id = sound_drivers[i].driver_id;
- int j;
-
- for (j = 0; j < 80 && name[j] == id[j]; j++)
- if (id[j] == 0 && name[j] == 0) /* Match */
- return sound_drivers[i].card_type;
- }
+ {
+ char *id = sound_drivers[i].driver_id;
+ int j;
+
+ for (j = 0; j < 80 && name[j] == id[j]; j++)
+ if (id[j] == 0 && name[j] == 0) /* Match */
+ return sound_drivers[i].card_type;
+ }
+ }
return 0;
}
-void
-sound_setup(char *str, int *ints)
+void sound_setup(char *str, int *ints)
{
- int i, n = num_sound_cards;
+ int i, n = num_sound_cards;
/*
- * First disable all drivers
+ * First disable all drivers
*/
for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
@@ -340,70 +328,69 @@ sound_setup(char *str, int *ints)
if (ints[0] == 0 || ints[1] == 0)
return;
/*
- * Then enable them one by time
+ * Then enable them one by time
*/
for (i = 1; i <= ints[0]; i++)
- {
- int card_type, ioaddr, irq, dma, dma2,
- ptr, j;
- unsigned int val;
-
- val = (unsigned int) ints[i];
-
- card_type = (val & 0x0ff00000) >> 20;
-
- if (card_type > 127)
- {
- /*
- * Add any future extensions here
- */
- return;
- }
- ioaddr = (val & 0x000fff00) >> 8;
- irq = (val & 0x000000f0) >> 4;
- dma = (val & 0x0000000f);
- dma2 = (val & 0xf0000000) >> 28;
-
- ptr = -1;
- for (j = 0; j < n && ptr == -1; j++)
- if (snd_installed_cards[j].card_type == card_type &&
- !snd_installed_cards[j].enabled) /*
+ {
+ int card_type, ioaddr, irq, dma, dma2, ptr, j;
+ unsigned int val;
+
+ val = (unsigned int) ints[i];
+ card_type = (val & 0x0ff00000) >> 20;
+
+ if (card_type > 127)
+ {
+ /*
+ * Add any future extensions here
+ */
+ return;
+ }
+ ioaddr = (val & 0x000fff00) >> 8;
+ irq = (val & 0x000000f0) >> 4;
+ dma = (val & 0x0000000f);
+ dma2 = (val & 0xf0000000) >> 28;
+
+ ptr = -1;
+ for (j = 0; j < n && ptr == -1; j++)
+ {
+ if (snd_installed_cards[j].card_type == card_type &&
+ !snd_installed_cards[j].enabled)/*
* Not already found
*/
- ptr = j;
-
- if (ptr == -1)
- printk("Sound: Invalid setup parameter 0x%08x\n", val);
- else
- {
- snd_installed_cards[ptr].enabled = 1;
- snd_installed_cards[ptr].config.io_base = ioaddr;
- snd_installed_cards[ptr].config.irq = irq;
- snd_installed_cards[ptr].config.dma = dma;
- snd_installed_cards[ptr].config.dma2 = dma2;
- snd_installed_cards[ptr].config.name = NULL;
- snd_installed_cards[ptr].config.always_detect = 0;
- snd_installed_cards[ptr].config.driver_use_1 = 0;
- snd_installed_cards[ptr].config.driver_use_2 = 0;
- snd_installed_cards[ptr].config.card_subtype = 0;
- }
- }
+ ptr = j;
+ }
+
+ if (ptr == -1)
+ printk(KERN_ERR "Sound: Invalid setup parameter 0x%08x\n", val);
+ else
+ {
+ snd_installed_cards[ptr].enabled = 1;
+ snd_installed_cards[ptr].config.io_base = ioaddr;
+ snd_installed_cards[ptr].config.irq = irq;
+ snd_installed_cards[ptr].config.dma = dma;
+ snd_installed_cards[ptr].config.dma2 = dma2;
+ snd_installed_cards[ptr].config.name = NULL;
+ snd_installed_cards[ptr].config.always_detect = 0;
+ snd_installed_cards[ptr].config.driver_use_1 = 0;
+ snd_installed_cards[ptr].config.driver_use_2 = 0;
+ snd_installed_cards[ptr].config.card_subtype = 0;
+ }
+ }
}
-struct address_info
- *
-sound_getconf(int card_type)
+struct address_info * sound_getconf(int card_type)
{
- int j, ptr;
- int n = num_sound_cards;
+ int j, ptr;
+ int n = num_sound_cards;
ptr = -1;
for (j = 0; j < n && ptr == -1 && snd_installed_cards[j].card_type; j++)
+ {
if (snd_installed_cards[j].card_type == card_type)
ptr = j;
-
+ }
if (ptr == -1)
return (struct address_info *) NULL;
@@ -412,60 +399,53 @@ sound_getconf(int card_type)
-int
-sound_install_audiodrv(int vers,
- char *name,
- struct audio_driver *driver,
- int driver_size,
- int flags,
- unsigned int format_mask,
- void *devc,
- int dma1,
- int dma2)
+int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
+ int driver_size, int flags, unsigned int format_mask,
+ void *devc, int dma1, int dma2)
{
#ifdef CONFIG_AUDIO
struct audio_driver *d;
struct audio_operations *op;
- int l, num;
+ int l, num;
- if (vers != AUDIO_DRIVER_VERSION ||
- driver_size > sizeof(struct audio_driver))
- {
- printk(KERN_ERR "Sound: Incompatible audio driver for %s\n", name);
- return -(EINVAL);
- }
+ if (vers != AUDIO_DRIVER_VERSION || driver_size > sizeof(struct audio_driver))
+ {
+ printk(KERN_ERR "Sound: Incompatible audio driver for %s\n", name);
+ return -(EINVAL);
+ }
num = sound_alloc_audiodev();
if (num == -1)
- {
- printk(KERN_ERR "sound: Too many audio drivers\n");
- return -(EBUSY);
- }
+ {
+ printk(KERN_ERR "sound: Too many audio drivers\n");
+ 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++;;
+ 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++;;
+ sound_nblocks++;
if (d == NULL || op == NULL)
- {
- printk(KERN_ERR "Sound: Can't allocate driver for (%s)\n", name);
- sound_unload_audiodev(num);
- return -(ENOMEM);
- }
+ {
+ printk(KERN_ERR "Sound: Can't allocate driver for (%s)\n", name);
+ sound_unload_audiodev(num);
+ return -(ENOMEM);
+ }
memset((char *) op, 0, sizeof(struct audio_operations));
+ init_waitqueue(&op->in_sleeper);
+ init_waitqueue(&op->out_sleeper);
if (driver_size < sizeof(struct audio_driver))
- memset((char *) d, 0, sizeof(struct audio_driver));
+ memset((char *) d, 0, sizeof(struct audio_driver));
memcpy((char *) d, (char *) driver, driver_size);
op->d = d;
-
l = strlen(name) + 1;
if (l > sizeof(op->name))
l = sizeof(op->name);
@@ -475,9 +455,9 @@ sound_install_audiodrv(int vers,
op->format_mask = format_mask;
op->devc = devc;
-/*
- * Hardcoded defaults
- */
+ /*
+ * Hardcoded defaults
+ */
audio_devs[num] = op;
DMAbuf_init(num, dma1, dma2);
@@ -489,41 +469,40 @@ sound_install_audiodrv(int vers,
#endif
}
-int
-sound_install_mixer(int vers,
- char *name,
- struct mixer_operations *driver,
- int driver_size,
- void *devc)
+int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
+ int driver_size, void *devc)
{
struct mixer_operations *op;
- int l;
+ int l;
- int n = sound_alloc_mixerdev();
+ int n = sound_alloc_mixerdev();
if (n == -1)
- {
- printk(KERN_ERR "Sound: Too many mixer drivers\n");
- return -(EBUSY);
- }
+ {
+ printk(KERN_ERR "Sound: Too many mixer drivers\n");
+ return -EBUSY;
+ }
if (vers != MIXER_DRIVER_VERSION ||
- driver_size > sizeof(struct mixer_operations))
- {
- printk(KERN_ERR "Sound: Incompatible mixer driver for %s\n", name);
- return -(EINVAL);
- }
+ driver_size > sizeof(struct mixer_operations))
+ {
+ printk(KERN_ERR "Sound: Incompatible mixer driver for %s\n", name);
+ return -EINVAL;
+ }
+
+ /* FIXME: This leaks a mixer_operations struct every time its called
+ 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++;;
+ sound_nblocks++;
if (op == NULL)
- {
- printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name);
- return -(ENOMEM);
- }
+ {
+ printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name);
+ return -ENOMEM;
+ }
memset((char *) op, 0, sizeof(struct mixer_operations));
-
memcpy((char *) op, (char *) driver, driver_size);
l = strlen(name) + 1;
@@ -537,108 +516,99 @@ sound_install_mixer(int vers,
return n;
}
-void
-sound_unload_audiodev(int dev)
+void sound_unload_audiodev(int dev)
{
if (dev != -1)
audio_devs[dev] = NULL;
}
-int
-sound_alloc_audiodev(void)
+int sound_alloc_audiodev(void)
{
- int i;
+ int i;
for (i = 0; i < MAX_AUDIO_DEV; i++)
- {
- if (audio_devs[i] == NULL)
- {
- if (i >= num_audiodevs)
- num_audiodevs = i + 1;
- return i;
- }
- }
+ {
+ if (audio_devs[i] == NULL)
+ {
+ if (i >= num_audiodevs)
+ num_audiodevs = i + 1;
+ return i;
+ }
+ }
return -1;
}
-int
-sound_alloc_mididev(void)
+int sound_alloc_mididev(void)
{
- int i;
+ int i;
for (i = 0; i < MAX_MIDI_DEV; i++)
- {
- if (midi_devs[i] == NULL)
- {
- if (i >= num_midis)
- num_midis++;
- return i;
- }
- }
-
+ {
+ if (midi_devs[i] == NULL)
+ {
+ if (i >= num_midis)
+ num_midis++;
+ return i;
+ }
+ }
return -1;
}
-int
-sound_alloc_synthdev(void)
+int sound_alloc_synthdev(void)
{
- int i;
+ int i;
for (i = 0; i < MAX_SYNTH_DEV; i++)
- {
- if (synth_devs[i] == NULL)
- {
- if (i >= num_synths)
- num_synths++;
- return i;
- }
- }
+ {
+ if (synth_devs[i] == NULL)
+ {
+ if (i >= num_synths)
+ num_synths++;
+ return i;
+ }
+ }
return -1;
}
-int
-sound_alloc_mixerdev(void)
+int sound_alloc_mixerdev(void)
{
- int i;
+ int i;
for (i = 0; i < MAX_MIXER_DEV; i++)
- {
- if (mixer_devs[i] == NULL)
- {
- if (i >= num_mixers)
- num_mixers++;
- return i;
- }
- }
+ {
+ if (mixer_devs[i] == NULL)
+ {
+ if (i >= num_mixers)
+ num_mixers++;
+ return i;
+ }
+ }
return -1;
}
-int
-sound_alloc_timerdev(void)
+int sound_alloc_timerdev(void)
{
- int i;
+ int i;
for (i = 0; i < MAX_TIMER_DEV; i++)
- {
- if (sound_timer_devs[i] == NULL)
- {
- if (i >= num_sound_timers)
- num_sound_timers++;
- return i;
- }
- }
+ {
+ if (sound_timer_devs[i] == NULL)
+ {
+ if (i >= num_sound_timers)
+ num_sound_timers++;
+ return i;
+ }
+ }
return -1;
}
-void
-sound_unload_mixerdev(int dev)
+void sound_unload_mixerdev(int dev)
{
if (dev != -1)
mixer_devs[dev] = NULL;
}
-void
-sound_unload_mididev(int dev)
+void sound_unload_mididev(int dev)
{
#ifdef CONFIG_MIDI
if (dev != -1)
@@ -646,16 +616,15 @@ sound_unload_mididev(int dev)
#endif
}
-void
-sound_unload_synthdev(int dev)
+void sound_unload_synthdev(int dev)
{
if (dev != -1)
synth_devs[dev] = NULL;
}
-void
-sound_unload_timerdev(int dev)
+void sound_unload_timerdev(int dev)
{
if (dev != -1)
sound_timer_devs[dev] = NULL;
}
+
diff --git a/drivers/sound/dev_table.h b/drivers/sound/dev_table.h
index a146614c8..878cb2971 100644
--- a/drivers/sound/dev_table.h
+++ b/drivers/sound/dev_table.h
@@ -2,8 +2,8 @@
* dev_table.h
*
* Global definitions for device call tables
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -15,17 +15,20 @@
#ifndef _DEV_TABLE_H_
#define _DEV_TABLE_H_
+#include <linux/config.h>
/*
* Sound card numbers 27 to 999. (1 to 26 are defined in soundcard.h)
* Numbers 1000 to N are reserved for driver's internal use.
*/
+
#define SNDCARD_DESKPROXL 27 /* Compaq Deskpro XL */
#define SNDCARD_SBPNP 29
#define SNDCARD_OPL3SA1 38
#define SNDCARD_OPL3SA1_SB 39
#define SNDCARD_OPL3SA1_MPU 40
#define SNDCARD_SOFTOSS 36
+#define SNDCARD_VMIDI 37
void attach_opl3sa_wss (struct address_info *hw_config);
int probe_opl3sa_wss (struct address_info *hw_config);
@@ -50,7 +53,8 @@ void unload_softsyn (struct address_info *hw_config);
extern int sound_started;
-struct driver_info {
+struct driver_info
+{
char *driver_id;
int card_subtype; /* Driver specific. Usually 0 */
int card_type; /* From soundcard.h */
@@ -60,7 +64,8 @@ struct driver_info {
void (*unload) (struct address_info *hw_config);
};
-struct card_info {
+struct card_info
+{
int card_type; /* Link (search key) to the driver list */
struct address_info config;
int enabled;
@@ -77,7 +82,8 @@ struct card_info {
#define DMODE_OUTPUT PCM_ENABLE_OUTPUT
#define DMODE_INPUT PCM_ENABLE_INPUT
-struct dma_buffparms {
+struct dma_buffparms
+{
int dma_mode; /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */
int closing;
@@ -154,17 +160,19 @@ struct dma_buffparms {
* Structure for use with various microcontrollers and DSP processors
* in the recent soundcards.
*/
-typedef struct coproc_operations {
- char name[64];
- int (*open) (void *devc, int sub_device);
- void (*close) (void *devc, int sub_device);
- int (*ioctl) (void *devc, unsigned int cmd, caddr_t arg, int local);
- void (*reset) (void *devc);
+typedef struct coproc_operations
+{
+ char name[64];
+ int (*open) (void *devc, int sub_device);
+ void (*close) (void *devc, int sub_device);
+ int (*ioctl) (void *devc, unsigned int cmd, caddr_t arg, int local);
+ void (*reset) (void *devc);
- void *devc; /* Driver specific info */
- } coproc_operations;
+ void *devc; /* Driver specific info */
+} coproc_operations;
-struct audio_driver {
+struct audio_driver
+{
int (*open) (int dev, int mode);
void (*close) (int dev);
void (*output_block) (int dev, unsigned long buf,
@@ -188,7 +196,8 @@ struct audio_driver {
void (*preprocess_read)(int dev); /* Device spesific preprocessing for read data */
};
-struct audio_operations {
+struct audio_operations
+{
char name[128];
int flags;
#define NOTHING_SPECIAL 0x00
@@ -212,11 +221,33 @@ struct audio_operations {
int min_fragment; /* 0 == unlimited */
int max_fragment; /* 0 == unlimited */
int parent_dev; /* 0 -> no parent, 1 to n -> parent=parent_dev+1 */
+
+ /* fields formerly in dmabuf.c */
+ struct wait_queue *in_sleeper;
+ struct wait_queue *out_sleeper;
+
+ /* fields formerly in audio.c */
+ int audio_mode;
+ /* why dont we use file->f_flags & O_NONBLOCK for the following? - ts */
+ int dev_nblock; /* 1 if in nonblocking mode */
+
+#define AM_NONE 0
+#define AM_WRITE OPEN_WRITE
+#define AM_READ OPEN_READ
+
+ int local_format;
+ int audio_format;
+ int local_conversion;
+#define CNV_MU_LAW 0x00000001
+
+ /* large structures at the end to keep offsets small */
+ struct dma_buffparms dmaps[2];
};
int *load_mixer_volumes(char *name, int *levels, int present);
-struct mixer_operations {
+struct mixer_operations
+{
char id[16];
char name[64];
int (*ioctl) (int dev, unsigned int cmd, caddr_t arg);
@@ -225,7 +256,8 @@ struct mixer_operations {
int modify_counter;
};
-struct synth_operations {
+struct synth_operations
+{
char *id; /* Unique identifier (ASCII) max 29 char */
struct synth_info *info;
int midi_dev;
@@ -261,20 +293,23 @@ struct synth_operations {
int sysex_ptr;
};
-struct midi_input_info { /* MIDI input scanner variables */
+struct midi_input_info
+{
+ /* MIDI input scanner variables */
#define MI_MAX 10
- int m_busy;
- unsigned char m_buf[MI_MAX];
- unsigned char m_prev_status; /* For running status */
- int m_ptr;
+ int m_busy;
+ unsigned char m_buf[MI_MAX];
+ unsigned char m_prev_status; /* For running status */
+ int m_ptr;
#define MST_INIT 0
#define MST_DATA 1
#define MST_SYSEX 2
- int m_state;
- int m_left;
- };
+ int m_state;
+ int m_left;
+};
-struct midi_operations {
+struct midi_operations
+{
struct midi_info info;
struct synth_operations *converter;
struct midi_input_info in_info;
@@ -295,15 +330,17 @@ struct midi_operations {
void *devc;
};
-struct sound_lowlev_timer {
- int dev;
- int priority;
- unsigned int (*tmr_start)(int dev, unsigned int usecs);
- void (*tmr_disable)(int dev);
- void (*tmr_restart)(int dev);
- };
+struct sound_lowlev_timer
+{
+ int dev;
+ int priority;
+ unsigned int (*tmr_start)(int dev, unsigned int usecs);
+ void (*tmr_disable)(int dev);
+ void (*tmr_restart)(int dev);
+};
-struct sound_timer_operations {
+struct sound_timer_operations
+{
struct sound_timer_info info;
int priority;
int devlink;
@@ -317,91 +354,94 @@ struct sound_timer_operations {
#ifdef _DEV_TABLE_C_
- struct audio_operations *audio_devs[MAX_AUDIO_DEV] = {NULL}; int num_audiodevs = 0;
- struct mixer_operations *mixer_devs[MAX_MIXER_DEV] = {NULL}; int num_mixers = 0;
- struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV] = {NULL}; int num_synths = 0;
- struct midi_operations *midi_devs[MAX_MIDI_DEV] = {NULL}; int num_midis = 0;
+struct audio_operations *audio_devs[MAX_AUDIO_DEV] = {NULL}; int num_audiodevs = 0;
+struct mixer_operations *mixer_devs[MAX_MIXER_DEV] = {NULL}; int num_mixers = 0;
+struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV] = {NULL}; int num_synths = 0;
+struct midi_operations *midi_devs[MAX_MIDI_DEV] = {NULL}; int num_midis = 0;
#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS) && !defined(VMIDI)
- extern struct sound_timer_operations default_sound_timer;
- struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] =
- {&default_sound_timer, NULL};
- int num_sound_timers = 1;
+extern struct sound_timer_operations default_sound_timer;
+struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
+ &default_sound_timer, NULL
+};
+int num_sound_timers = 1;
#else
- struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] =
- {NULL};
- int num_sound_timers = 0;
+struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
+ NULL
+};
+int num_sound_timers = 0;
#endif
/*
* List of low level drivers compiled into the kernel.
*/
- struct driver_info sound_drivers[] = {
+struct driver_info sound_drivers[] =
+{
#if defined(CONFIG_PSS) && !defined(CONFIG_PSS_MODULE)
- {"PSS", 0, SNDCARD_PSS, "Echo Personal Sound System PSS (ESC614)", attach_pss, probe_pss, unload_pss},
- {"PSSMPU", 0, SNDCARD_PSS_MPU, "PSS-MPU", attach_pss_mpu, probe_pss_mpu, unload_pss_mpu},
- {"PSSMSS", 0, SNDCARD_PSS_MSS, "PSS-MSS", attach_pss_mss, probe_pss_mss, unload_pss_mss},
+ {"PSS", 0, SNDCARD_PSS, "Echo Personal Sound System PSS (ESC614)", attach_pss, probe_pss, unload_pss},
+ {"PSSMPU", 0, SNDCARD_PSS_MPU, "PSS-MPU", attach_pss_mpu, probe_pss_mpu, unload_pss_mpu},
+ {"PSSMSS", 0, SNDCARD_PSS_MSS, "PSS-MSS", attach_pss_mss, probe_pss_mss, unload_pss_mss},
#endif
#if defined(CONFIG_GUS) && !defined(CONFIG_GUS_MODULE)
#ifdef CONFIG_GUS16
- {"GUS16", 0, SNDCARD_GUS16, "Ultrasound 16-bit opt.", attach_gus_db16, probe_gus_db16, unload_gus_db16},
+ {"GUS16", 0, SNDCARD_GUS16, "Ultrasound 16-bit opt.", attach_gus_db16, probe_gus_db16, unload_gus_db16},
#endif
-#ifdef CONFIG_GUSHW
- {"GUS", 0, SNDCARD_GUS, "Gravis Ultrasound", attach_gus_card, probe_gus, unload_gus},
- {"GUSPNP", 1, SNDCARD_GUSPNP, "GUS PnP", attach_gus_card, probe_gus, unload_gus},
+#ifdef CONFIG_GUS
+ {"GUS", 0, SNDCARD_GUS, "Gravis Ultrasound", attach_gus_card, probe_gus, unload_gus},
+ {"GUSPNP", 1, SNDCARD_GUSPNP, "GUS PnP", attach_gus_card, probe_gus, unload_gus},
#endif
#endif
#if defined(CONFIG_MSS) && !defined(CONFIG_MSS_MODULE)
- {"MSS", 0, SNDCARD_MSS, "MS Sound System", attach_ms_sound, probe_ms_sound, unload_ms_sound},
+ {"MSS", 0, SNDCARD_MSS, "MS Sound System", attach_ms_sound, probe_ms_sound, unload_ms_sound},
/* Compaq Deskpro XL */
- {"DESKPROXL", 2, SNDCARD_DESKPROXL, "Compaq Deskpro XL", attach_ms_sound, probe_ms_sound, unload_ms_sound},
+ {"DESKPROXL", 2, SNDCARD_DESKPROXL, "Compaq Deskpro XL", attach_ms_sound, probe_ms_sound, unload_ms_sound},
#endif
#ifdef CONFIG_MAD16
- {"MAD16", 0, SNDCARD_MAD16, "MAD16/Mozart (MSS)", attach_mad16, probe_mad16, unload_mad16},
- {"MAD16MPU", 0, SNDCARD_MAD16_MPU, "MAD16/Mozart (MPU)", attach_mad16_mpu, probe_mad16_mpu, unload_mad16_mpu},
+ {"MAD16", 0, SNDCARD_MAD16, "MAD16/Mozart (MSS)", attach_mad16, probe_mad16, unload_mad16},
+ {"MAD16MPU", 0, SNDCARD_MAD16_MPU, "MAD16/Mozart (MPU)", attach_mad16_mpu, probe_mad16_mpu, unload_mad16_mpu},
#endif
#ifdef CONFIG_CS4232
- {"CS4232", 0, SNDCARD_CS4232, "CS4232", attach_cs4232, probe_cs4232, unload_cs4232},
- {"CS4232MPU", 0, SNDCARD_CS4232_MPU, "CS4232 MIDI", attach_cs4232_mpu, probe_cs4232_mpu, unload_cs4232_mpu},
+ {"CS4232", 0, SNDCARD_CS4232, "CS4232", attach_cs4232, probe_cs4232, unload_cs4232},
+ {"CS4232MPU", 0, SNDCARD_CS4232_MPU, "CS4232 MIDI", attach_cs4232_mpu, probe_cs4232_mpu, unload_cs4232_mpu},
#endif
#if defined(CONFIG_YM3812) && !defined(CONFIG_YM3812_MODULE)
- {"OPL3", 0, SNDCARD_ADLIB, "OPL-2/OPL-3 FM", attach_adlib_card, probe_adlib, unload_adlib},
+ {"OPL3", 0, SNDCARD_ADLIB, "OPL-2/OPL-3 FM", attach_adlib_card, probe_adlib, unload_adlib},
#endif
#if defined(CONFIG_PAS) && !defined(CONFIG_PAS_MODULE)
- {"PAS16", 0, SNDCARD_PAS, "ProAudioSpectrum", attach_pas_card, probe_pas, unload_pas},
+ {"PAS16", 0, SNDCARD_PAS, "ProAudioSpectrum", attach_pas_card, probe_pas, unload_pas},
#endif
#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) && !defined(CONFIG_MPU401_MODULE)
- {"MPU401", 0, SNDCARD_MPU401,"Roland MPU-401", attach_mpu401, probe_mpu401, unload_mpu401},
+ {"MPU401", 0, SNDCARD_MPU401,"Roland MPU-401", attach_mpu401, probe_mpu401, unload_mpu401},
#endif
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI) && !defined(CONFIG_UART401_MODULE)
{"UART401", 0, SNDCARD_UART401,"MPU-401 (UART)",
attach_uart401, probe_uart401, unload_uart401},
#endif
#if defined(CONFIG_MAUI) && !defined(CONFIG_MAUI_MODULE)
- {"MAUI", 0, SNDCARD_MAUI,"TB Maui", attach_maui, probe_maui, unload_maui},
+ {"MAUI", 0, SNDCARD_MAUI,"TB Maui", attach_maui, probe_maui, unload_maui},
#endif
#if defined(CONFIG_UART6850) && defined(CONFIG_MIDI) && !defined(CONFIG_UART6850_MODULE)
- {"MIDI6850", 0, SNDCARD_UART6850,"6860 UART Midi", attach_uart6850, probe_uart6850, unload_uart6850},
+ {"MIDI6850", 0, SNDCARD_UART6850,"6860 UART Midi", attach_uart6850, probe_uart6850, unload_uart6850},
#endif
#if defined(CONFIG_SBDSP) && !defined(CONFIG_SBDSP_MODULE)
- {"SBLAST", 0, SNDCARD_SB, "Sound Blaster", attach_sb_card, probe_sb, unload_sb},
- {"SBPNP", 6, SNDCARD_SBPNP, "Sound Blaster PnP", attach_sb_card, probe_sb, unload_sb},
+ {"SBLAST", 0, SNDCARD_SB, "Sound Blaster", attach_sb_card, probe_sb, unload_sb},
+ {"SBPNP", 6, SNDCARD_SBPNP, "Sound Blaster PnP", attach_sb_card, probe_sb, unload_sb},
-# ifdef CONFIG_MIDI
- {"SBMPU", 0, SNDCARD_SB16MIDI,"SB MPU-401", attach_sbmpu, probe_sbmpu, unload_sbmpu},
-# endif
+#ifdef CONFIG_MIDI
+ {"SBMPU", 0, SNDCARD_SB16MIDI,"SB MPU-401", attach_sbmpu, probe_sbmpu, unload_sbmpu},
+#endif
#endif
-#ifdef CONFIG_SSCAPEHW
- {"SSCAPE", 0, SNDCARD_SSCAPE, "Ensoniq SoundScape", attach_sscape, probe_sscape, unload_sscape},
- {"SSCAPEMSS", 0, SNDCARD_SSCAPE_MSS, "MS Sound System (SoundScape)", attach_ss_ms_sound, probe_ss_ms_sound, unload_ss_ms_sound},
+#ifdef CONFIG_SSCAPE
+ {"SSCAPE", 0, SNDCARD_SSCAPE, "Ensoniq SoundScape", attach_sscape, probe_sscape, unload_sscape},
+ {"SSCAPEMSS", 0, SNDCARD_SSCAPE_MSS, "MS Sound System (SoundScape)", attach_ss_ms_sound, probe_ss_ms_sound, unload_ss_ms_sound},
#endif
#ifdef CONFIG_OPL3SA1
@@ -411,196 +451,199 @@ struct sound_timer_operations {
#endif
#if defined (CONFIG_TRIX) && !defined(CONFIG_TRIX_MODULE)
- {"TRXPRO", 0, SNDCARD_TRXPRO, "MediaTrix AudioTrix Pro", attach_trix_wss, probe_trix_wss, unload_trix_wss},
- {"TRXPROSB", 0, SNDCARD_TRXPRO_SB, "AudioTrix (SB mode)", attach_trix_sb, probe_trix_sb, unload_trix_sb},
- {"TRXPROMPU", 0, SNDCARD_TRXPRO_MPU, "AudioTrix MIDI", attach_trix_mpu, probe_trix_mpu, unload_trix_mpu},
+ {"TRXPRO", 0, SNDCARD_TRXPRO, "MediaTrix AudioTrix Pro", attach_trix_wss, probe_trix_wss, unload_trix_wss},
+ {"TRXPROSB", 0, SNDCARD_TRXPRO_SB, "AudioTrix (SB mode)", attach_trix_sb, probe_trix_sb, unload_trix_sb},
+ {"TRXPROMPU", 0, SNDCARD_TRXPRO_MPU, "AudioTrix MIDI", attach_trix_mpu, probe_trix_mpu, unload_trix_mpu},
#endif
#if defined(CONFIG_SOFTOSS) && !defined(CONFIG_SOFTOSS_MODULE)
- {"SOFTSYN", 0, SNDCARD_SOFTOSS, "SoftOSS Virtual Wave Table",
+ {"SOFTSYN", 0, SNDCARD_SOFTOSS, "SoftOSS Virtual Wave Table",
attach_softsyn_card, probe_softsyn, unload_softsyn},
#endif
+#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
+ {NULL, 0, 0, "*?*", NULL, NULL, NULL}
+};
-
-
- {NULL, 0, 0, "*?*", NULL, NULL, NULL}
- };
-
- int num_sound_drivers =
- sizeof(sound_drivers) / sizeof (struct driver_info);
+int num_sound_drivers = sizeof(sound_drivers) / sizeof (struct driver_info);
#ifndef FULL_SOUND
+
/*
* List of devices actually configured in the system.
*
* Note! The detection order is significant. Don't change it.
*/
- struct card_info snd_installed_cards[] = {
+struct card_info snd_installed_cards[] =
+{
#ifdef CONFIG_PSS
- {SNDCARD_PSS, {PSS_BASE, 0, -1, -1}, SND_DEFAULT_ENABLE},
-# ifdef PSS_MPU_BASE
- {SNDCARD_PSS_MPU, {PSS_MPU_BASE, PSS_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-# endif
-# ifdef PSS_MSS_BASE
- {SNDCARD_PSS_MSS, {PSS_MSS_BASE, PSS_MSS_IRQ, PSS_MSS_DMA, -1}, SND_DEFAULT_ENABLE},
-# endif
+ {SNDCARD_PSS, {CONFIG_PSS_BASE, 0, -1, -1}, SND_DEFAULT_ENABLE},
+#ifdef CONFIG_PSS_MPU_BASE
+ {SNDCARD_PSS_MPU, {CONFIG_PSS_MPU_BASE, CONFIG_PSS_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+#endif
+#ifdef CONFIG_PSS_MSS_BASE
+ {SNDCARD_PSS_MSS, {CONFIG_PSS_MSS_BASE, CONFIG_PSS_MSS_IRQ, CONFIG_PSS_MSS_DMA, -1}, SND_DEFAULT_ENABLE},
+#endif
#endif
#ifdef CONFIG_TRIX
-#ifndef TRIX_DMA2
-#define TRIX_DMA2 TRIX_DMA
+#ifndef CONFIG_TRIX_DMA2
+#define CONFIG_TRIX_DMA2 CONFIG_TRIX_DMA
+#endif
+ {SNDCARD_TRXPRO, {CONFIG_TRIX_BASE, CONFIG_TRIX_IRQ, CONFIG_TRIX_DMA, CONFIG_TRIX_DMA2}, SND_DEFAULT_ENABLE},
+#ifdef CONFIG_TRIX_SB_BASE
+ {SNDCARD_TRXPRO_SB, {CONFIG_TRIX_SB_BASE, CONFIG_TRIX_SB_IRQ, CONFIG_TRIX_SB_DMA, -1}, SND_DEFAULT_ENABLE},
+#endif
+#ifdef CONFIG_TRIX_MPU_BASE
+ {SNDCARD_TRXPRO_MPU, {CONFIG_TRIX_MPU_BASE, CONFIG_TRIX_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
#endif
- {SNDCARD_TRXPRO, {TRIX_BASE, TRIX_IRQ, TRIX_DMA, TRIX_DMA2}, SND_DEFAULT_ENABLE},
-# ifdef TRIX_SB_BASE
- {SNDCARD_TRXPRO_SB, {TRIX_SB_BASE, TRIX_SB_IRQ, TRIX_SB_DMA, -1}, SND_DEFAULT_ENABLE},
-# endif
-# ifdef TRIX_MPU_BASE
- {SNDCARD_TRXPRO_MPU, {TRIX_MPU_BASE, TRIX_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-# endif
#endif
#ifdef CONFIG_OPL3SA1
- {SNDCARD_OPL3SA1, {OPL3SA1_BASE, OPL3SA1_IRQ, OPL3SA1_DMA, OPL3SA1_DMA2}, SND_DEFAULT_ENABLE},
-# ifdef OPL3SA1_MPU_BASE
- {SNDCARD_OPL3SA1_MPU, {OPL3SA1_MPU_BASE, OPL3SA1_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-# endif
+ {SNDCARD_OPL3SA1, {CONFIG_OPL3SA1_BASE, CONFIG_OPL3SA1_IRQ, CONFIG_OPL3SA1_DMA, CONFIG_OPL3SA1_DMA2}, SND_DEFAULT_ENABLE},
+#ifdef CONFIG_OPL3SA1_MPU_BASE
+ {SNDCARD_OPL3SA1_MPU, {CONFIG_OPL3SA1_MPU_BASE, CONFIG_OPL3SA1_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+#endif
#endif
#ifdef CONFIG_SOFTOSS
- {SNDCARD_SOFTOSS, {0, 0, -1, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_SOFTOSS, {0, 0, -1, -1}, SND_DEFAULT_ENABLE},
#endif
#ifdef CONFIG_SSCAPE
- {SNDCARD_SSCAPE, {SSCAPE_BASE, SSCAPE_IRQ, SSCAPE_DMA, -1}, SND_DEFAULT_ENABLE},
- {SNDCARD_SSCAPE_MSS, {SSCAPE_MSS_BASE, SSCAPE_MSS_IRQ, SSCAPE_DMA, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_SSCAPE, {CONFIG_SSCAPE_BASE, CONFIG_SSCAPE_IRQ, CONFIG_SSCAPE_DMA, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_SSCAPE_MSS, {CONFIG_SSCAPE_MSS_BASE, CONFIG_SSCAPE_MSS_IRQ, CONFIG_SSCAPE_DMA, -1}, SND_DEFAULT_ENABLE},
#endif
#ifdef CONFIG_MAD16
-#ifndef MAD16_DMA2
-#define MAD16_DMA2 MAD16_DMA
+#ifndef CONFIG_MAD16_DMA2
+#define CONFIG_MAD16_DMA2 CONFIG_MAD16_DMA
+#endif
+ {SNDCARD_MAD16, {CONFIG_MAD16_BASE, CONFIG_MAD16_IRQ, CONFIG_MAD16_DMA, CONFIG_MAD16_DMA2}, SND_DEFAULT_ENABLE},
+#ifdef CONFIG_MAD16_MPU_BASE
+ {SNDCARD_MAD16_MPU, {CONFIG_MAD16_MPU_BASE, CONFIG_MAD16_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
#endif
- {SNDCARD_MAD16, {MAD16_BASE, MAD16_IRQ, MAD16_DMA, MAD16_DMA2}, SND_DEFAULT_ENABLE},
-# ifdef MAD16_MPU_BASE
- {SNDCARD_MAD16_MPU, {MAD16_MPU_BASE, MAD16_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-# endif
#endif
#ifdef CONFIG_CS4232
-#ifndef CS4232_DMA2
-#define CS4232_DMA2 CS4232_DMA
+#ifndef CONFIG_CS4232_DMA2
+#define CONFIG_CS4232_DMA2 CONFIG_CS4232_DMA
+#endif
+#ifdef CONFIG_CS4232_MPU_BASE
+ {SNDCARD_CS4232_MPU, {CONFIG_CS4232_MPU_BASE, CONFIG_CS4232_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
#endif
-# ifdef CS4232_MPU_BASE
- {SNDCARD_CS4232_MPU, {CS4232_MPU_BASE, CS4232_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-# endif
- {SNDCARD_CS4232, {CS4232_BASE, CS4232_IRQ, CS4232_DMA, CS4232_DMA2}, SND_DEFAULT_ENABLE},
+ {SNDCARD_CS4232, {CONFIG_CS4232_BASE, CONFIG_CS4232_IRQ, CONFIG_CS4232_DMA, CONFIG_CS4232_DMA2}, SND_DEFAULT_ENABLE},
#endif
#ifdef CONFIG_MSS
-# ifndef MSS_DMA2
-# define MSS_DMA2 -1
-# endif
+#ifndef CONFIG_MSS_DMA2
+#define CONFIG_MSS_DMA2 -1
+#endif
-# ifdef DESKPROXL
- {SNDCARD_DESKPROXL, {MSS_BASE, MSS_IRQ, MSS_DMA, MSS_DMA2}, SND_DEFAULT_ENABLE},
-# else
- {SNDCARD_MSS, {MSS_BASE, MSS_IRQ, MSS_DMA, MSS_DMA2}, SND_DEFAULT_ENABLE},
-# endif
-# ifdef MSS2_BASE
- {SNDCARD_MSS, {MSS2_BASE, MSS2_IRQ, MSS2_DMA, MSS2_DMA2}, SND_DEFAULT_ENABLE},
-# endif
+#ifdef DESKPROXL
+ {SNDCARD_DESKPROXL, {CONFIG_MSS_BASE, CONFIG_MSS_IRQ, CONFIG_MSS_DMA, CONFIG_MSS_DMA2}, SND_DEFAULT_ENABLE},
+#else
+ {SNDCARD_MSS, {CONFIG_MSS_BASE, CONFIG_MSS_IRQ, CONFIG_MSS_DMA, CONFIG_MSS_DMA2}, SND_DEFAULT_ENABLE},
+#endif
+#ifdef MSS2_BASE
+ {SNDCARD_MSS, {MSS2_BASE, MSS2_IRQ, MSS2_DMA, MSS2_DMA2}, SND_DEFAULT_ENABLE},
+#endif
#endif
#ifdef CONFIG_PAS
- {SNDCARD_PAS, {PAS_BASE, PAS_IRQ, PAS_DMA, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_PAS, {CONFIG_PAS_BASE, CONFIG_PAS_IRQ, CONFIG_PAS_DMA, -1}, SND_DEFAULT_ENABLE},
#endif
#ifdef CONFIG_SB
-# ifndef SBC_DMA
-# define SBC_DMA 1
-# endif
-# ifndef SB_DMA2
-# define SB_DMA2 -1
-# endif
- {SNDCARD_SB, {SBC_BASE, SBC_IRQ, SBC_DMA, SB_DMA2}, SND_DEFAULT_ENABLE},
-# ifdef SB2_BASE
- {SNDCARD_SB, {SB2_BASE, SB2_IRQ, SB2_DMA, SB2_DMA2}, SND_DEFAULT_ENABLE},
-# endif
+#ifndef CONFIG_SB_DMA
+#define CONFIG_SB_DMA 1
+#endif
+#ifndef CONFIG_SB_DMA2
+#define CONFIG_SB_DMA2 -1
+#endif
+ {SNDCARD_SB, {CONFIG_SB_BASE, CONFIG_SB_IRQ, CONFIG_SB_DMA, CONFIG_SB_DMA2}, SND_DEFAULT_ENABLE},
+#ifdef SB2_BASE
+ {SNDCARD_SB, {SB2_BASE, SB2_IRQ, SB2_DMA, SB2_DMA2}, SND_DEFAULT_ENABLE},
+#endif
#endif
#if defined(CONFIG_MAUI)
- {SNDCARD_MAUI, {MAUI_BASE, MAUI_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_MAUI, {CONFIG_MAUI_BASE, CONFIG_MAUI_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
#endif
#if defined(CONFIG_MPU401) && defined(CONFIG_MIDI)
- {SNDCARD_MPU401, {MPU_BASE, MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_MPU401, {CONFIG_MPU_BASE, CONFIG_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
#ifdef MPU2_BASE
- {SNDCARD_MPU401, {MPU2_BASE, MPU2_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_MPU401, {MPU2_BASE, MPU2_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
#endif
#ifdef MPU3_BASE
- {SNDCARD_MPU401, {MPU3_BASE, MPU2_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_MPU401, {MPU3_BASE, MPU3_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
#endif
#endif
#if defined(CONFIG_UART6850) && defined(CONFIG_MIDI)
- {SNDCARD_UART6850, {U6850_BASE, U6850_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_UART6850, {CONFIG_U6850_BASE, CONFIG_U6850_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
#endif
#if defined(CONFIG_SB)
-#if defined(CONFIG_MIDI) && defined(SB_MPU_BASE)
- {SNDCARD_SB16MIDI,{SB_MPU_BASE, SB_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+#if defined(CONFIG_MIDI) && defined(CONFIG_SB_MPU_BASE)
+ {SNDCARD_SB16MIDI,{CONFIG_SB_MPU_BASE, CONFIG_SB_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
#endif
#endif
#ifdef CONFIG_GUS
-#ifndef GUS_DMA2
-#define GUS_DMA2 GUS_DMA
+#ifndef CONFIG_GUS_DMA2
+#define CONFIG_GUS_DMA2 CONFIG_GUS_DMA
#endif
#ifdef CONFIG_GUS16
- {SNDCARD_GUS16, {GUS16_BASE, GUS16_IRQ, GUS16_DMA, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_GUS16, {CONFIG_GUS16_BASE, CONFIG_GUS16_IRQ, CONFIG_GUS16_DMA, -1}, SND_DEFAULT_ENABLE},
#endif
- {SNDCARD_GUS, {GUS_BASE, GUS_IRQ, GUS_DMA, GUS_DMA2}, SND_DEFAULT_ENABLE},
+ {SNDCARD_GUS, {CONFIG_GUS_BASE, CONFIG_GUS_IRQ, CONFIG_GUS_DMA, CONFIG_GUS_DMA2}, SND_DEFAULT_ENABLE},
#endif
#if defined(CONFIG_YM3812)
- {SNDCARD_ADLIB, {FM_MONO, 0, 0, -1}, SND_DEFAULT_ENABLE},
+ {SNDCARD_ADLIB, {FM_MONO, 0, 0, -1}, SND_DEFAULT_ENABLE},
#endif
- {0, {0}, 0}
- };
- int num_sound_cards =
- sizeof(snd_installed_cards) / sizeof (struct card_info);
- static int max_sound_cards =
- sizeof(snd_installed_cards) / sizeof (struct card_info);
+#if defined(CONFIG_VMIDI) && defined(CONFIG_MIDI)
+ {SNDCARD_VMIDI, {0, 0, 0, -1}, SND_DEFAULT_ENABLE},
+#endif
+
+ {0, {0}, 0}
+};
+
+int num_sound_cards = sizeof(snd_installed_cards) / sizeof (struct card_info);
+static int max_sound_cards = sizeof(snd_installed_cards) / sizeof (struct card_info);
#else
- int num_sound_cards = 0;
- struct card_info snd_installed_cards[20] = {{0}};
- static int max_sound_cards = 20;
+int num_sound_cards = 0;
+struct card_info snd_installed_cards[20] = {{0}};
+static int max_sound_cards = 20;
#endif
#if defined(MODULE) || (!defined(linux) && !defined(_AIX))
- int trace_init = 0;
-# else
- int trace_init = 1;
-# endif
+int trace_init = 0;
+#else
+int trace_init = 1;
+#endif
#else
- extern struct audio_operations * audio_devs[MAX_AUDIO_DEV]; extern int num_audiodevs;
- extern struct mixer_operations * mixer_devs[MAX_MIXER_DEV]; extern int num_mixers;
- extern struct synth_operations * synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV]; extern int num_synths;
- extern struct midi_operations * midi_devs[MAX_MIDI_DEV]; extern int num_midis;
- extern struct sound_timer_operations * sound_timer_devs[MAX_TIMER_DEV]; extern int num_sound_timers;
-
- extern struct driver_info sound_drivers[];
- extern int num_sound_drivers;
- extern struct card_info snd_installed_cards[];
- extern int num_sound_cards;
-
- extern int trace_init;
+extern struct audio_operations * audio_devs[MAX_AUDIO_DEV]; extern int num_audiodevs;
+extern struct mixer_operations * mixer_devs[MAX_MIXER_DEV]; extern int num_mixers;
+extern struct synth_operations * synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV]; extern int num_synths;
+extern struct midi_operations * midi_devs[MAX_MIDI_DEV]; extern int num_midis;
+extern struct sound_timer_operations * sound_timer_devs[MAX_TIMER_DEV]; extern int num_sound_timers;
+
+extern struct driver_info sound_drivers[];
+extern int num_sound_drivers;
+extern struct card_info snd_installed_cards[];
+extern int num_sound_cards;
+
+extern int trace_init;
#endif /* _DEV_TABLE_C_ */
-
void sndtable_init(void);
int sndtable_get_cardcount (void);
struct address_info *sound_getconf(int card_type);
@@ -611,34 +654,20 @@ void sound_unload_driver(int type);
int sndtable_identify_card(char *name);
void sound_setup (char *str, int *ints);
-int sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan);
-void sound_free_dmap (int dev, struct dma_buffparms *dmap, int chn);
extern int sound_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc *info);
int sndtable_probe (int unit, struct address_info *hw_config);
int sndtable_init_card (int unit, struct address_info *hw_config);
int sndtable_start_card (int unit, struct address_info *hw_config);
void sound_timer_init (struct sound_lowlev_timer *t, char *name);
-int sound_start_dma ( int dev, struct dma_buffparms *dmap, int chan,
- unsigned long physaddr,
- int count, int dma_mode, int autoinit);
void sound_dma_intr (int dev, struct dma_buffparms *dmap, int chan);
#define AUDIO_DRIVER_VERSION 2
#define MIXER_DRIVER_VERSION 2
-int sound_install_audiodrv(int vers,
- char *name,
- struct audio_driver *driver,
- int driver_size,
- int flags,
- unsigned int format_mask,
- void *devc,
- int dma1,
- int dma2);
-int sound_install_mixer(int vers,
- char *name,
- struct mixer_operations *driver,
- int driver_size,
- void *devc);
+int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
+ int driver_size, int flags, unsigned int format_mask,
+ void *devc, int dma1, int dma2);
+int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
+ int driver_size, void *devc);
void sound_unload_audiodev(int dev);
void sound_unload_mixerdev(int dev);
diff --git a/drivers/sound/dmabuf.c b/drivers/sound/dmabuf.c
index ab5164ee4..151e20449 100644
--- a/drivers/sound/dmabuf.c
+++ b/drivers/sound/dmabuf.c
@@ -9,6 +9,15 @@
* 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 : moved several static variables into struct audio_operations
+ * (which is grossly misnamed btw.) because they have the same
+ * lifetime as the rest in there and dynamic allocation saves
+ * 12k or so
+ * Thomas Sailer : remove {in,out}_sleep_flag. It was used for the sleeper to
+ * determine if it was woken up by the expiring timeout or by
+ * an explicit wake_up. current->timeout can be used instead;
+ * if 0, the wakeup was due to the timeout.
*/
#include <linux/config.h>
@@ -17,35 +26,133 @@
#include "sound_config.h"
-#if defined(CONFIG_AUDIO) || defined(CONFIG_GUSHW)
+#if defined(CONFIG_AUDIO) || defined(CONFIG_GUS)
+
+
+static void dma_reset_output(int dev);
+static void dma_reset_input(int dev);
+static int local_start_dma(struct audio_operations *adev, unsigned long physaddr, int count, int dma_mode);
+
-static struct wait_queue *in_sleeper[MAX_AUDIO_DEV] =
-{NULL};
-static volatile struct snd_wait in_sleep_flag[MAX_AUDIO_DEV] =
+
+static int debugmem = 0; /* switched off by default */
+static int dma_buffsize = DSP_BUFFSIZE;
+
+static void dmabuf_set_timeout(struct dma_buffparms *dmap)
{
- {0}};
-static struct wait_queue *out_sleeper[MAX_AUDIO_DEV] =
-{NULL};
-static volatile struct snd_wait out_sleep_flag[MAX_AUDIO_DEV] =
+ unsigned long tmout;
+
+ tmout = (dmap->fragment_size * HZ) / dmap->data_rate;
+ tmout += HZ / 5; /* Some safety distance */
+ if (tmout < (HZ / 2))
+ tmout = HZ / 2;
+ if (tmout > 20 * HZ)
+ tmout = 20 * HZ;
+ current->timeout = jiffies + tmout;
+}
+
+static int sound_alloc_dmap(struct dma_buffparms *dmap)
{
- {0}};
+ char *start_addr, *end_addr;
+ int i, dma_pagesize;
+ int sz, size;
+
+ dmap->mapping_flags &= ~DMA_MAP_MAPPED;
+
+ if (dmap->raw_buf != NULL)
+ return 0; /* Already done */
+ if (dma_buffsize < 4096)
+ dma_buffsize = 4096;
+ dma_pagesize = (dmap->dma < 4) ? (64 * 1024) : (128 * 1024);
+ dmap->raw_buf = NULL;
+ dmap->buffsize = dma_buffsize;
+ if (dmap->buffsize > dma_pagesize)
+ dmap->buffsize = dma_pagesize;
+ start_addr = NULL;
+ /*
+ * Now loop until we get a free buffer. Try to get smaller buffer if
+ * it fails. Don't accept smaller than 8k buffer for performance
+ * reasons.
+ */
+ while (start_addr == NULL && dmap->buffsize > PAGE_SIZE) {
+ for (sz = 0, size = PAGE_SIZE; size < dmap->buffsize; sz++, size <<= 1);
+ dmap->buffsize = PAGE_SIZE * (1 << sz);
+ start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA, sz);
+ if (start_addr == NULL)
+ dmap->buffsize /= 2;
+ }
-static int ndmaps = 0;
+ if (start_addr == NULL) {
+ printk(KERN_WARNING "Sound error: Couldn't allocate DMA buffer\n");
+ return -ENOMEM;
+ } else {
+ /* make some checks */
+ end_addr = start_addr + dmap->buffsize - 1;
+
+ if (debugmem)
+ printk(KERN_DEBUG "sound: start 0x%lx, end 0x%lx\n", (long) start_addr, (long) end_addr);
+
+ /* now check if it fits into the same dma-pagesize */
+
+ if (((long) start_addr & ~(dma_pagesize - 1)) != ((long) end_addr & ~(dma_pagesize - 1))
+ || end_addr >= (char *) (MAX_DMA_ADDRESS)) {
+ printk(KERN_ERR "sound: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, dmap->buffsize);
+ return -EFAULT;
+ }
+ }
+ dmap->raw_buf = start_addr;
+ dmap->raw_buf_phys = virt_to_bus(start_addr);
-#define MAX_DMAP (MAX_AUDIO_DEV*2)
+ for (i = MAP_NR(start_addr); i <= MAP_NR(end_addr); i++)
+ set_bit(PG_reserved, &mem_map[i].flags);;
+ return 0;
+}
-static struct dma_buffparms dmaps[MAX_DMAP] =
+static void sound_free_dmap(struct dma_buffparms *dmap)
{
- {0}};
+ int sz, size, i;
+ unsigned long start_addr, end_addr;
+
+ 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);
-static void dma_reset_output(int dev);
-static void dma_reset_input(int dev);
-static int local_start_dma(int dev, unsigned long physaddr, int count, int dma_mode);
+ start_addr = (unsigned long) dmap->raw_buf;
+ end_addr = start_addr + dmap->buffsize;
-static void
-dma_init_buffers(int dev, struct dma_buffparms *dmap)
+ for (i = MAP_NR(start_addr); i <= MAP_NR(end_addr); i++)
+ clear_bit(PG_reserved, &mem_map[i].flags);;
+
+ free_pages((unsigned long) dmap->raw_buf, sz);
+ dmap->raw_buf = NULL;
+}
+
+
+/* Intel version !!!!!!!!! */
+
+static int sound_start_dma(struct dma_buffparms *dmap, unsigned long physaddr, int count, int dma_mode)
{
+ unsigned long flags;
+ int chan = dmap->dma;
+ /* printk( "Start DMA%d %d, %d\n", chan, (int)(physaddr-dmap->raw_buf_phys), count); */
+ save_flags(flags);
+ cli();
+ disable_dma(chan);
+ clear_dma_ff(chan);
+ set_dma_mode(chan, dma_mode);
+ set_dma_addr(chan, physaddr);
+ set_dma_count(chan, count);
+ enable_dma(chan);
+ restore_flags(flags);
+
+ return 0;
+}
+
+static void dma_init_buffers(struct dma_buffparms *dmap)
+{
dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
dmap->byte_counter = 0;
dmap->max_byte_counter = 8000 * 60 * 60;
@@ -61,30 +168,24 @@ dma_init_buffers(int dev, struct dma_buffparms *dmap)
dmap->flags = DMA_BUSY; /* Other flags off */
}
-static int
-open_dmap(int dev, int mode, struct dma_buffparms *dmap, int chan)
+static int open_dmap(struct audio_operations *adev, int mode, struct dma_buffparms *dmap)
{
+ int err;
+
if (dmap->flags & DMA_BUSY)
return -EBUSY;
+ if ((err = sound_alloc_dmap(dmap)) < 0)
+ return err;
- {
- int err;
-
- if ((err = sound_alloc_dmap(dev, dmap, chan)) < 0)
- return err;
+ if (dmap->raw_buf == NULL) {
+ printk(KERN_WARNING "Sound: DMA buffers not available\n");
+ return -ENOSPC; /* Memory allocation failed during boot */
}
-
- if (dmap->raw_buf == NULL)
- {
- printk("Sound: DMA buffers not available\n");
- return -ENOSPC; /* Memory allocation failed during boot */
- }
- if (sound_open_dma(chan, audio_devs[dev]->name))
- {
- printk("Unable to grab(2) DMA%d for the audio driver\n", chan);
- return -EBUSY;
- }
- dma_init_buffers(dev, dmap);
+ if (sound_open_dma(dmap->dma, adev->name)) {
+ printk(KERN_WARNING "Unable to grab(2) DMA%d for the audio driver\n", dmap->dma);
+ return -EBUSY;
+ }
+ dma_init_buffers(dmap);
dmap->open_mode = mode;
dmap->subdivision = dmap->underrun_count = 0;
dmap->fragment_size = 0;
@@ -95,54 +196,51 @@ open_dmap(int dev, int mode, struct dma_buffparms *dmap, int chan)
dmap->needs_reorg = 1;
dmap->audio_callback = NULL;
dmap->callback_parm = 0;
-
-
- if (dmap->dma_mode & DMODE_OUTPUT)
- {
- out_sleep_flag[dev].opts = WK_NONE;
- } else
- {
- in_sleep_flag[dev].opts = WK_NONE;
- }
-
return 0;
}
-static void
-close_dmap(int dev, struct dma_buffparms *dmap, int chan)
+static void close_dmap(struct audio_operations *adev, struct dma_buffparms *dmap)
{
- sound_close_dma(chan);
-
+ sound_close_dma(dmap->dma);
if (dmap->flags & DMA_BUSY)
dmap->dma_mode = DMODE_NONE;
dmap->flags &= ~DMA_BUSY;
-
disable_dma(dmap->dma);
}
-static unsigned int
-default_set_bits(int dev, unsigned int bits)
+static unsigned int default_set_bits(int dev, unsigned int bits)
{
- return audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_SETFMT, (caddr_t) & bits);
+ mm_segment_t fs = get_fs();
+
+ set_fs(get_ds());
+ audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_SETFMT, (caddr_t)&bits);
+ set_fs(fs);
+ return bits;
}
-static int
-default_set_speed(int dev, int speed)
+static int default_set_speed(int dev, int speed)
{
- return audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_SPEED, (caddr_t) & speed);
+ mm_segment_t fs = get_fs();
+
+ set_fs(get_ds());
+ audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_SPEED, (caddr_t)&speed);
+ set_fs(fs);
+ return speed;
}
-static short
-default_set_channels(int dev, short channels)
+static short default_set_channels(int dev, short channels)
{
- int c = channels;
+ int c = channels;
+ mm_segment_t fs = get_fs();
- return audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_CHANNELS, (caddr_t) & c);
+ set_fs(get_ds());
+ audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_CHANNELS, (caddr_t)&c);
+ set_fs(fs);
+ return c;
}
-static void
-check_driver(struct audio_driver *d)
+static void check_driver(struct audio_driver *d)
{
if (d->set_speed == NULL)
d->set_speed = default_set_speed;
@@ -152,85 +250,55 @@ check_driver(struct audio_driver *d)
d->set_channels = default_set_channels;
}
-int
-DMAbuf_open(int dev, int mode)
+int DMAbuf_open(int dev, int mode)
{
- int retval;
+ struct audio_operations *adev = audio_devs[dev];
+ int retval;
struct dma_buffparms *dmap_in = NULL;
struct dma_buffparms *dmap_out = NULL;
- if (dev >= num_audiodevs || audio_devs[dev] == NULL)
- {
+ if (!adev)
return -ENXIO;
- }
- if (!audio_devs[dev])
- {
- return -ENXIO;
- }
- if (!(audio_devs[dev]->flags & DMA_DUPLEX))
- {
- audio_devs[dev]->dmap_in = audio_devs[dev]->dmap_out;
- audio_devs[dev]->dmap_in->dma = audio_devs[dev]->dmap_out->dma;
- }
- check_driver(audio_devs[dev]->d);
-
- if ((retval = audio_devs[dev]->d->open(dev, mode)) < 0)
- return retval;
-
- dmap_out = audio_devs[dev]->dmap_out;
- dmap_in = audio_devs[dev]->dmap_in;
+ if (!(adev->flags & DMA_DUPLEX))
+ adev->dmap_in = adev->dmap_out;
+ check_driver(adev->d);
+ if ((retval = adev->d->open(dev, mode)) < 0)
+ return retval;
+ dmap_out = adev->dmap_out;
+ dmap_in = adev->dmap_in;
if (dmap_in == dmap_out)
- audio_devs[dev]->flags &= ~DMA_DUPLEX;
-
- if (mode & OPEN_WRITE)
- {
- if ((retval = open_dmap(dev, mode, dmap_out, audio_devs[dev]->dmap_out->dma)) < 0)
- {
- audio_devs[dev]->d->close(dev);
- return retval;
- }
- }
- audio_devs[dev]->enable_bits = mode;
-
- if (mode == OPEN_READ || (mode != OPEN_WRITE &&
- audio_devs[dev]->flags & DMA_DUPLEX))
- {
- if ((retval = open_dmap(dev, mode, dmap_in, audio_devs[dev]->dmap_in->dma)) < 0)
- {
- audio_devs[dev]->d->close(dev);
-
- if (mode & OPEN_WRITE)
- {
- close_dmap(dev, dmap_out, audio_devs[dev]->dmap_out->dma);
- }
- return retval;
- }
- }
- audio_devs[dev]->open_mode = mode;
- audio_devs[dev]->go = 1;
-
- if (mode & OPEN_READ)
- in_sleep_flag[dev].opts = WK_NONE;
-
- if (mode & OPEN_WRITE)
- out_sleep_flag[dev].opts = WK_NONE;
-
- audio_devs[dev]->d->set_bits(dev, 8);
- audio_devs[dev]->d->set_channels(dev, 1);
- audio_devs[dev]->d->set_speed(dev, DSP_DEFAULT_SPEED);
-
- if (audio_devs[dev]->dmap_out->dma_mode == DMODE_OUTPUT)
- {
- memset(audio_devs[dev]->dmap_out->raw_buf,
- audio_devs[dev]->dmap_out->neutral_byte,
- audio_devs[dev]->dmap_out->bytes_in_use);
- }
+ adev->flags &= ~DMA_DUPLEX;
+
+ if (mode & OPEN_WRITE) {
+ if ((retval = open_dmap(adev, mode, dmap_out)) < 0) {
+ adev->d->close(dev);
+ return retval;
+ }
+ }
+ adev->enable_bits = mode;
+
+ if (mode == OPEN_READ || (mode != OPEN_WRITE && adev->flags & DMA_DUPLEX)) {
+ if ((retval = open_dmap(adev, mode, dmap_in)) < 0) {
+ adev->d->close(dev);
+ if (mode & OPEN_WRITE)
+ close_dmap(adev, dmap_out);
+ return retval;
+ }
+ }
+ adev->open_mode = mode;
+ adev->go = 1;
+
+ adev->d->set_bits(dev, 8);
+ adev->d->set_channels(dev, 1);
+ adev->d->set_speed(dev, DSP_DEFAULT_SPEED);
+ if (adev->dmap_out->dma_mode == DMODE_OUTPUT)
+ memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte,
+ adev->dmap_out->bytes_in_use);
return 0;
}
-void
-DMAbuf_reset(int dev)
+void DMAbuf_reset(int dev)
{
if (audio_devs[dev]->open_mode & OPEN_WRITE)
dma_reset_output(dev);
@@ -239,493 +307,333 @@ DMAbuf_reset(int dev)
dma_reset_input(dev);
}
-static void
-dma_reset_output(int dev)
+static void dma_reset_output(int dev)
{
- unsigned long flags;
- int tmout;
-
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
-
+ struct audio_operations *adev = audio_devs[dev];
+ unsigned long flags;
+ struct dma_buffparms *dmap = adev->dmap_out;
if (!(dmap->flags & DMA_STARTED)) /* DMA is not active */
return;
-/*
- * First wait until the current fragment has been played completely
- */
+ /*
+ * First wait until the current fragment has been played completely
+ */
save_flags(flags);
cli();
+ adev->dmap_out->flags |= DMA_SYNCING;
+
+ adev->dmap_out->underrun_count = 0;
+ if (!signal_pending(current) && adev->dmap_out->qlen &&
+ adev->dmap_out->underrun_count == 0) {
+ dmabuf_set_timeout(dmap);
+ interruptible_sleep_on(&adev->out_sleeper);
+ current->timeout = 0;
+ }
+ adev->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
- tmout =
- (dmap->fragment_size * HZ) / dmap->data_rate;
-
- tmout += HZ / 5; /* Some safety distance */
-
- if (tmout < (HZ / 2))
- tmout = HZ / 2;
- if (tmout > 20 * HZ)
- tmout = 20 * HZ;
-
- audio_devs[dev]->dmap_out->flags |= DMA_SYNCING;
-
- audio_devs[dev]->dmap_out->underrun_count = 0;
- if (!signal_pending(current)
- && audio_devs[dev]->dmap_out->qlen
- && audio_devs[dev]->dmap_out->underrun_count == 0)
- {
-
- {
- unsigned long tlimit;
-
- if (tmout)
- current->timeout = tlimit = jiffies + (tmout);
- else
- tlimit = (unsigned long) -1;
- out_sleep_flag[dev].opts = WK_SLEEP;
- interruptible_sleep_on(&out_sleeper[dev]);
- if (!(out_sleep_flag[dev].opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- out_sleep_flag[dev].opts |= WK_TIMEOUT;
- }
- out_sleep_flag[dev].opts &= ~WK_SLEEP;
- };
- }
- audio_devs[dev]->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
-
-/*
- * Finally shut the device off
- */
-
- if (!(audio_devs[dev]->flags & DMA_DUPLEX) ||
- !audio_devs[dev]->d->halt_output)
- audio_devs[dev]->d->halt_io(dev);
+ /*
+ * Finally shut the device off
+ */
+ if (!(adev->flags & DMA_DUPLEX) || !adev->d->halt_output)
+ adev->d->halt_io(dev);
else
- audio_devs[dev]->d->halt_output(dev);
- audio_devs[dev]->dmap_out->flags &= ~DMA_STARTED;
- restore_flags(flags);
-
+ adev->d->halt_output(dev);
+ adev->dmap_out->flags &= ~DMA_STARTED;
clear_dma_ff(dmap->dma);
disable_dma(dmap->dma);
+ restore_flags(flags);
dmap->byte_counter = 0;
- reorganize_buffers(dev, audio_devs[dev]->dmap_out, 0);
+ reorganize_buffers(dev, adev->dmap_out, 0);
dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
}
-static void
-dma_reset_input(int dev)
+static void dma_reset_input(int dev)
{
- unsigned long flags;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
+ struct audio_operations *adev = audio_devs[dev];
+ unsigned long flags;
+ struct dma_buffparms *dmap = adev->dmap_in;
save_flags(flags);
cli();
- if (!(audio_devs[dev]->flags & DMA_DUPLEX) ||
- !audio_devs[dev]->d->halt_input)
- audio_devs[dev]->d->halt_io(dev);
+ if (!(adev->flags & DMA_DUPLEX) || !adev->d->halt_input)
+ adev->d->halt_io(dev);
else
- audio_devs[dev]->d->halt_input(dev);
- audio_devs[dev]->dmap_in->flags &= ~DMA_STARTED;
+ adev->d->halt_input(dev);
+ adev->dmap_in->flags &= ~DMA_STARTED;
restore_flags(flags);
dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
dmap->byte_counter = 0;
- reorganize_buffers(dev, audio_devs[dev]->dmap_in, 1);
+ reorganize_buffers(dev, adev->dmap_in, 1);
}
-void
-DMAbuf_launch_output(int dev, struct dma_buffparms *dmap)
+void DMAbuf_launch_output(int dev, struct dma_buffparms *dmap)
{
- if (!((audio_devs[dev]->enable_bits * audio_devs[dev]->go) & PCM_ENABLE_OUTPUT))
- return; /* Don't start DMA yet */
+ struct audio_operations *adev = audio_devs[dev];
+ if (!((adev->enable_bits * adev->go) & PCM_ENABLE_OUTPUT))
+ return; /* Don't start DMA yet */
dmap->dma_mode = DMODE_OUTPUT;
- if (!(dmap->flags & DMA_ACTIVE) || !(audio_devs[dev]->flags & DMA_AUTOMODE) || dmap->flags & DMA_NODMA)
- {
- if (!(dmap->flags & DMA_STARTED))
- {
- reorganize_buffers(dev, dmap, 0);
-
- if (audio_devs[dev]->d->prepare_for_output(dev,
- dmap->fragment_size, dmap->nbufs))
- return;
-
- if (!(dmap->flags & DMA_NODMA))
- {
- local_start_dma(dev, dmap->raw_buf_phys, dmap->bytes_in_use,
- DMA_MODE_WRITE);
- }
- dmap->flags |= DMA_STARTED;
- }
- if (dmap->counts[dmap->qhead] == 0)
- dmap->counts[dmap->qhead] = dmap->fragment_size;
-
- dmap->dma_mode = DMODE_OUTPUT;
- audio_devs[dev]->d->output_block(dev, dmap->raw_buf_phys +
- dmap->qhead * dmap->fragment_size,
- dmap->counts[dmap->qhead], 1);
- if (audio_devs[dev]->d->trigger)
- audio_devs[dev]->d->trigger(dev,
- audio_devs[dev]->enable_bits * audio_devs[dev]->go);
- }
+ if (!(dmap->flags & DMA_ACTIVE) || !(adev->flags & DMA_AUTOMODE) || dmap->flags & DMA_NODMA) {
+ if (!(dmap->flags & DMA_STARTED)) {
+ reorganize_buffers(dev, dmap, 0);
+ if (adev->d->prepare_for_output(dev, dmap->fragment_size, dmap->nbufs))
+ return;
+ if (!(dmap->flags & DMA_NODMA))
+ local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use,DMA_MODE_WRITE);
+ dmap->flags |= DMA_STARTED;
+ }
+ if (dmap->counts[dmap->qhead] == 0)
+ dmap->counts[dmap->qhead] = dmap->fragment_size;
+ dmap->dma_mode = DMODE_OUTPUT;
+ adev->d->output_block(dev, dmap->raw_buf_phys + dmap->qhead * dmap->fragment_size,
+ dmap->counts[dmap->qhead], 1);
+ if (adev->d->trigger)
+ adev->d->trigger(dev,adev->enable_bits * adev->go);
+ }
dmap->flags |= DMA_ACTIVE;
}
-int
-DMAbuf_sync(int dev)
+int DMAbuf_sync(int dev)
{
- unsigned long flags;
- int tmout, n = 0;
+ struct audio_operations *adev = audio_devs[dev];
+ unsigned long flags;
+ int n = 0;
+ struct dma_buffparms *dmap;
- if (!audio_devs[dev]->go && (!audio_devs[dev]->enable_bits & PCM_ENABLE_OUTPUT))
+ if (!adev->go && (!adev->enable_bits & PCM_ENABLE_OUTPUT))
return 0;
- if (audio_devs[dev]->dmap_out->dma_mode == DMODE_OUTPUT)
- {
-
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
-
- save_flags(flags);
- cli();
-
- tmout =
- (dmap->fragment_size * HZ) / dmap->data_rate;
-
- tmout += HZ / 5; /* Some safety distance */
-
- if (tmout < (HZ / 2))
- tmout = HZ / 2;
- if (tmout > 20 * HZ)
- tmout = 20 * HZ;
-
- ;
- if (dmap->qlen > 0)
- if (!(dmap->flags & DMA_ACTIVE))
- DMAbuf_launch_output(dev, dmap);
- ;
-
- audio_devs[dev]->dmap_out->flags |= DMA_SYNCING;
-
- audio_devs[dev]->dmap_out->underrun_count = 0;
- while (!signal_pending(current)
- && n++ <= audio_devs[dev]->dmap_out->nbufs
- && audio_devs[dev]->dmap_out->qlen
- && audio_devs[dev]->dmap_out->underrun_count == 0)
- {
-
- {
- unsigned long tlimit;
-
- if (tmout)
- current->timeout = tlimit = jiffies + (tmout);
- else
- tlimit = (unsigned long) -1;
- out_sleep_flag[dev].opts = WK_SLEEP;
- interruptible_sleep_on(&out_sleeper[dev]);
- if (!(out_sleep_flag[dev].opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- out_sleep_flag[dev].opts |= WK_TIMEOUT;
- }
- out_sleep_flag[dev].opts &= ~WK_SLEEP;
- };
- if ((out_sleep_flag[dev].opts & WK_TIMEOUT))
- {
- audio_devs[dev]->dmap_out->flags &= ~DMA_SYNCING;
- restore_flags(flags);
- return audio_devs[dev]->dmap_out->qlen;
- }
- }
- audio_devs[dev]->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
- restore_flags(flags);
- /*
- * Some devices such as GUS have huge amount of on board RAM for the
- * audio data. We have to wait until the device has finished playing.
- */
-
- save_flags(flags);
- cli();
- if (audio_devs[dev]->d->local_qlen) /* Device has hidden buffers */
- {
- while (!signal_pending(current)
- && audio_devs[dev]->d->local_qlen(dev))
- {
-
- {
- unsigned long tlimit;
-
- if (tmout)
- current->timeout = tlimit = jiffies + (tmout);
- else
- tlimit = (unsigned long) -1;
- out_sleep_flag[dev].opts = WK_SLEEP;
- interruptible_sleep_on(&out_sleeper[dev]);
- if (!(out_sleep_flag[dev].opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- out_sleep_flag[dev].opts |= WK_TIMEOUT;
- }
- out_sleep_flag[dev].opts &= ~WK_SLEEP;
- };
- }
- }
- restore_flags(flags);
- }
- audio_devs[dev]->dmap_out->dma_mode = DMODE_NONE;
- return audio_devs[dev]->dmap_out->qlen;
+ if (adev->dmap_out->dma_mode == DMODE_OUTPUT) {
+ dmap = adev->dmap_out;
+ save_flags(flags);
+ cli();
+ if (dmap->qlen > 0 && !(dmap->flags & DMA_ACTIVE))
+ DMAbuf_launch_output(dev, dmap);
+ adev->dmap_out->flags |= DMA_SYNCING;
+ adev->dmap_out->underrun_count = 0;
+ while (!signal_pending(current) && n++ <= adev->dmap_out->nbufs &&
+ adev->dmap_out->qlen && adev->dmap_out->underrun_count == 0) {
+ dmabuf_set_timeout(dmap);
+ interruptible_sleep_on(&adev->out_sleeper);
+ if (!current->timeout) {
+ adev->dmap_out->flags &= ~DMA_SYNCING;
+ restore_flags(flags);
+ return adev->dmap_out->qlen;
+ }
+ current->timeout = 0;
+ }
+ adev->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
+ restore_flags(flags);
+
+ /*
+ * Some devices such as GUS have huge amount of on board RAM for the
+ * audio data. We have to wait until the device has finished playing.
+ */
+
+ save_flags(flags);
+ cli();
+ if (adev->d->local_qlen) { /* Device has hidden buffers */
+ while (!signal_pending(current) && adev->d->local_qlen(dev)) {
+ dmabuf_set_timeout(dmap);
+ interruptible_sleep_on(&adev->out_sleeper);
+ current->timeout = 0;
+ }
+ }
+ restore_flags(flags);
+ }
+ adev->dmap_out->dma_mode = DMODE_NONE;
+ return adev->dmap_out->qlen;
}
-int
-DMAbuf_release(int dev, int mode)
+int DMAbuf_release(int dev, int mode)
{
- unsigned long flags;
-
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- audio_devs[dev]->dmap_out->closing = 1;
- if (audio_devs[dev]->open_mode & OPEN_READ)
- audio_devs[dev]->dmap_in->closing = 1;
-
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- if (!(audio_devs[dev]->dmap_in->mapping_flags & DMA_MAP_MAPPED))
- if (!signal_pending(current)
- && (audio_devs[dev]->dmap_out->dma_mode == DMODE_OUTPUT))
- {
- DMAbuf_sync(dev);
- }
- if (audio_devs[dev]->dmap_out->dma_mode == DMODE_OUTPUT)
- {
- memset(audio_devs[dev]->dmap_out->raw_buf,
- audio_devs[dev]->dmap_out->neutral_byte,
- audio_devs[dev]->dmap_out->bytes_in_use);
- }
+ struct audio_operations *adev = audio_devs[dev];
+ unsigned long flags;
+
+ if (adev->open_mode & OPEN_WRITE)
+ adev->dmap_out->closing = 1;
+ if (adev->open_mode & OPEN_READ)
+ adev->dmap_in->closing = 1;
+
+ if (adev->open_mode & OPEN_WRITE)
+ if (!(adev->dmap_in->mapping_flags & DMA_MAP_MAPPED))
+ if (!signal_pending(current) && (adev->dmap_out->dma_mode == DMODE_OUTPUT))
+ DMAbuf_sync(dev);
+ if (adev->dmap_out->dma_mode == DMODE_OUTPUT)
+ memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte, adev->dmap_out->bytes_in_use);
save_flags(flags);
cli();
DMAbuf_reset(dev);
- audio_devs[dev]->d->close(dev);
+ adev->d->close(dev);
- if (audio_devs[dev]->open_mode & OPEN_WRITE)
- close_dmap(dev, audio_devs[dev]->dmap_out, audio_devs[dev]->dmap_out->dma);
-
- if (audio_devs[dev]->open_mode == OPEN_READ ||
- (audio_devs[dev]->open_mode != OPEN_WRITE &&
- audio_devs[dev]->flags & DMA_DUPLEX))
- close_dmap(dev, audio_devs[dev]->dmap_in, audio_devs[dev]->dmap_in->dma);
- audio_devs[dev]->open_mode = 0;
+ if (adev->open_mode & OPEN_WRITE)
+ close_dmap(adev, adev->dmap_out);
+ if (adev->open_mode == OPEN_READ ||
+ (adev->open_mode != OPEN_WRITE &&
+ adev->flags & DMA_DUPLEX))
+ close_dmap(adev, adev->dmap_in);
+ adev->open_mode = 0;
restore_flags(flags);
-
return 0;
}
-int
-DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
+int DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
{
- if (!(audio_devs[dev]->open_mode & OPEN_READ))
- return 0;
+ struct audio_operations *adev = audio_devs[dev];
+ int err;
- if (!(audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT))
+ if (!(adev->open_mode & OPEN_READ))
return 0;
-
- if (dmap->dma_mode == DMODE_OUTPUT) /* Direction change */
- {
- DMAbuf_sync(dev);
- DMAbuf_reset(dev);
- dmap->dma_mode = DMODE_NONE;
- }
- if (!dmap->dma_mode)
- {
- int err;
-
- reorganize_buffers(dev, dmap, 1);
- if ((err = audio_devs[dev]->d->prepare_for_input(dev,
- dmap->fragment_size, dmap->nbufs)) < 0)
- {
- return err;
- }
- dmap->dma_mode = DMODE_INPUT;
- }
- if (!(dmap->flags & DMA_ACTIVE))
- {
- if (dmap->needs_reorg)
- reorganize_buffers(dev, dmap, 0);
- local_start_dma(dev, dmap->raw_buf_phys, dmap->bytes_in_use,
- DMA_MODE_READ);
- audio_devs[dev]->d->start_input(dev, dmap->raw_buf_phys +
- dmap->qtail * dmap->fragment_size,
- dmap->fragment_size, 0);
- dmap->flags |= DMA_ACTIVE;
- if (audio_devs[dev]->d->trigger)
- audio_devs[dev]->d->trigger(dev,
- audio_devs[dev]->enable_bits * audio_devs[dev]->go);
- }
+ if (!(adev->enable_bits & PCM_ENABLE_INPUT))
+ return 0;
+ if (dmap->dma_mode == DMODE_OUTPUT) { /* Direction change */
+ DMAbuf_sync(dev);
+ DMAbuf_reset(dev);
+ dmap->dma_mode = DMODE_NONE;
+ }
+ if (!dmap->dma_mode) {
+ reorganize_buffers(dev, dmap, 1);
+ if ((err = adev->d->prepare_for_input(dev,
+ dmap->fragment_size, dmap->nbufs)) < 0)
+ return err;
+ dmap->dma_mode = DMODE_INPUT;
+ }
+ if (!(dmap->flags & DMA_ACTIVE)) {
+ if (dmap->needs_reorg)
+ reorganize_buffers(dev, dmap, 0);
+ local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use, DMA_MODE_READ);
+ adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size,
+ dmap->fragment_size, 0);
+ dmap->flags |= DMA_ACTIVE;
+ if (adev->d->trigger)
+ adev->d->trigger(dev, adev->enable_bits * adev->go);
+ }
return 0;
}
-int
-DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
+int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
{
- unsigned long flags;
- int err = 0, n = 0;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
+ struct audio_operations *adev = audio_devs[dev];
+ unsigned long flags;
+ int err = 0, n = 0;
+ struct dma_buffparms *dmap = adev->dmap_in;
+ int go;
- if (!(audio_devs[dev]->open_mode & OPEN_READ))
+ if (!(adev->open_mode & OPEN_READ))
return -EIO;
if (dmap->needs_reorg)
reorganize_buffers(dev, dmap, 0);
-
save_flags(flags);
cli();
- if (audio_devs[dev]->dmap_in->mapping_flags & DMA_MAP_MAPPED)
- {
- printk("Sound: Can't read from mmapped device (1)\n");
+ if (adev->dmap_in->mapping_flags & DMA_MAP_MAPPED) {
+/* printk(KERN_WARNING "Sound: Can't read from mmapped device (1)\n");*/
restore_flags(flags);
return -EINVAL;
- } else
- while (dmap->qlen <= 0 && n++ < 10)
- {
- int tmout;
-
- if (!(audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT) ||
- !audio_devs[dev]->go)
- {
- restore_flags(flags);
- return -EAGAIN;
- }
- if ((err = DMAbuf_activate_recording(dev, dmap)) < 0)
- {
- restore_flags(flags);
- return err;
- }
- /* Wait for the next block */
-
- if (dontblock)
- {
- restore_flags(flags);
- return -EAGAIN;
- }
- if (!audio_devs[dev]->go)
- tmout = 0;
- else
- {
- tmout =
- (dmap->fragment_size * HZ) / dmap->data_rate;
-
- tmout += HZ / 5; /* Some safety distance */
-
- if (tmout < (HZ / 2))
- tmout = HZ / 2;
- if (tmout > 20 * HZ)
- tmout = 20 * HZ;
- }
-
-
- {
- unsigned long tlimit;
-
- if (tmout)
- current->timeout = tlimit = jiffies + (tmout);
- else
- tlimit = (unsigned long) -1;
- in_sleep_flag[dev].opts = WK_SLEEP;
- interruptible_sleep_on(&in_sleeper[dev]);
- if (!(in_sleep_flag[dev].opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- in_sleep_flag[dev].opts |= WK_TIMEOUT;
- }
- in_sleep_flag[dev].opts &= ~WK_SLEEP;
- };
- if ((in_sleep_flag[dev].opts & WK_TIMEOUT))
- {
- err = -EIO;
- printk("Sound: DMA (input) timed out - IRQ/DRQ config error?\n");
- dma_reset_input(dev);
- ;
- } else
- err = -EINTR;
- }
+ } else while (dmap->qlen <= 0 && n++ < 10) {
+ if (!(adev->enable_bits & PCM_ENABLE_INPUT) || !adev->go) {
+ restore_flags(flags);
+ return -EAGAIN;
+ }
+ if ((err = DMAbuf_activate_recording(dev, dmap)) < 0) {
+ restore_flags(flags);
+ return err;
+ }
+ /* Wait for the next block */
+
+ if (dontblock) {
+ restore_flags(flags);
+ return -EAGAIN;
+ }
+ if (!(go = adev->go))
+ current->timeout = 0;
+ else
+ dmabuf_set_timeout(dmap);
+ interruptible_sleep_on(&adev->in_sleeper);
+ if (go && !current->timeout) {
+ /* FIXME: include device name */
+ err = -EIO;
+ printk(KERN_WARNING "Sound: DMA (input) timed out - IRQ/DRQ config error?\n");
+ dma_reset_input(dev);
+ } else
+ err = -EINTR;
+ current->timeout = 0;
+ }
restore_flags(flags);
if (dmap->qlen <= 0)
- {
- if (err == 0)
- err = -EINTR;
- return err;
- }
+ return err ? err : -EINTR;
*buf = &dmap->raw_buf[dmap->qhead * dmap->fragment_size + dmap->counts[dmap->qhead]];
*len = dmap->fragment_size - dmap->counts[dmap->qhead];
return dmap->qhead;
}
-int
-DMAbuf_rmchars(int dev, int buff_no, int c)
+int DMAbuf_rmchars(int dev, int buff_no, int c)
{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
-
- int p = dmap->counts[dmap->qhead] + c;
+ struct audio_operations *adev = audio_devs[dev];
+ struct dma_buffparms *dmap = adev->dmap_in;
+ int p = dmap->counts[dmap->qhead] + c;
if (dmap->mapping_flags & DMA_MAP_MAPPED)
- {
- printk("Sound: Can't read from mmapped device (2)\n");
- return -EINVAL;
- } else if (dmap->qlen <= 0)
+ {
+/* printk("Sound: Can't read from mmapped device (2)\n");*/
+ return -EINVAL;
+ }
+ else if (dmap->qlen <= 0)
return -EIO;
- else if (p >= dmap->fragment_size)
- { /* This buffer is completely empty */
- dmap->counts[dmap->qhead] = 0;
- dmap->qlen--;
- dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
- } else
- dmap->counts[dmap->qhead] = p;
+ else if (p >= dmap->fragment_size) { /* This buffer is completely empty */
+ dmap->counts[dmap->qhead] = 0;
+ dmap->qlen--;
+ dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
+ }
+ else dmap->counts[dmap->qhead] = p;
return 0;
}
-int
-DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction)
+int DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction)
{
-/*
- * Try to approximate the active byte position of the DMA pointer within the
- * buffer area as well as possible.
- */
- int pos;
- unsigned long flags;
+ /*
+ * Try to approximate the active byte position of the DMA pointer within the
+ * buffer area as well as possible.
+ */
+
+ int pos;
+ unsigned long flags;
save_flags(flags);
cli();
if (!(dmap->flags & DMA_ACTIVE))
pos = 0;
- else
- {
- int chan = dmap->dma;
-
- clear_dma_ff(chan);
- disable_dma(dmap->dma);
- pos = get_dma_residue(chan);
- pos = dmap->bytes_in_use - pos;
-
- if (!(dmap->mapping_flags & DMA_MAP_MAPPED))
- if (direction == DMODE_OUTPUT)
- {
- if (dmap->qhead == 0)
- if (pos > dmap->fragment_size)
- pos = 0;
- } else
- {
- if (dmap->qtail == 0)
- if (pos > dmap->fragment_size)
- pos = 0;
- }
- if (pos < 0)
- pos = 0;
- if (pos >= dmap->bytes_in_use)
- pos = 0;
- enable_dma(dmap->dma);
- }
+ else {
+ int chan = dmap->dma;
+ clear_dma_ff(chan);
+ disable_dma(dmap->dma);
+ pos = get_dma_residue(chan);
+ pos = dmap->bytes_in_use - pos;
+
+ if (!(dmap->mapping_flags & DMA_MAP_MAPPED)) {
+ if (direction == DMODE_OUTPUT) {
+ if (dmap->qhead == 0)
+ if (pos > dmap->fragment_size)
+ pos = 0;
+ } else {
+ if (dmap->qtail == 0)
+ if (pos > dmap->fragment_size)
+ pos = 0;
+ }
+ }
+ if (pos < 0)
+ pos = 0;
+ if (pos >= dmap->bytes_in_use)
+ pos = 0;
+ enable_dma(dmap->dma);
+ }
restore_flags(flags);
/* printk( "%04x ", pos); */
@@ -733,42 +641,37 @@ DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction)
}
/*
- * DMAbuf_start_devices() is called by the /dev/music driver to start
- * one or more audio devices at desired moment.
+ * DMAbuf_start_devices() is called by the /dev/music driver to start
+ * one or more audio devices at desired moment.
*/
-static void
-DMAbuf_start_device(int dev)
-{
- if (audio_devs[dev]->open_mode != 0)
- if (!audio_devs[dev]->go)
- {
- /* OK to start the device */
- audio_devs[dev]->go = 1;
-
- if (audio_devs[dev]->d->trigger)
- audio_devs[dev]->d->trigger(dev,
- audio_devs[dev]->enable_bits * audio_devs[dev]->go);
- }
-}
-void
-DMAbuf_start_devices(unsigned int devmask)
+void DMAbuf_start_devices(unsigned int devmask)
{
- int dev;
-
- for (dev = 0; dev < num_audiodevs; dev++)
- if ((devmask & (1 << dev)) && audio_devs[dev] != NULL)
- DMAbuf_start_device(dev);
+ struct audio_operations *adev;
+ int dev;
+
+ for (dev = 0; dev < num_audiodevs; dev++) {
+ if (!(devmask & (1 << dev)))
+ continue;
+ if (!(adev = audio_devs[dev]))
+ continue;
+ if (adev->open_mode == 0)
+ continue;
+ if (adev->go)
+ continue;
+ /* OK to start the device */
+ adev->go = 1;
+ if (adev->d->trigger)
+ adev->d->trigger(dev,adev->enable_bits * adev->go);
+ }
}
-int
-DMAbuf_space_in_queue(int dev)
+int DMAbuf_space_in_queue(int dev)
{
- int len, max, tmp;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
-
- int lim = dmap->nbufs;
-
+ struct audio_operations *adev = audio_devs[dev];
+ int len, max, tmp;
+ struct dma_buffparms *dmap = adev->dmap_out;
+ int lim = dmap->nbufs;
if (lim < 2)
lim = 2;
@@ -777,8 +680,8 @@ DMAbuf_space_in_queue(int dev)
return 0;
/*
- * Verify that there are no more pending buffers than the limit
- * defined by the process.
+ * Verify that there are no more pending buffers than the limit
+ * defined by the process.
*/
max = dmap->max_fragments;
@@ -786,15 +689,12 @@ DMAbuf_space_in_queue(int dev)
max = lim;
len = dmap->qlen;
- if (audio_devs[dev]->d->local_qlen)
- {
- tmp = audio_devs[dev]->d->local_qlen(dev);
- if (tmp && len)
- tmp--; /*
- * This buffer has been counted twice
- */
- len += tmp;
- }
+ if (adev->d->local_qlen) {
+ tmp = adev->d->local_qlen(dev);
+ if (tmp && len)
+ tmp--; /* This buffer has been counted twice */
+ len += tmp;
+ }
if (dmap->byte_counter % dmap->fragment_size) /* There is a partial fragment */
len = len + 1;
@@ -803,87 +703,53 @@ DMAbuf_space_in_queue(int dev)
return max - len;
}
-static int
-output_sleep(int dev, int dontblock)
+static int output_sleep(int dev, int dontblock)
{
- int tmout;
- int err = 0;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
+ struct audio_operations *adev = audio_devs[dev];
+ int err = 0;
+ struct dma_buffparms *dmap = adev->dmap_out;
+ int timeout;
if (dontblock)
- {
- return -EAGAIN;
- }
- if (!(audio_devs[dev]->enable_bits & PCM_ENABLE_OUTPUT))
- {
- return -EAGAIN;
- }
+ return -EAGAIN;
+ if (!(adev->enable_bits & PCM_ENABLE_OUTPUT))
+ return -EAGAIN;
+
/*
* Wait for free space
*/
- if (!audio_devs[dev]->go || dmap->flags & DMA_NOTIMEOUT)
- tmout = 0;
- else
- {
- tmout =
- (dmap->fragment_size * HZ) / dmap->data_rate;
-
- tmout += HZ / 5; /* Some safety distance */
-
- if (tmout < (HZ / 2))
- tmout = HZ / 2;
- if (tmout > 20 * HZ)
- tmout = 20 * HZ;
- }
-
if (signal_pending(current))
return -EIO;
-
-
- {
- unsigned long tlimit;
-
- if (tmout)
- current->timeout = tlimit = jiffies + (tmout);
- else
- tlimit = (unsigned long) -1;
- out_sleep_flag[dev].opts = WK_SLEEP;
- interruptible_sleep_on(&out_sleeper[dev]);
- if (!(out_sleep_flag[dev].opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- out_sleep_flag[dev].opts |= WK_TIMEOUT;
- }
- out_sleep_flag[dev].opts &= ~WK_SLEEP;
- };
- if ((out_sleep_flag[dev].opts & WK_TIMEOUT))
- {
- printk("Sound: DMA (output) timed out - IRQ/DRQ config error?\n");
- ;
- dma_reset_output(dev);
- } else if (signal_pending(current))
- {
- err = -EINTR;
- }
+ timeout = (adev->go && !(dmap->flags & DMA_NOTIMEOUT));
+ if (timeout)
+ dmabuf_set_timeout(dmap);
+ else
+ current->timeout = 0;
+ interruptible_sleep_on(&adev->out_sleeper);
+ if (timeout && !current->timeout) {
+ printk(KERN_WARNING "Sound: DMA (output) timed out - IRQ/DRQ config error?\n");
+ dma_reset_output(dev);
+ } else {
+ current->timeout = 0;
+ if (signal_pending(current))
+ err = -EINTR;
+ }
return err;
}
-static int
-find_output_space(int dev, char **buf, int *size)
+static int find_output_space(int dev, char **buf, int *size)
{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
- unsigned long flags;
- unsigned long active_offs;
- long len, offs;
- int maxfrags;
- int occupied_bytes = (dmap->user_counter % dmap->fragment_size);
+ struct audio_operations *adev = audio_devs[dev];
+ struct dma_buffparms *dmap = adev->dmap_out;
+ unsigned long flags;
+ unsigned long active_offs;
+ long len, offs;
+ int maxfrags;
+ int occupied_bytes = (dmap->user_counter % dmap->fragment_size);
*buf = dmap->raw_buf;
-
if (!(maxfrags = DMAbuf_space_in_queue(dev)) && !occupied_bytes)
- {
- return 0;
- }
+ return 0;
save_flags(flags);
cli();
@@ -898,260 +764,183 @@ find_output_space(int dev, char **buf, int *size)
#endif
offs = (dmap->user_counter % dmap->bytes_in_use) & ~SAMPLE_ROUNDUP;
- if (offs < 0 || offs >= dmap->bytes_in_use)
- {
- printk("OSS: Got unexpected offs %ld. Giving up.\n", offs);
- printk("Counter = %ld, bytes=%d\n", dmap->user_counter, dmap->bytes_in_use);
- return 0;
- }
+ if (offs < 0 || offs >= dmap->bytes_in_use) {
+ printk(KERN_ERR "Sound: Got unexpected offs %ld. Giving up.\n", offs);
+ printk("Counter = %ld, bytes=%d\n", dmap->user_counter, dmap->bytes_in_use);
+ return 0;
+ }
*buf = dmap->raw_buf + offs;
len = active_offs + dmap->bytes_in_use - dmap->user_counter; /* Number of unused bytes in buffer */
if ((offs + len) > dmap->bytes_in_use)
- {
- len = dmap->bytes_in_use - offs;
- }
- if (len < 0)
- {
- restore_flags(flags);
- return 0;
- }
+ len = dmap->bytes_in_use - offs;
+ if (len < 0) {
+ restore_flags(flags);
+ return 0;
+ }
if (len > ((maxfrags * dmap->fragment_size) - occupied_bytes))
- {
- len = (maxfrags * dmap->fragment_size) - occupied_bytes;
- }
+ len = (maxfrags * dmap->fragment_size) - occupied_bytes;
*size = len & ~SAMPLE_ROUNDUP;
-
restore_flags(flags);
return (*size > 0);
}
-int
-DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock)
+int DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock)
{
- unsigned long flags;
- int err = -EIO;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
+ struct audio_operations *adev = audio_devs[dev];
+ unsigned long flags;
+ int err = -EIO;
+ struct dma_buffparms *dmap = adev->dmap_out;
if (dmap->needs_reorg)
reorganize_buffers(dev, dmap, 0);
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- {
- printk("Sound: Can't write to mmapped device (3)\n");
- return -EINVAL;
- }
- if (dmap->dma_mode == DMODE_INPUT) /* Direction change */
- {
- DMAbuf_reset(dev);
- dmap->dma_mode = DMODE_NONE;
- }
+ if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+/* printk(KERN_DEBUG "Sound: Can't write to mmapped device (3)\n");*/
+ return -EINVAL;
+ }
+ if (dmap->dma_mode == DMODE_INPUT) { /* Direction change */
+ DMAbuf_reset(dev);
+ dmap->dma_mode = DMODE_NONE;
+ }
dmap->dma_mode = DMODE_OUTPUT;
save_flags(flags);
cli();
-
- while (find_output_space(dev, buf, size) <= 0)
- {
- if ((err = output_sleep(dev, dontblock)) < 0)
- {
- restore_flags(flags);
- return err;
- }
- }
-
+ while (find_output_space(dev, buf, size) <= 0) {
+ if ((err = output_sleep(dev, dontblock)) < 0) {
+ restore_flags(flags);
+ return err;
+ }
+ }
restore_flags(flags);
return 0;
}
-int
-DMAbuf_move_wrpointer(int dev, int l)
+int DMAbuf_move_wrpointer(int dev, int l)
{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
- unsigned long ptr = (dmap->user_counter / dmap->fragment_size)
- * dmap->fragment_size;
-
- unsigned long end_ptr, p;
- int post = (dmap->flags & DMA_POST);
-
- ;
+ struct audio_operations *adev = audio_devs[dev];
+ struct dma_buffparms *dmap = adev->dmap_out;
+ unsigned long ptr = (dmap->user_counter / dmap->fragment_size) * dmap->fragment_size;
+ unsigned long end_ptr, p;
+ int post = (dmap->flags & DMA_POST);
dmap->flags &= ~DMA_POST;
-
dmap->cfrag = -1;
-
dmap->user_counter += l;
dmap->flags |= DMA_DIRTY;
- if (dmap->user_counter >= dmap->max_byte_counter)
- { /* Wrap the byte counters */
- long decr = dmap->user_counter;
-
- dmap->user_counter = (dmap->user_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
- decr -= dmap->user_counter;
- dmap->byte_counter -= decr;
- }
+ if (dmap->user_counter >= dmap->max_byte_counter) {
+ /* Wrap the byte counters */
+ long decr = dmap->user_counter;
+ dmap->user_counter = (dmap->user_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
+ decr -= dmap->user_counter;
+ dmap->byte_counter -= decr;
+ }
end_ptr = (dmap->user_counter / dmap->fragment_size) * dmap->fragment_size;
p = (dmap->user_counter - 1) % dmap->bytes_in_use;
dmap->neutral_byte = dmap->raw_buf[p];
/* Update the fragment based bookkeeping too */
- while (ptr < end_ptr)
- {
- dmap->counts[dmap->qtail] = dmap->fragment_size;
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- dmap->qlen++;
- ptr += dmap->fragment_size;
- }
+ while (ptr < end_ptr) {
+ dmap->counts[dmap->qtail] = dmap->fragment_size;
+ dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
+ dmap->qlen++;
+ ptr += dmap->fragment_size;
+ }
dmap->counts[dmap->qtail] = dmap->user_counter - ptr;
-/*
- * Let the low level driver to perform some postprocessing to
- * the written data.
- */
- if (audio_devs[dev]->d->postprocess_write)
- audio_devs[dev]->d->postprocess_write(dev);
+ /*
+ * Let the low level driver to perform some postprocessing to
+ * the written data.
+ */
+ if (adev->d->postprocess_write)
+ adev->d->postprocess_write(dev);
if (!(dmap->flags & DMA_ACTIVE))
- if (dmap->qlen > 1 ||
- (dmap->qlen > 0 && (post || dmap->qlen >= dmap->nbufs - 1)))
- {
- DMAbuf_launch_output(dev, dmap);
- };
+ if (dmap->qlen > 1 || (dmap->qlen > 0 && (post || dmap->qlen >= dmap->nbufs - 1)))
+ DMAbuf_launch_output(dev, dmap);
return 0;
}
-int
-DMAbuf_start_dma(int dev, unsigned long physaddr, int count, int dma_mode)
+int DMAbuf_start_dma(int dev, unsigned long physaddr, int count, int dma_mode)
{
- int chan;
- struct dma_buffparms *dmap;
-
- if (dma_mode == DMA_MODE_WRITE)
- {
- chan = audio_devs[dev]->dmap_out->dma;
- dmap = audio_devs[dev]->dmap_out;
- } else
- {
- chan = audio_devs[dev]->dmap_in->dma;
- dmap = audio_devs[dev]->dmap_in;
- }
+ struct audio_operations *adev = audio_devs[dev];
+ struct dma_buffparms *dmap = (dma_mode == DMA_MODE_WRITE) ? adev->dmap_out : adev->dmap_in;
- if (dmap->raw_buf == NULL)
- {
- printk("sound: DMA buffer(1) == NULL\n");
- printk("Device %d, chn=%s\n", dev, (dmap == audio_devs[dev]->dmap_out) ? "out" : "in");
- return 0;
- }
- if (chan < 0)
+ if (dmap->raw_buf == NULL) {
+ printk(KERN_ERR "sound: DMA buffer(1) == NULL\n");
+ printk("Device %d, chn=%s\n", dev, (dmap == adev->dmap_out) ? "out" : "in");
return 0;
-
- sound_start_dma(dev, dmap, chan, physaddr, count, dma_mode, 0);
-
+ }
+ if (dmap->dma < 0)
+ return 0;
+ sound_start_dma(dmap, physaddr, count, dma_mode);
return count;
}
-static int
-local_start_dma(int dev, unsigned long physaddr, int count, int dma_mode)
+static int local_start_dma(struct audio_operations *adev, unsigned long physaddr, int count, int dma_mode)
{
- int chan;
- struct dma_buffparms *dmap;
-
- if (dma_mode == DMA_MODE_WRITE)
- {
- chan = audio_devs[dev]->dmap_out->dma;
- dmap = audio_devs[dev]->dmap_out;
- } else
- {
- chan = audio_devs[dev]->dmap_in->dma;
- dmap = audio_devs[dev]->dmap_in;
- }
+ struct dma_buffparms *dmap = (dma_mode == DMA_MODE_WRITE) ? adev->dmap_out : adev->dmap_in;
- if (dmap->raw_buf == NULL)
- {
- printk("sound: DMA buffer(2) == NULL\n");
- printk("Device %d, chn=%s\n", dev, (dmap == audio_devs[dev]->dmap_out) ? "out" : "in");
- return 0;
- }
+ if (dmap->raw_buf == NULL) {
+ printk(KERN_ERR "sound: DMA buffer(2) == NULL\n");
+ printk(KERN_ERR "Device %s, chn=%s\n", adev->name, (dmap == adev->dmap_out) ? "out" : "in");
+ return 0;
+ }
if (dmap->flags & DMA_NODMA)
- {
- return 1;
- }
- if (chan < 0)
+ return 1;
+ if (dmap->dma < 0)
return 0;
-
- sound_start_dma(dev, dmap, chan, dmap->raw_buf_phys, dmap->bytes_in_use, dma_mode, 1);
+ sound_start_dma(dmap, dmap->raw_buf_phys, dmap->bytes_in_use, dma_mode | DMA_AUTOINIT);
dmap->flags |= DMA_STARTED;
-
return count;
}
-static void
-finish_output_interrupt(int dev, struct dma_buffparms *dmap)
+static void finish_output_interrupt(int dev, struct dma_buffparms *dmap)
{
- unsigned long flags;
+ struct audio_operations *adev = audio_devs[dev];
if (dmap->audio_callback != NULL)
dmap->audio_callback(dev, dmap->callback_parm);
-
- save_flags(flags);
- cli();
- if ((out_sleep_flag[dev].opts & WK_SLEEP))
- {
- {
- out_sleep_flag[dev].opts = WK_WAKEUP;
- wake_up(&out_sleeper[dev]);
- };
- }
- restore_flags(flags);
+ wake_up(&adev->out_sleeper);
}
-static void
-do_outputintr(int dev, int dummy)
+static void do_outputintr(int dev, int dummy)
{
- unsigned long flags;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
- int this_fragment;
-
-#ifdef OS_DMA_INTR
- if (audio_devs[dev]->dmap_out->dma >= 0)
- sound_dma_intr(dev, audio_devs[dev]->dmap_out, audio_devs[dev]->dmap_out->dma);
-#endif
+ struct audio_operations *adev = audio_devs[dev];
+ unsigned long flags;
+ struct dma_buffparms *dmap = adev->dmap_out;
+ int this_fragment;
- if (dmap->raw_buf == NULL)
- {
- printk("Sound: Fatal error. Audio interrupt (%d) after freeing buffers.\n", dev);
- return;
- }
- if (dmap->mapping_flags & DMA_MAP_MAPPED) /* Virtual memory mapped access */
- {
- /* mmapped access */
- dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
- if (dmap->qhead == 0) /* Wrapped */
- {
- dmap->byte_counter += dmap->bytes_in_use;
- if (dmap->byte_counter >= dmap->max_byte_counter) /* Overflow */
- {
- long decr = dmap->byte_counter;
-
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
- decr -= dmap->byte_counter;
- dmap->user_counter -= decr;
- }
- }
- dmap->qlen++; /* Yes increment it (don't decrement) */
- if (!(audio_devs[dev]->flags & DMA_AUTOMODE))
- dmap->flags &= ~DMA_ACTIVE;
- dmap->counts[dmap->qhead] = dmap->fragment_size;
-
- DMAbuf_launch_output(dev, dmap);
- finish_output_interrupt(dev, dmap);
- return;
- }
+ if (dmap->raw_buf == NULL) {
+ printk(KERN_ERR "Sound: Error. Audio interrupt (%d) after freeing buffers.\n", dev);
+ return;
+ }
+ if (dmap->mapping_flags & DMA_MAP_MAPPED) { /* Virtual memory mapped access */
+ /* mmapped access */
+ dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
+ if (dmap->qhead == 0) { /* Wrapped */
+ dmap->byte_counter += dmap->bytes_in_use;
+ if (dmap->byte_counter >= dmap->max_byte_counter) { /* Overflow */
+ long decr = dmap->byte_counter;
+ dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
+ decr -= dmap->byte_counter;
+ dmap->user_counter -= decr;
+ }
+ }
+ dmap->qlen++; /* Yes increment it (don't decrement) */
+ if (!(adev->flags & DMA_AUTOMODE))
+ dmap->flags &= ~DMA_ACTIVE;
+ dmap->counts[dmap->qhead] = dmap->fragment_size;
+ DMAbuf_launch_output(dev, dmap);
+ finish_output_interrupt(dev, dmap);
+ return;
+ }
save_flags(flags);
cli();
@@ -1159,394 +948,280 @@ do_outputintr(int dev, int dummy)
this_fragment = dmap->qhead;
dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
- if (dmap->qhead == 0) /* Wrapped */
- {
- dmap->byte_counter += dmap->bytes_in_use;
- if (dmap->byte_counter >= dmap->max_byte_counter) /* Overflow */
- {
- long decr = dmap->byte_counter;
-
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
- decr -= dmap->byte_counter;
- dmap->user_counter -= decr;
- }
- }
- if (!(audio_devs[dev]->flags & DMA_AUTOMODE))
+ if (dmap->qhead == 0) { /* Wrapped */
+ dmap->byte_counter += dmap->bytes_in_use;
+ if (dmap->byte_counter >= dmap->max_byte_counter) { /* Overflow */
+ long decr = dmap->byte_counter;
+ dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
+ decr -= dmap->byte_counter;
+ dmap->user_counter -= decr;
+ }
+ }
+ if (!(adev->flags & DMA_AUTOMODE))
dmap->flags &= ~DMA_ACTIVE;
-
- while (dmap->qlen < 0)
- {
- dmap->underrun_count++;
-
- dmap->qlen++;
- if (dmap->flags & DMA_DIRTY && dmap->applic_profile != APF_CPUINTENS)
- {
- dmap->flags &= ~DMA_DIRTY;
- memset(audio_devs[dev]->dmap_out->raw_buf,
- audio_devs[dev]->dmap_out->neutral_byte,
- audio_devs[dev]->dmap_out->buffsize);
- }
- dmap->user_counter += dmap->fragment_size;
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- }
-
+ while (dmap->qlen <= 0) {
+ dmap->underrun_count++;
+ dmap->qlen++;
+ if (dmap->flags & DMA_DIRTY && dmap->applic_profile != APF_CPUINTENS) {
+ dmap->flags &= ~DMA_DIRTY;
+ memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte,
+ adev->dmap_out->buffsize);
+ }
+ dmap->user_counter += dmap->fragment_size;
+ dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
+ }
if (dmap->qlen > 0)
DMAbuf_launch_output(dev, dmap);
-
restore_flags(flags);
finish_output_interrupt(dev, dmap);
}
-void
-DMAbuf_outputintr(int dev, int notify_only)
+void DMAbuf_outputintr(int dev, int notify_only)
{
- unsigned long flags;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
+ struct audio_operations *adev = audio_devs[dev];
+ unsigned long flags;
+ struct dma_buffparms *dmap = adev->dmap_out;
save_flags(flags);
cli();
-
- if (!(dmap->flags & DMA_NODMA))
- {
- int chan = dmap->dma, pos, n;
-
- clear_dma_ff(chan);
- disable_dma(dmap->dma);
- pos = dmap->bytes_in_use - get_dma_residue(chan);
- enable_dma(dmap->dma);
-
- pos = pos / dmap->fragment_size; /* Actual qhead */
- if (pos < 0 || pos >= dmap->nbufs)
- pos = 0;
-
- n = 0;
- while (dmap->qhead != pos && n++ < dmap->nbufs)
- {
- do_outputintr(dev, notify_only);
- }
- } else
+ if (!(dmap->flags & DMA_NODMA)) {
+ int chan = dmap->dma, pos, n;
+ clear_dma_ff(chan);
+ disable_dma(dmap->dma);
+ pos = dmap->bytes_in_use - get_dma_residue(chan);
+ enable_dma(dmap->dma);
+ pos = pos / dmap->fragment_size; /* Actual qhead */
+ if (pos < 0 || pos >= dmap->nbufs)
+ pos = 0;
+ n = 0;
+ while (dmap->qhead != pos && n++ < dmap->nbufs)
+ do_outputintr(dev, notify_only);
+ }
+ else
do_outputintr(dev, notify_only);
restore_flags(flags);
}
-static void
-do_inputintr(int dev)
+static void do_inputintr(int dev)
{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
- unsigned long flags;
-
-#ifdef OS_DMA_INTR
- if (audio_devs[dev]->dmap_in->dma >= 0)
- sound_dma_intr(dev, audio_devs[dev]->dmap_in, audio_devs[dev]->dmap_in->dma);
-#endif
+ struct audio_operations *adev = audio_devs[dev];
+ struct dma_buffparms *dmap = adev->dmap_in;
- if (dmap->raw_buf == NULL)
- {
- printk("Sound: Fatal error. Audio interrupt after freeing buffers.\n");
- return;
- }
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- {
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- if (dmap->qtail == 0) /* Wrapped */
- {
- dmap->byte_counter += dmap->bytes_in_use;
- if (dmap->byte_counter >= dmap->max_byte_counter) /* Overflow */
- {
- long decr = dmap->byte_counter;
-
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
- decr -= dmap->byte_counter;
- dmap->user_counter -= decr;
- }
- }
- dmap->qlen++;
-
- if (!(audio_devs[dev]->flags & DMA_AUTOMODE))
- {
- if (dmap->needs_reorg)
- reorganize_buffers(dev, dmap, 0);
- local_start_dma(dev, dmap->raw_buf_phys, dmap->bytes_in_use,
- DMA_MODE_READ);
- audio_devs[dev]->d->start_input(dev, dmap->raw_buf_phys +
- dmap->qtail * dmap->fragment_size,
- dmap->fragment_size, 1);
- if (audio_devs[dev]->d->trigger)
- audio_devs[dev]->d->trigger(dev,
- audio_devs[dev]->enable_bits * audio_devs[dev]->go);
- }
- dmap->flags |= DMA_ACTIVE;
- } else if (dmap->qlen >= (dmap->nbufs - 1))
- {
- printk("Sound: Recording overrun\n");
- dmap->underrun_count++;
-
- /* Just throw away the oldest fragment but keep the engine running */
- dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- } else if (dmap->qlen >= 0 && dmap->qlen < dmap->nbufs)
- {
- dmap->qlen++;
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- if (dmap->qtail == 0) /* Wrapped */
- {
- dmap->byte_counter += dmap->bytes_in_use;
- if (dmap->byte_counter >= dmap->max_byte_counter) /* Overflow */
- {
- long decr = dmap->byte_counter;
-
- dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
- decr -= dmap->byte_counter;
- dmap->user_counter -= decr;
- }
- }
- }
- if (!(audio_devs[dev]->flags & DMA_AUTOMODE) || dmap->flags & DMA_NODMA)
- {
- local_start_dma(dev, dmap->raw_buf_phys, dmap->bytes_in_use,
- DMA_MODE_READ);
- audio_devs[dev]->d->start_input(dev, dmap->raw_buf_phys +
- dmap->qtail * dmap->fragment_size,
- dmap->fragment_size, 1);
- if (audio_devs[dev]->d->trigger)
- audio_devs[dev]->d->trigger(dev,
- audio_devs[dev]->enable_bits * audio_devs[dev]->go);
- }
+ if (dmap->raw_buf == NULL) {
+ printk(KERN_ERR "Sound: Fatal error. Audio interrupt after freeing buffers.\n");
+ return;
+ }
+ if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+ dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
+ if (dmap->qtail == 0) { /* Wrapped */
+ dmap->byte_counter += dmap->bytes_in_use;
+ if (dmap->byte_counter >= dmap->max_byte_counter) { /* Overflow */
+ long decr = dmap->byte_counter;
+ dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
+ decr -= dmap->byte_counter;
+ dmap->user_counter -= decr;
+ }
+ }
+ dmap->qlen++;
+
+ if (!(adev->flags & DMA_AUTOMODE)) {
+ if (dmap->needs_reorg)
+ reorganize_buffers(dev, dmap, 0);
+ local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use,DMA_MODE_READ);
+ adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size,
+ dmap->fragment_size, 1);
+ if (adev->d->trigger)
+ adev->d->trigger(dev, adev->enable_bits * adev->go);
+ }
+ dmap->flags |= DMA_ACTIVE;
+ } else if (dmap->qlen >= (dmap->nbufs - 1)) {
+ printk(KERN_WARNING "Sound: Recording overrun\n");
+ dmap->underrun_count++;
+
+ /* Just throw away the oldest fragment but keep the engine running */
+ dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
+ dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
+ } else if (dmap->qlen >= 0 && dmap->qlen < dmap->nbufs) {
+ dmap->qlen++;
+ dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
+ if (dmap->qtail == 0) { /* Wrapped */
+ dmap->byte_counter += dmap->bytes_in_use;
+ if (dmap->byte_counter >= dmap->max_byte_counter) { /* Overflow */
+ long decr = dmap->byte_counter;
+ dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
+ decr -= dmap->byte_counter;
+ dmap->user_counter -= decr;
+ }
+ }
+ }
+ if (!(adev->flags & DMA_AUTOMODE) || dmap->flags & DMA_NODMA) {
+ local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use, DMA_MODE_READ);
+ adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size, dmap->fragment_size, 1);
+ if (adev->d->trigger)
+ adev->d->trigger(dev,adev->enable_bits * adev->go);
+ }
dmap->flags |= DMA_ACTIVE;
-
- save_flags(flags);
- cli();
if (dmap->qlen > 0)
- if ((in_sleep_flag[dev].opts & WK_SLEEP))
- {
- {
- in_sleep_flag[dev].opts = WK_WAKEUP;
- wake_up(&in_sleeper[dev]);
- };
- }
- restore_flags(flags);
+ wake_up(&adev->in_sleeper);
}
-void
-DMAbuf_inputintr(int dev)
+void DMAbuf_inputintr(int dev)
{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
- unsigned long flags;
+ struct audio_operations *adev = audio_devs[dev];
+ struct dma_buffparms *dmap = adev->dmap_in;
+ unsigned long flags;
save_flags(flags);
cli();
- if (!(dmap->flags & DMA_NODMA))
- {
- int chan = dmap->dma, pos, n;
+ if (!(dmap->flags & DMA_NODMA)) {
+ int chan = dmap->dma, pos, n;
+ clear_dma_ff(chan);
+ disable_dma(dmap->dma);
+ pos = dmap->bytes_in_use - get_dma_residue(chan);
+ enable_dma(dmap->dma);
- clear_dma_ff(chan);
- disable_dma(dmap->dma);
- pos = dmap->bytes_in_use - get_dma_residue(chan);
- enable_dma(dmap->dma);
+ pos = pos / dmap->fragment_size; /* Actual qhead */
+ if (pos < 0 || pos >= dmap->nbufs)
+ pos = 0;
- pos = pos / dmap->fragment_size; /* Actual qhead */
- if (pos < 0 || pos >= dmap->nbufs)
- pos = 0;
-
- n = 0;
- while (dmap->qtail != pos && ++n < dmap->nbufs)
- {
- do_inputintr(dev);
- }
+ n = 0;
+ while (dmap->qtail != pos && ++n < dmap->nbufs)
+ do_inputintr(dev);
} else
do_inputintr(dev);
restore_flags(flags);
}
-int
-DMAbuf_open_dma(int dev)
+int DMAbuf_open_dma(int dev)
{
-/*
- * NOTE! This routine opens only the primary DMA channel (output).
- */
+ /*
+ * NOTE! This routine opens only the primary DMA channel (output).
+ */
+ struct audio_operations *adev = audio_devs[dev];
+ int err;
- int chan = audio_devs[dev]->dmap_out->dma;
- int err;
-
- if ((err = open_dmap(dev, OPEN_READWRITE, audio_devs[dev]->dmap_out, chan)) < 0)
- {
- return -EBUSY;
- }
- dma_init_buffers(dev, audio_devs[dev]->dmap_out);
- out_sleep_flag[dev].opts = WK_NONE;
- audio_devs[dev]->dmap_out->flags |= DMA_ALLOC_DONE;
- audio_devs[dev]->dmap_out->fragment_size = audio_devs[dev]->dmap_out->buffsize;
-
- if (chan >= 0)
- {
- unsigned long flags;
-
- save_flags(flags);
- cli();
- disable_dma(audio_devs[dev]->dmap_out->dma);
- clear_dma_ff(chan);
- restore_flags(flags);
- }
+ if ((err = open_dmap(adev, OPEN_READWRITE, adev->dmap_out)) < 0)
+ return -EBUSY;
+ dma_init_buffers(adev->dmap_out);
+ adev->dmap_out->flags |= DMA_ALLOC_DONE;
+ adev->dmap_out->fragment_size = adev->dmap_out->buffsize;
+
+ if (adev->dmap_out->dma >= 0) {
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+ clear_dma_ff(adev->dmap_out->dma);
+ disable_dma(adev->dmap_out->dma);
+ restore_flags(flags);
+ }
return 0;
}
-void
-DMAbuf_close_dma(int dev)
+void DMAbuf_close_dma(int dev)
{
- close_dmap(dev, audio_devs[dev]->dmap_out, audio_devs[dev]->dmap_out->dma);
+ close_dmap(audio_devs[dev], audio_devs[dev]->dmap_out);
}
-void
-DMAbuf_init(int dev, int dma1, int dma2)
+void DMAbuf_init(int dev, int dma1, int dma2)
{
+ struct audio_operations *adev = audio_devs[dev];
/*
- * NOTE! This routine could be called several times.
+ * NOTE! This routine could be called several times.
*/
- if (audio_devs[dev] && audio_devs[dev]->dmap_out == NULL)
- {
- if (audio_devs[dev]->d == NULL)
- panic("OSS: audio_devs[%d]->d == NULL\n", dev);
-
- if (audio_devs[dev]->parent_dev)
- { /* Use DMA map of the parent dev */
- int parent = audio_devs[dev]->parent_dev - 1;
-
- audio_devs[dev]->dmap_out = audio_devs[parent]->dmap_out;
- audio_devs[dev]->dmap_in = audio_devs[parent]->dmap_in;
- } else
- {
- audio_devs[dev]->dmap_out =
- audio_devs[dev]->dmap_in =
- &dmaps[ndmaps++];
- audio_devs[dev]->dmap_out->dma = dma1;
-
- if (audio_devs[dev]->flags & DMA_DUPLEX)
- {
- audio_devs[dev]->dmap_in =
- &dmaps[ndmaps++];
- audio_devs[dev]->dmap_in->dma = dma2;
- }
- }
- }
+ if (adev && adev->dmap_out == NULL) {
+ if (adev->d == NULL)
+ panic("OSS: audio_devs[%d]->d == NULL\n", dev);
+
+ if (adev->parent_dev) { /* Use DMA map of the parent dev */
+ int parent = adev->parent_dev - 1;
+ adev->dmap_out = audio_devs[parent]->dmap_out;
+ adev->dmap_in = audio_devs[parent]->dmap_in;
+ } else {
+ adev->dmap_out = adev->dmap_in = &adev->dmaps[0];
+ adev->dmap_out->dma = dma1;
+ if (adev->flags & DMA_DUPLEX) {
+ adev->dmap_in = &adev->dmaps[1];
+ adev->dmap_in->dma = dma2;
+ }
+ }
+ }
}
-int
-DMAbuf_select(int dev, struct fileinfo *file, int sel_type, poll_table * wait)
+static unsigned int poll_input(struct file * file, int dev, poll_table *wait)
{
- struct dma_buffparms *dmap;
- unsigned long flags;
-
- switch (sel_type)
- {
- case SEL_IN:
- if (!(audio_devs[dev]->open_mode & OPEN_READ))
- return 0;
-
- dmap = audio_devs[dev]->dmap_in;
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- {
- if (dmap->qlen)
- return 1;
-
- save_flags(flags);
- cli();
-
- in_sleep_flag[dev].opts = WK_SLEEP;
- poll_wait(&in_sleeper[dev], wait);
- restore_flags(flags);
- return 0;
- }
- if (dmap->dma_mode != DMODE_INPUT)
- {
- if (dmap->dma_mode == DMODE_NONE &&
- audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT &&
- !dmap->qlen &&
- audio_devs[dev]->go)
- {
- unsigned long flags;
-
- save_flags(flags);
- cli();
- DMAbuf_activate_recording(dev, dmap);
- restore_flags(flags);
- }
- return 0;
- }
- if (!dmap->qlen)
- {
- save_flags(flags);
- cli();
-
- in_sleep_flag[dev].opts = WK_SLEEP;
- poll_wait(&in_sleeper[dev], wait);
- restore_flags(flags);
- return 0;
- }
- return 1;
- break;
-
- case SEL_OUT:
- dmap = audio_devs[dev]->dmap_out;
-
- if (!(audio_devs[dev]->open_mode & OPEN_WRITE))
- return 0;
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- {
- if (dmap->qlen)
- return 1;
-
- save_flags(flags);
- cli();
-
- out_sleep_flag[dev].opts = WK_SLEEP;
- poll_wait(&out_sleeper[dev], wait);
- restore_flags(flags);
- return 0;
- }
- if (dmap->dma_mode == DMODE_INPUT)
- {
- return 0;
- }
- if (dmap->dma_mode == DMODE_NONE)
- {
- return 1;
- }
- if (!DMAbuf_space_in_queue(dev))
- {
- save_flags(flags);
- cli();
-
- out_sleep_flag[dev].opts = WK_SLEEP;
- poll_wait(&out_sleeper[dev], wait);
- restore_flags(flags);
- return 0;
- }
- return 1;
- break;
-
- case SEL_EX:
- return 0;
- }
+ struct audio_operations *adev = audio_devs[dev];
+ struct dma_buffparms *dmap = adev->dmap_in;
- return 0;
+ if (!(adev->open_mode & OPEN_READ))
+ return 0;
+ if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+ poll_wait(file, &adev->in_sleeper, wait);
+ if (dmap->qlen)
+ return POLLIN | POLLRDNORM;
+ return 0;
+ }
+ if (dmap->dma_mode != DMODE_INPUT) {
+ if (dmap->dma_mode == DMODE_NONE &&
+ adev->enable_bits & PCM_ENABLE_INPUT &&
+ !dmap->qlen && adev->go) {
+ unsigned long flags;
+
+ poll_wait(file, &adev->in_sleeper, wait);
+ save_flags(flags);
+ cli();
+ DMAbuf_activate_recording(dev, dmap);
+ restore_flags(flags);
+ }
+ return 0;
+ }
+ poll_wait(file, &adev->in_sleeper, wait);
+ if (!dmap->qlen)
+ return 0;
+ return POLLIN | POLLRDNORM;
}
-void
-DMAbuf_deinit(int dev)
+static unsigned int poll_output(struct file * file, int dev, poll_table *wait)
{
-/* This routine is called when driver is being unloaded */
+ struct audio_operations *adev = audio_devs[dev];
+ struct dma_buffparms *dmap = adev->dmap_out;
+
+ if (!(adev->open_mode & OPEN_WRITE))
+ return 0;
+ if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+ poll_wait(file, &adev->out_sleeper, wait);
+ if (dmap->qlen)
+ return POLLOUT | POLLWRNORM;
+ return 0;
+ }
+ if (dmap->dma_mode == DMODE_INPUT)
+ return 0;
+ poll_wait(file, &adev->out_sleeper, wait);
+ if (dmap->dma_mode == DMODE_NONE)
+ return POLLOUT | POLLWRNORM;
+ if (!DMAbuf_space_in_queue(dev))
+ return 0;
+ return POLLOUT | POLLWRNORM;
+}
+
+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
- if (audio_devs[dev])
- sound_free_dmap (dev, audio_devs[dev]->dmap_out,
- audio_devs[dev]->dmap_out->dma);
+ sound_free_dmap(adev->dmap_out);
- if (audio_devs[dev] && audio_devs[dev]->flags & DMA_DUPLEX)
- sound_free_dmap (dev, audio_devs[dev]->dmap_in,
- audio_devs[dev]->dmap_in->dma);
+ if (adev->flags & DMA_DUPLEX)
+ sound_free_dmap(adev->dmap_in);
#endif
}
diff --git a/drivers/sound/gus_card.c b/drivers/sound/gus_card.c
index eba6072d6..0f4f769eb 100644
--- a/drivers/sound/gus_card.c
+++ b/drivers/sound/gus_card.c
@@ -16,7 +16,7 @@
#include "sound_config.h"
#include "soundmodule.h"
-#if defined(CONFIG_GUSHW) || defined(MODULE)
+#if defined(CONFIG_GUS) || defined(MODULE)
#include "gus_hw.h"
@@ -28,8 +28,7 @@ extern int gus_pcm_volume;
extern int have_gus_max;
int gus_pnp_flag = 0;
-void
-attach_gus_card(struct address_info *hw_config)
+void attach_gus_card(struct address_info *hw_config)
{
snd_set_irq_handler(hw_config->irq, gusintr, "Gravis Ultrasound", hw_config->osp);
@@ -48,8 +47,7 @@ attach_gus_card(struct address_info *hw_config)
#endif
}
-int
-probe_gus(struct address_info *hw_config)
+int probe_gus(struct address_info *hw_config)
{
int irq;
int io_addr;
@@ -63,13 +61,13 @@ probe_gus(struct address_info *hw_config)
if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
irq != 11 && irq != 12 && irq != 15)
{
- printk("GUS: Unsupported IRQ %d\n", irq);
+ printk(KERN_ERR "GUS: Unsupported IRQ %d\n", irq);
return 0;
}
if (check_region(hw_config->io_base, 16))
- printk("GUS: I/O range conflict (1)\n");
+ printk(KERN_ERR "GUS: I/O range conflict (1)\n");
else if (check_region(hw_config->io_base + 0x100, 16))
- printk("GUS: I/O range conflict (2)\n");
+ printk(KERN_ERR "GUS: I/O range conflict (2)\n");
else if (gus_wave_detect(hw_config->io_base))
return 1;
@@ -95,8 +93,7 @@ probe_gus(struct address_info *hw_config)
return 0;
}
-void
-unload_gus(struct address_info *hw_config)
+void unload_gus(struct address_info *hw_config)
{
DDB(printk("unload_gus(%x)\n", hw_config->io_base));
@@ -112,8 +109,7 @@ unload_gus(struct address_info *hw_config)
sound_free_dma(hw_config->dma2);
}
-void
-gusintr(int irq, void *dev_id, struct pt_regs *dummy)
+void gusintr(int irq, void *dev_id, struct pt_regs *dummy)
{
unsigned char src;
extern int gus_timer_enabled;
@@ -126,58 +122,52 @@ gusintr(int irq, void *dev_id, struct pt_regs *dummy)
#endif
while (1)
- {
- if (!(src = inb(u_IrqStatus)))
- return;
-
- if (src & DMA_TC_IRQ)
- {
- guswave_dma_irq();
- }
- if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
- {
+ {
+ if (!(src = inb(u_IrqStatus)))
+ return;
+
+ if (src & DMA_TC_IRQ)
+ {
+ guswave_dma_irq();
+ }
+ if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
+ {
#if defined(CONFIG_MIDI)
- gus_midi_interrupt(0);
+ gus_midi_interrupt(0);
#endif
- }
- if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
- {
+ }
+ if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
+ {
#if defined(CONFIG_SEQUENCER) || defined(CONFIG_SEQUENCER_MODULE)
- if (gus_timer_enabled)
- {
- sound_timer_interrupt();
- }
- gus_write8(0x45, 0); /* Ack IRQ */
- gus_timer_command(4, 0x80); /* Reset IRQ flags */
-
+ if (gus_timer_enabled)
+ sound_timer_interrupt();
+ gus_write8(0x45, 0); /* Ack IRQ */
+ gus_timer_command(4, 0x80); /* Reset IRQ flags */
#else
- gus_write8(0x45, 0); /* Stop timers */
+ gus_write8(0x45, 0); /* Stop timers */
#endif
- }
- if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
- {
- gus_voice_irq();
- }
- }
+ }
+ if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
+ gus_voice_irq();
+ }
}
#endif
/*
- * Some extra code for the 16 bit sampling option
+ * Some extra code for the 16 bit sampling option
*/
+
#ifdef CONFIG_GUS16
-int
-probe_gus_db16(struct address_info *hw_config)
+int probe_gus_db16(struct address_info *hw_config)
{
return ad1848_detect(hw_config->io_base, NULL, hw_config->osp);
}
-void
-attach_gus_db16(struct address_info *hw_config)
+void attach_gus_db16(struct address_info *hw_config)
{
-#if defined(CONFIG_GUSHW) || defined(MODULE)
+#if defined(CONFIG_GUS) || defined(MODULE)
gus_pcm_volume = 100;
gus_wave_volume = 90;
#endif
@@ -189,8 +179,7 @@ attach_gus_db16(struct address_info *hw_config)
hw_config->osp);
}
-void
-unload_gus_db16(struct address_info *hw_config)
+void unload_gus_db16(struct address_info *hw_config)
{
ad1848_unload(hw_config->io_base,
@@ -226,16 +215,15 @@ MODULE_PARM(type, "i");
MODULE_PARM(gus16, "i");
MODULE_PARM(db16, "i");
-int
-init_module(void)
+int init_module(void)
{
- printk("Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+ printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
if (io == -1 || dma == -1 || irq == -1)
- {
- printk("I/O, IRQ, and DMA are mandatory\n");
- return -EINVAL;
- }
+ {
+ printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n");
+ return -EINVAL;
+ }
config.io_base = io;
config.irq = irq;
config.dma = dma;
@@ -244,10 +232,10 @@ init_module(void)
#if defined(CONFIG_GUS16)
if (probe_gus_db16(&config) && gus16)
- {
- attach_gus_db16(&config);
- db16 = 1;
- }
+ {
+ attach_gus_db16(&config);
+ db16 = 1;
+ }
#endif
if (probe_gus(&config) == 0)
return -ENODEV;
@@ -256,11 +244,12 @@ init_module(void)
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
+#if defined(CONFIG_GUS16)
if (db16)
unload_gus_db16(&config);
+#endif
unload_gus(&config);
SOUND_LOCK_END;
}
diff --git a/drivers/sound/gus_midi.c b/drivers/sound/gus_midi.c
index fdbde32fd..1055aa509 100644
--- a/drivers/sound/gus_midi.c
+++ b/drivers/sound/gus_midi.c
@@ -17,7 +17,7 @@
#include "gus_hw.h"
-#if ( defined(CONFIG_GUSHW) && defined(CONFIG_MIDI) ) || defined (MODULE)
+#if ( defined(CONFIG_GUS) && defined(CONFIG_MIDI) ) || defined (MODULE)
static int midi_busy = 0, input_opened = 0;
static int my_dev;
@@ -33,24 +33,18 @@ static volatile unsigned char qhead, qtail;
extern int gus_base, gus_irq, gus_dma;
extern int *gus_osp;
-static int
-GUS_MIDI_STATUS(void)
+static int GUS_MIDI_STATUS(void)
{
return inb(u_MidiStatus);
}
-static int
-gus_midi_open(int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
+static int gus_midi_open(int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev))
{
-
if (midi_busy)
- {
- printk("GUS: Midi busy\n");
- return -EBUSY;
- }
+ {
+/* printk("GUS: Midi busy\n");*/
+ return -EBUSY;
+ }
outb((MIDI_RESET), u_MidiControl);
gus_delay();
@@ -59,10 +53,10 @@ gus_midi_open(int dev, int mode,
if (mode == OPEN_READ || mode == OPEN_READWRITE)
if (!gus_pnp_flag)
- {
- gus_midi_control |= MIDI_ENABLE_RCV;
- input_opened = 1;
- }
+ {
+ gus_midi_control |= MIDI_ENABLE_RCV;
+ input_opened = 1;
+ }
outb((gus_midi_control), u_MidiControl); /* Enable */
midi_busy = 1;
@@ -72,8 +66,7 @@ gus_midi_open(int dev, int mode,
return 0;
}
-static int
-dump_to_midi(unsigned char midi_byte)
+static int dump_to_midi(unsigned char midi_byte)
{
unsigned long flags;
int ok = 0;
@@ -84,24 +77,24 @@ dump_to_midi(unsigned char midi_byte)
cli();
if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY)
- {
- ok = 1;
- outb((midi_byte), u_MidiData);
- } else
- {
- /*
- * Enable Midi xmit interrupts (again)
- */
- gus_midi_control |= MIDI_ENABLE_XMIT;
- outb((gus_midi_control), u_MidiControl);
- }
+ {
+ ok = 1;
+ outb((midi_byte), u_MidiData);
+ }
+ else
+ {
+ /*
+ * Enable Midi xmit interrupts (again)
+ */
+ gus_midi_control |= MIDI_ENABLE_XMIT;
+ outb((gus_midi_control), u_MidiControl);
+ }
restore_flags(flags);
return ok;
}
-static void
-gus_midi_close(int dev)
+static void gus_midi_close(int dev)
{
/*
* Reset FIFO pointers, disable intrs
@@ -111,10 +104,8 @@ gus_midi_close(int dev)
midi_busy = 0;
}
-static int
-gus_midi_out(int dev, unsigned char midi_byte)
+static int gus_midi_out(int dev, unsigned char midi_byte)
{
-
unsigned long flags;
/*
@@ -125,15 +116,14 @@ gus_midi_out(int dev, unsigned char midi_byte)
cli();
while (qlen && dump_to_midi(tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
-
+ {
+ qlen--;
+ qhead++;
+ }
restore_flags(flags);
/*
- * Output the byte if the local queue is empty.
+ * Output the byte if the local queue is empty.
*/
if (!qlen)
@@ -143,14 +133,13 @@ gus_midi_out(int dev, unsigned char midi_byte)
*/
/*
- * Put to the local queue
+ * Put to the local queue
*/
if (qlen >= 256)
return 0; /*
* Local queue full
*/
-
save_flags(flags);
cli();
@@ -159,35 +148,24 @@ gus_midi_out(int dev, unsigned char midi_byte)
qtail++;
restore_flags(flags);
-
return 1;
}
-static int
-gus_midi_start_read(int dev)
+static int gus_midi_start_read(int dev)
{
return 0;
}
-static int
-gus_midi_end_read(int dev)
+static int gus_midi_end_read(int dev)
{
return 0;
}
-static int
-gus_midi_ioctl(int dev, unsigned cmd, caddr_t arg)
+static void gus_midi_kick(int dev)
{
- return -EINVAL;
}
-static void
-gus_midi_kick(int dev)
-{
-}
-
-static int
-gus_midi_buffer_status(int dev)
+static int gus_midi_buffer_status(int dev)
{
unsigned long flags;
@@ -198,12 +176,11 @@ gus_midi_buffer_status(int dev)
cli();
if (qlen && dump_to_midi(tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
+ {
+ qlen--;
+ qhead++;
+ }
restore_flags(flags);
-
return (qlen > 0) | !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
}
@@ -213,12 +190,14 @@ gus_midi_buffer_status(int dev)
static struct midi_operations gus_midi_operations =
{
- {"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
+ {
+ "Gravis UltraSound Midi", 0, 0, SNDCARD_GUS
+ },
&std_midi_synth,
{0},
gus_midi_open,
gus_midi_close,
- gus_midi_ioctl,
+ NULL, /* ioctl */
gus_midi_out,
gus_midi_start_read,
gus_midi_end_read,
@@ -230,16 +209,15 @@ static struct midi_operations gus_midi_operations =
NULL
};
-void
-gus_midi_init(struct address_info *hw_config)
+void gus_midi_init(struct address_info *hw_config)
{
- int dev = sound_alloc_mididev();
+ int dev = sound_alloc_mididev();
if (dev == -1)
- {
- printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
- return;
- }
+ {
+ printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
+ return;
+ }
outb((MIDI_RESET), u_MidiControl);
std_midi_synth.midi_dev = my_dev = dev;
@@ -249,44 +227,41 @@ gus_midi_init(struct address_info *hw_config)
return;
}
-void
-gus_midi_interrupt(int dummy)
+void gus_midi_interrupt(int dummy)
{
volatile unsigned char stat, data;
- unsigned long flags;
- int timeout = 10;
+ unsigned long flags;
+ int timeout = 10;
save_flags(flags);
cli();
while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
- {
- if (stat & MIDI_RCV_FULL)
- {
- data = inb(u_MidiData);
- if (input_opened)
- midi_input_intr(my_dev, data);
- }
- if (stat & MIDI_XMIT_EMPTY)
- {
- while (qlen && dump_to_midi(tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
-
- if (!qlen)
- {
- /*
- * Disable Midi output interrupts, since no data in the buffer
- */
- gus_midi_control &= ~MIDI_ENABLE_XMIT;
- outb((gus_midi_control), u_MidiControl);
- outb((gus_midi_control), u_MidiControl);
- }
- }
- }
-
+ {
+ if (stat & MIDI_RCV_FULL)
+ {
+ data = inb(u_MidiData);
+ if (input_opened)
+ midi_input_intr(my_dev, data);
+ }
+ if (stat & MIDI_XMIT_EMPTY)
+ {
+ while (qlen && dump_to_midi(tmp_queue[qhead]))
+ {
+ qlen--;
+ qhead++;
+ }
+ if (!qlen)
+ {
+ /*
+ * Disable Midi output interrupts, since no data in the buffer
+ */
+ gus_midi_control &= ~MIDI_ENABLE_XMIT;
+ outb((gus_midi_control), u_MidiControl);
+ outb((gus_midi_control), u_MidiControl);
+ }
+ }
+ }
restore_flags(flags);
}
diff --git a/drivers/sound/gus_vol.c b/drivers/sound/gus_vol.c
index a42c5c6e1..0e03aa685 100644
--- a/drivers/sound/gus_vol.c
+++ b/drivers/sound/gus_vol.c
@@ -12,7 +12,7 @@
#include <linux/config.h>
#include "sound_config.h"
-#if defined(CONFIG_GUSHW) || defined(MODULE)
+#if defined(CONFIG_GUS) || defined(MODULE)
#include "gus_linearvol.h"
#define GUS_VOLUME gus_wave_volume
@@ -34,10 +34,10 @@ extern int gus_wave_volume;
* we can give a big boost to very weak voices like nylon guitar and the
* basses. The normal value is 64. Strings are assigned lower values.
*/
-unsigned short
-gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
+
+unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
{
- int i, m, n, x;
+ int i, m, n, x;
/*
@@ -50,6 +50,7 @@ gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
/*
* Boost expression by voice volume above neutral.
*/
+
if (voicev > 65)
xpn += voicev - 64;
xpn += (voicev - 64) / 2;
@@ -85,18 +86,22 @@ gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
* Convert to GUS's logarithmic form with 4 bit exponent i and 8 bit
* mantissa m.
*/
+
n = x;
i = 7;
if (n < 128)
- {
+ {
while (i > 0 && n < (1 << i))
i--;
- } else
+ }
+ else
+ {
while (n > 255)
- {
+ {
n >>= 1;
i++;
- }
+ }
+ }
/*
* Mantissa is part of linear volume not expressed in exponent. (This is
* not quite like real logs -- I wonder if it's right.)
@@ -107,12 +112,12 @@ gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
* Adjust mantissa to 8 bits.
*/
if (m > 0)
- {
- if (i > 8)
- m >>= i - 8;
- else if (i < 8)
- m <<= 8 - i;
- }
+ {
+ if (i > 8)
+ m >>= i - 8;
+ else if (i < 8)
+ m <<= 8 - i;
+ }
return ((i << 8) + m);
}
@@ -122,10 +127,9 @@ gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
* and the volume set by the mixer-device (default 60%).
*/
-unsigned short
-gus_linear_vol(int vol, int mainvol)
+unsigned short gus_linear_vol(int vol, int mainvol)
{
- int mixer_mainvol;
+ int mixer_mainvol;
if (vol <= 0)
vol = 0;
@@ -146,7 +150,6 @@ gus_linear_vol(int vol, int mainvol)
#else
mainvol = 127;
#endif
-
return gus_linearvol[(((vol * mainvol) / 127) * mixer_mainvol) / 100];
}
diff --git a/drivers/sound/gus_wave.c b/drivers/sound/gus_wave.c
index 2814ffe12..7b202f3ef 100644
--- a/drivers/sound/gus_wave.c
+++ b/drivers/sound/gus_wave.c
@@ -10,6 +10,9 @@
* 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>
@@ -19,7 +22,7 @@
#include <linux/ultrasound.h>
#include "gus_hw.h"
-#if defined(CONFIG_GUSHW) || defined(MODULE)
+#if defined(CONFIG_GUS) || defined(MODULE)
#define GUS_BANK_SIZE (((iw_mode) ? 256*1024*1024 : 256*1024))
@@ -29,42 +32,42 @@
#define NOT_SAMPLE 0xffff
struct voice_info
- {
- unsigned long orig_freq;
- unsigned long current_freq;
- unsigned long mode;
- int fixed_pitch;
- int bender;
- int bender_range;
- int panning;
- int midi_volume;
- unsigned int initial_volume;
- unsigned int current_volume;
- int loop_irq_mode, loop_irq_parm;
+{
+ unsigned long orig_freq;
+ unsigned long current_freq;
+ unsigned long mode;
+ int fixed_pitch;
+ int bender;
+ int bender_range;
+ int panning;
+ int midi_volume;
+ unsigned int initial_volume;
+ unsigned int current_volume;
+ int loop_irq_mode, loop_irq_parm;
#define LMODE_FINISH 1
#define LMODE_PCM 2
#define LMODE_PCM_STOP 3
- int volume_irq_mode, volume_irq_parm;
+ int volume_irq_mode, volume_irq_parm;
#define VMODE_HALT 1
#define VMODE_ENVELOPE 2
#define VMODE_START_NOTE 3
- int env_phase;
- unsigned char env_rate[6];
- unsigned char env_offset[6];
+ int env_phase;
+ unsigned char env_rate[6];
+ unsigned char env_offset[6];
- /*
- * Volume computation parameters for gus_adagio_vol()
- */
- int main_vol, expression_vol, patch_vol;
+ /*
+ * Volume computation parameters for gus_adagio_vol()
+ */
+ int main_vol, expression_vol, patch_vol;
- /* Variables for "Ultraclick" removal */
- int dev_pending, note_pending, volume_pending,
- sample_pending;
- char kill_pending;
- long offset_pending;
+ /* Variables for "Ultraclick" removal */
+ int dev_pending, note_pending, volume_pending,
+ sample_pending;
+ char kill_pending;
+ long offset_pending;
- };
+};
static struct voice_alloc_info *voice_alloc;
@@ -98,6 +101,7 @@ int gus_timer_enabled = 0;
* Current version of this driver doesn't allow synth and PCM functions
* at the same time. The active_device specifies the active driver
*/
+
static int active_device = 0;
#define GUS_DEV_WAVE 1 /* Wave table synth */
@@ -111,12 +115,11 @@ static int gus_audio_bsize;
static char bounce_buf[8 * 1024]; /* Must match value set to max_fragment */
static struct wait_queue *dram_sleeper = NULL;
-static volatile struct snd_wait dram_sleep_flag =
-{0};
/*
* Variables and buffers for PCM output
*/
+
#define MAX_PCM_BUFFERS (128*MAX_REALTIME_FACTOR) /* Don't change */
static int pcm_bsize, pcm_nblk, pcm_banksize;
@@ -159,7 +162,7 @@ static int freq_div_table[] =
19293 /* 32 */
};
-static struct patch_info *samples;
+static struct patch_info *samples = NULL;
static long sample_ptrs[MAX_SAMPLE + 1];
static int sample_map[32];
static int free_sample;
@@ -169,8 +172,10 @@ static int mixer_type = 0;
static int patch_table[MAX_PATCH];
static int patch_map[32];
-static struct synth_info gus_info =
-{"Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 0, 16, 0, MAX_PATCH};
+static struct synth_info gus_info = {
+ "Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS,
+ 0, 16, 0, MAX_PATCH
+};
static void gus_poke(long addr, unsigned char data);
static void compute_and_set_volume(int voice, int volume, int ramp_time);
@@ -184,10 +189,9 @@ static void gus_tmr_install(int io_base);
#define INSTANT_RAMP -1 /* Instant change. No ramping */
#define FAST_RAMP 0 /* Fastest possible ramp */
-static void
-reset_sample_memory(void)
+static void reset_sample_memory(void)
{
- int i;
+ int i;
for (i = 0; i <= MAX_SAMPLE; i++)
sample_ptrs[i] = -1;
@@ -206,17 +210,15 @@ reset_sample_memory(void)
patch_table[i] = NOT_SAMPLE;
}
-void
-gus_delay(void)
+void gus_delay(void)
{
- int i;
+ int i;
for (i = 0; i < 7; i++)
inb(u_DRAMIO);
}
-static void
-gus_poke(long addr, unsigned char data)
+static void gus_poke(long addr, unsigned char data)
{ /* Writes a byte to the DRAM */
unsigned long flags;
@@ -232,8 +234,7 @@ gus_poke(long addr, unsigned char data)
restore_flags(flags);
}
-static unsigned char
-gus_peek(long addr)
+static unsigned char gus_peek(long addr)
{ /* Reads a byte from the DRAM */
unsigned long flags;
unsigned char tmp;
@@ -252,8 +253,7 @@ gus_peek(long addr)
return tmp;
}
-void
-gus_write8(int reg, unsigned int data)
+void gus_write8(int reg, unsigned int data)
{ /* Writes to an indirect register (8 bit) */
unsigned long flags;
@@ -266,9 +266,9 @@ gus_write8(int reg, unsigned int data)
restore_flags(flags);
}
-static unsigned char
-gus_read8(int reg)
-{ /* Reads from an indirect register (8 bit). Offset 0x80. */
+static unsigned char gus_read8(int reg)
+{
+ /* Reads from an indirect register (8 bit). Offset 0x80. */
unsigned long flags;
unsigned char val;
@@ -281,9 +281,9 @@ gus_read8(int reg)
return val;
}
-static unsigned char
-gus_look8(int reg)
-{ /* Reads from an indirect register (8 bit). No additional offset. */
+static unsigned char gus_look8(int reg)
+{
+ /* Reads from an indirect register (8 bit). No additional offset. */
unsigned long flags;
unsigned char val;
@@ -296,9 +296,9 @@ gus_look8(int reg)
return val;
}
-static void
-gus_write16(int reg, unsigned int data)
-{ /* Writes to an indirect register (16 bit) */
+static void gus_write16(int reg, unsigned int data)
+{
+ /* Writes to an indirect register (16 bit) */
unsigned long flags;
save_flags(flags);
@@ -312,9 +312,9 @@ gus_write16(int reg, unsigned int data)
restore_flags(flags);
}
-static unsigned short
-gus_read16(int reg)
-{ /* Reads from an indirect register (16 bit). Offset 0x80. */
+static unsigned short gus_read16(int reg)
+{
+ /* Reads from an indirect register (16 bit). Offset 0x80. */
unsigned long flags;
unsigned char hi, lo;
@@ -331,9 +331,9 @@ gus_read16(int reg)
return ((hi << 8) & 0xff00) | lo;
}
-static unsigned short
-gus_look16(int reg)
-{ /* Reads from an indirect register (16 bit). No additional offset. */
+static unsigned short gus_look16(int reg)
+{
+ /* Reads from an indirect register (16 bit). No additional offset. */
unsigned long flags;
unsigned char hi, lo;
@@ -350,32 +350,33 @@ gus_look16(int reg)
return ((hi << 8) & 0xff00) | lo;
}
-static void
-gus_write_addr(int reg, unsigned long address, int frac, int is16bit)
-{ /* Writes an 24 bit memory address */
+static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit)
+{
+ /* Writes an 24 bit memory address */
unsigned long hold_address;
unsigned long flags;
save_flags(flags);
cli();
if (is16bit)
- {
- if (iw_mode)
- {
- /* Interwave spesific address translations */
- address >>= 1;
- } else
- {
- /*
- * Special processing required for 16 bit patches
- */
-
- hold_address = address;
- address = address >> 1;
- address &= 0x0001ffffL;
- address |= (hold_address & 0x000c0000L);
- }
- }
+ {
+ if (iw_mode)
+ {
+ /* Interwave spesific address translations */
+ address >>= 1;
+ }
+ else
+ {
+ /*
+ * Special processing required for 16 bit patches
+ */
+
+ hold_address = address;
+ address = address >> 1;
+ address &= 0x0001ffffL;
+ address |= (hold_address & 0x000c0000L);
+ }
+ }
gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
+ (frac << 5));
@@ -387,17 +388,14 @@ gus_write_addr(int reg, unsigned long address, int frac, int is16bit)
restore_flags(flags);
}
-static void
-gus_select_voice(int voice)
+static void gus_select_voice(int voice)
{
if (voice < 0 || voice > 31)
return;
-
outb((voice), u_Voice);
}
-static void
-gus_select_max_voices(int nvoices)
+static void gus_select_max_voices(int nvoices)
{
if (iw_mode)
nvoices = 32;
@@ -407,26 +405,22 @@ gus_select_max_voices(int nvoices)
nvoices = 32;
voice_alloc->max_voice = nr_voices = nvoices;
-
gus_write8(0x0e, (nvoices - 1) | 0xc0);
}
-static void
-gus_voice_on(unsigned int mode)
+static void gus_voice_on(unsigned int mode)
{
gus_write8(0x00, (unsigned char) (mode & 0xfc));
gus_delay();
gus_write8(0x00, (unsigned char) (mode & 0xfc));
}
-static void
-gus_voice_off(void)
+static void gus_voice_off(void)
{
gus_write8(0x00, gus_read8(0x00) | 0x03);
}
-static void
-gus_voice_mode(unsigned int m)
+static void gus_voice_mode(unsigned int m)
{
unsigned char mode = (unsigned char) (m & 0xff);
@@ -436,8 +430,7 @@ gus_voice_mode(unsigned int m)
gus_write8(0x00, (gus_read8(0x00) & 0x03) | (mode & 0xfc));
}
-static void
-gus_voice_freq(unsigned long freq)
+static void gus_voice_freq(unsigned long freq)
{
unsigned long divisor = freq_div_table[nr_voices - 14];
unsigned short fc;
@@ -452,34 +445,29 @@ gus_voice_freq(unsigned long freq)
gus_write16(0x01, fc);
}
-static void
-gus_voice_volume(unsigned int vol)
+static void gus_voice_volume(unsigned int vol)
{
gus_write8(0x0d, 0x03); /* Stop ramp before setting volume */
gus_write16(0x09, (unsigned short) (vol << 4));
}
-static void
-gus_voice_balance(unsigned int balance)
+static void gus_voice_balance(unsigned int balance)
{
gus_write8(0x0c, (unsigned char) (balance & 0xff));
}
-static void
-gus_ramp_range(unsigned int low, unsigned int high)
+static void gus_ramp_range(unsigned int low, unsigned int high)
{
gus_write8(0x07, (unsigned char) ((low >> 4) & 0xff));
gus_write8(0x08, (unsigned char) ((high >> 4) & 0xff));
}
-static void
-gus_ramp_rate(unsigned int scale, unsigned int rate)
+static void gus_ramp_rate(unsigned int scale, unsigned int rate)
{
gus_write8(0x06, (unsigned char) (((scale & 0x03) << 6) | (rate & 0x3f)));
}
-static void
-gus_rampon(unsigned int m)
+static void gus_rampon(unsigned int m)
{
unsigned char mode = (unsigned char) (m & 0xff);
@@ -488,10 +476,9 @@ gus_rampon(unsigned int m)
gus_write8(0x0d, mode & 0xfc);
}
-static void
-gus_ramp_mode(unsigned int m)
+static void gus_ramp_mode(unsigned int m)
{
- unsigned char mode = (unsigned char) (m & 0xff);
+ unsigned char mode = (unsigned char) (m & 0xff);
gus_write8(0x0d, (gus_read8(0x0d) & 0x03) |
(mode & 0xfc)); /* Leave the last 2 bits alone */
@@ -499,16 +486,14 @@ gus_ramp_mode(unsigned int m)
gus_write8(0x0d, (gus_read8(0x0d) & 0x03) | (mode & 0xfc));
}
-static void
-gus_rampoff(void)
+static void gus_rampoff(void)
{
gus_write8(0x0d, 0x03);
}
-static void
-gus_set_voice_pos(int voice, long position)
+static void gus_set_voice_pos(int voice, long position)
{
- int sample_no;
+ int sample_no;
if ((sample_no = sample_map[voice]) != -1)
if (position < samples[sample_no].len)
@@ -519,8 +504,7 @@ gus_set_voice_pos(int voice, long position)
samples[sample_no].mode & WAVE_16_BITS);
}
-static void
-gus_voice_init(int voice)
+static void gus_voice_init(int voice)
{
unsigned long flags;
@@ -538,8 +522,7 @@ gus_voice_init(int voice)
}
-static void
-gus_voice_init2(int voice)
+static void gus_voice_init2(int voice)
{
voices[voice].panning = 0;
voices[voice].mode = 0;
@@ -561,30 +544,30 @@ gus_voice_init2(int voice)
voices[voice].fixed_pitch = 0;
}
-static void
-step_envelope(int voice)
+static void step_envelope(int voice)
{
unsigned vol, prev_vol, phase;
unsigned char rate;
long int flags;
if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
- {
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_rampoff();
- restore_flags(flags);
- return;
- /*
- * Sustain phase begins. Continue envelope after receiving note off.
- */
- }
+ {
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_rampoff();
+ restore_flags(flags);
+ return;
+ /*
+ * Sustain phase begins. Continue envelope after receiving note off.
+ */
+ }
if (voices[voice].env_phase >= 5)
- { /* Envelope finished. Shoot the voice down */
- gus_voice_init(voice);
- return;
- }
+ {
+ /* Envelope finished. Shoot the voice down */
+ gus_voice_init(voice);
+ return;
+ }
prev_vol = voices[voice].current_volume;
phase = ++voices[voice].env_phase;
compute_volume(voice, voices[voice].midi_volume);
@@ -603,30 +586,30 @@ step_envelope(int voice)
voices[voice].volume_irq_mode = VMODE_ENVELOPE;
if (((vol - prev_vol) / 64) == 0) /* No significant volume change */
- {
- restore_flags(flags);
- step_envelope(voice); /* Continue the envelope on the next step */
- return;
- }
+ {
+ restore_flags(flags);
+ step_envelope(voice); /* Continue the envelope on the next step */
+ return;
+ }
if (vol > prev_vol)
- {
- if (vol >= (4096 - 64))
- vol = 4096 - 65;
- gus_ramp_range(0, vol);
- gus_rampon(0x20); /* Increasing volume, with IRQ */
- } else
- {
- if (vol <= 64)
- vol = 65;
- gus_ramp_range(vol, 4030);
- gus_rampon(0x60); /* Decreasing volume, with IRQ */
- }
+ {
+ if (vol >= (4096 - 64))
+ vol = 4096 - 65;
+ gus_ramp_range(0, vol);
+ gus_rampon(0x20); /* Increasing volume, with IRQ */
+ }
+ else
+ {
+ if (vol <= 64)
+ vol = 65;
+ gus_ramp_range(vol, 4030);
+ gus_rampon(0x60); /* Decreasing volume, with IRQ */
+ }
voices[voice].current_volume = vol;
restore_flags(flags);
}
-static void
-init_envelope(int voice)
+static void init_envelope(int voice)
{
voices[voice].env_phase = -1;
voices[voice].current_volume = 64;
@@ -634,17 +617,15 @@ init_envelope(int voice)
step_envelope(voice);
}
-static void
-start_release(int voice, long int flags)
+static void start_release(int voice, long int flags)
{
if (gus_read8(0x00) & 0x03)
return; /* Voice already stopped */
voices[voice].env_phase = 2; /* Will be incremented by step_envelope */
- voices[voice].current_volume =
- voices[voice].initial_volume =
- gus_read16(0x09) >> 4; /* Get current volume */
+ voices[voice].current_volume = voices[voice].initial_volume =
+ gus_read16(0x09) >> 4; /* Get current volume */
voices[voice].mode &= ~WAVE_SUSTAIN_ON;
gus_rampoff();
@@ -652,42 +633,41 @@ start_release(int voice, long int flags)
step_envelope(voice);
}
-static void
-gus_voice_fade(int voice)
+static void gus_voice_fade(int voice)
{
- int instr_no = sample_map[voice], is16bits;
- long int flags;
+ int instr_no = sample_map[voice], is16bits;
+ long int flags;
save_flags(flags);
cli();
gus_select_voice(voice);
if (instr_no < 0 || instr_no > MAX_SAMPLE)
- {
- gus_write8(0x00, 0x03); /* Hard stop */
- voice_alloc->map[voice] = 0;
- restore_flags(flags);
- return;
- }
+ {
+ gus_write8(0x00, 0x03); /* Hard stop */
+ voice_alloc->map[voice] = 0;
+ restore_flags(flags);
+ return;
+ }
is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /* 8 or 16 bits */
if (voices[voice].mode & WAVE_ENVELOPES)
- {
- start_release(voice, flags);
- restore_flags(flags);
- return;
- }
+ {
+ start_release(voice, flags);
+ restore_flags(flags);
+ return;
+ }
/*
* Ramp the volume down but not too quickly.
*/
if ((int) (gus_read16(0x09) >> 4) < 100) /* Get current volume */
- {
- gus_voice_off();
- gus_rampoff();
- gus_voice_init(voice);
- restore_flags(flags);
- return;
- }
+ {
+ gus_voice_off();
+ gus_rampoff();
+ gus_voice_init(voice);
+ restore_flags(flags);
+ return;
+ }
gus_ramp_range(65, 4030);
gus_ramp_rate(2, 4);
gus_rampon(0x40 | 0x20); /* Down, once, with IRQ */
@@ -695,10 +675,9 @@ gus_voice_fade(int voice)
restore_flags(flags);
}
-static void
-gus_reset(void)
+static void gus_reset(void)
{
- int i;
+ int i;
gus_select_max_voices(24);
volume_base = 3071;
@@ -706,23 +685,24 @@ gus_reset(void)
volume_method = VOL_METHOD_ADAGIO;
for (i = 0; i < 32; i++)
- {
- gus_voice_init(i); /* Turn voice off */
- gus_voice_init2(i);
- }
+ {
+ gus_voice_init(i); /* Turn voice off */
+ gus_voice_init2(i);
+ }
}
-static void
-gus_initialize(void)
+static void gus_initialize(void)
{
- unsigned long flags;
- unsigned char dma_image, irq_image, tmp;
+ unsigned long flags;
+ unsigned char dma_image, irq_image, tmp;
- static unsigned char gus_irq_map[16] =
- {0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7};
+ static unsigned char gus_irq_map[16] = {
+ 0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7
+ };
- static unsigned char gus_dma_map[8] =
- {0, 1, 0, 2, 0, 3, 4, 5};
+ static unsigned char gus_dma_map[8] = {
+ 0, 1, 0, 2, 0, 3, 4, 5
+ };
save_flags(flags);
cli();
@@ -784,37 +764,39 @@ gus_initialize(void)
irq_image = 0;
tmp = gus_irq_map[gus_irq];
if (!gus_pnp_flag && !tmp)
- printk("Warning! GUS IRQ not selected\n");
+ printk(KERN_WARNING "Warning! GUS IRQ not selected\n");
irq_image |= tmp;
irq_image |= 0x40; /* Combine IRQ1 (GF1) and IRQ2 (Midi) */
dual_dma_mode = 1;
if (gus_dma2 == gus_dma || gus_dma2 == -1)
- {
- dual_dma_mode = 0;
- dma_image = 0x40; /* Combine DMA1 (DRAM) and IRQ2 (ADC) */
+ {
+ dual_dma_mode = 0;
+ dma_image = 0x40; /* Combine DMA1 (DRAM) and IRQ2 (ADC) */
- tmp = gus_dma_map[gus_dma];
- if (!tmp)
- printk("Warning! GUS DMA not selected\n");
+ tmp = gus_dma_map[gus_dma];
+ if (!tmp)
+ printk(KERN_WARNING "Warning! GUS DMA not selected\n");
- dma_image |= tmp;
- } else
+ dma_image |= tmp;
+ }
+ else
+ {
/* Setup dual DMA channel mode for GUS MAX */
- {
- dma_image = gus_dma_map[gus_dma];
- if (!dma_image)
- printk("Warning! GUS DMA not selected\n");
-
- tmp = gus_dma_map[gus_dma2] << 3;
- if (!tmp)
- {
- printk("Warning! Invalid GUS MAX DMA\n");
- tmp = 0x40; /* Combine DMA channels */
+
+ dma_image = gus_dma_map[gus_dma];
+ if (!dma_image)
+ printk(KERN_WARNING "Warning! GUS DMA not selected\n");
+
+ tmp = gus_dma_map[gus_dma2] << 3;
+ if (!tmp)
+ {
+ printk(KERN_WARNING "Warning! Invalid GUS MAX DMA\n");
+ tmp = 0x40; /* Combine DMA channels */
dual_dma_mode = 0;
- }
- dma_image |= tmp;
- }
+ }
+ dma_image |= tmp;
+ }
/*
* For some reason the IRQ and DMA addresses must be written twice
@@ -845,8 +827,8 @@ gus_initialize(void)
mix_image &= ~0x02; /* Enable line out */
mix_image |= 0x08; /* Enable IRQ */
outb((mix_image), u_Mixer); /*
- * Turn mixer channels on
- * Note! Mic in is left off.
+ * Turn mixer channels on
+ * Note! Mic in is left off.
*/
gus_select_voice(0); /* This disables writes to IRQ/DMA reg */
@@ -866,17 +848,16 @@ gus_initialize(void)
}
-static void
-pnp_mem_init(void)
+static void pnp_mem_init(void)
{
#include "iwmem.h"
#define CHUNK_SIZE (256*1024)
#define BANK_SIZE (4*1024*1024)
#define CHUNKS_PER_BANK (BANK_SIZE/CHUNK_SIZE)
- int bank, chunk, addr, total = 0;
- int bank_sizes[4];
- int i, j, bits = -1, nbanks = 0;
+ int bank, chunk, addr, total = 0;
+ 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
@@ -899,133 +880,137 @@ pnp_mem_init(void)
* Perform the DRAM size detection for each bank individually.
*/
for (bank = 0; bank < 4; bank++)
- {
- int size = 0;
+ {
+ int size = 0;
- addr = bank * BANK_SIZE;
+ addr = bank * BANK_SIZE;
- /* Clean check points of each chunk */
- for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
- {
- gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
- gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
- }
+ /* Clean check points of each chunk */
+ for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
+ {
+ gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
+ gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
+ }
- /* Write a value to each chunk point and verify the result */
- for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
- {
- gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x55);
- gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0xAA);
+ /* Write a value to each chunk point and verify the result */
+ for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
+ {
+ gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x55);
+ gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0xAA);
- if (gus_peek(addr + chunk * CHUNK_SIZE + 0L) == 0x55 &&
+ if (gus_peek(addr + chunk * CHUNK_SIZE + 0L) == 0x55 &&
gus_peek(addr + chunk * CHUNK_SIZE + 1L) == 0xAA)
- { /* OK. There is RAM. Now check for possible shadows */
- int ok = 1, chunk2;
-
- for (chunk2 = 0; ok && chunk2 < chunk; chunk2++)
- if (gus_peek(addr + chunk2 * CHUNK_SIZE + 0L) ||
- gus_peek(addr + chunk2 * CHUNK_SIZE + 1L))
- ok = 0; /* Addressing wraps */
-
- if (ok)
- size = (chunk + 1) * CHUNK_SIZE;
- }
- gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
- gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
- }
-
- bank_sizes[bank] = size;
- if (size)
- nbanks = bank + 1;
- DDB(printk("Interwave: Bank %d, size=%dk\n", bank, size / 1024));
- }
+ {
+ /* OK. There is RAM. Now check for possible shadows */
+ int ok = 1, chunk2;
+
+ for (chunk2 = 0; ok && chunk2 < chunk; chunk2++)
+ if (gus_peek(addr + chunk2 * CHUNK_SIZE + 0L) ||
+ gus_peek(addr + chunk2 * CHUNK_SIZE + 1L))
+ ok = 0; /* Addressing wraps */
+
+ if (ok)
+ size = (chunk + 1) * CHUNK_SIZE;
+ }
+ gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
+ gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
+ }
+ bank_sizes[bank] = size;
+ if (size)
+ nbanks = bank + 1;
+ DDB(printk("Interwave: Bank %d, size=%dk\n", bank, size / 1024));
+ }
if (nbanks == 0) /* No RAM - Give up */
- {
- printk("Sound: An Interwave audio chip detected but no DRAM\n");
- printk("Sound: Unable to work with this card.\n");
- gus_write8(0x19, gus_read8(0x19) & ~0x01);
- gus_mem_size = 0;
- return;
- }
-/*
- * Now we know how much DRAM there is in each bank. The next step is
- * to find a DRAM size encoding (0 to 12) which is best for the combination
- * we have.
- *
- * First try if any of the possible alternatives matches exactly the amount
- * of memory we have.
- */
+ {
+ printk(KERN_ERR "Sound: An Interwave audio chip detected but no DRAM\n");
+ printk(KERN_ERR "Sound: Unable to work with this card.\n");
+ gus_write8(0x19, gus_read8(0x19) & ~0x01);
+ gus_mem_size = 0;
+ return;
+ }
+
+ /*
+ * Now we know how much DRAM there is in each bank. The next step is
+ * to find a DRAM size encoding (0 to 12) which is best for the combination
+ * we have.
+ *
+ * First try if any of the possible alternatives matches exactly the amount
+ * of memory we have.
+ */
for (i = 0; bits == -1 && i < 13; i++)
- {
- bits = i;
+ {
+ bits = i;
- for (j = 0; bits != -1 && j < 4; j++)
- if (mem_decode[i][j] != bank_sizes[j])
- bits = -1; /* No hit */
- }
+ for (j = 0; bits != -1 && j < 4; j++)
+ if (mem_decode[i][j] != bank_sizes[j])
+ bits = -1; /* No hit */
+ }
+
+ /*
+ * If necessary, try to find a combination where other than the last
+ * bank matches our configuration and the last bank is left oversized.
+ * In this way we don't leave holes in the middle of memory.
+ */
-/*
- * If necessary, try to find a combination where other than the last
- * bank matches our configuration and the last bank is left oversized.
- * In this way we don't leave holes in the middle of memory.
- */
if (bits == -1) /* No luck yet */
+ {
for (i = 0; bits == -1 && i < 13; i++)
- {
- bits = i;
-
- for (j = 0; bits != -1 && j < nbanks - 1; j++)
- if (mem_decode[i][j] != bank_sizes[j])
- bits = -1; /* No hit */
- if (mem_decode[i][nbanks - 1] < bank_sizes[nbanks - 1])
- bits = -1; /* The last bank is too small */
- }
-/*
- * The last resort is to search for a combination where the last bank is
- * smaller than the actual SIMM. This leaves some memory in the last bank
- * unused but doesn't leave holes in the DRAM address space.
- */
+ {
+ bits = i;
+
+ for (j = 0; bits != -1 && j < nbanks - 1; j++)
+ if (mem_decode[i][j] != bank_sizes[j])
+ bits = -1; /* No hit */
+ if (mem_decode[i][nbanks - 1] < bank_sizes[nbanks - 1])
+ bits = -1; /* The last bank is too small */
+ }
+ }
+ /*
+ * The last resort is to search for a combination where the last bank is
+ * smaller than the actual SIMM. This leaves some memory in the last bank
+ * unused but doesn't leave holes in the DRAM address space.
+ */
if (bits == -1) /* No luck yet */
- {
- for (i = 0; bits == -1 && i < 13; i++)
- {
- bits = i;
-
- for (j = 0; bits != -1 && j < nbanks - 1; j++)
- if (mem_decode[i][j] != bank_sizes[j])
- bits = -1; /* No hit */
- }
-
- if (bits != -1)
- {
- printk("Interwave: Can't use all installed RAM.\n");
- printk("Interwave: Try reordering SIMMS.\n");
- }
- }
+ {
+ for (i = 0; bits == -1 && i < 13; i++)
+ {
+ bits = i;
+
+ for (j = 0; bits != -1 && j < nbanks - 1; j++)
+ if (mem_decode[i][j] != bank_sizes[j])
+ bits = -1; /* No hit */
+ }
+ if (bits != -1)
+ {
+ printk(KERN_INFO "Interwave: Can't use all installed RAM.\n");
+ printk(KERN_INFO "Interwave: Try reordering SIMMS.\n");
+ }
+ }
if (bits == -1)
- {
- printk("Interwave: Can't find working DRAM encoding.\n");
- printk("Interwave: Defaulting to 256k. Try reordering SIMMS.\n");
- bits = 0;
- }
+ {
+ printk(KERN_INFO "Interwave: Can't find working DRAM encoding.\n");
+ printk(KERN_INFO "Interwave: Defaulting to 256k. Try reordering SIMMS.\n");
+ bits = 0;
+ }
DDB(printk("Interwave: Selecting DRAM addressing mode %d\n", bits));
for (bank = 0; bank < 4; bank++)
- {
- DDB(printk(" Bank %d, mem=%dk (limit %dk)\n", bank, bank_sizes[bank] / 1024, mem_decode[bits][bank] / 1024));
+ {
+ DDB(printk(" Bank %d, mem=%dk (limit %dk)\n", bank, bank_sizes[bank] / 1024, mem_decode[bits][bank] / 1024));
- if (bank_sizes[bank] > mem_decode[bits][bank])
- total += mem_decode[bits][bank];
- else
- total += bank_sizes[bank];
- }
+ if (bank_sizes[bank] > mem_decode[bits][bank])
+ total += mem_decode[bits][bank];
+ else
+ total += bank_sizes[bank];
+ }
DDB(printk("Total %dk of DRAM (enhanced mode)\n", total / 1024));
-/*
- * Set the memory addressing mode.
- */
+
+ /*
+ * Set the memory addressing mode.
+ */
gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | bits);
/* Leave the chip into enhanced mode. Disable LFO */
@@ -1034,8 +1019,7 @@ pnp_mem_init(void)
gus_write8(0x19, (gus_read8(0x19) | 0x01) & ~0x02);
}
-int
-gus_wave_detect(int baseaddr)
+int gus_wave_detect(int baseaddr)
{
unsigned long i, max_mem = 1024L;
unsigned long loc;
@@ -1056,15 +1040,18 @@ gus_wave_detect(int baseaddr)
gus_write8(0x5b, ~val); /* Invert all bits */
if ((gus_look8(0x5b) & 0xf0) == (val & 0xf0)) /* No change */
+ {
if ((gus_look8(0x5b) & 0x0f) == ((~val) & 0x0f)) /* Change */
- {
- DDB(printk("Interwave chip version %d detected\n", (val & 0xf0) >> 4));
- gus_pnp_flag = 1;
- } else
- {
- DDB(printk("Not an Interwave chip (%x)\n", gus_look8(0x5b)));
- gus_pnp_flag = 0;
- }
+ {
+ DDB(printk("Interwave chip version %d detected\n", (val & 0xf0) >> 4));
+ gus_pnp_flag = 1;
+ }
+ else
+ {
+ DDB(printk("Not an Interwave chip (%x)\n", gus_look8(0x5b)));
+ gus_pnp_flag = 0;
+ }
+ }
gus_write8(0x5b, val); /* Restore all bits */
#endif
@@ -1081,66 +1068,59 @@ gus_wave_detect(int baseaddr)
/* Now zero it out so that I can check for mirroring .. */
gus_poke(0L, 0x00);
for (i = 1L; i < max_mem; i++)
- {
- int n, failed;
-
- /* check for mirroring ... */
- if (gus_peek(0L) != 0)
- break;
- loc = i << 10;
-
- for (n = loc - 1, failed = 0; n <= loc; n++)
- {
- gus_poke(loc, 0xaa);
- if (gus_peek(loc) != 0xaa)
- failed = 1;
-
- gus_poke(loc, 0x55);
- if (gus_peek(loc) != 0x55)
- failed = 1;
- }
-
- if (failed)
- break;
- }
+ {
+ int n, failed;
+
+ /* check for mirroring ... */
+ if (gus_peek(0L) != 0)
+ break;
+ loc = i << 10;
+
+ for (n = loc - 1, failed = 0; n <= loc; n++)
+ {
+ gus_poke(loc, 0xaa);
+ if (gus_peek(loc) != 0xaa)
+ failed = 1;
+ gus_poke(loc, 0x55);
+ if (gus_peek(loc) != 0x55)
+ failed = 1;
+ }
+ if (failed)
+ break;
+ }
gus_mem_size = i << 10;
return 1;
}
-static int
-guswave_ioctl(int dev,
- unsigned int cmd, caddr_t arg)
+static int guswave_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- switch (cmd)
- {
- case SNDCTL_SYNTH_INFO:
- gus_info.nr_voices = nr_voices;
- memcpy((&((char *) arg)[0]), (char *) &gus_info, sizeof(gus_info));
- return 0;
- break;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- reset_sample_memory();
- return 0;
- break;
-
- case SNDCTL_SEQ_PERCMODE:
- return 0;
- break;
-
- case SNDCTL_SYNTH_MEMAVL:
- return (gus_mem_size == 0) ? 0 : gus_mem_size - free_mem_ptr - 32;
-
- default:
- return -EINVAL;
- }
+ switch (cmd)
+ {
+ case SNDCTL_SYNTH_INFO:
+ gus_info.nr_voices = nr_voices;
+ if (copy_to_user(arg, &gus_info, sizeof(gus_info)))
+ return -EFAULT;
+ return 0;
+
+ case SNDCTL_SEQ_RESETSAMPLES:
+ reset_sample_memory();
+ return 0;
+
+ case SNDCTL_SEQ_PERCMODE:
+ return 0;
+
+ case SNDCTL_SYNTH_MEMAVL:
+ return (gus_mem_size == 0) ? 0 : gus_mem_size - free_mem_ptr - 32;
+
+ default:
+ return -EINVAL;
+ }
}
-static int
-guswave_set_instr(int dev, int voice, int instr_no)
+static int guswave_set_instr(int dev, int voice, int instr_no)
{
- int sample_no;
+ int sample_no;
if (instr_no < 0 || instr_no > MAX_PATCH)
instr_no = 0; /* Default to acoustic piano */
@@ -1149,103 +1129,97 @@ guswave_set_instr(int dev, int voice, int instr_no)
return -EINVAL;
if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- {
- voices[voice].sample_pending = instr_no;
- return 0;
- }
+ {
+ voices[voice].sample_pending = instr_no;
+ return 0;
+ }
sample_no = patch_table[instr_no];
patch_map[voice] = -1;
if (sample_no == NOT_SAMPLE)
- {
- printk("GUS: Undefined patch %d for voice %d\n", instr_no, voice);
- return -EINVAL; /* Patch not defined */
- }
+ {
+/* printk("GUS: Undefined patch %d for voice %d\n", instr_no, voice);*/
+ return -EINVAL; /* Patch not defined */
+ }
if (sample_ptrs[sample_no] == -1) /* Sample not loaded */
- {
- printk("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice);
- return -EINVAL;
- }
+ {
+/* printk("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice);*/
+ return -EINVAL;
+ }
sample_map[voice] = sample_no;
patch_map[voice] = instr_no;
return 0;
}
-static int
-guswave_kill_note(int dev, int voice, int note, int velocity)
+static int guswave_kill_note(int dev, int voice, int note, int velocity)
{
- unsigned long flags;
+ unsigned long flags;
save_flags(flags);
cli();
/* voice_alloc->map[voice] = 0xffff; */
if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- {
- voices[voice].kill_pending = 1;
- restore_flags(flags);
- } else
- {
- restore_flags(flags);
- gus_voice_fade(voice);
- }
+ {
+ voices[voice].kill_pending = 1;
+ restore_flags(flags);
+ }
+ else
+ {
+ restore_flags(flags);
+ gus_voice_fade(voice);
+ }
restore_flags(flags);
return 0;
}
-static void
-guswave_aftertouch(int dev, int voice, int pressure)
+static void guswave_aftertouch(int dev, int voice, int pressure)
{
}
-static void
-guswave_panning(int dev, int voice, int value)
+static void guswave_panning(int dev, int voice, int value)
{
if (voice >= 0 || voice < 32)
voices[voice].panning = value;
}
-static void
-guswave_volume_method(int dev, int mode)
+static void guswave_volume_method(int dev, int mode)
{
if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO)
volume_method = mode;
}
-static void
-compute_volume(int voice, int volume)
+static void compute_volume(int voice, int volume)
{
if (volume < 128)
voices[voice].midi_volume = volume;
switch (volume_method)
- {
- case VOL_METHOD_ADAGIO:
- voices[voice].initial_volume =
- gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol,
- voices[voice].expression_vol,
- voices[voice].patch_vol);
- break;
-
- case VOL_METHOD_LINEAR: /* Totally ignores patch-volume and expression */
- voices[voice].initial_volume =
- gus_linear_vol(volume, voices[voice].main_vol);
- break;
-
- default:
- voices[voice].initial_volume = volume_base +
- (voices[voice].midi_volume * volume_scale);
- }
+ {
+ case VOL_METHOD_ADAGIO:
+ voices[voice].initial_volume =
+ gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol,
+ voices[voice].expression_vol,
+ voices[voice].patch_vol);
+ break;
+
+ case VOL_METHOD_LINEAR: /* Totally ignores patch-volume and expression */
+ voices[voice].initial_volume = gus_linear_vol(volume, voices[voice].main_vol);
+ break;
+
+ default:
+ voices[voice].initial_volume = volume_base +
+ (voices[voice].midi_volume * volume_scale);
+ }
if (voices[voice].initial_volume > 4030)
voices[voice].initial_volume = 4030;
}
-static void
-compute_and_set_volume(int voice, int volume, int ramp_time)
+static void compute_and_set_volume(int voice, int volume, int ramp_time)
{
- int curr, target, rate;
- unsigned long flags;
+ int curr, target, rate;
+ unsigned long flags;
compute_volume(voice, volume);
voices[voice].current_volume = voices[voice].initial_volume;
@@ -1253,7 +1227,7 @@ compute_and_set_volume(int voice, int volume, int ramp_time)
save_flags(flags);
cli();
/*
- * CAUTION! Interrupts disabled. Enable them before returning
+ * CAUTION! Interrupts disabled. Enable them before returning
*/
gus_select_voice(voice);
@@ -1262,12 +1236,12 @@ compute_and_set_volume(int voice, int volume, int ramp_time)
target = voices[voice].initial_volume;
if (ramp_time == INSTANT_RAMP)
- {
- gus_rampoff();
- gus_voice_volume(target);
- restore_flags(flags);
- return;
- }
+ {
+ gus_rampoff();
+ gus_voice_volume(target);
+ restore_flags(flags);
+ return;
+ }
if (ramp_time == FAST_RAMP)
rate = 63;
else
@@ -1275,34 +1249,34 @@ compute_and_set_volume(int voice, int volume, int ramp_time)
gus_ramp_rate(0, rate);
if ((target - curr) / 64 == 0) /* Close enough to target. */
- {
- gus_rampoff();
- gus_voice_volume(target);
- restore_flags(flags);
- return;
- }
+ {
+ gus_rampoff();
+ gus_voice_volume(target);
+ restore_flags(flags);
+ return;
+ }
if (target > curr)
- {
- if (target > (4095 - 65))
- target = 4095 - 65;
- gus_ramp_range(curr, target);
- gus_rampon(0x00); /* Ramp up, once, no IRQ */
- } else
- {
- if (target < 65)
- target = 65;
-
- gus_ramp_range(target, curr);
- gus_rampon(0x40); /* Ramp down, once, no irq */
- }
+ {
+ if (target > (4095 - 65))
+ target = 4095 - 65;
+ gus_ramp_range(curr, target);
+ gus_rampon(0x00); /* Ramp up, once, no IRQ */
+ }
+ else
+ {
+ if (target < 65)
+ target = 65;
+
+ gus_ramp_range(target, curr);
+ gus_rampon(0x40); /* Ramp down, once, no irq */
+ }
restore_flags(flags);
}
-static void
-dynamic_volume_change(int voice)
+static void dynamic_volume_change(int voice)
{
- unsigned char status;
- unsigned long flags;
+ unsigned char status;
+ unsigned long flags;
save_flags(flags);
cli();
@@ -1314,10 +1288,11 @@ dynamic_volume_change(int voice)
return; /* Voice was not running */
if (!(voices[voice].mode & WAVE_ENVELOPES))
- {
- compute_and_set_volume(voice, voices[voice].midi_volume, 1);
- return;
- }
+ {
+ compute_and_set_volume(voice, voices[voice].midi_volume, 1);
+ return;
+ }
+
/*
* Voice is running and has envelopes.
*/
@@ -1329,10 +1304,10 @@ dynamic_volume_change(int voice)
restore_flags(flags);
if (status & 0x03) /* Sustain phase? */
- {
- compute_and_set_volume(voice, voices[voice].midi_volume, 1);
- return;
- }
+ {
+ compute_and_set_volume(voice, voices[voice].midi_volume, 1);
+ return;
+ }
if (voices[voice].env_phase < 0)
return;
@@ -1340,8 +1315,7 @@ dynamic_volume_change(int voice)
}
-static void
-guswave_controller(int dev, int voice, int ctrl_num, int value)
+static void guswave_controller(int dev, int voice, int ctrl_num, int value)
{
unsigned long flags;
unsigned long freq;
@@ -1350,88 +1324,84 @@ guswave_controller(int dev, int voice, int ctrl_num, int value)
return;
switch (ctrl_num)
- {
- case CTRL_PITCH_BENDER:
- voices[voice].bender = value;
-
- if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
- {
- freq = compute_finetune(voices[voice].orig_freq, value,
- voices[voice].bender_range, 0);
- voices[voice].current_freq = freq;
-
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_voice_freq(freq);
- restore_flags(flags);
- }
- break;
-
- case CTRL_PITCH_BENDER_RANGE:
- voices[voice].bender_range = value;
- break;
- case CTL_EXPRESSION:
- value /= 128;
- case CTRL_EXPRESSION:
- if (volume_method == VOL_METHOD_ADAGIO)
- {
- voices[voice].expression_vol = value;
- if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
- dynamic_volume_change(voice);
- }
- break;
-
- case CTL_PAN:
- voices[voice].panning = (value * 2) - 128;
- break;
-
- case CTL_MAIN_VOLUME:
- value = (value * 100) / 16383;
-
- case CTRL_MAIN_VOLUME:
- voices[voice].main_vol = value;
- if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
- dynamic_volume_change(voice);
- break;
-
- default:
- break;
- }
-}
-
-static int
-guswave_start_note2(int dev, int voice, int note_num, int volume)
-{
- int sample, best_sample, best_delta, delta_freq;
- int is16bits, samplep, patch, pan;
+ {
+ case CTRL_PITCH_BENDER:
+ voices[voice].bender = value;
+
+ if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
+ {
+ freq = compute_finetune(voices[voice].orig_freq, value, voices[voice].bender_range, 0);
+ voices[voice].current_freq = freq;
+
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_voice_freq(freq);
+ restore_flags(flags);
+ }
+ break;
+
+ case CTRL_PITCH_BENDER_RANGE:
+ voices[voice].bender_range = value;
+ break;
+ case CTL_EXPRESSION:
+ value /= 128;
+ case CTRL_EXPRESSION:
+ if (volume_method == VOL_METHOD_ADAGIO)
+ {
+ voices[voice].expression_vol = value;
+ if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
+ dynamic_volume_change(voice);
+ }
+ break;
+
+ case CTL_PAN:
+ voices[voice].panning = (value * 2) - 128;
+ break;
+
+ case CTL_MAIN_VOLUME:
+ value = (value * 100) / 16383;
+
+ case CTRL_MAIN_VOLUME:
+ voices[voice].main_vol = value;
+ if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
+ dynamic_volume_change(voice);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int guswave_start_note2(int dev, int voice, int note_num, int volume)
+{
+ int sample, best_sample, best_delta, delta_freq;
+ int is16bits, samplep, patch, pan;
unsigned long note_freq, base_note, freq, flags;
unsigned char mode = 0;
if (voice < 0 || voice > 31)
- {
- printk("GUS: Invalid voice\n");
- return -EINVAL;
- }
+ {
+/* printk("GUS: Invalid voice\n");*/
+ return -EINVAL;
+ }
if (note_num == 255)
- {
- if (voices[voice].mode & WAVE_ENVELOPES)
- {
- voices[voice].midi_volume = volume;
- dynamic_volume_change(voice);
- return 0;
- }
- compute_and_set_volume(voice, volume, 1);
- return 0;
- }
+ {
+ if (voices[voice].mode & WAVE_ENVELOPES)
+ {
+ voices[voice].midi_volume = volume;
+ dynamic_volume_change(voice);
+ return 0;
+ }
+ compute_and_set_volume(voice, volume, 1);
+ return 0;
+ }
if ((patch = patch_map[voice]) == -1)
- {
- return -EINVAL;
- }
+ return -EINVAL;
if ((samplep = patch_table[patch]) == NOT_SAMPLE)
- {
- return -EINVAL;
- }
+ {
+ return -EINVAL;
+ }
note_freq = note_to_freq(note_num);
/*
@@ -1443,29 +1413,31 @@ guswave_start_note2(int dev, int voice, int note_num, int volume)
best_sample = samplep;
best_delta = 1000000;
while (samplep != 0 && samplep != NOT_SAMPLE && sample == -1)
- {
- delta_freq = note_freq - samples[samplep].base_note;
- if (delta_freq < 0)
- delta_freq = -delta_freq;
- if (delta_freq < best_delta)
- {
- best_sample = samplep;
- best_delta = delta_freq;
- }
- if (samples[samplep].low_note <= note_freq &&
- note_freq <= samples[samplep].high_note)
- sample = samplep;
- else
- samplep = samples[samplep].key; /* Link to next sample */
+ {
+ delta_freq = note_freq - samples[samplep].base_note;
+ if (delta_freq < 0)
+ delta_freq = -delta_freq;
+ if (delta_freq < best_delta)
+ {
+ best_sample = samplep;
+ best_delta = delta_freq;
+ }
+ if (samples[samplep].low_note <= note_freq &&
+ note_freq <= samples[samplep].high_note)
+ {
+ sample = samplep;
+ }
+ else
+ samplep = samples[samplep].key; /* Link to next sample */
}
if (sample == -1)
sample = best_sample;
if (sample == -1)
- {
- printk("GUS: Patch %d not defined for note %d\n", patch, note_num);
- return 0; /* Should play default patch ??? */
- }
+ {
+/* printk("GUS: Patch %d not defined for note %d\n", patch, note_num);*/
+ return 0; /* Should play default patch ??? */
+ }
is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0;
voices[voice].mode = samples[sample].mode;
voices[voice].patch_vol = samples[sample].volume;
@@ -1474,27 +1446,28 @@ guswave_start_note2(int dev, int voice, int note_num, int volume)
gus_write8(0x15, 0x00); /* RAM, Reset voice deactivate bit of SMSI */
if (voices[voice].mode & WAVE_ENVELOPES)
- {
- int i;
-
- for (i = 0; i < 6; i++)
- {
- voices[voice].env_rate[i] = samples[sample].env_rate[i];
- voices[voice].env_offset[i] = samples[sample].env_offset[i];
- }
- }
+ {
+ int i;
+
+ for (i = 0; i < 6; i++)
+ {
+ voices[voice].env_rate[i] = samples[sample].env_rate[i];
+ voices[voice].env_offset[i] = samples[sample].env_offset[i];
+ }
+ }
sample_map[voice] = sample;
if (voices[voice].fixed_pitch) /* Fixed pitch */
- {
+ {
freq = samples[sample].base_freq;
- } else
- {
- base_note = samples[sample].base_note / 100;
- note_freq /= 100;
+ }
+ else
+ {
+ base_note = samples[sample].base_note / 100;
+ note_freq /= 100;
- freq = samples[sample].base_freq * note_freq / base_note;
- }
+ freq = samples[sample].base_freq * note_freq / base_note;
+ }
voices[voice].orig_freq = freq;
@@ -1515,15 +1488,15 @@ guswave_start_note2(int dev, int voice, int note_num, int volume)
pan = 15;
if (samples[sample].mode & WAVE_16_BITS)
- {
- mode |= 0x04; /* 16 bits */
- if ((sample_ptrs[sample] / GUS_BANK_SIZE) !=
- ((sample_ptrs[sample] + samples[sample].len) / GUS_BANK_SIZE))
- printk("GUS: Sample address error\n");
- }
- /*************************************************************************
- * CAUTION! Interrupts disabled. Don't return before enabling
- *************************************************************************/
+ {
+ mode |= 0x04; /* 16 bits */
+ if ((sample_ptrs[sample] / GUS_BANK_SIZE) !=
+ ((sample_ptrs[sample] + samples[sample].len) / GUS_BANK_SIZE))
+ printk(KERN_ERR "GUS: Sample address error\n");
+ }
+ /*************************************************************************
+ * CAUTION! Interrupts disabled. Don't return before enabling
+ *************************************************************************/
save_flags(flags);
cli();
@@ -1534,13 +1507,14 @@ guswave_start_note2(int dev, int voice, int note_num, int volume)
restore_flags(flags);
if (voices[voice].mode & WAVE_ENVELOPES)
- {
- compute_volume(voice, volume);
- init_envelope(voice);
- } else
- {
- compute_and_set_volume(voice, volume, 0);
- }
+ {
+ compute_volume(voice, volume);
+ init_envelope(voice);
+ }
+ else
+ {
+ compute_and_set_volume(voice, volume, 0);
+ }
save_flags(flags);
cli();
@@ -1548,43 +1522,38 @@ guswave_start_note2(int dev, int voice, int note_num, int volume)
if (samples[sample].mode & WAVE_LOOP_BACK)
gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].len -
- voices[voice].offset_pending, 0, is16bits); /* start=end */
+ voices[voice].offset_pending, 0, is16bits); /* start=end */
else
- gus_write_addr(0x0a, sample_ptrs[sample] + voices[voice].offset_pending,
- 0, is16bits); /* Sample start=begin */
+ gus_write_addr(0x0a, sample_ptrs[sample] + voices[voice].offset_pending, 0, is16bits); /* Sample start=begin */
if (samples[sample].mode & WAVE_LOOPING)
- {
- mode |= 0x08;
+ {
+ mode |= 0x08;
- if (samples[sample].mode & WAVE_BIDIR_LOOP)
- mode |= 0x10;
+ if (samples[sample].mode & WAVE_BIDIR_LOOP)
+ mode |= 0x10;
- if (samples[sample].mode & WAVE_LOOP_BACK)
- {
- gus_write_addr(0x0a,
- sample_ptrs[sample] + samples[sample].loop_end -
+ if (samples[sample].mode & WAVE_LOOP_BACK)
+ {
+ gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].loop_end -
voices[voice].offset_pending,
(samples[sample].fractions >> 4) & 0x0f, is16bits);
- mode |= 0x40;
- }
- gus_write_addr(0x02, sample_ptrs[sample] + samples[sample].loop_start,
- samples[sample].fractions & 0x0f,
- is16bits); /* Loop start location */
- gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].loop_end,
- (samples[sample].fractions >> 4) & 0x0f,
- is16bits); /* Loop end location */
- } else
- {
- mode |= 0x20; /* Loop IRQ at the end */
- voices[voice].loop_irq_mode = LMODE_FINISH; /* Ramp down at the end */
- voices[voice].loop_irq_parm = 1;
- gus_write_addr(0x02, sample_ptrs[sample],
- 0, is16bits); /* Loop start location */
- gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].len - 1,
- (samples[sample].fractions >> 4) & 0x0f,
- is16bits); /* Loop end location */
- }
+ mode |= 0x40;
+ }
+ gus_write_addr(0x02, sample_ptrs[sample] + samples[sample].loop_start,
+ samples[sample].fractions & 0x0f, is16bits); /* Loop start location */
+ gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].loop_end,
+ (samples[sample].fractions >> 4) & 0x0f, is16bits); /* Loop end location */
+ }
+ else
+ {
+ mode |= 0x20; /* Loop IRQ at the end */
+ voices[voice].loop_irq_mode = LMODE_FINISH; /* Ramp down at the end */
+ voices[voice].loop_irq_parm = 1;
+ gus_write_addr(0x02, sample_ptrs[sample], 0, is16bits); /* Loop start location */
+ gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].len - 1,
+ (samples[sample].fractions >> 4) & 0x0f, is16bits); /* Loop end location */
+ }
gus_voice_freq(freq);
gus_voice_balance(pan);
gus_voice_on(mode);
@@ -1599,82 +1568,81 @@ guswave_start_note2(int dev, int voice, int note_num, int volume)
* ramping.
*/
-static int
-guswave_start_note(int dev, int voice, int note_num, int volume)
+static int guswave_start_note(int dev, int voice, int note_num, int volume)
{
- long int flags;
- int mode;
- int ret_val = 0;
+ long int flags;
+ int mode;
+ int ret_val = 0;
save_flags(flags);
cli();
if (note_num == 255)
- {
- if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- {
- voices[voice].volume_pending = volume;
- } else
- {
- ret_val = guswave_start_note2(dev, voice, note_num, volume);
- }
- } else
- {
- gus_select_voice(voice);
- mode = gus_read8(0x00);
- if (mode & 0x20)
- gus_write8(0x00, mode & 0xdf); /* No interrupt! */
-
- voices[voice].offset_pending = 0;
- voices[voice].kill_pending = 0;
- voices[voice].volume_irq_mode = 0;
- voices[voice].loop_irq_mode = 0;
-
- if (voices[voice].sample_pending >= 0)
- {
- restore_flags(flags); /* Run temporarily with interrupts enabled */
- guswave_set_instr(voices[voice].dev_pending, voice,
- voices[voice].sample_pending);
- voices[voice].sample_pending = -1;
- save_flags(flags);
- cli();
- gus_select_voice(voice); /* Reselect the voice (just to be sure) */
- }
- if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < (unsigned) 2065))
- {
- ret_val = guswave_start_note2(dev, voice, note_num, volume);
- } else
- {
- voices[voice].dev_pending = dev;
- voices[voice].note_pending = note_num;
- voices[voice].volume_pending = volume;
- voices[voice].volume_irq_mode = VMODE_START_NOTE;
-
- gus_rampoff();
- gus_ramp_range(2000, 4065);
- gus_ramp_rate(0, 63); /* Fastest possible rate */
- gus_rampon(0x20 | 0x40); /* Ramp down, once, irq */
- }
- }
+ {
+ if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
+ {
+ voices[voice].volume_pending = volume;
+ }
+ else
+ {
+ ret_val = guswave_start_note2(dev, voice, note_num, volume);
+ }
+ }
+ else
+ {
+ gus_select_voice(voice);
+ mode = gus_read8(0x00);
+ if (mode & 0x20)
+ gus_write8(0x00, mode & 0xdf); /* No interrupt! */
+
+ voices[voice].offset_pending = 0;
+ voices[voice].kill_pending = 0;
+ voices[voice].volume_irq_mode = 0;
+ voices[voice].loop_irq_mode = 0;
+
+ if (voices[voice].sample_pending >= 0)
+ {
+ restore_flags(flags); /* Run temporarily with interrupts enabled */
+ guswave_set_instr(voices[voice].dev_pending, voice, voices[voice].sample_pending);
+ voices[voice].sample_pending = -1;
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice); /* Reselect the voice (just to be sure) */
+ }
+ if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < (unsigned) 2065))
+ {
+ ret_val = guswave_start_note2(dev, voice, note_num, volume);
+ }
+ else
+ {
+ voices[voice].dev_pending = dev;
+ voices[voice].note_pending = note_num;
+ voices[voice].volume_pending = volume;
+ voices[voice].volume_irq_mode = VMODE_START_NOTE;
+
+ gus_rampoff();
+ gus_ramp_range(2000, 4065);
+ gus_ramp_rate(0, 63); /* Fastest possible rate */
+ gus_rampon(0x20 | 0x40); /* Ramp down, once, irq */
+ }
+ }
restore_flags(flags);
return ret_val;
}
-static void
-guswave_reset(int dev)
+static void guswave_reset(int dev)
{
- int i;
+ int i;
for (i = 0; i < 32; i++)
- {
- gus_voice_init(i);
- gus_voice_init2(i);
- }
+ {
+ gus_voice_init(i);
+ gus_voice_init2(i);
+ }
}
-static int
-guswave_open(int dev, int mode)
+static int guswave_open(int dev, int mode)
{
- int err;
+ int err;
if (gus_busy)
return -EBUSY;
@@ -1682,13 +1650,14 @@ 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 */
- } else
+ {
+ /* printk( "GUS: Loading samples without DMA\n"); */
+ gus_no_dma = 1; /* Upload samples using PIO */
+ }
+ else
gus_no_dma = 0;
- dram_sleep_flag.opts = WK_NONE;
+ init_waitqueue(&dram_sleeper);
gus_busy = 1;
active_device = GUS_DEV_WAVE;
@@ -1700,8 +1669,7 @@ guswave_open(int dev, int mode)
return 0;
}
-static void
-guswave_close(int dev)
+static void guswave_close(int dev)
{
gus_busy = 0;
active_device = 0;
@@ -1711,35 +1679,34 @@ guswave_close(int dev)
DMAbuf_close_dma(gus_devnum);
}
-static int
-guswave_load_patch(int dev, int format, const char *addr,
+static int guswave_load_patch(int dev, int format, const char *addr,
int offs, int count, int pmgr_flag)
{
struct patch_info patch;
- int instr;
- long sizeof_patch;
+ int instr;
+ long sizeof_patch;
- unsigned long blk_sz, blk_end, left, src_offs, target;
+ unsigned long blk_sz, blk_end, left, src_offs, target;
sizeof_patch = (long) &patch.data[0] - (long) &patch; /* Header size */
if (format != GUS_PATCH)
- {
- printk("GUS Error: Invalid patch format (key) 0x%x\n", format);
- return -EINVAL;
- }
+ {
+/* printk("GUS Error: Invalid patch format (key) 0x%x\n", format);*/
+ return -EINVAL;
+ }
if (count < sizeof_patch)
- {
- printk("GUS Error: Patch header too short\n");
+ {
+/* printk("GUS Error: Patch header too short\n");*/
return -EINVAL;
- }
+ }
count -= sizeof_patch;
if (free_sample >= MAX_SAMPLE)
- {
- printk("GUS: Sample table full\n");
+ {
+/* printk("GUS: Sample table full\n");*/
return -ENOSPC;
- }
+ }
/*
* Copy the header from user space but ignore the first bytes which have
* been transferred already.
@@ -1750,63 +1717,63 @@ guswave_load_patch(int dev, int format, const char *addr,
if (patch.mode & WAVE_ROM)
return -EINVAL;
if (gus_mem_size == 0)
-
return -ENOSPC;
instr = patch.instr_no;
if (instr < 0 || instr > MAX_PATCH)
- {
- printk("GUS: Invalid patch number %d\n", instr);
- return -EINVAL;
- }
+ {
+/* printk(KERN_ERR "GUS: Invalid patch number %d\n", instr);*/
+ return -EINVAL;
+ }
if (count < patch.len)
- {
- printk("GUS Warning: Patch record too short (%d<%d)\n", count, (int) patch.len);
- patch.len = count;
- }
+ {
+/* printk(KERN_ERR "GUS Warning: Patch record too short (%d<%d)\n", count, (int) patch.len);*/
+ patch.len = count;
+ }
if (patch.len <= 0 || patch.len > gus_mem_size)
- {
- printk("GUS: Invalid sample length %d\n", (int) patch.len);
- return -EINVAL;
- }
+ {
+/* printk(KERN_ERR "GUS: Invalid sample length %d\n", (int) patch.len);*/
+ return -EINVAL;
+ }
if (patch.mode & WAVE_LOOPING)
- {
- if (patch.loop_start < 0 || patch.loop_start >= patch.len)
- {
- printk("GUS: Invalid loop start\n");
- return -EINVAL;
- }
- if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len)
- {
- printk("GUS: Invalid loop end\n");
- return -EINVAL;
- }
- }
+ {
+ if (patch.loop_start < 0 || patch.loop_start >= patch.len)
+ {
+/* printk(KERN_ERR "GUS: Invalid loop start\n");*/
+ return -EINVAL;
+ }
+ if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len)
+ {
+/* printk(KERN_ERR "GUS: Invalid loop end\n");*/
+ return -EINVAL;
+ }
+ }
free_mem_ptr = (free_mem_ptr + 31) & ~31; /* 32 byte alignment */
if (patch.mode & WAVE_16_BITS)
- {
- /*
- * 16 bit samples must fit one 256k bank.
- */
- if (patch.len >= GUS_BANK_SIZE)
- {
- printk("GUS: Sample (16 bit) too long %d\n", (int) patch.len);
- return -ENOSPC;
- }
- if ((free_mem_ptr / GUS_BANK_SIZE) !=
- ((free_mem_ptr + patch.len) / GUS_BANK_SIZE))
- {
- unsigned long tmp_mem = /* Align to 256K */
- ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
-
- if ((tmp_mem + patch.len) > gus_mem_size)
- return -ENOSPC;
-
- free_mem_ptr = tmp_mem; /* This leaves unusable memory */
- }
- }
+ {
+ /*
+ * 16 bit samples must fit one 256k bank.
+ */
+ if (patch.len >= GUS_BANK_SIZE)
+ {
+/* printk("GUS: Sample (16 bit) too long %d\n", (int) patch.len);*/
+ return -ENOSPC;
+ }
+ if ((free_mem_ptr / GUS_BANK_SIZE) !=
+ ((free_mem_ptr + patch.len) / GUS_BANK_SIZE))
+ {
+ unsigned long tmp_mem =
+ /* Align to 256K */
+ ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
+
+ if ((tmp_mem + patch.len) > gus_mem_size)
+ return -ENOSPC;
+
+ free_mem_ptr = tmp_mem; /* This leaves unusable memory */
+ }
+ }
if ((free_mem_ptr + patch.len) > gus_mem_size)
return -ENOSPC;
@@ -1820,9 +1787,9 @@ guswave_load_patch(int dev, int format, const char *addr,
patch.mode &= ~WAVE_TREMOLO;
if (!(patch.mode & WAVE_FRACTIONS))
- {
+ {
patch.fractions = 0;
- }
+ }
memcpy((char *) &samples[free_sample], &patch, sizeof_patch);
/*
@@ -1841,162 +1808,147 @@ guswave_load_patch(int dev, int format, const char *addr,
target = free_mem_ptr;
while (left) /* Not completely transferred yet */
- {
- blk_sz = audio_devs[gus_devnum]->dmap_out->bytes_in_use;
- if (blk_sz > left)
- blk_sz = left;
-
- /*
- * DMA cannot cross bank (256k) boundaries. Check for that.
- */
- blk_end = target + blk_sz;
-
- if ((target / GUS_BANK_SIZE) != (blk_end / GUS_BANK_SIZE))
- { /* Split the block */
-
- blk_end &= ~(GUS_BANK_SIZE - 1);
- blk_sz = blk_end - target;
- }
- if (gus_no_dma)
- {
- /*
- * For some reason the DMA is not possible. We have to use PIO.
- */
- long i;
- unsigned char data;
-
- for (i = 0; i < blk_sz; i++)
- {
- get_user(*(unsigned char *) &data, (unsigned char *) &((addr)[sizeof_patch + i]));
- if (patch.mode & WAVE_UNSIGNED)
- if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
- data ^= 0x80; /* Convert to signed */
- gus_poke(target + i, data);
- }
- } else
- {
- unsigned long address, hold_address;
- unsigned char dma_command;
- unsigned long flags;
-
- if (audio_devs[gus_devnum]->dmap_out->raw_buf == NULL)
- {
- printk("GUS: DMA buffer == NULL\n");
- return -ENOSPC;
- }
- /*
- * OK, move now. First in and then out.
- */
-
- copy_from_user(audio_devs[gus_devnum]->dmap_out->raw_buf, &(addr)[sizeof_patch + src_offs], blk_sz);
-
- save_flags(flags);
- cli();
-/******** INTERRUPTS DISABLED NOW ********/
- gus_write8(0x41, 0); /* Disable GF1 DMA */
- DMAbuf_start_dma(gus_devnum,
- audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
- blk_sz, DMA_MODE_WRITE);
-
- /*
- * Set the DRAM address for the wave data
- */
-
- if (iw_mode)
- {
- /* Different address translation in enhanced mode */
-
- unsigned char hi;
-
- if (gus_dma > 4)
- address = target >> 1; /* Convert to 16 bit word address */
- else
- address = target;
-
- hi = (unsigned char) ((address >> 16) & 0xf0);
- hi += (unsigned char) (address & 0x0f);
-
- gus_write16(0x42, (address >> 4) & 0xffff); /* DMA address (low) */
- gus_write8(0x50, hi);
- } else
- {
- address = target;
-
- if (audio_devs[gus_devnum]->dmap_out->dma > 3)
- {
- hold_address = address;
- address = address >> 1;
- address &= 0x0001ffffL;
- address |= (hold_address & 0x000c0000L);
- }
- gus_write16(0x42, (address >> 4) & 0xffff); /* DRAM DMA address */
- }
-
- /*
- * Start the DMA transfer
- */
-
- dma_command = 0x21; /* IRQ enable, DMA start */
- if (patch.mode & WAVE_UNSIGNED)
- dma_command |= 0x80; /* Invert MSB */
- if (patch.mode & WAVE_16_BITS)
- dma_command |= 0x40; /* 16 bit _DATA_ */
- if (audio_devs[gus_devnum]->dmap_out->dma > 3)
- dma_command |= 0x04; /* 16 bit DMA _channel_ */
-
- gus_write8(0x41, dma_command); /* Lets go luteet (=bugs) */
-
- /*
- * Sleep here until the DRAM DMA done interrupt is served
- */
- active_device = GUS_DEV_WAVE;
-
-
- {
- unsigned long tlimit;
-
- if (HZ)
- current->timeout = tlimit = jiffies + (HZ);
- else
- tlimit = (unsigned long) -1;
- dram_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&dram_sleeper);
- if (!(dram_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- dram_sleep_flag.opts |= WK_TIMEOUT;
- }
- dram_sleep_flag.opts &= ~WK_SLEEP;
- };
- if ((dram_sleep_flag.opts & WK_TIMEOUT))
- printk("GUS: DMA Transfer timed out\n");
- restore_flags(flags);
- }
-
- /*
- * Now the next part
- */
-
- left -= blk_sz;
- src_offs += blk_sz;
- target += blk_sz;
-
- gus_write8(0x41, 0); /* Stop DMA */
- }
+ {
+ blk_sz = audio_devs[gus_devnum]->dmap_out->bytes_in_use;
+ if (blk_sz > left)
+ blk_sz = left;
+
+ /*
+ * DMA cannot cross bank (256k) boundaries. Check for that.
+ */
+
+ blk_end = target + blk_sz;
+
+ if ((target / GUS_BANK_SIZE) != (blk_end / GUS_BANK_SIZE))
+ {
+ /* Split the block */
+ blk_end &= ~(GUS_BANK_SIZE - 1);
+ blk_sz = blk_end - target;
+ }
+ if (gus_no_dma)
+ {
+ /*
+ * For some reason the DMA is not possible. We have to use PIO.
+ */
+ long i;
+ unsigned char data;
+
+ for (i = 0; i < blk_sz; i++)
+ {
+ get_user(*(unsigned char *) &data, (unsigned char *) &((addr)[sizeof_patch + i]));
+ if (patch.mode & WAVE_UNSIGNED)
+ if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
+ data ^= 0x80; /* Convert to signed */
+ gus_poke(target + i, data);
+ }
+ }
+ else
+ {
+ unsigned long address, hold_address;
+ unsigned char dma_command;
+ unsigned long flags;
+
+ if (audio_devs[gus_devnum]->dmap_out->raw_buf == NULL)
+ {
+ printk(KERN_ERR "GUS: DMA buffer == NULL\n");
+ return -ENOSPC;
+ }
+ /*
+ * OK, move now. First in and then out.
+ */
+
+ copy_from_user(audio_devs[gus_devnum]->dmap_out->raw_buf, &(addr)[sizeof_patch + src_offs], blk_sz);
+
+ save_flags(flags);
+ cli();
+ /******** INTERRUPTS DISABLED NOW ********/
+ gus_write8(0x41, 0); /* Disable GF1 DMA */
+ DMAbuf_start_dma(gus_devnum, audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
+ blk_sz, DMA_MODE_WRITE);
+
+ /*
+ * Set the DRAM address for the wave data
+ */
+
+ if (iw_mode)
+ {
+ /* Different address translation in enhanced mode */
+
+ unsigned char hi;
+
+ if (gus_dma > 4)
+ address = target >> 1; /* Convert to 16 bit word address */
+ else
+ address = target;
+
+ hi = (unsigned char) ((address >> 16) & 0xf0);
+ hi += (unsigned char) (address & 0x0f);
+
+ gus_write16(0x42, (address >> 4) & 0xffff); /* DMA address (low) */
+ gus_write8(0x50, hi);
+ }
+ else
+ {
+ address = target;
+ if (audio_devs[gus_devnum]->dmap_out->dma > 3)
+ {
+ hold_address = address;
+ address = address >> 1;
+ address &= 0x0001ffffL;
+ address |= (hold_address & 0x000c0000L);
+ }
+ gus_write16(0x42, (address >> 4) & 0xffff); /* DRAM DMA address */
+ }
+
+ /*
+ * Start the DMA transfer
+ */
+
+ dma_command = 0x21; /* IRQ enable, DMA start */
+ if (patch.mode & WAVE_UNSIGNED)
+ dma_command |= 0x80; /* Invert MSB */
+ if (patch.mode & WAVE_16_BITS)
+ dma_command |= 0x40; /* 16 bit _DATA_ */
+ if (audio_devs[gus_devnum]->dmap_out->dma > 3)
+ dma_command |= 0x04; /* 16 bit DMA _channel_ */
+
+ gus_write8(0x41, dma_command); /* Lets go luteet (=bugs) */
+
+ /*
+ * Sleep here until the DRAM DMA done interrupt is served
+ */
+ active_device = GUS_DEV_WAVE;
+
+ current->timeout = jiffies + HZ;
+ interruptible_sleep_on(&dram_sleeper);
+ if (!current->timeout)
+ printk("GUS: DMA Transfer timed out\n");
+ current->timeout = 0;
+ restore_flags(flags);
+ }
+
+ /*
+ * Now the next part
+ */
+
+ left -= blk_sz;
+ src_offs += blk_sz;
+ target += blk_sz;
+
+ gus_write8(0x41, 0); /* Stop DMA */
+ }
free_mem_ptr += patch.len;
-
free_sample++;
return 0;
}
-static void
-guswave_hw_control(int dev, unsigned char *event_rec)
+static void guswave_hw_control(int dev, unsigned char *event_rec)
{
- int voice, cmd;
- unsigned short p1, p2;
- unsigned int plong;
- unsigned flags;
+ int voice, cmd;
+ unsigned short p1, p2;
+ unsigned int plong;
+ unsigned flags;
cmd = event_rec[2];
voice = event_rec[3];
@@ -2005,156 +1957,152 @@ guswave_hw_control(int dev, unsigned char *event_rec)
plong = *(unsigned int *) &event_rec[4];
if ((voices[voice].volume_irq_mode == VMODE_START_NOTE) &&
- (cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))
+ (cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))
do_volume_irq(voice);
switch (cmd)
- {
-
- case _GUS_NUMVOICES:
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_select_max_voices(p1);
- restore_flags(flags);
- break;
-
- case _GUS_VOICESAMPLE:
- guswave_set_instr(dev, voice, p1);
- break;
-
- case _GUS_VOICEON:
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- p1 &= ~0x20; /* Don't allow interrupts */
- gus_voice_on(p1);
- restore_flags(flags);
- break;
-
- case _GUS_VOICEOFF:
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_voice_off();
- restore_flags(flags);
- break;
-
- case _GUS_VOICEFADE:
- gus_voice_fade(voice);
- break;
-
- case _GUS_VOICEMODE:
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- p1 &= ~0x20; /* Don't allow interrupts */
- gus_voice_mode(p1);
- restore_flags(flags);
- break;
-
- case _GUS_VOICEBALA:
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_voice_balance(p1);
- restore_flags(flags);
- break;
-
- case _GUS_VOICEFREQ:
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_voice_freq(plong);
- restore_flags(flags);
- break;
-
- case _GUS_VOICEVOL:
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_voice_volume(p1);
- restore_flags(flags);
- break;
-
- case _GUS_VOICEVOL2: /* Just update the software voice level */
- voices[voice].initial_volume =
- voices[voice].current_volume = p1;
- break;
-
- case _GUS_RAMPRANGE:
- if (voices[voice].mode & WAVE_ENVELOPES)
- break; /* NO-NO */
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_ramp_range(p1, p2);
- restore_flags(flags);
- break;
-
- case _GUS_RAMPRATE:
- if (voices[voice].mode & WAVE_ENVELOPES)
- break; /* NJET-NJET */
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_ramp_rate(p1, p2);
- restore_flags(flags);
- break;
-
- case _GUS_RAMPMODE:
- if (voices[voice].mode & WAVE_ENVELOPES)
- break; /* NO-NO */
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- p1 &= ~0x20; /* Don't allow interrupts */
- gus_ramp_mode(p1);
- restore_flags(flags);
- break;
-
- case _GUS_RAMPON:
- if (voices[voice].mode & WAVE_ENVELOPES)
- break; /* EI-EI */
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- p1 &= ~0x20; /* Don't allow interrupts */
- gus_rampon(p1);
- restore_flags(flags);
- break;
-
- case _GUS_RAMPOFF:
- if (voices[voice].mode & WAVE_ENVELOPES)
- break; /* NEJ-NEJ */
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_rampoff();
- restore_flags(flags);
- break;
-
- case _GUS_VOLUME_SCALE:
- volume_base = p1;
- volume_scale = p2;
- break;
-
- case _GUS_VOICE_POS:
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_set_voice_pos(voice, plong);
- restore_flags(flags);
- break;
-
- default:;
- }
-}
-
-static int
-gus_audio_set_speed(int speed)
+ {
+ case _GUS_NUMVOICES:
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_select_max_voices(p1);
+ restore_flags(flags);
+ break;
+
+ case _GUS_VOICESAMPLE:
+ guswave_set_instr(dev, voice, p1);
+ break;
+
+ case _GUS_VOICEON:
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ p1 &= ~0x20; /* Don't allow interrupts */
+ gus_voice_on(p1);
+ restore_flags(flags);
+ break;
+
+ case _GUS_VOICEOFF:
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_voice_off();
+ restore_flags(flags);
+ break;
+
+ case _GUS_VOICEFADE:
+ gus_voice_fade(voice);
+ break;
+
+ case _GUS_VOICEMODE:
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ p1 &= ~0x20; /* Don't allow interrupts */
+ gus_voice_mode(p1);
+ restore_flags(flags);
+ break;
+
+ case _GUS_VOICEBALA:
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_voice_balance(p1);
+ restore_flags(flags);
+ break;
+
+ case _GUS_VOICEFREQ:
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_voice_freq(plong);
+ restore_flags(flags);
+ break;
+
+ case _GUS_VOICEVOL:
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_voice_volume(p1);
+ restore_flags(flags);
+ break;
+
+ case _GUS_VOICEVOL2: /* Just update the software voice level */
+ voices[voice].initial_volume = voices[voice].current_volume = p1;
+ break;
+
+ case _GUS_RAMPRANGE:
+ if (voices[voice].mode & WAVE_ENVELOPES)
+ break; /* NO-NO */
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_ramp_range(p1, p2);
+ restore_flags(flags);
+ break;
+
+ case _GUS_RAMPRATE:
+ if (voices[voice].mode & WAVE_ENVELOPES)
+ break; /* NJET-NJET */
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_ramp_rate(p1, p2);
+ restore_flags(flags);
+ break;
+
+ case _GUS_RAMPMODE:
+ if (voices[voice].mode & WAVE_ENVELOPES)
+ break; /* NO-NO */
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ p1 &= ~0x20; /* Don't allow interrupts */
+ gus_ramp_mode(p1);
+ restore_flags(flags);
+ break;
+
+ case _GUS_RAMPON:
+ if (voices[voice].mode & WAVE_ENVELOPES)
+ break; /* EI-EI */
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ p1 &= ~0x20; /* Don't allow interrupts */
+ gus_rampon(p1);
+ restore_flags(flags);
+ break;
+
+ case _GUS_RAMPOFF:
+ if (voices[voice].mode & WAVE_ENVELOPES)
+ break; /* NEJ-NEJ */
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_rampoff();
+ restore_flags(flags);
+ break;
+
+ case _GUS_VOLUME_SCALE:
+ volume_base = p1;
+ volume_scale = p2;
+ break;
+
+ case _GUS_VOICE_POS:
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_set_voice_pos(voice, plong);
+ restore_flags(flags);
+ break;
+
+ default:
+ }
+}
+
+static int gus_audio_set_speed(int speed)
{
-
if (speed <= 0)
speed = gus_audio_speed;
@@ -2167,18 +2115,17 @@ gus_audio_set_speed(int speed)
gus_audio_speed = speed;
if (only_read_access)
- {
- /* Compute nearest valid recording speed and return it */
+ {
+ /* Compute nearest valid recording speed and return it */
- /* speed = (9878400 / (gus_audio_speed + 2)) / 16; */
- speed = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16;
- speed = (9878400 / (speed * 16)) - 2;
- }
+ /* speed = (9878400 / (gus_audio_speed + 2)) / 16; */
+ speed = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16;
+ speed = (9878400 / (speed * 16)) - 2;
+ }
return speed;
}
-static int
-gus_audio_set_channels(int channels)
+static int gus_audio_set_channels(int channels)
{
if (!channels)
return gus_audio_channels;
@@ -2190,8 +2137,7 @@ gus_audio_set_channels(int channels)
return channels;
}
-static int
-gus_audio_set_bits(int bits)
+static int gus_audio_set_bits(int bits)
{
if (!bits)
return gus_audio_bits;
@@ -2206,79 +2152,79 @@ gus_audio_set_bits(int bits)
return bits;
}
-static int
-gus_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
-{
- int val;
-
- switch (cmd)
- {
- case SOUND_PCM_WRITE_RATE:
- val = *(int *) arg;
- return (*(int *) arg = gus_audio_set_speed(val));
- break;
-
- case SOUND_PCM_READ_RATE:
- return (*(int *) arg = gus_audio_speed);
- break;
-
- case SNDCTL_DSP_STEREO:
- val = *(int *) arg;
- return (*(int *) arg = gus_audio_set_channels(val + 1) - 1);
- break;
-
- case SOUND_PCM_WRITE_CHANNELS:
- val = *(int *) arg;
- return (*(int *) arg = gus_audio_set_channels(val));
- break;
-
- case SOUND_PCM_READ_CHANNELS:
- return (*(int *) arg = gus_audio_channels);
- break;
-
- case SNDCTL_DSP_SETFMT:
- val = *(int *) arg;
- return (*(int *) arg = gus_audio_set_bits(val));
- break;
-
- case SOUND_PCM_READ_BITS:
- return (*(int *) arg = gus_audio_bits);
-
- case SOUND_PCM_WRITE_FILTER: /* NOT POSSIBLE */
- return (*(int *) arg = -EINVAL);
- break;
-
- case SOUND_PCM_READ_FILTER:
- return (*(int *) arg = -EINVAL);
- break;
-
- }
- return -EINVAL;
-}
-
-static void
-gus_audio_reset(int dev)
+static int gus_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
+{
+ int val;
+
+ switch (cmd)
+ {
+ case SOUND_PCM_WRITE_RATE:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = gus_audio_set_speed(val);
+ break;
+
+ case SOUND_PCM_READ_RATE:
+ val = gus_audio_speed;
+ break;
+
+ case SNDCTL_DSP_STEREO:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = gus_audio_set_channels(val + 1) - 1;
+ break;
+
+ case SOUND_PCM_WRITE_CHANNELS:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = gus_audio_set_channels(val);
+ break;
+
+ case SOUND_PCM_READ_CHANNELS:
+ val = gus_audio_channels;
+ break;
+
+ case SNDCTL_DSP_SETFMT:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val = gus_audio_set_bits(val);
+ break;
+
+ case SOUND_PCM_READ_BITS:
+ val = gus_audio_bits;
+ break;
+
+ case SOUND_PCM_WRITE_FILTER: /* NOT POSSIBLE */
+ case SOUND_PCM_READ_FILTER:
+ val = -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return put_user(val, (int *)arg);
+}
+
+static void gus_audio_reset(int dev)
{
if (recording_active)
- {
- gus_write8(0x49, 0x00); /* Halt recording */
- set_input_volumes();
- }
+ {
+ gus_write8(0x49, 0x00); /* Halt recording */
+ set_input_volumes();
+ }
}
-static int saved_iw_mode; /* A hack hack hack */
+static int saved_iw_mode; /* A hack hack hack */
-static int
-gus_audio_open(int dev, int mode)
+static int gus_audio_open(int dev, int mode)
{
if (gus_busy)
return -EBUSY;
if (gus_pnp_flag && mode & OPEN_READ)
- {
- printk("GUS: Audio device #%d is playback only.\n", dev);
- return -EIO;
- }
+ {
+/* printk(KERN_ERR "GUS: Audio device #%d is playback only.\n", dev);*/
+ return -EIO;
+ }
gus_initialize();
gus_busy = 1;
@@ -2289,19 +2235,19 @@ gus_audio_open(int dev, int mode)
gus_select_max_voices(14);
saved_iw_mode = iw_mode;
if (iw_mode)
- {
- /* There are some problems with audio in enhanced mode so disable it */
- gus_write8(0x19, gus_read8(0x19) & ~0x01); /* Disable enhanced mode */
- iw_mode = 0;
- }
+ {
+ /* There are some problems with audio in enhanced mode so disable it */
+ gus_write8(0x19, gus_read8(0x19) & ~0x01); /* Disable enhanced mode */
+ iw_mode = 0;
+ }
pcm_active = 0;
dma_active = 0;
pcm_opened = 1;
if (mode & OPEN_READ)
- {
- recording_active = 1;
- set_input_volumes();
- }
+ {
+ recording_active = 1;
+ set_input_volumes();
+ }
only_read_access = !(mode & OPEN_WRITE);
only_8_bits = mode & OPEN_READ;
if (only_8_bits)
@@ -2312,8 +2258,7 @@ gus_audio_open(int dev, int mode)
return 0;
}
-static void
-gus_audio_close(int dev)
+static void gus_audio_close(int dev)
{
iw_mode = saved_iw_mode;
gus_reset();
@@ -2322,40 +2267,38 @@ gus_audio_close(int dev)
active_device = 0;
if (recording_active)
- {
- gus_write8(0x49, 0x00); /* Halt recording */
- set_input_volumes();
- }
+ {
+ gus_write8(0x49, 0x00); /* Halt recording */
+ set_input_volumes();
+ }
recording_active = 0;
}
-static void
-gus_audio_update_volume(void)
+static void gus_audio_update_volume(void)
{
- unsigned long flags;
- int voice;
+ unsigned long flags;
+ int voice;
if (pcm_active && pcm_opened)
for (voice = 0; voice < gus_audio_channels; voice++)
- {
- save_flags(flags);
- cli();
- gus_select_voice(voice);
- gus_rampoff();
- gus_voice_volume(1530 + (25 * gus_pcm_volume));
- gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
- restore_flags(flags);
- }
+ {
+ save_flags(flags);
+ cli();
+ gus_select_voice(voice);
+ gus_rampoff();
+ gus_voice_volume(1530 + (25 * gus_pcm_volume));
+ gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
+ restore_flags(flags);
+ }
}
-static void
-play_next_pcm_block(void)
+static void play_next_pcm_block(void)
{
- unsigned long flags;
- int speed = gus_audio_speed;
- int this_one, is16bits, chn;
- unsigned long dram_loc;
- unsigned char mode[2], ramp_mode[2];
+ unsigned long flags;
+ int speed = gus_audio_speed;
+ int this_one, is16bits, chn;
+ unsigned long dram_loc;
+ unsigned char mode[2], ramp_mode[2];
if (!pcm_qlen)
return;
@@ -2363,95 +2306,91 @@ play_next_pcm_block(void)
this_one = pcm_head;
for (chn = 0; chn < gus_audio_channels; chn++)
- {
- mode[chn] = 0x00;
- ramp_mode[chn] = 0x03; /* Ramping and rollover off */
-
- if (chn == 0)
- {
- mode[chn] |= 0x20; /* Loop IRQ */
- voices[chn].loop_irq_mode = LMODE_PCM;
- }
- if (gus_audio_bits != 8)
- {
- is16bits = 1;
- mode[chn] |= 0x04; /* 16 bit data */
- } else
- is16bits = 0;
-
- dram_loc = this_one * pcm_bsize;
- dram_loc += chn * pcm_banksize;
-
- if (this_one == (pcm_nblk - 1)) /* Last fragment of the DRAM buffer */
- {
- mode[chn] |= 0x08; /* Enable loop */
- ramp_mode[chn] = 0x03; /* Disable rollover bit */
- } else
- {
- if (chn == 0)
- ramp_mode[chn] = 0x04; /* Enable rollover bit */
- }
-
- save_flags(flags);
- cli();
- gus_select_voice(chn);
- gus_voice_freq(speed);
-
- if (gus_audio_channels == 1)
- gus_voice_balance(7); /* mono */
- else if (chn == 0)
- gus_voice_balance(0); /* left */
- else
- gus_voice_balance(15); /* right */
-
- if (!pcm_active) /* Playback not already active */
- {
- /*
- * The playback was not started yet (or there has been a pause).
- * Start the voice (again) and ask for a rollover irq at the end of
- * this_one block. If this_one one is last of the buffers, use just
- * the normal loop with irq.
- */
-
- gus_voice_off();
- gus_rampoff();
- gus_voice_volume(1530 + (25 * gus_pcm_volume));
- gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
-
- gus_write_addr(0x0a, chn * pcm_banksize, 0, is16bits); /* Starting position */
- gus_write_addr(0x02, chn * pcm_banksize, 0, is16bits); /* Loop start */
-
- if (chn != 0)
- gus_write_addr(0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1,
+ {
+ mode[chn] = 0x00;
+ ramp_mode[chn] = 0x03; /* Ramping and rollover off */
+
+ if (chn == 0)
+ {
+ mode[chn] |= 0x20; /* Loop IRQ */
+ voices[chn].loop_irq_mode = LMODE_PCM;
+ }
+ if (gus_audio_bits != 8)
+ {
+ is16bits = 1;
+ mode[chn] |= 0x04; /* 16 bit data */
+ }
+ else
+ is16bits = 0;
+
+ dram_loc = this_one * pcm_bsize;
+ dram_loc += chn * pcm_banksize;
+
+ if (this_one == (pcm_nblk - 1)) /* Last fragment of the DRAM buffer */
+ {
+ mode[chn] |= 0x08; /* Enable loop */
+ ramp_mode[chn] = 0x03; /* Disable rollover bit */
+ }
+ else
+ {
+ if (chn == 0)
+ ramp_mode[chn] = 0x04; /* Enable rollover bit */
+ }
+ save_flags(flags);
+ cli();
+ gus_select_voice(chn);
+ gus_voice_freq(speed);
+
+ if (gus_audio_channels == 1)
+ gus_voice_balance(7); /* mono */
+ else if (chn == 0)
+ gus_voice_balance(0); /* left */
+ else
+ gus_voice_balance(15); /* right */
+
+ if (!pcm_active) /* Playback not already active */
+ {
+ /*
+ * The playback was not started yet (or there has been a pause).
+ * Start the voice (again) and ask for a rollover irq at the end of
+ * this_one block. If this_one one is last of the buffers, use just
+ * the normal loop with irq.
+ */
+
+ gus_voice_off();
+ gus_rampoff();
+ gus_voice_volume(1530 + (25 * gus_pcm_volume));
+ gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
+
+ gus_write_addr(0x0a, chn * pcm_banksize, 0, is16bits); /* Starting position */
+ gus_write_addr(0x02, chn * pcm_banksize, 0, is16bits); /* Loop start */
+
+ if (chn != 0)
+ gus_write_addr(0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1,
0, is16bits); /* Loop end location */
- }
- if (chn == 0)
- gus_write_addr(0x04, dram_loc + pcm_bsize - 1,
+ }
+ if (chn == 0)
+ gus_write_addr(0x04, dram_loc + pcm_bsize - 1,
0, is16bits); /* Loop end location */
- else
- mode[chn] |= 0x08; /* Enable looping */
-
-
- restore_flags(flags);
- }
-
+ else
+ mode[chn] |= 0x08; /* Enable looping */
+ restore_flags(flags);
+ }
for (chn = 0; chn < gus_audio_channels; chn++)
- {
- save_flags(flags);
- cli();
- gus_select_voice(chn);
- gus_write8(0x0d, ramp_mode[chn]);
- if (iw_mode)
- gus_write8(0x15, 0x00); /* Reset voice deactivate bit of SMSI */
- gus_voice_on(mode[chn]);
- restore_flags(flags);
- }
-
+ {
+ save_flags(flags);
+ cli();
+ gus_select_voice(chn);
+ gus_write8(0x0d, ramp_mode[chn]);
+ if (iw_mode)
+ gus_write8(0x15, 0x00); /* Reset voice deactivate bit of SMSI */
+ gus_voice_on(mode[chn]);
+ restore_flags(flags);
+ }
pcm_active = 1;
}
-static void
-gus_transfer_output_block(int dev, unsigned long buf,
+static void gus_transfer_output_block(int dev, unsigned long buf,
int total_count, int intrflag, int chn)
{
/*
@@ -2463,10 +2402,10 @@ gus_transfer_output_block(int dev, unsigned long buf,
* right data to the area pointed by gus_page_size.
*/
- int this_one, count;
- unsigned long flags;
- unsigned char dma_command;
- unsigned long address, hold_address;
+ int this_one, count;
+ unsigned long flags;
+ unsigned char dma_command;
+ unsigned long address, hold_address;
save_flags(flags);
cli();
@@ -2474,15 +2413,16 @@ gus_transfer_output_block(int dev, unsigned long buf,
count = total_count / gus_audio_channels;
if (chn == 0)
- {
- if (pcm_qlen >= pcm_nblk)
- printk("GUS Warning: PCM buffers out of sync\n");
-
- this_one = pcm_current_block = pcm_tail;
- pcm_qlen++;
- pcm_tail = (pcm_tail + 1) % pcm_nblk;
- pcm_datasize[this_one] = count;
- } else
+ {
+ if (pcm_qlen >= pcm_nblk)
+ printk(KERN_WARNING "GUS Warning: PCM buffers out of sync\n");
+
+ this_one = pcm_current_block = pcm_tail;
+ pcm_qlen++;
+ pcm_tail = (pcm_tail + 1) % pcm_nblk;
+ pcm_datasize[this_one] = count;
+ }
+ else
this_one = pcm_current_block;
gus_write8(0x41, 0); /* Disable GF1 DMA */
@@ -2492,12 +2432,12 @@ gus_transfer_output_block(int dev, unsigned long buf,
address += chn * pcm_banksize;
if (audio_devs[dev]->dmap_out->dma > 3)
- {
- hold_address = address;
- address = address >> 1;
- address &= 0x0001ffffL;
- address |= (hold_address & 0x000c0000L);
- }
+ {
+ hold_address = address;
+ address = address >> 1;
+ address &= 0x0001ffffL;
+ address |= (hold_address & 0x000c0000L);
+ }
gus_write16(0x42, (address >> 4) & 0xffff); /* DRAM DMA address */
dma_command = 0x21; /* IRQ enable, DMA start */
@@ -2513,62 +2453,60 @@ gus_transfer_output_block(int dev, unsigned long buf,
gus_write8(0x41, dma_command); /* Kick start */
if (chn == (gus_audio_channels - 1)) /* Last channel */
- {
- /*
- * Last (right or mono) channel data
- */
- dma_active = 1; /* DMA started. There is a unacknowledged buffer */
- active_device = GUS_DEV_PCM_DONE;
- if (!pcm_active && (pcm_qlen > 1 || count < pcm_bsize))
- {
- play_next_pcm_block();
- }
- } else
- {
- /*
- * Left channel data. The right channel
- * is transferred after DMA interrupt
- */
- active_device = GUS_DEV_PCM_CONTINUE;
- }
+ {
+ /*
+ * Last (right or mono) channel data
+ */
+ dma_active = 1; /* DMA started. There is a unacknowledged buffer */
+ active_device = GUS_DEV_PCM_DONE;
+ if (!pcm_active && (pcm_qlen > 1 || count < pcm_bsize))
+ {
+ play_next_pcm_block();
+ }
+ }
+ else
+ {
+ /*
+ * Left channel data. The right channel
+ * is transferred after DMA interrupt
+ */
+ active_device = GUS_DEV_PCM_CONTINUE;
+ }
restore_flags(flags);
}
-static void
-gus_uninterleave8(char *buf, int l)
+static void gus_uninterleave8(char *buf, int l)
{
/* This routine uninterleaves 8 bit stereo output (LRLRLR->LLLRRR) */
- int i, p = 0, halfsize = l / 2;
- char *buf2 = buf + halfsize, *src = bounce_buf;
+ int i, p = 0, halfsize = l / 2;
+ char *buf2 = buf + halfsize, *src = bounce_buf;
memcpy(bounce_buf, buf, l);
for (i = 0; i < halfsize; i++)
- {
- buf[i] = src[p++]; /* Left channel */
- buf2[i] = src[p++]; /* Right channel */
- }
+ {
+ buf[i] = src[p++]; /* Left channel */
+ buf2[i] = src[p++]; /* Right channel */
+ }
}
-static void
-gus_uninterleave16(short *buf, int l)
+static void gus_uninterleave16(short *buf, int l)
{
/* This routine uninterleaves 16 bit stereo output (LRLRLR->LLLRRR) */
- int i, p = 0, halfsize = l / 2;
- short *buf2 = buf + halfsize, *src = (short *) bounce_buf;
+ int i, p = 0, halfsize = l / 2;
+ short *buf2 = buf + halfsize, *src = (short *) bounce_buf;
memcpy(bounce_buf, (char *) buf, l * 2);
for (i = 0; i < halfsize; i++)
- {
- buf[i] = src[p++]; /* Left channel */
- buf2[i] = src[p++]; /* Right channel */
- }
+ {
+ buf[i] = src[p++]; /* Left channel */
+ buf2[i] = src[p++]; /* Right channel */
+ }
}
-static void
-gus_audio_output_block(int dev, unsigned long buf, int total_count,
+static void gus_audio_output_block(int dev, unsigned long buf, int total_count,
int intrflag)
{
struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
@@ -2580,29 +2518,27 @@ gus_audio_output_block(int dev, unsigned long buf, int total_count,
pcm_current_intrflag = intrflag;
pcm_current_dev = dev;
if (gus_audio_channels == 2)
- {
- char *b = dmap->raw_buf + (buf - dmap->raw_buf_phys);
-
- if (gus_audio_bits == 8)
- gus_uninterleave8(b, total_count);
- else
- gus_uninterleave16((short *) b, total_count / 2);
- }
+ {
+ char *b = dmap->raw_buf + (buf - dmap->raw_buf_phys);
+
+ if (gus_audio_bits == 8)
+ gus_uninterleave8(b, total_count);
+ else
+ gus_uninterleave16((short *) b, total_count / 2);
+ }
gus_transfer_output_block(dev, buf, total_count, intrflag, 0);
}
-static void
-gus_audio_start_input(int dev, unsigned long buf, int count,
+static void gus_audio_start_input(int dev, unsigned long buf, int count,
int intrflag)
{
- unsigned long flags;
- unsigned char mode;
+ unsigned long flags;
+ unsigned char mode;
save_flags(flags);
cli();
DMAbuf_start_dma(dev, buf, count, DMA_MODE_READ);
-
mode = 0xa0; /* DMA IRQ enabled, invert MSB */
if (audio_devs[dev]->dmap_in->dma > 3)
@@ -2612,14 +2548,12 @@ gus_audio_start_input(int dev, unsigned long buf, int count,
mode |= 0x01; /* DMA enable */
gus_write8(0x49, mode);
-
restore_flags(flags);
}
-static int
-gus_audio_prepare_for_input(int dev, int bsize, int bcount)
+static int gus_audio_prepare_for_input(int dev, int bsize, int bcount)
{
- unsigned int rate;
+ unsigned int rate;
gus_audio_bsize = bsize;
audio_devs[dev]->dmap_in->flags |= DMA_NODMA;
@@ -2628,19 +2562,18 @@ gus_audio_prepare_for_input(int dev, int bsize, int bcount)
gus_write8(0x48, rate & 0xff); /* Set sampling rate */
if (gus_audio_bits != 8)
- {
- printk("GUS Error: 16 bit recording not supported\n");
- return -EINVAL;
- }
+ {
+/* printk("GUS Error: 16 bit recording not supported\n");*/
+ return -EINVAL;
+ }
return 0;
}
-static int
-gus_audio_prepare_for_output(int dev, int bsize, int bcount)
+static int gus_audio_prepare_for_output(int dev, int bsize, int bcount)
{
- int i;
+ int i;
- long mem_ptr, mem_size;
+ long mem_ptr, mem_size;
audio_devs[dev]->dmap_out->flags |= DMA_NODMA | DMA_NOTIMEOUT;
mem_ptr = 0;
@@ -2664,12 +2597,10 @@ gus_audio_prepare_for_output(int dev, int bsize, int bcount)
if (gus_audio_bits != 8 && pcm_banksize == (256 * 1024))
pcm_nblk--;
gus_write8(0x41, 0); /* Disable GF1 DMA */
-
return 0;
}
-static int
-gus_local_qlen(int dev)
+static int gus_local_qlen(int dev)
{
return pcm_qlen;
}
@@ -2689,20 +2620,14 @@ static struct audio_driver gus_audio_driver =
NULL
};
-static void
-guswave_setup_voice(int dev, int voice, int chn)
+static void guswave_setup_voice(int dev, int voice, int chn)
{
- struct channel_info *info =
- &synth_devs[dev]->chn_info[chn];
+ struct channel_info *info = &synth_devs[dev]->chn_info[chn];
guswave_set_instr(dev, voice, info->pgm_num);
-
- voices[voice].expression_vol =
- info->controllers[CTL_EXPRESSION]; /* Just MSB */
- voices[voice].main_vol =
- (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
- voices[voice].panning =
- (info->controllers[CTL_PAN] * 2) - 128;
+ voices[voice].expression_vol = info->controllers[CTL_EXPRESSION]; /* Just MSB */
+ voices[voice].main_vol = (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
+ voices[voice].panning = (info->controllers[CTL_PAN] * 2) - 128;
voices[voice].bender = 0;
voices[voice].bender_range = info->bender_range;
@@ -2710,15 +2635,13 @@ guswave_setup_voice(int dev, int voice, int chn)
voices[voice].fixed_pitch = 1;
}
-static void
-guswave_bender(int dev, int voice, int value)
+static void guswave_bender(int dev, int voice, int value)
{
- int freq;
+ int freq;
unsigned long flags;
voices[voice].bender = value - 8192;
- freq = compute_finetune(voices[voice].orig_freq, value - 8192,
- voices[voice].bender_range, 0);
+ freq = compute_finetune(voices[voice].orig_freq, value - 8192, voices[voice].bender_range, 0);
voices[voice].current_freq = freq;
save_flags(flags);
@@ -2728,45 +2651,43 @@ guswave_bender(int dev, int voice, int value)
restore_flags(flags);
}
-static int
-guswave_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
+static int guswave_alloc(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;
- 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;
+ 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;
- return p;
- }
- p = (p + 1) % alloc->max_voice;
- }
-
+ {
+ if (alloc->map[p] == 0xffff)
+ {
+ alloc->ptr = p;
+ return p;
+ }
+ p = (p + 1) % alloc->max_voice;
+ }
if (best >= 0)
p = best;
@@ -2799,11 +2720,10 @@ static struct synth_operations guswave_operations =
guswave_setup_voice
};
-static void
-set_input_volumes(void)
+static void set_input_volumes(void)
{
- unsigned long flags;
- unsigned char mask = 0xff & ~0x06; /* Just line out enabled */
+ unsigned long flags;
+ unsigned char mask = 0xff & ~0x06; /* Just line out enabled */
if (have_gus_max) /* Don't disturb GUS MAX */
return;
@@ -2822,15 +2742,15 @@ set_input_volumes(void)
mask |= 0x04;
if (recording_active)
- {
- /*
- * Disable channel, if not selected for recording
- */
- if (!(gus_recmask & SOUND_MASK_LINE))
- mask |= 0x01;
- if (!(gus_recmask & SOUND_MASK_MIC))
- mask &= ~0x04;
- }
+ {
+ /*
+ * Disable channel, if not selected for recording
+ */
+ if (!(gus_recmask & SOUND_MASK_LINE))
+ mask |= 0x01;
+ if (!(gus_recmask & SOUND_MASK_MIC))
+ mask &= ~0x04;
+ }
mix_image &= ~0x07;
mix_image |= mask & 0x07;
outb((mix_image), u_Mixer);
@@ -2838,139 +2758,133 @@ set_input_volumes(void)
restore_flags(flags);
}
-int
-gus_default_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
-{
#define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
SOUND_MASK_SYNTH|SOUND_MASK_PCM)
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- gus_recmask = *(int *) arg;
- gus_recmask &= MIX_DEVS;
- if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
- gus_recmask = SOUND_MASK_MIC;
- /* Note! Input volumes are updated during next open for recording */
- return (*(int *) arg = gus_recmask);
- break;
-
- case SOUND_MIXER_MIC:
- {
- int vol;
-
- vol = *(int *) arg;
- vol &= 0xff;
-
- if (vol < 0)
- vol = 0;
- if (vol > 100)
- vol = 100;
- gus_mic_vol = vol;
- set_input_volumes();
- return (*(int *) arg = vol | (vol << 8));
- }
- break;
-
- case SOUND_MIXER_LINE:
- {
- int vol;
-
- vol = *(int *) arg;
- vol &= 0xff;
-
- if (vol < 0)
- vol = 0;
- if (vol > 100)
- vol = 100;
- gus_line_vol = vol;
- set_input_volumes();
- return (*(int *) arg = vol | (vol << 8));
- }
- break;
-
- case SOUND_MIXER_PCM:
- gus_pcm_volume = *(int *) arg;
- gus_pcm_volume &= 0xff;
- if (gus_pcm_volume < 0)
- gus_pcm_volume = 0;
- if (gus_pcm_volume > 100)
- gus_pcm_volume = 100;
- gus_audio_update_volume();
- return (*(int *) arg = gus_pcm_volume | (gus_pcm_volume << 8));
- break;
-
- case SOUND_MIXER_SYNTH:
- {
- int voice;
-
- gus_wave_volume = *(int *) arg;
- gus_wave_volume &= 0xff;
-
- if (gus_wave_volume < 0)
- gus_wave_volume = 0;
- if (gus_wave_volume > 100)
- gus_wave_volume = 100;
-
- if (active_device == GUS_DEV_WAVE)
- for (voice = 0; voice < nr_voices; voice++)
- dynamic_volume_change(voice); /* Apply the new vol */
-
- return (*(int *) arg = gus_wave_volume | (gus_wave_volume << 8));
- }
- break;
-
- default:
- return -EINVAL;
- } else
- switch (cmd & 0xff) /*
- * Return parameters
- */
- {
-
- case SOUND_MIXER_RECSRC:
- return (*(int *) arg = gus_recmask);
- break;
-
- case SOUND_MIXER_DEVMASK:
- return (*(int *) arg = MIX_DEVS);
- break;
-
- case SOUND_MIXER_STEREODEVS:
- return (*(int *) arg = 0);
- break;
-
- case SOUND_MIXER_RECMASK:
- return (*(int *) arg = SOUND_MASK_MIC | SOUND_MASK_LINE);
- break;
-
- case SOUND_MIXER_CAPS:
- return (*(int *) arg = 0);
- break;
-
- case SOUND_MIXER_MIC:
- return (*(int *) arg = gus_mic_vol | (gus_mic_vol << 8));
- break;
-
- case SOUND_MIXER_LINE:
- return (*(int *) arg = gus_line_vol | (gus_line_vol << 8));
- break;
-
- case SOUND_MIXER_PCM:
- return (*(int *) arg = gus_pcm_volume | (gus_pcm_volume << 8));
- break;
-
- case SOUND_MIXER_SYNTH:
- return (*(int *) arg = gus_wave_volume | (gus_wave_volume << 8));
- break;
-
- default:
- return -EINVAL;
- }
- } else
+
+int gus_default_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+{
+ int vol, val;
+
+ if (((cmd >> 8) & 0xff) != 'M')
return -EINVAL;
+
+ if (!access_ok(VERIFY_WRITE, (int *)arg, sizeof(int)))
+ return -EFAULT;
+
+ if (_SIOC_DIR(cmd) & _SIOC_WRITE)
+ {
+ if (__get_user(val, (int *) arg))
+ return -EFAULT;
+
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ gus_recmask = val & MIX_DEVS;
+ if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
+ gus_recmask = SOUND_MASK_MIC;
+ /* Note! Input volumes are updated during next open for recording */
+ val = gus_recmask;
+ break;
+
+ case SOUND_MIXER_MIC:
+ vol = val & 0xff;
+ if (vol < 0)
+ vol = 0;
+ if (vol > 100)
+ vol = 100;
+ gus_mic_vol = vol;
+ set_input_volumes();
+ val = vol | (vol << 8);
+ break;
+
+ case SOUND_MIXER_LINE:
+ vol = val & 0xff;
+ if (vol < 0)
+ vol = 0;
+ if (vol > 100)
+ vol = 100;
+ gus_line_vol = vol;
+ set_input_volumes();
+ val = vol | (vol << 8);
+ break;
+
+ case SOUND_MIXER_PCM:
+ gus_pcm_volume = val & 0xff;
+ if (gus_pcm_volume < 0)
+ gus_pcm_volume = 0;
+ if (gus_pcm_volume > 100)
+ gus_pcm_volume = 100;
+ gus_audio_update_volume();
+ val = gus_pcm_volume | (gus_pcm_volume << 8);
+ break;
+
+ case SOUND_MIXER_SYNTH:
+ gus_wave_volume = val & 0xff;
+ if (gus_wave_volume < 0)
+ gus_wave_volume = 0;
+ if (gus_wave_volume > 100)
+ gus_wave_volume = 100;
+ if (active_device == GUS_DEV_WAVE)
+ {
+ int voice;
+ for (voice = 0; voice < nr_voices; voice++)
+ dynamic_volume_change(voice); /* Apply the new vol */
+ }
+ val = gus_wave_volume | (gus_wave_volume << 8);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+ else
+ {
+ switch (cmd & 0xff)
+ {
+ /*
+ * Return parameters
+ */
+ case SOUND_MIXER_RECSRC:
+ val = gus_recmask;
+ break;
+
+ case SOUND_MIXER_DEVMASK:
+ val = MIX_DEVS;
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ val = 0;
+ break;
+
+ case SOUND_MIXER_RECMASK:
+ val = SOUND_MASK_MIC | SOUND_MASK_LINE;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ val = 0;
+ break;
+
+ case SOUND_MIXER_MIC:
+ val = gus_mic_vol | (gus_mic_vol << 8);
+ break;
+
+ case SOUND_MIXER_LINE:
+ val = gus_line_vol | (gus_line_vol << 8);
+ break;
+
+ case SOUND_MIXER_PCM:
+ val = gus_pcm_volume | (gus_pcm_volume << 8);
+ break;
+
+ case SOUND_MIXER_SYNTH:
+ val = gus_wave_volume | (gus_wave_volume << 8);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+ return __put_user(val, (int *)arg);
}
static struct mixer_operations gus_mixer_operations =
@@ -2980,44 +2894,42 @@ static struct mixer_operations gus_mixer_operations =
gus_default_mixer_ioctl
};
-static int
-gus_default_mixer_init(void)
+static int gus_default_mixer_init(void)
{
- int n;
+ int n;
if ((n = sound_alloc_mixerdev()) != -1)
- { /*
- * Don't install if there is another
- * mixer
- */
- mixer_devs[n] = &gus_mixer_operations;
- }
+ {
+ /*
+ * Don't install if there is another
+ * mixer
+ */
+ mixer_devs[n] = &gus_mixer_operations;
+ }
if (have_gus_max)
- {
-/*
- * Enable all mixer channels on the GF1 side. Otherwise recording will
- * not be possible using GUS MAX.
- */
- mix_image &= ~0x07;
- mix_image |= 0x04; /* All channels enabled */
- outb((mix_image), u_Mixer);
- }
+ {
+ /*
+ * Enable all mixer channels on the GF1 side. Otherwise recording will
+ * not be possible using GUS MAX.
+ */
+ mix_image &= ~0x07;
+ mix_image |= 0x04; /* All channels enabled */
+ outb((mix_image), u_Mixer);
+ }
return n;
}
-void
-gus_wave_init(struct address_info *hw_config)
+void gus_wave_init(struct address_info *hw_config)
{
- unsigned long flags;
- unsigned char val;
- char *model_num = "2.4";
- char tmp[64], tmp2[64];
- int gus_type = 0x24; /* 2.4 */
+ unsigned long flags;
+ unsigned char val;
+ char *model_num = "2.4";
+ char tmp[64], tmp2[64];
+ int gus_type = 0x24; /* 2.4 */
- int irq = hw_config->irq, dma = hw_config->dma,
- dma2 = hw_config->dma2;
- int dev;
- int sdev;
+ int irq = hw_config->irq, dma = hw_config->dma, dma2 = hw_config->dma2;
+ int dev;
+ int sdev;
hw_config->slots[0] = -1; /* No wave */
hw_config->slots[1] = -1; /* No ad1848 */
@@ -3025,16 +2937,19 @@ gus_wave_init(struct address_info *hw_config)
hw_config->slots[5] = -1; /* No mixer */
if (!gus_pnp_flag)
+ {
if (irq < 0 || irq > 15)
- {
- printk("ERROR! Invalid IRQ#%d. GUS Disabled", irq);
- return;
- }
+ {
+ printk(KERN_ERR "ERROR! Invalid IRQ#%d. GUS Disabled", irq);
+ return;
+ }
+ }
+
if (dma < 0 || dma > 7 || dma == 4)
- {
- printk("ERROR! Invalid DMA#%d. GUS Disabled", dma);
- return;
- }
+ {
+ printk(KERN_ERR "ERROR! Invalid DMA#%d. GUS Disabled", dma);
+ return;
+ }
gus_irq = irq;
gus_dma = dma;
gus_dma2 = dma2;
@@ -3043,9 +2958,9 @@ gus_wave_init(struct address_info *hw_config)
gus_dma2 = dma;
/*
- * Try to identify the GUS model.
- *
- * Versions < 3.6 don't have the digital ASIC. Try to probe it first.
+ * Try to identify the GUS model.
+ *
+ * Versions < 3.6 don't have the digital ASIC. Try to probe it first.
*/
save_flags(flags);
@@ -3055,126 +2970,128 @@ gus_wave_init(struct address_info *hw_config)
restore_flags(flags);
if (gus_pnp_flag || (val != 0xff && (val & 0x06))) /* Should be 0x02?? */
- {
- int ad_flags = 0;
-
- if (gus_pnp_flag)
- ad_flags = 0x12345678; /* Interwave "magic" */
- /*
- * It has the digital ASIC so the card is at least v3.4.
- * Next try to detect the true model.
- */
-
- if (gus_pnp_flag) /* Hack hack hack */
- val = 10;
- else
- val = inb(u_MixSelect);
-
- /*
- * Value 255 means pre-3.7 which don't have mixer.
- * Values 5 thru 9 mean v3.7 which has a ICS2101 mixer.
- * 10 and above is GUS MAX which has the CS4231 codec/mixer.
- *
- */
-
- if (val == 255 || val < 5)
- {
- model_num = "3.4";
- gus_type = 0x34;
- } else if (val < 10)
- {
- model_num = "3.7";
- gus_type = 0x37;
- mixer_type = ICS2101;
- request_region(u_MixSelect, 1, "GUS mixer");
- } else
- {
- model_num = "MAX";
- gus_type = 0x40;
- mixer_type = CS4231;
+ {
+ int ad_flags = 0;
+
+ if (gus_pnp_flag)
+ ad_flags = 0x12345678; /* Interwave "magic" */
+ /*
+ * It has the digital ASIC so the card is at least v3.4.
+ * Next try to detect the true model.
+ */
+
+ if (gus_pnp_flag) /* Hack hack hack */
+ val = 10;
+ else
+ val = inb(u_MixSelect);
+
+ /*
+ * Value 255 means pre-3.7 which don't have mixer.
+ * Values 5 thru 9 mean v3.7 which has a ICS2101 mixer.
+ * 10 and above is GUS MAX which has the CS4231 codec/mixer.
+ *
+ */
+
+ if (val == 255 || val < 5)
+ {
+ model_num = "3.4";
+ gus_type = 0x34;
+ }
+ else if (val < 10)
+ {
+ model_num = "3.7";
+ gus_type = 0x37;
+ mixer_type = ICS2101;
+ request_region(u_MixSelect, 1, "GUS mixer");
+ }
+ else
+ {
+ model_num = "MAX";
+ gus_type = 0x40;
+ mixer_type = CS4231;
#ifdef CONFIG_GUSMAX
- {
- unsigned char max_config = 0x40; /* Codec enable */
-
- if (gus_dma2 == -1)
- gus_dma2 = gus_dma;
-
- if (gus_dma > 3)
- max_config |= 0x10; /* 16 bit capture DMA */
-
- if (gus_dma2 > 3)
- max_config |= 0x20; /* 16 bit playback DMA */
-
- max_config |= (gus_base >> 4) & 0x0f; /* Extract the X from 2X0 */
-
- outb((max_config), gus_base + 0x106); /* UltraMax control */
- }
-
- if (ad1848_detect(gus_base + 0x10c, &ad_flags, hw_config->osp))
- {
- char *name = "GUS MAX";
- int old_num_mixers = num_mixers;
-
- if (gus_pnp_flag)
- name = "GUS PnP";
-
- gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
- gus_wave_volume = 90;
- have_gus_max = 1;
- if (hw_config->name)
- name = hw_config->name;
-
- hw_config->slots[1] = ad1848_init(name, gus_base + 0x10c,
- -irq,
- gus_dma2, /* Playback DMA */
- gus_dma, /* Capture DMA */
- 1, /* Share DMA channels with GF1 */
- hw_config->osp);
-
- if (num_mixers > old_num_mixers)
- { /* GUS has it's own mixer map */
- AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_SYNTH);
- AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
- AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
- }
- } else
- printk("[Where's the CS4231?]");
+ {
+ unsigned char max_config = 0x40; /* Codec enable */
+
+ if (gus_dma2 == -1)
+ gus_dma2 = gus_dma;
+
+ if (gus_dma > 3)
+ max_config |= 0x10; /* 16 bit capture DMA */
+
+ if (gus_dma2 > 3)
+ max_config |= 0x20; /* 16 bit playback DMA */
+
+ max_config |= (gus_base >> 4) & 0x0f; /* Extract the X from 2X0 */
+
+ outb((max_config), gus_base + 0x106); /* UltraMax control */
+ }
+
+ if (ad1848_detect(gus_base + 0x10c, &ad_flags, hw_config->osp))
+ {
+ char *name = "GUS MAX";
+ int old_num_mixers = num_mixers;
+
+ if (gus_pnp_flag)
+ name = "GUS PnP";
+
+ gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
+ gus_wave_volume = 90;
+ have_gus_max = 1;
+ if (hw_config->name)
+ name = hw_config->name;
+
+ hw_config->slots[1] = ad1848_init(name, gus_base + 0x10c,
+ -irq, gus_dma2, /* Playback DMA */
+ gus_dma, /* Capture DMA */
+ 1, /* Share DMA channels with GF1 */
+ hw_config->osp);
+
+ if (num_mixers > old_num_mixers)
+ {
+ /* GUS has it's own mixer map */
+ AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_SYNTH);
+ AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
+ AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
+ }
+ }
+ else
+ printk(KERN_WARNING "GUS: No CS4231 ??");
#else
- printk("\n\n\nGUS MAX support was not compiled in!!!\n\n\n\n");
+ printk(KERN_ERR "GUS MAX found, but not compiled in\n");
#endif
- }
- } else
- {
- /*
- * ASIC not detected so the card must be 2.2 or 2.4.
- * There could still be the 16-bit/mixer daughter card.
- */
- }
+ }
+ }
+ else
+ {
+ /*
+ * ASIC not detected so the card must be 2.2 or 2.4.
+ * There could still be the 16-bit/mixer daughter card.
+ */
+ }
if (hw_config->name)
- {
-
- strncpy(tmp, hw_config->name, 45);
- tmp[45] = 0;
- sprintf(tmp2, "%s (%dk)", tmp, (int) gus_mem_size / 1024);
- tmp2[sizeof(tmp2) - 1] = 0;
- } else if (gus_pnp_flag)
- {
- sprintf(tmp2, "Gravis UltraSound PnP (%dk)",
- (int) gus_mem_size / 1024);
- } else
+ {
+ strncpy(tmp, hw_config->name, 45);
+ tmp[45] = 0;
+ sprintf(tmp2, "%s (%dk)", tmp, (int) gus_mem_size / 1024);
+ tmp2[sizeof(tmp2) - 1] = 0;
+ }
+ else if (gus_pnp_flag)
+ {
+ sprintf(tmp2, "Gravis UltraSound PnP (%dk)",
+ (int) gus_mem_size / 1024);
+ }
+ else
sprintf(tmp2, "Gravis UltraSound %s (%dk)", model_num, (int) gus_mem_size / 1024);
- samples = (struct patch_info *) (sound_mem_blocks[sound_nblocks] = vmalloc((MAX_SAMPLE + 1) * sizeof(*samples)));
- sound_mem_sizes[sound_nblocks] = (MAX_SAMPLE + 1) * sizeof(*samples);
- if (sound_nblocks < 1024)
- sound_nblocks++;;
+ samples = (struct patch_info *)vmalloc((MAX_SAMPLE + 1) * sizeof(*samples));
if (samples == NULL)
- {
- printk(KERN_WARNING "gus_init: Cant allocate memory for instrument tables\n");
- return;
- }
+ {
+ printk(KERN_WARNING "gus_init: Cant allocate memory for instrument tables\n");
+ return;
+ }
conf_printf(tmp2, hw_config);
tmp2[sizeof(gus_info.name) - 1] = 0;
strcpy(gus_info.name, tmp2);
@@ -3182,27 +3099,28 @@ gus_wave_init(struct address_info *hw_config)
if ((sdev = sound_alloc_synthdev()) == -1)
printk(KERN_WARNING "gus_init: Too many synthesizers\n");
else
- {
- voice_alloc = &guswave_operations.alloc;
- if (iw_mode)
- guswave_operations.id = "IWAVE";
- hw_config->slots[0] = sdev;
- synth_devs[sdev] = &guswave_operations;
- sequencer_init();
+ {
+ voice_alloc = &guswave_operations.alloc;
+ if (iw_mode)
+ guswave_operations.id = "IWAVE";
+ hw_config->slots[0] = sdev;
+ synth_devs[sdev] = &guswave_operations;
+ sequencer_init();
#if defined(CONFIG_SEQUENCER) || defined(MODULE)
- gus_tmr_install(gus_base + 8);
+ gus_tmr_install(gus_base + 8);
#endif
- }
+ }
reset_sample_memory();
gus_initialize();
if (gus_mem_size > 0)
+ {
if ((dev = sound_alloc_audiodev()) != -1)
- {
- hw_config->slots[4] = dev;
- if ((gus_devnum = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
+ {
+ hw_config->slots[4] = dev;
+ if ((gus_devnum = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
"Ultrasound",
&gus_audio_driver,
sizeof(struct audio_driver),
@@ -3213,56 +3131,58 @@ gus_wave_init(struct address_info *hw_config)
NULL,
dma,
dma2)) < 0)
- return;
-
- audio_devs[gus_devnum]->min_fragment = 9; /* 512k */
- audio_devs[gus_devnum]->max_fragment = 11; /* 8k (must match size of bounce_buf */
- audio_devs[gus_devnum]->mixer_dev = -1; /* Next mixer# */
- audio_devs[gus_devnum]->flags |= DMA_HARDSTOP;
+ {
+ return;
+ }
+
+ audio_devs[gus_devnum]->min_fragment = 9; /* 512k */
+ audio_devs[gus_devnum]->max_fragment = 11; /* 8k (must match size of bounce_buf */
+ audio_devs[gus_devnum]->mixer_dev = -1; /* Next mixer# */
+ audio_devs[gus_devnum]->flags |= DMA_HARDSTOP;
} else
- printk("GUS: Too many audio devices available\n");
-
+ printk(KERN_WARNING "GUS: Too many audio devices available\n");
+ }
+
/*
- * Mixer dependent initialization.
+ * Mixer dependent initialization.
*/
switch (mixer_type)
- {
- case ICS2101:
- gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
- gus_wave_volume = 90;
- request_region(u_MixSelect, 1, "GUS mixer");
- hw_config->slots[5] = ics2101_mixer_init();
- audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5]; /* Next mixer# */
- return;
-
- case CS4231:
- /* Initialized elsewhere (ad1848.c) */
- default:
- hw_config->slots[5] = gus_default_mixer_init();
- audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5]; /* Next mixer# */
- return;
- }
-}
-
-void
-gus_wave_unload(struct address_info *hw_config)
+ {
+ case ICS2101:
+ gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
+ gus_wave_volume = 90;
+ request_region(u_MixSelect, 1, "GUS mixer");
+ hw_config->slots[5] = ics2101_mixer_init();
+ audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5]; /* Next mixer# */
+ return;
+
+ case CS4231:
+ /* Initialized elsewhere (ad1848.c) */
+ default:
+ hw_config->slots[5] = gus_default_mixer_init();
+ audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5]; /* Next mixer# */
+ return;
+ }
+}
+
+void gus_wave_unload(struct address_info *hw_config)
{
#ifdef CONFIG_GUSMAX
if (have_gus_max)
- {
- ad1848_unload(gus_base + 0x10c,
+ {
+ ad1848_unload(gus_base + 0x10c,
-gus_irq,
gus_dma2, /* Playback DMA */
gus_dma, /* Capture DMA */
1); /* Share DMA channels with GF1 */
- }
+ }
#endif
if (mixer_type == ICS2101)
- {
- release_region(u_MixSelect, 1);
- }
+ {
+ release_region(u_MixSelect, 1);
+ }
if (hw_config->slots[0] != -1)
sound_unload_synthdev(hw_config->slots[0]);
if (hw_config->slots[1] != -1)
@@ -3272,11 +3192,14 @@ gus_wave_unload(struct address_info *hw_config)
if (hw_config->slots[4] != -1)
sound_unload_audiodev(hw_config->slots[4]);
if (hw_config->slots[5] != -1)
- sound_unload_mixerdev(hw_config->slots[4]);
+ sound_unload_mixerdev(hw_config->slots[5]);
+
+ if(samples)
+ vfree(samples);
+ samples=NULL;
}
-static void
-do_loop_irq(int voice)
+static void do_loop_irq(int voice)
{
unsigned char tmp;
int mode, parm;
@@ -3300,78 +3223,77 @@ do_loop_irq(int voice)
parm = voices[voice].loop_irq_parm;
switch (mode)
- {
-
- case LMODE_FINISH: /*
- * Final loop finished, shoot volume down
- */
+ {
+ case LMODE_FINISH: /*
+ * Final loop finished, shoot volume down
+ */
- if ((int) (gus_read16(0x09) >> 4) < 100) /*
- * Get current volume
- */
- {
- gus_voice_off();
- gus_rampoff();
- gus_voice_init(voice);
- break;
- }
- gus_ramp_range(65, 4065);
- gus_ramp_rate(0, 63); /*
- * Fastest possible rate
- */
- gus_rampon(0x20 | 0x40); /*
- * Ramp down, once, irq
- */
- voices[voice].volume_irq_mode = VMODE_HALT;
- break;
-
- case LMODE_PCM_STOP:
- pcm_active = 0; /* Signal to the play_next_pcm_block routine */
- case LMODE_PCM:
- {
-
- pcm_qlen--;
- pcm_head = (pcm_head + 1) % pcm_nblk;
- if (pcm_qlen && pcm_active)
- {
- play_next_pcm_block();
- } else
- { /* Underrun. Just stop the voice */
- gus_select_voice(0); /* Left channel */
- gus_voice_off();
- gus_rampoff();
- gus_select_voice(1); /* Right channel */
- gus_voice_off();
- gus_rampoff();
- pcm_active = 0;
- }
-
- /*
- * If the queue was full before this interrupt, the DMA transfer was
- * suspended. Let it continue now.
- */
- if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
- DMAbuf_outputintr(gus_devnum, 0);
- }
- break;
-
- default:;
- }
+ if ((int) (gus_read16(0x09) >> 4) < 100) /*
+ * Get current volume
+ */
+ {
+ gus_voice_off();
+ gus_rampoff();
+ gus_voice_init(voice);
+ break;
+ }
+ gus_ramp_range(65, 4065);
+ gus_ramp_rate(0, 63); /*
+ * Fastest possible rate
+ */
+ gus_rampon(0x20 | 0x40); /*
+ * Ramp down, once, irq
+ */
+ voices[voice].volume_irq_mode = VMODE_HALT;
+ break;
+
+ case LMODE_PCM_STOP:
+ pcm_active = 0; /* Signal to the play_next_pcm_block routine */
+ case LMODE_PCM:
+ {
+ pcm_qlen--;
+ pcm_head = (pcm_head + 1) % pcm_nblk;
+ if (pcm_qlen && pcm_active)
+ {
+ play_next_pcm_block();
+ }
+ else
+ {
+ /* Underrun. Just stop the voice */
+ gus_select_voice(0); /* Left channel */
+ gus_voice_off();
+ gus_rampoff();
+ gus_select_voice(1); /* Right channel */
+ gus_voice_off();
+ gus_rampoff();
+ pcm_active = 0;
+ }
+
+ /*
+ * If the queue was full before this interrupt, the DMA transfer was
+ * suspended. Let it continue now.
+ */
+
+ if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
+ DMAbuf_outputintr(gus_devnum, 0);
+ }
+ break;
+
+ default:
+ }
restore_flags(flags);
}
-static void
-do_volume_irq(int voice)
+static void do_volume_irq(int voice)
{
- unsigned char tmp;
- int mode, parm;
- unsigned long flags;
+ unsigned char tmp;
+ int mode, parm;
+ unsigned long flags;
save_flags(flags);
cli();
gus_select_voice(voice);
-
tmp = gus_read8(0x0d);
tmp &= ~0x20; /*
* Disable volume ramp IRQ
@@ -3383,138 +3305,132 @@ do_volume_irq(int voice)
parm = voices[voice].volume_irq_parm;
switch (mode)
- {
- case VMODE_HALT: /* Decay phase finished */
- if (iw_mode)
- gus_write8(0x15, 0x02); /* Set voice deactivate bit of SMSI */
- restore_flags(flags);
- gus_voice_init(voice);
- break;
-
- case VMODE_ENVELOPE:
- gus_rampoff();
- restore_flags(flags);
- step_envelope(voice);
- break;
-
- case VMODE_START_NOTE:
- restore_flags(flags);
- guswave_start_note2(voices[voice].dev_pending, voice,
+ {
+ case VMODE_HALT: /* Decay phase finished */
+ if (iw_mode)
+ gus_write8(0x15, 0x02); /* Set voice deactivate bit of SMSI */
+ restore_flags(flags);
+ gus_voice_init(voice);
+ break;
+
+ case VMODE_ENVELOPE:
+ gus_rampoff();
+ restore_flags(flags);
+ step_envelope(voice);
+ break;
+
+ case VMODE_START_NOTE:
+ restore_flags(flags);
+ guswave_start_note2(voices[voice].dev_pending, voice,
voices[voice].note_pending, voices[voice].volume_pending);
- if (voices[voice].kill_pending)
- guswave_kill_note(voices[voice].dev_pending, voice,
+ if (voices[voice].kill_pending)
+ guswave_kill_note(voices[voice].dev_pending, voice,
voices[voice].note_pending, 0);
- if (voices[voice].sample_pending >= 0)
- {
- guswave_set_instr(voices[voice].dev_pending, voice,
- voices[voice].sample_pending);
- voices[voice].sample_pending = -1;
- }
- break;
-
- default:
- restore_flags(flags);
- }
+ if (voices[voice].sample_pending >= 0)
+ {
+ guswave_set_instr(voices[voice].dev_pending, voice,
+ voices[voice].sample_pending);
+ voices[voice].sample_pending = -1;
+ }
+ break;
+
+ default:
+ restore_flags(flags);
+ }
restore_flags(flags);
}
-void
-gus_voice_irq(void)
+void gus_voice_irq(void)
{
- unsigned long wave_ignore = 0, volume_ignore = 0;
- unsigned long voice_bit;
+ unsigned long wave_ignore = 0, volume_ignore = 0;
+ unsigned long voice_bit;
- unsigned char src, voice;
+ unsigned char src, voice;
while (1)
- {
- src = gus_read8(0x0f); /*
- * Get source info
- */
- voice = src & 0x1f;
- src &= 0xc0;
-
- if (src == (0x80 | 0x40))
- return; /*
- * No interrupt
+ {
+ src = gus_read8(0x0f); /*
+ * Get source info
*/
+ voice = src & 0x1f;
+ src &= 0xc0;
- voice_bit = 1 << voice;
+ if (src == (0x80 | 0x40))
+ return; /*
+ * No interrupt
+ */
+
+ voice_bit = 1 << voice;
- if (!(src & 0x80)) /*
+ if (!(src & 0x80)) /*
* Wave IRQ pending
*/
- if (!(wave_ignore & voice_bit) && (int) voice < nr_voices) /*
- * Not done
- * yet
+ if (!(wave_ignore & voice_bit) && (int) voice < nr_voices) /*
+ * Not done
+ * yet
*/
- {
- wave_ignore |= voice_bit;
- do_loop_irq(voice);
- }
- if (!(src & 0x40)) /*
+ {
+ wave_ignore |= voice_bit;
+ do_loop_irq(voice);
+ }
+ if (!(src & 0x40)) /*
* Volume IRQ pending
*/
- if (!(volume_ignore & voice_bit) && (int) voice < nr_voices) /*
+ if (!(volume_ignore & voice_bit) && (int) voice < nr_voices) /*
* Not done
* yet
*/
- {
- volume_ignore |= voice_bit;
- do_volume_irq(voice);
- }
- }
+ {
+ volume_ignore |= voice_bit;
+ do_volume_irq(voice);
+ }
+ }
}
-void
-guswave_dma_irq(void)
+void guswave_dma_irq(void)
{
unsigned char status;
status = gus_look8(0x41); /* Get DMA IRQ Status */
if (status & 0x40) /* DMA interrupt pending */
switch (active_device)
- {
- case GUS_DEV_WAVE:
- if ((dram_sleep_flag.opts & WK_SLEEP))
- {
- dram_sleep_flag.opts = WK_WAKEUP;
- wake_up(&dram_sleeper);
- };
- break;
-
- case GUS_DEV_PCM_CONTINUE: /* Left channel data transferred */
- gus_write8(0x41, 0); /* Disable GF1 DMA */
- gus_transfer_output_block(pcm_current_dev, pcm_current_buf,
- pcm_current_count,
+ {
+ case GUS_DEV_WAVE:
+ wake_up(&dram_sleeper);
+ break;
+
+ case GUS_DEV_PCM_CONTINUE: /* Left channel data transferred */
+ gus_write8(0x41, 0); /* Disable GF1 DMA */
+ gus_transfer_output_block(pcm_current_dev, pcm_current_buf,
+ pcm_current_count,
pcm_current_intrflag, 1);
- break;
-
- case GUS_DEV_PCM_DONE: /* Right or mono channel data transferred */
- gus_write8(0x41, 0); /* Disable GF1 DMA */
- if (pcm_qlen < pcm_nblk)
- {
- dma_active = 0;
- if (gus_busy)
- {
- if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
- DMAbuf_outputintr(gus_devnum, 0);
- }
- }
- break;
-
- default:;
- }
+ break;
+
+ case GUS_DEV_PCM_DONE: /* Right or mono channel data transferred */
+ gus_write8(0x41, 0); /* Disable GF1 DMA */
+ if (pcm_qlen < pcm_nblk)
+ {
+ dma_active = 0;
+ if (gus_busy)
+ {
+ if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
+ DMAbuf_outputintr(gus_devnum, 0);
+ }
+ }
+ break;
+
+ default:
+ }
status = gus_look8(0x49); /*
* Get Sampling IRQ Status
*/
if (status & 0x40) /*
* Sampling Irq pending
*/
- {
- DMAbuf_inputintr(gus_devnum);
- }
+ {
+ DMAbuf_inputintr(gus_devnum);
+ }
}
#if defined(CONFIG_SEQUENCER) || defined(MODULE)
@@ -3526,10 +3442,9 @@ guswave_dma_irq(void)
static volatile int select_addr, data_addr;
static volatile int curr_timer = 0;
-void
-gus_timer_command(unsigned int addr, unsigned int val)
+void gus_timer_command(unsigned int addr, unsigned int val)
{
- int i;
+ int i;
outb(((unsigned char) (addr & 0xff)), select_addr);
@@ -3542,59 +3457,54 @@ gus_timer_command(unsigned int addr, unsigned int val)
inb(select_addr);
}
-static void
-arm_timer(int timer, unsigned int interval)
+static void arm_timer(int timer, unsigned int interval)
{
-
curr_timer = timer;
if (timer == 1)
- {
- gus_write8(0x46, 256 - interval); /* Set counter for timer 1 */
- gus_write8(0x45, 0x04); /* Enable timer 1 IRQ */
- gus_timer_command(0x04, 0x01); /* Start timer 1 */
- } else
- {
- gus_write8(0x47, 256 - interval); /* Set counter for timer 2 */
- gus_write8(0x45, 0x08); /* Enable timer 2 IRQ */
- gus_timer_command(0x04, 0x02); /* Start timer 2 */
- }
+ {
+ gus_write8(0x46, 256 - interval); /* Set counter for timer 1 */
+ gus_write8(0x45, 0x04); /* Enable timer 1 IRQ */
+ gus_timer_command(0x04, 0x01); /* Start timer 1 */
+ }
+ else
+ {
+ gus_write8(0x47, 256 - interval); /* Set counter for timer 2 */
+ gus_write8(0x45, 0x08); /* Enable timer 2 IRQ */
+ gus_timer_command(0x04, 0x02); /* Start timer 2 */
+ }
gus_timer_enabled = 1;
}
-static unsigned int
-gus_tmr_start(int dev, unsigned int usecs_per_tick)
+static unsigned int gus_tmr_start(int dev, unsigned int usecs_per_tick)
{
- int timer_no, resolution;
- int divisor;
+ int timer_no, resolution;
+ int divisor;
if (usecs_per_tick > (256 * 80))
- {
- timer_no = 2;
- resolution = 320; /* usec */
- } else
- {
- timer_no = 1;
- resolution = 80; /* usec */
- }
-
+ {
+ timer_no = 2;
+ resolution = 320; /* usec */
+ }
+ else
+ {
+ timer_no = 1;
+ resolution = 80; /* usec */
+ }
divisor = (usecs_per_tick + (resolution / 2)) / resolution;
-
arm_timer(timer_no, divisor);
return divisor * resolution;
}
-static void
-gus_tmr_disable(int dev)
+static void gus_tmr_disable(int dev)
{
gus_write8(0x45, 0); /* Disable both timers */
gus_timer_enabled = 0;
}
-static void
-gus_tmr_restart(int dev)
+static void gus_tmr_restart(int dev)
{
if (curr_timer == 1)
gus_write8(0x45, 0x04); /* Start timer 1 again */
@@ -3612,8 +3522,7 @@ static struct sound_lowlev_timer gus_tmr =
gus_tmr_restart
};
-static void
-gus_tmr_install(int io_base)
+static void gus_tmr_install(int io_base)
{
struct sound_lowlev_timer *tmr;
diff --git a/drivers/sound/hex2hex.c b/drivers/sound/hex2hex.c
new file mode 100644
index 000000000..19753bfc2
--- /dev/null
+++ b/drivers/sound/hex2hex.c
@@ -0,0 +1,87 @@
+/*
+ * hex2hex reads stdin in Intel HEX format and produces an
+ * (unsigned char) array which contains the bytes and writes it
+ * to stdout using C syntax
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ABANDON(why) { fprintf(stderr, "%s\n", why); exit(1); }
+#define MAX_SIZE (256*1024)
+unsigned char buf[MAX_SIZE];
+
+int loadhex(FILE *inf, unsigned char *buf)
+{
+ int l=0, c, i;
+
+ while ((c=getc(inf))!=EOF)
+ {
+ if (c == ':') /* Sync with beginning of line */
+ {
+ int n, check;
+ unsigned char sum;
+ int addr;
+ int linetype;
+
+ if (fscanf(inf, "%02x", &n) != 1)
+ ABANDON("File format error");
+ sum = n;
+
+ if (fscanf(inf, "%04x", &addr) != 1)
+ ABANDON("File format error");
+ sum += addr/256;
+ sum += addr%256;
+
+ if (fscanf(inf, "%02x", &linetype) != 1)
+ ABANDON("File format error");
+ sum += linetype;
+
+ if (linetype != 0)
+ continue;
+
+ for (i=0;i<n;i++)
+ {
+ if (fscanf(inf, "%02x", &c) != 1)
+ ABANDON("File format error");
+ if (addr >= MAX_SIZE)
+ ABANDON("File too large");
+ buf[addr++] = c;
+ if (addr > l)
+ l = addr;
+ sum += c;
+ }
+
+ if (fscanf(inf, "%02x", &check) != 1)
+ ABANDON("File format error");
+
+ sum = ~sum + 1;
+ if (check != sum)
+ ABANDON("Line checksum error");
+ }
+ }
+
+ return l;
+}
+
+int main( int argc, const char * argv [] )
+{
+ const char * varline = argv[1];
+ int i,l;
+
+ l = loadhex(stdin, buf);
+
+ printf("/*\n *\t Computer generated file. Do not edit.\n */\n");
+ printf("static int %s_len = %d;\n", varline, l);
+ printf("static unsigned char %s[] = {\n", varline);
+
+ for (i=0;i<l;i++)
+ {
+ if (i) printf(",");
+ if (i && !(i % 16)) printf("\n");
+ printf("0x%02x", buf[i]);
+ }
+
+ printf("\n};\n\n");
+ return 0;
+}
diff --git a/drivers/sound/hex2hex.h b/drivers/sound/hex2hex.h
deleted file mode 100644
index 05d12b1cf..000000000
--- a/drivers/sound/hex2hex.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * This file is a part of configure.c
- *
- * hex2hex reads an input file in Intel HEX format and produces
- * an (unsigned char) array which contains the bytes and writes it to the
- * output file using C syntax
- */
-
-#define MAX_SIZE (256*1024)
-#define ABANDON(why) { \
- fprintf(stderr, "%s: " why "\n", source); \
- return 0; \
- }
-
-int loadhex(FILE *inf, unsigned char *buf, char *source)
-{
- int l=0, c, i;
-
- while ((c=getc(inf))!=EOF)
- {
- if (c == ':') /* Sync with beginning of line */
- {
- int n, check;
- unsigned char sum;
- int addr;
- int linetype;
-
- if (fscanf(inf, "%02x", &n) != 1)
- ABANDON("File format error");
- sum = n;
-
- if (fscanf(inf, "%04x", &addr) != 1)
- ABANDON("File format error");
- sum += addr/256;
- sum += addr%256;
-
- if (fscanf(inf, "%02x", &linetype) != 1)
- ABANDON("File format error");
- sum += linetype;
-
- if (linetype != 0)
- continue;
-
- for (i=0;i<n;i++)
- {
- if (fscanf(inf, "%02x", &c) != 1)
- ABANDON("File format error");
- if (addr >= MAX_SIZE)
- ABANDON("File too large");
- buf[addr++] = c;
- if (addr > l)
- l = addr;
- sum += c;
- }
-
- if (fscanf(inf, "%02x", &check) != 1)
- ABANDON("File format error");
-
- sum = ~sum + 1;
- if (check != sum)
- ABANDON("Line checksum error");
- }
- }
-
- return l;
-}
-
-int hex2hex(char *source, char *target, char *varline)
-{
- FILE *inf, *outf;
-
- int i,l;
- unsigned char buf[MAX_SIZE];
-
- if ((inf=fopen(source, "r"))==NULL)
- {
- perror(source);
- return 0;
- }
-
- if ((outf=fopen(target, "w"))==NULL)
- {
- perror(target);
- fclose(inf);
- return 0;
- }
-
- l=loadhex(inf, buf, source);
- if (l<=0)
- {
- fclose(inf);
- fclose(outf);
- return l;
- }
-
-
- fprintf(outf, "/*\n *\t Computer generated file. Do not edit.\n */\n");
- fprintf(outf, "static int %s_len = %d;\n", varline, l);
- fprintf(outf, "static unsigned char %s[] = {\n", varline);
-
- for (i=0;i<l;i++)
- {
- if (i) fprintf(outf, ",");
- if (i && !(i % 16)) fprintf(outf, "\n");
- fprintf(outf, "0x%02x", buf[i]);
- }
-
- fprintf(outf, "\n};\n\n");
- fclose(inf);
- fclose(outf);
- return 1;
-}
diff --git a/drivers/sound/ics2101.c b/drivers/sound/ics2101.c
index 3c47f5a50..35b82ac2c 100644
--- a/drivers/sound/ics2101.c
+++ b/drivers/sound/ics2101.c
@@ -10,11 +10,14 @@
* 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 "sound_config.h"
-#if defined(CONFIG_GUSHW) || defined(MODULE)
+#if defined(CONFIG_GUS) || defined(MODULE)
#include <linux/ultrasound.h>
#include "gus_hw.h"
@@ -115,79 +118,89 @@ static int set_volumes(int dev, int vol)
static int ics2101_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- {
- int val;
-
- val = *(int *) arg;
-
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- return gus_default_mixer_ioctl(dev, cmd, arg);
-
- case SOUND_MIXER_MIC:
- return (*(int *) arg = set_volumes(DEV_MIC, val));
-
- case SOUND_MIXER_CD:
- return (*(int *) arg = set_volumes(DEV_CD, val));
-
- case SOUND_MIXER_LINE:
- return (*(int *) arg = set_volumes(DEV_LINE, val));
-
- case SOUND_MIXER_SYNTH:
- return (*(int *) arg = set_volumes(DEV_GF1, val));
-
- case SOUND_MIXER_VOLUME:
- return (*(int *) arg = set_volumes(DEV_VOL, val));
-
- default:
- return -EINVAL;
+ int val;
+
+ if (((cmd >> 8) & 0xff) == 'M') {
+ if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
+
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ switch (cmd & 0xff) {
+ case SOUND_MIXER_RECSRC:
+ return gus_default_mixer_ioctl(dev, cmd, arg);
+
+ case SOUND_MIXER_MIC:
+ val = set_volumes(DEV_MIC, val);
+ break;
+
+ case SOUND_MIXER_CD:
+ val = set_volumes(DEV_CD, val);
+ break;
+
+ case SOUND_MIXER_LINE:
+ val = set_volumes(DEV_LINE, val);
+ break;
+
+ case SOUND_MIXER_SYNTH:
+ val = set_volumes(DEV_GF1, val);
+ break;
+
+ case SOUND_MIXER_VOLUME:
+ val = set_volumes(DEV_VOL, val);
+ break;
+
+ default:
+ return -EINVAL;
}
- }
- else
- {
- switch (cmd & 0xff) /*
- * Return parameters
- */
- {
-
- case SOUND_MIXER_RECSRC:
- return gus_default_mixer_ioctl(dev, cmd, arg);
-
- case SOUND_MIXER_DEVMASK:
- return (*(int *) arg = MIX_DEVS);
-
- case SOUND_MIXER_STEREODEVS:
- return (*(int *) arg = SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC);
-
- case SOUND_MIXER_RECMASK:
- return (*(int *) arg = SOUND_MASK_MIC | SOUND_MASK_LINE);
-
- case SOUND_MIXER_CAPS:
- return (*(int *) arg = 0);
- break;
-
- case SOUND_MIXER_MIC:
- return (*(int *) arg = volumes[DEV_MIC]);
-
- case SOUND_MIXER_LINE:
- return (*(int *) arg = volumes[DEV_LINE]);
-
- case SOUND_MIXER_CD:
- return (*(int *) arg = volumes[DEV_CD]);
-
- case SOUND_MIXER_VOLUME:
- return (*(int *) arg = volumes[DEV_VOL]);
-
- case SOUND_MIXER_SYNTH:
- return (*(int *) arg = volumes[DEV_GF1]);
-
- default:
- return -EINVAL;
+ return put_user(val, (int *)arg);
+ } else {
+ switch (cmd & 0xff) {
+ /*
+ * Return parameters
+ */
+ case SOUND_MIXER_RECSRC:
+ return gus_default_mixer_ioctl(dev, cmd, arg);
+
+ case SOUND_MIXER_DEVMASK:
+ val = MIX_DEVS;
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ val = SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC;
+ break;
+
+ case SOUND_MIXER_RECMASK:
+ val = SOUND_MASK_MIC | SOUND_MASK_LINE;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ val = 0;
+ break;
+
+ case SOUND_MIXER_MIC:
+ val = volumes[DEV_MIC];
+ break;
+
+ case SOUND_MIXER_LINE:
+ val = volumes[DEV_LINE];
+ break;
+
+ case SOUND_MIXER_CD:
+ val = volumes[DEV_CD];
+ break;
+
+ case SOUND_MIXER_VOLUME:
+ val = volumes[DEV_VOL];
+ break;
+
+ case SOUND_MIXER_SYNTH:
+ val = volumes[DEV_GF1];
+ break;
+
+ default:
+ return -EINVAL;
}
+ return put_user(val, (int *)arg);
}
}
return -EINVAL;
@@ -208,7 +221,6 @@ ics2101_mixer_init(void)
if ((n = sound_alloc_mixerdev()) != -1)
{
- n = num_mixers;
mixer_devs[n] = &ics2101_mixer_operations;
/*
diff --git a/drivers/sound/local.h.master b/drivers/sound/local.h.master
index 91ad38d1d..b333f0ce0 100644
--- a/drivers/sound/local.h.master
+++ b/drivers/sound/local.h.master
@@ -1,118 +1,6 @@
/* Computer generated file. Please don't edit! */
-#define KERNEL_COMPATIBLE_CONFIG
-
-#define SELECTED_SOUND_OPTIONS 0x00000000
-
-#if \
- defined(CONFIG_PSS) || defined(CONFIG_SSCAPE) || \
- defined(CONFIG_CS4232) || defined(CONFIG_MAUI) || \
- defined(CONFIG_PSS_MODULE) || defined(CONFIG_SSCAPE_MODULE) || \
- defined(CONFIG_CS4232_MODULE) || defined(CONFIG_MAUI_MODULE)
-# define CONFIG_MPU_EMU
-#endif
-
-#if \
- defined(CONFIG_PSS) || defined(CONFIG_GUS16) || \
- defined(CONFIG_GUSMAX) || defined(CONFIG_MSS) || \
- defined(CONFIG_SSCAPE) || defined(CONFIG_TRIX) || \
- defined(CONFIG_MAD16) || defined(CONFIG_CS4232) || \
- defined(CONFIG_PSS_MODULE) || defined(CONFIG_GUS16_MODULE) || \
- defined(CONFIG_GUSMAX_MODULE) || defined(CONFIG_MSS_MODULE) || \
- defined(CONFIG_SSCAPE_MODULE) || defined(CONFIG_TRIX_MODULE) || \
- defined(CONFIG_MAD16_MODULE) || defined(CONFIG_CS4232_MODULE)
-# define CONFIG_AD1848
-#endif
-
-#if \
- defined(CONFIG_PAS) || defined(CONFIG_SB) || \
- defined(CONFIG_GUS) || defined(CONFIG_PSS) || \
- defined(CONFIG_GUS16) || defined(CONFIG_GUSMAX) || \
- defined(CONFIG_MSS) || defined(CONFIG_SSCAPE) || \
- defined(CONFIG_TRIX) || defined(CONFIG_MAD16) || \
- defined(CONFIG_CS4232) || defined(CONFIG_OPL3SA1) || \
- defined(CONFIG_SOFTOSS) || \
- defined(CONFIG_PAS_MODULE) || defined(CONFIG_SB_MODULE) || \
- defined(CONFIG_GUS_MODULE) || defined(CONFIG_PSS_MODULE) || \
- defined(CONFIG_GUS16_MODULE) || defined(CONFIG_GUSMAX_MODULE) || \
- 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)
-# define CONFIG_AUDIO
-#endif
-
-#if \
- defined(CONFIG_PAS) || defined(CONFIG_SB) || \
- defined(CONFIG_GUS) || defined(CONFIG_MPU401) || \
- defined(CONFIG_PSS) || defined(CONFIG_GUS16) || \
- defined(CONFIG_GUSMAX) || defined(CONFIG_SSCAPE) || \
- defined(CONFIG_TRIX) || defined(CONFIG_MAD16) || \
- defined(CONFIG_CS4232) || defined(CONFIG_MAUI) || \
- defined(CONFIG_OPL3SA1) || defined(CONFIG_SOFTOSS) || \
- defined(CONFIG_PAS_MODULE) || defined(CONFIG_SB_MODULE) || \
- defined(CONFIG_GUS_MODULE) || defined(CONFIG_MPU401_MODULE) || \
- defined(CONFIG_PSS_MODULE) || defined(CONFIG_GUS16_MODULE) || \
- defined(CONFIG_GUSMAX_MODULE) || defined(CONFIG_SSCAPE_MODULE) || \
- defined(CONFIG_TRIX_MODULE) || defined(CONFIG_MAD16_MODULE) || \
- defined(CONFIG_CS4232_MODULE) || defined(CONFIG_MAUI_MODULE) || \
- defined(CONFIG_OPL3SA1_MODULE) || defined(CONFIG_SOFTOSS_MODULE)
-# define CONFIG_MIDI
-#endif
-
-#if \
- defined(CONFIG_SB) || defined(CONFIG_TRIX) || \
- defined(CONFIG_MAD16) || \
- defined(CONFIG_SB_MODULE) || defined(CONFIG_TRIX_MODULE) || \
- defined(CONFIG_MAD16_MODULE)
-# define CONFIG_SBDSP
-#endif
-#if \
- defined(CONFIG_SB_MODULE) || defined(CONFIG_TRIX_MODULE) || \
- defined(CONFIG_MAD16_MODULE)
-# define CONFIG_SBDSP_MODULE
-#endif
-
-#if \
- defined(CONFIG_SB) || defined(CONFIG_TRIX) || \
- defined(CONFIG_MAD16) || defined(CONFIG_SB_MODULE) || \
- defined(CONFIG_TRIX_MODULE) || defined(CONFIG_MAD16_MODULE)
-# define CONFIG_UART401
-#endif
-
-#if \
- defined(CONFIG_SB_MODULE) || defined(CONFIG_TRIX_MODULE) || \
- defined(CONFIG_MAD16_MODULE)
-#ifndef CONFIG_UART401_MODULE
-#define CONFIG_UART401_MODULE
-#endif
-#endif
-
-#if \
- defined(CONFIG_PAS) || defined(CONFIG_SB) || \
- defined(CONFIG_ADLIB) || defined(CONFIG_GUS) || \
- defined(CONFIG_MPU401) || defined(CONFIG_PSS) || \
- defined(CONFIG_SSCAPE) || defined(CONFIG_TRIX) || \
- defined(CONFIG_MAD16) || defined(CONFIG_CS4232) || \
- defined(CONFIG_MAUI) || \
- defined(CONFIG_PAS_MODULE) || defined(CONFIG_SB_MODULE) || \
- defined(CONFIG_ADLIB_MODULE) || defined(CONFIG_GUS_MODULE) || \
- defined(CONFIG_MPU401_MODULE) || defined(CONFIG_PSS_MODULE) || \
- defined(CONFIG_SSCAPE_MODULE) || defined(CONFIG_TRIX_MODULE) || \
- defined(CONFIG_MAD16_MODULE) || defined(CONFIG_CS4232_MODULE) || \
- defined(CONFIG_MAUI_MODULE)
-# define CONFIG_SEQUENCER
-#endif
-
-/*
- * Force on additional support
- */
-
-#define SM_WAVE
-#define __SGNXPRO__
-#define SM_GAMES
-#define DESKPROXL
-/* Computer generated file. Please don't edit! */
+#include <linux/config.h>
#define KERNEL_COMPATIBLE_CONFIG
@@ -131,10 +19,12 @@
defined(CONFIG_GUSMAX) || defined(CONFIG_MSS) || \
defined(CONFIG_SSCAPE) || defined(CONFIG_TRIX) || \
defined(CONFIG_MAD16) || defined(CONFIG_CS4232) || \
+ defined(CONFIG_OPL3SA1) || \
defined(CONFIG_PSS_MODULE) || defined(CONFIG_GUS16_MODULE) || \
defined(CONFIG_GUSMAX_MODULE) || defined(CONFIG_MSS_MODULE) || \
defined(CONFIG_SSCAPE_MODULE) || defined(CONFIG_TRIX_MODULE) || \
- defined(CONFIG_MAD16_MODULE) || defined(CONFIG_CS4232_MODULE)
+ defined(CONFIG_MAD16_MODULE) || defined(CONFIG_CS4232_MODULE) || \
+ defined(CONFIG_OPL3SA1_MODULE)
# define CONFIG_AD1848
#endif
@@ -208,13 +98,13 @@
defined(CONFIG_MPU401) || defined(CONFIG_PSS) || \
defined(CONFIG_SSCAPE) || defined(CONFIG_TRIX) || \
defined(CONFIG_MAD16) || defined(CONFIG_CS4232) || \
- defined(CONFIG_MAUI) || \
+ defined(CONFIG_MAUI) || defined(CONFIG_OPL3SA1) || \
defined(CONFIG_PAS_MODULE) || defined(CONFIG_SB_MODULE) || \
defined(CONFIG_ADLIB_MODULE) || defined(CONFIG_GUS_MODULE) || \
defined(CONFIG_MPU401_MODULE) || defined(CONFIG_PSS_MODULE) || \
defined(CONFIG_SSCAPE_MODULE) || defined(CONFIG_TRIX_MODULE) || \
defined(CONFIG_MAD16_MODULE) || defined(CONFIG_CS4232_MODULE) || \
- defined(CONFIG_MAUI_MODULE)
+ defined(CONFIG_MAUI_MODULE) || defined(CONFIG_OPL3SA1_MODULE)
# define CONFIG_SEQUENCER
#endif
@@ -224,5 +114,5 @@
#define SM_WAVE
#define __SGNXPRO__
-#define SM_GAMES
+/* #define SM_GAMES */
#define DESKPROXL
diff --git a/drivers/sound/lowlevel/.cvsignore b/drivers/sound/lowlevel/.cvsignore
index 4671378ae..857dd22e9 100644
--- a/drivers/sound/lowlevel/.cvsignore
+++ b/drivers/sound/lowlevel/.cvsignore
@@ -1 +1,2 @@
.depend
+.*.flags
diff --git a/drivers/sound/lowlevel/Config.tmpl b/drivers/sound/lowlevel/Config.tmpl
index a3864b96f..e3ad81dbb 100644
--- a/drivers/sound/lowlevel/Config.tmpl
+++ b/drivers/sound/lowlevel/Config.tmpl
@@ -14,10 +14,10 @@ if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
if [ "$CONFIG_AEDSP16_SBPRO" = "y" ]; then
comment 'Audio Excel DSP 16 [Sound Blaster Pro]'
hex 'I/O base for Audio Excel DSP 16 220 or 240' \
- AEDSP16_BASE $SBC_BASE
+ CONFIG_AEDSP16_BASE $CONFIG_SB_BASE
int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' \
- AEDSP16_SBC_IRQ $SBC_IRQ
- int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_SBC_DMA $SBC_DMA
+ CONFIG_AEDSP16_SB_IRQ $CONFIG_SB_IRQ
+ int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_SB_DMA $CONFIG_SB_DMA
fi
fi
@@ -25,10 +25,10 @@ if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
bool 'Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS
if [ "$CONFIG_AEDSP16_MSS" = "y" ]; then
comment 'Audio Excel DSP 16 [Microsoft Sound System]'
- hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220
+ hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220
int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' \
- AEDSP16_MSS_IRQ $MSS_IRQ
- int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_MSS_DMA $MSS_DMA
+ CONFIG_AEDSP16_MSS_IRQ $CONFIG_MSS_IRQ
+ int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_MSS_DMA $CONFIG_MSS_DMA
fi
fi
@@ -38,10 +38,10 @@ if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
comment 'Audio Excel DSP 16 [MPU-401]'
if [ "$CONFIG_AEDSP16_SBPRO" != "y" \
-a "$CONFIG_AEDSP16_MSS" != "y" ]; then
- hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220
+ hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220
fi
int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' \
- AEDSP16_MPU_IRQ $MPU_IRQ
+ CONFIG_AEDSP16_MPU_IRQ $CONFIG_MPU_IRQ
fi
fi
diff --git a/drivers/sound/lowlevel/Makefile b/drivers/sound/lowlevel/Makefile
index 1a4c6a396..0340b37b9 100644
--- a/drivers/sound/lowlevel/Makefile
+++ b/drivers/sound/lowlevel/Makefile
@@ -16,6 +16,10 @@ else
endif
ifeq ($(CONFIG_AEDSP16),y)
OBJS := $(OBJS) aedsp16.o
+else
+ ifeq ($(CONFIG_AEDSP16),m)
+ MX_OBJS := $(MX_OBJS) aedsp16.o
+ endif
endif
endif
@@ -23,9 +27,6 @@ ifndef TOPDIR
TOPDIR=/usr/src/linux
endif
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
lowlevel.o: $(OBJS)
$(LD) -r -o lowlevel.o $(OBJS)
diff --git a/drivers/sound/lowlevel/README.aedsp16 b/drivers/sound/lowlevel/README.aedsp16
index 7b61363a3..8f5b05afd 100644
--- a/drivers/sound/lowlevel/README.aedsp16
+++ b/drivers/sound/lowlevel/README.aedsp16
@@ -20,6 +20,37 @@ I you own a Gallant's audio card based on SC-6600, activate the SC-6600 support.
If you want to change the configuration of the sound board, be sure to
check off all the configuration items before re-configure it.
+Module parameters
+-----------------
+To use this driver as a module, you must configure some module parameters, to
+set up I/O addresses, IRQ lines and DMA channels. Some parameters are
+mandatory while some others are optional. Here a list of parameters you can
+use with this module:
+
+Name Description
+==== ===========
+MANDATORY
+io I/O base address (0x220 or 0x240)
+irq irq line (5, 7, 9, 10 or 11)
+dma dma channel (0, 1 or 3)
+
+OPTIONAL
+mss_base I/O base address for activate MSS mode (default SBPRO)
+ (0x530 or 0xE80)
+mpu_base I/O base address for activate MPU-401 mode
+ (0x300, 0x310, 0x320 or 0x330)
+mpu_irq MPU-401 irq line (5, 7, 9, 10 or 0)
+
+The /etc/conf.modules will have a line like this:
+
+options aedsp16 io=0x220 irq=10 dma=3 mss_base=0x530
+
+Of course, you must write the 'options' for all other subsequent modules,
+opl3, ad1848, adlib_card, sb
+
+Then you must load the sound modules stack in this order:
+sound -> aedsp16 -> [ ad1848, opl3 ]
+
Sound cards supported
---------------------
This driver supports the SC-6000 and SC-6600 based Gallant's sound card.
diff --git a/drivers/sound/lowlevel/aci.c b/drivers/sound/lowlevel/aci.c
index 7599d5a6c..84d5c73c2 100644
--- a/drivers/sound/lowlevel/aci.c
+++ b/drivers/sound/lowlevel/aci.c
@@ -58,6 +58,7 @@
*
*/
+#include <linux/config.h> /* for CONFIG_ACI_MIXER */
#include "lowlevel.h"
#include "../sound_config.h"
#include "lowlevel.h"
diff --git a/drivers/sound/lowlevel/aedsp16.c b/drivers/sound/lowlevel/aedsp16.c
index 93db242a1..cb919507e 100644
--- a/drivers/sound/lowlevel/aedsp16.c
+++ b/drivers/sound/lowlevel/aedsp16.c
@@ -1,8 +1,8 @@
/*
- sound/aedsp16.c
+ drivers/sound/lowlevel/aedsp16.c
Audio Excel DSP 16 software configuration routines
- Copyright (C) 1995 Riccardo Facchetti (riccardo@cdc8g5.cdc.polimi.it)
+ Copyright (C) 1995,1996,1997,1998 Riccardo Facchetti (fizban@tin.it)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,13 +24,24 @@
* headers needed by this source.
*/
#include <linux/config.h>
-#include "../sound_config.h"
#include <linux/delay.h>
+#include <linux/module.h>
+#include "../sound_config.h"
+#include "../soundmodule.h"
+
+/*
+ * Sanity checks
+ */
-#ifndef AEDSP16_BASE
-#undef CONFIG_AEDSP16
+#if !defined(CONFIG_AEDSP16_BASE)
+# undef CONFIG_AEDSP16
+#else
+# if defined(MODULE) && defined(CONFIG_AEDSP16_MODULE)
+# define CONFIG_AEDSP16 1
+# endif
#endif
+
#if defined(CONFIG_AEDSP16)
#if defined(CONFIG_AEDSP16_SBPRO) && defined(CONFIG_AEDSP16_MSS)
@@ -232,6 +243,11 @@
- Prep for merging with OSS Lite and Linux kernel 2.1.13
- Corrected a bug in request/check/release region calls (thanks to the
new kernel exception handling).
+ v1.1
+ - Revamped for integration with new modularized sound drivers: to enhance
+ the flexibility of modular version, I have removed all the conditional
+ compilation for SBPRO, MPU and MSS code. Now it is all managed with
+ the ae_config structure.
Known Problems:
- Audio Excel DSP 16 III don't work with this driver.
@@ -243,7 +259,7 @@
*/
-#define VERSION "1.0.0" /* Version of Audio Excel DSP 16 driver */
+#define VERSION "1.1" /* Version of Audio Excel DSP 16 driver */
#undef AEDSP16_DEBUG 1 /* Define this to enable debug code */
#undef AEDSP16_DEBUG_MORE 1 /* Define this to enable more debug */
@@ -439,6 +455,8 @@ struct aedsp16_info {
int irq; /* irq value for DSP I/O */
int mpu_irq; /* irq for mpu401 interface I/O */
int dma; /* dma value for DSP I/O */
+ int mss_base; /* base I/O for Microsoft Sound System */
+ int mpu_base; /* base I/O for MPU-401 emulation */
int init; /* Initialization status of the card */
};
@@ -477,6 +495,8 @@ static struct aedsp16_info ae_config = {
DEF_AEDSP16_IRQ,
DEF_AEDSP16_MRQ,
DEF_AEDSP16_DMA,
+ -1,
+ -1,
INIT_NONE
};
@@ -619,13 +639,9 @@ void aedsp16_hard_decode(void) {
/*
* Now set up the real kernel configuration.
*/
- decoded_hcfg.iobase = AEDSP16_BASE;
-#if defined(CONFIG_AEDSP16_MSS)
- decoded_hcfg.wssbase = MSS_BASE;
-#endif
-#if defined(CONFIG_AEDSP16_MPU401)
- decoded_hcfg.mpubase = MPU_BASE;
-#endif
+ decoded_hcfg.iobase = ae_config.base_io;
+ decoded_hcfg.wssbase = ae_config.mss_base;
+ decoded_hcfg.mpubase = ae_config.mpu_base;
#if defined(CONFIG_SC6600_JOY)
decoded_hcfg.joystick = CONFIG_SC6600_JOY; /* Enable */
@@ -805,8 +821,6 @@ static int aedsp16_cfg_write(int port) {
return TRUE;
}
-#if defined(CONFIG_AEDSP16_MSS)
-
static int aedsp16_init_mss(int port)
{
DBG(("aedsp16_init_mss:\n"));
@@ -824,15 +838,13 @@ static int aedsp16_init_mss(int port)
if (aedsp16_cfg_write(port) == FALSE)
return FALSE;
- outb(soft_cfg_1, MSS_BASE);
+ outb(soft_cfg_1, ae_config.mss_base);
DBG(("success.\n"));
return TRUE;
}
-#endif /* CONFIG_AEDSP16_MSS */
-
static int aedsp16_setup_board(int port) {
int loop = RETRY;
@@ -1082,15 +1094,15 @@ static int aedsp16_init_board(void)
return FALSE;
}
-#if defined(CONFIG_AEDSP16_MSS)
- if (ae_config.init & INIT_MSS) {
- if (aedsp16_init_mss(ae_config.base_io) == FALSE) {
- printk(
- "[AEDSP16] Can not initialize Microsoft Sound System mode.\n");
- return FALSE;
+ if (ae_config.mss_base != -1) {
+ if (ae_config.init & INIT_MSS) {
+ if (aedsp16_init_mss(ae_config.base_io) == FALSE) {
+ printk("[AEDSP16] Can not initialize"
+ "Microsoft Sound System mode.\n");
+ return FALSE;
+ }
}
}
-#endif
#if !defined(MODULE) || defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
@@ -1098,27 +1110,26 @@ static int aedsp16_init_board(void)
VERSION, DSPCopyright,
DSPVersion);
-#if defined(CONFIG_AEDSP16_MPU401)
- if (ae_config.init & INIT_MPU401) {
- printk("MPU401");
- if ((ae_config.init & INIT_MSS) ||
- (ae_config.init & INIT_SBPRO))
- printk(" ");
+ if (ae_config.mpu_base != -1) {
+ if (ae_config.init & INIT_MPU401) {
+ printk("MPU401");
+ if ((ae_config.init & INIT_MSS) ||
+ (ae_config.init & INIT_SBPRO))
+ printk(" ");
+ }
}
-#endif
-#if defined(CONFIG_AEDSP16_SBPRO)
- if (ae_config.init & INIT_SBPRO) {
- printk("SBPro");
- if (ae_config.init & INIT_MSS)
- printk(" ");
+ if (ae_config.mss_base == -1) {
+ if (ae_config.init & INIT_SBPRO) {
+ printk("SBPro");
+ if (ae_config.init & INIT_MSS)
+ printk(" ");
+ }
}
-#endif
-#if defined(CONFIG_AEDSP16_MSS)
- if (ae_config.init & INIT_MSS)
- printk("MSS");
-#endif
+ if (ae_config.mss_base != -1)
+ if (ae_config.init & INIT_MSS)
+ printk("MSS");
printk("]\n");
#endif /* MODULE || AEDSP16_INFO || AEDSP16_DEBUG */
@@ -1128,8 +1139,6 @@ static int aedsp16_init_board(void)
return TRUE;
}
-#if defined(CONFIG_AEDSP16_SBPRO)
-
static int init_aedsp16_sb(void)
{
DBG(("init_aedsp16_sb: "));
@@ -1158,9 +1167,6 @@ static void uninit_aedsp16_sb(void)
DBG(("done.\n"));
}
-#endif
-
-#if defined(CONFIG_AEDSP16_MSS)
static int init_aedsp16_mss(void)
{
@@ -1175,8 +1181,8 @@ static int init_aedsp16_mss(void)
if (ae_config.init & INIT_MSS)
return FALSE;
/*
- * We must check the AEDSP16_BASE region too because these are the I/O ports
- * to access card's control registers.
+ * We must check the CONFIG_AEDSP16_BASE region too because these are the I/O
+ * ports to access card's control registers.
*/
if (!(ae_config.init & INIT_MPU401)) {
if (check_region(ae_config.base_io, IOBASE_REGION_SIZE)) {
@@ -1187,8 +1193,8 @@ static int init_aedsp16_mss(void)
}
/*
- * We must allocate the AEDSP16_BASE region too because these are the I/O ports
- * to access card's control registers.
+ * We must allocate the CONFIG_AEDSP16_BASE region too because these are the
+ * I/O ports to access card's control registers.
*/
if (!(ae_config.init & INIT_MPU401))
request_region(ae_config.base_io, IOBASE_REGION_SIZE,
@@ -1214,9 +1220,6 @@ static void uninit_aedsp16_mss(void)
ae_config.init &= ~INIT_MSS;
DBG(("done.\n"));
}
-#endif
-
-#if defined(CONFIG_AEDSP16_MPU401)
static int init_aedsp16_mpu(void)
{
@@ -1226,8 +1229,8 @@ static int init_aedsp16_mpu(void)
return FALSE;
/*
- * We must check the AEDSP16_BASE region too because these are the I/O ports
- * to access card's control registers.
+ * We must check the CONFIG_AEDSP16_BASE region too because these are the I/O
+ * ports to access card's control registers.
*/
if (!(ae_config.init & (INIT_MSS | INIT_SBPRO))) {
if (check_region(ae_config.base_io, IOBASE_REGION_SIZE)) {
@@ -1262,43 +1265,45 @@ static void uninit_aedsp16_mpu(void)
DBG(("done.\n"));
}
-#endif
int init_aedsp16(void)
{
int initialized = FALSE;
- ae_config.base_io = AEDSP16_BASE;
+#if !defined(MODULE)
+ ae_config.base_io = CONFIG_AEDSP16_BASE;
#if defined(CONFIG_AEDSP16_SBPRO)
- ae_config.irq = AEDSP16_SBC_IRQ;
- ae_config.dma = AEDSP16_SBC_DMA;
+ ae_config.irq = CONFIG_AEDSP16_SB_IRQ;
+ ae_config.dma = CONFIG_AEDSP16_SB_DMA;
#endif
#if defined(CONFIG_AEDSP16_MSS)
- ae_config.irq = AEDSP16_MSS_IRQ;
- ae_config.dma = AEDSP16_MSS_DMA;
+ ae_config.mss_base = CONFIG_MSS_BASE;
+ ae_config.irq = CONFIG_AEDSP16_MSS_IRQ;
+ ae_config.dma = CONFIG_AEDSP16_MSS_DMA;
#endif
#if defined(CONFIG_AEDSP16_MPU401)
- ae_config.mpu_irq = AEDSP16_MPU_IRQ;
+ ae_config.mpu_base = CONFIG_MPU_BASE;
+ ae_config.mpu_irq = CONFIG_AEDSP16_MPU_IRQ;
#endif
-
+#endif /* !MODULE */
DBG(("Initializing BASE[0x%x] IRQ[%d] DMA[%d] MIRQ[%d]\n",
ae_config.base_io,ae_config.irq,ae_config.dma,ae_config.mpu_irq));
-#if defined(CONFIG_AEDSP16_SBPRO)
- if (init_aedsp16_sb() == FALSE)
- uninit_aedsp16_sb();
- else
- initialized = TRUE;
-#endif
-
-#if defined(CONFIG_AEDSP16_MPU401)
- if (init_aedsp16_mpu() == FALSE)
- uninit_aedsp16_mpu();
- else
- initialized = TRUE;
-#endif
+ if (ae_config.mss_base == -1) {
+ if (init_aedsp16_sb() == FALSE) {
+ uninit_aedsp16_sb();
+ } else {
+ initialized = TRUE;
+ }
+ }
-#if defined(CONFIG_AEDSP16_MSS)
+ if (ae_config.mpu_base != -1) {
+ if (init_aedsp16_mpu() == FALSE) {
+ uninit_aedsp16_mpu();
+ } else {
+ initialized = TRUE;
+ }
+ }
/*
* In the sequence of init routines, the MSS init MUST be the last!
@@ -1306,11 +1311,13 @@ int init_aedsp16(void)
* A board reset would disable the MSS mode restoring the default SBPRO
* mode.
*/
- if (init_aedsp16_mss() == FALSE)
- uninit_aedsp16_mss();
- else
- initialized = TRUE;
-#endif
+ if (ae_config.mss_base != -1) {
+ if (init_aedsp16_mss() == FALSE) {
+ uninit_aedsp16_mss();
+ } else {
+ initialized = TRUE;
+ }
+ }
if (initialized)
initialized = aedsp16_init_board();
@@ -1319,16 +1326,62 @@ int init_aedsp16(void)
void uninit_aedsp16(void)
{
-#if defined(CONFIG_AEDSP16_MSS)
- uninit_aedsp16_mss();
-#endif
+ if (ae_config.mss_base != -1)
+ uninit_aedsp16_mss();
+ else
+ uninit_aedsp16_sb();
+ if (ae_config.mpu_base != -1)
+ uninit_aedsp16_mpu();
+}
-#if defined(CONFIG_AEDSP16_SBPRO)
- uninit_aedsp16_sb();
-#endif
+#if defined(MODULE)
-#if defined(CONFIG_AEDSP16_MPU401)
- uninit_aedsp16_mpu();
-#endif
+int io = -1;
+int irq = -1;
+int dma = -1;
+int mpu_irq = -1;
+int mss_base = -1;
+int mpu_base = -1;
+
+
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
+MODULE_PARM(dma,"i");
+MODULE_PARM(mpu_irq,"i");
+MODULE_PARM(mss_base,"i");
+MODULE_PARM(mpu_base,"i");
+
+int init_module(void) {
+ printk("Audio Excel DSP 16 init driver Copyright (C) Riccardo Facchetti 1995-98\n");
+ if (io == -1 || dma == -1 || irq == -1) {
+ printk(KERN_INFO "aedsp16: I/O, IRQ and DMA are mandatory\n");
+ return -EINVAL;
+ }
+
+ ae_config.base_io = io;
+ ae_config.irq = irq;
+ ae_config.dma = dma;
+
+ ae_config.mss_base = mss_base;
+ ae_config.mpu_base = mpu_base;
+ ae_config.mpu_irq = mpu_irq;
+
+ if (init_aedsp16() == FALSE) {
+ printk(KERN_ERR "aedsp16: initialization failed\n");
+ /*
+ * XXX
+ * What error should we return here ?
+ */
+ return -EINVAL;
+ }
+ SOUND_LOCK;
+ return 0;
}
-#endif /* CONFIG_AEDSP16 */
+
+void cleanup_module(void) {
+ uninit_aedsp16();
+ SOUND_LOCK_END;
+}
+#endif /* MODULE */
+
+#endif /* CONFIG_AEDSP16 */
diff --git a/drivers/sound/lowlevel/awe_version.h b/drivers/sound/lowlevel/awe_version.h
index a579b09ef..c1de31715 100644
--- a/drivers/sound/lowlevel/awe_version.h
+++ b/drivers/sound/lowlevel/awe_version.h
@@ -10,15 +10,4 @@
#define AWE_TINY_VERSION(id) ((id) & 0xff)
#endif
-/* AWE32 driver version number */
-#ifndef AWE_VERSION_H_DEF
-#define AWE_VERSION_H_DEF
-
-#define AWE_VERSION_NUMBER 0x00040202
-#define AWEDRV_VERSION "0.4.2b"
-#define AWE_MAJOR_VERSION(id) (((id) >> 16) & 0xff)
-#define AWE_MINOR_VERSION(id) (((id) >> 8) & 0xff)
-#define AWE_TINY_VERSION(id) ((id) & 0xff)
-
-#endif
diff --git a/drivers/sound/lowlevel/init.c b/drivers/sound/lowlevel/init.c
index 4b96bf032..d2e9242e4 100644
--- a/drivers/sound/lowlevel/init.c
+++ b/drivers/sound/lowlevel/init.c
@@ -28,7 +28,7 @@ extern void uninit_aedsp16(void);
void
sound_preinit_lowlevel_drivers(void)
{
-#ifdef CONFIG_AEDSP16
+#if defined(CONFIG_AEDSP16) && !defined(MODULE)
init_aedsp16();
#endif
}
diff --git a/drivers/sound/mad16.c b/drivers/sound/mad16.c
index bffc6ef17..4870ec799 100644
--- a/drivers/sound/mad16.c
+++ b/drivers/sound/mad16.c
@@ -112,6 +112,7 @@ static int already_initialized = 0;
static int board_type = C928;
static int *mad16_osp;
+static int c931_detected; /* minor diferences from C930 */
#ifndef DDB
#define DDB(x)
@@ -225,6 +226,44 @@ detect_c930(void)
DDB(printk("MC7 not writable2 (%x)\n", tmp));
return 0;
}
+
+ tmp = mad_read(MC0_PORT+18);
+ if (tmp == 0xff)
+ return 1;
+ /* We probably have a C931 */
+ DDB(printk("Detected C931 config=0x%02x\n", tmp));
+ c931_detected = 1;
+
+ /*
+ * We cannot configure the chip if it is in PnP mode.
+ * If we have a CSN assigned (bit 8 in MC13) we first try
+ * a software reset, then a software power off, finally
+ * Clearing PnP mode. The last option is not
+ * Bit 8 in MC13
+ */
+ if ((mad_read(MC0_PORT+13) & 0x80) == 0)
+ return 1;
+
+ /* Software reset */
+ mad_write(MC9_PORT, 0x02);
+ mad_write(MC9_PORT, 0x00);
+
+ if ((mad_read(MC0_PORT+13) & 0x80) == 0)
+ return 1;
+
+ /* Power off, and on again */
+ mad_write(MC9_PORT, 0xc2);
+ mad_write(MC9_PORT, 0xc0);
+
+ if ((mad_read(MC0_PORT+13) & 0x80) == 0)
+ return 1;
+
+ /* Force off PnP mode, This is not recommended because
+ * 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;
}
@@ -329,10 +368,20 @@ wss_init(struct address_info *hw_config)
static int
init_c930(struct address_info *hw_config)
{
- unsigned char cfg;
+ unsigned char cfg = 0;
+
+#ifdef MAD16_CONF
+ cfg |= (0x0f & MAD16_CONF);
+#endif
- cfg = (mad_read(MC1_PORT) & ~0x30);
- /* mad_write(MC1_PORT, 0); */
+ if(c931_detected)
+ {
+ /* Bit 0 has reversd meaning. Bits 1 and 2 sese
+ reversed on write.
+ Support only IDE cdrom. IDE port programmed
+ somewhere else. */
+ cfg = (cfg & 0x09) ^ 0x07;
+ }
switch (hw_config->io_base)
{
@@ -358,7 +407,14 @@ init_c930(struct address_info *hw_config)
/* MC2 is CD configuration. Don't touch it. */
mad_write(MC3_PORT, 0); /* Disable SB mode IRQ and DMA */
- mad_write(MC4_PORT, 0x52); /* ??? */
+#ifdef MAD16_CDSEL
+ if(MAD16_CDSEL & 0x20)
+ mad_write(MC4_PORT, 0x66); /* opl4 */
+ else
+ mad_write(MC4_PORT, 0x56); /* opl3 */
+#else
+ mad_write(MC4_PORT, 0x56);
+#endif
mad_write(MC5_PORT, 0x3C); /* Init it into mode2 */
mad_write(MC6_PORT, 0x02); /* Enable WSS, Disable MPU and SB */
mad_write(MC7_PORT, 0xCB);
diff --git a/drivers/sound/maui.c b/drivers/sound/maui.c
index 83d489d52..5cd620dbf 100644
--- a/drivers/sound/maui.c
+++ b/drivers/sound/maui.c
@@ -41,210 +41,185 @@ static int *maui_osp;
static int (*orig_load_patch) (int dev, int format, const char *addr,
int offs, int count, int pmgr_flag) = NULL;
-#ifdef HAVE_MAUI_BOOT
+#ifdef CONFIG_MAUI_HAVE_BOOT
#include "maui_boot.h"
#else
static unsigned char *maui_os = NULL;
-static int maui_osLen = 0;
-
+static int maui_osLen = 0;
#endif
-static struct wait_queue *maui_sleeper = NULL;
-static volatile struct snd_wait maui_sleep_flag =
-{0};
-
-static int
-maui_wait(int mask)
+static int maui_wait(int mask)
{
- int i;
+ int i;
-/*
- * Perform a short initial wait without sleeping
- */
+ /*
+ * Perform a short initial wait without sleeping
+ */
for (i = 0; i < 100; i++)
- {
- if (inb(HOST_STAT_PORT) & mask)
- {
- return 1;
- }
- }
+ {
+ if (inb(HOST_STAT_PORT) & mask)
+ {
+ return 1;
+ }
+ }
-/*
- * Wait up to 15 seconds with sleeping
- */
+ /*
+ * Wait up to 15 seconds with sleeping
+ */
for (i = 0; i < 150; i++)
- {
- if (inb(HOST_STAT_PORT) & mask)
- {
- return 1;
- }
- {
- unsigned long tlimit;
-
- if (HZ / 10)
- current->timeout = tlimit = jiffies + (HZ / 10);
- else
- tlimit = (unsigned long) -1;
- maui_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&maui_sleeper);
- if (!(maui_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- maui_sleep_flag.opts |= WK_TIMEOUT;
- }
- maui_sleep_flag.opts &= ~WK_SLEEP;
- };
- if (signal_pending(current))
- {
- return 0;
- }
- }
-
+ {
+ if (inb(HOST_STAT_PORT) & mask)
+ return 1;
+ current->timeout = jiffies + HZ / 10;
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ current->timeout = 0;
+ if (signal_pending(current))
+ return 0;
+ }
return 0;
}
-static int
-maui_read(void)
+static int maui_read(void)
{
if (maui_wait(STAT_RX_AVAIL))
return inb(HOST_DATA_PORT);
-
return -1;
}
-static int
-maui_write(unsigned char data)
+static int maui_write(unsigned char data)
{
if (maui_wait(STAT_TX_AVAIL))
- {
- outb((data), HOST_DATA_PORT);
- return 1;
- }
- printk("Maui: Write timeout\n");
-
+ {
+ outb((data), HOST_DATA_PORT);
+ return 1;
+ }
+ printk(KERN_WARNING "Maui: Write timeout\n");
return 0;
}
-static void
-mauiintr(int irq, void *dev_id, struct pt_regs *dummy)
+static void mauiintr(int irq, void *dev_id, struct pt_regs *dummy)
{
irq_ok = 1;
}
-static int
-download_code(void)
+static int download_code(void)
{
- int i, lines = 0;
- int eol_seen = 0, done = 0;
- int skip = 1;
+ int i, lines = 0;
+ int eol_seen = 0, done = 0;
+ int skip = 1;
- printk("Code download (%d bytes): ", maui_osLen);
+ printk(KERN_INFO "Code download (%d bytes): ", maui_osLen);
for (i = 0; i < maui_osLen; i++)
- {
- if (maui_os[i] != '\r')
- if (!skip || (maui_os[i] == 'S' && (i == 0 || maui_os[i - 1] == '\n')))
- {
- skip = 0;
-
- if (maui_os[i] == '\n')
- eol_seen = skip = 1;
- else if (maui_os[i] == 'S')
- {
- if (maui_os[i + 1] == '8')
- done = 1;
- if (!maui_write(0xF1))
- goto failure;
- if (!maui_write('S'))
- goto failure;
- } else
- {
- if (!maui_write(maui_os[i]))
- goto failure;
- }
-
- if (eol_seen)
- {
- int c = 0;
-
- int n;
-
- eol_seen = 0;
-
- for (n = 0; n < 2; n++)
- if (maui_wait(STAT_RX_AVAIL))
- {
- c = inb(HOST_DATA_PORT);
- break;
- }
- if (c != 0x80)
- {
- printk("Download not acknowledged\n");
- return 0;
- } else if (!(lines++ % 10))
- printk(".");
-
- if (done)
+ {
+ if (maui_os[i] != '\r')
+ {
+ if (!skip || (maui_os[i] == 'S' && (i == 0 || maui_os[i - 1] == '\n')))
+ {
+ skip = 0;
+
+ if (maui_os[i] == '\n')
+ eol_seen = skip = 1;
+ else if (maui_os[i] == 'S')
+ {
+ if (maui_os[i + 1] == '8')
+ done = 1;
+ if (!maui_write(0xF1))
+ goto failure;
+ if (!maui_write('S'))
+ goto failure;
+ }
+ else
+ {
+ if (!maui_write(maui_os[i]))
+ goto failure;
+ }
+
+ if (eol_seen)
+ {
+ int c = 0;
+ int n;
+
+ eol_seen = 0;
+
+ for (n = 0; n < 2; n++)
+ {
+ if (maui_wait(STAT_RX_AVAIL))
{
- printk("\nDownload complete\n");
- return 1;
+ c = inb(HOST_DATA_PORT);
+ break;
}
- }
- }
- }
-
- failure:
-
- printk("\nDownload failed!!!\n");
+ }
+ if (c != 0x80)
+ {
+ printk("Download not acknowledged\n");
+ return 0;
+ }
+ else if (!(lines++ % 10))
+ printk(".");
+
+ if (done)
+ {
+ printk("\n");
+ printk(KERN_INFO "Download complete\n");
+ return 1;
+ }
+ }
+ }
+ }
+ }
+
+failure:
+ printk("\n");
+ printk(KERN_ERR "Download failed!!!\n");
return 0;
}
-static int
-maui_init(int irq)
+static int maui_init(int irq)
{
- int i;
- unsigned char bits;
+#ifdef __SMP__
+ int i;
+#endif
+ unsigned char bits;
switch (irq)
- {
- case 9:
- bits = 0x00;
- break;
- case 5:
- bits = 0x08;
- break;
- case 12:
- bits = 0x10;
- break;
- case 15:
- bits = 0x18;
- break;
-
- default:
- printk("Maui: Invalid IRQ %d\n", irq);
- return 0;
- }
+ {
+ case 9:
+ bits = 0x00;
+ break;
+ case 5:
+ bits = 0x08;
+ break;
+ case 12:
+ bits = 0x10;
+ break;
+ case 15:
+ bits = 0x18;
+ break;
+ default:
+ printk(KERN_ERR "Maui: Invalid IRQ %d\n", irq);
+ return 0;
+ }
outb((0x00), HOST_CTRL_PORT); /* Reset */
-
outb((bits), HOST_DATA_PORT); /* Set the IRQ bits */
outb((bits | 0x80), HOST_DATA_PORT); /* Set the IRQ bits again? */
-
outb((0x80), HOST_CTRL_PORT); /* Leave reset */
outb((0x80), HOST_CTRL_PORT); /* Leave reset */
-
outb((0xD0), HOST_CTRL_PORT); /* Cause interrupt */
+#ifdef __SMP__
for (i = 0; i < 1000000 && !irq_ok; i++);
if (!irq_ok)
return 0;
-
+#endif
outb((0x80), HOST_CTRL_PORT); /* Leave reset */
- printk("Turtle Beach Maui initialization\n");
+ printk(KERN_INFO "Turtle Beach Maui initialization\n");
if (!download_code())
return 0;
@@ -256,54 +231,51 @@ maui_init(int irq)
maui_write(0xf0);
maui_write(1);
if (maui_read() != 0x80)
- {
- maui_write(0xf0);
- maui_write(1);
- if (maui_read() != 0x80)
- printk("Maui didn't acknowledge set HW mode command\n");
- }
- printk("Maui initialized OK\n");
+ {
+ maui_write(0xf0);
+ maui_write(1);
+ if (maui_read() != 0x80)
+ printk(KERN_ERR "Maui didn't acknowledge set HW mode command\n");
+ }
+ printk(KERN_INFO "Maui initialized OK\n");
return 1;
}
-static int
-maui_short_wait(int mask)
+static int maui_short_wait(int mask)
{
- int i;
+ int i;
for (i = 0; i < 1000; i++)
- {
- if (inb(HOST_STAT_PORT) & mask)
- {
- return 1;
- }
- }
-
+ {
+ if (inb(HOST_STAT_PORT) & mask)
+ {
+ return 1;
+ }
+ }
return 0;
}
-static int
-maui_load_patch(int dev, int format, const char *addr,
+static int maui_load_patch(int dev, int format, const char *addr,
int offs, int count, int pmgr_flag)
{
struct sysex_info header;
- unsigned long left, src_offs;
- int hdr_size = (unsigned long) &header.data[0] - (unsigned long) &header;
- int i;
+ unsigned long left, src_offs;
+ int hdr_size = (unsigned long) &header.data[0] - (unsigned long) &header;
+ int i;
if (format == SYSEX_PATCH) /* Handled by midi_synth.c */
return orig_load_patch(dev, format, addr, offs, count, pmgr_flag);
if (format != MAUI_PATCH)
- {
- printk("Maui: Unknown patch format\n");
- }
+ {
+ printk(KERN_WARNING "Maui: Unknown patch format\n");
+ }
if (count < hdr_size)
- {
- printk("Maui error: Patch header too short\n");
+ {
+/* printk("Maui error: Patch header too short\n");*/
return -EINVAL;
- }
+ }
count -= hdr_size;
/*
@@ -311,43 +283,43 @@ maui_load_patch(int dev, int format, const char *addr,
* been transferred already.
*/
- copy_from_user(&((char *) &header)[offs], &(addr)[offs], hdr_size - offs);
+ if(copy_from_user(&((char *) &header)[offs], &(addr)[offs], hdr_size - offs))
+ return -EFAULT;
if (count < header.len)
- {
- printk("Maui warning: Host command record too short (%d<%d)\n", count, (int) header.len);
+ {
+ printk(KERN_ERR "Maui warning: Host command record too short (%d<%d)\n", count, (int) header.len);
header.len = count;
- }
+ }
left = header.len;
src_offs = 0;
for (i = 0; i < left; i++)
- {
- unsigned char data;
+ {
+ unsigned char data;
- get_user(*(unsigned char *) &data, (unsigned char *) &((addr)[hdr_size + i]));
- if (i == 0 && !(data & 0x80))
- return -EINVAL;
+ if(get_user(*(unsigned char *) &data, (unsigned char *) &((addr)[hdr_size + i])))
+ return -EFAULT;
+ if (i == 0 && !(data & 0x80))
+ return -EINVAL;
- if (maui_write(data) == -1)
- return -EIO;
- }
+ if (maui_write(data) == -1)
+ return -EIO;
+ }
if ((i = maui_read()) != 0x80)
- {
- if (i != -1)
- printk("Maui: Error status %02x\n", i);
-
- return -EIO;
- }
+ {
+ if (i != -1)
+ printk("Maui: Error status %02x\n", i);
+ return -EIO;
+ }
return 0;
}
-int
-probe_maui(struct address_info *hw_config)
+int probe_maui(struct address_info *hw_config)
{
- int i;
- int tmp1, tmp2, ret;
+ int i;
+ int tmp1, tmp2, ret;
if (check_region(hw_config->io_base, 8))
return 0;
@@ -358,42 +330,41 @@ probe_maui(struct address_info *hw_config)
if (snd_set_irq_handler(hw_config->irq, mauiintr, "Maui", maui_osp) < 0)
return 0;
- maui_sleep_flag.opts = WK_NONE;
-/*
- * Initialize the processor if necessary
- */
+ /*
+ * Initialize the processor if necessary
+ */
if (maui_osLen > 0)
- {
- if (!(inb(HOST_STAT_PORT) & STAT_TX_AVAIL) ||
- !maui_write(0x9F) || /* Report firmware version */
- !maui_short_wait(STAT_RX_AVAIL) ||
- maui_read() == -1 || maui_read() == -1)
- if (!maui_init(hw_config->irq))
- {
- snd_release_irq(hw_config->irq);
- return 0;
- }
- }
+ {
+ if (!(inb(HOST_STAT_PORT) & STAT_TX_AVAIL) ||
+ !maui_write(0x9F) || /* Report firmware version */
+ !maui_short_wait(STAT_RX_AVAIL) ||
+ maui_read() == -1 || maui_read() == -1)
+ if (!maui_init(hw_config->irq))
+ {
+ snd_release_irq(hw_config->irq);
+ return 0;
+ }
+ }
if (!maui_write(0xCF)) /* Report hardware version */
- {
- printk("No WaveFront firmware detected (card uninitialized?)\n");
- snd_release_irq(hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
+ snd_release_irq(hw_config->irq);
+ return 0;
+ }
if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
- {
- printk("No WaveFront firmware detected (card uninitialized?)\n");
- snd_release_irq(hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
+ snd_release_irq(hw_config->irq);
+ return 0;
+ }
if (tmp1 == 0xff || tmp2 == 0xff)
- {
+ {
snd_release_irq(hw_config->irq);
return 0;
- }
+ }
if (trace_init)
- printk("WaveFront hardware version %d.%d\n", tmp1, tmp2);
+ printk(KERN_DEBUG "WaveFront hardware version %d.%d\n", tmp1, tmp2);
if (!maui_write(0x9F)) /* Report firmware version */
return 0;
@@ -401,17 +372,17 @@ probe_maui(struct address_info *hw_config)
return 0;
if (trace_init)
- printk("WaveFront firmware version %d.%d\n", tmp1, tmp2);
+ printk(KERN_DEBUG "WaveFront firmware version %d.%d\n", tmp1, tmp2);
if (!maui_write(0x85)) /* Report free DRAM */
return 0;
tmp1 = 0;
for (i = 0; i < 4; i++)
- {
- tmp1 |= maui_read() << (7 * i);
- }
+ {
+ tmp1 |= maui_read() << (7 * i);
+ }
if (trace_init)
- printk("Available DRAM %dk\n", tmp1 / 1024);
+ printk(KERN_DEBUG "Available DRAM %dk\n", tmp1 / 1024);
for (i = 0; i < 1000; i++)
if (probe_mpu401(hw_config))
@@ -425,10 +396,9 @@ probe_maui(struct address_info *hw_config)
return ret;
}
-void
-attach_maui(struct address_info *hw_config)
+void attach_maui(struct address_info *hw_config)
{
- int this_dev;
+ int this_dev;
conf_printf("Maui", hw_config);
@@ -437,75 +407,71 @@ attach_maui(struct address_info *hw_config)
attach_mpu401(hw_config);
if (hw_config->slots[1] != -1) /* The MPU401 driver installed itself */
- {
- struct synth_operations *synth;
-
- this_dev = hw_config->slots[1];
-
- /*
- * Intercept patch loading calls so that they can be handled
- * by the Maui driver.
- */
-
- synth = midi_devs[this_dev]->converter;
- synth->id = "MAUI";
-
- if (synth != NULL)
- {
- orig_load_patch = synth->load_patch;
- synth->load_patch = &maui_load_patch;
- } else
- printk(KERN_ERR "Maui: Can't install patch loader\n");
- }
+ {
+ struct synth_operations *synth;
+
+ this_dev = hw_config->slots[1];
+
+ /*
+ * Intercept patch loading calls so that they can be handled
+ * by the Maui driver.
+ */
+
+ synth = midi_devs[this_dev]->converter;
+ synth->id = "MAUI";
+
+ if (synth != NULL)
+ {
+ orig_load_patch = synth->load_patch;
+ synth->load_patch = &maui_load_patch;
+ }
+ else
+ printk(KERN_ERR "Maui: Can't install patch loader\n");
+ }
}
-void
-unload_maui(struct address_info *hw_config)
+void unload_maui(struct address_info *hw_config)
{
- int irq = hw_config->irq;
-
+ int irq = hw_config->irq;
release_region(hw_config->io_base + 2, 6);
-
unload_mpu401(hw_config);
if (irq < 0)
irq = -irq;
-
if (irq > 0)
snd_release_irq(irq);
}
#ifdef MODULE
-int io = -1;
-int irq = -1;
+int io = -1;
+int irq = -1;
-static int fw_load = 0;
+static int fw_load = 0;
struct address_info cfg;
/*
- * Install a CS4232 based card. Need to have ad1848 and mpu401
- * loaded ready.
+ * Install a CS4232 based card. Need to have ad1848 and mpu401
+ * loaded ready.
*/
-int
-init_module(void)
+int init_module(void)
{
- printk("Turtle beach Maui and Tropez driver, Copyright (C) by Hannu Savolainen 1993-1996\n");
+ printk(KERN_INFO "Turtle beach Maui and Tropez driver, Copyright (C) by Hannu Savolainen 1993-1996\n");
if (io == -1 || irq == -1)
- {
- printk("maui: irq and io must be set.\n");
- return -EINVAL;
- }
+ {
+ printk(KERN_INFO "maui: irq and io must be set.\n");
+ return -EINVAL;
+ }
cfg.io_base = io;
cfg.irq = irq;
if (maui_os == NULL)
- {
- fw_load = 1;
- maui_osLen = mod_firmware_load("/etc/sound/oswf.mot", (char **) &maui_os);
- }
+ {
+ fw_load = 1;
+ maui_osLen = mod_firmware_load("/etc/sound/oswf.mot", (char **) &maui_os);
+ }
if (probe_maui(&cfg) == 0)
return -ENODEV;
attach_maui(&cfg);
@@ -513,8 +479,7 @@ init_module(void)
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
if (fw_load && maui_os)
kfree(maui_os);
diff --git a/drivers/sound/midi_synth.c b/drivers/sound/midi_synth.c
index b123473cc..4fb23261b 100644
--- a/drivers/sound/midi_synth.c
+++ b/drivers/sound/midi_synth.c
@@ -10,6 +10,9 @@
* 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>
#define USE_SEQ_MACROS
@@ -21,10 +24,6 @@
#define _MIDI_SYNTH_C_
-static struct wait_queue *sysex_sleeper = NULL;
-static volatile struct snd_wait sysex_sleep_flag =
-{0};
-
#include "midi_synth.h"
static int midi2synth[MAX_MIDI_DEV];
@@ -258,30 +257,25 @@ midi_synth_output(int dev)
*/
}
-int
-midi_synth_ioctl(int dev,
- unsigned int cmd, caddr_t arg)
+int midi_synth_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
/*
* int orig_dev = synth_devs[dev]->midi_dev;
*/
- switch (cmd)
- {
+ switch (cmd) {
- case SNDCTL_SYNTH_INFO:
- memcpy((&((char *) arg)[0]), (char *) synth_devs[dev]->info, sizeof(struct synth_info));
-
- return 0;
- break;
-
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
- break;
+ case SNDCTL_SYNTH_INFO:
+ if (__copy_to_user(arg, synth_devs[dev]->info, sizeof(struct synth_info)))
+ return -EFAULT;
+ return 0;
+
+ case SNDCTL_SYNTH_MEMAVL:
+ return 0x7fffffff;
- default:
- return -EINVAL;
- }
+ default:
+ return -EINVAL;
+ }
}
int
@@ -452,8 +446,6 @@ midi_synth_open(int dev, int mode)
inc->m_prev_status = 0x00;
restore_flags(flags);
- sysex_sleep_flag.opts = WK_NONE;
-
return 1;
}
@@ -525,8 +517,6 @@ midi_synth_load_patch(int dev, int format, const char *addr,
left = sysex.len;
src_offs = 0;
- sysex_sleep_flag.opts = WK_NONE;
-
for (i = 0; i < left && !signal_pending(current); i++)
{
unsigned char data;
@@ -548,23 +538,7 @@ midi_synth_load_patch(int dev, int format, const char *addr,
}
while (!midi_devs[orig_dev]->outputc(orig_dev, (unsigned char) (data & 0xff)) &&
!signal_pending(current))
-
- {
- unsigned long tlimit;
-
- if (1)
- current->timeout = tlimit = jiffies + (1);
- else
- tlimit = (unsigned long) -1;
- sysex_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&sysex_sleeper);
- if (!(sysex_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- sysex_sleep_flag.opts |= WK_TIMEOUT;
- }
- sysex_sleep_flag.opts &= ~WK_SLEEP;
- }; /* Wait for timeout */
+ schedule();
if (!first_byte && data & 0x80)
return 0;
diff --git a/drivers/sound/midibuf.c b/drivers/sound/midibuf.c
index fb6534191..0c024a454 100644
--- a/drivers/sound/midibuf.c
+++ b/drivers/sound/midibuf.c
@@ -10,7 +10,12 @@
* 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/stddef.h>
+#include <linux/kerneld.h>
#define MIDIBUF_C
@@ -24,41 +29,33 @@
#define MAX_QUEUE_SIZE 4000
-static struct wait_queue *midi_sleeper[MAX_MIDI_DEV] =
-{NULL};
-static volatile struct snd_wait midi_sleep_flag[MAX_MIDI_DEV] =
-{
- {0}};
-static struct wait_queue *input_sleeper[MAX_MIDI_DEV] =
-{NULL};
-static volatile struct snd_wait input_sleep_flag[MAX_MIDI_DEV] =
-{
- {0}};
+static struct wait_queue *midi_sleeper[MAX_MIDI_DEV] = {NULL};
+static struct wait_queue *input_sleeper[MAX_MIDI_DEV] = {NULL};
struct midi_buf
- {
- int len, head, tail;
- unsigned char queue[MAX_QUEUE_SIZE];
- };
+{
+ int len, head, tail;
+ unsigned char queue[MAX_QUEUE_SIZE];
+};
struct midi_parms
- {
- int prech_timeout; /*
- * Timeout before the first ch
- */
- };
+{
+ int prech_timeout; /*
+ * Timeout before the first ch
+ */
+};
-static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] =
-{NULL};
-static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] =
-{NULL};
+static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] = {NULL};
+static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] = {NULL};
static struct midi_parms parms[MAX_MIDI_DEV];
-static void midi_poll(unsigned long dummy);
+static void midi_poll(unsigned long dummy);
+
+static struct timer_list poll_timer = {
+ NULL, NULL, 0, 0, midi_poll
+};
-static struct timer_list poll_timer =
-{NULL, NULL, 0, 0, midi_poll};
static volatile int open_devs = 0;
#define DATA_AVAIL(q) (q->len)
@@ -84,8 +81,7 @@ static volatile int open_devs = 0;
restore_flags(flags); \
}
-static void
-drain_midi_queue(int dev)
+static void drain_midi_queue(int dev)
{
/*
@@ -93,29 +89,15 @@ drain_midi_queue(int dev)
*/
if (midi_devs[dev]->buffer_status != NULL)
- while (!signal_pending(current) &&
- midi_devs[dev]->buffer_status(dev))
-
- {
- unsigned long tlimit;
-
- if (HZ / 10)
- current->timeout = tlimit = jiffies + (HZ / 10);
- else
- tlimit = (unsigned long) -1;
- midi_sleep_flag[dev].opts = WK_SLEEP;
- interruptible_sleep_on(&midi_sleeper[dev]);
- if (!(midi_sleep_flag[dev].opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- midi_sleep_flag[dev].opts |= WK_TIMEOUT;
- }
- midi_sleep_flag[dev].opts &= ~WK_SLEEP;
- };
+ while (!signal_pending(current) && midi_devs[dev]->buffer_status(dev))
+ {
+ current->timeout = jiffies + HZ / 10;
+ interruptible_sleep_on(&midi_sleeper[dev]);
+ current->timeout = 0;
+ }
}
-static void
-midi_input_intr(int dev, unsigned char data)
+static void midi_input_intr(int dev, unsigned char data)
{
if (midi_in_buf[dev] == NULL)
return;
@@ -127,27 +109,20 @@ midi_input_intr(int dev, unsigned char data)
* Ignore
*/
- if (SPACE_AVAIL(midi_in_buf[dev]))
- {
- QUEUE_BYTE(midi_in_buf[dev], data);
- if ((input_sleep_flag[dev].opts & WK_SLEEP))
- {
- input_sleep_flag[dev].opts = WK_WAKEUP;
- wake_up(&input_sleeper[dev]);
- };
- }
+ if (SPACE_AVAIL(midi_in_buf[dev])) {
+ QUEUE_BYTE(midi_in_buf[dev], data);
+ wake_up(&input_sleeper[dev]);
+ }
}
-static void
-midi_output_intr(int dev)
+static void midi_output_intr(int dev)
{
/*
* Currently NOP
*/
}
-static void
-midi_poll(unsigned long dummy)
+static void midi_poll(unsigned long dummy)
{
unsigned long flags;
int dev;
@@ -155,116 +130,99 @@ midi_poll(unsigned long dummy)
save_flags(flags);
cli();
if (open_devs)
- {
- for (dev = 0; dev < num_midis; dev++)
- if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
- {
- int ok = 1;
-
- while (DATA_AVAIL(midi_out_buf[dev]) && ok)
- {
- int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
-
- restore_flags(flags); /* Give some time to others */
- ok = midi_devs[dev]->outputc(dev, c);
- save_flags(flags);
- cli();
- midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
- midi_out_buf[dev]->len--;
- }
-
- if (DATA_AVAIL(midi_out_buf[dev]) < 100 &&
- (midi_sleep_flag[dev].opts & WK_SLEEP))
- {
- midi_sleep_flag[dev].opts = WK_WAKEUP;
- wake_up(&midi_sleeper[dev]);
- };
- }
- {
- poll_timer.expires = (1) + jiffies;
- add_timer(&poll_timer);
- }; /*
- * Come back later
- */
- }
+ {
+ for (dev = 0; dev < num_midis; dev++)
+ if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
+ {
+ int ok = 1;
+
+ while (DATA_AVAIL(midi_out_buf[dev]) && ok)
+ {
+ int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
+
+ restore_flags(flags); /* Give some time to others */
+ ok = midi_devs[dev]->outputc(dev, c);
+ cli();
+ midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
+ midi_out_buf[dev]->len--;
+ }
+
+ if (DATA_AVAIL(midi_out_buf[dev]) < 100)
+ wake_up(&midi_sleeper[dev]);
+ }
+ poll_timer.expires = (1) + jiffies;
+ add_timer(&poll_timer);
+ /*
+ * Come back later
+ */
+ }
restore_flags(flags);
}
-int
-MIDIbuf_open(int dev, struct fileinfo *file)
+int MIDIbuf_open(int dev, struct file *file)
{
- int mode, err;
+ int mode, err;
dev = dev >> 4;
- mode = file->mode & O_ACCMODE;
+ mode = translate_mode(file);
if (num_midis > MAX_MIDI_DEV)
- {
- printk("Sound: FATAL ERROR: Too many midi interfaces\n");
- num_midis = MAX_MIDI_DEV;
- }
+ {
+ printk(KERN_ERR "midi: Too many midi interfaces\n");
+ num_midis = MAX_MIDI_DEV;
+ }
if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
- {
- printk("Sound: Nonexistent MIDI interface %d\n", dev);
return -ENXIO;
- }
/*
- * Interrupts disabled. Be careful
+ * Interrupts disabled. Be careful
*/
if ((err = midi_devs[dev]->open(dev, mode,
midi_input_intr, midi_output_intr)) < 0)
- {
- return err;
- }
- parms[dev].prech_timeout = 0;
+ return err;
+ parms[dev].prech_timeout = 0;
midi_in_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf));
if (midi_in_buf[dev] == NULL)
- {
- printk("midi: Can't allocate buffer\n");
- midi_devs[dev]->close(dev);
- return -EIO;
- }
+ {
+ printk(KERN_WARNING "midi: Can't allocate buffer\n");
+ midi_devs[dev]->close(dev);
+ return -EIO;
+ }
midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
midi_out_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf));
if (midi_out_buf[dev] == NULL)
- {
- printk("midi: Can't allocate buffer\n");
- midi_devs[dev]->close(dev);
- vfree(midi_in_buf[dev]);
- midi_in_buf[dev] = NULL;
- return -EIO;
- }
+ {
+ printk(KERN_WARNING "midi: Can't allocate buffer\n");
+ midi_devs[dev]->close(dev);
+ vfree(midi_in_buf[dev]);
+ midi_in_buf[dev] = NULL;
+ return -EIO;
+ }
midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
open_devs++;
- midi_sleep_flag[dev].opts = WK_NONE;
- input_sleep_flag[dev].opts = WK_NONE;
+ init_waitqueue(&midi_sleeper[dev]);
+ init_waitqueue(&input_sleeper[dev]);
if (open_devs < 2) /* This was first open */
- {
- ;
-
- {
- poll_timer.expires = (1) + jiffies;
- add_timer(&poll_timer);
- }; /* Start polling */
- }
+ {
+ poll_timer.expires = 1 + jiffies;
+ add_timer(&poll_timer); /* Start polling */
+ }
return err;
}
-void
-MIDIbuf_release(int dev, struct fileinfo *file)
+void MIDIbuf_release(int dev, struct file *file)
{
- int mode;
- unsigned long flags;
+ int mode;
+ unsigned long flags;
dev = dev >> 4;
- mode = file->mode & O_ACCMODE;
+ mode = translate_mode(file);
if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
return;
@@ -273,42 +231,26 @@ MIDIbuf_release(int dev, struct fileinfo *file)
cli();
/*
- * Wait until the queue is empty
+ * Wait until the queue is empty
*/
if (mode != OPEN_READ)
- {
- midi_devs[dev]->outputc(dev, 0xfe); /*
+ {
+ midi_devs[dev]->outputc(dev, 0xfe); /*
* Active sensing to shut the
* devices
*/
- while (!signal_pending(current) &&
- DATA_AVAIL(midi_out_buf[dev]))
-
- {
- unsigned long tlimit;
-
- if (0)
- current->timeout = tlimit = jiffies + (0);
- else
- tlimit = (unsigned long) -1;
- midi_sleep_flag[dev].opts = WK_SLEEP;
- interruptible_sleep_on(&midi_sleeper[dev]);
- if (!(midi_sleep_flag[dev].opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- midi_sleep_flag[dev].opts |= WK_TIMEOUT;
- }
- midi_sleep_flag[dev].opts &= ~WK_SLEEP;
- }; /*
- * Sync
- */
+ while (!signal_pending(current) && DATA_AVAIL(midi_out_buf[dev]))
+ interruptible_sleep_on(&midi_sleeper[dev]);
+ /*
+ * Sync
+ */
- drain_midi_queue(dev); /*
- * Ensure the output queues are empty
- */
- }
+ drain_midi_queue(dev); /*
+ * Ensure the output queues are empty
+ */
+ }
restore_flags(flags);
midi_devs[dev]->close(dev);
@@ -322,12 +264,11 @@ MIDIbuf_release(int dev, struct fileinfo *file)
open_devs--;
}
-int
-MIDIbuf_write(int dev, struct fileinfo *file, const char *buf, int count)
+int MIDIbuf_write(int dev, struct file *file, const char *buf, int count)
{
- unsigned long flags;
- int c, n, i;
- unsigned char tmp_data;
+ unsigned long flags;
+ int c, n, i;
+ unsigned char tmp_data;
dev = dev >> 4;
@@ -340,192 +281,144 @@ MIDIbuf_write(int dev, struct fileinfo *file, const char *buf, int count)
c = 0;
while (c < count)
- {
- n = SPACE_AVAIL(midi_out_buf[dev]);
+ {
+ n = SPACE_AVAIL(midi_out_buf[dev]);
- if (n == 0) /*
+ if (n == 0) { /*
* No space just now. We have to sleep
*/
- {
-
- {
- unsigned long tlimit;
-
- if (0)
- current->timeout = tlimit = jiffies + (0);
- else
- tlimit = (unsigned long) -1;
- midi_sleep_flag[dev].opts = WK_SLEEP;
- interruptible_sleep_on(&midi_sleeper[dev]);
- if (!(midi_sleep_flag[dev].opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- midi_sleep_flag[dev].opts |= WK_TIMEOUT;
- }
- midi_sleep_flag[dev].opts &= ~WK_SLEEP;
- };
- if (signal_pending(current))
- {
- restore_flags(flags);
- return -EINTR;
- }
- n = SPACE_AVAIL(midi_out_buf[dev]);
- }
- if (n > (count - c))
- n = count - c;
-
- for (i = 0; i < n; i++)
- {
- copy_from_user((char *) &tmp_data, &(buf)[c], 1);
- QUEUE_BYTE(midi_out_buf[dev], tmp_data);
- c++;
- }
- }
-
+ interruptible_sleep_on(&midi_sleeper[dev]);
+ if (signal_pending(current))
+ {
+ restore_flags(flags);
+ return -EINTR;
+ }
+ n = SPACE_AVAIL(midi_out_buf[dev]);
+ }
+ if (n > (count - c))
+ n = count - c;
+
+ for (i = 0; i < n; i++)
+ {
+ /* BROKE BROKE BROKE - CANT DO THIS WITH CLI !! */
+ copy_from_user((char *) &tmp_data, &(buf)[c], 1);
+ QUEUE_BYTE(midi_out_buf[dev], tmp_data);
+ c++;
+ }
+ }
restore_flags(flags);
-
return c;
}
-int
-MIDIbuf_read(int dev, struct fileinfo *file, char *buf, int count)
+int MIDIbuf_read(int dev, struct file *file, char *buf, int count)
{
- int n, c = 0;
- unsigned long flags;
- unsigned char tmp_data;
+ int n, c = 0;
+ unsigned long flags;
+ unsigned char tmp_data;
dev = dev >> 4;
save_flags(flags);
cli();
- if (!DATA_AVAIL(midi_in_buf[dev])) /*
+ if (!DATA_AVAIL(midi_in_buf[dev])) { /*
* No data yet, wait
*/
- {
-
- {
- unsigned long tlimit;
-
- if (parms[dev].prech_timeout)
- current->timeout = tlimit = jiffies + (parms[dev].prech_timeout);
- else
- tlimit = (unsigned long) -1;
- input_sleep_flag[dev].opts = WK_SLEEP;
- interruptible_sleep_on(&input_sleeper[dev]);
- if (!(input_sleep_flag[dev].opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- input_sleep_flag[dev].opts |= WK_TIMEOUT;
- }
- input_sleep_flag[dev].opts &= ~WK_SLEEP;
- };
- if (signal_pending(current))
- c = -EINTR; /*
- * The user is getting restless
- */
- }
+ current->timeout = parms[dev].prech_timeout ? jiffies + parms[dev].prech_timeout : 0;
+ interruptible_sleep_on(&input_sleeper[dev]);
+ current->timeout = 0;
+ if (signal_pending(current))
+ c = -EINTR; /* The user is getting restless */
+ }
if (c == 0 && DATA_AVAIL(midi_in_buf[dev])) /*
* Got some bytes
*/
- {
- n = DATA_AVAIL(midi_in_buf[dev]);
- if (n > count)
- n = count;
- c = 0;
-
- while (c < n)
- {
- REMOVE_BYTE(midi_in_buf[dev], tmp_data);
- {
- char *fixit = (char *) &tmp_data;
-
- copy_to_user(&(buf)[c], fixit, 1);
- };
- c++;
- }
- }
+ {
+ n = DATA_AVAIL(midi_in_buf[dev]);
+ if (n > count)
+ n = count;
+ c = 0;
+
+ while (c < n)
+ {
+ char *fixit;
+ REMOVE_BYTE(midi_in_buf[dev], tmp_data);
+ fixit = (char *) &tmp_data;
+ /* BROKE BROKE BROKE */
+ copy_to_user(&(buf)[c], fixit, 1);
+ c++;
+ }
+ }
restore_flags(flags);
-
return c;
}
-int
-MIDIbuf_ioctl(int dev, struct fileinfo *file,
- unsigned int cmd, caddr_t arg)
+int MIDIbuf_ioctl(int dev, struct file *file,
+ unsigned int cmd, caddr_t arg)
{
- int val;
+ int val;
dev = dev >> 4;
-
- if (((cmd >> 8) & 0xff) == 'C')
- {
- if (midi_devs[dev]->coproc) /* Coprocessor ioctl */
- return midi_devs[dev]->coproc->ioctl(midi_devs[dev]->coproc->devc, cmd, arg, 0);
- else
- printk("/dev/midi%d: No coprocessor for this device\n", dev);
-
- return -ENXIO;
- } else
- switch (cmd)
- {
-
- case SNDCTL_MIDI_PRETIME:
- val = *(int *) arg;
- if (val < 0)
- val = 0;
-
- val = (HZ * val) / 10;
- parms[dev].prech_timeout = val;
- return (*(int *) arg = val);
- break;
-
- default:
- return midi_devs[dev]->ioctl(dev, cmd, arg);
- }
+
+ if (((cmd >> 8) & 0xff) == 'C')
+ {
+ if (midi_devs[dev]->coproc) /* Coprocessor ioctl */
+ return midi_devs[dev]->coproc->ioctl(midi_devs[dev]->coproc->devc, cmd, arg, 0);
+/* printk("/dev/midi%d: No coprocessor for this device\n", dev);*/
+ return -ENXIO;
+ }
+ else
+ {
+ switch (cmd)
+ {
+ case SNDCTL_MIDI_PRETIME:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val < 0)
+ val = 0;
+ val = (HZ * val) / 10;
+ parms[dev].prech_timeout = val;
+ return put_user(val, (int *)arg);
+
+ default:
+ if (!midi_devs[dev]->ioctl)
+ return -EINVAL;
+ return midi_devs[dev]->ioctl(dev, cmd, arg);
+ }
+ }
}
-int
-MIDIbuf_select(int dev, struct fileinfo *file, int sel_type, poll_table * wait)
+unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait)
{
- dev = dev >> 4;
+ unsigned int mask = 0;
- switch (sel_type)
- {
- case SEL_IN:
- if (!DATA_AVAIL(midi_in_buf[dev]))
- {
-
- input_sleep_flag[dev].opts = WK_SLEEP;
- poll_wait(&input_sleeper[dev], wait);
- return 0;
- }
- return 1;
- break;
-
- case SEL_OUT:
- if (SPACE_AVAIL(midi_out_buf[dev]))
- {
-
- midi_sleep_flag[dev].opts = WK_SLEEP;
- poll_wait(&midi_sleeper[dev], wait);
- return 0;
- }
- return 1;
- break;
-
- case SEL_EX:
- return 0;
- }
+ dev = dev >> 4;
- return 0;
+ /* input */
+ poll_wait(file, &input_sleeper[dev], wait);
+ if (DATA_AVAIL(midi_in_buf[dev]))
+ mask |= POLLIN | POLLRDNORM;
+
+ /* output */
+ poll_wait(file, &midi_sleeper[dev], wait);
+ if (!SPACE_AVAIL(midi_out_buf[dev]))
+ mask |= POLLOUT | POLLWRNORM;
+
+ return mask;
}
-void
-MIDIbuf_init(void)
+void MIDIbuf_init(void)
+{
+}
+
+int MIDIbuf_avail(int dev)
{
+ if (midi_in_buf[dev])
+ return DATA_AVAIL (midi_in_buf[dev]);
+ return 0;
}
+
#endif
diff --git a/drivers/sound/mpu401.c b/drivers/sound/mpu401.c
index cf00dc9e4..9ae597404 100644
--- a/drivers/sound/mpu401.c
+++ b/drivers/sound/mpu401.c
@@ -10,6 +10,9 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+/*
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ */
#include <linux/config.h>
#include <linux/module.h>
@@ -746,45 +749,36 @@ mpu401_end_read(int dev)
return 0;
}
-static int
-mpu401_ioctl(int dev, unsigned cmd, caddr_t arg)
+static int mpu401_ioctl(int dev, unsigned cmd, caddr_t arg)
{
struct mpu_config *devc;
- int val;
+ mpu_command_rec rec;
+ int val, ret;
devc = &dev_conf[dev];
+ switch (cmd) {
+ case SNDCTL_MIDI_MPUMODE:
+ if (!(devc->capabilities & MPU_CAP_INTLG)) { /* No intelligent mode */
+ printk("MPU-401: Intelligent mode not supported by the HW\n");
+ return -EINVAL;
+ }
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ set_uart_mode(dev, devc, !val);
+ return 0;
- switch (cmd)
- {
- case SNDCTL_MIDI_MPUMODE:
- if (!(devc->capabilities & MPU_CAP_INTLG)) /* No intelligent mode */
- {
- printk("MPU-401: Intelligent mode not supported by the HW\n");
- return -EINVAL;
- }
- val = *(int *) arg;
- set_uart_mode(dev, devc, !val);
- return 0;
- break;
-
- case SNDCTL_MIDI_MPUCMD:
- {
- int ret;
- mpu_command_rec rec;
-
- memcpy((char *) &rec, (&((char *) arg)[0]), sizeof(rec));
-
- if ((ret = mpu401_command(dev, &rec)) < 0)
- return ret;
-
- memcpy((&((char *) arg)[0]), (char *) &rec, sizeof(rec));
- return 0;
- }
- break;
+ case SNDCTL_MIDI_MPUCMD:
+ if (__copy_from_user(&rec, arg, sizeof(rec)))
+ return -EFAULT;
+ if ((ret = mpu401_command(dev, &rec)) < 0)
+ return ret;
+ if (__copy_to_user(arg, &rec, sizeof(rec)))
+ return -EFAULT;
+ return 0;
- default:
- return -EINVAL;
- }
+ default:
+ return -EINVAL;
+ }
}
static void
diff --git a/drivers/sound/opl3.c b/drivers/sound/opl3.c
index beb146710..36734c2e7 100644
--- a/drivers/sound/opl3.c
+++ b/drivers/sound/opl3.c
@@ -10,8 +10,12 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+/*
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ */
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/delay.h>
/*
* Major improvements to the FM handling 30AUG92 by Rob Hooft,
@@ -102,40 +106,35 @@ static void enter_4op_mode(void)
static int opl3_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- switch (cmd)
- {
-
- case SNDCTL_FM_LOAD_INSTR:
- {
- struct sbi_instrument ins;
-
- printk(KERN_WARNING "Warning: Obsolete ioctl(SNDCTL_FM_LOAD_INSTR) used. Fix the program.\n");
- memcpy((char *) &ins, (&((char *) arg)[0]), sizeof(ins));
-
- if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR)
- {
- printk("FM Error: Invalid instrument number %d\n", ins.channel);
- return -EINVAL;
- }
- return store_instr(ins.channel, &ins);
+ struct sbi_instrument ins;
+
+ switch (cmd) {
+ case SNDCTL_FM_LOAD_INSTR:
+ printk(KERN_WARNING "Warning: Obsolete ioctl(SNDCTL_FM_LOAD_INSTR) used. Fix the program.\n");
+ if (__copy_from_user(&ins, arg, sizeof(ins)))
+ return -EFAULT;
+ if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) {
+ printk("FM Error: Invalid instrument number %d\n", ins.channel);
+ return -EINVAL;
}
+ return store_instr(ins.channel, &ins);
- case SNDCTL_SYNTH_INFO:
- devc->fm_info.nr_voices =
- (devc->nr_voice == 12) ? 6 : devc->nr_voice;
- memcpy((&((char *) arg)[0]), (char *) &devc->fm_info, sizeof(devc->fm_info));
- return 0;
+ case SNDCTL_SYNTH_INFO:
+ devc->fm_info.nr_voices = (devc->nr_voice == 12) ? 6 : devc->nr_voice;
+ if (__copy_to_user(arg, &devc->fm_info, sizeof(devc->fm_info)))
+ return -EFAULT;
+ return 0;
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
+ case SNDCTL_SYNTH_MEMAVL:
+ return 0x7fffffff;
- case SNDCTL_FM_4OP_ENABLE:
- if (devc->model == 2)
- enter_4op_mode();
- return 0;
+ case SNDCTL_FM_4OP_ENABLE:
+ if (devc->model == 2)
+ enter_4op_mode();
+ return 0;
- default:
- return -EINVAL;
+ default:
+ return -EINVAL;
}
}
@@ -219,17 +218,17 @@ int opl3_detect(int ioaddr, int *osp)
int tmp;
outb((0x02), ioaddr - 8); /* Select OPL4 ID register */
- tenmicrosec(devc->osp);
+ udelay(10);
tmp = inb(ioaddr - 7); /* Read it */
- tenmicrosec(devc->osp);
+ udelay(10);
if (tmp == 0x20) /* OPL4 should return 0x20 here */
{
detected_model = 4;
outb((0xF8), ioaddr - 8); /* Select OPL4 FM mixer control */
- tenmicrosec(devc->osp);
+ udelay(10);
outb((0x1B), ioaddr - 7); /* Write value */
- tenmicrosec(devc->osp);
+ udelay(10);
}
else
detected_model = 3;
@@ -711,7 +710,7 @@ static void opl3_command (int io_addr, unsigned int addr, unsigned int val)
outb(((unsigned char) (addr & 0xff)), io_addr);
if (devc->model != 2)
- tenmicrosec(devc->osp);
+ udelay(10);
else
for (i = 0; i < 2; i++)
inb(io_addr);
@@ -719,11 +718,7 @@ static void opl3_command (int io_addr, unsigned int addr, unsigned int val)
outb(((unsigned char) (val & 0xff)), io_addr + 1);
if (devc->model != 2)
- {
- tenmicrosec(devc->osp);
- tenmicrosec(devc->osp);
- tenmicrosec(devc->osp);
- }
+ udelay(30);
else
for (i = 0; i < 2; i++)
inb(io_addr);
@@ -1204,7 +1199,6 @@ void cleanup_module(void)
{
if (devc)
{
- vfree(devc);
devc = NULL;
sound_unload_synthdev(me);
}
diff --git a/drivers/sound/os.h b/drivers/sound/os.h
index 1acffb768..5bd4a27eb 100644
--- a/drivers/sound/os.h
+++ b/drivers/sound/os.h
@@ -41,15 +41,13 @@
#define FALSE 0
#define TRUE 1
-struct snd_wait {
- volatile int opts;
- };
-
extern int sound_alloc_dma(int chn, char *deviceID);
extern int sound_open_dma(int chn, char *deviceID);
extern void sound_free_dma(int chn);
extern void sound_close_dma(int chn);
+extern void reprogram_timer(void);
+
#define RUNTIME_DMA_ALLOC
#define USE_AUTOINIT_DMA
diff --git a/drivers/sound/pas2_card.c b/drivers/sound/pas2_card.c
index 7e3c23f59..656034d54 100644
--- a/drivers/sound/pas2_card.c
+++ b/drivers/sound/pas2_card.c
@@ -11,14 +11,22 @@
#if defined(CONFIG_PAS) || defined(MODULE)
-static unsigned char dma_bits[] =
-{4, 1, 2, 3, 0, 5, 6, 7};
-static unsigned char irq_bits[] =
-{0, 0, 1, 2, 3, 4, 5, 6, 0, 1, 7, 8, 9, 0, 10, 11};
-static unsigned char sb_irq_bits[] =
-{0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x08, 0x28, 0x30, 0x38, 0, 0};
-static unsigned char sb_dma_bits[] =
-{0x00, 0x40, 0x80, 0xC0, 0, 0, 0, 0};
+static unsigned char dma_bits[] = {
+ 4, 1, 2, 3, 0, 5, 6, 7
+};
+
+static unsigned char irq_bits[] = {
+ 0, 0, 1, 2, 3, 4, 5, 6, 0, 1, 7, 8, 9, 0, 10, 11
+};
+
+static unsigned char sb_irq_bits[] = {
+ 0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20,
+ 0x00, 0x08, 0x28, 0x30, 0x38, 0, 0
+};
+
+static unsigned char sb_dma_bits[] = {
+ 0x00, 0x40, 0x80, 0xC0, 0, 0, 0, 0
+};
/*
* The Address Translation code is used to convert I/O register addresses to
@@ -32,32 +40,35 @@ static int pas_sb_base = 0;
char pas_model = 0;
-static char *pas_model_names[] =
-{"", "Pro AudioSpectrum+", "CDPC", "Pro AudioSpectrum 16", "Pro AudioSpectrum 16D"};
+static char *pas_model_names[] = {
+ "",
+ "Pro AudioSpectrum+",
+ "CDPC",
+ "Pro AudioSpectrum 16",
+ "Pro AudioSpectrum 16D"
+};
/*
* pas_read() and pas_write() are equivalents of inb and outb
* These routines perform the I/O address translation required
* to support other than the default base address
*/
+
extern void mix_write(unsigned char data, int ioaddr);
-unsigned char
-pas_read(int ioaddr)
+unsigned char pas_read(int ioaddr)
{
return inb(ioaddr ^ translate_code);
}
-void
-pas_write(unsigned char data, int ioaddr)
+void pas_write(unsigned char data, int ioaddr)
{
outb((data), ioaddr ^ translate_code);
}
/******************* Begin of the Interrupt Handler ********************/
-static void
-pasintr(int irq, void *dev_id, struct pt_regs *dummy)
+static void pasintr(int irq, void *dev_id, struct pt_regs *dummy)
{
int status;
@@ -65,23 +76,22 @@ pasintr(int irq, void *dev_id, struct pt_regs *dummy)
pas_write(status, 0x0B89); /* Clear interrupt */
if (status & 0x08)
- {
+ {
#ifdef CONFIG_AUDIO
pas_pcm_interrupt(status, 1);
#endif
status &= ~0x08;
- }
+ }
if (status & 0x10)
- {
+ {
#if defined(CONFIG_MIDI)
pas_midi_interrupt();
#endif
status &= ~0x10;
- }
+ }
}
-int
-pas_set_intr(int mask)
+int pas_set_intr(int mask)
{
if (!mask)
return 0;
@@ -92,8 +102,7 @@ pas_set_intr(int mask)
return 0;
}
-int
-pas_remove_intr(int mask)
+int pas_remove_intr(int mask)
{
if (!mask)
return 0;
@@ -110,8 +119,7 @@ pas_remove_intr(int mask)
extern struct address_info sbhw_config;
-static int
-config_pas_hw(struct address_info *hw_config)
+static int config_pas_hw(struct address_info *hw_config)
{
char ok = 1;
unsigned int_ptrs; /* scsi/sound interrupt pointers */
@@ -129,8 +137,8 @@ config_pas_hw(struct address_info *hw_config)
pas_write(0x80 | 0x40 | 0x20 | 1, 0x0B8A);
pas_write(0x80 | 0x20 | 0x10 | 0x08 | 0x01, 0xF8A);
pas_write(0x01 | 0x02 | 0x04 | 0x10 /*
- * |
- * 0x80
+ * |
+ * 0x80
*/ , 0xB88);
pas_write(0x80
@@ -140,49 +148,53 @@ config_pas_hw(struct address_info *hw_config)
,0xF388);
if (pas_irq < 0 || pas_irq > 15)
- {
- printk("PAS16: Invalid IRQ %d", pas_irq);
- ok = 0;
- } else
- {
- int_ptrs = pas_read(0xF38A);
- int_ptrs |= irq_bits[pas_irq] & 0xf;
- pas_write(int_ptrs, 0xF38A);
- if (!irq_bits[pas_irq])
- {
- printk("PAS16: Invalid IRQ %d", pas_irq);
- ok = 0;
- } else
- {
- if (snd_set_irq_handler(pas_irq, pasintr, "PAS16", hw_config->osp) < 0)
- ok = 0;
- }
- }
+ {
+ printk(KERN_ERR "PAS16: Invalid IRQ %d", pas_irq);
+ ok = 0;
+ }
+ else
+ {
+ int_ptrs = pas_read(0xF38A);
+ int_ptrs |= irq_bits[pas_irq] & 0xf;
+ pas_write(int_ptrs, 0xF38A);
+ if (!irq_bits[pas_irq])
+ {
+ printk(KERN_ERR "PAS16: Invalid IRQ %d", pas_irq);
+ ok = 0;
+ }
+ else
+ {
+ if (snd_set_irq_handler(pas_irq, pasintr, "PAS16", hw_config->osp) < 0)
+ ok = 0;
+ }
+ }
if (hw_config->dma < 0 || hw_config->dma > 7)
- {
- printk("PAS16: Invalid DMA selection %d", hw_config->dma);
- ok = 0;
- } else
- {
- pas_write(dma_bits[hw_config->dma], 0xF389);
- if (!dma_bits[hw_config->dma])
- {
- printk("PAS16: Invalid DMA selection %d", hw_config->dma);
- ok = 0;
- } else
- {
- if (sound_alloc_dma(hw_config->dma, "PAS16"))
- {
- printk("pas2_card.c: Can't allocate DMA channel\n");
- ok = 0;
- }
- }
- }
+ {
+ printk(KERN_ERR "PAS16: Invalid DMA selection %d", hw_config->dma);
+ ok = 0;
+ }
+ else
+ {
+ pas_write(dma_bits[hw_config->dma], 0xF389);
+ if (!dma_bits[hw_config->dma])
+ {
+ printk(KERN_ERR "PAS16: Invalid DMA selection %d", hw_config->dma);
+ ok = 0;
+ }
+ else
+ {
+ if (sound_alloc_dma(hw_config->dma, "PAS16"))
+ {
+ printk(KERN_ERR "pas2_card.c: Can't allocate DMA channel\n");
+ ok = 0;
+ }
+ }
+ }
/*
- * This fixes the timing problems of the PAS due to the Symphony chipset
- * as per Media Vision. Only define this if your PAS doesn't work correctly.
+ * This fixes the timing problems of the PAS due to the Symphony chipset
+ * as per Media Vision. Only define this if your PAS doesn't work correctly.
*/
#ifdef SYMPHONY_PAS
outb((0x05), 0xa8);
@@ -215,33 +227,36 @@ config_pas_hw(struct address_info *hw_config)
sb_config = &sbhw_config;
if (sb_config->io_base)
#endif
- {
- unsigned char irq_dma;
-
- /*
- * Turn on Sound Blaster compatibility
- * bit 1 = SB emulation
- * bit 0 = MPU401 emulation (CDPC only :-( )
- */
- pas_write(0x02, 0xF788);
-
- /*
- * "Emulation address"
- */
- pas_write((sb_config->io_base >> 4) & 0x0f, 0xF789);
- pas_sb_base = sb_config->io_base;
-
- if (!sb_dma_bits[sb_config->dma])
- printk("\n\nPAS16 Warning: Invalid SB DMA %d\n\n", sb_config->dma);
-
- if (!sb_irq_bits[sb_config->irq])
- printk("\n\nPAS16 Warning: Invalid SB IRQ %d\n\n", sb_config->irq);
-
- irq_dma = sb_dma_bits[sb_config->dma] |
- sb_irq_bits[sb_config->irq];
-
- pas_write(irq_dma, 0xFB8A);
- } else
+ {
+ unsigned char irq_dma;
+
+ /*
+ * Turn on Sound Blaster compatibility
+ * bit 1 = SB emulation
+ * bit 0 = MPU401 emulation (CDPC only :-( )
+ */
+
+ pas_write(0x02, 0xF788);
+
+ /*
+ * "Emulation address"
+ */
+
+ pas_write((sb_config->io_base >> 4) & 0x0f, 0xF789);
+ pas_sb_base = sb_config->io_base;
+
+ if (!sb_dma_bits[sb_config->dma])
+ printk(KERN_ERR "PAS16 Warning: Invalid SB DMA %d\n\n", sb_config->dma);
+
+ if (!sb_irq_bits[sb_config->irq])
+ printk(KERN_ERR "PAS16 Warning: Invalid SB IRQ %d\n\n", sb_config->irq);
+
+ irq_dma = sb_dma_bits[sb_config->dma] |
+ sb_irq_bits[sb_config->irq];
+
+ pas_write(irq_dma, 0xFB8A);
+ }
+ else
pas_write(0x00, 0xF788);
}
#else
@@ -249,13 +264,12 @@ config_pas_hw(struct address_info *hw_config)
#endif
if (!ok)
- printk("PAS16: Driver not enabled\n");
+ printk(KERN_WARNING "PAS16: Driver not enabled\n");
return ok;
}
-static int
-detect_pas_hw(struct address_info *hw_config)
+static int detect_pas_hw(struct address_info *hw_config)
{
unsigned char board_id, foo;
@@ -296,40 +310,39 @@ detect_pas_hw(struct address_info *hw_config)
return pas_model;
}
-void
-attach_pas_card(struct address_info *hw_config)
+void attach_pas_card(struct address_info *hw_config)
{
pas_irq = hw_config->irq;
if (detect_pas_hw(hw_config))
- {
+ {
- if ((pas_model = pas_read(0xFF88)))
- {
- char temp[100];
+ if ((pas_model = pas_read(0xFF88)))
+ {
+ char temp[100];
- sprintf(temp,
+ sprintf(temp,
"%s rev %d", pas_model_names[(int) pas_model],
pas_read(0x2789));
- conf_printf(temp, hw_config);
- }
- if (config_pas_hw(hw_config))
- {
+ conf_printf(temp, hw_config);
+ }
+ if (config_pas_hw(hw_config))
+ {
#ifdef CONFIG_AUDIO
- pas_pcm_init(hw_config);
+ pas_pcm_init(hw_config);
#endif
#if !defined(DISABLE_SB_EMULATION) && (defined(CONFIG_SB) || defined(CONFIG_SB_MODULE))
- sb_dsp_disable_midi(pas_sb_base); /* No MIDI capability */
+ sb_dsp_disable_midi(pas_sb_base); /* No MIDI capability */
#endif
#if defined(CONFIG_MIDI)
- pas_midi_init();
+ pas_midi_init();
#endif
- pas_init_mixer();
- }
- }
+ pas_init_mixer();
+ }
+ }
}
int
@@ -357,18 +370,28 @@ int sb_irq = -1;
int sb_dma = -1;
int sb_dma16 = -1;
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
+MODULE_PARM(dma,"i");
+MODULE_PARM(dma16,"i");
+
+MODULE_PARM(sb_io,"i");
+MODULE_PARM(sb_irq,"i");
+MODULE_PARM(sb_dma,"i");
+MODULE_PARM(sb_dma16,"i");
+
struct address_info config;
struct address_info sbhw_config;
int init_module(void)
{
- printk("MediaTrix audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+ printk(KERN_INFO "MediaTrix audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
if (io == -1 || dma == -1 || irq == -1)
- {
- printk("I/O, IRQ, DMA and type are mandatory\n");
+ {
+ printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
return -EINVAL;
- }
+ }
config.io_base = io;
config.irq = irq;
config.dma = dma;
@@ -386,8 +409,7 @@ int init_module(void)
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
unload_pas(&config);
SOUND_LOCK_END;
diff --git a/drivers/sound/pas2_midi.c b/drivers/sound/pas2_midi.c
index 45b60fefd..72120b83b 100644
--- a/drivers/sound/pas2_midi.c
+++ b/drivers/sound/pas2_midi.c
@@ -185,12 +185,6 @@ pas_midi_end_read(int dev)
return 0;
}
-static int
-pas_midi_ioctl(int dev, unsigned cmd, caddr_t arg)
-{
- return -EINVAL;
-}
-
static void
pas_midi_kick(int dev)
{
@@ -213,7 +207,7 @@ static struct midi_operations pas_midi_operations =
{0},
pas_midi_open,
pas_midi_close,
- pas_midi_ioctl,
+ NULL,
pas_midi_out,
pas_midi_start_read,
pas_midi_end_read,
diff --git a/drivers/sound/pas2_mixer.c b/drivers/sound/pas2_mixer.c
index 335e7dd39..7c0687b77 100644
--- a/drivers/sound/pas2_mixer.c
+++ b/drivers/sound/pas2_mixer.c
@@ -12,6 +12,9 @@
* 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 "sound_config.h"
@@ -211,122 +214,97 @@ pas_mixer_reset(void)
set_mode(0x04 | 0x01);
}
-static int
-pas_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+static int pas_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- DEB(printk("pas2_mixer.c: int pas_mixer_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
-
- if (cmd == SOUND_MIXER_PRIVATE1) /* Set loudness bit */
- {
- int level;
-
- level = *(int *) arg;
-
- if (level == -1) /* Return current settings */
- {
- if (mode_control & 0x04)
- return (*(int *) arg = 1);
- else
- return (*(int *) arg = 0);
- } else
- {
- mode_control &= ~0x04;
- if (level)
- mode_control |= 0x04;
- set_mode(mode_control);
- return (*(int *) arg = !!level); /* 0 or 1 */
- }
- }
- if (cmd == SOUND_MIXER_PRIVATE2) /* Set enhance bit */
- {
- int level;
+ int level,v ;
- level = *(int *) arg;
-
- if (level == -1) /* Return current settings */
- {
- if (!(mode_control & 0x03))
- return (*(int *) arg = 0);
- return (*(int *) arg = ((mode_control & 0x03) + 1) * 20);
- } else
- {
- int i = 0;
-
- level &= 0x7f;
- if (level)
- i = (level / 20) - 1;
-
- mode_control &= ~0x03;
- mode_control |= i & 0x03;
- set_mode(mode_control);
-
- if (i)
- i = (i + 1) * 20;
-
- return i;
- }
- }
- if (cmd == SOUND_MIXER_PRIVATE3) /* Set mute bit */
- {
- int level;
-
- level = *(int *) arg;
-
- if (level == -1) /* Return current settings */
- {
- return (*(int *) arg = !(pas_read(0x0B8A) & 0x20));
- } else
- {
- if (level)
- pas_write(pas_read(0x0B8A) & (~0x20),
- 0x0B8A);
- else
- pas_write(pas_read(0x0B8A) | 0x20,
- 0x0B8A);
-
- return !(pas_read(0x0B8A) & 0x20);
- }
- }
- if (((cmd >> 8) & 0xff) == 'M')
- {
- int v;
-
- v = *(int *) arg;
-
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- return (*(int *) arg = pas_mixer_set(cmd & 0xff, v));
- else
- {
-
- switch (cmd & 0xff)
- {
-
- case SOUND_MIXER_RECSRC:
- return (*(int *) arg = rec_devices);
- break;
-
- case SOUND_MIXER_STEREODEVS:
- return (*(int *) arg = SUPPORTED_MIXER_DEVICES & ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE));
- break;
-
- case SOUND_MIXER_DEVMASK:
- return (*(int *) arg = SUPPORTED_MIXER_DEVICES);
- break;
-
- case SOUND_MIXER_RECMASK:
- return (*(int *) arg = POSSIBLE_RECORDING_DEVICES & SUPPORTED_MIXER_DEVICES);
- break;
-
- case SOUND_MIXER_CAPS:
- return (*(int *) arg = 0); /* No special capabilities */
- break;
-
-
- default:
- return (*(int *) arg = levels[cmd & 0xff]);
- }
- }
- }
+ DEB(printk("pas2_mixer.c: int pas_mixer_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
+ if (cmd == SOUND_MIXER_PRIVATE1) { /* Set loudness bit */
+ if (get_user(level, (int *)arg))
+ return -EFAULT;
+ if (level == -1) /* Return current settings */
+ level = (mode_control & 0x04);
+ else {
+ mode_control &= ~0x04;
+ if (level)
+ mode_control |= 0x04;
+ set_mode(mode_control);
+ }
+ level = !!level;
+ return put_user(level, (int *)arg);
+ }
+ if (cmd == SOUND_MIXER_PRIVATE2) { /* Set enhance bit */
+ if (get_user(level, (int *)arg))
+ return -EFAULT;
+ if (level == -1) { /* Return current settings */
+ if (!(mode_control & 0x03))
+ level = 0;
+ else
+ level = ((mode_control & 0x03) + 1) * 20;
+ } else {
+ int i = 0;
+
+ level &= 0x7f;
+ if (level)
+ i = (level / 20) - 1;
+ mode_control &= ~0x03;
+ mode_control |= i & 0x03;
+ set_mode(mode_control);
+ if (i)
+ i = (i + 1) * 20;
+ level = i;
+ }
+ return put_user(level, (int *)arg);
+ }
+ if (cmd == SOUND_MIXER_PRIVATE3) { /* Set mute bit */
+ if (get_user(level, (int *)arg))
+ return -EFAULT;
+ if (level == -1) /* Return current settings */
+ level = !(pas_read(0x0B8A) & 0x20);
+ else {
+ if (level)
+ pas_write(pas_read(0x0B8A) & (~0x20), 0x0B8A);
+ else
+ pas_write(pas_read(0x0B8A) | 0x20, 0x0B8A);
+
+ level = !(pas_read(0x0B8A) & 0x20);
+ }
+ return put_user(level, (int *)arg);
+ }
+ if (((cmd >> 8) & 0xff) == 'M') {
+ if (get_user(v, (int *)arg))
+ return -EFAULT;
+ if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
+ v = pas_mixer_set(cmd & 0xff, v);
+ } else {
+ switch (cmd & 0xff) {
+ case SOUND_MIXER_RECSRC:
+ v = rec_devices;
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ v = SUPPORTED_MIXER_DEVICES & ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE);
+ break;
+
+ case SOUND_MIXER_DEVMASK:
+ v = SUPPORTED_MIXER_DEVICES;
+ break;
+
+ case SOUND_MIXER_RECMASK:
+ v = POSSIBLE_RECORDING_DEVICES & SUPPORTED_MIXER_DEVICES;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ v = 0; /* No special capabilities */
+ break;
+
+ default:
+ v = levels[cmd & 0xff];
+ break;
+ }
+ }
+ return put_user(v, (int *)arg);
+ }
return -EINVAL;
}
diff --git a/drivers/sound/pas2_pcm.c b/drivers/sound/pas2_pcm.c
index 99e897161..c155dc3a6 100644
--- a/drivers/sound/pas2_pcm.c
+++ b/drivers/sound/pas2_pcm.c
@@ -8,6 +8,9 @@
* 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 "sound_config.h"
@@ -144,51 +147,53 @@ pcm_set_bits(int arg)
return pcm_bits;
}
-static int
-pas_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
+static int pas_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- int val;
+ int val, ret;
DEB(printk("pas2_pcm.c: static int pas_audio_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
- switch (cmd)
- {
- case SOUND_PCM_WRITE_RATE:
- val = *(int *) arg;
- return (*(int *) arg = pcm_set_speed(val));
- break;
-
- case SOUND_PCM_READ_RATE:
- return (*(int *) arg = pcm_speed);
- break;
-
- case SNDCTL_DSP_STEREO:
- val = *(int *) arg;
- return (*(int *) arg = pcm_set_channels(val + 1) - 1);
- break;
-
- case SOUND_PCM_WRITE_CHANNELS:
- val = *(int *) arg;
- return (*(int *) arg = pcm_set_channels(val));
- break;
-
- case SOUND_PCM_READ_CHANNELS:
- return (*(int *) arg = pcm_channels);
- break;
-
- case SNDCTL_DSP_SETFMT:
- val = *(int *) arg;
- return (*(int *) arg = pcm_set_bits(val));
- break;
-
- case SOUND_PCM_READ_BITS:
- return (*(int *) arg = pcm_bits);
-
- default:
- return -EINVAL;
- }
-
- return -EINVAL;
+ switch (cmd) {
+ case SOUND_PCM_WRITE_RATE:
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ ret = pcm_set_speed(val);
+ break;
+
+ case SOUND_PCM_READ_RATE:
+ ret = pcm_speed;
+ break;
+
+ case SNDCTL_DSP_STEREO:
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ ret = pcm_set_channels(val + 1) - 1;
+ break;
+
+ case SOUND_PCM_WRITE_CHANNELS:
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ ret = pcm_set_channels(val);
+ break;
+
+ case SOUND_PCM_READ_CHANNELS:
+ ret = pcm_channels;
+ break;
+
+ case SNDCTL_DSP_SETFMT:
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ ret = pcm_set_bits(val);
+ break;
+
+ case SOUND_PCM_READ_BITS:
+ ret = pcm_bits;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return __put_user(ret, (int *)arg);
}
static void
diff --git a/drivers/sound/pss.c b/drivers/sound/pss.c
index 50c06e6d0..9d62dd485 100644
--- a/drivers/sound/pss.c
+++ b/drivers/sound/pss.c
@@ -10,6 +10,9 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+/*
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ */
#include <linux/config.h>
#include <linux/module.h>
@@ -51,13 +54,11 @@
#include "coproc.h"
-#ifdef PSS_HAVE_LD
-#include "synth-ld.h"
+#ifdef CONFIG_PSS_HAVE_BOOT
+#include "pss_boot.h"
#else
-static int pss_synthLen = 0;
-static unsigned char *pss_synth =
-NULL;
-
+static unsigned char *pss_synth = NULL;
+static int pss_synthLen = 0;
#endif
typedef struct pss_confdata
@@ -500,257 +501,181 @@ download_boot_block(void *dev_info, copr_buffer * buf)
return 0;
}
-static int
-pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int local)
+static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int local)
{
+ copr_buffer *buf;
+ copr_msg *mbuf;
+ copr_debug_buf dbuf;
+ unsigned short tmp;
+ unsigned long flags;
+ unsigned short *data;
+ int i, err;
/* printk( "PSS coproc ioctl %x %x %d\n", cmd, arg, local); */
+
+ switch (cmd) {
+ case SNDCTL_COPR_RESET:
+ pss_coproc_reset(dev_info);
+ return 0;
- switch (cmd)
- {
- case SNDCTL_COPR_RESET:
- pss_coproc_reset(dev_info);
- return 0;
- break;
-
- case SNDCTL_COPR_LOAD:
- {
- copr_buffer *buf;
- int err;
-
- buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
- if (buf == NULL)
- return -ENOSPC;
-
- memcpy((char *) buf, (&((char *) arg)[0]), sizeof(*buf));
- err = download_boot_block(dev_info, buf);
- vfree(buf);
- return err;
- }
- break;
-
- case SNDCTL_COPR_SENDMSG:
- {
- copr_msg *buf;
- unsigned long flags;
- unsigned short *data;
- int i;
-
- buf = (copr_msg *) vmalloc(sizeof(copr_msg));
- if (buf == NULL)
- return -ENOSPC;
-
- memcpy((char *) buf, (&((char *) arg)[0]), sizeof(*buf));
-
- data = (unsigned short *) (buf->data);
-
- save_flags(flags);
- cli();
-
- for (i = 0; i < buf->len; i++)
- {
- if (!pss_put_dspword(devc, *data++))
- {
- restore_flags(flags);
- buf->len = i; /* feed back number of WORDs sent */
- memcpy((&((char *) arg)[0]), (char *) buf, sizeof(*buf));
- vfree(buf);
- return -EIO;
- }
- }
-
- restore_flags(flags);
- vfree(buf);
-
- return 0;
- }
- break;
-
-
- case SNDCTL_COPR_RCVMSG:
- {
- copr_msg *buf;
- unsigned long flags;
- unsigned short *data;
- unsigned int i;
- int err = 0;
-
- buf = (copr_msg *) vmalloc(sizeof(copr_msg));
- if (buf == NULL)
- return -ENOSPC;
-
-
- data = (unsigned short *) buf->data;
-
- save_flags(flags);
- cli();
-
- for (i = 0; i < buf->len; i++)
- {
- buf->len = i; /* feed back number of WORDs read */
- if (!pss_get_dspword(devc, data++))
- {
- if (i == 0)
- err = -EIO;
- break;
- }
- }
-
- restore_flags(flags);
-
- memcpy((&((char *) arg)[0]), (char *) buf, sizeof(*buf));
- vfree(buf);
-
- return err;
- }
- break;
-
-
- case SNDCTL_COPR_RDATA:
- {
- copr_debug_buf buf;
- unsigned long flags;
- unsigned short tmp;
-
- memcpy((char *) &buf, (&((char *) arg)[0]), sizeof(buf));
-
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d0))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short) (buf.parm1 & 0xffff)))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_get_dspword(devc, &tmp))
- {
- restore_flags(flags);
- return -EIO;
- }
- buf.parm1 = tmp;
- restore_flags(flags);
-
- memcpy((&((char *) arg)[0]), (char *) &buf, sizeof(buf));
- return 0;
- }
- break;
-
- case SNDCTL_COPR_WDATA:
- {
- copr_debug_buf buf;
- unsigned long flags;
- unsigned short tmp;
-
- memcpy((char *) &buf, (&((char *) arg)[0]), sizeof(buf));
-
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d1))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short) (buf.parm1 & 0xffff)))
- {
- restore_flags(flags);
- return -EIO;
- }
- tmp = (unsigned int) buf.parm2 & 0xffff;
- if (!pss_put_dspword(devc, tmp))
- {
- restore_flags(flags);
- return -EIO;
- }
- restore_flags(flags);
- return 0;
- }
- break;
-
- case SNDCTL_COPR_WCODE:
- {
- copr_debug_buf buf;
- unsigned long flags;
- unsigned short tmp;
-
- memcpy((char *) &buf, (&((char *) arg)[0]), sizeof(buf));
-
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d3))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short) (buf.parm1 & 0xffff)))
- {
- restore_flags(flags);
- return -EIO;
- }
- tmp = (unsigned int) buf.parm2 & 0x00ff;
- if (!pss_put_dspword(devc, tmp))
- {
- restore_flags(flags);
- return -EIO;
- }
- tmp = ((unsigned int) buf.parm2 >> 8) & 0xffff;
- if (!pss_put_dspword(devc, tmp))
- {
- restore_flags(flags);
- return -EIO;
- }
- restore_flags(flags);
- return 0;
- }
- break;
-
- case SNDCTL_COPR_RCODE:
- {
- copr_debug_buf buf;
- unsigned long flags;
- unsigned short tmp;
-
- memcpy((char *) &buf, (&((char *) arg)[0]), sizeof(buf));
-
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d2))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short) (buf.parm1 & 0xffff)))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_get_dspword(devc, &tmp)) /* Read MSB */
- {
- restore_flags(flags);
- return -EIO;
- }
- buf.parm1 = tmp << 8;
-
- if (!pss_get_dspword(devc, &tmp)) /* Read LSB */
- {
- restore_flags(flags);
- return -EIO;
- }
- buf.parm1 |= tmp & 0x00ff;
-
- restore_flags(flags);
-
- memcpy((&((char *) arg)[0]), (char *) &buf, sizeof(buf));
- return 0;
- }
- break;
+ case SNDCTL_COPR_LOAD:
+ buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
+ if (buf == NULL)
+ return -ENOSPC;
+ if (__copy_from_user(buf, arg, sizeof(copr_buffer))) {
+ vfree(buf);
+ return -EFAULT;
+ }
+ err = download_boot_block(dev_info, buf);
+ vfree(buf);
+ return err;
+
+ case SNDCTL_COPR_SENDMSG:
+ mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
+ if (mbuf == NULL)
+ return -ENOSPC;
+ if (__copy_from_user(mbuf, arg, sizeof(copr_msg))) {
+ vfree(mbuf);
+ return -EFAULT;
+ }
+ data = (unsigned short *)(mbuf->data);
+ save_flags(flags);
+ cli();
+ for (i = 0; i < mbuf->len; i++) {
+ if (!pss_put_dspword(devc, *data++)) {
+ restore_flags(flags);
+ mbuf->len = i; /* feed back number of WORDs sent */
+ err = __copy_to_user(arg, mbuf, sizeof(copr_msg));
+ vfree(mbuf);
+ return err ? -EFAULT : -EIO;
+ }
+ }
+ restore_flags(flags);
+ vfree(mbuf);
+ return 0;
- default:
- return -EINVAL;
- }
+ case SNDCTL_COPR_RCVMSG:
+ err = 0;
+ mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
+ if (mbuf == NULL)
+ return -ENOSPC;
+ data = (unsigned short *)mbuf->data;
+ save_flags(flags);
+ cli();
+ for (i = 0; i < mbuf->len; i++) {
+ mbuf->len = i; /* feed back number of WORDs read */
+ if (!pss_get_dspword(devc, data++)) {
+ if (i == 0)
+ err = -EIO;
+ break;
+ }
+ }
+ restore_flags(flags);
+ if (__copy_to_user(arg, mbuf, sizeof(copr_msg)))
+ err = -EFAULT;
+ vfree(mbuf);
+ return err;
+
+ case SNDCTL_COPR_RDATA:
+ if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d0)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_get_dspword(devc, &tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ dbuf.parm1 = tmp;
+ restore_flags(flags);
+ if (__copy_to_user(arg, &dbuf, sizeof(dbuf)))
+ return -EFAULT;
+ return 0;
+
+ case SNDCTL_COPR_WDATA:
+ if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d1)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ tmp = (unsigned int)dbuf.parm2 & 0xffff;
+ if (!pss_put_dspword(devc, tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ restore_flags(flags);
+ return 0;
+
+ case SNDCTL_COPR_WCODE:
+ if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d3)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ tmp = (unsigned int)dbuf.parm2 & 0x00ff;
+ if (!pss_put_dspword(devc, tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
+ if (!pss_put_dspword(devc, tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ restore_flags(flags);
+ return 0;
+
+ case SNDCTL_COPR_RCODE:
+ if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d2)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
+ restore_flags(flags);
+ return -EIO;
+ }
+ dbuf.parm1 = tmp << 8;
+ if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
+ restore_flags(flags);
+ return -EIO;
+ }
+ dbuf.parm1 |= tmp & 0x00ff;
+ restore_flags(flags);
+ if (__copy_to_user(arg, &dbuf, sizeof(dbuf)))
+ return -EFAULT;
+ return 0;
+ default:
+ return -EINVAL;
+ }
return -EINVAL;
}
diff --git a/drivers/sound/sb.h b/drivers/sound/sb.h
index 861f13c3b..431645165 100644
--- a/drivers/sound/sb.h
+++ b/drivers/sound/sb.h
@@ -1,3 +1,5 @@
+#include <linux/config.h>
+
#ifdef CONFIG_SBDSP
#define DSP_RESET (devc->base + 0x6)
#define DSP_READ (devc->base + 0xA)
diff --git a/drivers/sound/sb_audio.c b/drivers/sound/sb_audio.c
index 13751da3d..9a0fe3c79 100644
--- a/drivers/sound/sb_audio.c
+++ b/drivers/sound/sb_audio.c
@@ -833,7 +833,7 @@ static unsigned int sb16_audio_set_bits(int dev, unsigned int bits)
if (bits != 0)
{
- if (devc->bits == AFMT_U8 || bits == AFMT_S16_LE)
+ if (bits == AFMT_U8 || bits == AFMT_S16_LE)
devc->bits = bits;
else
devc->bits = AFMT_U8;
@@ -956,18 +956,13 @@ static void sb16_audio_trigger(int dev, int bits)
devc->trigger_bits = bits;
}
-static int sb_audio_ioctl(int dev, unsigned int cmd, caddr_t arg)
-{
- return -EINVAL;
-}
-
static struct audio_driver sb1_audio_driver = /* SB1.x */
{
sb_audio_open,
sb_audio_close,
sb_set_output_parms,
sb_set_input_parms,
- sb_audio_ioctl,
+ NULL, /* ioctl */
sb1_audio_prepare_for_input,
sb1_audio_prepare_for_output,
sb1_audio_halt_xfer,
@@ -987,7 +982,7 @@ static struct audio_driver sb20_audio_driver = /* SB2.0 */
sb_audio_close,
sb_set_output_parms,
sb_set_input_parms,
- sb_audio_ioctl,
+ NULL,
sb1_audio_prepare_for_input,
sb1_audio_prepare_for_output,
sb1_audio_halt_xfer,
@@ -1007,7 +1002,7 @@ static struct audio_driver sb201_audio_driver = /* SB2.01 */
sb_audio_close,
sb_set_output_parms,
sb_set_input_parms,
- sb_audio_ioctl,
+ NULL,
sb1_audio_prepare_for_input,
sb1_audio_prepare_for_output,
sb1_audio_halt_xfer,
@@ -1027,7 +1022,7 @@ static struct audio_driver sbpro_audio_driver = /* SB Pro */
sb_audio_close,
sb_set_output_parms,
sb_set_input_parms,
- sb_audio_ioctl,
+ NULL,
sbpro_audio_prepare_for_input,
sbpro_audio_prepare_for_output,
sb1_audio_halt_xfer,
@@ -1047,7 +1042,7 @@ static struct audio_driver jazz16_audio_driver = /* Jazz16 and SM Wave */
sb_audio_close,
sb_set_output_parms,
sb_set_input_parms,
- sb_audio_ioctl,
+ NULL,
sbpro_audio_prepare_for_input,
sbpro_audio_prepare_for_output,
sb1_audio_halt_xfer,
@@ -1067,7 +1062,7 @@ static struct audio_driver sb16_audio_driver = /* SB16 */
sb_audio_close,
sb_set_output_parms,
sb_set_input_parms,
- sb_audio_ioctl,
+ NULL,
sb16_audio_prepare_for_input,
sb16_audio_prepare_for_output,
sb1_audio_halt_xfer,
@@ -1087,7 +1082,7 @@ static struct audio_driver ess_audio_driver = /* ESS ES688/1688 */
sb_audio_close,
sb_set_output_parms,
sb_set_input_parms,
- sb_audio_ioctl,
+ NULL,
ess_audio_prepare_for_input,
ess_audio_prepare_for_output,
sb1_audio_halt_xfer,
diff --git a/drivers/sound/sb_card.c b/drivers/sound/sb_card.c
index 57cdc59e3..fddf74b79 100644
--- a/drivers/sound/sb_card.c
+++ b/drivers/sound/sb_card.c
@@ -34,10 +34,10 @@ int
probe_sb(struct address_info *hw_config)
{
if (check_region(hw_config->io_base, 16))
- {
- printk("\n\nsb_dsp.c: I/O port %x already in use\n\n", hw_config->io_base);
- return 0;
- }
+ {
+ printk("\n\nsb_card.c: I/O port %x is already in use\n\n", hw_config->io_base);
+ return 0;
+ }
return sb_dsp_detect(hw_config);
}
@@ -85,37 +85,36 @@ static int sbmpu = 0;
void *smw_free = NULL;
-int
-init_module(void)
+int init_module(void)
{
- printk("Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+ printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
if (mad16 == 0 && trix == 0 && pas2 == 0)
- {
- if (io == -1 || dma == -1 || irq == -1)
- {
- printk("I/O, IRQ, DMA and type are mandatory\n");
- return -EINVAL;
- }
- config.io_base = io;
- config.irq = irq;
- config.dma = dma;
- config.dma2 = dma16;
- config.card_subtype = type;
-
- if (!probe_sb(&config))
- return -ENODEV;
- attach_sb_card(&config);
+ {
+ if (io == -1 || dma == -1 || irq == -1)
+ {
+ printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n");
+ return -EINVAL;
+ }
+ config.io_base = io;
+ config.irq = irq;
+ config.dma = dma;
+ config.dma2 = dma16;
+ config.card_subtype = type;
+
+ if (!probe_sb(&config))
+ return -ENODEV;
+ attach_sb_card(&config);
#ifdef CONFIG_MIDI
- config_mpu.io_base = mpu_io;
- if (mpu_io && probe_sbmpu(&config_mpu))
- sbmpu = 1;
+ config_mpu.io_base = mpu_io;
+ if (mpu_io && probe_sbmpu(&config_mpu))
+ sbmpu = 1;
#endif
#ifdef CONFIG_MIDI
- if (sbmpu)
- attach_sbmpu(&config_mpu);
+ if (sbmpu)
+ attach_sbmpu(&config_mpu);
#endif
- }
+ }
SOUND_LOCK;
return 0;
}
diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c
index 70f67d75f..0f3e1e6aa 100644
--- a/drivers/sound/sb_common.c
+++ b/drivers/sound/sb_common.c
@@ -11,6 +11,7 @@
* for more info.
*/
#include <linux/config.h>
+#include <linux/delay.h>
#include "sound_config.h"
@@ -27,12 +28,13 @@
static sb_devc *detected_devc = NULL; /* For communication from probe to init */
static sb_devc *last_devc = NULL; /* For MPU401 initialization */
-static sb_devc *irq2devc[16] =
-{NULL};
-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};
+static sb_devc *irq2devc[16] = {NULL};
+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
+};
/*
* Jazz16 chipset specific control variables
@@ -54,8 +56,7 @@ static int smw_ucodeLen = 0;
#endif
-int
-sb_dsp_command(sb_devc * devc, unsigned char val)
+int sb_dsp_command(sb_devc * devc, unsigned char val)
{
int i;
unsigned long limit;
@@ -70,33 +71,31 @@ sb_dsp_command(sb_devc * devc, unsigned char val)
*/
for (i = 0; i < 500000 && jiffies < limit; i++)
- {
- if ((inb(DSP_STATUS) & 0x80) == 0)
- {
- outb((val), DSP_COMMAND);
- return 1;
- }
- }
-
- printk("Sound Blaster: DSP Command(%x) Timeout.\n", val);
+ {
+ if ((inb(DSP_STATUS) & 0x80) == 0)
+ {
+ outb((val), DSP_COMMAND);
+ return 1;
+ }
+ }
+
+ printk(KERN_WARNING "Sound Blaster: DSP Command(%x) Timeout.\n", val);
return 0;
}
-static int
-sb_dsp_get_byte(sb_devc * devc)
+static int sb_dsp_get_byte(sb_devc * devc)
{
int i;
for (i = 1000; i; i--)
if (inb(DSP_DATA_AVAIL) & 0x80)
- {
- return inb(DSP_READ);
- }
+ {
+ return inb(DSP_READ);
+ }
return 0xffff;
}
-int
-ess_write(sb_devc * devc, unsigned char reg, unsigned char data)
+int ess_write(sb_devc * devc, unsigned char reg, unsigned char data)
{
/* Write a byte to an extended mode register of ES1688 */
@@ -106,8 +105,7 @@ ess_write(sb_devc * devc, unsigned char reg, unsigned char data)
return sb_dsp_command(devc, data);
}
-int
-ess_read(sb_devc * devc, unsigned char reg)
+int ess_read(sb_devc * devc, unsigned char reg)
{
/* Read a byte from an extended mode register of ES1688 */
@@ -120,61 +118,61 @@ ess_read(sb_devc * devc, unsigned char reg)
return sb_dsp_get_byte(devc);
}
-static void
-sbintr(int irq, void *dev_id, struct pt_regs *dummy)
+static void sbintr(int irq, void *dev_id, struct pt_regs *dummy)
{
- int status;
+ int status;
unsigned char src = 0xff;
- sb_devc *devc = irq2devc[irq];
+ sb_devc *devc = irq2devc[irq];
if (devc == NULL || devc->irq != irq)
- {
- DEB(printk("sbintr: Bogus interrupt IRQ%d\n", irq));
- return;
- }
+ {
+ DEB(printk("sbintr: Bogus interrupt IRQ%d\n", irq));
+ return;
+ }
devc->irq_ok = 1;
if (devc->model == MDL_SB16)
- {
-
- src = sb_getmixer(devc, IRQ_STAT); /* Interrupt source register */
+ {
+ src = sb_getmixer(devc, IRQ_STAT); /* Interrupt source register */
#if defined(CONFIG_MIDI)&& (defined(CONFIG_UART401)||defined(CONFIG_UART401_MODULE))
- if (src & 4)
- uart401intr(devc->irq, NULL, NULL); /* MPU401 interrupt */
+ if (src & 4)
+ uart401intr(devc->irq, NULL, NULL); /* MPU401 interrupt */
#endif
- if (!(src & 3))
- return; /* Not a DSP interrupt */
- }
+ if (!(src & 3))
+ return; /* Not a DSP interrupt */
+ }
if (devc->intr_active)
+ {
switch (devc->irq_mode)
- {
- case IMODE_OUTPUT:
- DMAbuf_outputintr(devc->dev, 1);
- break;
+ {
+ case IMODE_OUTPUT:
+ DMAbuf_outputintr(devc->dev, 1);
+ break;
- case IMODE_INPUT:
- DMAbuf_inputintr(devc->dev);
- break;
+ case IMODE_INPUT:
+ DMAbuf_inputintr(devc->dev);
+ break;
- case IMODE_INIT:
- break;
+ case IMODE_INIT:
+ break;
- case IMODE_MIDI:
+ case IMODE_MIDI:
#if defined(CONFIG_MIDI)
- sb_midi_interrupt(devc);
+ sb_midi_interrupt(devc);
#endif
- break;
+ break;
- default:
- /* printk( "Sound Blaster: Unexpected interrupt\n"); */
- ;
- }
-/*
- * Acknowledge interrupts
- */
+ default:
+ /* printk( "Sound Blaster: Unexpected interrupt\n"); */
+ ;
+ }
+ }
+ /*
+ * Acknowledge interrupts
+ */
if (src & 0x01)
status = inb(DSP_DATA_AVAIL);
@@ -184,31 +182,28 @@ sbintr(int irq, void *dev_id, struct pt_regs *dummy)
}
-int
-sb_dsp_reset(sb_devc * devc)
+int sb_dsp_reset(sb_devc * devc)
{
- int loopc;
+ int loopc;
DEB(printk("Entered sb_dsp_reset()\n"));
if (devc->model == MDL_ESS)
- outb((3), DSP_RESET); /* Reset FIFO too */
+ outb(3, DSP_RESET); /* Reset FIFO too */
else
- outb((1), DSP_RESET);
+ outb(1, DSP_RESET);
- tenmicrosec(devc->osp);
- outb((0), DSP_RESET);
- tenmicrosec(devc->osp);
- tenmicrosec(devc->osp);
- tenmicrosec(devc->osp);
+ udelay(10);
+ outb(0, DSP_RESET);
+ udelay(30);
for (loopc = 0; loopc < 1000 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++);
if (inb(DSP_READ) != 0xAA)
- {
- DDB(printk("sb: No response to RESET\n"));
- return 0; /* Sorry */
- }
+ {
+ DDB(printk("sb: No response to RESET\n"));
+ return 0; /* Sorry */
+ }
if (devc->model == MDL_ESS)
sb_dsp_command(devc, 0xc6); /* Enable extended mode */
@@ -216,10 +211,9 @@ sb_dsp_reset(sb_devc * devc)
return 1;
}
-static void
-dsp_get_vers(sb_devc * devc)
+static void dsp_get_vers(sb_devc * devc)
{
- int i;
+ int i;
unsigned long flags;
@@ -230,32 +224,31 @@ dsp_get_vers(sb_devc * devc)
sb_dsp_command(devc, 0xe1); /* Get version */
for (i = 100000; i; i--)
- {
- if (inb(DSP_DATA_AVAIL) & 0x80)
- {
- if (devc->major == 0)
- devc->major = inb(DSP_READ);
- else
- {
- devc->minor = inb(DSP_READ);
- break;
- }
- }
- }
+ {
+ if (inb(DSP_DATA_AVAIL) & 0x80)
+ {
+ if (devc->major == 0)
+ devc->major = inb(DSP_READ);
+ else
+ {
+ devc->minor = inb(DSP_READ);
+ break;
+ }
+ }
+ }
DDB(printk("DSP version %d.%d\n", devc->major, devc->minor));
restore_flags(flags);
}
-static int
-sb16_set_dma_hw(sb_devc * devc)
+static int sb16_set_dma_hw(sb_devc * devc)
{
- int bits;
+ int bits;
if (devc->dma8 != 0 && devc->dma8 != 1 && devc->dma8 != 3)
- {
- printk("SB16: Invalid 8 bit DMA (%d)\n", devc->dma8);
- return 0;
- }
+ {
+ printk(KERN_ERR "SB16: Invalid 8 bit DMA (%d)\n", devc->dma8);
+ return 0;
+ }
bits = (1 << devc->dma8);
if (devc->dma16 >= 5 && devc->dma16 <= 7)
@@ -266,90 +259,84 @@ sb16_set_dma_hw(sb_devc * devc)
}
#if defined(CONFIG_MIDI) && defined(CONFIG_UART401)
-static void
-sb16_set_mpu_port(sb_devc * devc, struct address_info *hw_config)
+static void sb16_set_mpu_port(sb_devc * devc, struct address_info *hw_config)
{
-/*
- * This routine initializes new MIDI port setup register of SB Vibra (CT2502).
- */
+ /*
+ * This routine initializes new MIDI port setup register of SB Vibra (CT2502).
+ */
unsigned char bits = sb_getmixer(devc, 0x84) & ~0x06;
switch (hw_config->io_base)
- {
- case 0x300:
- sb_setmixer(devc, 0x84, bits | 0x04);
- break;
-
- case 0x330:
- sb_setmixer(devc, 0x84, bits | 0x00);
- break;
-
- default:
- sb_setmixer(devc, 0x84, bits | 0x02); /* Disable MPU */
- printk("SB16: Invalid MIDI I/O port %x\n", hw_config->io_base);
- }
+ {
+ case 0x300:
+ sb_setmixer(devc, 0x84, bits | 0x04);
+ break;
+
+ case 0x330:
+ sb_setmixer(devc, 0x84, bits | 0x00);
+ break;
+
+ default:
+ sb_setmixer(devc, 0x84, bits | 0x02); /* Disable MPU */
+ printk(KERN_ERR "SB16: Invalid MIDI I/O port %x\n", hw_config->io_base);
+ }
}
#endif
-static int
-sb16_set_irq_hw(sb_devc * devc, int level)
+static int sb16_set_irq_hw(sb_devc * devc, int level)
{
- int ival;
+ int ival;
switch (level)
- {
- case 5:
- ival = 2;
- break;
- case 7:
- ival = 4;
- break;
- case 9:
- ival = 1;
- break;
- case 10:
- ival = 8;
- break;
- default:
- printk("SB16 IRQ%d is not possible\n", level);
- return 0;
- }
+ {
+ case 5:
+ ival = 2;
+ break;
+ case 7:
+ ival = 4;
+ break;
+ case 9:
+ ival = 1;
+ break;
+ case 10:
+ ival = 8;
+ break;
+ default:
+ printk(KERN_ERR "SB16 IRQ%d is not possible\n", level);
+ return 0;
+ }
sb_setmixer(devc, IRQ_NR, ival);
return 1;
}
-static void
-relocate_Jazz16(sb_devc * devc, struct address_info *hw_config)
+static void relocate_Jazz16(sb_devc * devc, struct address_info *hw_config)
{
- unsigned char bits = 0;
- unsigned long flags;
+ unsigned char bits = 0;
+ unsigned long flags;
if (jazz16_base != 0 && jazz16_base != hw_config->io_base)
return;
switch (hw_config->io_base)
- {
- case 0x220:
- bits = 1;
- break;
- case 0x240:
- bits = 2;
- break;
- case 0x260:
- bits = 3;
- break;
-
- default:
- return;
- }
-
+ {
+ case 0x220:
+ bits = 1;
+ break;
+ case 0x240:
+ bits = 2;
+ break;
+ case 0x260:
+ bits = 3;
+ break;
+ default:
+ return;
+ }
bits = jazz16_bits = bits << 5;
-
jazz16_base = hw_config->io_base;
-/*
- * Magic wake up sequence by writing to 0x201 (aka Joystick port)
- */
+ /*
+ * Magic wake up sequence by writing to 0x201 (aka Joystick port)
+ */
save_flags(flags);
cli();
outb((0xAF), 0x201);
@@ -358,15 +345,13 @@ relocate_Jazz16(sb_devc * devc, struct address_info *hw_config)
restore_flags(flags);
}
-static int
-init_Jazz16(sb_devc * devc, struct address_info *hw_config)
+static int init_Jazz16(sb_devc * devc, struct address_info *hw_config)
{
- char name[100];
-
-/*
- * First try to check that the card has Jazz16 chip. It identifies itself
- * by returning 0x12 as response to DSP command 0xfa.
- */
+ char name[100];
+ /*
+ * First try to check that the card has Jazz16 chip. It identifies itself
+ * by returning 0x12 as response to DSP command 0xfa.
+ */
if (!sb_dsp_command(devc, 0xfa))
return 0;
@@ -374,32 +359,32 @@ init_Jazz16(sb_devc * devc, struct address_info *hw_config)
if (sb_dsp_get_byte(devc) != 0x12)
return 0;
-/*
- * OK so far. Now configure the IRQ and DMA channel used by the card.
- */
+ /*
+ * 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)
- {
- printk("Jazz16: Invalid interrupt (IRQ%d)\n", hw_config->irq);
- return 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)
- {
- printk("Jazz16: Invalid 8 bit DMA (DMA%d)\n", hw_config->dma);
+ {
+ printk(KERN_ERR "Jazz16: Invalid 8 bit DMA (DMA%d)\n", hw_config->dma);
return 0;
- }
+ }
if (hw_config->dma2 < 0)
- {
- printk("Jazz16: No 16 bit DMA channel defined\n");
- return 0;
- }
+ {
+ 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)
- {
- printk("Jazz16: Invalid 16 bit DMA (DMA%d)\n", hw_config->dma2);
- return 0;
- }
+ {
+ printk(KERN_ERR "Jazz16: Invalid 16 bit DMA (DMA%d)\n", hw_config->dma2);
+ return 0;
+ }
devc->dma16 = hw_config->dma2;
if (!sb_dsp_command(devc, 0xfb))
@@ -412,52 +397,45 @@ init_Jazz16(sb_devc * devc, struct address_info *hw_config)
if (!sb_dsp_command(devc, jazz_irq_bits[hw_config->irq]))
return 0;
-/*
- * Now we have configured a standard Jazz16 device.
- */
+ /*
+ * Now we have configured a standard Jazz16 device.
+ */
devc->model = MDL_JAZZ;
strcpy(name, "Jazz16");
-
- hw_config->name = (char *) (sound_mem_blocks[sound_nblocks] = vmalloc(strlen(name + 1)));
- sound_mem_sizes[sound_nblocks] = strlen(name + 1);
- if (sound_nblocks < 1024)
- sound_nblocks++;;
- if (hw_config->name != NULL)
- strcpy(hw_config->name, name);
+ hw_config->name = "Jazz16";
devc->caps |= SB_NO_MIDI;
return 1;
}
-static void
-relocate_ess1688(sb_devc * devc)
+static void relocate_ess1688(sb_devc * devc)
{
- unsigned char bits;
+ unsigned char bits;
switch (devc->base)
- {
- case 0x220:
- bits = 0x04;
- break;
- case 0x230:
- bits = 0x05;
- break;
- case 0x240:
- bits = 0x06;
- break;
- case 0x250:
- bits = 0x07;
- break;
- default:
- return; /* Wrong port */
- }
+ {
+ case 0x220:
+ bits = 0x04;
+ break;
+ case 0x230:
+ bits = 0x05;
+ break;
+ case 0x240:
+ bits = 0x06;
+ break;
+ case 0x250:
+ bits = 0x07;
+ break;
+ default:
+ return; /* Wrong port */
+ }
DDB(printk("Doing ESS1688 address selection\n"));
-
-/*
- * ES1688 supports two alternative ways for software address config.
- * First try the so called Read-Sequence-Key method.
- */
+
+ /*
+ * ES1688 supports two alternative ways for software address config.
+ * First try the so called Read-Sequence-Key method.
+ */
/* Reset the sequence logic */
inb(0x229);
@@ -479,9 +457,9 @@ relocate_ess1688(sb_devc * devc)
return;
#if 0 /* This causes system lockups (Nokia 386/25 at least) */
-/*
- * The last resort is the system control register method.
- */
+ /*
+ * The last resort is the system control register method.
+ */
outb((0x00), 0xfb); /* 0xFB is the unlock register */
outb((0x00), 0xe0); /* Select index 0 */
@@ -490,130 +468,123 @@ relocate_ess1688(sb_devc * devc)
#endif
}
-static int
-ess_init(sb_devc * devc, struct address_info *hw_config)
+static int ess_init(sb_devc * devc, struct address_info *hw_config)
{
- unsigned char cfg, irq_bits = 0, dma_bits = 0;
- int ess_major = 0, ess_minor = 0;
- int i;
- char name[100];
+ unsigned char cfg, irq_bits = 0, dma_bits = 0;
+ int ess_major = 0, ess_minor = 0;
+ int i;
+ static char name[100];
-/*
- * Try to detect ESS chips.
- */
+ /*
+ * Try to detect ESS chips.
+ */
sb_dsp_command(devc, 0xe7); /* Return identification */
for (i = 1000; i; i--)
- {
- if (inb(DSP_DATA_AVAIL) & 0x80)
- {
- if (ess_major == 0)
- ess_major = inb(DSP_READ);
- else
- {
- ess_minor = inb(DSP_READ);
- break;
- }
- }
- }
+ {
+ if (inb(DSP_DATA_AVAIL) & 0x80)
+ {
+ if (ess_major == 0)
+ ess_major = inb(DSP_READ);
+ else
+ {
+ ess_minor = inb(DSP_READ);
+ break;
+ }
+ }
+ }
if (ess_major == 0)
return 0;
if (ess_major == 0x48 && (ess_minor & 0xf0) == 0x80)
- {
- sprintf(name, "ESS ES488 AudioDrive (rev %d)",
+ {
+ sprintf(name, "ESS ES488 AudioDrive (rev %d)",
ess_minor & 0x0f);
- hw_config->name = name;
- devc->model = MDL_SBPRO;
- return 1;
- } else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80)
- {
- char *chip = "ES688";
-
- if ((ess_minor & 0x0f) >= 8)
- chip = "ES1688";
-
- sprintf(name,
- "ESS %s AudioDrive (rev %d)",
- chip, ess_minor & 0x0f);
- } else
+ hw_config->name = name;
+ devc->model = MDL_SBPRO;
+ return 1;
+ }
+ else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80)
+ {
+ char *chip = "ES688";
+
+ if ((ess_minor & 0x0f) >= 8)
+ chip = "ES1688";
+
+ sprintf(name,"ESS %s AudioDrive (rev %d)",
+ chip, ess_minor & 0x0f);
+ }
+ else
strcpy(name, "Jazz16");
devc->model = MDL_ESS;
devc->submodel = ess_minor & 0x0f;
-
- hw_config->name = (char *) (sound_mem_blocks[sound_nblocks] = vmalloc(strlen(name + 1)));
- sound_mem_sizes[sound_nblocks] = strlen(name + 1);
- if (sound_nblocks < 1024)
- sound_nblocks++;;
- if (hw_config->name != NULL)
- strcpy(hw_config->name, name);
-
-
+ hw_config->name = name;
sb_dsp_reset(devc); /* Turn on extended mode */
-/*
- * Set IRQ configuration register
- */
+ /*
+ * Set IRQ configuration register
+ */
cfg = 0x50; /* Enable only DMA counter interrupt */
switch (devc->irq)
- {
- case 2:
- case 9:
- irq_bits = 0;
- break;
-
- case 5:
- irq_bits = 1;
- break;
-
- case 7:
- irq_bits = 2;
- break;
-
- case 10:
- irq_bits = 3;
- break;
-
- default:
- irq_bits = 0;
- cfg = 0x10; /* Disable all interrupts */
- printk("\nESS1688: Invalid IRQ %d\n", devc->irq);
- return 0;
- }
+ {
+ case 2:
+ case 9:
+ irq_bits = 0;
+ break;
+
+ case 5:
+ irq_bits = 1;
+ break;
+
+ case 7:
+ irq_bits = 2;
+ break;
+
+ case 10:
+ irq_bits = 3;
+ break;
+
+ default:
+ irq_bits = 0;
+ cfg = 0x10; /* Disable all interrupts */
+ printk(KERN_ERR "ESS1688: Invalid IRQ %d\n", devc->irq);
+ return 0;
+ }
if (!ess_write(devc, 0xb1, cfg | (irq_bits << 2)))
- printk("\nESS1688: Failed to write to IRQ config register\n");
+ printk(KERN_ERR "ESS1688: Failed to write to IRQ config register\n");
-/*
- * Set DMA configuration register
- */
+ /*
+ * Set DMA configuration register
+ */
cfg = 0x50; /* Extended mode DMA enable */
if (devc->dma8 > 3 || devc->dma8 < 0 || devc->dma8 == 2)
- {
- dma_bits = 0;
- cfg = 0x00; /* Disable all DMA */
- printk("\nESS1688: Invalid DMA %d\n", devc->dma8);
- } else
- {
- if (devc->dma8 == 3)
- dma_bits = 3;
- else
- dma_bits = devc->dma8 + 1;
- }
+ {
+ dma_bits = 0;
+ cfg = 0x00; /* Disable all DMA */
+ printk(KERN_ERR "ESS1688: Invalid DMA %d\n", devc->dma8);
+ }
+ else
+ {
+ if (devc->dma8 == 3)
+ dma_bits = 3;
+ else
+ dma_bits = devc->dma8 + 1;
+ }
if (!ess_write(devc, 0xb2, cfg | (dma_bits << 2)))
- printk("\nESS1688: Failed to write to DMA config register\n");
+ printk(KERN_ERR "ESS1688: Failed to write to DMA config register\n");
-/*
- * Enable joystick and OPL3
- */
+ /*
+ * Enable joystick and OPL3
+ */
cfg = sb_getmixer(devc, 0x40);
sb_setmixer(devc, 0x40, cfg | 0x03);
@@ -623,26 +594,27 @@ ess_init(sb_devc * devc, struct address_info *hw_config)
return 1;
}
-int
-sb_dsp_detect(struct address_info *hw_config)
+int sb_dsp_detect(struct address_info *hw_config)
{
- sb_devc sb_info;
- sb_devc *devc = &sb_info;
+ sb_devc sb_info;
+ sb_devc *devc = &sb_info;
sb_info.my_mididev = -1;
sb_info.my_mixerdev = -1;
sb_info.my_dev = -1;
-/*
- * Initialize variables
- */
+
+ /*
+ * Initialize variables
+ */
+
DDB(printk("sb_dsp_detect(%x) entered\n", hw_config->io_base));
if (check_region(hw_config->io_base, 16))
- {
+ {
#ifdef MODULE
- printk("sb: I/O region in use.\n");
+ printk(KERN_INFO "sb: I/O region in use.\n");
#endif
- return 0;
- }
+ return 0;
+ }
memset((char *) &sb_info, 0, sizeof(sb_info)); /* Zero everything */
devc->type = hw_config->card_subtype;
@@ -654,24 +626,24 @@ sb_dsp_detect(struct address_info *hw_config)
devc->dma16 = -1;
if (acer)
- {
- cli();
- inb(devc->base + 0x09);
- inb(devc->base + 0x09);
- inb(devc->base + 0x09);
- inb(devc->base + 0x0b);
- inb(devc->base + 0x09);
- inb(devc->base + 0x0b);
- inb(devc->base + 0x09);
- inb(devc->base + 0x09);
- inb(devc->base + 0x0b);
- inb(devc->base + 0x09);
- inb(devc->base + 0x00);
- sti();
- }
-/*
- * Detect the device
- */
+ {
+ cli();
+ inb(devc->base + 0x09);
+ inb(devc->base + 0x09);
+ inb(devc->base + 0x09);
+ inb(devc->base + 0x0b);
+ inb(devc->base + 0x09);
+ inb(devc->base + 0x0b);
+ inb(devc->base + 0x09);
+ inb(devc->base + 0x09);
+ inb(devc->base + 0x0b);
+ inb(devc->base + 0x09);
+ inb(devc->base + 0x00);
+ sti();
+ }
+ /*
+ * Detect the device
+ */
if (sb_dsp_reset(devc))
dsp_get_vers(devc);
@@ -686,36 +658,36 @@ sb_dsp_detect(struct address_info *hw_config)
relocate_ess1688(devc);
if (!sb_dsp_reset(devc))
- {
- DDB(printk("SB reset failed\n"));
+ {
+ DDB(printk("SB reset failed\n"));
#ifdef MODULE
- printk("sb: dsp reset failed.\n");
+ printk(KERN_INFO "sb: dsp reset failed.\n");
#endif
- return 0;
- }
+ return 0;
+ }
if (devc->major == 0)
dsp_get_vers(devc);
if (devc->major == 3 && devc->minor == 1)
- {
- if (devc->type == MDL_AZTECH) /* SG Washington? */
- {
- if (sb_dsp_command(devc, 0x09))
- if (sb_dsp_command(devc, 0x00)) /* Enter WSS mode */
- {
- int i;
-
- /* Have some delay */
- for (i = 0; i < 10000; i++)
- inb(DSP_DATA_AVAIL);
- devc->caps = SB_NO_AUDIO | SB_NO_MIDI; /* Mixer only */
- devc->model = MDL_AZTECH;
- }
- }
- }
-/*
- * Save device information for sb_dsp_init()
- */
+ {
+ if (devc->type == MDL_AZTECH) /* SG Washington? */
+ {
+ if (sb_dsp_command(devc, 0x09))
+ if (sb_dsp_command(devc, 0x00)) /* Enter WSS mode */
+ {
+ int i;
+
+ /* Have some delay */
+ for (i = 0; i < 10000; i++)
+ inb(DSP_DATA_AVAIL);
+ devc->caps = SB_NO_AUDIO | SB_NO_MIDI; /* Mixer only */
+ devc->model = MDL_AZTECH;
+ }
+ }
+ }
+ /*
+ * Save device information for sb_dsp_init()
+ */
detected_devc = (sb_devc *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(sb_devc)));
@@ -724,22 +696,20 @@ sb_dsp_detect(struct address_info *hw_config)
sound_nblocks++;;
if (detected_devc == NULL)
- {
- printk(KERN_ERR "sb: Can't allocate memory for device information\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "sb: Can't allocate memory for device information\n");
+ return 0;
+ }
memcpy((char *) detected_devc, (char *) devc, sizeof(sb_devc));
-
MDB(printk("SB %d.%d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base));
return 1;
}
-void
-sb_dsp_init(struct address_info *hw_config)
+void sb_dsp_init(struct address_info *hw_config)
{
- sb_devc *devc;
- char name[100];
- extern int sb_be_quiet;
+ sb_devc *devc;
+ char name[100];
+ extern int sb_be_quiet;
/*
* Check if we had detected a SB device earlier
@@ -748,130 +718,131 @@ sb_dsp_init(struct address_info *hw_config)
name[0] = 0;
if (detected_devc == NULL)
- {
- MDB(printk("No detected device\n"));
- return;
- }
+ {
+ MDB(printk("No detected device\n"));
+ return;
+ }
devc = detected_devc;
detected_devc = NULL;
if (devc->base != hw_config->io_base)
- {
- DDB(printk("I/O port mismatch\n"));
- return;
- }
-/*
- * Now continue initialization of the device
- */
+ {
+ DDB(printk("I/O port mismatch\n"));
+ return;
+ }
+ /*
+ * Now continue initialization of the device
+ */
devc->dev = sound_alloc_audiodev();
if (devc->dev == -1)
- {
- printk(KERN_WARNING "sb: too many audio devices.\n");
- return;
- }
+ {
+ printk(KERN_WARNING "sb: too many audio devices.\n");
+ return;
+ }
devc->caps = hw_config->driver_use_1;
- if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) &&
- hw_config->irq > 0)
- { /* IRQ setup */
- if (snd_set_irq_handler(hw_config->irq,
- sbintr, "soundblaster", devc->osp) < 0)
- {
- printk(KERN_ERR "SB: Can't allocate IRQ%d\n", hw_config->irq);
- sound_unload_audiodev(devc->dev);
- return;
- }
- irq2devc[hw_config->irq] = devc;
- devc->irq_ok = 0;
-
- if (devc->major == 4)
- if (!sb16_set_irq_hw(devc, devc->irq)) /* Unsupported IRQ */
- {
- snd_release_irq(devc->irq);
- sound_unload_audiodev(devc->dev);
- irq2devc[hw_config->irq] = NULL;
- return;
- }
- if ((devc->type == 0 || devc->type == MDL_ESS) &&
- devc->major == 3 && devc->minor == 1)
- { /* Handle various chipsets which claim they are SB Pro compatible */
- if ((devc->type != 0 && devc->type != MDL_ESS) ||
+ if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) && hw_config->irq > 0)
+ { /* IRQ setup */
+ if (snd_set_irq_handler(hw_config->irq, sbintr, "soundblaster", devc->osp) < 0)
+ {
+ printk(KERN_ERR "SB: Can't allocate IRQ%d\n", hw_config->irq);
+ sound_unload_audiodev(devc->dev);
+ return;
+ }
+ irq2devc[hw_config->irq] = devc;
+ devc->irq_ok = 0;
+
+ if (devc->major == 4)
+ if (!sb16_set_irq_hw(devc, devc->irq)) /* Unsupported IRQ */
+ {
+ snd_release_irq(devc->irq);
+ sound_unload_audiodev(devc->dev);
+ irq2devc[hw_config->irq] = NULL;
+ return;
+ }
+ if ((devc->type == 0 || devc->type == MDL_ESS) &&
+ devc->major == 3 && devc->minor == 1)
+ { /* Handle various chipsets which claim they are SB Pro compatible */
+ if ((devc->type != 0 && devc->type != MDL_ESS) ||
!ess_init(devc, hw_config))
- if ((devc->type != 0 && devc->type != MDL_JAZZ &&
+ {
+ if ((devc->type != 0 && devc->type != MDL_JAZZ &&
devc->type != MDL_SMW) || !init_Jazz16(devc, hw_config))
- {
- DDB(printk("This is a genuine SB Pro\n"));
- }
- }
-#if defined(__SMP__) || defined(__FreeBSD__)
- /* Skip IRQ detection if SMP (doesn't work) */
- devc->irq_ok = 1;
+ {
+ DDB(printk("This is a genuine SB Pro\n"));
+ }
+ }
+ }
+#if defined(__SMP__)
+ /* Skip IRQ detection if SMP (doesn't work) */
+ devc->irq_ok = 1;
#else
- if (devc->major == 4 && devc->minor <= 11) /* Won't work */
- devc->irq_ok = 1;
- else
- {
- int n;
-
- for (n = 0; n < 3 && devc->irq_ok == 0; n++)
- if (sb_dsp_command(devc, 0xf2)) /* Cause interrupt immediately */
- {
- int i;
-
- for (i = 0; !devc->irq_ok && i < 10000; i++);
- }
- if (!devc->irq_ok)
- {
- printk("sb: Interrupt test on IRQ%d failed - Probable IRQ conflict\n", devc->irq);
- } else
- {
- DDB(printk("IRQ test OK (IRQ%d)\n", devc->irq));
- }
-
- }
+ if (devc->major == 4 && devc->minor <= 11) /* Won't work */
+ devc->irq_ok = 1;
+ else
+ {
+ int n;
+
+ for (n = 0; n < 3 && devc->irq_ok == 0; n++)
+ {
+ if (sb_dsp_command(devc, 0xf2)) /* Cause interrupt immediately */
+ {
+ int i;
+
+ for (i = 0; !devc->irq_ok && i < 10000; i++);
+ }
+ }
+ if (!devc->irq_ok)
+ printk(KERN_WARNING "sb: Interrupt test on IRQ%d failed - Probable IRQ conflict\n", devc->irq);
+ else
+ {
+ DDB(printk("IRQ test OK (IRQ%d)\n", devc->irq));
+ }
+ }
#endif /* __SMP__ */
- } /* IRQ setup */
+ } /* IRQ setup */
request_region(hw_config->io_base, 16, "soundblaster");
switch (devc->major)
- {
- case 1: /* SB 1.0 or 1.5 */
- devc->model = hw_config->card_subtype = MDL_SB1;
- break;
-
- case 2: /* SB 2.x */
- if (devc->minor == 0)
- devc->model = hw_config->card_subtype = MDL_SB2;
- else
- devc->model = hw_config->card_subtype = MDL_SB201;
- break;
-
- case 3: /* SB Pro and most clones */
- if (devc->model == 0)
- {
- devc->model = hw_config->card_subtype = MDL_SBPRO;
- if (hw_config->name == NULL)
- hw_config->name = "Sound Blaster Pro (8 BIT ONLY)";
- }
- break;
-
- case 4:
- devc->model = hw_config->card_subtype = MDL_SB16;
- if (hw_config->name == NULL)
- hw_config->name = "Sound Blaster 16";
-
- if (hw_config->dma2 == -1)
- devc->dma16 = devc->dma8;
- else if (hw_config->dma2 < 5 || hw_config->dma2 > 7)
- {
- printk("SB16: Bad or missing 16 bit DMA channel\n");
- devc->dma16 = devc->dma8;
- } else
- devc->dma16 = hw_config->dma2;
-
- sb16_set_dma_hw(devc);
- devc->caps |= SB_NO_MIDI;
- }
+ {
+ case 1: /* SB 1.0 or 1.5 */
+ devc->model = hw_config->card_subtype = MDL_SB1;
+ break;
+
+ case 2: /* SB 2.x */
+ if (devc->minor == 0)
+ devc->model = hw_config->card_subtype = MDL_SB2;
+ else
+ devc->model = hw_config->card_subtype = MDL_SB201;
+ break;
+
+ case 3: /* SB Pro and most clones */
+ if (devc->model == 0)
+ {
+ devc->model = hw_config->card_subtype = MDL_SBPRO;
+ if (hw_config->name == NULL)
+ hw_config->name = "Sound Blaster Pro (8 BIT ONLY)";
+ }
+ break;
+
+ case 4:
+ devc->model = hw_config->card_subtype = MDL_SB16;
+ if (hw_config->name == NULL)
+ hw_config->name = "Sound Blaster 16";
+
+ if (hw_config->dma2 == -1)
+ devc->dma16 = devc->dma8;
+ else if (hw_config->dma2 < 5 || hw_config->dma2 > 7)
+ {
+ printk(KERN_WARNING "SB16: Bad or missing 16 bit DMA channel\n");
+ devc->dma16 = devc->dma8;
+ }
+ else
+ devc->dma16 = hw_config->dma2;
+
+ sb16_set_dma_hw(devc);
+ devc->caps |= SB_NO_MIDI;
+ }
if (!(devc->caps & SB_NO_MIXER))
if (devc->major == 3 || devc->major == 4)
@@ -888,62 +859,63 @@ sb_dsp_init(struct address_info *hw_config)
sprintf(name, "%s (%d.%d)", hw_config->name, devc->major, devc->minor);
conf_printf(name, hw_config);
-/*
- * Assuming that a soundcard is Sound Blaster (compatible) is the most common
- * configuration error and the mother of all problems. Usually soundcards
- * emulate SB Pro but in addition they have a 16 bit native mode which should be
- * used in Unix. See Readme.cards for more information about configuring OSS/Free
- * properly.
- */
+ /*
+ * Assuming that a soundcard is Sound Blaster (compatible) is the most common
+ * configuration error and the mother of all problems. Usually soundcards
+ * emulate SB Pro but in addition they have a 16 bit native mode which should be
+ * used in Unix. See Readme.cards for more information about configuring OSS/Free
+ * properly.
+ */
if (devc->model <= MDL_SBPRO)
+ {
if (devc->major == 3 && devc->minor != 1) /* "True" SB Pro should have v3.1 (rare ones may have 3.2). */
- {
- printk("This soundcard may not be fully Sound Blaster Pro compatible.\n");
- printk("In many cases there is another way to configure OSS so that\n");
- printk("it works properly with OSS (for example in 16 bit mode).\n");
- printk("Please ignore this message if you _really_ have a SB Pro.\n");
- } else if (!sb_be_quiet && devc->model == MDL_SBPRO)
- {
- printk("SB DSP version is just %d.%d which means that your card is\n", devc->major, devc->minor);
- printk("several years old (8 bit only device)\n");
- printk("or alternatively the sound driver is incorrectly configured.\n");
- }
+ {
+ printk(KERN_INFO "This soundcard may not be fully Sound Blaster Pro compatible.\n");
+ printk(KERN_INFO "In many cases there is another way to configure OSS so that\n");
+ printk(KERN_INFO "it works properly with OSS (for example in 16 bit mode).\n");
+ printk(KERN_INFO "Please ignore this message if you _really_ have a SB Pro.\n");
+ }
+ else if (!sb_be_quiet && devc->model == MDL_SBPRO)
+ {
+ printk(KERN_INFO "SB DSP version is just %d.%d which means that your card is\n", devc->major, devc->minor);
+ printk(KERN_INFO "several years old (8 bit only device) or alternatively the sound driver\n");
+ printk(KERN_INFO "is incorrectly configured.\n");
+ }
+ }
hw_config->card_subtype = devc->model;
last_devc = devc; /* For SB MPU detection */
if (!(devc->caps & SB_NO_AUDIO) && devc->dma8 >= 0)
- {
- if (sound_alloc_dma(devc->dma8, "SoundBlaster8"))
- {
- printk("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("SB: 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"));
- }
+ {
+ if (sound_alloc_dma(devc->dma8, "SoundBlaster8"))
+ {
+ 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);
+ }
+ sb_audio_init(devc, name);
+ }
+ else
+ {
+ MDB(printk("sb: No audio devices found.\n"));
+ }
}
-void
-sb_dsp_disable_midi(int io_base)
+void sb_dsp_disable_midi(int io_base)
{
}
-void
-sb_dsp_disable_recording(int io_base)
+void sb_dsp_disable_recording(int io_base)
{
}
-void
-sb_dsp_unload(struct address_info *hw_config)
+void sb_dsp_unload(struct address_info *hw_config)
{
- sb_devc *devc;
- int irq = hw_config->irq;
+ sb_devc *devc;
+ int irq = hw_config->irq;
if (irq < 0)
irq *= -1;
@@ -954,36 +926,33 @@ sb_dsp_unload(struct address_info *hw_config)
devc = NULL;
if (devc && devc->base == hw_config->io_base)
- {
- release_region(devc->base, 16);
-
- if (!(devc->caps & SB_NO_AUDIO))
- {
- sound_free_dma(devc->dma8);
-
- if (devc->dma16 >= 0)
- sound_free_dma(devc->dma16);
- }
- if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) &&
- devc->irq > 0)
- {
- snd_release_irq(devc->irq);
- irq2devc[devc->irq] = NULL;
- sound_unload_mixerdev(devc->my_mixerdev);
- sound_unload_mididev(devc->my_mididev);
- sound_unload_audiodev(devc->my_dev);
- }
- } else
+ {
+ release_region(devc->base, 16);
+
+ if (!(devc->caps & SB_NO_AUDIO))
+ {
+ sound_free_dma(devc->dma8);
+ if (devc->dma16 >= 0)
+ sound_free_dma(devc->dma16);
+ }
+ if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) && devc->irq > 0)
+ {
+ snd_release_irq(devc->irq);
+ irq2devc[devc->irq] = NULL;
+ sound_unload_mixerdev(devc->my_mixerdev);
+ sound_unload_mididev(devc->my_mididev);
+ sound_unload_audiodev(devc->my_dev);
+ }
+ }
+ else
release_region(hw_config->io_base, 16);
-
}
/*
- * Mixer access routines
+ * Mixer access routines
*/
-void
-sb_setmixer(sb_devc * devc, unsigned int port, unsigned int value)
+void sb_setmixer(sb_devc * devc, unsigned int port, unsigned int value)
{
unsigned long flags;
@@ -991,43 +960,38 @@ sb_setmixer(sb_devc * devc, unsigned int port, unsigned int value)
cli();
outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
- tenmicrosec(devc->osp);
- tenmicrosec(devc->osp);
+ udelay(20);
outb(((unsigned char) (value & 0xff)), MIXER_DATA);
- tenmicrosec(devc->osp);
- tenmicrosec(devc->osp);
+ udelay(20);
restore_flags(flags);
}
-unsigned int
-sb_getmixer(sb_devc * devc, unsigned int port)
+unsigned int sb_getmixer(sb_devc * devc, unsigned int port)
{
- unsigned int val;
- unsigned long flags;
+ unsigned int val;
+ unsigned long flags;
save_flags(flags);
cli();
outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
- tenmicrosec(devc->osp);
- tenmicrosec(devc->osp);
+ udelay(20);
val = inb(MIXER_DATA);
- tenmicrosec(devc->osp);
- tenmicrosec(devc->osp);
+ udelay(20);
restore_flags(flags);
return val;
}
#if defined(CONFIG_MIDI)
+
/*
- * MPU401 MIDI initialization.
+ * MPU401 MIDI initialization.
*/
-static void
-smw_putmem(sb_devc * devc, int base, int addr, unsigned char val)
+static void smw_putmem(sb_devc * devc, int base, int addr, unsigned char val)
{
- unsigned long flags;
+ unsigned long flags;
save_flags(flags);
cli();
@@ -1039,11 +1003,10 @@ smw_putmem(sb_devc * devc, int base, int addr, unsigned char val)
restore_flags(flags);
}
-static unsigned char
-smw_getmem(sb_devc * devc, int base, int addr)
+static unsigned char smw_getmem(sb_devc * devc, int base, int addr)
{
- unsigned long flags;
- unsigned char val;
+ unsigned long flags;
+ unsigned char val;
save_flags(flags);
cli();
@@ -1056,42 +1019,40 @@ smw_getmem(sb_devc * devc, int base, int addr)
return val;
}
-static int
-smw_midi_init(sb_devc * devc, struct address_info *hw_config)
+static int smw_midi_init(sb_devc * devc, struct address_info *hw_config)
{
- int mpu_base = hw_config->io_base;
- int mp_base = mpu_base + 4; /* Microcontroller base */
- int i;
- unsigned char control;
+ int mpu_base = hw_config->io_base;
+ int mp_base = mpu_base + 4; /* Microcontroller base */
+ int i;
+ unsigned char control;
/*
- * Reset the microcontroller so that the RAM can be accessed
+ * Reset the microcontroller so that the RAM can be accessed
*/
control = inb(mpu_base + 7);
outb((control | 3), mpu_base + 7); /* Set last two bits to 1 (?) */
outb(((control & 0xfe) | 2), mpu_base + 7); /* xxxxxxx0 resets the mc */
- for (i = 0; i < 300; i++) /* Wait at least 1ms */
- tenmicrosec(devc->osp);
+ udelay(3000); /* Wait at least 1ms */
outb((control & 0xfc), mpu_base + 7); /* xxxxxx00 enables RAM */
/*
- * Detect microcontroller by probing the 8k RAM area
+ * Detect microcontroller by probing the 8k RAM area
*/
smw_putmem(devc, mp_base, 0, 0x00);
smw_putmem(devc, mp_base, 1, 0xff);
- tenmicrosec(devc->osp);
+ udelay(10);
if (smw_getmem(devc, mp_base, 0) != 0x00 || smw_getmem(devc, mp_base, 1) != 0xff)
- {
- DDB(printk("\nSM Wave: No microcontroller RAM detected (%02x, %02x)\n", smw_getmem(devc, mp_base, 0), smw_getmem(devc, mp_base, 1)));
- return 0; /* No RAM */
- }
+ {
+ DDB(printk("SM Wave: No microcontroller RAM detected (%02x, %02x)\n", smw_getmem(devc, mp_base, 0), smw_getmem(devc, mp_base, 1)));
+ return 0; /* No RAM */
+ }
/*
- * There is RAM so assume it's really a SM Wave
+ * There is RAM so assume it's really a SM Wave
*/
devc->model = MDL_SMW;
@@ -1099,179 +1060,173 @@ smw_midi_init(sb_devc * devc, struct address_info *hw_config)
#ifdef MODULE
if (!smw_ucode)
- {
- extern void *smw_free;
+ {
+ extern void *smw_free;
- smw_ucodeLen = mod_firmware_load("/etc/sound/midi0001.bin", (void *) &smw_ucode);
- smw_free = smw_ucode;
- }
+ smw_ucodeLen = mod_firmware_load("/etc/sound/midi0001.bin", (void *) &smw_ucode);
+ smw_free = smw_ucode;
+ }
#endif
if (smw_ucodeLen > 0)
- {
- if (smw_ucodeLen != 8192)
- {
- printk("\nSM Wave: Invalid microcode (MIDI0001.BIN) length\n");
- return 1;
- }
- /*
- * Download microcode
- */
-
- for (i = 0; i < 8192; i++)
- smw_putmem(devc, mp_base, i, smw_ucode[i]);
-
- /*
- * Verify microcode
- */
-
- for (i = 0; i < 8192; i++)
- if (smw_getmem(devc, mp_base, i) != smw_ucode[i])
- {
- printk("SM Wave: Microcode verification failed\n");
- return 0;
- }
- }
+ {
+ if (smw_ucodeLen != 8192)
+ {
+ printk(KERN_ERR "SM Wave: Invalid microcode (MIDI0001.BIN) length\n");
+ return 1;
+ }
+ /*
+ * Download microcode
+ */
+
+ for (i = 0; i < 8192; i++)
+ smw_putmem(devc, mp_base, i, smw_ucode[i]);
+
+ /*
+ * Verify microcode
+ */
+
+ for (i = 0; i < 8192; i++)
+ if (smw_getmem(devc, mp_base, i) != smw_ucode[i])
+ {
+ printk(KERN_ERR "SM Wave: Microcode verification failed\n");
+ return 0;
+ }
+ }
control = 0;
#ifdef SMW_SCSI_IRQ
/*
- * Set the SCSI interrupt (IRQ2/9, IRQ3 or IRQ10). The SCSI interrupt
- * is disabled by default.
- *
- * BTW the Zilog 5380 SCSI controller is located at MPU base + 0x10.
+ * Set the SCSI interrupt (IRQ2/9, IRQ3 or IRQ10). The SCSI interrupt
+ * is disabled by default.
+ *
+ * FIXME - make this a module option
+ *
+ * BTW the Zilog 5380 SCSI controller is located at MPU base + 0x10.
*/
{
- static unsigned char scsi_irq_bits[] =
- {0, 0, 3, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0};
-
+ static unsigned char scsi_irq_bits[] = {
+ 0, 0, 3, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0
+ };
control |= scsi_irq_bits[SMW_SCSI_IRQ] << 6;
}
#endif
#ifdef SMW_OPL4_ENABLE
/*
- * Make the OPL4 chip visible on the PC bus at 0x380.
- *
- * There is no need to enable this feature since this driver
- * doesn't support OPL4 yet. Also there is no RAM in SM Wave so
- * enabling OPL4 is pretty useless.
+ * Make the OPL4 chip visible on the PC bus at 0x380.
+ *
+ * There is no need to enable this feature since this driver
+ * doesn't support OPL4 yet. Also there is no RAM in SM Wave so
+ * enabling OPL4 is pretty useless.
*/
control |= 0x10; /* Uses IRQ12 if bit 0x20 == 0 */
/* control |= 0x20; Uncomment this if you want to use IRQ7 */
#endif
-
outb((control | 0x03), mpu_base + 7); /* xxxxxx11 restarts */
hw_config->name = "SoundMan Wave";
return 1;
}
-static int
-ess_midi_init(sb_devc * devc, struct address_info *hw_config)
+static int ess_midi_init(sb_devc * devc, struct address_info *hw_config)
{
unsigned char cfg, tmp;
cfg = sb_getmixer(devc, 0x40) & 0x03;
if (devc->submodel < 8)
- {
- sb_setmixer(devc, 0x40, cfg | 0x03); /* Enable OPL3 & joystick */
- return 0; /* ES688 doesn't support MPU401 mode */
- }
+ {
+ sb_setmixer(devc, 0x40, cfg | 0x03); /* Enable OPL3 & joystick */
+ return 0; /* ES688 doesn't support MPU401 mode */
+ }
tmp = (hw_config->io_base & 0x0f0) >> 4;
if (tmp > 3)
- {
- sb_setmixer(devc, 0x40, cfg);
- return 0;
- }
+ {
+ sb_setmixer(devc, 0x40, cfg);
+ return 0;
+ }
cfg |= tmp << 3;
tmp = 1; /* MPU enabled without interrupts */
switch (hw_config->irq)
- {
- case 9:
- tmp = 0x4;
- break;
- case 5:
- tmp = 0x5;
- break;
- case 7:
- tmp = 0x6;
- break;
- case 10:
- tmp = 0x7;
- break;
- default:
- return 0;
- }
+ {
+ case 9:
+ tmp = 0x4;
+ break;
+ case 5:
+ tmp = 0x5;
+ break;
+ case 7:
+ tmp = 0x6;
+ break;
+ case 10:
+ tmp = 0x7;
+ break;
+ default:
+ return 0;
+ }
cfg |= tmp << 5;
-
sb_setmixer(devc, 0x40, cfg | 0x03);
return 1;
}
-static int
-init_Jazz16_midi(sb_devc * devc, struct address_info *hw_config)
+static int init_Jazz16_midi(sb_devc * devc, struct address_info *hw_config)
{
- int mpu_base = hw_config->io_base;
- int sb_base = devc->base;
- int irq = hw_config->irq;
+ int mpu_base = hw_config->io_base;
+ int sb_base = devc->base;
+ int irq = hw_config->irq;
- unsigned char bits = 0;
- unsigned long flags;
+ unsigned char bits = 0;
+ unsigned long flags;
if (irq < 0)
irq *= -1;
if (irq < 1 || irq > 15 ||
jazz_irq_bits[irq] == 0)
- {
- printk("Jazz16: Invalid MIDI interrupt (IRQ%d)\n", irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "Jazz16: Invalid MIDI interrupt (IRQ%d)\n", irq);
+ return 0;
+ }
switch (sb_base)
- {
- case 0x220:
- bits = 1;
- break;
- case 0x240:
- bits = 2;
- break;
- case 0x260:
- bits = 3;
- break;
-
- default:
- return 0;
- }
-
+ {
+ case 0x220:
+ bits = 1;
+ break;
+ case 0x240:
+ bits = 2;
+ break;
+ case 0x260:
+ bits = 3;
+ break;
+ default:
+ return 0;
+ }
bits = jazz16_bits = bits << 5;
-
switch (mpu_base)
- {
- case 0x310:
- bits |= 1;
- break;
- case 0x320:
- bits |= 2;
- break;
- case 0x330:
- bits |= 3;
- break;
-
- default:
- printk("Jazz16: Invalid MIDI I/O port %x\n", mpu_base);
- return 0;
- }
-/*
- * Magic wake up sequence by writing to 0x201 (aka Joystick port)
- */
+ {
+ case 0x310:
+ bits |= 1;
+ break;
+ case 0x320:
+ bits |= 2;
+ break;
+ case 0x330:
+ bits |= 3;
+ break;
+ default:
+ printk(KERN_ERR "Jazz16: Invalid MIDI I/O port %x\n", mpu_base);
+ return 0;
+ }
+ /*
+ * Magic wake up sequence by writing to 0x201 (aka Joystick port)
+ */
save_flags(flags);
cli();
- outb((0xAF), 0x201);
- outb((0x50), 0x201);
- outb((bits), 0x201);
+ outb(0xAF, 0x201);
+ outb(0x50, 0x201);
+ outb(bits, 0x201);
restore_flags(flags);
hw_config->name = "Jazz16";
@@ -1291,19 +1246,17 @@ init_Jazz16_midi(sb_devc * devc, struct address_info *hw_config)
return 1;
}
-void
-attach_sbmpu(struct address_info *hw_config)
+void attach_sbmpu(struct address_info *hw_config)
{
#if defined(CONFIG_MIDI) && (defined(CONFIG_UART401)||defined(CONFIG_UART401_MODULE))
attach_uart401(hw_config);
#endif
}
-int
-probe_sbmpu(struct address_info *hw_config)
+int probe_sbmpu(struct address_info *hw_config)
{
#if defined(CONFIG_MIDI) && (defined(CONFIG_UART401)||defined(CONFIG_UART401_MODULE))
- sb_devc *devc = last_devc;
+ sb_devc *devc = last_devc;
if (last_devc == NULL)
return 0;
@@ -1314,53 +1267,51 @@ probe_sbmpu(struct address_info *hw_config)
return 0;
if (check_region(hw_config->io_base, 4))
- {
- printk("sbmpu: I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
+ {
+ printk(KERN_ERR "sbmpu: I/O port conflict (%x)\n", hw_config->io_base);
+ return 0;
+ }
switch (devc->model)
- {
- case MDL_SB16:
- if (hw_config->io_base != 0x300 && hw_config->io_base != 0x330)
- {
- printk("SB16: Invalid MIDI port %x\n", hw_config->irq);
- return 0;
- }
- hw_config->name = "Sound Blaster 16";
- hw_config->irq = -devc->irq;
+ {
+ case MDL_SB16:
+ if (hw_config->io_base != 0x300 && hw_config->io_base != 0x330)
+ {
+ printk(KERN_ERR "SB16: Invalid MIDI port %x\n", hw_config->irq);
+ return 0;
+ }
+ hw_config->name = "Sound Blaster 16";
+ hw_config->irq = -devc->irq;
#if defined(CONFIG_MIDI) && defined(CONFIG_UART401)
- if (devc->minor > 12) /* What is Vibra's version??? */
- sb16_set_mpu_port(devc, hw_config);
+ if (devc->minor > 12) /* What is Vibra's version??? */
+ sb16_set_mpu_port(devc, hw_config);
#endif
- break;
-
- case MDL_ESS:
- if (hw_config->irq < 3 || hw_config->irq == devc->irq)
- hw_config->irq = -devc->irq;
- if (!ess_midi_init(devc, hw_config))
- return 0;
- hw_config->name = "ESS ES1688";
- break;
-
- case MDL_JAZZ:
- if (hw_config->irq < 3 || hw_config->irq == devc->irq)
- hw_config->irq = -devc->irq;
- if (!init_Jazz16_midi(devc, hw_config))
- return 0;
- break;
-
- default:
- return 0;
- }
-
+ break;
+
+ case MDL_ESS:
+ if (hw_config->irq < 3 || hw_config->irq == devc->irq)
+ hw_config->irq = -devc->irq;
+ if (!ess_midi_init(devc, hw_config))
+ return 0;
+ hw_config->name = "ESS ES1688";
+ break;
+
+ case MDL_JAZZ:
+ if (hw_config->irq < 3 || hw_config->irq == devc->irq)
+ hw_config->irq = -devc->irq;
+ if (!init_Jazz16_midi(devc, hw_config))
+ return 0;
+ break;
+
+ default:
+ return 0;
+ }
return probe_uart401(hw_config);
#else
return 0;
#endif
}
-void
-unload_sbmpu(struct address_info *hw_config)
+void unload_sbmpu(struct address_info *hw_config)
{
#if defined(CONFIG_MIDI) && (defined(CONFIG_UART401)||defined(CONFIG_UART401_MODULE))
unload_uart401(hw_config);
@@ -1368,22 +1319,18 @@ unload_sbmpu(struct address_info *hw_config)
}
#else /* !CONFIG_MIDI */
-void
-unload_sbmpu(struct address_info *hw_config)
+void unload_sbmpu(struct address_info *hw_config)
{
}
-int
-probe_sbmpu(struct address_info *hw_config)
+int probe_sbmpu(struct address_info *hw_config)
{
return 0;
}
-void
-attach_sbmpu(struct address_info *hw_config)
+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 06acc19ef..b08f8d43f 100644
--- a/drivers/sound/sb_midi.c
+++ b/drivers/sound/sb_midi.c
@@ -128,10 +128,10 @@ sb_midi_end_read(int dev)
return 0;
}
-static int
-sb_midi_ioctl(int dev, unsigned cmd, caddr_t arg)
+/* why -EPERM and not -EINVAL?? */
+static int sb_midi_ioctl(int dev, unsigned cmd, caddr_t arg)
{
- return -EPERM;
+ return -EPERM;
}
void
diff --git a/drivers/sound/sb_mixer.c b/drivers/sound/sb_mixer.c
index 6a7070e28..2d494a0dd 100644
--- a/drivers/sound/sb_mixer.c
+++ b/drivers/sound/sb_mixer.c
@@ -11,6 +11,9 @@
* 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>
@@ -281,68 +284,61 @@ set_recmask(sb_devc * devc, int mask)
return devc->recmask;
}
-static int
-sb_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+static int sb_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- sb_devc *devc = mixer_devs[dev]->devc;
- int val;
-
-/*
- * Use ioctl(fd, SOUND_MIXER_PRIVATE1, &mode) to turn AGC off (0) or on (1).
- */
- if (cmd == SOUND_MIXER_PRIVATE1 && devc->model == MDL_SB16)
- {
- int tmp;
-
- tmp = *(int *) arg;
-
- sb_setmixer(devc, 0x43, (~tmp) & 0x01);
- return 0;
- }
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- val = *(int *) arg;
- return (*(int *) arg = set_recmask(devc, val));
- break;
-
- default:
-
- val = *(int *) arg;
- return (*(int *) arg = sb_mixer_set(devc, cmd & 0xff, val));
+ sb_devc *devc = mixer_devs[dev]->devc;
+ int val, ret;
+
+ /*
+ * 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 (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 (get_user(val, (int *)arg))
+ return -EFAULT;
+ 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:
- return (*(int *) arg = devc->recmask);
- break;
-
- case SOUND_MIXER_DEVMASK:
- return (*(int *) arg = devc->supported_devices);
- break;
-
- case SOUND_MIXER_STEREODEVS:
- if (devc->model == MDL_JAZZ || devc->model == MDL_SMW)
- return (*(int *) arg = devc->supported_devices);
- else
- return (*(int *) arg = devc->supported_devices & ~(SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_IMIX));
- break;
-
- case SOUND_MIXER_RECMASK:
- return (*(int *) arg = devc->supported_rec_devices);
- break;
-
- case SOUND_MIXER_CAPS:
- return (*(int *) arg = devc->mixer_caps);
- break;
-
- default:
- return (*(int *) arg = sb_mixer_get(devc, cmd & 0xff));
- }
+ switch (cmd & 0xff) {
+ case SOUND_MIXER_RECSRC:
+ ret = devc->recmask;
+ 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_RECMASK:
+ ret = devc->supported_rec_devices;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ ret = devc->mixer_caps;
+ break;
+
+ default:
+ ret = sb_mixer_get(devc, cmd & 0xff);
+ break;
+ }
+ return put_user(ret, (int *)arg);
} else
return -EINVAL;
}
diff --git a/drivers/sound/sb_mixer.h b/drivers/sound/sb_mixer.h
index d83c2dbad..2f68a62f3 100644
--- a/drivers/sound/sb_mixer.h
+++ b/drivers/sound/sb_mixer.h
@@ -17,6 +17,8 @@
* Added defines for the Sound Galaxy NX Pro mixer.
*
*/
+#include <linux/config.h>
+
#ifdef CONFIG_SBDSP
#define SBPRO_RECORDING_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD)
@@ -134,7 +136,8 @@ MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
};
#ifdef __SGNXPRO__
-static mixer_tab sgnxpro_mix = {
+#if 0
+static mixer_tab sgnxpro_mix = { /* not used anywhere */
MIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
MIX_ENT(SOUND_MIXER_BASS, 0x46, 2, 3, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_TREBLE, 0x44, 2, 3, 0x00, 0, 0),
@@ -151,6 +154,7 @@ MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0)
};
#endif
+#endif
static mixer_tab sb16_mix = {
MIX_ENT(SOUND_MIXER_VOLUME, 0x30, 7, 5, 0x31, 7, 5),
diff --git a/drivers/sound/sequencer.c b/drivers/sound/sequencer.c
index fe18beea9..22d30569f 100644
--- a/drivers/sound/sequencer.c
+++ b/drivers/sound/sequencer.c
@@ -10,6 +10,10 @@
* 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 : reformatted and fixed a pair of null pointer bugs
+ */
#include <linux/config.h>
@@ -48,16 +52,15 @@ static int max_synthdev = 0;
static int seq_mode = SEQ_1;
static struct wait_queue *seq_sleeper = NULL;
-static volatile struct snd_wait seq_sleep_flag =
-{0};
static struct wait_queue *midi_sleeper = NULL;
-static volatile struct snd_wait midi_sleep_flag =
-{0};
-static int midi_opened[MAX_MIDI_DEV] =
-{0};
-static int midi_written[MAX_MIDI_DEV] =
-{0};
+static int midi_opened[MAX_MIDI_DEV] = {
+ 0
+};
+
+static int midi_written[MAX_MIDI_DEV] = {
+ 0
+};
static unsigned long prev_input_time = 0;
static int prev_event_time;
@@ -66,6 +69,7 @@ static int prev_event_time;
#define EV_SZ 8
#define IEV_SZ 8
+
static unsigned char *queue = NULL;
static unsigned char *iqueue = NULL;
@@ -86,12 +90,11 @@ static void seq_reset(void);
#error Too many synthesizer devices enabled.
#endif
-int
-sequencer_read(int dev, struct fileinfo *file, char *buf, int count)
+int sequencer_read(int dev, struct file *file, char *buf, int count)
{
- int c = count, p = 0;
- int ev_len;
- unsigned long flags;
+ int c = count, p = 0;
+ int ev_len;
+ unsigned long flags;
dev = dev >> 4;
@@ -99,71 +102,49 @@ sequencer_read(int dev, struct fileinfo *file, char *buf, int count)
save_flags(flags);
cli();
+
if (!iqlen)
- {
- if ((file->flags & (O_NONBLOCK) ?
- 1 : 0))
- {
- restore_flags(flags);
- return -EAGAIN;
- }
- {
- unsigned long tlimit;
-
- if (pre_event_timeout)
- current->timeout = tlimit = jiffies + (pre_event_timeout);
- else
- tlimit = (unsigned long) -1;
- midi_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&midi_sleeper);
- if (!(midi_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- midi_sleep_flag.opts |= WK_TIMEOUT;
- }
- midi_sleep_flag.opts &= ~WK_SLEEP;
- };
-
- if (!iqlen)
- {
- restore_flags(flags);
- return 0;
- }
- }
+ {
+ if (file->f_flags & O_NONBLOCK) {
+ restore_flags(flags);
+ return -EAGAIN;
+ }
+ current->timeout = pre_event_timeout ? jiffies + pre_event_timeout : 0;
+ interruptible_sleep_on(&midi_sleeper);
+ current->timeout = 0;
+ if (!iqlen)
+ {
+ restore_flags(flags);
+ return 0;
+ }
+ }
while (iqlen && c >= ev_len)
- {
-
- {
- char *fixit = (char *) &iqueue[iqhead * IEV_SZ];
-
- copy_to_user(&(buf)[p], fixit, ev_len);
- };
- p += ev_len;
- c -= ev_len;
-
- iqhead = (iqhead + 1) % SEQ_MAX_QUEUE;
- iqlen--;
- }
+ {
+ char *fixit = (char *) &iqueue[iqhead * IEV_SZ];
+ copy_to_user(&(buf)[p], fixit, ev_len);
+ p += ev_len;
+ c -= ev_len;
+
+ iqhead = (iqhead + 1) % SEQ_MAX_QUEUE;
+ iqlen--;
+ }
restore_flags(flags);
-
return count - c;
}
-static void
-sequencer_midi_output(int dev)
+static void sequencer_midi_output(int dev)
{
/*
* Currently NOP
*/
}
-void
-seq_copy_to_input(unsigned char *event_rec, int len)
+void seq_copy_to_input(unsigned char *event_rec, int len)
{
- unsigned long flags;
+ unsigned long flags;
/*
- * Verify that the len is valid for the current mode.
+ * Verify that the len is valid for the current mode.
*/
if (len != 4 && len != 8)
@@ -179,22 +160,14 @@ seq_copy_to_input(unsigned char *event_rec, int len)
memcpy(&iqueue[iqtail * IEV_SZ], event_rec, len);
iqlen++;
iqtail = (iqtail + 1) % SEQ_MAX_QUEUE;
-
- if ((midi_sleep_flag.opts & WK_SLEEP))
- {
- {
- midi_sleep_flag.opts = WK_WAKEUP;
- wake_up(&midi_sleeper);
- };
- }
+ wake_up(&midi_sleeper);
restore_flags(flags);
}
-static void
-sequencer_midi_input(int dev, unsigned char data)
+static void sequencer_midi_input(int dev, unsigned char data)
{
- unsigned int tstamp;
- unsigned char event_rec[4];
+ unsigned int tstamp;
+ unsigned char event_rec[4];
if (data == 0xfe) /* Ignore active sensing */
return;
@@ -205,12 +178,11 @@ sequencer_midi_input(int dev, unsigned char data)
tstamp = jiffies - seq_time;
if (tstamp != prev_input_time)
- {
- tstamp = (tstamp << 8) | SEQ_WAIT;
-
- seq_copy_to_input((unsigned char *) &tstamp, 4);
- prev_input_time = tstamp;
- }
+ {
+ tstamp = (tstamp << 8) | SEQ_WAIT;
+ seq_copy_to_input((unsigned char *) &tstamp, 4);
+ prev_input_time = tstamp;
+ }
event_rec[0] = SEQ_MIDIPUTC;
event_rec[1] = data;
event_rec[2] = dev;
@@ -219,10 +191,9 @@ sequencer_midi_input(int dev, unsigned char data)
seq_copy_to_input(event_rec, 4);
}
-void
-seq_input_event(unsigned char *event_rec, int len)
+void seq_input_event(unsigned char *event_rec, int len)
{
- unsigned long this_time;
+ unsigned long this_time;
if (seq_mode == SEQ_2)
this_time = tmr->get_time(tmr_no);
@@ -232,28 +203,27 @@ seq_input_event(unsigned char *event_rec, int len)
this_time = jiffies - seq_time;
if (this_time != prev_input_time)
- {
- unsigned char tmp_event[8];
-
- tmp_event[0] = EV_TIMING;
- tmp_event[1] = TMR_WAIT_ABS;
- tmp_event[2] = 0;
- tmp_event[3] = 0;
- *(unsigned int *) &tmp_event[4] = this_time;
-
- seq_copy_to_input(tmp_event, 8);
- prev_input_time = this_time;
- }
+ {
+ unsigned char tmp_event[8];
+
+ tmp_event[0] = EV_TIMING;
+ tmp_event[1] = TMR_WAIT_ABS;
+ tmp_event[2] = 0;
+ tmp_event[3] = 0;
+ *(unsigned int *) &tmp_event[4] = this_time;
+
+ seq_copy_to_input(tmp_event, 8);
+ prev_input_time = this_time;
+ }
seq_copy_to_input(event_rec, len);
}
-int
-sequencer_write(int dev, struct fileinfo *file, const char *buf, int count)
+int sequencer_write(int dev, struct file *file, const char *buf, int count)
{
- unsigned char event_rec[EV_SZ], ev_code;
- int p = 0, c, ev_size;
- int err;
- int mode = file->mode & O_ACCMODE;
+ unsigned char event_rec[EV_SZ], ev_code;
+ int p = 0, c, ev_size;
+ int err;
+ int mode = translate_mode(file);
dev = dev >> 4;
@@ -265,100 +235,98 @@ sequencer_write(int dev, struct fileinfo *file, const char *buf, int count)
c = count;
while (c >= 4)
- {
- copy_from_user((char *) event_rec, &(buf)[p], 4);
- ev_code = event_rec[0];
-
- if (ev_code == SEQ_FULLSIZE)
- {
- int err, fmt;
-
- dev = *(unsigned short *) &event_rec[2];
- if (dev < 0 || dev >= max_synthdev || synth_devs[dev] == NULL)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)))
- return -ENXIO;
-
- fmt = (*(short *) &event_rec[0]) & 0xffff;
- err = synth_devs[dev]->load_patch(dev, fmt, buf, p + 4, c, 0);
- if (err < 0)
- return err;
-
- return err;
- }
- if (ev_code >= 128)
- {
- if (seq_mode == SEQ_2 && ev_code == SEQ_EXTENDED)
- {
- printk("Sequencer: Invalid level 2 event %x\n", ev_code);
- return -EINVAL;
- }
- ev_size = 8;
-
- if (c < ev_size)
- {
- if (!seq_playing)
- seq_startplay();
- return count - c;
- }
- copy_from_user((char *) &event_rec[4], &(buf)[p + 4], 4);
-
- } else
- {
- if (seq_mode == SEQ_2)
- {
- printk("Sequencer: 4 byte event in level 2 mode\n");
- return -EINVAL;
- }
- ev_size = 4;
-
- if (event_rec[0] != SEQ_MIDIPUTC)
- obsolete_api_used = 1;
- }
-
- if (event_rec[0] == SEQ_MIDIPUTC)
- {
-
- if (!midi_opened[event_rec[2]])
- {
- int mode;
- int dev = event_rec[2];
-
- if (dev >= max_mididev)
- {
- printk("Sequencer Error: Nonexistent MIDI device %d\n", dev);
- return -ENXIO;
- }
- mode = file->mode & O_ACCMODE;
-
- if ((err = midi_devs[dev]->open(dev, mode,
- sequencer_midi_input, sequencer_midi_output)) < 0)
- {
- seq_reset();
- printk("Sequencer Error: Unable to open Midi #%d\n", dev);
- return err;
- }
- midi_opened[dev] = 1;
- }
- }
- if (!seq_queue(event_rec, (file->flags & (O_NONBLOCK) ?
- 1 : 0)))
- {
- int processed = count - c;
-
- if (!seq_playing)
- seq_startplay();
-
- if (!processed && (file->flags & (O_NONBLOCK) ?
- 1 : 0))
- return -EAGAIN;
- else
- return processed;
- }
- p += ev_size;
- c -= ev_size;
- }
+ {
+ copy_from_user((char *) event_rec, &(buf)[p], 4);
+ ev_code = event_rec[0];
+
+ if (ev_code == SEQ_FULLSIZE)
+ {
+ int err, fmt;
+
+ dev = *(unsigned short *) &event_rec[2];
+ if (dev < 0 || dev >= max_synthdev || synth_devs[dev] == NULL)
+ return -ENXIO;
+
+ if (!(synth_open_mask & (1 << dev)))
+ return -ENXIO;
+
+ fmt = (*(short *) &event_rec[0]) & 0xffff;
+ err = synth_devs[dev]->load_patch(dev, fmt, buf, p + 4, c, 0);
+ if (err < 0)
+ return err;
+
+ return err;
+ }
+ if (ev_code >= 128)
+ {
+ if (seq_mode == SEQ_2 && ev_code == SEQ_EXTENDED)
+ {
+ printk(KERN_WARNING "Sequencer: Invalid level 2 event %x\n", ev_code);
+ return -EINVAL;
+ }
+ ev_size = 8;
+
+ if (c < ev_size)
+ {
+ if (!seq_playing)
+ seq_startplay();
+ return count - c;
+ }
+ copy_from_user((char *) &event_rec[4], &(buf)[p + 4], 4);
+
+ }
+ else
+ {
+ if (seq_mode == SEQ_2)
+ {
+ printk(KERN_WARNING "Sequencer: 4 byte event in level 2 mode\n");
+ return -EINVAL;
+ }
+ ev_size = 4;
+
+ if (event_rec[0] != SEQ_MIDIPUTC)
+ obsolete_api_used = 1;
+ }
+
+ if (event_rec[0] == SEQ_MIDIPUTC)
+ {
+ if (!midi_opened[event_rec[2]])
+ {
+ int mode;
+ int dev = event_rec[2];
+
+ if (dev >= max_mididev || midi_devs[dev]==NULL)
+ {
+ /*printk("Sequencer Error: Nonexistent MIDI device %d\n", dev);*/
+ return -ENXIO;
+ }
+ mode = translate_mode(file);
+
+ if ((err = midi_devs[dev]->open(dev, mode,
+ sequencer_midi_input, sequencer_midi_output)) < 0)
+ {
+ seq_reset();
+ printk(KERN_WARNING "Sequencer Error: Unable to open Midi #%d\n", dev);
+ return err;
+ }
+ midi_opened[dev] = 1;
+ }
+ }
+ if (!seq_queue(event_rec, (file->f_flags & (O_NONBLOCK) ? 1 : 0)))
+ {
+ int processed = count - c;
+
+ if (!seq_playing)
+ seq_startplay();
+
+ if (!processed && (file->f_flags & O_NONBLOCK))
+ return -EAGAIN;
+ else
+ return processed;
+ }
+ p += ev_size;
+ c -= ev_size;
+ }
if (!seq_playing)
seq_startplay();
@@ -366,8 +334,7 @@ sequencer_write(int dev, struct fileinfo *file, const char *buf, int count)
return count;
}
-static int
-seq_queue(unsigned char *note, char nonblock)
+static int seq_queue(unsigned char *note, char nonblock)
{
/*
@@ -380,22 +347,19 @@ seq_queue(unsigned char *note, char nonblock)
* Give chance to drain the queue
*/
- if (!nonblock && qlen >= SEQ_MAX_QUEUE && !(seq_sleep_flag.opts & WK_SLEEP))
- {
- /*
- * Sleep until there is enough space on the queue
- */
-
- seq_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&seq_sleeper);
- seq_sleep_flag.opts &= ~WK_SLEEP;;
- }
+ if (!nonblock && qlen >= SEQ_MAX_QUEUE && !waitqueue_active(&seq_sleeper)) {
+ /*
+ * Sleep until there is enough space on the queue
+ */
+ current->timeout = 0;
+ interruptible_sleep_on(&seq_sleeper);
+ }
if (qlen >= SEQ_MAX_QUEUE)
- {
- return 0; /*
+ {
+ return 0; /*
* To be sure
*/
- }
+ }
memcpy(&queue[qtail * EV_SZ], note, EV_SZ);
qtail = (qtail + 1) % SEQ_MAX_QUEUE;
@@ -404,10 +368,9 @@ seq_queue(unsigned char *note, char nonblock)
return 1;
}
-static int
-extended_event(unsigned char *q)
+static int extended_event(unsigned char *q)
{
- int dev = q[2];
+ int dev = q[2];
if (dev < 0 || dev >= max_synthdev)
return -ENXIO;
@@ -416,71 +379,66 @@ extended_event(unsigned char *q)
return -ENXIO;
switch (q[1])
- {
- case SEQ_NOTEOFF:
- synth_devs[dev]->kill_note(dev, q[3], q[4], q[5]);
- break;
-
- case SEQ_NOTEON:
- if (q[4] > 127 && q[4] != 255)
- return 0;
-
- if (q[5] == 0)
- {
- synth_devs[dev]->kill_note(dev, q[3], q[4], q[5]);
- break;
- }
- synth_devs[dev]->start_note(dev, q[3], q[4], q[5]);
- break;
-
- case SEQ_PGMCHANGE:
- synth_devs[dev]->set_instr(dev, q[3], q[4]);
- break;
-
- case SEQ_AFTERTOUCH:
- synth_devs[dev]->aftertouch(dev, q[3], q[4]);
- break;
-
- case SEQ_BALANCE:
- synth_devs[dev]->panning(dev, q[3], (char) q[4]);
- break;
-
- case SEQ_CONTROLLER:
- synth_devs[dev]->controller(dev, q[3], q[4], (short) (q[5] | (q[6] << 8)));
- break;
-
- case SEQ_VOLMODE:
- if (synth_devs[dev]->volume_method != NULL)
- synth_devs[dev]->volume_method(dev, q[3]);
- break;
-
- default:
- return -EINVAL;
- }
-
+ {
+ case SEQ_NOTEOFF:
+ synth_devs[dev]->kill_note(dev, q[3], q[4], q[5]);
+ break;
+
+ case SEQ_NOTEON:
+ if (q[4] > 127 && q[4] != 255)
+ return 0;
+
+ if (q[5] == 0)
+ {
+ synth_devs[dev]->kill_note(dev, q[3], q[4], q[5]);
+ break;
+ }
+ synth_devs[dev]->start_note(dev, q[3], q[4], q[5]);
+ break;
+
+ case SEQ_PGMCHANGE:
+ synth_devs[dev]->set_instr(dev, q[3], q[4]);
+ break;
+
+ case SEQ_AFTERTOUCH:
+ synth_devs[dev]->aftertouch(dev, q[3], q[4]);
+ break;
+
+ case SEQ_BALANCE:
+ synth_devs[dev]->panning(dev, q[3], (char) q[4]);
+ break;
+
+ case SEQ_CONTROLLER:
+ synth_devs[dev]->controller(dev, q[3], q[4], (short) (q[5] | (q[6] << 8)));
+ break;
+
+ case SEQ_VOLMODE:
+ if (synth_devs[dev]->volume_method != NULL)
+ synth_devs[dev]->volume_method(dev, q[3]);
+ break;
+
+ default:
+ return -EINVAL;
+ }
return 0;
}
-static int
-find_voice(int dev, int chn, int note)
+static int find_voice(int dev, int chn, int note)
{
- unsigned short key;
- int i;
+ unsigned short key;
+ int i;
key = (chn << 8) | (note + 1);
-
for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
if (synth_devs[dev]->alloc.map[i] == key)
return i;
-
return -1;
}
-static int
-alloc_voice(int dev, int chn, int note)
+static int alloc_voice(int dev, int chn, int note)
{
unsigned short key;
- int voice;
+ int voice;
key = (chn << 8) | (note + 1);
@@ -488,12 +446,11 @@ alloc_voice(int dev, int chn, int note)
&synth_devs[dev]->alloc);
synth_devs[dev]->alloc.map[voice] = key;
synth_devs[dev]->alloc.alloc_times[voice] =
- synth_devs[dev]->alloc.timestamp++;
+ synth_devs[dev]->alloc.timestamp++;
return voice;
}
-static void
-seq_chn_voice_event(unsigned char *event_rec)
+static void seq_chn_voice_event(unsigned char *event_rec)
{
#define dev event_rec[1]
#define cmd event_rec[2]
@@ -501,7 +458,7 @@ seq_chn_voice_event(unsigned char *event_rec)
#define note event_rec[4]
#define parm event_rec[5]
- int voice = -1;
+ int voice = -1;
if ((int) dev > max_synthdev || synth_devs[dev] == NULL)
return;
@@ -511,60 +468,62 @@ seq_chn_voice_event(unsigned char *event_rec)
return;
if (seq_mode == SEQ_2)
- {
- if (synth_devs[dev]->alloc_voice)
- voice = find_voice(dev, chn, note);
-
- if (cmd == MIDI_NOTEON && parm == 0)
- {
- cmd = MIDI_NOTEOFF;
- parm = 64;
- }
- }
+ {
+ if (synth_devs[dev]->alloc_voice)
+ voice = find_voice(dev, chn, note);
+
+ if (cmd == MIDI_NOTEON && parm == 0)
+ {
+ cmd = MIDI_NOTEOFF;
+ parm = 64;
+ }
+ }
+
switch (cmd)
- {
- case MIDI_NOTEON:
- if (note > 127 && note != 255) /* Not a seq2 feature */
- return;
-
- if (voice == -1 && seq_mode == SEQ_2 && synth_devs[dev]->alloc_voice)
- { /* Internal synthesizer (FM, GUS, etc) */
- voice = alloc_voice(dev, chn, note);
- }
- if (voice == -1)
- voice = chn;
-
- if (seq_mode == SEQ_2 && (int) dev < num_synths)
- {
- /*
- * The MIDI channel 10 is a percussive channel. Use the note
- * number to select the proper patch (128 to 255) to play.
- */
-
- if (chn == 9)
- {
- synth_devs[dev]->set_instr(dev, voice, 128 + note);
- synth_devs[dev]->chn_info[chn].pgm_num = 128 + note;
- }
- synth_devs[dev]->setup_voice(dev, voice, chn);
- }
- synth_devs[dev]->start_note(dev, voice, note, parm);
- break;
-
- case MIDI_NOTEOFF:
- if (voice == -1)
- voice = chn;
- synth_devs[dev]->kill_note(dev, voice, note, parm);
- break;
-
- case MIDI_KEY_PRESSURE:
- if (voice == -1)
- voice = chn;
- synth_devs[dev]->aftertouch(dev, voice, parm);
- break;
-
- default:;
- }
+ {
+ case MIDI_NOTEON:
+ if (note > 127 && note != 255) /* Not a seq2 feature */
+ return;
+
+ if (voice == -1 && seq_mode == SEQ_2 && synth_devs[dev]->alloc_voice)
+ {
+ /* Internal synthesizer (FM, GUS, etc) */
+ voice = alloc_voice(dev, chn, note);
+ }
+ if (voice == -1)
+ voice = chn;
+
+ if (seq_mode == SEQ_2 && (int) dev < num_synths)
+ {
+ /*
+ * The MIDI channel 10 is a percussive channel. Use the note
+ * number to select the proper patch (128 to 255) to play.
+ */
+
+ if (chn == 9)
+ {
+ synth_devs[dev]->set_instr(dev, voice, 128 + note);
+ synth_devs[dev]->chn_info[chn].pgm_num = 128 + note;
+ }
+ synth_devs[dev]->setup_voice(dev, voice, chn);
+ }
+ synth_devs[dev]->start_note(dev, voice, note, parm);
+ break;
+
+ case MIDI_NOTEOFF:
+ if (voice == -1)
+ voice = chn;
+ synth_devs[dev]->kill_note(dev, voice, note, parm);
+ break;
+
+ case MIDI_KEY_PRESSURE:
+ if (voice == -1)
+ voice = chn;
+ synth_devs[dev]->aftertouch(dev, voice, parm);
+ break;
+
+ default:
+ }
#undef dev
#undef cmd
#undef chn
@@ -573,16 +532,15 @@ seq_chn_voice_event(unsigned char *event_rec)
}
-static void
-seq_chn_common_event(unsigned char *event_rec)
+static void seq_chn_common_event(unsigned char *event_rec)
{
- unsigned char dev = event_rec[1];
- unsigned char cmd = event_rec[2];
- unsigned char chn = event_rec[3];
- unsigned char p1 = event_rec[4];
+ unsigned char dev = event_rec[1];
+ unsigned char cmd = event_rec[2];
+ unsigned char chn = event_rec[3];
+ unsigned char p1 = event_rec[4];
- /* unsigned char p2 = event_rec[5]; */
- unsigned short w14 = *(short *) &event_rec[6];
+ /* unsigned char p2 = event_rec[5]; */
+ unsigned short w14 = *(short *) &event_rec[6];
if ((int) dev > max_synthdev || synth_devs[dev] == NULL)
return;
@@ -592,211 +550,187 @@ seq_chn_common_event(unsigned char *event_rec)
return;
switch (cmd)
- {
- case MIDI_PGM_CHANGE:
- if (seq_mode == SEQ_2)
- {
- synth_devs[dev]->chn_info[chn].pgm_num = p1;
- if ((int) dev >= num_synths)
- synth_devs[dev]->set_instr(dev, chn, p1);
- } else
- synth_devs[dev]->set_instr(dev, chn, p1);
-
- break;
-
- case MIDI_CTL_CHANGE:
- if (seq_mode == SEQ_2)
- {
- if (chn > 15 || p1 > 127)
- break;
-
- synth_devs[dev]->chn_info[chn].controllers[p1] = w14 & 0x7f;
-
- if (p1 < 32) /* Setting MSB should clear LSB to 0 */
- synth_devs[dev]->chn_info[chn].controllers[p1 + 32] = 0;
-
- if ((int) dev < num_synths)
- {
- int val = w14 & 0x7f;
- int i, key;
-
- if (p1 < 64) /* Combine MSB and LSB */
+ {
+ case MIDI_PGM_CHANGE:
+ if (seq_mode == SEQ_2)
+ {
+ synth_devs[dev]->chn_info[chn].pgm_num = p1;
+ if ((int) dev >= num_synths)
+ synth_devs[dev]->set_instr(dev, chn, p1);
+ }
+ else
+ synth_devs[dev]->set_instr(dev, chn, p1);
+
+ break;
+
+ case MIDI_CTL_CHANGE:
+ if (seq_mode == SEQ_2)
+ {
+ if (chn > 15 || p1 > 127)
+ break;
+
+ synth_devs[dev]->chn_info[chn].controllers[p1] = w14 & 0x7f;
+
+ if (p1 < 32) /* Setting MSB should clear LSB to 0 */
+ synth_devs[dev]->chn_info[chn].controllers[p1 + 32] = 0;
+
+ if ((int) dev < num_synths)
+ {
+ int val = w14 & 0x7f;
+ int i, key;
+
+ if (p1 < 64) /* Combine MSB and LSB */
{
val = ((synth_devs[dev]->
chn_info[chn].controllers[p1 & ~32] & 0x7f) << 7)
- | (synth_devs[dev]->
- chn_info[chn].controllers[p1 | 32] & 0x7f);
+ | (synth_devs[dev]->
+ chn_info[chn].controllers[p1 | 32] & 0x7f);
p1 &= ~32;
}
- /* Handle all playing notes on this channel */
-
- key = ((int) chn << 8);
-
- for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
- if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)
- synth_devs[dev]->controller(dev, i, p1, val);
- } else
- synth_devs[dev]->controller(dev, chn, p1, w14);
- } else /* Mode 1 */
- synth_devs[dev]->controller(dev, chn, p1, w14);
- break;
-
- case MIDI_PITCH_BEND:
- if (seq_mode == SEQ_2)
- {
- synth_devs[dev]->chn_info[chn].bender_value = w14;
-
- if ((int) dev < num_synths)
- { /* Handle all playing notes on this channel */
- int i, key;
-
- key = (chn << 8);
-
- for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
- if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)
- synth_devs[dev]->bender(dev, i, w14);
- } else
- synth_devs[dev]->bender(dev, chn, w14);
- } else /* MODE 1 */
- synth_devs[dev]->bender(dev, chn, w14);
- break;
-
- default:;
- }
+ /* Handle all playing notes on this channel */
+
+ key = ((int) chn << 8);
+
+ for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
+ if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)
+ synth_devs[dev]->controller(dev, i, p1, val);
+ }
+ else
+ synth_devs[dev]->controller(dev, chn, p1, w14);
+ }
+ else /* Mode 1 */
+ synth_devs[dev]->controller(dev, chn, p1, w14);
+ break;
+
+ case MIDI_PITCH_BEND:
+ if (seq_mode == SEQ_2)
+ {
+ synth_devs[dev]->chn_info[chn].bender_value = w14;
+
+ if ((int) dev < num_synths)
+ {
+ /* Handle all playing notes on this channel */
+ int i, key;
+
+ key = (chn << 8);
+
+ for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
+ if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)
+ synth_devs[dev]->bender(dev, i, w14);
+ }
+ else
+ synth_devs[dev]->bender(dev, chn, w14);
+ }
+ else /* MODE 1 */
+ synth_devs[dev]->bender(dev, chn, w14);
+ break;
+
+ default:
+ }
}
-static int
-seq_timing_event(unsigned char *event_rec)
+static int seq_timing_event(unsigned char *event_rec)
{
- unsigned char cmd = event_rec[1];
- unsigned int parm = *(int *) &event_rec[4];
+ unsigned char cmd = event_rec[1];
+ unsigned int parm = *(int *) &event_rec[4];
if (seq_mode == SEQ_2)
- {
- int ret;
-
- if ((ret = tmr->event(tmr_no, event_rec)) == TIMER_ARMED)
- {
- if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
- {
- unsigned long flags;
-
- save_flags(flags);
- cli();
- if ((seq_sleep_flag.opts & WK_SLEEP))
- {
- {
- seq_sleep_flag.opts = WK_WAKEUP;
- wake_up(&seq_sleeper);
- };
- }
- restore_flags(flags);
- }
- }
- return ret;
- }
+ {
+ int ret;
+
+ if ((ret = tmr->event(tmr_no, event_rec)) == TIMER_ARMED)
+ if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
+ wake_up(&seq_sleeper);
+ return ret;
+ }
switch (cmd)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
-
- /*
- * NOTE! No break here. Execution of TMR_WAIT_REL continues in the
- * next case (TMR_WAIT_ABS)
- */
-
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- time = parm;
- prev_event_time = time;
-
- seq_playing = 1;
- if (softsynthp != NULL)
- softsynthp(SSYN_REQUEST, time, 0, 0);
- else
- request_sound_timer(time);
-
- if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
- {
- unsigned long flags;
-
- save_flags(flags);
- cli();
- if ((seq_sleep_flag.opts & WK_SLEEP))
- {
- {
- seq_sleep_flag.opts = WK_WAKEUP;
- wake_up(&seq_sleeper);
- };
- }
- restore_flags(flags);
- }
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- if (softsynthp != NULL)
- {
- softsynthp(SSYN_START, 0, 0, 0);
- seq_time = 0;
- } else
- seq_time = jiffies;
- prev_input_time = 0;
- prev_event_time = 0;
- break;
-
- case TMR_STOP:
- break;
-
- case TMR_CONTINUE:
- break;
-
- case TMR_TEMPO:
- break;
-
- case TMR_ECHO:
- if (seq_mode == SEQ_2)
- seq_copy_to_input(event_rec, 8);
- else
- {
- parm = (parm << 8 | SEQ_ECHO);
- seq_copy_to_input((unsigned char *) &parm, 4);
- }
- break;
-
- default:;
- }
+ {
+ case TMR_WAIT_REL:
+ parm += prev_event_time;
+
+ /*
+ * NOTE! No break here. Execution of TMR_WAIT_REL continues in the
+ * next case (TMR_WAIT_ABS)
+ */
+
+ case TMR_WAIT_ABS:
+ if (parm > 0)
+ {
+ long time;
+
+ time = parm;
+ prev_event_time = time;
+
+ seq_playing = 1;
+ if (softsynthp != NULL)
+ softsynthp(SSYN_REQUEST, time, 0, 0);
+ else
+ request_sound_timer(time);
+
+ if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
+ wake_up(&seq_sleeper);
+ return TIMER_ARMED;
+ }
+ break;
+
+ case TMR_START:
+ if (softsynthp != NULL)
+ {
+ softsynthp(SSYN_START, 0, 0, 0);
+ seq_time = 0;
+ }
+ else
+ seq_time = jiffies;
+ prev_input_time = 0;
+ prev_event_time = 0;
+ break;
+
+ case TMR_STOP:
+ break;
+
+ case TMR_CONTINUE:
+ break;
+
+ case TMR_TEMPO:
+ break;
+
+ case TMR_ECHO:
+ if (seq_mode == SEQ_2)
+ seq_copy_to_input(event_rec, 8);
+ else
+ {
+ parm = (parm << 8 | SEQ_ECHO);
+ seq_copy_to_input((unsigned char *) &parm, 4);
+ }
+ break;
+
+ default:
+ }
return TIMER_NOT_ARMED;
}
-static void
-seq_local_event(unsigned char *event_rec)
+static void seq_local_event(unsigned char *event_rec)
{
unsigned char cmd = event_rec[1];
unsigned int parm = *((unsigned int *) &event_rec[4]);
switch (cmd)
- {
- case LOCL_STARTAUDIO:
+ {
+ case LOCL_STARTAUDIO:
#ifdef CONFIG_AUDIO
- DMAbuf_start_devices(parm);
+ DMAbuf_start_devices(parm);
#endif
- break;
+ break;
- default:;
- }
+ default:
+ }
}
-static void
-seq_sysex_message(unsigned char *event_rec)
+static void seq_sysex_message(unsigned char *event_rec)
{
- int dev = event_rec[1];
- int i, l = 0;
+ int dev = event_rec[1];
+ int i, l = 0;
unsigned char *buf = &event_rec[2];
if ((int) dev > max_synthdev)
@@ -816,265 +750,232 @@ seq_sysex_message(unsigned char *event_rec)
synth_devs[dev]->send_sysex(dev, buf, l);
}
-static int
-play_event(unsigned char *q)
+static int play_event(unsigned char *q)
{
/*
- * NOTE! This routine returns
- * 0 = normal event played.
- * 1 = Timer armed. Suspend playback until timer callback.
- * 2 = MIDI output buffer full. Restore queue and suspend until timer
+ * NOTE! This routine returns
+ * 0 = normal event played.
+ * 1 = Timer armed. Suspend playback until timer callback.
+ * 2 = MIDI output buffer full. Restore queue and suspend until timer
*/
- unsigned int *delay;
+ unsigned int *delay;
switch (q[0])
- {
- case SEQ_NOTEOFF:
- if (synth_open_mask & (1 << 0))
- if (synth_devs[0])
- synth_devs[0]->kill_note(0, q[1], 255, q[3]);
- break;
-
- case SEQ_NOTEON:
- if (q[4] < 128 || q[4] == 255)
- if (synth_open_mask & (1 << 0))
- if (synth_devs[0])
- synth_devs[0]->start_note(0, q[1], q[2], q[3]);
- break;
-
- case SEQ_WAIT:
- delay = (unsigned int *) q; /*
- * Bytes 1 to 3 are containing the *
- * delay in 'ticks'
- */
- *delay = (*delay >> 8) & 0xffffff;
-
- if (*delay > 0)
- {
- long time;
-
- seq_playing = 1;
- time = *delay;
- prev_event_time = time;
-
- if (softsynthp != NULL)
- softsynthp(SSYN_REQUEST, time, 0, 0);
- else
- request_sound_timer(time);
-
- if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
- {
- unsigned long flags;
-
- save_flags(flags);
- cli();
- if ((seq_sleep_flag.opts & WK_SLEEP))
- {
- {
- seq_sleep_flag.opts = WK_WAKEUP;
- wake_up(&seq_sleeper);
- };
- }
- restore_flags(flags);
- }
- /*
- * The timer is now active and will reinvoke this function
- * after the timer expires. Return to the caller now.
- */
- return 1;
- }
- break;
-
- case SEQ_PGMCHANGE:
- if (synth_open_mask & (1 << 0))
- if (synth_devs[0])
- synth_devs[0]->set_instr(0, q[1], q[2]);
- break;
-
- case SEQ_SYNCTIMER: /*
- * Reset timer
- */
- if (softsynthp != NULL)
- seq_time = 0;
- else
- seq_time = jiffies;
- prev_input_time = 0;
- prev_event_time = 0;
- if (softsynthp != NULL)
- softsynthp(SSYN_START, 0, 0, 0);
- break;
-
- case SEQ_MIDIPUTC: /*
- * Put a midi character
+ {
+ case SEQ_NOTEOFF:
+ if (synth_open_mask & (1 << 0))
+ if (synth_devs[0])
+ synth_devs[0]->kill_note(0, q[1], 255, q[3]);
+ break;
+
+ case SEQ_NOTEON:
+ if (q[4] < 128 || q[4] == 255)
+ if (synth_open_mask & (1 << 0))
+ if (synth_devs[0])
+ synth_devs[0]->start_note(0, q[1], q[2], q[3]);
+ break;
+
+ case SEQ_WAIT:
+ delay = (unsigned int *) q; /*
+ * Bytes 1 to 3 are containing the *
+ * delay in 'ticks'
+ */
+ *delay = (*delay >> 8) & 0xffffff;
+
+ if (*delay > 0)
+ {
+ long time;
+
+ seq_playing = 1;
+ time = *delay;
+ prev_event_time = time;
+
+ if (softsynthp != NULL)
+ softsynthp(SSYN_REQUEST, time, 0, 0);
+ else
+ request_sound_timer(time);
+
+ if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
+ wake_up(&seq_sleeper);
+ /*
+ * The timer is now active and will reinvoke this function
+ * after the timer expires. Return to the caller now.
*/
- if (midi_opened[q[2]])
- {
- int dev;
-
- dev = q[2];
-
- if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
- break;
-
- if (!midi_devs[dev]->outputc(dev, q[1]))
- {
- /*
- * Output FIFO is full. Wait one timer cycle and try again.
- */
-
- seq_playing = 1;
- if (softsynthp != NULL)
- softsynthp(SSYN_REQUEST, -1, 0, 0);
- else
- request_sound_timer(-1);
- return 2;
- } else
- midi_written[dev] = 1;
- }
- break;
-
- case SEQ_ECHO:
- seq_copy_to_input(q, 4); /*
- * Echo back to the process
- */
- break;
-
- case SEQ_PRIVATE:
- if ((int) q[1] < max_synthdev)
- synth_devs[q[1]]->hw_control(q[1], q);
- break;
-
- case SEQ_EXTENDED:
- extended_event(q);
- break;
-
- case EV_CHN_VOICE:
- seq_chn_voice_event(q);
- break;
-
- case EV_CHN_COMMON:
- seq_chn_common_event(q);
- break;
-
- case EV_TIMING:
- if (seq_timing_event(q) == TIMER_ARMED)
- {
- return 1;
- }
- break;
-
- case EV_SEQ_LOCAL:
- seq_local_event(q);
- break;
-
- case EV_SYSEX:
- seq_sysex_message(q);
- break;
-
- default:;
- }
-
+ return 1;
+ }
+ break;
+
+ case SEQ_PGMCHANGE:
+ if (synth_open_mask & (1 << 0))
+ if (synth_devs[0])
+ synth_devs[0]->set_instr(0, q[1], q[2]);
+ break;
+
+ case SEQ_SYNCTIMER: /*
+ * Reset timer
+ */
+ if (softsynthp != NULL)
+ seq_time = 0;
+ else
+ seq_time = jiffies;
+ prev_input_time = 0;
+ prev_event_time = 0;
+ if (softsynthp != NULL)
+ softsynthp(SSYN_START, 0, 0, 0);
+ break;
+
+ case SEQ_MIDIPUTC: /*
+ * Put a midi character
+ */
+ if (midi_opened[q[2]])
+ {
+ int dev;
+
+ dev = q[2];
+
+ if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)
+ break;
+
+ if (!midi_devs[dev]->outputc(dev, q[1]))
+ {
+ /*
+ * Output FIFO is full. Wait one timer cycle and try again.
+ */
+
+ seq_playing = 1;
+ if (softsynthp != NULL)
+ softsynthp(SSYN_REQUEST, -1, 0, 0);
+ else
+ request_sound_timer(-1);
+ return 2;
+ }
+ else
+ midi_written[dev] = 1;
+ }
+ break;
+
+ case SEQ_ECHO:
+ seq_copy_to_input(q, 4); /*
+ * Echo back to the process
+ */
+ break;
+
+ case SEQ_PRIVATE:
+ if ((int) q[1] < max_synthdev)
+ synth_devs[q[1]]->hw_control(q[1], q);
+ break;
+
+ case SEQ_EXTENDED:
+ extended_event(q);
+ break;
+
+ case EV_CHN_VOICE:
+ seq_chn_voice_event(q);
+ break;
+
+ case EV_CHN_COMMON:
+ seq_chn_common_event(q);
+ break;
+
+ case EV_TIMING:
+ if (seq_timing_event(q) == TIMER_ARMED)
+ {
+ return 1;
+ }
+ break;
+
+ case EV_SEQ_LOCAL:
+ seq_local_event(q);
+ break;
+
+ case EV_SYSEX:
+ seq_sysex_message(q);
+ break;
+
+ default:
+ }
return 0;
}
-static void
-seq_startplay(void)
+static void seq_startplay(void)
{
- unsigned long flags;
- int this_one, action;
+ unsigned long flags;
+ int this_one, action;
while (qlen > 0)
- {
-
- save_flags(flags);
- cli();
- qhead = ((this_one = qhead) + 1) % SEQ_MAX_QUEUE;
- qlen--;
- restore_flags(flags);
-
- seq_playing = 1;
-
- if ((action = play_event(&queue[this_one * EV_SZ])))
- { /* Suspend playback. Next timer routine invokes this routine again */
- if (action == 2)
- {
- qlen++;
- qhead = this_one;
- }
- return;
- }
- }
+ {
+
+ save_flags(flags);
+ cli();
+ qhead = ((this_one = qhead) + 1) % SEQ_MAX_QUEUE;
+ qlen--;
+ restore_flags(flags);
+
+ seq_playing = 1;
+
+ if ((action = play_event(&queue[this_one * EV_SZ])))
+ { /* Suspend playback. Next timer routine invokes this routine again */
+ if (action == 2)
+ {
+ qlen++;
+ qhead = this_one;
+ }
+ return;
+ }
+ }
seq_playing = 0;
if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
- {
- unsigned long flags;
-
- save_flags(flags);
- cli();
- if ((seq_sleep_flag.opts & WK_SLEEP))
- {
- {
- seq_sleep_flag.opts = WK_WAKEUP;
- wake_up(&seq_sleeper);
- };
- }
- restore_flags(flags);
- }
+ wake_up(&seq_sleeper);
}
-static void
-reset_controllers(int dev, unsigned char *controller, int update_dev)
+static void reset_controllers(int dev, unsigned char *controller, int update_dev)
{
-
- int i;
-
+ int i;
for (i = 0; i < 128; i++)
controller[i] = ctrl_def_values[i];
}
-static void
-setup_mode2(void)
+static void setup_mode2(void)
{
- int dev;
+ int dev;
max_synthdev = num_synths;
for (dev = 0; dev < num_midis; dev++)
+ {
if (midi_devs[dev] && midi_devs[dev]->converter != NULL)
- {
- synth_devs[max_synthdev++] =
- midi_devs[dev]->converter;
- }
+ {
+ synth_devs[max_synthdev++] = midi_devs[dev]->converter;
+ }
+ }
+
for (dev = 0; dev < max_synthdev; dev++)
- {
- int chn;
-
- synth_devs[dev]->sysex_ptr = 0;
- synth_devs[dev]->emulation = 0;
-
- for (chn = 0; chn < 16; chn++)
- {
- synth_devs[dev]->chn_info[chn].pgm_num = 0;
- reset_controllers(dev,
- synth_devs[dev]->chn_info[chn].controllers,
- 0);
- synth_devs[dev]->chn_info[chn].bender_value = (1 << 7); /* Neutral */
- synth_devs[dev]->chn_info[chn].bender_range = 200;
- }
- }
-
+ {
+ int chn;
+
+ synth_devs[dev]->sysex_ptr = 0;
+ synth_devs[dev]->emulation = 0;
+
+ for (chn = 0; chn < 16; chn++)
+ {
+ synth_devs[dev]->chn_info[chn].pgm_num = 0;
+ reset_controllers(dev,
+ synth_devs[dev]->chn_info[chn].controllers,0);
+ synth_devs[dev]->chn_info[chn].bender_value = (1 << 7); /* Neutral */
+ synth_devs[dev]->chn_info[chn].bender_range = 200;
+ }
+ }
max_mididev = 0;
seq_mode = SEQ_2;
}
-int
-sequencer_open(int dev, struct fileinfo *file)
+int sequencer_open(int dev, struct file *file)
{
- int retval, mode, i;
- int level, tmp;
- unsigned long flags;
+ int retval, mode, i;
+ int level, tmp;
+ unsigned long flags;
if (!sequencer_ok)
sequencer_init();
@@ -1082,33 +983,34 @@ sequencer_open(int dev, struct fileinfo *file)
level = ((dev & 0x0f) == SND_DEV_SEQ2) ? 2 : 1;
dev = dev >> 4;
- mode = file->mode & O_ACCMODE;
+ mode = translate_mode(file);
DEB(printk("sequencer_open(dev=%d)\n", dev));
if (!sequencer_ok)
- {
- printk("Soundcard: Sequencer not initialized\n");
- return -ENXIO;
- }
+ {
+/* printk("Soundcard: Sequencer not initialized\n");*/
+ return -ENXIO;
+ }
if (dev) /* Patch manager device (obsolete) */
- {
return -ENXIO;
- }
+
if (mode == OPEN_READ)
+ {
if (!num_midis)
- {
- printk("Sequencer: No MIDI devices. Input not possible\n");
+ {
+ /*printk("Sequencer: No MIDI devices. Input not possible\n");*/
sequencer_busy = 0;
return -ENXIO;
- }
+ }
+ }
save_flags(flags);
cli();
if (sequencer_busy)
- {
- restore_flags(flags);
- return -EBUSY;
- }
+ {
+ restore_flags(flags);
+ return -EBUSY;
+ }
sequencer_busy = 1;
obsolete_api_used = 0;
restore_flags(flags);
@@ -1119,61 +1021,65 @@ sequencer_open(int dev, struct fileinfo *file)
seq_mode = SEQ_1;
if (pending_timer != -1)
- {
- tmr_no = pending_timer;
- pending_timer = -1;
- }
+ {
+ tmr_no = pending_timer;
+ pending_timer = -1;
+ }
if (tmr_no == -1) /* Not selected yet */
- {
- int i, best;
+ {
+ int i, best;
- best = -1;
- for (i = 0; i < num_sound_timers; i++)
- if (sound_timer_devs[i] && sound_timer_devs[i]->priority > best)
- {
+ best = -1;
+ 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;
- }
- if (tmr_no == -1) /* Should not be */
- tmr_no = 0;
- }
+ }
+ if (tmr_no == -1) /* Should not be */
+ tmr_no = 0;
+ }
tmr = sound_timer_devs[tmr_no];
if (level == 2)
- {
- if (tmr == NULL)
- {
- printk("sequencer: No timer for level 2\n");
- sequencer_busy = 0;
- return -ENXIO;
- }
- setup_mode2();
- }
+ {
+ if (tmr == NULL)
+ {
+ /*printk("sequencer: No timer for level 2\n");*/
+ sequencer_busy = 0;
+ return -ENXIO;
+ }
+ setup_mode2();
+ }
if (!max_synthdev && !max_mididev)
return -ENXIO;
synth_open_mask = 0;
for (i = 0; i < max_mididev; i++)
- {
- midi_opened[i] = 0;
- midi_written[i] = 0;
- }
+ {
+ midi_opened[i] = 0;
+ midi_written[i] = 0;
+ }
for (i = 0; i < max_synthdev; i++)
- {
- if ((tmp = synth_devs[i]->open(i, mode)) < 0)
- {
- printk("Sequencer: Warning! Cannot open synth device #%d (%d)\n", i, tmp);
- if (synth_devs[i]->midi_dev)
- printk("(Maps to MIDI dev #%d)\n", synth_devs[i]->midi_dev);
- } else
- {
- synth_open_mask |= (1 << i);
- if (synth_devs[i]->midi_dev)
- midi_opened[synth_devs[i]->midi_dev] = 1;
- }
- }
+ {
+ 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);
+ if (synth_devs[i]->midi_dev)
+ printk(KERN_WARNING "(Maps to MIDI dev #%d)\n", synth_devs[i]->midi_dev);
+ }
+ else
+ {
+ synth_open_mask |= (1 << i);
+ if (synth_devs[i]->midi_dev)
+ midi_opened[synth_devs[i]->midi_dev] = 1;
+ }
+ }
if (softsynthp != NULL)
seq_time = 0;
@@ -1186,32 +1092,34 @@ sequencer_open(int dev, struct fileinfo *file)
softsynthp(SSYN_START, 0, 0, 0);
if (seq_mode == SEQ_1 && (mode == OPEN_READ || mode == OPEN_READWRITE))
- { /*
- * Initialize midi input devices
- */
- for (i = 0; i < max_mididev; i++)
- if (!midi_opened[i])
- {
- if ((retval = midi_devs[i]->open(i, mode,
- sequencer_midi_input, sequencer_midi_output)) >= 0)
- midi_opened[i] = 1;
- }
- }
+ {
+ /*
+ * Initialize midi input devices
+ */
+
+ for (i = 0; i < max_mididev; i++)
+ if (!midi_opened[i])
+ {
+ if ((retval = midi_devs[i]->open(i, mode,
+ sequencer_midi_input, sequencer_midi_output)) >= 0)
+ {
+ midi_opened[i] = 1;
+ }
+ }
+ }
if (seq_mode == SEQ_2)
- {
- tmr->open(tmr_no, seq_mode);
- }
- seq_sleep_flag.opts = WK_NONE;
- midi_sleep_flag.opts = WK_NONE;
+ tmr->open(tmr_no, seq_mode);
+
+ init_waitqueue(&seq_sleeper);
+ init_waitqueue(&midi_sleeper);
output_threshold = SEQ_MAX_QUEUE / 2;
return 0;
}
-void
-seq_drain_midi_queues(void)
+void seq_drain_midi_queues(void)
{
- int i, n;
+ int i, n;
/*
* Give the Midi drivers time to drain their output queues
@@ -1220,46 +1128,31 @@ seq_drain_midi_queues(void)
n = 1;
while (!signal_pending(current) && n)
- {
- n = 0;
-
- for (i = 0; i < max_mididev; i++)
- if (midi_opened[i] && midi_written[i])
- if (midi_devs[i]->buffer_status != NULL)
- if (midi_devs[i]->buffer_status(i))
- n++;
-
- /*
- * Let's have a delay
- */
- if (n)
- {
-
- {
- unsigned long tlimit;
-
- if (HZ / 10)
- current->timeout = tlimit = jiffies + (HZ / 10);
- else
- tlimit = (unsigned long) -1;
- seq_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&seq_sleeper);
- if (!(seq_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- seq_sleep_flag.opts |= WK_TIMEOUT;
- }
- seq_sleep_flag.opts &= ~WK_SLEEP;
- };
- }
- }
+ {
+ n = 0;
+
+ for (i = 0; i < max_mididev; i++)
+ if (midi_opened[i] && midi_written[i])
+ if (midi_devs[i]->buffer_status != NULL)
+ if (midi_devs[i]->buffer_status(i))
+ n++;
+
+ /*
+ * Let's have a delay
+ */
+
+ if (n) {
+ current->timeout = jiffies + HZ / 10;
+ interruptible_sleep_on(&seq_sleeper);
+ current->timeout = 0;
+ }
+ }
}
-void
-sequencer_release(int dev, struct fileinfo *file)
+void sequencer_release(int dev, struct file *file)
{
- int i;
- int mode = file->mode & O_ACCMODE;
+ int i;
+ int mode = translate_mode(file);
dev = dev >> 4;
@@ -1269,29 +1162,18 @@ sequencer_release(int dev, struct fileinfo *file)
* Wait until the queue is empty (if we don't have nonblock)
*/
- if (mode != OPEN_READ && !(file->flags & (O_NONBLOCK) ?
- 1 : 0))
+ if (mode != OPEN_READ && !(file->f_flags & O_NONBLOCK))
+ {
while (!signal_pending(current) && qlen > 0)
- {
- seq_sync();
-
- {
- unsigned long tlimit;
-
- if (3 * HZ)
- current->timeout = tlimit = jiffies + (3 * HZ);
- else
- tlimit = (unsigned long) -1;
- seq_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&seq_sleeper);
- if (!(seq_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- seq_sleep_flag.opts |= WK_TIMEOUT;
- }
- seq_sleep_flag.opts &= ~WK_SLEEP;
- }; /* Extra delay */
- }
+ {
+ seq_sync();
+ current->timeout = jiffies + 3 * HZ;
+ interruptible_sleep_on(&seq_sleeper);
+ current->timeout = 0;
+ /* Extra delay */
+ }
+ }
+
if (mode != OPEN_READ)
seq_drain_midi_queues(); /*
* Ensure the output queues are empty
@@ -1303,77 +1185,59 @@ sequencer_release(int dev, struct fileinfo *file)
*/
for (i = 0; i < max_synthdev; i++)
- {
- if (synth_open_mask & (1 << i)) /*
- * Actually opened
- */
- if (synth_devs[i])
- {
- synth_devs[i]->close(i);
+ {
+ if (synth_open_mask & (1 << i)) /*
+ * Actually opened
+ */
+ if (synth_devs[i])
+ {
+ synth_devs[i]->close(i);
- if (synth_devs[i]->midi_dev)
- midi_opened[synth_devs[i]->midi_dev] = 0;
- }
- }
+ if (synth_devs[i]->midi_dev)
+ midi_opened[synth_devs[i]->midi_dev] = 0;
+ }
+ }
for (i = 0; i < max_mididev; i++)
- {
- if (midi_opened[i])
+ {
+ if (midi_opened[i])
midi_devs[i]->close(i);
- }
+ }
if (seq_mode == SEQ_2)
tmr->close(tmr_no);
if (obsolete_api_used)
- printk("/dev/music: Obsolete (4 byte) API was used by this program\n");
+ printk(KERN_WARNING "/dev/music: Obsolete (4 byte) API was used by %s\n", current->comm);
sequencer_busy = 0;
}
-static int
-seq_sync(void)
+static int seq_sync(void)
{
- unsigned long flags;
+ unsigned long flags;
if (qlen && !seq_playing && !signal_pending(current))
seq_startplay();
save_flags(flags);
cli();
- if (qlen > 0)
- {
-
- {
- unsigned long tlimit;
-
- if (HZ)
- current->timeout = tlimit = jiffies + (HZ);
- else
- tlimit = (unsigned long) -1;
- seq_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&seq_sleeper);
- if (!(seq_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- seq_sleep_flag.opts |= WK_TIMEOUT;
- }
- seq_sleep_flag.opts &= ~WK_SLEEP;
- };
- }
+ if (qlen > 0) {
+ current->timeout = jiffies + HZ;
+ interruptible_sleep_on(&seq_sleeper);
+ current->timeout = 0;
+ }
restore_flags(flags);
-
return qlen;
}
-static void
-midi_outc(int dev, unsigned char data)
+static void midi_outc(int dev, unsigned char data)
{
/*
* NOTE! Calls sleep(). Don't call this from interrupt.
*/
- int n;
- unsigned long flags;
+ int n;
+ unsigned long flags;
/*
* This routine sends one byte to the Midi channel.
@@ -1385,40 +1249,24 @@ midi_outc(int dev, unsigned char data)
save_flags(flags);
cli();
- while (n && !midi_devs[dev]->outputc(dev, data))
- {
-
- {
- unsigned long tlimit;
-
- if (4)
- current->timeout = tlimit = jiffies + (4);
- else
- tlimit = (unsigned long) -1;
- seq_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&seq_sleeper);
- if (!(seq_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- seq_sleep_flag.opts |= WK_TIMEOUT;
- }
- seq_sleep_flag.opts &= ~WK_SLEEP;
- };
- n--;
- }
+ while (n && !midi_devs[dev]->outputc(dev, data)) {
+ current->timeout = jiffies + 4;
+ interruptible_sleep_on(&seq_sleeper);
+ current->timeout = 0;
+ n--;
+ }
restore_flags(flags);
}
-static void
-seq_reset(void)
+static void seq_reset(void)
{
/*
* NOTE! Calls sleep(). Don't call this from interrupt.
*/
- int i;
- int chn;
- unsigned long flags;
+ int i;
+ int chn;
+ unsigned long flags;
if (softsynthp != NULL)
softsynthp(SSYN_STOP, 0, 0, 0);
@@ -1438,448 +1286,325 @@ seq_reset(void)
synth_devs[i]->reset(i);
if (seq_mode == SEQ_2)
- {
-
- for (chn = 0; chn < 16; chn++)
- for (i = 0; i < max_synthdev; i++)
- if (synth_open_mask & (1 << i))
- if (synth_devs[i])
- {
- synth_devs[i]->controller(i, chn, 123, 0); /* All notes off */
- synth_devs[i]->controller(i, chn, 121, 0); /* Reset all ctl */
- synth_devs[i]->bender(i, chn, 1 << 13); /* Bender off */
- }
- } else
- /* seq_mode == SEQ_1 */
- {
- for (i = 0; i < max_mididev; i++)
- if (midi_written[i]) /*
+ {
+ for (chn = 0; chn < 16; chn++)
+ for (i = 0; i < max_synthdev; i++)
+ if (synth_open_mask & (1 << i))
+ if (synth_devs[i])
+ {
+ synth_devs[i]->controller(i, chn, 123, 0); /* All notes off */
+ synth_devs[i]->controller(i, chn, 121, 0); /* Reset all ctl */
+ synth_devs[i]->bender(i, chn, 1 << 13); /* Bender off */
+ }
+ }
+ else /* seq_mode == SEQ_1 */
+ {
+ for (i = 0; i < max_mididev; i++)
+ if (midi_written[i]) /*
* Midi used. Some notes may still be playing
*/
- {
- /*
- * Sending just a ACTIVE SENSING message should be enough to stop all
- * playing notes. Since there are devices not recognizing the
- * active sensing, we have to send some all notes off messages also.
- */
- midi_outc(i, 0xfe);
-
- for (chn = 0; chn < 16; chn++)
- {
- midi_outc(i,
- (unsigned char) (0xb0 + (chn & 0x0f))); /* control change */
- midi_outc(i, 0x7b); /* All notes off */
- midi_outc(i, 0); /* Dummy parameter */
- }
-
- midi_devs[i]->close(i);
-
- midi_written[i] = 0;
- midi_opened[i] = 0;
- }
- }
+ {
+ /*
+ * Sending just a ACTIVE SENSING message should be enough to stop all
+ * playing notes. Since there are devices not recognizing the
+ * active sensing, we have to send some all notes off messages also.
+ */
+ midi_outc(i, 0xfe);
+
+ for (chn = 0; chn < 16; chn++)
+ {
+ midi_outc(i, (unsigned char) (0xb0 + (chn & 0x0f))); /* control change */
+ midi_outc(i, 0x7b); /* All notes off */
+ midi_outc(i, 0); /* Dummy parameter */
+ }
+
+ midi_devs[i]->close(i);
+
+ midi_written[i] = 0;
+ midi_opened[i] = 0;
+ }
+ }
seq_playing = 0;
save_flags(flags);
cli();
- if ((seq_sleep_flag.opts & WK_SLEEP))
- {
- /* printk( "Sequencer Warning: Unexpected sleeping process - Waking up\n"); */
- {
- seq_sleep_flag.opts = WK_WAKEUP;
- wake_up(&seq_sleeper);
- };
- }
+
+ if (waitqueue_active(&seq_sleeper)) {
+ /* printk( "Sequencer Warning: Unexpected sleeping process - Waking up\n"); */
+ wake_up(&seq_sleeper);
+ }
restore_flags(flags);
-
}
-static void
-seq_panic(void)
+static void seq_panic(void)
{
/*
- * This routine is called by the application in case the user
- * wants to reset the system to the default state.
+ * This routine is called by the application in case the user
+ * wants to reset the system to the default state.
*/
seq_reset();
/*
- * Since some of the devices don't recognize the active sensing and
- * all notes off messages, we have to shut all notes manually.
- *
- * TO BE IMPLEMENTED LATER
+ * Since some of the devices don't recognize the active sensing and
+ * all notes off messages, we have to shut all notes manually.
+ *
+ * TO BE IMPLEMENTED LATER
*/
/*
- * Also return the controllers to their default states
+ * Also return the controllers to their default states
*/
}
-int
-sequencer_ioctl(int dev, struct fileinfo *file,
- unsigned int cmd, caddr_t arg)
+int sequencer_ioctl(int dev, struct file *file, unsigned int cmd, caddr_t arg)
{
- int midi_dev, orig_dev, val;
- int mode = file->mode & O_ACCMODE;
+ int midi_dev, orig_dev, val, err;
+ int mode = translate_mode(file);
+ struct synth_info inf;
+ struct seq_event_rec event_rec;
+ unsigned long flags;
orig_dev = dev = dev >> 4;
- switch (cmd)
- {
- case SNDCTL_TMR_TIMEBASE:
- case SNDCTL_TMR_TEMPO:
- case SNDCTL_TMR_START:
- case SNDCTL_TMR_STOP:
- case SNDCTL_TMR_CONTINUE:
- case SNDCTL_TMR_METRONOME:
- case SNDCTL_TMR_SOURCE:
-
- if (seq_mode != SEQ_2)
- return -EINVAL;
- return tmr->ioctl(tmr_no, cmd, arg);
- break;
-
- case SNDCTL_TMR_SELECT:
-
- if (seq_mode != SEQ_2)
- return -EINVAL;
- pending_timer = *(int *) arg;
-
- if (pending_timer < 0 || pending_timer >= num_sound_timers || sound_timer_devs[pending_timer] == NULL)
- {
- pending_timer = -1;
- return -EINVAL;
- }
- return (*(int *) arg = pending_timer);
- break;
-
- case SNDCTL_SEQ_PANIC:
- seq_panic();
- break;
-
- case SNDCTL_SEQ_SYNC:
-
- if (mode == OPEN_READ)
- return 0;
- while (qlen > 0 && !signal_pending(current))
- seq_sync();
- if (qlen)
- return -EINTR;
- else
- return 0;
- break;
-
- case SNDCTL_SEQ_RESET:
-
- seq_reset();
- return 0;
- break;
-
- case SNDCTL_SEQ_TESTMIDI:
- midi_dev = *(int *) arg;
- if (midi_dev < 0 || midi_dev >= max_mididev)
- return -ENXIO;
-
- if (!midi_opened[midi_dev])
- {
- int err, mode;
-
- mode = file->mode & O_ACCMODE;
- if ((err = midi_devs[midi_dev]->open(midi_dev, mode,
- sequencer_midi_input,
- sequencer_midi_output)) < 0)
- return err;
- }
- midi_opened[midi_dev] = 1;
-
- return 0;
- break;
-
- case SNDCTL_SEQ_GETINCOUNT:
- if (mode == OPEN_WRITE)
- return 0;
- return (*(int *) arg = iqlen);
- break;
-
- case SNDCTL_SEQ_GETOUTCOUNT:
-
- if (mode == OPEN_READ)
- return 0;
- return (*(int *) arg = SEQ_MAX_QUEUE - qlen);
- break;
-
- case SNDCTL_SEQ_GETTIME:
- if (seq_mode == SEQ_2)
- return tmr->ioctl(tmr_no, cmd, arg);
-
- if (softsynthp != NULL)
- return (*(int *) arg = softsynthp(SSYN_GETTIME, 0, 0, 0));
- else
- return (*(int *) arg = 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);
-
- val = *(int *) arg;
- if (val != 0)
- return -EINVAL;
-
- return (*(int *) arg = HZ);
- break;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- case SNDCTL_SYNTH_REMOVESAMPLE:
- case SNDCTL_SYNTH_CONTROL:
- {
- int err;
-
- dev = *(int *) arg;
- if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
- {
- return -ENXIO;
- }
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- {
- return -EBUSY;
- }
- err = synth_devs[dev]->ioctl(dev, cmd, arg);
- return err;
- }
- break;
-
- case SNDCTL_SEQ_NRSYNTHS:
- return (*(int *) arg = max_synthdev);
- break;
-
- case SNDCTL_SEQ_NRMIDIS:
- return (*(int *) arg = max_mididev);
- break;
-
- case SNDCTL_SYNTH_MEMAVL:
- {
- int dev;
-
- dev = *(int *) arg;
-
- if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return -EBUSY;
-
- return (*(int *) arg = synth_devs[dev]->ioctl(dev, cmd, arg));
- }
- break;
-
- case SNDCTL_FM_4OP_ENABLE:
- {
- int dev;
-
- dev = *(int *) arg;
-
- if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)))
- return -ENXIO;
-
- synth_devs[dev]->ioctl(dev, cmd, arg);
- return 0;
- }
- break;
-
- case SNDCTL_SYNTH_INFO:
- {
- struct synth_info inf;
- int dev;
-
- memcpy((char *) &inf, (&((char *) arg)[0]), sizeof(inf));
- dev = inf.device;
-
- if (dev < 0 || dev >= max_synthdev)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return -EBUSY;
-
- return synth_devs[dev]->ioctl(dev, cmd, arg);
- }
- break;
-
-
- /* Like SYNTH_INFO but returns ID in the name field */
- case SNDCTL_SYNTH_ID:
- {
- struct synth_info inf;
- int dev;
-
- memcpy((char *) &inf, (&((char *) arg)[0]), sizeof(inf));
- dev = inf.device;
-
- if (dev < 0 || dev >= max_synthdev)
- return -ENXIO;
-
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return -EBUSY;
-
- memcpy((char *) &inf, (char *) synth_devs[dev]->info, sizeof(inf));
- strcpy(inf.name, synth_devs[dev]->id);
- inf.device = dev;
- memcpy((&((char *) arg)[0]), (char *) &inf, sizeof(inf));
- return 0;
- }
- break;
-
- case SNDCTL_SEQ_OUTOFBAND:
- {
- struct seq_event_rec event_rec;
- unsigned long flags;
-
- memcpy((char *) &event_rec, (&((char *) arg)[0]), sizeof(event_rec));
-
- save_flags(flags);
- cli();
- play_event(event_rec.arr);
- restore_flags(flags);
-
- return 0;
- }
- break;
-
- case SNDCTL_MIDI_INFO:
- {
- struct midi_info inf;
- int dev;
- char *pp;
-
- memcpy((char *) &inf, (&((char *) arg)[0]), sizeof(inf));
- dev = inf.device;
-
- if (dev < 0 || dev >= max_mididev)
- return -ENXIO;
-
- midi_devs[dev]->info.device = dev;
- pp = (char *) &midi_devs[dev]->info;
- memcpy((&((char *) arg)[0]), pp, sizeof(inf));
- return 0;
- }
- break;
-
- case SNDCTL_SEQ_THRESHOLD:
- {
- int tmp;
-
- tmp = *(int *) arg;
-
- if (tmp < 1)
- tmp = 1;
- if (tmp >= SEQ_MAX_QUEUE)
- tmp = SEQ_MAX_QUEUE - 1;
- output_threshold = tmp;
- return 0;
- }
- break;
-
- case SNDCTL_MIDI_PRETIME:
- {
- int val;
-
- val = *(int *) arg;
-
- if (val < 0)
- val = 0;
-
- val = (HZ * val) / 10;
- pre_event_timeout = val;
- return (*(int *) arg = val);
- }
- break;
-
- default:
- if (mode == OPEN_READ)
- return -EIO;
-
- if (!synth_devs[0])
- return -ENXIO;
- if (!(synth_open_mask & (1 << 0)))
- return -ENXIO;
- return synth_devs[0]->ioctl(0, cmd, arg);
- break;
- }
-
- return -EINVAL;
+ switch (cmd)
+ {
+ case SNDCTL_TMR_TIMEBASE:
+ case SNDCTL_TMR_TEMPO:
+ case SNDCTL_TMR_START:
+ case SNDCTL_TMR_STOP:
+ case SNDCTL_TMR_CONTINUE:
+ case SNDCTL_TMR_METRONOME:
+ case SNDCTL_TMR_SOURCE:
+ 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)
+ {
+ pending_timer = -1;
+ return -EINVAL;
+ }
+ val = pending_timer;
+ break;
+
+ 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;
+
+ case SNDCTL_SEQ_TESTMIDI:
+ if (__get_user(midi_dev, (int *)arg))
+ return -EFAULT;
+ if (midi_dev < 0 || midi_dev >= max_mididev)
+ return -ENXIO;
+
+ if (!midi_opened[midi_dev] &&
+ (err = midi_devs[midi_dev]->open(midi_dev, mode, sequencer_midi_input,
+ sequencer_midi_output)) < 0)
+ return err;
+ midi_opened[midi_dev] = 1;
+ return 0;
+
+ case SNDCTL_SEQ_GETINCOUNT:
+ if (mode == OPEN_WRITE)
+ 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);
+ if (softsynthp != NULL)
+ val = softsynthp(SSYN_GETTIME, 0, 0, 0);
+ 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)
+ return -EINVAL;
+ val = HZ;
+ break;
+
+ case SNDCTL_SEQ_RESETSAMPLES:
+ case SNDCTL_SYNTH_REMOVESAMPLE:
+ case SNDCTL_SYNTH_CONTROL:
+ if (get_user(dev, (int *)arg))
+ return -EFAULT;
+ if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << dev)) && !orig_dev)
+ return -EBUSY;
+ return synth_devs[dev]->ioctl(dev, cmd, arg);
+
+ case SNDCTL_SEQ_NRSYNTHS:
+ val = max_synthdev;
+ break;
+
+ case SNDCTL_SEQ_NRMIDIS:
+ val = max_mididev;
+ break;
+
+ case SNDCTL_SYNTH_MEMAVL:
+ if (get_user(dev, (int *)arg))
+ return -EFAULT;
+ if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << dev)) && !orig_dev)
+ return -EBUSY;
+ val = synth_devs[dev]->ioctl(dev, cmd, arg);
+ break;
+
+ case SNDCTL_FM_4OP_ENABLE:
+ if (get_user(dev, (int *)arg))
+ return -EFAULT;
+ if (dev < 0 || dev >= num_synths || synth_devs[dev] == NULL)
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << dev)))
+ return -ENXIO;
+ synth_devs[dev]->ioctl(dev, cmd, arg);
+ return 0;
+
+ case SNDCTL_SYNTH_INFO:
+ if (get_user(dev, (int *)(&(((struct synth_info *)arg)->device))))
+ return -EFAULT;
+ if (dev < 0 || dev >= max_synthdev)
+ return -ENXIO;
+ 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))))
+ return -EFAULT;
+ if (dev < 0 || dev >= max_synthdev)
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << dev)) && !orig_dev)
+ return -EBUSY;
+ memcpy(&inf, synth_devs[dev]->info, sizeof(inf));
+ 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;
+ save_flags(flags);
+ cli();
+ 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;
+ if (dev < 0 || dev >= max_mididev)
+ 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;
+ if (val < 1)
+ val = 1;
+ if (val >= SEQ_MAX_QUEUE)
+ val = SEQ_MAX_QUEUE - 1;
+ output_threshold = val;
+ return 0;
+
+ case SNDCTL_MIDI_PRETIME:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val < 0)
+ val = 0;
+ val = (HZ * val) / 10;
+ pre_event_timeout = val;
+ break;
+
+ default:
+ if (mode == OPEN_READ)
+ return -EIO;
+ if (!synth_devs[0])
+ return -ENXIO;
+ if (!(synth_open_mask & (1 << 0)))
+ return -ENXIO;
+ if (!synth_devs[0]->ioctl)
+ return -EINVAL;
+ return synth_devs[0]->ioctl(0, cmd, arg);
+ }
+ return put_user(val, (int *)arg);
}
-int
-sequencer_select(int dev, struct fileinfo *file, int sel_type, poll_table * wait)
+unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait)
{
- unsigned long flags;
+ unsigned long flags;
+ unsigned int mask = 0;
dev = dev >> 4;
- switch (sel_type)
- {
- case SEL_IN:
- save_flags(flags);
- cli();
- if (!iqlen)
- {
-
- midi_sleep_flag.opts = WK_SLEEP;
- poll_wait(&midi_sleeper, wait);
- restore_flags(flags);
- return 0;
- }
- restore_flags(flags);
- return 1;
- break;
-
- case SEL_OUT:
- save_flags(flags);
- cli();
- if ((SEQ_MAX_QUEUE - qlen) < output_threshold)
- {
-
- seq_sleep_flag.opts = WK_SLEEP;
- poll_wait(&seq_sleeper, wait);
- restore_flags(flags);
- return 0;
- }
- restore_flags(flags);
- return 1;
- break;
-
- case SEL_EX:
- return 0;
- }
-
- return 0;
+ save_flags(flags);
+ cli();
+ /* input */
+ poll_wait(file, &midi_sleeper, wait);
+ if (iqlen)
+ mask |= POLLIN | POLLRDNORM;
+
+ /* output */
+ poll_wait(file, &seq_sleeper, wait);
+ if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
+ mask |= POLLOUT | POLLWRNORM;
+ restore_flags(flags);
+ return mask;
}
-void
-sequencer_timer(unsigned long dummy)
+void sequencer_timer(unsigned long dummy)
{
seq_startplay();
}
-int
-note_to_freq(int note_num)
+int note_to_freq(int note_num)
{
/*
* This routine converts a midi note to a frequency (multiplied by 1000)
*/
- int note, octave, note_freq;
- static int notes[] =
+ int note, octave, note_freq;
+ static int notes[] =
{
261632, 277189, 293671, 311132, 329632, 349232,
369998, 391998, 415306, 440000, 466162, 493880
@@ -1904,12 +1629,11 @@ note_to_freq(int note_num)
return note_freq;
}
-unsigned long
-compute_finetune(unsigned long base_freq, int bend, int range,
+unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
int vibrato_cents)
{
- unsigned long amount;
- int negative, semitones, cents, multiplier = 1;
+ unsigned long amount;
+ int negative, semitones, cents, multiplier = 1;
if (!bend)
return base_freq;
@@ -1940,18 +1664,17 @@ compute_finetune(unsigned long base_freq, int bend, int range,
bend = 2399;
*/
while (bend > 2399)
- {
+ {
multiplier *= 4;
bend -= 2400;
- }
+ }
semitones = bend / 100;
if (semitones > 99)
semitones = 99;
cents = bend % 100;
- amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents])
- / 10000;
+ amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents]) / 10000;
if (negative)
return (base_freq * 10000) / amount; /* Bend down */
@@ -1960,36 +1683,41 @@ compute_finetune(unsigned long base_freq, int bend, int range,
}
-void
-sequencer_init(void)
+void sequencer_init(void)
{
if (sequencer_ok)
return;
-
#ifdef CONFIG_MIDI
MIDIbuf_init();
#endif
-
-
- queue = (unsigned char *) (sound_mem_blocks[sound_nblocks] = vmalloc(SEQ_MAX_QUEUE * EV_SZ));
- sound_mem_sizes[sound_nblocks] = SEQ_MAX_QUEUE * EV_SZ;
- if (sound_nblocks < 1024)
- sound_nblocks++;;
+ queue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * EV_SZ);
if (queue == NULL)
- {
- printk("Sound: Can't allocate memory for sequencer output queue\n");
+ {
+ printk(KERN_ERR "sequencer: Can't allocate memory for sequencer output queue\n");
return;
- }
- iqueue = (unsigned char *) (sound_mem_blocks[sound_nblocks] = vmalloc(SEQ_MAX_QUEUE * IEV_SZ));
- sound_mem_sizes[sound_nblocks] = SEQ_MAX_QUEUE * IEV_SZ;
- if (sound_nblocks < 1024)
- sound_nblocks++;;
+ }
+ iqueue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * IEV_SZ);
if (iqueue == NULL)
- {
- printk("Sound: Can't allocate memory for sequencer input queue\n");
- return;
- }
+ {
+ printk(KERN_ERR "sequencer: Can't allocate memory for sequencer input queue\n");
+ vfree(queue);
+ return;
+ }
sequencer_ok = 1;
}
+void sequencer_unload(void)
+{
+ if(queue)
+ {
+ vfree(queue);
+ queue=NULL;
+ }
+ if(iqueue)
+ {
+ vfree(iqueue);
+ iqueue=NULL;
+ }
+}
+
#endif
diff --git a/drivers/sound/softoss.c b/drivers/sound/softoss.c
index a47133a8a..43c3a7ec3 100644
--- a/drivers/sound/softoss.c
+++ b/drivers/sound/softoss.c
@@ -10,6 +10,9 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+/*
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ */
#include <linux/config.h>
#include <linux/module.h>
@@ -103,7 +106,7 @@ static struct synth_info softsyn_info =
static struct softsyn_devc sdev_info =
{0};
-softsyn_devc *devc = &sdev_info;
+softsyn_devc *devc = &sdev_info; /* used in softoss_rs.c */
static struct voice_alloc_info *voice_alloc;
@@ -114,6 +117,7 @@ static void compute_step(int voice);
static volatile int tmr_running = 0;
static int voice_limit = 24;
+
static void
set_max_voices(int nr)
{
@@ -662,10 +666,11 @@ softsyn_callback(int dev, int parm)
}
#endif
-static void
-start_engine(softsyn_devc * devc)
+static void start_engine(softsyn_devc * devc)
{
struct dma_buffparms *dmap;
+ int trig, n;
+ mm_segment_t fs;
if (!devc->audio_opened)
if (softsyn_open(devc->synthdev, 0) < 0)
@@ -673,46 +678,37 @@ start_engine(softsyn_devc * devc)
if (devc->audiodev >= num_audiodevs)
return;
-
+
dmap = audio_devs[devc->audiodev]->dmap_out;
-
+
devc->usecs = 0;
devc->next_event_usecs = ~0;
devc->control_rate = 64;
devc->control_counter = 0;
- if (devc->engine_state == ES_STOPPED)
- {
- int trig, n = 0;
-
- trig = 0;
- dma_ioctl(devc->audiodev, SNDCTL_DSP_SETTRIGGER, (caddr_t) & trig);
+ 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;
- add_timer(&poll_timer);
- }; /* Start polling */
+ poll_timer.expires = (1) + jiffies;
+ add_timer(&poll_timer);
+ /* Start polling */
#else
- dmap->audio_callback = softsyn_callback;
- dmap->qhead = dmap->qtail = dmap->qlen = 0;
+ dmap->audio_callback = softsyn_callback;
+ dmap->qhead = dmap->qtail = dmap->qlen = 0;
#endif
-
- while (dmap->qlen < devc->max_playahead && n++ < 2)
- do_resample(0);
-
- devc->engine_state = ES_STARTED;
- last_resample_jiffies = jiffies;
- resample_counter = 0;
-
- trig = PCM_ENABLE_OUTPUT;
- if (dma_ioctl(devc->audiodev, SNDCTL_DSP_SETTRIGGER,
- (caddr_t) & trig) < 0)
- {
- printk("SoftOSS: Trigger failed\n");
- }
- }
+ while (dmap->qlen < devc->max_playahead && n++ < 2)
+ do_resample(0);
+ devc->engine_state = ES_STARTED;
+ last_resample_jiffies = jiffies;
+ resample_counter = 0;
+ trig = PCM_ENABLE_OUTPUT;
+ if (dma_ioctl(devc->audiodev, SNDCTL_DSP_SETTRIGGER, (caddr_t)&trig) < 0)
+ printk(KERN_ERR "SoftOSS: Trigger failed\n");
+ set_fs(fs);
+ }
}
static void
@@ -760,34 +756,27 @@ softsynth_hook(int cmd, int parm1, int parm2, unsigned long parm3)
return 0;
}
-static int
-softsyn_ioctl(int dev,
- unsigned int cmd, caddr_t arg)
+static int softsyn_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- switch (cmd)
- {
-
- case SNDCTL_SYNTH_INFO:
- softsyn_info.nr_voices = devc->maxvoice;
-
- memcpy((&((char *) arg)[0]), (char *) &softsyn_info, sizeof(softsyn_info));
- return 0;
- break;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- stop_engine(devc);
- reset_samples(devc);
- return 0;
- break;
+ switch (cmd) {
- case SNDCTL_SYNTH_MEMAVL:
- return devc->ram_size - devc->ram_used;
- break;
+ case SNDCTL_SYNTH_INFO:
+ softsyn_info.nr_voices = devc->maxvoice;
+ if (__copy_to_user(arg, &softsyn_info, sizeof(softsyn_info)))
+ return -EFAULT;
+ return 0;
- default:
- return -EINVAL;
- }
+ case SNDCTL_SEQ_RESETSAMPLES:
+ stop_engine(devc);
+ reset_samples(devc);
+ return 0;
+
+ case SNDCTL_SYNTH_MEMAVL:
+ return devc->ram_size - devc->ram_used;
+ default:
+ return -EINVAL;
+ }
}
static int
@@ -994,19 +983,19 @@ softsyn_start_note(int dev, int voice, int note, int volume)
return 0;
}
-static int
-softsyn_open(int synthdev, int mode)
+static int softsyn_open(int synthdev, int mode)
{
int err;
extern int softoss_dev;
int frags = 0x7fff0007; /* fragment size of 128 bytes */
+ mm_segment_t fs;
if (devc->audio_opened) /* Already opened */
return 0;
softsynth_disabled = 0;
- devc->finfo.mode = OPEN_WRITE;
- devc->finfo.flags = 0;
+ devc->finfo.f_mode = FMODE_WRITE;
+ devc->finfo.f_flags = 0;
if (softoss_dev >= num_audiodevs)
softoss_dev = num_audiodevs - 1;
@@ -1035,8 +1024,11 @@ 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);
dma_ioctl(devc->audiodev, SNDCTL_DSP_GETBLKSIZE, (caddr_t) & devc->fragsize);
+ set_fs(fs);
if (devc->bits != 16 || devc->channels != 2)
{
@@ -1055,14 +1047,18 @@ softsyn_open(int synthdev, int mode)
return 0;
}
-static void
-softsyn_close(int synthdev)
+static void softsyn_close(int synthdev)
{
+ mm_segment_t fs;
+
devc->engine_state = ES_STOPPED;
#ifdef POLLED_MODE
- del_timer(&poll_timer);;
+ del_timer(&poll_timer);
#endif
+ fs = get_fs();
+ set_fs(get_ds());
dma_ioctl(devc->audiodev, SNDCTL_DSP_RESET, 0);
+ set_fs(fs);
if (devc->audio_opened)
audio_release((devc->audiodev << 4) | SND_DEV_DSP16, &devc->finfo);
devc->audio_opened = 0;
@@ -1509,14 +1505,14 @@ probe_softsyn(struct address_info *hw_config)
devc->bits = 16;
devc->max_playahead = 32;
-#ifdef SOFTOSS_RATE
- devc->speed = SOFTOSS_RATE;
+#ifdef CONFIG_SOFTOSS_RATE
+ devc->speed = CONFIG_SOFTOSS_RATE;
#else
devc->speed = 32000;
#endif
-#ifdef SOFTOSS_VOICES
- devc->default_max_voices = SOFTOSS_VOICES;
+#ifdef CONFIG_SOFTOSS_VOICES
+ devc->default_max_voices = CONFIG_SOFTOSS_VOICES;
#else
devc->default_max_voices = 32;
#endif
diff --git a/drivers/sound/softoss.h b/drivers/sound/softoss.h
index f0b07e8d0..42dab13dc 100644
--- a/drivers/sound/softoss.h
+++ b/drivers/sound/softoss.h
@@ -105,7 +105,7 @@ typedef struct softsyn_devc
int bits;
int default_max_voices;
int max_playahead;
- struct fileinfo finfo;
+ struct file finfo;
int fragsize;
int samples_per_fragment;
@@ -119,7 +119,7 @@ typedef struct softsyn_devc
/*
* Programs
*/
- int programs[MAX_SAMPLE];
+ int programs[MAX_PATCH];
/*
* Timer parameters
diff --git a/drivers/sound/sound_calls.h b/drivers/sound/sound_calls.h
index 829cfcf91..aed677c89 100644
--- a/drivers/sound/sound_calls.h
+++ b/drivers/sound/sound_calls.h
@@ -22,7 +22,7 @@ int DMAbuf_space_in_queue (int dev);
int DMAbuf_activate_recording (int dev, struct dma_buffparms *dmap);
int DMAbuf_get_buffer_pointer (int dev, struct dma_buffparms *dmap, int direction);
void DMAbuf_launch_output(int dev, struct dma_buffparms *dmap);
-int DMAbuf_select(int dev, struct fileinfo *file, int sel_type, poll_table * wait);
+unsigned int DMAbuf_poll(struct file *file, int dev, poll_table *wait);
void DMAbuf_start_devices(unsigned int devmask);
void DMAbuf_reset (int dev);
int DMAbuf_sync (int dev);
@@ -31,15 +31,13 @@ int DMAbuf_sync (int dev);
* System calls for /dev/dsp and /dev/audio (audio.c)
*/
-int audio_read (int dev, struct fileinfo *file, char *buf, int count);
-int audio_write (int dev, struct fileinfo *file, const char *buf, int count);
-int audio_open (int dev, struct fileinfo *file);
-void audio_release (int dev, struct fileinfo *file);
-int audio_ioctl (int dev, struct fileinfo *file,
+int audio_read (int dev, struct file *file, char *buf, int count);
+int audio_write (int dev, struct file *file, const char *buf, int count);
+int audio_open (int dev, struct file *file);
+void audio_release (int dev, struct file *file);
+int audio_ioctl (int dev, struct file *file,
unsigned int cmd, caddr_t arg);
void audio_init_devices (void);
-
-int audio_select(int dev, struct fileinfo *file, int sel_type, poll_table * wait);
void reorganize_buffers (int dev, struct dma_buffparms *dmap, int recording);
int dma_ioctl (int dev, unsigned int cmd, caddr_t arg);
@@ -47,15 +45,15 @@ int dma_ioctl (int dev, unsigned int cmd, caddr_t arg);
* System calls for the /dev/sequencer
*/
-int sequencer_read (int dev, struct fileinfo *file, char *buf, int count);
-int sequencer_write (int dev, struct fileinfo *file, const char *buf, int count);
-int sequencer_open (int dev, struct fileinfo *file);
-void sequencer_release (int dev, struct fileinfo *file);
-int sequencer_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, caddr_t arg);
-int sequencer_select(int dev, struct fileinfo *file, int sel_type, poll_table * wait);
+int sequencer_read (int dev, struct file *file, char *buf, int count);
+int sequencer_write (int dev, struct file *file, const char *buf, int count);
+int sequencer_open (int dev, struct file *file);
+void sequencer_release (int dev, struct file *file);
+int sequencer_ioctl (int dev, struct file *file, unsigned int cmd, caddr_t arg);
+unsigned int sequencer_poll(int dev, struct file *file, poll_table * wait);
void sequencer_init (void);
+void sequencer_unload (void);
void sequencer_timer(unsigned long dummy);
int note_to_freq(int note_num);
unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
@@ -67,13 +65,13 @@ void seq_copy_to_input (unsigned char *event, int len);
* System calls for the /dev/midi
*/
-int MIDIbuf_read (int dev, struct fileinfo *file, char *buf, int count);
-int MIDIbuf_write (int dev, struct fileinfo *file, const char *buf, int count);
-int MIDIbuf_open (int dev, struct fileinfo *file);
-void MIDIbuf_release (int dev, struct fileinfo *file);
-int MIDIbuf_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, caddr_t arg);
-int MIDIbuf_select(int dev, struct fileinfo *file, int sel_type, poll_table * wait);
+int MIDIbuf_read (int dev, struct file *file, char *buf, int count);
+int MIDIbuf_write (int dev, struct file *file, const char *buf, int count);
+int MIDIbuf_open (int dev, struct file *file);
+void MIDIbuf_release (int dev, struct file *file);
+int MIDIbuf_ioctl (int dev, struct file *file, unsigned int cmd, caddr_t arg);
+unsigned int MIDIbuf_poll(int dev, struct file *file, poll_table * wait);
+int MIDIbuf_avail(int dev);
void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
void MIDIbuf_init(void);
@@ -84,9 +82,6 @@ void MIDIbuf_init(void);
*/
/* From soundcard.c */
-#if !defined(__bsdi__) && !defined(__NjetBSD__)
-void tenmicrosec(int *osp);
-#endif
void request_sound_timer (int count);
void sound_stop_timer(void);
int snd_set_irq_handler (int interrupt_level, void(*iproc)(int, void*, struct pt_regs *), char *name, int *osp);
@@ -98,14 +93,6 @@ 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 sound_switch.c */
-int sound_read_sw (int dev, struct fileinfo *file, char *buf, int count);
-int sound_write_sw (int dev, struct fileinfo *file, const char *buf, int count);
-int sound_open_sw (int dev, struct fileinfo *file);
-void sound_release_sw (int dev, struct fileinfo *file);
-int sound_ioctl_sw (int dev, struct fileinfo *file,
- unsigned int cmd, caddr_t arg);
-
/* From opl3.c */
int opl3_detect (int ioaddr, int *osp);
int opl3_init(int ioaddr, int *osp);
@@ -286,3 +273,8 @@ void attach_cs4232_mpu (struct address_info *hw_config);
void attach_maui(struct address_info * hw_config);
int probe_maui(struct address_info *hw_config);
+/* From v_midi.c */
+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);
+
diff --git a/drivers/sound/sound_config.h b/drivers/sound/sound_config.h
index 9ca2f3d8a..d158a48ff 100644
--- a/drivers/sound/sound_config.h
+++ b/drivers/sound/sound_config.h
@@ -10,17 +10,14 @@
* for more info.
*/
-
+#include <linux/fs.h>
#include "local.h.master"
-
+#include <linux/config.h>
#include "os.h"
#include "soundvers.h"
-
-
-
#ifndef SND_DEFAULT_ENABLE
#define SND_DEFAULT_ENABLE 1
#endif
@@ -43,20 +40,20 @@
#define FM_MONO 0x388 /* This is the I/O address used by AdLib */
-#ifndef PAS_BASE
-#define PAS_BASE 0x388
+#ifndef CONFIG_PAS_BASE
+#define CONFIG_PAS_BASE 0x388
#endif
-#if defined(SB16_DMA) && !defined(SB_DMA2)
-# define SB_DMA2 SB16_DMA
+#if defined(CONFIG_SB16_DMA) && !defined(CONFIG_SB_DMA2)
+# define CONFIG_SB_DMA2 CONFIG_SB16_DMA
#endif
-#if defined(SB16MIDI_BASE) && !defined(SB_MPU_BASE)
-# define SB_MPU_BASE SB16MIDI_BASE
+#if defined(SB16MIDI_BASE) && !defined(CONFIG_SB_MPU_BASE)
+# define CONFIG_SB_MPU_BASE SB16MIDI_BASE
#endif
-#ifndef SB_MPU_IRQ
-# define SB_MPU_IRQ SBC_IRQ
+#ifndef CONFIG_SB_MPU_IRQ
+# define CONFIG_SB_MPU_IRQ CONFIG_SB_IRQ
#endif
/* SEQ_MAX_QUEUE is the maximum number of sequencer events buffered by the
@@ -91,21 +88,12 @@
#define DSP_DEFAULT_SPEED 8000
-#define ON 1
-#define OFF 0
-
#define MAX_AUDIO_DEV 5
#define MAX_MIXER_DEV 5
#define MAX_SYNTH_DEV 5
#define MAX_MIDI_DEV 6
#define MAX_TIMER_DEV 4
-struct fileinfo {
- int mode; /* Open mode */
- int flags;
- int dummy; /* Reference to file-flags. OS-dependent. */
- };
-
struct address_info {
int io_base;
int irq;
@@ -154,6 +142,24 @@ struct channel_info {
#define OPEN_WRITE PCM_ENABLE_OUTPUT
#define OPEN_READWRITE (OPEN_READ|OPEN_WRITE)
+#if OPEN_READ == FMODE_READ && OPEN_WRITE == FMODE_WRITE
+
+extern __inline__ int translate_mode(struct file *file)
+{
+ return file->f_mode;
+}
+
+#else
+
+extern __inline__ int translate_mode(struct file *file)
+{
+ return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) |
+ ((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0);
+}
+
+#endif
+
+
#include "sound_calls.h"
#include "dev_table.h"
@@ -175,7 +181,3 @@ struct channel_info {
#define TIMER_ARMED 121234
#define TIMER_NOT_ARMED 1
-
-
-
-
diff --git a/drivers/sound/sound_firmware.c b/drivers/sound/sound_firmware.c
index c7c8091c2..cc566e497 100644
--- a/drivers/sound/sound_firmware.c
+++ b/drivers/sound/sound_firmware.c
@@ -6,7 +6,6 @@
#include <asm/uaccess.h>
static int errno;
-
static int do_mod_firmware_load(const char *fn, char **fp)
{
int fd;
diff --git a/drivers/sound/sound_switch.c b/drivers/sound/sound_switch.c
deleted file mode 100644
index 8e8c553bf..000000000
--- a/drivers/sound/sound_switch.c
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- * sound/sound_switch.c
- *
- * The system call switch handler
- */
-/*
- * 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 "sound_config.h"
-
-static int in_use = 0; /* Total # of open devices */
-unsigned long seq_time = 0; /* Time for /dev/sequencer */
-
-/*
- * Table for configurable mixer volume handling
- */
-static mixer_vol_table mixer_vols[MAX_MIXER_DEV];
-static int num_mixer_volumes = 0;
-
-/*
- * /dev/sndstatus -device
- */
-static char *status_buf = NULL;
-static int status_len, status_ptr;
-static int status_busy = 0;
-
-int
- *
-load_mixer_volumes(char *name, int *levels, int present)
-{
- int i, n;
-
- for (i = 0; i < num_mixer_volumes; i++)
- if (strcmp(name, mixer_vols[i].name) == 0)
- {
- if (present)
- mixer_vols[i].num = i;
- return mixer_vols[i].levels;
- }
- if (num_mixer_volumes >= MAX_MIXER_DEV)
- {
- printk("Sound: Too many mixers (%s)\n", name);
- return levels;
- }
- n = num_mixer_volumes++;
-
- strcpy(mixer_vols[n].name, name);
-
- if (present)
- mixer_vols[n].num = n;
- else
- mixer_vols[n].num = -1;
-
- for (i = 0; i < 32; i++)
- mixer_vols[n].levels[i] = levels[i];
- return mixer_vols[n].levels;
-}
-
-static int
-set_mixer_levels(caddr_t arg)
-{
- mixer_vol_table *buf = NULL;
- int err = 0;
-
- if ((buf = (mixer_vol_table *) vmalloc(sizeof(mixer_vol_table))) == NULL)
- return -ENOSPC;
-
- memcpy((char *) buf, (&((char *) arg)[0]), sizeof(*buf));
-
- load_mixer_volumes(buf->name, buf->levels, 0);
-
- memcpy((&((char *) arg)[0]), (char *) buf, sizeof(*buf));
- vfree(buf);
-
- return err;
-}
-
-static int
-get_mixer_levels(caddr_t arg)
-{
- mixer_vol_table *buf = NULL;
- int n, err = 0;
-
- if ((buf = (mixer_vol_table *) vmalloc(sizeof(mixer_vol_table))) == NULL)
- return -ENOSPC;
-
- memcpy((char *) buf, (&((char *) arg)[0]), sizeof(*buf));
-
- n = buf->num;
- if (n < 0 || n >= num_mixer_volumes)
- err = -EINVAL;
- else
- {
- memcpy((char *) buf, (char *) &mixer_vols[n], sizeof(*buf));
- }
-
- memcpy((&((char *) arg)[0]), (char *) buf, sizeof(*buf));
- vfree(buf);
-
- return err;
-}
-
-static int
-put_status(char *s)
-{
- int l = strlen(s);
-
- if (status_len + l >= 4000)
- return 0;
-
- memcpy(&status_buf[status_len], s, l);
- status_len += l;
-
- return 1;
-}
-
-static int
-put_status_int(unsigned int val, int radix)
-{
- int l, v;
-
- static char hx[] = "0123456789abcdef";
- char buf[11];
-
- if (!val)
- return put_status("0");
-
- l = 0;
- buf[10] = 0;
-
- while (val)
- {
- v = val % radix;
- val = val / radix;
-
- buf[9 - l] = hx[v];
- l++;
- }
-
- if (status_len + l >= 4000)
- return 0;
-
- memcpy(&status_buf[status_len], &buf[10 - l], l);
- status_len += l;
-
- return 1;
-}
-
-static void
-init_status(void)
-{
- /*
- * Write the status information to the status_buf and update status_len.
- * There is a limit of 4000 bytes for the data.
- */
-
- int i;
-
- status_ptr = 0;
-
-#ifdef SOUND_UNAME_A
- put_status("OSS/Free" SOUND_VERSION_STRING
- " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY ",\n"
- SOUND_UNAME_A ")"
- "\n");
-#else
- put_status("OSS/Free:" SOUND_VERSION_STRING
-#if 0
- " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY "@"
- SOUND_CONFIG_HOST "." SOUND_CONFIG_DOMAIN ")"
-#endif
- "\n");
-#endif
-
-#ifdef MODULE
- put_status("Load type: Driver loaded as a module.\n");
-#else
- put_status("Load type: Driver compiled into kernel\n");
-#endif
- put_status("Kernel: ");
- put_status(system_utsname.sysname);
- put_status(" ");
- put_status(system_utsname.nodename);
- put_status(" ");
- put_status(system_utsname.release);
- put_status(" ");
- put_status(system_utsname.version);
- put_status(" ");
- put_status(system_utsname.machine);
- put_status("\n");
-
-
- if (!put_status("Config options: "))
- return;
- if (!put_status_int(SELECTED_SOUND_OPTIONS, 16))
- return;
-
- if (!put_status("\n\nInstalled drivers: \n"))
- return;
-
- for (i = 0; i < num_sound_drivers; i++)
- if (sound_drivers[i].card_type != 0)
- {
- if (!put_status("Type "))
- return;
- if (!put_status_int(sound_drivers[i].card_type, 10))
- return;
- if (!put_status(": "))
- return;
- if (!put_status(sound_drivers[i].name))
- return;
-
- if (!put_status("\n"))
- return;
- }
- if (!put_status("\nCard config: \n"))
- return;
-
- for (i = 0; i < num_sound_cards; i++)
- if (snd_installed_cards[i].card_type != 0)
- {
- int drv, tmp;
-
- if (!snd_installed_cards[i].enabled)
- if (!put_status("("))
- return;
-
- /*
- * if (!put_status_int(snd_installed_cards[i].card_type, 10)) return;
- * if (!put_status (": ")) return;
- */
-
- if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) != -1)
- if (!put_status(sound_drivers[drv].name))
- return;
-
- if (snd_installed_cards[i].config.io_base)
- {
- if (!put_status(" at 0x"))
- return;
- if (!put_status_int(snd_installed_cards[i].config.io_base, 16))
- return;
- }
- tmp = snd_installed_cards[i].config.irq;
- if (tmp != 0)
- {
- if (!put_status(" irq "))
- return;
- if (tmp < 0)
- tmp = -tmp;
- if (!put_status_int(tmp, 10))
- return;
- }
- if (snd_installed_cards[i].config.dma != -1)
- {
- if (!put_status(" drq "))
- return;
- if (!put_status_int(snd_installed_cards[i].config.dma, 10))
- return;
- if (snd_installed_cards[i].config.dma2 != -1)
- {
- if (!put_status(","))
- return;
- if (!put_status_int(snd_installed_cards[i].config.dma2, 10))
- return;
- }
- }
- if (!snd_installed_cards[i].enabled)
- if (!put_status(")"))
- return;
-
- if (!put_status("\n"))
- return;
- }
- if (!sound_started)
- {
- put_status("\n\n***** Sound driver not started *****\n\n");
- return;
- }
-#ifndef CONFIG_AUDIO
- if (!put_status("\nAudio devices: NOT ENABLED IN CONFIG\n"))
- return;
-#else
- if (!put_status("\nAudio devices:\n"))
- return;
-
- for (i = 0; i < num_audiodevs; i++)
- {
- if (audio_devs[i] == NULL)
- continue;
- if (!put_status_int(i, 10))
- return;
- if (!put_status(": "))
- return;
- if (!put_status(audio_devs[i]->name))
- return;
-
- if (audio_devs[i]->flags & DMA_DUPLEX)
- if (!put_status(" (DUPLEX)"))
- return;
-
- if (!put_status("\n"))
- return;
- }
-#endif
-
-#ifndef CONFIG_SEQUENCER
- if (!put_status("\nSynth devices: NOT ENABLED IN CONFIG\n"))
- return;
-#else
- if (!put_status("\nSynth devices:\n"))
- return;
-
- for (i = 0; i < num_synths; i++)
- {
- if (synth_devs[i] == NULL)
- continue;
- if (!put_status_int(i, 10))
- return;
- if (!put_status(": "))
- return;
- if (!put_status(synth_devs[i]->info->name))
- return;
- if (!put_status("\n"))
- return;
- }
-#endif
-
-#ifndef CONFIG_MIDI
- if (!put_status("\nMidi devices: NOT ENABLED IN CONFIG\n"))
- return;
-#else
- if (!put_status("\nMidi devices:\n"))
- return;
-
- for (i = 0; i < num_midis; i++)
- {
- if (midi_devs[i] == NULL)
- continue;
- if (!put_status_int(i, 10))
- return;
- if (!put_status(": "))
- return;
- if (!put_status(midi_devs[i]->info.name))
- return;
- if (!put_status("\n"))
- return;
- }
-#endif
-
-#ifdef CONFIG_SEQUENCER
- if (!put_status("\nTimers:\n"))
- return;
-
- for (i = 0; i < num_sound_timers; i++)
- {
- if (sound_timer_devs[i] == NULL)
- continue;
- if (!put_status_int(i, 10))
- return;
- if (!put_status(": "))
- return;
- if (!put_status(sound_timer_devs[i]->info.name))
- return;
- if (!put_status("\n"))
- return;
- }
-#endif
-
- if (!put_status("\nMixers:\n"))
- return;
-
- for (i = 0; i < num_mixers; i++)
- {
- if (mixer_devs[i] == NULL)
- continue;
- if (!put_status_int(i, 10))
- return;
- if (!put_status(": "))
- return;
- if (!put_status(mixer_devs[i]->name))
- return;
- if (!put_status("\n"))
- return;
- }
-}
-
-static int
-read_status(char *buf, int count)
-{
- /*
- * Return at most 'count' bytes from the status_buf.
- */
- int l, c;
-
- l = count;
- c = status_len - status_ptr;
-
- if (l > c)
- l = c;
- if (l <= 0)
- return 0;
-
- {
- char *fixit = &status_buf[status_ptr];
-
- copy_to_user(&(buf)[0], fixit, l);
- };
- status_ptr += l;
-
- return l;
-}
-
-int
-sound_read_sw(int dev, struct fileinfo *file, char *buf, int count)
-{
- DEB(printk("sound_read_sw(dev=%d, count=%d)\n", dev, count));
-
- switch (dev & 0x0f)
- {
- case SND_DEV_STATUS:
- return read_status(buf, count);
- break;
-
-#ifdef CONFIG_AUDIO
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- return audio_read(dev, file, buf, count);
- break;
-#endif
-
-#ifdef CONFIG_SEQUENCER
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- return sequencer_read(dev, file, buf, count);
- break;
-#endif
-
-#ifdef CONFIG_MIDI
- case SND_DEV_MIDIN:
- return MIDIbuf_read(dev, file, buf, count);
-#endif
-
- default:;
- }
-
- return -EINVAL;
-}
-
-int
-sound_write_sw(int dev, struct fileinfo *file, const char *buf, int count)
-{
-
- DEB(printk("sound_write_sw(dev=%d, count=%d)\n", dev, count));
-
-
- switch (dev & 0x0f)
- {
-
-#ifdef CONFIG_SEQUENCER
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- return sequencer_write(dev, file, buf, count);
- break;
-#endif
-
-#ifdef CONFIG_AUDIO
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- return audio_write(dev, file, buf, count);
- break;
-#endif
-
-#ifdef CONFIG_MIDI
- case SND_DEV_MIDIN:
- return MIDIbuf_write(dev, file, buf, count);
-#endif
-
- }
-
- return -EINVAL;
-}
-
-int
-sound_open_sw(int dev, struct fileinfo *file)
-{
- int retval;
-
- DEB(printk("sound_open_sw(dev=%d)\n", dev));
-
- if ((dev >= SND_NDEVS) || (dev < 0))
- {
- printk("Invalid minor device %d\n", dev);
- return -ENXIO;
- }
- switch (dev & 0x0f)
- {
- case SND_DEV_STATUS:
- if (status_busy)
- return -EBUSY;
- status_busy = 1;
- if ((status_buf = (char *) vmalloc(4000)) == NULL)
- {
- status_busy = 0;
- return -EIO;
- }
- status_len = status_ptr = 0;
- init_status();
- break;
-
- case SND_DEV_CTL:
- if ((dev & 0xf0) && ((dev & 0xf0) >> 4) >= num_mixers)
- return -ENXIO;
- return 0;
- break;
-
-#ifdef CONFIG_SEQUENCER
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- if ((retval = sequencer_open(dev, file)) < 0)
- return retval;
- break;
-#endif
-
-#ifdef CONFIG_MIDI
- case SND_DEV_MIDIN:
- if ((retval = MIDIbuf_open(dev, file)) < 0)
- return retval;
- break;
-#endif
-
-#ifdef CONFIG_AUDIO
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- if ((retval = audio_open(dev, file)) < 0)
- return retval;
- break;
-#endif
-
- default:
- printk("Invalid minor device %d\n", dev);
- return -ENXIO;
- }
-
- in_use++;
-
- return 0;
-}
-
-void
-sound_release_sw(int dev, struct fileinfo *file)
-{
-
- DEB(printk("sound_release_sw(dev=%d)\n", dev));
-
- switch (dev & 0x0f)
- {
- case SND_DEV_STATUS:
- if (status_buf)
- vfree(status_buf);
- status_buf = NULL;
- status_busy = 0;
- break;
-
- case SND_DEV_CTL:
- break;
-
-#ifdef CONFIG_SEQUENCER
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- sequencer_release(dev, file);
- break;
-#endif
-
-#ifdef CONFIG_MIDI
- case SND_DEV_MIDIN:
- MIDIbuf_release(dev, file);
- break;
-#endif
-
-#ifdef CONFIG_AUDIO
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- audio_release(dev, file);
- break;
-#endif
-
- default:
- printk("Sound error: Releasing unknown device 0x%02x\n", dev);
- }
- in_use--;
-}
-
-static int
-get_mixer_info(int dev, caddr_t arg)
-{
- mixer_info info;
- int i;
-
- if (dev < 0 || dev >= num_mixers)
- return -ENXIO;
-
- strcpy(info.id, mixer_devs[dev]->id);
- for (i = 0; i < 32 && mixer_devs[dev]->name; i++)
- info.name[i] = mixer_devs[dev]->name[i];
- info.name[i] = 0;
- info.modify_counter = mixer_devs[dev]->modify_counter;
-
- memcpy((&((char *) arg)[0]), (char *) &info, sizeof(info));
- return 0;
-}
-
-static int
-get_old_mixer_info(int dev, caddr_t arg)
-{
- _old_mixer_info info;
- int i;
-
- if (dev < 0 || dev >= num_mixers)
- return -ENXIO;
-
- strcpy(info.id, mixer_devs[dev]->id);
- for (i = 0; i < 32 && mixer_devs[dev]->name; i++)
- info.name[i] = mixer_devs[dev]->name[i];
- info.name[i] = 0;
-
- memcpy((&((char *) arg)[0]), (char *) &info, sizeof(info));
- return 0;
-}
-
-static int
-sound_mixer_ioctl(int mixdev,
- unsigned int cmd, caddr_t arg)
-{
- if (cmd == SOUND_MIXER_INFO)
- return get_mixer_info(mixdev, arg);
- if (cmd == SOUND_OLD_MIXER_INFO)
- return get_old_mixer_info(mixdev, arg);
-
- if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- mixer_devs[mixdev]->modify_counter++;
-
- return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg);
-}
-
-int
-sound_ioctl_sw(int dev, struct fileinfo *file,
- unsigned int cmd, caddr_t arg)
-{
- DEB(printk("sound_ioctl_sw(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
-
- if (cmd == OSS_GETVERSION)
- return (*(int *) arg = SOUND_VERSION);
-
-
- if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0) /* Mixer ioctl */
- if ((dev & 0x0f) != SND_DEV_CTL)
- {
- int dtype = dev & 0x0f;
- int mixdev;
-
- switch (dtype)
- {
-#ifdef CONFIG_AUDIO
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- mixdev = audio_devs[dev >> 4]->mixer_dev;
- if (mixdev < 0 || mixdev >= num_mixers)
- return -ENXIO;
- return sound_mixer_ioctl(mixdev, cmd, arg);
- break;
-#endif
-
- default:
- return sound_mixer_ioctl(dev, cmd, arg);
- }
- }
- switch (dev & 0x0f)
- {
-
- case SND_DEV_CTL:
- if (cmd == SOUND_MIXER_GETLEVELS)
- return get_mixer_levels(arg);
- if (cmd == SOUND_MIXER_SETLEVELS)
- return set_mixer_levels(arg);
-
- if (!num_mixers)
- return -ENXIO;
-
- dev = dev >> 4;
-
- if (dev >= num_mixers)
- return -ENXIO;
-
- return sound_mixer_ioctl(dev, cmd, arg);
- break;
-
-#ifdef CONFIG_SEQUENCER
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- return sequencer_ioctl(dev, file, cmd, arg);
- break;
-#endif
-
-#ifdef CONFIG_AUDIO
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- return audio_ioctl(dev, file, cmd, arg);
- break;
-#endif
-
-#ifdef CONFIG_MIDI
- case SND_DEV_MIDIN:
- return MIDIbuf_ioctl(dev, file, cmd, arg);
- break;
-#endif
-
- }
-
- return -EINVAL;
-}
diff --git a/drivers/sound/sound_syms.c b/drivers/sound/sound_syms.c
index 2b80bd165..648a769a4 100644
--- a/drivers/sound/sound_syms.c
+++ b/drivers/sound/sound_syms.c
@@ -5,7 +5,6 @@
* (C) Copyright 1997 Alan Cox, Licensed under the GNU GPL
*/
-#include <linux/config.h>
#include <linux/module.h>
#include "sound_config.h"
#define _MIDI_SYNTH_C_
@@ -14,14 +13,18 @@
#include "sound_firmware.h"
extern struct notifier_block *sound_locker;
+extern void sound_notifier_chain_register(struct notifier_block *);
+
EXPORT_SYMBOL(mixer_devs);
EXPORT_SYMBOL(audio_devs);
+EXPORT_SYMBOL(num_mixers);
EXPORT_SYMBOL(num_audiodevs);
EXPORT_SYMBOL(note_to_freq);
EXPORT_SYMBOL(compute_finetune);
EXPORT_SYMBOL(seq_copy_to_input);
+EXPORT_SYMBOL(sequencer_init);
EXPORT_SYMBOL(sequencer_timer);
EXPORT_SYMBOL(sound_install_audiodrv);
@@ -35,17 +38,25 @@ 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);
EXPORT_SYMBOL(sound_unload_timerdev);
EXPORT_SYMBOL(sound_unload_synthdev);
+EXPORT_SYMBOL(load_mixer_volumes);
+
EXPORT_SYMBOL(DMAbuf_start_dma);
+EXPORT_SYMBOL(DMAbuf_open_dma);
+EXPORT_SYMBOL(DMAbuf_close_dma);
EXPORT_SYMBOL(DMAbuf_inputintr);
EXPORT_SYMBOL(DMAbuf_outputintr);
EXPORT_SYMBOL(dma_ioctl);
+EXPORT_SYMBOL(conf_printf);
EXPORT_SYMBOL(conf_printf2);
EXPORT_SYMBOL(sound_timer_init);
@@ -54,6 +65,7 @@ EXPORT_SYMBOL(sound_timer_syncinterval);
/* Locking */
EXPORT_SYMBOL(sound_locker);
+EXPORT_SYMBOL(sound_notifier_chain_register);
/* MIDI symbols */
EXPORT_SYMBOL(midi_devs);
@@ -76,3 +88,5 @@ EXPORT_SYMBOL(midi_synth_panning);
EXPORT_SYMBOL(midi_synth_setup_voice);
EXPORT_SYMBOL(midi_synth_send_sysex);
EXPORT_SYMBOL(midi_synth_bender);
+EXPORT_SYMBOL(midi_synth_load_patch);
+
diff --git a/drivers/sound/sound_timer.c b/drivers/sound/sound_timer.c
index 5fafccc42..8a519e7e2 100644
--- a/drivers/sound/sound_timer.c
+++ b/drivers/sound/sound_timer.c
@@ -1,5 +1,3 @@
-
-
/*
* sound/sound_timer.c
*/
@@ -10,6 +8,9 @@
* 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>
@@ -28,32 +29,28 @@ static volatile unsigned long usecs_per_tmr; /* Length of the current interval *
static struct sound_lowlev_timer *tmr = NULL;
-static unsigned long
-tmr2ticks(int tmr_value)
+static unsigned long tmr2ticks(int tmr_value)
{
/*
* Convert timer ticks to MIDI ticks
*/
- unsigned long tmp;
- unsigned long scale;
+ unsigned long tmp;
+ unsigned long scale;
tmp = tmr_value * usecs_per_tmr; /* Convert to usecs */
-
scale = (60 * 1000000) / (curr_tempo * curr_timebase); /* usecs per MIDI tick */
-
return (tmp + (scale / 2)) / scale;
}
-static void
-reprogram_timer(void)
+void reprogram_timer(void)
{
unsigned long usecs_per_tick;
usecs_per_tick = (60 * 1000000) / (curr_tempo * curr_timebase);
/*
- * Don't kill the system by setting too high timer rate
+ * Don't kill the system by setting too high timer rate
*/
if (usecs_per_tick < 2000)
usecs_per_tick = 2000;
@@ -61,22 +58,19 @@ reprogram_timer(void)
usecs_per_tmr = tmr->tmr_start(tmr->dev, usecs_per_tick);
}
-void
-sound_timer_syncinterval(unsigned int new_usecs)
+void sound_timer_syncinterval(unsigned int new_usecs)
{
-/*
- * This routine is called by the hardware level if
- * the clock frequency has changed for some reason.
- */
+ /*
+ * This routine is called by the hardware level if
+ * the clock frequency has changed for some reason.
+ */
tmr_offs = tmr_ctr;
ticks_offs += tmr2ticks(tmr_ctr);
tmr_ctr = 0;
-
usecs_per_tmr = new_usecs;
}
-static void
-tmr_reset(void)
+static void tmr_reset(void)
{
unsigned long flags;
@@ -91,187 +85,167 @@ tmr_reset(void)
restore_flags(flags);
}
-static int
-timer_open(int dev, int mode)
+static int timer_open(int dev, int mode)
{
if (opened)
return -EBUSY;
-
tmr_reset();
curr_tempo = 60;
curr_timebase = 100;
opened = 1;
reprogram_timer();
-
return 0;
}
-static void
-timer_close(int dev)
+static void timer_close(int dev)
{
opened = tmr_running = 0;
tmr->tmr_disable(tmr->dev);
}
-static int
-timer_event(int dev, unsigned char *event)
+static int timer_event(int dev, unsigned char *event)
{
- unsigned char cmd = event[1];
- unsigned long parm = *(int *) &event[4];
+ unsigned char cmd = event[1];
+ unsigned long parm = *(int *) &event[4];
switch (cmd)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- if (parm <= curr_ticks) /* It's the time */
- return TIMER_NOT_ARMED;
-
- time = parm;
- next_event_time = prev_event_time = time;
-
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- tmr_reset();
- tmr_running = 1;
- reprogram_timer();
- break;
-
- case TMR_STOP:
- tmr_running = 0;
- break;
-
- case TMR_CONTINUE:
- tmr_running = 1;
- reprogram_timer();
- break;
-
- case TMR_TEMPO:
- if (parm)
- {
- if (parm < 8)
- parm = 8;
- if (parm > 250)
- parm = 250;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks(tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = parm;
- reprogram_timer();
- }
- break;
-
- case TMR_ECHO:
- seq_copy_to_input(event, 8);
- break;
-
- default:;
- }
-
+ {
+ case TMR_WAIT_REL:
+ parm += prev_event_time;
+ case TMR_WAIT_ABS:
+ if (parm > 0)
+ {
+ long time;
+
+ if (parm <= curr_ticks) /* It's the time */
+ return TIMER_NOT_ARMED;
+ time = parm;
+ next_event_time = prev_event_time = time;
+ return TIMER_ARMED;
+ }
+ break;
+
+ case TMR_START:
+ tmr_reset();
+ tmr_running = 1;
+ reprogram_timer();
+ break;
+
+ case TMR_STOP:
+ tmr_running = 0;
+ break;
+
+ case TMR_CONTINUE:
+ tmr_running = 1;
+ reprogram_timer();
+ break;
+
+ case TMR_TEMPO:
+ if (parm)
+ {
+ if (parm < 8)
+ parm = 8;
+ if (parm > 250)
+ parm = 250;
+ tmr_offs = tmr_ctr;
+ ticks_offs += tmr2ticks(tmr_ctr);
+ tmr_ctr = 0;
+ curr_tempo = parm;
+ reprogram_timer();
+ }
+ break;
+
+ case TMR_ECHO:
+ seq_copy_to_input(event, 8);
+ break;
+
+ default:
+ }
return TIMER_NOT_ARMED;
}
-static unsigned long
-timer_get_time(int dev)
+static unsigned long timer_get_time(int dev)
{
if (!opened)
return 0;
-
return curr_ticks;
}
-static int
-timer_ioctl(int dev,
- unsigned int cmd, caddr_t arg)
+static int timer_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- int val;
-
- switch (cmd)
- {
- case SNDCTL_TMR_SOURCE:
- return (*(int *) arg = TMR_INTERNAL);
- break;
-
- case SNDCTL_TMR_START:
- tmr_reset();
- tmr_running = 1;
- return 0;
- break;
-
- case SNDCTL_TMR_STOP:
- tmr_running = 0;
- return 0;
- break;
-
- case SNDCTL_TMR_CONTINUE:
- tmr_running = 1;
- return 0;
- break;
-
- case SNDCTL_TMR_TIMEBASE:
- val = *(int *) arg;
-
- if (val)
- {
- if (val < 1)
- val = 1;
- if (val > 1000)
- val = 1000;
- curr_timebase = val;
- }
- return (*(int *) arg = curr_timebase);
- break;
-
- case SNDCTL_TMR_TEMPO:
- val = *(int *) arg;
-
- if (val)
- {
- if (val < 8)
- val = 8;
- if (val > 250)
- val = 250;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks(tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = val;
- reprogram_timer();
- }
- return (*(int *) arg = curr_tempo);
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- val = *(int *) arg;
-
- if (val != 0) /* Can't change */
- return -EINVAL;
-
- return (*(int *) arg = ((curr_tempo * curr_timebase) + 30) / 60);
- break;
-
- case SNDCTL_SEQ_GETTIME:
- return (*(int *) arg = curr_ticks);
- break;
-
- case SNDCTL_TMR_METRONOME:
- /* NOP */
- break;
-
- default:;
- }
-
- return -EINVAL;
+ int val;
+
+ switch (cmd)
+ {
+ case SNDCTL_TMR_SOURCE:
+ val = TMR_INTERNAL;
+ break;
+
+ case SNDCTL_TMR_START:
+ tmr_reset();
+ tmr_running = 1;
+ return 0;
+
+ case SNDCTL_TMR_STOP:
+ tmr_running = 0;
+ return 0;
+
+ case SNDCTL_TMR_CONTINUE:
+ tmr_running = 1;
+ return 0;
+
+ case SNDCTL_TMR_TIMEBASE:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val)
+ {
+ if (val < 1)
+ val = 1;
+ if (val > 1000)
+ val = 1000;
+ curr_timebase = val;
+ }
+ val = curr_timebase;
+ break;
+
+ case SNDCTL_TMR_TEMPO:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val)
+ {
+ if (val < 8)
+ val = 8;
+ if (val > 250)
+ val = 250;
+ tmr_offs = tmr_ctr;
+ ticks_offs += tmr2ticks(tmr_ctr);
+ tmr_ctr = 0;
+ curr_tempo = val;
+ reprogram_timer();
+ }
+ val = curr_tempo;
+ break;
+
+ case SNDCTL_SEQ_CTRLRATE:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val != 0) /* Can't change */
+ return -EINVAL;
+ val = ((curr_tempo * curr_timebase) + 30) / 60;
+ break;
+
+ case SNDCTL_SEQ_GETTIME:
+ val = curr_ticks;
+ break;
+
+ case SNDCTL_TMR_METRONOME:
+ default:
+ return -EINVAL;
+ }
+ return put_user(val, (int *)arg);
}
-static void
-timer_arm(int dev, long time)
+static void timer_arm(int dev, long time)
{
if (time < 0)
time = curr_ticks + 1;
@@ -279,7 +253,6 @@ timer_arm(int dev, long time)
return;
next_event_time = prev_event_time = time;
-
return;
}
@@ -296,8 +269,7 @@ static struct sound_timer_operations sound_timer =
timer_arm
};
-void
-sound_timer_interrupt(void)
+void sound_timer_interrupt(void)
{
if (!opened)
return;
@@ -311,26 +283,24 @@ sound_timer_interrupt(void)
curr_ticks = ticks_offs + tmr2ticks(tmr_ctr);
if (curr_ticks >= next_event_time)
- {
- next_event_time = (unsigned long) -1;
- sequencer_timer(0);
- }
+ {
+ next_event_time = (unsigned long) -1;
+ sequencer_timer(0);
+ }
}
-void
-sound_timer_init(struct sound_lowlev_timer *t, char *name)
+void sound_timer_init(struct sound_lowlev_timer *t, char *name)
{
- int n;
+ int n;
if (initialized)
- {
- if (t->priority <= tmr->priority)
- return; /* There is already a similar or better timer */
- tmr = t;
- return;
- }
+ {
+ if (t->priority <= tmr->priority)
+ return; /* There is already a similar or better timer */
+ tmr = t;
+ return;
+ }
initialized = 1;
-
tmr = t;
n = sound_alloc_timerdev();
diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c
index f6d17e4e8..e23e5486e 100644
--- a/drivers/sound/soundcard.c
+++ b/drivers/sound/soundcard.c
@@ -1,5 +1,5 @@
/*
- * linux/kernel/chr_drv/sound/soundcard.c
+ * linux/drivers/sound/soundcard.c
*
* Soundcard driver for Linux
*/
@@ -10,6 +10,12 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+/*
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * integrated sound_switch.c
+ * Stefan Reinauer : integrated /proc/sound (equals to /dev/sndstat,
+ * which should disappear in the near future)
+ */
#include <linux/config.h>
@@ -19,6 +25,8 @@
#include <linux/signal.h>
#include <linux/fcntl.h>
#include <linux/ctype.h>
+#include <linux/stddef.h>
+#include <linux/kerneld.h>
#ifdef __KERNEL__
#include <asm/io.h>
#include <asm/segment.h>
@@ -27,6 +35,7 @@
#include <linux/ioport.h>
#endif /* __KERNEL__ */
#include <linux/delay.h>
+#include <linux/proc_fs.h>
#define SOUND_CORE
@@ -53,8 +62,6 @@ int sound_nblocks = 0;
static int soundcard_configured = 0;
-static struct fileinfo files[SND_NDEVS];
-
static char dma_alloc_map[8] =
{0};
@@ -63,27 +70,344 @@ static char dma_alloc_map[8] =
#define DMA_MAP_BUSY 2
+static int in_use = 0; /* Total # of open devices */
+unsigned long seq_time = 0; /* Time for /dev/sequencer */
+
+/*
+ * Table for configurable mixer volume handling
+ */
+static mixer_vol_table mixer_vols[MAX_MIXER_DEV];
+static int num_mixer_volumes = 0;
+
+
+int *load_mixer_volumes(char *name, int *levels, int present)
+{
+ int i, n;
+
+ for (i = 0; i < num_mixer_volumes; i++)
+ if (strcmp(name, mixer_vols[i].name) == 0)
+ {
+ if (present)
+ mixer_vols[i].num = i;
+ return mixer_vols[i].levels;
+ }
+ if (num_mixer_volumes >= MAX_MIXER_DEV)
+ {
+ printk("Sound: Too many mixers (%s)\n", name);
+ return levels;
+ }
+ n = num_mixer_volumes++;
+
+ strcpy(mixer_vols[n].name, name);
+
+ if (present)
+ mixer_vols[n].num = n;
+ else
+ mixer_vols[n].num = -1;
+
+ for (i = 0; i < 32; i++)
+ mixer_vols[n].levels[i] = levels[i];
+ return mixer_vols[n].levels;
+}
+
+static int set_mixer_levels(caddr_t arg)
+{
+ /* mixer_vol_table is 174 bytes, so IMHO no reason to not allocate it on the stack */
+ mixer_vol_table buf;
+
+ if (__copy_from_user(&buf, arg, sizeof(buf)))
+ return -EFAULT;
+ load_mixer_volumes(buf.name, buf.levels, 0);
+ if (__copy_to_user(arg, &buf, sizeof(buf)))
+ return -EFAULT;
+ return 0;
+}
+
+static int get_mixer_levels(caddr_t arg)
+{
+ int n;
+
+ if (__get_user(n, (int *)(&(((mixer_vol_table *)arg)->num))))
+ return -EFAULT;
+ if (n < 0 || n >= num_mixer_volumes)
+ return -EINVAL;
+ if (__copy_to_user(arg, &mixer_vols[n], sizeof(mixer_vol_table)))
+ return -EFAULT;
+ return 0;
+}
+
+static int sound_proc_get_info(char *buffer, char **start, off_t offset, int length, int inout)
+{
+ int len, i, drv;
+ off_t pos = 0;
+ off_t begin = 0;
+
+#ifdef MODULE
+#define MODULEPROCSTRING "Driver loaded as a module"
+#else
+#define MODULEPROCSTRING "Driver compiled into kernel"
+#endif
+
+ len = sprintf(buffer, "OSS/Free:" SOUND_VERSION_STRING "\n"
+ "Load type: " MODULEPROCSTRING "\n"
+ "Kernel: %s %s %s %s %s\n"
+ "Config options: %x\n\nInstalled drivers: \n",
+ system_utsname.sysname, system_utsname.nodename, system_utsname.release,
+ system_utsname.version, system_utsname.machine, SELECTED_SOUND_OPTIONS);
+
+ for (i = 0; (i < num_sound_drivers) && (pos <= offset + length); i++) {
+ if (!sound_drivers[i].card_type)
+ continue;
+ len += sprintf(buffer + len, "Type %d: %s\n",
+ sound_drivers[i].card_type, sound_drivers[i].name);
+ pos = begin + len;
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ }
+ len += sprintf(buffer + len, "\nCard config: \n");
+
+ for (i = 0; (i < num_sound_cards) && (pos <= offset + length); i++) {
+ if (!snd_installed_cards[i].card_type)
+ continue;
+ if (!snd_installed_cards[i].enabled)
+ len += sprintf(buffer + len, "(");
+ if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) != -1)
+ len += sprintf(buffer + len, "%s", sound_drivers[drv].name);
+ if (snd_installed_cards[i].config.io_base)
+ len += sprintf(buffer + len, " at 0x%x", snd_installed_cards[i].config.io_base);
+ if (snd_installed_cards[i].config.irq != 0)
+ len += sprintf(buffer + len, " irq %d", abs(snd_installed_cards[i].config.irq));
+ if (snd_installed_cards[i].config.dma != -1) {
+ len += sprintf(buffer + len, " drq %d", snd_installed_cards[i].config.dma);
+ if (snd_installed_cards[i].config.dma2 != -1)
+ len += sprintf(buffer + len, ",%d", snd_installed_cards[i].config.dma2);
+ }
+ if (!snd_installed_cards[i].enabled)
+ len += sprintf(buffer + len, ")");
+ len += sprintf(buffer + len, "\n");
+ pos = begin + len;
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ }
+ if (!sound_started)
+ len += sprintf(buffer + len, "\n\n***** Sound driver not started *****\n\n");
+#ifndef CONFIG_AUDIO
+ len += sprintf(buffer + len, "\nAudio devices: NOT ENABLED IN CONFIG\n");
+#else
+ len += sprintf(buffer + len, "\nAudio devices:\n");
+ for (i = 0; (i < num_audiodevs) && (pos <= offset + length); i++) {
+ if (audio_devs[i] == NULL)
+ continue;
+ len += sprintf(buffer + len, "%d: %s%s\n", i, audio_devs[i]->name,
+ audio_devs[i]->flags & DMA_DUPLEX ? " (DUPLEX)" : "");
+ pos = begin + len;
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ }
+#endif
+
+#ifndef CONFIG_SEQUENCER
+ len += sprintf(buffer + len, "\nSynth devices: NOT ENABLED IN CONFIG\n");
+#else
+ len += sprintf(buffer + len, "\nSynth devices:\n");
+ for (i = 0; (i < num_synths) && (pos <= offset + length); i++) {
+ if (synth_devs[i] == NULL)
+ continue;
+ len += sprintf(buffer + len, "%d: %s\n", i, synth_devs[i]->info->name);
+ pos = begin + len;
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ }
+#endif
+
+#ifndef CONFIG_MIDI
+ len += sprintf(buffer + len, "\nMidi devices: NOT ENABLED IN CONFIG\n");
+#else
+ len += sprintf(buffer + len, "\nMidi devices:\n");
+ for (i = 0; (i < num_midis) && (pos <= offset + length); i++) {
+ if (midi_devs[i] == NULL)
+ continue;
+ len += sprintf(buffer + len, "%d: %s\n", i, midi_devs[i]->info.name);
+ pos = begin + len;
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ }
+#endif
+
+#ifdef CONFIG_SEQUENCER
+ len += sprintf(buffer + len, "\nTimers:\n");
+
+ for (i = 0; (i < num_sound_timers) && (pos <= offset + length); i++) {
+ if (sound_timer_devs[i] == NULL)
+ continue;
+ len += sprintf(buffer + len, "%d: %s\n", i, sound_timer_devs[i]->info.name);
+ pos = begin + len;
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ }
+#endif
+
+ len += sprintf(buffer + len, "\nMixers:\n");
+ for (i = 0; (i < num_mixers) && (pos <= offset + length); i++) {
+ if (mixer_devs[i] == NULL)
+ continue;
+ len += sprintf(buffer + len, "%d: %s\n", i, mixer_devs[i]->name);
+ pos = begin + len;
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ }
+ *start = buffer + (offset - begin);
+ len -= (offset - begin);
+ if (len > length)
+ len = length;
+ return len;
+}
+
+static struct proc_dir_entry proc_root_sound = {
+ PROC_SOUND, 5, "sound",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, NULL, sound_proc_get_info
+};
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+/* 4K page size but our output routines use some slack for overruns */
+#define PROC_BLOCK_SIZE (3*1024)
+
+/*
+ * basically copied from fs/proc/generic.c:proc_file_read
+ * should be removed sometime in the future together with /dev/sndstat
+ * (a symlink /dev/sndstat -> /proc/sound will do as well)
+ */
+static ssize_t sndstat_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+{
+ char *page;
+ ssize_t retval=0;
+ int eof=0;
+ ssize_t n, count;
+ char *start;
+
+ if (!(page = (char*) __get_free_page(GFP_KERNEL)))
+ return -ENOMEM;
+
+ while ((nbytes > 0) && !eof)
+ {
+ count = MIN(PROC_BLOCK_SIZE, nbytes);
+
+ start = NULL;
+ n = sound_proc_get_info(page, &start, *ppos, count, 0);
+ if (n < count)
+ eof = 1;
+
+ if (!start) {
+ /*
+ * For proc files that are less than 4k
+ */
+ start = page + *ppos;
+ n -= *ppos;
+ if (n <= 0)
+ break;
+ if (n > count)
+ n = count;
+ }
+ if (n == 0)
+ break; /* End of file */
+ if (n < 0) {
+ if (retval == 0)
+ retval = n;
+ break;
+ }
+
+ n -= copy_to_user(buf, start, n); /* BUG ??? */
+ if (n == 0) {
+ if (retval == 0)
+ retval = -EFAULT;
+ break;
+ }
+
+ *ppos += n; /* Move down the file */
+ nbytes -= n;
+ buf += n;
+ retval += n;
+ }
+ free_page((unsigned long) page);
+ return retval;
+}
+
static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
- int dev;
+ int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+
+ DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
+ switch (dev & 0x0f) {
+ case SND_DEV_STATUS:
+ return sndstat_file_read(file, buf, count, ppos);
- dev = MINOR(file->f_dentry->d_inode->i_rdev);
+#ifdef CONFIG_AUDIO
+ case SND_DEV_DSP:
+ case SND_DEV_DSP16:
+ case SND_DEV_AUDIO:
+ return audio_read(dev, file, buf, count);
+#endif
+
+#ifdef CONFIG_SEQUENCER
+ case SND_DEV_SEQ:
+ case SND_DEV_SEQ2:
+ return sequencer_read(dev, file, buf, count);
+#endif
- files[dev].flags = file->f_flags;
+#ifdef CONFIG_MIDI
+ case SND_DEV_MIDIN:
+ return MIDIbuf_read(dev, file, buf, count);
+#endif
- return sound_read_sw(dev, &files[dev], buf, count);
+ default:;
+ }
+ return -EINVAL;
}
static ssize_t sound_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
- int dev;
-
- dev = MINOR(file->f_dentry->d_inode->i_rdev);
+ int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+
+ DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count));
+ switch (dev & 0x0f) {
+#ifdef CONFIG_SEQUENCER
+ case SND_DEV_SEQ:
+ case SND_DEV_SEQ2:
+ return sequencer_write(dev, file, buf, count);
+#endif
- files[dev].flags = file->f_flags;
+#ifdef CONFIG_AUDIO
+ case SND_DEV_DSP:
+ case SND_DEV_DSP16:
+ case SND_DEV_AUDIO:
+ return audio_write(dev, file, buf, count);
+#endif
- return sound_write_sw(dev, &files[dev], buf, count);
+#ifdef CONFIG_MIDI
+ case SND_DEV_MIDIN:
+ return MIDIbuf_write(dev, file, buf, count);
+#endif
+ }
+ return -EINVAL;
}
static long long sound_lseek(struct file *file, long long offset, int orig)
@@ -93,170 +417,271 @@ static long long sound_lseek(struct file *file, long long offset, int orig)
static int sound_open(struct inode *inode, struct file *file)
{
- int dev, retval;
- struct fileinfo tmp_file;
+ int dev, retval;
- if (is_unloading)
- {
-/* printk(KERN_ERR "Sound: Driver partially removed. Can't open device\n");*/
- return -EBUSY;
+ if (is_unloading) {
+ /* printk(KERN_ERR "Sound: Driver partially removed. Can't open device\n");*/
+ return -EBUSY;
}
dev = MINOR(inode->i_rdev);
-
- if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
- {
-/* printk("SoundCard Error: The soundcard system has not been configured\n");*/
- return -ENXIO;
+ if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS) {
+ /* printk("SoundCard Error: The soundcard system has not been configured\n");*/
+ return -ENXIO;
+ }
+ DEB(printk("sound_open(dev=%d)\n", dev));
+ if ((dev >= SND_NDEVS) || (dev < 0)) {
+ printk(KERN_ERR "Invalid minor device %d\n", dev);
+ return -ENXIO;
}
- tmp_file.mode = 0;
- tmp_file.flags = file->f_flags;
+ switch (dev & 0x0f) {
+ case SND_DEV_STATUS:
+ break;
+
+ case SND_DEV_CTL:
+ dev >>= 4;
+#ifdef CONFIG_KERNELD
+ if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) {
+ char modname[20];
+ sprintf(modname, "mixer%d", dev);
+ request_module(modname);
+ }
+#endif
+ if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL))
+ return -ENXIO;
+ break;
+
+#ifdef CONFIG_SEQUENCER
+ case SND_DEV_SEQ:
+ case SND_DEV_SEQ2:
+ if ((retval = sequencer_open(dev, file)) < 0)
+ return retval;
+ break;
+#endif
- if ((tmp_file.flags & O_ACCMODE) == O_RDWR)
- tmp_file.mode = OPEN_READWRITE;
- if ((tmp_file.flags & O_ACCMODE) == O_RDONLY)
- tmp_file.mode = OPEN_READ;
- if ((tmp_file.flags & O_ACCMODE) == O_WRONLY)
- tmp_file.mode = OPEN_WRITE;
+#ifdef CONFIG_MIDI
+ case SND_DEV_MIDIN:
+ if ((retval = MIDIbuf_open(dev, file)) < 0)
+ return retval;
+ break;
+#endif
- if ((retval = sound_open_sw(dev, &tmp_file)) < 0)
- return retval;
+#ifdef CONFIG_AUDIO
+ case SND_DEV_DSP:
+ case SND_DEV_DSP16:
+ case SND_DEV_AUDIO:
+ if ((retval = audio_open(dev, file)) < 0)
+ return retval;
+ break;
+#endif
+ default:
+ printk(KERN_ERR "Invalid minor device %d\n", dev);
+ return -ENXIO;
+ }
+ in_use++;
#ifdef MODULE
SOUND_INC_USE_COUNT;
#endif
-
- memcpy((char *) &files[dev], (char *) &tmp_file, sizeof(tmp_file));
- return retval;
+ return 0;
}
static int sound_release(struct inode *inode, struct file *file)
{
- int dev;
+ int dev = MINOR(inode->i_rdev);
+
+ DEB(printk("sound_release(dev=%d)\n", dev));
+ switch (dev & 0x0f) {
+ case SND_DEV_STATUS:
+ case SND_DEV_CTL:
+ break;
+
+#ifdef CONFIG_SEQUENCER
+ case SND_DEV_SEQ:
+ case SND_DEV_SEQ2:
+ sequencer_release(dev, file);
+ break;
+#endif
- dev = MINOR(inode->i_rdev);
+#ifdef CONFIG_MIDI
+ case SND_DEV_MIDIN:
+ MIDIbuf_release(dev, file);
+ break;
+#endif
- files[dev].flags = file->f_flags;
+#ifdef CONFIG_AUDIO
+ case SND_DEV_DSP:
+ case SND_DEV_DSP16:
+ case SND_DEV_AUDIO:
+ audio_release(dev, file);
+ break;
+#endif
- sound_release_sw(dev, &files[dev]);
+ default:
+ printk(KERN_ERR "Sound error: Releasing unknown device 0x%02x\n", dev);
+ }
+ in_use--;
#ifdef MODULE
SOUND_DEC_USE_COUNT;
#endif
return 0;
}
-static int sound_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int get_mixer_info(int dev, caddr_t arg)
{
- int dev, err;
- int len = 0;
- int alloced = 0;
- char *ptr = (char *) arg;
+ mixer_info info;
+
+ strncpy(info.id, mixer_devs[dev]->id, sizeof(info.id));
+ strncpy(info.name, mixer_devs[dev]->name, sizeof(info.name));
+ info.name[sizeof(info.name)-1] = 0;
+ info.modify_counter = mixer_devs[dev]->modify_counter;
+ if (__copy_to_user(arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+}
- dev = MINOR(inode->i_rdev);
+static int get_old_mixer_info(int dev, caddr_t arg)
+{
+ _old_mixer_info info;
+
+ strncpy(info.id, mixer_devs[dev]->id, sizeof(info.id));
+ strncpy(info.name, mixer_devs[dev]->name, sizeof(info.name));
+ info.name[sizeof(info.name)-1] = 0;
+ if (copy_to_user(arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+}
+
+static int sound_mixer_ioctl(int mixdev, unsigned int cmd, caddr_t arg)
+{
+ if (mixdev < 0 || mixdev >= MAX_MIXER_DEV)
+ return -ENXIO;
+#ifdef CONFIG_KERNELD
+ /* Try to load the mixer... */
+ if (mixer_devs[mixdev] == NULL) {
+ char modname[20];
+ sprintf(modname, "mixer%d", mixdev);
+ request_module(modname);
+ }
+#endif /* CONFIG_KERNELD */
+ if (mixdev >= num_mixers || !mixer_devs[mixdev])
+ return -ENXIO;
+ if (cmd == SOUND_MIXER_INFO)
+ return get_mixer_info(mixdev, arg);
+ if (cmd == SOUND_OLD_MIXER_INFO)
+ return get_old_mixer_info(mixdev, arg);
+ if (_SIOC_DIR(cmd) & _SIOC_WRITE)
+ mixer_devs[mixdev]->modify_counter++;
+ if (!mixer_devs[mixdev]->ioctl)
+ return -EINVAL;
+ return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg);
+}
- files[dev].flags = file->f_flags;
+static int sound_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int err, len = 0, dtype;
+ int dev = MINOR(inode->i_rdev);
- if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0)
- {
+ if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) {
/*
* Have to validate the address given by the process.
*/
-
len = _SIOC_SIZE(cmd);
if (len < 1 || len > 65536 || arg == 0)
return -EFAULT;
-
- ptr = vmalloc(len);
- alloced = 1;
- if (ptr == NULL)
- return -EFAULT;
-
if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- {
- if ((err = verify_area(VERIFY_READ, (void *) arg, len)) < 0)
+ if ((err = verify_area(VERIFY_READ, (void *)arg, len)) < 0)
return err;
- copy_from_user(ptr, (char *) arg, len);
- }
if (_SIOC_DIR(cmd) & _SIOC_READ)
- {
- if ((err = verify_area(VERIFY_WRITE, (void *) arg, len)) < 0)
+ if ((err = verify_area(VERIFY_WRITE, (void *)arg, len)) < 0)
return err;
+ }
+ DEB(printk("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
+ if (cmd == OSS_GETVERSION)
+ return __put_user(SOUND_VERSION, (int *)arg);
+
+ if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */
+ (dev & 0x0f) != SND_DEV_CTL) {
+ dtype = dev & 0x0f;
+ switch (dtype) {
+#ifdef CONFIG_AUDIO
+ case SND_DEV_DSP:
+ case SND_DEV_DSP16:
+ case SND_DEV_AUDIO:
+ return sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
+ cmd, (caddr_t)arg);
+#endif
+
+ default:
+ return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
}
}
- err = sound_ioctl_sw(dev, &files[dev], cmd, (caddr_t) ptr);
+ switch (dev & 0x0f) {
+ case SND_DEV_CTL:
+ if (cmd == SOUND_MIXER_GETLEVELS)
+ return get_mixer_levels((caddr_t)arg);
+ if (cmd == SOUND_MIXER_SETLEVELS)
+ return set_mixer_levels((caddr_t)arg);
+ return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
+
+#ifdef CONFIG_SEQUENCER
+ case SND_DEV_SEQ:
+ case SND_DEV_SEQ2:
+ return sequencer_ioctl(dev, file, cmd, (caddr_t)arg);
+#endif
- if (_SIOC_DIR(cmd) & _SIOC_READ)
- copy_to_user((char *) arg, ptr, len);
+#ifdef CONFIG_AUDIO
+ case SND_DEV_DSP:
+ case SND_DEV_DSP16:
+ case SND_DEV_AUDIO:
+ return audio_ioctl(dev, file, cmd, (caddr_t)arg);
+ break;
+#endif
- if (ptr != NULL && alloced)
- vfree(ptr);
+#ifdef CONFIG_MIDI
+ case SND_DEV_MIDIN:
+ return MIDIbuf_ioctl(dev, file, cmd, (caddr_t)arg);
+ break;
+#endif
- return ((err < 0) ? err : 0);
+ }
+ return -EINVAL;
}
-static int sound_select(struct inode *inode, struct file *file, int sel_type, poll_table * wait)
+static unsigned int sound_poll(struct file *file, poll_table * wait)
{
- int dev;
-
- dev = MINOR(inode->i_rdev);
+ struct inode *inode = file->f_dentry->d_inode;
+ int dev = MINOR(inode->i_rdev);
- files[dev].flags = file->f_flags;
-
- DEB(printk("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
-
- switch (dev & 0x0f)
- {
+ DEB(printk("sound_poll(dev=%d)\n", dev));
+ switch (dev & 0x0f) {
#if defined(CONFIG_SEQUENCER) || defined(MODULE)
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- return sequencer_select(dev, &files[dev], sel_type, wait);
- break;
+ case SND_DEV_SEQ:
+ case SND_DEV_SEQ2:
+ return sequencer_poll(dev, file, wait);
#endif
#if defined(CONFIG_MIDI)
- case SND_DEV_MIDIN:
- return MIDIbuf_select(dev, &files[dev], sel_type, wait);
- break;
+ case SND_DEV_MIDIN:
+ return MIDIbuf_poll(dev, file, wait);
#endif
#if defined(CONFIG_AUDIO) || defined(MODULE)
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- return DMAbuf_select(dev >> 4, &files[dev], sel_type, wait);
- break;
+ case SND_DEV_DSP:
+ case SND_DEV_DSP16:
+ case SND_DEV_AUDIO:
+ return DMAbuf_poll(file, dev >> 4, wait);
#endif
-
- default:
- return 0;
}
-
return 0;
}
-static unsigned int sound_poll(struct file *file, poll_table * wait)
-{
- struct inode *inode;
- int ret = 0;
-
- inode = file->f_dentry->d_inode;
-
- if (sound_select(inode, file, SEL_IN, wait))
- ret |= POLLIN;
- if (sound_select(inode, file, SEL_OUT, wait))
- ret |= POLLOUT;
- return ret;
-}
-
static int sound_mmap(struct file *file, struct vm_area_struct *vma)
{
- int dev, dev_class;
- unsigned long size;
+ int dev_class;
+ unsigned long size;
struct dma_buffparms *dmap = NULL;
-
- dev = MINOR(file->f_dentry->d_inode->i_rdev);
-
- files[dev].flags = file->f_flags;
+ int dev = MINOR(file->f_dentry->d_inode->i_rdev);
dev_class = dev & 0x0f;
dev >>= 4;
@@ -307,7 +732,8 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_page_prot))
return -EAGAIN;
- vma->vm_dentry = dget(file->f_dentry);
+ vma->vm_file = file;
+ file->f_count++;
dmap->mapping_flags |= DMA_MAP_MAPPED;
@@ -385,8 +811,6 @@ char kernel_version[] = UTS_RELEASE;
#endif
-static int debugmem = 0; /* switched off by default */
-
static int sound[20] =
{0};
@@ -418,7 +842,9 @@ int init_module(void)
if (sound_nblocks >= 1024)
printk(KERN_ERR "Sound warning: Deallocation table was too small.\n");
-
+
+ if (proc_register(&proc_root, &proc_root_sound))
+ printk(KERN_ERR "sound: registering /proc/sound failed\n");
return 0;
}
@@ -433,6 +859,8 @@ void cleanup_module(void)
{
return;
}
+ if (proc_unregister(&proc_root, PROC_SOUND))
+ printk(KERN_ERR "sound: unregistering /proc/sound failed\n");
if (chrdev_registered)
unregister_chrdev(sound_major, "sound");
@@ -448,8 +876,8 @@ 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++)
{
@@ -467,11 +895,6 @@ void cleanup_module(void)
}
#endif
-void tenmicrosec(int *osp)
-{
- udelay(10);
-}
-
int snd_set_irq_handler(int interrupt_level, void (*iproc) (int, void *, struct pt_regs *), char *name, int *osp)
{
int retcode;
@@ -602,146 +1025,6 @@ void sound_stop_timer(void)
}
#endif
-#ifdef CONFIG_AUDIO
-
-static int dma_buffsize = DSP_BUFFSIZE;
-
-int
-sound_alloc_dmap(int dev, struct dma_buffparms *dmap, int chan)
-{
- char *start_addr, *end_addr;
- int i, dma_pagesize;
-
- dmap->mapping_flags &= ~DMA_MAP_MAPPED;
-
- if (dmap->raw_buf != NULL)
- return 0; /* Already done */
-
- if (dma_buffsize < 4096)
- dma_buffsize = 4096;
-
- if (chan < 4)
- dma_pagesize = 64 * 1024;
- else
- dma_pagesize = 128 * 1024;
-
- dmap->raw_buf = NULL;
-
- dmap->buffsize = dma_buffsize;
-
- if (dmap->buffsize > dma_pagesize)
- dmap->buffsize = dma_pagesize;
-
- start_addr = NULL;
-
-/*
- * Now loop until we get a free buffer. Try to get smaller buffer if
- * it fails. Don't accept smaller than 8k buffer for performance
- * reasons.
- */
-
- while (start_addr == NULL && dmap->buffsize > PAGE_SIZE)
- {
- int sz, size;
-
- for (sz = 0, size = PAGE_SIZE;
- size < dmap->buffsize;
- sz++, size <<= 1);
-
- dmap->buffsize = PAGE_SIZE * (1 << sz);
-
- if ((start_addr = (char *) __get_free_pages(GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL)
- dmap->buffsize /= 2;
- }
-
- if (start_addr == NULL)
- {
- printk(KERN_WARNING "Sound error: Couldn't allocate DMA buffer\n");
- return -ENOMEM;
- }
- else
- {
- /* make some checks */
- end_addr = start_addr + dmap->buffsize - 1;
-
- if (debugmem)
- printk(KERN_DEBUG "sound: start 0x%lx, end 0x%lx\n", (long) start_addr, (long) end_addr);
-
- /* now check if it fits into the same dma-pagesize */
-
- if (((long) start_addr & ~(dma_pagesize - 1))
- != ((long) end_addr & ~(dma_pagesize - 1))
- || end_addr >= (char *) (MAX_DMA_ADDRESS))
- {
- printk(KERN_ERR "sound: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, dmap->buffsize);
- return -EFAULT;
- }
- }
- dmap->raw_buf = start_addr;
- 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);;
- }
-
- return 0;
-}
-
-void sound_free_dmap(int dev, struct dma_buffparms *dmap, int chan)
-{
- int sz, size, i;
- unsigned long start_addr, end_addr;
-
- 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;
- end_addr = start_addr + dmap->buffsize;
-
- for (i = MAP_NR(start_addr); i <= MAP_NR(end_addr); i++)
- {
- clear_bit(PG_reserved, &mem_map[i].flags);;
- }
-
- free_pages((unsigned long) dmap->raw_buf, sz);
- dmap->raw_buf = NULL;
-}
-
-
-/* Intel version !!!!!!!!! */
-
-int sound_start_dma(int dev, struct dma_buffparms *dmap, int chan,
- unsigned long physaddr,
- int count, int dma_mode, int autoinit)
-{
- unsigned long flags;
-
- /* printk( "Start DMA%d %d, %d\n", chan, (int)(physaddr-dmap->raw_buf_phys), count); */
- if (autoinit)
- dma_mode |= DMA_AUTOINIT;
- save_flags(flags);
- cli();
- disable_dma(chan);
- clear_dma_ff(chan);
- set_dma_mode(chan, dma_mode);
- set_dma_addr(chan, physaddr);
- set_dma_count(chan, count);
- enable_dma(chan);
- restore_flags(flags);
-
- return 0;
-}
-
-#endif
-
void conf_printf(char *name, struct address_info *hw_config)
{
if (!trace_init)
@@ -779,3 +1062,34 @@ void conf_printf2(char *name, int base, int irq, int dma, int dma2)
}
printk("\n");
}
+
+/*
+ * Module and lock management
+ */
+
+struct notifier_block *sound_locker=(struct notifier_block *)0;
+static int lock_depth = 0;
+
+#define SOUND_INC_USE_COUNT do { notifier_call_chain(&sound_locker, 1, 0); lock_depth++; } while(0);
+#define SOUND_DEC_USE_COUNT do { notifier_call_chain(&sound_locker, 0, 0); lock_depth--; } while(0);
+
+/*
+ * When a sound module is registered we need to bring it to the current
+ * lock level...
+ */
+
+void sound_notifier_chain_register(struct notifier_block *bl)
+{
+ int ct=0;
+
+ notifier_chain_register(&sound_locker, bl);
+ /*
+ * Normalise the lock count by calling the entry directly. We
+ * have to call the module as it owns its own use counter
+ */
+ while(ct<lock_depth)
+ {
+ bl->notifier_call(bl, 1, 0);
+ ct++;
+ }
+}
diff --git a/drivers/sound/soundmodule.h b/drivers/sound/soundmodule.h
index d590acc0b..dac6316bb 100644
--- a/drivers/sound/soundmodule.h
+++ b/drivers/sound/soundmodule.h
@@ -1,23 +1,25 @@
#ifndef _SOUNDMODULE_H
#define _SOUNDMODULE_H
-#ifdef MODULE
-
#include <linux/notifier.h>
-#ifdef SOUND_CORE
+extern struct notifier_block *sound_locker;
+extern void sound_notifier_chain_register(struct notifier_block *);
+extern int lock_depth;
-struct notifier_block *sound_locker=(struct notifier_block *)0;
+#ifdef MODULE
-#define SOUND_INC_USE_COUNT notifier_call_chain(&sound_locker, 1, 0)
-#define SOUND_DEC_USE_COUNT notifier_call_chain(&sound_locker, 0, 0)
+#ifdef SOUND_CORE
+
+#define SOUND_INC_USE_COUNT do { notifier_call_chain(&sound_locker, 1, 0); lock_depth++; } while(0);
+#define SOUND_DEC_USE_COUNT do { notifier_call_chain(&sound_locker, 0, 0); lock_depth--; } while(0);
#else
-#define SOUND_LOCK notifier_chain_register(&sound_locker, &sound_notifier)
+
+#define SOUND_LOCK sound_notifier_chain_register(&sound_notifier);
#define SOUND_LOCK_END notifier_chain_unregister(&sound_locker, &sound_notifier)
-extern struct notifier_block *sound_locker;
static int my_notifier_call(struct notifier_block *b, unsigned long foo, void *bar)
diff --git a/drivers/sound/sscape.c b/drivers/sound/sscape.c
index befd924d0..8ea3e87f8 100644
--- a/drivers/sound/sscape.c
+++ b/drivers/sound/sscape.c
@@ -3,6 +3,7 @@
*
* Low level driver for Ensoniq SoundScape
*/
+
/*
* Copyright (C) by Hannu Savolainen 1993-1997
*
@@ -10,79 +11,87 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+
+/*
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ */
+
#include <linux/config.h>
#include <linux/module.h>
#include "sound_config.h"
#include "soundmodule.h"
-#if defined(CONFIG_SSCAPEHW) || defined(MODULE)
+#if defined(CONFIG_SSCAPE) || defined(MODULE)
#include "coproc.h"
/*
* I/O ports
*/
-#define MIDI_DATA 0
-#define MIDI_CTRL 1
-#define HOST_CTRL 2
-#define TX_READY 0x02
-#define RX_READY 0x01
-#define HOST_DATA 3
-#define ODIE_ADDR 4
-#define ODIE_DATA 5
+#define MIDI_DATA 0
+#define MIDI_CTRL 1
+#define HOST_CTRL 2
+#define TX_READY 0x02
+#define RX_READY 0x01
+#define HOST_DATA 3
+#define ODIE_ADDR 4
+#define ODIE_DATA 5
/*
* Indirect registers
*/
-#define GA_INTSTAT_REG 0
-#define GA_INTENA_REG 1
-#define GA_DMAA_REG 2
-#define GA_DMAB_REG 3
-#define GA_INTCFG_REG 4
-#define GA_DMACFG_REG 5
-#define GA_CDCFG_REG 6
-#define GA_SMCFGA_REG 7
-#define GA_SMCFGB_REG 8
-#define GA_HMCTL_REG 9
+
+#define GA_INTSTAT_REG 0
+#define GA_INTENA_REG 1
+#define GA_DMAA_REG 2
+#define GA_DMAB_REG 3
+#define GA_INTCFG_REG 4
+#define GA_DMACFG_REG 5
+#define GA_CDCFG_REG 6
+#define GA_SMCFGA_REG 7
+#define GA_SMCFGB_REG 8
+#define GA_HMCTL_REG 9
/*
* DMA channel identifiers (A and B)
*/
-#define SSCAPE_DMA_A 0
-#define SSCAPE_DMA_B 1
+
+#define SSCAPE_DMA_A 0
+#define SSCAPE_DMA_B 1
#define PORT(name) (devc->base+name)
/*
* Host commands recognized by the OBP microcode
*/
-#define CMD_GEN_HOST_ACK 0x80
-#define CMD_GEN_MPU_ACK 0x81
-#define CMD_GET_BOARD_TYPE 0x82
-#define CMD_SET_CONTROL 0x88 /* Old firmware only */
-#define CMD_GET_CONTROL 0x89 /* Old firmware only */
-#define CTL_MASTER_VOL 0
-#define CTL_MIC_MODE 2
-#define CTL_SYNTH_VOL 4
-#define CTL_WAVE_VOL 7
+
+#define CMD_GEN_HOST_ACK 0x80
+#define CMD_GEN_MPU_ACK 0x81
+#define CMD_GET_BOARD_TYPE 0x82
+#define CMD_SET_CONTROL 0x88 /* Old firmware only */
+#define CMD_GET_CONTROL 0x89 /* Old firmware only */
+#define CTL_MASTER_VOL 0
+#define CTL_MIC_MODE 2
+#define CTL_SYNTH_VOL 4
+#define CTL_WAVE_VOL 7
#define CMD_SET_EXTMIDI 0x8a
#define CMD_GET_EXTMIDI 0x8b
-#define CMD_SET_MT32 0x8c
-#define CMD_GET_MT32 0x8d
+#define CMD_SET_MT32 0x8c
+#define CMD_GET_MT32 0x8d
#define CMD_ACK 0x80
typedef struct sscape_info
{
- int base, irq, dma;
- int ok; /* Properly detected */
- int failed;
- int dma_allocated;
- int codec_audiodev;
- int opened;
- int *osp;
- int my_audiodev;
+ int base, irq, dma;
+ int ok; /* Properly detected */
+ int failed;
+ int dma_allocated;
+ int codec_audiodev;
+ int opened;
+ int *osp;
+ int my_audiodev;
} sscape_info;
static struct sscape_info adev_info = {
@@ -90,112 +99,111 @@ static struct sscape_info adev_info = {
};
static struct sscape_info *devc = &adev_info;
-static int sscape_mididev = -1;
-
-static struct wait_queue *sscape_sleeper = NULL;
-static volatile struct snd_wait sscape_sleep_flag = {
- 0
-};
+static int sscape_mididev = -1;
/* Some older cards have assigned interrupt bits differently than new ones */
-static char valid_interrupts_old[] =
-{9, 7, 5, 15};
+static char valid_interrupts_old[] = {
+ 9, 7, 5, 15
+};
-static char valid_interrupts_new[] =
-{9, 5, 7, 10};
+static char valid_interrupts_new[] = {
+ 9, 5, 7, 10
+};
-static char *valid_interrupts = valid_interrupts_new;
+static char *valid_interrupts = valid_interrupts_new;
+/*
+ * See the bottom of the driver. This can be set by spea =0/1.
+ */
+
#ifdef REVEAL_SPEA
-static char old_hardware = 1;
-
+static char old_hardware = 1;
#else
-static char old_hardware = 0;
-
+static char old_hardware = 0;
#endif
+static void sleep(unsigned howlong)
+{
+ current->timeout = jiffies + 1;
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ current->timeout = 0;
+}
+
static unsigned char sscape_read(struct sscape_info *devc, int reg)
{
- unsigned long flags;
- unsigned char val;
+ unsigned long flags;
+ unsigned char val;
save_flags(flags);
cli();
- outb((reg), PORT(ODIE_ADDR));
+ outb(reg, PORT(ODIE_ADDR));
val = inb(PORT(ODIE_DATA));
restore_flags(flags);
return val;
}
-static void
-sscape_write(struct sscape_info *devc, int reg, int data)
+static void sscape_write(struct sscape_info *devc, int reg, int data)
{
- unsigned long flags;
+ unsigned long flags;
save_flags(flags);
cli();
- outb((reg), PORT(ODIE_ADDR));
- outb((data), PORT(ODIE_DATA));
+ outb(reg, PORT(ODIE_ADDR));
+ outb(data, PORT(ODIE_DATA));
restore_flags(flags);
}
-static void
-host_open(struct sscape_info *devc)
+static void host_open(struct sscape_info *devc)
{
outb((0x00), PORT(HOST_CTRL)); /* Put the board to the host mode */
}
-static void
-host_close(struct sscape_info *devc)
+static void host_close(struct sscape_info *devc)
{
outb((0x03), PORT(HOST_CTRL)); /* Put the board to the MIDI mode */
}
-static int
-host_write(struct sscape_info *devc, unsigned char *data, int count)
+static int host_write(struct sscape_info *devc, unsigned char *data, int count)
{
- unsigned long flags;
- int i, timeout_val;
+ unsigned long flags;
+ int i, timeout_val;
save_flags(flags);
cli();
/*
- * Send the command and data bytes
+ * Send the command and data bytes
*/
for (i = 0; i < count; i++)
- {
- for (timeout_val = 10000; timeout_val > 0; timeout_val--)
- if (inb(PORT(HOST_CTRL)) & TX_READY)
- break;
+ {
+ for (timeout_val = 10000; timeout_val > 0; timeout_val--)
+ if (inb(PORT(HOST_CTRL)) & TX_READY)
+ break;
- if (timeout_val <= 0)
- {
+ if (timeout_val <= 0)
+ {
restore_flags(flags);
return 0;
- }
- outb((data[i]), PORT(HOST_DATA));
- }
-
-
+ }
+ outb(data[i], PORT(HOST_DATA));
+ }
restore_flags(flags);
-
return 1;
}
-static int
-host_read(struct sscape_info *devc)
+static int host_read(struct sscape_info *devc)
{
- unsigned long flags;
- int timeout_val;
- unsigned char data;
+ unsigned long flags;
+ int timeout_val;
+ unsigned char data;
save_flags(flags);
cli();
/*
- * Read a byte
+ * Read a byte
*/
for (timeout_val = 10000; timeout_val > 0; timeout_val--)
@@ -203,22 +211,19 @@ host_read(struct sscape_info *devc)
break;
if (timeout_val <= 0)
- {
- restore_flags(flags);
- return -1;
- }
+ {
+ restore_flags(flags);
+ return -1;
+ }
data = inb(PORT(HOST_DATA));
-
restore_flags(flags);
-
return data;
}
-static int
-host_command2(struct sscape_info *devc, int cmd, int parm1)
+static int host_command2(struct sscape_info *devc, int cmd, int parm1)
{
- unsigned char buf[10];
+ unsigned char buf[10];
buf[0] = (unsigned char) (cmd & 0xff);
buf[1] = (unsigned char) (parm1 & 0xff);
@@ -226,61 +231,49 @@ host_command2(struct sscape_info *devc, int cmd, int parm1)
return host_write(devc, buf, 2);
}
-static int
-host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2)
+static int host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2)
{
- unsigned char buf[10];
+ unsigned char buf[10];
buf[0] = (unsigned char) (cmd & 0xff);
buf[1] = (unsigned char) (parm1 & 0xff);
buf[2] = (unsigned char) (parm2 & 0xff);
-
return host_write(devc, buf, 3);
}
-static void
-set_mt32(struct sscape_info *devc, int value)
+static void set_mt32(struct sscape_info *devc, int value)
{
host_open(devc);
- host_command2(devc, CMD_SET_MT32,
- value ? 1 : 0);
+ host_command2(devc, CMD_SET_MT32, value ? 1 : 0);
if (host_read(devc) != CMD_ACK)
- {
- /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
- }
+ {
+ /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
+ }
host_close(devc);
}
-static void
-set_control(struct sscape_info *devc, int ctrl, int value)
+static void set_control(struct sscape_info *devc, int ctrl, int value)
{
host_open(devc);
host_command3(devc, CMD_SET_CONTROL, ctrl, value);
if (host_read(devc) != CMD_ACK)
- {
- /* printk( "SNDSCAPE: Setting control (%d) failed\n", ctrl); */
- }
+ {
+ /* printk( "SNDSCAPE: Setting control (%d) failed\n", ctrl); */
+ }
host_close(devc);
}
-
-
-
-
-static void
-do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
+static void do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
{
- unsigned char temp;
+ unsigned char temp;
if (dma_chan != SSCAPE_DMA_A)
- {
- printk("SSCAPE: Tried to use DMA channel != A. Why?\n");
- return;
- }
+ {
+ printk(KERN_WARNING "soundscape: Tried to use DMA channel != A. Why?\n");
+ return;
+ }
audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE;
- DMAbuf_start_dma(devc->codec_audiodev,
- buf,
- blk_size, mode);
+ DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode);
audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE;
temp = devc->dma << 4; /* Setup DMA channel select bits */
@@ -293,49 +286,44 @@ do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size,
sscape_write(devc, GA_DMAA_REG, temp);
}
-static int
-verify_mpu(struct sscape_info *devc)
+static int verify_mpu(struct sscape_info *devc)
{
/*
- * The SoundScape board could be in three modes (MPU, 8250 and host).
- * If the card is not in the MPU mode, enabling the MPU driver will
- * cause infinite loop (the driver believes that there is always some
- * received data in the buffer.
- *
- * Detect this by looking if there are more than 10 received MIDI bytes
- * (0x00) in the buffer.
+ * The SoundScape board could be in three modes (MPU, 8250 and host).
+ * If the card is not in the MPU mode, enabling the MPU driver will
+ * cause infinite loop (the driver believes that there is always some
+ * received data in the buffer.
+ *
+ * Detect this by looking if there are more than 10 received MIDI bytes
+ * (0x00) in the buffer.
*/
- int i;
+ int i;
for (i = 0; i < 10; i++)
- {
- if (inb(devc->base + HOST_CTRL) & 0x80)
- return 1;
-
- if (inb(devc->base) != 0x00)
- return 1;
- }
+ {
+ if (inb(devc->base + HOST_CTRL) & 0x80)
+ return 1;
- printk("SoundScape: The device is not in the MPU-401 mode\n");
+ if (inb(devc->base) != 0x00)
+ return 1;
+ }
+ printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n");
return 0;
}
-static int
-sscape_coproc_open(void *dev_info, int sub_device)
+static int sscape_coproc_open(void *dev_info, int sub_device)
{
if (sub_device == COPR_MIDI)
- {
- set_mt32(devc, 0);
- if (!verify_mpu(devc))
- return -EIO;
- }
- sscape_sleep_flag.opts = WK_NONE;
+ {
+ set_mt32(devc, 0);
+ if (!verify_mpu(devc))
+ return -EIO;
+ }
return 0;
}
-static void
-sscape_coproc_close(void *dev_info, int sub_device)
+static void sscape_coproc_close(void *dev_info, int sub_device)
{
struct sscape_info *devc = dev_info;
unsigned long flags;
@@ -343,69 +331,66 @@ sscape_coproc_close(void *dev_info, int sub_device)
save_flags(flags);
cli();
if (devc->dma_allocated)
- {
- sscape_write(devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */
- devc->dma_allocated = 0;
- }
- sscape_sleep_flag.opts = WK_NONE;
+ {
+ sscape_write(devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */
+ devc->dma_allocated = 0;
+ }
restore_flags(flags);
-
return;
}
-static void
-sscape_coproc_reset(void *dev_info)
+static void sscape_coproc_reset(void *dev_info)
{
}
-static int
-sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
+static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
{
- unsigned long flags;
- unsigned char temp;
- volatile int done, timeout_val;
+ unsigned long flags;
+ unsigned char temp;
+ volatile int done, timeout_val;
static unsigned char codec_dma_bits = 0;
if (flag & CPF_FIRST)
- {
- /*
- * First block. Have to allocate DMA and to reset the board
- * before continuing.
- */
-
- save_flags(flags);
- cli();
- codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
-
- if (devc->dma_allocated == 0)
- {
- devc->dma_allocated = 1;
- }
- restore_flags(flags);
-
- sscape_write(devc, GA_HMCTL_REG,
+ {
+ /*
+ * First block. Have to allocate DMA and to reset the board
+ * before continuing.
+ */
+
+ save_flags(flags);
+ cli();
+ codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
+
+ if (devc->dma_allocated == 0)
+ devc->dma_allocated = 1;
+
+ restore_flags(flags);
+
+ sscape_write(devc, GA_HMCTL_REG,
(temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f); /*Reset */
- for (timeout_val = 10000; timeout_val > 0; timeout_val--)
- sscape_read(devc, GA_HMCTL_REG); /* Delay */
+ for (timeout_val = 10000; timeout_val > 0; timeout_val--)
+ sscape_read(devc, GA_HMCTL_REG); /* Delay */
- /* Take board out of reset */
- sscape_write(devc, GA_HMCTL_REG,
+ /* Take board out of reset */
+ sscape_write(devc, GA_HMCTL_REG,
(temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
- }
+ }
/*
* Transfer one code block using DMA
*/
if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
- {
- printk("SSCAPE: Error: DMA buffer not available\n");
- return 0;
- }
+ {
+ printk(KERN_WARNING "soundscape: DMA buffer not available\n");
+ return 0;
+ }
memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
save_flags(flags);
cli();
-/******** INTERRUPTS DISABLED NOW ********/
+
+ /******** INTERRUPTS DISABLED NOW ********/
+
do_dma(devc, SSCAPE_DMA_A,
audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
size, DMA_MODE_WRITE);
@@ -413,193 +398,141 @@ sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, i
/*
* Wait until transfer completes.
*/
- sscape_sleep_flag.opts = WK_NONE;
+
done = 0;
timeout_val = 30;
while (!done && timeout_val-- > 0)
- {
- int resid;
-
- {
- unsigned long tlimit;
-
- if (HZ / 50)
- current->timeout = tlimit = jiffies + (HZ / 50);
- else
- tlimit = (unsigned long) -1;
- sscape_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&sscape_sleeper);
- if (!(sscape_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- sscape_sleep_flag.opts |= WK_TIMEOUT;
- }
- sscape_sleep_flag.opts &= ~WK_SLEEP;
- };
- clear_dma_ff(devc->dma);
- if ((resid = get_dma_residue(devc->dma)) == 0)
- {
- done = 1;
- }
- }
+ {
+ int resid;
+
+ if (HZ / 50)
+ sleep(HZ / 50);
+ clear_dma_ff(devc->dma);
+ if ((resid = get_dma_residue(devc->dma)) == 0)
+ done = 1;
+ }
restore_flags(flags);
if (!done)
return 0;
if (flag & CPF_LAST)
- {
- /*
- * Take the board out of reset
- */
- outb((0x00), PORT(HOST_CTRL));
- outb((0x00), PORT(MIDI_CTRL));
-
- temp = sscape_read(devc, GA_HMCTL_REG);
- temp |= 0x40;
- sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */
-
- /*
- * Wait until the ODB wakes up
- */
-
- save_flags(flags);
- cli();
- done = 0;
- timeout_val = 5 * HZ;
- while (!done && timeout_val-- > 0)
- {
- unsigned char x;
-
-
- {
- unsigned long tlimit;
-
- if (1)
- current->timeout = tlimit = jiffies + (1);
- else
- tlimit = (unsigned long) -1;
- sscape_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&sscape_sleeper);
- if (!(sscape_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- sscape_sleep_flag.opts |= WK_TIMEOUT;
- }
- sscape_sleep_flag.opts &= ~WK_SLEEP;
- };
- x = inb(PORT(HOST_DATA));
- if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */
- {
- DDB(printk("Soundscape: Acknowledge = %x\n", x));
- done = 1;
- }
- }
- sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
-
- restore_flags(flags);
- if (!done)
- {
- printk("SoundScape: The OBP didn't respond after code download\n");
- return 0;
- }
- save_flags(flags);
- cli();
- done = 0;
- timeout_val = 5 * HZ;
- while (!done && timeout_val-- > 0)
- {
-
- {
- unsigned long tlimit;
-
- if (1)
- current->timeout = tlimit = jiffies + (1);
- else
- tlimit = (unsigned long) -1;
- sscape_sleep_flag.opts = WK_SLEEP;
- interruptible_sleep_on(&sscape_sleeper);
- if (!(sscape_sleep_flag.opts & WK_WAKEUP))
- {
- if (jiffies >= tlimit)
- sscape_sleep_flag.opts |= WK_TIMEOUT;
- }
- sscape_sleep_flag.opts &= ~WK_SLEEP;
- };
- if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */
- done = 1;
- }
- restore_flags(flags);
- if (!done)
- {
- printk("SoundScape: OBP Initialization failed.\n");
- return 0;
- }
- printk("SoundScape board initialized OK\n");
- set_control(devc, CTL_MASTER_VOL, 100);
- set_control(devc, CTL_SYNTH_VOL, 100);
+ {
+ /*
+ * Take the board out of reset
+ */
+ outb((0x00), PORT(HOST_CTRL));
+ outb((0x00), PORT(MIDI_CTRL));
+
+ temp = sscape_read(devc, GA_HMCTL_REG);
+ temp |= 0x40;
+ sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */
+
+ /*
+ * Wait until the ODB wakes up
+ */
+
+ save_flags(flags);
+ cli();
+ done = 0;
+ timeout_val = 5 * HZ;
+ while (!done && timeout_val-- > 0)
+ {
+ unsigned char x;
+
+ sleep(1);
+ x = inb(PORT(HOST_DATA));
+ if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */
+ {
+ DDB(printk("Soundscape: Acknowledge = %x\n", x));
+ done = 1;
+ }
+ }
+ sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
+
+ restore_flags(flags);
+ if (!done)
+ {
+ printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
+ return 0;
+ }
+ save_flags(flags);
+ cli();
+ done = 0;
+ timeout_val = 5 * HZ;
+ while (!done && timeout_val-- > 0)
+ {
+ sleep(1);
+ if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */
+ done = 1;
+ }
+ restore_flags(flags);
+ if (!done)
+ {
+ printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
+ return 0;
+ }
+ printk(KERN_INFO "SoundScape board initialized OK\n");
+ set_control(devc, CTL_MASTER_VOL, 100);
+ set_control(devc, CTL_SYNTH_VOL, 100);
#ifdef SSCAPE_DEBUG3
- /*
- * Temporary debugging aid. Print contents of the registers after
- * downloading the code.
- */
- {
- int i;
-
- for (i = 0; i < 13; i++)
- printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
- }
+ /*
+ * Temporary debugging aid. Print contents of the registers after
+ * downloading the code.
+ */
+ {
+ int i;
+
+ for (i = 0; i < 13; i++)
+ printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
+ }
#endif
- }
+ }
return 1;
}
-static int
-download_boot_block(void *dev_info, copr_buffer * buf)
+static int download_boot_block(void *dev_info, copr_buffer * buf)
{
if (buf->len <= 0 || buf->len > sizeof(buf->data))
return -EINVAL;
if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags))
- {
- printk("SSCAPE: Unable to load microcode block to the OBP.\n");
- return -EIO;
- }
+ {
+ printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n");
+ return -EIO;
+ }
return 0;
}
-static int
-sscape_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int local)
+static int sscape_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int local)
{
+ copr_buffer *buf;
+ int err;
- switch (cmd)
- {
- case SNDCTL_COPR_RESET:
- sscape_coproc_reset(dev_info);
- return 0;
- break;
-
- case SNDCTL_COPR_LOAD:
- {
- copr_buffer *buf;
- int err;
-
- buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
- if (buf == NULL)
- return -ENOSPC;
- memcpy((char *) buf, (&((char *) arg)[0]), sizeof(*buf));
- err = download_boot_block(dev_info, buf);
- vfree(buf);
- return err;
- }
- break;
-
- default:
- return -EINVAL;
- }
-
+ switch (cmd)
+ {
+ case SNDCTL_COPR_RESET:
+ sscape_coproc_reset(dev_info);
+ return 0;
+
+ case SNDCTL_COPR_LOAD:
+ buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
+ if (buf == NULL)
+ return -ENOSPC;
+ if (copy_from_user(buf, arg, sizeof(copr_buffer)))
+ {
+ vfree(buf);
+ return -EFAULT;
+ }
+ err = download_boot_block(dev_info, buf);
+ vfree(buf);
+ return err;
+
+ default:
+ return -EINVAL;
+ }
}
static coproc_operations sscape_coproc_operations =
@@ -612,25 +545,23 @@ static coproc_operations sscape_coproc_operations =
&adev_info
};
-static int sscape_detected = 0;
+static int sscape_detected = 0;
-void
-attach_sscape(struct address_info *hw_config)
+void attach_sscape(struct address_info *hw_config)
{
-
#ifndef SSCAPE_REGS
/*
- * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
- * These values are card
- * dependent. If you have another SoundScape based card, you have to
- * find the correct values. Do the following:
- * - Compile this driver with SSCAPE_DEBUG1 defined.
- * - Shut down and power off your machine.
- * - Boot with DOS so that the SSINIT.EXE program is run.
- * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
- * when detecting the SoundScape.
- * - Modify the following list to use the values printed during boot.
- * Undefine the SSCAPE_DEBUG1
+ * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
+ * These values are card
+ * dependent. If you have another SoundScape based card, you have to
+ * find the correct values. Do the following:
+ * - Compile this driver with SSCAPE_DEBUG1 defined.
+ * - Shut down and power off your machine.
+ * - Boot with DOS so that the SSINIT.EXE program is run.
+ * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
+ * when detecting the SoundScape.
+ * - Modify the following list to use the values printed during boot.
+ * Undefine the SSCAPE_DEBUG1
*/
#define SSCAPE_REGS { \
/* I0 */ 0x00, \
@@ -649,76 +580,78 @@ attach_sscape(struct address_info *hw_config)
unsigned long flags;
static unsigned char regs[10] = SSCAPE_REGS;
- int i, irq_bits = 0xff;
+ int i, irq_bits = 0xff;
if (sscape_detected != hw_config->io_base)
return;
request_region(devc->base + 2, 6, "SoundScape");
if (old_hardware)
- {
- valid_interrupts = valid_interrupts_old;
- conf_printf("Ensoniq SoundScape (old)", hw_config);
- } else
+ {
+ valid_interrupts = valid_interrupts_old;
+ conf_printf("Ensoniq SoundScape (old)", hw_config);
+ }
+ else
conf_printf("Ensoniq SoundScape", hw_config);
for (i = 0; i < sizeof(valid_interrupts); i++)
+ {
if (hw_config->irq == valid_interrupts[i])
- {
- irq_bits = i;
- break;
- }
+ {
+ irq_bits = i;
+ break;
+ }
+ }
if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
- {
- printk("Invalid IRQ%d\n", hw_config->irq);
- return;
- }
+ {
+ printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
+ return;
+ }
save_flags(flags);
cli();
for (i = 1; i < 10; i++)
+ {
switch (i)
- {
- case 1: /* Host interrupt enable */
- sscape_write(devc, i, 0xf0); /* All interrupts enabled */
- break;
-
- case 2: /* DMA A status/trigger register */
- case 3: /* DMA B status/trigger register */
- sscape_write(devc, i, 0x20); /* DMA channel disabled */
- break;
-
- case 4: /* Host interrupt config reg */
- sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
- break;
-
- case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */
- sscape_write(devc, i, (regs[i] & 0x3f) |
- (sscape_read(devc, i) & 0xc0));
- break;
-
- case 6: /* CD-ROM config (WSS codec actually) */
- sscape_write(devc, i, regs[i]);
- break;
-
- case 9: /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
- sscape_write(devc, i,
- (sscape_read(devc, i) & 0xf0) | 0x08);
- break;
-
- default:
- sscape_write(devc, i, regs[i]);
- }
-
+ {
+ case 1: /* Host interrupt enable */
+ sscape_write(devc, i, 0xf0); /* All interrupts enabled */
+ break;
+
+ case 2: /* DMA A status/trigger register */
+ case 3: /* DMA B status/trigger register */
+ sscape_write(devc, i, 0x20); /* DMA channel disabled */
+ break;
+
+ case 4: /* Host interrupt config reg */
+ sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
+ break;
+
+ case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */
+ sscape_write(devc, i, (regs[i] & 0x3f) | (sscape_read(devc, i) & 0xc0));
+ break;
+
+ case 6: /* CD-ROM config (WSS codec actually) */
+ sscape_write(devc, i, regs[i]);
+ break;
+
+ case 9: /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
+ sscape_write(devc, i, (sscape_read(devc, i) & 0xf0) | 0x08);
+ break;
+
+ default:
+ sscape_write(devc, i, regs[i]);
+ }
+ }
restore_flags(flags);
#ifdef SSCAPE_DEBUG2
/*
- * Temporary debugging aid. Print contents of the registers after
- * changing them.
+ * Temporary debugging aid. Print contents of the registers after
+ * changing them.
*/
{
- int i;
+ int i;
for (i = 0; i < 13; i++)
printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
@@ -728,31 +661,26 @@ attach_sscape(struct address_info *hw_config)
#if defined(CONFIG_MIDI) && defined(CONFIG_MPU_EMU)
if (probe_mpu401(hw_config))
hw_config->always_detect = 1;
- {
- hw_config->name = "SoundScape";
+ hw_config->name = "SoundScape";
- hw_config->irq *= -1; /* Negative value signals IRQ sharing */
- attach_mpu401(hw_config);
- hw_config->irq *= -1; /* Restore it */
+ hw_config->irq *= -1; /* Negative value signals IRQ sharing */
+ attach_mpu401(hw_config);
+ hw_config->irq *= -1; /* Restore it */
- if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
- {
- sscape_mididev = hw_config->slots[1];
- midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
- }
+ if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
+ {
+ sscape_mididev = hw_config->slots[1];
+ midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
}
#endif
-
sscape_write(devc, GA_INTENA_REG, 0x80); /* Master IRQ enable */
devc->ok = 1;
devc->failed = 0;
-
}
-static int
-detect_ga(sscape_info * devc)
+static int detect_ga(sscape_info * devc)
{
- unsigned char save;
+ unsigned char save;
DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));
@@ -760,54 +688,54 @@ detect_ga(sscape_info * devc)
return 0;
/*
- * First check that the address register of "ODIE" is
- * there and that it has exactly 4 writable bits.
- * First 4 bits
+ * First check that the address register of "ODIE" is
+ * there and that it has exactly 4 writable bits.
+ * First 4 bits
*/
+
if ((save = inb(PORT(ODIE_ADDR))) & 0xf0)
- {
- DDB(printk("soundscape: Detect error A\n"));
- return 0;
- }
+ {
+ DDB(printk("soundscape: Detect error A\n"));
+ return 0;
+ }
outb((0x00), PORT(ODIE_ADDR));
if (inb(PORT(ODIE_ADDR)) != 0x00)
- {
- DDB(printk("soundscape: Detect error B\n"));
- return 0;
- }
+ {
+ DDB(printk("soundscape: Detect error B\n"));
+ return 0;
+ }
outb((0xff), PORT(ODIE_ADDR));
if (inb(PORT(ODIE_ADDR)) != 0x0f)
- {
- DDB(printk("soundscape: Detect error C\n"));
- return 0;
- }
+ {
+ DDB(printk("soundscape: Detect error C\n"));
+ return 0;
+ }
outb((save), PORT(ODIE_ADDR));
/*
- * Now verify that some indirect registers return zero on some bits.
- * This may break the driver with some future revisions of "ODIE" but...
+ * Now verify that some indirect registers return zero on some bits.
+ * This may break the driver with some future revisions of "ODIE" but...
*/
if (sscape_read(devc, 0) & 0x0c)
- {
- DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0)));
- return 0;
- }
+ {
+ DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0)));
+ return 0;
+ }
if (sscape_read(devc, 1) & 0x0f)
- {
- DDB(printk("soundscape: Detect error E\n"));
- return 0;
- }
+ {
+ DDB(printk("soundscape: Detect error E\n"));
+ return 0;
+ }
if (sscape_read(devc, 5) & 0x0f)
- {
- DDB(printk("soundscape: Detect error F\n"));
- return 0;
- }
+ {
+ DDB(printk("soundscape: Detect error F\n"));
+ return 0;
+ }
return 1;
}
-int
-probe_sscape(struct address_info *hw_config)
+int probe_sscape(struct address_info *hw_config)
{
if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
@@ -820,110 +748,110 @@ probe_sscape(struct address_info *hw_config)
#ifdef SSCAPE_DEBUG1
/*
- * Temporary debugging aid. Print contents of the registers before
- * changing them.
+ * Temporary debugging aid. Print contents of the registers before
+ * changing them.
*/
{
- int i;
+ int i;
for (i = 0; i < 13; i++)
printk("I%d = %02x (old value)\n", i, sscape_read(devc, i));
}
#endif
-
-
devc->failed = 1;
if (!detect_ga(devc))
return 0;
if (old_hardware) /* Check that it's really an old Spea/Reveal card. */
- {
- unsigned char tmp;
- int cc;
-
- if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0))
- {
- sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
- for (cc = 0; cc < 200000; ++cc)
- inb(devc->base + ODIE_ADDR);
- }
- }
+ {
+ unsigned char tmp;
+ int cc;
+
+ if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0))
+ {
+ sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
+ for (cc = 0; cc < 200000; ++cc)
+ inb(devc->base + ODIE_ADDR);
+ }
+ }
sscape_detected = hw_config->io_base;
-
return 1;
}
-int
-probe_ss_ms_sound(struct address_info *hw_config)
+int probe_ss_ms_sound(struct address_info *hw_config)
{
- int i, irq_bits = 0xff;
- int ad_flags = 0;
+ int i, irq_bits = 0xff;
+ int ad_flags = 0;
if (devc->failed)
- {
- printk("Soundscape: Card not detected\n");
+ {
+ printk(KERN_ERR "soundscape: Card not detected\n");
return 0;
- }
+ }
if (devc->ok == 0)
- {
- printk("SoundScape: Invalid initialization order.\n");
- return 0;
- }
+ {
+ printk(KERN_ERR "soundscape: Invalid initialization order.\n");
+ return 0;
+ }
for (i = 0; i < sizeof(valid_interrupts); i++)
+ {
if (hw_config->irq == valid_interrupts[i])
- {
- irq_bits = i;
- break;
- }
+ {
+ irq_bits = i;
+ break;
+ }
+ }
if (hw_config->irq > 15 || irq_bits == 0xff)
- {
- printk("SoundScape: Invalid MSS IRQ%d\n", hw_config->irq);
- return 0;
- }
+ {
+ printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq);
+ return 0;
+ }
if (old_hardware)
ad_flags = 0x12345677; /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
return ad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp);
}
-void
-attach_ss_ms_sound(struct address_info *hw_config)
+void attach_ss_ms_sound(struct address_info *hw_config)
{
/*
- * This routine configures the SoundScape card for use with the
- * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
- * config registers of the "ODIE".
+ * This routine configures the SoundScape card for use with the
+ * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
+ * config registers of the "ODIE".
*/
- int i, irq_bits = 0xff;
+ int i, irq_bits = 0xff;
hw_config->dma = devc->dma; /* Share the DMA with the ODIE/OPUS chip */
/*
* Setup the DMA polarity.
*/
+
sscape_write(devc, GA_DMACFG_REG, 0x50);
/*
- * Take the gate-array off of the DMA channel.
+ * Take the gate-array off of the DMA channel.
*/
+
sscape_write(devc, GA_DMAB_REG, 0x20);
/*
- * Init the AD1848 (CD-ROM) config reg.
+ * Init the AD1848 (CD-ROM) config reg.
*/
for (i = 0; i < sizeof(valid_interrupts); i++)
+ {
if (hw_config->irq == valid_interrupts[i])
- {
- irq_bits = i;
- break;
- }
- sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) |
- (irq_bits << 1));
+ {
+ irq_bits = i;
+ break;
+ }
+ }
+ sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | (irq_bits << 1));
if (hw_config->irq == devc->irq)
- printk("SoundScape: Warning! The WSS mode can't share IRQ with MIDI\n");
+ printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n");
hw_config->slots[0] = ad1848_init("SoundScape", hw_config->io_base,
hw_config->irq,
@@ -933,21 +861,21 @@ attach_ss_ms_sound(struct address_info *hw_config)
devc->osp);
if (hw_config->slots[0] != -1) /* The AD1848 driver installed itself */
- {
- audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
- devc->codec_audiodev = hw_config->slots[0];
- devc->my_audiodev = hw_config->slots[0];
-
- /* Set proper routings here (what are they) */
- AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
- }
+ {
+ audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
+ devc->codec_audiodev = hw_config->slots[0];
+ devc->my_audiodev = hw_config->slots[0];
+
+ /* Set proper routings here (what are they) */
+ AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
+ }
#ifdef SSCAPE_DEBUG5
/*
- * Temporary debugging aid. Print contents of the registers
- * after the AD1848 device has been initialized.
+ * Temporary debugging aid. Print contents of the registers
+ * after the AD1848 device has been initialized.
*/
{
- int i;
+ int i;
for (i = 0; i < 13; i++)
printk("I%d = %02x\n", i, sscape_read(devc, i));
@@ -956,8 +884,7 @@ attach_ss_ms_sound(struct address_info *hw_config)
}
-void
-unload_sscape(struct address_info *hw_config)
+void unload_sscape(struct address_info *hw_config)
{
release_region(devc->base + 2, 6);
#if defined(CONFIG_MPU_EMU) && defined(CONFIG_MIDI)
@@ -965,8 +892,7 @@ unload_sscape(struct address_info *hw_config)
#endif
}
-void
-unload_ss_ms_sound(struct address_info *hw_config)
+void unload_ss_ms_sound(struct address_info *hw_config)
{
ad1848_unload(hw_config->io_base,
hw_config->irq,
@@ -985,11 +911,14 @@ int io = -1;
int mpu_irq = -1;
int mpu_io = -1;
+int spea = -1;
+
static int mss = 0;
MODULE_PARM(dma, "i");
MODULE_PARM(irq, "i");
MODULE_PARM(io, "i");
+MODULE_PARM(spea, "i"); /* spea=0/1 set the old_hardware */
MODULE_PARM(mpu_irq, "i");
MODULE_PARM(mpu_io, "i");
MODULE_PARM(mss, "i");
@@ -997,18 +926,17 @@ MODULE_PARM(mss, "i");
struct address_info config;
struct address_info mpu_config;
-int
-init_module(void)
+int init_module(void)
{
- printk("Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+ printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
if (dma == -1 || irq == -1 || io == -1)
{
- printk("DMA, IRQ, and IO port must be specified.\n");
- return -EINVAL;
+ printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
+ return -EINVAL;
}
if (mpu_irq == -1 && mpu_io != -1)
{
- printk("MPU_IRQ must be specified if MPU_IO is set.\n");
+ printk(KERN_ERR "CONFIG_MPU_IRQ must be specified if CONFIG_MPU_IO is set.\n");
return -EINVAL;
}
config.irq = irq;
@@ -1018,6 +946,12 @@ init_module(void)
mpu_config.irq = mpu_irq;
mpu_config.io_base = mpu_io;
+ if(spea != -1)
+ {
+ old_hardware = spea;
+ printk(KERN_INFO "Forcing %s hardware support.\n",
+ spea?"new":"old");
+ }
if (probe_sscape(&mpu_config) == 0)
return -ENODEV;
@@ -1031,8 +965,7 @@ init_module(void)
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
if (mss)
unload_ss_ms_sound(&config);
@@ -1041,5 +974,4 @@ cleanup_module(void)
}
#endif
-
#endif
diff --git a/drivers/sound/sys_timer.c b/drivers/sound/sys_timer.c
index 8097d1872..4d0456dd1 100644
--- a/drivers/sound/sys_timer.c
+++ b/drivers/sound/sys_timer.c
@@ -11,6 +11,9 @@
* 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>
@@ -184,94 +187,73 @@ def_tmr_get_time(int dev)
return curr_ticks;
}
-static int
-def_tmr_ioctl(int dev,
- unsigned int cmd, caddr_t arg)
+/* same as sound_timer.c:timer_ioctl!? */
+static int def_tmr_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
- switch (cmd)
- {
- case SNDCTL_TMR_SOURCE:
- return (*(int *) arg = TMR_INTERNAL);
- break;
+ int val;
- case SNDCTL_TMR_START:
- tmr_reset();
- tmr_running = 1;
- return 0;
- break;
+ switch (cmd) {
+ case SNDCTL_TMR_SOURCE:
+ return __put_user(TMR_INTERNAL, (int *)arg);
- case SNDCTL_TMR_STOP:
- tmr_running = 0;
- return 0;
- break;
-
- case SNDCTL_TMR_CONTINUE:
- tmr_running = 1;
- return 0;
- break;
-
- case SNDCTL_TMR_TIMEBASE:
- {
- int val;
-
- val = *(int *) arg;
-
- if (val)
- {
- if (val < 1)
- val = 1;
- if (val > 1000)
- val = 1000;
- curr_timebase = val;
- }
- return (*(int *) arg = curr_timebase);
- }
- break;
-
- case SNDCTL_TMR_TEMPO:
- {
- int val;
-
- val = *(int *) arg;
-
- if (val)
- {
- if (val < 8)
- val = 8;
- if (val > 250)
- val = 250;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks(tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = val;
- }
- return (*(int *) arg = curr_tempo);
- }
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- {
- int val;
-
- val = *(int *) arg;
- if (val != 0) /* Can't change */
- return -EINVAL;
-
- return (*(int *) arg = ((curr_tempo * curr_timebase) + 30) / 60);
- }
- break;
-
- case SNDCTL_SEQ_GETTIME:
- return (*(int *) arg = curr_ticks);
- break;
+ case SNDCTL_TMR_START:
+ tmr_reset();
+ tmr_running = 1;
+ return 0;
- case SNDCTL_TMR_METRONOME:
- /* NOP */
- break;
+ case SNDCTL_TMR_STOP:
+ tmr_running = 0;
+ return 0;
- default:;
- }
+ case SNDCTL_TMR_CONTINUE:
+ tmr_running = 1;
+ return 0;
+ case SNDCTL_TMR_TIMEBASE:
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val) {
+ if (val < 1)
+ val = 1;
+ if (val > 1000)
+ val = 1000;
+ curr_timebase = val;
+ }
+ return __put_user(curr_timebase, (int *)arg);
+
+ case SNDCTL_TMR_TEMPO:
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val) {
+ if (val < 8)
+ val = 8;
+ if (val > 250)
+ val = 250;
+ tmr_offs = tmr_ctr;
+ ticks_offs += tmr2ticks(tmr_ctr);
+ tmr_ctr = 0;
+ curr_tempo = val;
+ reprogram_timer();
+ }
+ return __put_user(curr_tempo, (int *)arg);
+
+ case SNDCTL_SEQ_CTRLRATE:
+ if (__get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val != 0) /* Can't change */
+ return -EINVAL;
+ val = ((curr_tempo * curr_timebase) + 30) / 60;
+ return __put_user(val, (int *)arg);
+
+ case SNDCTL_SEQ_GETTIME:
+ return __put_user(curr_ticks, (int *)arg);
+
+ case SNDCTL_TMR_METRONOME:
+ /* NOP */
+ break;
+
+ default:;
+ }
return -EINVAL;
}
diff --git a/drivers/sound/trix.c b/drivers/sound/trix.c
index 4c3d0fb2c..9b34c4422 100644
--- a/drivers/sound/trix.c
+++ b/drivers/sound/trix.c
@@ -27,12 +27,11 @@
#endif
#endif
-#ifdef INCLUDE_TRIX_BOOT
+#ifdef CONFIG_TRIX_HAVE_BOOT
#include "trix_boot.h"
#else
static unsigned char *trix_boot = NULL;
-static int trix_boot_len = 0;
-
+static int trix_boot_len = 0;
#endif
@@ -507,12 +506,12 @@ init_module(void)
if (sb_io != -1 && (sb_irq == -1 || sb_dma == -1))
{
- printk(KERN_INFO "SB_IRQ and SB_DMA must be specified if SB_IO is set.\n");
+ 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 "MPU_IRQ must be specified if MPU_IO is set.\n");
+ printk(KERN_INFO "CONFIG_MPU_IRQ must be specified if MPU_IO is set.\n");
return -EINVAL;
}
if (!trix_boot)
diff --git a/drivers/sound/uart401.c b/drivers/sound/uart401.c
index 63bfd9211..7293e9047 100644
--- a/drivers/sound/uart401.c
+++ b/drivers/sound/uart401.c
@@ -186,12 +186,6 @@ uart401_end_read(int dev)
return 0;
}
-static int
-uart401_ioctl(int dev, unsigned cmd, caddr_t arg)
-{
- return -EINVAL;
-}
-
static void
uart401_kick(int dev)
{
@@ -214,7 +208,7 @@ static struct midi_operations uart401_operations =
{0},
uart401_open,
uart401_close,
- uart401_ioctl,
+ NULL, /* ioctl */
uart401_out,
uart401_start_read,
uart401_end_read,
@@ -452,8 +446,8 @@ unload_uart401(struct address_info *hw_config)
if (!devc->share_irq)
snd_release_irq(devc->irq);
- if (!devc)
- vfree(devc);
+ if (devc)
+ devc = NULL;
sound_unload_mididev(hw_config->slots[4]);
}
diff --git a/drivers/sound/uart6850.c b/drivers/sound/uart6850.c
index 9285e40b1..932be1846 100644
--- a/drivers/sound/uart6850.c
+++ b/drivers/sound/uart6850.c
@@ -1,6 +1,3 @@
-
-
-
/*
* sound/uart6850.c
*/
@@ -25,35 +22,35 @@
#include "soundmodule.h"
#if defined(CONFIG_UART6850) && defined(CONFIG_MIDI) || defined(MODULE)
-static int uart6850_base = 0x330;
+static int uart6850_base = 0x330;
-static int *uart6850_osp;
+static int *uart6850_osp;
#define DATAPORT (uart6850_base)
#define COMDPORT (uart6850_base+1)
#define STATPORT (uart6850_base+1)
-static int
-uart6850_status(void)
+static int uart6850_status(void)
{
return inb(STATPORT);
}
+
#define input_avail() (uart6850_status()&INPUT_AVAIL)
#define output_ready() (uart6850_status()&OUTPUT_READY)
-static void
-uart6850_cmd(unsigned char cmd)
+
+static void uart6850_cmd(unsigned char cmd)
{
- outb((cmd), COMDPORT);
+ outb(cmd, COMDPORT);
}
-static int
-uart6850_read(void)
+
+static int uart6850_read(void)
{
return inb(DATAPORT);
}
-static void
-uart6850_write(unsigned char byte)
+
+static void uart6850_write(unsigned char byte)
{
- outb((byte), DATAPORT);
+ outb(byte, DATAPORT);
}
#define OUTPUT_READY 0x02 /* Mask for data ready Bit */
@@ -62,58 +59,58 @@ uart6850_write(unsigned char byte)
#define UART_RESET 0x95
#define UART_MODE_ON 0x03
-static int uart6850_opened = 0;
-static int uart6850_irq;
-static int uart6850_detected = 0;
-static int my_dev;
+static int uart6850_opened = 0;
+static int uart6850_irq;
+static int uart6850_detected = 0;
+static int my_dev;
-static int reset_uart6850(void);
-static void (*midi_input_intr) (int dev, unsigned char data);
-static void poll_uart6850(unsigned long dummy);
+static int reset_uart6850(void);
+static void (*midi_input_intr) (int dev, unsigned char data);
+static void poll_uart6850(unsigned long dummy);
-static struct timer_list uart6850_timer =
-{NULL, NULL, 0, 0, poll_uart6850};
+static struct timer_list uart6850_timer = {
+ NULL, NULL, 0, 0, poll_uart6850
+};
-static void
-uart6850_input_loop(void)
+static void uart6850_input_loop(void)
{
- int count;
+ int count = 10;
- count = 10;
-
- while (count) /*
- * Not timed out
- */
+ while (count)
+ {
+ /*
+ * Not timed out
+ */
if (input_avail())
- {
- unsigned char c = uart6850_read();
-
- count = 100;
-
- if (uart6850_opened & OPEN_READ)
- midi_input_intr(my_dev, c);
- } else
+ {
+ unsigned char c = uart6850_read();
+ count = 100;
+ if (uart6850_opened & OPEN_READ)
+ midi_input_intr(my_dev, c);
+ }
+ else
+ {
while (!input_avail() && count)
count--;
+ }
+ }
}
-void
-m6850intr(int irq, void *dev_id, struct pt_regs *dummy)
+void m6850intr(int irq, void *dev_id, struct pt_regs *dummy)
{
if (input_avail())
uart6850_input_loop();
}
/*
- * It looks like there is no input interrupts in the UART mode. Let's try
- * polling.
+ * It looks like there is no input interrupts in the UART mode. Let's try
+ * polling.
*/
-static void
-poll_uart6850(unsigned long dummy)
+static void poll_uart6850(unsigned long dummy)
{
- unsigned long flags;
+ unsigned long flags;
if (!(uart6850_opened & OPEN_READ))
return; /* Device has been closed */
@@ -124,34 +121,30 @@ poll_uart6850(unsigned long dummy)
if (input_avail())
uart6850_input_loop();
-
- {
- uart6850_timer.expires = (1) + jiffies;
- add_timer(&uart6850_timer);
- }; /*
- * Come back later
- */
+ uart6850_timer.expires = 1 + jiffies;
+ add_timer(&uart6850_timer);
+
+ /*
+ * Come back later
+ */
restore_flags(flags);
}
-static int
-uart6850_open(int dev, int mode,
+static int uart6850_open(int dev, int mode,
void (*input) (int dev, unsigned char data),
void (*output) (int dev)
)
{
if (uart6850_opened)
- {
- printk("Midi6850: Midi busy\n");
+ {
+/* printk("Midi6850: Midi busy\n");*/
return -EBUSY;
- };
+ };
MOD_INC_USE_COUNT;
uart6850_cmd(UART_RESET);
-
uart6850_input_loop();
-
midi_input_intr = input;
uart6850_opened = mode;
poll_uart6850(0); /*
@@ -161,22 +154,18 @@ uart6850_open(int dev, int mode,
return 0;
}
-static void
-uart6850_close(int dev)
+static void uart6850_close(int dev)
{
uart6850_cmd(UART_MODE_ON);
-
- del_timer(&uart6850_timer);;
+ del_timer(&uart6850_timer);
uart6850_opened = 0;
-
MOD_DEC_USE_COUNT;
}
-static int
-uart6850_out(int dev, unsigned char midi_byte)
+static int uart6850_out(int dev, unsigned char midi_byte)
{
- int timeout;
- unsigned long flags;
+ int timeout;
+ unsigned long flags;
/*
* Test for input since pending input seems to block the output.
@@ -198,47 +187,35 @@ uart6850_out(int dev, unsigned char midi_byte)
for (timeout = 30000; timeout > 0 && !output_ready(); timeout--); /*
* Wait
*/
-
if (!output_ready())
- {
- printk("Midi6850: Timeout\n");
- return 0;
- }
+ {
+ printk(KERN_WARNING "Midi6850: Timeout\n");
+ return 0;
+ }
uart6850_write(midi_byte);
return 1;
}
-static int
-uart6850_command(int dev, unsigned char *midi_byte)
+static int uart6850_command(int dev, unsigned char *midi_byte)
{
return 1;
}
-static int
-uart6850_start_read(int dev)
+static int uart6850_start_read(int dev)
{
return 0;
}
-static int
-uart6850_end_read(int dev)
+static int uart6850_end_read(int dev)
{
return 0;
}
-static int
-uart6850_ioctl(int dev, unsigned cmd, caddr_t arg)
+static void uart6850_kick(int dev)
{
- return -EINVAL;
}
-static void
-uart6850_kick(int dev)
-{
-}
-
-static int
-uart6850_buffer_status(int dev)
+static int uart6850_buffer_status(int dev)
{
return 0; /*
* No data in buffers
@@ -256,7 +233,7 @@ static struct midi_operations uart6850_operations =
{0},
uart6850_open,
uart6850_close,
- uart6850_ioctl,
+ NULL, /* ioctl */
uart6850_out,
uart6850_start_read,
uart6850_end_read,
@@ -266,26 +243,25 @@ static struct midi_operations uart6850_operations =
};
-void
-attach_uart6850(struct address_info *hw_config)
+void attach_uart6850(struct address_info *hw_config)
{
- int ok, timeout;
+ int ok, timeout;
unsigned long flags;
if ((my_dev = sound_alloc_mididev()) == -1)
- {
- printk(KERN_INFO "uart6850: Too many midi devices detected\n");
- return;
- }
+ {
+ printk(KERN_INFO "uart6850: Too many midi devices detected\n");
+ return;
+ }
uart6850_base = hw_config->io_base;
uart6850_osp = hw_config->osp;
uart6850_irq = hw_config->irq;
if (!uart6850_detected)
- {
- sound_unload_mididev(my_dev);
- return;
- }
+ {
+ sound_unload_mididev(my_dev);
+ return;
+ }
save_flags(flags);
cli();
@@ -293,9 +269,7 @@ attach_uart6850(struct address_info *hw_config)
* Wait
*/
uart6850_cmd(UART_MODE_ON);
-
ok = 1;
-
restore_flags(flags);
conf_printf("6850 Midi Interface", hw_config);
@@ -306,8 +280,7 @@ attach_uart6850(struct address_info *hw_config)
sequencer_init();
}
-static int
-reset_uart6850(void)
+static int reset_uart6850(void)
{
uart6850_read();
return 1; /*
@@ -316,10 +289,9 @@ reset_uart6850(void)
}
-int
-probe_uart6850(struct address_info *hw_config)
+int probe_uart6850(struct address_info *hw_config)
{
- int ok = 0;
+ int ok = 0;
uart6850_osp = hw_config->osp;
uart6850_base = hw_config->io_base;
@@ -329,13 +301,11 @@ probe_uart6850(struct address_info *hw_config)
return 0;
ok = reset_uart6850();
-
uart6850_detected = ok;
return ok;
}
-void
-unload_uart6850(struct address_info *hw_config)
+void unload_uart6850(struct address_info *hw_config)
{
snd_release_irq(hw_config->irq);
sound_unload_mididev(hw_config->slots[4]);
@@ -344,19 +314,21 @@ unload_uart6850(struct address_info *hw_config)
#ifdef MODULE
-int io = -1;
-int irq = -1;
+int io = -1;
+int irq = -1;
+
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
struct address_info cfg;
-int
-init_module(void)
+int init_module(void)
{
if (io == -1 || irq == -1)
- {
- printk("uart6850: irq and io must be set.\n");
- return -EINVAL;
- }
+ {
+ printk(KERN_INFO "uart6850: irq and io must be set.\n");
+ return -EINVAL;
+ }
cfg.io_base = io;
cfg.irq = irq;
@@ -367,8 +339,7 @@ init_module(void)
return 0;
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
unload_uart6850(&cfg);
SOUND_LOCK_END;
diff --git a/drivers/sound/v_midi.c b/drivers/sound/v_midi.c
new file mode 100644
index 000000000..12c221a68
--- /dev/null
+++ b/drivers/sound/v_midi.c
@@ -0,0 +1,296 @@
+/*
+ * sound/v_midi.c
+ *
+ * The low level driver for the Sound Blaster DS chips.
+ */
+/*
+ * Copyright (C) by Hannu Savolainen 1993-1996
+ *
+ * USS/Lite 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"
+
+#if defined(CONFIG_VMIDI) || defined(MODULE)
+
+#include "v_midi.h"
+
+static vmidi_devc *v_devc[2] = { NULL, NULL};
+static int midi1,midi2;
+static void *midi_mem = NULL;
+
+#ifdef MODULE
+
+static struct address_info config; /* dummy */
+
+int init_module(void)
+{
+ printk("MIDI Loopback device driver\n");
+ if (!probe_v_midi(&config))
+ return -ENODEV;
+ attach_v_midi(&config);
+ SOUND_LOCK;
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ unload_v_midi(&config);
+ SOUND_LOCK_END;
+}
+
+#endif
+
+/*
+ * The DSP channel can be used either for input or output. Variable
+ * 'sb_irq_mode' will be set when the program calls read or write first time
+ * after open. Current version doesn't support mode changes without closing
+ * and reopening the device. Support for this feature may be implemented in a
+ * future version of this driver.
+ */
+
+
+void (*midi_input_intr) (int dev, unsigned char data);
+
+static int v_midi_open (int dev, int mode,
+ void (*input) (int dev, unsigned char data),
+ void (*output) (int dev)
+)
+{
+ vmidi_devc *devc = midi_devs[dev]->devc;
+ unsigned long flags;
+
+ if (devc == NULL)
+ return -(ENXIO);
+
+ save_flags (flags);
+ cli();
+ if (devc->opened)
+ {
+ restore_flags (flags);
+ return -(EBUSY);
+ }
+ devc->opened = 1;
+ restore_flags (flags);
+
+ devc->intr_active = 1;
+
+ if (mode & OPEN_READ)
+ {
+ devc->input_opened = 1;
+ devc->midi_input_intr = input;
+ }
+
+ return 0;
+}
+
+static void v_midi_close (int dev)
+{
+ vmidi_devc *devc = midi_devs[dev]->devc;
+ unsigned long flags;
+
+ if (devc == NULL)
+ return;
+
+ save_flags (flags);
+ cli ();
+ devc->intr_active = 0;
+ devc->input_opened = 0;
+ devc->opened = 0;
+ restore_flags (flags);
+}
+
+static int v_midi_out (int dev, unsigned char midi_byte)
+{
+ vmidi_devc *devc = midi_devs[dev]->devc;
+ vmidi_devc *pdevc = midi_devs[devc->pair_mididev]->devc;
+
+ if (devc == NULL)
+ return -(ENXIO);
+
+ if (pdevc->input_opened > 0){
+ if (MIDIbuf_avail(pdevc->my_mididev) > 500)
+ return 0;
+ pdevc->midi_input_intr (pdevc->my_mididev, midi_byte);
+ }
+ return 1;
+}
+
+static int v_midi_start_read (int dev)
+{
+ return 0;
+}
+
+static int v_midi_end_read (int dev)
+{
+ vmidi_devc *devc = midi_devs[dev]->devc;
+ if (devc == NULL)
+ return -ENXIO;
+
+ devc->intr_active = 0;
+ return 0;
+}
+
+/* why -EPERM and not -EINVAL?? */
+
+static int v_midi_ioctl (int dev, unsigned cmd, caddr_t arg)
+{
+ return -EPERM;
+}
+
+
+#define MIDI_SYNTH_NAME "Loopback MIDI"
+#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
+
+#include "midi_synth.h"
+
+static struct midi_operations v_midi_operations =
+{
+ {"Loopback MIDI Port 1", 0, 0, SNDCARD_VMIDI},
+ &std_midi_synth,
+ {0},
+ v_midi_open,
+ v_midi_close,
+ v_midi_ioctl,
+ v_midi_out,
+ v_midi_start_read,
+ v_midi_end_read,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static struct midi_operations v_midi_operations2 =
+{
+ {"Loopback MIDI Port 2", 0, 0, SNDCARD_VMIDI},
+ &std_midi_synth,
+ {0},
+ v_midi_open,
+ v_midi_close,
+ v_midi_ioctl,
+ v_midi_out,
+ v_midi_start_read,
+ v_midi_end_read,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+/*
+ * We kmalloc just one of these - it makes life simpler and the code
+ * cleaner and the memory handling far more efficient
+ */
+
+struct vmidi_memory
+{
+ /* Must be first */
+ struct midi_operations m_ops[2];
+ struct synth_operations s_ops[2];
+ struct vmidi_devc v_ops[2];
+};
+
+void attach_v_midi (struct address_info *hw_config)
+{
+ struct vmidi_memory *m;
+ /* printk("Attaching v_midi device.....\n"); */
+
+ midi1 = sound_alloc_mididev();
+ if (midi1 == -1)
+ {
+ printk(KERN_ERR "v_midi: Too many midi devices detected\n");
+ return;
+ }
+
+ m=(struct vmidi_memory *)kmalloc(sizeof(struct vmidi_memory), GFP_KERNEL);
+ if (m == NULL)
+ {
+ printk(KERN_WARNING "Loopback MIDI: Failed to allocate memory\n");
+ sound_unload_mididev(midi1);
+ return;
+ }
+
+ midi_mem = m;
+
+ midi_devs[midi1] = &m->m_ops[0];
+
+
+ midi2 = sound_alloc_mididev();
+ if (midi2 == -1)
+ {
+ printk (KERN_ERR "v_midi: Too many midi devices detected\n");
+ kfree(m);
+ sound_unload_mididev(midi1);
+ return;
+ }
+
+ midi_devs[midi2] = &m->m_ops[1];
+
+ /* printk("VMIDI1: %d VMIDI2: %d\n",midi1,midi2); */
+
+ /* for MIDI-1 */
+ v_devc[0] = &m->v_ops[0];
+ memcpy ((char *) midi_devs[midi1], (char *) &v_midi_operations,
+ sizeof (struct midi_operations));
+
+ v_devc[0]->my_mididev = midi1;
+ v_devc[0]->pair_mididev = midi2;
+ v_devc[0]->opened = v_devc[0]->input_opened = 0;
+ v_devc[0]->intr_active = 0;
+ v_devc[0]->midi_input_intr = NULL;
+
+ midi_devs[midi1]->devc = v_devc[0];
+
+ midi_devs[midi1]->converter = &m->s_ops[0];
+ std_midi_synth.midi_dev = midi1;
+ memcpy ((char *) midi_devs[midi1]->converter, (char *) &std_midi_synth,
+ sizeof (struct synth_operations));
+ midi_devs[midi1]->converter->id = "V_MIDI 1";
+
+ /* for MIDI-2 */
+ v_devc[1] = &m->v_ops[1];
+
+ memcpy ((char *) midi_devs[midi2], (char *) &v_midi_operations2,
+ sizeof (struct midi_operations));
+
+ v_devc[1]->my_mididev = midi2;
+ v_devc[1]->pair_mididev = midi1;
+ v_devc[1]->opened = v_devc[1]->input_opened = 0;
+ v_devc[1]->intr_active = 0;
+ v_devc[1]->midi_input_intr = NULL;
+
+ midi_devs[midi2]->devc = v_devc[1];
+ midi_devs[midi2]->converter = &m->s_ops[1];
+
+ std_midi_synth.midi_dev = midi2;
+ memcpy ((char *) midi_devs[midi2]->converter, (char *) &std_midi_synth,
+ sizeof (struct synth_operations));
+ midi_devs[midi2]->converter->id = "V_MIDI 2";
+
+ sequencer_init();
+ /* printk("Attached v_midi device\n"); */
+}
+
+int probe_v_midi(struct address_info *hw_config)
+{
+ return(1); /* always OK */
+}
+
+
+void unload_v_midi(struct address_info *hw_config)
+{
+ sound_unload_mididev(midi1);
+ sound_unload_mididev(midi2);
+ kfree(midi_mem);
+}
+
+#endif
diff --git a/drivers/sound/v_midi.h b/drivers/sound/v_midi.h
new file mode 100644
index 000000000..ae759dc6b
--- /dev/null
+++ b/drivers/sound/v_midi.h
@@ -0,0 +1,15 @@
+typedef struct vmidi_devc {
+ int dev;
+
+ /* State variables */
+ int opened;
+
+
+ /* MIDI fields */
+ int my_mididev;
+ int pair_mididev;
+ int input_opened;
+ int intr_active;
+ void (*midi_input_intr) (int dev, unsigned char data);
+ } vmidi_devc;
+