1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * vivid-vid-common.c - common video 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 17 #include "vivid-core.h" 18 #include "vivid-vid-common.h" 19 20 const struct v4l2_dv_timings_cap vivid_dv_timings_cap = { 21 .type = V4L2_DV_BT_656_1120, 22 /* keep this initialization for compatibility with GCC < 4.4.6 */ 23 .reserved = { 0 }, 24 V4L2_INIT_BT_TIMINGS(16, MAX_WIDTH, 16, MAX_HEIGHT, 14000000, 775000000, 25 V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | 26 V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF, 27 V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED) 28 }; 29 30 /* ------------------------------------------------------------------ 31 Basic structures 32 ------------------------------------------------------------------*/ 33 34 struct vivid_fmt vivid_formats[] = { 35 { 36 .fourcc = V4L2_PIX_FMT_YUYV, 37 .vdownsampling = { 1 }, 38 .bit_depth = { 16 }, 39 .color_enc = TGP_COLOR_ENC_YCBCR, 40 .planes = 1, 41 .buffers = 1, 42 .data_offset = { PLANE0_DATA_OFFSET }, 43 }, 44 { 45 .fourcc = V4L2_PIX_FMT_UYVY, 46 .vdownsampling = { 1 }, 47 .bit_depth = { 16 }, 48 .color_enc = TGP_COLOR_ENC_YCBCR, 49 .planes = 1, 50 .buffers = 1, 51 }, 52 { 53 .fourcc = V4L2_PIX_FMT_YVYU, 54 .vdownsampling = { 1 }, 55 .bit_depth = { 16 }, 56 .color_enc = TGP_COLOR_ENC_YCBCR, 57 .planes = 1, 58 .buffers = 1, 59 }, 60 { 61 .fourcc = V4L2_PIX_FMT_VYUY, 62 .vdownsampling = { 1 }, 63 .bit_depth = { 16 }, 64 .color_enc = TGP_COLOR_ENC_YCBCR, 65 .planes = 1, 66 .buffers = 1, 67 }, 68 { 69 .fourcc = V4L2_PIX_FMT_YUV422P, 70 .vdownsampling = { 1, 1, 1 }, 71 .bit_depth = { 8, 4, 4 }, 72 .color_enc = TGP_COLOR_ENC_YCBCR, 73 .planes = 3, 74 .buffers = 1, 75 }, 76 { 77 .fourcc = V4L2_PIX_FMT_YUV420, 78 .vdownsampling = { 1, 2, 2 }, 79 .bit_depth = { 8, 4, 4 }, 80 .color_enc = TGP_COLOR_ENC_YCBCR, 81 .planes = 3, 82 .buffers = 1, 83 }, 84 { 85 .fourcc = V4L2_PIX_FMT_YVU420, 86 .vdownsampling = { 1, 2, 2 }, 87 .bit_depth = { 8, 4, 4 }, 88 .color_enc = TGP_COLOR_ENC_YCBCR, 89 .planes = 3, 90 .buffers = 1, 91 }, 92 { 93 .fourcc = V4L2_PIX_FMT_NV12, 94 .vdownsampling = { 1, 2 }, 95 .bit_depth = { 8, 8 }, 96 .color_enc = TGP_COLOR_ENC_YCBCR, 97 .planes = 2, 98 .buffers = 1, 99 }, 100 { 101 .fourcc = V4L2_PIX_FMT_NV21, 102 .vdownsampling = { 1, 2 }, 103 .bit_depth = { 8, 8 }, 104 .color_enc = TGP_COLOR_ENC_YCBCR, 105 .planes = 2, 106 .buffers = 1, 107 }, 108 { 109 .fourcc = V4L2_PIX_FMT_NV16, 110 .vdownsampling = { 1, 1 }, 111 .bit_depth = { 8, 8 }, 112 .color_enc = TGP_COLOR_ENC_YCBCR, 113 .planes = 2, 114 .buffers = 1, 115 }, 116 { 117 .fourcc = V4L2_PIX_FMT_NV61, 118 .vdownsampling = { 1, 1 }, 119 .bit_depth = { 8, 8 }, 120 .color_enc = TGP_COLOR_ENC_YCBCR, 121 .planes = 2, 122 .buffers = 1, 123 }, 124 { 125 .fourcc = V4L2_PIX_FMT_NV24, 126 .vdownsampling = { 1, 1 }, 127 .bit_depth = { 8, 16 }, 128 .color_enc = TGP_COLOR_ENC_YCBCR, 129 .planes = 2, 130 .buffers = 1, 131 }, 132 { 133 .fourcc = V4L2_PIX_FMT_NV42, 134 .vdownsampling = { 1, 1 }, 135 .bit_depth = { 8, 16 }, 136 .color_enc = TGP_COLOR_ENC_YCBCR, 137 .planes = 2, 138 .buffers = 1, 139 }, 140 { 141 .fourcc = V4L2_PIX_FMT_YUV555, /* uuuvvvvv ayyyyyuu */ 142 .vdownsampling = { 1 }, 143 .bit_depth = { 16 }, 144 .planes = 1, 145 .buffers = 1, 146 .alpha_mask = 0x8000, 147 }, 148 { 149 .fourcc = V4L2_PIX_FMT_YUV565, /* uuuvvvvv yyyyyuuu */ 150 .vdownsampling = { 1 }, 151 .bit_depth = { 16 }, 152 .planes = 1, 153 .buffers = 1, 154 }, 155 { 156 .fourcc = V4L2_PIX_FMT_YUV444, /* uuuuvvvv aaaayyyy */ 157 .vdownsampling = { 1 }, 158 .bit_depth = { 16 }, 159 .planes = 1, 160 .buffers = 1, 161 .alpha_mask = 0xf000, 162 }, 163 { 164 .fourcc = V4L2_PIX_FMT_YUV32, /* ayuv */ 165 .vdownsampling = { 1 }, 166 .bit_depth = { 32 }, 167 .planes = 1, 168 .buffers = 1, 169 .alpha_mask = 0x000000ff, 170 }, 171 { 172 .fourcc = V4L2_PIX_FMT_AYUV32, 173 .vdownsampling = { 1 }, 174 .bit_depth = { 32 }, 175 .planes = 1, 176 .buffers = 1, 177 .alpha_mask = 0x000000ff, 178 }, 179 { 180 .fourcc = V4L2_PIX_FMT_XYUV32, 181 .vdownsampling = { 1 }, 182 .bit_depth = { 32 }, 183 .planes = 1, 184 .buffers = 1, 185 }, 186 { 187 .fourcc = V4L2_PIX_FMT_VUYA32, 188 .vdownsampling = { 1 }, 189 .bit_depth = { 32 }, 190 .planes = 1, 191 .buffers = 1, 192 .alpha_mask = 0xff000000, 193 }, 194 { 195 .fourcc = V4L2_PIX_FMT_VUYX32, 196 .vdownsampling = { 1 }, 197 .bit_depth = { 32 }, 198 .planes = 1, 199 .buffers = 1, 200 }, 201 { 202 .fourcc = V4L2_PIX_FMT_YUVA32, 203 .vdownsampling = { 1 }, 204 .bit_depth = { 32 }, 205 .planes = 1, 206 .buffers = 1, 207 .alpha_mask = 0xff000000, 208 }, 209 { 210 .fourcc = V4L2_PIX_FMT_YUVX32, 211 .vdownsampling = { 1 }, 212 .bit_depth = { 32 }, 213 .planes = 1, 214 .buffers = 1, 215 }, 216 { 217 .fourcc = V4L2_PIX_FMT_GREY, 218 .vdownsampling = { 1 }, 219 .bit_depth = { 8 }, 220 .color_enc = TGP_COLOR_ENC_LUMA, 221 .planes = 1, 222 .buffers = 1, 223 }, 224 { 225 .fourcc = V4L2_PIX_FMT_Y10, 226 .vdownsampling = { 1 }, 227 .bit_depth = { 16 }, 228 .color_enc = TGP_COLOR_ENC_LUMA, 229 .planes = 1, 230 .buffers = 1, 231 }, 232 { 233 .fourcc = V4L2_PIX_FMT_Y12, 234 .vdownsampling = { 1 }, 235 .bit_depth = { 16 }, 236 .color_enc = TGP_COLOR_ENC_LUMA, 237 .planes = 1, 238 .buffers = 1, 239 }, 240 { 241 .fourcc = V4L2_PIX_FMT_Y16, 242 .vdownsampling = { 1 }, 243 .bit_depth = { 16 }, 244 .color_enc = TGP_COLOR_ENC_LUMA, 245 .planes = 1, 246 .buffers = 1, 247 }, 248 { 249 .fourcc = V4L2_PIX_FMT_Y16_BE, 250 .vdownsampling = { 1 }, 251 .bit_depth = { 16 }, 252 .color_enc = TGP_COLOR_ENC_LUMA, 253 .planes = 1, 254 .buffers = 1, 255 }, 256 { 257 .fourcc = V4L2_PIX_FMT_RGB332, /* rrrgggbb */ 258 .vdownsampling = { 1 }, 259 .bit_depth = { 8 }, 260 .planes = 1, 261 .buffers = 1, 262 }, 263 { 264 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ 265 .vdownsampling = { 1 }, 266 .bit_depth = { 16 }, 267 .planes = 1, 268 .buffers = 1, 269 .can_do_overlay = true, 270 }, 271 { 272 .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ 273 .vdownsampling = { 1 }, 274 .bit_depth = { 16 }, 275 .planes = 1, 276 .buffers = 1, 277 .can_do_overlay = true, 278 }, 279 { 280 .fourcc = V4L2_PIX_FMT_RGB444, /* ggggbbbb xxxxrrrr */ 281 .vdownsampling = { 1 }, 282 .bit_depth = { 16 }, 283 .planes = 1, 284 .buffers = 1, 285 }, 286 { 287 .fourcc = V4L2_PIX_FMT_XRGB444, /* ggggbbbb xxxxrrrr */ 288 .vdownsampling = { 1 }, 289 .bit_depth = { 16 }, 290 .planes = 1, 291 .buffers = 1, 292 }, 293 { 294 .fourcc = V4L2_PIX_FMT_ARGB444, /* ggggbbbb aaaarrrr */ 295 .vdownsampling = { 1 }, 296 .bit_depth = { 16 }, 297 .planes = 1, 298 .buffers = 1, 299 .alpha_mask = 0x00f0, 300 }, 301 { 302 .fourcc = V4L2_PIX_FMT_RGBX444, /* bbbbxxxx rrrrgggg */ 303 .vdownsampling = { 1 }, 304 .bit_depth = { 16 }, 305 .planes = 1, 306 .buffers = 1, 307 }, 308 { 309 .fourcc = V4L2_PIX_FMT_RGBA444, /* bbbbaaaa rrrrgggg */ 310 .vdownsampling = { 1 }, 311 .bit_depth = { 16 }, 312 .planes = 1, 313 .buffers = 1, 314 .alpha_mask = 0x00f0, 315 }, 316 { 317 .fourcc = V4L2_PIX_FMT_XBGR444, /* ggggrrrr xxxxbbbb */ 318 .vdownsampling = { 1 }, 319 .bit_depth = { 16 }, 320 .planes = 1, 321 .buffers = 1, 322 }, 323 { 324 .fourcc = V4L2_PIX_FMT_ABGR444, /* ggggrrrr aaaabbbb */ 325 .vdownsampling = { 1 }, 326 .bit_depth = { 16 }, 327 .planes = 1, 328 .buffers = 1, 329 .alpha_mask = 0x00f0, 330 }, 331 { 332 .fourcc = V4L2_PIX_FMT_BGRX444, /* rrrrxxxx bbbbgggg */ 333 .vdownsampling = { 1 }, 334 .bit_depth = { 16 }, 335 .planes = 1, 336 .buffers = 1, 337 }, 338 { 339 .fourcc = V4L2_PIX_FMT_BGRA444, /* rrrraaaa bbbbgggg */ 340 .vdownsampling = { 1 }, 341 .bit_depth = { 16 }, 342 .planes = 1, 343 .buffers = 1, 344 .alpha_mask = 0x00f0, 345 }, 346 { 347 .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb xrrrrrgg */ 348 .vdownsampling = { 1 }, 349 .bit_depth = { 16 }, 350 .planes = 1, 351 .buffers = 1, 352 .can_do_overlay = true, 353 }, 354 { 355 .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb xrrrrrgg */ 356 .vdownsampling = { 1 }, 357 .bit_depth = { 16 }, 358 .planes = 1, 359 .buffers = 1, 360 .can_do_overlay = true, 361 }, 362 { 363 .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ 364 .vdownsampling = { 1 }, 365 .bit_depth = { 16 }, 366 .planes = 1, 367 .buffers = 1, 368 .can_do_overlay = true, 369 .alpha_mask = 0x8000, 370 }, 371 { 372 .fourcc = V4L2_PIX_FMT_RGBX555, /* ggbbbbbx rrrrrggg */ 373 .vdownsampling = { 1 }, 374 .bit_depth = { 16 }, 375 .planes = 1, 376 .buffers = 1, 377 .can_do_overlay = true, 378 }, 379 { 380 .fourcc = V4L2_PIX_FMT_RGBA555, /* ggbbbbba rrrrrggg */ 381 .vdownsampling = { 1 }, 382 .bit_depth = { 16 }, 383 .planes = 1, 384 .buffers = 1, 385 .can_do_overlay = true, 386 .alpha_mask = 0x8000, 387 }, 388 { 389 .fourcc = V4L2_PIX_FMT_XBGR555, /* gggrrrrr xbbbbbgg */ 390 .vdownsampling = { 1 }, 391 .bit_depth = { 16 }, 392 .planes = 1, 393 .buffers = 1, 394 .can_do_overlay = true, 395 }, 396 { 397 .fourcc = V4L2_PIX_FMT_ABGR555, /* gggrrrrr abbbbbgg */ 398 .vdownsampling = { 1 }, 399 .bit_depth = { 16 }, 400 .planes = 1, 401 .buffers = 1, 402 .can_do_overlay = true, 403 .alpha_mask = 0x8000, 404 }, 405 { 406 .fourcc = V4L2_PIX_FMT_BGRX555, /* ggrrrrrx bbbbbggg */ 407 .vdownsampling = { 1 }, 408 .bit_depth = { 16 }, 409 .planes = 1, 410 .buffers = 1, 411 .can_do_overlay = true, 412 }, 413 { 414 .fourcc = V4L2_PIX_FMT_BGRA555, /* ggrrrrra bbbbbggg */ 415 .vdownsampling = { 1 }, 416 .bit_depth = { 16 }, 417 .planes = 1, 418 .buffers = 1, 419 .can_do_overlay = true, 420 .alpha_mask = 0x8000, 421 }, 422 { 423 .fourcc = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */ 424 .vdownsampling = { 1 }, 425 .bit_depth = { 16 }, 426 .planes = 1, 427 .buffers = 1, 428 }, 429 { 430 .fourcc = V4L2_PIX_FMT_XRGB555X, /* xrrrrrgg gggbbbbb */ 431 .vdownsampling = { 1 }, 432 .bit_depth = { 16 }, 433 .planes = 1, 434 .buffers = 1, 435 }, 436 { 437 .fourcc = V4L2_PIX_FMT_ARGB555X, /* arrrrrgg gggbbbbb */ 438 .vdownsampling = { 1 }, 439 .bit_depth = { 16 }, 440 .planes = 1, 441 .buffers = 1, 442 .alpha_mask = 0x0080, 443 }, 444 { 445 .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ 446 .vdownsampling = { 1 }, 447 .bit_depth = { 24 }, 448 .planes = 1, 449 .buffers = 1, 450 }, 451 { 452 .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ 453 .vdownsampling = { 1 }, 454 .bit_depth = { 24 }, 455 .planes = 1, 456 .buffers = 1, 457 }, 458 { 459 .fourcc = V4L2_PIX_FMT_BGR666, /* bbbbbbgg ggggrrrr rrxxxxxx */ 460 .vdownsampling = { 1 }, 461 .bit_depth = { 32 }, 462 .planes = 1, 463 .buffers = 1, 464 }, 465 { 466 .fourcc = V4L2_PIX_FMT_RGB32, /* xrgb */ 467 .vdownsampling = { 1 }, 468 .bit_depth = { 32 }, 469 .planes = 1, 470 .buffers = 1, 471 }, 472 { 473 .fourcc = V4L2_PIX_FMT_BGR32, /* bgrx */ 474 .vdownsampling = { 1 }, 475 .bit_depth = { 32 }, 476 .planes = 1, 477 .buffers = 1, 478 }, 479 { 480 .fourcc = V4L2_PIX_FMT_XRGB32, /* xrgb */ 481 .vdownsampling = { 1 }, 482 .bit_depth = { 32 }, 483 .planes = 1, 484 .buffers = 1, 485 }, 486 { 487 .fourcc = V4L2_PIX_FMT_XBGR32, /* bgrx */ 488 .vdownsampling = { 1 }, 489 .bit_depth = { 32 }, 490 .planes = 1, 491 .buffers = 1, 492 }, 493 { 494 .fourcc = V4L2_PIX_FMT_ARGB32, /* argb */ 495 .vdownsampling = { 1 }, 496 .bit_depth = { 32 }, 497 .planes = 1, 498 .buffers = 1, 499 .alpha_mask = 0x000000ff, 500 }, 501 { 502 .fourcc = V4L2_PIX_FMT_ABGR32, /* bgra */ 503 .vdownsampling = { 1 }, 504 .bit_depth = { 32 }, 505 .planes = 1, 506 .buffers = 1, 507 .alpha_mask = 0xff000000, 508 }, 509 { 510 .fourcc = V4L2_PIX_FMT_RGBX32, /* rgbx */ 511 .vdownsampling = { 1 }, 512 .bit_depth = { 32 }, 513 .planes = 1, 514 .buffers = 1, 515 }, 516 { 517 .fourcc = V4L2_PIX_FMT_BGRX32, /* xbgr */ 518 .vdownsampling = { 1 }, 519 .bit_depth = { 32 }, 520 .planes = 1, 521 .buffers = 1, 522 }, 523 { 524 .fourcc = V4L2_PIX_FMT_RGBA32, /* rgba */ 525 .vdownsampling = { 1 }, 526 .bit_depth = { 32 }, 527 .planes = 1, 528 .buffers = 1, 529 .alpha_mask = 0x000000ff, 530 }, 531 { 532 .fourcc = V4L2_PIX_FMT_BGRA32, /* abgr */ 533 .vdownsampling = { 1 }, 534 .bit_depth = { 32 }, 535 .planes = 1, 536 .buffers = 1, 537 .alpha_mask = 0xff000000, 538 }, 539 { 540 .fourcc = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */ 541 .vdownsampling = { 1 }, 542 .bit_depth = { 8 }, 543 .planes = 1, 544 .buffers = 1, 545 }, 546 { 547 .fourcc = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */ 548 .vdownsampling = { 1 }, 549 .bit_depth = { 8 }, 550 .planes = 1, 551 .buffers = 1, 552 }, 553 { 554 .fourcc = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */ 555 .vdownsampling = { 1 }, 556 .bit_depth = { 8 }, 557 .planes = 1, 558 .buffers = 1, 559 }, 560 { 561 .fourcc = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */ 562 .vdownsampling = { 1 }, 563 .bit_depth = { 8 }, 564 .planes = 1, 565 .buffers = 1, 566 }, 567 { 568 .fourcc = V4L2_PIX_FMT_SBGGR10, /* Bayer BG/GR */ 569 .vdownsampling = { 1 }, 570 .bit_depth = { 16 }, 571 .planes = 1, 572 .buffers = 1, 573 }, 574 { 575 .fourcc = V4L2_PIX_FMT_SGBRG10, /* Bayer GB/RG */ 576 .vdownsampling = { 1 }, 577 .bit_depth = { 16 }, 578 .planes = 1, 579 .buffers = 1, 580 }, 581 { 582 .fourcc = V4L2_PIX_FMT_SGRBG10, /* Bayer GR/BG */ 583 .vdownsampling = { 1 }, 584 .bit_depth = { 16 }, 585 .planes = 1, 586 .buffers = 1, 587 }, 588 { 589 .fourcc = V4L2_PIX_FMT_SRGGB10, /* Bayer RG/GB */ 590 .vdownsampling = { 1 }, 591 .bit_depth = { 16 }, 592 .planes = 1, 593 .buffers = 1, 594 }, 595 { 596 .fourcc = V4L2_PIX_FMT_SBGGR12, /* Bayer BG/GR */ 597 .vdownsampling = { 1 }, 598 .bit_depth = { 16 }, 599 .planes = 1, 600 .buffers = 1, 601 }, 602 { 603 .fourcc = V4L2_PIX_FMT_SGBRG12, /* Bayer GB/RG */ 604 .vdownsampling = { 1 }, 605 .bit_depth = { 16 }, 606 .planes = 1, 607 .buffers = 1, 608 }, 609 { 610 .fourcc = V4L2_PIX_FMT_SGRBG12, /* Bayer GR/BG */ 611 .vdownsampling = { 1 }, 612 .bit_depth = { 16 }, 613 .planes = 1, 614 .buffers = 1, 615 }, 616 { 617 .fourcc = V4L2_PIX_FMT_SRGGB12, /* Bayer RG/GB */ 618 .vdownsampling = { 1 }, 619 .bit_depth = { 16 }, 620 .planes = 1, 621 .buffers = 1, 622 }, 623 { 624 .fourcc = V4L2_PIX_FMT_SBGGR16, /* Bayer BG/GR */ 625 .vdownsampling = { 1 }, 626 .bit_depth = { 16 }, 627 .planes = 1, 628 .buffers = 1, 629 }, 630 { 631 .fourcc = V4L2_PIX_FMT_SGBRG16, /* Bayer GB/RG */ 632 .vdownsampling = { 1 }, 633 .bit_depth = { 16 }, 634 .planes = 1, 635 .buffers = 1, 636 }, 637 { 638 .fourcc = V4L2_PIX_FMT_SGRBG16, /* Bayer GR/BG */ 639 .vdownsampling = { 1 }, 640 .bit_depth = { 16 }, 641 .planes = 1, 642 .buffers = 1, 643 }, 644 { 645 .fourcc = V4L2_PIX_FMT_SRGGB16, /* Bayer RG/GB */ 646 .vdownsampling = { 1 }, 647 .bit_depth = { 16 }, 648 .planes = 1, 649 .buffers = 1, 650 }, 651 { 652 .fourcc = V4L2_PIX_FMT_HSV24, /* HSV 24bits */ 653 .color_enc = TGP_COLOR_ENC_HSV, 654 .vdownsampling = { 1 }, 655 .bit_depth = { 24 }, 656 .planes = 1, 657 .buffers = 1, 658 }, 659 { 660 .fourcc = V4L2_PIX_FMT_HSV32, /* HSV 32bits */ 661 .color_enc = TGP_COLOR_ENC_HSV, 662 .vdownsampling = { 1 }, 663 .bit_depth = { 32 }, 664 .planes = 1, 665 .buffers = 1, 666 }, 667 668 /* Multiplanar formats */ 669 670 { 671 .fourcc = V4L2_PIX_FMT_NV16M, 672 .vdownsampling = { 1, 1 }, 673 .bit_depth = { 8, 8 }, 674 .color_enc = TGP_COLOR_ENC_YCBCR, 675 .planes = 2, 676 .buffers = 2, 677 .data_offset = { PLANE0_DATA_OFFSET, 0 }, 678 }, 679 { 680 .fourcc = V4L2_PIX_FMT_NV61M, 681 .vdownsampling = { 1, 1 }, 682 .bit_depth = { 8, 8 }, 683 .color_enc = TGP_COLOR_ENC_YCBCR, 684 .planes = 2, 685 .buffers = 2, 686 .data_offset = { 0, PLANE0_DATA_OFFSET }, 687 }, 688 { 689 .fourcc = V4L2_PIX_FMT_YUV420M, 690 .vdownsampling = { 1, 2, 2 }, 691 .bit_depth = { 8, 4, 4 }, 692 .color_enc = TGP_COLOR_ENC_YCBCR, 693 .planes = 3, 694 .buffers = 3, 695 }, 696 { 697 .fourcc = V4L2_PIX_FMT_YVU420M, 698 .vdownsampling = { 1, 2, 2 }, 699 .bit_depth = { 8, 4, 4 }, 700 .color_enc = TGP_COLOR_ENC_YCBCR, 701 .planes = 3, 702 .buffers = 3, 703 }, 704 { 705 .fourcc = V4L2_PIX_FMT_NV12M, 706 .vdownsampling = { 1, 2 }, 707 .bit_depth = { 8, 8 }, 708 .color_enc = TGP_COLOR_ENC_YCBCR, 709 .planes = 2, 710 .buffers = 2, 711 }, 712 { 713 .fourcc = V4L2_PIX_FMT_NV21M, 714 .vdownsampling = { 1, 2 }, 715 .bit_depth = { 8, 8 }, 716 .color_enc = TGP_COLOR_ENC_YCBCR, 717 .planes = 2, 718 .buffers = 2, 719 }, 720 { 721 .fourcc = V4L2_PIX_FMT_YUV422M, 722 .vdownsampling = { 1, 1, 1 }, 723 .bit_depth = { 8, 4, 4 }, 724 .color_enc = TGP_COLOR_ENC_YCBCR, 725 .planes = 3, 726 .buffers = 3, 727 }, 728 { 729 .fourcc = V4L2_PIX_FMT_YVU422M, 730 .vdownsampling = { 1, 1, 1 }, 731 .bit_depth = { 8, 4, 4 }, 732 .color_enc = TGP_COLOR_ENC_YCBCR, 733 .planes = 3, 734 .buffers = 3, 735 }, 736 { 737 .fourcc = V4L2_PIX_FMT_YUV444M, 738 .vdownsampling = { 1, 1, 1 }, 739 .bit_depth = { 8, 8, 8 }, 740 .color_enc = TGP_COLOR_ENC_YCBCR, 741 .planes = 3, 742 .buffers = 3, 743 }, 744 { 745 .fourcc = V4L2_PIX_FMT_YVU444M, 746 .vdownsampling = { 1, 1, 1 }, 747 .bit_depth = { 8, 8, 8 }, 748 .color_enc = TGP_COLOR_ENC_YCBCR, 749 .planes = 3, 750 .buffers = 3, 751 }, 752 }; 753 754 /* There are this many multiplanar formats in the list */ 755 #define VIVID_MPLANAR_FORMATS 10 756 757 const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat) 758 { 759 const struct vivid_fmt *fmt; 760 unsigned k; 761 762 for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) { 763 fmt = &vivid_formats[k]; 764 if (fmt->fourcc == pixelformat) 765 if (fmt->buffers == 1 || dev->multiplanar) 766 return fmt; 767 } 768 769 return NULL; 770 } 771 772 bool vivid_vid_can_loop(struct vivid_dev *dev) 773 { 774 if (dev->src_rect.width != dev->sink_rect.width || 775 dev->src_rect.height != dev->sink_rect.height) 776 return false; 777 if (dev->fmt_cap->fourcc != dev->fmt_out->fourcc) 778 return false; 779 if (dev->field_cap != dev->field_out) 780 return false; 781 /* 782 * While this can be supported, it is just too much work 783 * to actually implement. 784 */ 785 if (dev->field_cap == V4L2_FIELD_SEQ_TB || 786 dev->field_cap == V4L2_FIELD_SEQ_BT) 787 return false; 788 if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) { 789 if (!(dev->std_cap[dev->input] & V4L2_STD_525_60) != 790 !(dev->std_out & V4L2_STD_525_60)) 791 return false; 792 return true; 793 } 794 if (vivid_is_hdmi_cap(dev) && vivid_is_hdmi_out(dev)) 795 return true; 796 return false; 797 } 798 799 void vivid_send_source_change(struct vivid_dev *dev, unsigned type) 800 { 801 struct v4l2_event ev = { 802 .type = V4L2_EVENT_SOURCE_CHANGE, 803 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, 804 }; 805 unsigned i; 806 807 for (i = 0; i < dev->num_inputs; i++) { 808 ev.id = i; 809 if (dev->input_type[i] == type) { 810 if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap) 811 v4l2_event_queue(&dev->vid_cap_dev, &ev); 812 if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap) 813 v4l2_event_queue(&dev->vbi_cap_dev, &ev); 814 } 815 } 816 } 817 818 /* 819 * Conversion function that converts a single-planar format to a 820 * single-plane multiplanar format. 821 */ 822 void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt) 823 { 824 struct v4l2_pix_format_mplane *mp = &mp_fmt->fmt.pix_mp; 825 struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0]; 826 const struct v4l2_pix_format *pix = &sp_fmt->fmt.pix; 827 bool is_out = sp_fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT; 828 829 memset(mp->reserved, 0, sizeof(mp->reserved)); 830 mp_fmt->type = is_out ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : 831 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 832 mp->width = pix->width; 833 mp->height = pix->height; 834 mp->pixelformat = pix->pixelformat; 835 mp->field = pix->field; 836 mp->colorspace = pix->colorspace; 837 mp->xfer_func = pix->xfer_func; 838 /* Also copies hsv_enc */ 839 mp->ycbcr_enc = pix->ycbcr_enc; 840 mp->quantization = pix->quantization; 841 mp->num_planes = 1; 842 mp->flags = pix->flags; 843 ppix->sizeimage = pix->sizeimage; 844 ppix->bytesperline = pix->bytesperline; 845 memset(ppix->reserved, 0, sizeof(ppix->reserved)); 846 } 847 848 int fmt_sp2mp_func(struct file *file, void *priv, 849 struct v4l2_format *f, fmtfunc func) 850 { 851 struct v4l2_format fmt; 852 struct v4l2_pix_format_mplane *mp = &fmt.fmt.pix_mp; 853 struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0]; 854 struct v4l2_pix_format *pix = &f->fmt.pix; 855 int ret; 856 857 /* Converts to a mplane format */ 858 fmt_sp2mp(f, &fmt); 859 /* Passes it to the generic mplane format function */ 860 ret = func(file, priv, &fmt); 861 /* Copies back the mplane data to the single plane format */ 862 pix->width = mp->width; 863 pix->height = mp->height; 864 pix->pixelformat = mp->pixelformat; 865 pix->field = mp->field; 866 pix->colorspace = mp->colorspace; 867 pix->xfer_func = mp->xfer_func; 868 /* Also copies hsv_enc */ 869 pix->ycbcr_enc = mp->ycbcr_enc; 870 pix->quantization = mp->quantization; 871 pix->sizeimage = ppix->sizeimage; 872 pix->bytesperline = ppix->bytesperline; 873 pix->flags = mp->flags; 874 return ret; 875 } 876 877 int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r) 878 { 879 unsigned w = r->width; 880 unsigned h = r->height; 881 882 /* sanitize w and h in case someone passes ~0 as the value */ 883 w &= 0xffff; 884 h &= 0xffff; 885 if (!(flags & V4L2_SEL_FLAG_LE)) { 886 w++; 887 h++; 888 if (w < 2) 889 w = 2; 890 if (h < 2) 891 h = 2; 892 } 893 if (!(flags & V4L2_SEL_FLAG_GE)) { 894 if (w > MAX_WIDTH) 895 w = MAX_WIDTH; 896 if (h > MAX_HEIGHT) 897 h = MAX_HEIGHT; 898 } 899 w = w & ~1; 900 h = h & ~1; 901 if (w < 2 || h < 2) 902 return -ERANGE; 903 if (w > MAX_WIDTH || h > MAX_HEIGHT) 904 return -ERANGE; 905 if (r->top < 0) 906 r->top = 0; 907 if (r->left < 0) 908 r->left = 0; 909 /* sanitize left and top in case someone passes ~0 as the value */ 910 r->left &= 0xfffe; 911 r->top &= 0xfffe; 912 if (r->left + w > MAX_WIDTH) 913 r->left = MAX_WIDTH - w; 914 if (r->top + h > MAX_HEIGHT) 915 r->top = MAX_HEIGHT - h; 916 if ((flags & (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE)) == 917 (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE) && 918 (r->width != w || r->height != h)) 919 return -ERANGE; 920 r->width = w; 921 r->height = h; 922 return 0; 923 } 924 925 int vivid_enum_fmt_vid(struct file *file, void *priv, 926 struct v4l2_fmtdesc *f) 927 { 928 struct vivid_dev *dev = video_drvdata(file); 929 const struct vivid_fmt *fmt; 930 931 if (f->index >= ARRAY_SIZE(vivid_formats) - 932 (dev->multiplanar ? 0 : VIVID_MPLANAR_FORMATS)) 933 return -EINVAL; 934 935 fmt = &vivid_formats[f->index]; 936 937 f->pixelformat = fmt->fourcc; 938 939 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 940 f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 941 return 0; 942 /* 943 * For capture devices, we support the CSC API. 944 * We allow userspace to: 945 * 1. set the colorspace 946 * 2. set the xfer_func 947 * 3. set the ycbcr_enc on YUV formats 948 * 4. set the hsv_enc on HSV formats 949 * 5. set the quantization on YUV and RGB formats 950 */ 951 f->flags |= V4L2_FMT_FLAG_CSC_COLORSPACE; 952 f->flags |= V4L2_FMT_FLAG_CSC_XFER_FUNC; 953 954 if (fmt->color_enc == TGP_COLOR_ENC_YCBCR) { 955 f->flags |= V4L2_FMT_FLAG_CSC_YCBCR_ENC; 956 f->flags |= V4L2_FMT_FLAG_CSC_QUANTIZATION; 957 } else if (fmt->color_enc == TGP_COLOR_ENC_HSV) { 958 f->flags |= V4L2_FMT_FLAG_CSC_HSV_ENC; 959 } else if (fmt->color_enc == TGP_COLOR_ENC_RGB) { 960 f->flags |= V4L2_FMT_FLAG_CSC_QUANTIZATION; 961 } 962 963 return 0; 964 } 965 966 int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) 967 { 968 struct vivid_dev *dev = video_drvdata(file); 969 struct video_device *vdev = video_devdata(file); 970 971 if (vdev->vfl_dir == VFL_DIR_RX) { 972 if (!vivid_is_sdtv_cap(dev)) 973 return -ENODATA; 974 *id = dev->std_cap[dev->input]; 975 } else { 976 if (!vivid_is_svid_out(dev)) 977 return -ENODATA; 978 *id = dev->std_out; 979 } 980 return 0; 981 } 982 983 int vidioc_g_dv_timings(struct file *file, void *_fh, 984 struct v4l2_dv_timings *timings) 985 { 986 struct vivid_dev *dev = video_drvdata(file); 987 struct video_device *vdev = video_devdata(file); 988 989 if (vdev->vfl_dir == VFL_DIR_RX) { 990 if (!vivid_is_hdmi_cap(dev)) 991 return -ENODATA; 992 *timings = dev->dv_timings_cap[dev->input]; 993 } else { 994 if (!vivid_is_hdmi_out(dev)) 995 return -ENODATA; 996 *timings = dev->dv_timings_out; 997 } 998 return 0; 999 } 1000 1001 int vidioc_enum_dv_timings(struct file *file, void *_fh, 1002 struct v4l2_enum_dv_timings *timings) 1003 { 1004 struct vivid_dev *dev = video_drvdata(file); 1005 struct video_device *vdev = video_devdata(file); 1006 1007 if (vdev->vfl_dir == VFL_DIR_RX) { 1008 if (!vivid_is_hdmi_cap(dev)) 1009 return -ENODATA; 1010 } else { 1011 if (!vivid_is_hdmi_out(dev)) 1012 return -ENODATA; 1013 } 1014 return v4l2_enum_dv_timings_cap(timings, &vivid_dv_timings_cap, 1015 NULL, NULL); 1016 } 1017 1018 int vidioc_dv_timings_cap(struct file *file, void *_fh, 1019 struct v4l2_dv_timings_cap *cap) 1020 { 1021 struct vivid_dev *dev = video_drvdata(file); 1022 struct video_device *vdev = video_devdata(file); 1023 1024 if (vdev->vfl_dir == VFL_DIR_RX) { 1025 if (!vivid_is_hdmi_cap(dev)) 1026 return -ENODATA; 1027 } else { 1028 if (!vivid_is_hdmi_out(dev)) 1029 return -ENODATA; 1030 } 1031 *cap = vivid_dv_timings_cap; 1032 return 0; 1033 } 1034 1035 int vidioc_g_edid(struct file *file, void *_fh, 1036 struct v4l2_edid *edid) 1037 { 1038 struct vivid_dev *dev = video_drvdata(file); 1039 struct video_device *vdev = video_devdata(file); 1040 struct cec_adapter *adap; 1041 1042 memset(edid->reserved, 0, sizeof(edid->reserved)); 1043 if (vdev->vfl_dir == VFL_DIR_RX) { 1044 if (edid->pad >= dev->num_inputs) 1045 return -EINVAL; 1046 if (dev->input_type[edid->pad] != HDMI) 1047 return -EINVAL; 1048 adap = dev->cec_rx_adap; 1049 } else { 1050 unsigned int bus_idx; 1051 1052 if (edid->pad >= dev->num_outputs) 1053 return -EINVAL; 1054 if (dev->output_type[edid->pad] != HDMI) 1055 return -EINVAL; 1056 if (!dev->display_present[edid->pad]) 1057 return -ENODATA; 1058 bus_idx = dev->cec_output2bus_map[edid->pad]; 1059 adap = dev->cec_tx_adap[bus_idx]; 1060 } 1061 if (edid->start_block == 0 && edid->blocks == 0) { 1062 edid->blocks = dev->edid_blocks; 1063 return 0; 1064 } 1065 if (dev->edid_blocks == 0) 1066 return -ENODATA; 1067 if (edid->start_block >= dev->edid_blocks) 1068 return -EINVAL; 1069 if (edid->blocks > dev->edid_blocks - edid->start_block) 1070 edid->blocks = dev->edid_blocks - edid->start_block; 1071 if (adap) 1072 v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); 1073 memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128); 1074 return 0; 1075 } 1076