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