Merge master.kernel.org:/home/rmk/linux-2.6-mmc
[sfrench/cifs-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         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 int dsp_ioctl(struct inode *inode, struct file *file,
377                      unsigned int cmd, unsigned long arg)
378 {
379         struct saa7134_dev *dev = file->private_data;
380         void __user *argp = (void __user *) arg;
381         int __user *p = argp;
382         int val = 0;
383
384         if (debug > 1)
385                 saa7134_print_ioctl(dev->name,cmd);
386         switch (cmd) {
387         case OSS_GETVERSION:
388                 return put_user(SOUND_VERSION, p);
389         case SNDCTL_DSP_GETCAPS:
390                 return 0;
391
392         case SNDCTL_DSP_SPEED:
393                 if (get_user(val, p))
394                         return -EFAULT;
395                 /* fall through */
396         case SOUND_PCM_READ_RATE:
397                 return put_user(dev->dmasound.rate, p);
398
399         case SNDCTL_DSP_STEREO:
400                 if (get_user(val, p))
401                         return -EFAULT;
402                 down(&dev->dmasound.lock);
403                 dev->dmasound.channels = val ? 2 : 1;
404                 if (dev->dmasound.recording_on) {
405                         dsp_rec_stop(dev);
406                         dsp_rec_start(dev);
407                 }
408                 up(&dev->dmasound.lock);
409                 return put_user(dev->dmasound.channels-1, p);
410
411         case SNDCTL_DSP_CHANNELS:
412                 if (get_user(val, p))
413                         return -EFAULT;
414                 if (val != 1 && val != 2)
415                         return -EINVAL;
416                 down(&dev->dmasound.lock);
417                 dev->dmasound.channels = val;
418                 if (dev->dmasound.recording_on) {
419                         dsp_rec_stop(dev);
420                         dsp_rec_start(dev);
421                 }
422                 up(&dev->dmasound.lock);
423                 /* fall through */
424         case SOUND_PCM_READ_CHANNELS:
425                 return put_user(dev->dmasound.channels, p);
426
427         case SNDCTL_DSP_GETFMTS: /* Returns a mask */
428                 return put_user(AFMT_U8     | AFMT_S8     |
429                                 AFMT_U16_LE | AFMT_U16_BE |
430                                 AFMT_S16_LE | AFMT_S16_BE, p);
431
432         case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
433                 if (get_user(val, p))
434                         return -EFAULT;
435                 switch (val) {
436                 case AFMT_QUERY:
437                         /* nothing to do */
438                         break;
439                 case AFMT_U8:
440                 case AFMT_S8:
441                 case AFMT_U16_LE:
442                 case AFMT_U16_BE:
443                 case AFMT_S16_LE:
444                 case AFMT_S16_BE:
445                         down(&dev->dmasound.lock);
446                         dev->dmasound.afmt = val;
447                         if (dev->dmasound.recording_on) {
448                                 dsp_rec_stop(dev);
449                                 dsp_rec_start(dev);
450                         }
451                         up(&dev->dmasound.lock);
452                         return put_user(dev->dmasound.afmt, p);
453                 default:
454                         return -EINVAL;
455                 }
456
457         case SOUND_PCM_READ_BITS:
458                 switch (dev->dmasound.afmt) {
459                 case AFMT_U8:
460                 case AFMT_S8:
461                         return put_user(8, p);
462                 case AFMT_U16_LE:
463                 case AFMT_U16_BE:
464                 case AFMT_S16_LE:
465                 case AFMT_S16_BE:
466                         return put_user(16, p);
467                 default:
468                         return -EINVAL;
469                 }
470
471         case SNDCTL_DSP_NONBLOCK:
472                 file->f_flags |= O_NONBLOCK;
473                 return 0;
474
475         case SNDCTL_DSP_RESET:
476                 down(&dev->dmasound.lock);
477                 if (dev->dmasound.recording_on)
478                         dsp_rec_stop(dev);
479                 up(&dev->dmasound.lock);
480                 return 0;
481         case SNDCTL_DSP_GETBLKSIZE:
482                 return put_user(dev->dmasound.blksize, p);
483
484         case SNDCTL_DSP_SETFRAGMENT:
485                 if (get_user(val, p))
486                         return -EFAULT;
487                 if (dev->dmasound.recording_on)
488                         return -EBUSY;
489                 dsp_buffer_free(dev);
490                 /* used to be arg >> 16 instead of val >> 16; fixed */
491                 dsp_buffer_conf(dev,1 << (val & 0xffff), (val >> 16) & 0xffff);
492                 dsp_buffer_init(dev);
493                 return 0;
494
495         case SNDCTL_DSP_SYNC:
496                 /* NOP */
497                 return 0;
498
499         case SNDCTL_DSP_GETISPACE:
500         {
501                 audio_buf_info info;
502                 info.fragsize   = dev->dmasound.blksize;
503                 info.fragstotal = dev->dmasound.blocks;
504                 info.bytes      = dev->dmasound.read_count;
505                 info.fragments  = info.bytes / info.fragsize;
506                 if (copy_to_user(argp, &info, sizeof(info)))
507                         return -EFAULT;
508                 return 0;
509         }
510         default:
511                 return -EINVAL;
512         }
513 }
514
515 static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
516 {
517         struct saa7134_dev *dev = file->private_data;
518         unsigned int mask = 0;
519
520         poll_wait(file, &dev->dmasound.wq, wait);
521
522         if (0 == dev->dmasound.read_count) {
523                 down(&dev->dmasound.lock);
524                 if (!dev->dmasound.recording_on)
525                         dsp_rec_start(dev);
526                 up(&dev->dmasound.lock);
527         } else
528                 mask |= (POLLIN | POLLRDNORM);
529         return mask;
530 }
531
532 struct file_operations saa7134_dsp_fops = {
533         .owner   = THIS_MODULE,
534         .open    = dsp_open,
535         .release = dsp_release,
536         .read    = dsp_read,
537         .write   = dsp_write,
538         .ioctl   = dsp_ioctl,
539         .poll    = dsp_poll,
540         .llseek  = no_llseek,
541 };
542
543 /* ------------------------------------------------------------------ */
544
545 static int
546 mixer_recsrc_7134(struct saa7134_dev *dev)
547 {
548         int analog_io,rate;
549
550         switch (dev->dmasound.input) {
551         case TV:
552                 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
553                 saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, 0x00);
554                 break;
555         case LINE1:
556         case LINE2:
557         case LINE2_LEFT:
558                 analog_io = (LINE1 == dev->dmasound.input) ? 0x00 : 0x08;
559                 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
560                 saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x08, analog_io);
561                 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
562                 saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, rate);
563                 break;
564         }
565         return 0;
566 }
567
568 static int
569 mixer_recsrc_7133(struct saa7134_dev *dev)
570 {
571         u32 anabar, xbarin;
572
573         xbarin = 0x03; // adc
574     anabar = 0;
575         switch (dev->dmasound.input) {
576         case TV:
577                 xbarin = 0; // Demodulator
578         anabar = 2; // DACs
579                 break;
580         case LINE1:
581                 anabar = 0;  // aux1, aux1
582                 break;
583         case LINE2:
584         case LINE2_LEFT:
585                 anabar = 9;  // aux2, aux2
586                 break;
587         }
588     /* output xbar always main channel */
589         saa_dsp_writel(dev, 0x46c >> 2, 0xbbbb10);
590         saa_dsp_writel(dev, 0x464 >> 2, xbarin);
591         saa_writel(0x594 >> 2, anabar);
592
593         return 0;
594 }
595
596 static int
597 mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
598 {
599         static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
600
601         dev->dmasound.count++;
602         dev->dmasound.input = src;
603         dprintk("mixer input = %s\n",iname[dev->dmasound.input]);
604
605         switch (dev->pci->device) {
606         case PCI_DEVICE_ID_PHILIPS_SAA7134:
607                 mixer_recsrc_7134(dev);
608                 break;
609         case PCI_DEVICE_ID_PHILIPS_SAA7133:
610         case PCI_DEVICE_ID_PHILIPS_SAA7135:
611                 mixer_recsrc_7133(dev);
612                 break;
613         }
614         return 0;
615 }
616
617 static int
618 mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
619 {
620         switch (dev->pci->device) {
621         case PCI_DEVICE_ID_PHILIPS_SAA7134:
622                 switch (src) {
623                 case TV:
624                         /* nothing */
625                         break;
626                 case LINE1:
627                         saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x10,
628                                    (100 == level) ? 0x00 : 0x10);
629                         break;
630                 case LINE2:
631                 case LINE2_LEFT:
632                         saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x20,
633                                    (100 == level) ? 0x00 : 0x20);
634                         break;
635                 }
636                 break;
637         case PCI_DEVICE_ID_PHILIPS_SAA7133:
638         case PCI_DEVICE_ID_PHILIPS_SAA7135:
639                 /* nothing */
640                 break;
641         }
642         return 0;
643 }
644
645 /* ------------------------------------------------------------------ */
646
647 static int mixer_open(struct inode *inode, struct file *file)
648 {
649         int minor = iminor(inode);
650         struct saa7134_dev *h,*dev = NULL;
651         struct list_head *list;
652
653         list_for_each(list,&saa7134_devlist) {
654                 h = list_entry(list, struct saa7134_dev, devlist);
655                 if (h->dmasound.minor_mixer == minor)
656                         dev = h;
657         }
658         if (NULL == dev)
659                 return -ENODEV;
660
661         file->private_data = dev;
662         return 0;
663 }
664
665 static int mixer_release(struct inode *inode, struct file *file)
666 {
667         file->private_data = NULL;
668         return 0;
669 }
670
671 static int mixer_ioctl(struct inode *inode, struct file *file,
672                      unsigned int cmd, unsigned long arg)
673 {
674         struct saa7134_dev *dev = file->private_data;
675         enum saa7134_audio_in input;
676         int val,ret;
677         void __user *argp = (void __user *) arg;
678         int __user *p = argp;
679
680         if (debug > 1)
681                 saa7134_print_ioctl(dev->name,cmd);
682         switch (cmd) {
683         case OSS_GETVERSION:
684                 return put_user(SOUND_VERSION, p);
685         case SOUND_MIXER_INFO:
686         {
687                 mixer_info info;
688                 memset(&info,0,sizeof(info));
689                 strlcpy(info.id,   "TV audio", sizeof(info.id));
690                 strlcpy(info.name, dev->name,  sizeof(info.name));
691                 info.modify_counter = dev->dmasound.count;
692                 if (copy_to_user(argp, &info, sizeof(info)))
693                         return -EFAULT;
694                 return 0;
695         }
696         case SOUND_OLD_MIXER_INFO:
697         {
698                 _old_mixer_info info;
699                 memset(&info,0,sizeof(info));
700                 strlcpy(info.id,   "TV audio", sizeof(info.id));
701                 strlcpy(info.name, dev->name,  sizeof(info.name));
702                 if (copy_to_user(argp, &info, sizeof(info)))
703                         return -EFAULT;
704                 return 0;
705         }
706         case MIXER_READ(SOUND_MIXER_CAPS):
707                 return put_user(SOUND_CAP_EXCL_INPUT, p);
708         case MIXER_READ(SOUND_MIXER_STEREODEVS):
709                 return put_user(0, p);
710         case MIXER_READ(SOUND_MIXER_RECMASK):
711         case MIXER_READ(SOUND_MIXER_DEVMASK):
712                 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
713                 if (32000 == dev->dmasound.rate)
714                         val |= SOUND_MASK_VIDEO;
715                 return put_user(val, p);
716
717         case MIXER_WRITE(SOUND_MIXER_RECSRC):
718                 if (get_user(val, p))
719                         return -EFAULT;
720                 input = dev->dmasound.input;
721                 if (32000 == dev->dmasound.rate  &&
722                     val & SOUND_MASK_VIDEO  &&  dev->dmasound.input != TV)
723                         input = TV;
724                 if (val & SOUND_MASK_LINE1  &&  dev->dmasound.input != LINE1)
725                         input = LINE1;
726                 if (val & SOUND_MASK_LINE2  &&  dev->dmasound.input != LINE2)
727                         input = LINE2;
728                 if (input != dev->dmasound.input)
729                         mixer_recsrc(dev,input);
730                 /* fall throuth */
731         case MIXER_READ(SOUND_MIXER_RECSRC):
732                 switch (dev->dmasound.input) {
733                 case TV:    ret = SOUND_MASK_VIDEO; break;
734                 case LINE1: ret = SOUND_MASK_LINE1; break;
735                 case LINE2: ret = SOUND_MASK_LINE2; break;
736                 default:    ret = 0;
737                 }
738                 return put_user(ret, p);
739
740         case MIXER_WRITE(SOUND_MIXER_VIDEO):
741         case MIXER_READ(SOUND_MIXER_VIDEO):
742                 if (32000 != dev->dmasound.rate)
743                         return -EINVAL;
744                 return put_user(100 | 100 << 8, p);
745
746         case MIXER_WRITE(SOUND_MIXER_LINE1):
747                 if (get_user(val, p))
748                         return -EFAULT;
749                 val &= 0xff;
750                 val = (val <= 50) ? 50 : 100;
751                 dev->dmasound.line1 = val;
752                 mixer_level(dev,LINE1,dev->dmasound.line1);
753                 /* fall throuth */
754         case MIXER_READ(SOUND_MIXER_LINE1):
755                 return put_user(dev->dmasound.line1 | dev->dmasound.line1 << 8, p);
756
757         case MIXER_WRITE(SOUND_MIXER_LINE2):
758                 if (get_user(val, p))
759                         return -EFAULT;
760                 val &= 0xff;
761                 val = (val <= 50) ? 50 : 100;
762                 dev->dmasound.line2 = val;
763                 mixer_level(dev,LINE2,dev->dmasound.line2);
764                 /* fall throuth */
765         case MIXER_READ(SOUND_MIXER_LINE2):
766                 return put_user(dev->dmasound.line2 | dev->dmasound.line2 << 8, p);
767
768         default:
769                 return -EINVAL;
770         }
771 }
772
773 struct file_operations saa7134_mixer_fops = {
774         .owner   = THIS_MODULE,
775         .open    = mixer_open,
776         .release = mixer_release,
777         .ioctl   = mixer_ioctl,
778         .llseek  = no_llseek,
779 };
780
781 /* ------------------------------------------------------------------ */
782
783 static irqreturn_t saa7134_oss_irq(int irq, void *dev_id, struct pt_regs *regs)
784 {
785         struct saa7134_dmasound *dmasound = dev_id;
786         struct saa7134_dev *dev = dmasound->priv_data;
787         unsigned long report, status;
788         int loop, handled = 0;
789
790         for (loop = 0; loop < 10; loop++) {
791                 report = saa_readl(SAA7134_IRQ_REPORT);
792                 status = saa_readl(SAA7134_IRQ_STATUS);
793
794                 if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
795                         handled = 1;
796                         saa_writel(SAA7134_IRQ_REPORT,report);
797                         saa7134_irq_oss_done(dev, status);
798                 } else {
799                         goto out;
800                 }
801         }
802
803         if (loop == 10) {
804                 dprintk("error! looping IRQ!");
805         }
806 out:
807         return IRQ_RETVAL(handled);
808 }
809
810 int saa7134_oss_init1(struct saa7134_dev *dev)
811 {
812
813         if ((request_irq(dev->pci->irq, saa7134_oss_irq,
814                          SA_SHIRQ | SA_INTERRUPT, dev->name,
815                         (void*) &dev->dmasound)) < 0)
816                 return -1;
817
818         /* general */
819         init_MUTEX(&dev->dmasound.lock);
820         init_waitqueue_head(&dev->dmasound.wq);
821
822         switch (dev->pci->device) {
823         case PCI_DEVICE_ID_PHILIPS_SAA7133:
824         case PCI_DEVICE_ID_PHILIPS_SAA7135:
825                 saa_writel(0x588 >> 2, 0x00000fff);
826                 saa_writel(0x58c >> 2, 0x00543210);
827                 saa_dsp_writel(dev, 0x46c >> 2, 0xbbbbbb);
828                 break;
829         }
830
831         /* dsp */
832         dev->dmasound.rate = 32000;
833         if (rate)
834                 dev->dmasound.rate = rate;
835         dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000;
836
837         /* mixer */
838         dev->dmasound.line1 = 50;
839         dev->dmasound.line2 = 50;
840         mixer_level(dev,LINE1,dev->dmasound.line1);
841         mixer_level(dev,LINE2,dev->dmasound.line2);
842         mixer_recsrc(dev, (dev->dmasound.rate == 32000) ? TV : LINE2);
843
844         return 0;
845 }
846
847 int saa7134_oss_fini(struct saa7134_dev *dev)
848 {
849         /* nothing */
850         return 0;
851 }
852
853 void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
854 {
855         int next_blk, reg = 0;
856
857         spin_lock(&dev->slock);
858         if (UNSET == dev->dmasound.dma_blk) {
859                 dprintk("irq: recording stopped\n");
860                 goto done;
861         }
862         if (0 != (status & 0x0f000000))
863                 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
864         if (0 == (status & 0x10000000)) {
865                 /* odd */
866                 if (0 == (dev->dmasound.dma_blk & 0x01))
867                         reg = SAA7134_RS_BA1(6);
868         } else {
869                 /* even */
870                 if (1 == (dev->dmasound.dma_blk & 0x01))
871                         reg = SAA7134_RS_BA2(6);
872         }
873         if (0 == reg) {
874                 dprintk("irq: field oops [%s]\n",
875                         (status & 0x10000000) ? "even" : "odd");
876                 goto done;
877         }
878         if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
879                 dprintk("irq: overrun [full=%d/%d]\n",dev->dmasound.read_count,
880                         dev->dmasound.bufsize);
881                 dsp_dma_stop(dev);
882                 goto done;
883         }
884
885         /* next block addr */
886         next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
887         saa_writel(reg,next_blk * dev->dmasound.blksize);
888         if (debug > 2)
889                 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
890                         (status & 0x10000000) ? "even" : "odd ", next_blk,
891                         next_blk * dev->dmasound.blksize);
892
893         /* update status & wake waiting readers */
894         dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
895         dev->dmasound.read_count += dev->dmasound.blksize;
896         wake_up(&dev->dmasound.wq);
897
898  done:
899         spin_unlock(&dev->slock);
900 }
901
902 static int saa7134_dsp_create(struct saa7134_dev *dev)
903 {
904         int err;
905
906         err = dev->dmasound.minor_dsp =
907                 register_sound_dsp(&saa7134_dsp_fops,
908                                    dsp_nr[dev->nr]);
909         if (err < 0) {
910                 goto fail;
911         }
912         printk(KERN_INFO "%s: registered device dsp%d\n",
913                dev->name,dev->dmasound.minor_dsp >> 4);
914
915         err = dev->dmasound.minor_mixer =
916                 register_sound_mixer(&saa7134_mixer_fops,
917                                      mixer_nr[dev->nr]);
918         if (err < 0)
919                 goto fail;
920         printk(KERN_INFO "%s: registered device mixer%d\n",
921                dev->name,dev->dmasound.minor_mixer >> 4);
922
923         return 0;
924
925 fail:
926         unregister_sound_dsp(dev->dmasound.minor_dsp);
927         return 0;
928
929
930 }
931
932 static int oss_device_init(struct saa7134_dev *dev)
933 {
934         dev->dmasound.priv_data = dev;
935         saa7134_oss_init1(dev);
936         saa7134_dsp_create(dev);
937         return 1;
938 }
939
940 static int oss_device_exit(struct saa7134_dev *dev)
941 {
942
943         unregister_sound_mixer(dev->dmasound.minor_mixer);
944         unregister_sound_dsp(dev->dmasound.minor_dsp);
945
946         saa7134_oss_fini(dev);
947
948         if (dev->pci->irq > 0) {
949                 synchronize_irq(dev->pci->irq);
950                 free_irq(dev->pci->irq,&dev->dmasound);
951         }
952
953         dev->dmasound.priv_data = NULL;
954         return 1;
955 }
956
957 static int saa7134_oss_init(void)
958 {
959         struct saa7134_dev *dev = NULL;
960         struct list_head *list;
961
962         printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n");
963
964         list_for_each(list,&saa7134_devlist) {
965                 dev = list_entry(list, struct saa7134_dev, devlist);
966                 if (dev->dmasound.priv_data == NULL) {
967                         oss_device_init(dev);
968                 } else {
969                         printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name);
970                         return -EBUSY;
971                 }
972         }
973
974         if (dev == NULL)
975                 printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n");
976
977         dmasound_init = oss_device_init;
978         dmasound_exit = oss_device_exit;
979
980         return 0;
981
982 }
983
984 static void saa7134_oss_exit(void)
985 {
986         struct saa7134_dev *dev = NULL;
987         struct list_head *list;
988
989         list_for_each(list,&saa7134_devlist) {
990                 dev = list_entry(list, struct saa7134_dev, devlist);
991
992                 /* Device isn't registered by OSS, probably ALSA's */
993                 if (!dev->dmasound.minor_dsp)
994                         continue;
995
996                 oss_device_exit(dev);
997
998         }
999
1000         printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n");
1001
1002         return;
1003 }
1004
1005 module_init(saa7134_oss_init);
1006 module_exit(saa7134_oss_exit);
1007 MODULE_LICENSE("GPL");
1008 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
1009
1010 /* ----------------------------------------------------------- */
1011 /*
1012  * Local variables:
1013  * c-basic-offset: 8
1014  * End:
1015  */