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

📄 planb.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
			/* Reset clip mask */			memset ((void *) pb->mask, 0xff, (pb->maxlines					* ((PLANB_MAXPIXELS + 7) & ~7)) / 8);			/* Add any clip rects */			for (i = 0; i < vw.clipcount; i++) {				if (copy_from_user(&clip, vw.clips + i,						sizeof(struct video_clip)))					return -EFAULT;				add_clip(pb, &clip);			}			/* restart overlay if it was running */			resume_overlay(pb);			planb_unlock(pb);			return 0;		}		case VIDIOCGWIN:		{			struct video_window vw;			DBG("PlanB: IOCTL VIDIOCGWIN\n");			vw.x=pb->win.x;			vw.y=pb->win.y;			vw.width=pb->win.width;			vw.height=pb->win.height;			vw.chromakey=0;			vw.flags=0;			if(pb->win.interlace)				vw.flags|=VIDEO_WINDOW_INTERLACE;			if(copy_to_user(arg,&vw,sizeof(vw)))				return -EFAULT;			return 0;		}	        case VIDIOCSYNC: {			int		i;			gbuf_ptr	gbuf;			DBG("PlanB: IOCTL VIDIOCSYNC\n");			if(copy_from_user((void *)&i,arg,sizeof(int)))				return -EFAULT;			DBG("PlanB: sync to frame %d\n", i);                        if(i > (MAX_GBUFFERS - 1) || i < 0)                                return -EINVAL;			gbuf = &pb->gbuf[i];chk_grab:                        switch (*gbuf->status) {                        case GBUFFER_UNUSED:                                return -EINVAL;			case GBUFFER_GRABBING:				DBG("PlanB: waiting for grab"							" done (%d)\n", i); 			        interruptible_sleep_on(&pb->capq);				if(signal_pending(current))					return -EINTR;				goto chk_grab;                        case GBUFFER_DONE:                                *gbuf->status = GBUFFER_UNUSED;                                break;                        }                        return 0;		}	        case VIDIOCMCAPTURE:		{                        struct video_mmap vm;			int		  fr;			DBG("PlanB: IOCTL VIDIOCMCAPTURE\n");			if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))				return -EFAULT;			fr = vm.frame;                        if(fr > (MAX_GBUFFERS - 1) || fr < 0)                                return -EINVAL;			if (*pb->gbuf[fr].status != GBUFFER_UNUSED)				return -EBUSY;			return vgrab(pb, &vm);		}				case VIDIOCGMBUF:		{			int i;			struct video_mbuf vm;			DBG("PlanB: IOCTL VIDIOCGMBUF\n");			memset(&vm, 0 , sizeof(vm));			vm.size = PLANB_MAX_FBUF * MAX_GBUFFERS;			vm.frames = MAX_GBUFFERS;			for(i = 0; i<MAX_GBUFFERS; i++)				vm.offsets[i] = PLANB_MAX_FBUF * i;			if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))				return -EFAULT;			return 0;		}				case VIDIOCGUNIT:		{			struct video_unit vu;			DBG("PlanB: IOCTL VIDIOCGUNIT\n");			vu.video=pb->video_dev.minor;			vu.vbi=pb->vbi_dev.minor;			vu.radio=VIDEO_NO_UNIT;			vu.audio=VIDEO_NO_UNIT;			vu.teletext=VIDEO_NO_UNIT;			if(copy_to_user((void *)arg, (void *)&vu, sizeof(vu)))				return -EFAULT;			return 0;		}		case PLANBIOCGSAAREGS:		{			struct planb_saa_regs preg;			DBG("PlanB: IOCTL PLANBIOCGSAAREGS\n");			if(copy_from_user(&preg, arg, sizeof(preg)))				return -EFAULT;			if(preg.addr >= SAA7196_NUMREGS)				return -EINVAL;			preg.val = saa_regs[pb->win.norm][preg.addr];			if(copy_to_user((void *)arg, (void *)&preg,								sizeof(preg)))				return -EFAULT;			return 0;		}				case PLANBIOCSSAAREGS:		{			struct planb_saa_regs preg;			DBG("PlanB: IOCTL PLANBIOCSSAAREGS\n");			if(copy_from_user(&preg, arg, sizeof(preg)))				return -EFAULT;			if(preg.addr >= SAA7196_NUMREGS)				return -EINVAL;			saa_set (preg.addr, preg.val, pb);			return 0;		}				case PLANBIOCGSTAT:		{			struct planb_stat_regs pstat;			DBG("PlanB: IOCTL PLANBIOCGSTAT\n");			pstat.ch1_stat = readl(&pb->planb_base->ch1.status);			pstat.ch2_stat = readl(&pb->planb_base->ch2.status);			pstat.ch1_cmdbase = (unsigned long)pb->vid_cbo.start;			pstat.ch2_cmdbase = (unsigned long)pb->clip_cbo.start;			pstat.ch1_cmdptr = readl(&pb->planb_base->ch1.cmdptr);			pstat.ch2_cmdptr = readl(&pb->planb_base->ch2.cmdptr);			pstat.saa_stat0 = saa_status(0, pb);			pstat.saa_stat1 = saa_status(1, pb);			if(copy_to_user((void *)arg, (void *)&pstat,							sizeof(pstat)))				return -EFAULT;			return 0;		}		case PLANBIOCSMODE: {			int v;			DBG("PlanB: IOCTL PLANBIOCSMODE\n");			if(copy_from_user(&v, arg, sizeof(v)))				return -EFAULT;			switch(v)			{			case PLANB_TV_MODE:				saa_set (SAA7196_STDC,					(saa_regs[pb->win.norm][SAA7196_STDC] &					  0x7f), pb);				break;			case PLANB_VTR_MODE:				saa_set (SAA7196_STDC,					(saa_regs[pb->win.norm][SAA7196_STDC] |					  0x80), pb);				break;			default:				return -EINVAL;				break;			}			pb->win.mode = v;			return 0;		}		case PLANBIOCGMODE: {			int v=pb->win.mode;			DBG("PlanB: IOCTL PLANBIOCGMODE\n");			if(copy_to_user(arg,&v,sizeof(v)))				return -EFAULT;			return 0;		}#ifdef PLANB_GSCANLINE		case PLANBG_GRAB_BPL: {			int v=pb->gbytes_per_line;			DBG("PlanB: IOCTL PLANBG_GRAB_BPL\n");			if(copy_to_user(arg,&v,sizeof(v)))				return -EFAULT;			return 0;		}#endif /* PLANB_GSCANLINE *//* These serve only for debugging... */#ifdef DEBUG		case PLANB_INTR_DEBUG: {			int i;			DBG("PlanB: IOCTL PLANB_INTR_DEBUG\n");			if(copy_from_user(&i, arg, sizeof(i)))				return -EFAULT;			/* avoid hang ups all together */			for (i = 0; i < MAX_GBUFFERS; i++) {				if(*pb->gbuf[i].status == GBUFFER_GRABBING) {					*pb->gbuf[i].status = GBUFFER_DONE;				}			}			if(pb->grabbing)				pb->grabbing--;			wake_up_interruptible(&pb->capq);			return 0;		}		case PLANB_INV_REGS: {			int i;			struct planb_any_regs any;			DBG("PlanB: IOCTL PLANB_INV_REGS\n");			if(copy_from_user(&any, arg, sizeof(any)))				return -EFAULT;			if(any.offset < 0 || any.offset + any.bytes > 0x400)				return -EINVAL;			if(any.bytes > 128)				return -EINVAL;			for (i = 0; i < any.bytes; i++) {				any.data[i] =					readb((unsigned char *)pb->planb_base							+ any.offset + i);			}			if(copy_to_user(arg,&any,sizeof(any)))				return -EFAULT;			return 0;		}		case PLANBIOCGDBDMABUF:		{			struct planb_buf_regs buf;			dbdma_cmd_ptr dc;			int i;			DBG("PlanB: IOCTL PLANBIOCGDBDMABUF\n");			if(copy_from_user(&buf, arg, sizeof(buf)))				return -EFAULT;			buf.end &= ~0xf;			if( (buf.start < 0) || (buf.end < 0x10) ||			    (buf.end < buf.start+0x10) ||			    (buf.end > 2*pb->tab_size) )				return -EINVAL;			printk ("PlanB DBDMA command buffer:\n");			for (i=(buf.start>>4); i<=(buf.end>>4); i++) {				printk(" 0x%04x:", i<<4);				dc = pb->vid_cbo.start + i;				printk (" %04x %04x %08x %08x %04x %04x\n",				  dc->req_count, dc->command, dc->phy_addr,				  dc->cmd_dep, dc->res_count, dc->xfer_status);			}			return 0;		}#endif /* DEBUG */		default:		{			DBG("PlanB: Unimplemented IOCTL: %d (0x%x)\n", cmd, cmd);			return -ENOIOCTLCMD;		}	/* Some IOCTLs are currently unsupported on PlanB */		case VIDIOCGTUNER: {		DBG("PlanB: IOCTL VIDIOCGTUNER\n");			goto unimplemented; }		case VIDIOCSTUNER: {		DBG("PlanB: IOCTL VIDIOCSTUNER\n");			goto unimplemented; }		case VIDIOCSFREQ: {		DBG("PlanB: IOCTL VIDIOCSFREQ\n");			goto unimplemented; }		case VIDIOCGFREQ: {		DBG("PlanB: IOCTL VIDIOCGFREQ\n");			goto unimplemented; }		case VIDIOCKEY: {		DBG("PlanB: IOCTL VIDIOCKEY\n");			goto unimplemented; }		case VIDIOCSAUDIO: {		DBG("PlanB: IOCTL VIDIOCSAUDIO\n");			goto unimplemented; }		case VIDIOCGAUDIO: {		DBG("PlanB: IOCTL VIDIOCGAUDIO\n");			goto unimplemented; }unimplemented:		DBG("       Unimplemented\n");			return -ENOIOCTLCMD;	}	return 0;}static int planb_mmap(struct video_device *dev, const char *adr, unsigned long size){	struct planb	*pb = (struct planb *)dev->priv;        unsigned long	start = (unsigned long)adr;	int		i;	if (size > MAX_GBUFFERS * PLANB_MAX_FBUF)	        return -EINVAL;	if (!pb->rawbuf) {		int err;		if((err=grabbuf_alloc(pb)))			return err;	}	for (i = 0; i < pb->rawbuf_nchunks; i++) {		if (remap_page_range(start, virt_to_phys((void *)pb->rawbuf[i]),						PAGE_SIZE, PAGE_SHARED))			return -EAGAIN;		start += PAGE_SIZE;		if (size <= PAGE_SIZE)			break;		size -= PAGE_SIZE;	}	return 0;}/********************************** * VBI device operation functions * **********************************/static long planb_vbi_read(struct video_device *dev, char *buf,	unsigned long count, int nonblock){	struct planb	*pb = (struct planb *)dev->priv;	int		q,todo;	DECLARE_WAITQUEUE(wait, current);/* Dummy for now */	printk ("PlanB: VBI read %li bytes.\n", count);	return (0);	todo=count;	while (todo && todo>(q=VBIBUF_SIZE-pb->vbip)) 	{		if(copy_to_user((void *) buf, (void *) pb->vbibuf+pb->vbip, q))			return -EFAULT;		todo-=q;		buf+=q;		add_wait_queue(&pb->vbiq, &wait);		current->state = TASK_INTERRUPTIBLE;		if (todo && q==VBIBUF_SIZE-pb->vbip) {			if(nonblock) {				remove_wait_queue(&pb->vbiq, &wait);				current->state = TASK_RUNNING;				if(count==todo)					return -EWOULDBLOCK;				return count-todo;			}			schedule();			if(signal_pending(current)) {				remove_wait_queue(&pb->vbiq, &wait);				current->state = TASK_RUNNING;				if(todo==count)					return -EINTR;				else					return count-todo;			}		}		remove_wait_queue(&pb->vbiq, &wait);		current->state = TASK_RUNNING;	}	if (todo) {		if(copy_to_user((void *) buf, (void *) pb->vbibuf+pb->vbip,		    todo))			return -EFAULT;		pb->vbip+=todo;	}	return count;}static unsigned int planb_vbi_poll(struct video_device *dev,	struct file *file, poll_table *wait){	struct planb	*pb = (struct planb *)dev->priv;	unsigned int	mask = 0;	printk ("PlanB: VBI poll.\n");	poll_wait(file, &pb->vbiq, wait);	if (pb->vbip < VBIBUF_SIZE)		mask |= (POLLIN | POLLRDNORM);	return mask;}static int planb_vbi_open(struct video_device *dev, int flags){	struct planb	*pb = (struct planb *)dev->priv;	int		err;	/* first open on the driver? */	if(pb->vid_user + pb->vbi_user == 0) {		if((err = planb_prepare_open(pb)) != 0)			return err;	}	/* first open on the vbi device? */	if(pb->vbi_user == 1) {		if((err = planb_prepare_vbi(pb)) != 0)			return err;	}	++pb->vbi_user;	DBG("PlanB: VBI open\n");	MOD_INC_USE_COUNT;	return 0;   }static void planb_vbi_close(struct video_device *dev){	struct planb	*pb = (struct planb *)dev->priv;	/* last close on vbi device? */	if(--pb->vbi_user == 0) {		planb_close_vbi(pb);	}	/* last close on any planb device? */	if(pb->vid_user + pb->vbi_user == 0) {		planb_prepare_close(pb);	}	DBG("PlanB: VBI close\n");	MOD_DEC_USE_COUNT;  	return;}static int planb_vbi_ioctl(struct video_device *dev, unsigned int cmd,	void *arg){	switch (cmd) {  		/* This is only for alevt */		case BTTV_VBISIZE:			DBG("PlanB: IOCTL BTTV_VBISIZE.\n");			return VBIBUF_SIZE;		default:			DBG("PlanB: Unimplemented 

⌨️ 快捷键说明

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