[PATCH] v4l: CX88 Update
[linux-2.6.git] / drivers / media / video / cx88 / cx88-core.c
1 /*
2  * $Id: cx88-core.c,v 1.33 2005/07/07 14:17:47 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
474 void cx88_sram_channel_dump(struct cx88_core *core,
475                             struct sram_channel *ch)
476 {
477         static char *name[] = {
478                 "initial risc",
479                 "cdt base",
480                 "cdt size",
481                 "iq base",
482                 "iq size",
483                 "risc pc",
484                 "iq wr ptr",
485                 "iq rd ptr",
486                 "cdt current",
487                 "pci target",
488                 "line / byte",
489         };
490         u32 risc;
491         unsigned int i,j,n;
492
493         printk("%s: %s - dma channel status dump\n",
494                core->name,ch->name);
495         for (i = 0; i < ARRAY_SIZE(name); i++)
496                 printk("%s:   cmds: %-12s: 0x%08x\n",
497                        core->name,name[i],
498                        cx_read(ch->cmds_start + 4*i));
499         for (i = 0; i < 4; i++) {
500                 risc = cx_read(ch->cmds_start + 4 * (i+11));
501                 printk("%s:   risc%d: ", core->name, i);
502                 cx88_risc_decode(risc);
503         }
504         for (i = 0; i < 16; i += n) {
505                 risc = cx_read(ch->ctrl_start + 4 * i);
506                 printk("%s:   iq %x: ", core->name, i);
507                 n = cx88_risc_decode(risc);
508                 for (j = 1; j < n; j++) {
509                         risc = cx_read(ch->ctrl_start + 4 * (i+j));
510                         printk("%s:   iq %x: 0x%08x [ arg #%d ]\n",
511                                core->name, i+j, risc, j);
512                 }
513         }
514
515         printk("%s: fifo: 0x%08x -> 0x%x\n",
516                core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
517         printk("%s: ctrl: 0x%08x -> 0x%x\n",
518                core->name, ch->ctrl_start, ch->ctrl_start+6*16);
519         printk("%s:   ptr1_reg: 0x%08x\n",
520                core->name,cx_read(ch->ptr1_reg));
521         printk("%s:   ptr2_reg: 0x%08x\n",
522                core->name,cx_read(ch->ptr2_reg));
523         printk("%s:   cnt1_reg: 0x%08x\n",
524                core->name,cx_read(ch->cnt1_reg));
525         printk("%s:   cnt2_reg: 0x%08x\n",
526                core->name,cx_read(ch->cnt2_reg));
527 }
528
529 static char *cx88_pci_irqs[32] = {
530         "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
531         "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
532         "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
533         "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
534 };
535
536 void cx88_print_irqbits(char *name, char *tag, char **strings,
537                         u32 bits, u32 mask)
538 {
539         unsigned int i;
540
541         printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
542         for (i = 0; i < 32; i++) {
543                 if (!(bits & (1 << i)))
544                         continue;
545                 if (strings[i])
546                         printk(" %s", strings[i]);
547                 else
548                         printk(" %d", i);
549                 if (!(mask & (1 << i)))
550                         continue;
551                 printk("*");
552         }
553         printk("\n");
554 }
555
556 /* ------------------------------------------------------------------ */
557
558 int cx88_core_irq(struct cx88_core *core, u32 status)
559 {
560         int handled = 0;
561
562         if (status & (1<<18)) {
563                 cx88_ir_irq(core);
564                 handled++;
565         }
566         if (!handled)
567                 cx88_print_irqbits(core->name, "irq pci",
568                                    cx88_pci_irqs, status,
569                                    core->pci_irqmask);
570         return handled;
571 }
572
573 void cx88_wakeup(struct cx88_core *core,
574                  struct cx88_dmaqueue *q, u32 count)
575 {
576         struct cx88_buffer *buf;
577         int bc;
578
579         for (bc = 0;; bc++) {
580                 if (list_empty(&q->active))
581                         break;
582                 buf = list_entry(q->active.next,
583                                  struct cx88_buffer, vb.queue);
584                 /* count comes from the hw and is is 16bit wide --
585                  * this trick handles wrap-arounds correctly for
586                  * up to 32767 buffers in flight... */
587                 if ((s16) (count - buf->count) < 0)
588                         break;
589                 do_gettimeofday(&buf->vb.ts);
590                 dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
591                         count, buf->count);
592                 buf->vb.state = STATE_DONE;
593                 list_del(&buf->vb.queue);
594                 wake_up(&buf->vb.done);
595         }
596         if (list_empty(&q->active)) {
597                 del_timer(&q->timeout);
598         } else {
599                 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
600         }
601         if (bc != 1)
602                 printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
603 }
604
605 void cx88_shutdown(struct cx88_core *core)
606 {
607         /* disable RISC controller + IRQs */
608         cx_write(MO_DEV_CNTRL2, 0);
609
610         /* stop dma transfers */
611         cx_write(MO_VID_DMACNTRL, 0x0);
612         cx_write(MO_AUD_DMACNTRL, 0x0);
613         cx_write(MO_TS_DMACNTRL, 0x0);
614         cx_write(MO_VIP_DMACNTRL, 0x0);
615         cx_write(MO_GPHST_DMACNTRL, 0x0);
616
617         /* stop interrupts */
618         cx_write(MO_PCI_INTMSK, 0x0);
619         cx_write(MO_VID_INTMSK, 0x0);
620         cx_write(MO_AUD_INTMSK, 0x0);
621         cx_write(MO_TS_INTMSK, 0x0);
622         cx_write(MO_VIP_INTMSK, 0x0);
623         cx_write(MO_GPHST_INTMSK, 0x0);
624
625         /* stop capturing */
626         cx_write(VID_CAPTURE_CONTROL, 0);
627 }
628
629 int cx88_reset(struct cx88_core *core)
630 {
631         dprintk(1,"%s\n",__FUNCTION__);
632         cx88_shutdown(core);
633
634         /* clear irq status */
635         cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
636         cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
637         cx_write(MO_INT1_STAT,   0xFFFFFFFF); // Clear RISC int
638
639         /* wait a bit */
640         msleep(100);
641
642         /* init sram */
643         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0);
644         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
645         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
646         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
647         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
648         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
649         cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
650
651         /* misc init ... */
652         cx_write(MO_INPUT_FORMAT, ((1 << 13) |   // agc enable
653                                    (1 << 12) |   // agc gain
654                                    (1 << 11) |   // adaptibe agc
655                                    (0 << 10) |   // chroma agc
656                                    (0 <<  9) |   // ckillen
657                                    (7)));
658
659         /* setup image format */
660         cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
661
662         /* setup FIFO Threshholds */
663         cx_write(MO_PDMA_STHRSH,   0x0807);
664         cx_write(MO_PDMA_DTHRSH,   0x0807);
665
666         /* fixes flashing of image */
667         cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
668         cx_write(MO_AGC_BACK_VBI,  0x00E00555);
669
670         cx_write(MO_VID_INTSTAT,   0xFFFFFFFF); // Clear PIV int
671         cx_write(MO_PCI_INTSTAT,   0xFFFFFFFF); // Clear PCI int
672         cx_write(MO_INT1_STAT,     0xFFFFFFFF); // Clear RISC int
673
674         /* Reset on-board parts */
675         cx_write(MO_SRST_IO, 0);
676         msleep(10);
677         cx_write(MO_SRST_IO, 1);
678
679         return 0;
680 }
681
682 /* ------------------------------------------------------------------ */
683
684 static unsigned int inline norm_swidth(struct cx88_tvnorm *norm)
685 {
686         return (norm->id & V4L2_STD_625_50) ? 922 : 754;
687 }
688
689 static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm)
690 {
691         return (norm->id & V4L2_STD_625_50) ? 186 : 135;
692 }
693
694 static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
695 {
696         return (norm->id & V4L2_STD_625_50) ? 0x24 : 0x18;
697 }
698
699 static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
700 {
701         static const unsigned int ntsc = 28636360;
702         static const unsigned int pal  = 35468950;
703         static const unsigned int palm  = 28604892;
704
705         if (norm->id & V4L2_STD_PAL_M)
706                 return palm;
707
708         return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
709 }
710
711 static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm)
712 {
713         return (norm->id & V4L2_STD_625_50)
714                 ? HLNotchFilter135PAL
715                 : HLNotchFilter135NTSC;
716 }
717
718 static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
719 {
720         /* Should always be Line Draw Time / (4*FSC) */
721
722         if (norm->id & V4L2_STD_PAL_M)
723                 return 909;
724
725         return (norm->id & V4L2_STD_625_50) ? 1135 : 910;
726 }
727
728 static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
729 {
730         return (norm->id & V4L2_STD_625_50) ? 511 : 288;
731 }
732
733 int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
734                    enum v4l2_field field)
735 {
736         unsigned int swidth  = norm_swidth(core->tvnorm);
737         unsigned int sheight = norm_maxh(core->tvnorm);
738         u32 value;
739
740         dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
741                 V4L2_FIELD_HAS_TOP(field)    ? "T" : "",
742                 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
743                 core->tvnorm->name);
744         if (!V4L2_FIELD_HAS_BOTH(field))
745                 height *= 2;
746
747         // recalc H delay and scale registers
748         value = (width * norm_hdelay(core->tvnorm)) / swidth;
749         value &= 0x3fe;
750         cx_write(MO_HDELAY_EVEN,  value);
751         cx_write(MO_HDELAY_ODD,   value);
752         dprintk(1,"set_scale: hdelay  0x%04x\n", value);
753
754         value = (swidth * 4096 / width) - 4096;
755         cx_write(MO_HSCALE_EVEN,  value);
756         cx_write(MO_HSCALE_ODD,   value);
757         dprintk(1,"set_scale: hscale  0x%04x\n", value);
758
759         cx_write(MO_HACTIVE_EVEN, width);
760         cx_write(MO_HACTIVE_ODD,  width);
761         dprintk(1,"set_scale: hactive 0x%04x\n", width);
762
763         // recalc V scale Register (delay is constant)
764         cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
765         cx_write(MO_VDELAY_ODD,  norm_vdelay(core->tvnorm));
766         dprintk(1,"set_scale: vdelay  0x%04x\n", norm_vdelay(core->tvnorm));
767
768         value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
769         cx_write(MO_VSCALE_EVEN,  value);
770         cx_write(MO_VSCALE_ODD,   value);
771         dprintk(1,"set_scale: vscale  0x%04x\n", value);
772
773         cx_write(MO_VACTIVE_EVEN, sheight);
774         cx_write(MO_VACTIVE_ODD,  sheight);
775         dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
776
777         // setup filters
778         value = 0;
779         value |= (1 << 19);        // CFILT (default)
780         if (core->tvnorm->id & V4L2_STD_SECAM) {
781                 value |= (1 << 15);
782                 value |= (1 << 16);
783         }
784         if (INPUT(core->input)->type == CX88_VMUX_SVIDEO)
785                 value |= (1 << 13) | (1 << 5);
786         if (V4L2_FIELD_INTERLACED == field)
787                 value |= (1 << 3); // VINT (interlaced vertical scaling)
788         if (width < 385)
789                 value |= (1 << 0); // 3-tap interpolation
790         if (width < 193)
791                 value |= (1 << 1); // 5-tap interpolation
792         if (nocomb)
793                 value |= (3 << 5); // disable comb filter
794
795         cx_write(MO_FILTER_EVEN,  value);
796         cx_write(MO_FILTER_ODD,   value);
797         dprintk(1,"set_scale: filter  0x%04x\n", value);
798
799         return 0;
800 }
801
802 static const u32 xtal = 28636363;
803
804 static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
805 {
806         static u32 pre[] = { 0, 0, 0, 3, 2, 1 };
807         u64 pll;
808         u32 reg;
809         int i;
810
811         if (prescale < 2)
812                 prescale = 2;
813         if (prescale > 5)
814                 prescale = 5;
815
816         pll = ofreq * 8 * prescale * (u64)(1 << 20);
817         do_div(pll,xtal);
818         reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
819         if (((reg >> 20) & 0x3f) < 14) {
820                 printk("%s/0: pll out of range\n",core->name);
821                 return -1;
822         }
823
824         dprintk(1,"set_pll:    MO_PLL_REG       0x%08x [old=0x%08x,freq=%d]\n",
825                 reg, cx_read(MO_PLL_REG), ofreq);
826         cx_write(MO_PLL_REG, reg);
827         for (i = 0; i < 100; i++) {
828                 reg = cx_read(MO_DEVICE_STATUS);
829                 if (reg & (1<<2)) {
830                         dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",
831                                 prescale,ofreq);
832                         return 0;
833                 }
834                 dprintk(1,"pll not locked yet, waiting ...\n");
835                 msleep(10);
836         }
837         dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
838         return -1;
839 }
840
841 static int set_tvaudio(struct cx88_core *core)
842 {
843         struct cx88_tvnorm *norm = core->tvnorm;
844
845         if (CX88_VMUX_TELEVISION != INPUT(core->input)->type)
846                 return 0;
847
848         if (V4L2_STD_PAL_BG & norm->id) {
849                 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG;
850
851         } else if (V4L2_STD_PAL_DK & norm->id) {
852                 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK;
853
854         } else if (V4L2_STD_PAL_I & norm->id) {
855                 core->tvaudio = WW_NICAM_I;
856
857         } else if (V4L2_STD_SECAM_L & norm->id) {
858                 core->tvaudio = WW_SYSTEM_L_AM;
859
860         } else if (V4L2_STD_SECAM_DK & norm->id) {
861                 core->tvaudio = WW_A2_DK;
862
863         } else if ((V4L2_STD_NTSC_M & norm->id) ||
864                    (V4L2_STD_PAL_M  & norm->id)) {
865                 core->tvaudio = WW_BTSC;
866
867         } else if (V4L2_STD_NTSC_M_JP & norm->id) {
868                 core->tvaudio = WW_EIAJ;
869
870         } else {
871                 printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
872                        core->name, norm->name);
873                 core->tvaudio = 0;
874                 return 0;
875         }
876
877         cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
878         cx88_set_tvaudio(core);
879         // cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO);
880
881         cx_write(MO_AUDD_LNGTH,    128); /* fifo size */
882         cx_write(MO_AUDR_LNGTH,    128); /* fifo size */
883         cx_write(MO_AUD_DMACNTRL, 0x03); /* need audio fifo */
884         return 0;
885 }
886
887 int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
888 {
889         u32 fsc8;
890         u32 adc_clock;
891         u32 vdec_clock;
892         u32 step_db,step_dr;
893         u64 tmp64;
894         u32 bdelay,agcdelay,htotal;
895
896         core->tvnorm = norm;
897         fsc8       = norm_fsc8(norm);
898         adc_clock  = xtal;
899         vdec_clock = fsc8;
900         step_db    = fsc8;
901         step_dr    = fsc8;
902
903         if (norm->id & V4L2_STD_SECAM) {
904                 step_db = 4250000 * 8;
905                 step_dr = 4406250 * 8;
906         }
907
908         dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
909                 norm->name, fsc8, adc_clock, vdec_clock, step_db, step_dr);
910         set_pll(core,2,vdec_clock);
911
912         dprintk(1,"set_tvnorm: MO_INPUT_FORMAT  0x%08x [old=0x%08x]\n",
913                 norm->cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
914         cx_andor(MO_INPUT_FORMAT, 0xf, norm->cxiformat);
915
916         // FIXME: as-is from DScaler
917         dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
918                 norm->cxoformat, cx_read(MO_OUTPUT_FORMAT));
919         cx_write(MO_OUTPUT_FORMAT, norm->cxoformat);
920
921         // MO_SCONV_REG = adc clock / video dec clock * 2^17
922         tmp64  = adc_clock * (u64)(1 << 17);
923         do_div(tmp64, vdec_clock);
924         dprintk(1,"set_tvnorm: MO_SCONV_REG     0x%08x [old=0x%08x]\n",
925                 (u32)tmp64, cx_read(MO_SCONV_REG));
926         cx_write(MO_SCONV_REG, (u32)tmp64);
927
928         // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
929         tmp64  = step_db * (u64)(1 << 22);
930         do_div(tmp64, vdec_clock);
931         dprintk(1,"set_tvnorm: MO_SUB_STEP      0x%08x [old=0x%08x]\n",
932                 (u32)tmp64, cx_read(MO_SUB_STEP));
933         cx_write(MO_SUB_STEP, (u32)tmp64);
934
935         // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
936         tmp64  = step_dr * (u64)(1 << 22);
937         do_div(tmp64, vdec_clock);
938         dprintk(1,"set_tvnorm: MO_SUB_STEP_DR   0x%08x [old=0x%08x]\n",
939                 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
940         cx_write(MO_SUB_STEP_DR, (u32)tmp64);
941
942         // bdelay + agcdelay
943         bdelay   = vdec_clock * 65 / 20000000 + 21;
944         agcdelay = vdec_clock * 68 / 20000000 + 15;
945         dprintk(1,"set_tvnorm: MO_AGC_BURST     0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
946                 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay);
947         cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
948
949         // htotal
950         tmp64 = norm_htotal(norm) * (u64)vdec_clock;
951         do_div(tmp64, fsc8);
952         htotal = (u32)tmp64 | (norm_notchfilter(norm) << 11);
953         dprintk(1,"set_tvnorm: MO_HTOTAL        0x%08x [old=0x%08x,htotal=%d]\n",
954                 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
955         cx_write(MO_HTOTAL, htotal);
956
957         // vbi stuff
958         cx_write(MO_VBI_PACKET, ((1 << 11) | /* (norm_vdelay(norm)   << 11) | */
959                                  norm_vbipack(norm)));
960
961         // this is needed as well to set all tvnorm parameter
962         cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
963
964         // audio
965         set_tvaudio(core);
966
967         // tell i2c chips
968         cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id);
969
970         // done
971         return 0;
972 }
973
974 /* ------------------------------------------------------------------ */
975
976 static int cx88_pci_quirks(char *name, struct pci_dev *pci)
977 {
978         unsigned int lat = UNSET;
979         u8 ctrl = 0;
980         u8 value;
981
982         /* check pci quirks */
983         if (pci_pci_problems & PCIPCI_TRITON) {
984                 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
985                        name);
986                 ctrl |= CX88X_EN_TBFX;
987         }
988         if (pci_pci_problems & PCIPCI_NATOMA) {
989                 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
990                        name);
991                 ctrl |= CX88X_EN_TBFX;
992         }
993         if (pci_pci_problems & PCIPCI_VIAETBF) {
994                 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
995                        name);
996                 ctrl |= CX88X_EN_TBFX;
997         }
998         if (pci_pci_problems & PCIPCI_VSFX) {
999                 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
1000                        name);
1001                 ctrl |= CX88X_EN_VSFX;
1002         }
1003 #ifdef PCIPCI_ALIMAGIK
1004         if (pci_pci_problems & PCIPCI_ALIMAGIK) {
1005                 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
1006                        name);
1007                 lat = 0x0A;
1008         }
1009 #endif
1010
1011         /* check insmod options */
1012         if (UNSET != latency)
1013                 lat = latency;
1014
1015         /* apply stuff */
1016         if (ctrl) {
1017                 pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
1018                 value |= ctrl;
1019                 pci_write_config_byte(pci, CX88X_DEVCTRL, value);
1020         }
1021         if (UNSET != lat) {
1022                 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
1023                        name, latency);
1024                 pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
1025         }
1026         return 0;
1027 }
1028
1029 /* ------------------------------------------------------------------ */
1030
1031 struct video_device *cx88_vdev_init(struct cx88_core *core,
1032                                     struct pci_dev *pci,
1033                                     struct video_device *template,
1034                                     char *type)
1035 {
1036         struct video_device *vfd;
1037
1038         vfd = video_device_alloc();
1039         if (NULL == vfd)
1040                 return NULL;
1041         *vfd = *template;
1042         vfd->minor   = -1;
1043         vfd->dev     = &pci->dev;
1044         vfd->release = video_device_release;
1045         snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1046                  core->name, type, cx88_boards[core->board].name);
1047         return vfd;
1048 }
1049
1050 static int get_ressources(struct cx88_core *core, struct pci_dev *pci)
1051 {
1052         if (request_mem_region(pci_resource_start(pci,0),
1053                                pci_resource_len(pci,0),
1054                                core->name))
1055                 return 0;
1056         printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n",
1057                core->name,pci_resource_start(pci,0));
1058         return -EBUSY;
1059 }
1060
1061 struct cx88_core* cx88_core_get(struct pci_dev *pci)
1062 {
1063         struct cx88_core *core;
1064         struct list_head *item;
1065         int i;
1066
1067         down(&devlist);
1068         list_for_each(item,&cx88_devlist) {
1069                 core = list_entry(item, struct cx88_core, devlist);
1070                 if (pci->bus->number != core->pci_bus)
1071                         continue;
1072                 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1073                         continue;
1074
1075                 if (0 != get_ressources(core,pci))
1076                         goto fail_unlock;
1077                 atomic_inc(&core->refcount);
1078                 up(&devlist);
1079                 return core;
1080         }
1081         core = kmalloc(sizeof(*core),GFP_KERNEL);
1082         if (NULL == core)
1083                 goto fail_unlock;
1084
1085         memset(core,0,sizeof(*core));
1086         atomic_inc(&core->refcount);
1087         core->pci_bus  = pci->bus->number;
1088         core->pci_slot = PCI_SLOT(pci->devfn);
1089         core->pci_irqmask = 0x00fc00;
1090
1091         core->nr = cx88_devcount++;
1092         sprintf(core->name,"cx88[%d]",core->nr);
1093         if (0 != get_ressources(core,pci)) {
1094                 cx88_devcount--;
1095                 goto fail_free;
1096         }
1097         list_add_tail(&core->devlist,&cx88_devlist);
1098
1099         /* PCI stuff */
1100         cx88_pci_quirks(core->name, pci);
1101         core->lmmio = ioremap(pci_resource_start(pci,0),
1102                               pci_resource_len(pci,0));
1103         core->bmmio = (u8 __iomem *)core->lmmio;
1104
1105         /* board config */
1106         core->board = UNSET;
1107         if (card[core->nr] < cx88_bcount)
1108                 core->board = card[core->nr];
1109         for (i = 0; UNSET == core->board  &&  i < cx88_idcount; i++)
1110                 if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
1111                     pci->subsystem_device == cx88_subids[i].subdevice)
1112                         core->board = cx88_subids[i].card;
1113         if (UNSET == core->board) {
1114                 core->board = CX88_BOARD_UNKNOWN;
1115                 cx88_card_list(core,pci);
1116         }
1117         printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1118                core->name,pci->subsystem_vendor,
1119                pci->subsystem_device,cx88_boards[core->board].name,
1120                core->board, card[core->nr] == core->board ?
1121                "insmod option" : "autodetected");
1122
1123         core->tuner_type = tuner[core->nr];
1124         core->radio_type = radio[core->nr];
1125         if (UNSET == core->tuner_type)
1126                 core->tuner_type = cx88_boards[core->board].tuner_type;
1127         if (UNSET == core->radio_type)
1128                 core->radio_type = cx88_boards[core->board].radio_type;
1129         if (!core->tuner_addr)
1130                 core->tuner_addr = cx88_boards[core->board].tuner_addr;
1131         if (!core->radio_addr)
1132                 core->radio_addr = cx88_boards[core->board].radio_addr;
1133
1134         printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
1135                 core->tuner_type, core->tuner_addr<<1,
1136                 core->radio_type, core->radio_addr<<1);
1137
1138         core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
1139
1140         /* init hardware */
1141         cx88_reset(core);
1142         cx88_i2c_init(core,pci);
1143         cx88_card_setup(core);
1144         cx88_ir_init(core,pci);
1145
1146         up(&devlist);
1147         return core;
1148
1149 fail_free:
1150         kfree(core);
1151 fail_unlock:
1152         up(&devlist);
1153         return NULL;
1154 }
1155
1156 void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1157 {
1158         release_mem_region(pci_resource_start(pci,0),
1159                            pci_resource_len(pci,0));
1160
1161         if (!atomic_dec_and_test(&core->refcount))
1162                 return;
1163
1164         down(&devlist);
1165         cx88_ir_fini(core);
1166         if (0 == core->i2c_rc)
1167                 i2c_bit_del_bus(&core->i2c_adap);
1168         list_del(&core->devlist);
1169         iounmap(core->lmmio);
1170         cx88_devcount--;
1171         up(&devlist);
1172         kfree(core);
1173 }
1174
1175 /* ------------------------------------------------------------------ */
1176
1177 EXPORT_SYMBOL(cx88_print_ioctl);
1178 EXPORT_SYMBOL(cx88_print_irqbits);
1179
1180 EXPORT_SYMBOL(cx88_core_irq);
1181 EXPORT_SYMBOL(cx88_wakeup);
1182 EXPORT_SYMBOL(cx88_reset);
1183 EXPORT_SYMBOL(cx88_shutdown);
1184
1185 EXPORT_SYMBOL(cx88_risc_buffer);
1186 EXPORT_SYMBOL(cx88_risc_databuffer);
1187 EXPORT_SYMBOL(cx88_risc_stopper);
1188 EXPORT_SYMBOL(cx88_free_buffer);
1189
1190 EXPORT_SYMBOL(cx88_sram_channels);
1191 EXPORT_SYMBOL(cx88_sram_channel_setup);
1192 EXPORT_SYMBOL(cx88_sram_channel_dump);
1193
1194 EXPORT_SYMBOL(cx88_set_tvnorm);
1195 EXPORT_SYMBOL(cx88_set_scale);
1196
1197 EXPORT_SYMBOL(cx88_vdev_init);
1198 EXPORT_SYMBOL(cx88_core_get);
1199 EXPORT_SYMBOL(cx88_core_put);
1200
1201 /*
1202  * Local variables:
1203  * c-basic-offset: 8
1204  * End:
1205  */