0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include "cx88.h"
0015
0016 #include <linux/init.h>
0017 #include <linux/list.h>
0018 #include <linux/module.h>
0019 #include <linux/kernel.h>
0020 #include <linux/slab.h>
0021 #include <linux/kmod.h>
0022 #include <linux/sound.h>
0023 #include <linux/interrupt.h>
0024 #include <linux/pci.h>
0025 #include <linux/delay.h>
0026 #include <linux/videodev2.h>
0027 #include <linux/mutex.h>
0028
0029 #include <media/v4l2-common.h>
0030 #include <media/v4l2-ioctl.h>
0031
0032 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
0033 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
0034 MODULE_LICENSE("GPL v2");
0035
0036
0037
0038 unsigned int cx88_core_debug;
0039 module_param_named(core_debug, cx88_core_debug, int, 0644);
0040 MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
0041
0042 static unsigned int nicam;
0043 module_param(nicam, int, 0644);
0044 MODULE_PARM_DESC(nicam, "tv audio is nicam");
0045
0046 static unsigned int nocomb;
0047 module_param(nocomb, int, 0644);
0048 MODULE_PARM_DESC(nocomb, "disable comb filter");
0049
0050 #define dprintk0(fmt, arg...) \
0051 printk(KERN_DEBUG pr_fmt("%s: core:" fmt), \
0052 __func__, ##arg) \
0053
0054 #define dprintk(level, fmt, arg...) do { \
0055 if (cx88_core_debug >= level) \
0056 printk(KERN_DEBUG pr_fmt("%s: core:" fmt), \
0057 __func__, ##arg); \
0058 } while (0)
0059
0060 static unsigned int cx88_devcount;
0061 static LIST_HEAD(cx88_devlist);
0062 static DEFINE_MUTEX(devlist);
0063
0064 #define NO_SYNC_LINE (-1U)
0065
0066
0067
0068
0069
0070 static __le32 *cx88_risc_field(__le32 *rp, struct scatterlist *sglist,
0071 unsigned int offset, u32 sync_line,
0072 unsigned int bpl, unsigned int padding,
0073 unsigned int lines, unsigned int lpi, bool jump)
0074 {
0075 struct scatterlist *sg;
0076 unsigned int line, todo, sol;
0077
0078 if (jump) {
0079 (*rp++) = cpu_to_le32(RISC_JUMP);
0080 (*rp++) = 0;
0081 }
0082
0083
0084 if (sync_line != NO_SYNC_LINE)
0085 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
0086
0087
0088 sg = sglist;
0089 for (line = 0; line < lines; line++) {
0090 while (offset && offset >= sg_dma_len(sg)) {
0091 offset -= sg_dma_len(sg);
0092 sg = sg_next(sg);
0093 }
0094 if (lpi && line > 0 && !(line % lpi))
0095 sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
0096 else
0097 sol = RISC_SOL;
0098 if (bpl <= sg_dma_len(sg) - offset) {
0099
0100 *(rp++) = cpu_to_le32(RISC_WRITE | sol |
0101 RISC_EOL | bpl);
0102 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
0103 offset += bpl;
0104 } else {
0105
0106 todo = bpl;
0107 *(rp++) = cpu_to_le32(RISC_WRITE | sol |
0108 (sg_dma_len(sg) - offset));
0109 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
0110 todo -= (sg_dma_len(sg) - offset);
0111 offset = 0;
0112 sg = sg_next(sg);
0113 while (todo > sg_dma_len(sg)) {
0114 *(rp++) = cpu_to_le32(RISC_WRITE |
0115 sg_dma_len(sg));
0116 *(rp++) = cpu_to_le32(sg_dma_address(sg));
0117 todo -= sg_dma_len(sg);
0118 sg = sg_next(sg);
0119 }
0120 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
0121 *(rp++) = cpu_to_le32(sg_dma_address(sg));
0122 offset += todo;
0123 }
0124 offset += padding;
0125 }
0126
0127 return rp;
0128 }
0129
0130 int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc,
0131 struct scatterlist *sglist,
0132 unsigned int top_offset, unsigned int bottom_offset,
0133 unsigned int bpl, unsigned int padding, unsigned int lines)
0134 {
0135 u32 instructions, fields;
0136 __le32 *rp;
0137
0138 fields = 0;
0139 if (top_offset != UNSET)
0140 fields++;
0141 if (bottom_offset != UNSET)
0142 fields++;
0143
0144
0145
0146
0147
0148
0149
0150 instructions = fields * (1 + ((bpl + padding) * lines) /
0151 PAGE_SIZE + lines);
0152 instructions += 4;
0153 risc->size = instructions * 8;
0154 risc->dma = 0;
0155 risc->cpu = dma_alloc_coherent(&pci->dev, risc->size, &risc->dma,
0156 GFP_KERNEL);
0157 if (!risc->cpu)
0158 return -ENOMEM;
0159
0160
0161 rp = risc->cpu;
0162 if (top_offset != UNSET)
0163 rp = cx88_risc_field(rp, sglist, top_offset, 0,
0164 bpl, padding, lines, 0, true);
0165 if (bottom_offset != UNSET)
0166 rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
0167 bpl, padding, lines, 0,
0168 top_offset == UNSET);
0169
0170
0171 risc->jmp = rp;
0172 WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
0173 return 0;
0174 }
0175 EXPORT_SYMBOL(cx88_risc_buffer);
0176
0177 int cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc,
0178 struct scatterlist *sglist, unsigned int bpl,
0179 unsigned int lines, unsigned int lpi)
0180 {
0181 u32 instructions;
0182 __le32 *rp;
0183
0184
0185
0186
0187
0188
0189
0190 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
0191 instructions += 3;
0192 risc->size = instructions * 8;
0193 risc->dma = 0;
0194 risc->cpu = dma_alloc_coherent(&pci->dev, risc->size, &risc->dma,
0195 GFP_KERNEL);
0196 if (!risc->cpu)
0197 return -ENOMEM;
0198
0199
0200 rp = risc->cpu;
0201 rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
0202 lines, lpi, !lpi);
0203
0204
0205 risc->jmp = rp;
0206 WARN_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
0207 return 0;
0208 }
0209 EXPORT_SYMBOL(cx88_risc_databuffer);
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 const struct sram_channel cx88_sram_channels[] = {
0243 [SRAM_CH21] = {
0244 .name = "video y / packed",
0245 .cmds_start = 0x180040,
0246 .ctrl_start = 0x180400,
0247 .cdt = 0x180400 + 64,
0248 .fifo_start = 0x180c00,
0249 .fifo_size = 0x002800,
0250 .ptr1_reg = MO_DMA21_PTR1,
0251 .ptr2_reg = MO_DMA21_PTR2,
0252 .cnt1_reg = MO_DMA21_CNT1,
0253 .cnt2_reg = MO_DMA21_CNT2,
0254 },
0255 [SRAM_CH22] = {
0256 .name = "video u",
0257 .cmds_start = 0x180080,
0258 .ctrl_start = 0x1804a0,
0259 .cdt = 0x1804a0 + 64,
0260 .fifo_start = 0x183400,
0261 .fifo_size = 0x000800,
0262 .ptr1_reg = MO_DMA22_PTR1,
0263 .ptr2_reg = MO_DMA22_PTR2,
0264 .cnt1_reg = MO_DMA22_CNT1,
0265 .cnt2_reg = MO_DMA22_CNT2,
0266 },
0267 [SRAM_CH23] = {
0268 .name = "video v",
0269 .cmds_start = 0x1800c0,
0270 .ctrl_start = 0x180540,
0271 .cdt = 0x180540 + 64,
0272 .fifo_start = 0x183c00,
0273 .fifo_size = 0x000800,
0274 .ptr1_reg = MO_DMA23_PTR1,
0275 .ptr2_reg = MO_DMA23_PTR2,
0276 .cnt1_reg = MO_DMA23_CNT1,
0277 .cnt2_reg = MO_DMA23_CNT2,
0278 },
0279 [SRAM_CH24] = {
0280 .name = "vbi",
0281 .cmds_start = 0x180100,
0282 .ctrl_start = 0x1805e0,
0283 .cdt = 0x1805e0 + 64,
0284 .fifo_start = 0x184400,
0285 .fifo_size = 0x001000,
0286 .ptr1_reg = MO_DMA24_PTR1,
0287 .ptr2_reg = MO_DMA24_PTR2,
0288 .cnt1_reg = MO_DMA24_CNT1,
0289 .cnt2_reg = MO_DMA24_CNT2,
0290 },
0291 [SRAM_CH25] = {
0292 .name = "audio from",
0293 .cmds_start = 0x180140,
0294 .ctrl_start = 0x180680,
0295 .cdt = 0x180680 + 64,
0296 .fifo_start = 0x185400,
0297 .fifo_size = 0x001000,
0298 .ptr1_reg = MO_DMA25_PTR1,
0299 .ptr2_reg = MO_DMA25_PTR2,
0300 .cnt1_reg = MO_DMA25_CNT1,
0301 .cnt2_reg = MO_DMA25_CNT2,
0302 },
0303 [SRAM_CH26] = {
0304 .name = "audio to",
0305 .cmds_start = 0x180180,
0306 .ctrl_start = 0x180720,
0307 .cdt = 0x180680 + 64,
0308 .fifo_start = 0x185400,
0309 .fifo_size = 0x001000,
0310 .ptr1_reg = MO_DMA26_PTR1,
0311 .ptr2_reg = MO_DMA26_PTR2,
0312 .cnt1_reg = MO_DMA26_CNT1,
0313 .cnt2_reg = MO_DMA26_CNT2,
0314 },
0315 [SRAM_CH28] = {
0316 .name = "mpeg",
0317 .cmds_start = 0x180200,
0318 .ctrl_start = 0x1807C0,
0319 .cdt = 0x1807C0 + 64,
0320 .fifo_start = 0x186400,
0321 .fifo_size = 0x001000,
0322 .ptr1_reg = MO_DMA28_PTR1,
0323 .ptr2_reg = MO_DMA28_PTR2,
0324 .cnt1_reg = MO_DMA28_CNT1,
0325 .cnt2_reg = MO_DMA28_CNT2,
0326 },
0327 [SRAM_CH27] = {
0328 .name = "audio rds",
0329 .cmds_start = 0x1801C0,
0330 .ctrl_start = 0x180860,
0331 .cdt = 0x180860 + 64,
0332 .fifo_start = 0x187400,
0333 .fifo_size = 0x000C00,
0334 .ptr1_reg = MO_DMA27_PTR1,
0335 .ptr2_reg = MO_DMA27_PTR2,
0336 .cnt1_reg = MO_DMA27_CNT1,
0337 .cnt2_reg = MO_DMA27_CNT2,
0338 },
0339 };
0340 EXPORT_SYMBOL(cx88_sram_channels);
0341
0342 int cx88_sram_channel_setup(struct cx88_core *core,
0343 const struct sram_channel *ch,
0344 unsigned int bpl, u32 risc)
0345 {
0346 unsigned int i, lines;
0347 u32 cdt;
0348
0349 bpl = (bpl + 7) & ~7;
0350 cdt = ch->cdt;
0351 lines = ch->fifo_size / bpl;
0352 if (lines > 6)
0353 lines = 6;
0354 WARN_ON(lines < 2);
0355
0356
0357 for (i = 0; i < lines; i++)
0358 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
0359
0360
0361 cx_write(ch->cmds_start + 0, risc);
0362 cx_write(ch->cmds_start + 4, cdt);
0363 cx_write(ch->cmds_start + 8, (lines * 16) >> 3);
0364 cx_write(ch->cmds_start + 12, ch->ctrl_start);
0365 cx_write(ch->cmds_start + 16, 64 >> 2);
0366 for (i = 20; i < 64; i += 4)
0367 cx_write(ch->cmds_start + i, 0);
0368
0369
0370 cx_write(ch->ptr1_reg, ch->fifo_start);
0371 cx_write(ch->ptr2_reg, cdt);
0372 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
0373 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
0374
0375 dprintk(2, "sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
0376 return 0;
0377 }
0378 EXPORT_SYMBOL(cx88_sram_channel_setup);
0379
0380
0381
0382
0383 static int cx88_risc_decode(u32 risc)
0384 {
0385 static const char * const instr[16] = {
0386 [RISC_SYNC >> 28] = "sync",
0387 [RISC_WRITE >> 28] = "write",
0388 [RISC_WRITEC >> 28] = "writec",
0389 [RISC_READ >> 28] = "read",
0390 [RISC_READC >> 28] = "readc",
0391 [RISC_JUMP >> 28] = "jump",
0392 [RISC_SKIP >> 28] = "skip",
0393 [RISC_WRITERM >> 28] = "writerm",
0394 [RISC_WRITECM >> 28] = "writecm",
0395 [RISC_WRITECR >> 28] = "writecr",
0396 };
0397 static int const incr[16] = {
0398 [RISC_WRITE >> 28] = 2,
0399 [RISC_JUMP >> 28] = 2,
0400 [RISC_WRITERM >> 28] = 3,
0401 [RISC_WRITECM >> 28] = 3,
0402 [RISC_WRITECR >> 28] = 4,
0403 };
0404 static const char * const bits[] = {
0405 "12", "13", "14", "resync",
0406 "cnt0", "cnt1", "18", "19",
0407 "20", "21", "22", "23",
0408 "irq1", "irq2", "eol", "sol",
0409 };
0410 int i;
0411
0412 dprintk0("0x%08x [ %s", risc,
0413 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
0414 for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--)
0415 if (risc & (1 << (i + 12)))
0416 pr_cont(" %s", bits[i]);
0417 pr_cont(" count=%d ]\n", risc & 0xfff);
0418 return incr[risc >> 28] ? incr[risc >> 28] : 1;
0419 }
0420
0421 void cx88_sram_channel_dump(struct cx88_core *core,
0422 const struct sram_channel *ch)
0423 {
0424 static const char * const name[] = {
0425 "initial risc",
0426 "cdt base",
0427 "cdt size",
0428 "iq base",
0429 "iq size",
0430 "risc pc",
0431 "iq wr ptr",
0432 "iq rd ptr",
0433 "cdt current",
0434 "pci target",
0435 "line / byte",
0436 };
0437 u32 risc;
0438 unsigned int i, j, n;
0439
0440 dprintk0("%s - dma channel status dump\n", ch->name);
0441 for (i = 0; i < ARRAY_SIZE(name); i++)
0442 dprintk0(" cmds: %-12s: 0x%08x\n",
0443 name[i], cx_read(ch->cmds_start + 4 * i));
0444 for (n = 1, i = 0; i < 4; i++) {
0445 risc = cx_read(ch->cmds_start + 4 * (i + 11));
0446 pr_cont(" risc%d: ", i);
0447 if (--n)
0448 pr_cont("0x%08x [ arg #%d ]\n", risc, n);
0449 else
0450 n = cx88_risc_decode(risc);
0451 }
0452 for (i = 0; i < 16; i += n) {
0453 risc = cx_read(ch->ctrl_start + 4 * i);
0454 dprintk0(" iq %x: ", i);
0455 n = cx88_risc_decode(risc);
0456 for (j = 1; j < n; j++) {
0457 risc = cx_read(ch->ctrl_start + 4 * (i + j));
0458 pr_cont(" iq %x: 0x%08x [ arg #%d ]\n",
0459 i + j, risc, j);
0460 }
0461 }
0462
0463 dprintk0("fifo: 0x%08x -> 0x%x\n",
0464 ch->fifo_start, ch->fifo_start + ch->fifo_size);
0465 dprintk0("ctrl: 0x%08x -> 0x%x\n",
0466 ch->ctrl_start, ch->ctrl_start + 6 * 16);
0467 dprintk0(" ptr1_reg: 0x%08x\n", cx_read(ch->ptr1_reg));
0468 dprintk0(" ptr2_reg: 0x%08x\n", cx_read(ch->ptr2_reg));
0469 dprintk0(" cnt1_reg: 0x%08x\n", cx_read(ch->cnt1_reg));
0470 dprintk0(" cnt2_reg: 0x%08x\n", cx_read(ch->cnt2_reg));
0471 }
0472 EXPORT_SYMBOL(cx88_sram_channel_dump);
0473
0474 static const char *cx88_pci_irqs[32] = {
0475 "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
0476 "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
0477 "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
0478 "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
0479 };
0480
0481 void cx88_print_irqbits(const char *tag, const char *strings[],
0482 int len, u32 bits, u32 mask)
0483 {
0484 unsigned int i;
0485
0486 dprintk0("%s [0x%x]", tag, bits);
0487 for (i = 0; i < len; i++) {
0488 if (!(bits & (1 << i)))
0489 continue;
0490 if (strings[i])
0491 pr_cont(" %s", strings[i]);
0492 else
0493 pr_cont(" %d", i);
0494 if (!(mask & (1 << i)))
0495 continue;
0496 pr_cont("*");
0497 }
0498 pr_cont("\n");
0499 }
0500 EXPORT_SYMBOL(cx88_print_irqbits);
0501
0502
0503
0504 int cx88_core_irq(struct cx88_core *core, u32 status)
0505 {
0506 int handled = 0;
0507
0508 if (status & PCI_INT_IR_SMPINT) {
0509 cx88_ir_irq(core);
0510 handled++;
0511 }
0512 if (!handled)
0513 cx88_print_irqbits("irq pci",
0514 cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs),
0515 status, core->pci_irqmask);
0516 return handled;
0517 }
0518 EXPORT_SYMBOL(cx88_core_irq);
0519
0520 void cx88_wakeup(struct cx88_core *core,
0521 struct cx88_dmaqueue *q, u32 count)
0522 {
0523 struct cx88_buffer *buf;
0524
0525 buf = list_entry(q->active.next,
0526 struct cx88_buffer, list);
0527 buf->vb.vb2_buf.timestamp = ktime_get_ns();
0528 buf->vb.field = core->field;
0529 buf->vb.sequence = q->count++;
0530 list_del(&buf->list);
0531 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
0532 }
0533 EXPORT_SYMBOL(cx88_wakeup);
0534
0535 void cx88_shutdown(struct cx88_core *core)
0536 {
0537
0538 cx_write(MO_DEV_CNTRL2, 0);
0539
0540
0541 cx_write(MO_VID_DMACNTRL, 0x0);
0542 cx_write(MO_AUD_DMACNTRL, 0x0);
0543 cx_write(MO_TS_DMACNTRL, 0x0);
0544 cx_write(MO_VIP_DMACNTRL, 0x0);
0545 cx_write(MO_GPHST_DMACNTRL, 0x0);
0546
0547
0548 cx_write(MO_PCI_INTMSK, 0x0);
0549 cx_write(MO_VID_INTMSK, 0x0);
0550 cx_write(MO_AUD_INTMSK, 0x0);
0551 cx_write(MO_TS_INTMSK, 0x0);
0552 cx_write(MO_VIP_INTMSK, 0x0);
0553 cx_write(MO_GPHST_INTMSK, 0x0);
0554
0555
0556 cx_write(VID_CAPTURE_CONTROL, 0);
0557 }
0558 EXPORT_SYMBOL(cx88_shutdown);
0559
0560 int cx88_reset(struct cx88_core *core)
0561 {
0562 dprintk(1, "");
0563 cx88_shutdown(core);
0564
0565
0566 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF);
0567 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF);
0568 cx_write(MO_INT1_STAT, 0xFFFFFFFF);
0569
0570
0571 msleep(100);
0572
0573
0574 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21],
0575 720 * 4, 0);
0576 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
0577 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
0578 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
0579 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
0580 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
0581 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
0582 188 * 4, 0);
0583 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0);
0584
0585
0586 cx_write(MO_INPUT_FORMAT, ((1 << 13) |
0587 (1 << 12) |
0588 (1 << 11) |
0589 (0 << 10) |
0590 (0 << 9) |
0591 (7)));
0592
0593
0594 cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
0595
0596
0597 cx_write(MO_PDMA_STHRSH, 0x0807);
0598 cx_write(MO_PDMA_DTHRSH, 0x0807);
0599
0600
0601 cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
0602 cx_write(MO_AGC_BACK_VBI, 0x00E00555);
0603
0604 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF);
0605 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF);
0606 cx_write(MO_INT1_STAT, 0xFFFFFFFF);
0607
0608
0609 cx_write(MO_SRST_IO, 0);
0610 usleep_range(10000, 20000);
0611 cx_write(MO_SRST_IO, 1);
0612
0613 return 0;
0614 }
0615 EXPORT_SYMBOL(cx88_reset);
0616
0617
0618
0619 static inline unsigned int norm_swidth(v4l2_std_id norm)
0620 {
0621 if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M))
0622 return 754;
0623
0624 if (norm & V4L2_STD_PAL_Nc)
0625 return 745;
0626
0627 return 922;
0628 }
0629
0630 static inline unsigned int norm_hdelay(v4l2_std_id norm)
0631 {
0632 if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M))
0633 return 135;
0634
0635 if (norm & V4L2_STD_PAL_Nc)
0636 return 149;
0637
0638 return 186;
0639 }
0640
0641 static inline unsigned int norm_vdelay(v4l2_std_id norm)
0642 {
0643 return (norm & V4L2_STD_625_50) ? 0x24 : 0x18;
0644 }
0645
0646 static inline unsigned int norm_fsc8(v4l2_std_id norm)
0647 {
0648 if (norm & V4L2_STD_PAL_M)
0649 return 28604892;
0650
0651 if (norm & V4L2_STD_PAL_Nc)
0652 return 28656448;
0653
0654 if (norm & V4L2_STD_NTSC)
0655 return 28636360;
0656
0657
0658
0659
0660
0661
0662
0663
0664 return 35468950;
0665 }
0666
0667 static inline unsigned int norm_htotal(v4l2_std_id norm)
0668 {
0669 unsigned int fsc4 = norm_fsc8(norm) / 2;
0670
0671
0672 return (norm & V4L2_STD_625_50) ?
0673 ((fsc4 + 312) / 625 + 12) / 25 :
0674 ((fsc4 + 262) / 525 * 1001 + 15000) / 30000;
0675 }
0676
0677 static inline unsigned int norm_vbipack(v4l2_std_id norm)
0678 {
0679 return (norm & V4L2_STD_625_50) ? 511 : 400;
0680 }
0681
0682 int cx88_set_scale(struct cx88_core *core, unsigned int width,
0683 unsigned int height, enum v4l2_field field)
0684 {
0685 unsigned int swidth = norm_swidth(core->tvnorm);
0686 unsigned int sheight = norm_maxh(core->tvnorm);
0687 u32 value;
0688
0689 dprintk(1, "set_scale: %dx%d [%s%s,%s]\n", width, height,
0690 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
0691 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
0692 v4l2_norm_to_name(core->tvnorm));
0693 if (!V4L2_FIELD_HAS_BOTH(field))
0694 height *= 2;
0695
0696
0697 value = (width * norm_hdelay(core->tvnorm)) / swidth;
0698 value &= 0x3fe;
0699 cx_write(MO_HDELAY_EVEN, value);
0700 cx_write(MO_HDELAY_ODD, value);
0701 dprintk(1, "set_scale: hdelay 0x%04x (width %d)\n", value, swidth);
0702
0703 value = (swidth * 4096 / width) - 4096;
0704 cx_write(MO_HSCALE_EVEN, value);
0705 cx_write(MO_HSCALE_ODD, value);
0706 dprintk(1, "set_scale: hscale 0x%04x\n", value);
0707
0708 cx_write(MO_HACTIVE_EVEN, width);
0709 cx_write(MO_HACTIVE_ODD, width);
0710 dprintk(1, "set_scale: hactive 0x%04x\n", width);
0711
0712
0713 cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
0714 cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm));
0715 dprintk(1, "set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm));
0716
0717 value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
0718 cx_write(MO_VSCALE_EVEN, value);
0719 cx_write(MO_VSCALE_ODD, value);
0720 dprintk(1, "set_scale: vscale 0x%04x\n", value);
0721
0722 cx_write(MO_VACTIVE_EVEN, sheight);
0723 cx_write(MO_VACTIVE_ODD, sheight);
0724 dprintk(1, "set_scale: vactive 0x%04x\n", sheight);
0725
0726
0727 value = 0;
0728 value |= (1 << 19);
0729 if (core->tvnorm & V4L2_STD_SECAM) {
0730 value |= (1 << 15);
0731 value |= (1 << 16);
0732 }
0733 if (INPUT(core->input).type == CX88_VMUX_SVIDEO)
0734 value |= (1 << 13) | (1 << 5);
0735 if (field == V4L2_FIELD_INTERLACED)
0736 value |= (1 << 3);
0737 if (width < 385)
0738 value |= (1 << 0);
0739 if (width < 193)
0740 value |= (1 << 1);
0741 if (nocomb)
0742 value |= (3 << 5);
0743
0744 cx_andor(MO_FILTER_EVEN, 0x7ffc7f, value);
0745 cx_andor(MO_FILTER_ODD, 0x7ffc7f, value);
0746 dprintk(1, "set_scale: filter 0x%04x\n", value);
0747
0748 return 0;
0749 }
0750 EXPORT_SYMBOL(cx88_set_scale);
0751
0752 static const u32 xtal = 28636363;
0753
0754 static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
0755 {
0756 static const u32 pre[] = { 0, 0, 0, 3, 2, 1 };
0757 u64 pll;
0758 u32 reg;
0759 int i;
0760
0761 if (prescale < 2)
0762 prescale = 2;
0763 if (prescale > 5)
0764 prescale = 5;
0765
0766 pll = ofreq * 8 * prescale * (u64)(1 << 20);
0767 do_div(pll, xtal);
0768 reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
0769 if (((reg >> 20) & 0x3f) < 14) {
0770 pr_err("pll out of range\n");
0771 return -1;
0772 }
0773
0774 dprintk(1, "set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n",
0775 reg, cx_read(MO_PLL_REG), ofreq);
0776 cx_write(MO_PLL_REG, reg);
0777 for (i = 0; i < 100; i++) {
0778 reg = cx_read(MO_DEVICE_STATUS);
0779 if (reg & (1 << 2)) {
0780 dprintk(1, "pll locked [pre=%d,ofreq=%d]\n",
0781 prescale, ofreq);
0782 return 0;
0783 }
0784 dprintk(1, "pll not locked yet, waiting ...\n");
0785 usleep_range(10000, 20000);
0786 }
0787 dprintk(1, "pll NOT locked [pre=%d,ofreq=%d]\n", prescale, ofreq);
0788 return -1;
0789 }
0790
0791 int cx88_start_audio_dma(struct cx88_core *core)
0792 {
0793
0794 int bpl = cx88_sram_channels[SRAM_CH25].fifo_size / 4;
0795
0796 int rds_bpl = cx88_sram_channels[SRAM_CH27].fifo_size / AUD_RDS_LINES;
0797
0798
0799 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
0800 return 0;
0801
0802
0803 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
0804 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
0805 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27],
0806 rds_bpl, 0);
0807
0808 cx_write(MO_AUDD_LNGTH, bpl);
0809 cx_write(MO_AUDR_LNGTH, rds_bpl);
0810
0811
0812 cx_write(MO_AUD_DMACNTRL, 0x0007);
0813
0814 return 0;
0815 }
0816
0817 int cx88_stop_audio_dma(struct cx88_core *core)
0818 {
0819
0820 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
0821 return 0;
0822
0823
0824 cx_write(MO_AUD_DMACNTRL, 0x0000);
0825
0826 return 0;
0827 }
0828
0829 static int set_tvaudio(struct cx88_core *core)
0830 {
0831 v4l2_std_id norm = core->tvnorm;
0832
0833 if (INPUT(core->input).type != CX88_VMUX_TELEVISION &&
0834 INPUT(core->input).type != CX88_VMUX_CABLE)
0835 return 0;
0836
0837 if (V4L2_STD_PAL_BG & norm) {
0838 core->tvaudio = WW_BG;
0839
0840 } else if (V4L2_STD_PAL_DK & norm) {
0841 core->tvaudio = WW_DK;
0842
0843 } else if (V4L2_STD_PAL_I & norm) {
0844 core->tvaudio = WW_I;
0845
0846 } else if (V4L2_STD_SECAM_L & norm) {
0847 core->tvaudio = WW_L;
0848
0849 } else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) &
0850 norm) {
0851 core->tvaudio = WW_BG;
0852
0853 } else if (V4L2_STD_SECAM_DK & norm) {
0854 core->tvaudio = WW_DK;
0855
0856 } else if ((V4L2_STD_NTSC_M | V4L2_STD_PAL_M | V4L2_STD_PAL_Nc) &
0857 norm) {
0858 core->tvaudio = WW_BTSC;
0859
0860 } else if (V4L2_STD_NTSC_M_JP & norm) {
0861 core->tvaudio = WW_EIAJ;
0862
0863 } else {
0864 pr_info("tvaudio support needs work for this tv norm [%s], sorry\n",
0865 v4l2_norm_to_name(core->tvnorm));
0866 core->tvaudio = WW_NONE;
0867 return 0;
0868 }
0869
0870 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
0871 cx88_set_tvaudio(core);
0872
0873
0874
0875
0876
0877
0878 cx88_start_audio_dma(core);
0879 return 0;
0880 }
0881
0882 int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
0883 {
0884 u32 fsc8;
0885 u32 adc_clock;
0886 u32 vdec_clock;
0887 u32 step_db, step_dr;
0888 u64 tmp64;
0889 u32 bdelay, agcdelay, htotal;
0890 u32 cxiformat, cxoformat;
0891
0892 if (norm == core->tvnorm)
0893 return 0;
0894 if (core->v4ldev && (vb2_is_busy(&core->v4ldev->vb2_vidq) ||
0895 vb2_is_busy(&core->v4ldev->vb2_vbiq)))
0896 return -EBUSY;
0897 if (core->dvbdev && vb2_is_busy(&core->dvbdev->vb2_mpegq))
0898 return -EBUSY;
0899 core->tvnorm = norm;
0900 fsc8 = norm_fsc8(norm);
0901 adc_clock = xtal;
0902 vdec_clock = fsc8;
0903 step_db = fsc8;
0904 step_dr = fsc8;
0905
0906 if (norm & V4L2_STD_NTSC_M_JP) {
0907 cxiformat = VideoFormatNTSCJapan;
0908 cxoformat = 0x181f0008;
0909 } else if (norm & V4L2_STD_NTSC_443) {
0910 cxiformat = VideoFormatNTSC443;
0911 cxoformat = 0x181f0008;
0912 } else if (norm & V4L2_STD_PAL_M) {
0913 cxiformat = VideoFormatPALM;
0914 cxoformat = 0x1c1f0008;
0915 } else if (norm & V4L2_STD_PAL_N) {
0916 cxiformat = VideoFormatPALN;
0917 cxoformat = 0x1c1f0008;
0918 } else if (norm & V4L2_STD_PAL_Nc) {
0919 cxiformat = VideoFormatPALNC;
0920 cxoformat = 0x1c1f0008;
0921 } else if (norm & V4L2_STD_PAL_60) {
0922 cxiformat = VideoFormatPAL60;
0923 cxoformat = 0x181f0008;
0924 } else if (norm & V4L2_STD_NTSC) {
0925 cxiformat = VideoFormatNTSC;
0926 cxoformat = 0x181f0008;
0927 } else if (norm & V4L2_STD_SECAM) {
0928 step_db = 4250000 * 8;
0929 step_dr = 4406250 * 8;
0930
0931 cxiformat = VideoFormatSECAM;
0932 cxoformat = 0x181f0008;
0933 } else {
0934 cxiformat = VideoFormatPAL;
0935 cxoformat = 0x181f0008;
0936 }
0937
0938 dprintk(1, "set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
0939 v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock,
0940 step_db, step_dr);
0941 set_pll(core, 2, vdec_clock);
0942
0943 dprintk(1, "set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n",
0944 cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
0945
0946
0947
0948
0949 cx_andor(MO_INPUT_FORMAT, 0x40f,
0950 norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400);
0951
0952
0953 dprintk(1, "set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
0954 cxoformat, cx_read(MO_OUTPUT_FORMAT));
0955 cx_write(MO_OUTPUT_FORMAT, cxoformat);
0956
0957
0958 tmp64 = adc_clock * (u64)(1 << 17);
0959 do_div(tmp64, vdec_clock);
0960 dprintk(1, "set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n",
0961 (u32)tmp64, cx_read(MO_SCONV_REG));
0962 cx_write(MO_SCONV_REG, (u32)tmp64);
0963
0964
0965 tmp64 = step_db * (u64)(1 << 22);
0966 do_div(tmp64, vdec_clock);
0967 dprintk(1, "set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n",
0968 (u32)tmp64, cx_read(MO_SUB_STEP));
0969 cx_write(MO_SUB_STEP, (u32)tmp64);
0970
0971
0972 tmp64 = step_dr * (u64)(1 << 22);
0973 do_div(tmp64, vdec_clock);
0974 dprintk(1, "set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n",
0975 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
0976 cx_write(MO_SUB_STEP_DR, (u32)tmp64);
0977
0978
0979 bdelay = vdec_clock * 65 / 20000000 + 21;
0980 agcdelay = vdec_clock * 68 / 20000000 + 15;
0981 dprintk(1,
0982 "set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
0983 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST),
0984 bdelay, agcdelay);
0985 cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
0986
0987
0988 tmp64 = norm_htotal(norm) * (u64)vdec_clock;
0989 do_div(tmp64, fsc8);
0990 htotal = (u32)tmp64;
0991 dprintk(1,
0992 "set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n",
0993 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
0994 cx_andor(MO_HTOTAL, 0x07ff, htotal);
0995
0996
0997
0998 cx_write(MO_VBI_PACKET, (10 << 11) | norm_vbipack(norm));
0999
1000
1001 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
1002
1003
1004 set_tvaudio(core);
1005
1006
1007 call_all(core, video, s_std, norm);
1008
1009
1010
1011
1012
1013 v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM);
1014
1015
1016 return 0;
1017 }
1018 EXPORT_SYMBOL(cx88_set_tvnorm);
1019
1020
1021
1022 void cx88_vdev_init(struct cx88_core *core,
1023 struct pci_dev *pci,
1024 struct video_device *vfd,
1025 const struct video_device *template_,
1026 const char *type)
1027 {
1028 *vfd = *template_;
1029
1030
1031
1032
1033
1034
1035
1036 vfd->v4l2_dev = &core->v4l2_dev;
1037 vfd->dev_parent = &pci->dev;
1038 vfd->release = video_device_release_empty;
1039 vfd->lock = &core->lock;
1040 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1041 core->name, type, core->board.name);
1042 }
1043 EXPORT_SYMBOL(cx88_vdev_init);
1044
1045 struct cx88_core *cx88_core_get(struct pci_dev *pci)
1046 {
1047 struct cx88_core *core;
1048
1049 mutex_lock(&devlist);
1050 list_for_each_entry(core, &cx88_devlist, devlist) {
1051 if (pci->bus->number != core->pci_bus)
1052 continue;
1053 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1054 continue;
1055
1056 if (cx88_get_resources(core, pci) != 0) {
1057 mutex_unlock(&devlist);
1058 return NULL;
1059 }
1060 refcount_inc(&core->refcount);
1061 mutex_unlock(&devlist);
1062 return core;
1063 }
1064
1065 core = cx88_core_create(pci, cx88_devcount);
1066 if (core) {
1067 cx88_devcount++;
1068 list_add_tail(&core->devlist, &cx88_devlist);
1069 }
1070
1071 mutex_unlock(&devlist);
1072 return core;
1073 }
1074 EXPORT_SYMBOL(cx88_core_get);
1075
1076 void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1077 {
1078 release_mem_region(pci_resource_start(pci, 0),
1079 pci_resource_len(pci, 0));
1080
1081 if (!refcount_dec_and_test(&core->refcount))
1082 return;
1083
1084 mutex_lock(&devlist);
1085 cx88_ir_fini(core);
1086 if (core->i2c_rc == 0) {
1087 i2c_unregister_device(core->i2c_rtc);
1088 i2c_del_adapter(&core->i2c_adap);
1089 }
1090 list_del(&core->devlist);
1091 iounmap(core->lmmio);
1092 cx88_devcount--;
1093 mutex_unlock(&devlist);
1094 v4l2_ctrl_handler_free(&core->video_hdl);
1095 v4l2_ctrl_handler_free(&core->audio_hdl);
1096 v4l2_device_unregister(&core->v4l2_dev);
1097 kfree(core);
1098 }
1099 EXPORT_SYMBOL(cx88_core_put);