Add linux-next specific files for 20110831
[linux-2.6/next.git] / drivers / media / video / cx88 / cx88-core.c
blobfbcaa1c5b09da7b43b7f54024a56c4ba7297e55f
1 /*
3 * device driver for Conexant 2388x based TV cards
4 * driver core
6 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
9 * - Multituner support
10 * - video_ioctl2 conversion
11 * - PAL/M fixes
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <linux/init.h>
29 #include <linux/list.h>
30 #include <linux/module.h>
31 #include <linux/kernel.h>
32 #include <linux/slab.h>
33 #include <linux/kmod.h>
34 #include <linux/sound.h>
35 #include <linux/interrupt.h>
36 #include <linux/pci.h>
37 #include <linux/delay.h>
38 #include <linux/videodev2.h>
39 #include <linux/mutex.h>
41 #include "cx88.h"
42 #include <media/v4l2-common.h>
43 #include <media/v4l2-ioctl.h>
45 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
46 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
47 MODULE_LICENSE("GPL");
49 /* ------------------------------------------------------------------ */
51 static unsigned int core_debug;
52 module_param(core_debug,int,0644);
53 MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
55 static unsigned int nicam;
56 module_param(nicam,int,0644);
57 MODULE_PARM_DESC(nicam,"tv audio is nicam");
59 static unsigned int nocomb;
60 module_param(nocomb,int,0644);
61 MODULE_PARM_DESC(nocomb,"disable comb filter");
63 #define dprintk(level,fmt, arg...) if (core_debug >= level) \
64 printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
66 static unsigned int cx88_devcount;
67 static LIST_HEAD(cx88_devlist);
68 static DEFINE_MUTEX(devlist);
70 #define NO_SYNC_LINE (-1U)
72 /* @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be
73 generated _after_ lpi lines are transferred. */
74 static __le32* cx88_risc_field(__le32 *rp, struct scatterlist *sglist,
75 unsigned int offset, u32 sync_line,
76 unsigned int bpl, unsigned int padding,
77 unsigned int lines, unsigned int lpi)
79 struct scatterlist *sg;
80 unsigned int line,todo,sol;
82 /* sync instruction */
83 if (sync_line != NO_SYNC_LINE)
84 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
86 /* scan lines */
87 sg = sglist;
88 for (line = 0; line < lines; line++) {
89 while (offset && offset >= sg_dma_len(sg)) {
90 offset -= sg_dma_len(sg);
91 sg++;
93 if (lpi && line>0 && !(line % lpi))
94 sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
95 else
96 sol = RISC_SOL;
97 if (bpl <= sg_dma_len(sg)-offset) {
98 /* fits into current chunk */
99 *(rp++)=cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl);
100 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
101 offset+=bpl;
102 } else {
103 /* scanline needs to be split */
104 todo = bpl;
105 *(rp++)=cpu_to_le32(RISC_WRITE|sol|
106 (sg_dma_len(sg)-offset));
107 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
108 todo -= (sg_dma_len(sg)-offset);
109 offset = 0;
110 sg++;
111 while (todo > sg_dma_len(sg)) {
112 *(rp++)=cpu_to_le32(RISC_WRITE|
113 sg_dma_len(sg));
114 *(rp++)=cpu_to_le32(sg_dma_address(sg));
115 todo -= sg_dma_len(sg);
116 sg++;
118 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
119 *(rp++)=cpu_to_le32(sg_dma_address(sg));
120 offset += todo;
122 offset += padding;
125 return rp;
128 int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
129 struct scatterlist *sglist,
130 unsigned int top_offset, unsigned int bottom_offset,
131 unsigned int bpl, unsigned int padding, unsigned int lines)
133 u32 instructions,fields;
134 __le32 *rp;
135 int rc;
137 fields = 0;
138 if (UNSET != top_offset)
139 fields++;
140 if (UNSET != bottom_offset)
141 fields++;
143 /* estimate risc mem: worst case is one write per page border +
144 one write per scan line + syncs + jump (all 2 dwords). Padding
145 can cause next bpl to start close to a page border. First DMA
146 region may be smaller than PAGE_SIZE */
147 instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
148 instructions += 2;
149 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
150 return rc;
152 /* write risc instructions */
153 rp = risc->cpu;
154 if (UNSET != top_offset)
155 rp = cx88_risc_field(rp, sglist, top_offset, 0,
156 bpl, padding, lines, 0);
157 if (UNSET != bottom_offset)
158 rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
159 bpl, padding, lines, 0);
161 /* save pointer to jmp instruction address */
162 risc->jmp = rp;
163 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
164 return 0;
167 int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
168 struct scatterlist *sglist, unsigned int bpl,
169 unsigned int lines, unsigned int lpi)
171 u32 instructions;
172 __le32 *rp;
173 int rc;
175 /* estimate risc mem: worst case is one write per page border +
176 one write per scan line + syncs + jump (all 2 dwords). Here
177 there is no padding and no sync. First DMA region may be smaller
178 than PAGE_SIZE */
179 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
180 instructions += 1;
181 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
182 return rc;
184 /* write risc instructions */
185 rp = risc->cpu;
186 rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines, lpi);
188 /* save pointer to jmp instruction address */
189 risc->jmp = rp;
190 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
191 return 0;
194 int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
195 u32 reg, u32 mask, u32 value)
197 __le32 *rp;
198 int rc;
200 if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
201 return rc;
203 /* write risc instructions */
204 rp = risc->cpu;
205 *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2 | RISC_IMM);
206 *(rp++) = cpu_to_le32(reg);
207 *(rp++) = cpu_to_le32(value);
208 *(rp++) = cpu_to_le32(mask);
209 *(rp++) = cpu_to_le32(RISC_JUMP);
210 *(rp++) = cpu_to_le32(risc->dma);
211 return 0;
214 void
215 cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
217 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
219 BUG_ON(in_interrupt());
220 videobuf_waiton(q, &buf->vb, 0, 0);
221 videobuf_dma_unmap(q->dev, dma);
222 videobuf_dma_free(dma);
223 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
224 buf->vb.state = VIDEOBUF_NEEDS_INIT;
227 /* ------------------------------------------------------------------ */
228 /* our SRAM memory layout */
230 /* we are going to put all thr risc programs into host memory, so we
231 * can use the whole SDRAM for the DMA fifos. To simplify things, we
232 * use a static memory layout. That surely will waste memory in case
233 * we don't use all DMA channels at the same time (which will be the
234 * case most of the time). But that still gives us enough FIFO space
235 * to be able to deal with insane long pci latencies ...
237 * FIFO space allocations:
238 * channel 21 (y video) - 10.0k
239 * channel 22 (u video) - 2.0k
240 * channel 23 (v video) - 2.0k
241 * channel 24 (vbi) - 4.0k
242 * channels 25+26 (audio) - 4.0k
243 * channel 28 (mpeg) - 4.0k
244 * channel 27 (audio rds)- 3.0k
245 * TOTAL = 29.0k
247 * Every channel has 160 bytes control data (64 bytes instruction
248 * queue and 6 CDT entries), which is close to 2k total.
250 * Address layout:
251 * 0x0000 - 0x03ff CMDs / reserved
252 * 0x0400 - 0x0bff instruction queues + CDs
253 * 0x0c00 - FIFOs
256 const struct sram_channel const cx88_sram_channels[] = {
257 [SRAM_CH21] = {
258 .name = "video y / packed",
259 .cmds_start = 0x180040,
260 .ctrl_start = 0x180400,
261 .cdt = 0x180400 + 64,
262 .fifo_start = 0x180c00,
263 .fifo_size = 0x002800,
264 .ptr1_reg = MO_DMA21_PTR1,
265 .ptr2_reg = MO_DMA21_PTR2,
266 .cnt1_reg = MO_DMA21_CNT1,
267 .cnt2_reg = MO_DMA21_CNT2,
269 [SRAM_CH22] = {
270 .name = "video u",
271 .cmds_start = 0x180080,
272 .ctrl_start = 0x1804a0,
273 .cdt = 0x1804a0 + 64,
274 .fifo_start = 0x183400,
275 .fifo_size = 0x000800,
276 .ptr1_reg = MO_DMA22_PTR1,
277 .ptr2_reg = MO_DMA22_PTR2,
278 .cnt1_reg = MO_DMA22_CNT1,
279 .cnt2_reg = MO_DMA22_CNT2,
281 [SRAM_CH23] = {
282 .name = "video v",
283 .cmds_start = 0x1800c0,
284 .ctrl_start = 0x180540,
285 .cdt = 0x180540 + 64,
286 .fifo_start = 0x183c00,
287 .fifo_size = 0x000800,
288 .ptr1_reg = MO_DMA23_PTR1,
289 .ptr2_reg = MO_DMA23_PTR2,
290 .cnt1_reg = MO_DMA23_CNT1,
291 .cnt2_reg = MO_DMA23_CNT2,
293 [SRAM_CH24] = {
294 .name = "vbi",
295 .cmds_start = 0x180100,
296 .ctrl_start = 0x1805e0,
297 .cdt = 0x1805e0 + 64,
298 .fifo_start = 0x184400,
299 .fifo_size = 0x001000,
300 .ptr1_reg = MO_DMA24_PTR1,
301 .ptr2_reg = MO_DMA24_PTR2,
302 .cnt1_reg = MO_DMA24_CNT1,
303 .cnt2_reg = MO_DMA24_CNT2,
305 [SRAM_CH25] = {
306 .name = "audio from",
307 .cmds_start = 0x180140,
308 .ctrl_start = 0x180680,
309 .cdt = 0x180680 + 64,
310 .fifo_start = 0x185400,
311 .fifo_size = 0x001000,
312 .ptr1_reg = MO_DMA25_PTR1,
313 .ptr2_reg = MO_DMA25_PTR2,
314 .cnt1_reg = MO_DMA25_CNT1,
315 .cnt2_reg = MO_DMA25_CNT2,
317 [SRAM_CH26] = {
318 .name = "audio to",
319 .cmds_start = 0x180180,
320 .ctrl_start = 0x180720,
321 .cdt = 0x180680 + 64, /* same as audio IN */
322 .fifo_start = 0x185400, /* same as audio IN */
323 .fifo_size = 0x001000, /* same as audio IN */
324 .ptr1_reg = MO_DMA26_PTR1,
325 .ptr2_reg = MO_DMA26_PTR2,
326 .cnt1_reg = MO_DMA26_CNT1,
327 .cnt2_reg = MO_DMA26_CNT2,
329 [SRAM_CH28] = {
330 .name = "mpeg",
331 .cmds_start = 0x180200,
332 .ctrl_start = 0x1807C0,
333 .cdt = 0x1807C0 + 64,
334 .fifo_start = 0x186400,
335 .fifo_size = 0x001000,
336 .ptr1_reg = MO_DMA28_PTR1,
337 .ptr2_reg = MO_DMA28_PTR2,
338 .cnt1_reg = MO_DMA28_CNT1,
339 .cnt2_reg = MO_DMA28_CNT2,
341 [SRAM_CH27] = {
342 .name = "audio rds",
343 .cmds_start = 0x1801C0,
344 .ctrl_start = 0x180860,
345 .cdt = 0x180860 + 64,
346 .fifo_start = 0x187400,
347 .fifo_size = 0x000C00,
348 .ptr1_reg = MO_DMA27_PTR1,
349 .ptr2_reg = MO_DMA27_PTR2,
350 .cnt1_reg = MO_DMA27_CNT1,
351 .cnt2_reg = MO_DMA27_CNT2,
355 int cx88_sram_channel_setup(struct cx88_core *core,
356 const struct sram_channel *ch,
357 unsigned int bpl, u32 risc)
359 unsigned int i,lines;
360 u32 cdt;
362 bpl = (bpl + 7) & ~7; /* alignment */
363 cdt = ch->cdt;
364 lines = ch->fifo_size / bpl;
365 if (lines > 6)
366 lines = 6;
367 BUG_ON(lines < 2);
369 /* write CDT */
370 for (i = 0; i < lines; i++)
371 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
373 /* write CMDS */
374 cx_write(ch->cmds_start + 0, risc);
375 cx_write(ch->cmds_start + 4, cdt);
376 cx_write(ch->cmds_start + 8, (lines*16) >> 3);
377 cx_write(ch->cmds_start + 12, ch->ctrl_start);
378 cx_write(ch->cmds_start + 16, 64 >> 2);
379 for (i = 20; i < 64; i += 4)
380 cx_write(ch->cmds_start + i, 0);
382 /* fill registers */
383 cx_write(ch->ptr1_reg, ch->fifo_start);
384 cx_write(ch->ptr2_reg, cdt);
385 cx_write(ch->cnt1_reg, (bpl >> 3) -1);
386 cx_write(ch->cnt2_reg, (lines*16) >> 3);
388 dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
389 return 0;
392 /* ------------------------------------------------------------------ */
393 /* debug helper code */
395 static int cx88_risc_decode(u32 risc)
397 static const char * const instr[16] = {
398 [ RISC_SYNC >> 28 ] = "sync",
399 [ RISC_WRITE >> 28 ] = "write",
400 [ RISC_WRITEC >> 28 ] = "writec",
401 [ RISC_READ >> 28 ] = "read",
402 [ RISC_READC >> 28 ] = "readc",
403 [ RISC_JUMP >> 28 ] = "jump",
404 [ RISC_SKIP >> 28 ] = "skip",
405 [ RISC_WRITERM >> 28 ] = "writerm",
406 [ RISC_WRITECM >> 28 ] = "writecm",
407 [ RISC_WRITECR >> 28 ] = "writecr",
409 static int const incr[16] = {
410 [ RISC_WRITE >> 28 ] = 2,
411 [ RISC_JUMP >> 28 ] = 2,
412 [ RISC_WRITERM >> 28 ] = 3,
413 [ RISC_WRITECM >> 28 ] = 3,
414 [ RISC_WRITECR >> 28 ] = 4,
416 static const char * const bits[] = {
417 "12", "13", "14", "resync",
418 "cnt0", "cnt1", "18", "19",
419 "20", "21", "22", "23",
420 "irq1", "irq2", "eol", "sol",
422 int i;
424 printk("0x%08x [ %s", risc,
425 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
426 for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
427 if (risc & (1 << (i + 12)))
428 printk(" %s",bits[i]);
429 printk(" count=%d ]\n", risc & 0xfff);
430 return incr[risc >> 28] ? incr[risc >> 28] : 1;
434 void cx88_sram_channel_dump(struct cx88_core *core,
435 const struct sram_channel *ch)
437 static const char * const name[] = {
438 "initial risc",
439 "cdt base",
440 "cdt size",
441 "iq base",
442 "iq size",
443 "risc pc",
444 "iq wr ptr",
445 "iq rd ptr",
446 "cdt current",
447 "pci target",
448 "line / byte",
450 u32 risc;
451 unsigned int i,j,n;
453 printk("%s: %s - dma channel status dump\n",
454 core->name,ch->name);
455 for (i = 0; i < ARRAY_SIZE(name); i++)
456 printk("%s: cmds: %-12s: 0x%08x\n",
457 core->name,name[i],
458 cx_read(ch->cmds_start + 4*i));
459 for (n = 1, i = 0; i < 4; i++) {
460 risc = cx_read(ch->cmds_start + 4 * (i+11));
461 printk("%s: risc%d: ", core->name, i);
462 if (--n)
463 printk("0x%08x [ arg #%d ]\n", risc, n);
464 else
465 n = cx88_risc_decode(risc);
467 for (i = 0; i < 16; i += n) {
468 risc = cx_read(ch->ctrl_start + 4 * i);
469 printk("%s: iq %x: ", core->name, i);
470 n = cx88_risc_decode(risc);
471 for (j = 1; j < n; j++) {
472 risc = cx_read(ch->ctrl_start + 4 * (i+j));
473 printk("%s: iq %x: 0x%08x [ arg #%d ]\n",
474 core->name, i+j, risc, j);
478 printk("%s: fifo: 0x%08x -> 0x%x\n",
479 core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
480 printk("%s: ctrl: 0x%08x -> 0x%x\n",
481 core->name, ch->ctrl_start, ch->ctrl_start+6*16);
482 printk("%s: ptr1_reg: 0x%08x\n",
483 core->name,cx_read(ch->ptr1_reg));
484 printk("%s: ptr2_reg: 0x%08x\n",
485 core->name,cx_read(ch->ptr2_reg));
486 printk("%s: cnt1_reg: 0x%08x\n",
487 core->name,cx_read(ch->cnt1_reg));
488 printk("%s: cnt2_reg: 0x%08x\n",
489 core->name,cx_read(ch->cnt2_reg));
492 static const char *cx88_pci_irqs[32] = {
493 "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
494 "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
495 "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
496 "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
499 void cx88_print_irqbits(const char *name, const char *tag, const char *strings[],
500 int len, u32 bits, u32 mask)
502 unsigned int i;
504 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
505 for (i = 0; i < len; i++) {
506 if (!(bits & (1 << i)))
507 continue;
508 if (strings[i])
509 printk(" %s", strings[i]);
510 else
511 printk(" %d", i);
512 if (!(mask & (1 << i)))
513 continue;
514 printk("*");
516 printk("\n");
519 /* ------------------------------------------------------------------ */
521 int cx88_core_irq(struct cx88_core *core, u32 status)
523 int handled = 0;
525 if (status & PCI_INT_IR_SMPINT) {
526 cx88_ir_irq(core);
527 handled++;
529 if (!handled)
530 cx88_print_irqbits(core->name, "irq pci",
531 cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs),
532 status, core->pci_irqmask);
533 return handled;
536 void cx88_wakeup(struct cx88_core *core,
537 struct cx88_dmaqueue *q, u32 count)
539 struct cx88_buffer *buf;
540 int bc;
542 for (bc = 0;; bc++) {
543 if (list_empty(&q->active))
544 break;
545 buf = list_entry(q->active.next,
546 struct cx88_buffer, vb.queue);
547 /* count comes from the hw and is is 16bit wide --
548 * this trick handles wrap-arounds correctly for
549 * up to 32767 buffers in flight... */
550 if ((s16) (count - buf->count) < 0)
551 break;
552 do_gettimeofday(&buf->vb.ts);
553 dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
554 count, buf->count);
555 buf->vb.state = VIDEOBUF_DONE;
556 list_del(&buf->vb.queue);
557 wake_up(&buf->vb.done);
559 if (list_empty(&q->active)) {
560 del_timer(&q->timeout);
561 } else {
562 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
564 if (bc != 1)
565 dprintk(2, "%s: %d buffers handled (should be 1)\n",
566 __func__, bc);
569 void cx88_shutdown(struct cx88_core *core)
571 /* disable RISC controller + IRQs */
572 cx_write(MO_DEV_CNTRL2, 0);
574 /* stop dma transfers */
575 cx_write(MO_VID_DMACNTRL, 0x0);
576 cx_write(MO_AUD_DMACNTRL, 0x0);
577 cx_write(MO_TS_DMACNTRL, 0x0);
578 cx_write(MO_VIP_DMACNTRL, 0x0);
579 cx_write(MO_GPHST_DMACNTRL, 0x0);
581 /* stop interrupts */
582 cx_write(MO_PCI_INTMSK, 0x0);
583 cx_write(MO_VID_INTMSK, 0x0);
584 cx_write(MO_AUD_INTMSK, 0x0);
585 cx_write(MO_TS_INTMSK, 0x0);
586 cx_write(MO_VIP_INTMSK, 0x0);
587 cx_write(MO_GPHST_INTMSK, 0x0);
589 /* stop capturing */
590 cx_write(VID_CAPTURE_CONTROL, 0);
593 int cx88_reset(struct cx88_core *core)
595 dprintk(1,"%s\n",__func__);
596 cx88_shutdown(core);
598 /* clear irq status */
599 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
600 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
601 cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
603 /* wait a bit */
604 msleep(100);
606 /* init sram */
607 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0);
608 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
609 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
610 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
611 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
612 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
613 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
614 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0);
616 /* misc init ... */
617 cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable
618 (1 << 12) | // agc gain
619 (1 << 11) | // adaptibe agc
620 (0 << 10) | // chroma agc
621 (0 << 9) | // ckillen
622 (7)));
624 /* setup image format */
625 cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
627 /* setup FIFO Thresholds */
628 cx_write(MO_PDMA_STHRSH, 0x0807);
629 cx_write(MO_PDMA_DTHRSH, 0x0807);
631 /* fixes flashing of image */
632 cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
633 cx_write(MO_AGC_BACK_VBI, 0x00E00555);
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 /* set default notch filter */
640 cx_andor(MO_HTOTAL, 0x1800, (HLNotchFilter4xFsc << 11));
642 /* Reset on-board parts */
643 cx_write(MO_SRST_IO, 0);
644 msleep(10);
645 cx_write(MO_SRST_IO, 1);
647 return 0;
650 /* ------------------------------------------------------------------ */
652 static unsigned int inline norm_swidth(v4l2_std_id norm)
654 return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
657 static unsigned int inline norm_hdelay(v4l2_std_id norm)
659 return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
662 static unsigned int inline norm_vdelay(v4l2_std_id norm)
664 return (norm & V4L2_STD_625_50) ? 0x24 : 0x18;
667 static unsigned int inline norm_fsc8(v4l2_std_id norm)
669 if (norm & V4L2_STD_PAL_M)
670 return 28604892; // 3.575611 MHz
672 if (norm & (V4L2_STD_PAL_Nc))
673 return 28656448; // 3.582056 MHz
675 if (norm & V4L2_STD_NTSC) // All NTSC/M and variants
676 return 28636360; // 3.57954545 MHz +/- 10 Hz
678 /* SECAM have also different sub carrier for chroma,
679 but step_db and step_dr, at cx88_set_tvnorm already handles that.
681 The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N
684 return 35468950; // 4.43361875 MHz +/- 5 Hz
687 static unsigned int inline norm_htotal(v4l2_std_id norm)
690 unsigned int fsc4=norm_fsc8(norm)/2;
692 /* returns 4*FSC / vtotal / frames per seconds */
693 return (norm & V4L2_STD_625_50) ?
694 ((fsc4+312)/625+12)/25 :
695 ((fsc4+262)/525*1001+15000)/30000;
698 static unsigned int inline norm_vbipack(v4l2_std_id norm)
700 return (norm & V4L2_STD_625_50) ? 511 : 400;
703 int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
704 enum v4l2_field field)
706 unsigned int swidth = norm_swidth(core->tvnorm);
707 unsigned int sheight = norm_maxh(core->tvnorm);
708 u32 value;
710 dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
711 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
712 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
713 v4l2_norm_to_name(core->tvnorm));
714 if (!V4L2_FIELD_HAS_BOTH(field))
715 height *= 2;
717 // recalc H delay and scale registers
718 value = (width * norm_hdelay(core->tvnorm)) / swidth;
719 value &= 0x3fe;
720 cx_write(MO_HDELAY_EVEN, value);
721 cx_write(MO_HDELAY_ODD, value);
722 dprintk(1,"set_scale: hdelay 0x%04x (width %d)\n", value,swidth);
724 value = (swidth * 4096 / width) - 4096;
725 cx_write(MO_HSCALE_EVEN, value);
726 cx_write(MO_HSCALE_ODD, value);
727 dprintk(1,"set_scale: hscale 0x%04x\n", value);
729 cx_write(MO_HACTIVE_EVEN, width);
730 cx_write(MO_HACTIVE_ODD, width);
731 dprintk(1,"set_scale: hactive 0x%04x\n", width);
733 // recalc V scale Register (delay is constant)
734 cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
735 cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm));
736 dprintk(1,"set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm));
738 value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
739 cx_write(MO_VSCALE_EVEN, value);
740 cx_write(MO_VSCALE_ODD, value);
741 dprintk(1,"set_scale: vscale 0x%04x\n", value);
743 cx_write(MO_VACTIVE_EVEN, sheight);
744 cx_write(MO_VACTIVE_ODD, sheight);
745 dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
747 // setup filters
748 value = 0;
749 value |= (1 << 19); // CFILT (default)
750 if (core->tvnorm & V4L2_STD_SECAM) {
751 value |= (1 << 15);
752 value |= (1 << 16);
754 if (INPUT(core->input).type == CX88_VMUX_SVIDEO)
755 value |= (1 << 13) | (1 << 5);
756 if (V4L2_FIELD_INTERLACED == field)
757 value |= (1 << 3); // VINT (interlaced vertical scaling)
758 if (width < 385)
759 value |= (1 << 0); // 3-tap interpolation
760 if (width < 193)
761 value |= (1 << 1); // 5-tap interpolation
762 if (nocomb)
763 value |= (3 << 5); // disable comb filter
765 cx_andor(MO_FILTER_EVEN, 0x7ffc7f, value); /* preserve PEAKEN, PSEL */
766 cx_andor(MO_FILTER_ODD, 0x7ffc7f, value);
767 dprintk(1,"set_scale: filter 0x%04x\n", value);
769 return 0;
772 static const u32 xtal = 28636363;
774 static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
776 static const u32 pre[] = { 0, 0, 0, 3, 2, 1 };
777 u64 pll;
778 u32 reg;
779 int i;
781 if (prescale < 2)
782 prescale = 2;
783 if (prescale > 5)
784 prescale = 5;
786 pll = ofreq * 8 * prescale * (u64)(1 << 20);
787 do_div(pll,xtal);
788 reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
789 if (((reg >> 20) & 0x3f) < 14) {
790 printk("%s/0: pll out of range\n",core->name);
791 return -1;
794 dprintk(1,"set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n",
795 reg, cx_read(MO_PLL_REG), ofreq);
796 cx_write(MO_PLL_REG, reg);
797 for (i = 0; i < 100; i++) {
798 reg = cx_read(MO_DEVICE_STATUS);
799 if (reg & (1<<2)) {
800 dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",
801 prescale,ofreq);
802 return 0;
804 dprintk(1,"pll not locked yet, waiting ...\n");
805 msleep(10);
807 dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
808 return -1;
811 int cx88_start_audio_dma(struct cx88_core *core)
813 /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
814 int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
816 int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size/AUD_RDS_LINES;
818 /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
819 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
820 return 0;
822 /* setup fifo + format */
823 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
824 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
825 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27],
826 rds_bpl, 0);
828 cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
829 cx_write(MO_AUDR_LNGTH, rds_bpl); /* fifo bpl size */
831 /* enable Up, Down and Audio RDS fifo */
832 cx_write(MO_AUD_DMACNTRL, 0x0007);
834 return 0;
837 int cx88_stop_audio_dma(struct cx88_core *core)
839 /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
840 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
841 return 0;
843 /* stop dma */
844 cx_write(MO_AUD_DMACNTRL, 0x0000);
846 return 0;
849 static int set_tvaudio(struct cx88_core *core)
851 v4l2_std_id norm = core->tvnorm;
853 if (CX88_VMUX_TELEVISION != INPUT(core->input).type &&
854 CX88_VMUX_CABLE != INPUT(core->input).type)
855 return 0;
857 if (V4L2_STD_PAL_BG & norm) {
858 core->tvaudio = WW_BG;
860 } else if (V4L2_STD_PAL_DK & norm) {
861 core->tvaudio = WW_DK;
863 } else if (V4L2_STD_PAL_I & norm) {
864 core->tvaudio = WW_I;
866 } else if (V4L2_STD_SECAM_L & norm) {
867 core->tvaudio = WW_L;
869 } else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) & norm) {
870 core->tvaudio = WW_BG;
872 } else if (V4L2_STD_SECAM_DK & norm) {
873 core->tvaudio = WW_DK;
875 } else if ((V4L2_STD_NTSC_M & norm) ||
876 (V4L2_STD_PAL_M & norm)) {
877 core->tvaudio = WW_BTSC;
879 } else if (V4L2_STD_NTSC_M_JP & norm) {
880 core->tvaudio = WW_EIAJ;
882 } else {
883 printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
884 core->name, v4l2_norm_to_name(core->tvnorm));
885 core->tvaudio = WW_NONE;
886 return 0;
889 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
890 cx88_set_tvaudio(core);
891 /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
894 This should be needed only on cx88-alsa. It seems that some cx88 chips have
895 bugs and does require DMA enabled for it to work.
897 cx88_start_audio_dma(core);
898 return 0;
903 int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
905 u32 fsc8;
906 u32 adc_clock;
907 u32 vdec_clock;
908 u32 step_db,step_dr;
909 u64 tmp64;
910 u32 bdelay,agcdelay,htotal;
911 u32 cxiformat, cxoformat;
913 core->tvnorm = norm;
914 fsc8 = norm_fsc8(norm);
915 adc_clock = xtal;
916 vdec_clock = fsc8;
917 step_db = fsc8;
918 step_dr = fsc8;
920 if (norm & V4L2_STD_NTSC_M_JP) {
921 cxiformat = VideoFormatNTSCJapan;
922 cxoformat = 0x181f0008;
923 } else if (norm & V4L2_STD_NTSC_443) {
924 cxiformat = VideoFormatNTSC443;
925 cxoformat = 0x181f0008;
926 } else if (norm & V4L2_STD_PAL_M) {
927 cxiformat = VideoFormatPALM;
928 cxoformat = 0x1c1f0008;
929 } else if (norm & V4L2_STD_PAL_N) {
930 cxiformat = VideoFormatPALN;
931 cxoformat = 0x1c1f0008;
932 } else if (norm & V4L2_STD_PAL_Nc) {
933 cxiformat = VideoFormatPALNC;
934 cxoformat = 0x1c1f0008;
935 } else if (norm & V4L2_STD_PAL_60) {
936 cxiformat = VideoFormatPAL60;
937 cxoformat = 0x181f0008;
938 } else if (norm & V4L2_STD_NTSC) {
939 cxiformat = VideoFormatNTSC;
940 cxoformat = 0x181f0008;
941 } else if (norm & V4L2_STD_SECAM) {
942 step_db = 4250000 * 8;
943 step_dr = 4406250 * 8;
945 cxiformat = VideoFormatSECAM;
946 cxoformat = 0x181f0008;
947 } else { /* PAL */
948 cxiformat = VideoFormatPAL;
949 cxoformat = 0x181f0008;
952 dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
953 v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock,
954 step_db, step_dr);
955 set_pll(core,2,vdec_clock);
957 dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n",
958 cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
959 /* Chroma AGC must be disabled if SECAM is used, we enable it
960 by default on PAL and NTSC */
961 cx_andor(MO_INPUT_FORMAT, 0x40f,
962 norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400);
964 // FIXME: as-is from DScaler
965 dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
966 cxoformat, cx_read(MO_OUTPUT_FORMAT));
967 cx_write(MO_OUTPUT_FORMAT, cxoformat);
969 // MO_SCONV_REG = adc clock / video dec clock * 2^17
970 tmp64 = adc_clock * (u64)(1 << 17);
971 do_div(tmp64, vdec_clock);
972 dprintk(1,"set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n",
973 (u32)tmp64, cx_read(MO_SCONV_REG));
974 cx_write(MO_SCONV_REG, (u32)tmp64);
976 // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
977 tmp64 = step_db * (u64)(1 << 22);
978 do_div(tmp64, vdec_clock);
979 dprintk(1,"set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n",
980 (u32)tmp64, cx_read(MO_SUB_STEP));
981 cx_write(MO_SUB_STEP, (u32)tmp64);
983 // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
984 tmp64 = step_dr * (u64)(1 << 22);
985 do_div(tmp64, vdec_clock);
986 dprintk(1,"set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n",
987 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
988 cx_write(MO_SUB_STEP_DR, (u32)tmp64);
990 // bdelay + agcdelay
991 bdelay = vdec_clock * 65 / 20000000 + 21;
992 agcdelay = vdec_clock * 68 / 20000000 + 15;
993 dprintk(1,"set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
994 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay);
995 cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
997 // htotal
998 tmp64 = norm_htotal(norm) * (u64)vdec_clock;
999 do_div(tmp64, fsc8);
1000 htotal = (u32)tmp64;
1001 dprintk(1,"set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n",
1002 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
1003 cx_andor(MO_HTOTAL, 0x07ff, htotal);
1005 // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
1006 // the effective vbi offset ~244 samples, the same as the Bt8x8
1007 cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm));
1009 // this is needed as well to set all tvnorm parameter
1010 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
1012 // audio
1013 set_tvaudio(core);
1015 // tell i2c chips
1016 call_all(core, core, s_std, norm);
1018 // done
1019 return 0;
1022 /* ------------------------------------------------------------------ */
1024 struct video_device *cx88_vdev_init(struct cx88_core *core,
1025 struct pci_dev *pci,
1026 const struct video_device *template_,
1027 const char *type)
1029 struct video_device *vfd;
1031 vfd = video_device_alloc();
1032 if (NULL == vfd)
1033 return NULL;
1034 *vfd = *template_;
1035 vfd->v4l2_dev = &core->v4l2_dev;
1036 vfd->parent = &pci->dev;
1037 vfd->release = video_device_release;
1038 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1039 core->name, type, core->board.name);
1040 return vfd;
1043 struct cx88_core* cx88_core_get(struct pci_dev *pci)
1045 struct cx88_core *core;
1047 mutex_lock(&devlist);
1048 list_for_each_entry(core, &cx88_devlist, devlist) {
1049 if (pci->bus->number != core->pci_bus)
1050 continue;
1051 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1052 continue;
1054 if (0 != cx88_get_resources(core, pci)) {
1055 mutex_unlock(&devlist);
1056 return NULL;
1058 atomic_inc(&core->refcount);
1059 mutex_unlock(&devlist);
1060 return core;
1063 core = cx88_core_create(pci, cx88_devcount);
1064 if (NULL != core) {
1065 cx88_devcount++;
1066 list_add_tail(&core->devlist, &cx88_devlist);
1069 mutex_unlock(&devlist);
1070 return core;
1073 void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1075 release_mem_region(pci_resource_start(pci,0),
1076 pci_resource_len(pci,0));
1078 if (!atomic_dec_and_test(&core->refcount))
1079 return;
1081 mutex_lock(&devlist);
1082 cx88_ir_fini(core);
1083 if (0 == core->i2c_rc) {
1084 if (core->i2c_rtc)
1085 i2c_unregister_device(core->i2c_rtc);
1086 i2c_del_adapter(&core->i2c_adap);
1088 list_del(&core->devlist);
1089 iounmap(core->lmmio);
1090 cx88_devcount--;
1091 mutex_unlock(&devlist);
1092 v4l2_device_unregister(&core->v4l2_dev);
1093 kfree(core);
1096 /* ------------------------------------------------------------------ */
1098 EXPORT_SYMBOL(cx88_print_irqbits);
1100 EXPORT_SYMBOL(cx88_core_irq);
1101 EXPORT_SYMBOL(cx88_wakeup);
1102 EXPORT_SYMBOL(cx88_reset);
1103 EXPORT_SYMBOL(cx88_shutdown);
1105 EXPORT_SYMBOL(cx88_risc_buffer);
1106 EXPORT_SYMBOL(cx88_risc_databuffer);
1107 EXPORT_SYMBOL(cx88_risc_stopper);
1108 EXPORT_SYMBOL(cx88_free_buffer);
1110 EXPORT_SYMBOL(cx88_sram_channels);
1111 EXPORT_SYMBOL(cx88_sram_channel_setup);
1112 EXPORT_SYMBOL(cx88_sram_channel_dump);
1114 EXPORT_SYMBOL(cx88_set_tvnorm);
1115 EXPORT_SYMBOL(cx88_set_scale);
1117 EXPORT_SYMBOL(cx88_vdev_init);
1118 EXPORT_SYMBOL(cx88_core_get);
1119 EXPORT_SYMBOL(cx88_core_put);
1121 EXPORT_SYMBOL(cx88_ir_start);
1122 EXPORT_SYMBOL(cx88_ir_stop);
1125 * Local variables:
1126 * c-basic-offset: 8
1127 * End:
1128 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off