diff options
Diffstat (limited to 'drivers/media/platform/vivid/vivid-core.c')
-rw-r--r-- | drivers/media/platform/vivid/vivid-core.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index 626e2b24a403..c931f007e5b0 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -324,13 +324,14 @@ static int vidioc_s_dv_timings(struct file *file, void *fh, struct v4l2_dv_timin return vivid_vid_out_s_dv_timings(file, fh, timings); } -static int vidioc_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cc) +static int vidioc_g_pixelaspect(struct file *file, void *fh, + int type, struct v4l2_fract *f) { struct video_device *vdev = video_devdata(file); if (vdev->vfl_dir == VFL_DIR_RX) - return vivid_vid_cap_cropcap(file, fh, cc); - return vivid_vid_out_cropcap(file, fh, cc); + return vivid_vid_cap_g_pixelaspect(file, fh, type, f); + return vivid_vid_out_g_pixelaspect(file, fh, type, f); } static int vidioc_g_selection(struct file *file, void *fh, @@ -519,7 +520,7 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = { .vidioc_g_selection = vidioc_g_selection, .vidioc_s_selection = vidioc_s_selection, - .vidioc_cropcap = vidioc_cropcap, + .vidioc_g_pixelaspect = vidioc_g_pixelaspect, .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, @@ -624,12 +625,24 @@ static void vivid_dev_release(struct v4l2_device *v4l2_dev) vfree(dev->bitmap_out); tpg_free(&dev->tpg); kfree(dev->query_dv_timings_qmenu); + kfree(dev->query_dv_timings_qmenu_strings); kfree(dev); } #ifdef CONFIG_MEDIA_CONTROLLER +static int vivid_req_validate(struct media_request *req) +{ + struct vivid_dev *dev = container_of(req->mdev, struct vivid_dev, mdev); + + if (dev->req_validate_error) { + dev->req_validate_error = false; + return -EINVAL; + } + return vb2_request_validate(req); +} + static const struct media_device_ops vivid_media_ops = { - .req_validate = vb2_request_validate, + .req_validate = vivid_req_validate, .req_queue = vb2_request_queue, }; #endif @@ -669,6 +682,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) /* Initialize media device */ strlcpy(dev->mdev.model, VIVID_MODULE_NAME, sizeof(dev->mdev.model)); + snprintf(dev->mdev.bus_info, sizeof(dev->mdev.bus_info), + "platform:%s-%03d", VIVID_MODULE_NAME, inst); dev->mdev.dev = &pdev->dev; media_device_init(&dev->mdev); dev->mdev.ops = &vivid_media_ops; @@ -873,20 +888,31 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) if (!dev->edid) goto free_dev; - /* create a string array containing the names of all the preset timings */ while (v4l2_dv_timings_presets[dev->query_dv_timings_size].bt.width) dev->query_dv_timings_size++; + + /* + * Create a char pointer array that points to the names of all the + * preset timings + */ dev->query_dv_timings_qmenu = kmalloc_array(dev->query_dv_timings_size, - (sizeof(void *) + 32), - GFP_KERNEL); - if (dev->query_dv_timings_qmenu == NULL) + sizeof(char *), GFP_KERNEL); + /* + * Create a string array containing the names of all the preset + * timings. Each name is max 31 chars long (+ terminating 0). + */ + dev->query_dv_timings_qmenu_strings = + kmalloc_array(dev->query_dv_timings_size, 32, GFP_KERNEL); + + if (!dev->query_dv_timings_qmenu || + !dev->query_dv_timings_qmenu_strings) goto free_dev; + for (i = 0; i < dev->query_dv_timings_size; i++) { const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt; - char *p = (char *)&dev->query_dv_timings_qmenu[dev->query_dv_timings_size]; + char *p = dev->query_dv_timings_qmenu_strings + i * 32; u32 htot, vtot; - p += i * 32; dev->query_dv_timings_qmenu[i] = p; htot = V4L2_DV_BT_FRAME_WIDTH(bt); |