diff options
Diffstat (limited to 'sound/sparc/dbri.c')
-rw-r--r-- | sound/sparc/dbri.c | 817 |
1 files changed, 387 insertions, 430 deletions
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index f3ae6e23610e..e4935fca12df 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) |
@@ -34,7 +36,7 @@ | |||
34 | * (the second one is a monitor/tee pipe, valid only for serial input). | 36 | * (the second one is a monitor/tee pipe, valid only for serial input). |
35 | * | 37 | * |
36 | * The mmcodec is connected via the CHI bus and needs the data & some | 38 | * The mmcodec is connected via the CHI bus and needs the data & some |
37 | * parameters (volume, balance, output selection) timemultiplexed in 8 byte | 39 | * parameters (volume, output selection) timemultiplexed in 8 byte |
38 | * chunks. It also has a control mode, which serves for audio format setting. | 40 | * chunks. It also has a control mode, which serves for audio format setting. |
39 | * | 41 | * |
40 | * Looking at the CS4215 data sheet it is easy to set up 2 or 4 codecs on | 42 | * Looking at the CS4215 data sheet it is easy to set up 2 or 4 codecs on |
@@ -83,7 +85,7 @@ MODULE_PARM_DESC(id, "ID string for Sun DBRI soundcard."); | |||
83 | module_param_array(enable, bool, NULL, 0444); | 85 | module_param_array(enable, bool, NULL, 0444); |
84 | MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard."); | 86 | MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard."); |
85 | 87 | ||
86 | #define DBRI_DEBUG | 88 | #undef DBRI_DEBUG |
87 | 89 | ||
88 | #define D_INT (1<<0) | 90 | #define D_INT (1<<0) |
89 | #define D_GEN (1<<1) | 91 | #define D_GEN (1<<1) |
@@ -104,17 +106,15 @@ static char *cmds[] = { | |||
104 | 106 | ||
105 | #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) |
106 | 108 | ||
107 | #define DBRI_CMD(cmd, intr, value) ((cmd << 28) | \ | ||
108 | (1 << 27) | \ | ||
109 | value) | ||
110 | #else | 109 | #else |
111 | #define dprintk(a, x...) | 110 | #define dprintk(a, x...) do { } while (0) |
112 | 111 | ||
113 | #define DBRI_CMD(cmd, intr, value) ((cmd << 28) | \ | ||
114 | (intr << 27) | \ | ||
115 | value) | ||
116 | #endif /* DBRI_DEBUG */ | 112 | #endif /* DBRI_DEBUG */ |
117 | 113 | ||
114 | #define DBRI_CMD(cmd, intr, value) ((cmd << 28) | \ | ||
115 | (intr << 27) | \ | ||
116 | value) | ||
117 | |||
118 | /*************************************************************************** | 118 | /*************************************************************************** |
119 | CS4215 specific definitions and structures | 119 | CS4215 specific definitions and structures |
120 | ****************************************************************************/ | 120 | ****************************************************************************/ |
@@ -160,7 +160,7 @@ static struct { | |||
160 | /* { NA, (1 << 4), (5 << 3) }, */ | 160 | /* { NA, (1 << 4), (5 << 3) }, */ |
161 | { 48000, (1 << 4), (6 << 3) }, | 161 | { 48000, (1 << 4), (6 << 3) }, |
162 | { 9600, (1 << 4), (7 << 3) }, | 162 | { 9600, (1 << 4), (7 << 3) }, |
163 | { 5513, (2 << 4), (0 << 3) }, /* Actually 5512.5 */ | 163 | { 5512, (2 << 4), (0 << 3) }, /* Actually 5512.5 */ |
164 | { 11025, (2 << 4), (1 << 3) }, | 164 | { 11025, (2 << 4), (1 << 3) }, |
165 | { 18900, (2 << 4), (2 << 3) }, | 165 | { 18900, (2 << 4), (2 << 3) }, |
166 | { 22050, (2 << 4), (3 << 3) }, | 166 | { 22050, (2 << 4), (3 << 3) }, |
@@ -240,28 +240,21 @@ static struct { | |||
240 | #define REG9 0x24UL /* Interrupt Queue Pointer */ | 240 | #define REG9 0x24UL /* Interrupt Queue Pointer */ |
241 | 241 | ||
242 | #define DBRI_NO_CMDS 64 | 242 | #define DBRI_NO_CMDS 64 |
243 | #define DBRI_NO_INTS 1 /* Note: the value of this define was | ||
244 | * originally 2. The ringbuffer to store | ||
245 | * interrupts in dma is currently broken. | ||
246 | * This is a temporary fix until the ringbuffer | ||
247 | * is fixed. | ||
248 | */ | ||
249 | #define DBRI_INT_BLK 64 | 243 | #define DBRI_INT_BLK 64 |
250 | #define DBRI_NO_DESCS 64 | 244 | #define DBRI_NO_DESCS 64 |
251 | #define DBRI_NO_PIPES 32 | 245 | #define DBRI_NO_PIPES 32 |
252 | 246 | #define DBRI_MAX_PIPE (DBRI_NO_PIPES - 1) | |
253 | #define DBRI_MM_ONB 1 | ||
254 | #define DBRI_MM_SB 2 | ||
255 | 247 | ||
256 | #define DBRI_REC 0 | 248 | #define DBRI_REC 0 |
257 | #define DBRI_PLAY 1 | 249 | #define DBRI_PLAY 1 |
258 | #define DBRI_NO_STREAMS 2 | 250 | #define DBRI_NO_STREAMS 2 |
259 | 251 | ||
260 | /* One transmit/receive descriptor */ | 252 | /* One transmit/receive descriptor */ |
253 | /* When ba != 0 descriptor is used */ | ||
261 | struct dbri_mem { | 254 | struct dbri_mem { |
262 | volatile __u32 word1; | 255 | volatile __u32 word1; |
263 | volatile __u32 ba; /* Transmit/Receive Buffer Address */ | 256 | __u32 ba; /* Transmit/Receive Buffer Address */ |
264 | volatile __u32 nda; /* Next Descriptor Address */ | 257 | __u32 nda; /* Next Descriptor Address */ |
265 | volatile __u32 word4; | 258 | volatile __u32 word4; |
266 | }; | 259 | }; |
267 | 260 | ||
@@ -269,8 +262,8 @@ struct dbri_mem { | |||
269 | * the CPU and the DBRI | 262 | * the CPU and the DBRI |
270 | */ | 263 | */ |
271 | struct dbri_dma { | 264 | struct dbri_dma { |
272 | volatile s32 cmd[DBRI_NO_CMDS]; /* Place for commands */ | 265 | s32 cmd[DBRI_NO_CMDS]; /* Place for commands */ |
273 | volatile s32 intr[DBRI_NO_INTS * DBRI_INT_BLK]; /* Interrupt field */ | 266 | volatile s32 intr[DBRI_INT_BLK]; /* Interrupt field */ |
274 | struct dbri_mem desc[DBRI_NO_DESCS]; /* Xmit/receive descriptors */ | 267 | struct dbri_mem desc[DBRI_NO_DESCS]; /* Xmit/receive descriptors */ |
275 | }; | 268 | }; |
276 | 269 | ||
@@ -282,58 +275,43 @@ enum in_or_out { PIPEinput, PIPEoutput }; | |||
282 | 275 | ||
283 | struct dbri_pipe { | 276 | struct dbri_pipe { |
284 | u32 sdp; /* SDP command word */ | 277 | u32 sdp; /* SDP command word */ |
285 | enum in_or_out direction; | ||
286 | int nextpipe; /* Next pipe in linked list */ | 278 | int nextpipe; /* Next pipe in linked list */ |
287 | int prevpipe; | ||
288 | int cycle; /* Offset of timeslot (bits) */ | ||
289 | int length; /* Length of timeslot (bits) */ | 279 | int length; /* Length of timeslot (bits) */ |
290 | int first_desc; /* Index of first descriptor */ | 280 | int first_desc; /* Index of first descriptor */ |
291 | int desc; /* Index of active descriptor */ | 281 | int desc; /* Index of active descriptor */ |
292 | volatile __u32 *recv_fixed_ptr; /* Ptr to receive fixed data */ | 282 | volatile __u32 *recv_fixed_ptr; /* Ptr to receive fixed data */ |
293 | }; | 283 | }; |
294 | 284 | ||
295 | struct dbri_desc { | ||
296 | int inuse; /* Boolean flag */ | ||
297 | int next; /* Index of next desc, or -1 */ | ||
298 | unsigned int len; | ||
299 | }; | ||
300 | |||
301 | /* Per stream (playback or record) information */ | 285 | /* Per stream (playback or record) information */ |
302 | struct dbri_streaminfo { | 286 | struct dbri_streaminfo { |
303 | struct snd_pcm_substream *substream; | 287 | struct snd_pcm_substream *substream; |
304 | u32 dvma_buffer; /* Device view of Alsa DMA buffer */ | 288 | u32 dvma_buffer; /* Device view of Alsa DMA buffer */ |
305 | int left; /* # of bytes left in DMA buffer */ | ||
306 | int size; /* Size of DMA buffer */ | 289 | int size; /* Size of DMA buffer */ |
307 | size_t offset; /* offset in user buffer */ | 290 | size_t offset; /* offset in user buffer */ |
308 | int pipe; /* Data pipe used */ | 291 | int pipe; /* Data pipe used */ |
309 | int left_gain; /* mixer elements */ | 292 | int left_gain; /* mixer elements */ |
310 | int right_gain; | 293 | int right_gain; |
311 | int balance; | ||
312 | }; | 294 | }; |
313 | 295 | ||
314 | /* This structure holds the information for both chips (DBRI & CS4215) */ | 296 | /* This structure holds the information for both chips (DBRI & CS4215) */ |
315 | struct snd_dbri { | 297 | struct snd_dbri { |
316 | struct snd_card *card; /* ALSA card */ | 298 | struct snd_card *card; /* ALSA card */ |
317 | struct snd_pcm *pcm; | ||
318 | 299 | ||
319 | int regs_size, irq; /* Needed for unload */ | 300 | int regs_size, irq; /* Needed for unload */ |
320 | struct sbus_dev *sdev; /* SBUS device info */ | 301 | struct sbus_dev *sdev; /* SBUS device info */ |
321 | spinlock_t lock; | 302 | spinlock_t lock; |
322 | 303 | ||
323 | volatile struct dbri_dma *dma; /* Pointer to our DMA block */ | 304 | struct dbri_dma *dma; /* Pointer to our DMA block */ |
324 | u32 dma_dvma; /* DBRI visible DMA address */ | 305 | u32 dma_dvma; /* DBRI visible DMA address */ |
325 | 306 | ||
326 | void __iomem *regs; /* dbri HW regs */ | 307 | void __iomem *regs; /* dbri HW regs */ |
327 | int dbri_version; /* 'e' and up is OK */ | ||
328 | int dbri_irqp; /* intr queue pointer */ | 308 | int dbri_irqp; /* intr queue pointer */ |
329 | int wait_send; /* sequence of command buffers send */ | ||
330 | int wait_ackd; /* sequence of command buffers acknowledged */ | ||
331 | 309 | ||
332 | 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 */ |
333 | struct dbri_desc descs[DBRI_NO_DESCS]; | 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 */ | ||
334 | 314 | ||
335 | int chi_in_pipe; | ||
336 | int chi_out_pipe; | ||
337 | int chi_bpf; | 315 | int chi_bpf; |
338 | 316 | ||
339 | struct cs4215 mm; /* mmcodec special info */ | 317 | struct cs4215 mm; /* mmcodec special info */ |
@@ -345,8 +323,6 @@ struct snd_dbri { | |||
345 | 323 | ||
346 | #define DBRI_MAX_VOLUME 63 /* Output volume */ | 324 | #define DBRI_MAX_VOLUME 63 /* Output volume */ |
347 | #define DBRI_MAX_GAIN 15 /* Input gain */ | 325 | #define DBRI_MAX_GAIN 15 /* Input gain */ |
348 | #define DBRI_RIGHT_BALANCE 255 | ||
349 | #define DBRI_MID_BALANCE (DBRI_RIGHT_BALANCE >> 1) | ||
350 | 326 | ||
351 | /* DBRI Reg0 - Status Control Register - defines. (Page 17) */ | 327 | /* DBRI Reg0 - Status Control Register - defines. (Page 17) */ |
352 | #define D_P (1<<15) /* Program command & queue pointer valid */ | 328 | #define D_P (1<<15) /* Program command & queue pointer valid */ |
@@ -569,7 +545,7 @@ struct snd_dbri { | |||
569 | #define DBRI_TD_TBC (1<<0) /* Transmit buffer Complete */ | 545 | #define DBRI_TD_TBC (1<<0) /* Transmit buffer Complete */ |
570 | #define DBRI_TD_STATUS(v) ((v)&0xff) /* Transmit status */ | 546 | #define DBRI_TD_STATUS(v) ((v)&0xff) /* Transmit status */ |
571 | /* Maximum buffer size per TD: almost 8Kb */ | 547 | /* Maximum buffer size per TD: almost 8Kb */ |
572 | #define DBRI_TD_MAXCNT ((1 << 13) - 1) | 548 | #define DBRI_TD_MAXCNT ((1 << 13) - 4) |
573 | 549 | ||
574 | /* Receive descriptor defines */ | 550 | /* Receive descriptor defines */ |
575 | #define DBRI_RD_F (1<<31) /* End of Frame */ | 551 | #define DBRI_RD_F (1<<31) /* End of Frame */ |
@@ -633,93 +609,124 @@ The list is terminated with a WAIT command, which generates a | |||
633 | CPU interrupt to signal completion. | 609 | CPU interrupt to signal completion. |
634 | 610 | ||
635 | 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 |
636 | synchronization present themselves. The method implemented here is close | 612 | synchronization present themselves. The method implemented here is only |
637 | to the original scheme (Rudolf's), and uses 2 counters (wait_send and | 613 | use of the dbri_cmdwait() to wait for execution of batch of sent commands. |
638 | wait_ackd) to synchronize the command buffer between the CPU and the DBRI. | ||
639 | 614 | ||
640 | A more sophisticated scheme might involve a circular command buffer | 615 | A circular command buffer is used here. A new command is being added |
641 | or an array of command buffers. A routine could fill one with | 616 | while another can be executed. The scheme works by adding two WAIT commands |
642 | commands and link it onto a list. When a interrupt signaled | 617 | after each sent batch of commands. When the next batch is prepared it is |
643 | completion of the current command buffer, look on the list for | 618 | added after the WAIT commands then the WAITs are replaced with single JUMP |
644 | the next one. | 619 | command to the new batch. The the DBRI is forced to reread the last WAIT |
620 | command (replaced by the JUMP by then). If the DBRI is still executing | ||
621 | previous commands the request to reread the WAIT command is ignored. | ||
645 | 622 | ||
646 | Every time a routine wants to write commands to the DBRI, it must | 623 | Every time a routine wants to write commands to the DBRI, it must |
647 | first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd | 624 | first call dbri_cmdlock() and get pointer to a free space in |
648 | in return. dbri_cmdlock() will block if the previous commands have not | 625 | dbri->dma->cmd buffer. After this, the commands can be written to |
649 | been completed yet. After this the commands can be written to the buffer, | 626 | the buffer, and dbri_cmdsend() is called with the final pointer value |
650 | and dbri_cmdsend() is called with the final pointer value to send them | 627 | to send them to the DBRI. |
651 | to the DBRI. | ||
652 | 628 | ||
653 | */ | 629 | */ |
654 | 630 | ||
655 | static void dbri_process_interrupt_buffer(struct snd_dbri * dbri); | 631 | #define MAXLOOPS 20 |
656 | 632 | /* | |
657 | enum dbri_lock { NoGetLock, GetLock }; | 633 | * Wait for the current command string to execute |
658 | #define MAXLOOPS 10 | 634 | */ |
659 | 635 | static void dbri_cmdwait(struct snd_dbri *dbri) | |
660 | static volatile s32 *dbri_cmdlock(struct snd_dbri * dbri, enum dbri_lock get) | ||
661 | { | 636 | { |
662 | int maxloops = MAXLOOPS; | 637 | int maxloops = MAXLOOPS; |
663 | 638 | unsigned long flags; | |
664 | #ifndef SMP | ||
665 | if ((get == GetLock) && spin_is_locked(&dbri->lock)) { | ||
666 | printk(KERN_ERR "DBRI: cmdlock called while in spinlock."); | ||
667 | } | ||
668 | #endif | ||
669 | 639 | ||
670 | /* Delay if previous commands are still being processed */ | 640 | /* Delay if previous commands are still being processed */ |
671 | while ((--maxloops) > 0 && (dbri->wait_send != dbri->wait_ackd)) { | 641 | spin_lock_irqsave(&dbri->lock, flags); |
642 | while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P)) { | ||
643 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
672 | msleep_interruptible(1); | 644 | msleep_interruptible(1); |
673 | /* If dbri_cmdlock() got called from inside the | 645 | spin_lock_irqsave(&dbri->lock, flags); |
674 | * interrupt handler, this will do the processing. | ||
675 | */ | ||
676 | dbri_process_interrupt_buffer(dbri); | ||
677 | } | 646 | } |
647 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
648 | |||
678 | if (maxloops == 0) { | 649 | if (maxloops == 0) { |
679 | printk(KERN_ERR "DBRI: Chip never completed command buffer %d\n", | 650 | printk(KERN_ERR "DBRI: Chip never completed command buffer\n"); |
680 | dbri->wait_send); | ||
681 | } else { | 651 | } else { |
682 | dprintk(D_CMD, "Chip completed command buffer (%d)\n", | 652 | dprintk(D_CMD, "Chip completed command buffer (%d)\n", |
683 | MAXLOOPS - maxloops - 1); | 653 | MAXLOOPS - maxloops - 1); |
684 | } | 654 | } |
655 | } | ||
656 | /* | ||
657 | * Lock the command queue and returns pointer to a space for len cmd words | ||
658 | * It locks the cmdlock spinlock. | ||
659 | */ | ||
660 | static s32 *dbri_cmdlock(struct snd_dbri * dbri, int len) | ||
661 | { | ||
662 | /* Space for 2 WAIT cmds (replaced later by 1 JUMP cmd) */ | ||
663 | len += 2; | ||
664 | spin_lock(&dbri->cmdlock); | ||
665 | if (dbri->cmdptr - dbri->dma->cmd + len < DBRI_NO_CMDS - 2) | ||
666 | return dbri->cmdptr + 2; | ||
667 | else if (len < sbus_readl(dbri->regs + REG8) - dbri->dma_dvma) | ||
668 | return dbri->dma->cmd; | ||
669 | else | ||
670 | printk(KERN_ERR "DBRI: no space for commands."); | ||
685 | 671 | ||
686 | /*if (get == GetLock) spin_lock(&dbri->lock); */ | 672 | return 0; |
687 | return &dbri->dma->cmd[0]; | ||
688 | } | 673 | } |
689 | 674 | ||
690 | static void dbri_cmdsend(struct snd_dbri * dbri, volatile s32 * cmd) | 675 | /* |
676 | * Send prepared cmd string. It works by writting a JUMP cmd into | ||
677 | * the last WAIT cmd and force DBRI to reread the cmd. | ||
678 | * The JUMP cmd points to the new cmd string. | ||
679 | * It also releases the cmdlock spinlock. | ||
680 | * | ||
681 | * Lock must not be held before calling this. | ||
682 | */ | ||
683 | static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len) | ||
691 | { | 684 | { |
692 | volatile s32 *ptr; | 685 | s32 tmp, addr; |
693 | u32 reg; | 686 | static int wait_id = 0; |
694 | 687 | ||
695 | for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) { | 688 | wait_id++; |
696 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | 689 | wait_id &= 0xffff; /* restrict it to a 16 bit counter. */ |
697 | } | 690 | *(cmd) = DBRI_CMD(D_WAIT, 1, wait_id); |
691 | *(cmd+1) = DBRI_CMD(D_WAIT, 1, wait_id); | ||
698 | 692 | ||
699 | if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) { | 693 | /* Replace the last command with JUMP */ |
700 | printk(KERN_ERR "DBRI: Command buffer overflow! (bug in driver)\n"); | 694 | addr = dbri->dma_dvma + (cmd - len - dbri->dma->cmd) * sizeof(s32); |
701 | /* Ignore the last part. */ | 695 | *(dbri->cmdptr+1) = addr; |
702 | cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3]; | 696 | *(dbri->cmdptr) = DBRI_CMD(D_JUMP, 0, 0); |
703 | } | ||
704 | 697 | ||
705 | dbri->wait_send++; | 698 | #ifdef DBRI_DEBUG |
706 | dbri->wait_send &= 0xffff; /* restrict it to a 16 bit counter. */ | 699 | if (cmd > dbri->cmdptr) { |
707 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | 700 | s32 *ptr; |
708 | *(cmd++) = DBRI_CMD(D_WAIT, 1, dbri->wait_send); | 701 | |
702 | for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++) | ||
703 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | ||
704 | } else { | ||
705 | s32 *ptr = dbri->cmdptr; | ||
706 | |||
707 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | ||
708 | ptr++; | ||
709 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | ||
710 | for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++) { | ||
711 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | ||
712 | } | ||
713 | } | ||
714 | #endif | ||
709 | 715 | ||
710 | /* Set command pointer and signal it is valid. */ | 716 | /* Reread the last command */ |
711 | sbus_writel(dbri->dma_dvma, dbri->regs + REG8); | 717 | tmp = sbus_readl(dbri->regs + REG0); |
712 | reg = sbus_readl(dbri->regs + REG0); | 718 | tmp |= D_P; |
713 | reg |= D_P; | 719 | sbus_writel(tmp, dbri->regs + REG0); |
714 | sbus_writel(reg, dbri->regs + REG0); | ||
715 | 720 | ||
716 | /*spin_unlock(&dbri->lock); */ | 721 | dbri->cmdptr = cmd; |
722 | spin_unlock(&dbri->cmdlock); | ||
717 | } | 723 | } |
718 | 724 | ||
719 | /* Lock must be held when calling this */ | 725 | /* Lock must be held when calling this */ |
720 | static void dbri_reset(struct snd_dbri * dbri) | 726 | static void dbri_reset(struct snd_dbri * dbri) |
721 | { | 727 | { |
722 | int i; | 728 | int i; |
729 | u32 tmp; | ||
723 | 730 | ||
724 | dprintk(D_GEN, "reset 0:%x 2:%x 8:%x 9:%x\n", | 731 | dprintk(D_GEN, "reset 0:%x 2:%x 8:%x 9:%x\n", |
725 | sbus_readl(dbri->regs + REG0), | 732 | sbus_readl(dbri->regs + REG0), |
@@ -729,13 +736,20 @@ static void dbri_reset(struct snd_dbri * dbri) | |||
729 | sbus_writel(D_R, dbri->regs + REG0); /* Soft Reset */ | 736 | sbus_writel(D_R, dbri->regs + REG0); /* Soft Reset */ |
730 | for (i = 0; (sbus_readl(dbri->regs + REG0) & D_R) && i < 64; i++) | 737 | for (i = 0; (sbus_readl(dbri->regs + REG0) & D_R) && i < 64; i++) |
731 | udelay(10); | 738 | udelay(10); |
739 | |||
740 | /* A brute approach - DBRI falls back to working burst size by itself | ||
741 | * On SS20 D_S does not work, so do not try so high. */ | ||
742 | tmp = sbus_readl(dbri->regs + REG0); | ||
743 | tmp |= D_G | D_E; | ||
744 | tmp &= ~D_S; | ||
745 | sbus_writel(tmp, dbri->regs + REG0); | ||
732 | } | 746 | } |
733 | 747 | ||
734 | /* Lock must not be held before calling this */ | 748 | /* Lock must not be held before calling this */ |
735 | static void dbri_initialize(struct snd_dbri * dbri) | 749 | static void dbri_initialize(struct snd_dbri * dbri) |
736 | { | 750 | { |
737 | volatile s32 *cmd; | 751 | s32 *cmd; |
738 | u32 dma_addr, tmp; | 752 | u32 dma_addr; |
739 | unsigned long flags; | 753 | unsigned long flags; |
740 | int n; | 754 | int n; |
741 | 755 | ||
@@ -743,42 +757,34 @@ static void dbri_initialize(struct snd_dbri * dbri) | |||
743 | 757 | ||
744 | dbri_reset(dbri); | 758 | dbri_reset(dbri); |
745 | 759 | ||
746 | cmd = dbri_cmdlock(dbri, NoGetLock); | 760 | /* Initialize pipes */ |
747 | dprintk(D_GEN, "init: cmd: %p, int: %p\n", | 761 | for (n = 0; n < DBRI_NO_PIPES; n++) |
748 | &dbri->dma->cmd[0], &dbri->dma->intr[0]); | 762 | dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1; |
749 | 763 | ||
764 | spin_lock_init(&dbri->cmdlock); | ||
750 | /* | 765 | /* |
751 | * Initialize the interrupt ringbuffer. | 766 | * Initialize the interrupt ringbuffer. |
752 | */ | 767 | */ |
753 | for (n = 0; n < DBRI_NO_INTS - 1; n++) { | ||
754 | dma_addr = dbri->dma_dvma; | ||
755 | dma_addr += dbri_dma_off(intr, ((n + 1) & DBRI_INT_BLK)); | ||
756 | dbri->dma->intr[n * DBRI_INT_BLK] = dma_addr; | ||
757 | } | ||
758 | dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0); | 768 | dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0); |
759 | dbri->dma->intr[n * DBRI_INT_BLK] = dma_addr; | 769 | dbri->dma->intr[0] = dma_addr; |
760 | dbri->dbri_irqp = 1; | 770 | dbri->dbri_irqp = 1; |
761 | |||
762 | /* Initialize pipes */ | ||
763 | for (n = 0; n < DBRI_NO_PIPES; n++) | ||
764 | dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1; | ||
765 | |||
766 | /* A brute approach - DBRI falls back to working burst size by itself | ||
767 | * On SS20 D_S does not work, so do not try so high. */ | ||
768 | tmp = sbus_readl(dbri->regs + REG0); | ||
769 | tmp |= D_G | D_E; | ||
770 | tmp &= ~D_S; | ||
771 | sbus_writel(tmp, dbri->regs + REG0); | ||
772 | |||
773 | /* | 771 | /* |
774 | * Set up the interrupt queue | 772 | * Set up the interrupt queue |
775 | */ | 773 | */ |
776 | dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0); | 774 | spin_lock(&dbri->cmdlock); |
775 | cmd = dbri->cmdptr = dbri->dma->cmd; | ||
777 | *(cmd++) = DBRI_CMD(D_IIQ, 0, 0); | 776 | *(cmd++) = DBRI_CMD(D_IIQ, 0, 0); |
778 | *(cmd++) = dma_addr; | 777 | *(cmd++) = dma_addr; |
778 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | ||
779 | dbri->cmdptr = cmd; | ||
780 | *(cmd++) = DBRI_CMD(D_WAIT, 1, 0); | ||
781 | *(cmd++) = DBRI_CMD(D_WAIT, 1, 0); | ||
782 | dma_addr = dbri->dma_dvma + dbri_dma_off(cmd, 0); | ||
783 | sbus_writel(dma_addr, dbri->regs + REG8); | ||
784 | spin_unlock(&dbri->cmdlock); | ||
779 | 785 | ||
780 | dbri_cmdsend(dbri, cmd); | ||
781 | spin_unlock_irqrestore(&dbri->lock, flags); | 786 | spin_unlock_irqrestore(&dbri->lock, flags); |
787 | dbri_cmdwait(dbri); | ||
782 | } | 788 | } |
783 | 789 | ||
784 | /* | 790 | /* |
@@ -809,9 +815,9 @@ static void reset_pipe(struct snd_dbri * dbri, int pipe) | |||
809 | { | 815 | { |
810 | int sdp; | 816 | int sdp; |
811 | int desc; | 817 | int desc; |
812 | volatile int *cmd; | 818 | s32 *cmd; |
813 | 819 | ||
814 | if (pipe < 0 || pipe > 31) { | 820 | if (pipe < 0 || pipe > DBRI_MAX_PIPE) { |
815 | printk(KERN_ERR "DBRI: reset_pipe called with illegal pipe number\n"); | 821 | printk(KERN_ERR "DBRI: reset_pipe called with illegal pipe number\n"); |
816 | return; | 822 | return; |
817 | } | 823 | } |
@@ -822,25 +828,29 @@ static void reset_pipe(struct snd_dbri * dbri, int pipe) | |||
822 | return; | 828 | return; |
823 | } | 829 | } |
824 | 830 | ||
825 | cmd = dbri_cmdlock(dbri, NoGetLock); | 831 | cmd = dbri_cmdlock(dbri, 3); |
826 | *(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P); | 832 | *(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P); |
827 | *(cmd++) = 0; | 833 | *(cmd++) = 0; |
828 | dbri_cmdsend(dbri, cmd); | 834 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); |
835 | dbri_cmdsend(dbri, cmd, 3); | ||
829 | 836 | ||
830 | desc = dbri->pipes[pipe].first_desc; | 837 | desc = dbri->pipes[pipe].first_desc; |
831 | while (desc != -1) { | 838 | if ( desc >= 0) |
832 | dbri->descs[desc].inuse = 0; | 839 | do { |
833 | desc = dbri->descs[desc].next; | 840 | dbri->dma->desc[desc].nda = dbri->dma->desc[desc].ba = 0; |
834 | } | 841 | desc = dbri->next_desc[desc]; |
842 | } while (desc != -1 && desc != dbri->pipes[pipe].first_desc); | ||
835 | 843 | ||
836 | dbri->pipes[pipe].desc = -1; | 844 | dbri->pipes[pipe].desc = -1; |
837 | dbri->pipes[pipe].first_desc = -1; | 845 | dbri->pipes[pipe].first_desc = -1; |
838 | } | 846 | } |
839 | 847 | ||
840 | /* FIXME: direction as an argument? */ | 848 | /* |
849 | * Lock must be held before calling this. | ||
850 | */ | ||
841 | static void setup_pipe(struct snd_dbri * dbri, int pipe, int sdp) | 851 | static void setup_pipe(struct snd_dbri * dbri, int pipe, int sdp) |
842 | { | 852 | { |
843 | if (pipe < 0 || pipe > 31) { | 853 | if (pipe < 0 || pipe > DBRI_MAX_PIPE) { |
844 | printk(KERN_ERR "DBRI: setup_pipe called with illegal pipe number\n"); | 854 | printk(KERN_ERR "DBRI: setup_pipe called with illegal pipe number\n"); |
845 | return; | 855 | return; |
846 | } | 856 | } |
@@ -860,119 +870,87 @@ static void setup_pipe(struct snd_dbri * dbri, int pipe, int sdp) | |||
860 | dbri->pipes[pipe].sdp = sdp; | 870 | dbri->pipes[pipe].sdp = sdp; |
861 | dbri->pipes[pipe].desc = -1; | 871 | dbri->pipes[pipe].desc = -1; |
862 | dbri->pipes[pipe].first_desc = -1; | 872 | dbri->pipes[pipe].first_desc = -1; |
863 | if (sdp & D_SDP_TO_SER) | ||
864 | dbri->pipes[pipe].direction = PIPEoutput; | ||
865 | else | ||
866 | dbri->pipes[pipe].direction = PIPEinput; | ||
867 | 873 | ||
868 | reset_pipe(dbri, pipe); | 874 | reset_pipe(dbri, pipe); |
869 | } | 875 | } |
870 | 876 | ||
871 | /* FIXME: direction not needed */ | 877 | /* |
878 | * Lock must be held before calling this. | ||
879 | */ | ||
872 | static void link_time_slot(struct snd_dbri * dbri, int pipe, | 880 | static void link_time_slot(struct snd_dbri * dbri, int pipe, |
873 | enum in_or_out direction, int basepipe, | 881 | int prevpipe, int nextpipe, |
874 | int length, int cycle) | 882 | int length, int cycle) |
875 | { | 883 | { |
876 | volatile s32 *cmd; | 884 | s32 *cmd; |
877 | int val; | 885 | int val; |
878 | int prevpipe; | ||
879 | int nextpipe; | ||
880 | 886 | ||
881 | if (pipe < 0 || pipe > 31 || basepipe < 0 || basepipe > 31) { | 887 | if (pipe < 0 || pipe > DBRI_MAX_PIPE |
888 | || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE | ||
889 | || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) { | ||
882 | printk(KERN_ERR | 890 | printk(KERN_ERR |
883 | "DBRI: link_time_slot called with illegal pipe number\n"); | 891 | "DBRI: link_time_slot called with illegal pipe number\n"); |
884 | return; | 892 | return; |
885 | } | 893 | } |
886 | 894 | ||
887 | if (dbri->pipes[pipe].sdp == 0 || dbri->pipes[basepipe].sdp == 0) { | 895 | if (dbri->pipes[pipe].sdp == 0 |
896 | || dbri->pipes[prevpipe].sdp == 0 | ||
897 | || dbri->pipes[nextpipe].sdp == 0) { | ||
888 | printk(KERN_ERR "DBRI: link_time_slot called on uninitialized pipe\n"); | 898 | printk(KERN_ERR "DBRI: link_time_slot called on uninitialized pipe\n"); |
889 | return; | 899 | return; |
890 | } | 900 | } |
891 | 901 | ||
892 | /* Deal with CHI special case: | 902 | dbri->pipes[prevpipe].nextpipe = pipe; |
893 | * "If transmission on edges 0 or 1 is desired, then cycle n | ||
894 | * (where n = # of bit times per frame...) must be used." | ||
895 | * - DBRI data sheet, page 11 | ||
896 | */ | ||
897 | if (basepipe == 16 && direction == PIPEoutput && cycle == 0) | ||
898 | cycle = dbri->chi_bpf; | ||
899 | |||
900 | if (basepipe == pipe) { | ||
901 | prevpipe = pipe; | ||
902 | nextpipe = pipe; | ||
903 | } else { | ||
904 | /* We're not initializing a new linked list (basepipe != pipe), | ||
905 | * so run through the linked list and find where this pipe | ||
906 | * should be sloted in, based on its cycle. CHI confuses | ||
907 | * things a bit, since it has a single anchor for both its | ||
908 | * transmit and receive lists. | ||
909 | */ | ||
910 | if (basepipe == 16) { | ||
911 | if (direction == PIPEinput) { | ||
912 | prevpipe = dbri->chi_in_pipe; | ||
913 | } else { | ||
914 | prevpipe = dbri->chi_out_pipe; | ||
915 | } | ||
916 | } else { | ||
917 | prevpipe = basepipe; | ||
918 | } | ||
919 | |||
920 | nextpipe = dbri->pipes[prevpipe].nextpipe; | ||
921 | |||
922 | while (dbri->pipes[nextpipe].cycle < cycle | ||
923 | && dbri->pipes[nextpipe].nextpipe != basepipe) { | ||
924 | prevpipe = nextpipe; | ||
925 | nextpipe = dbri->pipes[nextpipe].nextpipe; | ||
926 | } | ||
927 | } | ||
928 | |||
929 | if (prevpipe == 16) { | ||
930 | if (direction == PIPEinput) { | ||
931 | dbri->chi_in_pipe = pipe; | ||
932 | } else { | ||
933 | dbri->chi_out_pipe = pipe; | ||
934 | } | ||
935 | } else { | ||
936 | dbri->pipes[prevpipe].nextpipe = pipe; | ||
937 | } | ||
938 | |||
939 | dbri->pipes[pipe].nextpipe = nextpipe; | 903 | dbri->pipes[pipe].nextpipe = nextpipe; |
940 | dbri->pipes[pipe].cycle = cycle; | ||
941 | dbri->pipes[pipe].length = length; | 904 | dbri->pipes[pipe].length = length; |
942 | 905 | ||
943 | cmd = dbri_cmdlock(dbri, NoGetLock); | 906 | cmd = dbri_cmdlock(dbri, 4); |
944 | 907 | ||
945 | if (direction == PIPEinput) { | 908 | if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { |
946 | val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(prevpipe) | pipe; | 909 | /* Deal with CHI special case: |
910 | * "If transmission on edges 0 or 1 is desired, then cycle n | ||
911 | * (where n = # of bit times per frame...) must be used." | ||
912 | * - DBRI data sheet, page 11 | ||
913 | */ | ||
914 | if (prevpipe == 16 && cycle == 0) | ||
915 | cycle = dbri->chi_bpf; | ||
916 | |||
917 | val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(prevpipe) | pipe; | ||
947 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | 918 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); |
919 | *(cmd++) = 0; | ||
948 | *(cmd++) = | 920 | *(cmd++) = |
949 | D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe); | 921 | D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe); |
950 | *(cmd++) = 0; | ||
951 | } else { | 922 | } else { |
952 | val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(prevpipe) | pipe; | 923 | val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(prevpipe) | pipe; |
953 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | 924 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); |
954 | *(cmd++) = 0; | ||
955 | *(cmd++) = | 925 | *(cmd++) = |
956 | D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe); | 926 | D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe); |
927 | *(cmd++) = 0; | ||
957 | } | 928 | } |
929 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | ||
958 | 930 | ||
959 | dbri_cmdsend(dbri, cmd); | 931 | dbri_cmdsend(dbri, cmd, 4); |
960 | } | 932 | } |
961 | 933 | ||
934 | #if 0 | ||
935 | /* | ||
936 | * Lock must be held before calling this. | ||
937 | */ | ||
962 | static void unlink_time_slot(struct snd_dbri * dbri, int pipe, | 938 | static void unlink_time_slot(struct snd_dbri * dbri, int pipe, |
963 | enum in_or_out direction, int prevpipe, | 939 | enum in_or_out direction, int prevpipe, |
964 | int nextpipe) | 940 | int nextpipe) |
965 | { | 941 | { |
966 | volatile s32 *cmd; | 942 | s32 *cmd; |
967 | int val; | 943 | int val; |
968 | 944 | ||
969 | if (pipe < 0 || pipe > 31 || prevpipe < 0 || prevpipe > 31) { | 945 | if (pipe < 0 || pipe > DBRI_MAX_PIPE |
946 | || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE | ||
947 | || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) { | ||
970 | printk(KERN_ERR | 948 | printk(KERN_ERR |
971 | "DBRI: unlink_time_slot called with illegal pipe number\n"); | 949 | "DBRI: unlink_time_slot called with illegal pipe number\n"); |
972 | return; | 950 | return; |
973 | } | 951 | } |
974 | 952 | ||
975 | cmd = dbri_cmdlock(dbri, NoGetLock); | 953 | cmd = dbri_cmdlock(dbri, 4); |
976 | 954 | ||
977 | if (direction == PIPEinput) { | 955 | if (direction == PIPEinput) { |
978 | val = D_DTS_VI | D_DTS_DEL | D_DTS_PRVIN(prevpipe) | pipe; | 956 | val = D_DTS_VI | D_DTS_DEL | D_DTS_PRVIN(prevpipe) | pipe; |
@@ -985,9 +963,11 @@ static void unlink_time_slot(struct snd_dbri * dbri, int pipe, | |||
985 | *(cmd++) = 0; | 963 | *(cmd++) = 0; |
986 | *(cmd++) = D_TS_NEXT(nextpipe); | 964 | *(cmd++) = D_TS_NEXT(nextpipe); |
987 | } | 965 | } |
966 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | ||
988 | 967 | ||
989 | dbri_cmdsend(dbri, cmd); | 968 | dbri_cmdsend(dbri, cmd, 4); |
990 | } | 969 | } |
970 | #endif | ||
991 | 971 | ||
992 | /* xmit_fixed() / recv_fixed() | 972 | /* xmit_fixed() / recv_fixed() |
993 | * | 973 | * |
@@ -1001,13 +981,16 @@ static void unlink_time_slot(struct snd_dbri * dbri, int pipe, | |||
1001 | * the actual time slot is. The interrupt handler takes care of bit | 981 | * the actual time slot is. The interrupt handler takes care of bit |
1002 | * ordering and alignment. An 8-bit time slot will always end up | 982 | * ordering and alignment. An 8-bit time slot will always end up |
1003 | * in the low-order 8 bits, filled either MSB-first or LSB-first, | 983 | * in the low-order 8 bits, filled either MSB-first or LSB-first, |
1004 | * depending on the settings passed to setup_pipe() | 984 | * depending on the settings passed to setup_pipe(). |
985 | * | ||
986 | * Lock must not be held before calling it. | ||
1005 | */ | 987 | */ |
1006 | static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data) | 988 | static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data) |
1007 | { | 989 | { |
1008 | volatile s32 *cmd; | 990 | s32 *cmd; |
991 | unsigned long flags; | ||
1009 | 992 | ||
1010 | if (pipe < 16 || pipe > 31) { | 993 | if (pipe < 16 || pipe > DBRI_MAX_PIPE) { |
1011 | printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n"); | 994 | printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n"); |
1012 | return; | 995 | return; |
1013 | } | 996 | } |
@@ -1032,17 +1015,22 @@ static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data) | |||
1032 | if (dbri->pipes[pipe].sdp & D_SDP_MSB) | 1015 | if (dbri->pipes[pipe].sdp & D_SDP_MSB) |
1033 | data = reverse_bytes(data, dbri->pipes[pipe].length); | 1016 | data = reverse_bytes(data, dbri->pipes[pipe].length); |
1034 | 1017 | ||
1035 | cmd = dbri_cmdlock(dbri, GetLock); | 1018 | cmd = dbri_cmdlock(dbri, 3); |
1036 | 1019 | ||
1037 | *(cmd++) = DBRI_CMD(D_SSP, 0, pipe); | 1020 | *(cmd++) = DBRI_CMD(D_SSP, 0, pipe); |
1038 | *(cmd++) = data; | 1021 | *(cmd++) = data; |
1022 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | ||
1023 | |||
1024 | spin_lock_irqsave(&dbri->lock, flags); | ||
1025 | dbri_cmdsend(dbri, cmd, 3); | ||
1026 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
1027 | dbri_cmdwait(dbri); | ||
1039 | 1028 | ||
1040 | dbri_cmdsend(dbri, cmd); | ||
1041 | } | 1029 | } |
1042 | 1030 | ||
1043 | static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr) | 1031 | static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr) |
1044 | { | 1032 | { |
1045 | if (pipe < 16 || pipe > 31) { | 1033 | if (pipe < 16 || pipe > DBRI_MAX_PIPE) { |
1046 | printk(KERN_ERR "DBRI: recv_fixed called with illegal pipe number\n"); | 1034 | printk(KERN_ERR "DBRI: recv_fixed called with illegal pipe number\n"); |
1047 | return; | 1035 | return; |
1048 | } | 1036 | } |
@@ -1071,12 +1059,16 @@ static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr) | |||
1071 | * and work by building chains of descriptors which identify the | 1059 | * and work by building chains of descriptors which identify the |
1072 | * data buffers. Buffers too large for a single descriptor will | 1060 | * data buffers. Buffers too large for a single descriptor will |
1073 | * be spread across multiple descriptors. | 1061 | * be spread across multiple descriptors. |
1062 | * | ||
1063 | * All descriptors create a ring buffer. | ||
1064 | * | ||
1065 | * Lock must be held before calling this. | ||
1074 | */ | 1066 | */ |
1075 | static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period) | 1067 | static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period) |
1076 | { | 1068 | { |
1077 | struct dbri_streaminfo *info = &dbri->stream_info[streamno]; | 1069 | struct dbri_streaminfo *info = &dbri->stream_info[streamno]; |
1078 | __u32 dvma_buffer; | 1070 | __u32 dvma_buffer; |
1079 | int desc = 0; | 1071 | int desc; |
1080 | int len; | 1072 | int len; |
1081 | int first_desc = -1; | 1073 | int first_desc = -1; |
1082 | int last_desc = -1; | 1074 | int last_desc = -1; |
@@ -1119,11 +1111,23 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1119 | len &= ~3; | 1111 | len &= ~3; |
1120 | } | 1112 | } |
1121 | 1113 | ||
1114 | /* Free descriptors if pipe has any */ | ||
1115 | desc = dbri->pipes[info->pipe].first_desc; | ||
1116 | if ( desc >= 0) | ||
1117 | do { | ||
1118 | dbri->dma->desc[desc].nda = dbri->dma->desc[desc].ba = 0; | ||
1119 | desc = dbri->next_desc[desc]; | ||
1120 | } while (desc != -1 && desc != dbri->pipes[info->pipe].first_desc); | ||
1121 | |||
1122 | dbri->pipes[info->pipe].desc = -1; | ||
1123 | dbri->pipes[info->pipe].first_desc = -1; | ||
1124 | |||
1125 | desc = 0; | ||
1122 | while (len > 0) { | 1126 | while (len > 0) { |
1123 | int mylen; | 1127 | int mylen; |
1124 | 1128 | ||
1125 | for (; desc < DBRI_NO_DESCS; desc++) { | 1129 | for (; desc < DBRI_NO_DESCS; desc++) { |
1126 | if (!dbri->descs[desc].inuse) | 1130 | if (!dbri->dma->desc[desc].ba) |
1127 | break; | 1131 | break; |
1128 | } | 1132 | } |
1129 | if (desc == DBRI_NO_DESCS) { | 1133 | if (desc == DBRI_NO_DESCS) { |
@@ -1131,37 +1135,33 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1131 | return -1; | 1135 | return -1; |
1132 | } | 1136 | } |
1133 | 1137 | ||
1134 | if (len > DBRI_TD_MAXCNT) { | 1138 | if (len > DBRI_TD_MAXCNT) |
1135 | mylen = DBRI_TD_MAXCNT; /* 8KB - 1 */ | 1139 | mylen = DBRI_TD_MAXCNT; /* 8KB - 4 */ |
1136 | } else { | 1140 | else |
1137 | mylen = len; | 1141 | mylen = len; |
1138 | } | 1142 | |
1139 | if (mylen > period) { | 1143 | if (mylen > period) |
1140 | mylen = period; | 1144 | mylen = period; |
1141 | } | ||
1142 | 1145 | ||
1143 | dbri->descs[desc].inuse = 1; | 1146 | dbri->next_desc[desc] = -1; |
1144 | dbri->descs[desc].next = -1; | ||
1145 | dbri->dma->desc[desc].ba = dvma_buffer; | 1147 | dbri->dma->desc[desc].ba = dvma_buffer; |
1146 | dbri->dma->desc[desc].nda = 0; | 1148 | dbri->dma->desc[desc].nda = 0; |
1147 | 1149 | ||
1148 | if (streamno == DBRI_PLAY) { | 1150 | if (streamno == DBRI_PLAY) { |
1149 | dbri->descs[desc].len = mylen; | ||
1150 | dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen); | 1151 | dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen); |
1151 | dbri->dma->desc[desc].word4 = 0; | 1152 | dbri->dma->desc[desc].word4 = 0; |
1152 | if (first_desc != -1) | 1153 | dbri->dma->desc[desc].word1 |= |
1153 | dbri->dma->desc[desc].word1 |= DBRI_TD_M; | 1154 | DBRI_TD_F | DBRI_TD_B; |
1154 | } else { | 1155 | } else { |
1155 | dbri->descs[desc].len = 0; | ||
1156 | dbri->dma->desc[desc].word1 = 0; | 1156 | dbri->dma->desc[desc].word1 = 0; |
1157 | dbri->dma->desc[desc].word4 = | 1157 | dbri->dma->desc[desc].word4 = |
1158 | DBRI_RD_B | DBRI_RD_BCNT(mylen); | 1158 | DBRI_RD_B | DBRI_RD_BCNT(mylen); |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | if (first_desc == -1) { | 1161 | if (first_desc == -1) |
1162 | first_desc = desc; | 1162 | first_desc = desc; |
1163 | } else { | 1163 | else { |
1164 | dbri->descs[last_desc].next = desc; | 1164 | dbri->next_desc[last_desc] = desc; |
1165 | dbri->dma->desc[last_desc].nda = | 1165 | dbri->dma->desc[last_desc].nda = |
1166 | dbri->dma_dvma + dbri_dma_off(desc, desc); | 1166 | dbri->dma_dvma + dbri_dma_off(desc, desc); |
1167 | } | 1167 | } |
@@ -1176,21 +1176,24 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1176 | return -1; | 1176 | return -1; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | dbri->dma->desc[last_desc].word1 &= ~DBRI_TD_M; | 1179 | dbri->dma->desc[last_desc].nda = |
1180 | if (streamno == DBRI_PLAY) { | 1180 | dbri->dma_dvma + dbri_dma_off(desc, first_desc); |
1181 | dbri->dma->desc[last_desc].word1 |= | 1181 | dbri->next_desc[last_desc] = first_desc; |
1182 | DBRI_TD_I | DBRI_TD_F | DBRI_TD_B; | ||
1183 | } | ||
1184 | dbri->pipes[info->pipe].first_desc = first_desc; | 1182 | dbri->pipes[info->pipe].first_desc = first_desc; |
1185 | dbri->pipes[info->pipe].desc = first_desc; | 1183 | dbri->pipes[info->pipe].desc = first_desc; |
1186 | 1184 | ||
1187 | for (desc = first_desc; desc != -1; desc = dbri->descs[desc].next) { | 1185 | #ifdef DBRI_DEBUG |
1186 | for (desc = first_desc; desc != -1; ) { | ||
1188 | dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n", | 1187 | dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n", |
1189 | desc, | 1188 | desc, |
1190 | dbri->dma->desc[desc].word1, | 1189 | dbri->dma->desc[desc].word1, |
1191 | dbri->dma->desc[desc].ba, | 1190 | dbri->dma->desc[desc].ba, |
1192 | dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4); | 1191 | dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4); |
1192 | desc = dbri->next_desc[desc]; | ||
1193 | if ( desc == first_desc ) | ||
1194 | break; | ||
1193 | } | 1195 | } |
1196 | #endif | ||
1194 | return 0; | 1197 | return 0; |
1195 | } | 1198 | } |
1196 | 1199 | ||
@@ -1207,56 +1210,30 @@ multiplexed serial interface which the DBRI can operate in either master | |||
1207 | 1210 | ||
1208 | enum master_or_slave { CHImaster, CHIslave }; | 1211 | enum master_or_slave { CHImaster, CHIslave }; |
1209 | 1212 | ||
1213 | /* | ||
1214 | * Lock must not be held before calling it. | ||
1215 | */ | ||
1210 | static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_slave, | 1216 | static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_slave, |
1211 | int bits_per_frame) | 1217 | int bits_per_frame) |
1212 | { | 1218 | { |
1213 | volatile s32 *cmd; | 1219 | s32 *cmd; |
1214 | int val; | 1220 | int val; |
1215 | static int chi_initialized = 0; /* FIXME: mutex? */ | ||
1216 | |||
1217 | if (!chi_initialized) { | ||
1218 | |||
1219 | cmd = dbri_cmdlock(dbri, GetLock); | ||
1220 | |||
1221 | /* Set CHI Anchor: Pipe 16 */ | ||
1222 | |||
1223 | val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(16) | D_PIPE(16); | ||
1224 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | ||
1225 | *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); | ||
1226 | *(cmd++) = 0; | ||
1227 | |||
1228 | val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(16) | D_PIPE(16); | ||
1229 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | ||
1230 | *(cmd++) = 0; | ||
1231 | *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); | ||
1232 | 1221 | ||
1233 | dbri->pipes[16].sdp = 1; | 1222 | /* Set CHI Anchor: Pipe 16 */ |
1234 | dbri->pipes[16].nextpipe = 16; | ||
1235 | dbri->chi_in_pipe = 16; | ||
1236 | dbri->chi_out_pipe = 16; | ||
1237 | |||
1238 | #if 0 | ||
1239 | chi_initialized++; | ||
1240 | #endif | ||
1241 | } else { | ||
1242 | int pipe; | ||
1243 | 1223 | ||
1244 | for (pipe = dbri->chi_in_pipe; | 1224 | cmd = dbri_cmdlock(dbri, 4); |
1245 | pipe != 16; pipe = dbri->pipes[pipe].nextpipe) { | 1225 | val = D_DTS_VO | D_DTS_VI | D_DTS_INS |
1246 | unlink_time_slot(dbri, pipe, PIPEinput, | 1226 | | D_DTS_PRVIN(16) | D_PIPE(16) | D_DTS_PRVOUT(16); |
1247 | 16, dbri->pipes[pipe].nextpipe); | 1227 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); |
1248 | } | 1228 | *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); |
1249 | for (pipe = dbri->chi_out_pipe; | 1229 | *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); |
1250 | pipe != 16; pipe = dbri->pipes[pipe].nextpipe) { | 1230 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); |
1251 | unlink_time_slot(dbri, pipe, PIPEoutput, | 1231 | dbri_cmdsend(dbri, cmd, 4); |
1252 | 16, dbri->pipes[pipe].nextpipe); | ||
1253 | } | ||
1254 | 1232 | ||
1255 | dbri->chi_in_pipe = 16; | 1233 | dbri->pipes[16].sdp = 1; |
1256 | dbri->chi_out_pipe = 16; | 1234 | dbri->pipes[16].nextpipe = 16; |
1257 | 1235 | ||
1258 | cmd = dbri_cmdlock(dbri, GetLock); | 1236 | cmd = dbri_cmdlock(dbri, 4); |
1259 | } | ||
1260 | 1237 | ||
1261 | if (master_or_slave == CHIslave) { | 1238 | if (master_or_slave == CHIslave) { |
1262 | /* Setup DBRI for CHI Slave - receive clock, frame sync (FS) | 1239 | /* Setup DBRI for CHI Slave - receive clock, frame sync (FS) |
@@ -1295,8 +1272,9 @@ static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_sla | |||
1295 | 1272 | ||
1296 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | 1273 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); |
1297 | *(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE | D_CDM_XEN | D_CDM_REN); | 1274 | *(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE | D_CDM_XEN | D_CDM_REN); |
1275 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | ||
1298 | 1276 | ||
1299 | dbri_cmdsend(dbri, cmd); | 1277 | dbri_cmdsend(dbri, cmd, 4); |
1300 | } | 1278 | } |
1301 | 1279 | ||
1302 | /* | 1280 | /* |
@@ -1307,9 +1285,14 @@ static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_sla | |||
1307 | In the standard SPARC audio configuration, the CS4215 codec is attached | 1285 | In the standard SPARC audio configuration, the CS4215 codec is attached |
1308 | to the DBRI via the CHI interface and few of the DBRI's PIO pins. | 1286 | to the DBRI via the CHI interface and few of the DBRI's PIO pins. |
1309 | 1287 | ||
1288 | * Lock must not be held before calling it. | ||
1289 | |||
1310 | */ | 1290 | */ |
1311 | static void cs4215_setup_pipes(struct snd_dbri * dbri) | 1291 | static void cs4215_setup_pipes(struct snd_dbri * dbri) |
1312 | { | 1292 | { |
1293 | unsigned long flags; | ||
1294 | |||
1295 | spin_lock_irqsave(&dbri->lock, flags); | ||
1313 | /* | 1296 | /* |
1314 | * Data mode: | 1297 | * Data mode: |
1315 | * Pipe 4: Send timeslots 1-4 (audio data) | 1298 | * Pipe 4: Send timeslots 1-4 (audio data) |
@@ -1333,6 +1316,9 @@ static void cs4215_setup_pipes(struct snd_dbri * dbri) | |||
1333 | setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB); | 1316 | setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB); |
1334 | setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); | 1317 | setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); |
1335 | setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); | 1318 | setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); |
1319 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
1320 | |||
1321 | dbri_cmdwait(dbri); | ||
1336 | } | 1322 | } |
1337 | 1323 | ||
1338 | static int cs4215_init_data(struct cs4215 *mm) | 1324 | static int cs4215_init_data(struct cs4215 *mm) |
@@ -1364,7 +1350,7 @@ static int cs4215_init_data(struct cs4215 *mm) | |||
1364 | mm->status = 0; | 1350 | mm->status = 0; |
1365 | mm->version = 0xff; | 1351 | mm->version = 0xff; |
1366 | mm->precision = 8; /* For ULAW */ | 1352 | mm->precision = 8; /* For ULAW */ |
1367 | mm->channels = 2; | 1353 | mm->channels = 1; |
1368 | 1354 | ||
1369 | return 0; | 1355 | return 0; |
1370 | } | 1356 | } |
@@ -1379,16 +1365,8 @@ static void cs4215_setdata(struct snd_dbri * dbri, int muted) | |||
1379 | } else { | 1365 | } else { |
1380 | /* Start by setting the playback attenuation. */ | 1366 | /* Start by setting the playback attenuation. */ |
1381 | struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY]; | 1367 | struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY]; |
1382 | int left_gain = info->left_gain % 64; | 1368 | int left_gain = info->left_gain & 0x3f; |
1383 | int right_gain = info->right_gain % 64; | 1369 | int right_gain = info->right_gain & 0x3f; |
1384 | |||
1385 | if (info->balance < DBRI_MID_BALANCE) { | ||
1386 | right_gain *= info->balance; | ||
1387 | right_gain /= DBRI_MID_BALANCE; | ||
1388 | } else { | ||
1389 | left_gain *= DBRI_RIGHT_BALANCE - info->balance; | ||
1390 | left_gain /= DBRI_MID_BALANCE; | ||
1391 | } | ||
1392 | 1370 | ||
1393 | dbri->mm.data[0] &= ~0x3f; /* Reset the volume bits */ | 1371 | dbri->mm.data[0] &= ~0x3f; /* Reset the volume bits */ |
1394 | dbri->mm.data[1] &= ~0x3f; | 1372 | dbri->mm.data[1] &= ~0x3f; |
@@ -1397,8 +1375,8 @@ static void cs4215_setdata(struct snd_dbri * dbri, int muted) | |||
1397 | 1375 | ||
1398 | /* Now set the recording gain. */ | 1376 | /* Now set the recording gain. */ |
1399 | info = &dbri->stream_info[DBRI_REC]; | 1377 | info = &dbri->stream_info[DBRI_REC]; |
1400 | left_gain = info->left_gain % 16; | 1378 | left_gain = info->left_gain & 0xf; |
1401 | right_gain = info->right_gain % 16; | 1379 | right_gain = info->right_gain & 0xf; |
1402 | dbri->mm.data[2] |= CS4215_LG(left_gain); | 1380 | dbri->mm.data[2] |= CS4215_LG(left_gain); |
1403 | dbri->mm.data[3] |= CS4215_RG(right_gain); | 1381 | dbri->mm.data[3] |= CS4215_RG(right_gain); |
1404 | } | 1382 | } |
@@ -1413,6 +1391,7 @@ static void cs4215_open(struct snd_dbri * dbri) | |||
1413 | { | 1391 | { |
1414 | int data_width; | 1392 | int data_width; |
1415 | u32 tmp; | 1393 | u32 tmp; |
1394 | unsigned long flags; | ||
1416 | 1395 | ||
1417 | dprintk(D_MM, "cs4215_open: %d channels, %d bits\n", | 1396 | dprintk(D_MM, "cs4215_open: %d channels, %d bits\n", |
1418 | dbri->mm.channels, dbri->mm.precision); | 1397 | dbri->mm.channels, dbri->mm.precision); |
@@ -1437,6 +1416,7 @@ static void cs4215_open(struct snd_dbri * dbri) | |||
1437 | * bits. The CS4215, it seems, observes TSIN (the delayed signal) | 1416 | * bits. The CS4215, it seems, observes TSIN (the delayed signal) |
1438 | * even if it's the CHI master. Don't ask me... | 1417 | * even if it's the CHI master. Don't ask me... |
1439 | */ | 1418 | */ |
1419 | spin_lock_irqsave(&dbri->lock, flags); | ||
1440 | tmp = sbus_readl(dbri->regs + REG0); | 1420 | tmp = sbus_readl(dbri->regs + REG0); |
1441 | tmp &= ~(D_C); /* Disable CHI */ | 1421 | tmp &= ~(D_C); /* Disable CHI */ |
1442 | sbus_writel(tmp, dbri->regs + REG0); | 1422 | sbus_writel(tmp, dbri->regs + REG0); |
@@ -1455,15 +1435,16 @@ static void cs4215_open(struct snd_dbri * dbri) | |||
1455 | */ | 1435 | */ |
1456 | data_width = dbri->mm.channels * dbri->mm.precision; | 1436 | data_width = dbri->mm.channels * dbri->mm.precision; |
1457 | 1437 | ||
1458 | link_time_slot(dbri, 20, PIPEoutput, 16, 32, dbri->mm.offset + 32); | 1438 | link_time_slot(dbri, 4, 16, 16, data_width, dbri->mm.offset); |
1459 | link_time_slot(dbri, 4, PIPEoutput, 16, data_width, dbri->mm.offset); | 1439 | link_time_slot(dbri, 20, 4, 16, 32, dbri->mm.offset + 32); |
1460 | link_time_slot(dbri, 6, PIPEinput, 16, data_width, dbri->mm.offset); | 1440 | link_time_slot(dbri, 6, 16, 16, data_width, dbri->mm.offset); |
1461 | link_time_slot(dbri, 21, PIPEinput, 16, 16, dbri->mm.offset + 40); | 1441 | link_time_slot(dbri, 21, 6, 16, 16, dbri->mm.offset + 40); |
1462 | 1442 | ||
1463 | /* FIXME: enable CHI after _setdata? */ | 1443 | /* FIXME: enable CHI after _setdata? */ |
1464 | tmp = sbus_readl(dbri->regs + REG0); | 1444 | tmp = sbus_readl(dbri->regs + REG0); |
1465 | tmp |= D_C; /* Enable CHI */ | 1445 | tmp |= D_C; /* Enable CHI */ |
1466 | sbus_writel(tmp, dbri->regs + REG0); | 1446 | sbus_writel(tmp, dbri->regs + REG0); |
1447 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
1467 | 1448 | ||
1468 | cs4215_setdata(dbri, 0); | 1449 | cs4215_setdata(dbri, 0); |
1469 | } | 1450 | } |
@@ -1475,6 +1456,7 @@ static int cs4215_setctrl(struct snd_dbri * dbri) | |||
1475 | { | 1456 | { |
1476 | int i, val; | 1457 | int i, val; |
1477 | u32 tmp; | 1458 | u32 tmp; |
1459 | unsigned long flags; | ||
1478 | 1460 | ||
1479 | /* FIXME - let the CPU do something useful during these delays */ | 1461 | /* FIXME - let the CPU do something useful during these delays */ |
1480 | 1462 | ||
@@ -1511,6 +1493,7 @@ static int cs4215_setctrl(struct snd_dbri * dbri) | |||
1511 | * done in hardware by a TI 248 that delays the DBRI->4215 | 1493 | * done in hardware by a TI 248 that delays the DBRI->4215 |
1512 | * frame sync signal by eight clock cycles. Anybody know why? | 1494 | * frame sync signal by eight clock cycles. Anybody know why? |
1513 | */ | 1495 | */ |
1496 | spin_lock_irqsave(&dbri->lock, flags); | ||
1514 | tmp = sbus_readl(dbri->regs + REG0); | 1497 | tmp = sbus_readl(dbri->regs + REG0); |
1515 | tmp &= ~D_C; /* Disable CHI */ | 1498 | tmp &= ~D_C; /* Disable CHI */ |
1516 | sbus_writel(tmp, dbri->regs + REG0); | 1499 | sbus_writel(tmp, dbri->regs + REG0); |
@@ -1524,17 +1507,20 @@ static int cs4215_setctrl(struct snd_dbri * dbri) | |||
1524 | * Pipe 19: Receive timeslot 7 (version). | 1507 | * Pipe 19: Receive timeslot 7 (version). |
1525 | */ | 1508 | */ |
1526 | 1509 | ||
1527 | link_time_slot(dbri, 17, PIPEoutput, 16, 32, dbri->mm.offset); | 1510 | link_time_slot(dbri, 17, 16, 16, 32, dbri->mm.offset); |
1528 | link_time_slot(dbri, 18, PIPEinput, 16, 8, dbri->mm.offset); | 1511 | link_time_slot(dbri, 18, 16, 16, 8, dbri->mm.offset); |
1529 | link_time_slot(dbri, 19, PIPEinput, 16, 8, dbri->mm.offset + 48); | 1512 | link_time_slot(dbri, 19, 18, 16, 8, dbri->mm.offset + 48); |
1513 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
1530 | 1514 | ||
1531 | /* Wait for the chip to echo back CLB (Control Latch Bit) as zero */ | 1515 | /* Wait for the chip to echo back CLB (Control Latch Bit) as zero */ |
1532 | dbri->mm.ctrl[0] &= ~CS4215_CLB; | 1516 | dbri->mm.ctrl[0] &= ~CS4215_CLB; |
1533 | xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl); | 1517 | xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl); |
1534 | 1518 | ||
1519 | spin_lock_irqsave(&dbri->lock, flags); | ||
1535 | tmp = sbus_readl(dbri->regs + REG0); | 1520 | tmp = sbus_readl(dbri->regs + REG0); |
1536 | tmp |= D_C; /* Enable CHI */ | 1521 | tmp |= D_C; /* Enable CHI */ |
1537 | sbus_writel(tmp, dbri->regs + REG0); | 1522 | sbus_writel(tmp, dbri->regs + REG0); |
1523 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
1538 | 1524 | ||
1539 | for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i) { | 1525 | for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i) { |
1540 | msleep_interruptible(1); | 1526 | msleep_interruptible(1); |
@@ -1614,8 +1600,7 @@ static int cs4215_prepare(struct snd_dbri * dbri, unsigned int rate, | |||
1614 | CS4215_BSEL_128 | CS4215_FREQ[freq_idx].xtal; | 1600 | CS4215_BSEL_128 | CS4215_FREQ[freq_idx].xtal; |
1615 | 1601 | ||
1616 | dbri->mm.channels = channels; | 1602 | dbri->mm.channels = channels; |
1617 | /* Stereo bit: 8 bit stereo not working yet. */ | 1603 | if (channels == 2) |
1618 | if ((channels > 1) && (dbri->mm.precision == 16)) | ||
1619 | dbri->mm.ctrl[1] |= CS4215_DFR_STEREO; | 1604 | dbri->mm.ctrl[1] |= CS4215_DFR_STEREO; |
1620 | 1605 | ||
1621 | ret = cs4215_setctrl(dbri); | 1606 | ret = cs4215_setctrl(dbri); |
@@ -1655,7 +1640,6 @@ static int cs4215_init(struct snd_dbri * dbri) | |||
1655 | } | 1640 | } |
1656 | 1641 | ||
1657 | cs4215_setup_pipes(dbri); | 1642 | cs4215_setup_pipes(dbri); |
1658 | |||
1659 | cs4215_init_data(&dbri->mm); | 1643 | cs4215_init_data(&dbri->mm); |
1660 | 1644 | ||
1661 | /* Enable capture of the status & version timeslots. */ | 1645 | /* Enable capture of the status & version timeslots. */ |
@@ -1684,88 +1668,71 @@ buffer and calls dbri_process_one_interrupt() for each interrupt word. | |||
1684 | Complicated interrupts are handled by dedicated functions (which | 1668 | Complicated interrupts are handled by dedicated functions (which |
1685 | appear first in this file). Any pending interrupts can be serviced by | 1669 | appear first in this file). Any pending interrupts can be serviced by |
1686 | calling dbri_process_interrupt_buffer(), which works even if the CPU's | 1670 | calling dbri_process_interrupt_buffer(), which works even if the CPU's |
1687 | interrupts are disabled. This function is used by dbri_cmdlock() | 1671 | interrupts are disabled. |
1688 | to make sure we're synced up with the chip before each command sequence, | ||
1689 | even if we're running cli'ed. | ||
1690 | 1672 | ||
1691 | */ | 1673 | */ |
1692 | 1674 | ||
1693 | /* xmit_descs() | 1675 | /* xmit_descs() |
1694 | * | 1676 | * |
1695 | * Transmit the current TD's for recording/playing, if needed. | 1677 | * Starts transmiting the current TD's for recording/playing. |
1696 | * For playback, ALSA has filled the DMA memory with new data (we hope). | 1678 | * For playback, ALSA has filled the DMA memory with new data (we hope). |
1697 | */ | 1679 | */ |
1698 | static void xmit_descs(unsigned long data) | 1680 | static void xmit_descs(struct snd_dbri *dbri) |
1699 | { | 1681 | { |
1700 | struct snd_dbri *dbri = (struct snd_dbri *) data; | ||
1701 | struct dbri_streaminfo *info; | 1682 | struct dbri_streaminfo *info; |
1702 | volatile s32 *cmd; | 1683 | s32 *cmd; |
1703 | unsigned long flags; | 1684 | unsigned long flags; |
1704 | int first_td; | 1685 | int first_td; |
1705 | 1686 | ||
1706 | if (dbri == NULL) | 1687 | if (dbri == NULL) |
1707 | return; /* Disabled */ | 1688 | return; /* Disabled */ |
1708 | 1689 | ||
1709 | /* First check the recording stream for buffer overflow */ | ||
1710 | info = &dbri->stream_info[DBRI_REC]; | 1690 | info = &dbri->stream_info[DBRI_REC]; |
1711 | spin_lock_irqsave(&dbri->lock, flags); | 1691 | spin_lock_irqsave(&dbri->lock, flags); |
1712 | 1692 | ||
1713 | if ((info->left >= info->size) && (info->pipe >= 0)) { | 1693 | if (info->pipe >= 0) { |
1714 | first_td = dbri->pipes[info->pipe].first_desc; | 1694 | first_td = dbri->pipes[info->pipe].first_desc; |
1715 | 1695 | ||
1716 | dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td); | 1696 | dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td); |
1717 | 1697 | ||
1718 | /* Stream could be closed by the time we run. */ | 1698 | /* Stream could be closed by the time we run. */ |
1719 | if (first_td < 0) { | 1699 | if (first_td >= 0) { |
1720 | goto play; | 1700 | cmd = dbri_cmdlock(dbri, 2); |
1721 | } | 1701 | *(cmd++) = DBRI_CMD(D_SDP, 0, |
1722 | 1702 | dbri->pipes[info->pipe].sdp | |
1723 | cmd = dbri_cmdlock(dbri, NoGetLock); | 1703 | | D_SDP_P | D_SDP_EVERY | D_SDP_C); |
1724 | *(cmd++) = DBRI_CMD(D_SDP, 0, | 1704 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); |
1725 | dbri->pipes[info->pipe].sdp | 1705 | dbri_cmdsend(dbri, cmd, 2); |
1726 | | D_SDP_P | D_SDP_EVERY | D_SDP_C); | ||
1727 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); | ||
1728 | dbri_cmdsend(dbri, cmd); | ||
1729 | 1706 | ||
1730 | /* Reset our admin of the pipe & bytes read. */ | 1707 | /* Reset our admin of the pipe. */ |
1731 | dbri->pipes[info->pipe].desc = first_td; | 1708 | dbri->pipes[info->pipe].desc = first_td; |
1732 | info->left = 0; | 1709 | } |
1733 | } | 1710 | } |
1734 | 1711 | ||
1735 | play: | ||
1736 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
1737 | |||
1738 | /* Now check the playback stream for buffer underflow */ | ||
1739 | info = &dbri->stream_info[DBRI_PLAY]; | 1712 | info = &dbri->stream_info[DBRI_PLAY]; |
1740 | spin_lock_irqsave(&dbri->lock, flags); | ||
1741 | 1713 | ||
1742 | if ((info->left <= 0) && (info->pipe >= 0)) { | 1714 | if (info->pipe >= 0) { |
1743 | first_td = dbri->pipes[info->pipe].first_desc; | 1715 | first_td = dbri->pipes[info->pipe].first_desc; |
1744 | 1716 | ||
1745 | dprintk(D_DESC, "xmit_descs play @ TD %d\n", first_td); | 1717 | dprintk(D_DESC, "xmit_descs play @ TD %d\n", first_td); |
1746 | 1718 | ||
1747 | /* Stream could be closed by the time we run. */ | 1719 | /* Stream could be closed by the time we run. */ |
1748 | if (first_td < 0) { | 1720 | if (first_td >= 0) { |
1749 | spin_unlock_irqrestore(&dbri->lock, flags); | 1721 | cmd = dbri_cmdlock(dbri, 2); |
1750 | return; | 1722 | *(cmd++) = DBRI_CMD(D_SDP, 0, |
1751 | } | 1723 | dbri->pipes[info->pipe].sdp |
1752 | 1724 | | D_SDP_P | D_SDP_EVERY | D_SDP_C); | |
1753 | cmd = dbri_cmdlock(dbri, NoGetLock); | 1725 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); |
1754 | *(cmd++) = DBRI_CMD(D_SDP, 0, | 1726 | dbri_cmdsend(dbri, cmd, 2); |
1755 | dbri->pipes[info->pipe].sdp | ||
1756 | | D_SDP_P | D_SDP_EVERY | D_SDP_C); | ||
1757 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); | ||
1758 | dbri_cmdsend(dbri, cmd); | ||
1759 | 1727 | ||
1760 | /* Reset our admin of the pipe & bytes written. */ | 1728 | /* Reset our admin of the pipe. */ |
1761 | dbri->pipes[info->pipe].desc = first_td; | 1729 | dbri->pipes[info->pipe].desc = first_td; |
1762 | info->left = info->size; | 1730 | } |
1763 | } | 1731 | } |
1732 | |||
1764 | spin_unlock_irqrestore(&dbri->lock, flags); | 1733 | spin_unlock_irqrestore(&dbri->lock, flags); |
1765 | } | 1734 | } |
1766 | 1735 | ||
1767 | static DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0); | ||
1768 | |||
1769 | /* transmission_complete_intr() | 1736 | /* transmission_complete_intr() |
1770 | * | 1737 | * |
1771 | * Called by main interrupt handler when DBRI signals transmission complete | 1738 | * Called by main interrupt handler when DBRI signals transmission complete |
@@ -1775,9 +1742,9 @@ static DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0); | |||
1775 | * them as available. Stops when the first descriptor is found without | 1742 | * them as available. Stops when the first descriptor is found without |
1776 | * TBC (Transmit Buffer Complete) set, or we've run through them all. | 1743 | * TBC (Transmit Buffer Complete) set, or we've run through them all. |
1777 | * | 1744 | * |
1778 | * The DMA buffers are not released, but re-used. Since the transmit buffer | 1745 | * The DMA buffers are not released. They form a ring buffer and |
1779 | * descriptors are not clobbered, they can be re-submitted as is. This is | 1746 | * they are filled by ALSA while others are transmitted by DMA. |
1780 | * done by the xmit_descs() tasklet above since that could take longer. | 1747 | * |
1781 | */ | 1748 | */ |
1782 | 1749 | ||
1783 | static void transmission_complete_intr(struct snd_dbri * dbri, int pipe) | 1750 | static void transmission_complete_intr(struct snd_dbri * dbri, int pipe) |
@@ -1803,21 +1770,9 @@ static void transmission_complete_intr(struct snd_dbri * dbri, int pipe) | |||
1803 | dprintk(D_INT, "TD %d, status 0x%02x\n", td, status); | 1770 | dprintk(D_INT, "TD %d, status 0x%02x\n", td, status); |
1804 | 1771 | ||
1805 | dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */ | 1772 | dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */ |
1806 | info->offset += dbri->descs[td].len; | 1773 | info->offset += DBRI_RD_CNT(dbri->dma->desc[td].word1); |
1807 | info->left -= dbri->descs[td].len; | ||
1808 | |||
1809 | /* On the last TD, transmit them all again. */ | ||
1810 | if (dbri->descs[td].next == -1) { | ||
1811 | if (info->left > 0) { | ||
1812 | printk(KERN_WARNING | ||
1813 | "%d bytes left after last transfer.\n", | ||
1814 | info->left); | ||
1815 | info->left = 0; | ||
1816 | } | ||
1817 | tasklet_schedule(&xmit_descs_task); | ||
1818 | } | ||
1819 | 1774 | ||
1820 | td = dbri->descs[td].next; | 1775 | td = dbri->next_desc[td]; |
1821 | dbri->pipes[pipe].desc = td; | 1776 | dbri->pipes[pipe].desc = td; |
1822 | } | 1777 | } |
1823 | 1778 | ||
@@ -1841,30 +1796,18 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe) | |||
1841 | return; | 1796 | return; |
1842 | } | 1797 | } |
1843 | 1798 | ||
1844 | dbri->descs[rd].inuse = 0; | 1799 | dbri->pipes[pipe].desc = dbri->next_desc[rd]; |
1845 | dbri->pipes[pipe].desc = dbri->descs[rd].next; | ||
1846 | status = dbri->dma->desc[rd].word1; | 1800 | status = dbri->dma->desc[rd].word1; |
1847 | dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */ | 1801 | dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */ |
1848 | 1802 | ||
1849 | info = &dbri->stream_info[DBRI_REC]; | 1803 | info = &dbri->stream_info[DBRI_REC]; |
1850 | info->offset += DBRI_RD_CNT(status); | 1804 | info->offset += DBRI_RD_CNT(status); |
1851 | info->left += DBRI_RD_CNT(status); | ||
1852 | 1805 | ||
1853 | /* FIXME: Check status */ | 1806 | /* FIXME: Check status */ |
1854 | 1807 | ||
1855 | dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n", | 1808 | dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n", |
1856 | rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); | 1809 | rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); |
1857 | 1810 | ||
1858 | /* On the last TD, transmit them all again. */ | ||
1859 | if (dbri->descs[rd].next == -1) { | ||
1860 | if (info->left > info->size) { | ||
1861 | printk(KERN_WARNING | ||
1862 | "%d bytes recorded in %d size buffer.\n", | ||
1863 | info->left, info->size); | ||
1864 | } | ||
1865 | tasklet_schedule(&xmit_descs_task); | ||
1866 | } | ||
1867 | |||
1868 | /* Notify ALSA */ | 1811 | /* Notify ALSA */ |
1869 | if (spin_is_locked(&dbri->lock)) { | 1812 | if (spin_is_locked(&dbri->lock)) { |
1870 | spin_unlock(&dbri->lock); | 1813 | spin_unlock(&dbri->lock); |
@@ -1892,16 +1835,11 @@ static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x) | |||
1892 | channel, code, rval); | 1835 | channel, code, rval); |
1893 | } | 1836 | } |
1894 | 1837 | ||
1895 | if (channel == D_INTR_CMD && command == D_WAIT) { | ||
1896 | dbri->wait_ackd = val; | ||
1897 | if (dbri->wait_send != val) { | ||
1898 | printk(KERN_ERR "Processing wait command %d when %d was send.\n", | ||
1899 | val, dbri->wait_send); | ||
1900 | } | ||
1901 | return; | ||
1902 | } | ||
1903 | |||
1904 | switch (code) { | 1838 | switch (code) { |
1839 | case D_INTR_CMDI: | ||
1840 | if (command != D_WAIT) | ||
1841 | printk(KERN_ERR "DBRI: Command read interrupt\n"); | ||
1842 | break; | ||
1905 | case D_INTR_BRDY: | 1843 | case D_INTR_BRDY: |
1906 | reception_complete_intr(dbri, channel); | 1844 | reception_complete_intr(dbri, channel); |
1907 | break; | 1845 | break; |
@@ -1914,8 +1852,10 @@ static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x) | |||
1914 | * resend SDP command with clear pipe bit (C) set | 1852 | * resend SDP command with clear pipe bit (C) set |
1915 | */ | 1853 | */ |
1916 | { | 1854 | { |
1917 | volatile s32 *cmd; | 1855 | /* FIXME: do something useful in case of underrun */ |
1918 | 1856 | printk(KERN_ERR "DBRI: Underrun error\n"); | |
1857 | #if 0 | ||
1858 | s32 *cmd; | ||
1919 | int pipe = channel; | 1859 | int pipe = channel; |
1920 | int td = dbri->pipes[pipe].desc; | 1860 | int td = dbri->pipes[pipe].desc; |
1921 | 1861 | ||
@@ -1926,6 +1866,7 @@ static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x) | |||
1926 | | D_SDP_P | D_SDP_C | D_SDP_2SAME); | 1866 | | D_SDP_P | D_SDP_C | D_SDP_2SAME); |
1927 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td); | 1867 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td); |
1928 | dbri_cmdsend(dbri, cmd); | 1868 | dbri_cmdsend(dbri, cmd); |
1869 | #endif | ||
1929 | } | 1870 | } |
1930 | break; | 1871 | break; |
1931 | case D_INTR_FXDT: | 1872 | case D_INTR_FXDT: |
@@ -1946,9 +1887,7 @@ static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x) | |||
1946 | /* dbri_process_interrupt_buffer advances through the DBRI's interrupt | 1887 | /* dbri_process_interrupt_buffer advances through the DBRI's interrupt |
1947 | * buffer until it finds a zero word (indicating nothing more to do | 1888 | * buffer until it finds a zero word (indicating nothing more to do |
1948 | * right now). Non-zero words require processing and are handed off | 1889 | * right now). Non-zero words require processing and are handed off |
1949 | * to dbri_process_one_interrupt AFTER advancing the pointer. This | 1890 | * to dbri_process_one_interrupt AFTER advancing the pointer. |
1950 | * order is important since we might recurse back into this function | ||
1951 | * and need to make sure the pointer has been advanced first. | ||
1952 | */ | 1891 | */ |
1953 | static void dbri_process_interrupt_buffer(struct snd_dbri * dbri) | 1892 | static void dbri_process_interrupt_buffer(struct snd_dbri * dbri) |
1954 | { | 1893 | { |
@@ -1957,10 +1896,8 @@ static void dbri_process_interrupt_buffer(struct snd_dbri * dbri) | |||
1957 | while ((x = dbri->dma->intr[dbri->dbri_irqp]) != 0) { | 1896 | while ((x = dbri->dma->intr[dbri->dbri_irqp]) != 0) { |
1958 | dbri->dma->intr[dbri->dbri_irqp] = 0; | 1897 | dbri->dma->intr[dbri->dbri_irqp] = 0; |
1959 | dbri->dbri_irqp++; | 1898 | dbri->dbri_irqp++; |
1960 | if (dbri->dbri_irqp == (DBRI_NO_INTS * DBRI_INT_BLK)) | 1899 | if (dbri->dbri_irqp == DBRI_INT_BLK) |
1961 | dbri->dbri_irqp = 1; | 1900 | dbri->dbri_irqp = 1; |
1962 | else if ((dbri->dbri_irqp & (DBRI_INT_BLK - 1)) == 0) | ||
1963 | dbri->dbri_irqp++; | ||
1964 | 1901 | ||
1965 | dbri_process_one_interrupt(dbri, x); | 1902 | dbri_process_one_interrupt(dbri, x); |
1966 | } | 1903 | } |
@@ -2020,8 +1957,6 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id, | |||
2020 | 1957 | ||
2021 | dbri_process_interrupt_buffer(dbri); | 1958 | dbri_process_interrupt_buffer(dbri); |
2022 | 1959 | ||
2023 | /* FIXME: Write 0 into regs to ACK interrupt */ | ||
2024 | |||
2025 | spin_unlock(&dbri->lock); | 1960 | spin_unlock(&dbri->lock); |
2026 | 1961 | ||
2027 | return IRQ_HANDLED; | 1962 | return IRQ_HANDLED; |
@@ -2039,8 +1974,8 @@ static struct snd_pcm_hardware snd_dbri_pcm_hw = { | |||
2039 | SNDRV_PCM_FMTBIT_A_LAW | | 1974 | SNDRV_PCM_FMTBIT_A_LAW | |
2040 | SNDRV_PCM_FMTBIT_U8 | | 1975 | SNDRV_PCM_FMTBIT_U8 | |
2041 | SNDRV_PCM_FMTBIT_S16_BE, | 1976 | SNDRV_PCM_FMTBIT_S16_BE, |
2042 | .rates = SNDRV_PCM_RATE_8000_48000, | 1977 | .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_5512, |
2043 | .rate_min = 8000, | 1978 | .rate_min = 5512, |
2044 | .rate_max = 48000, | 1979 | .rate_max = 48000, |
2045 | .channels_min = 1, | 1980 | .channels_min = 1, |
2046 | .channels_max = 2, | 1981 | .channels_max = 2, |
@@ -2051,6 +1986,39 @@ static struct snd_pcm_hardware snd_dbri_pcm_hw = { | |||
2051 | .periods_max = 1024, | 1986 | .periods_max = 1024, |
2052 | }; | 1987 | }; |
2053 | 1988 | ||
1989 | static int snd_hw_rule_format(struct snd_pcm_hw_params *params, | ||
1990 | struct snd_pcm_hw_rule *rule) | ||
1991 | { | ||
1992 | struct snd_interval *c = hw_param_interval(params, | ||
1993 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
1994 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
1995 | struct snd_mask fmt; | ||
1996 | |||
1997 | snd_mask_any(&fmt); | ||
1998 | if (c->min > 1) { | ||
1999 | fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_BE; | ||
2000 | return snd_mask_refine(f, &fmt); | ||
2001 | } | ||
2002 | return 0; | ||
2003 | } | ||
2004 | |||
2005 | static int snd_hw_rule_channels(struct snd_pcm_hw_params *params, | ||
2006 | struct snd_pcm_hw_rule *rule) | ||
2007 | { | ||
2008 | struct snd_interval *c = hw_param_interval(params, | ||
2009 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
2010 | struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
2011 | struct snd_interval ch; | ||
2012 | |||
2013 | snd_interval_any(&ch); | ||
2014 | if (!(f->bits[0] & SNDRV_PCM_FMTBIT_S16_BE)) { | ||
2015 | ch.min = ch.max = 1; | ||
2016 | ch.integer = 1; | ||
2017 | return snd_interval_refine(c, &ch); | ||
2018 | } | ||
2019 | return 0; | ||
2020 | } | ||
2021 | |||
2054 | static int snd_dbri_open(struct snd_pcm_substream *substream) | 2022 | static int snd_dbri_open(struct snd_pcm_substream *substream) |
2055 | { | 2023 | { |
2056 | struct snd_dbri *dbri = snd_pcm_substream_chip(substream); | 2024 | struct snd_dbri *dbri = snd_pcm_substream_chip(substream); |
@@ -2063,12 +2031,19 @@ static int snd_dbri_open(struct snd_pcm_substream *substream) | |||
2063 | 2031 | ||
2064 | spin_lock_irqsave(&dbri->lock, flags); | 2032 | spin_lock_irqsave(&dbri->lock, flags); |
2065 | info->substream = substream; | 2033 | info->substream = substream; |
2066 | info->left = 0; | ||
2067 | info->offset = 0; | 2034 | info->offset = 0; |
2068 | info->dvma_buffer = 0; | 2035 | info->dvma_buffer = 0; |
2069 | info->pipe = -1; | 2036 | info->pipe = -1; |
2070 | spin_unlock_irqrestore(&dbri->lock, flags); | 2037 | spin_unlock_irqrestore(&dbri->lock, flags); |
2071 | 2038 | ||
2039 | snd_pcm_hw_rule_add(runtime,0,SNDRV_PCM_HW_PARAM_CHANNELS, | ||
2040 | snd_hw_rule_format, 0, SNDRV_PCM_HW_PARAM_FORMAT, | ||
2041 | -1); | ||
2042 | snd_pcm_hw_rule_add(runtime,0,SNDRV_PCM_HW_PARAM_FORMAT, | ||
2043 | snd_hw_rule_channels, 0, | ||
2044 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
2045 | -1); | ||
2046 | |||
2072 | cs4215_open(dbri); | 2047 | cs4215_open(dbri); |
2073 | 2048 | ||
2074 | return 0; | 2049 | return 0; |
@@ -2081,7 +2056,6 @@ static int snd_dbri_close(struct snd_pcm_substream *substream) | |||
2081 | 2056 | ||
2082 | dprintk(D_USR, "close audio output.\n"); | 2057 | dprintk(D_USR, "close audio output.\n"); |
2083 | info->substream = NULL; | 2058 | info->substream = NULL; |
2084 | info->left = 0; | ||
2085 | info->offset = 0; | 2059 | info->offset = 0; |
2086 | 2060 | ||
2087 | return 0; | 2061 | return 0; |
@@ -2134,6 +2108,7 @@ static int snd_dbri_hw_free(struct snd_pcm_substream *substream) | |||
2134 | struct snd_dbri *dbri = snd_pcm_substream_chip(substream); | 2108 | struct snd_dbri *dbri = snd_pcm_substream_chip(substream); |
2135 | struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream); | 2109 | struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream); |
2136 | int direction; | 2110 | int direction; |
2111 | |||
2137 | dprintk(D_USR, "hw_free.\n"); | 2112 | dprintk(D_USR, "hw_free.\n"); |
2138 | 2113 | ||
2139 | /* hw_free can get called multiple times. Only unmap the DMA once. | 2114 | /* hw_free can get called multiple times. Only unmap the DMA once. |
@@ -2148,7 +2123,10 @@ static int snd_dbri_hw_free(struct snd_pcm_substream *substream) | |||
2148 | substream->runtime->buffer_size, direction); | 2123 | substream->runtime->buffer_size, direction); |
2149 | info->dvma_buffer = 0; | 2124 | info->dvma_buffer = 0; |
2150 | } | 2125 | } |
2151 | info->pipe = -1; | 2126 | if (info->pipe != -1) { |
2127 | reset_pipe(dbri, info->pipe); | ||
2128 | info->pipe = -1; | ||
2129 | } | ||
2152 | 2130 | ||
2153 | return snd_pcm_lib_free_pages(substream); | 2131 | return snd_pcm_lib_free_pages(substream); |
2154 | } | 2132 | } |
@@ -2157,18 +2135,16 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream) | |||
2157 | { | 2135 | { |
2158 | struct snd_dbri *dbri = snd_pcm_substream_chip(substream); | 2136 | struct snd_dbri *dbri = snd_pcm_substream_chip(substream); |
2159 | struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream); | 2137 | struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream); |
2160 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
2161 | int ret; | 2138 | int ret; |
2162 | 2139 | ||
2163 | info->size = snd_pcm_lib_buffer_bytes(substream); | 2140 | info->size = snd_pcm_lib_buffer_bytes(substream); |
2164 | if (DBRI_STREAMNO(substream) == DBRI_PLAY) | 2141 | if (DBRI_STREAMNO(substream) == DBRI_PLAY) |
2165 | info->pipe = 4; /* Send pipe */ | 2142 | info->pipe = 4; /* Send pipe */ |
2166 | else { | 2143 | else |
2167 | info->pipe = 6; /* Receive pipe */ | 2144 | info->pipe = 6; /* Receive pipe */ |
2168 | info->left = info->size; /* To trigger submittal */ | ||
2169 | } | ||
2170 | 2145 | ||
2171 | spin_lock_irq(&dbri->lock); | 2146 | spin_lock_irq(&dbri->lock); |
2147 | info->offset = 0; | ||
2172 | 2148 | ||
2173 | /* Setup the all the transmit/receive desciptors to cover the | 2149 | /* Setup the all the transmit/receive desciptors to cover the |
2174 | * whole DMA buffer. | 2150 | * whole DMA buffer. |
@@ -2176,8 +2152,6 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream) | |||
2176 | ret = setup_descs(dbri, DBRI_STREAMNO(substream), | 2152 | ret = setup_descs(dbri, DBRI_STREAMNO(substream), |
2177 | snd_pcm_lib_period_bytes(substream)); | 2153 | snd_pcm_lib_period_bytes(substream)); |
2178 | 2154 | ||
2179 | runtime->stop_threshold = DBRI_TD_MAXCNT / runtime->channels; | ||
2180 | |||
2181 | spin_unlock_irq(&dbri->lock); | 2155 | spin_unlock_irq(&dbri->lock); |
2182 | 2156 | ||
2183 | dprintk(D_USR, "prepare audio output. %d bytes\n", info->size); | 2157 | dprintk(D_USR, "prepare audio output. %d bytes\n", info->size); |
@@ -2194,14 +2168,11 @@ static int snd_dbri_trigger(struct snd_pcm_substream *substream, int cmd) | |||
2194 | case SNDRV_PCM_TRIGGER_START: | 2168 | case SNDRV_PCM_TRIGGER_START: |
2195 | dprintk(D_USR, "start audio, period is %d bytes\n", | 2169 | dprintk(D_USR, "start audio, period is %d bytes\n", |
2196 | (int)snd_pcm_lib_period_bytes(substream)); | 2170 | (int)snd_pcm_lib_period_bytes(substream)); |
2197 | /* Enable & schedule the tasklet that re-submits the TDs. */ | 2171 | /* Re-submit the TDs. */ |
2198 | xmit_descs_task.data = (unsigned long)dbri; | 2172 | xmit_descs(dbri); |
2199 | tasklet_schedule(&xmit_descs_task); | ||
2200 | break; | 2173 | break; |
2201 | case SNDRV_PCM_TRIGGER_STOP: | 2174 | case SNDRV_PCM_TRIGGER_STOP: |
2202 | dprintk(D_USR, "stop audio.\n"); | 2175 | dprintk(D_USR, "stop audio.\n"); |
2203 | /* Make the tasklet bail out immediately. */ | ||
2204 | xmit_descs_task.data = 0; | ||
2205 | reset_pipe(dbri, info->pipe); | 2176 | reset_pipe(dbri, info->pipe); |
2206 | break; | 2177 | break; |
2207 | default: | 2178 | default: |
@@ -2219,8 +2190,8 @@ static snd_pcm_uframes_t snd_dbri_pointer(struct snd_pcm_substream *substream) | |||
2219 | 2190 | ||
2220 | ret = bytes_to_frames(substream->runtime, info->offset) | 2191 | ret = bytes_to_frames(substream->runtime, info->offset) |
2221 | % substream->runtime->buffer_size; | 2192 | % substream->runtime->buffer_size; |
2222 | dprintk(D_USR, "I/O pointer: %ld frames, %d bytes left.\n", | 2193 | dprintk(D_USR, "I/O pointer: %ld frames of %ld.\n", |
2223 | ret, info->left); | 2194 | ret, substream->runtime->buffer_size); |
2224 | return ret; | 2195 | return ret; |
2225 | } | 2196 | } |
2226 | 2197 | ||
@@ -2254,7 +2225,6 @@ static int __devinit snd_dbri_pcm(struct snd_dbri * dbri) | |||
2254 | pcm->private_data = dbri; | 2225 | pcm->private_data = dbri; |
2255 | pcm->info_flags = 0; | 2226 | pcm->info_flags = 0; |
2256 | strcpy(pcm->name, dbri->card->shortname); | 2227 | strcpy(pcm->name, dbri->card->shortname); |
2257 | dbri->pcm = pcm; | ||
2258 | 2228 | ||
2259 | if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, | 2229 | if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, |
2260 | SNDRV_DMA_TYPE_CONTINUOUS, | 2230 | SNDRV_DMA_TYPE_CONTINUOUS, |
@@ -2303,7 +2273,6 @@ static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol, | |||
2303 | { | 2273 | { |
2304 | struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol); | 2274 | struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol); |
2305 | struct dbri_streaminfo *info = &dbri->stream_info[kcontrol->private_value]; | 2275 | struct dbri_streaminfo *info = &dbri->stream_info[kcontrol->private_value]; |
2306 | unsigned long flags; | ||
2307 | int changed = 0; | 2276 | int changed = 0; |
2308 | 2277 | ||
2309 | if (info->left_gain != ucontrol->value.integer.value[0]) { | 2278 | if (info->left_gain != ucontrol->value.integer.value[0]) { |
@@ -2318,13 +2287,9 @@ static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol, | |||
2318 | /* First mute outputs, and wait 1/8000 sec (125 us) | 2287 | /* First mute outputs, and wait 1/8000 sec (125 us) |
2319 | * to make sure this takes. This avoids clicking noises. | 2288 | * to make sure this takes. This avoids clicking noises. |
2320 | */ | 2289 | */ |
2321 | spin_lock_irqsave(&dbri->lock, flags); | ||
2322 | |||
2323 | cs4215_setdata(dbri, 1); | 2290 | cs4215_setdata(dbri, 1); |
2324 | udelay(125); | 2291 | udelay(125); |
2325 | cs4215_setdata(dbri, 0); | 2292 | cs4215_setdata(dbri, 0); |
2326 | |||
2327 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
2328 | } | 2293 | } |
2329 | return changed; | 2294 | return changed; |
2330 | } | 2295 | } |
@@ -2371,7 +2336,6 @@ static int snd_cs4215_put_single(struct snd_kcontrol *kcontrol, | |||
2371 | struct snd_ctl_elem_value *ucontrol) | 2336 | struct snd_ctl_elem_value *ucontrol) |
2372 | { | 2337 | { |
2373 | struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol); | 2338 | struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol); |
2374 | unsigned long flags; | ||
2375 | int elem = kcontrol->private_value & 0xff; | 2339 | int elem = kcontrol->private_value & 0xff; |
2376 | int shift = (kcontrol->private_value >> 8) & 0xff; | 2340 | int shift = (kcontrol->private_value >> 8) & 0xff; |
2377 | int mask = (kcontrol->private_value >> 16) & 0xff; | 2341 | int mask = (kcontrol->private_value >> 16) & 0xff; |
@@ -2404,13 +2368,9 @@ static int snd_cs4215_put_single(struct snd_kcontrol *kcontrol, | |||
2404 | /* First mute outputs, and wait 1/8000 sec (125 us) | 2368 | /* First mute outputs, and wait 1/8000 sec (125 us) |
2405 | * to make sure this takes. This avoids clicking noises. | 2369 | * to make sure this takes. This avoids clicking noises. |
2406 | */ | 2370 | */ |
2407 | spin_lock_irqsave(&dbri->lock, flags); | ||
2408 | |||
2409 | cs4215_setdata(dbri, 1); | 2371 | cs4215_setdata(dbri, 1); |
2410 | udelay(125); | 2372 | udelay(125); |
2411 | cs4215_setdata(dbri, 0); | 2373 | cs4215_setdata(dbri, 0); |
2412 | |||
2413 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
2414 | } | 2374 | } |
2415 | return changed; | 2375 | return changed; |
2416 | } | 2376 | } |
@@ -2473,7 +2433,6 @@ static int __init snd_dbri_mixer(struct snd_dbri * dbri) | |||
2473 | for (idx = DBRI_REC; idx < DBRI_NO_STREAMS; idx++) { | 2433 | for (idx = DBRI_REC; idx < DBRI_NO_STREAMS; idx++) { |
2474 | dbri->stream_info[idx].left_gain = 0; | 2434 | dbri->stream_info[idx].left_gain = 0; |
2475 | dbri->stream_info[idx].right_gain = 0; | 2435 | dbri->stream_info[idx].right_gain = 0; |
2476 | dbri->stream_info[idx].balance = DBRI_MID_BALANCE; | ||
2477 | } | 2436 | } |
2478 | 2437 | ||
2479 | return 0; | 2438 | return 0; |
@@ -2505,12 +2464,11 @@ static void dbri_debug_read(struct snd_info_entry * entry, | |||
2505 | struct dbri_pipe *pptr = &dbri->pipes[pipe]; | 2464 | struct dbri_pipe *pptr = &dbri->pipes[pipe]; |
2506 | snd_iprintf(buffer, | 2465 | snd_iprintf(buffer, |
2507 | "Pipe %d: %s SDP=0x%x desc=%d, " | 2466 | "Pipe %d: %s SDP=0x%x desc=%d, " |
2508 | "len=%d @ %d prev: %d next %d\n", | 2467 | "len=%d next %d\n", |
2509 | pipe, | 2468 | pipe, |
2510 | (pptr->direction == | 2469 | ((pptr->sdp & D_SDP_TO_SER) ? "output" : "input"), |
2511 | PIPEinput ? "input" : "output"), pptr->sdp, | 2470 | pptr->sdp, pptr->desc, |
2512 | pptr->desc, pptr->length, pptr->cycle, | 2471 | pptr->length, pptr->nextpipe); |
2513 | pptr->prevpipe, pptr->nextpipe); | ||
2514 | } | 2472 | } |
2515 | } | 2473 | } |
2516 | } | 2474 | } |
@@ -2549,7 +2507,6 @@ static int __init snd_dbri_create(struct snd_card *card, | |||
2549 | dbri->card = card; | 2507 | dbri->card = card; |
2550 | dbri->sdev = sdev; | 2508 | dbri->sdev = sdev; |
2551 | dbri->irq = irq->pri; | 2509 | dbri->irq = irq->pri; |
2552 | dbri->dbri_version = sdev->prom_name[9]; | ||
2553 | 2510 | ||
2554 | dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), | 2511 | dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), |
2555 | &dbri->dma_dvma); | 2512 | &dbri->dma_dvma); |
@@ -2669,7 +2626,7 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | |||
2669 | 2626 | ||
2670 | printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", | 2627 | printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", |
2671 | dev, dbri->regs, | 2628 | dev, dbri->regs, |
2672 | dbri->irq, dbri->dbri_version, dbri->mm.version); | 2629 | dbri->irq, sdev->prom_name[9], dbri->mm.version); |
2673 | dev++; | 2630 | dev++; |
2674 | 2631 | ||
2675 | return 0; | 2632 | return 0; |