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