]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/oss/omap-audio-dma-intfc.c
[PATCH] ARM: OMAP: omap1510/16xx fixes for the tsc2101 oss driver
[linux-2.6-omap-h63xx.git] / sound / oss / omap-audio-dma-intfc.c
1 /*
2  * linux/sound/oss/omap-audio-dma-intfc.c
3  *
4  * Common audio DMA handling for the OMAP processors
5  *
6  * Copyright (C) 2004 Texas Instruments, Inc.
7  *
8  * Copyright (C) 2000, 2001 Nicolas Pitre <nico@cam.org>
9  *
10  * This package is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  *
18  * History:
19  *
20  * 2004-06-07   Sriram Kannan   - Created new file from omap_audio_dma_intfc.c. This file
21  *                                will contain only the DMA interface and buffer handling of OMAP
22  *                                audio driver.
23  *
24  * 2004-06-22   Sriram Kannan   - removed legacy code (auto-init). Self-linking of DMA logical channel.
25  *
26  * 2004-08-12   Nishanth Menon  - Modified to integrate Audio requirements on 1610,1710 platforms
27  *
28  * 2004-11-01   Nishanth Menon  - 16xx platform code base modified to support multi channel chaining.
29  *
30  * 2004-12-15   Nishanth Menon  - Improved 16xx platform channel logic introduced - tasklets, queue handling updated
31  *
32  * 2005-12-10   Dirk Behme      - Added L/R Channel Interchange fix as proposed by Ajaya Babu
33  */
34
35 #include <linux/config.h>
36 #include <linux/module.h>
37 #include <linux/init.h>
38 #include <linux/types.h>
39 #include <linux/fs.h>
40 #include <linux/mm.h>
41 #include <linux/slab.h>
42 #include <linux/sched.h>
43 #include <linux/poll.h>
44 #include <linux/pm.h>
45 #include <linux/errno.h>
46 #include <linux/sound.h>
47 #include <linux/soundcard.h>
48 #include <linux/sysrq.h>
49 #include <linux/interrupt.h>
50 #include <linux/dma-mapping.h>
51 #include <linux/completion.h>
52
53 #include <asm/uaccess.h>
54 #include <asm/io.h>
55 #include <asm/hardware.h>
56 #include <asm/semaphore.h>
57
58 #include <asm/arch/dma.h>
59 #include "omap-audio-dma-intfc.h"
60
61 #include <asm/arch/mcbsp.h>
62
63 #include "omap-audio.h"
64
65 #undef DEBUG
66 //#define DEBUG
67 #ifdef DEBUG
68 #define DPRINTK(ARGS...)  printk(KERN_INFO "<%s>: ",__FUNCTION__);printk(ARGS)
69 #define FN_IN printk(KERN_INFO "[%s]: start\n", __FUNCTION__)
70 #define FN_OUT(n) printk(KERN_INFO "[%s]: end(%u)\n",__FUNCTION__, n)
71 #else
72
73 #define DPRINTK( x... )
74 #define FN_IN
75 #define FN_OUT(x)
76 #endif
77
78 #define ERR(ARGS...) printk(KERN_ERR "{%s}-ERROR: ", __FUNCTION__);printk(ARGS);
79
80 #define AUDIO_NAME              "omap-audio"
81 #define AUDIO_NBFRAGS_DEFAULT   8
82 #define AUDIO_FRAGSIZE_DEFAULT  8192
83
84 #define AUDIO_ACTIVE(state)     ((state)->rd_ref || (state)->wr_ref)
85
86 #define SPIN_ADDR               (dma_addr_t)0
87 #define SPIN_SIZE               2048
88
89 /* Channel Queue Handling macros
90  * tail always points to the current free entry
91  * Head always points to the current entry being used
92  * end is either head or tail
93  */
94
95 #define AUDIO_QUEUE_INIT(s) s->dma_q_head = s->dma_q_tail = s->dma_q_count = 0;
96 #define AUDIO_QUEUE_FULL(s) (nr_linked_channels == s->dma_q_count)
97 #define AUDIO_QUEUE_LAST(s) (1 == s->dma_q_count)
98 #define AUDIO_QUEUE_EMPTY(s) (0 == s->dma_q_count)
99 #define __AUDIO_INCREMENT_QUEUE(end) ((end)=((end)+1) % nr_linked_channels)
100 #define AUDIO_INCREMENT_HEAD(s) __AUDIO_INCREMENT_QUEUE(s->dma_q_head); s->dma_q_count--;
101 #define AUDIO_INCREMENT_TAIL(s) __AUDIO_INCREMENT_QUEUE(s->dma_q_tail); s->dma_q_count++;
102
103 /* DMA buffer fragmentation sizes */
104 #define MAX_DMA_SIZE             0x1000000
105 #define CUT_DMA_SIZE             0x1000
106 /* TODO: To be moved to more appropriate location */
107 #define DCSR_ERROR           0x3
108 #define DCSR_SYNC_SET        (1 << 6)
109
110 #define DCCR_FS              (1 << 5)
111 #define DCCR_PRIO            (1 << 6)
112 #define DCCR_EN              (1 << 7)
113 #define DCCR_AI              (1 << 8)
114 #define DCCR_REPEAT          (1 << 9)
115 /* if 0 the channel works in 3.1 compatible mode*/
116 #define DCCR_N31COMP         (1 << 10)
117 #define DCCR_EP              (1 << 11)
118 #define DCCR_SRC_AMODE_BIT   12
119 #define DCCR_SRC_AMODE_MASK  (0x3<<12)
120 #define DCCR_DST_AMODE_BIT   14
121 #define DCCR_DST_AMODE_MASK  (0x3<<14)
122 #define AMODE_CONST          0x0
123 #define AMODE_POST_INC       0x1
124 #define AMODE_SINGLE_INDEX   0x2
125 #define AMODE_DOUBLE_INDEX   0x3
126
127 /**************************** DATA STRUCTURES *****************************************/
128
129 static spinlock_t dma_list_lock = SPIN_LOCK_UNLOCKED;
130
131 struct audio_isr_work_item {
132         int current_lch;
133         u16 ch_status;
134         audio_stream_t *s;
135 };
136
137 static char work_item_running = 0;
138 static char nr_linked_channels = 1;
139 static struct audio_isr_work_item work1, work2;
140
141
142 /*********************************** MODULE SPECIFIC FUNCTIONS PROTOTYPES *************/
143
144 static void audio_dsr_handler(unsigned long);
145 static DECLARE_TASKLET(audio_isr_work1, audio_dsr_handler,
146                 (unsigned long)&work1);
147 static DECLARE_TASKLET(audio_isr_work2, audio_dsr_handler,
148                 (unsigned long)&work2);
149
150 static void sound_dma_irq_handler(int lch, u16 ch_status, void *data);
151 static void audio_dma_callback(int lch, u16 ch_status, void *data);
152 static int omap_start_sound_dma(audio_stream_t * s, dma_addr_t dma_ptr,
153                                 u_int size);
154 static int audio_set_dma_params_play(int channel, dma_addr_t dma_ptr,
155                                      u_int dma_size);
156 static int audio_set_dma_params_capture(int channel, dma_addr_t dma_ptr,
157                                         u_int dma_size);
158 static int audio_start_dma_chain(audio_stream_t * s);
159
160 /*********************************** GLOBAL FUNCTIONS DEFINTIONS ***********************/
161
162 /***************************************************************************************
163  *
164  * Buffer creation/destruction
165  *
166  **************************************************************************************/
167 int audio_setup_buf(audio_stream_t * s)
168 {
169         int frag;
170         int dmasize = 0;
171         char *dmabuf = NULL;
172         dma_addr_t dmaphys = 0;
173         FN_IN;
174         if (s->buffers) {
175                 FN_OUT(1);
176                 return -EBUSY;
177         }
178         s->buffers = kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);
179         if (!s->buffers)
180                 goto err;
181         memset(s->buffers, 0, sizeof(audio_buf_t) * s->nbfrags);
182         for (frag = 0; frag < s->nbfrags; frag++) {
183                 audio_buf_t *b = &s->buffers[frag];
184                 /*
185                  * Let's allocate non-cached memory for DMA buffers.
186                  * We try to allocate all memory at once.
187                  * If this fails (a common reason is memory fragmentation),
188                  * then we allocate more smaller buffers.
189                  */
190                 if (!dmasize) {
191                         dmasize = (s->nbfrags - frag) * s->fragsize;
192                         do {
193                                 dmabuf =
194                                     dma_alloc_coherent(NULL, dmasize, &dmaphys,
195                                                        0);
196                                 if (!dmabuf)
197                                         dmasize -= s->fragsize;
198                         }
199                         while (!dmabuf && dmasize);
200                         if (!dmabuf)
201                                 goto err;
202                         b->master = dmasize;
203                         memzero(dmabuf, dmasize);
204                 }
205                 b->data = dmabuf;
206                 b->dma_addr = dmaphys;
207                 dmabuf += s->fragsize;
208                 dmaphys += s->fragsize;
209                 dmasize -= s->fragsize;
210         }
211         s->usr_head = s->dma_head = s->dma_tail = 0;
212         AUDIO_QUEUE_INIT(s);
213         s->started = 0;
214         s->bytecount = 0;
215         s->fragcount = 0;
216         init_completion(&s->wfc);
217         s->wfc.done = s->nbfrags;
218         FN_OUT(0);
219         return 0;
220       err:
221         audio_discard_buf(s);
222         FN_OUT(1);
223         return -ENOMEM;
224 }
225
226 void audio_discard_buf(audio_stream_t * s)
227 {
228         FN_IN;
229         /* ensure DMA isn't using those buffers */
230         audio_reset(s);
231         if (s->buffers) {
232                 int frag;
233                 for (frag = 0; frag < s->nbfrags; frag++) {
234                         if (!s->buffers[frag].master)
235                                 continue;
236                         dma_free_coherent(NULL,
237                                           s->buffers[frag].master,
238                                           s->buffers[frag].data,
239                                           s->buffers[frag].dma_addr);
240                 }
241                 kfree(s->buffers);
242                 s->buffers = NULL;
243         }
244         FN_OUT(0);
245 }
246
247 /***************************************************************************************
248  *
249  * DMA channel requests
250  *
251  **************************************************************************************/
252 static void omap_sound_dma_link_lch(void *data)
253 {
254         audio_stream_t *s = (audio_stream_t *) data;
255         int *chan = s->lch;
256         int i;
257
258         FN_IN;
259         if (s->linked) {
260                 FN_OUT(1);
261                 return;
262         }
263         for (i = 0; i < nr_linked_channels; i++) {
264                 int cur_chan = chan[i];
265                 int nex_chan =
266                     ((nr_linked_channels - 1 ==
267                       i) ? chan[0] : chan[i + 1]);
268                 omap_dma_link_lch(cur_chan, nex_chan);
269         }
270         s->linked = 1;
271         FN_OUT(0);
272 }
273
274 int
275 omap_request_sound_dma(int device_id, const char *device_name, void *data,
276                        int **channels)
277 {
278         int i, err = 0;
279         int *chan = NULL;
280         FN_IN;
281         if (unlikely((NULL == channels) || (NULL == device_name))) {
282                 BUG();
283                 return -EPERM;
284         }
285         /* Try allocate memory for the num channels */
286         *channels =
287             (int *)kmalloc(sizeof(int) * nr_linked_channels,
288                            GFP_KERNEL);
289         chan = *channels;
290         if (NULL == chan) {
291                 ERR("No Memory for channel allocs!\n");
292                 FN_OUT(-ENOMEM);
293                 return -ENOMEM;
294         }
295         spin_lock(&dma_list_lock);
296         for (i = 0; i < nr_linked_channels; i++) {
297                 err =
298                     omap_request_dma(device_id, device_name,
299                                      sound_dma_irq_handler, data, &chan[i]);
300                 /* Handle Failure condition here */
301                 if (err < 0) {
302                         int j;
303                         for (j = 0; j < i; j++) {
304                                 omap_free_dma(chan[j]);
305                         }
306                         spin_unlock(&dma_list_lock);
307                         kfree(chan);
308                         *channels = NULL;
309                         ERR("Error in requesting channel %d=0x%x\n", i, err);
310                         FN_OUT(err);
311                         return err;
312                 }
313         }
314
315         /* Chain the channels together */
316         if (!cpu_is_omap1510())
317                 omap_sound_dma_link_lch(data);
318
319         spin_unlock(&dma_list_lock);
320         FN_OUT(0);
321         return 0;
322 }
323
324 /***************************************************************************************
325  *
326  * DMA channel requests Freeing
327  *
328  **************************************************************************************/
329 static void omap_sound_dma_unlink_lch(void *data)
330 {
331         audio_stream_t *s = (audio_stream_t *) data;
332         int *chan = s->lch;
333         int i;
334
335         FN_IN;
336         if (!s->linked) {
337                 FN_OUT(1);
338                 return;
339         }
340         for (i = 0; i < nr_linked_channels; i++) {
341                 int cur_chan = chan[i];
342                 int nex_chan =
343                     ((nr_linked_channels - 1 ==
344                       i) ? chan[0] : chan[i + 1]);
345                 omap_dma_unlink_lch(cur_chan, nex_chan);
346         }
347         s->linked = 0;
348         FN_OUT(0);
349 }
350
351 int omap_free_sound_dma(void *data, int **channels)
352 {
353         int i;
354         int *chan = NULL;
355         FN_IN;
356         if (unlikely(NULL == channels)) {
357                 BUG();
358                 return -EPERM;
359         }
360         if (unlikely(NULL == *channels)) {
361                 BUG();
362                 return -EPERM;
363         }
364         chan = (*channels);
365
366         if (!cpu_is_omap1510())
367                 omap_sound_dma_unlink_lch(data);
368         for (i = 0; i < nr_linked_channels; i++) {
369                 int cur_chan = chan[i];
370                 omap_stop_dma(cur_chan);
371                 omap_free_dma(cur_chan);
372         }
373         kfree(*channels);
374         *channels = NULL;
375         FN_OUT(0);
376         return 0;
377 }
378
379 /***************************************************************************************
380  *
381  * Process DMA requests - This will end up starting the transfer. Proper fragments of
382  * Transfers will be initiated.
383  *
384  **************************************************************************************/
385 int audio_process_dma(audio_stream_t * s)
386 {
387         int ret = 0;
388         unsigned long flags;
389         FN_IN;
390
391         /* Dont let the ISR over ride touching the in_use flag */
392         local_irq_save(flags);
393         if (1 == s->in_use) {
394                 local_irq_restore(flags);
395                 ERR("Called again while In Use\n");
396                 return 0;
397         }
398         s->in_use = 1;
399         local_irq_restore(flags);
400
401         if (s->stopped)
402                 goto spin;
403
404         if (s->dma_spinref > 0 && s->pending_frags) {
405                 s->dma_spinref = 0;
406                 DMA_CLEAR(s);
407         }
408         while (s->pending_frags) {
409                 audio_buf_t *b = &s->buffers[s->dma_head];
410                 u_int dma_size = s->fragsize - b->offset;
411                 if (dma_size > MAX_DMA_SIZE)
412                         dma_size = CUT_DMA_SIZE;
413                 ret =
414                     omap_start_sound_dma(s, b->dma_addr + b->offset, dma_size);
415                 if (ret) {
416                         goto process_out;
417                 }
418                 b->dma_ref++;
419                 b->offset += dma_size;
420                 if (b->offset >= s->fragsize) {
421                         s->pending_frags--;
422                         if (++s->dma_head >= s->nbfrags)
423                                 s->dma_head = 0;
424                 }
425         }
426       spin:
427         if (s->spin_idle) {
428                 int spincnt = 0;
429                 ERR("we are spinning\n");
430                 while (omap_start_sound_dma(s, SPIN_ADDR, SPIN_SIZE) == 0)
431                         spincnt++;
432                 /*
433                  * Note: if there is still a data buffer being
434                  * processed then the ref count is negative.  This
435                  * allows for the DMA termination to be accounted in
436                  * the proper order.  Of course dma_spinref can't be
437                  * greater than 0 if dma_ref is not 0 since we kill
438                  * the spinning above as soon as there is real data to process.
439                  */
440                 if (s->buffers && s->buffers[s->dma_tail].dma_ref)
441                         spincnt = -spincnt;
442                 s->dma_spinref += spincnt;
443         }
444
445       process_out:
446         s->in_use = 0;
447
448         FN_OUT(ret);
449         return ret;
450 }
451
452 /***************************************************************************************
453  *
454  * Prime Rx - Since the recieve buffer has no time limit as to when it would arrive,
455  *            we need to prime it
456  *            
457  **************************************************************************************/
458 void audio_prime_rx(audio_state_t * state)
459 {
460         audio_stream_t *is = state->input_stream;
461
462         FN_IN;
463         if (state->need_tx_for_rx) {
464                 /*
465                  * With some codecs like the Philips UDA1341 we must ensure
466                  * there is an output stream at any time while recording since
467                  * this is how the UDA1341 gets its clock from the SA1100.
468                  * So while there is no playback data to send, the output DMA
469                  * will spin with all zeroes.  We use the cache flush special
470                  * area for that.
471                  */
472                 state->output_stream->spin_idle = 1;
473                 audio_process_dma(state->output_stream);
474         }
475         is->pending_frags = is->nbfrags;
476         init_completion(&is->wfc);
477         is->wfc.done = 0;
478
479         is->active = 1;
480         audio_process_dma(is);
481
482         FN_OUT(0);
483         return;
484 }
485
486 /***************************************************************************************
487  *
488  * set the fragment size
489  *
490  **************************************************************************************/
491 int audio_set_fragments(audio_stream_t * s, int val)
492 {
493         FN_IN;
494         if (s->active)
495                 return -EBUSY;
496         if (s->buffers)
497                 audio_discard_buf(s);
498         s->nbfrags = (val >> 16) & 0x7FFF;
499         val &= 0xFFFF;
500         if (val < 4)
501                 val = 4;
502         if (val > 15)
503                 val = 15;
504         s->fragsize = 1 << val;
505         if (s->nbfrags < 2)
506                 s->nbfrags = 2;
507         if (s->nbfrags * s->fragsize > 128 * 1024)
508                 s->nbfrags = 128 * 1024 / s->fragsize;
509         FN_OUT(0);
510         if (audio_setup_buf(s))
511                 return -ENOMEM;
512         return val | (s->nbfrags << 16);
513
514 }
515
516 /***************************************************************************************
517  *
518  * Sync up the buffers before we shutdown, else under-run errors will happen
519  *
520  **************************************************************************************/
521 int audio_sync(struct file *file)
522 {
523         audio_state_t *state = file->private_data;
524         audio_stream_t *s = state->output_stream;
525         audio_buf_t *b;
526         u_int shiftval = 0;
527         unsigned long flags;
528
529         DECLARE_WAITQUEUE(wait, current);
530
531         FN_IN;
532
533         if (!(file->f_mode & FMODE_WRITE) || !s->buffers || s->mapped) {
534                 FN_OUT(1);
535                 return 0;
536         }
537
538         /*
539          * Send current buffer if it contains data.  Be sure to send
540          * a full sample count.
541          */
542         b = &s->buffers[s->usr_head];
543         if (b->offset &= ~3) {
544                 /* Wait for a buffer to become free */
545                 if (wait_for_completion_interruptible(&s->wfc))
546                         return 0;
547                 /*
548                  * HACK ALERT !
549                  * To avoid increased complexity in the rest of the code
550                  * where full fragment sizes are assumed, we cheat a little
551                  * with the start pointer here and don't forget to restore
552                  * it later.
553                  */
554                 
555                 /* As this is a last frag we need only one dma channel
556                  * to complete. So it's need to unlink dma channels
557                  * to avoid empty dma work.
558                  */
559                 if (!cpu_is_omap1510() && AUDIO_QUEUE_EMPTY(s))
560                         omap_sound_dma_unlink_lch(s);
561
562                 shiftval = s->fragsize - b->offset;
563                 b->offset = shiftval;
564                 b->dma_addr -= shiftval;
565                 b->data -= shiftval;
566                 local_irq_save(flags);
567                 s->bytecount -= shiftval;
568                 if (++s->usr_head >= s->nbfrags)
569                         s->usr_head = 0;
570
571                 s->pending_frags++;
572                 audio_process_dma(s);
573                 local_irq_restore(flags);
574         }
575
576         /* Let's wait for all buffers to complete */
577         set_current_state(TASK_INTERRUPTIBLE);
578         add_wait_queue(&s->wq, &wait);
579         while ((s->pending_frags || (s->wfc.done < s->nbfrags))
580                && !signal_pending(current)) {
581                 schedule();
582                 set_current_state(TASK_INTERRUPTIBLE);
583         }
584         set_current_state(TASK_RUNNING);
585         remove_wait_queue(&s->wq, &wait);
586
587         /* undo the pointer hack above */
588         if (shiftval) {
589                 local_irq_save(flags);
590                 b->dma_addr += shiftval;
591                 b->data += shiftval;
592                 /* ensure sane DMA code behavior if not yet processed */
593                 if (b->offset != 0)
594                         b->offset = s->fragsize;
595                 local_irq_restore(flags);
596         }
597
598         FN_OUT(0);
599         return 0;
600 }
601
602 /***************************************************************************************
603  *
604  * Stop all the DMA channels of the stream
605  *
606  **************************************************************************************/
607 void audio_stop_dma(audio_stream_t * s)
608 {
609         int *chan = s->lch;
610         int i;
611         FN_IN;
612         if (unlikely(NULL == chan)) {
613                 BUG();
614                 return;
615         }
616         for (i = 0; i < nr_linked_channels; i++) {
617                 int cur_chan = chan[i];
618                 omap_stop_dma(cur_chan);
619         }
620         s->started = 0;
621         FN_OUT(0);
622         return;
623 }
624
625 /***************************************************************************************
626  *
627  * Get the dma posn
628  *
629  **************************************************************************************/
630 u_int audio_get_dma_pos(audio_stream_t * s)
631 {
632         audio_buf_t *b = &s->buffers[s->dma_tail];
633         u_int offset;
634
635         FN_IN;
636         if (b->dma_ref) {
637                 offset = omap_get_dma_src_pos(s->lch[s->dma_q_head]) - b->dma_addr;
638                 if (offset >= s->fragsize)
639                         offset = s->fragsize - 4;
640         } else if (s->pending_frags) {
641                 offset = b->offset;
642         } else {
643                 offset = 0;
644         }
645         FN_OUT(offset);
646         return offset;
647 }
648
649 /***************************************************************************************
650  *
651  * Reset the audio buffers
652  *
653  **************************************************************************************/
654 void audio_reset(audio_stream_t * s)
655 {
656         FN_IN;
657         if (s->buffers) {
658                 audio_stop_dma(s);
659                 s->buffers[s->dma_head].offset = 0;
660                 s->buffers[s->usr_head].offset = 0;
661                 s->usr_head = s->dma_head;
662                 s->pending_frags = 0;
663                 init_completion(&s->wfc);
664                 s->wfc.done = s->nbfrags;
665         }
666         s->active = 0;
667         s->stopped = 0;
668         s->started = 0;
669         FN_OUT(0);
670         return;
671 }
672
673 /***************************************************************************************
674  *
675  * Clear any pending transfers
676  *
677  **************************************************************************************/
678 void omap_clear_sound_dma(audio_stream_t * s)
679 {
680         FN_IN;
681         omap_clear_dma(s->lch[s->dma_q_head]);
682         FN_OUT(0);
683         return;
684 }
685
686 /***************************************************************************************
687  *
688  * DMA related functions
689  *
690  **************************************************************************************/
691 static int audio_set_dma_params_play(int channel, dma_addr_t dma_ptr,
692                                      u_int dma_size)
693 {
694         int dt = 0x1;           /* data type 16 */
695         int cen = 32;           /* Stereo */
696         int cfn = dma_size / (2 * cen);
697         unsigned long dest_start;
698         int dest_port = 0;
699         int sync_dev = 0;
700
701         FN_IN;
702
703         if (cpu_is_omap1510() || cpu_is_omap16xx()) {
704                 dest_start = AUDIO_MCBSP_DATAWRITE;
705                 dest_port = OMAP_DMA_PORT_MPUI;
706         }
707         if (cpu_is_omap24xx()) {
708                 dest_start = AUDIO_MCBSP_DATAWRITE;
709                 sync_dev = AUDIO_DMA_TX;
710         }
711
712         omap_set_dma_dest_params(channel, dest_port, OMAP_DMA_AMODE_CONSTANT, dest_start, 0, 0);
713         omap_set_dma_src_params(channel, 0, OMAP_DMA_AMODE_POST_INC, dma_ptr, 0, 0);
714         omap_set_dma_transfer_params(channel, dt, cen, cfn, OMAP_DMA_SYNC_ELEMENT, sync_dev, 0);
715
716         FN_OUT(0);
717         return 0;
718 }
719
720 static int audio_set_dma_params_capture(int channel, dma_addr_t dma_ptr,
721                                         u_int dma_size)
722 {
723         int dt = 0x1;           /* data type 16 */
724         int cen = 16;           /* mono */
725         int cfn = dma_size / (2 * cen);
726         unsigned long src_start;
727         int src_port = 0;
728         int sync_dev = 0;
729         int src_sync = 0;
730
731         FN_IN;
732
733         if (cpu_is_omap1510() || cpu_is_omap16xx()) {
734                 src_start = AUDIO_MCBSP_DATAREAD;
735                 src_port = OMAP_DMA_PORT_MPUI;
736         }
737         if (cpu_is_omap24xx()) {
738                 src_start = AUDIO_MCBSP_DATAREAD;
739                 sync_dev = AUDIO_DMA_RX;
740                 src_sync = 1;
741         }
742
743         omap_set_dma_src_params(channel, src_port, OMAP_DMA_AMODE_CONSTANT, src_start, 0, 0);
744         omap_set_dma_dest_params(channel, 0, OMAP_DMA_AMODE_POST_INC, dma_ptr, 0, 0);
745         omap_set_dma_transfer_params(channel, dt, cen, cfn, OMAP_DMA_SYNC_ELEMENT, sync_dev, src_sync);
746
747         FN_OUT(0);
748         return 0;
749 }
750
751 static int audio_start_dma_chain(audio_stream_t * s)
752 {
753         int channel = s->lch[s->dma_q_head];
754         FN_IN;
755         if (!s->started) {
756                 s->hw_stop();           /* stops McBSP Interface */
757                 omap_start_dma(channel);
758                 s->started = 1;
759                 s->hw_start();          /* start McBSP interface */
760         }
761         /* else the dma itself will progress forward with out our help */
762         FN_OUT(0);
763         return 0;
764 }
765
766 /* Start DMA -
767  * Do the initial set of work to initialize all the channels as required.
768  * We shall then initate a transfer
769  */
770 static int omap_start_sound_dma(audio_stream_t * s, dma_addr_t dma_ptr,
771                                 u_int dma_size)
772 {
773         int ret = -EPERM;
774
775         FN_IN;
776         if (unlikely(dma_size > MAX_DMA_SIZE)) {
777                 ERR("DmaSoundDma: Start: overflowed %d-%d\n", dma_size,
778                     MAX_DMA_SIZE);
779                 return -EOVERFLOW;
780         }
781
782         if (AUDIO_QUEUE_FULL(s)) {
783                 ret = -2;
784                 goto sound_out;
785         }
786         
787         if (s->input_or_output == FMODE_WRITE)
788                 /*playback */
789         {
790                 ret =
791                     audio_set_dma_params_play(s->lch[s->dma_q_tail], dma_ptr,
792                                               dma_size);
793         } else {
794                 ret =
795                     audio_set_dma_params_capture(s->lch[s->dma_q_tail], dma_ptr,
796                                                  dma_size);
797         }
798         if (ret != 0) {
799                 ret = -2;       /* indicate queue full */
800                 goto sound_out;
801         }
802         AUDIO_INCREMENT_TAIL(s);
803         ret = audio_start_dma_chain(s);
804         if (ret) {
805                 ERR("dma start failed");
806         }
807       sound_out:
808         FN_OUT(ret);
809         return ret;
810
811 }
812
813 /***************************************************************************************
814  *
815  * ISR related functions
816  *
817  **************************************************************************************/
818 /* The work item handler */
819 static void audio_dsr_handler(unsigned long inData)
820 {
821         void *data = (void *)inData;
822         struct audio_isr_work_item *work = data;
823         audio_stream_t *s = (work->s);
824         int sound_curr_lch = work->current_lch;
825         u16 ch_status = work->ch_status;
826
827         FN_IN;
828         DPRINTK("lch=%d,status=0x%x, data=%p as=%p\n", sound_curr_lch,
829                 ch_status, data, s);
830         if (AUDIO_QUEUE_EMPTY(s)) {
831                 ERR("Interrupt(%d)  for empty queue(h=%d, T=%d)???\n",
832                     sound_curr_lch, s->dma_q_head, s->dma_q_tail);
833                 ERR("nbfrag=%d,pendfrags=%d,USR-H=%d, QH-%d QT-%d\n",
834                     s->nbfrags, s->pending_frags, s->usr_head, s->dma_head,
835                     s->dma_tail);
836                 FN_OUT(-1);
837                 return;
838         }
839
840         AUDIO_INCREMENT_HEAD(s);        /* Empty the queue */
841
842         /* Try to fill again */
843         audio_dma_callback(sound_curr_lch, ch_status, s);
844         FN_OUT(0);
845
846 }
847
848 /* Macro to trace the IRQ calls - checks for multi-channel irqs */
849 //#define IRQ_TRACE
850 #ifdef IRQ_TRACE
851 #define MAX_UP 10
852 static char xyz[MAX_UP] = { 0 };
853 static int h = 0;
854 #endif
855
856 /* ISRs have to be short and smart.. So we transfer every heavy duty stuff to the 
857  * work item
858  */
859 static void sound_dma_irq_handler(int sound_curr_lch, u16 ch_status, void *data)
860 {
861         int dma_status = ch_status;
862         audio_stream_t *s = (audio_stream_t *) data;
863         FN_IN;
864 #ifdef IRQ_TRACE
865         xyz[h++] = '0' + sound_curr_lch;
866         if (h == MAX_UP - 1) {
867                 printk("%s-", xyz);
868                 h = 0;
869         }
870 #endif
871         DPRINTK("lch=%d,status=0x%x, dma_status=%d, data=%p\n", sound_curr_lch,
872                 ch_status, dma_status, data);
873
874         if (dma_status & (DCSR_ERROR)) {
875                 if (cpu_is_omap1510() || cpu_is_omap16xx())
876                         OMAP_DMA_CCR_REG(sound_curr_lch) &= ~DCCR_EN;
877                 ERR("DCSR_ERROR!\n");
878                 FN_OUT(-1);
879                 return;
880         }
881
882         if (AUDIO_QUEUE_LAST(s))
883                 audio_stop_dma(s);
884
885         /* Start the work item  - we ping pong the work items */
886         if (!work_item_running) {
887                 work1.current_lch = sound_curr_lch;
888                 work1.ch_status = ch_status;
889                 work1.s = s;
890                 /* schedule tasklet 1 */
891                 tasklet_schedule(&audio_isr_work1);
892                 work_item_running = 1;
893         } else {
894                 work2.current_lch = sound_curr_lch;
895                 work2.ch_status = ch_status;
896                 work2.s = s;
897                 /* schedule tasklet 2 */
898                 tasklet_schedule(&audio_isr_work2);
899                 work_item_running = 0;
900         }
901         FN_OUT(0);
902         return;
903 }
904
905 /* The call back that handles buffer stuff */
906 static void audio_dma_callback(int lch, u16 ch_status, void *data)
907 {
908         audio_stream_t *s = data;
909         audio_buf_t *b = &s->buffers[s->dma_tail];
910         FN_IN;
911
912         if (s->dma_spinref > 0) {
913                 s->dma_spinref--;
914         } else if (!s->buffers) {
915                 printk(KERN_CRIT
916                        "omap_audio: received DMA IRQ for non existent buffers!\n");
917                 return;
918         } else if (b->dma_ref && --b->dma_ref == 0 && b->offset >= s->fragsize) {
919                 /* This fragment is done */
920                 b->offset = 0;
921                 s->bytecount += s->fragsize;
922                 s->fragcount++;
923                 s->dma_spinref = -s->dma_spinref;
924
925                 if (++s->dma_tail >= s->nbfrags)
926                         s->dma_tail = 0;
927
928                 if (!s->mapped)
929                         complete(&s->wfc);
930                 else
931                         s->pending_frags++;
932
933                 wake_up(&s->wq);
934         }
935
936         audio_process_dma(s);
937         
938         FN_OUT(0);
939         return;
940 }
941
942 /*********************************************************************************
943  *
944  * audio_get_dma_callback(): return the dma interface call back function
945  *
946  *********************************************************************************/
947 dma_callback_t audio_get_dma_callback(void)
948 {
949         FN_IN;
950         FN_OUT(0);
951         return audio_dma_callback;
952 }
953
954 static int __init audio_dma_init(void)
955 {
956         if (!cpu_is_omap1510())
957                 nr_linked_channels = 2;
958
959         return 0;
960 }
961
962 static void __exit audio_dma_exit(void)
963 {
964         /* Nothing */
965 }
966
967 module_init(audio_dma_init);
968 module_exit(audio_dma_exit);
969
970 MODULE_AUTHOR("Texas Instruments");
971 MODULE_DESCRIPTION("Common DMA handling for Audio driver on OMAP processors");
972 MODULE_LICENSE("GPL");
973
974 EXPORT_SYMBOL(omap_clear_sound_dma);
975 EXPORT_SYMBOL(omap_request_sound_dma);
976 EXPORT_SYMBOL(omap_free_sound_dma);
977
978 EXPORT_SYMBOL(audio_get_dma_callback);
979 EXPORT_SYMBOL(audio_setup_buf);
980 EXPORT_SYMBOL(audio_process_dma);
981 EXPORT_SYMBOL(audio_prime_rx);
982 EXPORT_SYMBOL(audio_set_fragments);
983 EXPORT_SYMBOL(audio_sync);
984 EXPORT_SYMBOL(audio_stop_dma);
985 EXPORT_SYMBOL(audio_get_dma_pos);
986 EXPORT_SYMBOL(audio_reset);
987 EXPORT_SYMBOL(audio_discard_buf);