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

📄 bttv-driver.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	case VIDIOCGCAP:	{		struct video_capability b;		strcpy(b.name,btv->video_dev.name);		b.type = VID_TYPE_CAPTURE|			((bttv_tvcards[btv->type].tuner != -1) ? VID_TYPE_TUNER : 0) |			VID_TYPE_OVERLAY|			VID_TYPE_CLIPPING|			VID_TYPE_FRAMERAM|			VID_TYPE_SCALES;		b.channels = bttv_tvcards[btv->type].video_inputs;		b.audios = bttv_tvcards[btv->type].audio_inputs;		b.maxwidth = tvnorms[btv->win.norm].swidth;		b.maxheight = tvnorms[btv->win.norm].sheight;		b.minwidth = 48;		b.minheight = 32;		if(copy_to_user(arg,&b,sizeof(b)))			return -EFAULT;		return 0;	}	case VIDIOCGCHAN:	{		struct video_channel v;		if(copy_from_user(&v, arg,sizeof(v)))			return -EFAULT;		v.flags=VIDEO_VC_AUDIO;		v.tuners=0;		v.type=VIDEO_TYPE_CAMERA;		v.norm = btv->win.norm;		if (v.channel>=bttv_tvcards[btv->type].video_inputs)			return -EINVAL;		if(v.channel==bttv_tvcards[btv->type].tuner) 		{			strcpy(v.name,"Television");			v.flags|=VIDEO_VC_TUNER;			v.type=VIDEO_TYPE_TV;			v.tuners=1;		} 		else if(v.channel==bttv_tvcards[btv->type].svhs) 			strcpy(v.name,"S-Video");		else			sprintf(v.name,"Composite%d",v.channel);				if(copy_to_user(arg,&v,sizeof(v)))			return -EFAULT;		return 0;	}	/*	 *	Each channel has 1 tuner	 */	case VIDIOCSCHAN:	{		struct video_channel v;		if(copy_from_user(&v, arg,sizeof(v)))			return -EFAULT;				if (v.channel>bttv_tvcards[btv->type].video_inputs)			return -EINVAL;		if (v.norm > (sizeof(tvnorms)/sizeof(*tvnorms)))			return -EOPNOTSUPP;		bttv_call_i2c_clients(btv,cmd,&v);		down(&btv->lock);		bt848_muxsel(btv, v.channel);		btv->channel=v.channel;		if (btv->win.norm != v.norm) {			btv->win.norm = v.norm;			make_vbitab(btv);			spin_lock_irqsave(&btv->s_lock, irq_flags);			bt848_set_winsize(btv);			spin_unlock_irqrestore(&btv->s_lock, irq_flags);		}		up(&btv->lock);		return 0;	}	case VIDIOCGTUNER:	{		struct video_tuner v;		if(copy_from_user(&v,arg,sizeof(v))!=0)			return -EFAULT;#if 0 /* tuner.signal might be of intrest for non-tuner sources too ... */		if(v.tuner||btv->channel)	/* Only tuner 0 */			return -EINVAL;#endif		strcpy(v.name, "Television");		v.rangelow=0;		v.rangehigh=0xFFFFFFFF;		v.flags=VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;		v.mode = btv->win.norm;		v.signal = (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) ? 0xFFFF : 0;		bttv_call_i2c_clients(btv,cmd,&v);		if(copy_to_user(arg,&v,sizeof(v)))			return -EFAULT;		return 0;	}	/* We have but one tuner */	case VIDIOCSTUNER:	{		struct video_tuner v;		if(copy_from_user(&v, arg, sizeof(v)))			return -EFAULT;		/* Only one channel has a tuner */		if(v.tuner!=bttv_tvcards[btv->type].tuner)			return -EINVAL; 						if(v.mode!=VIDEO_MODE_PAL&&v.mode!=VIDEO_MODE_NTSC		   &&v.mode!=VIDEO_MODE_SECAM)			return -EOPNOTSUPP;		bttv_call_i2c_clients(btv,cmd,&v);		if (btv->win.norm != v.mode) {			btv->win.norm = v.mode;                        down(&btv->lock);			set_pll(btv);			make_vbitab(btv);			spin_lock_irqsave(&btv->s_lock, irq_flags);			bt848_set_winsize(btv);			spin_unlock_irqrestore(&btv->s_lock, irq_flags);			up(&btv->lock);		}		return 0;	}	case VIDIOCGPICT:	{		struct video_picture p=btv->picture;		if(copy_to_user(arg, &p, sizeof(p)))			return -EFAULT;		return 0;	}	case VIDIOCSPICT:	{		struct video_picture p;		if(copy_from_user(&p, arg,sizeof(p)))			return -EFAULT;		if (p.palette > PALETTEFMT_MAX)			return -EINVAL;		down(&btv->lock);		/* We want -128 to 127 we get 0-65535 */		bt848_bright(btv, (p.brightness>>8)-128);		/* 0-511 for the colour */		bt848_sat_u(btv, p.colour>>7);		bt848_sat_v(btv, ((p.colour>>7)*201L)/237);		/* -128 to 127 */		bt848_hue(btv, (p.hue>>8)-128);		/* 0-511 */		bt848_contrast(btv, p.contrast>>7);		btv->picture = p;		up(&btv->lock);		return 0;	}	case VIDIOCSWIN:	{		struct video_window vw;		struct video_clip *vcp = NULL;					if(copy_from_user(&vw,arg,sizeof(vw)))			return -EFAULT;		down(&btv->lock);		if(vw.flags || vw.width < 16 || vw.height < 16) 		{			spin_lock_irqsave(&btv->s_lock, irq_flags);			btv->scr_on = 0;			bt848_set_risc_jmps(btv,-1);			spin_unlock_irqrestore(&btv->s_lock, irq_flags);			up(&btv->lock);			return -EINVAL;		}		if (btv->win.bpp < 4) 		{	/* adjust and align writes */			vw.x = (vw.x + 3) & ~3;			vw.width &= ~3;		}		if (btv->needs_restart)			bt848_restart(btv);		btv->win.x=vw.x;		btv->win.y=vw.y;		btv->win.width=vw.width;		btv->win.height=vw.height;				spin_lock_irqsave(&btv->s_lock, irq_flags);		bt848_set_risc_jmps(btv,0);		bt848_set_winsize(btv);		spin_unlock_irqrestore(&btv->s_lock, irq_flags);		/*		 *	Do any clips.		 */		if(vw.clipcount<0) {			if((vcp=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL) {				up(&btv->lock);				return -ENOMEM;			}			if(copy_from_user(vcp, vw.clips,					  VIDEO_CLIPMAP_SIZE)) {				up(&btv->lock);				vfree(vcp);				return -EFAULT;			}		} else if (vw.clipcount > 2048) {			up(&btv->lock);			return -EINVAL;		} else if (vw.clipcount) {			if((vcp=vmalloc(sizeof(struct video_clip)*					(vw.clipcount))) == NULL) {				up(&btv->lock);				return -ENOMEM;			}			if(copy_from_user(vcp,vw.clips,					  sizeof(struct video_clip)*					  vw.clipcount)) {				up(&btv->lock);				vfree(vcp);				return -EFAULT;			}		}		make_clip_tab(btv, vcp, vw.clipcount);		if (vw.clipcount != 0)			vfree(vcp);		spin_lock_irqsave(&btv->s_lock, irq_flags);		bt848_set_risc_jmps(btv,-1);		spin_unlock_irqrestore(&btv->s_lock, irq_flags);		up(&btv->lock);		return 0;	}	case VIDIOCGWIN:	{		struct video_window vw;		memset(&vw,0,sizeof(vw));		vw.x=btv->win.x;		vw.y=btv->win.y;		vw.width=btv->win.width;		vw.height=btv->win.height;		if(btv->win.interlace)			vw.flags|=VIDEO_WINDOW_INTERLACE;		if(copy_to_user(arg,&vw,sizeof(vw)))			return -EFAULT;		return 0;	}	case VIDIOCCAPTURE:	{		int v;		if(copy_from_user(&v, arg,sizeof(v)))			return -EFAULT;		if(btv->win.vidadr == 0)			return -EINVAL;		if (btv->win.width==0 || btv->win.height==0)			return -EINVAL;		if (1 == no_overlay)			return -EIO;		spin_lock_irqsave(&btv->s_lock, irq_flags);		if (v == 1 && btv->win.vidadr != 0)			btv->scr_on = 1;		if (v == 0)			btv->scr_on = 0;		bt848_set_risc_jmps(btv,-1);		spin_unlock_irqrestore(&btv->s_lock, irq_flags);		return 0;	}	case VIDIOCGFBUF:	{		struct video_buffer v;		v.base=(void *)btv->win.vidadr;		v.height=btv->win.sheight;		v.width=btv->win.swidth;		v.depth=btv->win.depth;		v.bytesperline=btv->win.bpl;		if(copy_to_user(arg, &v,sizeof(v)))			return -EFAULT;		return 0;				}	case VIDIOCSFBUF:	{		struct video_buffer v;		if(!capable(CAP_SYS_ADMIN) &&		   !capable(CAP_SYS_RAWIO))			return -EPERM;		if(copy_from_user(&v, arg,sizeof(v)))			return -EFAULT;		if(v.depth!=8 && v.depth!=15 && v.depth!=16 && 		   v.depth!=24 && v.depth!=32 && v.width > 16 &&		   v.height > 16 && v.bytesperline > 16)			return -EINVAL;		down(&btv->lock);		if (v.base)			btv->win.vidadr=(unsigned long)v.base;		btv->win.sheight=v.height;		btv->win.swidth=v.width;		btv->win.bpp=((v.depth+7)&0x38)/8;		btv->win.depth=v.depth;		btv->win.bpl=v.bytesperline;#if 0 /* was broken for ages and nobody noticed.  Looks like we don't need	 it any more as everybody explicitly sets the palette using VIDIOCSPICT	 these days */		/* set sefault color format */		switch (v.depth) {		case  8: btv->picture.palette = VIDEO_PALETTE_HI240;  break;		case 15: btv->picture.palette = VIDEO_PALETTE_RGB555; break;		case 16: btv->picture.palette = VIDEO_PALETTE_RGB565; break;		case 24: btv->picture.palette = VIDEO_PALETTE_RGB24;  break;		case 32: btv->picture.palette = VIDEO_PALETTE_RGB32;  break;		}#endif			if (bttv_debug)			printk("Display at %p is %d by %d, bytedepth %d, bpl %d\n",			       v.base, v.width,v.height, btv->win.bpp, btv->win.bpl);		spin_lock_irqsave(&btv->s_lock, irq_flags);		bt848_set_winsize(btv);		spin_unlock_irqrestore(&btv->s_lock, irq_flags);		up(&btv->lock);		return 0;			}	case VIDIOCKEY:	{		/* Will be handled higher up .. */		return 0;	}	case VIDIOCGFREQ:	{		unsigned long v=btv->win.freq;		if(copy_to_user(arg,&v,sizeof(v)))			return -EFAULT;		return 0;	}	case VIDIOCSFREQ:	{		unsigned long v;		if(copy_from_user(&v, arg, sizeof(v)))			return -EFAULT;		btv->win.freq=v;		bttv_call_i2c_clients(btv,cmd,&v);#if 1		if (btv->radio && btv->has_matchbox)			tea5757_set_freq(btv,v);#endif		return 0;	}		case VIDIOCGAUDIO:	{		struct video_audio v;		v=btv->audio_dev;		v.flags&=~(VIDEO_AUDIO_MUTE|VIDEO_AUDIO_MUTABLE);		v.flags|=VIDEO_AUDIO_MUTABLE;		strcpy(v.name,"TV");		v.mode = VIDEO_SOUND_MONO;		bttv_call_i2c_clients(btv,cmd,&v);		/* card specific hooks */		if (bttv_tvcards[btv->type].audio_hook)			bttv_tvcards[btv->type].audio_hook(btv,&v,0);		if(copy_to_user(arg,&v,sizeof(v)))			return -EFAULT;		return 0;	}	case VIDIOCSAUDIO:	{		struct video_audio v;		if(copy_from_user(&v,arg, sizeof(v)))			return -EFAULT;		down(&btv->lock);		if(v.flags&VIDEO_AUDIO_MUTE)			audio(btv, AUDIO_MUTE, 1);		/* One audio source per tuner -- huh? <GA> */		if(v.audio<0 || v.audio >= bttv_tvcards[btv->type].audio_inputs) {			up(&btv->lock);			return -EINVAL;		}		/* bt848_muxsel(btv,v.audio); */		if(!(v.flags&VIDEO_AUDIO_MUTE))			audio(btv, AUDIO_UNMUTE, 1);		bttv_call_i2c_clients(btv,cmd,&v);				/* card specific hooks */		if (bttv_tvcards[btv->type].audio_hook)			bttv_tvcards[btv->type].audio_hook(btv,&v,1);		btv->audio_dev=v;		up(&btv->lock);		return 0;	}	case VIDIOCSYNC:	{		DECLARE_WAITQUEUE(wait, current);		if(copy_from_user((void *)&i,arg,sizeof(int)))			return -EFAULT;		if (i < 0 || i >= gbuffers)			return -EINVAL;		switch (btv->gbuf[i].stat) {		case GBUFFER_UNUSED:			ret = -EINVAL;			break;		case GBUFFER_GRABBING:			add_wait_queue(&btv->capq, &wait);			current->state = TASK_INTERRUPTIBLE;			while(btv->gbuf[i].stat==GBUFFER_GRABBING) {				if (bttv_debug)					printk("bttv%d: cap sync: sleep on %d\n",btv->nr,i);				schedule();				if(signal_pending(current)) {					remove_wait_queue(&btv->capq, &wait);					current->state = TASK_RUNNING;					return -EINTR;				}			}			remove_wait_queue(&btv->capq, &wait);			current->state = TASK_RUNNING;			/* fall throuth */		case GBUFFER_DONE:		case GBUFFER_ERROR:			ret = (btv->gbuf[i].stat == GBUFFER_ERROR) ? -EIO : 0;			if (bttv_debug)				printk("bttv%d: cap sync: buffer %d, retval %d\n",btv->nr,i,ret);			btv->gbuf[i].stat = GBUFFER_UNUSED;		}		if (btv->needs_restart) {			down(&btv->lock);			bt848_restart(btv);			up(&btv->lock);		}		return ret;	}	case BTTV_FIELDNR: 		if(copy_to_user((void *) arg, (void *) &btv->last_field, 				sizeof(btv->last_field)))			return -EFAULT;		break;      	case BTTV_PLLSET: {		struct bttv_pll_info p;		if(!capable(CAP_SYS_ADMIN))			return -EPERM;		if(copy_from_user(&p , (void *) arg, sizeof(btv->pll)))			return -EFAULT;		down(&btv->lock);		btv->pll.pll_ifreq = p.pll_ifreq;		btv->pll.pll_ofreq = p.pll_ofreq;		btv->pll.pll_crystal = p.pll_crystal;		up(&btv->lock);		break;	}	case VIDIOCMCAPTURE:	{		struct video_mmap vm;		int ret;		if(copy_from_user((void *) &vm, (void *) arg, sizeof(vm)))			return -EFAULT;		down(&btv->lock);		ret = vgrab(btv, &vm);		up(&btv->lock);		return ret;	}			case VIDIOCGMBUF:	{		struct video_mbuf vm;		memset(&vm, 0 , sizeof(vm));		vm.size=gbufsize*gbuffers;		vm.frames=gbuffers;		for (i = 0; i < gbuffers; i++)			vm.offsets[i]=i*gbufsize;		if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))			return -EFAULT;		return 0;	}			case VIDIOCGUNIT:	{		struct video_unit vu;		vu.video=btv->video_dev.minor;		vu.vbi=btv->vbi_dev.minor;		if(btv->radio_dev.minor!=-1)			vu.radio=btv->radio_dev.minor;		else			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 BTTV_BURST_ON:	{		burst(1);		return 0;	}	case BTTV_BURST_OFF:	{		burst(0);		return 0;

⌨️ 快捷键说明

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