root/drivers/media/platform/sunxi/sun8i-rotate/sun8i_formats.c
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2020 Jernej Skrabec <jernej.skrabec@siol.net> */

#include "sun8i-formats.h"
#include "sun8i-rotate.h"

/*
 * Formats not included in array:
 * ROTATE_FORMAT_BGR565
 * ROTATE_FORMAT_VYUV
 */

static const struct rotate_format rotate_formats[] = {
        {
                .fourcc = V4L2_PIX_FMT_ARGB32,
                .hw_format = ROTATE_FORMAT_ARGB32,
                .planes = 1,
                .bpp = { 4, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_ABGR32,
                .hw_format = ROTATE_FORMAT_ABGR32,
                .planes = 1,
                .bpp = { 4, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_RGBA32,
                .hw_format = ROTATE_FORMAT_RGBA32,
                .planes = 1,
                .bpp = { 4, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_BGRA32,
                .hw_format = ROTATE_FORMAT_BGRA32,
                .planes = 1,
                .bpp = { 4, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_XRGB32,
                .hw_format = ROTATE_FORMAT_XRGB32,
                .planes = 1,
                .bpp = { 4, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_XBGR32,
                .hw_format = ROTATE_FORMAT_XBGR32,
                .planes = 1,
                .bpp = { 4, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_RGB32,
                .hw_format = ROTATE_FORMAT_RGBX32,
                .planes = 1,
                .bpp = { 4, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_BGR32,
                .hw_format = ROTATE_FORMAT_BGRX32,
                .planes = 1,
                .bpp = { 4, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_RGB24,
                .hw_format = ROTATE_FORMAT_RGB24,
                .planes = 1,
                .bpp = { 3, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_BGR24,
                .hw_format = ROTATE_FORMAT_BGR24,
                .planes = 1,
                .bpp = { 3, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_RGB565,
                .hw_format = ROTATE_FORMAT_RGB565,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_ARGB444,
                .hw_format = ROTATE_FORMAT_ARGB4444,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_ABGR444,
                .hw_format = ROTATE_FORMAT_ABGR4444,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_RGBA444,
                .hw_format = ROTATE_FORMAT_RGBA4444,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_BGRA444,
                .hw_format = ROTATE_FORMAT_BGRA4444,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_ARGB555,
                .hw_format = ROTATE_FORMAT_ARGB1555,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_ABGR555,
                .hw_format = ROTATE_FORMAT_ABGR1555,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_RGBA555,
                .hw_format = ROTATE_FORMAT_RGBA5551,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_BGRA555,
                .hw_format = ROTATE_FORMAT_BGRA5551,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 1,
                .vsub = 1,
                .flags = ROTATE_FLAG_OUTPUT
        }, {
                .fourcc = V4L2_PIX_FMT_YVYU,
                .hw_format = ROTATE_FORMAT_YVYU,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 2,
                .vsub = 1,
                .flags = ROTATE_FLAG_YUV
        }, {
                .fourcc = V4L2_PIX_FMT_UYVY,
                .hw_format = ROTATE_FORMAT_UYVY,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 2,
                .vsub = 1,
                .flags = ROTATE_FLAG_YUV
        }, {
                .fourcc = V4L2_PIX_FMT_YUYV,
                .hw_format = ROTATE_FORMAT_YUYV,
                .planes = 1,
                .bpp = { 2, 0, 0 },
                .hsub = 2,
                .vsub = 1,
                .flags = ROTATE_FLAG_YUV
        }, {
                .fourcc = V4L2_PIX_FMT_NV61,
                .hw_format = ROTATE_FORMAT_NV61,
                .planes = 2,
                .bpp = { 1, 2, 0 },
                .hsub = 2,
                .vsub = 1,
                .flags = ROTATE_FLAG_YUV
        }, {
                .fourcc = V4L2_PIX_FMT_NV16,
                .hw_format = ROTATE_FORMAT_NV16,
                .planes = 2,
                .bpp = { 1, 2, 0 },
                .hsub = 2,
                .vsub = 1,
                .flags = ROTATE_FLAG_YUV
        }, {
                .fourcc = V4L2_PIX_FMT_YUV422P,
                .hw_format = ROTATE_FORMAT_YUV422P,
                .planes = 3,
                .bpp = { 1, 1, 1 },
                .hsub = 2,
                .vsub = 1,
                .flags = ROTATE_FLAG_YUV
        }, {
                .fourcc = V4L2_PIX_FMT_NV21,
                .hw_format = ROTATE_FORMAT_NV21,
                .planes = 2,
                .bpp = { 1, 2, 0 },
                .hsub = 2,
                .vsub = 2,
                .flags = ROTATE_FLAG_YUV
        }, {
                .fourcc = V4L2_PIX_FMT_NV12,
                .hw_format = ROTATE_FORMAT_NV12,
                .planes = 2,
                .bpp = { 1, 2, 0 },
                .hsub = 2,
                .vsub = 2,
                .flags = ROTATE_FLAG_YUV
        }, {
                .fourcc = V4L2_PIX_FMT_YUV420,
                .hw_format = ROTATE_FORMAT_YUV420P,
                .planes = 3,
                .bpp = { 1, 1, 1 },
                .hsub = 2,
                .vsub = 2,
                .flags = ROTATE_FLAG_YUV | ROTATE_FLAG_OUTPUT
        },
};

const struct rotate_format *rotate_find_format(u32 pixelformat)
{
        unsigned int i;

        for (i = 0; i < ARRAY_SIZE(rotate_formats); i++)
                if (rotate_formats[i].fourcc == pixelformat)
                        return &rotate_formats[i];

        return NULL;
}

int rotate_enum_fmt(struct v4l2_fmtdesc *f, bool dst)
{
        int i, index;

        index = 0;

        for (i = 0; i < ARRAY_SIZE(rotate_formats); i++) {
                /* not all formats can be used for capture buffers */
                if (dst && !(rotate_formats[i].flags & ROTATE_FLAG_OUTPUT))
                        continue;

                if (index == f->index) {
                        f->pixelformat = rotate_formats[i].fourcc;

                        return 0;
                }

                index++;
        }

        return -EINVAL;
}