V4L/DVB (5298): Added support for deferred module requesting to cx88
[safe/jmp/linux-2.6] / drivers / media / video / cx88 / cx88-mpeg.c
1 /*
2  *
3  *  Support for the mpeg transport stream transfers
4  *  PCI function #2 of the cx2388x.
5  *
6  *    (c) 2004 Jelle Foks <jelle@foks.8m.com>
7  *    (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
8  *    (c) 2004 Gerd Knorr <kraxel@bytesex.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/module.h>
26 #include <linux/moduleparam.h>
27 #include <linux/init.h>
28 #include <linux/device.h>
29 #include <linux/interrupt.h>
30 #include <asm/delay.h>
31
32 #include "cx88.h"
33
34 /* ------------------------------------------------------------------ */
35
36 MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards");
37 MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
38 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
39 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
40 MODULE_LICENSE("GPL");
41
42 static unsigned int debug = 0;
43 module_param(debug,int,0644);
44 MODULE_PARM_DESC(debug,"enable debug messages [mpeg]");
45
46 #define dprintk(level,fmt, arg...)      if (debug >= level) \
47         printk(KERN_DEBUG "%s/2-mpeg: " fmt, dev->core->name, ## arg)
48
49 #define mpeg_dbg(level,fmt, arg...)     if (debug >= level) \
50         printk(KERN_DEBUG "%s/2-mpeg: " fmt, core->name, ## arg)
51
52 #if defined(CONFIG_MODULES) && defined(MODULE)
53 static void request_module_async(struct work_struct *work)
54 {
55         struct cx8802_dev *dev=container_of(work, struct cx8802_dev, request_module_wk);
56         switch (cx88_boards[dev->core->board].mpeg) {
57         case CX88_MPEG_BLACKBIRD:
58                 request_module("cx88-blackbird");
59                 break;
60         case CX88_MPEG_DVB:
61                 request_module("cx88-dvb");
62                 break;
63         case CX88_BOARD_NONE:
64                 /* reaching this one isn't possible */
65                 break;
66         default:
67                 printk("cx88-mpeg.c: WARNING extension [%d] is not supposed to be supported\n",cx88_boards[dev->core->board].mpeg);
68         }
69 }
70
71 static void request_modules(struct cx8802_dev *dev)
72 {
73         INIT_WORK(&dev->request_module_wk, request_module_async);
74         schedule_work(&dev->request_module_wk);
75 }
76 #else
77 #define request_modules(dev)
78 #endif /* CONFIG_MODULES */
79
80
81 static LIST_HEAD(cx8802_devlist);
82 /* ------------------------------------------------------------------ */
83
84 static int cx8802_start_dma(struct cx8802_dev    *dev,
85                             struct cx88_dmaqueue *q,
86                             struct cx88_buffer   *buf)
87 {
88         struct cx88_core *core = dev->core;
89
90         dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
91
92         /* setup fifo + format */
93         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
94                                 dev->ts_packet_size, buf->risc.dma);
95
96         /* write TS length to chip */
97         cx_write(MO_TS_LNGTH, buf->vb.width);
98
99         /* FIXME: this needs a review.
100          * also: move to cx88-blackbird + cx88-dvb source files? */
101
102         dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id);
103
104         if ( (core->active_type_id == CX88_MPEG_DVB) &&
105                 (cx88_boards[core->board].mpeg & CX88_MPEG_DVB) ) {
106
107                 dprintk( 1, "cx8802_start_dma doing .dvb\n");
108                 /* negedge driven & software reset */
109                 cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl);
110                 udelay(100);
111                 cx_write(MO_PINMUX_IO, 0x00);
112                 cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01);
113                 switch (core->board) {
114                 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
115                 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
116                 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
117                 case CX88_BOARD_PCHDTV_HD5500:
118                         cx_write(TS_SOP_STAT, 1<<13);
119                         break;
120                 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
121                 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
122                         cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
123                         udelay(100);
124                         break;
125                 case CX88_BOARD_HAUPPAUGE_HVR1300:
126                         break;
127                 default:
128                         cx_write(TS_SOP_STAT, 0x00);
129                         break;
130                 }
131                 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
132                 udelay(100);
133         } else if ( (core->active_type_id == CX88_MPEG_BLACKBIRD) &&
134                 (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) ) {
135                 dprintk( 1, "cx8802_start_dma doing .blackbird\n");
136                 cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
137
138                 cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */
139                 udelay(100);
140
141                 cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */
142                 cx_write(TS_VALERR_CNTRL, 0x2000);
143
144                 cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
145                 udelay(100);
146         } else {
147                 printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __FUNCTION__,
148                         cx88_boards[core->board].mpeg );
149                 return -EINVAL;
150         }
151
152         /* reset counter */
153         cx_write(MO_TS_GPCNTRL, GP_COUNT_CONTROL_RESET);
154         q->count = 1;
155
156         /* enable irqs */
157         dprintk( 1, "setting the interrupt mask\n" );
158         cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
159         cx_set(MO_TS_INTMSK,  0x1f0011);
160
161         /* start dma */
162         cx_set(MO_DEV_CNTRL2, (1<<5));
163         cx_set(MO_TS_DMACNTRL, 0x11);
164         return 0;
165 }
166
167 static int cx8802_stop_dma(struct cx8802_dev *dev)
168 {
169         struct cx88_core *core = dev->core;
170         dprintk( 1, "cx8802_stop_dma\n" );
171
172         /* stop dma */
173         cx_clear(MO_TS_DMACNTRL, 0x11);
174
175         /* disable irqs */
176         cx_clear(MO_PCI_INTMSK, 0x000004);
177         cx_clear(MO_TS_INTMSK, 0x1f0011);
178
179         /* Reset the controller */
180         cx_write(TS_GEN_CNTRL, 0xcd);
181         return 0;
182 }
183
184 static int cx8802_restart_queue(struct cx8802_dev    *dev,
185                                 struct cx88_dmaqueue *q)
186 {
187         struct cx88_buffer *buf;
188         struct list_head *item;
189
190        dprintk( 1, "cx8802_restart_queue\n" );
191         if (list_empty(&q->active))
192         {
193                struct cx88_buffer *prev;
194                prev = NULL;
195
196                dprintk(1, "cx8802_restart_queue: queue is empty\n" );
197
198                for (;;) {
199                        if (list_empty(&q->queued))
200                                return 0;
201                        buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
202                        if (NULL == prev) {
203                                list_del(&buf->vb.queue);
204                                list_add_tail(&buf->vb.queue,&q->active);
205                                cx8802_start_dma(dev, q, buf);
206                                buf->vb.state = STATE_ACTIVE;
207                                buf->count    = q->count++;
208                                mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
209                                dprintk(1,"[%p/%d] restart_queue - first active\n",
210                                        buf,buf->vb.i);
211
212                        } else if (prev->vb.width  == buf->vb.width  &&
213                                   prev->vb.height == buf->vb.height &&
214                                   prev->fmt       == buf->fmt) {
215                                list_del(&buf->vb.queue);
216                                list_add_tail(&buf->vb.queue,&q->active);
217                                buf->vb.state = STATE_ACTIVE;
218                                buf->count    = q->count++;
219                                prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
220                                dprintk(1,"[%p/%d] restart_queue - move to active\n",
221                                        buf,buf->vb.i);
222                        } else {
223                                return 0;
224                        }
225                        prev = buf;
226                }
227                 return 0;
228         }
229
230         buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
231         dprintk(2,"restart_queue [%p/%d]: restart dma\n",
232                 buf, buf->vb.i);
233         cx8802_start_dma(dev, q, buf);
234         list_for_each(item,&q->active) {
235                 buf = list_entry(item, struct cx88_buffer, vb.queue);
236                 buf->count = q->count++;
237         }
238         mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
239         return 0;
240 }
241
242 /* ------------------------------------------------------------------ */
243
244 int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
245                         struct cx88_buffer *buf, enum v4l2_field field)
246 {
247         int size = dev->ts_packet_size * dev->ts_packet_count;
248         int rc;
249
250         dprintk(1, "%s: %p\n", __FUNCTION__, buf);
251         if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
252                 return -EINVAL;
253
254         if (STATE_NEEDS_INIT == buf->vb.state) {
255                 buf->vb.width  = dev->ts_packet_size;
256                 buf->vb.height = dev->ts_packet_count;
257                 buf->vb.size   = size;
258                 buf->vb.field  = field /*V4L2_FIELD_TOP*/;
259
260                 if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
261                         goto fail;
262                 cx88_risc_databuffer(dev->pci, &buf->risc,
263                                      buf->vb.dma.sglist,
264                                      buf->vb.width, buf->vb.height);
265         }
266         buf->vb.state = STATE_PREPARED;
267         return 0;
268
269  fail:
270         cx88_free_buffer(q,buf);
271         return rc;
272 }
273
274 void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
275 {
276         struct cx88_buffer    *prev;
277         struct cx88_dmaqueue  *cx88q = &dev->mpegq;
278
279         dprintk( 1, "cx8802_buf_queue\n" );
280         /* add jump to stopper */
281         buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
282         buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
283
284         if (list_empty(&cx88q->active)) {
285                 dprintk( 1, "queue is empty - first active\n" );
286                 list_add_tail(&buf->vb.queue,&cx88q->active);
287                 cx8802_start_dma(dev, cx88q, buf);
288                 buf->vb.state = STATE_ACTIVE;
289                 buf->count    = cx88q->count++;
290                 mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
291                 dprintk(1,"[%p/%d] %s - first active\n",
292                         buf, buf->vb.i, __FUNCTION__);
293
294         } else {
295                 dprintk( 1, "queue is not empty - append to active\n" );
296                 prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue);
297                 list_add_tail(&buf->vb.queue,&cx88q->active);
298                 buf->vb.state = STATE_ACTIVE;
299                 buf->count    = cx88q->count++;
300                 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
301                 dprintk( 1, "[%p/%d] %s - append to active\n",
302                         buf, buf->vb.i, __FUNCTION__);
303         }
304 }
305
306 /* ----------------------------------------------------------- */
307
308 static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart)
309 {
310         struct cx88_dmaqueue *q = &dev->mpegq;
311         struct cx88_buffer *buf;
312         unsigned long flags;
313
314         spin_lock_irqsave(&dev->slock,flags);
315         while (!list_empty(&q->active)) {
316                 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
317                 list_del(&buf->vb.queue);
318                 buf->vb.state = STATE_ERROR;
319                 wake_up(&buf->vb.done);
320                 dprintk(1,"[%p/%d] %s - dma=0x%08lx\n",
321                         buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
322         }
323         if (restart)
324         {
325                 dprintk(1, "restarting queue\n" );
326                 cx8802_restart_queue(dev,q);
327         }
328         spin_unlock_irqrestore(&dev->slock,flags);
329 }
330
331 void cx8802_cancel_buffers(struct cx8802_dev *dev)
332 {
333         struct cx88_dmaqueue *q = &dev->mpegq;
334
335         dprintk( 1, "cx8802_cancel_buffers" );
336         del_timer_sync(&q->timeout);
337         cx8802_stop_dma(dev);
338         do_cancel_buffers(dev,"cancel",0);
339 }
340
341 static void cx8802_timeout(unsigned long data)
342 {
343         struct cx8802_dev *dev = (struct cx8802_dev*)data;
344
345         dprintk(0, "%s\n",__FUNCTION__);
346
347         if (debug)
348                 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
349         cx8802_stop_dma(dev);
350         do_cancel_buffers(dev,"timeout",1);
351 }
352
353 static char *cx88_mpeg_irqs[32] = {
354         "ts_risci1", NULL, NULL, NULL,
355         "ts_risci2", NULL, NULL, NULL,
356         "ts_oflow",  NULL, NULL, NULL,
357         "ts_sync",   NULL, NULL, NULL,
358         "opc_err", "par_err", "rip_err", "pci_abort",
359         "ts_err?",
360 };
361
362 static void cx8802_mpeg_irq(struct cx8802_dev *dev)
363 {
364         struct cx88_core *core = dev->core;
365         u32 status, mask, count;
366
367         dprintk( 1, "cx8802_mpeg_irq\n" );
368         status = cx_read(MO_TS_INTSTAT);
369         mask   = cx_read(MO_TS_INTMSK);
370         if (0 == (status & mask))
371                 return;
372
373         cx_write(MO_TS_INTSTAT, status);
374
375         if (debug || (status & mask & ~0xff))
376                 cx88_print_irqbits(core->name, "irq mpeg ",
377                                    cx88_mpeg_irqs, status, mask);
378
379         /* risc op code error */
380         if (status & (1 << 16)) {
381                 printk(KERN_WARNING "%s: mpeg risc op code error\n",core->name);
382                 cx_clear(MO_TS_DMACNTRL, 0x11);
383                 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
384         }
385
386         /* risc1 y */
387         if (status & 0x01) {
388                 dprintk( 1, "wake up\n" );
389                 spin_lock(&dev->slock);
390                 count = cx_read(MO_TS_GPCNT);
391                 cx88_wakeup(dev->core, &dev->mpegq, count);
392                 spin_unlock(&dev->slock);
393         }
394
395         /* risc2 y */
396         if (status & 0x10) {
397                 spin_lock(&dev->slock);
398                 cx8802_restart_queue(dev,&dev->mpegq);
399                 spin_unlock(&dev->slock);
400         }
401
402         /* other general errors */
403         if (status & 0x1f0100) {
404                 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
405                 spin_lock(&dev->slock);
406                 cx8802_stop_dma(dev);
407                 cx8802_restart_queue(dev,&dev->mpegq);
408                 spin_unlock(&dev->slock);
409         }
410 }
411
412 #define MAX_IRQ_LOOP 10
413
414 static irqreturn_t cx8802_irq(int irq, void *dev_id)
415 {
416         struct cx8802_dev *dev = dev_id;
417         struct cx88_core *core = dev->core;
418         u32 status;
419         int loop, handled = 0;
420
421         for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
422                 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);
423                 if (0 == status)
424                         goto out;
425                 dprintk( 1, "cx8802_irq\n" );
426                 dprintk( 1, "    loop: %d/%d\n", loop, MAX_IRQ_LOOP );
427                 dprintk( 1, "    status: %d\n", status );
428                 handled = 1;
429                 cx_write(MO_PCI_INTSTAT, status);
430
431                 if (status & core->pci_irqmask)
432                         cx88_core_irq(core,status);
433                 if (status & 0x04)
434                         cx8802_mpeg_irq(dev);
435         };
436         if (MAX_IRQ_LOOP == loop) {
437                 dprintk( 0, "clearing mask\n" );
438                 printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
439                        core->name);
440                 cx_write(MO_PCI_INTMSK,0);
441         }
442
443  out:
444         return IRQ_RETVAL(handled);
445 }
446
447 /* ----------------------------------------------------------- */
448 /* exported stuff                                              */
449
450 int cx8802_init_common(struct cx8802_dev *dev)
451 {
452         struct cx88_core *core = dev->core;
453         int err;
454
455         /* pci init */
456         if (pci_enable_device(dev->pci))
457                 return -EIO;
458         pci_set_master(dev->pci);
459         if (!pci_dma_supported(dev->pci,0xffffffff)) {
460                 printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
461                 return -EIO;
462         }
463
464         pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev);
465         pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER,  &dev->pci_lat);
466         printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
467                "latency: %d, mmio: 0x%llx\n", dev->core->name,
468                pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
469                dev->pci_lat,(unsigned long long)pci_resource_start(dev->pci,0));
470
471         /* initialize driver struct */
472         spin_lock_init(&dev->slock);
473
474         /* init dma queue */
475         INIT_LIST_HEAD(&dev->mpegq.active);
476         INIT_LIST_HEAD(&dev->mpegq.queued);
477         dev->mpegq.timeout.function = cx8802_timeout;
478         dev->mpegq.timeout.data     = (unsigned long)dev;
479         init_timer(&dev->mpegq.timeout);
480         cx88_risc_stopper(dev->pci,&dev->mpegq.stopper,
481                           MO_TS_DMACNTRL,0x11,0x00);
482
483         /* get irq */
484         err = request_irq(dev->pci->irq, cx8802_irq,
485                           IRQF_SHARED | IRQF_DISABLED, dev->core->name, dev);
486         if (err < 0) {
487                 printk(KERN_ERR "%s: can't get IRQ %d\n",
488                        dev->core->name, dev->pci->irq);
489                 return err;
490         }
491         cx_set(MO_PCI_INTMSK, core->pci_irqmask);
492
493         /* everything worked */
494         pci_set_drvdata(dev->pci,dev);
495         return 0;
496 }
497
498 void cx8802_fini_common(struct cx8802_dev *dev)
499 {
500         dprintk( 2, "cx8802_fini_common\n" );
501         cx8802_stop_dma(dev);
502         pci_disable_device(dev->pci);
503
504         /* unregister stuff */
505         free_irq(dev->pci->irq, dev);
506         pci_set_drvdata(dev->pci, NULL);
507
508         /* free memory */
509         btcx_riscmem_free(dev->pci,&dev->mpegq.stopper);
510 }
511
512 /* ----------------------------------------------------------- */
513
514 int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
515 {
516         struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
517         struct cx88_core *core = dev->core;
518
519         /* stop mpeg dma */
520         spin_lock(&dev->slock);
521         if (!list_empty(&dev->mpegq.active)) {
522                 dprintk( 2, "suspend\n" );
523                 printk("%s: suspend mpeg\n", core->name);
524                 cx8802_stop_dma(dev);
525                 del_timer(&dev->mpegq.timeout);
526         }
527         spin_unlock(&dev->slock);
528
529         /* FIXME -- shutdown device */
530         cx88_shutdown(dev->core);
531
532         pci_save_state(pci_dev);
533         if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
534                 pci_disable_device(pci_dev);
535                 dev->state.disabled = 1;
536         }
537         return 0;
538 }
539
540 int cx8802_resume_common(struct pci_dev *pci_dev)
541 {
542         struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
543         struct cx88_core *core = dev->core;
544         int err;
545
546         if (dev->state.disabled) {
547                 err=pci_enable_device(pci_dev);
548                 if (err) {
549                         printk(KERN_ERR "%s: can't enable device\n",
550                                                dev->core->name);
551                         return err;
552                 }
553                 dev->state.disabled = 0;
554         }
555         err=pci_set_power_state(pci_dev, PCI_D0);
556         if (err) {
557                 printk(KERN_ERR "%s: can't enable device\n",
558                                                dev->core->name);
559                 pci_disable_device(pci_dev);
560                 dev->state.disabled = 1;
561
562                 return err;
563         }
564         pci_restore_state(pci_dev);
565
566         /* FIXME: re-initialize hardware */
567         cx88_reset(dev->core);
568
569         /* restart video+vbi capture */
570         spin_lock(&dev->slock);
571         if (!list_empty(&dev->mpegq.active)) {
572                 printk("%s: resume mpeg\n", core->name);
573                 cx8802_restart_queue(dev,&dev->mpegq);
574         }
575         spin_unlock(&dev->slock);
576
577         return 0;
578 }
579
580 struct cx8802_dev * cx8802_get_device(struct inode *inode)
581 {
582         int minor = iminor(inode);
583         struct cx8802_dev *h = NULL;
584         struct list_head *list;
585
586         list_for_each(list,&cx8802_devlist) {
587                 h = list_entry(list, struct cx8802_dev, devlist);
588                 if (h->mpeg_dev->minor == minor)
589                         return h;
590         }
591
592         return NULL;
593 }
594
595 struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype)
596 {
597         struct cx8802_dev *h = NULL;
598         struct cx8802_driver *d = NULL;
599         struct list_head *list;
600         struct list_head *list2;
601
602         list_for_each(list,&cx8802_devlist) {
603                 h = list_entry(list, struct cx8802_dev, devlist);
604                 if (h != dev)
605                         continue;
606
607                 list_for_each(list2, &h->drvlist.devlist) {
608                         d = list_entry(list2, struct cx8802_driver, devlist);
609
610                         /* only unregister the correct driver type */
611                         if (d->type_id == btype) {
612                                 return d;
613                         }
614                 }
615         }
616
617         return NULL;
618 }
619
620 /* Driver asked for hardware access. */
621 int cx8802_request_acquire(struct cx8802_driver *drv)
622 {
623         struct cx88_core *core = drv->core;
624
625         /* Fail a request for hardware if the device is busy. */
626         if (core->active_type_id != CX88_BOARD_NONE)
627                 return -EBUSY;
628
629         if (drv->advise_acquire)
630         {
631                 core->active_type_id = drv->type_id;
632                 drv->advise_acquire(drv);
633
634                 mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
635         }
636
637         return 0;
638 }
639
640 /* Driver asked to release hardware. */
641 int cx8802_request_release(struct cx8802_driver *drv)
642 {
643         struct cx88_core *core = drv->core;
644
645         if (drv->advise_release)
646         {
647                 drv->advise_release(drv);
648                 core->active_type_id = CX88_BOARD_NONE;
649                 mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
650         }
651
652         return 0;
653 }
654
655 static int cx8802_check_driver(struct cx8802_driver *drv)
656 {
657         if (drv == NULL)
658                 return -ENODEV;
659
660         if ((drv->type_id != CX88_MPEG_DVB) &&
661                 (drv->type_id != CX88_MPEG_BLACKBIRD))
662                 return -EINVAL;
663
664         if ((drv->hw_access != CX8802_DRVCTL_SHARED) &&
665                 (drv->hw_access != CX8802_DRVCTL_EXCLUSIVE))
666                 return -EINVAL;
667
668         if ((drv->probe == NULL) ||
669                 (drv->remove == NULL) ||
670                 (drv->advise_acquire == NULL) ||
671                 (drv->advise_release == NULL))
672                 return -EINVAL;
673
674         return 0;
675 }
676
677 int cx8802_register_driver(struct cx8802_driver *drv)
678 {
679         struct cx8802_dev *h;
680         struct cx8802_driver *driver;
681         struct list_head *list;
682         int err = 0, i = 0;
683
684         printk(KERN_INFO "%s() ->registering driver type=%s access=%s\n", __FUNCTION__ ,
685                 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
686                 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
687
688         if ((err = cx8802_check_driver(drv)) != 0) {
689                 printk(KERN_INFO "%s() cx8802_driver is invalid\n", __FUNCTION__ );
690                 return err;
691         }
692
693         list_for_each(list,&cx8802_devlist) {
694                 h = list_entry(list, struct cx8802_dev, devlist);
695
696                 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n",
697                         h->core->name,h->pci->subsystem_vendor,
698                         h->pci->subsystem_device,cx88_boards[h->core->board].name,
699                         h->core->board);
700
701                 /* Bring up a new struct for each driver instance */
702                 driver = kzalloc(sizeof(*drv),GFP_KERNEL);
703                 if (driver == NULL)
704                         return -ENOMEM;
705
706                 /* Snapshot of the driver registration data */
707                 drv->core = h->core;
708                 drv->suspend = cx8802_suspend_common;
709                 drv->resume = cx8802_resume_common;
710                 drv->request_acquire = cx8802_request_acquire;
711                 drv->request_release = cx8802_request_release;
712                 memcpy(driver, drv, sizeof(*driver));
713
714                 err = drv->probe(driver);
715                 if (err == 0) {
716                         i++;
717                         mutex_lock(&drv->core->lock);
718                         list_add_tail(&driver->devlist,&h->drvlist.devlist);
719                         mutex_unlock(&drv->core->lock);
720                 } else {
721                         printk(KERN_ERR "%s() ->probe failed err = %d\n", __FUNCTION__, err);
722                 }
723
724         }
725         if (i == 0)
726                 err = -ENODEV;
727         else
728                 err = 0;
729
730         return err;
731 }
732
733 int cx8802_unregister_driver(struct cx8802_driver *drv)
734 {
735         struct cx8802_dev *h;
736         struct cx8802_driver *d;
737         struct list_head *list;
738         struct list_head *list2, *q;
739         int err = 0, i = 0;
740
741         printk(KERN_INFO "%s() ->unregistering driver type=%s\n", __FUNCTION__ ,
742                 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird");
743
744         list_for_each(list,&cx8802_devlist) {
745                 i++;
746                 h = list_entry(list, struct cx8802_dev, devlist);
747
748                 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n",
749                         h->core->name,h->pci->subsystem_vendor,
750                         h->pci->subsystem_device,cx88_boards[h->core->board].name,
751                         h->core->board);
752
753                 list_for_each_safe(list2, q, &h->drvlist.devlist) {
754                         d = list_entry(list2, struct cx8802_driver, devlist);
755
756                         /* only unregister the correct driver type */
757                         if (d->type_id != drv->type_id)
758                                 continue;
759
760                         err = d->remove(d);
761                         if (err == 0) {
762                                 mutex_lock(&drv->core->lock);
763                                 list_del(list2);
764                                 mutex_unlock(&drv->core->lock);
765                         } else
766                                 printk(KERN_ERR "%s() ->remove failed err = %d\n", __FUNCTION__, err);
767
768                 }
769
770         }
771
772         return err;
773 }
774
775 /* ----------------------------------------------------------- */
776 static int __devinit cx8802_probe(struct pci_dev *pci_dev,
777                                const struct pci_device_id *pci_id)
778 {
779         struct cx8802_dev *dev;
780         struct cx88_core  *core;
781         int err;
782
783         /* general setup */
784         core = cx88_core_get(pci_dev);
785         if (NULL == core)
786                 return -EINVAL;
787
788         printk("%s/2: cx2388x 8802 Driver Manager\n", core->name);
789
790         err = -ENODEV;
791         if (!cx88_boards[core->board].mpeg)
792                 goto fail_core;
793
794         err = -ENOMEM;
795         dev = kzalloc(sizeof(*dev),GFP_KERNEL);
796         if (NULL == dev)
797                 goto fail_core;
798         dev->pci = pci_dev;
799         dev->core = core;
800
801         err = cx8802_init_common(dev);
802         if (err != 0)
803                 goto fail_free;
804
805         INIT_LIST_HEAD(&dev->drvlist.devlist);
806         list_add_tail(&dev->devlist,&cx8802_devlist);
807
808         /* Maintain a reference so cx88-video can query the 8802 device. */
809         core->dvbdev = dev;
810
811         /* now autoload cx88-dvb or cx88-blackbird */
812         request_modules(dev);
813         return 0;
814
815  fail_free:
816         kfree(dev);
817  fail_core:
818         cx88_core_put(core,pci_dev);
819         return err;
820 }
821
822 static void __devexit cx8802_remove(struct pci_dev *pci_dev)
823 {
824         struct cx8802_dev *dev;
825         struct cx8802_driver *h;
826         struct list_head *list;
827
828         dev = pci_get_drvdata(pci_dev);
829
830         dprintk( 1, "%s\n", __FUNCTION__);
831
832         list_for_each(list,&dev->drvlist.devlist) {
833                 h = list_entry(list, struct cx8802_driver, devlist);
834                 dprintk( 1, " ->driver\n");
835                 if (h->remove == NULL) {
836                         printk(KERN_ERR "%s .. skipping driver, no probe function\n", __FUNCTION__);
837                         continue;
838                 }
839                 printk(KERN_INFO "%s .. Removing driver type %d\n", __FUNCTION__, h->type_id);
840                 cx8802_unregister_driver(h);
841                 list_del(&dev->drvlist.devlist);
842         }
843
844         /* Destroy any 8802 reference. */
845         dev->core->dvbdev = NULL;
846
847         /* common */
848         cx8802_fini_common(dev);
849         cx88_core_put(dev->core,dev->pci);
850         kfree(dev);
851 }
852
853 static struct pci_device_id cx8802_pci_tbl[] = {
854         {
855                 .vendor       = 0x14f1,
856                 .device       = 0x8802,
857                 .subvendor    = PCI_ANY_ID,
858                 .subdevice    = PCI_ANY_ID,
859         },{
860                 /* --- end of list --- */
861         }
862 };
863 MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
864
865 static struct pci_driver cx8802_pci_driver = {
866         .name     = "cx88-mpeg driver manager",
867         .id_table = cx8802_pci_tbl,
868         .probe    = cx8802_probe,
869         .remove   = __devexit_p(cx8802_remove),
870 };
871
872 static int cx8802_init(void)
873 {
874         printk(KERN_INFO "cx2388x cx88-mpeg Driver Manager version %d.%d.%d loaded\n",
875                (CX88_VERSION_CODE >> 16) & 0xff,
876                (CX88_VERSION_CODE >>  8) & 0xff,
877                CX88_VERSION_CODE & 0xff);
878 #ifdef SNAPSHOT
879         printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
880                SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
881 #endif
882         return pci_register_driver(&cx8802_pci_driver);
883 }
884
885 static void cx8802_fini(void)
886 {
887         pci_unregister_driver(&cx8802_pci_driver);
888 }
889
890 module_init(cx8802_init);
891 module_exit(cx8802_fini);
892 EXPORT_SYMBOL(cx8802_buf_prepare);
893 EXPORT_SYMBOL(cx8802_buf_queue);
894 EXPORT_SYMBOL(cx8802_cancel_buffers);
895
896 EXPORT_SYMBOL(cx8802_init_common);
897 EXPORT_SYMBOL(cx8802_fini_common);
898
899 EXPORT_SYMBOL(cx8802_register_driver);
900 EXPORT_SYMBOL(cx8802_unregister_driver);
901 EXPORT_SYMBOL(cx8802_get_device);
902 EXPORT_SYMBOL(cx8802_get_driver);
903 /* ----------------------------------------------------------- */
904 /*
905  * Local variables:
906  * c-basic-offset: 8
907  * End:
908  * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
909  */