summaryrefslogtreecommitdiffstats
path: root/drivers/sound
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
commit74a9f2e1b4d3ab45a9f72cb5b556c9f521524ab3 (patch)
tree7c4cdb103ab1b388c9852a88bd6fb1e73eba0b5c /drivers/sound
parentee6374c8b0d333c08061c6a97bc77090d7461225 (diff)
Merge with Linux 2.4.3.
Note that mingetty does no longer work with serial console, you have to switch to another getty like getty_ps. This commit also includes a fix for a setitimer bug which did prevent getty_ps from working on older kernels.
Diffstat (limited to 'drivers/sound')
-rw-r--r--drivers/sound/Config.in2
-rw-r--r--drivers/sound/awe_wave.c10
-rw-r--r--drivers/sound/cs46xx.c4
-rw-r--r--drivers/sound/emu10k1/main.c2
-rw-r--r--drivers/sound/es1370.c6
-rw-r--r--drivers/sound/es1371.c6
-rw-r--r--drivers/sound/esssolo1.c14
-rw-r--r--drivers/sound/gus_midi.c2
-rw-r--r--drivers/sound/i810_audio.c492
-rw-r--r--drivers/sound/maestro.c8
-rw-r--r--drivers/sound/maestro3.c47
-rw-r--r--drivers/sound/msnd_pinnacle.c4
-rw-r--r--drivers/sound/opl3sa2.c20
-rw-r--r--drivers/sound/skeleton.c2
-rw-r--r--drivers/sound/sonicvibes.c3
-rw-r--r--drivers/sound/trident.c414
-rw-r--r--drivers/sound/via82cxxx_audio.c43
-rw-r--r--drivers/sound/wavfront.c10
-rw-r--r--drivers/sound/ymfpci.c56
19 files changed, 746 insertions, 399 deletions
diff --git a/drivers/sound/Config.in b/drivers/sound/Config.in
index 6b7de58a7..51fd93356 100644
--- a/drivers/sound/Config.in
+++ b/drivers/sound/Config.in
@@ -6,7 +6,7 @@
# Prompt user for primary drivers.
-dep_tristate ' C-Media PCI (CMI8338/8378)' CONFIG_SOUND_CMPCI $CONFIG_SOUND
+dep_tristate ' C-Media PCI (CMI8338/8378)' CONFIG_SOUND_CMPCI $CONFIG_SOUND $CONFIG_PCI
if [ "$CONFIG_SOUND_CMPCI" = "y" -o "$CONFIG_SOUND_CMPCI" = "m" ]; then
bool ' Enable S/PDIF loop for CMI8738' CONFIG_SOUND_CMPCI_SPDIFLOOP
bool ' Enable 4 channel mode for CMI8738' CONFIG_SOUND_CMPCI_4CH
diff --git a/drivers/sound/awe_wave.c b/drivers/sound/awe_wave.c
index 7e2258624..5f99eb41c 100644
--- a/drivers/sound/awe_wave.c
+++ b/drivers/sound/awe_wave.c
@@ -206,7 +206,7 @@ static awe_chan_info channels[AWE_MAX_CHANNELS];
int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
-static int isapnp = 1;
+static int isapnp = -1;
#else
static int isapnp = 0;
#endif
@@ -4843,10 +4843,12 @@ awe_detect(void)
if (isapnp) {
if (awe_probe_isapnp(&io) < 0) {
printk(KERN_ERR "AWE32: No ISAPnP cards found\n");
- return 0;
+ if (isapnp != -1)
+ return 0;
+ } else {
+ setup_ports(io, 0, 0);
+ return 1;
}
- setup_ports(io, 0, 0);
- return 1;
}
#endif /* isapnp */
diff --git a/drivers/sound/cs46xx.c b/drivers/sound/cs46xx.c
index bc9ba60e1..8a5d6c2d3 100644
--- a/drivers/sound/cs46xx.c
+++ b/drivers/sound/cs46xx.c
@@ -4020,8 +4020,8 @@ static int __init cs_install(struct pci_dev *pci_dev)
}
memset(card, 0, sizeof(*card));
- card->ba0_addr = pci_dev->resource[0].start&PCI_BASE_ADDRESS_MEM_MASK;
- card->ba1_addr = pci_dev->resource[1].start&PCI_BASE_ADDRESS_MEM_MASK;
+ card->ba0_addr = pci_resource_start(pci_dev, 0);
+ card->ba1_addr = pci_resource_start(pci_dev, 1);
card->pci_dev = pci_dev;
card->irq = pci_dev->irq;
card->magic = CS_CARD_MAGIC;
diff --git a/drivers/sound/emu10k1/main.c b/drivers/sound/emu10k1/main.c
index 171b5aa59..f93ceb318 100644
--- a/drivers/sound/emu10k1/main.c
+++ b/drivers/sound/emu10k1/main.c
@@ -619,7 +619,7 @@ static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_dev
}
memset(card, 0, sizeof(struct emu10k1_card));
- if (!pci_dma_supported(pci_dev, EMU10K1_DMA_MASK)) {
+ if (pci_set_dma_mask(pci_dev, EMU10K1_DMA_MASK)) {
printk(KERN_ERR "emu10k1: architecture does not support 32bit PCI busmaster DMA\n");
kfree(card);
return -ENODEV;
diff --git a/drivers/sound/es1370.c b/drivers/sound/es1370.c
index b5f270fb4..7d8ef2457 100644
--- a/drivers/sound/es1370.c
+++ b/drivers/sound/es1370.c
@@ -2524,9 +2524,10 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic
return -1;
if (pcidev->irq == 0)
return -1;
- if (!pci_dma_supported(pcidev, 0xffffffff)) {
+ i = pci_set_dma_mask(pcidev, 0xffffffff);
+ if (i) {
printk(KERN_WARNING "es1370: architecture does not support 32bit PCI busmaster DMA\n");
- return -1;
+ return i;
}
if (!(s = kmalloc(sizeof(struct es1370_state), GFP_KERNEL))) {
printk(KERN_WARNING "es1370: out of memory\n");
@@ -2608,7 +2609,6 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic
set_fs(fs);
/* store it in the driver field */
pci_set_drvdata(pcidev, s);
- pcidev->dma_mask = 0xffffffff;
/* put it into driver list */
list_add_tail(&s->devs, &devs);
/* increment devindex */
diff --git a/drivers/sound/es1371.c b/drivers/sound/es1371.c
index 4abcfe663..ea71063d6 100644
--- a/drivers/sound/es1371.c
+++ b/drivers/sound/es1371.c
@@ -2737,9 +2737,10 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
return -1;
if (pcidev->irq == 0)
return -1;
- if (!pci_dma_supported(pcidev, 0xffffffff)) {
+ i = pci_set_dma_mask(pcidev, 0xffffffff);
+ if (i) {
printk(KERN_WARNING "es1371: architecture does not support 32bit PCI busmaster DMA\n");
- return -1;
+ return i;
}
if (!(s = kmalloc(sizeof(struct es1371_state), GFP_KERNEL))) {
printk(KERN_WARNING PFX "out of memory\n");
@@ -2874,7 +2875,6 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
outl(cssr, s->io+ES1371_REG_STATUS);
/* store it in the driver field */
pci_set_drvdata(pcidev, s);
- pcidev->dma_mask = 0xffffffff;
/* put it into driver list */
list_add_tail(&s->devs, &devs);
/* increment devindex */
diff --git a/drivers/sound/esssolo1.c b/drivers/sound/esssolo1.c
index 2763f6522..e1c650804 100644
--- a/drivers/sound/esssolo1.c
+++ b/drivers/sound/esssolo1.c
@@ -2244,7 +2244,6 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device
{
struct solo1_state *s;
struct pm_dev *pmdev;
- dma_addr_t dma_mask;
if (!RSRCISIOREGION(pcidev, 0) ||
!RSRCISIOREGION(pcidev, 1) ||
@@ -2253,14 +2252,16 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device
return -1;
if (pcidev->irq == 0)
return -1;
- if (pci_dma_supported(pcidev, 0x00ffffff)) {
- dma_mask = 0x00ffffff; /* this enables playback and recording */
- } else if (pci_dma_supported(pcidev, 0xffffffff)) {
- dma_mask = 0xffffffff; /* this enables only playback, as the recording BMDMA can handle only 24bits */
- } else {
+
+ /* Recording requires 24-bit DMA, so attempt to set dma mask
+ * to 24 bits first, then 32 bits (playback only) if that fails.
+ */
+ if (pci_set_dma_mask(pcidev, 0x00ffffff) &&
+ pci_set_dma_mask(pcidev, 0xffffffff)) {
printk(KERN_WARNING "solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n");
return -1;
}
+
if (!(s = kmalloc(sizeof(struct solo1_state), GFP_KERNEL))) {
printk(KERN_WARNING "solo1: out of memory\n");
return -1;
@@ -2318,7 +2319,6 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device
goto err;
/* store it in the driver field */
pci_set_drvdata(pcidev, s);
- pcidev->dma_mask = dma_mask;
/* put it into driver list */
list_add_tail(&s->devs, &devs);
diff --git a/drivers/sound/gus_midi.c b/drivers/sound/gus_midi.c
index 6fb1ac762..542f5fe17 100644
--- a/drivers/sound/gus_midi.c
+++ b/drivers/sound/gus_midi.c
@@ -15,7 +15,7 @@
* Added __init to gus_midi_init()
*/
-#include "linux/init.h"
+#include <linux/init.h>
#include "sound_config.h"
#include "gus.h"
diff --git a/drivers/sound/i810_audio.c b/drivers/sound/i810_audio.c
index 6d447403f..eaed7d132 100644
--- a/drivers/sound/i810_audio.c
+++ b/drivers/sound/i810_audio.c
@@ -194,8 +194,12 @@ enum {
/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
#define NR_AC97 2
+/* Please note that an 8bit mono stream is not valid on this card, you must have a 16bit */
+/* stream at a minimum for this card to be happy */
static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+/* Samples are 16bit values, so we are shifting to a word, not to a byte, hence shift */
+/* values are one less than might be expected */
+static const unsigned sample_shift[] = { -1, 0, 0, 1 };
enum {
ICH82801AA = 0,
@@ -246,7 +250,8 @@ struct i810_state {
unsigned char fmt, enable;
/* hardware channel */
- struct i810_channel *channel;
+ struct i810_channel *read_channel;
+ struct i810_channel *write_channel;
/* OSS buffer management stuff */
void *rawbuf;
@@ -258,7 +263,7 @@ struct i810_state {
/* our buffer acts like a circular ring */
unsigned hwptr; /* where dma last started, updated by update_ptr */
unsigned swptr; /* where driver last clear/filled, updated by read/write */
- int count; /* bytes to be comsumed or been generated by dma machine */
+ int count; /* bytes to be consumed or been generated by dma machine */
unsigned total_bytes; /* total bytes dmaed by hardware */
unsigned error; /* number of over/underruns */
@@ -313,6 +318,7 @@ struct i810_card {
/* Function support */
struct i810_channel *(*alloc_pcm_channel)(struct i810_card *);
struct i810_channel *(*alloc_rec_pcm_channel)(struct i810_card *);
+ struct i810_channel *(*alloc_rec_mic_channel)(struct i810_card *);
void (*free_pcm_channel)(struct i810_card *, int chan);
};
@@ -356,9 +362,6 @@ static struct i810_channel *i810_alloc_pcm_channel(struct i810_card *card)
if(card->channel[1].used==1)
return NULL;
card->channel[1].used=1;
- card->channel[1].offset = 0;
- card->channel[1].port = 0x10;
- card->channel[1].num=1;
return &card->channel[1];
}
@@ -367,12 +370,17 @@ static struct i810_channel *i810_alloc_rec_pcm_channel(struct i810_card *card)
if(card->channel[0].used==1)
return NULL;
card->channel[0].used=1;
- card->channel[0].offset = 0;
- card->channel[0].port = 0x00;
- card->channel[1].num=0;
return &card->channel[0];
}
+static struct i810_channel *i810_alloc_rec_mic_channel(struct i810_card *card)
+{
+ if(card->channel[2].used==1)
+ return NULL;
+ card->channel[2].used=1;
+ return &card->channel[2];
+}
+
static void i810_free_pcm_channel(struct i810_card *card, int channel)
{
card->channel[channel].used=0;
@@ -382,7 +390,7 @@ static void i810_free_pcm_channel(struct i810_card *card, int channel)
static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int rate)
{
struct dmabuf *dmabuf = &state->dmabuf;
- u32 dacp;
+ u32 dacp, new_rate;
struct ac97_codec *codec=state->card->ac97_codec[0];
if(!(state->card->ac97_features&0x0001))
@@ -395,6 +403,7 @@ static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int ra
rate = 48000;
if (rate < 8000)
rate = 8000;
+ dmabuf->rate = rate;
/*
* Adjust for misclocked crap
@@ -402,12 +411,6 @@ static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int ra
rate = ( rate * clocking)/48000;
- /* Analog codecs can go lower via magic registers but others
- might not */
-
- if(rate < 8000)
- rate = 8000;
-
if(rate != i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE))
{
/* Power down the DAC */
@@ -415,24 +418,25 @@ static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int ra
i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0200);
/* Load the rate and read the effective rate */
i810_ac97_set(codec, AC97_PCM_FRONT_DAC_RATE, rate);
- rate=i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE);
+ new_rate=i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE);
/* Power it back up */
i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
+ if(new_rate != rate) {
+ dmabuf->rate = (new_rate * 48000)/clocking;
+ rate = new_rate;
+ }
}
- rate=(rate * 48000) / clocking;
- dmabuf->rate = rate;
#ifdef DEBUG
- printk("i810_audio: called i810_set_dac_rate : rate = %d\n", rate);
+ printk("i810_audio: called i810_set_dac_rate : rate = %d/%d\n", dmabuf->rate, rate);
#endif
-
- return rate;
+ return dmabuf->rate;
}
/* set recording sample rate */
static unsigned int i810_set_adc_rate(struct i810_state * state, unsigned int rate)
{
struct dmabuf *dmabuf = &state->dmabuf;
- u32 dacp;
+ u32 dacp, new_rate;
struct ac97_codec *codec=state->card->ac97_codec[0];
if(!(state->card->ac97_features&0x0001))
@@ -445,6 +449,7 @@ static unsigned int i810_set_adc_rate(struct i810_state * state, unsigned int ra
rate = 48000;
if (rate < 8000)
rate = 8000;
+ dmabuf->rate = rate;
/*
* Adjust for misclocked crap
@@ -452,12 +457,6 @@ static unsigned int i810_set_adc_rate(struct i810_state * state, unsigned int ra
rate = ( rate * clocking)/48000;
- /* Analog codecs can go lower via magic registers but others
- might not */
-
- if(rate < 8000)
- rate = 8000;
-
if(rate != i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE))
{
/* Power down the ADC */
@@ -465,16 +464,18 @@ static unsigned int i810_set_adc_rate(struct i810_state * state, unsigned int ra
i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0100);
/* Load the rate and read the effective rate */
i810_ac97_set(codec, AC97_PCM_LR_DAC_RATE, rate);
- rate=i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE);
+ new_rate=i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE);
/* Power it back up */
i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
+ if(new_rate != rate) {
+ dmabuf->rate = (new_rate * 48000)/clocking;
+ rate = new_rate;
+ }
}
- rate = (rate * 48000) / clocking;
- dmabuf->rate = rate;
#ifdef DEBUG
- printk("i810_audio: called i810_set_adc_rate : rate = %d\n", rate);
+ printk("i810_audio: called i810_set_adc_rate : rate = %d/%d\n", dmabuf->rate, rate);
#endif
- return rate;
+ return dmabuf->rate;
}
/* prepare channel attributes for playback */
@@ -508,10 +509,18 @@ extern __inline__ unsigned i810_get_dma_addr(struct i810_state *state)
{
struct dmabuf *dmabuf = &state->dmabuf;
unsigned int civ, offset;
- struct i810_channel *c = dmabuf->channel;
+ struct i810_channel *c;
if (!dmabuf->enable)
return 0;
+ if (dmabuf->enable & DAC_RUNNING)
+ c = dmabuf->write_channel;
+ else if (dmabuf->enable & ADC_RUNNING)
+ c = dmabuf->read_channel;
+ else {
+ printk("i810_audio: invalid dmabuf->enable state in get_dma_addr\n");
+ return 0;
+ }
do {
civ = inb(state->card->iobase+c->port+OFF_CIV);
offset = (civ + 1) * (dmabuf->dmasize/SG_LEN) -
@@ -523,12 +532,17 @@ extern __inline__ unsigned i810_get_dma_addr(struct i810_state *state)
return offset;
}
-static void resync_dma_ptrs(struct i810_state *state)
+static void resync_dma_ptrs(struct i810_state *state, int rec)
{
struct dmabuf *dmabuf = &state->dmabuf;
- struct i810_channel *c = dmabuf->channel;
+ struct i810_channel *c;
int offset;
-
+
+ if(rec) {
+ c = dmabuf->read_channel;
+ } else {
+ c = dmabuf->write_channel;
+ }
offset = inb(state->card->iobase+c->port+OFF_CIV);
offset *= (dmabuf->dmasize/SG_LEN);
@@ -597,23 +611,20 @@ static void start_dac(struct i810_state *state)
spin_lock_irqsave(&card->lock, flags);
if ((dmabuf->mapped || dmabuf->count > 0) && dmabuf->ready) {
- if(!(dmabuf->enable&DAC_RUNNING))
- {
- dmabuf->enable |= DAC_RUNNING;
- outb((1<<4) | 1<<2 | 1, card->iobase + PO_CR);
- }
+ dmabuf->enable |= DAC_RUNNING;
+ outb((1<<4) | 1<<2 | 1, card->iobase + PO_CR);
}
spin_unlock_irqrestore(&card->lock, flags);
}
-#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
+#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
#define DMABUF_MINORDER 1
/* allocate DMA buffer, playback and recording buffer should be allocated seperately */
static int alloc_dmabuf(struct i810_state *state)
{
struct dmabuf *dmabuf = &state->dmabuf;
- void *rawbuf;
+ void *rawbuf= NULL;
int order;
struct page *page, *pend;
@@ -664,6 +675,7 @@ static void dealloc_dmabuf(struct i810_state *state)
static int prog_dmabuf(struct i810_state *state, unsigned rec)
{
struct dmabuf *dmabuf = &state->dmabuf;
+ struct i810_channel *c;
struct sg_item *sg;
unsigned bytepersec;
unsigned bufsize;
@@ -673,7 +685,7 @@ static int prog_dmabuf(struct i810_state *state, unsigned rec)
int i;
spin_lock_irqsave(&state->card->lock, flags);
- resync_dma_ptrs(state);
+ resync_dma_ptrs(state, rec);
dmabuf->total_bytes = 0;
dmabuf->count = dmabuf->error = 0;
spin_unlock_irqrestore(&state->card->lock, flags);
@@ -684,7 +696,8 @@ static int prog_dmabuf(struct i810_state *state, unsigned rec)
return ret;
/* FIXME: figure out all this OSS fragment stuff */
- bytepersec = dmabuf->rate << sample_shift[dmabuf->fmt];
+ /* sample_shift is for 16 byte samples, add an extra shift for bytes */
+ bytepersec = dmabuf->rate << (sample_shift[dmabuf->fmt] + 1);
bufsize = PAGE_SIZE << dmabuf->buforder;
if (dmabuf->ossfragshift) {
if ((1000 << dmabuf->ossfragshift) < bytepersec)
@@ -709,44 +722,52 @@ static int prog_dmabuf(struct i810_state *state, unsigned rec)
memset(dmabuf->rawbuf, (dmabuf->fmt & I810_FMT_16BIT) ? 0 : 0x80,
dmabuf->dmasize);
- /*
- * Now set up the ring
- */
-
- sg=&dmabuf->channel->sg[0];
fragsize = bufsize / SG_LEN;
-
/*
- * Load up 32 sg entries and take an interrupt at half
- * way (we might want more interrupts later..)
+ * Now set up the ring
*/
+ if(dmabuf->read_channel)
+ c = dmabuf->read_channel;
+ else
+ c = dmabuf->write_channel;
+ while(c != NULL) {
+ sg=&c->sg[0];
+ /*
+ * Load up 32 sg entries and take an interrupt at half
+ * way (we might want more interrupts later..)
+ */
- for(i=0;i<32;i++)
- {
- sg->busaddr=virt_to_bus(dmabuf->rawbuf+fragsize*i);
- sg->control=(fragsize>>1);
- sg->control|=CON_IOC;
- sg++;
- }
+ for(i=0;i<32;i++)
+ {
+ sg->busaddr=virt_to_bus(dmabuf->rawbuf+fragsize*i);
+ sg->control=(fragsize>>sample_shift[dmabuf->fmt]);
+ sg->control|=CON_IOC;
+ sg++;
+ }
+ spin_lock_irqsave(&state->card->lock, flags);
+ outb(2, state->card->iobase+c->port+OFF_CR); /* reset DMA machine */
+ outl(virt_to_bus(&c->sg[0]), state->card->iobase+c->port+OFF_BDBAR);
+ outb(31, state->card->iobase+c->port+OFF_LVI);
+ outb(0, state->card->iobase+c->port+OFF_CIV);
- spin_lock_irqsave(&state->card->lock, flags);
- outb(2, state->card->iobase+dmabuf->channel->port+OFF_CR); /* reset DMA machine */
- outl(virt_to_bus(&dmabuf->channel->sg[0]), state->card->iobase+dmabuf->channel->port+OFF_BDBAR);
- outb(16, state->card->iobase+dmabuf->channel->port+OFF_LVI);
- outb(0, state->card->iobase+dmabuf->channel->port+OFF_CIV);
+ if (c == dmabuf->read_channel) {
+ i810_rec_setup(state);
+ } else {
+ i810_play_setup(state);
+ }
+ spin_unlock_irqrestore(&state->card->lock, flags);
- if (rec) {
- i810_rec_setup(state);
- } else {
- i810_play_setup(state);
+ if(c != dmabuf->write_channel)
+ c = dmabuf->write_channel;
+ else
+ c = NULL;
}
- spin_unlock_irqrestore(&state->card->lock, flags);
-
+
/* set the ready flag for the dma buffer */
dmabuf->ready = 1;
#ifdef DEBUG
- printk("i810_audio: prog_dmabuf, sample rate = %d, format = %d, numfrag = %d, "
+ printk("i810_audio: prog_dmabuf, sample rate = %d, format = %d,\n\tnumfrag = %d, "
"fragsize = %d dmasize = %d\n",
dmabuf->rate, dmabuf->fmt, dmabuf->numfrag,
dmabuf->fragsize, dmabuf->dmasize);
@@ -912,7 +933,6 @@ static void i810_channel_interrupt(struct i810_card *card)
{
int i;
-// printk("CHANNEL IRQ .. ");
for(i=0;i<NR_HW_CH;i++)
{
struct i810_state *state = card->states[i];
@@ -924,38 +944,35 @@ static void i810_channel_interrupt(struct i810_card *card)
continue;
if(!state->dmabuf.ready)
continue;
- c=state->dmabuf.channel;
+ if(state->dmabuf.enable & DAC_RUNNING)
+ c=state->dmabuf.write_channel;
+ else
+ c=state->dmabuf.read_channel;
port+=c->port;
-// printk("PORT %lX (", port);
-
status = inw(port + OFF_SR);
-// printk("ST%d ", status);
-
- if(status & DMA_INT_LVI)
- {
- /* Back to the start */
-// printk("LVI - STOP");
- outb((inb(port+OFF_CIV)-1)&31, port+OFF_LVI);
- i810_update_ptr(state);
- outb(0, port + OFF_CR);
- }
if(status & DMA_INT_COMPLETE)
{
int x;
/* Keep the card chasing its tail */
outb(x=((inb(port+OFF_CIV)-1)&31), port+OFF_LVI);
i810_update_ptr(state);
-// printk("COMP%d ",x);
}
-// printk(")");
+ if(status & DMA_INT_LVI)
+ {
+ /* Back to the start */
+ i810_update_ptr(state);
+ outb(0, port + OFF_CR);
+ }
outw(status & DMA_INT_MASK, port + OFF_SR);
}
-// printk("\n");
}
+static u32 jiff = 0;
+static u32 jiff_count = 0;
+
static void i810_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct i810_card *card = (struct i810_card *)dev_id;
@@ -964,13 +981,13 @@ static void i810_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_lock(&card->lock);
status = inl(card->iobase + GLOB_STA);
+
if(!(status & INT_MASK))
{
spin_unlock(&card->lock);
return; /* not for us */
}
-// printk("Interrupt %X: ", status);
if(status & (INT_PO|INT_PI|INT_MC))
i810_channel_interrupt(card);
@@ -1003,6 +1020,15 @@ static ssize_t i810_read(struct file *file, char *buffer, size_t count, loff_t *
return -ESPIPE;
if (dmabuf->mapped)
return -ENXIO;
+ if (dmabuf->enable & DAC_RUNNING)
+ return -ENODEV;
+ if (!dmabuf->read_channel) {
+ dmabuf->ready = 0;
+ dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card);
+ if (!dmabuf->read_channel) {
+ return -ENODEV;
+ }
+ }
if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
return ret;
if (!access_ok(VERIFY_WRITE, buffer, count))
@@ -1100,6 +1126,14 @@ static ssize_t i810_write(struct file *file, const char *buffer, size_t count, l
return -ESPIPE;
if (dmabuf->mapped)
return -ENXIO;
+ if (dmabuf->enable & ADC_RUNNING)
+ return -ENODEV;
+ if (!dmabuf->write_channel) {
+ dmabuf->ready = 0;
+ dmabuf->write_channel = state->card->alloc_pcm_channel(state->card);
+ if(!dmabuf->write_channel)
+ return -ENODEV;
+ }
if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
return ret;
if (!access_ok(VERIFY_READ, buffer, count))
@@ -1132,8 +1166,8 @@ static ssize_t i810_write(struct file *file, const char *buffer, size_t count, l
return ret;
}
/* Not strictly correct but works */
- tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
- tmo >>= sample_shift[dmabuf->fmt];
+ tmo = dmabuf->rate << (sample_shift[dmabuf->fmt] + 1);
+ tmo = dmabuf->dmasize * HZ / tmo;
/* There are two situations when sleep_on_timeout returns, one is when
the interrupt is serviced correctly and the process is waked up by
ISR ON TIME. Another is when timeout is expired, which means that
@@ -1187,22 +1221,27 @@ static unsigned int i810_poll(struct file *file, struct poll_table_struct *wait)
unsigned int mask = 0;
if (file->f_mode & FMODE_WRITE) {
+ if (!dmabuf->write_channel)
+ return 0;
if (!dmabuf->ready && prog_dmabuf(state, 0))
return 0;
poll_wait(file, &dmabuf->wait, wait);
- }
- if (file->f_mode & FMODE_READ) {
+ } else {
+ // don't do both read and write paths or we won't get woke up properly
+ // when we have a file with both permissions
+ if (!dmabuf->read_channel)
+ return 0;
if (!dmabuf->ready && prog_dmabuf(state, 1))
return 0;
poll_wait(file, &dmabuf->wait, wait);
}
spin_lock_irqsave(&state->card->lock, flags);
i810_update_ptr(state);
- if (file->f_mode & FMODE_READ) {
+ if (file->f_mode & FMODE_READ && dmabuf->enable & ADC_RUNNING) {
if (dmabuf->count >= (signed)dmabuf->fragsize)
mask |= POLLIN | POLLRDNORM;
}
- if (file->f_mode & FMODE_WRITE) {
+ if (file->f_mode & FMODE_WRITE && dmabuf->enable & DAC_RUNNING) {
if (dmabuf->mapped) {
if (dmabuf->count >= (signed)dmabuf->fragsize)
mask |= POLLOUT | POLLWRNORM;
@@ -1223,11 +1262,19 @@ static int i810_mmap(struct file *file, struct vm_area_struct *vma)
int ret = -EINVAL;
unsigned long size;
+ /*
+ * Until we figure out a few problems
+ */
+
lock_kernel();
if (vma->vm_flags & VM_WRITE) {
+ if (!dmabuf->write_channel && (dmabuf->write_channel = state->card->alloc_pcm_channel(state->card)) == NULL)
+ goto out;
if ((ret = prog_dmabuf(state, 0)) != 0)
goto out;
} else if (vma->vm_flags & VM_READ) {
+ if (!dmabuf->read_channel && (dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card)) == NULL)
+ goto out;
if ((ret = prog_dmabuf(state, 1)) != 0)
goto out;
} else
@@ -1245,6 +1292,9 @@ static int i810_mmap(struct file *file, struct vm_area_struct *vma)
goto out;
dmabuf->mapped = 1;
ret = 0;
+#ifdef DEBUG
+ printk("i810_audio: mmap'ed %d bytes of data space\n", size);
+#endif
out:
unlock_kernel();
return ret;
@@ -1277,14 +1327,14 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
stop_dac(state);
synchronize_irq();
dmabuf->ready = 0;
- resync_dma_ptrs(state);
+ resync_dma_ptrs(state, 0);
dmabuf->swptr = dmabuf->hwptr = 0;
dmabuf->count = dmabuf->total_bytes = 0;
}
if (file->f_mode & FMODE_READ) {
stop_adc(state);
synchronize_irq();
- resync_dma_ptrs(state);
+ resync_dma_ptrs(state, 1);
dmabuf->ready = 0;
dmabuf->swptr = dmabuf->hwptr = 0;
dmabuf->count = dmabuf->total_bytes = 0;
@@ -1325,23 +1375,23 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (file->f_mode & FMODE_WRITE) {
stop_dac(state);
dmabuf->ready = 0;
- dmabuf->fmt = I810_FMT_STEREO;
+ dmabuf->fmt |= I810_FMT_STEREO;
}
if (file->f_mode & FMODE_READ) {
stop_adc(state);
dmabuf->ready = 0;
- dmabuf->fmt = I810_FMT_STEREO;
+ dmabuf->fmt |= I810_FMT_STEREO;
}
return 0;
case SNDCTL_DSP_GETBLKSIZE:
if (file->f_mode & FMODE_WRITE) {
- if ((val = prog_dmabuf(state, 0)))
+ if (!dmabuf->ready && (val = prog_dmabuf(state, 0)))
return val;
return put_user(dmabuf->fragsize, (int *)arg);
}
if (file->f_mode & FMODE_READ) {
- if ((val = prog_dmabuf(state, 1)))
+ if (!dmabuf->ready && (val = prog_dmabuf(state, 1)))
return val;
return put_user(dmabuf->fragsize, (int *)arg);
}
@@ -1356,10 +1406,12 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (file->f_mode & FMODE_WRITE) {
stop_dac(state);
dmabuf->ready = 0;
+ dmabuf->fmt |= I810_FMT_16BIT;
}
if (file->f_mode & FMODE_READ) {
stop_adc(state);
dmabuf->ready = 0;
+ dmabuf->fmt |= I810_FMT_16BIT;
}
}
return put_user(AFMT_S16_LE, (int *)arg);
@@ -1391,6 +1443,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
dmabuf->subdivision = val;
+ dmabuf->ready = 0;
return 0;
case SNDCTL_DSP_SETFRAGMENT:
@@ -1405,13 +1458,14 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
dmabuf->ossfragshift = 15;
if (dmabuf->ossmaxfrags < 4)
dmabuf->ossmaxfrags = 4;
+ dmabuf->ready = 0;
return 0;
case SNDCTL_DSP_GETOSPACE:
if (!(file->f_mode & FMODE_WRITE))
return -EINVAL;
- if (!dmabuf->enable && (val = prog_dmabuf(state, 0)) != 0)
+ if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
return val;
spin_lock_irqsave(&state->card->lock, flags);
i810_update_ptr(state);
@@ -1425,7 +1479,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
return -EINVAL;
- if (!dmabuf->enable && (val = prog_dmabuf(state, 1)) != 0)
+ if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
return val;
spin_lock_irqsave(&state->card->lock, flags);
i810_update_ptr(state);
@@ -1446,30 +1500,40 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case SNDCTL_DSP_GETTRIGGER:
val = 0;
- if (file->f_mode & FMODE_READ && dmabuf->enable)
+ if (file->f_mode & FMODE_READ && dmabuf->enable & ADC_RUNNING)
val |= PCM_ENABLE_INPUT;
- if (file->f_mode & FMODE_WRITE && dmabuf->enable)
+ if (file->f_mode & FMODE_WRITE && dmabuf->enable & DAC_RUNNING)
val |= PCM_ENABLE_OUTPUT;
return put_user(val, (int *)arg);
case SNDCTL_DSP_SETTRIGGER:
if (get_user(val, (int *)arg))
return -EFAULT;
- if (file->f_mode & FMODE_READ) {
- if (val & PCM_ENABLE_INPUT) {
- if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
- return ret;
- start_adc(state);
- } else
- stop_adc(state);
+ if (file->f_mode & FMODE_READ && val & PCM_ENABLE_INPUT) {
+ if (dmabuf->enable & DAC_RUNNING)
+ return -ENODEV;
+ if (!dmabuf->read_channel) {
+ dmabuf->ready = 0;
+ dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card);
+ if (!dmabuf->read_channel)
+ return -ENODEV;
+ }
+ if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
+ return ret;
+ start_adc(state);
}
- if (file->f_mode & FMODE_WRITE) {
- if (val & PCM_ENABLE_OUTPUT) {
- if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
- return ret;
- start_dac(state);
- } else
- stop_dac(state);
+ if (file->f_mode & FMODE_WRITE && val & PCM_ENABLE_OUTPUT) {
+ if (dmabuf->enable & ADC_RUNNING)
+ return -ENODEV;
+ if (!dmabuf->write_channel) {
+ dmabuf->ready = 0;
+ dmabuf->write_channel = state->card->alloc_pcm_channel(state->card);
+ if (!dmabuf->write_channel)
+ return -ENODEV;
+ }
+ if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
+ return ret;
+ start_dac(state);
}
return 0;
@@ -1558,18 +1622,6 @@ static int i810_open(struct inode *inode, struct file *file)
return -ENODEV;
found_virt:
- /* found a free virtual channel, allocate hardware channels */
- if(file->f_mode & FMODE_READ)
- dmabuf->channel = card->alloc_rec_pcm_channel(card);
- else
- dmabuf->channel = card->alloc_pcm_channel(card);
-
- if (dmabuf->channel == NULL) {
- kfree (card->states[i]);
- card->states[i] = NULL;;
- return -ENODEV;
- }
-
/* initialize the virtual channel */
state->virt = i;
state->card = card;
@@ -1578,28 +1630,34 @@ static int i810_open(struct inode *inode, struct file *file)
init_MUTEX(&state->open_sem);
file->private_data = state;
+ /* allocate hardware channels */
+ if(file->f_mode & FMODE_READ) {
+ if((dmabuf->read_channel = card->alloc_rec_pcm_channel(card)) == NULL) {
+ kfree (card->states[i]);
+ card->states[i] = NULL;;
+ return -ENODEV;
+ }
+ i810_set_adc_rate(state, 48000);
+ }
+ if(file->f_mode & FMODE_WRITE) {
+ if((dmabuf->write_channel = card->alloc_pcm_channel(card)) == NULL) {
+ kfree (card->states[i]);
+ card->states[i] = NULL;;
+ return -ENODEV;
+ }
+ i810_set_dac_rate(state, 48000);
+ }
+
down(&state->open_sem);
/* set default sample format. According to OSS Programmer's Guide /dev/dsp
should be default to unsigned 8-bits, mono, with sample rate 8kHz and
/dev/dspW will accept 16-bits sample */
- if (file->f_mode & FMODE_WRITE) {
- dmabuf->fmt &= ~I810_FMT_MASK;
- dmabuf->fmt |= I810_FMT_16BIT;
- dmabuf->ossfragshift = 0;
- dmabuf->ossmaxfrags = 0;
- dmabuf->subdivision = 0;
- i810_set_dac_rate(state, 48000);
- }
-
- if (file->f_mode & FMODE_READ) {
- dmabuf->fmt &= ~I810_FMT_MASK;
- dmabuf->fmt |= I810_FMT_16BIT;
- dmabuf->ossfragshift = 0;
- dmabuf->ossmaxfrags = 0;
- dmabuf->subdivision = 0;
- i810_set_adc_rate(state, 48000);
- }
+ dmabuf->fmt &= ~I810_FMT_MASK;
+ dmabuf->fmt |= I810_FMT_16BIT;
+ dmabuf->ossfragshift = 0;
+ dmabuf->ossmaxfrags = 0;
+ dmabuf->subdivision = 0;
state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&state->open_sem);
@@ -1614,29 +1672,33 @@ static int i810_release(struct inode *inode, struct file *file)
lock_kernel();
if (file->f_mode & FMODE_WRITE) {
- i810_clear_tail(state);
- drain_dac(state, file->f_flags & O_NONBLOCK);
}
/* stop DMA state machine and free DMA buffers/channels */
down(&state->open_sem);
- if (file->f_mode & FMODE_WRITE) {
+ if (dmabuf->enable & DAC_RUNNING) {
+ i810_clear_tail(state);
+ drain_dac(state, file->f_flags & O_NONBLOCK);
stop_dac(state);
dealloc_dmabuf(state);
- state->card->free_pcm_channel(state->card, dmabuf->channel->num);
}
- if (file->f_mode & FMODE_READ) {
+ if(dmabuf->enable & ADC_RUNNING) {
stop_adc(state);
dealloc_dmabuf(state);
- state->card->free_pcm_channel(state->card, dmabuf->channel->num);
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ state->card->free_pcm_channel(state->card, dmabuf->write_channel->num);
+ }
+ if (file->f_mode & FMODE_READ) {
+ state->card->free_pcm_channel(state->card, dmabuf->read_channel->num);
}
/* we're covered by the open_sem */
up(&state->open_sem);
- kfree(state->card->states[state->virt]);
state->card->states[state->virt] = NULL;
+ kfree(state);
unlock_kernel();
return 0;
@@ -1688,16 +1750,11 @@ static int i810_open_mixdev(struct inode *inode, struct file *file)
for (card = devs; card != NULL; card = card->next)
for (i = 0; i < NR_AC97; i++)
if (card->ac97_codec[i] != NULL &&
- card->ac97_codec[i]->dev_mixer == minor)
- goto match;
-
- if (!card)
- return -ENODEV;
-
- match:
- file->private_data = card->ac97_codec[i];
-
- return 0;
+ card->ac97_codec[i]->dev_mixer == minor) {
+ file->private_data = card->ac97_codec[i];
+ return 0;
+ }
+ return -ENODEV;
}
static int i810_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
@@ -1788,10 +1845,6 @@ static int __init i810_ac97_init(struct i810_card *card)
printk(KERN_WARNING "i810_audio: only 48Khz playback available.\n");
else
{
- /* Enable variable rate mode */
- i810_ac97_set(codec, AC97_EXTENDED_STATUS, 9);
- i810_ac97_set(codec,AC97_EXTENDED_STATUS,
- i810_ac97_get(codec, AC97_EXTENDED_STATUS)|0xE800);
/* power up everything, modify this when implementing power saving */
i810_ac97_set(codec, AC97_POWER_CONTROL,
i810_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00);
@@ -1804,6 +1857,11 @@ static int __init i810_ac97_init(struct i810_card *card)
schedule_timeout(HZ/20);
}
+ /* Enable variable rate mode */
+ i810_ac97_set(codec, AC97_EXTENDED_STATUS, 9);
+ i810_ac97_set(codec,AC97_EXTENDED_STATUS,
+ i810_ac97_get(codec, AC97_EXTENDED_STATUS)|0xE800);
+
if(!(i810_ac97_get(codec, AC97_EXTENDED_STATUS)&1))
{
printk(KERN_WARNING "i810_audio: Codec refused to allow VRA, using 48Khz only.\n");
@@ -1833,14 +1891,15 @@ static int __init i810_probe(struct pci_dev *pci_dev, const struct pci_device_id
{
struct i810_card *card;
- if (!pci_dma_supported(pci_dev, I810_DMA_MASK)) {
+ if (pci_enable_device(pci_dev))
+ return -EIO;
+
+ if (pci_set_dma_mask(pci_dev, I810_DMA_MASK)) {
printk(KERN_ERR "intel810: architecture does not support"
" 32bit PCI busmaster DMA\n");
return -ENODEV;
}
- if (pci_enable_device(pci_dev))
- return -EIO;
if ((card = kmalloc(sizeof(struct i810_card), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "i810_audio: out of memory\n");
return -ENOMEM;
@@ -1865,7 +1924,17 @@ static int __init i810_probe(struct pci_dev *pci_dev, const struct pci_device_id
card->alloc_pcm_channel = i810_alloc_pcm_channel;
card->alloc_rec_pcm_channel = i810_alloc_rec_pcm_channel;
+ card->alloc_rec_mic_channel = i810_alloc_rec_mic_channel;
card->free_pcm_channel = i810_free_pcm_channel;
+ card->channel[0].offset = 0;
+ card->channel[0].port = 0x00;
+ card->channel[0].num=0;
+ card->channel[1].offset = 0;
+ card->channel[1].port = 0x10;
+ card->channel[1].num=1;
+ card->channel[2].offset = 0;
+ card->channel[2].port = 0x20;
+ card->channel[2].num=2;
/* claim our iospace and irq */
request_region(card->iobase, 64, card_names[pci_id->driver_data]);
@@ -1900,7 +1969,6 @@ static int __init i810_probe(struct pci_dev *pci_dev, const struct pci_device_id
return -ENODEV;
}
pci_dev->driver_data = card;
- pci_dev->dma_mask = I810_DMA_MASK;
return 0;
}
@@ -1938,14 +2006,74 @@ static struct pci_driver i810_pci_driver = {
remove: i810_remove,
};
+static void __init i810_configure_clocking (void)
+{
+ struct i810_card *card;
+ struct i810_state *state;
+ struct dmabuf *dmabuf;
+ unsigned int i, offset, new_offset;
+ unsigned long flags;
+
+ card = devs;
+ /* We could try to set the clocking for multiple cards, but can you even have
+ * more than one i810 in a machine? Besides, clocking is global, so unless
+ * someone actually thinks more than one i810 in a machine is possible and
+ * decides to rewrite that little bit, setting the rate for more than one card
+ * is a waste of time.
+ */
+ if(card != NULL) {
+ state = card->states[0] = (struct i810_state *)
+ kmalloc(sizeof(struct i810_state), GFP_KERNEL);
+ if (state == NULL)
+ return;
+ memset(state, 0, sizeof(struct i810_state));
+ dmabuf = &state->dmabuf;
+
+ dmabuf->write_channel = card->alloc_pcm_channel(card);
+ state->virt = 0;
+ state->card = card;
+ state->magic = I810_STATE_MAGIC;
+ init_waitqueue_head(&dmabuf->wait);
+ init_MUTEX(&state->open_sem);
+ dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
+ i810_set_dac_rate(state, 48000);
+ if(prog_dmabuf(state, 0) != 0) {
+ goto config_out_nodmabuf;
+ }
+ if(dmabuf->dmasize < 16384) {
+ goto config_out;
+ }
+ dmabuf->count = dmabuf->dmasize;
+ save_flags(flags);
+ cli();
+ start_dac(state);
+ offset = i810_get_dma_addr(state);
+ mdelay(50);
+ new_offset = i810_get_dma_addr(state);
+ stop_dac(state);
+ outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
+ restore_flags(flags);
+ i = new_offset - offset;
+ printk("i810_audio: %d bytes in 50 milliseconds\n", i);
+ i = i / 4 * 20;
+ if (i > 48500 || i < 47500) {
+ clocking = clocking * clocking / i;
+ printk("i810_audio: setting clocking to %d to compensate\n", clocking);
+ }
+config_out_nodmabuf:
+ dealloc_dmabuf(state);
+config_out:
+ state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num);
+ kfree(state);
+ card->states[0] = NULL;
+ }
+}
+
static int __init i810_init_module (void)
{
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- if(ftsodell==1)
- clocking=41194;
-
printk(KERN_INFO "Intel 810 + AC97 Audio, version "
DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
@@ -1953,6 +2081,12 @@ static int __init i810_init_module (void)
pci_unregister_driver(&i810_pci_driver);
return -ENODEV;
}
+ if(ftsodell != 0) {
+ printk("i810_audio: ftsodell is now a deprecated option.\n");
+ }
+ if(clocking == 48000) {
+ i810_configure_clocking();
+ }
return 0;
}
diff --git a/drivers/sound/maestro.c b/drivers/sound/maestro.c
index 32d55cb76..5552d5f80 100644
--- a/drivers/sound/maestro.c
+++ b/drivers/sound/maestro.c
@@ -1427,7 +1427,7 @@ ess_play_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size
apu_set_register(ess, channel, 10, 0x8F08);
}
- /* clear WP interupts */
+ /* clear WP interrupts */
outw(1, ess->card->iobase+0x04);
/* enable WP ints */
outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18);
@@ -1559,7 +1559,7 @@ ess_rec_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size)
apu_set_register(ess, channel, 11, route);
}
- /* clear WP interupts */
+ /* clear WP interrupts */
outw(1, ess->card->iobase+0x04);
/* enable WP ints */
outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18);
@@ -3446,10 +3446,10 @@ maestro_install(struct pci_dev *pcidev, int card_type)
printk(KERN_INFO "maestro: not attempting power management.\n");
else {
if(!parse_power(card,pcidev))
- printk(KERN_INFO "maestro: no PCI power managment interface found.\n");
+ printk(KERN_INFO "maestro: no PCI power management interface found.\n");
else {
pci_read_config_dword(pcidev, card->power_regs, &n);
- printk(KERN_INFO "maestro: PCI power managment capability: 0x%x\n",n>>16);
+ printk(KERN_INFO "maestro: PCI power management capability: 0x%x\n",n>>16);
}
}
diff --git a/drivers/sound/maestro3.c b/drivers/sound/maestro3.c
index b1d409ece..428629bcf 100644
--- a/drivers/sound/maestro3.c
+++ b/drivers/sound/maestro3.c
@@ -28,6 +28,9 @@
* Shouts go out to Mike "DJ XPCom" Ang.
*
* History
+ * v1.22 - Feb 28 2001 - Zach Brown <zab@zabbo.net>
+ * allocate mem at insmod/setup, rather than open
+ * limit pci dma addresses to 28bit, thanks guys.
* v1.21 - Feb 04 2001 - Zach Brown <zab@zabbo.net>
* fix up really dumb notifier -> suspend oops
* v1.20 - Jan 30 2001 - Zach Brown <zab@zabbo.net>
@@ -150,7 +153,7 @@
#define M_DEBUG 1
-#define DRIVER_VERSION "1.21"
+#define DRIVER_VERSION "1.22"
#define M3_MODULE_NAME "maestro3"
#define PFX M3_MODULE_NAME ": "
@@ -330,6 +333,12 @@ static struct pci_device_id m3_id_table[] __initdata = {
MODULE_DEVICE_TABLE (pci, m3_id_table);
+/*
+ * reports seem to indicate that the m3 is limited
+ * to 28bit bus addresses. aaaargggh...
+ */
+#define M3_PCI_DMA_MASK 0x0fffffff
+
static unsigned
ld2(unsigned int x)
{
@@ -1943,6 +1952,9 @@ nuke_lists(struct m3_card *card, struct dmabuf *db)
static void
free_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db)
{
+ if(db->rawbuf == NULL)
+ return;
+
DPRINTK(DPSTR,"freeing %p from dmabuf %p\n",db->rawbuf, db);
{
@@ -1967,7 +1979,7 @@ static int m3_open(struct inode *inode, struct file *file)
int minor = MINOR(inode->i_rdev);
struct m3_card *c;
struct m3_state *s = NULL;
- int i, ret = 0;
+ int i;
unsigned char fmtm = ~0, fmts = 0;
unsigned long flags;
@@ -2013,10 +2025,6 @@ static int m3_open(struct inode *inode, struct file *file)
spin_lock_irqsave(&s->lock, flags);
if (file->f_mode & FMODE_READ) {
- if(allocate_dmabuf(s->card->pcidev, &(s->dma_adc))) {
- ret = -ENOMEM;
- goto out;
- }
fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT);
if ((minor & 0xf) == SND_DEV_DSP16)
fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
@@ -2025,10 +2033,6 @@ static int m3_open(struct inode *inode, struct file *file)
set_adc_rate(s, 8000);
}
if (file->f_mode & FMODE_WRITE) {
- if(allocate_dmabuf(s->card->pcidev, &(s->dma_dac))) {
- ret = -ENOMEM;
- goto out;
- }
fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT);
if ((minor & 0xf) == SND_DEV_DSP16)
fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
@@ -2040,7 +2044,6 @@ static int m3_open(struct inode *inode, struct file *file)
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
MOD_INC_USE_COUNT;
-out:
up(&s->open_sem);
spin_unlock_irqrestore(&s->lock, flags);
return 0;
@@ -2064,7 +2067,6 @@ static int m3_release(struct inode *inode, struct file *file)
m3_remove_list(s->card, &(s->card->mixer_list), s->dma_dac.mixer_index);
nuke_lists(s->card, &(s->dma_dac));
}
- free_dmabuf(s->card->pcidev, &(s->dma_dac));
}
if (file->f_mode & FMODE_READ) {
stop_adc(s);
@@ -2072,7 +2074,6 @@ static int m3_release(struct inode *inode, struct file *file)
m3_remove_list(s->card, &(s->card->adc1_list), s->dma_adc.adc1_index);
nuke_lists(s->card, &(s->dma_adc));
}
- free_dmabuf(s->card->pcidev, &(s->dma_adc));
}
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
@@ -2594,8 +2595,8 @@ static int __init m3_probe(struct pci_dev *pci_dev, const struct pci_device_id *
DPRINTK(DPMOD, "in maestro_install\n");
- if (!pci_dma_supported(pci_dev, 0xffffffff)) {
- printk(KERN_ERR PFX "architecture does not support 32bit PCI busmaster DMA\n");
+ if (!pci_dma_supported(pci_dev, M3_PCI_DMA_MASK)) {
+ printk(KERN_ERR PFX "architecture does not support limiting to 28bit PCI bus addresses\n");
return -ENODEV;
}
@@ -2604,6 +2605,8 @@ static int __init m3_probe(struct pci_dev *pci_dev, const struct pci_device_id *
pci_set_master(pci_dev);
+ pci_dev->dma_mask = M3_PCI_DMA_MASK;
+
if( (card = kmalloc(sizeof(struct m3_card), GFP_KERNEL)) == NULL) {
printk(KERN_WARNING PFX "out of memory\n");
return -ENOMEM;
@@ -2681,6 +2684,12 @@ static int __init m3_probe(struct pci_dev *pci_dev, const struct pci_device_id *
if ((s->dev_audio = register_sound_dsp(&m3_audio_fops, -1)) < 0) {
break;
}
+
+ if( allocate_dmabuf(card->pcidev, &(s->dma_adc)) ||
+ allocate_dmabuf(card->pcidev, &(s->dma_dac))) {
+ ret = -ENOMEM;
+ goto out;
+ }
}
if(request_irq(card->irq, m3_interrupt, SA_SHIRQ, card_names[card->card_type], card)) {
@@ -2734,8 +2743,12 @@ static void m3_remove(struct pci_dev *pci_dev)
for(i=0;i<NR_DSPS;i++)
{
struct m3_state *s = &card->channels[i];
- if(s->dev_audio != -1)
- unregister_sound_dsp(s->dev_audio);
+ if(s->dev_audio < 0)
+ continue;
+
+ unregister_sound_dsp(s->dev_audio);
+ free_dmabuf(card->pcidev, &s->dma_adc);
+ free_dmabuf(card->pcidev, &s->dma_dac);
}
release_region(card->iobase, 256);
diff --git a/drivers/sound/msnd_pinnacle.c b/drivers/sound/msnd_pinnacle.c
index f9914634e..b8ca09e71 100644
--- a/drivers/sound/msnd_pinnacle.c
+++ b/drivers/sound/msnd_pinnacle.c
@@ -47,7 +47,9 @@
#include "sound_config.h"
#include "sound_firmware.h"
#ifdef MSND_CLASSIC
+# ifndef __alpha__
# define SLOWIO
+# endif
#endif
#include "msnd.h"
#ifdef MSND_CLASSIC
@@ -1403,7 +1405,6 @@ static int __init attach_multisound(void)
return 0;
}
-#ifdef MODULE
static void __exit unload_multisound(void)
{
release_region(dev.io, dev.numio);
@@ -1412,7 +1413,6 @@ static void __exit unload_multisound(void)
unregister_sound_dsp(dev.dsp_minor);
msnd_unregister(&dev);
}
-#endif
#ifndef MSND_CLASSIC
diff --git a/drivers/sound/opl3sa2.c b/drivers/sound/opl3sa2.c
index 137afd90d..7f2b0d347 100644
--- a/drivers/sound/opl3sa2.c
+++ b/drivers/sound/opl3sa2.c
@@ -806,6 +806,16 @@ static void __exit unload_opl3sa2(struct address_info* hw_config, int card)
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+
+struct isapnp_device_id isapnp_opl3sa2_list[] __initdata = {
+ { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+ ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021),
+ NULL },
+ {0}
+};
+
+MODULE_DEVICE_TABLE(isapnp, isapnp_opl3sa2_list);
+
static int __init opl3sa2_isapnp_probe(struct address_info* hw_cfg,
struct address_info* mss_cfg,
struct address_info* mpu_cfg,
@@ -908,13 +918,17 @@ static int __init init_opl3sa2(void)
&cfg_mpu[card],
card) < 0) {
if(!opl3sa2_cards_num)
- printk(KERN_NOTICE "opl3sa2: No cards found\n");
- break;
+ printk(KERN_INFO "opl3sa2: No PnP cards found\n");
+ if(io == -1)
+ break;
+ isapnp=0;
+ printk(KERN_INFO "opl3sa2: Search for a card at 0x%d.\n", io);
+ /* Fall through */
}
#endif
/* If a user wants an I/O then assume they meant it */
- if(!isapnp && io == -1 ) {
+ if(!isapnp) {
if(io == -1 || irq == -1 || dma == -1 ||
dma2 == -1 || mss_io == -1) {
printk(KERN_ERR
diff --git a/drivers/sound/skeleton.c b/drivers/sound/skeleton.c
index 9d5d4ac22..c42c4438b 100644
--- a/drivers/sound/skeleton.c
+++ b/drivers/sound/skeleton.c
@@ -4,7 +4,7 @@
* (c) 1998 Red Hat Software
*
* This software may be used and distributed according to the
- * terms of the GNU Public License, incorporated herein by
+ * terms of the GNU General Public License, incorporated herein by
* reference.
*
* This example is designed to be built in the linux/drivers/sound
diff --git a/drivers/sound/sonicvibes.c b/drivers/sound/sonicvibes.c
index d0c37ba0a..7c71168bd 100644
--- a/drivers/sound/sonicvibes.c
+++ b/drivers/sound/sonicvibes.c
@@ -2478,7 +2478,7 @@ static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id
return -1;
if (pcidev->irq == 0)
return -1;
- if (!pci_dma_supported(pcidev, 0x00ffffff)) {
+ if (pci_set_dma_mask(pcidev, 0x00ffffff)) {
printk(KERN_WARNING "sonicvibes: architecture does not support 24bit PCI busmaster DMA\n");
return -1;
}
@@ -2602,7 +2602,6 @@ static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id
set_fs(fs);
/* store it in the driver field */
pci_set_drvdata(pcidev, s);
- pcidev->dma_mask = 0x00ffffff;
/* put it into driver list */
list_add_tail(&s->devs, &devs);
/* increment devindex */
diff --git a/drivers/sound/trident.c b/drivers/sound/trident.c
index 0a8192439..07d2c7e08 100644
--- a/drivers/sound/trident.c
+++ b/drivers/sound/trident.c
@@ -13,6 +13,7 @@
* Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Ollie Lho <ollie@sis.com.tw> SiS 7018 Audio Core Support
* Ching-Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support
+ * Matt Wu <mattwu@acersoftech.com.cn> ALi 5451 Audio Core Support
*
*
* This program is free software; you can redistribute it and/or modify
@@ -30,6 +31,12 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* History
+ * v0.14.7
+ * Feb 06 2001 Matt Wu
+ * Fix ac97 initialization
+ * Fix bug: an extra tail will be played when playing
+ * Jan 05 2001 Matt Wu
+ * Implement multi-channels and S/PDIF in support for ALi 1535+
* v0.14.6
* Nov 1 2000 Ching-Ling Lee
* Fix the bug of memory leak when swithing 5.1-channels to 2 channels.
@@ -140,12 +147,12 @@
/* maxinum nuber of AC97 codecs connected, AC97 2.0 defined 4, but 7018 and 4D-NX only
have 2 SDATA_IN lines (currently) */
-#define NR_AC97 2
+#define NR_AC97 2
/* minor number of /dev/swmodem (temporary, experimental) */
#define SND_DEV_SWMODEM 7
-static const unsigned ali_multi_channels_5_1[] = { ALI_CENTER_CHANNEL, ALI_LEF_CHANNEL, ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL};
+static const unsigned ali_multi_channels_5_1[] = { /*ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL,*/ ALI_CENTER_CHANNEL, ALI_LEF_CHANNEL, ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL};
static const unsigned sample_size[] = { 1, 2, 2, 4 };
static const unsigned sample_shift[] = { 0, 1, 1, 2 };
@@ -312,6 +319,10 @@ struct trident_card {
struct trident_channel *(*alloc_rec_pcm_channel)(struct trident_card *);
void (*free_pcm_channel)(struct trident_card *, unsigned int chan);
void (*address_interrupt)(struct trident_card *);
+
+ /* Add by Matt Wu 01-05-2001 for spdif in */
+ int multi_channel_use_count;
+ int rec_channel_use_count;
};
/* table to map from CHANNELMASK to channel attribute for SiS 7018 */
@@ -327,6 +338,11 @@ static int attr2mask [] = {
DSP_BIND_I2S, DSP_BIND_CENTER_LFE, DSP_BIND_SURR, DSP_BIND_SPDIF
};
+/* Add by Matt Wu 01-05-2001 for spdif in */
+static int ali_close_multi_channels(void);
+static void ali_delay(struct trident_card *card,int interval);
+static void ali_detect_spdif_rate(struct trident_card *card);
+
static struct trident_card *devs;
static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val);
@@ -760,6 +776,8 @@ static void trident_play_setup(struct trident_state *state)
static void trident_rec_setup(struct trident_state *state)
{
u16 w;
+ u8 bval;
+
struct trident_card *card = state->card;
struct dmabuf *dmabuf = &state->dmabuf;
struct trident_channel *channel = dmabuf->channel;
@@ -794,6 +812,18 @@ static void trident_rec_setup(struct trident_state *state)
channel->delta = compute_rate_rec(dmabuf->rate);
if ((card->pci_id == PCI_DEVICE_ID_ALI_5451) && (channel->num == ALI_SPDIF_IN_CHANNEL)) {
rate = ali_get_spdif_in_rate(card);
+ if (rate == 0)
+ {
+ printk(KERN_WARNING "trident: ALi 5451 S/PDIF input setup error!\n");
+ rate = 48000;
+ }
+ bval = inb(TRID_REG(card,ALI_SPDIF_CTRL));
+ if (bval & 0x10)
+ {
+ outb(bval,TRID_REG(card,ALI_SPDIF_CTRL));
+ printk(KERN_WARNING "trident: cleared ALi 5451 S/PDIF parity error flag.\n");
+ }
+
if (rate != 48000)
channel->delta = ((rate << 12) / dmabuf->rate) & 0x0000ffff;
}
@@ -959,7 +989,7 @@ static void start_dac(struct trident_state *state)
static int alloc_dmabuf(struct trident_state *state)
{
struct dmabuf *dmabuf = &state->dmabuf;
- void *rawbuf;
+ void *rawbuf=NULL;
int order;
struct page *page, *pend;
@@ -1138,11 +1168,13 @@ static void trident_clear_tail(struct trident_state *state)
len = dmabuf->dmasize - swptr;
memset(dmabuf->rawbuf + swptr, silence, len);
-
- spin_lock_irqsave(&state->card->lock, flags);
- dmabuf->swptr += len;
- dmabuf->count += len;
- spin_unlock_irqrestore(&state->card->lock, flags);
+ if(state->card->pci_id != PCI_DEVICE_ID_ALI_5451)
+ {
+ spin_lock_irqsave(&state->card->lock, flags);
+ dmabuf->swptr += len;
+ dmabuf->count += len;
+ spin_unlock_irqrestore(&state->card->lock, flags);
+ }
/* restart the dma machine in case it is halted */
start_dac(state);
@@ -1155,6 +1187,7 @@ static int drain_dac(struct trident_state *state, int nonblock)
unsigned long flags;
unsigned long tmo;
int count;
+ unsigned long diff = 0;
if (dmabuf->mapped || !dmabuf->ready)
return 0;
@@ -1183,10 +1216,19 @@ static int drain_dac(struct trident_state *state, int nonblock)
/* No matter how much data left in the buffer, we have to wait untill
CSO == ESO/2 or CSO == ESO when address engine interrupts */
- tmo = (dmabuf->dmasize * HZ) / dmabuf->rate;
+ if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451)
+ {
+ diff = dmabuf->swptr - trident_get_dma_addr(state) + dmabuf->dmasize ;
+ diff = diff % (dmabuf->dmasize);
+ tmo = (diff * HZ) / dmabuf->rate;
+ }
+ else
+ {
+ tmo = (dmabuf->dmasize * HZ) / dmabuf->rate;
+ }
tmo >>= sample_shift[dmabuf->fmt];
+// printk("trident: diff=%d count= %d/%d total=%d tmo=%d hwptr=%d swptr=%d curptr=%d\n",diff,dmabuf->count,dmabuf->dmasize,dmabuf->total_bytes,tmo,dmabuf->hwptr,dmabuf->swptr,trident_get_dma_addr(state));
if (!schedule_timeout(tmo ? tmo : 1) && tmo){
- printk(KERN_ERR "trident: drain_dac, dma timeout?\n");
break;
}
}
@@ -1412,7 +1454,7 @@ static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_
if (!ret) ret = -EAGAIN;
return ret;
}
- /* No matter how much space left in the buffer, we have to wait untill
+ /* No matter how much space left in the buffer, we have to wait until
CSO == ESO/2 or CSO == ESO when address engine interrupts */
tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
tmo >>= sample_shift[dmabuf->fmt];
@@ -1430,7 +1472,7 @@ static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_
dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
dmabuf->hwptr, dmabuf->swptr);
#endif
- /* a buffer overrun, we delay the recovery untill next time the
+ /* a buffer overrun, we delay the recovery until next time the
while loop begin and we REALLY have space to record */
}
if (signal_pending(current)) {
@@ -1512,7 +1554,7 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
if (!ret) ret = -EAGAIN;
return ret;
}
- /* No matter how much data left in the buffer, we have to wait untill
+ /* No matter how much data left in the buffer, we have to wait until
CSO == ESO/2 or CSO == ESO when address engine interrupts */
lock_set_fmt(state);
tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
@@ -1532,7 +1574,7 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
dmabuf->hwptr, dmabuf->swptr);
#endif
- /* a buffer underrun, we delay the recovery untill next time the
+ /* a buffer underrun, we delay the recovery until next time the
while loop begin and we REALLY have data to play */
}
if (signal_pending(current)) {
@@ -1671,6 +1713,8 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
count_info cinfo;
int val, mapped, ret;
+ struct trident_card *card = state->card;
+
VALIDATE_STATE(state);
mapped = ((file->f_mode & FMODE_WRITE) && dmabuf->mapped) ||
((file->f_mode & FMODE_READ) && dmabuf->mapped);
@@ -1807,17 +1851,32 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
state->chans_num = 1;
}
- if (val >= 2) {
+ if (val >= 2)
+ {
+
dmabuf->fmt |= TRIDENT_FMT_STEREO;
if ((val == 6) && (state->card->pci_id == PCI_DEVICE_ID_ALI_5451)) {
- ali_setup_multi_channels(state->card, 6);
+
+ if( card->rec_channel_use_count > 0 )
+ {
+ printk("Err: Record is working on the card!\n");
+ return -EBUSY;
+ }
+
+ ret = ali_setup_multi_channels(state->card, 6);
+ if (ret < 0) {
+ unlock_set_fmt(state);
+ return ret;
+ }
down(&state->card->open_sem);
ret = ali_allocate_other_states_resources(state, 6);
- up(&state->card->open_sem);
if (ret < 0) {
+ up(&state->card->open_sem);
unlock_set_fmt(state);
return ret;
}
+ state->card->multi_channel_use_count ++;
+ up(&state->card->open_sem);
}
else val = 2; /*yield to 2-channels*/
}
@@ -2031,10 +2090,20 @@ static int trident_open(struct inode *inode, struct file *file)
struct trident_card *card = devs;
struct trident_state *state = NULL;
struct dmabuf *dmabuf = NULL;
-
+
/* find an avaiable virtual channel (instance of /dev/dsp) */
while (card != NULL) {
down(&card->open_sem);
+ if(file->f_mode & FMODE_READ)
+ {
+ /* Skip opens on cards that are in 6 channel mode */
+ if (card->multi_channel_use_count > 0)
+ {
+ up(&card->open_sem);
+ card = card->next;
+ continue;
+ }
+ }
for (i = 0; i < NR_HW_CH; i++) {
if (card->states[i] == NULL) {
state = card->states[i] = (struct trident_state *)
@@ -2107,6 +2176,7 @@ static int trident_open(struct inode *inode, struct file *file)
(CHANNEL_REC|PCM_LR|MONO_MIX);
}
trident_set_adc_rate(state, 8000);
+ card->rec_channel_use_count ++;
}
state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
@@ -2143,16 +2213,29 @@ static int trident_release(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE) {
stop_dac(state);
lock_set_fmt(state);
- if (state->chans_num > 2)
- ali_free_other_states_resources(state);
+
unlock_set_fmt(state);
dealloc_dmabuf(state);
state->card->free_pcm_channel(state->card, dmabuf->channel->num);
+
+ if (state->chans_num > 2)
+ {
+ if( card->multi_channel_use_count-- < 0 )
+ card->multi_channel_use_count = 0;
+
+ if (card->multi_channel_use_count == 0)
+ ali_close_multi_channels();
+
+ ali_free_other_states_resources(state);
+ }
}
if (file->f_mode & FMODE_READ) {
stop_adc(state);
dealloc_dmabuf(state);
state->card->free_pcm_channel(state->card, dmabuf->channel->num);
+
+ if( card->rec_channel_use_count-- < 0 )
+ card->rec_channel_use_count = 0;
}
card->states[state->virt] = NULL;
@@ -2295,6 +2378,9 @@ static void ali_ac97_set(struct ac97_codec *codec, u8 reg, u16 val)
data = ((u32) val) << 16;
+ if(!card)
+ BUG();
+
address = ALI_AC97_WRITE;
mask = ALI_AC97_WRITE_ACTION | ALI_AC97_AUDIO_BUSY;
if (codec->id)
@@ -2391,11 +2477,29 @@ static void ali_enable_special_channel(struct trident_state *stat)
flag: ALI_SPDIF_OUT_TO_SPDIF_OUT
ALI_PCM_TO_SPDIF_OUT
*/
+
static void ali_setup_spdif_out(struct trident_card *card, int flag)
{
unsigned long spdif;
unsigned char ch;
+ char temp;
+ struct pci_dev *pci_dev = NULL;
+
+ pci_dev = pci_find_device(PCI_VENDOR_ID_AL,PCI_DEVICE_ID_AL_M1533, pci_dev);
+ if (pci_dev == NULL)
+ return;
+ pci_read_config_byte(pci_dev, 0x61, &temp);
+ temp |= 0x40;
+ pci_write_config_byte(pci_dev, 0x61, temp);
+ pci_read_config_byte(pci_dev, 0x7d, &temp);
+ temp |= 0x01;
+ pci_write_config_byte(pci_dev, 0x7d, temp);
+ pci_read_config_byte(pci_dev, 0x7e, &temp);
+ temp &= (~0x20);
+ temp |= 0x10;
+ pci_write_config_byte(pci_dev, 0x7e, temp);
+
ch = inb(TRID_REG(card, ALI_SCTRL));
outb(ch | ALI_SPDIF_OUT_ENABLE, TRID_REG(card, ALI_SCTRL));
ch = inb(TRID_REG(card, ALI_SPDIF_CTRL));
@@ -2448,112 +2552,207 @@ static void ali_setup_spdif_in(struct trident_card *card)
spdif |= ALI_SPDIF_IN_SUPPORT;
outl(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL));
- spdif = inb(TRID_REG(card, ALI_SPDIF_CTRL));
- spdif |= ALI_SPDIF_IN_CH_STATUS;
- outb(spdif, TRID_REG(card, ALI_SPDIF_CTRL));
-
//Set SPDIF IN Rec
spdif = inl(TRID_REG(card, ALI_GLOBAL_CONTROL));
spdif |= ALI_SPDIF_IN_CH_ENABLE;
outl(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL));
spdif = inb(TRID_REG(card, ALI_SPDIF_CTRL));
+ spdif |= ALI_SPDIF_IN_CH_STATUS;
+ outb(spdif, TRID_REG(card, ALI_SPDIF_CTRL));
+/*
+ spdif = inb(TRID_REG(card, ALI_SPDIF_CTRL));
spdif |= ALI_SPDIF_IN_FUNC_ENABLE;
outb(spdif, TRID_REG(card, ALI_SPDIF_CTRL));
+*/
}
-static unsigned int ali_get_spdif_in_rate(struct trident_card *card)
+static void ali_delay(struct trident_card *card,int interval)
{
- unsigned long spdif, time1, time2;
- unsigned count1, count2, count3;
- unsigned char R1, R2 = 0;
-
- outb(0xAA, TRID_REG(card, ALI_SPDIF_CTRL + 1));
- count1 = 0xFFFF;
- while(--count1)
+ unsigned long begintimer,currenttimer;
+
+ begintimer = inl(TRID_REG(card, ALI_STIMER));
+ currenttimer = inl(TRID_REG(card, ALI_STIMER));
+
+ while (currenttimer < begintimer + interval)
+ currenttimer = inl(TRID_REG(card, ALI_STIMER));
+}
+
+static void ali_detect_spdif_rate(struct trident_card *card)
+{
+ u16 wval = 0;
+ u16 count = 0;
+ u8 bval = 0, R1 = 0, R2 = 0;
+
+ bval = inb(TRID_REG(card,ALI_SPDIF_CTRL));
+ bval |= 0x02;
+ outb(bval,TRID_REG(card,ALI_SPDIF_CTRL));
+
+ bval = inb(TRID_REG(card,ALI_SPDIF_CTRL + 1));
+ bval |= 0x1F;
+ outb(bval,TRID_REG(card,ALI_SPDIF_CTRL + 1));
+
+ while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000)
{
- count2 = 0xffff;
- do{
- count3 = 0xffff;
- time1 = inl(TRID_REG(card, ALI_STIMER));
-
- do{
- time2 = inl(TRID_REG(card, ALI_STIMER));
- }while((count3--) && (time2 <= (time1 + 5)));
- if (!count3) {
- printk("ali: STimer is stopped! Error!\n");
- return FALSE;
- }
- R1 = inb(TRID_REG(card, ALI_SPDIF_CTRL + 1));
- }while((count2--) && (!((R1 == 0x0B)||(R1 == 0x0C)||(R1 == 0x0D)||(R1 == 0x0E)||(R1 == 0x12))));
- if (!count2)
- continue;
+ count ++;
- count2 = 0xffff;
- time1 = inl(TRID_REG(card, ALI_STIMER));
- do{
- time2 = inl(TRID_REG(card, ALI_STIMER));
- }while((count2--) && (time2 <= (time1 + 5)));
- if (!count2)
- continue;
+ ali_delay(card, 6);
- R2 = inb(TRID_REG(card, ALI_SPDIF_CTRL + 1));
- count2 = 0xffff;
- while((--count2) && (R2 != R1))
- {
+ bval = inb(TRID_REG(card,ALI_SPDIF_CTRL + 1));
+ R1 = bval & 0x1F;
+ }
+
+ if (count > 50000)
+ {
+ printk(KERN_WARNING "trident: Error in ali_detect_spdif_rate!\n");
+ return;
+ }
+
+ count = 0;
+
+ while (count <= 50000)
+ {
+ count ++;
+
+ ali_delay(card, 6);
+
+ bval = inb(TRID_REG(card,ALI_SPDIF_CTRL + 1));
+ R2 = bval & 0x1F;
+
+ if(R2 != R1)
R1 = R2;
- count3 = 0xffff;
- time1 = inl(TRID_REG(card, ALI_STIMER));
- do{
- time2 = inl(TRID_REG(card, ALI_STIMER));
- }while((count3--) && (time2 <= (time1 + 5)));
- if (!count3) {
- printk("ali: STimer is stopped! Error!\n");
- return FALSE;
- }
- R2 = inb(TRID_REG(card, ALI_SPDIF_CTRL + 1));
- }
- if(R2 == R1)
+ else
break;
}
- if(!count1) {
- printk("ali: Can not Detect the sample rate from SPDIF IN!\n");
- return FALSE;
+ if (count > 50000)
+ {
+ printk(KERN_WARNING "trident: Error in ali_detect_spdif_rate!\n");
+ return;
}
- spdif = inb(TRID_REG(card, ALI_SPDIF_CTRL)) | ALI_SPDIF_IN_CH_STATUS;
- outb(spdif, TRID_REG(card, ALI_SPDIF_CTRL));
+ switch (R2)
+ {
+ case 0x0b:
+ case 0x0c:
+ case 0x0d:
+ case 0x0e:
+ wval = inw(TRID_REG(card,ALI_SPDIF_CTRL + 2));
+ wval &= 0xE0F0;
+ wval |= (u16)0x09 << 8 | (u16)0x05;
+ outw(wval,TRID_REG(card,ALI_SPDIF_CTRL + 2));
+
+ bval = inb(TRID_REG(card,ALI_SPDIF_CS +3)) & 0xF0;
+ outb(bval|0x02,TRID_REG(card,ALI_SPDIF_CS + 3));
+ break;
- /* SPDIF only supprts 48k, 44.1k, 32k */
- switch(R2) {
case 0x12:
- outw(0x0E08, TRID_REG(card, ALI_SPDIF_CTRL + 2));
- return 32000;
- case 0x0B:
- case 0x0C:
- case 0x0D:
- case 0x0E:
+ wval = inw(TRID_REG(card,ALI_SPDIF_CTRL + 2));
+ wval &= 0xE0F0;
+ wval |= (u16)0x0E << 8 | (u16)0x08;
+ outw(wval,TRID_REG(card,ALI_SPDIF_CTRL + 2));
+
+ bval = inb(TRID_REG(card,ALI_SPDIF_CS +3)) & 0xF0;
+ outb(bval|0x03,TRID_REG(card,ALI_SPDIF_CS + 3));
+ break;
+
default:
- outw(0x0905, TRID_REG(card, ALI_SPDIF_CTRL + 2));
break;
}
+
+}
+
+static unsigned int ali_get_spdif_in_rate(struct trident_card *card)
+{
+ u32 dwRate = 0;
+ u8 bval = 0;
+
+ ali_detect_spdif_rate(card);
+
+ bval = inb(TRID_REG(card,ALI_SPDIF_CTRL));
+ bval &= 0x7F;
+ bval |= 0x40;
+ outb(bval,TRID_REG(card,ALI_SPDIF_CTRL));
+
+ bval = inb(TRID_REG(card,ALI_SPDIF_CS + 3));
+ bval &= 0x0F;
+
+ switch (bval)
+ {
+ case 0:
+ dwRate = 44100;
+ break;
+ case 1:
+ dwRate = 48000;
+ break;
+ case 2:
+ dwRate = 32000;
+ break;
+ default:
+ // Error occurs
+ break;
+ }
+
+ return dwRate;
+
+}
+
+static int ali_close_multi_channels(void)
+{
+ char temp = 0;
+ struct pci_dev *pci_dev = NULL;
+
+ pci_dev = pci_find_device(PCI_VENDOR_ID_AL,PCI_DEVICE_ID_AL_M1533, pci_dev);
+ if (pci_dev == NULL)
+ return -1;
+ temp = 0x80;
+ pci_write_config_byte(pci_dev, 0x59, ~temp);
- spdif = inb(TRID_REG(card, ALI_SPDIF_CS + 3)) & 0xf;
- if (spdif == 0)
- return 44100;
- else return 48000;
+ pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, pci_dev);
+ if (pci_dev == NULL)
+ return -1;
+
+ temp = 0x20;
+ pci_write_config_byte(pci_dev, 0xB8, ~temp);
+
+ return 0;
}
static int ali_setup_multi_channels(struct trident_card *card, int chan_nums)
{
unsigned long dwValue;
+ char temp = 0;
+ struct pci_dev *pci_dev = NULL;
+
+ pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pci_dev);
+ if (pci_dev == NULL)
+ return -1;
+ temp = 0x80;
+ pci_write_config_byte(pci_dev, 0x59, temp);
+ pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, pci_dev);
+ if (pci_dev == NULL)
+ return -1;
+ temp = 0x20;
+ pci_write_config_byte(pci_dev, (int)0xB8,(u8) temp);
if (chan_nums == 6) {
dwValue = inl(TRID_REG(card, ALI_SCTRL)) | 0x000f0000;
outl(dwValue, TRID_REG(card, ALI_SCTRL));
+ mdelay(4);
+ dwValue = inl(TRID_REG(card, ALI_SCTRL));
+ if (dwValue & 0x2000000) {
+ ali_ac97_set(card->ac97_codec[0], 0x02, 8080);
+ ali_ac97_set(card->ac97_codec[0], 0x36, 0);
+ ali_ac97_set(card->ac97_codec[0], 0x38, 0);
+ ali_ac97_set(card->ac97_codec[1], 0x36, 0);
+ ali_ac97_set(card->ac97_codec[1], 0x38, 0);
+ ali_ac97_set(card->ac97_codec[1], 0x02, 0);
+ ali_ac97_set(card->ac97_codec[1], 0x18, 0x0808);
+ ali_ac97_set(card->ac97_codec[1], 0x74, 0x3);
+ return 1;
+ }
}
- return 1;
+ return -EINVAL;
}
static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel)
@@ -2746,7 +2945,7 @@ static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card)
}
/* no more free channels avaliable */
- printk(KERN_ERR "ali: no more channels available on Bank A.\n");
+// printk(KERN_ERR "ali: no more channels available on Bank A.\n");
return NULL;
}
@@ -2769,7 +2968,7 @@ static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *ca
}
/* no free recordable channels avaliable */
- printk(KERN_ERR "ali: no recordable channels available on Bank A.\n");
+// printk(KERN_ERR "ali: no recordable channels available on Bank A.\n");
return NULL;
}
@@ -2778,9 +2977,6 @@ static void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate)
unsigned char ch_st_sel;
unsigned short status_rate;
-#ifdef DEBUG
- printk("ali: spdif out rate =%d\n", rate);
-#endif
switch(rate) {
case 44100:
status_rate = 0;
@@ -2803,9 +2999,6 @@ static void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate)
ch_st_sel &= (~0x80); //select left
outb(ch_st_sel, TRID_REG(card, ALI_SPDIF_CTRL));
outw(status_rate | 0x10, TRID_REG(card, ALI_SPDIF_CS + 2));
-#ifdef DEBUG
- printk("ali: SPDIF_CS=%lxh\n", inl(TRID_REG(card, ALI_SPDIF_CS)));
-#endif
}
static void ali_address_interrupt(struct trident_card *card)
@@ -2822,6 +3015,7 @@ static void ali_address_interrupt(struct trident_card *card)
if ((channel_mask = 1 << channel) & mask) {
mask &= ~channel_mask;
trident_ack_channel_interrupt(card, channel);
+ udelay(100);
state->dmabuf.update_flag |= ALI_ADDRESS_INT_UPDATE;
trident_update_ptr(state);
}
@@ -2986,7 +3180,7 @@ static int ali_write_proc(struct file *file, const char *buffer, unsigned long c
/* OSS /dev/mixer file operation methods */
static int trident_open_mixdev(struct inode *inode, struct file *file)
{
- int i;
+ int i = 0;
int minor = MINOR(inode->i_rdev);
struct trident_card *card = devs;
@@ -3033,10 +3227,17 @@ static int __init trident_ac97_init(struct trident_card *card)
switch (card->pci_id)
{
case PCI_DEVICE_ID_ALI_5451:
+ outl(0x80000000,TRID_REG(card, ALI_GLOBAL_CONTROL));
+ outl(0x00000000,TRID_REG(card, 0xa4));
+ outl(0xffffffff,TRID_REG(card, 0x98));
+ outl(0x00000000,TRID_REG(card, 0xa8));
+ outb(0x10, TRID_REG(card, 0x22));
ready_2nd = inl(TRID_REG(card, ALI_SCTRL));
- outl(ready_2nd | PCMOUT | SECONDARY_ID, TRID_REG(card, ALI_SCTRL));
+ ready_2nd &= 0x3fff;
+ outl(ready_2nd | PCMOUT | 0x8000, TRID_REG(card, ALI_SCTRL));
ready_2nd = inl(TRID_REG(card, ALI_SCTRL));
ready_2nd &= SI_AC97_SECONDARY_READY;
+// printk("codec 2 ready flag= %lx\n", ready_2nd);
break;
case PCI_DEVICE_ID_SI_7018:
/* disable AC97 GPIO interrupt */
@@ -3097,18 +3298,18 @@ static int __init trident_ac97_init(struct trident_card *card)
return num_ac97+1;
}
- return num_ac97;
+ return 1/*num_ac97*/;
}
/* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered
- untill "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
+ until "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
{
unsigned long iobase;
struct trident_card *card;
u8 revision;
- if (!pci_dma_supported(pci_dev, TRIDENT_DMA_MASK)) {
+ if (pci_set_dma_mask(pci_dev, TRIDENT_DMA_MASK)) {
printk(KERN_ERR "trident: architecture does not support"
" 30bit PCI busmaster DMA\n");
return -ENODEV;
@@ -3167,6 +3368,10 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
card->address_interrupt = ali_address_interrupt;
+ /* Added by Matt Wu 01-05-2001 for spdif in */
+ card->multi_channel_use_count = 0;
+ card->rec_channel_use_count = 0;
+
/* ALi SPDIF OUT function */
if(card->revision == ALI_5451_V02) {
ali_setup_spdif_out(card, ALI_PCM_TO_SPDIF_OUT);
@@ -3203,7 +3408,7 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
kfree(card);
return -ENODEV;
}
- /* initilize AC97 codec and register /dev/mixer */
+ /* initialize AC97 codec and register /dev/mixer */
if (trident_ac97_init(card) <= 0) {
unregister_sound_dsp(card->dev_audio);
release_region(iobase, 256);
@@ -3224,7 +3429,6 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
}
pci_set_drvdata(pci_dev, card);
- pci_dev->dma_mask = TRIDENT_DMA_MASK;
/* Enable Address Engine Interrupts */
trident_enable_loop_interrupts(card);
diff --git a/drivers/sound/via82cxxx_audio.c b/drivers/sound/via82cxxx_audio.c
index 5a644ddc5..f66d08b1b 100644
--- a/drivers/sound/via82cxxx_audio.c
+++ b/drivers/sound/via82cxxx_audio.c
@@ -15,7 +15,7 @@
*/
-#define VIA_VERSION "1.1.14a"
+#define VIA_VERSION "1.1.14b"
#include <linux/config.h>
@@ -282,6 +282,8 @@ struct via_info {
unsigned rev_h : 1;
+ int locked_rate : 1;
+
struct semaphore syscall_sem;
struct semaphore open_sem;
@@ -508,10 +510,16 @@ static void via_stop_everything (struct via_info *card)
static int via_set_rate (struct ac97_codec *ac97,
struct via_channel *chan, unsigned rate)
{
+ struct via_info *card = ac97->private_data;
int rate_reg;
DPRINTK ("ENTER, rate = %d\n", rate);
+ if (card->locked_rate) {
+ chan->rate = 48000;
+ goto out;
+ }
+
if (rate > 48000) rate = 48000;
if (rate < 4000) rate = 4000;
@@ -535,6 +543,13 @@ static int via_set_rate (struct ac97_codec *ac97,
*/
chan->rate = via_ac97_read_reg (ac97, rate_reg);
+ if (chan->rate == 0) {
+ card->locked_rate = 1;
+ chan->rate = 48000;
+ printk (KERN_WARNING PFX "Codec rate locked at 48Khz\n");
+ }
+
+out:
DPRINTK ("EXIT, returning rate %d Hz\n", chan->rate);
return chan->rate;
}
@@ -1421,15 +1436,19 @@ static int __init via_ac97_reset (struct via_info *card)
/* WARNING: this line is magic. Remove this
* and things break. */
/* enable variable rate, variable rate MIC ADC */
- tmp16 = via_ac97_read_reg (&card->ac97, 0x2A);
- via_ac97_write_reg (&card->ac97, 0x2A, tmp16 | (1<<0));
-
- pci_read_config_byte (pdev, VIA_ACLINK_CTRL, &tmp8);
- if ((tmp8 & (VIA_CR41_AC97_ENABLE | VIA_CR41_AC97_RESET)) == 0) {
- printk (KERN_ERR PFX "cannot enable AC97 controller, aborting\n");
- DPRINTK ("EXIT, tmp8=%X, returning -ENODEV\n", tmp8);
- return -ENODEV;
- }
+ /*
+ * If we cannot enable VRA, we have a locked-rate codec.
+ * We try again to enable VRA before assuming so, however.
+ */
+ tmp16 = via_ac97_read_reg (&card->ac97, AC97_EXTENDED_STATUS);
+ if ((tmp16 & 1) == 0) {
+ via_ac97_write_reg (&card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
+ tmp16 = via_ac97_read_reg (&card->ac97, AC97_EXTENDED_STATUS);
+ if ((tmp16 & 1) == 0) {
+ card->locked_rate = 1;
+ printk (KERN_WARNING PFX "Codec rate locked at 48Khz\n");
+ }
+ }
DPRINTK ("EXIT, returning 0\n");
return 0;
@@ -1478,8 +1497,8 @@ static int __init via_ac97_init (struct via_info *card)
}
/* enable variable rate, variable rate MIC ADC */
- tmp16 = via_ac97_read_reg (&card->ac97, 0x2A);
- via_ac97_write_reg (&card->ac97, 0x2A, tmp16 | (1<<0));
+ tmp16 = via_ac97_read_reg (&card->ac97, AC97_EXTENDED_STATUS);
+ via_ac97_write_reg (&card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
DPRINTK ("EXIT, returning 0\n");
return 0;
diff --git a/drivers/sound/wavfront.c b/drivers/sound/wavfront.c
index accc16ccf..f0d9676b5 100644
--- a/drivers/sound/wavfront.c
+++ b/drivers/sound/wavfront.c
@@ -94,7 +94,7 @@
#ifdef CONFIG_SMP
#define LOOPS_PER_TICK cpu_data[smp_processor_id()].loops_per_jiffy
#else
-#define LOOPS_PER_TICK loops_per_sec
+#define LOOPS_PER_TICK loops_per_jiffy
#endif
#endif
@@ -693,7 +693,7 @@ wavefront_cmd (int cmd, unsigned char *rbuf, unsigned char *wbuf)
/***********************************************************************
WaveFront: data munging
-Things here are wierd. All data written to the board cannot
+Things here are weird. All data written to the board cannot
have its most significant bit set. Any data item with values
potentially > 0x7F (127) must be split across multiple bytes.
@@ -702,7 +702,7 @@ the x86 side as 8-32 bit values. Sometimes, we need to munge data
that is represented on the x86 side as an array of bytes. The most
efficient approach to handling both cases seems to be to use 2
different functions for munging and 2 for de-munging. This avoids
-wierd casting and worrying about bit-level offsets.
+weird casting and worrying about bit-level offsets.
**********************************************************************/
@@ -1213,7 +1213,7 @@ wavefront_send_sample (wavefront_patch_info *header,
shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleEndOffset),
shptr, 4);
- /* This one is truly wierd. What kind of wierdo decided that in
+ /* This one is truly weird. What kind of weirdo decided that in
a system dominated by 16 and 32 bit integers, they would use
a just 12 bits ?
*/
@@ -3069,7 +3069,7 @@ wffx_ioctl (wavefront_fx_info *r)
This code was developed using DOSEMU. The Turtle Beach SETUPSND
utility was run with I/O tracing in DOSEMU enabled, and a reconstruction
of the port I/O done, using the Yamaha faxback document as a guide
- to add more logic to the code. Its really pretty wierd.
+ to add more logic to the code. Its really pretty weird.
There was an alternative approach of just dumping the whole I/O
sequence as a series of port/value pairs and a simple loop
diff --git a/drivers/sound/ymfpci.c b/drivers/sound/ymfpci.c
index 07b7d186c..5640b421a 100644
--- a/drivers/sound/ymfpci.c
+++ b/drivers/sound/ymfpci.c
@@ -95,34 +95,6 @@ static struct pci_device_id ymf_id_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, ymf_id_tbl);
/*
- * Mindlessly copied from cs46xx XXX
- */
-static inline unsigned ld2(unsigned int x)
-{
- unsigned r = 0;
-
- if (x >= 0x10000) {
- x >>= 16;
- r += 16;
- }
- if (x >= 0x100) {
- x >>= 8;
- r += 8;
- }
- if (x >= 0x10) {
- x >>= 4;
- r += 4;
- }
- if (x >= 4) {
- x >>= 2;
- r += 2;
- }
- if (x >= 2)
- r++;
- return r;
-}
-
-/*
* common I/O routines
*/
@@ -347,7 +319,6 @@ static int prog_dmabuf(struct ymf_state *state, int rec)
{
struct ymf_dmabuf *dmabuf;
int w_16;
- unsigned bytepersec;
unsigned bufsize;
unsigned long flags;
int redzone;
@@ -367,20 +338,16 @@ static int prog_dmabuf(struct ymf_state *state, int rec)
if ((ret = alloc_dmabuf(dmabuf)))
return ret;
- bytepersec = state->format.rate << state->format.shift;
-
/*
* Create fake fragment sizes and numbers for OSS ioctls.
+ * Import what Doom might have set with SNDCTL_DSP_SETFRAGMENT.
*/
bufsize = PAGE_SIZE << dmabuf->buforder;
- if (dmabuf->ossfragshift) {
- if ((1000 << dmabuf->ossfragshift) < bytepersec)
- dmabuf->fragshift = ld2(bytepersec/1000);
- else
- dmabuf->fragshift = dmabuf->ossfragshift;
- } else {
- /* lets hand out reasonable big ass buffers by default */
- dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT -2);
+ /* lets hand out reasonable big ass buffers by default */
+ dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT -2);
+ if (dmabuf->ossfragshift > 3 &&
+ dmabuf->ossfragshift < dmabuf->fragshift) {
+ dmabuf->fragshift = dmabuf->ossfragshift;
}
dmabuf->numfrag = bufsize >> dmabuf->fragshift;
while (dmabuf->numfrag < 4 && dmabuf->fragshift > 3) {
@@ -390,9 +357,6 @@ static int prog_dmabuf(struct ymf_state *state, int rec)
dmabuf->fragsize = 1 << dmabuf->fragshift;
dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
- /*
- * Import what Doom might have set with SNDCTL_DSD_SETFRAGMENT.
- */
if (dmabuf->ossmaxfrags >= 2 && dmabuf->ossmaxfrags < dmabuf->numfrag) {
dmabuf->numfrag = dmabuf->ossmaxfrags;
dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
@@ -1726,8 +1690,6 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
dmabuf->ossfragshift = 4;
if (dmabuf->ossfragshift > 15)
dmabuf->ossfragshift = 15;
- if (dmabuf->ossmaxfrags < 4)
- dmabuf->ossmaxfrags = 4;
return 0;
case SNDCTL_DSP_GETOSPACE:
@@ -1879,7 +1841,7 @@ static int ymf_ioctl(struct inode *inode, struct file *file,
static int ymf_open(struct inode *inode, struct file *file)
{
struct list_head *list;
- ymfpci_t *unit;
+ ymfpci_t *unit = NULL;
int minor;
struct ymf_state *state;
int err;
@@ -2370,9 +2332,9 @@ static int __devinit ymf_probe_one(struct pci_dev *pcidev, const struct pci_devi
int err;
- if (pci_enable_device(pcidev) < 0) {
+ if ((err = pci_enable_device(pcidev)) != 0) {
printk(KERN_ERR "ymfpci: pci_enable_device failed\n");
- return -ENODEV;
+ return err;
}
if ((codec = kmalloc(sizeof(ymfpci_t), GFP_KERNEL)) == NULL) {