blob: 21cb3d6be839cfa3e969a155ce49a68a79020b43 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
3 * device driver for philips saa7134 based TV cards
4 * driver core
5 *
6 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/config.h>
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/kmod.h>
31#include <linux/sound.h>
32#include <linux/interrupt.h>
33#include <linux/delay.h>
34
35#include "saa7134-reg.h"
36#include "saa7134.h"
37
38MODULE_DESCRIPTION("v4l2 driver module for saa7130/34 based TV cards");
39MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
40MODULE_LICENSE("GPL");
41
42/* ------------------------------------------------------------------ */
43
44static unsigned int irq_debug = 0;
45module_param(irq_debug, int, 0644);
46MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]");
47
48static unsigned int core_debug = 0;
49module_param(core_debug, int, 0644);
50MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
51
52static unsigned int gpio_tracking = 0;
53module_param(gpio_tracking, int, 0644);
54MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
55
Ricardo Cerqueirabd15eba2005-11-08 21:37:11 -080056static unsigned int alsa = 0;
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -080057module_param(alsa, int, 0644);
58MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]");
59
60static unsigned int oss = 0;
61module_param(oss, int, 0644);
62MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]");
Ricardo Cerqueirabd15eba2005-11-08 21:37:11 -080063
Linus Torvalds1da177e2005-04-16 15:20:36 -070064static unsigned int latency = UNSET;
65module_param(latency, int, 0444);
66MODULE_PARM_DESC(latency,"pci latency timer");
67
68static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
69static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
70static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
Linus Torvalds1da177e2005-04-16 15:20:36 -070071static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
72static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
73
Mauro Carvalho Chehab674434c2005-12-12 00:37:28 -080074
Linus Torvalds1da177e2005-04-16 15:20:36 -070075module_param_array(video_nr, int, NULL, 0444);
76module_param_array(vbi_nr, int, NULL, 0444);
77module_param_array(radio_nr, int, NULL, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -070078module_param_array(tuner, int, NULL, 0444);
79module_param_array(card, int, NULL, 0444);
80
81MODULE_PARM_DESC(video_nr, "video device number");
82MODULE_PARM_DESC(vbi_nr, "vbi device number");
83MODULE_PARM_DESC(radio_nr, "radio device number");
Linus Torvalds1da177e2005-04-16 15:20:36 -070084MODULE_PARM_DESC(tuner, "tuner type");
85MODULE_PARM_DESC(card, "card type");
86
87static DECLARE_MUTEX(devlist_lock);
88LIST_HEAD(saa7134_devlist);
89static LIST_HEAD(mops_list);
90static unsigned int saa7134_devcount;
91
Ricardo Cerqueiraf5b974c2005-12-01 00:51:20 -080092int (*dmasound_init)(struct saa7134_dev *dev);
93int (*dmasound_exit)(struct saa7134_dev *dev);
94
Linus Torvalds1da177e2005-04-16 15:20:36 -070095#define dprintk(fmt, arg...) if (core_debug) \
96 printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg)
97
98/* ------------------------------------------------------------------ */
99/* debug help functions */
100
101static const char *v4l1_ioctls[] = {
102 "0", "GCAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
103 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
104 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
105 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
106 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
107#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
108
109static const char *v4l2_ioctls[] = {
110 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
111 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
112 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
113 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
114 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
115 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
116 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
117 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
118 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
119 "S_MODULATOR"
120};
121#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
122
123static const char *osspcm_ioctls[] = {
124 "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
125 "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS",
126 "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER",
127 "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
128 "SETDUPLEX", "GETODELAY"
129};
130#define OSSPCM_IOCTLS ARRAY_SIZE(v4l2_ioctls)
131
132void saa7134_print_ioctl(char *name, unsigned int cmd)
133{
134 char *dir;
135
136 switch (_IOC_DIR(cmd)) {
137 case _IOC_NONE: dir = "--"; break;
138 case _IOC_READ: dir = "r-"; break;
139 case _IOC_WRITE: dir = "-w"; break;
140 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
141 default: dir = "??"; break;
142 }
143 switch (_IOC_TYPE(cmd)) {
144 case 'v':
145 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
146 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
147 v4l1_ioctls[_IOC_NR(cmd)] : "???");
148 break;
149 case 'V':
150 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
151 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
152 v4l2_ioctls[_IOC_NR(cmd)] : "???");
153 break;
154 case 'P':
155 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
156 name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
157 osspcm_ioctls[_IOC_NR(cmd)] : "???");
158 break;
159 case 'M':
160 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
161 name, cmd, dir, _IOC_NR(cmd));
162 break;
163 default:
164 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
165 name, cmd, dir, _IOC_NR(cmd));
166 }
167}
168
169void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
170{
171 unsigned long mode,status;
172
173 if (!gpio_tracking)
174 return;
175 /* rising SAA7134_GPIO_GPRESCAN reads the status */
176 saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,0);
177 saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,SAA7134_GPIO_GPRESCAN);
178 mode = saa_readl(SAA7134_GPIO_GPMODE0 >> 2) & 0xfffffff;
179 status = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & 0xfffffff;
180 printk(KERN_DEBUG
181 "%s: gpio: mode=0x%07lx in=0x%07lx out=0x%07lx [%s]\n",
182 dev->name, mode, (~mode) & status, mode & status, msg);
183}
184
185/* ------------------------------------------------------------------ */
186
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187
188/* ----------------------------------------------------------- */
189/* delayed request_module */
190
Reimar Doeffingerfd1eab72005-12-01 00:51:39 -0800191#if defined(CONFIG_MODULES) && defined(MODULE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192static int need_empress;
193static int need_dvb;
Ricardo Cerqueirab54134b2005-11-08 21:38:54 -0800194static int need_alsa;
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -0800195static int need_oss;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197static int pending_call(struct notifier_block *self, unsigned long state,
198 void *module)
199{
200 if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
201 return NOTIFY_DONE;
202
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800203 if (need_empress)
204 request_module("saa7134-empress");
205 if (need_dvb)
206 request_module("saa7134-dvb");
Ricardo Cerqueirab54134b2005-11-08 21:38:54 -0800207 if (need_alsa)
208 request_module("saa7134-alsa");
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -0800209 if (need_oss)
210 request_module("saa7134-oss");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 return NOTIFY_DONE;
212}
213
214static int pending_registered;
215static struct notifier_block pending_notifier = {
216 .notifier_call = pending_call,
217};
218
219static void request_module_depend(char *name, int *flag)
220{
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -0800221 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 switch (THIS_MODULE->state) {
223 case MODULE_STATE_COMING:
224 if (!pending_registered) {
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -0800225 err = register_module_notifier(&pending_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 pending_registered = 1;
227 }
228 *flag = 1;
229 break;
230 case MODULE_STATE_LIVE:
231 request_module(name);
232 break;
233 default:
234 /* nothing */;
235 break;
236 }
237}
238
239#else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240#define request_module_depend(name,flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241#endif /* CONFIG_MODULES */
242
243/* ------------------------------------------------------------------ */
244
245/* nr of (saa7134-)pages for the given buffer size */
246static int saa7134_buffer_pages(int size)
247{
248 size = PAGE_ALIGN(size);
249 size += PAGE_SIZE; /* for non-page-aligned buffers */
250 size /= 4096;
251 return size;
252}
253
254/* calc max # of buffers from size (must not exceed the 4MB virtual
255 * address space per DMA channel) */
256int saa7134_buffer_count(unsigned int size, unsigned int count)
257{
258 unsigned int maxcount;
259
260 maxcount = 1024 / saa7134_buffer_pages(size);
261 if (count > maxcount)
262 count = maxcount;
263 return count;
264}
265
266int saa7134_buffer_startpage(struct saa7134_buf *buf)
267{
268 return saa7134_buffer_pages(buf->vb.bsize) * buf->vb.i;
269}
270
271unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
272{
273 unsigned long base;
274
275 base = saa7134_buffer_startpage(buf) * 4096;
276 base += buf->vb.dma.sglist[0].offset;
277 return base;
278}
279
280/* ------------------------------------------------------------------ */
281
282int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
283{
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800284 __le32 *cpu;
285 dma_addr_t dma_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286
287 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
288 if (NULL == cpu)
289 return -ENOMEM;
290 pt->size = SAA7134_PGTABLE_SIZE;
291 pt->cpu = cpu;
292 pt->dma = dma_addr;
293 return 0;
294}
295
296int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
297 struct scatterlist *list, unsigned int length,
298 unsigned int startpage)
299{
Alexey Dobriyanc9c12b72005-06-23 22:04:37 -0700300 __le32 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 unsigned int i,p;
302
303 BUG_ON(NULL == pt || NULL == pt->cpu);
304
305 ptr = pt->cpu + startpage;
306 for (i = 0; i < length; i++, list++)
307 for (p = 0; p * 4096 < list->length; p++, ptr++)
Gerd Knorra20758f2005-06-23 22:04:34 -0700308 *ptr = cpu_to_le32(sg_dma_address(list) - list->offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 return 0;
310}
311
312void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
313{
314 if (NULL == pt->cpu)
315 return;
316 pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
317 pt->cpu = NULL;
318}
319
320/* ------------------------------------------------------------------ */
321
322void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf)
323{
324 if (in_interrupt())
325 BUG();
326
327 videobuf_waiton(&buf->vb,0,0);
328 videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
329 videobuf_dma_free(&buf->vb.dma);
330 buf->vb.state = STATE_NEEDS_INIT;
331}
332
333/* ------------------------------------------------------------------ */
334
335int saa7134_buffer_queue(struct saa7134_dev *dev,
336 struct saa7134_dmaqueue *q,
337 struct saa7134_buf *buf)
338{
339 struct saa7134_buf *next = NULL;
340
341 assert_spin_locked(&dev->slock);
342 dprintk("buffer_queue %p\n",buf);
343 if (NULL == q->curr) {
344 if (!q->need_two) {
345 q->curr = buf;
346 buf->activate(dev,buf,NULL);
347 } else if (list_empty(&q->queue)) {
348 list_add_tail(&buf->vb.queue,&q->queue);
349 buf->vb.state = STATE_QUEUED;
350 } else {
351 next = list_entry(q->queue.next,struct saa7134_buf,
352 vb.queue);
353 q->curr = buf;
354 buf->activate(dev,buf,next);
355 }
356 } else {
357 list_add_tail(&buf->vb.queue,&q->queue);
358 buf->vb.state = STATE_QUEUED;
359 }
360 return 0;
361}
362
363void saa7134_buffer_finish(struct saa7134_dev *dev,
364 struct saa7134_dmaqueue *q,
365 unsigned int state)
366{
367 assert_spin_locked(&dev->slock);
368 dprintk("buffer_finish %p\n",q->curr);
369
370 /* finish current buffer */
371 q->curr->vb.state = state;
372 do_gettimeofday(&q->curr->vb.ts);
373 wake_up(&q->curr->vb.done);
374 q->curr = NULL;
375}
376
377void saa7134_buffer_next(struct saa7134_dev *dev,
378 struct saa7134_dmaqueue *q)
379{
380 struct saa7134_buf *buf,*next = NULL;
381
382 assert_spin_locked(&dev->slock);
383 BUG_ON(NULL != q->curr);
384
385 if (!list_empty(&q->queue)) {
386 /* activate next one from queue */
387 buf = list_entry(q->queue.next,struct saa7134_buf,vb.queue);
388 dprintk("buffer_next %p [prev=%p/next=%p]\n",
389 buf,q->queue.prev,q->queue.next);
390 list_del(&buf->vb.queue);
391 if (!list_empty(&q->queue))
392 next = list_entry(q->queue.next,struct saa7134_buf,
393 vb.queue);
394 q->curr = buf;
395 buf->activate(dev,buf,next);
396 dprintk("buffer_next #2 prev=%p/next=%p\n",
397 q->queue.prev,q->queue.next);
398 } else {
399 /* nothing to do -- just stop DMA */
400 dprintk("buffer_next %p\n",NULL);
401 saa7134_set_dmabits(dev);
402 del_timer(&q->timeout);
403 }
404}
405
406void saa7134_buffer_timeout(unsigned long data)
407{
408 struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data;
409 struct saa7134_dev *dev = q->dev;
410 unsigned long flags;
411
412 spin_lock_irqsave(&dev->slock,flags);
413
414 /* try to reset the hardware (SWRST) */
415 saa_writeb(SAA7134_REGION_ENABLE, 0x00);
416 saa_writeb(SAA7134_REGION_ENABLE, 0x80);
417 saa_writeb(SAA7134_REGION_ENABLE, 0x00);
418
419 /* flag current buffer as failed,
420 try to start over with the next one. */
421 if (q->curr) {
422 dprintk("timeout on %p\n",q->curr);
423 saa7134_buffer_finish(dev,q,STATE_ERROR);
424 }
425 saa7134_buffer_next(dev,q);
426 spin_unlock_irqrestore(&dev->slock,flags);
427}
428
429/* ------------------------------------------------------------------ */
430
431int saa7134_set_dmabits(struct saa7134_dev *dev)
432{
433 u32 split, task=0, ctrl=0, irq=0;
434 enum v4l2_field cap = V4L2_FIELD_ANY;
435 enum v4l2_field ov = V4L2_FIELD_ANY;
436
437 assert_spin_locked(&dev->slock);
438
439 /* video capture -- dma 0 + video task A */
440 if (dev->video_q.curr) {
441 task |= 0x01;
442 ctrl |= SAA7134_MAIN_CTRL_TE0;
443 irq |= SAA7134_IRQ1_INTE_RA0_1 |
444 SAA7134_IRQ1_INTE_RA0_0;
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800445 cap = dev->video_q.curr->vb.field;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 }
447
448 /* video capture -- dma 1+2 (planar modes) */
449 if (dev->video_q.curr &&
450 dev->video_q.curr->fmt->planar) {
451 ctrl |= SAA7134_MAIN_CTRL_TE4 |
452 SAA7134_MAIN_CTRL_TE5;
453 }
454
455 /* screen overlay -- dma 0 + video task B */
456 if (dev->ovenable) {
457 task |= 0x10;
458 ctrl |= SAA7134_MAIN_CTRL_TE1;
459 ov = dev->ovfield;
460 }
461
462 /* vbi capture -- dma 0 + vbi task A+B */
463 if (dev->vbi_q.curr) {
464 task |= 0x22;
465 ctrl |= SAA7134_MAIN_CTRL_TE2 |
466 SAA7134_MAIN_CTRL_TE3;
467 irq |= SAA7134_IRQ1_INTE_RA0_7 |
468 SAA7134_IRQ1_INTE_RA0_6 |
469 SAA7134_IRQ1_INTE_RA0_5 |
470 SAA7134_IRQ1_INTE_RA0_4;
471 }
472
473 /* audio capture -- dma 3 */
Ricardo Cerqueirab54134b2005-11-08 21:38:54 -0800474 if (dev->dmasound.dma_running) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 ctrl |= SAA7134_MAIN_CTRL_TE6;
476 irq |= SAA7134_IRQ1_INTE_RA3_1 |
477 SAA7134_IRQ1_INTE_RA3_0;
478 }
479
480 /* TS capture -- dma 5 */
481 if (dev->ts_q.curr) {
482 ctrl |= SAA7134_MAIN_CTRL_TE5;
483 irq |= SAA7134_IRQ1_INTE_RA2_3 |
484 SAA7134_IRQ1_INTE_RA2_2 |
485 SAA7134_IRQ1_INTE_RA2_1 |
486 SAA7134_IRQ1_INTE_RA2_0;
487 }
488
489 /* set task conditions + field handling */
490 if (V4L2_FIELD_HAS_BOTH(cap) || V4L2_FIELD_HAS_BOTH(ov) || cap == ov) {
491 /* default config -- use full frames */
492 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
493 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
494 saa_writeb(SAA7134_FIELD_HANDLING(TASK_A), 0x02);
495 saa_writeb(SAA7134_FIELD_HANDLING(TASK_B), 0x02);
496 split = 0;
497 } else {
498 /* split fields between tasks */
499 if (V4L2_FIELD_TOP == cap) {
500 /* odd A, even B, repeat */
501 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
502 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0e);
503 } else {
504 /* odd B, even A, repeat */
505 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0e);
506 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
507 }
508 saa_writeb(SAA7134_FIELD_HANDLING(TASK_A), 0x01);
509 saa_writeb(SAA7134_FIELD_HANDLING(TASK_B), 0x01);
510 split = 1;
511 }
512
513 /* irqs */
514 saa_writeb(SAA7134_REGION_ENABLE, task);
515 saa_writel(SAA7134_IRQ1, irq);
516 saa_andorl(SAA7134_MAIN_CTRL,
517 SAA7134_MAIN_CTRL_TE0 |
518 SAA7134_MAIN_CTRL_TE1 |
519 SAA7134_MAIN_CTRL_TE2 |
520 SAA7134_MAIN_CTRL_TE3 |
521 SAA7134_MAIN_CTRL_TE4 |
522 SAA7134_MAIN_CTRL_TE5 |
523 SAA7134_MAIN_CTRL_TE6,
524 ctrl);
525 dprintk("dmabits: task=0x%02x ctrl=0x%02x irq=0x%x split=%s\n",
526 task, ctrl, irq, split ? "no" : "yes");
527
528 return 0;
529}
530
531/* ------------------------------------------------------------------ */
532/* IRQ handler + helpers */
533
534static char *irqbits[] = {
535 "DONE_RA0", "DONE_RA1", "DONE_RA2", "DONE_RA3",
536 "AR", "PE", "PWR_ON", "RDCAP", "INTL", "FIDT", "MMC",
537 "TRIG_ERR", "CONF_ERR", "LOAD_ERR",
538 "GPIO16?", "GPIO18", "GPIO22", "GPIO23"
539};
540#define IRQBITS ARRAY_SIZE(irqbits)
541
542static void print_irqstatus(struct saa7134_dev *dev, int loop,
543 unsigned long report, unsigned long status)
544{
545 unsigned int i;
546
547 printk(KERN_DEBUG "%s/irq[%d,%ld]: r=0x%lx s=0x%02lx",
548 dev->name,loop,jiffies,report,status);
549 for (i = 0; i < IRQBITS; i++) {
550 if (!(report & (1 << i)))
551 continue;
552 printk(" %s",irqbits[i]);
553 }
554 if (report & SAA7134_IRQ_REPORT_DONE_RA0) {
555 printk(" | RA0=%s,%s,%s,%ld",
556 (status & 0x40) ? "vbi" : "video",
557 (status & 0x20) ? "b" : "a",
558 (status & 0x10) ? "odd" : "even",
559 (status & 0x0f));
560 }
561 printk("\n");
562}
563
564static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
565{
566 struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
567 unsigned long report,status;
568 int loop, handled = 0;
569
570 for (loop = 0; loop < 10; loop++) {
571 report = saa_readl(SAA7134_IRQ_REPORT);
572 status = saa_readl(SAA7134_IRQ_STATUS);
573 if (0 == report) {
574 if (irq_debug > 1)
575 printk(KERN_DEBUG "%s/irq: no (more) work\n",
576 dev->name);
577 goto out;
578 }
Ricardo Cerqueira79dd0c692005-11-08 21:38:53 -0800579
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -0800580 /* If dmasound support is active and we get a sound report, exit
581 and let the saa7134-alsa/oss module deal with it */
Ricardo Cerqueira79dd0c692005-11-08 21:38:53 -0800582
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -0800583 if ((report & SAA7134_IRQ_REPORT_DONE_RA3) &&
584 (dev->dmasound.priv_data != NULL) )
585 {
Ricardo Cerqueira79dd0c692005-11-08 21:38:53 -0800586 if (irq_debug > 1)
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -0800587 printk(KERN_DEBUG "%s/irq: ignoring interrupt for DMA sound\n",
Ricardo Cerqueira79dd0c692005-11-08 21:38:53 -0800588 dev->name);
589 goto out;
590 }
591
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 handled = 1;
593 saa_writel(SAA7134_IRQ_REPORT,report);
594 if (irq_debug)
595 print_irqstatus(dev,loop,report,status);
596
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597
598 if (report & SAA7134_IRQ_REPORT_RDCAP /* _INTL */)
599 saa7134_irq_video_intl(dev);
600
601 if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
602 (status & 0x60) == 0)
603 saa7134_irq_video_done(dev,status);
604
605 if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
606 (status & 0x40) == 0x40)
607 saa7134_irq_vbi_done(dev,status);
608
609 if ((report & SAA7134_IRQ_REPORT_DONE_RA2) &&
610 card_has_mpeg(dev))
611 saa7134_irq_ts_done(dev,status);
612
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
614 SAA7134_IRQ_REPORT_GPIO18)) &&
615 dev->remote)
616 saa7134_input_irq(dev);
Ricardo Cerqueirabd15eba2005-11-08 21:37:11 -0800617
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 }
619
620 if (10 == loop) {
621 print_irqstatus(dev,loop,report,status);
622 if (report & SAA7134_IRQ_REPORT_PE) {
623 /* disable all parity error */
624 printk(KERN_WARNING "%s/irq: looping -- "
625 "clearing PE (parity error!) enable bit\n",dev->name);
626 saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE);
627 } else if (report & (SAA7134_IRQ_REPORT_GPIO16 |
628 SAA7134_IRQ_REPORT_GPIO18)) {
629 /* disable gpio IRQs */
630 printk(KERN_WARNING "%s/irq: looping -- "
631 "clearing GPIO enable bits\n",dev->name);
632 saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 |
633 SAA7134_IRQ2_INTE_GPIO18));
634 } else {
635 /* disable all irqs */
636 printk(KERN_WARNING "%s/irq: looping -- "
637 "clearing all enable bits\n",dev->name);
638 saa_writel(SAA7134_IRQ1,0);
639 saa_writel(SAA7134_IRQ2,0);
640 }
641 }
642
643 out:
644 return IRQ_RETVAL(handled);
645}
646
647/* ------------------------------------------------------------------ */
648
649/* early init (no i2c, no irq) */
650static int saa7134_hwinit1(struct saa7134_dev *dev)
651{
652 dprintk("hwinit1\n");
653
654 saa_writel(SAA7134_IRQ1, 0);
655 saa_writel(SAA7134_IRQ2, 0);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800656 init_MUTEX(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 spin_lock_init(&dev->slock);
658
659 saa7134_track_gpio(dev,"pre-init");
660 saa7134_video_init1(dev);
661 saa7134_vbi_init1(dev);
662 if (card_has_mpeg(dev))
663 saa7134_ts_init1(dev);
664 saa7134_input_init1(dev);
665
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 /* RAM FIFO config */
667 saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
668 saa_writel(SAA7134_THRESHOULD,0x02020202);
669
670 /* enable audio + video processing */
671 saa_writel(SAA7134_MAIN_CTRL,
672 SAA7134_MAIN_CTRL_VPLLE |
673 SAA7134_MAIN_CTRL_APLLE |
674 SAA7134_MAIN_CTRL_EXOSC |
675 SAA7134_MAIN_CTRL_EVFE1 |
676 SAA7134_MAIN_CTRL_EVFE2 |
677 SAA7134_MAIN_CTRL_ESFE |
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 SAA7134_MAIN_CTRL_EBDAC);
679
Nickolay V. Shmyrev17a05ef2005-11-08 21:36:36 -0800680 /*
681 * Initialize OSS _after_ enabling audio clock PLL and audio processing.
682 * OSS initialization writes to registers via the audio DSP; these
683 * writes will fail unless the audio clock has been started. At worst,
684 * audio will not work.
685 */
686
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 /* enable peripheral devices */
688 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
689
690 /* set vertical line numbering start (vbi needs this) */
691 saa_writeb(SAA7134_SOURCE_TIMING2, 0x20);
692
693 return 0;
694}
695
696/* late init (with i2c + irq) */
697static int saa7134_hwinit2(struct saa7134_dev *dev)
698{
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700699 unsigned int irq2_mask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 dprintk("hwinit2\n");
701
702 saa7134_video_init2(dev);
703 saa7134_tvaudio_init2(dev);
704
705 /* enable IRQ's */
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800706 irq2_mask =
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700707 SAA7134_IRQ2_INTE_DEC3 |
708 SAA7134_IRQ2_INTE_DEC2 |
709 SAA7134_IRQ2_INTE_DEC1 |
710 SAA7134_IRQ2_INTE_DEC0 |
711 SAA7134_IRQ2_INTE_PE |
712 SAA7134_IRQ2_INTE_AR;
713
Ricardo Cerqueiracb2444d2005-11-08 21:38:47 -0800714 if (dev->has_remote == SAA7134_REMOTE_GPIO)
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700715 irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
716 SAA7134_IRQ2_INTE_GPIO18A |
717 SAA7134_IRQ2_INTE_GPIO16 );
718
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 saa_writel(SAA7134_IRQ1, 0);
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700720 saa_writel(SAA7134_IRQ2, irq2_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
722 return 0;
723}
724
725/* shutdown */
726static int saa7134_hwfini(struct saa7134_dev *dev)
727{
728 dprintk("hwfini\n");
729
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 if (card_has_mpeg(dev))
731 saa7134_ts_fini(dev);
732 saa7134_input_fini(dev);
733 saa7134_vbi_fini(dev);
734 saa7134_video_fini(dev);
735 saa7134_tvaudio_fini(dev);
736 return 0;
737}
738
739static void __devinit must_configure_manually(void)
740{
741 unsigned int i,p;
742
743 printk(KERN_WARNING
744 "saa7134: <rant>\n"
745 "saa7134: Congratulations! Your TV card vendor saved a few\n"
746 "saa7134: cents for a eeprom, thus your pci board has no\n"
747 "saa7134: subsystem ID and I can't identify it automatically\n"
748 "saa7134: </rant>\n"
749 "saa7134: I feel better now. Ok, here are the good news:\n"
750 "saa7134: You can use the card=<nr> insmod option to specify\n"
751 "saa7134: which board do you have. The list:\n");
752 for (i = 0; i < saa7134_bcount; i++) {
753 printk(KERN_WARNING "saa7134: card=%d -> %-40.40s",
754 i,saa7134_boards[i].name);
755 for (p = 0; saa7134_pci_tbl[p].driver_data; p++) {
756 if (saa7134_pci_tbl[p].driver_data != i)
757 continue;
758 printk(" %04x:%04x",
759 saa7134_pci_tbl[p].subvendor,
760 saa7134_pci_tbl[p].subdevice);
761 }
762 printk("\n");
763 }
764}
765
766static struct video_device *vdev_init(struct saa7134_dev *dev,
767 struct video_device *template,
768 char *type)
769{
770 struct video_device *vfd;
771
772 vfd = video_device_alloc();
773 if (NULL == vfd)
774 return NULL;
775 *vfd = *template;
776 vfd->minor = -1;
777 vfd->dev = &dev->pci->dev;
778 vfd->release = video_device_release;
779 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
780 dev->name, type, saa7134_boards[dev->board].name);
781 return vfd;
782}
783
784static void saa7134_unregister_video(struct saa7134_dev *dev)
785{
786 if (dev->video_dev) {
787 if (-1 != dev->video_dev->minor)
788 video_unregister_device(dev->video_dev);
789 else
790 video_device_release(dev->video_dev);
791 dev->video_dev = NULL;
792 }
793 if (dev->vbi_dev) {
794 if (-1 != dev->vbi_dev->minor)
795 video_unregister_device(dev->vbi_dev);
796 else
797 video_device_release(dev->vbi_dev);
798 dev->vbi_dev = NULL;
799 }
800 if (dev->radio_dev) {
801 if (-1 != dev->radio_dev->minor)
802 video_unregister_device(dev->radio_dev);
803 else
804 video_device_release(dev->radio_dev);
805 dev->radio_dev = NULL;
806 }
807}
808
809static void mpeg_ops_attach(struct saa7134_mpeg_ops *ops,
810 struct saa7134_dev *dev)
811{
812 int err;
813
814 if (NULL != dev->mops)
815 return;
816 if (saa7134_boards[dev->board].mpeg != ops->type)
817 return;
818 err = ops->init(dev);
819 if (0 != err)
820 return;
821 dev->mops = ops;
822}
823
824static void mpeg_ops_detach(struct saa7134_mpeg_ops *ops,
825 struct saa7134_dev *dev)
826{
827 if (NULL == dev->mops)
828 return;
829 if (dev->mops != ops)
830 return;
831 dev->mops->fini(dev);
832 dev->mops = NULL;
833}
834
835static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
836 const struct pci_device_id *pci_id)
837{
838 struct saa7134_dev *dev;
839 struct list_head *item;
840 struct saa7134_mpeg_ops *mops;
841 int err;
842
843 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
844 if (NULL == dev)
845 return -ENOMEM;
846 memset(dev,0,sizeof(*dev));
847
848 /* pci init */
849 dev->pci = pci_dev;
850 if (pci_enable_device(pci_dev)) {
851 err = -EIO;
852 goto fail1;
853 }
854
855 dev->nr = saa7134_devcount;
856 sprintf(dev->name,"saa%x[%d]",pci_dev->device,dev->nr);
857
858 /* pci quirks */
859 if (pci_pci_problems) {
860 if (pci_pci_problems & PCIPCI_TRITON)
861 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON\n", dev->name);
862 if (pci_pci_problems & PCIPCI_NATOMA)
863 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA\n", dev->name);
864 if (pci_pci_problems & PCIPCI_VIAETBF)
865 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF\n", dev->name);
866 if (pci_pci_problems & PCIPCI_VSFX)
867 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX\n",dev->name);
868#ifdef PCIPCI_ALIMAGIK
869 if (pci_pci_problems & PCIPCI_ALIMAGIK) {
870 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
871 dev->name);
872 latency = 0x0A;
873 }
874#endif
875 }
876 if (UNSET != latency) {
877 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
878 dev->name,latency);
879 pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
880 }
881
882 /* print pci info */
883 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800884 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
885 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 "latency: %d, mmio: 0x%lx\n", dev->name,
887 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
888 dev->pci_lat,pci_resource_start(pci_dev,0));
889 pci_set_master(pci_dev);
890 if (!pci_dma_supported(pci_dev,0xffffffff)) {
891 printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name);
892 err = -EIO;
893 goto fail1;
894 }
895
896 /* board config */
897 dev->board = pci_id->driver_data;
898 if (card[dev->nr] >= 0 &&
899 card[dev->nr] < saa7134_bcount)
900 dev->board = card[dev->nr];
901 if (SAA7134_BOARD_NOAUTO == dev->board) {
902 must_configure_manually();
903 dev->board = SAA7134_BOARD_UNKNOWN;
904 }
905 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
906 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
907 if (UNSET != tuner[dev->nr])
908 dev->tuner_type = tuner[dev->nr];
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800909 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 dev->name,pci_dev->subsystem_vendor,
911 pci_dev->subsystem_device,saa7134_boards[dev->board].name,
912 dev->board, card[dev->nr] == dev->board ?
913 "insmod option" : "autodetected");
914
915 /* get mmio */
916 if (!request_mem_region(pci_resource_start(pci_dev,0),
917 pci_resource_len(pci_dev,0),
918 dev->name)) {
919 err = -EBUSY;
920 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n",
921 dev->name,pci_resource_start(pci_dev,0));
922 goto fail1;
923 }
924 dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000);
925 dev->bmmio = (__u8 __iomem *)dev->lmmio;
926 if (NULL == dev->lmmio) {
927 err = -EIO;
928 printk(KERN_ERR "%s: can't ioremap() MMIO memory\n",
929 dev->name);
930 goto fail2;
931 }
932
933 /* initialize hardware #1 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 saa7134_board_init1(dev);
935 saa7134_hwinit1(dev);
936
937 /* get irq */
938 err = request_irq(pci_dev->irq, saa7134_irq,
939 SA_SHIRQ | SA_INTERRUPT, dev->name, dev);
940 if (err < 0) {
941 printk(KERN_ERR "%s: can't get IRQ %d\n",
942 dev->name,pci_dev->irq);
943 goto fail3;
944 }
945
946 /* wait a bit, register i2c bus */
947 msleep(100);
948 saa7134_i2c_register(dev);
949
950 /* initialize hardware #2 */
951 saa7134_board_init2(dev);
952 saa7134_hwinit2(dev);
953
954 /* load i2c helpers */
955 if (TUNER_ABSENT != dev->tuner_type)
956 request_module("tuner");
957 if (dev->tda9887_conf)
958 request_module("tda9887");
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800959 if (card_is_empress(dev)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 request_module("saa6752hs");
961 request_module_depend("saa7134-empress",&need_empress);
962 }
Mauro Carvalho Chehab330a1152005-07-12 13:59:01 -0700963
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800964 if (card_is_dvb(dev))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 request_module_depend("saa7134-dvb",&need_dvb);
966
Ricardo Cerqueirab54134b2005-11-08 21:38:54 -0800967
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -0800968 if (alsa)
969 request_module_depend("saa7134-alsa",&need_alsa);
970
971 if (oss)
972 request_module_depend("saa7134-oss",&need_oss);
Ricardo Cerqueirab54134b2005-11-08 21:38:54 -0800973
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 v4l2_prio_init(&dev->prio);
975
976 /* register v4l devices */
977 dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
978 err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
979 video_nr[dev->nr]);
980 if (err < 0) {
981 printk(KERN_INFO "%s: can't register video device\n",
982 dev->name);
983 goto fail4;
984 }
985 printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
986 dev->name,dev->video_dev->minor & 0x1f);
987
988 dev->vbi_dev = vdev_init(dev,&saa7134_vbi_template,"vbi");
989 err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
990 vbi_nr[dev->nr]);
991 if (err < 0)
992 goto fail4;
993 printk(KERN_INFO "%s: registered device vbi%d\n",
994 dev->name,dev->vbi_dev->minor & 0x1f);
995
996 if (card_has_radio(dev)) {
997 dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
998 err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
999 radio_nr[dev->nr]);
1000 if (err < 0)
1001 goto fail4;
1002 printk(KERN_INFO "%s: registered device radio%d\n",
1003 dev->name,dev->radio_dev->minor & 0x1f);
1004 }
1005
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 /* everything worked */
1007 pci_set_drvdata(pci_dev,dev);
1008 saa7134_devcount++;
1009
1010 down(&devlist_lock);
1011 list_for_each(item,&mops_list) {
1012 mops = list_entry(item, struct saa7134_mpeg_ops, next);
1013 mpeg_ops_attach(mops, dev);
1014 }
1015 list_add_tail(&dev->devlist,&saa7134_devlist);
1016 up(&devlist_lock);
1017
1018 /* check for signal */
1019 saa7134_irq_video_intl(dev);
Ricardo Cerqueirac817e762005-11-13 16:07:47 -08001020
Ricardo Cerqueiraf5b974c2005-12-01 00:51:20 -08001021 if (dmasound_init && !dev->dmasound.priv_data) {
1022 dmasound_init(dev);
1023 }
1024
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 return 0;
1026
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 fail4:
1028 saa7134_unregister_video(dev);
1029 saa7134_i2c_unregister(dev);
1030 free_irq(pci_dev->irq, dev);
1031 fail3:
1032 saa7134_hwfini(dev);
1033 iounmap(dev->lmmio);
1034 fail2:
1035 release_mem_region(pci_resource_start(pci_dev,0),
1036 pci_resource_len(pci_dev,0));
1037 fail1:
1038 kfree(dev);
1039 return err;
1040}
1041
1042static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1043{
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -08001044 struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 struct list_head *item;
1046 struct saa7134_mpeg_ops *mops;
1047
Ricardo Cerqueiraf5b974c2005-12-01 00:51:20 -08001048 /* Release DMA sound modules if present */
1049 if (dmasound_exit && dev->dmasound.priv_data) {
1050 dmasound_exit(dev);
1051 }
1052
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 /* debugging ... */
1054 if (irq_debug) {
1055 u32 report = saa_readl(SAA7134_IRQ_REPORT);
1056 u32 status = saa_readl(SAA7134_IRQ_STATUS);
1057 print_irqstatus(dev,42,report,status);
1058 }
1059
1060 /* disable peripheral devices */
1061 saa_writeb(SAA7134_SPECIAL_MODE,0);
1062
1063 /* shutdown hardware */
1064 saa_writel(SAA7134_IRQ1,0);
1065 saa_writel(SAA7134_IRQ2,0);
1066 saa_writel(SAA7134_MAIN_CTRL,0);
1067
1068 /* shutdown subsystems */
1069 saa7134_hwfini(dev);
1070
1071 /* unregister */
1072 down(&devlist_lock);
1073 list_del(&dev->devlist);
1074 list_for_each(item,&mops_list) {
1075 mops = list_entry(item, struct saa7134_mpeg_ops, next);
1076 mpeg_ops_detach(mops, dev);
1077 }
1078 up(&devlist_lock);
1079 saa7134_devcount--;
1080
1081 saa7134_i2c_unregister(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 saa7134_unregister_video(dev);
1083
Ricardo Cerqueiraf5b974c2005-12-01 00:51:20 -08001084
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -08001085 /* the DMA sound modules should be unloaded before reaching
1086 this, but just in case they are still present... */
1087 if (dev->dmasound.priv_data != NULL) {
1088 free_irq(pci_dev->irq, &dev->dmasound);
1089 dev->dmasound.priv_data = NULL;
1090 }
1091
Ricardo Cerqueiraf5b974c2005-12-01 00:51:20 -08001092
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -08001093 /* release resources */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 free_irq(pci_dev->irq, dev);
1095 iounmap(dev->lmmio);
1096 release_mem_region(pci_resource_start(pci_dev,0),
1097 pci_resource_len(pci_dev,0));
1098
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 pci_set_drvdata(pci_dev, NULL);
1100
1101 /* free memory */
1102 kfree(dev);
1103}
1104
1105/* ----------------------------------------------------------- */
1106
1107int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
1108{
1109 struct list_head *item;
1110 struct saa7134_dev *dev;
1111
1112 down(&devlist_lock);
1113 list_for_each(item,&saa7134_devlist) {
1114 dev = list_entry(item, struct saa7134_dev, devlist);
1115 mpeg_ops_attach(ops, dev);
1116 }
1117 list_add_tail(&ops->next,&mops_list);
1118 up(&devlist_lock);
1119 return 0;
1120}
1121
1122void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops)
1123{
1124 struct list_head *item;
1125 struct saa7134_dev *dev;
1126
1127 down(&devlist_lock);
1128 list_del(&ops->next);
1129 list_for_each(item,&saa7134_devlist) {
1130 dev = list_entry(item, struct saa7134_dev, devlist);
1131 mpeg_ops_detach(ops, dev);
1132 }
1133 up(&devlist_lock);
1134}
1135
1136EXPORT_SYMBOL(saa7134_ts_register);
1137EXPORT_SYMBOL(saa7134_ts_unregister);
1138
1139/* ----------------------------------------------------------- */
1140
1141static struct pci_driver saa7134_pci_driver = {
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -08001142 .name = "saa7134",
1143 .id_table = saa7134_pci_tbl,
1144 .probe = saa7134_initdev,
1145 .remove = __devexit_p(saa7134_finidev),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146};
1147
1148static int saa7134_init(void)
1149{
1150 INIT_LIST_HEAD(&saa7134_devlist);
1151 printk(KERN_INFO "saa7130/34: v4l2 driver version %d.%d.%d loaded\n",
1152 (SAA7134_VERSION_CODE >> 16) & 0xff,
1153 (SAA7134_VERSION_CODE >> 8) & 0xff,
1154 SAA7134_VERSION_CODE & 0xff);
1155#ifdef SNAPSHOT
1156 printk(KERN_INFO "saa7130/34: snapshot date %04d-%02d-%02d\n",
1157 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1158#endif
Otavio Salvador23047592006-01-09 15:25:17 -02001159 return pci_register_driver(&saa7134_pci_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160}
1161
1162static void saa7134_fini(void)
1163{
Reimar Doeffingerfd1eab72005-12-01 00:51:39 -08001164#if defined(CONFIG_MODULES) && defined(MODULE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 if (pending_registered)
1166 unregister_module_notifier(&pending_notifier);
Reimar Doeffingerfd1eab72005-12-01 00:51:39 -08001167#endif /* CONFIG_MODULES */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 pci_unregister_driver(&saa7134_pci_driver);
1169}
1170
1171module_init(saa7134_init);
1172module_exit(saa7134_fini);
1173
1174/* ----------------------------------------------------------- */
1175
1176EXPORT_SYMBOL(saa7134_print_ioctl);
1177EXPORT_SYMBOL(saa7134_i2c_call_clients);
1178EXPORT_SYMBOL(saa7134_devlist);
1179EXPORT_SYMBOL(saa7134_boards);
1180
Ricardo Cerqueira4aabf632005-11-13 16:08:00 -08001181/* ----------------- for the DMA sound modules --------------- */
Ricardo Cerqueira79dd0c692005-11-08 21:38:53 -08001182
Ricardo Cerqueiraf5b974c2005-12-01 00:51:20 -08001183EXPORT_SYMBOL(dmasound_init);
1184EXPORT_SYMBOL(dmasound_exit);
Ricardo Cerqueira79dd0c692005-11-08 21:38:53 -08001185EXPORT_SYMBOL(saa7134_pgtable_free);
1186EXPORT_SYMBOL(saa7134_pgtable_build);
1187EXPORT_SYMBOL(saa7134_pgtable_alloc);
1188EXPORT_SYMBOL(saa7134_set_dmabits);
1189
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190/* ----------------------------------------------------------- */
1191/*
1192 * Local variables:
1193 * c-basic-offset: 8
1194 * End:
1195 */