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

📄 cx23885-video.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* When changing channels it is required to reset TVAUDIO */	msleep(10);	mutex_unlock(&dev->lock);	return 0;}static int vidioc_s_frequency(struct file *file, void *priv,				struct v4l2_frequency *f){	struct cx23885_fh *fh = priv;	struct cx23885_dev *dev = fh->dev;	if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV))		return -EINVAL;	if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO))		return -EINVAL;	return		cx23885_set_freq(dev, f);}#ifdef CONFIG_VIDEO_ADV_DEBUGstatic int vidioc_g_register(struct file *file, void *fh,				struct v4l2_register *reg){	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;	if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))		return -EINVAL;	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg);	return 0;}static int vidioc_s_register(struct file *file, void *fh,				struct v4l2_register *reg){	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;	if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))		return -EINVAL;	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg);	return 0;}#endif#if 0/* ----------------------------------------------------------- *//* RADIO ESPECIFIC IOCTLS                                      *//* ----------------------------------------------------------- */static int radio_querycap(struct file *file, void  *priv,					struct v4l2_capability *cap){	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;	strcpy(cap->driver, "cx23885");	strlcpy(cap->card, cx23885_boards[dev->board].name,		sizeof(cap->card));	sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));	cap->version = CX23885_VERSION_CODE;	cap->capabilities = V4L2_CAP_TUNER;	return 0;}static int radio_g_tuner(struct file *file, void *priv,				struct v4l2_tuner *t){	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;	if (unlikely(t->index > 0))		return -EINVAL;	strcpy(t->name, "Radio");	t->type = V4L2_TUNER_RADIO;	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);	return 0;}static int radio_enum_input(struct file *file, void *priv,				struct v4l2_input *i){	if (i->index != 0)		return -EINVAL;	strcpy(i->name, "Radio");	i->type = V4L2_INPUT_TYPE_TUNER;	return 0;}static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a){	if (unlikely(a->index))		return -EINVAL;	memset(a, 0, sizeof(*a));	strcpy(a->name, "Radio");	return 0;}/* FIXME: Should add a standard for radio */static int radio_s_tuner(struct file *file, void *priv,				struct v4l2_tuner *t){	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;	if (0 != t->index)		return -EINVAL;	cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_TUNER, t);	return 0;}static int radio_s_audio(struct file *file, void *fh,			  struct v4l2_audio *a){	return 0;}static int radio_s_input(struct file *file, void *fh, unsigned int i){	return 0;}static int radio_queryctrl(struct file *file, void *priv,			    struct v4l2_queryctrl *c){	int i;	if (c->id <  V4L2_CID_BASE ||		c->id >= V4L2_CID_LASTP1)		return -EINVAL;	if (c->id == V4L2_CID_AUDIO_MUTE) {		for (i = 0; i < CX23885_CTLS; i++)			if (cx23885_ctls[i].v.id == c->id)				break;		*c = cx23885_ctls[i].v;	} else		*c = no_ctl;	return 0;}#endif/* ----------------------------------------------------------- */static void cx23885_vid_timeout(unsigned long data){	struct cx23885_dev *dev = (struct cx23885_dev *)data;	struct cx23885_dmaqueue *q = &dev->vidq;	struct cx23885_buffer *buf;	unsigned long flags;	cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]);	cx_clear(VID_A_DMA_CTL, 0x11);	spin_lock_irqsave(&dev->slock, flags);	while (!list_empty(&q->active)) {		buf = list_entry(q->active.next,			struct cx23885_buffer, vb.queue);		list_del(&buf->vb.queue);		buf->vb.state = VIDEOBUF_ERROR;		wake_up(&buf->vb.done);		printk(KERN_ERR "%s/0: [%p/%d] timeout - dma=0x%08lx\n",			dev->name, buf, buf->vb.i,			(unsigned long)buf->risc.dma);	}	cx23885_restart_video_queue(dev, q);	spin_unlock_irqrestore(&dev->slock, flags);}int cx23885_video_irq(struct cx23885_dev *dev, u32 status){	u32 mask, count;	int handled = 0;	mask   = cx_read(VID_A_INT_MSK);	if (0 == (status & mask))		return handled;	cx_write(VID_A_INT_STAT, status);	dprintk(2, "%s() status = 0x%08x\n", __func__, status);	/* risc op code error */	if (status & (1 << 16)) {		printk(KERN_WARNING "%s/0: video risc op code error\n",			dev->name);		cx_clear(VID_A_DMA_CTL, 0x11);		cx23885_sram_channel_dump(dev, &dev->sram_channels[SRAM_CH01]);	}	/* risc1 y */	if (status & 0x01) {		spin_lock(&dev->slock);		count = cx_read(VID_A_GPCNT);		cx23885_video_wakeup(dev, &dev->vidq, count);		spin_unlock(&dev->slock);		handled++;	}#if 0	/* risc1 vbi */	if (status & 0x08) {		spin_lock(&dev->slock);		count = cx_read(MO_VBI_GPCNT);		cx88_wakeup(core, &dev->vbiq, count);		spin_unlock(&dev->slock);		handled++;	}#endif	/* risc2 y */	if (status & 0x10) {		dprintk(2, "stopper video\n");		spin_lock(&dev->slock);		cx23885_restart_video_queue(dev, &dev->vidq);		spin_unlock(&dev->slock);		handled++;	}#if 0	/* risc2 vbi */	if (status & 0x80) {		dprintk(2, "stopper vbi\n");		spin_lock(&dev->slock);		cx8800_restart_vbi_queue(dev, &dev->vbiq);		spin_unlock(&dev->slock);		handled++;	}#endif	return handled;}/* ----------------------------------------------------------- *//* exported stuff                                              */static const struct file_operations video_fops = {	.owner	       = THIS_MODULE,	.open	       = video_open,	.release       = video_release,	.read	       = video_read,	.poll          = video_poll,	.mmap	       = video_mmap,	.ioctl	       = video_ioctl2,	.compat_ioctl  = v4l_compat_ioctl32,	.llseek        = no_llseek,};static const struct v4l2_ioctl_ops video_ioctl_ops = {	.vidioc_querycap      = vidioc_querycap,	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,	.vidioc_g_fmt_vbi_cap     = cx23885_vbi_fmt,	.vidioc_try_fmt_vbi_cap   = cx23885_vbi_fmt,	.vidioc_s_fmt_vbi_cap     = cx23885_vbi_fmt,	.vidioc_reqbufs       = vidioc_reqbufs,	.vidioc_querybuf      = vidioc_querybuf,	.vidioc_qbuf          = vidioc_qbuf,	.vidioc_dqbuf         = vidioc_dqbuf,	.vidioc_s_std         = vidioc_s_std,	.vidioc_enum_input    = vidioc_enum_input,	.vidioc_g_input       = vidioc_g_input,	.vidioc_s_input       = vidioc_s_input,	.vidioc_queryctrl     = vidioc_queryctrl,	.vidioc_g_ctrl        = vidioc_g_ctrl,	.vidioc_s_ctrl        = vidioc_s_ctrl,	.vidioc_streamon      = vidioc_streamon,	.vidioc_streamoff     = vidioc_streamoff,#ifdef CONFIG_VIDEO_V4L1_COMPAT	.vidiocgmbuf          = vidiocgmbuf,#endif	.vidioc_g_tuner       = vidioc_g_tuner,	.vidioc_s_tuner       = vidioc_s_tuner,	.vidioc_g_frequency   = vidioc_g_frequency,	.vidioc_s_frequency   = vidioc_s_frequency,#ifdef CONFIG_VIDEO_ADV_DEBUG	.vidioc_g_register    = vidioc_g_register,	.vidioc_s_register    = vidioc_s_register,#endif};static struct video_device cx23885_vbi_template;static struct video_device cx23885_video_template = {	.name                 = "cx23885-video",	.fops                 = &video_fops,	.minor                = -1,	.ioctl_ops 	      = &video_ioctl_ops,	.tvnorms              = CX23885_NORMS,	.current_norm         = V4L2_STD_NTSC_M,};static const struct file_operations radio_fops = {	.owner         = THIS_MODULE,	.open          = video_open,	.release       = video_release,	.ioctl         = video_ioctl2,	.compat_ioctl  = v4l_compat_ioctl32,	.llseek        = no_llseek,};#if 0static const struct v4l2_ioctl_ops radio_ioctl_ops = {	.vidioc_querycap      = radio_querycap,	.vidioc_g_tuner       = radio_g_tuner,	.vidioc_enum_input    = radio_enum_input,	.vidioc_g_audio       = radio_g_audio,	.vidioc_s_tuner       = radio_s_tuner,	.vidioc_s_audio       = radio_s_audio,	.vidioc_s_input       = radio_s_input,	.vidioc_queryctrl     = radio_queryctrl,	.vidioc_g_ctrl        = vidioc_g_ctrl,	.vidioc_s_ctrl        = vidioc_s_ctrl,	.vidioc_g_frequency   = vidioc_g_frequency,	.vidioc_s_frequency   = vidioc_s_frequency,};static struct video_device cx23885_radio_template = {	.name                 = "cx23885-radio",	.fops                 = &radio_fops,	.ioctl_ops 	      = &radio_ioctl_ops,	.minor                = -1,};#endifvoid cx23885_video_unregister(struct cx23885_dev *dev){	dprintk(1, "%s()\n", __func__);	cx_clear(PCI_INT_MSK, 1);#if 0	if (dev->radio_dev) {		if (-1 != dev->radio_dev->minor)			video_unregister_device(dev->radio_dev);		else			video_device_release(dev->radio_dev);		dev->radio_dev = NULL;	}	if (dev->vbi_dev) {		if (-1 != dev->vbi_dev->minor)			video_unregister_device(dev->vbi_dev);		else			video_device_release(dev->vbi_dev);		dev->vbi_dev = NULL;		btcx_riscmem_free(dev->pci, &dev->vbiq.stopper);	}#endif	if (dev->video_dev) {		if (-1 != dev->video_dev->minor)			video_unregister_device(dev->video_dev);		else			video_device_release(dev->video_dev);		dev->video_dev = NULL;		btcx_riscmem_free(dev->pci, &dev->vidq.stopper);	}}int cx23885_video_register(struct cx23885_dev *dev){	int err;	dprintk(1, "%s()\n", __func__);	spin_lock_init(&dev->slock);	/* Initialize VBI template */	memcpy(&cx23885_vbi_template, &cx23885_video_template,		sizeof(cx23885_vbi_template));	strcpy(cx23885_vbi_template.name, "cx23885-vbi");	dev->tvnorm = cx23885_video_template.current_norm;	/* init video dma queues */	INIT_LIST_HEAD(&dev->vidq.active);	INIT_LIST_HEAD(&dev->vidq.queued);	dev->vidq.timeout.function = cx23885_vid_timeout;	dev->vidq.timeout.data = (unsigned long)dev;	init_timer(&dev->vidq.timeout);	cx23885_risc_stopper(dev->pci, &dev->vidq.stopper,		VID_A_DMA_CTL, 0x11, 0x00);	/* Don't enable VBI yet */#if 0	/* init vbi dma queues */	INIT_LIST_HEAD(&dev->vbiq.active);	INIT_LIST_HEAD(&dev->vbiq.queued);	dev->vbiq.timeout.function = cx23885_vbi_timeout;	dev->vbiq.timeout.data = (unsigned long)dev;	init_timer(&dev->vbiq.timeout);	cx23885_risc_stopper(dev->pci, &dev->vbiq.stopper,		VID_A_DMA_CTL, 0x88, 0x00);#endif	cx_set(PCI_INT_MSK, 1);#if 0	/* FIXME: These should be correctly defined */	/* load and configure helper modules */	if (TUNER_ABSENT != core->tuner_type)		request_module("tuner");	if (cx23885_boards[dev->board].audio_chip == V4L2_IDENT_WM8775)		request_module("wm8775");#endif	/* register v4l devices */	dev->video_dev = cx23885_vdev_init(dev, dev->pci,		&cx23885_video_template, "video");	err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER,				    video_nr[dev->nr]);	if (err < 0) {		printk(KERN_INFO "%s: can't register video device\n",			dev->name);		goto fail_unreg;	}	printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n",	       dev->name, dev->video_dev->num);#if 0	dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,		&cx23885_vbi_template, "vbi");	err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,				    vbi_nr[dev->nr]);	if (err < 0) {		printk(KERN_INFO "%s/0: can't register vbi device\n",			dev->name);		goto fail_unreg;	}	printk(KERN_INFO "%s/0: registered device vbi%d\n",	       dev->name, dev->vbi_dev->num);	if (dev->has_radio) {		dev->radio_dev = cx23885_vdev_init(dev, dev->pci,			&cx23885_radio_template, "radio");		err = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,					    radio_nr[dev->nr]);		if (err < 0) {			printk(KERN_INFO "%s/0: can't register radio device\n",			       dev->name);			goto fail_unreg;		}		printk(KERN_INFO "%s/0: registered device radio%d\n",		       dev->name, dev->radio_dev->num);	}#endif	/* initial device configuration */	mutex_lock(&dev->lock);	cx23885_set_tvnorm(dev, dev->tvnorm);	init_controls(dev);	cx23885_video_mux(dev, 0);	mutex_unlock(&dev->lock);	return 0;fail_unreg:	cx23885_video_unregister(dev);	return err;}

⌨️ 快捷键说明

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