Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.10 864 lines 20 kB view raw
1/* 2 * vivid-vid-common.c - common video support functions. 3 * 4 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 5 * 6 * This program is free software; you may redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 * SOFTWARE. 18 */ 19 20#include <linux/errno.h> 21#include <linux/kernel.h> 22#include <linux/sched.h> 23#include <linux/videodev2.h> 24#include <linux/v4l2-dv-timings.h> 25#include <media/v4l2-common.h> 26#include <media/v4l2-event.h> 27#include <media/v4l2-dv-timings.h> 28 29#include "vivid-core.h" 30#include "vivid-vid-common.h" 31 32const struct v4l2_dv_timings_cap vivid_dv_timings_cap = { 33 .type = V4L2_DV_BT_656_1120, 34 /* keep this initialization for compatibility with GCC < 4.4.6 */ 35 .reserved = { 0 }, 36 V4L2_INIT_BT_TIMINGS(0, MAX_WIDTH, 0, MAX_HEIGHT, 14000000, 775000000, 37 V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | 38 V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF, 39 V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED) 40}; 41 42/* ------------------------------------------------------------------ 43 Basic structures 44 ------------------------------------------------------------------*/ 45 46struct vivid_fmt vivid_formats[] = { 47 { 48 .fourcc = V4L2_PIX_FMT_YUYV, 49 .vdownsampling = { 1 }, 50 .bit_depth = { 16 }, 51 .color_enc = TGP_COLOR_ENC_YCBCR, 52 .planes = 1, 53 .buffers = 1, 54 .data_offset = { PLANE0_DATA_OFFSET }, 55 }, 56 { 57 .fourcc = V4L2_PIX_FMT_UYVY, 58 .vdownsampling = { 1 }, 59 .bit_depth = { 16 }, 60 .color_enc = TGP_COLOR_ENC_YCBCR, 61 .planes = 1, 62 .buffers = 1, 63 }, 64 { 65 .fourcc = V4L2_PIX_FMT_YVYU, 66 .vdownsampling = { 1 }, 67 .bit_depth = { 16 }, 68 .color_enc = TGP_COLOR_ENC_YCBCR, 69 .planes = 1, 70 .buffers = 1, 71 }, 72 { 73 .fourcc = V4L2_PIX_FMT_VYUY, 74 .vdownsampling = { 1 }, 75 .bit_depth = { 16 }, 76 .color_enc = TGP_COLOR_ENC_YCBCR, 77 .planes = 1, 78 .buffers = 1, 79 }, 80 { 81 .fourcc = V4L2_PIX_FMT_YUV422P, 82 .vdownsampling = { 1, 1, 1 }, 83 .bit_depth = { 8, 4, 4 }, 84 .color_enc = TGP_COLOR_ENC_YCBCR, 85 .planes = 3, 86 .buffers = 1, 87 }, 88 { 89 .fourcc = V4L2_PIX_FMT_YUV420, 90 .vdownsampling = { 1, 2, 2 }, 91 .bit_depth = { 8, 4, 4 }, 92 .color_enc = TGP_COLOR_ENC_YCBCR, 93 .planes = 3, 94 .buffers = 1, 95 }, 96 { 97 .fourcc = V4L2_PIX_FMT_YVU420, 98 .vdownsampling = { 1, 2, 2 }, 99 .bit_depth = { 8, 4, 4 }, 100 .color_enc = TGP_COLOR_ENC_YCBCR, 101 .planes = 3, 102 .buffers = 1, 103 }, 104 { 105 .fourcc = V4L2_PIX_FMT_NV12, 106 .vdownsampling = { 1, 2 }, 107 .bit_depth = { 8, 8 }, 108 .color_enc = TGP_COLOR_ENC_YCBCR, 109 .planes = 2, 110 .buffers = 1, 111 }, 112 { 113 .fourcc = V4L2_PIX_FMT_NV21, 114 .vdownsampling = { 1, 2 }, 115 .bit_depth = { 8, 8 }, 116 .color_enc = TGP_COLOR_ENC_YCBCR, 117 .planes = 2, 118 .buffers = 1, 119 }, 120 { 121 .fourcc = V4L2_PIX_FMT_NV16, 122 .vdownsampling = { 1, 1 }, 123 .bit_depth = { 8, 8 }, 124 .color_enc = TGP_COLOR_ENC_YCBCR, 125 .planes = 2, 126 .buffers = 1, 127 }, 128 { 129 .fourcc = V4L2_PIX_FMT_NV61, 130 .vdownsampling = { 1, 1 }, 131 .bit_depth = { 8, 8 }, 132 .color_enc = TGP_COLOR_ENC_YCBCR, 133 .planes = 2, 134 .buffers = 1, 135 }, 136 { 137 .fourcc = V4L2_PIX_FMT_NV24, 138 .vdownsampling = { 1, 1 }, 139 .bit_depth = { 8, 16 }, 140 .color_enc = TGP_COLOR_ENC_YCBCR, 141 .planes = 2, 142 .buffers = 1, 143 }, 144 { 145 .fourcc = V4L2_PIX_FMT_NV42, 146 .vdownsampling = { 1, 1 }, 147 .bit_depth = { 8, 16 }, 148 .color_enc = TGP_COLOR_ENC_YCBCR, 149 .planes = 2, 150 .buffers = 1, 151 }, 152 { 153 .fourcc = V4L2_PIX_FMT_YUV555, /* uuuvvvvv ayyyyyuu */ 154 .vdownsampling = { 1 }, 155 .bit_depth = { 16 }, 156 .planes = 1, 157 .buffers = 1, 158 .alpha_mask = 0x8000, 159 }, 160 { 161 .fourcc = V4L2_PIX_FMT_YUV565, /* uuuvvvvv yyyyyuuu */ 162 .vdownsampling = { 1 }, 163 .bit_depth = { 16 }, 164 .planes = 1, 165 .buffers = 1, 166 }, 167 { 168 .fourcc = V4L2_PIX_FMT_YUV444, /* uuuuvvvv aaaayyyy */ 169 .vdownsampling = { 1 }, 170 .bit_depth = { 16 }, 171 .planes = 1, 172 .buffers = 1, 173 .alpha_mask = 0xf000, 174 }, 175 { 176 .fourcc = V4L2_PIX_FMT_YUV32, /* ayuv */ 177 .vdownsampling = { 1 }, 178 .bit_depth = { 32 }, 179 .planes = 1, 180 .buffers = 1, 181 .alpha_mask = 0x000000ff, 182 }, 183 { 184 .fourcc = V4L2_PIX_FMT_GREY, 185 .vdownsampling = { 1 }, 186 .bit_depth = { 8 }, 187 .color_enc = TGP_COLOR_ENC_LUMA, 188 .planes = 1, 189 .buffers = 1, 190 }, 191 { 192 .fourcc = V4L2_PIX_FMT_Y16, 193 .vdownsampling = { 1 }, 194 .bit_depth = { 16 }, 195 .color_enc = TGP_COLOR_ENC_LUMA, 196 .planes = 1, 197 .buffers = 1, 198 }, 199 { 200 .fourcc = V4L2_PIX_FMT_Y16_BE, 201 .vdownsampling = { 1 }, 202 .bit_depth = { 16 }, 203 .color_enc = TGP_COLOR_ENC_LUMA, 204 .planes = 1, 205 .buffers = 1, 206 }, 207 { 208 .fourcc = V4L2_PIX_FMT_RGB332, /* rrrgggbb */ 209 .vdownsampling = { 1 }, 210 .bit_depth = { 8 }, 211 .planes = 1, 212 .buffers = 1, 213 }, 214 { 215 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ 216 .vdownsampling = { 1 }, 217 .bit_depth = { 16 }, 218 .planes = 1, 219 .buffers = 1, 220 .can_do_overlay = true, 221 }, 222 { 223 .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ 224 .vdownsampling = { 1 }, 225 .bit_depth = { 16 }, 226 .planes = 1, 227 .buffers = 1, 228 .can_do_overlay = true, 229 }, 230 { 231 .fourcc = V4L2_PIX_FMT_RGB444, /* xxxxrrrr ggggbbbb */ 232 .vdownsampling = { 1 }, 233 .bit_depth = { 16 }, 234 .planes = 1, 235 .buffers = 1, 236 }, 237 { 238 .fourcc = V4L2_PIX_FMT_XRGB444, /* xxxxrrrr ggggbbbb */ 239 .vdownsampling = { 1 }, 240 .bit_depth = { 16 }, 241 .planes = 1, 242 .buffers = 1, 243 }, 244 { 245 .fourcc = V4L2_PIX_FMT_ARGB444, /* aaaarrrr ggggbbbb */ 246 .vdownsampling = { 1 }, 247 .bit_depth = { 16 }, 248 .planes = 1, 249 .buffers = 1, 250 .alpha_mask = 0x00f0, 251 }, 252 { 253 .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb xrrrrrgg */ 254 .vdownsampling = { 1 }, 255 .bit_depth = { 16 }, 256 .planes = 1, 257 .buffers = 1, 258 .can_do_overlay = true, 259 }, 260 { 261 .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb xrrrrrgg */ 262 .vdownsampling = { 1 }, 263 .bit_depth = { 16 }, 264 .planes = 1, 265 .buffers = 1, 266 .can_do_overlay = true, 267 }, 268 { 269 .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ 270 .vdownsampling = { 1 }, 271 .bit_depth = { 16 }, 272 .planes = 1, 273 .buffers = 1, 274 .can_do_overlay = true, 275 .alpha_mask = 0x8000, 276 }, 277 { 278 .fourcc = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */ 279 .vdownsampling = { 1 }, 280 .bit_depth = { 16 }, 281 .planes = 1, 282 .buffers = 1, 283 }, 284 { 285 .fourcc = V4L2_PIX_FMT_XRGB555X, /* xrrrrrgg gggbbbbb */ 286 .vdownsampling = { 1 }, 287 .bit_depth = { 16 }, 288 .planes = 1, 289 .buffers = 1, 290 }, 291 { 292 .fourcc = V4L2_PIX_FMT_ARGB555X, /* arrrrrgg gggbbbbb */ 293 .vdownsampling = { 1 }, 294 .bit_depth = { 16 }, 295 .planes = 1, 296 .buffers = 1, 297 .alpha_mask = 0x0080, 298 }, 299 { 300 .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ 301 .vdownsampling = { 1 }, 302 .bit_depth = { 24 }, 303 .planes = 1, 304 .buffers = 1, 305 }, 306 { 307 .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ 308 .vdownsampling = { 1 }, 309 .bit_depth = { 24 }, 310 .planes = 1, 311 .buffers = 1, 312 }, 313 { 314 .fourcc = V4L2_PIX_FMT_BGR666, /* bbbbbbgg ggggrrrr rrxxxxxx */ 315 .vdownsampling = { 1 }, 316 .bit_depth = { 32 }, 317 .planes = 1, 318 .buffers = 1, 319 }, 320 { 321 .fourcc = V4L2_PIX_FMT_RGB32, /* xrgb */ 322 .vdownsampling = { 1 }, 323 .bit_depth = { 32 }, 324 .planes = 1, 325 .buffers = 1, 326 }, 327 { 328 .fourcc = V4L2_PIX_FMT_BGR32, /* bgrx */ 329 .vdownsampling = { 1 }, 330 .bit_depth = { 32 }, 331 .planes = 1, 332 .buffers = 1, 333 }, 334 { 335 .fourcc = V4L2_PIX_FMT_XRGB32, /* xrgb */ 336 .vdownsampling = { 1 }, 337 .bit_depth = { 32 }, 338 .planes = 1, 339 .buffers = 1, 340 }, 341 { 342 .fourcc = V4L2_PIX_FMT_XBGR32, /* bgrx */ 343 .vdownsampling = { 1 }, 344 .bit_depth = { 32 }, 345 .planes = 1, 346 .buffers = 1, 347 }, 348 { 349 .fourcc = V4L2_PIX_FMT_ARGB32, /* argb */ 350 .vdownsampling = { 1 }, 351 .bit_depth = { 32 }, 352 .planes = 1, 353 .buffers = 1, 354 .alpha_mask = 0x000000ff, 355 }, 356 { 357 .fourcc = V4L2_PIX_FMT_ABGR32, /* bgra */ 358 .vdownsampling = { 1 }, 359 .bit_depth = { 32 }, 360 .planes = 1, 361 .buffers = 1, 362 .alpha_mask = 0xff000000, 363 }, 364 { 365 .fourcc = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */ 366 .vdownsampling = { 1 }, 367 .bit_depth = { 8 }, 368 .planes = 1, 369 .buffers = 1, 370 }, 371 { 372 .fourcc = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */ 373 .vdownsampling = { 1 }, 374 .bit_depth = { 8 }, 375 .planes = 1, 376 .buffers = 1, 377 }, 378 { 379 .fourcc = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */ 380 .vdownsampling = { 1 }, 381 .bit_depth = { 8 }, 382 .planes = 1, 383 .buffers = 1, 384 }, 385 { 386 .fourcc = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */ 387 .vdownsampling = { 1 }, 388 .bit_depth = { 8 }, 389 .planes = 1, 390 .buffers = 1, 391 }, 392 { 393 .fourcc = V4L2_PIX_FMT_SBGGR10, /* Bayer BG/GR */ 394 .vdownsampling = { 1 }, 395 .bit_depth = { 16 }, 396 .planes = 1, 397 .buffers = 1, 398 }, 399 { 400 .fourcc = V4L2_PIX_FMT_SGBRG10, /* Bayer GB/RG */ 401 .vdownsampling = { 1 }, 402 .bit_depth = { 16 }, 403 .planes = 1, 404 .buffers = 1, 405 }, 406 { 407 .fourcc = V4L2_PIX_FMT_SGRBG10, /* Bayer GR/BG */ 408 .vdownsampling = { 1 }, 409 .bit_depth = { 16 }, 410 .planes = 1, 411 .buffers = 1, 412 }, 413 { 414 .fourcc = V4L2_PIX_FMT_SRGGB10, /* Bayer RG/GB */ 415 .vdownsampling = { 1 }, 416 .bit_depth = { 16 }, 417 .planes = 1, 418 .buffers = 1, 419 }, 420 { 421 .fourcc = V4L2_PIX_FMT_SBGGR12, /* Bayer BG/GR */ 422 .vdownsampling = { 1 }, 423 .bit_depth = { 16 }, 424 .planes = 1, 425 .buffers = 1, 426 }, 427 { 428 .fourcc = V4L2_PIX_FMT_SGBRG12, /* Bayer GB/RG */ 429 .vdownsampling = { 1 }, 430 .bit_depth = { 16 }, 431 .planes = 1, 432 .buffers = 1, 433 }, 434 { 435 .fourcc = V4L2_PIX_FMT_SGRBG12, /* Bayer GR/BG */ 436 .vdownsampling = { 1 }, 437 .bit_depth = { 16 }, 438 .planes = 1, 439 .buffers = 1, 440 }, 441 { 442 .fourcc = V4L2_PIX_FMT_SRGGB12, /* Bayer RG/GB */ 443 .vdownsampling = { 1 }, 444 .bit_depth = { 16 }, 445 .planes = 1, 446 .buffers = 1, 447 }, 448 { 449 .fourcc = V4L2_PIX_FMT_HSV24, /* HSV 24bits */ 450 .color_enc = TGP_COLOR_ENC_HSV, 451 .vdownsampling = { 1 }, 452 .bit_depth = { 24 }, 453 .planes = 1, 454 .buffers = 1, 455 }, 456 { 457 .fourcc = V4L2_PIX_FMT_HSV32, /* HSV 32bits */ 458 .color_enc = TGP_COLOR_ENC_HSV, 459 .vdownsampling = { 1 }, 460 .bit_depth = { 32 }, 461 .planes = 1, 462 .buffers = 1, 463 }, 464 465 /* Multiplanar formats */ 466 467 { 468 .fourcc = V4L2_PIX_FMT_NV16M, 469 .vdownsampling = { 1, 1 }, 470 .bit_depth = { 8, 8 }, 471 .color_enc = TGP_COLOR_ENC_YCBCR, 472 .planes = 2, 473 .buffers = 2, 474 .data_offset = { PLANE0_DATA_OFFSET, 0 }, 475 }, 476 { 477 .fourcc = V4L2_PIX_FMT_NV61M, 478 .vdownsampling = { 1, 1 }, 479 .bit_depth = { 8, 8 }, 480 .color_enc = TGP_COLOR_ENC_YCBCR, 481 .planes = 2, 482 .buffers = 2, 483 .data_offset = { 0, PLANE0_DATA_OFFSET }, 484 }, 485 { 486 .fourcc = V4L2_PIX_FMT_YUV420M, 487 .vdownsampling = { 1, 2, 2 }, 488 .bit_depth = { 8, 4, 4 }, 489 .color_enc = TGP_COLOR_ENC_YCBCR, 490 .planes = 3, 491 .buffers = 3, 492 }, 493 { 494 .fourcc = V4L2_PIX_FMT_YVU420M, 495 .vdownsampling = { 1, 2, 2 }, 496 .bit_depth = { 8, 4, 4 }, 497 .color_enc = TGP_COLOR_ENC_YCBCR, 498 .planes = 3, 499 .buffers = 3, 500 }, 501 { 502 .fourcc = V4L2_PIX_FMT_NV12M, 503 .vdownsampling = { 1, 2 }, 504 .bit_depth = { 8, 8 }, 505 .color_enc = TGP_COLOR_ENC_YCBCR, 506 .planes = 2, 507 .buffers = 2, 508 }, 509 { 510 .fourcc = V4L2_PIX_FMT_NV21M, 511 .vdownsampling = { 1, 2 }, 512 .bit_depth = { 8, 8 }, 513 .color_enc = TGP_COLOR_ENC_YCBCR, 514 .planes = 2, 515 .buffers = 2, 516 }, 517 { 518 .fourcc = V4L2_PIX_FMT_YUV422M, 519 .vdownsampling = { 1, 1, 1 }, 520 .bit_depth = { 8, 4, 4 }, 521 .color_enc = TGP_COLOR_ENC_YCBCR, 522 .planes = 3, 523 .buffers = 3, 524 }, 525 { 526 .fourcc = V4L2_PIX_FMT_YVU422M, 527 .vdownsampling = { 1, 1, 1 }, 528 .bit_depth = { 8, 4, 4 }, 529 .color_enc = TGP_COLOR_ENC_YCBCR, 530 .planes = 3, 531 .buffers = 3, 532 }, 533 { 534 .fourcc = V4L2_PIX_FMT_YUV444M, 535 .vdownsampling = { 1, 1, 1 }, 536 .bit_depth = { 8, 8, 8 }, 537 .color_enc = TGP_COLOR_ENC_YCBCR, 538 .planes = 3, 539 .buffers = 3, 540 }, 541 { 542 .fourcc = V4L2_PIX_FMT_YVU444M, 543 .vdownsampling = { 1, 1, 1 }, 544 .bit_depth = { 8, 8, 8 }, 545 .color_enc = TGP_COLOR_ENC_YCBCR, 546 .planes = 3, 547 .buffers = 3, 548 }, 549}; 550 551/* There are this many multiplanar formats in the list */ 552#define VIVID_MPLANAR_FORMATS 10 553 554const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat) 555{ 556 const struct vivid_fmt *fmt; 557 unsigned k; 558 559 for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) { 560 fmt = &vivid_formats[k]; 561 if (fmt->fourcc == pixelformat) 562 if (fmt->buffers == 1 || dev->multiplanar) 563 return fmt; 564 } 565 566 return NULL; 567} 568 569bool vivid_vid_can_loop(struct vivid_dev *dev) 570{ 571 if (dev->src_rect.width != dev->sink_rect.width || 572 dev->src_rect.height != dev->sink_rect.height) 573 return false; 574 if (dev->fmt_cap->fourcc != dev->fmt_out->fourcc) 575 return false; 576 if (dev->field_cap != dev->field_out) 577 return false; 578 /* 579 * While this can be supported, it is just too much work 580 * to actually implement. 581 */ 582 if (dev->field_cap == V4L2_FIELD_SEQ_TB || 583 dev->field_cap == V4L2_FIELD_SEQ_BT) 584 return false; 585 if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) { 586 if (!(dev->std_cap & V4L2_STD_525_60) != 587 !(dev->std_out & V4L2_STD_525_60)) 588 return false; 589 return true; 590 } 591 if (vivid_is_hdmi_cap(dev) && vivid_is_hdmi_out(dev)) 592 return true; 593 return false; 594} 595 596void vivid_send_source_change(struct vivid_dev *dev, unsigned type) 597{ 598 struct v4l2_event ev = { 599 .type = V4L2_EVENT_SOURCE_CHANGE, 600 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, 601 }; 602 unsigned i; 603 604 for (i = 0; i < dev->num_inputs; i++) { 605 ev.id = i; 606 if (dev->input_type[i] == type) { 607 if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap) 608 v4l2_event_queue(&dev->vid_cap_dev, &ev); 609 if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap) 610 v4l2_event_queue(&dev->vbi_cap_dev, &ev); 611 } 612 } 613} 614 615/* 616 * Conversion function that converts a single-planar format to a 617 * single-plane multiplanar format. 618 */ 619void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt) 620{ 621 struct v4l2_pix_format_mplane *mp = &mp_fmt->fmt.pix_mp; 622 struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0]; 623 const struct v4l2_pix_format *pix = &sp_fmt->fmt.pix; 624 bool is_out = sp_fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT; 625 626 memset(mp->reserved, 0, sizeof(mp->reserved)); 627 mp_fmt->type = is_out ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : 628 V4L2_CAP_VIDEO_CAPTURE_MPLANE; 629 mp->width = pix->width; 630 mp->height = pix->height; 631 mp->pixelformat = pix->pixelformat; 632 mp->field = pix->field; 633 mp->colorspace = pix->colorspace; 634 mp->xfer_func = pix->xfer_func; 635 /* Also copies hsv_enc */ 636 mp->ycbcr_enc = pix->ycbcr_enc; 637 mp->quantization = pix->quantization; 638 mp->num_planes = 1; 639 mp->flags = pix->flags; 640 ppix->sizeimage = pix->sizeimage; 641 ppix->bytesperline = pix->bytesperline; 642 memset(ppix->reserved, 0, sizeof(ppix->reserved)); 643} 644 645int fmt_sp2mp_func(struct file *file, void *priv, 646 struct v4l2_format *f, fmtfunc func) 647{ 648 struct v4l2_format fmt; 649 struct v4l2_pix_format_mplane *mp = &fmt.fmt.pix_mp; 650 struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0]; 651 struct v4l2_pix_format *pix = &f->fmt.pix; 652 int ret; 653 654 /* Converts to a mplane format */ 655 fmt_sp2mp(f, &fmt); 656 /* Passes it to the generic mplane format function */ 657 ret = func(file, priv, &fmt); 658 /* Copies back the mplane data to the single plane format */ 659 pix->width = mp->width; 660 pix->height = mp->height; 661 pix->pixelformat = mp->pixelformat; 662 pix->field = mp->field; 663 pix->colorspace = mp->colorspace; 664 pix->xfer_func = mp->xfer_func; 665 /* Also copies hsv_enc */ 666 pix->ycbcr_enc = mp->ycbcr_enc; 667 pix->quantization = mp->quantization; 668 pix->sizeimage = ppix->sizeimage; 669 pix->bytesperline = ppix->bytesperline; 670 pix->flags = mp->flags; 671 return ret; 672} 673 674int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r) 675{ 676 unsigned w = r->width; 677 unsigned h = r->height; 678 679 /* sanitize w and h in case someone passes ~0 as the value */ 680 w &= 0xffff; 681 h &= 0xffff; 682 if (!(flags & V4L2_SEL_FLAG_LE)) { 683 w++; 684 h++; 685 if (w < 2) 686 w = 2; 687 if (h < 2) 688 h = 2; 689 } 690 if (!(flags & V4L2_SEL_FLAG_GE)) { 691 if (w > MAX_WIDTH) 692 w = MAX_WIDTH; 693 if (h > MAX_HEIGHT) 694 h = MAX_HEIGHT; 695 } 696 w = w & ~1; 697 h = h & ~1; 698 if (w < 2 || h < 2) 699 return -ERANGE; 700 if (w > MAX_WIDTH || h > MAX_HEIGHT) 701 return -ERANGE; 702 if (r->top < 0) 703 r->top = 0; 704 if (r->left < 0) 705 r->left = 0; 706 /* sanitize left and top in case someone passes ~0 as the value */ 707 r->left &= 0xfffe; 708 r->top &= 0xfffe; 709 if (r->left + w > MAX_WIDTH) 710 r->left = MAX_WIDTH - w; 711 if (r->top + h > MAX_HEIGHT) 712 r->top = MAX_HEIGHT - h; 713 if ((flags & (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE)) == 714 (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE) && 715 (r->width != w || r->height != h)) 716 return -ERANGE; 717 r->width = w; 718 r->height = h; 719 return 0; 720} 721 722int vivid_enum_fmt_vid(struct file *file, void *priv, 723 struct v4l2_fmtdesc *f) 724{ 725 struct vivid_dev *dev = video_drvdata(file); 726 const struct vivid_fmt *fmt; 727 728 if (f->index >= ARRAY_SIZE(vivid_formats) - 729 (dev->multiplanar ? 0 : VIVID_MPLANAR_FORMATS)) 730 return -EINVAL; 731 732 fmt = &vivid_formats[f->index]; 733 734 f->pixelformat = fmt->fourcc; 735 return 0; 736} 737 738int vidioc_enum_fmt_vid_mplane(struct file *file, void *priv, 739 struct v4l2_fmtdesc *f) 740{ 741 struct vivid_dev *dev = video_drvdata(file); 742 743 if (!dev->multiplanar) 744 return -ENOTTY; 745 return vivid_enum_fmt_vid(file, priv, f); 746} 747 748int vidioc_enum_fmt_vid(struct file *file, void *priv, 749 struct v4l2_fmtdesc *f) 750{ 751 struct vivid_dev *dev = video_drvdata(file); 752 753 if (dev->multiplanar) 754 return -ENOTTY; 755 return vivid_enum_fmt_vid(file, priv, f); 756} 757 758int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) 759{ 760 struct vivid_dev *dev = video_drvdata(file); 761 struct video_device *vdev = video_devdata(file); 762 763 if (vdev->vfl_dir == VFL_DIR_RX) { 764 if (!vivid_is_sdtv_cap(dev)) 765 return -ENODATA; 766 *id = dev->std_cap; 767 } else { 768 if (!vivid_is_svid_out(dev)) 769 return -ENODATA; 770 *id = dev->std_out; 771 } 772 return 0; 773} 774 775int vidioc_g_dv_timings(struct file *file, void *_fh, 776 struct v4l2_dv_timings *timings) 777{ 778 struct vivid_dev *dev = video_drvdata(file); 779 struct video_device *vdev = video_devdata(file); 780 781 if (vdev->vfl_dir == VFL_DIR_RX) { 782 if (!vivid_is_hdmi_cap(dev)) 783 return -ENODATA; 784 *timings = dev->dv_timings_cap; 785 } else { 786 if (!vivid_is_hdmi_out(dev)) 787 return -ENODATA; 788 *timings = dev->dv_timings_out; 789 } 790 return 0; 791} 792 793int vidioc_enum_dv_timings(struct file *file, void *_fh, 794 struct v4l2_enum_dv_timings *timings) 795{ 796 struct vivid_dev *dev = video_drvdata(file); 797 struct video_device *vdev = video_devdata(file); 798 799 if (vdev->vfl_dir == VFL_DIR_RX) { 800 if (!vivid_is_hdmi_cap(dev)) 801 return -ENODATA; 802 } else { 803 if (!vivid_is_hdmi_out(dev)) 804 return -ENODATA; 805 } 806 return v4l2_enum_dv_timings_cap(timings, &vivid_dv_timings_cap, 807 NULL, NULL); 808} 809 810int vidioc_dv_timings_cap(struct file *file, void *_fh, 811 struct v4l2_dv_timings_cap *cap) 812{ 813 struct vivid_dev *dev = video_drvdata(file); 814 struct video_device *vdev = video_devdata(file); 815 816 if (vdev->vfl_dir == VFL_DIR_RX) { 817 if (!vivid_is_hdmi_cap(dev)) 818 return -ENODATA; 819 } else { 820 if (!vivid_is_hdmi_out(dev)) 821 return -ENODATA; 822 } 823 *cap = vivid_dv_timings_cap; 824 return 0; 825} 826 827int vidioc_g_edid(struct file *file, void *_fh, 828 struct v4l2_edid *edid) 829{ 830 struct vivid_dev *dev = video_drvdata(file); 831 struct video_device *vdev = video_devdata(file); 832 struct cec_adapter *adap; 833 834 memset(edid->reserved, 0, sizeof(edid->reserved)); 835 if (vdev->vfl_dir == VFL_DIR_RX) { 836 if (edid->pad >= dev->num_inputs) 837 return -EINVAL; 838 if (dev->input_type[edid->pad] != HDMI) 839 return -EINVAL; 840 adap = dev->cec_rx_adap; 841 } else { 842 unsigned int bus_idx; 843 844 if (edid->pad >= dev->num_outputs) 845 return -EINVAL; 846 if (dev->output_type[edid->pad] != HDMI) 847 return -EINVAL; 848 bus_idx = dev->cec_output2bus_map[edid->pad]; 849 adap = dev->cec_tx_adap[bus_idx]; 850 } 851 if (edid->start_block == 0 && edid->blocks == 0) { 852 edid->blocks = dev->edid_blocks; 853 return 0; 854 } 855 if (dev->edid_blocks == 0) 856 return -ENODATA; 857 if (edid->start_block >= dev->edid_blocks) 858 return -EINVAL; 859 if (edid->start_block + edid->blocks > dev->edid_blocks) 860 edid->blocks = dev->edid_blocks - edid->start_block; 861 memcpy(edid->edid, dev->edid, edid->blocks * 128); 862 cec_set_edid_phys_addr(edid->edid, edid->blocks * 128, adap->phys_addr); 863 return 0; 864}