diff options
Diffstat (limited to 'sound/isa/gus')
| -rw-r--r-- | sound/isa/gus/Makefile | 14 | ||||
| -rw-r--r-- | sound/isa/gus/gus_dma.c | 40 | ||||
| -rw-r--r-- | sound/isa/gus/gus_dram.c | 3 | ||||
| -rw-r--r-- | sound/isa/gus/gus_instr.c | 3 | ||||
| -rw-r--r-- | sound/isa/gus/gus_io.c | 3 | ||||
| -rw-r--r-- | sound/isa/gus/gus_irq.c | 31 | ||||
| -rw-r--r-- | sound/isa/gus/gus_main.c | 61 | ||||
| -rw-r--r-- | sound/isa/gus/gus_mem.c | 33 | ||||
| -rw-r--r-- | sound/isa/gus/gus_mem_proc.c | 51 | ||||
| -rw-r--r-- | sound/isa/gus/gus_mixer.c | 18 | ||||
| -rw-r--r-- | sound/isa/gus/gus_pcm.c | 47 | ||||
| -rw-r--r-- | sound/isa/gus/gus_reset.c | 3 | ||||
| -rw-r--r-- | sound/isa/gus/gus_sample.c | 165 | ||||
| -rw-r--r-- | sound/isa/gus/gus_simple.c | 634 | ||||
| -rw-r--r-- | sound/isa/gus/gus_synth.c | 312 | ||||
| -rw-r--r-- | sound/isa/gus/gus_tables.h | 2 | ||||
| -rw-r--r-- | sound/isa/gus/gus_timer.c | 3 | ||||
| -rw-r--r-- | sound/isa/gus/gus_uart.c | 13 | ||||
| -rw-r--r-- | sound/isa/gus/gus_volume.c | 4 | ||||
| -rw-r--r-- | sound/isa/gus/gusclassic.c | 296 | ||||
| -rw-r--r-- | sound/isa/gus/gusextreme.c | 387 | ||||
| -rw-r--r-- | sound/isa/gus/gusmax.c | 154 | ||||
| -rw-r--r-- | sound/isa/gus/interwave.c | 330 |
23 files changed, 657 insertions, 1950 deletions
diff --git a/sound/isa/gus/Makefile b/sound/isa/gus/Makefile index bae5dbd6c8e..6cd4ee03754 100644 --- a/sound/isa/gus/Makefile +++ b/sound/isa/gus/Makefile @@ -1,6 +1,6 @@ # # Makefile for ALSA -# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> +# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz> # snd-gus-lib-objs := gus_main.o \ @@ -9,7 +9,6 @@ snd-gus-lib-objs := gus_main.o \ gus_pcm.o gus_mixer.o \ gus_uart.o \ gus_reset.o -snd-gus-synth-objs := gus_synth.o gus_sample.o gus_simple.o gus_instr.o snd-gusclassic-objs := gusclassic.o snd-gusextreme-objs := gusextreme.o @@ -17,20 +16,9 @@ snd-gusmax-objs := gusmax.o snd-interwave-objs := interwave.o snd-interwave-stb-objs := interwave-stb.o -# -# this function returns: -# "m" - CONFIG_SND_SEQUENCER is m -# <empty string> - CONFIG_SND_SEQUENCER is undefined -# otherwise parameter #1 value -# -sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) - # Toplevel Module Dependency obj-$(CONFIG_SND_GUSCLASSIC) += snd-gusclassic.o snd-gus-lib.o obj-$(CONFIG_SND_GUSMAX) += snd-gusmax.o snd-gus-lib.o obj-$(CONFIG_SND_GUSEXTREME) += snd-gusextreme.o snd-gus-lib.o obj-$(CONFIG_SND_INTERWAVE) += snd-interwave.o snd-gus-lib.o obj-$(CONFIG_SND_INTERWAVE_STB) += snd-interwave-stb.o snd-gus-lib.o -obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-gus-synth.o - -obj-m := $(sort $(obj-m)) diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c index 930f4bc56f3..36c27c83236 100644 --- a/sound/isa/gus/gus_dma.c +++ b/sound/isa/gus/gus_dma.c @@ -1,6 +1,6 @@ /* * Routines for GF1 DMA control - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <asm/dma.h> #include <linux/slab.h> #include <sound/core.h> @@ -46,7 +45,8 @@ static void snd_gf1_dma_program(struct snd_gus_card * gus, unsigned char dma_cmd; unsigned int address_high; - // snd_printk("dma_transfer: addr=0x%x, buf=0x%lx, count=0x%x\n", addr, (long) buf, count); + snd_printdd("dma_transfer: addr=0x%x, buf=0x%lx, count=0x%x\n", + addr, buf_addr, count); if (gus->gf1.dma1 > 3) { if (gus->gf1.enh_mode) { @@ -78,7 +78,8 @@ static void snd_gf1_dma_program(struct snd_gus_card * gus, snd_gf1_dma_ack(gus); snd_dma_program(gus->gf1.dma1, buf_addr, count, dma_cmd & SNDRV_GF1_DMA_READ ? DMA_MODE_READ : DMA_MODE_WRITE); #if 0 - snd_printk("address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n", address << 1, count, dma_cmd); + snd_printk(KERN_DEBUG "address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n", + address << 1, count, dma_cmd); #endif spin_lock_irqsave(&gus->reg_lock, flags); if (gus->gf1.enh_mode) { @@ -143,16 +144,18 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus) snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd); kfree(block); #if 0 - printk("program dma (IRQ) - addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", addr, (long) buffer, count, cmd); + snd_printd(KERN_DEBUG "program dma (IRQ) - " + "addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", + block->addr, block->buf_addr, block->count, block->cmd); #endif } int snd_gf1_dma_init(struct snd_gus_card * gus) { - down(&gus->dma_mutex); + mutex_lock(&gus->dma_mutex); gus->gf1.dma_shared++; if (gus->gf1.dma_shared > 1) { - up(&gus->dma_mutex); + mutex_unlock(&gus->dma_mutex); return 0; } gus->gf1.interrupt_handler_dma_write = snd_gf1_dma_interrupt; @@ -160,7 +163,7 @@ int snd_gf1_dma_init(struct snd_gus_card * gus) gus->gf1.dma_data_pcm_last = gus->gf1.dma_data_synth = gus->gf1.dma_data_synth_last = NULL; - up(&gus->dma_mutex); + mutex_unlock(&gus->dma_mutex); return 0; } @@ -168,7 +171,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus) { struct snd_gf1_dma_block *block; - down(&gus->dma_mutex); + mutex_lock(&gus->dma_mutex); gus->gf1.dma_shared--; if (!gus->gf1.dma_shared) { snd_dma_disable(gus->gf1.dma1); @@ -185,7 +188,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus) gus->gf1.dma_data_pcm_last = gus->gf1.dma_data_synth_last = NULL; } - up(&gus->dma_mutex); + mutex_unlock(&gus->dma_mutex); return 0; } @@ -204,13 +207,16 @@ int snd_gf1_dma_transfer_block(struct snd_gus_card * gus, } *block = *__block; block->next = NULL; -#if 0 - printk("addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", block->addr, (long) block->buffer, block->count, block->cmd); -#endif -#if 0 - printk("gus->gf1.dma_data_pcm_last = 0x%lx\n", (long)gus->gf1.dma_data_pcm_last); - printk("gus->gf1.dma_data_pcm = 0x%lx\n", (long)gus->gf1.dma_data_pcm); -#endif + + snd_printdd("addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", + block->addr, (long) block->buffer, block->count, + block->cmd); + + snd_printdd("gus->gf1.dma_data_pcm_last = 0x%lx\n", + (long)gus->gf1.dma_data_pcm_last); + snd_printdd("gus->gf1.dma_data_pcm = 0x%lx\n", + (long)gus->gf1.dma_data_pcm); + spin_lock_irqsave(&gus->dma_lock, flags); if (synth) { if (gus->gf1.dma_data_synth_last) { diff --git a/sound/isa/gus/gus_dram.c b/sound/isa/gus/gus_dram.c index f22fe7967fc..fd2e2e2ed4e 100644 --- a/sound/isa/gus/gus_dram.c +++ b/sound/isa/gus/gus_dram.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * DRAM access routines * * @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <linux/time.h> #include <sound/core.h> #include <sound/gus.h> diff --git a/sound/isa/gus/gus_instr.c b/sound/isa/gus/gus_instr.c index d0c38e1856e..4dc9caf8ddc 100644 --- a/sound/isa/gus/gus_instr.c +++ b/sound/isa/gus/gus_instr.c @@ -1,6 +1,6 @@ /* * Routines for Gravis UltraSound soundcards - Synthesizer - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <linux/time.h> #include <sound/core.h> #include <sound/gus.h> diff --git a/sound/isa/gus/gus_io.c b/sound/isa/gus/gus_io.c index 9b1fe292de4..ca79878d8d8 100644 --- a/sound/isa/gus/gus_io.c +++ b/sound/isa/gus/gus_io.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * I/O routines for GF1/InterWave synthesizer chips * * @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <linux/delay.h> #include <linux/time.h> #include <sound/core.h> diff --git a/sound/isa/gus/gus_irq.c b/sound/isa/gus/gus_irq.c index c19ba2910b7..2055aff71b5 100644 --- a/sound/isa/gus/gus_irq.c +++ b/sound/isa/gus/gus_irq.c @@ -1,6 +1,6 @@ /* * Routine for IRQ handling from GF1/InterWave chip - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <sound/core.h> #include <sound/info.h> #include <sound/gus.h> @@ -30,7 +29,7 @@ #define STAT_ADD(x) while (0) { ; } #endif -irqreturn_t snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t snd_gus_interrupt(int irq, void *dev_id) { struct snd_gus_card * gus = dev_id; unsigned char status; @@ -42,14 +41,16 @@ __again: if (status == 0) return IRQ_RETVAL(handled); handled = 1; - // snd_printk("IRQ: status = 0x%x\n", status); + /* snd_printk(KERN_DEBUG "IRQ: status = 0x%x\n", status); */ if (status & 0x02) { STAT_ADD(gus->gf1.interrupt_stat_midi_in); - gus->gf1.interrupt_handler_midi_in(gus); + if (gus->gf1.interrupt_handler_midi_in) + gus->gf1.interrupt_handler_midi_in(gus); } if (status & 0x01) { STAT_ADD(gus->gf1.interrupt_stat_midi_out); - gus->gf1.interrupt_handler_midi_out(gus); + if (gus->gf1.interrupt_handler_midi_out) + gus->gf1.interrupt_handler_midi_out(gus); } if (status & (0x20 | 0x40)) { unsigned int already, _current_; @@ -64,7 +65,9 @@ __again: continue; /* multi request */ already |= _current_; /* mark request */ #if 0 - printk("voice = %i, voice_status = 0x%x, voice_verify = %i\n", voice, voice_status, inb(GUSP(gus, GF1PAGE))); + printk(KERN_DEBUG "voice = %i, voice_status = 0x%x, " + "voice_verify = %i\n", + voice, voice_status, inb(GUSP(gus, GF1PAGE))); #endif pvoice = &gus->gf1.voices[voice]; if (pvoice->use) { @@ -85,20 +88,24 @@ __again: } if (status & 0x04) { STAT_ADD(gus->gf1.interrupt_stat_timer1); - gus->gf1.interrupt_handler_timer1(gus); + if (gus->gf1.interrupt_handler_timer1) + gus->gf1.interrupt_handler_timer1(gus); } if (status & 0x08) { STAT_ADD(gus->gf1.interrupt_stat_timer2); - gus->gf1.interrupt_handler_timer2(gus); + if (gus->gf1.interrupt_handler_timer2) + gus->gf1.interrupt_handler_timer2(gus); } if (status & 0x80) { if (snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL) & 0x40) { STAT_ADD(gus->gf1.interrupt_stat_dma_write); - gus->gf1.interrupt_handler_dma_write(gus); + if (gus->gf1.interrupt_handler_dma_write) + gus->gf1.interrupt_handler_dma_write(gus); } if (snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL) & 0x40) { STAT_ADD(gus->gf1.interrupt_stat_dma_read); - gus->gf1.interrupt_handler_dma_read(gus); + if (gus->gf1.interrupt_handler_dma_read) + gus->gf1.interrupt_handler_dma_read(gus); } } if (--loop > 0) @@ -136,7 +143,7 @@ void snd_gus_irq_profile_init(struct snd_gus_card *gus) struct snd_info_entry *entry; if (! snd_card_proc_new(gus->card, "gusirq", &entry)) - snd_info_set_text_ops(entry, gus, 1024, snd_gus_irq_info_read); + snd_info_set_text_ops(entry, gus, snd_gus_irq_info_read); } #endif diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c index 6d15b3d18a8..4490ee442ff 100644 --- a/sound/isa/gus/gus_main.c +++ b/sound/isa/gus/gus_main.c @@ -1,6 +1,6 @@ /* * Routines for Gravis UltraSound soundcards - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -19,19 +19,19 @@ * */ -#include <sound/driver.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/slab.h> #include <linux/ioport.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/gus.h> #include <sound/control.h> #include <asm/dma.h> -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("Routines for Gravis UltraSound soundcards"); MODULE_LICENSE("GPL"); @@ -104,12 +104,6 @@ static int snd_gus_free(struct snd_gus_card *gus) { if (gus->gf1.res_port2 == NULL) goto __hw_end; -#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) - if (gus->seq_dev) { - snd_device_free(gus->card, gus->seq_dev); - gus->seq_dev = NULL; - } -#endif snd_gf1_stop(gus); snd_gus_init_dma_irq(gus, 0); __hw_end: @@ -154,6 +148,14 @@ int snd_gus_create(struct snd_card *card, gus = kzalloc(sizeof(*gus), GFP_KERNEL); if (gus == NULL) return -ENOMEM; + spin_lock_init(&gus->reg_lock); + spin_lock_init(&gus->voice_alloc); + spin_lock_init(&gus->active_voice_lock); + spin_lock_init(&gus->event_lock); + spin_lock_init(&gus->dma_lock); + spin_lock_init(&gus->pcm_volume_level_lock); + spin_lock_init(&gus->uart_cmd_lock); + mutex_init(&gus->dma_mutex); gus->gf1.irq = -1; gus->gf1.dma1 = -1; gus->gf1.dma2 = -1; @@ -179,7 +181,7 @@ int snd_gus_create(struct snd_card *card, snd_gus_free(gus); return -EBUSY; } - if (irq >= 0 && request_irq(irq, snd_gus_interrupt, SA_INTERRUPT, "GUS GF1", (void *) gus)) { + if (irq >= 0 && request_irq(irq, snd_gus_interrupt, 0, "GUS GF1", (void *) gus)) { snd_printk(KERN_ERR "gus: can't grab irq %d\n", irq); snd_gus_free(gus); return -EBUSY; @@ -218,14 +220,6 @@ int snd_gus_create(struct snd_card *card, gus->gf1.pcm_channels = pcm_channels; gus->gf1.volume_ramp = 25; gus->gf1.smooth_pan = 1; - spin_lock_init(&gus->reg_lock); - spin_lock_init(&gus->voice_alloc); - spin_lock_init(&gus->active_voice_lock); - spin_lock_init(&gus->event_lock); - spin_lock_init(&gus->dma_lock); - spin_lock_init(&gus->pcm_volume_level_lock); - spin_lock_init(&gus->uart_cmd_lock); - init_MUTEX(&gus->dma_mutex); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) { snd_gus_free(gus); return err; @@ -283,9 +277,11 @@ static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches) static unsigned char dmas[8] = {6, 1, 0, 2, 0, 3, 4, 5}; - snd_assert(gus != NULL, return -EINVAL); + if (snd_BUG_ON(!gus)) + return -EINVAL; card = gus->card; - snd_assert(card != NULL, return -EINVAL); + if (snd_BUG_ON(!card)) + return -EINVAL; gus->mix_cntrl_reg &= 0xf8; gus->mix_cntrl_reg |= 0x01; /* disable MIC, LINE IN, enable LINE OUT */ @@ -294,10 +290,10 @@ static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches) gus->mix_cntrl_reg |= 4; /* enable MIC */ } dma1 = gus->gf1.dma1; - dma1 = dma1 < 0 ? -dma1 : dma1; + dma1 = abs(dma1); dma1 = dmas[dma1 & 7]; dma2 = gus->gf1.dma2; - dma2 = dma2 < 0 ? -dma2 : dma2; + dma2 = abs(dma2); dma2 = dmas[dma2 & 7]; dma1 |= gus->equal_dma ? 0x40 : (dma2 << 3); @@ -306,7 +302,7 @@ static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches) return -EINVAL; } irq = gus->gf1.irq; - irq = irq < 0 ? -irq : irq; + irq = abs(irq); irq = irqs[irq & 0x0f]; if (irq == 0) { snd_printk(KERN_ERR "Error! IRQ isn't defined.\n"); @@ -398,7 +394,7 @@ static int snd_gus_check_version(struct snd_gus_card * gus) gus->ess_flag = 1; } else { snd_printk(KERN_ERR "unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val); - snd_printk(KERN_ERR " please - report to <perex@suse.cz>\n"); + snd_printk(KERN_ERR " please - report to <perex@perex.cz>\n"); } } } @@ -408,14 +404,6 @@ static int snd_gus_check_version(struct snd_gus_card * gus) return 0; } -#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) -static void snd_gus_seq_dev_free(struct snd_seq_device *seq_dev) -{ - struct snd_gus_card *gus = seq_dev->private_data; - gus->seq_dev = NULL; -} -#endif - int snd_gus_initialize(struct snd_gus_card *gus) { int err; @@ -430,15 +418,6 @@ int snd_gus_initialize(struct snd_gus_card *gus) } if ((err = snd_gus_init_dma_irq(gus, 1)) < 0) return err; -#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) - if (snd_seq_device_new(gus->card, 1, SNDRV_SEQ_DEV_ID_GUS, - sizeof(struct snd_gus_card *), &gus->seq_dev) >= 0) { - strcpy(gus->seq_dev->name, "GUS"); - *(struct snd_gus_card **)SNDRV_SEQ_DEVICE_ARGPTR(gus->seq_dev) = gus; - gus->seq_dev->private_data = gus; - gus->seq_dev->private_free = snd_gus_seq_dev_free; - } -#endif snd_gf1_start(gus); gus->initialized = 1; return 0; diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c index e8bdb860a19..af888a022fc 100644 --- a/sound/isa/gus/gus_mem.c +++ b/sound/isa/gus/gus_mem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * GUS's memory allocation routines / bottom layer * * @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <linux/slab.h> #include <linux/string.h> #include <sound/core.h> @@ -34,9 +33,9 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry, void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup) { if (!xup) { - down(&alloc->memory_mutex); + mutex_lock(&alloc->memory_mutex); } else { - up(&alloc->memory_mutex); + mutex_unlock(&alloc->memory_mutex); } } @@ -59,7 +58,7 @@ static struct snd_gf1_mem_block *snd_gf1_mem_xalloc(struct snd_gf1_mem * alloc, alloc->first = nblock; else nblock->prev->next = nblock; - up(&alloc->memory_mutex); + mutex_unlock(&alloc->memory_mutex); return NULL; } pblock = pblock->next; @@ -80,7 +79,7 @@ int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * blo { if (block->share) { /* ok.. shared block */ block->share--; - up(&alloc->memory_mutex); + mutex_unlock(&alloc->memory_mutex); return 0; } if (alloc->first == block) { @@ -128,7 +127,8 @@ static struct snd_gf1_mem_block *snd_gf1_mem_share(struct snd_gf1_mem * alloc, !share_id[2] && !share_id[3]) return NULL; for (block = alloc->first; block; block = block->next) - if (!memcmp(share_id, block->share_id, sizeof(share_id))) + if (!memcmp(share_id, block->share_id, + sizeof(block->share_id))) return block; return NULL; } @@ -143,9 +143,8 @@ static int snd_gf1_mem_find(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block *pblock; unsigned int ptr1, ptr2; - align--; - if (w_16 && align < 1) - align = 1; + if (w_16 && align < 2) + align = 2; block->flags = w_16 ? SNDRV_GF1_MEM_BLOCK_16BIT : 0; block->owner = SNDRV_GF1_MEM_OWNER_DRIVER; block->share = 0; @@ -165,7 +164,7 @@ static int snd_gf1_mem_find(struct snd_gf1_mem * alloc, if (pblock->next->ptr < boundary) ptr2 = pblock->next->ptr; } - ptr1 = (pblock->ptr + pblock->size + align) & ~align; + ptr1 = ALIGN(pblock->ptr + pblock->size, align); if (ptr1 >= ptr2) continue; size1 = ptr2 - ptr1; @@ -244,7 +243,7 @@ int snd_gf1_mem_init(struct snd_gus_card * gus) #endif alloc = &gus->gf1.mem_alloc; - init_MUTEX(&alloc->memory_mutex); + mutex_init(&alloc->memory_mutex); alloc->first = alloc->last = NULL; if (!gus->gf1.memory) return 0; @@ -264,10 +263,8 @@ int snd_gf1_mem_init(struct snd_gus_card * gus) if (snd_gf1_mem_xalloc(alloc, &block) == NULL) return -ENOMEM; #ifdef CONFIG_SND_DEBUG - if (! snd_card_proc_new(gus->card, "gusmem", &entry)) { - snd_info_set_text_ops(entry, gus, 1024, snd_gf1_mem_info_read); - entry->c.text.read_size = 256 * 1024; - } + if (! snd_card_proc_new(gus->card, "gusmem", &entry)) + snd_info_set_text_ops(entry, gus, snd_gf1_mem_info_read); #endif return 0; } @@ -299,7 +296,7 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry, gus = entry->private_data; alloc = &gus->gf1.mem_alloc; - down(&alloc->memory_mutex); + mutex_lock(&alloc->memory_mutex); snd_iprintf(buffer, "8-bit banks : \n "); for (i = 0; i < 4; i++) snd_iprintf(buffer, "0x%06x (%04ik)%s", alloc->banks_8[i].address, alloc->banks_8[i].size >> 10, i + 1 < 4 ? "," : ""); @@ -343,7 +340,7 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry, } snd_iprintf(buffer, " Total: memory = %i, used = %i, free = %i\n", total, used, total - used); - up(&alloc->memory_mutex); + mutex_unlock(&alloc->memory_mutex); #if 0 ultra_iprintf(buffer, " Verify: free = %i, max 8-bit block = %i, max 16-bit block = %i\n", ultra_memory_free_size(card, &card->gf1.mem_alloc), diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c index 4080255007d..2ccb3fadd7b 100644 --- a/sound/isa/gus/gus_mem_proc.c +++ b/sound/isa/gus/gus_mem_proc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * GUS's memory access via proc filesystem * * @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/gus.h> @@ -32,52 +31,21 @@ struct gus_proc_private { struct snd_gus_card * gus; }; -static long snd_gf1_mem_proc_dump(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { - long size; struct gus_proc_private *priv = entry->private_data; struct snd_gus_card *gus = priv->gus; int err; - size = count; - if (pos + size > priv->size) - size = (long)priv->size - pos; - if (size > 0) { - if ((err = snd_gus_dram_read(gus, buf, pos, size, priv->rom)) < 0) - return err; - return size; - } - return 0; + err = snd_gus_dram_read(gus, buf, pos, count, priv->rom); + if (err < 0) + return err; + return count; } -static long long snd_gf1_mem_proc_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - long long offset, - int orig) -{ - struct gus_proc_private *priv = entry->private_data; - - switch (orig) { - case 0: /* SEEK_SET */ - file->f_pos = offset; - break; - case 1: /* SEEK_CUR */ - file->f_pos += offset; - break; - case 2: /* SEEK_END, offset is negative */ - file->f_pos = priv->size + offset; - break; - default: - return -EINVAL; - } - if (file->f_pos > priv->size) - file->f_pos = priv->size; - return file->f_pos; -} - static void snd_gf1_mem_proc_free(struct snd_info_entry *entry) { struct gus_proc_private *priv = entry->private_data; @@ -86,7 +54,6 @@ static void snd_gf1_mem_proc_free(struct snd_info_entry *entry) static struct snd_info_entry_ops snd_gf1_mem_proc_ops = { .read = snd_gf1_mem_proc_dump, - .llseek = snd_gf1_mem_proc_llseek, }; int snd_gf1_mem_proc_init(struct snd_gus_card * gus) diff --git a/sound/isa/gus/gus_mixer.c b/sound/isa/gus/gus_mixer.c index acc25a29720..0dd43414016 100644 --- a/sound/isa/gus/gus_mixer.c +++ b/sound/isa/gus/gus_mixer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Routines for control of ICS 2101 chip and "mixer" in GF1 chip * * @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <linux/time.h> #include <linux/wait.h> #include <sound/core.h> @@ -36,14 +35,7 @@ .get = snd_gf1_get_single, .put = snd_gf1_put_single, \ .private_value = shift | (invert << 8) } -static int snd_gf1_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} +#define snd_gf1_info_single snd_ctl_boolean_mono_info static int snd_gf1_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -169,9 +161,11 @@ int snd_gf1_new_mixer(struct snd_gus_card * gus) unsigned int idx, max; int err; - snd_assert(gus != NULL, return -EINVAL); + if (snd_BUG_ON(!gus)) + return -EINVAL; card = gus->card; - snd_assert(card != NULL, return -EINVAL); + if (snd_BUG_ON(!card)) + return -EINVAL; if (gus->ics_flag) snd_component_add(card, "ICS2101"); diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index d0829393ec8..2dcf45bf729 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Routines for control of GF1 chip (PCM things) * * InterWave chips supports interleaved DMA, but this feature isn't used in @@ -25,7 +25,6 @@ * */ -#include <sound/driver.h> #include <asm/dma.h> #include <linux/slab.h> #include <sound/core.h> @@ -83,7 +82,10 @@ static int snd_gf1_pcm_block_change(struct snd_pcm_substream *substream, count += offset & 31; offset &= ~31; - // snd_printk("block change - offset = 0x%x, count = 0x%x\n", offset, count); + /* + snd_printk(KERN_DEBUG "block change - offset = 0x%x, count = 0x%x\n", + offset, count); + */ memset(&block, 0, sizeof(block)); block.cmd = SNDRV_GF1_DMA_IRQ; if (snd_pcm_format_unsigned(runtime->format)) @@ -114,8 +116,6 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream) unsigned char pan; unsigned int voice; - if (substream == NULL) - return; spin_lock_irqsave(&pcmp->lock, flags); if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE) { spin_unlock_irqrestore(&pcmp->lock, flags); @@ -138,7 +138,11 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream) curr = begin + (pcmp->bpos * pcmp->block_size) / runtime->channels; end = curr + (pcmp->block_size / runtime->channels); end -= snd_pcm_format_width(runtime->format) == 16 ? 2 : 1; - // snd_printk("init: curr=0x%x, begin=0x%x, end=0x%x, ctrl=0x%x, ramp=0x%x, rate=0x%x\n", curr, begin, end, voice_ctrl, ramp_ctrl, rate); + /* + snd_printk(KERN_DEBUG "init: curr=0x%x, begin=0x%x, end=0x%x, " + "ctrl=0x%x, ramp=0x%x, rate=0x%x\n", + curr, begin, end, voice_ctrl, ramp_ctrl, rate); + */ pan = runtime->channels == 2 ? (!voice ? 1 : 14) : 8; vol = !voice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right; spin_lock_irqsave(&gus->reg_lock, flags); @@ -208,9 +212,11 @@ static void snd_gf1_pcm_interrupt_wave(struct snd_gus_card * gus, ramp_ctrl = (snd_gf1_read8(gus, SNDRV_GF1_VB_VOLUME_CONTROL) & ~0xa4) | 0x03; #if 0 snd_gf1_select_voice(gus, pvoice->number); - printk("position = 0x%x\n", (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); + printk(KERN_DEBUG "position = 0x%x\n", + (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); snd_gf1_select_voice(gus, pcmp->pvoices[1]->number); - printk("position = 0x%x\n", (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); + printk(KERN_DEBUG "position = 0x%x\n", + (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4)); snd_gf1_select_voice(gus, pvoice->number); #endif pcmp->bpos++; @@ -302,7 +308,11 @@ static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf, unsigned int len; unsigned long flags; - // printk("poke block; buf = 0x%x, pos = %i, count = %i, port = 0x%x\n", (int)buf, pos, count, gus->gf1.port); + /* + printk(KERN_DEBUG + "poke block; buf = 0x%x, pos = %i, count = %i, port = 0x%x\n", + (int)buf, pos, count, gus->gf1.port); + */ while (count > 0) { len = count; if (len > 512) /* limit, to allow IRQ */ @@ -355,8 +365,10 @@ static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream, bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2)); len = samples_to_bytes(runtime, count); - snd_assert(bpos <= pcmp->dma_size, return -EIO); - snd_assert(bpos + len <= pcmp->dma_size, return -EIO); + if (snd_BUG_ON(bpos > pcmp->dma_size)) + return -EIO; + if (snd_BUG_ON(bpos + len > pcmp->dma_size)) + return -EIO; if (copy_from_user(runtime->dma_area + bpos, src, len)) return -EFAULT; if (snd_gf1_pcm_use_dma && len > 32) { @@ -384,8 +396,10 @@ static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream, bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2)); len = samples_to_bytes(runtime, count); - snd_assert(bpos <= pcmp->dma_size, return -EIO); - snd_assert(bpos + len <= pcmp->dma_size, return -EIO); + if (snd_BUG_ON(bpos > pcmp->dma_size)) + return -EIO; + if (snd_BUG_ON(bpos + len > pcmp->dma_size)) + return -EIO; snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos, count); if (snd_gf1_pcm_use_dma && len > 32) { return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len); @@ -679,7 +693,8 @@ static int snd_gf1_pcm_playback_open(struct snd_pcm_substream *substream) runtime->private_free = snd_gf1_pcm_playback_free; #if 0 - printk("playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n", (long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer); + printk(KERN_DEBUG "playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n", + (long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer); #endif if ((err = snd_gf1_dma_init(gus)) < 0) return err; @@ -780,13 +795,13 @@ static int snd_gf1_pcm_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ if (!(pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE)) continue; /* load real volume - better precision */ - spin_lock_irqsave(&gus->reg_lock, flags); + spin_lock(&gus->reg_lock); snd_gf1_select_voice(gus, pvoice->number); snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); vol = pvoice == pcmp->pvoices[0] ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right; snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, vol); pcmp->final_volume = 1; - spin_unlock_irqrestore(&gus->reg_lock, flags); + spin_unlock(&gus->reg_lock); } spin_unlock_irqrestore(&gus->voice_alloc, flags); return change; diff --git a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c index b263655c411..3d1fed0c262 100644 --- a/sound/isa/gus/gus_reset.c +++ b/sound/isa/gus/gus_reset.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -18,7 +18,6 @@ * */ -#include <sound/driver.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/time.h> diff --git a/sound/isa/gus/gus_sample.c b/sound/isa/gus/gus_sample.c deleted file mode 100644 index 9e0c55ab25b..00000000000 --- a/sound/isa/gus/gus_sample.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Routines for Gravis UltraSound soundcards - Sample support - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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/gus.h> - -/* - * - */ - -static void select_instrument(struct snd_gus_card * gus, struct snd_gus_voice * v) -{ - struct snd_seq_kinstr *instr; - -#if 0 - printk("select instrument: cluster = %li, std = 0x%x, bank = %i, prg = %i\n", - v->instr.cluster, - v->instr.std, - v->instr.bank, - v->instr.prg); -#endif - instr = snd_seq_instr_find(gus->gf1.ilist, &v->instr, 0, 1); - if (instr != NULL) { - if (instr->ops) { - 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); - } -} - -/* - * - */ - -static void event_sample(struct snd_seq_event *ev, struct snd_gus_port *p, - struct snd_gus_voice *v) -{ - if (v->sample_ops && v->sample_ops->sample_stop) - v->sample_ops->sample_stop(p->gus, v, SAMPLE_STOP_IMMEDIATELY); - v->instr.std = ev->data.sample.param.sample.std; - if (v->instr.std & 0xff000000) { /* private instrument */ - v->instr.std &= 0x00ffffff; - v->instr.std |= (unsigned int)ev->source.client << 24; - } - v->instr.bank = ev->data.sample.param.sample.bank; - v->instr.prg = ev->data.sample.param.sample.prg; - select_instrument(p->gus, v); -} - -static void event_cluster(struct snd_seq_event *ev, struct snd_gus_port *p, - struct snd_gus_voice *v) -{ - if (v->sample_ops && v->sample_ops->sample_stop) - v->sample_ops->sample_stop(p->gus, v, SAMPLE_STOP_IMMEDIATELY); - v->instr.cluster = ev->data.sample.param.cluster.cluster; - select_instrument(p->gus, v); -} - -static void event_start(struct snd_seq_event *ev, struct snd_gus_port *p, - struct snd_gus_voice *v) -{ - if (v->sample_ops && v->sample_ops->sample_start) - v->sample_ops->sample_start(p->gus, v, ev->data.sample.param.position); -} - -static void event_stop(struct snd_seq_event *ev, struct snd_gus_port *p, - struct snd_gus_voice *v) -{ - if (v->sample_ops && v->sample_ops->sample_stop) - v->sample_ops->sample_stop(p->gus, v, ev->data.sample.param.stop_mode); -} - -static void event_freq(struct snd_seq_event *ev, struct snd_gus_port *p, - struct snd_gus_voice *v) -{ - if (v->sample_ops && v->sample_ops->sample_freq) - v->sample_ops->sample_freq(p->gus, v, ev->data.sample.param.frequency); -} - -static void event_volume(struct snd_seq_event *ev, struct snd_gus_port *p, - struct snd_gus_voice *v) -{ - if (v->sample_ops && v->sample_ops->sample_volume) - v->sample_ops->sample_volume(p->gus, v, &ev->data.sample.param.volume); -} - -static void event_loop(struct snd_seq_event *ev, struct snd_gus_port *p, - struct snd_gus_voice *v) -{ - if (v->sample_ops && v->sample_ops->sample_loop) - v->sample_ops->sample_loop(p->gus, v, &ev->data.sample.param.loop); -} - -static void event_position(struct snd_seq_event *ev, struct snd_gus_port *p, - struct snd_gus_voice *v) -{ - if (v->sample_ops && v->sample_ops->sample_pos) - v->sample_ops->sample_pos(p->gus, v, ev->data.sample.param.position); -} - -static void event_private1(struct snd_seq_event *ev, struct snd_gus_port *p, - struct snd_gus_voice *v) -{ - if (v->sample_ops && v->sample_ops->sample_private1) - v->sample_ops->sample_private1(p->gus, v, (unsigned char *)&ev->data.sample.param.raw8); -} - -typedef void (gus_sample_event_handler_t)(struct snd_seq_event *ev, - struct snd_gus_port *p, - struct snd_gus_voice *v); -static gus_sample_event_handler_t *gus_sample_event_handlers[9] = { - event_sample, - event_cluster, - event_start, - event_stop, - event_freq, - event_volume, - event_loop, - event_position, - event_private1 -}; - -void snd_gus_sample_event(struct snd_seq_event *ev, struct snd_gus_port *p) -{ - int idx, voice; - struct snd_gus_card *gus = p->gus; - struct snd_gus_voice *v; - unsigned long flags; - - idx = ev->type - SNDRV_SEQ_EVENT_SAMPLE; - if (idx < 0 || idx > 8) - return; - for (voice = 0; voice < 32; voice++) { - v = &gus->gf1.voices[voice]; - if (v->use && v->client == ev->source.client && - v->port == ev->source.port && - v->index == ev->data.sample.channel) { - spin_lock_irqsave(&gus->event_lock, flags); - gus_sample_event_handlers[idx](ev, p, v); - spin_unlock_irqrestore(&gus->event_lock, flags); - return; - } - } -} diff --git a/sound/isa/gus/gus_simple.c b/sound/isa/gus/gus_simple.c deleted file mode 100644 index dcad6ed0198..00000000000 --- a/sound/isa/gus/gus_simple.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Routines for Gravis UltraSound soundcards - Simple instrument handlers - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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/gus.h> -#include "gus_tables.h" - -/* - * - */ - -static void interrupt_wave(struct snd_gus_card *gus, struct snd_gus_voice *voice); -static void interrupt_volume(struct snd_gus_card *gus, struct snd_gus_voice *voice); -static void interrupt_effect(struct snd_gus_card *gus, struct snd_gus_voice *voice); - -static void sample_start(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_position_t position); -static void sample_stop(struct snd_gus_card *gus, struct snd_gus_voice *voice, int mode); -static void sample_freq(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_frequency_t freq); -static void sample_volume(struct snd_gus_card *card, struct snd_gus_voice *voice, struct snd_seq_ev_volume *volume); -static void sample_loop(struct snd_gus_card *card, struct snd_gus_voice *voice, struct snd_seq_ev_loop *loop); -static void sample_pos(struct snd_gus_card *card, struct snd_gus_voice *voice, snd_seq_position_t position); -static void sample_private1(struct snd_gus_card *card, struct snd_gus_voice *voice, unsigned char *data); - -static struct snd_gus_sample_ops sample_ops = { - sample_start, - sample_stop, - sample_freq, - sample_volume, - sample_loop, - sample_pos, - sample_private1 -}; - -#if 0 - -static void note_stop(struct snd_gus_card *gus, struct snd_gus_voice *voice, int wait); -static void note_wait(struct snd_gus_card *gus, struct snd_gus_voice *voice); -static void note_off(struct snd_gus_card *gus, struct snd_gus_voice *voice); -static void note_volume(struct snd_gus_card *card, struct snd_gus_voice *voice); -static void note_pitchbend(struct snd_gus_card *card, struct snd_gus_voice *voice); -static void note_vibrato(struct snd_gus_card *card, struct snd_gus_voice *voice); -static void note_tremolo(struct snd_gus_card *card, struct snd_gus_voice *voice); - -static struct snd_gus_note_handlers note_commands = { - note_stop, - note_wait, - note_off, - note_volume, - note_pitchbend, - note_vibrato, - note_tremolo -}; - -static void chn_trigger_down(struct snd_gus_card *card, ultra_channel_t *channel, ultra_instrument_t *instrument, unsigned char note, unsigned char velocity, unsigned char priority ); -static void chn_trigger_up( ultra_card_t *card, ultra_note_t *note ); -static void chn_control( ultra_card_t *card, ultra_channel_t *channel, unsigned short p1, unsigned short p2 ); - -static struct ULTRA_STRU_INSTRUMENT_CHANNEL_COMMANDS channel_commands = { - chn_trigger_down, - chn_trigger_up, - chn_control -}; - -#endif - -static void do_volume_envelope(struct snd_gus_card *card, struct snd_gus_voice *voice); -static void do_pan_envelope(struct snd_gus_card *card, struct snd_gus_voice *voice); - -/* - * - */ - -static void interrupt_wave(struct snd_gus_card *gus, struct snd_gus_voice *voice) -{ - spin_lock(&gus->event_lock); - snd_gf1_stop_voice(gus, voice->number); - spin_lock(&gus->reg_lock); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, 0); - spin_unlock(&gus->reg_lock); - voice->flags &= ~SNDRV_GF1_VFLG_RUNNING; - spin_unlock(&gus->event_lock); -} - -static void interrupt_volume(struct snd_gus_card *gus, struct snd_gus_voice *voice) -{ - spin_lock(&gus->event_lock); - if (voice->flags & SNDRV_GF1_VFLG_RUNNING) - do_volume_envelope(gus, voice); - else - snd_gf1_stop_voice(gus, voice->number); - spin_unlock(&gus->event_lock); -} - -static void interrupt_effect(struct snd_gus_card *gus, struct snd_gus_voice *voice) -{ - spin_lock(&gus->event_lock); - if ((voice->flags & (SNDRV_GF1_VFLG_RUNNING|SNDRV_GF1_VFLG_EFFECT_TIMER1)) == - (SNDRV_GF1_VFLG_RUNNING|SNDRV_GF1_VFLG_EFFECT_TIMER1)) - do_pan_envelope(gus, voice); - spin_unlock(&gus->event_lock); -} - -/* - * - */ - -static void do_volume_envelope(struct snd_gus_card *gus, struct snd_gus_voice *voice) -{ - unsigned short next, rate, old_volume; - int program_next_ramp; - unsigned long flags; - - if (!gus->gf1.volume_ramp) { - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); - snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, voice->gf1_volume); - /* printk("gf1_volume = 0x%x\n", voice->gf1_volume); */ - spin_unlock_irqrestore(&gus->reg_lock, flags); - return; - } - program_next_ramp = 0; - rate = next = 0; - while (1) { - program_next_ramp = 0; - rate = next = 0; - switch (voice->venv_state) { - case VENV_BEFORE: - voice->venv_state = VENV_ATTACK; - voice->venv_value_next = 0; - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); - snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, SNDRV_GF1_MIN_VOLUME); - spin_unlock_irqrestore(&gus->reg_lock, flags); - break; - case VENV_ATTACK: - voice->venv_state = VENV_SUSTAIN; - program_next_ramp++; - next = 255; - rate = gus->gf1.volume_ramp; - break; - case VENV_SUSTAIN: - voice->venv_state = VENV_RELEASE; - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); - snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, ((int)voice->gf1_volume * (int)voice->venv_value_next) / 255); - spin_unlock_irqrestore(&gus->reg_lock, flags); - return; - case VENV_RELEASE: - voice->venv_state = VENV_DONE; - program_next_ramp++; - next = 0; - rate = gus->gf1.volume_ramp; - break; - case VENV_DONE: - snd_gf1_stop_voice(gus, voice->number); - voice->flags &= ~SNDRV_GF1_VFLG_RUNNING; - return; - case VENV_VOLUME: - program_next_ramp++; - next = voice->venv_value_next; - rate = gus->gf1.volume_ramp; - voice->venv_state = voice->venv_state_prev; - break; - } - voice->venv_value_next = next; - if (!program_next_ramp) - continue; - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); - old_volume = snd_gf1_read16(gus, SNDRV_GF1_VW_VOLUME) >> 8; - if (!rate) { - spin_unlock_irqrestore(&gus->reg_lock, flags); - continue; - } - next = (((int)voice->gf1_volume * (int)next) / 255) >> 8; - if (old_volume < SNDRV_GF1_MIN_OFFSET) - old_volume = SNDRV_GF1_MIN_OFFSET; - if (next < SNDRV_GF1_MIN_OFFSET) - next = SNDRV_GF1_MIN_OFFSET; - if (next > SNDRV_GF1_MAX_OFFSET) - next = SNDRV_GF1_MAX_OFFSET; - if (old_volume == next) { - spin_unlock_irqrestore(&gus->reg_lock, flags); - continue; - } - voice->volume_control &= ~0xc3; - voice->volume_control |= 0x20; - if (old_volume > next) { - snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_START, next); - snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_END, old_volume); - voice->volume_control |= 0x40; - } else { - snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_START, old_volume); - snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_END, next); - } - snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_RATE, rate); - snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, voice->volume_control); - if (!gus->gf1.enh_mode) { - snd_gf1_delay(gus); - snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, voice->volume_control); - } - spin_unlock_irqrestore(&gus->reg_lock, flags); - return; - } -} - -static void do_pan_envelope(struct snd_gus_card *gus, struct snd_gus_voice *voice) -{ - unsigned long flags; - unsigned char old_pan; - -#if 0 - snd_gf1_select_voice(gus, voice->number); - printk(" -%i- do_pan_envelope - flags = 0x%x (0x%x -> 0x%x)\n", - voice->number, - voice->flags, - voice->gf1_pan, - snd_gf1_i_read8(gus, SNDRV_GF1_VB_PAN) & 0x0f); -#endif - if (gus->gf1.enh_mode) { - voice->flags &= ~(SNDRV_GF1_VFLG_EFFECT_TIMER1|SNDRV_GF1_VFLG_PAN); - return; - } - if (!gus->gf1.smooth_pan) { - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, voice->gf1_pan); - spin_unlock_irqrestore(&gus->reg_lock, flags); - return; - } - if (!(voice->flags & SNDRV_GF1_VFLG_PAN)) /* before */ - voice->flags |= SNDRV_GF1_VFLG_EFFECT_TIMER1|SNDRV_GF1_VFLG_PAN; - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - old_pan = snd_gf1_read8(gus, SNDRV_GF1_VB_PAN) & 0x0f; - if (old_pan > voice->gf1_pan ) - old_pan--; - if (old_pan < voice->gf1_pan) - old_pan++; - snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, old_pan); - spin_unlock_irqrestore(&gus->reg_lock, flags); - if (old_pan == voice->gf1_pan) /* the goal was reached */ - voice->flags &= ~(SNDRV_GF1_VFLG_EFFECT_TIMER1|SNDRV_GF1_VFLG_PAN); -#if 0 - snd_gf1_select_voice(gus, voice->number); - printk(" -%i- (1) do_pan_envelope - flags = 0x%x (0x%x -> 0x%x)\n", - voice->number, - voice->flags, - voice->gf1_pan, - snd_gf1_i_read8(gus, GF1_VB_PAN) & 0x0f); -#endif -} - -static void set_enhanced_pan(struct snd_gus_card *gus, struct snd_gus_voice *voice, unsigned short pan) -{ - unsigned long flags; - unsigned short vlo, vro; - - vlo = SNDRV_GF1_ATTEN((SNDRV_GF1_ATTEN_TABLE_SIZE-1) - pan); - vro = SNDRV_GF1_ATTEN(pan); - if (pan != SNDRV_GF1_ATTEN_TABLE_SIZE - 1 && pan != 0) { - vlo >>= 1; - vro >>= 1; - } - vlo <<= 4; - vro <<= 4; -#if 0 - printk("vlo = 0x%x (0x%x), vro = 0x%x (0x%x)\n", - vlo, snd_gf1_i_read16(gus, GF1_VW_OFFSET_LEFT), - vro, snd_gf1_i_read16(gus, GF1_VW_OFFSET_RIGHT)); -#endif - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_LEFT_FINAL, vlo); - snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_RIGHT_FINAL, vro); - spin_unlock_irqrestore(&gus->reg_lock, flags); - voice->vlo = vlo; - voice->vro = vro; -} - -/* - * - */ - -static void sample_start(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_position_t position) -{ - unsigned long flags; - unsigned int begin, addr, addr_end, addr_start; - int w_16; - struct simple_instrument *simple; - struct snd_seq_kinstr *instr; - - instr = snd_seq_instr_find(gus->gf1.ilist, &voice->instr, 0, 1); - if (instr == NULL) - return; - voice->instr = instr->instr; /* copy ID to speedup aliases */ - simple = KINSTR_DATA(instr); - begin = simple->address.memory << 4; - w_16 = simple->format & SIMPLE_WAVE_16BIT ? 0x04 : 0; - addr_start = simple->loop_start; - if (simple->format & SIMPLE_WAVE_LOOP) { - addr_end = simple->loop_end; - } else { - addr_end = (simple->size << 4) - (w_16 ? 40 : 24); - } - if (simple->format & SIMPLE_WAVE_BACKWARD) { - addr = simple->loop_end; - if (position < simple->loop_end) - addr -= position; - } else { - addr = position; - } - voice->control = 0x00; - voice->mode = 0x20; /* enable offset registers */ - if (simple->format & SIMPLE_WAVE_16BIT) - voice->control |= 0x04; - if (simple->format & SIMPLE_WAVE_BACKWARD) - voice->control |= 0x40; - if (simple->format & SIMPLE_WAVE_LOOP) { - voice->control |= 0x08; - } else { - voice->control |= 0x20; - } - if (simple->format & SIMPLE_WAVE_BIDIR) - voice->control |= 0x10; - if (simple->format & SIMPLE_WAVE_ULAW) - voice->mode |= 0x40; - if (w_16) { - addr = ((addr << 1) & ~0x1f) | (addr & 0x0f); - addr_start = ((addr_start << 1) & ~0x1f) | (addr_start & 0x0f); - addr_end = ((addr_end << 1) & ~0x1f) | (addr_end & 0x0f); - } - addr += begin; - addr_start += begin; - addr_end += begin; - snd_gf1_stop_voice(gus, voice->number); - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, voice->fc_register + voice->fc_lfo); - voice->venv_state = VENV_BEFORE; - voice->volume_control = 0x03; - snd_gf1_write_addr(gus, SNDRV_GF1_VA_START, addr_start, w_16); - snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, addr_end, w_16); - snd_gf1_write_addr(gus, SNDRV_GF1_VA_CURRENT, addr, w_16); - if (!gus->gf1.enh_mode) { - snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, voice->gf1_pan); - } else { - snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_LEFT, voice->vlo); - snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_LEFT_FINAL, voice->vlo); - snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_RIGHT, voice->vro); - snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_RIGHT_FINAL, voice->vro); - snd_gf1_write8(gus, SNDRV_GF1_VB_ACCUMULATOR, voice->effect_accumulator); - snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME, voice->gf1_effect_volume); - snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME_FINAL, voice->gf1_effect_volume); - } - spin_unlock_irqrestore(&gus->reg_lock, flags); - do_volume_envelope(gus, voice); - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - if (gus->gf1.enh_mode) - snd_gf1_write8(gus, SNDRV_GF1_VB_MODE, voice->mode); - snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice->control); - if (!gus->gf1.enh_mode) { - snd_gf1_delay(gus); - snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice->control ); - } - spin_unlock_irqrestore(&gus->reg_lock, flags); -#if 0 - snd_gf1_print_voice_registers(gus); -#endif - voice->flags |= SNDRV_GF1_VFLG_RUNNING; - snd_seq_instr_free_use(gus->gf1.ilist, instr); -} - -static void sample_stop(struct snd_gus_card *gus, struct snd_gus_voice *voice, int mode) -{ - unsigned char control; - unsigned long flags; - - if (!(voice->flags & SNDRV_GF1_VFLG_RUNNING)) - return; - switch (mode) { - default: - if (gus->gf1.volume_ramp > 0) { - if (voice->venv_state < VENV_RELEASE) { - voice->venv_state = VENV_RELEASE; - do_volume_envelope(gus, voice); - } - } - if (mode != SAMPLE_STOP_VENVELOPE) { - snd_gf1_stop_voice(gus, voice->number); - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, SNDRV_GF1_MIN_VOLUME); - spin_unlock_irqrestore(&gus->reg_lock, flags); - voice->flags &= ~SNDRV_GF1_VFLG_RUNNING; - } - break; - case SAMPLE_STOP_LOOP: /* disable loop only */ - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - control = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL); - control &= ~(0x83 | 0x04); - control |= 0x20; - snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, control); - spin_unlock_irqrestore(&gus->reg_lock, flags); - break; - } -} - -static void sample_freq(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_frequency_t freq) -{ - unsigned long flags; - - spin_lock_irqsave(&gus->reg_lock, flags); - voice->fc_register = snd_gf1_translate_freq(gus, freq); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, voice->fc_register + voice->fc_lfo); - spin_unlock_irqrestore(&gus->reg_lock, flags); -} - -static void sample_volume(struct snd_gus_card *gus, struct snd_gus_voice *voice, struct snd_seq_ev_volume *volume) -{ - if (volume->volume >= 0) { - volume->volume &= 0x3fff; - voice->gf1_volume = snd_gf1_lvol_to_gvol_raw(volume->volume << 2) << 4; - voice->venv_state_prev = VENV_SUSTAIN; - voice->venv_state = VENV_VOLUME; - do_volume_envelope(gus, voice); - } - if (volume->lr >= 0) { - volume->lr &= 0x3fff; - if (!gus->gf1.enh_mode) { - voice->gf1_pan = (volume->lr >> 10) & 15; - if (!gus->gf1.full_range_pan) { - if (voice->gf1_pan == 0) - voice->gf1_pan++; - if (voice->gf1_pan == 15) - voice->gf1_pan--; - } - voice->flags &= ~SNDRV_GF1_VFLG_PAN; /* before */ - do_pan_envelope(gus, voice); - } else { - set_enhanced_pan(gus, voice, volume->lr >> 7); - } - } -} - -static void sample_loop(struct snd_gus_card *gus, struct snd_gus_voice *voice, struct snd_seq_ev_loop *loop) -{ - unsigned long flags; - int w_16 = voice->control & 0x04; - unsigned int begin, addr_start, addr_end; - struct simple_instrument *simple; - struct snd_seq_kinstr *instr; - -#if 0 - printk("voice_loop: start = 0x%x, end = 0x%x\n", loop->start, loop->end); -#endif - instr = snd_seq_instr_find(gus->gf1.ilist, &voice->instr, 0, 1); - if (instr == NULL) - return; - voice->instr = instr->instr; /* copy ID to speedup aliases */ - simple = KINSTR_DATA(instr); - begin = simple->address.memory; - addr_start = loop->start; - addr_end = loop->end; - addr_start = (((addr_start << 1) & ~0x1f) | (addr_start & 0x0f)) + begin; - addr_end = (((addr_end << 1) & ~0x1f) | (addr_end & 0x0f)) + begin; - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_write_addr(gus, SNDRV_GF1_VA_START, addr_start, w_16); - snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, addr_end, w_16); - spin_unlock_irqrestore(&gus->reg_lock, flags); - snd_seq_instr_free_use(gus->gf1.ilist, instr); -} - -static void sample_pos(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_position_t position) -{ - unsigned long flags; - int w_16 = voice->control & 0x04; - unsigned int begin, addr; - struct simple_instrument *simple; - struct snd_seq_kinstr *instr; - -#if 0 - printk("voice_loop: start = 0x%x, end = 0x%x\n", loop->start, loop->end); -#endif - instr = snd_seq_instr_find(gus->gf1.ilist, &voice->instr, 0, 1); - if (instr == NULL) - return; - voice->instr = instr->instr; /* copy ID to speedup aliases */ - simple = KINSTR_DATA(instr); - begin = simple->address.memory; - addr = (((position << 1) & ~0x1f) | (position & 0x0f)) + begin; - spin_lock_irqsave(&gus->reg_lock, flags); - snd_gf1_select_voice(gus, voice->number); - snd_gf1_write_addr(gus, SNDRV_GF1_VA_CURRENT, addr, w_16); - spin_unlock_irqrestore(&gus->reg_lock, flags); - snd_seq_instr_free_use(gus->gf1.ilist, instr); -} - -#if 0 - -static unsigned char get_effects_mask( ultra_card_t *card, int value ) -{ - if ( value > 7 ) return 0; - if ( card -> gf1.effects && card -> gf1.effects -> chip_type == ULTRA_EFFECT_CHIP_INTERWAVE ) - return card -> gf1.effects -> chip.interwave.voice_output[ value ]; - return 0; -} - -#endif - -static void sample_private1(struct snd_gus_card *card, struct snd_gus_voice *voice, unsigned char *data) -{ -#if 0 - unsigned long flags; - unsigned char uc; - - switch ( *data ) { - case ULTRA_PRIV1_IW_EFFECT: - uc = get_effects_mask( card, ultra_get_byte( data, 4 ) ); - uc |= get_effects_mask( card, ultra_get_byte( data, 4 ) >> 4 ); - uc |= get_effects_mask( card, ultra_get_byte( data, 5 ) ); - uc |= get_effects_mask( card, ultra_get_byte( data, 5 ) >> 4 ); - voice -> data.simple.effect_accumulator = uc; - voice -> data.simple.effect_volume = ultra_translate_voice_volume( card, ultra_get_word( data, 2 ) ) << 4; - if ( !card -> gf1.enh_mode ) return; - if ( voice -> flags & VFLG_WAIT_FOR_START ) return; - if ( voice -> flags & VFLG_RUNNING ) - { - CLI( &flags ); - gf1_select_voice( card, voice -> number ); - ultra_write8( card, GF1_VB_ACCUMULATOR, voice -> data.simple.effect_accumulator ); - ultra_write16( card, GF1_VW_EFFECT_VOLUME_FINAL, voice -> data.simple.effect_volume ); - STI( &flags ); - } - break; - case ULTRA_PRIV1_IW_LFO: - ultra_lfo_command( card, voice -> number, data ); - } -#endif -} - -#if 0 - -/* - * - */ - -static void note_stop( ultra_card_t *card, ultra_voice_t *voice, int wait ) -{ -} - -static void note_wait( ultra_card_t *card, ultra_voice_t *voice ) -{ -} - -static void note_off( ultra_card_t *card, ultra_voice_t *voice ) -{ -} - -static void note_volume( ultra_card_t *card, ultra_voice_t *voice ) -{ -} - -static void note_pitchbend( ultra_card_t *card, ultra_voice_t *voice ) -{ -} - -static void note_vibrato( ultra_card_t *card, ultra_voice_t *voice ) -{ -} - -static void note_tremolo( ultra_card_t *card, ultra_voice_t *voice ) -{ -} - -/* - * - */ - -static void chn_trigger_down( ultra_card_t *card, ultra_channel_t *channel, ultra_instrument_t *instrument, unsigned char note, unsigned char velocity, unsigned char priority ) -{ -} - -static void chn_trigger_up( ultra_card_t *card, ultra_note_t *note ) -{ -} - -static void chn_control( ultra_card_t *card, ultra_channel_t *channel, unsigned short p1, unsigned short p2 ) -{ -} - -/* - * - */ - -#endif - -void snd_gf1_simple_init(struct snd_gus_voice *voice) -{ - voice->handler_wave = interrupt_wave; - voice->handler_volume = interrupt_volume; - voice->handler_effect = interrupt_effect; - voice->volume_change = NULL; - voice->sample_ops = &sample_ops; -} diff --git a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c deleted file mode 100644 index 85a1b051f09..00000000000 --- a/sound/isa/gus/gus_synth.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Routines for Gravis UltraSound soundcards - Synthesizer - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include <sound/driver.h> -#include <linux/init.h> -#include <linux/time.h> -#include <sound/core.h> -#include <sound/gus.h> -#include <sound/seq_device.h> - -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); -MODULE_DESCRIPTION("Routines for Gravis UltraSound soundcards - Synthesizer"); -MODULE_LICENSE("GPL"); - -/* - * - */ - -static void snd_gus_synth_free_voices(struct snd_gus_card * gus, int client, int port) -{ - int idx; - struct snd_gus_voice * voice; - - for (idx = 0; idx < 32; idx++) { - voice = &gus->gf1.voices[idx]; - if (voice->use && voice->client == client && voice->port == port) - snd_gf1_free_voice(gus, voice); - } -} - -static int snd_gus_synth_use(void *private_data, struct snd_seq_port_subscribe *info) -{ - struct snd_gus_port * port = private_data; - struct snd_gus_card * gus = port->gus; - struct snd_gus_voice * voice; - unsigned int idx; - - if (info->voices > 32) - return -EINVAL; - down(&gus->register_mutex); - if (!snd_gus_use_inc(gus)) { - up(&gus->register_mutex); - return -EFAULT; - } - for (idx = 0; idx < info->voices; idx++) { - voice = snd_gf1_alloc_voice(gus, SNDRV_GF1_VOICE_TYPE_SYNTH, info->sender.client, info->sender.port); - if (voice == NULL) { - snd_gus_synth_free_voices(gus, info->sender.client, info->sender.port); - snd_gus_use_dec(gus); - up(&gus->register_mutex); - return -EBUSY; - } - voice->index = idx; - } - up(&gus->register_mutex); - return 0; -} - -static int snd_gus_synth_unuse(void *private_data, struct snd_seq_port_subscribe *info) -{ - struct snd_gus_port * port = private_data; - struct snd_gus_card * gus = port->gus; - - down(&gus->register_mutex); - snd_gus_synth_free_voices(gus, info->sender.client, info->sender.port); - snd_gus_use_dec(gus); - up(&gus->register_mutex); - return 0; -} - -/* - * - */ - -static void snd_gus_synth_free_private_instruments(struct snd_gus_port *p, int client) -{ - struct snd_seq_instr_header ifree; - - memset(&ifree, 0, sizeof(ifree)); - ifree.cmd = SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE; - snd_seq_instr_list_free_cond(p->gus->gf1.ilist, &ifree, client, 0); -} - -static int snd_gus_synth_event_input(struct snd_seq_event *ev, int direct, - void *private_data, int atomic, int hop) -{ - struct snd_gus_port * p = private_data; - - snd_assert(p != NULL, return -EINVAL); - if (ev->type >= SNDRV_SEQ_EVENT_SAMPLE && - ev->type <= SNDRV_SEQ_EVENT_SAMPLE_PRIVATE1) { - snd_gus_sample_event(ev, p); - return 0; - } - if (ev->source.client == SNDRV_SEQ_CLIENT_SYSTEM && - ev->source.port == SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE) { - if (ev->type == SNDRV_SEQ_EVENT_CLIENT_EXIT) { - snd_gus_synth_free_private_instruments(p, ev->data.addr.client); - return 0; - } - } - if (direct) { - if (ev->type >= SNDRV_SEQ_EVENT_INSTR_BEGIN) { - snd_seq_instr_event(&p->gus->gf1.iwffff_ops.kops, - p->gus->gf1.ilist, - ev, - p->gus->gf1.seq_client, - atomic, hop); - return 0; - } - } - return 0; -} - -static void snd_gus_synth_instr_notify(void *private_data, - struct snd_seq_kinstr *instr, - int what) -{ - unsigned int idx; - struct snd_gus_card *gus = private_data; - struct snd_gus_voice *pvoice; - unsigned long flags; - - spin_lock_irqsave(&gus->event_lock, flags); - for (idx = 0; idx < 32; idx++) { - pvoice = &gus->gf1.voices[idx]; - if (pvoice->use && !memcmp(&pvoice->instr, &instr->instr, sizeof(pvoice->instr))) { - if (pvoice->sample_ops && pvoice->sample_ops->sample_stop) { - pvoice->sample_ops->sample_stop(gus, pvoice, SAMPLE_STOP_IMMEDIATELY); - } else { - snd_gf1_stop_voice(gus, pvoice->number); - pvoice->flags &= ~SNDRV_GF1_VFLG_RUNNING; - } - } - } - spin_unlock_irqrestore(&gus->event_lock, flags); -} - -/* - * - */ - -static void snd_gus_synth_free_port(void *private_data) -{ - struct snd_gus_port * p = private_data; - - if (p) - snd_midi_channel_free_set(p->chset); -} - -static int snd_gus_synth_create_port(struct snd_gus_card * gus, int idx) -{ - struct snd_gus_port * p; - struct snd_seq_port_callback callbacks; - char name[32]; - int result; - - p = &gus->gf1.seq_ports[idx]; - p->chset = snd_midi_channel_alloc_set(16); - if (p->chset == NULL) - return -ENOMEM; - p->chset->private_data = p; - p->gus = gus; - p->client = gus->gf1.seq_client; - - memset(&callbacks, 0, sizeof(callbacks)); - callbacks.owner = THIS_MODULE; - callbacks.use = snd_gus_synth_use; - callbacks.unuse = snd_gus_synth_unuse; - callbacks.event_input = snd_gus_synth_event_input; - callbacks.private_free = snd_gus_synth_free_port; - callbacks.private_data = p; - - sprintf(name, "%s port %i", gus->interwave ? "AMD InterWave" : "GF1", idx); - p->chset->port = snd_seq_event_port_attach(gus->gf1.seq_client, - &callbacks, - SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE, - SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE | - SNDRV_SEQ_PORT_TYPE_SYNTH, - 16, 0, - name); - if (p->chset->port < 0) { - result = p->chset->port; - snd_gus_synth_free_port(p); - return result; - } - p->port = p->chset->port; - return 0; -} - -/* - * - */ - -static int snd_gus_synth_new_device(struct snd_seq_device *dev) -{ - struct snd_gus_card *gus; - int client, i; - struct snd_seq_port_subscribe sub; - struct snd_iwffff_ops *iwops; - struct snd_gf1_ops *gf1ops; - struct snd_simple_ops *simpleops; - - gus = *(struct snd_gus_card **)SNDRV_SEQ_DEVICE_ARGPTR(dev); - if (gus == NULL) - return -EINVAL; - - init_MUTEX(&gus->register_mutex); - gus->gf1.seq_client = -1; - - /* allocate new client */ - client = gus->gf1.seq_client = - snd_seq_create_kernel_client(gus->card, 1, gus->interwave ? - "AMD InterWave" : "GF1"); - if (client < 0) - return client; - - for (i = 0; i < 4; i++) - snd_gus_synth_create_port(gus, i); - - gus->gf1.ilist = snd_seq_instr_list_new(); - if (gus->gf1.ilist == NULL) { - snd_seq_delete_kernel_client(client); - gus->gf1.seq_client = -1; - return -ENOMEM; - } - gus->gf1.ilist->flags = SNDRV_SEQ_INSTR_FLG_DIRECT; - - simpleops = &gus->gf1.simple_ops; - snd_seq_simple_init(simpleops, gus, NULL); - simpleops->put_sample = snd_gus_simple_put_sample; - simpleops->get_sample = snd_gus_simple_get_sample; - simpleops->remove_sample = snd_gus_simple_remove_sample; - simpleops->notify = snd_gus_synth_instr_notify; - - gf1ops = &gus->gf1.gf1_ops; - snd_seq_gf1_init(gf1ops, gus, &simpleops->kops); - gf1ops->put_sample = snd_gus_gf1_put_sample; - gf1ops->get_sample = snd_gus_gf1_get_sample; - gf1ops->remove_sample = snd_gus_gf1_remove_sample; - gf1ops->notify = snd_gus_synth_instr_notify; - - iwops = &gus->gf1.iwffff_ops; - snd_seq_iwffff_init(iwops, gus, &gf1ops->kops); - iwops->put_sample = snd_gus_iwffff_put_sample; - iwops->get_sample = snd_gus_iwffff_get_sample; - iwops->remove_sample = snd_gus_iwffff_remove_sample; - iwops->notify = snd_gus_synth_instr_notify; - - memset(&sub, 0, sizeof(sub)); - sub.sender.client = SNDRV_SEQ_CLIENT_SYSTEM; - sub.sender.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE; - sub.dest.client = client; - sub.dest.port = 0; - snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &sub); - - return 0; -} - -static int snd_gus_synth_delete_device(struct snd_seq_device *dev) -{ - struct snd_gus_card *gus; - - gus = *(struct snd_gus_card **)SNDRV_SEQ_DEVICE_ARGPTR(dev); - if (gus == NULL) - return -EINVAL; - - if (gus->gf1.seq_client >= 0) { - snd_seq_delete_kernel_client(gus->gf1.seq_client); - gus->gf1.seq_client = -1; - } - if (gus->gf1.ilist) - snd_seq_instr_list_free(&gus->gf1.ilist); - return 0; -} - -static int __init alsa_gus_synth_init(void) -{ - static struct snd_seq_dev_ops ops = { - snd_gus_synth_new_device, - snd_gus_synth_delete_device - }; - - return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_GUS, &ops, - sizeof(struct snd_gus_card *)); -} - -static void __exit alsa_gus_synth_exit(void) -{ - snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_GUS); -} - -module_init(alsa_gus_synth_init) -module_exit(alsa_gus_synth_exit) diff --git a/sound/isa/gus/gus_tables.h b/sound/isa/gus/gus_tables.h index 4adf098d326..42a4ca0d622 100644 --- a/sound/isa/gus/gus_tables.h +++ b/sound/isa/gus/gus_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify diff --git a/sound/isa/gus/gus_timer.c b/sound/isa/gus/gus_timer.c index a43b662f17c..c53727147a1 100644 --- a/sound/isa/gus/gus_timer.c +++ b/sound/isa/gus/gus_timer.c @@ -1,6 +1,6 @@ /* * Routines for Gravis UltraSound soundcards - Timers - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * GUS have similar timers as AdLib (OPL2/OPL3 chips). * @@ -21,7 +21,6 @@ * */ -#include <sound/driver.h> #include <linux/time.h> #include <sound/core.h> #include <sound/gus.h> diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c index 654290a8b21..21cc42e4c4b 100644 --- a/sound/isa/gus/gus_uart.c +++ b/sound/isa/gus/gus_uart.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * Routines for the GF1 MIDI interface - like UART 6850 * * @@ -19,7 +19,6 @@ * */ -#include <sound/driver.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/time.h> @@ -130,8 +129,14 @@ static int snd_gf1_uart_input_open(struct snd_rawmidi_substream *substream) } spin_unlock_irqrestore(&gus->uart_cmd_lock, flags); #if 0 - snd_printk("read init - enable = %i, cmd = 0x%x, stat = 0x%x\n", gus->uart_enable, gus->gf1.uart_cmd, snd_gf1_uart_stat(gus)); - snd_printk("[0x%x] reg (ctrl/status) = 0x%x, reg (data) = 0x%x (page = 0x%x)\n", gus->gf1.port + 0x100, inb(gus->gf1.port + 0x100), inb(gus->gf1.port + 0x101), inb(gus->gf1.port + 0x102)); + snd_printk(KERN_DEBUG + "read init - enable = %i, cmd = 0x%x, stat = 0x%x\n", + gus->uart_enable, gus->gf1.uart_cmd, snd_gf1_uart_stat(gus)); + snd_printk(KERN_DEBUG + "[0x%x] reg (ctrl/status) = 0x%x, reg (data) = 0x%x " + "(page = 0x%x)\n", + gus->gf1.port + 0x100, inb(gus->gf1.port + 0x100), + inb(gus->gf1.port + 0x101), inb(gus->gf1.port + 0x102)); #endif return 0; } diff --git a/sound/isa/gus/gus_volume.c b/sound/isa/gus/gus_volume.c index dbbc0a6d765..3dd841ae708 100644 --- a/sound/isa/gus/gus_volume.c +++ b/sound/isa/gus/gus_volume.c @@ -1,5 +1,5 @@ /* - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -18,8 +18,8 @@ * */ -#include <sound/driver.h> #include <linux/time.h> +#include <linux/export.h> #include <sound/core.h> #include <sound/gus.h> #define __GUS_TABLES_ALLOC__ diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index d1165b96fa3..7ce29ffa1af 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c @@ -1,6 +1,6 @@ /* * Driver for Gravis UltraSound Classic soundcard - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -19,13 +19,12 @@ * */ -#include <sound/driver.h> #include <linux/init.h> #include <linux/err.h> -#include <linux/platform_device.h> +#include <linux/isa.h> #include <linux/delay.h> #include <linux/time.h> -#include <linux/moduleparam.h> +#include <linux/module.h> #include <asm/dma.h> #include <sound/core.h> #include <sound/gus.h> @@ -33,14 +32,17 @@ #define SNDRV_LEGACY_FIND_FREE_DMA #include <sound/initval.h> -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); -MODULE_DESCRIPTION("Gravis UltraSound Classic"); +#define CRD_NAME "Gravis UltraSound Classic" +#define DEV_NAME "gusclassic" + +MODULE_DESCRIPTION(CRD_NAME); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x230,0x240,0x250,0x260 */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 3,5,9,11,12,15 */ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */ @@ -51,32 +53,78 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24}; static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for GUS Classic soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for GUS Classic soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable GUS Classic soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for GUS Classic driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for GUS Classic driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(dma1, int, NULL, 0444); -MODULE_PARM_DESC(dma1, "DMA1 # for GUS Classic driver."); +MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver."); module_param_array(dma2, int, NULL, 0444); -MODULE_PARM_DESC(dma2, "DMA2 # for GUS Classic driver."); +MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver."); module_param_array(joystick_dac, int, NULL, 0444); -MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Classic driver."); +MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver."); module_param_array(channels, int, NULL, 0444); -MODULE_PARM_DESC(channels, "GF1 channels for GUS Classic driver."); +MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver."); module_param_array(pcm_channels, int, NULL, 0444); -MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver."); +MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver."); + +static int snd_gusclassic_match(struct device *dev, unsigned int n) +{ + return enable[n]; +} + +static int snd_gusclassic_create(struct snd_card *card, + struct device *dev, unsigned int n, + struct snd_gus_card **rgus) +{ + static long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260}; + static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1}; + static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; + + int i, error; + + if (irq[n] == SNDRV_AUTO_IRQ) { + irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (irq[n] < 0) { + dev_err(dev, "unable to find a free IRQ\n"); + return -EBUSY; + } + } + if (dma1[n] == SNDRV_AUTO_DMA) { + dma1[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma1[n] < 0) { + dev_err(dev, "unable to find a free DMA1\n"); + return -EBUSY; + } + } + if (dma2[n] == SNDRV_AUTO_DMA) { + dma2[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma2[n] < 0) { + dev_err(dev, "unable to find a free DMA2\n"); + return -EBUSY; + } + } -static struct platform_device *devices[SNDRV_CARDS]; + if (port[n] != SNDRV_AUTO_PORT) + return snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n], + 0, channels[n], pcm_channels[n], 0, rgus); + i = 0; + do { + port[n] = possible_ports[i]; + error = snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n], + 0, channels[n], pcm_channels[n], 0, rgus); + } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); -#define PFX "gusclassic: " + return error; +} -static int __init snd_gusclassic_detect(struct snd_gus_card * gus) +static int snd_gusclassic_detect(struct snd_gus_card *gus) { unsigned char d; @@ -95,187 +143,101 @@ static int __init snd_gusclassic_detect(struct snd_gus_card * gus) return 0; } -static void __init snd_gusclassic_init(int dev, struct snd_gus_card * gus) -{ - gus->equal_irq = 0; - gus->codec_flag = 0; - gus->max_flag = 0; - gus->joystick_dac = joystick_dac[dev]; -} - -static int __init snd_gusclassic_probe(struct platform_device *pdev) +static int snd_gusclassic_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; - static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1}; - static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; - int xirq, xdma1, xdma2; struct snd_card *card; - struct snd_gus_card *gus = NULL; - int err; - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; - if (pcm_channels[dev] < 2) - pcm_channels[dev] = 2; - - xirq = irq[dev]; - if (xirq == SNDRV_AUTO_IRQ) { - if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); - err = -EBUSY; - goto _err; - } - } - xdma1 = dma1[dev]; - if (xdma1 == SNDRV_AUTO_DMA) { - if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA1\n"); - err = -EBUSY; - goto _err; - } - } - xdma2 = dma2[dev]; - if (xdma2 == SNDRV_AUTO_DMA) { - if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA2\n"); - err = -EBUSY; - goto _err; - } - } + struct snd_gus_card *gus; + int error; - if (port[dev] != SNDRV_AUTO_PORT) { - err = snd_gus_create(card, - port[dev], - xirq, xdma1, xdma2, - 0, channels[dev], pcm_channels[dev], - 0, &gus); - } else { - /* auto-probe legacy ports */ - static unsigned long possible_ports[] = { - 0x220, 0x230, 0x240, 0x250, 0x260, - }; - int i; - for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { - err = snd_gus_create(card, - possible_ports[i], - xirq, xdma1, xdma2, - 0, channels[dev], pcm_channels[dev], - 0, &gus); - if (err >= 0) { - port[dev] = possible_ports[i]; - break; - } - } - } - if (err < 0) - goto _err; + error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card); + if (error < 0) + return error; - if ((err = snd_gusclassic_detect(gus)) < 0) - goto _err; + if (pcm_channels[n] < 2) + pcm_channels[n] = 2; - snd_gusclassic_init(dev, gus); - if ((err = snd_gus_initialize(gus)) < 0) - goto _err; + error = snd_gusclassic_create(card, dev, n, &gus); + if (error < 0) + goto out; + error = snd_gusclassic_detect(gus); + if (error < 0) + goto out; + + gus->joystick_dac = joystick_dac[n]; + + error = snd_gus_initialize(gus); + if (error < 0) + goto out; + + error = -ENODEV; if (gus->max_flag || gus->ess_flag) { - snd_printk(KERN_ERR PFX "GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port); - err = -ENODEV; - goto _err; + dev_err(dev, "GUS Classic or ACE soundcard was " + "not detected at 0x%lx\n", gus->gf1.port); + goto out; } - if ((err = snd_gf1_new_mixer(gus)) < 0) - goto _err; + error = snd_gf1_new_mixer(gus); + if (error < 0) + goto out; - if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0) - goto _err; + error = snd_gf1_pcm_new(gus, 0, 0, NULL); + if (error < 0) + goto out; if (!gus->ace_flag) { - if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) - goto _err; + error = snd_gf1_rawmidi_new(gus, 0, NULL); + if (error < 0) + goto out; } - sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1); - if (dma2 >= 0) - sprintf(card->longname + strlen(card->longname), "&%d", xdma2); - snd_card_set_dev(card, &pdev->dev); + sprintf(card->longname + strlen(card->longname), + " at 0x%lx, irq %d, dma %d", + gus->gf1.port, gus->gf1.irq, gus->gf1.dma1); - if ((err = snd_card_register(card)) < 0) - goto _err; + if (gus->gf1.dma2 >= 0) + sprintf(card->longname + strlen(card->longname), + "&%d", gus->gf1.dma2); - platform_set_drvdata(pdev, card); + error = snd_card_register(card); + if (error < 0) + goto out; + + dev_set_drvdata(dev, card); return 0; - _err: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int snd_gusclassic_remove(struct platform_device *devptr) +static int snd_gusclassic_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); return 0; } -#define GUSCLASSIC_DRIVER "snd_gusclassic" - -static struct platform_driver snd_gusclassic_driver = { +static struct isa_driver snd_gusclassic_driver = { + .match = snd_gusclassic_match, .probe = snd_gusclassic_probe, .remove = snd_gusclassic_remove, - /* FIXME: suspend/resume */ +#if 0 /* FIXME */ + .suspend = snd_gusclassic_suspend, + .remove = snd_gusclassic_remove, +#endif .driver = { - .name = GUSCLASSIC_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_gusclassic_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_gusclassic_driver); -} - static int __init alsa_card_gusclassic_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_gusclassic_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { - struct platform_device *device; - device = platform_device_register_simple(GUSCLASSIC_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) { - err = PTR_ERR(device); - goto errout; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "GUS Classic soundcard not found or device busy\n"); -#endif - err = -ENODEV; - goto errout; - } - return 0; - - errout: - snd_gusclassic_unregister_all(); - return err; + return isa_register_driver(&snd_gusclassic_driver, SNDRV_CARDS); } static void __exit alsa_card_gusclassic_exit(void) { - snd_gusclassic_unregister_all(); + isa_unregister_driver(&snd_gusclassic_driver); } -module_init(alsa_card_gusclassic_init) -module_exit(alsa_card_gusclassic_exit) +module_init(alsa_card_gusclassic_init); +module_exit(alsa_card_gusclassic_exit); diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 239f16e6b9e..28a16936a39 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c @@ -1,6 +1,6 @@ /* * Driver for Gravis UltraSound Extreme soundcards - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -19,13 +19,12 @@ * */ -#include <sound/driver.h> #include <linux/init.h> #include <linux/err.h> -#include <linux/platform_device.h> +#include <linux/isa.h> #include <linux/delay.h> #include <linux/time.h> -#include <linux/moduleparam.h> +#include <linux/module.h> #include <asm/dma.h> #include <sound/core.h> #include <sound/gus.h> @@ -37,14 +36,17 @@ #define SNDRV_LEGACY_FIND_FREE_DMA #include <sound/initval.h> -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); -MODULE_DESCRIPTION("Gravis UltraSound Extreme"); +#define CRD_NAME "Gravis UltraSound Extreme" +#define DEV_NAME "gusextreme" + +MODULE_DESCRIPTION(CRD_NAME); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ static long gf1_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS) - 1] = -1}; /* 0x210,0x220,0x230,0x240,0x250,0x260,0x270 */ static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS) - 1] = -1}; /* 0x300,0x310,0x320 */ @@ -59,43 +61,105 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24}; static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for GUS Extreme soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for GUS Extreme soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable GUS Extreme soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for GUS Extreme driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(gf1_port, long, NULL, 0444); -MODULE_PARM_DESC(gf1_port, "GF1 port # for GUS Extreme driver (optional)."); +MODULE_PARM_DESC(gf1_port, "GF1 port # for " CRD_NAME " driver (optional)."); module_param_array(mpu_port, long, NULL, 0444); -MODULE_PARM_DESC(mpu_port, "MPU-401 port # for GUS Extreme driver."); +MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for GUS Extreme driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(mpu_irq, int, NULL, 0444); -MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for GUS Extreme driver."); +MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); module_param_array(gf1_irq, int, NULL, 0444); -MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for GUS Extreme driver."); +MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for " CRD_NAME " driver."); module_param_array(dma8, int, NULL, 0444); -MODULE_PARM_DESC(dma8, "8-bit DMA # for GUS Extreme driver."); +MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); module_param_array(dma1, int, NULL, 0444); -MODULE_PARM_DESC(dma1, "GF1 DMA # for GUS Extreme driver."); +MODULE_PARM_DESC(dma1, "GF1 DMA # for " CRD_NAME " driver."); module_param_array(joystick_dac, int, NULL, 0444); -MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Extreme driver."); +MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver."); module_param_array(channels, int, NULL, 0444); -MODULE_PARM_DESC(channels, "GF1 channels for GUS Extreme driver."); +MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver."); module_param_array(pcm_channels, int, NULL, 0444); -MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver."); +MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver."); -struct platform_device *devices[SNDRV_CARDS]; +static int snd_gusextreme_match(struct device *dev, unsigned int n) +{ + return enable[n]; +} + +static int snd_gusextreme_es1688_create(struct snd_card *card, + struct snd_es1688 *chip, + struct device *dev, unsigned int n) +{ + static long possible_ports[] = {0x220, 0x240, 0x260}; + static int possible_irqs[] = {5, 9, 10, 7, -1}; + static int possible_dmas[] = {1, 3, 0, -1}; + int i, error; -#define PFX "gusextreme: " + if (irq[n] == SNDRV_AUTO_IRQ) { + irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (irq[n] < 0) { + dev_err(dev, "unable to find a free IRQ for ES1688\n"); + return -EBUSY; + } + } + if (dma8[n] == SNDRV_AUTO_DMA) { + dma8[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma8[n] < 0) { + dev_err(dev, "unable to find a free DMA for ES1688\n"); + return -EBUSY; + } + } -static int __init snd_gusextreme_detect(int dev, - struct snd_card *card, - struct snd_gus_card * gus, - struct snd_es1688 *es1688) + if (port[n] != SNDRV_AUTO_PORT) + return snd_es1688_create(card, chip, port[n], mpu_port[n], + irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688); + + i = 0; + do { + port[n] = possible_ports[i]; + error = snd_es1688_create(card, chip, port[n], mpu_port[n], + irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688); + } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); + + return error; +} + +static int snd_gusextreme_gus_card_create(struct snd_card *card, + struct device *dev, unsigned int n, + struct snd_gus_card **rgus) +{ + static int possible_irqs[] = {11, 12, 15, 9, 5, 7, 3, -1}; + static int possible_dmas[] = {5, 6, 7, 3, 1, -1}; + + if (gf1_irq[n] == SNDRV_AUTO_IRQ) { + gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (gf1_irq[n] < 0) { + dev_err(dev, "unable to find a free IRQ for GF1\n"); + return -EBUSY; + } + } + if (dma1[n] == SNDRV_AUTO_DMA) { + dma1[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma1[n] < 0) { + dev_err(dev, "unable to find a free DMA for GF1\n"); + return -EBUSY; + } + } + return snd_gus_create(card, gf1_port[n], gf1_irq[n], dma1[n], -1, + 0, channels[n], pcm_channels[n], 0, rgus); +} + +static int snd_gusextreme_detect(struct snd_gus_card *gus, + struct snd_es1688 *es1688) { unsigned long flags; unsigned char d; @@ -117,12 +181,13 @@ static int __init snd_gusextreme_detect(int dev, spin_lock_irqsave(&es1688->mixer_lock, flags); snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */ spin_unlock_irqrestore(&es1688->mixer_lock, flags); + spin_lock_irqsave(&es1688->reg_lock, flags); - outb(gf1_port[dev] & 0x040 ? 2 : 0, ES1688P(es1688, INIT1)); + outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1)); outb(0, 0x201); - outb(gf1_port[dev] & 0x020 ? 2 : 0, ES1688P(es1688, INIT1)); + outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1)); outb(0, 0x201); - outb(gf1_port[dev] & 0x010 ? 3 : 1, ES1688P(es1688, INIT1)); + outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1)); spin_unlock_irqrestore(&es1688->reg_lock, flags); udelay(100); @@ -139,253 +204,169 @@ static int __init snd_gusextreme_detect(int dev, snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d); return -EIO; } - return 0; -} -static void __init snd_gusextreme_init(int dev, struct snd_gus_card * gus) -{ - gus->joystick_dac = joystick_dac[dev]; + return 0; } -static int __init snd_gusextreme_mixer(struct snd_es1688 *chip) +static int snd_gusextreme_mixer(struct snd_card *card) { - struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; - int err; + int error; memset(&id1, 0, sizeof(id1)); memset(&id2, 0, sizeof(id2)); id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + /* reassign AUX to SYNTHESIZER */ strcpy(id1.name, "Aux Playback Volume"); strcpy(id2.name, "Synth Playback Volume"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) - return err; + error = snd_ctl_rename_id(card, &id1, &id2); + if (error < 0) + return error; + /* reassign Master Playback Switch to Synth Playback Switch */ strcpy(id1.name, "Master Playback Switch"); strcpy(id2.name, "Synth Playback Switch"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) - return err; + error = snd_ctl_rename_id(card, &id1, &id2); + if (error < 0) + return error; + return 0; } -static int __init snd_gusextreme_probe(struct platform_device *pdev) +static int snd_gusextreme_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; - static int possible_ess_irqs[] = {5, 9, 10, 7, -1}; - static int possible_ess_dmas[] = {1, 3, 0, -1}; - static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; - static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1}; - int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma; struct snd_card *card; struct snd_gus_card *gus; struct snd_es1688 *es1688; struct snd_opl3 *opl3; - int err; + int error; - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; + error = snd_card_new(dev, index[n], id[n], THIS_MODULE, + sizeof(struct snd_es1688), &card); + if (error < 0) + return error; - xgf1_irq = gf1_irq[dev]; - if (xgf1_irq == SNDRV_AUTO_IRQ) { - if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n"); - err = -EBUSY; - goto out; - } - } - xess_irq = irq[dev]; - if (xess_irq == SNDRV_AUTO_IRQ) { - if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n"); - err = -EBUSY; - goto out; - } - } - if (mpu_port[dev] == SNDRV_AUTO_PORT) - mpu_port[dev] = 0; - xmpu_irq = mpu_irq[dev]; - if (xmpu_irq > 15) - xmpu_irq = -1; - xgf1_dma = dma1[dev]; - if (xgf1_dma == SNDRV_AUTO_DMA) { - if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n"); - err = -EBUSY; - goto out; - } - } - xess_dma = dma8[dev]; - if (xess_dma == SNDRV_AUTO_DMA) { - if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n"); - err = -EBUSY; - goto out; - } - } + es1688 = card->private_data; - if (port[dev] != SNDRV_AUTO_PORT) { - err = snd_es1688_create(card, port[dev], mpu_port[dev], - xess_irq, xmpu_irq, xess_dma, - ES1688_HW_1688, &es1688); - } else { - /* auto-probe legacy ports */ - static unsigned long possible_ports[] = {0x220, 0x240, 0x260}; - int i; - for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { - err = snd_es1688_create(card, - possible_ports[i], - mpu_port[dev], - xess_irq, xmpu_irq, xess_dma, - ES1688_HW_1688, &es1688); - if (err >= 0) { - port[dev] = possible_ports[i]; - break; - } - } - } - if (err < 0) + if (mpu_port[n] == SNDRV_AUTO_PORT) + mpu_port[n] = 0; + + if (mpu_irq[n] > 15) + mpu_irq[n] = -1; + + error = snd_gusextreme_es1688_create(card, es1688, dev, n); + if (error < 0) goto out; - if (gf1_port[dev] < 0) - gf1_port[dev] = port[dev] + 0x20; - if ((err = snd_gus_create(card, - gf1_port[dev], - xgf1_irq, - xgf1_dma, - -1, - 0, channels[dev], - pcm_channels[dev], 0, - &gus)) < 0) + if (gf1_port[n] < 0) + gf1_port[n] = es1688->port + 0x20; + + error = snd_gusextreme_gus_card_create(card, dev, n, &gus); + if (error < 0) goto out; - if ((err = snd_gusextreme_detect(dev, card, gus, es1688)) < 0) + error = snd_gusextreme_detect(gus, es1688); + if (error < 0) goto out; - snd_gusextreme_init(dev, gus); - if ((err = snd_gus_initialize(gus)) < 0) + gus->joystick_dac = joystick_dac[n]; + + error = snd_gus_initialize(gus); + if (error < 0) goto out; + error = -ENODEV; if (!gus->ess_flag) { - snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port); - err = -ENODEV; + dev_err(dev, "GUS Extreme soundcard was not " + "detected at 0x%lx\n", gus->gf1.port); goto out; } - if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0) + gus->codec_flag = 1; + + error = snd_es1688_pcm(card, es1688, 0, NULL); + if (error < 0) goto out; - if ((err = snd_es1688_mixer(es1688)) < 0) + error = snd_es1688_mixer(card, es1688); + if (error < 0) goto out; snd_component_add(card, "ES1688"); - if (pcm_channels[dev] > 0) { - if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) + + if (pcm_channels[n] > 0) { + error = snd_gf1_pcm_new(gus, 1, 1, NULL); + if (error < 0) goto out; } - if ((err = snd_gf1_new_mixer(gus)) < 0) + + error = snd_gf1_new_mixer(gus); + if (error < 0) goto out; - if ((err = snd_gusextreme_mixer(es1688)) < 0) + error = snd_gusextreme_mixer(card); + if (error < 0) goto out; if (snd_opl3_create(card, es1688->port, es1688->port + 2, - OPL3_HW_OPL3, 0, &opl3) < 0) { - printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port); - } else { - if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0) + OPL3_HW_OPL3, 0, &opl3) < 0) + dev_warn(dev, "opl3 not detected at 0x%lx\n", es1688->port); + else { + error = snd_opl3_hwdep_new(opl3, 0, 2, NULL); + if (error < 0) goto out; } - if (es1688->mpu_port >= 0x300 && - (err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, - es1688->mpu_port, 0, - xmpu_irq, - SA_INTERRUPT, - NULL)) < 0) - goto out; - - sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i", - es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma); + if (es1688->mpu_port >= 0x300) { + error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, + es1688->mpu_port, 0, mpu_irq[n], NULL); + if (error < 0) + goto out; + } - snd_card_set_dev(card, &pdev->dev); + sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, " + "irq %i&%i, dma %i&%i", es1688->port, + gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8); - if ((err = snd_card_register(card)) < 0) + error = snd_card_register(card); + if (error < 0) goto out; - platform_set_drvdata(pdev, card); + dev_set_drvdata(dev, card); return 0; - out: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int snd_gusextreme_remove(struct platform_device *devptr) +static int snd_gusextreme_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); return 0; } -#define GUSEXTREME_DRIVER "snd_gusextreme" - -static struct platform_driver snd_gusextreme_driver = { +static struct isa_driver snd_gusextreme_driver = { + .match = snd_gusextreme_match, .probe = snd_gusextreme_probe, .remove = snd_gusextreme_remove, - /* FIXME: suspend/resume */ +#if 0 /* FIXME */ + .suspend = snd_gusextreme_suspend, + .resume = snd_gusextreme_resume, +#endif .driver = { - .name = GUSEXTREME_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_gusextreme_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_gusextreme_driver); -} - static int __init alsa_card_gusextreme_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_gusextreme_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { - struct platform_device *device; - device = platform_device_register_simple(GUSEXTREME_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) { - err = PTR_ERR(device); - goto errout; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n"); -#endif - err = -ENODEV; - goto errout; - } - return 0; - - errout: - snd_gusextreme_unregister_all(); - return err; + return isa_register_driver(&snd_gusextreme_driver, SNDRV_CARDS); } static void __exit alsa_card_gusextreme_exit(void) { - snd_gusextreme_unregister_all(); + isa_unregister_driver(&snd_gusextreme_driver); } -module_init(alsa_card_gusextreme_init) -module_exit(alsa_card_gusextreme_exit) +module_init(alsa_card_gusextreme_init); +module_exit(alsa_card_gusextreme_exit); diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index d4d2b2a517d..39df36ca3ac 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c @@ -1,6 +1,6 @@ /* * Driver for Gravis UltraSound MAX soundcard - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -19,29 +19,28 @@ * */ -#include <sound/driver.h> #include <linux/init.h> #include <linux/err.h> -#include <linux/platform_device.h> +#include <linux/isa.h> #include <linux/delay.h> #include <linux/time.h> -#include <linux/moduleparam.h> +#include <linux/module.h> #include <asm/dma.h> #include <sound/core.h> #include <sound/gus.h> -#include <sound/cs4231.h> +#include <sound/wss.h> #define SNDRV_LEGACY_FIND_FREE_IRQ #define SNDRV_LEGACY_FIND_FREE_DMA #include <sound/initval.h> -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("Gravis UltraSound MAX"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound MAX}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x230,0x240,0x250,0x260 */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,3,5,9,11,12,15 */ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */ @@ -72,20 +71,18 @@ MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver."); module_param_array(pcm_channels, int, NULL, 0444); MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver."); -static struct platform_device *devices[SNDRV_CARDS]; - struct snd_gusmax { int irq; struct snd_card *card; struct snd_gus_card *gus; - struct snd_cs4231 *cs4231; + struct snd_wss *wss; unsigned short gus_status_reg; unsigned short pcm_status_reg; }; #define PFX "gusmax: " -static int __init snd_gusmax_detect(struct snd_gus_card * gus) +static int snd_gusmax_detect(struct snd_gus_card *gus) { unsigned char d; @@ -105,9 +102,9 @@ static int __init snd_gusmax_detect(struct snd_gus_card * gus) return 0; } -static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id) { - struct snd_gusmax *maxcard = (struct snd_gusmax *) dev_id; + struct snd_gusmax *maxcard = dev_id; int loop, max = 5; int handled = 0; @@ -115,19 +112,20 @@ static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id, struct pt_regs *r loop = 0; if (inb(maxcard->gus_status_reg)) { handled = 1; - snd_gus_interrupt(irq, maxcard->gus, regs); + snd_gus_interrupt(irq, maxcard->gus); loop++; } if (inb(maxcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */ handled = 1; - snd_cs4231_interrupt(irq, maxcard->cs4231, regs); + snd_wss_interrupt(irq, maxcard->wss); loop++; } } while (loop && --max > 0); return IRQ_RETVAL(handled); } -static void __init snd_gusmax_init(int dev, struct snd_card *card, struct snd_gus_card * gus) +static void snd_gusmax_init(int dev, struct snd_card *card, + struct snd_gus_card *gus) { gus->equal_irq = 1; gus->codec_flag = 1; @@ -142,10 +140,7 @@ static void __init snd_gusmax_init(int dev, struct snd_card *card, struct snd_gu outb(gus->max_cntrl_val, GUSP(gus, MAXCNTRLPORT)); } -#define CS4231_PRIVATE( left, right, shift, mute ) \ - ((left << 24)|(right << 16)|(shift<<8)|mute) - -static int __init snd_gusmax_mixer(struct snd_cs4231 *chip) +static int snd_gusmax_mixer(struct snd_wss *chip) { struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; @@ -196,7 +191,7 @@ static int __init snd_gusmax_mixer(struct snd_cs4231 *chip) static void snd_gusmax_free(struct snd_card *card) { - struct snd_gusmax *maxcard = (struct snd_gusmax *)card->private_data; + struct snd_gusmax *maxcard = card->private_data; if (maxcard == NULL) return; @@ -204,23 +199,27 @@ static void snd_gusmax_free(struct snd_card *card) free_irq(maxcard->irq, (void *)maxcard); } -static int __init snd_gusmax_probe(struct platform_device *pdev) +static int snd_gusmax_match(struct device *pdev, unsigned int dev) +{ + return enable[dev]; +} + +static int snd_gusmax_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; int xirq, xdma1, xdma2, err; struct snd_card *card; struct snd_gus_card *gus = NULL; - struct snd_cs4231 *cs4231; + struct snd_wss *wss; struct snd_gusmax *maxcard; - card = snd_card_new(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_gusmax)); - if (card == NULL) - return -ENOMEM; + err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_gusmax), &card); + if (err < 0) + return err; card->private_free = snd_gusmax_free; - maxcard = (struct snd_gusmax *)card->private_data; + maxcard = card->private_data; maxcard->card = card; maxcard->irq = -1; @@ -292,55 +291,60 @@ static int __init snd_gusmax_probe(struct platform_device *pdev) goto _err; } - if (request_irq(xirq, snd_gusmax_interrupt, SA_INTERRUPT, "GUS MAX", (void *)maxcard)) { + if (request_irq(xirq, snd_gusmax_interrupt, 0, "GUS MAX", (void *)maxcard)) { snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); err = -EBUSY; goto _err; } maxcard->irq = xirq; - if ((err = snd_cs4231_create(card, - gus->gf1.port + 0x10c, -1, xirq, - xdma2 < 0 ? xdma1 : xdma2, xdma1, - CS4231_HW_DETECT, - CS4231_HWSHARE_IRQ | - CS4231_HWSHARE_DMA1 | - CS4231_HWSHARE_DMA2, - &cs4231)) < 0) + err = snd_wss_create(card, + gus->gf1.port + 0x10c, -1, xirq, + xdma2 < 0 ? xdma1 : xdma2, xdma1, + WSS_HW_DETECT, + WSS_HWSHARE_IRQ | + WSS_HWSHARE_DMA1 | + WSS_HWSHARE_DMA2, + &wss); + if (err < 0) goto _err; - if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0) + err = snd_wss_pcm(wss, 0, NULL); + if (err < 0) goto _err; - if ((err = snd_cs4231_mixer(cs4231)) < 0) + err = snd_wss_mixer(wss); + if (err < 0) goto _err; - if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) + err = snd_wss_timer(wss, 2, NULL); + if (err < 0) goto _err; if (pcm_channels[dev] > 0) { if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) goto _err; } - if ((err = snd_gusmax_mixer(cs4231)) < 0) + err = snd_gusmax_mixer(wss); + if (err < 0) goto _err; - if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) + err = snd_gf1_rawmidi_new(gus, 0, NULL); + if (err < 0) goto _err; sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %i, dma %i", gus->gf1.port, xirq, xdma1); if (xdma2 >= 0) sprintf(card->longname + strlen(card->longname), "&%i", xdma2); - snd_card_set_dev(card, &pdev->dev); - - if ((err = snd_card_register(card)) < 0) + err = snd_card_register(card); + if (err < 0) goto _err; maxcard->gus = gus; - maxcard->cs4231 = cs4231; + maxcard->wss = wss; - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; _err: @@ -348,70 +352,32 @@ static int __init snd_gusmax_probe(struct platform_device *pdev) return err; } -static int snd_gusmax_remove(struct platform_device *devptr) +static int snd_gusmax_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); return 0; } -#define GUSMAX_DRIVER "snd_gusmax" +#define DEV_NAME "gusmax" -static struct platform_driver snd_gusmax_driver = { +static struct isa_driver snd_gusmax_driver = { + .match = snd_gusmax_match, .probe = snd_gusmax_probe, .remove = snd_gusmax_remove, /* FIXME: suspend/resume */ .driver = { - .name = GUSMAX_DRIVER + .name = DEV_NAME }, }; -static void __init_or_module snd_gusmax_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_gusmax_driver); -} - static int __init alsa_card_gusmax_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_gusmax_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { - struct platform_device *device; - device = platform_device_register_simple(GUSMAX_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) { - err = PTR_ERR(device); - goto errout; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "GUS MAX soundcard not found or device busy\n"); -#endif - err = -ENODEV; - goto errout; - } - return 0; - - errout: - snd_gusmax_unregister_all(); - return err; + return isa_register_driver(&snd_gusmax_driver, SNDRV_CARDS); } static void __exit alsa_card_gusmax_exit(void) { - snd_gusmax_unregister_all(); + isa_unregister_driver(&snd_gusmax_driver); } module_init(alsa_card_gusmax_init) diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 9838d992b10..ad55e5cb8e9 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -1,6 +1,6 @@ /* * Driver for AMD InterWave soundcard - * Copyright (c) by Jaroslav Kysela <perex@suse.cz> + * Copyright (c) by Jaroslav Kysela <perex@perex.cz> * * * This program is free software; you can redistribute it and/or modify @@ -22,18 +22,16 @@ * */ -#include <sound/driver.h> #include <linux/init.h> #include <linux/err.h> -#include <linux/platform_device.h> +#include <linux/isa.h> #include <linux/delay.h> -#include <linux/slab.h> #include <linux/pnp.h> -#include <linux/moduleparam.h> +#include <linux/module.h> #include <asm/dma.h> #include <sound/core.h> #include <sound/gus.h> -#include <sound/cs4231.h> +#include <sound/wss.h> #ifdef SNDRV_STB #include <sound/tea6330t.h> #endif @@ -41,7 +39,7 @@ #define SNDRV_LEGACY_FIND_FREE_DMA #include <sound/initval.h> -MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); +MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_LICENSE("GPL"); #ifndef SNDRV_STB MODULE_DESCRIPTION("AMD InterWave"); @@ -57,9 +55,9 @@ MODULE_SUPPORTED_DEVICE("{{AMD,InterWave STB with TEA6330T}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x210,0x220,0x230,0x240,0x250,0x260 */ #ifdef SNDRV_STB @@ -70,9 +68,9 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29}; /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */ -static int midi[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; +static int midi[SNDRV_CARDS]; static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; -static int effect[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; +static int effect[SNDRV_CARDS]; #ifdef SNDRV_STB #define PFX "interwave-stb: " @@ -115,14 +113,11 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver."); module_param_array(effect, int, NULL, 0444); MODULE_PARM_DESC(effect, "Effects enable for InterWave driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; -static int pnp_registered; - struct snd_interwave { int irq; struct snd_card *card; struct snd_gus_card *gus; - struct snd_cs4231 *cs4231; + struct snd_wss *wss; #ifdef SNDRV_STB struct resource *i2c_res; #endif @@ -138,6 +133,8 @@ struct snd_interwave { #ifdef CONFIG_PNP +static int isa_registered; +static int pnp_registered; static struct pnp_card_device_id snd_interwave_pnpids[] = { #ifndef SNDRV_STB @@ -172,7 +169,7 @@ static void snd_interwave_i2c_setlines(struct snd_i2c_bus *bus, int ctrl, int da unsigned long port = bus->private_value; #if 0 - printk("i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data); + printk(KERN_DEBUG "i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data); #endif outb((data << 1) | ctrl, port); udelay(10); @@ -185,7 +182,7 @@ static int snd_interwave_i2c_getclockline(struct snd_i2c_bus *bus) res = inb(port) & 1; #if 0 - printk("i2c_getclockline - 0x%lx -> %i\n", port, res); + printk(KERN_DEBUG "i2c_getclockline - 0x%lx -> %i\n", port, res); #endif return res; } @@ -199,7 +196,7 @@ static int snd_interwave_i2c_getdataline(struct snd_i2c_bus *bus, int ack) udelay(10); res = (inb(port) & 2) >> 1; #if 0 - printk("i2c_getdataline - 0x%lx -> %i\n", port, res); + printk(KERN_DEBUG "i2c_getdataline - 0x%lx -> %i\n", port, res); #endif return res; } @@ -210,9 +207,9 @@ static struct snd_i2c_bit_ops snd_interwave_i2c_bit_ops = { .getdata = snd_interwave_i2c_getdataline, }; -static int __devinit snd_interwave_detect_stb(struct snd_interwave *iwcard, - struct snd_gus_card * gus, int dev, - struct snd_i2c_bus **rbus) +static int snd_interwave_detect_stb(struct snd_interwave *iwcard, + struct snd_gus_card *gus, int dev, + struct snd_i2c_bus **rbus) { unsigned long port; struct snd_i2c_bus *bus; @@ -252,11 +249,11 @@ static int __devinit snd_interwave_detect_stb(struct snd_interwave *iwcard, } #endif -static int __devinit snd_interwave_detect(struct snd_interwave *iwcard, - struct snd_gus_card * gus, - int dev +static int snd_interwave_detect(struct snd_interwave *iwcard, + struct snd_gus_card *gus, + int dev #ifdef SNDRV_STB - , struct snd_i2c_bus **rbus + , struct snd_i2c_bus **rbus #endif ) { @@ -299,9 +296,9 @@ static int __devinit snd_interwave_detect(struct snd_interwave *iwcard, return -ENODEV; } -static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id) { - struct snd_interwave *iwcard = (struct snd_interwave *) dev_id; + struct snd_interwave *iwcard = dev_id; int loop, max = 5; int handled = 0; @@ -309,19 +306,19 @@ static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id, struct pt_regs loop = 0; if (inb(iwcard->gus_status_reg)) { handled = 1; - snd_gus_interrupt(irq, iwcard->gus, regs); + snd_gus_interrupt(irq, iwcard->gus); loop++; } if (inb(iwcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */ handled = 1; - snd_cs4231_interrupt(irq, iwcard->cs4231, regs); + snd_wss_interrupt(irq, iwcard->wss); loop++; } } while (loop && --max > 0); return IRQ_RETVAL(handled); } -static void __devinit snd_interwave_reset(struct snd_gus_card * gus) +static void snd_interwave_reset(struct snd_gus_card *gus) { snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x00); udelay(160); @@ -329,7 +326,7 @@ static void __devinit snd_interwave_reset(struct snd_gus_card * gus) udelay(160); } -static void __devinit snd_interwave_bank_sizes(struct snd_gus_card * gus, int *sizes) +static void snd_interwave_bank_sizes(struct snd_gus_card *gus, int *sizes) { unsigned int idx; unsigned int local; @@ -344,7 +341,8 @@ static void __devinit snd_interwave_bank_sizes(struct snd_gus_card * gus, int *s snd_gf1_poke(gus, local, d); snd_gf1_poke(gus, local + 1, d + 1); #if 0 - printk("d = 0x%x, local = 0x%x, local + 1 = 0x%x, idx << 22 = 0x%x\n", + printk(KERN_DEBUG "d = 0x%x, local = 0x%x, " + "local + 1 = 0x%x, idx << 22 = 0x%x\n", d, snd_gf1_peek(gus, local), snd_gf1_peek(gus, local + 1), @@ -358,7 +356,8 @@ static void __devinit snd_interwave_bank_sizes(struct snd_gus_card * gus, int *s } } #if 0 - printk("sizes: %i %i %i %i\n", sizes[0], sizes[1], sizes[2], sizes[3]); + printk(KERN_DEBUG "sizes: %i %i %i %i\n", + sizes[0], sizes[1], sizes[2], sizes[3]); #endif } @@ -378,7 +377,7 @@ struct rom_hdr { /* 511 */ unsigned char csum; }; -static void __devinit snd_interwave_detect_memory(struct snd_gus_card * gus) +static void snd_interwave_detect_memory(struct snd_gus_card *gus) { static unsigned int lmc[13] = { @@ -412,12 +411,12 @@ static void __devinit snd_interwave_detect_memory(struct snd_gus_card * gus) lmct = (psizes[3] << 24) | (psizes[2] << 16) | (psizes[1] << 8) | psizes[0]; #if 0 - printk("lmct = 0x%08x\n", lmct); + printk(KERN_DEBUG "lmct = 0x%08x\n", lmct); #endif for (i = 0; i < ARRAY_SIZE(lmc); i++) if (lmct == lmc[i]) { #if 0 - printk("found !!! %i\n", i); + printk(KERN_DEBUG "found !!! %i\n", i); #endif snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | i); snd_interwave_bank_sizes(gus, psizes); @@ -443,19 +442,11 @@ static void __devinit snd_interwave_detect_memory(struct snd_gus_card * gus) for (bank_pos = 0; bank_pos < 16L * 1024L * 1024L; bank_pos += 4L * 1024L * 1024L) { for (i = 0; i < 8; ++i) iwave[i] = snd_gf1_peek(gus, bank_pos + i); -#ifdef CONFIG_SND_DEBUG_ROM - printk(KERN_DEBUG "ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos, - iwave[0], iwave[1], iwave[2], iwave[3], - iwave[4], iwave[5], iwave[6], iwave[7]); -#endif if (strncmp(iwave, "INTRWAVE", 8)) continue; /* first check */ csum = 0; for (i = 0; i < sizeof(struct rom_hdr); i++) csum += snd_gf1_peek(gus, bank_pos + i); -#ifdef CONFIG_SND_DEBUG_ROM - printk(KERN_DEBUG "ROM checksum = 0x%x (computed)\n", csum); -#endif if (csum != 0) continue; /* not valid rom */ gus->gf1.rom_banks++; @@ -477,7 +468,7 @@ static void __devinit snd_interwave_detect_memory(struct snd_gus_card * gus) snd_interwave_reset(gus); } -static void __devinit snd_interwave_init(int dev, struct snd_gus_card * gus) +static void snd_interwave_init(int dev, struct snd_gus_card *gus) { unsigned long flags; @@ -500,13 +491,17 @@ static void __devinit snd_interwave_init(int dev, struct snd_gus_card * gus) } static struct snd_kcontrol_new snd_interwave_controls[] = { -CS4231_DOUBLE("Master Playback Switch", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Master Playback Volume", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1), -CS4231_DOUBLE("Mic Playback Switch", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1), -CS4231_DOUBLE("Mic Playback Volume", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1) +WSS_DOUBLE("Master Playback Switch", 0, + CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1), +WSS_DOUBLE("Master Playback Volume", 0, + CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1), +WSS_DOUBLE("Mic Playback Switch", 0, + CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1), +WSS_DOUBLE("Mic Playback Volume", 0, + CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1) }; -static int __devinit snd_interwave_mixer(struct snd_cs4231 *chip) +static int snd_interwave_mixer(struct snd_wss *chip) { struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; @@ -529,10 +524,10 @@ static int __devinit snd_interwave_mixer(struct snd_cs4231 *chip) for (idx = 0; idx < ARRAY_SIZE(snd_interwave_controls); idx++) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip))) < 0) return err; - snd_cs4231_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f); - snd_cs4231_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f); - snd_cs4231_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f); - snd_cs4231_out(chip, CS4231_RIGHT_MIC_INPUT, 0x9f); + snd_wss_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f); + snd_wss_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f); + snd_wss_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f); + snd_wss_out(chip, CS4231_RIGHT_MIC_INPUT, 0x9f); /* reassign AUXA to SYNTHESIZER */ strcpy(id1.name, "Aux Playback Switch"); strcpy(id2.name, "Synth Playback Switch"); @@ -556,53 +551,32 @@ static int __devinit snd_interwave_mixer(struct snd_cs4231 *chip) #ifdef CONFIG_PNP -static int __devinit snd_interwave_pnp(int dev, struct snd_interwave *iwcard, - struct pnp_card_link *card, - const struct pnp_card_device_id *id) +static int snd_interwave_pnp(int dev, struct snd_interwave *iwcard, + struct pnp_card_link *card, + const struct pnp_card_device_id *id) { struct pnp_dev *pdev; - struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); int err; iwcard->dev = pnp_request_card_device(card, id->devs[0].id, NULL); - if (iwcard->dev == NULL) { - kfree(cfg); + if (iwcard->dev == NULL) return -EBUSY; - } + #ifdef SNDRV_STB iwcard->devtc = pnp_request_card_device(card, id->devs[1].id, NULL); - if (iwcard->devtc == NULL) { - kfree(cfg); + if (iwcard->devtc == NULL) return -EBUSY; - } #endif /* Synth & Codec initialization */ pdev = iwcard->dev; - pnp_init_resource_table(cfg); - if (port[dev] != SNDRV_AUTO_PORT) { - pnp_resource_change(&cfg->port_resource[0], port[dev], 16); - pnp_resource_change(&cfg->port_resource[1], port[dev] + 0x100, 12); - pnp_resource_change(&cfg->port_resource[2], port[dev] + 0x10c, 4); - } - if (dma1[dev] != SNDRV_AUTO_DMA) - pnp_resource_change(&cfg->dma_resource[0], dma1[dev], 1); - if (dma2[dev] != SNDRV_AUTO_DMA) - pnp_resource_change(&cfg->dma_resource[1], dma2[dev], 1); - if (dma2[dev] < 0) - pnp_resource_change(&cfg->dma_resource[1], 4, 1); - if (irq[dev] != SNDRV_AUTO_IRQ) - pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1); - if (pnp_manual_config_dev(pdev, cfg, 0) < 0) - snd_printk(KERN_ERR "InterWave - Synth - the requested resources are invalid, using auto config\n"); + err = pnp_activate_dev(pdev); if (err < 0) { - kfree(cfg); snd_printk(KERN_ERR "InterWave PnP configure failure (out of resources?)\n"); return err; } if (pnp_port_start(pdev, 0) + 0x100 != pnp_port_start(pdev, 1) || pnp_port_start(pdev, 0) + 0x10c != pnp_port_start(pdev, 2)) { - kfree(cfg); snd_printk(KERN_ERR "PnP configure failure (wrong ports)\n"); return -ENOENT; } @@ -611,29 +585,23 @@ static int __devinit snd_interwave_pnp(int dev, struct snd_interwave *iwcard, if (dma2[dev] >= 0) dma2[dev] = pnp_dma(pdev, 1); irq[dev] = pnp_irq(pdev, 0); - snd_printdd("isapnp IW: sb port=0x%lx, gf1 port=0x%lx, codec port=0x%lx\n", - pnp_port_start(pdev, 0), - pnp_port_start(pdev, 1), - pnp_port_start(pdev, 2)); + snd_printdd("isapnp IW: sb port=0x%llx, gf1 port=0x%llx, codec port=0x%llx\n", + (unsigned long long)pnp_port_start(pdev, 0), + (unsigned long long)pnp_port_start(pdev, 1), + (unsigned long long)pnp_port_start(pdev, 2)); snd_printdd("isapnp IW: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]); #ifdef SNDRV_STB /* Tone Control initialization */ pdev = iwcard->devtc; - pnp_init_resource_table(cfg); - if (port_tc[dev] != SNDRV_AUTO_PORT) - pnp_resource_change(&cfg->port_resource[0], port_tc[dev], 1); - if (pnp_manual_config_dev(pdev, cfg, 0) < 0) - snd_printk(KERN_ERR "InterWave - ToneControl - the requested resources are invalid, using auto config\n"); + err = pnp_activate_dev(pdev); if (err < 0) { - kfree(cfg); snd_printk(KERN_ERR "InterWave ToneControl PnP configure failure (out of resources?)\n"); return err; } port_tc[dev] = pnp_port_start(pdev, 0); snd_printdd("isapnp IW: tone control port=0x%lx\n", port_tc[dev]); #endif - kfree(cfg); return 0; } #endif /* CONFIG_PNP */ @@ -651,27 +619,30 @@ static void snd_interwave_free(struct snd_card *card) free_irq(iwcard->irq, (void *)iwcard); } -static struct snd_card *snd_interwave_card_new(int dev) +static int snd_interwave_card_new(struct device *pdev, int dev, + struct snd_card **cardp) { struct snd_card *card; struct snd_interwave *iwcard; + int err; - card = snd_card_new(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_interwave)); - if (card == NULL) - return NULL; + err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_interwave), &card); + if (err < 0) + return err; iwcard = card->private_data; iwcard->card = card; iwcard->irq = -1; card->private_free = snd_interwave_free; - return card; + *cardp = card; + return 0; } -static int __devinit snd_interwave_probe(struct snd_card *card, int dev) +static int snd_interwave_probe(struct snd_card *card, int dev) { int xirq, xdma1, xdma2; struct snd_interwave *iwcard = card->private_data; - struct snd_cs4231 *cs4231; + struct snd_wss *wss; struct snd_gus_card *gus; #ifdef SNDRV_STB struct snd_i2c_bus *i2c_bus; @@ -706,40 +677,46 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev) if ((err = snd_gus_initialize(gus)) < 0) return err; - if (request_irq(xirq, snd_interwave_interrupt, SA_INTERRUPT, + if (request_irq(xirq, snd_interwave_interrupt, 0, "InterWave", iwcard)) { snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); return -EBUSY; } iwcard->irq = xirq; - if ((err = snd_cs4231_create(card, - gus->gf1.port + 0x10c, -1, xirq, - xdma2 < 0 ? xdma1 : xdma2, xdma1, - CS4231_HW_INTERWAVE, - CS4231_HWSHARE_IRQ | - CS4231_HWSHARE_DMA1 | - CS4231_HWSHARE_DMA2, - &cs4231)) < 0) + err = snd_wss_create(card, + gus->gf1.port + 0x10c, -1, xirq, + xdma2 < 0 ? xdma1 : xdma2, xdma1, + WSS_HW_INTERWAVE, + WSS_HWSHARE_IRQ | + WSS_HWSHARE_DMA1 | + WSS_HWSHARE_DMA2, + &wss); + if (err < 0) return err; - if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0) + err = snd_wss_pcm(wss, 0, &pcm); + if (err < 0) return err; sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A'); strcat(pcm->name, " (codec)"); - if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) + err = snd_wss_timer(wss, 2, NULL); + if (err < 0) return err; - if ((err = snd_cs4231_mixer(cs4231)) < 0) + err = snd_wss_mixer(wss); + if (err < 0) return err; if (pcm_channels[dev] > 0) { - if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) + err = snd_gf1_pcm_new(gus, 1, 1, NULL); + if (err < 0) return err; } - if ((err = snd_interwave_mixer(cs4231)) < 0) + err = snd_interwave_mixer(wss); + if (err < 0) return err; #ifdef SNDRV_STB @@ -783,35 +760,47 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev) if (xdma2 >= 0) sprintf(card->longname + strlen(card->longname), "&%d", xdma2); - if ((err = snd_card_register(card)) < 0) + err = snd_card_register(card); + if (err < 0) return err; - iwcard->cs4231 = cs4231; + iwcard->wss = wss; iwcard->gus = gus; return 0; } -static int __init snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr) +static int snd_interwave_isa_probe1(int dev, struct device *devptr) { struct snd_card *card; int err; - card = snd_interwave_card_new(dev); - if (! card) - return -ENOMEM; + err = snd_interwave_card_new(devptr, dev, &card); + if (err < 0) + return err; - snd_card_set_dev(card, &devptr->dev); if ((err = snd_interwave_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; } -static int __init snd_interwave_nonpnp_probe(struct platform_device *pdev) +static int snd_interwave_isa_match(struct device *pdev, + unsigned int dev) +{ + if (!enable[dev]) + return 0; +#ifdef CONFIG_PNP + if (isapnp[dev]) + return 0; +#endif + return 1; +} + +static int snd_interwave_isa_probe(struct device *pdev, + unsigned int dev) { - int dev = pdev->id; int err; static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1}; @@ -836,13 +825,13 @@ static int __init snd_interwave_nonpnp_probe(struct platform_device *pdev) } if (port[dev] != SNDRV_AUTO_PORT) - return snd_interwave_nonpnp_probe1(dev, pdev); + return snd_interwave_isa_probe1(dev, pdev); else { static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260}; int i; for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { port[dev] = possible_ports[i]; - err = snd_interwave_nonpnp_probe1(dev, pdev); + err = snd_interwave_isa_probe1(dev, pdev); if (! err) return 0; } @@ -850,16 +839,16 @@ static int __init snd_interwave_nonpnp_probe(struct platform_device *pdev) } } -static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr) +static int snd_interwave_isa_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); return 0; } -static struct platform_driver snd_interwave_driver = { - .probe = snd_interwave_nonpnp_probe, - .remove = __devexit_p(snd_interwave_nonpnp_remove), +static struct isa_driver snd_interwave_driver = { + .match = snd_interwave_isa_match, + .probe = snd_interwave_isa_probe, + .remove = snd_interwave_isa_remove, /* FIXME: suspend,resume */ .driver = { .name = INTERWAVE_DRIVER @@ -867,9 +856,8 @@ static struct platform_driver snd_interwave_driver = { }; #ifdef CONFIG_PNP - -static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, - const struct pnp_card_device_id *pid) +static int snd_interwave_pnp_detect(struct pnp_card_link *pcard, + const struct pnp_card_device_id *pid) { static int dev; struct snd_card *card; @@ -882,15 +870,14 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, if (dev >= SNDRV_CARDS) return -ENODEV; - card = snd_interwave_card_new(dev); - if (! card) - return -ENOMEM; + res = snd_interwave_card_new(&pcard->card->dev, dev, &card); + if (res < 0) + return res; if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) { snd_card_free(card); return res; } - snd_card_set_dev(card, &pcard->card->dev); if ((res = snd_interwave_probe(card, dev)) < 0) { snd_card_free(card); return res; @@ -900,7 +887,7 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, return 0; } -static void __devexit snd_interwave_pnp_remove(struct pnp_card_link * pcard) +static void snd_interwave_pnp_remove(struct pnp_card_link *pcard) { snd_card_free(pnp_get_card_drvdata(pcard)); pnp_set_card_drvdata(pcard, NULL); @@ -911,70 +898,39 @@ static struct pnp_card_driver interwave_pnpc_driver = { .name = INTERWAVE_PNP_DRIVER, .id_table = snd_interwave_pnpids, .probe = snd_interwave_pnp_detect, - .remove = __devexit_p(snd_interwave_pnp_remove), + .remove = snd_interwave_pnp_remove, /* FIXME: suspend,resume */ }; #endif /* CONFIG_PNP */ -static void __init_or_module snd_interwave_unregister_all(void) -{ - int i; - - if (pnp_registered) - pnp_unregister_card_driver(&interwave_pnpc_driver); - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_interwave_driver); -} - static int __init alsa_card_interwave_init(void) { - int i, err, cards = 0; - - if ((err = platform_driver_register(&snd_interwave_driver)) < 0) - return err; + int err; - for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { - struct platform_device *device; + err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS); #ifdef CONFIG_PNP - if (isapnp[i]) - continue; -#endif - device = platform_device_register_simple(INTERWAVE_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) { - err = PTR_ERR(device); - goto errout; - } - platform_devices[i] = device; - cards++; - } + if (!err) + isa_registered = 1; - /* ISA PnP cards */ - i = pnp_register_card_driver(&interwave_pnpc_driver); - if (i >= 0) { + err = pnp_register_card_driver(&interwave_pnpc_driver); + if (!err) pnp_registered = 1; - cards += i; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "InterWave soundcard not found or device busy\n"); + if (isa_registered) + err = 0; #endif - err = -ENODEV; - goto errout; - } - return 0; - - errout: - snd_interwave_unregister_all(); return err; } static void __exit alsa_card_interwave_exit(void) { - snd_interwave_unregister_all(); +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&interwave_pnpc_driver); + if (isa_registered) +#endif + isa_unregister_driver(&snd_interwave_driver); } module_init(alsa_card_interwave_init) |
