diff options
Diffstat (limited to 'drivers/media/video/cx23885')
-rw-r--r-- | drivers/media/video/cx23885/Kconfig | 4 | ||||
-rw-r--r-- | drivers/media/video/cx23885/cx23885-417.c | 714 | ||||
-rw-r--r-- | drivers/media/video/cx23885/cx23885-cards.c | 69 | ||||
-rw-r--r-- | drivers/media/video/cx23885/cx23885-core.c | 161 | ||||
-rw-r--r-- | drivers/media/video/cx23885/cx23885-dvb.c | 44 | ||||
-rw-r--r-- | drivers/media/video/cx23885/cx23885-i2c.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx23885/cx23885-reg.h | 2 | ||||
-rw-r--r-- | drivers/media/video/cx23885/cx23885-vbi.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx23885/cx23885-video.c | 47 | ||||
-rw-r--r-- | drivers/media/video/cx23885/cx23885.h | 3 |
10 files changed, 660 insertions, 388 deletions
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index 7bf14c9a15c..e60bd31b51a 100644 --- a/drivers/media/video/cx23885/Kconfig +++ b/drivers/media/video/cx23885/Kconfig @@ -1,19 +1,19 @@ config VIDEO_CX23885 tristate "Conexant cx23885 (2388x successor) support" depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT - depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT - select FW_LOADER select VIDEO_BTCX select VIDEO_TUNER 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..7b0e8c01692 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -4,7 +4,7 @@ * * (c) 2004 Jelle Foks <jelle@foks.8m.com> * (c) 2004 Gerd Knorr <kraxel@bytesex.org> - * (c) 2008 Steven Toth <stoth@hauppauge.com> + * (c) 2008 Steven Toth <stoth@linuxtv.org> * - CX23885/7/8 support * * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/), @@ -32,6 +32,7 @@ #include <linux/device.h> #include <linux/firmware.h> #include <media/v4l2-common.h> +#include <media/v4l2-ioctl.h> #include <media/cx2341x.h> #include "cx23885.h" @@ -1173,379 +1174,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 mpeg_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +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 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,17 +1696,43 @@ static struct file_operations mpeg_fops = { .read = mpeg_read, .poll = mpeg_poll, .mmap = mpeg_mmap, - .ioctl = mpeg_ioctl, + .ioctl = video_ioctl2, .llseek = no_llseek, }; +static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { + .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, +}; + static struct video_device cx23885_mpeg_template = { .name = "cx23885", - .type = VID_TYPE_CAPTURE | - VID_TYPE_TUNER | - VID_TYPE_SCALES | - VID_TYPE_MPEG_ENCODER, .fops = &mpeg_fops, + .ioctl_ops = &mpeg_ioctl_ops, .minor = -1, }; @@ -1715,7 +1767,7 @@ static struct video_device *cx23885_video_dev_alloc( vfd->minor = -1; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, cx23885_boards[tsport->dev->board].name); - vfd->dev = &pci->dev; + vfd->parent = &pci->dev; vfd->release = video_device_release; return vfd; } diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 20e05f23054..c36d3f63210 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -1,7 +1,7 @@ /* * Driver for the Conexant CX23885 PCIe bridge * - * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> + * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -143,6 +143,11 @@ 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", + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -210,6 +215,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); @@ -317,25 +326,41 @@ int cx23885_tuner_callback(void *priv, int command, int arg) { struct cx23885_i2c *bus = priv; struct cx23885_dev *dev = bus->dev; + u32 bitmask = 0; + + if (command != 0) { + printk(KERN_ERR "%s(): Unknown command 0x%x.\n", + __func__, command); + return -EINVAL; + } switch(dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - if(command == 0) { /* Tuner Reset Command from xc5000 */ - /* Drive the tuner into reset and out */ - cx_clear(GP0_IO, 0x00000004); - mdelay(200); - cx_set(GP0_IO, 0x00000004); - return 0; - } - else { - printk(KERN_ERR - "%s(): Unknow command.\n", __func__); - return -EINVAL; + /* Tuner Reset Command from xc5000 */ + if (command == 0) + bitmask = 0x04; + break; + case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: + if (command == 0) { + + /* Two identical tuners on two different i2c buses, + * we need to reset the correct gpio. */ + if (bus->nr == 0) + bitmask = 0x01; + else if (bus->nr == 1) + bitmask = 0x04; } break; } - return 0; /* Should never be here */ + if (bitmask) { + /* Drive the tuner into reset and back out */ + cx_clear(GP0_IO, bitmask); + mdelay(200); + cx_set(GP0_IO, bitmask); + } + + return 0; } void cx23885_gpio_setup(struct cx23885_dev *dev) @@ -427,6 +452,19 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) mdelay(20); cx_set(GP0_IO, 0x00050005); break; + case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: + /* GPIO-0 xc5000 tuner reset i2c bus 0 */ + /* GPIO-1 s5h1409 demod reset i2c bus 0 */ + /* GPIO-2 xc5000 tuner reset i2c bus 1 */ + /* GPIO-3 s5h1409 demod reset i2c bus 0 */ + + /* Put the parts into reset and back */ + cx_set(GP0_IO, 0x000f0000); + mdelay(20); + cx_clear(GP0_IO, 0x0000000f); + mdelay(20); + cx_set(GP0_IO, 0x000f000f); + break; } } @@ -477,6 +515,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..25fb0993874 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -1,7 +1,7 @@ /* * Driver for the Conexant CX23885 PCIe bridge * - * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> + * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ #include "cx23885.h" MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); -MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); +MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); MODULE_LICENSE("GPL"); static unsigned int debug; @@ -76,6 +76,117 @@ LIST_HEAD(cx23885_devlist); * 0x00010ea0 0x00010xxx Free */ +static struct sram_channel cx23885_sram_channels[] = { + [SRAM_CH01] = { + .name = "VID A", + .cmds_start = 0x10000, + .ctrl_start = 0x10380, + .cdt = 0x104c0, + .fifo_start = 0x40, + .fifo_size = 0x2800, + .ptr1_reg = DMA1_PTR1, + .ptr2_reg = DMA1_PTR2, + .cnt1_reg = DMA1_CNT1, + .cnt2_reg = DMA1_CNT2, + }, + [SRAM_CH02] = { + .name = "ch2", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA2_PTR1, + .ptr2_reg = DMA2_PTR2, + .cnt1_reg = DMA2_CNT1, + .cnt2_reg = DMA2_CNT2, + }, + [SRAM_CH03] = { + .name = "TS1 B", + .cmds_start = 0x100A0, + .ctrl_start = 0x10400, + .cdt = 0x10580, + .fifo_start = 0x5000, + .fifo_size = 0x1000, + .ptr1_reg = DMA3_PTR1, + .ptr2_reg = DMA3_PTR2, + .cnt1_reg = DMA3_CNT1, + .cnt2_reg = DMA3_CNT2, + }, + [SRAM_CH04] = { + .name = "ch4", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA4_PTR1, + .ptr2_reg = DMA4_PTR2, + .cnt1_reg = DMA4_CNT1, + .cnt2_reg = DMA4_CNT2, + }, + [SRAM_CH05] = { + .name = "ch5", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA5_PTR1, + .ptr2_reg = DMA5_PTR2, + .cnt1_reg = DMA5_CNT1, + .cnt2_reg = DMA5_CNT2, + }, + [SRAM_CH06] = { + .name = "TS2 C", + .cmds_start = 0x10140, + .ctrl_start = 0x10440, + .cdt = 0x105e0, + .fifo_start = 0x6000, + .fifo_size = 0x1000, + .ptr1_reg = DMA5_PTR1, + .ptr2_reg = DMA5_PTR2, + .cnt1_reg = DMA5_CNT1, + .cnt2_reg = DMA5_CNT2, + }, + [SRAM_CH07] = { + .name = "ch7", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA6_PTR1, + .ptr2_reg = DMA6_PTR2, + .cnt1_reg = DMA6_CNT1, + .cnt2_reg = DMA6_CNT2, + }, + [SRAM_CH08] = { + .name = "ch8", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA7_PTR1, + .ptr2_reg = DMA7_PTR2, + .cnt1_reg = DMA7_CNT1, + .cnt2_reg = DMA7_CNT2, + }, + [SRAM_CH09] = { + .name = "ch9", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA8_PTR1, + .ptr2_reg = DMA8_PTR2, + .cnt1_reg = DMA8_CNT1, + .cnt2_reg = DMA8_CNT2, + }, +}; + static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH01] = { .name = "VID A", @@ -104,8 +215,8 @@ static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH03] = { .name = "TS1 B", .cmds_start = 0x100A0, - .ctrl_start = 0x10780, - .cdt = 0x10400, + .ctrl_start = 0x10630, + .cdt = 0x10870, .fifo_start = 0x5000, .fifo_size = 0x1000, .ptr1_reg = DMA3_PTR1, @@ -140,7 +251,7 @@ static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH06] = { .name = "TS2 C", .cmds_start = 0x10140, - .ctrl_start = 0x10680, + .ctrl_start = 0x10670, .cdt = 0x108d0, .fifo_start = 0x6000, .fifo_size = 0x1000, @@ -291,9 +402,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 +519,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; } } @@ -460,6 +571,7 @@ static void cx23885_reset(struct cx23885_dev *dev) cx_write(AUDIO_INT_INT_STAT, 0xffffffff); cx_write(AUDIO_EXT_INT_STAT, 0xffffffff); cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000); + cx_write(PAD_CTRL, 0x00500300); mdelay(100); @@ -625,7 +737,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) atomic_inc(&dev->refcount); dev->nr = cx23885_devcount++; - dev->sram_channels = cx23887_sram_channels; sprintf(dev->name, "cx23885[%d]", dev->nr); mutex_lock(&devlist); @@ -637,11 +748,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) dev->bridge = CX23885_BRIDGE_887; /* Apply a sensible clock frequency for the PCIe bridge */ dev->clk_freq = 25000000; + dev->sram_channels = cx23887_sram_channels; } else if(dev->pci->device == 0x8852) { dev->bridge = CX23885_BRIDGE_885; /* Apply a sensible clock frequency for the PCIe bridge */ dev->clk_freq = 28000000; + dev->sram_channels = cx23885_sram_channels; } else BUG(); @@ -1010,8 +1123,9 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl)); dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __func__, port->reg_dma_ctl, cx_read(port->reg_dma_ctl)); - dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, - port->reg_src_sel, cx_read(port->reg_src_sel)); + if (port->reg_src_sel) + dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, + port->reg_src_sel, cx_read(port->reg_src_sel)); dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __func__, port->reg_lngth, cx_read(port->reg_lngth)); dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __func__, @@ -1042,6 +1156,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port, dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, buf->vb.width, buf->vb.height, buf->vb.field); + /* Stop the fifo and risc engine for this port */ + cx_clear(port->reg_dma_ctl, port->dma_ctl_val); + /* setup fifo + format */ cx23885_sram_channel_setup(dev, &dev->sram_channels[ port->sram_chno ], @@ -1083,7 +1200,21 @@ static int cx23885_start_dma(struct cx23885_tsport *port, cx_write(port->reg_gpcnt_ctl, 3); q->count = 1; - if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) { + /* Set VIDB pins to input */ + if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { + reg = cx_read(PAD_CTRL); + reg &= ~0x3; /* Clear TS1_OE & TS1_SOP_OE */ + cx_write(PAD_CTRL, reg); + } + + /* Set VIDC pins to input */ + if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { + reg = cx_read(PAD_CTRL); + reg &= ~0x4; /* Clear TS2_SOP_OE */ + cx_write(PAD_CTRL, reg); + } + + if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { reg = cx_read(PAD_CTRL); reg = reg & ~0x1; /* Clear TS1_OE */ @@ -1133,7 +1264,7 @@ static int cx23885_stop_dma(struct cx23885_tsport *port) cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) { + if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { reg = cx_read(PAD_CTRL); diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 022aa391937..291b9d008da 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -1,7 +1,7 @@ /* * Driver for the Conexant CX23885 PCIe bridge * - * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> + * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index c6bb0a05bc1..f98e476e961 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c @@ -1,7 +1,7 @@ /* * Driver for the Conexant CX23885 PCIe bridge * - * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> + * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h index bdd11bc513a..20b68a23626 100644 --- a/drivers/media/video/cx23885/cx23885-reg.h +++ b/drivers/media/video/cx23885/cx23885-reg.h @@ -1,7 +1,7 @@ /* * Driver for the Conexant CX23885 PCIe bridge * - * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> + * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx23885/cx23885-vbi.c b/drivers/media/video/cx23885/cx23885-vbi.c index e36e3fcae2f..35e61cd112f 100644 --- a/drivers/media/video/cx23885/cx23885-vbi.c +++ b/drivers/media/video/cx23885/cx23885-vbi.c @@ -1,7 +1,7 @@ /* * Driver for the Conexant CX23885 PCIe bridge * - * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> + * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 84652210a28..6047c78d84b 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -1,7 +1,7 @@ /* * Driver for the Conexant CX23885 PCIe bridge * - * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> + * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +33,7 @@ #include "cx23885.h" #include <media/v4l2-common.h> +#include <media/v4l2-ioctl.h> #ifdef CONFIG_VIDEO_V4L1_COMPAT /* Include V4L1 specific functions. Should be removed soon */ @@ -40,7 +41,7 @@ #endif MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); -MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); +MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); MODULE_LICENSE("GPL"); /* ------------------------------------------------------------------ */ @@ -326,7 +327,7 @@ struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, return NULL; *vfd = *template; vfd->minor = -1; - vfd->dev = &pci->dev; + vfd->parent = &pci->dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, cx23885_boards[dev->board].name); @@ -915,7 +916,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 +933,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 +984,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 +992,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 +1026,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))) @@ -1433,20 +1434,15 @@ static const struct file_operations video_fops = { .llseek = no_llseek, }; -static struct video_device cx23885_vbi_template; -static struct video_device cx23885_video_template = { - .name = "cx23885-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, - .fops = &video_fops, - .minor = -1, +static const struct v4l2_ioctl_ops video_ioctl_ops = { .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, @@ -1471,6 +1467,14 @@ static struct video_device cx23885_video_template = { .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, }; @@ -1512,7 +1516,6 @@ int cx23885_video_register(struct cx23885_dev *dev) memcpy(&cx23885_vbi_template, &cx23885_video_template, sizeof(cx23885_vbi_template)); strcpy(cx23885_vbi_template.name, "cx23885-vbi"); - cx23885_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER; dev->tvnorm = cx23885_video_template.current_norm; diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 32af87f25e7..e23d97c071e 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -1,7 +1,7 @@ /* * Driver for the Conexant CX23885 PCIe bridge * - * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> + * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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 (\ |