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

📄 planb.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	DEBUG("PlanB: device opened\n");	return 0;   }static void planb_close(struct video_device *dev){	struct planb *pb = (struct planb *)dev;	if(pb->user < 1) /* ??? */		return;	planb_lock(pb);	if (pb->user == 1) {		if (pb->overlay) {			planb_dbdma_stop(&pb->planb_base->ch2);			planb_dbdma_stop(&pb->planb_base->ch1);			pb->overlay = 0;		}		planb_prepare_close(pb);	}	pb->user--;	planb_unlock(pb);	DEBUG("PlanB: device closed\n");}static long planb_read(struct video_device *v, char *buf, unsigned long count,				int nonblock){	DEBUG("planb: read request\n");	return -EINVAL;}static long planb_write(struct video_device *v, const char *buf,				unsigned long count, int nonblock){	DEBUG("planb: write request\n");	return -EINVAL;}static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg){	struct planb *pb=(struct planb *)dev;  		switch (cmd)	{			case VIDIOCGCAP:		{			struct video_capability b;			DEBUG("PlanB: IOCTL VIDIOCGCAP\n");			strcpy (b.name, pb->video_dev.name);			b.type = VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |				 VID_TYPE_FRAMERAM | VID_TYPE_SCALES |				 VID_TYPE_CAPTURE;			b.channels = 2;	/* composite & svhs */			b.audios = 0;			b.maxwidth = PLANB_MAXPIXELS;                        b.maxheight = PLANB_MAXLINES;                        b.minwidth = 32; /* wild guess */                        b.minheight = 32;                        if (copy_to_user(arg,&b,sizeof(b)))                                return -EFAULT;			return 0;		}		case VIDIOCSFBUF:		{                        struct video_buffer v;			unsigned short bpp;			unsigned int fmt;			DEBUG("PlanB: IOCTL VIDIOCSFBUF\n");                        if (!capable(CAP_SYS_ADMIN)			|| !capable(CAP_SYS_RAWIO))                                return -EPERM;                        if (copy_from_user(&v, arg,sizeof(v)))                                return -EFAULT;			planb_lock(pb);			switch(v.depth) {			case 8:				bpp = 1;				fmt = PLANB_GRAY;				break;			case 15:			case 16:				bpp = 2;				fmt = PLANB_COLOUR15;				break;			case 24:			case 32:				bpp = 4;				fmt = PLANB_COLOUR32;				break;			default:				planb_unlock(pb);                                return -EINVAL;			}			if (bpp * v.width > v.bytesperline) {				planb_unlock(pb);				return -EINVAL;			}			pb->win.bpp = bpp;			pb->win.color_fmt = fmt;			pb->frame_buffer_phys = (unsigned long) v.base;			pb->win.sheight = v.height;			pb->win.swidth = v.width;			pb->picture.depth = pb->win.depth = v.depth;			pb->win.bpl = pb->win.bpp * pb->win.swidth;			pb->win.pad = v.bytesperline - pb->win.bpl;                        DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d,"				" bpl %d (+ %d)\n", v.base, v.width,v.height,				pb->win.bpp, pb->win.bpl, pb->win.pad);			pb->cmd_buff_inited = 0;			if(pb->overlay) {				suspend_overlay(pb);				fill_cmd_buff(pb);				resume_overlay(pb);			}			planb_unlock(pb);			return 0;				}		case VIDIOCGFBUF:		{                        struct video_buffer v;			DEBUG("PlanB: IOCTL VIDIOCGFBUF\n");			v.base = (void *)pb->frame_buffer_phys;			v.height = pb->win.sheight;			v.width = pb->win.swidth;			v.depth = pb->win.depth;			v.bytesperline = pb->win.bpl + pb->win.pad;			if (copy_to_user(arg, &v, sizeof(v)))                                return -EFAULT;			return 0;		}		case VIDIOCCAPTURE:		{			int i;                        if(copy_from_user(&i, arg, sizeof(i)))                                return -EFAULT;			if(i==0) {				DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n");				if (!(pb->overlay))					return 0;				planb_lock(pb);				pb->overlay = 0;				overlay_stop(pb);				planb_unlock(pb);			} else {				DEBUG("PlanB: IOCTL VIDIOCCAPTURE Start\n");				if (pb->frame_buffer_phys == 0 ||					  pb->win.width == 0 ||					  pb->win.height == 0)					return -EINVAL;				if (pb->overlay)					return 0;				planb_lock(pb);				pb->overlay = 1;				if(!(pb->cmd_buff_inited))					fill_cmd_buff(pb);				overlay_start(pb);				planb_unlock(pb);			}			return 0;		}		case VIDIOCGCHAN:		{			struct video_channel v;			DEBUG("PlanB: IOCTL VIDIOCGCHAN\n");			if(copy_from_user(&v, arg,sizeof(v)))				return -EFAULT;			v.flags = 0;			v.tuners = 0;			v.type = VIDEO_TYPE_CAMERA;			v.norm = pb->win.norm;			switch(v.channel)			{			case 0:				strcpy(v.name,"Composite");				break;			case 1:				strcpy(v.name,"SVHS");				break;			default:				return -EINVAL;				break;			}			if(copy_to_user(arg,&v,sizeof(v)))				return -EFAULT;			return 0;		}		case VIDIOCSCHAN:		{			struct video_channel v;			DEBUG("PlanB: IOCTL VIDIOCSCHAN\n");			if(copy_from_user(&v, arg, sizeof(v)))				return -EFAULT;			if (v.norm != pb->win.norm) {				int i, maxlines;				switch (v.norm)				{				case VIDEO_MODE_PAL:				case VIDEO_MODE_SECAM:					maxlines = PLANB_MAXLINES;					break;				case VIDEO_MODE_NTSC:					maxlines = PLANB_NTSC_MAXLINES;					break;				default:					return -EINVAL;					break;				}				planb_lock(pb);				/* empty the grabbing queue */				wait_event(pb->capq, !pb->grabbing);				pb->maxlines = maxlines;				pb->win.norm = v.norm;				/* Stop overlay if running */				suspend_overlay(pb);				for(i = 0; i < MAX_GBUFFERS; i++)					pb->gnorm_switch[i] = 1;				/* I know it's an overkill, but.... */				fill_cmd_buff(pb);				/* ok, now init it accordingly */				saa_init_regs (pb);				/* restart overlay if it was running */				resume_overlay(pb);				planb_unlock(pb);			}			switch(v.channel)			{			case 0:	/* Composite	*/				saa_set (SAA7196_IOCC,					((saa_regs[pb->win.norm][SAA7196_IOCC] &					  ~7) | 3), pb);				break;			case 1:	/* SVHS		*/				saa_set (SAA7196_IOCC,					((saa_regs[pb->win.norm][SAA7196_IOCC] &					  ~7) | 4), pb);				break;			default:				return -EINVAL;				break;			}			return 0;		}		case VIDIOCGPICT:		{			struct video_picture vp = pb->picture;			DEBUG("PlanB: IOCTL VIDIOCGPICT\n");			switch(pb->win.color_fmt) {			case PLANB_GRAY:				vp.palette = VIDEO_PALETTE_GREY;			case PLANB_COLOUR15:				vp.palette = VIDEO_PALETTE_RGB555;				break;			case PLANB_COLOUR32:				vp.palette = VIDEO_PALETTE_RGB32;				break;			default:				vp.palette = 0;				break;			}			if(copy_to_user(arg,&vp,sizeof(vp)))				return -EFAULT;			return 0;		}		case VIDIOCSPICT:		{			struct video_picture vp;			DEBUG("PlanB: IOCTL VIDIOCSPICT\n");			if(copy_from_user(&vp,arg,sizeof(vp)))				return -EFAULT;			pb->picture = vp;			/* Should we do sanity checks here? */			saa_set (SAA7196_BRIG, (unsigned char)			    ((pb->picture.brightness) >> 8), pb);			saa_set (SAA7196_HUEC, (unsigned char)			    ((pb->picture.hue) >> 8) ^ 0x80, pb);			saa_set (SAA7196_CSAT, (unsigned char)			    ((pb->picture.colour) >> 9), pb);			saa_set (SAA7196_CONT, (unsigned char)			    ((pb->picture.contrast) >> 9), pb);			return 0;		}		case VIDIOCSWIN:		{			struct video_window	vw;			struct video_clip	clip;			int 			i;						DEBUG("PlanB: IOCTL VIDIOCSWIN\n");			if(copy_from_user(&vw,arg,sizeof(vw)))				return -EFAULT;			planb_lock(pb);			/* Stop overlay if running */			suspend_overlay(pb);			pb->win.interlace = (vw.height > pb->maxlines/2)? 1: 0;			if (pb->win.x != vw.x ||			    pb->win.y != vw.y ||			    pb->win.width != vw.width ||			    pb->win.height != vw.height ||			    !pb->cmd_buff_inited) {				pb->win.x = vw.x;				pb->win.y = vw.y;				pb->win.width = vw.width;				pb->win.height = vw.height;				fill_cmd_buff(pb);			}			/* 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;			DEBUG("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;			IDEBUG("PlanB: IOCTL VIDIOCSYNC\n");			if(copy_from_user((void *)&i,arg,sizeof(int)))				return -EFAULT;			IDEBUG("PlanB: sync to frame %d\n", i);                        if(i > (MAX_GBUFFERS - 1) || i < 0)                                return -EINVAL;chk_grab:                        switch (pb->frame_stat[i]) {                        case GBUFFER_UNUSED:                                return -EINVAL;			case GBUFFER_GRABBING:				IDEBUG("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:                                pb->frame_stat[i] = GBUFFER_UNUSED;                                break;                        }                        return 0;		}	        case VIDIOCMCAPTURE:		{                        struct video_mmap vm;			volatile unsigned int status;			IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n");			if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))				return -EFAULT;                        status = pb->frame_stat[vm.frame];                        if (status != GBUFFER_UNUSED)                                return -EBUSY;		        return vgrab(pb, &vm);		}				case VIDIOCGMBUF:		{			int i;			struct video_mbuf vm;			DEBUG("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 PLANBIOCGSAAREGS:		{			struct planb_saa_regs preg;			DEBUG("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;			DEBUG("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;		}

⌨️ 快捷键说明

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