aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2006-08-28 06:59:23 -0400
committerJaroslav Kysela <perex@suse.cz>2006-09-23 04:44:31 -0400
commitaaad3653a5f073ce9eaef4efd387cf7fc3a53d18 (patch)
treefa42d208052b9b960bc6e689c543898e470b5db8
parent2c7782b420ee137057eeec7c24a565ac85fc1988 (diff)
[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>
-rw-r--r--sound/sparc/dbri.c65
1 files changed, 20 insertions, 45 deletions
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 3e6ad507849d..cdca8e4a96e4 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -107,7 +107,7 @@ static char *cmds[] = {
107#define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x) 107#define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x)
108 108
109#else 109#else
110#define dprintk(a, x...) 110#define dprintk(a, x...) do { } while (0)
111 111
112#endif /* DBRI_DEBUG */ 112#endif /* DBRI_DEBUG */
113 113
@@ -610,10 +610,10 @@ CPU interrupt to signal completion.
610 610
611Since the DBRI can run in parallel with the CPU, several means of 611Since the DBRI can run in parallel with the CPU, several means of
612synchronization present themselves. The method implemented here is only 612synchronization present themselves. The method implemented here is only
613to use the dbri_cmdwait() to wait for execution of batch of sent commands. 613use of the dbri_cmdwait() to wait for execution of batch of sent commands.
614 614
615A circular command buffer is used here. A new command is being added 615A circular command buffer is used here. A new command is being added
616while other can be executed. The scheme works by adding two WAIT commands 616while another can be executed. The scheme works by adding two WAIT commands
617after each sent batch of commands. When the next batch is prepared it is 617after each sent batch of commands. When the next batch is prepared it is
618added after the WAIT commands then the WAITs are replaced with single JUMP 618added after the WAIT commands then the WAITs are replaced with single JUMP
619command to the new batch. The the DBRI is forced to reread the last WAIT 619command 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 628
629*/ 629*/
630 630
631#define MAXLOOPS 10 631#define MAXLOOPS 20
632/* 632/*
633 * Wait for the current command string to execute 633 * Wait for the current command string to execute
634 */ 634 */
@@ -692,9 +692,8 @@ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len)
692 if (cmd > dbri->cmdptr) { 692 if (cmd > dbri->cmdptr) {
693 s32 *ptr; 693 s32 *ptr;
694 694
695 for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++) { 695 for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++)
696 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); 696 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
697 }
698 } else { 697 } else {
699 s32 *ptr = dbri->cmdptr; 698 s32 *ptr = dbri->cmdptr;
700 699
@@ -1141,13 +1140,9 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
1141 return -1; 1140 return -1;
1142 } 1141 }
1143 1142
1144 if (streamno == DBRI_PLAY) { 1143 dbri->dma->desc[last_desc].nda =
1145 dbri->dma->desc[last_desc].word1 |= 1144 dbri->dma_dvma + dbri_dma_off(desc, first_desc);
1146 DBRI_TD_F | DBRI_TD_B; 1145 dbri->next_desc[last_desc] = first_desc;
1147 dbri->dma->desc[last_desc].nda =
1148 dbri->dma_dvma + dbri_dma_off(desc, first_desc);
1149 dbri->next_desc[last_desc] = first_desc;
1150 }
1151 dbri->pipes[info->pipe].first_desc = first_desc; 1146 dbri->pipes[info->pipe].first_desc = first_desc;
1152 dbri->pipes[info->pipe].desc = first_desc; 1147 dbri->pipes[info->pipe].desc = first_desc;
1153 1148
@@ -1639,7 +1634,6 @@ static void xmit_descs(struct snd_dbri *dbri)
1639 if (dbri == NULL) 1634 if (dbri == NULL)
1640 return; /* Disabled */ 1635 return; /* Disabled */
1641 1636
1642 /* First check the recording stream for buffer overflow */
1643 info = &dbri->stream_info[DBRI_REC]; 1637 info = &dbri->stream_info[DBRI_REC];
1644 spin_lock_irqsave(&dbri->lock, flags); 1638 spin_lock_irqsave(&dbri->lock, flags);
1645 1639
@@ -1649,27 +1643,20 @@ static void xmit_descs(struct snd_dbri *dbri)
1649 dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td); 1643 dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td);
1650 1644
1651 /* Stream could be closed by the time we run. */ 1645 /* Stream could be closed by the time we run. */
1652 if (first_td < 0) { 1646 if (first_td >= 0) {
1653 goto play; 1647 cmd = dbri_cmdlock(dbri, 2);
1654 } 1648 *(cmd++) = DBRI_CMD(D_SDP, 0,
1655 1649 dbri->pipes[info->pipe].sdp
1656 cmd = dbri_cmdlock(dbri, 2); 1650 | D_SDP_P | D_SDP_EVERY | D_SDP_C);
1657 *(cmd++) = DBRI_CMD(D_SDP, 0, 1651 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
1658 dbri->pipes[info->pipe].sdp 1652 dbri_cmdsend(dbri, cmd, 2);
1659 | D_SDP_P | D_SDP_EVERY | D_SDP_C);
1660 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
1661 dbri_cmdsend(dbri, cmd, 2);
1662 1653
1663 /* Reset our admin of the pipe & bytes read. */ 1654 /* Reset our admin of the pipe. */
1664 dbri->pipes[info->pipe].desc = first_td; 1655 dbri->pipes[info->pipe].desc = first_td;
1656 }
1665 } 1657 }
1666 1658
1667play:
1668 spin_unlock_irqrestore(&dbri->lock, flags);
1669
1670 /* Now check the playback stream for buffer underflow */
1671 info = &dbri->stream_info[DBRI_PLAY]; 1659 info = &dbri->stream_info[DBRI_PLAY];
1672 spin_lock_irqsave(&dbri->lock, flags);
1673 1660
1674 if (info->pipe >= 0) { 1661 if (info->pipe >= 0) {
1675 first_td = dbri->pipes[info->pipe].first_desc; 1662 first_td = dbri->pipes[info->pipe].first_desc;
@@ -1685,7 +1672,7 @@ play:
1685 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); 1672 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
1686 dbri_cmdsend(dbri, cmd, 2); 1673 dbri_cmdsend(dbri, cmd, 2);
1687 1674
1688 /* Reset our admin of the pipe & bytes written. */ 1675 /* Reset our admin of the pipe. */
1689 dbri->pipes[info->pipe].desc = first_td; 1676 dbri->pipes[info->pipe].desc = first_td;
1690 } 1677 }
1691 } 1678 }
@@ -1755,7 +1742,6 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe)
1755 return; 1742 return;
1756 } 1743 }
1757 1744
1758 dbri->dma->desc[rd].ba = 0;
1759 dbri->pipes[pipe].desc = dbri->next_desc[rd]; 1745 dbri->pipes[pipe].desc = dbri->next_desc[rd];
1760 status = dbri->dma->desc[rd].word1; 1746 status = dbri->dma->desc[rd].word1;
1761 dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */ 1747 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 dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n", 1754 dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n",
1769 rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); 1755 rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status));
1770 1756
1771 /* On the last TD, transmit them all again. */
1772#if 0
1773 if (dbri->next_desc[rd] == -1) {
1774 if (info->left > info->size) {
1775 printk(KERN_WARNING
1776 "%d bytes recorded in %d size buffer.\n",
1777 info->left, info->size);
1778 }
1779 tasklet_schedule(&xmit_descs_task);
1780 }
1781#endif
1782
1783 /* Notify ALSA */ 1757 /* Notify ALSA */
1784 if (spin_is_locked(&dbri->lock)) { 1758 if (spin_is_locked(&dbri->lock)) {
1785 spin_unlock(&dbri->lock); 1759 spin_unlock(&dbri->lock);
@@ -2113,6 +2087,7 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream)
2113 info->pipe = 6; /* Receive pipe */ 2087 info->pipe = 6; /* Receive pipe */
2114 2088
2115 spin_lock_irq(&dbri->lock); 2089 spin_lock_irq(&dbri->lock);
2090 info->offset = 0;
2116 2091
2117 /* Setup the all the transmit/receive desciptors to cover the 2092 /* Setup the all the transmit/receive desciptors to cover the
2118 * whole DMA buffer. 2093 * whole DMA buffer.