1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * vivid-vid-out.c - video output 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/videodev2.h> 12 #include <linux/v4l2-dv-timings.h> 13 #include <media/v4l2-common.h> 14 #include <media/v4l2-event.h> 15 #include <media/v4l2-dv-timings.h> 16 #include <media/v4l2-rect.h> 17 18 #include "vivid-core.h" 19 #include "vivid-vid-common.h" 20 #include "vivid-kthread-out.h" 21 #include "vivid-vid-out.h" 22 23 static int vid_out_queue_setup(struct vb2_queue *vq, 24 unsigned *nbuffers, unsigned *nplanes, 25 unsigned sizes[], struct device *alloc_devs[]) 26 { 27 struct vivid_dev *dev = vb2_get_drv_priv(vq); 28 const struct vivid_fmt *vfmt = dev->fmt_out; 29 unsigned planes = vfmt->buffers; 30 unsigned h = dev->fmt_out_rect.height; 31 unsigned int size = dev->bytesperline_out[0] * h + vfmt->data_offset[0]; 32 unsigned p; 33 34 for (p = vfmt->buffers; p < vfmt->planes; p++) 35 size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p] + 36 vfmt->data_offset[p]; 37 38 if (dev->field_out == V4L2_FIELD_ALTERNATE) { 39 /* 40 * You cannot use write() with FIELD_ALTERNATE since the field 41 * information (TOP/BOTTOM) cannot be passed to the kernel. 42 */ 43 if (vb2_fileio_is_active(vq)) 44 return -EINVAL; 45 } 46 47 if (dev->queue_setup_error) { 48 /* 49 * Error injection: test what happens if queue_setup() returns 50 * an error. 51 */ 52 dev->queue_setup_error = false; 53 return -EINVAL; 54 } 55 56 if (*nplanes) { 57 /* 58 * Check if the number of requested planes match 59 * the number of planes in the current format. You can't mix that. 60 */ 61 if (*nplanes != planes) 62 return -EINVAL; 63 if (sizes[0] < size) 64 return -EINVAL; 65 for (p = 1; p < planes; p++) { 66 if (sizes[p] < dev->bytesperline_out[p] * h / 67 vfmt->vdownsampling[p] + 68 vfmt->data_offset[p]) 69 return -EINVAL; 70 } 71 } else { 72 for (p = 0; p < planes; p++) 73 sizes[p] = p ? dev->bytesperline_out[p] * h / 74 vfmt->vdownsampling[p] + 75 vfmt->data_offset[p] : size; 76 } 77 78 *nplanes = planes; 79 80 dprintk(dev, 1, "%s: count=%u\n", __func__, *nbuffers); 81 for (p = 0; p < planes; p++) 82 dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]); 83 return 0; 84 } 85 86 static int vid_out_buf_out_validate(struct vb2_buffer *vb) 87 { 88 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 89 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 90 91 dprintk(dev, 1, "%s\n", __func__); 92 93 if (dev->field_out != V4L2_FIELD_ALTERNATE) 94 vbuf->field = dev->field_out; 95 else if (vbuf->field != V4L2_FIELD_TOP && 96 vbuf->field != V4L2_FIELD_BOTTOM) 97 return -EINVAL; 98 return 0; 99 } 100 101 static int vid_out_buf_prepare(struct vb2_buffer *vb) 102 { 103 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 104 const struct vivid_fmt *vfmt = dev->fmt_out; 105 unsigned int planes = vfmt->buffers; 106 unsigned int h = dev->fmt_out_rect.height; 107 unsigned int size = dev->bytesperline_out[0] * h; 108 unsigned p; 109 110 for (p = vfmt->buffers; p < vfmt->planes; p++) 111 size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p]; 112 113 dprintk(dev, 1, "%s\n", __func__); 114 115 if (WARN_ON(NULL == dev->fmt_out)) 116 return -EINVAL; 117 118 if (dev->buf_prepare_error) { 119 /* 120 * Error injection: test what happens if buf_prepare() returns 121 * an error. 122 */ 123 dev->buf_prepare_error = false; 124 return -EINVAL; 125 } 126 127 for (p = 0; p < planes; p++) { 128 if (p) 129 size = dev->bytesperline_out[p] * h / vfmt->vdownsampling[p]; 130 size += vb->planes[p].data_offset; 131 132 if (vb2_get_plane_payload(vb, p) < size) { 133 dprintk(dev, 1, "%s the payload is too small for plane %u (%lu < %u)\n", 134 __func__, p, vb2_get_plane_payload(vb, p), size); 135 return -EINVAL; 136 } 137 } 138 139 return 0; 140 } 141 142 static void vid_out_buf_queue(struct vb2_buffer *vb) 143 { 144 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 145 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 146 struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb); 147 148 dprintk(dev, 1, "%s\n", __func__); 149 150 spin_lock(&dev->slock); 151 list_add_tail(&buf->list, &dev->vid_out_active); 152 spin_unlock(&dev->slock); 153 } 154 155 static int vid_out_start_streaming(struct vb2_queue *vq, unsigned count) 156 { 157 struct vivid_dev *dev = vb2_get_drv_priv(vq); 158 int err; 159 160 if (vb2_is_streaming(&dev->vb_vid_cap_q)) 161 dev->can_loop_video = vivid_vid_can_loop(dev); 162 163 dev->vid_out_seq_count = 0; 164 dprintk(dev, 1, "%s\n", __func__); 165 if (dev->start_streaming_error) { 166 dev->start_streaming_error = false; 167 err = -EINVAL; 168 } else { 169 err = vivid_start_generating_vid_out(dev, &dev->vid_out_streaming); 170 } 171 if (err) { 172 struct vivid_buffer *buf, *tmp; 173 174 list_for_each_entry_safe(buf, tmp, &dev->vid_out_active, list) { 175 list_del(&buf->list); 176 vb2_buffer_done(&buf->vb.vb2_buf, 177 VB2_BUF_STATE_QUEUED); 178 } 179 } 180 return err; 181 } 182 183 /* abort streaming and wait for last buffer */ 184 static void vid_out_stop_streaming(struct vb2_queue *vq) 185 { 186 struct vivid_dev *dev = vb2_get_drv_priv(vq); 187 188 dprintk(dev, 1, "%s\n", __func__); 189 vivid_stop_generating_vid_out(dev, &dev->vid_out_streaming); 190 dev->can_loop_video = false; 191 } 192 193 static void vid_out_buf_request_complete(struct vb2_buffer *vb) 194 { 195 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 196 197 v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vid_out); 198 } 199 200 const struct vb2_ops vivid_vid_out_qops = { 201 .queue_setup = vid_out_queue_setup, 202 .buf_out_validate = vid_out_buf_out_validate, 203 .buf_prepare = vid_out_buf_prepare, 204 .buf_queue = vid_out_buf_queue, 205 .start_streaming = vid_out_start_streaming, 206 .stop_streaming = vid_out_stop_streaming, 207 .buf_request_complete = vid_out_buf_request_complete, 208 .wait_prepare = vb2_ops_wait_prepare, 209 .wait_finish = vb2_ops_wait_finish, 210 }; 211 212 /* 213 * Called whenever the format has to be reset which can occur when 214 * changing outputs, standard, timings, etc. 215 */ 216 void vivid_update_format_out(struct vivid_dev *dev) 217 { 218 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; 219 unsigned size, p; 220 u64 pixelclock; 221 222 switch (dev->output_type[dev->output]) { 223 case SVID: 224 default: 225 dev->field_out = dev->tv_field_out; 226 dev->sink_rect.width = 720; 227 if (dev->std_out & V4L2_STD_525_60) { 228 dev->sink_rect.height = 480; 229 dev->timeperframe_vid_out = (struct v4l2_fract) { 1001, 30000 }; 230 dev->service_set_out = V4L2_SLICED_CAPTION_525; 231 } else { 232 dev->sink_rect.height = 576; 233 dev->timeperframe_vid_out = (struct v4l2_fract) { 1000, 25000 }; 234 dev->service_set_out = V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B; 235 } 236 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; 237 break; 238 case HDMI: 239 dev->sink_rect.width = bt->width; 240 dev->sink_rect.height = bt->height; 241 size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt); 242 243 if (can_reduce_fps(bt) && (bt->flags & V4L2_DV_FL_REDUCED_FPS)) 244 pixelclock = div_u64(bt->pixelclock * 1000, 1001); 245 else 246 pixelclock = bt->pixelclock; 247 248 dev->timeperframe_vid_out = (struct v4l2_fract) { 249 size / 100, (u32)pixelclock / 100 250 }; 251 if (bt->interlaced) 252 dev->field_out = V4L2_FIELD_ALTERNATE; 253 else 254 dev->field_out = V4L2_FIELD_NONE; 255 if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) { 256 if (bt->width == 720 && bt->height <= 576) 257 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; 258 else 259 dev->colorspace_out = V4L2_COLORSPACE_REC709; 260 } else { 261 dev->colorspace_out = V4L2_COLORSPACE_SRGB; 262 } 263 break; 264 } 265 dev->xfer_func_out = V4L2_XFER_FUNC_DEFAULT; 266 dev->ycbcr_enc_out = V4L2_YCBCR_ENC_DEFAULT; 267 dev->hsv_enc_out = V4L2_HSV_ENC_180; 268 dev->quantization_out = V4L2_QUANTIZATION_DEFAULT; 269 dev->compose_out = dev->sink_rect; 270 dev->compose_bounds_out = dev->sink_rect; 271 dev->crop_out = dev->compose_out; 272 if (V4L2_FIELD_HAS_T_OR_B(dev->field_out)) 273 dev->crop_out.height /= 2; 274 dev->fmt_out_rect = dev->crop_out; 275 for (p = 0; p < dev->fmt_out->planes; p++) 276 dev->bytesperline_out[p] = 277 (dev->sink_rect.width * dev->fmt_out->bit_depth[p]) / 8; 278 } 279 280 /* Map the field to something that is valid for the current output */ 281 static enum v4l2_field vivid_field_out(struct vivid_dev *dev, enum v4l2_field field) 282 { 283 if (vivid_is_svid_out(dev)) { 284 switch (field) { 285 case V4L2_FIELD_INTERLACED_TB: 286 case V4L2_FIELD_INTERLACED_BT: 287 case V4L2_FIELD_SEQ_TB: 288 case V4L2_FIELD_SEQ_BT: 289 case V4L2_FIELD_ALTERNATE: 290 return field; 291 case V4L2_FIELD_INTERLACED: 292 default: 293 return V4L2_FIELD_INTERLACED; 294 } 295 } 296 if (vivid_is_hdmi_out(dev)) 297 return dev->dv_timings_out.bt.interlaced ? V4L2_FIELD_ALTERNATE : 298 V4L2_FIELD_NONE; 299 return V4L2_FIELD_NONE; 300 } 301 302 static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev *dev) 303 { 304 if (vivid_is_svid_out(dev)) 305 return (dev->std_out & V4L2_STD_525_60) ? 306 TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL; 307 308 if (vivid_is_hdmi_out(dev) && 309 dev->sink_rect.width == 720 && dev->sink_rect.height <= 576) 310 return dev->sink_rect.height == 480 ? 311 TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL; 312 313 return TPG_PIXEL_ASPECT_SQUARE; 314 } 315 316 int vivid_g_fmt_vid_out(struct file *file, void *priv, 317 struct v4l2_format *f) 318 { 319 struct vivid_dev *dev = video_drvdata(file); 320 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 321 const struct vivid_fmt *fmt = dev->fmt_out; 322 unsigned p; 323 324 mp->width = dev->fmt_out_rect.width; 325 mp->height = dev->fmt_out_rect.height; 326 mp->field = dev->field_out; 327 mp->pixelformat = fmt->fourcc; 328 mp->colorspace = dev->colorspace_out; 329 mp->xfer_func = dev->xfer_func_out; 330 mp->ycbcr_enc = dev->ycbcr_enc_out; 331 mp->quantization = dev->quantization_out; 332 mp->num_planes = fmt->buffers; 333 for (p = 0; p < mp->num_planes; p++) { 334 mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p]; 335 mp->plane_fmt[p].sizeimage = 336 mp->plane_fmt[p].bytesperline * mp->height / 337 fmt->vdownsampling[p] + fmt->data_offset[p]; 338 } 339 for (p = fmt->buffers; p < fmt->planes; p++) { 340 unsigned stride = dev->bytesperline_out[p]; 341 342 mp->plane_fmt[0].sizeimage += 343 (stride * mp->height) / fmt->vdownsampling[p]; 344 } 345 return 0; 346 } 347 348 int vivid_try_fmt_vid_out(struct file *file, void *priv, 349 struct v4l2_format *f) 350 { 351 struct vivid_dev *dev = video_drvdata(file); 352 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; 353 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 354 struct v4l2_plane_pix_format *pfmt = mp->plane_fmt; 355 const struct vivid_fmt *fmt; 356 unsigned bytesperline, max_bpl; 357 unsigned factor = 1; 358 unsigned w, h; 359 unsigned p; 360 361 fmt = vivid_get_format(dev, mp->pixelformat); 362 if (!fmt) { 363 dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n", 364 mp->pixelformat); 365 mp->pixelformat = V4L2_PIX_FMT_YUYV; 366 fmt = vivid_get_format(dev, mp->pixelformat); 367 } 368 369 mp->field = vivid_field_out(dev, mp->field); 370 if (vivid_is_svid_out(dev)) { 371 w = 720; 372 h = (dev->std_out & V4L2_STD_525_60) ? 480 : 576; 373 } else { 374 w = dev->sink_rect.width; 375 h = dev->sink_rect.height; 376 } 377 if (V4L2_FIELD_HAS_T_OR_B(mp->field)) 378 factor = 2; 379 if (!dev->has_scaler_out && !dev->has_crop_out && !dev->has_compose_out) { 380 mp->width = w; 381 mp->height = h / factor; 382 } else { 383 struct v4l2_rect r = { 0, 0, mp->width, mp->height * factor }; 384 385 v4l2_rect_set_min_size(&r, &vivid_min_rect); 386 v4l2_rect_set_max_size(&r, &vivid_max_rect); 387 if (dev->has_scaler_out && !dev->has_crop_out) { 388 struct v4l2_rect max_r = { 0, 0, MAX_ZOOM * w, MAX_ZOOM * h }; 389 390 v4l2_rect_set_max_size(&r, &max_r); 391 } else if (!dev->has_scaler_out && dev->has_compose_out && !dev->has_crop_out) { 392 v4l2_rect_set_max_size(&r, &dev->sink_rect); 393 } else if (!dev->has_scaler_out && !dev->has_compose_out) { 394 v4l2_rect_set_min_size(&r, &dev->sink_rect); 395 } 396 mp->width = r.width; 397 mp->height = r.height / factor; 398 } 399 400 /* This driver supports custom bytesperline values */ 401 402 mp->num_planes = fmt->buffers; 403 for (p = 0; p < fmt->buffers; p++) { 404 /* Calculate the minimum supported bytesperline value */ 405 bytesperline = (mp->width * fmt->bit_depth[p]) >> 3; 406 /* Calculate the maximum supported bytesperline value */ 407 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3; 408 409 if (pfmt[p].bytesperline > max_bpl) 410 pfmt[p].bytesperline = max_bpl; 411 if (pfmt[p].bytesperline < bytesperline) 412 pfmt[p].bytesperline = bytesperline; 413 414 pfmt[p].sizeimage = (pfmt[p].bytesperline * mp->height) / 415 fmt->vdownsampling[p] + fmt->data_offset[p]; 416 417 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 418 } 419 for (p = fmt->buffers; p < fmt->planes; p++) 420 pfmt[0].sizeimage += (pfmt[0].bytesperline * mp->height * 421 (fmt->bit_depth[p] / fmt->vdownsampling[p])) / 422 (fmt->bit_depth[0] / fmt->vdownsampling[0]); 423 424 mp->xfer_func = V4L2_XFER_FUNC_DEFAULT; 425 mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 426 mp->quantization = V4L2_QUANTIZATION_DEFAULT; 427 if (vivid_is_svid_out(dev)) { 428 mp->colorspace = V4L2_COLORSPACE_SMPTE170M; 429 } else if (dev->dvi_d_out || !(bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) { 430 mp->colorspace = V4L2_COLORSPACE_SRGB; 431 if (dev->dvi_d_out) 432 mp->quantization = V4L2_QUANTIZATION_LIM_RANGE; 433 } else if (bt->width == 720 && bt->height <= 576) { 434 mp->colorspace = V4L2_COLORSPACE_SMPTE170M; 435 } else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M && 436 mp->colorspace != V4L2_COLORSPACE_REC709 && 437 mp->colorspace != V4L2_COLORSPACE_OPRGB && 438 mp->colorspace != V4L2_COLORSPACE_BT2020 && 439 mp->colorspace != V4L2_COLORSPACE_SRGB) { 440 mp->colorspace = V4L2_COLORSPACE_REC709; 441 } 442 memset(mp->reserved, 0, sizeof(mp->reserved)); 443 return 0; 444 } 445 446 int vivid_s_fmt_vid_out(struct file *file, void *priv, 447 struct v4l2_format *f) 448 { 449 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 450 struct vivid_dev *dev = video_drvdata(file); 451 struct v4l2_rect *crop = &dev->crop_out; 452 struct v4l2_rect *compose = &dev->compose_out; 453 struct vb2_queue *q = &dev->vb_vid_out_q; 454 int ret = vivid_try_fmt_vid_out(file, priv, f); 455 unsigned factor = 1; 456 unsigned p; 457 458 if (ret < 0) 459 return ret; 460 461 if (vb2_is_busy(q) && 462 (vivid_is_svid_out(dev) || 463 mp->width != dev->fmt_out_rect.width || 464 mp->height != dev->fmt_out_rect.height || 465 mp->pixelformat != dev->fmt_out->fourcc || 466 mp->field != dev->field_out)) { 467 dprintk(dev, 1, "%s device busy\n", __func__); 468 return -EBUSY; 469 } 470 471 /* 472 * Allow for changing the colorspace on the fly. Useful for testing 473 * purposes, and it is something that HDMI transmitters are able 474 * to do. 475 */ 476 if (vb2_is_busy(q)) 477 goto set_colorspace; 478 479 dev->fmt_out = vivid_get_format(dev, mp->pixelformat); 480 if (V4L2_FIELD_HAS_T_OR_B(mp->field)) 481 factor = 2; 482 483 if (dev->has_scaler_out || dev->has_crop_out || dev->has_compose_out) { 484 struct v4l2_rect r = { 0, 0, mp->width, mp->height }; 485 486 if (dev->has_scaler_out) { 487 if (dev->has_crop_out) 488 v4l2_rect_map_inside(crop, &r); 489 else 490 *crop = r; 491 if (dev->has_compose_out && !dev->has_crop_out) { 492 struct v4l2_rect min_r = { 493 0, 0, 494 r.width / MAX_ZOOM, 495 factor * r.height / MAX_ZOOM 496 }; 497 struct v4l2_rect max_r = { 498 0, 0, 499 r.width * MAX_ZOOM, 500 factor * r.height * MAX_ZOOM 501 }; 502 503 v4l2_rect_set_min_size(compose, &min_r); 504 v4l2_rect_set_max_size(compose, &max_r); 505 v4l2_rect_map_inside(compose, &dev->compose_bounds_out); 506 } else if (dev->has_compose_out) { 507 struct v4l2_rect min_r = { 508 0, 0, 509 crop->width / MAX_ZOOM, 510 factor * crop->height / MAX_ZOOM 511 }; 512 struct v4l2_rect max_r = { 513 0, 0, 514 crop->width * MAX_ZOOM, 515 factor * crop->height * MAX_ZOOM 516 }; 517 518 v4l2_rect_set_min_size(compose, &min_r); 519 v4l2_rect_set_max_size(compose, &max_r); 520 v4l2_rect_map_inside(compose, &dev->compose_bounds_out); 521 } 522 } else if (dev->has_compose_out && !dev->has_crop_out) { 523 v4l2_rect_set_size_to(crop, &r); 524 r.height *= factor; 525 v4l2_rect_set_size_to(compose, &r); 526 v4l2_rect_map_inside(compose, &dev->compose_bounds_out); 527 } else if (!dev->has_compose_out) { 528 v4l2_rect_map_inside(crop, &r); 529 r.height /= factor; 530 v4l2_rect_set_size_to(compose, &r); 531 } else { 532 r.height *= factor; 533 v4l2_rect_set_max_size(compose, &r); 534 v4l2_rect_map_inside(compose, &dev->compose_bounds_out); 535 crop->top *= factor; 536 crop->height *= factor; 537 v4l2_rect_set_size_to(crop, compose); 538 v4l2_rect_map_inside(crop, &r); 539 crop->top /= factor; 540 crop->height /= factor; 541 } 542 } else { 543 struct v4l2_rect r = { 0, 0, mp->width, mp->height }; 544 545 v4l2_rect_set_size_to(crop, &r); 546 r.height /= factor; 547 v4l2_rect_set_size_to(compose, &r); 548 } 549 550 dev->fmt_out_rect.width = mp->width; 551 dev->fmt_out_rect.height = mp->height; 552 for (p = 0; p < mp->num_planes; p++) 553 dev->bytesperline_out[p] = mp->plane_fmt[p].bytesperline; 554 for (p = dev->fmt_out->buffers; p < dev->fmt_out->planes; p++) 555 dev->bytesperline_out[p] = 556 (dev->bytesperline_out[0] * dev->fmt_out->bit_depth[p]) / 557 dev->fmt_out->bit_depth[0]; 558 dev->field_out = mp->field; 559 if (vivid_is_svid_out(dev)) 560 dev->tv_field_out = mp->field; 561 562 set_colorspace: 563 dev->colorspace_out = mp->colorspace; 564 dev->xfer_func_out = mp->xfer_func; 565 dev->ycbcr_enc_out = mp->ycbcr_enc; 566 dev->quantization_out = mp->quantization; 567 if (dev->loop_video) { 568 vivid_send_source_change(dev, SVID); 569 vivid_send_source_change(dev, HDMI); 570 } 571 return 0; 572 } 573 574 int vidioc_g_fmt_vid_out_mplane(struct file *file, void *priv, 575 struct v4l2_format *f) 576 { 577 struct vivid_dev *dev = video_drvdata(file); 578 579 if (!dev->multiplanar) 580 return -ENOTTY; 581 return vivid_g_fmt_vid_out(file, priv, f); 582 } 583 584 int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, 585 struct v4l2_format *f) 586 { 587 struct vivid_dev *dev = video_drvdata(file); 588 589 if (!dev->multiplanar) 590 return -ENOTTY; 591 return vivid_try_fmt_vid_out(file, priv, f); 592 } 593 594 int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv, 595 struct v4l2_format *f) 596 { 597 struct vivid_dev *dev = video_drvdata(file); 598 599 if (!dev->multiplanar) 600 return -ENOTTY; 601 return vivid_s_fmt_vid_out(file, priv, f); 602 } 603 604 int vidioc_g_fmt_vid_out(struct file *file, void *priv, 605 struct v4l2_format *f) 606 { 607 struct vivid_dev *dev = video_drvdata(file); 608 609 if (dev->multiplanar) 610 return -ENOTTY; 611 return fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_out); 612 } 613 614 int vidioc_try_fmt_vid_out(struct file *file, void *priv, 615 struct v4l2_format *f) 616 { 617 struct vivid_dev *dev = video_drvdata(file); 618 619 if (dev->multiplanar) 620 return -ENOTTY; 621 return fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_out); 622 } 623 624 int vidioc_s_fmt_vid_out(struct file *file, void *priv, 625 struct v4l2_format *f) 626 { 627 struct vivid_dev *dev = video_drvdata(file); 628 629 if (dev->multiplanar) 630 return -ENOTTY; 631 return fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_out); 632 } 633 634 int vivid_vid_out_g_selection(struct file *file, void *priv, 635 struct v4l2_selection *sel) 636 { 637 struct vivid_dev *dev = video_drvdata(file); 638 639 if (!dev->has_crop_out && !dev->has_compose_out) 640 return -ENOTTY; 641 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 642 return -EINVAL; 643 644 sel->r.left = sel->r.top = 0; 645 switch (sel->target) { 646 case V4L2_SEL_TGT_CROP: 647 if (!dev->has_crop_out) 648 return -EINVAL; 649 sel->r = dev->crop_out; 650 break; 651 case V4L2_SEL_TGT_CROP_DEFAULT: 652 if (!dev->has_crop_out) 653 return -EINVAL; 654 sel->r = dev->fmt_out_rect; 655 break; 656 case V4L2_SEL_TGT_CROP_BOUNDS: 657 if (!dev->has_crop_out) 658 return -EINVAL; 659 sel->r = vivid_max_rect; 660 break; 661 case V4L2_SEL_TGT_COMPOSE: 662 if (!dev->has_compose_out) 663 return -EINVAL; 664 sel->r = dev->compose_out; 665 break; 666 case V4L2_SEL_TGT_COMPOSE_DEFAULT: 667 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 668 if (!dev->has_compose_out) 669 return -EINVAL; 670 sel->r = dev->sink_rect; 671 break; 672 default: 673 return -EINVAL; 674 } 675 return 0; 676 } 677 678 int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection *s) 679 { 680 struct vivid_dev *dev = video_drvdata(file); 681 struct v4l2_rect *crop = &dev->crop_out; 682 struct v4l2_rect *compose = &dev->compose_out; 683 unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_out) ? 2 : 1; 684 int ret; 685 686 if (!dev->has_crop_out && !dev->has_compose_out) 687 return -ENOTTY; 688 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 689 return -EINVAL; 690 691 switch (s->target) { 692 case V4L2_SEL_TGT_CROP: 693 if (!dev->has_crop_out) 694 return -EINVAL; 695 ret = vivid_vid_adjust_sel(s->flags, &s->r); 696 if (ret) 697 return ret; 698 v4l2_rect_set_min_size(&s->r, &vivid_min_rect); 699 v4l2_rect_set_max_size(&s->r, &dev->fmt_out_rect); 700 if (dev->has_scaler_out) { 701 struct v4l2_rect max_rect = { 702 0, 0, 703 dev->sink_rect.width * MAX_ZOOM, 704 (dev->sink_rect.height / factor) * MAX_ZOOM 705 }; 706 707 v4l2_rect_set_max_size(&s->r, &max_rect); 708 if (dev->has_compose_out) { 709 struct v4l2_rect min_rect = { 710 0, 0, 711 s->r.width / MAX_ZOOM, 712 (s->r.height * factor) / MAX_ZOOM 713 }; 714 struct v4l2_rect max_rect = { 715 0, 0, 716 s->r.width * MAX_ZOOM, 717 (s->r.height * factor) * MAX_ZOOM 718 }; 719 720 v4l2_rect_set_min_size(compose, &min_rect); 721 v4l2_rect_set_max_size(compose, &max_rect); 722 v4l2_rect_map_inside(compose, &dev->compose_bounds_out); 723 } 724 } else if (dev->has_compose_out) { 725 s->r.top *= factor; 726 s->r.height *= factor; 727 v4l2_rect_set_max_size(&s->r, &dev->sink_rect); 728 v4l2_rect_set_size_to(compose, &s->r); 729 v4l2_rect_map_inside(compose, &dev->compose_bounds_out); 730 s->r.top /= factor; 731 s->r.height /= factor; 732 } else { 733 v4l2_rect_set_size_to(&s->r, &dev->sink_rect); 734 s->r.height /= factor; 735 } 736 v4l2_rect_map_inside(&s->r, &dev->fmt_out_rect); 737 *crop = s->r; 738 break; 739 case V4L2_SEL_TGT_COMPOSE: 740 if (!dev->has_compose_out) 741 return -EINVAL; 742 ret = vivid_vid_adjust_sel(s->flags, &s->r); 743 if (ret) 744 return ret; 745 v4l2_rect_set_min_size(&s->r, &vivid_min_rect); 746 v4l2_rect_set_max_size(&s->r, &dev->sink_rect); 747 v4l2_rect_map_inside(&s->r, &dev->compose_bounds_out); 748 s->r.top /= factor; 749 s->r.height /= factor; 750 if (dev->has_scaler_out) { 751 struct v4l2_rect fmt = dev->fmt_out_rect; 752 struct v4l2_rect max_rect = { 753 0, 0, 754 s->r.width * MAX_ZOOM, 755 s->r.height * MAX_ZOOM 756 }; 757 struct v4l2_rect min_rect = { 758 0, 0, 759 s->r.width / MAX_ZOOM, 760 s->r.height / MAX_ZOOM 761 }; 762 763 v4l2_rect_set_min_size(&fmt, &min_rect); 764 if (!dev->has_crop_out) 765 v4l2_rect_set_max_size(&fmt, &max_rect); 766 if (!v4l2_rect_same_size(&dev->fmt_out_rect, &fmt) && 767 vb2_is_busy(&dev->vb_vid_out_q)) 768 return -EBUSY; 769 if (dev->has_crop_out) { 770 v4l2_rect_set_min_size(crop, &min_rect); 771 v4l2_rect_set_max_size(crop, &max_rect); 772 } 773 dev->fmt_out_rect = fmt; 774 } else if (dev->has_crop_out) { 775 struct v4l2_rect fmt = dev->fmt_out_rect; 776 777 v4l2_rect_set_min_size(&fmt, &s->r); 778 if (!v4l2_rect_same_size(&dev->fmt_out_rect, &fmt) && 779 vb2_is_busy(&dev->vb_vid_out_q)) 780 return -EBUSY; 781 dev->fmt_out_rect = fmt; 782 v4l2_rect_set_size_to(crop, &s->r); 783 v4l2_rect_map_inside(crop, &dev->fmt_out_rect); 784 } else { 785 if (!v4l2_rect_same_size(&s->r, &dev->fmt_out_rect) && 786 vb2_is_busy(&dev->vb_vid_out_q)) 787 return -EBUSY; 788 v4l2_rect_set_size_to(&dev->fmt_out_rect, &s->r); 789 v4l2_rect_set_size_to(crop, &s->r); 790 crop->height /= factor; 791 v4l2_rect_map_inside(crop, &dev->fmt_out_rect); 792 } 793 s->r.top *= factor; 794 s->r.height *= factor; 795 *compose = s->r; 796 break; 797 default: 798 return -EINVAL; 799 } 800 801 return 0; 802 } 803 804 int vivid_vid_out_g_pixelaspect(struct file *file, void *priv, 805 int type, struct v4l2_fract *f) 806 { 807 struct vivid_dev *dev = video_drvdata(file); 808 809 if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 810 return -EINVAL; 811 812 switch (vivid_get_pixel_aspect(dev)) { 813 case TPG_PIXEL_ASPECT_NTSC: 814 f->numerator = 11; 815 f->denominator = 10; 816 break; 817 case TPG_PIXEL_ASPECT_PAL: 818 f->numerator = 54; 819 f->denominator = 59; 820 break; 821 default: 822 break; 823 } 824 return 0; 825 } 826 827 int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv, 828 struct v4l2_format *f) 829 { 830 struct vivid_dev *dev = video_drvdata(file); 831 const struct v4l2_rect *compose = &dev->compose_out; 832 struct v4l2_window *win = &f->fmt.win; 833 834 if (!dev->has_fb) 835 return -EINVAL; 836 win->w.top = dev->overlay_out_top; 837 win->w.left = dev->overlay_out_left; 838 win->w.width = compose->width; 839 win->w.height = compose->height; 840 win->field = V4L2_FIELD_ANY; 841 win->chromakey = dev->chromakey_out; 842 win->global_alpha = dev->global_alpha_out; 843 return 0; 844 } 845 846 int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv, 847 struct v4l2_format *f) 848 { 849 struct vivid_dev *dev = video_drvdata(file); 850 const struct v4l2_rect *compose = &dev->compose_out; 851 struct v4l2_window *win = &f->fmt.win; 852 853 if (!dev->has_fb) 854 return -EINVAL; 855 win->w.left = clamp_t(int, win->w.left, 856 -dev->display_width, dev->display_width); 857 win->w.top = clamp_t(int, win->w.top, 858 -dev->display_height, dev->display_height); 859 win->w.width = compose->width; 860 win->w.height = compose->height; 861 /* 862 * It makes no sense for an OSD to overlay only top or bottom fields, 863 * so always set this to ANY. 864 */ 865 win->field = V4L2_FIELD_ANY; 866 return 0; 867 } 868 869 int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv, 870 struct v4l2_format *f) 871 { 872 struct vivid_dev *dev = video_drvdata(file); 873 struct v4l2_window *win = &f->fmt.win; 874 int ret = vidioc_try_fmt_vid_out_overlay(file, priv, f); 875 876 if (ret) 877 return ret; 878 879 dev->overlay_out_top = win->w.top; 880 dev->overlay_out_left = win->w.left; 881 dev->chromakey_out = win->chromakey; 882 dev->global_alpha_out = win->global_alpha; 883 return ret; 884 } 885 886 int vivid_vid_out_overlay(struct file *file, void *fh, unsigned i) 887 { 888 struct vivid_dev *dev = video_drvdata(file); 889 890 if (i && !dev->fmt_out->can_do_overlay) { 891 dprintk(dev, 1, "unsupported output format for output overlay\n"); 892 return -EINVAL; 893 } 894 895 dev->overlay_out_enabled = i; 896 return 0; 897 } 898 899 int vivid_vid_out_g_fbuf(struct file *file, void *fh, 900 struct v4l2_framebuffer *a) 901 { 902 struct vivid_dev *dev = video_drvdata(file); 903 904 a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | 905 V4L2_FBUF_CAP_CHROMAKEY | 906 V4L2_FBUF_CAP_SRC_CHROMAKEY | 907 V4L2_FBUF_CAP_GLOBAL_ALPHA | 908 V4L2_FBUF_CAP_LOCAL_ALPHA | 909 V4L2_FBUF_CAP_LOCAL_INV_ALPHA; 910 a->flags = V4L2_FBUF_FLAG_OVERLAY | dev->fbuf_out_flags; 911 a->base = (void *)dev->video_pbase; 912 a->fmt.width = dev->display_width; 913 a->fmt.height = dev->display_height; 914 if (dev->fb_defined.green.length == 5) 915 a->fmt.pixelformat = V4L2_PIX_FMT_ARGB555; 916 else 917 a->fmt.pixelformat = V4L2_PIX_FMT_RGB565; 918 a->fmt.bytesperline = dev->display_byte_stride; 919 a->fmt.sizeimage = a->fmt.height * a->fmt.bytesperline; 920 a->fmt.field = V4L2_FIELD_NONE; 921 a->fmt.colorspace = V4L2_COLORSPACE_SRGB; 922 a->fmt.priv = 0; 923 return 0; 924 } 925 926 int vivid_vid_out_s_fbuf(struct file *file, void *fh, 927 const struct v4l2_framebuffer *a) 928 { 929 struct vivid_dev *dev = video_drvdata(file); 930 const unsigned chroma_flags = V4L2_FBUF_FLAG_CHROMAKEY | 931 V4L2_FBUF_FLAG_SRC_CHROMAKEY; 932 const unsigned alpha_flags = V4L2_FBUF_FLAG_GLOBAL_ALPHA | 933 V4L2_FBUF_FLAG_LOCAL_ALPHA | 934 V4L2_FBUF_FLAG_LOCAL_INV_ALPHA; 935 936 937 if ((a->flags & chroma_flags) == chroma_flags) 938 return -EINVAL; 939 switch (a->flags & alpha_flags) { 940 case 0: 941 case V4L2_FBUF_FLAG_GLOBAL_ALPHA: 942 case V4L2_FBUF_FLAG_LOCAL_ALPHA: 943 case V4L2_FBUF_FLAG_LOCAL_INV_ALPHA: 944 break; 945 default: 946 return -EINVAL; 947 } 948 dev->fbuf_out_flags &= ~(chroma_flags | alpha_flags); 949 dev->fbuf_out_flags |= a->flags & (chroma_flags | alpha_flags); 950 return 0; 951 } 952 953 static const struct v4l2_audioout vivid_audio_outputs[] = { 954 { 0, "Line-Out 1" }, 955 { 1, "Line-Out 2" }, 956 }; 957 958 int vidioc_enum_output(struct file *file, void *priv, 959 struct v4l2_output *out) 960 { 961 struct vivid_dev *dev = video_drvdata(file); 962 963 if (out->index >= dev->num_outputs) 964 return -EINVAL; 965 966 out->type = V4L2_OUTPUT_TYPE_ANALOG; 967 switch (dev->output_type[out->index]) { 968 case SVID: 969 snprintf(out->name, sizeof(out->name), "S-Video %03u-%u", 970 dev->inst, dev->output_name_counter[out->index]); 971 out->std = V4L2_STD_ALL; 972 if (dev->has_audio_outputs) 973 out->audioset = (1 << ARRAY_SIZE(vivid_audio_outputs)) - 1; 974 out->capabilities = V4L2_OUT_CAP_STD; 975 break; 976 case HDMI: 977 snprintf(out->name, sizeof(out->name), "HDMI %03u-%u", 978 dev->inst, dev->output_name_counter[out->index]); 979 out->capabilities = V4L2_OUT_CAP_DV_TIMINGS; 980 break; 981 } 982 return 0; 983 } 984 985 int vidioc_g_output(struct file *file, void *priv, unsigned *o) 986 { 987 struct vivid_dev *dev = video_drvdata(file); 988 989 *o = dev->output; 990 return 0; 991 } 992 993 int vidioc_s_output(struct file *file, void *priv, unsigned o) 994 { 995 struct vivid_dev *dev = video_drvdata(file); 996 997 if (o >= dev->num_outputs) 998 return -EINVAL; 999 1000 if (o == dev->output) 1001 return 0; 1002 1003 if (vb2_is_busy(&dev->vb_vid_out_q) || 1004 vb2_is_busy(&dev->vb_vbi_out_q) || 1005 vb2_is_busy(&dev->vb_meta_out_q)) 1006 return -EBUSY; 1007 1008 dev->output = o; 1009 dev->tv_audio_output = 0; 1010 if (dev->output_type[o] == SVID) 1011 dev->vid_out_dev.tvnorms = V4L2_STD_ALL; 1012 else 1013 dev->vid_out_dev.tvnorms = 0; 1014 1015 dev->vbi_out_dev.tvnorms = dev->vid_out_dev.tvnorms; 1016 dev->meta_out_dev.tvnorms = dev->vid_out_dev.tvnorms; 1017 vivid_update_format_out(dev); 1018 1019 v4l2_ctrl_activate(dev->ctrl_display_present, vivid_is_hdmi_out(dev)); 1020 if (vivid_is_hdmi_out(dev)) 1021 v4l2_ctrl_s_ctrl(dev->ctrl_display_present, 1022 dev->display_present[dev->output]); 1023 1024 return 0; 1025 } 1026 1027 int vidioc_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vout) 1028 { 1029 if (vout->index >= ARRAY_SIZE(vivid_audio_outputs)) 1030 return -EINVAL; 1031 *vout = vivid_audio_outputs[vout->index]; 1032 return 0; 1033 } 1034 1035 int vidioc_g_audout(struct file *file, void *fh, struct v4l2_audioout *vout) 1036 { 1037 struct vivid_dev *dev = video_drvdata(file); 1038 1039 if (!vivid_is_svid_out(dev)) 1040 return -EINVAL; 1041 *vout = vivid_audio_outputs[dev->tv_audio_output]; 1042 return 0; 1043 } 1044 1045 int vidioc_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout) 1046 { 1047 struct vivid_dev *dev = video_drvdata(file); 1048 1049 if (!vivid_is_svid_out(dev)) 1050 return -EINVAL; 1051 if (vout->index >= ARRAY_SIZE(vivid_audio_outputs)) 1052 return -EINVAL; 1053 dev->tv_audio_output = vout->index; 1054 return 0; 1055 } 1056 1057 int vivid_vid_out_s_std(struct file *file, void *priv, v4l2_std_id id) 1058 { 1059 struct vivid_dev *dev = video_drvdata(file); 1060 1061 if (!vivid_is_svid_out(dev)) 1062 return -ENODATA; 1063 if (dev->std_out == id) 1064 return 0; 1065 if (vb2_is_busy(&dev->vb_vid_out_q) || vb2_is_busy(&dev->vb_vbi_out_q)) 1066 return -EBUSY; 1067 dev->std_out = id; 1068 vivid_update_format_out(dev); 1069 return 0; 1070 } 1071 1072 static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings) 1073 { 1074 struct v4l2_bt_timings *bt = &timings->bt; 1075 1076 if ((bt->standards & (V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF)) && 1077 v4l2_valid_dv_timings(timings, &vivid_dv_timings_cap, NULL, NULL)) 1078 return true; 1079 1080 return false; 1081 } 1082 1083 int vivid_vid_out_s_dv_timings(struct file *file, void *_fh, 1084 struct v4l2_dv_timings *timings) 1085 { 1086 struct vivid_dev *dev = video_drvdata(file); 1087 if (!vivid_is_hdmi_out(dev)) 1088 return -ENODATA; 1089 if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap, 1090 0, NULL, NULL) && 1091 !valid_cvt_gtf_timings(timings)) 1092 return -EINVAL; 1093 if (v4l2_match_dv_timings(timings, &dev->dv_timings_out, 0, true)) 1094 return 0; 1095 if (vb2_is_busy(&dev->vb_vid_out_q)) 1096 return -EBUSY; 1097 dev->dv_timings_out = *timings; 1098 vivid_update_format_out(dev); 1099 return 0; 1100 } 1101 1102 int vivid_vid_out_g_parm(struct file *file, void *priv, 1103 struct v4l2_streamparm *parm) 1104 { 1105 struct vivid_dev *dev = video_drvdata(file); 1106 1107 if (parm->type != (dev->multiplanar ? 1108 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : 1109 V4L2_BUF_TYPE_VIDEO_OUTPUT)) 1110 return -EINVAL; 1111 1112 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 1113 parm->parm.output.timeperframe = dev->timeperframe_vid_out; 1114 parm->parm.output.writebuffers = 1; 1115 1116 return 0; 1117 } 1118 1119 int vidioc_subscribe_event(struct v4l2_fh *fh, 1120 const struct v4l2_event_subscription *sub) 1121 { 1122 switch (sub->type) { 1123 case V4L2_EVENT_SOURCE_CHANGE: 1124 if (fh->vdev->vfl_dir == VFL_DIR_RX) 1125 return v4l2_src_change_event_subscribe(fh, sub); 1126 break; 1127 default: 1128 return v4l2_ctrl_subscribe_event(fh, sub); 1129 } 1130 return -EINVAL; 1131 } 1132