]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/oss/omap-audio.c
38857007e70f7c56a11d94efe79de2efcd14c191
[linux-2.6-omap-h63xx.git] / sound / oss / omap-audio.c
1 /*
2  * linux/sound/oss/omap-audio.c
3  *
4  * Common audio 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/08/12   Nishanth Menon - Modified to integrate Audio requirements on 1610,1710 platforms
21  *
22  * 2004-11-01   Nishanth Menon - modified to support 16xx and 17xx 
23  *                platform multi channel chaining.
24  *
25  * 2004-11-04   Nishanth Menon - Added support for power management
26  *
27  * 2004-12-17   Nishanth Menon - Provided proper module handling support
28  */
29
30 /***************************** INCLUDES ************************************/
31
32 #include <linux/config.h>
33 #include <linux/module.h>
34 #include <linux/init.h>
35 #include <linux/types.h>
36 #include <linux/fs.h>
37 #include <linux/mm.h>
38 #include <linux/slab.h>
39 #include <linux/sched.h>
40 #include <linux/poll.h>
41 #include <linux/pm.h>
42 #include <linux/errno.h>
43 #include <linux/sound.h>
44 #include <linux/soundcard.h>
45 #include <linux/sysrq.h>
46 #include <linux/delay.h>
47 #include <linux/platform_device.h>
48 #include <linux/completion.h>
49
50 #include <asm/uaccess.h>
51 #include <asm/io.h>
52 #include <asm/hardware.h>
53 #include <asm/semaphore.h>
54
55 #include "omap-audio-dma-intfc.h"
56 #include "omap-audio.h"
57
58 /***************************** MACROS ************************************/
59
60 #undef DEBUG
61 //#define DEBUG
62 #ifdef DEBUG
63 #define DPRINTK  printk
64 #define FN_IN printk("[omap_audio.c:[%s] start\n", __FUNCTION__)
65 #define FN_OUT(n) printk("[omap_audio.c:[%s] end(%d)\n", __FUNCTION__ , n)
66 #else
67 #define DPRINTK( x... )
68 #define FN_IN
69 #define FN_OUT(x)
70 #endif
71
72 #define OMAP_AUDIO_NAME         "omap-audio"
73 #define AUDIO_NBFRAGS_DEFAULT   8
74 #define AUDIO_FRAGSIZE_DEFAULT  8192
75
76 /* HACK ALERT!: These values will bave to be tuned as this is a trade off b/w
77  * Sampling Rate vs buffer size and delay we are prepared to do before giving up
78  */
79 #define MAX_QUEUE_FULL_RETRIES 1000000
80 #define QUEUE_WAIT_TIME        10
81
82 #define AUDIO_ACTIVE(state)     ((state)->rd_ref || (state)->wr_ref)
83
84 #define SPIN_ADDR               (dma_addr_t)0
85 #define SPIN_SIZE               2048
86
87 /***************************** MODULES SPECIFIC FUNCTION PROTOTYPES ********************/
88
89 static int audio_write(struct file *file, const char __user *buffer,
90                        size_t count, loff_t * ppos);
91
92 static int audio_read(struct file *file, char __user *buffer, size_t count,
93                       loff_t * ppos);
94
95 static int audio_mmap(struct file *file, struct vm_area_struct *vma);
96
97 static unsigned int audio_poll(struct file *file,
98                                struct poll_table_struct *wait);
99
100 static loff_t audio_llseek(struct file *file, loff_t offset, int origin);
101
102 static int audio_ioctl(struct inode *inode, struct file *file, uint cmd,
103                        ulong arg);
104
105 static int audio_open(struct inode *inode, struct file *file);
106
107 static int audio_release(struct inode *inode, struct file *file);
108
109 static int audio_probe(struct platform_device *pdev);
110
111 static int audio_remove(struct platform_device *pdev);
112
113 static void audio_shutdown(struct platform_device *pdev);
114
115 static int audio_suspend(struct platform_device *pdev, pm_message_t mesg);
116
117 static int audio_resume(struct platform_device *pdev);
118
119 static void audio_free(struct device *dev);
120
121 /***************************** Data Structures **********************************/
122
123 /*
124  * The function pointer set to be registered by the codec.
125  */
126 static audio_state_t audio_state = { NULL };
127
128 /* DMA Call back function */
129 static dma_callback_t audio_dma_callback = NULL;
130
131 /* File Ops structure */
132 static struct file_operations omap_audio_fops = {
133         .open           = audio_open,
134         .release        = audio_release,
135         .write          = audio_write,
136         .read           = audio_read,
137         .mmap           = audio_mmap,
138         .poll           = audio_poll,
139         .ioctl          = audio_ioctl,
140         .llseek         = audio_llseek,
141         .owner          = THIS_MODULE
142 };
143
144 /* Driver information */
145 static struct platform_driver omap_audio_driver = {
146         .probe          = audio_probe,
147         .remove         = audio_remove,
148         .suspend        = audio_suspend,
149         .shutdown       = audio_shutdown,
150         .resume         = audio_resume,
151         .driver         = {
152                 .name   = OMAP_AUDIO_NAME,
153         },
154 };
155
156 /* Device Information */
157 static struct platform_device omap_audio_device = {
158         .name = OMAP_AUDIO_NAME,
159         .dev = {
160                 .driver_data = &audio_state,
161                 .release = audio_free,
162                 },
163         .id = 0,
164 };
165
166 /***************************** GLOBAL FUNCTIONs **********************************/
167
168 /* Power Management Functions for Linux Device Model  */
169 /* DEBUG PUPOSES ONLY! */
170 #ifdef CONFIG_PM
171 //#undef CONFIG_PM
172 #endif
173
174 #ifdef CONFIG_PM
175 /*********************************************************************************
176  *
177  * audio_ldm_suspend(): Suspend operation
178  *
179  *********************************************************************************/
180 static int audio_ldm_suspend(void *data)
181 {
182         audio_state_t *state = data;
183
184         FN_IN;
185
186         /* 
187          * Reject the suspend request if we are already actively transmitting data 
188          * Rationale: We dont want to be suspended while in the middle of a call!
189          */
190         if (AUDIO_ACTIVE(state) && state->hw_init) {
191                 printk(KERN_ERR "Audio device Active, Cannot Suspend");
192                 return -EPERM;
193 #if 0
194                 /* NOTE:
195                  * This Piece of code is commented out in hope
196                  * That one day we would need to suspend the device while 
197                  * audio operations are in progress and resume the operations
198                  * once the resume is done.
199                  * This is just a sample implementation of how it could be done.
200                  * Currently NOT SUPPORTED
201                  */
202                 audio_stream_t *is = state->input_stream;
203                 audio_stream_t *os = state->output_stream;
204                 int stopstate;
205                 if (is && is->buffers) {
206                         printk("IS Suspend\n");
207                         stopstate = is->stopped;
208                         audio_stop_dma(is);
209                         DMA_CLEAR(is);
210                         is->dma_spinref = 0;
211                         is->stopped = stopstate;
212                 }
213                 if (os && os->buffers) {
214                         printk("OS Suspend\n");
215                         stopstate = os->stopped;
216                         audio_stop_dma(os);
217                         DMA_CLEAR(os);
218                         os->dma_spinref = 0;
219                         os->stopped = stopstate;
220                 }
221 #endif
222         }
223
224         FN_OUT(0);
225         return 0;
226 }
227
228 /*********************************************************************************
229  *
230  * audio_ldm_resume(): Resume Operations
231  *
232  *********************************************************************************/
233 static int audio_ldm_resume(void *data)
234 {
235         audio_state_t *state = data;
236
237         FN_IN;
238         if (AUDIO_ACTIVE(state) && state->hw_init) {
239                 /* Should never occur - since we never suspend with active state */
240                 BUG();
241                 return -EPERM;
242 #if 0
243                 /* NOTE:
244                  * This Piece of code is commented out in hope
245                  * That one day we would need to suspend the device while 
246                  * audio operations are in progress and resume the operations
247                  * once the resume is done.
248                  * This is just a sample implementation of how it could be done.
249                  * Currently NOT SUPPORTED
250                  */
251                 audio_stream_t *is = state->input_stream;
252                 audio_stream_t *os = state->output_stream;
253                 if (os && os->buffers) {
254                         printk("OS Resume\n");
255                         audio_reset(os);
256                         audio_process_dma(os);
257                 }
258                 if (is && is->buffers) {
259                         printk("IS Resume\n");
260                         audio_reset(is);
261                         audio_process_dma(is);
262                 }
263 #endif
264         }
265         FN_OUT(0);
266         return 0;
267 }
268 #endif                          /* End of #ifdef CONFIG_PM */
269
270 /*********************************************************************************
271  *
272  * audio_free(): The Audio driver release function
273  * This is a dummy function required by the platform driver
274  *
275  *********************************************************************************/
276 static void audio_free(struct device *dev)
277 {
278         /* Nothing to Release! */
279 }
280
281 /*********************************************************************************
282  *
283  * audio_probe(): The Audio driver probe function
284  * WARNING!!!!  : It is expected that the codec would have registered with us by now
285  *
286  *********************************************************************************/
287 static int audio_probe(struct platform_device *pdev)
288 {
289         int ret;
290         FN_IN;
291         if (!audio_state.hw_probe) {
292                 printk(KERN_ERR "Probe Function Not Registered\n");
293                 return -ENODEV;
294         }
295         ret = audio_state.hw_probe();
296         FN_OUT(ret);
297         return ret;
298 }
299
300 /*********************************************************************************
301  *
302  * audio_remove() Function to handle removal operations
303  *
304  *********************************************************************************/
305 static int audio_remove(struct platform_device *pdev)
306 {
307         FN_IN;
308         if (audio_state.hw_remove) {
309                 audio_state.hw_remove();
310         }
311         FN_OUT(0);
312         return 0;
313 }
314
315 /*********************************************************************************
316  *
317  * audio_shutdown(): Function to handle shutdown operations
318  *
319  *********************************************************************************/
320 static void audio_shutdown(struct platform_device *pdev)
321 {
322         FN_IN;
323         if (audio_state.hw_cleanup) {
324                 audio_state.hw_cleanup();
325         }
326         FN_OUT(0);
327         return;
328 }
329
330 /*********************************************************************************
331  *
332  * audio_suspend(): Function to handle suspend operations 
333  *
334  *********************************************************************************/
335 static int audio_suspend(struct platform_device *pdev, pm_message_t mesg)
336 {
337         int ret = 0;
338
339 #ifdef CONFIG_PM
340         void *data = pdev->dev.driver_data;
341         FN_IN;
342         if (audio_state.hw_suspend) {
343                 ret = audio_ldm_suspend(data);
344                 if (ret == 0)
345                         ret = audio_state.hw_suspend();
346         }
347         if (ret) {
348                 printk(KERN_INFO "Audio Suspend Failed \n");
349         } else {
350                 printk(KERN_INFO "Audio Suspend Success \n");
351         }
352 #endif                          /* CONFIG_PM */
353
354         FN_OUT(ret);
355         return ret;
356 }
357
358 /*********************************************************************************
359  *
360  * audio_resume(): Function to handle resume operations
361  *
362  *********************************************************************************/
363 static int audio_resume(struct platform_device *pdev)
364 {
365         int ret = 0;
366
367 #ifdef  CONFIG_PM
368         void *data = pdev->dev.driver_data;
369         FN_IN;
370         if (audio_state.hw_resume) {
371                 ret = audio_ldm_resume(data);
372                 if (ret == 0)
373                         ret = audio_state.hw_resume();
374         }
375         if (ret) {
376                 printk(KERN_INFO " Audio Resume Failed \n");
377         } else {
378                 printk(KERN_INFO " Audio Resume Success \n");
379         }
380 #endif                          /* CONFIG_PM */
381
382         FN_OUT(ret);
383         return ret;
384 }
385
386 /*********************************************************************************
387  *
388  * audio_get_fops(): Return the fops required to get the function pointers of 
389  *                   OMAP Audio Driver
390  *
391  *********************************************************************************/
392 struct file_operations *audio_get_fops(void)
393 {
394         FN_IN;
395         FN_OUT(0);
396         return &omap_audio_fops;
397 }
398
399 /*********************************************************************************
400  *
401  * audio_register_codec(): Register a Codec fn points using this function
402  * WARNING!!!!!          : Codecs should ensure that they do so! no sanity checks
403  *                         during runtime is done due to obvious performance 
404  *                         penalties.
405  *
406  *********************************************************************************/
407 int audio_register_codec(audio_state_t * codec_state)
408 {
409         int ret;
410         FN_IN;
411
412         /* We dont handle multiple codecs now */
413         if (audio_state.hw_init) {
414                 printk(KERN_ERR " Codec Already registered\n");
415                 return -EPERM;
416         }
417
418         /* Grab the dma Callback */
419         audio_dma_callback = audio_get_dma_callback();
420         if (!audio_dma_callback) {
421                 printk(KERN_ERR "Unable to get call back function\n");
422                 return -EPERM;
423         }
424
425         /* Sanity checks */
426         if (!codec_state) {
427                 printk(KERN_ERR "NULL ARGUMENT!\n");
428                 return -EPERM;
429         }
430
431         if (!codec_state->hw_probe || !codec_state->hw_init
432             || !codec_state->hw_shutdown || !codec_state->client_ioctl) {
433                 printk(KERN_ERR
434                        "Required Fn Entry point Missing probe=%p init=%p,down=%p,ioctl=%p!\n",
435                        codec_state->hw_probe, codec_state->hw_init,
436                        codec_state->hw_shutdown, codec_state->client_ioctl);
437                 return -EPERM;
438         }
439
440         memcpy(&audio_state, codec_state, sizeof(audio_state_t));
441         sema_init(&audio_state.sem, 1);
442
443         ret = platform_device_register(&omap_audio_device);
444         if (ret != 0) {
445                 printk(KERN_ERR "Platform dev_register failed =%d\n", ret);
446                 ret = -ENODEV;
447                 goto register_out;
448         }
449
450         ret = platform_driver_register(&omap_audio_driver);
451         if (ret != 0) {
452                 printk(KERN_ERR "Device Register failed =%d\n", ret);
453                 ret = -ENODEV;
454                 platform_device_unregister(&omap_audio_device);
455                 goto register_out;
456         }
457
458       register_out:
459
460         FN_OUT(ret);
461         return ret;
462 }
463
464 /*********************************************************************************
465  *
466  * audio_unregister_codec(): Un-Register a Codec using this function
467  *
468  *********************************************************************************/
469 int audio_unregister_codec(audio_state_t * codec_state)
470 {
471         FN_IN;
472
473         /* We dont handle multiple codecs now */
474         if (!audio_state.hw_init) {
475                 printk(KERN_ERR " No Codec registered\n");
476                 return -EPERM;
477         }
478         /* Security check */
479         if (audio_state.hw_init != codec_state->hw_init) {
480                 printk(KERN_ERR
481                        " Attempt to unregister codec which was not registered with us\n");
482                 return -EPERM;
483         }
484
485         platform_driver_unregister(&omap_audio_driver);
486         platform_device_unregister(&omap_audio_device);
487
488         memset(&audio_state, 0, sizeof(audio_state_t));
489
490         FN_OUT(0);
491         return 0;
492 }
493
494 /***************************** MODULES SPECIFIC FUNCTION *************************/
495
496 /*********************************************************************************
497  *
498  * audio_write(): Exposed to write() call
499  *
500  *********************************************************************************/
501 static int
502 audio_write(struct file *file, const char __user *buffer,
503                 size_t count, loff_t * ppos)
504 {
505         const char __user *buffer0 = buffer;
506         audio_state_t *state = file->private_data;
507         audio_stream_t *s = state->output_stream;
508         int chunksize, ret = 0;
509
510         DPRINTK("audio_write: count=%d\n", count);
511         if (*ppos != file->f_pos) {
512                 printk("FPOS not ppos ppos=0x%x fpos =0x%x\n", (u32) * ppos,
513                        (u32) file->f_pos);
514                 return -ESPIPE;
515         }
516         if (s->mapped) {
517                 printk("s already mapped\n");
518                 return -ENXIO;
519         }
520         if (!s->buffers && audio_setup_buf(s)) {
521                 printk("NO MEMORY\n");
522                 return -ENOMEM;
523         }
524
525         while (count > 0) {
526                 audio_buf_t *b = &s->buffers[s->usr_head];
527
528                 /* Wait for a buffer to become free */
529                 if (file->f_flags & O_NONBLOCK) {
530                         ret = -EAGAIN;
531                         if (!s->wfc.done)
532                                 break;
533                 }
534                 ret = -ERESTARTSYS;
535                 if (wait_for_completion_interruptible(&s->wfc))
536                         break;
537
538                 /* Feed the current buffer */
539                 chunksize = s->fragsize - b->offset;
540                 if (chunksize > count)
541                         chunksize = count;
542                 DPRINTK("write %d to %d\n", chunksize, s->usr_head);
543                 if (copy_from_user(b->data + b->offset, buffer, chunksize)) {
544                         printk(KERN_ERR "Audio: CopyFrom User failed \n");
545                         complete(&s->wfc);
546                         return -EFAULT;
547                 }
548
549                 buffer += chunksize;
550                 count -= chunksize;
551                 b->offset += chunksize;
552
553                 if (b->offset < s->fragsize) {
554                         complete(&s->wfc);
555                         break;
556                 }
557
558                 /* Update pointers and send current fragment to DMA */
559                 b->offset = 0;
560                 if (++s->usr_head >= s->nbfrags)
561                         s->usr_head = 0;
562                 /* Add the num of frags pending */
563                 s->pending_frags++;
564                 s->active = 1;
565
566                 audio_process_dma(s);
567
568         }
569
570         if ((buffer - buffer0))
571                 ret = buffer - buffer0;
572         DPRINTK("audio_write: return=%d\n", ret);
573         return ret;
574 }
575
576 /*********************************************************************************
577  *
578  * audio_read(): Exposed as read() function
579  *
580  *********************************************************************************/
581 static int
582 audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
583 {
584         char __user *buffer0 = buffer;
585         audio_state_t *state = file->private_data;
586         audio_stream_t *s = state->input_stream;
587         int chunksize, ret = 0;
588         unsigned long flags;
589
590         DPRINTK("audio_read: count=%d\n", count);
591
592         if (*ppos != file->f_pos) {
593                 printk("AudioRead - FPOS not ppos ppos=0x%x fpos =0x%x\n",
594                        (u32) * ppos, (u32) file->f_pos);
595                 return -ESPIPE;
596         }
597         if (s->mapped) {
598                 printk("AudioRead - s already mapped\n");
599                 return -ENXIO;
600         }
601
602         if (!s->active) {
603                 if (!s->buffers && audio_setup_buf(s)) {
604                         printk("AudioRead - No Memory\n");
605                         return -ENOMEM;
606                 }
607                 audio_prime_rx(state);
608         }
609
610         while (count > 0) {
611                 audio_buf_t *b = &s->buffers[s->usr_head];
612
613                 /* Wait for a buffer to become full */
614                 if (file->f_flags & O_NONBLOCK) {
615                         ret = -EAGAIN;
616                         if (!s->wfc.done)
617                                 break;
618                 }
619                 ret = -ERESTARTSYS;
620                 if (wait_for_completion_interruptible(&s->wfc))
621                         break;
622
623                 /* Grab data from the current buffer */
624                 chunksize = s->fragsize - b->offset;
625                 if (chunksize > count)
626                         chunksize = count;
627                 DPRINTK("read %d from %d\n", chunksize, s->usr_head);
628                 if (copy_to_user(buffer, b->data + b->offset, chunksize)) {
629                         complete(&s->wfc);
630                         return -EFAULT;
631                 }
632                 buffer += chunksize;
633                 count -= chunksize;
634                 b->offset += chunksize;
635                 if (b->offset < s->fragsize) {
636                         complete(&s->wfc);
637                         break;
638                 }
639
640                 /* Update pointers and return current fragment to DMA */
641                 local_irq_save(flags);
642                 b->offset = 0;
643                 if (++s->usr_head >= s->nbfrags)
644                         s->usr_head = 0;
645
646                 s->pending_frags++;
647                 local_irq_restore(flags);
648                 audio_process_dma(s);
649
650         }
651
652         if ((buffer - buffer0))
653                 ret = buffer - buffer0;
654         DPRINTK("audio_read: return=%d\n", ret);
655         return ret;
656 }
657
658 /*********************************************************************************
659  *
660  * audio_mmap(): Exposed as mmap Function
661  * !!WARNING: Still under development
662  *
663  *********************************************************************************/
664 static int audio_mmap(struct file *file, struct vm_area_struct *vma)
665 {
666         audio_state_t *state = file->private_data;
667         audio_stream_t *s;
668         unsigned long size, vma_addr;
669         int i, ret;
670
671         FN_IN;
672         if (vma->vm_pgoff != 0)
673                 return -EINVAL;
674
675         if (vma->vm_flags & VM_WRITE) {
676                 if (!state->wr_ref)
677                         return -EINVAL;;
678                 s = state->output_stream;
679         } else if (vma->vm_flags & VM_READ) {
680                 if (!state->rd_ref)
681                         return -EINVAL;
682                 s = state->input_stream;
683         } else
684                 return -EINVAL;
685
686         if (s->mapped)
687                 return -EINVAL;
688         size = vma->vm_end - vma->vm_start;
689         if (size != s->fragsize * s->nbfrags)
690                 return -EINVAL;
691         if (!s->buffers && audio_setup_buf(s))
692                 return -ENOMEM;
693         vma_addr = vma->vm_start;
694         for (i = 0; i < s->nbfrags; i++) {
695                 audio_buf_t *buf = &s->buffers[i];
696                 if (!buf->master)
697                         continue;
698                 ret =
699                     remap_pfn_range(vma, vma_addr, buf->dma_addr >> PAGE_SHIFT,
700                                     buf->master, vma->vm_page_prot);
701                 if (ret)
702                         return ret;
703                 vma_addr += buf->master;
704         }
705         s->mapped = 1;
706
707         FN_OUT(0);
708         return 0;
709 }
710
711 /*********************************************************************************
712  *
713  * audio_poll(): Exposed as poll function
714  *
715  *********************************************************************************/
716 static unsigned int
717 audio_poll(struct file *file, struct poll_table_struct *wait)
718 {
719         audio_state_t *state = file->private_data;
720         audio_stream_t *is = state->input_stream;
721         audio_stream_t *os = state->output_stream;
722         unsigned int mask = 0;
723
724         DPRINTK("audio_poll(): mode=%s%s\n",
725                 (file->f_mode & FMODE_READ) ? "r" : "",
726                 (file->f_mode & FMODE_WRITE) ? "w" : "");
727
728         if (file->f_mode & FMODE_READ) {
729                 /* Start audio input if not already active */
730                 if (!is->active) {
731                         if (!is->buffers && audio_setup_buf(is))
732                                 return -ENOMEM;
733                         audio_prime_rx(state);
734                 }
735                 poll_wait(file, &is->wq, wait);
736         }
737
738         if (file->f_mode & FMODE_WRITE) {
739                 if (!os->buffers && audio_setup_buf(os))
740                         return -ENOMEM;
741                 poll_wait(file, &os->wq, wait);
742         }
743
744         if (file->f_mode & FMODE_READ)
745                 if ((is->mapped && is->bytecount > 0) ||
746                     (!is->mapped && is->wfc.done > 0))
747                         mask |= POLLIN | POLLRDNORM;
748
749         if (file->f_mode & FMODE_WRITE)
750                 if ((os->mapped && os->bytecount > 0) ||
751                     (!os->mapped && os->wfc.done > 0))
752                         mask |= POLLOUT | POLLWRNORM;
753
754         DPRINTK("audio_poll() returned mask of %s%s\n",
755                 (mask & POLLIN) ? "r" : "", (mask & POLLOUT) ? "w" : "");
756
757         FN_OUT(mask);
758         return mask;
759 }
760
761 /*********************************************************************************
762  *
763  * audio_llseek(): Exposed as lseek() function.
764  *
765  *********************************************************************************/
766 static loff_t audio_llseek(struct file *file, loff_t offset, int origin)
767 {
768         FN_IN;
769         FN_OUT(0);
770         return -ESPIPE;
771 }
772
773 /*********************************************************************************
774  *
775  * audio_ioctl(): Handles generic ioctls. If there is a request for something this
776  * fn cannot handle, its then given to client specific ioctl routine, that will take
777  * up platform specific requests
778  *
779  *********************************************************************************/
780 static int
781 audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
782 {
783         audio_state_t *state = file->private_data;
784         audio_stream_t *os = state->output_stream;
785         audio_stream_t *is = state->input_stream;
786         long val;
787
788         DPRINTK(__FILE__ " audio_ioctl 0x%08x\n", cmd);
789
790         /* dispatch based on command */
791         switch (cmd) {
792         case OSS_GETVERSION:
793                 return put_user(SOUND_VERSION, (int __user *)arg);
794
795         case SNDCTL_DSP_GETBLKSIZE:
796                 if (file->f_mode & FMODE_WRITE)
797                         return put_user(os->fragsize, (int __user *)arg);
798                 else
799                         return put_user(is->fragsize, (int __user *)arg);
800
801         case SNDCTL_DSP_GETCAPS:
802                 val = DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP;
803                 if (is && os)
804                         val |= DSP_CAP_DUPLEX;
805                 FN_OUT(1);
806                 return put_user(val, (int __user *)arg);
807
808         case SNDCTL_DSP_SETFRAGMENT:
809                 if (get_user(val, (long __user *)arg)) {
810                         FN_OUT(2);
811                         return -EFAULT;
812                 }
813                 if (file->f_mode & FMODE_READ) {
814                         int ret = audio_set_fragments(is, val);
815                         if (ret < 0) {
816                                 FN_OUT(3);
817                                 return ret;
818                         }
819                         ret = put_user(ret, (int __user *)arg);
820                         if (ret) {
821                                 FN_OUT(4);
822                                 return ret;
823                         }
824                 }
825                 if (file->f_mode & FMODE_WRITE) {
826                         int ret = audio_set_fragments(os, val);
827                         if (ret < 0) {
828                                 FN_OUT(5);
829                                 return ret;
830                         }
831                         ret = put_user(ret, (int __user *)arg);
832                         if (ret) {
833                                 FN_OUT(6);
834                                 return ret;
835                         }
836                 }
837                 FN_OUT(7);
838                 return 0;
839
840         case SNDCTL_DSP_SYNC:
841                 FN_OUT(8);
842                 return audio_sync(file);
843
844         case SNDCTL_DSP_SETDUPLEX:
845                 FN_OUT(9);
846                 return 0;
847
848         case SNDCTL_DSP_POST:
849                 FN_OUT(10);
850                 return 0;
851
852         case SNDCTL_DSP_GETTRIGGER:
853                 val = 0;
854                 if (file->f_mode & FMODE_READ && is->active && !is->stopped)
855                         val |= PCM_ENABLE_INPUT;
856                 if (file->f_mode & FMODE_WRITE && os->active && !os->stopped)
857                         val |= PCM_ENABLE_OUTPUT;
858                 FN_OUT(11);
859                 return put_user(val, (int __user *)arg);
860
861         case SNDCTL_DSP_SETTRIGGER:
862                 if (get_user(val, (int __user *)arg)) {
863                         FN_OUT(12);
864                         return -EFAULT;
865                 }
866                 if (file->f_mode & FMODE_READ) {
867                         if (val & PCM_ENABLE_INPUT) {
868                                 unsigned long flags;
869                                 if (!is->active) {
870                                         if (!is->buffers && audio_setup_buf(is)) {
871                                                 FN_OUT(13);
872                                                 return -ENOMEM;
873                                         }
874                                         audio_prime_rx(state);
875                                 }
876                                 local_irq_save(flags);
877                                 is->stopped = 0;
878                                 local_irq_restore(flags);
879                                 audio_process_dma(is);
880
881                         } else {
882                                 audio_stop_dma(is);
883                         }
884                 }
885                 if (file->f_mode & FMODE_WRITE) {
886                         if (val & PCM_ENABLE_OUTPUT) {
887                                 unsigned long flags;
888                                 if (!os->buffers && audio_setup_buf(os)) {
889                                         FN_OUT(14);
890                                         return -ENOMEM;
891                                 }
892                                 local_irq_save(flags);
893                                 if (os->mapped && !os->pending_frags) {
894                                         os->pending_frags = os->nbfrags;
895                                         init_completion(&os->wfc);
896                                         os->wfc.done = 0;
897                                         os->active = 1;
898                                 }
899                                 os->stopped = 0;
900                                 local_irq_restore(flags);
901                                 audio_process_dma(os);
902
903                         } else {
904                                 audio_stop_dma(os);
905                         }
906                 }
907                 FN_OUT(15);
908                 return 0;
909
910         case SNDCTL_DSP_GETOPTR:
911         case SNDCTL_DSP_GETIPTR:
912                 {
913                         count_info inf = { 0, };
914                         audio_stream_t *s =
915                             (cmd == SNDCTL_DSP_GETOPTR) ? os : is;
916                         int bytecount, offset;
917                         unsigned long flags;
918
919                         if ((s == is && !(file->f_mode & FMODE_READ)) ||
920                             (s == os && !(file->f_mode & FMODE_WRITE))) {
921                                 FN_OUT(16);
922                                 return -EINVAL;
923                         }
924                         if (s->active) {
925                                 local_irq_save(flags);
926                                 offset = audio_get_dma_pos(s);
927                                 inf.ptr = s->dma_tail * s->fragsize + offset;
928                                 bytecount = s->bytecount + offset;
929                                 s->bytecount = -offset;
930                                 inf.blocks = s->fragcount;
931                                 s->fragcount = 0;
932                                 local_irq_restore(flags);
933                                 if (bytecount < 0)
934                                         bytecount = 0;
935                                 inf.bytes = bytecount;
936                         }
937                         FN_OUT(17);
938                         return copy_to_user((void __user *)arg, &inf, sizeof(inf));
939                 }
940
941         case SNDCTL_DSP_GETOSPACE:
942         case SNDCTL_DSP_GETISPACE:
943                 {
944                         audio_buf_info inf = { 0, };
945                         audio_stream_t *s =
946                             (cmd == SNDCTL_DSP_GETOSPACE) ? os : is;
947
948                         if ((s == is && !(file->f_mode & FMODE_READ)) ||
949                             (s == os && !(file->f_mode & FMODE_WRITE))) {
950                                 FN_OUT(18);
951                                 return -EINVAL;
952                         }
953                         if (!s->buffers && audio_setup_buf(s)) {
954                                 FN_OUT(19);
955                                 return -ENOMEM;
956                         }
957                         inf.bytes = s->wfc.done * s->fragsize;
958
959                         inf.fragments = inf.bytes / s->fragsize;
960                         inf.fragsize = s->fragsize;
961                         inf.fragstotal = s->nbfrags;
962                         FN_OUT(20);
963                         return copy_to_user((void __user *)arg, &inf, sizeof(inf));
964                 }
965
966         case SNDCTL_DSP_NONBLOCK:
967                 file->f_flags |= O_NONBLOCK;
968                 FN_OUT(21);
969                 return 0;
970
971         case SNDCTL_DSP_RESET:
972                 if (file->f_mode & FMODE_READ) {
973                         audio_reset(is);
974                         if (state->need_tx_for_rx) {
975                                 unsigned long flags;
976                                 local_irq_save(flags);
977                                 os->spin_idle = 0;
978                                 local_irq_restore(flags);
979                         }
980                 }
981                 if (file->f_mode & FMODE_WRITE) {
982                         audio_reset(os);
983                 }
984                 FN_OUT(22);
985                 return 0;
986
987         default:
988                 /*
989                  * Let the client of this module handle the
990                  * non generic ioctls
991                  */
992                 FN_OUT(23);
993                 return state->client_ioctl(inode, file, cmd, arg);
994         }
995
996         FN_OUT(0);
997         return 0;
998 }
999
1000 /*********************************************************************************
1001  *
1002  * audio_open(): Exposed as open() function
1003  *
1004  *********************************************************************************/
1005 static int audio_open(struct inode *inode, struct file *file)
1006 {
1007         audio_state_t *state = (&audio_state);
1008         audio_stream_t *os = state->output_stream;
1009         audio_stream_t *is = state->input_stream;
1010         int err, need_tx_dma;
1011         static unsigned char tsc2101_init_flag = 0;
1012
1013         FN_IN;
1014
1015         /* Lock the module */
1016         if (!try_module_get(THIS_MODULE)) {
1017                 printk(KERN_CRIT "Failed to get module\n");
1018                 return -ESTALE;
1019         }
1020         /* Lock the codec module */
1021         if (!try_module_get(state->owner)) {
1022                 printk(KERN_CRIT "Failed to get codec module\n");
1023                 module_put(THIS_MODULE);
1024                 return -ESTALE;
1025         }
1026
1027         down(&state->sem);
1028
1029         /* access control */
1030         err = -ENODEV;
1031         if ((file->f_mode & FMODE_WRITE) && !os)
1032                 goto out;
1033         if ((file->f_mode & FMODE_READ) && !is)
1034                 goto out;
1035         err = -EBUSY;
1036         if ((file->f_mode & FMODE_WRITE) && state->wr_ref)
1037                 goto out;
1038         if ((file->f_mode & FMODE_READ) && state->rd_ref)
1039                 goto out;
1040         err = -EINVAL;
1041         if ((file->f_mode & FMODE_READ) && state->need_tx_for_rx && !os)
1042                 goto out;
1043
1044         /* request DMA channels */
1045         need_tx_dma = ((file->f_mode & FMODE_WRITE) ||
1046                        ((file->f_mode & FMODE_READ) && state->need_tx_for_rx));
1047         if (state->wr_ref || (state->rd_ref && state->need_tx_for_rx))
1048                 need_tx_dma = 0;
1049         if (need_tx_dma) {
1050                 DMA_REQUEST(err, os, audio_dma_callback);
1051                 if (err < 0)
1052                         goto out;
1053         }
1054         if (file->f_mode & FMODE_READ) {
1055                 DMA_REQUEST(err, is, audio_dma_callback);
1056                 if (err < 0) {
1057                         if (need_tx_dma)
1058                                 DMA_FREE(os);
1059                         goto out;
1060                 }
1061         }
1062
1063         /* now complete initialisation */
1064         if (!AUDIO_ACTIVE(state)) {
1065                 if (state->hw_init && !tsc2101_init_flag) {
1066                         state->hw_init(state->data);
1067                         tsc2101_init_flag = 0;
1068
1069                 }
1070
1071         }
1072
1073         if ((file->f_mode & FMODE_WRITE)) {
1074                 state->wr_ref = 1;
1075                 audio_reset(os);
1076                 os->fragsize = AUDIO_FRAGSIZE_DEFAULT;
1077                 os->nbfrags = AUDIO_NBFRAGS_DEFAULT;
1078                 os->mapped = 0;
1079                 init_waitqueue_head(&os->wq);
1080         }
1081
1082         if (file->f_mode & FMODE_READ) {
1083                 state->rd_ref = 1;
1084                 audio_reset(is);
1085                 is->fragsize = AUDIO_FRAGSIZE_DEFAULT;
1086                 is->nbfrags = AUDIO_NBFRAGS_DEFAULT;
1087                 is->mapped = 0;
1088                 init_waitqueue_head(&is->wq);
1089         }
1090
1091         file->private_data = state;
1092         err = 0;
1093
1094       out:
1095         up(&state->sem);
1096         if (err) {
1097                 module_put(state->owner);
1098                 module_put(THIS_MODULE);
1099         }
1100         FN_OUT(err);
1101         return err;
1102 }
1103
1104 /*********************************************************************************
1105  *
1106  * audio_release(): Exposed as release function()
1107  *
1108  *********************************************************************************/
1109 static int audio_release(struct inode *inode, struct file *file)
1110 {
1111         audio_state_t *state = file->private_data;
1112         audio_stream_t *os = state->output_stream;
1113         audio_stream_t *is = state->input_stream;
1114
1115         FN_IN;
1116
1117         down(&state->sem);
1118
1119         if (file->f_mode & FMODE_READ) {
1120                 audio_discard_buf(is);
1121                 DMA_FREE(is);
1122                 is->dma_spinref = 0;
1123                 if (state->need_tx_for_rx) {
1124                         os->spin_idle = 0;
1125                         if (!state->wr_ref) {
1126                                 DMA_FREE(os);
1127                                 os->dma_spinref = 0;
1128                         }
1129                 }
1130                 state->rd_ref = 0;
1131         }
1132
1133         if (file->f_mode & FMODE_WRITE) {
1134                 audio_sync(file);
1135                 audio_discard_buf(os);
1136                 if (!state->need_tx_for_rx || !state->rd_ref) {
1137                         DMA_FREE(os);
1138                         os->dma_spinref = 0;
1139                 }
1140                 state->wr_ref = 0;
1141         }
1142
1143         if (!AUDIO_ACTIVE(state)) {
1144                 if (state->hw_shutdown)
1145                         state->hw_shutdown(state->data);
1146         }
1147
1148         up(&state->sem);
1149
1150         module_put(state->owner);
1151         module_put(THIS_MODULE);
1152
1153         FN_OUT(0);
1154         return 0;
1155 }
1156
1157 EXPORT_SYMBOL(audio_register_codec);
1158 EXPORT_SYMBOL(audio_unregister_codec);
1159 EXPORT_SYMBOL(audio_get_fops);
1160
1161 MODULE_AUTHOR("Texas Instruments");
1162 MODULE_DESCRIPTION("Common audio handling for OMAP processors");
1163 MODULE_LICENSE("GPL");