aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2006-08-21 13:30:57 -0400
committerJaroslav Kysela <perex@suse.cz>2006-09-23 04:42:33 -0400
commit1be54c824be9b5e163cd83dabdf0ad3ac81c72a8 (patch)
tree1a559701342e767a6add56a9e7960f26c1baba4c
parent294a30dc8cf13c492913f2ed3a6540bdf6e84e39 (diff)
[ALSA] sparc dbri: ring buffered version
It is a complete rework of low level layer to work on ring buffers for comands and data descriptors. This removes annoying noise due to delay in data buffer switching. 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.c385
1 files changed, 192 insertions, 193 deletions
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 5696f792e3d1..3fb2ede80eaf 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -2,6 +2,8 @@
2 * Driver for DBRI sound chip found on Sparcs. 2 * Driver for DBRI sound chip found on Sparcs.
3 * Copyright (C) 2004, 2005 Martin Habets (mhabets@users.sourceforge.net) 3 * Copyright (C) 2004, 2005 Martin Habets (mhabets@users.sourceforge.net)
4 * 4 *
5 * Converted to ring buffered version by Krzysztof Helt (krzysztof.h1@wp.pl)
6 *
5 * Based entirely upon drivers/sbus/audio/dbri.c which is: 7 * Based entirely upon drivers/sbus/audio/dbri.c which is:
6 * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) 8 * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
7 * Copyright (C) 1998, 1999 Brent Baccala (baccala@freesoft.org) 9 * Copyright (C) 1998, 1999 Brent Baccala (baccala@freesoft.org)
@@ -260,7 +262,7 @@ struct dbri_mem {
260 * the CPU and the DBRI 262 * the CPU and the DBRI
261 */ 263 */
262struct dbri_dma { 264struct dbri_dma {
263 volatile s32 cmd[DBRI_NO_CMDS]; /* Place for commands */ 265 s32 cmd[DBRI_NO_CMDS]; /* Place for commands */
264 volatile s32 intr[DBRI_INT_BLK]; /* Interrupt field */ 266 volatile s32 intr[DBRI_INT_BLK]; /* Interrupt field */
265 struct dbri_mem desc[DBRI_NO_DESCS]; /* Xmit/receive descriptors */ 267 struct dbri_mem desc[DBRI_NO_DESCS]; /* Xmit/receive descriptors */
266}; 268};
@@ -284,7 +286,6 @@ struct dbri_pipe {
284struct dbri_streaminfo { 286struct dbri_streaminfo {
285 struct snd_pcm_substream *substream; 287 struct snd_pcm_substream *substream;
286 u32 dvma_buffer; /* Device view of Alsa DMA buffer */ 288 u32 dvma_buffer; /* Device view of Alsa DMA buffer */
287 int left; /* # of bytes left in DMA buffer */
288 int size; /* Size of DMA buffer */ 289 int size; /* Size of DMA buffer */
289 size_t offset; /* offset in user buffer */ 290 size_t offset; /* offset in user buffer */
290 int pipe; /* Data pipe used */ 291 int pipe; /* Data pipe used */
@@ -305,11 +306,11 @@ struct snd_dbri {
305 306
306 void __iomem *regs; /* dbri HW regs */ 307 void __iomem *regs; /* dbri HW regs */
307 int dbri_irqp; /* intr queue pointer */ 308 int dbri_irqp; /* intr queue pointer */
308 int wait_send; /* sequence of command buffers send */
309 int wait_ackd; /* sequence of command buffers acknowledged */
310 309
311 struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */ 310 struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */
312 int next_desc[DBRI_NO_DESCS]; /* Index of next desc, or -1 */ 311 int next_desc[DBRI_NO_DESCS]; /* Index of next desc, or -1 */
312 spinlock_t cmdlock; /* Protects cmd queue accesses */
313 s32 *cmdptr; /* Pointer to the last queued cmd */
313 314
314 int chi_bpf; 315 int chi_bpf;
315 316
@@ -544,7 +545,7 @@ struct snd_dbri {
544#define DBRI_TD_TBC (1<<0) /* Transmit buffer Complete */ 545#define DBRI_TD_TBC (1<<0) /* Transmit buffer Complete */
545#define DBRI_TD_STATUS(v) ((v)&0xff) /* Transmit status */ 546#define DBRI_TD_STATUS(v) ((v)&0xff) /* Transmit status */
546 /* Maximum buffer size per TD: almost 8Kb */ 547 /* Maximum buffer size per TD: almost 8Kb */
547#define DBRI_TD_MAXCNT ((1 << 13) - 1) 548#define DBRI_TD_MAXCNT ((1 << 13) - 4)
548 549
549/* Receive descriptor defines */ 550/* Receive descriptor defines */
550#define DBRI_RD_F (1<<31) /* End of Frame */ 551#define DBRI_RD_F (1<<31) /* End of Frame */
@@ -608,79 +609,110 @@ The list is terminated with a WAIT command, which generates a
608CPU interrupt to signal completion. 609CPU interrupt to signal completion.
609 610
610Since 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
611synchronization present themselves. The method implemented here is close 612synchronization present themselves. The method implemented here is only
612to the original scheme (Rudolf's), and uses 2 counters (wait_send and 613to use the dbri_cmdwait() to wait for execution of batch of sent commands.
613wait_ackd) to synchronize the command buffer between the CPU and the DBRI.
614 614
615A more sophisticated scheme might involve a circular command buffer 615A circular command buffer is used here. A new command is being added
616or an array of command buffers. A routine could fill one with 616while other can be executed. The scheme works by adding two WAIT commands
617commands and link it onto a list. When a interrupt signaled 617after each sent batch of commands. When the next batch is prepared it is
618completion of the current command buffer, look on the list for 618added after the WAIT commands then the WAITs are replaced with single JUMP
619the next one. 619command to the new batch. The the DBRI is forced to reread the last WAIT
620command (replaced by the JUMP by then). If the DBRI is still executing
621previous commands the request to reread the WAIT command is ignored.
620 622
621Every time a routine wants to write commands to the DBRI, it must 623Every time a routine wants to write commands to the DBRI, it must
622first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd 624first call dbri_cmdlock() and get pointer to a free space in
623in return. dbri_cmdlock() will block if the previous commands have not 625dbri->dma->cmd buffer. After this, the commands can be written to
624been completed yet. After this the commands can be written to the buffer, 626the buffer, and dbri_cmdsend() is called with the final pointer value
625and dbri_cmdsend() is called with the final pointer value to send them 627to send them to the DBRI.
626to the DBRI.
627 628
628*/ 629*/
629 630
630static void dbri_process_interrupt_buffer(struct snd_dbri * dbri); 631static void dbri_process_interrupt_buffer(struct snd_dbri * dbri);
631 632
632enum dbri_lock { NoGetLock, GetLock };
633#define MAXLOOPS 10 633#define MAXLOOPS 10
634 634/*
635static volatile s32 *dbri_cmdlock(struct snd_dbri * dbri, enum dbri_lock get) 635 * Wait for the current command string to execute
636 */
637static void dbri_cmdwait(struct snd_dbri *dbri)
636{ 638{
637 int maxloops = MAXLOOPS; 639 int maxloops = MAXLOOPS;
638 640
639#ifndef SMP
640 if ((get == GetLock) && spin_is_locked(&dbri->lock)) {
641 printk(KERN_ERR "DBRI: cmdlock called while in spinlock.");
642 }
643#endif
644
645 /* Delay if previous commands are still being processed */ 641 /* Delay if previous commands are still being processed */
646 while ((--maxloops) > 0 && (dbri->wait_send != dbri->wait_ackd)) { 642 while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P))
647 msleep_interruptible(1); 643 msleep_interruptible(1);
648 } 644
649 if (maxloops == 0) { 645 if (maxloops == 0) {
650 printk(KERN_ERR "DBRI: Chip never completed command buffer %d\n", 646 printk(KERN_ERR "DBRI: Chip never completed command buffer\n");
651 dbri->wait_send);
652 } else { 647 } else {
653 dprintk(D_CMD, "Chip completed command buffer (%d)\n", 648 dprintk(D_CMD, "Chip completed command buffer (%d)\n",
654 MAXLOOPS - maxloops - 1); 649 MAXLOOPS - maxloops - 1);
655 } 650 }
651}
652/*
653 * Lock the command queue and returns pointer to a space for len cmd words
654 * It locks the cmdlock spinlock.
655 */
656static s32 *dbri_cmdlock(struct snd_dbri * dbri, int len)
657{
658 /* Space for 2 WAIT cmds (replaced later by 1 JUMP cmd) */
659 len += 2;
660 spin_lock(&dbri->cmdlock);
661 if (dbri->cmdptr - dbri->dma->cmd + len < DBRI_NO_CMDS - 2)
662 return dbri->cmdptr + 2;
663 else if (len < sbus_readl(dbri->regs + REG8) - dbri->dma_dvma)
664 return dbri->dma->cmd;
665 else
666 printk(KERN_ERR "DBRI: no space for commands.");
656 667
657 /*if (get == GetLock) spin_lock(&dbri->lock); */ 668 return 0;
658 return &dbri->dma->cmd[0];
659} 669}
660 670
661static void dbri_cmdsend(struct snd_dbri * dbri, volatile s32 * cmd) 671/*
672 * Send prepared cmd string. It works by writting a JMP cmd into
673 * the last WAIT cmd and force DBRI to reread the cmd.
674 * The JMP cmd points to the new cmd string.
675 * It also releases the cmdlock spinlock.
676 */
677static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len)
662{ 678{
663 volatile s32 *ptr; 679 s32 *ptr;
680 s32 tmp, addr;
681 static int wait_id = 0;
664 682
665 for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) { 683 wait_id++;
666 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); 684 wait_id &= 0xffff; /* restrict it to a 16 bit counter. */
667 } 685 *(cmd) = DBRI_CMD(D_WAIT, 1, wait_id);
686 *(cmd+1) = DBRI_CMD(D_WAIT, 1, wait_id);
668 687
669 if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) { 688 /* Replace the last command with JUMP */
670 printk(KERN_ERR "DBRI: Command buffer overflow! (bug in driver)\n"); 689 addr = dbri->dma_dvma + (cmd - len - dbri->dma->cmd) * sizeof(s32);
671 /* Ignore the last part. */ 690 *(dbri->cmdptr+1) = addr;
672 cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3]; 691 *(dbri->cmdptr) = DBRI_CMD(D_JUMP, 0, 0);
673 }
674 692
675 dbri->wait_send++; 693#ifdef DBRI_DEBUG
676 dbri->wait_send &= 0xffff; /* restrict it to a 16 bit counter. */ 694 if (cmd > dbri->cmdptr )
677 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); 695 for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++) {
678 *(cmd++) = DBRI_CMD(D_WAIT, 1, dbri->wait_send); 696 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
697 }
698 else {
699 ptr = dbri->cmdptr;
700 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
701 ptr = dbri->cmdptr+1;
702 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
703 for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++) {
704 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
705 }
706 }
707#endif
679 708
680 /* Set command pointer and signal it is valid. */ 709 /* Reread the last command */
681 sbus_writel(dbri->dma_dvma, dbri->regs + REG8); 710 tmp = sbus_readl(dbri->regs + REG0);
711 tmp |= D_P;
712 sbus_writel(tmp, dbri->regs + REG0);
682 713
683 /*spin_unlock(&dbri->lock); */ 714 dbri->cmdptr = cmd;
715 spin_unlock(&dbri->cmdlock);
684} 716}
685 717
686/* Lock must be held when calling this */ 718/* Lock must be held when calling this */
@@ -709,7 +741,7 @@ static void dbri_reset(struct snd_dbri * dbri)
709/* Lock must not be held before calling this */ 741/* Lock must not be held before calling this */
710static void dbri_initialize(struct snd_dbri * dbri) 742static void dbri_initialize(struct snd_dbri * dbri)
711{ 743{
712 volatile s32 *cmd; 744 s32 *cmd;
713 u32 dma_addr; 745 u32 dma_addr;
714 unsigned long flags; 746 unsigned long flags;
715 int n; 747 int n;
@@ -718,14 +750,11 @@ static void dbri_initialize(struct snd_dbri * dbri)
718 750
719 dbri_reset(dbri); 751 dbri_reset(dbri);
720 752
721 cmd = dbri_cmdlock(dbri, NoGetLock);
722 dprintk(D_GEN, "init: cmd: %p, int: %p\n",
723 &dbri->dma->cmd[0], &dbri->dma->intr[0]);
724
725 /* Initialize pipes */ 753 /* Initialize pipes */
726 for (n = 0; n < DBRI_NO_PIPES; n++) 754 for (n = 0; n < DBRI_NO_PIPES; n++)
727 dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1; 755 dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1;
728 756
757 spin_lock_init(&dbri->cmdlock);
729 /* 758 /*
730 * Initialize the interrupt ringbuffer. 759 * Initialize the interrupt ringbuffer.
731 */ 760 */
@@ -735,10 +764,19 @@ static void dbri_initialize(struct snd_dbri * dbri)
735 /* 764 /*
736 * Set up the interrupt queue 765 * Set up the interrupt queue
737 */ 766 */
767 spin_lock(&dbri->cmdlock);
768 cmd = dbri->cmdptr = dbri->dma->cmd;
738 *(cmd++) = DBRI_CMD(D_IIQ, 0, 0); 769 *(cmd++) = DBRI_CMD(D_IIQ, 0, 0);
739 *(cmd++) = dma_addr; 770 *(cmd++) = dma_addr;
771 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
772 dbri->cmdptr = cmd;
773 *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
774 *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
775 dma_addr = dbri->dma_dvma + dbri_dma_off(cmd, 0);
776 sbus_writel(dma_addr, dbri->regs + REG8);
777 spin_unlock(&dbri->cmdlock);
778 dbri_cmdwait(dbri);
740 779
741 dbri_cmdsend(dbri, cmd);
742 spin_unlock_irqrestore(&dbri->lock, flags); 780 spin_unlock_irqrestore(&dbri->lock, flags);
743} 781}
744 782
@@ -770,7 +808,7 @@ static void reset_pipe(struct snd_dbri * dbri, int pipe)
770{ 808{
771 int sdp; 809 int sdp;
772 int desc; 810 int desc;
773 volatile int *cmd; 811 s32 *cmd;
774 812
775 if (pipe < 0 || pipe > DBRI_MAX_PIPE) { 813 if (pipe < 0 || pipe > DBRI_MAX_PIPE) {
776 printk(KERN_ERR "DBRI: reset_pipe called with illegal pipe number\n"); 814 printk(KERN_ERR "DBRI: reset_pipe called with illegal pipe number\n");
@@ -783,16 +821,18 @@ static void reset_pipe(struct snd_dbri * dbri, int pipe)
783 return; 821 return;
784 } 822 }
785 823
786 cmd = dbri_cmdlock(dbri, NoGetLock); 824 cmd = dbri_cmdlock(dbri, 3);
787 *(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P); 825 *(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P);
788 *(cmd++) = 0; 826 *(cmd++) = 0;
789 dbri_cmdsend(dbri, cmd); 827 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
828 dbri_cmdsend(dbri, cmd, 3);
790 829
791 desc = dbri->pipes[pipe].first_desc; 830 desc = dbri->pipes[pipe].first_desc;
792 while (desc != -1) { 831 if ( desc >= 0)
793 dbri->dma->desc[desc].nda = dbri->dma->desc[desc].ba = 0; 832 do {
794 desc = dbri->next_desc[desc]; 833 dbri->dma->desc[desc].nda = dbri->dma->desc[desc].ba = 0;
795 } 834 desc = dbri->next_desc[desc];
835 } while (desc != -1 && desc != dbri->pipes[pipe].first_desc);
796 836
797 dbri->pipes[pipe].desc = -1; 837 dbri->pipes[pipe].desc = -1;
798 dbri->pipes[pipe].first_desc = -1; 838 dbri->pipes[pipe].first_desc = -1;
@@ -828,7 +868,7 @@ static void link_time_slot(struct snd_dbri * dbri, int pipe,
828 int prevpipe, int nextpipe, 868 int prevpipe, int nextpipe,
829 int length, int cycle) 869 int length, int cycle)
830{ 870{
831 volatile s32 *cmd; 871 s32 *cmd;
832 int val; 872 int val;
833 873
834 if (pipe < 0 || pipe > DBRI_MAX_PIPE 874 if (pipe < 0 || pipe > DBRI_MAX_PIPE
@@ -847,11 +887,10 @@ static void link_time_slot(struct snd_dbri * dbri, int pipe,
847 } 887 }
848 888
849 dbri->pipes[prevpipe].nextpipe = pipe; 889 dbri->pipes[prevpipe].nextpipe = pipe;
850
851 dbri->pipes[pipe].nextpipe = nextpipe; 890 dbri->pipes[pipe].nextpipe = nextpipe;
852 dbri->pipes[pipe].length = length; 891 dbri->pipes[pipe].length = length;
853 892
854 cmd = dbri_cmdlock(dbri, NoGetLock); 893 cmd = dbri_cmdlock(dbri, 4);
855 894
856 if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { 895 if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
857 /* Deal with CHI special case: 896 /* Deal with CHI special case:
@@ -874,25 +913,27 @@ static void link_time_slot(struct snd_dbri * dbri, int pipe,
874 D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe); 913 D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe);
875 *(cmd++) = 0; 914 *(cmd++) = 0;
876 } 915 }
916 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
877 917
878 dbri_cmdsend(dbri, cmd); 918 dbri_cmdsend(dbri, cmd, 4);
879} 919}
880 920
881static void unlink_time_slot(struct snd_dbri * dbri, int pipe, 921static void unlink_time_slot(struct snd_dbri * dbri, int pipe,
882 enum in_or_out direction, int prevpipe, 922 enum in_or_out direction, int prevpipe,
883 int nextpipe) 923 int nextpipe)
884{ 924{
885 volatile s32 *cmd; 925 s32 *cmd;
886 int val; 926 int val;
887 927
888 if (pipe < 0 || pipe > DBRI_MAX_PIPE 928 if (pipe < 0 || pipe > DBRI_MAX_PIPE
889 || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE) { 929 || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE
930 || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) {
890 printk(KERN_ERR 931 printk(KERN_ERR
891 "DBRI: unlink_time_slot called with illegal pipe number\n"); 932 "DBRI: unlink_time_slot called with illegal pipe number\n");
892 return; 933 return;
893 } 934 }
894 935
895 cmd = dbri_cmdlock(dbri, NoGetLock); 936 cmd = dbri_cmdlock(dbri, 4);
896 937
897 if (direction == PIPEinput) { 938 if (direction == PIPEinput) {
898 val = D_DTS_VI | D_DTS_DEL | D_DTS_PRVIN(prevpipe) | pipe; 939 val = D_DTS_VI | D_DTS_DEL | D_DTS_PRVIN(prevpipe) | pipe;
@@ -905,8 +946,9 @@ static void unlink_time_slot(struct snd_dbri * dbri, int pipe,
905 *(cmd++) = 0; 946 *(cmd++) = 0;
906 *(cmd++) = D_TS_NEXT(nextpipe); 947 *(cmd++) = D_TS_NEXT(nextpipe);
907 } 948 }
949 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
908 950
909 dbri_cmdsend(dbri, cmd); 951 dbri_cmdsend(dbri, cmd, 4);
910} 952}
911 953
912/* xmit_fixed() / recv_fixed() 954/* xmit_fixed() / recv_fixed()
@@ -925,7 +967,7 @@ static void unlink_time_slot(struct snd_dbri * dbri, int pipe,
925 */ 967 */
926static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data) 968static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data)
927{ 969{
928 volatile s32 *cmd; 970 s32 *cmd;
929 971
930 if (pipe < 16 || pipe > DBRI_MAX_PIPE) { 972 if (pipe < 16 || pipe > DBRI_MAX_PIPE) {
931 printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n"); 973 printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n");
@@ -952,12 +994,14 @@ static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data)
952 if (dbri->pipes[pipe].sdp & D_SDP_MSB) 994 if (dbri->pipes[pipe].sdp & D_SDP_MSB)
953 data = reverse_bytes(data, dbri->pipes[pipe].length); 995 data = reverse_bytes(data, dbri->pipes[pipe].length);
954 996
955 cmd = dbri_cmdlock(dbri, GetLock); 997 cmd = dbri_cmdlock(dbri, 3);
956 998
957 *(cmd++) = DBRI_CMD(D_SSP, 0, pipe); 999 *(cmd++) = DBRI_CMD(D_SSP, 0, pipe);
958 *(cmd++) = data; 1000 *(cmd++) = data;
1001 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
959 1002
960 dbri_cmdsend(dbri, cmd); 1003 dbri_cmdsend(dbri, cmd, 3);
1004 dbri_cmdwait(dbri);
961} 1005}
962 1006
963static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr) 1007static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr)
@@ -991,6 +1035,8 @@ static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr)
991 * and work by building chains of descriptors which identify the 1035 * and work by building chains of descriptors which identify the
992 * data buffers. Buffers too large for a single descriptor will 1036 * data buffers. Buffers too large for a single descriptor will
993 * be spread across multiple descriptors. 1037 * be spread across multiple descriptors.
1038 *
1039 * All descriptors create a ring buffer.
994 */ 1040 */
995static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period) 1041static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period)
996{ 1042{
@@ -1051,14 +1097,13 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
1051 return -1; 1097 return -1;
1052 } 1098 }
1053 1099
1054 if (len > DBRI_TD_MAXCNT) { 1100 if (len > DBRI_TD_MAXCNT)
1055 mylen = DBRI_TD_MAXCNT; /* 8KB - 1 */ 1101 mylen = DBRI_TD_MAXCNT; /* 8KB - 4 */
1056 } else { 1102 else
1057 mylen = len; 1103 mylen = len;
1058 } 1104
1059 if (mylen > period) { 1105 if (mylen > period)
1060 mylen = period; 1106 mylen = period;
1061 }
1062 1107
1063 dbri->next_desc[desc] = -1; 1108 dbri->next_desc[desc] = -1;
1064 dbri->dma->desc[desc].ba = dvma_buffer; 1109 dbri->dma->desc[desc].ba = dvma_buffer;
@@ -1067,17 +1112,17 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
1067 if (streamno == DBRI_PLAY) { 1112 if (streamno == DBRI_PLAY) {
1068 dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen); 1113 dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen);
1069 dbri->dma->desc[desc].word4 = 0; 1114 dbri->dma->desc[desc].word4 = 0;
1070 if (first_desc != -1) 1115 dbri->dma->desc[desc].word1 |=
1071 dbri->dma->desc[desc].word1 |= DBRI_TD_M; 1116 DBRI_TD_F | DBRI_TD_B;
1072 } else { 1117 } else {
1073 dbri->dma->desc[desc].word1 = 0; 1118 dbri->dma->desc[desc].word1 = 0;
1074 dbri->dma->desc[desc].word4 = 1119 dbri->dma->desc[desc].word4 =
1075 DBRI_RD_B | DBRI_RD_BCNT(mylen); 1120 DBRI_RD_B | DBRI_RD_BCNT(mylen);
1076 } 1121 }
1077 1122
1078 if (first_desc == -1) { 1123 if (first_desc == -1)
1079 first_desc = desc; 1124 first_desc = desc;
1080 } else { 1125 else {
1081 dbri->next_desc[last_desc] = desc; 1126 dbri->next_desc[last_desc] = desc;
1082 dbri->dma->desc[last_desc].nda = 1127 dbri->dma->desc[last_desc].nda =
1083 dbri->dma_dvma + dbri_dma_off(desc, desc); 1128 dbri->dma_dvma + dbri_dma_off(desc, desc);
@@ -1093,21 +1138,28 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
1093 return -1; 1138 return -1;
1094 } 1139 }
1095 1140
1096 dbri->dma->desc[last_desc].word1 &= ~DBRI_TD_M;
1097 if (streamno == DBRI_PLAY) { 1141 if (streamno == DBRI_PLAY) {
1098 dbri->dma->desc[last_desc].word1 |= 1142 dbri->dma->desc[last_desc].word1 |=
1099 DBRI_TD_I | DBRI_TD_F | DBRI_TD_B; 1143 DBRI_TD_F | DBRI_TD_B;
1144 dbri->dma->desc[last_desc].nda =
1145 dbri->dma_dvma + dbri_dma_off(desc, first_desc);
1146 dbri->next_desc[last_desc] = first_desc;
1100 } 1147 }
1101 dbri->pipes[info->pipe].first_desc = first_desc; 1148 dbri->pipes[info->pipe].first_desc = first_desc;
1102 dbri->pipes[info->pipe].desc = first_desc; 1149 dbri->pipes[info->pipe].desc = first_desc;
1103 1150
1104 for (desc = first_desc; desc != -1; desc = dbri->next_desc[desc]) { 1151#ifdef DBRI_DEBUG
1152 for (desc = first_desc; desc != -1; ) {
1105 dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n", 1153 dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n",
1106 desc, 1154 desc,
1107 dbri->dma->desc[desc].word1, 1155 dbri->dma->desc[desc].word1,
1108 dbri->dma->desc[desc].ba, 1156 dbri->dma->desc[desc].ba,
1109 dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4); 1157 dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4);
1158 desc = dbri->next_desc[desc];
1159 if ( desc == first_desc )
1160 break;
1110 } 1161 }
1162#endif
1111 return 0; 1163 return 0;
1112} 1164}
1113 1165
@@ -1127,43 +1179,24 @@ enum master_or_slave { CHImaster, CHIslave };
1127static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_slave, 1179static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_slave,
1128 int bits_per_frame) 1180 int bits_per_frame)
1129{ 1181{
1130 volatile s32 *cmd; 1182 s32 *cmd;
1131 int val; 1183 int val;
1132 static int chi_initialized = 0; /* FIXME: mutex? */
1133
1134 if (!chi_initialized) {
1135 1184
1136 cmd = dbri_cmdlock(dbri, GetLock); 1185 /* Set CHI Anchor: Pipe 16 */
1137 1186
1138 /* Set CHI Anchor: Pipe 16 */ 1187 cmd = dbri_cmdlock(dbri, 4);
1139 1188 val = D_DTS_VO | D_DTS_VI | D_DTS_INS
1140 val = D_DTS_VO | D_DTS_VI | D_DTS_INS 1189 | D_DTS_PRVIN(16) | D_PIPE(16) | D_DTS_PRVOUT(16);
1141 | D_DTS_PRVIN(16) | D_PIPE(16) | D_DTS_PRVOUT(16); 1190 *(cmd++) = DBRI_CMD(D_DTS, 0, val);
1142 *(cmd++) = DBRI_CMD(D_DTS, 0, val); 1191 *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
1143 *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); 1192 *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
1144 *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); 1193 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
1194 dbri_cmdsend(dbri, cmd, 4);
1145 1195
1146 dbri->pipes[16].sdp = 1; 1196 dbri->pipes[16].sdp = 1;
1147 dbri->pipes[16].nextpipe = 16; 1197 dbri->pipes[16].nextpipe = 16;
1148 1198
1149#if 0 1199 cmd = dbri_cmdlock(dbri, 4);
1150 chi_initialized++;
1151#endif
1152 } else {
1153 int pipe;
1154
1155 for (pipe = 0; pipe < DBRI_NO_PIPES; pipe++ )
1156 if ( pipe != 16 ) {
1157 if (dbri->pipes[pipe].sdp & D_SDP_TO_SER)
1158 unlink_time_slot(dbri, pipe, PIPEoutput,
1159 16, dbri->pipes[pipe].nextpipe);
1160 else
1161 unlink_time_slot(dbri, pipe, PIPEinput,
1162 16, dbri->pipes[pipe].nextpipe);
1163 }
1164
1165 cmd = dbri_cmdlock(dbri, GetLock);
1166 }
1167 1200
1168 if (master_or_slave == CHIslave) { 1201 if (master_or_slave == CHIslave) {
1169 /* Setup DBRI for CHI Slave - receive clock, frame sync (FS) 1202 /* Setup DBRI for CHI Slave - receive clock, frame sync (FS)
@@ -1202,8 +1235,9 @@ static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_sla
1202 1235
1203 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); 1236 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
1204 *(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE | D_CDM_XEN | D_CDM_REN); 1237 *(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE | D_CDM_XEN | D_CDM_REN);
1238 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
1205 1239
1206 dbri_cmdsend(dbri, cmd); 1240 dbri_cmdsend(dbri, cmd, 4);
1207} 1241}
1208 1242
1209/* 1243/*
@@ -1240,6 +1274,8 @@ static void cs4215_setup_pipes(struct snd_dbri * dbri)
1240 setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB); 1274 setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
1241 setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); 1275 setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
1242 setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); 1276 setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
1277
1278 dbri_cmdwait(dbri);
1243} 1279}
1244 1280
1245static int cs4215_init_data(struct cs4215 *mm) 1281static int cs4215_init_data(struct cs4215 *mm)
@@ -1271,7 +1307,7 @@ static int cs4215_init_data(struct cs4215 *mm)
1271 mm->status = 0; 1307 mm->status = 0;
1272 mm->version = 0xff; 1308 mm->version = 0xff;
1273 mm->precision = 8; /* For ULAW */ 1309 mm->precision = 8; /* For ULAW */
1274 mm->channels = 2; 1310 mm->channels = 1;
1275 1311
1276 return 0; 1312 return 0;
1277} 1313}
@@ -1554,7 +1590,6 @@ static int cs4215_init(struct snd_dbri * dbri)
1554 } 1590 }
1555 1591
1556 cs4215_setup_pipes(dbri); 1592 cs4215_setup_pipes(dbri);
1557
1558 cs4215_init_data(&dbri->mm); 1593 cs4215_init_data(&dbri->mm);
1559 1594
1560 /* Enable capture of the status & version timeslots. */ 1595 /* Enable capture of the status & version timeslots. */
@@ -1583,9 +1618,7 @@ buffer and calls dbri_process_one_interrupt() for each interrupt word.
1583Complicated interrupts are handled by dedicated functions (which 1618Complicated interrupts are handled by dedicated functions (which
1584appear first in this file). Any pending interrupts can be serviced by 1619appear first in this file). Any pending interrupts can be serviced by
1585calling dbri_process_interrupt_buffer(), which works even if the CPU's 1620calling dbri_process_interrupt_buffer(), which works even if the CPU's
1586interrupts are disabled. This function is used by dbri_cmdlock() 1621interrupts are disabled.
1587to make sure we're synced up with the chip before each command sequence,
1588even if we're running cli'ed.
1589 1622
1590*/ 1623*/
1591 1624
@@ -1594,11 +1627,10 @@ even if we're running cli'ed.
1594 * Transmit the current TD's for recording/playing, if needed. 1627 * Transmit the current TD's for recording/playing, if needed.
1595 * For playback, ALSA has filled the DMA memory with new data (we hope). 1628 * For playback, ALSA has filled the DMA memory with new data (we hope).
1596 */ 1629 */
1597static void xmit_descs(unsigned long data) 1630static void xmit_descs(struct snd_dbri *dbri)
1598{ 1631{
1599 struct snd_dbri *dbri = (struct snd_dbri *) data;
1600 struct dbri_streaminfo *info; 1632 struct dbri_streaminfo *info;
1601 volatile s32 *cmd; 1633 s32 *cmd;
1602 unsigned long flags; 1634 unsigned long flags;
1603 int first_td; 1635 int first_td;
1604 1636
@@ -1609,7 +1641,7 @@ static void xmit_descs(unsigned long data)
1609 info = &dbri->stream_info[DBRI_REC]; 1641 info = &dbri->stream_info[DBRI_REC];
1610 spin_lock_irqsave(&dbri->lock, flags); 1642 spin_lock_irqsave(&dbri->lock, flags);
1611 1643
1612 if ((info->left >= info->size) && (info->pipe >= 0)) { 1644 if (info->pipe >= 0) {
1613 first_td = dbri->pipes[info->pipe].first_desc; 1645 first_td = dbri->pipes[info->pipe].first_desc;
1614 1646
1615 dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td); 1647 dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td);
@@ -1619,16 +1651,15 @@ static void xmit_descs(unsigned long data)
1619 goto play; 1651 goto play;
1620 } 1652 }
1621 1653
1622 cmd = dbri_cmdlock(dbri, NoGetLock); 1654 cmd = dbri_cmdlock(dbri, 2);
1623 *(cmd++) = DBRI_CMD(D_SDP, 0, 1655 *(cmd++) = DBRI_CMD(D_SDP, 0,
1624 dbri->pipes[info->pipe].sdp 1656 dbri->pipes[info->pipe].sdp
1625 | D_SDP_P | D_SDP_EVERY | D_SDP_C); 1657 | D_SDP_P | D_SDP_EVERY | D_SDP_C);
1626 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); 1658 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
1627 dbri_cmdsend(dbri, cmd); 1659 dbri_cmdsend(dbri, cmd, 2);
1628 1660
1629 /* Reset our admin of the pipe & bytes read. */ 1661 /* Reset our admin of the pipe & bytes read. */
1630 dbri->pipes[info->pipe].desc = first_td; 1662 dbri->pipes[info->pipe].desc = first_td;
1631 info->left = 0;
1632 } 1663 }
1633 1664
1634play: 1665play:
@@ -1638,33 +1669,27 @@ play:
1638 info = &dbri->stream_info[DBRI_PLAY]; 1669 info = &dbri->stream_info[DBRI_PLAY];
1639 spin_lock_irqsave(&dbri->lock, flags); 1670 spin_lock_irqsave(&dbri->lock, flags);
1640 1671
1641 if ((info->left <= 0) && (info->pipe >= 0)) { 1672 if (info->pipe >= 0) {
1642 first_td = dbri->pipes[info->pipe].first_desc; 1673 first_td = dbri->pipes[info->pipe].first_desc;
1643 1674
1644 dprintk(D_DESC, "xmit_descs play @ TD %d\n", first_td); 1675 dprintk(D_DESC, "xmit_descs play @ TD %d\n", first_td);
1645 1676
1646 /* Stream could be closed by the time we run. */ 1677 /* Stream could be closed by the time we run. */
1647 if (first_td < 0) { 1678 if (first_td >= 0) {
1648 spin_unlock_irqrestore(&dbri->lock, flags); 1679 cmd = dbri_cmdlock(dbri, 2);
1649 return; 1680 *(cmd++) = DBRI_CMD(D_SDP, 0,
1650 } 1681 dbri->pipes[info->pipe].sdp
1651 1682 | D_SDP_P | D_SDP_EVERY | D_SDP_C);
1652 cmd = dbri_cmdlock(dbri, NoGetLock); 1683 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
1653 *(cmd++) = DBRI_CMD(D_SDP, 0, 1684 dbri_cmdsend(dbri, cmd, 2);
1654 dbri->pipes[info->pipe].sdp
1655 | D_SDP_P | D_SDP_EVERY | D_SDP_C);
1656 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
1657 dbri_cmdsend(dbri, cmd);
1658 1685
1659 /* Reset our admin of the pipe & bytes written. */ 1686 /* Reset our admin of the pipe & bytes written. */
1660 dbri->pipes[info->pipe].desc = first_td; 1687 dbri->pipes[info->pipe].desc = first_td;
1661 info->left = info->size; 1688 }
1662 } 1689 }
1663 spin_unlock_irqrestore(&dbri->lock, flags); 1690 spin_unlock_irqrestore(&dbri->lock, flags);
1664} 1691}
1665 1692
1666static DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0);
1667
1668/* transmission_complete_intr() 1693/* transmission_complete_intr()
1669 * 1694 *
1670 * Called by main interrupt handler when DBRI signals transmission complete 1695 * Called by main interrupt handler when DBRI signals transmission complete
@@ -1684,7 +1709,6 @@ static void transmission_complete_intr(struct snd_dbri * dbri, int pipe)
1684 struct dbri_streaminfo *info; 1709 struct dbri_streaminfo *info;
1685 int td; 1710 int td;
1686 int status; 1711 int status;
1687 int len;
1688 1712
1689 info = &dbri->stream_info[DBRI_PLAY]; 1713 info = &dbri->stream_info[DBRI_PLAY];
1690 1714
@@ -1703,20 +1727,7 @@ static void transmission_complete_intr(struct snd_dbri * dbri, int pipe)
1703 dprintk(D_INT, "TD %d, status 0x%02x\n", td, status); 1727 dprintk(D_INT, "TD %d, status 0x%02x\n", td, status);
1704 1728
1705 dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */ 1729 dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */
1706 len = DBRI_RD_CNT(dbri->dma->desc[td].word1); 1730 info->offset += DBRI_RD_CNT(dbri->dma->desc[td].word1);
1707 info->offset += len;
1708 info->left -= len;
1709
1710 /* On the last TD, transmit them all again. */
1711 if (dbri->next_desc[td] == -1) {
1712 if (info->left > 0) {
1713 printk(KERN_WARNING
1714 "%d bytes left after last transfer.\n",
1715 info->left);
1716 info->left = 0;
1717 }
1718 tasklet_schedule(&xmit_descs_task);
1719 }
1720 1731
1721 td = dbri->next_desc[td]; 1732 td = dbri->next_desc[td];
1722 dbri->pipes[pipe].desc = td; 1733 dbri->pipes[pipe].desc = td;
@@ -1749,7 +1760,6 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe)
1749 1760
1750 info = &dbri->stream_info[DBRI_REC]; 1761 info = &dbri->stream_info[DBRI_REC];
1751 info->offset += DBRI_RD_CNT(status); 1762 info->offset += DBRI_RD_CNT(status);
1752 info->left += DBRI_RD_CNT(status);
1753 1763
1754 /* FIXME: Check status */ 1764 /* FIXME: Check status */
1755 1765
@@ -1757,6 +1767,7 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe)
1757 rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); 1767 rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status));
1758 1768
1759 /* On the last TD, transmit them all again. */ 1769 /* On the last TD, transmit them all again. */
1770#if 0
1760 if (dbri->next_desc[rd] == -1) { 1771 if (dbri->next_desc[rd] == -1) {
1761 if (info->left > info->size) { 1772 if (info->left > info->size) {
1762 printk(KERN_WARNING 1773 printk(KERN_WARNING
@@ -1765,6 +1776,7 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe)
1765 } 1776 }
1766 tasklet_schedule(&xmit_descs_task); 1777 tasklet_schedule(&xmit_descs_task);
1767 } 1778 }
1779#endif
1768 1780
1769 /* Notify ALSA */ 1781 /* Notify ALSA */
1770 if (spin_is_locked(&dbri->lock)) { 1782 if (spin_is_locked(&dbri->lock)) {
@@ -1793,16 +1805,11 @@ static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x)
1793 channel, code, rval); 1805 channel, code, rval);
1794 } 1806 }
1795 1807
1796 if (channel == D_INTR_CMD && command == D_WAIT) {
1797 dbri->wait_ackd = val;
1798 if (dbri->wait_send != val) {
1799 printk(KERN_ERR "Processing wait command %d when %d was send.\n",
1800 val, dbri->wait_send);
1801 }
1802 return;
1803 }
1804
1805 switch (code) { 1808 switch (code) {
1809 case D_INTR_CMDI:
1810 if (command != D_WAIT)
1811 printk(KERN_ERR "DBRI: Command read interrupt\n");
1812 break;
1806 case D_INTR_BRDY: 1813 case D_INTR_BRDY:
1807 reception_complete_intr(dbri, channel); 1814 reception_complete_intr(dbri, channel);
1808 break; 1815 break;
@@ -1815,8 +1822,10 @@ static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x)
1815 * resend SDP command with clear pipe bit (C) set 1822 * resend SDP command with clear pipe bit (C) set
1816 */ 1823 */
1817 { 1824 {
1818 volatile s32 *cmd; 1825 /* FIXME: do something useful in case of underrun */
1819 1826 printk(KERN_ERR "DBRI: Underrun error\n");
1827#if 0
1828 s32 *cmd;
1820 int pipe = channel; 1829 int pipe = channel;
1821 int td = dbri->pipes[pipe].desc; 1830 int td = dbri->pipes[pipe].desc;
1822 1831
@@ -1827,6 +1836,7 @@ static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x)
1827 | D_SDP_P | D_SDP_C | D_SDP_2SAME); 1836 | D_SDP_P | D_SDP_C | D_SDP_2SAME);
1828 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td); 1837 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td);
1829 dbri_cmdsend(dbri, cmd); 1838 dbri_cmdsend(dbri, cmd);
1839#endif
1830 } 1840 }
1831 break; 1841 break;
1832 case D_INTR_FXDT: 1842 case D_INTR_FXDT:
@@ -1847,9 +1857,7 @@ static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x)
1847/* dbri_process_interrupt_buffer advances through the DBRI's interrupt 1857/* dbri_process_interrupt_buffer advances through the DBRI's interrupt
1848 * buffer until it finds a zero word (indicating nothing more to do 1858 * buffer until it finds a zero word (indicating nothing more to do
1849 * right now). Non-zero words require processing and are handed off 1859 * right now). Non-zero words require processing and are handed off
1850 * to dbri_process_one_interrupt AFTER advancing the pointer. This 1860 * to dbri_process_one_interrupt AFTER advancing the pointer.
1851 * order is important since we might recurse back into this function
1852 * and need to make sure the pointer has been advanced first.
1853 */ 1861 */
1854static void dbri_process_interrupt_buffer(struct snd_dbri * dbri) 1862static void dbri_process_interrupt_buffer(struct snd_dbri * dbri)
1855{ 1863{
@@ -1919,8 +1927,6 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id,
1919 1927
1920 dbri_process_interrupt_buffer(dbri); 1928 dbri_process_interrupt_buffer(dbri);
1921 1929
1922 /* FIXME: Write 0 into regs to ACK interrupt */
1923
1924 spin_unlock(&dbri->lock); 1930 spin_unlock(&dbri->lock);
1925 1931
1926 return IRQ_HANDLED; 1932 return IRQ_HANDLED;
@@ -1962,7 +1968,6 @@ static int snd_dbri_open(struct snd_pcm_substream *substream)
1962 1968
1963 spin_lock_irqsave(&dbri->lock, flags); 1969 spin_lock_irqsave(&dbri->lock, flags);
1964 info->substream = substream; 1970 info->substream = substream;
1965 info->left = 0;
1966 info->offset = 0; 1971 info->offset = 0;
1967 info->dvma_buffer = 0; 1972 info->dvma_buffer = 0;
1968 info->pipe = -1; 1973 info->pipe = -1;
@@ -1980,7 +1985,6 @@ static int snd_dbri_close(struct snd_pcm_substream *substream)
1980 1985
1981 dprintk(D_USR, "close audio output.\n"); 1986 dprintk(D_USR, "close audio output.\n");
1982 info->substream = NULL; 1987 info->substream = NULL;
1983 info->left = 0;
1984 info->offset = 0; 1988 info->offset = 0;
1985 1989
1986 return 0; 1990 return 0;
@@ -2062,10 +2066,8 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream)
2062 info->size = snd_pcm_lib_buffer_bytes(substream); 2066 info->size = snd_pcm_lib_buffer_bytes(substream);
2063 if (DBRI_STREAMNO(substream) == DBRI_PLAY) 2067 if (DBRI_STREAMNO(substream) == DBRI_PLAY)
2064 info->pipe = 4; /* Send pipe */ 2068 info->pipe = 4; /* Send pipe */
2065 else { 2069 else
2066 info->pipe = 6; /* Receive pipe */ 2070 info->pipe = 6; /* Receive pipe */
2067 info->left = info->size; /* To trigger submittal */
2068 }
2069 2071
2070 spin_lock_irq(&dbri->lock); 2072 spin_lock_irq(&dbri->lock);
2071 2073
@@ -2093,14 +2095,11 @@ static int snd_dbri_trigger(struct snd_pcm_substream *substream, int cmd)
2093 case SNDRV_PCM_TRIGGER_START: 2095 case SNDRV_PCM_TRIGGER_START:
2094 dprintk(D_USR, "start audio, period is %d bytes\n", 2096 dprintk(D_USR, "start audio, period is %d bytes\n",
2095 (int)snd_pcm_lib_period_bytes(substream)); 2097 (int)snd_pcm_lib_period_bytes(substream));
2096 /* Enable & schedule the tasklet that re-submits the TDs. */ 2098 /* Re-submit the TDs. */
2097 xmit_descs_task.data = (unsigned long)dbri; 2099 xmit_descs(dbri);
2098 tasklet_schedule(&xmit_descs_task);
2099 break; 2100 break;
2100 case SNDRV_PCM_TRIGGER_STOP: 2101 case SNDRV_PCM_TRIGGER_STOP:
2101 dprintk(D_USR, "stop audio.\n"); 2102 dprintk(D_USR, "stop audio.\n");
2102 /* Make the tasklet bail out immediately. */
2103 xmit_descs_task.data = 0;
2104 reset_pipe(dbri, info->pipe); 2103 reset_pipe(dbri, info->pipe);
2105 break; 2104 break;
2106 default: 2105 default:
@@ -2118,8 +2117,8 @@ static snd_pcm_uframes_t snd_dbri_pointer(struct snd_pcm_substream *substream)
2118 2117
2119 ret = bytes_to_frames(substream->runtime, info->offset) 2118 ret = bytes_to_frames(substream->runtime, info->offset)
2120 % substream->runtime->buffer_size; 2119 % substream->runtime->buffer_size;
2121 dprintk(D_USR, "I/O pointer: %ld frames, %d bytes left.\n", 2120 dprintk(D_USR, "I/O pointer: %ld frames of %ld.\n",
2122 ret, info->left); 2121 ret, substream->runtime->buffer_size);
2123 return ret; 2122 return ret;
2124} 2123}
2125 2124