]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/oss/omap-audio.c
Merge with /home/tmlind/src/kernel/linux-2.6
[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/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 device *dev);
110
111 static int audio_remove(struct device *dev);
112
113 static void audio_shutdown(struct device *dev);
114
115 static int audio_suspend(struct device *dev, pm_message_t mesg, u32 level);
116
117 static int audio_resume(struct device *dev, u32 level);
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 device_driver omap_audio_driver = {
146         .name           = OMAP_AUDIO_NAME,
147         .bus            = &platform_bus_type,
148         .probe          = audio_probe,
149         .remove         = audio_remove,
150         .suspend        = audio_suspend,
151         .resume         = audio_resume,
152         .shutdown       = audio_shutdown,
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 device *dev)
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 device *dev)
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 device *dev)
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 device *dev, pm_message_t mesg, u32 level)
335 {
336         int ret = 0;
337
338 #ifdef CONFIG_PM
339         void *data = dev->driver_data;
340         FN_IN;
341         if (level != SUSPEND_POWER_DOWN) {
342                 return 0;
343         }
344         if (audio_state.hw_suspend) {
345                 ret = audio_ldm_suspend(data);
346                 if (ret == 0)
347                         ret = audio_state.hw_suspend();
348         }
349         if (ret) {
350                 printk(KERN_INFO "Audio Suspend Failed \n");
351         } else {
352                 printk(KERN_INFO "Audio Suspend Success \n");
353         }
354 #endif                          /* CONFIG_PM */
355
356         FN_OUT(ret);
357         return ret;
358 }
359
360 /*********************************************************************************
361  *
362  * audio_resume(): Function to handle resume operations
363  *
364  *********************************************************************************/
365 static int audio_resume(struct device *dev, u32 level)
366 {
367         int ret = 0;
368
369 #ifdef  CONFIG_PM
370         void *data = dev->driver_data;
371         FN_IN;
372         if (level != RESUME_POWER_ON) {
373                 return 0;
374         }
375         if (audio_state.hw_resume) {
376                 ret = audio_ldm_resume(data);
377                 if (ret == 0)
378                         ret = audio_state.hw_resume();
379         }
380         if (ret) {
381                 printk(KERN_INFO " Audio Resume Failed \n");
382         } else {
383                 printk(KERN_INFO " Audio Resume Success \n");
384         }
385 #endif                          /* CONFIG_PM */
386
387         FN_OUT(ret);
388         return ret;
389 }
390
391 /*********************************************************************************
392  *
393  * audio_get_fops(): Return the fops required to get the function pointers of 
394  *                   OMAP Audio Driver
395  *
396  *********************************************************************************/
397 struct file_operations *audio_get_fops(void)
398 {
399         FN_IN;
400         FN_OUT(0);
401         return &omap_audio_fops;
402 }
403
404 /*********************************************************************************
405  *
406  * audio_register_codec(): Register a Codec fn points using this function
407  * WARNING!!!!!          : Codecs should ensure that they do so! no sanity checks
408  *                         during runtime is done due to obvious performance 
409  *                         penalties.
410  *
411  *********************************************************************************/
412 int audio_register_codec(audio_state_t * codec_state)
413 {
414         int ret;
415         FN_IN;
416
417         /* We dont handle multiple codecs now */
418         if (audio_state.hw_init) {
419                 printk(KERN_ERR " Codec Already registered\n");
420                 return -EPERM;
421         }
422
423         /* Grab the dma Callback */
424         audio_dma_callback = audio_get_dma_callback();
425         if (!audio_dma_callback) {
426                 printk(KERN_ERR "Unable to get call back function\n");
427                 return -EPERM;
428         }
429
430         /* Sanity checks */
431         if (!codec_state) {
432                 printk(KERN_ERR "NULL ARGUMENT!\n");
433                 return -EPERM;
434         }
435
436         if (!codec_state->hw_probe || !codec_state->hw_init
437             || !codec_state->hw_shutdown || !codec_state->client_ioctl) {
438                 printk(KERN_ERR
439                        "Required Fn Entry point Missing probe=%p init=%p,down=%p,ioctl=%p!\n",
440                        codec_state->hw_probe, codec_state->hw_init,
441                        codec_state->hw_shutdown, codec_state->client_ioctl);
442                 return -EPERM;
443         }
444
445         memcpy(&audio_state, codec_state, sizeof(audio_state_t));
446         sema_init(&audio_state.sem, 1);
447
448         ret = platform_device_register(&omap_audio_device);
449         if (ret != 0) {
450                 printk(KERN_ERR "Platform dev_register failed =%d\n", ret);
451                 ret = -ENODEV;
452                 goto register_out;
453         }
454
455         ret = driver_register(&omap_audio_driver);
456         if (ret != 0) {
457                 printk(KERN_ERR "Device Register failed =%d\n", ret);
458                 ret = -ENODEV;
459                 platform_device_unregister(&omap_audio_device);
460                 goto register_out;
461         }
462
463       register_out:
464
465         FN_OUT(ret);
466         return ret;
467 }
468
469 /*********************************************************************************
470  *
471  * audio_unregister_codec(): Un-Register a Codec using this function
472  *
473  *********************************************************************************/
474 int audio_unregister_codec(audio_state_t * codec_state)
475 {
476         FN_IN;
477
478         /* We dont handle multiple codecs now */
479         if (!audio_state.hw_init) {
480                 printk(KERN_ERR " No Codec registered\n");
481                 return -EPERM;
482         }
483         /* Security check */
484         if (audio_state.hw_init != codec_state->hw_init) {
485                 printk(KERN_ERR
486                        " Attempt to unregister codec which was not registered with us\n");
487                 return -EPERM;
488         }
489
490         driver_unregister(&omap_audio_driver);
491         platform_device_unregister(&omap_audio_device);
492
493         memset(&audio_state, 0, sizeof(audio_state_t));
494
495         FN_OUT(0);
496         return 0;
497 }
498
499 /***************************** MODULES SPECIFIC FUNCTION *************************/
500
501 /*********************************************************************************
502  *
503  * audio_write(): Exposed to write() call
504  *
505  *********************************************************************************/
506 static int
507 audio_write(struct file *file, const char __user *buffer,
508                 size_t count, loff_t * ppos)
509 {
510         const char __user *buffer0 = buffer;
511         audio_state_t *state = file->private_data;
512         audio_stream_t *s = state->output_stream;
513         int chunksize, ret = 0;
514
515         DPRINTK("audio_write: count=%d\n", count);
516         if (*ppos != file->f_pos) {
517                 printk("FPOS not ppos ppos=0x%x fpos =0x%x\n", (u32) * ppos,
518                        (u32) file->f_pos);
519                 return -ESPIPE;
520         }
521         if (s->mapped) {
522                 printk("s already mapped\n");
523                 return -ENXIO;
524         }
525         if (!s->buffers && audio_setup_buf(s)) {
526                 printk("NO MEMORY\n");
527                 return -ENOMEM;
528         }
529
530         while (count > 0) {
531                 audio_buf_t *b = &s->buffers[s->usr_head];
532
533                 /* Wait for a buffer to become free */
534                 if (file->f_flags & O_NONBLOCK) {
535                         ret = -EAGAIN;
536                         if (!s->wfc.done)
537                                 break;
538                 }
539                 ret = -ERESTARTSYS;
540                 if (wait_for_completion_interruptible(&s->wfc))
541                         break;
542
543                 /* Feed the current buffer */
544                 chunksize = s->fragsize - b->offset;
545                 if (chunksize > count)
546                         chunksize = count;
547                 DPRINTK("write %d to %d\n", chunksize, s->usr_head);
548                 if (copy_from_user(b->data + b->offset, buffer, chunksize)) {
549                         printk(KERN_ERR "Audio: CopyFrom User failed \n");
550                         complete(&s->wfc);
551                         return -EFAULT;
552                 }
553
554                 buffer += chunksize;
555                 count -= chunksize;
556                 b->offset += chunksize;
557
558                 if (b->offset < s->fragsize) {
559                         complete(&s->wfc);
560                         break;
561                 }
562
563                 /* Update pointers and send current fragment to DMA */
564                 b->offset = 0;
565                 if (++s->usr_head >= s->nbfrags)
566                         s->usr_head = 0;
567                 /* Add the num of frags pending */
568                 s->pending_frags++;
569                 s->active = 1;
570
571                 audio_process_dma(s);
572
573         }
574
575         if ((buffer - buffer0))
576                 ret = buffer - buffer0;
577         DPRINTK("audio_write: return=%d\n", ret);
578         return ret;
579 }
580
581 /*********************************************************************************
582  *
583  * audio_read(): Exposed as read() function
584  *
585  *********************************************************************************/
586 static int
587 audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
588 {
589         char __user *buffer0 = buffer;
590         audio_state_t *state = file->private_data;
591         audio_stream_t *s = state->input_stream;
592         int chunksize, ret = 0;
593         unsigned long flags;
594
595         DPRINTK("audio_read: count=%d\n", count);
596
597         if (*ppos != file->f_pos) {
598                 printk("AudioRead - FPOS not ppos ppos=0x%x fpos =0x%x\n",
599                        (u32) * ppos, (u32) file->f_pos);
600                 return -ESPIPE;
601         }
602         if (s->mapped) {
603                 printk("AudioRead - s already mapped\n");
604                 return -ENXIO;
605         }
606
607         if (!s->active) {
608                 if (!s->buffers && audio_setup_buf(s)) {
609                         printk("AudioRead - No Memory\n");
610                         return -ENOMEM;
611                 }
612                 audio_prime_rx(state);
613         }
614
615         while (count > 0) {
616                 audio_buf_t *b = &s->buffers[s->usr_head];
617
618                 /* Wait for a buffer to become full */
619                 if (file->f_flags & O_NONBLOCK) {
620                         ret = -EAGAIN;
621                         if (!s->wfc.done)
622                                 break;
623                 }
624                 ret = -ERESTARTSYS;
625                 if (wait_for_completion_interruptible(&s->wfc))
626                         break;
627
628                 /* Grab data from the current buffer */
629                 chunksize = s->fragsize - b->offset;
630                 if (chunksize > count)
631                         chunksize = count;
632                 DPRINTK("read %d from %d\n", chunksize, s->usr_head);
633                 if (copy_to_user(buffer, b->data + b->offset, chunksize)) {
634                         complete(&s->wfc);
635                         return -EFAULT;
636                 }
637                 buffer += chunksize;
638                 count -= chunksize;
639                 b->offset += chunksize;
640                 if (b->offset < s->fragsize) {
641                         complete(&s->wfc);
642                         break;
643                 }
644
645                 /* Update pointers and return current fragment to DMA */
646                 local_irq_save(flags);
647                 b->offset = 0;
648                 if (++s->usr_head >= s->nbfrags)
649                         s->usr_head = 0;
650
651                 s->pending_frags++;
652                 local_irq_restore(flags);
653                 audio_process_dma(s);
654
655         }
656
657         if ((buffer - buffer0))
658                 ret = buffer - buffer0;
659         DPRINTK("audio_read: return=%d\n", ret);
660         return ret;
661 }
662
663 /*********************************************************************************
664  *
665  * audio_mmap(): Exposed as mmap Function
666  * !!WARNING: Still under development
667  *
668  *********************************************************************************/
669 static int audio_mmap(struct file *file, struct vm_area_struct *vma)
670 {
671         audio_state_t *state = file->private_data;
672         audio_stream_t *s;
673         unsigned long size, vma_addr;
674         int i, ret;
675
676         FN_IN;
677         if (vma->vm_pgoff != 0)
678                 return -EINVAL;
679
680         if (vma->vm_flags & VM_WRITE) {
681                 if (!state->wr_ref)
682                         return -EINVAL;;
683                 s = state->output_stream;
684         } else if (vma->vm_flags & VM_READ) {
685                 if (!state->rd_ref)
686                         return -EINVAL;
687                 s = state->input_stream;
688         } else
689                 return -EINVAL;
690
691         if (s->mapped)
692                 return -EINVAL;
693         size = vma->vm_end - vma->vm_start;
694         if (size != s->fragsize * s->nbfrags)
695                 return -EINVAL;
696         if (!s->buffers && audio_setup_buf(s))
697                 return -ENOMEM;
698         vma_addr = vma->vm_start;
699         for (i = 0; i < s->nbfrags; i++) {
700                 audio_buf_t *buf = &s->buffers[i];
701                 if (!buf->master)
702                         continue;
703                 ret =
704                     remap_pfn_range(vma, vma_addr, buf->dma_addr >> PAGE_SHIFT,
705                                     buf->master, vma->vm_page_prot);
706                 if (ret)
707                         return ret;
708                 vma_addr += buf->master;
709         }
710         s->mapped = 1;
711
712         FN_OUT(0);
713         return 0;
714 }
715
716 /*********************************************************************************
717  *
718  * audio_poll(): Exposed as poll function
719  *
720  *********************************************************************************/
721 static unsigned int
722 audio_poll(struct file *file, struct poll_table_struct *wait)
723 {
724         audio_state_t *state = file->private_data;
725         audio_stream_t *is = state->input_stream;
726         audio_stream_t *os = state->output_stream;
727         unsigned int mask = 0;
728
729         DPRINTK("audio_poll(): mode=%s%s\n",
730                 (file->f_mode & FMODE_READ) ? "r" : "",
731                 (file->f_mode & FMODE_WRITE) ? "w" : "");
732
733         if (file->f_mode & FMODE_READ) {
734                 /* Start audio input if not already active */
735                 if (!is->active) {
736                         if (!is->buffers && audio_setup_buf(is))
737                                 return -ENOMEM;
738                         audio_prime_rx(state);
739                 }
740                 poll_wait(file, &is->wq, wait);
741         }
742
743         if (file->f_mode & FMODE_WRITE) {
744                 if (!os->buffers && audio_setup_buf(os))
745                         return -ENOMEM;
746                 poll_wait(file, &os->wq, wait);
747         }
748
749         if (file->f_mode & FMODE_READ)
750                 if ((is->mapped && is->bytecount > 0) ||
751                     (!is->mapped && is->wfc.done > 0))
752                         mask |= POLLIN | POLLRDNORM;
753
754         if (file->f_mode & FMODE_WRITE)
755                 if ((os->mapped && os->bytecount > 0) ||
756                     (!os->mapped && os->wfc.done > 0))
757                         mask |= POLLOUT | POLLWRNORM;
758
759         DPRINTK("audio_poll() returned mask of %s%s\n",
760                 (mask & POLLIN) ? "r" : "", (mask & POLLOUT) ? "w" : "");
761
762         FN_OUT(mask);
763         return mask;
764 }
765
766 /*********************************************************************************
767  *
768  * audio_llseek(): Exposed as lseek() function.
769  *
770  *********************************************************************************/
771 static loff_t audio_llseek(struct file *file, loff_t offset, int origin)
772 {
773         FN_IN;
774         FN_OUT(0);
775         return -ESPIPE;
776 }
777
778 /*********************************************************************************
779  *
780  * audio_ioctl(): Handles generic ioctls. If there is a request for something this
781  * fn cannot handle, its then given to client specific ioctl routine, that will take
782  * up platform specific requests
783  *
784  *********************************************************************************/
785 static int
786 audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
787 {
788         audio_state_t *state = file->private_data;
789         audio_stream_t *os = state->output_stream;
790         audio_stream_t *is = state->input_stream;
791         long val;
792
793         DPRINTK(__FILE__ " audio_ioctl 0x%08x\n", cmd);
794
795         /* dispatch based on command */
796         switch (cmd) {
797         case OSS_GETVERSION:
798                 return put_user(SOUND_VERSION, (int __user *)arg);
799
800         case SNDCTL_DSP_GETBLKSIZE:
801                 if (file->f_mode & FMODE_WRITE)
802                         return put_user(os->fragsize, (int __user *)arg);
803                 else
804                         return put_user(is->fragsize, (int __user *)arg);
805
806         case SNDCTL_DSP_GETCAPS:
807                 val = DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP;
808                 if (is && os)
809                         val |= DSP_CAP_DUPLEX;
810                 FN_OUT(1);
811                 return put_user(val, (int __user *)arg);
812
813         case SNDCTL_DSP_SETFRAGMENT:
814                 if (get_user(val, (long __user *)arg)) {
815                         FN_OUT(2);
816                         return -EFAULT;
817                 }
818                 if (file->f_mode & FMODE_READ) {
819                         int ret = audio_set_fragments(is, val);
820                         if (ret < 0) {
821                                 FN_OUT(3);
822                                 return ret;
823                         }
824                         ret = put_user(ret, (int __user *)arg);
825                         if (ret) {
826                                 FN_OUT(4);
827                                 return ret;
828                         }
829                 }
830                 if (file->f_mode & FMODE_WRITE) {
831                         int ret = audio_set_fragments(os, val);
832                         if (ret < 0) {
833                                 FN_OUT(5);
834                                 return ret;
835                         }
836                         ret = put_user(ret, (int __user *)arg);
837                         if (ret) {
838                                 FN_OUT(6);
839                                 return ret;
840                         }
841                 }
842                 FN_OUT(7);
843                 return 0;
844
845         case SNDCTL_DSP_SYNC:
846                 FN_OUT(8);
847                 return audio_sync(file);
848
849         case SNDCTL_DSP_SETDUPLEX:
850                 FN_OUT(9);
851                 return 0;
852
853         case SNDCTL_DSP_POST:
854                 FN_OUT(10);
855                 return 0;
856
857         case SNDCTL_DSP_GETTRIGGER:
858                 val = 0;
859                 if (file->f_mode & FMODE_READ && is->active && !is->stopped)
860                         val |= PCM_ENABLE_INPUT;
861                 if (file->f_mode & FMODE_WRITE && os->active && !os->stopped)
862                         val |= PCM_ENABLE_OUTPUT;
863                 FN_OUT(11);
864                 return put_user(val, (int __user *)arg);
865
866         case SNDCTL_DSP_SETTRIGGER:
867                 if (get_user(val, (int __user *)arg)) {
868                         FN_OUT(12);
869                         return -EFAULT;
870                 }
871                 if (file->f_mode & FMODE_READ) {
872                         if (val & PCM_ENABLE_INPUT) {
873                                 unsigned long flags;
874                                 if (!is->active) {
875                                         if (!is->buffers && audio_setup_buf(is)) {
876                                                 FN_OUT(13);
877                                                 return -ENOMEM;
878                                         }
879                                         audio_prime_rx(state);
880                                 }
881                                 local_irq_save(flags);
882                                 is->stopped = 0;
883                                 local_irq_restore(flags);
884                                 audio_process_dma(is);
885
886                         } else {
887                                 audio_stop_dma(is);
888                         }
889                 }
890                 if (file->f_mode & FMODE_WRITE) {
891                         if (val & PCM_ENABLE_OUTPUT) {
892                                 unsigned long flags;
893                                 if (!os->buffers && audio_setup_buf(os)) {
894                                         FN_OUT(14);
895                                         return -ENOMEM;
896                                 }
897                                 local_irq_save(flags);
898                                 if (os->mapped && !os->pending_frags) {
899                                         os->pending_frags = os->nbfrags;
900                                         init_completion(&os->wfc);
901                                         os->wfc.done = 0;
902                                         os->active = 1;
903                                 }
904                                 os->stopped = 0;
905                                 local_irq_restore(flags);
906                                 audio_process_dma(os);
907
908                         } else {
909                                 audio_stop_dma(os);
910                         }
911                 }
912                 FN_OUT(15);
913                 return 0;
914
915         case SNDCTL_DSP_GETOPTR:
916         case SNDCTL_DSP_GETIPTR:
917                 {
918                         count_info inf = { 0, };
919                         audio_stream_t *s =
920                             (cmd == SNDCTL_DSP_GETOPTR) ? os : is;
921                         int bytecount, offset;
922                         unsigned long flags;
923
924                         if ((s == is && !(file->f_mode & FMODE_READ)) ||
925                             (s == os && !(file->f_mode & FMODE_WRITE))) {
926                                 FN_OUT(16);
927                                 return -EINVAL;
928                         }
929                         if (s->active) {
930                                 local_irq_save(flags);
931                                 offset = audio_get_dma_pos(s);
932                                 inf.ptr = s->dma_tail * s->fragsize + offset;
933                                 bytecount = s->bytecount + offset;
934                                 s->bytecount = -offset;
935                                 inf.blocks = s->fragcount;
936                                 s->fragcount = 0;
937                                 local_irq_restore(flags);
938                                 if (bytecount < 0)
939                                         bytecount = 0;
940                                 inf.bytes = bytecount;
941                         }
942                         FN_OUT(17);
943                         return copy_to_user((void __user *)arg, &inf, sizeof(inf));
944                 }
945
946         case SNDCTL_DSP_GETOSPACE:
947         case SNDCTL_DSP_GETISPACE:
948                 {
949                         audio_buf_info inf = { 0, };
950                         audio_stream_t *s =
951                             (cmd == SNDCTL_DSP_GETOSPACE) ? os : is;
952
953                         if ((s == is && !(file->f_mode & FMODE_READ)) ||
954                             (s == os && !(file->f_mode & FMODE_WRITE))) {
955                                 FN_OUT(18);
956                                 return -EINVAL;
957                         }
958                         if (!s->buffers && audio_setup_buf(s)) {
959                                 FN_OUT(19);
960                                 return -ENOMEM;
961                         }
962                         inf.bytes = s->wfc.done * s->fragsize;
963
964                         inf.fragments = inf.bytes / s->fragsize;
965                         inf.fragsize = s->fragsize;
966                         inf.fragstotal = s->nbfrags;
967                         FN_OUT(20);
968                         return copy_to_user((void __user *)arg, &inf, sizeof(inf));
969                 }
970
971         case SNDCTL_DSP_NONBLOCK:
972                 file->f_flags |= O_NONBLOCK;
973                 FN_OUT(21);
974                 return 0;
975
976         case SNDCTL_DSP_RESET:
977                 if (file->f_mode & FMODE_READ) {
978                         audio_reset(is);
979                         if (state->need_tx_for_rx) {
980                                 unsigned long flags;
981                                 local_irq_save(flags);
982                                 os->spin_idle = 0;
983                                 local_irq_restore(flags);
984                         }
985                 }
986                 if (file->f_mode & FMODE_WRITE) {
987                         audio_reset(os);
988                 }
989                 FN_OUT(22);
990                 return 0;
991
992         default:
993                 /*
994                  * Let the client of this module handle the
995                  * non generic ioctls
996                  */
997                 FN_OUT(23);
998                 return state->client_ioctl(inode, file, cmd, arg);
999         }
1000
1001         FN_OUT(0);
1002         return 0;
1003 }
1004
1005 /*********************************************************************************
1006  *
1007  * audio_open(): Exposed as open() function
1008  *
1009  *********************************************************************************/
1010 static int audio_open(struct inode *inode, struct file *file)
1011 {
1012         audio_state_t *state = (&audio_state);
1013         audio_stream_t *os = state->output_stream;
1014         audio_stream_t *is = state->input_stream;
1015         int err, need_tx_dma;
1016         static unsigned char tsc2101_init_flag = 0;
1017
1018         FN_IN;
1019
1020         /* Lock the module */
1021         if (!try_module_get(THIS_MODULE)) {
1022                 printk(KERN_CRIT "Failed to get module\n");
1023                 return -ESTALE;
1024         }
1025         /* Lock the codec module */
1026         if (!try_module_get(state->owner)) {
1027                 printk(KERN_CRIT "Failed to get codec module\n");
1028                 module_put(THIS_MODULE);
1029                 return -ESTALE;
1030         }
1031
1032         down(&state->sem);
1033
1034         /* access control */
1035         err = -ENODEV;
1036         if ((file->f_mode & FMODE_WRITE) && !os)
1037                 goto out;
1038         if ((file->f_mode & FMODE_READ) && !is)
1039                 goto out;
1040         err = -EBUSY;
1041         if ((file->f_mode & FMODE_WRITE) && state->wr_ref)
1042                 goto out;
1043         if ((file->f_mode & FMODE_READ) && state->rd_ref)
1044                 goto out;
1045         err = -EINVAL;
1046         if ((file->f_mode & FMODE_READ) && state->need_tx_for_rx && !os)
1047                 goto out;
1048
1049         /* request DMA channels */
1050         need_tx_dma = ((file->f_mode & FMODE_WRITE) ||
1051                        ((file->f_mode & FMODE_READ) && state->need_tx_for_rx));
1052         if (state->wr_ref || (state->rd_ref && state->need_tx_for_rx))
1053                 need_tx_dma = 0;
1054         if (need_tx_dma) {
1055                 DMA_REQUEST(err, os, audio_dma_callback);
1056                 if (err < 0)
1057                         goto out;
1058         }
1059         if (file->f_mode & FMODE_READ) {
1060                 DMA_REQUEST(err, is, audio_dma_callback);
1061                 if (err < 0) {
1062                         if (need_tx_dma)
1063                                 DMA_FREE(os);
1064                         goto out;
1065                 }
1066         }
1067
1068         /* now complete initialisation */
1069         if (!AUDIO_ACTIVE(state)) {
1070                 if (state->hw_init && !tsc2101_init_flag) {
1071                         state->hw_init(state->data);
1072                         tsc2101_init_flag = 0;
1073
1074                 }
1075
1076         }
1077
1078         if ((file->f_mode & FMODE_WRITE)) {
1079                 state->wr_ref = 1;
1080                 audio_reset(os);
1081                 os->fragsize = AUDIO_FRAGSIZE_DEFAULT;
1082                 os->nbfrags = AUDIO_NBFRAGS_DEFAULT;
1083                 os->mapped = 0;
1084                 init_waitqueue_head(&os->wq);
1085         }
1086
1087         if (file->f_mode & FMODE_READ) {
1088                 state->rd_ref = 1;
1089                 audio_reset(is);
1090                 is->fragsize = AUDIO_FRAGSIZE_DEFAULT;
1091                 is->nbfrags = AUDIO_NBFRAGS_DEFAULT;
1092                 is->mapped = 0;
1093                 init_waitqueue_head(&is->wq);
1094         }
1095
1096         file->private_data = state;
1097         err = 0;
1098
1099       out:
1100         up(&state->sem);
1101         if (err) {
1102                 module_put(state->owner);
1103                 module_put(THIS_MODULE);
1104         }
1105         FN_OUT(err);
1106         return err;
1107 }
1108
1109 /*********************************************************************************
1110  *
1111  * audio_release(): Exposed as release function()
1112  *
1113  *********************************************************************************/
1114 static int audio_release(struct inode *inode, struct file *file)
1115 {
1116         audio_state_t *state = file->private_data;
1117         audio_stream_t *os = state->output_stream;
1118         audio_stream_t *is = state->input_stream;
1119
1120         FN_IN;
1121
1122         down(&state->sem);
1123
1124         if (file->f_mode & FMODE_READ) {
1125                 audio_discard_buf(is);
1126                 DMA_FREE(is);
1127                 is->dma_spinref = 0;
1128                 if (state->need_tx_for_rx) {
1129                         os->spin_idle = 0;
1130                         if (!state->wr_ref) {
1131                                 DMA_FREE(os);
1132                                 os->dma_spinref = 0;
1133                         }
1134                 }
1135                 state->rd_ref = 0;
1136         }
1137
1138         if (file->f_mode & FMODE_WRITE) {
1139                 audio_sync(file);
1140                 audio_discard_buf(os);
1141                 if (!state->need_tx_for_rx || !state->rd_ref) {
1142                         DMA_FREE(os);
1143                         os->dma_spinref = 0;
1144                 }
1145                 state->wr_ref = 0;
1146         }
1147
1148         if (!AUDIO_ACTIVE(state)) {
1149                 if (state->hw_shutdown)
1150                         state->hw_shutdown(state->data);
1151         }
1152
1153         up(&state->sem);
1154
1155         module_put(state->owner);
1156         module_put(THIS_MODULE);
1157
1158         FN_OUT(0);
1159         return 0;
1160 }
1161
1162 EXPORT_SYMBOL(audio_register_codec);
1163 EXPORT_SYMBOL(audio_unregister_codec);
1164 EXPORT_SYMBOL(audio_get_fops);
1165
1166 MODULE_AUTHOR("Texas Instruments");
1167 MODULE_DESCRIPTION("Common audio handling for OMAP processors");
1168 MODULE_LICENSE("GPL");