diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2006-08-28 06:59:23 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-09-23 04:44:31 -0400 |
commit | aaad3653a5f073ce9eaef4efd387cf7fc3a53d18 (patch) | |
tree | fa42d208052b9b960bc6e689c543898e470b5db8 | |
parent | 2c7782b420ee137057eeec7c24a565ac85fc1988 (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.c | 65 |
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 | ||
611 | Since the DBRI can run in parallel with the CPU, several means of | 611 | Since the DBRI can run in parallel with the CPU, several means of |
612 | synchronization present themselves. The method implemented here is only | 612 | synchronization present themselves. The method implemented here is only |
613 | to use the dbri_cmdwait() to wait for execution of batch of sent commands. | 613 | use of the dbri_cmdwait() to wait for execution of batch of sent commands. |
614 | 614 | ||
615 | A circular command buffer is used here. A new command is being added | 615 | A circular command buffer is used here. A new command is being added |
616 | while other can be executed. The scheme works by adding two WAIT commands | 616 | while another can be executed. The scheme works by adding two WAIT commands |
617 | after each sent batch of commands. When the next batch is prepared it is | 617 | after each sent batch of commands. When the next batch is prepared it is |
618 | added after the WAIT commands then the WAITs are replaced with single JUMP | 618 | added after the WAIT commands then the WAITs are replaced with single JUMP |
619 | command to the new batch. The the DBRI is forced to reread the last WAIT | 619 | 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 | 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 | ||
1667 | play: | ||
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. |