1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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>
40
41#include "cx88.h"
42#include <media/v4l2-common.h>
43#include <media/v4l2-ioctl.h>
44
45MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
46MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
47MODULE_LICENSE("GPL");
48
49
50
51static unsigned int core_debug;
52module_param(core_debug,int,0644);
53MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
54
55static unsigned int nicam;
56module_param(nicam,int,0644);
57MODULE_PARM_DESC(nicam,"tv audio is nicam");
58
59static unsigned int nocomb;
60module_param(nocomb,int,0644);
61MODULE_PARM_DESC(nocomb,"disable comb filter");
62
63#define dprintk(level,fmt, arg...) if (core_debug >= level) \
64 printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
65
66static unsigned int cx88_devcount;
67static LIST_HEAD(cx88_devlist);
68static DEFINE_MUTEX(devlist);
69
70#define NO_SYNC_LINE (-1U)
71
72
73
74static __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)
78{
79 struct scatterlist *sg;
80 unsigned int line,todo,sol;
81
82
83 if (sync_line != NO_SYNC_LINE)
84 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
85
86
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++;
92 }
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
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
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++;
117 }
118 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
119 *(rp++)=cpu_to_le32(sg_dma_address(sg));
120 offset += todo;
121 }
122 offset += padding;
123 }
124
125 return rp;
126}
127
128int 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)
132{
133 u32 instructions,fields;
134 __le32 *rp;
135 int rc;
136
137 fields = 0;
138 if (UNSET != top_offset)
139 fields++;
140 if (UNSET != bottom_offset)
141 fields++;
142
143
144
145
146
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;
151
152
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);
160
161
162 risc->jmp = rp;
163 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
164 return 0;
165}
166
167int 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)
170{
171 u32 instructions;
172 __le32 *rp;
173 int rc;
174
175
176
177
178
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;
183
184
185 rp = risc->cpu;
186 rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines, lpi);
187
188
189 risc->jmp = rp;
190 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
191 return 0;
192}
193
194int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
195 u32 reg, u32 mask, u32 value)
196{
197 __le32 *rp;
198 int rc;
199
200 if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
201 return rc;
202
203
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;
212}
213
214void
215cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
216{
217 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
218
219 BUG_ON(in_interrupt());
220 videobuf_waiton(&buf->vb,0,0);
221 videobuf_dma_unmap(q, dma);
222 videobuf_dma_free(dma);
223 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
224 buf->vb.state = VIDEOBUF_NEEDS_INIT;
225}
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256struct sram_channel 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,
268 },
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,
280 },
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,
292 },
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,
304 },
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,
316 },
317 [SRAM_CH26] = {
318 .name = "audio to",
319 .cmds_start = 0x180180,
320 .ctrl_start = 0x180720,
321 .cdt = 0x180680 + 64,
322 .fifo_start = 0x185400,
323 .fifo_size = 0x001000,
324 .ptr1_reg = MO_DMA26_PTR1,
325 .ptr2_reg = MO_DMA26_PTR2,
326 .cnt1_reg = MO_DMA26_CNT1,
327 .cnt2_reg = MO_DMA26_CNT2,
328 },
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,
340 },
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,
352 },
353};
354
355int cx88_sram_channel_setup(struct cx88_core *core,
356 struct sram_channel *ch,
357 unsigned int bpl, u32 risc)
358{
359 unsigned int i,lines;
360 u32 cdt;
361
362 bpl = (bpl + 7) & ~7;
363 cdt = ch->cdt;
364 lines = ch->fifo_size / bpl;
365 if (lines > 6)
366 lines = 6;
367 BUG_ON(lines < 2);
368
369
370 for (i = 0; i < lines; i++)
371 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
372
373
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);
381
382
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);
387
388 dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
389 return 0;
390}
391
392
393
394
395static int cx88_risc_decode(u32 risc)
396{
397 static char *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",
408 };
409 static int 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,
415 };
416 static char *bits[] = {
417 "12", "13", "14", "resync",
418 "cnt0", "cnt1", "18", "19",
419 "20", "21", "22", "23",
420 "irq1", "irq2", "eol", "sol",
421 };
422 int i;
423
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;
431}
432
433
434void cx88_sram_channel_dump(struct cx88_core *core,
435 struct sram_channel *ch)
436{
437 static char *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",
449 };
450 u32 risc;
451 unsigned int i,j,n;
452
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);
466 }
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);
475 }
476 }
477
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));
490}
491
492static 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"
497};
498
499void cx88_print_irqbits(char *name, char *tag, char **strings,
500 int len, u32 bits, u32 mask)
501{
502 unsigned int i;
503
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("*");
515 }
516 printk("\n");
517}
518
519
520
521int cx88_core_irq(struct cx88_core *core, u32 status)
522{
523 int handled = 0;
524
525 if (status & PCI_INT_IR_SMPINT) {
526 cx88_ir_irq(core);
527 handled++;
528 }
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;
534}
535
536void cx88_wakeup(struct cx88_core *core,
537 struct cx88_dmaqueue *q, u32 count)
538{
539 struct cx88_buffer *buf;
540 int bc;
541
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
548
549
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);
558 }
559 if (list_empty(&q->active)) {
560 del_timer(&q->timeout);
561 } else {
562 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
563 }
564 if (bc != 1)
565 dprintk(2, "%s: %d buffers handled (should be 1)\n",
566 __func__, bc);
567}
568
569void cx88_shutdown(struct cx88_core *core)
570{
571
572 cx_write(MO_DEV_CNTRL2, 0);
573
574
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);
580
581
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);
588
589
590 cx_write(VID_CAPTURE_CONTROL, 0);
591}
592
593int cx88_reset(struct cx88_core *core)
594{
595 dprintk(1,"%s\n",__func__);
596 cx88_shutdown(core);
597
598
599 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF);
600 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF);
601 cx_write(MO_INT1_STAT, 0xFFFFFFFF);
602
603
604 msleep(100);
605
606
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);
615
616
617 cx_write(MO_INPUT_FORMAT, ((1 << 13) |
618 (1 << 12) |
619 (1 << 11) |
620 (0 << 10) |
621 (0 << 9) |
622 (7)));
623
624
625 cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
626
627
628 cx_write(MO_PDMA_STHRSH, 0x0807);
629 cx_write(MO_PDMA_DTHRSH, 0x0807);
630
631
632 cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
633 cx_write(MO_AGC_BACK_VBI, 0x00E00555);
634
635 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF);
636 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF);
637 cx_write(MO_INT1_STAT, 0xFFFFFFFF);
638
639
640 cx_write(MO_SRST_IO, 0);
641 msleep(10);
642 cx_write(MO_SRST_IO, 1);
643
644 return 0;
645}
646
647
648
649static unsigned int inline norm_swidth(v4l2_std_id norm)
650{
651 return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
652}
653
654static unsigned int inline norm_hdelay(v4l2_std_id norm)
655{
656 return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
657}
658
659static unsigned int inline norm_vdelay(v4l2_std_id norm)
660{
661 return (norm & V4L2_STD_625_50) ? 0x24 : 0x18;
662}
663
664static unsigned int inline norm_fsc8(v4l2_std_id norm)
665{
666 if (norm & V4L2_STD_PAL_M)
667 return 28604892;
668
669 if (norm & (V4L2_STD_PAL_Nc))
670 return 28656448;
671
672 if (norm & V4L2_STD_NTSC)
673 return 28636360;
674
675
676
677
678
679
680
681 return 35468950;
682}
683
684static unsigned int inline norm_htotal(v4l2_std_id norm)
685{
686
687 unsigned int fsc4=norm_fsc8(norm)/2;
688
689
690 return (norm & V4L2_STD_625_50) ?
691 ((fsc4+312)/625+12)/25 :
692 ((fsc4+262)/525*1001+15000)/30000;
693}
694
695static unsigned int inline norm_vbipack(v4l2_std_id norm)
696{
697 return (norm & V4L2_STD_625_50) ? 511 : 400;
698}
699
700int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
701 enum v4l2_field field)
702{
703 unsigned int swidth = norm_swidth(core->tvnorm);
704 unsigned int sheight = norm_maxh(core->tvnorm);
705 u32 value;
706
707 dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
708 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
709 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
710 v4l2_norm_to_name(core->tvnorm));
711 if (!V4L2_FIELD_HAS_BOTH(field))
712 height *= 2;
713
714
715 value = (width * norm_hdelay(core->tvnorm)) / swidth;
716 value &= 0x3fe;
717 cx_write(MO_HDELAY_EVEN, value);
718 cx_write(MO_HDELAY_ODD, value);
719 dprintk(1,"set_scale: hdelay 0x%04x (width %d)\n", value,swidth);
720
721 value = (swidth * 4096 / width) - 4096;
722 cx_write(MO_HSCALE_EVEN, value);
723 cx_write(MO_HSCALE_ODD, value);
724 dprintk(1,"set_scale: hscale 0x%04x\n", value);
725
726 cx_write(MO_HACTIVE_EVEN, width);
727 cx_write(MO_HACTIVE_ODD, width);
728 dprintk(1,"set_scale: hactive 0x%04x\n", width);
729
730
731 cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
732 cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm));
733 dprintk(1,"set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm));
734
735 value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
736 cx_write(MO_VSCALE_EVEN, value);
737 cx_write(MO_VSCALE_ODD, value);
738 dprintk(1,"set_scale: vscale 0x%04x\n", value);
739
740 cx_write(MO_VACTIVE_EVEN, sheight);
741 cx_write(MO_VACTIVE_ODD, sheight);
742 dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
743
744
745 value = 0;
746 value |= (1 << 19);
747 if (core->tvnorm & V4L2_STD_SECAM) {
748 value |= (1 << 15);
749 value |= (1 << 16);
750 }
751 if (INPUT(core->input).type == CX88_VMUX_SVIDEO)
752 value |= (1 << 13) | (1 << 5);
753 if (V4L2_FIELD_INTERLACED == field)
754 value |= (1 << 3);
755 if (width < 385)
756 value |= (1 << 0);
757 if (width < 193)
758 value |= (1 << 1);
759 if (nocomb)
760 value |= (3 << 5);
761
762 cx_write(MO_FILTER_EVEN, value);
763 cx_write(MO_FILTER_ODD, value);
764 dprintk(1,"set_scale: filter 0x%04x\n", value);
765
766 return 0;
767}
768
769static const u32 xtal = 28636363;
770
771static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
772{
773 static u32 pre[] = { 0, 0, 0, 3, 2, 1 };
774 u64 pll;
775 u32 reg;
776 int i;
777
778 if (prescale < 2)
779 prescale = 2;
780 if (prescale > 5)
781 prescale = 5;
782
783 pll = ofreq * 8 * prescale * (u64)(1 << 20);
784 do_div(pll,xtal);
785 reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
786 if (((reg >> 20) & 0x3f) < 14) {
787 printk("%s/0: pll out of range\n",core->name);
788 return -1;
789 }
790
791 dprintk(1,"set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n",
792 reg, cx_read(MO_PLL_REG), ofreq);
793 cx_write(MO_PLL_REG, reg);
794 for (i = 0; i < 100; i++) {
795 reg = cx_read(MO_DEVICE_STATUS);
796 if (reg & (1<<2)) {
797 dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",
798 prescale,ofreq);
799 return 0;
800 }
801 dprintk(1,"pll not locked yet, waiting ...\n");
802 msleep(10);
803 }
804 dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
805 return -1;
806}
807
808int cx88_start_audio_dma(struct cx88_core *core)
809{
810
811 int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
812
813 int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size/AUD_RDS_LINES;
814
815
816 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
817 return 0;
818
819
820 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
821 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
822 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27],
823 rds_bpl, 0);
824
825 cx_write(MO_AUDD_LNGTH, bpl);
826 cx_write(MO_AUDR_LNGTH, rds_bpl);
827
828
829 cx_write(MO_AUD_DMACNTRL, 0x0007);
830
831 return 0;
832}
833
834int cx88_stop_audio_dma(struct cx88_core *core)
835{
836
837 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
838 return 0;
839
840
841 cx_write(MO_AUD_DMACNTRL, 0x0000);
842
843 return 0;
844}
845
846static int set_tvaudio(struct cx88_core *core)
847{
848 v4l2_std_id norm = core->tvnorm;
849
850 if (CX88_VMUX_TELEVISION != INPUT(core->input).type)
851 return 0;
852
853 if (V4L2_STD_PAL_BG & norm) {
854 core->tvaudio = WW_BG;
855
856 } else if (V4L2_STD_PAL_DK & norm) {
857 core->tvaudio = WW_DK;
858
859 } else if (V4L2_STD_PAL_I & norm) {
860 core->tvaudio = WW_I;
861
862 } else if (V4L2_STD_SECAM_L & norm) {
863 core->tvaudio = WW_L;
864
865 } else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) & norm) {
866 core->tvaudio = WW_BG;
867
868 } else if (V4L2_STD_SECAM_DK & norm) {
869 core->tvaudio = WW_DK;
870
871 } else if ((V4L2_STD_NTSC_M & norm) ||
872 (V4L2_STD_PAL_M & norm)) {
873 core->tvaudio = WW_BTSC;
874
875 } else if (V4L2_STD_NTSC_M_JP & norm) {
876 core->tvaudio = WW_EIAJ;
877
878 } else {
879 printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
880 core->name, v4l2_norm_to_name(core->tvnorm));
881 core->tvaudio = 0;
882 return 0;
883 }
884
885 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
886 cx88_set_tvaudio(core);
887
888
889
890
891
892
893 cx88_start_audio_dma(core);
894 return 0;
895}
896
897
898
899int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
900{
901 u32 fsc8;
902 u32 adc_clock;
903 u32 vdec_clock;
904 u32 step_db,step_dr;
905 u64 tmp64;
906 u32 bdelay,agcdelay,htotal;
907 u32 cxiformat, cxoformat;
908
909 core->tvnorm = norm;
910 fsc8 = norm_fsc8(norm);
911 adc_clock = xtal;
912 vdec_clock = fsc8;
913 step_db = fsc8;
914 step_dr = fsc8;
915
916 if (norm & V4L2_STD_NTSC_M_JP) {
917 cxiformat = VideoFormatNTSCJapan;
918 cxoformat = 0x181f0008;
919 } else if (norm & V4L2_STD_NTSC_443) {
920 cxiformat = VideoFormatNTSC443;
921 cxoformat = 0x181f0008;
922 } else if (norm & V4L2_STD_PAL_M) {
923 cxiformat = VideoFormatPALM;
924 cxoformat = 0x1c1f0008;
925 } else if (norm & V4L2_STD_PAL_N) {
926 cxiformat = VideoFormatPALN;
927 cxoformat = 0x1c1f0008;
928 } else if (norm & V4L2_STD_PAL_Nc) {
929 cxiformat = VideoFormatPALNC;
930 cxoformat = 0x1c1f0008;
931 } else if (norm & V4L2_STD_PAL_60) {
932 cxiformat = VideoFormatPAL60;
933 cxoformat = 0x181f0008;
934 } else if (norm & V4L2_STD_NTSC) {
935 cxiformat = VideoFormatNTSC;
936 cxoformat = 0x181f0008;
937 } else if (norm & V4L2_STD_SECAM) {
938 step_db = 4250000 * 8;
939 step_dr = 4406250 * 8;
940
941 cxiformat = VideoFormatSECAM;
942 cxoformat = 0x181f0008;
943 } else {
944 cxiformat = VideoFormatPAL;
945 cxoformat = 0x181f0008;
946 }
947
948 dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
949 v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock,
950 step_db, step_dr);
951 set_pll(core,2,vdec_clock);
952
953 dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n",
954 cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
955
956
957 cx_andor(MO_INPUT_FORMAT, 0x40f,
958 norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400);
959
960
961 dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
962 cxoformat, cx_read(MO_OUTPUT_FORMAT));
963 cx_write(MO_OUTPUT_FORMAT, cxoformat);
964
965
966 tmp64 = adc_clock * (u64)(1 << 17);
967 do_div(tmp64, vdec_clock);
968 dprintk(1,"set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n",
969 (u32)tmp64, cx_read(MO_SCONV_REG));
970 cx_write(MO_SCONV_REG, (u32)tmp64);
971
972
973 tmp64 = step_db * (u64)(1 << 22);
974 do_div(tmp64, vdec_clock);
975 dprintk(1,"set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n",
976 (u32)tmp64, cx_read(MO_SUB_STEP));
977 cx_write(MO_SUB_STEP, (u32)tmp64);
978
979
980 tmp64 = step_dr * (u64)(1 << 22);
981 do_div(tmp64, vdec_clock);
982 dprintk(1,"set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n",
983 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
984 cx_write(MO_SUB_STEP_DR, (u32)tmp64);
985
986
987 bdelay = vdec_clock * 65 / 20000000 + 21;
988 agcdelay = vdec_clock * 68 / 20000000 + 15;
989 dprintk(1,"set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
990 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay);
991 cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
992
993
994 tmp64 = norm_htotal(norm) * (u64)vdec_clock;
995 do_div(tmp64, fsc8);
996 htotal = (u32)tmp64 | (HLNotchFilter4xFsc << 11);
997 dprintk(1,"set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n",
998 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
999 cx_write(MO_HTOTAL, htotal);
1000
1001
1002
1003 cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm));
1004
1005
1006 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
1007
1008
1009 set_tvaudio(core);
1010
1011
1012 call_all(core, core, s_std, norm);
1013
1014
1015 return 0;
1016}
1017
1018
1019
1020struct video_device *cx88_vdev_init(struct cx88_core *core,
1021 struct pci_dev *pci,
1022 struct video_device *template,
1023 char *type)
1024{
1025 struct video_device *vfd;
1026
1027 vfd = video_device_alloc();
1028 if (NULL == vfd)
1029 return NULL;
1030 *vfd = *template;
1031 vfd->v4l2_dev = &core->v4l2_dev;
1032 vfd->parent = &pci->dev;
1033 vfd->release = video_device_release;
1034 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1035 core->name, type, core->board.name);
1036 return vfd;
1037}
1038
1039struct cx88_core* cx88_core_get(struct pci_dev *pci)
1040{
1041 struct cx88_core *core;
1042
1043 mutex_lock(&devlist);
1044 list_for_each_entry(core, &cx88_devlist, devlist) {
1045 if (pci->bus->number != core->pci_bus)
1046 continue;
1047 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1048 continue;
1049
1050 if (0 != cx88_get_resources(core, pci)) {
1051 mutex_unlock(&devlist);
1052 return NULL;
1053 }
1054 atomic_inc(&core->refcount);
1055 mutex_unlock(&devlist);
1056 return core;
1057 }
1058
1059 core = cx88_core_create(pci, cx88_devcount);
1060 if (NULL != core) {
1061 cx88_devcount++;
1062 list_add_tail(&core->devlist, &cx88_devlist);
1063 }
1064
1065 mutex_unlock(&devlist);
1066 return core;
1067}
1068
1069void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1070{
1071 release_mem_region(pci_resource_start(pci,0),
1072 pci_resource_len(pci,0));
1073
1074 if (!atomic_dec_and_test(&core->refcount))
1075 return;
1076
1077 mutex_lock(&devlist);
1078 cx88_ir_fini(core);
1079 if (0 == core->i2c_rc) {
1080 if (core->i2c_rtc)
1081 i2c_unregister_device(core->i2c_rtc);
1082 i2c_del_adapter(&core->i2c_adap);
1083 }
1084 list_del(&core->devlist);
1085 iounmap(core->lmmio);
1086 cx88_devcount--;
1087 mutex_unlock(&devlist);
1088 v4l2_device_unregister(&core->v4l2_dev);
1089 kfree(core);
1090}
1091
1092
1093
1094EXPORT_SYMBOL(cx88_print_irqbits);
1095
1096EXPORT_SYMBOL(cx88_core_irq);
1097EXPORT_SYMBOL(cx88_wakeup);
1098EXPORT_SYMBOL(cx88_reset);
1099EXPORT_SYMBOL(cx88_shutdown);
1100
1101EXPORT_SYMBOL(cx88_risc_buffer);
1102EXPORT_SYMBOL(cx88_risc_databuffer);
1103EXPORT_SYMBOL(cx88_risc_stopper);
1104EXPORT_SYMBOL(cx88_free_buffer);
1105
1106EXPORT_SYMBOL(cx88_sram_channels);
1107EXPORT_SYMBOL(cx88_sram_channel_setup);
1108EXPORT_SYMBOL(cx88_sram_channel_dump);
1109
1110EXPORT_SYMBOL(cx88_set_tvnorm);
1111EXPORT_SYMBOL(cx88_set_scale);
1112
1113EXPORT_SYMBOL(cx88_vdev_init);
1114EXPORT_SYMBOL(cx88_core_get);
1115EXPORT_SYMBOL(cx88_core_put);
1116
1117EXPORT_SYMBOL(cx88_ir_start);
1118EXPORT_SYMBOL(cx88_ir_stop);
1119
1120
1121
1122
1123
1124
1125
1126