return v;
}
-static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun)
+static inline void
+aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask)
{
u32 val;
int timeout = 5000;
do {
val = readl(aacirun->base + AACI_SR);
- } while (val & (SR_TXB|SR_RXB) && timeout--);
+ } while (val & mask && timeout--);
}
writel(0, aacirun->base + AACI_IE);
return;
}
- ptr = aacirun->ptr;
+ spin_lock(&aacirun->lock);
+
+ ptr = aacirun->ptr;
do {
unsigned int len = aacirun->fifosz;
u32 val;
if (aacirun->bytes <= 0) {
aacirun->bytes += aacirun->period;
aacirun->ptr = ptr;
- spin_unlock(&aaci->lock);
+ spin_unlock(&aacirun->lock);
snd_pcm_period_elapsed(aacirun->substream);
- spin_lock(&aaci->lock);
+ spin_lock(&aacirun->lock);
}
if (!(aacirun->cr & CR_EN))
break;
ptr = aacirun->start;
}
} while(1);
+
aacirun->ptr = ptr;
+
+ spin_unlock(&aacirun->lock);
}
if (mask & ISR_URINTR) {
return;
}
+ spin_lock(&aacirun->lock);
+
ptr = aacirun->ptr;
do {
unsigned int len = aacirun->fifosz;
if (aacirun->bytes <= 0) {
aacirun->bytes += aacirun->period;
aacirun->ptr = ptr;
- spin_unlock(&aaci->lock);
+ spin_unlock(&aacirun->lock);
snd_pcm_period_elapsed(aacirun->substream);
- spin_lock(&aaci->lock);
+ spin_lock(&aacirun->lock);
}
if (!(aacirun->cr & CR_EN))
break;
} while (1);
aacirun->ptr = ptr;
+
+ spin_unlock(&aacirun->lock);
}
}
u32 mask;
int i;
- spin_lock(&aaci->lock);
mask = readl(aaci->base + AACI_ALLINTS);
if (mask) {
u32 m = mask;
}
}
}
- spin_unlock(&aaci->lock);
return mask ? IRQ_HANDLED : IRQ_NONE;
}
ie &= ~(IE_URIE|IE_TXIE);
writel(ie, aacirun->base + AACI_IE);
aacirun->cr &= ~CR_EN;
- aaci_chan_wait_ready(aacirun);
+ aaci_chan_wait_ready(aacirun, SR_TXB);
writel(aacirun->cr, aacirun->base + AACI_TXCR);
}
{
u32 ie;
- aaci_chan_wait_ready(aacirun);
+ aaci_chan_wait_ready(aacirun, SR_TXB);
aacirun->cr |= CR_EN;
ie = readl(aacirun->base + AACI_IE);
static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
{
- struct aaci *aaci = substream->private_data;
struct aaci_runtime *aacirun = substream->runtime->private_data;
unsigned long flags;
int ret = 0;
- spin_lock_irqsave(&aaci->lock, flags);
+ spin_lock_irqsave(&aacirun->lock, flags);
+
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
aaci_pcm_playback_start(aacirun);
default:
ret = -EINVAL;
}
- spin_unlock_irqrestore(&aaci->lock, flags);
+
+ spin_unlock_irqrestore(&aacirun->lock, flags);
return ret;
}
{
u32 ie;
- aaci_chan_wait_ready(aacirun);
+ aaci_chan_wait_ready(aacirun, SR_RXB);
ie = readl(aacirun->base + AACI_IE);
ie &= ~(IE_ORIE | IE_RXIE);
{
u32 ie;
- aaci_chan_wait_ready(aacirun);
+ aaci_chan_wait_ready(aacirun, SR_RXB);
#ifdef DEBUG
/* RX Timeout value: bits 28:17 in RXCR */
static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
{
- struct aaci *aaci = substream->private_data;
struct aaci_runtime *aacirun = substream->runtime->private_data;
unsigned long flags;
int ret = 0;
- spin_lock_irqsave(&aaci->lock, flags);
+ spin_lock_irqsave(&aacirun->lock, flags);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
ret = -EINVAL;
}
- spin_unlock_irqrestore(&aaci->lock, flags);
+ spin_unlock_irqrestore(&aacirun->lock, flags);
return ret;
}
aaci = card->private_data;
mutex_init(&aaci->ac97_sem);
- spin_lock_init(&aaci->lock);
aaci->card = card;
aaci->dev = dev;
/*
* Playback uses AACI channel 0
*/
+ spin_lock_init(&aaci->playback.lock);
aaci->playback.base = aaci->base + AACI_CSCH1;
aaci->playback.fifo = aaci->base + AACI_DR1;
/*
* Capture uses AACI channel 0
*/
+ spin_lock_init(&aaci->capture.lock);
aaci->capture.base = aaci->base + AACI_CSCH1;
aaci->capture.fifo = aaci->base + AACI_DR1;