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