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

📄 zr36067.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
				if (!zr->jpg_gbuf[i].frag_tab[2 * j])					break;				mem_map_unreserve(MAP_NR						  (bus_to_virt						   (zr->jpg_gbuf[i].						    frag_tab[2 * j])));				free_page((unsigned long)					  bus_to_virt(zr->jpg_gbuf[i].						      frag_tab[2 * j]));				zr->jpg_gbuf[i].frag_tab[2 * j] = 0;				zr->jpg_gbuf[i].frag_tab[2 * j + 1] = 0;			}		}		free_page((unsigned long) zr->jpg_gbuf[i].frag_tab);		zr->jpg_gbuf[i].frag_tab = NULL;	}	zr->jpg_buffers_allocated = 0;}/* ----------------------------------------------------------------------- *//* I2C functions                                                           */#define I2C_DELAY   10/* software I2C functions */static void i2c_setlines(struct i2c_bus *bus, int ctrl, int data){	struct zoran *zr = (struct zoran *) bus->data;	btwrite((data << 1) | ctrl, ZR36057_I2CBR);	udelay(I2C_DELAY);}static int i2c_getdataline(struct i2c_bus *bus){	struct zoran *zr = (struct zoran *) bus->data;	return (btread(ZR36057_I2CBR) >> 1) & 1;}static void attach_inform(struct i2c_bus *bus, int id){	int i;	struct zoran *zr = (struct zoran *) bus->data;	DEBUG1(printk(KERN_DEBUG "%s: i2c attach %02x\n", zr->name, id));	for (i = 0; i < bus->devcount; i++) {		if (strcmp(bus->devices[i]->name, "saa7110") == 0) {			if (zr->revision < 2) {				zr->card = DC10;				sprintf(zr->name, "DC10[%u]", zr->id);			} else {				zr->card = DC10plus;				sprintf(zr->name, "DC10plus[%u]", zr->id);			}			break;		}		if (strcmp(bus->devices[i]->name, "bt819") == 0) {			zr->card = LML33;			sprintf(zr->name, "LML33[%u]", zr->id);			break;		}		if (strcmp(bus->devices[i]->name, "saa7111") == 0) {			zr->card = BUZ;			sprintf(zr->name, "Buz[%u]", zr->id);			break;		}	}}static void detach_inform(struct i2c_bus *bus, int id){	DEBUG1(struct zoran *zr = (struct zoran *) bus->data);	DEBUG1(printk(KERN_DEBUG "%s: i2c detach %02x\n", zr->name, id));}static struct i2c_bus zoran_i2c_bus_template = {	"zr36057",	I2C_BUSID_BT848,	NULL,	SPIN_LOCK_UNLOCKED,	attach_inform,	detach_inform,	i2c_setlines,	i2c_getdataline,	NULL,	NULL,};/* *   Set the registers for the size we have specified. Don't bother *   trying to understand this without the ZR36057 manual in front of *   you [AC]. * *   PS: The manual is free for download in .pdf format from *   www.zoran.com - nicely done those folks. */static struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 };static struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 };static struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 };static struct tvnorm f60ccir601 = { 858, 720, 57, 788, 525, 480, 16 };static struct tvnorm *dc10norms[] = {	&f50sqpixel,		/* PAL-BDGHI */	&f60sqpixel,		/* NTSC */	&f50sqpixel,		/* SECAM */};static struct tvnorm *lml33norms[] = {	&f50ccir601,		/* PAL-BDGHI */	&f60ccir601,		/* NTSC      */	NULL,			/* SECAM (not supported in LML33) */};static struct tvnorm *buznorms[] = {	&f50ccir601,		/* PAL-BDGHI */	&f60ccir601,		/* NTSC      */	NULL,			/* SECAM     */};static struct tvnorm *unsupported[] = {	NULL,			/* PAL-BDGHI */	NULL,			/* NTSC      */	NULL,			/* SECAM     */};static struct tvnorm **cardnorms[] = {	unsupported,		/* UNKNOWN  */	dc10norms,		/* DC10     */	dc10norms,		/* DC10plus */	lml33norms,		/* LML33    */	buznorms,		/* Buz      */};static u32 cardvsync[] = {	0,			/* UNKNOWN  */	ZR36057_ISR_GIRQ1,	/* DC10     */	ZR36057_ISR_GIRQ1,	/* DC10plus */	ZR36057_ISR_GIRQ0,	/* LML33    */	ZR36057_ISR_GIRQ0,	/* Buz      */};static u32 cardjpegint[] = {	0,			/* UNKNOWN  */	ZR36057_ISR_GIRQ0,	/* DC10     */	ZR36057_ISR_GIRQ0,	/* DC10plus */	ZR36057_ISR_GIRQ1,	/* LML33    */	ZR36057_ISR_GIRQ1,	/* Buz      */};static int format2bpp(int format){	int bpp;	/* Determine the number of bytes per pixel for the video format requested */	switch (format) {	case VIDEO_PALETTE_YUV422:		bpp = 2;		break;	case VIDEO_PALETTE_RGB555:		bpp = 2;		break;	case VIDEO_PALETTE_RGB565:		bpp = 2;		break;	case VIDEO_PALETTE_RGB24:		bpp = 3;		break;	case VIDEO_PALETTE_RGB32:		bpp = 4;		break;	default:		bpp = 0;	}	return bpp;}static void zr36057_adjust_vfe(struct zoran *zr,			       enum zoran_codec_mode mode){	u32 reg;	switch (mode) {	case BUZ_MODE_MOTION_DECOMPRESS:		btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);		reg = btread(ZR36057_VFEHCR);		if (reg & (1 << 10)) {			reg += ((1 << 10) | 1);		}		btwrite(reg, ZR36057_VFEHCR);		break;	case BUZ_MODE_MOTION_COMPRESS:	case BUZ_MODE_IDLE:	default:		if (zr->params.norm == VIDEO_MODE_NTSC)			btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);		else			btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);		reg = btread(ZR36057_VFEHCR);		if (!(reg & (1 << 10))) {			reg -= ((1 << 10) | 1);		}		btwrite(reg, ZR36057_VFEHCR);		break;	}}/* * set geometry */static void zr36057_set_vfe(struct zoran *zr, int video_width,			    int video_height, unsigned int video_format){	struct tvnorm *tvn;	unsigned HStart, HEnd, VStart, VEnd;	unsigned DispMode;	unsigned VidWinWid, VidWinHt;	unsigned hcrop1, hcrop2, vcrop1, vcrop2;	unsigned Wa, We, Ha, He;	unsigned X, Y, HorDcm, VerDcm;	u32 reg;	unsigned mask_line_size;	tvn = zr->timing;	Wa = tvn->Wa;	Ha = tvn->Ha;	DEBUG1(printk (BUZ_INFO ": width = %d, height = %d\n", video_width, video_height));	if (zr->params.norm != VIDEO_MODE_PAL	    && zr->params.norm != VIDEO_MODE_NTSC	    && zr->params.norm != VIDEO_MODE_SECAM) {		printk(KERN_ERR "%s: set_vfe: video_norm = %d not valid\n",		       zr->name, zr->params.norm);		return;	}	if (video_width < BUZ_MIN_WIDTH || video_height < BUZ_MIN_HEIGHT	    || video_width > Wa || video_height > Ha) {		printk(KERN_ERR "%s: set_vfe: w=%d h=%d not valid\n",		       zr->name, video_width, video_height);		return;	}	/* if window has more than half of active height,	   switch on interlacing - we want the full information */	zr->video_interlace = (video_height > Ha / 2);	/**** zr36057 ****/	/* horizontal */	VidWinWid = video_width;	X = (VidWinWid * 64 + tvn->Wa - 1) / tvn->Wa;	We = (VidWinWid * 64) / X;	HorDcm = 64 - X;	hcrop1 = 2 * ((tvn->Wa - We) / 4);	hcrop2 = tvn->Wa - We - hcrop1;	HStart = tvn->HStart | 1;	if (zr->card == LML33)		HStart += 62;	if (zr->card == BUZ) {	//HStart += 67;		HStart += 44;	}	HEnd = HStart + tvn->Wa - 1;	HStart += hcrop1;	HEnd -= hcrop2;	reg = ((HStart & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HStart)	    | ((HEnd & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HEnd);	if (zr->card != BUZ)		reg |= ZR36057_VFEHCR_HSPol;	btwrite(reg, ZR36057_VFEHCR);	/* Vertical */	DispMode = !zr->video_interlace;	VidWinHt = DispMode ? video_height : video_height / 2;	Y = (VidWinHt * 64 * 2 + tvn->Ha - 1) / tvn->Ha;	He = (VidWinHt * 64) / Y;	VerDcm = 64 - Y;	vcrop1 = (tvn->Ha / 2 - He) / 2;	vcrop2 = tvn->Ha / 2 - He - vcrop1;	VStart = tvn->VStart;	VEnd = VStart + tvn->Ha / 2 - 1;	VStart += vcrop1;	VEnd -= vcrop2;	reg = ((VStart & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VStart)	    | ((VEnd & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VEnd);	reg |= ZR36057_VFEVCR_VSPol;	btwrite(reg, ZR36057_VFEVCR);	/* scaler and pixel format */	reg = 0;	reg |= (HorDcm << ZR36057_VFESPFR_HorDcm);	reg |= (VerDcm << ZR36057_VFESPFR_VerDcm);	reg |= (DispMode << ZR36057_VFESPFR_DispMode);	reg |= ZR36057_VFESPFR_LittleEndian;	/* RJ: I don't know, why the following has to be the opposite	   of the corresponding ZR36060 setting, but only this way	   we get the correct colors when uncompressing to the screen  */	//reg |= ZR36057_VFESPFR_VCLKPol; /**/	/* RJ: Don't know if that is needed for NTSC also */	if (zr->params.norm != VIDEO_MODE_NTSC)		reg |= ZR36057_VFESPFR_ExtFl;	// NEEDED!!!!!!! Wolfgang	reg |= ZR36057_VFESPFR_TopField;	switch (video_format) {	case VIDEO_PALETTE_YUV422:		reg |= ZR36057_VFESPFR_YUV422;		break;	case VIDEO_PALETTE_RGB555:		reg |= ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ErrDif;		break;	case VIDEO_PALETTE_RGB565:		reg |= ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ErrDif;		break;	case VIDEO_PALETTE_RGB24:		reg |= ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_Pack24;		break;	case VIDEO_PALETTE_RGB32:		reg |= ZR36057_VFESPFR_RGB888;		break;	default:		printk(KERN_INFO "%s: Unknown color_fmt=%x\n", zr->name,		       video_format);		return;	}	if (HorDcm >= 48) {		reg |= 3 << ZR36057_VFESPFR_HFilter;	/* 5 tap filter */	} else if (HorDcm >= 32) {		reg |= 2 << ZR36057_VFESPFR_HFilter;	/* 4 tap filter */	} else if (HorDcm >= 16) {		reg |= 1 << ZR36057_VFESPFR_HFilter;	/* 3 tap filter */	}	btwrite(reg, ZR36057_VFESPFR);	/* display configuration */	reg = (16 << ZR36057_VDCR_MinPix)	    | (VidWinHt << ZR36057_VDCR_VidWinHt)	    | (VidWinWid << ZR36057_VDCR_VidWinWid);	if (triton || zr->revision <= 1)		reg &= ~ZR36057_VDCR_Triton;	else		reg |= ZR36057_VDCR_Triton;	btwrite(reg, ZR36057_VDCR);	/* Write overlay clipping mask data, but don't enable overlay clipping */	/* RJ: since this makes only sense on the screen, we use 	   zr->window.width instead of video_width */	mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;	reg = virt_to_bus(zr->overlay_mask);	btwrite(reg, ZR36057_MMTR);	reg = virt_to_bus(zr->overlay_mask + mask_line_size);	btwrite(reg, ZR36057_MMBR);	reg = mask_line_size - (zr->window.width + 31) / 32;	if (DispMode == 0)		reg += mask_line_size;	reg <<= ZR36057_OCR_MaskStride;	btwrite(reg, ZR36057_OCR);	zr36057_adjust_vfe(zr, zr->codec_mode);}/* * Switch overlay on or off */static void zr36057_overlay(struct zoran *zr, int on){	int fmt, bpp;	u32 reg;	if (on) {		/* do the necessary settings ... */		btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);	/* switch it off first */		switch (zr->buffer.depth) {		case 15:			fmt = VIDEO_PALETTE_RGB555;			bpp = 2;			break;		case 16:			fmt = VIDEO_PALETTE_RGB565;			bpp = 2;			break;		case 24:			fmt = VIDEO_PALETTE_RGB24;			bpp = 3;			break;		case 32:			fmt = VIDEO_PALETTE_RGB32;			bpp = 4;			break;		default:			fmt = 0;			bpp = 0;		}		zr36057_set_vfe(zr, zr->window.width, zr->window.height,				fmt);		/* Start and length of each line MUST be 4-byte aligned.		   This should be allready checked before the call to this routine.		   All error messages are internal driver checking only! */		/* video display top and bottom registers */		reg =		    (u32) zr->buffer.base + zr->window.x * bpp +		    zr->window.y * zr->buffer.bytesperline;		btwrite(reg, ZR36057_VDTR);		if (reg & 3)			printk(KERN_ERR			       "%s: zr36057_overlay: video_address not aligned\n",			       zr->name);		if (zr->video_interlace)			reg += zr->buffer.bytesperline;		btwrite(reg, ZR36057_VDBR);		/* video stride, status, and frame grab register */		reg = zr->buffer.bytesperline - zr->window.width * bpp;		if (zr->video_interlace)			reg += zr->buffer.bytesperline;		if (reg & 3)			printk(KERN_ERR			       "%s: zr36057_overlay: video_stride not aligned\n",			       zr->name);		reg = (reg << ZR36057_VSSFGR_DispStride);		reg |= ZR36057_VSSFGR_VidOvf;	/* clear overflow status */		btwrite(reg, ZR36057_VSSFGR);		/* Set overlay clipping */		if (zr->window.clipcount)			btor(ZR36057_OCR_OvlEnable, ZR36057_OCR);		/* ... and switch it on */		btor(ZR36057_VDCR_VidEn, ZR36057_VDCR);	} else {		/* Switch it off */		btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);	}}/* * The overlay mask has one bit for each pixel on a scan line, *  and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels. */static void write_overlay_mask(struct zoran *zr, struct video_clip *vp,			       int count){	unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;	u32 *mask;	int x, y, width, height;	unsigned i, j, k;	u32 reg;	/* fill mask with one bits */	memset(zr->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT);	reg = 0;	for (i = 0; i < count; ++i) {		/* pick up local copy of clip */		x = vp[i].x;		y = vp[i].y;		width = vp[i].width;		height = vp[i].height;		/* trim clips that extend beyond the window */		if (x < 0) {			width += x;			x = 0;		}		if (y < 0) {			height += y;			y = 0;		}		if (x + width > zr->window.width) {			width = zr->window.width - x;		}		if (y + height > zr->window.height) {			height = zr->window.height - y;		}		/* ignore degenerate clips */		if (height <= 0) {			continue;

⌨️ 快捷键说明

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