[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
|
@ -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.
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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)
|
||||||
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
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streamno == DBRI_PLAY) {
|
dbri->dma->desc[last_desc].nda =
|
||||||
dbri->dma->desc[last_desc].word1 |=
|
dbri->dma_dvma + dbri_dma_off(desc, first_desc);
|
||||||
DBRI_TD_F | DBRI_TD_B;
|
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].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)
|
||||||
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,27 +1643,20 @@ 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_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];
|
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 @@ play:
|
||||||
*(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)
|
||||||
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)
|
||||||
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)
|
||||||
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.
|
||||||
|
|
Loading…
Reference in a new issue