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