// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2011-2018 Magewell Electronics Co., Ltd. (Nanjing)
* Author: Yong Deng <yong.deng@magewell.com>
* Copyright 2021-2022 Bootlin
* Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
*/
#include <linux/of.h>
#include <linux/regmap.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mc.h>
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-v4l2.h>
#include "sun6i_csi.h"
#include "sun6i_csi_bridge.h"
#include "sun6i_csi_capture.h"
#include "sun6i_csi_reg.h"
/* Helpers */
void sun6i_csi_capture_dimensions(struct sun6i_csi_device *csi_dev,
unsigned int *width, unsigned int *height)
{
if (width)
*width = csi_dev->capture.format.fmt.pix.width;
if (height)
*height = csi_dev->capture.format.fmt.pix.height;
}
void sun6i_csi_capture_format(struct sun6i_csi_device *csi_dev,
u32 *pixelformat, u32 *field)
{
if (pixelformat)
*pixelformat = csi_dev->capture.format.fmt.pix.pixelformat;
if (field)
*field = csi_dev->capture.format.fmt.pix.field;
}
/* Format */
static const struct sun6i_csi_capture_format sun6i_csi_capture_formats[] = {
/* Bayer */
{
.pixelformat = V4L2_PIX_FMT_SBGGR8,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8,
},
{
.pixelformat = V4L2_PIX_FMT_SGBRG8,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8,
},
{
.pixelformat = V4L2_PIX_FMT_SGRBG8,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8,
},
{
.pixelformat = V4L2_PIX_FMT_SRGGB8,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8,
},
{
.pixelformat = V4L2_PIX_FMT_SBGGR10,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_10,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_10,
},
{
.pixelformat = V4L2_PIX_FMT_SGBRG10,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_10,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_10,
},
{
.pixelformat = V4L2_PIX_FMT_SGRBG10,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_10,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_10,
},
{
.pixelformat = V4L2_PIX_FMT_SRGGB10,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_10,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_10,
},
{
.pixelformat = V4L2_PIX_FMT_SBGGR12,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_12,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_12,
},
{
.pixelformat = V4L2_PIX_FMT_SGBRG12,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_12,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_12,
},
{
.pixelformat = V4L2_PIX_FMT_SGRBG12,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_12,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_12,
},
{
.pixelformat = V4L2_PIX_FMT_SRGGB12,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_12,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_12,
},
/* RGB */
{
.pixelformat = V4L2_PIX_FMT_RGB565,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RGB565,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RGB565,
},
{
.pixelformat = V4L2_PIX_FMT_RGB565X,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RGB565,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RGB565,
},
/* YUV422 */
{
.pixelformat = V4L2_PIX_FMT_YUYV,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8,
.input_format_raw = true,
.hsize_len_factor = 2,
},
{
.pixelformat = V4L2_PIX_FMT_YVYU,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8,
.input_format_raw = true,
.hsize_len_factor = 2,
},
{
.pixelformat = V4L2_PIX_FMT_UYVY,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8,
.input_format_raw = true,
.hsize_len_factor = 2,
},
{
.pixelformat = V4L2_PIX_FMT_VYUY,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_RAW_8,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_RAW_8,
.input_format_raw = true,
.hsize_len_factor = 2,
},
{
.pixelformat = V4L2_PIX_FMT_NV16,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV422SP,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV422SP,
},
{
.pixelformat = V4L2_PIX_FMT_NV61,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV422SP,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV422SP,
.input_yuv_seq_invert = true,
},
{
.pixelformat = V4L2_PIX_FMT_YUV422P,
.output_format_frame = SUN6I_CSI_OUTPUT_FMT_FRAME_YUV422P,
.output_format_field = SUN6I_CSI_OUTPUT_FMT_FIELD_YUV422P,
},
/* YUV420 */
{
.pixelformat = V4L2_PIX_FMT_NV12_16L16,
.output_format_frame = SUN6I_CSI_O