File Index
Files and directories
Sign in
FILE

vivid-vid-common.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/test-drivers/vivid/vivid-vid-common.c C
   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
  20const 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
  34struct 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
 757const 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
 772struct vivid_dev *vivid_output_is_connected_to(struct vivid_dev *dev)
 773{
 774	struct vivid_dev *input_inst = dev->output_to_input_instance[dev->output];
 775
 776	if (!input_inst)
 777		return NULL;
 778	if (input_inst->input != dev->output_to_input_index[dev->output])
 779		return NULL;
 780	return input_inst;
 781}
 782
 783struct vivid_dev *vivid_input_is_connected_to(struct vivid_dev *dev)
 784{
 785	s32 connected_output = dev->input_is_connected_to_output[dev->input];
 786
 787	if (connected_output < FIXED_MENU_ITEMS)
 788		return NULL;
 789	struct vivid_dev *output_inst = NULL;
 790
 791	if (vivid_is_hdmi_cap(dev)) {
 792		output_inst = vivid_ctrl_hdmi_to_output_instance[connected_output];
 793		if (vivid_ctrl_hdmi_to_output_index[connected_output] != output_inst->output)
 794			return NULL;
 795		return output_inst;
 796	} else if (vivid_is_svid_cap(dev)) {
 797		output_inst = vivid_ctrl_svid_to_output_instance[connected_output];
 798		if (vivid_ctrl_svid_to_output_index[connected_output] != output_inst->output)
 799			return NULL;
 800		return output_inst;
 801	} else {
 802		return NULL;
 803	}
 804	return output_inst;
 805}
 806
 807bool vivid_vid_can_loop(struct vivid_dev *dev)
 808{
 809	struct vivid_dev *output_inst = vivid_input_is_connected_to(dev);
 810
 811	if (!output_inst)
 812		return false;
 813	if (!vb2_is_streaming(&output_inst->vb_vid_out_q))
 814		return false;
 815	if (dev->src_rect.width != output_inst->sink_rect.width ||
 816	    dev->src_rect.height != output_inst->sink_rect.height)
 817		return false;
 818	if (dev->fmt_cap->fourcc != output_inst->fmt_out->fourcc)
 819		return false;
 820	if (dev->field_cap != output_inst->field_out)
 821		return false;
 822	/*
 823	 * While this can be supported, it is just too much work
 824	 * to actually implement.
 825	 */
 826	if (dev->field_cap == V4L2_FIELD_SEQ_TB ||
 827	    dev->field_cap == V4L2_FIELD_SEQ_BT)
 828		return false;
 829	if (vivid_is_hdmi_cap(dev))
 830		return true;
 831	if (!(dev->std_cap[dev->input] & V4L2_STD_525_60) !=
 832	    !(output_inst->std_out & V4L2_STD_525_60))
 833		return false;
 834	return true;
 835}
 836
 837void vivid_send_input_source_change(struct vivid_dev *dev, unsigned int input_index)
 838{
 839	struct v4l2_event ev = {
 840		.type = V4L2_EVENT_SOURCE_CHANGE,
 841		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
 842	};
 843	ev.id = input_index;
 844
 845	if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap)
 846		v4l2_event_queue(&dev->vid_cap_dev, &ev);
 847	if (dev->input_type[input_index] == TV || dev->input_type[input_index] == SVID)
 848		if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap)
 849			v4l2_event_queue(&dev->vbi_cap_dev, &ev);
 850}
 851
 852void vivid_send_source_change(struct vivid_dev *dev, unsigned int type)
 853{
 854	for (int i = 0; i < dev->num_inputs; i++)
 855		if (dev->input_type[i] == type)
 856			vivid_send_input_source_change(dev, i);
 857}
 858
 859/*
 860 * Conversion function that converts a single-planar format to a
 861 * single-plane multiplanar format.
 862 */
 863void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt)
 864{
 865	struct v4l2_pix_format_mplane *mp = &mp_fmt->fmt.pix_mp;
 866	struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
 867	const struct v4l2_pix_format *pix = &sp_fmt->fmt.pix;
 868	bool is_out = sp_fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
 869
 870	memset(mp->reserved, 0, sizeof(mp->reserved));
 871	mp_fmt->type = is_out ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
 872			   V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
 873	mp->width = pix->width;
 874	mp->height = pix->height;
 875	mp->pixelformat = pix->pixelformat;
 876	mp->field = pix->field;
 877	mp->colorspace = pix->colorspace;
 878	mp->xfer_func = pix->xfer_func;
 879	/* Also copies hsv_enc */
 880	mp->ycbcr_enc = pix->ycbcr_enc;
 881	mp->quantization = pix->quantization;
 882	mp->num_planes = 1;
 883	mp->flags = pix->flags;
 884	ppix->sizeimage = pix->sizeimage;
 885	ppix->bytesperline = pix->bytesperline;
 886	memset(ppix->reserved, 0, sizeof(ppix->reserved));
 887}
 888
 889int fmt_sp2mp_func(struct file *file, void *priv,
 890		struct v4l2_format *f, fmtfunc func)
 891{
 892	struct v4l2_format fmt;
 893	struct v4l2_pix_format_mplane *mp = &fmt.fmt.pix_mp;
 894	struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
 895	struct v4l2_pix_format *pix = &f->fmt.pix;
 896	int ret;
 897
 898	/* Converts to a mplane format */
 899	fmt_sp2mp(f, &fmt);
 900	/* Passes it to the generic mplane format function */
 901	ret = func(file, priv, &fmt);
 902	/* Copies back the mplane data to the single plane format */
 903	pix->width = mp->width;
 904	pix->height = mp->height;
 905	pix->pixelformat = mp->pixelformat;
 906	pix->field = mp->field;
 907	pix->colorspace = mp->colorspace;
 908	pix->xfer_func = mp->xfer_func;
 909	/* Also copies hsv_enc */
 910	pix->ycbcr_enc = mp->ycbcr_enc;
 911	pix->quantization = mp->quantization;
 912	pix->sizeimage = ppix->sizeimage;
 913	pix->bytesperline = ppix->bytesperline;
 914	pix->flags = mp->flags;
 915	return ret;
 916}
 917
 918int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
 919{
 920	unsigned w = r->width;
 921	unsigned h = r->height;
 922
 923	/* sanitize w and h in case someone passes ~0 as the value */
 924	w &= 0xffff;
 925	h &= 0xffff;
 926	if (!(flags & V4L2_SEL_FLAG_LE)) {
 927		w++;
 928		h++;
 929		if (w < 2)
 930			w = 2;
 931		if (h < 2)
 932			h = 2;
 933	}
 934	if (!(flags & V4L2_SEL_FLAG_GE)) {
 935		if (w > MAX_WIDTH)
 936			w = MAX_WIDTH;
 937		if (h > MAX_HEIGHT)
 938			h = MAX_HEIGHT;
 939	}
 940	w = w & ~1;
 941	h = h & ~1;
 942	if (w < 2 || h < 2)
 943		return -ERANGE;
 944	if (w > MAX_WIDTH || h > MAX_HEIGHT)
 945		return -ERANGE;
 946	if (r->top < 0)
 947		r->top = 0;
 948	if (r->left < 0)
 949		r->left = 0;
 950	/* sanitize left and top in case someone passes ~0 as the value */
 951	r->left &= 0xfffe;
 952	r->top &= 0xfffe;
 953	if (r->left + w > MAX_WIDTH)
 954		r->left = MAX_WIDTH - w;
 955	if (r->top + h > MAX_HEIGHT)
 956		r->top = MAX_HEIGHT - h;
 957	if ((flags & (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE)) ==
 958			(V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE) &&
 959	    (r->width != w || r->height != h))
 960		return -ERANGE;
 961	r->width = w;
 962	r->height = h;
 963	return 0;
 964}
 965
 966int vivid_enum_fmt_vid(struct file *file, void  *priv,
 967					struct v4l2_fmtdesc *f)
 968{
 969	struct vivid_dev *dev = video_drvdata(file);
 970	const struct vivid_fmt *fmt;
 971
 972	if (f->index >= ARRAY_SIZE(vivid_formats) -
 973	    (dev->multiplanar ? 0 : VIVID_MPLANAR_FORMATS))
 974		return -EINVAL;
 975
 976	fmt = &vivid_formats[f->index];
 977
 978	f->pixelformat = fmt->fourcc;
 979
 980	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
 981	    f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
 982		return 0;
 983	/*
 984	 * For capture devices, we support the CSC API.
 985	 * We allow userspace to:
 986	 * 1. set the colorspace
 987	 * 2. set the xfer_func
 988	 * 3. set the ycbcr_enc on YUV formats
 989	 * 4. set the hsv_enc on HSV formats
 990	 * 5. set the quantization on YUV and RGB formats
 991	 */
 992	f->flags |= V4L2_FMT_FLAG_CSC_COLORSPACE;
 993	f->flags |= V4L2_FMT_FLAG_CSC_XFER_FUNC;
 994
 995	if (fmt->color_enc == TGP_COLOR_ENC_YCBCR) {
 996		f->flags |= V4L2_FMT_FLAG_CSC_YCBCR_ENC;
 997		f->flags |= V4L2_FMT_FLAG_CSC_QUANTIZATION;
 998	} else if (fmt->color_enc == TGP_COLOR_ENC_HSV) {
 999		f->flags |= V4L2_FMT_FLAG_CSC_HSV_ENC;
1000	} else if (fmt->color_enc == TGP_COLOR_ENC_RGB) {
1001		f->flags |= V4L2_FMT_FLAG_CSC_QUANTIZATION;
1002	}
1003
1004	return 0;
1005}
1006
1007int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
1008{
1009	struct vivid_dev *dev = video_drvdata(file);
1010	struct video_device *vdev = video_devdata(file);
1011
1012	if (vdev->vfl_dir == VFL_DIR_RX) {
1013		if (!vivid_is_sdtv_cap(dev))
1014			return -ENODATA;
1015		*id = dev->std_cap[dev->input];
1016	} else {
1017		if (!vivid_is_svid_out(dev))
1018			return -ENODATA;
1019		*id = dev->std_out;
1020	}
1021	return 0;
1022}
1023
1024int vidioc_g_dv_timings(struct file *file, void *priv,
1025				    struct v4l2_dv_timings *timings)
1026{
1027	struct vivid_dev *dev = video_drvdata(file);
1028	struct video_device *vdev = video_devdata(file);
1029
1030	if (vdev->vfl_dir == VFL_DIR_RX) {
1031		if (!vivid_is_hdmi_cap(dev))
1032			return -ENODATA;
1033		*timings = dev->dv_timings_cap[dev->input];
1034	} else {
1035		if (!vivid_is_hdmi_out(dev))
1036			return -ENODATA;
1037		*timings = dev->dv_timings_out;
1038	}
1039	return 0;
1040}
1041
1042int vidioc_enum_dv_timings(struct file *file, void *priv,
1043				    struct v4l2_enum_dv_timings *timings)
1044{
1045	struct vivid_dev *dev = video_drvdata(file);
1046	struct video_device *vdev = video_devdata(file);
1047
1048	if (vdev->vfl_dir == VFL_DIR_RX) {
1049		if (!vivid_is_hdmi_cap(dev))
1050			return -ENODATA;
1051	} else {
1052		if (!vivid_is_hdmi_out(dev))
1053			return -ENODATA;
1054	}
1055	return v4l2_enum_dv_timings_cap(timings, &vivid_dv_timings_cap,
1056			NULL, NULL);
1057}
1058
1059int vidioc_dv_timings_cap(struct file *file, void *priv,
1060				    struct v4l2_dv_timings_cap *cap)
1061{
1062	struct vivid_dev *dev = video_drvdata(file);
1063	struct video_device *vdev = video_devdata(file);
1064
1065	if (vdev->vfl_dir == VFL_DIR_RX) {
1066		if (!vivid_is_hdmi_cap(dev))
1067			return -ENODATA;
1068	} else {
1069		if (!vivid_is_hdmi_out(dev))
1070			return -ENODATA;
1071	}
1072	*cap = vivid_dv_timings_cap;
1073	return 0;
1074}
1075
1076int vidioc_g_edid(struct file *file, void *priv,
1077			 struct v4l2_edid *edid)
1078{
1079	struct vivid_dev *dev = video_drvdata(file);
1080	struct vivid_dev *dev_rx = dev;
1081	struct video_device *vdev = video_devdata(file);
1082	struct cec_adapter *adap;
1083	unsigned int loc;
1084
1085	memset(edid->reserved, 0, sizeof(edid->reserved));
1086	if (vdev->vfl_dir == VFL_DIR_RX) {
1087		if (edid->pad >= dev->num_inputs)
1088			return -EINVAL;
1089		if (dev->input_type[edid->pad] != HDMI)
1090			return -EINVAL;
1091		adap = dev->cec_rx_adap;
1092	} else {
1093		if (edid->pad >= dev->num_outputs)
1094			return -EINVAL;
1095		if (dev->output_type[edid->pad] != HDMI)
1096			return -EINVAL;
1097		dev_rx = dev->output_to_input_instance[edid->pad];
1098		if (!dev_rx)
1099			return -ENODATA;
1100
1101		unsigned int hdmi_output = dev->output_to_iface_index[edid->pad];
1102
1103		adap = dev->cec_tx_adap[hdmi_output];
1104	}
1105	if (edid->start_block == 0 && edid->blocks == 0) {
1106		edid->blocks = dev_rx->edid_blocks;
1107		return 0;
1108	}
1109	if (dev_rx->edid_blocks == 0)
1110		return -ENODATA;
1111	if (edid->start_block >= dev_rx->edid_blocks)
1112		return -EINVAL;
1113	if (edid->blocks > dev_rx->edid_blocks - edid->start_block)
1114		edid->blocks = dev_rx->edid_blocks - edid->start_block;
1115
1116	memcpy(edid->edid, dev_rx->edid + edid->start_block * 128, edid->blocks * 128);
1117
1118	loc = cec_get_edid_spa_location(dev_rx->edid,
1119					dev_rx->edid_blocks * 128);
1120	if (vdev->vfl_dir == VFL_DIR_TX && adap && loc &&
1121	    loc >= edid->start_block * 128 &&
1122	    loc < (edid->start_block + edid->blocks) * 128) {
1123		unsigned int i;
1124		u8 sum = 0;
1125
1126		loc -= edid->start_block * 128;
1127		edid->edid[loc] = adap->phys_addr >> 8;
1128		edid->edid[loc + 1] = adap->phys_addr & 0xff;
1129		loc &= ~0x7f;
1130
1131		/* update the checksum */
1132		for (i = loc; i < loc + 127; i++)
1133			sum += edid->edid[i];
1134		edid->edid[i] = 256 - sum;
1135	}
1136	return 0;
1137}
~/ Read-only file preview.