hc
2023-12-06 d38611ca164021d018c1b23eee65bbebc09c63e0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* 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_ */