[PATCH] W1: w1_netlink: New init/fini netlink callbacks.
[linux-2.6/verdex.git] / drivers / media / video / cx88 / cx88-core.c
blob5e868f5cd0c0bae1cc84c9dfd2872b59694ba914
1 /*
2 * $Id: cx88-core.c,v 1.33 2005/07/07 14:17:47 mchehab Exp $
4 * device driver for Conexant 2388x based TV cards
5 * driver core
7 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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.
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.
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.
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>
37 #include "cx88.h"
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");
43 /* ------------------------------------------------------------------ */
45 static unsigned int core_debug = 0;
46 module_param(core_debug,int,0644);
47 MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
49 static unsigned int latency = UNSET;
50 module_param(latency,int,0444);
51 MODULE_PARM_DESC(latency,"pci latency timer");
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 };
57 module_param_array(tuner, int, NULL, 0444);
58 module_param_array(radio, int, NULL, 0444);
59 module_param_array(card, int, NULL, 0444);
61 MODULE_PARM_DESC(tuner,"tuner type");
62 MODULE_PARM_DESC(radio,"radio tuner type");
63 MODULE_PARM_DESC(card,"card type");
65 static unsigned int nicam = 0;
66 module_param(nicam,int,0644);
67 MODULE_PARM_DESC(nicam,"tv audio is nicam");
69 static unsigned int nocomb = 0;
70 module_param(nocomb,int,0644);
71 MODULE_PARM_DESC(nocomb,"disable comb filter");
73 #define dprintk(level,fmt, arg...) if (core_debug >= level) \
74 printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
76 static unsigned int cx88_devcount;
77 static LIST_HEAD(cx88_devlist);
78 static DECLARE_MUTEX(devlist);
80 /* ------------------------------------------------------------------ */
81 /* debug help functions */
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)
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"
103 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
105 void cx88_print_ioctl(char *name, unsigned int cmd)
107 char *dir;
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;
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));
133 /* ------------------------------------------------------------------ */
134 #define NO_SYNC_LINE (-1U)
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)
141 struct scatterlist *sg;
142 unsigned int line,todo;
144 /* sync instruction */
145 if (sync_line != NO_SYNC_LINE)
146 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
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++;
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++;
176 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
177 *(rp++)=cpu_to_le32(sg_dma_address(sg));
178 offset += todo;
180 offset += padding;
183 return rp;
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)
191 u32 instructions,fields;
192 u32 *rp;
193 int rc;
195 fields = 0;
196 if (UNSET != top_offset)
197 fields++;
198 if (UNSET != bottom_offset)
199 fields++;
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;
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);
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;
223 int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
224 struct scatterlist *sglist, unsigned int bpl,
225 unsigned int lines)
227 u32 instructions;
228 u32 *rp;
229 int rc;
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;
238 /* write risc instructions */
239 rp = risc->cpu;
240 rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines);
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;
248 int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
249 u32 reg, u32 mask, u32 value)
251 u32 *rp;
252 int rc;
254 if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
255 return rc;
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;
268 void
269 cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
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;
280 /* ------------------------------------------------------------------ */
281 /* our SRAM memory layout */
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 ...
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
299 * Every channel has 160 bytes control data (64 bytes instruction
300 * queue and 6 CDT entries), which is close to 2k total.
302 * Address layout:
303 * 0x0000 - 0x03ff CMDs / reserved
304 * 0x0400 - 0x0bff instruction queues + CDs
305 * 0x0c00 - FIFOs
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,
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,
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,
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,
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,
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,
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,
395 int cx88_sram_channel_setup(struct cx88_core *core,
396 struct sram_channel *ch,
397 unsigned int bpl, u32 risc)
399 unsigned int i,lines;
400 u32 cdt;
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);
409 /* write CDT */
410 for (i = 0; i < lines; i++)
411 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
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);
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);
428 dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
429 return 0;
432 /* ------------------------------------------------------------------ */
433 /* debug helper code */
435 int cx88_risc_decode(u32 risc)
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",
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,
456 static char *bits[] = {
457 "12", "13", "14", "resync",
458 "cnt0", "cnt1", "18", "19",
459 "20", "21", "22", "23",
460 "irq1", "irq2", "eol", "sol",
462 int i;
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;
474 void cx88_sram_channel_dump(struct cx88_core *core,
475 struct sram_channel *ch)
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",
490 u32 risc;
491 unsigned int i,j,n;
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);
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);
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));
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"
536 void cx88_print_irqbits(char *name, char *tag, char **strings,
537 u32 bits, u32 mask)
539 unsigned int i;
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("*");
553 printk("\n");
556 /* ------------------------------------------------------------------ */
558 int cx88_core_irq(struct cx88_core *core, u32 status)
560 int handled = 0;
562 if (status & (1<<18)) {
563 cx88_ir_irq(core);
564 handled++;
566 if (!handled)
567 cx88_print_irqbits(core->name, "irq pci",
568 cx88_pci_irqs, status,
569 core->pci_irqmask);
570 return handled;
573 void cx88_wakeup(struct cx88_core *core,
574 struct cx88_dmaqueue *q, u32 count)
576 struct cx88_buffer *buf;
577 int bc;
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);
596 if (list_empty(&q->active)) {
597 del_timer(&q->timeout);
598 } else {
599 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
601 if (bc != 1)
602 printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
605 void cx88_shutdown(struct cx88_core *core)
607 /* disable RISC controller + IRQs */
608 cx_write(MO_DEV_CNTRL2, 0);
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);
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);
625 /* stop capturing */
626 cx_write(VID_CAPTURE_CONTROL, 0);
629 int cx88_reset(struct cx88_core *core)
631 dprintk(1,"%s\n",__FUNCTION__);
632 cx88_shutdown(core);
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
639 /* wait a bit */
640 msleep(100);
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);
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)));
659 /* setup image format */
660 cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
662 /* setup FIFO Threshholds */
663 cx_write(MO_PDMA_STHRSH, 0x0807);
664 cx_write(MO_PDMA_DTHRSH, 0x0807);
666 /* fixes flashing of image */
667 cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
668 cx_write(MO_AGC_BACK_VBI, 0x00E00555);
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
674 /* Reset on-board parts */
675 cx_write(MO_SRST_IO, 0);
676 msleep(10);
677 cx_write(MO_SRST_IO, 1);
679 return 0;
682 /* ------------------------------------------------------------------ */
684 static unsigned int inline norm_swidth(struct cx88_tvnorm *norm)
686 return (norm->id & V4L2_STD_625_50) ? 922 : 754;
689 static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm)
691 return (norm->id & V4L2_STD_625_50) ? 186 : 135;
694 static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
696 return (norm->id & V4L2_STD_625_50) ? 0x24 : 0x18;
699 static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
701 static const unsigned int ntsc = 28636360;
702 static const unsigned int pal = 35468950;
703 static const unsigned int palm = 28604892;
705 if (norm->id & V4L2_STD_PAL_M)
706 return palm;
708 return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
711 static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm)
713 return (norm->id & V4L2_STD_625_50)
714 ? HLNotchFilter135PAL
715 : HLNotchFilter135NTSC;
718 static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
720 /* Should always be Line Draw Time / (4*FSC) */
722 if (norm->id & V4L2_STD_PAL_M)
723 return 909;
725 return (norm->id & V4L2_STD_625_50) ? 1135 : 910;
728 static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
730 return (norm->id & V4L2_STD_625_50) ? 511 : 288;
733 int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
734 enum v4l2_field field)
736 unsigned int swidth = norm_swidth(core->tvnorm);
737 unsigned int sheight = norm_maxh(core->tvnorm);
738 u32 value;
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;
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);
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);
759 cx_write(MO_HACTIVE_EVEN, width);
760 cx_write(MO_HACTIVE_ODD, width);
761 dprintk(1,"set_scale: hactive 0x%04x\n", width);
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));
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);
773 cx_write(MO_VACTIVE_EVEN, sheight);
774 cx_write(MO_VACTIVE_ODD, sheight);
775 dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
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);
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
795 cx_write(MO_FILTER_EVEN, value);
796 cx_write(MO_FILTER_ODD, value);
797 dprintk(1,"set_scale: filter 0x%04x\n", value);
799 return 0;
802 static const u32 xtal = 28636363;
804 static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
806 static u32 pre[] = { 0, 0, 0, 3, 2, 1 };
807 u64 pll;
808 u32 reg;
809 int i;
811 if (prescale < 2)
812 prescale = 2;
813 if (prescale > 5)
814 prescale = 5;
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;
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;
834 dprintk(1,"pll not locked yet, waiting ...\n");
835 msleep(10);
837 dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
838 return -1;
841 static int set_tvaudio(struct cx88_core *core)
843 struct cx88_tvnorm *norm = core->tvnorm;
845 if (CX88_VMUX_TELEVISION != INPUT(core->input)->type)
846 return 0;
848 if (V4L2_STD_PAL_BG & norm->id) {
849 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG;
851 } else if (V4L2_STD_PAL_DK & norm->id) {
852 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK;
854 } else if (V4L2_STD_PAL_I & norm->id) {
855 core->tvaudio = WW_NICAM_I;
857 } else if (V4L2_STD_SECAM_L & norm->id) {
858 core->tvaudio = WW_SYSTEM_L_AM;
860 } else if (V4L2_STD_SECAM_DK & norm->id) {
861 core->tvaudio = WW_A2_DK;
863 } else if ((V4L2_STD_NTSC_M & norm->id) ||
864 (V4L2_STD_PAL_M & norm->id)) {
865 core->tvaudio = WW_BTSC;
867 } else if (V4L2_STD_NTSC_M_JP & norm->id) {
868 core->tvaudio = WW_EIAJ;
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;
877 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
878 cx88_set_tvaudio(core);
879 // cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO);
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;
887 int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
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;
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;
903 if (norm->id & V4L2_STD_SECAM) {
904 step_db = 4250000 * 8;
905 step_dr = 4406250 * 8;
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);
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);
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);
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);
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);
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);
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);
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);
957 // vbi stuff
958 cx_write(MO_VBI_PACKET, ((1 << 11) | /* (norm_vdelay(norm) << 11) | */
959 norm_vbipack(norm)));
961 // this is needed as well to set all tvnorm parameter
962 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
964 // audio
965 set_tvaudio(core);
967 // tell i2c chips
968 cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id);
970 // done
971 return 0;
974 /* ------------------------------------------------------------------ */
976 static int cx88_pci_quirks(char *name, struct pci_dev *pci)
978 unsigned int lat = UNSET;
979 u8 ctrl = 0;
980 u8 value;
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;
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;
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;
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;
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;
1009 #endif
1011 /* check insmod options */
1012 if (UNSET != latency)
1013 lat = latency;
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);
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);
1026 return 0;
1029 /* ------------------------------------------------------------------ */
1031 struct video_device *cx88_vdev_init(struct cx88_core *core,
1032 struct pci_dev *pci,
1033 struct video_device *template,
1034 char *type)
1036 struct video_device *vfd;
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;
1050 static int get_ressources(struct cx88_core *core, struct pci_dev *pci)
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;
1061 struct cx88_core* cx88_core_get(struct pci_dev *pci)
1063 struct cx88_core *core;
1064 struct list_head *item;
1065 int i;
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;
1075 if (0 != get_ressources(core,pci))
1076 goto fail_unlock;
1077 atomic_inc(&core->refcount);
1078 up(&devlist);
1079 return core;
1081 core = kmalloc(sizeof(*core),GFP_KERNEL);
1082 if (NULL == core)
1083 goto fail_unlock;
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;
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;
1097 list_add_tail(&core->devlist,&cx88_devlist);
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;
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);
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");
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;
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);
1138 core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
1140 /* init hardware */
1141 cx88_reset(core);
1142 cx88_i2c_init(core,pci);
1143 cx88_card_setup(core);
1144 cx88_ir_init(core,pci);
1146 up(&devlist);
1147 return core;
1149 fail_free:
1150 kfree(core);
1151 fail_unlock:
1152 up(&devlist);
1153 return NULL;
1156 void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1158 release_mem_region(pci_resource_start(pci,0),
1159 pci_resource_len(pci,0));
1161 if (!atomic_dec_and_test(&core->refcount))
1162 return;
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);
1175 /* ------------------------------------------------------------------ */
1177 EXPORT_SYMBOL(cx88_print_ioctl);
1178 EXPORT_SYMBOL(cx88_print_irqbits);
1180 EXPORT_SYMBOL(cx88_core_irq);
1181 EXPORT_SYMBOL(cx88_wakeup);
1182 EXPORT_SYMBOL(cx88_reset);
1183 EXPORT_SYMBOL(cx88_shutdown);
1185 EXPORT_SYMBOL(cx88_risc_buffer);
1186 EXPORT_SYMBOL(cx88_risc_databuffer);
1187 EXPORT_SYMBOL(cx88_risc_stopper);
1188 EXPORT_SYMBOL(cx88_free_buffer);
1190 EXPORT_SYMBOL(cx88_sram_channels);
1191 EXPORT_SYMBOL(cx88_sram_channel_setup);
1192 EXPORT_SYMBOL(cx88_sram_channel_dump);
1194 EXPORT_SYMBOL(cx88_set_tvnorm);
1195 EXPORT_SYMBOL(cx88_set_scale);
1197 EXPORT_SYMBOL(cx88_vdev_init);
1198 EXPORT_SYMBOL(cx88_core_get);
1199 EXPORT_SYMBOL(cx88_core_put);
1202 * Local variables:
1203 * c-basic-offset: 8
1204 * End: