aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/video/cx23885
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx23885')
-rw-r--r--drivers/media/video/cx23885/Kconfig2
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c701
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c13
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c10
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c42
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c24
-rw-r--r--drivers/media/video/cx23885/cx23885.h1
7 files changed, 451 insertions, 342 deletions
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index 7bf14c9a15c..5cfb46bbdaa 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -9,11 +9,13 @@ config VIDEO_CX23885
select VIDEO_TVEEPROM
select VIDEO_IR
select VIDEOBUF_DVB
+ select VIDEOBUF_DMA_SG
select VIDEO_CX25840
select VIDEO_CX2341X
select DVB_DIB7000P if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE
select DVB_S5H1409 if !DVB_FE_CUSTOMISE
+ select DVB_S5H1411 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index acdd3b6b3e7..e7ef093265a 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1173,379 +1173,404 @@ static int cx23885_querymenu(struct cx23885_dev *dev,
qctrl.id = qmenu->id;
cx23885_queryctrl(dev, &qctrl);
return v4l2_ctrl_query_menu(qmenu, &qctrl,
- cx2341x_ctrl_get_menu(qmenu->id));
+ cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id));
}
-int cx23885_do_ioctl(struct inode *inode, struct file *file, int radio,
- struct cx23885_dev *dev, unsigned int cmd, void *arg,
- v4l2_kioctl driver_ioctl)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
{
- int err;
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+ unsigned int i;
- switch (cmd) {
- /* ---------- tv norms ---------- */
- case VIDIOC_ENUMSTD:
- {
- struct v4l2_standard *e = arg;
- unsigned int i;
-
- i = e->index;
- if (i >= ARRAY_SIZE(cx23885_tvnorms))
- return -EINVAL;
- err = v4l2_video_std_construct(e,
- cx23885_tvnorms[e->index].id,
- cx23885_tvnorms[e->index].name);
- e->index = i;
- if (err < 0)
- return err;
- return 0;
- }
- case VIDIOC_G_STD:
- {
- v4l2_std_id *id = arg;
+ for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
+ if (*id & cx23885_tvnorms[i].id)
+ break;
+ if (i == ARRAY_SIZE(cx23885_tvnorms))
+ return -EINVAL;
+ dev->encodernorm = cx23885_tvnorms[i];
+ return 0;
+}
- *id = dev->encodernorm.id;
- return 0;
- }
- case VIDIOC_S_STD:
- {
- v4l2_std_id *id = arg;
- unsigned int i;
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *i)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+ struct cx23885_input *input;
+ unsigned int n;
- for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
- if (*id & cx23885_tvnorms[i].id)
- break;
- if (i == ARRAY_SIZE(cx23885_tvnorms))
- return -EINVAL;
- dev->encodernorm = cx23885_tvnorms[i];
+ n = i->index;
- return 0;
- }
+ if (n >= 4)
+ return -EINVAL;
- /* ------ input switching ---------- */
- case VIDIOC_ENUMINPUT:
- {
- struct cx23885_input *input;
- struct v4l2_input *i = arg;
- unsigned int n;
-
- n = i->index;
- if (n >= 4)
- return -EINVAL;
- input = &cx23885_boards[dev->board].input[n];
- if (input->type == 0)
- return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = n;
- /* FIXME
- * strcpy(i->name, input->name); */
- strcpy(i->name, "unset");
- if (input->type == CX23885_VMUX_TELEVISION ||
- input->type == CX23885_VMUX_CABLE)
- i->type = V4L2_INPUT_TYPE_TUNER;
- else
- i->type = V4L2_INPUT_TYPE_CAMERA;
+ input = &cx23885_boards[dev->board].input[n];
- for (n = 0; n < ARRAY_SIZE(cx23885_tvnorms); n++)
- i->std |= cx23885_tvnorms[n].id;
- return 0;
- }
- case VIDIOC_G_INPUT:
- {
- unsigned int *i = arg;
+ if (input->type == 0)
+ return -EINVAL;
- *i = dev->input;
- return 0;
- }
- case VIDIOC_S_INPUT:
- {
- unsigned int *i = arg;
+ memset(i, 0, sizeof(*i));
+ i->index = n;
- if (*i >= 4)
- return -EINVAL;
+ /* FIXME
+ * strcpy(i->name, input->name); */
+ strcpy(i->name, "unset");
- return 0;
- }
+ if (input->type == CX23885_VMUX_TELEVISION ||
+ input->type == CX23885_VMUX_CABLE)
+ i->type = V4L2_INPUT_TYPE_TUNER;
+ else
+ i->type = V4L2_INPUT_TYPE_CAMERA;
- /* --- tuner ioctls ------------------------------------------ */
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *t = arg;
+ for (n = 0; n < ARRAY_SIZE(cx23885_tvnorms); n++)
+ i->std |= cx23885_tvnorms[n].id;
+ return 0;
+}
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
- memset(t, 0, sizeof(*t));
- strcpy(t->name, "Television");
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
- dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
+ *i = dev->input;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ if (i >= 4)
+ return -EINVAL;
- if (UNSET == dev->tuner_type)
- return -EINVAL;
+ return 0;
+}
- /* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *t)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ if (UNSET == dev->tuner_type)
+ return -EINVAL;
+ if (0 != t->index)
+ return -EINVAL;
+ memset(t, 0, sizeof(*t));
+ strcpy(t->name, "Television");
+ cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);
+ cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
- memset(f, 0, sizeof(*f));
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- f->type = V4L2_TUNER_ANALOG_TV;
- f->frequency = dev->freq;
+ dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1],
- VIDIOC_G_FREQUENCY, f);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
-
- dprintk(1, "VIDIOC_S_FREQUENCY: dev type %d, f\n",
- dev->tuner_type);
- dprintk(1, "VIDIOC_S_FREQUENCY: f tuner %d, f type %d\n",
- f->tuner, f->type);
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- if (f->tuner != 0)
- return -EINVAL;
- if (f->type != V4L2_TUNER_ANALOG_TV)
- return -EINVAL;
- dev->freq = f->frequency;
-
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1],
- VIDIOC_S_FREQUENCY, f);
- return 0;
- }
- case VIDIOC_S_CTRL:
- {
- /* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, arg);
- return 0;
- }
- default:
- /* Convert V4L ioctl to V4L2 and call mpeg_do_ioctl
- * (driver_ioctl) */
- return v4l_compat_translate_ioctl(inode, file, cmd, arg,
- driver_ioctl);
- }
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *t)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+
+ if (UNSET == dev->tuner_type)
+ return -EINVAL;
+
+ /* Update the A/V core */
+ cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);
+
+ return 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+
+ memset(f, 0, sizeof(*f));
+ if (UNSET == dev->tuner_type)
+ return -EINVAL;
+ f->type = V4L2_TUNER_ANALOG_TV;
+ f->frequency = dev->freq;
+
+ /* Assumption that tuner is always on bus 1 */
+ cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+
+ return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+
+ cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
+ CX23885_END_NOW, CX23885_MPEG_CAPTURE,
+ CX23885_RAW_BITS_NONE);
+
+ dprintk(1, "VIDIOC_S_FREQUENCY: dev type %d, f\n",
+ dev->tuner_type);
+ dprintk(1, "VIDIOC_S_FREQUENCY: f tuner %d, f type %d\n",
+ f->tuner, f->type);
+ if (UNSET == dev->tuner_type)
+ return -EINVAL;
+ if (f->tuner != 0)
+ return -EINVAL;
+ if (f->type != V4L2_TUNER_ANALOG_TV)
+ return -EINVAL;
+ dev->freq = f->frequency;
+
+ /* Assumption that tuner is always on bus 1 */
+ cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+
+ cx23885_initialize_codec(dev);
return 0;
}
-static int mpeg_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctl)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+
+ /* Update the A/V core */
+ cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl);
+ return 0;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_tsport *tsport = &dev->ts1;
- if (v4l_debug > 1)
- v4l_print_ioctl(dev->name, cmd);
+ memset(cap, 0, sizeof(*cap));
+ strcpy(cap->driver, dev->name);
+ strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
+ sizeof(cap->card));
+ sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
+ cap->version = CX23885_VERSION_CODE;
+ cap->capabilities =
+ V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_STREAMING |
+ 0;
+ if (UNSET != dev->tuner_type)
+ cap->capabilities |= V4L2_CAP_TUNER;
- switch (cmd) {
+ return 0;
+}
- /* --- capabilities ------------------------------------------ */
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *cap = arg;
-
- memset(cap, 0, sizeof(*cap));
- strcpy(cap->driver, dev->name);
- strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
- sizeof(cap->card));
- sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
- cap->version = CX23885_VERSION_CODE;
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING |
- 0;
- if (UNSET != dev->tuner_type)
- cap->capabilities |= V4L2_CAP_TUNER;
-
- return 0;
- }
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ int index;
- /* --- capture ioctls ---------------------------------------- */
- case VIDIOC_ENUM_FMT:
- {
- struct v4l2_fmtdesc *f = arg;
- int index;
-
- index = f->index;
- if (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:
- {
- struct v4l2_format *f = arg;
-
- 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;
- f->fmt.pix.sizeimage =
- dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.width = dev->ts1.width;
- f->fmt.pix.height = dev->ts1.height;
- f->fmt.pix.field = fh->mpegq.field;
- dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
- dev->ts1.width, dev->ts1.height, fh->mpegq.field);
- return 0;
- }
- case VIDIOC_TRY_FMT:
- {
- struct v4l2_format *f = arg;
-
- 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->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.sizeimage =
- f->fmt.pix.colorspace = 0;
- dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
- dev->ts1.width, dev->ts1.height, fh->mpegq.field);
- return 0;
- }
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
-
- 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->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.colorspace = 0;
- dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
- return 0;
- }
+ index = f->index;
+ if (index != 0)
+ return -EINVAL;
- /* --- streaming capture ------------------------------------- */
- case VIDIOC_REQBUFS:
- return videobuf_reqbufs(&fh->mpegq, arg);
+ 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;
- case VIDIOC_QUERYBUF:
- return videobuf_querybuf(&fh->mpegq, arg);
+ return 0;
+}
- case VIDIOC_QBUF:
- return videobuf_qbuf(&fh->mpegq, arg);
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
- case VIDIOC_DQBUF:
- return videobuf_dqbuf(&fh->mpegq, arg,
- file->f_flags & O_NONBLOCK);
+ 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;
+ f->fmt.pix.sizeimage =
+ dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
+ f->fmt.pix.colorspace = 0;
+ f->fmt.pix.width = dev->ts1.width;
+ f->fmt.pix.height = dev->ts1.height;
+ f->fmt.pix.field = fh->mpegq.field;
+ dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
+ dev->ts1.width, dev->ts1.height, fh->mpegq.field);
+ return 0;
+}
- case VIDIOC_STREAMON:
- return videobuf_streamon(&fh->mpegq);
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
- case VIDIOC_STREAMOFF:
- return videobuf_streamoff(&fh->mpegq);
+ 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->ts1.ts_packet_size * dev->ts1.ts_packet_count;
+ f->fmt.pix.sizeimage =
+ f->fmt.pix.colorspace = 0;
+ dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
+ dev->ts1.width, dev->ts1.height, fh->mpegq.field);
+ return 0;
+}
- case VIDIOC_G_EXT_CTRLS:
- {
- struct v4l2_ext_controls *f = arg;
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
- if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, cmd);
- }
- case VIDIOC_S_EXT_CTRLS:
- case VIDIOC_TRY_EXT_CTRLS:
- {
- struct v4l2_ext_controls *f = arg;
- struct cx2341x_mpeg_params p;
- int err;
-
- if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- p = dev->mpeg_params;
- err = cx2341x_ext_ctrls(&p, 0, f, cmd);
- if (err == 0 && cmd == VIDIOC_S_EXT_CTRLS) {
- err = cx2341x_update(dev, cx23885_mbox_func,
- &dev->mpeg_params, &p);
- dev->mpeg_params = p;
- }
- return err;
- }
- case VIDIOC_S_FREQUENCY:
- {
- cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
- CX23885_END_NOW, CX23885_MPEG_CAPTURE,
- CX23885_RAW_BITS_NONE);
- cx23885_do_ioctl(inode, file, 0, dev, cmd, arg,
- mpeg_do_ioctl);
- cx23885_initialize_codec(dev);
-
- return 0;
- }
- case VIDIOC_LOG_STATUS:
- {
- char name[32 + 2];
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO
- "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS,
- NULL);
- cx2341x_log_status(&dev->mpeg_params, name);
- printk(KERN_INFO
- "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
- }
- case VIDIOC_QUERYMENU:
- return cx23885_querymenu(dev, arg);
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *c = arg;
+ 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->ts1.ts_packet_size * dev->ts1.ts_packet_count;
+ f->fmt.pix.colorspace = 0;
+ dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
+ f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
+ return 0;
+}
- return cx23885_queryctrl(dev, c);
- }
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *p)
+{
+ struct cx23885_fh *fh = file->private_data;
- default:
- return cx23885_do_ioctl(inode, file, 0, dev, cmd, arg,
- mpeg_do_ioctl);
+ return videobuf_reqbufs(&fh->mpegq, p);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+{
+ struct cx23885_fh *fh = file->private_data;
+
+ return videobuf_querybuf(&fh->mpegq, p);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+{
+ struct cx23885_fh *fh = file->private_data;
+
+ return videobuf_qbuf(&fh->mpegq, p);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct cx23885_fh *fh = priv;
+
+ return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK);
+}
+
+
+static int vidioc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type i)
+{
+ struct cx23885_fh *fh = file->private_data;
+
+ return videobuf_streamon(&fh->mpegq);
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ struct cx23885_fh *fh = file->private_data;
+
+ return videobuf_streamoff(&fh->mpegq);
+}
+
+static int vidioc_g_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *f)
+{
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+
+ if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+ return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS);
+}
+
+static int vidioc_s_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *f)
+{
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+ struct cx2341x_mpeg_params p;
+ int err;
+
+ if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+
+ p = dev->mpeg_params;
+ err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
+
+ if (err == 0) {
+ err = cx2341x_update(dev, cx23885_mbox_func,
+ &dev->mpeg_params, &p);
+ dev->mpeg_params = p;
}
+ return err;
+}
+
+static int vidioc_try_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *f)
+{
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+ struct cx2341x_mpeg_params p;
+ int err;
+
+ if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+
+ p = dev->mpeg_params;
+ err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
+ return err;
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+ char name[32 + 2];
+
+ snprintf(name, sizeof(name), "%s/2", dev->name);
+ printk(KERN_INFO
+ "%s/2: ============ START LOG STATUS ============\n",
+ dev->name);
+ cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS,
+ NULL);
+ cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS,
+ NULL);
+ cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS,
+ NULL);
+ cx2341x_log_status(&dev->mpeg_params, name);
+ printk(KERN_INFO
+ "%s/2: ============= END LOG STATUS =============\n",
+ dev->name);
return 0;
}
-static int mpeg_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_querymenu(struct file *file, void *priv,
+ struct v4l2_querymenu *a)
+{
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+
+ return cx23885_querymenu(dev, a);
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *c)
{
- return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl);
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+
+ return cx23885_queryctrl(dev, c);
}
static int mpeg_open(struct inode *inode, struct file *file)
@@ -1670,7 +1695,7 @@ static struct file_operations mpeg_fops = {
.read = mpeg_read,
.poll = mpeg_poll,
.mmap = mpeg_mmap,
- .ioctl = mpeg_ioctl,
+ .ioctl = video_ioctl2,
.llseek = no_llseek,
};
@@ -1682,6 +1707,32 @@ static struct video_device cx23885_mpeg_template = {
VID_TYPE_MPEG_ENCODER,
.fops = &mpeg_fops,
.minor = -1,
+ .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_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .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_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_ext_ctrls = vidioc_g_ext_ctrls,
+ .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
+ .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
+ .vidioc_log_status = vidioc_log_status,
+ .vidioc_querymenu = vidioc_querymenu,
+ .vidioc_queryctrl = vidioc_queryctrl,
};
void cx23885_417_unregister(struct cx23885_dev *dev)
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 20e05f23054..fd7112c11d3 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -143,6 +143,10 @@ struct cx23885_board cx23885_boards[] = {
.name = "Hauppauge WinTV-HVR1400",
.portc = CX23885_MPEG_DVB,
},
+ [CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = {
+ .name = "DViCO FusionHDTV7 Dual Express",
+ .portc = CX23885_MPEG_DVB,
+ },
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -210,6 +214,10 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x0070,
.subdevice = 0x8010,
.card = CX23885_BOARD_HAUPPAUGE_HVR1400,
+ },{
+ .subvendor = 0x18ac,
+ .subdevice = 0xd618,
+ .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -477,6 +485,11 @@ void cx23885_card_setup(struct cx23885_dev *dev)
}
switch (dev->board) {
+ case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
+ ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
+ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ /* break omitted intentionally */
case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index c4cc2f3b887..d17343ea0d3 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -291,9 +291,9 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
lines = 6;
BUG_ON(lines < 2);
- cx_write(8 + 0, cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC) );
- cx_write(8 + 4, cpu_to_le32(8) );
- cx_write(8 + 8, cpu_to_le32(0) );
+ cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+ cx_write(8 + 4, 8);
+ cx_write(8 + 8, 0);
/* write CDT */
for (i = 0; i < lines; i++) {
@@ -408,11 +408,11 @@ static void cx23885_risc_disasm(struct cx23885_tsport *port,
dev->name, risc->cpu, (unsigned long)risc->dma);
for (i = 0; i < (risc->size >> 2); i += n) {
printk("%s: %04d: ", dev->name, i);
- n = cx23885_risc_decode(risc->cpu[i]);
+ n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i]));
for (j = 1; j < n; j++)
printk("%s: %04d: 0x%08x [ arg #%d ]\n",
dev->name, i + j, risc->cpu[i + j], j);
- if (risc->cpu[i] == RISC_JUMP)
+ if (risc->cpu[i] == cpu_to_le32(RISC_JUMP))
break;
}
}
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 022aa391937..0a2e6558cd6 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -31,6 +31,7 @@
#include <media/v4l2-common.h>
#include "s5h1409.h"
+#include "s5h1411.h"
#include "mt2131.h"
#include "tda8290.h"
#include "tda18271.h"
@@ -164,12 +165,38 @@ static struct s5h1409_config hauppauge_hvr1500q_config = {
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
};
+static struct s5h1409_config dvico_s5h1409_config = {
+ .demod_address = 0x32 >> 1,
+ .output_mode = S5H1409_SERIAL_OUTPUT,
+ .gpio = S5H1409_GPIO_ON,
+ .qam_if = 44000,
+ .inversion = S5H1409_INVERSION_OFF,
+ .status_mode = S5H1409_DEMODLOCKING,
+ .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
+};
+
+static struct s5h1411_config dvico_s5h1411_config = {
+ .output_mode = S5H1411_SERIAL_OUTPUT,
+ .gpio = S5H1411_GPIO_ON,
+ .qam_if = S5H1411_IF_44000,
+ .vsb_if = S5H1411_IF_44000,
+ .inversion = S5H1411_INVERSION_OFF,
+ .status_mode = S5H1411_DEMODLOCKING,
+ .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
+};
+
static struct xc5000_config hauppauge_hvr1500q_tunerconfig = {
.i2c_address = 0x61,
.if_khz = 5380,
.tuner_callback = cx23885_tuner_callback
};
+static struct xc5000_config dvico_xc5000_tunerconfig = {
+ .i2c_address = 0x64,
+ .if_khz = 5380,
+ .tuner_callback = cx23885_tuner_callback
+};
+
static struct tda829x_config tda829x_no_probe = {
.probe_tuner = TDA829X_DONT_PROBE,
};
@@ -453,6 +480,21 @@ static int dvb_register(struct cx23885_tsport *port)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
break;
+ case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
+ i2c_bus = &dev->i2c_bus[port->nr - 1];
+
+ port->dvb.frontend = dvb_attach(s5h1409_attach,
+ &dvico_s5h1409_config,
+ &i2c_bus->i2c_adap);
+ if (port->dvb.frontend == NULL)
+ port->dvb.frontend = dvb_attach(s5h1411_attach,
+ &dvico_s5h1411_config,
+ &i2c_bus->i2c_adap);
+ if (port->dvb.frontend != NULL)
+ dvb_attach(xc5000_attach, port->dvb.frontend,
+ &i2c_bus->i2c_adap,
+ &dvico_xc5000_tunerconfig, i2c_bus);
+ break;
default:
printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
dev->name);
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 84652210a28..043fc4e5c58 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -915,7 +915,7 @@ static void init_controls(struct cx23885_dev *dev)
/* ------------------------------------------------------------------ */
/* VIDEO IOCTLS */
-static int vidioc_g_fmt_cap(struct file *file, void *priv,
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx23885_fh *fh = priv;
@@ -932,7 +932,7 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_try_fmt_cap(struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
@@ -983,7 +983,7 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_s_fmt_cap(struct file *file, void *priv,
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx23885_fh *fh = priv;
@@ -991,7 +991,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv,
int err;
dprintk(2, "%s()\n", __func__);
- err = vidioc_try_fmt_cap(file, priv, f);
+ err = vidioc_try_fmt_vid_cap(file, priv, f);
if (0 != err)
return err;
@@ -1025,7 +1025,7 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt_cap(struct file *file, void *priv,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (unlikely(f->index >= ARRAY_SIZE(formats)))
@@ -1440,13 +1440,13 @@ static struct video_device cx23885_video_template = {
.fops = &video_fops,
.minor = -1,
.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_g_fmt_vbi = cx23885_vbi_fmt,
- .vidioc_try_fmt_vbi = cx23885_vbi_fmt,
- .vidioc_s_fmt_vbi = cx23885_vbi_fmt,
+ .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,
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 32af87f25e7..00dfdc89d64 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -63,6 +63,7 @@
#define CX23885_BOARD_HAUPPAUGE_HVR1200 7
#define CX23885_BOARD_HAUPPAUGE_HVR1700 8
#define CX23885_BOARD_HAUPPAUGE_HVR1400 9
+#define CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP 10
/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
#define CX23885_NORMS (\