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