diff options
Diffstat (limited to 'drivers/media/platform/vivid')
-rw-r--r-- | drivers/media/platform/vivid/vivid-core.c | 26 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-vid-cap.c | 10 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-vid-common.c | 30 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-vid-out.c | 57 |
4 files changed, 91 insertions, 32 deletions
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index c931f007e5b0..342e0e6c103b 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -371,7 +371,7 @@ static int vidioc_s_parm(struct file *file, void *fh, if (vdev->vfl_dir == VFL_DIR_RX) return vivid_vid_cap_s_parm(file, fh, parm); - return vivid_vid_out_g_parm(file, fh, parm); + return -ENOTTY; } static int vidioc_log_status(struct file *file, void *fh) @@ -1094,7 +1094,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) q = &dev->vb_vid_cap_q; q->type = dev->multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_CAPTURE; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; + q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; + if (!allocator) + q->io_modes |= VB2_USERPTR; q->drv_priv = dev; q->buf_struct_size = sizeof(struct vivid_buffer); q->ops = &vivid_vid_cap_qops; @@ -1115,7 +1117,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) q = &dev->vb_vid_out_q; q->type = dev->multiplanar ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_WRITE; + q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_WRITE; + if (!allocator) + q->io_modes |= VB2_USERPTR; q->drv_priv = dev; q->buf_struct_size = sizeof(struct vivid_buffer); q->ops = &vivid_vid_out_qops; @@ -1136,7 +1140,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) q = &dev->vb_vbi_cap_q; q->type = dev->has_raw_vbi_cap ? V4L2_BUF_TYPE_VBI_CAPTURE : V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; + q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; + if (!allocator) + q->io_modes |= VB2_USERPTR; q->drv_priv = dev; q->buf_struct_size = sizeof(struct vivid_buffer); q->ops = &vivid_vbi_cap_qops; @@ -1157,7 +1163,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) q = &dev->vb_vbi_out_q; q->type = dev->has_raw_vbi_out ? V4L2_BUF_TYPE_VBI_OUTPUT : V4L2_BUF_TYPE_SLICED_VBI_OUTPUT; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_WRITE; + q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_WRITE; + if (!allocator) + q->io_modes |= VB2_USERPTR; q->drv_priv = dev; q->buf_struct_size = sizeof(struct vivid_buffer); q->ops = &vivid_vbi_out_qops; @@ -1177,7 +1185,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) /* initialize sdr_cap queue */ q = &dev->vb_sdr_cap_q; q->type = V4L2_BUF_TYPE_SDR_CAPTURE; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; + q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; + if (!allocator) + q->io_modes |= VB2_USERPTR; q->drv_priv = dev; q->buf_struct_size = sizeof(struct vivid_buffer); q->ops = &vivid_sdr_cap_qops; @@ -1468,9 +1478,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) return 0; unreg_dev: -#ifdef CONFIG_MEDIA_CONTROLLER - media_device_unregister(&dev->mdev); -#endif video_unregister_device(&dev->radio_tx_dev); video_unregister_device(&dev->radio_rx_dev); video_unregister_device(&dev->sdr_cap_dev); @@ -1543,6 +1550,7 @@ static int vivid_remove(struct platform_device *pdev) #ifdef CONFIG_MEDIA_CONTROLLER media_device_unregister(&dev->mdev); + media_device_cleanup(&dev->mdev); #endif if (dev->has_vid_cap) { diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index c059fc12668a..52eeda624d7e 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -124,7 +124,8 @@ static int vid_cap_queue_setup(struct vb2_queue *vq, } } else { for (p = 0; p < buffers; p++) - sizes[p] = tpg_g_line_width(&dev->tpg, p) * h + + sizes[p] = (tpg_g_line_width(&dev->tpg, p) * h) / + dev->fmt_cap->vdownsampling[p] + dev->fmt_cap->data_offset[p]; } @@ -161,7 +162,9 @@ static int vid_cap_buf_prepare(struct vb2_buffer *vb) return -EINVAL; } for (p = 0; p < buffers; p++) { - size = tpg_g_line_width(&dev->tpg, p) * dev->fmt_cap_rect.height + + size = (tpg_g_line_width(&dev->tpg, p) * + dev->fmt_cap_rect.height) / + dev->fmt_cap->vdownsampling[p] + dev->fmt_cap->data_offset[p]; if (vb2_plane_size(vb, p) < size) { @@ -545,7 +548,8 @@ int vivid_g_fmt_vid_cap(struct file *file, void *priv, for (p = 0; p < mp->num_planes; p++) { mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p); mp->plane_fmt[p].sizeimage = - tpg_g_line_width(&dev->tpg, p) * mp->height + + (tpg_g_line_width(&dev->tpg, p) * mp->height) / + dev->fmt_cap->vdownsampling[p] + dev->fmt_cap->data_offset[p]; } return 0; diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index 661f4015fba1..74b83bcc6119 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -169,6 +169,36 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0x000000ff, }, { + .fourcc = V4L2_PIX_FMT_AYUV32, + .vdownsampling = { 1 }, + .bit_depth = { 32 }, + .planes = 1, + .buffers = 1, + .alpha_mask = 0x000000ff, + }, + { + .fourcc = V4L2_PIX_FMT_XYUV32, + .vdownsampling = { 1 }, + .bit_depth = { 32 }, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_VUYA32, + .vdownsampling = { 1 }, + .bit_depth = { 32 }, + .planes = 1, + .buffers = 1, + .alpha_mask = 0xff000000, + }, + { + .fourcc = V4L2_PIX_FMT_VUYX32, + .vdownsampling = { 1 }, + .bit_depth = { 32 }, + .planes = 1, + .buffers = 1, + }, + { .fourcc = V4L2_PIX_FMT_GREY, .vdownsampling = { 1 }, .bit_depth = { 8 }, diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index ea250aee2b2e..e61b91b414f9 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -28,11 +28,12 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct vivid_fmt *vfmt = dev->fmt_out; unsigned planes = vfmt->buffers; unsigned h = dev->fmt_out_rect.height; - unsigned size = dev->bytesperline_out[0] * h; + unsigned int size = dev->bytesperline_out[0] * h + vfmt->data_offset[0]; unsigned p; for (p = vfmt->buffers; p < vfmt->planes; p++) - size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p]; + size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p] + + vfmt->data_offset[p]; if (dev->field_out == V4L2_FIELD_ALTERNATE) { /* @@ -62,12 +63,14 @@ static int vid_out_queue_setup(struct vb2_queue *vq, if (sizes[0] < size) return -EINVAL; for (p = 1; p < planes; p++) { - if (sizes[p] < dev->bytesperline_out[p] * h) + if (sizes[p] < dev->bytesperline_out[p] * h + + vfmt->data_offset[p]) return -EINVAL; } } else { for (p = 0; p < planes; p++) - sizes[p] = p ? dev->bytesperline_out[p] * h : size; + sizes[p] = p ? dev->bytesperline_out[p] * h + + vfmt->data_offset[p] : size; } if (vq->num_buffers + *nbuffers < 2) @@ -81,21 +84,38 @@ static int vid_out_queue_setup(struct vb2_queue *vq, return 0; } -static int vid_out_buf_prepare(struct vb2_buffer *vb) +static int vid_out_buf_out_validate(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); - unsigned long size; - unsigned planes; + + dprintk(dev, 1, "%s\n", __func__); + + if (dev->field_out != V4L2_FIELD_ALTERNATE) + vbuf->field = dev->field_out; + else if (vbuf->field != V4L2_FIELD_TOP && + vbuf->field != V4L2_FIELD_BOTTOM) + return -EINVAL; + return 0; +} + +static int vid_out_buf_prepare(struct vb2_buffer *vb) +{ + struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); + const struct vivid_fmt *vfmt = dev->fmt_out; + unsigned int planes = vfmt->buffers; + unsigned int h = dev->fmt_out_rect.height; + unsigned int size = dev->bytesperline_out[0] * h; unsigned p; + for (p = vfmt->buffers; p < vfmt->planes; p++) + size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p]; + dprintk(dev, 1, "%s\n", __func__); if (WARN_ON(NULL == dev->fmt_out)) return -EINVAL; - planes = dev->fmt_out->planes; - if (dev->buf_prepare_error) { /* * Error injection: test what happens if buf_prepare() returns @@ -105,18 +125,13 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb) return -EINVAL; } - if (dev->field_out != V4L2_FIELD_ALTERNATE) - vbuf->field = dev->field_out; - else if (vbuf->field != V4L2_FIELD_TOP && - vbuf->field != V4L2_FIELD_BOTTOM) - return -EINVAL; - for (p = 0; p < planes; p++) { - size = dev->bytesperline_out[p] * dev->fmt_out_rect.height + - vb->planes[p].data_offset; + if (p) + size = dev->bytesperline_out[p] * h; + size += vb->planes[p].data_offset; if (vb2_get_plane_payload(vb, p) < size) { - dprintk(dev, 1, "%s the payload is too small for plane %u (%lu < %lu)\n", + dprintk(dev, 1, "%s the payload is too small for plane %u (%lu < %u)\n", __func__, p, vb2_get_plane_payload(vb, p), size); return -EINVAL; } @@ -188,6 +203,7 @@ static void vid_out_buf_request_complete(struct vb2_buffer *vb) const struct vb2_ops vivid_vid_out_qops = { .queue_setup = vid_out_queue_setup, + .buf_out_validate = vid_out_buf_out_validate, .buf_prepare = vid_out_buf_prepare, .buf_queue = vid_out_buf_queue, .start_streaming = vid_out_start_streaming, @@ -321,7 +337,8 @@ int vivid_g_fmt_vid_out(struct file *file, void *priv, for (p = 0; p < mp->num_planes; p++) { mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p]; mp->plane_fmt[p].sizeimage = - mp->plane_fmt[p].bytesperline * mp->height; + mp->plane_fmt[p].bytesperline * mp->height + + fmt->data_offset[p]; } for (p = fmt->buffers; p < fmt->planes; p++) { unsigned stride = dev->bytesperline_out[p]; @@ -399,7 +416,7 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv, pfmt[p].bytesperline = bytesperline; pfmt[p].sizeimage = (pfmt[p].bytesperline * mp->height) / - fmt->vdownsampling[p]; + fmt->vdownsampling[p] + fmt->data_offset[p]; memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); } |