1
2
3
4
5
6
7
8
9#ifndef CAMIF_CORE_H_
10#define CAMIF_CORE_H_
11
12#include <linux/io.h>
13#include <linux/irq.h>
14#include <linux/platform_device.h>
15#include <linux/sched.h>
16#include <linux/spinlock.h>
17#include <linux/types.h>
18#include <linux/videodev2.h>
19
20#include <media/media-entity.h>
21#include <media/v4l2-ctrls.h>
22#include <media/v4l2-dev.h>
23#include <media/v4l2-device.h>
24#include <media/v4l2-mediabus.h>
25#include <media/videobuf2-v4l2.h>
26#include <media/drv-intf/s3c_camif.h>
27
28#define S3C_CAMIF_DRIVER_NAME "s3c-camif"
29#define CAMIF_REQ_BUFS_MIN 3
30#define CAMIF_MAX_OUT_BUFS 4
31#define CAMIF_MAX_PIX_WIDTH 4096
32#define CAMIF_MAX_PIX_HEIGHT 4096
33#define SCALER_MAX_RATIO 64
34#define CAMIF_DEF_WIDTH 640
35#define CAMIF_DEF_HEIGHT 480
36#define CAMIF_STOP_TIMEOUT 1500
37
38#define S3C244X_CAMIF_IP_REV 0x20
39#define S3C2450_CAMIF_IP_REV 0x30
40#define S3C6400_CAMIF_IP_REV 0x31
41#define S3C6410_CAMIF_IP_REV 0x32
42
43
44
45#define ST_VP_PENDING (1 << 0)
46#define ST_VP_RUNNING (1 << 1)
47#define ST_VP_STREAMING (1 << 2)
48#define ST_VP_SENSOR_STREAMING (1 << 3)
49
50#define ST_VP_ABORTING (1 << 4)
51#define ST_VP_OFF (1 << 5)
52#define ST_VP_LASTIRQ (1 << 6)
53
54#define ST_VP_CONFIG (1 << 8)
55
56#define CAMIF_SD_PAD_SINK 0
57#define CAMIF_SD_PAD_SOURCE_C 1
58#define CAMIF_SD_PAD_SOURCE_P 2
59#define CAMIF_SD_PADS_NUM 3
60
61enum img_fmt {
62 IMG_FMT_RGB565 = 0x0010,
63 IMG_FMT_RGB666,
64 IMG_FMT_XRGB8888,
65 IMG_FMT_YCBCR420 = 0x0020,
66 IMG_FMT_YCRCB420,
67 IMG_FMT_YCBCR422P,
68 IMG_FMT_YCBYCR422 = 0x0040,
69 IMG_FMT_YCRYCB422,
70 IMG_FMT_CBYCRY422,
71 IMG_FMT_CRYCBY422,
72};
73
74#define img_fmt_is_rgb(x) ((x) & 0x10)
75#define img_fmt_is_ycbcr(x) ((x) & 0x60)
76
77
78#define FMT_FL_S3C24XX_CODEC (1 << 0)
79#define FMT_FL_S3C24XX_PREVIEW (1 << 1)
80#define FMT_FL_S3C64XX (1 << 2)
81
82
83
84
85
86
87
88
89
90
91struct camif_fmt {
92 u32 fourcc;
93 u32 color;
94 u16 colplanes;
95 u16 flags;
96 u8 depth;
97 u8 ybpp;
98};
99
100
101
102
103
104
105struct camif_dma_offset {
106 int initial;
107 int line;
108};
109
110
111
112
113
114
115
116
117struct camif_frame {
118 u16 f_width;
119 u16 f_height;
120 struct v4l2_rect rect;
121 struct camif_dma_offset dma_offset;
122};
123
124
125enum {
126 CLK_GATE,
127 CLK_CAM,
128 CLK_MAX_NUM,
129};
130
131struct vp_pix_limits {
132 u16 max_out_width;
133 u16 max_sc_out_width;
134 u16 out_width_align;
135 u16 max_height;
136 u8 min_out_width;
137 u16 out_hor_offset_align;
138};
139
140struct camif_pix_limits {
141 u16 win_hor_offset_align;
142};
143
144
145
146
147
148
149
150
151
152struct s3c_camif_variant {
153 struct vp_pix_limits vp_pix_limits[2];
154 struct camif_pix_limits pix_limits;
155 u8 ip_revision;
156 u8 has_img_effect;
157 unsigned int vp_offset;
158};
159
160struct s3c_camif_drvdata {
161 const struct s3c_camif_variant *variant;
162 unsigned long bus_clk_freq;
163};
164
165struct camif_scaler {
166 u8 scaleup_h;
167 u8 scaleup_v;
168 u8 copy;
169 u8 enable;
170 u32 h_shift;
171 u32 v_shift;
172 u32 pre_h_ratio;
173 u32 pre_v_ratio;
174 u32 pre_dst_width;
175 u32 pre_dst_height;
176 u32 main_h_ratio;
177 u32 main_v_ratio;
178};
179
180struct camif_dev;
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210struct camif_vp {
211 wait_queue_head_t irq_queue;
212 int irq;
213 struct camif_dev *camif;
214 struct media_pad pad;
215 struct video_device vdev;
216 struct v4l2_ctrl_handler ctrl_handler;
217 struct v4l2_fh *owner;
218 struct vb2_queue vb_queue;
219 struct list_head pending_buf_q;
220 struct list_head active_buf_q;
221 unsigned int active_buffers;
222 unsigned int buf_index;
223 unsigned int frame_sequence;
224 unsigned int reqbufs_count;
225 struct camif_scaler scaler;
226 const struct camif_fmt *out_fmt;
227 unsigned int payload;
228 struct camif_frame out_frame;
229 unsigned int state;
230 u16 fmt_flags;
231 u8 id;
232 u16 rotation;
233 u8 hflip;
234 u8 vflip;
235 unsigned int offset;
236};
237
238
239#define VP_CODEC 0
240#define VP_PREVIEW 1
241#define CAMIF_VP_NUM 2
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271struct camif_dev {
272 struct media_device media_dev;
273 struct v4l2_device v4l2_dev;
274 struct v4l2_subdev subdev;
275 struct v4l2_mbus_framefmt mbus_fmt;
276 struct v4l2_rect camif_crop;
277 struct media_pad pads[CAMIF_SD_PADS_NUM];
278 int stream_count;
279
280 struct cam_sensor {
281 struct v4l2_subdev *sd;
282 short power_count;
283 short stream_count;
284 } sensor;
285 struct media_pipeline *m_pipeline;
286
287 struct v4l2_ctrl_handler ctrl_handler;
288 struct v4l2_ctrl *ctrl_test_pattern;
289 struct {
290 struct v4l2_ctrl *ctrl_colorfx;
291 struct v4l2_ctrl *ctrl_colorfx_cbcr;
292 };
293 u8 test_pattern;
294 u8 colorfx;
295 u8 colorfx_cb;
296 u8 colorfx_cr;
297
298 struct camif_vp vp[CAMIF_VP_NUM];
299
300 const struct s3c_camif_variant *variant;
301 struct device *dev;
302 struct s3c_camif_plat_data pdata;
303 struct clk *clock[CLK_MAX_NUM];
304 struct mutex lock;
305 spinlock_t slock;
306 void __iomem *io_base;
307};
308
309
310
311
312
313
314
315struct camif_addr {
316 dma_addr_t y;
317 dma_addr_t cb;
318 dma_addr_t cr;
319};
320
321
322
323
324
325
326
327
328struct camif_buffer {
329 struct vb2_v4l2_buffer vb;
330 struct list_head list;
331 struct camif_addr paddr;
332 unsigned int index;
333};
334
335const struct camif_fmt *s3c_camif_find_format(struct camif_vp *vp,
336 const u32 *pixelformat, int index);
337int s3c_camif_register_video_node(struct camif_dev *camif, int idx);
338void s3c_camif_unregister_video_node(struct camif_dev *camif, int idx);
339irqreturn_t s3c_camif_irq_handler(int irq, void *priv);
340int s3c_camif_create_subdev(struct camif_dev *camif);
341void s3c_camif_unregister_subdev(struct camif_dev *camif);
342int s3c_camif_set_defaults(struct camif_dev *camif);
343int s3c_camif_get_scaler_config(struct camif_vp *vp,
344 struct camif_scaler *scaler);
345
346static inline void camif_active_queue_add(struct camif_vp *vp,
347 struct camif_buffer *buf)
348{
349 list_add_tail(&buf->list, &vp->active_buf_q);
350 vp->active_buffers++;
351}
352
353static inline struct camif_buffer *camif_active_queue_pop(
354 struct camif_vp *vp)
355{
356 struct camif_buffer *buf = list_first_entry(&vp->active_buf_q,
357 struct camif_buffer, list);
358 list_del(&buf->list);
359 vp->active_buffers--;
360 return buf;
361}
362
363static inline struct camif_buffer *camif_active_queue_peek(
364 struct camif_vp *vp, int index)
365{
366 struct camif_buffer *tmp, *buf;
367
368 if (WARN_ON(list_empty(&vp->active_buf_q)))
369 return NULL;
370
371 list_for_each_entry_safe(buf, tmp, &vp->active_buf_q, list) {
372 if (buf->index == index) {
373 list_del(&buf->list);
374 vp->active_buffers--;
375 return buf;
376 }
377 }
378
379 return NULL;
380}
381
382static inline void camif_pending_queue_add(struct camif_vp *vp,
383 struct camif_buffer *buf)
384{
385 list_add_tail(&buf->list, &vp->pending_buf_q);
386}
387
388static inline struct camif_buffer *camif_pending_queue_pop(
389 struct camif_vp *vp)
390{
391 struct camif_buffer *buf = list_first_entry(&vp->pending_buf_q,
392 struct camif_buffer, list);
393 list_del(&buf->list);
394 return buf;
395}
396
397#endif
398