--- zzzz-none-000/linux-3.10.107/drivers/media/pci/cx18/cx18-streams.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/media/pci/cx18/cx18-streams.c 2021-02-04 17:41:59.000000000 +0000 @@ -58,11 +58,14 @@ int vfl_type; int num_offset; int dma; + u32 caps; } cx18_stream_info[] = { { /* CX18_ENC_STREAM_TYPE_MPG */ "encoder MPEG", VFL_TYPE_GRABBER, 0, PCI_DMA_FROMDEVICE, + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | + V4L2_CAP_AUDIO | V4L2_CAP_TUNER }, { /* CX18_ENC_STREAM_TYPE_TS */ "TS", @@ -73,16 +76,21 @@ "encoder YUV", VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET, PCI_DMA_FROMDEVICE, + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING | V4L2_CAP_AUDIO | V4L2_CAP_TUNER }, { /* CX18_ENC_STREAM_TYPE_VBI */ "encoder VBI", VFL_TYPE_VBI, 0, PCI_DMA_FROMDEVICE, + V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | + V4L2_CAP_READWRITE | V4L2_CAP_TUNER }, { /* CX18_ENC_STREAM_TYPE_PCM */ "encoder PCM audio", VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET, PCI_DMA_FROMDEVICE, + V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, }, { /* CX18_ENC_STREAM_TYPE_IDX */ "encoder IDX", @@ -93,6 +101,7 @@ "encoder radio", VFL_TYPE_RADIO, 0, PCI_DMA_NONE, + V4L2_CAP_RADIO | V4L2_CAP_TUNER }, }; @@ -246,11 +255,8 @@ 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; @@ -260,6 +266,7 @@ s->handle = CX18_INVALID_TASK_HANDLE; s->dma = cx18_stream_info[type].dma; + s->v4l2_dev_caps = cx18_stream_info[type].caps; s->buffers = cx->stream_buffers[type]; s->buf_size = cx->stream_buf_size[type]; INIT_LIST_HEAD(&s->buf_pool); @@ -298,6 +305,7 @@ /* 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; } } @@ -310,12 +318,12 @@ /* * 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; @@ -358,25 +366,20 @@ 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; - set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags); - 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; } @@ -420,31 +423,30 @@ } } - 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: @@ -534,10 +536,9 @@ } /* 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) @@ -545,11 +546,7 @@ 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); } } @@ -1034,7 +1031,7 @@ 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;