Merge branch 'HEAD' of master.kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-2.6] / drivers / media / video / cx88 / cx88-core.c
1 /*
2  *
3  * device driver for Conexant 2388x based TV cards
4  * driver core
5  *
6  * (c) 2003 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/init.h>
24 #include <linux/list.h>
25 #include <linux/module.h>
26 #include <linux/moduleparam.h>
27 #include <linux/kernel.h>
28 #include <linux/slab.h>
29 #include <linux/kmod.h>
30 #include <linux/sound.h>
31 #include <linux/interrupt.h>
32 #include <linux/pci.h>
33 #include <linux/delay.h>
34 #include <linux/videodev2.h>
35 #include <linux/mutex.h>
36
37 #include "cx88.h"
38 #include <media/v4l2-common.h>
39
40 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
41 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
42 MODULE_LICENSE("GPL");
43
44 /* ------------------------------------------------------------------ */
45
46 static unsigned int core_debug = 0;
47 module_param(core_debug,int,0644);
48 MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
49
50 static unsigned int latency = UNSET;
51 module_param(latency,int,0444);
52 MODULE_PARM_DESC(latency,"pci latency timer");
53
54 static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
55 static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
56 static unsigned int card[]  = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
57
58 module_param_array(tuner, int, NULL, 0444);
59 module_param_array(radio, int, NULL, 0444);
60 module_param_array(card,  int, NULL, 0444);
61
62 MODULE_PARM_DESC(tuner,"tuner type");
63 MODULE_PARM_DESC(radio,"radio tuner type");
64 MODULE_PARM_DESC(card,"card type");
65
66 static unsigned int nicam = 0;
67 module_param(nicam,int,0644);
68 MODULE_PARM_DESC(nicam,"tv audio is nicam");
69
70 static unsigned int nocomb = 0;
71 module_param(nocomb,int,0644);
72 MODULE_PARM_DESC(nocomb,"disable comb filter");
73
74 #define dprintk(level,fmt, arg...)      if (core_debug >= level)        \
75         printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
76
77 static unsigned int cx88_devcount;
78 static LIST_HEAD(cx88_devlist);
79 static DEFINE_MUTEX(devlist);
80
81 #define NO_SYNC_LINE (-1U)
82
83 static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
84                             unsigned int offset, u32 sync_line,
85                             unsigned int bpl, unsigned int padding,
86                             unsigned int lines)
87 {
88         struct scatterlist *sg;
89         unsigned int line,todo;
90
91         /* sync instruction */
92         if (sync_line != NO_SYNC_LINE)
93                 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
94
95         /* scan lines */
96         sg = sglist;
97         for (line = 0; line < lines; line++) {
98                 while (offset && offset >= sg_dma_len(sg)) {
99                         offset -= sg_dma_len(sg);
100                         sg++;
101                 }
102                 if (bpl <= sg_dma_len(sg)-offset) {
103                         /* fits into current chunk */
104                         *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
105                         *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
106                         offset+=bpl;
107                 } else {
108                         /* scanline needs to be split */
109                         todo = bpl;
110                         *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
111                                             (sg_dma_len(sg)-offset));
112                         *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
113                         todo -= (sg_dma_len(sg)-offset);
114                         offset = 0;
115                         sg++;
116                         while (todo > sg_dma_len(sg)) {
117                                 *(rp++)=cpu_to_le32(RISC_WRITE|
118                                                     sg_dma_len(sg));
119                                 *(rp++)=cpu_to_le32(sg_dma_address(sg));
120                                 todo -= sg_dma_len(sg);
121                                 sg++;
122                         }
123                         *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
124                         *(rp++)=cpu_to_le32(sg_dma_address(sg));
125                         offset += todo;
126                 }
127                 offset += padding;
128         }
129
130         return rp;
131 }
132
133 int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
134                      struct scatterlist *sglist,
135                      unsigned int top_offset, unsigned int bottom_offset,
136                      unsigned int bpl, unsigned int padding, unsigned int lines)
137 {
138         u32 instructions,fields;
139         u32 *rp;
140         int rc;
141
142         fields = 0;
143         if (UNSET != top_offset)
144                 fields++;
145         if (UNSET != bottom_offset)
146                 fields++;
147
148         /* estimate risc mem: worst case is one write per page border +
149            one write per scan line + syncs + jump (all 2 dwords).  Padding
150            can cause next bpl to start close to a page border.  First DMA
151            region may be smaller than PAGE_SIZE */
152         instructions  = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
153         instructions += 2;
154         if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
155                 return rc;
156
157         /* write risc instructions */
158         rp = risc->cpu;
159         if (UNSET != top_offset)
160                 rp = cx88_risc_field(rp, sglist, top_offset, 0,
161                                      bpl, padding, lines);
162         if (UNSET != bottom_offset)
163                 rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
164                                      bpl, padding, lines);
165
166         /* save pointer to jmp instruction address */
167         risc->jmp = rp;
168         BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
169         return 0;
170 }
171
172 int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
173                          struct scatterlist *sglist, unsigned int bpl,
174                          unsigned int lines)
175 {
176         u32 instructions;
177         u32 *rp;
178         int rc;
179
180         /* estimate risc mem: worst case is one write per page border +
181            one write per scan line + syncs + jump (all 2 dwords).  Here
182            there is no padding and no sync.  First DMA region may be smaller
183            than PAGE_SIZE */
184         instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
185         instructions += 1;
186         if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
187                 return rc;
188
189         /* write risc instructions */
190         rp = risc->cpu;
191         rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines);
192
193         /* save pointer to jmp instruction address */
194         risc->jmp = rp;
195         BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
196         return 0;
197 }
198
199 int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
200                       u32 reg, u32 mask, u32 value)
201 {
202         u32 *rp;
203         int rc;
204
205         if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
206                 return rc;
207
208         /* write risc instructions */
209         rp = risc->cpu;
210         *(rp++) = cpu_to_le32(RISC_WRITECR  | RISC_IRQ2 | RISC_IMM);
211         *(rp++) = cpu_to_le32(reg);
212         *(rp++) = cpu_to_le32(value);
213         *(rp++) = cpu_to_le32(mask);
214         *(rp++) = cpu_to_le32(RISC_JUMP);
215         *(rp++) = cpu_to_le32(risc->dma);
216         return 0;
217 }
218
219 void
220 cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
221 {
222         BUG_ON(in_interrupt());
223         videobuf_waiton(&buf->vb,0,0);
224         videobuf_dma_unmap(q, &buf->vb.dma);
225         videobuf_dma_free(&buf->vb.dma);
226         btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
227         buf->vb.state = STATE_NEEDS_INIT;
228 }
229
230 /* ------------------------------------------------------------------ */
231 /* our SRAM memory layout                                             */
232
233 /* we are going to put all thr risc programs into host memory, so we
234  * can use the whole SDRAM for the DMA fifos.  To simplify things, we
235  * use a static memory layout.  That surely will waste memory in case
236  * we don't use all DMA channels at the same time (which will be the
237  * case most of the time).  But that still gives us enougth FIFO space
238  * to be able to deal with insane long pci latencies ...
239  *
240  * FIFO space allocations:
241  *    channel  21    (y video)  - 10.0k
242  *    channel  22    (u video)  -  2.0k
243  *    channel  23    (v video)  -  2.0k
244  *    channel  24    (vbi)      -  4.0k
245  *    channels 25+26 (audio)    -  4.0k
246  *    channel  28    (mpeg)     -  4.0k
247  *    TOTAL                     = 29.0k
248  *
249  * Every channel has 160 bytes control data (64 bytes instruction
250  * queue and 6 CDT entries), which is close to 2k total.
251  *
252  * Address layout:
253  *    0x0000 - 0x03ff    CMDs / reserved
254  *    0x0400 - 0x0bff    instruction queues + CDs
255  *    0x0c00 -           FIFOs
256  */
257
258 struct sram_channel cx88_sram_channels[] = {
259         [SRAM_CH21] = {
260                 .name       = "video y / packed",
261                 .cmds_start = 0x180040,
262                 .ctrl_start = 0x180400,
263                 .cdt        = 0x180400 + 64,
264                 .fifo_start = 0x180c00,
265                 .fifo_size  = 0x002800,
266                 .ptr1_reg   = MO_DMA21_PTR1,
267                 .ptr2_reg   = MO_DMA21_PTR2,
268                 .cnt1_reg   = MO_DMA21_CNT1,
269                 .cnt2_reg   = MO_DMA21_CNT2,
270         },
271         [SRAM_CH22] = {
272                 .name       = "video u",
273                 .cmds_start = 0x180080,
274                 .ctrl_start = 0x1804a0,
275                 .cdt        = 0x1804a0 + 64,
276                 .fifo_start = 0x183400,
277                 .fifo_size  = 0x000800,
278                 .ptr1_reg   = MO_DMA22_PTR1,
279                 .ptr2_reg   = MO_DMA22_PTR2,
280                 .cnt1_reg   = MO_DMA22_CNT1,
281                 .cnt2_reg   = MO_DMA22_CNT2,
282         },
283         [SRAM_CH23] = {
284                 .name       = "video v",
285                 .cmds_start = 0x1800c0,
286                 .ctrl_start = 0x180540,
287                 .cdt        = 0x180540 + 64,
288                 .fifo_start = 0x183c00,
289                 .fifo_size  = 0x000800,
290                 .ptr1_reg   = MO_DMA23_PTR1,
291                 .ptr2_reg   = MO_DMA23_PTR2,
292                 .cnt1_reg   = MO_DMA23_CNT1,
293                 .cnt2_reg   = MO_DMA23_CNT2,
294         },
295         [SRAM_CH24] = {
296                 .name       = "vbi",
297                 .cmds_start = 0x180100,
298                 .ctrl_start = 0x1805e0,
299                 .cdt        = 0x1805e0 + 64,
300                 .fifo_start = 0x184400,
301                 .fifo_size  = 0x001000,
302                 .ptr1_reg   = MO_DMA24_PTR1,
303                 .ptr2_reg   = MO_DMA24_PTR2,
304                 .cnt1_reg   = MO_DMA24_CNT1,
305                 .cnt2_reg   = MO_DMA24_CNT2,
306         },
307         [SRAM_CH25] = {
308                 .name       = "audio from",
309                 .cmds_start = 0x180140,
310                 .ctrl_start = 0x180680,
311                 .cdt        = 0x180680 + 64,
312                 .fifo_start = 0x185400,
313                 .fifo_size  = 0x001000,
314                 .ptr1_reg   = MO_DMA25_PTR1,
315                 .ptr2_reg   = MO_DMA25_PTR2,
316                 .cnt1_reg   = MO_DMA25_CNT1,
317                 .cnt2_reg   = MO_DMA25_CNT2,
318         },
319         [SRAM_CH26] = {
320                 .name       = "audio to",
321                 .cmds_start = 0x180180,
322                 .ctrl_start = 0x180720,
323                 .cdt        = 0x180680 + 64,  /* same as audio IN */
324                 .fifo_start = 0x185400,       /* same as audio IN */
325                 .fifo_size  = 0x001000,       /* same as audio IN */
326                 .ptr1_reg   = MO_DMA26_PTR1,
327                 .ptr2_reg   = MO_DMA26_PTR2,
328                 .cnt1_reg   = MO_DMA26_CNT1,
329                 .cnt2_reg   = MO_DMA26_CNT2,
330         },
331         [SRAM_CH28] = {
332                 .name       = "mpeg",
333                 .cmds_start = 0x180200,
334                 .ctrl_start = 0x1807C0,
335                 .cdt        = 0x1807C0 + 64,
336                 .fifo_start = 0x186400,
337                 .fifo_size  = 0x001000,
338                 .ptr1_reg   = MO_DMA28_PTR1,
339                 .ptr2_reg   = MO_DMA28_PTR2,
340                 .cnt1_reg   = MO_DMA28_CNT1,
341                 .cnt2_reg   = MO_DMA28_CNT2,
342         },
343 };
344
345 int cx88_sram_channel_setup(struct cx88_core *core,
346                             struct sram_channel *ch,
347                             unsigned int bpl, u32 risc)
348 {
349         unsigned int i,lines;
350         u32 cdt;
351
352         bpl   = (bpl + 7) & ~7; /* alignment */
353         cdt   = ch->cdt;
354         lines = ch->fifo_size / bpl;
355         if (lines > 6)
356                 lines = 6;
357         BUG_ON(lines < 2);
358
359         /* write CDT */
360         for (i = 0; i < lines; i++)
361                 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
362
363         /* write CMDS */
364         cx_write(ch->cmds_start +  0, risc);
365         cx_write(ch->cmds_start +  4, cdt);
366         cx_write(ch->cmds_start +  8, (lines*16) >> 3);
367         cx_write(ch->cmds_start + 12, ch->ctrl_start);
368         cx_write(ch->cmds_start + 16, 64 >> 2);
369         for (i = 20; i < 64; i += 4)
370                 cx_write(ch->cmds_start + i, 0);
371
372         /* fill registers */
373         cx_write(ch->ptr1_reg, ch->fifo_start);
374         cx_write(ch->ptr2_reg, cdt);
375         cx_write(ch->cnt1_reg, (bpl >> 3) -1);
376         cx_write(ch->cnt2_reg, (lines*16) >> 3);
377
378         dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
379         return 0;
380 }
381
382 /* ------------------------------------------------------------------ */
383 /* debug helper code                                                  */
384
385 static int cx88_risc_decode(u32 risc)
386 {
387         static char *instr[16] = {
388                 [ RISC_SYNC    >> 28 ] = "sync",
389                 [ RISC_WRITE   >> 28 ] = "write",
390                 [ RISC_WRITEC  >> 28 ] = "writec",
391                 [ RISC_READ    >> 28 ] = "read",
392                 [ RISC_READC   >> 28 ] = "readc",
393                 [ RISC_JUMP    >> 28 ] = "jump",
394                 [ RISC_SKIP    >> 28 ] = "skip",
395                 [ RISC_WRITERM >> 28 ] = "writerm",
396                 [ RISC_WRITECM >> 28 ] = "writecm",
397                 [ RISC_WRITECR >> 28 ] = "writecr",
398         };
399         static int incr[16] = {
400                 [ RISC_WRITE   >> 28 ] = 2,
401                 [ RISC_JUMP    >> 28 ] = 2,
402                 [ RISC_WRITERM >> 28 ] = 3,
403                 [ RISC_WRITECM >> 28 ] = 3,
404                 [ RISC_WRITECR >> 28 ] = 4,
405         };
406         static char *bits[] = {
407                 "12",   "13",   "14",   "resync",
408                 "cnt0", "cnt1", "18",   "19",
409                 "20",   "21",   "22",   "23",
410                 "irq1", "irq2", "eol",  "sol",
411         };
412         int i;
413
414         printk("0x%08x [ %s", risc,
415                instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
416         for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
417                 if (risc & (1 << (i + 12)))
418                         printk(" %s",bits[i]);
419         printk(" count=%d ]\n", risc & 0xfff);
420         return incr[risc >> 28] ? incr[risc >> 28] : 1;
421 }
422
423
424 void cx88_sram_channel_dump(struct cx88_core *core,
425                             struct sram_channel *ch)
426 {
427         static char *name[] = {
428                 "initial risc",
429                 "cdt base",
430                 "cdt size",
431                 "iq base",
432                 "iq size",
433                 "risc pc",
434                 "iq wr ptr",
435                 "iq rd ptr",
436                 "cdt current",
437                 "pci target",
438                 "line / byte",
439         };
440         u32 risc;
441         unsigned int i,j,n;
442
443         printk("%s: %s - dma channel status dump\n",
444                core->name,ch->name);
445         for (i = 0; i < ARRAY_SIZE(name); i++)
446                 printk("%s:   cmds: %-12s: 0x%08x\n",
447                        core->name,name[i],
448                        cx_read(ch->cmds_start + 4*i));
449         for (i = 0; i < 4; i++) {
450                 risc = cx_read(ch->cmds_start + 4 * (i+11));
451                 printk("%s:   risc%d: ", core->name, i);
452                 cx88_risc_decode(risc);
453         }
454         for (i = 0; i < 16; i += n) {
455                 risc = cx_read(ch->ctrl_start + 4 * i);
456                 printk("%s:   iq %x: ", core->name, i);
457                 n = cx88_risc_decode(risc);
458                 for (j = 1; j < n; j++) {
459                         risc = cx_read(ch->ctrl_start + 4 * (i+j));
460                         printk("%s:   iq %x: 0x%08x [ arg #%d ]\n",
461                                core->name, i+j, risc, j);
462                 }
463         }
464
465         printk("%s: fifo: 0x%08x -> 0x%x\n",
466                core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
467         printk("%s: ctrl: 0x%08x -> 0x%x\n",
468                core->name, ch->ctrl_start, ch->ctrl_start+6*16);
469         printk("%s:   ptr1_reg: 0x%08x\n",
470                core->name,cx_read(ch->ptr1_reg));
471         printk("%s:   ptr2_reg: 0x%08x\n",
472                core->name,cx_read(ch->ptr2_reg));
473         printk("%s:   cnt1_reg: 0x%08x\n",
474                core->name,cx_read(ch->cnt1_reg));
475         printk("%s:   cnt2_reg: 0x%08x\n",
476                core->name,cx_read(ch->cnt2_reg));
477 }
478
479 static char *cx88_pci_irqs[32] = {
480         "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
481         "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
482         "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
483         "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
484 };
485
486 void cx88_print_irqbits(char *name, char *tag, char **strings,
487                         u32 bits, u32 mask)
488 {
489         unsigned int i;
490
491         printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
492         for (i = 0; i < 32; i++) {
493                 if (!(bits & (1 << i)))
494                         continue;
495                 if (strings[i])
496                         printk(" %s", strings[i]);
497                 else
498                         printk(" %d", i);
499                 if (!(mask & (1 << i)))
500                         continue;
501                 printk("*");
502         }
503         printk("\n");
504 }
505
506 /* ------------------------------------------------------------------ */
507
508 int cx88_core_irq(struct cx88_core *core, u32 status)
509 {
510         int handled = 0;
511
512         if (status & (1<<18)) {
513                 cx88_ir_irq(core);
514                 handled++;
515         }
516         if (!handled)
517                 cx88_print_irqbits(core->name, "irq pci",
518                                    cx88_pci_irqs, status,
519                                    core->pci_irqmask);
520         return handled;
521 }
522
523 void cx88_wakeup(struct cx88_core *core,
524                  struct cx88_dmaqueue *q, u32 count)
525 {
526         struct cx88_buffer *buf;
527         int bc;
528
529         for (bc = 0;; bc++) {
530                 if (list_empty(&q->active))
531                         break;
532                 buf = list_entry(q->active.next,
533                                  struct cx88_buffer, vb.queue);
534                 /* count comes from the hw and is is 16bit wide --
535                  * this trick handles wrap-arounds correctly for
536                  * up to 32767 buffers in flight... */
537                 if ((s16) (count - buf->count) < 0)
538                         break;
539                 do_gettimeofday(&buf->vb.ts);
540                 dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
541                         count, buf->count);
542                 buf->vb.state = STATE_DONE;
543                 list_del(&buf->vb.queue);
544                 wake_up(&buf->vb.done);
545         }
546         if (list_empty(&q->active)) {
547                 del_timer(&q->timeout);
548         } else {
549                 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
550         }
551         if (bc != 1)
552                 printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
553 }
554
555 void cx88_shutdown(struct cx88_core *core)
556 {
557         /* disable RISC controller + IRQs */
558         cx_write(MO_DEV_CNTRL2, 0);
559
560         /* stop dma transfers */
561         cx_write(MO_VID_DMACNTRL, 0x0);
562         cx_write(MO_AUD_DMACNTRL, 0x0);
563         cx_write(MO_TS_DMACNTRL, 0x0);
564         cx_write(MO_VIP_DMACNTRL, 0x0);
565         cx_write(MO_GPHST_DMACNTRL, 0x0);
566
567         /* stop interrupts */
568         cx_write(MO_PCI_INTMSK, 0x0);
569         cx_write(MO_VID_INTMSK, 0x0);
570         cx_write(MO_AUD_INTMSK, 0x0);
571         cx_write(MO_TS_INTMSK, 0x0);
572         cx_write(MO_VIP_INTMSK, 0x0);
573         cx_write(MO_GPHST_INTMSK, 0x0);
574
575         /* stop capturing */
576         cx_write(VID_CAPTURE_CONTROL, 0);
577 }
578
579 int cx88_reset(struct cx88_core *core)
580 {
581         dprintk(1,"%s\n",__FUNCTION__);
582         cx88_shutdown(core);
583
584         /* clear irq status */
585         cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
586         cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
587         cx_write(MO_INT1_STAT,   0xFFFFFFFF); // Clear RISC int
588
589         /* wait a bit */
590         msleep(100);
591
592         /* init sram */
593         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0);
594         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
595         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
596         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
597         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
598         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
599         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
600
601         /* misc init ... */
602         cx_write(MO_INPUT_FORMAT, ((1 << 13) |   // agc enable
603                                    (1 << 12) |   // agc gain
604                                    (1 << 11) |   // adaptibe agc
605                                    (0 << 10) |   // chroma agc
606                                    (0 <<  9) |   // ckillen
607                                    (7)));
608
609         /* setup image format */
610         cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
611
612         /* setup FIFO Threshholds */
613         cx_write(MO_PDMA_STHRSH,   0x0807);
614         cx_write(MO_PDMA_DTHRSH,   0x0807);
615
616         /* fixes flashing of image */
617         cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
618         cx_write(MO_AGC_BACK_VBI,  0x00E00555);
619
620         cx_write(MO_VID_INTSTAT,   0xFFFFFFFF); // Clear PIV int
621         cx_write(MO_PCI_INTSTAT,   0xFFFFFFFF); // Clear PCI int
622         cx_write(MO_INT1_STAT,     0xFFFFFFFF); // Clear RISC int
623
624         /* Reset on-board parts */
625         cx_write(MO_SRST_IO, 0);
626         msleep(10);
627         cx_write(MO_SRST_IO, 1);
628
629         return 0;
630 }
631
632 /* ------------------------------------------------------------------ */
633
634 static unsigned int inline norm_swidth(struct cx88_tvnorm *norm)
635 {
636         return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
637 }
638
639 static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm)
640 {
641         return (norm->id & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
642 }
643
644 static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
645 {
646         return (norm->id & V4L2_STD_625_50) ? 0x24 : 0x18;
647 }
648
649 static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
650 {
651         if (norm->id & V4L2_STD_PAL_M)
652                 return 28604892;      // 3.575611 MHz
653
654         if (norm->id & (V4L2_STD_PAL_Nc))
655                 return 28656448;      // 3.582056 MHz
656
657         if (norm->id & V4L2_STD_NTSC) // All NTSC/M and variants
658                 return 28636360;      // 3.57954545 MHz +/- 10 Hz
659
660         /* SECAM have also different sub carrier for chroma,
661            but step_db and step_dr, at cx88_set_tvnorm already handles that.
662
663            The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N
664          */
665
666         return 35468950;      // 4.43361875 MHz +/- 5 Hz
667 }
668
669 static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
670 {
671
672         unsigned int fsc4=norm_fsc8(norm)/2;
673
674         /* returns 4*FSC / vtotal / frames per seconds */
675         return (norm->id & V4L2_STD_625_50) ?
676                                 ((fsc4+312)/625+12)/25 :
677                                 ((fsc4+262)/525*1001+15000)/30000;
678 }
679
680 static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
681 {
682         return (norm->id & V4L2_STD_625_50) ? 511 : 400;
683 }
684
685 int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
686                    enum v4l2_field field)
687 {
688         unsigned int swidth  = norm_swidth(core->tvnorm);
689         unsigned int sheight = norm_maxh(core->tvnorm);
690         u32 value;
691
692         dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
693                 V4L2_FIELD_HAS_TOP(field)    ? "T" : "",
694                 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
695                 core->tvnorm->name);
696         if (!V4L2_FIELD_HAS_BOTH(field))
697                 height *= 2;
698
699         // recalc H delay and scale registers
700         value = (width * norm_hdelay(core->tvnorm)) / swidth;
701         value &= 0x3fe;
702         cx_write(MO_HDELAY_EVEN,  value);
703         cx_write(MO_HDELAY_ODD,   value);
704         dprintk(1,"set_scale: hdelay  0x%04x (width %d)\n", value,swidth);
705
706         value = (swidth * 4096 / width) - 4096;
707         cx_write(MO_HSCALE_EVEN,  value);
708         cx_write(MO_HSCALE_ODD,   value);
709         dprintk(1,"set_scale: hscale  0x%04x\n", value);
710
711         cx_write(MO_HACTIVE_EVEN, width);
712         cx_write(MO_HACTIVE_ODD,  width);
713         dprintk(1,"set_scale: hactive 0x%04x\n", width);
714
715         // recalc V scale Register (delay is constant)
716         cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
717         cx_write(MO_VDELAY_ODD,  norm_vdelay(core->tvnorm));
718         dprintk(1,"set_scale: vdelay  0x%04x\n", norm_vdelay(core->tvnorm));
719
720         value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
721         cx_write(MO_VSCALE_EVEN,  value);
722         cx_write(MO_VSCALE_ODD,   value);
723         dprintk(1,"set_scale: vscale  0x%04x\n", value);
724
725         cx_write(MO_VACTIVE_EVEN, sheight);
726         cx_write(MO_VACTIVE_ODD,  sheight);
727         dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
728
729         // setup filters
730         value = 0;
731         value |= (1 << 19);        // CFILT (default)
732         if (core->tvnorm->id & V4L2_STD_SECAM) {
733                 value |= (1 << 15);
734                 value |= (1 << 16);
735         }
736         if (INPUT(core->input)->type == CX88_VMUX_SVIDEO)
737                 value |= (1 << 13) | (1 << 5);
738         if (V4L2_FIELD_INTERLACED == field)
739                 value |= (1 << 3); // VINT (interlaced vertical scaling)
740         if (width < 385)
741                 value |= (1 << 0); // 3-tap interpolation
742         if (width < 193)
743                 value |= (1 << 1); // 5-tap interpolation
744         if (nocomb)
745                 value |= (3 << 5); // disable comb filter
746
747         cx_write(MO_FILTER_EVEN,  value);
748         cx_write(MO_FILTER_ODD,   value);
749         dprintk(1,"set_scale: filter  0x%04x\n", value);
750
751         return 0;
752 }
753
754 static const u32 xtal = 28636363;
755
756 static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
757 {
758         static u32 pre[] = { 0, 0, 0, 3, 2, 1 };
759         u64 pll;
760         u32 reg;
761         int i;
762
763         if (prescale < 2)
764                 prescale = 2;
765         if (prescale > 5)
766                 prescale = 5;
767
768         pll = ofreq * 8 * prescale * (u64)(1 << 20);
769         do_div(pll,xtal);
770         reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
771         if (((reg >> 20) & 0x3f) < 14) {
772                 printk("%s/0: pll out of range\n",core->name);
773                 return -1;
774         }
775
776         dprintk(1,"set_pll:    MO_PLL_REG       0x%08x [old=0x%08x,freq=%d]\n",
777                 reg, cx_read(MO_PLL_REG), ofreq);
778         cx_write(MO_PLL_REG, reg);
779         for (i = 0; i < 100; i++) {
780                 reg = cx_read(MO_DEVICE_STATUS);
781                 if (reg & (1<<2)) {
782                         dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",
783                                 prescale,ofreq);
784                         return 0;
785                 }
786                 dprintk(1,"pll not locked yet, waiting ...\n");
787                 msleep(10);
788         }
789         dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
790         return -1;
791 }
792
793 int cx88_start_audio_dma(struct cx88_core *core)
794 {
795         /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
796         int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
797
798         /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
799         if (cx_read(MO_AUD_DMACNTRL) & 0x10)
800                 return 0;
801
802         /* setup fifo + format */
803         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
804         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
805
806         cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
807         cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */
808
809         /* start dma */
810         cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
811
812         return 0;
813 }
814
815 int cx88_stop_audio_dma(struct cx88_core *core)
816 {
817         /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
818         if (cx_read(MO_AUD_DMACNTRL) & 0x10)
819                 return 0;
820
821         /* stop dma */
822         cx_write(MO_AUD_DMACNTRL, 0x0000);
823
824         return 0;
825 }
826
827 static int set_tvaudio(struct cx88_core *core)
828 {
829         struct cx88_tvnorm *norm = core->tvnorm;
830
831         if (CX88_VMUX_TELEVISION != INPUT(core->input)->type)
832                 return 0;
833
834         if (V4L2_STD_PAL_BG & norm->id) {
835                 core->tvaudio = WW_BG;
836
837         } else if (V4L2_STD_PAL_DK & norm->id) {
838                 core->tvaudio = WW_DK;
839
840         } else if (V4L2_STD_PAL_I & norm->id) {
841                 core->tvaudio = WW_I;
842
843         } else if (V4L2_STD_SECAM_L & norm->id) {
844                 core->tvaudio = WW_L;
845
846         } else if (V4L2_STD_SECAM_DK & norm->id) {
847                 core->tvaudio = WW_DK;
848
849         } else if ((V4L2_STD_NTSC_M & norm->id) ||
850                    (V4L2_STD_PAL_M  & norm->id)) {
851                 core->tvaudio = WW_BTSC;
852
853         } else if (V4L2_STD_NTSC_M_JP & norm->id) {
854                 core->tvaudio = WW_EIAJ;
855
856         } else {
857                 printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
858                        core->name, norm->name);
859                 core->tvaudio = 0;
860                 return 0;
861         }
862
863         cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
864         cx88_set_tvaudio(core);
865         /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
866
867 /*
868    This should be needed only on cx88-alsa. It seems that some cx88 chips have
869    bugs and does require DMA enabled for it to work.
870  */
871         cx88_start_audio_dma(core);
872         return 0;
873 }
874
875
876
877 int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
878 {
879         u32 fsc8;
880         u32 adc_clock;
881         u32 vdec_clock;
882         u32 step_db,step_dr;
883         u64 tmp64;
884         u32 bdelay,agcdelay,htotal;
885
886         core->tvnorm = norm;
887         fsc8       = norm_fsc8(norm);
888         adc_clock  = xtal;
889         vdec_clock = fsc8;
890         step_db    = fsc8;
891         step_dr    = fsc8;
892
893         if (norm->id & V4L2_STD_SECAM) {
894                 step_db = 4250000 * 8;
895                 step_dr = 4406250 * 8;
896         }
897
898         dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
899                 norm->name, fsc8, adc_clock, vdec_clock, step_db, step_dr);
900         set_pll(core,2,vdec_clock);
901
902         dprintk(1,"set_tvnorm: MO_INPUT_FORMAT  0x%08x [old=0x%08x]\n",
903                 norm->cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
904         cx_andor(MO_INPUT_FORMAT, 0xf, norm->cxiformat);
905
906         // FIXME: as-is from DScaler
907         dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
908                 norm->cxoformat, cx_read(MO_OUTPUT_FORMAT));
909         cx_write(MO_OUTPUT_FORMAT, norm->cxoformat);
910
911         // MO_SCONV_REG = adc clock / video dec clock * 2^17
912         tmp64  = adc_clock * (u64)(1 << 17);
913         do_div(tmp64, vdec_clock);
914         dprintk(1,"set_tvnorm: MO_SCONV_REG     0x%08x [old=0x%08x]\n",
915                 (u32)tmp64, cx_read(MO_SCONV_REG));
916         cx_write(MO_SCONV_REG, (u32)tmp64);
917
918         // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
919         tmp64  = step_db * (u64)(1 << 22);
920         do_div(tmp64, vdec_clock);
921         dprintk(1,"set_tvnorm: MO_SUB_STEP      0x%08x [old=0x%08x]\n",
922                 (u32)tmp64, cx_read(MO_SUB_STEP));
923         cx_write(MO_SUB_STEP, (u32)tmp64);
924
925         // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
926         tmp64  = step_dr * (u64)(1 << 22);
927         do_div(tmp64, vdec_clock);
928         dprintk(1,"set_tvnorm: MO_SUB_STEP_DR   0x%08x [old=0x%08x]\n",
929                 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
930         cx_write(MO_SUB_STEP_DR, (u32)tmp64);
931
932         // bdelay + agcdelay
933         bdelay   = vdec_clock * 65 / 20000000 + 21;
934         agcdelay = vdec_clock * 68 / 20000000 + 15;
935         dprintk(1,"set_tvnorm: MO_AGC_BURST     0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
936                 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay);
937         cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
938
939         // htotal
940         tmp64 = norm_htotal(norm) * (u64)vdec_clock;
941         do_div(tmp64, fsc8);
942         htotal = (u32)tmp64 | (HLNotchFilter4xFsc << 11);
943         dprintk(1,"set_tvnorm: MO_HTOTAL        0x%08x [old=0x%08x,htotal=%d]\n",
944                 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
945         cx_write(MO_HTOTAL, htotal);
946
947         // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
948         // the effective vbi offset ~244 samples, the same as the Bt8x8
949         cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm));
950
951         // this is needed as well to set all tvnorm parameter
952         cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
953
954         // audio
955         set_tvaudio(core);
956
957         // tell i2c chips
958         cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id);
959
960         // done
961         return 0;
962 }
963
964 /* ------------------------------------------------------------------ */
965
966 static int cx88_pci_quirks(char *name, struct pci_dev *pci)
967 {
968         unsigned int lat = UNSET;
969         u8 ctrl = 0;
970         u8 value;
971
972         /* check pci quirks */
973         if (pci_pci_problems & PCIPCI_TRITON) {
974                 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
975                        name);
976                 ctrl |= CX88X_EN_TBFX;
977         }
978         if (pci_pci_problems & PCIPCI_NATOMA) {
979                 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
980                        name);
981                 ctrl |= CX88X_EN_TBFX;
982         }
983         if (pci_pci_problems & PCIPCI_VIAETBF) {
984                 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
985                        name);
986                 ctrl |= CX88X_EN_TBFX;
987         }
988         if (pci_pci_problems & PCIPCI_VSFX) {
989                 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
990                        name);
991                 ctrl |= CX88X_EN_VSFX;
992         }
993 #ifdef PCIPCI_ALIMAGIK
994         if (pci_pci_problems & PCIPCI_ALIMAGIK) {
995                 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
996                        name);
997                 lat = 0x0A;
998         }
999 #endif
1000
1001         /* check insmod options */
1002         if (UNSET != latency)
1003                 lat = latency;
1004
1005         /* apply stuff */
1006         if (ctrl) {
1007                 pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
1008                 value |= ctrl;
1009                 pci_write_config_byte(pci, CX88X_DEVCTRL, value);
1010         }
1011         if (UNSET != lat) {
1012                 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
1013                        name, latency);
1014                 pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
1015         }
1016         return 0;
1017 }
1018
1019 /* ------------------------------------------------------------------ */
1020
1021 struct video_device *cx88_vdev_init(struct cx88_core *core,
1022                                     struct pci_dev *pci,
1023                                     struct video_device *template,
1024                                     char *type)
1025 {
1026         struct video_device *vfd;
1027
1028         vfd = video_device_alloc();
1029         if (NULL == vfd)
1030                 return NULL;
1031         *vfd = *template;
1032         vfd->minor   = -1;
1033         vfd->dev     = &pci->dev;
1034         vfd->release = video_device_release;
1035         snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1036                  core->name, type, cx88_boards[core->board].name);
1037         return vfd;
1038 }
1039
1040 static int get_ressources(struct cx88_core *core, struct pci_dev *pci)
1041 {
1042         if (request_mem_region(pci_resource_start(pci,0),
1043                                pci_resource_len(pci,0),
1044                                core->name))
1045                 return 0;
1046         printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
1047                core->name,(unsigned long long)pci_resource_start(pci,0));
1048         return -EBUSY;
1049 }
1050
1051 struct cx88_core* cx88_core_get(struct pci_dev *pci)
1052 {
1053         struct cx88_core *core;
1054         struct list_head *item;
1055         int i;
1056
1057         mutex_lock(&devlist);
1058         list_for_each(item,&cx88_devlist) {
1059                 core = list_entry(item, struct cx88_core, devlist);
1060                 if (pci->bus->number != core->pci_bus)
1061                         continue;
1062                 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1063                         continue;
1064
1065                 if (0 != get_ressources(core,pci))
1066                         goto fail_unlock;
1067                 atomic_inc(&core->refcount);
1068                 mutex_unlock(&devlist);
1069                 return core;
1070         }
1071         core = kzalloc(sizeof(*core),GFP_KERNEL);
1072         if (NULL == core)
1073                 goto fail_unlock;
1074
1075         atomic_inc(&core->refcount);
1076         core->pci_bus  = pci->bus->number;
1077         core->pci_slot = PCI_SLOT(pci->devfn);
1078         core->pci_irqmask = 0x00fc00;
1079         mutex_init(&core->lock);
1080
1081         core->nr = cx88_devcount++;
1082         sprintf(core->name,"cx88[%d]",core->nr);
1083         if (0 != get_ressources(core,pci)) {
1084                 printk(KERN_ERR "CORE %s No more PCI ressources for "
1085                         "subsystem: %04x:%04x, board: %s\n",
1086                         core->name,pci->subsystem_vendor,
1087                         pci->subsystem_device,
1088                         cx88_boards[core->board].name);
1089
1090                 cx88_devcount--;
1091                 goto fail_free;
1092         }
1093         list_add_tail(&core->devlist,&cx88_devlist);
1094
1095         /* PCI stuff */
1096         cx88_pci_quirks(core->name, pci);
1097         core->lmmio = ioremap(pci_resource_start(pci,0),
1098                               pci_resource_len(pci,0));
1099         core->bmmio = (u8 __iomem *)core->lmmio;
1100
1101         /* board config */
1102         core->board = UNSET;
1103         if (card[core->nr] < cx88_bcount)
1104                 core->board = card[core->nr];
1105         for (i = 0; UNSET == core->board  &&  i < cx88_idcount; i++)
1106                 if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
1107                     pci->subsystem_device == cx88_subids[i].subdevice)
1108                         core->board = cx88_subids[i].card;
1109         if (UNSET == core->board) {
1110                 core->board = CX88_BOARD_UNKNOWN;
1111                 cx88_card_list(core,pci);
1112         }
1113         printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1114                 core->name,pci->subsystem_vendor,
1115                 pci->subsystem_device,cx88_boards[core->board].name,
1116                 core->board, card[core->nr] == core->board ?
1117                 "insmod option" : "autodetected");
1118
1119         core->tuner_type = tuner[core->nr];
1120         core->radio_type = radio[core->nr];
1121         if (UNSET == core->tuner_type)
1122                 core->tuner_type = cx88_boards[core->board].tuner_type;
1123         if (UNSET == core->radio_type)
1124                 core->radio_type = cx88_boards[core->board].radio_type;
1125         if (!core->tuner_addr)
1126                 core->tuner_addr = cx88_boards[core->board].tuner_addr;
1127         if (!core->radio_addr)
1128                 core->radio_addr = cx88_boards[core->board].radio_addr;
1129
1130         printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
1131                 core->tuner_type, core->tuner_addr<<1,
1132                 core->radio_type, core->radio_addr<<1);
1133
1134         core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
1135
1136         /* init hardware */
1137         cx88_reset(core);
1138         cx88_card_setup_pre_i2c(core);
1139         cx88_i2c_init(core,pci);
1140         cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
1141         cx88_card_setup(core);
1142         cx88_ir_init(core,pci);
1143
1144         mutex_unlock(&devlist);
1145         return core;
1146
1147 fail_free:
1148         kfree(core);
1149 fail_unlock:
1150         mutex_unlock(&devlist);
1151         return NULL;
1152 }
1153
1154 void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1155 {
1156         release_mem_region(pci_resource_start(pci,0),
1157                            pci_resource_len(pci,0));
1158
1159         if (!atomic_dec_and_test(&core->refcount))
1160                 return;
1161
1162         mutex_lock(&devlist);
1163         cx88_ir_fini(core);
1164         if (0 == core->i2c_rc)
1165                 i2c_del_adapter(&core->i2c_adap);
1166         list_del(&core->devlist);
1167         iounmap(core->lmmio);
1168         cx88_devcount--;
1169         mutex_unlock(&devlist);
1170         kfree(core);
1171 }
1172
1173 /* ------------------------------------------------------------------ */
1174
1175 EXPORT_SYMBOL(cx88_print_irqbits);
1176
1177 EXPORT_SYMBOL(cx88_core_irq);
1178 EXPORT_SYMBOL(cx88_wakeup);
1179 EXPORT_SYMBOL(cx88_reset);
1180 EXPORT_SYMBOL(cx88_shutdown);
1181
1182 EXPORT_SYMBOL(cx88_risc_buffer);
1183 EXPORT_SYMBOL(cx88_risc_databuffer);
1184 EXPORT_SYMBOL(cx88_risc_stopper);
1185 EXPORT_SYMBOL(cx88_free_buffer);
1186
1187 EXPORT_SYMBOL(cx88_sram_channels);
1188 EXPORT_SYMBOL(cx88_sram_channel_setup);
1189 EXPORT_SYMBOL(cx88_sram_channel_dump);
1190
1191 EXPORT_SYMBOL(cx88_set_tvnorm);
1192 EXPORT_SYMBOL(cx88_set_scale);
1193
1194 EXPORT_SYMBOL(cx88_vdev_init);
1195 EXPORT_SYMBOL(cx88_core_get);
1196 EXPORT_SYMBOL(cx88_core_put);
1197
1198 /*
1199  * Local variables:
1200  * c-basic-offset: 8
1201  * End:
1202  * 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
1203  */