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