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>
#define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x)
#else
#define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x)
#else
-#define dprintk(a, x...)
+#define dprintk(a, x...) do { } while (0)
Since the DBRI can run in parallel with the CPU, several means of
synchronization present themselves. The method implemented here is only
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
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
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
/*
* Wait for the current command string to execute
*/
/*
* Wait for the current command string to execute
*/
if (cmd > dbri->cmdptr) {
s32 *ptr;
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);
dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
} else {
s32 *ptr = dbri->cmdptr;
} else {
s32 *ptr = dbri->cmdptr;
- 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;
dbri->pipes[info->pipe].first_desc = first_desc;
dbri->pipes[info->pipe].desc = first_desc;
if (dbri == NULL)
return; /* Disabled */
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);
info = &dbri->stream_info[DBRI_REC];
spin_lock_irqsave(&dbri->lock, flags);
dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td);
/* Stream could be closed by the time we run. */
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;
- }
-
- 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);
+ 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 & bytes read. */
- dbri->pipes[info->pipe].desc = first_td;
+ /* Reset our admin of the pipe. */
+ 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) {
first_td = dbri->pipes[info->pipe].first_desc;
if (info->pipe >= 0) {
first_td = dbri->pipes[info->pipe].first_desc;
*(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
dbri_cmdsend(dbri, cmd, 2);
*(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;
}
}
dbri->pipes[info->pipe].desc = first_td;
}
}
- 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. */
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. */
dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n",
rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status));
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);
/* Notify ALSA */
if (spin_is_locked(&dbri->lock)) {
spin_unlock(&dbri->lock);
info->pipe = 6; /* Receive pipe */
spin_lock_irq(&dbri->lock);
info->pipe = 6; /* Receive pipe */
spin_lock_irq(&dbri->lock);
/* Setup the all the transmit/receive desciptors to cover the
* whole DMA buffer.
/* Setup the all the transmit/receive desciptors to cover the
* whole DMA buffer.