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