/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2016 NextThing Co * Copyright (C) 2016-2019 Bootlin * * Author: Maxime Ripard */ #ifndef _SUN4I_CSI_H_ #define _SUN4I_CSI_H_ #include #include #include #include #include #include #define CSI_EN_REG 0x00 #define CSI_CFG_REG 0x04 #define CSI_CFG_INPUT_FMT(fmt) ((fmt) << 20) #define CSI_CFG_OUTPUT_FMT(fmt) ((fmt) << 16) #define CSI_CFG_YUV_DATA_SEQ(seq) ((seq) << 8) #define CSI_CFG_VREF_POL(pol) ((pol) << 2) #define CSI_CFG_HREF_POL(pol) ((pol) << 1) #define CSI_CFG_PCLK_POL(pol) ((pol) << 0) #define CSI_CPT_CTRL_REG 0x08 #define CSI_CPT_CTRL_VIDEO_START BIT(1) #define CSI_CPT_CTRL_IMAGE_START BIT(0) #define CSI_BUF_ADDR_REG(fifo, buf) (0x10 + (0x8 * (fifo)) + (0x4 * (buf))) #define CSI_BUF_CTRL_REG 0x28 #define CSI_BUF_CTRL_DBN BIT(2) #define CSI_BUF_CTRL_DBS BIT(1) #define CSI_BUF_CTRL_DBE BIT(0) #define CSI_INT_EN_REG 0x30 #define CSI_INT_FRM_DONE BIT(1) #define CSI_INT_CPT_DONE BIT(0) #define CSI_INT_STA_REG 0x34 #define CSI_WIN_CTRL_W_REG 0x40 #define CSI_WIN_CTRL_W_ACTIVE(w) ((w) << 16) #define CSI_WIN_CTRL_H_REG 0x44 #define CSI_WIN_CTRL_H_ACTIVE(h) ((h) << 16) #define CSI_BUF_LEN_REG 0x48 #define CSI_MAX_BUFFER 2 #define CSI_MAX_HEIGHT 8192U #define CSI_MAX_WIDTH 8192U enum csi_input { CSI_INPUT_RAW = 0, CSI_INPUT_BT656 = 2, CSI_INPUT_YUV = 3, }; enum csi_output_raw { CSI_OUTPUT_RAW_PASSTHROUGH = 0, }; enum csi_output_yuv { CSI_OUTPUT_YUV_422_PLANAR = 0, CSI_OUTPUT_YUV_420_PLANAR = 1, CSI_OUTPUT_YUV_422_UV = 4, CSI_OUTPUT_YUV_420_UV = 5, CSI_OUTPUT_YUV_422_MACRO = 8, CSI_OUTPUT_YUV_420_MACRO = 9, }; enum csi_yuv_data_seq { CSI_YUV_DATA_SEQ_YUYV = 0, CSI_YUV_DATA_SEQ_YVYU = 1, CSI_YUV_DATA_SEQ_UYVY = 2, CSI_YUV_DATA_SEQ_VYUY = 3, }; enum csi_subdev_pads { CSI_SUBDEV_SINK, CSI_SUBDEV_SOURCE, CSI_SUBDEV_PADS, }; extern const struct v4l2_subdev_ops sun4i_csi_subdev_ops; extern const struct v4l2_subdev_internal_ops sun4i_csi_subdev_internal_ops; struct sun4i_csi_format { u32 mbus; u32 fourcc; enum csi_input input; u32 output; unsigned int num_planes; u8 bpp[3]; unsigned int hsub; unsigned int vsub; }; const struct sun4i_csi_format *sun4i_csi_find_format(const u32 *fourcc, const u32 *mbus); struct sun4i_csi { /* Device resources */ struct device *dev; const struct sun4i_csi_traits *traits; void __iomem *regs; struct clk *bus_clk; struct clk *isp_clk; struct clk *ram_clk; struct reset_control *rst; struct vb2_v4l2_buffer *current_buf[CSI_MAX_BUFFER]; struct { size_t size; void *vaddr; dma_addr_t paddr; } scratch; struct v4l2_mbus_config_parallel bus; /* Main Device */ struct v4l2_device v4l; struct media_device mdev; struct video_device vdev; struct media_pad vdev_pad; struct v4l2_pix_format_mplane fmt; /* Local subdev */ struct v4l2_subdev subdev; struct media_pad subdev_pads[CSI_SUBDEV_PADS]; struct v4l2_mbus_framefmt subdev_fmt; /* V4L2 Async variables */ struct v4l2_async_notifier notifier; struct v4l2_subdev *src_subdev; int src_pad; /* V4L2 variables */ struct mutex lock; /* Videobuf2 */ struct vb2_queue queue; struct list_head buf_list; spinlock_t qlock; unsigned int sequence; }; int sun4i_csi_dma_register(struct sun4i_csi *csi, int irq); void sun4i_csi_dma_unregister(struct sun4i_csi *csi); int sun4i_csi_v4l2_register(struct sun4i_csi *csi); #endif /* _SUN4I_CSI_H_ */