Commit b3c4ee70 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

V4L/DVB (5109): Convert cx88-blackbird to use video_ioctl2



This patch finishes cx88-blackbird conversion to use video_ioctl2. Video
standards are generated automatically inside videodev.c. the big ioctl
parser is removed, using, instead, video_ioctl2.

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 7730bef9
Loading
Loading
Loading
Loading
+344 −434
Original line number Diff line number Diff line
@@ -6,6 +6,9 @@
 *    (c) 2004 Jelle Foks <jelle@foks.8m.com>
 *    (c) 2004 Gerd Knorr <kraxel@bytesex.org>
 *
 *    (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
 *        - video_ioctl2 conversion
 *
 *  Includes parts from the ivtv driver( http://ivtv.sourceforge.net/),
 *
 *  This program is free software; you can redistribute it and/or modify
@@ -53,73 +56,6 @@ MODULE_PARM_DESC(debug,"enable debug messages [blackbird]");

/* ------------------------------------------------------------------ */


struct cx88_tvnorm {
	char                   *name;
	v4l2_std_id            id;
	u32                    cxiformat;
	u32                    cxoformat;
};

static struct cx88_tvnorm tvnorms[] = {
	{
		.name      = "NTSC-M",
		.id        = V4L2_STD_NTSC_M,
		.cxiformat = VideoFormatNTSC,
		.cxoformat = 0x181f0008,
	},{
		.name      = "NTSC-JP",
		.id        = V4L2_STD_NTSC_M_JP,
		.cxiformat = VideoFormatNTSCJapan,
		.cxoformat = 0x181f0008,
	},{
		.name      = "PAL-BG",
		.id        = V4L2_STD_PAL_BG,
		.cxiformat = VideoFormatPAL,
		.cxoformat = 0x181f0008,
	},{
		.name      = "PAL-DK",
		.id        = V4L2_STD_PAL_DK,
		.cxiformat = VideoFormatPAL,
		.cxoformat = 0x181f0008,
	},{
		.name      = "PAL-I",
		.id        = V4L2_STD_PAL_I,
		.cxiformat = VideoFormatPAL,
		.cxoformat = 0x181f0008,
	},{
		.name      = "PAL-M",
		.id        = V4L2_STD_PAL_M,
		.cxiformat = VideoFormatPALM,
		.cxoformat = 0x1c1f0008,
	},{
		.name      = "PAL-N",
		.id        = V4L2_STD_PAL_N,
		.cxiformat = VideoFormatPALN,
		.cxoformat = 0x1c1f0008,
	},{
		.name      = "PAL-Nc",
		.id        = V4L2_STD_PAL_Nc,
		.cxiformat = VideoFormatPALNC,
		.cxoformat = 0x1c1f0008,
	},{
		.name      = "PAL-60",
		.id        = V4L2_STD_PAL_60,
		.cxiformat = VideoFormatPAL60,
		.cxoformat = 0x181f0008,
	},{
		.name      = "SECAM-L",
		.id        = V4L2_STD_SECAM_L,
		.cxiformat = VideoFormatSECAM,
		.cxoformat = 0x181f0008,
	},{
		.name      = "SECAM-DK",
		.id        = V4L2_STD_SECAM_DK,
		.cxiformat = VideoFormatSECAM,
		.cxoformat = 0x181f0008,
	}
};

#define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024

/* defines below are from ivtv-driver.h */
@@ -777,8 +713,13 @@ static int blackbird_queryctrl(struct cx8802_dev *dev, struct v4l2_queryctrl *qc
	return 0;
}

static int blackbird_querymenu(struct cx8802_dev *dev, struct v4l2_querymenu *qmenu)
/* ------------------------------------------------------------------ */
/* IOCTL Handlers                                                     */

static int vidioc_querymenu (struct file *file, void *priv,
				struct v4l2_querymenu *qmenu)
{
	struct cx8802_dev *dev  = ((struct cx8802_fh *)priv)->dev;
	struct v4l2_queryctrl qctrl;

	qctrl.id = qmenu->id;
@@ -786,26 +727,12 @@ static int blackbird_querymenu(struct cx8802_dev *dev, struct v4l2_querymenu *qm
	return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
}

/* ------------------------------------------------------------------ */

static int mpeg_do_ioctl(struct inode *inode, struct file *file,
			 unsigned int cmd, void *arg)
static int vidioc_querycap (struct file *file, void  *priv,
					struct v4l2_capability *cap)
{
	struct cx8802_fh  *fh  = file->private_data;
	struct cx8802_dev *dev = fh->dev;
	struct cx8802_dev *dev  = ((struct cx8802_fh *)priv)->dev;
	struct cx88_core  *core = dev->core;

	if (debug > 1)
		v4l_print_ioctl(core->name,cmd);

	switch (cmd) {

	/* --- capabilities ------------------------------------------ */
	case VIDIOC_QUERYCAP:
	{
		struct v4l2_capability *cap = arg;

		memset(cap,0,sizeof(*cap));
	strcpy(cap->driver, "cx88_blackbird");
	strlcpy(cap->card, cx88_boards[core->board].name,sizeof(cap->card));
	sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -816,32 +743,27 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
		V4L2_CAP_STREAMING;
	if (UNSET != core->tuner_type)
		cap->capabilities |= V4L2_CAP_TUNER;

	return 0;
}

	/* --- capture ioctls ---------------------------------------- */
	case VIDIOC_ENUM_FMT:
static int vidioc_enum_fmt_cap (struct file *file, void  *priv,
					struct v4l2_fmtdesc *f)
{
		struct v4l2_fmtdesc *f = arg;
		int index;

		index = f->index;
		if (index != 0)
	if (f->index != 0)
		return -EINVAL;

		memset(f,0,sizeof(*f));
		f->index = index;
	strlcpy(f->description, "MPEG", sizeof(f->description));
	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	f->pixelformat = V4L2_PIX_FMT_MPEG;
	return 0;
}
	case VIDIOC_G_FMT:

static int vidioc_g_fmt_cap (struct file *file, void *priv,
					struct v4l2_format *f)
{
		struct v4l2_format *f = arg;
	struct cx8802_fh  *fh   = priv;
	struct cx8802_dev *dev  = fh->dev;

		memset(f,0,sizeof(*f));
	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
	f->fmt.pix.bytesperline = 0;
@@ -854,9 +776,12 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
		dev->width, dev->height, fh->mpegq.field );
	return 0;
}
	case VIDIOC_TRY_FMT:

static int vidioc_try_fmt_cap (struct file *file, void *priv,
			struct v4l2_format *f)
{
		struct v4l2_format *f = arg;
	struct cx8802_fh  *fh   = priv;
	struct cx8802_dev *dev  = fh->dev;

	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
@@ -867,108 +792,149 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
		dev->width, dev->height, fh->mpegq.field );
	return 0;
}
	case VIDIOC_S_FMT:

static int vidioc_s_fmt_cap (struct file *file, void *priv,
					struct v4l2_format *f)
{
		struct v4l2_format *f = arg;
	struct cx8802_fh  *fh   = priv;
	struct cx8802_dev *dev  = fh->dev;
	struct cx88_core  *core = dev->core;

	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
	f->fmt.pix.bytesperline = 0;
	f->fmt.pix.sizeimage    = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
	f->fmt.pix.colorspace   = 0;
	dev->width              = f->fmt.pix.width;
	dev->height             = f->fmt.pix.height;
	fh->mpegq.field         = f->fmt.pix.field;
	cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
	blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
				f->fmt.pix.height, f->fmt.pix.width);
	dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
		f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
	return 0;
}

	/* --- streaming capture ------------------------------------- */
	case VIDIOC_REQBUFS:
		return videobuf_reqbufs(&fh->mpegq, arg);
static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p)
{
	struct cx8802_fh  *fh   = priv;
	return (videobuf_reqbufs(&fh->mpegq, p));
}

	case VIDIOC_QUERYBUF:
		return videobuf_querybuf(&fh->mpegq, arg);
static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p)
{
	struct cx8802_fh  *fh   = priv;
	return (videobuf_querybuf(&fh->mpegq, p));
}

	case VIDIOC_QBUF:
		return videobuf_qbuf(&fh->mpegq, arg);
static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p)
{
	struct cx8802_fh  *fh   = priv;
	return (videobuf_qbuf(&fh->mpegq, p));
}

	case VIDIOC_DQBUF:
		return videobuf_dqbuf(&fh->mpegq, arg,
				      file->f_flags & O_NONBLOCK);
static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
{
	struct cx8802_fh  *fh   = priv;
	return (videobuf_dqbuf(&fh->mpegq, p,
				file->f_flags & O_NONBLOCK));
}

	case VIDIOC_STREAMON:
static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
	struct cx8802_fh  *fh   = priv;
	return videobuf_streamon(&fh->mpegq);
}

	case VIDIOC_STREAMOFF:
static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
{
	struct cx8802_fh  *fh   = priv;
	return videobuf_streamoff(&fh->mpegq);
}

	/* --- mpeg compression -------------------------------------- */
	case VIDIOC_G_MPEGCOMP:
static int vidioc_g_mpegcomp (struct file *file, void *fh,
			      struct v4l2_mpeg_compression *f)
{
		struct v4l2_mpeg_compression *f = arg;

	printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. "
				"Replace with VIDIOC_G_EXT_CTRLS!");
	memcpy(f,&default_mpeg_params,sizeof(*f));
	return 0;
}
	case VIDIOC_S_MPEGCOMP:

static int vidioc_s_mpegcomp (struct file *file, void *fh,
			      struct v4l2_mpeg_compression *f)
{
	printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. "
				"Replace with VIDIOC_S_EXT_CTRLS!");
	return 0;
	case VIDIOC_G_EXT_CTRLS:
}

static int vidioc_g_ext_ctrls (struct file *file, void *priv,
			       struct v4l2_ext_controls *f)
{
		struct v4l2_ext_controls *f = arg;
	struct cx8802_dev *dev  = ((struct cx8802_fh *)priv)->dev;

	if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
		return -EINVAL;
		return cx2341x_ext_ctrls(&dev->params, f, cmd);
	return cx2341x_ext_ctrls(&dev->params, f, VIDIOC_G_EXT_CTRLS);
}
	case VIDIOC_S_EXT_CTRLS:

static int vidioc_s_ext_ctrls (struct file *file, void *priv,
			       struct v4l2_ext_controls *f)
{
		struct v4l2_ext_controls *f = arg;
	struct cx8802_dev *dev  = ((struct cx8802_fh *)priv)->dev;
	struct cx2341x_mpeg_params p;
	int err;

	if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
		return -EINVAL;
	p = dev->params;
		err = cx2341x_ext_ctrls(&p, VIDIOC_S_EXT_CTRLS, cmd);
		if (err == 0 && cmd == VIDIOC_S_EXT_CTRLS) {
	err = cx2341x_ext_ctrls(&p, f, VIDIOC_S_EXT_CTRLS);
	if (!err) {
		err = cx2341x_update(dev, blackbird_mbox_func, &dev->params, &p);
		dev->params = p;
	}
	return err;
}
	case VIDIOC_TRY_EXT_CTRLS:

static int vidioc_try_ext_ctrls (struct file *file, void *priv,
			       struct v4l2_ext_controls *f)
{
		struct v4l2_ext_controls *f = arg;
	struct cx8802_dev *dev  = ((struct cx8802_fh *)priv)->dev;
	struct cx2341x_mpeg_params p;
	int err;

	if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
		return -EINVAL;
	p = dev->params;
		err = cx2341x_ext_ctrls(&p, VIDIOC_TRY_EXT_CTRLS, cmd);
	err = cx2341x_ext_ctrls(&p, f, VIDIOC_TRY_EXT_CTRLS);

	return err;
}
	case VIDIOC_S_FREQUENCY:

static int vidioc_s_frequency (struct file *file, void *priv,
				struct v4l2_frequency *f)
{
		struct v4l2_frequency *f = arg;
	struct cx8802_fh  *fh   = priv;
	struct cx8802_dev *dev  = fh->dev;
	struct cx88_core  *core = dev->core;

	blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
				BLACKBIRD_END_NOW,
				BLACKBIRD_MPEG_CAPTURE,
				BLACKBIRD_RAW_BITS_NONE);

	cx88_set_freq (core,f);

	blackbird_initialize_codec(dev);
	cx88_set_scale(dev->core, dev->width, dev->height,
			fh->mpegq.field);
	return 0;
}
	case VIDIOC_LOG_STATUS:

static int vidioc_log_status (struct file *file, void *priv)
{
	struct cx8802_dev *dev  = ((struct cx8802_fh *)priv)->dev;
	struct cx88_core  *core = dev->core;
	char name[32 + 2];

	snprintf(name, sizeof(name), "%s/2", core->name);
@@ -980,110 +946,91 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
		core->name);
	return 0;
}
	case VIDIOC_QUERYMENU:
		return blackbird_querymenu(dev, arg);
	case VIDIOC_QUERYCTRL:

static int vidioc_queryctrl (struct file *file, void *priv,
				struct v4l2_queryctrl *qctrl)
{
		struct v4l2_queryctrl *qctrl = arg;
	struct cx8802_dev *dev  = ((struct cx8802_fh *)priv)->dev;

	if (blackbird_queryctrl(dev, qctrl) == 0)
		return 0;

		struct v4l2_queryctrl *qctrl = arg;

	qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
	if (unlikely(qctrl->id == 0))
		return -EINVAL;
	return cx8800_ctrl_query(qctrl);
}

	/* ------ input switching ---------- */
	case VIDIOC_ENUMINPUT:
static int vidioc_enum_input (struct file *file, void *priv,
				struct v4l2_input *i)
{
		static const char *iname[] = {
			[ CX88_VMUX_COMPOSITE1 ] = "Composite1",
			[ CX88_VMUX_COMPOSITE2 ] = "Composite2",
			[ CX88_VMUX_COMPOSITE3 ] = "Composite3",
			[ CX88_VMUX_COMPOSITE4 ] = "Composite4",
			[ CX88_VMUX_SVIDEO     ] = "S-Video",
			[ CX88_VMUX_TELEVISION ] = "Television",
			[ CX88_VMUX_CABLE      ] = "Cable TV",
			[ CX88_VMUX_DVB        ] = "DVB",
			[ CX88_VMUX_DEBUG      ] = "for debug only",
		};
		struct v4l2_input *i = arg;
		unsigned int n;
	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;
	return cx88_enum_input (core,i);
}

		n = i->index;
		if (n >= 4)
			return -EINVAL;
		if (0 == INPUT(n)->type)
			return -EINVAL;
		memset(i,0,sizeof(*i));
		i->index = n;
		i->type  = V4L2_INPUT_TYPE_CAMERA;
		strcpy(i->name,iname[INPUT(n)->type]);
		if ((CX88_VMUX_TELEVISION == INPUT(n)->type) ||
		    (CX88_VMUX_CABLE      == INPUT(n)->type))
			i->type = V4L2_INPUT_TYPE_TUNER;
		for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
			i->std |= tvnorms[n].id;
		return 0;
static int vidioc_g_ctrl (struct file *file, void *priv,
				struct v4l2_control *ctl)
{
	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;
	return
		cx88_get_control(core,ctl);
}
	case VIDIOC_G_CTRL:
		return cx88_get_control(core,arg);
	case VIDIOC_S_CTRL:
		return cx88_set_control(core,arg);

	case VIDIOC_G_FREQUENCY:
static int vidioc_s_ctrl (struct file *file, void *priv,
				struct v4l2_control *ctl)
{
		struct v4l2_frequency *f = arg;
	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;
	return
		cx88_set_control(core,ctl);
}

		memset(f,0,sizeof(*f));
static int vidioc_g_frequency (struct file *file, void *priv,
				struct v4l2_frequency *f)
{
	struct cx8802_fh  *fh   = priv;
	struct cx88_core  *core = fh->dev->core;

		if (UNSET == core->tuner_type)
	if (unlikely(UNSET == core->tuner_type))
		return -EINVAL;

		/* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */
		f->type = radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
	f->type = V4L2_TUNER_ANALOG_TV;
	f->frequency = core->freq;

	cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);

	return 0;
}
	case VIDIOC_G_INPUT:

static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
{
		unsigned int *i = arg;
	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;

	*i = core->input;
	return 0;
}
	case VIDIOC_S_INPUT:

static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
{
		unsigned int *i = arg;
	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;

		if (*i >= 4)
	if (i >= 4)
		return -EINVAL;

	mutex_lock(&core->lock);
	cx88_newstation(core);
		cx88_video_mux(core,*i);
	cx88_video_mux(core,i);
	mutex_unlock(&core->lock);
	return 0;
}


	case VIDIOC_G_TUNER:
static int vidioc_g_tuner (struct file *file, void *priv,
				struct v4l2_tuner *t)
{
		struct v4l2_tuner *t = arg;
	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;
	u32 reg;

		if (UNSET == core->tuner_type)
			return -EINVAL;
		if (0 != t->index)
	if (unlikely(UNSET == core->tuner_type))
		return -EINVAL;

		memset(t,0,sizeof(*t));
	strcpy(t->name, "Television");
	t->type       = V4L2_TUNER_ANALOG_TV;
	t->capability = V4L2_TUNER_CAP_NORM;
@@ -1094,104 +1041,32 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
	t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
	return 0;
}
	case VIDIOC_S_TUNER:

static int vidioc_s_tuner (struct file *file, void *priv,
				struct v4l2_tuner *t)
{
		struct v4l2_tuner *t = arg;
	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;

	if (UNSET == core->tuner_type)
		return -EINVAL;
	if (0 != t->index)
		return -EINVAL;

	cx88_set_stereo(core, t->audmode, 1);
	return 0;
}
	/* ---------- tv norms ---------- */
	case VIDIOC_S_STD:
	{
		v4l2_std_id *id = arg;
		unsigned int i;

		for(i = 0; i < ARRAY_SIZE(tvnorms); i++)
			if (*id & tvnorms[i].id)
				break;
		if (i == ARRAY_SIZE(tvnorms))
			return -EINVAL;
static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id)
{
	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;

	mutex_lock(&core->lock);
		cx88_set_tvnorm(core,tvnorms[i].id);
	cx88_set_tvnorm(core,*id);
	mutex_unlock(&core->lock);
	return 0;
}
	case VIDIOC_ENUMSTD:
	{
		struct v4l2_standard *e = arg;
		unsigned int i;

		i = e->index;
		if (i >= ARRAY_SIZE(tvnorms))
			return -EINVAL;
		err = v4l2_video_std_construct(e, tvnorms[e->index].id,
					       tvnorms[e->index].name);
		e->index = i;
		if (err < 0)
			return err;
		return 0;
	}
	case VIDIOC_G_STD:
	{
		v4l2_std_id *id = arg;

		*id = core->tvnorm;
		return 0;
	}

#ifdef CONFIG_VIDEO_ADV_DEBUG
	/* ioctls to allow direct acces to the cx2388x registers */
	case VIDIOC_INT_G_REGISTER:
	{
		struct v4l2_register *reg = arg;

		if (reg->i2c_id != 0)
			return -EINVAL;
		/* cx2388x has a 24-bit register space */
		reg->val = cx_read(reg->reg&0xffffff);
		return 0;
	}
	case VIDIOC_INT_S_REGISTER:
	{
		struct v4l2_register *reg = arg;

		if (reg->i2c_id != 0)
			return -EINVAL;
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;
		cx_write(reg->reg&0xffffff, reg->val);
		return 0;
	}
#endif

	default:
		return v4l_compat_translate_ioctl(inode,file,cmd,arg,
						  driver_ioctl);
	}
	return 0;
}

int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
			unsigned int cmd, void *arg);
unsigned int (*cx88_ioctl_translator)(unsigned int cmd);

static unsigned int mpeg_translate_ioctl(unsigned int cmd)
{
	return cmd;
}

static int mpeg_ioctl(struct inode *inode, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	cmd = cx88_ioctl_translator( cmd );
	return video_usercopy(inode, file, cmd, arg, cx88_ioctl_hook);
}
/* FIXME: cx88_ioctl_hook not implemented */

static int mpeg_open(struct inode *inode, struct file *file)
{
@@ -1318,7 +1193,7 @@ static const struct file_operations mpeg_fops =
	.read	       = mpeg_read,
	.poll          = mpeg_poll,
	.mmap	       = mpeg_mmap,
	.ioctl	       = mpeg_ioctl,
	.ioctl	       = video_ioctl2,
	.llseek        = no_llseek,
};

@@ -1326,9 +1201,39 @@ static struct video_device cx8802_mpeg_template =
{
	.name                 = "cx8802",
	.type                 = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES|VID_TYPE_MPEG_ENCODER,
	.hardware      = 0,
	.fops                 = &mpeg_fops,
	.minor                = -1,
	.vidioc_querymenu     = vidioc_querymenu,
	.vidioc_querycap      = vidioc_querycap,
	.vidioc_enum_fmt_cap  = vidioc_enum_fmt_cap,
	.vidioc_g_fmt_cap     = vidioc_g_fmt_cap,
	.vidioc_try_fmt_cap   = vidioc_try_fmt_cap,
	.vidioc_s_fmt_cap     = vidioc_s_fmt_cap,
	.vidioc_reqbufs       = vidioc_reqbufs,
	.vidioc_querybuf      = vidioc_querybuf,
	.vidioc_qbuf          = vidioc_qbuf,
	.vidioc_dqbuf         = vidioc_dqbuf,
	.vidioc_streamon      = vidioc_streamon,
	.vidioc_streamoff     = vidioc_streamoff,
	.vidioc_g_mpegcomp    = vidioc_g_mpegcomp,
	.vidioc_s_mpegcomp    = vidioc_s_mpegcomp,
	.vidioc_g_ext_ctrls   = vidioc_g_ext_ctrls,
	.vidioc_s_ext_ctrls   = vidioc_s_ext_ctrls,
	.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
	.vidioc_s_frequency   = vidioc_s_frequency,
	.vidioc_log_status    = vidioc_log_status,
	.vidioc_queryctrl     = vidioc_queryctrl,
	.vidioc_enum_input    = vidioc_enum_input,
	.vidioc_g_ctrl        = vidioc_g_ctrl,
	.vidioc_s_ctrl        = vidioc_s_ctrl,
	.vidioc_g_frequency   = vidioc_g_frequency,
	.vidioc_g_input       = vidioc_g_input,
	.vidioc_s_input       = vidioc_s_input,
	.vidioc_g_tuner       = vidioc_g_tuner,
	.vidioc_s_tuner       = vidioc_s_tuner,
	.vidioc_s_std         = vidioc_s_std,
	.tvnorms              = CX88_NORMS,
	.current_norm         = V4L2_STD_PAL_BG,
};

/* ------------------------------------------------------------------ */
@@ -1423,6 +1328,8 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
	cx2341x_fill_defaults(&dev->params);
	dev->params.port = CX2341X_PORT_STREAMING;

	cx8802_mpeg_template.current_norm = core->tvnorm;

	if (core->tvnorm & V4L2_STD_525_60) {
		dev->height = 480;
	} else {
@@ -1437,6 +1344,11 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
	blackbird_register_video(dev);

	/* initial device configuration: needed ? */
	mutex_lock(&dev->core->lock);
//	init_controls(core);
	cx88_set_tvnorm(core,core->tvnorm);
	cx88_video_mux(core,0);
	mutex_unlock(&dev->core->lock);

	return 0;

@@ -1471,8 +1383,6 @@ static int blackbird_init(void)
	printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
	       SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
#endif
	cx88_ioctl_hook = mpeg_do_ioctl;
	cx88_ioctl_translator = mpeg_translate_ioctl;
	return cx8802_register_driver(&cx8802_blackbird_driver);
}

@@ -1484,8 +1394,8 @@ static void blackbird_fini(void)
module_init(blackbird_init);
module_exit(blackbird_fini);

EXPORT_SYMBOL(cx88_ioctl_hook);
EXPORT_SYMBOL(cx88_ioctl_translator);
module_param_named(video_debug,cx8802_mpeg_template.debug, int, 0644);
MODULE_PARM_DESC(debug,"enable debug messages [video]");

/* ----------------------------------------------------------- */
/*
+0 −7
Original line number Diff line number Diff line
@@ -645,13 +645,6 @@ int cx88_get_control(struct cx88_core *core, struct v4l2_control *ctl);
int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl);
int cx88_video_mux(struct cx88_core *core, unsigned int input);

/* ----------------------------------------------------------- */
/* cx88-blackbird.c                                            */
/* used by cx88-ivtv ioctl emulation layer                     */
extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
			      unsigned int cmd, void *arg);
extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);

/*
 * Local variables:
 * c-basic-offset: 8