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