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

📄 bttv-driver.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
        { 28636363,          640, 576,  910, 0x68, 0x5d, (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),          780, 130, 734, 0x1a, 144},	/* PAL-M */	{ 28636363,           640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0),	  780, 135, 754, 0x1a, 144},	/* PAL-N */	{ 35468950,           768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_N|BT848_IFORM_XT1),	  944, 186, 922, 0x20, 144},	/* NTSC-Japan */	{ 28636363,          640, 480,  910, 0x68, 0x5d, (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),	  780, 135, 754, 0x16, 144},};#define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))#define VBI_SPL 2044/* RISC command to write one VBI data line */#define VBI_RISC BT848_RISC_WRITE|VBI_SPL|BT848_RISC_EOL|BT848_RISC_SOLstatic void make_vbitab(struct bttv *btv){	int i;	unsigned int *po=(unsigned int *) btv->vbi_odd;	unsigned int *pe=(unsigned int *) btv->vbi_even;  	if (bttv_debug > 1)		printk("bttv%d: vbi1: po=%08lx pe=%08lx\n",		       btv->nr,virt_to_bus(po), virt_to_bus(pe));        	*(po++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(po++)=0;	for (i=0; i<VBI_MAXLINES; i++) 	{		*(po++)=cpu_to_le32(VBI_RISC);		*(po++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));	}	*(po++)=cpu_to_le32(BT848_RISC_JUMP);	*(po++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));	*(pe++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(pe++)=0;	for (i=VBI_MAXLINES; i<VBI_MAXLINES*2; i++) 	{		*(pe++)=cpu_to_le32(VBI_RISC);		*(pe++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));	}	*(pe++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(0x01<<16));	*(pe++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));	if (bttv_debug > 1)		printk("bttv%d: vbi2: po=%08lx pe=%08lx\n",		       btv->nr,virt_to_bus(po), virt_to_bus(pe));}static int fmtbppx2[16] = {        8, 6, 4, 4, 4, 3, 2, 2, 4, 3, 0, 0, 0, 0, 2, 0 };static int palette2fmt[] = {	0,	BT848_COLOR_FMT_Y8,	BT848_COLOR_FMT_RGB8,	BT848_COLOR_FMT_RGB16,	BT848_COLOR_FMT_RGB24,	BT848_COLOR_FMT_RGB32,	BT848_COLOR_FMT_RGB15,	BT848_COLOR_FMT_YUY2,	BT848_COLOR_FMT_YUY2,	-1,	-1,	-1,	BT848_COLOR_FMT_RAW,	BT848_COLOR_FMT_YCrCb422,	BT848_COLOR_FMT_YCrCb411,	BT848_COLOR_FMT_YCrCb422,	BT848_COLOR_FMT_YCrCb411,};#define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(int))static int make_rawrisctab(struct bttv *btv, unsigned int *ro,                            unsigned int *re, unsigned int *vbuf){        unsigned long line;	unsigned long bpl=1024;		/* bytes per line */	unsigned long vadr=(unsigned long) vbuf;	*(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);         *(ro++)=cpu_to_le32(0);	*(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);        *(re++)=cpu_to_le32(0);          /* In PAL 650 blocks of 256 DWORDs are sampled, but only if VDELAY           is 2 and without separate VBI grabbing.           We'll have to handle this inside the IRQ handler ... */	for (line=0; line < 640; line++)	{                *(ro++)=cpu_to_le32(BT848_RISC_WRITE|bpl|BT848_RISC_SOL|BT848_RISC_EOL);                *(ro++)=cpu_to_le32(kvirt_to_bus(vadr));                *(re++)=cpu_to_le32(BT848_RISC_WRITE|bpl|BT848_RISC_SOL|BT848_RISC_EOL);                *(re++)=cpu_to_le32(kvirt_to_bus(vadr+gbufsize/2));                vadr+=bpl;	}		*(ro++)=cpu_to_le32(BT848_RISC_JUMP);	*(ro++)=cpu_to_le32(btv->bus_vbi_even);	*(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));	*(re++)=cpu_to_le32(btv->bus_vbi_odd);		return 0;}static int  make_prisctab(struct bttv *btv, unsigned int *ro,                          unsigned int *re,                           unsigned int *vbuf, unsigned short width,                          unsigned short height, unsigned short fmt){        unsigned long line, lmask;	unsigned long bl, blcr, blcb, rcmd;	unsigned long todo;	unsigned int **rp;	int inter;	unsigned long cbadr, cradr;	unsigned long vadr=(unsigned long) vbuf;	int shift, csize;		if (bttv_debug > 1)		printk("bttv%d: prisc1: ro=%08lx re=%08lx\n",		       btv->nr,virt_to_bus(ro), virt_to_bus(re));	switch(fmt)	{        case VIDEO_PALETTE_YUV422P:                csize=(width*height)>>1;                shift=1;                lmask=0;                break;                        case VIDEO_PALETTE_YUV411P:                csize=(width*height)>>2;                shift=2;                lmask=0;                break;	 					 case VIDEO_PALETTE_YUV420P:                csize=(width*height)>>2;                shift=1;                lmask=1;                break;                	 case VIDEO_PALETTE_YUV410P:                csize=(width*height)>>4;                shift=2;                lmask=3;                break;                        default:                return -1;	}	cbadr=vadr+(width*height);	cradr=cbadr+csize;	inter = (height>tvnorms[btv->win.norm].sheight/2) ? 1 : 0;		*(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);        *(ro++)=0;	*(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);        *(re++)=0;  	for (line=0; line < (height<<(1^inter)); line++)	{		if(line==height)		{			vadr+=csize<<1;			cbadr=vadr+(width*height);			cradr=cbadr+csize;		}	        if (inter) 		        rp= (line&1) ? &re : &ro;		else 	                rp= (line>=height) ? &ro : &re; 	                	        if(line&lmask)	        	rcmd=BT848_RISC_WRITE1S23|BT848_RISC_SOL;	        else	        	rcmd=BT848_RISC_WRITE123|BT848_RISC_SOL;	        todo=width;		while(todo)		{                 bl=PAGE_SIZE-((PAGE_SIZE-1)&vadr);                 blcr=(PAGE_SIZE-((PAGE_SIZE-1)&cradr))<<shift;		 blcb=(PAGE_SIZE-((PAGE_SIZE-1)&cbadr))<<shift;		 bl=(blcr<bl) ? blcr : bl;		 bl=(blcb<bl) ? blcb : bl;		 bl=(bl>todo) ? todo : bl;		 blcr=bl>>shift;		 blcb=blcr;		 /* bl now containts the longest row that can be written */		 todo-=bl;		 if(!todo) rcmd|=BT848_RISC_EOL; /* if this is the last EOL */		 		 *((*rp)++)=cpu_to_le32(rcmd|bl);		 *((*rp)++)=cpu_to_le32(blcb|(blcr<<16));		 *((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));		 vadr+=bl;		 if((rcmd&(15<<28))==BT848_RISC_WRITE123)		 {		 	*((*rp)++)=cpu_to_le32(kvirt_to_bus(cbadr));		 	cbadr+=blcb;		 	*((*rp)++)=cpu_to_le32(kvirt_to_bus(cradr));		 	cradr+=blcr;		 }		 		 rcmd&=~BT848_RISC_SOL; /* only the first has SOL */		}	}		*(ro++)=cpu_to_le32(BT848_RISC_JUMP);	*(ro++)=cpu_to_le32(btv->bus_vbi_even);	*(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));	*(re++)=cpu_to_le32(btv->bus_vbi_odd);		if (bttv_debug > 1)		printk("bttv%d: prisc2: ro=%08lx re=%08lx\n",		       btv->nr,virt_to_bus(ro), virt_to_bus(re));	return 0;} static int  make_vrisctab(struct bttv *btv, unsigned int *ro,                          unsigned int *re,                           unsigned int *vbuf, unsigned short width,                          unsigned short height, unsigned short palette){        unsigned long line;	unsigned long bpl;  /* bytes per line */	unsigned long bl;	unsigned long todo;	unsigned int **rp;	int inter;	unsigned long vadr=(unsigned long) vbuf;        if (palette==VIDEO_PALETTE_RAW)                 return make_rawrisctab(btv, ro, re, vbuf);        if (palette>=VIDEO_PALETTE_PLANAR)                return make_prisctab(btv, ro, re, vbuf, width, height, palette);	if (bttv_debug > 1)		printk("bttv%d: vrisc1: ro=%08lx re=%08lx\n",		       btv->nr,virt_to_bus(ro), virt_to_bus(re));		inter = (height>tvnorms[btv->win.norm].sheight/2) ? 1 : 0;	bpl=width*fmtbppx2[palette2fmt[palette]&0xf]/2;		*(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);         *(ro++)=cpu_to_le32(0);	*(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);        *(re++)=cpu_to_le32(0);  	for (line=0; line < (height<<(1^inter)); line++)	{	        if (inter) 		        rp= (line&1) ? &re : &ro;		else 	                rp= (line>=height) ? &ro : &re; 		bl=PAGE_SIZE-((PAGE_SIZE-1)&vadr);		if (bpl<=bl)                {		        *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|			        BT848_RISC_EOL|bpl); 			*((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));			vadr+=bpl;		}		else		{		        todo=bpl;		        *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|bl);			*((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));			vadr+=bl;			todo-=bl;			while (todo>PAGE_SIZE)			{			        *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|PAGE_SIZE);				*((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));				vadr+=PAGE_SIZE;				todo-=PAGE_SIZE;			}			*((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|todo);			*((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));			vadr+=todo;		}	}		*(ro++)=cpu_to_le32(BT848_RISC_JUMP);	*(ro++)=cpu_to_le32(btv->bus_vbi_even);	*(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));	*(re++)=cpu_to_le32(btv->bus_vbi_odd);	if (bttv_debug > 1)		printk("bttv%d: vrisc2: ro=%08lx re=%08lx\n",		       btv->nr,virt_to_bus(ro), virt_to_bus(re));		return 0;}static unsigned char lmaskt[8] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};static unsigned char rmaskt[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};static void clip_draw_rectangle(unsigned char *clipmap, int x, int y, int w, int h){        unsigned char lmask, rmask, *p;        int W, l, r;	int i;	if (bttv_debug > 1)		printk("bttv clip: %dx%d+%d+%d\n",w,h,x,y);	/* bitmap is fixed width, 128 bytes (1024 pixels represented) */        if (x<0)        {                w+=x;                x=0;        }        if (y<0)        {                h+=y;                y=0;        }	if (w < 0 || h < 0)	/* catch bad clips */		return;	/* out of range data should just fall through */        if (y+h>=625)                h=625-y;        if (x+w>=1024)                w=1024-x;        l=x>>3;        r=(x+w-1)>>3;        W=r-l-1;        lmask=lmaskt[x&7];        rmask=rmaskt[(x+w-1)&7];        p=clipmap+128*y+l;                if (W>0)         {                for (i=0; i<h; i++, p+=128)                 {                        *p|=lmask;                        memset(p+1, 0xff, W);                        p[W+1]|=rmask;                }        } else if (!W) {                for (i=0; i<h; i++, p+=128)                 {                        p[0]|=lmask;                        p[1]|=rmask;                }        } else {                for (i=0; i<h; i++, p+=128)                         p[0]|=lmask&rmask;        }               }static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr){	int i, line, x, y, bpl, width, height, inter, maxw;	unsigned int bpp, dx, sx, **rp, *ro, *re, flags, len;	unsigned long adr;	unsigned char *clipmap, *clipline, cbit, lastbit, outofmem;	/* take care: bpp != btv->win.bpp is allowed here */	bpp = fmtbppx2[btv->win.color_fmt&0xf]/2;	bpl=btv->win.bpl;	adr=btv->win.vidadr + btv->win.x * btv->win.bpp + btv->win.y * bpl;	inter=(btv->win.interlace&1)^1;	width=btv->win.width;	height=btv->win.height;	if (bttv_debug > 1)		printk("bttv%d: clip1: pal=%d size=%dx%d, bpl=%d bpp=%d\n",		       btv->nr,btv->picture.palette,width,height,bpl,bpp);	if(width > 1023)		width = 1023;		/* sanity check */	if(height > 625)		height = 625;		/* sanity check */	ro=btv->risc_scr_odd;	re=btv->risc_scr_even;	if (bttv_debug)		printk("bttv%d: clip: ro=%08lx re=%08lx\n",		       btv->nr,virt_to_bus(ro), virt_to_bus(re));	if ((clipmap=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL) {		/* can't clip, don't generate any risc code */		*(ro++)=cpu_to_le32(BT848_RISC_JUMP);		*(ro++)=cpu_to_le32(btv->bus_vbi_even);		*(re++)=cpu_to_le32(BT848_RISC_JUMP);		*(re++)=cpu_to_le32(btv->bus_vbi_odd);	}	if (ncr < 0) {	/* bitmap was pased */		memcpy(clipmap, (unsigned char *)cr, VIDEO_CLIPMAP_SIZE);	} else {	/* convert rectangular clips to a bitmap */		memset(clipmap, 0, VIDEO_CLIPMAP_SIZE); /* clear map */		for (i=0; i<ncr; i++)			clip_draw_rectangle(clipmap, cr[i].x, cr[i].y,				cr[i].width, cr[i].height);	}	/* clip against viewing window AND screen 	   so we do not have to rely on the user program	 */	maxw = (bpl - btv->win.x * btv->win.bpp) / bpp;	clip_draw_rectangle(clipmap, (width > maxw) ? maxw : width,			    0, 1024, 768);	clip_draw_rectangle(clipmap,0,(btv->win.y+height>btv->win.sheight) ?			    (btv->win.sheight-btv->win.y) : height,1024,768);	if (btv->win.x<0)		clip_draw_rectangle(clipmap, 0, 0, -(btv->win.x), 768);	if (btv->win.y<0)		clip_draw_rectangle(clipmap, 0, 0, 1024, -(btv->win.y));		*(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);        *(ro++)=cpu_to_le32(0);	*(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);        *(re++)=cpu_to_le32(0);		/* translate bitmap to risc code */        for (line=outofmem=0; line < (height<<inter) && !outofmem; line++)        {		y = line>>inter;		rp= (line&1) ? &re : &ro;		clipline = clipmap + (y<<7); /* running pointers ... */		lastbit = *clipline & 1;		for(x=dx=0,sx=0; x<=width && !outofmem;) {			if (0 == (x&7)) {				/* check bytes not bits if we can ... */				if (lastbit) {					while (0xff==*clipline && x<width-8) {						x  += 8;						dx += 8;						clipline++;					}				} else {					while (0x00==*clipline && x<width-8) {						x  += 8;						dx += 8;						clipline++;					}				}			}			cbit = *clipline & (1<<(x&7));			if (x < width && !lastbit == !cbit) {				dx++;			} else {				/* generate the dma controller code */				len = dx * bpp;				flags = ((bpp==4) ? BT848_RISC_BYTE3 : 0);				flags |= ((!sx) ? BT848_RISC_SOL : 0);				flags |= ((sx + dx == width) ? BT848_RISC_EOL : 0);				if (!lastbit) {					*((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|flags|len);					*((*rp)++)=cpu_to_le32(adr + bpp * sx);				} else {					*((*rp)++)=cpu_to_le32(BT848_RISC_SKIP|flags|len);				}				lastbit=cbit;				sx += dx;				dx = 1;				if (ro - btv->risc_scr_odd>(RISCMEM_LEN>>3) - 16)					outofmem++;				if (re - btv->risc_scr_even>(RISCMEM_LEN>>3) - 16)					outofmem++;			}			x++;			if (0 == (x&7))				clipline++;		}		if ((!inter)||(line&1))                        adr+=bpl;	}	vfree(clipmap);	/* outofmem flag relies on the following code to discard extra data */	*(ro++)=cpu_to_le32(BT848_RISC_JUMP);	*(ro++)=cpu_to_le32(btv->bus_vbi_even);	*(re++)=cpu_to_le32(BT848_RISC_JUMP);	*(re++)=cpu_to_le32(btv->bus_vbi_odd);	if (bttv_debug > 1)		printk("bttv%d: clip2: pal=%d size=%dx%d, bpl=%d bpp=%d\n",		       btv->nr,btv->picture.palette,width,height,bpl,bpp);}/* *	Set the registers for the size we have specified. Don't bother *	trying to understand this without the BT848 manual in front of *	you [AC].  *

⌨️ 快捷键说明

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