V4L/DVB (6081): ivtv: Fix static structure initialization
[deliverable/linux.git] / drivers / media / video / cx88 / cx88-core.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2 *
3 * device driver for Conexant 2388x based TV cards
4 * driver core
5 *
6 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
7 *
8d87cb9f
MCC
8 * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
9 * - Multituner support
10 * - video_ioctl2 conversion
11 * - PAL/M fixes
12 *
1da177e4
LT
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.
17 *
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.
22 *
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.
26 */
27
28#include <linux/init.h>
29#include <linux/list.h>
30#include <linux/module.h>
1da177e4
LT
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>
98f30ed0 38#include <linux/videodev2.h>
1e4baed3 39#include <linux/mutex.h>
1da177e4
LT
40
41#include "cx88.h"
5e453dc7 42#include <media/v4l2-common.h>
1da177e4
LT
43
44MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
45MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
46MODULE_LICENSE("GPL");
47
48/* ------------------------------------------------------------------ */
49
50static unsigned int core_debug = 0;
51module_param(core_debug,int,0644);
52MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
53
1da177e4
LT
54static unsigned int nicam = 0;
55module_param(nicam,int,0644);
56MODULE_PARM_DESC(nicam,"tv audio is nicam");
57
58static unsigned int nocomb = 0;
59module_param(nocomb,int,0644);
60MODULE_PARM_DESC(nocomb,"disable comb filter");
61
62#define dprintk(level,fmt, arg...) if (core_debug >= level) \
63 printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
64
65static unsigned int cx88_devcount;
66static LIST_HEAD(cx88_devlist);
1e4baed3 67static DEFINE_MUTEX(devlist);
1da177e4 68
1da177e4
LT
69#define NO_SYNC_LINE (-1U)
70
71static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
72 unsigned int offset, u32 sync_line,
73 unsigned int bpl, unsigned int padding,
74 unsigned int lines)
75{
76 struct scatterlist *sg;
77 unsigned int line,todo;
78
79 /* sync instruction */
80 if (sync_line != NO_SYNC_LINE)
81 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
82
83 /* scan lines */
84 sg = sglist;
85 for (line = 0; line < lines; line++) {
86 while (offset && offset >= sg_dma_len(sg)) {
87 offset -= sg_dma_len(sg);
88 sg++;
89 }
90 if (bpl <= sg_dma_len(sg)-offset) {
91 /* fits into current chunk */
4ac97914
MCC
92 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
93 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
94 offset+=bpl;
1da177e4 95 } else {
d1009bd7 96 /* scanline needs to be split */
4ac97914
MCC
97 todo = bpl;
98 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
1da177e4 99 (sg_dma_len(sg)-offset));
4ac97914
MCC
100 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
101 todo -= (sg_dma_len(sg)-offset);
102 offset = 0;
103 sg++;
104 while (todo > sg_dma_len(sg)) {
f2421ca3 105 *(rp++)=cpu_to_le32(RISC_WRITE|
1da177e4 106 sg_dma_len(sg));
f2421ca3 107 *(rp++)=cpu_to_le32(sg_dma_address(sg));
1da177e4
LT
108 todo -= sg_dma_len(sg);
109 sg++;
110 }
4ac97914 111 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
1da177e4
LT
112 *(rp++)=cpu_to_le32(sg_dma_address(sg));
113 offset += todo;
114 }
115 offset += padding;
116 }
117
118 return rp;
119}
120
121int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
122 struct scatterlist *sglist,
123 unsigned int top_offset, unsigned int bottom_offset,
124 unsigned int bpl, unsigned int padding, unsigned int lines)
125{
126 u32 instructions,fields;
127 u32 *rp;
128 int rc;
129
130 fields = 0;
131 if (UNSET != top_offset)
132 fields++;
133 if (UNSET != bottom_offset)
134 fields++;
135
136 /* estimate risc mem: worst case is one write per page border +
bba3ad76
DS
137 one write per scan line + syncs + jump (all 2 dwords). Padding
138 can cause next bpl to start close to a page border. First DMA
139 region may be smaller than PAGE_SIZE */
140 instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
141 instructions += 2;
1da177e4
LT
142 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
143 return rc;
144
145 /* write risc instructions */
146 rp = risc->cpu;
147 if (UNSET != top_offset)
148 rp = cx88_risc_field(rp, sglist, top_offset, 0,
149 bpl, padding, lines);
150 if (UNSET != bottom_offset)
151 rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
152 bpl, padding, lines);
153
154 /* save pointer to jmp instruction address */
155 risc->jmp = rp;
4a287cfe 156 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
1da177e4
LT
157 return 0;
158}
159
160int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
161 struct scatterlist *sglist, unsigned int bpl,
162 unsigned int lines)
163{
164 u32 instructions;
165 u32 *rp;
166 int rc;
167
168 /* estimate risc mem: worst case is one write per page border +
bba3ad76
DS
169 one write per scan line + syncs + jump (all 2 dwords). Here
170 there is no padding and no sync. First DMA region may be smaller
171 than PAGE_SIZE */
172 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
173 instructions += 1;
1da177e4
LT
174 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
175 return rc;
176
177 /* write risc instructions */
178 rp = risc->cpu;
179 rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines);
180
181 /* save pointer to jmp instruction address */
182 risc->jmp = rp;
4a287cfe 183 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
1da177e4
LT
184 return 0;
185}
186
187int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
188 u32 reg, u32 mask, u32 value)
189{
190 u32 *rp;
191 int rc;
192
193 if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
194 return rc;
195
196 /* write risc instructions */
197 rp = risc->cpu;
198 *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2 | RISC_IMM);
199 *(rp++) = cpu_to_le32(reg);
200 *(rp++) = cpu_to_le32(value);
201 *(rp++) = cpu_to_le32(mask);
202 *(rp++) = cpu_to_le32(RISC_JUMP);
203 *(rp++) = cpu_to_le32(risc->dma);
204 return 0;
205}
206
207void
c7b0ac05 208cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
1da177e4 209{
ae24601b 210 BUG_ON(in_interrupt());
1da177e4 211 videobuf_waiton(&buf->vb,0,0);
c7b0ac05 212 videobuf_dma_unmap(q, &buf->vb.dma);
1da177e4 213 videobuf_dma_free(&buf->vb.dma);
c7b0ac05 214 btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
1da177e4
LT
215 buf->vb.state = STATE_NEEDS_INIT;
216}
217
218/* ------------------------------------------------------------------ */
219/* our SRAM memory layout */
220
221/* we are going to put all thr risc programs into host memory, so we
222 * can use the whole SDRAM for the DMA fifos. To simplify things, we
223 * use a static memory layout. That surely will waste memory in case
224 * we don't use all DMA channels at the same time (which will be the
225 * case most of the time). But that still gives us enougth FIFO space
226 * to be able to deal with insane long pci latencies ...
227 *
228 * FIFO space allocations:
229 * channel 21 (y video) - 10.0k
230 * channel 22 (u video) - 2.0k
231 * channel 23 (v video) - 2.0k
232 * channel 24 (vbi) - 4.0k
b7f355d2 233 * channels 25+26 (audio) - 4.0k
1da177e4 234 * channel 28 (mpeg) - 4.0k
b7f355d2 235 * TOTAL = 29.0k
1da177e4
LT
236 *
237 * Every channel has 160 bytes control data (64 bytes instruction
238 * queue and 6 CDT entries), which is close to 2k total.
239 *
240 * Address layout:
241 * 0x0000 - 0x03ff CMDs / reserved
242 * 0x0400 - 0x0bff instruction queues + CDs
243 * 0x0c00 - FIFOs
244 */
245
246struct sram_channel cx88_sram_channels[] = {
247 [SRAM_CH21] = {
248 .name = "video y / packed",
249 .cmds_start = 0x180040,
250 .ctrl_start = 0x180400,
4ac97914 251 .cdt = 0x180400 + 64,
1da177e4
LT
252 .fifo_start = 0x180c00,
253 .fifo_size = 0x002800,
254 .ptr1_reg = MO_DMA21_PTR1,
255 .ptr2_reg = MO_DMA21_PTR2,
256 .cnt1_reg = MO_DMA21_CNT1,
257 .cnt2_reg = MO_DMA21_CNT2,
258 },
259 [SRAM_CH22] = {
260 .name = "video u",
261 .cmds_start = 0x180080,
262 .ctrl_start = 0x1804a0,
4ac97914 263 .cdt = 0x1804a0 + 64,
1da177e4
LT
264 .fifo_start = 0x183400,
265 .fifo_size = 0x000800,
266 .ptr1_reg = MO_DMA22_PTR1,
267 .ptr2_reg = MO_DMA22_PTR2,
268 .cnt1_reg = MO_DMA22_CNT1,
269 .cnt2_reg = MO_DMA22_CNT2,
270 },
271 [SRAM_CH23] = {
272 .name = "video v",
273 .cmds_start = 0x1800c0,
274 .ctrl_start = 0x180540,
4ac97914 275 .cdt = 0x180540 + 64,
1da177e4
LT
276 .fifo_start = 0x183c00,
277 .fifo_size = 0x000800,
278 .ptr1_reg = MO_DMA23_PTR1,
279 .ptr2_reg = MO_DMA23_PTR2,
280 .cnt1_reg = MO_DMA23_CNT1,
281 .cnt2_reg = MO_DMA23_CNT2,
282 },
283 [SRAM_CH24] = {
284 .name = "vbi",
285 .cmds_start = 0x180100,
286 .ctrl_start = 0x1805e0,
4ac97914 287 .cdt = 0x1805e0 + 64,
1da177e4
LT
288 .fifo_start = 0x184400,
289 .fifo_size = 0x001000,
290 .ptr1_reg = MO_DMA24_PTR1,
291 .ptr2_reg = MO_DMA24_PTR2,
292 .cnt1_reg = MO_DMA24_CNT1,
293 .cnt2_reg = MO_DMA24_CNT2,
294 },
295 [SRAM_CH25] = {
296 .name = "audio from",
297 .cmds_start = 0x180140,
298 .ctrl_start = 0x180680,
4ac97914 299 .cdt = 0x180680 + 64,
1da177e4 300 .fifo_start = 0x185400,
b7f355d2 301 .fifo_size = 0x001000,
1da177e4
LT
302 .ptr1_reg = MO_DMA25_PTR1,
303 .ptr2_reg = MO_DMA25_PTR2,
304 .cnt1_reg = MO_DMA25_CNT1,
305 .cnt2_reg = MO_DMA25_CNT2,
306 },
307 [SRAM_CH26] = {
308 .name = "audio to",
309 .cmds_start = 0x180180,
310 .ctrl_start = 0x180720,
4ac97914 311 .cdt = 0x180680 + 64, /* same as audio IN */
1da177e4 312 .fifo_start = 0x185400, /* same as audio IN */
b7f355d2 313 .fifo_size = 0x001000, /* same as audio IN */
1da177e4
LT
314 .ptr1_reg = MO_DMA26_PTR1,
315 .ptr2_reg = MO_DMA26_PTR2,
316 .cnt1_reg = MO_DMA26_CNT1,
317 .cnt2_reg = MO_DMA26_CNT2,
318 },
319 [SRAM_CH28] = {
320 .name = "mpeg",
321 .cmds_start = 0x180200,
322 .ctrl_start = 0x1807C0,
323 .cdt = 0x1807C0 + 64,
b7f355d2 324 .fifo_start = 0x186400,
1da177e4
LT
325 .fifo_size = 0x001000,
326 .ptr1_reg = MO_DMA28_PTR1,
327 .ptr2_reg = MO_DMA28_PTR2,
328 .cnt1_reg = MO_DMA28_CNT1,
329 .cnt2_reg = MO_DMA28_CNT2,
330 },
331};
332
333int cx88_sram_channel_setup(struct cx88_core *core,
334 struct sram_channel *ch,
335 unsigned int bpl, u32 risc)
336{
337 unsigned int i,lines;
338 u32 cdt;
339
340 bpl = (bpl + 7) & ~7; /* alignment */
341 cdt = ch->cdt;
342 lines = ch->fifo_size / bpl;
343 if (lines > 6)
344 lines = 6;
345 BUG_ON(lines < 2);
346
347 /* write CDT */
348 for (i = 0; i < lines; i++)
349 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
350
351 /* write CMDS */
352 cx_write(ch->cmds_start + 0, risc);
353 cx_write(ch->cmds_start + 4, cdt);
354 cx_write(ch->cmds_start + 8, (lines*16) >> 3);
355 cx_write(ch->cmds_start + 12, ch->ctrl_start);
356 cx_write(ch->cmds_start + 16, 64 >> 2);
357 for (i = 20; i < 64; i += 4)
358 cx_write(ch->cmds_start + i, 0);
359
360 /* fill registers */
361 cx_write(ch->ptr1_reg, ch->fifo_start);
362 cx_write(ch->ptr2_reg, cdt);
363 cx_write(ch->cnt1_reg, (bpl >> 3) -1);
364 cx_write(ch->cnt2_reg, (lines*16) >> 3);
365
366 dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
367 return 0;
368}
369
370/* ------------------------------------------------------------------ */
371/* debug helper code */
372
f9e7a020 373static int cx88_risc_decode(u32 risc)
1da177e4
LT
374{
375 static char *instr[16] = {
376 [ RISC_SYNC >> 28 ] = "sync",
377 [ RISC_WRITE >> 28 ] = "write",
378 [ RISC_WRITEC >> 28 ] = "writec",
379 [ RISC_READ >> 28 ] = "read",
380 [ RISC_READC >> 28 ] = "readc",
381 [ RISC_JUMP >> 28 ] = "jump",
382 [ RISC_SKIP >> 28 ] = "skip",
383 [ RISC_WRITERM >> 28 ] = "writerm",
384 [ RISC_WRITECM >> 28 ] = "writecm",
385 [ RISC_WRITECR >> 28 ] = "writecr",
386 };
387 static int incr[16] = {
388 [ RISC_WRITE >> 28 ] = 2,
389 [ RISC_JUMP >> 28 ] = 2,
390 [ RISC_WRITERM >> 28 ] = 3,
391 [ RISC_WRITECM >> 28 ] = 3,
392 [ RISC_WRITECR >> 28 ] = 4,
393 };
394 static char *bits[] = {
395 "12", "13", "14", "resync",
396 "cnt0", "cnt1", "18", "19",
397 "20", "21", "22", "23",
398 "irq1", "irq2", "eol", "sol",
399 };
400 int i;
401
402 printk("0x%08x [ %s", risc,
403 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
404 for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
405 if (risc & (1 << (i + 12)))
406 printk(" %s",bits[i]);
407 printk(" count=%d ]\n", risc & 0xfff);
408 return incr[risc >> 28] ? incr[risc >> 28] : 1;
409}
410
1da177e4
LT
411
412void cx88_sram_channel_dump(struct cx88_core *core,
413 struct sram_channel *ch)
414{
415 static char *name[] = {
416 "initial risc",
417 "cdt base",
418 "cdt size",
419 "iq base",
420 "iq size",
421 "risc pc",
422 "iq wr ptr",
423 "iq rd ptr",
424 "cdt current",
425 "pci target",
426 "line / byte",
427 };
428 u32 risc;
429 unsigned int i,j,n;
430
431 printk("%s: %s - dma channel status dump\n",
432 core->name,ch->name);
433 for (i = 0; i < ARRAY_SIZE(name); i++)
434 printk("%s: cmds: %-12s: 0x%08x\n",
435 core->name,name[i],
436 cx_read(ch->cmds_start + 4*i));
437 for (i = 0; i < 4; i++) {
438 risc = cx_read(ch->cmds_start + 4 * (i+11));
439 printk("%s: risc%d: ", core->name, i);
440 cx88_risc_decode(risc);
441 }
442 for (i = 0; i < 16; i += n) {
443 risc = cx_read(ch->ctrl_start + 4 * i);
444 printk("%s: iq %x: ", core->name, i);
445 n = cx88_risc_decode(risc);
446 for (j = 1; j < n; j++) {
447 risc = cx_read(ch->ctrl_start + 4 * (i+j));
448 printk("%s: iq %x: 0x%08x [ arg #%d ]\n",
449 core->name, i+j, risc, j);
450 }
451 }
452
453 printk("%s: fifo: 0x%08x -> 0x%x\n",
454 core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
455 printk("%s: ctrl: 0x%08x -> 0x%x\n",
456 core->name, ch->ctrl_start, ch->ctrl_start+6*16);
457 printk("%s: ptr1_reg: 0x%08x\n",
458 core->name,cx_read(ch->ptr1_reg));
459 printk("%s: ptr2_reg: 0x%08x\n",
460 core->name,cx_read(ch->ptr2_reg));
461 printk("%s: cnt1_reg: 0x%08x\n",
462 core->name,cx_read(ch->cnt1_reg));
463 printk("%s: cnt2_reg: 0x%08x\n",
464 core->name,cx_read(ch->cnt2_reg));
465}
466
408b664a 467static char *cx88_pci_irqs[32] = {
1da177e4
LT
468 "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
469 "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
470 "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
471 "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
472};
1da177e4
LT
473
474void cx88_print_irqbits(char *name, char *tag, char **strings,
66623a04 475 int len, u32 bits, u32 mask)
1da177e4
LT
476{
477 unsigned int i;
478
479 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
66623a04 480 for (i = 0; i < len; i++) {
1da177e4
LT
481 if (!(bits & (1 << i)))
482 continue;
483 if (strings[i])
484 printk(" %s", strings[i]);
485 else
486 printk(" %d", i);
487 if (!(mask & (1 << i)))
488 continue;
489 printk("*");
490 }
491 printk("\n");
492}
493
494/* ------------------------------------------------------------------ */
495
496int cx88_core_irq(struct cx88_core *core, u32 status)
497{
498 int handled = 0;
499
8ddac9ee 500 if (status & PCI_INT_IR_SMPINT) {
1da177e4
LT
501 cx88_ir_irq(core);
502 handled++;
503 }
504 if (!handled)
505 cx88_print_irqbits(core->name, "irq pci",
66623a04
MCC
506 cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs),
507 status, core->pci_irqmask);
1da177e4
LT
508 return handled;
509}
510
511void cx88_wakeup(struct cx88_core *core,
512 struct cx88_dmaqueue *q, u32 count)
513{
514 struct cx88_buffer *buf;
515 int bc;
516
517 for (bc = 0;; bc++) {
518 if (list_empty(&q->active))
519 break;
520 buf = list_entry(q->active.next,
521 struct cx88_buffer, vb.queue);
1da177e4
LT
522 /* count comes from the hw and is is 16bit wide --
523 * this trick handles wrap-arounds correctly for
524 * up to 32767 buffers in flight... */
525 if ((s16) (count - buf->count) < 0)
526 break;
1da177e4
LT
527 do_gettimeofday(&buf->vb.ts);
528 dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
529 count, buf->count);
530 buf->vb.state = STATE_DONE;
531 list_del(&buf->vb.queue);
532 wake_up(&buf->vb.done);
533 }
534 if (list_empty(&q->active)) {
535 del_timer(&q->timeout);
536 } else {
537 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
538 }
539 if (bc != 1)
540 printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
541}
542
543void cx88_shutdown(struct cx88_core *core)
544{
545 /* disable RISC controller + IRQs */
546 cx_write(MO_DEV_CNTRL2, 0);
547
548 /* stop dma transfers */
549 cx_write(MO_VID_DMACNTRL, 0x0);
550 cx_write(MO_AUD_DMACNTRL, 0x0);
551 cx_write(MO_TS_DMACNTRL, 0x0);
552 cx_write(MO_VIP_DMACNTRL, 0x0);
553 cx_write(MO_GPHST_DMACNTRL, 0x0);
554
555 /* stop interrupts */
556 cx_write(MO_PCI_INTMSK, 0x0);
557 cx_write(MO_VID_INTMSK, 0x0);
558 cx_write(MO_AUD_INTMSK, 0x0);
559 cx_write(MO_TS_INTMSK, 0x0);
560 cx_write(MO_VIP_INTMSK, 0x0);
561 cx_write(MO_GPHST_INTMSK, 0x0);
562
563 /* stop capturing */
564 cx_write(VID_CAPTURE_CONTROL, 0);
565}
566
567int cx88_reset(struct cx88_core *core)
568{
569 dprintk(1,"%s\n",__FUNCTION__);
570 cx88_shutdown(core);
571
572 /* clear irq status */
573 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
574 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
575 cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
576
577 /* wait a bit */
578 msleep(100);
579
580 /* init sram */
581 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0);
582 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
583 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
584 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
585 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
586 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
587 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
588
589 /* misc init ... */
590 cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable
591 (1 << 12) | // agc gain
592 (1 << 11) | // adaptibe agc
593 (0 << 10) | // chroma agc
594 (0 << 9) | // ckillen
595 (7)));
596
597 /* setup image format */
598 cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
599
600 /* setup FIFO Threshholds */
601 cx_write(MO_PDMA_STHRSH, 0x0807);
602 cx_write(MO_PDMA_DTHRSH, 0x0807);
603
604 /* fixes flashing of image */
605 cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
606 cx_write(MO_AGC_BACK_VBI, 0x00E00555);
607
608 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
609 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
610 cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
611
612 /* Reset on-board parts */
613 cx_write(MO_SRST_IO, 0);
614 msleep(10);
615 cx_write(MO_SRST_IO, 1);
616
617 return 0;
618}
619
620/* ------------------------------------------------------------------ */
621
63ab1bdc 622static unsigned int inline norm_swidth(v4l2_std_id norm)
1da177e4 623{
63ab1bdc 624 return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
1da177e4
LT
625}
626
63ab1bdc 627static unsigned int inline norm_hdelay(v4l2_std_id norm)
1da177e4 628{
63ab1bdc 629 return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
1da177e4
LT
630}
631
63ab1bdc 632static unsigned int inline norm_vdelay(v4l2_std_id norm)
1da177e4 633{
63ab1bdc 634 return (norm & V4L2_STD_625_50) ? 0x24 : 0x18;
1da177e4
LT
635}
636
63ab1bdc 637static unsigned int inline norm_fsc8(v4l2_std_id norm)
1da177e4 638{
63ab1bdc 639 if (norm & V4L2_STD_PAL_M)
315eb962
MCC
640 return 28604892; // 3.575611 MHz
641
63ab1bdc 642 if (norm & (V4L2_STD_PAL_Nc))
315eb962
MCC
643 return 28656448; // 3.582056 MHz
644
63ab1bdc 645 if (norm & V4L2_STD_NTSC) // All NTSC/M and variants
315eb962 646 return 28636360; // 3.57954545 MHz +/- 10 Hz
1da177e4 647
315eb962
MCC
648 /* SECAM have also different sub carrier for chroma,
649 but step_db and step_dr, at cx88_set_tvnorm already handles that.
650
651 The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N
652 */
653
654 return 35468950; // 4.43361875 MHz +/- 5 Hz
1da177e4
LT
655}
656
63ab1bdc 657static unsigned int inline norm_htotal(v4l2_std_id norm)
1da177e4 658{
59dcd948 659
315eb962 660 unsigned int fsc4=norm_fsc8(norm)/2;
59dcd948 661
315eb962 662 /* returns 4*FSC / vtotal / frames per seconds */
63ab1bdc 663 return (norm & V4L2_STD_625_50) ?
315eb962
MCC
664 ((fsc4+312)/625+12)/25 :
665 ((fsc4+262)/525*1001+15000)/30000;
1da177e4
LT
666}
667
63ab1bdc 668static unsigned int inline norm_vbipack(v4l2_std_id norm)
1da177e4 669{
63ab1bdc 670 return (norm & V4L2_STD_625_50) ? 511 : 400;
1da177e4
LT
671}
672
673int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
674 enum v4l2_field field)
675{
676 unsigned int swidth = norm_swidth(core->tvnorm);
677 unsigned int sheight = norm_maxh(core->tvnorm);
678 u32 value;
679
680 dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
681 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
682 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
63ab1bdc 683 v4l2_norm_to_name(core->tvnorm));
1da177e4
LT
684 if (!V4L2_FIELD_HAS_BOTH(field))
685 height *= 2;
686
687 // recalc H delay and scale registers
688 value = (width * norm_hdelay(core->tvnorm)) / swidth;
689 value &= 0x3fe;
690 cx_write(MO_HDELAY_EVEN, value);
691 cx_write(MO_HDELAY_ODD, value);
315eb962 692 dprintk(1,"set_scale: hdelay 0x%04x (width %d)\n", value,swidth);
1da177e4
LT
693
694 value = (swidth * 4096 / width) - 4096;
695 cx_write(MO_HSCALE_EVEN, value);
696 cx_write(MO_HSCALE_ODD, value);
697 dprintk(1,"set_scale: hscale 0x%04x\n", value);
698
699 cx_write(MO_HACTIVE_EVEN, width);
700 cx_write(MO_HACTIVE_ODD, width);
701 dprintk(1,"set_scale: hactive 0x%04x\n", width);
702
703 // recalc V scale Register (delay is constant)
704 cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
705 cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm));
706 dprintk(1,"set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm));
707
708 value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
709 cx_write(MO_VSCALE_EVEN, value);
710 cx_write(MO_VSCALE_ODD, value);
711 dprintk(1,"set_scale: vscale 0x%04x\n", value);
712
713 cx_write(MO_VACTIVE_EVEN, sheight);
714 cx_write(MO_VACTIVE_ODD, sheight);
715 dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
716
717 // setup filters
718 value = 0;
719 value |= (1 << 19); // CFILT (default)
63ab1bdc 720 if (core->tvnorm & V4L2_STD_SECAM) {
1da177e4
LT
721 value |= (1 << 15);
722 value |= (1 << 16);
723 }
6a59d64c 724 if (INPUT(core->input).type == CX88_VMUX_SVIDEO)
1da177e4
LT
725 value |= (1 << 13) | (1 << 5);
726 if (V4L2_FIELD_INTERLACED == field)
727 value |= (1 << 3); // VINT (interlaced vertical scaling)
728 if (width < 385)
729 value |= (1 << 0); // 3-tap interpolation
730 if (width < 193)
731 value |= (1 << 1); // 5-tap interpolation
732 if (nocomb)
733 value |= (3 << 5); // disable comb filter
734
735 cx_write(MO_FILTER_EVEN, value);
736 cx_write(MO_FILTER_ODD, value);
737 dprintk(1,"set_scale: filter 0x%04x\n", value);
738
739 return 0;
740}
741
742static const u32 xtal = 28636363;
743
744static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
745{
746 static u32 pre[] = { 0, 0, 0, 3, 2, 1 };
747 u64 pll;
748 u32 reg;
749 int i;
750
751 if (prescale < 2)
752 prescale = 2;
753 if (prescale > 5)
754 prescale = 5;
755
756 pll = ofreq * 8 * prescale * (u64)(1 << 20);
757 do_div(pll,xtal);
758 reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
759 if (((reg >> 20) & 0x3f) < 14) {
760 printk("%s/0: pll out of range\n",core->name);
761 return -1;
762 }
763
764 dprintk(1,"set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n",
765 reg, cx_read(MO_PLL_REG), ofreq);
766 cx_write(MO_PLL_REG, reg);
767 for (i = 0; i < 100; i++) {
768 reg = cx_read(MO_DEVICE_STATUS);
769 if (reg & (1<<2)) {
770 dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",
771 prescale,ofreq);
772 return 0;
773 }
774 dprintk(1,"pll not locked yet, waiting ...\n");
775 msleep(10);
776 }
777 dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
778 return -1;
779}
780
6f502b8a
MCC
781int cx88_start_audio_dma(struct cx88_core *core)
782{
17801f5f
MR
783 /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
784 int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
e738e35d
RC
785
786 /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
787 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
788 return 0;
789
6f502b8a 790 /* setup fifo + format */
17801f5f
MR
791 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
792 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
6f502b8a 793
17801f5f
MR
794 cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
795 cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */
6f502b8a
MCC
796
797 /* start dma */
798 cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
e738e35d 799
6f502b8a
MCC
800 return 0;
801}
802
803int cx88_stop_audio_dma(struct cx88_core *core)
804{
e738e35d
RC
805 /* If downstream RISC is enabled, bail out; ALSA is managing DMA */
806 if (cx_read(MO_AUD_DMACNTRL) & 0x10)
807 return 0;
808
6f502b8a
MCC
809 /* stop dma */
810 cx_write(MO_AUD_DMACNTRL, 0x0000);
811
812 return 0;
813}
814
1da177e4
LT
815static int set_tvaudio(struct cx88_core *core)
816{
63ab1bdc 817 v4l2_std_id norm = core->tvnorm;
1da177e4 818
6a59d64c 819 if (CX88_VMUX_TELEVISION != INPUT(core->input).type)
1da177e4
LT
820 return 0;
821
63ab1bdc 822 if (V4L2_STD_PAL_BG & norm) {
b1706b91 823 core->tvaudio = WW_BG;
1da177e4 824
63ab1bdc 825 } else if (V4L2_STD_PAL_DK & norm) {
b1706b91 826 core->tvaudio = WW_DK;
1da177e4 827
63ab1bdc 828 } else if (V4L2_STD_PAL_I & norm) {
b1706b91 829 core->tvaudio = WW_I;
1da177e4 830
63ab1bdc 831 } else if (V4L2_STD_SECAM_L & norm) {
b1706b91 832 core->tvaudio = WW_L;
1da177e4 833
63ab1bdc 834 } else if (V4L2_STD_SECAM_DK & norm) {
b1706b91 835 core->tvaudio = WW_DK;
1da177e4 836
63ab1bdc
MCC
837 } else if ((V4L2_STD_NTSC_M & norm) ||
838 (V4L2_STD_PAL_M & norm)) {
1da177e4
LT
839 core->tvaudio = WW_BTSC;
840
63ab1bdc 841 } else if (V4L2_STD_NTSC_M_JP & norm) {
1da177e4
LT
842 core->tvaudio = WW_EIAJ;
843
844 } else {
845 printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
63ab1bdc 846 core->name, v4l2_norm_to_name(core->tvnorm));
1da177e4
LT
847 core->tvaudio = 0;
848 return 0;
849 }
850
851 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
852 cx88_set_tvaudio(core);
e52e98a7 853 /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
1da177e4 854
6f502b8a
MCC
855/*
856 This should be needed only on cx88-alsa. It seems that some cx88 chips have
857 bugs and does require DMA enabled for it to work.
858 */
859 cx88_start_audio_dma(core);
1da177e4
LT
860 return 0;
861}
862
6f502b8a
MCC
863
864
63ab1bdc 865int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
1da177e4
LT
866{
867 u32 fsc8;
868 u32 adc_clock;
869 u32 vdec_clock;
870 u32 step_db,step_dr;
871 u64 tmp64;
872 u32 bdelay,agcdelay,htotal;
8d87cb9f 873 u32 cxiformat, cxoformat;
1da177e4
LT
874
875 core->tvnorm = norm;
876 fsc8 = norm_fsc8(norm);
877 adc_clock = xtal;
878 vdec_clock = fsc8;
879 step_db = fsc8;
880 step_dr = fsc8;
881
63ab1bdc 882 if (norm & V4L2_STD_NTSC_M_JP) {
8d87cb9f
MCC
883 cxiformat = VideoFormatNTSCJapan;
884 cxoformat = 0x181f0008;
63ab1bdc 885 } else if (norm & V4L2_STD_NTSC_443) {
1427f6b6
MCC
886 cxiformat = VideoFormatNTSC443;
887 cxoformat = 0x181f0008;
63ab1bdc 888 } else if (norm & V4L2_STD_PAL_M) {
8d87cb9f
MCC
889 cxiformat = VideoFormatPALM;
890 cxoformat = 0x1c1f0008;
63ab1bdc 891 } else if (norm & V4L2_STD_PAL_N) {
8d87cb9f
MCC
892 cxiformat = VideoFormatPALN;
893 cxoformat = 0x1c1f0008;
63ab1bdc 894 } else if (norm & V4L2_STD_PAL_Nc) {
8d87cb9f
MCC
895 cxiformat = VideoFormatPALNC;
896 cxoformat = 0x1c1f0008;
63ab1bdc 897 } else if (norm & V4L2_STD_PAL_60) {
8d87cb9f
MCC
898 cxiformat = VideoFormatPAL60;
899 cxoformat = 0x181f0008;
63ab1bdc 900 } else if (norm & V4L2_STD_NTSC) {
8d87cb9f
MCC
901 cxiformat = VideoFormatNTSC;
902 cxoformat = 0x181f0008;
63ab1bdc 903 } else if (norm & V4L2_STD_SECAM) {
1da177e4
LT
904 step_db = 4250000 * 8;
905 step_dr = 4406250 * 8;
1427f6b6
MCC
906
907 cxiformat = VideoFormatSECAM;
908 cxoformat = 0x181f0008;
8d87cb9f
MCC
909 } else { /* PAL */
910 cxiformat = VideoFormatPAL;
911 cxoformat = 0x181f0008;
1da177e4
LT
912 }
913
914 dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
63ab1bdc
MCC
915 v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock,
916 step_db, step_dr);
1da177e4
LT
917 set_pll(core,2,vdec_clock);
918
919 dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n",
8d87cb9f
MCC
920 cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
921 cx_andor(MO_INPUT_FORMAT, 0xf, cxiformat);
1da177e4 922
1da177e4
LT
923 // FIXME: as-is from DScaler
924 dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
8d87cb9f
MCC
925 cxoformat, cx_read(MO_OUTPUT_FORMAT));
926 cx_write(MO_OUTPUT_FORMAT, cxoformat);
1da177e4
LT
927
928 // MO_SCONV_REG = adc clock / video dec clock * 2^17
929 tmp64 = adc_clock * (u64)(1 << 17);
930 do_div(tmp64, vdec_clock);
931 dprintk(1,"set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n",
932 (u32)tmp64, cx_read(MO_SCONV_REG));
933 cx_write(MO_SCONV_REG, (u32)tmp64);
934
935 // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
936 tmp64 = step_db * (u64)(1 << 22);
937 do_div(tmp64, vdec_clock);
938 dprintk(1,"set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n",
939 (u32)tmp64, cx_read(MO_SUB_STEP));
940 cx_write(MO_SUB_STEP, (u32)tmp64);
941
942 // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
943 tmp64 = step_dr * (u64)(1 << 22);
944 do_div(tmp64, vdec_clock);
945 dprintk(1,"set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n",
946 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
947 cx_write(MO_SUB_STEP_DR, (u32)tmp64);
948
949 // bdelay + agcdelay
950 bdelay = vdec_clock * 65 / 20000000 + 21;
951 agcdelay = vdec_clock * 68 / 20000000 + 15;
952 dprintk(1,"set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
953 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay);
954 cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
955
956 // htotal
957 tmp64 = norm_htotal(norm) * (u64)vdec_clock;
958 do_div(tmp64, fsc8);
ccbf64b1 959 htotal = (u32)tmp64 | (HLNotchFilter4xFsc << 11);
1da177e4
LT
960 dprintk(1,"set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n",
961 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
962 cx_write(MO_HTOTAL, htotal);
963
3eb73170
TP
964 // vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
965 // the effective vbi offset ~244 samples, the same as the Bt8x8
966 cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm));
1da177e4
LT
967
968 // this is needed as well to set all tvnorm parameter
969 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
970
971 // audio
972 set_tvaudio(core);
973
974 // tell i2c chips
63ab1bdc 975 cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm);
1da177e4
LT
976
977 // done
978 return 0;
979}
980
981/* ------------------------------------------------------------------ */
982
1da177e4
LT
983struct video_device *cx88_vdev_init(struct cx88_core *core,
984 struct pci_dev *pci,
985 struct video_device *template,
986 char *type)
987{
988 struct video_device *vfd;
989
990 vfd = video_device_alloc();
991 if (NULL == vfd)
992 return NULL;
993 *vfd = *template;
994 vfd->minor = -1;
995 vfd->dev = &pci->dev;
996 vfd->release = video_device_release;
997 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
6a59d64c 998 core->name, type, core->board.name);
1da177e4
LT
999 return vfd;
1000}
1001
1da177e4
LT
1002struct cx88_core* cx88_core_get(struct pci_dev *pci)
1003{
1004 struct cx88_core *core;
1005 struct list_head *item;
1da177e4 1006
1e4baed3 1007 mutex_lock(&devlist);
1da177e4
LT
1008 list_for_each(item,&cx88_devlist) {
1009 core = list_entry(item, struct cx88_core, devlist);
1010 if (pci->bus->number != core->pci_bus)
1011 continue;
1012 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1013 continue;
1014
bbc83597
TP
1015 if (0 != cx88_get_resources(core, pci)) {
1016 mutex_unlock(&devlist);
1017 return NULL;
1018 }
1da177e4 1019 atomic_inc(&core->refcount);
1e4baed3 1020 mutex_unlock(&devlist);
1da177e4
LT
1021 return core;
1022 }
b45009b0 1023
bbc83597
TP
1024 core = cx88_core_create(pci, cx88_devcount);
1025 if (NULL != core) {
1026 cx88_devcount++;
1027 list_add_tail(&core->devlist, &cx88_devlist);
1028 }
1da177e4 1029
1e4baed3 1030 mutex_unlock(&devlist);
1da177e4 1031 return core;
1da177e4
LT
1032}
1033
1034void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1035{
1036 release_mem_region(pci_resource_start(pci,0),
1037 pci_resource_len(pci,0));
1038
1039 if (!atomic_dec_and_test(&core->refcount))
1040 return;
1041
1e4baed3 1042 mutex_lock(&devlist);
1da177e4
LT
1043 cx88_ir_fini(core);
1044 if (0 == core->i2c_rc)
3269711b 1045 i2c_del_adapter(&core->i2c_adap);
1da177e4
LT
1046 list_del(&core->devlist);
1047 iounmap(core->lmmio);
1048 cx88_devcount--;
1e4baed3 1049 mutex_unlock(&devlist);
1da177e4
LT
1050 kfree(core);
1051}
1052
1053/* ------------------------------------------------------------------ */
1054
1da177e4
LT
1055EXPORT_SYMBOL(cx88_print_irqbits);
1056
1057EXPORT_SYMBOL(cx88_core_irq);
1058EXPORT_SYMBOL(cx88_wakeup);
1059EXPORT_SYMBOL(cx88_reset);
1060EXPORT_SYMBOL(cx88_shutdown);
1061
1062EXPORT_SYMBOL(cx88_risc_buffer);
1063EXPORT_SYMBOL(cx88_risc_databuffer);
1064EXPORT_SYMBOL(cx88_risc_stopper);
1065EXPORT_SYMBOL(cx88_free_buffer);
1066
1067EXPORT_SYMBOL(cx88_sram_channels);
1068EXPORT_SYMBOL(cx88_sram_channel_setup);
1069EXPORT_SYMBOL(cx88_sram_channel_dump);
1070
1071EXPORT_SYMBOL(cx88_set_tvnorm);
1072EXPORT_SYMBOL(cx88_set_scale);
1073
1074EXPORT_SYMBOL(cx88_vdev_init);
1075EXPORT_SYMBOL(cx88_core_get);
1076EXPORT_SYMBOL(cx88_core_put);
1077
1078/*
1079 * Local variables:
1080 * c-basic-offset: 8
1081 * End:
e52e98a7 1082 * 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
1da177e4 1083 */
This page took 0.346108 seconds and 5 git commands to generate.