aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@suse.cz>2005-01-03 16:55:25 +0100
committerJaroslav Kysela <perex@suse.cz>2005-01-03 16:55:25 +0100
commitfcc58f6aea548cf95626827454c36fe09ac5d6c7 (patch)
tree8cea702225d5478fd58bad02c08277ec799e3c9a /sound
parent0a299616d4b14ec5b72ec3965ea38f0460e7940c (diff)
parent2945a055d6731c867617b3942913adc402f4cc5d (diff)
downloadhistory-fcc58f6aea548cf95626827454c36fe09ac5d6c7.tar.gz
Merge suse.cz:/home/perex/bk/linux-sound/linux-2.5
into suse.cz:/home/perex/bk/linux-sound/linux-sound
Diffstat (limited to 'sound')
-rw-r--r--sound/Kconfig2
-rw-r--r--sound/core/Kconfig2
-rw-r--r--sound/core/info.c20
-rw-r--r--sound/core/init.c3
-rw-r--r--sound/core/memory.c2
-rw-r--r--sound/core/oss/pcm_oss.c2
-rw-r--r--sound/core/pcm_memory.c2
-rw-r--r--sound/core/seq/instr/ainstr_fm.c5
-rw-r--r--sound/core/seq/instr/ainstr_gf1.c5
-rw-r--r--sound/core/seq/instr/ainstr_iw.c5
-rw-r--r--sound/core/seq/instr/ainstr_simple.c5
-rw-r--r--sound/core/seq/oss/seq_oss_timer.c2
-rw-r--r--sound/core/seq/seq_clientmgr.c2
-rw-r--r--sound/core/seq/seq_midi_emul.c4
-rw-r--r--sound/core/sound.c1
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c10
-rw-r--r--sound/isa/ad1848/ad1848_lib.c22
-rw-r--r--sound/isa/als100.c2
-rw-r--r--sound/isa/cs423x/cs4231_lib.c32
-rw-r--r--sound/isa/cs423x/cs4236.c2
-rw-r--r--sound/isa/es1688/es1688_lib.c8
-rw-r--r--sound/isa/es18xx.c6
-rw-r--r--sound/isa/gus/gus_dma.c12
-rw-r--r--sound/isa/gus/gus_sample.c2
-rw-r--r--sound/isa/opl3sa2.c10
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c12
-rw-r--r--sound/isa/sb/emu8000_callback.c4
-rw-r--r--sound/isa/sb/sb16_main.c10
-rw-r--r--sound/isa/sb/sb8_main.c4
-rw-r--r--sound/isa/sb/sb_common.c2
-rw-r--r--sound/isa/wavefront/wavefront.c6
-rw-r--r--sound/isa/wavefront/wavefront_synth.c98
-rw-r--r--sound/pci/Kconfig5
-rw-r--r--sound/pci/ac97/ac97_codec.c109
-rw-r--r--sound/pci/ac97/ac97_local.h2
-rw-r--r--sound/pci/ac97/ac97_patch.c113
-rw-r--r--sound/pci/au88x0/au88x0.c15
-rw-r--r--sound/pci/au88x0/au88x0.h6
-rw-r--r--sound/pci/au88x0/au88x0_core.c29
-rw-r--r--sound/pci/au88x0/au88x0_eq.c58
-rw-r--r--sound/pci/au88x0/au88x0_mixer.c4
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c4
-rw-r--r--sound/pci/azt3328.c29
-rw-r--r--sound/pci/bt87x.c149
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c34
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.h40
-rw-r--r--sound/pci/cs46xx/dsp_spos.c12
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c12
-rw-r--r--sound/pci/cs46xx/imgs/cwcdma.h8
-rw-r--r--sound/pci/emu10k1/Makefile2
-rw-r--r--sound/pci/emu10k1/emu10k1.c32
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c31
-rw-r--r--sound/pci/emu10k1/emu10k1_synth.c4
-rw-r--r--sound/pci/emu10k1/emufx.c209
-rw-r--r--sound/pci/emu10k1/emumixer.c70
-rw-r--r--sound/pci/emu10k1/emupcm.c11
-rw-r--r--sound/pci/emu10k1/emuproc.c220
-rw-r--r--sound/pci/emu10k1/io.c25
-rw-r--r--sound/pci/emu10k1/irq.c4
-rw-r--r--sound/pci/emu10k1/timer.c99
-rw-r--r--sound/pci/es1968.c6
-rw-r--r--sound/pci/ice1712/aureon.c6
-rw-r--r--sound/pci/intel8x0.c18
-rw-r--r--sound/pci/korg1212/korg1212.c3
-rw-r--r--sound/pci/mixart/mixart_core.c5
-rw-r--r--sound/pci/rme9652/hdsp.c9
-rw-r--r--sound/pci/rme9652/rme9652.c2
-rw-r--r--sound/pci/sonicvibes.c4
-rw-r--r--sound/pci/trident/trident_main.c38
-rw-r--r--sound/pci/trident/trident_memory.c23
-rw-r--r--sound/pci/trident/trident_synth.c4
-rw-r--r--sound/pci/via82xx.c8
-rw-r--r--sound/pci/vx222/vx222.c4
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c4
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.h2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c4
-rw-r--r--sound/sparc/cs4231.c17
-rw-r--r--sound/usb/usbmixer.c60
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c10
-rw-r--r--sound/usb/usx2y/usbusx2y.c25
-rw-r--r--sound/usb/usx2y/usbusx2y.h45
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c765
82 files changed, 1622 insertions, 1080 deletions
diff --git a/sound/Kconfig b/sound/Kconfig
index 1e4511a7b6a2f2..ec85c5f9fa0815 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -70,7 +70,7 @@ source "sound/parisc/Kconfig"
endmenu
menu "Open Sound System"
- depends on SOUND!=n && (BROKEN || !(SPARC32 || SPARC64))
+ depends on SOUND!=n && (BROKEN || (!SPARC32 && !SPARC64))
config SOUND_PRIME
tristate "Open Sound System (DEPRECATED)"
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index a62b83988cd0b6..e0dd38a084423a 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -83,7 +83,7 @@ config SND_SEQUENCER_OSS
config SND_BIT32_EMUL
tristate "Emulation for 32-bit applications"
- depends on SND && (MIPS64 || SPARC64 || PPC64 || X86_64 && IA32_EMULATION)
+ depends on SND && COMPAT
select SND_PCM
select SND_RAWMIDI
select SND_TIMER
diff --git a/sound/core/info.c b/sound/core/info.c
index f3338d999fcdbe..76f7f5a74e5de3 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -20,18 +20,14 @@
*/
#include <sound/driver.h>
-#include <linux/version.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/time.h>
#include <linux/smp_lock.h>
-#include <linux/utsname.h>
-#include <linux/config.h>
-
#include <sound/core.h>
-#include <sound/version.h>
#include <sound/minors.h>
#include <sound/info.h>
+#include <sound/version.h>
#include <linux/proc_fs.h>
#include <linux/devfs_fs_kernel.h>
#include <stdarg.h>
@@ -962,18 +958,10 @@ static snd_info_entry_t *snd_info_version_entry = NULL;
static void snd_info_version_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
{
- static char *kernel_version = system_utsname.release;
-
snd_iprintf(buffer,
- "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
- "Compiled on " __DATE__ " for kernel %s"
-#ifdef CONFIG_SMP
- " (SMP)"
-#endif
-#ifdef MODVERSIONS
- " with versioned symbols"
-#endif
- ".\n", kernel_version);
+ "Advanced Linux Sound Architecture Driver Version "
+ CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
+ );
}
static int __init snd_info_version_init(void)
diff --git a/sound/core/init.c b/sound/core/init.c
index efa128c275e8ec..509fdf2f84ce70 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -37,7 +37,6 @@ struct snd_shutdown_f_ops {
struct snd_shutdown_f_ops *next;
};
-int snd_cards_count = 0;
unsigned int snd_cards_lock = 0; /* locked for registering/using */
snd_card_t *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL};
rwlock_t snd_card_rwlock = RW_LOCK_UNLOCKED;
@@ -251,7 +250,6 @@ int snd_card_free(snd_card_t * card)
return -EINVAL;
write_lock(&snd_card_rwlock);
snd_cards[card->number] = NULL;
- snd_cards_count--;
write_unlock(&snd_card_rwlock);
#ifdef CONFIG_PM
@@ -441,7 +439,6 @@ int snd_card_register(snd_card_t * card)
if (card->id[0] == '\0')
choose_default_id(card);
snd_cards[card->number] = card;
- snd_cards_count++;
write_unlock(&snd_card_rwlock);
if ((err = snd_info_card_register(card)) < 0) {
snd_printd("unable to create card info\n");
diff --git a/sound/core/memory.c b/sound/core/memory.c
index bb4150a9c2e9cd..5949405282d18c 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -267,7 +267,7 @@ int copy_to_user_fromio(void __user *dst, const void __iomem *src, size_t count)
size_t c = count;
if (c > sizeof(buf))
c = sizeof(buf);
- memcpy_fromio(buf, src, c);
+ memcpy_fromio(buf, (void __iomem *)src, c);
if (copy_to_user(dst, buf, c))
return -EFAULT;
count -= c;
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 0f615469d8baf7..29141f644c4d52 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -46,7 +46,7 @@
static int dsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0};
static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
-static int nonblock_open;
+static int nonblock_open = 1;
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Abramo Bagnara <abramo@alsa-project.org>");
MODULE_DESCRIPTION("PCM OSS emulation for ALSA.");
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 16a81240ad7a07..e165fee4891c1f 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -37,7 +37,7 @@ static int maximum_substreams = 4;
module_param(maximum_substreams, int, 0444);
MODULE_PARM_DESC(maximum_substreams, "Maximum substreams with preallocated DMA memory.");
-const static size_t snd_minimum_buffer = 16384;
+static const size_t snd_minimum_buffer = 16384;
/*
diff --git a/sound/core/seq/instr/ainstr_fm.c b/sound/core/seq/instr/ainstr_fm.c
index 52a070b909182d..5c671e69884f9f 100644
--- a/sound/core/seq/instr/ainstr_fm.c
+++ b/sound/core/seq/instr/ainstr_fm.c
@@ -30,8 +30,6 @@ MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture FM Instrument support.");
MODULE_LICENSE("GPL");
-char *snd_seq_fm_id = SNDRV_SEQ_INSTR_ID_OPL2_3;
-
static int snd_seq_fm_put(void *private_data, snd_seq_kinstr_t *instr,
char __user *instr_data, long len, int atomic, int cmd)
{
@@ -129,7 +127,7 @@ int snd_seq_fm_init(snd_seq_kinstr_ops_t *ops,
memset(ops, 0, sizeof(*ops));
// ops->private_data = private_data;
ops->add_len = sizeof(fm_instrument_t);
- ops->instr_type = snd_seq_fm_id;
+ ops->instr_type = SNDRV_SEQ_INSTR_ID_OPL2_3;
ops->put = snd_seq_fm_put;
ops->get = snd_seq_fm_get;
ops->get_size = snd_seq_fm_get_size;
@@ -155,5 +153,4 @@ static void __exit alsa_ainstr_fm_exit(void)
module_init(alsa_ainstr_fm_init)
module_exit(alsa_ainstr_fm_exit)
-EXPORT_SYMBOL(snd_seq_fm_id);
EXPORT_SYMBOL(snd_seq_fm_init);
diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
index 6c21e52ca61ea9..0779c41ca03769 100644
--- a/sound/core/seq/instr/ainstr_gf1.c
+++ b/sound/core/seq/instr/ainstr_gf1.c
@@ -31,8 +31,6 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture GF1 (GUS) Patch support.");
MODULE_LICENSE("GPL");
-char *snd_seq_gf1_id = SNDRV_SEQ_INSTR_ID_GUS_PATCH;
-
static unsigned int snd_seq_gf1_size(unsigned int size, unsigned int format)
{
unsigned int result = size;
@@ -331,7 +329,7 @@ int snd_seq_gf1_init(snd_gf1_ops_t *ops,
ops->private_data = private_data;
ops->kops.private_data = ops;
ops->kops.add_len = sizeof(gf1_instrument_t);
- ops->kops.instr_type = snd_seq_gf1_id;
+ ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_GUS_PATCH;
ops->kops.put = snd_seq_gf1_put;
ops->kops.get = snd_seq_gf1_get;
ops->kops.get_size = snd_seq_gf1_get_size;
@@ -357,5 +355,4 @@ static void __exit alsa_ainstr_gf1_exit(void)
module_init(alsa_ainstr_gf1_init)
module_exit(alsa_ainstr_gf1_exit)
-EXPORT_SYMBOL(snd_seq_gf1_id);
EXPORT_SYMBOL(snd_seq_gf1_init);
diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
index 005171abe94dc9..39ff72b2aab367 100644
--- a/sound/core/seq/instr/ainstr_iw.c
+++ b/sound/core/seq/instr/ainstr_iw.c
@@ -31,8 +31,6 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture IWFFFF support.");
MODULE_LICENSE("GPL");
-char *snd_seq_iwffff_id = SNDRV_SEQ_INSTR_ID_INTERWAVE;
-
static unsigned int snd_seq_iwffff_size(unsigned int size, unsigned int format)
{
unsigned int result = size;
@@ -595,7 +593,7 @@ int snd_seq_iwffff_init(snd_iwffff_ops_t *ops,
ops->private_data = private_data;
ops->kops.private_data = ops;
ops->kops.add_len = sizeof(iwffff_instrument_t);
- ops->kops.instr_type = snd_seq_iwffff_id;
+ ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_INTERWAVE;
ops->kops.put = snd_seq_iwffff_put;
ops->kops.get = snd_seq_iwffff_get;
ops->kops.get_size = snd_seq_iwffff_get_size;
@@ -621,5 +619,4 @@ static void __exit alsa_ainstr_iw_exit(void)
module_init(alsa_ainstr_iw_init)
module_exit(alsa_ainstr_iw_exit)
-EXPORT_SYMBOL(snd_seq_iwffff_id);
EXPORT_SYMBOL(snd_seq_iwffff_init);
diff --git a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c
index 8ae5d10e51c164..6183d21510345c 100644
--- a/sound/core/seq/instr/ainstr_simple.c
+++ b/sound/core/seq/instr/ainstr_simple.c
@@ -31,8 +31,6 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture Simple Instrument support.");
MODULE_LICENSE("GPL");
-char *snd_seq_simple_id = SNDRV_SEQ_INSTR_ID_SIMPLE;
-
static unsigned int snd_seq_simple_size(unsigned int size, unsigned int format)
{
unsigned int result = size;
@@ -188,7 +186,7 @@ int snd_seq_simple_init(snd_simple_ops_t *ops,
ops->private_data = private_data;
ops->kops.private_data = ops;
ops->kops.add_len = sizeof(simple_instrument_t);
- ops->kops.instr_type = snd_seq_simple_id;
+ ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_SIMPLE;
ops->kops.put = snd_seq_simple_put;
ops->kops.get = snd_seq_simple_get;
ops->kops.get_size = snd_seq_simple_get_size;
@@ -214,5 +212,4 @@ static void __exit alsa_ainstr_simple_exit(void)
module_init(alsa_ainstr_simple_init)
module_exit(alsa_ainstr_simple_exit)
-EXPORT_SYMBOL(snd_seq_simple_id);
EXPORT_SYMBOL(snd_seq_simple_init);
diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c
index b17c1f8d1011e4..42ca9493fa600a 100644
--- a/sound/core/seq/oss/seq_oss_timer.c
+++ b/sound/core/seq/oss/seq_oss_timer.c
@@ -149,7 +149,7 @@ send_timer_event(seq_oss_devinfo_t *dp, int type, int value)
ev.queue = dp->queue;
ev.data.queue.queue = dp->queue;
ev.data.queue.param.value = value;
- return snd_seq_kernel_client_dispatch(dp->cseq, &ev, 0, 0);
+ return snd_seq_kernel_client_dispatch(dp->cseq, &ev, 1, 0);
}
/*
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index dd7650dddc48a4..e32aa926f4ffcd 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -904,7 +904,7 @@ static int snd_seq_client_enqueue_event(client_t *client,
return -ENXIO; /* queue is not allocated */
/* allocate an event cell */
- err = snd_seq_event_dup(client->pool, event, &cell, !blocking && !atomic, file);
+ err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, file);
if (err < 0)
return err;
diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
index 7ea8db2cffec44..c8cbe8fdb06c0b 100644
--- a/sound/core/seq/seq_midi_emul.c
+++ b/sound/core/seq/seq_midi_emul.c
@@ -549,12 +549,12 @@ sysex(snd_midi_op_t *ops, void *private, unsigned char *buf, int len, snd_midi_c
} else if (buf[5] == 0x01 && buf[6] == 0x30) {
/* reverb mode */
- parsed = SNDRV_MIDI_SYSEX_GS_CHORUS_MODE;
+ parsed = SNDRV_MIDI_SYSEX_GS_REVERB_MODE;
chset->gs_reverb_mode = buf[7];
} else if (buf[5] == 0x01 && buf[6] == 0x38) {
/* chorus mode */
- parsed = SNDRV_MIDI_SYSEX_GS_REVERB_MODE;
+ parsed = SNDRV_MIDI_SYSEX_GS_CHORUS_MODE;
chset->gs_chorus_mode = buf[7];
} else if (buf[5] == 0x00 && buf[6] == 0x04) {
diff --git a/sound/core/sound.c b/sound/core/sound.c
index a9e477c2e72975..1fef4ed60a33b3 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -411,7 +411,6 @@ EXPORT_SYMBOL(snd_kmalloc_strdup);
EXPORT_SYMBOL(copy_to_user_fromio);
EXPORT_SYMBOL(copy_from_user_toio);
/* init.c */
-EXPORT_SYMBOL(snd_cards_count);
EXPORT_SYMBOL(snd_cards);
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 026198317b358d..625b2eff14a14d 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -46,20 +46,20 @@ static inline int snd_ad1816a_busy_wait(ad1816a_t *chip)
return -EBUSY;
}
-inline unsigned char snd_ad1816a_in(ad1816a_t *chip, unsigned char reg)
+static inline unsigned char snd_ad1816a_in(ad1816a_t *chip, unsigned char reg)
{
snd_ad1816a_busy_wait(chip);
return inb(AD1816A_REG(reg));
}
-inline void snd_ad1816a_out(ad1816a_t *chip, unsigned char reg,
+static inline void snd_ad1816a_out(ad1816a_t *chip, unsigned char reg,
unsigned char value)
{
snd_ad1816a_busy_wait(chip);
outb(value, AD1816A_REG(reg));
}
-inline void snd_ad1816a_out_mask(ad1816a_t *chip, unsigned char reg,
+static inline void snd_ad1816a_out_mask(ad1816a_t *chip, unsigned char reg,
unsigned char mask, unsigned char value)
{
snd_ad1816a_out(chip, reg,
@@ -372,6 +372,7 @@ static snd_pcm_hardware_t snd_ad1816a_capture = {
.fifo_size = 0,
};
+#if 0 /* not used now */
static int snd_ad1816a_timer_close(snd_timer_t *timer)
{
ad1816a_t *chip = snd_timer_chip(timer);
@@ -435,6 +436,7 @@ static struct _snd_timer_hardware snd_ad1816a_timer_table = {
.start = snd_ad1816a_timer_start,
.stop = snd_ad1816a_timer_stop,
};
+#endif /* not used now */
static int snd_ad1816a_playback_open(snd_pcm_substream_t *substream)
@@ -692,6 +694,7 @@ int snd_ad1816a_pcm(ad1816a_t *chip, int device, snd_pcm_t **rpcm)
return 0;
}
+#if 0 /* not used now */
static void snd_ad1816a_timer_free(snd_timer_t *timer)
{
ad1816a_t *chip = timer->private_data;
@@ -720,6 +723,7 @@ int snd_ad1816a_timer(ad1816a_t *chip, int device, snd_timer_t **rtimer)
*rtimer = timer;
return 0;
}
+#endif /* not used now */
/*
*
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index d0a62f71b5d8c8..7cab7c5e0b250d 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -119,9 +119,8 @@ void snd_ad1848_out(ad1848_t *chip,
#endif
}
-void snd_ad1848_dout(ad1848_t *chip,
- unsigned char reg,
- unsigned char value)
+static void snd_ad1848_dout(ad1848_t *chip,
+ unsigned char reg, unsigned char value)
{
int timeout;
@@ -132,7 +131,7 @@ void snd_ad1848_dout(ad1848_t *chip,
mb();
}
-unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg)
+static unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg)
{
int timeout;
@@ -147,9 +146,9 @@ unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg)
return inb(AD1848P(chip, REG));
}
-#ifdef CONFIG_SND_DEBUG
+#if 0
-void snd_ad1848_debug(ad1848_t *chip)
+static void snd_ad1848_debug(ad1848_t *chip)
{
printk("AD1848 REGS: INDEX = 0x%02x ", inb(AD1848P(chip, REGSEL)));
printk(" STATUS = 0x%02x\n", inb(AD1848P(chip, STATUS)));
@@ -177,7 +176,7 @@ void snd_ad1848_debug(ad1848_t *chip)
* AD1848 detection / MCE routines
*/
-void snd_ad1848_mce_up(ad1848_t *chip)
+static void snd_ad1848_mce_up(ad1848_t *chip)
{
unsigned long flags;
int timeout;
@@ -198,7 +197,7 @@ void snd_ad1848_mce_up(ad1848_t *chip)
spin_unlock_irqrestore(&chip->reg_lock, flags);
}
-void snd_ad1848_mce_down(ad1848_t *chip)
+static void snd_ad1848_mce_down(ad1848_t *chip)
{
unsigned long flags;
int timeout;
@@ -584,7 +583,7 @@ static int snd_ad1848_capture_prepare(snd_pcm_substream_t * substream)
return 0;
}
-irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
ad1848_t *chip = dev_id;
@@ -1264,12 +1263,7 @@ int snd_ad1848_mixer(ad1848_t *chip)
return 0;
}
-EXPORT_SYMBOL(snd_ad1848_in);
EXPORT_SYMBOL(snd_ad1848_out);
-EXPORT_SYMBOL(snd_ad1848_dout);
-EXPORT_SYMBOL(snd_ad1848_mce_up);
-EXPORT_SYMBOL(snd_ad1848_mce_down);
-EXPORT_SYMBOL(snd_ad1848_interrupt);
EXPORT_SYMBOL(snd_ad1848_create);
EXPORT_SYMBOL(snd_ad1848_pcm);
EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index f0f1c4251c1ea0..3fa1f5c532abba 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -94,6 +94,8 @@ static struct pnp_card_device_id snd_als100_pnpids[] = {
{ .id = "ALS0120", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } },
/* ALS200 */
{ .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } } },
+ /* ALS200 OEM */
+ { .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } } },
/* RTL3000 */
{ .id = "RTL3000", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } },
{ .id = "", } /* end */
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index d323e36378f8a1..2a626be82b99da 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -166,8 +166,8 @@ static __CS4231_INLINE__ u8 cs4231_inb(cs4231_t *chip, u8 offset)
#endif
}
-void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
- unsigned char mask, unsigned char value)
+static void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
+ unsigned char mask, unsigned char value)
{
int timeout;
unsigned char tmp;
@@ -271,9 +271,9 @@ unsigned char snd_cs4236_ext_in(cs4231_t *chip, unsigned char reg)
#endif
}
-#ifdef CONFIG_SND_DEBUG
+#if 0
-void snd_cs4231_debug(cs4231_t *chip)
+static void snd_cs4231_debug(cs4231_t *chip)
{
printk("CS4231 REGS: INDEX = 0x%02x ", cs4231_inb(chip, CS4231P(REGSEL)));
printk(" STATUS = 0x%02x\n", cs4231_inb(chip, CS4231P(STATUS)));
@@ -356,7 +356,6 @@ void snd_cs4231_mce_down(cs4231_t *chip)
{
unsigned long flags;
int timeout;
- signed long time;
snd_cs4231_busy_wait(chip);
#if 0
@@ -390,34 +389,26 @@ void snd_cs4231_mce_down(cs4231_t *chip)
#if 0
printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
#endif
- timeout = HZ / 4 / 2;
- time = 2;
+ /* in 10 ms increments, check condition, up to 250 ms */
+ timeout = 25;
while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
- set_current_state(TASK_INTERRUPTIBLE);
- time = schedule_timeout(time);
- if (time > 0)
- continue;
- time = 2;
if (--timeout < 0) {
snd_printk("mce_down - auto calibration time out (2)\n");
return;
}
+ msleep(10);
}
#if 0
printk("(3) jiffies = %li\n", jiffies);
#endif
- timeout = HZ / 10 / 2;
- time = 2;
+ /* in 10 ms increments, check condition, up to 100 ms */
+ timeout = 10;
while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
- set_current_state(TASK_INTERRUPTIBLE);
- time = schedule_timeout(time);
- if (time > 0)
- continue;
- time = 2;
if (--timeout < 0) {
snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
return;
}
+ msleep(10);
}
#if 0
printk("(4) jiffies = %li\n", jiffies);
@@ -1035,7 +1026,7 @@ static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substr
*/
-int snd_cs4231_probe(cs4231_t *chip)
+static int snd_cs4231_probe(cs4231_t *chip)
{
unsigned long flags;
int i, id, rev;
@@ -1943,7 +1934,6 @@ int snd_cs4231_mixer(cs4231_t *chip)
EXPORT_SYMBOL(snd_cs4231_out);
EXPORT_SYMBOL(snd_cs4231_in);
-EXPORT_SYMBOL(snd_cs4231_outm);
EXPORT_SYMBOL(snd_cs4236_ext_out);
EXPORT_SYMBOL(snd_cs4236_ext_in);
EXPORT_SYMBOL(snd_cs4231_mce_up);
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 79e32744eebd8f..e745a54e00a1be 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -242,6 +242,8 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = {
{ .id = "CSCd937", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
/* CS4235 without MPU401 */
{ .id = "CSCe825", .devs = { { "CSC0100" }, { "CSC0110" } } },
+ /* Unknown SiS530 - CS4235 */
+ { .id = "CSC4825", .devs = { { "CSC0100" }, { "CSC0110" } } },
/* IBM IntelliStation M Pro 6898 11U - CS4236B */
{ .id = "CSCe835", .devs = { { "CSC0000" }, { "CSC0010" } } },
/* IBM PC 300PL Onboard - CS4236B */
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index c20bc7fc83d234..17f68d07d9b244 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -70,7 +70,7 @@ static int snd_es1688_write(es1688_t *chip,
return snd_es1688_dsp_command(chip, data);
}
-int snd_es1688_read(es1688_t *chip, unsigned char reg)
+static int snd_es1688_read(es1688_t *chip, unsigned char reg)
{
/* Read a byte from an extended mode register of ES1688 */
if (!snd_es1688_dsp_command(chip, 0xc0))
@@ -89,7 +89,7 @@ void snd_es1688_mixer_write(es1688_t *chip,
udelay(10);
}
-unsigned char snd_es1688_mixer_read(es1688_t *chip, unsigned char reg)
+static unsigned char snd_es1688_mixer_read(es1688_t *chip, unsigned char reg)
{
unsigned char result;
@@ -479,7 +479,7 @@ static int snd_es1688_capture_trigger(snd_pcm_substream_t * substream,
return snd_es1688_trigger(chip, cmd, 0x0f);
}
-irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
es1688_t *chip = dev_id;
@@ -1041,8 +1041,6 @@ int snd_es1688_mixer(es1688_t *chip)
}
EXPORT_SYMBOL(snd_es1688_mixer_write);
-EXPORT_SYMBOL(snd_es1688_mixer_read);
-EXPORT_SYMBOL(snd_es1688_interrupt);
EXPORT_SYMBOL(snd_es1688_create);
EXPORT_SYMBOL(snd_es1688_pcm);
EXPORT_SYMBOL(snd_es1688_mixer);
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 9b0d5a9ecfbb96..c212d3c0574f5b 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -268,7 +268,7 @@ static int snd_es18xx_bits(es18xx_t *chip, unsigned char reg,
return ret;
}
-inline void snd_es18xx_mixer_write(es18xx_t *chip,
+static inline void snd_es18xx_mixer_write(es18xx_t *chip,
unsigned char reg, unsigned char data)
{
unsigned long flags;
@@ -281,7 +281,7 @@ inline void snd_es18xx_mixer_write(es18xx_t *chip,
#endif
}
-inline int snd_es18xx_mixer_read(es18xx_t *chip, unsigned char reg)
+static inline int snd_es18xx_mixer_read(es18xx_t *chip, unsigned char reg)
{
unsigned long flags;
int data;
@@ -1569,7 +1569,7 @@ static void snd_es18xx_pcm_free(snd_pcm_t *pcm)
snd_pcm_lib_preallocate_free_for_all(pcm);
}
-int __devinit snd_es18xx_pcm(es18xx_t *chip, int device, snd_pcm_t ** rpcm)
+static int __devinit snd_es18xx_pcm(es18xx_t *chip, int device, snd_pcm_t ** rpcm)
{
snd_pcm_t *pcm;
char str[16];
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c
index cb4c2959bddd31..de4b56d80b3566 100644
--- a/sound/isa/gus/gus_dma.c
+++ b/sound/isa/gus/gus_dma.c
@@ -25,7 +25,7 @@
#include <sound/core.h>
#include <sound/gus.h>
-void snd_gf1_dma_ack(snd_gus_card_t * gus)
+static void snd_gf1_dma_ack(snd_gus_card_t * gus)
{
unsigned long flags;
@@ -35,11 +35,11 @@ void snd_gf1_dma_ack(snd_gus_card_t * gus)
spin_unlock_irqrestore(&gus->reg_lock, flags);
}
-void snd_gf1_dma_program(snd_gus_card_t * gus,
- unsigned int addr,
- unsigned long buf_addr,
- unsigned int count,
- unsigned int cmd)
+static void snd_gf1_dma_program(snd_gus_card_t * gus,
+ unsigned int addr,
+ unsigned long buf_addr,
+ unsigned int count,
+ unsigned int cmd)
{
unsigned long flags;
unsigned int address;
diff --git a/sound/isa/gus/gus_sample.c b/sound/isa/gus/gus_sample.c
index 44d4036d515606..4290e03acd519f 100644
--- a/sound/isa/gus/gus_sample.c
+++ b/sound/isa/gus/gus_sample.c
@@ -42,7 +42,7 @@ static void select_instrument(snd_gus_card_t * gus, snd_gus_voice_t * v)
instr = snd_seq_instr_find(gus->gf1.ilist, &v->instr, 0, 1);
if (instr != NULL) {
if (instr->ops) {
- if (instr->ops->instr_type == snd_seq_simple_id)
+ if (!strcmp(instr->ops->instr_type, SNDRV_SEQ_INSTR_ID_SIMPLE))
snd_gf1_simple_init(v);
}
snd_seq_instr_free_use(gus->gf1.ilist, instr);
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 317cb9e374604b..52381fcee59670 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -341,7 +341,7 @@ static int snd_opl3sa2_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
return 0;
}
-int snd_opl3sa2_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
unsigned long flags;
@@ -358,7 +358,7 @@ int snd_opl3sa2_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uco
return 0;
}
-int snd_opl3sa2_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
unsigned long flags;
@@ -388,7 +388,7 @@ int snd_opl3sa2_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uco
.get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
-int snd_opl3sa2_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_opl3sa2_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
{
int mask = (kcontrol->private_value >> 24) & 0xff;
@@ -399,7 +399,7 @@ int snd_opl3sa2_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinf
return 0;
}
-int snd_opl3sa2_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
unsigned long flags;
@@ -421,7 +421,7 @@ int snd_opl3sa2_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uco
return 0;
}
-int snd_opl3sa2_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
unsigned long flags;
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index c4fbf6fffd0cf5..411a702d85ba54 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -1095,7 +1095,7 @@ static void snd_opti93x_overrange(opti93x_t *chip)
spin_unlock_irqrestore(&chip->lock, flags);
}
-irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
opti93x_t *codec = dev_id;
unsigned char status;
@@ -1263,9 +1263,9 @@ static const char *snd_opti93x_chip_id(opti93x_t *codec)
}
}
-int snd_opti93x_create(snd_card_t *card, opti9xx_t *chip,
- int dma1, int dma2,
- opti93x_t **rcodec)
+static int snd_opti93x_create(snd_card_t *card, opti9xx_t *chip,
+ int dma1, int dma2,
+ opti93x_t **rcodec)
{
static snd_device_ops_t ops = {
.dev_free = snd_opti93x_dev_free,
@@ -1359,7 +1359,7 @@ static void snd_opti93x_pcm_free(snd_pcm_t *pcm)
snd_pcm_lib_preallocate_free_for_all(pcm);
}
-int snd_opti93x_pcm(opti93x_t *codec, int device, snd_pcm_t **rpcm)
+static int snd_opti93x_pcm(opti93x_t *codec, int device, snd_pcm_t **rpcm)
{
int error;
snd_pcm_t *pcm;
@@ -1603,7 +1603,7 @@ OPTi93X_DOUBLE("Capture Volume", 0, OPTi93X_MIXOUT_LEFT, OPTi93X_MIXOUT_RIGHT, 0
}
};
-int snd_opti93x_mixer(opti93x_t *chip)
+static int snd_opti93x_mixer(opti93x_t *chip)
{
snd_card_t *card;
snd_kcontrol_new_t knew;
diff --git a/sound/isa/sb/emu8000_callback.c b/sound/isa/sb/emu8000_callback.c
index 05565f31db1c9d..1cc4101a17a4b7 100644
--- a/sound/isa/sb/emu8000_callback.c
+++ b/sound/isa/sb/emu8000_callback.c
@@ -528,6 +528,10 @@ load_fx(snd_emux_t *emu, int type, int mode, const void __user *buf, long len)
emu8000_t *hw;
hw = emu->hw;
+ /* skip header */
+ buf += 16;
+ len -= 16;
+
switch (type) {
case SNDRV_EMU8000_LOAD_CHORUS_FX:
return snd_emu8000_load_chorus_fx(hw, mode, buf, len);
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index e58f486d9754a1..a6a0fa51626840 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -509,7 +509,7 @@ static snd_pcm_hardware_t snd_sb16_capture =
* open/close
*/
-int snd_sb16_playback_open(snd_pcm_substream_t * substream)
+static int snd_sb16_playback_open(snd_pcm_substream_t * substream)
{
unsigned long flags;
sb_t *chip = snd_pcm_substream_chip(substream);
@@ -566,7 +566,7 @@ int snd_sb16_playback_open(snd_pcm_substream_t * substream)
return 0;
}
-int snd_sb16_playback_close(snd_pcm_substream_t * substream)
+static int snd_sb16_playback_close(snd_pcm_substream_t * substream)
{
unsigned long flags;
sb_t *chip = snd_pcm_substream_chip(substream);
@@ -579,7 +579,7 @@ int snd_sb16_playback_close(snd_pcm_substream_t * substream)
return 0;
}
-int snd_sb16_capture_open(snd_pcm_substream_t * substream)
+static int snd_sb16_capture_open(snd_pcm_substream_t * substream)
{
unsigned long flags;
sb_t *chip = snd_pcm_substream_chip(substream);
@@ -636,7 +636,7 @@ int snd_sb16_capture_open(snd_pcm_substream_t * substream)
return 0;
}
-int snd_sb16_capture_close(snd_pcm_substream_t * substream)
+static int snd_sb16_capture_close(snd_pcm_substream_t * substream)
{
unsigned long flags;
sb_t *chip = snd_pcm_substream_chip(substream);
@@ -728,7 +728,7 @@ static int snd_sb16_dma_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu
return change;
}
-snd_kcontrol_new_t snd_sb16_dma_control = {
+static snd_kcontrol_new_t snd_sb16_dma_control = {
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "16-bit DMA Allocation",
.info = snd_sb16_dma_control_info,
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index d2e3abed239d5d..87c9b1ba06cf8f 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -425,7 +425,7 @@ static snd_pcm_hardware_t snd_sb8_capture =
*
*/
-int snd_sb8_open(snd_pcm_substream_t *substream)
+static int snd_sb8_open(snd_pcm_substream_t *substream)
{
sb_t *chip = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -471,7 +471,7 @@ int snd_sb8_open(snd_pcm_substream_t *substream)
return 0;
}
-int snd_sb8_close(snd_pcm_substream_t *substream)
+static int snd_sb8_close(snd_pcm_substream_t *substream)
{
unsigned long flags;
sb_t *chip = snd_pcm_substream_chip(substream);
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index 8935ae93d4f85c..5b6bde213ea005 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -92,7 +92,7 @@ int snd_sbdsp_reset(sb_t *chip)
return -ENODEV;
}
-int snd_sbdsp_version(sb_t * chip)
+static int snd_sbdsp_version(sb_t * chip)
{
unsigned int result = -ENODEV;
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 3aa25a610141a8..79b022070ba33b 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -279,7 +279,7 @@ static irqreturn_t snd_wavefront_ics2115_interrupt(int irq,
return IRQ_HANDLED;
}
-snd_hwdep_t * __devinit
+static snd_hwdep_t * __devinit
snd_wavefront_new_synth (snd_card_t *card,
int hw_dev,
snd_wavefront_card_t *acard)
@@ -305,7 +305,7 @@ snd_wavefront_new_synth (snd_card_t *card,
return wavefront_synth;
}
-snd_hwdep_t * __devinit
+static snd_hwdep_t * __devinit
snd_wavefront_new_fx (snd_card_t *card,
int hw_dev,
snd_wavefront_card_t *acard,
@@ -332,7 +332,7 @@ snd_wavefront_new_fx (snd_card_t *card,
static snd_wavefront_mpu_id internal_id = internal_mpu;
static snd_wavefront_mpu_id external_id = external_mpu;
-snd_rawmidi_t * __devinit
+static snd_rawmidi_t * __devinit
snd_wavefront_new_midi (snd_card_t *card,
int midi_dev,
snd_wavefront_card_t *acard,
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 1d9ee967b0e6d4..e923148dce7ba8 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -32,58 +32,58 @@
#include <sound/snd_wavefront.h>
#include <sound/initval.h>
-int wf_raw = 0; /* we normally check for "raw state" to firmware
- loading. if non-zero, then during driver loading, the
- state of the board is ignored, and we reset the
- board and load the firmware anyway.
- */
+static int wf_raw = 0; /* we normally check for "raw state" to firmware
+ loading. if non-zero, then during driver loading, the
+ state of the board is ignored, and we reset the
+ board and load the firmware anyway.
+ */
-int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
- whatever state it is when the driver is loaded.
- The default is to download the microprogram and
- associated coefficients to set it up for "default"
- operation, whatever that means.
- */
-
-int debug_default = 0; /* you can set this to control debugging
- during driver loading. it takes any combination
- of the WF_DEBUG_* flags defined in
- wavefront.h
- */
+static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
+ whatever state it is when the driver is loaded.
+ The default is to download the microprogram and
+ associated coefficients to set it up for "default"
+ operation, whatever that means.
+ */
+
+static int debug_default = 0; /* you can set this to control debugging
+ during driver loading. it takes any combination
+ of the WF_DEBUG_* flags defined in
+ wavefront.h
+ */
/* XXX this needs to be made firmware and hardware version dependent */
-char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
- version of the WaveFront OS
- */
-
-int wait_usecs = 150; /* This magic number seems to give pretty optimal
- throughput based on my limited experimentation.
- If you want to play around with it and find a better
- value, be my guest. Remember, the idea is to
- get a number that causes us to just busy wait
- for as many WaveFront commands as possible, without
- coming up with a number so large that we hog the
- whole CPU.
-
- Specifically, with this number, out of about 134,000
- status waits, only about 250 result in a sleep.
- */
-
-int sleep_interval = 100; /* HZ/sleep_interval seconds per sleep */
-int sleep_tries = 50; /* number of times we'll try to sleep */
-
-int reset_time = 2; /* hundreths of a second we wait after a HW
- reset for the expected interrupt.
- */
-
-int ramcheck_time = 20; /* time in seconds to wait while ROM code
- checks on-board RAM.
- */
-
-int osrun_time = 10; /* time in seconds we wait for the OS to
- start running.
- */
+static char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
+ version of the WaveFront OS
+ */
+
+static int wait_usecs = 150; /* This magic number seems to give pretty optimal
+ throughput based on my limited experimentation.
+ If you want to play around with it and find a better
+ value, be my guest. Remember, the idea is to
+ get a number that causes us to just busy wait
+ for as many WaveFront commands as possible, without
+ coming up with a number so large that we hog the
+ whole CPU.
+
+ Specifically, with this number, out of about 134,000
+ status waits, only about 250 result in a sleep.
+ */
+
+static int sleep_interval = 100; /* HZ/sleep_interval seconds per sleep */
+static int sleep_tries = 50; /* number of times we'll try to sleep */
+
+static int reset_time = 2; /* hundreths of a second we wait after a HW
+ reset for the expected interrupt.
+ */
+
+static int ramcheck_time = 20; /* time in seconds to wait while ROM code
+ checks on-board RAM.
+ */
+
+static int osrun_time = 10; /* time in seconds we wait for the OS to
+ start running.
+ */
module_param(wf_raw, int, 0444);
MODULE_PARM_DESC(wf_raw, "if non-zero, assume that we need to boot the OS");
module_param(fx_raw, int, 0444);
@@ -1709,7 +1709,7 @@ snd_wavefront_internal_interrupt (snd_wavefront_card_t *card)
7 Unused
*/
-int __init
+static int __init
snd_wavefront_interrupt_bits (int irq)
{
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 3248ed924ba7fd..d2b9b49e461d98 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -106,8 +106,9 @@ config SND_BT87X
depends on SND
select SND_PCM
help
- Say Y here to include support for recording audio from TV
- cards based on Brooktree Bt878/Bt879 chips.
+ If you want to record audio from TV cards based on
+ Brooktree Bt878/Bt879 chips, say Y here and read
+ <file:Documentation/sound/alsa/Bt87x.txt>.
To compile this driver as a module, choose M here: the module
will be called snd-bt87x.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index b5c032036f1b50..a1675fd03f413c 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -633,7 +633,7 @@ static int snd_ac97_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *
(val1 << shift_left) | (val2 << shift_right));
}
-int snd_ac97_getput_page(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol,
+static int snd_ac97_getput_page(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol,
int (*func)(snd_kcontrol_t *, snd_ctl_elem_value_t *))
{
ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
@@ -2213,6 +2213,46 @@ void snd_ac97_suspend(ac97_t *ac97)
snd_ac97_powerdown(ac97);
}
+/*
+ * restore ac97 status
+ */
+void snd_ac97_restore_status(ac97_t *ac97)
+{
+ int i;
+
+ for (i = 2; i < 0x7c ; i += 2) {
+ if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
+ continue;
+ /* restore only accessible registers
+ * some chip (e.g. nm256) may hang up when unsupported registers
+ * are accessed..!
+ */
+ if (test_bit(i, ac97->reg_accessed)) {
+ snd_ac97_write(ac97, i, ac97->regs[i]);
+ snd_ac97_read(ac97, i);
+ }
+ }
+}
+
+/*
+ * restore IEC958 status
+ */
+void snd_ac97_restore_iec958(ac97_t *ac97)
+{
+ if (ac97->ext_id & AC97_EI_SPDIF) {
+ if (ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_SPDIF) {
+ /* reset spdif status */
+ snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
+ snd_ac97_write(ac97, AC97_EXTENDED_STATUS, ac97->regs[AC97_EXTENDED_STATUS]);
+ if (ac97->flags & AC97_CS_SPDIF)
+ snd_ac97_write(ac97, AC97_CSR_SPDIF, ac97->regs[AC97_CSR_SPDIF]);
+ else
+ snd_ac97_write(ac97, AC97_SPDIF, ac97->regs[AC97_SPDIF]);
+ snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
+ }
+ }
+}
+
/**
* snd_ac97_resume - General resume function for AC97 codec
* @ac97: the ac97 instance
@@ -2222,7 +2262,7 @@ void snd_ac97_suspend(ac97_t *ac97)
*/
void snd_ac97_resume(ac97_t *ac97)
{
- int i, is_ad18xx, codec;
+ int i;
if (ac97->bus->ops->reset) {
ac97->bus->ops->reset(ac97);
@@ -2264,66 +2304,11 @@ __reset_ready:
if (ac97->bus->ops->init)
ac97->bus->ops->init(ac97);
- is_ad18xx = (ac97->flags & AC97_AD_MULTI);
- if (is_ad18xx) {
- /* restore the AD18xx codec configurations */
- for (codec = 0; codec < 3; codec++) {
- if (! ac97->spec.ad18xx.id[codec])
- continue;
- /* select single codec */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
- ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
- ac97->bus->ops->write(ac97, AC97_AD_CODEC_CFG, ac97->spec.ad18xx.codec_cfg[codec]);
- }
- /* select all codecs */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
- }
-
- /* restore ac97 status */
- for (i = 2; i < 0x7c ; i += 2) {
- if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
- continue;
- /* restore only accessible registers
- * some chip (e.g. nm256) may hang up when unsupported registers
- * are accessed..!
- */
- if (test_bit(i, ac97->reg_accessed)) {
- if (is_ad18xx) {
- /* handle multi codecs for AD18xx */
- if (i == AC97_PCM) {
- for (codec = 0; codec < 3; codec++) {
- if (! ac97->spec.ad18xx.id[codec])
- continue;
- /* select single codec */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
- ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
- /* update PCM bits */
- ac97->bus->ops->write(ac97, AC97_PCM, ac97->spec.ad18xx.pcmreg[codec]);
- }
- /* select all codecs */
- snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
- continue;
- } else if (i == AC97_AD_TEST ||
- i == AC97_AD_CODEC_CFG ||
- i == AC97_AD_SERIAL_CFG)
- continue; /* ignore */
- }
- snd_ac97_write(ac97, i, ac97->regs[i]);
- snd_ac97_read(ac97, i);
- }
- }
-
- if (ac97->ext_id & AC97_EI_SPDIF) {
- if (ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_SPDIF) {
- /* reset spdif status */
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
- snd_ac97_write(ac97, AC97_EXTENDED_STATUS, ac97->regs[AC97_EXTENDED_STATUS]);
- if (ac97->flags & AC97_CS_SPDIF)
- snd_ac97_write(ac97, AC97_CSR_SPDIF, ac97->regs[AC97_CSR_SPDIF]);
- else
- snd_ac97_write(ac97, AC97_SPDIF, ac97->regs[AC97_SPDIF]);
- snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
- }
+ if (ac97->build_ops->resume)
+ ac97->build_ops->resume(ac97);
+ else {
+ snd_ac97_restore_status(ac97);
+ snd_ac97_restore_iec958(ac97);
}
}
#endif
diff --git a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h
index 21b58d759735a1..de412dbe988a23 100644
--- a/sound/pci/ac97/ac97_local.h
+++ b/sound/pci/ac97/ac97_local.h
@@ -49,6 +49,8 @@ int snd_ac97_remove_ctl(ac97_t *ac97, const char *name, const char *suffix);
int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst, const char *suffix);
int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2, const char *suffix);
void snd_ac97_rename_vol_ctl(ac97_t *ac97, const char *src, const char *dst);
+void snd_ac97_restore_status(ac97_t *ac97);
+void snd_ac97_restore_iec958(ac97_t *ac97);
/* ac97_proc.c */
#ifdef CONFIG_PROC_FS
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index a03291b4bcf872..602ab1699c1523 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -775,6 +775,69 @@ int patch_conexant(ac97_t * ac97)
/*
* Analog Device AD18xx, AD19xx codecs
*/
+static void ad18xx_resume(ac97_t *ac97)
+{
+ static unsigned short setup_regs[] = {
+ AC97_AD_MISC, AC97_AD_SERIAL_CFG, AC97_AD_JACK_SPDIF,
+ };
+ int i, codec;
+
+ for (i = 0; i < (int)ARRAY_SIZE(setup_regs); i++) {
+ unsigned short reg = setup_regs[i];
+ if (test_bit(reg, ac97->reg_accessed)) {
+ snd_ac97_write(ac97, reg, ac97->regs[reg]);
+ snd_ac97_read(ac97, reg);
+ }
+ }
+
+ if (! (ac97->flags & AC97_AD_MULTI))
+ /* normal restore */
+ snd_ac97_restore_status(ac97);
+ else {
+ /* restore the AD18xx codec configurations */
+ for (codec = 0; codec < 3; codec++) {
+ if (! ac97->spec.ad18xx.id[codec])
+ continue;
+ /* select single codec */
+ snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
+ ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
+ ac97->bus->ops->write(ac97, AC97_AD_CODEC_CFG, ac97->spec.ad18xx.codec_cfg[codec]);
+ }
+ /* select all codecs */
+ snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
+
+ /* restore status */
+ for (i = 2; i < 0x7c ; i += 2) {
+ if (i == AC97_POWERDOWN || i == AC97_EXTENDED_ID)
+ continue;
+ if (test_bit(i, ac97->reg_accessed)) {
+ /* handle multi codecs for AD18xx */
+ if (i == AC97_PCM) {
+ for (codec = 0; codec < 3; codec++) {
+ if (! ac97->spec.ad18xx.id[codec])
+ continue;
+ /* select single codec */
+ snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
+ ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
+ /* update PCM bits */
+ ac97->bus->ops->write(ac97, AC97_PCM, ac97->spec.ad18xx.pcmreg[codec]);
+ }
+ /* select all codecs */
+ snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
+ continue;
+ } else if (i == AC97_AD_TEST ||
+ i == AC97_AD_CODEC_CFG ||
+ i == AC97_AD_SERIAL_CFG)
+ continue; /* ignore */
+ }
+ snd_ac97_write(ac97, i, ac97->regs[i]);
+ snd_ac97_read(ac97, i);
+ }
+ }
+
+ snd_ac97_restore_iec958(ac97);
+}
+
int patch_ad1819(ac97_t * ac97)
{
unsigned short scfg;
@@ -843,6 +906,10 @@ static void patch_ad1881_chained(ac97_t * ac97, int unchained_idx, int cidx1, in
}
}
+static struct snd_ac97_build_ops patch_ad1881_build_ops = {
+ .resume = &ad18xx_resume
+};
+
int patch_ad1881(ac97_t * ac97)
{
static const char cfg_idxs[3][2] = {
@@ -897,6 +964,7 @@ int patch_ad1881(ac97_t * ac97)
ac97->id &= 0xffff0000;
ac97->id |= ac97->spec.ad18xx.id[0];
}
+ ac97->build_ops = &patch_ad1881_build_ops;
return 0;
}
@@ -919,7 +987,8 @@ static int patch_ad1885_specific(ac97_t * ac97)
}
static struct snd_ac97_build_ops patch_ad1885_build_ops = {
- .build_specific = &patch_ad1885_specific
+ .build_specific = &patch_ad1885_specific,
+ .resume = &ad18xx_resume
};
int patch_ad1885(ac97_t * ac97)
@@ -1013,8 +1082,21 @@ static int patch_ad198x_post_spdif(ac97_t * ac97)
return patch_build_controls(ac97, &snd_ac97_ad198x_spdif_source, 1);
}
+static const snd_kcontrol_new_t snd_ac97_ad1981x_jack_sense[] = {
+ AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 11, 1, 0),
+ AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
+};
+
+static int patch_ad1981a_specific(ac97_t * ac97)
+{
+ return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
+ ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
+}
+
static struct snd_ac97_build_ops patch_ad1981a_build_ops = {
- .build_post_spdif = patch_ad198x_post_spdif
+ .build_post_spdif = patch_ad198x_post_spdif,
+ .build_specific = patch_ad1981a_specific,
+ .resume = ad18xx_resume
};
int patch_ad1981a(ac97_t *ac97)
@@ -1023,6 +1105,7 @@ int patch_ad1981a(ac97_t *ac97)
ac97->build_ops = &patch_ad1981a_build_ops;
snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
ac97->flags |= AC97_STEREO_MUTES;
+ snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); /* HP jack sense */
return 0;
}
@@ -1031,12 +1114,18 @@ AC97_SINGLE("Stereo Mic", AC97_AD_MISC, 6, 1, 0);
static int patch_ad1981b_specific(ac97_t *ac97)
{
- return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
+ int err;
+
+ if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
+ return err;
+ return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
+ ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
}
static struct snd_ac97_build_ops patch_ad1981b_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
- .build_specific = patch_ad1981b_specific
+ .build_specific = patch_ad1981b_specific,
+ .resume = ad18xx_resume
};
int patch_ad1981b(ac97_t *ac97)
@@ -1045,6 +1134,7 @@ int patch_ad1981b(ac97_t *ac97)
ac97->build_ops = &patch_ad1981b_build_ops;
snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
ac97->flags |= AC97_STEREO_MUTES;
+ snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); /* HP jack sense */
return 0;
}
@@ -1150,7 +1240,8 @@ static int patch_ad1888_specific(ac97_t *ac97)
static struct snd_ac97_build_ops patch_ad1888_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
- .build_specific = patch_ad1888_specific
+ .build_specific = patch_ad1888_specific,
+ .resume = ad18xx_resume
};
int patch_ad1888(ac97_t * ac97)
@@ -1184,7 +1275,8 @@ static int patch_ad1980_specific(ac97_t *ac97)
static struct snd_ac97_build_ops patch_ad1980_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
- .build_specific = patch_ad1980_specific
+ .build_specific = patch_ad1980_specific,
+ .resume = ad18xx_resume
};
int patch_ad1980(ac97_t * ac97)
@@ -1210,7 +1302,8 @@ static int patch_ad1985_specific(ac97_t *ac97)
static struct snd_ac97_build_ops patch_ad1985_build_ops = {
.build_post_spdif = patch_ad198x_post_spdif,
- .build_specific = patch_ad1985_specific
+ .build_specific = patch_ad1985_specific,
+ .resume = ad18xx_resume
};
int patch_ad1985(ac97_t * ac97)
@@ -1304,7 +1397,8 @@ static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = {
static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = {
AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0),
AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0),
- AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0),
+ /* disable this controls since it doesn't work as expected */
+ /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */
};
static int patch_alc650_specific(ac97_t * ac97)
@@ -1454,7 +1548,8 @@ static int alc655_iec958_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_
static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = {
AC97_PAGE_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0, 0),
- AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0),
+ /* disable this controls since it doesn't work as expected */
+ /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC958 Playback Route",
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 611ee42eb844ce..7ce2e7631217e5 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -4,7 +4,7 @@
*
* This driver is the result of the OpenVortex Project from Savannah
* (savannah.nongnu.org/projects/openvortex). I would like to thank
- * the developers of OpenVortex, Jeff Muizelar and Kester Maddock, from
+ * the developers of OpenVortex, Jeff Muizelaar and Kester Maddock, from
* whom i got plenty of help, and their codebase was invaluable.
* Thanks to the ALSA developers, they helped a lot working out
* the ALSA part.
@@ -170,9 +170,8 @@ snd_vortex_create(snd_card_t * card, struct pci_dev *pci, vortex_t ** rchip)
if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0)
goto regions_out;
- chip->mmio =
- ioremap_nocache(pci_resource_start(pci, 0),
- pci_resource_len(pci, 0));
+ chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
+ pci_resource_len(pci, 0));
if (!chip->mmio) {
printk(KERN_ERR "MMIO area remap failed.\n");
err = -ENOMEM;
@@ -187,10 +186,9 @@ snd_vortex_create(snd_card_t * card, struct pci_dev *pci, vortex_t ** rchip)
goto core_out;
}
- if ((err =
- request_irq(pci->irq, vortex_interrupt,
- SA_INTERRUPT | SA_SHIRQ, CARD_NAME_SHORT,
- (void *)chip)) != 0) {
+ if ((err = request_irq(pci->irq, vortex_interrupt,
+ SA_INTERRUPT | SA_SHIRQ, CARD_NAME_SHORT,
+ chip)) != 0) {
printk(KERN_ERR "cannot grab irq\n");
goto irq_out;
}
@@ -214,7 +212,6 @@ snd_vortex_create(snd_card_t * card, struct pci_dev *pci, vortex_t ** rchip)
irq_out:
vortex_core_shutdown(chip);
core_out:
- //FIXME: the type of chip->mmio might need to be changed??
iounmap(chip->mmio);
ioremap_out:
pci_release_regions(chip->pci_dev);
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index a300bfdabef250..d573d9c171b1e5 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -80,7 +80,8 @@
#define VORTEX_RESOURCE_LAST 0x00000005
/* Check for SDAC bit in "Extended audio ID" AC97 register */
-#define VORTEX_IS_QUAD(x) ((x->codec == NULL) ? 0 : (x->codec->ext_id&0x80))
+//#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ? 0 : ((x)->codec->ext_id&0x80))
+#define VORTEX_IS_QUAD(x) ((x)->isquad)
/* Check if chip has bug. */
#define IS_BAD_CHIP(x) (\
(x->rev == 0xfe && x->device == PCI_DEVICE_ID_AUREAL_VORTEX_2) || \
@@ -164,6 +165,8 @@ struct snd_vortex {
int xt_mode; /* 1: speakers, 0:headphones. */
#endif
+ int isquad; /* cache of extended ID codec flag. */
+
/* Gameport stuff. */
struct gameport *gameport;
@@ -208,6 +211,7 @@ static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma);
static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma);
static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma);
static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma);
+static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma);
#ifndef CHIP_AU8810
static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma);
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 684f639a20288c..3e4c3e0fb6f676 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -21,7 +21,7 @@
These functions are mainly the result of translations made
from the original disassembly of the au88x0 binary drivers,
written by Aureal before they went down.
- Many thanks to the Jeff Muizelar, Kester Maddock, and whoever
+ Many thanks to the Jeff Muizelaar, Kester Maddock, and whoever
contributed to the OpenVortex project.
The author of this file, put the few available pieces together
and translated the rest of the riddle (Mix, Src and connection stuff).
@@ -1223,6 +1223,33 @@ static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
return delta;
}
+
+static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
+ stream_t *dma = &vortex->dma_adb[adbdma];
+ int p, pp, i;
+
+ /* refresh hw page table */
+ for (i=0 ; i < 4 && i < dma->nr_periods; i++) {
+ /* p: audio buffer page index */
+ p = dma->period_virt + i;
+ if (p >= dma->nr_periods)
+ p -= dma->nr_periods;
+ /* pp: hardware DMA page index. */
+ pp = dma->period_real + i;
+ if (dma->nr_periods < 4) {
+ if (pp >= dma->nr_periods)
+ pp -= dma->nr_periods;
+ }
+ else {
+ if (pp >= 4)
+ pp -= 4;
+ }
+ hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));
+ /* Force write thru cache. */
+ hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
+ }
+}
+
static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
{
stream_t *dma = &vortex->dma_adb[adbdma];
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 9045a4bf193b75..53b47a42c7d805 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -45,6 +45,8 @@
#define VORTEX_EQ_SOURCE (VORTEX_EQ_BASE + 0x430)
#define VORTEX_EQ_CTRL (VORTEX_EQ_BASE + 0x440)
+#define VORTEX_BAND_COEFF_SIZE 0x30
+
/* CEqHw.s */
static void vortex_EqHw_SetTimeConsts(vortex_t * vortex, u16 gain, u16 level)
{
@@ -52,10 +54,10 @@ static void vortex_EqHw_SetTimeConsts(vortex_t * vortex, u16 gain, u16 level)
hwwrite(vortex->mmio, 0x2b3c8, level);
}
-static inline short sign_invert(short a)
+static inline u16 sign_invert(u16 a)
{
/* -(-32768) -> -32768 so we do -(-32768) -> 32767 to make the result positive */
- if (a == -32768)
+ if (a == (u16)-32768)
return 32767;
else
return -a;
@@ -71,13 +73,13 @@ static void vortex_EqHw_SetLeftCoefs(vortex_t * vortex, u16 coefs[])
hwwrite(vortex->mmio, 0x2b004 + n * 0x30, coefs[i + 1]);
if (eqhw->this08 == 0) {
- hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2] & 0xffff);
- hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3] & 0xffff);
- hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4] & 0xffff);
+ hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2]);
+ hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3]);
+ hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4]);
} else {
- hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i]) & 0xffff);
- hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i]) & 0xffff);
- hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i]) & 0xffff);
+ hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i]));
+ hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i]));
+ hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i]));
}
i += 5;
}
@@ -93,13 +95,13 @@ static void vortex_EqHw_SetRightCoefs(vortex_t * vortex, u16 coefs[])
hwwrite(vortex->mmio, 0x2b1e4 + n * 0x30, coefs[1 + i]);
if (eqhw->this08 == 0) {
- hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i] & 0xffff);
- hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i] & 0xffff);
- hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i] & 0xffff);
+ hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i]);
+ hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i]);
+ hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i]);
} else {
- hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i]) & 0xffff);
- hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i]) & 0xffff);
- hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i]) & 0xffff);
+ hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i]));
+ hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i]));
+ hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i]));
}
i += 5;
}
@@ -176,8 +178,8 @@ static void vortex_EqHw_SetBypassGain(vortex_t * vortex, u16 a, u16 b)
hwwrite(vortex->mmio, 0x2b3d4, a);
hwwrite(vortex->mmio, 0x2b3ec, b);
} else {
- hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a) & 0xffff);
- hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b) & 0xffff);
+ hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a));
+ hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b));
}
}
@@ -319,25 +321,27 @@ static void vortex_EqHw_GetRightGainsCurrent(vortex_t * vortex, u16 a[])
#endif
/* EQ band levels settings */
-static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 a[])
+static void vortex_EqHw_SetLevels(vortex_t * vortex, u16 peaks[])
{
eqhw_t *eqhw = &(vortex->eq.this04);
- int ebx;
+ int i;
- for (ebx = 0; ebx < eqhw->this04; ebx++) {
- hwwrite(vortex->mmio, 0x2b024 + ebx * 0x30, a[ebx]);
+ /* set left peaks */
+ for (i = 0; i < eqhw->this04; i++) {
+ hwwrite(vortex->mmio, 0x2b024 + i * VORTEX_BAND_COEFF_SIZE, peaks[i]);
}
- hwwrite(vortex->mmio, 0x2b3cc, a[eqhw->this04]);
- hwwrite(vortex->mmio, 0x2b3d8, a[eqhw->this04 + 1]);
+ hwwrite(vortex->mmio, 0x2b3cc, peaks[eqhw->this04]);
+ hwwrite(vortex->mmio, 0x2b3d8, peaks[eqhw->this04 + 1]);
- for (ebx = 0; ebx < eqhw->this04; ebx++) {
- hwwrite(vortex->mmio, 0x2b204 + ebx * 0x30,
- a[ebx + (eqhw->this04 + 2)]);
+ /* set right peaks */
+ for (i = 0; i < eqhw->this04; i++) {
+ hwwrite(vortex->mmio, 0x2b204 + i * VORTEX_BAND_COEFF_SIZE,
+ peaks[i + (eqhw->this04 + 2)]);
}
- hwwrite(vortex->mmio, 0x2b3e4, a[2 + (eqhw->this04 * 2)]);
- hwwrite(vortex->mmio, 0x2b3f0, a[3 + (eqhw->this04 * 2)]);
+ hwwrite(vortex->mmio, 0x2b3e4, peaks[2 + (eqhw->this04 * 2)]);
+ hwwrite(vortex->mmio, 0x2b3f0, peaks[3 + (eqhw->this04 * 2)]);
}
#if 0
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
index 477b2d15ba5e74..95ed26ead5c516 100644
--- a/sound/pci/au88x0/au88x0_mixer.c
+++ b/sound/pci/au88x0/au88x0_mixer.c
@@ -26,5 +26,7 @@ static int __devinit snd_vortex_mixer(vortex_t * vortex)
memset(&ac97, 0, sizeof(ac97));
// Intialize AC97 codec stuff.
ac97.private_data = vortex;
- return snd_ac97_mixer(pbus, &ac97, &vortex->codec);
+ err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
+ vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80));
+ return err;
}
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 8e6322158858d1..c9dfc32cc3ea05 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -313,8 +313,10 @@ static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
// do something to start the PCM engine
//printk(KERN_INFO "vortex: start %d\n", dma);
stream->fifo_enabled = 1;
- if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
+ if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
+ vortex_adbdma_resetup(chip, dma);
vortex_adbdma_startfifo(chip, dma);
+ }
#ifndef CHIP_AU8810
else {
printk(KERN_INFO "vortex: wt start %d\n", dma);
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 02c835a31604aa..7e2dee3488cf6e 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -214,17 +214,17 @@ static struct pci_device_id snd_azf3328_ids[] = {
MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
-void snd_azf3328_io2_write(azf3328_t *chip, int reg, unsigned char value)
+static void snd_azf3328_io2_write(azf3328_t *chip, int reg, unsigned char value)
{
outb(value, chip->io2_port + reg);
}
-unsigned char snd_azf3328_io2_read(azf3328_t *chip, int reg)
+static unsigned char snd_azf3328_io2_read(azf3328_t *chip, int reg)
{
return inb(chip->io2_port + reg);
}
-void snd_azf3328_mixer_write(azf3328_t *chip, int reg, unsigned long value, int type)
+static void snd_azf3328_mixer_write(azf3328_t *chip, int reg, unsigned long value, int type)
{
switch(type) {
case WORD_VALUE:
@@ -239,26 +239,7 @@ void snd_azf3328_mixer_write(azf3328_t *chip, int reg, unsigned long value, int
}
}
-unsigned long snd_azf3328_mixer_read(azf3328_t *chip, int reg, int type)
-{
- unsigned long res = 0;
-
- switch(type) {
- case WORD_VALUE:
- res = (unsigned long)inw(chip->mixer_port + reg);
- break;
- case DWORD_VALUE:
- res = (unsigned long)inl(chip->mixer_port + reg);
- break;
- case BYTE_VALUE:
- res = (unsigned long)inb(chip->mixer_port + reg);
- break;
- }
-
- return res;
-}
-
-void snd_azf3328_mixer_set_mute(azf3328_t *chip, int reg, int do_mute)
+static void snd_azf3328_mixer_set_mute(azf3328_t *chip, int reg, int do_mute)
{
unsigned char oldval;
@@ -272,7 +253,7 @@ void snd_azf3328_mixer_set_mute(azf3328_t *chip, int reg, int do_mute)
outb(oldval, chip->mixer_port + reg + 1);
}
-void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
+static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
{
unsigned char curr_vol_left = 0, curr_vol_right = 0;
int left_done = 0, right_done = 0;
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 83b7546ee6fd88..a850d709a11eca 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -45,6 +45,7 @@ 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_PNP; /* Enable this card */
static int digital_rate[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* digital input rate */
+static int load_all; /* allow to load the non-whitelisted cards */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Bt87x soundcard");
@@ -54,6 +55,8 @@ module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable Bt87x soundcard");
module_param_array(digital_rate, int, NULL, 0444);
MODULE_PARM_DESC(digital_rate, "Digital input rate for Bt87x soundcard");
+module_param(load_all, bool, 0444);
+MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards");
#ifndef PCI_VENDOR_ID_BROOKTREE
@@ -173,7 +176,11 @@ struct snd_bt87x {
unsigned int lines;
u32 reg_control;
+ u32 interrupt_mask;
+
int current_line;
+
+ int pci_parity_errors;
};
enum { DEVICE_DIGITAL, DEVICE_ANALOG };
@@ -246,33 +253,53 @@ static void snd_bt87x_free_risc(bt87x_t *chip)
}
}
+static void snd_bt87x_pci_error(bt87x_t *chip, unsigned int status)
+{
+ u16 pci_status;
+
+ pci_read_config_word(chip->pci, PCI_STATUS, &pci_status);
+ pci_status &= PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
+ PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
+ PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY;
+ pci_write_config_word(chip->pci, PCI_STATUS, pci_status);
+ if (pci_status != PCI_STATUS_DETECTED_PARITY)
+ snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n",
+ status & ERROR_INTERRUPTS, pci_status);
+ else {
+ snd_printk(KERN_ERR "Aieee - PCI parity error detected!\n");
+ /* error 'handling' similar to aic7xxx_pci.c: */
+ chip->pci_parity_errors++;
+ if (chip->pci_parity_errors > 20) {
+ snd_printk(KERN_ERR "Too many PCI parity errors observed.\n");
+ snd_printk(KERN_ERR "Some device on this bus is generating bad parity.\n");
+ snd_printk(KERN_ERR "This is an error *observed by*, not *generated by*, this card.\n");
+ snd_printk(KERN_ERR "PCI parity error checking has been disabled.\n");
+ chip->interrupt_mask &= ~(INT_PPERR | INT_RIPERR);
+ snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
+ }
+ }
+}
+
static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
bt87x_t *chip = dev_id;
- unsigned int status;
+ unsigned int status, irq_status;
status = snd_bt87x_readl(chip, REG_INT_STAT);
- if (!(status & MY_INTERRUPTS))
+ irq_status = status & chip->interrupt_mask;
+ if (!irq_status)
return IRQ_NONE;
- snd_bt87x_writel(chip, REG_INT_STAT, status & MY_INTERRUPTS);
+ snd_bt87x_writel(chip, REG_INT_STAT, irq_status);
- if (status & ERROR_INTERRUPTS) {
- if (status & (INT_FBUS | INT_FTRGT))
+ if (irq_status & ERROR_INTERRUPTS) {
+ if (irq_status & (INT_FBUS | INT_FTRGT))
snd_printk(KERN_WARNING "FIFO overrun, status %#08x\n", status);
- if (status & INT_OCERR)
+ if (irq_status & INT_OCERR)
snd_printk(KERN_ERR "internal RISC error, status %#08x\n", status);
- if (status & (INT_PPERR | INT_RIPERR | INT_PABORT)) {
- u16 pci_status;
- pci_read_config_word(chip->pci, PCI_STATUS, &pci_status);
- pci_write_config_word(chip->pci, PCI_STATUS, pci_status &
- (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
- PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
- PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));
- snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n",
- status, pci_status);
- }
+ if (irq_status & (INT_PPERR | INT_RIPERR | INT_PABORT))
+ snd_bt87x_pci_error(chip, irq_status);
}
- if ((status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) {
+ if ((irq_status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) {
int current_block, irq_block;
/* assume that exactly one line has been recorded */
@@ -458,7 +485,7 @@ static int snd_bt87x_start(bt87x_t *chip)
snd_bt87x_writel(chip, REG_RISC_STRT_ADD, chip->dma_risc.addr);
snd_bt87x_writel(chip, REG_PACKET_LEN,
chip->line_bytes | (chip->lines << 16));
- snd_bt87x_writel(chip, REG_INT_MASK, MY_INTERRUPTS);
+ snd_bt87x_writel(chip, REG_INT_MASK, chip->interrupt_mask);
snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
spin_unlock(&chip->reg_lock);
return 0;
@@ -717,6 +744,7 @@ static int __devinit snd_bt87x_create(snd_card_t *card,
}
chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT);
+ chip->interrupt_mask = MY_INTERRUPTS;
snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
snd_bt87x_writel(chip, REG_INT_MASK, 0);
snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
@@ -741,13 +769,73 @@ static int __devinit snd_bt87x_create(snd_card_t *card,
return 0;
}
+#define BT_DEVICE(chip, subvend, subdev, rate) \
+ { .vendor = PCI_VENDOR_ID_BROOKTREE, \
+ .device = PCI_DEVICE_ID_BROOKTREE_##chip, \
+ .subvendor = subvend, .subdevice = subdev, \
+ .driver_data = rate }
+
+/* driver_data is the default digital_rate value for that device */
+static struct pci_device_id snd_bt87x_ids[] = {
+ BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
+ BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */
+ BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */
+ { }
+};
+MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
+
+/* cards known not to have audio
+ * (DVB cards use the audio function to transfer MPEG data) */
+static struct {
+ unsigned short subvendor, subdevice;
+} blacklist[] __devinitdata = {
+ {0x0071, 0x0101}, /* Nebula Electronics DigiTV */
+ {0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */
+ {0x1461, 0x0761}, /* AVermedia AverTV DVB-T */
+ {0x1461, 0x0771}, /* AVermedia DVB-T 771 */
+ {0x1822, 0x0001}, /* Twinhan VisionPlus DVB-T */
+ {0x18ac, 0xdb10}, /* DVICO FusionHDTV DVB-T Lite */
+ {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */
+};
+
+/* return the rate of the card, or a negative value if it's blacklisted */
+static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
+{
+ int i;
+ const struct pci_device_id *supported;
+
+ supported = pci_match_device(snd_bt87x_ids, pci);
+ if (supported)
+ return supported->driver_data;
+
+ for (i = 0; i < ARRAY_SIZE(blacklist); ++i)
+ if (blacklist[i].subvendor == pci->subsystem_vendor &&
+ blacklist[i].subdevice == pci->subsystem_device) {
+ snd_printdd(KERN_INFO "card %#04x:%#04x has no audio\n",
+ pci->subsystem_vendor, pci->subsystem_device);
+ return -EBUSY;
+ }
+
+ snd_printk(KERN_INFO "unknown card %#04x:%#04x, using default rate 32000\n",
+ pci->subsystem_vendor, pci->subsystem_device);
+ snd_printk(KERN_DEBUG "please mail id, board name, and, "
+ "if it works, the correct digital_rate option to "
+ "<alsa-devel@lists.sf.net>\n");
+ return 32000; /* default rate */
+}
+
static int __devinit snd_bt87x_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
static int dev;
snd_card_t *card;
bt87x_t *chip;
- int err;
+ int err, rate;
+
+ rate = pci_id->driver_data;
+ if (! rate)
+ if ((rate = snd_bt87x_detect_card(pci)) <= 0)
+ return -ENODEV;
if (dev >= SNDRV_CARDS)
return -ENODEV;
@@ -767,7 +855,7 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci,
if (digital_rate[dev] > 0)
chip->dig_rate = digital_rate[dev];
else
- chip->dig_rate = (int)pci_id->driver_data;
+ chip->dig_rate = rate;
err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
if (err < 0)
@@ -811,22 +899,13 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
-#define BT_DEVICE(chip, subvend, subdev, rate) \
- { .vendor = PCI_VENDOR_ID_BROOKTREE, \
- .device = PCI_DEVICE_ID_BROOKTREE_##chip, \
- .subvendor = subvend, .subdevice = subdev, \
- .driver_data = rate }
-
-/* driver_data is the default digital_rate value for that device */
-static struct pci_device_id snd_bt87x_ids[] = {
- BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Osprey 200 */
-
- /* default entries for 32kHz and generic Bt87x cards */
- BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 32000),
- BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 32000),
+/* default entries for all Bt87x cards - it's not exported */
+/* driver_data is set to 0 to call detection */
+static struct pci_device_id snd_bt87x_default_ids[] = {
+ BT_DEVICE(878, PCI_ANY_ID, PCI_ANY_ID, 0),
+ BT_DEVICE(879, PCI_ANY_ID, PCI_ANY_ID, 0),
{ }
};
-MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
static struct pci_driver driver = {
.name = "Bt87x",
@@ -837,6 +916,8 @@ static struct pci_driver driver = {
static int __init alsa_card_bt87x_init(void)
{
+ if (load_all)
+ driver.id_table = snd_bt87x_default_ids;
return pci_module_init(&driver);
}
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 565c45b5a0e278..d85f78c42f086d 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -68,6 +68,20 @@
static void amp_voyetra(cs46xx_t *chip, int change);
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+static snd_pcm_ops_t snd_cs46xx_playback_rear_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops;
+#endif
+
+static snd_pcm_ops_t snd_cs46xx_playback_ops;
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops;
+static snd_pcm_ops_t snd_cs46xx_capture_ops;
+static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops;
+
static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip,
unsigned short reg,
int codec_index)
@@ -1446,7 +1460,7 @@ static int snd_cs46xx_capture_close(snd_pcm_substream_t * substream)
}
#ifdef CONFIG_SND_CS46XX_NEW_DSP
-snd_pcm_ops_t snd_cs46xx_playback_rear_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_rear_ops = {
.open = snd_cs46xx_playback_open_rear,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1457,7 +1471,7 @@ snd_pcm_ops_t snd_cs46xx_playback_rear_ops = {
.pointer = snd_cs46xx_playback_direct_pointer,
};
-snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops = {
.open = snd_cs46xx_playback_open_rear,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1469,7 +1483,7 @@ snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops = {
.ack = snd_cs46xx_playback_transfer,
};
-snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = {
.open = snd_cs46xx_playback_open_clfe,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1480,7 +1494,7 @@ snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = {
.pointer = snd_cs46xx_playback_direct_pointer,
};
-snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = {
.open = snd_cs46xx_playback_open_clfe,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1492,7 +1506,7 @@ snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = {
.ack = snd_cs46xx_playback_transfer,
};
-snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = {
.open = snd_cs46xx_playback_open_iec958,
.close = snd_cs46xx_playback_close_iec958,
.ioctl = snd_pcm_lib_ioctl,
@@ -1503,7 +1517,7 @@ snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = {
.pointer = snd_cs46xx_playback_direct_pointer,
};
-snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops = {
.open = snd_cs46xx_playback_open_iec958,
.close = snd_cs46xx_playback_close_iec958,
.ioctl = snd_pcm_lib_ioctl,
@@ -1517,7 +1531,7 @@ snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops = {
#endif
-snd_pcm_ops_t snd_cs46xx_playback_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_ops = {
.open = snd_cs46xx_playback_open,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1528,7 +1542,7 @@ snd_pcm_ops_t snd_cs46xx_playback_ops = {
.pointer = snd_cs46xx_playback_direct_pointer,
};
-snd_pcm_ops_t snd_cs46xx_playback_indirect_ops = {
+static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops = {
.open = snd_cs46xx_playback_open,
.close = snd_cs46xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1540,7 +1554,7 @@ snd_pcm_ops_t snd_cs46xx_playback_indirect_ops = {
.ack = snd_cs46xx_playback_transfer,
};
-snd_pcm_ops_t snd_cs46xx_capture_ops = {
+static snd_pcm_ops_t snd_cs46xx_capture_ops = {
.open = snd_cs46xx_capture_open,
.close = snd_cs46xx_capture_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1551,7 +1565,7 @@ snd_pcm_ops_t snd_cs46xx_capture_ops = {
.pointer = snd_cs46xx_capture_direct_pointer,
};
-snd_pcm_ops_t snd_cs46xx_capture_indirect_ops = {
+static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops = {
.open = snd_cs46xx_capture_open,
.close = snd_cs46xx_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
index 52575f92472004..d7bec096d247fb 100644
--- a/sound/pci/cs46xx/cs46xx_lib.h
+++ b/sound/pci/cs46xx/cs46xx_lib.h
@@ -53,18 +53,6 @@
#define BA1_DWORD_SIZE (13 * 1024 + 512)
#define BA1_MEMORY_COUNT 3
-extern snd_pcm_ops_t snd_cs46xx_playback_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_indirect_ops;
-extern snd_pcm_ops_t snd_cs46xx_capture_ops;
-extern snd_pcm_ops_t snd_cs46xx_capture_indirect_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_rear_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_iec958_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_clfe_ops;
-extern snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops;
-
-
/*
* common I/O routines
*/
@@ -99,11 +87,9 @@ dsp_spos_instance_t * cs46xx_dsp_spos_create (cs46xx_t * chip);
void cs46xx_dsp_spos_destroy (cs46xx_t * chip);
int cs46xx_dsp_load_module (cs46xx_t * chip,dsp_module_desc_t * module);
symbol_entry_t * cs46xx_dsp_lookup_symbol (cs46xx_t * chip,char * symbol_name,int symbol_type);
-symbol_entry_t * cs46xx_dsp_lookup_symbol_addr (cs46xx_t * chip,u32 address,int symbol_type);
int cs46xx_dsp_proc_init (snd_card_t * card, cs46xx_t *chip);
int cs46xx_dsp_proc_done (cs46xx_t *chip);
int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip);
-int cs46xx_dsp_async_init (cs46xx_t *chip,dsp_scb_descriptor_t * fg_entry);
int snd_cs46xx_download (cs46xx_t *chip,u32 *src,unsigned long offset,
unsigned long len);
int snd_cs46xx_clear_BA1(cs46xx_t *chip,unsigned long offset,unsigned long len);
@@ -120,8 +106,6 @@ int cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data)
dsp_scb_descriptor_t * cs46xx_dsp_create_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest);
void cs46xx_dsp_proc_free_scb_desc (dsp_scb_descriptor_t * scb);
void cs46xx_dsp_proc_register_scb_desc (cs46xx_t *chip,dsp_scb_descriptor_t * scb);
-dsp_task_descriptor_t * cs46xx_dsp_create_task_tree (cs46xx_t *chip,char * name,
- u32 * task_data,u32 dest,int size);
dsp_scb_descriptor_t * cs46xx_dsp_create_timing_master_scb (cs46xx_t *chip);
dsp_scb_descriptor_t * cs46xx_dsp_create_codec_out_scb(cs46xx_t * chip,char * codec_name,
u16 channel_disp,u16 fifo_addr,
@@ -136,21 +120,11 @@ dsp_scb_descriptor_t * cs46xx_dsp_create_codec_in_scb(cs46xx_t * chip,char * cod
dsp_scb_descriptor_t * parent_scb,
int scb_child_type);
void cs46xx_dsp_remove_scb (cs46xx_t *chip,dsp_scb_descriptor_t * scb);
-dsp_scb_descriptor_t * cs46xx_dsp_create_generic_scb (cs46xx_t *chip,char * name,
- u32 * scb_data,u32 dest,
- char * task_entry_name,
- dsp_scb_descriptor_t * parent_scb,
- int scb_child_type);
dsp_scb_descriptor_t * cs46xx_dsp_create_codec_in_scb(cs46xx_t * chip,char * codec_name,
u16 channel_disp,u16 fifo_addr,
u16 sample_buffer_addr,
u32 dest,dsp_scb_descriptor_t * parent_scb,
int scb_child_type);
-dsp_scb_descriptor_t * cs46xx_dsp_create_pcm_reader_scb(cs46xx_t * chip,char * scb_name,
- u16 sample_buffer_addr,u32 dest,
- int virtual_channel,u32 playback_hw_addr,
- dsp_scb_descriptor_t * parent_scb,
- int scb_child_type);
dsp_scb_descriptor_t * cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
int sample_rate,
u16 src_buffer_addr,
@@ -169,15 +143,6 @@ dsp_scb_descriptor_t * cs46xx_dsp_create_vari_decimate_scb(cs46xx_t * chip,char
u32 dest,
dsp_scb_descriptor_t * parent_scb,
int scb_child_type);
-dsp_scb_descriptor_t * cs46xx_dsp_create_pcm_serial_input_scb(cs46xx_t * chip,char * scb_name,u32 dest,
- dsp_scb_descriptor_t * input_scb,
- dsp_scb_descriptor_t * parent_scb,
- int scb_child_type);
-dsp_scb_descriptor_t * cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
- u16 hfg_scb_address,
- u16 asynch_buffer_address,
- dsp_scb_descriptor_t * parent_scb,
- int scb_child_type);
dsp_scb_descriptor_t * cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
u16 hfg_scb_address,
u16 asynch_buffer_address,
@@ -190,11 +155,6 @@ dsp_scb_descriptor_t * cs46xx_dsp_create_mix_to_ostream_scb(cs46xx_t * chip,cha
u16 mix_buffer_addr,u16 writeback_spb,u32 dest,
dsp_scb_descriptor_t * parent_scb,
int scb_child_type);
-dsp_scb_descriptor_t * cs46xx_dsp_create_output_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
- u16 snoop_buffer_address,
- dsp_scb_descriptor_t * snoop_scb,
- dsp_scb_descriptor_t * parent_scb,
- int scb_child_type);
dsp_scb_descriptor_t * cs46xx_dsp_create_magic_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
u16 snoop_buffer_address,
dsp_scb_descriptor_t * snoop_scb,
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index 0f3ab7a96969d4..ce79f3933c2a46 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -37,6 +37,8 @@
#include "cs46xx_lib.h"
#include "dsp_spos.h"
+static int cs46xx_dsp_async_init (cs46xx_t *chip, dsp_scb_descriptor_t * fg_entry);
+
static wide_opcode_t wide_opcodes[] = {
WIDE_FOR_BEGIN_LOOP,
WIDE_FOR_BEGIN_LOOP2,
@@ -439,7 +441,7 @@ symbol_entry_t * cs46xx_dsp_lookup_symbol (cs46xx_t * chip, char * symbol_name,
}
-symbol_entry_t * cs46xx_dsp_lookup_symbol_addr (cs46xx_t * chip, u32 address, int symbol_type)
+static symbol_entry_t * cs46xx_dsp_lookup_symbol_addr (cs46xx_t * chip, u32 address, int symbol_type)
{
int i;
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
@@ -914,7 +916,7 @@ static void _dsp_create_task_tree (cs46xx_t *chip,u32 * task_data, u32 dest, in
int i;
for (i = 0; i < size; ++i) {
- if (debug_tree) printk ("addr %p, val %08x\n", spdst,task_data[i]);
+ if (debug_tree) printk ("addr %p, val %08x\n",spdst,task_data[i]);
writel(task_data[i],spdst);
spdst += sizeof(u32);
}
@@ -928,7 +930,7 @@ static void _dsp_create_scb (cs46xx_t *chip,u32 * scb_data, u32 dest)
int i;
for (i = 0; i < 0x10; ++i) {
- if (debug_scb) printk ("addr %p, val %08x\n", spdst,scb_data[i]);
+ if (debug_scb) printk ("addr %p, val %08x\n",spdst,scb_data[i]);
writel(scb_data[i],spdst);
spdst += sizeof(u32);
}
@@ -1019,7 +1021,7 @@ dsp_scb_descriptor_t * cs46xx_dsp_create_scb (cs46xx_t *chip,char * name, u32 *
}
-dsp_task_descriptor_t * cs46xx_dsp_create_task_tree (cs46xx_t *chip,char * name, u32 * task_data,u32 dest,int size)
+static dsp_task_descriptor_t * cs46xx_dsp_create_task_tree (cs46xx_t *chip,char * name, u32 * task_data,u32 dest,int size)
{
dsp_task_descriptor_t * desc;
@@ -1452,7 +1454,7 @@ int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip)
return -EINVAL;
}
-int cs46xx_dsp_async_init (cs46xx_t *chip, dsp_scb_descriptor_t * fg_entry)
+static int cs46xx_dsp_async_init (cs46xx_t *chip, dsp_scb_descriptor_t * fg_entry)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
symbol_entry_t * s16_async_codec_input_task;
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index acd0db847e72b8..92849e1340bbfb 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -342,7 +342,7 @@ _dsp_create_generic_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest,
return scb;
}
-dsp_scb_descriptor_t *
+static dsp_scb_descriptor_t *
cs46xx_dsp_create_generic_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest,
char * task_entry_name,
dsp_scb_descriptor_t * parent_scb,
@@ -481,7 +481,7 @@ cs46xx_dsp_create_codec_in_scb(cs46xx_t * chip,char * codec_name,
}
-dsp_scb_descriptor_t *
+static dsp_scb_descriptor_t *
cs46xx_dsp_create_pcm_reader_scb(cs46xx_t * chip,char * scb_name,
u16 sample_buffer_addr,u32 dest,
int virtual_channel, u32 playback_hw_addr,
@@ -687,6 +687,7 @@ cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
return scb;
}
+#if 0 /* not used */
dsp_scb_descriptor_t *
cs46xx_dsp_create_filter_scb(cs46xx_t * chip,char * scb_name,
u16 buffer_addr,u32 dest,
@@ -735,6 +736,7 @@ cs46xx_dsp_create_filter_scb(cs46xx_t * chip,char * scb_name,
return scb;
}
+#endif /* not used */
dsp_scb_descriptor_t *
cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name,
@@ -874,7 +876,7 @@ cs46xx_dsp_create_vari_decimate_scb(cs46xx_t * chip,char * scb_name,
}
-dsp_scb_descriptor_t *
+static dsp_scb_descriptor_t *
cs46xx_dsp_create_pcm_serial_input_scb(cs46xx_t * chip,char * scb_name,u32 dest,
dsp_scb_descriptor_t * input_scb,
dsp_scb_descriptor_t * parent_scb,
@@ -917,7 +919,7 @@ cs46xx_dsp_create_pcm_serial_input_scb(cs46xx_t * chip,char * scb_name,u32 dest,
}
-dsp_scb_descriptor_t *
+static dsp_scb_descriptor_t *
cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
u16 hfg_scb_address,
u16 asynch_buffer_address,
@@ -1013,6 +1015,7 @@ cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
}
+#if 0 /* not used */
dsp_scb_descriptor_t *
cs46xx_dsp_create_output_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
u16 snoop_buffer_address,
@@ -1052,6 +1055,7 @@ cs46xx_dsp_create_output_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
scb_child_type);
return scb;
}
+#endif /* not used */
dsp_scb_descriptor_t *
diff --git a/sound/pci/cs46xx/imgs/cwcdma.h b/sound/pci/cs46xx/imgs/cwcdma.h
index 7b6e65be328ed8..92860435beed44 100644
--- a/sound/pci/cs46xx/imgs/cwcdma.h
+++ b/sound/pci/cs46xx/imgs/cwcdma.h
@@ -3,7 +3,7 @@
#ifndef __HEADER_cwcdma_H__
#define __HEADER_cwcdma_H__
-symbol_entry_t cwcdma_symbols[] = {
+static symbol_entry_t cwcdma_symbols[] = {
{ 0x8000, "EXECCHILD",0x03 },
{ 0x8001, "EXECCHILD_98",0x03 },
{ 0x8003, "EXECCHILD_PUSH1IND",0x03 },
@@ -33,7 +33,7 @@ symbol_entry_t cwcdma_symbols[] = {
{ 0x0018, "#CODE_END",0x00 },
}; /* cwcdma symbols */
-u32 cwcdma_code[] = {
+static u32 cwcdma_code[] = {
/* OVERLAYBEGINADDRESS */
/* 0000 */ 0x00002731,0x00001400,0x0004c108,0x000e5044,
/* 0002 */ 0x0005f608,0x00000000,0x000007ae,0x000be300,
@@ -51,11 +51,11 @@ u32 cwcdma_code[] = {
/* #CODE_END */
-segment_desc_t cwcdma_segments[] = {
+static segment_desc_t cwcdma_segments[] = {
{ SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000030, cwcdma_code },
};
-dsp_module_desc_t cwcdma_module = {
+static dsp_module_desc_t cwcdma_module = {
"cwcdma",
{
27,
diff --git a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile
index cdcb408c20f265..348a92c37768fc 100644
--- a/sound/pci/emu10k1/Makefile
+++ b/sound/pci/emu10k1/Makefile
@@ -5,7 +5,7 @@
snd-emu10k1-objs := emu10k1.o emu10k1_main.o \
irq.o memory.o voice.o emumpu401.o emupcm.o io.o \
- emuproc.o emumixer.o emufx.o
+ emuproc.o emumixer.o emufx.o timer.o
snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o
#
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 2f22d03a91eee6..20165abbf7ebdd 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -2,6 +2,9 @@
* The driver for the EMU10K1 (SB Live!) based soundcards
* Copyright (c) by Jaroslav Kysela <perex@suse.cz>
*
+ * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
+ * Added support for Audigy 2 Value.
+ *
*
* 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
@@ -17,6 +20,7 @@
* 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>
@@ -68,12 +72,27 @@ MODULE_PARM_DESC(max_buffer_size, "Maximum sample buffer size in MB.");
module_param_array(enable_ir, bool, NULL, 0444);
MODULE_PARM_DESC(enable_ir, "Enable IR.");
+/*
+ * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
+ */
static struct pci_device_id snd_emu10k1_ids[] = {
{ 0x1102, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* EMU10K1 */
{ 0x1102, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy */
+ { 0x1102, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy 2 Value SB0400 */
{ 0, }
};
+/*
+ * Audigy 2 Value notes:
+ * A_IOCFG Input (GPIO)
+ * 0x400 = Front analog jack plugged in. (Green socket)
+ * 0x1000 = Read analog jack plugged in. (Black socket)
+ * 0x2000 = Center/LFE analog jack plugged in. (Orange socket)
+ * A_IOCFG Output (GPIO)
+ * 0x60 = Sound out of front Left.
+ * Win sets it to 0xXX61
+ */
+
MODULE_DEVICE_TABLE(pci, snd_emu10k1_ids);
static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
@@ -124,6 +143,12 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
snd_card_free(card);
return err;
}
+
+ if ((err = snd_emu10k1_timer(emu, 0)) < 0) {
+ snd_card_free(card);
+ return err;
+ }
+
if (emu->audigy) {
if ((err = snd_emu10k1_audigy_midi(emu)) < 0) {
snd_card_free(card);
@@ -155,7 +180,10 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
}
#endif
- if (emu->audigy && (emu->revision == 4) ) {
+ if (emu->audigy && (emu->serial == 0x10011102) ) {
+ strcpy(card->driver, "Audigy2");
+ strcpy(card->shortname, "Sound Blaster Audigy2_Value");
+ } else if (emu->audigy && (emu->revision == 4) ) {
strcpy(card->driver, "Audigy2");
strcpy(card->shortname, "Sound Blaster Audigy2");
} else if (emu->audigy) {
@@ -168,7 +196,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
strcpy(card->driver, "EMU10K1");
strcpy(card->shortname, "Sound Blaster Live!");
}
- sprintf(card->longname, "%s (rev.%d) at 0x%lx, irq %i", card->shortname, emu->revision, emu->port, emu->irq);
+ sprintf(card->longname, "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", card->shortname, emu->revision, emu->serial, emu->port, emu->irq);
if ((err = snd_card_register(card)) < 0) {
snd_card_free(card);
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 45f3ceda5c3c41..cb406e3024a9d8 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -3,6 +3,10 @@
* Creative Labs, Inc.
* Routines for control of EMU10K1 chips
*
+ * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
+ * Added support for Audigy 2 Value.
+ *
+ *
* BUGS:
* --
*
@@ -183,6 +187,26 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir)
outl(0x6E0000, emu->port + 0x20);
outl(0xFF00FF00, emu->port + 0x24);
}
+ if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */
+ /* Hacks for Alice3 to work independent of haP16V driver */
+ u32 tmp;
+
+ snd_printk(KERN_ERR "Audigy2 value:Special config.\n");
+ //Setup SRCMulti_I2S SamplingRate
+ tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
+ tmp &= 0xfffff1ff;
+ tmp |= (0x2<<9);
+ snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
+
+ /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
+ outl(0x600000, emu->port + 0x20);
+ outl(0x14, emu->port + 0x24);
+
+ /* Setup SRCMulti Input Audio Enable */
+ outl(0x7b0000, emu->port + 0x20);
+ outl(0xFF000000, emu->port + 0x24);
+ }
+
/*
* Clear page with silence & setup all pointers to this page
@@ -267,6 +291,9 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir)
* This has to be done after init ALice3 I2SOut beyond 48KHz.
* So, sequence is important. */
outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
+ } else if (emu->serial == 0x10011102) { /* audigy2 value */
+ /* Unmute Analog now. */
+ outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
} else {
/* Disable routing from AC97 line out to Front speakers */
outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
@@ -590,7 +617,7 @@ int __devinit snd_emu10k1_create(snd_card_t * card,
*remu = NULL;
// is_audigy = (int)pci->driver_data;
- is_audigy = (pci->device == 0x0004);
+ is_audigy = (pci->device == 0x0004) || ( (pci->device == 0x0008) );
/* enable PCI device */
if ((err = pci_enable_device(pci)) < 0)
@@ -689,7 +716,7 @@ int __devinit snd_emu10k1_create(snd_card_t * card,
emu->no_ac97 = 1;
}
- if (emu->revision == 4 && emu->model == 0x2002) {
+ if (emu->revision == 4 && (emu->model == 0x2001 || emu->model == 0x2002)) {
/* Audigy 2 ZS */
snd_printdd(KERN_INFO "Audigy2 ZS is detected. setting 7.1 mode.\n");
emu->spk71 = 1;
diff --git a/sound/pci/emu10k1/emu10k1_synth.c b/sound/pci/emu10k1/emu10k1_synth.c
index 2af8ffa6b9a600..8bd58d1dcc2642 100644
--- a/sound/pci/emu10k1/emu10k1_synth.c
+++ b/sound/pci/emu10k1/emu10k1_synth.c
@@ -28,7 +28,7 @@ MODULE_LICENSE("GPL");
/*
* create a new hardware dependent device for Emu10k1
*/
-int snd_emu10k1_synth_new_device(snd_seq_device_t *dev)
+static int snd_emu10k1_synth_new_device(snd_seq_device_t *dev)
{
snd_emux_t *emu;
emu10k1_t *hw;
@@ -76,7 +76,7 @@ int snd_emu10k1_synth_new_device(snd_seq_device_t *dev)
return 0;
}
-int snd_emu10k1_synth_delete_device(snd_seq_device_t *dev)
+static int snd_emu10k1_synth_delete_device(snd_seq_device_t *dev)
{
snd_emux_t *emu;
emu10k1_t *hw;
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index cc651b087e0aa7..06d27926602ffc 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -437,7 +437,7 @@ int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
}
int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
- snd_emu10k1_fx8010_irq_t *irq)
+ snd_emu10k1_fx8010_irq_t *irq)
{
snd_emu10k1_fx8010_irq_t *tmp;
unsigned long flags;
@@ -470,8 +470,8 @@ static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr
{
snd_assert(*ptr < 512, return);
set_bit(*ptr, icode->code_valid);
- icode->code[*ptr ][0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
- icode->code[(*ptr)++][1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
+ icode->code[(*ptr) * 2 + 0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
+ icode->code[(*ptr)++ * 2 + 1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
}
#define OP(icode, ptr, op, r, a, x, y) \
@@ -482,14 +482,14 @@ static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned i
{
snd_assert(*ptr < 1024, return);
set_bit(*ptr, icode->code_valid);
- icode->code[*ptr ][0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
- icode->code[(*ptr)++][1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
+ icode->code[(*ptr) * 2 + 0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
+ icode->code[(*ptr)++ * 2 + 1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
}
#define A_OP(icode, ptr, op, r, a, x, y) \
snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
-void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
+static void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
{
pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
snd_emu10k1_ptr_write(emu, pc, 0, data);
@@ -501,83 +501,108 @@ unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc)
return snd_emu10k1_ptr_read(emu, pc, 0);
}
-static void snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
int gpr;
+ u32 val;
for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
if (!test_bit(gpr, icode->gpr_valid))
continue;
- snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, icode->gpr_map[gpr]);
+ if (get_user(val, &icode->gpr_map[gpr]))
+ return -EFAULT;
+ snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
}
+ return 0;
}
-static void snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
int gpr;
+ u32 val;
for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
set_bit(gpr, icode->gpr_valid);
- icode->gpr_map[gpr] = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
+ val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
+ if (put_user(val, &icode->gpr_map[gpr]))
+ return -EFAULT;
}
+ return 0;
}
-static void snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
int tram;
+ u32 addr, val;
for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
if (!test_bit(tram, icode->tram_valid))
continue;
- snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, icode->tram_data_map[tram]);
- if (!emu->audigy)
- snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram]);
- else {
- snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram] << 12);
- snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, icode->tram_addr_map[tram] >> 20);
+ if (get_user(val, &icode->tram_data_map[tram]) ||
+ get_user(addr, &icode->tram_addr_map[tram]))
+ return -EFAULT;
+ snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
+ if (!emu->audigy) {
+ snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
+ } else {
+ snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
+ snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
}
}
+ return 0;
}
-static void snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
int tram;
+ u32 val, addr;
memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
set_bit(tram, icode->tram_valid);
- icode->tram_data_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
- if (!emu->audigy)
- icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
- else {
- icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
- icode->tram_addr_map[tram] |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
+ val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
+ if (!emu->audigy) {
+ addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
+ } else {
+ addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
+ addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
}
+ if (put_user(val, &icode->tram_data_map[tram]) ||
+ put_user(addr, &icode->tram_addr_map[tram]))
+ return -EFAULT;
}
+ return 0;
}
-static void snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
- u32 pc;
+ u32 pc, lo, hi;
- for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
- if (!test_bit(pc, icode->code_valid))
+ for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
+ if (!test_bit(pc / 2, icode->code_valid))
continue;
- snd_emu10k1_efx_write(emu, pc * 2, icode->code[pc][0]);
- snd_emu10k1_efx_write(emu, pc * 2 + 1, icode->code[pc][1]);
+ if (get_user(lo, &icode->code[pc + 0]) ||
+ get_user(hi, &icode->code[pc + 1]))
+ return -EFAULT;
+ snd_emu10k1_efx_write(emu, pc + 0, lo);
+ snd_emu10k1_efx_write(emu, pc + 1, hi);
}
+ return 0;
}
-static void snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
u32 pc;
memset(icode->code_valid, 0, sizeof(icode->code_valid));
- for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
- set_bit(pc, icode->code_valid);
- icode->code[pc][0] = snd_emu10k1_efx_read(emu, pc * 2);
- icode->code[pc][1] = snd_emu10k1_efx_read(emu, pc * 2 + 1);
+ for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
+ set_bit(pc / 2, icode->code_valid);
+ if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
+ return -EFAULT;
+ if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
+ return -EFAULT;
}
+ return 0;
}
static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
@@ -647,7 +672,7 @@ static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
kfree(ctl);
}
-static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
unsigned int i, j;
emu10k1_fx8010_control_gpr_t __user *_gctl;
@@ -656,17 +681,20 @@ static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icod
snd_kcontrol_new_t knew;
snd_kcontrol_t *kctl;
snd_ctl_elem_value_t *val;
+ int err = 0;
val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
if (!val)
- return;
+ return -ENOMEM;
for (i = 0, _gctl = icode->gpr_add_controls;
i < icode->gpr_add_control_count; i++, _gctl++) {
- if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
- break;
+ if (copy_from_user(&gctl, _gctl, sizeof(gctl))) {
+ err = -EFAULT;
+ goto __error;
+ }
snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
- gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue);
- snd_runtime_check(gctl.id.name[0] != '\0', continue);
+ gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
+ snd_runtime_check(gctl.id.name[0] != '\0', err = -EINVAL; goto __error);
ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
memset(&knew, 0, sizeof(knew));
knew.iface = gctl.id.iface;
@@ -694,9 +722,9 @@ static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icod
continue;
knew.private_value = (unsigned long)ctl;
memcpy(ctl, &nctl, sizeof(nctl));
- if (snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu)) < 0) {
+ if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
kfree(ctl);
- continue;
+ goto __error;
}
kctl->private_free = snd_emu10k1_ctl_private_free;
ctl->kcontrol = kctl;
@@ -711,10 +739,12 @@ static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icod
}
snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
}
+ __error:
kfree(val);
+ return err;
}
-static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
unsigned int i;
snd_ctl_elem_id_t id;
@@ -724,13 +754,14 @@ static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icod
for (i = 0, _id = icode->gpr_del_controls;
i < icode->gpr_del_control_count; i++, _id++) {
- snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, continue);
+ snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
down_write(&card->controls_rwsem);
ctl = snd_emu10k1_look_for_ctl(emu, &id);
if (ctl)
snd_ctl_remove(card, ctl->kcontrol);
up_write(&card->controls_rwsem);
}
+ return 0;
}
static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
@@ -789,11 +820,12 @@ static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
else
snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
/* ok, do the main job */
- snd_emu10k1_del_controls(emu, icode);
- snd_emu10k1_gpr_poke(emu, icode);
- snd_emu10k1_tram_poke(emu, icode);
- snd_emu10k1_code_poke(emu, icode);
- snd_emu10k1_add_controls(emu, icode);
+ if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
+ (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
+ (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
+ (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
+ (err = snd_emu10k1_add_controls(emu, icode)) < 0)
+ goto __error;
/* start FX processor when the DSP code is updated */
if (emu->audigy)
snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
@@ -811,10 +843,13 @@ static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
down(&emu->fx8010.lock);
strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
/* ok, do the main job */
- snd_emu10k1_gpr_peek(emu, icode);
- snd_emu10k1_tram_peek(emu, icode);
- snd_emu10k1_code_peek(emu, icode);
- err = snd_emu10k1_list_controls(emu, icode);
+ err = snd_emu10k1_gpr_peek(emu, icode);
+ if (err >= 0)
+ err = snd_emu10k1_tram_peek(emu, icode);
+ if (err >= 0)
+ err = snd_emu10k1_code_peek(emu, icode);
+ if (err >= 0)
+ err = snd_emu10k1_list_controls(emu, icode);
up(&emu->fx8010.lock);
return err;
}
@@ -957,20 +992,24 @@ static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
const int stereo_mix = capture + 2;
const int tmp = 0x88;
u32 ptr;
- emu10k1_fx8010_code_t *icode;
- emu10k1_fx8010_control_gpr_t *controls, *ctl;
+ emu10k1_fx8010_code_t *icode = NULL;
+ emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
mm_segment_t seg;
spin_lock_init(&emu->fx8010.irq_lock);
INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
- if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
- return -ENOMEM;
- if ((controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
- kfree(icode);
- return -ENOMEM;
+ if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL ||
+ (icode->gpr_map = kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
+ (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
+ err = -ENOMEM;
+ goto __err;
}
+ icode->tram_data_map = icode->gpr_map + 512;
+ icode->tram_addr_map = icode->tram_data_map + 256;
+ icode->code = icode->tram_addr_map + 256;
+
/* clear free GPRs */
for (i = 0; i < 512; i++)
set_bit(i, icode->gpr_valid);
@@ -1312,8 +1351,12 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
/* ADC buffer */
+#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
+ A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
+#else
A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
+#endif
/*
* ok, set up done..
@@ -1335,8 +1378,13 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
snd_leave_user(seg);
__err:
- kfree(controls);
- kfree(icode);
+ if (controls != NULL)
+ kfree(controls);
+ if (icode != NULL) {
+ if (icode->gpr_map != NULL)
+ kfree(icode->gpr_map);
+ kfree(icode);
+ }
return err;
}
@@ -1398,8 +1446,8 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
int err, i, z, gpr, tmp, playback, capture;
u32 ptr;
emu10k1_fx8010_code_t *icode;
- emu10k1_fx8010_pcm_t *ipcm;
- emu10k1_fx8010_control_gpr_t *controls, *ctl;
+ emu10k1_fx8010_pcm_t *ipcm = NULL;
+ emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
mm_segment_t seg;
spin_lock_init(&emu->fx8010.irq_lock);
@@ -1407,15 +1455,16 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
return -ENOMEM;
- if ((controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL) {
- kfree(icode);
- return -ENOMEM;
- }
- if ((ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
- kfree(controls);
- kfree(icode);
- return -ENOMEM;
+ if ((icode->gpr_map = kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
+ (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
+ (ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
+ err = -ENOMEM;
+ goto __err;
}
+
+ icode->tram_data_map = icode->gpr_map + 256;
+ icode->tram_addr_map = icode->tram_data_map + 160;
+ icode->code = icode->tram_addr_map + 160;
/* clear free GPRs */
for (i = 0; i < 256; i++)
@@ -1906,9 +1955,15 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
if (err >= 0)
err = snd_emu10k1_ipcm_poke(emu, ipcm);
__err:
- kfree(ipcm);
- kfree(controls);
- kfree(icode);
+ if (ipcm != NULL)
+ kfree(ipcm);
+ if (controls != NULL)
+ kfree(controls);
+ if (icode != NULL) {
+ if (icode->gpr_map != NULL)
+ kfree(icode->gpr_map);
+ kfree(icode);
+ }
return err;
}
@@ -1959,7 +2014,7 @@ int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
}
size = 0x2000 << size_reg;
}
- if (emu->fx8010.etram_pages.bytes == size)
+ if ((emu->fx8010.etram_pages.bytes / 2) == size)
return 0;
spin_lock_irq(&emu->emu_lock);
outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index f73ac0ef65535c..bd01a7708d2c93 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -54,7 +54,7 @@ static int snd_emu10k1_spdif_get(snd_kcontrol_t * kcontrol,
ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
+ return 0;
}
static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol,
@@ -64,7 +64,7 @@ static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol,
ucontrol->value.iec958.status[1] = 0xff;
ucontrol->value.iec958.status[2] = 0xff;
ucontrol->value.iec958.status[3] = 0xff;
- return 0;
+ return 0;
}
static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
@@ -87,27 +87,27 @@ static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
emu->spdif_bits[idx] = val;
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
+ return change;
}
static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
.count = 4,
- .info = snd_emu10k1_spdif_info,
- .get = snd_emu10k1_spdif_get_mask
+ .info = snd_emu10k1_spdif_info,
+ .get = snd_emu10k1_spdif_get_mask
};
static snd_kcontrol_new_t snd_emu10k1_spdif_control =
{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
.count = 4,
- .info = snd_emu10k1_spdif_info,
- .get = snd_emu10k1_spdif_get,
- .put = snd_emu10k1_spdif_put
+ .info = snd_emu10k1_spdif_info,
+ .get = snd_emu10k1_spdif_get,
+ .put = snd_emu10k1_spdif_put
};
@@ -165,7 +165,7 @@ static int snd_emu10k1_send_routing_get(snd_kcontrol_t * kcontrol,
ucontrol->value.integer.value[(voice * num_efx) + idx] =
mix->send_routing[voice][idx] & mask;
spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
+ return 0;
}
static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol,
@@ -199,18 +199,18 @@ static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol,
}
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
+ return change;
}
static snd_kcontrol_new_t snd_emu10k1_send_routing_control =
{
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "EMU10K1 PCM Send Routing",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "EMU10K1 PCM Send Routing",
.count = 32,
- .info = snd_emu10k1_send_routing_info,
- .get = snd_emu10k1_send_routing_get,
- .put = snd_emu10k1_send_routing_put
+ .info = snd_emu10k1_send_routing_info,
+ .get = snd_emu10k1_send_routing_get,
+ .put = snd_emu10k1_send_routing_put
};
static int snd_emu10k1_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
@@ -236,7 +236,7 @@ static int snd_emu10k1_send_volume_get(snd_kcontrol_t * kcontrol,
for (idx = 0; idx < 3*num_efx; idx++)
ucontrol->value.integer.value[idx] = mix->send_volume[idx/num_efx][idx%num_efx];
spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
+ return 0;
}
static int snd_emu10k1_send_volume_put(snd_kcontrol_t * kcontrol,
@@ -268,18 +268,18 @@ static int snd_emu10k1_send_volume_put(snd_kcontrol_t * kcontrol,
}
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
+ return change;
}
static snd_kcontrol_new_t snd_emu10k1_send_volume_control =
{
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "EMU10K1 PCM Send Volume",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "EMU10K1 PCM Send Volume",
.count = 32,
- .info = snd_emu10k1_send_volume_info,
- .get = snd_emu10k1_send_volume_get,
- .put = snd_emu10k1_send_volume_put
+ .info = snd_emu10k1_send_volume_info,
+ .get = snd_emu10k1_send_volume_get,
+ .put = snd_emu10k1_send_volume_put
};
static int snd_emu10k1_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
@@ -303,7 +303,7 @@ static int snd_emu10k1_attn_get(snd_kcontrol_t * kcontrol,
for (idx = 0; idx < 3; idx++)
ucontrol->value.integer.value[idx] = mix->attn[idx];
spin_unlock_irqrestore(&emu->reg_lock, flags);
- return 0;
+ return 0;
}
static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol,
@@ -331,18 +331,18 @@ static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol,
}
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
+ return change;
}
static snd_kcontrol_new_t snd_emu10k1_attn_control =
{
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "EMU10K1 PCM Volume",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "EMU10K1 PCM Volume",
.count = 32,
- .info = snd_emu10k1_attn_info,
- .get = snd_emu10k1_attn_get,
- .put = snd_emu10k1_attn_put
+ .info = snd_emu10k1_attn_info,
+ .get = snd_emu10k1_attn_get,
+ .put = snd_emu10k1_attn_put
};
static int snd_emu10k1_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
@@ -363,7 +363,7 @@ static int snd_emu10k1_shared_spdif_get(snd_kcontrol_t * kcontrol,
ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
else
ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
- return 0;
+ return 0;
}
static int snd_emu10k1_shared_spdif_put(snd_kcontrol_t * kcontrol,
@@ -394,7 +394,7 @@ static int snd_emu10k1_shared_spdif_put(snd_kcontrol_t * kcontrol,
outl(reg | val, emu->port + HCFG);
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
- return change;
+ return change;
}
static snd_kcontrol_new_t snd_emu10k1_shared_spdif __devinitdata =
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 080d9d490df6d5..0fe70290003cdf 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -267,6 +267,7 @@ static void snd_emu10k1_pcm_init_voice(emu10k1_t *emu,
send_routing[3] = 3;
memset(send_amount, 0, sizeof(send_amount));
} else {
+ /* mono, left, right (master voice = left) */
tmp = stereo ? (master ? 1 : 2) : 0;
memcpy(send_routing, &mix->send_routing[tmp][0], 8);
memcpy(send_amount, &mix->send_volume[tmp][0], 8);
@@ -292,15 +293,9 @@ static void snd_emu10k1_pcm_init_voice(emu10k1_t *emu,
// setup routing
if (emu->audigy) {
snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
- ((unsigned int)send_routing[3] << 24) |
- ((unsigned int)send_routing[2] << 16) |
- ((unsigned int)send_routing[1] << 8) |
- (unsigned int)send_routing[0]);
+ snd_emu10k1_compose_audigy_fxrt1(send_routing));
snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
- ((unsigned int)send_routing[7] << 24) |
- ((unsigned int)send_routing[6] << 16) |
- ((unsigned int)send_routing[5] << 8) |
- (unsigned int)send_routing[4]);
+ snd_emu10k1_compose_audigy_fxrt2(send_routing));
snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice,
((unsigned int)send_amount[4] << 24) |
((unsigned int)send_amount[5] << 16) |
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index 90dcbe3ab34ee5..a65fce3bda3dd3 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -175,32 +175,45 @@ static void snd_emu10k1_proc_read(snd_info_entry_t *entry,
};
emu10k1_t *emu = entry->private_data;
- unsigned int val;
+ unsigned int val, val1;
int nefx = emu->audigy ? 64 : 32;
char **outputs = emu->audigy ? audigy_outs : creative_outs;
int idx;
snd_iprintf(buffer, "EMU10K1\n\n");
- val = emu->audigy ?
- snd_emu10k1_ptr_read(emu, A_FXRT1, 0) :
- snd_emu10k1_ptr_read(emu, FXRT, 0);
snd_iprintf(buffer, "Card : %s\n",
emu->audigy ? "Audigy" : (emu->APS ? "EMU APS" : "Creative"));
snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size);
snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes);
snd_iprintf(buffer, "\n");
- if (emu->audigy) {
- snd_iprintf(buffer, "Effect Send Routing : A=%i, B=%i, C=%i, D=%i\n",
- val & 0x3f,
- (val >> 8) & 0x3f,
- (val >> 16) & 0x3f,
- (val >> 24) & 0x3f);
- } else {
- snd_iprintf(buffer, "Effect Send Routing : A=%i, B=%i, C=%i, D=%i\n",
- (val >> 16) & 0x0f,
- (val >> 20) & 0x0f,
- (val >> 24) & 0x0f,
- (val >> 28) & 0x0f);
+ snd_iprintf(buffer, "Effect Send Routing :\n");
+ for (idx = 0; idx < NUM_G; idx++) {
+ val = emu->audigy ?
+ snd_emu10k1_ptr_read(emu, A_FXRT1, idx) :
+ snd_emu10k1_ptr_read(emu, FXRT, idx);
+ val1 = emu->audigy ?
+ snd_emu10k1_ptr_read(emu, A_FXRT2, idx) :
+ 0;
+ if (emu->audigy) {
+ snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i, ",
+ idx,
+ val & 0x3f,
+ (val >> 8) & 0x3f,
+ (val >> 16) & 0x3f,
+ (val >> 24) & 0x3f);
+ snd_iprintf(buffer, "E=%i, F=%i, G=%i, H=%i\n",
+ val1 & 0x3f,
+ (val1 >> 8) & 0x3f,
+ (val1 >> 16) & 0x3f,
+ (val1 >> 24) & 0x3f);
+ } else {
+ snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i\n",
+ idx,
+ (val >> 16) & 0x0f,
+ (val >> 20) & 0x0f,
+ (val >> 24) & 0x0f,
+ (val >> 28) & 0x0f);
+ }
}
snd_iprintf(buffer, "\nCaptured FX Outputs :\n");
for (idx = 0; idx < nefx; idx++) {
@@ -309,6 +322,152 @@ static long snd_emu10k1_fx8010_read(snd_info_entry_t *entry, void *file_private_
return 0;
}
+#ifdef CONFIG_SND_DEBUG
+static void snd_emu_proc_io_reg_read(snd_info_entry_t *entry,
+ snd_info_buffer_t * buffer)
+{
+ emu10k1_t *emu = entry->private_data;
+ unsigned long value;
+ unsigned long flags;
+ int i;
+ snd_iprintf(buffer, "IO Registers:\n\n");
+ for(i = 0; i < 0x40; i+=4) {
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ value = inl(emu->port + i);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ snd_iprintf(buffer, "%02X: %08lX\n", i, value);
+ }
+}
+
+static void snd_emu_proc_io_reg_write(snd_info_entry_t *entry,
+ snd_info_buffer_t * buffer)
+{
+ emu10k1_t *emu = entry->private_data;
+ unsigned long flags;
+ char line[64];
+ u32 reg, val;
+ while (!snd_info_get_line(buffer, line, sizeof(line))) {
+ if (sscanf(line, "%x %x", &reg, &val) != 2)
+ continue;
+ if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) {
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ outl(val, emu->port + (reg & 0xfffffffc));
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ }
+ }
+}
+
+static unsigned int snd_ptr_read(emu10k1_t * emu,
+ unsigned int iobase,
+ unsigned int reg,
+ unsigned int chn)
+{
+ unsigned long flags;
+ unsigned int regptr, val;
+
+ regptr = (reg << 16) | chn;
+
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ outl(regptr, emu->port + iobase + PTR);
+ val = inl(emu->port + iobase + DATA);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ return val;
+}
+
+static void snd_ptr_write(emu10k1_t *emu,
+ unsigned int iobase,
+ unsigned int reg,
+ unsigned int chn,
+ unsigned int data)
+{
+ unsigned int regptr;
+ unsigned long flags;
+
+ regptr = (reg << 16) | chn;
+
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ outl(regptr, emu->port + iobase + PTR);
+ outl(data, emu->port + iobase + DATA);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+
+static void snd_emu_proc_ptr_reg_read(snd_info_entry_t *entry,
+ snd_info_buffer_t * buffer, int iobase, int offset, int length)
+{
+ emu10k1_t *emu = entry->private_data;
+ unsigned long value;
+ int i,j;
+ if (offset+length > 0x80) {
+ snd_iprintf(buffer, "Input values out of range\n");
+ return;
+ }
+ snd_iprintf(buffer, "Registers 0x%x\n", iobase);
+ for(i = offset; i < offset+length; i++) {
+ snd_iprintf(buffer, "%02X: ",i);
+ for (j = 0; j < 4; j++) {
+ if(iobase == 0)
+ value = snd_ptr_read(emu, 0, i, j);
+ else
+ value = snd_ptr_read(emu, 0x20, i, j);
+ snd_iprintf(buffer, "%08lX ", value);
+ }
+ snd_iprintf(buffer, "\n");
+ }
+}
+
+static void snd_emu_proc_ptr_reg_write(snd_info_entry_t *entry,
+ snd_info_buffer_t * buffer, int iobase)
+{
+ emu10k1_t *emu = entry->private_data;
+ char line[64];
+ unsigned int reg, channel_id , val;
+ while (!snd_info_get_line(buffer, line, sizeof(line))) {
+ if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
+ continue;
+ if ((reg < 0x80) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) )
+ snd_ptr_write(emu, iobase, reg, channel_id, val);
+ }
+}
+
+static void snd_emu_proc_ptr_reg_write00(snd_info_entry_t *entry,
+ snd_info_buffer_t * buffer)
+{
+ snd_emu_proc_ptr_reg_write(entry, buffer, 0);
+}
+
+static void snd_emu_proc_ptr_reg_write20(snd_info_entry_t *entry,
+ snd_info_buffer_t * buffer)
+{
+ snd_emu_proc_ptr_reg_write(entry, buffer, 0x20);
+}
+
+
+static void snd_emu_proc_ptr_reg_read00a(snd_info_entry_t *entry,
+ snd_info_buffer_t * buffer)
+{
+ snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0, 0x40);
+}
+
+static void snd_emu_proc_ptr_reg_read00b(snd_info_entry_t *entry,
+ snd_info_buffer_t * buffer)
+{
+ snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0x40, 0x40);
+}
+
+static void snd_emu_proc_ptr_reg_read20a(snd_info_entry_t *entry,
+ snd_info_buffer_t * buffer)
+{
+ snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0, 0x40);
+}
+
+static void snd_emu_proc_ptr_reg_read20b(snd_info_entry_t *entry,
+ snd_info_buffer_t * buffer)
+{
+ snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x40, 0x40);
+}
+#endif
+
static struct snd_info_entry_ops snd_emu10k1_proc_ops_fx8010 = {
.read = snd_emu10k1_fx8010_read,
};
@@ -316,9 +475,36 @@ static struct snd_info_entry_ops snd_emu10k1_proc_ops_fx8010 = {
int __devinit snd_emu10k1_proc_init(emu10k1_t * emu)
{
snd_info_entry_t *entry;
+#ifdef CONFIG_SND_DEBUG
+ if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
+ snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_io_reg_read);
+ entry->c.text.write_size = 64;
+ entry->c.text.write = snd_emu_proc_io_reg_write;
+ }
+ if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) {
+ snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_ptr_reg_read00a);
+ entry->c.text.write_size = 64;
+ entry->c.text.write = snd_emu_proc_ptr_reg_write00;
+ }
+ if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) {
+ snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_ptr_reg_read00b);
+ entry->c.text.write_size = 64;
+ entry->c.text.write = snd_emu_proc_ptr_reg_write00;
+ }
+ if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) {
+ snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_ptr_reg_read20a);
+ entry->c.text.write_size = 64;
+ entry->c.text.write = snd_emu_proc_ptr_reg_write20;
+ }
+ if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) {
+ snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_ptr_reg_read20b);
+ entry->c.text.write_size = 64;
+ entry->c.text.write = snd_emu_proc_ptr_reg_write20;
+ }
+#endif
if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
- snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1_proc_read);
+ snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read);
if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) {
entry->content = SNDRV_INFO_CONTENT_DATA;
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index 22d8e3dd60ffbd..dfe327a27af8db 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -313,28 +313,3 @@ unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate)
return 0; /* Should never reach this point */
}
-/*
- * Returns an attenuation based upon a cumulative volume value
- * Algorithm calculates 0x200 - 0x10 log2 (input)
- */
-
-unsigned char snd_emu10k1_sum_vol_attn(unsigned int value)
-{
- unsigned short count = 16, ans;
-
- if (value == 0)
- return 0xFF;
-
- /* Find first SET bit. This is the integer part of the value */
- while ((value & 0x10000) == 0) {
- value <<= 1;
- count--;
- }
-
- /* The REST of the data is the fractional part. */
- ans = (unsigned short) (0x110 - ((count << 4) + ((value & 0x0FFFFL) >> 12)));
- if (ans > 0xFF)
- ans = 0xFF;
-
- return (unsigned char) ans;
-}
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
index e960828e04aff4..70f4020603c2cc 100644
--- a/sound/pci/emu10k1/irq.c
+++ b/sound/pci/emu10k1/irq.c
@@ -112,8 +112,8 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2);
}
if (status & IPR_INTERVALTIMER) {
- if (emu->timer_interrupt)
- emu->timer_interrupt(emu);
+ if (emu->timer)
+ snd_timer_interrupt(emu->timer, emu->timer->sticks);
else
snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
status &= ~IPR_INTERVALTIMER;
diff --git a/sound/pci/emu10k1/timer.c b/sound/pci/emu10k1/timer.c
new file mode 100644
index 00000000000000..c9c421a6474365
--- /dev/null
+++ b/sound/pci/emu10k1/timer.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) by Lee Revell <rlrevell@joe-job.com>
+ *
+ * Routines for control of EMU10K1 chips
+ *
+ * Copied from similar code by Clemens Ladisch in the ymfpci driver
+ *
+ * BUGS:
+ * --
+ *
+ * TODO:
+ * --
+ *
+ * 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/time.h>
+#include <sound/core.h>
+#include <sound/emu10k1.h>
+
+static int snd_emu10k1_timer_start(snd_timer_t *timer)
+{
+ emu10k1_t *emu;
+ unsigned long flags;
+ unsigned int delay;
+
+ emu = snd_timer_chip(timer);
+ delay = timer->sticks - 1;
+ if (delay < 5 ) /* minimum time is 5 ticks */
+ delay = 5;
+ spin_lock_irqsave(&emu->reg_lock, flags);
+ snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
+ outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
+ spin_unlock_irqrestore(&emu->reg_lock, flags);
+ return 0;
+}
+
+static int snd_emu10k1_timer_stop(snd_timer_t *timer)
+{
+ emu10k1_t *emu;
+ unsigned long flags;
+
+ emu = snd_timer_chip(timer);
+ spin_lock_irqsave(&emu->reg_lock, flags);
+ snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
+ spin_unlock_irqrestore(&emu->reg_lock, flags);
+ return 0;
+}
+
+static int snd_emu10k1_timer_precise_resolution(snd_timer_t *timer,
+ unsigned long *num, unsigned long *den)
+{
+ *num = 1;
+ *den = 48000;
+ return 0;
+}
+
+static struct _snd_timer_hardware snd_emu10k1_timer_hw = {
+ .flags = SNDRV_TIMER_HW_AUTO,
+ .resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */
+ .ticks = 1024,
+ .start = snd_emu10k1_timer_start,
+ .stop = snd_emu10k1_timer_stop,
+ .precise_resolution = snd_emu10k1_timer_precise_resolution,
+};
+
+int __devinit snd_emu10k1_timer(emu10k1_t *emu, int device)
+{
+ snd_timer_t *timer = NULL;
+ snd_timer_id_t tid;
+ int err;
+
+ tid.dev_class = SNDRV_TIMER_CLASS_CARD;
+ tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
+ tid.card = emu->card->number;
+ tid.device = device;
+ tid.subdevice = 0;
+ if ((err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer)) >= 0) {
+ strcpy(timer->name, "EMU10K1 timer");
+ timer->private_data = emu;
+ timer->hw = snd_emu10k1_timer_hw;
+ }
+ emu->timer = timer;
+ return err;
+}
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 6a6979263fe2b8..b8efd0d4cf0ac8 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -837,23 +837,19 @@ static u16 wave_get_register(es1968_t *chip, u16 reg)
static void snd_es1968_bob_stop(es1968_t *chip)
{
u16 reg;
- unsigned long flags;
- spin_lock_irqsave(&chip->reg_lock, flags);
reg = __maestro_read(chip, 0x11);
reg &= ~ESM_BOB_ENABLE;
__maestro_write(chip, 0x11, reg);
reg = __maestro_read(chip, 0x17);
reg &= ~ESM_BOB_START;
__maestro_write(chip, 0x17, reg);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
static void snd_es1968_bob_start(es1968_t *chip)
{
int prescale;
int divide;
- unsigned long flags;
/* compute ideal interrupt frequency for buffer size & play rate */
/* first, find best prescaler value to match freq */
@@ -882,13 +878,11 @@ static void snd_es1968_bob_start(es1968_t *chip)
} else if (divide > 1)
divide--;
- spin_lock_irqsave(&chip->reg_lock, flags);
__maestro_write(chip, 6, 0x9000 | (prescale << 5) | divide); /* set reg */
/* Now set IDR 11/17 */
__maestro_write(chip, 0x11, __maestro_read(chip, 0x11) | 1);
__maestro_write(chip, 0x17, __maestro_read(chip, 0x17) | 1);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
}
/* call with substream spinlock */
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 77a8e278fabed4..b02c94778d7975 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -1290,9 +1290,9 @@ static int __devinit aureon_init(ice1712_t *ice)
{
static unsigned short wm_inits_aureon[] = {
/* These come first to reduce init pop noise */
- 0x1b, 0x005, /* ADC Mux (AC'97 source) */
- 0x1c, 0x00B, /* Out Mux1 (VOUT1 = ADC+AUX, VOUT2 = ADC) */
- 0x1d, 0x009, /* Out Mux2 (VOUT2 = ADC, VOUT3 = ADC) */
+ 0x1b, 0x044, /* ADC Mux (AC'97 source) */
+ 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
+ 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
0x18, 0x000, /* All power-up */
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 32b733520fbab7..f2bd304a46c28d 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1743,6 +1743,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
},
{
.vendor = 0x1028,
+ .device = 0x010d,
+ .name = "Dell", /* which model? AD1885 */
+ .type = AC97_TUNE_HP_ONLY
+ },
+ {
+ .vendor = 0x1028,
.device = 0x0126,
.name = "Dell Optiplex GX260", /* AD1981A */
.type = AC97_TUNE_HP_ONLY
@@ -1753,6 +1759,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.name = "Dell Precision 450", /* AD1981B*/
.type = AC97_TUNE_HP_ONLY
},
+ {
+ .vendor = 0x1028,
+ .device = 0x0147,
+ .name = "Dell", /* which model? AD1981B*/
+ .type = AC97_TUNE_HP_ONLY
+ },
{ /* FIXME: which codec? */
.vendor = 0x103c,
.device = 0x00c3,
@@ -2765,11 +2777,7 @@ static struct pci_driver driver = {
static int __init alsa_card_intel8x0_init(void)
{
- int err;
-
- if ((err = pci_module_init(&driver)) < 0)
- return err;
- return 0;
+ return pci_module_init(&driver);
}
static void __exit alsa_card_intel8x0_exit(void)
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index ca256c4f18b9a0..e89b826c675150 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -472,7 +472,8 @@ static char* channelName[] = {
"SPDIF-R",
};
-u16 ClockSourceSelector[] = {0x8000, // selects source as ADAT at 44.1 kHz
+static u16 ClockSourceSelector[] =
+ {0x8000, // selects source as ADAT at 44.1 kHz
0x0000, // selects source as ADAT at 48 kHz
0x8001, // selects source as S/PDIF at 44.1 kHz
0x0001, // selects source as S/PDIF at 48 kHz
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
index 1f588eeb824a35..60f6b87b756cec 100644
--- a/sound/pci/mixart/mixart_core.c
+++ b/sound/pci/mixart/mixart_core.c
@@ -72,9 +72,12 @@ static int retrieve_msg_frame(mixart_mgr_t *mgr, u32 *msg_frame)
static int get_msg(mixart_mgr_t *mgr, mixart_msg_t *resp, u32 msg_frame_address )
{
unsigned long flags;
- u32 headptr, i;
+ u32 headptr;
u32 size;
int err;
+#ifndef __BIG_ENDIAN
+ unsigned int i;
+#endif
spin_lock_irqsave(&mgr->msg_lock, flags);
err = 0;
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 1b76f18baad1e3..a730a19c488376 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -934,6 +934,7 @@ static snd_pcm_uframes_t hdsp_hw_pointer(hdsp_t *hdsp)
}
position &= HDSP_BufferPositionMask;
+ position /= 4;
position &= (hdsp->period_bytes/2) - 1;
return position;
}
@@ -1443,14 +1444,14 @@ static int snd_hdsp_midi_output_close(snd_rawmidi_substream_t * substream)
return 0;
}
-snd_rawmidi_ops_t snd_hdsp_midi_output =
+static snd_rawmidi_ops_t snd_hdsp_midi_output =
{
.open = snd_hdsp_midi_output_open,
.close = snd_hdsp_midi_output_close,
.trigger = snd_hdsp_midi_output_trigger,
};
-snd_rawmidi_ops_t snd_hdsp_midi_input =
+static snd_rawmidi_ops_t snd_hdsp_midi_input =
{
.open = snd_hdsp_midi_input_open,
.close = snd_hdsp_midi_input_close,
@@ -3137,7 +3138,7 @@ HDSP_LINE_OUT("Line Out", 0),
static snd_kcontrol_new_t snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
static snd_kcontrol_new_t snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
-int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
+static int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
{
unsigned int idx;
int err;
@@ -3651,7 +3652,7 @@ static int snd_hdsp_set_defaults(hdsp_t *hdsp)
return 0;
}
-void hdsp_midi_tasklet(unsigned long arg)
+static void hdsp_midi_tasklet(unsigned long arg)
{
hdsp_t *hdsp = (hdsp_t *)arg;
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 420779931869e7..69cd81eaa111bc 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -1584,7 +1584,7 @@ RME9652_ADAT_SYNC("ADAT3 Sync Check", 0, 2);
static snd_kcontrol_new_t snd_rme9652_adat1_input =
RME9652_ADAT1_IN("ADAT1 Input Source", 0);
-int snd_rme9652_create_controls(snd_card_t *card, rme9652_t *rme9652)
+static int snd_rme9652_create_controls(snd_card_t *card, rme9652_t *rme9652)
{
unsigned int idx;
int err;
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 8dcfc0800c4933..80d225d7c64060 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -357,8 +357,8 @@ static unsigned char snd_sonicvibes_in(sonicvibes_t * sonic, unsigned char reg)
return value;
}
-#ifdef CONFIG_SND_DEBUG
-void snd_sonicvibes_debug(sonicvibes_t * sonic)
+#if 0
+static void snd_sonicvibes_debug(sonicvibes_t * sonic)
{
printk("SV REGS: INDEX = 0x%02x ", inb(SV_REG(sonic, INDEX)));
printk(" STATUS = 0x%02x\n", inb(SV_REG(sonic, STATUS)));
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 815e87883e8628..bb0d87f3b7dbc1 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -53,6 +53,9 @@ static int snd_trident_resume(snd_card_t *card, unsigned int state);
#endif
static int snd_trident_sis_reset(trident_t *trident);
+static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max);
+static int snd_trident_free(trident_t *trident);
+
/*
* common I/O routines
*/
@@ -632,7 +635,7 @@ static void snd_trident_write_cvol_reg(trident_t * trident, snd_trident_voice_t
Returns: Delta value.
---------------------------------------------------------------------------*/
-unsigned int snd_trident_convert_rate(unsigned int rate)
+static unsigned int snd_trident_convert_rate(unsigned int rate)
{
unsigned int delta;
@@ -692,7 +695,7 @@ static unsigned int snd_trident_convert_adc_rate(unsigned int rate)
Returns: Delta value.
---------------------------------------------------------------------------*/
-unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size)
+static unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size)
{
unsigned int res = (rate * period_size) / 48000;
if (res < 64)
@@ -713,7 +716,7 @@ unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int peri
Returns: Control value.
---------------------------------------------------------------------------*/
-unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream)
+static unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream)
{
unsigned int CTRL;
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -770,8 +773,8 @@ static int snd_trident_ioctl(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
-int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,
- snd_pcm_hw_params_t * hw_params)
+static int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,
+ snd_pcm_hw_params_t * hw_params)
{
trident_t *trident = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -804,8 +807,8 @@ int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,
---------------------------------------------------------------------------*/
-int snd_trident_allocate_evoice(snd_pcm_substream_t * substream,
- snd_pcm_hw_params_t * hw_params)
+static int snd_trident_allocate_evoice(snd_pcm_substream_t * substream,
+ snd_pcm_hw_params_t * hw_params)
{
trident_t *trident = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
@@ -3658,7 +3661,7 @@ int __devinit snd_trident_create(snd_card_t * card,
---------------------------------------------------------------------------*/
-int snd_trident_free(trident_t *trident)
+static int snd_trident_free(trident_t *trident)
{
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
if (trident->gameport) {
@@ -3807,9 +3810,9 @@ static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *
}
/*---------------------------------------------------------------------------
- snd_trident_attach_synthesizer, snd_trident_detach_synthesizer
+ snd_trident_attach_synthesizer
- Description: Attach/detach synthesizer hooks
+ Description: Attach synthesizer hooks
Paramters: trident - device specific private data for 4DWave card
@@ -3828,17 +3831,6 @@ int snd_trident_attach_synthesizer(trident_t *trident)
return 0;
}
-int snd_trident_detach_synthesizer(trident_t *trident)
-{
-#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
- if (trident->seq_dev) {
- snd_device_free(trident->card, trident->seq_dev);
- trident->seq_dev = NULL;
- }
-#endif
- return 0;
-}
-
snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int client, int port)
{
snd_trident_voice_t *pvoice;
@@ -3911,7 +3903,7 @@ void snd_trident_free_voice(trident_t * trident, snd_trident_voice_t *voice)
private_free(voice);
}
-void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max)
+static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max)
{
unsigned int i, val, mask[2] = { 0, 0 };
@@ -4001,9 +3993,7 @@ EXPORT_SYMBOL(snd_trident_free_voice);
EXPORT_SYMBOL(snd_trident_start_voice);
EXPORT_SYMBOL(snd_trident_stop_voice);
EXPORT_SYMBOL(snd_trident_write_voice_regs);
-EXPORT_SYMBOL(snd_trident_clear_voices);
/* trident_memory.c symbols */
EXPORT_SYMBOL(snd_trident_synth_alloc);
EXPORT_SYMBOL(snd_trident_synth_free);
-EXPORT_SYMBOL(snd_trident_synth_bzero);
EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index 6fd58f18047318..6cc282681e096c 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -450,29 +450,6 @@ static int synth_free_pages(trident_t *trident, snd_util_memblk_t *blk)
}
/*
- * bzero(blk + offset, size)
- */
-int snd_trident_synth_bzero(trident_t *trident, snd_util_memblk_t *blk, int offset, int size)
-{
- int page, nextofs, end_offset, temp, temp1;
-
- offset += blk->offset;
- end_offset = offset + size;
- page = get_aligned_page(offset) + 1;
- do {
- nextofs = aligned_page_offset(page);
- temp = nextofs - offset;
- temp1 = end_offset - offset;
- if (temp1 < temp)
- temp = temp1;
- memset(offset_ptr(trident, offset), 0, temp);
- offset = nextofs;
- page++;
- } while (offset < end_offset);
- return 0;
-}
-
-/*
* copy_from_user(blk + offset, data, size)
*/
int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size)
diff --git a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c
index 72d36b11bcd3d5..64aab2346b4640 100644
--- a/sound/pci/trident/trident_synth.c
+++ b/sound/pci/trident/trident_synth.c
@@ -618,7 +618,7 @@ static void select_instrument(trident_t * trident, snd_trident_voice_t * v)
instr = snd_seq_instr_find(trident->synth.ilist, &v->instr, 0, 1);
if (instr != NULL) {
if (instr->ops) {
- if (instr->ops->instr_type == snd_seq_simple_id)
+ if (!strcmp(instr->ops->instr_type, SNDRV_SEQ_INSTR_ID_SIMPLE))
snd_trident_simple_init(v);
}
snd_seq_instr_free_use(trident->synth.ilist, instr);
@@ -811,7 +811,7 @@ static void snd_trident_synth_free_private_instruments(snd_trident_port_t * p, i
snd_seq_instr_list_free_cond(p->trident->synth.ilist, &ifree, client, 0);
}
-int snd_trident_synth_event_input(snd_seq_event_t * ev, int direct, void *private_data, int atomic, int hop)
+static int snd_trident_synth_event_input(snd_seq_event_t * ev, int direct, void *private_data, int atomic, int hop)
{
snd_trident_port_t *p = (snd_trident_port_t *) private_data;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index ea853d19f4e03c..56727ae9676008 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2107,11 +2107,13 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
{ .vendor = 0x1297, .device = 0xa232, .action = VIA_DXS_ENABLE }, /* Shuttle ?? */
{ .vendor = 0x1297, .device = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */
{ .vendor = 0x1458, .device = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */
- { .vendor = 0x147b, .device = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
- { .vendor = 0x14ff, .device = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
{ .vendor = 0x1462, .device = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
- { .vendor = 0x1462, .device = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
{ .vendor = 0x1462, .device = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
+ { .vendor = 0x1462, .device = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
+ { .vendor = 0x147b, .device = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
+ { .vendor = 0x147b, .device = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */
+ { .vendor = 0x147b, .device = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */
+ { .vendor = 0x14ff, .device = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
{ .vendor = 0x1584, .device = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */
{ .vendor = 0x1584, .device = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */
{ .vendor = 0x161f, .device = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index f465590c94df03..75e53b50924afe 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -61,8 +61,8 @@ enum {
};
static struct pci_device_id snd_vx222_ids[] = {
- { 0x10b5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */
- { 0x10b5, 0x9030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */
+ { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */
+ { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */
{ 0, }
};
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 87214a02b50ac8..81d833db59cbaf 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -258,7 +258,7 @@ static int voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpc
return -ENOMEM;
}
-int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice)
+static int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice)
{
unsigned long flags;
int result;
@@ -278,7 +278,7 @@ int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, y
return result;
}
-int snd_ymfpci_voice_free(ymfpci_t *chip, ymfpci_voice_t *pvoice)
+static int snd_ymfpci_voice_free(ymfpci_t *chip, ymfpci_voice_t *pvoice)
{
unsigned long flags;
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h
index 440a92c66b2caa..ddaa69d542360f 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.h
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h
@@ -130,8 +130,6 @@ static inline unsigned short pdacf_reg_read(pdacf_t *chip, unsigned char reg)
return inw(chip->port + reg);
}
-unsigned char pdacf_ak4117_read(void *private_data, unsigned char reg);
-void pdacf_ak4117_write(void *private_data, unsigned char reg, unsigned char val);
pdacf_t *snd_pdacf_create(snd_card_t *card);
int snd_pdacf_ak4117_create(pdacf_t *pdacf);
void snd_pdacf_powerdown(pdacf_t *chip);
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index 9e194fb070c491..11eb7275456c55 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -28,7 +28,7 @@
/*
*
*/
-unsigned char pdacf_ak4117_read(void *private_data, unsigned char reg)
+static unsigned char pdacf_ak4117_read(void *private_data, unsigned char reg)
{
pdacf_t *chip = private_data;
unsigned long timeout;
@@ -60,7 +60,7 @@ unsigned char pdacf_ak4117_read(void *private_data, unsigned char reg)
return res;
}
-void pdacf_ak4117_write(void *private_data, unsigned char reg, unsigned char val)
+static void pdacf_ak4117_write(void *private_data, unsigned char reg, unsigned char val)
{
pdacf_t *chip = private_data;
unsigned long timeout;
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 696543c4da28f9..df09c2c22b20d4 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -560,7 +560,6 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
{
unsigned long flags;
int timeout;
- signed long time;
spin_lock_irqsave(&chip->lock, flags);
snd_cs4231_busy_wait(chip);
@@ -594,29 +593,29 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
#if 0
printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
#endif
- time = HZ / 4;
+ /* in 10ms increments, check condition, up to 250ms */
+ timeout = 25;
while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
spin_unlock_irqrestore(&chip->lock, flags);
- if (time <= 0) {
+ if (--timeout < 0) {
snd_printk("mce_down - auto calibration time out (2)\n");
return;
}
- set_current_state(TASK_INTERRUPTIBLE);
- time = schedule_timeout(time);
+ msleep(10);
spin_lock_irqsave(&chip->lock, flags);
}
#if 0
printk("(3) jiffies = %li\n", jiffies);
#endif
- time = HZ / 10;
+ /* in 10ms increments, check condition, up to 100ms */
+ timeout = 10;
while (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) {
spin_unlock_irqrestore(&chip->lock, flags);
- if (time <= 0) {
+ if (--timeout < 0) {
snd_printk("mce_down - auto calibration time out (3)\n");
return;
}
- set_current_state(TASK_INTERRUPTIBLE);
- time = schedule_timeout(time);
+ msleep(10);
spin_lock_irqsave(&chip->lock, flags);
}
spin_unlock_irqrestore(&chip->lock, flags);
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 1d0aa0332403af..f554be7b828f62 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -374,7 +374,7 @@ static int parse_audio_unit(mixer_build_t *state, int unitid);
static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs)
{
int idx = ich * num_outs + och;
- return bmap[-(idx >> 3)] & (0x80 >> (idx & 7));
+ return bmap[idx >> 3] & (0x80 >> (idx & 7));
}
@@ -931,14 +931,14 @@ static int parse_audio_feature_unit(mixer_build_t *state, int unitid, unsigned c
*/
static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
- int in_ch, int unitid)
+ int in_pin, int in_ch, int unitid,
+ usb_audio_term_t *iterm)
{
usb_mixer_elem_info_t *cval;
- unsigned int num_ins = desc[4];
- unsigned int num_outs = desc[5 + num_ins];
+ unsigned int input_pins = desc[4];
+ unsigned int num_outs = desc[5 + input_pins];
unsigned int i, len;
snd_kcontrol_t *kctl;
- usb_audio_term_t iterm;
if (check_ignored_ctl(state, unitid, 0))
return;
@@ -947,16 +947,13 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
if (! cval)
return;
- if (check_input_term(state, desc[5 + in_ch], &iterm) < 0)
- return;
-
cval->chip = state->chip;
cval->ctrlif = state->ctrlif;
cval->id = unitid;
cval->control = in_ch + 1; /* based on 1 */
cval->val_type = USB_MIXER_S16;
for (i = 0; i < num_outs; i++) {
- if (check_matrix_bitmap(desc + 9 + num_ins, in_ch, i, num_outs)) {
+ if (check_matrix_bitmap(desc + 9 + input_pins, in_ch, i, num_outs)) {
cval->cmask |= (1 << i);
cval->channels++;
}
@@ -975,9 +972,9 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name));
if (! len)
- len = get_term_name(state, &iterm, kctl->id.name, sizeof(kctl->id.name), 0);
+ len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
if (! len)
- len = sprintf(kctl->id.name, "Mixer Source %d", in_ch);
+ len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
strlcat(kctl->id.name + len, " Volume", sizeof(kctl->id.name));
snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
@@ -991,17 +988,44 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
*/
static int parse_audio_mixer_unit(mixer_build_t *state, int unitid, unsigned char *desc)
{
- int num_ins, num_outs;
- int i, err;
- if (desc[0] < 12 || ! (num_ins = desc[4]) || ! (num_outs = desc[5 + num_ins]))
+ usb_audio_term_t iterm;
+ int input_pins, num_ins, num_outs;
+ int pin, ich, err;
+
+ if (desc[0] < 11 || ! (input_pins = desc[4]) || ! (num_outs = desc[5 + input_pins])) {
+ snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid);
return -EINVAL;
+ }
+ /* no bmControls field (e.g. Maya44) -> ignore */
+ if (desc[0] <= 10 + input_pins) {
+ snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid);
+ return 0;
+ }
- for (i = 0; i < num_ins; i++) {
- err = parse_audio_unit(state, desc[5 + i]);
+ num_ins = 0;
+ ich = 0;
+ for (pin = 0; pin < input_pins; pin++) {
+ err = parse_audio_unit(state, desc[5 + pin]);
+ if (err < 0)
+ return err;
+ err = check_input_term(state, desc[5 + pin], &iterm);
if (err < 0)
return err;
- if (check_matrix_bitmap(desc + 9 + num_ins, i, 0, num_outs))
- build_mixer_unit_ctl(state, desc, i, unitid);
+ num_ins += iterm.channels;
+ for (; ich < num_ins; ++ich) {
+ int och, ich_has_controls = 0;
+
+ for (och = 0; och < num_outs; ++och) {
+ if (check_matrix_bitmap(desc + 9 + input_pins,
+ ich, och, num_outs)) {
+ ich_has_controls = 1;
+ break;
+ }
+ }
+ if (ich_has_controls)
+ build_mixer_unit_ctl(state, desc, pin, ich,
+ unitid, &iterm);
+ }
}
return 0;
}
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index e6717f3e1bfc2c..97c9d45d7b792b 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -95,20 +95,14 @@ static unsigned int snd_us428ctls_poll(snd_hwdep_t *hw, struct file *file, poll_
{
unsigned int mask = 0;
usX2Ydev_t *us428 = (usX2Ydev_t*)hw->private_data;
- static unsigned LastN;
-
+ us428ctls_sharedmem_t *shm = us428->us428ctls_sharedmem;
if (us428->chip_status & USX2Y_STAT_CHIP_HUP)
return POLLHUP;
poll_wait(file, &us428->us428ctls_wait_queue_head, wait);
- down(&us428->open_mutex);
- if (us428->us428ctls_sharedmem
- && us428->us428ctls_sharedmem->CtlSnapShotLast != LastN) {
+ if (shm != NULL && shm->CtlSnapShotLast != shm->CtlSnapShotRed)
mask |= POLLIN;
- LastN = us428->us428ctls_sharedmem->CtlSnapShotLast;
- }
- up(&us428->open_mutex);
return mask;
}
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 82ecbf6025b05d..cca3d26b3c0688 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -1,6 +1,22 @@
/*
- * usbus428.c - ALSA USB US-428 Driver
+ * usbusy2y.c - ALSA USB US-428 Driver
*
+2004-10-26 Karsten Wiese
+ Version 0.8.6:
+ wake_up() process waiting in usX2Y_urbs_start() on error.
+
+2004-10-21 Karsten Wiese
+ Version 0.8.5:
+ nrpacks is runtime or compiletime configurable now with tested values from 1 to 4.
+
+2004-10-03 Karsten Wiese
+ Version 0.8.2:
+ Avoid any possible racing while in prepare callback.
+
+2004-09-30 Karsten Wiese
+ Version 0.8.0:
+ Simplified things and made ohci work again.
+
2004-09-20 Karsten Wiese
Version 0.7.3:
Use usb_kill_urb() instead of deprecated (kernel 2.6.9) usb_unlink_urb().
@@ -84,7 +100,7 @@
Version 0.0.2: midi works with snd-usb-midi, audio (only fullduplex now) with i.e. bristol.
The firmware has been sniffed from win2k us-428 driver 3.09.
- * Copyright (c) 2002 Karsten Wiese
+ * Copyright (c) 2002 - 2004 Karsten Wiese
*
* 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
@@ -119,7 +135,7 @@
MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
-MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.7.3");
+MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.6");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}");
@@ -325,7 +341,8 @@ static snd_card_t* usX2Y_create_card(struct usb_device* device)
card->private_free = snd_usX2Y_card_private_free;
usX2Y(card)->chip.dev = device;
usX2Y(card)->chip.card = card;
- init_MUTEX (&usX2Y(card)->open_mutex);
+ init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
+ init_MUTEX (&usX2Y(card)->prepare_mutex);
INIT_LIST_HEAD(&usX2Y(card)->chip.midi_list);
strcpy(card->driver, "USB "NAME_ALLCAPS"");
sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index 71883dc170fb99..9f1dc0d849928b 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -3,15 +3,8 @@
#include "../usbaudio.h"
#include "usbus428ctldefs.h"
-#define NRURBS 2 /* */
-#define NRPACKS 1 /* FIXME: Currently only 1 works.
- usb-frames/ms per urb: 1 and 2 are supported.
- setting to 2 will PERHAPS make it easier for slow machines.
- Jitter will be higher though.
- On my PIII 500Mhz Laptop setting to 1 is the only way to go
- for PLAYING synths. i.e. Jack & Aeolus sound quit nicely
- at 4 periods 64 frames.
- */
+#define NRURBS 2
+
#define URBS_AsyncSeq 10
#define URB_DataLen_AsyncSeq 32
@@ -40,15 +33,43 @@ typedef struct {
snd_usX2Y_AsyncSeq_t AS04;
unsigned int rate,
format;
- int refframes;
int chip_status;
- struct semaphore open_mutex;
+ struct semaphore prepare_mutex;
us428ctls_sharedmem_t *us428ctls_sharedmem;
+ int wait_iso_frame;
wait_queue_head_t us428ctls_wait_queue_head;
- snd_usX2Y_substream_t *substream[4];
+ snd_usX2Y_substream_t *subs[4];
+ snd_usX2Y_substream_t * volatile prepare_subs;
+ wait_queue_head_t prepare_wait_queue;
} usX2Ydev_t;
+struct snd_usX2Y_substream {
+ usX2Ydev_t *usX2Y;
+ snd_pcm_substream_t *pcm_substream;
+
+ int endpoint;
+ unsigned int maxpacksize; /* max packet size in bytes */
+
+ atomic_t state;
+#define state_STOPPED 0
+#define state_STARTING1 1
+#define state_STARTING2 2
+#define state_STARTING3 3
+#define state_PREPARED 4
+#define state_PRERUNNING 6
+#define state_RUNNING 8
+
+ int hwptr; /* free frame position in the buffer (only for playback) */
+ int hwptr_done; /* processed frame position in the buffer */
+ int transfer_done; /* processed frames since last period update */
+
+ struct urb *urb[NRURBS]; /* data urb table */
+ struct urb *completed_urb;
+ char *tmpbuf; /* temporary buffer for playback */
+};
+
+
#define usX2Y(c) ((usX2Ydev_t*)(c)->private_data)
int usX2Y_audio_create(snd_card_t* card);
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index e32673e707915a..152bfa2ff39e91 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -1,10 +1,9 @@
/*
- * US-428 AUDIO
-
- * Copyright (c) 2002-2003 by Karsten Wiese
-
+ * US-X2Y AUDIO
+ * Copyright (c) 2002-2004 by Karsten Wiese
+ *
* based on
-
+ *
* (Tentative) USB Audio Driver for ALSA
*
* Main and PCM part
@@ -42,33 +41,30 @@
#include "usx2y.h"
#include "usbusx2y.h"
-
-struct snd_usX2Y_substream {
- usX2Ydev_t *usX2Y;
- snd_pcm_substream_t *pcm_substream;
-
- unsigned char endpoint;
- unsigned int datapipe; /* the data i/o pipe */
- unsigned int maxpacksize; /* max packet size in bytes */
-
- char prepared,
- running,
- stalled;
-
- int hwptr; /* free frame position in the buffer (only for playback) */
- int hwptr_done; /* processed frame position in the buffer */
- int transfer_done; /* processed frames since last period update */
-
- struct urb *urb[NRURBS]; /* data urb table */
- int next_urb_complete;
- struct urb *completed_urb;
- char *tmpbuf; /* temporary buffer for playback */
- volatile int submitted_urbs;
- wait_queue_head_t wait_queue;
-};
-
-
-
+#define USX2Y_NRPACKS 4 /* Default value used for nr of packs per urb.
+ 1 to 4 have been tested ok on uhci.
+ To use 3 on ohci, you'd need a patch:
+ look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
+ "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
+ .
+ 1, 2 and 4 work out of the box on ohci, if I recall correctly.
+ Bigger is safer operation,
+ smaller gives lower latencies.
+ */
+#define USX2Y_NRPACKS_VARIABLE y /* If your system works ok with this module's parameter
+ nrpacks set to 1, you might as well comment
+ this #define out, and thereby produce smaller, faster code.
+ You'd also set USX2Y_NRPACKS to 1 then.
+ */
+
+#ifdef USX2Y_NRPACKS_VARIABLE
+ static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
+ #define nr_of_packs() nrpacks
+ module_param(nrpacks, int, 0444);
+ MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
+#else
+ #define nr_of_packs() USX2Y_NRPACKS
+#endif
@@ -80,15 +76,15 @@ static int usX2Y_urb_capt_retire(snd_usX2Y_substream_t *subs)
int i, len, lens = 0, hwptr_done = subs->hwptr_done;
usX2Ydev_t *usX2Y = subs->usX2Y;
- for (i = 0; i < NRPACKS; i++) {
+ for (i = 0; i < nr_of_packs(); i++) {
cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
- snd_printdd("activ frame status %i\n", urb->iso_frame_desc[i].status);
+ snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
return urb->iso_frame_desc[i].status;
}
len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
if (! len) {
- snd_printk("0 == len ERROR!\n");
+ snd_printd("0 == len ERROR!\n");
continue;
}
@@ -134,7 +130,7 @@ static int usX2Y_urb_play_prepare(snd_usX2Y_substream_t *subs,
snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
count = 0;
- for (pack = 0; pack < NRPACKS; pack++) {
+ for (pack = 0; pack < nr_of_packs(); pack++) {
/* calculate the size of a packet */
counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
count += counts;
@@ -142,28 +138,32 @@ static int usX2Y_urb_play_prepare(snd_usX2Y_substream_t *subs,
snd_printk("should not be here with counts=%i\n", counts);
return -EPIPE;
}
-
/* set up descriptor */
- urb->iso_frame_desc[pack].offset = pack ? urb->iso_frame_desc[pack - 1].offset + urb->iso_frame_desc[pack - 1].length : 0;
- urb->iso_frame_desc[pack].length = counts * usX2Y->stride;
+ urb->iso_frame_desc[pack].offset = pack ?
+ urb->iso_frame_desc[pack - 1].offset + urb->iso_frame_desc[pack - 1].length :
+ 0;
+ urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
}
- if (subs->hwptr + count > runtime->buffer_size) {
- /* err, the transferred area goes over buffer boundary.
- * copy the data to the temp buffer.
- */
- int len;
- len = runtime->buffer_size - subs->hwptr;
- urb->transfer_buffer = subs->tmpbuf;
- memcpy(subs->tmpbuf, runtime->dma_area + subs->hwptr * usX2Y->stride, len * usX2Y->stride);
- memcpy(subs->tmpbuf + len * usX2Y->stride, runtime->dma_area, (count - len) * usX2Y->stride);
- subs->hwptr += count;
- subs->hwptr -= runtime->buffer_size;
- } else {
- /* set the buffer pointer */
- urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
- if ((subs->hwptr += count) >= runtime->buffer_size)
+ if (atomic_read(&subs->state) >= state_PRERUNNING)
+ if (subs->hwptr + count > runtime->buffer_size) {
+ /* err, the transferred area goes over buffer boundary.
+ * copy the data to the temp buffer.
+ */
+ int len;
+ len = runtime->buffer_size - subs->hwptr;
+ urb->transfer_buffer = subs->tmpbuf;
+ memcpy(subs->tmpbuf, runtime->dma_area + subs->hwptr * usX2Y->stride, len * usX2Y->stride);
+ memcpy(subs->tmpbuf + len * usX2Y->stride, runtime->dma_area, (count - len) * usX2Y->stride);
+ subs->hwptr += count;
+ subs->hwptr -= runtime->buffer_size;
+ } else {
+ /* set the buffer pointer */
+ urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
+ if ((subs->hwptr += count) >= runtime->buffer_size)
subs->hwptr -= runtime->buffer_size;
- }
+ }
+ else
+ urb->transfer_buffer = subs->tmpbuf;
urb->transfer_buffer_length = count * usX2Y->stride;
return 0;
}
@@ -173,14 +173,10 @@ static int usX2Y_urb_play_prepare(snd_usX2Y_substream_t *subs,
*
* update the current position and call callback if a period is processed.
*/
-inline static int usX2Y_urb_play_retire(snd_usX2Y_substream_t *subs, struct urb *urb)
+static void usX2Y_urb_play_retire(snd_usX2Y_substream_t *subs, struct urb *urb)
{
snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
- int len = (urb->iso_frame_desc[0].actual_length
-#if NRPACKS > 1
- + urb->iso_frame_desc[1].actual_length
-#endif
- ) / subs->usX2Y->stride;
+ int len = urb->actual_length / subs->usX2Y->stride;
subs->transfer_done += len;
subs->hwptr_done += len;
@@ -190,224 +186,206 @@ inline static int usX2Y_urb_play_retire(snd_usX2Y_substream_t *subs, struct urb
subs->transfer_done -= runtime->period_size;
snd_pcm_period_elapsed(subs->pcm_substream);
}
- return 0;
}
-inline static int usX2Y_urb_submit(snd_usX2Y_substream_t *subs, struct urb *urb, int frame)
+static int usX2Y_urb_submit(snd_usX2Y_substream_t *subs, struct urb *urb, int frame)
{
int err;
if (!urb)
return -ENODEV;
- urb->start_frame = (frame + NRURBS*NRPACKS) & (1024 - 1);
+ urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks
urb->hcpriv = NULL;
urb->dev = subs->usX2Y->chip.dev; /* we need to set this at each time */
if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- snd_printk("%i\n", err);
+ snd_printk("usb_submit_urb() returned %i\n", err);
return err;
- } else {
- subs->submitted_urbs++;
- if (subs->next_urb_complete < 0)
- subs->next_urb_complete = 0;
}
return 0;
}
-
-static inline int frame_distance(int from, int to)
+static inline int usX2Y_usbframe_complete(snd_usX2Y_substream_t *capsubs, snd_usX2Y_substream_t *playbacksubs, int frame)
{
- int distance = to - from;
- if (distance < -512)
- distance += 1024;
- else
- if (distance > 511)
- distance -= 1024;
- return distance;
-}
+ int err, state;
+ {
+ struct urb *urb = playbacksubs->completed_urb;
+ state = atomic_read(&playbacksubs->state);
+ if (NULL != urb) {
+ if (state == state_RUNNING)
+ usX2Y_urb_play_retire(playbacksubs, urb);
+ else
+ if (state >= state_PRERUNNING) {
+ atomic_inc(&playbacksubs->state);
+ }
+ } else {
+ switch (state) {
+ case state_STARTING1:
+ urb = playbacksubs->urb[0];
+ atomic_inc(&playbacksubs->state);
+ break;
+ case state_STARTING2:
+ urb = playbacksubs->urb[1];
+ atomic_inc(&playbacksubs->state);
+ break;
+ }
+ }
+ if (urb) {
+ if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) ||
+ (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
+ return err;
+ }
+ }
-static void usX2Y_subs_set_next_urb_complete(snd_usX2Y_substream_t *subs)
-{
- int next_urb_complete = subs->next_urb_complete + 1;
- int distance;
- if (next_urb_complete >= NRURBS)
- next_urb_complete = 0;
- distance = frame_distance(subs->completed_urb->start_frame,
- subs->urb[next_urb_complete]->start_frame);
- if (1 == distance) {
- subs->next_urb_complete = next_urb_complete;
- } else {
- snd_printdd("distance %i not set_nuc %i %i %i \n", distance, subs->endpoint, next_urb_complete, subs->urb[next_urb_complete]->status);
- subs->next_urb_complete = -1;
+ playbacksubs->completed_urb = NULL;
+ }
+ state = atomic_read(&capsubs->state);
+ if (state >= state_PREPARED) {
+ if (state == state_RUNNING) {
+ if ((err = usX2Y_urb_capt_retire(capsubs)))
+ return err;
+ } else
+ if (state >= state_PRERUNNING) {
+ atomic_inc(&capsubs->state);
+ }
+ if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
+ return err;
}
+ capsubs->completed_urb = NULL;
+ return 0;
}
-static inline void usX2Y_usbframe_complete(snd_usX2Y_substream_t *capsubs, snd_usX2Y_substream_t *playbacksubs, int frame)
+static void usX2Y_clients_stop(usX2Ydev_t *usX2Y)
{
- {
- struct urb *urb;
- if ((urb = playbacksubs->completed_urb)) {
- if (playbacksubs->prepared)
- usX2Y_urb_play_retire(playbacksubs, urb);
- usX2Y_subs_set_next_urb_complete(playbacksubs);
+ int s, u;
+ for (s = 0; s < 4; s++) {
+ snd_usX2Y_substream_t *subs = usX2Y->subs[s];
+ if (subs) {
+ snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
+ atomic_set(&subs->state, state_STOPPED);
}
- if (playbacksubs->running) {
- if (NULL == urb)
- urb = playbacksubs->urb[playbacksubs->next_urb_complete + 1];
- if (urb && 0 == usX2Y_urb_play_prepare(playbacksubs,
- capsubs->completed_urb,
- urb)) {
- if (usX2Y_urb_submit(playbacksubs, urb, frame) < 0)
- return;
- } else
- snd_pcm_stop(playbacksubs->pcm_substream, SNDRV_PCM_STATE_XRUN);
+ }
+ for (s = 0; s < 4; s++) {
+ snd_usX2Y_substream_t *subs = usX2Y->subs[s];
+ if (subs) {
+ if (atomic_read(&subs->state) >= state_PRERUNNING) {
+ snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
+ }
+ for (u = 0; u < NRURBS; u++) {
+ struct urb *urb = subs->urb[u];
+ if (NULL != urb)
+ snd_printdd("%i status=%i start_frame=%i\n", u, urb->status, urb->start_frame);
+ }
}
- playbacksubs->completed_urb = NULL;
}
- if (capsubs->running)
- usX2Y_urb_capt_retire(capsubs);
- usX2Y_subs_set_next_urb_complete(capsubs);
- if (capsubs->prepared)
- usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame);
- capsubs->completed_urb = NULL;
+ usX2Y->prepare_subs = NULL;
+ wake_up(&usX2Y->prepare_wait_queue);
}
-
-static void usX2Y_clients_stop(snd_usX2Y_substream_t *subs)
+static void usX2Y_error_urb_status(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
{
- usX2Ydev_t *usX2Y = subs->usX2Y;
- int i;
- for (i = 0; i < 4; i++) {
- snd_usX2Y_substream_t *substream = usX2Y->substream[i];
- if (substream && substream->running)
- snd_pcm_stop(substream->pcm_substream, SNDRV_PCM_STATE_XRUN);
- }
+ snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
+ urb->status = 0;
+ usX2Y_clients_stop(usX2Y);
}
+static void usX2Y_error_sequence(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
+{
+ snd_printk("Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
+ "Most propably some urb of usb-frame %i is still missing.\n"
+ "Cause could be too long delays in usb-hcd interrupt handling.\n",
+ usb_get_current_frame_number(usX2Y->chip.dev),
+ subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
+ usX2Y_clients_stop(usX2Y);
+}
static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs)
{
snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
+ usX2Ydev_t *usX2Y = subs->usX2Y;
- subs->submitted_urbs--;
- if (urb->status) {
- snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
- subs->stalled = 1;
- usX2Y_clients_stop(subs);
- urb->status = 0;
+ if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
+ snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", usb_get_current_frame_number(usX2Y->chip.dev), subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", urb->status, urb->start_frame);
+ return;
+ }
+ if (unlikely(urb->status)) {
+ usX2Y_error_urb_status(usX2Y, subs, urb);
return;
}
- if (urb == subs->urb[subs->next_urb_complete]) {
+ if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame))
subs->completed_urb = urb;
- } else {
- snd_printk("Sequence Error!(ep=%i;nuc=%i,frame=%i)\n",
- subs->endpoint, subs->next_urb_complete, urb->start_frame);
- subs->stalled = 1;
- usX2Y_clients_stop(subs);
+ else {
+ usX2Y_error_sequence(usX2Y, subs, urb);
return;
}
- if (waitqueue_active(&subs->wait_queue))
- wake_up(&subs->wait_queue);
{
- snd_usX2Y_substream_t *capsubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE],
- *playbacksubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK];
- if (capsubs->completed_urb &&
- (playbacksubs->completed_urb ||
- !playbacksubs->prepared ||
- (playbacksubs->prepared && (playbacksubs->next_urb_complete < 0 || // not started yet
- frame_distance(capsubs->completed_urb->start_frame,
- playbacksubs->urb[playbacksubs->next_urb_complete]->start_frame)
- > 0 || // other expected later
- playbacksubs->stalled))))
- usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame);
+ snd_usX2Y_substream_t *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
+ *playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+ if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
+ (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
+ if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) {
+ if (nr_of_packs() <= urb->start_frame &&
+ urb->start_frame <= (2 * nr_of_packs() - 1)) // uhci and ohci
+ usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
+ else
+ usX2Y->wait_iso_frame += nr_of_packs();
+ } else {
+ snd_printdd("\n");
+ usX2Y_clients_stop(usX2Y);
+ }
+ }
}
}
-
-static int usX2Y_urbs_capt_start(snd_usX2Y_substream_t *subs)
+static void usX2Y_urbs_set_complete(usX2Ydev_t * usX2Y, void (*complete)(struct urb *, struct pt_regs *))
{
- int i, err;
-
- for (i = 0; i < NRURBS; i++) {
- unsigned long pack;
- struct urb *urb = subs->urb[i];
- urb->dev = subs->usX2Y->chip.dev;
- urb->transfer_flags = URB_ISO_ASAP;
- for (pack = 0; pack < NRPACKS; pack++) {
- urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
- urb->iso_frame_desc[pack].length = subs->maxpacksize;
- }
- urb->transfer_buffer_length = subs->maxpacksize * NRPACKS;
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
- return -EPIPE;
- } else {
- subs->submitted_urbs++;
- }
- urb->transfer_flags = 0;
+ int s, u;
+ for (s = 0; s < 4; s++) {
+ snd_usX2Y_substream_t *subs = usX2Y->subs[s];
+ if (NULL != subs)
+ for (u = 0; u < NRURBS; u++) {
+ struct urb * urb = subs->urb[u];
+ if (NULL != urb)
+ urb->complete = complete;
+ }
}
- subs->stalled = 0;
- subs->next_urb_complete = 0;
- subs->prepared = 1;
- return 0;
}
-/*
- * wait until all urbs are processed.
- */
-static int usX2Y_urbs_wait_clear(snd_usX2Y_substream_t *subs)
-{
- int timeout = HZ;
-
- do {
- if (0 == subs->submitted_urbs)
- break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- snd_printdd("snd_usX2Y_urbs_wait_clear waiting\n");
- schedule_timeout(1);
- } while (--timeout > 0);
- if (subs->submitted_urbs)
- snd_printk(KERN_ERR "timeout: still %d active urbs..\n", subs->submitted_urbs);
- return 0;
-}
-/*
- * return the current pcm pointer. just return the hwptr_done value.
- */
-static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(snd_pcm_substream_t *substream)
+static void usX2Y_subs_startup_finish(usX2Ydev_t * usX2Y)
{
- snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
- return subs->hwptr_done;
+ usX2Y_urbs_set_complete(usX2Y, i_usX2Y_urb_complete);
+ usX2Y->prepare_subs = NULL;
}
-/*
- * start/stop substream
- */
-static int snd_usX2Y_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+
+static void i_usX2Y_subs_startup(struct urb *urb, struct pt_regs *regs)
{
- snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
+ snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
+ usX2Ydev_t *usX2Y = subs->usX2Y;
+ snd_usX2Y_substream_t *prepare_subs = usX2Y->prepare_subs;
+ if (NULL != prepare_subs)
+ if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
+ usX2Y_subs_startup_finish(usX2Y);
+ atomic_inc(&prepare_subs->state);
+ wake_up(&usX2Y->prepare_wait_queue);
+ }
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_printdd("snd_usX2Y_pcm_trigger(START)\n");
- if (subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE]->stalled)
- return -EPIPE;
- else
- subs->running = 1;
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n");
- subs->running = 0;
- break;
- default:
- return -EINVAL;
- }
- return 0;
+ i_usX2Y_urb_complete(urb, regs);
}
+static void usX2Y_subs_prepare(snd_usX2Y_substream_t *subs)
+{
+ snd_printdd("usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n", subs, subs->endpoint, subs->urb[0], subs->urb[1]);
+ /* reset the pointer */
+ subs->hwptr = 0;
+ subs->hwptr_done = 0;
+ subs->transfer_done = 0;
+}
static void usX2Y_urb_release(struct urb** urb, int free_tb)
{
if (*urb) {
+ usb_kill_urb(*urb);
if (free_tb)
kfree((*urb)->transfer_buffer);
usb_free_urb(*urb);
@@ -415,97 +393,181 @@ static void usX2Y_urb_release(struct urb** urb, int free_tb)
}
}
/*
- * release a substream
+ * release a substreams urbs
*/
static void usX2Y_urbs_release(snd_usX2Y_substream_t *subs)
{
int i;
- snd_printdd("snd_usX2Y_urbs_release() %i\n", subs->endpoint);
- usX2Y_urbs_wait_clear(subs);
+ snd_printdd("usX2Y_urbs_release() %i\n", subs->endpoint);
for (i = 0; i < NRURBS; i++)
- usX2Y_urb_release(subs->urb + i, subs != subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK]);
+ usX2Y_urb_release(subs->urb + i, subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
if (subs->tmpbuf) {
kfree(subs->tmpbuf);
subs->tmpbuf = NULL;
}
}
-
-static void usX2Y_substream_prepare(snd_usX2Y_substream_t *subs)
-{
- snd_printdd("usX2Y_substream_prepare() ep=%i urb0=%p urb1=%p\n", subs->endpoint, subs->urb[0], subs->urb[1]);
- /* reset the pointer */
- subs->hwptr = 0;
- subs->hwptr_done = 0;
- subs->transfer_done = 0;
-}
-
-
/*
* initialize a substream's urbs
*/
static int usX2Y_urbs_allocate(snd_usX2Y_substream_t *subs)
{
int i;
- int is_playback = subs == subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK];
+ unsigned int datapipe; /* the data i/o pipe */
+ int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
struct usb_device *dev = subs->usX2Y->chip.dev;
- snd_assert(!subs->prepared, return 0);
-
if (is_playback) { /* allocate a temporary buffer for playback */
- subs->datapipe = usb_sndisocpipe(dev, subs->endpoint);
+ datapipe = usb_sndisocpipe(dev, subs->endpoint);
subs->maxpacksize = dev->epmaxpacketout[subs->endpoint];
if (NULL == subs->tmpbuf) {
- subs->tmpbuf = kcalloc(NRPACKS, subs->maxpacksize, GFP_KERNEL);
+ subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL);
if (NULL == subs->tmpbuf) {
snd_printk(KERN_ERR "cannot malloc tmpbuf\n");
return -ENOMEM;
}
}
} else {
- subs->datapipe = usb_rcvisocpipe(dev, subs->endpoint);
+ datapipe = usb_rcvisocpipe(dev, subs->endpoint);
subs->maxpacksize = dev->epmaxpacketin[subs->endpoint];
}
/* allocate and initialize data urbs */
for (i = 0; i < NRURBS; i++) {
struct urb** purb = subs->urb + i;
- if (*purb)
+ if (*purb) {
+ usb_kill_urb(*purb);
continue;
- *purb = usb_alloc_urb(NRPACKS, GFP_KERNEL);
+ }
+ *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
if (NULL == *purb) {
usX2Y_urbs_release(subs);
return -ENOMEM;
}
if (!is_playback && !(*purb)->transfer_buffer) {
/* allocate a capture buffer per urb */
- (*purb)->transfer_buffer = kmalloc(subs->maxpacksize*NRPACKS, GFP_KERNEL);
+ (*purb)->transfer_buffer = kmalloc(subs->maxpacksize * nr_of_packs(), GFP_KERNEL);
if (NULL == (*purb)->transfer_buffer) {
usX2Y_urbs_release(subs);
return -ENOMEM;
}
}
(*purb)->dev = dev;
- (*purb)->pipe = subs->datapipe;
- (*purb)->number_of_packets = NRPACKS;
+ (*purb)->pipe = datapipe;
+ (*purb)->number_of_packets = nr_of_packs();
(*purb)->context = subs;
(*purb)->interval = 1;
- (*purb)->complete = snd_usb_complete_callback(i_usX2Y_urb_complete);
+ (*purb)->complete = i_usX2Y_subs_startup;
}
return 0;
}
-static void i_usX2Y_04Int(struct urb* urb, struct pt_regs *regs)
+static void usX2Y_subs_startup(snd_usX2Y_substream_t *subs)
{
- usX2Ydev_t* usX2Y = urb->context;
-
- if (urb->status) {
- snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status);
- return;
+ usX2Ydev_t *usX2Y = subs->usX2Y;
+ usX2Y->prepare_subs = subs;
+ subs->urb[0]->start_frame = -1;
+ wmb();
+ usX2Y_urbs_set_complete(usX2Y, i_usX2Y_subs_startup);
+}
+
+static int usX2Y_urbs_start(snd_usX2Y_substream_t *subs)
+{
+ int i, err;
+ usX2Ydev_t *usX2Y = subs->usX2Y;
+
+ if ((err = usX2Y_urbs_allocate(subs)) < 0)
+ return err;
+ subs->completed_urb = NULL;
+ for (i = 0; i < 4; i++) {
+ snd_usX2Y_substream_t *subs = usX2Y->subs[i];
+ if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
+ goto start;
}
- if (0 == --usX2Y->US04->len)
- wake_up(&usX2Y->In04WaitQueue);
+ usX2Y->wait_iso_frame = -1;
+ start:
+ {
+ usX2Y_subs_startup(subs);
+ for (i = 0; i < NRURBS; i++) {
+ struct urb *urb = subs->urb[i];
+ if (usb_pipein(urb->pipe)) {
+ unsigned long pack;
+ if (0 == i)
+ atomic_set(&subs->state, state_STARTING3);
+ urb->dev = usX2Y->chip.dev;
+ urb->transfer_flags = URB_ISO_ASAP;
+ for (pack = 0; pack < nr_of_packs(); pack++) {
+ urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
+ urb->iso_frame_desc[pack].length = subs->maxpacksize;
+ }
+ urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
+ if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
+ snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
+ err = -EPIPE;
+ goto cleanup;
+ } else {
+ if (0 > usX2Y->wait_iso_frame)
+ usX2Y->wait_iso_frame = urb->start_frame;
+ }
+ urb->transfer_flags = 0;
+ } else {
+ atomic_set(&subs->state, state_STARTING1);
+ break;
+ }
+ }
+ err = 0;
+ wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
+ if (atomic_read(&subs->state) != state_PREPARED) {
+ err = -EPIPE;
+ }
+
+ cleanup:
+ if (err) {
+ usX2Y_subs_startup_finish(usX2Y);
+ usX2Y_clients_stop(usX2Y); // something is completely wroong > stop evrything
+ }
+ }
+ return err;
+}
+
+/*
+ * return the current pcm pointer. just return the hwptr_done value.
+ */
+static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(snd_pcm_substream_t *substream)
+{
+ snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
+ return subs->hwptr_done;
+}
+/*
+ * start/stop substream
+ */
+static int snd_usX2Y_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+{
+ snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ snd_printdd("snd_usX2Y_pcm_trigger(START)\n");
+ if (atomic_read(&subs->state) == state_PREPARED &&
+ atomic_read(&subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= state_PREPARED) {
+ atomic_set(&subs->state, state_PRERUNNING);
+ } else {
+ snd_printdd("\n");
+ return -EPIPE;
+ }
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n");
+ if (atomic_read(&subs->state) >= state_PRERUNNING)
+ atomic_set(&subs->state, state_PREPARED);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
}
+
+
/*
* allocate a buffer, setup samplerate
*
@@ -592,76 +654,74 @@ static struct s_c2 SetRate48000[] =
};
#define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)
+static void i_usX2Y_04Int(struct urb* urb, struct pt_regs *regs)
+{
+ usX2Ydev_t* usX2Y = urb->context;
+
+ if (urb->status) {
+ snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status);
+ }
+ if (0 == --usX2Y->US04->len)
+ wake_up(&usX2Y->In04WaitQueue);
+}
+
static int usX2Y_rate_set(usX2Ydev_t *usX2Y, int rate)
{
int err = 0, i;
snd_usX2Y_urbSeq_t *us = NULL;
int *usbdata = NULL;
- DECLARE_WAITQUEUE(wait, current);
struct s_c2 *ra = rate == 48000 ? SetRate48000 : SetRate44100;
if (usX2Y->rate != rate) {
- do {
- us = kmalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
- if (NULL == us) {
- err = -ENOMEM;
- break;
- }
- memset(us, 0, sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS);
- usbdata = kmalloc(sizeof(int)*NOOF_SETRATE_URBS, GFP_KERNEL);
- if (NULL == usbdata) {
+ us = kmalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
+ if (NULL == us) {
+ err = -ENOMEM;
+ goto cleanup;
+ }
+ memset(us, 0, sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS);
+ usbdata = kmalloc(sizeof(int)*NOOF_SETRATE_URBS, GFP_KERNEL);
+ if (NULL == usbdata) {
+ err = -ENOMEM;
+ goto cleanup;
+ }
+ for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
+ if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
err = -ENOMEM;
- break;
+ goto cleanup;
}
- for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
- if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
- err = -ENOMEM;
- break;
- }
- ((char*)(usbdata + i))[0] = ra[i].c1;
- ((char*)(usbdata + i))[1] = ra[i].c2;
- usb_fill_bulk_urb(us->urb[i], usX2Y->chip.dev, usb_sndbulkpipe(usX2Y->chip.dev, 4),
- usbdata + i, 2, i_usX2Y_04Int, usX2Y);
+ ((char*)(usbdata + i))[0] = ra[i].c1;
+ ((char*)(usbdata + i))[1] = ra[i].c2;
+ usb_fill_bulk_urb(us->urb[i], usX2Y->chip.dev, usb_sndbulkpipe(usX2Y->chip.dev, 4),
+ usbdata + i, 2, i_usX2Y_04Int, usX2Y);
#ifdef OLD_USB
- us->urb[i]->transfer_flags = USB_QUEUE_BULK;
+ us->urb[i]->transfer_flags = USB_QUEUE_BULK;
#endif
- }
- if (err)
- break;
-
- add_wait_queue(&usX2Y->In04WaitQueue, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
- us->submitted = 0;
- us->len = NOOF_SETRATE_URBS;
- usX2Y->US04 = us;
-
- do {
- signed long timeout = schedule_timeout(HZ/2);
-
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
- }
- if (0 == timeout) {
- err = -ENODEV;
- break;
- }
- usX2Y->rate = rate;
- usX2Y->refframes = rate == 48000 ? 47 : 44;
- } while (0);
-
- remove_wait_queue(&usX2Y->In04WaitQueue, &wait);
- } while (0);
-
+ }
+ us->submitted = 0;
+ us->len = NOOF_SETRATE_URBS;
+ usX2Y->US04 = us;
+ wait_event_timeout(usX2Y->In04WaitQueue, 0 == us->len, HZ);
+ usX2Y->US04 = NULL;
+ if (us->len)
+ err = -ENODEV;
+ cleanup:
if (us) {
us->submitted = 2*NOOF_SETRATE_URBS;
for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
- usb_kill_urb(us->urb[i]);
- usb_free_urb(us->urb[i]);
+ struct urb *urb = us->urb[i];
+ if (urb->status) {
+ if (!err)
+ err = -ENODEV;
+ usb_kill_urb(urb);
+ }
+ usb_free_urb(urb);
}
usX2Y->US04 = NULL;
kfree(usbdata);
kfree(us);
+ if (!err) {
+ usX2Y->rate = rate;
+ }
}
}
@@ -745,27 +805,28 @@ static int snd_usX2Y_pcm_hw_free(snd_pcm_substream_t *substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
+ down(&subs->usX2Y->prepare_mutex);
snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
- snd_usX2Y_substream_t *cap_subs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE];
- subs->prepared = 0;
+ snd_usX2Y_substream_t *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+ atomic_set(&subs->state, state_STOPPED);
usX2Y_urbs_release(subs);
if (!cap_subs->pcm_substream ||
!cap_subs->pcm_substream->runtime ||
!cap_subs->pcm_substream->runtime->status ||
cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
- cap_subs->prepared = 0;
+ atomic_set(&cap_subs->state, state_STOPPED);
usX2Y_urbs_release(cap_subs);
}
} else {
- snd_usX2Y_substream_t *playback_subs = subs->usX2Y->substream[SNDRV_PCM_STREAM_PLAYBACK];
- if (!playback_subs->prepared) {
- subs->prepared = 0;
+ snd_usX2Y_substream_t *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+ if (atomic_read(&playback_subs->state) < state_PREPARED) {
+ atomic_set(&subs->state, state_STOPPED);
usX2Y_urbs_release(subs);
}
}
-
+ up(&subs->usX2Y->prepare_mutex);
return snd_pcm_lib_free_pages(substream);
}
/*
@@ -777,71 +838,32 @@ static int snd_usX2Y_pcm_prepare(snd_pcm_substream_t *substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
- snd_usX2Y_substream_t *capsubs = subs->usX2Y->substream[SNDRV_PCM_STREAM_CAPTURE];
+ usX2Ydev_t *usX2Y = subs->usX2Y;
+ snd_usX2Y_substream_t *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
int err = 0;
snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
+ down(&usX2Y->prepare_mutex);
+ usX2Y_subs_prepare(subs);
// Start hardware streams
// SyncStream first....
- if (! capsubs->prepared) {
- if (subs->usX2Y->format != runtime->format)
- if ((err = usX2Y_format_set(subs->usX2Y, runtime->format)) < 0)
- return err;
- if (subs->usX2Y->rate != runtime->rate)
- if ((err = usX2Y_rate_set(subs->usX2Y, runtime->rate)) < 0)
- return err;
- snd_printdd("starting capture pipe for playpipe\n");
- usX2Y_urbs_allocate(capsubs);
- capsubs->completed_urb = NULL;
- {
- DECLARE_WAITQUEUE(wait, current);
- add_wait_queue(&capsubs->wait_queue, &wait);
- if (0 <= (err = usX2Y_urbs_capt_start(capsubs))) {
- signed long timeout;
- set_current_state(TASK_INTERRUPTIBLE);
- timeout = schedule_timeout(HZ/4);
- if (signal_pending(current))
- err = -ERESTARTSYS;
- else {
- snd_printdd("%li\n", HZ/4 - timeout);
- if (0 == timeout)
- err = -EPIPE;
- }
- }
- remove_wait_queue(&capsubs->wait_queue, &wait);
- if (0 > err)
- return err;
- }
+ if (atomic_read(&capsubs->state) < state_PREPARED) {
+ if (usX2Y->format != runtime->format)
+ if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
+ goto up_prepare_mutex;
+ if (usX2Y->rate != runtime->rate)
+ if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
+ goto up_prepare_mutex;
+ snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
+ if (0 > (err = usX2Y_urbs_start(capsubs)))
+ goto up_prepare_mutex;
}
- if (subs != capsubs) {
- int u;
- if (!subs->prepared) {
- if ((err = usX2Y_urbs_allocate(subs)) < 0)
- return err;
- subs->prepared = 1;
- }
- while (subs->submitted_urbs)
- for (u = 0; u < NRURBS; u++) {
- snd_printdd("%i\n", subs->urb[u]->status);
- while(subs->urb[u]->status || NULL != subs->urb[u]->hcpriv) {
- signed long timeout;
- snd_printdd("ep=%i waiting for urb=%p status=%i hcpriv=%p\n",
- subs->endpoint, subs->urb[u],
- subs->urb[u]->status, subs->urb[u]->hcpriv);
- set_current_state(TASK_INTERRUPTIBLE);
- timeout = schedule_timeout(HZ/10);
- if (signal_pending(current)) {
- return -ERESTARTSYS;
- }
- }
- }
- subs->completed_urb = NULL;
- subs->next_urb_complete = -1;
- subs->stalled = 0;
- }
+ if (subs != capsubs && atomic_read(&subs->state) < state_PREPARED)
+ err = usX2Y_urbs_start(subs);
- usX2Y_substream_prepare(subs);
+ up_prepare_mutex:
+ up(&usX2Y->prepare_mutex);
return err;
}
@@ -933,7 +955,7 @@ static int usX2Y_audio_stream_new(snd_card_t *card, int playback_endpoint, int c
snd_pcm_t *pcm;
int err, i;
snd_usX2Y_substream_t **usX2Y_substream =
- usX2Y(card)->substream + 2 * usX2Y(card)->chip.pcm_devs;
+ usX2Y(card)->subs + 2 * usX2Y(card)->chip.pcm_devs;
for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
@@ -942,7 +964,6 @@ static int usX2Y_audio_stream_new(snd_card_t *card, int playback_endpoint, int c
snd_printk(KERN_ERR "cannot malloc\n");
return -ENOMEM;
}
- init_waitqueue_head(&usX2Y_substream[i]->wait_queue);
usX2Y_substream[i]->usX2Y = usX2Y(card);
}