1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include "cx88.h"
24
25#include <linux/init.h>
26#include <linux/list.h>
27#include <linux/module.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/videodev2.h>
36#include <linux/mutex.h>
37
38#include <media/v4l2-common.h>
39#include <media/v4l2-ioctl.h>
40
41MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
42MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
43MODULE_LICENSE("GPL");
44
45
46
47unsigned int cx88_core_debug;
48module_param_named(core_debug, cx88_core_debug, int, 0644);
49MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
50
51static unsigned int nicam;
52module_param(nicam, int, 0644);
53MODULE_PARM_DESC(nicam, "tv audio is nicam");
54
55static unsigned int nocomb;
56module_param(nocomb, int, 0644);
57MODULE_PARM_DESC(nocomb, "disable comb filter");
58
59#define dprintk0(fmt, arg...) \
60 printk(KERN_DEBUG pr_fmt("%s: core:" fmt), \
61 __func__, ##arg) \
62
63#define dprintk(level, fmt, arg...) do { \
64 if (cx88_core_debug >= level) \
65 printk(KERN_DEBUG pr_fmt("%s: core:" fmt), \
66 __func__, ##arg); \
67} while (0)
68
69static unsigned int cx88_devcount;
70static LIST_HEAD(cx88_devlist);
71static DEFINE_MUTEX(devlist);
72
73#define NO_SYNC_LINE (-1U)
74
75
76
77
78
79static __le32 *cx88_risc_field(__le32 *rp, struct scatterlist *sglist,
80 unsigned int offset, u32 sync_line,
81 unsigned int bpl, unsigned int padding,
82 unsigned int lines, unsigned int lpi, bool jump)
83{
84 struct scatterlist *sg;
85 unsigned int line, todo, sol;
86
87 if (jump) {
88 (*rp++) = cpu_to_le32(RISC_JUMP);
89 (*rp++) = 0;
90 }
91
92
93 if (sync_line != NO_SYNC_LINE)
94 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
95
96
97 sg = sglist;
98 for (line = 0; line < lines; line++) {
99 while (offset && offset >= sg_dma_len(sg)) {
100 offset -= sg_dma_len(sg);
101 sg = sg_next(sg);
102 }
103 if (lpi && line > 0 && !(line % lpi))
104 sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
105 else
106 sol = RISC_SOL;
107 if (bpl <= sg_dma_len(sg) - offset) {
108
109 *(rp++) = cpu_to_le32(RISC_WRITE | sol |
110 RISC_EOL | bpl);
111 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
112 offset += bpl;
113 } else {
114
115 todo = bpl;
116 *(rp++) = cpu_to_le32(RISC_WRITE | sol |
117 (sg_dma_len(sg) - offset));
118 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
119 todo -= (sg_dma_len(sg) - offset);
120 offset = 0;
121 sg = sg_next(sg);
122 while (todo > sg_dma_len(sg)) {
123 *(rp++) = cpu_to_le32(RISC_WRITE |
124 sg_dma_len(sg));
125 *(rp++) = cpu_to_le32(sg_dma_address(sg));
126 todo -= sg_dma_len(sg);
127 sg = sg_next(sg);
128 }
129 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
130 *(rp++) = cpu_to_le32(sg_dma_address(sg));
131 offset += todo;
132 }
133 offset += padding;
134 }
135
136 return rp;
137}
138
139int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc,
140 struct scatterlist *sglist,
141 unsigned int top_offset, unsigned int bottom_offset,
142 unsigned int bpl, unsigned int padding, unsigned int lines)
143{
144 u32 instructions, fields;
145 __le32 *rp;
146
147 fields = 0;
148 if (top_offset != UNSET)
149 fields++;
150 if (bottom_offset != UNSET)
151 fields++;
152
153
154
155
156
157
158
159 instructions = fields * (1 + ((bpl + padding) * lines) /
160 PAGE_SIZE + lines);
161 instructions += 4;
162 risc->size = instructions * 8;
163 risc->dma = 0;
164 risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma);
165 if (!risc->cpu)
166 return -ENOMEM;
167
168
169 rp = risc->cpu;
170 if (top_offset != UNSET)
171 rp = cx88_risc_field(rp, sglist, top_offset, 0,
172 bpl, padding, lines, 0, true);
173 if (bottom_offset != UNSET)
174 rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
175 bpl, padding, lines, 0,
176 top_offset == UNSET);
177
178
179 risc->jmp = rp;
180 WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
181 return 0;
182}
183EXPORT_SYMBOL(cx88_risc_buffer);
184
185int cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc,
186 struct scatterlist *sglist, unsigned int bpl,
187 unsigned int lines, unsigned int lpi)
188{
189 u32 instructions;
190 __le32 *rp;
191
192
193
194
195
196
197
198 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
199 instructions += 3;
200 risc->size = instructions * 8;
201 risc->dma = 0;
202 risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma);
203 if (!risc->cpu)
204 return -ENOMEM;
205
206
207 rp = risc->cpu;
208 rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
209 lines, lpi, !lpi);
210
211
212 risc->jmp = rp;
213 WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
214 return 0;
215}
216EXPORT_SYMBOL(cx88_risc_databuffer);
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249const struct sram_channel cx88_sram_channels[] = {
250 [SRAM_CH21] = {
251 .name = "video y / packed",
252 .cmds_start = 0x180040,
253 .ctrl_start = 0x180400,
254 .cdt = 0x180400 + 64,
255 .fifo_start = 0x180c00,
256 .fifo_size = 0x002800,
257 .ptr1_reg = MO_DMA21_PTR1,
258 .ptr2_reg = MO_DMA21_PTR2,
259 .cnt1_reg = MO_DMA21_CNT1,
260 .cnt2_reg = MO_DMA21_CNT2,
261 },
262 [SRAM_CH22] = {
263 .name = "video u",
264 .cmds_start = 0x180080,
265 .ctrl_start = 0x1804a0,
266 .cdt = 0x1804a0 + 64,
267 .fifo_start = 0x183400,
268 .fifo_size = 0x000800,
269 .ptr1_reg = MO_DMA22_PTR1,
270 .ptr2_reg = MO_DMA22_PTR2,
271 .cnt1_reg = MO_DMA22_CNT1,
272 .cnt2_reg = MO_DMA22_CNT2,
273 },
274 [SRAM_CH23] = {
275 .name = "video v",
276 .cmds_start = 0x1800c0,
277 .ctrl_start = 0x180540,
278 .cdt = 0x180540 + 64,
279 .fifo_start = 0x183c00,
280 .fifo_size = 0x000800,
281 .ptr1_reg = MO_DMA23_PTR1,
282 .ptr2_reg = MO_DMA23_PTR2,
283 .cnt1_reg = MO_DMA23_CNT1,
284 .cnt2_reg = MO_DMA23_CNT2,
285 },
286 [SRAM_CH24] = {
287 .name = "vbi",
288 .cmds_start = 0x180100,
289 .ctrl_start = 0x1805e0,
290 .cdt = 0x1805e0 + 64,
291 .fifo_start = 0x184400,
292 .fifo_size = 0x001000,
293 .ptr1_reg = MO_DMA24_PTR1,
294 .ptr2_reg = MO_DMA24_PTR2,
295 .cnt1_reg = MO_DMA24_CNT1,
296 .cnt2_reg = MO_DMA24_CNT2,
297 },
298 [SRAM_CH25] = {
299 .name = "audio from",
300 .cmds_start = 0x180140,
301 .ctrl_start = 0x180680,
302 .cdt = 0x180680 + 64,
303 .fifo_start = 0x185400,
304 .fifo_size = 0x001000,
305 .ptr1_reg = MO_DMA25_PTR1,
306 .ptr2_reg = MO_DMA25_PTR2,
307 .cnt1_reg = MO_DMA25_CNT1,
308 .cnt2_reg = MO_DMA25_CNT2,
309 },
310 [SRAM_CH26] = {
311 .name = "audio to",
312 .cmds_start = 0x180180,
313 .ctrl_start = 0x180720,
314 .cdt = 0x180680 + 64,
315 .fifo_start = 0x185400,
316 .fifo_size = 0x001000,
317 .ptr1_reg = MO_DMA26_PTR1,
318 .ptr2_reg = MO_DMA26_PTR2,
319 .cnt1_reg = MO_DMA26_CNT1,
320 .cnt2_reg = MO_DMA26_CNT2,
321 },
322 [SRAM_CH28] = {
323 .name = "mpeg",
324 .cmds_start = 0x180200,
325 .ctrl_start = 0x1807C0,
326 .cdt = 0x1807C0 + 64,
327 .fifo_start = 0x186400,
328 .fifo_size = 0x001000,
329 .ptr1_reg = MO_DMA28_PTR1,
330 .ptr2_reg = MO_DMA28_PTR2,
331 .cnt1_reg = MO_DMA28_CNT1,
332 .cnt2_reg = MO_DMA28_CNT2,
333 },
334 [SRAM_CH27] = {
335 .name = "audio rds",
336 .cmds_start = 0x1801C0,
337 .ctrl_start = 0x180860,
338 .cdt = 0x180860 + 64,
339 .fifo_start = 0x187400,
340 .fifo_size = 0x000C00,
341 .ptr1_reg = MO_DMA27_PTR1,
342 .ptr2_reg = MO_DMA27_PTR2,
343 .cnt1_reg = MO_DMA27_CNT1,
344 .cnt2_reg = MO_DMA27_CNT2,
345 },
346};
347EXPORT_SYMBOL(cx88_sram_channels);
348
349int cx88_sram_channel_setup(struct cx88_core *core,
350 const struct sram_channel *ch,
351 unsigned int bpl, u32 risc)
352{
353 unsigned int i, lines;
354 u32 cdt;
355
356 bpl = (bpl + 7) & ~7;
357 cdt = ch->cdt;
358 lines = ch->fifo_size / bpl;
359 if (lines > 6)
360 lines = 6;
361 WARN_ON(lines < 2);
362
363
364 for (i = 0; i < lines; i++)
365 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
366
367
368 cx_write(ch->cmds_start + 0, risc);
369 cx_write(ch->cmds_start + 4, cdt);
370 cx_write(ch->cmds_start + 8, (lines * 16) >> 3);
371 cx_write(ch->cmds_start + 12, ch->ctrl_start);
372 cx_write(ch->cmds_start + 16, 64 >> 2);
373 for (i = 20; i < 64; i += 4)
374 cx_write(ch->cmds_start + i, 0);
375
376
377 cx_write(ch->ptr1_reg, ch->fifo_start);
378 cx_write(ch->ptr2_reg, cdt);
379 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
380 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
381
382 dprintk(2, "sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
383 return 0;
384}
385EXPORT_SYMBOL(cx88_sram_channel_setup);
386
387
388
389
390static int cx88_risc_decode(u32 risc)
391{
392 static const char * const instr[16] = {
393 [RISC_SYNC >> 28] = "sync",
394 [RISC_WRITE >> 28] = "write",
395 [RISC_WRITEC >> 28] = "writec",
396 [RISC_READ >> 28] = "read",
397 [RISC_READC >> 28] = "readc",
398 [RISC_JUMP >> 28] = "jump",
399 [RISC_SKIP >> 28] = "skip",
400 [RISC_WRITERM >> 28] = "writerm",
401 [RISC_WRITECM >> 28] = "writecm",
402 [RISC_WRITECR >> 28] = "writecr",
403 };
404 static int const incr[16] = {
405 [RISC_WRITE >> 28] = 2,
406 [RISC_JUMP >> 28] = 2,
407 [RISC_WRITERM >> 28] = 3,
408 [RISC_WRITECM >> 28] = 3,
409 [RISC_WRITECR >> 28] = 4,
410 };
411 static const char * const bits[] = {
412 "12", "13", "14", "resync",
413 "cnt0", "cnt1", "18", "19",
414 "20", "21", "22", "23",
415 "irq1", "irq2", "eol", "sol",
416 };
417 int i;
418
419 dprintk0("0x%08x [ %s", risc,
420 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
421 for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--)
422 if (risc & (1 << (i + 12)))
423 pr_cont(" %s", bits[i]);
424 pr_cont(" count=%d ]\n", risc & 0xfff);
425 return incr[risc >> 28] ? incr[risc >> 28] : 1;
426}
427
428void cx88_sram_channel_dump(struct cx88_core *core,
429 const struct sram_channel *ch)
430{
431 static const char * const name[] = {
432 "initial risc",
433 "cdt base",
434 "cdt size",
435 "iq base",
436 "iq size",
437 "risc pc",
438 "iq wr ptr",
439 "iq rd ptr",
440 "cdt current",
441 "pci target",
442 "line / byte",
443 };
444 u32 risc;
445 unsigned int i, j, n;
446
447 dprintk0("%s - dma channel status dump\n", ch->name);
448 for (i = 0; i < ARRAY_SIZE(name); i++)
449 dprintk0(" cmds: %-12s: 0x%08x\n",
450 name[i], cx_read(ch->cmds_start + 4 * i));
451 for (n = 1, i = 0; i < 4; i++) {
452 risc = cx_read(ch->cmds_start + 4 * (i + 11));
453 pr_cont(" risc%d: ", i);
454 if (--n)
455 pr_cont("0x%08x [ arg #%d ]\n", risc, n);
456 else
457 n = cx88_risc_decode(risc);
458 }
459 for (i = 0; i < 16; i += n) {
460 risc = cx_read(ch->ctrl_start + 4 * i);
461 dprintk0(" iq %x: ", i);
462 n = cx88_risc_decode(risc);
463 for (j = 1; j < n; j++) {
464 risc = cx_read(ch->ctrl_start + 4 * (i + j));
465 pr_cont(" iq %x: 0x%08x [ arg #%d ]\n",
466 i + j, risc, j);
467 }
468 }
469
470 dprintk0("fifo: 0x%08x -> 0x%x\n",
471 ch->fifo_start, ch->fifo_start + ch->fifo_size);
472 dprintk0("ctrl: 0x%08x -> 0x%x\n",
473 ch->ctrl_start, ch->ctrl_start + 6 * 16);
474 dprintk0(" ptr1_reg: 0x%08x\n", cx_read(ch->ptr1_reg));
475 dprintk0(" ptr2_reg: 0x%08x\n", cx_read(ch->ptr2_reg));
476 dprintk0(" cnt1_reg: 0x%08x\n", cx_read(ch->cnt1_reg));
477 dprintk0(" cnt2_reg: 0x%08x\n", cx_read(ch->cnt2_reg));
478}
479EXPORT_SYMBOL(cx88_sram_channel_dump);
480
481static const char *cx88_pci_irqs[32] = {
482 "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
483 "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
484 "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
485 "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
486};
487
488void cx88_print_irqbits(const char *tag, const char *strings[],
489 int len, u32 bits, u32 mask)
490{
491 unsigned int i;
492
493 dprintk0("%s [0x%x]", tag, bits);
494 for (i = 0; i < len; i++) {
495 if (!(bits & (1 << i)))
496 continue;
497 if (strings[i])
498 pr_cont(" %s", strings[i]);
499 else
500 pr_cont(" %d", i);
501 if (!(mask & (1 << i)))
502 continue;
503 pr_cont("*");
504 }
505 pr_cont("\n");
506}
507EXPORT_SYMBOL(cx88_print_irqbits);
508
509
510
511int cx88_core_irq(struct cx88_core *core, u32 status)
512{
513 int handled = 0;
514
515 if (status & PCI_INT_IR_SMPINT) {
516 cx88_ir_irq(core);
517 handled++;
518 }
519 if (!handled)
520 cx88_print_irqbits("irq pci",
521 cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs),
522 status, core->pci_irqmask);
523 return handled;
524}
525EXPORT_SYMBOL(cx88_core_irq);
526
527void cx88_wakeup(struct cx88_core *core,
528 struct cx88_dmaqueue *q, u32 count)
529{
530 struct cx88_buffer *buf;
531
532 buf = list_entry(q->active.next,
533 struct cx88_buffer, list);
534 buf->vb.vb2_buf.timestamp = ktime_get_ns();
535 buf->vb.field = core->field;
536 buf->vb.sequence = q->count++;
537 list_del(&buf->list);
538 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
539}
540EXPORT_SYMBOL(cx88_wakeup);
541
542void cx88_shutdown(struct cx88_core *core)
543{
544
545 cx_write(MO_DEV_CNTRL2, 0);
546
547
548 cx_write(MO_VID_DMACNTRL, 0x0);
549 cx_write(MO_AUD_DMACNTRL, 0x0);
550 cx_write(MO_TS_DMACNTRL, 0x0);
551 cx_write(MO_VIP_DMACNTRL, 0x0);
552 cx_write(MO_GPHST_DMACNTRL, 0x0);
553
554
555 cx_write(MO_PCI_INTMSK, 0x0);
556 cx_write(MO_VID_INTMSK, 0x0);
557 cx_write(MO_AUD_INTMSK, 0x0);
558 cx_write(MO_TS_INTMSK, 0x0);
559 cx_write(MO_VIP_INTMSK, 0x0);
560 cx_write(MO_GPHST_INTMSK, 0x0);
561
562
563 cx_write(VID_CAPTURE_CONTROL, 0);
564}
565EXPORT_SYMBOL(cx88_shutdown);
566
567int cx88_reset(struct cx88_core *core)
568{
569 dprintk(1, "");
570 cx88_shutdown(core);
571
572
573 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF);
574 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF);
575 cx_write(MO_INT1_STAT, 0xFFFFFFFF);
576
577
578 msleep(100);
579
580
581 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21],
582 720 * 4, 0);
583 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
584 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
585 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
586 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
587 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
588 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
589 188 * 4, 0);
590 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0);
591
592
593 cx_write(MO_INPUT_FORMAT, ((1 << 13) |
594 (1 << 12) |
595 (1 << 11) |
596 (0 << 10) |
597 (0 << 9) |
598 (7)));
599
600
601 cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
602
603
604 cx_write(MO_PDMA_STHRSH, 0x0807);
605 cx_write(MO_PDMA_DTHRSH, 0x0807);
606
607
608 cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
609 cx_write(MO_AGC_BACK_VBI, 0x00E00555);
610
611 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF);
612 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF);
613 cx_write(MO_INT1_STAT, 0xFFFFFFFF);
614
615
616 cx_write(MO_SRST_IO, 0);
617 usleep_range(10000, 20000);
618 cx_write(MO_SRST_IO, 1);
619
620 return 0;
621}
622EXPORT_SYMBOL(cx88_reset);
623
624
625
626static inline unsigned int norm_swidth(v4l2_std_id norm)
627{
628 return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
629}
630
631static inline unsigned int norm_hdelay(v4l2_std_id norm)
632{
633 return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
634}
635
636static inline unsigned int norm_vdelay(v4l2_std_id norm)
637{
638 return (norm & V4L2_STD_625_50) ? 0x24 : 0x18;
639}
640
641static inline unsigned int norm_fsc8(v4l2_std_id norm)
642{
643 if (norm & V4L2_STD_PAL_M)
644 return 28604892;
645
646 if (norm & (V4L2_STD_PAL_Nc))
647 return 28656448;
648
649 if (norm & V4L2_STD_NTSC)
650 return 28636360;
651
652
653
654
655
656
657
658
659 return 35468950;
660}
661
662static inline unsigned int norm_htotal(v4l2_std_id norm)
663{
664 unsigned int fsc4 = norm_fsc8(norm) / 2;
665
666
667 return (norm & V4L2_STD_625_50) ?
668 ((fsc4 + 312) / 625 + 12) / 25 :
669 ((fsc4 + 262) / 525 * 1001 + 15000) / 30000;
670}
671
672static inline unsigned int norm_vbipack(v4l2_std_id norm)
673{
674 return (norm & V4L2_STD_625_50) ? 511 : 400;
675}
676
677int cx88_set_scale(struct cx88_core *core, unsigned int width,
678 unsigned int height, enum v4l2_field field)
679{
680 unsigned int swidth = norm_swidth(core->tvnorm);
681 unsigned int sheight = norm_maxh(core->tvnorm);
682 u32 value;
683
684 dprintk(1, "set_scale: %dx%d [%s%s,%s]\n", width, height,
685 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
686 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
687 v4l2_norm_to_name(core->tvnorm));
688 if (!V4L2_FIELD_HAS_BOTH(field))
689 height *= 2;
690
691
692 value = (width * norm_hdelay(core->tvnorm)) / swidth;
693 value &= 0x3fe;
694 cx_write(MO_HDELAY_EVEN, value);
695 cx_write(MO_HDELAY_ODD, value);
696 dprintk(1, "set_scale: hdelay 0x%04x (width %d)\n", value, swidth);
697
698 value = (swidth * 4096 / width) - 4096;
699 cx_write(MO_HSCALE_EVEN, value);
700 cx_write(MO_HSCALE_ODD, value);
701 dprintk(1, "set_scale: hscale 0x%04x\n", value);
702
703 cx_write(MO_HACTIVE_EVEN, width);
704 cx_write(MO_HACTIVE_ODD, width);
705 dprintk(1, "set_scale: hactive 0x%04x\n", width);
706
707
708 cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
709 cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm));
710 dprintk(1, "set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm));
711
712 value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
713 cx_write(MO_VSCALE_EVEN, value);
714 cx_write(MO_VSCALE_ODD, value);
715 dprintk(1, "set_scale: vscale 0x%04x\n", value);
716
717 cx_write(MO_VACTIVE_EVEN, sheight);
718 cx_write(MO_VACTIVE_ODD, sheight);
719 dprintk(1, "set_scale: vactive 0x%04x\n", sheight);
720
721
722 value = 0;
723 value |= (1 << 19);
724 if (core->tvnorm & V4L2_STD_SECAM) {
725 value |= (1 << 15);
726 value |= (1 << 16);
727 }
728 if (INPUT(core->input).type == CX88_VMUX_SVIDEO)
729 value |= (1 << 13) | (1 << 5);
730 if (field == V4L2_FIELD_INTERLACED)
731 value |= (1 << 3);
732 if (width < 385)
733 value |= (1 << 0);
734 if (width < 193)
735 value |= (1 << 1);
736 if (nocomb)
737 value |= (3 << 5);
738
739 cx_andor(MO_FILTER_EVEN, 0x7ffc7f, value);
740 cx_andor(MO_FILTER_ODD, 0x7ffc7f, value);
741 dprintk(1, "set_scale: filter 0x%04x\n", value);
742
743 return 0;
744}
745EXPORT_SYMBOL(cx88_set_scale);
746
747static const u32 xtal = 28636363;
748
749static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
750{
751 static const u32 pre[] = { 0, 0, 0, 3, 2, 1 };
752 u64 pll;
753 u32 reg;
754 int i;
755
756 if (prescale < 2)
757 prescale = 2;
758 if (prescale > 5)
759 prescale = 5;
760
761 pll = ofreq * 8 * prescale * (u64)(1 << 20);
762 do_div(pll, xtal);
763 reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
764 if (((reg >> 20) & 0x3f) < 14) {
765 pr_err("pll out of range\n");
766 return -1;
767 }
768
769 dprintk(1, "set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n",
770 reg, cx_read(MO_PLL_REG), ofreq);
771 cx_write(MO_PLL_REG, reg);
772 for (i = 0; i < 100; i++) {
773 reg = cx_read(MO_DEVICE_STATUS);
774 if (reg & (1 << 2)) {
775 dprintk(1, "pll locked [pre=%d,ofreq=%d]\n",
776 prescale, ofreq);
777 return 0;
778 }
779 dprintk(1, "pll not locked yet, waiting ...\n");
780 usleep_range(10000, 20000);
781 }
782 dprintk(1, "pll NOT locked [pre=%d,ofreq=%d]\n", prescale, ofreq);
783 return -1;
784}
785
786int cx88_start_audio_dma(struct cx88_core *core)
787{
788
789 int bpl = cx88_sram_channels[SRAM_CH25].fifo_size / 4;
790
791 int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size / AUD_RDS_LINES;
792
793
794 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
795 return 0;
796
797
798 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
799 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
800 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27],
801 rds_bpl, 0);
802
803 cx_write(MO_AUDD_LNGTH, bpl);
804 cx_write(MO_AUDR_LNGTH, rds_bpl);
805
806
807 cx_write(MO_AUD_DMACNTRL, 0x0007);
808
809 return 0;
810}
811
812int cx88_stop_audio_dma(struct cx88_core *core)
813{
814
815 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
816 return 0;
817
818
819 cx_write(MO_AUD_DMACNTRL, 0x0000);
820
821 return 0;
822}
823
824static int set_tvaudio(struct cx88_core *core)
825{
826 v4l2_std_id norm = core->tvnorm;
827
828 if (INPUT(core->input).type != CX88_VMUX_TELEVISION &&
829 INPUT(core->input).type != CX88_VMUX_CABLE)
830 return 0;
831
832 if (V4L2_STD_PAL_BG & norm) {
833 core->tvaudio = WW_BG;
834
835 } else if (V4L2_STD_PAL_DK & norm) {
836 core->tvaudio = WW_DK;
837
838 } else if (V4L2_STD_PAL_I & norm) {
839 core->tvaudio = WW_I;
840
841 } else if (V4L2_STD_SECAM_L & norm) {
842 core->tvaudio = WW_L;
843
844 } else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) &
845 norm) {
846 core->tvaudio = WW_BG;
847
848 } else if (V4L2_STD_SECAM_DK & norm) {
849 core->tvaudio = WW_DK;
850
851 } else if ((V4L2_STD_NTSC_M & norm) ||
852 (V4L2_STD_PAL_M & norm)) {
853 core->tvaudio = WW_BTSC;
854
855 } else if (V4L2_STD_NTSC_M_JP & norm) {
856 core->tvaudio = WW_EIAJ;
857
858 } else {
859 pr_info("tvaudio support needs work for this tv norm [%s], sorry\n",
860 v4l2_norm_to_name(core->tvnorm));
861 core->tvaudio = WW_NONE;
862 return 0;
863 }
864
865 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
866 cx88_set_tvaudio(core);
867
868
869
870
871
872
873 cx88_start_audio_dma(core);
874 return 0;
875}
876
877int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
878{
879 u32 fsc8;
880 u32 adc_clock;
881 u32 vdec_clock;
882 u32 step_db, step_dr;
883 u64 tmp64;
884 u32 bdelay, agcdelay, htotal;
885 u32 cxiformat, cxoformat;
886
887 if (norm == core->tvnorm)
888 return 0;
889 if (core->v4ldev && (vb2_is_busy(&core->v4ldev->vb2_vidq) ||
890 vb2_is_busy(&core->v4ldev->vb2_vbiq)))
891 return -EBUSY;
892 if (core->dvbdev && vb2_is_busy(&core->dvbdev->vb2_mpegq))
893 return -EBUSY;
894 core->tvnorm = norm;
895 fsc8 = norm_fsc8(norm);
896 adc_clock = xtal;
897 vdec_clock = fsc8;
898 step_db = fsc8;
899 step_dr = fsc8;
900
901 if (norm & V4L2_STD_NTSC_M_JP) {
902 cxiformat = VideoFormatNTSCJapan;
903 cxoformat = 0x181f0008;
904 } else if (norm & V4L2_STD_NTSC_443) {
905 cxiformat = VideoFormatNTSC443;
906 cxoformat = 0x181f0008;
907 } else if (norm & V4L2_STD_PAL_M) {
908 cxiformat = VideoFormatPALM;
909 cxoformat = 0x1c1f0008;
910 } else if (norm & V4L2_STD_PAL_N) {
911 cxiformat = VideoFormatPALN;
912 cxoformat = 0x1c1f0008;
913 } else if (norm & V4L2_STD_PAL_Nc) {
914 cxiformat = VideoFormatPALNC;
915 cxoformat = 0x1c1f0008;
916 } else if (norm & V4L2_STD_PAL_60) {
917 cxiformat = VideoFormatPAL60;
918 cxoformat = 0x181f0008;
919 } else if (norm & V4L2_STD_NTSC) {
920 cxiformat = VideoFormatNTSC;
921 cxoformat = 0x181f0008;
922 } else if (norm & V4L2_STD_SECAM) {
923 step_db = 4250000 * 8;
924 step_dr = 4406250 * 8;
925
926 cxiformat = VideoFormatSECAM;
927 cxoformat = 0x181f0008;
928 } else {
929 cxiformat = VideoFormatPAL;
930 cxoformat = 0x181f0008;
931 }
932
933 dprintk(1, "set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
934 v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock,
935 step_db, step_dr);
936 set_pll(core, 2, vdec_clock);
937
938 dprintk(1, "set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n",
939 cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
940
941
942
943
944 cx_andor(MO_INPUT_FORMAT, 0x40f,
945 norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400);
946
947
948 dprintk(1, "set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
949 cxoformat, cx_read(MO_OUTPUT_FORMAT));
950 cx_write(MO_OUTPUT_FORMAT, cxoformat);
951
952
953 tmp64 = adc_clock * (u64)(1 << 17);
954 do_div(tmp64, vdec_clock);
955 dprintk(1, "set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n",
956 (u32)tmp64, cx_read(MO_SCONV_REG));
957 cx_write(MO_SCONV_REG, (u32)tmp64);
958
959
960 tmp64 = step_db * (u64)(1 << 22);
961 do_div(tmp64, vdec_clock);
962 dprintk(1, "set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n",
963 (u32)tmp64, cx_read(MO_SUB_STEP));
964 cx_write(MO_SUB_STEP, (u32)tmp64);
965
966
967 tmp64 = step_dr * (u64)(1 << 22);
968 do_div(tmp64, vdec_clock);
969 dprintk(1, "set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n",
970 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
971 cx_write(MO_SUB_STEP_DR, (u32)tmp64);
972
973
974 bdelay = vdec_clock * 65 / 20000000 + 21;
975 agcdelay = vdec_clock * 68 / 20000000 + 15;
976 dprintk(1,
977 "set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
978 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST),
979 bdelay, agcdelay);
980 cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
981
982
983 tmp64 = norm_htotal(norm) * (u64)vdec_clock;
984 do_div(tmp64, fsc8);
985 htotal = (u32)tmp64;
986 dprintk(1,
987 "set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n",
988 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
989 cx_andor(MO_HTOTAL, 0x07ff, htotal);
990
991
992
993 cx_write(MO_VBI_PACKET, (10 << 11) | norm_vbipack(norm));
994
995
996 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
997
998
999 set_tvaudio(core);
1000
1001
1002 call_all(core, video, s_std, norm);
1003
1004
1005
1006
1007
1008 v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM);
1009
1010
1011 return 0;
1012}
1013EXPORT_SYMBOL(cx88_set_tvnorm);
1014
1015
1016
1017void cx88_vdev_init(struct cx88_core *core,
1018 struct pci_dev *pci,
1019 struct video_device *vfd,
1020 const struct video_device *template_,
1021 const char *type)
1022{
1023 *vfd = *template_;
1024
1025
1026
1027
1028
1029
1030
1031 vfd->v4l2_dev = &core->v4l2_dev;
1032 vfd->dev_parent = &pci->dev;
1033 vfd->release = video_device_release_empty;
1034 vfd->lock = &core->lock;
1035 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1036 core->name, type, core->board.name);
1037}
1038EXPORT_SYMBOL(cx88_vdev_init);
1039
1040struct cx88_core *cx88_core_get(struct pci_dev *pci)
1041{
1042 struct cx88_core *core;
1043
1044 mutex_lock(&devlist);
1045 list_for_each_entry(core, &cx88_devlist, devlist) {
1046 if (pci->bus->number != core->pci_bus)
1047 continue;
1048 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1049 continue;
1050
1051 if (cx88_get_resources(core, pci) != 0) {
1052 mutex_unlock(&devlist);
1053 return NULL;
1054 }
1055 refcount_inc(&core->refcount);
1056 mutex_unlock(&devlist);
1057 return core;
1058 }
1059
1060 core = cx88_core_create(pci, cx88_devcount);
1061 if (core) {
1062 cx88_devcount++;
1063 list_add_tail(&core->devlist, &cx88_devlist);
1064 }
1065
1066 mutex_unlock(&devlist);
1067 return core;
1068}
1069EXPORT_SYMBOL(cx88_core_get);
1070
1071void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1072{
1073 release_mem_region(pci_resource_start(pci, 0),
1074 pci_resource_len(pci, 0));
1075
1076 if (!refcount_dec_and_test(&core->refcount))
1077 return;
1078
1079 mutex_lock(&devlist);
1080 cx88_ir_fini(core);
1081 if (core->i2c_rc == 0) {
1082 if (core->i2c_rtc)
1083 i2c_unregister_device(core->i2c_rtc);
1084 i2c_del_adapter(&core->i2c_adap);
1085 }
1086 list_del(&core->devlist);
1087 iounmap(core->lmmio);
1088 cx88_devcount--;
1089 mutex_unlock(&devlist);
1090 v4l2_ctrl_handler_free(&core->video_hdl);
1091 v4l2_ctrl_handler_free(&core->audio_hdl);
1092 v4l2_device_unregister(&core->v4l2_dev);
1093 kfree(core);
1094}
1095EXPORT_SYMBOL(cx88_core_put);
1096