[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: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
This commit is contained in:
parent
2c7782b420
commit
aaad3653a5
1 changed files with 20 additions and 45 deletions
|
@ -107,7 +107,7 @@ static char *cmds[] = {
|
|||
#define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x)
|
||||
|
||||
#else
|
||||
#define dprintk(a, x...)
|
||||
#define dprintk(a, x...) do { } while (0)
|
||||
|
||||
#endif /* DBRI_DEBUG */
|
||||
|
||||
|
@ -610,10 +610,10 @@ CPU interrupt to signal completion.
|
|||
|
||||
Since the DBRI can run in parallel with the CPU, several means of
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -628,7 +628,7 @@ to send them to the DBRI.
|
|||
|
||||
*/
|
||||
|
||||
#define MAXLOOPS 10
|
||||
#define MAXLOOPS 20
|
||||
/*
|
||||
* Wait for the current command string to execute
|
||||
*/
|
||||
|
@ -692,9 +692,8 @@ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len)
|
|||
if (cmd > dbri->cmdptr) {
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
s32 *ptr = dbri->cmdptr;
|
||||
|
||||
|
@ -1141,13 +1140,9 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
|
|||
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_dvma + dbri_dma_off(desc, first_desc);
|
||||
dbri->next_desc[last_desc] = first_desc;
|
||||
}
|
||||
dbri->dma->desc[last_desc].nda =
|
||||
dbri->dma_dvma + dbri_dma_off(desc, first_desc);
|
||||
dbri->next_desc[last_desc] = first_desc;
|
||||
dbri->pipes[info->pipe].first_desc = first_desc;
|
||||
dbri->pipes[info->pipe].desc = first_desc;
|
||||
|
||||
|
@ -1639,7 +1634,6 @@ static void xmit_descs(struct snd_dbri *dbri)
|
|||
if (dbri == NULL)
|
||||
return; /* Disabled */
|
||||
|
||||
/* First check the recording stream for buffer overflow */
|
||||
info = &dbri->stream_info[DBRI_REC];
|
||||
spin_lock_irqsave(&dbri->lock, flags);
|
||||
|
||||
|
@ -1649,27 +1643,20 @@ static void xmit_descs(struct snd_dbri *dbri)
|
|||
dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td);
|
||||
|
||||
/* Stream could be closed by the time we run. */
|
||||
if (first_td < 0) {
|
||||
goto play;
|
||||
if (first_td >= 0) {
|
||||
cmd = dbri_cmdlock(dbri, 2);
|
||||
*(cmd++) = DBRI_CMD(D_SDP, 0,
|
||||
dbri->pipes[info->pipe].sdp
|
||||
| D_SDP_P | D_SDP_EVERY | D_SDP_C);
|
||||
*(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
|
||||
dbri_cmdsend(dbri, cmd, 2);
|
||||
|
||||
/* Reset our admin of the pipe. */
|
||||
dbri->pipes[info->pipe].desc = first_td;
|
||||
}
|
||||
|
||||
cmd = dbri_cmdlock(dbri, 2);
|
||||
*(cmd++) = DBRI_CMD(D_SDP, 0,
|
||||
dbri->pipes[info->pipe].sdp
|
||||
| D_SDP_P | D_SDP_EVERY | D_SDP_C);
|
||||
*(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
|
||||
dbri_cmdsend(dbri, cmd, 2);
|
||||
|
||||
/* Reset our admin of the pipe & bytes read. */
|
||||
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];
|
||||
spin_lock_irqsave(&dbri->lock, flags);
|
||||
|
||||
if (info->pipe >= 0) {
|
||||
first_td = dbri->pipes[info->pipe].first_desc;
|
||||
|
@ -1685,7 +1672,7 @@ play:
|
|||
*(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1755,7 +1742,6 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe)
|
|||
return;
|
||||
}
|
||||
|
||||
dbri->dma->desc[rd].ba = 0;
|
||||
dbri->pipes[pipe].desc = dbri->next_desc[rd];
|
||||
status = dbri->dma->desc[rd].word1;
|
||||
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)
|
|||
dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n",
|
||||
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 */
|
||||
if (spin_is_locked(&dbri->lock)) {
|
||||
spin_unlock(&dbri->lock);
|
||||
|
@ -2113,6 +2087,7 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream)
|
|||
info->pipe = 6; /* Receive pipe */
|
||||
|
||||
spin_lock_irq(&dbri->lock);
|
||||
info->offset = 0;
|
||||
|
||||
/* Setup the all the transmit/receive desciptors to cover the
|
||||
* whole DMA buffer.
|
||||
|
|
Loading…
Reference in a new issue