Commit aaad3653 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Jaroslav Kysela

[ALSA] sparc dbri: recording is back

This patch fixes sound recording after the driver convertion to
ring buffered version. It also contains small clean ups to the
driver.
Signed-off-by: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent 2c7782b4
...@@ -107,7 +107,7 @@ static char *cmds[] = { ...@@ -107,7 +107,7 @@ static char *cmds[] = {
#define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x) #define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x)
#else #else
#define dprintk(a, x...) #define dprintk(a, x...) do { } while (0)
#endif /* DBRI_DEBUG */ #endif /* DBRI_DEBUG */
...@@ -610,10 +610,10 @@ CPU interrupt to signal completion. ...@@ -610,10 +610,10 @@ CPU interrupt to signal completion.
Since the DBRI can run in parallel with the CPU, several means of Since the DBRI can run in parallel with the CPU, several means of
synchronization present themselves. The method implemented here is only synchronization present themselves. The method implemented here is only
to use the dbri_cmdwait() to wait for execution of batch of sent commands. use of the dbri_cmdwait() to wait for execution of batch of sent commands.
A circular command buffer is used here. A new command is being added A circular command buffer is used here. A new command is being added
while other can be executed. The scheme works by adding two WAIT commands while another can be executed. The scheme works by adding two WAIT commands
after each sent batch of commands. When the next batch is prepared it is after each sent batch of commands. When the next batch is prepared it is
added after the WAIT commands then the WAITs are replaced with single JUMP added after the WAIT commands then the WAITs are replaced with single JUMP
command to the new batch. The the DBRI is forced to reread the last WAIT command to the new batch. The the DBRI is forced to reread the last WAIT
...@@ -628,7 +628,7 @@ to send them to the DBRI. ...@@ -628,7 +628,7 @@ to send them to the DBRI.
*/ */
#define MAXLOOPS 10 #define MAXLOOPS 20
/* /*
* Wait for the current command string to execute * Wait for the current command string to execute
*/ */
...@@ -692,9 +692,8 @@ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len) ...@@ -692,9 +692,8 @@ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len)
if (cmd > dbri->cmdptr) { if (cmd > dbri->cmdptr) {
s32 *ptr; s32 *ptr;
for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++) { for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++)
dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
}
} else { } else {
s32 *ptr = dbri->cmdptr; s32 *ptr = dbri->cmdptr;
...@@ -1141,13 +1140,9 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period ...@@ -1141,13 +1140,9 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
return -1; return -1;
} }
if (streamno == DBRI_PLAY) {
dbri->dma->desc[last_desc].word1 |=
DBRI_TD_F | DBRI_TD_B;
dbri->dma->desc[last_desc].nda = dbri->dma->desc[last_desc].nda =
dbri->dma_dvma + dbri_dma_off(desc, first_desc); dbri->dma_dvma + dbri_dma_off(desc, first_desc);
dbri->next_desc[last_desc] = first_desc; dbri->next_desc[last_desc] = first_desc;
}
dbri->pipes[info->pipe].first_desc = first_desc; dbri->pipes[info->pipe].first_desc = first_desc;
dbri->pipes[info->pipe].desc = first_desc; dbri->pipes[info->pipe].desc = first_desc;
...@@ -1639,7 +1634,6 @@ static void xmit_descs(struct snd_dbri *dbri) ...@@ -1639,7 +1634,6 @@ static void xmit_descs(struct snd_dbri *dbri)
if (dbri == NULL) if (dbri == NULL)
return; /* Disabled */ return; /* Disabled */
/* First check the recording stream for buffer overflow */
info = &dbri->stream_info[DBRI_REC]; info = &dbri->stream_info[DBRI_REC];
spin_lock_irqsave(&dbri->lock, flags); spin_lock_irqsave(&dbri->lock, flags);
...@@ -1649,10 +1643,7 @@ static void xmit_descs(struct snd_dbri *dbri) ...@@ -1649,10 +1643,7 @@ static void xmit_descs(struct snd_dbri *dbri)
dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td); dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td);
/* Stream could be closed by the time we run. */ /* Stream could be closed by the time we run. */
if (first_td < 0) { if (first_td >= 0) {
goto play;
}
cmd = dbri_cmdlock(dbri, 2); cmd = dbri_cmdlock(dbri, 2);
*(cmd++) = DBRI_CMD(D_SDP, 0, *(cmd++) = DBRI_CMD(D_SDP, 0,
dbri->pipes[info->pipe].sdp dbri->pipes[info->pipe].sdp
...@@ -1660,16 +1651,12 @@ static void xmit_descs(struct snd_dbri *dbri) ...@@ -1660,16 +1651,12 @@ static void xmit_descs(struct snd_dbri *dbri)
*(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
dbri_cmdsend(dbri, cmd, 2); dbri_cmdsend(dbri, cmd, 2);
/* Reset our admin of the pipe & bytes read. */ /* Reset our admin of the pipe. */
dbri->pipes[info->pipe].desc = first_td; dbri->pipes[info->pipe].desc = first_td;
} }
}
play:
spin_unlock_irqrestore(&dbri->lock, flags);
/* Now check the playback stream for buffer underflow */
info = &dbri->stream_info[DBRI_PLAY]; info = &dbri->stream_info[DBRI_PLAY];
spin_lock_irqsave(&dbri->lock, flags);
if (info->pipe >= 0) { if (info->pipe >= 0) {
first_td = dbri->pipes[info->pipe].first_desc; first_td = dbri->pipes[info->pipe].first_desc;
...@@ -1685,7 +1672,7 @@ static void xmit_descs(struct snd_dbri *dbri) ...@@ -1685,7 +1672,7 @@ static void xmit_descs(struct snd_dbri *dbri)
*(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
dbri_cmdsend(dbri, cmd, 2); dbri_cmdsend(dbri, cmd, 2);
/* Reset our admin of the pipe & bytes written. */ /* Reset our admin of the pipe. */
dbri->pipes[info->pipe].desc = first_td; dbri->pipes[info->pipe].desc = first_td;
} }
} }
...@@ -1755,7 +1742,6 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe) ...@@ -1755,7 +1742,6 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe)
return; return;
} }
dbri->dma->desc[rd].ba = 0;
dbri->pipes[pipe].desc = dbri->next_desc[rd]; dbri->pipes[pipe].desc = dbri->next_desc[rd];
status = dbri->dma->desc[rd].word1; status = dbri->dma->desc[rd].word1;
dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */ dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */
...@@ -1768,18 +1754,6 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe) ...@@ -1768,18 +1754,6 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe)
dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n", dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n",
rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status));
/* On the last TD, transmit them all again. */
#if 0
if (dbri->next_desc[rd] == -1) {
if (info->left > info->size) {
printk(KERN_WARNING
"%d bytes recorded in %d size buffer.\n",
info->left, info->size);
}
tasklet_schedule(&xmit_descs_task);
}
#endif
/* Notify ALSA */ /* Notify ALSA */
if (spin_is_locked(&dbri->lock)) { if (spin_is_locked(&dbri->lock)) {
spin_unlock(&dbri->lock); spin_unlock(&dbri->lock);
...@@ -2113,6 +2087,7 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream) ...@@ -2113,6 +2087,7 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream)
info->pipe = 6; /* Receive pipe */ info->pipe = 6; /* Receive pipe */
spin_lock_irq(&dbri->lock); spin_lock_irq(&dbri->lock);
info->offset = 0;
/* Setup the all the transmit/receive desciptors to cover the /* Setup the all the transmit/receive desciptors to cover the
* whole DMA buffer. * whole DMA buffer.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment