summaryrefslogtreecommitdiffstats
path: root/drivers/sound
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-03-12 23:15:27 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-03-12 23:15:27 +0000
commitae38fd1e4c98588314a42097c5a5e77dcef23561 (patch)
treef9f10c203bb9e5fbad4810d1f8774c08dfad20ff /drivers/sound
parent466a823d79f41d0713b272e48fd73e494b0588e0 (diff)
Merge with Linux 2.3.50.
Diffstat (limited to 'drivers/sound')
-rw-r--r--drivers/sound/Config.in160
-rw-r--r--drivers/sound/Makefile86
-rw-r--r--drivers/sound/ac97_codec.c53
-rw-r--r--drivers/sound/ad1816.c227
-rw-r--r--drivers/sound/ad1848.c106
-rw-r--r--drivers/sound/ad1848.h28
-rw-r--r--drivers/sound/adlib_card.c54
-rw-r--r--drivers/sound/cs4232.c119
-rw-r--r--drivers/sound/cs4232.h11
-rw-r--r--drivers/sound/dev_table.c388
-rw-r--r--drivers/sound/dev_table.h328
-rw-r--r--drivers/sound/gus.h30
-rw-r--r--drivers/sound/gus_card.c131
-rw-r--r--drivers/sound/gus_midi.c6
-rw-r--r--drivers/sound/gus_vol.c6
-rw-r--r--drivers/sound/gus_wave.c14
-rw-r--r--drivers/sound/ics2101.c10
-rw-r--r--drivers/sound/mad16.c150
-rw-r--r--drivers/sound/maui.c186
-rw-r--r--drivers/sound/mpu401.c70
-rw-r--r--drivers/sound/mpu401.h21
-rw-r--r--drivers/sound/nm256_audio.c15
-rw-r--r--drivers/sound/opl3.c47
-rw-r--r--drivers/sound/opl3.h243
-rw-r--r--drivers/sound/opl3_hw.h246
-rw-r--r--drivers/sound/opl3sa.c88
-rw-r--r--drivers/sound/opl3sa2.c135
-rw-r--r--drivers/sound/pas2.h23
-rw-r--r--drivers/sound/pas2_card.c110
-rw-r--r--drivers/sound/pas2_midi.c3
-rw-r--r--drivers/sound/pas2_mixer.c2
-rw-r--r--drivers/sound/pas2_pcm.c2
-rw-r--r--drivers/sound/pss.c117
-rw-r--r--drivers/sound/sb.h10
-rw-r--r--drivers/sound/sb_card.c283
-rw-r--r--drivers/sound/sb_common.c51
-rw-r--r--drivers/sound/sgalaxy.c86
-rw-r--r--drivers/sound/softoss.c29
-rw-r--r--drivers/sound/sound_calls.h235
-rw-r--r--drivers/sound/sound_config.h12
-rw-r--r--drivers/sound/sound_syms.c2
-rw-r--r--drivers/sound/soundcard.c275
-rw-r--r--drivers/sound/soundmodule.h4
-rw-r--r--drivers/sound/sscape.c137
-rw-r--r--drivers/sound/trident.c837
-rw-r--r--drivers/sound/trident.h6
-rw-r--r--drivers/sound/trix.c151
-rw-r--r--drivers/sound/uart401.c81
-rw-r--r--drivers/sound/uart6850.c74
-rw-r--r--drivers/sound/v_midi.c57
-rw-r--r--drivers/sound/via82cxxx_audio.c1
-rw-r--r--drivers/sound/vidc.c23
-rw-r--r--drivers/sound/waveartist.c73
-rw-r--r--drivers/sound/wavfront.c50
-rw-r--r--drivers/sound/wf_midi.c67
55 files changed, 2408 insertions, 3351 deletions
diff --git a/drivers/sound/Config.in b/drivers/sound/Config.in
index c218ca69d..30ffe5cc0 100644
--- a/drivers/sound/Config.in
+++ b/drivers/sound/Config.in
@@ -81,79 +81,21 @@ fi
dep_tristate ' OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND
if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
- if [ "$CONFIG_SOUND_OSS" = "y" ]; then
- bool ' Persistent DMA buffers' CONFIG_SOUND_DMAP
- fi
-
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' AD1816(A) based cards (EXPERIMENTAL)' CONFIG_SOUND_AD1816 $CONFIG_SOUND
- if [ "$CONFIG_SOUND_AD1816" = "y" ]; then
- hex 'AD1816 audio I/O base 530, 604, E80 or F40' CONFIG_AD1816_BASE 530
- int 'AD1816 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_AD1816_IRQ 7
- int 'AD1816 audio DMA 0, 1 or 3' CONFIG_AD1816_DMA 0
- int 'AD1816 second (duplex) DMA 0, 1 or 3' CONFIG_AD1816_DMA2 3
- int 'AD1816 clock chip frequency' CONFIG_AD1816_CLOCK 33000
- fi
fi
dep_tristate ' Aztech Sound Galaxy (non-PnP) cards' CONFIG_SOUND_SGALAXY $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_SGALAXY" = "y" ]; then
- hex 'SGALAXY audio I/O base 530, 604, E80 or F40' CONFIG_SGALAXY_BASE 530
- int 'SGALAXY audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_SGALAXY_IRQ 11
- int 'SGALAXY audio DMA 0, 1 or 3' CONFIG_SGALAXY_DMA 0
- int 'SGALAXY second (duplex) DMA 0, 1 or 3' CONFIG_SGALAXY_DMA2 3
- hex 'SGALAXY SB I/O base 220 or 240' CONFIG_SGALAXY_SGBASE 220
- fi
-
dep_tristate ' Crystal CS4232 based (PnP) cards' CONFIG_SOUND_CS4232 $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_CS4232" = "y" ]; then
- hex 'CS4232 audio I/O base (normally 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
-
dep_tristate ' Ensoniq SoundScape support' CONFIG_SOUND_SSCAPE $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_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
-
dep_tristate ' Gravis Ultrasound support' CONFIG_SOUND_GUS $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_GUS" = "y" -o "$CONFIG_SOUND_GUS" = "m" ]; then
- bool ' 16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16
- bool ' GUS MAX support' CONFIG_GUSMAX
+ if [ "$CONFIG_SOUND_GUS" != "n" ]; then
+ bool ' 16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_SOUND_GUS16
+ bool ' GUS MAX support' CONFIG_SOUND_GUSMAX
fi
- if [ "$CONFIG_SOUND_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
-
dep_tristate ' Loopback MIDI device support' CONFIG_SOUND_VMIDI $CONFIG_SOUND_OSS
-
dep_tristate ' MediaTrix AudioTrix Pro support' CONFIG_SOUND_TRIX $CONFIG_SOUND_OSS
if [ "$CONFIG_SOUND_TRIX" = "y" ]; then
- hex 'TRIX audio I/O base 530, 604, E80 or F40' CONFIG_TRIX_BASE 530
- int 'TRIX audio IRQ 7, 9, 10 or 11' CONFIG_TRIX_IRQ 11
- int 'TRIX audio DMA 0, 1 or 3' CONFIG_TRIX_DMA 0
- int 'TRIX second (duplex) DMA 0, 1 or 3' CONFIG_TRIX_DMA2 3
- hex 'TRIX MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_TRIX_MPU_BASE 330
- int 'TRIX MIDI IRQ 3, 4, 5, 7 or 9' CONFIG_TRIX_MPU_IRQ 9
- hex 'TRIX SB I/O base 220, 210, 230, 240, 250, 260 or 270' CONFIG_TRIX_SB_BASE 220
- int 'TRIX SB IRQ 3, 4, 5 or 7' CONFIG_TRIX_SB_IRQ 7
- int 'TRIX 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 /etc/sound/trxpro.hex
@@ -161,58 +103,23 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
fi
dep_tristate ' Microsoft Sound System support' CONFIG_SOUND_MSS $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_MSS" = "y" ]; then
- bool ' Enable support for the SoundPro mixer' CONFIG_SOUND_SPRO
- 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
-
dep_tristate ' MPU-401 support (NOT for SB16)' CONFIG_SOUND_MPU401 $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_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
-
dep_tristate ' NM256AV/NM256ZX audio support' CONFIG_SOUND_NM256 $CONFIG_SOUND_OSS
-
dep_tristate ' OPTi MAD16 and/or Mozart based cards' CONFIG_SOUND_MAD16 $CONFIG_SOUND_OSS
if [ "$CONFIG_SOUND_MAD16" = "y" -o "$CONFIG_SOUND_MAD16" = "m" ]; then
bool ' Support MIDI in older MAD16 based cards (requires SB)' CONFIG_MAD16_OLDCARD
fi
- if [ "$CONFIG_SOUND_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
-
dep_tristate ' ProAudioSpectrum 16 support' CONFIG_SOUND_PAS $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_PAS" = "y" ]; then
- int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' CONFIG_PAS_IRQ 10
- int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' CONFIG_PAS_DMA 3
- bool ' Enable PAS16 joystick port' CONFIG_PAS_JOYSTICK
- fi
+ dep_bool ' Enable PAS16 joystick port' CONFIG_PAS_JOYSTICK $CONFIG_SOUND_PAS
dep_tristate ' PSS (AD1848, ADSP-2115, ESC614) support' CONFIG_SOUND_PSS $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_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, 9, 10, 11, 12' 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 /etc/sound/dsp001.ld
- fi
- fi
if [ "$CONFIG_SOUND_PSS" = "y" -o "$CONFIG_SOUND_PSS" = "m" ]; then
bool ' Enable PSS mixer (Beethoven ADSP-16 and other compatibile)' CONFIG_PSS_MIXER
fi
+ 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 /etc/sound/dsp001.ld
+ fi
dep_tristate ' SoftOSS software wave table engine' CONFIG_SOUND_SOFTOSS $CONFIG_SOUND_OSS
if [ "$CONFIG_SOUND_SOFTOSS" = "y" ]; then
@@ -221,27 +128,9 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
fi
dep_tristate ' 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SOUND_SB $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_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' CONFIG_SB_MPU_IRQ -1
- fi
-
dep_tristate ' Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS m
- if [ "$CONFIG_SOUND_WAVEFRONT" = "y" ]; then
- hex 'I/O base for WaveFront 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_WAVEFRONT_BASE 330
- int 'WaveFront IRQ 5, 9, 12 or 15' CONFIG_WAVEFRONT_IRQ 9
- fi
-
dep_tristate ' Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS
if [ "$CONFIG_SOUND_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 /etc/sound/oswf.mot
@@ -249,47 +138,14 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
fi
dep_tristate ' VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX $CONFIG_SOUND_OSS
-
dep_tristate ' Yamaha FM synthesizer (YM3812/OPL-3) support' CONFIG_SOUND_YM3812 $CONFIG_SOUND_OSS
-
dep_tristate ' Yamaha OPL3-SA1 audio controller' CONFIG_SOUND_OPL3SA1 $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_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
-
dep_tristate ' Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_OPL3SA2" = "y" ]; then
- int 'Chipset (-1 for autoprobe, 2, or 3)' CONFIG_OPL3SA2_CHIPSET -1
- hex 'OPL3SA2 audio I/O base (530 - F48 valid)' CONFIG_OPL3SA2_BASE 530
- int 'OPL3SA2 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_IRQ 9
- int 'OPL3SA2 audio DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA 0
- int 'OPL3SA2 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA2 1
- hex 'OPL3SA2 control I/O base (100 - FFE valid)' CONFIG_OPL3SA2_CTRL_BASE 370
- hex 'OPL3SA2 MIDI I/O base (300 - 334 valid)' CONFIG_OPL3SA2_MPU_BASE 330
- int 'OPL3SA2 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_MPU_IRQ 9
- fi
-
-
dep_tristate ' 6850 UART support' CONFIG_SOUND_UART6850 $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_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
if [ "$CONFIG_ARM" = "y" ]; then
dep_tristate ' VIDC 16-bit sound' CONFIG_SOUND_VIDC $CONFIG_SOUND_OSS
dep_tristate ' Netwinder WaveArtist' CONFIG_SOUND_WAVEARTIST $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_WAVEARTIST" != "n" ]; then
- hex ' WaveArtist I/O base' CONFIG_WAVEARTIST_BASE 250
- int ' WaveArtist IRQ' CONFIG_WAVEARTIST_IRQ 12
- int ' WaveArtist DMA' CONFIG_WAVEARTIST_DMA 3
- int ' WaveArtist second DMA' CONFIG_WAVEARTIST_DMA2 7
- fi
fi
diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile
index 41b55ea4c..2c5df3f14 100644
--- a/drivers/sound/Makefile
+++ b/drivers/sound/Makefile
@@ -23,7 +23,7 @@ endif
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
export-objs := ad1848.o audio_syms.o midi_syms.o mpu401.o \
- msnd.o opl3.o sb_card.o sequencer_syms.o \
+ msnd.o opl3.o sb_common.o sequencer_syms.o \
sound_core.o sound_syms.o uart401.o ad1816.o \
nm256_audio.o ac97.o ac97_codec.o
@@ -45,39 +45,36 @@ obj-$(CONFIG_DMASOUND) += dmasound.o
obj-$(CONFIG_SOUND_OSS) += sound.o
obj-$(CONFIG_SOUND_CS4232) += cs4232.o ad1848.o
-# In theory, there's probably no reason to include the uart401 code
-# to support a WaveFront card's CS4232 module. However, it makes
-# reconfiguring things require a recompile, so just leave this
-# here and try not to worry about the extra uart401 module.
+# Please leave it as is, cause the link order is significant !
-obj-$(CONFIG_SOUND_CS4232) += uart401.o
+obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
+obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o
+obj-$(CONFIG_SOUND_OPL3SA1) += opl3sa.o ad1848.o uart401.o
+obj-$(CONFIG_SOUND_SOFTOSS) += softoss2.o
+obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o
+obj-$(CONFIG_SOUND_MAD16) += mad16.o ad1848.o sb_lib.o uart401.o
+obj-$(CONFIG_SOUND_CS4232) += cs4232.o uart401.o
+obj-$(CONFIG_SOUND_OPL3SA2) += opl3sa2.o ad1848.o uart401.o mpu401.o
+obj-$(CONFIG_SOUND_MSS) += ad1848.o
+obj-$(CONFIG_SOUND_PAS) += pas2.o sb_lib.o uart401.o
+obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o
+obj-$(CONFIG_SOUND_WAVEFRONT) += wavefront.o
+obj-$(CONFIG_SOUND_MAUI) += maui.o mpu401.o
+obj-$(CONFIG_SOUND_MPU401) += mpu401.o
+obj-$(CONFIG_SOUND_UART6850) += uart6850.o
obj-$(CONFIG_SOUND_GUS) += gus.o ad1848.o
-obj-$(CONFIG_SOUND_MAD16) += mad16.o ad1848.o sb.o uart401.o
-obj-$(CONFIG_SOUND_VIA82CXXX) += via82cxxx_audio.o sb.o uart401.o ac97.o
-obj-$(CONFIG_SOUND_MAUI) += maui.o mpu401.o
-obj-$(CONFIG_SOUND_MPU401) += mpu401.o
+obj-$(CONFIG_SOUND_YM3812) += adlib_card.o opl3.o
+obj-$(CONFIG_SOUND_VMIDI) += v_midi.o
+obj-$(CONFIG_SOUND_VIDC) += vidc_mod.o
+obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
+obj-$(CONFIG_SOUND_SGALAXY) += sgalaxy.o ad1848.o
+obj-$(CONFIG_SOUND_AD1816) += ad1816.o
+
+obj-$(CONFIG_SOUND_VIA82CXXX) += via82cxxx_audio.o sb_lib.o uart401.o ac97.o
obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o
obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o
-obj-$(CONFIG_SOUND_MSS) += ad1848.o
-obj-$(CONFIG_SOUND_OPL3SA1) += opl3sa.o ad1848.o uart401.o
-obj-$(CONFIG_SOUND_OPL3SA2) += opl3sa2.o ad1848.o uart401.o mpu401.o
-obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o uart401.o
-obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
-obj-$(CONFIG_SOUND_SB) += sb.o uart401.o
-obj-$(CONFIG_SOUND_SOFTOSS) += softoss2.o
-obj-$(CONFIG_SOUND_SGALAXY) += sgalaxy.o ad1848.o
-obj-$(CONFIG_SOUND_AD1816) += ad1816.o
-obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o
-obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb.o uart401.o
-obj-$(CONFIG_SOUND_UART6850) += uart6850.o
-obj-$(CONFIG_SOUND_VMIDI) += v_midi.o
-obj-$(CONFIG_SOUND_YM3812) += adlib_card.o opl3.o
-obj-$(CONFIG_SOUND_VIDC) += vidc_mod.o
obj-$(CONFIG_SOUND_VWSND) += vwsnd.o
-obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
-obj-$(CONFIG_SOUND_WAVEFRONT) += wavefront.o
-obj-$(CONFIG_SOUND_NM256) += nm256.o
-
+obj-$(CONFIG_SOUND_NM256) += nm256_audio.o ac97.o
obj-$(CONFIG_SOUND_SONICVIBES) += sonicvibes.o
obj-$(CONFIG_SOUND_CMPCI) += cmpci.o
obj-$(CONFIG_SOUND_ES1370) += es1370.o
@@ -89,7 +86,7 @@ obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o
# Declare multi-part drivers.
list-multi := sound.o gus.o pas2.o sb.o softoss2.o vidc_mod.o \
- soundcore.o wavefront.o nm256.o
+ soundcore.o wavefront.o
sound-objs := \
dev_table.o soundcard.o sound_syms.o \
@@ -101,12 +98,11 @@ soundcore-objs := sound_core.o sound_firmware.o
gus-objs := gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
pas2-objs := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
-sb-objs := sb_audio.o sb_card.o sb_common.o sb_midi.o sb_mixer.o \
- sb_ess.o
+sb-objs := sb_card.o
+sb_lib-objs := sb_common.o sb_audio.o sb_midi.o sb_mixer.o sb_ess.o
softoss2-objs := softoss.o softoss_rs.o
vidc_mod-objs := vidc.o vidc_fill.o
wavefront-objs := wavfront.o wf_midi.o yss225.o
-nm256-objs := nm256_audio.o ac97.o
# Extract lists of the multi-part drivers.
@@ -125,20 +121,6 @@ obj-m := $(filter-out $(obj-y), $(obj-m))
int-m := $(filter-out $(int-y), $(int-m))
-
-# Set flags for secondary drivers.
-# I have to do this before I reduce obj-y to components.
-
-EXTRA_CFLAGS := $(sort \
- $(patsubst ad1848.o, -DCONFIG_SOUND_AD1848, \
- $(patsubst mpu401.o, -DCONFIG_SOUND_MPU_EMU, \
- $(patsubst sb.o, -DCONFIG_SOUND_SBDSP, \
- $(patsubst uart401.o, -DCONFIG_SOUND_UART401, \
- $(filter ad1848.o mpu401.o sb.o uart401.o, $(obj-y)) \
- )))))
-
-
-
# Take multi-part drivers out of obj-y and put components in.
obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y)
@@ -155,8 +137,8 @@ O_OBJS := $(filter-out $(export-objs), $(obj-y))
OX_OBJS := $(filter $(export-objs), $(obj-y))
M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
-MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m)))
-MIX_OBJS := $(sort $(filter $(export-objs), $(int-m)))
+#MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m)))
+#MIX_OBJS := $(sort $(filter $(export-objs), $(int-m)))
ifeq ($(CONFIG_LOWLEVEL_SOUND),y)
O_OBJS += lowlevel/lowlevel.o
@@ -183,6 +165,9 @@ pas2.o: $(pas2-objs)
sb.o: $(sb-objs)
$(LD) -r -o $@ $(sb-objs)
+sb_lib.o: $(sb_lib-objs)
+ $(LD) -r -o $@ $(sb_lib-objs)
+
softoss2.o: $(softoss2-objs)
$(LD) -r -o $@ $(softoss2-objs)
@@ -192,9 +177,6 @@ vidc_mod.o: $(vidc_mod-objs)
wavefront.o: $(wavefront-objs)
$(LD) -r -o $@ $(wavefront-objs)
-nm256.o: $(nm256-objs)
- $(LD) -r -o $@ $(nm256-objs)
-
# Firmware files that need translation
#
# The translated files are protected by a file that keeps track
diff --git a/drivers/sound/ac97_codec.c b/drivers/sound/ac97_codec.c
index 95bafcf20..32a3380e9 100644
--- a/drivers/sound/ac97_codec.c
+++ b/drivers/sound/ac97_codec.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* History
+ * v0.3 Feb 22 2000 Ollie Lho
+ * bug fix for record mask setting
* v0.2 Feb 10 2000 Ollie Lho
* add ac97_read_proc for /proc/driver/vnedor/ac97
* v0.1 Jan 14 2000 Ollie Lho <ollie@sis.com.tw>
@@ -40,7 +42,9 @@ static void ac97_set_mixer(struct ac97_codec *codec, unsigned int oss_mixer, uns
static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask);
static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
-#define arraysize(x) (sizeof(x)/sizeof((x)[0]))
+static int sigmatel_init(struct ac97_codec * codec);
+
+#define arraysize(x) (sizeof(x)/sizeof((x)[0]))
static struct {
unsigned int id;
@@ -50,14 +54,16 @@ static struct {
{0x414B4D00, "Asahi Kasei AK4540" , NULL},
{0x41445340, "Analog Devices AD1881" , NULL},
{0x43525900, "Cirrus Logic CS4297" , NULL},
+ {0x43525903, "Cirrus Logic CS4297" , NULL},
{0x43525913, "Cirrus Logic CS4297A" , NULL},
+ {0x43525923, "Cirrus Logic CS4298" , NULL},
{0x43525931, "Cirrus Logic CS4299" , NULL},
- {0x4e534331, "National Semiconductor LM4549", NULL},
+ {0x4e534331, "National Semiconductor LM4549" , NULL},
{0x83847600, "SigmaTel STAC????" , NULL},
{0x83847604, "SigmaTel STAC9701/3/4/5", NULL},
{0x83847605, "SigmaTel STAC9704" , NULL},
{0x83847608, "SigmaTel STAC9708" , NULL},
- {0x83847609, "SigmaTel STAC9721/23" , NULL},
+ {0x83847609, "SigmaTel STAC9721/23" , sigmatel_init},
{0x54524108, "TriTech TR28028" , NULL},
{0x574D4C00, "Wolfson WM9704" , NULL},
{0x00000000, NULL, NULL}
@@ -156,11 +162,12 @@ enum ac97_recsettings {
};
static unsigned int ac97_rm2oss[] = {
- [AC97_REC_MIC] = SOUND_MIXER_MIC,
- [AC97_REC_CD] = SOUND_MIXER_CD,
- [AC97_REC_VIDEO] = SOUND_MIXER_VIDEO,
- [AC97_REC_AUX] = SOUND_MIXER_LINE1,
- [AC97_REC_LINE] = SOUND_MIXER_LINE,
+ [AC97_REC_MIC] = SOUND_MIXER_MIC,
+ [AC97_REC_CD] = SOUND_MIXER_CD,
+ [AC97_REC_VIDEO] = SOUND_MIXER_VIDEO,
+ [AC97_REC_AUX] = SOUND_MIXER_LINE1,
+ [AC97_REC_LINE] = SOUND_MIXER_LINE,
+ [AC97_REC_STEREO]= SOUND_MIXER_IGAIN,
[AC97_REC_PHONE] = SOUND_MIXER_PHONEIN
};
@@ -171,6 +178,7 @@ static unsigned int ac97_oss_rm[] = {
[SOUND_MIXER_VIDEO] = AC97_REC_VIDEO,
[SOUND_MIXER_LINE1] = AC97_REC_AUX,
[SOUND_MIXER_LINE] = AC97_REC_LINE,
+ [SOUND_MIXER_IGAIN] = AC97_REC_STEREO,
[SOUND_MIXER_PHONEIN] = AC97_REC_PHONE
};
@@ -216,8 +224,10 @@ static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel)
}
#ifdef DEBUG
- printk("ac97_codec: read OSS mixer %2d (ac97 register 0x%02x), "
- "0x%04x -> 0x%04x\n", oss_channel, mh->offset, val, ret);
+ printk("ac97_codec: read OSS mixer %2d (%s ac97 register 0x%02x), "
+ "0x%04x -> 0x%04x\n",
+ oss_channel, codec->id ? "Secondary" : "Primary",
+ mh->offset, val, ret);
#endif
return ret;
@@ -269,6 +279,7 @@ static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel,
#ifdef DEBUG
printk(" 0x%04x", val);
#endif
+
codec->codec_write(codec, mh->offset, val);
#ifdef DEBUG
@@ -303,8 +314,11 @@ static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask)
if (rw) {
/* read it from the card */
- val = codec->codec_read(codec, 0x1a) & 0x7;
- return ac97_rm2oss[val];
+ val = codec->codec_read(codec, AC97_RECORD_SELECT);
+#ifdef DEBUG
+ printk("ac97_codec: ac97 recmask to set to 0x%04x\n", val);
+#endif
+ return (1 << ac97_rm2oss[val & 0x07]);
}
/* else, write the first set in the mask as the
@@ -315,10 +329,10 @@ static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask)
val |= val << 8; /* set both channels */
#ifdef DEBUG
- printk("ac97_codec: setting ac97 recmask to 0x%x\n", val);
+ printk("ac97_codec: setting ac97 recmask to 0x%04x\n", val);
#endif
- codec->codec_write(codec, 0x1a, val);
+ codec->codec_write(codec, AC97_RECORD_SELECT, val);
return 0;
};
@@ -384,9 +398,9 @@ static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned
return -EINVAL;
/* do we ever want to touch the hardware? */
- val = codec->read_mixer(codec, i);
- /* val = codec->mixer_state[i]; */
- break;
+ /* val = codec->read_mixer(codec, i); */
+ val = codec->mixer_state[i];
+ break;
}
return put_user(val, (int *)arg);
}
@@ -497,9 +511,10 @@ int ac97_probe_codec(struct ac97_codec *codec)
codec->codec_write(codec, AC97_RESET, 0L);
if ((cap = codec->codec_read(codec, AC97_RESET)) & 0x8000)
return 0;
-
+
codec->name = NULL;
codec->codec_init = NULL;
+
id1 = codec->codec_read(codec, AC97_VENDOR_ID1);
id2 = codec->codec_read(codec, AC97_VENDOR_ID2);
for (i = 0; i < arraysize(ac97_codec_ids); i++) {
@@ -520,6 +535,8 @@ int ac97_probe_codec(struct ac97_codec *codec)
codec->record_sources = AC97_RECORD_MASK;
if (!(cap & 0x04))
codec->supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE);
+ if (!(cap & 0x10))
+ codec->supported_mixers &= ~SOUND_MASK_ALTPCM;
/* generic OSS to AC97 wrapper */
codec->read_mixer = ac97_read_mixer;
diff --git a/drivers/sound/ad1816.c b/drivers/sound/ad1816.c
index 8813d519e..d44cf1389 100644
--- a/drivers/sound/ad1816.c
+++ b/drivers/sound/ad1816.c
@@ -1,59 +1,43 @@
/*
-
-AD1816 lowlevel sound driver for Linux 2.2.0 and above
-
-Copyright (C) 1998 by Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de>
-Based on the CS4232/AD1848 driver Copyright (C) by Hannu Savolainen 1993-1996
-
-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
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
--------------------------------------------------------------------------------
-NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE! NOTE!
-
-This software is still under development. New versions of the driver
-are available from:
- http://www.student.informatik.tu-darmstadt.de/~tek/projects/linux.html
-or
- http://www.tu-darmstadt.de/~tek01/projects/linux.html
-
-Please report any bugs to: tek@rbg.informatik.tu-darmstadt.de
-
--------------------------------------------------------------------------------
-
-version: 1.3
-cvs: $Header: /home/tek/CVSROOT/sound22/ad1816.c,v 1.3 1999/04/18 16:41:41 tek Exp $
-status: experimental
-date: 1999/4/18
-
-Changes:
- Oleg Drokin: Some cleanup of load/unload functions. 1998/11/24
-
- Thorsten Knabe: attach and unload rewritten,
- some argument checks added 1998/11/30
-
- Thorsten Knabe: Buggy isa bridge workaround added 1999/01/16
-
- David Moews/Thorsten Knabe: Introduced options
- parameter. Added slightly modified patch from
- David Moews to disable dsp audio sources by setting
- bit 0 of options parameter. This seems to be
- required by some Aztech/Newcom SC-16 cards. 1999/04/18
-
-*/
+ *
+ * AD1816 lowlevel sound driver for Linux 2.2.0 and above
+ *
+ * Copyright (C) 1998 by Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de>
+ *
+ * Based on the CS4232/AD1848 driver Copyright (C) by Hannu Savolainen 1993-1996
+ *
+ * This software is still under development. New versions of the driver
+ * are available from:
+ * http://www.student.informatik.tu-darmstadt.de/~tek/projects/linux.html
+ * or http://www.tu-darmstadt.de/~tek01/projects/linux.html
+ *
+ * Please report any bugs to: tek@rbg.informatik.tu-darmstadt.de
+ *
+ *
+ * version: 1.3
+ * cvs: $Header: /home/tek/CVSROOT/sound22/ad1816.c,v 1.3 1999/04/18 16:41:41 tek Exp $
+ * status: experimental
+ * date: 1999/4/18
+ *
+ * Changes:
+ * Oleg Drokin: Some cleanup of load/unload functions. 1998/11/24
+ *
+ * Thorsten Knabe: attach and unload rewritten,
+ * some argument checks added 1998/11/30
+ *
+ * Thorsten Knabe: Buggy isa bridge workaround added 1999/01/16
+ *
+ * David Moews/Thorsten Knabe: Introduced options
+ * parameter. Added slightly modified patch from
+ * David Moews to disable dsp audio sources by setting
+ * bit 0 of options parameter. This seems to be
+ * required by some Aztech/Newcom SC-16 cards. 1999/04/18
+ *
+ * Christoph Hellwig: Adapted to module_init/module_exit. 2000/03/03
+ */
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/stddef.h>
#include "soundmodule.h"
#include "sound_config.h"
@@ -96,14 +80,10 @@ typedef struct
int irq_ok;
int *osp;
-}
-
-ad1816_info;
-
-static int nr_ad1816_devs = 0;
-
-static int ad1816_clockfreq=33000;
+} ad1816_info;
+static int nr_ad1816_devs = 0;
+static int ad1816_clockfreq=33000;
static int options=0;
/* for backward mapping of irq to sound device */
@@ -617,7 +597,8 @@ static struct audio_driver ad1816_audio_driver =
/* Interrupt handler */
-void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
+
+static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
{
unsigned char status;
ad1816_info *devc;
@@ -1089,7 +1070,7 @@ static struct mixer_operations ad1816_mixer_operations =
/* replace with probe routine */
-int probe_ad1816 ( struct address_info *hw_config )
+static int __init probe_ad1816 ( struct address_info *hw_config )
{
ad1816_info *devc = &dev_info[nr_ad1816_devs];
int io_base=hw_config->io_base;
@@ -1097,7 +1078,6 @@ int probe_ad1816 ( struct address_info *hw_config )
int tmp;
printk("ad1816: AD1816 sounddriver Copyright (C) 1998 by Thorsten Knabe\n");
- printk("ad1816: $Header: /home/tek/CVSROOT/sound22/ad1816.c,v 1.3 1999/04/18 16:41:41 tek Exp $\n");
printk("ad1816: io=0x%x, irq=%d, dma=%d, dma2=%d, clockfreq=%d, options=%d isadmabug=%d\n",
hw_config->io_base,
hw_config->irq,
@@ -1183,7 +1163,7 @@ int probe_ad1816 ( struct address_info *hw_config )
*/
-void attach_ad1816 (struct address_info *hw_config)
+static void __init attach_ad1816 (struct address_info *hw_config)
{
int my_dev;
char dev_name[100];
@@ -1309,7 +1289,7 @@ void attach_ad1816 (struct address_info *hw_config)
}
}
-void unload_card(ad1816_info *devc)
+static void __exit unload_card(ad1816_info *devc)
{
int mixer, dev = 0;
@@ -1343,51 +1323,12 @@ void unload_card(ad1816_info *devc)
}
}
-void unload_ad1816 (struct address_info *hw_config)
-{
- int i;
- ad1816_info *devc = NULL;
-
- /* remove any soundcard */
- if (hw_config==NULL) {
- for (i = 0; i < nr_ad1816_devs; i++) {
- devc = &dev_info[i];
- unload_card(devc);
- }
- nr_ad1816_devs=0;
- } else {
- /* remove specified soundcard */
- for (i = 0; i < nr_ad1816_devs; i++) {
- int j;
-
- if (dev_info[i].base == hw_config->io_base) {
- devc = &dev_info[i];
- unload_card(devc);
- nr_ad1816_devs--;
- for ( j=i; j < nr_ad1816_devs ; j++) {
- dev_info[j] = dev_info[j+1];
- }
- i--;
- }
- }
- }
-}
-
-
-/* ----------------------------- 2.1.xxx module stuff ----------------- */
-
-EXPORT_SYMBOL(ad1816_interrupt);
-EXPORT_SYMBOL(probe_ad1816);
-EXPORT_SYMBOL(attach_ad1816);
-EXPORT_SYMBOL(unload_ad1816);
+static struct address_info cfg;
-
-#ifdef MODULE
-
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma2 = -1;
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma2 = -1;
MODULE_PARM(io,"i");
MODULE_PARM(irq,"i");
@@ -1396,33 +1337,59 @@ MODULE_PARM(dma2,"i");
MODULE_PARM(ad1816_clockfreq,"i");
MODULE_PARM(options,"i");
-struct address_info cfg;
+static int __init init_ad1816(void)
+{
+ cfg.io_base = io;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.dma2 = dma2;
+
+ if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.dma2 == -1) {
+ printk(KERN_INFO "ad1816: dma, dma2, irq and io must be set.\n");
+ return -EINVAL;
+ }
+ if (probe_ad1816(&cfg) == 0) {
+ return -ENODEV;
+ }
+
+ attach_ad1816(&cfg);
+ SOUND_LOCK;
+}
-int init_module(void)
+static void __exit cleanup_ad1816 (void)
{
- if (io == -1 || irq == -1 || dma == -1 || dma2 == -1) {
- printk("ad1816: dma, dma2, irq and io must be set.\n");
- return -EINVAL;
- }
- cfg.io_base = io;
- cfg.irq = irq;
- cfg.dma = dma;
- cfg.dma2 = dma2;
-
- if (probe_ad1816(&cfg) == 0) {
- return -ENODEV;
- }
- attach_ad1816(&cfg);
- SOUND_LOCK;
- return 0;
+ int i;
+ ad1816_info *devc = NULL;
+
+ /* remove any soundcard */
+ for (i = 0; i < nr_ad1816_devs; i++) {
+ devc = &dev_info[i];
+ unload_card(devc);
+ }
+ nr_ad1816_devs=0;
+
+ SOUND_LOCK_END;
}
+module_init(init_ad1816);
+module_exit(cleanup_ad1816);
-void cleanup_module(void)
+#ifndef MODULE
+static int __init setup_ad1816(char *str)
{
- unload_ad1816(NULL);
- SOUND_LOCK_END;
+ /* io, irq, dma, dma2 */
+ int ints[5];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma16 = ints[4];
+
+ return 1;
}
-#endif /* MODULE */
+__setup("ad1816=", setup_ad1816);
+#endif
diff --git a/drivers/sound/ad1848.c b/drivers/sound/ad1848.c
index b7d93fdb4..b7ad6f75c 100644
--- a/drivers/sound/ad1848.c
+++ b/drivers/sound/ad1848.c
@@ -22,16 +22,18 @@
* for more info.
*
*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * general sleep/wakeup clean up.
- * Alan Cox : reformatted. Fixed SMP bugs. Moved to kernel alloc/free
- * of irqs. Use dev_id.
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * general sleep/wakeup clean up.
+ * Alan Cox : reformatted. Fixed SMP bugs. Moved to kernel alloc/free
+ * of irqs. Use dev_id.
+ * Christoph Hellwig : adapted to module_init/module_exit
*
* Status:
* Tested. Believed fully functional.
*/
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
#include <linux/stddef.h>
@@ -40,6 +42,8 @@
#define DEB(x)
#define DEB1(x)
#include "sound_config.h"
+
+#include "ad1848.h"
#include "ad1848_mixer.h"
typedef struct
@@ -99,23 +103,19 @@ ad1848_port_info;
static int nr_ad1848_devs = 0;
int deskpro_xl = 0;
int deskpro_m = 0;
-#ifdef CONFIG_SOUND_SPRO
-int soundpro = 1;
-#else
int soundpro = 0;
-#endif
static volatile signed char irq2dev[17] = {
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1
};
-#ifdef MODULE
-
+#ifndef EXCLUDE_TIMERS
static int timer_installed = -1;
-
#endif
+static int loaded = 0;
+
static int ad_format_mask[10 /*devc->model */ ] =
{
0,
@@ -2502,6 +2502,11 @@ void attach_ms_sound(struct address_info *hw_config)
int dma = hw_config->dma;
int dma2 = hw_config->dma2;
+ if(hw_config->io_base != -1 || hw_config->irq == -1 || hw_config->dma == -1) {
+ printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
+ return;
+ }
+
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,
@@ -2568,6 +2573,9 @@ void attach_ms_sound(struct address_info *hw_config)
dma2, 0,
hw_config->osp);
request_region(hw_config->io_base, 4, "WSS config");
+
+ SOUND_LOCK;
+ loaded = 1;
}
void unload_ms_sound(struct address_info *hw_config)
@@ -2702,8 +2710,6 @@ EXPORT_SYMBOL(probe_ms_sound);
EXPORT_SYMBOL(attach_ms_sound);
EXPORT_SYMBOL(unload_ms_sound);
-#ifdef MODULE
-
MODULE_PARM(io, "i"); /* I/O for a raw AD1848 card */
MODULE_PARM(irq, "i"); /* IRQ to use */
MODULE_PARM(dma, "i"); /* First DMA channel */
@@ -2713,45 +2719,57 @@ MODULE_PARM(deskpro_xl, "i"); /* Special magic for Deskpro XL boxen */
MODULE_PARM(deskpro_m, "i"); /* Special magic for Deskpro M box */
MODULE_PARM(soundpro, "i"); /* More special magic for SoundPro chips */
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma2 = -1;
-int type = 0;
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma2 = -1;
+static int __initdata type = 0;
-static int loaded = 0;
-
-struct address_info hw_config;
+static struct address_info cfg;
-int init_module(void)
+static int __init init_ad1848(void)
{
printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n");
- if(io != -1)
- {
- if(irq == -1 || dma == -1)
- {
- printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
- return -EINVAL;
- }
- hw_config.irq = irq;
- hw_config.io_base = io;
- hw_config.dma = dma;
- hw_config.dma2 = dma2;
- hw_config.card_subtype = type;
- if(!probe_ms_sound(&hw_config))
- return -ENODEV;
- attach_ms_sound(&hw_config);
- loaded=1;
- }
- SOUND_LOCK;
- return 0;
+
+ cfg.irq = irq;
+ cfg.io_base = io;
+ cfg.dma = dma;
+ cfg.dma2 = dma2;
+ cfg.card_subtype = type;
+
+ if(probe_ms_sound(&cfg)) {
+ attach_ms_sound(&cfg);
+ return 0;
+ } else
+ return -ENODEV;
}
-void cleanup_module(void)
+static void __exit cleanup_ad1848(void)
{
SOUND_LOCK_END;
if(loaded)
- unload_ms_sound(&hw_config);
+ unload_ms_sound(&cfg);
}
-#endif /* MODULE */
+module_init(init_ad1848);
+module_exit(cleanup_ad1848);
+
+#ifndef MODULE
+static int __init setup_ad1848(char *str)
+{
+ /* io, irq, dma, dma2, type */
+ int ints[6];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma2 = ints[4];
+ type = ints[5];
+
+ return 1;
+}
+
+__setup("ad1848=", setup_ad1848);
+#endif
diff --git a/drivers/sound/ad1848.h b/drivers/sound/ad1848.h
new file mode 100644
index 000000000..2f2225546
--- /dev/null
+++ b/drivers/sound/ad1848.h
@@ -0,0 +1,28 @@
+/*
+ * ad1848.c
+ *
+ * Copyright: Christoph Hellwig <chhellwig@gmx.net>
+ */
+
+#define AD_F_CS4231 0x0001 /* Returned if a CS4232 (or compatible) detected */
+#define AD_F_CS4248 0x0001 /* Returned if a CS4248 (or compatible) detected */
+
+#define AD1848_SET_XTAL 1
+#define AD1848_MIXER_REROUTE 2
+
+#define AD1848_REROUTE(oldctl, newctl) \
+ ad1848_control(AD1848_MIXER_REROUTE, ((oldctl)<<8)|(newctl))
+
+
+int ad1848_init(char *name, int io_base, int irq, int dma_playback,
+ int dma_capture, int share_dma, int *osp);
+void ad1848_unload (int io_base, int irq, int dma_playback, int dma_capture, int share_dma);
+
+int ad1848_detect (int io_base, int *flags, int *osp);
+int ad1848_control(int cmd, int arg);
+
+void adintr(int irq, void *dev_id, struct pt_regs * dummy);
+void attach_ms_sound(struct address_info * hw_config);
+
+int probe_ms_sound(struct address_info *hw_config);
+void unload_ms_sound(struct address_info *hw_info);
diff --git a/drivers/sound/adlib_card.c b/drivers/sound/adlib_card.c
index 087c57b68..95974d444 100644
--- a/drivers/sound/adlib_card.c
+++ b/drivers/sound/adlib_card.c
@@ -11,47 +11,42 @@
*/
#include <linux/module.h>
+#include <linux/init.h>
+
#include "sound_config.h"
#include "soundmodule.h"
-void attach_adlib_card(struct address_info *hw_config)
+#include "opl3.h"
+
+static void __init attach_adlib_card(struct address_info *hw_config)
{
hw_config->slots[0] = opl3_init(hw_config->io_base, hw_config->osp);
request_region(hw_config->io_base, 4, "OPL3/OPL2");
}
-int probe_adlib(struct address_info *hw_config)
+static int __init probe_adlib(struct address_info *hw_config)
{
- if (check_region(hw_config->io_base, 4))
- {
+ if (check_region(hw_config->io_base, 4)) {
DDB(printk("opl3.c: I/O port %x already in use\n", hw_config->io_base));
return 0;
}
return opl3_detect(hw_config->io_base, hw_config->osp);
}
-void unload_adlib(struct address_info *hw_config)
-{
- release_region(hw_config->io_base, 4);
- sound_unload_synthdev(hw_config->slots[0]);
-}
+static struct address_info cfg;
-#ifdef MODULE
+static int __initdata io = -1;
-int io = -1;
MODULE_PARM(io, "i");
-EXPORT_NO_SYMBOLS;
-
-struct address_info cfg;
-
-int init_module(void)
+static int __init init_adlib(void)
{
- if (io == -1) {
+ cfg.io_base = io;
+
+ if (cfg.io_base == -1) {
printk(KERN_ERR "adlib: must specify I/O address.\n");
return -EINVAL;
}
- cfg.io_base = io;
if (probe_adlib(&cfg) == 0)
return -ENODEV;
attach_adlib_card(&cfg);
@@ -59,10 +54,27 @@ int init_module(void)
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_adlib(void)
{
- unload_adlib(&cfg);
+ release_region(cfg.io_base, 4);
+ sound_unload_synthdev(cfg.slots[0]);
+
SOUND_LOCK_END;
}
-#endif /* MODULE */
+module_init(init_adlib);
+module_exit(cleanup_adlib);
+
+#ifndef MODULE
+static int __init setup_adlib(char *str)
+{
+ /* io */
+ int ints[2];
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+
+ return 1;
+}
+__setup("adlib=", setup_adlib);
+#endif
diff --git a/drivers/sound/cs4232.c b/drivers/sound/cs4232.c
index 0778273f9..2098c85a8 100644
--- a/drivers/sound/cs4232.c
+++ b/drivers/sound/cs4232.c
@@ -1,5 +1,7 @@
/*
- * sound/cs4232.c
+ * Copyright (C) by Hannu Savolainen 1993-1997
+ *
+ * cs4232.c
*
* The low level driver for Crystal CS4232 based cards. The CS4232 is
* a PnP compatible chip which contains a CS4231A codec, SB emulation,
@@ -35,22 +37,21 @@
* Alan Cox Modularisation, Basic cleanups.
* Paul Barton-Davis Separated MPU configuration, added
* Tropez+ (WaveFront) support
- */
-
-/*
- * 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.
+ * Christoph Hellwig Adapted to module_init/module_exit,
+ * simple cleanups
*/
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/init.h>
#include "sound_config.h"
#include "soundmodule.h"
+#include "cs4232.h"
+#include "ad1848.h"
+#include "mpu401.h"
+
#define KEY_PORT 0x279 /* Same as LPT1 status port */
#define CSN_NUM 0x99 /* Just a random number */
@@ -78,11 +79,6 @@ int probe_cs4232_mpu(struct address_info *hw_config)
return 1;
}
-void attach_cs4232_mpu(struct address_info *hw_config)
-{
- /* Nothing needs doing */
-}
-
static unsigned char crystal_key[] = /* A 32 byte magic key sequence */
{
0x96, 0x35, 0x9a, 0xcd, 0xe6, 0xf3, 0x79, 0xbc,
@@ -215,8 +211,15 @@ int probe_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 base = hw_config->io_base,
+ irq = hw_config->irq,
+ dma1 = hw_config->dma,
+ dma2 = hw_config->dma2;
+
+ if (base == -1 || irq == -1 || dma1 == -1) {
+ printk(KERN_ERR "cs4232: dma, irq and io must be set.\n");
+ return;
+ }
if (dma2 == -1)
dma2 = dma1;
@@ -263,6 +266,7 @@ void attach_cs4232(struct address_info *hw_config)
}
hw_config->slots[1] = hw_config2.slots[1];
}
+ SOUND_LOCK;
}
void unload_cs4232(struct address_info *hw_config)
@@ -302,19 +306,18 @@ void unload_cs4232(struct address_info *hw_config)
}
}
-void unload_cs4232_mpu(struct address_info *hw_config)
-{
- /* Not required. Handled by cs4232_unload */
-}
+static struct address_info cfg;
+static struct address_info cfg_mpu;
-#ifdef MODULE
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma2 = -1;
+static int __initdata mpuio = -1;
+static int __initdata mpuirq = -1;
+static int __initdata synthio = -1;
+static int __initdata synthirq = -1;
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma2 = -1;
-int mpuio = -1;
-int mpuirq = -1;
MODULE_PARM(io,"i");
MODULE_PARM(irq,"i");
@@ -322,34 +325,20 @@ MODULE_PARM(dma,"i");
MODULE_PARM(dma2,"i");
MODULE_PARM(mpuio,"i");
MODULE_PARM(mpuirq,"i");
-
-int synthio = -1;
-int synthirq = -1;
MODULE_PARM(synthio,"i");
MODULE_PARM(synthirq,"i");
-EXPORT_NO_SYMBOLS;
-
-struct address_info cfg;
-struct address_info mpu_cfg;
-
/*
* Install a CS4232 based card. Need to have ad1848 and mpu401
* loaded ready.
*/
-int init_module(void)
+static int __init init_cs4232(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;
- }
#ifdef CONFIG_SOUND_WAVEFRONT_MODULE
if(synthio == -1)
printk(KERN_WARNING "cs4232: set synthio and synthirq to use the wavefront facilities.\n");
- else
- {
+ else {
synth_base = synthio;
synth_irq = synthirq;
}
@@ -363,32 +352,48 @@ int init_module(void)
cfg.dma = dma;
cfg.dma2 = dma2;
- mpu_cfg.io_base = -1;
- mpu_cfg.irq = -1;
+ cfg_mpu.io_base = -1;
+ cfg_mpu.irq = -1;
if (mpuio != -1 && mpuirq != -1) {
- mpu_cfg.io_base = mpuio;
- mpu_cfg.irq = mpuirq;
- probe_cs4232_mpu(&mpu_cfg); /* Bug always returns 0 not OK -- AC */
+ cfg_mpu.io_base = mpuio;
+ cfg_mpu.irq = mpuirq;
+ probe_cs4232_mpu(&cfg_mpu); /* Bug always returns 0 not OK -- AC */
}
if (probe_cs4232(&cfg) == 0)
return -ENODEV;
-
attach_cs4232(&cfg);
-
- if (mpuio != -1 && mpuirq != -1) {
- attach_cs4232_mpu(&mpu_cfg);
- }
-
- SOUND_LOCK;
+
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_cs4232(void)
{
unload_cs4232(&cfg); /* unloads MPU as well, if needed */
SOUND_LOCK_END;
}
-#endif /* MODULE */
+module_init(init_cs4232);
+module_exit(cleanup_cs4232);
+
+#ifndef MODULE
+static int __init setup_cs4232(char *str)
+{
+ /* io, irq, dma, dma2 mpuio, mpuirq*/
+ int ints[7];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma2 = ints[4];
+ mpuio = ints[5];
+ mpuirq = ints[6];
+
+ return 1;
+}
+
+__setup("cs4232=", setup_cs4232);
+#endif
diff --git a/drivers/sound/cs4232.h b/drivers/sound/cs4232.h
new file mode 100644
index 000000000..7b5782199
--- /dev/null
+++ b/drivers/sound/cs4232.h
@@ -0,0 +1,11 @@
+/*
+ * cs4232.h
+ *
+ * Copyright: Christoph Hellwig <chhellwig@gmx.net>
+ *
+ */
+
+int probe_cs4232 (struct address_info *hw_config);
+void attach_cs4232 (struct address_info *hw_config);
+int probe_cs4232_mpu (struct address_info *hw_config);
+void attach_cs4232_mpu (struct address_info *hw_config);
diff --git a/drivers/sound/dev_table.c b/drivers/sound/dev_table.c
index 5e9657c8a..5be9a1eef 100644
--- a/drivers/sound/dev_table.c
+++ b/drivers/sound/dev_table.c
@@ -2,9 +2,8 @@
* sound/dev_table.c
*
* Device call tables.
- */
-
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -15,7 +14,6 @@
#include <linux/config.h>
#include <linux/init.h>
-
#define _DEV_TABLE_C_
#include "sound_config.h"
@@ -23,387 +21,6 @@ int softoss_dev = 0;
int sound_started = 0;
int sndtable_get_cardcount(void);
-int snd_find_driver(int type)
-{
- int i, n = num_sound_drivers;
-
- for (i = 0; i < n; i++)
- if (sound_drivers[i].card_type == type)
- return i;
-
- return -1;
-}
-
-static void start_services(void)
-{
-#ifdef FIXME
- int soundcards_installed;
-
- if (!(soundcards_installed = sndtable_get_cardcount()))
- return; /* No cards detected */
-#endif
-
- if (num_audiodevs) /* Audio devices present */
- {
- int dev;
- for (dev = 0; dev < num_audiodevs; dev++)
- {
- }
- audio_init_devices();
- }
-
- return;
-}
-
-static void
-start_cards(void)
-{
- int i, n = num_sound_cards;
- int drv;
-
- sound_started = 1;
- if (trace_init)
- printk(KERN_DEBUG "Sound initialization started\n");
-
-#ifdef CONFIG_LOWLEVEL_SOUND
- {
- extern void sound_preinit_lowlevel_drivers(void);
- sound_preinit_lowlevel_drivers();
- }
-#endif
-
-/*
- * Check the number of cards actually defined in the table
- */
-
- for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
- 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; /*
- * Mark as not detected
- */
- }
- }
-#ifdef CONFIG_LOWLEVEL_SOUND
- {
- extern void sound_init_lowlevel_drivers(void);
- sound_init_lowlevel_drivers();
- }
-#endif
- if (trace_init)
- printk(KERN_DEBUG "Sound initialization complete\n");
-}
-
-void sndtable_init(void)
-{
- start_cards();
-}
-
-
-void sound_unload_drivers(void)
-{
- int i, n = num_sound_cards;
- int drv;
-
- if (!sound_started)
- return;
-
- if (trace_init)
- 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;
- }
- }
- }
- }
-
- for (i=0;i<num_audiodevs;i++)
- DMAbuf_deinit(i);
-
- if (trace_init)
- printk(KERN_DEBUG "Sound unload complete\n");
-}
-
-void sound_unload_driver(int type)
-{
- 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;
- }
- }
- }
- }
- }
- DEB(printk("\n"));
-}
-
-
-int sndtable_probe(int unit, struct address_info *hw_config)
-{
- int sel = -1;
-
- 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;
- }
- 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(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;
-}
-
-
-int sndtable_init_card(int unit, struct address_info *hw_config)
-{
- int i, n = num_sound_cards;
-
- DEB(printk("sndtable_init_card(%d) entered\n", unit));
-
- if (!unit)
- {
- 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; /*
- * Mark as not detected
- */
- 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)
-{
- return num_audiodevs + num_mixers + num_synths + num_midis;
-}
-
-int sndtable_identify_card(char *name)
-{
- 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;
- }
- }
- return 0;
-}
-
-static int __init sound_setup(char *str)
-{
- int i, n = num_sound_cards;
- int ints[32];
-
- str = get_options(str, ARRAY_SIZE(ints), ints);
-
- /*
- * First disable all drivers
- */
-
- for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
- snd_installed_cards[i].enabled = 0;
-
- if (ints[0] == 0 || ints[1] == 0)
- return 1;
- /*
- * 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 1;
- }
- 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(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;
- }
- }
-
- return 1;
-}
-
-__setup("sound=", sound_setup);
-
-
-struct address_info * sound_getconf(int card_type)
-{
- 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;
-
- return &snd_installed_cards[ptr].config;
-}
-
-
-
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)
@@ -619,4 +236,3 @@ 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 5c0cf1d0f..b15fd505c 100644
--- a/drivers/sound/dev_table.h
+++ b/drivers/sound/dev_table.h
@@ -370,318 +370,6 @@ struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
int num_sound_timers = 0;
#endif
-/*
- * List of low level drivers compiled into the kernel.
- */
-
-struct driver_info sound_drivers[] =
-{
-#ifdef CONFIG_SOUND_PSS
- {"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
-
-#ifdef CONFIG_SOUND_GUS
-#ifdef CONFIG_GUS16
- {"GUS16", 0, SNDCARD_GUS16, "Ultrasound 16-bit opt.", attach_gus_db16, probe_gus_db16, unload_gus_db16},
-#endif
- {"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
-
-#ifdef CONFIG_SOUND_MSS
- {"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},
-#endif
-
-#ifdef CONFIG_SOUND_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},
-#endif
-
-#ifdef CONFIG_SOUND_CS4232
- {"CS4232", 0, SNDCARD_CS4232, "CS4232", attach_cs4232, probe_cs4232, unload_cs4232},
-#endif
-#ifdef CONFIG_CS4232_MPU_BASE
- {"CS4232MPU", 0, SNDCARD_CS4232_MPU, "CS4232 MIDI", attach_cs4232_mpu, probe_cs4232_mpu, unload_cs4232_mpu},
-#endif
-
-#ifdef CONFIG_SOUND_OPL3SA2
- {"OPL3SA2", 0, SNDCARD_OPL3SA2, "OPL3SA2", attach_opl3sa2, probe_opl3sa2, unload_opl3sa2},
- {"OPL3SA2MSS", 1, SNDCARD_OPL3SA2_MSS, "OPL3SA2 MSS", attach_opl3sa2_mss, probe_opl3sa2_mss, unload_opl3sa2_mss},
- {"OPL3SA2MPU", 0, SNDCARD_OPL3SA2_MPU, "OPL3SA2 MIDI", attach_opl3sa2_mpu, probe_opl3sa2_mpu, unload_opl3sa2_mpu},
-#endif
-
-#ifdef CONFIG_SGALAXY
- {"SGALAXY", 0, SNDCARD_SGALAXY, "Sound Galaxy WSS", attach_sgalaxy, probe_sgalaxy, unload_sgalaxy},
-#endif
-
-#ifdef CONFIG_SOUND_AD1816
- {"AD1816", 0, SNDCARD_AD1816, "AD1816", attach_ad1816,
-probe_ad1816, unload_ad1816},
-#endif
-
-#ifdef CONFIG_SOUND_YM3812
- {"OPL3", 0, SNDCARD_ADLIB, "OPL-2/OPL-3 FM", attach_adlib_card, probe_adlib, unload_adlib},
-#endif
-
-#ifdef CONFIG_SOUND_PAS
- {"PAS16", 0, SNDCARD_PAS, "ProAudioSpectrum", attach_pas_card, probe_pas, unload_pas},
-#endif
-
-#if (defined(CONFIG_SOUND_MPU401) || defined(CONFIG_SOUND_MPU_EMU))
- {"MPU401", 0, SNDCARD_MPU401,"Roland MPU-401", attach_mpu401, probe_mpu401, unload_mpu401},
-#endif
-
-#if defined(CONFIG_SOUND_UART401)
- {"UART401", 0, SNDCARD_UART401,"MPU-401 (UART)",
- attach_uart401, probe_uart401, unload_uart401},
-#endif
-
-#if defined(CONFIG_SOUND_WAVEFRONT)
- {"WAVEFRONT", 0, SNDCARD_WAVEFRONT,"TB WaveFront", attach_wavefront, probe_wavefront, unload_wavefront},
-#endif
-
-#if defined(CONFIG_SOUND_MAUI)
- {"MAUI", 0, SNDCARD_MAUI,"TB Maui", attach_maui, probe_maui, unload_maui},
-#endif
-
-#if defined(CONFIG_SOUND_UART6850)
- {"MIDI6850", 0, SNDCARD_UART6850,"6860 UART Midi", attach_uart6850, probe_uart6850, unload_uart6850},
-#endif
-
-
-
-
-#ifdef CONFIG_SOUND_SBDSP
- {"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},
-
- {"SBMPU", 0, SNDCARD_SB16MIDI,"SB MPU-401", attach_sbmpu, probe_sbmpu, unload_sbmpu},
-#endif
-
-#ifdef CONFIG_SOUND_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_SOUND_OPL3SA1
- {"OPL3SA", 0, SNDCARD_OPL3SA1, "Yamaha OPL3-SA", attach_opl3sa_wss, probe_opl3sa_wss, unload_opl3sa_wss},
-/* {"OPL3SASB", 0, SNDCARD_OPL3SA1_SB, "OPL3-SA (SB mode)", attach_opl3sa_sb, probe_opl3sa_sb, unload_opl3sa_sb}, */
- {"OPL3SAMPU", 0, SNDCARD_OPL3SA1_MPU, "OPL3-SA MIDI", attach_opl3sa_mpu, probe_opl3sa_mpu, unload_opl3sa_mpu},
-#endif
-
-#ifdef CONFIG_SOUND_TRIX
- {"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
-
-#ifdef CONFIG_SOUND_SOFTOSS
- {"SOFTSYN", 0, SNDCARD_SOFTOSS, "SoftOSS Virtual Wave Table",
- attach_softsyn_card, probe_softsyn, unload_softsyn},
-#endif
-
-#ifdef CONFIG_SOUND_VMIDI
- {"VMIDI", 0, SNDCARD_VMIDI,"Loopback MIDI Device", attach_v_midi, probe_v_midi, unload_v_midi},
-#endif
-#ifdef CONFIG_SOUND_VIDC
- {"VIDC", 0, SNDCARD_VIDC, "ARM VIDC 16-bit D/A", attach_vidc, probe_vidc, unload_vidc },
-#endif
-#ifdef CONFIG_SOUND_WAVEARTIST
- {"WaveArtist", 0, SNDCARD_WAVEARTIST, "NetWinder WaveArtist", attach_waveartist, probe_waveartist, unload_waveartist },
-#endif
- {NULL, 0, 0, "*?*", NULL, NULL, NULL}
-};
-
-int num_sound_drivers = sizeof(sound_drivers) / sizeof (struct driver_info);
-
-
-/*
- * List of devices actually configured in the system.
- *
- * Note! The detection order is significant. Don't change it.
- */
-
-struct card_info snd_installed_cards[] =
-{
-#ifdef CONFIG_SOUND_PSS
- {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_SOUND_TRIX
-#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
-#endif
-
-#ifdef CONFIG_SOUND_OPL3SA1
- {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_SOUND_SOFTOSS
- {SNDCARD_SOFTOSS, {0, 0, -1, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_SSCAPE
- {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_SOUND_MAD16
-#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
-#endif
-
-#ifdef CONFIG_SOUND_CS4232
-#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
- {SNDCARD_CS4232, {CONFIG_CS4232_BASE, CONFIG_CS4232_IRQ, CONFIG_CS4232_DMA, CONFIG_CS4232_DMA2}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_OPL3SA2
-#ifndef CONFIG_OPL3SA2_DMA2
-#define CONFIG_OPL3SA2_DMA2 CONFIG_OPL3SA2_DMA
-#endif
- {SNDCARD_OPL3SA2, {CONFIG_OPL3SA2_CTRL_BASE, CONFIG_OPL3SA2_IRQ, CONFIG_OPL3SA2_DMA, CONFIG_OPL3SA2_DMA2}, SND_DEFAULT_ENABLE},
- {SNDCARD_OPL3SA2_MSS, {CONFIG_OPL3SA2_BASE, CONFIG_OPL3SA2_IRQ, CONFIG_OPL3SA2_DMA, CONFIG_OPL3SA2_DMA2}, SND_DEFAULT_ENABLE},
-#ifdef CONFIG_OPL3SA2_MPU_BASE
- {SNDCARD_OPL3SA2_MPU, {CONFIG_OPL3SA2_MPU_BASE, CONFIG_OPL3SA2_MPU_IRQ, CONFIG_OPL3SA2_DMA, -1}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SGALAXY
-#ifndef CONFIG_SGALAXY_DMA2
-#define CONFIG_SGALAXY_DMA2 CONFIG_SGALAXY_DMA
-#endif
- {SNDCARD_SGALAXY, {CONFIG_SGALAXY_BASE, CONFIG_SGALAXY_IRQ, CONFIG_SGALAXY_DMA, CONFIG_SGALAXY_DMA2, 0, NULL, CONFIG_SGALAXY_SGBASE}, SND_DEFAULT_ENABLE},
-#endif
-
-
-#ifdef CONFIG_SOUND_MSS
-#ifndef CONFIG_MSS_DMA2
-#define CONFIG_MSS_DMA2 -1
-#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_SOUND_PAS
- {SNDCARD_PAS, {CONFIG_PAS_BASE, CONFIG_PAS_IRQ, CONFIG_PAS_DMA, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_SB
-#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_WAVEFRONT)
- {SNDCARD_WAVEFRONT, {WAVEFRONT_BASE, WAVEFRONT_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_MAUI
- {SNDCARD_MAUI, {CONFIG_MAUI_BASE, CONFIG_MAUI_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_MPU401
- {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},
-#endif
-#ifdef MPU3_BASE
- {SNDCARD_MPU401, {MPU3_BASE, MPU3_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SOUND_UART6850
- {SNDCARD_UART6850, {CONFIG_U6850_BASE, CONFIG_U6850_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_SB
-#ifdef CONFIG_SB_MPU_BASE
- {SNDCARD_SB16MIDI,{CONFIG_SB_MPU_BASE, CONFIG_SB_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SOUND_GUS
-#ifndef CONFIG_GUS_DMA2
-#define CONFIG_GUS_DMA2 CONFIG_GUS_DMA
-#endif
-#ifdef CONFIG_GUS16
- {SNDCARD_GUS16, {CONFIG_GUS16_BASE, CONFIG_GUS16_IRQ, CONFIG_GUS16_DMA, -1}, SND_DEFAULT_ENABLE},
-#endif
- {SNDCARD_GUS, {CONFIG_GUS_BASE, CONFIG_GUS_IRQ, CONFIG_GUS_DMA, CONFIG_GUS_DMA2}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_YM3812
- {SNDCARD_ADLIB, {FM_MONO, 0, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_VMIDI
- {SNDCARD_VMIDI, {0, 0, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_VIDC
- { SNDCARD_VIDC, {0, 0, 0, 0}, SND_DEFAULT_ENABLE },
-#endif
-
-#ifdef CONFIG_SOUND_WAVEARTIST
- { SNDCARD_WAVEARTIST, { CONFIG_WAVEARTIST_BASE, CONFIG_WAVEARTIST_IRQ, CONFIG_WAVEARTIST_DMA, CONFIG_WAVEARTIST_DMA2 }, 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(MODULE)
-int trace_init = 0;
-#else
-int trace_init = 1;
-#endif
#else
extern struct audio_operations * audio_devs[MAX_AUDIO_DEV]; extern int num_audiodevs;
@@ -689,30 +377,16 @@ extern struct mixer_operations * mixer_devs[MAX_MIXER_DEV]; extern int num_mixer
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);
+void setup_cards(void);
int sndtable_get_cardcount (void);
-struct address_info *sound_getconf(int card_type);
void sound_chconf(int card_type, int ioaddr, int irq, int dma);
int snd_find_driver(int type);
-void sound_unload_drivers(void);
void sound_unload_driver(int type);
int sndtable_identify_card(char *name);
-#if FIXED_FOR_2_4_0
-void sound_setup (char *str, int *ints);
-#endif
-
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);
void sound_dma_intr (int dev, struct dma_buffparms *dmap, int chan);
diff --git a/drivers/sound/gus.h b/drivers/sound/gus.h
new file mode 100644
index 000000000..fe795ecdb
--- /dev/null
+++ b/drivers/sound/gus.h
@@ -0,0 +1,30 @@
+/*
+ * gus.h
+ *
+ * Copyright: Christoph Hellwig <chhellwig@gmx.net>
+ *
+ */
+
+#include "ad1848.h"
+
+/* From gus_card.c */
+int gus_set_midi_irq(int num);
+void gusintr(int irq, void *dev_id, struct pt_regs * dummy);
+
+/* From gus_wave.c */
+int gus_wave_detect(int baseaddr);
+void gus_wave_init(struct address_info *hw_config);
+void gus_wave_unload (struct address_info *hw_config);
+void gus_voice_irq(void);
+void gus_write8(int reg, unsigned int data);
+void guswave_dma_irq(void);
+void gus_delay(void);
+int gus_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg);
+void gus_timer_command (unsigned int addr, unsigned int val);
+
+/* From gus_midi.c */
+void gus_midi_init(struct address_info *hw_config);
+void gus_midi_interrupt(int dummy);
+
+/* From ics2101.c */
+int ics2101_mixer_init(void);
diff --git a/drivers/sound/gus_card.c b/drivers/sound/gus_card.c
index 6a42c4ce5..1029f179a 100644
--- a/drivers/sound/gus_card.c
+++ b/drivers/sound/gus_card.c
@@ -2,18 +2,13 @@
* sound/gus_card.c
*
* Detection routine for the Gravis Ultrasound.
- */
-
-/*
+ *
* 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.
- */
-/*
+ *
* Frank van de Pol : Fixed GUS MAX interrupt handling, enabled simultanious
* usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
+ * Christoph Hellwig: Adapted to module_init/module_exit, simple cleanups.
*
* Status:
* Tested...
@@ -21,11 +16,13 @@
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
#include "sound_config.h"
#include "soundmodule.h"
+#include "gus.h"
#include "gus_hw.h"
void gusintr(int irq, void *dev_id, struct pt_regs *dummy);
@@ -36,13 +33,12 @@ extern int gus_wave_volume;
extern int gus_pcm_volume;
extern int have_gus_max;
int gus_pnp_flag = 0;
-#ifdef CONFIG_GUS16
+#ifdef CONFIG_SOUND_GUS16
static int db16 = 0; /* Has a Gus16 AD1848 on it */
#endif
-void attach_gus_card(struct address_info *hw_config)
+static void __init attach_gus(struct address_info *hw_config)
{
-
gus_wave_init(hw_config);
request_region(hw_config->io_base, 16, "GUS");
@@ -57,9 +53,10 @@ void attach_gus_card(struct address_info *hw_config)
if(request_irq(hw_config->irq, gusintr, 0, "Gravis Ultrasound", hw_config)<0)
printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq);
+ return;
}
-int probe_gus(struct address_info *hw_config)
+static int __init probe_gus(struct address_info *hw_config)
{
int irq;
int io_addr;
@@ -102,10 +99,11 @@ int probe_gus(struct address_info *hw_config)
}
#endif
+ printk("NO GUS card found !\n");
return 0;
}
-void unload_gus(struct address_info *hw_config)
+static void __exit unload_gus(struct address_info *hw_config)
{
DDB(printk("unload_gus(%x)\n", hw_config->io_base));
@@ -128,13 +126,13 @@ void gusintr(int irq, void *dev_id, struct pt_regs *dummy)
sti();
-#ifdef CONFIG_GUSMAX
+#ifdef CONFIG_SOUND_GUSMAX
if (have_gus_max) {
struct address_info *hw_config = dev_id;
adintr(irq, (void *)hw_config->slots[1], NULL);
}
#endif
-#ifdef CONFIG_GUS16
+#ifdef CONFIG_SOUND_GUS16
if (db16) {
struct address_info *hw_config = dev_id;
adintr(irq, (void *)hw_config->slots[3], NULL);
@@ -170,14 +168,14 @@ void gusintr(int irq, void *dev_id, struct pt_regs *dummy)
* Some extra code for the 16 bit sampling option
*/
-#ifdef CONFIG_GUS16
+#ifdef CONFIG_SOUND_GUS16
-int probe_gus_db16(struct address_info *hw_config)
+static int __init 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)
+static void __init attach_gus_db16(struct address_info *hw_config)
{
gus_pcm_volume = 100;
gus_wave_volume = 90;
@@ -189,7 +187,7 @@ void attach_gus_db16(struct address_info *hw_config)
hw_config->osp);
}
-void unload_gus_db16(struct address_info *hw_config)
+static void __exit unload_gus_db16(struct address_info *hw_config)
{
ad1848_unload(hw_config->io_base,
@@ -200,27 +198,25 @@ void unload_gus_db16(struct address_info *hw_config)
}
#endif
+static int gus16 = 0;
+#ifdef CONFIG_SOUND_GUSMAX
+static int no_wave_dma = 0;/* Set if no dma is to be used for the
+ wave table (GF1 chip) */
+#endif
-#ifdef MODULE
-
-static struct address_info config;
-
/*
* Note DMA2 of -1 has the right meaning in the GUS driver as well
* as here.
*/
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma16 = -1; /* Set this for modules that need it */
-int type = 0; /* 1 for PnP */
-int gus16 = 0;
-#ifdef CONFIG_GUSMAX
-static int no_wave_dma = 0;/* Set if no dma is to be used for the
- wave table (GF1 chip) */
-#endif
+static struct address_info cfg;
+
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma16 = -1; /* Set this for modules that need it */
+static int __initdata type = 0; /* 1 for PnP */
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
@@ -228,54 +224,73 @@ MODULE_PARM(dma, "i");
MODULE_PARM(dma16, "i");
MODULE_PARM(type, "i");
MODULE_PARM(gus16, "i");
-#ifdef CONFIG_GUSMAX
+#ifdef CONFIG_SOUND_GUSMAX
MODULE_PARM(no_wave_dma, "i");
#endif
-#ifdef CONFIG_GUS16
+#ifdef CONFIG_SOUND_GUS16
MODULE_PARM(db16, "i");
#endif
-int init_module(void)
+static int __init init_gus(void)
{
printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
- if (io == -1 || dma == -1 || irq == -1)
- {
+ cfg.io_base = io;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.dma2 = dma16;
+ cfg.card_subtype = type;
+#ifdef CONFIG_SOUND_GUSMAX
+ gus_no_wave_dma = no_wave_dma;
+#endif
+
+ if (cfg.io_base == -1 || cfg.dma == -1 || cfg.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;
-
-#ifdef CONFIG_GUSMAX
- gus_no_wave_dma = no_wave_dma;
-#endif
-#if defined(CONFIG_GUS16)
- if (probe_gus_db16(&config) && gus16)
- {
- attach_gus_db16(&config);
+#ifdef CONFIG_SOUND_GUS16
+ if (probe_gus_db16(&cfg) && gus16) {
+ /* FIXME: This can't work, can it ? -- Christoph */
+ attach_gus_db16(&cfg);
db16 = 1;
}
#endif
- if (probe_gus(&config) == 0)
+ if (!probe_gus(&cfg))
return -ENODEV;
- attach_gus_card(&config);
+ attach_gus(&cfg);
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_gus(void)
{
-#if defined(CONFIG_GUS16)
+#ifdef CONFIG_SOUND_GUS16
if (db16)
- unload_gus_db16(&config);
+ unload_gus_db16(&cfg);
#endif
- unload_gus(&config);
+ unload_gus(&cfg);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+module_init(init_gus);
+module_exit(cleanup_gus);
+
+#ifndef MODULE
+static int __init setup_gus(char *str)
+{
+ /* io, irq, dma, dma2 */
+ int ints[5];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma16 = ints[4];
+
+ return 1;
+}
+
+__setup("gus=", setup_gus);
+#endif
diff --git a/drivers/sound/gus_midi.c b/drivers/sound/gus_midi.c
index 92987f46d..1594afb1a 100644
--- a/drivers/sound/gus_midi.c
+++ b/drivers/sound/gus_midi.c
@@ -2,8 +2,8 @@
* sound/gus2_midi.c
*
* The low level driver for the GUS Midi Interface.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -11,6 +11,8 @@
* for more info.
*/
#include "sound_config.h"
+
+#include "gus.h"
#include "gus_hw.h"
static int midi_busy = 0, input_opened = 0;
diff --git a/drivers/sound/gus_vol.c b/drivers/sound/gus_vol.c
index 8951cbfc3..6ae6924e1 100644
--- a/drivers/sound/gus_vol.c
+++ b/drivers/sound/gus_vol.c
@@ -1,8 +1,8 @@
/*
* gus_vol.c - Compute volume for GUS.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -10,6 +10,8 @@
* for more info.
*/
#include "sound_config.h"
+
+#include "gus.h"
#include "gus_linearvol.h"
#define GUS_VOLUME gus_wave_volume
diff --git a/drivers/sound/gus_wave.c b/drivers/sound/gus_wave.c
index 16eac5769..30ba0ede3 100644
--- a/drivers/sound/gus_wave.c
+++ b/drivers/sound/gus_wave.c
@@ -2,15 +2,15 @@
* sound/gus_wave.c
*
* Driver for the Gravis UltraSound wave table synth.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
- */
-/*
+ *
+ *
* Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
* Frank van de Pol : Fixed GUS MAX interrupt handling. Enabled simultanious
* usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
@@ -23,6 +23,8 @@
#include "sound_config.h"
#include <linux/ultrasound.h>
+
+#include "gus.h"
#include "gus_hw.h"
#define GUS_BANK_SIZE (((iw_mode) ? 256*1024*1024 : 256*1024))
@@ -3012,7 +3014,7 @@ void gus_wave_init(struct address_info *hw_config)
model_num = "MAX";
gus_type = 0x40;
mixer_type = CS4231;
-#ifdef CONFIG_GUSMAX
+#ifdef CONFIG_SOUND_GUSMAX
{
unsigned char max_config = 0x40; /* Codec enable */
@@ -3164,7 +3166,7 @@ void gus_wave_init(struct address_info *hw_config)
void gus_wave_unload(struct address_info *hw_config)
{
-#ifdef CONFIG_GUSMAX
+#ifdef CONFIG_SOUND_GUSMAX
if (have_gus_max)
{
ad1848_unload(gus_base + 0x10c,
diff --git a/drivers/sound/ics2101.c b/drivers/sound/ics2101.c
index a6b6fb4cc..3b97a157b 100644
--- a/drivers/sound/ics2101.c
+++ b/drivers/sound/ics2101.c
@@ -2,20 +2,22 @@
* sound/ics2101.c
*
* Driver for the ICS2101 mixer of GUS v3.7.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
- */
-/*
+ *
+ *
* Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
*/
#include "sound_config.h"
#include <linux/ultrasound.h>
+
+#include "gus.h"
#include "gus_hw.h"
#define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
diff --git a/drivers/sound/mad16.c b/drivers/sound/mad16.c
index dedf7c843..06b98aec2 100644
--- a/drivers/sound/mad16.c
+++ b/drivers/sound/mad16.c
@@ -1,14 +1,7 @@
/*
* Copyright (C) by Hannu Savolainen 1993-1997
*
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-#include <linux/config.h>
-#include <linux/module.h>
-/*
- * sound/mad16.c
+ * mad16.c
*
* Initialization code for OPTi MAD16 compatible audio chips. Including
*
@@ -72,22 +65,23 @@
*
* Paul Grayson Added support for Midi on later Mozart cards.
* 25-Nov-1999
+ * Christoph Hellwig Adapted to module_init/module_exit.
*/
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
#include "sound_config.h"
#include "soundmodule.h"
-#ifdef MODULE
-#define MAD16_CDSEL mad16_cdsel
-#define MAD16_CONF mad16_conf
+#include "ad1848.h"
+#include "sb.h"
+#include "mpu401.h"
static int mad16_conf;
static int mad16_cdsel;
-#endif
-
-#include "sb.h"
-
static int already_initialized = 0;
#define C928 1
@@ -222,7 +216,7 @@ static void mad_write(int port, int value)
restore_flags(flags);
}
-static int detect_c930(void)
+static int __init detect_c930(void)
{
unsigned char tmp = mad_read(MC1_PORT);
@@ -295,7 +289,7 @@ static int detect_c930(void)
return 1;
}
-static int detect_mad16(void)
+static int __init detect_mad16(void)
{
unsigned char tmp, tmp2, bit;
int i, port;
@@ -346,7 +340,7 @@ static int detect_mad16(void)
return 1; /* Bingo */
}
-static int wss_init(struct address_info *hw_config)
+static int __init wss_init(struct address_info *hw_config)
{
int ad_flags = 0;
@@ -397,7 +391,7 @@ static int wss_init(struct address_info *hw_config)
return 1;
}
-static int init_c930(struct address_info *hw_config)
+static int __init init_c930(struct address_info *hw_config)
{
unsigned char cfg = 0;
@@ -457,7 +451,7 @@ static int init_c930(struct address_info *hw_config)
return wss_init(hw_config);
}
-static int chip_detect(void)
+static int __init chip_detect(void)
{
int i;
@@ -536,7 +530,7 @@ static int chip_detect(void)
return 1;
}
-int probe_mad16(struct address_info *hw_config)
+static int __init probe_mad16(struct address_info *hw_config)
{
int i;
static int valid_ports[] =
@@ -646,7 +640,7 @@ int probe_mad16(struct address_info *hw_config)
return 1;
}
-void attach_mad16(struct address_info *hw_config)
+static void __init attach_mad16(struct address_info *hw_config)
{
static char interrupt_bits[12] = {
@@ -720,7 +714,7 @@ void attach_mad16(struct address_info *hw_config)
request_region(hw_config->io_base, 4, "MAD16 WSS config");
}
-void attach_mad16_mpu(struct address_info *hw_config)
+static void __init attach_mad16_mpu(struct address_info *hw_config)
{
#ifdef CONFIG_MAD16_OLDCARD
@@ -742,7 +736,7 @@ void attach_mad16_mpu(struct address_info *hw_config)
attach_uart401(hw_config);
}
-int probe_mad16_mpu(struct address_info *hw_config)
+static int __init probe_mad16_mpu(struct address_info *hw_config)
{
static int mpu_attached = 0;
static int valid_ports[] = {
@@ -898,7 +892,7 @@ int probe_mad16_mpu(struct address_info *hw_config)
return probe_uart401(hw_config);
}
-void unload_mad16(struct address_info *hw_config)
+static void __exit unload_mad16(struct address_info *hw_config)
{
ad1848_unload(hw_config->io_base + 4,
hw_config->irq,
@@ -908,8 +902,7 @@ void unload_mad16(struct address_info *hw_config)
sound_unload_audiodev(hw_config->slots[0]);
}
-void
-unload_mad16_mpu(struct address_info *hw_config)
+static void __exit unload_mad16_mpu(struct address_info *hw_config)
{
#ifdef CONFIG_MAD16_OLDCARD
if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
@@ -922,21 +915,23 @@ unload_mad16_mpu(struct address_info *hw_config)
unload_uart401(hw_config);
}
-#ifdef MODULE
+static struct address_info cfg;
+static struct address_info cfg_mpu;
-int mpu_io = 0;
-int mpu_irq = 0;
-int io = -1;
-int dma = -1;
-int dma16 = -1; /* Set this for modules that need it */
-int irq = -1;
+static int found_mpu;
-int cdtype = 0;
-int cdirq = 0;
-int cdport = 0x340;
-int cddma = -1;
-int opl4 = 0;
-int joystick = 0;
+static int __initdata mpu_io = 0;
+static int __initdata mpu_irq = 0;
+static int __initdata io = -1;
+static int __initdata dma = -1;
+static int __initdata dma16 = -1; /* Set this for modules that need it */
+static int __initdata irq = -1;
+static int __initdata cdtype = 0;
+static int __initdata cdirq = 0;
+static int __initdata cdport = 0x340;
+static int __initdata cddma = -1;
+static int __initdata opl4 = 0;
+static int __initdata joystick = 0;
MODULE_PARM(mpu_io, "i");
MODULE_PARM(mpu_irq, "i");
@@ -952,18 +947,13 @@ MODULE_PARM(opl4,"i");
MODULE_PARM(joystick,"i");
MODULE_PARM(debug,"i");
-EXPORT_NO_SYMBOLS;
-
-static int found_mpu;
-
-
-static int dma_map[2][8] =
+static int __initdata dma_map[2][8] =
{
{0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
{0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
};
-static int irq_map[16] =
+static int __initdata irq_map[16] =
{
0x00, -1, -1, 0x0A,
-1, 0x04, -1, 0x08,
@@ -971,20 +961,12 @@ static int irq_map[16] =
-1, -1, -1, -1
};
-struct address_info config;
-struct address_info config_mpu;
-
-int init_module(void)
+static int __init init_mad16(void)
{
int dmatype = 0;
printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
- if (io == -1 || dma == -1 || irq == -1)
- {
- printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
- return -EINVAL;
- }
printk(KERN_INFO "CDROM ");
switch (cdtype)
{
@@ -1089,33 +1071,61 @@ int init_module(void)
printk("disabled.\n");
}
- config.io_base = io;
- config.irq = irq;
- config.dma = dma;
- config.dma2 = dma16;
+ cfg.io_base = io;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.dma2 = dma16;
- if (!probe_mad16(&config))
+ if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
+ printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
+ return -EINVAL;
+ }
+
+ if (!probe_mad16(&cfg))
return -ENODEV;
- config_mpu.io_base = mpu_io;
- config_mpu.irq = mpu_irq;
- attach_mad16(&config);
+ cfg_mpu.io_base = mpu_io;
+ cfg_mpu.irq = mpu_irq;
+
+ attach_mad16(&cfg);
- found_mpu = probe_mad16_mpu(&config_mpu);
+ found_mpu = probe_mad16_mpu(&cfg_mpu);
if (found_mpu)
- attach_mad16_mpu(&config_mpu);
+ attach_mad16_mpu(&cfg_mpu);
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_mad16(void)
{
if (found_mpu)
- unload_mad16_mpu(&config_mpu);
- unload_mad16(&config);
+ unload_mad16_mpu(&cfg_mpu);
+ unload_mad16(&cfg);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+module_init(init_mad16);
+module_exit(exit_mad16);
+
+#ifndef MODULE
+static int __init setup_mad16(char *str)
+{
+ /* io, irq */
+ int ints[7];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma16 = ints[4];
+ mpu_io = ints[5];
+ mpu_irq = ints[6];
+
+ return 1;
+}
+
+__setup("mad16=", setup_mad16);
+#endif
diff --git a/drivers/sound/maui.c b/drivers/sound/maui.c
index 532e7573b..797150997 100644
--- a/drivers/sound/maui.c
+++ b/drivers/sound/maui.c
@@ -2,8 +2,8 @@
* sound/maui.c
*
* The low level driver for Turtle Beach Maui and Tropez.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -13,6 +13,7 @@
* Changes:
* Alan Cox General clean up, use kernel IRQ
* system
+ * Christoph Hellwig Adapted to module_init/module_exit
*
* Status:
* Andrew J. Kroll Tested 06/01/1999 with:
@@ -32,6 +33,8 @@
#include "soundmodule.h"
#include "sound_firmware.h"
+#include "mpu401.h"
+
static int maui_base = 0x330;
static volatile int irq_ok = 0;
@@ -62,19 +65,14 @@ static int maui_wait(int mask)
*/
for (i = 0; i < 100; i++)
- {
if (inb(HOST_STAT_PORT) & mask)
- {
return 1;
- }
- }
/*
* Wait up to 15 seconds with sleeping
*/
- for (i = 0; i < 150; i++)
- {
+ for (i = 0; i < 150; i++) {
if (inb(HOST_STAT_PORT) & mask)
return 1;
current->state = TASK_INTERRUPTIBLE;
@@ -94,8 +92,7 @@ static int maui_read(void)
static int maui_write(unsigned char data)
{
- if (maui_wait(STAT_TX_AVAIL))
- {
+ if (maui_wait(STAT_TX_AVAIL)) {
outb((data), HOST_DATA_PORT);
return 1;
}
@@ -116,56 +113,45 @@ static int download_code(void)
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')))
- {
+ 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')
- {
+ 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
- {
+ } else {
if (!maui_write(maui_os[i]))
goto failure;
}
- if (eol_seen)
- {
+ if (eol_seen) {
int c = 0;
int n;
eol_seen = 0;
- for (n = 0; n < 2; n++)
- {
- if (maui_wait(STAT_RX_AVAIL))
- {
+ for (n = 0; n < 2; n++) {
+ if (maui_wait(STAT_RX_AVAIL)) {
c = inb(HOST_DATA_PORT);
break;
}
}
- if (c != 0x80)
- {
+ if (c != 0x80) {
printk("Download not acknowledged\n");
return 0;
}
else if (!(lines++ % 10))
printk(".");
- if (done)
- {
+ if (done) {
printk("\n");
printk(KERN_INFO "Download complete\n");
return 1;
@@ -181,15 +167,11 @@ failure:
return 0;
}
-static int maui_init(int irq)
+static int __init maui_init(int irq)
{
-#ifdef CONFIG_SMP
- int i;
-#endif
unsigned char bits;
- switch (irq)
- {
+ switch (irq) {
case 9:
bits = 0x00;
break;
@@ -215,10 +197,13 @@ static int maui_init(int irq)
outb((0xD0), HOST_CTRL_PORT); /* Cause interrupt */
#ifdef CONFIG_SMP
- for (i = 0; i < 1000000 && !irq_ok; i++);
-
- if (!irq_ok)
- return 0;
+ {
+ int i;
+ for (i = 0; i < 1000000 && !irq_ok; i++)
+ ;
+ if (!irq_ok)
+ return 0;
+ }
#endif
outb((0x80), HOST_CTRL_PORT); /* Leave reset */
@@ -233,8 +218,7 @@ static int maui_init(int irq)
maui_write(0xf0);
maui_write(1);
- if (maui_read() != 0x80)
- {
+ if (maui_read() != 0x80) {
maui_write(0xf0);
maui_write(1);
if (maui_read() != 0x80)
@@ -244,14 +228,11 @@ static int maui_init(int irq)
return 1;
}
-static int maui_short_wait(int mask)
-{
+static int maui_short_wait(int mask) {
int i;
- for (i = 0; i < 1000; i++)
- {
- if (inb(HOST_STAT_PORT) & mask)
- {
+ for (i = 0; i < 1000; i++) {
+ if (inb(HOST_STAT_PORT) & mask) {
return 1;
}
}
@@ -274,8 +255,7 @@ static int maui_load_patch(int dev, int format, const char *addr,
{
printk(KERN_WARNING "Maui: Unknown patch format\n");
}
- if (count < hdr_size)
- {
+ if (count < hdr_size) {
/* printk("Maui error: Patch header too short\n");*/
return -EINVAL;
}
@@ -289,16 +269,14 @@ static int maui_load_patch(int dev, int format, const char *addr,
if(copy_from_user(&((char *) &header)[offs], &(addr)[offs], hdr_size - offs))
return -EFAULT;
- if (count < header.len)
- {
+ if (count < 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++)
- {
+ for (i = 0; i < left; i++) {
unsigned char data;
if(get_user(*(unsigned char *) &data, (unsigned char *) &((addr)[hdr_size + i])))
@@ -310,8 +288,7 @@ static int maui_load_patch(int dev, int format, const char *addr,
return -EIO;
}
- if ((i = maui_read()) != 0x80)
- {
+ if ((i = maui_read()) != 0x80) {
if (i != -1)
printk("Maui: Error status %02x\n", i);
return -EIO;
@@ -319,7 +296,7 @@ static int maui_load_patch(int dev, int format, const char *addr,
return 0;
}
-int probe_maui(struct address_info *hw_config)
+static int __init probe_maui(struct address_info *hw_config)
{
int i;
int tmp1, tmp2, ret;
@@ -337,55 +314,46 @@ int probe_maui(struct address_info *hw_config)
* Initialize the processor if necessary
*/
- if (maui_osLen > 0)
- {
+ 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))
- {
+ if (!maui_init(hw_config->irq)) {
free_irq(hw_config->irq, NULL);
return 0;
}
}
- if (!maui_write(0xCF)) /* Report hardware version */
- {
+ if (!maui_write(0xCF)) /* Report hardware version */ {
printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
free_irq(hw_config->irq, NULL);
return 0;
}
- if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
- {
+ if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) {
printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
free_irq(hw_config->irq, NULL);
return 0;
}
- if (tmp1 == 0xff || tmp2 == 0xff)
- {
+ if (tmp1 == 0xff || tmp2 == 0xff) {
free_irq(hw_config->irq, NULL);
return 0;
}
- if (trace_init)
- printk(KERN_DEBUG "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;
if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
return 0;
- if (trace_init)
- printk(KERN_DEBUG "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++)
- {
+ for (i = 0; i < 4; i++) {
tmp1 |= maui_read() << (7 * i);
}
- if (trace_init)
- printk(KERN_DEBUG "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))
@@ -399,7 +367,7 @@ int probe_maui(struct address_info *hw_config)
return ret;
}
-void attach_maui(struct address_info *hw_config)
+static void __init attach_maui(struct address_info *hw_config)
{
int this_dev;
@@ -409,8 +377,7 @@ void attach_maui(struct address_info *hw_config)
hw_config->name = "Maui";
attach_mpu401(hw_config);
- if (hw_config->slots[1] != -1) /* The MPU401 driver installed itself */
- {
+ if (hw_config->slots[1] != -1) /* The MPU401 driver installed itself */ {
struct synth_operations *synth;
this_dev = hw_config->slots[1];
@@ -423,17 +390,15 @@ void attach_maui(struct address_info *hw_config)
synth = midi_devs[this_dev]->converter;
synth->id = "MAUI";
- if (synth != NULL)
- {
+ if (synth != NULL) {
orig_load_patch = synth->load_patch;
synth->load_patch = &maui_load_patch;
- }
- else
+ } else
printk(KERN_ERR "Maui: Can't install patch loader\n");
}
}
-void unload_maui(struct address_info *hw_config)
+static void __exit unload_maui(struct address_info *hw_config)
{
int irq = hw_config->irq;
release_region(hw_config->io_base + 2, 6);
@@ -445,37 +410,33 @@ void unload_maui(struct address_info *hw_config)
free_irq(irq, NULL);
}
-#ifdef MODULE
-
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
-
-EXPORT_NO_SYMBOLS;
+static int fw_load = 0;
-int io = -1;
-int irq = -1;
+static struct address_info cfg;
-static int fw_load = 0;
+static int __initdata io = -1;
+static int __initdata irq = -1;
-struct address_info cfg;
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
/*
* Install a Maui card. Needs mpu401 loaded already.
*/
-int init_module(void)
+static int __init init_maui(void)
{
printk(KERN_INFO "Turtle beach Maui and Tropez driver, Copyright (C) by Hannu Savolainen 1993-1996\n");
- if (io == -1 || irq == -1)
- {
+
+ cfg.io_base = io;
+ cfg.irq = irq;
+
+ if (cfg.io_base == -1 || cfg.irq == -1) {
printk(KERN_INFO "maui: irq and io must be set.\n");
return -EINVAL;
}
- cfg.io_base = io;
- cfg.irq = irq;
- if (maui_os == NULL)
- {
+ if (maui_os == NULL) {
fw_load = 1;
maui_osLen = mod_firmware_load("/etc/sound/oswf.mot", (char **) &maui_os);
}
@@ -486,11 +447,30 @@ int init_module(void)
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_maui(void)
{
if (fw_load && maui_os)
vfree(maui_os);
unload_maui(&cfg);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+
+module_init(init_maui);
+module_exit(cleanup_maui);
+
+#ifndef MODULE
+static int __init setup_maui(char *str)
+{
+ /* io, irq */
+ int ints[3];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+
+ return 1;
+}
+
+__setup("maui=", setup_maui);
+#endif
diff --git a/drivers/sound/mpu401.c b/drivers/sound/mpu401.c
index 8a334d263..2757659ac 100644
--- a/drivers/sound/mpu401.c
+++ b/drivers/sound/mpu401.c
@@ -15,6 +15,7 @@
* Alan Cox modularisation, use normal request_irq, use dev_id
*/
+#include <linux/init.h>
#include <linux/module.h>
#define USE_SEQ_MACROS
@@ -24,7 +25,7 @@
#include "soundmodule.h"
#include "coproc.h"
-
+#include "mpu401.h"
static int timer_mode = TMR_INTERNAL, timer_caps = TMR_INTERNAL;
@@ -910,7 +911,7 @@ static struct midi_operations mpu401_midi_proto =
static struct midi_operations mpu401_midi_operations[MAX_MIDI_DEV];
-static void mpu401_chk_version(int n, struct mpu_config *devc)
+static void __init mpu401_chk_version(int n, struct mpu_config *devc)
{
int tmp;
unsigned long flags;
@@ -941,7 +942,7 @@ static void mpu401_chk_version(int n, struct mpu_config *devc)
restore_flags(flags);
}
-void attach_mpu401(struct address_info *hw_config)
+void __init attach_mpu401(struct address_info *hw_config)
{
unsigned long flags;
char revision_char;
@@ -1164,7 +1165,7 @@ static void set_uart_mode(int dev, struct mpu_config *devc, int arg)
}
-int probe_mpu401(struct address_info *hw_config)
+int __init probe_mpu401(struct address_info *hw_config)
{
int ok = 0;
struct mpu_config tmp_devc;
@@ -1197,7 +1198,7 @@ int probe_mpu401(struct address_info *hw_config)
return ok;
}
-void unload_mpu401(struct address_info *hw_config)
+void __exit unload_mpu401(struct address_info *hw_config)
{
void *p;
int n=hw_config->slots[1];
@@ -1659,7 +1660,7 @@ static void timer_ext_event(struct mpu_config *devc, int event, int parm)
}
}
-static int mpu_timer_init(int midi_dev)
+static int __init mpu_timer_init(int midi_dev)
{
struct mpu_config *devc;
int n;
@@ -1713,39 +1714,56 @@ EXPORT_SYMBOL(unload_mpu401);
EXPORT_SYMBOL(intchk_mpu401);
EXPORT_SYMBOL(mpuintr);
-#ifdef MODULE
+static struct address_info cfg;
+
+static int __initdata io = -1;
+static int __initdata irq = -1;
MODULE_PARM(irq, "i");
MODULE_PARM(io, "i");
-int io = -1;
-int irq = -1;
-struct address_info hw;
-
-int init_module(void)
+int init_mpu401(void)
{
/* Can be loaded either for module use or to provide functions
to others */
- if (io != -1 && irq != -1)
- {
- hw.irq = irq;
- hw.io_base = io;
- if (probe_mpu401(&hw) == 0)
- return -ENODEV;
- attach_mpu401(&hw);
+ cfg.irq = irq;
+ cfg.io_base = io;
+
+ if (cfg.io_base != -1 && cfg.irq != -1) {
+ printk(KERN_WARNING "mpu401: need io and irq !");
+ return -ENODEV;
}
+
+ if (probe_mpu401(&cfg) == 0)
+ return -ENODEV;
+ attach_mpu401(&cfg);
+
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+void cleanup_mpu401(void)
{
- if (io != -1 && irq != -1)
- {
- unload_mpu401(&hw);
- }
- /* FREE SYMTAB */
+ unload_mpu401(&cfg);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+module_init(init_mpu401);
+module_exit(cleanup_mpu401);
+
+#ifndef MODULE
+static int __init setup_mpu401(char *str)
+{
+ /* io, irq */
+ int ints[3];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+
+ return 1;
+}
+
+__setup("mpu401=", setup_mpu401);
+#endif
diff --git a/drivers/sound/mpu401.h b/drivers/sound/mpu401.h
new file mode 100644
index 000000000..a6a41cbde
--- /dev/null
+++ b/drivers/sound/mpu401.h
@@ -0,0 +1,21 @@
+/*
+ * uart401.h
+ *
+ * Copyright: Christoph Hellwig <chhellwig@gmx.net>
+ *
+ */
+
+/* From uart401.c */
+int probe_uart401 (struct address_info *hw_config);
+void attach_uart401 (struct address_info *hw_config);
+void unload_uart401 (struct address_info *hw_config);
+
+void uart401intr (int irq, void *dev_id, struct pt_regs * dummy);
+
+/* From mpu401.c */
+int probe_mpu401(struct address_info *hw_config);
+void attach_mpu401(struct address_info * hw_config);
+void unload_mpu401(struct address_info *hw_info);
+
+int intchk_mpu401(void *dev_id);
+void mpuintr(int irq, void *dev_id, struct pt_regs * dummy);
diff --git a/drivers/sound/nm256_audio.c b/drivers/sound/nm256_audio.c
index 53e54404a..ef0a1ce2e 100644
--- a/drivers/sound/nm256_audio.c
+++ b/drivers/sound/nm256_audio.c
@@ -15,6 +15,7 @@
#define __NO_VERSION__
#include <linux/pci.h>
+#include <linux/init.h>
#include <linux/module.h>
#include <linux/pm.h>
#include "sound_config.h"
@@ -1639,8 +1640,6 @@ static struct audio_driver nm256_audio_driver =
EXPORT_SYMBOL(init_nm256);
-#ifdef MODULE
-
static int loaded = 0;
MODULE_PARM (usecache, "i");
@@ -1648,8 +1647,7 @@ MODULE_PARM (buffertop, "i");
MODULE_PARM (nm256_debug, "i");
MODULE_PARM (force_load, "i");
-int
-init_module (void)
+static int __init do_init_nm256(void)
{
nmcard_list = NULL;
printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1\n");
@@ -1663,8 +1661,7 @@ init_module (void)
return -ENODEV;
}
-void
-cleanup_module (void)
+static void __exit cleanup_nm256 (void)
{
if (loaded) {
struct nm256_info *card;
@@ -1688,8 +1685,10 @@ cleanup_module (void)
}
pm_unregister_all (&handle_pm_event);
}
-#endif
-
+
+module_init(do_init_nm256);
+module_exit(cleanup_nm256);
+
/*
* Local variables:
* c-basic-offset: 4
diff --git a/drivers/sound/opl3.c b/drivers/sound/opl3.c
index acaf989ca..951dfe4d3 100644
--- a/drivers/sound/opl3.c
+++ b/drivers/sound/opl3.c
@@ -3,7 +3,7 @@
*
* A low level driver for Yamaha YM3812 and OPL-3 -chips
*
-*
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -12,14 +12,16 @@
*
*
* Changes
- * Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
- * Alan Cox modularisation, fixed sound_mem allocs.
+ * Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
+ * Alan Cox modularisation, fixed sound_mem allocs.
+ * Christoph Hellwig Adapted to module_init/module_exit
*
* Status
* Believed to work. Badly needs rewriting a bit to support multiple
* OPL3 devices.
*/
+#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
@@ -32,6 +34,7 @@
#include "soundmodule.h"
#include "opl3.h"
+#include "opl3_hw.h"
#define MAX_VOICE 18
#define OFFS_4OP 11
@@ -1171,18 +1174,19 @@ int opl3_init(int ioaddr, int *osp)
return me;
}
-#ifdef MODULE
+EXPORT_SYMBOL(opl3_init);
+EXPORT_SYMBOL(opl3_detect);
-/*
- * We provide OPL3 functions.
- */
+static int me;
+
+static int io = -1;
-int io = -1;
-int me;
+MODULE_PARM(io, "i");
-int init_module (void)
+static int __init init_opl3 (void)
{
printk(KERN_INFO "YM3812 and OPL-3 driver Copyright (C) by Hannu Savolainen, Rob Hooft 1993-1996\n");
+
if (io != -1) /* User loading pure OPL3 module */
{
if (check_region(io, 4))
@@ -1195,14 +1199,14 @@ int init_module (void)
return -ENODEV;
}
me = opl3_init(io, NULL);
- request_region(io,4,devc->fm_info.name);
+ request_region(io, 4, devc->fm_info.name);
}
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_opl3(void)
{
if (devc && io != -1)
{
@@ -1215,10 +1219,21 @@ void cleanup_module(void)
SOUND_LOCK_END;
}
-MODULE_PARM(io, "i");
+module_init(init_opl3);
+module_exit(cleanup_opl3);
-#endif /* MODULE */
+#ifndef MODULE
+static int __init setup_opl3(char *str)
+{
+ /* io */
+ int ints[2];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
-EXPORT_SYMBOL(opl3_init);
-EXPORT_SYMBOL(opl3_detect);
+ return 1;
+}
+__setup("opl3=", setup_opl3);
+#endif
diff --git a/drivers/sound/opl3.h b/drivers/sound/opl3.h
index 5529d19d8..6ef00614b 100644
--- a/drivers/sound/opl3.h
+++ b/drivers/sound/opl3.h
@@ -1,244 +1,11 @@
/*
- * opl3.h - Definitions of the OPL-3 registers
- */
-/*
- * 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.
- */
-
-/*
- * The OPL-3 mode is switched on by writing 0x01, to the offset 5
- * of the right side.
- *
- * Another special register at the right side is at offset 4. It contains
- * a bit mask defining which voices are used as 4 OP voices.
- *
- * The percussive mode is implemented in the left side only.
- *
- * With the above exceptions the both sides can be operated independently.
- *
- * A 4 OP voice can be created by setting the corresponding
- * bit at offset 4 of the right side.
+ * opl3.h
*
- * For example setting the rightmost bit (0x01) changes the
- * first voice on the right side to the 4 OP mode. The fourth
- * voice is made inaccessible.
+ * Copyright: Christoph Hellwig <chhellwig@gmx.net>
*
- * If a voice is set to the 2 OP mode, it works like 2 OP modes
- * of the original YM3812 (AdLib). In addition the voice can
- * be connected the left, right or both stereo channels. It can
- * even be left unconnected. This works with 4 OP voices also.
- *
- * The stereo connection bits are located in the FEEDBACK_CONNECTION
- * register of the voice (0xC0-0xC8). In 4 OP voices these bits are
- * in the second half of the voice.
- */
-
-/*
- * Register numbers for the global registers
- */
-
-#define TEST_REGISTER 0x01
-#define ENABLE_WAVE_SELECT 0x20
-
-#define TIMER1_REGISTER 0x02
-#define TIMER2_REGISTER 0x03
-#define TIMER_CONTROL_REGISTER 0x04 /* Left side */
-#define IRQ_RESET 0x80
-#define TIMER1_MASK 0x40
-#define TIMER2_MASK 0x20
-#define TIMER1_START 0x01
-#define TIMER2_START 0x02
-
-#define CONNECTION_SELECT_REGISTER 0x04 /* Right side */
-#define RIGHT_4OP_0 0x01
-#define RIGHT_4OP_1 0x02
-#define RIGHT_4OP_2 0x04
-#define LEFT_4OP_0 0x08
-#define LEFT_4OP_1 0x10
-#define LEFT_4OP_2 0x20
-
-#define OPL3_MODE_REGISTER 0x05 /* Right side */
-#define OPL3_ENABLE 0x01
-#define OPL4_ENABLE 0x02
-
-#define KBD_SPLIT_REGISTER 0x08 /* Left side */
-#define COMPOSITE_SINE_WAVE_MODE 0x80 /* Don't use with OPL-3? */
-#define KEYBOARD_SPLIT 0x40
-
-#define PERCOSSION_REGISTER 0xbd /* Left side only */
-#define TREMOLO_DEPTH 0x80
-#define VIBRATO_DEPTH 0x40
-#define PERCOSSION_ENABLE 0x20
-#define BASSDRUM_ON 0x10
-#define SNAREDRUM_ON 0x08
-#define TOMTOM_ON 0x04
-#define CYMBAL_ON 0x02
-#define HIHAT_ON 0x01
-
-/*
- * Offsets to the register banks for operators. To get the
- * register number just add the operator offset to the bank offset
- *
- * AM/VIB/EG/KSR/Multiple (0x20 to 0x35)
- */
-#define AM_VIB 0x20
-#define TREMOLO_ON 0x80
-#define VIBRATO_ON 0x40
-#define SUSTAIN_ON 0x20
-#define KSR 0x10 /* Key scaling rate */
-#define MULTIPLE_MASK 0x0f /* Frequency multiplier */
-
- /*
- * KSL/Total level (0x40 to 0x55)
- */
-#define KSL_LEVEL 0x40
-#define KSL_MASK 0xc0 /* Envelope scaling bits */
-#define TOTAL_LEVEL_MASK 0x3f /* Strength (volume) of OP */
-
-/*
- * Attack / Decay rate (0x60 to 0x75)
- */
-#define ATTACK_DECAY 0x60
-#define ATTACK_MASK 0xf0
-#define DECAY_MASK 0x0f
-
-/*
- * Sustain level / Release rate (0x80 to 0x95)
- */
-#define SUSTAIN_RELEASE 0x80
-#define SUSTAIN_MASK 0xf0
-#define RELEASE_MASK 0x0f
-
-/*
- * Wave select (0xE0 to 0xF5)
*/
-#define WAVE_SELECT 0xe0
-
-/*
- * Offsets to the register banks for voices. Just add to the
- * voice number to get the register number.
- *
- * F-Number low bits (0xA0 to 0xA8).
- */
-#define FNUM_LOW 0xa0
-
-/*
- * F-number high bits / Key on / Block (octave) (0xB0 to 0xB8)
- */
-#define KEYON_BLOCK 0xb0
-#define KEYON_BIT 0x20
-#define BLOCKNUM_MASK 0x1c
-#define FNUM_HIGH_MASK 0x03
-
-/*
- * Feedback / Connection (0xc0 to 0xc8)
- *
- * These registers have two new bits when the OPL-3 mode
- * is selected. These bits controls connecting the voice
- * to the stereo channels. For 4 OP voices this bit is
- * defined in the second half of the voice (add 3 to the
- * register offset).
- *
- * For 4 OP voices the connection bit is used in the
- * both halves (gives 4 ways to connect the operators).
- */
-#define FEEDBACK_CONNECTION 0xc0
-#define FEEDBACK_MASK 0x0e /* Valid just for 1st OP of a voice */
-#define CONNECTION_BIT 0x01
-/*
- * In the 4 OP mode there is four possible configurations how the
- * operators can be connected together (in 2 OP modes there is just
- * AM or FM). The 4 OP connection mode is defined by the rightmost
- * bit of the FEEDBACK_CONNECTION (0xC0-0xC8) on the both halves.
- *
- * First half Second half Mode
- *
- * +---+
- * v |
- * 0 0 >+-1-+--2--3--4-->
- *
- *
- *
- * +---+
- * | |
- * 0 1 >+-1-+--2-+
- * |->
- * >--3----4-+
- *
- * +---+
- * | |
- * 1 0 >+-1-+-----+
- * |->
- * >--2--3--4-+
- *
- * +---+
- * | |
- * 1 1 >+-1-+--+
- * |
- * >--2--3-+->
- * |
- * >--4----+
- */
-#define STEREO_BITS 0x30 /* OPL-3 only */
-#define VOICE_TO_LEFT 0x10
-#define VOICE_TO_RIGHT 0x20
-
-/*
- * Definition table for the physical voices
- */
-
-struct physical_voice_info {
- unsigned char voice_num;
- unsigned char voice_mode; /* 0=unavailable, 2=2 OP, 4=4 OP */
- unsigned short ioaddr; /* I/O port (left or right side) */
- unsigned char op[4]; /* Operator offsets */
- };
-
-/*
- * There is 18 possible 2 OP voices
- * (9 in the left and 9 in the right).
- * The first OP is the modulator and 2nd is the carrier.
- *
- * The first three voices in the both sides may be connected
- * with another voice to a 4 OP voice. For example voice 0
- * can be connected with voice 3. The operators of voice 3 are
- * used as operators 3 and 4 of the new 4 OP voice.
- * In this case the 2 OP voice number 0 is the 'first half' and
- * voice 3 is the second.
- */
-
-#define USE_LEFT 0
-#define USE_RIGHT 1
-
-static struct physical_voice_info pv_map[18] =
-{
-/* No Mode Side OP1 OP2 OP3 OP4 */
-/* --------------------------------------------------- */
- { 0, 2, USE_LEFT, {0x00, 0x03, 0x08, 0x0b}},
- { 1, 2, USE_LEFT, {0x01, 0x04, 0x09, 0x0c}},
- { 2, 2, USE_LEFT, {0x02, 0x05, 0x0a, 0x0d}},
-
- { 3, 2, USE_LEFT, {0x08, 0x0b, 0x00, 0x00}},
- { 4, 2, USE_LEFT, {0x09, 0x0c, 0x00, 0x00}},
- { 5, 2, USE_LEFT, {0x0a, 0x0d, 0x00, 0x00}},
-
- { 6, 2, USE_LEFT, {0x10, 0x13, 0x00, 0x00}}, /* Used by percussive voices */
- { 7, 2, USE_LEFT, {0x11, 0x14, 0x00, 0x00}}, /* if the percussive mode */
- { 8, 2, USE_LEFT, {0x12, 0x15, 0x00, 0x00}}, /* is selected */
-
- { 0, 2, USE_RIGHT, {0x00, 0x03, 0x08, 0x0b}},
- { 1, 2, USE_RIGHT, {0x01, 0x04, 0x09, 0x0c}},
- { 2, 2, USE_RIGHT, {0x02, 0x05, 0x0a, 0x0d}},
- { 3, 2, USE_RIGHT, {0x08, 0x0b, 0x00, 0x00}},
- { 4, 2, USE_RIGHT, {0x09, 0x0c, 0x00, 0x00}},
- { 5, 2, USE_RIGHT, {0x0a, 0x0d, 0x00, 0x00}},
+int opl3_detect (int ioaddr, int *osp);
+int opl3_init(int ioaddr, int *osp);
- { 6, 2, USE_RIGHT, {0x10, 0x13, 0x00, 0x00}},
- { 7, 2, USE_RIGHT, {0x11, 0x14, 0x00, 0x00}},
- { 8, 2, USE_RIGHT, {0x12, 0x15, 0x00, 0x00}}
-};
+void enable_opl3_mode(int left, int right, int both);
diff --git a/drivers/sound/opl3_hw.h b/drivers/sound/opl3_hw.h
new file mode 100644
index 000000000..8b11c893e
--- /dev/null
+++ b/drivers/sound/opl3_hw.h
@@ -0,0 +1,246 @@
+/*
+ * opl3_hw.h - Definitions of the OPL-3 registers
+ *
+ *
+ * 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.
+ *
+ *
+ * The OPL-3 mode is switched on by writing 0x01, to the offset 5
+ * of the right side.
+ *
+ * Another special register at the right side is at offset 4. It contains
+ * a bit mask defining which voices are used as 4 OP voices.
+ *
+ * The percussive mode is implemented in the left side only.
+ *
+ * With the above exceptions the both sides can be operated independently.
+ *
+ * A 4 OP voice can be created by setting the corresponding
+ * bit at offset 4 of the right side.
+ *
+ * For example setting the rightmost bit (0x01) changes the
+ * first voice on the right side to the 4 OP mode. The fourth
+ * voice is made inaccessible.
+ *
+ * If a voice is set to the 2 OP mode, it works like 2 OP modes
+ * of the original YM3812 (AdLib). In addition the voice can
+ * be connected the left, right or both stereo channels. It can
+ * even be left unconnected. This works with 4 OP voices also.
+ *
+ * The stereo connection bits are located in the FEEDBACK_CONNECTION
+ * register of the voice (0xC0-0xC8). In 4 OP voices these bits are
+ * in the second half of the voice.
+ */
+
+/*
+ * Register numbers for the global registers
+ */
+
+#define TEST_REGISTER 0x01
+#define ENABLE_WAVE_SELECT 0x20
+
+#define TIMER1_REGISTER 0x02
+#define TIMER2_REGISTER 0x03
+#define TIMER_CONTROL_REGISTER 0x04 /* Left side */
+#define IRQ_RESET 0x80
+#define TIMER1_MASK 0x40
+#define TIMER2_MASK 0x20
+#define TIMER1_START 0x01
+#define TIMER2_START 0x02
+
+#define CONNECTION_SELECT_REGISTER 0x04 /* Right side */
+#define RIGHT_4OP_0 0x01
+#define RIGHT_4OP_1 0x02
+#define RIGHT_4OP_2 0x04
+#define LEFT_4OP_0 0x08
+#define LEFT_4OP_1 0x10
+#define LEFT_4OP_2 0x20
+
+#define OPL3_MODE_REGISTER 0x05 /* Right side */
+#define OPL3_ENABLE 0x01
+#define OPL4_ENABLE 0x02
+
+#define KBD_SPLIT_REGISTER 0x08 /* Left side */
+#define COMPOSITE_SINE_WAVE_MODE 0x80 /* Don't use with OPL-3? */
+#define KEYBOARD_SPLIT 0x40
+
+#define PERCOSSION_REGISTER 0xbd /* Left side only */
+#define TREMOLO_DEPTH 0x80
+#define VIBRATO_DEPTH 0x40
+#define PERCOSSION_ENABLE 0x20
+#define BASSDRUM_ON 0x10
+#define SNAREDRUM_ON 0x08
+#define TOMTOM_ON 0x04
+#define CYMBAL_ON 0x02
+#define HIHAT_ON 0x01
+
+/*
+ * Offsets to the register banks for operators. To get the
+ * register number just add the operator offset to the bank offset
+ *
+ * AM/VIB/EG/KSR/Multiple (0x20 to 0x35)
+ */
+#define AM_VIB 0x20
+#define TREMOLO_ON 0x80
+#define VIBRATO_ON 0x40
+#define SUSTAIN_ON 0x20
+#define KSR 0x10 /* Key scaling rate */
+#define MULTIPLE_MASK 0x0f /* Frequency multiplier */
+
+ /*
+ * KSL/Total level (0x40 to 0x55)
+ */
+#define KSL_LEVEL 0x40
+#define KSL_MASK 0xc0 /* Envelope scaling bits */
+#define TOTAL_LEVEL_MASK 0x3f /* Strength (volume) of OP */
+
+/*
+ * Attack / Decay rate (0x60 to 0x75)
+ */
+#define ATTACK_DECAY 0x60
+#define ATTACK_MASK 0xf0
+#define DECAY_MASK 0x0f
+
+/*
+ * Sustain level / Release rate (0x80 to 0x95)
+ */
+#define SUSTAIN_RELEASE 0x80
+#define SUSTAIN_MASK 0xf0
+#define RELEASE_MASK 0x0f
+
+/*
+ * Wave select (0xE0 to 0xF5)
+ */
+#define WAVE_SELECT 0xe0
+
+/*
+ * Offsets to the register banks for voices. Just add to the
+ * voice number to get the register number.
+ *
+ * F-Number low bits (0xA0 to 0xA8).
+ */
+#define FNUM_LOW 0xa0
+
+/*
+ * F-number high bits / Key on / Block (octave) (0xB0 to 0xB8)
+ */
+#define KEYON_BLOCK 0xb0
+#define KEYON_BIT 0x20
+#define BLOCKNUM_MASK 0x1c
+#define FNUM_HIGH_MASK 0x03
+
+/*
+ * Feedback / Connection (0xc0 to 0xc8)
+ *
+ * These registers have two new bits when the OPL-3 mode
+ * is selected. These bits controls connecting the voice
+ * to the stereo channels. For 4 OP voices this bit is
+ * defined in the second half of the voice (add 3 to the
+ * register offset).
+ *
+ * For 4 OP voices the connection bit is used in the
+ * both halves (gives 4 ways to connect the operators).
+ */
+#define FEEDBACK_CONNECTION 0xc0
+#define FEEDBACK_MASK 0x0e /* Valid just for 1st OP of a voice */
+#define CONNECTION_BIT 0x01
+/*
+ * In the 4 OP mode there is four possible configurations how the
+ * operators can be connected together (in 2 OP modes there is just
+ * AM or FM). The 4 OP connection mode is defined by the rightmost
+ * bit of the FEEDBACK_CONNECTION (0xC0-0xC8) on the both halves.
+ *
+ * First half Second half Mode
+ *
+ * +---+
+ * v |
+ * 0 0 >+-1-+--2--3--4-->
+ *
+ *
+ *
+ * +---+
+ * | |
+ * 0 1 >+-1-+--2-+
+ * |->
+ * >--3----4-+
+ *
+ * +---+
+ * | |
+ * 1 0 >+-1-+-----+
+ * |->
+ * >--2--3--4-+
+ *
+ * +---+
+ * | |
+ * 1 1 >+-1-+--+
+ * |
+ * >--2--3-+->
+ * |
+ * >--4----+
+ */
+#define STEREO_BITS 0x30 /* OPL-3 only */
+#define VOICE_TO_LEFT 0x10
+#define VOICE_TO_RIGHT 0x20
+
+/*
+ * Definition table for the physical voices
+ */
+
+struct physical_voice_info {
+ unsigned char voice_num;
+ unsigned char voice_mode; /* 0=unavailable, 2=2 OP, 4=4 OP */
+ unsigned short ioaddr; /* I/O port (left or right side) */
+ unsigned char op[4]; /* Operator offsets */
+ };
+
+/*
+ * There is 18 possible 2 OP voices
+ * (9 in the left and 9 in the right).
+ * The first OP is the modulator and 2nd is the carrier.
+ *
+ * The first three voices in the both sides may be connected
+ * with another voice to a 4 OP voice. For example voice 0
+ * can be connected with voice 3. The operators of voice 3 are
+ * used as operators 3 and 4 of the new 4 OP voice.
+ * In this case the 2 OP voice number 0 is the 'first half' and
+ * voice 3 is the second.
+ */
+
+#define USE_LEFT 0
+#define USE_RIGHT 1
+
+static struct physical_voice_info pv_map[18] =
+{
+/* No Mode Side OP1 OP2 OP3 OP4 */
+/* --------------------------------------------------- */
+ { 0, 2, USE_LEFT, {0x00, 0x03, 0x08, 0x0b}},
+ { 1, 2, USE_LEFT, {0x01, 0x04, 0x09, 0x0c}},
+ { 2, 2, USE_LEFT, {0x02, 0x05, 0x0a, 0x0d}},
+
+ { 3, 2, USE_LEFT, {0x08, 0x0b, 0x00, 0x00}},
+ { 4, 2, USE_LEFT, {0x09, 0x0c, 0x00, 0x00}},
+ { 5, 2, USE_LEFT, {0x0a, 0x0d, 0x00, 0x00}},
+
+ { 6, 2, USE_LEFT, {0x10, 0x13, 0x00, 0x00}}, /* Used by percussive voices */
+ { 7, 2, USE_LEFT, {0x11, 0x14, 0x00, 0x00}}, /* if the percussive mode */
+ { 8, 2, USE_LEFT, {0x12, 0x15, 0x00, 0x00}}, /* is selected */
+
+ { 0, 2, USE_RIGHT, {0x00, 0x03, 0x08, 0x0b}},
+ { 1, 2, USE_RIGHT, {0x01, 0x04, 0x09, 0x0c}},
+ { 2, 2, USE_RIGHT, {0x02, 0x05, 0x0a, 0x0d}},
+
+ { 3, 2, USE_RIGHT, {0x08, 0x0b, 0x00, 0x00}},
+ { 4, 2, USE_RIGHT, {0x09, 0x0c, 0x00, 0x00}},
+ { 5, 2, USE_RIGHT, {0x0a, 0x0d, 0x00, 0x00}},
+
+ { 6, 2, USE_RIGHT, {0x10, 0x13, 0x00, 0x00}},
+ { 7, 2, USE_RIGHT, {0x11, 0x14, 0x00, 0x00}},
+ { 8, 2, USE_RIGHT, {0x12, 0x15, 0x00, 0x00}}
+};
+/*
+ * DMA buffer calls
+ */
diff --git a/drivers/sound/opl3sa.c b/drivers/sound/opl3sa.c
index 721157fdd..6b82d2a17 100644
--- a/drivers/sound/opl3sa.c
+++ b/drivers/sound/opl3sa.c
@@ -13,21 +13,26 @@
*
* Changes:
* Alan Cox Modularisation
+ * Christoph Hellwig Adapted to module_init/module_exit
*
* FIXME:
* Check for install of mpu etc is wrong, should check result of the mss stuff
*/
-
+
+#include <linux/init.h>
#include <linux/module.h>
#undef SB_OK
#include "sound_config.h"
#include "soundmodule.h"
+
+#include "ad1848.h"
+#include "mpu401.h"
+
#ifdef SB_OK
#include "sb.h"
static int sb_initialized = 0;
-
#endif
static int kilroy_was_here = 0; /* Don't detect twice */
@@ -62,7 +67,7 @@ static void opl3sa_write(int addr, int data)
restore_flags(flags);
}
-static int opl3sa_detect(void)
+static int __init opl3sa_detect(void)
{
int tmp;
@@ -102,7 +107,7 @@ static int opl3sa_detect(void)
* OPL3-SA
*/
-int probe_opl3sa_wss(struct address_info *hw_config)
+static int __init probe_opl3sa_wss(struct address_info *hw_config)
{
int ret;
unsigned char tmp = 0x24; /* WSS enable */
@@ -157,7 +162,7 @@ int probe_opl3sa_wss(struct address_info *hw_config)
return ret;
}
-void attach_opl3sa_wss(struct address_info *hw_config)
+static void __init attach_opl3sa_wss(struct address_info *hw_config)
{
int nm = num_mixers;
@@ -172,13 +177,13 @@ void attach_opl3sa_wss(struct address_info *hw_config)
}
-void attach_opl3sa_mpu(struct address_info *hw_config)
+static void __init attach_opl3sa_mpu(struct address_info *hw_config)
{
hw_config->name = "OPL3-SA (MPU401)";
attach_uart401(hw_config);
}
-int probe_opl3sa_mpu(struct address_info *hw_config)
+static int __init probe_opl3sa_mpu(struct address_info *hw_config)
{
unsigned char conf;
static signed char irq_bits[] = {
@@ -236,7 +241,7 @@ int probe_opl3sa_mpu(struct address_info *hw_config)
return probe_uart401(hw_config);
}
-void unload_opl3sa_wss(struct address_info *hw_config)
+static void __exit unload_opl3sa_wss(struct address_info *hw_config)
{
int dma2 = hw_config->dma2;
@@ -254,26 +259,29 @@ void unload_opl3sa_wss(struct address_info *hw_config)
sound_unload_audiodev(hw_config->slots[0]);
}
-void unload_opl3sa_mpu(struct address_info *hw_config)
+static inline void __exit unload_opl3sa_mpu(struct address_info *hw_config)
{
unload_uart401(hw_config);
}
#ifdef SB_OK
-void unload_opl3sa_sb(struct address_info *hw_config)
+static inline void __exit unload_opl3sa_sb(struct address_info *hw_config)
{
sb_dsp_unload(hw_config);
}
#endif
-#ifdef MODULE
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma2 = -1;
+static int found_mpu;
+
+static struct address_info cfg;
+static struct address_info cfg_mpu;
-int mpu_io = -1;
-int mpu_irq = -1;
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma2 = -1;
+static int __initdata mpu_io = -1;
+static int __initdata mpu_irq = -1;
MODULE_PARM(io,"i");
MODULE_PARM(irq,"i");
@@ -282,43 +290,61 @@ MODULE_PARM(dma2,"i");
MODULE_PARM(mpu_io,"i");
MODULE_PARM(mpu_irq,"i");
-struct address_info cfg;
-struct address_info mpu_cfg;
-static int found_mpu;
-
-int init_module(void)
+static int __init init_opl3sa(void)
{
- if (io == -1 || irq == -1 || dma == -1)
- {
+ if (io == -1 || irq == -1 || dma == -1) {
printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n");
return -EINVAL;
}
+
cfg.io_base = io;
cfg.irq = irq;
cfg.dma = dma;
cfg.dma2 = dma2;
- mpu_cfg.io_base = mpu_io;
- mpu_cfg.irq = mpu_irq;
+ cfg_mpu.io_base = mpu_io;
+ cfg_mpu.irq = mpu_irq;
if (probe_opl3sa_wss(&cfg) == 0)
return -ENODEV;
- found_mpu=probe_opl3sa_mpu(&mpu_cfg);
+ found_mpu=probe_opl3sa_mpu(&cfg_mpu);
attach_opl3sa_wss(&cfg);
if(found_mpu)
- attach_opl3sa_mpu(&mpu_cfg);
+ attach_opl3sa_mpu(&cfg_mpu);
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_opl3sa(void)
{
if(found_mpu)
- unload_opl3sa_mpu(&mpu_cfg);
+ unload_opl3sa_mpu(&cfg_mpu);
unload_opl3sa_wss(&cfg);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+module_init(init_opl3sa);
+module_exit(cleanup_opl3sa);
+
+#ifndef MODULE
+static int __init setup_opl3sa(char *str)
+{
+ /* io, irq, dma, dma2, mpu_io, mpu_irq */
+ int ints[7];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma2 = ints[4];
+ mpu_io = ints[5];
+ mpu_irq = ints[6];
+
+ return 1;
+}
+
+__setup("opl3sa=", setup_opl3sa);
+#endif
diff --git a/drivers/sound/opl3sa2.c b/drivers/sound/opl3sa2.c
index c3fff526f..23f85733e 100644
--- a/drivers/sound/opl3sa2.c
+++ b/drivers/sound/opl3sa2.c
@@ -32,15 +32,20 @@
* Scott Murray Simpler detection code should work all the time now
* (with thanks to Ben Hutchings for the heuristic),
* removed now unnecessary force option. (Jan 5, 1999)
+ * Christoph Hellwig Adapted to module_init/module_exit (Mar 4, 2000)
*
*/
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
#include "sound_config.h"
#include "soundmodule.h"
+#include "ad1848.h"
+#include "mpu401.h"
+
/* Useful control port indexes: */
#define OPL3SA2_MASTER_LEFT 0x07
#define OPL3SA2_MASTER_RIGHT 0x08
@@ -439,31 +444,31 @@ static struct mixer_operations opl3sa2_mixer_operations =
/* End of mixer-related stuff */
-int probe_opl3sa2_mpu(struct address_info *hw_config)
+static inline int __init probe_opl3sa2_mpu(struct address_info *hw_config)
{
return probe_mpu401(hw_config);
}
-void attach_opl3sa2_mpu(struct address_info *hw_config)
+static inline void __init attach_opl3sa2_mpu(struct address_info *hw_config)
{
attach_mpu401(hw_config);
}
-void unload_opl3sa2_mpu(struct address_info *hw_config)
+static inline void __exit unload_opl3sa2_mpu(struct address_info *hw_config)
{
unload_mpu401(hw_config);
}
-int probe_opl3sa2_mss(struct address_info *hw_config)
+static inline int __init probe_opl3sa2_mss(struct address_info *hw_config)
{
return probe_ms_sound(hw_config);
}
-void attach_opl3sa2_mss(struct address_info *hw_config)
+static void __init attach_opl3sa2_mss(struct address_info *hw_config)
{
char mixer_name[64];
@@ -506,13 +511,13 @@ void attach_opl3sa2_mss(struct address_info *hw_config)
}
-void unload_opl3sa2_mss(struct address_info *hw_config)
+static inline void __exit unload_opl3sa2_mss(struct address_info *hw_config)
{
unload_ms_sound(hw_config);
}
-int probe_opl3sa2(struct address_info *hw_config)
+static int __init probe_opl3sa2(struct address_info *hw_config)
{
unsigned char version = 0;
char tag;
@@ -582,16 +587,13 @@ int probe_opl3sa2(struct address_info *hw_config)
{
/* Generate a pretty name */
sprintf(chipset_name, "OPL3-SA%c", tag);
-#if defined(CONFIG_OPL3SA2_MPU_BASE) && !defined(MODULE)
- sound_getconf(SNDCARD_OPL3SA2_MPU)->always_detect = 1;
-#endif
return 1;
}
return 0;
}
-void attach_opl3sa2(struct address_info *hw_config)
+static void __init attach_opl3sa2(struct address_info *hw_config)
{
request_region(hw_config->io_base, 2, chipset_name);
@@ -599,7 +601,7 @@ void attach_opl3sa2(struct address_info *hw_config)
}
-void unload_opl3sa2(struct address_info *hw_config)
+static void __exit unload_opl3sa2(struct address_info *hw_config)
{
/* Release control ports */
release_region(hw_config->io_base, 2);
@@ -609,15 +611,16 @@ void unload_opl3sa2(struct address_info *hw_config)
sound_unload_mixerdev(opl3sa2_mixer);
}
+static struct address_info cfg;
+static struct address_info cfg2;
+static struct address_info cfg_mpu;
-#ifdef MODULE
-
-int io = -1;
-int mss_io = -1;
-int mpu_io = -1;
-int irq = -1;
-int dma = -1;
-int dma2 = -1;
+static int __initdata io = -1;
+static int __initdata mss_io = -1;
+static int __initdata mpu_io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma2 = -1;
MODULE_PARM(io, "i");
MODULE_PARM_DESC(io, "Set i/o base of OPL3-SA2 or SA3 card (usually 0x370)");
@@ -640,30 +643,15 @@ MODULE_PARM_DESC(dma2, "Set MSS (audio) second DMA channel (0, 1, 3)");
MODULE_DESCRIPTION("Module for OPL3-SA2 and SA3 sound cards (uses AD1848 MSS driver).");
MODULE_AUTHOR("Scott Murray <scottm@interlog.com>");
-EXPORT_NO_SYMBOLS;
-
-struct address_info cfg;
-struct address_info mss_cfg;
-struct address_info mpu_cfg;
-
-
/*
* Install a OPL3SA2 based card.
*
* Need to have ad1848 and mpu401 loaded ready.
*/
-int init_module(void)
+static int __init init_opl3sa2(void)
{
int i;
- if(io == -1 || irq == -1 || dma == -1 || dma2 == -1 || mss_io == -1)
- {
- printk(KERN_ERR
- "%s: io, mss_io, irq, dma, and dma2 must be set.\n",
- __FILE__);
- return -EINVAL;
- }
-
/* Our own config: */
cfg.io_base = io;
cfg.irq = irq;
@@ -671,16 +659,26 @@ int init_module(void)
cfg.dma2 = dma2;
/* The MSS config: */
- mss_cfg.io_base = mss_io;
- mss_cfg.irq = irq;
- mss_cfg.dma = dma;
- mss_cfg.dma2 = dma2;
- mss_cfg.card_subtype = 1; /* No IRQ or DMA setup */
+ cfg2.io_base = mss_io;
+ cfg2.irq = irq;
+ cfg2.dma = dma;
+ cfg2.dma2 = dma2;
+ cfg2.card_subtype = 1; /* No IRQ or DMA setup */
+
+ cfg_mpu.io_base = mpu_io;
+ cfg_mpu.irq = irq;
+ cfg_mpu.dma = dma;
+ cfg_mpu.always_detect = 1; /* It's there, so use shared IRQs */
+
+ if(cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.dma2 == -1 || cfg2.io_base == -1) {
+ printk(KERN_ERR "opl3sa2: io, mss_io, irq, dma, and dma2 must be set.\n");
+ return -EINVAL;
+ }
/* Call me paranoid: */
for(i = 0; i < 6; i++)
{
- cfg.slots[i] = mss_cfg.slots[i] = mpu_cfg.slots[i] = -1;
+ cfg.slots[i] = cfg2.slots[i] = cfg_mpu.slots[i] = -1;
}
if(probe_opl3sa2(&cfg) == 0)
@@ -688,41 +686,54 @@ int init_module(void)
return -ENODEV;
}
- if(probe_opl3sa2_mss(&mss_cfg) == 0)
+ if(probe_opl3sa2_mss(&cfg2) == 0)
{
return -ENODEV;
}
attach_opl3sa2(&cfg);
- attach_opl3sa2_mss(&mss_cfg);
+ attach_opl3sa2_mss(&cfg2);
- if(mpu_io != -1)
- {
- /* MPU config: */
- mpu_cfg.io_base = mpu_io;
- mpu_cfg.irq = irq;
- mpu_cfg.dma = dma;
- mpu_cfg.always_detect = 1; /* It's there, so use shared IRQs */
-
- if(probe_opl3sa2_mpu(&mpu_cfg))
- {
- attach_opl3sa2_mpu(&mpu_cfg);
- }
+ if(cfg_mpu.io_base != -1) {
+ if(probe_opl3sa2_mpu(&cfg_mpu)) {
+ attach_opl3sa2_mpu(&cfg_mpu);
+ }
}
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_opl3sa2(void)
{
- if(mpu_cfg.slots[1] != -1)
- {
- unload_opl3sa2_mpu(&mpu_cfg);
+ if(cfg_mpu.slots[1] != -1) {
+ unload_opl3sa2_mpu(&cfg_mpu);
}
- unload_opl3sa2_mss(&mss_cfg);
+ unload_opl3sa2_mss(&cfg2);
unload_opl3sa2(&cfg);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+module_init(init_opl3sa2);
+module_exit(cleanup_opl3sa2);
+
+#ifndef MODULE
+static int __init setup_opl3sa2(char *str)
+{
+ /* io, irq, dma, dma2 */
+ int ints[7];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma2 = ints[4];
+ mss_io = ints[5];
+ mpu_io = ints[6];
+
+ return 1;
+}
+
+__setup("opl3sa2=", setup_opl3sa2);
+#endif
diff --git a/drivers/sound/pas2.h b/drivers/sound/pas2.h
new file mode 100644
index 000000000..7ac521fe0
--- /dev/null
+++ b/drivers/sound/pas2.h
@@ -0,0 +1,23 @@
+/*
+ * pas2.h
+ *
+ * Copyright: Christoph Hellwig <chhellwig@gmx.net>
+ *
+ */
+
+/* From pas_card.c */
+int pas_set_intr(int mask);
+int pas_remove_intr(int mask);
+unsigned char pas_read(int ioaddr);
+void pas_write(unsigned char data, int ioaddr);
+
+/* From pas_audio.c */
+void pas_pcm_interrupt(unsigned char status, int cause);
+void pas_pcm_init(struct address_info *hw_config);
+
+/* From pas_mixer.c */
+int pas_init_mixer(void);
+
+/* From pas_midi.c */
+void pas_midi_init(void);
+void pas_midi_interrupt(void);
diff --git a/drivers/sound/pas2_card.c b/drivers/sound/pas2_card.c
index 762871063..68936e577 100644
--- a/drivers/sound/pas2_card.c
+++ b/drivers/sound/pas2_card.c
@@ -5,10 +5,14 @@
*/
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
#include "sound_config.h"
#include "soundmodule.h"
+#include "pas2.h"
+#include "sb.h"
+
static unsigned char dma_bits[] = {
4, 1, 2, 3, 0, 5, 6, 7
};
@@ -51,6 +55,8 @@ static int broken_bus_clock = 1;
static int broken_bus_clock = 0;
#endif
+static struct address_info cfg;
+static struct address_info cfg2;
char pas_model = 0;
static char *pas_model_names[] = {
@@ -81,7 +87,7 @@ void pas_write(unsigned char data, int ioaddr)
/******************* Begin of the Interrupt Handler ********************/
-static void pasintr(int irq, void *dev_id, struct pt_regs *dummy)
+void pasintr(int irq, void *dev_id, struct pt_regs *dummy)
{
int status;
@@ -126,9 +132,7 @@ int pas_remove_intr(int mask)
/******************* Begin of the Initialization Code ******************/
-extern struct address_info sbhw_config;
-
-static int config_pas_hw(struct address_info *hw_config)
+static int __init config_pas_hw(struct address_info *hw_config)
{
char ok = 1;
unsigned int_ptrs; /* scsi/sound interrupt pointers */
@@ -238,12 +242,8 @@ static int config_pas_hw(struct address_info *hw_config)
{
struct address_info *sb_config;
-#ifndef MODULE
- if ((sb_config = sound_getconf(SNDCARD_SB)))
-#else
- sb_config = &sbhw_config;
+ sb_config = &cfg2;
if (sb_config->io_base)
-#endif
{
unsigned char irq_dma;
@@ -286,7 +286,7 @@ static int config_pas_hw(struct address_info *hw_config)
return ok;
}
-static int detect_pas_hw(struct address_info *hw_config)
+static int __init detect_pas_hw(struct address_info *hw_config)
{
unsigned char board_id, foo;
@@ -327,7 +327,7 @@ static int detect_pas_hw(struct address_info *hw_config)
return pas_model;
}
-void attach_pas_card(struct address_info *hw_config)
+static void __init attach_pas_card(struct address_info *hw_config)
{
pas_irq = hw_config->irq;
@@ -348,7 +348,6 @@ void attach_pas_card(struct address_info *hw_config)
pas_pcm_init(hw_config);
#if !defined(MODULE) && !defined(DISABLE_SB_EMULATION)
-
sb_dsp_disable_midi(pas_sb_base); /* No MIDI capability */
#endif
@@ -358,12 +357,12 @@ void attach_pas_card(struct address_info *hw_config)
}
}
-int probe_pas(struct address_info *hw_config)
+static inline int __init probe_pas(struct address_info *hw_config)
{
return detect_pas_hw(hw_config);
}
-void unload_pas(struct address_info *hw_config)
+static void __exit unload_pas(struct address_info *hw_config)
{
extern int pas_audiodev;
extern int pas2_mididev;
@@ -381,17 +380,15 @@ void unload_pas(struct address_info *hw_config)
sound_unload_audiodev(pas_audiodev);
}
-#ifdef MODULE
-
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma16 = -1; /* Set this for modules that need it */
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma16 = -1; /* Set this for modules that need it */
-int sb_io = 0;
-int sb_irq = -1;
-int sb_dma = -1;
-int sb_dma16 = -1;
+static int __initdata sb_io = 0;
+static int __initdata sb_irq = -1;
+static int __initdata sb_dma = -1;
+static int __initdata sb_dma16 = -1;
MODULE_PARM(io,"i");
MODULE_PARM(irq,"i");
@@ -407,40 +404,61 @@ MODULE_PARM(joystick,"i");
MODULE_PARM(symphony,"i");
MODULE_PARM(broken_bus_clock,"i");
-struct address_info config;
-struct address_info sbhw_config;
-
-int init_module(void)
+static int __init init_pas2(void)
{
printk(KERN_INFO "Pro Audio Spectrum driver Copyright (C) by Hannu Savolainen 1993-1996\n");
- if (io == -1 || dma == -1 || irq == -1)
- {
- printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
- return -EINVAL;
- }
- config.io_base = io;
- config.irq = irq;
- config.dma = dma;
- config.dma2 = dma16;
+ cfg.io_base = io;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.dma2 = dma16;
+
+ cfg2.io_base = sb_io;
+ cfg2.irq = sb_irq;
+ cfg2.dma = sb_dma;
+ cfg2.dma2 = sb_dma16;
- sbhw_config.io_base = sb_io;
- sbhw_config.irq = sb_irq;
- sbhw_config.dma = sb_dma;
- sbhw_config.dma2 = sb_dma16;
+ if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
+ printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
+ return -EINVAL;
+ }
- if (!probe_pas(&config))
+ if (!probe_pas(&cfg))
return -ENODEV;
- attach_pas_card(&config);
+ attach_pas_card(&cfg);
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_pas2(void)
{
- unload_pas(&config);
+ unload_pas(&cfg);
SOUND_LOCK_END;
}
+module_init(init_pas2);
+module_exit(cleanup_pas2);
+
+#ifndef MODULE
+static int __init setup_pas2(char *str)
+{
+ /* io, irq, dma, dma2, sb_io, sb_irq, sb_dma, sb_dma2 */
+ int ints[9];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma16 = ints[4];
+
+ sb_io = ints[5];
+ sb_irq = ints[6];
+ sb_dma = ints[7];
+ sb_dma16 = ints[8];
+
+ return 1;
+}
-#endif /* MODULE */
+__setup("pas2=", setup_pas2);
+#endif
diff --git a/drivers/sound/pas2_midi.c b/drivers/sound/pas2_midi.c
index 83d6ff5bd..385bdd1db 100644
--- a/drivers/sound/pas2_midi.c
+++ b/drivers/sound/pas2_midi.c
@@ -10,8 +10,11 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+
#include "sound_config.h"
+#include "pas2.h"
+
static int midi_busy = 0, input_opened = 0;
static int my_dev;
diff --git a/drivers/sound/pas2_mixer.c b/drivers/sound/pas2_mixer.c
index 1f2f12336..86e9a50ca 100644
--- a/drivers/sound/pas2_mixer.c
+++ b/drivers/sound/pas2_mixer.c
@@ -17,6 +17,8 @@
*/
#include "sound_config.h"
+#include "pas2.h"
+
#ifndef DEB
#define DEB(what) /* (what) */
#endif
diff --git a/drivers/sound/pas2_pcm.c b/drivers/sound/pas2_pcm.c
index 36fc7f72b..5a79ebb86 100644
--- a/drivers/sound/pas2_pcm.c
+++ b/drivers/sound/pas2_pcm.c
@@ -16,6 +16,8 @@
#include "sound_config.h"
+#include "pas2.h"
+
#ifndef DEB
#define DEB(WHAT)
#endif
diff --git a/drivers/sound/pss.c b/drivers/sound/pss.c
index ffbb08b77..7e883a625 100644
--- a/drivers/sound/pss.c
+++ b/drivers/sound/pss.c
@@ -24,16 +24,22 @@
* To probe_pss_mss added test for initialize AD1848
* 98-05-28: Vladimir Michl <vladimir.michl@upol.cz>
* Fixed computation of mixer volumes
+ * 00-03-03: Christoph Hellwig <chhellwig@gmx.net>
+ * Adapted to module_init/module_exit
*/
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
#include "sound_config.h"
#include "sound_firmware.h"
#include "soundmodule.h"
+#include "ad1848.h"
+#include "mpu401.h"
+
/*
* PSS registers.
*/
@@ -910,14 +916,14 @@ static coproc_operations pss_coproc_operations =
&pss_data
};
-void attach_pss_mpu(struct address_info *hw_config)
+static void __init attach_pss_mpu(struct address_info *hw_config)
{
attach_mpu401(hw_config); /* Slot 1 */
if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
}
-int probe_pss_mss(struct address_info *hw_config)
+static int __init probe_pss_mss(struct address_info *hw_config)
{
volatile int timeout;
@@ -950,16 +956,20 @@ int probe_pss_mss(struct address_info *hw_config)
* downloaded to the ADSP2115 spends some time initializing the card.
* Let's try to wait until it finishes this task.
*/
- for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) & WSS_INITIALIZING); timeout++);
+ for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) &
+ WSS_INITIALIZING); timeout++)
+ ;
outb((0x0b), hw_config->io_base + WSS_INDEX); /* Required by some cards */
- for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) && (timeout < 100000); timeout++);
+ for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) &&
+ (timeout < 100000); timeout++)
+ ;
return probe_ms_sound(hw_config);
}
-void attach_pss_mss(struct address_info *hw_config)
+static void __init attach_pss_mss(struct address_info *hw_config)
{
int my_mix = -999; /* gcc shut up */
@@ -991,36 +1001,33 @@ void attach_pss_mss(struct address_info *hw_config)
}
}
-void unload_pss(struct address_info *hw_config)
+static inline void __exit unload_pss(struct address_info *hw_config)
{
release_region(hw_config->io_base, 0x10);
release_region(hw_config->io_base+0x10, 0x9);
}
-void unload_pss_mpu(struct address_info *hw_config)
+static inline void __exit unload_pss_mpu(struct address_info *hw_config)
{
unload_mpu401(hw_config);
}
-void unload_pss_mss(struct address_info *hw_config)
+static inline void __exit unload_pss_mss(struct address_info *hw_config)
{
unload_ms_sound(hw_config);
}
-#ifdef MODULE
-
-int pss_io = -1;
-
-int mss_io = -1;
-int mss_irq = -1;
-int mss_dma = -1;
-int mpu_io = -1;
-int mpu_irq = -1;
+static struct address_info cfg;
+static struct address_info cfg2;
+static struct address_info cfg_mpu;
-struct address_info cfgpss = { 0 /* pss_io */, 0, -1, -1 };
-struct address_info cfgmpu = { 0 /* mpu_io */, 0 /* mpu_irq */, 0, -1 };
-struct address_info cfgmss = { 0 /* mss_io */, 0 /* mss_irq */, 0 /* mss_dma */, -1 };
+static int pss_io __initdata = -1;
+static int mss_io __initdata = -1;
+static int mss_irq __initdata = -1;
+static int mss_dma __initdata = -1;
+static int mpu_io __initdata = -1;
+static int mpu_irq __initdata = -1;
MODULE_PARM(pss_io, "i");
MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
@@ -1046,54 +1053,76 @@ static int pssmpu = 0, pssmss = 0;
* Load a PSS sound card module
*/
-int init_module(void)
+static int __init init_pss(void)
{
- if (pss_io == -1 || mss_io == -1 || mss_irq == -1 || mss_dma == -1) {
- printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
- return -EINVAL;
- }
+ cfg.io_base = pss_io;
- cfgpss.io_base = pss_io;
+ cfg2.io_base = mss_io;
+ cfg2.irq = mss_irq;
+ cfg2.dma = mss_dma;
- cfgmss.io_base = mss_io;
- cfgmss.irq = mss_irq;
- cfgmss.dma = mss_dma;
+ cfg_mpu.io_base = mpu_io;
+ cfg_mpu.irq = mpu_irq;
- cfgmpu.io_base = mpu_io;
- cfgmpu.irq = mpu_irq;
+ if (cfg.io_base == -1 || cfg2.io_base == -1 || cfg2.irq == -1 || cfg.dma == -1) {
+ printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
+ return -EINVAL;
+ }
- if (!pss_synth)
- {
+ if (!pss_synth) {
fw_load = 1;
pss_synthLen = mod_firmware_load("/etc/sound/pss_synth", (void *) &pss_synth);
}
- if (!probe_pss(&cfgpss))
+ if (!probe_pss(&cfg))
return -ENODEV;
- attach_pss(&cfgpss);
+ attach_pss(&cfg);
/*
* Attach stuff
*/
- if (probe_pss_mpu(&cfgmpu)) {
+ if (probe_pss_mpu(&cfg_mpu)) {
pssmpu = 1;
- attach_pss_mpu(&cfgmpu);
+ attach_pss_mpu(&cfg_mpu);
}
- if (probe_pss_mss(&cfgmss)) {
+ if (probe_pss_mss(&cfg2)) {
pssmss = 1;
- attach_pss_mss(&cfgmss);
+ attach_pss_mss(&cfg2);
}
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_pss(void)
{
if (fw_load && pss_synth)
vfree(pss_synth);
if (pssmss)
- unload_pss_mss(&cfgmss);
+ unload_pss_mss(&cfg2);
if (pssmpu)
- unload_pss_mpu(&cfgmpu);
- unload_pss(&cfgpss);
+ unload_pss_mpu(&cfg_mpu);
+ unload_pss(&cfg);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+
+module_init(init_pss);
+module_exit(cleanup_pss);
+
+#ifndef MODULE
+static int __init setup_pss(char *str)
+{
+ /* io, mss_io, mss_irq, mss_dma, mpu_io, mpu_irq */
+ int ints[7];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ pss_io = ints[1];
+ mss_io = ints[2];
+ mss_irq = ints[3];
+ mss_dma = ints[4];
+ mpu_io = ints[5];
+ mpu_irq = ints[6];
+
+ return 1;
+}
+
+__setup("pss=", setup_pss);
+#endif
diff --git a/drivers/sound/sb.h b/drivers/sound/sb.h
index b2eef8254..282e644a3 100644
--- a/drivers/sound/sb.h
+++ b/drivers/sound/sb.h
@@ -164,3 +164,13 @@ void sb_audio_close(int dev);
extern int acer;
extern sb_devc *last_sb;
+
+/* From sb_common.c */
+void sb_dsp_disable_midi(int port);
+void sb_dsp_disable_recording(int port);
+void attach_sbmpu (struct address_info *hw_config);
+int probe_sbmpu (struct address_info *hw_config);
+void unload_sbmpu (struct address_info *hw_config);
+
+void unload_sb16(struct address_info *hw_info);
+void unload_sb16midi(struct address_info *hw_info);
diff --git a/drivers/sound/sb_card.c b/drivers/sound/sb_card.c
index 49a55288f..7e3ecb1a1 100644
--- a/drivers/sound/sb_card.c
+++ b/drivers/sound/sb_card.c
@@ -11,19 +11,22 @@
* for more info.
*
*
- * 26th November 1999 - patched to compile without ISA PnP support in the
- * kernel. -Daniel Stone (tamriel@ductape.net)
+ * 26-11-1999 Patched to compile without ISA PnP support in the
+ * kernel - Daniel Stone (tamriel@ductape.net)
*
* 06-01-2000 Refined and bugfixed ISA PnP support, added
* CMI 8330 support - Alessandro Zummo <azummo@ita.flashnet.it>
*
+ * 18-01-2000 Separated sb_card and sb_common
+ * Jeff Garzik <jgarzik@mandrakesoft.com>
+ *
* 04-02-2000 Added Soundblaster AWE 64 PnP support, isapnpjump
* Alessandro Zummo <azummo@ita.flashnet.it>
*
* 11-02-2000 Added Soundblaster AWE 32 PnP support, refined PnP code
* Alessandro Zummo <azummo@ita.flashnet.it>
*
- * 13-02-2000 Hopefully fixed awe/sb16 related bugs, code cleanup.
+ * 13-02-2000 Hopefully fixed awe/sb16 related bugs, code cleanup
* Alessandro Zummo <azummo@ita.flashnet.it>
*
*/
@@ -42,14 +45,23 @@
static int sbmpu = 0;
-void attach_sb_card(struct address_info *hw_config)
+extern void *smw_free;
+
+static void __init attach_sb_card(struct address_info *hw_config)
{
if(!sb_dsp_init(hw_config))
hw_config->slots[0] = -1;
+ SOUND_LOCK;
}
-int probe_sb(struct address_info *hw_config)
+static int __init probe_sb(struct address_info *hw_config)
{
+ if (hw_config->io_base == -1 || hw_config->dma == -1 || hw_config->irq == -1)
+ {
+ printk(KERN_ERR "sb_card: I/O, IRQ, and DMA are mandatory\n");
+ return -EINVAL;
+ }
+
#ifdef CONFIG_MCA
/* MCA code added by ZP Gu (zpg@castle.net) */
if (MCA_bus) { /* no multiple REPLY card probing */
@@ -121,19 +133,16 @@ iobase=0x%x irq=%d lo_dma=%d hi_dma=%d\n",
return sb_dsp_detect(hw_config, 0, 0);
}
-void unload_sb(struct address_info *hw_config)
+static void __exit unload_sb(struct address_info *hw_config)
{
if(hw_config->slots[0]!=-1)
sb_dsp_unload(hw_config, sbmpu);
}
-int sb_be_quiet=0;
extern int esstype; /* ESS chip type */
-#ifdef MODULE
-
-static struct address_info config;
-static struct address_info config_mpu;
+static struct address_info cfg;
+static struct address_info cfg_mpu;
struct pci_dev *sb_dev = NULL,
*wss_dev = NULL,
@@ -146,25 +155,21 @@ struct pci_dev *sb_dev = NULL,
* to the 8bit channel.
*/
-int mpu_io = 0;
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma16 = -1; /* Set this for modules that need it */
-int type = 0; /* Can set this to a specific card type */
-int mad16 = 0; /* Set mad16=1 to load this as support for mad16 */
-int trix = 0; /* Set trix=1 to load this as support for trix */
-int pas2 = 0; /* Set pas2=1 to load this as support for pas2 */
-int support = 0; /* Set support to load this as a support module */
-int sm_games = 0; /* Mixer - see sb_mixer.c */
-int acer = 0; /* Do acer notebook init */
+static int __initdata mpu_io = 0;
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma16 = -1; /* Set this for modules that need it */
+static int __initdata type = 0; /* Can set this to a specific card type */
+
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
-int isapnp = 1;
-int isapnpjump = 0;
-int nosbwave = 0; /* This option will be removed when the new awe_wave driver will be in the kernel tree */
+static int isapnp = 1;
+static int isapnpjump = 0;
+static int nosbwave = 0; /* This option will be removed when the new awe_wave driver will be
+ in the kernel tree */
#else
-int isapnp = 0;
+int isapnp = 0;
#endif
MODULE_DESCRIPTION("Soundblaster driver");
@@ -175,10 +180,6 @@ MODULE_PARM(dma, "i");
MODULE_PARM(dma16, "i");
MODULE_PARM(mpu_io, "i");
MODULE_PARM(type, "i");
-MODULE_PARM(mad16, "i");
-MODULE_PARM(support, "i");
-MODULE_PARM(trix, "i");
-MODULE_PARM(pas2, "i");
MODULE_PARM(sm_games, "i");
MODULE_PARM(esstype, "i");
MODULE_PARM(acer, "i");
@@ -198,16 +199,10 @@ MODULE_PARM_DESC(dma, "8-bit DMA channel (0,1,3)");
MODULE_PARM_DESC(dma16, "16-bit DMA channel (5,6,7)");
MODULE_PARM_DESC(mpu_io, "Mpu base address");
MODULE_PARM_DESC(type, "You can set this to specific card type");
-MODULE_PARM_DESC(mad16, "Enable MAD16 support");
-MODULE_PARM_DESC(trix, "Enable Audiotrix support");
-MODULE_PARM_DESC(pas2, "Enable Pas2 support");
-MODULE_PARM_DESC(support, "Set this to load as generic support module");
MODULE_PARM_DESC(sm_games, "Enable support for Logitech soundman games");
MODULE_PARM_DESC(esstype, "ESS chip type");
MODULE_PARM_DESC(acer, "Set this to detect cards in some ACER notebooks");
-void *smw_free = NULL;
-
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
/* That's useful. */
@@ -394,6 +389,97 @@ static struct pci_dev *sb_init_cmi(struct pci_bus *bus, struct pci_dev *card, st
return(sb_dev);
}
+static struct pci_dev *sb_init_diamond(struct pci_bus *bus, struct pci_dev *card, struct address_info *hw_config, struct address_info *mpu_config)
+{
+ /*
+ * Diamonds DT0197H
+ * very similar to the CMI8330 above
+ */
+
+ /* @@@0001:Soundblaster.
+ */
+
+ if((sb_dev = isapnp_find_dev(bus,
+ ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), NULL)))
+ {
+ sb_dev->prepare(sb_dev);
+
+ if((sb_dev = activate_dev("DT0197H", "sb", sb_dev)))
+ {
+ hw_config->io_base = sb_dev->resource[0].start;
+ hw_config->irq = sb_dev->irq_resource[0].start;
+ hw_config->dma = sb_dev->dma_resource[0].start;
+ hw_config->dma2 = -1;
+
+ show_base("DT0197H", "sb", &sb_dev->resource[0]);
+ }
+
+ if(!sb_dev) return(NULL);
+
+ }
+ else
+ printk(KERN_ERR "sb: DT0197H panic: sb base not found\n");
+
+ /* @X@0001:mpu
+ */
+
+#ifdef CONFIG_MIDI
+ if((mpu_dev = isapnp_find_dev(bus,
+ ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), NULL)))
+ {
+ mpu_dev->prepare(mpu_dev);
+
+ if((mpu_dev = activate_dev("DT0197H", "mpu", mpu_dev)))
+ {
+ show_base("DT0197H", "mpu", &mpu_dev->resource[0]);
+ mpu_config->io_base = mpu_dev->resource[0].start;
+ }
+ }
+ else
+ printk(KERN_ERR "sb: DT0197H panic: mpu not found\n");
+#endif
+
+
+ /* @P@:Gameport
+ */
+
+ if((jp_dev = isapnp_find_dev(bus,
+ ISAPNP_VENDOR('@','P','@'), ISAPNP_FUNCTION(0x0001), NULL)))
+ {
+ jp_dev->prepare(jp_dev);
+
+ if((jp_dev = activate_dev("DT0197H", "gameport", jp_dev)))
+ show_base("DT0197H", "gameport", &jp_dev->resource[0]);
+ }
+ else
+ printk(KERN_ERR "sb: DT0197H panic: gameport not found\n");
+
+ /* @H@0001:OPL3
+ */
+
+#if defined(CONFIG_SOUND_YM3812) || defined(CONFIG_SOUND_YM3812_MODULE)
+ if((wss_dev = isapnp_find_dev(bus,
+ ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), NULL)))
+ {
+ wss_dev->prepare(wss_dev);
+
+ /* Let's disable IRQ and DMA for WSS device */
+
+ wss_dev->irq_resource[0].flags = 0;
+ wss_dev->dma_resource[0].flags = 0;
+
+ if((wss_dev = activate_dev("DT0197H", "opl3", wss_dev)))
+ show_base("DT0197H", "opl3", &wss_dev->resource[0]);
+ }
+ else
+ printk(KERN_ERR "sb: DT0197H panic: opl3 not found\n");
+#endif
+
+ printk(KERN_INFO "sb: DT0197H mail reports to Torsten Werner <twerner@intercomm.de>\n");
+
+ return(sb_dev);
+}
+
/* Specific support for awe will be dropped when:
* a) The new awe_wawe driver with PnP support will be introduced in the kernel
* b) The joystick driver will support PnP - a little patch is available from me....hint, hint :-)
@@ -491,12 +577,14 @@ isapnp_sb_list[] __initdata = {
{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x009D), 0, &sb_init_awe, "Sound Blaster AWE 64" },
{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x00C5), 0, &sb_init_awe, "Sound Blaster AWE 64" },
{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x00E4), 0, &sb_init_awe, "Sound Blaster AWE 64" },
+ {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968), SBF_DEV, &sb_init_ess, "ESS 1688" },
{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868), SBF_DEV, &sb_init_ess, "ESS 1868" },
{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611), SBF_DEV, &sb_init_ess, "ESS 1868" },
{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), SBF_DEV, &sb_init_ess, "ESS 1869" },
{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878), SBF_DEV, &sb_init_ess, "ESS 1878" },
{ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879), SBF_DEV, &sb_init_ess, "ESS 1879" },
{ISAPNP_VENDOR('C','M','I'), ISAPNP_FUNCTION(0x0001), 0, &sb_init_cmi, "CMI 8330 SoundPRO" },
+ {ISAPNP_VENDOR('R','W','B'), ISAPNP_FUNCTION(0x1688), 0, &sb_init_diamond, "Diamond DT0197H" },
{0}
};
@@ -538,7 +626,7 @@ static int __init sb_init_isapnp(struct address_info *hw_config, struct address_
Should this be fixed? - azummo
*/
-static int __init sb_probe_isapnp(struct address_info *hw_config, struct address_info *mpu_config)
+int __init sb_probe_isapnp(struct address_info *hw_config, struct address_info *mpu_config)
{
int i;
@@ -594,65 +682,55 @@ static int __init sb_probe_isapnp(struct address_info *hw_config, struct address
}
#endif
-int init_module(void)
+static int __init init_sb(void)
{
printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
- if (mad16 == 0 && trix == 0 && pas2 == 0 && support == 0)
- {
- /* Please remember that even with CONFIG_ISAPNP defined one should still be
- able to disable PNP support for this single driver!
- */
+ /* Please remember that even with CONFIG_ISAPNP defined one should still be
+ able to disable PNP support for this single driver!
+ */
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
- if(isapnp && (sb_probe_isapnp(&config, &config_mpu) < 0) )
- {
- printk(KERN_NOTICE "sb_card: No ISAPnP cards found, trying standard ones...\n");
- isapnp = 0;
- }
+ if(isapnp && (sb_probe_isapnp(&cfg, &cfg_mpu) < 0) ) {
+ printk(KERN_NOTICE "sb_card: No ISAPnP cards found, trying standard ones...\n");
+ isapnp = 0;
+ }
#endif
- if(isapnp == 0)
- {
- if (io == -1 || dma == -1 || irq == -1)
- {
- printk(KERN_ERR "sb_card: I/O, IRQ, and DMA are mandatory\n");
- return -EINVAL;
- }
- config.io_base = io;
- config.irq = irq;
- config.dma = dma;
- config.dma2 = dma16;
- }
+ if( isapnp == 0 ) {
+ cfg.io_base = io;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.dma2 = dma16;
+ }
- config.card_subtype = type;
+ cfg.card_subtype = type;
- if (!probe_sb(&config))
- return -ENODEV;
- attach_sb_card(&config);
-
- if(config.slots[0]==-1)
- return -ENODEV;
-
- if (isapnp == 0)
- config_mpu.io_base = mpu_io;
- if (probe_sbmpu(&config_mpu))
- sbmpu = 1;
- if (sbmpu)
- attach_sbmpu(&config_mpu);
- }
- SOUND_LOCK;
+ if (!probe_sb(&cfg))
+ return -ENODEV;
+ attach_sb_card(&cfg);
+
+ if(cfg.slots[0]==-1)
+ return -ENODEV;
+
+ if (isapnp == 0)
+ cfg_mpu.io_base = mpu_io;
+ if (probe_sbmpu(&cfg_mpu))
+ sbmpu = 1;
+ if (sbmpu)
+ attach_sbmpu(&cfg_mpu);
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_sb(void)
{
- if (smw_free)
+ if (smw_free) {
vfree(smw_free);
- if (!mad16 && !trix && !pas2 && !support)
- unload_sb(&config);
+ smw_free = NULL;
+ }
+ unload_sb(&cfg);
if (sbmpu)
- unload_sbmpu(&config_mpu);
+ unload_sbmpu(&cfg_mpu);
SOUND_LOCK_END;
if(sb_dev) sb_dev->deactivate(sb_dev);
@@ -662,28 +740,23 @@ void cleanup_module(void)
if(wss_dev) wss_dev->deactivate(wss_dev);
}
-#else
+module_init(init_sb);
+module_exit(cleanup_sb);
-#ifdef CONFIG_SM_GAMES
-int sm_games = 1;
-#else
-int sm_games = 0;
-#endif
-#ifdef CONFIG_SB_ACER
-int acer = 1;
-#else
-int acer = 0;
-#endif
-#endif
+#ifndef MODULE
+static int __init setup_sb(char *str)
+{
+ /* io, irq, dma, dma2 */
+ int ints[5];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma16 = ints[4];
-EXPORT_SYMBOL(sb_dsp_init);
-EXPORT_SYMBOL(sb_dsp_detect);
-EXPORT_SYMBOL(sb_dsp_unload);
-EXPORT_SYMBOL(sb_dsp_disable_midi);
-EXPORT_SYMBOL(attach_sb_card);
-EXPORT_SYMBOL(probe_sb);
-EXPORT_SYMBOL(unload_sb);
-EXPORT_SYMBOL(sb_be_quiet);
-EXPORT_SYMBOL(attach_sbmpu);
-EXPORT_SYMBOL(probe_sbmpu);
-EXPORT_SYMBOL(unload_sbmpu);
+ return 1;
+}
+__setup("sb=", setup_sb);
+#endif
diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c
index bda10bfad..ffb1204ad 100644
--- a/drivers/sound/sb_common.c
+++ b/drivers/sound/sb_common.c
@@ -9,25 +9,42 @@
* 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.
- */
-/*
+ *
+ *
* Daniel J. Rodriksson: Modified sbintr to handle 8 and 16 bit interrupts
* for full duplex support ( only sb16 by now )
* Rolf Fokkens: Added (BETA?) support for ES1887 chips.
* (fokkensr@vertis.nl) Which means: You can adjust the recording levels.
+ *
+ * 2000/01/18 - separated sb_card and sb_common -
+ * Jeff Garzik <jgarzik@mandrakesoft.com>
+ *
*/
+
+/* FIXME: *grr* why can't the f**in Makefile do this for me ? */
+#define EXPORT_SYMTAB
+
#include <linux/config.h>
-#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
#include "sound_config.h"
#include "sound_firmware.h"
+#include "soundmodule.h"
+
+#include "mpu401.h"
#include "sb_mixer.h"
#include "sb.h"
-
#include "sb_ess.h"
+/*
+ * global module flag
+ */
+
+int sb_be_quiet = 0;
+
static sb_devc *detected_devc = NULL; /* For communication from probe to init */
static sb_devc *last_devc = NULL; /* For MPU401 initialization */
@@ -39,6 +56,16 @@ static unsigned char jazz_dma_bits[] = {
0, 1, 0, 2, 0, 3, 0, 4
};
+/* Do acer notebook init? */
+int acer = 0;
+
+/* soundman games? */
+int sm_games = 0;
+
+extern int esstype;
+
+void *smw_free = NULL;
+
/*
* Jazz16 chipset specific control variables
*/
@@ -1033,8 +1060,6 @@ static int smw_midi_init(sb_devc * devc, struct address_info *hw_config)
#ifdef MODULE
if (!smw_ucode)
{
- extern void *smw_free;
-
smw_ucodeLen = mod_firmware_load("/etc/sound/midi0001.bin", (void *) &smw_ucode);
smw_free = smw_ucode;
}
@@ -1272,3 +1297,17 @@ void unload_sbmpu(struct address_info *hw_config)
#endif
unload_uart401(hw_config);
}
+
+MODULE_PARM(acer, "i");
+MODULE_PARM(sm_games, "i");
+MODULE_PARM(esstype, "i");
+
+EXPORT_SYMBOL(sb_dsp_init);
+EXPORT_SYMBOL(sb_dsp_detect);
+EXPORT_SYMBOL(sb_dsp_unload);
+EXPORT_SYMBOL(sb_dsp_disable_midi);
+EXPORT_SYMBOL(sb_be_quiet);
+EXPORT_SYMBOL(attach_sbmpu);
+EXPORT_SYMBOL(probe_sbmpu);
+EXPORT_SYMBOL(unload_sbmpu);
+EXPORT_SYMBOL(smw_free);
diff --git a/drivers/sound/sgalaxy.c b/drivers/sound/sgalaxy.c
index 6859b20c3..7c02ee8b2 100644
--- a/drivers/sound/sgalaxy.c
+++ b/drivers/sound/sgalaxy.c
@@ -9,8 +9,8 @@
* Aztech Sound Galaxy Washington 16
*
* Based on cs4232.c by Hannu Savolainen and Alan Cox.
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -18,11 +18,14 @@
* for more info.
*/
+#include <linux/init.h>
#include <linux/module.h>
#include "sound_config.h"
#include "soundmodule.h"
+#include "ad1848.h"
+
static void sleep( unsigned howlong )
{
current->state = TASK_INTERRUPTIBLE;
@@ -79,10 +82,9 @@ static int sb_cmd( int base, unsigned char val )
#define ai_sgbase driver_use_1
-int probe_sgalaxy( struct address_info *ai )
+static int __init probe_sgalaxy( struct address_info *ai )
{
- if ( check_region( ai->io_base, 8 ) )
- {
+ if ( check_region( ai->io_base, 8 ) ) {
printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
return 0;
}
@@ -90,8 +92,7 @@ int probe_sgalaxy( struct address_info *ai )
if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) )
return probe_ms_sound(ai); /* The card is already active, check irq etc... */
- if ( check_region( ai->ai_sgbase, 0x10 ) )
- {
+ if ( check_region( ai->ai_sgbase, 0x10 ) ) {
printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase);
return 0;
}
@@ -108,7 +109,7 @@ int probe_sgalaxy( struct address_info *ai )
return probe_ms_sound(ai);
}
-void attach_sgalaxy( struct address_info *ai )
+static void __init attach_sgalaxy( struct address_info *ai )
{
int n;
@@ -117,27 +118,26 @@ void attach_sgalaxy( struct address_info *ai )
attach_ms_sound( ai );
n=ai->slots[0];
- if (n!=-1 && audio_devs[n]->mixer_dev != -1 )
- {
+ if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) {
AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE ); /* Line-in */
AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH ); /* FM+Wavetable*/
AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD ); /* CD */
}
}
-void unload_sgalaxy( struct address_info *ai )
+static void __exit unload_sgalaxy( struct address_info *ai )
{
unload_ms_sound( ai );
release_region( ai->ai_sgbase, 0x10 );
}
-#ifdef MODULE
+static struct address_info cfg;
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma2 = -1;
-int sgbase = -1;
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma2 = -1;
+static int __initdata sgbase = -1;
MODULE_PARM(io,"i");
MODULE_PARM(irq,"i");
@@ -145,38 +145,52 @@ MODULE_PARM(dma,"i");
MODULE_PARM(dma2,"i");
MODULE_PARM(sgbase,"i");
-EXPORT_NO_SYMBOLS;
-
-struct address_info ai;
-
-
-int init_module(void)
+static int __init init_sgalaxy(void)
{
- if ( io==-1 || irq==-1 || dma==-1 || sgbase==-1 )
- {
+ cfg.io_base = io;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.dma2 = dma2;
+ cfg.ai_sgbase = sgbase;
+
+ if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.ai_sgbase == -1 ) {
printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.\n");
return -EINVAL;
}
- ai.io_base = io;
- ai.irq = irq;
- ai.dma = dma;
- ai.dma2 = dma2;
- ai.ai_sgbase = sgbase;
-
- if ( probe_sgalaxy( &ai )==0 )
+ if ( probe_sgalaxy(&cfg) == 0 )
return -ENODEV;
- attach_sgalaxy( &ai );
+ attach_sgalaxy(&cfg);
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_sgalaxy(void)
{
- unload_sgalaxy( &ai );
+ unload_sgalaxy(&cfg);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+module_init(init_sgalaxy);
+module_exit(cleanup_sgalaxy);
+
+#ifndef MODULE
+static int __init setup_sgalaxy(char *str)
+{
+ /* io, irq, dma, dma2, sgbase */
+ int ints[6];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma2 = ints[4];
+ sgbase = ints[5];
+
+ return 1;
+}
+
+__setup("sgalaxy=", setup_sgalaxy);
+#endif
diff --git a/drivers/sound/softoss.c b/drivers/sound/softoss.c
index ac8e4034f..0ef54e6d0 100644
--- a/drivers/sound/softoss.c
+++ b/drivers/sound/softoss.c
@@ -11,9 +11,12 @@
* for more info.
*
*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * Christoph Hellwig : adapted to module_init/module_exit
*/
+
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
/*
@@ -1445,7 +1448,7 @@ static struct sound_lowlev_timer soft_tmr =
soft_tmr_restart
};
-int probe_softsyn(struct address_info *hw_config)
+static int __init probe_softsyn(struct address_info *hw_config)
{
int i;
@@ -1484,7 +1487,7 @@ int probe_softsyn(struct address_info *hw_config)
return 1;
}
-void attach_softsyn_card(struct address_info *hw_config)
+static void __init attach_softsyn_card(struct address_info *hw_config)
{
voice_alloc = &softsyn_operations.alloc;
synth_devs[devc->synthdev = num_synths++] = &softsyn_operations;
@@ -1497,7 +1500,7 @@ void attach_softsyn_card(struct address_info *hw_config)
#endif
}
-void unload_softsyn(struct address_info *hw_config)
+static void __exit unload_softsyn(struct address_info *hw_config)
{
if (!softsynth_loaded)
return;
@@ -1506,25 +1509,25 @@ void unload_softsyn(struct address_info *hw_config)
reset_samples(devc);
}
-#ifdef MODULE
-
-static struct address_info config;
+static struct address_info cfg;
-int init_module(void)
+static int __init init_softoss(void)
{
printk(KERN_INFO "SoftOSS driver Copyright (C) by Hannu Savolainen 1993-1997\n");
- if (!probe_softsyn(&config))
+ if (!probe_softsyn(&cfg))
return -ENODEV;
- attach_softsyn_card(&config);
+ attach_softsyn_card(&cfg);
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_softoss(void)
{
- unload_softsyn(&config);
+ unload_softsyn(&cfg);
sound_unload_synthdev(devc->synthdev);
sound_unload_timerdev(devc->timerdev);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+
+module_init(init_softoss);
+module_exit(cleanup_softoss);
diff --git a/drivers/sound/sound_calls.h b/drivers/sound/sound_calls.h
index 1029df1f2..8d450ca66 100644
--- a/drivers/sound/sound_calls.h
+++ b/drivers/sound/sound_calls.h
@@ -76,10 +76,6 @@ int MIDIbuf_avail(int dev);
void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
void MIDIbuf_init(void);
-/*
- *
- * Misc calls from various sources
- */
/* From soundcard.c */
void request_sound_timer (int count);
@@ -87,237 +83,16 @@ void sound_stop_timer(void);
void conf_printf(char *name, struct address_info *hw_config);
void conf_printf2(char *name, int base, int irq, int dma, int dma2);
-/* From opl3.c */
-int opl3_detect (int ioaddr, int *osp);
-int opl3_init(int ioaddr, int *osp);
-
-/* From sb_card.c */
-void attach_sb_card(struct address_info *hw_config);
-int probe_sb(struct address_info *hw_config);
-
-/* From sb_common.c */
-void sb_dsp_disable_midi(int port);
-void sb_dsp_disable_recording(int port);
-void attach_sbmpu (struct address_info *hw_config);
-int probe_sbmpu (struct address_info *hw_config);
-void unload_sbmpu (struct address_info *hw_config);
-
-/* From uart401.c */
-void attach_uart401 (struct address_info *hw_config);
-int probe_uart401 (struct address_info *hw_config);
-void unload_uart401 (struct address_info *hw_config);
-void uart401intr (int irq, void *dev_id, struct pt_regs * dummy);
-
-/* From adlib_card.c */
-void attach_adlib_card(struct address_info *hw_config);
-int probe_adlib(struct address_info *hw_config);
-
-/* From pas_card.c */
-void attach_pas_card(struct address_info *hw_config);
-int probe_pas(struct address_info *hw_config);
-int pas_set_intr(int mask);
-int pas_remove_intr(int mask);
-unsigned char pas_read(int ioaddr);
-void pas_write(unsigned char data, int ioaddr);
-
-/* From pas_audio.c */
-void pas_pcm_interrupt(unsigned char status, int cause);
-void pas_pcm_init(struct address_info *hw_config);
-
-/* From pas_mixer.c */
-int pas_init_mixer(void);
-
-/* From pas_midi.c */
-void pas_midi_init(void);
-void pas_midi_interrupt(void);
-
-/* From gus_card.c */
-void attach_gus_card(struct address_info * hw_config);
-int probe_gus(struct address_info *hw_config);
-int gus_set_midi_irq(int num);
-void gusintr(int irq, void *dev_id, struct pt_regs * dummy);
-void attach_gus_db16(struct address_info * hw_config);
-int probe_gus_db16(struct address_info *hw_config);
-
-/* From gus_wave.c */
-int gus_wave_detect(int baseaddr);
-void gus_wave_init(struct address_info *hw_config);
-void gus_wave_unload (struct address_info *hw_config);
-void gus_voice_irq(void);
-void gus_write8(int reg, unsigned int data);
-void guswave_dma_irq(void);
-void gus_delay(void);
-int gus_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg);
-void gus_timer_command (unsigned int addr, unsigned int val);
-
-/* From gus_midi.c */
-void gus_midi_init(struct address_info *hw_config);
-void gus_midi_interrupt(int dummy);
-
-/* From mpu401.c */
-void attach_mpu401(struct address_info * hw_config);
-int probe_mpu401(struct address_info *hw_config);
-int intchk_mpu401(void *dev_id);
-void mpuintr(int irq, void *dev_id, struct pt_regs * dummy);
-
-/* From uart6850.c */
-void attach_uart6850(struct address_info * hw_config);
-int probe_uart6850(struct address_info *hw_config);
-
-/* From opl3.c */
-void enable_opl3_mode(int left, int right, int both);
-
-/* From ics2101.c */
-int ics2101_mixer_init(void);
-
/* From sound_timer.c */
void sound_timer_interrupt(void);
void sound_timer_syncinterval(unsigned int new_usecs);
-/* From ad1848.c */
-int ad1848_init (char *name, int io_base, int irq, int dma_playback, int dma_capture, int share_dma, int *osp);
-void ad1848_unload (int io_base, int irq, int dma_playback, int dma_capture, int share_dma);
-
-int ad1848_detect (int io_base, int *flags, int *osp);
-#define AD_F_CS4231 0x0001 /* Returned if a CS4232 (or compatible) detected */
-#define AD_F_CS4248 0x0001 /* Returned if a CS4248 (or compatible) detected */
-
-int ad1848_control(int cmd, int arg);
-#define AD1848_SET_XTAL 1
-#define AD1848_MIXER_REROUTE 2
-#define AD1848_REROUTE(oldctl, newctl) \
- ad1848_control(AD1848_MIXER_REROUTE, ((oldctl)<<8)|(newctl))
-
-void adintr(int irq, void *dev_id, struct pt_regs * dummy);
-void attach_ms_sound(struct address_info * hw_config);
-int probe_ms_sound(struct address_info *hw_config);
-
-/* From pss.c */
-int probe_pss (struct address_info *hw_config);
-void attach_pss (struct address_info *hw_config);
-int probe_pss_mpu (struct address_info *hw_config);
-void attach_pss_mpu (struct address_info *hw_config);
-int probe_pss_mss (struct address_info *hw_config);
-void attach_pss_mss (struct address_info *hw_config);
-
-/* From sscape.c */
-int probe_sscape (struct address_info *hw_config);
-void attach_sscape (struct address_info *hw_config);
-int probe_ss_ms_sound (struct address_info *hw_config);
-void attach_ss_ms_sound(struct address_info * hw_config);
-
-/* From ad1816.c */
-void unload_ad1816(struct address_info *hw_info);
-int probe_ad1816 (struct address_info *hw_config);
-void attach_ad1816 (struct address_info *hw_config);
+/* From midi_synth.c */
+void do_midi_msg (int synthno, unsigned char *msg, int mlen);
-/* From aedsp16.c */
+#ifdef FIXED_LOWLEVEL_SOUND
+/* From aedsp16.c */
int InitAEDSP16_SBPRO(struct address_info *hw_config);
int InitAEDSP16_MSS(struct address_info *hw_config);
int InitAEDSP16_MPU401(struct address_info *hw_config);
-
-/* From midi_synth.c */
-void do_midi_msg (int synthno, unsigned char *msg, int mlen);
-
-/* From trix.c */
-void attach_trix_wss (struct address_info *hw_config);
-int probe_trix_wss (struct address_info *hw_config);
-void attach_trix_sb (struct address_info *hw_config);
-int probe_trix_sb (struct address_info *hw_config);
-void attach_trix_mpu (struct address_info *hw_config);
-int probe_trix_mpu (struct address_info *hw_config);
-
-/* From mad16.c */
-void attach_mad16 (struct address_info *hw_config);
-int probe_mad16 (struct address_info *hw_config);
-void attach_mad16_mpu (struct address_info *hw_config);
-int probe_mad16_mpu (struct address_info *hw_config);
-
-/* Unload routines from various source files*/
-void unload_pss(struct address_info *hw_info);
-void unload_pss_mpu(struct address_info *hw_info);
-void unload_pss_mss(struct address_info *hw_info);
-void unload_mad16(struct address_info *hw_info);
-void unload_mad16_mpu(struct address_info *hw_info);
-void unload_adlib(struct address_info *hw_info);
-void unload_pas(struct address_info *hw_info);
-void unload_mpu401(struct address_info *hw_info);
-void unload_maui(struct address_info *hw_info);
-void unload_uart6850(struct address_info *hw_info);
-void unload_sb(struct address_info *hw_info);
-void unload_sb16(struct address_info *hw_info);
-void unload_sb16midi(struct address_info *hw_info);
-void unload_gus_db16(struct address_info *hw_info);
-void unload_ms_sound(struct address_info *hw_info);
-void unload_gus(struct address_info *hw_info);
-void unload_sscape(struct address_info *hw_info);
-void unload_ss_ms_sound(struct address_info *hw_info);
-void unload_trix_wss(struct address_info *hw_info);
-void unload_trix_sb(struct address_info *hw_info);
-void unload_trix_mpu(struct address_info *hw_info);
-void unload_cs4232(struct address_info *hw_info);
-void unload_cs4232_mpu(struct address_info *hw_info);
-void unload_opl3sa_wss(struct address_info *hw_info);
-void unload_opl3sa_sb(struct address_info *hw_info);
-void unload_opl3sa_mpu(struct address_info *hw_info);
-void unload_opl3sa2(struct address_info *hw_info);
-void unload_opl3sa2_mpu(struct address_info *hw_info);
-void unload_opl3sa2_mss(struct address_info *hw_info);
-void unload_softsyn (struct address_info *hw_config);
-
-/* From cs4232.c */
-int probe_cs4232 (struct address_info *hw_config);
-void attach_cs4232 (struct address_info *hw_config);
-int probe_cs4232_mpu (struct address_info *hw_config);
-void attach_cs4232_mpu (struct address_info *hw_config);
-
-/* From opl3sa.c */
-void attach_opl3sa_wss (struct address_info *hw_config);
-int probe_opl3sa_wss (struct address_info *hw_config);
-void attach_opl3sa_sb (struct address_info *hw_config);
-int probe_opl3sa_sb (struct address_info *hw_config);
-void attach_opl3sa_mpu (struct address_info *hw_config);
-int probe_opl3sa_mpu (struct address_info *hw_config);
-
-/* From opl3sa2.c */
-int probe_opl3sa2 (struct address_info *hw_config);
-void attach_opl3sa2 (struct address_info *hw_config);
-int probe_opl3sa2_mpu (struct address_info *hw_config);
-void attach_opl3sa2_mpu (struct address_info *hw_config);
-int probe_opl3sa2_mss (struct address_info *hw_config);
-void attach_opl3sa2_mss (struct address_info *hw_config);
-
-/* From softoss.c */
-void attach_softsyn_card (struct address_info *hw_config);
-int probe_softsyn (struct address_info *hw_config);
-
-/* From maui.c */
-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);
-
-/* From vidc.c */
-void attach_vidc(struct address_info *hw_config);
-int probe_vidc(struct address_info *hw_config);
-void unload_vidc(struct address_info *hw_config);
-
-/* From waveartist.c */
-void attach_waveartist(struct address_info *hw_config);
-int probe_waveartist(struct address_info *hw_config);
-void unload_waveartist(struct address_info *hw_config);
-
-/* From wavefront.c */
-void attach_wavefront (struct address_info *hw_config);
-int probe_wavefront (struct address_info *hw_config);
-void unload_wavefront (struct address_info *hw_config);
-
-/* From wf_midi.c */
-void attach_wf_mpu(struct address_info * hw_config);
-int probe_wf_mpu(struct address_info *hw_config);
-void unload_wf_mpu(struct address_info *hw_config);
-int virtual_midi_enable (void);
-int virtual_midi_disable (void);
+#endif
diff --git a/drivers/sound/sound_config.h b/drivers/sound/sound_config.h
index 7621f33be..35c39e947 100644
--- a/drivers/sound/sound_config.h
+++ b/drivers/sound/sound_config.h
@@ -46,18 +46,6 @@
#define CONFIG_PAS_BASE 0x388
#endif
-#if defined(CONFIG_SB16_DMA) && !defined(CONFIG_SB_DMA2)
-# define CONFIG_SB_DMA2 CONFIG_SB16_DMA
-#endif
-
-#if defined(SB16MIDI_BASE) && !defined(CONFIG_SB_MPU_BASE)
-# define CONFIG_SB_MPU_BASE SB16MIDI_BASE
-#endif
-
-#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
driver. (There is no need to alter this) */
#define SEQ_MAX_QUEUE 1024
diff --git a/drivers/sound/sound_syms.c b/drivers/sound/sound_syms.c
index bf3ff10fe..b6f2855be 100644
--- a/drivers/sound/sound_syms.c
+++ b/drivers/sound/sound_syms.c
@@ -46,8 +46,6 @@ EXPORT_SYMBOL(sound_unload_synthdev);
EXPORT_SYMBOL(load_mixer_volumes);
-EXPORT_SYMBOL(trace_init); /* oops! this is needed for maui.c -- AJK */
-
EXPORT_SYMBOL(conf_printf);
EXPORT_SYMBOL(conf_printf2);
diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c
index 81f9cdb19..00f8b6e7b 100644
--- a/drivers/sound/soundcard.c
+++ b/drivers/sound/soundcard.c
@@ -2,24 +2,24 @@
* linux/drivers/sound/soundcard.c
*
* Sound card driver for Linux
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
- */
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ *
+ *
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
* integrated sound_switch.c
- * Stefan Reinauer : integrated /proc/sound (equals to /dev/sndstat,
+ * Stefan Reinauer : integrated /proc/sound (equals to /dev/sndstat,
* which should disappear in the near future)
- * Eric Dumas : devfs support (22-Jan-98) <dumas@linux.eu.org> with fixups
- * by C. Scott Ananian <cananian@alumni.princeton.edu>
- * Richard Gooch : moved common (non OSS-specific) devices to sound_core.c
- *
- * Rob Riggs Added persistent DMA buffers support (1998/10/17)
+ * Eric Dumas : devfs support (22-Jan-98) <dumas@linux.eu.org> with
+ * fixups by C. Scott Ananian <cananian@alumni.princeton.edu>
+ * Richard Gooch : moved common (non OSS-specific) devices to sound_core.c
+ * Rob Riggs : Added persistent DMA buffers support (1998/10/17)
+ * Christoph Hellwig : Some cleanup work (2000/03/01)
*/
#include <linux/config.h>
@@ -32,7 +32,6 @@
#include <linux/ctype.h>
#include <linux/stddef.h>
#include <linux/kmod.h>
-#ifdef __KERNEL__
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/segment.h>
@@ -41,24 +40,23 @@
#include <linux/ioport.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/major.h>
-#endif /* __KERNEL__ */
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include "soundmodule.h"
+
+#if defined(CONFIG_LOWLEVEL_SOUND) && !defined MODULE
+extern void sound_preinit_lowlevel_drivers(void);
+extern void sound_init_lowlevel_drivers(void);
+#endif
+
/* From obsolete legacy.h */
#define SELECTED_SOUND_OPTIONS 0x0
struct notifier_block *sound_locker=(struct notifier_block *)0;
static int lock_depth = 0;
-#ifdef MODULE
-#define modular 1
-#else
-#define modular 0
-#endif
-
/*
* This ought to be moved into include/asm/dma.h
*/
@@ -76,16 +74,9 @@ caddr_t sound_mem_blocks[1024];
int sound_nblocks = 0;
/* Persistent DMA buffers */
-#ifdef CONFIG_SOUND_DMAP
-int sound_dmap_flag = 1;
-#else
int sound_dmap_flag = 0;
-#endif
-
static int soundcard_configured = 0;
-
-static char dma_alloc_map[MAX_DMA_CHANNELS] =
-{0};
+static char dma_alloc_map[MAX_DMA_CHANNELS] = {0};
#define DMA_MAP_UNAVAIL 0
#define DMA_MAP_FREE 1
@@ -101,6 +92,8 @@ unsigned long seq_time = 0; /* Time for /dev/sequencer */
static mixer_vol_table mixer_vols[MAX_MIXER_DEV];
static int num_mixer_volumes = 0;
+int traceinit = 0;
+
int *load_mixer_volumes(char *name, int *levels, int present)
{
int i, n;
@@ -159,137 +152,6 @@ static int get_mixer_levels(caddr_t arg)
return 0;
}
-static int sound_proc_get_info(char *buffer, char **start, off_t offset, int length)
-{
- 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
-
- down_read(&uts_sem);
-
- 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);
- up_read(&uts_sem);
-
- 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");
- 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;
- }
- }
-
- 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;
- }
- }
-
- 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;
- }
- }
-
- 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;
- }
- }
-
- 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;
-}
-
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
@@ -297,67 +159,6 @@ static int sound_proc_get_info(char *buffer, char **start, off_t offset, int len
/* 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);
- 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 = MINOR(file->f_dentry->d_inode->i_rdev);
@@ -373,10 +174,6 @@ static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *pp
DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
switch (dev & 0x0f) {
- case SND_DEV_STATUS:
- ret = sndstat_file_read(file, buf, count, ppos);
- break;
-
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
@@ -484,10 +281,8 @@ static int sound_open(struct inode *inode, struct file *file)
}
in_use++;
-#ifdef CONFIG_MODULES
notifier_call_chain(&sound_locker, 1, 0);
lock_depth++;
-#endif
return 0;
}
@@ -522,10 +317,8 @@ static int sound_release(struct inode *inode, struct file *file)
}
in_use--;
-#ifdef CONFIG_MODULES
notifier_call_chain(&sound_locker, 0, 0);
lock_depth--;
-#endif
return 0;
}
@@ -844,22 +637,13 @@ soundcard_init(void)
soundcard_configured = 1;
- sndtable_init(); /* Initialize call tables and detect cards */
-
-
-#ifdef FIXME
- if (sndtable_get_cardcount() == 0)
- return; /* No cards detected */
+#if defined(CONFIG_LOWLEVEL_SOUND) && !defined(MODULE)
+ sound_preinit_lowlevel_drivers();
+ sound_init_lowlevel_drivers();
#endif
- if (num_audiodevs || modular) /* Audio devices present */
- {
- audio_init_devices();
- }
-#ifdef CONFIG_PROC_FS
- if (!create_proc_info_entry("sound", 0, NULL, sound_proc_get_info))
- printk(KERN_ERR "sound: registering /proc/sound failed\n");
-#endif
+ audio_init_devices();
+
soundcard_register_devfs(1); /* register after we know # of devices */
}
@@ -876,7 +660,6 @@ static int sound[20] = {
0
};
-int traceinit = 0;
static int dmabuf = 0;
static int dmabug = 0;
@@ -892,8 +675,6 @@ int init_module(void)
int i;
#endif
- trace_init=traceinit;
-
#ifdef HAS_BRIDGE_BUGGY_FUNC
if(dmabug)
isa_dma_bridge_buggy = dmabug;
@@ -956,7 +737,6 @@ void cleanup_module(void)
sound_unload_lowlevel_drivers();
}
#endif
- sound_unload_drivers();
sequencer_unload();
for (i = 0; i < MAX_DMA_CHANNELS; i++)
@@ -1075,9 +855,8 @@ void sound_stop_timer(void)
void conf_printf(char *name, struct address_info *hw_config)
{
- if (!trace_init)
+ if (!traceinit)
return;
-
printk("<%s> at 0x%03x", name, hw_config->io_base);
if (hw_config->irq)
@@ -1094,7 +873,7 @@ void conf_printf(char *name, struct address_info *hw_config)
void conf_printf2(char *name, int base, int irq, int dma, int dma2)
{
- if (!trace_init)
+ if (!traceinit)
return;
printk("<%s> at 0x%03x", name, base);
diff --git a/drivers/sound/soundmodule.h b/drivers/sound/soundmodule.h
index b89e74e51..6fb0b00a0 100644
--- a/drivers/sound/soundmodule.h
+++ b/drivers/sound/soundmodule.h
@@ -2,12 +2,11 @@
#define _SOUNDMODULE_H
#include <linux/notifier.h>
+#include <linux/module.h>
extern struct notifier_block *sound_locker;
extern void sound_notifier_chain_register(struct notifier_block *);
-#ifdef MODULE
-
#define SOUND_LOCK sound_notifier_chain_register(&sound_notifier);
#define SOUND_LOCK_END notifier_chain_unregister(&sound_locker, &sound_notifier)
@@ -28,4 +27,3 @@ static struct notifier_block sound_notifier=
};
#endif
-#endif
diff --git a/drivers/sound/sscape.c b/drivers/sound/sscape.c
index 1c06b7c31..5efd99dd2 100644
--- a/drivers/sound/sscape.c
+++ b/drivers/sound/sscape.c
@@ -2,21 +2,22 @@
* sound/sscape.c
*
* Low level driver for Ensoniq SoundScape
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
- */
-
-/*
+ *
+ *
* Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
* Sergey Smitienko : ensoniq p'n'p support
+ * Christoph Hellwig : adapted to module_init/module_exit
*/
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
#include "sound_config.h"
@@ -30,19 +31,20 @@
#include <linux/ctype.h>
#include <linux/stddef.h>
#include <linux/kmod.h>
-#ifdef __KERNEL__
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <linux/wait.h>
#include <linux/malloc.h>
#include <linux/ioport.h>
-#endif /* __KERNEL__ */
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include "coproc.h"
+#include "ad1848.h"
+#include "mpu401.h"
+
/*
* I/O ports
*/
@@ -1005,7 +1007,7 @@ static int sscape_pnp_upload_file(sscape_info* devc, char* fn)
return 1;
}
-static void sscape_pnp_init_hw(sscape_info* devc)
+static void __init sscape_pnp_init_hw(sscape_info* devc)
{
unsigned char midi_irq = 0, sb_irq = 0;
unsigned i;
@@ -1127,7 +1129,7 @@ static void sscape_pnp_init_hw(sscape_info* devc)
sscape_pnp_free_dma(devc);
}
-static int detect_sscape_pnp(sscape_info* devc)
+static int __init detect_sscape_pnp(sscape_info* devc)
{
long i, irq_bits = 0xff;
unsigned int d;
@@ -1240,7 +1242,7 @@ static int detect_sscape_pnp(sscape_info* devc)
return 1;
}
-int probe_sscape(struct address_info *hw_config)
+static int __init probe_sscape(struct address_info *hw_config)
{
if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
@@ -1289,7 +1291,7 @@ int probe_sscape(struct address_info *hw_config)
return 1;
}
-int probe_ss_ms_sound(struct address_info *hw_config)
+static int __init probe_ss_ms_sound(struct address_info *hw_config)
{
int i, irq_bits = 0xff;
int ad_flags = 0;
@@ -1332,7 +1334,7 @@ int probe_ss_ms_sound(struct address_info *hw_config)
}
}
-void attach_ss_ms_sound(struct address_info *hw_config)
+static void __init attach_ss_ms_sound(struct address_info *hw_config)
{
/*
* This routine configures the SoundScape card for use with the
@@ -1413,13 +1415,13 @@ void attach_ss_ms_sound(struct address_info *hw_config)
}
-void unload_sscape(struct address_info *hw_config)
+static void __exit unload_sscape(struct address_info *hw_config)
{
release_region(devc->base + 2, 6);
unload_mpu401(hw_config);
}
-void unload_ss_ms_sound(struct address_info *hw_config)
+static void __exit unload_ss_ms_sound(struct address_info *hw_config)
{
ad1848_unload(hw_config->io_base,
hw_config->irq,
@@ -1429,18 +1431,16 @@ void unload_ss_ms_sound(struct address_info *hw_config)
sound_unload_audiodev(hw_config->slots[0]);
}
-#ifdef MODULE
-
-int dma = -1;
-int irq = -1;
-int io = -1;
+static struct address_info cfg;
+static struct address_info cfg_mpu;
-int mpu_irq = -1;
-int mpu_io = -1;
-
-int spea = -1;
-
-static int mss = 0;
+static int __initdata spea = -1;
+static int __initdata mss = 0;
+static int __initdata dma = -1;
+static int __initdata irq = -1;
+static int __initdata io = -1;
+static int __initdata mpu_irq = -1;
+static int __initdata mpu_io = -1;
MODULE_PARM(dma, "i");
MODULE_PARM(irq, "i");
@@ -1450,63 +1450,80 @@ MODULE_PARM(mpu_irq, "i");
MODULE_PARM(mpu_io, "i");
MODULE_PARM(mss, "i");
-struct address_info config;
-struct address_info mpu_config;
-
-int init_module(void)
+static int __init init_sscape(void)
{
printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
- if (dma == -1 || irq == -1 || io == -1)
- {
- printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
- return -EINVAL;
- }
- if (mpu_irq == -1 && mpu_io != -1)
- {
- printk(KERN_ERR "CONFIG_MPU_IRQ must be specified if CONFIG_MPU_IO is set.\n");
- return -EINVAL;
- }
- devc->codec = io;
- devc->codec_irq = irq;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.io_base = io;
+
+ cfg_mpu.irq = mpu_irq;
+ cfg_mpu.io_base = mpu_io;
+ /* WEH - Try to get right dma channel */
+ cfg_mpu.dma = dma;
+
+ devc->codec = cfg.io_base;
+ devc->codec_irq = cfg.irq;
devc->codec_type = 0;
devc->ic_type = 0;
devc->raw_buf = NULL;
-
- config.irq = irq;
- config.dma = dma;
- config.io_base = io;
- mpu_config.irq = mpu_irq;
- mpu_config.io_base = mpu_io;
- /* WEH - Try to get right dma channel */
- mpu_config.dma = dma;
-
- if(spea != -1)
- {
+ if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
+ printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
+ return -EINVAL;
+ }
+
+ if (cfg_mpu.irq == -1 && cfg_mpu.io_base != -1) {
+ printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n");
+ return -EINVAL;
+ }
+
+ if(spea != -1) {
old_hardware = spea;
printk(KERN_INFO "Forcing %s hardware support.\n",
spea?"new":"old");
}
- if (probe_sscape(&mpu_config) == 0)
+ if (probe_sscape(&cfg_mpu) == 0)
return -ENODEV;
- attach_sscape(&mpu_config);
+ attach_sscape(&cfg_mpu);
- mss = probe_ss_ms_sound(&config);
+ mss = probe_ss_ms_sound(&cfg);
if (mss)
- attach_ss_ms_sound(&config);
+ attach_ss_ms_sound(&cfg);
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_sscape(void)
{
if (mss)
- unload_ss_ms_sound(&config);
+ unload_ss_ms_sound(&cfg);
SOUND_LOCK_END;
- unload_sscape(&mpu_config);
+ unload_sscape(&cfg_mpu);
+}
+
+module_init(init_sscape);
+module_exit(cleanup_sscape);
+
+#ifndef MODULE
+static int __init setup_sscape(char *str)
+{
+ /* io, irq, dma, mpu_io, mpu_irq */
+ int ints[6];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ mpu_io = ints[4];
+ mpu_irq = ints[5];
+
+ return 1;
}
-#endif /* MODULE */
+__setup("sscape=", setup_sscape);
+#endif
diff --git a/drivers/sound/trident.c b/drivers/sound/trident.c
index de01c6cbe..b3a9f7504 100644
--- a/drivers/sound/trident.c
+++ b/drivers/sound/trident.c
@@ -29,6 +29,12 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* History
+ * v0.13 Mar 03 2000 Ollie Lho
+ * new pci_* for 2.4 kernel, back ported to 2.2
+ * v0.12 Feb 23 2000 Ollie Lho
+ * Preliminary Recording support
+ * v0.11.2 Feb 19 2000 Ollie Lho
+ * removed incomplete full-dulplex support
* v0.11.1 Jan 28 2000 Ollie Lho
* small bug in setting sample rate for 4d-nx (reported by Aaron)
* v0.11 Jan 27 2000 Ollie Lho
@@ -58,9 +64,10 @@
* Clean up of low level channel register access code. (done)
* Fix the bug on dma buffer management in update_ptr, read/write, drain_dac (done)
* Dual AC97 codecs support (done partially, need channel binding to test)
- * Recording support
+ * Recording support (done)
* Mmap support
* "Channel Binding" ioctl extension
+ * new pci device driver interface for 2.4 kernel
*/
#include <linux/module.h>
@@ -85,27 +92,15 @@
#include "trident.h"
-#undef DEBUG
-
-#define DRIVER_VERSION "0.11.1"
+#define DRIVER_VERSION "0.13"
/* magic numbers to protect our data structures */
#define TRIDENT_CARD_MAGIC 0x5072696E /* "Prin" */
#define TRIDENT_STATE_MAGIC 0x63657373 /* "cess" */
-/* The first 32 channels are called Bank A. They are (should be) reserved
- for MIDI synthesizer. But since that is not supported yet, we can (ab)use
- them to play PCM samples */
-#undef ABUSE_BANK_A
-
-/* maxinum number of instances of opening /dev/dspN, can your CPU handle this ?
- NOTE: If /dev/dsp is opened O_RDWR (i.e. full duplex) it will consume 2 HW
- channels */
-#ifdef ABUSE_BANK_A
-#define NR_HW_CH 64
-#else
+#define TRIDENT_DMA_MASK 0x3fffffff /* DMA buffer mask for pci_alloc_consist */
+
#define NR_HW_CH 32
-#endif
/* maxinum nuber of AC97 codecs connected, AC97 2.0 defined 4, but 7018 and 4D-NX only
have 2 SDATA_IN lines (currently) */
@@ -119,18 +114,29 @@ static const unsigned sample_shift[] = { 0, 1, 1, 2 };
static const char invalid_magic[] = KERN_CRIT "trident: invalid magic value in %s\n";
-struct pci_audio_info {
- u16 vendor;
- u16 device;
- char *name;
+enum {
+ TRIDENT_4D_DX = 0,
+ TRIDENT_4D_NX,
+ SIS_7018
};
-static struct pci_audio_info pci_audio_devices[] = {
- {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX, "Trident 4DWave DX"},
- {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX, "Trident 4DWave NX"},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018, "SiS 7018 PCI Audio"}
+static char * card_names[] = {
+ "Trident 4DWave DX",
+ "Trident 4DWave NX",
+ "SiS 7018 PCI Audio"
};
+static struct pci_device_id trident_pci_tbl [] __devinitdata = {
+ {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_DX},
+ {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_NX},
+ {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_7018},
+};
+
+MODULE_DEVICE_TABLE (pci, trident_pci_tbl);
+
/* "software" or virtual channel, an instance of opened /dev/dsp */
struct trident_state {
unsigned int magic;
@@ -156,14 +162,15 @@ struct trident_state {
/* OSS buffer manangemeent stuff */
void *rawbuf;
+ dma_addr_t dma_handle;
unsigned buforder;
unsigned numfrag;
unsigned fragshift;
/* our buffer acts like a circular ring */
- unsigned hwptr; /* where dma last started, update by update_ptr */
+ unsigned hwptr; /* where dma last started, updated by update_ptr */
unsigned swptr; /* where driver last clear/filled, updated by read/write */
- int count; /* bytes to be comsumed by dma machine */
+ int count; /* bytes to be comsumed or been generated by dma machine */
unsigned total_bytes; /* total bytes dmaed by hardware */
unsigned error; /* number of over/underruns */
@@ -177,22 +184,21 @@ struct trident_state {
/* OSS stuff */
unsigned mapped:1;
unsigned ready:1;
- unsigned endcleared:1;
unsigned ossfragshift;
int ossmaxfrags;
unsigned subdivision;
- } dma_dac, dma_adc;
+ } dmabuf;
};
/* hardware channels */
struct trident_channel {
int num; /* channel number */
- u32 lba; /* reg 0xe4 */
- u32 eso; /* reg 0xe8 */
- u32 delta;
- u16 attribute; /* reg 0xec */
+ u32 lba; /* Loop Begine Address, where dma buffer starts */
+ u32 eso; /* End Sample Offset, wehre dma buffer ends (in the unit of samples) */
+ u32 delta; /* delta value, sample rate / 48k for playback, 48k/sample rate for recording */
+ u16 attribute; /* control where PCM data go and come */
u16 fm_vol;
- u32 control; /* reg 0xf0 */
+ u32 control; /* signed/unsigned, 8/16 bits, mono/stereo */
};
struct trident_pcm_bank_address {
@@ -234,7 +240,6 @@ struct trident_card {
spinlock_t lock;
/* PCI device stuff */
- struct pci_audio_info *pci_info;
struct pci_dev * pci_dev;
u16 pci_id;
@@ -422,9 +427,6 @@ static struct trident_channel * trident_alloc_pcm_channel(struct trident_card *c
if (bank->bitmap == ~0UL) {
/* no more free channels avaliable */
printk(KERN_ERR "trident: no more channels available on Bank B.\n");
-#ifdef ABUSE_BANK_A
- goto bank_a;
-#endif
return NULL;
}
for (idx = 31; idx >= 0; idx--) {
@@ -435,26 +437,6 @@ static struct trident_channel * trident_alloc_pcm_channel(struct trident_card *c
return channel;
}
}
-
-#ifdef ABUSE_BANK_A
- /* channels in Bank A should be reserved for synthesizer
- not for normal use (channels in Bank A can't record) */
- bank_a:
- bank = &card->banks[BANK_A];
- if (bank->bitmap == ~0UL) {
- /* no more free channels avaliable */
- printk(KERN_ERR "trident: no more channels available on Bank A.\n");
- return NULL;
- }
- for (idx = 31; idx >= 0; idx--) {
- if (!(bank->bitmap & (1 << idx))) {
- struct trident_channel *channel = &bank->channels[idx];
- banks->bitmap |= 1 << idx;
- channel->num = idx;
- return channels;
- }
- }
-#endif
return NULL;
}
@@ -462,13 +444,8 @@ static void trident_free_pcm_channel(struct trident_card *card, int channel)
{
int bank;
-#ifdef ABUSE_BANK_A
- if (channel < 0 || channel > 63)
- return;
-#else
if (channel < 31 || channel > 63)
return;
-#endif
bank = channel >> 5;
channel = channel & 0x1f;
@@ -497,15 +474,12 @@ static int trident_load_channel_registers(struct trident_card *card, u32 *data,
}
/* called with spin lock held */
-static int trident_write_voice_regs(struct trident_state *state, unsigned int rec)
+static int trident_write_voice_regs(struct trident_state *state)
{
unsigned int data[CHANNEL_REGS + 1];
struct trident_channel *channel;
- if (rec)
- channel = state->dma_adc.channel;
- else
- channel = state->dma_dac.channel;
+ channel = state->dmabuf.channel;
data[1] = channel->lba;
data[4] = channel->control;
@@ -534,7 +508,7 @@ static int trident_write_voice_regs(struct trident_state *state, unsigned int re
return trident_load_channel_registers(state->card, data, channel->num);
}
-static int compute_rate(u32 rate)
+static int compute_rate_play(u32 rate)
{
int delta;
/* We special case 44100 and 8000 since rounding with the equation
@@ -552,10 +526,25 @@ static int compute_rate(u32 rate)
return delta;
}
+static int compute_rate_rec(u32 rate)
+{
+ int delta;
+
+ if (rate == 44100)
+ delta = 0x116a;
+ else if (rate == 8000)
+ delta = 0x6000;
+ else if (rate == 48000)
+ delta = 0x1000;
+ else
+ delta = ((48000 << 12) / rate) & 0x0000ffff;
+
+ return delta;
+}
/* set playback sample rate */
static unsigned int trident_set_dac_rate(struct trident_state * state, unsigned int rate)
{
- struct dmabuf *dmabuf = &state->dma_dac;
+ struct dmabuf *dmabuf = &state->dmabuf;
if (rate > 48000)
rate = 48000;
@@ -563,9 +552,9 @@ static unsigned int trident_set_dac_rate(struct trident_state * state, unsigned
rate = 4000;
dmabuf->rate = rate;
- dmabuf->channel->delta = compute_rate(rate);
+ dmabuf->channel->delta = compute_rate_play(rate);
- trident_write_voice_regs(state, 0);
+ trident_write_voice_regs(state);
#ifdef DEBUG
printk("trident: called trident_set_dac_rate : rate = %d\n", rate);
@@ -577,16 +566,17 @@ static unsigned int trident_set_dac_rate(struct trident_state * state, unsigned
/* set recording sample rate */
static unsigned int trident_set_adc_rate(struct trident_state * state, unsigned int rate)
{
- struct dmabuf *dmabuf = &state->dma_adc;
+ struct dmabuf *dmabuf = &state->dmabuf;
+
if (rate > 48000)
rate = 48000;
if (rate < 4000)
rate = 4000;
dmabuf->rate = rate;
- dmabuf->channel->delta = compute_rate(rate);
+ dmabuf->channel->delta = compute_rate_rec(rate);
- trident_write_voice_regs(state, 1);
+ trident_write_voice_regs(state);
#ifdef DEBUG
printk("trident: called trident_set_adc_rate : rate = %d\n", rate);
@@ -597,18 +587,18 @@ static unsigned int trident_set_adc_rate(struct trident_state * state, unsigned
/* prepare channel attributes for playback */
static void trident_play_setup(struct trident_state *state)
{
- struct dmabuf *dmabuf = &state->dma_dac;
+ struct dmabuf *dmabuf = &state->dmabuf;
struct trident_channel *channel = dmabuf->channel;
channel->lba = virt_to_bus(dmabuf->rawbuf);
- channel->delta = compute_rate(dmabuf->rate);
+ channel->delta = compute_rate_play(dmabuf->rate);
channel->eso = dmabuf->dmasize >> sample_shift[dmabuf->fmt];
channel->eso -= 1;
if (state->card->pci_id == PCI_DEVICE_ID_SI_7018) {
- /* FIXME: channel attributes are configured by ioctls, but it is not implemented
- so just set to ZERO for the moment */
+ /* FIXME: channel attributes are configured by ioctls, but it is not
+ implemented so just set to ZERO for the moment */
channel->attribute = 0;
} else {
channel->attribute = 0;
@@ -631,7 +621,7 @@ static void trident_play_setup(struct trident_state *state)
"Delat = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
channel->lba, channel->delta, channel->eso, channel->control);
#endif
- trident_write_voice_regs(state, 0);
+ trident_write_voice_regs(state);
}
/* prepare channel attributes for recording */
@@ -639,7 +629,7 @@ static void trident_rec_setup(struct trident_state *state)
{
u16 w;
struct trident_card *card = state->card;
- struct dmabuf *dmabuf = &state->dma_adc;
+ struct dmabuf *dmabuf = &state->dmabuf;
struct trident_channel *channel = dmabuf->channel;
/* Enable AC-97 ADC (capture) */
@@ -651,25 +641,30 @@ static void trident_rec_setup(struct trident_state *state)
case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
w = inb(TRID_REG(card, DX_ACR2_AC97_COM_STAT));
outb(w | 0x48, TRID_REG(card, DX_ACR2_AC97_COM_STAT));
+ /* enable and set record channel */
+ outb(0x80 | channel->num, TRID_REG(card, T4D_REC_CH));
break;
case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
w = inw(TRID_REG(card, T4D_MISCINT));
outw(w | 0x1000, TRID_REG(card, T4D_MISCINT));
+ /* enable and set record channel */
+ outb(0x80 | channel->num, TRID_REG(card, T4D_REC_CH));
break;
default:
return;
}
channel->lba = virt_to_bus(dmabuf->rawbuf);
- channel->delta = compute_rate(dmabuf->rate);
+ channel->delta = compute_rate_rec(dmabuf->rate);
channel->eso = dmabuf->dmasize >> sample_shift[dmabuf->fmt];
channel->eso -= 1;
if (state->card->pci_id == PCI_DEVICE_ID_SI_7018) {
- /* FIXME: channel attributes are configured by ioctls, but it is not implemented
- so just set to ZERO for the moment */
- channel->attribute = 0;
+ /* FIXME: channel attributes are configured by ioctls, but it is not
+ implemented so just set to 0x8a80 for the moment, record from PCM L/R
+ input and mono = (left + right + 1)/2*/
+ channel->attribute = 0x8A80;
} else {
channel->attribute = 0;
}
@@ -691,21 +686,16 @@ static void trident_rec_setup(struct trident_state *state)
"Delat = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
channel->lba, channel->delta, channel->eso, channel->control);
#endif
- trident_write_voice_regs(state, 1);
+ trident_write_voice_regs(state);
}
/* get current playback/recording dma buffer pointer (byte offset from LBA),
called with spinlock held! */
-extern __inline__ unsigned trident_get_dma_addr(struct trident_state *state, unsigned rec)
+extern __inline__ unsigned trident_get_dma_addr(struct trident_state *state)
{
- struct dmabuf *dmabuf;
+ struct dmabuf *dmabuf = &state->dmabuf;
u32 cso;
- if (rec)
- dmabuf = &state->dma_adc;
- else
- dmabuf = &state->dma_dac;
-
if (!dmabuf->enable)
return 0;
@@ -727,7 +717,8 @@ extern __inline__ unsigned trident_get_dma_addr(struct trident_state *state, uns
}
#ifdef DEBUG
- printk("trident: trident_get_dma_addr: chip reported channel: %d, cso = %d\n",
+ printk("trident: trident_get_dma_addr: chip reported channel: %d, "
+ "cso = 0x%04x\n",
dmabuf->channel->num, cso);
#endif
/* ESO and CSO are in units of Samples, convert to byte offset */
@@ -739,11 +730,11 @@ extern __inline__ unsigned trident_get_dma_addr(struct trident_state *state, uns
/* Stop recording (lock held) */
extern __inline__ void __stop_adc(struct trident_state *state)
{
- struct dmabuf *dmabuf = &state->dma_adc;
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned int chan_num = dmabuf->channel->num;
struct trident_card *card = state->card;
- dmabuf->enable &= ~DMA_RUNNING;
+ dmabuf->enable &= ~ADC_RUNNING;
trident_stop_voice(card, chan_num);
trident_disable_voice_irq(card, chan_num);
}
@@ -760,16 +751,14 @@ static void stop_adc(struct trident_state *state)
static void start_adc(struct trident_state *state)
{
- struct dmabuf *dmabuf = &state->dma_adc;
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned int chan_num = dmabuf->channel->num;
struct trident_card *card = state->card;
unsigned long flags;
spin_lock_irqsave(&card->lock, flags);
- if ((dmabuf->mapped ||
- dmabuf->count < (signed)(dmabuf->dmasize - 2*dmabuf->fragsize))
- && dmabuf->ready) {
- dmabuf->enable |= DMA_RUNNING;
+ if ((dmabuf->mapped || dmabuf->count < (signed)dmabuf->dmasize) && dmabuf->ready) {
+ dmabuf->enable |= ADC_RUNNING;
trident_enable_voice_irq(card, chan_num);
trident_start_voice(card, chan_num);
}
@@ -779,11 +768,11 @@ static void start_adc(struct trident_state *state)
/* stop playback (lock held) */
extern __inline__ void __stop_dac(struct trident_state *state)
{
- struct dmabuf *dmabuf = &state->dma_dac;
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned int chan_num = dmabuf->channel->num;
struct trident_card *card = state->card;
- dmabuf->enable &= ~DMA_RUNNING;
+ dmabuf->enable &= ~DAC_RUNNING;
trident_stop_voice(card, chan_num);
trident_disable_voice_irq(card, chan_num);
}
@@ -800,14 +789,14 @@ static void stop_dac(struct trident_state *state)
static void start_dac(struct trident_state *state)
{
- struct dmabuf *dmabuf = &state->dma_dac;
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned int chan_num = dmabuf->channel->num;
struct trident_card *card = state->card;
unsigned long flags;
spin_lock_irqsave(&card->lock, flags);
if ((dmabuf->mapped || dmabuf->count > 0) && dmabuf->ready) {
- dmabuf->enable |= DMA_RUNNING;
+ dmabuf->enable |= DAC_RUNNING;
trident_enable_voice_irq(card, chan_num);
trident_start_voice(card, chan_num);
}
@@ -818,39 +807,27 @@ static void start_dac(struct trident_state *state)
#define DMABUF_MINORDER 1
/* allocate DMA buffer, playback and recording buffer should be allocated seperately */
-static int alloc_dmabuf(struct trident_state *state, unsigned rec)
+static int alloc_dmabuf(struct trident_state *state)
{
- struct dmabuf *dmabuf;
+ struct dmabuf *dmabuf = &state->dmabuf;
void *rawbuf;
int order;
unsigned long map, mapend;
- if (rec)
- dmabuf = &state->dma_adc;
- else
- dmabuf = &state->dma_dac;
-
/* alloc as big a chunk as we can, FIXME: is this necessary ?? */
for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
- if ((rawbuf = (void *)__get_free_pages(GFP_KERNEL, order)))
+ if ((rawbuf = pci_alloc_consistent(state->card->pci_dev,
+ PAGE_SIZE << order,
+ &dmabuf->dma_handle)))
break;
if (!rawbuf)
return -ENOMEM;
+
#ifdef DEBUG
printk("trident: allocated %ld (order = %d) bytes at %p\n",
PAGE_SIZE << order, order, rawbuf);
#endif
- /* for 4DWave and 7018, there are only 30 (31) siginifcan bits for Loop Begin Address
- (LBA) which limits the address space to 1 (2) GB, bad T^2 design */
- if ((virt_to_bus(rawbuf) + (PAGE_SIZE << order) - 1) & ~0x3fffffff) {
- printk(KERN_ERR "trident: DMA buffer beyond 1 GB; "
- "bus address = 0x%lx, size = %ld\n",
- virt_to_bus(rawbuf), PAGE_SIZE << order);
- free_pages((unsigned long)rawbuf, order);
- return -ENOMEM;
- }
-
dmabuf->ready = dmabuf->mapped = 0;
dmabuf->rawbuf = rawbuf;
dmabuf->buforder = order;
@@ -864,16 +841,18 @@ static int alloc_dmabuf(struct trident_state *state, unsigned rec)
}
/* free DMA buffer */
-static void dealloc_dmabuf(struct dmabuf *dmabuf)
+static void dealloc_dmabuf(struct trident_state *state)
{
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned long map, mapend;
if (dmabuf->rawbuf) {
/* undo marking the pages as reserved */
mapend = MAP_NR(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1);
for (map = MAP_NR(dmabuf->rawbuf); map <= mapend; map++)
- clear_bit(PG_reserved, &mem_map[map].flags);
- free_pages((unsigned long)dmabuf->rawbuf, dmabuf->buforder);
+ clear_bit(PG_reserved, &mem_map[map].flags);
+ pci_free_consistent(state->card->pci_dev, PAGE_SIZE << dmabuf->buforder,
+ dmabuf->rawbuf, dmabuf->dma_handle);
}
dmabuf->rawbuf = NULL;
dmabuf->mapped = dmabuf->ready = 0;
@@ -881,25 +860,20 @@ static void dealloc_dmabuf(struct dmabuf *dmabuf)
static int prog_dmabuf(struct trident_state *state, unsigned rec)
{
- struct dmabuf *dmabuf;
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned bytepersec;
unsigned bufsize;
unsigned long flags;
int ret;
- if (rec)
- dmabuf = &state->dma_adc;
- else
- dmabuf = &state->dma_dac;
-
spin_lock_irqsave(&state->card->lock, flags);
- dmabuf->hwptr = dmabuf->swptr = dmabuf->total_bytes = 0;
- dmabuf->count = dmabuf->error = dmabuf->endcleared = 0;
+ dmabuf->hwptr = dmabuf->swptr = dmabuf->total_bytes = 0;
+ dmabuf->count = dmabuf->error = 0;
spin_unlock_irqrestore(&state->card->lock, flags);
/* allocate DMA buffer if not allocated yet */
if (!dmabuf->rawbuf)
- if ((ret = alloc_dmabuf(state, rec)))
+ if ((ret = alloc_dmabuf(state)))
return ret;
/* FIXME: figure out all this OSS fragment stuff */
@@ -958,7 +932,7 @@ static int prog_dmabuf(struct trident_state *state, unsigned rec)
*/
static void trident_clear_tail(struct trident_state *state)
{
- struct dmabuf *dmabuf = &state->dma_dac;
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned swptr;
unsigned char silence = (dmabuf->fmt & TRIDENT_FMT_16BIT) ? 0 : 0x80;
unsigned int len;
@@ -971,7 +945,6 @@ static void trident_clear_tail(struct trident_state *state)
if (swptr == 0 || swptr == dmabuf->dmasize / 2 || swptr == dmabuf->dmasize)
return;
-
if (swptr < dmabuf->dmasize/2)
len = dmabuf->dmasize/2 - swptr;
else
@@ -979,7 +952,7 @@ static void trident_clear_tail(struct trident_state *state)
memset(dmabuf->rawbuf + swptr, silence, len);
- spin_lock_irqsave(&state->card->lock, flags);
+ spin_lock_irqsave(&state->card->lock, flags);
dmabuf->swptr += len;
dmabuf->count += len;
spin_unlock_irqrestore(&state->card->lock, flags);
@@ -991,7 +964,7 @@ static void trident_clear_tail(struct trident_state *state)
static int drain_dac(struct trident_state *state, int nonblock)
{
DECLARE_WAITQUEUE(wait, current);
- struct dmabuf *dmabuf = &state->dma_dac;
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned long flags;
unsigned long tmo;
int count;
@@ -1038,49 +1011,49 @@ static int drain_dac(struct trident_state *state, int nonblock)
return 0;
}
-/* call with spinlock held! */
+/* update buffer manangement pointers, especially, dmabuf->count and dmabuf->hwptr */
static void trident_update_ptr(struct trident_state *state)
{
- struct dmabuf *dmabuf;
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned hwptr;
int diff;
- /* update ADC pointer */
- if (state->dma_adc.ready) {
- dmabuf = &state->dma_adc;
- hwptr = trident_get_dma_addr(state, 1);
- diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
+ /* update hardware pointer */
+ hwptr = trident_get_dma_addr(state);
+ diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
+ dmabuf->hwptr = hwptr;
+ dmabuf->total_bytes += diff;
- dmabuf->hwptr = hwptr;
- dmabuf->total_bytes += diff;
- dmabuf->count += diff;
+ /* error handling and process wake up for DAC */
+ if (dmabuf->enable == ADC_RUNNING) {
+ if (dmabuf->mapped) {
+ dmabuf->count -= diff;
+ if (dmabuf->count >= (signed)dmabuf->fragsize)
+ wake_up(&dmabuf->wait);
+ } else {
+ dmabuf->count += diff;
- if (dmabuf->count >= (signed)dmabuf->fragsize)
- wake_up(&dmabuf->wait);
- if (!dmabuf->mapped) {
- if (dmabuf->count > (signed)(dmabuf->dmasize - ((3 * dmabuf->fragsize) >> 1))) {
- __stop_adc(state);
+ if (dmabuf->count < 0 || dmabuf->count > dmabuf->dmasize) {
+ /* buffer underrun or buffer overrun, we have no way to recover
+ it here, just stop the machine and let the process force hwptr
+ and swptr to sync */
+ __stop_adc(state);
dmabuf->error++;
}
+ /* since dma machine only interrupts at ESO and ESO/2, we sure have at
+ least half of dma buffer free, so wake up the process unconditionally */
+ wake_up(&dmabuf->wait);
}
}
-
- /* update DAC pointer */
- if (state->dma_dac.ready) {
- dmabuf = &state->dma_dac;
- hwptr = trident_get_dma_addr(state, 0);
- diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-
- dmabuf->hwptr = hwptr;
- dmabuf->total_bytes += diff;
-
+ /* error handling and process wake up for DAC */
+ if (dmabuf->enable == DAC_RUNNING) {
if (dmabuf->mapped) {
dmabuf->count += diff;
- if (dmabuf->count >= (signed)dmabuf->fragsize)
+ if (dmabuf->count >= (signed)dmabuf->fragsize)
wake_up(&dmabuf->wait);
- }
- else {
+ } else {
dmabuf->count -= diff;
+
if (dmabuf->count < 0 || dmabuf->count > dmabuf->dmasize) {
/* buffer underrun or buffer overrun, we have no way to recover
it here, just stop the machine and let the process force hwptr
@@ -1088,7 +1061,7 @@ static void trident_update_ptr(struct trident_state *state)
__stop_dac(state);
dmabuf->error++;
}
- /* since dma machine only interrupts at ESO and ESO/2, we sure have at
+ /* since dma machine only interrupts at ESO and ESO/2, we sure have at
least half of dma buffer free, so wake up the process unconditionally */
wake_up(&dmabuf->wait);
}
@@ -1120,17 +1093,13 @@ static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
} else {
printk("trident: spurious channel irq %d.\n",
63 - i);
- trident_stop_voice(card, i);
- trident_disable_voice_irq(card, i);
+ trident_stop_voice(card, 63 - i);
+ trident_disable_voice_irq(card, 63 - i);
}
}
}
}
- if (event & SB_IRQ){
- /* Midi - TODO */
- }
-
/* manually clear interrupt status, bad hardware design, blame T^2 */
outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW),
TRID_REG(card, T4D_MISCINT));
@@ -1142,18 +1111,21 @@ static loff_t trident_llseek(struct file *file, loff_t offset, int origin)
return -ESPIPE;
}
-/* in this loop, dma_adc.count signifies the amount of data thats waiting
- to be copied to the user's buffer. it is filled by the interrupt
- handler and drained by this loop. */
+/* in this loop, dmabuf.count signifies the amount of data that is waiting to be copied to
+ the user's buffer. it is filled by the dma machine and drained by this loop. */
static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
{
struct trident_state *state = (struct trident_state *)file->private_data;
- struct dmabuf *dmabuf = &state->dma_dac;
+ struct dmabuf *dmabuf = &state->dmabuf;
ssize_t ret;
unsigned long flags;
unsigned swptr;
int cnt;
+#ifdef DEBUG
+ printk("trident: trident_read called, count = %d\n", count);
+#endif
+
VALIDATE_STATE(state);
if (ppos != &file->f_pos)
return -ESPIPE;
@@ -1167,6 +1139,12 @@ static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_
while (count > 0) {
spin_lock_irqsave(&state->card->lock, flags);
+ if (dmabuf->count > (signed) dmabuf->dmasize) {
+ /* buffer overrun, we are recovering from sleep_on_timeout,
+ resync hwptr and swptr, make process flush the buffer */
+ dmabuf->count = dmabuf->dmasize;
+ dmabuf->swptr = dmabuf->hwptr;
+ }
swptr = dmabuf->swptr;
cnt = dmabuf->dmasize - swptr;
if (dmabuf->count < cnt)
@@ -1175,25 +1153,35 @@ static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_
if (cnt > count)
cnt = count;
-
if (cnt <= 0) {
+ unsigned long tmo;
+ /* buffer is empty, start the dma machine and wait for data to be
+ recorded */
start_adc(state);
if (file->f_flags & O_NONBLOCK) {
- ret = ret ? ret : -EAGAIN;
+ if (!ret) ret = -EAGAIN;
return ret;
}
- if (!interruptible_sleep_on_timeout(&dmabuf->wait, HZ)) {
- printk(KERN_ERR
- "(trident) read: chip lockup? "
+ /* No matter how much space left in the buffer, we have to wait untill
+ CSO == ESO/2 or CSO == ESO when address engine interrupts */
+ tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
+ tmo >>= sample_shift[dmabuf->fmt];
+ /* There are two situations when sleep_on_timeout returns, one is when
+ the interrupt is serviced correctly and the process is waked up by
+ ISR ON TIME. Another is when timeout is expired, which means that
+ either interrupt is NOT serviced correctly (pending interrupt) or it
+ is TOO LATE for the process to be scheduled to run (scheduler latency)
+ which results in a (potential) buffer overrun. And worse, there is
+ NOTHING we can do to prevent it. */
+ if (!interruptible_sleep_on_timeout(&dmabuf->wait, tmo)) {
+#ifdef DEBUG
+ printk(KERN_ERR "trident: recording schedule timeout, "
"dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
dmabuf->hwptr, dmabuf->swptr);
- stop_adc(state);
- spin_lock_irqsave(&state->card->lock, flags);
- dmabuf->count = 0;
- dmabuf->hwptr = 0;
- dmabuf->swptr = 0;
- spin_unlock_irqrestore(&state->card->lock, flags);
+#endif
+ /* a buffer overrun, we delay the recovery untill next time the
+ while loop begin and we REALLY have space to record */
}
if (signal_pending(current)) {
ret = ret ? ret : -ERESTARTSYS;
@@ -1203,7 +1191,7 @@ static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_
}
if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
- ret = ret ? ret : -EFAULT;
+ if (!ret) ret = -EFAULT;
return ret;
}
@@ -1219,14 +1207,15 @@ static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_
ret += cnt;
start_adc(state);
}
-
return ret;
}
+/* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to
+ the soundcard. it is drained by the dma machine and filled by this loop. */
static ssize_t trident_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
{
struct trident_state *state = (struct trident_state *)file->private_data;
- struct dmabuf *dmabuf = &state->dma_dac;
+ struct dmabuf *dmabuf = &state->dmabuf;
ssize_t ret;
unsigned long flags;
unsigned swptr;
@@ -1234,7 +1223,7 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
#ifdef DEBUG
printk("trident: trident_write called, count = %d\n", count);
-#endif
+#endif
VALIDATE_STATE(state);
if (ppos != &file->f_pos)
@@ -1265,7 +1254,8 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
cnt = count;
if (cnt <= 0) {
unsigned long tmo;
- /* buffer is full, start the dma machine and wait for data to be played */
+ /* buffer is full, start the dma machine and wait for data to be
+ played */
start_dac(state);
if (file->f_flags & O_NONBLOCK) {
if (!ret) ret = -EAGAIN;
@@ -1275,15 +1265,16 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
CSO == ESO/2 or CSO == ESO when address engine interrupts */
tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
tmo >>= sample_shift[dmabuf->fmt];
- /* There are two situations when sleep_on_timeout returns, one is when the
- interrupt is serviced correctly and the process is waked up by ISR ON TIME.
- Another is when timeout is expired, which means that either interrupt is NOT
- serviced correctly (pending interrupt) or it is TOO LATE for the process to
- be scheduled to run (scheduler latency) which results in a (potential) buffer
- underrun. And worse, there is NOTHING we can do to prevent it. */
+ /* There are two situations when sleep_on_timeout returns, one is when
+ the interrupt is serviced correctly and the process is waked up by
+ ISR ON TIME. Another is when timeout is expired, which means that
+ either interrupt is NOT serviced correctly (pending interrupt) or it
+ is TOO LATE for the process to be scheduled to run (scheduler latency)
+ which results in a (potential) buffer underrun. And worse, there is
+ NOTHING we can do to prevent it. */
if (!interruptible_sleep_on_timeout(&dmabuf->wait, tmo)) {
#ifdef DEBUG
- printk(KERN_ERR "trident: schedule timeout, "
+ printk(KERN_ERR "trident: playback schedule timeout, "
"dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
dmabuf->hwptr, dmabuf->swptr);
@@ -1307,7 +1298,6 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
spin_lock_irqsave(&state->card->lock, flags);
dmabuf->swptr = swptr;
dmabuf->count += cnt;
- dmabuf->endcleared = 0;
spin_unlock_irqrestore(&state->card->lock, flags);
count -= cnt;
@@ -1320,32 +1310,33 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
static unsigned int trident_poll(struct file *file, struct poll_table_struct *wait)
{
- struct trident_state *s = (struct trident_state *)file->private_data;
+ struct trident_state *state = (struct trident_state *)file->private_data;
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned long flags;
unsigned int mask = 0;
- VALIDATE_STATE(s);
+ VALIDATE_STATE(state);
if (file->f_mode & FMODE_WRITE)
- poll_wait(file, &s->dma_dac.wait, wait);
+ poll_wait(file, &dmabuf->wait, wait);
if (file->f_mode & FMODE_READ)
- poll_wait(file, &s->dma_adc.wait, wait);
+ poll_wait(file, &dmabuf->wait, wait);
- spin_lock_irqsave(&s->card->lock, flags);
- trident_update_ptr(s);
+ spin_lock_irqsave(&state->card->lock, flags);
+ trident_update_ptr(state);
if (file->f_mode & FMODE_READ) {
- if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+ if (dmabuf->count >= (signed)dmabuf->fragsize)
mask |= POLLIN | POLLRDNORM;
}
if (file->f_mode & FMODE_WRITE) {
- if (s->dma_dac.mapped) {
- if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
+ if (dmabuf->mapped) {
+ if (dmabuf->count >= (signed)dmabuf->fragsize)
mask |= POLLOUT | POLLWRNORM;
} else {
- if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
+ if ((signed)dmabuf->dmasize >= dmabuf->count + (signed)dmabuf->fragsize)
mask |= POLLOUT | POLLWRNORM;
}
}
- spin_unlock_irqrestore(&s->card->lock, flags);
+ spin_unlock_irqrestore(&state->card->lock, flags);
return mask;
}
@@ -1353,7 +1344,7 @@ static unsigned int trident_poll(struct file *file, struct poll_table_struct *wa
static int trident_mmap(struct file *file, struct vm_area_struct *vma)
{
struct trident_state *state = (struct trident_state *)file->private_data;
- struct dmabuf *dmabuf;
+ struct dmabuf *dmabuf = &state->dmabuf;
int ret;
unsigned long size;
@@ -1361,11 +1352,9 @@ static int trident_mmap(struct file *file, struct vm_area_struct *vma)
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf(state, 0)) != 0)
return ret;
- dmabuf = &state->dma_dac;
} else if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf(state, 1)) != 0)
return ret;
- dmabuf = &state->dma_adc;
} else
return -EINVAL;
@@ -1385,14 +1374,15 @@ static int trident_mmap(struct file *file, struct vm_area_struct *vma)
static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
struct trident_state *state = (struct trident_state *)file->private_data;
+ struct dmabuf *dmabuf = &state->dmabuf;
unsigned long flags;
audio_buf_info abinfo;
count_info cinfo;
int val, mapped, ret;
VALIDATE_STATE(state);
- mapped = ((file->f_mode & FMODE_WRITE) && state->dma_dac.mapped) ||
- ((file->f_mode & FMODE_READ) && state->dma_adc.mapped);
+ mapped = ((file->f_mode & FMODE_WRITE) && dmabuf->mapped) ||
+ ((file->f_mode & FMODE_READ) && dmabuf->mapped);
#ifdef DEBUG
printk("trident: trident_ioctl, command = %2d, arg = 0x%08x\n",
_IOC_NR(cmd), arg ? *(int *)arg : 0);
@@ -1404,19 +1394,20 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
return put_user(SOUND_VERSION, (int *)arg);
case SNDCTL_DSP_RESET:
+ /* FIXME: spin_lock ? */
if (file->f_mode & FMODE_WRITE) {
stop_dac(state);
synchronize_irq();
- state->dma_dac.ready = 0;
- state->dma_dac.swptr = state->dma_dac.hwptr = 0;
- state->dma_dac.count = state->dma_dac.total_bytes = 0;
+ dmabuf->ready = 0;
+ dmabuf->swptr = dmabuf->hwptr = 0;
+ dmabuf->count = dmabuf->total_bytes = 0;
}
if (file->f_mode & FMODE_READ) {
stop_adc(state);
synchronize_irq();
- state->dma_adc.ready = 0;
- state->dma_adc.swptr = state->dma_adc.hwptr = 0;
- state->dma_adc.count = state->dma_adc.total_bytes = 0;
+ dmabuf->ready = 0;
+ dmabuf->swptr = dmabuf->hwptr = 0;
+ dmabuf->count = dmabuf->total_bytes = 0;
}
return 0;
@@ -1430,40 +1421,38 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
if (val >= 0) {
if (file->f_mode & FMODE_WRITE) {
stop_dac(state);
- state->dma_dac.ready = 0;
+ dmabuf->ready = 0;
spin_lock_irqsave(&state->card->lock, flags);
trident_set_dac_rate(state, val);
spin_unlock_irqrestore(&state->card->lock, flags);
}
if (file->f_mode & FMODE_READ) {
stop_adc(state);
- state->dma_adc.ready = 0;
+ dmabuf->ready = 0;
spin_lock_irqsave(&state->card->lock, flags);
trident_set_adc_rate(state, val);
spin_unlock_irqrestore(&state->card->lock, flags);
}
}
- return put_user((file->f_mode & FMODE_READ) ? state->dma_adc.rate :
- state->dma_dac.rate,
- (int *)arg);
+ return put_user(dmabuf->rate, (int *)arg);
case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
get_user_ret(val, (int *)arg, -EFAULT);
if (file->f_mode & FMODE_WRITE) {
stop_dac(state);
- state->dma_dac.ready = 0;
+ dmabuf->ready = 0;
if (val)
- state->dma_dac.fmt |= TRIDENT_FMT_STEREO;
+ dmabuf->fmt |= TRIDENT_FMT_STEREO;
else
- state->dma_dac.fmt &= ~TRIDENT_FMT_STEREO;
+ dmabuf->fmt &= ~TRIDENT_FMT_STEREO;
}
if (file->f_mode & FMODE_READ) {
stop_adc(state);
- state->dma_adc.ready = 0;
+ dmabuf->ready = 0;
if (val)
- state->dma_adc.fmt |= TRIDENT_FMT_STEREO;
+ dmabuf->fmt |= TRIDENT_FMT_STEREO;
else
- state->dma_adc.fmt &= ~TRIDENT_FMT_STEREO;
+ dmabuf->fmt &= ~TRIDENT_FMT_STEREO;
}
return 0;
@@ -1471,12 +1460,12 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
if (file->f_mode & FMODE_WRITE) {
if ((val = prog_dmabuf(state, 0)))
return val;
- return put_user(state->dma_dac.fragsize, (int *)arg);
+ return put_user(dmabuf->fragsize, (int *)arg);
}
if (file->f_mode & FMODE_READ) {
if ((val = prog_dmabuf(state, 1)))
return val;
- return put_user(state->dma_adc.fragsize, (int *)arg);
+ return put_user(dmabuf->fragsize, (int *)arg);
}
case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
@@ -1487,120 +1476,99 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
if (val != AFMT_QUERY) {
if (file->f_mode & FMODE_WRITE) {
stop_dac(state);
- state->dma_dac.ready = 0;
+ dmabuf->ready = 0;
if (val == AFMT_S16_LE)
- state->dma_dac.fmt |= TRIDENT_FMT_16BIT;
+ dmabuf->fmt |= TRIDENT_FMT_16BIT;
else
- state->dma_dac.fmt &= ~TRIDENT_FMT_16BIT;
+ dmabuf->fmt &= ~TRIDENT_FMT_16BIT;
}
if (file->f_mode & FMODE_READ) {
stop_adc(state);
- state->dma_adc.ready = 0;
+ dmabuf->ready = 0;
if (val == AFMT_S16_LE)
- state->dma_adc.fmt |= TRIDENT_FMT_16BIT;
+ dmabuf->fmt |= TRIDENT_FMT_16BIT;
else
- state->dma_adc.fmt &= ~TRIDENT_FMT_16BIT;
+ dmabuf->fmt &= ~TRIDENT_FMT_16BIT;
}
}
- if (file->f_mode & FMODE_WRITE)
- return put_user((state->dma_dac.fmt & TRIDENT_FMT_16BIT) ?
- AFMT_S16_LE : AFMT_U8, (int *)arg);
- else
- return put_user((state->dma_adc.fmt & TRIDENT_FMT_16BIT) ?
- AFMT_S16_LE : AFMT_U8, (int *)arg);
+ return put_user((dmabuf->fmt & TRIDENT_FMT_16BIT) ?
+ AFMT_S16_LE : AFMT_U8, (int *)arg);
case SNDCTL_DSP_CHANNELS:
get_user_ret(val, (int *)arg, -EFAULT);
if (val != 0) {
if (file->f_mode & FMODE_WRITE) {
stop_dac(state);
- state->dma_dac.ready = 0;
+ dmabuf->ready = 0;
if (val >= 2)
- state->dma_dac.fmt |= TRIDENT_FMT_STEREO;
+ dmabuf->fmt |= TRIDENT_FMT_STEREO;
else
- state->dma_dac.fmt &= ~TRIDENT_FMT_STEREO;
+ dmabuf->fmt &= ~TRIDENT_FMT_STEREO;
}
if (file->f_mode & FMODE_READ) {
stop_adc(state);
- state->dma_adc.ready = 0;
+ dmabuf->ready = 0;
if (val >= 2)
- state->dma_adc.fmt |= TRIDENT_FMT_STEREO;
+ dmabuf->fmt |= TRIDENT_FMT_STEREO;
else
- state->dma_adc.fmt &= ~TRIDENT_FMT_STEREO;
+ dmabuf->fmt &= ~TRIDENT_FMT_STEREO;
}
}
- if (file->f_mode & FMODE_WRITE)
- return put_user((state->dma_dac.fmt & TRIDENT_FMT_STEREO) ? 2 : 1,
- (int *)arg);
- else
- return put_user((state->dma_adc.fmt & TRIDENT_FMT_STEREO) ? 2 : 1,
- (int *)arg);
+ return put_user((dmabuf->fmt & TRIDENT_FMT_STEREO) ? 2 : 1,
+ (int *)arg);
+
case SNDCTL_DSP_POST:
/* FIXME: the same as RESET ?? */
return 0;
case SNDCTL_DSP_SUBDIVIDE:
- if ((file->f_mode & FMODE_READ && state->dma_adc.subdivision) ||
- (file->f_mode & FMODE_WRITE && state->dma_dac.subdivision))
+ if (dmabuf->subdivision)
return -EINVAL;
get_user_ret(val, (int *)arg, -EFAULT);
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
- if (file->f_mode & FMODE_READ)
- state->dma_adc.subdivision = val;
- if (file->f_mode & FMODE_WRITE)
- state->dma_dac.subdivision = val;
+ dmabuf->subdivision = val;
return 0;
case SNDCTL_DSP_SETFRAGMENT:
get_user_ret(val, (int *)arg, -EFAULT);
- if (file->f_mode & FMODE_READ) {
- state->dma_adc.ossfragshift = val & 0xffff;
- state->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
- if (state->dma_adc.ossfragshift < 4)
- state->dma_adc.ossfragshift = 4;
- if (state->dma_adc.ossfragshift > 15)
- state->dma_adc.ossfragshift = 15;
- if (state->dma_adc.ossmaxfrags < 4)
- state->dma_adc.ossmaxfrags = 4;
- }
- if (file->f_mode & FMODE_WRITE) {
- state->dma_dac.ossfragshift = val & 0xffff;
- state->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
- if (state->dma_dac.ossfragshift < 4)
- state->dma_dac.ossfragshift = 4;
- if (state->dma_dac.ossfragshift > 15)
- state->dma_dac.ossfragshift = 15;
- if (state->dma_dac.ossmaxfrags < 4)
- state->dma_dac.ossmaxfrags = 4;
- }
+
+ dmabuf->ossfragshift = val & 0xffff;
+ dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
+ if (dmabuf->ossfragshift < 4)
+ dmabuf->ossfragshift = 4;
+ if (dmabuf->ossfragshift > 15)
+ dmabuf->ossfragshift = 15;
+ if (dmabuf->ossmaxfrags < 4)
+ dmabuf->ossmaxfrags = 4;
+
return 0;
case SNDCTL_DSP_GETOSPACE:
if (!(file->f_mode & FMODE_WRITE))
return -EINVAL;
- if (!state->dma_dac.enable && (val = prog_dmabuf(state, 0)) != 0)
+ if (!dmabuf->enable && (val = prog_dmabuf(state, 0)) != 0)
return val;
spin_lock_irqsave(&state->card->lock, flags);
trident_update_ptr(state);
- abinfo.fragsize = state->dma_dac.fragsize;
- abinfo.bytes = state->dma_dac.dmasize - state->dma_dac.count;
- abinfo.fragstotal = state->dma_dac.numfrag;
- abinfo.fragments = abinfo.bytes >> state->dma_dac.fragshift;
+ abinfo.fragsize = dmabuf->fragsize;
+ abinfo.bytes = dmabuf->dmasize - dmabuf->count;
+ abinfo.fragstotal = dmabuf->numfrag;
+ abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
spin_unlock_irqrestore(&state->card->lock, flags);
return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
return -EINVAL;
- if (!state->dma_adc.enable && (val = prog_dmabuf(state, 1)) != 0)
+ if (!dmabuf->enable && (val = prog_dmabuf(state, 1)) != 0)
return val;
spin_lock_irqsave(&state->card->lock, flags);
trident_update_ptr(state);
- abinfo.fragsize = state->dma_adc.fragsize;
- abinfo.bytes = state->dma_adc.count;
- abinfo.fragstotal = state->dma_adc.numfrag;
- abinfo.fragments = abinfo.bytes >> state->dma_adc.fragshift;
+ abinfo.fragsize = dmabuf->fragsize;
+ abinfo.bytes = dmabuf->count;
+ abinfo.fragstotal = dmabuf->numfrag;
+ abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
spin_unlock_irqrestore(&state->card->lock, flags);
return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
@@ -1609,14 +1577,13 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(/* DSP_CAP_DUPLEX|*/DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP,
- (int *)arg);
+ return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP, (int *)arg);
case SNDCTL_DSP_GETTRIGGER:
val = 0;
- if (file->f_mode & FMODE_READ && state->dma_adc.enable)
+ if (file->f_mode & FMODE_READ && dmabuf->enable)
val |= PCM_ENABLE_INPUT;
- if (file->f_mode & FMODE_WRITE && state->dma_dac.enable)
+ if (file->f_mode & FMODE_WRITE && dmabuf->enable)
val |= PCM_ENABLE_OUTPUT;
return put_user(val, (int *)arg);
@@ -1624,20 +1591,18 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
get_user_ret(val, (int *)arg, -EFAULT);
if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) {
- if (!state->dma_adc.ready && (ret = prog_dmabuf(state, 1)))
+ if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
return ret;
start_adc(state);
- }
- else
+ } else
stop_adc(state);
}
if (file->f_mode & FMODE_WRITE) {
if (val & PCM_ENABLE_OUTPUT) {
- if (!state->dma_dac.ready && (ret = prog_dmabuf(state, 0)))
+ if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
return ret;
start_dac(state);
- }
- else
+ } else
stop_dac(state);
}
return 0;
@@ -1647,59 +1612,50 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
return -EINVAL;
spin_lock_irqsave(&state->card->lock, flags);
trident_update_ptr(state);
- cinfo.bytes = state->dma_adc.total_bytes;
- cinfo.blocks = state->dma_adc.count >> state->dma_adc.fragshift;
- cinfo.ptr = state->dma_adc.hwptr;
- if (state->dma_adc.mapped)
- state->dma_adc.count &= state->dma_adc.fragsize-1;
+ cinfo.bytes = dmabuf->total_bytes;
+ cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
+ cinfo.ptr = dmabuf->hwptr;
+ if (dmabuf->mapped)
+ dmabuf->count &= dmabuf->fragsize-1;
spin_unlock_irqrestore(&state->card->lock, flags);
return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
-
+
case SNDCTL_DSP_GETOPTR:
if (!(file->f_mode & FMODE_WRITE))
return -EINVAL;
spin_lock_irqsave(&state->card->lock, flags);
trident_update_ptr(state);
- cinfo.bytes = state->dma_dac.total_bytes;
- cinfo.blocks = state->dma_dac.count >> state->dma_dac.fragshift;
- cinfo.ptr = state->dma_dac.hwptr;
- if (state->dma_dac.mapped)
- state->dma_dac.count &= state->dma_dac.fragsize-1;
+ cinfo.bytes = dmabuf->total_bytes;
+ cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
+ cinfo.ptr = dmabuf->hwptr;
+ if (dmabuf->mapped)
+ dmabuf->count &= dmabuf->fragsize-1;
spin_unlock_irqrestore(&state->card->lock, flags);
return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
case SNDCTL_DSP_SETDUPLEX:
- /* XXX fix */
- return 0;
+ return -EINVAL;
case SNDCTL_DSP_GETODELAY:
if (!(file->f_mode & FMODE_WRITE))
return -EINVAL;
spin_lock_irqsave(&state->card->lock, flags);
trident_update_ptr(state);
- val = state->dma_dac.count;
+ val = dmabuf->count;
spin_unlock_irqrestore(&state->card->lock, flags);
return put_user(val, (int *)arg);
case SOUND_PCM_READ_RATE:
- return put_user((file->f_mode & FMODE_READ) ? state->dma_adc.rate :
- state->dma_dac.rate, (int *)arg);
+ return put_user(dmabuf->rate, (int *)arg);
case SOUND_PCM_READ_CHANNELS:
- if (file->f_mode & FMODE_WRITE)
- return put_user((state->dma_dac.fmt & TRIDENT_FMT_STEREO) ? 2 : 1,
- (int *)arg);
- else
- return put_user((state->dma_adc.fmt & TRIDENT_FMT_STEREO) ? 2 : 1,
- (int *)arg);
-
+ return put_user((dmabuf->fmt & TRIDENT_FMT_STEREO) ? 2 : 1,
+ (int *)arg);
+
case SOUND_PCM_READ_BITS:
- if (file->f_mode & FMODE_WRITE)
- return put_user((state->dma_dac.fmt & TRIDENT_FMT_16BIT) ?
- AFMT_S16_LE : AFMT_U8, (int *)arg);
- else
- return put_user((state->dma_adc.fmt & TRIDENT_FMT_16BIT) ?
- AFMT_S16_LE : AFMT_U8, (int *)arg);
+ return put_user((dmabuf->fmt & TRIDENT_FMT_16BIT) ?
+ AFMT_S16_LE : AFMT_U8, (int *)arg);
+
case SNDCTL_DSP_MAPINBUF:
case SNDCTL_DSP_MAPOUTBUF:
case SNDCTL_DSP_SETSYNCRO:
@@ -1738,70 +1694,61 @@ static int trident_open(struct inode *inode, struct file *file)
found_virt:
/* found a free virtual channel, allocate hardware channels */
- if (file->f_mode & FMODE_READ)
- if ((state->dma_adc.channel = trident_alloc_pcm_channel(card)) == NULL) {
- kfree (card->states[i]);
- card->states[i] = NULL;;
- return -ENODEV;
- }
- if (file->f_mode & FMODE_WRITE)
- if ((state->dma_dac.channel = trident_alloc_pcm_channel(card)) == NULL) {
- kfree (card->states[i]);
- card->states[i] = NULL;
- if (file->f_mode & FMODE_READ)
- /* free previously allocated hardware channel */
- trident_free_pcm_channel(card, state->dma_adc.channel->num);
- return -ENODEV;
- }
+ if ((state->dmabuf.channel = trident_alloc_pcm_channel(card)) == NULL) {
+ kfree (card->states[i]);
+ card->states[i] = NULL;;
+ return -ENODEV;
+ }
/* initialize the virtual channel */
state->virt = i;
state->card = card;
state->magic = TRIDENT_STATE_MAGIC;
- init_waitqueue_head(&state->dma_adc.wait);
- init_waitqueue_head(&state->dma_dac.wait);
+ init_waitqueue_head(&state->dmabuf.wait);
init_MUTEX(&state->open_sem);
file->private_data = state;
down(&state->open_sem);
- /* set default sample format, Refer to OSS Programmer's Guide */
- if (file->f_mode & FMODE_READ) {
- /* FIXME: Trident 4d can only record in singed 16-bits stereo, 48kHz sample */
- state->dma_adc.fmt = TRIDENT_FMT_STEREO|TRIDENT_FMT_16BIT;
- state->dma_adc.ossfragshift = 0;
- state->dma_adc.ossmaxfrags = 0;
- state->dma_adc.subdivision = 0;
- trident_set_adc_rate(state, 48000);
- }
-
- /* according to OSS document, /dev/dsp should be default to unsigned 8-bits,
- mono, with sample rate 8kHz and /dev/dspW will accept 16-bits sample */
+ /* set default sample format. According to OSS Programmer's Guide /dev/dsp
+ should be default to unsigned 8-bits, mono, with sample rate 8kHz and
+ /dev/dspW will accept 16-bits sample */
if (file->f_mode & FMODE_WRITE) {
- state->dma_dac.fmt &= ~TRIDENT_FMT_MASK;
+ state->dmabuf.fmt &= ~TRIDENT_FMT_MASK;
if ((minor & 0xf) == SND_DEV_DSP16)
- state->dma_dac.fmt |= TRIDENT_FMT_16BIT;
- state->dma_dac.ossfragshift = 0;
- state->dma_dac.ossmaxfrags = 0;
- state->dma_dac.subdivision = 0;
+ state->dmabuf.fmt |= TRIDENT_FMT_16BIT;
+ state->dmabuf.ossfragshift = 0;
+ state->dmabuf.ossmaxfrags = 0;
+ state->dmabuf.subdivision = 0;
trident_set_dac_rate(state, 8000);
}
+ if (file->f_mode & FMODE_READ) {
+ /* FIXME: Trident 4d can only record in singed 16-bits stereo, 48kHz sample,
+ to be dealed with in trident_set_adc_rate() ?? */
+ state->dmabuf.fmt &= ~TRIDENT_FMT_MASK;
+ if ((minor & 0xf) == SND_DEV_DSP16)
+ state->dmabuf.fmt |= TRIDENT_FMT_16BIT;
+ state->dmabuf.ossfragshift = 0;
+ state->dmabuf.ossmaxfrags = 0;
+ state->dmabuf.subdivision = 0;
+ trident_set_adc_rate(state, 8000);
+ }
+
state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&state->open_sem);
- //FIXME put back in
- //MOD_INC_USE_COUNT;
+ MOD_INC_USE_COUNT;
return 0;
}
static int trident_release(struct inode *inode, struct file *file)
{
struct trident_state *state = (struct trident_state *)file->private_data;
+ struct dmabuf *dmabuf = &state->dmabuf;
VALIDATE_STATE(state);
-
if (file->f_mode & FMODE_WRITE) {
trident_clear_tail(state);
drain_dac(state, file->f_flags & O_NONBLOCK);
@@ -1812,13 +1759,13 @@ static int trident_release(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE) {
stop_dac(state);
- dealloc_dmabuf(&state->dma_dac);
- trident_free_pcm_channel(state->card, state->dma_dac.channel->num);
+ dealloc_dmabuf(state);
+ trident_free_pcm_channel(state->card, dmabuf->channel->num);
}
if (file->f_mode & FMODE_READ) {
stop_adc(state);
- dealloc_dmabuf(&state->dma_adc);
- trident_free_pcm_channel(state->card, state->dma_adc.channel->num);
+ dealloc_dmabuf(state);
+ trident_free_pcm_channel(state->card, dmabuf->channel->num);
}
kfree(state->card->states[state->virt]);
@@ -1828,8 +1775,7 @@ static int trident_release(struct inode *inode, struct file *file)
/* we're covered by the open_sem */
up(&state->open_sem);
- //FIXME put back in
- //MOD_DEC_USE_COUNT;
+ MOD_DEC_USE_COUNT;
return 0;
}
@@ -1845,7 +1791,7 @@ static /*const*/ struct file_operations trident_audio_fops = {
};
/* trident specific AC97 functions */
-/* Write AC97 mixer registers */
+/* Write AC97 codec registers */
static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val)
{
struct trident_card *card = (struct trident_card *)codec->private_data;
@@ -1863,7 +1809,7 @@ static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val)
address = SI_AC97_WRITE;
mask = SI_AC97_BUSY_WRITE | SI_AC97_AUDIO_BUSY;
if (codec->id)
- mask |= SI_AC97_SECONDARY;
+ mask |= SI_AC97_SECONDARY;
busy = SI_AC97_BUSY_WRITE;
break;
case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
@@ -1874,7 +1820,7 @@ static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val)
address = NX_ACR1_AC97_W;
mask = NX_AC97_BUSY_WRITE;
if (codec->id)
- mask |= NX_AC97_WRITE_SECONDARY;
+ mask |= NX_AC97_WRITE_SECONDARY;
busy = NX_AC97_BUSY_WRITE;
break;
}
@@ -1968,17 +1914,13 @@ static int trident_open_mixdev(struct inode *inode, struct file *file)
match:
file->private_data = card->ac97_codec[i];
- //FIXME put back in
- //MOD_INC_USE_COUNT;
+ MOD_INC_USE_COUNT;
return 0;
}
static int trident_release_mixdev(struct inode *inode, struct file *file)
{
- //struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
-
- //FIXME put back in
- //MOD_DEC_USE_COUNT;
+ MOD_DEC_USE_COUNT;
return 0;
}
@@ -2061,36 +2003,35 @@ static int __init trident_ac97_init(struct trident_card *card)
}
/* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered
- untill "ACCESS" time (in prog_dmabuf calles by open/read/write/ioctl/mmap) */
-static int __init trident_install(struct pci_dev *pcidev, struct pci_audio_info *pci_info)
+ untill "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
+static int __devinit trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
{
- u16 w;
unsigned long iobase;
struct trident_card *card;
- iobase = pcidev->resource[0].start;
+ if (!pci_dma_supported(pci_dev, TRIDENT_DMA_MASK)) {
+ printk(KERN_ERR "trident: architecture does not support"
+ " 30bit PCI busmaster DMA\n");
+ return -1;
+ }
+
+ iobase = pci_dev->resource[0].start;
if (check_region(iobase, 256)) {
printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n",
iobase);
- return 0;
+ return -1;
}
- /* just to be sure that IO space and bus master is on */
- pci_set_master(pcidev);
- pci_read_config_word(pcidev, PCI_COMMAND, &w);
- w |= PCI_COMMAND_IO|PCI_COMMAND_MASTER;
- pci_write_config_word(pcidev, PCI_COMMAND, w);
-
if ((card = kmalloc(sizeof(struct trident_card), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "trident: out of memory\n");
- return 0;
+ return -1;
}
memset(card, 0, sizeof(*card));
card->iobase = iobase;
- card->pci_info = pci_info;
- card->pci_id = pci_info->device;
- card->irq = pcidev->irq;
+ card->pci_dev = pci_dev;
+ card->pci_id = pci_id->device;
+ card->irq = pci_dev->irq;
card->next = devs;
card->magic = TRIDENT_CARD_MAGIC;
card->banks[BANK_A].addresses = &bank_a_addrs;
@@ -2098,14 +2039,18 @@ static int __init trident_install(struct pci_dev *pcidev, struct pci_audio_info
card->banks[BANK_B].addresses = &bank_b_addrs;
card->banks[BANK_B].bitmap = 0UL;
spin_lock_init(&card->lock);
- devs = card;
+ devs = card;
+
+ pci_set_master(pci_dev);
+ pci_enable_device(pci_dev);
printk(KERN_INFO "trident: %s found at IO 0x%04lx, IRQ %d\n",
- card->pci_info->name, card->iobase, card->irq);
+ card_names[pci_id->driver_data], card->iobase, card->irq);
/* claim our iospace and irq */
- request_region(card->iobase, 256, card->pci_info->name);
- if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ, card->pci_info->name, card)) {
+ request_region(card->iobase, 256, card_names[pci_id->driver_data]);
+ if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ,
+ card_names[pci_id->driver_data], card)) {
printk(KERN_ERR "trident: unable to allocate irq %d\n", card->irq);
release_region(card->iobase, 256);
kfree(card);
@@ -2117,7 +2062,7 @@ static int __init trident_install(struct pci_dev *pcidev, struct pci_audio_info
release_region(iobase, 256);
free_irq(card->irq, card);
kfree(card);
- return 0;
+ return -1;
}
/* initilize AC97 codec and register /dev/mixer */
if (trident_ac97_init(card) <= 0) {
@@ -2125,68 +2070,66 @@ static int __init trident_install(struct pci_dev *pcidev, struct pci_audio_info
release_region(iobase, 256);
free_irq(card->irq, card);
kfree(card);
- return 0;
+ return -1;
}
outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL));
+ pci_dev->driver_data = card;
+ pci_dev->dma_mask = TRIDENT_DMA_MASK;
+
/* Enable Address Engine Interrupts */
trident_enable_loop_interrupts(card);
- return 1;
+ return 0;
}
-static int __init init_trident(void)
+static void __devexit trident_remove(struct pci_dev *pci_dev)
{
- struct pci_dev *pcidev = NULL;
- int foundone = 0;
int i;
+ struct trident_card *card = pci_dev->driver_data;
- if (!pci_present()) /* No PCI bus in this machine! */
- return -ENODEV;
+ /* Kill interrupts, and SP/DIF */
+ trident_disable_loop_interrupts(card);
- printk(KERN_INFO "Trident 4DWave/SiS 7018 PCI Audio, version "
- DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
+ /* free hardware resources */
+ free_irq(card->irq, devs);
+ release_region(card->iobase, 256);
- for (i = 0; i < sizeof (pci_audio_devices); i++) {
- pcidev = NULL;
- while ((pcidev = pci_find_device(pci_audio_devices[i].vendor,
- pci_audio_devices[i].device,
- pcidev)) != NULL) {
- foundone += trident_install(pcidev, pci_audio_devices + i);
+ /* unregister audio devices */
+ for (i = 0; i < NR_AC97; i++)
+ if (devs->ac97_codec[i] != NULL) {
+ unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
+ kfree (card->ac97_codec[i]);
}
- }
+ unregister_sound_dsp(card->dev_audio);
- if (!foundone)
- return -ENODEV;
- return 0;
+ kfree(card);
}
MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho");
MODULE_DESCRIPTION("Trident 4DWave/SiS 7018 PCI Audio Driver");
-static void __exit cleanup_trident(void)
-{
- while (devs != NULL) {
- int i;
- /* Kill interrupts, and SP/DIF */
- trident_disable_loop_interrupts(devs);
+#define TRIDENT_MODULE_NAME "trident"
- /* free hardware resources */
- free_irq(devs->irq, devs);
- release_region(devs->iobase, 256);
+static struct pci_driver trident_pci_driver = {
+ name: TRIDENT_MODULE_NAME,
+ id_table: trident_pci_tbl,
+ probe: trident_probe,
+ remove: trident_remove,
+};
- /* unregister audio devices */
- for (i = 0; i < NR_AC97; i++)
- if (devs->ac97_codec[i] != NULL) {
- unregister_sound_mixer(devs->ac97_codec[i]->dev_mixer);
- kfree (devs->ac97_codec[i]);
- }
- unregister_sound_dsp(devs->dev_audio);
+static int __init trident_init_module (void)
+{
+ printk(KERN_INFO "Trident 4DWave/SiS 7018 PCI Audio, version "
+ DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
- kfree(devs);
- devs = devs->next;
- }
+ return pci_module_init (&trident_pci_driver);
+}
+
+static void __exit trident_cleanup_module (void)
+{
+ pci_unregister_driver (&trident_pci_driver);
}
-module_init(init_trident);
-module_exit(cleanup_trident);
+module_init(trident_init_module);
+module_exit(trident_cleanup_module);
diff --git a/drivers/sound/trident.h b/drivers/sound/trident.h
index 4504cb303..6bbb25bd1 100644
--- a/drivers/sound/trident.h
+++ b/drivers/sound/trident.h
@@ -60,13 +60,13 @@
#define TRIDENT_FMT_16BIT 0x02
#define TRIDENT_FMT_MASK 0x03
-#define DMA_ENABLE 0x01
-#define DMA_RUNNING 0x02
-
+#define DAC_RUNNING 0x01
+#define ADC_RUNNING 0x02
/* Register Addresses */
/* operational registers common to DX, NX, 7018 */
enum trident_op_registers {
+ T4D_REC_CH = 0x70,
T4D_START_A = 0x80, T4D_STOP_A = 0x84,
T4D_DLY_A = 0x88, T4D_SIGN_CSO_A = 0x8c,
T4D_CSPF_A = 0x90, T4D_CEBC_A = 0x94,
diff --git a/drivers/sound/trix.c b/drivers/sound/trix.c
index 107c6ca9e..d36da3f9c 100644
--- a/drivers/sound/trix.c
+++ b/drivers/sound/trix.c
@@ -13,9 +13,11 @@
*
* Changes
* Alan Cox Modularisation, cleanup.
+ * Christoph Hellwig Adapted to module_init/module_exit
*/
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
#include "sound_config.h"
@@ -23,9 +25,10 @@
#include "sb.h"
#include "sound_firmware.h"
-#include <linux/init.h>
-#include "trix_boot.h"
+#include "ad1848.h"
+#include "mpu401.h"
+#include "trix_boot.h"
static int kilroy_was_here = 0; /* Don't detect twice */
static int sb_initialized = 0;
@@ -35,11 +38,7 @@ static int *trix_osp = NULL;
static int mpu = 0;
-#ifdef TRIX_JOYSTICK
-static int joystick=1;
-#else
static int joystick=0;
-#endif
static unsigned char trix_read(int addr)
{
@@ -137,7 +136,7 @@ static int trix_set_wss_port(struct address_info *hw_config)
* AudioTrix Pro
*/
-int probe_trix_wss(struct address_info *hw_config)
+static int __init probe_trix_wss(struct address_info *hw_config)
{
int ret;
@@ -202,8 +201,7 @@ int probe_trix_wss(struct address_info *hw_config)
return ret;
}
-void
-attach_trix_wss(struct address_info *hw_config)
+static void __init attach_trix_wss(struct address_info *hw_config)
{
static unsigned char interrupt_bits[12] = {
0, 0, 0, 0, 0, 0, 0, 0x08, 0, 0x10, 0x18, 0x20
@@ -273,7 +271,7 @@ attach_trix_wss(struct address_info *hw_config)
}
}
-int probe_trix_sb(struct address_info *hw_config)
+static int __init probe_trix_sb(struct address_info *hw_config)
{
int tmp;
@@ -323,7 +321,7 @@ int probe_trix_sb(struct address_info *hw_config)
return sb_dsp_detect(hw_config, 0, 0);
}
-void attach_trix_sb(struct address_info *hw_config)
+static void __init attach_trix_sb(struct address_info *hw_config)
{
extern int sb_be_quiet;
int old_quiet;
@@ -339,13 +337,13 @@ void attach_trix_sb(struct address_info *hw_config)
sb_be_quiet = old_quiet;
}
-void attach_trix_mpu(struct address_info *hw_config)
+static void __init attach_trix_mpu(struct address_info *hw_config)
{
hw_config->name = "AudioTrix Pro";
attach_uart401(hw_config);
}
-int probe_trix_mpu(struct address_info *hw_config)
+static int __init probe_trix_mpu(struct address_info *hw_config)
{
unsigned char conf;
static char irq_bits[] = {
@@ -406,7 +404,7 @@ int probe_trix_mpu(struct address_info *hw_config)
return probe_uart401(hw_config);
}
-void unload_trix_wss(struct address_info *hw_config)
+static void __exit unload_trix_wss(struct address_info *hw_config)
{
int dma2 = hw_config->dma2;
@@ -424,31 +422,32 @@ void unload_trix_wss(struct address_info *hw_config)
sound_unload_audiodev(hw_config->slots[0]);
}
-void unload_trix_mpu(struct address_info *hw_config)
+static inline void __exit unload_trix_mpu(struct address_info *hw_config)
{
unload_uart401(hw_config);
}
-void unload_trix_sb(struct address_info *hw_config)
+static inline void __exit unload_trix_sb(struct address_info *hw_config)
{
sb_dsp_unload(hw_config, mpu);
}
-#ifdef MODULE
-
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma2 = -1; /* Set this for modules that need it */
-
-int sb_io = -1;
-int sb_dma = -1;
-int sb_irq = -1;
+static struct address_info cfg;
+static struct address_info cfg2;
+static struct address_info cfg_mpu;
-int mpu_io = -1;
-int mpu_irq = -1;
+static int sb = 0;
+static int fw_load;
-EXPORT_NO_SYMBOLS;
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma2 = -1; /* Set this for modules that need it */
+static int __initdata sb_io = -1;
+static int __initdata sb_dma = -1;
+static int __initdata sb_irq = -1;
+static int __initdata mpu_io = -1;
+static int __initdata mpu_irq = -1;
MODULE_PARM(io,"i");
MODULE_PARM(irq,"i");
@@ -460,42 +459,33 @@ MODULE_PARM(sb_irq,"i");
MODULE_PARM(mpu_io,"i");
MODULE_PARM(mpu_irq,"i");
MODULE_PARM(joystick, "i");
-struct address_info config;
-struct address_info sb_config;
-struct address_info mpu_config;
-static int sb = 0;
-
-static int fw_load;
-
-int init_module(void)
+static int __init init_trix(void)
{
printk(KERN_INFO "MediaTrix audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
- if (io == -1 || dma == -1 || irq == -1)
- {
+ cfg.io_base = io;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.dma2 = dma2;
+
+ cfg2.io_base = sb_io;
+ cfg2.irq = sb_irq;
+ cfg2.dma = sb_dma;
+
+ cfg_mpu.io_base = mpu_io;
+ cfg_mpu.irq = mpu_irq;
+
+ if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
return -EINVAL;
}
- config.io_base = io;
- config.irq = irq;
- config.dma = dma;
- config.dma2 = dma2;
-
- sb_config.io_base = sb_io;
- sb_config.irq = sb_irq;
- sb_config.dma = sb_dma;
- mpu_config.io_base = mpu_io;
- mpu_config.irq = mpu_irq;
-
- if (sb_io != -1 && (sb_irq == -1 || sb_dma == -1))
- {
+ if (cfg2.io_base != -1 && (cfg2.irq == -1 || cfg2.dma == -1)) {
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)
- {
+ if (cfg_mpu.io_base != -1 && cfg_mpu.irq == -1) {
printk(KERN_INFO "CONFIG_MPU_IRQ must be specified if MPU_IO is set.\n");
return -EINVAL;
}
@@ -505,42 +495,65 @@ int init_module(void)
trix_boot_len = mod_firmware_load("/etc/sound/trxpro.bin",
(char **) &trix_boot);
}
- if (!probe_trix_wss(&config))
+ if (!probe_trix_wss(&cfg))
return -ENODEV;
- attach_trix_wss(&config);
+ attach_trix_wss(&cfg);
/*
* We must attach in the right order to get the firmware
* loaded up in time.
*/
- if (sb_io != -1)
- {
- sb = probe_trix_sb(&sb_config);
+ if (cfg2.io_base != -1) {
+ sb = probe_trix_sb(&cfg2);
if (sb)
- attach_trix_sb(&sb_config);
+ attach_trix_sb(&cfg2);
}
- if (mpu_io != -1)
- {
- mpu = probe_trix_mpu(&mpu_config);
+ if (cfg_mpu.io_base != -1) {
+ mpu = probe_trix_mpu(&cfg_mpu);
if (mpu)
- attach_trix_mpu(&mpu_config);
+ attach_trix_mpu(&cfg_mpu);
}
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_trix(void)
{
if (fw_load && trix_boot)
vfree(trix_boot);
if (sb)
- unload_trix_sb(&sb_config);
+ unload_trix_sb(&cfg2);
if (mpu)
- unload_trix_mpu(&mpu_config);
- unload_trix_wss(&config);
+ unload_trix_mpu(&cfg_mpu);
+ unload_trix_wss(&cfg);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+module_init(init_trix);
+module_exit(cleanup_trix);
+
+#ifndef MODULE
+static int __init setup_trix (char *str)
+{
+ /* io, irq, dma, dma2, sb_io, sb_irq, sb_dma, mpu_io, mpu_irq */
+ int ints[9];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma2 = ints[4];
+ sb_io = ints[5];
+ sb_irq = ints[6];
+ sb_dma = ints[6];
+ mpu_io = ints[7];
+ mpu_irq = ints[8];
+
+ return 1;
+}
+
+__setup("trix=", setup_trix);
+#endif
diff --git a/drivers/sound/uart401.c b/drivers/sound/uart401.c
index c4f105ef5..71721dd3e 100644
--- a/drivers/sound/uart401.c
+++ b/drivers/sound/uart401.c
@@ -2,8 +2,8 @@
* sound/uart401.c
*
* MPU-401 UART driver (formerly uart401_midi.c)
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -11,19 +11,23 @@
* for more info.
*
* Changes:
- * Alan Cox Reformatted, removed sound_mem usage, use normal Linux
- * interrupt allocation. Protect against bogus unload
- * Fixed to allow IRQ > 15
+ * Alan Cox Reformatted, removed sound_mem usage, use normal Linux
+ * interrupt allocation. Protect against bogus unload
+ * Fixed to allow IRQ > 15
+ * Christoph Hellwig Adapted to module_init/module_exit
*
* Status:
* Untested
*/
-
+
+#include <linux/init.h>
#include <linux/module.h>
#include "sound_config.h"
#include "soundmodule.h"
+#include "mpu401.h"
+
typedef struct uart401_devc
{
int base;
@@ -177,21 +181,21 @@ static int uart401_out(int dev, unsigned char midi_byte)
return 1;
}
-static int uart401_start_read(int dev)
+static inline int uart401_start_read(int dev)
{
return 0;
}
-static int uart401_end_read(int dev)
+static inline int uart401_end_read(int dev)
{
return 0;
}
-static void uart401_kick(int dev)
+static inline void uart401_kick(int dev)
{
}
-static int uart401_buffer_status(int dev)
+static inline int uart401_buffer_status(int dev)
{
return 0;
}
@@ -444,43 +448,60 @@ void unload_uart401(struct address_info *hw_config)
sound_unload_mididev(hw_config->slots[4]);
}
-#ifdef MODULE
+EXPORT_SYMBOL(attach_uart401);
+EXPORT_SYMBOL(probe_uart401);
+EXPORT_SYMBOL(unload_uart401);
+EXPORT_SYMBOL(uart401intr);
-int io = -1;
-int irq = -1;
+static struct address_info cfg_mpu;
+
+static int __initdata io = -1;
+static int __initdata irq = -1;
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
-struct address_info hw;
-int init_module(void)
+
+static int __init init_uart401(void)
{
+ cfg_mpu.irq = irq;
+ cfg_mpu.io_base = io;
+
/* Can be loaded either for module use or to provide functions
to others */
- if (io != -1 && irq != -1)
- {
+ if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1) {
printk(KERN_INFO "MPU-401 UART driver Copyright (C) Hannu Savolainen 1993-1997");
- hw.irq = irq;
- hw.io_base = io;
- if (probe_uart401(&hw) == 0)
+ if (probe_uart401(&cfg_mpu) == 0)
return -ENODEV;
- attach_uart401(&hw);
+ attach_uart401(&cfg_mpu);
}
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_uart401(void)
{
- if (io != -1 && irq != -1)
- unload_uart401(&hw);
- /* FREE SYMTAB */
+ if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1)
+ unload_uart401(&cfg_mpu);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+module_init(init_uart401);
+module_exit(cleanup_uart401);
-EXPORT_SYMBOL(attach_uart401);
-EXPORT_SYMBOL(probe_uart401);
-EXPORT_SYMBOL(unload_uart401);
-EXPORT_SYMBOL(uart401intr);
+#ifndef MODULE
+static int __init setup_uart401(char *str)
+{
+ /* io, irq */
+ int ints[3];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+
+ return 1;
+}
+
+__setup("uart401=", setup_uart401);
+#endif
diff --git a/drivers/sound/uart6850.c b/drivers/sound/uart6850.c
index b0548d513..6540df0f6 100644
--- a/drivers/sound/uart6850.c
+++ b/drivers/sound/uart6850.c
@@ -1,7 +1,7 @@
/*
* sound/uart6850.c
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -10,12 +10,15 @@
* Extended by Alan Cox for Red Hat Software. Now a loadable MIDI driver.
* 28/4/97 - (C) Copyright Alan Cox. Released under the GPL version 2.
*
- * Alan Cox: Updated for new modular code. Removed snd_* irq handling. Now
- * uses native linux resources
+ * Alan Cox: Updated for new modular code. Removed snd_* irq handling. Now
+ * uses native linux resources
+ * Christoph Hellwig: Adapted to module_init/module_exit
*
* Status: Testing required
*
*/
+
+#include <linux/init.h>
#include <linux/module.h>
/* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
@@ -199,26 +202,26 @@ static int uart6850_out(int dev, unsigned char midi_byte)
return 1;
}
-static int uart6850_command(int dev, unsigned char *midi_byte)
+static inline int uart6850_command(int dev, unsigned char *midi_byte)
{
return 1;
}
-static int uart6850_start_read(int dev)
+static inline int uart6850_start_read(int dev)
{
return 0;
}
-static int uart6850_end_read(int dev)
+static inline int uart6850_end_read(int dev)
{
return 0;
}
-static void uart6850_kick(int dev)
+static inline void uart6850_kick(int dev)
{
}
-static int uart6850_buffer_status(int dev)
+static inline int uart6850_buffer_status(int dev)
{
return 0; /*
* No data in buffers
@@ -246,7 +249,7 @@ static struct midi_operations uart6850_operations =
};
-void attach_uart6850(struct address_info *hw_config)
+static void __init attach_uart6850(struct address_info *hw_config)
{
int ok, timeout;
unsigned long flags;
@@ -292,7 +295,7 @@ static int reset_uart6850(void)
}
-int probe_uart6850(struct address_info *hw_config)
+static int __init probe_uart6850(struct address_info *hw_config)
{
int ok = 0;
@@ -308,45 +311,58 @@ int probe_uart6850(struct address_info *hw_config)
return ok;
}
-void unload_uart6850(struct address_info *hw_config)
+static void __exit unload_uart6850(struct address_info *hw_config)
{
free_irq(hw_config->irq, NULL);
sound_unload_mididev(hw_config->slots[4]);
}
+static struct address_info cfg_mpu;
-#ifdef MODULE
-
-int io = -1;
-int irq = -1;
+static int __initdata io = -1;
+static int __initdata irq = -1;
MODULE_PARM(io,"i");
MODULE_PARM(irq,"i");
-EXPORT_NO_SYMBOLS;
-
-struct address_info cfg;
-
-int init_module(void)
+static int __init init_uart6850(void)
{
- if (io == -1 || irq == -1)
- {
+ cfg_mpu.io_base = io;
+ cfg_mpu.irq = irq;
+
+ if (cfg_mpu.io_base == -1 || cfg_mpu.irq == -1) {
printk(KERN_INFO "uart6850: irq and io must be set.\n");
return -EINVAL;
}
- cfg.io_base = io;
- cfg.irq = irq;
- if (probe_uart6850(&cfg))
+ if (probe_uart6850(&cfg_mpu))
return -ENODEV;
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_uart6850(void)
{
- unload_uart6850(&cfg);
+ unload_uart6850(&cfg_mpu);
SOUND_LOCK_END;
}
-#endif /* MODULE */
+
+module_init(init_uart6850);
+module_exit(cleanup_uart6850);
+
+#ifndef MODULE
+static int __init setup_uart6850(char *str)
+{
+ /* io, irq */
+ int ints[3];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+
+ return 1;
+}
+__setup("uart6850=", setup_uart6850);
+#endif
diff --git a/drivers/sound/v_midi.c b/drivers/sound/v_midi.c
index 0cab16199..9c18ff5c8 100644
--- a/drivers/sound/v_midi.c
+++ b/drivers/sound/v_midi.c
@@ -13,11 +13,13 @@
*
* Changes
* Alan Cox Modularisation, changed memory allocations
+ * Christoph Hellwig Adapted to module_init/module_exit
*
* Status
* Untested
*/
+#include <linux/init.h>
#include <linux/module.h>
#include "sound_config.h"
@@ -29,28 +31,6 @@ 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 /* MODULE */
-
/*
* 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
@@ -126,7 +106,7 @@ static int v_midi_out (int dev, unsigned char midi_byte)
return 1;
}
-static int v_midi_start_read (int dev)
+static inline int v_midi_start_read (int dev)
{
return 0;
}
@@ -143,7 +123,7 @@ static int v_midi_end_read (int dev)
/* why -EPERM and not -EINVAL?? */
-static int v_midi_ioctl (int dev, unsigned cmd, caddr_t arg)
+static inline int v_midi_ioctl (int dev, unsigned cmd, caddr_t arg)
{
return -EPERM;
}
@@ -201,7 +181,7 @@ struct vmidi_memory
struct vmidi_devc v_ops[2];
};
-void attach_v_midi (struct address_info *hw_config)
+static void __init attach_v_midi (struct address_info *hw_config)
{
struct vmidi_memory *m;
/* printk("Attaching v_midi device.....\n"); */
@@ -282,15 +262,38 @@ void attach_v_midi (struct address_info *hw_config)
/* printk("Attached v_midi device\n"); */
}
-int probe_v_midi(struct address_info *hw_config)
+static inline int __init probe_v_midi(struct address_info *hw_config)
{
return(1); /* always OK */
}
-void unload_v_midi(struct address_info *hw_config)
+static void __exit unload_v_midi(struct address_info *hw_config)
{
sound_unload_mididev(midi1);
sound_unload_mididev(midi2);
kfree(midi_mem);
}
+
+static struct address_info cfg; /* dummy */
+
+static int __init init_vmidi(void)
+{
+ printk("MIDI Loopback device driver\n");
+ if (!probe_v_midi(&cfg))
+ return -ENODEV;
+ attach_v_midi(&cfg);
+
+ SOUND_LOCK;
+
+ return 0;
+}
+
+static void __exit cleanup_vmidi(void)
+{
+ unload_v_midi(&cfg);
+ SOUND_LOCK_END;
+}
+
+module_init(init_vmidi);
+module_exit(cleanup_vmidi);
diff --git a/drivers/sound/via82cxxx_audio.c b/drivers/sound/via82cxxx_audio.c
index cee2e7b0a..5745a9037 100644
--- a/drivers/sound/via82cxxx_audio.c
+++ b/drivers/sound/via82cxxx_audio.c
@@ -33,6 +33,7 @@
#include "soundmodule.h"
#include "sb.h"
#include "ac97.h"
+#include "mpu401.h"
#ifndef SOUND_LOCK
#define SOUND_LOCK do {} while (0)
diff --git a/drivers/sound/vidc.c b/drivers/sound/vidc.c
index 578d4dff9..9cebcc324 100644
--- a/drivers/sound/vidc.c
+++ b/drivers/sound/vidc.c
@@ -14,6 +14,7 @@
*/
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -412,7 +413,7 @@ void vidc_update_filler(int format, int channels)
}
}
-void attach_vidc(struct address_info *hw_config)
+static void __init attach_vidc(struct address_info *hw_config)
{
char name[32];
int i, adev;
@@ -486,7 +487,7 @@ audio_failed:
return;
}
-int probe_vidc(struct address_info *hw_config)
+static int __init probe_vidc(struct address_info *hw_config)
{
hw_config->irq = IRQ_DMAS0;
hw_config->dma = DMA_VIRTUAL_SOUND;
@@ -496,7 +497,7 @@ int probe_vidc(struct address_info *hw_config)
return 1;
}
-void unload_vidc(struct address_info *hw_config)
+static void __exit unload_vidc(struct address_info *hw_config)
{
int i, adev = vidc_adev;
@@ -516,27 +517,27 @@ void unload_vidc(struct address_info *hw_config)
}
}
-#ifdef MODULE
-static struct address_info config;
+static struct address_info cfg;
/*
* Note! Module use count is handled by SOUNDLOCK/SOUND_LOCK_END
*/
-int init_module(void)
+static int __init init_vidc(void)
{
- if (probe_vidc(&config) == 0)
+ if (probe_vidc(&cfg) == 0)
return -ENODEV;
SOUND_LOCK;
- attach_vidc(&config);
+ attach_vidc(&cfg);
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_vidc(void)
{
- unload_vidc(&config);
+ unload_vidc(&cfg);
SOUND_LOCK_END;
}
-#endif
+module_init(init_vidc);
+module_exit(cleanup_vidc);
diff --git a/drivers/sound/waveartist.c b/drivers/sound/waveartist.c
index 905b9cff6..d1631defd 100644
--- a/drivers/sound/waveartist.c
+++ b/drivers/sound/waveartist.c
@@ -6,9 +6,8 @@
*
* Cleaned up and integrated into 2.1 by Russell King (rmk@arm.linux.org.uk)
* and Pat Beirne (patb@corel.ca)
- */
-
-/*
+ *
+ *
* Copyright (C) by Rebel.com 1998-1999
*
* RWA010 specs received under NDA from Rockwell
@@ -31,6 +30,7 @@
#define debug_flg (0)
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
@@ -1281,8 +1281,7 @@ nomem:
return -1;
}
-int
-probe_waveartist(struct address_info *hw_config)
+static int __init probe_waveartist(struct address_info *hw_config)
{
wavnc_info *devc = &adev_info[nr_waveartist_devs];
@@ -1316,8 +1315,7 @@ probe_waveartist(struct address_info *hw_config)
return 1;
}
-void
-attach_waveartist(struct address_info *hw)
+static void __init attach_waveartist(struct address_info *hw)
{
wavnc_info *devc = &adev_info[nr_waveartist_devs];
@@ -1359,8 +1357,7 @@ attach_waveartist(struct address_info *hw)
}
}
-void
-unload_waveartist(struct address_info *hw)
+static void __exit unload_waveartist(struct address_info *hw)
{
wavnc_info *devc = NULL;
int i;
@@ -1757,45 +1754,63 @@ vnc_private_ioctl(int dev, unsigned int cmd, caddr_t arg)
return -ENOIOCTLCMD;
}
-#ifdef MODULE
+static struct address_info cfg;
+
+static int attached;
+
+static int __initdata io;
+static int __initdata irq;
+static int __initdata dma;
+static int __initdata dma2;
+
MODULE_PARM(io, "i"); /* IO base */
MODULE_PARM(irq, "i"); /* IRQ */
MODULE_PARM(dma, "i"); /* DMA */
MODULE_PARM(dma2, "i"); /* DMA2 */
-static int io = CONFIG_WAVEARTIST_BASE;
-static int irq = CONFIG_WAVEARTIST_IRQ;
-static int dma = CONFIG_WAVEARTIST_DMA;
-static int dma2 = CONFIG_WAVEARTIST_DMA2;
-
-static int attached;
-
-static struct address_info hw_config;
-
-int init_module(void)
+static int __init init_waveartist(void)
{
- hw_config.io_base = io;
- hw_config.irq = irq;
- hw_config.dma = dma;
- hw_config.dma2 = dma2;
+ cfg.io_base = io;
+ cfg.irq = irq;
+ cfg.dma = dma;
+ cfg.dma2 = dma2;
- if (!probe_waveartist(&hw_config))
+ if (!probe_waveartist(&cfg))
return -ENODEV;
- attach_waveartist(&hw_config);
+ attach_waveartist(&cfg);
attached = 1;
SOUND_LOCK;
return 0;
}
-void cleanup_module(void)
+static void __exit cleanup_waveartist(void)
{
if (attached) {
SOUND_LOCK_END;
-
- unload_waveartist(&hw_config);
+ unload_waveartist(&cfg);
}
}
+
+module_init(init_waveartist);
+module_exit(cleanup_waveartist);
+
+#ifndef MODULE
+static int __init setup_waveartist(char *str)
+{
+ /* io, irq, dma, dma2 */
+ int ints[5];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+
+ io = ints[1];
+ irq = ints[2];
+ dma = ints[3];
+ dma16 = ints[4];
+
+ return 1;
+}
+__setup("waveartist=", setup_waveartist);
#endif
diff --git a/drivers/sound/wavfront.c b/drivers/sound/wavfront.c
index 2967fdf18..af1f8970d 100644
--- a/drivers/sound/wavfront.c
+++ b/drivers/sound/wavfront.c
@@ -65,6 +65,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/fcntl.h>
@@ -128,10 +129,6 @@ static int (*midi_load_patch) (int devno, int format, const char *addr,
int offs, int count, int pmgr_flag) = NULL;
#endif OSS_SUPPORT_SEQ
-/* This is meant to work as a module */
-
-#if defined(CONFIG_SOUND_WAVEFRONT_MODULE) && defined(MODULE)
-
/* if WF_DEBUG not defined, no run-time debugging messages will
be available via the debug flag setting. Given the current
beta state of the driver, this will remain set until a future
@@ -2144,25 +2141,23 @@ static struct synth_operations wavefront_operations =
#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_STATIC_INSTALL
-void attach_wavefront (struct address_info *hw_config)
-
+static void __init attach_wavefront (struct address_info *hw_config)
{
(void) install_wavefront ();
}
-int probe_wavefront (struct address_info *hw_config)
-
+static int __init probe_wavefront (struct address_info *hw_config)
{
return !detect_wavefront (hw_config->irq, hw_config->io_base);
}
-void unload_wavefront (struct address_info *hw_config)
+static void __exit unload_wavefront (struct address_info *hw_config)
{
(void) uninstall_wavefront ();
}
#endif OSS_SUPPORT_STATIC_INSTALL
-
+
/***********************************************************************/
/* WaveFront: Linux modular sound kernel installation interface */
/***********************************************************************/
@@ -2814,8 +2809,7 @@ wavefront_do_reset (int atboot)
return 1;
}
-static int
-wavefront_init (int atboot)
+static int __init wavefront_init (int atboot)
{
int samples_are_from_rom;
@@ -2884,9 +2878,7 @@ static int __init install_wavefront (void)
return dev.oss_dev;
}
-void
-uninstall_wavefront (void)
-
+static void __exit uninstall_wavefront (void)
{
/* the first two i/o addresses are freed by the wf_mpu code */
release_region (dev.base+2, 6);
@@ -2938,7 +2930,7 @@ wffx_idle (void)
return (1);
}
-static int __init detect_wffx (void)
+int __init detect_wffx (void)
{
/* This is a crude check, but its the best one I have for now.
Certainly on the Maui and the Tropez, wffx_idle() will
@@ -2954,7 +2946,7 @@ static int __init detect_wffx (void)
return 0;
}
-static int __init attach_wffx (void)
+int __init attach_wffx (void)
{
if ((dev.fx_mididev = sound_alloc_mididev ()) < 0) {
printk (KERN_WARNING LOGNAME "cannot install FX Midi driver\n");
@@ -2964,7 +2956,7 @@ static int __init attach_wffx (void)
return 0;
}
-static void
+void
wffx_mute (int onoff)
{
@@ -3087,9 +3079,7 @@ wffx_ioctl (wavefront_fx_info *r)
a somewhat "algorithmic" approach.
*/
-static int
-wffx_init (void)
-
+static int wffx_init (void)
{
int i;
int j;
@@ -3543,18 +3533,15 @@ wffx_init (void)
return (0);
}
-EXPORT_NO_SYMBOLS;
-
-int io = -1;
-int irq = -1;
+static int io = -1;
+static int irq = -1;
MODULE_AUTHOR ("Paul Barton-Davis <pbd@op.net>");
MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver");
MODULE_PARM (io,"i");
MODULE_PARM (irq,"i");
-int init_module (void)
-
+static int __init init_wavfront (void)
{
printk ("Turtle Beach WaveFront Driver\n"
"Copyright (C) by Hannu Solvainen, "
@@ -3585,14 +3572,11 @@ int init_module (void)
return 0;
}
-void cleanup_module (void)
-
+static void __exit cleanup_wavfront (void)
{
uninstall_wavefront ();
-
SOUND_LOCK_END;
}
-#endif CONFIG_SOUND_WAVEFRONT_MODULE && MODULE
-
-
+module_init(init_wavfront);
+module_exit(cleanup_wavfront);
diff --git a/drivers/sound/wf_midi.c b/drivers/sound/wf_midi.c
index 45db0f8b1..4b0708ec7 100644
--- a/drivers/sound/wf_midi.c
+++ b/drivers/sound/wf_midi.c
@@ -42,7 +42,7 @@
* Copyright (C) by Paul Barton-Davis 1998
* Some portions of this file are derived from work that is:
*
- * Copyright (C) by Hannu Savolainen 1993-1996
+ * 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
@@ -56,7 +56,7 @@
#include <linux/wavefront.h>
-#if defined(CONFIG_SOUND_WAVEFRONT_MODULE) && defined(MODULE)
+#ifdef MODULE
struct wf_mpu_config {
int base;
@@ -87,37 +87,27 @@ static void start_uart_mode (void);
#define MPU_ACK 0xFE
#define UART_MODE_ON 0x3F
-static inline int
-wf_mpu_status (void)
-
+static inline int wf_mpu_status (void)
{
return inb (STATPORT (phys_dev));
}
-static inline int
-input_avail (void)
-
+static inline int input_avail (void)
{
return !(wf_mpu_status() & INPUT_AVAIL);
}
-static inline int
-output_ready (void)
-
+static inline int output_ready (void)
{
return !(wf_mpu_status() & OUTPUT_READY);
}
-static inline int
-read_data (void)
-
+static inline int read_data (void)
{
return inb (DATAPORT (phys_dev));
}
-static inline void
-write_data (unsigned char byte)
-
+static inline void write_data (unsigned char byte)
{
outb (byte, DATAPORT (phys_dev));
}
@@ -536,28 +526,22 @@ wf_mpu_out (int dev, unsigned char midi_byte)
return 1;
}
-static int
-wf_mpu_start_read (int dev)
-{
+static inline int wf_mpu_start_read (int dev) {
return 0;
}
-static int
-wf_mpu_end_read (int dev)
-{
+static inline int wf_mpu_end_read (int dev) {
return 0;
}
-static int
-wf_mpu_ioctl (int dev, unsigned cmd, caddr_t arg)
+static int wf_mpu_ioctl (int dev, unsigned cmd, caddr_t arg)
{
printk (KERN_WARNING
"WF-MPU: Intelligent mode not supported by hardware.\n");
return -(EINVAL);
}
-static int
-wf_mpu_buffer_status (int dev)
+static int wf_mpu_buffer_status (int dev)
{
return 0;
}
@@ -901,31 +885,4 @@ start_uart_mode (void)
restore_flags (flags);
}
-
-#ifdef OSS_SUPPORT
-
-int
-probe_wf_mpu (struct address_info *hw_config)
-
-{
- return !detect_wf_mpu (hw_config->irq, hw_config->io_base);
-}
-
-void
-attach_wf_mpu (struct address_info *hw_config)
-
-{
- (void) install_wf_mpu ();
-}
-
-void
-unload_wf_mpu (void)
-{
- uninstall_wf_mpu ();
-}
-
-#endif OSS_SUPPORT
-
-#endif CONFIG_SOUND_WAVEFRONT_MODULE_AND_MODULE
-
-
+#endif