• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/media/video/cx88/
1/*
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 *
8 * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
9 *     - Multituner support
10 *     - video_ioctl2 conversion
11 *     - PAL/M fixes
12 *
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>
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/* @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be
73	 generated _after_ lpi lines are transferred. */
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	/* sync instruction */
83	if (sync_line != NO_SYNC_LINE)
84		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
85
86	/* scan lines */
87	sg = sglist;
88	for (line = 0; line < lines; line++) {
89		while (offset && offset >= sg_dma_len(sg)) {
90			offset -= sg_dma_len(sg);
91			sg++;
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			/* fits into current chunk */
99			*(rp++)=cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl);
100			*(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
101			offset+=bpl;
102		} else {
103			/* scanline needs to be split */
104			todo = bpl;
105			*(rp++)=cpu_to_le32(RISC_WRITE|sol|
106					    (sg_dma_len(sg)-offset));
107			*(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
108			todo -= (sg_dma_len(sg)-offset);
109			offset = 0;
110			sg++;
111			while (todo > sg_dma_len(sg)) {
112				*(rp++)=cpu_to_le32(RISC_WRITE|
113						    sg_dma_len(sg));
114				*(rp++)=cpu_to_le32(sg_dma_address(sg));
115				todo -= sg_dma_len(sg);
116				sg++;
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	/* estimate risc mem: worst case is one write per page border +
144	   one write per scan line + syncs + jump (all 2 dwords).  Padding
145	   can cause next bpl to start close to a page border.  First DMA
146	   region may be smaller than PAGE_SIZE */
147	instructions  = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
148	instructions += 2;
149	if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
150		return rc;
151
152	/* write risc instructions */
153	rp = risc->cpu;
154	if (UNSET != top_offset)
155		rp = cx88_risc_field(rp, sglist, top_offset, 0,
156				     bpl, padding, lines, 0);
157	if (UNSET != bottom_offset)
158		rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
159				     bpl, padding, lines, 0);
160
161	/* save pointer to jmp instruction address */
162	risc->jmp = rp;
163	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
164	return 0;
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	/* estimate risc mem: worst case is one write per page border +
176	   one write per scan line + syncs + jump (all 2 dwords).  Here
177	   there is no padding and no sync.  First DMA region may be smaller
178	   than PAGE_SIZE */
179	instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
180	instructions += 1;
181	if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
182		return rc;
183
184	/* write risc instructions */
185	rp = risc->cpu;
186	rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines, lpi);
187
188	/* save pointer to jmp instruction address */
189	risc->jmp = rp;
190	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
191	return 0;
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	/* write risc instructions */
204	rp = risc->cpu;
205	*(rp++) = cpu_to_le32(RISC_WRITECR  | RISC_IRQ2 | RISC_IMM);
206	*(rp++) = cpu_to_le32(reg);
207	*(rp++) = cpu_to_le32(value);
208	*(rp++) = cpu_to_le32(mask);
209	*(rp++) = cpu_to_le32(RISC_JUMP);
210	*(rp++) = cpu_to_le32(risc->dma);
211	return 0;
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->dev, dma);
222	videobuf_dma_free(dma);
223	btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
224	buf->vb.state = VIDEOBUF_NEEDS_INIT;
225}
226
227/* ------------------------------------------------------------------ */
228/* our SRAM memory layout                                             */
229
230/* we are going to put all thr risc programs into host memory, so we
231 * can use the whole SDRAM for the DMA fifos.  To simplify things, we
232 * use a static memory layout.  That surely will waste memory in case
233 * we don't use all DMA channels at the same time (which will be the
234 * case most of the time).  But that still gives us enough FIFO space
235 * to be able to deal with insane long pci latencies ...
236 *
237 * FIFO space allocations:
238 *    channel  21    (y video)  - 10.0k
239 *    channel  22    (u video)  -  2.0k
240 *    channel  23    (v video)  -  2.0k
241 *    channel  24    (vbi)      -  4.0k
242 *    channels 25+26 (audio)    -  4.0k
243 *    channel  28    (mpeg)     -  4.0k
244 *    channel  27    (audio rds)-  3.0k
245 *    TOTAL                     = 29.0k
246 *
247 * Every channel has 160 bytes control data (64 bytes instruction
248 * queue and 6 CDT entries), which is close to 2k total.
249 *
250 * Address layout:
251 *    0x0000 - 0x03ff    CMDs / reserved
252 *    0x0400 - 0x0bff    instruction queues + CDs
253 *    0x0c00 -           FIFOs
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,  /* same as audio IN */
322		.fifo_start = 0x185400,       /* same as audio IN */
323		.fifo_size  = 0x001000,       /* same as audio IN */
324		.ptr1_reg   = MO_DMA26_PTR1,
325		.ptr2_reg   = MO_DMA26_PTR2,
326		.cnt1_reg   = MO_DMA26_CNT1,
327		.cnt2_reg   = MO_DMA26_CNT2,
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; /* alignment */
363	cdt   = ch->cdt;
364	lines = ch->fifo_size / bpl;
365	if (lines > 6)
366		lines = 6;
367	BUG_ON(lines < 2);
368
369	/* write CDT */
370	for (i = 0; i < lines; i++)
371		cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
372
373	/* write CMDS */
374	cx_write(ch->cmds_start +  0, risc);
375	cx_write(ch->cmds_start +  4, cdt);
376	cx_write(ch->cmds_start +  8, (lines*16) >> 3);
377	cx_write(ch->cmds_start + 12, ch->ctrl_start);
378	cx_write(ch->cmds_start + 16, 64 >> 2);
379	for (i = 20; i < 64; i += 4)
380		cx_write(ch->cmds_start + i, 0);
381
382	/* fill registers */
383	cx_write(ch->ptr1_reg, ch->fifo_start);
384	cx_write(ch->ptr2_reg, cdt);
385	cx_write(ch->cnt1_reg, (bpl >> 3) -1);
386	cx_write(ch->cnt2_reg, (lines*16) >> 3);
387
388	dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
389	return 0;
390}
391
392/* ------------------------------------------------------------------ */
393/* debug helper code                                                  */
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		/* count comes from the hw and is is 16bit wide --
548		 * this trick handles wrap-arounds correctly for
549		 * up to 32767 buffers in flight... */
550		if ((s16) (count - buf->count) < 0)
551			break;
552		do_gettimeofday(&buf->vb.ts);
553		dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
554			count, buf->count);
555		buf->vb.state = VIDEOBUF_DONE;
556		list_del(&buf->vb.queue);
557		wake_up(&buf->vb.done);
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	/* disable RISC controller + IRQs */
572	cx_write(MO_DEV_CNTRL2, 0);
573
574	/* stop dma transfers */
575	cx_write(MO_VID_DMACNTRL, 0x0);
576	cx_write(MO_AUD_DMACNTRL, 0x0);
577	cx_write(MO_TS_DMACNTRL, 0x0);
578	cx_write(MO_VIP_DMACNTRL, 0x0);
579	cx_write(MO_GPHST_DMACNTRL, 0x0);
580
581	/* stop interrupts */
582	cx_write(MO_PCI_INTMSK, 0x0);
583	cx_write(MO_VID_INTMSK, 0x0);
584	cx_write(MO_AUD_INTMSK, 0x0);
585	cx_write(MO_TS_INTMSK, 0x0);
586	cx_write(MO_VIP_INTMSK, 0x0);
587	cx_write(MO_GPHST_INTMSK, 0x0);
588
589	/* stop capturing */
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	/* clear irq status */
599	cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
600	cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
601	cx_write(MO_INT1_STAT,   0xFFFFFFFF); // Clear RISC int
602
603	/* wait a bit */
604	msleep(100);
605
606	/* init sram */
607	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0);
608	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
609	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
610	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
611	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
612	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
613	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
614	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH27], 128, 0);
615
616	/* misc init ... */
617	cx_write(MO_INPUT_FORMAT, ((1 << 13) |   // agc enable
618				   (1 << 12) |   // agc gain
619				   (1 << 11) |   // adaptibe agc
620				   (0 << 10) |   // chroma agc
621				   (0 <<  9) |   // ckillen
622				   (7)));
623
624	/* setup image format */
625	cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
626
627	/* setup FIFO Thresholds */
628	cx_write(MO_PDMA_STHRSH,   0x0807);
629	cx_write(MO_PDMA_DTHRSH,   0x0807);
630
631	/* fixes flashing of image */
632	cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
633	cx_write(MO_AGC_BACK_VBI,  0x00E00555);
634
635	cx_write(MO_VID_INTSTAT,   0xFFFFFFFF); // Clear PIV int
636	cx_write(MO_PCI_INTSTAT,   0xFFFFFFFF); // Clear PCI int
637	cx_write(MO_INT1_STAT,     0xFFFFFFFF); // Clear RISC int
638
639	/* Reset on-board parts */
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;      // 3.575611 MHz
668
669	if (norm & (V4L2_STD_PAL_Nc))
670		return 28656448;      // 3.582056 MHz
671
672	if (norm & V4L2_STD_NTSC) // All NTSC/M and variants
673		return 28636360;      // 3.57954545 MHz +/- 10 Hz
674
675	/* SECAM have also different sub carrier for chroma,
676	   but step_db and step_dr, at cx88_set_tvnorm already handles that.
677
678	   The same FSC applies to PAL/BGDKIH, PAL/60, NTSC/4.43 and PAL/N
679	 */
680
681	return 35468950;      // 4.43361875 MHz +/- 5 Hz
682}
683
684static unsigned int inline norm_htotal(v4l2_std_id norm)
685{
686
687	unsigned int fsc4=norm_fsc8(norm)/2;
688
689	/* returns 4*FSC / vtotal / frames per seconds */
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	// recalc H delay and scale registers
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	// recalc V scale Register (delay is constant)
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	// setup filters
745	value = 0;
746	value |= (1 << 19);        // CFILT (default)
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); // VINT (interlaced vertical scaling)
755	if (width < 385)
756		value |= (1 << 0); // 3-tap interpolation
757	if (width < 193)
758		value |= (1 << 1); // 5-tap interpolation
759	if (nocomb)
760		value |= (3 << 5); // disable comb filter
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	/* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
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	/* If downstream RISC is enabled, bail out; ALSA is managing DMA */
816	if (cx_read(MO_AUD_DMACNTRL) & 0x10)
817		return 0;
818
819	/* setup fifo + format */
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); /* fifo bpl size */
826	cx_write(MO_AUDR_LNGTH, rds_bpl); /* fifo bpl size */
827
828	/* enable Up, Down and Audio RDS fifo */
829	cx_write(MO_AUD_DMACNTRL, 0x0007);
830
831	return 0;
832}
833
834int cx88_stop_audio_dma(struct cx88_core *core)
835{
836	/* If downstream RISC is enabled, bail out; ALSA is managing DMA */
837	if (cx_read(MO_AUD_DMACNTRL) & 0x10)
838		return 0;
839
840	/* stop dma */
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	    CX88_VMUX_CABLE != INPUT(core->input).type)
852		return 0;
853
854	if (V4L2_STD_PAL_BG & norm) {
855		core->tvaudio = WW_BG;
856
857	} else if (V4L2_STD_PAL_DK & norm) {
858		core->tvaudio = WW_DK;
859
860	} else if (V4L2_STD_PAL_I & norm) {
861		core->tvaudio = WW_I;
862
863	} else if (V4L2_STD_SECAM_L & norm) {
864		core->tvaudio = WW_L;
865
866	} else if ((V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H) & norm) {
867		core->tvaudio = WW_BG;
868
869	} else if (V4L2_STD_SECAM_DK & norm) {
870		core->tvaudio = WW_DK;
871
872	} else if ((V4L2_STD_NTSC_M & norm) ||
873		   (V4L2_STD_PAL_M  & norm)) {
874		core->tvaudio = WW_BTSC;
875
876	} else if (V4L2_STD_NTSC_M_JP & norm) {
877		core->tvaudio = WW_EIAJ;
878
879	} else {
880		printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
881		       core->name, v4l2_norm_to_name(core->tvnorm));
882		core->tvaudio = 0;
883		return 0;
884	}
885
886	cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
887	cx88_set_tvaudio(core);
888	/* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
889
890/*
891   This should be needed only on cx88-alsa. It seems that some cx88 chips have
892   bugs and does require DMA enabled for it to work.
893 */
894	cx88_start_audio_dma(core);
895	return 0;
896}
897
898
899
900int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
901{
902	u32 fsc8;
903	u32 adc_clock;
904	u32 vdec_clock;
905	u32 step_db,step_dr;
906	u64 tmp64;
907	u32 bdelay,agcdelay,htotal;
908	u32 cxiformat, cxoformat;
909
910	core->tvnorm = norm;
911	fsc8       = norm_fsc8(norm);
912	adc_clock  = xtal;
913	vdec_clock = fsc8;
914	step_db    = fsc8;
915	step_dr    = fsc8;
916
917	if (norm & V4L2_STD_NTSC_M_JP) {
918		cxiformat = VideoFormatNTSCJapan;
919		cxoformat = 0x181f0008;
920	} else if (norm & V4L2_STD_NTSC_443) {
921		cxiformat = VideoFormatNTSC443;
922		cxoformat = 0x181f0008;
923	} else if (norm & V4L2_STD_PAL_M) {
924		cxiformat = VideoFormatPALM;
925		cxoformat = 0x1c1f0008;
926	} else if (norm & V4L2_STD_PAL_N) {
927		cxiformat = VideoFormatPALN;
928		cxoformat = 0x1c1f0008;
929	} else if (norm & V4L2_STD_PAL_Nc) {
930		cxiformat = VideoFormatPALNC;
931		cxoformat = 0x1c1f0008;
932	} else if (norm & V4L2_STD_PAL_60) {
933		cxiformat = VideoFormatPAL60;
934		cxoformat = 0x181f0008;
935	} else if (norm & V4L2_STD_NTSC) {
936		cxiformat = VideoFormatNTSC;
937		cxoformat = 0x181f0008;
938	} else if (norm & V4L2_STD_SECAM) {
939		step_db = 4250000 * 8;
940		step_dr = 4406250 * 8;
941
942		cxiformat = VideoFormatSECAM;
943		cxoformat = 0x181f0008;
944	} else { /* PAL */
945		cxiformat = VideoFormatPAL;
946		cxoformat = 0x181f0008;
947	}
948
949	dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
950		v4l2_norm_to_name(core->tvnorm), fsc8, adc_clock, vdec_clock,
951		step_db, step_dr);
952	set_pll(core,2,vdec_clock);
953
954	dprintk(1,"set_tvnorm: MO_INPUT_FORMAT  0x%08x [old=0x%08x]\n",
955		cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
956	/* Chroma AGC must be disabled if SECAM is used, we enable it
957	   by default on PAL and NTSC */
958	cx_andor(MO_INPUT_FORMAT, 0x40f,
959		 norm & V4L2_STD_SECAM ? cxiformat : cxiformat | 0x400);
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	// MO_SCONV_REG = adc clock / video dec clock * 2^17
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	// MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
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	// MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
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	// bdelay + agcdelay
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	// htotal
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	// vbi stuff, set vbi offset to 10 (for 20 Clk*2 pixels), this makes
1002	// the effective vbi offset ~244 samples, the same as the Bt8x8
1003	cx_write(MO_VBI_PACKET, (10<<11) | norm_vbipack(norm));
1004
1005	// this is needed as well to set all tvnorm parameter
1006	cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
1007
1008	// audio
1009	set_tvaudio(core);
1010
1011	// tell i2c chips
1012	call_all(core, core, s_std, norm);
1013
1014	// done
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 * Local variables:
1122 * c-basic-offset: 8
1123 * End:
1124 * 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
1125 */
1126