]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/media/video/saa7134/saa7134-oss.c
Merge branch 'audit.b3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit...
[linux-2.6.git] / drivers / media / video / saa7134 / saa7134-oss.c
1 /*
2  *
3  * device driver for philips saa7134 based TV cards
4  * oss dsp interface
5  *
6  * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
7  *     2005 conversion to standalone module:
8  *         Ricardo Cerqueira <v4l@cerqueira.org>
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 #include <linux/init.h>
26 #include <linux/list.h>
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/kernel.h>
30 #include <linux/interrupt.h>
31 #include <linux/slab.h>
32 #include <linux/sound.h>
33 #include <linux/soundcard.h>
34
35 #include "saa7134-reg.h"
36 #include "saa7134.h"
37
38 /* ------------------------------------------------------------------ */
39
40 static unsigned int debug  = 0;
41 module_param(debug, int, 0644);
42 MODULE_PARM_DESC(debug,"enable debug messages [oss]");
43
44 static unsigned int rate  = 0;
45 module_param(rate, int, 0444);
46 MODULE_PARM_DESC(rate,"sample rate (valid are: 32000,48000)");
47
48 static unsigned int dsp_nr[]   = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
49 MODULE_PARM_DESC(dsp_nr, "device numbers for SAA7134 capture interface(s).");
50 module_param_array(dsp_nr,   int, NULL, 0444);
51
52 static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
53 MODULE_PARM_DESC(mixer_nr, "mixer numbers for SAA7134 capture interface(s).");
54 module_param_array(mixer_nr, int, NULL, 0444);
55
56 #define dprintk(fmt, arg...)    if (debug) \
57         printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
58
59
60 /* ------------------------------------------------------------------ */
61
62 static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
63 {
64         if (blksize < 0x100)
65                 blksize = 0x100;
66         if (blksize > 0x10000)
67                 blksize = 0x10000;
68
69         if (blocks < 2)
70                 blocks = 2;
71         if ((blksize * blocks) > 1024*1024)
72                 blocks = 1024*1024 / blksize;
73
74         dev->dmasound.blocks  = blocks;
75         dev->dmasound.blksize = blksize;
76         dev->dmasound.bufsize = blksize * blocks;
77
78         dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
79                 blocks,blksize,blksize * blocks / 1024);
80         return 0;
81 }
82
83 static int dsp_buffer_init(struct saa7134_dev *dev)
84 {
85         int err;
86
87         BUG_ON(!dev->dmasound.bufsize);
88         videobuf_dma_init(&dev->dmasound.dma);
89         err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
90                                        (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
91         if (0 != err)
92                 return err;
93         return 0;
94 }
95
96 static int dsp_buffer_free(struct saa7134_dev *dev)
97 {
98         BUG_ON(!dev->dmasound.blksize);
99         videobuf_dma_free(&dev->dmasound.dma);
100         dev->dmasound.blocks  = 0;
101         dev->dmasound.blksize = 0;
102         dev->dmasound.bufsize = 0;
103         return 0;
104 }
105
106 static void dsp_dma_start(struct saa7134_dev *dev)
107 {
108         dev->dmasound.dma_blk     = 0;
109         dev->dmasound.dma_running = 1;
110         saa7134_set_dmabits(dev);
111 }
112
113 static void dsp_dma_stop(struct saa7134_dev *dev)
114 {
115         dev->dmasound.dma_blk     = -1;
116         dev->dmasound.dma_running = 0;
117         saa7134_set_dmabits(dev);
118 }
119
120 static int dsp_rec_start(struct saa7134_dev *dev)
121 {
122         int err, bswap, sign;
123         u32 fmt, control;
124         unsigned long flags;
125
126         /* prepare buffer */
127         if (0 != (err = videobuf_pci_dma_map(dev->pci,&dev->dmasound.dma)))
128                 return err;
129         if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
130                 goto fail1;
131         if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
132                                               dev->dmasound.dma.sglist,
133                                               dev->dmasound.dma.sglen,
134                                               0)))
135                 goto fail2;
136
137         /* sample format */
138         switch (dev->dmasound.afmt) {
139         case AFMT_U8:
140         case AFMT_S8:     fmt = 0x00;  break;
141         case AFMT_U16_LE:
142         case AFMT_U16_BE:
143         case AFMT_S16_LE:
144         case AFMT_S16_BE: fmt = 0x01;  break;
145         default:
146                 err = -EINVAL;
147                 goto fail2;
148         }
149
150         switch (dev->dmasound.afmt) {
151         case AFMT_S8:
152         case AFMT_S16_LE:
153         case AFMT_S16_BE: sign = 1; break;
154         default:          sign = 0; break;
155         }
156
157         switch (dev->dmasound.afmt) {
158         case AFMT_U16_BE:
159         case AFMT_S16_BE: bswap = 1; break;
160         default:          bswap = 0; break;
161         }
162
163         switch (dev->pci->device) {
164         case PCI_DEVICE_ID_PHILIPS_SAA7134:
165                 if (1 == dev->dmasound.channels)
166                         fmt |= (1 << 3);
167                 if (2 == dev->dmasound.channels)
168                         fmt |= (3 << 3);
169                 if (sign)
170                         fmt |= 0x04;
171                 fmt |= (TV == dev->dmasound.input) ? 0xc0 : 0x80;
172
173                 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
174                 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >>  8);
175                 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
176                 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
177
178                 break;
179         case PCI_DEVICE_ID_PHILIPS_SAA7133:
180         case PCI_DEVICE_ID_PHILIPS_SAA7135:
181                 if (1 == dev->dmasound.channels)
182                         fmt |= (1 << 4);
183                 if (2 == dev->dmasound.channels)
184                         fmt |= (2 << 4);
185                 if (!sign)
186                         fmt |= 0x04;
187                 saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -4);
188                 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
189                 break;
190         }
191         dprintk("rec_start: afmt=%d ch=%d  =>  fmt=0x%x swap=%c\n",
192                 dev->dmasound.afmt, dev->dmasound.channels, fmt,
193                 bswap ? 'b' : '-');
194
195         /* dma: setup channel 6 (= AUDIO) */
196         control = SAA7134_RS_CONTROL_BURST_16 |
197                 SAA7134_RS_CONTROL_ME |
198                 (dev->dmasound.pt.dma >> 12);
199         if (bswap)
200                 control |= SAA7134_RS_CONTROL_BSWAP;
201         saa_writel(SAA7134_RS_BA1(6),0);
202         saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
203         saa_writel(SAA7134_RS_PITCH(6),0);
204         saa_writel(SAA7134_RS_CONTROL(6),control);
205
206         /* start dma */
207         dev->dmasound.recording_on = 1;
208         spin_lock_irqsave(&dev->slock,flags);
209         dsp_dma_start(dev);
210         spin_unlock_irqrestore(&dev->slock,flags);
211         return 0;
212
213  fail2:
214         saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
215  fail1:
216         videobuf_pci_dma_unmap(dev->pci,&dev->dmasound.dma);
217         return err;
218 }
219
220 static int dsp_rec_stop(struct saa7134_dev *dev)
221 {
222         unsigned long flags;
223
224         dprintk("rec_stop dma_blk=%d\n",dev->dmasound.dma_blk);
225
226         /* stop dma */
227         dev->dmasound.recording_on = 0;
228         spin_lock_irqsave(&dev->slock,flags);
229         dsp_dma_stop(dev);
230         spin_unlock_irqrestore(&dev->slock,flags);
231
232         /* unlock buffer */
233         saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
234         videobuf_pci_dma_unmap(dev->pci,&dev->dmasound.dma);
235         return 0;
236 }
237
238 /* ------------------------------------------------------------------ */
239
240 static int dsp_open(struct inode *inode, struct file *file)
241 {
242         int minor = iminor(inode);
243         struct saa7134_dev *h,*dev = NULL;
244         struct list_head *list;
245         int err;
246
247         list_for_each(list,&saa7134_devlist) {
248                 h = list_entry(list, struct saa7134_dev, devlist);
249                 if (h->dmasound.minor_dsp == minor)
250                         dev = h;
251         }
252         if (NULL == dev)
253                 return -ENODEV;
254
255         mutex_lock(&dev->dmasound.lock);
256         err = -EBUSY;
257         if (dev->dmasound.users_dsp)
258                 goto fail1;
259         dev->dmasound.users_dsp++;
260         file->private_data = dev;
261
262         dev->dmasound.afmt        = AFMT_U8;
263         dev->dmasound.channels    = 1;
264         dev->dmasound.read_count  = 0;
265         dev->dmasound.read_offset = 0;
266         dsp_buffer_conf(dev,PAGE_SIZE,64);
267         err = dsp_buffer_init(dev);
268         if (0 != err)
269                 goto fail2;
270
271         mutex_unlock(&dev->dmasound.lock);
272         return 0;
273
274  fail2:
275         dev->dmasound.users_dsp--;
276  fail1:
277         mutex_unlock(&dev->dmasound.lock);
278         return err;
279 }
280
281 static int dsp_release(struct inode *inode, struct file *file)
282 {
283         struct saa7134_dev *dev = file->private_data;
284
285         mutex_lock(&dev->dmasound.lock);
286         if (dev->dmasound.recording_on)
287                 dsp_rec_stop(dev);
288         dsp_buffer_free(dev);
289         dev->dmasound.users_dsp--;
290         file->private_data = NULL;
291         mutex_unlock(&dev->dmasound.lock);
292         return 0;
293 }
294
295 static ssize_t dsp_read(struct file *file, char __user *buffer,
296                         size_t count, loff_t *ppos)
297 {
298         struct saa7134_dev *dev = file->private_data;
299         DECLARE_WAITQUEUE(wait, current);
300         unsigned int bytes;
301         unsigned long flags;
302         int err,ret = 0;
303
304         add_wait_queue(&dev->dmasound.wq, &wait);
305         mutex_lock(&dev->dmasound.lock);
306         while (count > 0) {
307                 /* wait for data if needed */
308                 if (0 == dev->dmasound.read_count) {
309                         if (!dev->dmasound.recording_on) {
310                                 err = dsp_rec_start(dev);
311                                 if (err < 0) {
312                                         if (0 == ret)
313                                                 ret = err;
314                                         break;
315                                 }
316                         }
317                         if (dev->dmasound.recording_on &&
318                             !dev->dmasound.dma_running) {
319                                 /* recover from overruns */
320                                 spin_lock_irqsave(&dev->slock,flags);
321                                 dsp_dma_start(dev);
322                                 spin_unlock_irqrestore(&dev->slock,flags);
323                         }
324                         if (file->f_flags & O_NONBLOCK) {
325                                 if (0 == ret)
326                                         ret = -EAGAIN;
327                                 break;
328                         }
329                         mutex_unlock(&dev->dmasound.lock);
330                         set_current_state(TASK_INTERRUPTIBLE);
331                         if (0 == dev->dmasound.read_count)
332                                 schedule();
333                         set_current_state(TASK_RUNNING);
334                         mutex_lock(&dev->dmasound.lock);
335                         if (signal_pending(current)) {
336                                 if (0 == ret)
337                                         ret = -EINTR;
338                                 break;
339                         }
340                 }
341
342                 /* copy data to userspace */
343                 bytes = count;
344                 if (bytes > dev->dmasound.read_count)
345                         bytes = dev->dmasound.read_count;
346                 if (bytes > dev->dmasound.bufsize - dev->dmasound.read_offset)
347                         bytes = dev->dmasound.bufsize - dev->dmasound.read_offset;
348                 if (copy_to_user(buffer + ret,
349                                  dev->dmasound.dma.vmalloc + dev->dmasound.read_offset,
350                                  bytes)) {
351                         if (0 == ret)
352                                 ret = -EFAULT;
353                         break;
354                 }
355
356                 ret   += bytes;
357                 count -= bytes;
358                 dev->dmasound.read_count  -= bytes;
359                 dev->dmasound.read_offset += bytes;
360                 if (dev->dmasound.read_offset == dev->dmasound.bufsize)
361                         dev->dmasound.read_offset = 0;
362         }
363         mutex_unlock(&dev->dmasound.lock);
364         remove_wait_queue(&dev->dmasound.wq, &wait);
365         return ret;
366 }
367
368 static ssize_t dsp_write(struct file *file, const char __user *buffer,
369                          size_t count, loff_t *ppos)
370 {
371         return -EINVAL;
372 }
373
374 static const char *osspcm_ioctls[] = {
375         "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
376         "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS",
377         "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER",
378         "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
379         "SETDUPLEX", "GETODELAY"
380 };
381 #define OSSPCM_IOCTLS ARRAY_SIZE(osspcm_ioctls)
382
383 static void saa7134_oss_print_ioctl(char *name, unsigned int cmd)
384 {
385         char *dir;
386
387         switch (_IOC_DIR(cmd)) {
388         case _IOC_NONE:              dir = "--"; break;
389         case _IOC_READ:              dir = "r-"; break;
390         case _IOC_WRITE:             dir = "-w"; break;
391         case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
392         default:                     dir = "??"; break;
393         }
394         switch (_IOC_TYPE(cmd)) {
395         case 'P':
396                 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
397                        name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
398                        osspcm_ioctls[_IOC_NR(cmd)] : "???");
399                 break;
400         case 'M':
401                 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
402                        name, cmd, dir, _IOC_NR(cmd));
403                 break;
404         default:
405                 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
406                        name, cmd, dir, _IOC_NR(cmd));
407         }
408 }
409
410 static int dsp_ioctl(struct inode *inode, struct file *file,
411                      unsigned int cmd, unsigned long arg)
412 {
413         struct saa7134_dev *dev = file->private_data;
414         void __user *argp = (void __user *) arg;
415         int __user *p = argp;
416         int val = 0;
417
418         if (debug > 1)
419                 saa7134_oss_print_ioctl(dev->name,cmd);
420         switch (cmd) {
421         case OSS_GETVERSION:
422                 return put_user(SOUND_VERSION, p);
423         case SNDCTL_DSP_GETCAPS:
424                 return 0;
425
426         case SNDCTL_DSP_SPEED:
427                 if (get_user(val, p))
428                         return -EFAULT;
429                 /* fall through */
430         case SOUND_PCM_READ_RATE:
431                 return put_user(dev->dmasound.rate, p);
432
433         case SNDCTL_DSP_STEREO:
434                 if (get_user(val, p))
435                         return -EFAULT;
436                 mutex_lock(&dev->dmasound.lock);
437                 dev->dmasound.channels = val ? 2 : 1;
438                 if (dev->dmasound.recording_on) {
439                         dsp_rec_stop(dev);
440                         dsp_rec_start(dev);
441                 }
442                 mutex_unlock(&dev->dmasound.lock);
443                 return put_user(dev->dmasound.channels-1, p);
444
445         case SNDCTL_DSP_CHANNELS:
446                 if (get_user(val, p))
447                         return -EFAULT;
448                 if (val != 1 && val != 2)
449                         return -EINVAL;
450                 mutex_lock(&dev->dmasound.lock);
451                 dev->dmasound.channels = val;
452                 if (dev->dmasound.recording_on) {
453                         dsp_rec_stop(dev);
454                         dsp_rec_start(dev);
455                 }
456                 mutex_unlock(&dev->dmasound.lock);
457                 /* fall through */
458         case SOUND_PCM_READ_CHANNELS:
459                 return put_user(dev->dmasound.channels, p);
460
461         case SNDCTL_DSP_GETFMTS: /* Returns a mask */
462                 return put_user(AFMT_U8     | AFMT_S8     |
463                                 AFMT_U16_LE | AFMT_U16_BE |
464                                 AFMT_S16_LE | AFMT_S16_BE, p);
465
466         case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
467                 if (get_user(val, p))
468                         return -EFAULT;
469                 switch (val) {
470                 case AFMT_QUERY:
471                         /* nothing to do */
472                         break;
473                 case AFMT_U8:
474                 case AFMT_S8:
475                 case AFMT_U16_LE:
476                 case AFMT_U16_BE:
477                 case AFMT_S16_LE:
478                 case AFMT_S16_BE:
479                         mutex_lock(&dev->dmasound.lock);
480                         dev->dmasound.afmt = val;
481                         if (dev->dmasound.recording_on) {
482                                 dsp_rec_stop(dev);
483                                 dsp_rec_start(dev);
484                         }
485                         mutex_unlock(&dev->dmasound.lock);
486                         return put_user(dev->dmasound.afmt, p);
487                 default:
488                         return -EINVAL;
489                 }
490
491         case SOUND_PCM_READ_BITS:
492                 switch (dev->dmasound.afmt) {
493                 case AFMT_U8:
494                 case AFMT_S8:
495                         return put_user(8, p);
496                 case AFMT_U16_LE:
497                 case AFMT_U16_BE:
498                 case AFMT_S16_LE:
499                 case AFMT_S16_BE:
500                         return put_user(16, p);
501                 default:
502                         return -EINVAL;
503                 }
504
505         case SNDCTL_DSP_NONBLOCK:
506                 file->f_flags |= O_NONBLOCK;
507                 return 0;
508
509         case SNDCTL_DSP_RESET:
510                 mutex_lock(&dev->dmasound.lock);
511                 if (dev->dmasound.recording_on)
512                         dsp_rec_stop(dev);
513                 mutex_unlock(&dev->dmasound.lock);
514                 return 0;
515         case SNDCTL_DSP_GETBLKSIZE:
516                 return put_user(dev->dmasound.blksize, p);
517
518         case SNDCTL_DSP_SETFRAGMENT:
519                 if (get_user(val, p))
520                         return -EFAULT;
521                 if (dev->dmasound.recording_on)
522                         return -EBUSY;
523                 dsp_buffer_free(dev);
524                 /* used to be arg >> 16 instead of val >> 16; fixed */
525                 dsp_buffer_conf(dev,1 << (val & 0xffff), (val >> 16) & 0xffff);
526                 dsp_buffer_init(dev);
527                 return 0;
528
529         case SNDCTL_DSP_SYNC:
530                 /* NOP */
531                 return 0;
532
533         case SNDCTL_DSP_GETISPACE:
534         {
535                 audio_buf_info info;
536                 info.fragsize   = dev->dmasound.blksize;
537                 info.fragstotal = dev->dmasound.blocks;
538                 info.bytes      = dev->dmasound.read_count;
539                 info.fragments  = info.bytes / info.fragsize;
540                 if (copy_to_user(argp, &info, sizeof(info)))
541                         return -EFAULT;
542                 return 0;
543         }
544         default:
545                 return -EINVAL;
546         }
547 }
548
549 static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
550 {
551         struct saa7134_dev *dev = file->private_data;
552         unsigned int mask = 0;
553
554         poll_wait(file, &dev->dmasound.wq, wait);
555
556         if (0 == dev->dmasound.read_count) {
557                 mutex_lock(&dev->dmasound.lock);
558                 if (!dev->dmasound.recording_on)
559                         dsp_rec_start(dev);
560                 mutex_unlock(&dev->dmasound.lock);
561         } else
562                 mask |= (POLLIN | POLLRDNORM);
563         return mask;
564 }
565
566 struct file_operations saa7134_dsp_fops = {
567         .owner   = THIS_MODULE,
568         .open    = dsp_open,
569         .release = dsp_release,
570         .read    = dsp_read,
571         .write   = dsp_write,
572         .ioctl   = dsp_ioctl,
573         .poll    = dsp_poll,
574         .llseek  = no_llseek,
575 };
576
577 /* ------------------------------------------------------------------ */
578
579 static int
580 mixer_recsrc_7134(struct saa7134_dev *dev)
581 {
582         int analog_io,rate;
583
584         switch (dev->dmasound.input) {
585         case TV:
586                 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
587                 saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, 0x00);
588                 break;
589         case LINE1:
590         case LINE2:
591         case LINE2_LEFT:
592                 analog_io = (LINE1 == dev->dmasound.input) ? 0x00 : 0x08;
593                 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
594                 saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x08, analog_io);
595                 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
596                 saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, rate);
597                 break;
598         }
599         return 0;
600 }
601
602 static int
603 mixer_recsrc_7133(struct saa7134_dev *dev)
604 {
605         u32 anabar, xbarin;
606
607         xbarin = 0x03; // adc
608     anabar = 0;
609         switch (dev->dmasound.input) {
610         case TV:
611                 xbarin = 0; // Demodulator
612         anabar = 2; // DACs
613                 break;
614         case LINE1:
615                 anabar = 0;  // aux1, aux1
616                 break;
617         case LINE2:
618         case LINE2_LEFT:
619                 anabar = 9;  // aux2, aux2
620                 break;
621         }
622     /* output xbar always main channel */
623         saa_dsp_writel(dev, 0x46c >> 2, 0xbbbb10);
624         saa_dsp_writel(dev, 0x464 >> 2, xbarin);
625         saa_writel(0x594 >> 2, anabar);
626
627         return 0;
628 }
629
630 static int
631 mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
632 {
633         static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
634
635         dev->dmasound.count++;
636         dev->dmasound.input = src;
637         dprintk("mixer input = %s\n",iname[dev->dmasound.input]);
638
639         switch (dev->pci->device) {
640         case PCI_DEVICE_ID_PHILIPS_SAA7134:
641                 mixer_recsrc_7134(dev);
642                 break;
643         case PCI_DEVICE_ID_PHILIPS_SAA7133:
644         case PCI_DEVICE_ID_PHILIPS_SAA7135:
645                 mixer_recsrc_7133(dev);
646                 break;
647         }
648         return 0;
649 }
650
651 static int
652 mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
653 {
654         switch (dev->pci->device) {
655         case PCI_DEVICE_ID_PHILIPS_SAA7134:
656                 switch (src) {
657                 case TV:
658                         /* nothing */
659                         break;
660                 case LINE1:
661                         saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x10,
662                                    (100 == level) ? 0x00 : 0x10);
663                         break;
664                 case LINE2:
665                 case LINE2_LEFT:
666                         saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x20,
667                                    (100 == level) ? 0x00 : 0x20);
668                         break;
669                 }
670                 break;
671         case PCI_DEVICE_ID_PHILIPS_SAA7133:
672         case PCI_DEVICE_ID_PHILIPS_SAA7135:
673                 /* nothing */
674                 break;
675         }
676         return 0;
677 }
678
679 /* ------------------------------------------------------------------ */
680
681 static int mixer_open(struct inode *inode, struct file *file)
682 {
683         int minor = iminor(inode);
684         struct saa7134_dev *h,*dev = NULL;
685         struct list_head *list;
686
687         list_for_each(list,&saa7134_devlist) {
688                 h = list_entry(list, struct saa7134_dev, devlist);
689                 if (h->dmasound.minor_mixer == minor)
690                         dev = h;
691         }
692         if (NULL == dev)
693                 return -ENODEV;
694
695         file->private_data = dev;
696         return 0;
697 }
698
699 static int mixer_release(struct inode *inode, struct file *file)
700 {
701         file->private_data = NULL;
702         return 0;
703 }
704
705 static int mixer_ioctl(struct inode *inode, struct file *file,
706                      unsigned int cmd, unsigned long arg)
707 {
708         struct saa7134_dev *dev = file->private_data;
709         enum saa7134_audio_in input;
710         int val,ret;
711         void __user *argp = (void __user *) arg;
712         int __user *p = argp;
713
714         if (debug > 1)
715                 saa7134_oss_print_ioctl(dev->name,cmd);
716         switch (cmd) {
717         case OSS_GETVERSION:
718                 return put_user(SOUND_VERSION, p);
719         case SOUND_MIXER_INFO:
720         {
721                 mixer_info info;
722                 memset(&info,0,sizeof(info));
723                 strlcpy(info.id,   "TV audio", sizeof(info.id));
724                 strlcpy(info.name, dev->name,  sizeof(info.name));
725                 info.modify_counter = dev->dmasound.count;
726                 if (copy_to_user(argp, &info, sizeof(info)))
727                         return -EFAULT;
728                 return 0;
729         }
730         case SOUND_OLD_MIXER_INFO:
731         {
732                 _old_mixer_info info;
733                 memset(&info,0,sizeof(info));
734                 strlcpy(info.id,   "TV audio", sizeof(info.id));
735                 strlcpy(info.name, dev->name,  sizeof(info.name));
736                 if (copy_to_user(argp, &info, sizeof(info)))
737                         return -EFAULT;
738                 return 0;
739         }
740         case MIXER_READ(SOUND_MIXER_CAPS):
741                 return put_user(SOUND_CAP_EXCL_INPUT, p);
742         case MIXER_READ(SOUND_MIXER_STEREODEVS):
743                 return put_user(0, p);
744         case MIXER_READ(SOUND_MIXER_RECMASK):
745         case MIXER_READ(SOUND_MIXER_DEVMASK):
746                 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
747                 if (32000 == dev->dmasound.rate)
748                         val |= SOUND_MASK_VIDEO;
749                 return put_user(val, p);
750
751         case MIXER_WRITE(SOUND_MIXER_RECSRC):
752                 if (get_user(val, p))
753                         return -EFAULT;
754                 input = dev->dmasound.input;
755                 if (32000 == dev->dmasound.rate  &&
756                     val & SOUND_MASK_VIDEO  &&  dev->dmasound.input != TV)
757                         input = TV;
758                 if (val & SOUND_MASK_LINE1  &&  dev->dmasound.input != LINE1)
759                         input = LINE1;
760                 if (val & SOUND_MASK_LINE2  &&  dev->dmasound.input != LINE2)
761                         input = LINE2;
762                 if (input != dev->dmasound.input)
763                         mixer_recsrc(dev,input);
764                 /* fall throuth */
765         case MIXER_READ(SOUND_MIXER_RECSRC):
766                 switch (dev->dmasound.input) {
767                 case TV:    ret = SOUND_MASK_VIDEO; break;
768                 case LINE1: ret = SOUND_MASK_LINE1; break;
769                 case LINE2: ret = SOUND_MASK_LINE2; break;
770                 default:    ret = 0;
771                 }
772                 return put_user(ret, p);
773
774         case MIXER_WRITE(SOUND_MIXER_VIDEO):
775         case MIXER_READ(SOUND_MIXER_VIDEO):
776                 if (32000 != dev->dmasound.rate)
777                         return -EINVAL;
778                 return put_user(100 | 100 << 8, p);
779
780         case MIXER_WRITE(SOUND_MIXER_LINE1):
781                 if (get_user(val, p))
782                         return -EFAULT;
783                 val &= 0xff;
784                 val = (val <= 50) ? 50 : 100;
785                 dev->dmasound.line1 = val;
786                 mixer_level(dev,LINE1,dev->dmasound.line1);
787                 /* fall throuth */
788         case MIXER_READ(SOUND_MIXER_LINE1):
789                 return put_user(dev->dmasound.line1 | dev->dmasound.line1 << 8, p);
790
791         case MIXER_WRITE(SOUND_MIXER_LINE2):
792                 if (get_user(val, p))
793                         return -EFAULT;
794                 val &= 0xff;
795                 val = (val <= 50) ? 50 : 100;
796                 dev->dmasound.line2 = val;
797                 mixer_level(dev,LINE2,dev->dmasound.line2);
798                 /* fall throuth */
799         case MIXER_READ(SOUND_MIXER_LINE2):
800                 return put_user(dev->dmasound.line2 | dev->dmasound.line2 << 8, p);
801
802         default:
803                 return -EINVAL;
804         }
805 }
806
807 struct file_operations saa7134_mixer_fops = {
808         .owner   = THIS_MODULE,
809         .open    = mixer_open,
810         .release = mixer_release,
811         .ioctl   = mixer_ioctl,
812         .llseek  = no_llseek,
813 };
814
815 /* ------------------------------------------------------------------ */
816
817 static irqreturn_t saa7134_oss_irq(int irq, void *dev_id, struct pt_regs *regs)
818 {
819         struct saa7134_dmasound *dmasound = dev_id;
820         struct saa7134_dev *dev = dmasound->priv_data;
821         unsigned long report, status;
822         int loop, handled = 0;
823
824         for (loop = 0; loop < 10; loop++) {
825                 report = saa_readl(SAA7134_IRQ_REPORT);
826                 status = saa_readl(SAA7134_IRQ_STATUS);
827
828                 if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
829                         handled = 1;
830                         saa_writel(SAA7134_IRQ_REPORT,report);
831                         saa7134_irq_oss_done(dev, status);
832                 } else {
833                         goto out;
834                 }
835         }
836
837         if (loop == 10) {
838                 dprintk("error! looping IRQ!");
839         }
840 out:
841         return IRQ_RETVAL(handled);
842 }
843
844 int saa7134_oss_init1(struct saa7134_dev *dev)
845 {
846
847         if ((request_irq(dev->pci->irq, saa7134_oss_irq,
848                          SA_SHIRQ | SA_INTERRUPT, dev->name,
849                         (void*) &dev->dmasound)) < 0)
850                 return -1;
851
852         /* general */
853         mutex_init(&dev->dmasound.lock);
854         init_waitqueue_head(&dev->dmasound.wq);
855
856         switch (dev->pci->device) {
857         case PCI_DEVICE_ID_PHILIPS_SAA7133:
858         case PCI_DEVICE_ID_PHILIPS_SAA7135:
859                 saa_writel(0x588 >> 2, 0x00000fff);
860                 saa_writel(0x58c >> 2, 0x00543210);
861                 saa_dsp_writel(dev, 0x46c >> 2, 0xbbbbbb);
862                 break;
863         }
864
865         /* dsp */
866         dev->dmasound.rate = 32000;
867         if (rate)
868                 dev->dmasound.rate = rate;
869         dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000;
870
871         /* mixer */
872         dev->dmasound.line1 = 50;
873         dev->dmasound.line2 = 50;
874         mixer_level(dev,LINE1,dev->dmasound.line1);
875         mixer_level(dev,LINE2,dev->dmasound.line2);
876         mixer_recsrc(dev, (dev->dmasound.rate == 32000) ? TV : LINE2);
877
878         return 0;
879 }
880
881 int saa7134_oss_fini(struct saa7134_dev *dev)
882 {
883         /* nothing */
884         return 0;
885 }
886
887 void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
888 {
889         int next_blk, reg = 0;
890
891         spin_lock(&dev->slock);
892         if (UNSET == dev->dmasound.dma_blk) {
893                 dprintk("irq: recording stopped\n");
894                 goto done;
895         }
896         if (0 != (status & 0x0f000000))
897                 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
898         if (0 == (status & 0x10000000)) {
899                 /* odd */
900                 if (0 == (dev->dmasound.dma_blk & 0x01))
901                         reg = SAA7134_RS_BA1(6);
902         } else {
903                 /* even */
904                 if (1 == (dev->dmasound.dma_blk & 0x01))
905                         reg = SAA7134_RS_BA2(6);
906         }
907         if (0 == reg) {
908                 dprintk("irq: field oops [%s]\n",
909                         (status & 0x10000000) ? "even" : "odd");
910                 goto done;
911         }
912         if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
913                 dprintk("irq: overrun [full=%d/%d]\n",dev->dmasound.read_count,
914                         dev->dmasound.bufsize);
915                 dsp_dma_stop(dev);
916                 goto done;
917         }
918
919         /* next block addr */
920         next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
921         saa_writel(reg,next_blk * dev->dmasound.blksize);
922         if (debug > 2)
923                 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
924                         (status & 0x10000000) ? "even" : "odd ", next_blk,
925                         next_blk * dev->dmasound.blksize);
926
927         /* update status & wake waiting readers */
928         dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
929         dev->dmasound.read_count += dev->dmasound.blksize;
930         wake_up(&dev->dmasound.wq);
931
932  done:
933         spin_unlock(&dev->slock);
934 }
935
936 static int saa7134_dsp_create(struct saa7134_dev *dev)
937 {
938         int err;
939
940         err = dev->dmasound.minor_dsp =
941                 register_sound_dsp(&saa7134_dsp_fops,
942                                    dsp_nr[dev->nr]);
943         if (err < 0) {
944                 goto fail;
945         }
946         printk(KERN_INFO "%s: registered device dsp%d\n",
947                dev->name,dev->dmasound.minor_dsp >> 4);
948
949         err = dev->dmasound.minor_mixer =
950                 register_sound_mixer(&saa7134_mixer_fops,
951                                      mixer_nr[dev->nr]);
952         if (err < 0)
953                 goto fail;
954         printk(KERN_INFO "%s: registered device mixer%d\n",
955                dev->name,dev->dmasound.minor_mixer >> 4);
956
957         return 0;
958
959 fail:
960         unregister_sound_dsp(dev->dmasound.minor_dsp);
961         return 0;
962
963
964 }
965
966 static int oss_device_init(struct saa7134_dev *dev)
967 {
968         dev->dmasound.priv_data = dev;
969         saa7134_oss_init1(dev);
970         saa7134_dsp_create(dev);
971         return 1;
972 }
973
974 static int oss_device_exit(struct saa7134_dev *dev)
975 {
976
977         unregister_sound_mixer(dev->dmasound.minor_mixer);
978         unregister_sound_dsp(dev->dmasound.minor_dsp);
979
980         saa7134_oss_fini(dev);
981
982         if (dev->pci->irq > 0) {
983                 synchronize_irq(dev->pci->irq);
984                 free_irq(dev->pci->irq,&dev->dmasound);
985         }
986
987         dev->dmasound.priv_data = NULL;
988         return 1;
989 }
990
991 static int saa7134_oss_init(void)
992 {
993         struct saa7134_dev *dev = NULL;
994         struct list_head *list;
995
996         if (!dmasound_init && !dmasound_exit) {
997                 dmasound_init = oss_device_init;
998                 dmasound_exit = oss_device_exit;
999         } else {
1000                 printk(KERN_WARNING "saa7134 OSS: can't load, DMA sound handler already assigned (probably to ALSA)\n");
1001                 return -EBUSY;
1002         }
1003
1004         printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n");
1005
1006
1007         list_for_each(list,&saa7134_devlist) {
1008                 dev = list_entry(list, struct saa7134_dev, devlist);
1009                 if (dev->dmasound.priv_data == NULL) {
1010                         oss_device_init(dev);
1011                 } else {
1012                         printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name);
1013                         return -EBUSY;
1014                 }
1015         }
1016
1017         if (dev == NULL)
1018                 printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n");
1019
1020         return 0;
1021
1022 }
1023
1024 static void saa7134_oss_exit(void)
1025 {
1026         struct saa7134_dev *dev = NULL;
1027         struct list_head *list;
1028
1029         list_for_each(list,&saa7134_devlist) {
1030                 dev = list_entry(list, struct saa7134_dev, devlist);
1031
1032                 /* Device isn't registered by OSS, probably ALSA's */
1033                 if (!dev->dmasound.minor_dsp)
1034                         continue;
1035
1036                 oss_device_exit(dev);
1037
1038         }
1039
1040         dmasound_init = NULL;
1041         dmasound_exit = NULL;
1042
1043         printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n");
1044
1045         return;
1046 }
1047
1048 /* We initialize this late, to make sure the sound system is up and running */
1049 late_initcall(saa7134_oss_init);
1050 module_exit(saa7134_oss_exit);
1051 MODULE_LICENSE("GPL");
1052 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
1053
1054 /* ----------------------------------------------------------- */
1055 /*
1056  * Local variables:
1057  * c-basic-offset: 8
1058  * End:
1059  */