⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cx88-core.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	cx_write(ch->cmds_start + 12, ch->ctrl_start);	cx_write(ch->cmds_start + 16, 64 >> 2);	for (i = 20; i < 64; i += 4)		cx_write(ch->cmds_start + i, 0);	/* fill registers */	cx_write(ch->ptr1_reg, ch->fifo_start);	cx_write(ch->ptr2_reg, cdt);	cx_write(ch->cnt1_reg, (bpl >> 3) -1);	cx_write(ch->cnt2_reg, (lines*16) >> 3);	dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);	return 0;}/* ------------------------------------------------------------------ *//* debug helper code                                                  */static int cx88_risc_decode(u32 risc){	static char *instr[16] = {		[ RISC_SYNC    >> 28 ] = "sync",		[ RISC_WRITE   >> 28 ] = "write",		[ RISC_WRITEC  >> 28 ] = "writec",		[ RISC_READ    >> 28 ] = "read",		[ RISC_READC   >> 28 ] = "readc",		[ RISC_JUMP    >> 28 ] = "jump",		[ RISC_SKIP    >> 28 ] = "skip",		[ RISC_WRITERM >> 28 ] = "writerm",		[ RISC_WRITECM >> 28 ] = "writecm",		[ RISC_WRITECR >> 28 ] = "writecr",	};	static int incr[16] = {		[ RISC_WRITE   >> 28 ] = 2,		[ RISC_JUMP    >> 28 ] = 2,		[ RISC_WRITERM >> 28 ] = 3,		[ RISC_WRITECM >> 28 ] = 3,		[ RISC_WRITECR >> 28 ] = 4,	};	static char *bits[] = {		"12",   "13",   "14",   "resync",		"cnt0", "cnt1", "18",   "19",		"20",   "21",   "22",   "23",		"irq1", "irq2", "eol",  "sol",	};	int i;	printk("0x%08x [ %s", risc,	       instr[risc >> 28] ? instr[risc >> 28] : "INVALID");	for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)		if (risc & (1 << (i + 12)))			printk(" %s",bits[i]);	printk(" count=%d ]\n", risc & 0xfff);	return incr[risc >> 28] ? incr[risc >> 28] : 1;}void cx88_sram_channel_dump(struct cx88_core *core,			    struct sram_channel *ch){	static char *name[] = {		"initial risc",		"cdt base",		"cdt size",		"iq base",		"iq size",		"risc pc",		"iq wr ptr",		"iq rd ptr",		"cdt current",		"pci target",		"line / byte",	};	u32 risc;	unsigned int i,j,n;	printk("%s: %s - dma channel status dump\n",	       core->name,ch->name);	for (i = 0; i < ARRAY_SIZE(name); i++)		printk("%s:   cmds: %-12s: 0x%08x\n",		       core->name,name[i],		       cx_read(ch->cmds_start + 4*i));	for (i = 0; i < 4; i++) {		risc = cx_read(ch->cmds_start + 4 * (i+11));		printk("%s:   risc%d: ", core->name, i);		cx88_risc_decode(risc);	}	for (i = 0; i < 16; i += n) {		risc = cx_read(ch->ctrl_start + 4 * i);		printk("%s:   iq %x: ", core->name, i);		n = cx88_risc_decode(risc);		for (j = 1; j < n; j++) {			risc = cx_read(ch->ctrl_start + 4 * (i+j));			printk("%s:   iq %x: 0x%08x [ arg #%d ]\n",			       core->name, i+j, risc, j);		}	}	printk("%s: fifo: 0x%08x -> 0x%x\n",	       core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);	printk("%s: ctrl: 0x%08x -> 0x%x\n",	       core->name, ch->ctrl_start, ch->ctrl_start+6*16);	printk("%s:   ptr1_reg: 0x%08x\n",	       core->name,cx_read(ch->ptr1_reg));	printk("%s:   ptr2_reg: 0x%08x\n",	       core->name,cx_read(ch->ptr2_reg));	printk("%s:   cnt1_reg: 0x%08x\n",	       core->name,cx_read(ch->cnt1_reg));	printk("%s:   cnt2_reg: 0x%08x\n",	       core->name,cx_read(ch->cnt2_reg));}static char *cx88_pci_irqs[32] = {	"vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",	"src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",	"brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",	"i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"};void cx88_print_irqbits(char *name, char *tag, char **strings,			u32 bits, u32 mask){	unsigned int i;	printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);	for (i = 0; i < 32; i++) {		if (!(bits & (1 << i)))			continue;		if (strings[i])			printk(" %s", strings[i]);		else			printk(" %d", i);		if (!(mask & (1 << i)))			continue;		printk("*");	}	printk("\n");}/* ------------------------------------------------------------------ */int cx88_core_irq(struct cx88_core *core, u32 status){	int handled = 0;	if (status & (1<<18)) {		cx88_ir_irq(core);		handled++;	}	if (!handled)		cx88_print_irqbits(core->name, "irq pci",				   cx88_pci_irqs, status,				   core->pci_irqmask);	return handled;}void cx88_wakeup(struct cx88_core *core,		 struct cx88_dmaqueue *q, u32 count){	struct cx88_buffer *buf;	int bc;	for (bc = 0;; bc++) {		if (list_empty(&q->active))			break;		buf = list_entry(q->active.next,				 struct cx88_buffer, vb.queue);		/* count comes from the hw and is is 16bit wide --		 * this trick handles wrap-arounds correctly for		 * up to 32767 buffers in flight... */		if ((s16) (count - buf->count) < 0)			break;		do_gettimeofday(&buf->vb.ts);		dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,			count, buf->count);		buf->vb.state = STATE_DONE;		list_del(&buf->vb.queue);		wake_up(&buf->vb.done);	}	if (list_empty(&q->active)) {		del_timer(&q->timeout);	} else {		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);	}	if (bc != 1)		printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);}void cx88_shutdown(struct cx88_core *core){	/* disable RISC controller + IRQs */	cx_write(MO_DEV_CNTRL2, 0);	/* stop dma transfers */	cx_write(MO_VID_DMACNTRL, 0x0);	cx_write(MO_AUD_DMACNTRL, 0x0);	cx_write(MO_TS_DMACNTRL, 0x0);	cx_write(MO_VIP_DMACNTRL, 0x0);	cx_write(MO_GPHST_DMACNTRL, 0x0);	/* stop interrupts */	cx_write(MO_PCI_INTMSK, 0x0);	cx_write(MO_VID_INTMSK, 0x0);	cx_write(MO_AUD_INTMSK, 0x0);	cx_write(MO_TS_INTMSK, 0x0);	cx_write(MO_VIP_INTMSK, 0x0);	cx_write(MO_GPHST_INTMSK, 0x0);	/* stop capturing */	cx_write(VID_CAPTURE_CONTROL, 0);}int cx88_reset(struct cx88_core *core){	dprintk(1,"%s\n",__FUNCTION__);	cx88_shutdown(core);	/* clear irq status */	cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int	cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int	cx_write(MO_INT1_STAT,   0xFFFFFFFF); // Clear RISC int	/* wait a bit */	msleep(100);	/* init sram */	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0);	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);	/* misc init ... */	cx_write(MO_INPUT_FORMAT, ((1 << 13) |   // agc enable				   (1 << 12) |   // agc gain				   (1 << 11) |   // adaptibe agc				   (0 << 10) |   // chroma agc				   (0 <<  9) |   // ckillen				   (7)));	/* setup image format */	cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);	/* setup FIFO Threshholds */	cx_write(MO_PDMA_STHRSH,   0x0807);	cx_write(MO_PDMA_DTHRSH,   0x0807);	/* fixes flashing of image */	cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);	cx_write(MO_AGC_BACK_VBI,  0x00E00555);	cx_write(MO_VID_INTSTAT,   0xFFFFFFFF); // Clear PIV int	cx_write(MO_PCI_INTSTAT,   0xFFFFFFFF); // Clear PCI int	cx_write(MO_INT1_STAT,     0xFFFFFFFF); // Clear RISC int	/* Reset on-board parts */	cx_write(MO_SRST_IO, 0);	msleep(10);	cx_write(MO_SRST_IO, 1);	return 0;}/* ------------------------------------------------------------------ */static unsigned int inline norm_swidth(struct cx88_tvnorm *norm){	return (norm->id & V4L2_STD_625_50) ? 922 : 754;}static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm){	return (norm->id & V4L2_STD_625_50) ? 186 : 135;}static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm){	return (norm->id & V4L2_STD_625_50) ? 0x24 : 0x18;}static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm){	static const unsigned int ntsc = 28636360;	static const unsigned int pal  = 35468950;	static const unsigned int palm  = 28604892;	if (norm->id & V4L2_STD_PAL_M)		return palm;	return (norm->id & V4L2_STD_625_50) ? pal : ntsc;}static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm){	return (norm->id & V4L2_STD_625_50)		? HLNotchFilter135PAL		: HLNotchFilter135NTSC;}static unsigned int inline norm_htotal(struct cx88_tvnorm *norm){	/* Should always be Line Draw Time / (4*FSC) */	if (norm->id & V4L2_STD_PAL_M)		return 909;	return (norm->id & V4L2_STD_625_50) ? 1135 : 910;}static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm){	return (norm->id & V4L2_STD_625_50) ? 511 : 288;}int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,		   enum v4l2_field field){	unsigned int swidth  = norm_swidth(core->tvnorm);	unsigned int sheight = norm_maxh(core->tvnorm);	u32 value;	dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,		V4L2_FIELD_HAS_TOP(field)    ? "T" : "",		V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",		core->tvnorm->name);	if (!V4L2_FIELD_HAS_BOTH(field))		height *= 2;	// recalc H delay and scale registers	value = (width * norm_hdelay(core->tvnorm)) / swidth;	value &= 0x3fe;	cx_write(MO_HDELAY_EVEN,  value);	cx_write(MO_HDELAY_ODD,   value);	dprintk(1,"set_scale: hdelay  0x%04x\n", value);	value = (swidth * 4096 / width) - 4096;	cx_write(MO_HSCALE_EVEN,  value);	cx_write(MO_HSCALE_ODD,   value);	dprintk(1,"set_scale: hscale  0x%04x\n", value);	cx_write(MO_HACTIVE_EVEN, width);	cx_write(MO_HACTIVE_ODD,  width);	dprintk(1,"set_scale: hactive 0x%04x\n", width);	// recalc V scale Register (delay is constant)	cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));	cx_write(MO_VDELAY_ODD,  norm_vdelay(core->tvnorm));	dprintk(1,"set_scale: vdelay  0x%04x\n", norm_vdelay(core->tvnorm));	value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;	cx_write(MO_VSCALE_EVEN,  value);	cx_write(MO_VSCALE_ODD,   value);	dprintk(1,"set_scale: vscale  0x%04x\n", value);	cx_write(MO_VACTIVE_EVEN, sheight);	cx_write(MO_VACTIVE_ODD,  sheight);	dprintk(1,"set_scale: vactive 0x%04x\n", sheight);	// setup filters	value = 0;	value |= (1 << 19);        // CFILT (default)	if (core->tvnorm->id & V4L2_STD_SECAM) {		value |= (1 << 15);		value |= (1 << 16);	}	if (INPUT(core->input)->type == CX88_VMUX_SVIDEO)		value |= (1 << 13) | (1 << 5);	if (V4L2_FIELD_INTERLACED == field)		value |= (1 << 3); // VINT (interlaced vertical scaling)	if (width < 385)		value |= (1 << 0); // 3-tap interpolation	if (width < 193)		value |= (1 << 1); // 5-tap interpolation	if (nocomb)		value |= (3 << 5); // disable comb filter	cx_write(MO_FILTER_EVEN,  value);	cx_write(MO_FILTER_ODD,   value);	dprintk(1,"set_scale: filter  0x%04x\n", value);	return 0;}static const u32 xtal = 28636363;static int set_pll(struct cx88_core *core, int prescale, u32 ofreq){	static u32 pre[] = { 0, 0, 0, 3, 2, 1 };	u64 pll;	u32 reg;	int i;	if (prescale < 2)		prescale = 2;	if (prescale > 5)		prescale = 5;	pll = ofreq * 8 * prescale * (u64)(1 << 20);	do_div(pll,xtal);	reg = (pll & 0x3ffffff) | (pre[prescale] << 26);	if (((reg >> 20) & 0x3f) < 14) {		printk("%s/0: pll out of range\n",core->name);		return -1;	}	dprintk(1,"set_pll:    MO_PLL_REG       0x%08x [old=0x%08x,freq=%d]\n",		reg, cx_read(MO_PLL_REG), ofreq);	cx_write(MO_PLL_REG, reg);	for (i = 0; i < 100; i++) {		reg = cx_read(MO_DEVICE_STATUS);		if (reg & (1<<2)) {			dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",				prescale,ofreq);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -