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