1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * vivid-vid-cap.c - video capture support functions. 4 * 5 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 6 */ 7 8 #include <linux/errno.h> 9 #include <linux/kernel.h> 10 #include <linux/sched.h> 11 #include <linux/vmalloc.h> 12 #include <linux/videodev2.h> 13 #include <linux/v4l2-dv-timings.h> 14 #include <media/v4l2-common.h> 15 #include <media/v4l2-event.h> 16 #include <media/v4l2-dv-timings.h> 17 #include <media/v4l2-rect.h> 18 19 #include "vivid-core.h" 20 #include "vivid-vid-common.h" 21 #include "vivid-kthread-cap.h" 22 #include "vivid-vid-cap.h" 23 24 /* Sizes must be in increasing order */ 25 static const struct v4l2_frmsize_discrete webcam_sizes[] = { 26 { 320, 180 }, 27 { 640, 360 }, 28 { 640, 480 }, 29 { 1280, 720 }, 30 { 1920, 1080 }, 31 { 3840, 2160 }, 32 }; 33 34 /* 35 * Intervals must be in increasing order and there must be twice as many 36 * elements in this array as there are in webcam_sizes. 37 */ 38 static const struct v4l2_fract webcam_intervals[] = { 39 { 1, 1 }, 40 { 1, 2 }, 41 { 1, 4 }, 42 { 1, 5 }, 43 { 1, 10 }, 44 { 2, 25 }, 45 { 1, 15 }, /* 7 - maximum for 2160p */ 46 { 1, 25 }, 47 { 1, 30 }, /* 9 - maximum for 1080p */ 48 { 1, 40 }, 49 { 1, 50 }, 50 { 1, 60 }, /* 12 - maximum for 720p */ 51 { 1, 120 }, 52 }; 53 54 /* Limit maximum FPS rates for high resolutions */ 55 #define IVAL_COUNT_720P 12 /* 720p and up is limited to 60 fps */ 56 #define IVAL_COUNT_1080P 9 /* 1080p and up is limited to 30 fps */ 57 #define IVAL_COUNT_2160P 7 /* 2160p and up is limited to 15 fps */ 58 59 static inline unsigned int webcam_ival_count(const struct vivid_dev *dev, 60 unsigned int frmsize_idx) 61 { 62 if (webcam_sizes[frmsize_idx].height >= 2160) 63 return IVAL_COUNT_2160P; 64 65 if (webcam_sizes[frmsize_idx].height >= 1080) 66 return IVAL_COUNT_1080P; 67 68 if (webcam_sizes[frmsize_idx].height >= 720) 69 return IVAL_COUNT_720P; 70 71 /* For low resolutions, allow all FPS rates */ 72 return ARRAY_SIZE(webcam_intervals); 73 } 74 75 static int vid_cap_queue_setup(struct vb2_queue *vq, 76 unsigned *nbuffers, unsigned *nplanes, 77 unsigned sizes[], struct device *alloc_devs[]) 78 { 79 struct vivid_dev *dev = vb2_get_drv_priv(vq); 80 unsigned buffers = tpg_g_buffers(&dev->tpg); 81 unsigned h = dev->fmt_cap_rect.height; 82 unsigned p; 83 84 if (dev->field_cap == V4L2_FIELD_ALTERNATE) { 85 /* 86 * You cannot use read() with FIELD_ALTERNATE since the field 87 * information (TOP/BOTTOM) cannot be passed back to the user. 88 */ 89 if (vb2_fileio_is_active(vq)) 90 return -EINVAL; 91 } 92 93 if (dev->queue_setup_error) { 94 /* 95 * Error injection: test what happens if queue_setup() returns 96 * an error. 97 */ 98 dev->queue_setup_error = false; 99 return -EINVAL; 100 } 101 if (*nplanes) { 102 /* 103 * Check if the number of requested planes match 104 * the number of buffers in the current format. You can't mix that. 105 */ 106 if (*nplanes != buffers) 107 return -EINVAL; 108 for (p = 0; p < buffers; p++) { 109 if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h + 110 dev->fmt_cap->data_offset[p]) 111 return -EINVAL; 112 } 113 } else { 114 for (p = 0; p < buffers; p++) 115 sizes[p] = (tpg_g_line_width(&dev->tpg, p) * h) / 116 dev->fmt_cap->vdownsampling[p] + 117 dev->fmt_cap->data_offset[p]; 118 } 119 120 *nplanes = buffers; 121 122 dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers); 123 for (p = 0; p < buffers; p++) 124 dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]); 125 126 return 0; 127 } 128 129 static int vid_cap_buf_prepare(struct vb2_buffer *vb) 130 { 131 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 132 unsigned long size; 133 unsigned buffers = tpg_g_buffers(&dev->tpg); 134 unsigned p; 135 136 dprintk(dev, 1, "%s\n", __func__); 137 138 if (WARN_ON(NULL == dev->fmt_cap)) 139 return -EINVAL; 140 141 if (dev->buf_prepare_error) { 142 /* 143 * Error injection: test what happens if buf_prepare() returns 144 * an error. 145 */ 146 dev->buf_prepare_error = false; 147 return -EINVAL; 148 } 149 for (p = 0; p < buffers; p++) { 150 size = (tpg_g_line_width(&dev->tpg, p) * 151 dev->fmt_cap_rect.height) / 152 dev->fmt_cap->vdownsampling[p] + 153 dev->fmt_cap->data_offset[p]; 154 155 if (vb2_plane_size(vb, p) < size) { 156 dprintk(dev, 1, "%s data will not fit into plane %u (%lu < %lu)\n", 157 __func__, p, vb2_plane_size(vb, p), size); 158 return -EINVAL; 159 } 160 161 vb2_set_plane_payload(vb, p, size); 162 vb->planes[p].data_offset = dev->fmt_cap->data_offset[p]; 163 } 164 165 return 0; 166 } 167 168 static void vid_cap_buf_finish(struct vb2_buffer *vb) 169 { 170 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 171 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 172 struct v4l2_timecode *tc = &vbuf->timecode; 173 unsigned fps = 25; 174 unsigned seq = vbuf->sequence; 175 176 if (!vivid_is_sdtv_cap(dev)) 177 return; 178 179 /* 180 * Set the timecode. Rarely used, so it is interesting to 181 * test this. 182 */ 183 vbuf->flags |= V4L2_BUF_FLAG_TIMECODE; 184 if (dev->std_cap[dev->input] & V4L2_STD_525_60) 185 fps = 30; 186 tc->type = (fps == 30) ? V4L2_TC_TYPE_30FPS : V4L2_TC_TYPE_25FPS; 187 tc->flags = 0; 188 tc->frames = seq % fps; 189 tc->seconds = (seq / fps) % 60; 190 tc->minutes = (seq / (60 * fps)) % 60; 191 tc->hours = (seq / (60 * 60 * fps)) % 24; 192 } 193 194 static void vid_cap_buf_queue(struct vb2_buffer *vb) 195 { 196 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 197 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 198 struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb); 199 200 dprintk(dev, 1, "%s\n", __func__); 201 202 spin_lock(&dev->slock); 203 list_add_tail(&buf->list, &dev->vid_cap_active); 204 spin_unlock(&dev->slock); 205 } 206 207 static int vid_cap_start_streaming(struct vb2_queue *vq, unsigned count) 208 { 209 struct vivid_dev *dev = vb2_get_drv_priv(vq); 210 unsigned i; 211 int err; 212 213 if (vb2_is_streaming(&dev->vb_vid_out_q)) 214 dev->can_loop_video = vivid_vid_can_loop(dev); 215 216 dev->vid_cap_seq_count = 0; 217 dprintk(dev, 1, "%s\n", __func__); 218 for (i = 0; i < VIDEO_MAX_FRAME; i++) 219 dev->must_blank[i] = tpg_g_perc_fill(&dev->tpg) < 100; 220 if (dev->start_streaming_error) { 221 dev->start_streaming_error = false; 222 err = -EINVAL; 223 } else { 224 err = vivid_start_generating_vid_cap(dev, &dev->vid_cap_streaming); 225 } 226 if (err) { 227 struct vivid_buffer *buf, *tmp; 228 229 list_for_each_entry_safe(buf, tmp, &dev->vid_cap_active, list) { 230 list_del(&buf->list); 231 vb2_buffer_done(&buf->vb.vb2_buf, 232 VB2_BUF_STATE_QUEUED); 233 } 234 } 235 return err; 236 } 237 238 /* abort streaming and wait for last buffer */ 239 static void vid_cap_stop_streaming(struct vb2_queue *vq) 240 { 241 struct vivid_dev *dev = vb2_get_drv_priv(vq); 242 243 dprintk(dev, 1, "%s\n", __func__); 244 vivid_stop_generating_vid_cap(dev, &dev->vid_cap_streaming); 245 dev->can_loop_video = false; 246 } 247 248 static void vid_cap_buf_request_complete(struct vb2_buffer *vb) 249 { 250 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 251 252 v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vid_cap); 253 } 254 255 const struct vb2_ops vivid_vid_cap_qops = { 256 .queue_setup = vid_cap_queue_setup, 257 .buf_prepare = vid_cap_buf_prepare, 258 .buf_finish = vid_cap_buf_finish, 259 .buf_queue = vid_cap_buf_queue, 260 .start_streaming = vid_cap_start_streaming, 261 .stop_streaming = vid_cap_stop_streaming, 262 .buf_request_complete = vid_cap_buf_request_complete, 263 .wait_prepare = vb2_ops_wait_prepare, 264 .wait_finish = vb2_ops_wait_finish, 265 }; 266 267 /* 268 * Determine the 'picture' quality based on the current TV frequency: either 269 * COLOR for a good 'signal', GRAY (grayscale picture) for a slightly off 270 * signal or NOISE for no signal. 271 */ 272 void vivid_update_quality(struct vivid_dev *dev) 273 { 274 unsigned freq_modulus; 275 276 if (dev->loop_video && (vivid_is_svid_cap(dev) || vivid_is_hdmi_cap(dev))) { 277 /* 278 * The 'noise' will only be replaced by the actual video 279 * if the output video matches the input video settings. 280 */ 281 tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0); 282 return; 283 } 284 if (vivid_is_hdmi_cap(dev) && 285 VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode[dev->input])) { 286 tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0); 287 return; 288 } 289 if (vivid_is_sdtv_cap(dev) && 290 VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) { 291 tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 0); 292 return; 293 } 294 if (!vivid_is_tv_cap(dev)) { 295 tpg_s_quality(&dev->tpg, TPG_QUAL_COLOR, 0); 296 return; 297 } 298 299 /* 300 * There is a fake channel every 6 MHz at 49.25, 55.25, etc. 301 * From +/- 0.25 MHz around the channel there is color, and from 302 * +/- 1 MHz there is grayscale (chroma is lost). 303 * Everywhere else it is just noise. 304 */ 305 freq_modulus = (dev->tv_freq - 676 /* (43.25-1) * 16 */) % (6 * 16); 306 if (freq_modulus > 2 * 16) { 307 tpg_s_quality(&dev->tpg, TPG_QUAL_NOISE, 308 next_pseudo_random32(dev->tv_freq ^ 0x55) & 0x3f); 309 return; 310 } 311 if (freq_modulus < 12 /*0.75 * 16*/ || freq_modulus > 20 /*1.25 * 16*/) 312 tpg_s_quality(&dev->tpg, TPG_QUAL_GRAY, 0); 313 else 314 tpg_s_quality(&dev->tpg, TPG_QUAL_COLOR, 0); 315 } 316 317 /* 318 * Get the current picture quality and the associated afc value. 319 */ 320 static enum tpg_quality vivid_get_quality(struct vivid_dev *dev, s32 *afc) 321 { 322 unsigned freq_modulus; 323 324 if (afc) 325 *afc = 0; 326 if (tpg_g_quality(&dev->tpg) == TPG_QUAL_COLOR || 327 tpg_g_quality(&dev->tpg) == TPG_QUAL_NOISE) 328 return tpg_g_quality(&dev->tpg); 329 330 /* 331 * There is a fake channel every 6 MHz at 49.25, 55.25, etc. 332 * From +/- 0.25 MHz around the channel there is color, and from 333 * +/- 1 MHz there is grayscale (chroma is lost). 334 * Everywhere else it is just gray. 335 */ 336 freq_modulus = (dev->tv_freq - 676 /* (43.25-1) * 16 */) % (6 * 16); 337 if (afc) 338 *afc = freq_modulus - 1 * 16; 339 return TPG_QUAL_GRAY; 340 } 341 342 enum tpg_video_aspect vivid_get_video_aspect(const struct vivid_dev *dev) 343 { 344 if (vivid_is_sdtv_cap(dev)) 345 return dev->std_aspect_ratio[dev->input]; 346 347 if (vivid_is_hdmi_cap(dev)) 348 return dev->dv_timings_aspect_ratio[dev->input]; 349 350 return TPG_VIDEO_ASPECT_IMAGE; 351 } 352 353 static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev *dev) 354 { 355 if (vivid_is_sdtv_cap(dev)) 356 return (dev->std_cap[dev->input] & V4L2_STD_525_60) ? 357 TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL; 358 359 if (vivid_is_hdmi_cap(dev) && 360 dev->src_rect.width == 720 && dev->src_rect.height <= 576) 361 return dev->src_rect.height == 480 ? 362 TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL; 363 364 return TPG_PIXEL_ASPECT_SQUARE; 365 } 366 367 /* 368 * Called whenever the format has to be reset which can occur when 369 * changing inputs, standard, timings, etc. 370 */ 371 void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls) 372 { 373 struct v4l2_bt_timings *bt = &dev->dv_timings_cap[dev->input].bt; 374 u32 dims[V4L2_CTRL_MAX_DIMS] = {}; 375 unsigned size; 376 u64 pixelclock; 377 378 switch (dev->input_type[dev->input]) { 379 case WEBCAM: 380 default: 381 dev->src_rect.width = webcam_sizes[dev->webcam_size_idx].width; 382 dev->src_rect.height = webcam_sizes[dev->webcam_size_idx].height; 383 dev->timeperframe_vid_cap = webcam_intervals[dev->webcam_ival_idx]; 384 dev->field_cap = V4L2_FIELD_NONE; 385 tpg_s_rgb_range(&dev->tpg, V4L2_DV_RGB_RANGE_AUTO); 386 break; 387 case TV: 388 case SVID: 389 dev->field_cap = dev->tv_field_cap; 390 dev->src_rect.width = 720; 391 if (dev->std_cap[dev->input] & V4L2_STD_525_60) { 392 dev->src_rect.height = 480; 393 dev->timeperframe_vid_cap = (struct v4l2_fract) { 1001, 30000 }; 394 dev->service_set_cap = V4L2_SLICED_CAPTION_525; 395 } else { 396 dev->src_rect.height = 576; 397 dev->timeperframe_vid_cap = (struct v4l2_fract) { 1000, 25000 }; 398 dev->service_set_cap = V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B; 399 } 400 tpg_s_rgb_range(&dev->tpg, V4L2_DV_RGB_RANGE_AUTO); 401 break; 402 case HDMI: 403 dev->src_rect.width = bt->width; 404 dev->src_rect.height = bt->height; 405 size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt); 406 if (dev->reduced_fps && can_reduce_fps(bt)) { 407 pixelclock = div_u64(bt->pixelclock * 1000, 1001); 408 bt->flags |= V4L2_DV_FL_REDUCED_FPS; 409 } else { 410 pixelclock = bt->pixelclock; 411 bt->flags &= ~V4L2_DV_FL_REDUCED_FPS; 412 } 413 dev->timeperframe_vid_cap = (struct v4l2_fract) { 414 size / 100, (u32)pixelclock / 100 415 }; 416 if (bt->interlaced) 417 dev->field_cap = V4L2_FIELD_ALTERNATE; 418 else 419 dev->field_cap = V4L2_FIELD_NONE; 420 421 /* 422 * We can be called from within s_ctrl, in that case we can't 423 * set/get controls. Luckily we don't need to in that case. 424 */ 425 if (keep_controls || !dev->colorspace) 426 break; 427 if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) { 428 if (bt->width == 720 && bt->height <= 576) 429 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); 430 else 431 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_709); 432 v4l2_ctrl_s_ctrl(dev->real_rgb_range_cap, 1); 433 } else { 434 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB); 435 v4l2_ctrl_s_ctrl(dev->real_rgb_range_cap, 0); 436 } 437 tpg_s_rgb_range(&dev->tpg, v4l2_ctrl_g_ctrl(dev->rgb_range_cap)); 438 break; 439 } 440 vivid_update_quality(dev); 441 tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap); 442 dev->crop_cap = dev->src_rect; 443 dev->crop_bounds_cap = dev->src_rect; 444 dev->compose_cap = dev->crop_cap; 445 if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap)) 446 dev->compose_cap.height /= 2; 447 dev->fmt_cap_rect = dev->compose_cap; 448 tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev)); 449 tpg_s_pixel_aspect(&dev->tpg, vivid_get_pixel_aspect(dev)); 450 tpg_update_mv_step(&dev->tpg); 451 452 /* 453 * We can be called from within s_ctrl, in that case we can't 454 * modify controls. Luckily we don't need to in that case. 455 */ 456 if (keep_controls) 457 return; 458 459 dims[0] = roundup(dev->src_rect.width, PIXEL_ARRAY_DIV); 460 dims[1] = roundup(dev->src_rect.height, PIXEL_ARRAY_DIV); 461 v4l2_ctrl_modify_dimensions(dev->pixel_array, dims); 462 } 463 464 /* Map the field to something that is valid for the current input */ 465 static enum v4l2_field vivid_field_cap(struct vivid_dev *dev, enum v4l2_field field) 466 { 467 if (vivid_is_sdtv_cap(dev)) { 468 switch (field) { 469 case V4L2_FIELD_INTERLACED_TB: 470 case V4L2_FIELD_INTERLACED_BT: 471 case V4L2_FIELD_SEQ_TB: 472 case V4L2_FIELD_SEQ_BT: 473 case V4L2_FIELD_TOP: 474 case V4L2_FIELD_BOTTOM: 475 case V4L2_FIELD_ALTERNATE: 476 return field; 477 case V4L2_FIELD_INTERLACED: 478 default: 479 return V4L2_FIELD_INTERLACED; 480 } 481 } 482 if (vivid_is_hdmi_cap(dev)) 483 return dev->dv_timings_cap[dev->input].bt.interlaced ? 484 V4L2_FIELD_ALTERNATE : V4L2_FIELD_NONE; 485 return V4L2_FIELD_NONE; 486 } 487 488 static unsigned vivid_colorspace_cap(struct vivid_dev *dev) 489 { 490 if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) 491 return tpg_g_colorspace(&dev->tpg); 492 return dev->colorspace_out; 493 } 494 495 static unsigned vivid_xfer_func_cap(struct vivid_dev *dev) 496 { 497 if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) 498 return tpg_g_xfer_func(&dev->tpg); 499 return dev->xfer_func_out; 500 } 501 502 static unsigned vivid_ycbcr_enc_cap(struct vivid_dev *dev) 503 { 504 if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) 505 return tpg_g_ycbcr_enc(&dev->tpg); 506 return dev->ycbcr_enc_out; 507 } 508 509 static unsigned int vivid_hsv_enc_cap(struct vivid_dev *dev) 510 { 511 if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) 512 return tpg_g_hsv_enc(&dev->tpg); 513 return dev->hsv_enc_out; 514 } 515 516 static unsigned vivid_quantization_cap(struct vivid_dev *dev) 517 { 518 if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) 519 return tpg_g_quantization(&dev->tpg); 520 return dev->quantization_out; 521 } 522 523 int vivid_g_fmt_vid_cap(struct file *file, void *priv, 524 struct v4l2_format *f) 525 { 526 struct vivid_dev *dev = video_drvdata(file); 527 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 528 unsigned p; 529 530 mp->width = dev->fmt_cap_rect.width; 531 mp->height = dev->fmt_cap_rect.height; 532 mp->field = dev->field_cap; 533 mp->pixelformat = dev->fmt_cap->fourcc; 534 mp->colorspace = vivid_colorspace_cap(dev); 535 mp->xfer_func = vivid_xfer_func_cap(dev); 536 if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_HSV) 537 mp->hsv_enc = vivid_hsv_enc_cap(dev); 538 else 539 mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); 540 mp->quantization = vivid_quantization_cap(dev); 541 mp->num_planes = dev->fmt_cap->buffers; 542 for (p = 0; p < mp->num_planes; p++) { 543 mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p); 544 mp->plane_fmt[p].sizeimage = 545 (tpg_g_line_width(&dev->tpg, p) * mp->height) / 546 dev->fmt_cap->vdownsampling[p] + 547 dev->fmt_cap->data_offset[p]; 548 } 549 return 0; 550 } 551 552 int vivid_try_fmt_vid_cap(struct file *file, void *priv, 553 struct v4l2_format *f) 554 { 555 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 556 struct v4l2_plane_pix_format *pfmt = mp->plane_fmt; 557 struct vivid_dev *dev = video_drvdata(file); 558 const struct vivid_fmt *fmt; 559 unsigned bytesperline, max_bpl; 560 unsigned factor = 1; 561 unsigned w, h; 562 unsigned p; 563 bool user_set_csc = !!(mp->flags & V4L2_PIX_FMT_FLAG_SET_CSC); 564 565 fmt = vivid_get_format(dev, mp->pixelformat); 566 if (!fmt) { 567 dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n", 568 mp->pixelformat); 569 mp->pixelformat = V4L2_PIX_FMT_YUYV; 570 fmt = vivid_get_format(dev, mp->pixelformat); 571 } 572 573 mp->field = vivid_field_cap(dev, mp->field); 574 if (vivid_is_webcam(dev)) { 575 const struct v4l2_frmsize_discrete *sz = 576 v4l2_find_nearest_size(webcam_sizes, 577 ARRAY_SIZE(webcam_sizes), width, 578 height, mp->width, mp->height); 579 580 w = sz->width; 581 h = sz->height; 582 } else if (vivid_is_sdtv_cap(dev)) { 583 w = 720; 584 h = (dev->std_cap[dev->input] & V4L2_STD_525_60) ? 480 : 576; 585 } else { 586 w = dev->src_rect.width; 587 h = dev->src_rect.height; 588 } 589 if (V4L2_FIELD_HAS_T_OR_B(mp->field)) 590 factor = 2; 591 if (vivid_is_webcam(dev) || 592 (!dev->has_scaler_cap && !dev->has_crop_cap && !dev->has_compose_cap)) { 593 mp->width = w; 594 mp->height = h / factor; 595 } else { 596 struct v4l2_rect r = { 0, 0, mp->width, mp->height * factor }; 597 598 v4l2_rect_set_min_size(&r, &vivid_min_rect); 599 v4l2_rect_set_max_size(&r, &vivid_max_rect); 600 if (dev->has_scaler_cap && !dev->has_compose_cap) { 601 struct v4l2_rect max_r = { 0, 0, MAX_ZOOM * w, MAX_ZOOM * h }; 602 603 v4l2_rect_set_max_size(&r, &max_r); 604 } else if (!dev->has_scaler_cap && dev->has_crop_cap && !dev->has_compose_cap) { 605 v4l2_rect_set_max_size(&r, &dev->src_rect); 606 } else if (!dev->has_scaler_cap && !dev->has_crop_cap) { 607 v4l2_rect_set_min_size(&r, &dev->src_rect); 608 } 609 mp->width = r.width; 610 mp->height = r.height / factor; 611 } 612 613 /* This driver supports custom bytesperline values */ 614 615 mp->num_planes = fmt->buffers; 616 for (p = 0; p < fmt->buffers; p++) { 617 /* Calculate the minimum supported bytesperline value */ 618 bytesperline = (mp->width * fmt->bit_depth[p]) >> 3; 619 /* Calculate the maximum supported bytesperline value */ 620 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3; 621 622 if (pfmt[p].bytesperline > max_bpl) 623 pfmt[p].bytesperline = max_bpl; 624 if (pfmt[p].bytesperline < bytesperline) 625 pfmt[p].bytesperline = bytesperline; 626 627 pfmt[p].sizeimage = (pfmt[p].bytesperline * mp->height) / 628 fmt->vdownsampling[p] + fmt->data_offset[p]; 629 630 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 631 } 632 for (p = fmt->buffers; p < fmt->planes; p++) 633 pfmt[0].sizeimage += (pfmt[0].bytesperline * mp->height * 634 (fmt->bit_depth[p] / fmt->vdownsampling[p])) / 635 (fmt->bit_depth[0] / fmt->vdownsampling[0]); 636 637 if (!user_set_csc || !v4l2_is_colorspace_valid(mp->colorspace)) 638 mp->colorspace = vivid_colorspace_cap(dev); 639 640 if (!user_set_csc || !v4l2_is_xfer_func_valid(mp->xfer_func)) 641 mp->xfer_func = vivid_xfer_func_cap(dev); 642 643 if (fmt->color_enc == TGP_COLOR_ENC_HSV) { 644 if (!user_set_csc || !v4l2_is_hsv_enc_valid(mp->hsv_enc)) 645 mp->hsv_enc = vivid_hsv_enc_cap(dev); 646 } else if (fmt->color_enc == TGP_COLOR_ENC_YCBCR) { 647 if (!user_set_csc || !v4l2_is_ycbcr_enc_valid(mp->ycbcr_enc)) 648 mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); 649 } else { 650 mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); 651 } 652 653 if (fmt->color_enc == TGP_COLOR_ENC_YCBCR || 654 fmt->color_enc == TGP_COLOR_ENC_RGB) { 655 if (!user_set_csc || !v4l2_is_quant_valid(mp->quantization)) 656 mp->quantization = vivid_quantization_cap(dev); 657 } else { 658 mp->quantization = vivid_quantization_cap(dev); 659 } 660 661 memset(mp->reserved, 0, sizeof(mp->reserved)); 662 return 0; 663 } 664 665 int vivid_s_fmt_vid_cap(struct file *file, void *priv, 666 struct v4l2_format *f) 667 { 668 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 669 struct vivid_dev *dev = video_drvdata(file); 670 struct v4l2_rect *crop = &dev->crop_cap; 671 struct v4l2_rect *compose = &dev->compose_cap; 672 struct vb2_queue *q = &dev->vb_vid_cap_q; 673 int ret = vivid_try_fmt_vid_cap(file, priv, f); 674 unsigned factor = 1; 675 unsigned p; 676 unsigned i; 677 678 if (ret < 0) 679 return ret; 680 681 if (vb2_is_busy(q)) { 682 dprintk(dev, 1, "%s device busy\n", __func__); 683 return -EBUSY; 684 } 685 686 dev->fmt_cap = vivid_get_format(dev, mp->pixelformat); 687 if (V4L2_FIELD_HAS_T_OR_B(mp->field)) 688 factor = 2; 689 690 /* Note: the webcam input doesn't support scaling, cropping or composing */ 691 692 if (!vivid_is_webcam(dev) && 693 (dev->has_scaler_cap || dev->has_crop_cap || dev->has_compose_cap)) { 694 struct v4l2_rect r = { 0, 0, mp->width, mp->height }; 695 696 if (dev->has_scaler_cap) { 697 if (dev->has_compose_cap) 698 v4l2_rect_map_inside(compose, &r); 699 else 700 *compose = r; 701 if (dev->has_crop_cap && !dev->has_compose_cap) { 702 struct v4l2_rect min_r = { 703 0, 0, 704 r.width / MAX_ZOOM, 705 factor * r.height / MAX_ZOOM 706 }; 707 struct v4l2_rect max_r = { 708 0, 0, 709 r.width * MAX_ZOOM, 710 factor * r.height * MAX_ZOOM 711 }; 712 713 v4l2_rect_set_min_size(crop, &min_r); 714 v4l2_rect_set_max_size(crop, &max_r); 715 v4l2_rect_map_inside(crop, &dev->crop_bounds_cap); 716 } else if (dev->has_crop_cap) { 717 struct v4l2_rect min_r = { 718 0, 0, 719 compose->width / MAX_ZOOM, 720 factor * compose->height / MAX_ZOOM 721 }; 722 struct v4l2_rect max_r = { 723 0, 0, 724 compose->width * MAX_ZOOM, 725 factor * compose->height * MAX_ZOOM 726 }; 727 728 v4l2_rect_set_min_size(crop, &min_r); 729 v4l2_rect_set_max_size(crop, &max_r); 730 v4l2_rect_map_inside(crop, &dev->crop_bounds_cap); 731 } 732 } else if (dev->has_crop_cap && !dev->has_compose_cap) { 733 r.height *= factor; 734 v4l2_rect_set_size_to(crop, &r); 735 v4l2_rect_map_inside(crop, &dev->crop_bounds_cap); 736 r = *crop; 737 r.height /= factor; 738 v4l2_rect_set_size_to(compose, &r); 739 } else if (!dev->has_crop_cap) { 740 v4l2_rect_map_inside(compose, &r); 741 } else { 742 r.height *= factor; 743 v4l2_rect_set_max_size(crop, &r); 744 v4l2_rect_map_inside(crop, &dev->crop_bounds_cap); 745 compose->top *= factor; 746 compose->height *= factor; 747 v4l2_rect_set_size_to(compose, crop); 748 v4l2_rect_map_inside(compose, &r); 749 compose->top /= factor; 750 compose->height /= factor; 751 } 752 } else if (vivid_is_webcam(dev)) { 753 unsigned int ival_sz = webcam_ival_count(dev, dev->webcam_size_idx); 754 755 /* Guaranteed to be a match */ 756 for (i = 0; i < ARRAY_SIZE(webcam_sizes); i++) 757 if (webcam_sizes[i].width == mp->width && 758 webcam_sizes[i].height == mp->height) 759 break; 760 dev->webcam_size_idx = i; 761 if (dev->webcam_ival_idx >= ival_sz) 762 dev->webcam_ival_idx = ival_sz - 1; 763 vivid_update_format_cap(dev, false); 764 } else { 765 struct v4l2_rect r = { 0, 0, mp->width, mp->height }; 766 767 v4l2_rect_set_size_to(compose, &r); 768 r.height *= factor; 769 v4l2_rect_set_size_to(crop, &r); 770 } 771 772 dev->fmt_cap_rect.width = mp->width; 773 dev->fmt_cap_rect.height = mp->height; 774 tpg_s_buf_height(&dev->tpg, mp->height); 775 tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc); 776 for (p = 0; p < tpg_g_buffers(&dev->tpg); p++) 777 tpg_s_bytesperline(&dev->tpg, p, mp->plane_fmt[p].bytesperline); 778 dev->field_cap = mp->field; 779 if (dev->field_cap == V4L2_FIELD_ALTERNATE) 780 tpg_s_field(&dev->tpg, V4L2_FIELD_TOP, true); 781 else 782 tpg_s_field(&dev->tpg, dev->field_cap, false); 783 tpg_s_crop_compose(&dev->tpg, &dev->crop_cap, &dev->compose_cap); 784 if (vivid_is_sdtv_cap(dev)) 785 dev->tv_field_cap = mp->field; 786 tpg_update_mv_step(&dev->tpg); 787 dev->tpg.colorspace = mp->colorspace; 788 dev->tpg.xfer_func = mp->xfer_func; 789 if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_YCBCR) 790 dev->tpg.ycbcr_enc = mp->ycbcr_enc; 791 else 792 dev->tpg.hsv_enc = mp->hsv_enc; 793 dev->tpg.quantization = mp->quantization; 794 795 return 0; 796 } 797 798 int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *priv, 799 struct v4l2_format *f) 800 { 801 struct vivid_dev *dev = video_drvdata(file); 802 803 if (!dev->multiplanar) 804 return -ENOTTY; 805 return vivid_g_fmt_vid_cap(file, priv, f); 806 } 807 808 int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, 809 struct v4l2_format *f) 810 { 811 struct vivid_dev *dev = video_drvdata(file); 812 813 if (!dev->multiplanar) 814 return -ENOTTY; 815 return vivid_try_fmt_vid_cap(file, priv, f); 816 } 817 818 int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv, 819 struct v4l2_format *f) 820 { 821 struct vivid_dev *dev = video_drvdata(file); 822 823 if (!dev->multiplanar) 824 return -ENOTTY; 825 return vivid_s_fmt_vid_cap(file, priv, f); 826 } 827 828 int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 829 struct v4l2_format *f) 830 { 831 struct vivid_dev *dev = video_drvdata(file); 832 833 if (dev->multiplanar) 834 return -ENOTTY; 835 return fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_cap); 836 } 837 838 int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 839 struct v4l2_format *f) 840 { 841 struct vivid_dev *dev = video_drvdata(file); 842 843 if (dev->multiplanar) 844 return -ENOTTY; 845 return fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_cap); 846 } 847 848 int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 849 struct v4l2_format *f) 850 { 851 struct vivid_dev *dev = video_drvdata(file); 852 853 if (dev->multiplanar) 854 return -ENOTTY; 855 return fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_cap); 856 } 857 858 int vivid_vid_cap_g_selection(struct file *file, void *priv, 859 struct v4l2_selection *sel) 860 { 861 struct vivid_dev *dev = video_drvdata(file); 862 863 if (!dev->has_crop_cap && !dev->has_compose_cap) 864 return -ENOTTY; 865 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 866 return -EINVAL; 867 if (vivid_is_webcam(dev)) 868 return -ENODATA; 869 870 sel->r.left = sel->r.top = 0; 871 switch (sel->target) { 872 case V4L2_SEL_TGT_CROP: 873 if (!dev->has_crop_cap) 874 return -EINVAL; 875 sel->r = dev->crop_cap; 876 break; 877 case V4L2_SEL_TGT_CROP_DEFAULT: 878 case V4L2_SEL_TGT_CROP_BOUNDS: 879 if (!dev->has_crop_cap) 880 return -EINVAL; 881 sel->r = dev->src_rect; 882 break; 883 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 884 if (!dev->has_compose_cap) 885 return -EINVAL; 886 sel->r = vivid_max_rect; 887 break; 888 case V4L2_SEL_TGT_COMPOSE: 889 if (!dev->has_compose_cap) 890 return -EINVAL; 891 sel->r = dev->compose_cap; 892 break; 893 case V4L2_SEL_TGT_COMPOSE_DEFAULT: 894 if (!dev->has_compose_cap) 895 return -EINVAL; 896 sel->r = dev->fmt_cap_rect; 897 break; 898 default: 899 return -EINVAL; 900 } 901 return 0; 902 } 903 904 int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection *s) 905 { 906 struct vivid_dev *dev = video_drvdata(file); 907 struct v4l2_rect *crop = &dev->crop_cap; 908 struct v4l2_rect *compose = &dev->compose_cap; 909 unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1; 910 int ret; 911 912 if (!dev->has_crop_cap && !dev->has_compose_cap) 913 return -ENOTTY; 914 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 915 return -EINVAL; 916 if (vivid_is_webcam(dev)) 917 return -ENODATA; 918 919 switch (s->target) { 920 case V4L2_SEL_TGT_CROP: 921 if (!dev->has_crop_cap) 922 return -EINVAL; 923 ret = vivid_vid_adjust_sel(s->flags, &s->r); 924 if (ret) 925 return ret; 926 v4l2_rect_set_min_size(&s->r, &vivid_min_rect); 927 v4l2_rect_set_max_size(&s->r, &dev->src_rect); 928 v4l2_rect_map_inside(&s->r, &dev->crop_bounds_cap); 929 s->r.top /= factor; 930 s->r.height /= factor; 931 if (dev->has_scaler_cap) { 932 struct v4l2_rect fmt = dev->fmt_cap_rect; 933 struct v4l2_rect max_rect = { 934 0, 0, 935 s->r.width * MAX_ZOOM, 936 s->r.height * MAX_ZOOM 937 }; 938 struct v4l2_rect min_rect = { 939 0, 0, 940 s->r.width / MAX_ZOOM, 941 s->r.height / MAX_ZOOM 942 }; 943 944 v4l2_rect_set_min_size(&fmt, &min_rect); 945 if (!dev->has_compose_cap) 946 v4l2_rect_set_max_size(&fmt, &max_rect); 947 if (!v4l2_rect_same_size(&dev->fmt_cap_rect, &fmt) && 948 vb2_is_busy(&dev->vb_vid_cap_q)) 949 return -EBUSY; 950 if (dev->has_compose_cap) { 951 v4l2_rect_set_min_size(compose, &min_rect); 952 v4l2_rect_set_max_size(compose, &max_rect); 953 v4l2_rect_map_inside(compose, &fmt); 954 } 955 dev->fmt_cap_rect = fmt; 956 tpg_s_buf_height(&dev->tpg, fmt.height); 957 } else if (dev->has_compose_cap) { 958 struct v4l2_rect fmt = dev->fmt_cap_rect; 959 960 v4l2_rect_set_min_size(&fmt, &s->r); 961 if (!v4l2_rect_same_size(&dev->fmt_cap_rect, &fmt) && 962 vb2_is_busy(&dev->vb_vid_cap_q)) 963 return -EBUSY; 964 dev->fmt_cap_rect = fmt; 965 tpg_s_buf_height(&dev->tpg, fmt.height); 966 v4l2_rect_set_size_to(compose, &s->r); 967 v4l2_rect_map_inside(compose, &dev->fmt_cap_rect); 968 } else { 969 if (!v4l2_rect_same_size(&s->r, &dev->fmt_cap_rect) && 970 vb2_is_busy(&dev->vb_vid_cap_q)) 971 return -EBUSY; 972 v4l2_rect_set_size_to(&dev->fmt_cap_rect, &s->r); 973 v4l2_rect_set_size_to(compose, &s->r); 974 v4l2_rect_map_inside(compose, &dev->fmt_cap_rect); 975 tpg_s_buf_height(&dev->tpg, dev->fmt_cap_rect.height); 976 } 977 s->r.top *= factor; 978 s->r.height *= factor; 979 *crop = s->r; 980 break; 981 case V4L2_SEL_TGT_COMPOSE: 982 if (!dev->has_compose_cap) 983 return -EINVAL; 984 ret = vivid_vid_adjust_sel(s->flags, &s->r); 985 if (ret) 986 return ret; 987 v4l2_rect_set_min_size(&s->r, &vivid_min_rect); 988 v4l2_rect_set_max_size(&s->r, &dev->fmt_cap_rect); 989 if (dev->has_scaler_cap) { 990 struct v4l2_rect max_rect = { 991 0, 0, 992 dev->src_rect.width * MAX_ZOOM, 993 (dev->src_rect.height / factor) * MAX_ZOOM 994 }; 995 996 v4l2_rect_set_max_size(&s->r, &max_rect); 997 if (dev->has_crop_cap) { 998 struct v4l2_rect min_rect = { 999 0, 0, 1000 s->r.width / MAX_ZOOM, 1001 (s->r.height * factor) / MAX_ZOOM 1002 }; 1003 struct v4l2_rect max_rect = { 1004 0, 0, 1005 s->r.width * MAX_ZOOM, 1006 (s->r.height * factor) * MAX_ZOOM 1007 }; 1008 1009 v4l2_rect_set_min_size(crop, &min_rect); 1010 v4l2_rect_set_max_size(crop, &max_rect); 1011 v4l2_rect_map_inside(crop, &dev->crop_bounds_cap); 1012 } 1013 } else if (dev->has_crop_cap) { 1014 s->r.top *= factor; 1015 s->r.height *= factor; 1016 v4l2_rect_set_max_size(&s->r, &dev->src_rect); 1017 v4l2_rect_set_size_to(crop, &s->r); 1018 v4l2_rect_map_inside(crop, &dev->crop_bounds_cap); 1019 s->r.top /= factor; 1020 s->r.height /= factor; 1021 } else { 1022 v4l2_rect_set_size_to(&s->r, &dev->src_rect); 1023 s->r.height /= factor; 1024 } 1025 v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect); 1026 *compose = s->r; 1027 break; 1028 default: 1029 return -EINVAL; 1030 } 1031 1032 tpg_s_crop_compose(&dev->tpg, crop, compose); 1033 return 0; 1034 } 1035 1036 int vivid_vid_cap_g_pixelaspect(struct file *file, void *priv, 1037 int type, struct v4l2_fract *f) 1038 { 1039 struct vivid_dev *dev = video_drvdata(file); 1040 1041 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1042 return -EINVAL; 1043 1044 switch (vivid_get_pixel_aspect(dev)) { 1045 case TPG_PIXEL_ASPECT_NTSC: 1046 f->numerator = 11; 1047 f->denominator = 10; 1048 break; 1049 case TPG_PIXEL_ASPECT_PAL: 1050 f->numerator = 54; 1051 f->denominator = 59; 1052 break; 1053 default: 1054 break; 1055 } 1056 return 0; 1057 } 1058 1059 static const struct v4l2_audio vivid_audio_inputs[] = { 1060 { 0, "TV", V4L2_AUDCAP_STEREO }, 1061 { 1, "Line-In", V4L2_AUDCAP_STEREO }, 1062 }; 1063 1064 int vidioc_enum_input(struct file *file, void *priv, 1065 struct v4l2_input *inp) 1066 { 1067 struct vivid_dev *dev = video_drvdata(file); 1068 1069 if (inp->index >= dev->num_inputs) 1070 return -EINVAL; 1071 1072 inp->type = V4L2_INPUT_TYPE_CAMERA; 1073 switch (dev->input_type[inp->index]) { 1074 case WEBCAM: 1075 snprintf(inp->name, sizeof(inp->name), "Webcam %u", 1076 dev->input_name_counter[inp->index]); 1077 inp->capabilities = 0; 1078 break; 1079 case TV: 1080 snprintf(inp->name, sizeof(inp->name), "TV %u", 1081 dev->input_name_counter[inp->index]); 1082 inp->type = V4L2_INPUT_TYPE_TUNER; 1083 inp->std = V4L2_STD_ALL; 1084 if (dev->has_audio_inputs) 1085 inp->audioset = (1 << ARRAY_SIZE(vivid_audio_inputs)) - 1; 1086 inp->capabilities = V4L2_IN_CAP_STD; 1087 break; 1088 case SVID: 1089 snprintf(inp->name, sizeof(inp->name), "S-Video %u", 1090 dev->input_name_counter[inp->index]); 1091 inp->std = V4L2_STD_ALL; 1092 if (dev->has_audio_inputs) 1093 inp->audioset = (1 << ARRAY_SIZE(vivid_audio_inputs)) - 1; 1094 inp->capabilities = V4L2_IN_CAP_STD; 1095 break; 1096 case HDMI: 1097 snprintf(inp->name, sizeof(inp->name), "HDMI %u", 1098 dev->input_name_counter[inp->index]); 1099 inp->capabilities = V4L2_IN_CAP_DV_TIMINGS; 1100 if (dev->edid_blocks == 0 || 1101 dev->dv_timings_signal_mode[dev->input] == NO_SIGNAL) 1102 inp->status |= V4L2_IN_ST_NO_SIGNAL; 1103 else if (dev->dv_timings_signal_mode[dev->input] == NO_LOCK || 1104 dev->dv_timings_signal_mode[dev->input] == OUT_OF_RANGE) 1105 inp->status |= V4L2_IN_ST_NO_H_LOCK; 1106 break; 1107 } 1108 if (dev->sensor_hflip) 1109 inp->status |= V4L2_IN_ST_HFLIP; 1110 if (dev->sensor_vflip) 1111 inp->status |= V4L2_IN_ST_VFLIP; 1112 if (dev->input == inp->index && vivid_is_sdtv_cap(dev)) { 1113 if (dev->std_signal_mode[dev->input] == NO_SIGNAL) { 1114 inp->status |= V4L2_IN_ST_NO_SIGNAL; 1115 } else if (dev->std_signal_mode[dev->input] == NO_LOCK) { 1116 inp->status |= V4L2_IN_ST_NO_H_LOCK; 1117 } else if (vivid_is_tv_cap(dev)) { 1118 switch (tpg_g_quality(&dev->tpg)) { 1119 case TPG_QUAL_GRAY: 1120 inp->status |= V4L2_IN_ST_COLOR_KILL; 1121 break; 1122 case TPG_QUAL_NOISE: 1123 inp->status |= V4L2_IN_ST_NO_H_LOCK; 1124 break; 1125 default: 1126 break; 1127 } 1128 } 1129 } 1130 return 0; 1131 } 1132 1133 int vidioc_g_input(struct file *file, void *priv, unsigned *i) 1134 { 1135 struct vivid_dev *dev = video_drvdata(file); 1136 1137 *i = dev->input; 1138 return 0; 1139 } 1140 1141 int vidioc_s_input(struct file *file, void *priv, unsigned i) 1142 { 1143 struct vivid_dev *dev = video_drvdata(file); 1144 struct v4l2_bt_timings *bt = &dev->dv_timings_cap[dev->input].bt; 1145 unsigned brightness; 1146 1147 if (i >= dev->num_inputs) 1148 return -EINVAL; 1149 1150 if (i == dev->input) 1151 return 0; 1152 1153 if (vb2_is_busy(&dev->vb_vid_cap_q) || 1154 vb2_is_busy(&dev->vb_vbi_cap_q) || 1155 vb2_is_busy(&dev->vb_meta_cap_q)) 1156 return -EBUSY; 1157 1158 dev->input = i; 1159 dev->vid_cap_dev.tvnorms = 0; 1160 if (dev->input_type[i] == TV || dev->input_type[i] == SVID) { 1161 dev->tv_audio_input = (dev->input_type[i] == TV) ? 0 : 1; 1162 dev->vid_cap_dev.tvnorms = V4L2_STD_ALL; 1163 } 1164 dev->vbi_cap_dev.tvnorms = dev->vid_cap_dev.tvnorms; 1165 dev->meta_cap_dev.tvnorms = dev->vid_cap_dev.tvnorms; 1166 vivid_update_format_cap(dev, false); 1167 1168 if (dev->colorspace) { 1169 switch (dev->input_type[i]) { 1170 case WEBCAM: 1171 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB); 1172 break; 1173 case TV: 1174 case SVID: 1175 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); 1176 break; 1177 case HDMI: 1178 if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) { 1179 if (dev->src_rect.width == 720 && dev->src_rect.height <= 576) 1180 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); 1181 else 1182 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_709); 1183 } else { 1184 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_SRGB); 1185 } 1186 break; 1187 } 1188 } 1189 1190 /* 1191 * Modify the brightness range depending on the input. 1192 * This makes it easy to use vivid to test if applications can 1193 * handle control range modifications and is also how this is 1194 * typically used in practice as different inputs may be hooked 1195 * up to different receivers with different control ranges. 1196 */ 1197 brightness = 128 * i + dev->input_brightness[i]; 1198 v4l2_ctrl_modify_range(dev->brightness, 1199 128 * i, 255 + 128 * i, 1, 128 + 128 * i); 1200 v4l2_ctrl_s_ctrl(dev->brightness, brightness); 1201 1202 /* Restore per-input states. */ 1203 v4l2_ctrl_activate(dev->ctrl_dv_timings_signal_mode, 1204 vivid_is_hdmi_cap(dev)); 1205 v4l2_ctrl_activate(dev->ctrl_dv_timings, vivid_is_hdmi_cap(dev) && 1206 dev->dv_timings_signal_mode[dev->input] == 1207 SELECTED_DV_TIMINGS); 1208 v4l2_ctrl_activate(dev->ctrl_std_signal_mode, vivid_is_sdtv_cap(dev)); 1209 v4l2_ctrl_activate(dev->ctrl_standard, vivid_is_sdtv_cap(dev) && 1210 dev->std_signal_mode[dev->input]); 1211 1212 if (vivid_is_hdmi_cap(dev)) { 1213 v4l2_ctrl_s_ctrl(dev->ctrl_dv_timings_signal_mode, 1214 dev->dv_timings_signal_mode[dev->input]); 1215 v4l2_ctrl_s_ctrl(dev->ctrl_dv_timings, 1216 dev->query_dv_timings[dev->input]); 1217 } else if (vivid_is_sdtv_cap(dev)) { 1218 v4l2_ctrl_s_ctrl(dev->ctrl_std_signal_mode, 1219 dev->std_signal_mode[dev->input]); 1220 v4l2_ctrl_s_ctrl(dev->ctrl_standard, 1221 dev->std_signal_mode[dev->input]); 1222 } 1223 1224 return 0; 1225 } 1226 1227 int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) 1228 { 1229 if (vin->index >= ARRAY_SIZE(vivid_audio_inputs)) 1230 return -EINVAL; 1231 *vin = vivid_audio_inputs[vin->index]; 1232 return 0; 1233 } 1234 1235 int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) 1236 { 1237 struct vivid_dev *dev = video_drvdata(file); 1238 1239 if (!vivid_is_sdtv_cap(dev)) 1240 return -EINVAL; 1241 *vin = vivid_audio_inputs[dev->tv_audio_input]; 1242 return 0; 1243 } 1244 1245 int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *vin) 1246 { 1247 struct vivid_dev *dev = video_drvdata(file); 1248 1249 if (!vivid_is_sdtv_cap(dev)) 1250 return -EINVAL; 1251 if (vin->index >= ARRAY_SIZE(vivid_audio_inputs)) 1252 return -EINVAL; 1253 dev->tv_audio_input = vin->index; 1254 return 0; 1255 } 1256 1257 int vivid_video_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) 1258 { 1259 struct vivid_dev *dev = video_drvdata(file); 1260 1261 if (vf->tuner != 0) 1262 return -EINVAL; 1263 vf->frequency = dev->tv_freq; 1264 return 0; 1265 } 1266 1267 int vivid_video_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf) 1268 { 1269 struct vivid_dev *dev = video_drvdata(file); 1270 1271 if (vf->tuner != 0) 1272 return -EINVAL; 1273 dev->tv_freq = clamp_t(unsigned, vf->frequency, MIN_TV_FREQ, MAX_TV_FREQ); 1274 if (vivid_is_tv_cap(dev)) 1275 vivid_update_quality(dev); 1276 return 0; 1277 } 1278 1279 int vivid_video_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt) 1280 { 1281 struct vivid_dev *dev = video_drvdata(file); 1282 1283 if (vt->index != 0) 1284 return -EINVAL; 1285 if (vt->audmode > V4L2_TUNER_MODE_LANG1_LANG2) 1286 return -EINVAL; 1287 dev->tv_audmode = vt->audmode; 1288 return 0; 1289 } 1290 1291 int vivid_video_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 1292 { 1293 struct vivid_dev *dev = video_drvdata(file); 1294 enum tpg_quality qual; 1295 1296 if (vt->index != 0) 1297 return -EINVAL; 1298 1299 vt->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | 1300 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 1301 vt->audmode = dev->tv_audmode; 1302 vt->rangelow = MIN_TV_FREQ; 1303 vt->rangehigh = MAX_TV_FREQ; 1304 qual = vivid_get_quality(dev, &vt->afc); 1305 if (qual == TPG_QUAL_COLOR) 1306 vt->signal = 0xffff; 1307 else if (qual == TPG_QUAL_GRAY) 1308 vt->signal = 0x8000; 1309 else 1310 vt->signal = 0; 1311 if (qual == TPG_QUAL_NOISE) { 1312 vt->rxsubchans = 0; 1313 } else if (qual == TPG_QUAL_GRAY) { 1314 vt->rxsubchans = V4L2_TUNER_SUB_MONO; 1315 } else { 1316 unsigned int channel_nr = dev->tv_freq / (6 * 16); 1317 unsigned int options = 1318 (dev->std_cap[dev->input] & V4L2_STD_NTSC_M) ? 4 : 3; 1319 1320 switch (channel_nr % options) { 1321 case 0: 1322 vt->rxsubchans = V4L2_TUNER_SUB_MONO; 1323 break; 1324 case 1: 1325 vt->rxsubchans = V4L2_TUNER_SUB_STEREO; 1326 break; 1327 case 2: 1328 if (dev->std_cap[dev->input] & V4L2_STD_NTSC_M) 1329 vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_SAP; 1330 else 1331 vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 1332 break; 1333 case 3: 1334 vt->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_SAP; 1335 break; 1336 } 1337 } 1338 strscpy(vt->name, "TV Tuner", sizeof(vt->name)); 1339 return 0; 1340 } 1341 1342 /* Must remain in sync with the vivid_ctrl_standard_strings array */ 1343 const v4l2_std_id vivid_standard[] = { 1344 V4L2_STD_NTSC_M, 1345 V4L2_STD_NTSC_M_JP, 1346 V4L2_STD_NTSC_M_KR, 1347 V4L2_STD_NTSC_443, 1348 V4L2_STD_PAL_BG | V4L2_STD_PAL_H, 1349 V4L2_STD_PAL_I, 1350 V4L2_STD_PAL_DK, 1351 V4L2_STD_PAL_M, 1352 V4L2_STD_PAL_N, 1353 V4L2_STD_PAL_Nc, 1354 V4L2_STD_PAL_60, 1355 V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, 1356 V4L2_STD_SECAM_DK, 1357 V4L2_STD_SECAM_L, 1358 V4L2_STD_SECAM_LC, 1359 V4L2_STD_UNKNOWN 1360 }; 1361 1362 /* Must remain in sync with the vivid_standard array */ 1363 const char * const vivid_ctrl_standard_strings[] = { 1364 "NTSC-M", 1365 "NTSC-M-JP", 1366 "NTSC-M-KR", 1367 "NTSC-443", 1368 "PAL-BGH", 1369 "PAL-I", 1370 "PAL-DK", 1371 "PAL-M", 1372 "PAL-N", 1373 "PAL-Nc", 1374 "PAL-60", 1375 "SECAM-BGH", 1376 "SECAM-DK", 1377 "SECAM-L", 1378 "SECAM-Lc", 1379 NULL, 1380 }; 1381 1382 int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *id) 1383 { 1384 struct vivid_dev *dev = video_drvdata(file); 1385 unsigned int last = dev->query_std_last[dev->input]; 1386 1387 if (!vivid_is_sdtv_cap(dev)) 1388 return -ENODATA; 1389 if (dev->std_signal_mode[dev->input] == NO_SIGNAL || 1390 dev->std_signal_mode[dev->input] == NO_LOCK) { 1391 *id = V4L2_STD_UNKNOWN; 1392 return 0; 1393 } 1394 if (vivid_is_tv_cap(dev) && tpg_g_quality(&dev->tpg) == TPG_QUAL_NOISE) { 1395 *id = V4L2_STD_UNKNOWN; 1396 } else if (dev->std_signal_mode[dev->input] == CURRENT_STD) { 1397 *id = dev->std_cap[dev->input]; 1398 } else if (dev->std_signal_mode[dev->input] == SELECTED_STD) { 1399 *id = dev->query_std[dev->input]; 1400 } else { 1401 *id = vivid_standard[last]; 1402 dev->query_std_last[dev->input] = 1403 (last + 1) % ARRAY_SIZE(vivid_standard); 1404 } 1405 1406 return 0; 1407 } 1408 1409 int vivid_vid_cap_s_std(struct file *file, void *priv, v4l2_std_id id) 1410 { 1411 struct vivid_dev *dev = video_drvdata(file); 1412 1413 if (!vivid_is_sdtv_cap(dev)) 1414 return -ENODATA; 1415 if (dev->std_cap[dev->input] == id) 1416 return 0; 1417 if (vb2_is_busy(&dev->vb_vid_cap_q) || vb2_is_busy(&dev->vb_vbi_cap_q)) 1418 return -EBUSY; 1419 dev->std_cap[dev->input] = id; 1420 vivid_update_format_cap(dev, false); 1421 return 0; 1422 } 1423 1424 static void find_aspect_ratio(u32 width, u32 height, 1425 u32 *num, u32 *denom) 1426 { 1427 if (!(height % 3) && ((height * 4 / 3) == width)) { 1428 *num = 4; 1429 *denom = 3; 1430 } else if (!(height % 9) && ((height * 16 / 9) == width)) { 1431 *num = 16; 1432 *denom = 9; 1433 } else if (!(height % 10) && ((height * 16 / 10) == width)) { 1434 *num = 16; 1435 *denom = 10; 1436 } else if (!(height % 4) && ((height * 5 / 4) == width)) { 1437 *num = 5; 1438 *denom = 4; 1439 } else if (!(height % 9) && ((height * 15 / 9) == width)) { 1440 *num = 15; 1441 *denom = 9; 1442 } else { /* default to 16:9 */ 1443 *num = 16; 1444 *denom = 9; 1445 } 1446 } 1447 1448 static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings) 1449 { 1450 struct v4l2_bt_timings *bt = &timings->bt; 1451 u32 total_h_pixel; 1452 u32 total_v_lines; 1453 u32 h_freq; 1454 1455 if (!v4l2_valid_dv_timings(timings, &vivid_dv_timings_cap, 1456 NULL, NULL)) 1457 return false; 1458 1459 total_h_pixel = V4L2_DV_BT_FRAME_WIDTH(bt); 1460 total_v_lines = V4L2_DV_BT_FRAME_HEIGHT(bt); 1461 1462 h_freq = (u32)bt->pixelclock / total_h_pixel; 1463 1464 if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) { 1465 if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync, bt->width, 1466 bt->polarities, bt->interlaced, timings)) 1467 return true; 1468 } 1469 1470 if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_GTF)) { 1471 struct v4l2_fract aspect_ratio; 1472 1473 find_aspect_ratio(bt->width, bt->height, 1474 &aspect_ratio.numerator, 1475 &aspect_ratio.denominator); 1476 if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync, 1477 bt->polarities, bt->interlaced, 1478 aspect_ratio, timings)) 1479 return true; 1480 } 1481 return false; 1482 } 1483 1484 int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh, 1485 struct v4l2_dv_timings *timings) 1486 { 1487 struct vivid_dev *dev = video_drvdata(file); 1488 1489 if (!vivid_is_hdmi_cap(dev)) 1490 return -ENODATA; 1491 if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap, 1492 0, NULL, NULL) && 1493 !valid_cvt_gtf_timings(timings)) 1494 return -EINVAL; 1495 1496 if (v4l2_match_dv_timings(timings, &dev->dv_timings_cap[dev->input], 1497 0, false)) 1498 return 0; 1499 if (vb2_is_busy(&dev->vb_vid_cap_q)) 1500 return -EBUSY; 1501 1502 dev->dv_timings_cap[dev->input] = *timings; 1503 vivid_update_format_cap(dev, false); 1504 return 0; 1505 } 1506 1507 int vidioc_query_dv_timings(struct file *file, void *_fh, 1508 struct v4l2_dv_timings *timings) 1509 { 1510 struct vivid_dev *dev = video_drvdata(file); 1511 unsigned int input = dev->input; 1512 unsigned int last = dev->query_dv_timings_last[input]; 1513 1514 if (!vivid_is_hdmi_cap(dev)) 1515 return -ENODATA; 1516 if (dev->dv_timings_signal_mode[input] == NO_SIGNAL || 1517 dev->edid_blocks == 0) 1518 return -ENOLINK; 1519 if (dev->dv_timings_signal_mode[input] == NO_LOCK) 1520 return -ENOLCK; 1521 if (dev->dv_timings_signal_mode[input] == OUT_OF_RANGE) { 1522 timings->bt.pixelclock = vivid_dv_timings_cap.bt.max_pixelclock * 2; 1523 return -ERANGE; 1524 } 1525 if (dev->dv_timings_signal_mode[input] == CURRENT_DV_TIMINGS) { 1526 *timings = dev->dv_timings_cap[input]; 1527 } else if (dev->dv_timings_signal_mode[input] == 1528 SELECTED_DV_TIMINGS) { 1529 *timings = 1530 v4l2_dv_timings_presets[dev->query_dv_timings[input]]; 1531 } else { 1532 *timings = 1533 v4l2_dv_timings_presets[last]; 1534 dev->query_dv_timings_last[input] = 1535 (last + 1) % dev->query_dv_timings_size; 1536 } 1537 return 0; 1538 } 1539 1540 int vidioc_s_edid(struct file *file, void *_fh, 1541 struct v4l2_edid *edid) 1542 { 1543 struct vivid_dev *dev = video_drvdata(file); 1544 u16 phys_addr; 1545 u32 display_present = 0; 1546 unsigned int i, j; 1547 int ret; 1548 1549 memset(edid->reserved, 0, sizeof(edid->reserved)); 1550 if (edid->pad >= dev->num_inputs) 1551 return -EINVAL; 1552 if (dev->input_type[edid->pad] != HDMI || edid->start_block) 1553 return -EINVAL; 1554 if (edid->blocks == 0) { 1555 dev->edid_blocks = 0; 1556 v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0); 1557 v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0); 1558 phys_addr = CEC_PHYS_ADDR_INVALID; 1559 goto set_phys_addr; 1560 } 1561 if (edid->blocks > dev->edid_max_blocks) { 1562 edid->blocks = dev->edid_max_blocks; 1563 return -E2BIG; 1564 } 1565 phys_addr = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL); 1566 ret = v4l2_phys_addr_validate(phys_addr, &phys_addr, NULL); 1567 if (ret) 1568 return ret; 1569 1570 if (vb2_is_busy(&dev->vb_vid_cap_q)) 1571 return -EBUSY; 1572 1573 dev->edid_blocks = edid->blocks; 1574 memcpy(dev->edid, edid->edid, edid->blocks * 128); 1575 1576 for (i = 0, j = 0; i < dev->num_outputs; i++) 1577 if (dev->output_type[i] == HDMI) 1578 display_present |= 1579 dev->display_present[i] << j++; 1580 1581 v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present); 1582 v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present); 1583 1584 set_phys_addr: 1585 /* TODO: a proper hotplug detect cycle should be emulated here */ 1586 cec_s_phys_addr(dev->cec_rx_adap, phys_addr, false); 1587 1588 for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) 1589 cec_s_phys_addr(dev->cec_tx_adap[i], 1590 dev->display_present[i] ? 1591 v4l2_phys_addr_for_input(phys_addr, i + 1) : 1592 CEC_PHYS_ADDR_INVALID, 1593 false); 1594 return 0; 1595 } 1596 1597 int vidioc_enum_framesizes(struct file *file, void *fh, 1598 struct v4l2_frmsizeenum *fsize) 1599 { 1600 struct vivid_dev *dev = video_drvdata(file); 1601 1602 if (!vivid_is_webcam(dev) && !dev->has_scaler_cap) 1603 return -EINVAL; 1604 if (vivid_get_format(dev, fsize->pixel_format) == NULL) 1605 return -EINVAL; 1606 if (vivid_is_webcam(dev)) { 1607 if (fsize->index >= ARRAY_SIZE(webcam_sizes)) 1608 return -EINVAL; 1609 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; 1610 fsize->discrete = webcam_sizes[fsize->index]; 1611 return 0; 1612 } 1613 if (fsize->index) 1614 return -EINVAL; 1615 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 1616 fsize->stepwise.min_width = MIN_WIDTH; 1617 fsize->stepwise.max_width = MAX_WIDTH * MAX_ZOOM; 1618 fsize->stepwise.step_width = 2; 1619 fsize->stepwise.min_height = MIN_HEIGHT; 1620 fsize->stepwise.max_height = MAX_HEIGHT * MAX_ZOOM; 1621 fsize->stepwise.step_height = 2; 1622 return 0; 1623 } 1624 1625 /* timeperframe is arbitrary and continuous */ 1626 int vidioc_enum_frameintervals(struct file *file, void *priv, 1627 struct v4l2_frmivalenum *fival) 1628 { 1629 struct vivid_dev *dev = video_drvdata(file); 1630 const struct vivid_fmt *fmt; 1631 int i; 1632 1633 fmt = vivid_get_format(dev, fival->pixel_format); 1634 if (!fmt) 1635 return -EINVAL; 1636 1637 if (!vivid_is_webcam(dev)) { 1638 if (fival->index) 1639 return -EINVAL; 1640 if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH * MAX_ZOOM) 1641 return -EINVAL; 1642 if (fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT * MAX_ZOOM) 1643 return -EINVAL; 1644 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; 1645 fival->discrete = dev->timeperframe_vid_cap; 1646 return 0; 1647 } 1648 1649 for (i = 0; i < ARRAY_SIZE(webcam_sizes); i++) 1650 if (fival->width == webcam_sizes[i].width && 1651 fival->height == webcam_sizes[i].height) 1652 break; 1653 if (i == ARRAY_SIZE(webcam_sizes)) 1654 return -EINVAL; 1655 if (fival->index >= webcam_ival_count(dev, i)) 1656 return -EINVAL; 1657 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; 1658 fival->discrete = webcam_intervals[fival->index]; 1659 return 0; 1660 } 1661 1662 int vivid_vid_cap_g_parm(struct file *file, void *priv, 1663 struct v4l2_streamparm *parm) 1664 { 1665 struct vivid_dev *dev = video_drvdata(file); 1666 1667 if (parm->type != (dev->multiplanar ? 1668 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : 1669 V4L2_BUF_TYPE_VIDEO_CAPTURE)) 1670 return -EINVAL; 1671 1672 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 1673 parm->parm.capture.timeperframe = dev->timeperframe_vid_cap; 1674 parm->parm.capture.readbuffers = 1; 1675 return 0; 1676 } 1677 1678 int vivid_vid_cap_s_parm(struct file *file, void *priv, 1679 struct v4l2_streamparm *parm) 1680 { 1681 struct vivid_dev *dev = video_drvdata(file); 1682 unsigned int ival_sz = webcam_ival_count(dev, dev->webcam_size_idx); 1683 struct v4l2_fract tpf; 1684 unsigned i; 1685 1686 if (parm->type != (dev->multiplanar ? 1687 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : 1688 V4L2_BUF_TYPE_VIDEO_CAPTURE)) 1689 return -EINVAL; 1690 if (!vivid_is_webcam(dev)) 1691 return vivid_vid_cap_g_parm(file, priv, parm); 1692 1693 tpf = parm->parm.capture.timeperframe; 1694 1695 if (tpf.denominator == 0) 1696 tpf = webcam_intervals[ival_sz - 1]; 1697 for (i = 0; i < ival_sz; i++) 1698 if (V4L2_FRACT_COMPARE(tpf, >=, webcam_intervals[i])) 1699 break; 1700 if (i == ival_sz) 1701 i = ival_sz - 1; 1702 dev->webcam_ival_idx = i; 1703 tpf = webcam_intervals[dev->webcam_ival_idx]; 1704 1705 /* resync the thread's timings */ 1706 dev->cap_seq_resync = true; 1707 dev->timeperframe_vid_cap = tpf; 1708 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 1709 parm->parm.capture.timeperframe = tpf; 1710 parm->parm.capture.readbuffers = 1; 1711 return 0; 1712 } 1713