| /* SPDX-License-Identifier: GPL-2.0+ */ |
| /* |
| * Copyright (C) 2016 NextThing Co |
| * Copyright (C) 2016-2019 Bootlin |
| * |
| * Author: Maxime Ripard <maxime.ripard@bootlin.com> |
| */ |
| |
| #ifndef _SUN4I_CSI_H_ |
| #define _SUN4I_CSI_H_ |
| |
| #include <media/media-device.h> |
| #include <media/v4l2-async.h> |
| #include <media/v4l2-dev.h> |
| #include <media/v4l2-device.h> |
| #include <media/v4l2-fwnode.h> |
| #include <media/videobuf2-core.h> |
| |
| #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; |
| |
| 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_fwnode_bus_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_ */ |