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