diff options
Diffstat (limited to 'sound/isa/sb')
| -rw-r--r-- | sound/isa/sb/Makefile | 31 | ||||
| -rw-r--r-- | sound/isa/sb/emu8000.c | 208 | ||||
| -rw-r--r-- | sound/isa/sb/emu8000_callback.c | 110 | ||||
| -rw-r--r-- | sound/isa/sb/emu8000_local.h | 14 | ||||
| -rw-r--r-- | sound/isa/sb/emu8000_patch.c | 28 | ||||
| -rw-r--r-- | sound/isa/sb/emu8000_pcm.c | 119 | ||||
| -rw-r--r-- | sound/isa/sb/emu8000_synth.c | 22 | ||||
| -rw-r--r-- | sound/isa/sb/es968.c | 235 | ||||
| -rw-r--r-- | sound/isa/sb/jazz16.c | 401 | ||||
| -rw-r--r-- | sound/isa/sb/sb16.c | 487 | ||||
| -rw-r--r-- | sound/isa/sb/sb16_csp.c | 350 | ||||
| -rw-r--r-- | sound/isa/sb/sb16_csp_codecs.h | 949 | ||||
| -rw-r--r-- | sound/isa/sb/sb16_main.c | 163 | ||||
| -rw-r--r-- | sound/isa/sb/sb8.c | 238 | ||||
| -rw-r--r-- | sound/isa/sb/sb8_main.c | 231 | ||||
| -rw-r--r-- | sound/isa/sb/sb8_midi.c | 65 | ||||
| -rw-r--r-- | sound/isa/sb/sb_common.c | 73 | ||||
| -rw-r--r-- | sound/isa/sb/sb_mixer.c | 640 |
18 files changed, 1951 insertions, 2413 deletions
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index fd9d9c5726f..08b9fb97465 100644 --- a/sound/isa/sb/Makefile +++ b/sound/isa/sb/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> +# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz> # snd-sb-common-objs := sb_common.o sb_mixer.o @@ -11,29 +11,18 @@ snd-sb8-objs := sb8.o snd-sb16-objs := sb16.o snd-sbawe-objs := sbawe.o emu8000.o snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o -snd-es968-objs := es968.o - -# -# this function returns: -# "m" - CONFIG_SND_SEQUENCER is m -# <empty string> - CONFIG_SND_SEQUENCER is undefined -# otherwise parameter #1 value -# -sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) +snd-jazz16-objs := jazz16.o # Toplevel Module Dependency -obj-$(CONFIG_SND_ALS100) += snd-sb16-dsp.o snd-sb-common.o -obj-$(CONFIG_SND_CMI8330) += snd-sb16-dsp.o snd-sb-common.o -obj-$(CONFIG_SND_DT019X) += snd-sb16-dsp.o snd-sb-common.o -obj-$(CONFIG_SND_SB8) += snd-sb8.o snd-sb8-dsp.o snd-sb-common.o -obj-$(CONFIG_SND_SB16) += snd-sb16.o snd-sb16-dsp.o snd-sb-common.o -obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o snd-sb16-dsp.o snd-sb-common.o -obj-$(CONFIG_SND_ES968) += snd-es968.o snd-sb8-dsp.o snd-sb-common.o -obj-$(CONFIG_SND_ALS4000) += snd-sb-common.o +obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o +obj-$(CONFIG_SND_SB16_DSP) += snd-sb16-dsp.o +obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o +obj-$(CONFIG_SND_SB8) += snd-sb8.o +obj-$(CONFIG_SND_SB16) += snd-sb16.o +obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o +obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o ifeq ($(CONFIG_SND_SB16_CSP),y) obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o endif -obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-emu8000-synth.o - -obj-m := $(sort $(obj-m)) +obj-$(CONFIG_SND_SBAWE_SEQ) += snd-emu8000-synth.o diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index 028af406659..45fcdff611f 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * and (c) 1999 Steve Ratcliffe <steve@parabola.demon.co.uk> * Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de> * @@ -20,11 +20,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <sound/driver.h> #include <linux/wait.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/ioport.h> +#include <linux/export.h> #include <linux/delay.h> #include <sound/core.h> #include <sound/emu8000.h> @@ -45,7 +45,7 @@ * directly. The macros handle the port number and command word. */ /* Write a word */ -void snd_emu8000_poke(emu8000_t *emu, unsigned int port, unsigned int reg, unsigned int val) +void snd_emu8000_poke(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val) { unsigned long flags; spin_lock_irqsave(&emu->reg_lock, flags); @@ -58,7 +58,7 @@ void snd_emu8000_poke(emu8000_t *emu, unsigned int port, unsigned int reg, unsig } /* Read a word */ -unsigned short snd_emu8000_peek(emu8000_t *emu, unsigned int port, unsigned int reg) +unsigned short snd_emu8000_peek(struct snd_emu8000 *emu, unsigned int port, unsigned int reg) { unsigned short res; unsigned long flags; @@ -73,7 +73,7 @@ unsigned short snd_emu8000_peek(emu8000_t *emu, unsigned int port, unsigned int } /* Write a double word */ -void snd_emu8000_poke_dw(emu8000_t *emu, unsigned int port, unsigned int reg, unsigned int val) +void snd_emu8000_poke_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val) { unsigned long flags; spin_lock_irqsave(&emu->reg_lock, flags); @@ -87,7 +87,7 @@ void snd_emu8000_poke_dw(emu8000_t *emu, unsigned int port, unsigned int reg, un } /* Read a double word */ -unsigned int snd_emu8000_peek_dw(emu8000_t *emu, unsigned int port, unsigned int reg) +unsigned int snd_emu8000_peek_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg) { unsigned short low; unsigned int res; @@ -107,7 +107,7 @@ unsigned int snd_emu8000_peek_dw(emu8000_t *emu, unsigned int port, unsigned int * Set up / close a channel to be used for DMA. */ /*exported*/ void -snd_emu8000_dma_chan(emu8000_t *emu, int ch, int mode) +snd_emu8000_dma_chan(struct snd_emu8000 *emu, int ch, int mode) { unsigned right_bit = (mode & EMU8000_RAM_RIGHT) ? 0x01000000 : 0; mode &= EMU8000_RAM_MODE_MASK; @@ -131,12 +131,11 @@ snd_emu8000_dma_chan(emu8000_t *emu, int ch, int mode) /* */ -static void __init -snd_emu8000_read_wait(emu8000_t *emu) +static void +snd_emu8000_read_wait(struct snd_emu8000 *emu) { while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); + schedule_timeout_interruptible(1); if (signal_pending(current)) break; } @@ -144,12 +143,11 @@ snd_emu8000_read_wait(emu8000_t *emu) /* */ -static void __init -snd_emu8000_write_wait(emu8000_t *emu) +static void +snd_emu8000_write_wait(struct snd_emu8000 *emu) { while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); + schedule_timeout_interruptible(1); if (signal_pending(current)) break; } @@ -158,8 +156,8 @@ snd_emu8000_write_wait(emu8000_t *emu) /* * detect a card at the given port */ -static int __init -snd_emu8000_detect(emu8000_t *emu) +static int +snd_emu8000_detect(struct snd_emu8000 *emu) { /* Initialise */ EMU8000_HWCF1_WRITE(emu, 0x0059); @@ -184,8 +182,8 @@ snd_emu8000_detect(emu8000_t *emu) /* * intiailize audio channels */ -static void __init -init_audio(emu8000_t *emu) +static void +init_audio(struct snd_emu8000 *emu) { int ch; @@ -225,8 +223,8 @@ init_audio(emu8000_t *emu) /* * initialize DMA address */ -static void __init -init_dma(emu8000_t *emu) +static void +init_dma(struct snd_emu8000 *emu) { EMU8000_SMALR_WRITE(emu, 0); EMU8000_SMARR_WRITE(emu, 0); @@ -237,7 +235,7 @@ init_dma(emu8000_t *emu) /* * initialization arrays; from ADIP */ -static unsigned short init1[128] /*__devinitdata*/ = { +static unsigned short init1[128] = { 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330, 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730, 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30, @@ -259,7 +257,7 @@ static unsigned short init1[128] /*__devinitdata*/ = { 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30, }; -static unsigned short init2[128] /*__devinitdata*/ = { +static unsigned short init2[128] = { 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330, 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730, 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30, @@ -281,7 +279,7 @@ static unsigned short init2[128] /*__devinitdata*/ = { 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30, }; -static unsigned short init3[128] /*__devinitdata*/ = { +static unsigned short init3[128] = { 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5, 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254, 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234, @@ -303,7 +301,7 @@ static unsigned short init3[128] /*__devinitdata*/ = { 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570, }; -static unsigned short init4[128] /*__devinitdata*/ = { +static unsigned short init4[128] = { 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5, 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254, 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234, @@ -329,8 +327,8 @@ 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 -send_array(emu8000_t *emu, unsigned short *data, int size) +static void +send_array(struct snd_emu8000 *emu, unsigned short *data, int size) { int i; unsigned short *p; @@ -351,8 +349,8 @@ 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 -init_arrays(emu8000_t *emu) +static void +init_arrays(struct snd_emu8000 *emu) { send_array(emu, init1, ARRAY_SIZE(init1)/4); @@ -373,19 +371,20 @@ init_arrays(emu8000_t *emu) /* * Size the onboard memory. - * This is written so as not to need arbitary delays after the write. It + * This is written so as not to need arbitrary delays after the write. It * seems that the only way to do this is to use the one channel and keep * reallocating between read and write. */ -static void __init -size_dram(emu8000_t *emu) +static void +size_dram(struct snd_emu8000 *emu) { - int i, size; + int i, size, detected_size; if (emu->dram_checked) return; size = 0; + detected_size = 0; /* write out a magic number */ snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE); @@ -417,8 +416,7 @@ size_dram(emu8000_t *emu) /*snd_emu8000_read_wait(emu);*/ EMU8000_SMLD_READ(emu); /* discard stale data */ if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2) - break; /* we must have wrapped around */ - + break; /* no memory at this address */ snd_emu8000_read_wait(emu); /* @@ -431,14 +429,25 @@ size_dram(emu8000_t *emu) if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1) break; /* we must have wrapped around */ snd_emu8000_read_wait(emu); + + /* Otherwise, it's valid memory. */ + detected_size = size + 512 * 1024; + } + + /* Distinguish 512 KiB from 0. */ + if (detected_size == 0) { + snd_emu8000_read_wait(emu); + EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET); + EMU8000_SMLD_READ(emu); /* discard stale data */ + if (EMU8000_SMLD_READ(emu) == UNIQUE_ID1) + detected_size = 512 * 1024; } /* wait until FULL bit in SMAxW register is false */ for (i = 0; i < 10000; i++) { if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0) break; - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); + schedule_timeout_interruptible(1); if (signal_pending(current)) break; } @@ -446,9 +455,9 @@ size_dram(emu8000_t *emu) snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE); snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n", - emu->port1, size/1024); + emu->port1, detected_size/1024); - emu->mem_size = size; + emu->mem_size = detected_size; emu->dram_checked = 1; } @@ -458,7 +467,7 @@ size_dram(emu8000_t *emu) * and therefore lose 2 voices. */ /*exported*/ void -snd_emu8000_init_fm(emu8000_t *emu) +snd_emu8000_init_fm(struct snd_emu8000 *emu) { unsigned long flags; @@ -503,8 +512,8 @@ snd_emu8000_init_fm(emu8000_t *emu) /* * The main initialization routine. */ -static void __init -snd_emu8000_init_hw(emu8000_t *emu) +static void +snd_emu8000_init_hw(struct snd_emu8000 *emu) { int i; @@ -588,7 +597,7 @@ static unsigned short treble_parm[12][9] = { * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB] */ /*exported*/ void -snd_emu8000_update_equalizer(emu8000_t *emu) +snd_emu8000_update_equalizer(struct snd_emu8000 *emu) { unsigned short w; int bass = emu->bass_level; @@ -631,17 +640,17 @@ snd_emu8000_update_equalizer(emu8000_t *emu) /* user can define chorus modes up to 32 */ #define SNDRV_EMU8000_CHORUS_NUMBERS 32 -typedef struct soundfont_chorus_fx_t { +struct soundfont_chorus_fx { unsigned short feedback; /* feedback level (0xE600-0xE6FF) */ unsigned short delay_offset; /* delay (0-0x0DA3) [1/44100 sec] */ unsigned short lfo_depth; /* LFO depth (0xBC00-0xBCFF) */ unsigned int delay; /* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */ unsigned int lfo_freq; /* LFO freq LFO freq (0-0xFFFFFFFF) */ -} soundfont_chorus_fx_t; +}; /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */ static char chorus_defined[SNDRV_EMU8000_CHORUS_NUMBERS]; -static soundfont_chorus_fx_t chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = { +static struct soundfont_chorus_fx chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = { {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */ {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */ {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */ @@ -653,9 +662,9 @@ static soundfont_chorus_fx_t chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = { }; /*exported*/ int -snd_emu8000_load_chorus_fx(emu8000_t *emu, int mode, const void __user *buf, long len) +snd_emu8000_load_chorus_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len) { - soundfont_chorus_fx_t rec; + struct soundfont_chorus_fx rec; if (mode < SNDRV_EMU8000_CHORUS_PREDEFINED || mode >= SNDRV_EMU8000_CHORUS_NUMBERS) { snd_printk(KERN_WARNING "invalid chorus mode %d for uploading\n", mode); return -EINVAL; @@ -668,7 +677,7 @@ snd_emu8000_load_chorus_fx(emu8000_t *emu, int mode, const void __user *buf, lon } /*exported*/ void -snd_emu8000_update_chorus_mode(emu8000_t *emu) +snd_emu8000_update_chorus_mode(struct snd_emu8000 *emu) { int effect = emu->chorus_mode; if (effect < 0 || effect >= SNDRV_EMU8000_CHORUS_NUMBERS || @@ -702,15 +711,15 @@ snd_emu8000_update_chorus_mode(emu8000_t *emu) /* user can define reverb modes up to 32 */ #define SNDRV_EMU8000_REVERB_NUMBERS 32 -typedef struct soundfont_reverb_fx_t { +struct soundfont_reverb_fx { unsigned short parms[28]; -} soundfont_reverb_fx_t; +}; /* reverb mode settings; write the following 28 data of 16 bit length * on the corresponding ports in the reverb_cmds array */ static char reverb_defined[SNDRV_EMU8000_CHORUS_NUMBERS]; -static soundfont_reverb_fx_t reverb_parm[SNDRV_EMU8000_REVERB_NUMBERS] = { +static struct soundfont_reverb_fx reverb_parm[SNDRV_EMU8000_REVERB_NUMBERS] = { {{ /* room 1 */ 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4, 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516, @@ -780,9 +789,9 @@ static struct reverb_cmd_pair { }; /*exported*/ int -snd_emu8000_load_reverb_fx(emu8000_t *emu, int mode, const void __user *buf, long len) +snd_emu8000_load_reverb_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len) { - soundfont_reverb_fx_t rec; + struct soundfont_reverb_fx rec; if (mode < SNDRV_EMU8000_REVERB_PREDEFINED || mode >= SNDRV_EMU8000_REVERB_NUMBERS) { snd_printk(KERN_WARNING "invalid reverb mode %d for uploading\n", mode); @@ -796,7 +805,7 @@ snd_emu8000_load_reverb_fx(emu8000_t *emu, int mode, const void __user *buf, lon } /*exported*/ void -snd_emu8000_update_reverb_mode(emu8000_t *emu) +snd_emu8000_update_reverb_mode(struct snd_emu8000 *emu) { int effect = emu->reverb_mode; int i; @@ -822,7 +831,7 @@ snd_emu8000_update_reverb_mode(emu8000_t *emu) /* * bass/treble */ -static int mixer_bass_treble_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int mixer_bass_treble_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; @@ -831,17 +840,17 @@ static int mixer_bass_treble_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t return 0; } -static int mixer_bass_treble_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int mixer_bass_treble_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - emu8000_t *emu = snd_kcontrol_chip(kcontrol); + struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->treble_level : emu->bass_level; return 0; } -static int mixer_bass_treble_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int mixer_bass_treble_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - emu8000_t *emu = snd_kcontrol_chip(kcontrol); + struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned short val1; @@ -860,7 +869,7 @@ static int mixer_bass_treble_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t return change; } -static snd_kcontrol_new_t mixer_bass_control = +static struct snd_kcontrol_new mixer_bass_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Synth Tone Control - Bass", @@ -870,7 +879,7 @@ static snd_kcontrol_new_t mixer_bass_control = .private_value = 0, }; -static snd_kcontrol_new_t mixer_treble_control = +static struct snd_kcontrol_new mixer_treble_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Synth Tone Control - Treble", @@ -883,7 +892,7 @@ static snd_kcontrol_new_t mixer_treble_control = /* * chorus/reverb mode */ -static int mixer_chorus_reverb_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int mixer_chorus_reverb_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; @@ -892,17 +901,17 @@ static int mixer_chorus_reverb_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_ return 0; } -static int mixer_chorus_reverb_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int mixer_chorus_reverb_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - emu8000_t *emu = snd_kcontrol_chip(kcontrol); + struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->chorus_mode : emu->reverb_mode; return 0; } -static int mixer_chorus_reverb_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int mixer_chorus_reverb_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - emu8000_t *emu = snd_kcontrol_chip(kcontrol); + struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned short val1; @@ -927,7 +936,7 @@ static int mixer_chorus_reverb_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value return change; } -static snd_kcontrol_new_t mixer_chorus_mode_control = +static struct snd_kcontrol_new mixer_chorus_mode_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Chorus Mode", @@ -937,7 +946,7 @@ static snd_kcontrol_new_t mixer_chorus_mode_control = .private_value = 1, }; -static snd_kcontrol_new_t mixer_reverb_mode_control = +static struct snd_kcontrol_new mixer_reverb_mode_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Reverb Mode", @@ -950,7 +959,7 @@ static snd_kcontrol_new_t mixer_reverb_mode_control = /* * FM OPL3 chorus/reverb depth */ -static int mixer_fm_depth_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int mixer_fm_depth_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; @@ -959,17 +968,17 @@ static int mixer_fm_depth_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * u return 0; } -static int mixer_fm_depth_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int mixer_fm_depth_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - emu8000_t *emu = snd_kcontrol_chip(kcontrol); + struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->fm_chorus_depth : emu->fm_reverb_depth; return 0; } -static int mixer_fm_depth_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int mixer_fm_depth_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - emu8000_t *emu = snd_kcontrol_chip(kcontrol); + struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned short val1; @@ -989,7 +998,7 @@ static int mixer_fm_depth_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * return change; } -static snd_kcontrol_new_t mixer_fm_chorus_depth_control = +static struct snd_kcontrol_new mixer_fm_chorus_depth_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "FM Chorus Depth", @@ -999,7 +1008,7 @@ static snd_kcontrol_new_t mixer_fm_chorus_depth_control = .private_value = 1, }; -static snd_kcontrol_new_t mixer_fm_reverb_depth_control = +static struct snd_kcontrol_new mixer_fm_reverb_depth_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "FM Reverb Depth", @@ -1010,7 +1019,7 @@ static snd_kcontrol_new_t mixer_fm_reverb_depth_control = }; -static snd_kcontrol_new_t *mixer_defs[EMU8000_NUM_CONTROLS] = { +static struct snd_kcontrol_new *mixer_defs[EMU8000_NUM_CONTROLS] = { &mixer_bass_control, &mixer_treble_control, &mixer_chorus_mode_control, @@ -1022,12 +1031,13 @@ static snd_kcontrol_new_t *mixer_defs[EMU8000_NUM_CONTROLS] = { /* * create and attach mixer elements for WaveTable treble/bass controls */ -static int __init -snd_emu8000_create_mixer(snd_card_t *card, emu8000_t *emu) +static int +snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu) { int i, err = 0; - snd_assert(emu != NULL && card != NULL, return -EINVAL); + if (snd_BUG_ON(!emu || !card)) + return -EINVAL; spin_lock_init(&emu->control_lock); @@ -1052,42 +1062,34 @@ __error: /* * free resources */ -static int snd_emu8000_free(emu8000_t *hw) +static int snd_emu8000_free(struct snd_emu8000 *hw) { - if (hw->res_port1) { - release_resource(hw->res_port1); - kfree_nocheck(hw->res_port1); - } - if (hw->res_port2) { - release_resource(hw->res_port2); - kfree_nocheck(hw->res_port2); - } - if (hw->res_port3) { - release_resource(hw->res_port3); - kfree_nocheck(hw->res_port3); - } + release_and_free_resource(hw->res_port1); + release_and_free_resource(hw->res_port2); + release_and_free_resource(hw->res_port3); kfree(hw); return 0; } /* */ -static int snd_emu8000_dev_free(snd_device_t *device) +static int snd_emu8000_dev_free(struct snd_device *device) { - emu8000_t *hw = device->device_data; + struct snd_emu8000 *hw = device->device_data; return snd_emu8000_free(hw); } /* * initialize and register emu8000 synth device. */ -int __init -snd_emu8000_new(snd_card_t *card, int index, long port, int seq_ports, snd_seq_device_t **awe_ret) +int +snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports, + struct snd_seq_device **awe_ret) { - snd_seq_device_t *awe; - emu8000_t *hw; + struct snd_seq_device *awe; + struct snd_emu8000 *hw; int err; - static snd_device_ops_t ops = { + static struct snd_device_ops ops = { .dev_free = snd_emu8000_dev_free, }; @@ -1097,7 +1099,7 @@ snd_emu8000_new(snd_card_t *card, int index, long port, int seq_ports, snd_seq_d if (seq_ports <= 0) return 0; - hw = kcalloc(1, sizeof(*hw), GFP_KERNEL); + hw = kzalloc(sizeof(*hw), GFP_KERNEL); if (hw == NULL) return -ENOMEM; spin_lock_init(&hw->reg_lock); @@ -1139,9 +1141,9 @@ snd_emu8000_new(snd_card_t *card, int index, long port, int seq_ports, snd_seq_d } #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000, - sizeof(emu8000_t*), &awe) >= 0) { + sizeof(struct snd_emu8000*), &awe) >= 0) { strcpy(awe->name, "EMU-8000"); - *(emu8000_t**)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw; + *(struct snd_emu8000 **)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw; } #else awe = NULL; diff --git a/sound/isa/sb/emu8000_callback.c b/sound/isa/sb/emu8000_callback.c index 1cc4101a17a..72a9ac5efb4 100644 --- a/sound/isa/sb/emu8000_callback.c +++ b/sound/isa/sb/emu8000_callback.c @@ -20,32 +20,36 @@ */ #include "emu8000_local.h" +#include <linux/export.h> #include <sound/asoundef.h> /* * prototypes */ -static snd_emux_voice_t *get_voice(snd_emux_t *emu, snd_emux_port_t *port); -static int start_voice(snd_emux_voice_t *vp); -static void trigger_voice(snd_emux_voice_t *vp); -static void release_voice(snd_emux_voice_t *vp); -static void update_voice(snd_emux_voice_t *vp, int update); -static void reset_voice(snd_emux_t *emu, int ch); -static void terminate_voice(snd_emux_voice_t *vp); -static void sysex(snd_emux_t *emu, char *buf, int len, int parsed, snd_midi_channel_set_t *chset); +static struct snd_emux_voice *get_voice(struct snd_emux *emu, + struct snd_emux_port *port); +static int start_voice(struct snd_emux_voice *vp); +static void trigger_voice(struct snd_emux_voice *vp); +static void release_voice(struct snd_emux_voice *vp); +static void update_voice(struct snd_emux_voice *vp, int update); +static void reset_voice(struct snd_emux *emu, int ch); +static void terminate_voice(struct snd_emux_voice *vp); +static void sysex(struct snd_emux *emu, char *buf, int len, int parsed, + struct snd_midi_channel_set *chset); #ifdef CONFIG_SND_SEQUENCER_OSS -static int oss_ioctl(snd_emux_t *emu, int cmd, int p1, int p2); +static int oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2); #endif -static int load_fx(snd_emux_t *emu, int type, int mode, const void __user *buf, long len); - -static void set_pitch(emu8000_t *hw, snd_emux_voice_t *vp); -static void set_volume(emu8000_t *hw, snd_emux_voice_t *vp); -static void set_pan(emu8000_t *hw, snd_emux_voice_t *vp); -static void set_fmmod(emu8000_t *hw, snd_emux_voice_t *vp); -static void set_tremfreq(emu8000_t *hw, snd_emux_voice_t *vp); -static void set_fm2frq2(emu8000_t *hw, snd_emux_voice_t *vp); -static void set_filterQ(emu8000_t *hw, snd_emux_voice_t *vp); -static void snd_emu8000_tweak_voice(emu8000_t *emu, int ch); +static int load_fx(struct snd_emux *emu, int type, int mode, + const void __user *buf, long len); + +static void set_pitch(struct snd_emu8000 *hw, struct snd_emux_voice *vp); +static void set_volume(struct snd_emu8000 *hw, struct snd_emux_voice *vp); +static void set_pan(struct snd_emu8000 *hw, struct snd_emux_voice *vp); +static void set_fmmod(struct snd_emu8000 *hw, struct snd_emux_voice *vp); +static void set_tremfreq(struct snd_emu8000 *hw, struct snd_emux_voice *vp); +static void set_fm2frq2(struct snd_emu8000 *hw, struct snd_emux_voice *vp); +static void set_filterQ(struct snd_emu8000 *hw, struct snd_emux_voice *vp); +static void snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int ch); /* * Ensure a value is between two points @@ -58,7 +62,7 @@ static void snd_emu8000_tweak_voice(emu8000_t *emu, int ch); /* * set up operators */ -static snd_emux_operators_t emu8000_ops = { +static struct snd_emux_operators emu8000_ops = { .owner = THIS_MODULE, .get_voice = get_voice, .prepare = start_voice, @@ -78,7 +82,7 @@ static snd_emux_operators_t emu8000_ops = { }; void -snd_emu8000_ops_setup(emu8000_t *hw) +snd_emu8000_ops_setup(struct snd_emu8000 *hw) { hw->emu->ops = emu8000_ops; } @@ -89,10 +93,10 @@ snd_emu8000_ops_setup(emu8000_t *hw) * Terminate a voice */ static void -release_voice(snd_emux_voice_t *vp) +release_voice(struct snd_emux_voice *vp) { int dcysusv; - emu8000_t *hw; + struct snd_emu8000 *hw; hw = vp->hw; dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease; @@ -105,9 +109,9 @@ release_voice(snd_emux_voice_t *vp) /* */ static void -terminate_voice(snd_emux_voice_t *vp) +terminate_voice(struct snd_emux_voice *vp) { - emu8000_t *hw; + struct snd_emu8000 *hw; hw = vp->hw; EMU8000_DCYSUSV_WRITE(hw, vp->ch, 0x807F); @@ -117,9 +121,9 @@ terminate_voice(snd_emux_voice_t *vp) /* */ static void -update_voice(snd_emux_voice_t *vp, int update) +update_voice(struct snd_emux_voice *vp, int update) { - emu8000_t *hw; + struct snd_emu8000 *hw; hw = vp->hw; if (update & SNDRV_EMUX_UPDATE_VOLUME) @@ -149,12 +153,12 @@ update_voice(snd_emux_voice_t *vp, int update) * The channel index (vp->ch) must be initialized in this routine. * In Emu8k, it is identical with the array index. */ -static snd_emux_voice_t * -get_voice(snd_emux_t *emu, snd_emux_port_t *port) +static struct snd_emux_voice * +get_voice(struct snd_emux *emu, struct snd_emux_port *port) { int i; - snd_emux_voice_t *vp; - emu8000_t *hw; + struct snd_emux_voice *vp; + struct snd_emu8000 *hw; /* what we are looking for, in order of preference */ enum { @@ -171,7 +175,7 @@ get_voice(snd_emux_t *emu, snd_emux_port_t *port) hw = emu->hw; for (i = 0; i < END; i++) { - best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */; + best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */ best[i].voice = -1; } @@ -227,13 +231,13 @@ get_voice(snd_emux_t *emu, snd_emux_port_t *port) /* */ static int -start_voice(snd_emux_voice_t *vp) +start_voice(struct snd_emux_voice *vp) { unsigned int temp; int ch; int addr; - snd_midi_channel_t *chan; - emu8000_t *hw; + struct snd_midi_channel *chan; + struct snd_emu8000 *hw; hw = vp->hw; ch = vp->ch; @@ -307,11 +311,11 @@ start_voice(snd_emux_voice_t *vp) * Start envelope */ static void -trigger_voice(snd_emux_voice_t *vp) +trigger_voice(struct snd_emux_voice *vp) { int ch = vp->ch; unsigned int temp; - emu8000_t *hw; + struct snd_emu8000 *hw; hw = vp->hw; @@ -329,9 +333,9 @@ trigger_voice(snd_emux_voice_t *vp) * reset voice parameters */ static void -reset_voice(snd_emux_t *emu, int ch) +reset_voice(struct snd_emux *emu, int ch) { - emu8000_t *hw; + struct snd_emu8000 *hw; hw = emu->hw; EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F); @@ -342,7 +346,7 @@ reset_voice(snd_emux_t *emu, int ch) * Set the pitch of a possibly playing note. */ static void -set_pitch(emu8000_t *hw, snd_emux_voice_t *vp) +set_pitch(struct snd_emu8000 *hw, struct snd_emux_voice *vp) { EMU8000_IP_WRITE(hw, vp->ch, vp->apitch); } @@ -351,7 +355,7 @@ set_pitch(emu8000_t *hw, snd_emux_voice_t *vp) * Set the volume of a possibly already playing note */ static void -set_volume(emu8000_t *hw, snd_emux_voice_t *vp) +set_volume(struct snd_emu8000 *hw, struct snd_emux_voice *vp) { int ifatn; @@ -365,7 +369,7 @@ set_volume(emu8000_t *hw, snd_emux_voice_t *vp) * Set pan and loop start address. */ static void -set_pan(emu8000_t *hw, snd_emux_voice_t *vp) +set_pan(struct snd_emu8000 *hw, struct snd_emux_voice *vp) { unsigned int temp; @@ -376,7 +380,7 @@ set_pan(emu8000_t *hw, snd_emux_voice_t *vp) #define MOD_SENSE 18 static void -set_fmmod(emu8000_t *hw, snd_emux_voice_t *vp) +set_fmmod(struct snd_emu8000 *hw, struct snd_emux_voice *vp) { unsigned short fmmod; short pitch; @@ -394,14 +398,14 @@ set_fmmod(emu8000_t *hw, snd_emux_voice_t *vp) /* set tremolo (lfo1) volume & frequency */ static void -set_tremfreq(emu8000_t *hw, snd_emux_voice_t *vp) +set_tremfreq(struct snd_emu8000 *hw, struct snd_emux_voice *vp) { EMU8000_TREMFRQ_WRITE(hw, vp->ch, vp->reg.parm.tremfrq); } /* set lfo2 pitch & frequency */ static void -set_fm2frq2(emu8000_t *hw, snd_emux_voice_t *vp) +set_fm2frq2(struct snd_emu8000 *hw, struct snd_emux_voice *vp) { unsigned short fm2frq2; short pitch; @@ -419,7 +423,7 @@ set_fm2frq2(emu8000_t *hw, snd_emux_voice_t *vp) /* set filterQ */ static void -set_filterQ(emu8000_t *hw, snd_emux_voice_t *vp) +set_filterQ(struct snd_emu8000 *hw, struct snd_emux_voice *vp) { unsigned int addr; addr = EMU8000_CCCA_READ(hw, vp->ch) & 0xffffff; @@ -431,7 +435,7 @@ set_filterQ(emu8000_t *hw, snd_emux_voice_t *vp) * set the envelope & LFO parameters to the default values */ static void -snd_emu8000_tweak_voice(emu8000_t *emu, int i) +snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int i) { /* set all mod/vol envelope shape to minimum */ EMU8000_ENVVOL_WRITE(emu, i, 0x8000); @@ -453,9 +457,9 @@ snd_emu8000_tweak_voice(emu8000_t *emu, int i) * sysex callback */ static void -sysex(snd_emux_t *emu, char *buf, int len, int parsed, snd_midi_channel_set_t *chset) +sysex(struct snd_emux *emu, char *buf, int len, int parsed, struct snd_midi_channel_set *chset) { - emu8000_t *hw; + struct snd_emu8000 *hw; hw = emu->hw; @@ -478,9 +482,9 @@ sysex(snd_emux_t *emu, char *buf, int len, int parsed, snd_midi_channel_set_t *c * OSS ioctl callback */ static int -oss_ioctl(snd_emux_t *emu, int cmd, int p1, int p2) +oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2) { - emu8000_t *hw; + struct snd_emu8000 *hw; hw = emu->hw; @@ -523,9 +527,9 @@ oss_ioctl(snd_emux_t *emu, int cmd, int p1, int p2) */ static int -load_fx(snd_emux_t *emu, int type, int mode, const void __user *buf, long len) +load_fx(struct snd_emux *emu, int type, int mode, const void __user *buf, long len) { - emu8000_t *hw; + struct snd_emu8000 *hw; hw = emu->hw; /* skip header */ diff --git a/sound/isa/sb/emu8000_local.h b/sound/isa/sb/emu8000_local.h index ea4996a895f..7e87c349272 100644 --- a/sound/isa/sb/emu8000_local.h +++ b/sound/isa/sb/emu8000_local.h @@ -21,7 +21,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <sound/driver.h> #include <linux/wait.h> #include <linux/sched.h> #include <linux/slab.h> @@ -30,14 +29,17 @@ #include <sound/emu8000_reg.h> /* emu8000_patch.c */ -int snd_emu8000_sample_new(snd_emux_t *rec, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void __user *data, long count); -int snd_emu8000_sample_free(snd_emux_t *rec, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr); -void snd_emu8000_sample_reset(snd_emux_t *rec); +int snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, + struct snd_util_memhdr *hdr, + const void __user *data, long count); +int snd_emu8000_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp, + struct snd_util_memhdr *hdr); +void snd_emu8000_sample_reset(struct snd_emux *rec); /* emu8000_callback.c */ -void snd_emu8000_ops_setup(emu8000_t *emu); +void snd_emu8000_ops_setup(struct snd_emu8000 *emu); /* emu8000_pcm.c */ -int snd_emu8000_pcm_new(snd_card_t *card, emu8000_t *emu, int index); +int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index); #endif /* __EMU8000_LOCAL_H */ diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c index 26e693078cb..c99c6078be3 100644 --- a/sound/isa/sb/emu8000_patch.c +++ b/sound/isa/sb/emu8000_patch.c @@ -23,7 +23,7 @@ #include <asm/uaccess.h> #include <linux/moduleparam.h> -static int emu8000_reset_addr = 0; +static int emu8000_reset_addr; module_param(emu8000_reset_addr, int, 0444); MODULE_PARM_DESC(emu8000_reset_addr, "reset write address at each time (makes slowdown)"); @@ -32,7 +32,7 @@ MODULE_PARM_DESC(emu8000_reset_addr, "reset write address at each time (makes sl * Open up channels. */ static int -snd_emu8000_open_dma(emu8000_t *emu, int write) +snd_emu8000_open_dma(struct snd_emu8000 *emu, int write) { int i; @@ -59,7 +59,7 @@ snd_emu8000_open_dma(emu8000_t *emu, int write) * Close all dram channels. */ static void -snd_emu8000_close_dma(emu8000_t *emu) +snd_emu8000_close_dma(struct snd_emu8000 *emu) { int i; @@ -106,11 +106,10 @@ read_word(const void __user *buf, int offset, int mode) /* */ static void -snd_emu8000_write_wait(emu8000_t *emu) +snd_emu8000_write_wait(struct snd_emu8000 *emu) { while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); + schedule_timeout_interruptible(1); if (signal_pending(current)) break; } @@ -129,7 +128,7 @@ snd_emu8000_write_wait(emu8000_t *emu) * working. */ static inline void -write_word(emu8000_t *emu, int *offset, unsigned short data) +write_word(struct snd_emu8000 *emu, int *offset, unsigned short data) { if (emu8000_reset_addr) { if (emu8000_reset_addr > 1) @@ -145,18 +144,20 @@ write_word(emu8000_t *emu, int *offset, unsigned short data) * the generic soundfont routines as a callback. */ int -snd_emu8000_sample_new(snd_emux_t *rec, snd_sf_sample_t *sp, - snd_util_memhdr_t *hdr, const void __user *data, long count) +snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, + struct snd_util_memhdr *hdr, + const void __user *data, long count) { int i; int rc; int offset; int truesize; int dram_offset, dram_start; - emu8000_t *emu; + struct snd_emu8000 *emu; emu = rec->hw; - snd_assert(sp != NULL, return -EINVAL); + if (snd_BUG_ON(!sp)) + return -EINVAL; if (sp->v.size == 0) return 0; @@ -283,7 +284,8 @@ snd_emu8000_sample_new(snd_emux_t *rec, snd_sf_sample_t *sp, * free a sample block */ int -snd_emu8000_sample_free(snd_emux_t *rec, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr) +snd_emu8000_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp, + struct snd_util_memhdr *hdr) { if (sp->block) { snd_util_mem_free(hdr, sp->block); @@ -297,7 +299,7 @@ snd_emu8000_sample_free(snd_emux_t *rec, snd_sf_sample_t *sp, snd_util_memhdr_t * sample_reset callback - terminate voices */ void -snd_emu8000_sample_reset(snd_emux_t *rec) +snd_emu8000_sample_reset(struct snd_emux *rec) { snd_emux_terminate_all(rec); } diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c index db5eb8b5505..2f85c66f8e3 100644 --- a/sound/isa/sb/emu8000_pcm.c +++ b/sound/isa/sb/emu8000_pcm.c @@ -20,6 +20,7 @@ #include "emu8000_local.h" #include <linux/init.h> +#include <linux/slab.h> #include <sound/initval.h> #include <sound/pcm.h> @@ -46,14 +47,12 @@ */ -typedef struct snd_emu8k_pcm emu8k_pcm_t; - struct snd_emu8k_pcm { - emu8000_t *emu; - snd_pcm_substream_t *substream; + struct snd_emu8000 *emu; + struct snd_pcm_substream *substream; unsigned int allocated_bytes; - snd_util_memblk_t *block; + struct snd_util_memblk *block; unsigned int offset; unsigned int buf_size; unsigned int period_size; @@ -77,7 +76,7 @@ struct snd_emu8k_pcm { * open up channels for the simultaneous data transfer and playback */ static int -emu8k_open_dram_for_pcm(emu8000_t *emu, int channels) +emu8k_open_dram_for_pcm(struct snd_emu8000 *emu, int channels) { int i; @@ -113,12 +112,11 @@ emu8k_open_dram_for_pcm(emu8000_t *emu, int channels) /* */ static void -snd_emu8000_write_wait(emu8000_t *emu, int can_schedule) +snd_emu8000_write_wait(struct snd_emu8000 *emu, int can_schedule) { while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) { if (can_schedule) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); + schedule_timeout_interruptible(1); if (signal_pending(current)) break; } @@ -129,7 +127,7 @@ snd_emu8000_write_wait(emu8000_t *emu, int can_schedule) * close all channels */ static void -emu8k_close_dram(emu8000_t *emu) +emu8k_close_dram(struct snd_emu8000 *emu) { int i; @@ -157,7 +155,7 @@ static int calc_rate_offset(int hz) /* */ -static snd_pcm_hardware_t emu8k_pcm_hw = { +static struct snd_pcm_hardware emu8k_pcm_hw = { #ifdef USE_NONINTERLEAVE .info = SNDRV_PCM_INFO_NONINTERLEAVED, #else @@ -181,7 +179,7 @@ static snd_pcm_hardware_t emu8k_pcm_hw = { /* * get the current position at the given channel from CCCA register */ -static inline int emu8k_get_curpos(emu8k_pcm_t *rec, int ch) +static inline int emu8k_get_curpos(struct snd_emu8k_pcm *rec, int ch) { int val = EMU8000_CCCA_READ(rec->emu, ch) & 0xfffffff; val -= rec->loop_start[ch] - 1; @@ -195,7 +193,7 @@ static inline int emu8k_get_curpos(emu8k_pcm_t *rec, int ch) */ static void emu8k_pcm_timer_func(unsigned long data) { - emu8k_pcm_t *rec = (emu8k_pcm_t *)data; + struct snd_emu8k_pcm *rec = (struct snd_emu8k_pcm *)data; int ptr, delta; spin_lock(&rec->timer_lock); @@ -227,13 +225,13 @@ static void emu8k_pcm_timer_func(unsigned long data) * open pcm * creating an instance here */ -static int emu8k_pcm_open(snd_pcm_substream_t *subs) +static int emu8k_pcm_open(struct snd_pcm_substream *subs) { - emu8000_t *emu = snd_pcm_substream_chip(subs); - emu8k_pcm_t *rec; - snd_pcm_runtime_t *runtime = subs->runtime; + struct snd_emu8000 *emu = snd_pcm_substream_chip(subs); + struct snd_emu8k_pcm *rec; + struct snd_pcm_runtime *runtime = subs->runtime; - rec = kcalloc(1, sizeof(*rec), GFP_KERNEL); + rec = kzalloc(sizeof(*rec), GFP_KERNEL); if (! rec) return -ENOMEM; @@ -257,9 +255,9 @@ static int emu8k_pcm_open(snd_pcm_substream_t *subs) return 0; } -static int emu8k_pcm_close(snd_pcm_substream_t *subs) +static int emu8k_pcm_close(struct snd_pcm_substream *subs) { - emu8k_pcm_t *rec = subs->runtime->private_data; + struct snd_emu8k_pcm *rec = subs->runtime->private_data; kfree(rec); subs->runtime->private_data = NULL; return 0; @@ -282,9 +280,9 @@ static int calc_pitch_target(int pitch) /* * set up the voice */ -static void setup_voice(emu8k_pcm_t *rec, int ch) +static void setup_voice(struct snd_emu8k_pcm *rec, int ch) { - emu8000_t *hw = rec->emu; + struct snd_emu8000 *hw = rec->emu; unsigned int temp; /* channel to be silent and idle */ @@ -335,10 +333,10 @@ static void setup_voice(emu8k_pcm_t *rec, int ch) /* * trigger the voice */ -static void start_voice(emu8k_pcm_t *rec, int ch) +static void start_voice(struct snd_emu8k_pcm *rec, int ch) { unsigned long flags; - emu8000_t *hw = rec->emu; + struct snd_emu8000 *hw = rec->emu; unsigned int temp, aux; int pt = calc_pitch_target(rec->pitch); @@ -371,10 +369,10 @@ static void start_voice(emu8k_pcm_t *rec, int ch) /* * stop the voice immediately */ -static void stop_voice(emu8k_pcm_t *rec, int ch) +static void stop_voice(struct snd_emu8k_pcm *rec, int ch) { unsigned long flags; - emu8000_t *hw = rec->emu; + struct snd_emu8000 *hw = rec->emu; EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F); @@ -387,9 +385,9 @@ static void stop_voice(emu8k_pcm_t *rec, int ch) spin_unlock_irqrestore(&rec->timer_lock, flags); } -static int emu8k_pcm_trigger(snd_pcm_substream_t *subs, int cmd) +static int emu8k_pcm_trigger(struct snd_pcm_substream *subs, int cmd) { - emu8k_pcm_t *rec = subs->runtime->private_data; + struct snd_emu8k_pcm *rec = subs->runtime->private_data; int ch; switch (cmd) { @@ -429,13 +427,14 @@ do { \ #ifdef USE_NONINTERLEAVE /* copy one channel block */ -static int emu8k_transfer_block(emu8000_t *emu, int offset, unsigned short *buf, int count) +static int emu8k_transfer_block(struct snd_emu8000 *emu, int offset, unsigned short *buf, int count) { EMU8000_SMALW_WRITE(emu, offset); while (count > 0) { unsigned short sval; CHECK_SCHEDULER(); - get_user(sval, buf); + if (get_user(sval, buf)) + return -EFAULT; EMU8000_SMLD_WRITE(emu, sval); buf++; count--; @@ -443,14 +442,14 @@ static int emu8k_transfer_block(emu8000_t *emu, int offset, unsigned short *buf, return 0; } -static int emu8k_pcm_copy(snd_pcm_substream_t *subs, +static int emu8k_pcm_copy(struct snd_pcm_substream *subs, int voice, snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count) { - emu8k_pcm_t *rec = subs->runtime->private_data; - emu8000_t *emu = rec->emu; + struct snd_emu8k_pcm *rec = subs->runtime->private_data; + struct snd_emu8000 *emu = rec->emu; snd_emu8000_write_wait(emu, 1); if (voice == -1) { @@ -470,7 +469,7 @@ static int emu8k_pcm_copy(snd_pcm_substream_t *subs, } /* make a channel block silence */ -static int emu8k_silence_block(emu8000_t *emu, int offset, int count) +static int emu8k_silence_block(struct snd_emu8000 *emu, int offset, int count) { EMU8000_SMALW_WRITE(emu, offset); while (count > 0) { @@ -481,13 +480,13 @@ static int emu8k_silence_block(emu8000_t *emu, int offset, int count) return 0; } -static int emu8k_pcm_silence(snd_pcm_substream_t *subs, +static int emu8k_pcm_silence(struct snd_pcm_substream *subs, int voice, snd_pcm_uframes_t pos, snd_pcm_uframes_t count) { - emu8k_pcm_t *rec = subs->runtime->private_data; - emu8000_t *emu = rec->emu; + struct snd_emu8k_pcm *rec = subs->runtime->private_data; + struct snd_emu8000 *emu = rec->emu; snd_emu8000_write_wait(emu, 1); if (voice == -1 && rec->voices == 1) @@ -509,14 +508,14 @@ static int emu8k_pcm_silence(snd_pcm_substream_t *subs, * copy the interleaved data can be done easily by using * DMA "left" and "right" channels on emu8k engine. */ -static int emu8k_pcm_copy(snd_pcm_substream_t *subs, +static int emu8k_pcm_copy(struct snd_pcm_substream *subs, int voice, snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count) { - emu8k_pcm_t *rec = subs->runtime->private_data; - emu8000_t *emu = rec->emu; + struct snd_emu8k_pcm *rec = subs->runtime->private_data; + struct snd_emu8000 *emu = rec->emu; unsigned short __user *buf = src; snd_emu8000_write_wait(emu, 1); @@ -527,12 +526,14 @@ static int emu8k_pcm_copy(snd_pcm_substream_t *subs, while (count-- > 0) { unsigned short sval; CHECK_SCHEDULER(); - get_user(sval, buf); + if (get_user(sval, buf)) + return -EFAULT; EMU8000_SMLD_WRITE(emu, sval); buf++; if (rec->voices > 1) { CHECK_SCHEDULER(); - get_user(sval, buf); + if (get_user(sval, buf)) + return -EFAULT; EMU8000_SMRD_WRITE(emu, sval); buf++; } @@ -540,13 +541,13 @@ static int emu8k_pcm_copy(snd_pcm_substream_t *subs, return 0; } -static int emu8k_pcm_silence(snd_pcm_substream_t *subs, +static int emu8k_pcm_silence(struct snd_pcm_substream *subs, int voice, snd_pcm_uframes_t pos, snd_pcm_uframes_t count) { - emu8k_pcm_t *rec = subs->runtime->private_data; - emu8000_t *emu = rec->emu; + struct snd_emu8k_pcm *rec = subs->runtime->private_data; + struct snd_emu8000 *emu = rec->emu; snd_emu8000_write_wait(emu, 1); EMU8000_SMALW_WRITE(emu, rec->loop_start[0] + pos); @@ -568,10 +569,10 @@ static int emu8k_pcm_silence(snd_pcm_substream_t *subs, /* * allocate a memory block */ -static int emu8k_pcm_hw_params(snd_pcm_substream_t *subs, - snd_pcm_hw_params_t *hw_params) +static int emu8k_pcm_hw_params(struct snd_pcm_substream *subs, + struct snd_pcm_hw_params *hw_params) { - emu8k_pcm_t *rec = subs->runtime->private_data; + struct snd_emu8k_pcm *rec = subs->runtime->private_data; if (rec->block) { /* reallocation - release the old block */ @@ -593,9 +594,9 @@ static int emu8k_pcm_hw_params(snd_pcm_substream_t *subs, /* * free the memory block */ -static int emu8k_pcm_hw_free(snd_pcm_substream_t *subs) +static int emu8k_pcm_hw_free(struct snd_pcm_substream *subs) { - emu8k_pcm_t *rec = subs->runtime->private_data; + struct snd_emu8k_pcm *rec = subs->runtime->private_data; if (rec->block) { int ch; @@ -611,9 +612,9 @@ static int emu8k_pcm_hw_free(snd_pcm_substream_t *subs) /* */ -static int emu8k_pcm_prepare(snd_pcm_substream_t *subs) +static int emu8k_pcm_prepare(struct snd_pcm_substream *subs) { - emu8k_pcm_t *rec = subs->runtime->private_data; + struct snd_emu8k_pcm *rec = subs->runtime->private_data; rec->pitch = 0xe000 + calc_rate_offset(subs->runtime->rate); rec->last_ptr = 0; @@ -657,16 +658,16 @@ static int emu8k_pcm_prepare(snd_pcm_substream_t *subs) return 0; } -static snd_pcm_uframes_t emu8k_pcm_pointer(snd_pcm_substream_t *subs) +static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs) { - emu8k_pcm_t *rec = subs->runtime->private_data; + struct snd_emu8k_pcm *rec = subs->runtime->private_data; if (rec->running) return emu8k_get_curpos(rec, 0); return 0; } -static snd_pcm_ops_t emu8k_pcm_ops = { +static struct snd_pcm_ops emu8k_pcm_ops = { .open = emu8k_pcm_open, .close = emu8k_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -680,15 +681,15 @@ static snd_pcm_ops_t emu8k_pcm_ops = { }; -static void snd_emu8000_pcm_free(snd_pcm_t *pcm) +static void snd_emu8000_pcm_free(struct snd_pcm *pcm) { - emu8000_t *emu = pcm->private_data; + struct snd_emu8000 *emu = pcm->private_data; emu->pcm = NULL; } -int snd_emu8000_pcm_new(snd_card_t *card, emu8000_t *emu, int index) +int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index) { - snd_pcm_t *pcm; + struct snd_pcm *pcm; int err; if ((err = snd_pcm_new(card, "Emu8000 PCM", index, 1, 0, &pcm)) < 0) diff --git a/sound/isa/sb/emu8000_synth.c b/sound/isa/sb/emu8000_synth.c index 1f63aa52d59..4e3fcfb15ad 100644 --- a/sound/isa/sb/emu8000_synth.c +++ b/sound/isa/sb/emu8000_synth.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * and (c) 1999 Steve Ratcliffe <steve@parabola.demon.co.uk> * Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de> * @@ -22,6 +22,7 @@ #include "emu8000_local.h" #include <linux/init.h> +#include <linux/module.h> #include <sound/initval.h> MODULE_AUTHOR("Takashi Iwai, Steve Ratcliffe"); @@ -33,12 +34,12 @@ MODULE_LICENSE("GPL"); /* * create a new hardware dependent device for Emu8000 */ -static int snd_emu8000_new_device(snd_seq_device_t *dev) +static int snd_emu8000_new_device(struct snd_seq_device *dev) { - emu8000_t *hw; - snd_emux_t *emu; + struct snd_emu8000 *hw; + struct snd_emux *emu; - hw = *(emu8000_t**)SNDRV_SEQ_DEVICE_ARGPTR(dev); + hw = *(struct snd_emu8000**)SNDRV_SEQ_DEVICE_ARGPTR(dev); if (hw == NULL) return -EINVAL; @@ -56,7 +57,7 @@ static int snd_emu8000_new_device(snd_seq_device_t *dev) emu->num_ports = hw->seq_ports; if (hw->memhdr) { - snd_printk("memhdr is already initialized!?\n"); + snd_printk(KERN_ERR "memhdr is already initialized!?\n"); snd_util_memhdr_free(hw->memhdr); } hw->memhdr = snd_util_memhdr_new(hw->mem_size); @@ -92,9 +93,9 @@ static int snd_emu8000_new_device(snd_seq_device_t *dev) /* * free all resources */ -static int snd_emu8000_delete_device(snd_seq_device_t *dev) +static int snd_emu8000_delete_device(struct snd_seq_device *dev) { - emu8000_t *hw; + struct snd_emu8000 *hw; if (dev->driver_data == NULL) return 0; /* no synth was allocated actually */ @@ -118,11 +119,12 @@ static int snd_emu8000_delete_device(snd_seq_device_t *dev) static int __init alsa_emu8000_init(void) { - static snd_seq_dev_ops_t ops = { + static struct snd_seq_dev_ops ops = { snd_emu8000_new_device, snd_emu8000_delete_device, }; - return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU8000, &ops, sizeof(emu8000_t*)); + return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU8000, &ops, + sizeof(struct snd_emu8000*)); } static void __exit alsa_emu8000_exit(void) diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c deleted file mode 100644 index c859917c14d..00000000000 --- a/sound/isa/sb/es968.c +++ /dev/null @@ -1,235 +0,0 @@ - -/* - card-es968.c - driver for ESS AudioDrive ES968 based soundcards. - Copyright (C) 1999 by Massimo Piccioni <dafastidio@libero.it> - - Thanks to Pierfrancesco 'qM2' Passerini. - - 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 -*/ - -#include <sound/driver.h> -#include <linux/init.h> -#include <linux/time.h> -#include <linux/pnp.h> -#include <linux/moduleparam.h> -#include <sound/core.h> -#include <sound/initval.h> -#include <sound/sb.h> - -#define PFX "es968: " - -MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>"); -MODULE_DESCRIPTION("ESS AudioDrive ES968"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{ESS,AudioDrive ES968}}"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ -static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ -static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */ -static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for es968 based soundcard."); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for es968 based soundcard."); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable es968 based soundcard."); -module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for es968 driver."); -module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for es968 driver."); -module_param_array(dma8, int, NULL, 0444); -MODULE_PARM_DESC(dma8, "8-bit DMA # for es968 driver."); - -struct snd_card_es968 { - struct pnp_dev *dev; -}; - -static struct pnp_card_device_id snd_es968_pnpids[] = { - { .id = "ESS0968", .devs = { { "@@@0968" }, } }, - { .id = "", } /* end */ -}; - -MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids); - -#define DRIVER_NAME "snd-card-es968" - -static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - sb_t *chip = dev_id; - - if (chip->open & SB_OPEN_PCM) { - return snd_sb8dsp_interrupt(chip); - } else { - return snd_sb8dsp_midi_interrupt(chip); - } -} - -static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard, - struct pnp_card_link *card, - const struct pnp_card_device_id *id) -{ - struct pnp_dev *pdev; - struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); - int err; - if (!cfg) - return -ENOMEM; - acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL); - if (acard->dev == NULL) { - kfree(cfg); - return -ENODEV; - } - - pdev = acard->dev; - - pnp_init_resource_table(cfg); - - /* override resources */ - if (port[dev] != SNDRV_AUTO_PORT) - pnp_resource_change(&cfg->port_resource[0], port[dev], 16); - if (dma8[dev] != SNDRV_AUTO_DMA) - pnp_resource_change(&cfg->dma_resource[0], dma8[dev], 1); - if (irq[dev] != SNDRV_AUTO_IRQ) - pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1); - if ((pnp_manual_config_dev(pdev, cfg, 0)) < 0) - snd_printk(KERN_ERR PFX "AUDIO the requested resources are invalid, using auto config\n"); - err = pnp_activate_dev(pdev); - if (err < 0) { - snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n"); - kfree(cfg); - return err; - } - port[dev] = pnp_port_start(pdev, 0); - dma8[dev] = pnp_dma(pdev, 1); - irq[dev] = pnp_irq(pdev, 0); - - kfree(cfg); - return 0; -} - -static int __init snd_card_es968_probe(int dev, - struct pnp_card_link *pcard, - const struct pnp_card_device_id *pid) -{ - int error; - sb_t *chip; - snd_card_t *card; - struct snd_card_es968 *acard; - - if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_es968))) == NULL) - return -ENOMEM; - acard = (struct snd_card_es968 *)card->private_data; - if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) { - snd_card_free(card); - return error; - } - snd_card_set_dev(card, &pcard->card->dev); - - if ((error = snd_sbdsp_create(card, port[dev], - irq[dev], - snd_card_es968_interrupt, - dma8[dev], - -1, - SB_HW_AUTO, &chip)) < 0) { - snd_card_free(card); - return error; - } - - if ((error = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) { - snd_card_free(card); - return error; - } - - if ((error = snd_sbmixer_new(chip)) < 0) { - snd_card_free(card); - return error; - } - - if ((error = snd_sb8dsp_midi(chip, 0, NULL)) < 0) { - snd_card_free(card); - return error; - } - - strcpy(card->driver, "ES968"); - strcpy(card->shortname, "ESS ES968"); - sprintf(card->longname, "%s soundcard, %s at 0x%lx, irq %d, dma %d", - card->shortname, chip->name, chip->port, irq[dev], dma8[dev]); - - if ((error = snd_card_register(card)) < 0) { - snd_card_free(card); - return error; - } - pnp_set_card_drvdata(pcard, card); - return 0; -} - -static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card, - const struct pnp_card_device_id *id) -{ - static int dev; - int res; - - for ( ; dev < SNDRV_CARDS; dev++) { - if (!enable[dev]) - continue; - res = snd_card_es968_probe(dev, card, id); - if (res < 0) - return res; - dev++; - return 0; - } - return -ENODEV; -} - -static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard) -{ - snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard); - - snd_card_disconnect(card); - snd_card_free_in_thread(card); -} - -static struct pnp_card_driver es968_pnpc_driver = { - .flags = PNP_DRIVER_RES_DISABLE, - .name = "es968", - .id_table = snd_es968_pnpids, - .probe = snd_es968_pnp_detect, - .remove = __devexit_p(snd_es968_pnp_remove), -}; - -static int __init alsa_card_es968_init(void) -{ - int cards = pnp_register_card_driver(&es968_pnpc_driver); -#ifdef MODULE - if (cards == 0) { - pnp_unregister_card_driver(&es968_pnpc_driver); - snd_printk(KERN_ERR "no ES968 based soundcards found\n"); - } -#endif - return cards ? 0 : -ENODEV; -} - -static void __exit alsa_card_es968_exit(void) -{ - pnp_unregister_card_driver(&es968_pnpc_driver); -} - -module_init(alsa_card_es968_init) -module_exit(alsa_card_es968_exit) diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c new file mode 100644 index 00000000000..90d2eba549e --- /dev/null +++ b/sound/isa/sb/jazz16.c @@ -0,0 +1,401 @@ + +/* + * jazz16.c - driver for Media Vision Jazz16 based soundcards. + * Copyright (C) 2009 Krzysztof Helt <krzysztof.h1@wp.pl> + * Based on patches posted by Rask Ingemann Lambertsen and Rene Herman. + * Based on OSS Sound Blaster driver. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <asm/dma.h> +#include <linux/isa.h> +#include <sound/core.h> +#include <sound/mpu401.h> +#include <sound/opl3.h> +#include <sound/sb.h> +#define SNDRV_LEGACY_FIND_FREE_IRQ +#define SNDRV_LEGACY_FIND_FREE_DMA +#include <sound/initval.h> + +#define PFX "jazz16: " + +MODULE_DESCRIPTION("Media Vision Jazz16"); +MODULE_SUPPORTED_DEVICE("{{Media Vision ??? }," + "{RTL,RTL3000}}"); + +MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>"); +MODULE_LICENSE("GPL"); + +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; +static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; +static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; +static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; +static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; +static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; + +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for Media Vision Jazz16 based soundcard."); +module_param_array(id, charp, NULL, 0444); +MODULE_PARM_DESC(id, "ID string for Media Vision Jazz16 based soundcard."); +module_param_array(enable, bool, NULL, 0444); +MODULE_PARM_DESC(enable, "Enable Media Vision Jazz16 based soundcard."); +module_param_array(port, long, NULL, 0444); +MODULE_PARM_DESC(port, "Port # for jazz16 driver."); +module_param_array(mpu_port, long, NULL, 0444); +MODULE_PARM_DESC(mpu_port, "MPU-401 port # for jazz16 driver."); +module_param_array(irq, int, NULL, 0444); +MODULE_PARM_DESC(irq, "IRQ # for jazz16 driver."); +module_param_array(mpu_irq, int, NULL, 0444); +MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for jazz16 driver."); +module_param_array(dma8, int, NULL, 0444); +MODULE_PARM_DESC(dma8, "DMA8 # for jazz16 driver."); +module_param_array(dma16, int, NULL, 0444); +MODULE_PARM_DESC(dma16, "DMA16 # for jazz16 driver."); + +#define SB_JAZZ16_WAKEUP 0xaf +#define SB_JAZZ16_SET_PORTS 0x50 +#define SB_DSP_GET_JAZZ_BRD_REV 0xfa +#define SB_JAZZ16_SET_DMAINTR 0xfb +#define SB_DSP_GET_JAZZ_MODEL 0xfe + +struct snd_card_jazz16 { + struct snd_sb *chip; +}; + +static irqreturn_t jazz16_interrupt(int irq, void *chip) +{ + return snd_sb8dsp_interrupt(chip); +} + +static int jazz16_configure_ports(unsigned long port, + unsigned long mpu_port, int idx) +{ + unsigned char val; + + if (!request_region(0x201, 1, "jazz16 config")) { + snd_printk(KERN_ERR "config port region is already in use.\n"); + return -EBUSY; + } + outb(SB_JAZZ16_WAKEUP - idx, 0x201); + udelay(100); + outb(SB_JAZZ16_SET_PORTS + idx, 0x201); + udelay(100); + val = port & 0x70; + val |= (mpu_port & 0x30) >> 4; + outb(val, 0x201); + + release_region(0x201, 1); + return 0; +} + +static int jazz16_detect_board(unsigned long port, + unsigned long mpu_port) +{ + int err; + int val; + struct snd_sb chip; + + if (!request_region(port, 0x10, "jazz16")) { + snd_printk(KERN_ERR "I/O port region is already in use.\n"); + return -EBUSY; + } + /* just to call snd_sbdsp_command/reset/get_byte() */ + chip.port = port; + + err = snd_sbdsp_reset(&chip); + if (err < 0) + for (val = 0; val < 4; val++) { + err = jazz16_configure_ports(port, mpu_port, val); + if (err < 0) + break; + + err = snd_sbdsp_reset(&chip); + if (!err) + break; + } + if (err < 0) { + err = -ENODEV; + goto err_unmap; + } + if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_BRD_REV)) { + err = -EBUSY; + goto err_unmap; + } + val = snd_sbdsp_get_byte(&chip); + if (val >= 0x30) + snd_sbdsp_get_byte(&chip); + + if ((val & 0xf0) != 0x10) { + err = -ENODEV; + goto err_unmap; + } + if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_MODEL)) { + err = -EBUSY; + goto err_unmap; + } + snd_sbdsp_get_byte(&chip); + err = snd_sbdsp_get_byte(&chip); + snd_printd("Media Vision Jazz16 board detected: rev 0x%x, model 0x%x\n", + val, err); + + err = 0; + +err_unmap: + release_region(port, 0x10); + return err; +} + +static int jazz16_configure_board(struct snd_sb *chip, int mpu_irq) +{ + static unsigned char jazz_irq_bits[] = { 0, 0, 2, 3, 0, 1, 0, 4, + 0, 2, 5, 0, 0, 0, 0, 6 }; + static unsigned char jazz_dma_bits[] = { 0, 1, 0, 2, 0, 3, 0, 4 }; + + if (jazz_dma_bits[chip->dma8] == 0 || + jazz_dma_bits[chip->dma16] == 0 || + jazz_irq_bits[chip->irq] == 0) + return -EINVAL; + + if (!snd_sbdsp_command(chip, SB_JAZZ16_SET_DMAINTR)) + return -EBUSY; + + if (!snd_sbdsp_command(chip, + jazz_dma_bits[chip->dma8] | + (jazz_dma_bits[chip->dma16] << 4))) + return -EBUSY; + + if (!snd_sbdsp_command(chip, + jazz_irq_bits[chip->irq] | + (jazz_irq_bits[mpu_irq] << 4))) + return -EBUSY; + + return 0; +} + +static int snd_jazz16_match(struct device *devptr, unsigned int dev) +{ + if (!enable[dev]) + return 0; + if (port[dev] == SNDRV_AUTO_PORT) { + snd_printk(KERN_ERR "please specify port\n"); + return 0; + } else if (port[dev] == 0x200 || (port[dev] & ~0x270)) { + snd_printk(KERN_ERR "incorrect port specified\n"); + return 0; + } + if (dma8[dev] != SNDRV_AUTO_DMA && + dma8[dev] != 1 && dma8[dev] != 3) { + snd_printk(KERN_ERR "dma8 must be 1 or 3\n"); + return 0; + } + if (dma16[dev] != SNDRV_AUTO_DMA && + dma16[dev] != 5 && dma16[dev] != 7) { + snd_printk(KERN_ERR "dma16 must be 5 or 7\n"); + return 0; + } + if (mpu_port[dev] != SNDRV_AUTO_PORT && + (mpu_port[dev] & ~0x030) != 0x300) { + snd_printk(KERN_ERR "incorrect mpu_port specified\n"); + return 0; + } + if (mpu_irq[dev] != SNDRV_AUTO_DMA && + mpu_irq[dev] != 2 && mpu_irq[dev] != 3 && + mpu_irq[dev] != 5 && mpu_irq[dev] != 7) { + snd_printk(KERN_ERR "mpu_irq must be 2, 3, 5 or 7\n"); + return 0; + } + return 1; +} + +static int snd_jazz16_probe(struct device *devptr, unsigned int dev) +{ + struct snd_card *card; + struct snd_card_jazz16 *jazz16; + struct snd_sb *chip; + struct snd_opl3 *opl3; + static int possible_irqs[] = {2, 3, 5, 7, 9, 10, 15, -1}; + static int possible_dmas8[] = {1, 3, -1}; + static int possible_dmas16[] = {5, 7, -1}; + int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq; + + err = snd_card_new(devptr, index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_jazz16), &card); + if (err < 0) + return err; + + jazz16 = card->private_data; + + xirq = irq[dev]; + if (xirq == SNDRV_AUTO_IRQ) { + xirq = snd_legacy_find_free_irq(possible_irqs); + if (xirq < 0) { + snd_printk(KERN_ERR "unable to find a free IRQ\n"); + err = -EBUSY; + goto err_free; + } + } + xdma8 = dma8[dev]; + if (xdma8 == SNDRV_AUTO_DMA) { + xdma8 = snd_legacy_find_free_dma(possible_dmas8); + if (xdma8 < 0) { + snd_printk(KERN_ERR "unable to find a free DMA8\n"); + err = -EBUSY; + goto err_free; + } + } + xdma16 = dma16[dev]; + if (xdma16 == SNDRV_AUTO_DMA) { + xdma16 = snd_legacy_find_free_dma(possible_dmas16); + if (xdma16 < 0) { + snd_printk(KERN_ERR "unable to find a free DMA16\n"); + err = -EBUSY; + goto err_free; + } + } + + xmpu_port = mpu_port[dev]; + if (xmpu_port == SNDRV_AUTO_PORT) + xmpu_port = 0; + err = jazz16_detect_board(port[dev], xmpu_port); + if (err < 0) { + printk(KERN_ERR "Media Vision Jazz16 board not detected\n"); + goto err_free; + } + err = snd_sbdsp_create(card, port[dev], irq[dev], + jazz16_interrupt, + dma8[dev], dma16[dev], + SB_HW_JAZZ16, + &chip); + if (err < 0) + goto err_free; + + xmpu_irq = mpu_irq[dev]; + if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT) + xmpu_irq = 0; + err = jazz16_configure_board(chip, xmpu_irq); + if (err < 0) { + printk(KERN_ERR "Media Vision Jazz16 configuration failed\n"); + goto err_free; + } + + jazz16->chip = chip; + + strcpy(card->driver, "jazz16"); + strcpy(card->shortname, "Media Vision Jazz16"); + sprintf(card->longname, + "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d", + port[dev], xirq, xdma8, xdma16); + + err = snd_sb8dsp_pcm(chip, 0, NULL); + if (err < 0) + goto err_free; + err = snd_sbmixer_new(chip); + if (err < 0) + goto err_free; + + err = snd_opl3_create(card, chip->port, chip->port + 2, + OPL3_HW_AUTO, 1, &opl3); + if (err < 0) + snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n", + chip->port, chip->port + 2); + else { + err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); + if (err < 0) + goto err_free; + } + if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { + if (mpu_irq[dev] == SNDRV_AUTO_IRQ) + mpu_irq[dev] = -1; + + if (snd_mpu401_uart_new(card, 0, + MPU401_HW_MPU401, + mpu_port[dev], 0, + mpu_irq[dev], + NULL) < 0) + snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n", + mpu_port[dev]); + } + + err = snd_card_register(card); + if (err < 0) + goto err_free; + + dev_set_drvdata(devptr, card); + return 0; + +err_free: + snd_card_free(card); + return err; +} + +static int snd_jazz16_remove(struct device *devptr, unsigned int dev) +{ + struct snd_card *card = dev_get_drvdata(devptr); + + snd_card_free(card); + return 0; +} + +#ifdef CONFIG_PM +static int snd_jazz16_suspend(struct device *pdev, unsigned int n, + pm_message_t state) +{ + struct snd_card *card = dev_get_drvdata(pdev); + struct snd_card_jazz16 *acard = card->private_data; + struct snd_sb *chip = acard->chip; + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + snd_pcm_suspend_all(chip->pcm); + snd_sbmixer_suspend(chip); + return 0; +} + +static int snd_jazz16_resume(struct device *pdev, unsigned int n) +{ + struct snd_card *card = dev_get_drvdata(pdev); + struct snd_card_jazz16 *acard = card->private_data; + struct snd_sb *chip = acard->chip; + + snd_sbdsp_reset(chip); + snd_sbmixer_resume(chip); + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +#endif + +static struct isa_driver snd_jazz16_driver = { + .match = snd_jazz16_match, + .probe = snd_jazz16_probe, + .remove = snd_jazz16_remove, +#ifdef CONFIG_PM + .suspend = snd_jazz16_suspend, + .resume = snd_jazz16_resume, +#endif + .driver = { + .name = "jazz16" + }, +}; + +static int __init alsa_card_jazz16_init(void) +{ + return isa_register_driver(&snd_jazz16_driver, SNDRV_CARDS); +} + +static void __exit alsa_card_jazz16_exit(void) +{ + isa_unregister_driver(&snd_jazz16_driver); +} + +module_init(alsa_card_jazz16_init) +module_exit(alsa_card_jazz16_exit) diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 60e2c53c49f..3f694543a7e 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c @@ -1,6 +1,6 @@ /* * Driver for SoundBlaster 16/AWE32/AWE64 soundcards - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -19,12 +19,12 @@ * */ -#include <sound/driver.h> #include <asm/dma.h> #include <linux/init.h> -#include <linux/slab.h> #include <linux/pnp.h> -#include <linux/moduleparam.h> +#include <linux/err.h> +#include <linux/isa.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/sb.h> #include <sound/sb16_csp.h> @@ -32,7 +32,6 @@ #include <sound/opl3.h> #include <sound/emu8000.h> #include <sound/seq_device.h> -#define SNDRV_LEGACY_AUTO_PROBE #define SNDRV_LEGACY_FIND_FREE_IRQ #define SNDRV_LEGACY_FIND_FREE_DMA #include <sound/initval.h> @@ -43,7 +42,7 @@ #define PFX "sb16: " #endif -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_LICENSE("GPL"); #ifndef SNDRV_SBAWE MODULE_DESCRIPTION("Sound Blaster 16"); @@ -69,9 +68,9 @@ MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB AWE 32}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */ static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x330,0x300 */ @@ -84,7 +83,7 @@ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */ static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 5,6,7 */ static int mic_agc[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #ifdef CONFIG_SND_SB16_CSP -static int csp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; +static int csp[SNDRV_CARDS]; #endif #ifdef SNDRV_SBAWE_EMU8000 static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4}; @@ -127,8 +126,14 @@ module_param_array(seq_ports, int, NULL, 0444); MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth."); #endif +#ifdef CONFIG_PNP +static int isa_registered; +static int pnp_registered; +#endif + struct snd_card_sb16 { struct resource *fm_res; /* used to block FM i/o region for legacy cards */ + struct snd_sb *chip; #ifdef CONFIG_PNP int dev_no; struct pnp_dev *dev; @@ -138,8 +143,6 @@ struct snd_card_sb16 { #endif }; -static snd_card_t *snd_sb16_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; - #ifdef CONFIG_PNP static struct pnp_card_device_id snd_sb16_pnpids[] = { @@ -174,6 +177,8 @@ static struct pnp_card_device_id snd_sb16_pnpids[] = { { .id = "CTL0086", .devs = { { "CTL0041" } } }, /* Sound Blaster Vibra16X */ { .id = "CTL00f0", .devs = { { "CTL0043" } } }, + /* Sound Blaster 16 (Virtual PC 2004) */ + { .id = "tBA03b0", .devs = { {.id="PNPb003" } } }, #else /* SNDRV_SBAWE defined */ /* Sound Blaster AWE 32 PnP */ { .id = "CTL0035", .devs = { { "CTL0031" }, { "CTL0021" } } }, @@ -230,8 +235,6 @@ static struct pnp_card_device_id snd_sb16_pnpids[] = { { .id = "CTLXXXX" , .devs = { { "CTL0044" }, { "CTL0023" } } }, { .id = "CTLXXXX" , .devs = { { "CTL0045" }, { "CTL0022" } } }, #endif /* SNDRV_SBAWE */ - /* Sound Blaster 16 PnP (Virtual PC 2004)*/ - { .id = "tBA03b0", .devs = { { "PNPb003" } } }, { .id = "", } }; @@ -247,49 +250,26 @@ MODULE_DEVICE_TABLE(pnp_card, snd_sb16_pnpids); #ifdef CONFIG_PNP -static int __devinit snd_card_sb16_pnp(int dev, struct snd_card_sb16 *acard, - struct pnp_card_link *card, - const struct pnp_card_device_id *id) +static int snd_card_sb16_pnp(int dev, struct snd_card_sb16 *acard, + struct pnp_card_link *card, + const struct pnp_card_device_id *id) { struct pnp_dev *pdev; - struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); int err; - if (!cfg) - return -ENOMEM; acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL); - if (acard->dev == NULL) { - kfree(cfg); + if (acard->dev == NULL) return -ENODEV; - } + #ifdef SNDRV_SBAWE_EMU8000 acard->devwt = pnp_request_card_device(card, id->devs[1].id, acard->dev); #endif /* Audio initialization */ pdev = acard->dev; - pnp_init_resource_table(cfg); - - /* override resources */ - - if (port[dev] != SNDRV_AUTO_PORT) - pnp_resource_change(&cfg->port_resource[0], port[dev], 16); - if (mpu_port[dev] != SNDRV_AUTO_PORT) - pnp_resource_change(&cfg->port_resource[1], mpu_port[dev], 2); - if (fm_port[dev] != SNDRV_AUTO_PORT) - pnp_resource_change(&cfg->port_resource[2], fm_port[dev], 4); - if (dma8[dev] != SNDRV_AUTO_DMA) - pnp_resource_change(&cfg->dma_resource[0], dma8[dev], 1); - if (dma16[dev] != SNDRV_AUTO_DMA) - pnp_resource_change(&cfg->dma_resource[1], dma16[dev], 1); - if (irq[dev] != SNDRV_AUTO_IRQ) - pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1); - if (pnp_manual_config_dev(pdev, cfg, 0) < 0) - snd_printk(KERN_ERR PFX "AUDIO the requested resources are invalid, using auto config\n"); err = pnp_activate_dev(pdev); if (err < 0) { snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n"); - kfree(cfg); return err; } port[dev] = pnp_port_start(pdev, 0); @@ -306,23 +286,13 @@ static int __devinit snd_card_sb16_pnp(int dev, struct snd_card_sb16 *acard, /* WaveTable initialization */ pdev = acard->devwt; if (pdev != NULL) { - pnp_init_resource_table(cfg); - - /* override resources */ - - if (awe_port[dev] != SNDRV_AUTO_PORT) { - pnp_resource_change(&cfg->port_resource[0], awe_port[dev], 4); - pnp_resource_change(&cfg->port_resource[1], awe_port[dev] + 0x400, 4); - pnp_resource_change(&cfg->port_resource[2], awe_port[dev] + 0x800, 4); - } - if ((pnp_manual_config_dev(pdev, cfg, 0)) < 0) - snd_printk(KERN_ERR PFX "WaveTable the requested resources are invalid, using auto config\n"); err = pnp_activate_dev(pdev); if (err < 0) { goto __wt_error; } awe_port[dev] = pnp_port_start(pdev, 0); - snd_printdd("pnp SB16: wavetable port=0x%lx\n", pnp_port_start(pdev, 0)); + snd_printdd("pnp SB16: wavetable port=0x%llx\n", + (unsigned long long)pnp_port_start(pdev, 0)); } else { __wt_error: if (pdev) { @@ -333,97 +303,57 @@ __wt_error: awe_port[dev] = -1; } #endif - kfree(cfg); return 0; } #endif /* CONFIG_PNP */ -static void snd_sb16_free(snd_card_t *card) +static void snd_sb16_free(struct snd_card *card) { - struct snd_card_sb16 *acard = (struct snd_card_sb16 *)card->private_data; + struct snd_card_sb16 *acard = card->private_data; if (acard == NULL) return; - if (acard->fm_res) { - release_resource(acard->fm_res); - kfree_nocheck(acard->fm_res); - } + release_and_free_resource(acard->fm_res); +} + +#ifdef CONFIG_PNP +#define is_isapnp_selected(dev) isapnp[dev] +#else +#define is_isapnp_selected(dev) 0 +#endif + +static int snd_sb16_card_new(struct device *devptr, int dev, + struct snd_card **cardp) +{ + struct snd_card *card; + int err; + + err = snd_card_new(devptr, index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_card_sb16), &card); + if (err < 0) + return err; + card->private_free = snd_sb16_free; + *cardp = card; + return 0; } -static int __init snd_sb16_probe(int dev, - struct pnp_card_link *pcard, - const struct pnp_card_device_id *pid) +static int snd_sb16_probe(struct snd_card *card, int dev) { - static int possible_irqs[] = {5, 9, 10, 7, -1}; - static int possible_dmas8[] = {1, 3, 0, -1}; - static int possible_dmas16[] = {5, 6, 7, -1}; int xirq, xdma8, xdma16; - sb_t *chip; - snd_card_t *card; - struct snd_card_sb16 *acard; - opl3_t *opl3; - snd_hwdep_t *synth = NULL; + struct snd_sb *chip; + struct snd_card_sb16 *acard = card->private_data; + struct snd_opl3 *opl3; + struct snd_hwdep *synth = NULL; #ifdef CONFIG_SND_SB16_CSP - snd_hwdep_t *xcsp = NULL; + struct snd_hwdep *xcsp = NULL; #endif unsigned long flags; int err; - card = snd_card_new(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_sb16)); - if (card == NULL) - return -ENOMEM; - acard = (struct snd_card_sb16 *) card->private_data; - card->private_free = snd_sb16_free; -#ifdef CONFIG_PNP - if (isapnp[dev]) { - if ((err = snd_card_sb16_pnp(dev, acard, pcard, pid))) { - snd_card_free(card); - return err; - } - snd_card_set_dev(card, &pcard->card->dev); - } -#endif - xirq = irq[dev]; xdma8 = dma8[dev]; xdma16 = dma16[dev]; -#ifdef CONFIG_PNP - if (!isapnp[dev]) { -#endif - if (xirq == SNDRV_AUTO_IRQ) { - if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); - return -EBUSY; - } - } - if (xdma8 == SNDRV_AUTO_DMA) { - if ((xdma8 = snd_legacy_find_free_dma(possible_dmas8)) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n"); - return -EBUSY; - } - } - if (xdma16 == SNDRV_AUTO_DMA) { - if ((xdma16 = snd_legacy_find_free_dma(possible_dmas16)) < 0) { - snd_card_free(card); - snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n"); - return -EBUSY; - } - } - /* non-PnP FM port address is hardwired with base port address */ - fm_port[dev] = port[dev]; - /* block the 0x388 port to avoid PnP conflicts */ - acard->fm_res = request_region(0x388, 4, "SoundBlaster FM"); -#ifdef SNDRV_SBAWE_EMU8000 - /* non-PnP AWE port address is hardwired with base port address */ - awe_port[dev] = port[dev] + 0x400; -#endif -#ifdef CONFIG_PNP - } -#endif if ((err = snd_sbdsp_create(card, port[dev], @@ -432,28 +362,20 @@ static int __init snd_sb16_probe(int dev, xdma8, xdma16, SB_HW_AUTO, - &chip)) < 0) { - snd_card_free(card); + &chip)) < 0) return err; - } + + acard->chip = chip; if (chip->hardware != SB_HW_16) { - snd_card_free(card); - snd_printdd("SB 16 chip was not detected at 0x%lx\n", port[dev]); + snd_printk(KERN_ERR PFX "SB 16 chip was not detected at 0x%lx\n", port[dev]); return -ENODEV; } chip->mpu_port = mpu_port[dev]; -#ifdef CONFIG_PNP - if (!isapnp[dev] && (err = snd_sb16dsp_configure(chip)) < 0) { -#else - if ((err = snd_sb16dsp_configure(chip)) < 0) { -#endif - snd_card_free(card); - return -ENXIO; - } - if ((err = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { - snd_card_free(card); - return -ENXIO; - } + if (! is_isapnp_selected(dev) && (err = snd_sb16dsp_configure(chip)) < 0) + return err; + + if ((err = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0) + return err; strcpy(card->driver, #ifdef SNDRV_SBAWE_EMU8000 @@ -473,11 +395,10 @@ static int __init snd_sb16_probe(int dev, if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) { if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB, - chip->mpu_port, 0, - xirq, 0, &chip->rmidi)) < 0) { - snd_card_free(card); - return -ENXIO; - } + chip->mpu_port, + MPU401_INFO_IRQ_HOOK, -1, + &chip->rmidi)) < 0) + return err; chip->rmidi_callback = snd_mpu401_uart_interrupt; } @@ -499,17 +420,13 @@ static int __init snd_sb16_probe(int dev, #else int seqdev = 1; #endif - if ((err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth)) < 0) { - snd_card_free(card); - return -ENXIO; - } + if ((err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth)) < 0) + return err; } } - if ((err = snd_sbmixer_new(chip)) < 0) { - snd_card_free(card); - return -ENXIO; - } + if ((err = snd_sbmixer_new(chip)) < 0) + return err; #ifdef CONFIG_SND_SB16_CSP /* CSP chip on SB16ASP/AWE32 */ @@ -525,11 +442,11 @@ static int __init snd_sb16_probe(int dev, #endif #ifdef SNDRV_SBAWE_EMU8000 if (awe_port[dev] > 0) { - if (snd_emu8000_new(card, 1, awe_port[dev], - seq_ports[dev], NULL) < 0) { + if ((err = snd_emu8000_new(card, 1, awe_port[dev], + seq_ports[dev], NULL)) < 0) { snd_printk(KERN_ERR PFX "fatal error - EMU-8000 synthesizer not detected at 0x%lx\n", awe_port[dev]); - snd_card_free(card); - return -ENXIO; + + return err; } } #endif @@ -541,52 +458,170 @@ static int __init snd_sb16_probe(int dev, (mic_agc[dev] ? 0x00 : 0x01)); spin_unlock_irqrestore(&chip->mixer_lock, flags); - if ((err = snd_card_register(card)) < 0) { + if ((err = snd_card_register(card)) < 0) + return err; + + return 0; +} + +#ifdef CONFIG_PM +static int snd_sb16_suspend(struct snd_card *card, pm_message_t state) +{ + struct snd_card_sb16 *acard = card->private_data; + struct snd_sb *chip = acard->chip; + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + snd_pcm_suspend_all(chip->pcm); + snd_sbmixer_suspend(chip); + return 0; +} + +static int snd_sb16_resume(struct snd_card *card) +{ + struct snd_card_sb16 *acard = card->private_data; + struct snd_sb *chip = acard->chip; + + snd_sbdsp_reset(chip); + snd_sbmixer_resume(chip); + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +#endif + +static int snd_sb16_isa_probe1(int dev, struct device *pdev) +{ + struct snd_card_sb16 *acard; + struct snd_card *card; + int err; + + err = snd_sb16_card_new(pdev, dev, &card); + if (err < 0) + return err; + + acard = card->private_data; + /* non-PnP FM port address is hardwired with base port address */ + fm_port[dev] = port[dev]; + /* block the 0x388 port to avoid PnP conflicts */ + acard->fm_res = request_region(0x388, 4, "SoundBlaster FM"); +#ifdef SNDRV_SBAWE_EMU8000 + /* non-PnP AWE port address is hardwired with base port address */ + awe_port[dev] = port[dev] + 0x400; +#endif + + if ((err = snd_sb16_probe(card, dev)) < 0) { snd_card_free(card); return err; } - if (pcard) - pnp_set_card_drvdata(pcard, card); - else - snd_sb16_legacy[dev] = card; + dev_set_drvdata(pdev, card); return 0; } -static int __init snd_sb16_probe_legacy_port(unsigned long xport) + +static int snd_sb16_isa_match(struct device *pdev, unsigned int dev) { - static int dev; - int res; + return enable[dev] && !is_isapnp_selected(dev); +} - for ( ; dev < SNDRV_CARDS; dev++) { - if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT) - continue; -#ifdef CONFIG_PNP - if (isapnp[dev]) - continue; -#endif - port[dev] = xport; - res = snd_sb16_probe(dev, NULL, NULL); - if (res < 0) - port[dev] = SNDRV_AUTO_PORT; - return res; +static int snd_sb16_isa_probe(struct device *pdev, unsigned int dev) +{ + int err; + static int possible_irqs[] = {5, 9, 10, 7, -1}; + static int possible_dmas8[] = {1, 3, 0, -1}; + static int possible_dmas16[] = {5, 6, 7, -1}; + + if (irq[dev] == SNDRV_AUTO_IRQ) { + if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) { + snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); + return -EBUSY; + } + } + if (dma8[dev] == SNDRV_AUTO_DMA) { + if ((dma8[dev] = snd_legacy_find_free_dma(possible_dmas8)) < 0) { + snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n"); + return -EBUSY; + } + } + if (dma16[dev] == SNDRV_AUTO_DMA) { + if ((dma16[dev] = snd_legacy_find_free_dma(possible_dmas16)) < 0) { + snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n"); + return -EBUSY; + } + } + + if (port[dev] != SNDRV_AUTO_PORT) + return snd_sb16_isa_probe1(dev, pdev); + else { + static int possible_ports[] = {0x220, 0x240, 0x260, 0x280}; + int i; + for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { + port[dev] = possible_ports[i]; + err = snd_sb16_isa_probe1(dev, pdev); + if (! err) + return 0; + } + return err; } - return -ENODEV; } -#ifdef CONFIG_PNP +static int snd_sb16_isa_remove(struct device *pdev, unsigned int dev) +{ + snd_card_free(dev_get_drvdata(pdev)); + return 0; +} + +#ifdef CONFIG_PM +static int snd_sb16_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) +{ + return snd_sb16_suspend(dev_get_drvdata(dev), state); +} + +static int snd_sb16_isa_resume(struct device *dev, unsigned int n) +{ + return snd_sb16_resume(dev_get_drvdata(dev)); +} +#endif + +#ifdef SNDRV_SBAWE +#define DEV_NAME "sbawe" +#else +#define DEV_NAME "sb16" +#endif + +static struct isa_driver snd_sb16_isa_driver = { + .match = snd_sb16_isa_match, + .probe = snd_sb16_isa_probe, + .remove = snd_sb16_isa_remove, +#ifdef CONFIG_PM + .suspend = snd_sb16_isa_suspend, + .resume = snd_sb16_isa_resume, +#endif + .driver = { + .name = DEV_NAME + }, +}; -static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *card, - const struct pnp_card_device_id *id) + +#ifdef CONFIG_PNP +static int snd_sb16_pnp_detect(struct pnp_card_link *pcard, + const struct pnp_card_device_id *pid) { static int dev; + struct snd_card *card; int res; for ( ; dev < SNDRV_CARDS; dev++) { if (!enable[dev] || !isapnp[dev]) continue; - res = snd_sb16_probe(dev, card, id); + res = snd_sb16_card_new(&pcard->card->dev, dev, &card); if (res < 0) return res; + if ((res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid)) < 0 || + (res = snd_sb16_probe(card, dev)) < 0) { + snd_card_free(card); + return res; + } + pnp_set_card_drvdata(pcard, card); dev++; return 0; } @@ -594,84 +629,68 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *card, return -ENODEV; } -static void __devexit snd_sb16_pnp_remove(struct pnp_card_link * pcard) +static void snd_sb16_pnp_remove(struct pnp_card_link *pcard) { - snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard); + snd_card_free(pnp_get_card_drvdata(pcard)); + pnp_set_card_drvdata(pcard, NULL); +} - snd_card_disconnect(card); - snd_card_free_in_thread(card); +#ifdef CONFIG_PM +static int snd_sb16_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state) +{ + return snd_sb16_suspend(pnp_get_card_drvdata(pcard), state); } +static int snd_sb16_pnp_resume(struct pnp_card_link *pcard) +{ + return snd_sb16_resume(pnp_get_card_drvdata(pcard)); +} +#endif static struct pnp_card_driver sb16_pnpc_driver = { .flags = PNP_DRIVER_RES_DISABLE, +#ifdef SNDRV_SBAWE + .name = "sbawe", +#else .name = "sb16", +#endif .id_table = snd_sb16_pnpids, .probe = snd_sb16_pnp_detect, - .remove = __devexit_p(snd_sb16_pnp_remove), + .remove = snd_sb16_pnp_remove, +#ifdef CONFIG_PM + .suspend = snd_sb16_pnp_suspend, + .resume = snd_sb16_pnp_resume, +#endif }; #endif /* CONFIG_PNP */ static int __init alsa_card_sb16_init(void) { - int dev, cards = 0, i; - static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280, -1}; + int err; - /* legacy non-auto cards at first */ - for (dev = 0; dev < SNDRV_CARDS; dev++) { - if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT) - continue; + err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS); #ifdef CONFIG_PNP - if (isapnp[dev]) - continue; -#endif - if (!snd_sb16_probe(dev, NULL, NULL)) { - cards++; - continue; - } -#ifdef MODULE - snd_printk(KERN_ERR "Sound Blaster 16+ soundcard #%i not found at 0x%lx or device busy\n", dev, port[dev]); -#endif - } - /* legacy auto configured cards */ - i = snd_legacy_auto_probe(possible_ports, snd_sb16_probe_legacy_port); - if (i > 0) - cards += i; + if (!err) + isa_registered = 1; -#ifdef CONFIG_PNP - /* PnP cards at last */ - i = pnp_register_card_driver(&sb16_pnpc_driver); - if (i >0) - cards += i; -#endif + err = pnp_register_card_driver(&sb16_pnpc_driver); + if (!err) + pnp_registered = 1; - if (!cards) { -#ifdef CONFIG_PNP - pnp_unregister_card_driver(&sb16_pnpc_driver); -#endif -#ifdef MODULE - snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n"); -#ifdef SNDRV_SBAWE_EMU8000 - snd_printk(KERN_ERR "In case, if you have non-AWE card, try snd-sb16 module\n"); -#else - snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n"); + if (isa_registered) + err = 0; #endif -#endif - return -ENODEV; - } - return 0; + return err; } static void __exit alsa_card_sb16_exit(void) { - int dev; - #ifdef CONFIG_PNP - /* PnP cards first */ - pnp_unregister_card_driver(&sb16_pnpc_driver); + if (pnp_registered) + pnp_unregister_card_driver(&sb16_pnpc_driver); + if (isa_registered) #endif - for (dev = 0; dev < SNDRV_CARDS; dev++) - snd_card_free(snd_sb16_legacy[dev]); + isa_unregister_driver(&snd_sb16_isa_driver); } module_init(alsa_card_sb16_init) diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index b62920eead3..48da2276683 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c @@ -23,10 +23,10 @@ * */ -#include <sound/driver.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/control.h> #include <sound/info.h> @@ -36,14 +36,17 @@ MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>"); MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("sb16/mulaw_main.csp"); +MODULE_FIRMWARE("sb16/alaw_main.csp"); +MODULE_FIRMWARE("sb16/ima_adpcm_init.csp"); +MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp"); +MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp"); #ifdef SNDRV_LITTLE_ENDIAN #define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) #else #define CSP_HDR_VALUE(a,b,c,d) ((d) | ((c)<<8) | ((b)<<16) | ((a)<<24)) #endif -#define LE_SHORT(v) le16_to_cpu(v) -#define LE_INT(v) le32_to_cpu(v) #define RIFF_HEADER CSP_HDR_VALUE('R', 'I', 'F', 'F') #define CSP__HEADER CSP_HDR_VALUE('C', 'S', 'P', ' ') @@ -56,64 +59,66 @@ MODULE_LICENSE("GPL"); /* * RIFF data format */ -typedef struct riff_header { +struct riff_header { __u32 name; __u32 len; -} riff_header_t; +}; -typedef struct desc_header { - riff_header_t info; +struct desc_header { + struct riff_header info; __u16 func_nr; __u16 VOC_type; __u16 flags_play_rec; __u16 flags_16bit_8bit; __u16 flags_stereo_mono; __u16 flags_rates; -} desc_header_t; +}; /* * prototypes */ -static void snd_sb_csp_free(snd_hwdep_t *hw); -static int snd_sb_csp_open(snd_hwdep_t * hw, struct file *file); -static int snd_sb_csp_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg); -static int snd_sb_csp_release(snd_hwdep_t * hw, struct file *file); - -static int csp_detect(sb_t *chip, int *version); -static int set_codec_parameter(sb_t *chip, unsigned char par, unsigned char val); -static int set_register(sb_t *chip, unsigned char reg, unsigned char val); -static int read_register(sb_t *chip, unsigned char reg); -static int set_mode_register(sb_t *chip, unsigned char mode); -static int get_version(sb_t *chip); - -static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user * code); -static int snd_sb_csp_unload(snd_sb_csp_t * p); -static int snd_sb_csp_load_user(snd_sb_csp_t * p, const unsigned char __user *buf, int size, int load_flags); -static int snd_sb_csp_autoload(snd_sb_csp_t * p, int pcm_sfmt, int play_rec_mode); -static int snd_sb_csp_check_version(snd_sb_csp_t * p); - -static int snd_sb_csp_use(snd_sb_csp_t * p); -static int snd_sb_csp_unuse(snd_sb_csp_t * p); -static int snd_sb_csp_start(snd_sb_csp_t * p, int sample_width, int channels); -static int snd_sb_csp_stop(snd_sb_csp_t * p); -static int snd_sb_csp_pause(snd_sb_csp_t * p); -static int snd_sb_csp_restart(snd_sb_csp_t * p); - -static int snd_sb_qsound_build(snd_sb_csp_t * p); -static void snd_sb_qsound_destroy(snd_sb_csp_t * p); -static int snd_sb_csp_qsound_transfer(snd_sb_csp_t * p); - -static int init_proc_entry(snd_sb_csp_t * p, int device); -static void info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer); +static void snd_sb_csp_free(struct snd_hwdep *hw); +static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file); +static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg); +static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file); + +static int csp_detect(struct snd_sb *chip, int *version); +static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val); +static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val); +static int read_register(struct snd_sb *chip, unsigned char reg); +static int set_mode_register(struct snd_sb *chip, unsigned char mode); +static int get_version(struct snd_sb *chip); + +static int snd_sb_csp_riff_load(struct snd_sb_csp * p, + struct snd_sb_csp_microcode __user * code); +static int snd_sb_csp_unload(struct snd_sb_csp * p); +static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags); +static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode); +static int snd_sb_csp_check_version(struct snd_sb_csp * p); + +static int snd_sb_csp_use(struct snd_sb_csp * p); +static int snd_sb_csp_unuse(struct snd_sb_csp * p); +static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels); +static int snd_sb_csp_stop(struct snd_sb_csp * p); +static int snd_sb_csp_pause(struct snd_sb_csp * p); +static int snd_sb_csp_restart(struct snd_sb_csp * p); + +static int snd_sb_qsound_build(struct snd_sb_csp * p); +static void snd_sb_qsound_destroy(struct snd_sb_csp * p); +static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p); + +static int init_proc_entry(struct snd_sb_csp * p, int device); +static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer); /* * Detect CSP chip and create a new instance */ -int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep) +int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep) { - snd_sb_csp_t *p; - int version, err; - snd_hwdep_t *hw; + struct snd_sb_csp *p; + int uninitialized_var(version); + int err; + struct snd_hwdep *hw; if (rhwdep) *rhwdep = NULL; @@ -124,7 +129,7 @@ int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep) if ((err = snd_hwdep_new(chip->card, "SB16-CSP", device, &hw)) < 0) return err; - if ((p = kcalloc(1, sizeof(*p), GFP_KERNEL)) == NULL) { + if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) { snd_device_free(chip->card, hw); return -ENOMEM; } @@ -139,7 +144,7 @@ int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep) p->ops.csp_stop = snd_sb_csp_stop; p->ops.csp_qsound_transfer = snd_sb_csp_qsound_transfer; - init_MUTEX(&p->access_mutex); + mutex_init(&p->access_mutex); sprintf(hw->name, "CSP v%d.%d", (version >> 4), (version & 0x0f)); hw->iface = SNDRV_HWDEP_IFACE_SB16CSP; hw->private_data = p; @@ -160,12 +165,15 @@ int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep) /* * free_private for hwdep instance */ -static void snd_sb_csp_free(snd_hwdep_t *hwdep) +static void snd_sb_csp_free(struct snd_hwdep *hwdep) { - snd_sb_csp_t *p = hwdep->private_data; + int i; + struct snd_sb_csp *p = hwdep->private_data; if (p) { if (p->running & SNDRV_SB_CSP_ST_RUNNING) snd_sb_csp_stop(p); + for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i) + release_firmware(p->csp_programs[i]); kfree(p); } } @@ -175,23 +183,24 @@ static void snd_sb_csp_free(snd_hwdep_t *hwdep) /* * open the device exclusively */ -static int snd_sb_csp_open(snd_hwdep_t * hw, struct file *file) +static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file) { - snd_sb_csp_t *p = hw->private_data; + struct snd_sb_csp *p = hw->private_data; return (snd_sb_csp_use(p)); } /* * ioctl for hwdep device: */ -static int snd_sb_csp_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg) +static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg) { - snd_sb_csp_t *p = hw->private_data; - snd_sb_csp_info_t info; - snd_sb_csp_start_t start_info; + struct snd_sb_csp *p = hw->private_data; + struct snd_sb_csp_info info; + struct snd_sb_csp_start start_info; int err; - snd_assert(p != NULL, return -EINVAL); + if (snd_BUG_ON(!p)) + return -EINVAL; if (snd_sb_csp_check_version(p)) return -ENODEV; @@ -199,6 +208,7 @@ static int snd_sb_csp_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cm switch (cmd) { /* get information */ case SNDRV_SB_CSP_IOCTL_INFO: + memset(&info, 0, sizeof(info)); *info.codec_name = *p->codec_name; info.func_nr = p->func_nr; info.acc_format = p->acc_format; @@ -219,7 +229,7 @@ static int snd_sb_csp_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cm /* load CSP microcode */ case SNDRV_SB_CSP_IOCTL_LOAD_CODE: err = (p->running & SNDRV_SB_CSP_ST_RUNNING ? - -EBUSY : snd_sb_csp_riff_load(p, (snd_sb_csp_microcode_t __user *) arg)); + -EBUSY : snd_sb_csp_riff_load(p, (struct snd_sb_csp_microcode __user *) arg)); break; case SNDRV_SB_CSP_IOCTL_UNLOAD_CODE: err = (p->running & SNDRV_SB_CSP_ST_RUNNING ? @@ -253,9 +263,9 @@ static int snd_sb_csp_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cm /* * close the device */ -static int snd_sb_csp_release(snd_hwdep_t * hw, struct file *file) +static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file) { - snd_sb_csp_t *p = hw->private_data; + struct snd_sb_csp *p = hw->private_data; return (snd_sb_csp_unuse(p)); } @@ -264,15 +274,15 @@ static int snd_sb_csp_release(snd_hwdep_t * hw, struct file *file) /* * acquire device */ -static int snd_sb_csp_use(snd_sb_csp_t * p) +static int snd_sb_csp_use(struct snd_sb_csp * p) { - down(&p->access_mutex); + mutex_lock(&p->access_mutex); if (p->used) { - up(&p->access_mutex); + mutex_unlock(&p->access_mutex); return -EAGAIN; } p->used++; - up(&p->access_mutex); + mutex_unlock(&p->access_mutex); return 0; @@ -281,11 +291,11 @@ static int snd_sb_csp_use(snd_sb_csp_t * p) /* * release device */ -static int snd_sb_csp_unuse(snd_sb_csp_t * p) +static int snd_sb_csp_unuse(struct snd_sb_csp * p) { - down(&p->access_mutex); + mutex_lock(&p->access_mutex); p->used--; - up(&p->access_mutex); + mutex_unlock(&p->access_mutex); return 0; } @@ -294,17 +304,18 @@ static int snd_sb_csp_unuse(snd_sb_csp_t * p) * load microcode via ioctl: * code is user-space pointer */ -static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user * mcode) +static int snd_sb_csp_riff_load(struct snd_sb_csp * p, + struct snd_sb_csp_microcode __user * mcode) { - snd_sb_csp_mc_header_t info; + struct snd_sb_csp_mc_header info; unsigned char __user *data_ptr; unsigned char __user *data_end; unsigned short func_nr = 0; - riff_header_t file_h, item_h, code_h; + struct riff_header file_h, item_h, code_h; __u32 item_type; - desc_header_t funcdesc_h; + struct desc_header funcdesc_h; unsigned long flags; int err; @@ -316,22 +327,22 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user if (copy_from_user(&file_h, data_ptr, sizeof(file_h))) return -EFAULT; if ((file_h.name != RIFF_HEADER) || - (LE_INT(file_h.len) >= SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE - sizeof(file_h))) { - snd_printd("%s: Invalid RIFF header\n", __FUNCTION__); + (le32_to_cpu(file_h.len) >= SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE - sizeof(file_h))) { + snd_printd("%s: Invalid RIFF header\n", __func__); return -EINVAL; } data_ptr += sizeof(file_h); - data_end = data_ptr + LE_INT(file_h.len); + data_end = data_ptr + le32_to_cpu(file_h.len); if (copy_from_user(&item_type, data_ptr, sizeof(item_type))) return -EFAULT; if (item_type != CSP__HEADER) { - snd_printd("%s: Invalid RIFF file type\n", __FUNCTION__); + snd_printd("%s: Invalid RIFF file type\n", __func__); return -EINVAL; } data_ptr += sizeof (item_type); - for (; data_ptr < data_end; data_ptr += LE_INT(item_h.len)) { + for (; data_ptr < data_end; data_ptr += le32_to_cpu(item_h.len)) { if (copy_from_user(&item_h, data_ptr, sizeof(item_h))) return -EFAULT; data_ptr += sizeof(item_h); @@ -344,7 +355,7 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user case FUNC_HEADER: if (copy_from_user(&funcdesc_h, data_ptr + sizeof(item_type), sizeof(funcdesc_h))) return -EFAULT; - func_nr = LE_SHORT(funcdesc_h.func_nr); + func_nr = le16_to_cpu(funcdesc_h.func_nr); break; case CODE_HEADER: if (func_nr != info.func_req) @@ -370,33 +381,33 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user if (code_h.name != INIT_HEADER) break; data_ptr += sizeof(code_h); - err = snd_sb_csp_load_user(p, data_ptr, LE_INT(code_h.len), + err = snd_sb_csp_load_user(p, data_ptr, le32_to_cpu(code_h.len), SNDRV_SB_CSP_LOAD_INITBLOCK); if (err) return err; - data_ptr += LE_INT(code_h.len); + data_ptr += le32_to_cpu(code_h.len); } /* main microcode block */ if (copy_from_user(&code_h, data_ptr, sizeof(code_h))) return -EFAULT; if (code_h.name != MAIN_HEADER) { - snd_printd("%s: Missing 'main' microcode\n", __FUNCTION__); + snd_printd("%s: Missing 'main' microcode\n", __func__); return -EINVAL; } data_ptr += sizeof(code_h); err = snd_sb_csp_load_user(p, data_ptr, - LE_INT(code_h.len), 0); + le32_to_cpu(code_h.len), 0); if (err) return err; /* fill in codec header */ strlcpy(p->codec_name, info.codec_name, sizeof(p->codec_name)); p->func_nr = func_nr; - p->mode = LE_SHORT(funcdesc_h.flags_play_rec); - switch (LE_SHORT(funcdesc_h.VOC_type)) { + p->mode = le16_to_cpu(funcdesc_h.flags_play_rec); + switch (le16_to_cpu(funcdesc_h.VOC_type)) { case 0x0001: /* QSound decoder */ - if (LE_SHORT(funcdesc_h.flags_play_rec) == SNDRV_SB_CSP_MODE_DSP_WRITE) { + if (le16_to_cpu(funcdesc_h.flags_play_rec) == SNDRV_SB_CSP_MODE_DSP_WRITE) { if (snd_sb_qsound_build(p) == 0) /* set QSound flag and clear all other mode flags */ p->mode = SNDRV_SB_CSP_MODE_QSOUND; @@ -425,13 +436,13 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user p->acc_format = p->acc_width = p->acc_rates = 0; p->mode = 0; snd_printd("%s: Unsupported CSP codec type: 0x%04x\n", - __FUNCTION__, - LE_SHORT(funcdesc_h.VOC_type)); + __func__, + le16_to_cpu(funcdesc_h.VOC_type)); return -EINVAL; } - p->acc_channels = LE_SHORT(funcdesc_h.flags_stereo_mono); - p->acc_width = LE_SHORT(funcdesc_h.flags_16bit_8bit); - p->acc_rates = LE_SHORT(funcdesc_h.flags_rates); + p->acc_channels = le16_to_cpu(funcdesc_h.flags_stereo_mono); + p->acc_width = le16_to_cpu(funcdesc_h.flags_16bit_8bit); + p->acc_rates = le16_to_cpu(funcdesc_h.flags_rates); /* Decouple CSP from IRQ and DMAREQ lines */ spin_lock_irqsave(&p->chip->reg_lock, flags); @@ -444,14 +455,14 @@ static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user return 0; } } - snd_printd("%s: Function #%d not found\n", __FUNCTION__, info.func_req); + snd_printd("%s: Function #%d not found\n", __func__, info.func_req); return -EINVAL; } /* * unload CSP microcode */ -static int snd_sb_csp_unload(snd_sb_csp_t * p) +static int snd_sb_csp_unload(struct snd_sb_csp * p) { if (p->running & SNDRV_SB_CSP_ST_RUNNING) return -EBUSY; @@ -474,7 +485,7 @@ static int snd_sb_csp_unload(snd_sb_csp_t * p) /* * send command sequence to DSP */ -static inline int command_seq(sb_t *chip, const unsigned char *seq, int size) +static inline int command_seq(struct snd_sb *chip, const unsigned char *seq, int size) { int i; for (i = 0; i < size; i++) { @@ -487,7 +498,7 @@ static inline int command_seq(sb_t *chip, const unsigned char *seq, int size) /* * set CSP codec parameter */ -static int set_codec_parameter(sb_t *chip, unsigned char par, unsigned char val) +static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val) { unsigned char dsp_cmd[3]; @@ -504,7 +515,7 @@ static int set_codec_parameter(sb_t *chip, unsigned char par, unsigned char val) /* * set CSP register */ -static int set_register(sb_t *chip, unsigned char reg, unsigned char val) +static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val) { unsigned char dsp_cmd[3]; @@ -518,7 +529,7 @@ static int set_register(sb_t *chip, unsigned char reg, unsigned char val) * read CSP register * return < 0 -> error */ -static int read_register(sb_t *chip, unsigned char reg) +static int read_register(struct snd_sb *chip, unsigned char reg) { unsigned char dsp_cmd[2]; @@ -531,7 +542,7 @@ static int read_register(sb_t *chip, unsigned char reg) /* * set CSP mode register */ -static int set_mode_register(sb_t *chip, unsigned char mode) +static int set_mode_register(struct snd_sb *chip, unsigned char mode) { unsigned char dsp_cmd[2]; @@ -544,7 +555,7 @@ static int set_mode_register(sb_t *chip, unsigned char mode) * Detect CSP * return 0 if CSP exists. */ -static int csp_detect(sb_t *chip, int *version) +static int csp_detect(struct snd_sb *chip, int *version) { unsigned char csp_test1, csp_test2; unsigned long flags; @@ -581,7 +592,7 @@ static int csp_detect(sb_t *chip, int *version) /* * get CSP version number */ -static int get_version(sb_t *chip) +static int get_version(struct snd_sb *chip) { unsigned char dsp_cmd[2]; @@ -595,10 +606,10 @@ static int get_version(sb_t *chip) /* * check if the CSP version is valid */ -static int snd_sb_csp_check_version(snd_sb_csp_t * p) +static int snd_sb_csp_check_version(struct snd_sb_csp * p) { if (p->version < 0x10 || p->version > 0x1f) { - snd_printd("%s: Invalid CSP version: 0x%x\n", __FUNCTION__, p->version); + snd_printd("%s: Invalid CSP version: 0x%x\n", __func__, p->version); return 1; } return 0; @@ -607,7 +618,7 @@ static int snd_sb_csp_check_version(snd_sb_csp_t * p) /* * download microcode to CSP (microcode should have one "main" block). */ -static int snd_sb_csp_load(snd_sb_csp_t * p, const unsigned char *buf, int size, int load_flags) +static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int size, int load_flags) { int status, i; int err; @@ -617,7 +628,7 @@ static int snd_sb_csp_load(snd_sb_csp_t * p, const unsigned char *buf, int size, spin_lock_irqsave(&p->chip->reg_lock, flags); snd_sbdsp_command(p->chip, 0x01); /* CSP download command */ if (snd_sbdsp_get_byte(p->chip)) { - snd_printd("%s: Download command failed\n", __FUNCTION__); + snd_printd("%s: Download command failed\n", __func__); goto __fail; } /* Send CSP low byte (size - 1) */ @@ -644,7 +655,7 @@ static int snd_sb_csp_load(snd_sb_csp_t * p, const unsigned char *buf, int size, udelay (10); } if (status != 0x55) { - snd_printd("%s: Microcode initialization failed\n", __FUNCTION__); + snd_printd("%s: Microcode initialization failed\n", __func__); goto __fail; } } else { @@ -673,27 +684,49 @@ static int snd_sb_csp_load(snd_sb_csp_t * p, const unsigned char *buf, int size, return result; } -static int snd_sb_csp_load_user(snd_sb_csp_t * p, const unsigned char __user *buf, int size, int load_flags) +static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags) { - int err = -ENOMEM; - unsigned char *kbuf = kmalloc(size, GFP_KERNEL); - if (kbuf) { - if (copy_from_user(kbuf, buf, size)) - err = -EFAULT; - else - err = snd_sb_csp_load(p, kbuf, size, load_flags); - kfree(kbuf); - } + int err; + unsigned char *kbuf; + + kbuf = memdup_user(buf, size); + if (IS_ERR(kbuf)) + return PTR_ERR(kbuf); + + err = snd_sb_csp_load(p, kbuf, size, load_flags); + + kfree(kbuf); return err; } -#include "sb16_csp_codecs.h" +static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags) +{ + static const char *const names[] = { + "sb16/mulaw_main.csp", + "sb16/alaw_main.csp", + "sb16/ima_adpcm_init.csp", + "sb16/ima_adpcm_playback.csp", + "sb16/ima_adpcm_capture.csp", + }; + const struct firmware *program; + + BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT); + program = p->csp_programs[index]; + if (!program) { + int err = request_firmware(&program, names[index], + p->chip->card->dev); + if (err < 0) + return err; + p->csp_programs[index] = program; + } + return snd_sb_csp_load(p, program->data, program->size, flags); +} /* * autoload hardware codec if necessary * return 0 if CSP is loaded and ready to run (p->running != 0) */ -static int snd_sb_csp_autoload(snd_sb_csp_t * p, int pcm_sfmt, int play_rec_mode) +static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode) { unsigned long flags; int err = 0; @@ -708,27 +741,27 @@ static int snd_sb_csp_autoload(snd_sb_csp_t * p, int pcm_sfmt, int play_rec_mode } else { switch (pcm_sfmt) { case SNDRV_PCM_FORMAT_MU_LAW: - err = snd_sb_csp_load(p, &mulaw_main[0], sizeof(mulaw_main), 0); + err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_MULAW, 0); p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW; p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE; break; case SNDRV_PCM_FORMAT_A_LAW: - err = snd_sb_csp_load(p, &alaw_main[0], sizeof(alaw_main), 0); + err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ALAW, 0); p->acc_format = SNDRV_PCM_FMTBIT_A_LAW; p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE; break; case SNDRV_PCM_FORMAT_IMA_ADPCM: - err = snd_sb_csp_load(p, &ima_adpcm_init[0], sizeof(ima_adpcm_init), - SNDRV_SB_CSP_LOAD_INITBLOCK); + err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ADPCM_INIT, + SNDRV_SB_CSP_LOAD_INITBLOCK); if (err) break; if (play_rec_mode == SNDRV_SB_CSP_MODE_DSP_WRITE) { - err = snd_sb_csp_load(p, &ima_adpcm_playback[0], - sizeof(ima_adpcm_playback), 0); + err = snd_sb_csp_firmware_load + (p, CSP_PROGRAM_ADPCM_PLAYBACK, 0); p->mode = SNDRV_SB_CSP_MODE_DSP_WRITE; } else { - err = snd_sb_csp_load(p, &ima_adpcm_capture[0], - sizeof(ima_adpcm_capture), 0); + err = snd_sb_csp_firmware_load + (p, CSP_PROGRAM_ADPCM_CAPTURE, 0); p->mode = SNDRV_SB_CSP_MODE_DSP_READ; } p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM; @@ -765,7 +798,7 @@ static int snd_sb_csp_autoload(snd_sb_csp_t * p, int pcm_sfmt, int play_rec_mode /* * start CSP */ -static int snd_sb_csp_start(snd_sb_csp_t * p, int sample_width, int channels) +static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels) { unsigned char s_type; /* sample type */ unsigned char mixL, mixR; @@ -773,19 +806,19 @@ static int snd_sb_csp_start(snd_sb_csp_t * p, int sample_width, int channels) unsigned long flags; if (!(p->running & (SNDRV_SB_CSP_ST_LOADED | SNDRV_SB_CSP_ST_AUTO))) { - snd_printd("%s: Microcode not loaded\n", __FUNCTION__); + snd_printd("%s: Microcode not loaded\n", __func__); return -ENXIO; } if (p->running & SNDRV_SB_CSP_ST_RUNNING) { - snd_printd("%s: CSP already running\n", __FUNCTION__); + snd_printd("%s: CSP already running\n", __func__); return -EBUSY; } if (!(sample_width & p->acc_width)) { - snd_printd("%s: Unsupported PCM sample width\n", __FUNCTION__); + snd_printd("%s: Unsupported PCM sample width\n", __func__); return -EINVAL; } if (!(channels & p->acc_channels)) { - snd_printd("%s: Invalid number of channels\n", __FUNCTION__); + snd_printd("%s: Invalid number of channels\n", __func__); return -EINVAL; } @@ -807,11 +840,11 @@ static int snd_sb_csp_start(snd_sb_csp_t * p, int sample_width, int channels) s_type |= 0x22; /* 00dX 00dX (d = 1 if 8 bit samples) */ if (set_codec_parameter(p->chip, 0x81, s_type)) { - snd_printd("%s: Set sample type command failed\n", __FUNCTION__); + snd_printd("%s: Set sample type command failed\n", __func__); goto __fail; } if (set_codec_parameter(p->chip, 0x80, 0x00)) { - snd_printd("%s: Codec start command failed\n", __FUNCTION__); + snd_printd("%s: Codec start command failed\n", __func__); goto __fail; } p->run_width = sample_width; @@ -844,7 +877,7 @@ static int snd_sb_csp_start(snd_sb_csp_t * p, int sample_width, int channels) /* * stop CSP */ -static int snd_sb_csp_stop(snd_sb_csp_t * p) +static int snd_sb_csp_stop(struct snd_sb_csp * p) { int result; unsigned char mixL, mixR; @@ -885,7 +918,7 @@ static int snd_sb_csp_stop(snd_sb_csp_t * p) /* * pause CSP codec and hold DMA transfer */ -static int snd_sb_csp_pause(snd_sb_csp_t * p) +static int snd_sb_csp_pause(struct snd_sb_csp * p) { int result; unsigned long flags; @@ -905,7 +938,7 @@ static int snd_sb_csp_pause(snd_sb_csp_t * p) /* * restart CSP codec and resume DMA transfer */ -static int snd_sb_csp_restart(snd_sb_csp_t * p) +static int snd_sb_csp_restart(struct snd_sb_csp * p) { int result; unsigned long flags; @@ -928,26 +961,19 @@ static int snd_sb_csp_restart(snd_sb_csp_t * p) * QSound mixer control for PCM */ -static int snd_sb_qsound_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define snd_sb_qsound_switch_info snd_ctl_boolean_mono_info -static int snd_sb_qsound_switch_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sb_qsound_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - snd_sb_csp_t *p = snd_kcontrol_chip(kcontrol); + struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = p->q_enabled ? 1 : 0; return 0; } -static int snd_sb_qsound_switch_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sb_qsound_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - snd_sb_csp_t *p = snd_kcontrol_chip(kcontrol); + struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned char nval; @@ -960,7 +986,7 @@ static int snd_sb_qsound_switch_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu return change; } -static int snd_sb_qsound_space_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int snd_sb_qsound_space_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 2; @@ -969,9 +995,9 @@ static int snd_sb_qsound_space_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_ return 0; } -static int snd_sb_qsound_space_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sb_qsound_space_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - snd_sb_csp_t *p = snd_kcontrol_chip(kcontrol); + struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol); unsigned long flags; spin_lock_irqsave(&p->q_lock, flags); @@ -981,9 +1007,9 @@ static int snd_sb_qsound_space_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value return 0; } -static int snd_sb_qsound_space_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - snd_sb_csp_t *p = snd_kcontrol_chip(kcontrol); + struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned char nval1, nval2; @@ -1003,7 +1029,7 @@ static int snd_sb_qsound_space_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value return change; } -static snd_kcontrol_new_t snd_sb_qsound_switch = { +static struct snd_kcontrol_new snd_sb_qsound_switch = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "3D Control - Switch", .info = snd_sb_qsound_switch_info, @@ -1011,7 +1037,7 @@ static snd_kcontrol_new_t snd_sb_qsound_switch = { .put = snd_sb_qsound_switch_put }; -static snd_kcontrol_new_t snd_sb_qsound_space = { +static struct snd_kcontrol_new snd_sb_qsound_space = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "3D Control - Space", .info = snd_sb_qsound_space_info, @@ -1019,12 +1045,13 @@ static snd_kcontrol_new_t snd_sb_qsound_space = { .put = snd_sb_qsound_space_put }; -static int snd_sb_qsound_build(snd_sb_csp_t * p) +static int snd_sb_qsound_build(struct snd_sb_csp * p) { - snd_card_t * card; + struct snd_card *card; int err; - snd_assert(p != NULL, return -EINVAL); + if (snd_BUG_ON(!p)) + return -EINVAL; card = p->chip->card; p->qpos_left = p->qpos_right = SNDRV_SB_CSP_QSOUND_MAX_RIGHT / 2; @@ -1044,12 +1071,13 @@ static int snd_sb_qsound_build(snd_sb_csp_t * p) return err; } -static void snd_sb_qsound_destroy(snd_sb_csp_t * p) +static void snd_sb_qsound_destroy(struct snd_sb_csp * p) { - snd_card_t * card; + struct snd_card *card; unsigned long flags; - snd_assert(p != NULL, return); + if (snd_BUG_ON(!p)) + return; card = p->chip->card; @@ -1070,7 +1098,7 @@ static void snd_sb_qsound_destroy(snd_sb_csp_t * p) * Transfer qsound parameters to CSP, * function should be called from interrupt routine */ -static int snd_sb_csp_qsound_transfer(snd_sb_csp_t * p) +static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p) { int err = -ENXIO; @@ -1095,19 +1123,19 @@ static int snd_sb_csp_qsound_transfer(snd_sb_csp_t * p) /* * proc interface */ -static int init_proc_entry(snd_sb_csp_t * p, int device) +static int init_proc_entry(struct snd_sb_csp * p, int device) { char name[16]; - snd_info_entry_t *entry; + struct snd_info_entry *entry; sprintf(name, "cspD%d", device); if (! snd_card_proc_new(p->chip->card, name, &entry)) - snd_info_set_text_ops(entry, p, 1024, info_read); + snd_info_set_text_ops(entry, p, info_read); return 0; } -static void info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) +static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { - snd_sb_csp_t *p = entry->private_data; + struct snd_sb_csp *p = entry->private_data; snd_iprintf(buffer, "Creative Signal Processor [v%d.%d]\n", (p->version >> 4), (p->version & 0x0f)); snd_iprintf(buffer, "State: %cx%c%c%c\n", ((p->running & SNDRV_SB_CSP_ST_QSOUND) ? 'Q' : '-'), diff --git a/sound/isa/sb/sb16_csp_codecs.h b/sound/isa/sb/sb16_csp_codecs.h deleted file mode 100644 index f0e8b0dcb57..00000000000 --- a/sound/isa/sb/sb16_csp_codecs.h +++ /dev/null @@ -1,949 +0,0 @@ -/* - * Copyright (c) 1994 Creative Technology Ltd. - * Microcode files for SB16 Advanced Signal Processor - * - * 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 - * - */ - -static unsigned char mulaw_main[] = { - 0x00, 0x10, 0x00, 0x44, 0x08, 0x00, 0x00, 0x44, - 0x00, 0xb1, 0x00, 0x44, 0x00, 0x61, 0x00, 0x44, - 0x08, 0x50, 0x00, 0x44, 0x0d, 0xf2, 0x61, 0xa8, - 0x44, 0x04, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x40, 0x49, 0x39, 0xac, 0x55, 0x55, 0x71, 0x8b, - 0x50, 0x05, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0xff, 0x2e, 0x21, 0x49, 0xff, 0x0f, 0xd4, 0x49, - 0x20, 0x01, 0x09, 0x0e, 0x20, 0x00, 0x71, 0x8b, - 0xa8, 0x01, 0xa8, 0x80, 0x88, 0x01, 0xa8, 0x80, - 0xa8, 0x00, 0x00, 0x80, 0xd2, 0x00, 0x71, 0x8b, - 0x88, 0x00, 0xa8, 0x80, 0xa8, 0x04, 0xb3, 0x80, - 0x20, 0x07, 0xb3, 0x80, 0x88, 0x03, 0xb1, 0x80, - 0xc0, 0x00, 0x09, 0x5c, 0xc2, 0x01, 0x00, 0x82, - 0xa1, 0x00, 0x71, 0x8b, 0xcd, 0x00, 0x04, 0x19, - 0xa2, 0x20, 0x71, 0x8b, 0xcf, 0x00, 0x04, 0x19, - 0x00, 0x00, 0xb1, 0x80, 0xc2, 0x00, 0x04, 0x19, - 0x00, 0x40, 0x00, 0x14, 0x08, 0x40, 0x04, 0x24, - 0x00, 0x00, 0x34, 0x49, 0x0c, 0x40, 0x00, 0x44, - 0x44, 0x04, 0x04, 0x39, 0x00, 0x00, 0x40, 0x45, - 0x32, 0x00, 0x09, 0x5c, 0x00, 0x00, 0x0c, 0x39, - 0x00, 0x00, 0x40, 0x45, 0x40, 0x40, 0x09, 0xef, - 0xff, 0x20, 0x09, 0xcf, 0x00, 0x04, 0x63, 0xa1, - 0x50, 0x03, 0x33, 0x80, 0x00, 0x04, 0xa3, 0x80, - 0x00, 0xff, 0xc2, 0x8b, 0x00, 0xd0, 0x04, 0x54, - 0x04, 0xe0, 0x00, 0xc4, 0x20, 0x03, 0x80, 0xc0, - 0x30, 0x00, 0x00, 0x88, 0x00, 0x00, 0x7a, 0x0a, - 0xd0, 0x01, 0x00, 0x82, 0x00, 0x60, 0x00, 0x44, - 0xc0, 0x00, 0x00, 0x99, 0x00, 0x60, 0x00, 0x44, - 0x00, 0xff, 0xc2, 0x8b, 0x20, 0x00, 0x00, 0x80, - 0x00, 0x0d, 0x42, 0x8b, 0x08, 0x32, 0x00, 0xc4, - 0x00, 0x0e, 0x42, 0x8b, 0x00, 0xa2, 0x00, 0xc4, - 0x00, 0x1e, 0x42, 0x8b, 0x0c, 0xb2, 0x00, 0xc4, - 0x00, 0x8e, 0x42, 0x8b, 0x00, 0x62, 0x00, 0xc4, - 0x00, 0x9e, 0x42, 0x8b, 0x08, 0x52, 0x00, 0xc4, - 0x00, 0xbe, 0x42, 0x8b, 0x08, 0x52, 0x00, 0xc4, - 0x00, 0x04, 0x42, 0x8b, 0x04, 0x72, 0x00, 0xc4, - 0x00, 0x24, 0x42, 0x8b, 0x00, 0xd2, 0x00, 0xc4, - 0x00, 0x55, 0x42, 0x8b, 0x00, 0x60, 0x00, 0xc4, - 0x00, 0x00, 0x40, 0x45, 0x20, 0x01, 0x79, 0x80, - 0x00, 0x30, 0x42, 0x8b, 0x08, 0x82, 0x00, 0xc4, - 0x00, 0x00, 0x40, 0x45, 0x00, 0x00, 0x71, 0x8b, - 0x40, 0x01, 0x00, 0x80, 0x00, 0x60, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0x00, 0xb2, 0x00, 0xc4, - 0x0f, 0xf2, 0xa8, 0xa8, 0x20, 0x00, 0xb1, 0x88, - 0x00, 0x00, 0x41, 0x02, 0x4d, 0xf2, 0x00, 0x39, - 0xc0, 0x01, 0x00, 0x82, 0x00, 0x60, 0x00, 0x44, - 0x0d, 0xf2, 0xa3, 0xa8, 0x4d, 0xf2, 0x00, 0x39, - 0x00, 0x60, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0x20, 0x00, 0x00, 0x88, 0x00, 0x00, 0x61, 0x02, - 0x4d, 0xf2, 0x04, 0x19, 0x00, 0x60, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0xa0, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x61, 0x10, 0x4d, 0xf2, 0x04, 0x19, - 0x00, 0x60, 0x00, 0x44, 0xff, 0x20, 0xe2, 0xab, - 0x60, 0x00, 0x00, 0x88, 0x00, 0x00, 0x71, 0xc0, - 0x4d, 0xf2, 0x04, 0x19, 0x00, 0x60, 0x00, 0x44, - 0x00, 0x00, 0x79, 0x80, 0x00, 0xe2, 0x00, 0x84, - 0x03, 0x03, 0x04, 0x49, 0x08, 0xc2, 0x00, 0x54, - 0x00, 0x60, 0x04, 0x64, 0x00, 0x60, 0x00, 0x44, - 0x00, 0x00, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x00, 0x60, 0x00, 0x44, - 0x20, 0x01, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x00, 0x20, 0xe2, 0x8b, 0x0c, 0xf2, 0x00, 0x84, - 0x3e, 0x00, 0x51, 0x8b, 0xc0, 0x20, 0x00, 0x39, - 0x08, 0x01, 0x00, 0x44, 0x6c, 0x00, 0x51, 0x8b, - 0xc0, 0x20, 0x00, 0x39, 0x00, 0x02, 0xe2, 0x8b, - 0x04, 0x21, 0x00, 0x84, 0xfd, 0x00, 0x51, 0x8b, - 0xc2, 0x20, 0x00, 0x39, 0x00, 0x11, 0x00, 0x44, - 0xfe, 0x00, 0x51, 0x8b, 0xc2, 0x20, 0x00, 0x39, - 0xe5, 0x00, 0x71, 0x8b, 0xcd, 0x00, 0x00, 0x39, - 0x00, 0x00, 0xb1, 0x80, 0xc9, 0x20, 0x04, 0x19, - 0xcb, 0x20, 0x04, 0x19, 0xc1, 0x20, 0x04, 0x19, - 0xc3, 0x20, 0x04, 0x19, 0x10, 0x00, 0x71, 0x8b, - 0xc7, 0x20, 0x04, 0x19, 0x5e, 0x00, 0x71, 0x8b, - 0xcf, 0x00, 0x00, 0x39, 0x00, 0x00, 0xb1, 0x80, - 0xc4, 0x20, 0x04, 0x19, 0xc6, 0x20, 0x04, 0x19, - 0xc8, 0x20, 0x04, 0x19, 0xca, 0x20, 0x04, 0x19, - 0x20, 0x00, 0x71, 0x8b, 0xcc, 0x20, 0x04, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x00, 0x60, 0x00, 0x44, - 0x09, 0x04, 0x61, 0xa8, 0xc1, 0x00, 0x04, 0x19, - 0x0b, 0x04, 0x61, 0xa8, 0xca, 0x00, 0x04, 0x19, - 0x04, 0x60, 0x00, 0xd4, 0x0d, 0x00, 0x61, 0x0a, - 0x90, 0x40, 0x09, 0x8f, 0x00, 0x01, 0x00, 0x45, - 0x0f, 0x00, 0x61, 0x0a, 0x00, 0x40, 0x09, 0x8f, - 0x00, 0x01, 0x00, 0x45, 0x82, 0x00, 0x09, 0x2e, - 0x80, 0x40, 0x09, 0xcf, 0x02, 0x00, 0x61, 0x22, - 0x43, 0x25, 0x61, 0x22, 0x40, 0x33, 0x00, 0x80, - 0x08, 0xa8, 0x00, 0x44, 0x20, 0x31, 0x49, 0x5c, - 0x92, 0x00, 0x09, 0x4e, 0x02, 0x03, 0x09, 0x2e, - 0x00, 0x00, 0xa3, 0x02, 0xc0, 0x00, 0x71, 0xc0, - 0x20, 0x00, 0xeb, 0x80, 0x00, 0x04, 0xc2, 0x8b, - 0x20, 0x04, 0x61, 0x80, 0x00, 0x04, 0x7a, 0x02, - 0xcb, 0x00, 0xa8, 0x58, 0xb0, 0x05, 0xf3, 0x80, - 0x20, 0x04, 0xa8, 0x10, 0x00, 0x00, 0x10, 0x39, - 0xb0, 0x00, 0xe0, 0x8b, 0x20, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x63, 0xcb, 0x00, 0x00, 0x7a, 0x02, - 0x40, 0x00, 0x01, 0x5b, 0x20, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x4a, 0xcb, 0x20, 0x00, 0x13, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0xe0, 0x21, 0x00, 0xc0, - 0x08, 0x00, 0x08, 0x49, 0x10, 0x41, 0x09, 0x8e, - 0xff, 0xff, 0x62, 0x8b, 0x00, 0x04, 0x61, 0x22, - 0x00, 0x03, 0x00, 0x45, 0x22, 0x01, 0x33, 0x80, - 0x20, 0x01, 0xa3, 0x02, 0x00, 0x00, 0x7a, 0x80, - 0xc0, 0x00, 0x00, 0x82, 0x07, 0x20, 0x40, 0x0a, - 0x08, 0x83, 0x00, 0x84, 0x40, 0x21, 0x00, 0x80, - 0x40, 0x05, 0x93, 0x10, 0xc7, 0x20, 0x00, 0x39, - 0x00, 0x00, 0x40, 0x45, 0x07, 0x20, 0x40, 0x0a, - 0x0c, 0xa3, 0x00, 0x84, 0x08, 0x00, 0x00, 0x82, - 0x0c, 0x24, 0x61, 0x50, 0x40, 0x01, 0x00, 0x80, - 0xc7, 0x20, 0x00, 0x39, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x04, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0x42, 0x01, 0x09, 0x0e, 0x02, 0x20, 0x61, 0x0a, - 0x00, 0x01, 0x00, 0x45, 0x0c, 0x20, 0x60, 0x0a, - 0x00, 0x73, 0x00, 0x84, 0x00, 0x04, 0xb1, 0x80, - 0x00, 0x00, 0x06, 0x39, 0x0c, 0x61, 0x04, 0xd4, - 0x00, 0x24, 0x71, 0xc0, 0x20, 0x33, 0x33, 0xc0, - 0xe0, 0x01, 0xa3, 0x82, 0x22, 0x03, 0x7a, 0x02, - 0xc3, 0x01, 0xa3, 0x82, 0x20, 0x01, 0x33, 0x80, - 0x00, 0x00, 0x7a, 0x80, 0xc2, 0x01, 0xb3, 0x50, - 0xcc, 0x20, 0x00, 0x39, 0x00, 0x00, 0x71, 0x80, - 0x00, 0xf3, 0x00, 0x44, 0x0c, 0x20, 0x60, 0x0a, - 0x00, 0xd3, 0x00, 0x84, 0x00, 0x04, 0xb1, 0x80, - 0x00, 0x00, 0x06, 0x39, 0x0c, 0x61, 0x04, 0xd4, - 0x00, 0x00, 0xb3, 0x10, 0xcc, 0x20, 0x00, 0x39, - 0x00, 0x00, 0x71, 0xc0, 0x00, 0xf3, 0x00, 0x44, - 0xcc, 0x20, 0x00, 0x39, 0x00, 0x20, 0x71, 0xc0, - 0x00, 0x30, 0x71, 0xc0, 0x00, 0xf3, 0x00, 0x44, - 0x20, 0x01, 0x00, 0x80, 0xff, 0xff, 0x62, 0x8b, - 0x20, 0x01, 0x33, 0x80, 0x00, 0x00, 0x83, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0x20, 0xe1, 0x09, 0x5c, - 0x82, 0x00, 0x09, 0x2f, 0x80, 0x4a, 0x09, 0x8e, - 0xe0, 0x01, 0xb3, 0x82, 0x20, 0x04, 0xa3, 0x80, - 0x00, 0x00, 0x7a, 0xcb, 0x03, 0x00, 0xa8, 0x18, - 0x00, 0x00, 0x10, 0x39, 0x08, 0x04, 0xea, 0x10, - 0x08, 0x04, 0x7a, 0x10, 0x20, 0x00, 0x00, 0x80, - 0x40, 0x00, 0x21, 0xcb, 0x0c, 0x00, 0xe8, 0x10, - 0x00, 0x00, 0x41, 0x02, 0x0c, 0x00, 0xeb, 0x10, - 0xf2, 0x01, 0x00, 0x82, 0x40, 0x21, 0x33, 0x02, - 0x08, 0x20, 0x61, 0x0a, 0xc4, 0x00, 0x04, 0x19, - 0xc7, 0x00, 0x00, 0x99, 0x02, 0x00, 0x61, 0x0a, - 0x0c, 0xe8, 0x04, 0x14, 0x01, 0x00, 0x61, 0x0a, - 0x03, 0x00, 0x48, 0x0a, 0x00, 0xb8, 0x04, 0x54, - 0xc3, 0x00, 0x04, 0x19, 0x0c, 0xb8, 0x00, 0x44, - 0x08, 0x00, 0xc8, 0x0a, 0x0c, 0xb8, 0x04, 0x54, - 0xc8, 0x00, 0x04, 0x19, 0x0a, 0x00, 0x61, 0x0a, - 0x09, 0x00, 0x48, 0x0a, 0x00, 0x68, 0x04, 0x54, - 0xc9, 0x00, 0x04, 0x19, 0x0c, 0x68, 0x00, 0x44, - 0x0b, 0x00, 0xc8, 0x0a, 0x0c, 0x68, 0x04, 0x54, - 0xcb, 0x00, 0x04, 0x19, 0x04, 0x00, 0x61, 0x0a, - 0x06, 0x00, 0x48, 0x0a, 0x00, 0x78, 0x04, 0x54, - 0xc6, 0x00, 0x04, 0x19, 0x0c, 0x78, 0x00, 0x44, - 0x05, 0x00, 0xc8, 0x0a, 0x0c, 0x78, 0x04, 0x54, - 0xc5, 0x00, 0x04, 0x19, 0x07, 0x00, 0x61, 0x0a, - 0x0c, 0x00, 0x48, 0x0a, 0x00, 0xe8, 0x04, 0x54, - 0xcc, 0x00, 0x04, 0x19, 0x0c, 0xe8, 0x00, 0x44, - 0x0e, 0x00, 0xc8, 0x0a, 0x0c, 0xe8, 0x04, 0x54, - 0xce, 0x00, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x20, 0x10, 0x71, 0x8b, 0x09, 0x3f, 0x07, 0x00 -}; - -static unsigned char alaw_main[] = { - 0x00, 0x10, 0x00, 0x44, 0x08, 0x00, 0x00, 0x44, - 0x00, 0xb1, 0x00, 0x44, 0x00, 0x61, 0x00, 0x44, - 0x08, 0x50, 0x00, 0x44, 0x0d, 0xf2, 0x61, 0xa8, - 0x44, 0x04, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x40, 0x49, 0x39, 0xac, 0x55, 0x55, 0x71, 0x8b, - 0x50, 0x05, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0xff, 0x2e, 0x21, 0x49, 0xff, 0x0f, 0xd4, 0x49, - 0x20, 0x01, 0x09, 0x0e, 0x20, 0x00, 0x71, 0x8b, - 0xa8, 0x01, 0xa8, 0x80, 0x88, 0x01, 0xa8, 0x80, - 0xa8, 0x00, 0x00, 0x80, 0xd2, 0x00, 0x71, 0x8b, - 0x88, 0x00, 0xa8, 0x80, 0xa8, 0x04, 0xb3, 0x80, - 0x20, 0x07, 0xb3, 0x80, 0x88, 0x03, 0xb1, 0x80, - 0xc0, 0x00, 0x09, 0x5c, 0xc2, 0x01, 0x00, 0x82, - 0xa1, 0x00, 0x71, 0x8b, 0xcd, 0x00, 0x04, 0x19, - 0x21, 0x20, 0x71, 0x8b, 0xcf, 0x00, 0x04, 0x19, - 0x00, 0x00, 0xb1, 0x80, 0xc2, 0x00, 0x04, 0x19, - 0x00, 0x40, 0x00, 0x14, 0x08, 0x40, 0x04, 0x24, - 0x00, 0x00, 0x34, 0x49, 0x0c, 0x40, 0x00, 0x44, - 0x44, 0x04, 0x04, 0x39, 0x00, 0x00, 0x40, 0x45, - 0x32, 0x00, 0x09, 0x5c, 0x00, 0x00, 0x0c, 0x39, - 0x00, 0x00, 0x40, 0x45, 0x40, 0x40, 0x09, 0xef, - 0xff, 0x20, 0x09, 0xcf, 0x00, 0x04, 0x63, 0xa1, - 0x50, 0x03, 0x33, 0x80, 0x00, 0x04, 0xa3, 0x80, - 0x00, 0xff, 0xc2, 0x8b, 0x00, 0xd0, 0x04, 0x54, - 0x04, 0xe0, 0x00, 0xc4, 0x20, 0x03, 0x80, 0xc0, - 0x30, 0x00, 0x00, 0x88, 0x00, 0x00, 0x7a, 0x0a, - 0xd0, 0x01, 0x00, 0x82, 0x00, 0x60, 0x00, 0x44, - 0xc0, 0x00, 0x00, 0x99, 0x00, 0x60, 0x00, 0x44, - 0x00, 0xff, 0xc2, 0x8b, 0x20, 0x00, 0x00, 0x80, - 0x00, 0x0d, 0x42, 0x8b, 0x08, 0x32, 0x00, 0xc4, - 0x00, 0x0e, 0x42, 0x8b, 0x00, 0xa2, 0x00, 0xc4, - 0x00, 0x1e, 0x42, 0x8b, 0x0c, 0xb2, 0x00, 0xc4, - 0x00, 0x8e, 0x42, 0x8b, 0x00, 0x62, 0x00, 0xc4, - 0x00, 0x9e, 0x42, 0x8b, 0x08, 0x52, 0x00, 0xc4, - 0x00, 0xbe, 0x42, 0x8b, 0x08, 0x52, 0x00, 0xc4, - 0x00, 0x04, 0x42, 0x8b, 0x04, 0x72, 0x00, 0xc4, - 0x00, 0x24, 0x42, 0x8b, 0x00, 0xd2, 0x00, 0xc4, - 0x00, 0x55, 0x42, 0x8b, 0x00, 0x60, 0x00, 0xc4, - 0x00, 0x00, 0x40, 0x45, 0x20, 0x01, 0x79, 0x80, - 0x00, 0x30, 0x42, 0x8b, 0x08, 0x82, 0x00, 0xc4, - 0x00, 0x00, 0x40, 0x45, 0x00, 0x00, 0x71, 0x8b, - 0x40, 0x01, 0x00, 0x80, 0x00, 0x60, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0x00, 0xb2, 0x00, 0xc4, - 0x0f, 0xf2, 0xa8, 0xa8, 0x20, 0x00, 0xb1, 0x88, - 0x00, 0x00, 0x41, 0x02, 0x4d, 0xf2, 0x00, 0x39, - 0xc0, 0x01, 0x00, 0x82, 0x00, 0x60, 0x00, 0x44, - 0x0d, 0xf2, 0xa3, 0xa8, 0x4d, 0xf2, 0x00, 0x39, - 0x00, 0x60, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0x20, 0x00, 0x00, 0x88, 0x00, 0x00, 0x61, 0x02, - 0x4d, 0xf2, 0x04, 0x19, 0x00, 0x60, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0xa0, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x61, 0x10, 0x4d, 0xf2, 0x04, 0x19, - 0x00, 0x60, 0x00, 0x44, 0xff, 0x20, 0xe2, 0xab, - 0x60, 0x00, 0x00, 0x88, 0x00, 0x00, 0x71, 0xc0, - 0x4d, 0xf2, 0x04, 0x19, 0x00, 0x60, 0x00, 0x44, - 0x00, 0x00, 0x79, 0x80, 0x00, 0xe2, 0x00, 0x84, - 0x03, 0x03, 0x04, 0x49, 0x04, 0xc2, 0x00, 0x54, - 0x00, 0x60, 0x04, 0x64, 0x00, 0x60, 0x00, 0x44, - 0x00, 0x00, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x00, 0x60, 0x00, 0x44, - 0x20, 0x01, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x00, 0x20, 0xe2, 0x8b, 0x0c, 0xf2, 0x00, 0x84, - 0xbe, 0x00, 0x51, 0x8b, 0xc0, 0x20, 0x00, 0x39, - 0x08, 0x01, 0x00, 0x44, 0xec, 0x00, 0x51, 0x8b, - 0xc0, 0x20, 0x00, 0x39, 0x00, 0x02, 0xe2, 0x8b, - 0x04, 0x21, 0x00, 0x84, 0x3f, 0x00, 0x51, 0x8b, - 0xc2, 0x20, 0x00, 0x39, 0x00, 0x11, 0x00, 0x44, - 0x3d, 0x00, 0x51, 0x8b, 0xc2, 0x20, 0x00, 0x39, - 0xe5, 0x00, 0x71, 0x8b, 0xcd, 0x00, 0x00, 0x39, - 0x00, 0x00, 0xb1, 0x80, 0xc9, 0x20, 0x04, 0x19, - 0xcb, 0x20, 0x04, 0x19, 0xc1, 0x20, 0x04, 0x19, - 0xc3, 0x20, 0x04, 0x19, 0x10, 0x00, 0x71, 0x8b, - 0xc7, 0x20, 0x04, 0x19, 0xde, 0x00, 0x51, 0x8b, - 0xcf, 0x00, 0x00, 0x39, 0x00, 0x01, 0xb1, 0x80, - 0xc4, 0x20, 0x04, 0x19, 0xc6, 0x20, 0x04, 0x19, - 0xc8, 0x20, 0x04, 0x19, 0xca, 0x20, 0x04, 0x19, - 0x20, 0x00, 0x71, 0x8b, 0xcc, 0x20, 0x04, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x00, 0x60, 0x00, 0x44, - 0x09, 0x04, 0x61, 0xa8, 0xc1, 0x00, 0x04, 0x19, - 0x0b, 0x04, 0x61, 0xa8, 0xca, 0x00, 0x04, 0x19, - 0x04, 0x60, 0x00, 0xd4, 0x0d, 0x00, 0x61, 0x0a, - 0x90, 0x40, 0x09, 0x8f, 0x00, 0x01, 0x00, 0x45, - 0x0f, 0x00, 0x61, 0x0a, 0x00, 0x40, 0x09, 0x8f, - 0x00, 0x01, 0x00, 0x45, 0x82, 0x00, 0x09, 0x2e, - 0x80, 0x40, 0x09, 0xcf, 0x02, 0x00, 0x61, 0x22, - 0x43, 0x25, 0x61, 0x22, 0x40, 0x33, 0x00, 0x80, - 0x08, 0x48, 0x00, 0x44, 0x20, 0xb1, 0x49, 0x5c, - 0x92, 0x00, 0x09, 0x4e, 0x02, 0x03, 0x09, 0x2e, - 0x00, 0x00, 0xa3, 0x02, 0xc0, 0x00, 0x71, 0xc0, - 0x20, 0x00, 0xeb, 0x80, 0x00, 0x04, 0xc2, 0x8b, - 0x20, 0x04, 0x61, 0x80, 0x00, 0x04, 0x7a, 0x02, - 0xc0, 0x00, 0x00, 0x82, 0x0c, 0xc3, 0x08, 0x49, - 0xb0, 0x01, 0xf3, 0x80, 0x00, 0x00, 0x10, 0x39, - 0x20, 0x00, 0x0c, 0x89, 0x0c, 0x88, 0x08, 0x49, - 0x03, 0x00, 0xa8, 0x18, 0x00, 0x00, 0x10, 0x39, - 0xbd, 0xff, 0x62, 0x8b, 0x20, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x63, 0xcb, 0x00, 0x00, 0x7a, 0x02, - 0x40, 0x00, 0x01, 0x5b, 0x20, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x4a, 0xcb, 0x20, 0x00, 0x13, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0xe0, 0x21, 0x00, 0xc0, - 0x08, 0x00, 0x08, 0x49, 0x10, 0x41, 0x09, 0x8e, - 0xae, 0xae, 0x62, 0x8b, 0x00, 0x04, 0x61, 0x22, - 0x00, 0x03, 0x00, 0x45, 0x22, 0x01, 0x33, 0x80, - 0x20, 0x01, 0xa3, 0x02, 0x00, 0x00, 0x7a, 0x80, - 0xc0, 0x00, 0x00, 0x82, 0x07, 0x20, 0x40, 0x0a, - 0x08, 0xa3, 0x00, 0x84, 0x40, 0x21, 0x00, 0x80, - 0x40, 0x05, 0x93, 0x10, 0xc7, 0x20, 0x00, 0x39, - 0x00, 0x00, 0x40, 0x45, 0x07, 0x20, 0x40, 0x0a, - 0x0c, 0x93, 0x00, 0x84, 0x08, 0x00, 0x00, 0x82, - 0x0c, 0x24, 0x61, 0x50, 0x40, 0x01, 0x00, 0x80, - 0xc7, 0x20, 0x00, 0x39, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x04, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0x42, 0x01, 0x09, 0x0e, 0x02, 0x20, 0x61, 0x0a, - 0x00, 0x01, 0x00, 0x45, 0x0c, 0x20, 0x60, 0x0a, - 0x00, 0xc3, 0x00, 0x84, 0x00, 0x04, 0xb1, 0x80, - 0x00, 0x00, 0x06, 0x39, 0x0c, 0x61, 0x04, 0xd4, - 0x00, 0x24, 0x71, 0xc0, 0x20, 0x33, 0x33, 0xc0, - 0xe0, 0x01, 0xa3, 0x82, 0x22, 0x03, 0x7a, 0x02, - 0xc3, 0x01, 0xa3, 0x82, 0x20, 0x01, 0x33, 0x80, - 0x00, 0x00, 0x7a, 0x80, 0xc2, 0x01, 0xb3, 0x50, - 0xcc, 0x20, 0x00, 0x39, 0x00, 0x00, 0x71, 0x80, - 0x00, 0x08, 0x00, 0x44, 0x0c, 0x20, 0x60, 0x0a, - 0x00, 0xf3, 0x00, 0x84, 0x00, 0x04, 0xb1, 0x80, - 0x00, 0x00, 0x06, 0x39, 0x0c, 0x61, 0x04, 0xd4, - 0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x93, 0x10, - 0xcc, 0x20, 0x00, 0x39, 0x00, 0x08, 0x00, 0x44, - 0xcc, 0x20, 0x00, 0x39, 0x00, 0x20, 0x00, 0xc0, - 0x00, 0x30, 0x71, 0xc0, 0x00, 0x08, 0x00, 0x44, - 0x20, 0x01, 0x00, 0x80, 0xae, 0xae, 0x62, 0x8b, - 0x20, 0x01, 0x33, 0x80, 0x00, 0x00, 0x83, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0x20, 0xa1, 0x49, 0x5c, - 0x82, 0x00, 0x09, 0x6e, 0x80, 0x4a, 0x09, 0x8e, - 0xe0, 0x01, 0xb3, 0x82, 0x20, 0x04, 0xa3, 0x80, - 0x00, 0x00, 0x7a, 0xcb, 0x28, 0x04, 0xea, 0x10, - 0x0c, 0x04, 0x7a, 0x10, 0x70, 0x00, 0xc0, 0x8b, - 0x00, 0x00, 0x10, 0x39, 0x90, 0x03, 0x00, 0x80, - 0x40, 0x00, 0x21, 0x5b, 0x90, 0x00, 0x61, 0x80, - 0x0c, 0x8a, 0x08, 0x49, 0x00, 0x00, 0x1c, 0x19, - 0x40, 0x00, 0x08, 0x5b, 0x08, 0x00, 0x08, 0x49, - 0x20, 0x02, 0x00, 0x80, 0x03, 0x00, 0xa8, 0x18, - 0x00, 0x00, 0x14, 0x19, 0x40, 0x00, 0x21, 0xcb, - 0x00, 0x00, 0x41, 0x02, 0x00, 0x00, 0xeb, 0x80, - 0xf2, 0x01, 0x00, 0x82, 0x40, 0x21, 0x33, 0x02, - 0x08, 0x20, 0x61, 0x0a, 0xc4, 0x00, 0x04, 0x19, - 0xc7, 0x00, 0x00, 0x99, 0x02, 0x00, 0x61, 0x0a, - 0x0c, 0x0a, 0x04, 0x14, 0x01, 0x00, 0x61, 0x0a, - 0x03, 0x00, 0x48, 0x0a, 0x00, 0x58, 0x04, 0x54, - 0xc3, 0x00, 0x04, 0x19, 0x0c, 0x58, 0x00, 0x44, - 0x08, 0x00, 0xc8, 0x0a, 0x0c, 0x58, 0x04, 0x54, - 0xc8, 0x00, 0x04, 0x19, 0x0a, 0x00, 0x61, 0x0a, - 0x09, 0x00, 0x48, 0x0a, 0x00, 0xc8, 0x04, 0x54, - 0xc9, 0x00, 0x04, 0x19, 0x0c, 0xc8, 0x00, 0x44, - 0x0b, 0x00, 0xc8, 0x0a, 0x0c, 0xc8, 0x04, 0x54, - 0xcb, 0x00, 0x04, 0x19, 0x04, 0x00, 0x61, 0x0a, - 0x06, 0x00, 0x48, 0x0a, 0x00, 0xd8, 0x04, 0x54, - 0xc6, 0x00, 0x04, 0x19, 0x0c, 0xd8, 0x00, 0x44, - 0x05, 0x00, 0xc8, 0x0a, 0x0c, 0xd8, 0x04, 0x54, - 0xc5, 0x00, 0x04, 0x19, 0x07, 0x00, 0x61, 0x0a, - 0x0c, 0x00, 0x48, 0x0a, 0x00, 0x0a, 0x04, 0x54, - 0xcc, 0x00, 0x04, 0x19, 0x0c, 0x0a, 0x00, 0x44, - 0x0e, 0x00, 0xc8, 0x0a, 0x0c, 0x0a, 0x04, 0x54, - 0xce, 0x00, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x20, 0x10, 0x71, 0x8b, 0x08, 0x42, 0x06, 0x00 -}; - - -static unsigned char ima_adpcm_init[] = { - 0x00, 0x10, 0x00, 0x44, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x00, 0x40, 0x45, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x00, 0x40, 0x45, 0xaa, 0xaa, 0x71, 0x8b, - 0x44, 0x04, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0xff, 0x6e, 0x21, 0x49, 0xff, 0x0f, 0xd4, 0x49, - 0x40, 0x49, 0x39, 0xac, 0x55, 0x55, 0x71, 0x8b, - 0x50, 0x05, 0xb1, 0x80, 0x62, 0x00, 0x19, 0x0e, - 0x21, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xb0, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x40, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x60, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x50, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x70, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc0, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xe0, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xd0, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x02, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x22, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x32, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xa2, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xb2, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x62, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc2, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xf2, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x11, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xa1, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x61, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xe1, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x13, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xb3, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc3, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x18, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x68, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x0a, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x4a, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x29, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x79, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x9b, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x14, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xf4, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xe6, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xe5, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xd7, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x2e, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x9d, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xef, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xb2, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x33, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x2a, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x3b, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x46, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x2c, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xdd, 0x20, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x01, 0x10, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x9a, 0x10, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x16, 0x10, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x8e, 0x10, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc2, 0x30, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc9, 0x30, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x3c, 0x30, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x81, 0x80, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xd4, 0x80, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x10, 0xa0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x34, 0xa0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x02, 0x90, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x75, 0x90, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x9a, 0xb0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x12, 0x40, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x0d, 0x40, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x3c, 0x60, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xe7, 0x50, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x0e, 0x70, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xff, 0xc0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc8, 0xd0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x57, 0xf0, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xc8, 0x22, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xb0, 0x32, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xdd, 0x82, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x90, 0xb2, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x8a, 0x62, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xce, 0x72, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xa5, 0xd2, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x97, 0x21, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xa2, 0xa1, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x5c, 0x41, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xfe, 0xc1, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x7a, 0x23, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x78, 0x93, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x67, 0x73, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x17, 0x28, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x88, 0x48, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xdb, 0xf8, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x2b, 0xba, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xf1, 0x09, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xdc, 0x69, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x19, 0x8b, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0xff, 0xfb, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x20, 0x00, 0x71, 0x8b, 0x88, 0x00, 0x00, 0x80, - 0x52, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0xff, 0xff, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0xc2, 0x00, 0x00, 0x82, 0xc2, 0x00, 0x00, 0x82, - 0xc2, 0x00, 0x00, 0x82, 0x10, 0x00, 0x71, 0x8b, - 0xc2, 0x00, 0x00, 0x82, 0x80, 0x00, 0x71, 0x8b, - 0xc2, 0x00, 0x00, 0x82, 0x90, 0x00, 0x71, 0x8b, - 0xc2, 0x00, 0x00, 0x82, 0x40, 0x00, 0x71, 0x8b, - 0xc2, 0x00, 0x00, 0x82, 0xff, 0xff, 0x71, 0x8b, - 0xc2, 0x00, 0x00, 0x82, 0xc2, 0x00, 0x00, 0x82, - 0xc2, 0x00, 0x00, 0x82, 0xc2, 0x00, 0x00, 0x82, - 0x10, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x80, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x90, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x40, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0xff, 0xfb, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x00, 0x04, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x4a, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x00, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0x00, 0x00, 0x71, 0x8b, 0xc2, 0x00, 0x00, 0x82, - 0xc2, 0x00, 0x00, 0x82, 0xc2, 0x30, 0x04, 0x19, - 0x10, 0x00, 0x09, 0x4f, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0xc2, 0x01, 0x00, 0x82, 0xc2, 0x01, 0x00, 0x82, - 0x00, 0x10, 0x71, 0x8b, 0xc1, 0x30, 0x04, 0x19, - 0x93, 0x00, 0x01, 0x4f, 0xcd, 0x30, 0x00, 0x09, - 0xcf, 0x30, 0x00, 0x09, 0x00, 0x00, 0x34, 0x49, - 0x00, 0x08, 0x00, 0x44, 0xc8, 0x54, 0x11, 0x00 -}; - -static unsigned char ima_adpcm_playback[] = { - 0x00, 0x10, 0x00, 0x44, 0x08, 0x00, 0x00, 0x44, - 0x0c, 0x50, 0x00, 0x44, 0x00, 0x70, 0x00, 0x44, - 0x04, 0x70, 0x00, 0x44, 0x0d, 0xf2, 0x61, 0xa8, - 0x44, 0x04, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x04, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0xff, 0x2e, 0x21, 0x49, 0xff, 0x0d, 0xd4, 0x49, - 0x40, 0x49, 0x39, 0xac, 0x55, 0x55, 0x71, 0x8b, - 0x50, 0x01, 0xb1, 0x80, 0x00, 0x01, 0xb1, 0x80, - 0xc9, 0x20, 0x04, 0x19, 0x51, 0x00, 0x71, 0x8b, - 0xcd, 0x00, 0x04, 0x19, 0xe4, 0x20, 0x71, 0x8b, - 0xcf, 0x00, 0x04, 0x19, 0x80, 0x00, 0x71, 0x8b, - 0xcb, 0x20, 0x04, 0x19, 0x10, 0x00, 0x71, 0x8b, - 0xc4, 0x20, 0x04, 0x19, 0x65, 0x00, 0x51, 0x8b, - 0xc2, 0x20, 0x00, 0x39, 0x00, 0x00, 0xb1, 0x80, - 0xc2, 0x30, 0x04, 0x19, 0x00, 0x00, 0x63, 0x80, - 0xc1, 0xa0, 0x04, 0x19, 0x93, 0x00, 0x01, 0x4f, - 0xcd, 0x30, 0x00, 0x09, 0xcf, 0x30, 0x00, 0x09, - 0x04, 0x40, 0x00, 0x14, 0x0c, 0x40, 0x00, 0x14, - 0x00, 0x04, 0x61, 0xa8, 0x02, 0x04, 0x61, 0xa8, - 0x04, 0x60, 0x04, 0x24, 0x00, 0x00, 0x34, 0x49, - 0x00, 0x50, 0x00, 0x44, 0x44, 0x04, 0x04, 0x39, - 0x00, 0x00, 0x40, 0x45, 0x00, 0x00, 0x40, 0x45, - 0x0f, 0x00, 0x61, 0x0a, 0x00, 0x01, 0x00, 0x45, - 0x40, 0x40, 0x09, 0xef, 0xff, 0x20, 0x09, 0xcf, - 0x00, 0x04, 0x63, 0xa1, 0x50, 0x03, 0x33, 0x80, - 0x00, 0x04, 0xa3, 0x80, 0x00, 0xff, 0xc2, 0x8b, - 0x08, 0xf0, 0x04, 0x54, 0x0c, 0xd0, 0x00, 0xc4, - 0x20, 0x03, 0x80, 0xc0, 0x30, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x7a, 0x0a, 0xd0, 0x01, 0x00, 0x82, - 0x08, 0x50, 0x00, 0x44, 0xc0, 0x00, 0x00, 0x99, - 0x08, 0x50, 0x00, 0x44, 0x00, 0xff, 0xc2, 0x8b, - 0x20, 0x00, 0x00, 0x80, 0x00, 0x0d, 0x42, 0x8b, - 0x00, 0xa2, 0x00, 0xc4, 0x00, 0x0e, 0x42, 0x8b, - 0x0c, 0x92, 0x00, 0xc4, 0x00, 0x1e, 0x42, 0x8b, - 0x04, 0x62, 0x00, 0xc4, 0x00, 0x8e, 0x42, 0x8b, - 0x0c, 0x52, 0x00, 0xc4, 0x00, 0x9e, 0x42, 0x8b, - 0x00, 0xc2, 0x00, 0xc4, 0x00, 0xbe, 0x42, 0x8b, - 0x00, 0xc2, 0x00, 0xc4, 0x00, 0x04, 0x42, 0x8b, - 0x00, 0xf2, 0x00, 0xc4, 0x00, 0x24, 0x42, 0x8b, - 0x00, 0x91, 0x00, 0xc4, 0x00, 0x55, 0x42, 0x8b, - 0x08, 0x50, 0x00, 0xc4, 0x00, 0x3f, 0x42, 0x8b, - 0x08, 0xe2, 0x00, 0xc4, 0x00, 0x00, 0x40, 0x45, - 0x20, 0x01, 0x79, 0x80, 0x00, 0x30, 0x42, 0x8b, - 0x00, 0x92, 0x00, 0xc4, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x00, 0x71, 0x8b, 0x40, 0x01, 0x00, 0x80, - 0x08, 0x50, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0x0c, 0x42, 0x00, 0xc4, 0x0f, 0xf2, 0xa8, 0xa8, - 0x20, 0x00, 0xb1, 0x88, 0x00, 0x00, 0x41, 0x02, - 0x4d, 0xf2, 0x00, 0x39, 0xc0, 0x01, 0x00, 0x82, - 0x08, 0x50, 0x00, 0x44, 0x0d, 0xf2, 0xa3, 0xa8, - 0x4d, 0xf2, 0x00, 0x39, 0x08, 0x50, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0x20, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x61, 0x02, 0x4d, 0xf2, 0x04, 0x19, - 0x08, 0x50, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0xa0, 0x00, 0x00, 0x88, 0x00, 0x00, 0x61, 0x10, - 0x4d, 0xf2, 0x04, 0x19, 0x08, 0x50, 0x00, 0x44, - 0xff, 0x20, 0xe2, 0xab, 0x60, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x71, 0xc0, 0x4d, 0xf2, 0x04, 0x19, - 0x08, 0x50, 0x00, 0x44, 0x00, 0x00, 0x7a, 0x0a, - 0x20, 0x01, 0xf0, 0x80, 0x01, 0xa0, 0x41, 0x0a, - 0x04, 0xd2, 0x00, 0xc4, 0x20, 0x01, 0xf0, 0x80, - 0xc1, 0x30, 0x04, 0x19, 0x08, 0x50, 0x00, 0x44, - 0x00, 0x00, 0x79, 0x80, 0x00, 0xa1, 0x00, 0x84, - 0xb5, 0x00, 0x51, 0x8b, 0xcf, 0x00, 0x00, 0x39, - 0x00, 0x01, 0xb1, 0x80, 0x88, 0x00, 0x04, 0x19, - 0x8a, 0x00, 0x04, 0x19, 0xc8, 0x20, 0x04, 0x19, - 0xca, 0x20, 0x04, 0x19, 0xc2, 0x30, 0x04, 0x19, - 0xcd, 0x10, 0x04, 0x19, 0xcf, 0x10, 0x04, 0x19, - 0xb0, 0x00, 0x71, 0x8b, 0x8c, 0x00, 0x04, 0x19, - 0x8e, 0x00, 0x04, 0x19, 0x10, 0x00, 0x71, 0x8b, - 0xc4, 0x20, 0x04, 0x19, 0x93, 0x00, 0x01, 0x4f, - 0xcd, 0x30, 0x00, 0x09, 0xcf, 0x30, 0x00, 0x09, - 0x03, 0x03, 0x04, 0x49, 0x04, 0x81, 0x00, 0x54, - 0x08, 0x50, 0x04, 0x64, 0x08, 0x50, 0x00, 0x44, - 0x00, 0x00, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x08, 0x50, 0x00, 0x44, - 0x20, 0x01, 0x63, 0x80, 0x00, 0x00, 0x06, 0x19, - 0x00, 0x02, 0xe2, 0x8b, 0x08, 0x41, 0x00, 0x84, - 0x65, 0x00, 0x51, 0x8b, 0xc2, 0x20, 0x00, 0x39, - 0x00, 0x00, 0x63, 0x80, 0xc1, 0xa0, 0x04, 0x19, - 0x08, 0x61, 0x00, 0x44, 0x2d, 0x00, 0x51, 0x8b, - 0xc2, 0x20, 0x00, 0x39, 0x00, 0x00, 0xb1, 0x80, - 0xc1, 0xa0, 0x04, 0x19, 0x03, 0x00, 0x04, 0x49, - 0x08, 0x50, 0x00, 0x44, 0x02, 0x20, 0x61, 0x0a, - 0x00, 0x01, 0x00, 0x45, 0x02, 0x30, 0x61, 0x0a, - 0x04, 0x03, 0x00, 0xc4, 0x05, 0xb0, 0xc8, 0x18, - 0x04, 0x71, 0x00, 0xc4, 0x00, 0x13, 0x00, 0x44, - 0x00, 0x79, 0x08, 0x44, 0x00, 0x04, 0x79, 0x80, - 0x00, 0x49, 0x00, 0xc4, 0xca, 0x20, 0x04, 0x19, - 0x4a, 0x04, 0x04, 0x19, 0xff, 0x00, 0xe2, 0x8b, - 0x0c, 0xf9, 0x08, 0x44, 0xcf, 0x10, 0x04, 0x19, - 0x0c, 0x2b, 0x08, 0x44, 0x8e, 0x00, 0x04, 0x19, - 0x03, 0x30, 0x61, 0x0a, 0xc8, 0x20, 0x00, 0x39, - 0x48, 0x04, 0x00, 0x39, 0x0a, 0x30, 0x61, 0x0a, - 0x0c, 0xf9, 0x08, 0x44, 0xcd, 0x10, 0x04, 0x19, - 0x0c, 0x2b, 0x08, 0x44, 0x8c, 0x00, 0x04, 0x19, - 0x0c, 0xd9, 0x08, 0x44, 0x0c, 0x5a, 0x00, 0x44, - 0x00, 0x79, 0x08, 0x44, 0x00, 0x04, 0x79, 0x80, - 0x00, 0x49, 0x00, 0xc4, 0xc3, 0x30, 0x04, 0x19, - 0xca, 0x30, 0x00, 0x99, 0x0c, 0xd9, 0x08, 0x44, - 0x42, 0x0a, 0x09, 0x0e, 0x00, 0x01, 0x33, 0x11, - 0x8c, 0x01, 0xa3, 0x80, 0x00, 0x01, 0x7a, 0x10, - 0x80, 0x05, 0xb1, 0x80, 0x05, 0xb0, 0xe0, 0x18, - 0x00, 0x93, 0x00, 0x84, 0x00, 0x79, 0x08, 0x44, - 0x00, 0x04, 0x79, 0x80, 0x00, 0x49, 0x00, 0xc4, - 0x0c, 0x1b, 0x08, 0x44, 0x88, 0x00, 0x04, 0x19, - 0x8a, 0x00, 0x00, 0x99, 0x0c, 0xd9, 0x08, 0x44, - 0x42, 0x0a, 0x09, 0x0e, 0x80, 0x00, 0x71, 0x8b, - 0xc0, 0x04, 0xb1, 0x82, 0x10, 0x00, 0xe0, 0x0b, - 0x00, 0x43, 0x00, 0x84, 0x02, 0x30, 0x61, 0x0a, - 0x01, 0x30, 0xc8, 0x0a, 0x00, 0x43, 0x00, 0x84, - 0x00, 0x00, 0xb1, 0x80, 0xc2, 0x30, 0x04, 0x19, - 0x0c, 0xa8, 0x00, 0x44, 0x02, 0x30, 0x61, 0x0a, - 0x00, 0xd3, 0x00, 0xc4, 0x05, 0xb0, 0xc8, 0x18, - 0x04, 0x63, 0x00, 0xc4, 0x08, 0xf3, 0x00, 0x44, - 0x00, 0x79, 0x08, 0x44, 0x00, 0x04, 0x79, 0x80, - 0x00, 0x49, 0x00, 0xc4, 0x20, 0x00, 0x04, 0x19, - 0xff, 0x00, 0xe2, 0x8b, 0x0c, 0xf9, 0x08, 0x44, - 0xcd, 0x10, 0x04, 0x19, 0xcf, 0x10, 0x04, 0x19, - 0x0c, 0x2b, 0x08, 0x44, 0x8c, 0x00, 0x04, 0x19, - 0x8e, 0x00, 0x04, 0x19, 0x03, 0x30, 0x61, 0x0a, - 0xc8, 0x20, 0x00, 0x39, 0xca, 0x20, 0x00, 0x39, - 0x48, 0x04, 0x00, 0x39, 0x4a, 0x04, 0x00, 0x39, - 0x0c, 0xd9, 0x08, 0x44, 0x0c, 0x5a, 0x00, 0x44, - 0x00, 0x79, 0x08, 0x44, 0x00, 0x04, 0x79, 0x80, - 0x00, 0x49, 0x00, 0xc4, 0xc3, 0x30, 0x04, 0x19, - 0x0c, 0xd9, 0x08, 0x44, 0x42, 0x0a, 0x09, 0x0e, - 0x05, 0xb0, 0xe0, 0x18, 0x00, 0x18, 0x00, 0x84, - 0x00, 0x79, 0x08, 0x44, 0x00, 0x04, 0x79, 0x80, - 0x00, 0x49, 0x00, 0xc4, 0x0c, 0x1b, 0x08, 0x44, - 0x80, 0x01, 0x00, 0x80, 0x0c, 0xd9, 0x08, 0x44, - 0x42, 0x0a, 0x09, 0x0e, 0x80, 0x00, 0x71, 0x8b, - 0xc0, 0x04, 0xb1, 0x82, 0x10, 0x00, 0xe0, 0x0b, - 0x00, 0x88, 0x00, 0x84, 0x02, 0x30, 0x61, 0x0a, - 0x01, 0x30, 0xc8, 0x0a, 0x00, 0x88, 0x00, 0x84, - 0x00, 0x00, 0xb1, 0x80, 0xc2, 0x30, 0x04, 0x19, - 0x00, 0x01, 0x00, 0x11, 0x00, 0x0f, 0xe2, 0x8b, - 0x00, 0x00, 0x41, 0xcb, 0x8c, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x48, 0xcb, 0x20, 0x00, 0x7a, 0x80, - 0x80, 0x01, 0x00, 0x80, 0x82, 0x0c, 0x09, 0x6e, - 0x03, 0x08, 0x09, 0x0e, 0x80, 0x40, 0x09, 0xcf, - 0x00, 0x01, 0x71, 0xc2, 0x00, 0x08, 0xc2, 0x1b, - 0x04, 0xb8, 0x00, 0xc4, 0x20, 0x05, 0xa8, 0x80, - 0x20, 0x01, 0xf0, 0x80, 0x00, 0x01, 0xc2, 0x1b, - 0x04, 0x48, 0x00, 0xc4, 0x20, 0x05, 0xa8, 0x80, - 0x20, 0x01, 0xf0, 0x80, 0x00, 0x02, 0xc2, 0x1b, - 0x04, 0x68, 0x00, 0xc4, 0x20, 0x05, 0xa8, 0x80, - 0x20, 0x01, 0xf0, 0x80, 0x20, 0x03, 0xa8, 0x80, - 0x00, 0x01, 0x00, 0x11, 0x00, 0x04, 0xc2, 0x8b, - 0x08, 0x78, 0x00, 0xc4, 0x00, 0x00, 0xe9, 0x80, - 0x05, 0xb0, 0xa8, 0x18, 0x00, 0x00, 0x4a, 0xcb, - 0x20, 0x00, 0xa8, 0x22, 0xd0, 0x01, 0x00, 0x82, - 0x40, 0x01, 0x00, 0x80, 0xc4, 0x00, 0x04, 0x19, - 0xb0, 0x00, 0xe2, 0x8b, 0x06, 0x20, 0xa8, 0x0a, - 0x2d, 0x10, 0x61, 0x0a, 0xd1, 0x08, 0x09, 0x2e, - 0x00, 0x01, 0xa8, 0x02, 0x0c, 0xf9, 0x08, 0x44, - 0xcd, 0x10, 0x04, 0x19, 0x0c, 0x2b, 0x08, 0x44, - 0x03, 0x08, 0x09, 0x0e, 0x9a, 0x25, 0xb1, 0x60, - 0xa2, 0x0e, 0x09, 0x6e, 0x03, 0x00, 0x09, 0x0f, - 0x00, 0x01, 0x71, 0x82, 0x20, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x61, 0xcb, 0x80, 0x01, 0x00, 0x80, - 0x03, 0x00, 0x09, 0x0f, 0x00, 0x01, 0x71, 0xc2, - 0x00, 0x08, 0xc2, 0x1b, 0x0c, 0x2a, 0x00, 0xc4, - 0x20, 0x05, 0xa8, 0x80, 0x20, 0x01, 0xf0, 0x80, - 0x00, 0x01, 0xc2, 0x1b, 0x0c, 0x1a, 0x00, 0xc4, - 0x20, 0x05, 0xa8, 0x80, 0x20, 0x01, 0xf0, 0x80, - 0x00, 0x02, 0xc2, 0x1b, 0x0c, 0x3a, 0x00, 0xc4, - 0x20, 0x05, 0xa8, 0x80, 0x20, 0x01, 0xf0, 0x80, - 0x20, 0x03, 0xa8, 0x80, 0x00, 0x01, 0x00, 0x11, - 0x00, 0x04, 0xc2, 0x8b, 0x04, 0xaa, 0x00, 0xc4, - 0x00, 0x00, 0xe9, 0x80, 0x05, 0xb0, 0xa8, 0x18, - 0x00, 0x00, 0x4a, 0xcb, 0x20, 0x00, 0xa8, 0x22, - 0xd0, 0x01, 0x00, 0x82, 0x40, 0x01, 0x00, 0x80, - 0xc7, 0x00, 0x04, 0x19, 0xb0, 0x00, 0xe2, 0x8b, - 0x06, 0x20, 0xa8, 0x0a, 0x2f, 0x10, 0x61, 0x0a, - 0xf1, 0x08, 0x09, 0x2e, 0x00, 0x01, 0xa8, 0x02, - 0x0c, 0xf9, 0x08, 0x44, 0xcf, 0x10, 0x04, 0x19, - 0x0c, 0x2b, 0x08, 0x44, 0x9f, 0x35, 0xb1, 0x60, - 0x03, 0x08, 0x09, 0x0e, 0x00, 0x01, 0x71, 0x82, - 0x20, 0x01, 0x00, 0x80, 0x00, 0x00, 0x61, 0xcb, - 0x80, 0x01, 0x00, 0x80, 0xe4, 0x20, 0x71, 0x8b, - 0x00, 0x01, 0x00, 0x45, 0x90, 0x40, 0x09, 0x8f, - 0x00, 0x05, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0x08, 0x19, 0x04, 0xd4, 0x93, 0x00, 0x01, 0x4f, - 0xe7, 0x00, 0x01, 0x6f, 0x0d, 0x30, 0x61, 0x0a, - 0x20, 0x04, 0x61, 0xa8, 0xc2, 0x00, 0x00, 0x82, - 0x02, 0x04, 0x61, 0xa8, 0xc2, 0x00, 0x00, 0x82, - 0xcd, 0x30, 0x00, 0x09, 0x02, 0x00, 0x00, 0x02, - 0x02, 0x00, 0x00, 0x02, 0xc0, 0x80, 0x00, 0x09, - 0x20, 0x00, 0x09, 0x49, 0x0f, 0x30, 0x61, 0x0a, - 0x0d, 0x30, 0xc8, 0x0a, 0x00, 0x29, 0x00, 0xc4, - 0x00, 0x80, 0xc8, 0x0a, 0x00, 0x29, 0x00, 0xc4, - 0x00, 0x04, 0xb1, 0x80, 0x00, 0x00, 0x06, 0x39, - 0xc9, 0x20, 0x04, 0x39, 0x00, 0x39, 0x00, 0x44, - 0x00, 0x04, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0x00, 0x04, 0xb1, 0x80, 0xc9, 0x20, 0x04, 0x39, - 0x00, 0x39, 0x00, 0x44, 0x09, 0x20, 0x23, 0x0a, - 0x00, 0x00, 0x06, 0x19, 0xc9, 0x20, 0x04, 0x19, - 0x00, 0x00, 0x40, 0x45, 0x02, 0x00, 0x61, 0x0a, - 0x0c, 0xb9, 0x04, 0x14, 0x04, 0x00, 0x61, 0x0a, - 0x06, 0x00, 0x48, 0x0a, 0x00, 0xa9, 0x04, 0x54, - 0xc6, 0x00, 0x04, 0x19, 0x0c, 0xa9, 0x00, 0x44, - 0x05, 0x00, 0xc8, 0x0a, 0x0c, 0xa9, 0x04, 0x54, - 0xc5, 0x00, 0x04, 0x19, 0x07, 0x00, 0x61, 0x0a, - 0x0c, 0x00, 0x48, 0x0a, 0x00, 0xb9, 0x04, 0x54, - 0xcc, 0x00, 0x04, 0x19, 0x0c, 0xb9, 0x00, 0x44, - 0x0e, 0x00, 0xc8, 0x0a, 0x0c, 0xb9, 0x04, 0x54, - 0xce, 0x00, 0x04, 0x19, 0x0c, 0x5a, 0x00, 0x44, - 0x82, 0x0d, 0x09, 0x2e, 0x80, 0x40, 0x09, 0xcf, - 0x00, 0xdf, 0x71, 0x8b, 0x80, 0x01, 0x00, 0x80, - 0x02, 0xc1, 0x00, 0x22, 0x03, 0xc1, 0x00, 0x22, - 0x00, 0x01, 0x65, 0x80, 0xd2, 0x05, 0x65, 0x82, - 0x40, 0x21, 0x00, 0x80, 0xd3, 0x03, 0x00, 0x82, - 0x40, 0x33, 0x00, 0x80, 0x0c, 0x5a, 0x00, 0x44, - 0x0f, 0x30, 0x61, 0x0a, 0x0d, 0x30, 0xc8, 0x0a, - 0x08, 0xd9, 0x00, 0xc4, 0x93, 0x00, 0x01, 0x4f, - 0xe7, 0x00, 0x01, 0x6f, 0x0f, 0x30, 0x61, 0x0a, - 0x20, 0x00, 0x00, 0x88, 0x02, 0x00, 0x61, 0x02, - 0x02, 0x00, 0x00, 0x03, 0xcf, 0x30, 0x00, 0x09, - 0x20, 0x00, 0x09, 0x49, 0x00, 0x04, 0x63, 0x80, - 0x04, 0xd9, 0x00, 0x44, 0x00, 0x04, 0xb1, 0x80, - 0x00, 0x00, 0x00, 0x46, 0x02, 0x30, 0x61, 0x0a, - 0x05, 0xb0, 0xa8, 0x18, 0xc2, 0x30, 0x04, 0x19, - 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0xc8, 0x0a, - 0x0c, 0x0b, 0x04, 0x14, 0x0e, 0x10, 0x61, 0x0a, - 0x04, 0x2b, 0x00, 0x44, 0x0c, 0x10, 0xc8, 0x0a, - 0x04, 0x2b, 0x04, 0x54, 0x0c, 0x10, 0x61, 0x0a, - 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0xa8, 0x18, - 0xa0, 0x00, 0x00, 0x88, 0x00, 0x01, 0x71, 0x82, - 0x00, 0x00, 0x00, 0x46, 0x00, 0x04, 0x33, 0x80, - 0x00, 0x00, 0x83, 0x80, 0x20, 0x04, 0x7a, 0x80, - 0x20, 0x01, 0x33, 0x80, 0x00, 0x00, 0x83, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0x20, 0x03, 0x00, 0x80, - 0x00, 0x00, 0x00, 0x46, 0x16, 0xce, 0x11, 0x00 -}; - -static unsigned char ima_adpcm_capture[] = { - 0x00, 0x10, 0x00, 0x44, 0x08, 0x00, 0x00, 0x44, - 0x00, 0x70, 0x00, 0x44, 0x08, 0xd0, 0x00, 0x44, - 0x00, 0xf0, 0x00, 0x44, 0x0d, 0xf2, 0x61, 0xa8, - 0x44, 0x04, 0x04, 0x19, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x04, 0x63, 0x80, 0x00, 0x00, 0x06, 0x39, - 0xff, 0x2e, 0x21, 0x49, 0xff, 0x0c, 0xd4, 0x49, - 0x40, 0x49, 0x39, 0xac, 0x55, 0x55, 0x71, 0x8b, - 0x50, 0x01, 0xb1, 0x80, 0x00, 0x00, 0x71, 0x8b, - 0xc2, 0x30, 0x04, 0x19, 0xc0, 0xa0, 0x04, 0x19, - 0xc2, 0xa0, 0x04, 0x19, 0x89, 0x00, 0x71, 0x8b, - 0xc8, 0x30, 0x04, 0x19, 0x71, 0x00, 0x71, 0x8b, - 0xcd, 0x00, 0x04, 0x19, 0xcf, 0x00, 0x04, 0x19, - 0x80, 0x00, 0x71, 0x8b, 0xcb, 0x20, 0x04, 0x19, - 0x20, 0x00, 0x71, 0x8b, 0xc4, 0x20, 0x04, 0x19, - 0x47, 0x00, 0x51, 0x8b, 0xc0, 0x20, 0x00, 0x39, - 0x00, 0x00, 0x63, 0x80, 0xc1, 0xa0, 0x04, 0x19, - 0x93, 0x00, 0x01, 0x4f, 0xcd, 0x30, 0x00, 0x09, - 0xcf, 0x30, 0x00, 0x09, 0x0c, 0x40, 0x00, 0x14, - 0x00, 0x60, 0x00, 0x14, 0x00, 0x04, 0x61, 0xa8, - 0x02, 0x04, 0x61, 0xa8, 0x0c, 0x60, 0x04, 0x24, - 0x00, 0x00, 0x34, 0x49, 0x08, 0x50, 0x00, 0x44, - 0x44, 0x04, 0x04, 0x39, 0x00, 0x00, 0x40, 0x45, - 0x08, 0x30, 0x61, 0x0a, 0x05, 0xb0, 0xe8, 0x18, - 0x0c, 0xc0, 0x04, 0x54, 0xc8, 0x30, 0x04, 0x19, - 0x09, 0x04, 0x00, 0xa8, 0x0b, 0x04, 0x00, 0xa8, - 0x00, 0x00, 0x40, 0x45, 0x09, 0x04, 0x61, 0xa8, - 0xc1, 0x00, 0x04, 0x19, 0x0b, 0x04, 0x61, 0xa8, - 0xca, 0x00, 0x04, 0x19, 0x0d, 0x00, 0x61, 0x0a, - 0x00, 0x01, 0x00, 0x45, 0x0f, 0x00, 0x61, 0x0a, - 0x00, 0x40, 0x09, 0x8f, 0x00, 0x01, 0x00, 0x45, - 0x40, 0x40, 0x09, 0xef, 0xff, 0x20, 0x09, 0xcf, - 0x00, 0x04, 0x63, 0xa1, 0x50, 0x03, 0x33, 0x80, - 0x00, 0x04, 0xa3, 0x80, 0x00, 0xff, 0xc2, 0x8b, - 0x0c, 0x12, 0x04, 0x54, 0x08, 0x12, 0x00, 0xc4, - 0x20, 0x03, 0x80, 0xc0, 0x30, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x7a, 0x0a, 0xd0, 0x01, 0x00, 0x82, - 0x04, 0x50, 0x00, 0x44, 0xc0, 0x00, 0x00, 0x99, - 0x04, 0x50, 0x00, 0x44, 0x00, 0xff, 0xc2, 0x8b, - 0x20, 0x00, 0x00, 0x80, 0x00, 0x0d, 0x42, 0x8b, - 0x04, 0x42, 0x00, 0xc4, 0x00, 0x0e, 0x42, 0x8b, - 0x08, 0x52, 0x00, 0xc4, 0x00, 0x1e, 0x42, 0x8b, - 0x00, 0xe2, 0x00, 0xc4, 0x00, 0x8e, 0x42, 0x8b, - 0x08, 0xd2, 0x00, 0xc4, 0x00, 0x9e, 0x42, 0x8b, - 0x04, 0xf2, 0x00, 0xc4, 0x00, 0xbe, 0x42, 0x8b, - 0x04, 0xf2, 0x00, 0xc4, 0x00, 0x04, 0x42, 0x8b, - 0x04, 0x11, 0x00, 0xc4, 0x00, 0x24, 0x42, 0x8b, - 0x0c, 0x61, 0x00, 0xc4, 0x00, 0x55, 0x42, 0x8b, - 0x04, 0x50, 0x00, 0xc4, 0x00, 0x3f, 0x42, 0x8b, - 0x0c, 0x01, 0x00, 0xc4, 0x00, 0x00, 0x40, 0x45, - 0x20, 0x01, 0x79, 0x80, 0x00, 0x30, 0x42, 0x8b, - 0x04, 0x62, 0x00, 0xc4, 0x00, 0x00, 0x40, 0x45, - 0x00, 0x00, 0x71, 0x8b, 0x40, 0x01, 0x00, 0x80, - 0x04, 0x50, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0x08, 0xc2, 0x00, 0xc4, 0x0f, 0xf2, 0xa8, 0xa8, - 0x20, 0x00, 0xb1, 0x88, 0x00, 0x00, 0x41, 0x02, - 0x4d, 0xf2, 0x00, 0x39, 0xc0, 0x01, 0x00, 0x82, - 0x04, 0x50, 0x00, 0x44, 0x0d, 0xf2, 0xa3, 0xa8, - 0x4d, 0xf2, 0x00, 0x39, 0x04, 0x50, 0x00, 0x44, - 0xff, 0x00, 0xe2, 0xab, 0x20, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x61, 0x02, 0x4d, 0xf2, 0x04, 0x19, - 0x04, 0x50, 0x00, 0x44, 0xff, 0x00, 0xe2, 0xab, - 0xa0, 0x00, 0x00, 0x88, 0x00, 0x00, 0x61, 0x10, - 0x4d, 0xf2, 0x04, 0x19, 0x04, 0x50, 0x00, 0x44, - 0xff, 0x20, 0xe2, 0xab, 0x60, 0x00, 0x00, 0x88, - 0x00, 0x00, 0x71, 0xc0, 0x4d, 0xf2, 0x04, 0x19, - 0x04, 0x50, 0x00, 0x44, 0x00, 0x00, 0x7a, 0x0a, - 0x20, 0x01, 0xf0, 0x80, 0x01, 0xa0, 0x41, 0x0a, - 0x00, 0x11, 0x00, 0xc4, 0x20, 0x01, 0xf0, 0x80, - 0xc1, 0x30, 0x04, 0x19, 0x04, 0x50, 0x00, 0x44, - 0x00, 0x00, 0x79, 0x80, 0x0c, 0x41, 0x00, 0x84, - 0x89, 0x00, 0x71, 0x8b, 0xc8, 0x30, 0x04, 0x19, - 0x97, 0x00, 0x71, 0x8b, 0xcd, 0x00, 0x00, 0x39, - 0x00, 0x01, 0xb1, 0x80, 0x80, 0x00, 0x04, 0x19, - 0x82, 0x00, 0x04, 0x19, 0xc1, 0x20, 0x04, 0x19, - 0xc3, 0x20, 0x04, 0x19, 0xc2, 0x30, 0x04, 0x19, - 0xcd, 0x10, 0x04, 0x19, 0xcf, 0x10, 0x04, 0x19, - 0xb0, 0x00, 0x71, 0x8b, 0x84, 0x00, 0x04, 0x19, - 0x86, 0x00, 0x04, 0x19, 0x80, 0x00, 0x71, 0x8b, - 0xcb, 0x20, 0x04, 0x19, 0x93, 0x00, 0x01, 0x4f, - 0xcd, 0x30, 0x00, 0x09, 0xcf, 0x30, 0x00, 0x09, - 0x03, 0x02, 0x04, 0x49, 0x08, 0x41, 0x00, 0x14, - 0x04, 0x50, 0x00, 0x44, 0x00, 0x00, 0x63, 0x80, - 0x00, 0x00, 0x06, 0x19, 0x03, 0x00, 0x04, 0x49, - 0x04, 0x50, 0x00, 0x44, 0x20, 0x01, 0x63, 0x80, - 0x00, 0x00, 0x06, 0x19, 0x00, 0x20, 0xe2, 0x8b, - 0x00, 0xc1, 0x00, 0x84, 0x47, 0x00, 0x51, 0x8b, - 0xc0, 0x20, 0x00, 0x39, 0x00, 0x00, 0x63, 0x80, - 0xc1, 0xa0, 0x04, 0x19, 0x00, 0xe1, 0x00, 0x44, - 0xbd, 0x00, 0x51, 0x8b, 0xc0, 0x20, 0x00, 0x39, - 0x00, 0x00, 0xb1, 0x80, 0xc1, 0xa0, 0x04, 0x19, - 0x03, 0x00, 0x04, 0x49, 0x04, 0x50, 0x00, 0x44, - 0x00, 0x20, 0x61, 0x0a, 0x00, 0x01, 0x00, 0x45, - 0x02, 0x30, 0x61, 0x0a, 0x0c, 0x83, 0x00, 0xc4, - 0x0c, 0x78, 0x08, 0x44, 0x04, 0x5a, 0x08, 0x44, - 0xb2, 0x00, 0x09, 0x4f, 0x10, 0x42, 0x09, 0x8e, - 0x05, 0xb0, 0xe0, 0x18, 0x04, 0x23, 0x00, 0x84, - 0x0c, 0x01, 0x00, 0x11, 0x08, 0x05, 0x61, 0x10, - 0x00, 0x49, 0x08, 0x44, 0x00, 0x48, 0x08, 0x44, - 0xb2, 0x00, 0x09, 0x4f, 0x80, 0x00, 0x71, 0x8b, - 0xc0, 0x00, 0x00, 0x82, 0x0c, 0x01, 0x33, 0x10, - 0x28, 0x01, 0xa3, 0x10, 0x00, 0x01, 0x7a, 0x80, - 0x8c, 0x01, 0x00, 0x80, 0x02, 0x30, 0x61, 0x0a, - 0x20, 0x00, 0x04, 0x19, 0x0c, 0x83, 0x00, 0xc4, - 0x05, 0xb0, 0xc8, 0x18, 0x08, 0x43, 0x00, 0xc4, - 0x01, 0x30, 0xc8, 0x0a, 0x0c, 0x38, 0x00, 0xc4, - 0x08, 0x88, 0x00, 0x44, 0x0c, 0x78, 0x08, 0x44, - 0x04, 0x5a, 0x08, 0x44, 0x00, 0x00, 0xa3, 0x18, - 0x80, 0x00, 0x04, 0x19, 0x0b, 0x04, 0x61, 0xa8, - 0xc3, 0x20, 0x00, 0x39, 0xc3, 0x30, 0x04, 0x19, - 0x0f, 0x10, 0x61, 0x0a, 0xca, 0x30, 0x04, 0x19, - 0x09, 0x04, 0x41, 0xa8, 0xe1, 0x20, 0x00, 0x39, - 0xd1, 0x00, 0x09, 0x4f, 0x00, 0x04, 0x61, 0x02, - 0x08, 0x63, 0x00, 0x44, 0x03, 0x30, 0x41, 0x0a, - 0x20, 0x00, 0x00, 0x39, 0xa3, 0x00, 0x09, 0x4f, - 0x00, 0x04, 0x61, 0x02, 0x00, 0x48, 0x08, 0x44, - 0x08, 0x88, 0x00, 0x44, 0x02, 0x30, 0x61, 0x0a, - 0x00, 0x08, 0x00, 0xc4, 0x0c, 0x78, 0x08, 0x44, - 0x04, 0x5a, 0x08, 0x44, 0xb2, 0x00, 0x09, 0x0f, - 0x10, 0x40, 0x09, 0x8e, 0x00, 0x00, 0x68, 0x5b, - 0x20, 0x04, 0xb1, 0x80, 0x02, 0x00, 0x61, 0x5b, - 0x88, 0x03, 0x7a, 0x80, 0xac, 0x01, 0x00, 0x80, - 0x05, 0xb0, 0xe0, 0x18, 0x00, 0xd3, 0x00, 0x84, - 0x00, 0x49, 0x08, 0x44, 0x00, 0x48, 0x08, 0x44, - 0xb2, 0x00, 0x09, 0x0f, 0x80, 0x00, 0x71, 0x8b, - 0xc0, 0x00, 0x00, 0x82, 0x02, 0x30, 0x61, 0x0a, - 0x00, 0x08, 0x00, 0xc4, 0x05, 0xb0, 0xc8, 0x18, - 0x0c, 0x18, 0x00, 0xc4, 0x01, 0x30, 0xc8, 0x0a, - 0x0c, 0x38, 0x00, 0xc4, 0x08, 0x88, 0x00, 0x44, - 0x0c, 0x78, 0x08, 0x44, 0x00, 0x00, 0x61, 0x18, - 0x20, 0x05, 0xb1, 0x80, 0x00, 0x00, 0x68, 0xcb, - 0x80, 0x00, 0x04, 0x19, 0x0d, 0x10, 0x61, 0x0a, - 0xc3, 0x30, 0x04, 0x19, 0x0b, 0x04, 0x41, 0xa8, - 0x09, 0x04, 0x41, 0xa8, 0xe1, 0x20, 0x00, 0x39, - 0x08, 0x38, 0x00, 0x44, 0x03, 0x30, 0x41, 0x0a, - 0x20, 0x04, 0xb1, 0x80, 0x00, 0x48, 0x08, 0x44, - 0x08, 0x88, 0x00, 0x44, 0x00, 0x00, 0xb1, 0x80, - 0xc2, 0x30, 0x04, 0x19, 0x0c, 0xb8, 0x00, 0xd4, - 0x0f, 0x30, 0x61, 0x0a, 0x0d, 0x30, 0xc8, 0x0a, - 0x0c, 0xb8, 0x00, 0xc4, 0x93, 0x00, 0x01, 0x4f, - 0xe7, 0x00, 0x01, 0x6f, 0x0f, 0x30, 0x61, 0x0a, - 0x20, 0x00, 0x00, 0x88, 0x02, 0x00, 0x61, 0x02, - 0x41, 0x04, 0x04, 0x19, 0x02, 0x04, 0x61, 0x02, - 0x43, 0x04, 0x04, 0x39, 0xcf, 0x30, 0x00, 0x09, - 0x20, 0x00, 0x09, 0x49, 0x00, 0x59, 0x00, 0x44, - 0x93, 0x00, 0x01, 0x4f, 0xe7, 0x00, 0x01, 0x6f, - 0x0d, 0x30, 0x61, 0x0a, 0x20, 0x00, 0x61, 0x88, - 0xc2, 0x00, 0x00, 0x82, 0xc2, 0x03, 0x00, 0x82, - 0xcd, 0x30, 0x00, 0x09, 0x20, 0x00, 0x09, 0x49, - 0x0f, 0x30, 0x61, 0x0a, 0x0d, 0x30, 0xc8, 0x0a, - 0x0c, 0x58, 0x00, 0x84, 0x02, 0x30, 0x61, 0x0a, - 0x05, 0xb0, 0xa8, 0x18, 0xc2, 0x30, 0x04, 0x19, - 0x00, 0x00, 0x00, 0x46, 0x90, 0x40, 0x09, 0x8f, - 0x12, 0x04, 0x09, 0x6e, 0x03, 0x00, 0x09, 0x0e, - 0x00, 0x01, 0x71, 0x82, 0x20, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x61, 0xcb, 0x80, 0x04, 0xb1, 0x80, - 0x00, 0x01, 0xe0, 0x60, 0x0c, 0xd8, 0x04, 0x14, - 0x00, 0x01, 0xeb, 0x80, 0x40, 0x00, 0x52, 0x1b, - 0x80, 0x00, 0x79, 0x80, 0xc0, 0x01, 0x71, 0xc2, - 0x20, 0x00, 0xc0, 0x80, 0x08, 0x0a, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x80, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0xf0, 0x80, - 0x20, 0x00, 0xc0, 0x80, 0x0c, 0x2a, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x10, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0xf0, 0x80, - 0x20, 0x00, 0xc0, 0x80, 0x08, 0x3a, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x20, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0xc0, 0x03, 0xf0, 0x82, - 0x20, 0x00, 0xa0, 0x80, 0x00, 0x01, 0x00, 0x11, - 0x40, 0x00, 0xc2, 0x8b, 0x00, 0xaa, 0x00, 0xc4, - 0x00, 0x00, 0xe9, 0x80, 0x05, 0xb0, 0xa8, 0x18, - 0x00, 0x01, 0xa8, 0x22, 0xd0, 0x01, 0x00, 0x82, - 0xf0, 0x00, 0xe2, 0x1b, 0x06, 0x20, 0xa8, 0x0a, - 0x2d, 0x10, 0x61, 0x0a, 0xd1, 0x00, 0x09, 0x2e, - 0x00, 0x01, 0xa8, 0x02, 0x0e, 0x10, 0xc8, 0x0a, - 0x0c, 0xba, 0x04, 0x14, 0x0e, 0x10, 0x61, 0x0a, - 0x04, 0x4a, 0x00, 0x44, 0x0c, 0x10, 0xc8, 0x0a, - 0x04, 0x4a, 0x04, 0x54, 0x0c, 0x10, 0x61, 0x0a, - 0xd0, 0x01, 0x00, 0x82, 0x00, 0x10, 0xa8, 0x18, - 0xa0, 0x00, 0x00, 0x88, 0x00, 0x01, 0x71, 0x82, - 0x03, 0x00, 0x09, 0x0e, 0x9a, 0x01, 0x00, 0x60, - 0x32, 0x00, 0x09, 0x2e, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x01, 0x71, 0x82, 0x20, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x61, 0xcb, 0x80, 0x24, 0xb1, 0xc0, - 0x00, 0x31, 0xe0, 0x60, 0x0c, 0xca, 0x04, 0x14, - 0x00, 0x01, 0xeb, 0x80, 0x40, 0x00, 0x52, 0x1b, - 0x80, 0x00, 0x79, 0x80, 0xc0, 0x01, 0x71, 0xc2, - 0x20, 0x00, 0xc0, 0x80, 0x08, 0xda, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x80, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0xf0, 0x80, - 0x20, 0x00, 0xc0, 0x80, 0x0c, 0xfa, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x10, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0xf0, 0x80, - 0x20, 0x00, 0xc0, 0x80, 0x08, 0x29, 0x04, 0x54, - 0xc0, 0x04, 0xa8, 0x82, 0x20, 0x00, 0x72, 0x1b, - 0x80, 0x00, 0x00, 0x80, 0xc0, 0x03, 0xf0, 0x82, - 0x20, 0x00, 0xa0, 0x80, 0x00, 0x01, 0x00, 0x11, - 0x40, 0x00, 0xc2, 0x8b, 0x00, 0x39, 0x00, 0xc4, - 0x00, 0x00, 0xe9, 0x80, 0x05, 0xb0, 0xa8, 0x18, - 0x00, 0x01, 0xa8, 0x22, 0xd0, 0x01, 0x00, 0x82, - 0xb0, 0x00, 0xe2, 0x1b, 0x06, 0x20, 0xa8, 0x0a, - 0x2f, 0x10, 0x61, 0x0a, 0xf1, 0x00, 0x09, 0x2e, - 0x00, 0x01, 0xa8, 0x02, 0x0e, 0x10, 0xc8, 0x0a, - 0x0c, 0xa9, 0x04, 0x14, 0x0e, 0x10, 0x61, 0x0a, - 0x04, 0x99, 0x00, 0x44, 0x0c, 0x10, 0xc8, 0x0a, - 0x04, 0x99, 0x04, 0x54, 0x0c, 0x10, 0x61, 0x0a, - 0xd0, 0x01, 0x00, 0x82, 0x00, 0x10, 0xa8, 0x18, - 0xa0, 0x00, 0x00, 0x88, 0x00, 0x01, 0x71, 0x82, - 0x9f, 0x01, 0x00, 0x60, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x33, 0x80, 0x00, 0x00, 0x83, 0x80, - 0x20, 0x00, 0x7a, 0x80, 0x20, 0x07, 0x33, 0x80, - 0x00, 0x00, 0x83, 0x80, 0x20, 0x04, 0x7a, 0x80, - 0x20, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x46, - 0x02, 0x00, 0x61, 0x0a, 0x04, 0x1b, 0x04, 0x14, - 0x01, 0x00, 0x61, 0x0a, 0x03, 0x00, 0x48, 0x0a, - 0x0c, 0x79, 0x04, 0x54, 0xc3, 0x00, 0x04, 0x19, - 0x04, 0xc9, 0x00, 0x44, 0x08, 0x00, 0xc8, 0x0a, - 0x04, 0xc9, 0x04, 0x54, 0xc8, 0x00, 0x04, 0x19, - 0x0a, 0x00, 0x61, 0x0a, 0x09, 0x00, 0x48, 0x0a, - 0x0c, 0xe9, 0x04, 0x54, 0xc9, 0x00, 0x04, 0x19, - 0x04, 0xd9, 0x00, 0x44, 0x0b, 0x00, 0xc8, 0x0a, - 0x04, 0xd9, 0x04, 0x54, 0xcb, 0x00, 0x04, 0x19, - 0x04, 0x00, 0x61, 0x0a, 0x06, 0x00, 0x48, 0x0a, - 0x0c, 0xf9, 0x04, 0x54, 0xc6, 0x00, 0x04, 0x19, - 0x04, 0x0b, 0x00, 0x44, 0x05, 0x00, 0xc8, 0x0a, - 0x04, 0x0b, 0x04, 0x54, 0xc5, 0x00, 0x04, 0x19, - 0x07, 0x00, 0x61, 0x0a, 0x0c, 0x00, 0x48, 0x0a, - 0x0c, 0x2b, 0x04, 0x54, 0xcc, 0x00, 0x04, 0x19, - 0x04, 0x1b, 0x00, 0x44, 0x0e, 0x00, 0xc8, 0x0a, - 0x04, 0x1b, 0x04, 0x54, 0xce, 0x00, 0x04, 0x19, - 0x00, 0x00, 0x40, 0x45, 0x92, 0x20, 0x71, 0x8b, - 0xa6, 0xc5, 0x11, 0x00 -}; diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index a6a0fa51626..0bbcd4714d2 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Routines for control of 16-bit SoundBlaster cards and clones * Note: This is very ugly hardware which uses one 8-bit DMA channel and * second 16-bit DMA channel. Unfortunately 8-bit DMA channel can't @@ -33,11 +33,11 @@ * */ -#include <sound/driver.h> #include <asm/io.h> #include <asm/dma.h> #include <linux/init.h> #include <linux/time.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/sb.h> #include <sound/sb16_csp.h> @@ -45,15 +45,15 @@ #include <sound/control.h> #include <sound/info.h> -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("Routines for control of 16-bit SoundBlaster cards and clones"); MODULE_LICENSE("GPL"); #ifdef CONFIG_SND_SB16_CSP -static void snd_sb16_csp_playback_prepare(sb_t *chip, snd_pcm_runtime_t *runtime) +static void snd_sb16_csp_playback_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime) { if (chip->hardware == SB_HW_16CSP) { - snd_sb_csp_t *csp = chip->csp; + struct snd_sb_csp *csp = chip->csp; if (csp->running & SNDRV_SB_CSP_ST_LOADED) { /* manually loaded codec */ @@ -98,10 +98,10 @@ static void snd_sb16_csp_playback_prepare(sb_t *chip, snd_pcm_runtime_t *runtime } } -static void snd_sb16_csp_capture_prepare(sb_t *chip, snd_pcm_runtime_t *runtime) +static void snd_sb16_csp_capture_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime) { if (chip->hardware == SB_HW_16CSP) { - snd_sb_csp_t *csp = chip->csp; + struct snd_sb_csp *csp = chip->csp; if (csp->running & SNDRV_SB_CSP_ST_LOADED) { /* manually loaded codec */ @@ -136,10 +136,10 @@ static void snd_sb16_csp_capture_prepare(sb_t *chip, snd_pcm_runtime_t *runtime) } } -static void snd_sb16_csp_update(sb_t *chip) +static void snd_sb16_csp_update(struct snd_sb *chip) { if (chip->hardware == SB_HW_16CSP) { - snd_sb_csp_t *csp = chip->csp; + struct snd_sb_csp *csp = chip->csp; if (csp->qpos_changed) { spin_lock(&chip->reg_lock); @@ -149,11 +149,11 @@ static void snd_sb16_csp_update(sb_t *chip) } } -static void snd_sb16_csp_playback_open(sb_t *chip, snd_pcm_runtime_t *runtime) +static void snd_sb16_csp_playback_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime) { /* CSP decoders (QSound excluded) support only 16bit transfers */ if (chip->hardware == SB_HW_16CSP) { - snd_sb_csp_t *csp = chip->csp; + struct snd_sb_csp *csp = chip->csp; if (csp->running & SNDRV_SB_CSP_ST_LOADED) { /* manually loaded codec */ @@ -168,10 +168,10 @@ static void snd_sb16_csp_playback_open(sb_t *chip, snd_pcm_runtime_t *runtime) } } -static void snd_sb16_csp_playback_close(sb_t *chip) +static void snd_sb16_csp_playback_close(struct snd_sb *chip) { if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_WRITE)) { - snd_sb_csp_t *csp = chip->csp; + struct snd_sb_csp *csp = chip->csp; if (csp->ops.csp_stop(csp) == 0) { csp->ops.csp_unuse(csp); @@ -180,11 +180,11 @@ static void snd_sb16_csp_playback_close(sb_t *chip) } } -static void snd_sb16_csp_capture_open(sb_t *chip, snd_pcm_runtime_t *runtime) +static void snd_sb16_csp_capture_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime) { /* CSP coders support only 16bit transfers */ if (chip->hardware == SB_HW_16CSP) { - snd_sb_csp_t *csp = chip->csp; + struct snd_sb_csp *csp = chip->csp; if (csp->running & SNDRV_SB_CSP_ST_LOADED) { /* manually loaded codec */ @@ -199,10 +199,10 @@ static void snd_sb16_csp_capture_open(sb_t *chip, snd_pcm_runtime_t *runtime) } } -static void snd_sb16_csp_capture_close(sb_t *chip) +static void snd_sb16_csp_capture_close(struct snd_sb *chip) { if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_READ)) { - snd_sb_csp_t *csp = chip->csp; + struct snd_sb_csp *csp = chip->csp; if (csp->ops.csp_stop(csp) == 0) { csp->ops.csp_unuse(csp); @@ -221,7 +221,7 @@ static void snd_sb16_csp_capture_close(sb_t *chip) #endif -static void snd_sb16_setup_rate(sb_t *chip, +static void snd_sb16_setup_rate(struct snd_sb *chip, unsigned short rate, int channel) { @@ -244,23 +244,23 @@ static void snd_sb16_setup_rate(sb_t *chip, spin_unlock_irqrestore(&chip->reg_lock, flags); } -static int snd_sb16_hw_params(snd_pcm_substream_t * substream, - snd_pcm_hw_params_t * hw_params) +static int snd_sb16_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) { return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } -static int snd_sb16_hw_free(snd_pcm_substream_t * substream) +static int snd_sb16_hw_free(struct snd_pcm_substream *substream) { snd_pcm_lib_free_pages(substream); return 0; } -static int snd_sb16_playback_prepare(snd_pcm_substream_t * substream) +static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_sb *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; unsigned char format; unsigned int size, count, dma; @@ -298,19 +298,21 @@ static int snd_sb16_playback_prepare(snd_pcm_substream_t * substream) return 0; } -static int snd_sb16_playback_trigger(snd_pcm_substream_t * substream, +static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream, int cmd) { - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); int result = 0; spin_lock(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: chip->mode |= SB_RATE_LOCK_PLAYBACK; snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON); break; case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF); /* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */ if (chip->mode & SB_RATE_LOCK_CAPTURE) @@ -324,11 +326,11 @@ static int snd_sb16_playback_trigger(snd_pcm_substream_t * substream, return result; } -static int snd_sb16_capture_prepare(snd_pcm_substream_t * substream) +static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_sb *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; unsigned char format; unsigned int size, count, dma; @@ -365,19 +367,21 @@ static int snd_sb16_capture_prepare(snd_pcm_substream_t * substream) return 0; } -static int snd_sb16_capture_trigger(snd_pcm_substream_t * substream, +static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream, int cmd) { - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); int result = 0; spin_lock(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: chip->mode |= SB_RATE_LOCK_CAPTURE; snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON); break; case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF); /* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */ if (chip->mode & SB_RATE_LOCK_PLAYBACK) @@ -391,9 +395,9 @@ static int snd_sb16_capture_trigger(snd_pcm_substream_t * substream, return result; } -irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id) { - sb_t *chip = dev_id; + struct snd_sb *chip = dev_id; unsigned char status; int ok; @@ -401,7 +405,7 @@ irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs) status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS); spin_unlock(&chip->mixer_lock); if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback) - chip->rmidi_callback(irq, chip->rmidi->private_data, regs); + chip->rmidi_callback(irq, chip->rmidi->private_data); if (status & SB_IRQTYPE_8BIT) { ok = 0; if (chip->mode & SB_MODE_PLAYBACK_8) { @@ -443,9 +447,9 @@ irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ -static snd_pcm_uframes_t snd_sb16_playback_pointer(snd_pcm_substream_t * substream) +static snd_pcm_uframes_t snd_sb16_playback_pointer(struct snd_pcm_substream *substream) { - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); unsigned int dma; size_t ptr; @@ -454,9 +458,9 @@ static snd_pcm_uframes_t snd_sb16_playback_pointer(snd_pcm_substream_t * substre return bytes_to_frames(substream->runtime, ptr); } -static snd_pcm_uframes_t snd_sb16_capture_pointer(snd_pcm_substream_t * substream) +static snd_pcm_uframes_t snd_sb16_capture_pointer(struct snd_pcm_substream *substream) { - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); unsigned int dma; size_t ptr; @@ -469,7 +473,7 @@ static snd_pcm_uframes_t snd_sb16_capture_pointer(snd_pcm_substream_t * substrea */ -static snd_pcm_hardware_t snd_sb16_playback = +static struct snd_pcm_hardware snd_sb16_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -487,7 +491,7 @@ static snd_pcm_hardware_t snd_sb16_playback = .fifo_size = 0, }; -static snd_pcm_hardware_t snd_sb16_capture = +static struct snd_pcm_hardware snd_sb16_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -509,11 +513,11 @@ static snd_pcm_hardware_t snd_sb16_capture = * open/close */ -static int snd_sb16_playback_open(snd_pcm_substream_t * substream) +static int snd_sb16_playback_open(struct snd_pcm_substream *substream) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_sb *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; spin_lock_irqsave(&chip->open_lock, flags); if (chip->mode & SB_MODE_PLAYBACK) { @@ -559,6 +563,11 @@ static int snd_sb16_playback_open(snd_pcm_substream_t * substream) __open_ok: if (chip->hardware == SB_HW_ALS100) runtime->hw.rate_max = 48000; + if (chip->hardware == SB_HW_CS5530) { + runtime->hw.buffer_bytes_max = 32 * 1024; + runtime->hw.periods_min = 2; + runtime->hw.rate_min = 44100; + } if (chip->mode & SB_RATE_LOCK) runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; chip->playback_substream = substream; @@ -566,10 +575,10 @@ static int snd_sb16_playback_open(snd_pcm_substream_t * substream) return 0; } -static int snd_sb16_playback_close(snd_pcm_substream_t * substream) +static int snd_sb16_playback_close(struct snd_pcm_substream *substream) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); snd_sb16_csp_playback_close(chip); spin_lock_irqsave(&chip->open_lock, flags); @@ -579,11 +588,11 @@ static int snd_sb16_playback_close(snd_pcm_substream_t * substream) return 0; } -static int snd_sb16_capture_open(snd_pcm_substream_t * substream) +static int snd_sb16_capture_open(struct snd_pcm_substream *substream) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_sb *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; spin_lock_irqsave(&chip->open_lock, flags); if (chip->mode & SB_MODE_CAPTURE) { @@ -629,6 +638,11 @@ static int snd_sb16_capture_open(snd_pcm_substream_t * substream) __open_ok: if (chip->hardware == SB_HW_ALS100) runtime->hw.rate_max = 48000; + if (chip->hardware == SB_HW_CS5530) { + runtime->hw.buffer_bytes_max = 32 * 1024; + runtime->hw.periods_min = 2; + runtime->hw.rate_min = 44100; + } if (chip->mode & SB_RATE_LOCK) runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; chip->capture_substream = substream; @@ -636,10 +650,10 @@ static int snd_sb16_capture_open(snd_pcm_substream_t * substream) return 0; } -static int snd_sb16_capture_close(snd_pcm_substream_t * substream) +static int snd_sb16_capture_close(struct snd_pcm_substream *substream) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); snd_sb16_csp_capture_close(chip); spin_lock_irqsave(&chip->open_lock, flags); @@ -653,10 +667,11 @@ static int snd_sb16_capture_close(snd_pcm_substream_t * substream) * DMA control interface */ -static int snd_sb16_set_dma_mode(sb_t *chip, int what) +static int snd_sb16_set_dma_mode(struct snd_sb *chip, int what) { if (chip->dma8 < 0 || chip->dma16 < 0) { - snd_assert(what == 0, return -EINVAL); + if (snd_BUG_ON(what)) + return -EINVAL; return 0; } if (what == 0) { @@ -671,7 +686,7 @@ static int snd_sb16_set_dma_mode(sb_t *chip, int what) return 0; } -static int snd_sb16_get_dma_mode(sb_t *chip) +static int snd_sb16_get_dma_mode(struct snd_sb *chip) { if (chip->dma8 < 0 || chip->dma16 < 0) return 0; @@ -685,7 +700,7 @@ static int snd_sb16_get_dma_mode(sb_t *chip) } } -static int snd_sb16_dma_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[3] = { "Auto", "Playback", "Capture" @@ -700,9 +715,9 @@ static int snd_sb16_dma_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info return 0; } -static int snd_sb16_dma_control_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *chip = snd_kcontrol_chip(kcontrol); + struct snd_sb *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; spin_lock_irqsave(&chip->reg_lock, flags); @@ -711,9 +726,9 @@ static int snd_sb16_dma_control_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu return 0; } -static int snd_sb16_dma_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *chip = snd_kcontrol_chip(kcontrol); + struct snd_sb *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; unsigned char nval, oval; int change; @@ -728,8 +743,8 @@ static int snd_sb16_dma_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu return change; } -static snd_kcontrol_new_t snd_sb16_dma_control = { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, +static struct snd_kcontrol_new snd_sb16_dma_control = { + .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = "16-bit DMA Allocation", .info = snd_sb16_dma_control_info, .get = snd_sb16_dma_control_get, @@ -740,14 +755,14 @@ static snd_kcontrol_new_t snd_sb16_dma_control = { * Initialization part */ -int snd_sb16dsp_configure(sb_t * chip) +int snd_sb16dsp_configure(struct snd_sb * chip) { unsigned long flags; unsigned char irqreg = 0, dmareg = 0, mpureg; unsigned char realirq, realdma, realmpureg; /* note: mpu register should be present only on SB16 Vibra soundcards */ - // printk("codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16); + // printk(KERN_DEBUG "codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16); spin_lock_irqsave(&chip->mixer_lock, flags); mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06; spin_unlock_irqrestore(&chip->mixer_lock, flags); @@ -821,15 +836,15 @@ int snd_sb16dsp_configure(sb_t * chip) spin_unlock_irqrestore(&chip->mixer_lock, flags); if ((~realirq) & irqreg || (~realdma) & dmareg) { - snd_printk("SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port); - snd_printk("SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg); - snd_printk("SB16 [0x%lx]: got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg); + snd_printk(KERN_ERR "SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port); + snd_printk(KERN_ERR "SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg); + snd_printk(KERN_ERR "SB16 [0x%lx]: got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg); return -ENODEV; } return 0; } -static snd_pcm_ops_t snd_sb16_playback_ops = { +static struct snd_pcm_ops snd_sb16_playback_ops = { .open = snd_sb16_playback_open, .close = snd_sb16_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -840,7 +855,7 @@ static snd_pcm_ops_t snd_sb16_playback_ops = { .pointer = snd_sb16_playback_pointer, }; -static snd_pcm_ops_t snd_sb16_capture_ops = { +static struct snd_pcm_ops snd_sb16_capture_ops = { .open = snd_sb16_capture_open, .close = snd_sb16_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -851,15 +866,10 @@ static snd_pcm_ops_t snd_sb16_capture_ops = { .pointer = snd_sb16_capture_pointer, }; -static void snd_sb16dsp_pcm_free(snd_pcm_t *pcm) -{ - snd_pcm_lib_preallocate_free_for_all(pcm); -} - -int snd_sb16dsp_pcm(sb_t * chip, int device, snd_pcm_t ** rpcm) +int snd_sb16dsp_pcm(struct snd_sb * chip, int device, struct snd_pcm ** rpcm) { - snd_card_t *card = chip->card; - snd_pcm_t *pcm; + struct snd_card *card = chip->card; + struct snd_pcm *pcm; int err; if (rpcm) @@ -869,7 +879,6 @@ int snd_sb16dsp_pcm(sb_t * chip, int device, snd_pcm_t ** rpcm) sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff); pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; pcm->private_data = chip; - pcm->private_free = snd_sb16dsp_pcm_free; 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); @@ -888,7 +897,7 @@ int snd_sb16dsp_pcm(sb_t * chip, int device, snd_pcm_t ** rpcm) return 0; } -const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction) +const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction) { return direction == SNDRV_PCM_STREAM_PLAYBACK ? &snd_sb16_playback_ops : &snd_sb16_capture_ops; diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index e2cbc4202b3..6c32b3aa34a 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c @@ -1,6 +1,6 @@ /* * Driver for SoundBlaster 1.0/2.0/Pro soundcards and compatible - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -19,25 +19,24 @@ * */ -#include <sound/driver.h> #include <linux/init.h> -#include <linux/slab.h> +#include <linux/err.h> +#include <linux/isa.h> #include <linux/ioport.h> -#include <linux/moduleparam.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/sb.h> #include <sound/opl3.h> -#define SNDRV_LEGACY_AUTO_PROBE #include <sound/initval.h> -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("Sound Blaster 1.0/2.0/Pro"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB 1.0/SB 2.0/SB Pro}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3 */ @@ -57,13 +56,12 @@ MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver."); struct snd_sb8 { struct resource *fm_res; /* used to block FM i/o region for legacy cards */ + struct snd_sb *chip; }; -static snd_card_t *snd_sb8_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; - -static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id) { - sb_t *chip = dev_id; + struct snd_sb *chip = dev_id; if (chip->open & SB_OPEN_PCM) { return snd_sb8dsp_interrupt(chip); @@ -72,89 +70,120 @@ static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id, struct pt_regs *regs } } -static void snd_sb8_free(snd_card_t *card) +static void snd_sb8_free(struct snd_card *card) { - struct snd_sb8 *acard = (struct snd_sb8 *)card->private_data; + struct snd_sb8 *acard = card->private_data; if (acard == NULL) return; - if (acard->fm_res) { - release_resource(acard->fm_res); - kfree_nocheck(acard->fm_res); + release_and_free_resource(acard->fm_res); +} + +static int snd_sb8_match(struct device *pdev, unsigned int dev) +{ + if (!enable[dev]) + return 0; + if (irq[dev] == SNDRV_AUTO_IRQ) { + dev_err(pdev, "please specify irq\n"); + return 0; + } + if (dma8[dev] == SNDRV_AUTO_DMA) { + dev_err(pdev, "please specify dma8\n"); + return 0; } + return 1; } -static int __init snd_sb8_probe(int dev) +static int snd_sb8_probe(struct device *pdev, unsigned int dev) { - sb_t *chip; - snd_card_t *card; + struct snd_sb *chip; + struct snd_card *card; struct snd_sb8 *acard; - opl3_t *opl3; + struct snd_opl3 *opl3; int err; - card = snd_card_new(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_sb8)); - if (card == NULL) - return -ENOMEM; - acard = (struct snd_sb8 *)card->private_data; + err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_sb8), &card); + if (err < 0) + return err; + acard = card->private_data; card->private_free = snd_sb8_free; /* block the 0x388 port to avoid PnP conflicts */ acard->fm_res = request_region(0x388, 4, "SoundBlaster FM"); - if ((err = snd_sbdsp_create(card, port[dev], irq[dev], - snd_sb8_interrupt, - dma8[dev], - -1, - SB_HW_AUTO, - &chip)) < 0) { - snd_card_free(card); - return err; + if (port[dev] != SNDRV_AUTO_PORT) { + if ((err = snd_sbdsp_create(card, port[dev], irq[dev], + snd_sb8_interrupt, + dma8[dev], + -1, + SB_HW_AUTO, + &chip)) < 0) + goto _err; + } else { + /* auto-probe legacy ports */ + static unsigned long possible_ports[] = { + 0x220, 0x240, 0x260, + }; + int i; + for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { + err = snd_sbdsp_create(card, possible_ports[i], + irq[dev], + snd_sb8_interrupt, + dma8[dev], + -1, + SB_HW_AUTO, + &chip); + if (err >= 0) { + port[dev] = possible_ports[i]; + break; + } + } + if (i >= ARRAY_SIZE(possible_ports)) { + err = -EINVAL; + goto _err; + } } + acard->chip = chip; + if (chip->hardware >= SB_HW_16) { - snd_card_free(card); if (chip->hardware == SB_HW_ALS100) - snd_printdd("ALS100 chip detected at 0x%lx, try snd-als100 module\n", + snd_printk(KERN_WARNING "ALS100 chip detected at 0x%lx, try snd-als100 module\n", port[dev]); else - snd_printdd("SB 16 chip detected at 0x%lx, try snd-sb16 module\n", - port[dev]); - return -ENODEV; + snd_printk(KERN_WARNING "SB 16 chip detected at 0x%lx, try snd-sb16 module\n", + port[dev]); + err = -ENODEV; + goto _err; } - if ((err = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) { - snd_card_free(card); - return err; - } - if ((err = snd_sbmixer_new(chip)) < 0) { - snd_card_free(card); - return err; - } + if ((err = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) + goto _err; + + if ((err = snd_sbmixer_new(chip)) < 0) + goto _err; + if (chip->hardware == SB_HW_10 || chip->hardware == SB_HW_20) { if ((err = snd_opl3_create(card, chip->port + 8, 0, OPL3_HW_AUTO, 1, &opl3)) < 0) { - snd_printk(KERN_ERR "sb8: no OPL device at 0x%lx\n", chip->port + 8); + snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx\n", chip->port + 8); } } else { if ((err = snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_AUTO, 1, &opl3)) < 0) { - snd_printk(KERN_ERR "sb8: no OPL device at 0x%lx-0x%lx\n", + snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx-0x%lx\n", chip->port, chip->port + 2); } } if (err >= 0) { - if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { - snd_card_free(card); - return err; - } + if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) + goto _err; } - if ((err = snd_sb8dsp_midi(chip, 0, NULL)) < 0) { - snd_card_free(card); - return err; - } + if ((err = snd_sb8dsp_midi(chip, 0, NULL)) < 0) + goto _err; strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8"); strcpy(card->shortname, chip->name); @@ -162,61 +191,74 @@ static int __init snd_sb8_probe(int dev) chip->name, chip->port, irq[dev], dma8[dev]); - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } - snd_sb8_cards[dev] = card; + + if ((err = snd_card_register(card)) < 0) + goto _err; + + dev_set_drvdata(pdev, card); return 0; + + _err: + snd_card_free(card); + return err; } -static int __init snd_card_sb8_legacy_auto_probe(unsigned long xport) +static int snd_sb8_remove(struct device *pdev, unsigned int dev) { - static int dev; - int res; - - for ( ; dev < SNDRV_CARDS; dev++) { - if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT) - continue; - port[dev] = xport; - res = snd_sb8_probe(dev); - if (res < 0) - port[dev] = SNDRV_AUTO_PORT; - return res; - } - return -ENODEV; + snd_card_free(dev_get_drvdata(pdev)); + return 0; } -static int __init alsa_card_sb8_init(void) +#ifdef CONFIG_PM +static int snd_sb8_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - static unsigned long possible_ports[] = {0x220, 0x240, 0x260, -1}; - int dev, cards, i; - - for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) { - if (port[dev] == SNDRV_AUTO_PORT) - continue; - if (snd_sb8_probe(dev) >= 0) - cards++; - } - i = snd_legacy_auto_probe(possible_ports, snd_card_sb8_legacy_auto_probe); - if (i > 0) - cards += i; + struct snd_card *card = dev_get_drvdata(dev); + struct snd_sb8 *acard = card->private_data; + struct snd_sb *chip = acard->chip; - if (!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "Sound Blaster soundcard not found or device busy\n"); -#endif - return -ENODEV; - } + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + snd_pcm_suspend_all(chip->pcm); + snd_sbmixer_suspend(chip); return 0; } -static void __exit alsa_card_sb8_exit(void) +static int snd_sb8_resume(struct device *dev, unsigned int n) +{ + struct snd_card *card = dev_get_drvdata(dev); + struct snd_sb8 *acard = card->private_data; + struct snd_sb *chip = acard->chip; + + snd_sbdsp_reset(chip); + snd_sbmixer_resume(chip); + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +#endif + +#define DEV_NAME "sb8" + +static struct isa_driver snd_sb8_driver = { + .match = snd_sb8_match, + .probe = snd_sb8_probe, + .remove = snd_sb8_remove, +#ifdef CONFIG_PM + .suspend = snd_sb8_suspend, + .resume = snd_sb8_resume, +#endif + .driver = { + .name = DEV_NAME + }, +}; + +static int __init alsa_card_sb8_init(void) { - int idx; + return isa_register_driver(&snd_sb8_driver, SNDRV_CARDS); +} - for (idx = 0; idx < SNDRV_CARDS; idx++) - snd_card_free(snd_sb8_cards[idx]); +static void __exit alsa_card_sb8_exit(void) +{ + isa_unregister_driver(&snd_sb8_driver); } module_init(alsa_card_sb8_init) diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 87c9b1ba06c..24d4121ab0e 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Uros Bizjak <uros@kss-loka.si> * * Routines for control of 8-bit SoundBlaster cards and clones @@ -30,15 +30,15 @@ * Cleaned up and rewrote lowlevel routines. */ -#include <sound/driver.h> #include <asm/io.h> #include <asm/dma.h> #include <linux/init.h> #include <linux/time.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/sb.h> -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Uros Bizjak <uros@kss-loka.si>"); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Uros Bizjak <uros@kss-loka.si>"); MODULE_DESCRIPTION("Routines for control of 8-bit SoundBlaster cards and clones"); MODULE_LICENSE("GPL"); @@ -46,19 +46,19 @@ MODULE_LICENSE("GPL"); #define SB8_DEN(v) ((SB8_CLOCK + (v) / 2) / (v)) #define SB8_RATE(v) (SB8_CLOCK / SB8_DEN(v)) -static ratnum_t clock = { +static struct snd_ratnum clock = { .num = SB8_CLOCK, .den_min = 1, .den_max = 256, .den_step = 1, }; -static snd_pcm_hw_constraint_ratnums_t hw_constraints_clock = { +static struct snd_pcm_hw_constraint_ratnums hw_constraints_clock = { .nrats = 1, .rats = &clock, }; -static ratnum_t stereo_clocks[] = { +static struct snd_ratnum stereo_clocks[] = { { .num = SB8_CLOCK, .den_min = SB8_DEN(22050), @@ -73,10 +73,10 @@ static ratnum_t stereo_clocks[] = { } }; -static int snd_sb8_hw_constraint_rate_channels(snd_pcm_hw_params_t *params, - snd_pcm_hw_rule_t *rule) +static int snd_sb8_hw_constraint_rate_channels(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) { - snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); if (c->min > 1) { unsigned int num = 0, den = 0; int err = snd_interval_ratnum(hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE), @@ -90,29 +90,43 @@ static int snd_sb8_hw_constraint_rate_channels(snd_pcm_hw_params_t *params, return 0; } -static int snd_sb8_hw_constraint_channels_rate(snd_pcm_hw_params_t *params, - snd_pcm_hw_rule_t *rule) +static int snd_sb8_hw_constraint_channels_rate(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) { - snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); if (r->min > SB8_RATE(22050) || r->max <= SB8_RATE(11025)) { - snd_interval_t t = { .min = 1, .max = 1 }; + struct snd_interval t = { .min = 1, .max = 1 }; return snd_interval_refine(hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS), &t); } return 0; } -static int snd_sb8_playback_prepare(snd_pcm_substream_t * substream) +static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_sb *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; unsigned int mixreg, rate, size, count; + unsigned char format; + unsigned char stereo = runtime->channels > 1; + int dma; rate = runtime->rate; switch (chip->hardware) { + case SB_HW_JAZZ16: + if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { + if (chip->mode & SB_MODE_CAPTURE_16) + return -EBUSY; + else + chip->mode |= SB_MODE_PLAYBACK_16; + } + chip->playback_format = SB_DSP_LO_OUTPUT_AUTO; + break; case SB_HW_PRO: if (runtime->channels > 1) { - snd_assert(rate == SB8_RATE(11025) || rate == SB8_RATE(22050), return -EINVAL); + if (snd_BUG_ON(rate != SB8_RATE(11025) && + rate != SB8_RATE(22050))) + return -EINVAL; chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; break; } @@ -132,11 +146,21 @@ static int snd_sb8_playback_prepare(snd_pcm_substream_t * substream) default: return -EINVAL; } + if (chip->mode & SB_MODE_PLAYBACK_16) { + format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT; + dma = chip->dma16; + } else { + format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT; + chip->mode |= SB_MODE_PLAYBACK_8; + dma = chip->dma8; + } size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); spin_lock_irqsave(&chip->reg_lock, flags); snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); - if (runtime->channels > 1) { + if (chip->hardware == SB_HW_JAZZ16) + snd_sbdsp_command(chip, format); + else if (stereo) { /* set playback stereo mode */ spin_lock(&chip->mixer_lock); mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); @@ -146,15 +170,14 @@ static int snd_sb8_playback_prepare(snd_pcm_substream_t * substream) /* Soundblaster hardware programming reference guide, 3-23 */ snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); runtime->dma_area[0] = 0x80; - snd_dma_program(chip->dma8, runtime->dma_addr, 1, DMA_MODE_WRITE); + snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE); /* force interrupt */ - chip->mode = SB_MODE_HALT; snd_sbdsp_command(chip, SB_DSP_OUTPUT); snd_sbdsp_command(chip, 0); snd_sbdsp_command(chip, 0); } snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); - if (runtime->channels > 1) { + if (stereo) { snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); spin_lock(&chip->mixer_lock); /* save output filter status and turn it off */ @@ -167,22 +190,24 @@ static int snd_sb8_playback_prepare(snd_pcm_substream_t * substream) snd_sbdsp_command(chip, 256 - runtime->rate_den); } if (chip->playback_format != SB_DSP_OUTPUT) { + if (chip->mode & SB_MODE_PLAYBACK_16) + count /= 2; count--; snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); snd_sbdsp_command(chip, count & 0xff); snd_sbdsp_command(chip, count >> 8); } spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_dma_program(chip->dma8, runtime->dma_addr, + snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); return 0; } -static int snd_sb8_playback_trigger(snd_pcm_substream_t * substream, +static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream, int cmd) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); unsigned int count; spin_lock_irqsave(&chip->reg_lock, flags); @@ -197,7 +222,7 @@ static int snd_sb8_playback_trigger(snd_pcm_substream_t * substream, break; case SNDRV_PCM_TRIGGER_STOP: if (chip->playback_format == SB_DSP_HI_OUTPUT_AUTO) { - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_pcm_runtime *runtime = substream->runtime; snd_sbdsp_reset(chip); if (runtime->channels > 1) { spin_lock(&chip->mixer_lock); @@ -211,34 +236,47 @@ static int snd_sb8_playback_trigger(snd_pcm_substream_t * substream, snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); } spin_unlock_irqrestore(&chip->reg_lock, flags); - chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_PLAYBACK_8 : SB_MODE_HALT; return 0; } -static int snd_sb8_hw_params(snd_pcm_substream_t * substream, - snd_pcm_hw_params_t * hw_params) +static int snd_sb8_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) { return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } -static int snd_sb8_hw_free(snd_pcm_substream_t * substream) +static int snd_sb8_hw_free(struct snd_pcm_substream *substream) { snd_pcm_lib_free_pages(substream); return 0; } -static int snd_sb8_capture_prepare(snd_pcm_substream_t * substream) +static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_sb *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; unsigned int mixreg, rate, size, count; + unsigned char format; + unsigned char stereo = runtime->channels > 1; + int dma; rate = runtime->rate; switch (chip->hardware) { + case SB_HW_JAZZ16: + if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { + if (chip->mode & SB_MODE_PLAYBACK_16) + return -EBUSY; + else + chip->mode |= SB_MODE_CAPTURE_16; + } + chip->capture_format = SB_DSP_LO_INPUT_AUTO; + break; case SB_HW_PRO: if (runtime->channels > 1) { - snd_assert(rate == SB8_RATE(11025) || rate == SB8_RATE(22050), return -EINVAL); + if (snd_BUG_ON(rate != SB8_RATE(11025) && + rate != SB8_RATE(22050))) + return -EINVAL; chip->capture_format = SB_DSP_HI_INPUT_AUTO; break; } @@ -259,14 +297,24 @@ static int snd_sb8_capture_prepare(snd_pcm_substream_t * substream) default: return -EINVAL; } + if (chip->mode & SB_MODE_CAPTURE_16) { + format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT; + dma = chip->dma16; + } else { + format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT; + chip->mode |= SB_MODE_CAPTURE_8; + dma = chip->dma8; + } size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); spin_lock_irqsave(&chip->reg_lock, flags); snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); - if (runtime->channels > 1) + if (chip->hardware == SB_HW_JAZZ16) + snd_sbdsp_command(chip, format); + else if (stereo) snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); - if (runtime->channels > 1) { + if (stereo) { snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); spin_lock(&chip->mixer_lock); /* save input filter status and turn it off */ @@ -278,23 +326,25 @@ static int snd_sb8_capture_prepare(snd_pcm_substream_t * substream) } else { snd_sbdsp_command(chip, 256 - runtime->rate_den); } - if (chip->capture_format != SB_DSP_OUTPUT) { + if (chip->capture_format != SB_DSP_INPUT) { + if (chip->mode & SB_MODE_PLAYBACK_16) + count /= 2; count--; snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); snd_sbdsp_command(chip, count & 0xff); snd_sbdsp_command(chip, count >> 8); } spin_unlock_irqrestore(&chip->reg_lock, flags); - snd_dma_program(chip->dma8, runtime->dma_addr, + snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); return 0; } -static int snd_sb8_capture_trigger(snd_pcm_substream_t * substream, +static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream, int cmd) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); unsigned int count; spin_lock_irqsave(&chip->reg_lock, flags); @@ -309,7 +359,7 @@ static int snd_sb8_capture_trigger(snd_pcm_substream_t * substream, break; case SNDRV_PCM_TRIGGER_STOP: if (chip->capture_format == SB_DSP_HI_INPUT_AUTO) { - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_pcm_runtime *runtime = substream->runtime; snd_sbdsp_reset(chip); if (runtime->channels > 1) { /* restore input filter status */ @@ -325,27 +375,31 @@ static int snd_sb8_capture_trigger(snd_pcm_substream_t * substream, snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); } spin_unlock_irqrestore(&chip->reg_lock, flags); - chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_CAPTURE_8 : SB_MODE_HALT; return 0; } -irqreturn_t snd_sb8dsp_interrupt(sb_t *chip) +irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip) { - snd_pcm_substream_t *substream; - snd_pcm_runtime_t *runtime; + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; -#if 0 - snd_printk("sb8: interrupt\n"); -#endif snd_sb_ack_8bit(chip); switch (chip->mode) { - case SB_MODE_PLAYBACK_8: /* ok.. playback is active */ + case SB_MODE_PLAYBACK_16: /* ok.. playback is active */ + if (chip->hardware != SB_HW_JAZZ16) + break; + /* fallthru */ + case SB_MODE_PLAYBACK_8: substream = chip->playback_substream; runtime = substream->runtime; if (chip->playback_format == SB_DSP_OUTPUT) snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START); snd_pcm_period_elapsed(substream); break; + case SB_MODE_CAPTURE_16: + if (chip->hardware != SB_HW_JAZZ16) + break; + /* fallthru */ case SB_MODE_CAPTURE_8: substream = chip->capture_substream; runtime = substream->runtime; @@ -357,25 +411,35 @@ irqreturn_t snd_sb8dsp_interrupt(sb_t *chip) return IRQ_HANDLED; } -static snd_pcm_uframes_t snd_sb8_playback_pointer(snd_pcm_substream_t * substream) +static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *substream) { - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); size_t ptr; + int dma; - if (chip->mode != SB_MODE_PLAYBACK_8) + if (chip->mode & SB_MODE_PLAYBACK_8) + dma = chip->dma8; + else if (chip->mode & SB_MODE_PLAYBACK_16) + dma = chip->dma16; + else return 0; - ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size); + ptr = snd_dma_pointer(dma, chip->p_dma_size); return bytes_to_frames(substream->runtime, ptr); } -static snd_pcm_uframes_t snd_sb8_capture_pointer(snd_pcm_substream_t * substream) +static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *substream) { - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); size_t ptr; + int dma; - if (chip->mode != SB_MODE_CAPTURE_8) + if (chip->mode & SB_MODE_CAPTURE_8) + dma = chip->dma8; + else if (chip->mode & SB_MODE_CAPTURE_16) + dma = chip->dma16; + else return 0; - ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size); + ptr = snd_dma_pointer(dma, chip->c_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -383,7 +447,7 @@ static snd_pcm_uframes_t snd_sb8_capture_pointer(snd_pcm_substream_t * substream */ -static snd_pcm_hardware_t snd_sb8_playback = +static struct snd_pcm_hardware snd_sb8_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -402,7 +466,7 @@ static snd_pcm_hardware_t snd_sb8_playback = .fifo_size = 0, }; -static snd_pcm_hardware_t snd_sb8_capture = +static struct snd_pcm_hardware snd_sb8_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -425,10 +489,10 @@ static snd_pcm_hardware_t snd_sb8_capture = * */ -static int snd_sb8_open(snd_pcm_substream_t *substream) +static int snd_sb8_open(struct snd_pcm_substream *substream) { - sb_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + struct snd_sb *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; unsigned long flags; spin_lock_irqsave(&chip->open_lock, flags); @@ -446,6 +510,14 @@ static int snd_sb8_open(snd_pcm_substream_t *substream) runtime->hw = snd_sb8_capture; } switch (chip->hardware) { + case SB_HW_JAZZ16: + if (chip->dma16 == 5 || chip->dma16 == 7) + runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE; + runtime->hw.rates |= SNDRV_PCM_RATE_8000_48000; + runtime->hw.rate_min = 4000; + runtime->hw.rate_max = 50000; + runtime->hw.channels_max = 2; + break; case SB_HW_PRO: runtime->hw.rate_max = 44100; runtime->hw.channels_max = 2; @@ -468,18 +540,30 @@ static int snd_sb8_open(snd_pcm_substream_t *substream) } snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_clock); + if (chip->dma8 > 3 || chip->dma16 >= 0) { + snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 2); + snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 2); + runtime->hw.buffer_bytes_max = 128 * 1024 * 1024; + runtime->hw.period_bytes_max = 128 * 1024 * 1024; + } return 0; } -static int snd_sb8_close(snd_pcm_substream_t *substream) +static int snd_sb8_close(struct snd_pcm_substream *substream) { unsigned long flags; - sb_t *chip = snd_pcm_substream_chip(substream); + struct snd_sb *chip = snd_pcm_substream_chip(substream); chip->playback_substream = NULL; chip->capture_substream = NULL; spin_lock_irqsave(&chip->open_lock, flags); chip->open &= ~SB_OPEN_PCM; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + chip->mode &= ~SB_MODE_PLAYBACK; + else + chip->mode &= ~SB_MODE_CAPTURE; spin_unlock_irqrestore(&chip->open_lock, flags); return 0; } @@ -488,7 +572,7 @@ static int snd_sb8_close(snd_pcm_substream_t *substream) * Initialization part */ -static snd_pcm_ops_t snd_sb8_playback_ops = { +static struct snd_pcm_ops snd_sb8_playback_ops = { .open = snd_sb8_open, .close = snd_sb8_close, .ioctl = snd_pcm_lib_ioctl, @@ -499,7 +583,7 @@ static snd_pcm_ops_t snd_sb8_playback_ops = { .pointer = snd_sb8_playback_pointer, }; -static snd_pcm_ops_t snd_sb8_capture_ops = { +static struct snd_pcm_ops snd_sb8_capture_ops = { .open = snd_sb8_open, .close = snd_sb8_close, .ioctl = snd_pcm_lib_ioctl, @@ -510,16 +594,12 @@ static snd_pcm_ops_t snd_sb8_capture_ops = { .pointer = snd_sb8_capture_pointer, }; -static void snd_sb8dsp_pcm_free(snd_pcm_t *pcm) -{ - snd_pcm_lib_preallocate_free_for_all(pcm); -} - -int snd_sb8dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm) +int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm) { - snd_card_t *card = chip->card; - snd_pcm_t *pcm; + struct snd_card *card = chip->card; + struct snd_pcm *pcm; int err; + size_t max_prealloc = 64 * 1024; if (rpcm) *rpcm = NULL; @@ -528,14 +608,15 @@ int snd_sb8dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm) sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff); pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; pcm->private_data = chip; - pcm->private_free = snd_sb8dsp_pcm_free; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops); + if (chip->dma8 > 3 || chip->dma16 >= 0) + max_prealloc = 128 * 1024; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_isa_data(), - 64*1024, 64*1024); + 64*1024, max_prealloc); if (rpcm) *rpcm = pcm; diff --git a/sound/isa/sb/sb8_midi.c b/sound/isa/sb/sb8_midi.c index d2c633a40e7..988a8b73475 100644 --- a/sound/isa/sb/sb8_midi.c +++ b/sound/isa/sb/sb8_midi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Routines for control of SoundBlaster cards - MIDI interface * * This program is free software; you can redistribute it and/or modify @@ -26,26 +26,27 @@ * Added full duplex UART mode for DSP version 2.0 and later. */ -#include <sound/driver.h> #include <asm/io.h> #include <linux/time.h> #include <sound/core.h> #include <sound/sb.h> -/* - - */ -irqreturn_t snd_sb8dsp_midi_interrupt(sb_t * chip) +irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb *chip) { - snd_rawmidi_t *rmidi; + struct snd_rawmidi *rmidi; int max = 64; char byte; - if (chip == NULL || (rmidi = chip->rmidi) == NULL) { + if (!chip) + return IRQ_NONE; + + rmidi = chip->rmidi; + if (!rmidi) { inb(SBP(chip, DATA_AVAIL)); /* ack interrupt */ return IRQ_NONE; } + spin_lock(&chip->midi_input_lock); while (max-- > 0) { if (inb(SBP(chip, DATA_AVAIL)) & 0x80) { @@ -59,14 +60,10 @@ irqreturn_t snd_sb8dsp_midi_interrupt(sb_t * chip) return IRQ_HANDLED; } -/* - - */ - -static int snd_sb8dsp_midi_input_open(snd_rawmidi_substream_t * substream) +static int snd_sb8dsp_midi_input_open(struct snd_rawmidi_substream *substream) { unsigned long flags; - sb_t *chip; + struct snd_sb *chip; unsigned int valid_open_flags; chip = substream->rmidi->private_data; @@ -90,10 +87,10 @@ static int snd_sb8dsp_midi_input_open(snd_rawmidi_substream_t * substream) return 0; } -static int snd_sb8dsp_midi_output_open(snd_rawmidi_substream_t * substream) +static int snd_sb8dsp_midi_output_open(struct snd_rawmidi_substream *substream) { unsigned long flags; - sb_t *chip; + struct snd_sb *chip; unsigned int valid_open_flags; chip = substream->rmidi->private_data; @@ -117,10 +114,10 @@ static int snd_sb8dsp_midi_output_open(snd_rawmidi_substream_t * substream) return 0; } -static int snd_sb8dsp_midi_input_close(snd_rawmidi_substream_t * substream) +static int snd_sb8dsp_midi_input_close(struct snd_rawmidi_substream *substream) { unsigned long flags; - sb_t *chip; + struct snd_sb *chip; chip = substream->rmidi->private_data; spin_lock_irqsave(&chip->open_lock, flags); @@ -135,10 +132,10 @@ static int snd_sb8dsp_midi_input_close(snd_rawmidi_substream_t * substream) return 0; } -static int snd_sb8dsp_midi_output_close(snd_rawmidi_substream_t * substream) +static int snd_sb8dsp_midi_output_close(struct snd_rawmidi_substream *substream) { unsigned long flags; - sb_t *chip; + struct snd_sb *chip; chip = substream->rmidi->private_data; spin_lock_irqsave(&chip->open_lock, flags); @@ -153,10 +150,10 @@ static int snd_sb8dsp_midi_output_close(snd_rawmidi_substream_t * substream) return 0; } -static void snd_sb8dsp_midi_input_trigger(snd_rawmidi_substream_t * substream, int up) +static void snd_sb8dsp_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; - sb_t *chip; + struct snd_sb *chip; chip = substream->rmidi->private_data; spin_lock_irqsave(&chip->open_lock, flags); @@ -176,10 +173,10 @@ static void snd_sb8dsp_midi_input_trigger(snd_rawmidi_substream_t * substream, i spin_unlock_irqrestore(&chip->open_lock, flags); } -static void snd_sb8dsp_midi_output_write(snd_rawmidi_substream_t * substream) +static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream) { unsigned long flags; - sb_t *chip; + struct snd_sb *chip; char byte; int max = 32; @@ -214,8 +211,8 @@ static void snd_sb8dsp_midi_output_write(snd_rawmidi_substream_t * substream) static void snd_sb8dsp_midi_output_timer(unsigned long data) { - snd_rawmidi_substream_t * substream = (snd_rawmidi_substream_t *) data; - sb_t * chip = substream->rmidi->private_data; + struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *) data; + struct snd_sb * chip = substream->rmidi->private_data; unsigned long flags; spin_lock_irqsave(&chip->open_lock, flags); @@ -225,10 +222,10 @@ static void snd_sb8dsp_midi_output_timer(unsigned long data) snd_sb8dsp_midi_output_write(substream); } -static void snd_sb8dsp_midi_output_trigger(snd_rawmidi_substream_t * substream, int up) +static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; - sb_t *chip; + struct snd_sb *chip; chip = substream->rmidi->private_data; spin_lock_irqsave(&chip->open_lock, flags); @@ -252,27 +249,23 @@ static void snd_sb8dsp_midi_output_trigger(snd_rawmidi_substream_t * substream, snd_sb8dsp_midi_output_write(substream); } -/* - - */ - -static snd_rawmidi_ops_t snd_sb8dsp_midi_output = +static struct snd_rawmidi_ops snd_sb8dsp_midi_output = { .open = snd_sb8dsp_midi_output_open, .close = snd_sb8dsp_midi_output_close, .trigger = snd_sb8dsp_midi_output_trigger, }; -static snd_rawmidi_ops_t snd_sb8dsp_midi_input = +static struct snd_rawmidi_ops snd_sb8dsp_midi_input = { .open = snd_sb8dsp_midi_input_open, .close = snd_sb8dsp_midi_input_close, .trigger = snd_sb8dsp_midi_input_trigger, }; -int snd_sb8dsp_midi(sb_t *chip, int device, snd_rawmidi_t ** rrawmidi) +int snd_sb8dsp_midi(struct snd_sb *chip, int device, struct snd_rawmidi ** rrawmidi) { - snd_rawmidi_t *rmidi; + struct snd_rawmidi *rmidi; int err; if (rrawmidi) diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c index 5b6bde213ea..3ef990602cd 100644 --- a/sound/isa/sb/sb_common.c +++ b/sound/isa/sb/sb_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Uros Bizjak <uros@kss-loka.si> * * Lowlevel routines for control of Sound Blaster cards @@ -20,12 +20,12 @@ * */ -#include <sound/driver.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/ioport.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/sb.h> #include <sound/initval.h> @@ -33,7 +33,7 @@ #include <asm/io.h> #include <asm/dma.h> -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("ALSA lowlevel driver for Sound Blaster cards"); MODULE_LICENSE("GPL"); @@ -41,22 +41,22 @@ MODULE_LICENSE("GPL"); #undef IO_DEBUG -int snd_sbdsp_command(sb_t *chip, unsigned char val) +int snd_sbdsp_command(struct snd_sb *chip, unsigned char val) { int i; #ifdef IO_DEBUG - snd_printk("command 0x%x\n", val); + snd_printk(KERN_DEBUG "command 0x%x\n", val); #endif for (i = BUSY_LOOPS; i; i--) if ((inb(SBP(chip, STATUS)) & 0x80) == 0) { outb(val, SBP(chip, COMMAND)); return 1; } - snd_printd("%s [0x%lx]: timeout (0x%x)\n", __FUNCTION__, chip->port, val); + snd_printd("%s [0x%lx]: timeout (0x%x)\n", __func__, chip->port, val); return 0; } -int snd_sbdsp_get_byte(sb_t *chip) +int snd_sbdsp_get_byte(struct snd_sb *chip) { int val; int i; @@ -64,16 +64,16 @@ int snd_sbdsp_get_byte(sb_t *chip) if (inb(SBP(chip, DATA_AVAIL)) & 0x80) { val = inb(SBP(chip, READ)); #ifdef IO_DEBUG - snd_printk("get_byte 0x%x\n", val); + snd_printk(KERN_DEBUG "get_byte 0x%x\n", val); #endif return val; } } - snd_printd("%s [0x%lx]: timeout\n", __FUNCTION__, chip->port); + snd_printd("%s [0x%lx]: timeout\n", __func__, chip->port); return -ENODEV; } -int snd_sbdsp_reset(sb_t *chip) +int snd_sbdsp_reset(struct snd_sb *chip) { int i; @@ -88,11 +88,11 @@ int snd_sbdsp_reset(sb_t *chip) else break; } - snd_printdd("%s [0x%lx] failed...\n", __FUNCTION__, chip->port); + snd_printdd("%s [0x%lx] failed...\n", __func__, chip->port); return -ENODEV; } -static int snd_sbdsp_version(sb_t * chip) +static int snd_sbdsp_version(struct snd_sb * chip) { unsigned int result = -ENODEV; @@ -102,7 +102,7 @@ static int snd_sbdsp_version(sb_t * chip) return result; } -static int snd_sbdsp_probe(sb_t * chip) +static int snd_sbdsp_probe(struct snd_sb * chip) { int version; int major, minor; @@ -128,7 +128,7 @@ static int snd_sbdsp_probe(sb_t * chip) minor = version & 0xff; snd_printdd("SB [0x%lx]: DSP chip found, version = %i.%i\n", chip->port, major, minor); - + switch (chip->hardware) { case SB_HW_AUTO: switch (major) { @@ -154,7 +154,7 @@ static int snd_sbdsp_probe(sb_t * chip) str = "16"; break; default: - snd_printk("SB [0x%lx]: unknown DSP chip version %i.%i\n", + snd_printk(KERN_INFO "SB [0x%lx]: unknown DSP chip version %i.%i\n", chip->port, major, minor); return -ENODEV; } @@ -168,6 +168,12 @@ static int snd_sbdsp_probe(sb_t * chip) case SB_HW_DT019X: str = "(DT019X/ALS007)"; break; + case SB_HW_CS5530: + str = "16 (CS5530)"; + break; + case SB_HW_JAZZ16: + str = "Pro (Jazz16)"; + break; default: return -ENODEV; } @@ -176,12 +182,10 @@ static int snd_sbdsp_probe(sb_t * chip) return 0; } -static int snd_sbdsp_free(sb_t *chip) +static int snd_sbdsp_free(struct snd_sb *chip) { - if (chip->res_port) { - release_resource(chip->res_port); - kfree_nocheck(chip->res_port); - } + if (chip->res_port) + release_and_free_resource(chip->res_port); if (chip->irq >= 0) free_irq(chip->irq, (void *) chip); #ifdef CONFIG_ISA @@ -198,30 +202,31 @@ static int snd_sbdsp_free(sb_t *chip) return 0; } -static int snd_sbdsp_dev_free(snd_device_t *device) +static int snd_sbdsp_dev_free(struct snd_device *device) { - sb_t *chip = device->device_data; + struct snd_sb *chip = device->device_data; return snd_sbdsp_free(chip); } -int snd_sbdsp_create(snd_card_t *card, +int snd_sbdsp_create(struct snd_card *card, unsigned long port, int irq, - irqreturn_t (*irq_handler)(int, void *, struct pt_regs *), + irq_handler_t irq_handler, int dma8, int dma16, unsigned short hardware, - sb_t **r_chip) + struct snd_sb **r_chip) { - sb_t *chip; + struct snd_sb *chip; int err; - static snd_device_ops_t ops = { + static struct snd_device_ops ops = { .dev_free = snd_sbdsp_dev_free, }; - snd_assert(r_chip != NULL, return -EINVAL); + if (snd_BUG_ON(!r_chip)) + return -EINVAL; *r_chip = NULL; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; spin_lock_init(&chip->reg_lock); @@ -233,8 +238,10 @@ int snd_sbdsp_create(snd_card_t *card, chip->dma16 = -1; chip->port = port; - if (request_irq(irq, irq_handler, hardware == SB_HW_ALS4000 ? - SA_INTERRUPT | SA_SHIRQ : SA_INTERRUPT, + if (request_irq(irq, irq_handler, + (hardware == SB_HW_ALS4000 || + hardware == SB_HW_CS5530) ? + IRQF_SHARED : 0, "SoundBlaster", (void *) chip)) { snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq); snd_sbdsp_free(chip); @@ -295,6 +302,10 @@ EXPORT_SYMBOL(snd_sbmixer_write); EXPORT_SYMBOL(snd_sbmixer_read); EXPORT_SYMBOL(snd_sbmixer_new); EXPORT_SYMBOL(snd_sbmixer_add_ctl); +#ifdef CONFIG_PM +EXPORT_SYMBOL(snd_sbmixer_suspend); +EXPORT_SYMBOL(snd_sbmixer_resume); +#endif /* * INIT part diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index ff4b5996802..1ff78ec9f0a 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Routines for Sound Blaster mixer control * * @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <asm/io.h> #include <linux/delay.h> #include <linux/time.h> @@ -29,18 +28,18 @@ #undef IO_DEBUG -void snd_sbmixer_write(sb_t *chip, unsigned char reg, unsigned char data) +void snd_sbmixer_write(struct snd_sb *chip, unsigned char reg, unsigned char data) { outb(reg, SBP(chip, MIXER_ADDR)); udelay(10); outb(data, SBP(chip, MIXER_DATA)); udelay(10); #ifdef IO_DEBUG - snd_printk("mixer_write 0x%x 0x%x\n", reg, data); + snd_printk(KERN_DEBUG "mixer_write 0x%x 0x%x\n", reg, data); #endif } -unsigned char snd_sbmixer_read(sb_t *chip, unsigned char reg) +unsigned char snd_sbmixer_read(struct snd_sb *chip, unsigned char reg) { unsigned char result; @@ -49,7 +48,7 @@ unsigned char snd_sbmixer_read(sb_t *chip, unsigned char reg) result = inb(SBP(chip, MIXER_DATA)); udelay(10); #ifdef IO_DEBUG - snd_printk("mixer_read 0x%x 0x%x\n", reg, result); + snd_printk(KERN_DEBUG "mixer_read 0x%x 0x%x\n", reg, result); #endif return result; } @@ -58,7 +57,7 @@ unsigned char snd_sbmixer_read(sb_t *chip, unsigned char reg) * Single channel mixer element */ -static int snd_sbmixer_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int snd_sbmixer_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { int mask = (kcontrol->private_value >> 24) & 0xff; @@ -69,9 +68,9 @@ static int snd_sbmixer_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t return 0; } -static int snd_sbmixer_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *sb = snd_kcontrol_chip(kcontrol); + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 16) & 0xff; @@ -85,9 +84,9 @@ static int snd_sbmixer_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ return 0; } -static int snd_sbmixer_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sbmixer_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *sb = snd_kcontrol_chip(kcontrol); + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift = (kcontrol->private_value >> 16) & 0x07; @@ -110,7 +109,7 @@ static int snd_sbmixer_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ * Double channel mixer element */ -static int snd_sbmixer_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int snd_sbmixer_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { int mask = (kcontrol->private_value >> 24) & 0xff; @@ -121,9 +120,9 @@ static int snd_sbmixer_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t return 0; } -static int snd_sbmixer_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sbmixer_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *sb = snd_kcontrol_chip(kcontrol); + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; @@ -141,9 +140,9 @@ static int snd_sbmixer_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ return 0; } -static int snd_sbmixer_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *sb = snd_kcontrol_chip(kcontrol); + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; @@ -181,9 +180,9 @@ static int snd_sbmixer_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ * DT-019x / ALS-007 capture/input switch */ -static int snd_dt019x_input_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[5] = { + static const char *texts[5] = { "CD", "Mic", "Line", "Synth", "Master" }; @@ -196,9 +195,9 @@ static int snd_dt019x_input_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_ return 0; } -static int snd_dt019x_input_sw_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_dt019x_input_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *sb = snd_kcontrol_chip(kcontrol); + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); unsigned long flags; unsigned char oval; @@ -232,9 +231,9 @@ static int snd_dt019x_input_sw_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value return 0; } -static int snd_dt019x_input_sw_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *sb = snd_kcontrol_chip(kcontrol); + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned char nval, oval; @@ -270,12 +269,73 @@ static int snd_dt019x_input_sw_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value } /* + * ALS4000 mono recording control switch + */ + +static int snd_als4k_mono_capture_route_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static const char *texts[3] = { + "L chan only", "R chan only", "L ch/2 + R ch/2" + }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 3; + if (uinfo->value.enumerated.item > 2) + uinfo->value.enumerated.item = 2; + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + return 0; +} + +static int snd_als4k_mono_capture_route_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); + unsigned long flags; + unsigned char oval; + + spin_lock_irqsave(&sb->mixer_lock, flags); + oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL); + spin_unlock_irqrestore(&sb->mixer_lock, flags); + oval >>= 6; + if (oval > 2) + oval = 2; + + ucontrol->value.enumerated.item[0] = oval; + return 0; +} + +static int snd_als4k_mono_capture_route_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int change; + unsigned char nval, oval; + + if (ucontrol->value.enumerated.item[0] > 2) + return -EINVAL; + spin_lock_irqsave(&sb->mixer_lock, flags); + oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL); + + nval = (oval & ~(3 << 6)) + | (ucontrol->value.enumerated.item[0] << 6); + change = nval != oval; + if (change) + snd_sbmixer_write(sb, SB_ALS4000_MONO_IO_CTRL, nval); + spin_unlock_irqrestore(&sb->mixer_lock, flags); + return change; +} + +/* * SBPRO input multiplexer */ -static int snd_sb8mixer_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[3] = { + static const char *texts[3] = { "Mic", "CD", "Line" }; @@ -289,9 +349,9 @@ static int snd_sb8mixer_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * } -static int snd_sb8mixer_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sb8mixer_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *sb = snd_kcontrol_chip(kcontrol); + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); unsigned long flags; unsigned char oval; @@ -312,9 +372,9 @@ static int snd_sb8mixer_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t return 0; } -static int snd_sb8mixer_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sb8mixer_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *sb = snd_kcontrol_chip(kcontrol); + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned char nval, oval; @@ -346,7 +406,7 @@ static int snd_sb8mixer_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * SB16 input switch */ -static int snd_sb16mixer_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) +static int snd_sb16mixer_info_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 4; @@ -355,9 +415,9 @@ static int snd_sb16mixer_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_i return 0; } -static int snd_sb16mixer_get_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sb16mixer_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *sb = snd_kcontrol_chip(kcontrol); + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg1 = kcontrol->private_value & 0xff; int reg2 = (kcontrol->private_value >> 8) & 0xff; @@ -376,9 +436,9 @@ static int snd_sb16mixer_get_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_va return 0; } -static int snd_sb16mixer_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_sb16mixer_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - sb_t *sb = snd_kcontrol_chip(kcontrol); + struct snd_sb *sb = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg1 = kcontrol->private_value & 0xff; int reg2 = (kcontrol->private_value >> 8) & 0xff; @@ -410,9 +470,9 @@ static int snd_sb16mixer_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_va */ /* */ -int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsigned long value) +int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int type, unsigned long value) { - static snd_kcontrol_new_t newctls[] = { + static struct snd_kcontrol_new newctls[] = { [SB_MIX_SINGLE] = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .info = snd_sbmixer_info_single, @@ -443,8 +503,14 @@ int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsig .get = snd_dt019x_input_sw_get, .put = snd_dt019x_input_sw_put, }, + [SB_MIX_MONO_CAPTURE_ALS4K] = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_als4k_mono_capture_route_info, + .get = snd_als4k_mono_capture_route_get, + .put = snd_als4k_mono_capture_route_put, + }, }; - snd_kcontrol_t *ctl; + struct snd_kcontrol *ctl; int err; ctl = snd_ctl_new1(&newctls[type], chip); @@ -453,10 +519,8 @@ int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsig strlcpy(ctl->id.name, name, sizeof(ctl->id.name)); ctl->id.index = index; ctl->private_value = value; - if ((err = snd_ctl_add(chip->card, ctl)) < 0) { - snd_ctl_free_one(ctl); + if ((err = snd_ctl_add(chip->card, ctl)) < 0) return err; - } return 0; } @@ -464,20 +528,11 @@ int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsig * SB 2.0 specific mixer elements */ -static struct sbmix_elem snd_sb20_ctl_master_play_vol = - SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7); -static struct sbmix_elem snd_sb20_ctl_pcm_play_vol = - SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3); -static struct sbmix_elem snd_sb20_ctl_synth_play_vol = - SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7); -static struct sbmix_elem snd_sb20_ctl_cd_play_vol = - SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7); - -static struct sbmix_elem *snd_sb20_controls[] = { - &snd_sb20_ctl_master_play_vol, - &snd_sb20_ctl_pcm_play_vol, - &snd_sb20_ctl_synth_play_vol, - &snd_sb20_ctl_cd_play_vol +static struct sbmix_elem snd_sb20_controls[] = { + SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7), + SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3), + SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7), + SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7) }; static unsigned char snd_sb20_init_values[][2] = { @@ -488,41 +543,24 @@ static unsigned char snd_sb20_init_values[][2] = { /* * SB Pro specific mixer elements */ -static struct sbmix_elem snd_sbpro_ctl_master_play_vol = - SB_DOUBLE("Master Playback Volume", SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7); -static struct sbmix_elem snd_sbpro_ctl_pcm_play_vol = - SB_DOUBLE("PCM Playback Volume", SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7); -static struct sbmix_elem snd_sbpro_ctl_pcm_play_filter = - SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1); -static struct sbmix_elem snd_sbpro_ctl_synth_play_vol = - SB_DOUBLE("Synth Playback Volume", SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7); -static struct sbmix_elem snd_sbpro_ctl_cd_play_vol = - SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7); -static struct sbmix_elem snd_sbpro_ctl_line_play_vol = - SB_DOUBLE("Line Playback Volume", SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7); -static struct sbmix_elem snd_sbpro_ctl_mic_play_vol = - SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3); -static struct sbmix_elem snd_sbpro_ctl_capture_source = +static struct sbmix_elem snd_sbpro_controls[] = { + SB_DOUBLE("Master Playback Volume", + SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7), + SB_DOUBLE("PCM Playback Volume", + SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7), + SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1), + SB_DOUBLE("Synth Playback Volume", + SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7), + SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7), + SB_DOUBLE("Line Playback Volume", + SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7), + SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3), { .name = "Capture Source", .type = SB_MIX_CAPTURE_PRO - }; -static struct sbmix_elem snd_sbpro_ctl_capture_filter = - SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1); -static struct sbmix_elem snd_sbpro_ctl_capture_low_filter = - SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1); - -static struct sbmix_elem *snd_sbpro_controls[] = { - &snd_sbpro_ctl_master_play_vol, - &snd_sbpro_ctl_pcm_play_vol, - &snd_sbpro_ctl_pcm_play_filter, - &snd_sbpro_ctl_synth_play_vol, - &snd_sbpro_ctl_cd_play_vol, - &snd_sbpro_ctl_line_play_vol, - &snd_sbpro_ctl_mic_play_vol, - &snd_sbpro_ctl_capture_source, - &snd_sbpro_ctl_capture_filter, - &snd_sbpro_ctl_capture_low_filter + }, + SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1), + SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1) }; static unsigned char snd_sbpro_init_values[][2] = { @@ -534,68 +572,42 @@ static unsigned char snd_sbpro_init_values[][2] = { /* * SB16 specific mixer elements */ -static struct sbmix_elem snd_sb16_ctl_master_play_vol = - SB_DOUBLE("Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31); -static struct sbmix_elem snd_sb16_ctl_3d_enhance_switch = - SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1); -static struct sbmix_elem snd_sb16_ctl_tone_bass = - SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15); -static struct sbmix_elem snd_sb16_ctl_tone_treble = - SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15); -static struct sbmix_elem snd_sb16_ctl_pcm_play_vol = - SB_DOUBLE("PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31); -static struct sbmix_elem snd_sb16_ctl_synth_capture_route = - SB16_INPUT_SW("Synth Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5); -static struct sbmix_elem snd_sb16_ctl_synth_play_vol = - SB_DOUBLE("Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31); -static struct sbmix_elem snd_sb16_ctl_cd_capture_route = - SB16_INPUT_SW("CD Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1); -static struct sbmix_elem snd_sb16_ctl_cd_play_switch = - SB_DOUBLE("CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1); -static struct sbmix_elem snd_sb16_ctl_cd_play_vol = - SB_DOUBLE("CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31); -static struct sbmix_elem snd_sb16_ctl_line_capture_route = - SB16_INPUT_SW("Line Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3); -static struct sbmix_elem snd_sb16_ctl_line_play_switch = - SB_DOUBLE("Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1); -static struct sbmix_elem snd_sb16_ctl_line_play_vol = - SB_DOUBLE("Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31); -static struct sbmix_elem snd_sb16_ctl_mic_capture_route = - SB16_INPUT_SW("Mic Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0); -static struct sbmix_elem snd_sb16_ctl_mic_play_switch = - SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1); -static struct sbmix_elem snd_sb16_ctl_mic_play_vol = - SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31); -static struct sbmix_elem snd_sb16_ctl_pc_speaker_vol = - SB_SINGLE("PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3); -static struct sbmix_elem snd_sb16_ctl_capture_vol = - SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3); -static struct sbmix_elem snd_sb16_ctl_play_vol = - SB_DOUBLE("Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3); -static struct sbmix_elem snd_sb16_ctl_auto_mic_gain = - SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1); - -static struct sbmix_elem *snd_sb16_controls[] = { - &snd_sb16_ctl_master_play_vol, - &snd_sb16_ctl_3d_enhance_switch, - &snd_sb16_ctl_tone_bass, - &snd_sb16_ctl_tone_treble, - &snd_sb16_ctl_pcm_play_vol, - &snd_sb16_ctl_synth_capture_route, - &snd_sb16_ctl_synth_play_vol, - &snd_sb16_ctl_cd_capture_route, - &snd_sb16_ctl_cd_play_switch, - &snd_sb16_ctl_cd_play_vol, - &snd_sb16_ctl_line_capture_route, - &snd_sb16_ctl_line_play_switch, - &snd_sb16_ctl_line_play_vol, - &snd_sb16_ctl_mic_capture_route, - &snd_sb16_ctl_mic_play_switch, - &snd_sb16_ctl_mic_play_vol, - &snd_sb16_ctl_pc_speaker_vol, - &snd_sb16_ctl_capture_vol, - &snd_sb16_ctl_play_vol, - &snd_sb16_ctl_auto_mic_gain +static struct sbmix_elem snd_sb16_controls[] = { + SB_DOUBLE("Master Playback Volume", + SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31), + SB_DOUBLE("PCM Playback Volume", + SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31), + SB16_INPUT_SW("Synth Capture Route", + SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5), + SB_DOUBLE("Synth Playback Volume", + SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31), + SB16_INPUT_SW("CD Capture Route", + SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1), + SB_DOUBLE("CD Playback Switch", + SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1), + SB_DOUBLE("CD Playback Volume", + SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31), + SB16_INPUT_SW("Mic Capture Route", + SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0), + SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1), + SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31), + SB_SINGLE("Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3), + SB_DOUBLE("Capture Volume", + SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3), + SB_DOUBLE("Playback Volume", + SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3), + SB16_INPUT_SW("Line Capture Route", + SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3), + SB_DOUBLE("Line Playback Switch", + SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1), + SB_DOUBLE("Line Playback Volume", + SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31), + SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1), + SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1), + SB_DOUBLE("Tone Control - Bass", + SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15), + SB_DOUBLE("Tone Control - Treble", + SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15) }; static unsigned char snd_sb16_init_values[][2] = { @@ -614,44 +626,34 @@ static unsigned char snd_sb16_init_values[][2] = { /* * DT019x specific mixer elements */ -static struct sbmix_elem snd_dt019x_ctl_master_play_vol = - SB_DOUBLE("Master Playback Volume", SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4,0, 15); -static struct sbmix_elem snd_dt019x_ctl_pcm_play_vol = - SB_DOUBLE("PCM Playback Volume", SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4,0, 15); -static struct sbmix_elem snd_dt019x_ctl_synth_play_vol = - SB_DOUBLE("Synth Playback Volume", SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4,0, 15); -static struct sbmix_elem snd_dt019x_ctl_cd_play_vol = - SB_DOUBLE("CD Playback Volume", SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4,0, 15); -static struct sbmix_elem snd_dt019x_ctl_mic_play_vol = - SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7); -static struct sbmix_elem snd_dt019x_ctl_pc_speaker_vol = - SB_SINGLE("PC Speaker Volume", SB_DT019X_SPKR_DEV, 0, 7); -static struct sbmix_elem snd_dt019x_ctl_line_play_vol = - SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0, 15); -static struct sbmix_elem snd_dt019x_ctl_pcm_play_switch = - SB_DOUBLE("PCM Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2,1, 1); -static struct sbmix_elem snd_dt019x_ctl_synth_play_switch = - SB_DOUBLE("Synth Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4,3, 1); -static struct sbmix_elem snd_dt019x_ctl_capture_source = +static struct sbmix_elem snd_dt019x_controls[] = { + /* ALS4000 below has some parts which we might be lacking, + * e.g. snd_als4000_ctl_mono_playback_switch - check it! */ + SB_DOUBLE("Master Playback Volume", + SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4, 0, 15), + SB_DOUBLE("PCM Playback Switch", + SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1), + SB_DOUBLE("PCM Playback Volume", + SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4, 0, 15), + SB_DOUBLE("Synth Playback Switch", + SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1), + SB_DOUBLE("Synth Playback Volume", + SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4, 0, 15), + SB_DOUBLE("CD Playback Switch", + SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1), + SB_DOUBLE("CD Playback Volume", + SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4, 0, 15), + SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1), + SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7), + SB_SINGLE("Beep Volume", SB_DT019X_SPKR_DEV, 0, 7), + SB_DOUBLE("Line Playback Switch", + SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1), + SB_DOUBLE("Line Playback Volume", + SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4, 0, 15), { .name = "Capture Source", .type = SB_MIX_CAPTURE_DT019X - }; - -static struct sbmix_elem *snd_dt019x_controls[] = { - &snd_dt019x_ctl_master_play_vol, - &snd_dt019x_ctl_pcm_play_vol, - &snd_dt019x_ctl_synth_play_vol, - &snd_dt019x_ctl_cd_play_vol, - &snd_dt019x_ctl_mic_play_vol, - &snd_dt019x_ctl_pc_speaker_vol, - &snd_dt019x_ctl_line_play_vol, - &snd_sb16_ctl_mic_play_switch, - &snd_sb16_ctl_cd_play_switch, - &snd_sb16_ctl_line_play_switch, - &snd_dt019x_ctl_pcm_play_switch, - &snd_dt019x_ctl_synth_play_switch, - &snd_dt019x_ctl_capture_source + } }; static unsigned char snd_dt019x_init_values[][2] = { @@ -669,63 +671,37 @@ static unsigned char snd_dt019x_init_values[][2] = { /* * ALS4000 specific mixer elements */ -/* FIXME: SB_ALS4000_MONO_IO_CTRL needs output select ctrl ! */ -static struct sbmix_elem snd_als4000_ctl_mono_output_switch = - SB_SINGLE("Mono Output Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1); -/* FIXME: mono input switch also available on DT019X ? */ -static struct sbmix_elem snd_als4000_ctl_mono_input_switch = - SB_SINGLE("Mono Input Switch", SB_DT019X_OUTPUT_SW2, 0, 1); -static struct sbmix_elem snd_als4000_ctl_mic_20db_boost = - SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03); -static struct sbmix_elem snd_als4000_ctl_mixer_out_to_in = - SB_SINGLE("Mixer Out To In", SB_ALS4000_MIC_IN_GAIN, 7, 0x01); -/* FIXME: 3D needs much more sophisticated controls, many more features ! */ -static struct sbmix_elem snd_als4000_ctl_3d_output_switch = - SB_SINGLE("3D Output Switch", SB_ALS4000_3D_SND_FX, 6, 0x01); -static struct sbmix_elem snd_als4000_ctl_3d_output_ratio = - SB_SINGLE("3D Output Ratio", SB_ALS4000_3D_SND_FX, 0, 0x07); -static struct sbmix_elem snd_als4000_ctl_3d_poweroff_switch = - SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01); -static struct sbmix_elem snd_als4000_ctl_3d_delay = - SB_SINGLE("3D Delay", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f); -#ifdef NOT_AVAILABLE -static struct sbmix_elem snd_als4000_ctl_fmdac = - SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01); -static struct sbmix_elem snd_als4000_ctl_qsound = - SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f); -#endif - -static struct sbmix_elem *snd_als4000_controls[] = { - &snd_sb16_ctl_master_play_vol, - &snd_dt019x_ctl_pcm_play_switch, - &snd_sb16_ctl_pcm_play_vol, - &snd_sb16_ctl_synth_capture_route, - &snd_dt019x_ctl_synth_play_switch, - &snd_sb16_ctl_synth_play_vol, - &snd_sb16_ctl_cd_capture_route, - &snd_sb16_ctl_cd_play_switch, - &snd_sb16_ctl_cd_play_vol, - &snd_sb16_ctl_line_capture_route, - &snd_sb16_ctl_line_play_switch, - &snd_sb16_ctl_line_play_vol, - &snd_sb16_ctl_mic_capture_route, - &snd_als4000_ctl_mic_20db_boost, - &snd_sb16_ctl_auto_mic_gain, - &snd_sb16_ctl_mic_play_switch, - &snd_sb16_ctl_mic_play_vol, - &snd_sb16_ctl_pc_speaker_vol, - &snd_sb16_ctl_capture_vol, - &snd_sb16_ctl_play_vol, - &snd_als4000_ctl_mono_output_switch, - &snd_als4000_ctl_mono_input_switch, - &snd_als4000_ctl_mixer_out_to_in, - &snd_als4000_ctl_3d_output_switch, - &snd_als4000_ctl_3d_output_ratio, - &snd_als4000_ctl_3d_delay, - &snd_als4000_ctl_3d_poweroff_switch, +static struct sbmix_elem snd_als4000_controls[] = { + SB_DOUBLE("PCM Playback Switch", + SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1), + SB_DOUBLE("Synth Playback Switch", + SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1), + SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03), + SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1), + { + .name = "Master Mono Capture Route", + .type = SB_MIX_MONO_CAPTURE_ALS4K + }, + SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1), + SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01), + SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01), + SB_SINGLE("Digital Loopback Switch", + SB_ALS4000_CR3_CONFIGURATION, 7, 0x01), + /* FIXME: functionality of 3D controls might be swapped, I didn't find + * a description of how to identify what is supposed to be what */ + SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07), + /* FIXME: maybe there's actually some standard 3D ctrl name for it?? */ + SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03), + /* FIXME: ALS4000a.pdf mentions BBD (Bucket Brigade Device) time delay, + * but what ALSA 3D attribute is that actually? "Center", "Depth", + * "Wide" or "Space" or even "Level"? Assuming "Wide" for now... */ + SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f), + SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01), + SB_SINGLE("Master Playback 8kHz / 20kHz LPF Switch", + SB_ALS4000_FMDAC, 5, 0x01), #ifdef NOT_AVAILABLE - &snd_als4000_ctl_fmdac, - &snd_als4000_ctl_qsound, + SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01), + SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f), #endif }; @@ -744,18 +720,17 @@ static unsigned char snd_als4000_init_values[][2] = { { SB_ALS4000_MIC_IN_GAIN, 0 }, }; - /* */ -static int snd_sbmixer_init(sb_t *chip, - struct sbmix_elem **controls, +static int snd_sbmixer_init(struct snd_sb *chip, + struct sbmix_elem *controls, int controls_count, unsigned char map[][2], int map_count, char *name) { unsigned long flags; - snd_card_t *card = chip->card; + struct snd_card *card = chip->card; int idx, err; /* mixer reset */ @@ -771,7 +746,8 @@ static int snd_sbmixer_init(sb_t *chip, } for (idx = 0; idx < controls_count; idx++) { - if ((err = snd_sbmixer_add_ctl_elem(chip, controls[idx])) < 0) + err = snd_sbmixer_add_ctl_elem(chip, &controls[idx]); + if (err < 0) return err; } snd_component_add(card, name); @@ -779,12 +755,13 @@ static int snd_sbmixer_init(sb_t *chip, return 0; } -int snd_sbmixer_new(sb_t *chip) +int snd_sbmixer_new(struct snd_sb *chip) { - snd_card_t * card; + struct snd_card *card; int err; - snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); + if (snd_BUG_ON(!chip || !chip->card)) + return -EINVAL; card = chip->card; @@ -802,6 +779,7 @@ int snd_sbmixer_new(sb_t *chip) return err; break; case SB_HW_PRO: + case SB_HW_JAZZ16: if ((err = snd_sbmixer_init(chip, snd_sbpro_controls, ARRAY_SIZE(snd_sbpro_controls), @@ -812,6 +790,7 @@ int snd_sbmixer_new(sb_t *chip) break; case SB_HW_16: case SB_HW_ALS100: + case SB_HW_CS5530: if ((err = snd_sbmixer_init(chip, snd_sb16_controls, ARRAY_SIZE(snd_sb16_controls), @@ -821,6 +800,15 @@ int snd_sbmixer_new(sb_t *chip) return err; break; case SB_HW_ALS4000: + /* use only the first 16 controls from SB16 */ + err = snd_sbmixer_init(chip, + snd_sb16_controls, + 16, + snd_sb16_init_values, + ARRAY_SIZE(snd_sb16_init_values), + "ALS4000"); + if (err < 0) + return err; if ((err = snd_sbmixer_init(chip, snd_als4000_controls, ARRAY_SIZE(snd_als4000_controls), @@ -830,15 +818,163 @@ int snd_sbmixer_new(sb_t *chip) return err; break; case SB_HW_DT019X: - if ((err = snd_sbmixer_init(chip, - snd_dt019x_controls, - ARRAY_SIZE(snd_dt019x_controls), - snd_dt019x_init_values, - ARRAY_SIZE(snd_dt019x_init_values), - "DT019X")) < 0) + err = snd_sbmixer_init(chip, + snd_dt019x_controls, + ARRAY_SIZE(snd_dt019x_controls), + snd_dt019x_init_values, + ARRAY_SIZE(snd_dt019x_init_values), + "DT019X"); + if (err < 0) + return err; break; default: strcpy(card->mixername, "???"); } return 0; } + +#ifdef CONFIG_PM +static unsigned char sb20_saved_regs[] = { + SB_DSP20_MASTER_DEV, + SB_DSP20_PCM_DEV, + SB_DSP20_FM_DEV, + SB_DSP20_CD_DEV, +}; + +static unsigned char sbpro_saved_regs[] = { + SB_DSP_MASTER_DEV, + SB_DSP_PCM_DEV, + SB_DSP_PLAYBACK_FILT, + SB_DSP_FM_DEV, + SB_DSP_CD_DEV, + SB_DSP_LINE_DEV, + SB_DSP_MIC_DEV, + SB_DSP_CAPTURE_SOURCE, + SB_DSP_CAPTURE_FILT, +}; + +static unsigned char sb16_saved_regs[] = { + SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1, + SB_DSP4_3DSE, + SB_DSP4_BASS_DEV, SB_DSP4_BASS_DEV + 1, + SB_DSP4_TREBLE_DEV, SB_DSP4_TREBLE_DEV + 1, + SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1, + SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, + SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1, + SB_DSP4_OUTPUT_SW, + SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1, + SB_DSP4_LINE_DEV, SB_DSP4_LINE_DEV + 1, + SB_DSP4_MIC_DEV, + SB_DSP4_SPEAKER_DEV, + SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1, + SB_DSP4_OGAIN_DEV, SB_DSP4_OGAIN_DEV + 1, + SB_DSP4_MIC_AGC +}; + +static unsigned char dt019x_saved_regs[] = { + SB_DT019X_MASTER_DEV, + SB_DT019X_PCM_DEV, + SB_DT019X_SYNTH_DEV, + SB_DT019X_CD_DEV, + SB_DT019X_MIC_DEV, + SB_DT019X_SPKR_DEV, + SB_DT019X_LINE_DEV, + SB_DSP4_OUTPUT_SW, + SB_DT019X_OUTPUT_SW2, + SB_DT019X_CAPTURE_SW, +}; + +static unsigned char als4000_saved_regs[] = { + /* please verify in dsheet whether regs to be added + are actually real H/W or just dummy */ + SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1, + SB_DSP4_OUTPUT_SW, + SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1, + SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, + SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1, + SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1, + SB_DSP4_MIC_DEV, + SB_DSP4_SPEAKER_DEV, + SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1, + SB_DSP4_OGAIN_DEV, SB_DSP4_OGAIN_DEV + 1, + SB_DT019X_OUTPUT_SW2, + SB_ALS4000_MONO_IO_CTRL, + SB_ALS4000_MIC_IN_GAIN, + SB_ALS4000_FMDAC, + SB_ALS4000_3D_SND_FX, + SB_ALS4000_3D_TIME_DELAY, + SB_ALS4000_CR3_CONFIGURATION, +}; + +static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) +{ + unsigned char *val = chip->saved_regs; + if (snd_BUG_ON(num_regs > ARRAY_SIZE(chip->saved_regs))) + return; + for (; num_regs; num_regs--) + *val++ = snd_sbmixer_read(chip, *regs++); +} + +static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) +{ + unsigned char *val = chip->saved_regs; + if (snd_BUG_ON(num_regs > ARRAY_SIZE(chip->saved_regs))) + return; + for (; num_regs; num_regs--) + snd_sbmixer_write(chip, *regs++, *val++); +} + +void snd_sbmixer_suspend(struct snd_sb *chip) +{ + switch (chip->hardware) { + case SB_HW_20: + case SB_HW_201: + save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); + break; + case SB_HW_PRO: + case SB_HW_JAZZ16: + save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); + break; + case SB_HW_16: + case SB_HW_ALS100: + case SB_HW_CS5530: + save_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); + break; + case SB_HW_ALS4000: + save_mixer(chip, als4000_saved_regs, ARRAY_SIZE(als4000_saved_regs)); + break; + case SB_HW_DT019X: + save_mixer(chip, dt019x_saved_regs, ARRAY_SIZE(dt019x_saved_regs)); + break; + default: + break; + } +} + +void snd_sbmixer_resume(struct snd_sb *chip) +{ + switch (chip->hardware) { + case SB_HW_20: + case SB_HW_201: + restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); + break; + case SB_HW_PRO: + case SB_HW_JAZZ16: + restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); + break; + case SB_HW_16: + case SB_HW_ALS100: + case SB_HW_CS5530: + restore_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); + break; + case SB_HW_ALS4000: + restore_mixer(chip, als4000_saved_regs, ARRAY_SIZE(als4000_saved_regs)); + break; + case SB_HW_DT019X: + restore_mixer(chip, dt019x_saved_regs, ARRAY_SIZE(dt019x_saved_regs)); + break; + default: + break; + } +} +#endif |
