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

📄 buz.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
	u32 reg;	zr36060_reset(zr);	mdelay(10);	reg = (0 << 7)		/* Load=0 */	    |(1 << 0);		/* SynRst=1 */	zr36060_write_8(zr, 0x000, reg);	zr36060_set_jpg(zr, mode);	zr36060_set_video(zr, mode);	zr36060_set_jpg_SOF(zr);	zr36060_set_jpg_SOS(zr);	zr36060_set_jpg_DRI(zr);	zr36060_set_jpg_DQT(zr);	zr36060_set_jpg_DHT(zr);	zr36060_set_jpg_APP(zr);	zr36060_set_jpg_COM(zr);	reg = (1 << 7)		/* Load=1 */	    |(0 << 0);		/* SynRst=0 */	zr36060_write_8(zr, 0x000, reg);	/* wait for codec to unbusy */	for (i = 0; i < 1000; ++i) {		reg = zr36060_read_8(zr, 0x001);		if ((reg & (1 << 7)) == 0) {			DEBUG(printk(KERN_DEBUG "060: loaded, loops=%u\n", i));			return;		}		udelay(1000);	}	printk(KERN_INFO "060: stuck busy, statux=%02x\n", reg);}static void zr36057_set_jpg(struct zoran *zr, enum zoran_codec_mode mode){	struct tvnorm *tvn;	u32 reg;	int i;	tvn = &tvnorms[zr->params.norm];	/* assert P_Reset */	btwrite(0, ZR36057_JPC);	/* re-initialize DMA ring stuff */	zr->jpg_que_head = 0;	zr->jpg_dma_head = 0;	zr->jpg_dma_tail = 0;	zr->jpg_que_tail = 0;	zr->jpg_seq_num = 0;	for (i = 0; i < BUZ_NUM_STAT_COM; ++i) {		zr->stat_com[i] = 1;	/* mark as unavailable to zr36057 */	}	for (i = 0; i < zr->jpg_nbufs; i++) {		zr->jpg_gbuf[i].state = BUZ_STATE_USER;	/* nothing going on */	}	/* MJPEG compression mode */	switch (mode) {	case BUZ_MODE_MOTION_COMPRESS:	default:		reg = ZR36057_JMC_MJPGCmpMode;		break;	case BUZ_MODE_MOTION_DECOMPRESS:		reg = ZR36057_JMC_MJPGExpMode;		reg |= ZR36057_JMC_SyncMstr;		/* RJ: The following is experimental - improves the output to screen */		if (zr->params.VFIFO_FB)			reg |= ZR36057_JMC_VFIFO_FB;		break;	case BUZ_MODE_STILL_COMPRESS:		reg = ZR36057_JMC_JPGCmpMode;		break;	case BUZ_MODE_STILL_DECOMPRESS:		reg = ZR36057_JMC_JPGExpMode;		break;	}	reg |= ZR36057_JMC_JPG;	if (zr->params.field_per_buff == 1)		reg |= ZR36057_JMC_Fld_per_buff;	btwrite(reg, ZR36057_JMC);	/* vertical */	btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR);	reg = (6 << ZR36057_VSP_VsyncSize) | (tvn->Ht << ZR36057_VSP_FrmTot);	btwrite(reg, ZR36057_VSP);	reg = ((zr->params.img_y + tvn->VStart) << ZR36057_FVAP_NAY)	    | (zr->params.img_height << ZR36057_FVAP_PAY);	btwrite(reg, ZR36057_FVAP);	/* horizontal */	btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR);	reg = ((tvn->Wt - 100) << ZR36057_HSP_HsyncStart) | (tvn->Wt << ZR36057_HSP_LineTot);	btwrite(reg, ZR36057_HSP);	reg = ((zr->params.img_x + tvn->HStart) << ZR36057_FHAP_NAX)	    | (zr->params.img_width << ZR36057_FHAP_PAX);	btwrite(reg, ZR36057_FHAP);	/* field process parameters */	if (zr->params.odd_even)		reg = ZR36057_FPP_Odd_Even;	else		reg = 0;	btwrite(reg, ZR36057_FPP);	/* Set proper VCLK Polarity, else colors will be wrong during playback */	btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR);	/* code base address and FIFO threshold */	reg = virt_to_bus(zr->stat_com);	btwrite(reg, ZR36057_JCBA);	reg = 0x50;	btwrite(reg, ZR36057_JCFT);	/* JPEG codec guest ID */	reg = (1 << ZR36057_JCGI_JPEGuestID) | (0 << ZR36057_JCGI_JPEGuestReg);	btwrite(reg, ZR36057_JCGI);	/* Code transfer guest ID */	reg = (0 << ZR36057_MCTCR_CodGuestID) | (3 << ZR36057_MCTCR_CodGuestReg);	reg |= ZR36057_MCTCR_CFlush;	btwrite(reg, ZR36057_MCTCR);	/* deassert P_Reset */	btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC);}static void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode){	static int zero = 0;	static int one = 1;	switch (mode) {	case BUZ_MODE_MOTION_COMPRESS:		zr36060_set_cap(zr, mode);		zr36057_set_jpg(zr, mode);		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &one);		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &zero);		/* deassert P_Reset, assert Code transfer enable */		btwrite(IRQ_MASK, ZR36057_ISR);		btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR);		break;	case BUZ_MODE_MOTION_DECOMPRESS:		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &zero);		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &one);		zr36060_set_cap(zr, mode);		zr36057_set_jpg(zr, mode);		/* deassert P_Reset, assert Code transfer enable */		btwrite(IRQ_MASK, ZR36057_ISR);		btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR);		break;	case BUZ_MODE_IDLE:	default:		/* shut down processing */		btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);		btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC);		btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC);		btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC);		btand(~ZR36057_JMC_Go_en, ZR36057_JMC);		btwrite(0, ZR36057_ISR);		zr36060_reset(zr);		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &one);		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &zero);		break;	}	zr->codec_mode = mode;}/* *   Queue a MJPEG buffer for capture/playback */static int jpg_qbuf(struct zoran *zr, int frame, enum zoran_codec_mode mode){	unsigned long flags;	int res;	/* Check if buffers are allocated */	if (!zr->jpg_buffers_allocated) {		printk(KERN_ERR "%s: jpg_qbuf: buffers not yet allocated\n", zr->name);		return -ENOMEM;	}	/* Does the user want to stop streaming? */	if (frame < 0) {		if (zr->codec_mode == mode) {			zr36057_enable_jpg(zr, BUZ_MODE_IDLE);			return 0;		} else {			printk(KERN_ERR "%s: jpg_qbuf - stop streaming but not in streaming mode\n", zr->name);			return -EINVAL;		}	}	/* No grabbing outside the buffer range! */	if (frame >= zr->jpg_nbufs) {		printk(KERN_ERR "%s: jpg_qbuf: buffer %d out of range\n", zr->name, frame);		return -EINVAL;	}	/* what is the codec mode right now? */	if (zr->codec_mode == BUZ_MODE_IDLE) {		/* Ok load up the zr36060 and go */		zr36057_enable_jpg(zr, mode);	} else if (zr->codec_mode != mode) {		/* wrong codec mode active - invalid */		printk(KERN_ERR "%s: jpg_qbuf - codec in wrong mode\n", zr->name);		return -EINVAL;	}	spin_lock_irqsave(&zr->lock, flags);	/* make sure a grab isn't going on currently with this buffer */	switch (zr->jpg_gbuf[frame].state) {	default:	case BUZ_STATE_DMA:	case BUZ_STATE_PEND:	case BUZ_STATE_DONE:		res = -EBUSY;	/* what are you doing? */		break;	case BUZ_STATE_USER:		/* since there is at least one unused buffer there's room for at least one more pend[] entry */		zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = frame;		zr->jpg_gbuf[frame].state = BUZ_STATE_PEND;		zoran_feed_stat_com(zr);		res = 0;		break;	}	spin_unlock_irqrestore(&zr->lock, flags);	/* Start the zr36060 when the first frame is queued  */	if (zr->jpg_que_head == 1) {		btor(ZR36057_JMC_Go_en, ZR36057_JMC);		btwrite(ZR36057_JPC_P_Reset | ZR36057_JPC_CodTrnsEn | ZR36057_JPC_Active, ZR36057_JPC);	}	return res;}/* *   Sync on a MJPEG buffer */static int jpg_sync(struct zoran *zr, struct zoran_sync *bs){	unsigned long flags;	int frame;	if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&	    zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {		return -EINVAL;	}	while (zr->jpg_que_tail == zr->jpg_dma_tail) {		interruptible_sleep_on(&zr->jpg_capq);		if (signal_pending(current))			return -ERESTARTSYS;	}	spin_lock_irqsave(&zr->lock, flags);	frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME];	/* buffer should now be in BUZ_STATE_DONE */	if (zr->jpg_gbuf[frame].state != BUZ_STATE_DONE)		printk(KERN_ERR "%s: jpg_sync - internal error\n", zr->name);	*bs = zr->jpg_gbuf[frame].bs;	zr->jpg_gbuf[frame].state = BUZ_STATE_USER;	spin_unlock_irqrestore(&zr->lock, flags);	return 0;}/* when this is called the spinlock must be held */static void zoran_feed_stat_com(struct zoran *zr){	/* move frames from pending queue to DMA */	int frame, i, max_stat_com;	max_stat_com = (zr->params.TmpDcm == 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1);	while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com	       && zr->jpg_dma_head != zr->jpg_que_head) {		frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME];		if (zr->params.TmpDcm == 1) {			/* fill 1 stat_com entry */			i = zr->jpg_dma_head & BUZ_MASK_STAT_COM;			zr->stat_com[i] = zr->jpg_gbuf[frame].frag_tab_bus;		} else {			/* fill 2 stat_com entries */			i = (zr->jpg_dma_head & 1) * 2;			zr->stat_com[i] = zr->jpg_gbuf[frame].frag_tab_bus;			zr->stat_com[i + 1] = zr->jpg_gbuf[frame].frag_tab_bus;		}		zr->jpg_gbuf[frame].state = BUZ_STATE_DMA;		zr->jpg_dma_head++;	}}/* when this is called the spinlock must be held */static void zoran_reap_stat_com(struct zoran *zr){	/* move frames from DMA queue to done queue */	int i;	u32 stat_com;	unsigned int seq;	unsigned int dif;	int frame;	struct zoran_gbuffer *gbuf;	/* In motion decompress we don't have a hardware frame counter,	   we just count the interrupts here */	if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)		zr->jpg_seq_num++;	while (zr->jpg_dma_tail != zr->jpg_dma_head) {		if (zr->params.TmpDcm == 1)			i = zr->jpg_dma_tail & BUZ_MASK_STAT_COM;		else			i = (zr->jpg_dma_tail & 1) * 2 + 1;		stat_com = zr->stat_com[i];		if ((stat_com & 1) == 0) {			return;		}		frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];		gbuf = &zr->jpg_gbuf[frame];		get_fast_time(&gbuf->bs.timestamp);		if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {			gbuf->bs.length = (stat_com & 0x7fffff) >> 1;			/* update sequence number with the help of the counter in stat_com */			seq = stat_com >> 24;			dif = (seq - zr->jpg_seq_num) & 0xff;			zr->jpg_seq_num += dif;		} else {			gbuf->bs.length = 0;		}		gbuf->bs.seq = zr->params.TmpDcm == 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num;		gbuf->state = BUZ_STATE_DONE;		zr->jpg_dma_tail++;	}}static void zoran_irq(int irq, void *dev_id, struct pt_regs *regs){	u32 stat, astat;	int count;	struct zoran *zr;	unsigned long flags;	zr = (struct zoran *) dev_id;	count = 0;	spin_lock_irqsave(&zr->lock, flags);	while (1) {		/* get/clear interrupt status bits */		stat = btread(ZR36057_ISR);		astat = stat & IRQ_MASK;		if (!astat) {			break;		}		btwrite(astat, ZR36057_ISR);		IDEBUG(printk(BUZ_DEBUG "-%u: astat %08x stat %08x\n", zr->id, astat, stat));#if (IRQ_MASK & ZR36057_ISR_GIRQ0)		if (astat & ZR36057_ISR_GIRQ0) {			/* Interrupts may still happen when zr->v4l_memgrab_active is switched off.			   We simply ignore them */			if (zr->v4l_memgrab_active) {/* A lot more checks should be here ... */				if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0)					printk(KERN_WARNING "%s: BuzIRQ with SnapShot off ???\n", zr->name);				if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) {					/* There is a grab on a frame going on, check if it has finished */					if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) {						/* it is finished, notify the user */						zr->v4l_gbuf[zr->v4l_grab_frame].state = BUZ_STATE_DONE;						zr->v4l_grab_frame = NO_GRAB_ACTIVE;						zr->v4l_grab_seq++;						zr->v4l_pend_tail++;					}				}				if (zr->v4l_grab_frame == NO_GRAB_ACTIVE)					wake_up_interruptible(&zr->v4l_capq);				/* Check if there is another grab queued */				if (zr->v4l_grab_frame == NO_GRAB_ACTIVE &&				    zr->v4l_pend_tail != zr->v4l_pend_head) {					int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];					u32 reg;					zr->v4l_grab_frame = frame;					/* Set zr36057 video front end and enable video */					/* Buffer address */					reg = zr->v4l_gbuf[frame].fbuffer_bus;					btwrite(reg, ZR36057_VDTR);					if (zr->video_interlace)						reg += zr->gbpl;					btwrite(reg, ZR36057_VDBR);					/* video stride, status, and frame grab register */#ifdef XAWTV_HACK					reg = (zr->gwidth > 720) ? ((zr->gwidth & ~3) - 720) * zr->gbpl / zr->gwidth : 0;#else					reg = 0;#endif					if (zr->video_interlace)						reg += zr->gbpl;					reg = (reg << ZR36057_VSSFGR_DispStride);					reg |= ZR36057_VSSFGR_VidOvf;					reg |= ZR36057_VSSFGR_SnapShot;					reg |= ZR36057_VSSFGR_FrameGrab;					btwrite(reg, ZR36057_VSSFGR);					btor(ZR36057_VDCR_VidEn, ZR36057_VDCR);				}			}		}#endif				/* (IRQ_MASK & ZR36057_ISR_GIRQ0) */#if (IRQ_MASK & ZR36057_ISR_GIRQ1)		if (astat & ZR36057_ISR_GIRQ1) {			unsigned csr = zr36060_read_8(zr, 0x001);			unsigned isr = zr36060_read_8(zr, 0x008);			IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_GIRQ1 60_code=%02x 60_intr=%02x\n",				      zr->name, csr, isr));			btand(~ZR36057_ICR_GIRQ1, ZR36057_ICR);			zoran_reap_stat_com(zr);			zoran_feed_stat_com(zr);		}#endif				/* (IRQ_MASK & ZR36057_ISR_GIRQ1) */#if (IRQ_MASK & ZR36057_ISR_CodRepIRQ)		if (astat & ZR36057_ISR_CodRepIRQ) {			IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", zr->name));			btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR);		}#endif				/* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */#if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ)		if ((astat & ZR36057_ISR_JPEGRepIRQ) &&		    (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||		     zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) {			zoran_reap_stat_com(zr);			zoran_feed_stat_com(zr);			wake_up_interruptible(&zr->jpg_capq);		}#endif				/* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */		count++;		if (count > 10) {			printk(KERN_WARNING "%s: irq loop %d\n", zr->name, count);			if (count > 20) {				btwrite(0, ZR36057_ICR);				printk(KERN_ERR  "%s: IRQ lockup, cleared int mask\n", zr->name);				break;			}		}	}	spin_unlock_irqrestore(&zr->lock, flags);}/* Check a zoran_params struct for correctness, insert default params */static int zoran_check_params(struct zoran *zr, struct zoran_params *params){	int err = 0, err0 = 0;

⌨️ 快捷键说明

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