]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/oss/omap-audio.c
Merge with ../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
49 #include <asm/uaccess.h>
50 #include <asm/io.h>
51 #include <asm/hardware.h>
52 #include <asm/semaphore.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 device *dev);
109
110 static int audio_remove(struct device *dev);
111
112 static void audio_shutdown(struct device *dev);
113
114 static int audio_suspend(struct device *dev, pm_message_t mesg, u32 level);
115
116 static int audio_resume(struct device *dev, u32 level);
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 device_driver omap_audio_driver = {
145         .name           = OMAP_AUDIO_NAME,
146         .bus            = &platform_bus_type,
147         .probe          = audio_probe,
148         .remove         = audio_remove,
149         .suspend        = audio_suspend,
150         .resume         = audio_resume,
151         .shutdown       = audio_shutdown,
152 };
153
154 /* Device Information */
155 static struct platform_device omap_audio_device = {
156         .name = OMAP_AUDIO_NAME,
157         .dev = {
158                 .driver_data = &audio_state,
159                 .release = audio_free,
160                 },
161         .id = 0,
162 };
163
164 /***************************** GLOBAL FUNCTIONs **********************************/
165
166 /* Power Management Functions for Linux Device Model  */
167 /* DEBUG PUPOSES ONLY! */
168 #ifdef CONFIG_PM
169 //#undef CONFIG_PM
170 #endif
171
172 #ifdef CONFIG_PM
173 /*********************************************************************************
174  *
175  * audio_ldm_suspend(): Suspend operation
176  *
177  *********************************************************************************/
178 static int audio_ldm_suspend(void *data)
179 {
180         audio_state_t *state = data;
181
182         FN_IN;
183
184         /* 
185          * Reject the suspend request if we are already actively transmitting data 
186          * Rationale: We dont want to be suspended while in the middle of a call!
187          */
188         if (AUDIO_ACTIVE(state) && state->hw_init) {
189                 printk(KERN_ERR "Audio device Active, Cannot Suspend");
190                 return -EPERM;
191 #if 0
192                 /* NOTE:
193                  * This Piece of code is commented out in hope
194                  * That one day we would need to suspend the device while 
195                  * audio operations are in progress and resume the operations
196                  * once the resume is done.
197                  * This is just a sample implementation of how it could be done.
198                  * Currently NOT SUPPORTED
199                  */
200                 audio_stream_t *is = state->input_stream;
201                 audio_stream_t *os = state->output_stream;
202                 int stopstate;
203                 if (is && is->buffers) {
204                         printk("IS Suspend\n");
205                         stopstate = is->stopped;
206                         audio_stop_dma(is);
207                         DMA_CLEAR(is);
208                         is->dma_spinref = 0;
209                         is->stopped = stopstate;
210                 }
211                 if (os && os->buffers) {
212                         printk("OS Suspend\n");
213                         stopstate = os->stopped;
214                         audio_stop_dma(os);
215                         DMA_CLEAR(os);
216                         os->dma_spinref = 0;
217                         os->stopped = stopstate;
218                 }
219 #endif
220         }
221
222         FN_OUT(0);
223         return 0;
224 }
225
226 /*********************************************************************************
227  *
228  * audio_ldm_resume(): Resume Operations
229  *
230  *********************************************************************************/
231 static int audio_ldm_resume(void *data)
232 {
233         audio_state_t *state = data;
234
235         FN_IN;
236         if (AUDIO_ACTIVE(state) && state->hw_init) {
237                 /* Should never occur - since we never suspend with active state */
238                 BUG();
239                 return -EPERM;
240 #if 0
241                 /* NOTE:
242                  * This Piece of code is commented out in hope
243                  * That one day we would need to suspend the device while 
244                  * audio operations are in progress and resume the operations
245                  * once the resume is done.
246                  * This is just a sample implementation of how it could be done.
247                  * Currently NOT SUPPORTED
248                  */
249                 audio_stream_t *is = state->input_stream;
250                 audio_stream_t *os = state->output_stream;
251                 if (os && os->buffers) {
252                         printk("OS Resume\n");
253                         audio_reset(os);
254                         audio_process_dma(os);
255                 }
256                 if (is && is->buffers) {
257                         printk("IS Resume\n");
258                         audio_reset(is);
259                         audio_process_dma(is);
260                 }
261 #endif
262         }
263         FN_OUT(0);
264         return 0;
265 }
266 #endif                          /* End of #ifdef CONFIG_PM */
267
268 /*********************************************************************************
269  *
270  * audio_free(): The Audio driver release function
271  * This is a dummy function required by the platform driver
272  *
273  *********************************************************************************/
274 static void audio_free(struct device *dev)
275 {
276         /* Nothing to Release! */
277 }
278
279 /*********************************************************************************
280  *
281  * audio_probe(): The Audio driver probe function
282  * WARNING!!!!  : It is expected that the codec would have registered with us by now
283  *
284  *********************************************************************************/
285 static int audio_probe(struct device *dev)
286 {
287         int ret;
288         FN_IN;
289         if (!audio_state.hw_probe) {
290                 printk(KERN_ERR "Probe Function Not Registered\n");
291                 return -ENODEV;
292         }
293         ret = audio_state.hw_probe();
294         FN_OUT(ret);
295         return ret;
296 }
297
298 /*********************************************************************************
299  *
300  * audio_remove() Function to handle removal operations
301  *
302  *********************************************************************************/
303 static int audio_remove(struct device *dev)
304 {
305         FN_IN;
306         if (audio_state.hw_remove) {
307                 audio_state.hw_remove();
308         }
309         FN_OUT(0);
310         return 0;
311 }
312
313 /*********************************************************************************
314  *
315  * audio_shutdown(): Function to handle shutdown operations
316  *
317  *********************************************************************************/
318 static void audio_shutdown(struct device *dev)
319 {
320         FN_IN;
321         if (audio_state.hw_cleanup) {
322                 audio_state.hw_cleanup();
323         }
324         FN_OUT(0);
325         return;
326 }
327
328 /*********************************************************************************
329  *
330  * audio_suspend(): Function to handle suspend operations 
331  *
332  *********************************************************************************/
333 static int audio_suspend(struct device *dev, pm_message_t mesg, u32 level)
334 {
335         int ret = 0;
336
337 #ifdef CONFIG_PM
338         void *data = dev->driver_data;
339         FN_IN;
340         if (level != SUSPEND_POWER_DOWN) {
341                 return 0;
342         }
343         if (audio_state.hw_suspend) {
344                 ret = audio_ldm_suspend(data);
345                 if (ret == 0)
346                         ret = audio_state.hw_suspend();
347         }
348         if (ret) {
349                 printk(KERN_INFO "Audio Suspend Failed \n");
350         } else {
351                 printk(KERN_INFO "Audio Suspend Success \n");
352         }
353 #endif                          /* CONFIG_PM */
354
355         FN_OUT(ret);
356         return ret;
357 }
358
359 /*********************************************************************************
360  *
361  * audio_resume(): Function to handle resume operations
362  *
363  *********************************************************************************/
364 static int audio_resume(struct device *dev, u32 level)
365 {
366         int ret = 0;
367
368 #ifdef  CONFIG_PM
369         void *data = dev->driver_data;
370         FN_IN;
371         if (level != RESUME_POWER_ON) {
372                 return 0;
373         }
374         if (audio_state.hw_resume) {
375                 ret = audio_ldm_resume(data);
376                 if (ret == 0)
377                         ret = audio_state.hw_resume();
378         }
379         if (ret) {
380                 printk(KERN_INFO " Audio Resume Failed \n");
381         } else {
382                 printk(KERN_INFO " Audio Resume Success \n");
383         }
384 #endif                          /* CONFIG_PM */
385
386         FN_OUT(ret);
387         return ret;
388 }
389
390 /*********************************************************************************
391  *
392  * audio_get_fops(): Return the fops required to get the function pointers of 
393  *                   OMAP Audio Driver
394  *
395  *********************************************************************************/
396 struct file_operations *audio_get_fops(void)
397 {
398         FN_IN;
399         FN_OUT(0);
400         return &omap_audio_fops;
401 }
402
403 /*********************************************************************************
404  *
405  * audio_register_codec(): Register a Codec fn points using this function
406  * WARNING!!!!!          : Codecs should ensure that they do so! no sanity checks
407  *                         during runtime is done due to obvious performance 
408  *                         penalties.
409  *
410  *********************************************************************************/
411 int audio_register_codec(audio_state_t * codec_state)
412 {
413         int ret;
414         FN_IN;
415
416         /* We dont handle multiple codecs now */
417         if (audio_state.hw_init) {
418                 printk(KERN_ERR " Codec Already registered\n");
419                 return -EPERM;
420         }
421
422         /* Grab the dma Callback */
423         audio_dma_callback = audio_get_dma_callback();
424         if (!audio_dma_callback) {
425                 printk(KERN_ERR "Unable to get call back function\n");
426                 return -EPERM;
427         }
428
429         /* Sanity checks */
430         if (!codec_state) {
431                 printk(KERN_ERR "NULL ARGUMENT!\n");
432                 return -EPERM;
433         }
434
435         if (!codec_state->hw_probe || !codec_state->hw_init
436             || !codec_state->hw_shutdown || !codec_state->client_ioctl) {
437                 printk(KERN_ERR
438                        "Required Fn Entry point Missing probe=%p init=%p,down=%p,ioctl=%p!\n",
439                        codec_state->hw_probe, codec_state->hw_init,
440                        codec_state->hw_shutdown, codec_state->client_ioctl);
441                 return -EPERM;
442         }
443
444         memcpy(&audio_state, codec_state, sizeof(audio_state_t));
445
446         ret = platform_device_register(&omap_audio_device);
447         if (ret != 0) {
448                 printk(KERN_ERR "Platform dev_register failed =%d\n", ret);
449                 ret = -ENODEV;
450                 goto register_out;
451         }
452
453         ret = driver_register(&omap_audio_driver);
454         if (ret != 0) {
455                 printk(KERN_ERR "Device Register failed =%d\n", ret);
456                 ret = -ENODEV;
457                 platform_device_unregister(&omap_audio_device);
458                 goto register_out;
459         }
460
461       register_out:
462
463         FN_OUT(ret);
464         return ret;
465 }
466
467 /*********************************************************************************
468  *
469  * audio_unregister_codec(): Un-Register a Codec using this function
470  *
471  *********************************************************************************/
472 int audio_unregister_codec(audio_state_t * codec_state)
473 {
474         FN_IN;
475
476         /* We dont handle multiple codecs now */
477         if (!audio_state.hw_init) {
478                 printk(KERN_ERR " No Codec registered\n");
479                 return -EPERM;
480         }
481         /* Security check */
482         if (audio_state.hw_init != codec_state->hw_init) {
483                 printk(KERN_ERR
484                        " Attempt to unregister codec which was not registered with us\n");
485                 return -EPERM;
486         }
487
488         driver_unregister(&omap_audio_driver);
489         platform_device_unregister(&omap_audio_device);
490
491         memset(&audio_state, 0, sizeof(audio_state_t));
492
493         FN_OUT(0);
494         return 0;
495 }
496
497 /***************************** MODULES SPECIFIC FUNCTION *************************/
498
499 /*********************************************************************************
500  *
501  * audio_write(): Exposed to write() call
502  *
503  *********************************************************************************/
504 static int
505 audio_write(struct file *file, const char __user *buffer,
506                 size_t count, loff_t * ppos)
507 {
508         const char __user *buffer0 = buffer;
509         audio_state_t *state = file->private_data;
510         audio_stream_t *s = state->output_stream;
511         int chunksize, ret = 0;
512
513         DPRINTK("audio_write: count=%d\n", count);
514         if (*ppos != file->f_pos) {
515                 printk("FPOS not ppos ppos=0x%x fpos =0x%x\n", (u32) * ppos,
516                        (u32) file->f_pos);
517                 return -ESPIPE;
518         }
519         if (s->mapped) {
520                 printk("s already mapped\n");
521                 return -ENXIO;
522         }
523         if (!s->buffers && audio_setup_buf(s)) {
524                 printk("NO MEMORY\n");
525                 return -ENOMEM;
526         }
527
528         while (count > 0) {
529                 audio_buf_t *b = &s->buffers[s->usr_head];
530
531                 /* Wait for a buffer to become free */
532                 if (file->f_flags & O_NONBLOCK) {
533                         ret = -EAGAIN;
534                         if (down_trylock(&s->sem))
535                                 break;
536                 } else {
537                         ret = -ERESTARTSYS;
538                         if (down_interruptible(&s->sem))
539                                 break;
540                 }
541
542                 /* Feed the current buffer */
543                 chunksize = s->fragsize - b->offset;
544                 if (chunksize > count)
545                         chunksize = count;
546                 DPRINTK("write %d to %d\n", chunksize, s->usr_head);
547                 if (copy_from_user(b->data + b->offset, buffer, chunksize)) {
548                         printk(KERN_ERR "Audio: CopyFrom User failed \n");
549                         up(&s->sem);
550                         return -EFAULT;
551                 }
552
553                 buffer += chunksize;
554                 count -= chunksize;
555                 b->offset += chunksize;
556
557                 if (b->offset < s->fragsize) {
558                         up(&s->sem);
559                         break;
560                 }
561
562                 /* Update pointers and send current fragment to DMA */
563                 b->offset = 0;
564                 if (++s->usr_head >= s->nbfrags)
565                         s->usr_head = 0;
566                 /* Add the num of frags pending */
567                 s->pending_frags++;
568                 s->active = 1;
569
570                 audio_process_dma(s);
571
572         }
573
574         if ((buffer - buffer0))
575                 ret = buffer - buffer0;
576         DPRINTK("audio_write: return=%d\n", ret);
577         return ret;
578 }
579
580 /*********************************************************************************
581  *
582  * audio_read(): Exposed as read() function
583  *
584  *********************************************************************************/
585 static int
586 audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
587 {
588         char __user *buffer0 = buffer;
589         audio_state_t *state = file->private_data;
590         audio_stream_t *s = state->input_stream;
591         int chunksize, ret = 0;
592         unsigned long flags;
593
594         DPRINTK("audio_read: count=%d\n", count);
595
596         if (*ppos != file->f_pos) {
597                 printk("AudioRead - FPOS not ppos ppos=0x%x fpos =0x%x\n",
598                        (u32) * ppos, (u32) file->f_pos);
599                 return -ESPIPE;
600         }
601         if (s->mapped) {
602                 printk("AudioRead - s already mapped\n");
603                 return -ENXIO;
604         }
605
606         if (!s->active) {
607                 if (!s->buffers && audio_setup_buf(s)) {
608                         printk("AudioRead - No Memory\n");
609                         return -ENOMEM;
610                 }
611                 audio_prime_rx(state);
612         }
613
614         while (count > 0) {
615                 audio_buf_t *b = &s->buffers[s->usr_head];
616
617                 /* Wait for a buffer to become full */
618                 if (file->f_flags & O_NONBLOCK) {
619                         ret = -EAGAIN;
620                         if (down_trylock(&s->sem))
621                                 break;
622                 } else {
623                         ret = -ERESTARTSYS;
624                         if (down_interruptible(&s->sem))
625                                 break;
626                 }
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                         up(&s->sem);
635                         return -EFAULT;
636                 }
637                 buffer += chunksize;
638                 count -= chunksize;
639                 b->offset += chunksize;
640                 if (b->offset < s->fragsize) {
641                         up(&s->sem);
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 && atomic_read(&is->sem.count) > 0))
752                         mask |= POLLIN | POLLRDNORM;
753
754         if (file->f_mode & FMODE_WRITE)
755                 if ((os->mapped && os->bytecount > 0) ||
756                     (!os->mapped && atomic_read(&os->sem.count) > 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                                         sema_init(&os->sem, 0);
901                                         os->active = 1;
902                                 }
903                                 os->stopped = 0;
904                                 local_irq_restore(flags);
905                                 audio_process_dma(os);
906
907                         } else {
908                                 audio_stop_dma(os);
909                         }
910                 }
911                 FN_OUT(15);
912                 return 0;
913
914         case SNDCTL_DSP_GETOPTR:
915         case SNDCTL_DSP_GETIPTR:
916                 {
917                         count_info inf = { 0, };
918                         audio_stream_t *s =
919                             (cmd == SNDCTL_DSP_GETOPTR) ? os : is;
920                         int bytecount, offset;
921                         unsigned long flags;
922
923                         if ((s == is && !(file->f_mode & FMODE_READ)) ||
924                             (s == os && !(file->f_mode & FMODE_WRITE))) {
925                                 FN_OUT(16);
926                                 return -EINVAL;
927                         }
928                         if (s->active) {
929                                 local_irq_save(flags);
930                                 offset = audio_get_dma_pos(s);
931                                 inf.ptr = s->dma_tail * s->fragsize + offset;
932                                 bytecount = s->bytecount + offset;
933                                 s->bytecount = -offset;
934                                 inf.blocks = s->fragcount;
935                                 s->fragcount = 0;
936                                 local_irq_restore(flags);
937                                 if (bytecount < 0)
938                                         bytecount = 0;
939                                 inf.bytes = bytecount;
940                         }
941                         FN_OUT(17);
942                         return copy_to_user((void __user *)arg, &inf, sizeof(inf));
943                 }
944
945         case SNDCTL_DSP_GETOSPACE:
946         case SNDCTL_DSP_GETISPACE:
947                 {
948                         audio_buf_info inf = { 0, };
949                         audio_stream_t *s =
950                             (cmd == SNDCTL_DSP_GETOSPACE) ? os : is;
951
952                         if ((s == is && !(file->f_mode & FMODE_READ)) ||
953                             (s == os && !(file->f_mode & FMODE_WRITE))) {
954                                 FN_OUT(18);
955                                 return -EINVAL;
956                         }
957                         if (!s->buffers && audio_setup_buf(s)) {
958                                 FN_OUT(19);
959                                 return -ENOMEM;
960                         }
961                         inf.bytes = atomic_read(&s->sem.count) * s->fragsize;
962
963                         inf.fragments = inf.bytes / s->fragsize;
964                         inf.fragsize = s->fragsize;
965                         inf.fragstotal = s->nbfrags;
966                         FN_OUT(20);
967                         return copy_to_user((void __user *)arg, &inf, sizeof(inf));
968                 }
969
970         case SNDCTL_DSP_NONBLOCK:
971                 file->f_flags |= O_NONBLOCK;
972                 FN_OUT(21);
973                 return 0;
974
975         case SNDCTL_DSP_RESET:
976                 if (file->f_mode & FMODE_READ) {
977                         audio_reset(is);
978                         if (state->need_tx_for_rx) {
979                                 unsigned long flags;
980                                 local_irq_save(flags);
981                                 os->spin_idle = 0;
982                                 local_irq_restore(flags);
983                         }
984                 }
985                 if (file->f_mode & FMODE_WRITE) {
986                         audio_reset(os);
987                 }
988                 FN_OUT(22);
989                 return 0;
990
991         default:
992                 /*
993                  * Let the client of this module handle the
994                  * non generic ioctls
995                  */
996                 FN_OUT(23);
997                 return state->client_ioctl(inode, file, cmd, arg);
998         }
999
1000         FN_OUT(0);
1001         return 0;
1002 }
1003
1004 /*********************************************************************************
1005  *
1006  * audio_open(): Exposed as open() function
1007  *
1008  *********************************************************************************/
1009 static int audio_open(struct inode *inode, struct file *file)
1010 {
1011         audio_state_t *state = (&audio_state);
1012         audio_stream_t *os = state->output_stream;
1013         audio_stream_t *is = state->input_stream;
1014         int err, need_tx_dma;
1015         static unsigned char tsc2101_init_flag = 0;
1016
1017         FN_IN;
1018
1019         /* Lock the module */
1020         if (!try_module_get(THIS_MODULE)) {
1021                 printk(KERN_CRIT "Failed to get module\n");
1022                 return -ESTALE;
1023         }
1024         /* Lock the codec module */
1025         if (!try_module_get(state->owner)) {
1026                 printk(KERN_CRIT "Failed to get codec module\n");
1027                 module_put(THIS_MODULE);
1028                 return -ESTALE;
1029         }
1030
1031         down(&state->sem);
1032
1033         /* access control */
1034         err = -ENODEV;
1035         if ((file->f_mode & FMODE_WRITE) && !os)
1036                 goto out;
1037         if ((file->f_mode & FMODE_READ) && !is)
1038                 goto out;
1039         err = -EBUSY;
1040         if ((file->f_mode & FMODE_WRITE) && state->wr_ref)
1041                 goto out;
1042         if ((file->f_mode & FMODE_READ) && state->rd_ref)
1043                 goto out;
1044         err = -EINVAL;
1045         if ((file->f_mode & FMODE_READ) && state->need_tx_for_rx && !os)
1046                 goto out;
1047
1048         /* request DMA channels */
1049         need_tx_dma = ((file->f_mode & FMODE_WRITE) ||
1050                        ((file->f_mode & FMODE_READ) && state->need_tx_for_rx));
1051         if (state->wr_ref || (state->rd_ref && state->need_tx_for_rx))
1052                 need_tx_dma = 0;
1053         if (need_tx_dma) {
1054                 DMA_REQUEST(err, os, audio_dma_callback);
1055                 if (err < 0)
1056                         goto out;
1057         }
1058         if (file->f_mode & FMODE_READ) {
1059                 DMA_REQUEST(err, is, audio_dma_callback);
1060                 if (err < 0) {
1061                         if (need_tx_dma)
1062                                 DMA_FREE(os);
1063                         goto out;
1064                 }
1065         }
1066
1067         /* now complete initialisation */
1068         if (!AUDIO_ACTIVE(state)) {
1069                 if (state->hw_init && !tsc2101_init_flag) {
1070                         state->hw_init(state->data);
1071                         tsc2101_init_flag = 0;
1072
1073                 }
1074
1075         }
1076
1077         if ((file->f_mode & FMODE_WRITE)) {
1078                 state->wr_ref = 1;
1079                 audio_reset(os);
1080                 os->fragsize = AUDIO_FRAGSIZE_DEFAULT;
1081                 os->nbfrags = AUDIO_NBFRAGS_DEFAULT;
1082                 os->mapped = 0;
1083                 init_waitqueue_head(&os->wq);
1084         }
1085
1086         if (file->f_mode & FMODE_READ) {
1087                 state->rd_ref = 1;
1088                 audio_reset(is);
1089                 is->fragsize = AUDIO_FRAGSIZE_DEFAULT;
1090                 is->nbfrags = AUDIO_NBFRAGS_DEFAULT;
1091                 is->mapped = 0;
1092                 init_waitqueue_head(&is->wq);
1093         }
1094
1095         file->private_data = state;
1096         err = 0;
1097
1098       out:
1099         up(&state->sem);
1100         if (err) {
1101                 module_put(state->owner);
1102                 module_put(THIS_MODULE);
1103         }
1104         FN_OUT(err);
1105         return err;
1106 }
1107
1108 /*********************************************************************************
1109  *
1110  * audio_release(): Exposed as release function()
1111  *
1112  *********************************************************************************/
1113 static int audio_release(struct inode *inode, struct file *file)
1114 {
1115         audio_state_t *state = file->private_data;
1116         audio_stream_t *os = state->output_stream;
1117         audio_stream_t *is = state->input_stream;
1118
1119         FN_IN;
1120
1121         down(&state->sem);
1122
1123         if (file->f_mode & FMODE_READ) {
1124                 audio_discard_buf(is);
1125                 DMA_FREE(is);
1126                 is->dma_spinref = 0;
1127                 if (state->need_tx_for_rx) {
1128                         os->spin_idle = 0;
1129                         if (!state->wr_ref) {
1130                                 DMA_FREE(os);
1131                                 os->dma_spinref = 0;
1132                         }
1133                 }
1134                 state->rd_ref = 0;
1135         }
1136
1137         if (file->f_mode & FMODE_WRITE) {
1138                 audio_sync(file);
1139                 audio_discard_buf(os);
1140                 if (!state->need_tx_for_rx || !state->rd_ref) {
1141                         DMA_FREE(os);
1142                         os->dma_spinref = 0;
1143                 }
1144                 state->wr_ref = 0;
1145         }
1146
1147         if (!AUDIO_ACTIVE(state)) {
1148                 if (state->hw_shutdown)
1149                         state->hw_shutdown(state->data);
1150         }
1151
1152         up(&state->sem);
1153
1154         module_put(state->owner);
1155         module_put(THIS_MODULE);
1156
1157         FN_OUT(0);
1158         return 0;
1159 }
1160
1161 EXPORT_SYMBOL(audio_register_codec);
1162 EXPORT_SYMBOL(audio_unregister_codec);
1163 EXPORT_SYMBOL(audio_get_fops);
1164
1165 MODULE_AUTHOR("Texas Instruments");
1166 MODULE_DESCRIPTION("Common audio handling for OMAP processors");
1167 MODULE_LICENSE("GPL");