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