Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64...
[cascardo/linux.git] / drivers / media / platform / vivid / vivid-vid-common.c
index 6bef1e6..aa44627 100644 (file)
@@ -33,8 +33,9 @@ const struct v4l2_dv_timings_cap vivid_dv_timings_cap = {
        .type = V4L2_DV_BT_656_1120,
        /* keep this initialization for compatibility with GCC < 4.4.6 */
        .reserved = { 0 },
-       V4L2_INIT_BT_TIMINGS(0, MAX_WIDTH, 0, MAX_HEIGHT, 25000000, 600000000,
-               V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT,
+       V4L2_INIT_BT_TIMINGS(0, MAX_WIDTH, 0, MAX_HEIGHT, 14000000, 775000000,
+               V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
+               V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF,
                V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED)
 };
 
@@ -46,145 +47,435 @@ struct vivid_fmt vivid_formats[] = {
        {
                .name     = "4:2:2, packed, YUYV",
                .fourcc   = V4L2_PIX_FMT_YUYV,
-               .depth    = 16,
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
                .is_yuv   = true,
                .planes   = 1,
-               .data_offset = { PLANE0_DATA_OFFSET, 0 },
+               .buffers = 1,
+               .data_offset = { PLANE0_DATA_OFFSET },
        },
        {
                .name     = "4:2:2, packed, UYVY",
                .fourcc   = V4L2_PIX_FMT_UYVY,
-               .depth    = 16,
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
                .is_yuv   = true,
                .planes   = 1,
+               .buffers = 1,
        },
        {
                .name     = "4:2:2, packed, YVYU",
                .fourcc   = V4L2_PIX_FMT_YVYU,
-               .depth    = 16,
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
                .is_yuv   = true,
                .planes   = 1,
+               .buffers = 1,
        },
        {
                .name     = "4:2:2, packed, VYUY",
                .fourcc   = V4L2_PIX_FMT_VYUY,
-               .depth    = 16,
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .is_yuv   = true,
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "YUV 4:2:2 triplanar",
+               .fourcc   = V4L2_PIX_FMT_YUV422P,
+               .vdownsampling = { 1, 1, 1 },
+               .bit_depth = { 8, 4, 4 },
+               .is_yuv   = true,
+               .planes   = 3,
+               .buffers = 1,
+       },
+       {
+               .name     = "YUV 4:2:0 triplanar",
+               .fourcc   = V4L2_PIX_FMT_YUV420,
+               .vdownsampling = { 1, 2, 2 },
+               .bit_depth = { 8, 4, 4 },
+               .is_yuv   = true,
+               .planes   = 3,
+               .buffers = 1,
+       },
+       {
+               .name     = "YVU 4:2:0 triplanar",
+               .fourcc   = V4L2_PIX_FMT_YVU420,
+               .vdownsampling = { 1, 2, 2 },
+               .bit_depth = { 8, 4, 4 },
+               .is_yuv   = true,
+               .planes   = 3,
+               .buffers = 1,
+       },
+       {
+               .name     = "YUV 4:2:0 biplanar",
+               .fourcc   = V4L2_PIX_FMT_NV12,
+               .vdownsampling = { 1, 2 },
+               .bit_depth = { 8, 8 },
+               .is_yuv   = true,
+               .planes   = 2,
+               .buffers = 1,
+       },
+       {
+               .name     = "YVU 4:2:0 biplanar",
+               .fourcc   = V4L2_PIX_FMT_NV21,
+               .vdownsampling = { 1, 2 },
+               .bit_depth = { 8, 8 },
+               .is_yuv   = true,
+               .planes   = 2,
+               .buffers = 1,
+       },
+       {
+               .name     = "YUV 4:2:2 biplanar",
+               .fourcc   = V4L2_PIX_FMT_NV16,
+               .vdownsampling = { 1, 1 },
+               .bit_depth = { 8, 8 },
+               .is_yuv   = true,
+               .planes   = 2,
+               .buffers = 1,
+       },
+       {
+               .name     = "YVU 4:2:2 biplanar",
+               .fourcc   = V4L2_PIX_FMT_NV61,
+               .vdownsampling = { 1, 1 },
+               .bit_depth = { 8, 8 },
+               .is_yuv   = true,
+               .planes   = 2,
+               .buffers = 1,
+       },
+       {
+               .name     = "YUV 4:4:4 biplanar",
+               .fourcc   = V4L2_PIX_FMT_NV24,
+               .vdownsampling = { 1, 1 },
+               .bit_depth = { 8, 16 },
+               .is_yuv   = true,
+               .planes   = 2,
+               .buffers = 1,
+       },
+       {
+               .name     = "YVU 4:4:4 biplanar",
+               .fourcc   = V4L2_PIX_FMT_NV42,
+               .vdownsampling = { 1, 1 },
+               .bit_depth = { 8, 16 },
+               .is_yuv   = true,
+               .planes   = 2,
+               .buffers = 1,
+       },
+       {
+               .name     = "YUV555 (LE)",
+               .fourcc   = V4L2_PIX_FMT_YUV555, /* uuuvvvvv ayyyyyuu */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+               .alpha_mask = 0x8000,
+       },
+       {
+               .name     = "YUV565 (LE)",
+               .fourcc   = V4L2_PIX_FMT_YUV565, /* uuuvvvvv yyyyyuuu */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "YUV444",
+               .fourcc   = V4L2_PIX_FMT_YUV444, /* uuuuvvvv aaaayyyy */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+               .alpha_mask = 0xf000,
+       },
+       {
+               .name     = "YUV32 (LE)",
+               .fourcc   = V4L2_PIX_FMT_YUV32, /* ayuv */
+               .vdownsampling = { 1 },
+               .bit_depth = { 32 },
+               .planes   = 1,
+               .buffers = 1,
+               .alpha_mask = 0x000000ff,
+       },
+       {
+               .name     = "Monochrome",
+               .fourcc   = V4L2_PIX_FMT_GREY,
+               .vdownsampling = { 1 },
+               .bit_depth = { 8 },
                .is_yuv   = true,
                .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "RGB332",
+               .fourcc   = V4L2_PIX_FMT_RGB332, /* rrrgggbb */
+               .vdownsampling = { 1 },
+               .bit_depth = { 8 },
+               .planes   = 1,
+               .buffers = 1,
        },
        {
                .name     = "RGB565 (LE)",
                .fourcc   = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
-               .depth    = 16,
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
                .planes   = 1,
+               .buffers = 1,
                .can_do_overlay = true,
        },
        {
                .name     = "RGB565 (BE)",
                .fourcc   = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
-               .depth    = 16,
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
                .planes   = 1,
+               .buffers = 1,
                .can_do_overlay = true,
        },
+       {
+               .name     = "RGB444",
+               .fourcc   = V4L2_PIX_FMT_RGB444, /* xxxxrrrr ggggbbbb */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "XRGB444",
+               .fourcc   = V4L2_PIX_FMT_XRGB444, /* xxxxrrrr ggggbbbb */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "ARGB444",
+               .fourcc   = V4L2_PIX_FMT_ARGB444, /* aaaarrrr ggggbbbb */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+               .alpha_mask = 0x00f0,
+       },
        {
                .name     = "RGB555 (LE)",
-               .fourcc   = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
-               .depth    = 16,
+               .fourcc   = V4L2_PIX_FMT_RGB555, /* gggbbbbb xrrrrrgg */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
                .planes   = 1,
+               .buffers = 1,
                .can_do_overlay = true,
        },
        {
                .name     = "XRGB555 (LE)",
-               .fourcc   = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */
-               .depth    = 16,
+               .fourcc   = V4L2_PIX_FMT_XRGB555, /* gggbbbbb xrrrrrgg */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
                .planes   = 1,
+               .buffers = 1,
                .can_do_overlay = true,
        },
        {
                .name     = "ARGB555 (LE)",
                .fourcc   = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */
-               .depth    = 16,
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
                .planes   = 1,
+               .buffers = 1,
                .can_do_overlay = true,
                .alpha_mask = 0x8000,
        },
        {
                .name     = "RGB555 (BE)",
-               .fourcc   = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
-               .depth    = 16,
+               .fourcc   = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
                .planes   = 1,
-               .can_do_overlay = true,
+               .buffers = 1,
+       },
+       {
+               .name     = "XRGB555 (BE)",
+               .fourcc   = V4L2_PIX_FMT_XRGB555X, /* xrrrrrgg gggbbbbb */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "ARGB555 (BE)",
+               .fourcc   = V4L2_PIX_FMT_ARGB555X, /* arrrrrgg gggbbbbb */
+               .vdownsampling = { 1 },
+               .bit_depth = { 16 },
+               .planes   = 1,
+               .buffers = 1,
+               .alpha_mask = 0x0080,
        },
        {
                .name     = "RGB24 (LE)",
                .fourcc   = V4L2_PIX_FMT_RGB24, /* rgb */
-               .depth    = 24,
+               .vdownsampling = { 1 },
+               .bit_depth = { 24 },
                .planes   = 1,
+               .buffers = 1,
        },
        {
                .name     = "RGB24 (BE)",
                .fourcc   = V4L2_PIX_FMT_BGR24, /* bgr */
-               .depth    = 24,
+               .vdownsampling = { 1 },
+               .bit_depth = { 24 },
                .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "BGR666",
+               .fourcc   = V4L2_PIX_FMT_BGR666, /* bbbbbbgg ggggrrrr rrxxxxxx */
+               .vdownsampling = { 1 },
+               .bit_depth = { 32 },
+               .planes   = 1,
+               .buffers = 1,
        },
        {
                .name     = "RGB32 (LE)",
-               .fourcc   = V4L2_PIX_FMT_RGB32, /* argb */
-               .depth    = 32,
+               .fourcc   = V4L2_PIX_FMT_RGB32, /* xrgb */
+               .vdownsampling = { 1 },
+               .bit_depth = { 32 },
                .planes   = 1,
+               .buffers = 1,
        },
        {
                .name     = "RGB32 (BE)",
-               .fourcc   = V4L2_PIX_FMT_BGR32, /* bgra */
-               .depth    = 32,
+               .fourcc   = V4L2_PIX_FMT_BGR32, /* bgrx */
+               .vdownsampling = { 1 },
+               .bit_depth = { 32 },
                .planes   = 1,
+               .buffers = 1,
        },
        {
                .name     = "XRGB32 (LE)",
-               .fourcc   = V4L2_PIX_FMT_XRGB32, /* argb */
-               .depth    = 32,
+               .fourcc   = V4L2_PIX_FMT_XRGB32, /* xrgb */
+               .vdownsampling = { 1 },
+               .bit_depth = { 32 },
                .planes   = 1,
+               .buffers = 1,
        },
        {
                .name     = "XRGB32 (BE)",
-               .fourcc   = V4L2_PIX_FMT_XBGR32, /* bgra */
-               .depth    = 32,
+               .fourcc   = V4L2_PIX_FMT_XBGR32, /* bgrx */
+               .vdownsampling = { 1 },
+               .bit_depth = { 32 },
                .planes   = 1,
+               .buffers = 1,
        },
        {
                .name     = "ARGB32 (LE)",
                .fourcc   = V4L2_PIX_FMT_ARGB32, /* argb */
-               .depth    = 32,
+               .vdownsampling = { 1 },
+               .bit_depth = { 32 },
                .planes   = 1,
+               .buffers = 1,
                .alpha_mask = 0x000000ff,
        },
        {
                .name     = "ARGB32 (BE)",
                .fourcc   = V4L2_PIX_FMT_ABGR32, /* bgra */
-               .depth    = 32,
+               .vdownsampling = { 1 },
+               .bit_depth = { 32 },
                .planes   = 1,
+               .buffers = 1,
                .alpha_mask = 0xff000000,
        },
        {
-               .name     = "4:2:2, planar, YUV",
+               .name     = "Bayer BG/GR",
+               .fourcc   = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */
+               .vdownsampling = { 1 },
+               .bit_depth = { 8 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "Bayer GB/RG",
+               .fourcc   = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */
+               .vdownsampling = { 1 },
+               .bit_depth = { 8 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "Bayer GR/BG",
+               .fourcc   = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */
+               .vdownsampling = { 1 },
+               .bit_depth = { 8 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "Bayer RG/GB",
+               .fourcc   = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */
+               .vdownsampling = { 1 },
+               .bit_depth = { 8 },
+               .planes   = 1,
+               .buffers = 1,
+       },
+       {
+               .name     = "4:2:2, biplanar, YUV",
                .fourcc   = V4L2_PIX_FMT_NV16M,
-               .depth    = 8,
+               .vdownsampling = { 1, 1 },
+               .bit_depth = { 8, 8 },
                .is_yuv   = true,
                .planes   = 2,
+               .buffers = 2,
                .data_offset = { PLANE0_DATA_OFFSET, 0 },
        },
        {
-               .name     = "4:2:2, planar, YVU",
+               .name     = "4:2:2, biplanar, YVU",
                .fourcc   = V4L2_PIX_FMT_NV61M,
-               .depth    = 8,
+               .vdownsampling = { 1, 1 },
+               .bit_depth = { 8, 8 },
                .is_yuv   = true,
                .planes   = 2,
+               .buffers = 2,
                .data_offset = { 0, PLANE0_DATA_OFFSET },
        },
+       {
+               .name     = "4:2:0, triplanar, YUV",
+               .fourcc   = V4L2_PIX_FMT_YUV420M,
+               .vdownsampling = { 1, 2, 2 },
+               .bit_depth = { 8, 4, 4 },
+               .is_yuv   = true,
+               .planes   = 3,
+               .buffers = 3,
+       },
+       {
+               .name     = "4:2:0, triplanar, YVU",
+               .fourcc   = V4L2_PIX_FMT_YVU420M,
+               .vdownsampling = { 1, 2, 2 },
+               .bit_depth = { 8, 4, 4 },
+               .is_yuv   = true,
+               .planes   = 3,
+               .buffers = 3,
+       },
+       {
+               .name     = "4:2:0, biplanar, YUV",
+               .fourcc   = V4L2_PIX_FMT_NV12M,
+               .vdownsampling = { 1, 2 },
+               .bit_depth = { 8, 8 },
+               .is_yuv   = true,
+               .planes   = 2,
+               .buffers = 2,
+       },
+       {
+               .name     = "4:2:0, biplanar, YVU",
+               .fourcc   = V4L2_PIX_FMT_NV21M,
+               .vdownsampling = { 1, 2 },
+               .bit_depth = { 8, 8 },
+               .is_yuv   = true,
+               .planes   = 2,
+               .buffers = 2,
+       },
 };
 
-/* There are 2 multiplanar formats in the list */
-#define VIVID_MPLANAR_FORMATS 2
+/* There are 6 multiplanar formats in the list */
+#define VIVID_MPLANAR_FORMATS 6
 
 const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
 {
@@ -194,7 +485,7 @@ const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
        for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) {
                fmt = &vivid_formats[k];
                if (fmt->fourcc == pixelformat)
-                       if (fmt->planes == 1 || dev->multiplanar)
+                       if (fmt->buffers == 1 || dev->multiplanar)
                                return fmt;
        }
 
@@ -210,6 +501,13 @@ bool vivid_vid_can_loop(struct vivid_dev *dev)
                return false;
        if (dev->field_cap != dev->field_out)
                return false;
+       /*
+        * While this can be supported, it is just too much work
+        * to actually implement.
+        */
+       if (dev->field_cap == V4L2_FIELD_SEQ_TB ||
+           dev->field_cap == V4L2_FIELD_SEQ_BT)
+               return false;
        if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) {
                if (!(dev->std_cap & V4L2_STD_525_60) !=
                    !(dev->std_out & V4L2_STD_525_60))
@@ -397,6 +695,9 @@ int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
        unsigned w = r->width;
        unsigned h = r->height;
 
+       /* sanitize w and h in case someone passes ~0 as the value */
+       w &= 0xffff;
+       h &= 0xffff;
        if (!(flags & V4L2_SEL_FLAG_LE)) {
                w++;
                h++;
@@ -421,8 +722,9 @@ int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
                r->top = 0;
        if (r->left < 0)
                r->left = 0;
-       r->left &= ~1;
-       r->top &= ~1;
+       /* sanitize left and top in case someone passes ~0 as the value */
+       r->left &= 0xfffe;
+       r->top &= 0xfffe;
        if (r->left + w > MAX_WIDTH)
                r->left = MAX_WIDTH - w;
        if (r->top + h > MAX_HEIGHT)