diff options
author | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-21 06:12:35 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-21 06:12:35 -0300 |
commit | 676ee36be04985062522804c2de04f0764212be6 (patch) | |
tree | 781df135c5a91a04decad1b7d53b5a925dc11522 /drivers/media/pci | |
parent | b18042a673e88c9457a6d1716219c2367ca447b0 (diff) | |
parent | e183201b9e917daf2530b637b2f34f1d5afb934d (diff) | |
download | linux-676ee36be04985062522804c2de04f0764212be6.tar.gz linux-676ee36be04985062522804c2de04f0764212be6.tar.bz2 linux-676ee36be04985062522804c2de04f0764212be6.zip |
Merge branch 'patchwork' into v4l_for_linus
* patchwork: (404 commits)
[media] uvcvideo: add support for VIDIOC_QUERY_EXT_CTRL
[media] uvcvideo: fix cropcap v4l2-compliance failure
[media] media: omap3isp: remove unused clkdev
[media] coda: Add tracing support
[media] coda: drop dma_sync_single_for_device in coda_bitstream_queue
[media] coda: fix fill bitstream errors in nonstreaming case
[media] coda: call SEQ_END when the first queue is stopped
[media] coda: fail to start streaming if userspace set invalid formats
[media] coda: remove duplicate error messages for buffer allocations
[media] coda: move parameter buffer in together with context buffer allocation
[media] coda: allocate bitstream buffer from REQBUFS, size depends on the format
[media] coda: allocate per-context buffers from REQBUFS
[media] coda: use strlcpy instead of snprintf
[media] coda: bitstream payload is unsigned
[media] coda: fix double call to debugfs_remove
[media] coda: check kasprintf return value in coda_open
[media] coda: bitrate can only be set in kbps steps
[media] v4l2-mem2mem: no need to initialize b in v4l2_m2m_next_buf and v4l2_m2m_buf_remove
[media] s5p-mfc: set allow_zero_bytesused flag for vb2_queue_init
[media] coda: set allow_zero_bytesused flag for vb2_queue_init
...
Diffstat (limited to 'drivers/media/pci')
39 files changed, 365 insertions, 415 deletions
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 4ec2a3c3f23c..bc12060e0882 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -2474,7 +2474,7 @@ static int bttv_querycap(struct file *file, void *priv, return -EINVAL; strlcpy(cap->driver, "bttv", sizeof(cap->driver)); - strlcpy(cap->card, btv->video_dev->name, sizeof(cap->card)); + strlcpy(cap->card, btv->video_dev.name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", pci_name(btv->c.pci)); cap->capabilities = @@ -2484,9 +2484,9 @@ static int bttv_querycap(struct file *file, void *priv, V4L2_CAP_DEVICE_CAPS; if (no_overlay <= 0) cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; - if (btv->vbi_dev) + if (video_is_registered(&btv->vbi_dev)) cap->capabilities |= V4L2_CAP_VBI_CAPTURE; - if (btv->radio_dev) + if (video_is_registered(&btv->radio_dev)) cap->capabilities |= V4L2_CAP_RADIO; /* @@ -3905,18 +3905,14 @@ static irqreturn_t bttv_irq(int irq, void *dev_id) /* ----------------------------------------------------------------------- */ /* initialization */ -static struct video_device *vdev_init(struct bttv *btv, - const struct video_device *template, - const char *type_name) +static void vdev_init(struct bttv *btv, + struct video_device *vfd, + const struct video_device *template, + const char *type_name) { - struct video_device *vfd; - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; *vfd = *template; vfd->v4l2_dev = &btv->c.v4l2_dev; - vfd->release = video_device_release; + vfd->release = video_device_release_empty; video_set_drvdata(vfd, btv); snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", @@ -3927,32 +3923,13 @@ static struct video_device *vdev_init(struct bttv *btv, v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); } - return vfd; } static void bttv_unregister_video(struct bttv *btv) { - if (btv->video_dev) { - if (video_is_registered(btv->video_dev)) - video_unregister_device(btv->video_dev); - else - video_device_release(btv->video_dev); - btv->video_dev = NULL; - } - if (btv->vbi_dev) { - if (video_is_registered(btv->vbi_dev)) - video_unregister_device(btv->vbi_dev); - else - video_device_release(btv->vbi_dev); - btv->vbi_dev = NULL; - } - if (btv->radio_dev) { - if (video_is_registered(btv->radio_dev)) - video_unregister_device(btv->radio_dev); - else - video_device_release(btv->radio_dev); - btv->radio_dev = NULL; - } + video_unregister_device(&btv->video_dev); + video_unregister_device(&btv->vbi_dev); + video_unregister_device(&btv->radio_dev); } /* register video4linux devices */ @@ -3962,44 +3939,38 @@ static int bttv_register_video(struct bttv *btv) pr_notice("Overlay support disabled\n"); /* video */ - btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); + vdev_init(btv, &btv->video_dev, &bttv_video_template, "video"); - if (NULL == btv->video_dev) - goto err; - if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER, + if (video_register_device(&btv->video_dev, VFL_TYPE_GRABBER, video_nr[btv->c.nr]) < 0) goto err; pr_info("%d: registered device %s\n", - btv->c.nr, video_device_node_name(btv->video_dev)); - if (device_create_file(&btv->video_dev->dev, + btv->c.nr, video_device_node_name(&btv->video_dev)); + if (device_create_file(&btv->video_dev.dev, &dev_attr_card)<0) { pr_err("%d: device_create_file 'card' failed\n", btv->c.nr); goto err; } /* vbi */ - btv->vbi_dev = vdev_init(btv, &bttv_video_template, "vbi"); + vdev_init(btv, &btv->vbi_dev, &bttv_video_template, "vbi"); - if (NULL == btv->vbi_dev) - goto err; - if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI, + if (video_register_device(&btv->vbi_dev, VFL_TYPE_VBI, vbi_nr[btv->c.nr]) < 0) goto err; pr_info("%d: registered device %s\n", - btv->c.nr, video_device_node_name(btv->vbi_dev)); + btv->c.nr, video_device_node_name(&btv->vbi_dev)); if (!btv->has_radio) return 0; /* radio */ - btv->radio_dev = vdev_init(btv, &radio_template, "radio"); - if (NULL == btv->radio_dev) - goto err; - btv->radio_dev->ctrl_handler = &btv->radio_ctrl_handler; - if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO, + vdev_init(btv, &btv->radio_dev, &radio_template, "radio"); + btv->radio_dev.ctrl_handler = &btv->radio_ctrl_handler; + if (video_register_device(&btv->radio_dev, VFL_TYPE_RADIO, radio_nr[btv->c.nr]) < 0) goto err; pr_info("%d: registered device %s\n", - btv->c.nr, video_device_node_name(btv->radio_dev)); + btv->c.nr, video_device_node_name(&btv->radio_dev)); /* all done */ return 0; diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index bc048c586b1f..a444cfb35c0b 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -404,9 +404,9 @@ struct bttv { struct v4l2_subdev *sd_tda7432; /* video4linux (1) */ - struct video_device *video_dev; - struct video_device *radio_dev; - struct video_device *vbi_dev; + struct video_device video_dev; + struct video_device radio_dev; + struct video_device vbi_dev; /* controls */ struct v4l2_ctrl_handler ctrl_handler; diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c index ea272bcb38df..0b0e8015ad34 100644 --- a/drivers/media/pci/cx18/cx18-alsa-main.c +++ b/drivers/media/pci/cx18/cx18-alsa-main.c @@ -216,7 +216,7 @@ static int cx18_alsa_load(struct cx18 *cx) } s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM]; - if (s->video_dev == NULL) { + if (s->video_dev.v4l2_dev == NULL) { CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - " "skipping\n", __func__); return 0; diff --git a/drivers/media/pci/cx18/cx18-driver.h b/drivers/media/pci/cx18/cx18-driver.h index 207d6e82403b..b15beed2dc14 100644 --- a/drivers/media/pci/cx18/cx18-driver.h +++ b/drivers/media/pci/cx18/cx18-driver.h @@ -373,7 +373,7 @@ struct cx18_in_work_order { struct cx18_stream { /* These first five fields are always set, even if the stream is not actually created. */ - struct video_device *video_dev; /* NULL when stream not created */ + struct video_device video_dev; /* v4l2_dev is NULL when stream not created */ struct cx18_dvb *dvb; /* DVB / Digital Transport */ struct cx18 *cx; /* for ease of use */ const char *name; /* name of the stream */ @@ -409,6 +409,7 @@ struct cx18_stream { /* Videobuf for YUV video */ u32 pixelformat; u32 vb_bytes_per_frame; + u32 vb_bytes_per_line; struct list_head vb_capture; /* video capture queue */ spinlock_t vb_lock; struct timer_list vb_timeout; diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c index 76a3b4ac541e..df837408efd5 100644 --- a/drivers/media/pci/cx18/cx18-fileops.c +++ b/drivers/media/pci/cx18/cx18-fileops.c @@ -34,6 +34,7 @@ #include "cx18-controls.h" #include "cx18-ioctl.h" #include "cx18-cards.h" +#include <media/v4l2-event.h> /* This function tries to claim the stream for a specific file descriptor. If no one else is using this stream then the stream is claimed and @@ -609,13 +610,16 @@ ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) { + unsigned long req_events = poll_requested_events(wait); struct cx18_open_id *id = file2id(filp); struct cx18 *cx = id->cx; struct cx18_stream *s = &cx->streams[id->type]; int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags); + unsigned res = 0; /* Start a capture if there is none */ - if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) { + if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags) && + (req_events & (POLLIN | POLLRDNORM))) { int rc; mutex_lock(&cx->serialize_lock); @@ -632,21 +636,26 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && (id->type == CX18_ENC_STREAM_TYPE_YUV)) { int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait); + + if (v4l2_event_pending(&id->fh)) + res |= POLLPRI; if (eof && videobuf_poll == POLLERR) - return POLLHUP; - else - return videobuf_poll; + return res | POLLHUP; + return res | videobuf_poll; } /* add stream's waitq to the poll list */ CX18_DEBUG_HI_FILE("Encoder poll\n"); - poll_wait(filp, &s->waitq, wait); + if (v4l2_event_pending(&id->fh)) + res |= POLLPRI; + else + poll_wait(filp, &s->waitq, wait); if (atomic_read(&s->q_full.depth)) - return POLLIN | POLLRDNORM; + return res | POLLIN | POLLRDNORM; if (eof) - return POLLHUP; - return 0; + return res | POLLHUP; + return res; } int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma) @@ -797,7 +806,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) CX18_DEBUG_WARN("nomem on v4l2 open\n"); return -ENOMEM; } - v4l2_fh_init(&item->fh, s->video_dev); + v4l2_fh_init(&item->fh, &s->video_dev); item->cx = cx; item->type = s->type; diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c index b8e4b68a9196..79aee30d5fd8 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.c +++ b/drivers/media/pci/cx18/cx18-ioctl.c @@ -39,6 +39,7 @@ #include "cx18-cards.h" #include "cx18-av-core.h" #include <media/tveeprom.h> +#include <media/v4l2-event.h> u16 cx18_service2vbi(int type) { @@ -159,7 +160,7 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh, if (id->type == CX18_ENC_STREAM_TYPE_YUV) { pixfmt->pixelformat = s->pixelformat; pixfmt->sizeimage = s->vb_bytes_per_frame; - pixfmt->bytesperline = 720; + pixfmt->bytesperline = s->vb_bytes_per_line; } else { pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; pixfmt->sizeimage = 128 * 1024; @@ -287,10 +288,13 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, s->pixelformat = fmt->fmt.pix.pixelformat; /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2))) UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */ - if (s->pixelformat == V4L2_PIX_FMT_HM12) + if (s->pixelformat == V4L2_PIX_FMT_HM12) { s->vb_bytes_per_frame = h * 720 * 3 / 2; - else + s->vb_bytes_per_line = 720; /* First plane */ + } else { s->vb_bytes_per_frame = h * 720 * 2; + s->vb_bytes_per_line = 1440; /* Packed */ + } mbus_fmt.width = cx->cxhdl.width = w; mbus_fmt.height = cx->cxhdl.height = h; @@ -447,34 +451,29 @@ static int cx18_cropcap(struct file *file, void *fh, if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - cropcap->bounds.top = cropcap->bounds.left = 0; - cropcap->bounds.width = 720; - cropcap->bounds.height = cx->is_50hz ? 576 : 480; cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10; cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11; - cropcap->defrect = cropcap->bounds; return 0; } -static int cx18_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop) -{ - struct cx18_open_id *id = fh2id(fh); - struct cx18 *cx = id->cx; - - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n"); - return -EINVAL; -} - -static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) +static int cx18_g_selection(struct file *file, void *fh, + struct v4l2_selection *sel) { struct cx18 *cx = fh2id(fh)->cx; - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n"); - return -EINVAL; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.top = sel->r.left = 0; + sel->r.width = 720; + sel->r.height = cx->is_50hz ? 576 : 480; + break; + default: + return -EINVAL; + } + return 0; } static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, @@ -510,6 +509,9 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp) { struct cx18_open_id *id = fh2id(fh); struct cx18 *cx = id->cx; + v4l2_std_id std = V4L2_STD_ALL; + const struct cx18_card_video_input *card_input = + cx->card->video_inputs + inp; if (inp >= cx->nof_inputs) return -EINVAL; @@ -525,6 +527,11 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp) cx->active_input = inp; /* Set the audio input to whatever is appropriate for the input type. */ cx->audio_input = cx->card->video_inputs[inp].audio_index; + if (card_input->video_type == V4L2_INPUT_TYPE_TUNER) + std = cx->tuner_std; + cx->streams[CX18_ENC_STREAM_TYPE_MPG].video_dev.tvnorms = std; + cx->streams[CX18_ENC_STREAM_TYPE_YUV].video_dev.tvnorms = std; + cx->streams[CX18_ENC_STREAM_TYPE_VBI].video_dev.tvnorms = std; /* prevent others from messing with the streams until we're finished changing inputs. */ @@ -1036,7 +1043,7 @@ static int cx18_log_status(struct file *file, void *fh) for (i = 0; i < CX18_MAX_STREAMS; i++) { struct cx18_stream *s = &cx->streams[i]; - if (s->video_dev == NULL || s->buffers == 0) + if (s->video_dev.v4l2_dev == NULL || s->buffers == 0) continue; CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, @@ -1078,8 +1085,7 @@ static const struct v4l2_ioctl_ops cx18_ioctl_ops = { .vidioc_enumaudio = cx18_enumaudio, .vidioc_enum_input = cx18_enum_input, .vidioc_cropcap = cx18_cropcap, - .vidioc_s_crop = cx18_s_crop, - .vidioc_g_crop = cx18_g_crop, + .vidioc_g_selection = cx18_g_selection, .vidioc_g_input = cx18_g_input, .vidioc_s_input = cx18_s_input, .vidioc_g_frequency = cx18_g_frequency, @@ -1114,6 +1120,8 @@ static const struct v4l2_ioctl_ops cx18_ioctl_ops = { .vidioc_querybuf = cx18_querybuf, .vidioc_qbuf = cx18_qbuf, .vidioc_dqbuf = cx18_dqbuf, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; void cx18_set_funcs(struct video_device *vdev) diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c index 369445fcf3e5..c82d25d53341 100644 --- a/drivers/media/pci/cx18/cx18-streams.c +++ b/drivers/media/pci/cx18/cx18-streams.c @@ -254,11 +254,8 @@ static struct videobuf_queue_ops cx18_videobuf_qops = { static void cx18_stream_init(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; - struct video_device *video_dev = s->video_dev; - /* we need to keep video_dev, so restore it afterwards */ memset(s, 0, sizeof(*s)); - s->video_dev = video_dev; /* initialize cx18_stream fields */ s->dvb = NULL; @@ -307,6 +304,7 @@ static void cx18_stream_init(struct cx18 *cx, int type) /* Assume the previous pixel default */ s->pixelformat = V4L2_PIX_FMT_HM12; s->vb_bytes_per_frame = cx->cxhdl.height * 720 * 3 / 2; + s->vb_bytes_per_line = 720; } } @@ -319,12 +317,12 @@ static int cx18_prep_dev(struct cx18 *cx, int type) /* * These five fields are always initialized. - * For analog capture related streams, if video_dev == NULL then the + * For analog capture related streams, if video_dev.v4l2_dev == NULL then the * stream is not in use. * For the TS stream, if dvb == NULL then the stream is not in use. * In those cases no other fields but these four can be used. */ - s->video_dev = NULL; + s->video_dev.v4l2_dev = NULL; s->dvb = NULL; s->cx = cx; s->type = type; @@ -367,24 +365,20 @@ static int cx18_prep_dev(struct cx18 *cx, int type) if (num_offset == -1) return 0; - /* allocate and initialize the v4l2 video device structure */ - s->video_dev = video_device_alloc(); - if (s->video_dev == NULL) { - CX18_ERR("Couldn't allocate v4l2 video_device for %s\n", - s->name); - return -ENOMEM; - } - - snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s", + /* initialize the v4l2 video device structure */ + snprintf(s->video_dev.name, sizeof(s->video_dev.name), "%s %s", cx->v4l2_dev.name, s->name); - s->video_dev->num = num; - s->video_dev->v4l2_dev = &cx->v4l2_dev; - s->video_dev->fops = &cx18_v4l2_enc_fops; - s->video_dev->release = video_device_release; - s->video_dev->tvnorms = V4L2_STD_ALL; - s->video_dev->lock = &cx->serialize_lock; - cx18_set_funcs(s->video_dev); + s->video_dev.num = num; + s->video_dev.v4l2_dev = &cx->v4l2_dev; + s->video_dev.fops = &cx18_v4l2_enc_fops; + s->video_dev.release = video_device_release_empty; + if (cx->card->video_inputs->video_type == CX18_CARD_INPUT_VID_TUNER) + s->video_dev.tvnorms = cx->tuner_std; + else + s->video_dev.tvnorms = V4L2_STD_ALL; + s->video_dev.lock = &cx->serialize_lock; + cx18_set_funcs(&s->video_dev); return 0; } @@ -428,31 +422,30 @@ static int cx18_reg_dev(struct cx18 *cx, int type) } } - if (s->video_dev == NULL) + if (s->video_dev.v4l2_dev == NULL) return 0; - num = s->video_dev->num; + num = s->video_dev.num; /* card number + user defined offset + device offset */ if (type != CX18_ENC_STREAM_TYPE_MPG) { struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; - if (s_mpg->video_dev) - num = s_mpg->video_dev->num + if (s_mpg->video_dev.v4l2_dev) + num = s_mpg->video_dev.num + cx18_stream_info[type].num_offset; } - video_set_drvdata(s->video_dev, s); + video_set_drvdata(&s->video_dev, s); /* Register device. First try the desired minor, then any free one. */ - ret = video_register_device_no_warn(s->video_dev, vfl_type, num); + ret = video_register_device_no_warn(&s->video_dev, vfl_type, num); if (ret < 0) { CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", s->name, num); - video_device_release(s->video_dev); - s->video_dev = NULL; + s->video_dev.v4l2_dev = NULL; return ret; } - name = video_device_node_name(s->video_dev); + name = video_device_node_name(&s->video_dev); switch (vfl_type) { case VFL_TYPE_GRABBER: @@ -542,10 +535,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) } /* If struct video_device exists, can have buffers allocated */ - vdev = cx->streams[type].video_dev; + vdev = &cx->streams[type].video_dev; - cx->streams[type].video_dev = NULL; - if (vdev == NULL) + if (vdev->v4l2_dev == NULL) continue; if (type == CX18_ENC_STREAM_TYPE_YUV) @@ -553,11 +545,7 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) cx18_stream_free(&cx->streams[type]); - /* Unregister or release device */ - if (unregister) - video_unregister_device(vdev); - else - video_device_release(vdev); + video_unregister_device(vdev); } } @@ -1042,7 +1030,7 @@ u32 cx18_find_handle(struct cx18 *cx) for (i = 0; i < CX18_MAX_STREAMS; i++) { struct cx18_stream *s = &cx->streams[i]; - if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE)) + if (s->video_dev.v4l2_dev && (s->handle != CX18_INVALID_TASK_HANDLE)) return s->handle; } return CX18_INVALID_TASK_HANDLE; diff --git a/drivers/media/pci/cx18/cx18-streams.h b/drivers/media/pci/cx18/cx18-streams.h index 713b0e61536d..27f8af9b11cd 100644 --- a/drivers/media/pci/cx18/cx18-streams.h +++ b/drivers/media/pci/cx18/cx18-streams.h @@ -33,7 +33,7 @@ void cx18_stream_rotate_idx_mdls(struct cx18 *cx); static inline bool cx18_stream_enabled(struct cx18_stream *s) { - return s->video_dev || + return s->video_dev.v4l2_dev || (s->dvb && s->dvb->enabled) || (s->type == CX18_ENC_STREAM_TYPE_IDX && s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0); diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig index 74d774e5227b..2e1b88ccdbf2 100644 --- a/drivers/media/pci/cx23885/Kconfig +++ b/drivers/media/pci/cx23885/Kconfig @@ -40,7 +40,6 @@ config VIDEO_CX23885 select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT - select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT ---help--- diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c index 2bbbf545b042..0a91df2c9f08 100644 --- a/drivers/media/pci/cx23885/altera-ci.c +++ b/drivers/media/pci/cx23885/altera-ci.c @@ -483,7 +483,6 @@ static void altera_hw_filt_release(void *main_dev, int filt_nr) } } -EXPORT_SYMBOL(altera_hw_filt_release); void altera_ci_release(void *dev, int ci_nr) { @@ -598,7 +597,6 @@ static int altera_pid_feed_control(void *demux_dev, int filt_nr, return 0; } -EXPORT_SYMBOL(altera_pid_feed_control); static int altera_ci_start_feed(struct dvb_demux_feed *feed, int num) { @@ -699,7 +697,6 @@ err: return ret; } -EXPORT_SYMBOL(altera_hw_filt_init); int altera_ci_init(struct altera_ci_config *config, int ci_nr) { diff --git a/drivers/media/pci/cx23885/altera-ci.h b/drivers/media/pci/cx23885/altera-ci.h index 5028f0cf83f4..6c511723fd1b 100644 --- a/drivers/media/pci/cx23885/altera-ci.h +++ b/drivers/media/pci/cx23885/altera-ci.h @@ -39,7 +39,7 @@ struct altera_ci_config { int (*fpga_rw) (void *dev, int ad_rg, int val, int rw); }; -#if IS_ENABLED(CONFIG_MEDIA_ALTERA_CI) +#if IS_REACHABLE(CONFIG_MEDIA_ALTERA_CI) extern int altera_ci_init(struct altera_ci_config *config, int ci_nr); extern void altera_ci_release(void *dev, int ci_nr); diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 1ad49946d7fa..7aee76af7a85 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -825,6 +825,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) int i; spin_lock_init(&dev->pci_irqmask_lock); + spin_lock_init(&dev->slock); mutex_init(&dev->lock); mutex_init(&dev->gpio_lock); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 45fbe1e4d2d0..745caabe3397 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -73,7 +73,6 @@ #include "si2157.h" #include "sp2.h" #include "m88ds3103.h" -#include "m88ts2022.h" #include "m88rs6000t.h" static unsigned int debug; @@ -1187,7 +1186,7 @@ static int dvb_register(struct cx23885_tsport *port) struct vb2_dvb_frontend *fe0, *fe1 = NULL; struct si2168_config si2168_config; struct si2157_config si2157_config; - struct m88ts2022_config m88ts2022_config; + struct ts2020_config ts2020_config; struct i2c_board_info info; struct i2c_adapter *adapter; struct i2c_client *client_demod = NULL, *client_tuner = NULL; @@ -1856,13 +1855,12 @@ static int dvb_register(struct cx23885_tsport *port) break; /* attach tuner */ - memset(&m88ts2022_config, 0, sizeof(m88ts2022_config)); - m88ts2022_config.fe = fe0->dvb.frontend; - m88ts2022_config.clock = 27000000; + memset(&ts2020_config, 0, sizeof(ts2020_config)); + ts2020_config.fe = fe0->dvb.frontend; memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); + strlcpy(info.type, "ts2020", I2C_NAME_SIZE); info.addr = 0x60; - info.platform_data = &m88ts2022_config; + info.platform_data = &ts2020_config; request_module(info.type); client_tuner = i2c_new_device(adapter, &info); if (client_tuner == NULL || @@ -1986,13 +1984,12 @@ static int dvb_register(struct cx23885_tsport *port) break; /* attach tuner */ - memset(&m88ts2022_config, 0, sizeof(m88ts2022_config)); - m88ts2022_config.fe = fe0->dvb.frontend; - m88ts2022_config.clock = 27000000; + memset(&ts2020_config, 0, sizeof(ts2020_config)); + ts2020_config.fe = fe0->dvb.frontend; memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); + strlcpy(info.type, "ts2020", I2C_NAME_SIZE); info.addr = 0x60; - info.platform_data = &m88ts2022_config; + info.platform_data = &ts2020_config; request_module(info.type); client_tuner = i2c_new_device(adapter, &info); if (client_tuner == NULL || client_tuner->dev.driver == NULL) @@ -2032,13 +2029,12 @@ static int dvb_register(struct cx23885_tsport *port) break; /* attach tuner */ - memset(&m88ts2022_config, 0, sizeof(m88ts2022_config)); - m88ts2022_config.fe = fe0->dvb.frontend; - m88ts2022_config.clock = 27000000; + memset(&ts2020_config, 0, sizeof(ts2020_config)); + ts2020_config.fe = fe0->dvb.frontend; memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); + strlcpy(info.type, "ts2020", I2C_NAME_SIZE); info.addr = 0x60; - info.platform_data = &m88ts2022_config; + info.platform_data = &ts2020_config; request_module(info.type); client_tuner = i2c_new_device(adapter, &info); if (client_tuner == NULL || client_tuner->dev.driver == NULL) diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 5e93c682a3f5..2232b389c441 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -1137,7 +1137,6 @@ int cx23885_video_register(struct cx23885_dev *dev) int err; dprintk(1, "%s()\n", __func__); - spin_lock_init(&dev->slock); /* Initialize VBI template */ cx23885_vbi_template = cx23885_video_template; diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index b6be46e94289..24216efa56e7 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -1102,32 +1102,26 @@ static int cx8802_blackbird_advise_release(struct cx8802_driver *drv) static void blackbird_unregister_video(struct cx8802_dev *dev) { - if (dev->mpeg_dev) { - if (video_is_registered(dev->mpeg_dev)) - video_unregister_device(dev->mpeg_dev); - else - video_device_release(dev->mpeg_dev); - dev->mpeg_dev = NULL; - } + video_unregister_device(&dev->mpeg_dev); } static int blackbird_register_video(struct cx8802_dev *dev) { int err; - dev->mpeg_dev = cx88_vdev_init(dev->core, dev->pci, - &cx8802_mpeg_template, "mpeg"); - dev->mpeg_dev->ctrl_handler = &dev->cxhdl.hdl; - video_set_drvdata(dev->mpeg_dev, dev); - dev->mpeg_dev->queue = &dev->vb2_mpegq; - err = video_register_device(dev->mpeg_dev, VFL_TYPE_GRABBER, -1); + cx88_vdev_init(dev->core, dev->pci, &dev->mpeg_dev, + &cx8802_mpeg_template, "mpeg"); + dev->mpeg_dev.ctrl_handler = &dev->cxhdl.hdl; + video_set_drvdata(&dev->mpeg_dev, dev); + dev->mpeg_dev.queue = &dev->vb2_mpegq; + err = video_register_device(&dev->mpeg_dev, VFL_TYPE_GRABBER, -1); if (err < 0) { printk(KERN_INFO "%s/2: can't register mpeg device\n", dev->core->name); return err; } printk(KERN_INFO "%s/2: registered device %s [mpeg]\n", - dev->core->name, video_device_node_name(dev->mpeg_dev)); + dev->core->name, video_device_node_name(&dev->mpeg_dev)); return 0; } diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index c38d5a12e277..3501be9f19d8 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -985,17 +985,14 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) /* ------------------------------------------------------------------ */ -struct video_device *cx88_vdev_init(struct cx88_core *core, - struct pci_dev *pci, - const struct video_device *template_, - const char *type) +void cx88_vdev_init(struct cx88_core *core, + struct pci_dev *pci, + struct video_device *vfd, + const struct video_device *template_, + const char *type) { - struct video_device *vfd; - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; *vfd = *template_; + /* * The dev pointer of v4l2_device is NULL, instead we set the * video_device dev_parent pointer to the correct PCI bus device. @@ -1004,11 +1001,10 @@ struct video_device *cx88_vdev_init(struct cx88_core *core, */ vfd->v4l2_dev = &core->v4l2_dev; vfd->dev_parent = &pci->dev; - vfd->release = video_device_release; + vfd->release = video_device_release_empty; vfd->lock = &core->lock; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", core->name, type, core->board.name); - return vfd; } struct cx88_core* cx88_core_get(struct pci_dev *pci) diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index a369b0840acf..98344540c51f 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -732,7 +732,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); if (IS_ERR(dev->alloc_ctx)) { err = PTR_ERR(dev->alloc_ctx); - goto fail_core; + goto fail_dev; } dev->core = core; @@ -754,6 +754,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, fail_free: vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); + fail_dev: kfree(dev); fail_core: core->dvbdev = NULL; diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 860c98fc72c7..c9decd80bf61 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -1274,27 +1274,9 @@ static const struct v4l2_ctrl_ops cx8800_ctrl_aud_ops = { static void cx8800_unregister_video(struct cx8800_dev *dev) { - if (dev->radio_dev) { - if (video_is_registered(dev->radio_dev)) - video_unregister_device(dev->radio_dev); - else - video_device_release(dev->radio_dev); - dev->radio_dev = NULL; - } - if (dev->vbi_dev) { - if (video_is_registered(dev->vbi_dev)) - video_unregister_device(dev->vbi_dev); - else - video_device_release(dev->vbi_dev); - dev->vbi_dev = NULL; - } - if (dev->video_dev) { - if (video_is_registered(dev->video_dev)) - video_unregister_device(dev->video_dev); - else - video_device_release(dev->video_dev); - dev->video_dev = NULL; - } + video_unregister_device(&dev->radio_dev); + video_unregister_device(&dev->vbi_dev); + video_unregister_device(&dev->video_dev); } static int cx8800_initdev(struct pci_dev *pci_dev, @@ -1485,12 +1467,12 @@ static int cx8800_initdev(struct pci_dev *pci_dev, goto fail_unreg; /* register v4l devices */ - dev->video_dev = cx88_vdev_init(core,dev->pci, - &cx8800_video_template,"video"); - video_set_drvdata(dev->video_dev, dev); - dev->video_dev->ctrl_handler = &core->video_hdl; - dev->video_dev->queue = &dev->vb2_vidq; - err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, + cx88_vdev_init(core, dev->pci, &dev->video_dev, + &cx8800_video_template, "video"); + video_set_drvdata(&dev->video_dev, dev); + dev->video_dev.ctrl_handler = &core->video_hdl; + dev->video_dev.queue = &dev->vb2_vidq; + err = video_register_device(&dev->video_dev, VFL_TYPE_GRABBER, video_nr[core->nr]); if (err < 0) { printk(KERN_ERR "%s/0: can't register video device\n", @@ -1498,12 +1480,13 @@ static int cx8800_initdev(struct pci_dev *pci_dev, goto fail_unreg; } printk(KERN_INFO "%s/0: registered device %s [v4l2]\n", - core->name, video_device_node_name(dev->video_dev)); + core->name, video_device_node_name(&dev->video_dev)); - dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi"); - video_set_drvdata(dev->vbi_dev, dev); - dev->vbi_dev->queue = &dev->vb2_vbiq; - err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, + cx88_vdev_init(core, dev->pci, &dev->vbi_dev, + &cx8800_vbi_template, "vbi"); + video_set_drvdata(&dev->vbi_dev, dev); + dev->vbi_dev.queue = &dev->vb2_vbiq; + err = video_register_device(&dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[core->nr]); if (err < 0) { printk(KERN_ERR "%s/0: can't register vbi device\n", @@ -1511,14 +1494,14 @@ static int cx8800_initdev(struct pci_dev *pci_dev, goto fail_unreg; } printk(KERN_INFO "%s/0: registered device %s\n", - core->name, video_device_node_name(dev->vbi_dev)); + core->name, video_device_node_name(&dev->vbi_dev)); if (core->board.radio.type == CX88_RADIO) { - dev->radio_dev = cx88_vdev_init(core,dev->pci, - &cx8800_radio_template,"radio"); - video_set_drvdata(dev->radio_dev, dev); - dev->radio_dev->ctrl_handler = &core->audio_hdl; - err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, + cx88_vdev_init(core, dev->pci, &dev->radio_dev, + &cx8800_radio_template, "radio"); + video_set_drvdata(&dev->radio_dev, dev); + dev->radio_dev.ctrl_handler = &core->audio_hdl; + err = video_register_device(&dev->radio_dev, VFL_TYPE_RADIO, radio_nr[core->nr]); if (err < 0) { printk(KERN_ERR "%s/0: can't register radio device\n", @@ -1526,7 +1509,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, goto fail_unreg; } printk(KERN_INFO "%s/0: registered device %s\n", - core->name, video_device_node_name(dev->radio_dev)); + core->name, video_device_node_name(&dev->radio_dev)); } /* start tvaudio thread */ diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 7748ca9abb09..b9fe1ac24803 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h @@ -478,9 +478,9 @@ struct cx8800_dev { /* various device info */ unsigned int resources; - struct video_device *video_dev; - struct video_device *vbi_dev; - struct video_device *radio_dev; + struct video_device video_dev; + struct video_device vbi_dev; + struct video_device radio_dev; /* pci i/o */ struct pci_dev *pci; @@ -563,7 +563,7 @@ struct cx8802_dev { /* for blackbird only */ struct list_head devlist; #if IS_ENABLED(CONFIG_VIDEO_CX88_BLACKBIRD) - struct video_device *mpeg_dev; + struct video_device mpeg_dev; u32 mailbox; /* mpeg params */ @@ -647,10 +647,11 @@ extern int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height, enum v4l2_field field); extern int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm); -extern struct video_device *cx88_vdev_init(struct cx88_core *core, - struct pci_dev *pci, - const struct video_device *template_, - const char *type); +extern void cx88_vdev_init(struct cx88_core *core, + struct pci_dev *pci, + struct video_device *vfd, + const struct video_device *template_, + const char *type); extern struct cx88_core *cx88_core_get(struct pci_dev *pci); extern void cx88_core_put(struct cx88_core *core, struct pci_dev *pci); diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c index 39b52929755a..41fa21534edf 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-main.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c @@ -224,7 +224,7 @@ static int ivtv_alsa_load(struct ivtv *itv) } s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; - if (s->vdev == NULL) { + if (s->vdev.v4l2_dev == NULL) { IVTV_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - " "skipping\n", __func__); return 0; diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c index 7bf9cbca4fa6..f198b9826ed8 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c @@ -167,7 +167,7 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream) s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; - v4l2_fh_init(&item.fh, s->vdev); + v4l2_fh_init(&item.fh, &s->vdev); item.itv = itv; item.type = s->type; diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index 802642d26643..c2e60b4f292d 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -1284,7 +1284,7 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) return 0; free_streams: - ivtv_streams_cleanup(itv, 1); + ivtv_streams_cleanup(itv); free_irq: free_irq(itv->pdev->irq, (void *)itv); free_i2c: @@ -1444,7 +1444,7 @@ static void ivtv_remove(struct pci_dev *pdev) flush_kthread_worker(&itv->irq_worker); kthread_stop(itv->irq_worker_task); - ivtv_streams_cleanup(itv, 1); + ivtv_streams_cleanup(itv); ivtv_udma_free(itv); v4l2_ctrl_handler_free(&itv->cxhdl.hdl); diff --git a/drivers/media/pci/ivtv/ivtv-driver.h b/drivers/media/pci/ivtv/ivtv-driver.h index bc309f42c8ed..e8b6c7ad2ba9 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.h +++ b/drivers/media/pci/ivtv/ivtv-driver.h @@ -327,7 +327,7 @@ struct ivtv; /* forward reference */ struct ivtv_stream { /* These first four fields are always set, even if the stream is not actually created. */ - struct video_device *vdev; /* NULL when stream not created */ + struct video_device vdev; /* vdev.v4l2_dev is NULL if there is no device */ struct ivtv *itv; /* for ease of use */ const char *name; /* name of the stream */ int type; /* stream type */ diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c b/drivers/media/pci/ivtv/ivtv-fileops.c index e5ff6277ca85..605d280d8a5f 100644 --- a/drivers/media/pci/ivtv/ivtv-fileops.c +++ b/drivers/media/pci/ivtv/ivtv-fileops.c @@ -995,7 +995,7 @@ static int ivtv_open(struct file *filp) IVTV_DEBUG_WARN("nomem on v4l2 open\n"); return -ENOMEM; } - v4l2_fh_init(&item->fh, s->vdev); + v4l2_fh_init(&item->fh, &s->vdev); item->itv = itv; item->type = s->type; diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 4d8ee18c3feb..6fe6c4a0e858 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -448,9 +448,12 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv *itv = fh2id(fh)->itv; + struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; struct v4l2_window *winfmt = &fmt->fmt.win; - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) + if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + return -EINVAL; + if (!itv->osd_video_pbase) return -EINVAL; winfmt->chromakey = itv->osd_chroma_key; winfmt->global_alpha = itv->osd_global_alpha; @@ -555,10 +558,13 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv *itv = fh2id(fh)->itv; + struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; u32 chromakey = fmt->fmt.win.chromakey; u8 global_alpha = fmt->fmt.win.global_alpha; - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) + if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + return -EINVAL; + if (!itv->osd_video_pbase) return -EINVAL; ivtv_g_fmt_vid_out_overlay(file, fh, fmt); fmt->fmt.win.chromakey = chromakey; @@ -741,6 +747,11 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS; vcap->device_caps = s->caps; + if ((s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) && + !itv->osd_video_pbase) { + vcap->capabilities &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; + vcap->device_caps &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; + } return 0; } @@ -816,80 +827,103 @@ static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropca { struct ivtv_open_id *id = fh2id(fh); struct ivtv *itv = id->itv; - struct yuv_playback_info *yi = &itv->yuv_info; - int streamtype; - - streamtype = id->type; - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) - return -EINVAL; - cropcap->bounds.top = cropcap->bounds.left = 0; - cropcap->bounds.width = 720; if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - cropcap->bounds.height = itv->is_50hz ? 576 : 480; cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; - } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { - if (yi->track_osd) { - cropcap->bounds.width = yi->osd_full_w; - cropcap->bounds.height = yi->osd_full_h; - } else { - cropcap->bounds.width = 720; - cropcap->bounds.height = - itv->is_out_50hz ? 576 : 480; - } + } else if (cropcap->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; } else { - cropcap->bounds.height = itv->is_out_50hz ? 576 : 480; - cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; - cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; + return -EINVAL; } - cropcap->defrect = cropcap->bounds; return 0; } -static int ivtv_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop) +static int ivtv_s_selection(struct file *file, void *fh, + struct v4l2_selection *sel) { struct ivtv_open_id *id = fh2id(fh); struct ivtv *itv = id->itv; struct yuv_playback_info *yi = &itv->yuv_info; - int streamtype; + struct v4l2_rect r = { 0, 0, 720, 0 }; + int streamtype = id->type; - streamtype = id->type; + if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || + !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) + return -EINVAL; - if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && - (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { - if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { - yi->main_rect = crop->c; - return 0; - } else { - if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, - crop->c.width, crop->c.height, crop->c.left, crop->c.top)) { - itv->main_rect = crop->c; - return 0; - } - } + if (sel->target != V4L2_SEL_TGT_COMPOSE) return -EINVAL; + + + if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || + !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) + return -EINVAL; + + r.height = itv->is_out_50hz ? 576 : 480; + if (streamtype == IVTV_DEC_STREAM_TYPE_YUV && yi->track_osd) { + r.width = yi->osd_full_w; + r.height = yi->osd_full_h; + } + sel->r.width = clamp(sel->r.width, 16U, r.width); + sel->r.height = clamp(sel->r.height, 16U, r.height); + sel->r.left = clamp_t(unsigned, sel->r.left, 0, r.width - sel->r.width); + sel->r.top = clamp_t(unsigned, sel->r.top, 0, r.height - sel->r.height); + + if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { + yi->main_rect = sel->r; + return 0; + } + if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, + sel->r.width, sel->r.height, sel->r.left, sel->r.top)) { + itv->main_rect = sel->r; + return 0; } return -EINVAL; } -static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) +static int ivtv_g_selection(struct file *file, void *fh, + struct v4l2_selection *sel) { struct ivtv_open_id *id = fh2id(fh); struct ivtv *itv = id->itv; struct yuv_playback_info *yi = &itv->yuv_info; - int streamtype; + struct v4l2_rect r = { 0, 0, 720, 0 }; + int streamtype = id->type; + + if (sel->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + switch (sel->target) { + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.top = sel->r.left = 0; + sel->r.width = 720; + sel->r.height = itv->is_50hz ? 576 : 480; + return 0; + default: + return -EINVAL; + } + } - streamtype = id->type; + if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || + !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) + return -EINVAL; - if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && - (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { + switch (sel->target) { + case V4L2_SEL_TGT_COMPOSE: if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) - crop->c = yi->main_rect; + sel->r = yi->main_rect; else - crop->c = itv->main_rect; + sel->r = itv->main_rect; + return 0; + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + r.height = itv->is_out_50hz ? 576 : 480; + if (streamtype == IVTV_DEC_STREAM_TYPE_YUV && yi->track_osd) { + r.width = yi->osd_full_w; + r.height = yi->osd_full_h; + } + sel->r = r; return 0; } return -EINVAL; @@ -987,7 +1021,7 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp) else std = V4L2_STD_ALL; for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++) - itv->streams[i].vdev->tvnorms = std; + itv->streams[i].vdev.tvnorms = std; /* prevent others from messing with the streams until we're finished changing inputs. */ @@ -1038,7 +1072,7 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency * struct ivtv *itv = fh2id(fh)->itv; struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; - if (s->vdev->vfl_dir) + if (s->vdev.vfl_dir) return -ENOTTY; if (vf->tuner != 0) return -EINVAL; @@ -1052,7 +1086,7 @@ int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v struct ivtv *itv = fh2id(fh)->itv; struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; - if (s->vdev->vfl_dir) + if (s->vdev.vfl_dir) return -ENOTTY; if (vf->tuner != 0) return -EINVAL; @@ -1340,6 +1374,7 @@ static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) { struct ivtv *itv = fh2id(fh)->itv; + struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; u32 data[CX2341X_MBOX_MAX_DATA]; struct yuv_playback_info *yi = &itv->yuv_info; @@ -1363,10 +1398,10 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) 0, }; - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) - return -EINVAL; + if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + return -ENOTTY; if (!itv->osd_video_pbase) - return -EINVAL; + return -ENOTTY; fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | V4L2_FBUF_CAP_GLOBAL_ALPHA; @@ -1427,12 +1462,13 @@ static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffe { struct ivtv_open_id *id = fh2id(fh); struct ivtv *itv = id->itv; + struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; struct yuv_playback_info *yi = &itv->yuv_info; - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) - return -EINVAL; + if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + return -ENOTTY; if (!itv->osd_video_pbase) - return -EINVAL; + return -ENOTTY; itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; itv->osd_local_alpha_state = @@ -1447,9 +1483,12 @@ static int ivtv_overlay(struct file *file, void *fh, unsigned int on) { struct ivtv_open_id *id = fh2id(fh); struct ivtv *itv = id->itv; + struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) - return -EINVAL; + if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + return -ENOTTY; + if (!itv->osd_video_pbase) + return -ENOTTY; ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0); @@ -1547,7 +1586,7 @@ static int ivtv_log_status(struct file *file, void *fh) for (i = 0; i < IVTV_MAX_STREAMS; i++) { struct ivtv_stream *s = &itv->streams[i]; - if (s->vdev == NULL || s->buffers == 0) + if (s->vdev.v4l2_dev == NULL || s->buffers == 0) continue; IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, (s->buffers - s->q_free.buffers) * 100 / s->buffers, @@ -1837,8 +1876,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { .vidioc_enum_output = ivtv_enum_output, .vidioc_enumaudout = ivtv_enumaudout, .vidioc_cropcap = ivtv_cropcap, - .vidioc_s_crop = ivtv_s_crop, - .vidioc_g_crop = ivtv_g_crop, + .vidioc_s_selection = ivtv_s_selection, + .vidioc_g_selection = ivtv_g_selection, .vidioc_g_input = ivtv_g_input, .vidioc_s_input = ivtv_s_input, .vidioc_g_output = ivtv_g_output, diff --git a/drivers/media/pci/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c index e7d701777e53..36ca2d67c812 100644 --- a/drivers/media/pci/ivtv/ivtv-irq.c +++ b/drivers/media/pci/ivtv/ivtv-irq.c @@ -75,7 +75,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv) IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n"); if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || - s->vdev == NULL || !ivtv_use_pio(s)) { + s->vdev.v4l2_dev == NULL || !ivtv_use_pio(s)) { itv->cur_pio_stream = -1; /* trigger PIO complete user interrupt */ write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); @@ -132,7 +132,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA int rc; /* sanity checks */ - if (s->vdev == NULL) { + if (s->vdev.v4l2_dev == NULL) { IVTV_DEBUG_WARN("Stream %s not started\n", s->name); return -1; } @@ -890,8 +890,8 @@ static void ivtv_irq_vsync(struct ivtv *itv) if (s) wake_up(&s->waitq); } - if (s && s->vdev) - v4l2_event_queue(s->vdev, frame ? &evtop : &evbottom); + if (s && s->vdev.v4l2_dev) + v4l2_event_queue(&s->vdev, frame ? &evtop : &evbottom); wake_up(&itv->vsync_waitq); /* Send VBI to saa7127 */ diff --git a/drivers/media/pci/ivtv/ivtv-streams.c b/drivers/media/pci/ivtv/ivtv-streams.c index f0a1cc472313..d27c6df97566 100644 --- a/drivers/media/pci/ivtv/ivtv-streams.c +++ b/drivers/media/pci/ivtv/ivtv-streams.c @@ -130,7 +130,8 @@ static struct { "decoder MPG", VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET, PCI_DMA_TODEVICE, 0, - V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | + V4L2_CAP_VIDEO_OUTPUT_OVERLAY, &ivtv_v4l2_dec_fops }, { /* IVTV_DEC_STREAM_TYPE_VBI */ @@ -151,7 +152,8 @@ static struct { "decoder YUV", VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET, PCI_DMA_TODEVICE, 0, - V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | + V4L2_CAP_VIDEO_OUTPUT_OVERLAY, &ivtv_v4l2_dec_fops } }; @@ -159,11 +161,9 @@ static struct { static void ivtv_stream_init(struct ivtv *itv, int type) { struct ivtv_stream *s = &itv->streams[type]; - struct video_device *vdev = s->vdev; /* we need to keep vdev, so restore it afterwards */ memset(s, 0, sizeof(*s)); - s->vdev = vdev; /* initialize ivtv_stream fields */ s->itv = itv; @@ -194,10 +194,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) int num_offset = ivtv_stream_info[type].num_offset; int num = itv->instance + ivtv_first_minor + num_offset; - /* These four fields are always initialized. If vdev == NULL, then + /* These four fields are always initialized. If vdev.v4l2_dev == NULL, then this stream is not in use. In that case no other fields but these four can be used. */ - s->vdev = NULL; + s->vdev.v4l2_dev = NULL; s->itv = itv; s->type = type; s->name = ivtv_stream_info[type].name; @@ -218,40 +218,33 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) ivtv_stream_init(itv, type); - /* allocate and initialize the v4l2 video device structure */ - s->vdev = video_device_alloc(); - if (s->vdev == NULL) { - IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name); - return -ENOMEM; - } - - snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s", + snprintf(s->vdev.name, sizeof(s->vdev.name), "%s %s", itv->v4l2_dev.name, s->name); - s->vdev->num = num; - s->vdev->v4l2_dev = &itv->v4l2_dev; + s->vdev.num = num; + s->vdev.v4l2_dev = &itv->v4l2_dev; if (ivtv_stream_info[type].v4l2_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT)) - s->vdev->vfl_dir = VFL_DIR_TX; - s->vdev->fops = ivtv_stream_info[type].fops; - s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler; - s->vdev->release = video_device_release; - s->vdev->tvnorms = V4L2_STD_ALL; - s->vdev->lock = &itv->serialize_lock; + s->vdev.vfl_dir = VFL_DIR_TX; + s->vdev.fops = ivtv_stream_info[type].fops; + s->vdev.ctrl_handler = itv->v4l2_dev.ctrl_handler; + s->vdev.release = video_device_release_empty; + s->vdev.tvnorms = V4L2_STD_ALL; + s->vdev.lock = &itv->serialize_lock; if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { - v4l2_disable_ioctl(s->vdev, VIDIOC_S_AUDIO); - v4l2_disable_ioctl(s->vdev, VIDIOC_G_AUDIO); - v4l2_disable_ioctl(s->vdev, VIDIOC_ENUMAUDIO); - v4l2_disable_ioctl(s->vdev, VIDIOC_ENUMINPUT); - v4l2_disable_ioctl(s->vdev, VIDIOC_S_INPUT); - v4l2_disable_ioctl(s->vdev, VIDIOC_G_INPUT); - v4l2_disable_ioctl(s->vdev, VIDIOC_S_FREQUENCY); - v4l2_disable_ioctl(s->vdev, VIDIOC_G_FREQUENCY); - v4l2_disable_ioctl(s->vdev, VIDIOC_S_TUNER); - v4l2_disable_ioctl(s->vdev, VIDIOC_G_TUNER); - v4l2_disable_ioctl(s->vdev, VIDIOC_S_STD); + v4l2_disable_ioctl(&s->vdev, VIDIOC_S_AUDIO); + v4l2_disable_ioctl(&s->vdev, VIDIOC_G_AUDIO); + v4l2_disable_ioctl(&s->vdev, VIDIOC_ENUMAUDIO); + v4l2_disable_ioctl(&s->vdev, VIDIOC_ENUMINPUT); + v4l2_disable_ioctl(&s->vdev, VIDIOC_S_INPUT); + v4l2_disable_ioctl(&s->vdev, VIDIOC_G_INPUT); + v4l2_disable_ioctl(&s->vdev, VIDIOC_S_FREQUENCY); + v4l2_disable_ioctl(&s->vdev, VIDIOC_G_FREQUENCY); + v4l2_disable_ioctl(&s->vdev, VIDIOC_S_TUNER); + v4l2_disable_ioctl(&s->vdev, VIDIOC_G_TUNER); + v4l2_disable_ioctl(&s->vdev, VIDIOC_S_STD); } - ivtv_set_funcs(s->vdev); + ivtv_set_funcs(&s->vdev); return 0; } @@ -266,7 +259,7 @@ int ivtv_streams_setup(struct ivtv *itv) if (ivtv_prep_dev(itv, type)) break; - if (itv->streams[type].vdev == NULL) + if (itv->streams[type].vdev.v4l2_dev == NULL) continue; /* Allocate Stream */ @@ -277,7 +270,7 @@ int ivtv_streams_setup(struct ivtv *itv) return 0; /* One or more streams could not be initialized. Clean 'em all up. */ - ivtv_streams_cleanup(itv, 0); + ivtv_streams_cleanup(itv); return -ENOMEM; } @@ -288,28 +281,26 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) const char *name; int num; - if (s->vdev == NULL) + if (s->vdev.v4l2_dev == NULL) return 0; - num = s->vdev->num; + num = s->vdev.num; /* card number + user defined offset + device offset */ if (type != IVTV_ENC_STREAM_TYPE_MPG) { struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; - if (s_mpg->vdev) - num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset; + if (s_mpg->vdev.v4l2_dev) + num = s_mpg->vdev.num + ivtv_stream_info[type].num_offset; } - video_set_drvdata(s->vdev, s); + video_set_drvdata(&s->vdev, s); /* Register device. First try the desired minor, then any free one. */ - if (video_register_device_no_warn(s->vdev, vfl_type, num)) { + if (video_register_device_no_warn(&s->vdev, vfl_type, num)) { IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", s->name, num); - video_device_release(s->vdev); - s->vdev = NULL; return -ENOMEM; } - name = video_device_node_name(s->vdev); + name = video_device_node_name(&s->vdev); switch (vfl_type) { case VFL_TYPE_GRABBER: @@ -346,29 +337,25 @@ int ivtv_streams_register(struct ivtv *itv) return 0; /* One or more streams could not be initialized. Clean 'em all up. */ - ivtv_streams_cleanup(itv, 1); + ivtv_streams_cleanup(itv); return -ENOMEM; } /* Unregister v4l2 devices */ -void ivtv_streams_cleanup(struct ivtv *itv, int unregister) +void ivtv_streams_cleanup(struct ivtv *itv) { int type; /* Teardown all streams */ for (type = 0; type < IVTV_MAX_STREAMS; type++) { - struct video_device *vdev = itv->streams[type].vdev; + struct video_device *vdev = &itv->streams[type].vdev; - itv->streams[type].vdev = NULL; - if (vdev == NULL) + if (vdev->v4l2_dev == NULL) continue; + video_unregister_device(vdev); ivtv_stream_free(&itv->streams[type]); - /* Unregister or release device */ - if (unregister) - video_unregister_device(vdev); - else - video_device_release(vdev); + itv->streams[type].vdev.v4l2_dev = NULL; } } @@ -492,7 +479,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) int captype = 0, subtype = 0; int enable_passthrough = 0; - if (s->vdev == NULL) + if (s->vdev.v4l2_dev == NULL) return -EINVAL; IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); @@ -661,7 +648,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) u16 width; u16 height; - if (s->vdev == NULL) + if (s->vdev.v4l2_dev == NULL) return -EINVAL; IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); @@ -723,7 +710,7 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset) struct ivtv *itv = s->itv; int rc; - if (s->vdev == NULL) + if (s->vdev.v4l2_dev == NULL) return -EINVAL; if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) @@ -778,7 +765,7 @@ void ivtv_stop_all_captures(struct ivtv *itv) for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) { struct ivtv_stream *s = &itv->streams[i]; - if (s->vdev == NULL) + if (s->vdev.v4l2_dev == NULL) continue; if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { ivtv_stop_v4l2_encode_stream(s, 0); @@ -793,7 +780,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) int cap_type; int stopmode; - if (s->vdev == NULL) + if (s->vdev.v4l2_dev == NULL) return -EINVAL; /* This function assumes that you are allowed to stop the capture @@ -917,7 +904,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) }; struct ivtv *itv = s->itv; - if (s->vdev == NULL) + if (s->vdev.v4l2_dev == NULL) return -EINVAL; if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG) @@ -969,7 +956,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags); wake_up(&itv->event_waitq); - v4l2_event_queue(s->vdev, &ev); + v4l2_event_queue(&s->vdev, &ev); /* wake up wait queues */ wake_up(&s->waitq); @@ -982,7 +969,7 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable) struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV]; struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; - if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL) + if (yuv_stream->vdev.v4l2_dev == NULL || dec_stream->vdev.v4l2_dev == NULL) return -EINVAL; IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n"); diff --git a/drivers/media/pci/ivtv/ivtv-streams.h b/drivers/media/pci/ivtv/ivtv-streams.h index a653a5136417..3d76a415fbd8 100644 --- a/drivers/media/pci/ivtv/ivtv-streams.h +++ b/drivers/media/pci/ivtv/ivtv-streams.h @@ -23,7 +23,7 @@ int ivtv_streams_setup(struct ivtv *itv); int ivtv_streams_register(struct ivtv *itv); -void ivtv_streams_cleanup(struct ivtv *itv, int unregister); +void ivtv_streams_cleanup(struct ivtv *itv); /* Capture related */ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s); diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 9d9f90cb7740..ba887e8e1b17 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -1546,7 +1546,7 @@ static struct video_device meye_template = { .name = "meye", .fops = &meye_fops, .ioctl_ops = &meye_ioctl_ops, - .release = video_device_release, + .release = video_device_release_empty, }; static const struct v4l2_ctrl_ops meye_ctrl_ops = { @@ -1623,7 +1623,7 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) if (meye.mchip_dev != NULL) { printk(KERN_ERR "meye: only one device allowed!\n"); - goto outnotdev; + return ret; } ret = v4l2_device_register(&pcidev->dev, v4l2_dev); @@ -1633,11 +1633,6 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) } ret = -ENOMEM; meye.mchip_dev = pcidev; - meye.vdev = video_device_alloc(); - if (!meye.vdev) { - v4l2_err(v4l2_dev, "video_device_alloc() failed!\n"); - goto outnotdev; - } meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE); if (!meye.grab_temp) { @@ -1658,8 +1653,8 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) goto outkfifoalloc2; } - memcpy(meye.vdev, &meye_template, sizeof(meye_template)); - meye.vdev->v4l2_dev = &meye.v4l2_dev; + meye.vdev = meye_template; + meye.vdev.v4l2_dev = &meye.v4l2_dev; ret = -EIO; if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) { @@ -1743,9 +1738,9 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) } v4l2_ctrl_handler_setup(&meye.hdl); - meye.vdev->ctrl_handler = &meye.hdl; + meye.vdev.ctrl_handler = &meye.hdl; - if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, + if (video_register_device(&meye.vdev, VFL_TYPE_GRABBER, video_nr) < 0) { v4l2_err(v4l2_dev, "video_register_device failed\n"); goto outvideoreg; @@ -1777,14 +1772,12 @@ outkfifoalloc2: outkfifoalloc1: vfree(meye.grab_temp); outvmalloc: - video_device_release(meye.vdev); -outnotdev: return ret; } static void meye_remove(struct pci_dev *pcidev) { - video_unregister_device(meye.vdev); + video_unregister_device(&meye.vdev); mchip_hic_stop(); diff --git a/drivers/media/pci/meye/meye.h b/drivers/media/pci/meye/meye.h index 6fed9274cfa5..751be5e533c7 100644 --- a/drivers/media/pci/meye/meye.h +++ b/drivers/media/pci/meye/meye.h @@ -311,7 +311,7 @@ struct meye { struct kfifo doneq; /* queue for grabbed buffers */ spinlock_t doneq_lock; /* lock protecting the queue */ wait_queue_head_t proc_list; /* wait queue */ - struct video_device *vdev; /* video device parameters */ + struct video_device vdev; /* video device parameters */ u16 brightness; u16 hue; u16 contrast; diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c index 366434f5647e..03cbcd2095c6 100644 --- a/drivers/media/pci/saa7146/hexium_gemini.c +++ b/drivers/media/pci/saa7146/hexium_gemini.c @@ -66,7 +66,7 @@ struct hexium { int type; - struct video_device *video_dev; + struct video_device video_dev; struct i2c_adapter i2c_adapter; int cur_input; /* current input */ diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c index a1eb26d11070..15f0d66ff78a 100644 --- a/drivers/media/pci/saa7146/hexium_orion.c +++ b/drivers/media/pci/saa7146/hexium_orion.c @@ -63,7 +63,7 @@ struct hexium_data struct hexium { int type; - struct video_device *video_dev; + struct video_device video_dev; struct i2c_adapter i2c_adapter; int cur_input; /* current input */ diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c index c4c8fce8f2b4..0ca1e07ae783 100644 --- a/drivers/media/pci/saa7146/mxb.c +++ b/drivers/media/pci/saa7146/mxb.c @@ -151,8 +151,8 @@ static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = { struct mxb { - struct video_device *video_dev; - struct video_device *vbi_dev; + struct video_device video_dev; + struct video_device vbi_dev; struct i2c_adapter i2c_adapter; diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 4b0bec3766ed..9cf3c6cba498 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -1436,11 +1436,11 @@ static void saa7164_finidev(struct pci_dev *pci_dev) saa7164_i2c_unregister(&dev->i2c_bus[1]); saa7164_i2c_unregister(&dev->i2c_bus[2]); - pci_disable_device(pci_dev); - /* unregister stuff */ free_irq(pci_dev->irq, dev); + pci_disable_device(pci_dev); + mutex_lock(&devlist); list_del(&dev->devlist); mutex_unlock(&devlist); diff --git a/drivers/media/pci/smipcie/Kconfig b/drivers/media/pci/smipcie/Kconfig index c8de53f5ea28..21a1583dbd8f 100644 --- a/drivers/media/pci/smipcie/Kconfig +++ b/drivers/media/pci/smipcie/Kconfig @@ -4,7 +4,7 @@ config DVB_SMIPCIE select I2C_ALGOBIT select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT - select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT + select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT help diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie.c index 36c8ed77309c..411592524c63 100644 --- a/drivers/media/pci/smipcie/smipcie.c +++ b/drivers/media/pci/smipcie/smipcie.c @@ -16,7 +16,7 @@ #include "smipcie.h" #include "m88ds3103.h" -#include "m88ts2022.h" +#include "ts2020.h" #include "m88rs6000t.h" #include "si2168.h" #include "si2157.h" @@ -532,9 +532,7 @@ static int smi_dvbsky_m88ds3103_fe_attach(struct smi_port *port) struct i2c_adapter *tuner_i2c_adapter; struct i2c_client *tuner_client; struct i2c_board_info tuner_info; - struct m88ts2022_config m88ts2022_config = { - .clock = 27000000, - }; + struct ts2020_config ts2020_config = {}; memset(&tuner_info, 0, sizeof(struct i2c_board_info)); i2c = (port->idx == 0) ? &dev->i2c_bus[0] : &dev->i2c_bus[1]; @@ -546,10 +544,10 @@ static int smi_dvbsky_m88ds3103_fe_attach(struct smi_port *port) return ret; } /* attach tuner */ - m88ts2022_config.fe = port->fe; - strlcpy(tuner_info.type, "m88ts2022", I2C_NAME_SIZE); + ts2020_config.fe = port->fe; + strlcpy(tuner_info.type, "ts2020", I2C_NAME_SIZE); tuner_info.addr = 0x60; - tuner_info.platform_data = &m88ts2022_config; + tuner_info.platform_data = &ts2020_config; tuner_client = smi_add_i2c_client(tuner_i2c_adapter, &tuner_info); if (!tuner_client) { ret = -ENODEV; diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c index 22450f583da1..d384a6b0b09f 100644 --- a/drivers/media/pci/sta2x11/sta2x11_vip.c +++ b/drivers/media/pci/sta2x11/sta2x11_vip.c @@ -127,7 +127,7 @@ static inline struct vip_buffer *to_vip_buffer(struct vb2_buffer *vb2) */ struct sta2x11_vip { struct v4l2_device v4l2_dev; - struct video_device *video_dev; + struct video_device video_dev; struct pci_dev *pdev; struct i2c_adapter *adapter; unsigned int register_save_area[IRQ_COUNT + SAVE_COUNT + AUX_COUNT]; @@ -763,7 +763,7 @@ static const struct v4l2_ioctl_ops vip_ioctl_ops = { static struct video_device video_dev_template = { .name = KBUILD_MODNAME, - .release = video_device_release, + .release = video_device_release_empty, .fops = &vip_fops, .ioctl_ops = &vip_ioctl_ops, .tvnorms = V4L2_STD_ALL, @@ -1082,19 +1082,13 @@ static int sta2x11_vip_init_one(struct pci_dev *pdev, goto release_buf; } - /* Alloc, initialize and register video device */ - vip->video_dev = video_device_alloc(); - if (!vip->video_dev) { - ret = -ENOMEM; - goto release_irq; - } + /* Initialize and register video device */ + vip->video_dev = video_dev_template; + vip->video_dev.v4l2_dev = &vip->v4l2_dev; + vip->video_dev.queue = &vip->vb_vidq; + video_set_drvdata(&vip->video_dev, vip); - vip->video_dev = &video_dev_template; - vip->video_dev->v4l2_dev = &vip->v4l2_dev; - vip->video_dev->queue = &vip->vb_vidq; - video_set_drvdata(vip->video_dev, vip); - - ret = video_register_device(vip->video_dev, VFL_TYPE_GRABBER, -1); + ret = video_register_device(&vip->video_dev, VFL_TYPE_GRABBER, -1); if (ret) goto vrelease; @@ -1124,13 +1118,9 @@ static int sta2x11_vip_init_one(struct pci_dev *pdev, return 0; vunreg: - video_set_drvdata(vip->video_dev, NULL); + video_set_drvdata(&vip->video_dev, NULL); vrelease: - if (video_is_registered(vip->video_dev)) - video_unregister_device(vip->video_dev); - else - video_device_release(vip->video_dev); -release_irq: + video_unregister_device(&vip->video_dev); free_irq(pdev->irq, vip); release_buf: sta2x11_vip_release_buffer(vip); @@ -1175,9 +1165,8 @@ static void sta2x11_vip_remove_one(struct pci_dev *pdev) sta2x11_vip_clear_register(vip); - video_set_drvdata(vip->video_dev, NULL); - video_unregister_device(vip->video_dev); - /*do not call video_device_release() here, is already done */ + video_set_drvdata(&vip->video_dev, NULL); + video_unregister_device(&vip->video_dev); free_irq(pdev->irq, vip); pci_disable_msi(pdev); vb2_queue_release(&vip->vb_vidq); diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h index ef3d9606b269..835635b0c712 100644 --- a/drivers/media/pci/ttpci/av7110.h +++ b/drivers/media/pci/ttpci/av7110.h @@ -102,8 +102,8 @@ struct av7110 { struct dvb_device dvb_dev; struct dvb_net dvb_net; - struct video_device *v4l_dev; - struct video_device *vbi_dev; + struct video_device v4l_dev; + struct video_device vbi_dev; struct saa7146_dev *dev; diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c index 0ba3875af22e..54c9910256f8 100644 --- a/drivers/media/pci/ttpci/budget-av.c +++ b/drivers/media/pci/ttpci/budget-av.c @@ -68,7 +68,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct budget_av { struct budget budget; - struct video_device *vd; + struct video_device vd; int cur_input; int has_saa7113; struct tasklet_struct ciintf_irq_tasklet; |