diff options
91 files changed, 819 insertions, 2208 deletions
diff --git a/Documentation/sound/alsa/serial-u16550.txt b/Documentation/sound/alsa/serial-u16550.txt new file mode 100644 index 000000000000..038e0d5a7ee4 --- /dev/null +++ b/Documentation/sound/alsa/serial-u16550.txt @@ -0,0 +1,84 @@ + + Serial UART 16450/16550 MIDI driver + =================================== + +The snd_adaptor module parameter allows you to select either: + + 0 - Roland Soundcanvas support (default) + 1 - Midiator MS-124T support (1) + 2 - Midiator MS-124W S/A mode (2) + 3 - MS-124W M/B mode support (3) + +For the Midiator MS-124W, you must set the physical M-S and A-B +switches on the Midiator to match the driver mode you select. + +In Roland Soundcanvas mode, multiple ALSA raw MIDI substreams are supported +(midiCnD0-midiCnD15). Whenever you write to a different substream, the driver +sends the nonstandard MIDI command sequence F5 NN, where NN is the substream +number plus 1. Roland modules use this command to switch between different +"parts", so this feature lets you treat each part as a distinct raw MIDI +substream. The driver provides no way to send F5 00 (no selection) or to not +send the F5 NN command sequence at all; perhaps it ought to. + +Usage example for simple serial converter: + + /sbin/setserial /dev/ttyS0 none + /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \ + snd_speed=115200 + +Usage example for Roland SoundCanvas with 4 MIDI ports: + + /sbin/setserial /dev/ttyS0 none + /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 snd_outs=4 + +In MS-124T mode, one raw MIDI substream is supported (midiCnD0); the snd_outs +module parameter is automatically set to 1. The driver sends the same data to +all four MIDI Out connectors. Set the A-B switch and the snd_speed module +parameter to match (A=19200, B=9600). + +Usage example for MS-124T, with A-B switch in A position: + + /sbin/setserial /dev/ttyS0 none + /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \ + snd_adaptor=1 snd_speed=19200 + +In MS-124W S/A mode, one raw MIDI substream is supported (midiCnD0); +the snd_outs module parameter is automatically set to 1. The driver sends +the same data to all four MIDI Out connectors at full MIDI speed. + +Usage example for S/A mode: + + /sbin/setserial /dev/ttyS0 none + /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \ + snd_adaptor=2 + +In MS-124W M/B mode, the driver supports 16 ALSA raw MIDI substreams; +the snd_outs module parameter is automatically set to 16. The substream +number gives a bitmask of which MIDI Out connectors the data should be +sent to, with midiCnD1 sending to Out 1, midiCnD2 to Out 2, midiCnD4 to +Out 3, and midiCnD8 to Out 4. Thus midiCnD15 sends the data to all 4 ports. +As a special case, midiCnD0 also sends to all ports, since it is not useful +to send the data to no ports. M/B mode has extra overhead to select the MIDI +Out for each byte, so the aggregate data rate across all four MIDI Outs is +at most one byte every 520 us, as compared with the full MIDI data rate of +one byte every 320 us per port. + +Usage example for M/B mode: + + /sbin/setserial /dev/ttyS0 none + /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \ + snd_adaptor=3 + +The MS-124W hardware's M/A mode is currently not supported. This mode allows +the MIDI Outs to act independently at double the aggregate throughput of M/B, +but does not allow sending the same byte simultaneously to multiple MIDI Outs. +The M/A protocol requires the driver to twiddle the modem control lines under +timing constraints, so it would be a bit more complicated to implement than +the other modes. + +Midiator models other than MS-124W and MS-124T are currently not supported. +Note that the suffix letter is significant; the MS-124 and MS-124B are not +compatible, nor are the other known models MS-101, MS-101B, MS-103, and MS-114. +I do have documentation (tim.mann@compaq.com) that partially covers these models, +but no units to experiment with. The MS-124W support is tested with a real unit. +The MS-124T support is untested, but should work. diff --git a/include/sound/asoundef.h b/include/sound/asoundef.h index d52f2416b709..e8b894586387 100644 --- a/include/sound/asoundef.h +++ b/include/sound/asoundef.h @@ -155,7 +155,7 @@ #define MIDI_CTL_MSB_MODWHEEL 0x01 #define MIDI_CTL_MSB_BREATH 0x02 #define MIDI_CTL_MSB_FOOT 0x04 -#define MIDI_CTL_MSB_PORTNAMENTO_TIME 0x05 +#define MIDI_CTL_MSB_PORTAMENTO_TIME 0x05 #define MIDI_CTL_MSB_DATA_ENTRY 0x06 #define MIDI_CTL_MSB_MAIN_VOLUME 0x07 #define MIDI_CTL_MSB_BALANCE 0x08 @@ -171,7 +171,7 @@ #define MIDI_CTL_LSB_MODWHEEL 0x21 #define MIDI_CTL_LSB_BREATH 0x22 #define MIDI_CTL_LSB_FOOT 0x24 -#define MIDI_CTL_LSB_PORTNAMENTO_TIME 0x25 +#define MIDI_CTL_LSB_PORTAMENTO_TIME 0x25 #define MIDI_CTL_LSB_DATA_ENTRY 0x26 #define MIDI_CTL_LSB_MAIN_VOLUME 0x27 #define MIDI_CTL_LSB_BALANCE 0x28 @@ -203,7 +203,7 @@ #define MIDI_CTL_GENERAL_PURPOSE6 0x51 #define MIDI_CTL_GENERAL_PURPOSE7 0x52 #define MIDI_CTL_GENERAL_PURPOSE8 0x53 -#define MIDI_CTL_PORNAMENTO_CONTROL 0x54 +#define MIDI_CTL_PORTAMENTO_CONTROL 0x54 #define MIDI_CTL_E1_REVERB_DEPTH 0x5b #define MIDI_CTL_E2_TREMOLO_DEPTH 0x5c #define MIDI_CTL_E3_CHORUS_DEPTH 0x5d diff --git a/include/sound/cs46xx.h b/include/sound/cs46xx.h index f900efa6b8c4..08f62c25df32 100644 --- a/include/sound/cs46xx.h +++ b/include/sound/cs46xx.h @@ -1697,6 +1697,9 @@ struct _snd_cs46xx { struct pci_dev *acpi_dev; int acpi_port; snd_kcontrol_t *eapd_switch; /* for amplifier hack */ + int accept_valid; /* accept mmap valid (for OSS) */ + + struct snd_cs46xx_gameport *gameport; #ifdef CONFIG_PM struct pm_dev *pm_dev; @@ -1711,6 +1714,7 @@ int snd_cs46xx_create(snd_card_t *card, int snd_cs46xx_pcm(cs46xx_t *chip, int device, snd_pcm_t **rpcm); int snd_cs46xx_mixer(cs46xx_t *chip); int snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rmidi); +void snd_cs46xx_gameport(cs46xx_t *chip); #ifdef CONFIG_PM void snd_cs46xx_suspend(cs46xx_t *chip); diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 3f03bec0cf41..96a3185ccba0 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -687,6 +687,12 @@ #define A_MUCMD2 0x73 #define A_MUSTAT2 A_MUCMD2 +/* The next two are the Audigy equivalent of FXWC */ +/* the Audigy can record any output (16bit, 48kHz, up to 64 channel simultaneously) */ +/* Each bit selects a channel for recording */ +#define A_FXWC1 0x74 /* Selects 0x7f-0x60 for FX recording */ +#define A_FXWC2 0x75 /* Selects 0x9f-0x80 for FX recording */ + #define A_SPDIF_SAMPLERATE 0x76 /* Set the sample rate of SPDIF output */ #define A_SPDIF_48000 0x00000080 #define A_SPDIF_44100 0x00000000 @@ -797,6 +803,7 @@ struct _snd_emu10k1_pcm { unsigned int capture_bs_reg; /* buffer size register */ unsigned int capture_idx_reg; /* buffer index register */ unsigned int capture_cr_val; /* control value */ + unsigned int capture_cr_val2; /* control value2 (for audigy) */ unsigned int capture_bs_val; /* buffer size value */ unsigned int capture_bufsize; /* buffer size in bytes */ }; @@ -982,7 +989,7 @@ struct _snd_emu10k1 { emu10k1_midi_t midi; emu10k1_midi_t midi2; /* for audigy */ - unsigned int efx_voices_mask; + unsigned int efx_voices_mask[2]; snd_info_entry_t *proc_entry; snd_info_entry_t *proc_entry_fx8010_gpr; @@ -1209,8 +1216,8 @@ int snd_emu10k1_proc_done(emu10k1_t * emu); #define A_EXTOUT_AREAR_R 0x0f /* right */ #define A_EXTOUT_AC97_L 0x10 /* AC97 left (front) */ #define A_EXTOUT_AC97_R 0x11 /* right */ -#define A_EXTOUT_ADC_CAP_L 0x12 /* ADC capture buffer left */ -#define A_EXTOUT_ADC_CAP_R 0x13 /* right */ +#define A_EXTOUT_ADC_CAP_L 0x16 /* ADC capture buffer left */ +#define A_EXTOUT_ADC_CAP_R 0x17 /* right */ /* Audigy constants */ #define A_C_00000000 0xc0 diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h index 34bbf0c21801..1cb793e55594 100644 --- a/include/sound/rawmidi.h +++ b/include/sound/rawmidi.h @@ -158,7 +158,7 @@ int snd_rawmidi_control_ioctl(snd_card_t * card, /* callbacks */ void snd_rawmidi_receive_reset(snd_rawmidi_substream_t * substream); -int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count); +int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, const unsigned char *buffer, int count); void snd_rawmidi_transmit_reset(snd_rawmidi_substream_t * substream); int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream); int snd_rawmidi_transmit_peek(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count); diff --git a/include/sound/sndmagic.h b/include/sound/sndmagic.h index 760651da578f..c2398e775e07 100644 --- a/include/sound/sndmagic.h +++ b/include/sound/sndmagic.h @@ -131,6 +131,7 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic) #define mtpav_port_t_magic 0xa15a3702 #define korg1212_t_magic 0xa15a3800 #define opl3sa2_t_magic 0xa15a3900 +#define serialmidi_t_magic 0xa15a3a00 #else diff --git a/include/sound/trident.h b/include/sound/trident.h index 1d8b1c3d7931..56bf20a14a03 100644 --- a/include/sound/trident.h +++ b/include/sound/trident.h @@ -161,6 +161,12 @@ enum miscint_bits { #define NX_SPESO 0x2c #define NX_SPCSTATUS 0x64 +/* Joystick */ +#define GAMEPORT_GCR 0x30 +#define GAMEPORT_MODE_ADC 0x80 +#define GAMEPORT_LEGACY 0x31 +#define GAMEPORT_AXES 0x34 + /* NX Specific Registers */ #define NX_TLBC 0x6c @@ -437,6 +443,8 @@ struct _snd_trident { spinlock_t reg_lock; snd_info_entry_t *proc_entry; + + struct snd_trident_gameport *gameport; }; int snd_trident_create(snd_card_t * card, @@ -446,6 +454,7 @@ int snd_trident_create(snd_card_t * card, int max_wavetable_size, trident_t ** rtrident); int snd_trident_free(trident_t *trident); +void snd_trident_gameport(trident_t *trident); int snd_trident_pcm(trident_t * trident, int device, snd_pcm_t **rpcm); int snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t **rpcm); diff --git a/include/sound/version.h b/include/sound/version.h index 21ced3f5bc47..f3f1456b8567 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h. Generated automatically by configure. */ #define CONFIG_SND_VERSION "0.9.0beta12" -#define CONFIG_SND_DATE " (Wed Mar 06 07:56:20 2002 UTC)" +#define CONFIG_SND_DATE " (Mon Mar 18 15:44:40 2002 UTC)" diff --git a/sound/core/Config.in b/sound/core/Config.in index 38c93ed8bb1c..369789768f12 100644 --- a/sound/core/Config.in +++ b/sound/core/Config.in @@ -1,13 +1,13 @@ # ALSA soundcard-configuration if [ "$CONFIG_X86_64" = "y" -a "$CONFIG_IA32_EMULATION" = "y" ]; then - dep_tristate ' Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL + dep_tristate ' Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL $CONFIG_SND fi if [ "$CONFIG_PPC64" = "y" ]; then - dep_tristate ' Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL + dep_tristate ' Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL $CONFIG_SND fi if [ "$CONFIG_SPARC64" = "y" ]; then - dep_tristate ' Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL + dep_tristate ' Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL $CONFIG_SND fi dep_tristate ' Sequencer support' CONFIG_SND_SEQUENCER $CONFIG_SND if [ "$CONFIG_SND_SEQUENCER" != "n" ]; then diff --git a/sound/core/Makefile b/sound/core/Makefile index 83f5d792b5e7..8835af24216c 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile @@ -37,6 +37,8 @@ ifeq ($(filter $(subdir-y),oss),oss) obj-y += oss/oss.o endif +obj-$(CONFIG_SND_PCM_OSS) += snd-pcm.o + subdir-$(CONFIG_SND_SEQUENCER) += seq ifeq ($(CONFIG_SND_SEQUENCER),y) subdir-m += seq @@ -53,6 +55,7 @@ endif # Toplevel Module Dependency obj-$(CONFIG_SND_DUMMY) += snd-pcm.o snd-timer.o snd.o obj-$(CONFIG_SND_VIRMIDI) += snd-rawmidi.o snd.o snd-timer.o +obj-$(CONFIG_SND_SERIAL_U16550) += snd-rawmidi.o snd.o snd-timer.o obj-$(CONFIG_SND_MTPAV) += snd-rawmidi.o snd.o snd-timer.o obj-$(CONFIG_SND_MPU401) += snd-rawmidi.o snd.o snd-timer.o obj-$(CONFIG_SND_ALS100) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o diff --git a/sound/core/ioctl32/Makefile b/sound/core/ioctl32/Makefile index ddd94bfd3dfd..33377a3c4d10 100644 --- a/sound/core/ioctl32/Makefile +++ b/sound/core/ioctl32/Makefile @@ -8,6 +8,9 @@ O_TARGET := _ioctl32.o list-multi := snd-ioctl32.o snd-ioctl32-objs := ioctl32.o pcm32.o rawmidi32.o timer32.o hwdep32.o +ifeq ($(CONFIG_SND_SEQUENCER),y) + snd-ioctl32-objs += seq32.o +endif obj-$(CONFIG_SND_BIT32_EMUL) += snd-ioctl32.o diff --git a/sound/core/ioctl32/hwdep32.c b/sound/core/ioctl32/hwdep32.c index 5d0eb0cc3ee0..a136640ef4c0 100644 --- a/sound/core/ioctl32/hwdep32.c +++ b/sound/core/ioctl32/hwdep32.c @@ -1,5 +1,5 @@ /* - * 32bit -> 64bit ioctl wrapper for timer API + * 32bit -> 64bit ioctl wrapper for hwdep API * Copyright (c) by Takashi Iwai <tiwai@suse.de> * * This program is free software; you can redistribute it and/or modify @@ -26,8 +26,6 @@ #include <asm/uaccess.h> #include "ioctl32.h" -#define AP(x) snd_ioctl32_##x - struct ioctl32_mapper hwdep_mappers[] = { { SNDRV_HWDEP_IOCTL_PVERSION, NULL }, { SNDRV_HWDEP_IOCTL_INFO, NULL }, diff --git a/sound/core/ioctl32/ioctl32.c b/sound/core/ioctl32/ioctl32.c index cb22362f40b9..a2adb2f8c59b 100644 --- a/sound/core/ioctl32/ioctl32.c +++ b/sound/core/ioctl32/ioctl32.c @@ -286,14 +286,21 @@ static int snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigne #define AP(x) snd_ioctl32_##x +enum { + SNDRV_CTL_IOCTL_ELEM_LIST32 = _IOWR('U', 0x10, struct sndrv_ctl_elem_list32), + SNDRV_CTL_IOCTL_ELEM_INFO32 = _IOWR('U', 0x11, struct sndrv_ctl_elem_info32), + SNDRV_CTL_IOCTL_ELEM_READ32 = _IOWR('U', 0x12, struct sndrv_ctl_elem_value32), + SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct sndrv_ctl_elem_value32), +}; + static struct ioctl32_mapper control_mappers[] = { /* controls (without rawmidi, hwdep, timer releated ones) */ { SNDRV_CTL_IOCTL_PVERSION, NULL }, { SNDRV_CTL_IOCTL_CARD_INFO , NULL }, - { SNDRV_CTL_IOCTL_ELEM_LIST, AP(ctl_elem_list) }, - { SNDRV_CTL_IOCTL_ELEM_INFO, AP(ctl_elem_info) }, - { SNDRV_CTL_IOCTL_ELEM_READ, AP(ctl_elem_value) }, - { SNDRV_CTL_IOCTL_ELEM_WRITE, AP(ctl_elem_value) }, + { SNDRV_CTL_IOCTL_ELEM_LIST32, AP(ctl_elem_list) }, + { SNDRV_CTL_IOCTL_ELEM_INFO32, AP(ctl_elem_info) }, + { SNDRV_CTL_IOCTL_ELEM_READ32, AP(ctl_elem_value) }, + { SNDRV_CTL_IOCTL_ELEM_WRITE32, AP(ctl_elem_value) }, { SNDRV_CTL_IOCTL_ELEM_LOCK, NULL }, { SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL }, { SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL }, @@ -314,9 +321,15 @@ extern struct ioctl32_mapper pcm_mappers[]; extern struct ioctl32_mapper rawmidi_mappers[]; extern struct ioctl32_mapper timer_mappers[]; extern struct ioctl32_mapper hwdep_mappers[]; +#ifdef CONFIG_SND_SEQUENCER +extern struct ioctl32_mapper seq_mappers[]; +#endif static void snd_ioctl32_done(void) { +#ifdef CONFIG_SND_SEQUENCER + snd_ioctl32_unregister(seq_mappers); +#endif snd_ioctl32_unregister(hwdep_mappers); snd_ioctl32_unregister(timer_mappers); snd_ioctl32_unregister(rawmidi_mappers); @@ -351,6 +364,13 @@ static int __init snd_ioctl32_init(void) snd_ioctl32_done(); return err; } +#ifdef CONFIG_SND_SEQUENCER + err = snd_ioctl32_register(seq_mappers); + if (err < 0) { + snd_ioctl32_done(); + return err; + } +#endif } module_init(snd_ioctl32_init) diff --git a/sound/core/ioctl32/pcm32.c b/sound/core/ioctl32/pcm32.c index 3aa994c7bc74..e15dc2ac60ac 100644 --- a/sound/core/ioctl32/pcm32.c +++ b/sound/core/ioctl32/pcm32.c @@ -262,29 +262,43 @@ static int snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long ar #define AP(x) snd_ioctl32_##x +enum { + SNDRV_PCM_IOCTL_HW_REFINE32 = _IOWR('A', 0x10, struct sndrv_pcm_hw_params32), + SNDRV_PCM_IOCTL_HW_PARAMS32 = _IOWR('A', 0x11, struct sndrv_pcm_hw_params32), + SNDRV_PCM_IOCTL_SW_PARAMS32 = _IOWR('A', 0x13, struct sndrv_pcm_sw_params32), + SNDRV_PCM_IOCTL_STATUS32 = _IOR('A', 0x20, struct sndrv_pcm_status32), + SNDRV_PCM_IOCTL_DELAY32 = _IOR('A', 0x21, s32), + SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct sndrv_pcm_channel_info32), + SNDRV_PCM_IOCTL_REWIND32 = _IOW('A', 0x46, u32), + SNDRV_PCM_IOCTL_WRITEI_FRAMES32 = _IOW('A', 0x50, struct sndrv_xferi32), + SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct sndrv_xferi32), + SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct sndrv_xfern32), + SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct sndrv_xfern32), +}; + struct ioctl32_mapper pcm_mappers[] = { { SNDRV_PCM_IOCTL_PVERSION, NULL }, { SNDRV_PCM_IOCTL_INFO, NULL }, - { SNDRV_PCM_IOCTL_HW_REFINE, AP(pcm_hw_params) }, - { SNDRV_PCM_IOCTL_HW_PARAMS, AP(pcm_hw_params) }, + { SNDRV_PCM_IOCTL_HW_REFINE32, AP(pcm_hw_params) }, + { SNDRV_PCM_IOCTL_HW_PARAMS32, AP(pcm_hw_params) }, { SNDRV_PCM_IOCTL_HW_FREE, NULL }, - { SNDRV_PCM_IOCTL_SW_PARAMS, AP(pcm_sw_params) }, - { SNDRV_PCM_IOCTL_STATUS, AP(pcm_status) }, - { SNDRV_PCM_IOCTL_DELAY, AP(pcm_sframes_str) }, - { SNDRV_PCM_IOCTL_CHANNEL_INFO, AP(pcm_channel_info) }, + { SNDRV_PCM_IOCTL_SW_PARAMS32, AP(pcm_sw_params) }, + { SNDRV_PCM_IOCTL_STATUS32, AP(pcm_status) }, + { SNDRV_PCM_IOCTL_DELAY32, AP(pcm_sframes_str) }, + { SNDRV_PCM_IOCTL_CHANNEL_INFO32, AP(pcm_channel_info) }, { SNDRV_PCM_IOCTL_PREPARE, NULL }, { SNDRV_PCM_IOCTL_RESET, NULL }, { SNDRV_PCM_IOCTL_START, NULL }, { SNDRV_PCM_IOCTL_DROP, NULL }, { SNDRV_PCM_IOCTL_DRAIN, NULL }, { SNDRV_PCM_IOCTL_PAUSE, NULL }, - { SNDRV_PCM_IOCTL_REWIND, AP(pcm_uframes_str) }, + { SNDRV_PCM_IOCTL_REWIND32, AP(pcm_uframes_str) }, { SNDRV_PCM_IOCTL_RESUME, NULL }, { SNDRV_PCM_IOCTL_XRUN, NULL }, - { SNDRV_PCM_IOCTL_WRITEI_FRAMES, AP(xferi) }, - { SNDRV_PCM_IOCTL_READI_FRAMES, AP(xferi) }, - { SNDRV_PCM_IOCTL_WRITEN_FRAMES, AP(xfern) }, - { SNDRV_PCM_IOCTL_READN_FRAMES, AP(xfern) }, + { SNDRV_PCM_IOCTL_WRITEI_FRAMES32, AP(xferi) }, + { SNDRV_PCM_IOCTL_READI_FRAMES32, AP(xferi) }, + { SNDRV_PCM_IOCTL_WRITEN_FRAMES32, AP(xfern) }, + { SNDRV_PCM_IOCTL_READN_FRAMES32, AP(xfern) }, { SNDRV_PCM_IOCTL_LINK, NULL }, { SNDRV_PCM_IOCTL_UNLINK, NULL }, diff --git a/sound/core/ioctl32/rawmidi32.c b/sound/core/ioctl32/rawmidi32.c index d5e89ffd9f98..d8ed82222a3b 100644 --- a/sound/core/ioctl32/rawmidi32.c +++ b/sound/core/ioctl32/rawmidi32.c @@ -70,11 +70,16 @@ DEFINE_ALSA_IOCTL(rawmidi_status); #define AP(x) snd_ioctl32_##x +enum { + SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct sndrv_rawmidi_params32), + SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct sndrv_rawmidi_status32), +}; + struct ioctl32_mapper rawmidi_mappers[] = { { SNDRV_RAWMIDI_IOCTL_PVERSION, NULL }, { SNDRV_RAWMIDI_IOCTL_INFO, NULL }, - { SNDRV_RAWMIDI_IOCTL_PARAMS, AP(rawmidi_params) }, - { SNDRV_RAWMIDI_IOCTL_STATUS, AP(rawmidi_status) }, + { SNDRV_RAWMIDI_IOCTL_PARAMS32, AP(rawmidi_params) }, + { SNDRV_RAWMIDI_IOCTL_STATUS32, AP(rawmidi_status) }, { SNDRV_RAWMIDI_IOCTL_DROP, NULL }, { SNDRV_RAWMIDI_IOCTL_DRAIN, NULL }, diff --git a/sound/core/ioctl32/seq32.c b/sound/core/ioctl32/seq32.c new file mode 100644 index 000000000000..d8ce91c477e7 --- /dev/null +++ b/sound/core/ioctl32/seq32.c @@ -0,0 +1,64 @@ +/* + * 32bit -> 64bit ioctl wrapper for sequencer API + * Copyright (c) by Takashi Iwai <tiwai@suse.de> + * + * 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 + * + */ + +#define __NO_VERSION__ +#include <sound/driver.h> +#include <linux/time.h> +#include <sound/core.h> +#include <sound/timer.h> +#include <asm/uaccess.h> +#include <sound/asequencer.h> +#include "ioctl32.h" + +struct ioctl32_mapper seq_mappers[] = { + { SNDRV_SEQ_IOCTL_PVERSION, NULL }, + { SNDRV_SEQ_IOCTL_CLIENT_ID, NULL }, + { SNDRV_SEQ_IOCTL_SYSTEM_INFO, NULL }, + { SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, NULL }, + { SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, NULL }, + { SNDRV_SEQ_IOCTL_CREATE_PORT, NULL }, + { SNDRV_SEQ_IOCTL_DELETE_PORT, NULL }, + { SNDRV_SEQ_IOCTL_GET_PORT_INFO, NULL }, + { SNDRV_SEQ_IOCTL_SET_PORT_INFO, NULL }, + { SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, NULL }, + { SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, NULL }, + { SNDRV_SEQ_IOCTL_CREATE_QUEUE, NULL }, + { SNDRV_SEQ_IOCTL_DELETE_QUEUE, NULL }, + { SNDRV_SEQ_IOCTL_GET_QUEUE_INFO, NULL }, + { SNDRV_SEQ_IOCTL_SET_QUEUE_INFO, NULL }, + { SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE, NULL }, + { SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS, NULL }, + { SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO, NULL }, + { SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO, NULL }, + { SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER, NULL }, + { SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER, NULL }, + { SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER, NULL }, + { SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER, NULL }, + { SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT, NULL }, + { SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT, NULL }, + { SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, NULL }, + { SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, NULL }, + { SNDRV_SEQ_IOCTL_REMOVE_EVENTS, NULL }, + { SNDRV_SEQ_IOCTL_QUERY_SUBS, NULL }, + { SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION, NULL }, + { SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, NULL }, + { SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, NULL }, + { 0 }, +}; diff --git a/sound/core/ioctl32/timer32.c b/sound/core/ioctl32/timer32.c index 4e657f7a309f..40ee60843825 100644 --- a/sound/core/ioctl32/timer32.c +++ b/sound/core/ioctl32/timer32.c @@ -79,13 +79,18 @@ DEFINE_ALSA_IOCTL(timer_status); #define AP(x) snd_ioctl32_##x +enum { + SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct sndrv_timer_info32), + SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct sndrv_timer_status32), +}; + struct ioctl32_mapper timer_mappers[] = { { SNDRV_TIMER_IOCTL_PVERSION, NULL }, { SNDRV_TIMER_IOCTL_NEXT_DEVICE, NULL }, { SNDRV_TIMER_IOCTL_SELECT, NULL }, - { SNDRV_TIMER_IOCTL_INFO, AP(timer_info) }, + { SNDRV_TIMER_IOCTL_INFO32, AP(timer_info) }, { SNDRV_TIMER_IOCTL_PARAMS, NULL }, - { SNDRV_TIMER_IOCTL_STATUS, AP(timer_status) }, + { SNDRV_TIMER_IOCTL_STATUS32, AP(timer_status) }, { SNDRV_TIMER_IOCTL_START, NULL }, { SNDRV_TIMER_IOCTL_STOP, NULL }, { SNDRV_TIMER_IOCTL_CONTINUE, NULL }, diff --git a/sound/core/misc.c b/sound/core/misc.c index 2e393982fdd9..b64656fe73c3 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c @@ -41,7 +41,7 @@ int snd_task_name(struct task_struct *task, char *name, size_t size) int snd_verbose_printk(const char *file, int line, const char *format) { if (format[0] == '<' && format[1] >= '0' && format[1] <= '9' && format[2] == '>') { - char tmp[] = "<0>ALSA %s:%d: "; + char tmp[] = "<0>"; tmp[1] = format[1]; printk("%sALSA %s:%d: ", tmp, file, line); return 1; diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 03cc8bce04b2..8b58b0e74fce 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -39,7 +39,7 @@ static int snd_dsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; static int snd_adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; -static int snd_nonblock_open = 0; +static int snd_nonblock_open; MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Abramo Bagnara <abramo@alsa-project.org>"); MODULE_DESCRIPTION("PCM OSS emulation for ALSA."); @@ -1650,7 +1650,8 @@ static int snd_pcm_oss_ioctl(struct inode *inode, struct file *file, pcm_oss_file = snd_magic_cast(snd_pcm_oss_file_t, file->private_data, return -ENXIO); if (cmd == OSS_GETVERSION) return put_user(SNDRV_OSS_VERSION, (int *)arg) ? -EFAULT : 0; - if (((cmd >> 8) & 0xff) == 'M') { /* mixer ioctl - for OSS (grrr) compatibility */ +#if defined(CONFIG_SND_MIXER_OSS) || (defined(MODULE) && defined(CONFIG_SND_MIXER_OSS_MODULE)) + if (((cmd >> 8) & 0xff) == 'M') { /* mixer ioctl - for OSS compatibility */ snd_pcm_substream_t *substream; int idx; for (idx = 0; idx < 2; ++idx) { @@ -1661,6 +1662,7 @@ static int snd_pcm_oss_ioctl(struct inode *inode, struct file *file, snd_assert(substream != NULL, return -ENXIO); return snd_mixer_oss_ioctl_card(substream->pcm->card, cmd, arg); } +#endif if (((cmd >> 8) & 0xff) != 'P') return -EINVAL; switch (cmd) { diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 88381f81154b..68018ea0c7c6 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -32,7 +32,7 @@ #include <sound/pcm_params.h> #include <sound/minors.h> -spinlock_t pcm_link_lock = SPIN_LOCK_UNLOCKED; +static rwlock_t pcm_link_lock = RW_LOCK_UNLOCKED; static inline mm_segment_t snd_enter_user(void) { @@ -569,7 +569,7 @@ static void snd_pcm_trigger_time(snd_pcm_substream_t *substream) #define _SND_PCM_ACTION(aname, substream, state, res, check_master) { \ snd_pcm_substream_t *s; \ res = 0; \ - spin_lock(&pcm_link_lock); \ + read_lock(&pcm_link_lock); \ s = substream; \ do { \ if (s != substream) \ @@ -606,7 +606,7 @@ static void snd_pcm_trigger_time(snd_pcm_substream_t *substream) s = s->link_next; \ } while (s != substream); \ _end: \ - spin_unlock(&pcm_link_lock); \ + read_unlock(&pcm_link_lock); \ } #define SND_PCM_ACTION(aname, substream, state) { \ @@ -965,7 +965,7 @@ int snd_pcm_prepare(snd_pcm_substream_t *substream) static void snd_pcm_change_state(snd_pcm_substream_t *substream, int state) { snd_pcm_substream_t *s; - spin_lock(&pcm_link_lock); + read_lock(&pcm_link_lock); s = substream->link_next; while (s != substream) { spin_lock(&s->runtime->lock); @@ -979,7 +979,7 @@ static void snd_pcm_change_state(snd_pcm_substream_t *substream, int state) spin_unlock(&runtime->lock); s = s->link_next; } while (s != substream); - spin_unlock(&pcm_link_lock); + read_unlock(&pcm_link_lock); } static int snd_pcm_playback_drop(snd_pcm_substream_t *substream); @@ -1277,7 +1277,7 @@ static int snd_pcm_link(snd_pcm_substream_t *substream, int fd) return -EBADFD; pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, return -ENXIO); substream1 = pcm_file->substream; - spin_lock_irq(&pcm_link_lock); + write_lock_irq(&pcm_link_lock); if (substream->runtime->status->state != substream1->runtime->status->state) { res = -EBADFD; goto _end; @@ -1295,19 +1295,19 @@ static int snd_pcm_link(snd_pcm_substream_t *substream, int fd) substream->link_next = substream1; substream1->link_prev = substream; _end: - spin_unlock_irq(&pcm_link_lock); + write_unlock_irq(&pcm_link_lock); fput(file); return res; } static int snd_pcm_unlink(snd_pcm_substream_t *substream) { - spin_lock_irq(&pcm_link_lock); + write_lock_irq(&pcm_link_lock); substream->link_prev->link_next = substream->link_next; substream->link_next->link_prev = substream->link_prev; substream->link_prev = substream; substream->link_next = substream; - spin_unlock_irq(&pcm_link_lock); + write_unlock_irq(&pcm_link_lock); return 0; } diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 9c6a7c0a979f..96be7fd0a615 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -143,6 +143,7 @@ int snd_rawmidi_drain_output(snd_rawmidi_substream_t * substream) break; } if (runtime->avail < runtime->buffer_size && !timeout) { + snd_printk(KERN_WARNING "rawmidi drain error (avail = %li, buffer_size = %li)\n", runtime->avail, runtime->buffer_size); err = -EIO; break; } @@ -335,10 +336,14 @@ int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice, return 0; __error: - if (input != NULL) + if (input != NULL) { + snd_rawmidi_done_buffer(input); kfree(input); - if (output != NULL) + } + if (output != NULL) { + snd_rawmidi_done_buffer(output); kfree(output); + } dec_mod_count(rmidi->card->module); up(&rmidi->open_mutex); __error1: @@ -820,7 +825,7 @@ void snd_rawmidi_receive_reset(snd_rawmidi_substream_t * substream) /* TODO: reset current state */ } -int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count) +int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, const unsigned char *buffer, int count) { unsigned long flags; int result = 0, count1; @@ -1100,8 +1105,10 @@ static long snd_rawmidi_kernel_write1(snd_rawmidi_substream_t * substream, const __end: if (result > 0) runtime->trigger = 1; + count1 = runtime->avail < runtime->buffer_size; spin_unlock_irqrestore(&runtime->lock, flags); - substream->ops->trigger(substream, 1); + if (count1) + substream->ops->trigger(substream, 1); return result; } diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c index b4610de3d099..68e4f7cb6587 100644 --- a/sound/core/rtctimer.c +++ b/sound/core/rtctimer.c @@ -76,7 +76,9 @@ static struct tasklet_struct rtc_tq; static int rtctimer_open(snd_timer_t *t) { - int err = rtc_register(&rtc_task); + int err; + + err = rtc_register(&rtc_task); if (err < 0) return err; t->private_data = &rtc_task; diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile index 569cd0ae110f..07481aa792c6 100644 --- a/sound/core/seq/Makefile +++ b/sound/core/seq/Makefile @@ -23,8 +23,7 @@ export-objs := seq_device.o seq.o seq_ports.o seq_instr.o seq_midi_emul.o \ snd-seq-device-objs := seq_device.o snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \ seq_fifo.o seq_prioq.o seq_timer.o \ - seq_system.o seq_ports.o seq_info.o seq_sync.o \ - seq_midi_clock.o seq_mtc.o seq_dtl.o + seq_system.o seq_ports.o seq_info.o snd-seq-midi-objs := seq_midi.o snd-seq-midi-emul-objs := seq_midi_emul.o snd-seq-midi-event-objs := seq_midi_event.o @@ -38,6 +37,7 @@ obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o # Toplevel Module Dependency obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o +obj-$(CONFIG_SND_SERIAL_U16550) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o obj-$(CONFIG_SND_MTPAV) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o obj-$(CONFIG_SND_MPU401) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o obj-$(CONFIG_SND_ALS100) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index 0026ff223678..7070a4093c81 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c @@ -40,7 +40,7 @@ static int system_client = -1; /* ALSA sequencer client number */ static int system_port = -1; int maxqlen = SNDRV_SEQ_OSS_MAX_QLEN; -static int num_clients = 0; +static int num_clients; static seq_oss_devinfo_t *client_table[SNDRV_SEQ_OSS_MAX_CLIENTS]; diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index fe3bfff2a868..274909b3cf49 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c @@ -54,7 +54,7 @@ struct seq_oss_midi_t { /* * midi device table */ -static int max_midi_devs = 0; +static int max_midi_devs; static seq_oss_midi_t *midi_devs[SNDRV_SEQ_OSS_MAX_MIDI_DEVS]; static spinlock_t register_lock = SPIN_LOCK_UNLOCKED; diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index 26a6924aaee3..d07708363a4c 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -66,7 +66,7 @@ struct seq_oss_synth_t { /* * device table */ -static int max_synth_devs = 0; +static int max_synth_devs; static seq_oss_synth_t *synth_devs[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS]; static seq_oss_synth_t midi_synth_dev = { -1, /* seq_device */ diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 1798f2a6ec0c..31b384d14118 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -82,7 +82,7 @@ struct ops_list { static LIST_HEAD(opslist); -static int num_ops = 0; +static int num_ops; static DECLARE_MUTEX(ops_mutex); static snd_info_entry_t *info_entry = NULL; diff --git a/sound/core/seq/seq_dtl.c b/sound/core/seq/seq_dtl.c deleted file mode 100644 index c41c97835674..000000000000 --- a/sound/core/seq/seq_dtl.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * DTL(e) event converter - * - * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de> - * - * 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 - * - */ - -#define __NO_VERSION__ -#include <sound/driver.h> -#include <sound/core.h> -#include "seq_queue.h" - -#ifdef SNDRV_SEQ_SYNC_SUPPORT - -typedef struct dtl_out { - int out_mtp_network; - unsigned int time_format; - unsigned int full_frame_count; - unsigned char sysex[11]; -} dtl_out_t; - -typedef struct dtl_in { - unsigned int time_format; - unsigned int cur_pos; -} dtl_in_t; - - -static int dtl_open_out(queue_sync_t *sync_info, seq_sync_arg_t *retp) -{ - dtl_out_t *arg; - - if (sync_info->time_format >= 4) - return -EINVAL; - if ((arg = kmalloc(sizeof(*arg), GFP_KERNEL)) == NULL) - return -ENOMEM; - arg->out_mtp_network = sync_info->opt_info[0]; - arg->full_frame_count = sync_info->opt_info[1]; - arg->time_format = sync_info->time_format; - sync_info->param.time.subframes = 1; /* MTC uses quarter frame */ - sync_info->param.time.resolution = snd_seq_get_smpte_resolution(arg->time_format); - *retp = arg; - return 0; -} - -static int dtl_open_in(queue_sync_t *sync_info, seq_sync_arg_t *retp) -{ - dtl_in_t *arg; - - if (sync_info->time_format >= 4) - return -EINVAL; - if ((arg = kmalloc(sizeof(*arg), GFP_KERNEL)) == NULL) - return -ENOMEM; - arg->time_format = sync_info->time_format; - arg->cur_pos = 0; - sync_info->param.time.subframes = 1; /* MTC uses quarter frame */ - sync_info->param.time.resolution = snd_seq_get_smpte_resolution(arg->time_format); - *retp = arg; - return 0; -} - - -/* decode sync position */ -static int sync_pos_out(dtl_out_t *arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - sndrv_seq_time_frame_t cur_out; - unsigned char *buf = arg->sysex; - - if (arg->time_format != src->data.queue.sync_time_format) - return -EINVAL; - - cur_out = snd_seq_position_to_time_frame(arg->time_format, 1, src->data.queue.param.position); - buf[0] = 0xf0; /* SYSEX */ - buf[1] = 0x00; /* MOTU */ - buf[2] = 0x33; /* MOTU */ - buf[3] = 0x7f; - buf[4] = 0x0c; /* DTL full frame */ - buf[5] = arg->out_mtp_network; /* 0x00 or 0x08 */ - buf[6] = cur_out.hour | (arg->time_format << 5); - buf[7] = cur_out.min; - buf[8] = cur_out.sec; - buf[9] = cur_out.frame; - buf[10] = 0xf7; - - ev->type = SNDRV_SEQ_EVENT_SYSEX; - ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK; - ev->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE; - ev->data.ext.len = 11; - ev->data.ext.ptr = buf; - - return 1; -} - -/* decode sync signal */ -static int sync_out(dtl_out_t *arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - unsigned int pos; - - if (arg->time_format != src->data.queue.sync_time_format) - return -EINVAL; - pos = src->data.queue.param.position; - if (arg->full_frame_count && - (pos % arg->full_frame_count) == 0) - /* send full frame */ - return sync_pos_out(arg, src, ev); - ev->type = SNDRV_SEQ_EVENT_CLOCK; - return 1; -} - -static int dtl_sync_out(seq_sync_arg_t _arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - dtl_out_t *arg = _arg; - switch (src->type) { - case SNDRV_SEQ_EVENT_SYNC: - return sync_out(arg, src, ev); - case SNDRV_SEQ_EVENT_SYNC_POS: - return sync_pos_out(arg, src, ev); - } - return 0; -} - -/* decode sync position */ -static int sync_pos_in(dtl_in_t *arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - unsigned time_format; - static unsigned char id[] = { - 0xf0, 0x00, 0x33, 0x7f, 0x0c, - }; - sndrv_seq_time_frame_t cur_in; - char buf[11]; - - if (snd_seq_expand_var_event(src, 11, buf, 1, 0) != 11) - return 0; - if (memcmp(buf, id, sizeof(id)) != 0) - return 0; - time_format = (buf[6] >> 5) & 3; - if (time_format != arg->time_format) - return -EINVAL; - cur_in.hour = buf[6] & 0x1f; - cur_in.min = buf[7]; - cur_in.sec = buf[8]; - cur_in.frame = buf[9]; - arg->cur_pos = snd_seq_time_frame_to_position(time_format, 1, &cur_in); - - ev->type = SNDRV_SEQ_EVENT_SYNC_POS; - ev->data.queue.sync_time_format = time_format; - ev->data.queue.param.position = arg->cur_pos; - - return 1; -} - -static int dtl_sync_in(seq_sync_arg_t _arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - dtl_in_t *arg = _arg; - switch (src->type) { - case SNDRV_SEQ_EVENT_CLOCK: - arg->cur_pos++; - ev->type = SNDRV_SEQ_EVENT_SYNC; - ev->data.queue.param.position = arg->cur_pos; - return 1; - case SNDRV_SEQ_EVENT_SYSEX: - return sync_pos_in(arg, src, ev); - } - return 0; -} - -/* exported */ -seq_sync_parser_t snd_seq_dtl_parser = { - format: SNDRV_SEQ_SYNC_FMT_DTL, - in: { - open: dtl_open_in, - sync: dtl_sync_in, - }, - out: { - open: dtl_open_out, - sync: dtl_sync_out, - }, -}; - -#endif /* SNDRV_SEQ_SYNC_SUPPORT */ diff --git a/sound/core/seq/seq_midi_clock.c b/sound/core/seq/seq_midi_clock.c deleted file mode 100644 index f27ad5a0bb04..000000000000 --- a/sound/core/seq/seq_midi_clock.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * MIDI clock event converter - * - * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de> - * - * 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 - * - */ - -#define __NO_VERSION__ -#include <sound/driver.h> -#include <sound/core.h> -#include "seq_queue.h" - -#ifdef SNDRV_SEQ_SYNC_SUPPORT - -typedef struct midi_clock { - unsigned int cur_pos; -} midi_clock_t; - -static int midi_open(queue_sync_t *sync_info, seq_sync_arg_t *retp) -{ - midi_clock_t *arg; - - if ((arg = kmalloc(sizeof(*arg), GFP_KERNEL)) == NULL) - return -ENOMEM; - sync_info->param.tick.ppq = 24; - sync_info->param.tick.ticks = 1; - arg->cur_pos = 0; - *retp = arg; - return 0; -} - -static int midi_sync_out(seq_sync_arg_t _arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - switch (src->type) { - case SNDRV_SEQ_EVENT_SYNC: - ev->type = SNDRV_SEQ_EVENT_CLOCK; - return 1; - case SNDRV_SEQ_EVENT_SYNC_POS: - ev->type = SNDRV_SEQ_EVENT_SONGPOS; - ev->data.control.value = src->data.queue.param.position / 6; - return 1; - } - return 0; -} - -static int midi_sync_in(seq_sync_arg_t _arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - midi_clock_t *arg = _arg; - switch (src->type) { - case SNDRV_SEQ_EVENT_CLOCK: - ev->type = SNDRV_SEQ_EVENT_SYNC; - ev->data.queue.param.position = arg->cur_pos; - arg->cur_pos++; - return 1; - case SNDRV_SEQ_EVENT_SONGPOS: - ev->type = SNDRV_SEQ_EVENT_SYNC_POS; - arg->cur_pos = src->data.control.value * 6; - ev->data.queue.param.position = arg->cur_pos; - return 1; - } - return 0; -} - -/* exported */ -seq_sync_parser_t snd_seq_midi_clock_parser = { - format: SNDRV_SEQ_SYNC_FMT_MIDI_CLOCK, - in: { - open: midi_open, - sync: midi_sync_in, - }, - out: { - open: midi_open, - sync: midi_sync_out, - }, -}; - -#endif /* SNDRV_SEQ_SYNC_SUPPORT */ diff --git a/sound/core/seq/seq_mtc.c b/sound/core/seq/seq_mtc.c deleted file mode 100644 index 25e1d609da6a..000000000000 --- a/sound/core/seq/seq_mtc.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * MTC event converter - * - * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de> - * - * 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 - * - */ - -#define __NO_VERSION__ -#include <sound/driver.h> -#include <sound/core.h> -#include "seq_queue.h" - -#ifdef SNDRV_SEQ_SYNC_SUPPORT - -typedef struct mtc_out { - int out_channel; - unsigned int time_format; - sndrv_seq_time_frame_t cur_time; - unsigned int decode_offset; - unsigned char sysex[10]; -} mtc_out_t; - -typedef struct mtc_in { - unsigned int time_format; - sndrv_seq_time_frame_t cur_time; - unsigned int cur_pos; - int prev_in_offset; -} mtc_in_t; - - -static int mtc_open_out(queue_sync_t *sync_info, seq_sync_arg_t *retp) -{ - mtc_out_t *arg; - - if (sync_info->time_format >= 4) - return -EINVAL; - if ((arg = kmalloc(sizeof(*arg), GFP_KERNEL)) == NULL) - return -ENOMEM; - arg->out_channel = sync_info->opt_info[0]; - if (arg->out_channel == 0) - arg->out_channel = 127; - arg->time_format = sync_info->time_format; - sync_info->param.time.subframes = 4; /* MTC uses quarter frame */ - sync_info->param.time.resolution = snd_seq_get_smpte_resolution(arg->time_format); - memset(&arg->cur_time, 0, sizeof(arg->cur_time)); - *retp = arg; - return 0; -} - -static int mtc_open_in(queue_sync_t *sync_info, seq_sync_arg_t *retp) -{ - mtc_in_t *arg; - - if (sync_info->time_format >= 4) - return -EINVAL; - if ((arg = kmalloc(sizeof(*arg), GFP_KERNEL)) == NULL) - return -ENOMEM; - arg->time_format = sync_info->time_format; - memset(&arg->cur_time, 0, sizeof(arg->cur_time)); - arg->cur_pos = 0; - arg->prev_in_offset = -1; - sync_info->param.time.subframes = 4; /* MTC uses quarter frame */ - sync_info->param.time.resolution = snd_seq_get_smpte_resolution(arg->time_format); - *retp = arg; - return 0; -} - - -/* decode sync signal */ -static int sync_out(mtc_out_t *arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - int val, offset; - - if (arg->time_format != src->data.queue.sync_time_format) - return -EINVAL; - offset = (src->data.queue.param.position + arg->decode_offset) % 8; - if (offset == 0) { - /* convert and remember the current time - for the following 7 MTC quarter frames */ - arg->cur_time = snd_seq_position_to_time_frame(arg->time_format, 4, src->data.queue.param.position); - } - switch (offset) { - case 0: val = arg->cur_time.frame & 0x0f; break; - case 1: val = (arg->cur_time.frame >> 4) & 0x0f; break; - case 2: val = arg->cur_time.sec & 0x0f; break; - case 3: val = (arg->cur_time.sec >> 4) & 0x0f; break; - case 4: val = arg->cur_time.min & 0x0f; break; - case 5: val = (arg->cur_time.min >> 4) & 0x0f; break; - case 6: val = arg->cur_time.hour & 0x0f; break; - case 7: - default: - val = ((arg->cur_time.hour >> 4) & 0x01) | (arg->time_format << 1); - break; - } - val |= (offset << 4); - ev->type = SNDRV_SEQ_EVENT_QFRAME; - ev->data.control.value = val; - return 1; -} - -/* decode sync position */ -static int sync_pos_out(mtc_out_t *arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - unsigned int pos; - unsigned char *buf = arg->sysex; - - if (arg->time_format != src->data.queue.sync_time_format) - return -EINVAL; - - pos = src->data.queue.param.position; /* quarter frames */ - arg->decode_offset = pos & 4; - pos /= 4; - arg->cur_time = snd_seq_position_to_time_frame(arg->time_format, 4, pos); - - buf[0] = 0xf0; /* SYSEX */ - buf[1] = 0x7f; - buf[2] = arg->out_channel; - buf[3] = 0x01; - buf[4] = 0x01; - buf[5] = arg->cur_time.hour | (arg->time_format << 5); - buf[6] = arg->cur_time.min; - buf[7] = arg->cur_time.sec; - buf[8] = arg->cur_time.frame; - buf[9] = 0xf7; - - ev->type = SNDRV_SEQ_EVENT_SYSEX; - ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK; - ev->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE; - ev->data.ext.len = 10; - ev->data.ext.ptr = buf; - - return 1; -} - -static int mtc_sync_out(seq_sync_arg_t _arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - mtc_out_t *arg = _arg; - switch (src->type) { - case SNDRV_SEQ_EVENT_SYNC: - return sync_out(arg, src, ev); - case SNDRV_SEQ_EVENT_SYNC_POS: - return sync_pos_out(arg, src, ev); - } - return 0; -} - -/* decode sync signal */ -static int sync_in(mtc_in_t *arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - int val, offset; - unsigned int time_format; - - offset = (src->data.control.value & 0x70) >> 4; - val = src->data.control.value & 0x0f; - if (offset > 0 && offset != arg->prev_in_offset + 1) { - /* bad quarter frame message - something missing.. */ - arg->prev_in_offset = -1; /* wait for next 0 */ - return -EINVAL; - } - switch (offset) { - case 0: arg->cur_time.frame = val; break; - case 1: arg->cur_time.frame |= (val << 4); break; - case 2: arg->cur_time.sec = val; break; - case 3: arg->cur_time.sec |= (val << 4); break; - case 4: arg->cur_time.min = val; break; - case 5: arg->cur_time.min |= (val << 4); break; - case 6: arg->cur_time.hour = val; break; - case 7: - default: - arg->cur_time.hour |= (val & 1) << 4; - time_format = (val >> 1) & 3; - if (time_format != arg->time_format) - return -EINVAL; - arg->cur_pos = snd_seq_time_frame_to_position(time_format, 4, &arg->cur_time); - arg->cur_pos += 7; /* correct the receive time */ - break; - } - - ev->type = SNDRV_SEQ_EVENT_SYNC; - ev->data.queue.sync_time_format = arg->time_format; - ev->data.queue.param.position = arg->cur_pos; - arg->cur_pos++; - - return 1; /* composed */ -} - -/* decode sync position */ -static int sync_pos_in(mtc_in_t *arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - unsigned time_format; - char buf[10]; - - if (snd_seq_expand_var_event(src, 10, buf, 1, 0) != 10) - return 0; - if (buf[1] != 0x7f || buf[3] != 0x01 || buf[4] != 0x01) - return 0; - time_format = (buf[5] >> 5) & 3; - if (time_format != arg->time_format) - return -EINVAL; - arg->cur_time.hour = buf[5] & 0x1f; - arg->cur_time.min = buf[6]; - arg->cur_time.sec = buf[7]; - arg->cur_time.frame = buf[8]; - arg->cur_pos = snd_seq_time_frame_to_position(time_format, 4, &arg->cur_time); - - ev->type = SNDRV_SEQ_EVENT_SYNC_POS; - ev->data.queue.sync_time_format = time_format; - ev->data.queue.param.position = arg->cur_pos; - - return 1; /* composed */ -} - -static int mtc_sync_in(seq_sync_arg_t _arg, const snd_seq_event_t *src, snd_seq_event_t *ev) -{ - mtc_in_t *arg = _arg; - switch (src->type) { - case SNDRV_SEQ_EVENT_QFRAME: - return sync_in(arg, src, ev); - case SNDRV_SEQ_EVENT_SYSEX: - return sync_pos_in(arg, src, ev); - } - return 0; -} - -/* exported */ -seq_sync_parser_t snd_seq_mtc_parser = { - format: SNDRV_SEQ_SYNC_FMT_MTC, - in: { - open: mtc_open_in, - sync: mtc_sync_in, - }, - out: { - open: mtc_open_out, - sync: mtc_sync_out, - }, -}; - -#endif /* SNDRV_SEQ_SYNC_SUPPORT */ diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 52993503185a..7cd9beb91909 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -48,18 +48,13 @@ #include "seq_timer.h" #include "seq_info.h" -#ifdef SNDRV_SEQ_SYNC_SUPPORT -/* FIXME: this should be in a header file */ -void snd_seq_sync_info_read(queue_t *q, snd_info_buffer_t *buffer); -#endif - static void snd_seq_check_queue_in_tasklet(unsigned long private_data); /* list of allocated queues */ static queue_t *queue_list[SNDRV_SEQ_MAX_QUEUES]; static spinlock_t queue_list_lock = SPIN_LOCK_UNLOCKED; /* number of queues allocated */ -static int num_queues = 0; +static int num_queues; int snd_seq_queue_get_cur_queues(void) { @@ -147,23 +142,12 @@ static queue_t *queue_new(int owner, int locked) q->locked = locked; q->klocked = 0; -#ifdef SNDRV_SEQ_SYNC_SUPPORT - q->master_lock = RW_LOCK_UNLOCKED; - q->slave_lock = RW_LOCK_UNLOCKED; - INIT_LIST_HEAD(&q->master_head); - q->slave.format = 0; -#endif - return q; } /* delete queue (destructor) */ static void queue_delete(queue_t *q) { -#ifdef SNDRV_SEQ_SYNC_SUPPORT - if (q->info_flags & SNDRV_SEQ_QUEUE_FLG_SYNC) - snd_seq_sync_delete_port(q); -#endif /* stop and release the timer */ snd_seq_timer_stop(q->timer); snd_seq_timer_close(q); @@ -218,12 +202,6 @@ int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags) return -ENOMEM; } snd_seq_queue_use(q->queue, client, 1); /* use this queue */ -#ifdef SNDRV_SEQ_SYNC_SUPPORT - if (q->info_flags & SNDRV_SEQ_QUEUE_FLG_SYNC) { - if (snd_seq_sync_create_port(q) < 0) - q->info_flags &= ~SNDRV_SEQ_QUEUE_FLG_SYNC; - } -#endif return q->queue; } @@ -547,9 +525,6 @@ int snd_seq_queue_timer_set_tempo(int queueid, int client, snd_seq_queue_tempo_t result = snd_seq_timer_set_ppq(q->timer, info->ppq); if (result >= 0 && info->skew_base > 0) result = snd_seq_timer_set_skew(q->timer, info->skew_value, info->skew_base); -#ifdef SNDRV_SEQ_SYNC_SUPPORT - snd_seq_sync_update_tempo(q); -#endif queue_access_unlock(q); queuefree(q); return result; @@ -724,14 +699,6 @@ static void queue_broadcast_event(queue_t *q, snd_seq_event_t *ev, int from_time sev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS; snd_seq_kernel_client_dispatch(SNDRV_SEQ_CLIENT_SYSTEM, &sev, atomic, hop); } -#ifdef SNDRV_SEQ_SYNC_SUPPORT - if (q->info_flags & SNDRV_SEQ_QUEUE_FLG_SYNC) { - /* broadcast events also to slave clients */ - sev.source = q->sync_port; - sev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS; - snd_seq_kernel_client_dispatch(SNDRV_SEQ_CLIENT_SYSTEM, &sev, atomic, hop); - } -#endif } /* @@ -744,24 +711,13 @@ void snd_seq_queue_process_event(queue_t *q, snd_seq_event_t *ev, int from_timer case SNDRV_SEQ_EVENT_START: snd_seq_prioq_leave(q->tickq, ev->source.client, 1); snd_seq_prioq_leave(q->timeq, ev->source.client, 1); -#ifdef SNDRV_SEQ_SYNC_SUPPORT - snd_seq_sync_clear(q); -#endif snd_seq_timer_start(q->timer); queue_broadcast_event(q, ev, from_timer_port, atomic, hop); -#ifdef SNDRV_SEQ_SYNC_SUPPORT - q->flags &= ~SNDRV_SEQ_QUEUE_FLG_SYNC_LOST; - snd_seq_sync_check(q, 0, atomic, hop); /* trigger the first signal */ -#endif break; case SNDRV_SEQ_EVENT_CONTINUE: snd_seq_timer_continue(q->timer); queue_broadcast_event(q, ev, from_timer_port, atomic, hop); -#ifdef SNDRV_SEQ_SYNC_SUPPORT - q->flags &= ~SNDRV_SEQ_QUEUE_FLG_SYNC_LOST; - snd_seq_sync_check(q, 0, atomic, hop); -#endif break; case SNDRV_SEQ_EVENT_STOP: @@ -771,26 +727,17 @@ void snd_seq_queue_process_event(queue_t *q, snd_seq_event_t *ev, int from_timer case SNDRV_SEQ_EVENT_TEMPO: snd_seq_timer_set_tempo(q->timer, ev->data.queue.param.value); -#ifdef SNDRV_SEQ_SYNC_SUPPORT - snd_seq_sync_update_tempo(q); -#endif queue_broadcast_event(q, ev, from_timer_port, atomic, hop); break; case SNDRV_SEQ_EVENT_SETPOS_TICK: if (snd_seq_timer_set_position_tick(q->timer, ev->data.queue.param.time.tick) == 0) { -#ifdef SNDRV_SEQ_SYNC_SUPPORT - snd_seq_sync_update_tick(q, 0, atomic, hop); -#endif queue_broadcast_event(q, ev, from_timer_port, atomic, hop); } break; case SNDRV_SEQ_EVENT_SETPOS_TIME: if (snd_seq_timer_set_position_time(q->timer, ev->data.queue.param.time.time) == 0) { -#ifdef SNDRV_SEQ_SYNC_SUPPORT - snd_seq_sync_update_time(q, 0, atomic, hop); -#endif queue_broadcast_event(q, ev, from_timer_port, atomic, hop); } break; @@ -864,9 +811,6 @@ void snd_seq_info_queues_read(snd_info_entry_t *entry, snd_iprintf(buffer, "current time : %d.%09d s\n", tmr->cur_time.tv_sec, tmr->cur_time.tv_nsec); snd_iprintf(buffer, "current tick : %d\n", tmr->tick.cur_tick); snd_iprintf(buffer, "\n"); -#ifdef SNDRV_SEQ_SYNC_SUPPORT - snd_seq_sync_info_read(q, buffer); -#endif queuefree(q); } } diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h index 4783d6e43ace..82139c43e9bf 100644 --- a/sound/core/seq/seq_queue.h +++ b/sound/core/seq/seq_queue.h @@ -24,9 +24,6 @@ #include "seq_prioq.h" #include "seq_timer.h" #include "seq_lock.h" -#ifdef SNDRV_SEQ_SYNC_SUPPORT -#include "seq_sync.h" -#endif #include <linux/interrupt.h> #include <linux/list.h> @@ -61,16 +58,6 @@ struct _snd_seq_queue { snd_use_lock_t use_lock; struct tasklet_struct taskq; - -#ifdef SNDRV_SEQ_SYNC_SUPPORT - struct list_head master_head; /* list of masters */ - queue_sync_t slave; /* slave (exclusive) */ - - rwlock_t master_lock; - rwlock_t slave_lock; - - snd_seq_addr_t sync_port; /* address of the attached sync port */ -#endif }; diff --git a/sound/core/seq/seq_sync.c b/sound/core/seq/seq_sync.c deleted file mode 100644 index a2c19bbc4051..000000000000 --- a/sound/core/seq/seq_sync.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* - * ALSA sequencer queue synchronization routine - * - * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de> - * - * 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 - * - */ - -#define __NO_VERSION__ -#include <sound/driver.h> -#include <sound/core.h> - -#include "seq_memory.h" -#include "seq_queue.h" -#include "seq_clientmgr.h" -#include "seq_fifo.h" -#include "seq_timer.h" -#include "seq_info.h" - -#ifdef SNDRV_SEQ_SYNC_SUPPORT - -#define FOR_EACH_LIST(var,list) \ -for (var = (list)->next; var != list; var = var->next) - -/* - * callbacks - */ -static int event_input_sync(snd_seq_event_t * ev, int direct, void *private_data, int atomic, int hop); -static int queue_master_add(void *private_data, snd_seq_port_subscribe_t *subs); -static int queue_master_remove(void *private_data, snd_seq_port_subscribe_t *subs); -static void queue_delete_all_masters(queue_t *q); -static int queue_slave_set(void *private_data, snd_seq_port_subscribe_t *subs); -static int queue_slave_reset(void *private_data, snd_seq_port_subscribe_t *subs); -static void queue_sync_close_parser(queue_sync_t *sync, int slave); - -/* - * pre-defined event parsers - */ - -extern seq_sync_parser_t snd_seq_midi_clock_parser; /* seq_midi_clock.c */ -extern seq_sync_parser_t snd_seq_mtc_parser; /* seq_mtc.c */ -extern seq_sync_parser_t snd_seq_dtl_parser; /* seq_dtl.c */ - -static seq_sync_parser_t *event_parsers[] = { - &snd_seq_midi_clock_parser, - &snd_seq_mtc_parser, - &snd_seq_dtl_parser, - NULL -}; - -/* - * create a sync port corresponding to the specified queue - */ -int snd_seq_sync_create_port(queue_t *queue) -{ - snd_seq_port_info_t port; - snd_seq_port_callback_t pcallbacks; - - memset(&pcallbacks, 0, sizeof(pcallbacks)); - memset(&port, 0, sizeof(port)); - pcallbacks.owner = THIS_MODULE; - pcallbacks.event_input = event_input_sync; - pcallbacks.subscribe = queue_master_add; - pcallbacks.unsubscribe = queue_master_remove; - pcallbacks.use = queue_slave_set; - pcallbacks.unuse = queue_slave_reset; - pcallbacks.private_data = queue; - pcallbacks.callback_all = 1; /* call callbacks at each subscription */ - port.capability = SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ| - SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_SUBS_WRITE| - SNDRV_SEQ_PORT_CAP_DUPLEX| - SNDRV_SEQ_PORT_CAP_SYNC_READ|SNDRV_SEQ_PORT_CAP_SYNC_WRITE; - port.type = 0; - sprintf(port.name, "Sync Queue %d", queue->queue); - port.kernel = &pcallbacks; - port.flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT; - port.port = snd_seq_queue_sync_port(queue->queue); - if (snd_seq_kernel_client_ctl(SNDRV_SEQ_CLIENT_SYSTEM, SNDRV_SEQ_IOCTL_CREATE_PORT, &port) < 0) - return -ENOMEM; - queue->sync_port.client = SNDRV_SEQ_CLIENT_SYSTEM; - queue->sync_port.port = port.port; - return 0; -} - -/* - * delete attached sync port to the queue - */ -int snd_seq_sync_delete_port(queue_t *queue) -{ - snd_seq_port_info_t port; - - memset(&port, 0, sizeof(port)); - port.client = queue->sync_port.client; - port.port = queue->sync_port.port; - if (snd_seq_kernel_client_ctl(SNDRV_SEQ_CLIENT_SYSTEM, SNDRV_SEQ_IOCTL_DELETE_PORT, &port) < 0) - return -ENOMEM; - queue_delete_all_masters(queue); - queue_sync_close_parser(&queue->slave, 1); - return 0; -} - - -/* - * send a sync signal to the sync slave client - */ -static void queue_send_sync_event(queue_t *q, queue_sync_t *master, int type, int atomic, int hop) -{ - snd_seq_event_t event; - - memset(&event, 0, sizeof(event)); - - event.flags = SNDRV_SEQ_TIME_MODE_ABS; - /* since we use direct delivery, we have to convert time stamp here.. */ - switch (master->format & SNDRV_SEQ_SYNC_MODE) { - case SNDRV_SEQ_SYNC_TICK: - event.flags |= SNDRV_SEQ_TIME_STAMP_TICK; - event.time.tick = q->timer->tick.cur_tick; - break; - case SNDRV_SEQ_SYNC_TIME: - event.flags |= SNDRV_SEQ_TIME_STAMP_REAL; - event.time.time = q->timer->cur_time; - break; - } - event.type = type; - event.data.queue.queue = q->queue; - event.data.queue.sync_format = master->format; - event.data.queue.sync_time_format = master->time_format; - event.data.queue.param.position = master->counter; - event.source = q->sync_port; - event.dest = master->addr; - if (master->parser) { - snd_seq_event_t newev; - newev = event; - if (master->parser->out.sync(master->parser_arg, &event, &newev) > 0) { - snd_seq_kernel_client_dispatch(SNDRV_SEQ_CLIENT_SYSTEM, &newev, atomic, hop); - return; - } - } - snd_seq_kernel_client_dispatch(SNDRV_SEQ_CLIENT_SYSTEM, &event, atomic, hop); -} - -/* - * initialize the sync position - */ -static void queue_sync_clear(queue_sync_t *sync) -{ - memset(&sync->cur_time, 0, sizeof(sync->cur_time)); - sync->counter = 0; - sync->sync_tick.cur_tick = 0; - sync->sync_tick.fraction = 0; -} - -/* - * initialize all sync positions - */ -void snd_seq_sync_clear(queue_t *q) -{ - struct list_head *head; - - /* clear master positions */ - read_lock(&q->master_lock); - FOR_EACH_LIST(head, &q->master_head) { - queue_sync_t *master = list_entry(head, queue_sync_t, list); - queue_sync_clear(master); - } - read_unlock(&q->master_lock); - read_lock(&q->slave_lock); - queue_sync_clear(&q->slave); - read_unlock(&q->slave_lock); -} - - -/* - * change tick resolution of sync master/slave - */ -static void queue_sync_set_tick_resolution(queue_t *q, queue_sync_t *sync) -{ - unsigned int tempo, ppq; - tempo = q->timer->tempo; - if (sync->param.tick.ppq == 0) - ppq = q->timer->ppq; - else - ppq = sync->param.tick.ppq; - snd_seq_timer_set_tick_resolution(&sync->sync_tick, tempo, ppq, sync->param.tick.ticks); -} - - -/* - * update sync-master resolutions - */ -void snd_seq_sync_update_tempo(queue_t *q) -{ - struct list_head *head; - - read_lock(&q->master_lock); - FOR_EACH_LIST(head, &q->master_head) { - queue_sync_t *master = list_entry(head, queue_sync_t, list); - if (master->format & SNDRV_SEQ_SYNC_TICK) - queue_sync_set_tick_resolution(q, master); - } - read_unlock(&q->master_lock); - read_lock(&q->slave_lock); - if (q->slave.format & SNDRV_SEQ_SYNC_TICK) - queue_sync_set_tick_resolution(q, &q->slave); - read_unlock(&q->slave_lock); -} - - -/* - * change the tick position from the current tick of the queue - */ -static void queue_sync_change_tick(queue_t *q, queue_sync_t *sync) -{ - if (sync->param.tick.ppq == 0) - sync->counter = q->timer->tick.cur_tick; - else - sync->counter = (q->timer->tick.cur_tick * sync->param.tick.ppq) / q->timer->ppq; - sync->counter /= sync->param.tick.ticks; - sync->sync_tick.cur_tick = sync->counter; - sync->sync_tick.fraction = 0; -} - -/* - * change the time position from the current time of the queue - */ -static void queue_sync_change_time(queue_t *q, queue_sync_t *sync) -{ - /* we need 64bit calculation here.. */ - u64 nsec; - - nsec = q->timer->cur_time.tv_sec; - nsec *= 1000000000UL; - nsec += q->timer->cur_time.tv_nsec; - u64_div(nsec, sync->param.time.resolution, sync->counter); - sync->counter *= sync->param.time.subframes; - sync->cur_time = q->timer->cur_time; -} - - -/* - * update the tick position of all sync - */ -void snd_seq_sync_update_tick(queue_t *q, int master_only, int atomic, int hop) -{ - struct list_head *head; - - read_lock(&q->master_lock); - FOR_EACH_LIST(head, &q->master_head) { - queue_sync_t *master = list_entry(head, queue_sync_t, list); - if (master->format & SNDRV_SEQ_SYNC_TICK) { - queue_sync_change_tick(q, master); - queue_send_sync_event(q, master, SNDRV_SEQ_EVENT_SYNC_POS, atomic, hop); /* broadcast to client */ - } - } - read_unlock(&q->master_lock); - if (master_only) - return; - read_lock(&q->slave_lock); - if (q->slave.format & SNDRV_SEQ_SYNC_TICK) - queue_sync_change_tick(q, &q->slave); - read_unlock(&q->slave_lock); -} - -/* - * update the time position of all sync - */ -void snd_seq_sync_update_time(queue_t *q, int master_only, int atomic, int hop) -{ - struct list_head *head; - - read_lock(&q->master_lock); - FOR_EACH_LIST(head, &q->master_head) { - queue_sync_t *master = list_entry(head, queue_sync_t, list); - if (master->format & SNDRV_SEQ_SYNC_TIME) { - queue_sync_change_time(q, master); - queue_send_sync_event(q, master, SNDRV_SEQ_EVENT_SYNC_POS, atomic, hop); - } - } - read_unlock(&q->master_lock); - if (master_only) - return; - read_lock(&q->slave_lock); - if (q->slave.format & SNDRV_SEQ_SYNC_TIME) - queue_sync_change_time(q, &q->slave); - read_unlock(&q->slave_lock); -} - - -/* - * check the current timer value and send sync messages if the sync - * time is elapsed - */ -static void queue_master_check(queue_t *q, unsigned long ticks, int atomic, int hop) -{ - struct list_head *head; - - read_lock(&q->master_lock); - FOR_EACH_LIST(head, &q->master_head) { - queue_sync_t *master = list_entry(head, queue_sync_t, list); - switch (master->format & SNDRV_SEQ_SYNC_MODE) { - case SNDRV_SEQ_SYNC_TICK: - snd_seq_timer_update_tick(&master->sync_tick, ticks); - while (master->sync_tick.cur_tick >= master->counter) { - queue_send_sync_event(q, master, SNDRV_SEQ_EVENT_SYNC, atomic, hop); - master->counter++; - } - break; - case SNDRV_SEQ_SYNC_TIME: - while (snd_seq_compare_real_time(&q->timer->cur_time, &master->cur_time)) { - queue_send_sync_event(q, master, SNDRV_SEQ_EVENT_SYNC, atomic, hop); - snd_seq_inc_time_nsec(&master->cur_time, master->resolution); - master->counter++; - } - break; - } - } - read_unlock(&q->master_lock); -} - - -/* - * slave stuff - */ - -/* - * update tick - */ -static void queue_slave_check(queue_t *q, unsigned long ticks) -{ - switch (q->slave.format & SNDRV_SEQ_SYNC_MODE) { - case SNDRV_SEQ_SYNC_TICK: - snd_seq_timer_update_tick(&q->slave.sync_tick, ticks); - break; - case SNDRV_SEQ_SYNC_TIME: - /* nothing */ - break; - } -} - -/* - * slave synchronization in real-time unit - */ -static int queue_slave_sync_time(queue_t *q, unsigned int position) -{ - struct timeval tm; - long diff_time, new_period; - queue_sync_t *sync = &q->slave; - sndrv_seq_queue_time_sync_t *p = &sync->param.time; - seq_timer_t *tmr = q->timer; - u64 external_counter, tmp; - - do_gettimeofday(&tm); - if (tmr->sync_start) { - /* XXX: we should use 64bit for diff_time, too. */ - diff_time = (tm.tv_sec - tmr->sync_last_tm.tv_sec) * 1000000 + - ((long)tm.tv_usec - (long)tmr->sync_last_tm.tv_usec); - diff_time = (p->x0 * tmr->sync_time_diff + p->x1 * (diff_time * 1000)) / (p->x0 + p->x1); -#define MIN_DIFF_TIME 1000 /* 1ms minimum */ - if (diff_time < MIN_DIFF_TIME) - diff_time = MIN_DIFF_TIME; - tmr->sync_time_diff = diff_time; - tmp = (u64)tmr->base_period * (u64)sync->resolution; - u64_div(tmp, diff_time, new_period); - - /* phase adjustment */ - external_counter = position; - external_counter *= sync->resolution; - - /* calculate current time */ - tmp = snd_seq_timer_get_cur_nsec(tmr, &tm); - - if (external_counter > tmp) { - tmp = external_counter - tmp; - if (tmp < p->max_time_diff) { - /* locked */ - int hz = p->phase_correct_time / tmr->base_period; - diff_time = (u32)tmp; - diff_time /= hz; - new_period += diff_time; - q->flags &= ~SNDRV_SEQ_QUEUE_FLG_SYNC_LOST; - } - } else { - tmp = tmp - external_counter; - if (tmp == 0) - q->flags &= ~SNDRV_SEQ_QUEUE_FLG_SYNC_LOST; - else if (tmp < p->max_time_diff) { - /* locked */ - int hz = p->phase_correct_time / tmr->base_period; - diff_time = (u32)tmp; - diff_time /= hz; - if (new_period - diff_time > MIN_DIFF_TIME) { - new_period -= diff_time; - q->flags &= ~SNDRV_SEQ_QUEUE_FLG_SYNC_LOST; - } else - q->flags |= SNDRV_SEQ_QUEUE_FLG_SYNC_LOST; - } - } - tmr->period = new_period; - } else { - tmr->sync_start = 1; - tmr->sync_time_diff = sync->resolution; - } - tmr->sync_last_tm = tm; - sync->counter = position; - - return 0; -} - -/* - * slave synchronization in tick unit - */ -static int queue_slave_sync_tick(queue_t *q, unsigned int position) -{ - struct timeval tm; - long diff_time, tick_diff; - unsigned int tick_time; - queue_sync_t *sync = &q->slave; - seq_timer_t *tmr = q->timer; - sndrv_seq_queue_tick_sync_t *p = &sync->param.tick; - - do_gettimeofday(&tm); - if (tmr->sync_start) { - /* XXX: diff_time should be 64bit for enough long sync period.. */ - diff_time = (tm.tv_sec - tmr->sync_last_tm.tv_sec) * 1000000 + - ((long)tm.tv_usec - (long)tmr->sync_last_tm.tv_usec); - diff_time *= 1000; /* in nsec */ - tick_time = (p->x0 * sync->sync_tick.resolution + - p->x1 * diff_time) / (p->x0 + p->x1); - /* phase adjustment */ - tick_diff = (long)position - (long)sync->sync_tick.cur_tick; - if (tick_diff != 0) { - if (tick_diff >= -p->max_tick_diff && - tick_diff <= p->max_tick_diff) { - /* locked */ - q->flags &= ~SNDRV_SEQ_QUEUE_FLG_SYNC_LOST; - tick_time = (tick_time * p->max_tick_diff2) / - (p->max_tick_diff2 + tick_diff); - } else { - /* sync lost.. freewheeling */ - q->flags |= SNDRV_SEQ_QUEUE_FLG_SYNC_LOST; - } - } else - q->flags &= ~SNDRV_SEQ_QUEUE_FLG_SYNC_LOST; - -#define MIN_TICK_TIME 1000 /* 1ms */ - if (tick_time < MIN_TICK_TIME) - tick_time = MIN_TICK_TIME; - - sync->sync_tick.resolution = tick_time; - snd_seq_timer_update_tick(&sync->sync_tick, 0); - if (p->ppq) - tmr->tick.resolution = (tick_time * p->ppq) / tmr->ppq; - else - tmr->tick.resolution = tick_time; - snd_seq_timer_update_tick(&tmr->tick, 0); - tmr->tempo = (tmr->tick.resolution * tmr->ppq) / 1000; - - } else - tmr->sync_start = 1; - tmr->sync_last_tm = tm; - - sync->counter = position; - - return 0; -} - - -/* - */ -static void queue_slave_jump_to_time(queue_t *q, unsigned int position, int atomic, int hop) -{ - u64 nsec; - queue_sync_t *sync = &q->slave; - - q->slave.counter = position; - nsec = sync->counter; - nsec *= sync->resolution; - u64_divmod(nsec, 1000000000, sync->cur_time.tv_sec, sync->cur_time.tv_nsec); - q->timer->cur_time = sync->cur_time; - - /* update master */ - snd_seq_sync_update_time(q, 1, atomic, hop); -} - -static void queue_slave_jump_to_tick(queue_t *q, unsigned int position, int atomic, int hop) -{ - unsigned int tick; - queue_sync_t *sync = &q->slave; - - sync->counter = position; - sync->sync_tick.cur_tick = sync->counter; - sync->sync_tick.fraction = 0; - - /* update queue timer */ - if (sync->param.tick.ppq == 0) - tick = sync->counter; - else - tick = sync->counter * q->timer->ppq / sync->param.tick.ppq; - q->timer->tick.cur_tick = tick * sync->param.tick.ticks; - q->timer->tick.fraction = 0; - - /* update master */ - snd_seq_sync_update_tick(q, 1, atomic, hop); -} - - -/* - * event input callback - */ -static int event_input_sync(snd_seq_event_t * ev, int direct, void *private_data, int atomic, int hop) -{ - queue_t *q = private_data; - unsigned long flags; - snd_seq_event_t newev; - - snd_assert(q != NULL, return -ENXIO); - - /* lock the queue owner access.. */ - spin_lock_irqsave(&q->owner_lock, flags); - q->klocked = 1; - spin_unlock_irqrestore(&q->owner_lock, flags); - - read_lock(&q->slave_lock); - if (q->slave.format) { - if (q->slave.parser) { - memset(&newev, 0, sizeof(newev)); - if (q->slave.parser->in.sync(q->slave.parser_arg, ev, &newev) > 0) - ev = &newev; - } - } - if (ev->type == SNDRV_SEQ_EVENT_SYNC) { - /* slave signal received */ - switch (q->slave.format & SNDRV_SEQ_SYNC_MODE) { - case SNDRV_SEQ_SYNC_TICK: - queue_slave_sync_tick(q, ev->data.queue.param.position); - break; - case SNDRV_SEQ_SYNC_TIME: - queue_slave_sync_time(q, ev->data.queue.param.position); - break; - } - } else if (ev->type == SNDRV_SEQ_EVENT_SYNC_POS) { - /* jump to position */ - switch (q->slave.format & SNDRV_SEQ_SYNC_MODE) { - case SNDRV_SEQ_SYNC_TICK: - if (q->timer->running) - queue_slave_sync_tick(q, ev->data.queue.param.position); - else - queue_slave_jump_to_tick(q, ev->data.queue.param.position, atomic, hop); - break; - case SNDRV_SEQ_SYNC_TIME: - if (q->timer->running) - queue_slave_sync_time(q, ev->data.queue.param.position); - else - queue_slave_jump_to_time(q, ev->data.queue.param.position, atomic, hop); - break; - } - } else { - /* control queue */ - snd_seq_queue_process_event(q, ev, 0, atomic, hop); - } - read_unlock(&q->slave_lock); - - /* unlock */ - spin_lock_irqsave(&q->owner_lock, flags); - q->klocked = 0; - spin_unlock_irqrestore(&q->owner_lock, flags); - - return 0; -} - - -/* - * initialize sync parameters - */ -static int queue_param_init(queue_t *q, queue_sync_t *sync, - snd_seq_addr_t *addr, sndrv_seq_queue_sync_t *info, - int slave) -{ - seq_sync_parser_t *parser, **list; - - sync->format = info->format; - sync->time_format = info->time_format; - *sync->opt_info = *info->info; - sync->addr = *addr; - /* copy params */ - if (info->format&SNDRV_SEQ_SYNC_TICK) - sync->param.tick=info->param.tick; - else - sync->param.time=info->param.time; - - sync->parser = NULL; - sync->parser_arg = NULL; - for (list = event_parsers; (parser = *list) != NULL; list++) { - if (parser->format == sync->format) { - int err; - if (slave) - err = parser->in.open(sync, &sync->parser_arg); - else - err = parser->out.open(sync, &sync->parser_arg); - if (err < 0) - return err; - sync->parser = parser; - break; - } - } - - switch (sync->format & SNDRV_SEQ_SYNC_MODE) { - case SNDRV_SEQ_SYNC_TICK: - if (sync->param.tick.ppq > 200) - goto __error; - if (sync->param.tick.ticks == 0) - sync->param.tick.ticks = 1; - queue_sync_set_tick_resolution(q, sync); - /* sync slave parameters -- will be configurable */ - sync->param.tick.x0 = 4; - sync->param.tick.x1 = 1; - sync->param.tick.max_tick_diff = 50; - sync->param.tick.max_tick_diff2 = sync->param.tick.max_tick_diff * 2; - break; - case SNDRV_SEQ_SYNC_TIME: - sync->resolution = sync->param.time.resolution; - if (sync->param.time.subframes == 0) - goto __error; - sync->resolution /= sync->param.time.subframes; - if (sync->resolution < 1000000) /* minimum = 1ms */ - goto __error; - /* sync slave parameters -- will be configurable */ - sync->param.time.x0 = 2; - sync->param.time.x1 = 1; - sync->param.time.max_time_diff = 1000000000UL; /* 1s */ - sync->param.time.phase_correct_time = 100000000UL; /* 0.1s */ - break; - default: - snd_printd("seq_sync: invalid format %x\n", sync->format); - goto __error; - } - return 0; - -__error: - queue_sync_close_parser(sync, slave); - return -EINVAL; -} - - -/* - * close event parser if exists - */ -static void queue_sync_close_parser(queue_sync_t *sync, int slave) -{ - if (sync->parser == NULL) - return; - if (slave) { - if (sync->parser->in.close) - sync->parser->in.close(sync->parser_arg); - else if (sync->parser_arg) - kfree(sync->parser_arg); - } else { - if (sync->parser->out.close) - sync->parser->out.close(sync->parser_arg); - else if (sync->parser_arg) - kfree(sync->parser_arg); - } - sync->parser = NULL; - sync->parser_arg = NULL; -} - - -/* - * add to master list - */ -static int queue_master_add(void *private_data, snd_seq_port_subscribe_t *subs) -{ - queue_t *q = private_data; - queue_sync_t *master; - unsigned long flags; - int err; - - snd_assert(q != NULL, return -EINVAL); - if (! subs->sync) - return -EINVAL; - master = snd_kcalloc(sizeof(*master), GFP_KERNEL); - if (master == NULL) - return -ENOMEM; - err = queue_param_init(q, master, &subs->dest, &subs->opt.sync_info, 0); - if (err < 0) { - kfree(master); - return err; - } - write_lock_irqsave(&q->master_lock, flags); - list_add(&master->list, &q->master_head); - write_unlock_irqrestore(&q->master_lock, flags); - - return 0; -} - -/* - * remove master - */ -static int queue_master_remove(void *private_data, snd_seq_port_subscribe_t *subs) -{ - queue_t *q = private_data; - sndrv_seq_queue_sync_t *info; - snd_seq_addr_t *addr; - struct list_head *head; - unsigned long flags; - - snd_assert(q != NULL, return -EINVAL); - if (! subs->sync) - return -EINVAL; - info = &subs->opt.sync_info; - addr = &subs->dest; - - write_lock_irqsave(&q->master_lock, flags); - FOR_EACH_LIST(head, &q->master_head) { - queue_sync_t *master = list_entry(head, queue_sync_t, list); - if (master->format == info->format && - master->addr.client == addr->client && - master->addr.port == addr->port) { - list_del(&master->list); - write_unlock_irqrestore(&q->master_lock, flags); - queue_sync_close_parser(master, 0); - kfree(master); - return 0; - } - } - write_unlock_irqrestore(&q->master_lock, flags); - snd_printd("seq_queue: can't find master from %d.%d format %0x\n", addr->client, addr->port, info->format); - return -ENXIO; -} - -/* remove all master connections if any exist */ -static void queue_delete_all_masters(queue_t *q) -{ - struct list_head *head; - unsigned long flags; - - write_lock_irqsave(&q->master_lock, flags); - FOR_EACH_LIST(head, &q->master_head) { - queue_sync_t *master = list_entry(head, queue_sync_t, list); - list_del(&master->list); - queue_sync_close_parser(master, 0); - kfree(master); - } - write_unlock_irqrestore(&q->master_lock, flags); -} - -/* - * set slave mode - */ -static int queue_slave_set(void *private_data, snd_seq_port_subscribe_t *subs) -{ - queue_t *q = private_data; - unsigned long flags; - int err; - - snd_assert(q != NULL, return -EINVAL); - if (! subs->sync) - return -EINVAL; - write_lock_irqsave(&q->slave_lock, flags); - if (q->slave.format) { - write_unlock_irqrestore(&q->slave_lock, flags); - return -EBUSY; - } - err = queue_param_init(q, &q->slave, &subs->sender, - &subs->opt.sync_info, 1); - if (err < 0) { - q->slave.format = 0; - write_unlock_irqrestore(&q->slave_lock, flags); - return err; - } - write_unlock_irqrestore(&q->slave_lock, flags); - return 0; -} - -/* - * remove slave mode - */ -static int queue_slave_reset(void *private_data, snd_seq_port_subscribe_t *subs) -{ - queue_t *q = private_data; - unsigned long flags; - - snd_assert(q != NULL, return -EINVAL); - if (! subs->sync) - return -EINVAL; - write_lock_irqsave(&q->slave_lock, flags); - if (q->slave.addr.client == subs->sender.client && - q->slave.addr.port == subs->sender.port) { - q->slave.format = 0; - queue_sync_close_parser(&q->slave, 1); - write_unlock_irqrestore(&q->slave_lock, flags); - return 0; - } - write_unlock_irqrestore(&q->slave_lock, flags); - snd_printd("seq_queue: can't match slave condition\n"); - return -ENXIO; -} - - -/* - * sync check - * this function is called at each timer interrupt. - */ - -void snd_seq_sync_check(queue_t *q, unsigned long resolution, int atomic, int hop) -{ - queue_master_check(q, resolution, atomic, hop); - queue_slave_check(q, resolution); -} - - -/* - * support functions for SMPTE time frame - */ -static unsigned int linear_time_to_position(sndrv_seq_time_frame_t time, - int nframes, int nsubs) -{ - unsigned int count; - count = time.hour * 60 + time.min; - count = count * 60 + time.sec; - count = count * nframes + time.frame; - count = count * nsubs + time.subframe; - return count; -} - -static sndrv_seq_time_frame_t linear_position_to_time(unsigned int count, - int nframes, int nsubs) -{ - sndrv_seq_time_frame_t time; - time.subframe = count % nsubs; - count /= nsubs; - time.hour = count / (3600 * nframes); - count %= 3600 * nframes; - time.min = count / (60 * nframes); - count %= 60 * nframes; - time.sec = count / nframes; - time.frame = count % nframes; - return time; -} - -/* drop frame - only 30fps */ -#define NFRAMES 30 -#define FRAMES_PER_MIN (NFRAMES * 60 - 2) -#define FRAMES_PER_10MIN (FRAMES_PER_MIN * 10 + 2) -#define FRAMES_PER_HOUR (FRAMES_PER_10MIN * 6) - -static unsigned int drop_time_to_position(sndrv_seq_time_frame_t time, int nsubs) -{ - unsigned int count, min; - - min = time.min % 10; - count = time.frame; - if (min > 0) { - if (time.sec == 0 && time.frame < 2) - count = 2; - } - count += time.sec * NFRAMES; - count += min * FRAMES_PER_MIN; - count += (time.min / 10) * FRAMES_PER_10MIN; - count += time.hour * (FRAMES_PER_HOUR); - count *= nsubs; - count += time.subframe; - - return count; -} - -static sndrv_seq_time_frame_t drop_position_to_time(int count, int nsubs) -{ - unsigned int min10; - sndrv_seq_time_frame_t time; - - time.subframe = count % nsubs; - count /= nsubs; - min10 = count / FRAMES_PER_10MIN; - time.hour = min10 / 6; - min10 %= 6; - count %= FRAMES_PER_10MIN; - if (count < 2) { - time.min = min10 * 10; - time.sec = 0; - } else { - count -= 2; - time.min = count / FRAMES_PER_MIN; - time.min += min10 * 10; - count %= FRAMES_PER_MIN; - count += 2; - time.sec = count / NFRAMES; - count %= NFRAMES; - } - time.frame = count; - - return time; -} - -/* convert from position counter to time frame */ -sndrv_seq_time_frame_t snd_seq_position_to_time_frame(int format, unsigned int nsubs, unsigned int pos) -{ - switch (format) { - case SNDRV_SEQ_SYNC_FPS_24: - return linear_position_to_time(pos, 24, nsubs); - case SNDRV_SEQ_SYNC_FPS_25: - return linear_position_to_time(pos, 25, nsubs); - case SNDRV_SEQ_SYNC_FPS_30_NDP: - return linear_position_to_time(pos, 30, nsubs); - case SNDRV_SEQ_SYNC_FPS_30_DP: - default: - return drop_position_to_time(pos, nsubs); - } -} - -/* convert from position counter to time frame */ -unsigned int snd_seq_time_frame_to_position(int format, unsigned int nsubs, sndrv_seq_time_frame_t *rtime) -{ - switch (format) { - case SNDRV_SEQ_SYNC_FPS_24: - return linear_time_to_position(*rtime, 24, nsubs); - case SNDRV_SEQ_SYNC_FPS_25: - return linear_time_to_position(*rtime, 25, nsubs); - case SNDRV_SEQ_SYNC_FPS_30_NDP: - return linear_time_to_position(*rtime, 30, nsubs); - case SNDRV_SEQ_SYNC_FPS_30_DP: - default: - return drop_time_to_position(*rtime, nsubs); - } -} - -/* resolution in nsec */ -unsigned long snd_seq_get_smpte_resolution(int time_format) -{ - switch (time_format) { - case SNDRV_SEQ_SYNC_FPS_24: - return 1000000000UL / 24; - case SNDRV_SEQ_SYNC_FPS_25: - return 1000000000UL / 25; - case SNDRV_SEQ_SYNC_FPS_30_DP: - case SNDRV_SEQ_SYNC_FPS_30_NDP: - return (unsigned long)(1000000000.0/29.97); - } - return 0; -} - - -/* - * proc interface - */ - -static void print_sync_info(snd_info_buffer_t *buffer, queue_sync_t *sync) -{ - snd_iprintf(buffer, " [%s] ==> %d:%d\n", - (sync->format & SNDRV_SEQ_SYNC_TICK ? "tick" : "time"), - sync->addr.client, sync->addr.port); - snd_iprintf(buffer, " format 0x%0x / time_format %d\n", - sync->format, sync->time_format); - switch (sync->format & SNDRV_SEQ_SYNC_MODE) { - case SNDRV_SEQ_SYNC_TICK: - snd_iprintf(buffer, " ppq: %d, ticks: %d\n", - sync->param.tick.ppq, sync->param.tick.ticks); - snd_iprintf(buffer, " resolution: %ld ns, position: %d\n", - sync->sync_tick.resolution, - sync->counter); - break; - case SNDRV_SEQ_SYNC_TIME: - snd_iprintf(buffer, " subframes %d, resolution: %ld ns, position: %d\n", - sync->param.time.subframes, - sync->resolution, - sync->counter); - break; - } -} - -void snd_seq_sync_info_read(queue_t *q, snd_info_buffer_t *buffer) -{ - struct list_head *head; - int count = 0; - - read_lock(&q->master_lock); - FOR_EACH_LIST(head, &q->master_head) { - queue_sync_t *master = list_entry(head, queue_sync_t, list); - snd_iprintf(buffer, "master %d", count); - print_sync_info(buffer, master); - count++; - } - read_unlock(&q->master_lock); - if (q->slave.format) { - snd_iprintf(buffer, "slave"); - print_sync_info(buffer, &q->slave); - count++; - } - if (count) - snd_iprintf(buffer, "\n"); -} - -#endif /* SNDRV_SEQ_SYNC_SUPPORT */ diff --git a/sound/core/seq/seq_sync.h b/sound/core/seq/seq_sync.h deleted file mode 100644 index 19d4b4d30a60..000000000000 --- a/sound/core/seq/seq_sync.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Synchronization of ALSA sequencer queues - * - * Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de> - * - * 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 - * - */ -#ifndef __SND_SEQ_SYNC_H -#define __SND_SEQ_SYNC_H - -typedef struct snd_queue_sync queue_sync_t; -typedef struct snd_seq_sync_parser seq_sync_parser_t; -typedef void *seq_sync_arg_t; - -struct snd_queue_sync { - unsigned char format; - unsigned char time_format; - unsigned char opt_info[6]; /* optional info */ - snd_seq_addr_t addr; /* master/slave address */ - - unsigned int counter; /* current position */ - unsigned long resolution; /* resolution for time */ - snd_seq_real_time_t cur_time; /* current time */ - seq_timer_tick_t sync_tick; /* tick info */ - - union { - struct sndrv_seq_queue_tick_sync tick; - struct sndrv_seq_queue_time_sync time; - } param; - - seq_sync_parser_t *parser; - seq_sync_arg_t parser_arg; - - struct list_head list; -}; - - -struct seq_sync_parser_ops { - int (*open)(queue_sync_t *sync_info, seq_sync_arg_t *retp); - int (*sync)(seq_sync_arg_t arg, const snd_seq_event_t *src, snd_seq_event_t *ev); - int (*close)(seq_sync_arg_t arg); -}; - -struct snd_seq_sync_parser { - unsigned int format; /* supported format */ - struct seq_sync_parser_ops in; /* sync-in (slave) */ - struct seq_sync_parser_ops out; /* sync-out (mastering) */ -}; - -/* - * prototypes - */ -int snd_seq_sync_create_port(queue_t *queue); -int snd_seq_sync_delete_port(queue_t *queue); -void snd_seq_sync_clear(queue_t *q); -void snd_seq_sync_update_tempo(queue_t *q); -void snd_seq_sync_update_tick(queue_t *q, int master_only, int atomic, int hop); -void snd_seq_sync_update_time(queue_t *q, int master_only, int atomic, int hop); -void snd_seq_sync_check(queue_t *q, unsigned long resolution, int atomic, int hop); - -sndrv_seq_time_frame_t snd_seq_position_to_time_frame(int format, unsigned int nsubs, unsigned int pos); -unsigned int snd_seq_time_frame_to_position(int format, unsigned int nsubs, sndrv_seq_time_frame_t *rtime); -unsigned long snd_seq_get_smpte_resolution(int time_format); - - -#endif diff --git a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h index 3012aa9391ad..e181aaf32ae9 100644 --- a/sound/core/seq/seq_timer.h +++ b/sound/core/seq/seq_timer.h @@ -52,12 +52,6 @@ typedef struct { unsigned int skew; unsigned int skew_base; -#ifdef SNDRV_SEQ_SYNC_SUPPORT - int sync_start; - struct timeval sync_last_tm; - unsigned int sync_time_diff; -#endif - struct timeval last_update; /* time of last clock update, used for interpolation */ spinlock_t lock; @@ -144,8 +138,4 @@ int snd_seq_timer_set_skew(seq_timer_t *tmr, unsigned int skew, unsigned int bas snd_seq_real_time_t snd_seq_timer_get_cur_time(seq_timer_t *tmr); snd_seq_tick_time_t snd_seq_timer_get_cur_tick(seq_timer_t *tmr); -#ifdef SNDRV_SEQ_SYNC_SUPPORT -u64 snd_seq_timer_get_cur_nsec(seq_timer_t *tmr, struct timeval *tm); -#endif - #endif diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index b2ff32b30623..4b3bd1ca47d5 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c @@ -7,85 +7,6 @@ * * This code is based on the code from ALSA 0.5.9, but heavily rewritten. * - * Sat Mar 31 17:27:57 PST 2001 tim.mann@compaq.com - * Added support for the Midiator MS-124T and for the MS-124W in - * Single Addressed (S/A) or Multiple Burst (M/B) mode, with - * power derived either parasitically from the serial port or - * from a separate power supply. - * - * The new snd_adaptor module parameter allows you to select - * either the default Roland Soundcanvas support (0), which was - * previously included in this driver but was not documented, - * Midiator MS-124T support (1), Midiator MS-124W S/A mode - * support (2), or MS-124W M/B mode support (3). For the - * Midiator MS-124W, you must set the physical M-S and A-B - * switches on the Midiator to match the driver mode you select. - * - * - In Roland Soundcanvas mode, multiple ALSA raw MIDI - * substreams are supported (midiCnD0-midiCnD15). Whenever you - * write to a different substream, the driver sends the - * nonstandard MIDI command sequence F5 NN, where NN is the - * substream number plus 1. Roland modules use this command to - * switch between different "parts", so this feature lets you - * treat each part as a distinct raw MIDI substream. The driver - * provides no way to send F5 00 (no selection) or to not send - * the F5 NN command sequence at all; perhaps it ought to. - * - * - In MS-124T mode, one raw MIDI substream is supported - * (midiCnD0); the snd_outs module parameter is automatically set - * to 1. The driver sends the same data to all four MIDI Out - * connectors. Set the A-B switch and the snd_speed module - * parameter to match (A=19200, B=9600). - * - * Usage example for MS-124T, with A-B switch in A position: - * setserial /dev/ttyS0 uart none - * /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \ - * snd_adaptor=1 snd_speed=19200 - * - * - In MS-124W S/A mode, one raw MIDI substream is supported - * (midiCnD0); the snd_outs module parameter is automatically set - * to 1. The driver sends the same data to all four MIDI Out - * connectors at full MIDI speed. - * - * Usage example for S/A mode: - * setserial /dev/ttyS0 uart none - * /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \ - * snd_adaptor=2 - * - * - In MS-124W M/B mode, the driver supports 16 ALSA raw MIDI - * substreams; the snd_outs module parameter is automatically set - * to 16. The substream number gives a bitmask of which MIDI Out - * connectors the data should be sent to, with midiCnD1 sending - * to Out 1, midiCnD2 to Out 2, midiCnD4 to Out 3, and midiCnD8 - * to Out 4. Thus midiCnD15 sends the data to all 4 ports. As a - * special case, midiCnD0 also sends to all ports, since it is - * not useful to send the data to no ports. M/B mode has extra - * overhead to select the MIDI Out for each byte, so the - * aggregate data rate across all four MIDI Outs is at most one - * byte every 520 us, as compared with the full MIDI data rate of - * one byte every 320 us per port. - * - * Usage example for M/B mode: - * setserial /dev/ttyS0 uart none - * /sbin/insmod snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \ - * snd_adaptor=3 - * - * - The MS-124W hardware's M/A mode is currently not supported. - * This mode allows the MIDI Outs to act independently at double - * the aggregate throughput of M/B, but does not allow sending - * the same byte simultaneously to multiple MIDI Outs. The M/A - * protocol requires the driver to twiddle the modem control - * lines under timing constraints, so it would be a bit more - * complicated to implement than the other modes. - * - * - Midiator models other than MS-124W and MS-124T are currently - * not supported. Note that the suffix letter is significant; - * the MS-124 and MS-124B are not compatible, nor are the other - * known models MS-101, MS-101B, MS-103, and MS-114. I do have - * documentation that partially covers these models, but no units - * to experiment with. The MS-124W support is tested with a real - * unit. The MS-124T support is untested, but should work. - * * 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 @@ -100,6 +21,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * Sat Mar 31 17:27:57 PST 2001 tim.mann@compaq.com + * Added support for the Midiator MS-124T and for the MS-124W in + * Single Addressed (S/A) or Multiple Burst (M/B) mode, with + * power derived either parasitically from the serial port or + * from a separate power supply. + * + * More documentation can be found in serial-u16550.txt. */ #include <sound/driver.h> @@ -115,10 +43,10 @@ #include <linux/serial_reg.h> EXPORT_NO_SYMBOLS; -MODULE_DESCRIPTION("MIDI serial"); +MODULE_DESCRIPTION("MIDI serial u16550"); MODULE_LICENSE("GPL"); MODULE_CLASSES("{sound}"); -MODULE_DEVICES("{{ALSA, MIDI serial}}"); +MODULE_DEVICES("{{ALSA, MIDI serial u16550}}"); #define SNDRV_SERIAL_SOUNDCANVAS 0 /* Roland Soundcanvas; F5 NN selects part */ #define SNDRV_SERIAL_MS124T 1 /* Midiator MS-124T */ @@ -134,12 +62,12 @@ static char *adaptor_names[] = { static int snd_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ -static long snd_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x3f8,0x2f8,0x3e8,0x2e8 */ -static int snd_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 3,4,5,7,9,10,11,14,15 */ +static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static long snd_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x3f8,0x2f8,0x3e8,0x2e8 */ +static int snd_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 3,4,5,7,9,10,11,14,15 */ static int snd_speed[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 38400}; /* 9600,19200,38400,57600,115200 */ static int snd_base[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 115200}; /* baud base */ -static int snd_outs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */ +static int snd_outs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */ static int snd_adaptor[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = SNDRV_SERIAL_SOUNDCANVAS}; MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); @@ -165,6 +93,7 @@ MODULE_PARM_DESC(snd_base, "Base for divisor in bauds."); MODULE_PARM_SYNTAX(snd_base, SNDRV_ENABLED ",allows:{57600,115200,230400,460800},dialog:list"); MODULE_PARM(snd_outs, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(snd_outs, "Number of MIDI outputs."); + MODULE_PARM_SYNTAX(snd_outs, SNDRV_ENABLED ",allows:{{1,16}},dialog:list"); MODULE_PARM(snd_adaptor, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(snd_adaptor, "Type of adaptor."); diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 29a62ca2d39e..bb3de44073a7 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c @@ -323,7 +323,7 @@ static int __init snd_card_ad1816a_probe(int dev) static int __init snd_ad1816a_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/als100.c b/sound/isa/als100.c index 72e52883fbc4..d6f0af9f90a9 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c @@ -347,7 +347,7 @@ static int __init snd_card_als100_probe(int dev) static int __init snd_als100_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index 8e84e21628be..fc2a4925081d 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c @@ -370,7 +370,7 @@ static int __init snd_card_azt2320_probe(int dev) static int __init snd_azt2320_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index d49c82efa0c1..3a8bb131de0a 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -450,7 +450,7 @@ static void __exit alsa_card_cmi8330_exit(void) static int __init snd_cmi8330_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 3e155d84cdbe..12945e26c4e7 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -538,7 +538,7 @@ static int __init snd_card_cs4236_probe(int dev) static int __init snd_cs4236_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/dt0197h.c b/sound/isa/dt0197h.c index e3c30768d1b8..eb55ed0a2599 100644 --- a/sound/isa/dt0197h.c +++ b/sound/isa/dt0197h.c @@ -318,7 +318,7 @@ static int __init snd_card_dt0197h_probe(int dev) static int __init snd_dt0197h_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 8f2d23e0a270..a4e91321be66 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -165,7 +165,7 @@ static int __init snd_audiodrive_probe(int dev) static int __init snd_audiodrive_legacy_auto_probe(unsigned long port) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index f54735518223..b2b17a5cef72 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -2194,7 +2194,7 @@ static int __init snd_audiodrive_probe(int dev) static int __init snd_audiodrive_probe_legacy_port(unsigned long port) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { @@ -2218,7 +2218,7 @@ static int __init snd_audiodrive_probe_legacy_port(unsigned long port) static int __init snd_audiodrive_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index 2c161f9797a2..3b96090dbc4b 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c @@ -222,7 +222,7 @@ static int __init snd_gusclassic_probe(int dev) static int __init snd_gusclassic_legacy_auto_probe(unsigned long port) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 3d6593e8e6f3..582c565ed93a 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c @@ -347,7 +347,7 @@ static int __init snd_gusextreme_probe(int dev) static int __init snd_gusextreme_legacy_auto_probe(unsigned long port) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index eadc412dd5dc..67a7338a7ff1 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c @@ -358,7 +358,7 @@ static int __init snd_gusmax_probe(int dev) static int __init snd_gusmax_legacy_auto_probe(unsigned long port) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index a28db1cd25aa..357d2ebc1f02 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -886,7 +886,7 @@ static int __init snd_interwave_probe(int dev) static int __init snd_interwave_probe_legacy_port(unsigned long port) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { @@ -910,7 +910,7 @@ static int __init snd_interwave_probe_legacy_port(unsigned long port) static int __init snd_interwave_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 1c8ca4ac6857..338c130b4fbb 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -856,7 +856,7 @@ static int __init snd_opl3sa2_probe(int dev) static int __init snd_opl3sa2_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index 01f06bf66086..f14713e510cb 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -35,13 +35,6 @@ #include <sound/control.h> #include <sound/initval.h> -#if 0 -MODULE_AUTHOR("Takashi Iwai, Steve Ratcliffe"); -MODULE_DESCRIPTION("Routines for control of EMU8000 chip"); -MODULE_LICENSE("GPL"); -MODULE_CLASSES("{sound}"); -#endif - /* * emu8000 register controls */ @@ -136,7 +129,7 @@ snd_emu8000_dma_chan(emu8000_t *emu, int ch, int mode) /* */ -static void /*__init*/ +static void __init snd_emu8000_read_wait(emu8000_t *emu) { while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) { @@ -149,7 +142,7 @@ snd_emu8000_read_wait(emu8000_t *emu) /* */ -static void /*__init*/ +static void __init snd_emu8000_write_wait(emu8000_t *emu) { while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) { @@ -163,7 +156,7 @@ snd_emu8000_write_wait(emu8000_t *emu) /* * detect a card at the given port */ -static int /*__init*/ +static int __init snd_emu8000_detect(emu8000_t *emu) { /* Initialise */ @@ -189,7 +182,7 @@ snd_emu8000_detect(emu8000_t *emu) /* * intiailize audio channels */ -static void /*__init*/ +static void __init init_audio(emu8000_t *emu) { int ch; @@ -230,7 +223,7 @@ init_audio(emu8000_t *emu) /* * initialize DMA address */ -static void /*__init*/ +static void __init init_dma(emu8000_t *emu) { EMU8000_SMALR_WRITE(emu, 0); @@ -334,7 +327,7 @@ static unsigned short init4[128] /*__devinitdata*/ = { * Taken from the oss driver, not obvious from the doc how this * is meant to work */ -static void /*__init*/ +static void __init send_array(emu8000_t *emu, unsigned short *data, int size) { int i; @@ -358,7 +351,7 @@ send_array(emu8000_t *emu, unsigned short *data, int size) * Send initialization arrays to start up, this just follows the * initialisation sequence in the adip. */ -static void /*__init*/ +static void __init init_arrays(emu8000_t *emu) { send_array(emu, init1, NELEM(init1)/4); @@ -385,7 +378,7 @@ init_arrays(emu8000_t *emu) * seems that the only way to do this is to use the one channel and keep * reallocating between read and write. */ -static void /*__init*/ +static void __init size_dram(emu8000_t *emu) { int i, size; @@ -511,7 +504,7 @@ snd_emu8000_init_fm(emu8000_t *emu) /* * The main initialization routine. */ -static void /*__init*/ +static void __init snd_emu8000_init_hw(emu8000_t *emu) { int i; @@ -665,7 +658,7 @@ snd_emu8000_load_chorus_fx(emu8000_t *emu, int mode, const void *buf, long len) { soundfont_chorus_fx_t rec; if (mode < SNDRV_EMU8000_CHORUS_PREDEFINED || mode >= SNDRV_EMU8000_CHORUS_NUMBERS) { - snd_printk("illegal chorus mode %d for uploading\n", mode); + snd_printk(KERN_WARNING "illegal chorus mode %d for uploading\n", mode); return -EINVAL; } if (len < sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec))) @@ -793,7 +786,7 @@ snd_emu8000_load_reverb_fx(emu8000_t *emu, int mode, const void *buf, long len) soundfont_reverb_fx_t rec; if (mode < SNDRV_EMU8000_REVERB_PREDEFINED || mode >= SNDRV_EMU8000_REVERB_NUMBERS) { - snd_printk("illegal reverb mode %d for uploading\n", mode); + snd_printk(KERN_WARNING "illegal reverb mode %d for uploading\n", mode); return -EINVAL; } if (len < sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec))) @@ -1032,7 +1025,7 @@ static snd_kcontrol_new_t *mixer_defs[EMU8000_NUM_CONTROLS] = { /* * create and attach mixer elements for WaveTable treble/bass controls */ -static int /*__init*/ +static int __init snd_emu8000_create_mixer(snd_card_t *card, emu8000_t *emu) { int i, err = 0; @@ -1089,7 +1082,7 @@ static int snd_emu8000_dev_free(snd_device_t *device) /* * initialize and register emu8000 synth device. */ -/*exported*/ int +int __init snd_emu8000_new(snd_card_t *card, int index, long port, int seq_ports, snd_seq_device_t **awe_ret) { snd_seq_device_t *awe; @@ -1160,7 +1153,6 @@ snd_emu8000_new(snd_card_t *card, int index, long port, int seq_ports, snd_seq_d * exported stuff */ -EXPORT_SYMBOL(snd_emu8000_new); EXPORT_SYMBOL(snd_emu8000_poke); EXPORT_SYMBOL(snd_emu8000_peek); EXPORT_SYMBOL(snd_emu8000_poke_dw); @@ -1172,21 +1164,3 @@ EXPORT_SYMBOL(snd_emu8000_load_reverb_fx); EXPORT_SYMBOL(snd_emu8000_update_chorus_mode); EXPORT_SYMBOL(snd_emu8000_update_reverb_mode); EXPORT_SYMBOL(snd_emu8000_update_equalizer); - -#if 0 -/* - * INIT part - */ - -static int __init alsa_emu8000_init(void) -{ - return 0; -} - -static void __exit alsa_emu8000_exit(void) -{ -} - -module_init(alsa_emu8000_init) -module_exit(alsa_emu8000_exit) -#endif diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c index bd9bace2c2b0..6be4cbf44654 100644 --- a/sound/isa/sb/es968.c +++ b/sound/isa/sb/es968.c @@ -231,7 +231,7 @@ static int __init snd_card_es968_probe(int dev) static int __init snd_es968_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 30f5c3d762da..a8e895946d6f 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c @@ -556,7 +556,7 @@ static int __init snd_sb16_probe(int dev) static int __init snd_sb16_probe_legacy_port(unsigned long port) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { @@ -580,7 +580,7 @@ static int __init snd_sb16_probe_legacy_port(unsigned long port) static int __init snd_sb16_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index bd3ddcf38e68..01ad20cd4c5d 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c @@ -778,7 +778,7 @@ int snd_sb16dsp_configure(sb_t * chip) return -EINVAL; } } - if (chip->dma16 >= 0) { + if (chip->dma16 >= 0 && chip->dma16 != chip->dma8) { switch (chip->dma16) { case 5: dmareg |= SB_DMASETUP_DMA5; @@ -869,7 +869,10 @@ int snd_sb16dsp_pcm(sb_t * chip, int device, snd_pcm_t ** rpcm) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb16_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb16_capture_ops); - snd_ctl_add(card, snd_ctl_new1(&snd_sb16_dma_control, chip)); + if (chip->dma16 >= 0 && chip->dma8 != chip->dma16) + snd_ctl_add(card, snd_ctl_new1(&snd_sb16_dma_control, chip)); + else + pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; snd_pcm_lib_preallocate_isa_pages_for_all(pcm, 64*1024, 128*1024); diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index 1cbf406d389f..f2bf2e5c1bbb 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c @@ -183,7 +183,7 @@ static int __init snd_sb8_probe(int dev) static int __init snd_card_sb8_legacy_auto_probe(unsigned long port) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c index 3f7a796773a0..ef6c1c5f7bed 100644 --- a/sound/isa/sb/sb_common.c +++ b/sound/isa/sb/sb_common.c @@ -191,7 +191,7 @@ static int snd_sbdsp_free(sb_t *chip) disable_dma(chip->dma8); free_dma(chip->dma8); } - if (chip->dma16 >= 0) { + if (chip->dma16 >= 0 && chip->dma16 != chip->dma8) { disable_dma(chip->dma16); free_dma(chip->dma16); } @@ -257,9 +257,14 @@ int snd_sbdsp_create(snd_card_t *card, return -EBUSY; } chip->dma8 = dma8; - if (dma16 >= 0 && request_dma(dma16, "SoundBlaster - 16bit")) { - snd_sbdsp_free(chip); - return -EBUSY; + if (dma16 >= 0) { + if (dma16 < 5 || dma16 > 7) { + /* Vibra has no 16bit DMA - no duplex */ + dma16 = dma8; + } else if (request_dma(dma16, "SoundBlaster - 16bit")) { + snd_sbdsp_free(chip); + return -EBUSY; + } } chip->dma16 = dma16; #endif diff --git a/sound/isa/wavefront/Makefile b/sound/isa/wavefront/Makefile index 230f389b1867..633ca2ee5127 100644 --- a/sound/isa/wavefront/Makefile +++ b/sound/isa/wavefront/Makefile @@ -5,14 +5,8 @@ O_TARGET := _wavefront.o -#list-multi := snd-wavefront-fx.o snd-wavefront-synth.o snd-wavefront.o list-multi := snd-wavefront.o -#export-objs := wavefront_fx.o wavefront_synth.o - -#snd-wavefront-fx-objs := wavefront_fx.o -#snd-wavefront-synth-objs := wavefront_synth.o wavefront_midi.o -#snd-wavefront-objs := wavefront.o snd-wavefront-objs := wavefront.o wavefront_fx.o wavefront_synth.o wavefront_midi.o # Toplevel Module Dependency @@ -20,11 +14,5 @@ obj-$(CONFIG_SND_WAVEFRONT) += snd-wavefront.o include $(TOPDIR)/Rules.make -snd-wavefront-fx.o: $(snd-wavefront-fx-objs) - $(LD) $(LD_RFLAG) -r -o $@ $(snd-wavefront-fx-objs) - -snd-wavefront-synth.o: $(snd-wavefront-synth-objs) - $(LD) $(LD_RFLAG) -r -o $@ $(snd-wavefront-synth-objs) - snd-wavefront.o: $(snd-wavefront-objs) $(LD) $(LD_RFLAG) -r -o $@ $(snd-wavefront-objs) diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index 0e0ae3c795c9..e52c8e0ce5e9 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -58,7 +58,8 @@ static int snd_dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ static int snd_use_cs4232_midi[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); -MODULE_PARM_SYNTAX(snd_index, "Index value for WaveFront soundcard."); +MODULE_PARM_DESC(snd_index, "Index value for WaveFront soundcard."); +MODULE_PARM_SYNTAX(snd_index, SNDRV_INDEX_DESC); MODULE_PARM(snd_id, "1-" __MODULE_STRING(SNDRV_CARDS) "s"); MODULE_PARM_DESC(snd_id, "ID string for WaveFront soundcard."); MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC); @@ -99,7 +100,7 @@ MODULE_PARM_DESC(snd_fm_port, "FM port #."); MODULE_PARM_SYNTAX(snd_fm_port, SNDRV_PORT12_DESC); MODULE_PARM(snd_use_cs4232_midi, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(snd_use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)"); -MODULE_PARM_SYNTAX(snd_use_cs4232_midi, SNDRV_ENABLED ",allows use of CS4323 MPU-401 interface"); +MODULE_PARM_SYNTAX(snd_use_cs4232_midi, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC); static snd_card_t *snd_wavefront_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; @@ -701,7 +702,7 @@ snd_wavefront_probe (int dev) static int __init snd_wavefront_isapnp_detect(struct isapnp_card *card, const struct isapnp_card_id *id) { - static int dev = 0; + static int dev; int res; for ( ; dev < SNDRV_CARDS; dev++) { diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c index 12e1cacb8225..578333e7cae6 100644 --- a/sound/isa/wavefront/wavefront_fx.c +++ b/sound/isa/wavefront/wavefront_fx.c @@ -27,13 +27,6 @@ #include <sound/yss225.h> #include <sound/initval.h> -#if 0 -MODULE_AUTHOR("Paul Davis <pbd@op.net>"); -MODULE_DESCRIPTION("ALSA driver for Turtle Beach Tropez+ YSS225 FX Processor"); -MODULE_LICENSE("GPL"); -MODULE_CLASSES("{sound}"); -#endif - /* Control bits for the Load Control Register */ @@ -256,7 +249,7 @@ snd_wavefront_fx_ioctl (snd_hwdep_t *sdev, struct file *file, */ -int +int __init snd_wavefront_fx_start (snd_wavefront_t *dev) { @@ -1031,22 +1024,3 @@ static unsigned char coefficients3[] __initdata = { 0x0f, 0xd7, 0x0f, 0xd7, 0x0f, 0xff, 0x0f, 0xff }; -#if 0 -EXPORT_SYMBOL(snd_wavefront_fx_start); -EXPORT_SYMBOL(snd_wavefront_fx_detect); -EXPORT_SYMBOL(snd_wavefront_fx_ioctl); -EXPORT_SYMBOL(snd_wavefront_fx_open); -EXPORT_SYMBOL(snd_wavefront_fx_release); - -static int __init alsa_wavefront_fx_init(void) -{ - return 0; -} - -static void __exit alsa_wavefront_fx_exit(void) -{ -} - -module_init(alsa_wavefront_fx_init) -module_exit(alsa_wavefront_fx_exit) -#endif diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c index b54c7171c280..74dfa45eaf69 100644 --- a/sound/isa/wavefront/wavefront_midi.c +++ b/sound/isa/wavefront/wavefront_midi.c @@ -478,7 +478,7 @@ snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card) spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags); } -int +int __init snd_wavefront_midi_start (snd_wavefront_card_t *card) { diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 777bb390fc0d..7eada978a69a 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -84,12 +84,6 @@ int ramcheck_time = 20; /* time in seconds to wait while ROM code int osrun_time = 10; /* time in seconds we wait for the OS to start running. */ -#if 0 -MODULE_AUTHOR("Paul Barton-Davis <pbd@op.net>"); -MODULE_DESCRIPTION("ALSA driver for Turtle Beach WaveFront ICS2215 Synth"); -MODULE_LICENSE("GPL"); -MODULE_CLASSES("{sound}"); -#endif MODULE_PARM(wf_raw,"i"); MODULE_PARM_DESC(wf_raw, "if non-zero, assume that we need to boot the OS"); MODULE_PARM(fx_raw,"i"); @@ -1729,7 +1723,7 @@ snd_wavefront_internal_interrupt (snd_wavefront_card_t *card) 7 Unused */ -int +int __init snd_wavefront_interrupt_bits (int irq) { @@ -1757,7 +1751,7 @@ snd_wavefront_interrupt_bits (int irq) return bits; } -static void +static void __init wavefront_should_cause_interrupt (snd_wavefront_t *dev, int val, int port, int timeout) @@ -1772,7 +1766,7 @@ wavefront_should_cause_interrupt (snd_wavefront_t *dev, restore_flags (flags); } -static int +static int __init wavefront_reset_to_cleanliness (snd_wavefront_t *dev) { @@ -1932,7 +1926,7 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev) static int errno; -static int +static int __init wavefront_download_firmware (snd_wavefront_t *dev, char *path) { @@ -2027,7 +2021,7 @@ wavefront_download_firmware (snd_wavefront_t *dev, char *path) } -static int +static int __init wavefront_do_reset (snd_wavefront_t *dev) { @@ -2116,7 +2110,7 @@ wavefront_do_reset (snd_wavefront_t *dev) return 1; } -int +int __init snd_wavefront_start (snd_wavefront_t *dev) { @@ -2158,7 +2152,7 @@ snd_wavefront_start (snd_wavefront_t *dev) return (0); } -int +int __init snd_wavefront_detect (snd_wavefront_card_t *card) { @@ -2212,33 +2206,3 @@ snd_wavefront_detect (snd_wavefront_card_t *card) return 0; } - -#if 0 -EXPORT_SYMBOL(snd_wavefront_synth_ioctl); -EXPORT_SYMBOL(snd_wavefront_synth_open); -EXPORT_SYMBOL(snd_wavefront_synth_release); -EXPORT_SYMBOL(snd_wavefront_internal_interrupt); -EXPORT_SYMBOL(snd_wavefront_interrupt_bits); -EXPORT_SYMBOL(snd_wavefront_start); -EXPORT_SYMBOL(snd_wavefront_detect); -EXPORT_SYMBOL(snd_wavefront_cmd); - /* wavefront_midi.c */ -EXPORT_SYMBOL(snd_wavefront_midi_interrupt); -EXPORT_SYMBOL(snd_wavefront_midi_enable_virtual); -EXPORT_SYMBOL(snd_wavefront_midi_disable_virtual); -EXPORT_SYMBOL(snd_wavefront_midi_start); -EXPORT_SYMBOL(snd_wavefront_midi_input); -EXPORT_SYMBOL(snd_wavefront_midi_output); - -static int __init alsa_wavefront_init(void) -{ - return 0; -} - -static void __exit alsa_wavefront_exit(void) -{ -} - -module_init(alsa_wavefront_init) -module_exit(alsa_wavefront_exit) -#endif diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index e722c3c1f759..7b6a98b6ec1a 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -36,7 +36,7 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); MODULE_DESCRIPTION("Universal interface for Audio Codec '97"); MODULE_LICENSE("GPL"); -static int enable_loopback = 0; +static int enable_loopback; MODULE_PARM(enable_loopback, "i"); MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control"); diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 224d39d5d909..655413335419 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -2177,7 +2177,7 @@ static int __devinit snd_ali_create(snd_card_t * card, static int __devinit snd_ali_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; ali_t *codec; int err; diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 0e937020dfbc..95da106ea22f 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -558,7 +558,7 @@ static void snd_card_als4k_free( snd_card_t *card ) static int __devinit snd_card_als4k_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; snd_card_als4000_t *acard; unsigned long gcr; diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 926b5705b01a..7a6ed6279386 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -1485,9 +1485,10 @@ static int snd_cmipci_playback_spdif_open(snd_pcm_substream_t *substream) if ((err = open_device_check(cm, CM_OPEN_SPDIF_PLAYBACK, substream)) < 0) /* use channel A */ return err; runtime->hw = snd_cmipci_playback_spdif; - if (cm->can_ac3_hw) { +#ifdef DO_SOFT_AC3 + if (cm->can_ac3_hw) +#endif runtime->hw.info |= SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID; - } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000); cm->dig_pcm_status = cm->dig_status; return 0; @@ -2461,8 +2462,11 @@ static int snd_cmipci_free(cmipci_t *cm) snd_cmipci_proc_done(cm); if (cm->irq >= 0) { + snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN); + snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); /* disable ints */ snd_cmipci_write(cm, CM_REG_FUNCTRL0, 0); /* disable channels */ + snd_cmipci_write(cm, CM_REG_FUNCTRL1, 0); /* reset mixer */ snd_cmipci_mixer_write(cm, 0, 0); @@ -2597,12 +2601,20 @@ static int __devinit snd_cmipci_create(snd_card_t *card, if (snd_opl3_create(card, iosynth, iosynth + 2, OPL3_HW_OPL3, 0, &cm->opl3) < 0) { - printk(KERN_ERR "cmipci: no OPL device at 0x%lx\n", iosynth); + printk(KERN_ERR "cmipci: no OPL device at 0x%lx, skipping...\n", iosynth); + iosynth = 0; } else { - if ((err = snd_opl3_hwdep_new(cm->opl3, 0, 1, &cm->opl3hwdep)) < 0) + if ((err = snd_opl3_hwdep_new(cm->opl3, 0, 1, &cm->opl3hwdep)) < 0) { printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n"); + return err; + } } } + if (! iosynth) { + /* disable FM */ + snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val & ~CM_FMSEL_MASK); + snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN); + } /* reset mixer */ snd_cmipci_mixer_write(cm, 0, 0); @@ -2658,7 +2670,7 @@ MODULE_DEVICE_TABLE(pci, snd_cmipci_ids); static int __devinit snd_cmipci_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; cmipci_t *cm; int err; diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index 5aad9f4f905d..0b3a68d6d3cd 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -35,16 +35,9 @@ #include <sound/initval.h> #ifndef LINUX_2_2 -#if defined(CONFIG_INPUT_GAMEPORT) || defined(CONFIG_INPUT_GAMEPORT_MODULE) -#define HAVE_GAMEPORT_SUPPORT -#endif -#endif - -#ifdef HAVE_GAMEPORT_SUPPORT #include <linux/gameport.h> #endif - EXPORT_NO_SYMBOLS; MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); @@ -469,13 +462,6 @@ struct snd_cs4281_dma { int frag; /* period number */ }; -#ifdef HAVE_GAMEPORT_SUPPORT -typedef struct snd_cs4281_gameport { - struct gameport info; - cs4281_t *chip; -} cs4281_gameport_t; -#endif - struct snd_cs4281 { int irq; @@ -513,9 +499,7 @@ struct snd_cs4281 { unsigned int uartm; snd_info_entry_t *proc_entry; -#ifdef HAVE_GAMEPORT_SUPPORT - cs4281_gameport_t *gameport; -#endif + struct snd_cs4281_gameport *gameport; }; static void snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -1192,12 +1176,109 @@ static void snd_cs4281_proc_done(cs4281_t * chip) } /* + * joystick support + */ + +#ifndef LINUX_2_2 + +typedef struct snd_cs4281_gameport { + struct gameport info; + cs4281_t *chip; +} cs4281_gameport_t; + +static void snd_cs4281_gameport_trigger(struct gameport *gameport) +{ + cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport; + cs4281_t *chip; + snd_assert(gp, return); + chip = snd_magic_cast(cs4281_t, gp->chip, return); + snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff); +} + +static unsigned char snd_cs4281_gameport_read(struct gameport *gameport) +{ + cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport; + cs4281_t *chip; + snd_assert(gp, return 0); + chip = snd_magic_cast(cs4281_t, gp->chip, return 0); + return snd_cs4281_peekBA0(chip, BA0_JSPT); +} + +#ifdef COOKED_MODE +static int snd_cs4281_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) +{ + cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport; + cs4281_t *chip; + unsigned js1, js2, jst; + + snd_assert(gp, return 0); + chip = snd_magic_cast(cs4281_t, gp->chip, return 0); + + js1 = snd_cs4281_peekBA0(chip, BA0_JSC1); + js2 = snd_cs4281_peekBA0(chip, BA0_JSC2); + jst = snd_cs4281_peekBA0(chip, BA0_JSPT); + + *buttons = (~jst >> 4) & 0x0F; + + axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF; + axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF; + axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF; + axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF; + + for(jst=0;jst<4;++jst) + if(axes[jst]==0xFFFF) axes[jst] = -1; + return 0; +} +#endif + +static int snd_cs4281_gameport_open(struct gameport *gameport, int mode) +{ + switch (mode) { +#ifdef COOKED_MODE + case GAMEPORT_MODE_COOKED: + return 0; +#endif + case GAMEPORT_MODE_RAW: + return 0; + default: + return -1; + } + return 0; +} + +static void __devinit snd_cs4281_gameport(cs4281_t *chip) +{ + cs4281_gameport_t *gp; + gp = kmalloc(sizeof(*gp), GFP_KERNEL); + if (! gp) { + snd_printk("cannot allocate gameport area\n"); + return; + } + memset(gp, 0, sizeof(*gp)); + gp->info.open = snd_cs4281_gameport_open; + gp->info.read = snd_cs4281_gameport_read; + gp->info.trigger = snd_cs4281_gameport_trigger; +#ifdef COOKED_MODE + gp->info.cooked_read = snd_cs4281_gameport_cooked_read; +#endif + gp->chip = chip; + chip->gameport = gp; + + snd_cs4281_pokeBA0(chip, BA0_JSIO, 0xFF); // ? + snd_cs4281_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); + gameport_register_port(&gp->info); +} + +#endif /* !LINUX_2_2 */ + + +/* */ static int snd_cs4281_free(cs4281_t *chip) { -#ifdef HAVE_GAMEPORT_SUPPORT +#ifndef LINUX_2_2 if (chip->gameport) { gameport_unregister_port(&chip->gameport->info); kfree(chip->gameport); @@ -1733,100 +1814,11 @@ static void snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs) snd_cs4281_pokeBA0(chip, BA0_HICR, BA0_HICR_EOI); } -#ifdef HAVE_GAMEPORT_SUPPORT -/* - * joystick support - */ -static void snd_cs4281_gameport_trigger(struct gameport *gameport) -{ - cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport; - cs4281_t *chip; - snd_assert(gp, return); - chip = snd_magic_cast(cs4281_t, gp->chip, return); - snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff); -} - -static unsigned char snd_cs4281_gameport_read(struct gameport *gameport) -{ - cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport; - cs4281_t *chip; - snd_assert(gp, return 0); - chip = snd_magic_cast(cs4281_t, gp->chip, return 0); - return snd_cs4281_peekBA0(chip, BA0_JSPT); -} - -#ifdef COOKED_MODE -static int snd_cs4281_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) -{ - cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport; - cs4281_t *chip; - unsigned js1, js2, jst; - - snd_assert(gp, return); - chip = snd_magic_cast(cs4281_t, gp->chip, return); - - js1 = snd_cs4281_peekBA0(chip, BA0_JSC1); - js2 = snd_cs4281_peekBA0(chip, BA0_JSC2); - jst = snd_cs4281_peekBA0(chip, BA0_JSPT); - - *buttons = (~jst >> 4) & 0x0F; - - axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF; - axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF; - axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF; - axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF; - - for(jst=0;jst<4;++jst) - if(axes[jst]==0xFFFF) axes[jst] = -1; - return 0; -} -#endif - -static int snd_cs4281_gameport_open(struct gameport *gameport, int mode) -{ - switch (mode) { -#ifdef COOKED_MODE - case GAMEPORT_MODE_COOKED: - return 0; -#endif - case GAMEPORT_MODE_RAW: - return 0; - default: - return -1; - } - return 0; -} - -static void __devinit snd_cs4281_gameport(cs4281_t *chip) -{ - cs4281_gameport_t *gp; - gp = kmalloc(sizeof(*gp), GFP_KERNEL); - if (! gp) { - snd_printk("cannot allocate gameport area\n"); - return; - } - memset(gp, 0, sizeof(*gp)); - gp->info.open = snd_cs4281_gameport_open; - gp->info.read = snd_cs4281_gameport_read; - gp->info.trigger = snd_cs4281_gameport_trigger; -#ifdef COOKED_MODE - gp->info.cooked_read = snd_cs4281_gameport_cooked_read; -#endif - gp->chip = chip; - chip->gameport = gp; - - snd_cs4281_pokeBA0(chip, BA0_JSIO, 0xFF); // ? - snd_cs4281_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); - gameport_register_port(&gp->info); -} - -#endif /* HAVE_GAMEPORT_SUPPORT */ - static int __devinit snd_cs4281_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; cs4281_t *chip; opl3_t *opl3; @@ -1871,7 +1863,7 @@ static int __devinit snd_cs4281_probe(struct pci_dev *pci, snd_card_free(card); return err; } -#ifdef HAVE_GAMEPORT_SUPPORT +#ifndef LINUX_2_2 snd_cs4281_gameport(chip); #endif strcpy(card->driver, "CS4281"); diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index 61a2120e8743..0d0f8493aefe 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c @@ -51,6 +51,9 @@ static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int snd_external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; static int snd_thinkpad[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; +#ifndef CONFIG_SND_CS46XX_ACCEPT_VALID +static int snd_mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; +#endif MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(snd_index, "Index value for the CS46xx soundcard."); @@ -67,6 +70,11 @@ MODULE_PARM_SYNTAX(snd_external_amp, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC) MODULE_PARM(snd_thinkpad, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(snd_thinkpad, "Force to enable Thinkpad's CLKRUN control."); MODULE_PARM_SYNTAX(snd_thinkpad, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC); +#ifndef CONFIG_SND_CS46XX_ACCEPT_VALID +MODULE_PARM(snd_mmap_valid, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); +MODULE_PARM_DESC(snd_mmap_valid, "Support OSS mmap."); +MODULE_PARM_SYNTAX(snd_mmap_valid, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC); +#endif static struct pci_device_id snd_cs46xx_ids[] __devinitdata = { { 0x1013, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4280 */ @@ -80,7 +88,7 @@ MODULE_DEVICE_TABLE(pci, snd_cs46xx_ids); static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; cs46xx_t *chip; int err; @@ -101,6 +109,11 @@ static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci, snd_card_free(card); return err; } +#ifdef CONFIG_SND_CS46XX_ACCEPT_VALID + chip->accept_valid = 1; +#else + chip->accept_valid = snd_mmap_valid[dev]; +#endif if ((err = snd_cs46xx_pcm(chip, 0, NULL)) < 0) { snd_card_free(card); return err; @@ -113,6 +126,8 @@ static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci, snd_card_free(card); return err; } + snd_cs46xx_gameport(chip); + strcpy(card->driver, "CS46xx"); strcpy(card->shortname, "Sound Fusion CS46xx"); sprintf(card->longname, "%s at 0x%lx/0x%lx, irq %i", diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 083a2b7236be..6f7ffc33efac 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -41,6 +41,9 @@ #include <sound/control.h> #include <sound/info.h> #include <sound/cs46xx.h> +#ifndef LINUX_2_2 +#include <linux/gameport.h> +#endif #define chip_t cs46xx_t @@ -48,10 +51,6 @@ * constants */ -#if 0 -#define SND_CONFIG_CS46XX_ACCEPT_VALID /* REQUIRED ONLY FOR OSS EMULATION */ -#endif - #define CS46XX_BA0_SIZE 0x1000 #define CS46XX_BA1_DATA0_SIZE 0x3000 #define CS46XX_BA1_DATA1_SIZE 0x3800 @@ -1049,10 +1048,6 @@ static void snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) static snd_pcm_hardware_t snd_cs46xx_playback = { info: (SNDRV_PCM_INFO_MMAP | -#ifdef SND_CONFIG_CS46XX_ACCEPT_VALID - /* NOT TRUE!!! OSS REQUIRES IT */ - SNDRV_PCM_INFO_MMAP_VALID | -#endif SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_RESUME), @@ -1075,10 +1070,6 @@ static snd_pcm_hardware_t snd_cs46xx_playback = static snd_pcm_hardware_t snd_cs46xx_capture = { info: (SNDRV_PCM_INFO_MMAP | -#ifdef SND_CONFIG_CS46XX_ACCEPT_VALID - /* NOT TRUE!!! OSS REQUIRES IT */ - SNDRV_PCM_INFO_MMAP_VALID | -#endif SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_RESUME), @@ -1104,6 +1095,8 @@ static int snd_cs46xx_playback_open(snd_pcm_substream_t * substream) return -ENOMEM; chip->play.substream = substream; substream->runtime->hw = snd_cs46xx_playback; + if (chip->accept_valid) + substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; chip->active_ctrl(chip, 1); chip->amplifier_ctrl(chip, 1); return 0; @@ -1117,6 +1110,8 @@ static int snd_cs46xx_capture_open(snd_pcm_substream_t * substream) return -ENOMEM; chip->capt.substream = substream; substream->runtime->hw = snd_cs46xx_capture; + if (chip->accept_valid) + substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; chip->active_ctrl(chip, 1); chip->amplifier_ctrl(chip, 1); return 0; @@ -1501,6 +1496,103 @@ int __devinit snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rrawmi return 0; } + +/* + * gameport interface + */ + +#ifndef LINUX_2_2 + +typedef struct snd_cs46xx_gameport { + struct gameport info; + cs46xx_t *chip; +} cs46xx_gameport_t; + +static void snd_cs46xx_gameport_trigger(struct gameport *gameport) +{ + cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport; + cs46xx_t *chip; + snd_assert(gp, return); + chip = snd_magic_cast(cs46xx_t, gp->chip, return); + snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); +} + +static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport) +{ + cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport; + cs46xx_t *chip; + snd_assert(gp, return 0); + chip = snd_magic_cast(cs46xx_t, gp->chip, return 0); + return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); +} + +static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) +{ + cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport; + cs46xx_t *chip; + unsigned js1, js2, jst; + + snd_assert(gp, return 0); + chip = snd_magic_cast(cs46xx_t, gp->chip, return 0); + + js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1); + js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2); + jst = snd_cs46xx_peekBA0(chip, BA0_JSPT); + + *buttons = (~jst >> 4) & 0x0F; + + axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF; + axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF; + axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF; + axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF; + + for(jst=0;jst<4;++jst) + if(axes[jst]==0xFFFF) axes[jst] = -1; + return 0; +} + +static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode) +{ + switch (mode) { + case GAMEPORT_MODE_COOKED: + return 0; + case GAMEPORT_MODE_RAW: + return 0; + default: + return -1; + } + return 0; +} + +void __devinit snd_cs46xx_gameport(cs46xx_t *chip) +{ + cs46xx_gameport_t *gp; + gp = kmalloc(sizeof(*gp), GFP_KERNEL); + if (! gp) { + snd_printk("cannot allocate gameport area\n"); + return; + } + memset(gp, 0, sizeof(*gp)); + gp->info.open = snd_cs46xx_gameport_open; + gp->info.read = snd_cs46xx_gameport_read; + gp->info.trigger = snd_cs46xx_gameport_trigger; + gp->info.cooked_read = snd_cs46xx_gameport_cooked_read; + gp->chip = chip; + chip->gameport = gp; + + snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ? + snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); + gameport_register_port(&gp->info); +} + +#else /* LINUX_2_2 */ + +void __devinit snd_cs46xx_gameport(cs46xx_t *chip) +{ +} + +#endif /* !LINUX_2_2 */ + /* * proc interface */ @@ -1635,6 +1727,12 @@ static int snd_cs46xx_free(cs46xx_t *chip) if (chip->active_ctrl) chip->active_ctrl(chip, 1); +#ifndef LINUX_2_2 + if (chip->gameport) { + gameport_unregister_port(&chip->gameport->info); + kfree(chip->gameport); + } +#endif #ifdef CONFIG_PM if (chip->pm_dev) pm_unregister(chip->pm_dev); diff --git a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile index fb6a5b0a6737..854541e5e73a 100644 --- a/sound/pci/emu10k1/Makefile +++ b/sound/pci/emu10k1/Makefile @@ -17,7 +17,7 @@ snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o # Toplevel Module Dependency obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1.o ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y) - obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1.o snd-emu10k1-synth.o + obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1-synth.o endif include $(TOPDIR)/Rules.make diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 84e0f8fbfbab..1bcbf5b05b10 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c @@ -88,7 +88,7 @@ MODULE_DEVICE_TABLE(pci, snd_emu10k1_ids); static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; emu10k1_t *emu; #ifdef ENABLE_SYNTH diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 25e08303ecbf..851f97b03593 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -547,7 +547,7 @@ int __devinit snd_emu10k1_create(snd_card_t * card, snd_printk("architecture does not support 31bit PCI busmaster DMA\n"); return -ENXIO; } - if (pci->driver_data) + if (pci_get_drvdata(pci)) pci_set_dma_mask(pci, 0xffffffff); /* audigy */ else pci_set_dma_mask(pci, 0x7fffffff); diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 3e92d39c8659..4995ab708ab3 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -617,7 +617,6 @@ static int snd_emu10k1_capture_trigger(snd_pcm_substream_t * substream, break; case CAPTURE_EFX: snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val); - printk(">> FXWC = 0x%x\n", snd_emu10k1_ptr_read(emu, FXWC, 0)); break; default: break; @@ -888,6 +887,7 @@ static int snd_emu10k1_capture_efx_open(snd_pcm_substream_t * substream) emu10k1_pcm_t *epcm; snd_pcm_runtime_t *runtime = substream->runtime; unsigned long flags; + int nefx = emu->audigy ? 64 : 32; int idx; epcm = snd_magic_kcalloc(emu10k1_pcm_t, 0, GFP_KERNEL); @@ -908,13 +908,14 @@ static int snd_emu10k1_capture_efx_open(snd_pcm_substream_t * substream) runtime->hw.rate_min = runtime->hw.rate_max = 48000; spin_lock_irqsave(&emu->reg_lock, flags); runtime->hw.channels_min = runtime->hw.channels_max = 0; - for (idx = 0; idx < 32; idx++) { - if (emu->efx_voices_mask & (1 << idx)) { + for (idx = 0; idx < nefx; idx++) { + if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) { runtime->hw.channels_min++; runtime->hw.channels_max++; } } - epcm->capture_cr_val = emu->efx_voices_mask; + epcm->capture_cr_val = emu->efx_voices_mask[0]; + epcm->capture_cr_val2 = emu->efx_voices_mask[1]; spin_unlock_irqrestore(&emu->reg_lock, flags); emu->capture_efx_interrupt = snd_emu10k1_pcm_efx_interrupt; emu->pcm_capture_efx_substream = substream; @@ -1037,8 +1038,10 @@ int __devinit snd_emu10k1_pcm_mic(emu10k1_t * emu, int device, snd_pcm_t ** rpcm static int snd_emu10k1_pcm_efx_voices_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { + emu10k1_t *emu = snd_kcontrol_chip(kcontrol); + int nefx = emu->audigy ? 64 : 32; uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 32; + uinfo->count = nefx; uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0; @@ -1048,11 +1051,12 @@ static int snd_emu10k1_pcm_efx_voices_mask_get(snd_kcontrol_t * kcontrol, snd_ct { emu10k1_t *emu = snd_kcontrol_chip(kcontrol); unsigned long flags; + int nefx = emu->audigy ? 64 : 32; int idx; spin_lock_irqsave(&emu->reg_lock, flags); - for (idx = 0; idx < 32; idx++) - ucontrol->value.integer.value[idx] = (emu->efx_voices_mask & (1 << idx)) ? 1 : 0; + for (idx = 0; idx < nefx; idx++) + ucontrol->value.integer.value[idx] = (emu->efx_voices_mask[idx / 32] & (1 << (idx % 32))) ? 1 : 0; spin_unlock_irqrestore(&emu->reg_lock, flags); return 0; } @@ -1061,19 +1065,23 @@ static int snd_emu10k1_pcm_efx_voices_mask_put(snd_kcontrol_t * kcontrol, snd_ct { emu10k1_t *emu = snd_kcontrol_chip(kcontrol); unsigned long flags; - unsigned int nval, bits; + unsigned int nval[2], bits; + int nefx = emu->audigy ? 64 : 32; int change, idx; - for (idx = 0, nval = bits = 0; idx < 32; idx++) + nval[0] = nval[1] = 0; + for (idx = 0, bits = 0; idx < nefx; idx++) if (ucontrol->value.integer.value[idx]) { - nval |= 1 << idx; + nval[idx / 32] |= 1 << (idx % 32); bits++; } if (bits != 1 && bits != 2 && bits != 4 && bits != 8) return -EINVAL; spin_lock_irqsave(&emu->reg_lock, flags); - change = nval != emu->efx_voices_mask; - emu->efx_voices_mask = nval; + change = (nval[0] != emu->efx_voices_mask[0]) || + (nval[1] != emu->efx_voices_mask[1]); + emu->efx_voices_mask[0] = nval[0]; + emu->efx_voices_mask[1] = nval[1]; spin_unlock_irqrestore(&emu->reg_lock, flags); return change; } @@ -1126,7 +1134,8 @@ int __devinit snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm if (rpcm) *rpcm = pcm; - emu->efx_voices_mask = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; + emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; + emu->efx_voices_mask[1] = 0; snd_ctl_add(emu->card, snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu)); snd_pcm_lib_preallocate_pci_pages_for_all(emu->pci, pcm, 64*1024, 64*1024); diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index a522736355b5..5e0b08a008a0 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -107,6 +107,7 @@ static void snd_emu10k1_proc_read(snd_info_entry_t *entry, }; emu10k1_t *emu = snd_magic_cast(emu10k1_t, entry->private_data, return); unsigned int val; + int nefx = emu->audigy ? 64 : 32; int idx; snd_iprintf(buffer, "EMU10K1\n\n"); @@ -132,9 +133,9 @@ static void snd_emu10k1_proc_read(snd_info_entry_t *entry, (val >> 28) & 0x0f); } snd_iprintf(buffer, "\nCaptured FX Outputs :\n"); - for (idx = 0; idx < 32; idx++) { - if (emu->efx_voices_mask & (1 << idx)) - snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]); + for (idx = 0; idx < nefx; idx++) { + if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) + snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx%32]); } snd_iprintf(buffer, "\nAll FX Outputs :\n"); for (idx = 0; idx < 32; idx++) diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 64e94e63a398..3e8ab6870712 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -1961,7 +1961,7 @@ static void snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs) static int __devinit snd_audiopci_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; ensoniq_t *ensoniq; int err, pcm_devs[2]; diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 0aaa38c0f18f..e112b7171a37 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -1583,7 +1583,7 @@ static int __init snd_es1938_mixer(snd_pcm_t *pcm) static int __devinit snd_es1938_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; es1938_t *chip; snd_pcm_t *pcm; diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 905e176d272d..0552bdcfc186 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -1939,11 +1939,11 @@ static void snd_es1968_update_pcm(es1968_t *chip, esschan_t *es) es->hwptr = hwptr; es->count += diff; - while (es->count > es->frag_size) { + if (es->count > es->frag_size) { spin_unlock(&chip->substream_lock); snd_pcm_period_elapsed(subs); spin_lock(&chip->substream_lock); - es->count -= es->frag_size; + es->count %= es->frag_size; } } @@ -2663,7 +2663,7 @@ static snd_kcontrol_new_t snd_es1968_control_switches[] __devinitdata = { static int __devinit snd_es1968_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; es1968_t *chip; int i, err; diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index c8432ef99477..b646dfe259fa 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1025,7 +1025,7 @@ static int __devinit snd_fm801_create(snd_card_t * card, static int __devinit snd_card_fm801_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; fm801_t *chip; opl3_t *opl3; diff --git a/sound/pci/ice1712.c b/sound/pci/ice1712.c index 6cf4a16cac2e..2fff96764285 100644 --- a/sound/pci/ice1712.c +++ b/sound/pci/ice1712.c @@ -98,6 +98,7 @@ MODULE_PARM_SYNTAX(snd_omni, SNDRV_ENABLED "," SNDRV_ENABLE_DESC); #define ICE1712_SUBDEVICE_DELTA66 0x121432d6 #define ICE1712_SUBDEVICE_DELTA44 0x121433d6 #define ICE1712_SUBDEVICE_AUDIOPHILE 0x121434d6 +#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6 #define ICE1712_SUBDEVICE_EWX2496 0x3b153011 #define ICE1712_SUBDEVICE_EWS88MT 0x3b151511 #define ICE1712_SUBDEVICE_EWS88D 0x3b152b11 @@ -4196,7 +4197,7 @@ static int __devinit snd_ice1712_create(snd_card_t * card, static int __devinit snd_ice1712_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; ice1712_t *ice; int pcm_dev = 0, err; @@ -4266,6 +4267,9 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, case ICE1712_SUBDEVICE_AUDIOPHILE: strcpy(card->shortname, "M Audio Audiophile 24/96"); break; + case ICE1712_SUBDEVICE_DELTA1010LT: + strcpy(card->shortname, "M Audio Delta 1010LT"); + break; case ICE1712_SUBDEVICE_EWX2496: strcpy(card->shortname, "TerraTec EWX 24/96"); break; diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 26bc53ed12cd..b971fa91fefe 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -51,7 +51,9 @@ MODULE_DEVICES("{{Intel,82801AA}," "{Intel,ICH3}," "{Intel,MX440}," "{SiS,SI7012}," - "{NVidia,NForce Audio}}"); + "{NVidia,NForce Audio}," + "{AMD,AMD768}," + "{AMD,AMD8111}}"); #define SUPPORT_JOYSTICK 1 #define SUPPORT_MIDI 1 @@ -285,7 +287,8 @@ static struct pci_device_id snd_intel8x0_ids[] __devinitdata = { { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */ { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7012 */ { 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE */ - { 0x764d, 0x1022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ + { 0x1022, 0x764d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ + { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */ { 0, } }; @@ -1392,14 +1395,15 @@ static struct shortname_table { { PCI_DEVICE_ID_INTEL_ICH3, "Intel ICH3" }, { PCI_DEVICE_ID_SI_7012, "SiS SI7012" }, { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" }, - { 0x1022, "AMD-8111" }, + { 0x764d, "AMD AMD8111" }, + { 0x7445, "AMD AMD768" }, { 0, 0 }, }; static int __devinit snd_intel8x0_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; intel8x0_t *chip; int pcm_dev = 0, err; @@ -1498,7 +1502,7 @@ static struct pci_driver driver = { static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; if (dev >= SNDRV_CARDS) return -ENODEV; if (!snd_enable[dev]) { diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 655b36921451..7ba21b339789 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -2249,7 +2249,7 @@ static int __devinit snd_korg1212_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; korg1212_t *korg1212; snd_card_t *card; int err; diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 310ec07efff0..de7e47180ef4 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -888,14 +888,22 @@ struct snd_m3 { #endif static struct pci_device_id snd_m3_ids[] __devinitdata = { - {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_CANYON3D_2LE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_CANYON3D_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_HW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, + {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, + {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_CANYON3D_2LE, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, + {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_CANYON3D_2, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, + {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, + {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_1, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, + {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_HW, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, + {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_MAESTRO3_2, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, {0,}, }; @@ -1481,8 +1489,8 @@ static void snd_m3_update_ptr(m3_t *chip, m3_dma_t *s) diff = (s->dma_size + hwptr - s->hwptr) % s->dma_size; s->hwptr = hwptr; s->count += diff; - while (s->count >= (signed)s->period_size) { - s->count -= s->period_size; + if (s->count >= (signed)s->period_size) { + s->count %= s->period_size; spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(subs); spin_lock(&chip->reg_lock); @@ -2595,14 +2603,14 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, static int __devinit snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; m3_t *chip; int err; /* don't pick up modems */ if (((pci->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO) - return 0; + return -ENODEV; if (dev >= SNDRV_CARDS) return -ENODEV; diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 8912c62b6fe0..8d603123ec95 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -1554,7 +1554,7 @@ __error: static int __devinit snd_nm256_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; nm256_t *chip; int err; diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 18891a006530..ea37f1eb9713 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -2410,7 +2410,7 @@ static int __devinit snd_rme96_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; rme96_t *rme96; snd_card_t *card; int err; diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index c4c716252834..0712b26692f4 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -2663,7 +2663,7 @@ static void snd_rme9652_card_free(snd_card_t *card) static int __devinit snd_rme9652_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; rme9652_t *rme9652; snd_card_t *card; int err; diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index d204ae0b7953..006b1ecce989 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -1453,7 +1453,7 @@ static int __devinit snd_sonicvibes_midi(sonicvibes_t * sonic, snd_rawmidi_t * r static int __devinit snd_sonic_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; sonicvibes_t *sonic; snd_rawmidi_t *midi_uart; diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index 127b0513a93e..8309cbc74166 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c @@ -80,7 +80,7 @@ MODULE_DEVICE_TABLE(pci, snd_trident_ids); static int __devinit snd_trident_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; trident_t *trident; const char *str; @@ -138,6 +138,8 @@ static int __devinit snd_trident_probe(struct pci_dev *pci, } #endif + snd_trident_gameport(trident); + switch (trident->device) { case TRIDENT_DEVICE_ID_DX: str = "TRID4DWAVEDX"; diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index afeeeb1f1526..a5248050c6f8 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -37,6 +37,9 @@ #include <sound/control.h> #include <sound/trident.h> #include <sound/asoundef.h> +#ifndef LINUX_2_2 +#include <linux/gameport.h> +#endif #define chip_t trident_t @@ -2946,6 +2949,100 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device return 0; } +/* + * gameport interface + */ +#ifndef LINUX_2_2 + +typedef struct snd_trident_gameport { + struct gameport info; + trident_t *chip; +} trident_gameport_t; + +static unsigned char snd_trident_gameport_read(struct gameport *gameport) +{ + trident_gameport_t *gp = (trident_gameport_t *)gameport; + trident_t *chip; + snd_assert(gp, return 0); + chip = snd_magic_cast(trident_t, gp->chip, return 0); + return inb(TRID_REG(chip, GAMEPORT_LEGACY)); +} + +static void snd_trident_gameport_trigger(struct gameport *gameport) +{ + trident_gameport_t *gp = (trident_gameport_t *)gameport; + trident_t *chip; + snd_assert(gp, return); + chip = snd_magic_cast(trident_t, gp->chip, return); + outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY)); +} + +static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) +{ + trident_gameport_t *gp = (trident_gameport_t *)gameport; + trident_t *chip; + int i; + + snd_assert(gp, return 0); + chip = snd_magic_cast(trident_t, gp->chip, return 0); + + *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf; + + for (i = 0; i < 4; i++) { + axes[i] = inw(TRID_REG(chip, GAMEPORT_AXES + i * 2)); + if (axes[i] == 0xffff) axes[i] = -1; + } + + return 0; +} + +static int snd_trident_gameport_open(struct gameport *gameport, int mode) +{ + trident_gameport_t *gp = (trident_gameport_t *)gameport; + trident_t *chip; + snd_assert(gp, return -1); + chip = snd_magic_cast(trident_t, gp->chip, return -1); + + switch (mode) { + case GAMEPORT_MODE_COOKED: + outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR)); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1 + 20 * HZ / 1000); /* 20msec */ + return 0; + case GAMEPORT_MODE_RAW: + outb(0, TRID_REG(chip, GAMEPORT_GCR)); + return 0; + default: + return -1; + } +} + +void __devinit snd_trident_gameport(trident_t *chip) +{ + trident_gameport_t *gp; + gp = kmalloc(sizeof(*gp), GFP_KERNEL); + if (! gp) { + snd_printk("cannot allocate gameport area\n"); + return; + } + memset(gp, 0, sizeof(*gp)); + gp->chip = chip; + gp->info.fuzz = 64; + gp->info.read = snd_trident_gameport_read; + gp->info.trigger = snd_trident_gameport_trigger; + gp->info.cooked_read = snd_trident_gameport_cooked_read; + gp->info.open = snd_trident_gameport_open; + chip->gameport = gp; + + gameport_register_port(&gp->info); +} + +#else +void __devinit snd_trident_gameport(trident_t *chip) +{ +} +#endif + /* * /proc interface */ @@ -3319,6 +3416,12 @@ int __devinit snd_trident_create(snd_card_t * card, int snd_trident_free(trident_t *trident) { +#ifndef LINUX_2_2 + if (trident->gameport) { + gameport_unregister_port(&trident->gameport->info); + kfree(trident->gameport); + } +#endif snd_trident_disable_eso(trident); // Disable S/PDIF out if (trident->device == TRIDENT_DEVICE_ID_NX) diff --git a/sound/pci/via686.c b/sound/pci/via686.c index a0fe9c1617d2..cd77658c2484 100644 --- a/sound/pci/via686.c +++ b/sound/pci/via686.c @@ -188,7 +188,6 @@ struct _snd_via686a { unsigned int ac97_secondary; /* secondary AC'97 codec is present */ spinlock_t reg_lock; - spinlock_t ac97_lock; snd_info_entry_t *proc_entry; void *tables; @@ -267,10 +266,10 @@ static void snd_via686a_codec_write(ac97_t *ac97, xval <<= VIA_REG_AC97_CODEC_ID_SHIFT; xval |= reg << VIA_REG_AC97_CMD_SHIFT; xval |= val << VIA_REG_AC97_DATA_SHIFT; - spin_lock(&chip->ac97_lock); + spin_lock(&chip->reg_lock); snd_via686a_codec_xwrite(chip, xval); snd_via686a_codec_ready(chip, ac97->num); - spin_unlock(&chip->ac97_lock); + spin_unlock(&chip->reg_lock); } static unsigned short snd_via686a_codec_read(ac97_t *ac97, unsigned short reg) @@ -284,10 +283,10 @@ static unsigned short snd_via686a_codec_read(ac97_t *ac97, unsigned short reg) xval = (!ac97->num ? VIA_REG_AC97_PRIMARY_VALID : VIA_REG_AC97_SECONDARY_VALID); xval |= VIA_REG_AC97_READ; xval |= reg << VIA_REG_AC97_CMD_SHIFT; - spin_lock(&chip->ac97_lock); + spin_lock(&chip->reg_lock); while (1) { if (again++ > 3) { - spin_unlock(&chip->ac97_lock); + spin_unlock(&chip->reg_lock); return 0xffff; } snd_via686a_codec_xwrite(chip, xval); @@ -299,7 +298,7 @@ static unsigned short snd_via686a_codec_read(ac97_t *ac97, unsigned short reg) break; } } - spin_unlock(&chip->ac97_lock); + spin_unlock(&chip->reg_lock); return val & 0xffff; } @@ -481,7 +480,6 @@ static int snd_via686a_capture_prepare(snd_pcm_substream_t * substream) static inline unsigned int snd_via686a_cur_ptr(via686a_t *chip, viadev_t *viadev) { unsigned int val, ptr, count; - // unsigned int tmp; ptr = inl(VIAREG(chip, OFFSET_CURR_PTR) + viadev->reg_offset); count = inl(VIAREG(chip, OFFSET_CURR_COUNT) + viadev->reg_offset); @@ -489,13 +487,12 @@ static inline unsigned int snd_via686a_cur_ptr(via686a_t *chip, viadev_t *viadev ptr += 8; if (!(inb(VIAREG(chip, OFFSET_STATUS) + viadev->reg_offset) & VIA_REG_STAT_ACTIVE)) return 0; - // tmp = val = (((unsigned int)(ptr - viadev->table_addr) / 8) - 1) % viadev->frags; val *= viadev->fragsize; val += viadev->fragsize - count; viadev->lastptr = ptr; viadev->lastcount = count; - // printk("pointer: ptr = 0x%x (%i), count = 0x%x, val = 0x%x\n", ptr, tmp, count, val); + // printk("pointer: ptr = 0x%x (%i), count = 0x%x, val = 0x%x\n", ptr, count, val); return val; } @@ -1041,7 +1038,6 @@ static int __devinit snd_via686a_create(snd_card_t * card, chip->old_legacy_cfg = old_legacy_cfg; spin_lock_init(&chip->reg_lock); - spin_lock_init(&chip->ac97_lock); chip->card = card; chip->pci = pci; chip->irq = -1; @@ -1100,7 +1096,7 @@ static int __devinit snd_via686a_create(snd_card_t * card, static int __devinit snd_via686a_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; via686a_t *chip; int pcm_dev = 0; diff --git a/sound/pci/via8233.c b/sound/pci/via8233.c index 61409bfb8b74..461d3a761fdc 100644 --- a/sound/pci/via8233.c +++ b/sound/pci/via8233.c @@ -1,8 +1,8 @@ /* * ALSA driver for VIA VT8233 (South Bridge) * - * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>, - * Tjeerd.Mulder@fujitsu-siemens.com + * Copyright (c) 2000 Tjeerd.Mulder@fujitsu-siemens.com + * This driver is based on VIA686 code by Jaroslav Kysela <perex@suse.cz> * * 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 @@ -175,7 +175,6 @@ struct _snd_via8233 { unsigned int ac97_clock; spinlock_t reg_lock; - spinlock_t update_lock; snd_info_entry_t *proc_entry; void *tables; @@ -417,8 +416,6 @@ static int snd_via8233_playback_prepare(snd_pcm_substream_t * substream) snd_pcm_runtime_t *runtime = substream->runtime; unsigned long tmp; - if (inb(VIAREG(chip, PLAYBACK_STATUS)) & VIA_REG_STAT_ACTIVE) - return 0; snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate); snd_via8233_setup_periods(chip, &chip->playback, substream); /* I don't understand this stuff but its from the documentation and this way it works */ @@ -746,7 +743,6 @@ static int __devinit snd_via8233_create(snd_card_t * card, return -ENOMEM; spin_lock_init(&chip->reg_lock); - spin_lock_init(&chip->update_lock); chip->card = card; chip->pci = pci; chip->irq = -1; @@ -808,7 +804,7 @@ static int __devinit snd_via8233_create(snd_card_t * card, static int __devinit snd_via8233_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; via8233_t *chip; int pcm_dev = 0; diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 9d9df8f76c5a..c60028dd5b84 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -79,7 +79,7 @@ MODULE_DEVICE_TABLE(pci, snd_ymfpci_ids); static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, const struct pci_device_id *id) { - static int dev = 0; + static int dev; snd_card_t *card; ymfpci_t *chip; opl3_t *opl3; @@ -127,7 +127,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, if (snd_mpu_port[dev] >= 0) { legacy_ctrl |= 8; pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, snd_mpu_port[dev]); - snd_printd("MPU401 supported on 0x%lx\n", snd_mpu_port[dev]); + //snd_printd("MPU401 supported on 0x%lx\n", snd_mpu_port[dev]); } } else { switch (snd_fm_port[dev]) { @@ -151,7 +151,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, default: snd_mpu_port[dev] = -1; break; } if (snd_mpu_port[dev] > 0 && check_region(snd_mpu_port[dev], 2) == 0) { - snd_printd("MPU401 supported on 0x%lx\n", snd_mpu_port[dev]); + //snd_printd("MPU401 supported on 0x%lx\n", snd_mpu_port[dev]); legacy_ctrl |= 8; } else { legacy_ctrl2 &= ~(3 << 4); @@ -159,7 +159,8 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, } } if (snd_mpu_port[dev] > 0) { - legacy_ctrl |= 0x10; /* MPU401 irq enable */ + // this bit is for legacy mpu irqs + // legacy_ctrl |= 0x10; /* MPU401 irq enable */ legacy_ctrl2 |= 1 << 15; /* IMOD */ } pci_read_config_word(pci, PCIR_DSXG_LEGACY, &old_legacy_ctrl); @@ -198,9 +199,10 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, snd_mpu_port[dev], 0, pci->irq, 0, &chip->rawmidi)) < 0) { printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", snd_mpu_port[dev]); - } else { - legacy_ctrl &= ~0x10; /* disable MPU401 irq */ - pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl); + snd_mpu_port[dev] = 0; + // only for legacy mpu irqs + // legacy_ctrl &= ~0x10; /* disable MPU401 irq */ + // pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl); } } if (snd_fm_port[dev] > 0) { @@ -209,6 +211,9 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, snd_fm_port[dev] + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) { printk(KERN_WARNING "ymfpci: cannot initialize FM OPL3 at 0x%lx, skipping...\n", snd_fm_port[dev]); + snd_fm_port[dev] = 0; + legacy_ctrl &= ~2; + pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl); } else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { snd_card_free(card); snd_printk("cannot create opl3 hwdep\n"); diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 4c6dd27f3306..ababc0a695fd 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -313,12 +313,12 @@ static void snd_ymfpci_pcm_interrupt(ymfpci_t *chip, ymfpci_voice_t *voice) delta = pos - ypcm->last_pos; ypcm->period_pos += delta; ypcm->last_pos = pos; - while (ypcm->period_pos >= ypcm->period_size) { + if (ypcm->period_pos >= ypcm->period_size) { // printk("done - active_bank = 0x%x, start = 0x%x\n", chip->active_bank, voice->bank[chip->active_bank].start); + ypcm->period_pos %= ypcm->period_size; spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(ypcm->substream); spin_lock(&chip->reg_lock); - ypcm->period_pos -= ypcm->period_size; } } spin_unlock(&chip->reg_lock); @@ -340,8 +340,8 @@ static void snd_ymfpci_pcm_capture_interrupt(snd_pcm_substream_t *substream) delta = pos - ypcm->last_pos; ypcm->period_pos += delta; ypcm->last_pos = pos; - while (ypcm->period_pos >= ypcm->period_size) { - ypcm->period_pos = 0; + if (ypcm->period_pos >= ypcm->period_size) { + ypcm->period_pos %= ypcm->period_size; // printk("done - active_bank = 0x%x, start = 0x%x\n", chip->active_bank, voice->bank[chip->active_bank].start); spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(substream); diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 36ca68f07ff4..a82dcf5337ad 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c @@ -1302,12 +1302,12 @@ int __init snd_pmac_new(snd_card_t *card, pmac_t **chip_return) * Save state when going to sleep, restore it afterwards. */ -static void snd_pmac_suspend(pmac_t *chip, int can_schedule) +static void snd_pmac_suspend(pmac_t *chip) { unsigned long flags; snd_card_t *card = chip->card; - snd_power_lock(card, can_schedule); + snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D3hot) goto __skip; @@ -1327,11 +1327,11 @@ static void snd_pmac_suspend(pmac_t *chip, int can_schedule) snd_power_unlock(card); } -static void snd_pmac_resume(pmac_t *chip, int can_schedule) +static void snd_pmac_resume(pmac_t *chip) { snd_card_t *card = chip->card; - snd_power_lock(card, can_schedule); + snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D0) goto __skip; @@ -1370,10 +1370,10 @@ static int snd_pmac_sleep_notify(struct pmu_sleep_notifier *self, int when) switch (when) { case PBOOK_SLEEP_NOW: - snd_pmac_suspend(chip, 0); + snd_pmac_suspend(chip); break; case PBOOK_WAKE: - snd_pmac_resume(chip, 0); + snd_pmac_resume(chip); break; } return PBOOK_SLEEP_OK; @@ -1416,11 +1416,11 @@ static int snd_pmac_set_power_state(snd_card_t *card, unsigned int power_state) case SNDRV_CTL_POWER_D0: case SNDRV_CTL_POWER_D1: case SNDRV_CTL_POWER_D2: - snd_pmac_resume(chip, 1); + snd_pmac_resume(chip); break; case SNDRV_CTL_POWER_D3hot: case SNDRV_CTL_POWER_D3cold: - snd_pmac_suspend(chip, 1); + snd_pmac_suspend(chip); break; default: return -EINVAL; |
