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

📄 bttv-driver.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	} else {		/* full video */		btwrite((btv->triton1)  |			(btv->gpioirq ? BT848_INT_GPINT : 0) |			BT848_INT_SCERR |			(fdsr ? BT848_INT_FDSR : 0) |			BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|			BT848_INT_FMTCHG|BT848_INT_HLOCK|			BT848_INT_I2CDONE,			BT848_INT_MASK);	}}static void init_bt848(struct bttv *btv){	int val;	if (bttv_tvcards[btv->c.type].no_video) {		/* very basic init only */		init_irqreg(btv);		return;	}	btwrite(0x00, BT848_CAP_CTL);	btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);	btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);	/* set planar and packed mode trigger points and         */	/* set rising edge of inverted GPINTR pin as irq trigger */	btwrite(BT848_GPIO_DMA_CTL_PKTP_32|		BT848_GPIO_DMA_CTL_PLTP1_16|		BT848_GPIO_DMA_CTL_PLTP23_16|		BT848_GPIO_DMA_CTL_GPINTC|		BT848_GPIO_DMA_CTL_GPINTI,		BT848_GPIO_DMA_CTL);	val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;	btwrite(val, BT848_E_SCLOOP);	btwrite(val, BT848_O_SCLOOP);	btwrite(0x20, BT848_E_VSCALE_HI);	btwrite(0x20, BT848_O_VSCALE_HI);	btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),		BT848_ADC);	btwrite(whitecrush_upper, BT848_WC_UP);	btwrite(whitecrush_lower, BT848_WC_DOWN);	if (btv->opt_lumafilter) {		btwrite(0, BT848_E_CONTROL);		btwrite(0, BT848_O_CONTROL);	} else {		btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL);		btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL);	}	bt848_bright(btv,   btv->bright);	bt848_hue(btv,      btv->hue);	bt848_contrast(btv, btv->contrast);	bt848_sat(btv,      btv->saturation);	/* interrupt */	init_irqreg(btv);}static void bttv_reinit_bt848(struct bttv *btv){	unsigned long flags;	if (bttv_verbose)		printk(KERN_INFO "bttv%d: reset, reinitialize\n",btv->c.nr);	spin_lock_irqsave(&btv->s_lock,flags);	btv->errors=0;	bttv_set_dma(btv,0);	spin_unlock_irqrestore(&btv->s_lock,flags);	init_bt848(btv);	btv->pll.pll_current = -1;	set_input(btv,btv->input);}static int get_control(struct bttv *btv, struct v4l2_control *c){	struct video_audio va;	int i;	for (i = 0; i < BTTV_CTLS; i++)		if (bttv_ctls[i].id == c->id)			break;	if (i == BTTV_CTLS)		return -EINVAL;	if (i >= 4 && i <= 8) {		memset(&va,0,sizeof(va));		bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);		if (btv->audio_hook)			btv->audio_hook(btv,&va,0);	}	switch (c->id) {	case V4L2_CID_BRIGHTNESS:		c->value = btv->bright;		break;	case V4L2_CID_HUE:		c->value = btv->hue;		break;	case V4L2_CID_CONTRAST:		c->value = btv->contrast;		break;	case V4L2_CID_SATURATION:		c->value = btv->saturation;		break;	case V4L2_CID_AUDIO_MUTE:		c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0;		break;	case V4L2_CID_AUDIO_VOLUME:		c->value = va.volume;		break;	case V4L2_CID_AUDIO_BALANCE:		c->value = va.balance;		break;	case V4L2_CID_AUDIO_BASS:		c->value = va.bass;		break;	case V4L2_CID_AUDIO_TREBLE:		c->value = va.treble;		break;	case V4L2_CID_PRIVATE_CHROMA_AGC:		c->value = btv->opt_chroma_agc;		break;	case V4L2_CID_PRIVATE_COMBFILTER:		c->value = btv->opt_combfilter;		break;	case V4L2_CID_PRIVATE_LUMAFILTER:		c->value = btv->opt_lumafilter;		break;	case V4L2_CID_PRIVATE_AUTOMUTE:		c->value = btv->opt_automute;		break;	case V4L2_CID_PRIVATE_AGC_CRUSH:		c->value = btv->opt_adc_crush;		break;	case V4L2_CID_PRIVATE_VCR_HACK:		c->value = btv->opt_vcr_hack;		break;	case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:		c->value = btv->opt_whitecrush_upper;		break;	case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:		c->value = btv->opt_whitecrush_lower;		break;	case V4L2_CID_PRIVATE_UV_RATIO:		c->value = btv->opt_uv_ratio;		break;	case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:		c->value = btv->opt_full_luma_range;		break;	case V4L2_CID_PRIVATE_CORING:		c->value = btv->opt_coring;		break;	default:		return -EINVAL;	}	return 0;}static int set_control(struct bttv *btv, struct v4l2_control *c){	struct video_audio va;	int i,val;	for (i = 0; i < BTTV_CTLS; i++)		if (bttv_ctls[i].id == c->id)			break;	if (i == BTTV_CTLS)		return -EINVAL;	if (i >= 4 && i <= 8) {		memset(&va,0,sizeof(va));		bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);		if (btv->audio_hook)			btv->audio_hook(btv,&va,0);	}	switch (c->id) {	case V4L2_CID_BRIGHTNESS:		bt848_bright(btv,c->value);		break;	case V4L2_CID_HUE:		bt848_hue(btv,c->value);		break;	case V4L2_CID_CONTRAST:		bt848_contrast(btv,c->value);		break;	case V4L2_CID_SATURATION:		bt848_sat(btv,c->value);		break;	case V4L2_CID_AUDIO_MUTE:		if (c->value) {			va.flags |= VIDEO_AUDIO_MUTE;			audio_mux(btv, AUDIO_MUTE);		} else {			va.flags &= ~VIDEO_AUDIO_MUTE;			audio_mux(btv, AUDIO_UNMUTE);		}		break;	case V4L2_CID_AUDIO_VOLUME:		va.volume = c->value;		break;	case V4L2_CID_AUDIO_BALANCE:		va.balance = c->value;		break;	case V4L2_CID_AUDIO_BASS:		va.bass = c->value;		break;	case V4L2_CID_AUDIO_TREBLE:		va.treble = c->value;		break;	case V4L2_CID_PRIVATE_CHROMA_AGC:		btv->opt_chroma_agc = c->value;		val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;		btwrite(val, BT848_E_SCLOOP);		btwrite(val, BT848_O_SCLOOP);		break;	case V4L2_CID_PRIVATE_COMBFILTER:		btv->opt_combfilter = c->value;		break;	case V4L2_CID_PRIVATE_LUMAFILTER:		btv->opt_lumafilter = c->value;		if (btv->opt_lumafilter) {			btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL);			btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL);		} else {			btor(BT848_CONTROL_LDEC, BT848_E_CONTROL);			btor(BT848_CONTROL_LDEC, BT848_O_CONTROL);		}		break;	case V4L2_CID_PRIVATE_AUTOMUTE:		btv->opt_automute = c->value;		break;	case V4L2_CID_PRIVATE_AGC_CRUSH:		btv->opt_adc_crush = c->value;		btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),			BT848_ADC);		break;	case V4L2_CID_PRIVATE_VCR_HACK:		btv->opt_vcr_hack = c->value;		break;	case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:		btv->opt_whitecrush_upper = c->value;		btwrite(c->value, BT848_WC_UP);		break;	case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:		btv->opt_whitecrush_lower = c->value;		btwrite(c->value, BT848_WC_DOWN);		break;	case V4L2_CID_PRIVATE_UV_RATIO:		btv->opt_uv_ratio = c->value;		bt848_sat(btv, btv->saturation);		break;	case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:		btv->opt_full_luma_range = c->value;		btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM);		break;	case V4L2_CID_PRIVATE_CORING:		btv->opt_coring = c->value;		btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM);		break;	default:		return -EINVAL;	}	if (i >= 4 && i <= 8) {		bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);		if (btv->audio_hook)			btv->audio_hook(btv,&va,1);	}	return 0;}/* ----------------------------------------------------------------------- */void bttv_gpio_tracking(struct bttv *btv, char *comment){	unsigned int outbits, data;	outbits = btread(BT848_GPIO_OUT_EN);	data    = btread(BT848_GPIO_DATA);	printk(KERN_DEBUG "bttv%d: gpio: en=%08x, out=%08x in=%08x [%s]\n",	       btv->c.nr,outbits,data & outbits, data & ~outbits, comment);}static void bttv_field_count(struct bttv *btv){	int need_count = 0;	if (btv->users)		need_count++;	if (need_count) {		/* start field counter */		btor(BT848_INT_VSYNC,BT848_INT_MASK);	} else {		/* stop field counter */		btand(~BT848_INT_VSYNC,BT848_INT_MASK);		btv->field_count = 0;	}}static const struct bttv_format*format_by_palette(int palette){	unsigned int i;	for (i = 0; i < BTTV_FORMATS; i++) {		if (-1 == bttv_formats[i].palette)			continue;		if (bttv_formats[i].palette == palette)			return bttv_formats+i;	}	return NULL;}static const struct bttv_format*format_by_fourcc(int fourcc){	unsigned int i;	for (i = 0; i < BTTV_FORMATS; i++) {		if (-1 == bttv_formats[i].fourcc)			continue;		if (bttv_formats[i].fourcc == fourcc)			return bttv_formats+i;	}	return NULL;}/* ----------------------------------------------------------------------- *//* misc helpers                                                            */static intbttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,		    struct bttv_buffer *new){	struct bttv_buffer *old;	unsigned long flags;	int retval = 0;	dprintk("switch_overlay: enter [new=%p]\n",new);	if (new)		new->vb.state = STATE_DONE;	spin_lock_irqsave(&btv->s_lock,flags);	old = btv->screen;	btv->screen = new;	btv->loop_irq |= 1;	bttv_set_dma(btv, 0x03);	spin_unlock_irqrestore(&btv->s_lock,flags);	if (NULL == new)		free_btres(btv,fh,RESOURCE_OVERLAY);	if (NULL != old) {		dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state);		bttv_dma_free(btv, old);		kfree(old);	}	dprintk("switch_overlay: done\n");	return retval;}/* ----------------------------------------------------------------------- *//* video4linux (1) interface                                               */static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,			       const struct bttv_format *fmt,			       unsigned int width, unsigned int height,			       enum v4l2_field field){	int redo_dma_risc = 0;	int rc;	/* check settings */	if (NULL == fmt)		return -EINVAL;	if (fmt->btformat == BT848_COLOR_FMT_RAW) {		width  = RAW_BPL;		height = RAW_LINES*2;		if (width*height > buf->vb.bsize)			return -EINVAL;		buf->vb.size = buf->vb.bsize;	} else {		if (width  < 48 ||		    height < 32 ||		    width  > bttv_tvnorms[btv->tvnorm].swidth ||		    height > bttv_tvnorms[btv->tvnorm].sheight)			return -EINVAL;		buf->vb.size = (width * height * fmt->depth) >> 3;		if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)			return -EINVAL;	}	/* alloc + fill struct bttv_buffer (if changed) */	if (buf->vb.width != width || buf->vb.height != height ||	    buf->vb.field != field ||	    buf->tvnorm != btv->tvnorm || buf->fmt != fmt) {		buf->vb.width  = width;		buf->vb.height = height;		buf->vb.field  = field;		buf->tvnorm    = btv->tvnorm;		buf->fmt       = fmt;		redo_dma_risc = 1;	}	/* alloc risc memory */	if (STATE_NEEDS_INIT == buf->vb.state) {		redo_dma_risc = 1;		if (0 != (rc = videobuf_iolock(btv->c.pci,&buf->vb,&btv->fbuf)))			goto fail;	}	if (redo_dma_risc)		if (0 != (rc = bttv_buffer_risc(btv,buf)))			goto fail;	buf->vb.state = STATE_PREPARED;	return 0; fail:	bttv_dma_free(btv,buf);	return rc;}static intbuffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size){	struct bttv_fh *fh = q->priv_data;	*size = fh->fmt->depth*fh->width*fh->height >> 3;	if (0 == *count)		*count = gbuffers;	while (*size * *count > gbuffers * gbufsize)		(*count)--;	return 0;}static intbuffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,	       enum v4l2_field field){	struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);	struct bttv_fh *fh = q->priv_data;	return bttv_prepare_buffer(fh->btv, buf, fh->fmt,				   fh->width, fh->height, field);}static voidbuffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb){	struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);	struct bttv_fh *fh = q->priv_data;	struct bttv    *btv = fh->btv;	buf->vb.state = STATE_QUEUED;	list_add_tail(&buf->vb.queue,&btv->capture);	if (!btv->curr.frame_irq) {		btv->loop_irq |= 1;		bttv_set_dma(btv, 0x03);	}}static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb){	struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);	struct bttv_fh *fh = q->priv_data;	bttv_dma_free(fh->btv,buf);}static struct videobuf_queue_ops bttv_video_qops = {	.buf_setup    = buffer_setup,	.buf_prepare  = buffer_prepare,	.buf_queue    = buffer_queue,	.buf_release  = buffer_release,};static const char *v4l1_ioctls[] = {	"?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",	"CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",	"SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",	"GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",	"SMICROCODE", "GVBIFMT", "SVBIFMT" };#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg){	switch (cmd) {	case BTTV_VERSION:		return BTTV_VERSION_CODE;	/* ***  v4l1  *** ************************************************ */	case VIDIOCGFREQ:	{		unsigned long *freq = arg;		*freq = btv->freq;		return 0;	}	case VIDIOCSFREQ:	{		unsigned long *freq = arg;		down(&btv->lock);		btv->freq=*freq;		bttv_call_i2c_clients(btv,VIDIOCSFREQ,freq);		if (btv->has_matchbox && btv->radio_user)			tea5757_set_freq(btv,*freq);		up(&btv->lock);		return 0;	}

⌨️ 快捷键说明

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