1 From 573919b9c0d6752c42b2b130fde41d6b80a843b7 Mon Sep 17 00:00:00 2001
2 From: SW.LEE <hitchcar@samsung.com>
3 Date: Fri, 25 Jul 2008 23:06:10 +0100
4 Subject: [PATCH] introduce-samsung-camera-unit-driver.patch
6 This is the kernel side of an old (2004) samsung camera driver for 2440
7 It doesn't compile on modern kernel yet, this patch introduces it into the
8 kernel tree without gross mods, so it is broken code we can start to work on
10 arch/arm/mach-s3c2440/Kconfig | 4 +-
11 arch/arm/mach-s3c2440/Makefile | 8 +-
12 arch/arm/mach-s3c2440/camera/Kconfig | 7 +
13 arch/arm/mach-s3c2440/camera/Makefile | 9 +
14 arch/arm/mach-s3c2440/camera/bits.h | 48 ++
15 arch/arm/mach-s3c2440/camera/cam_reg.h | 220 ++++++
16 arch/arm/mach-s3c2440/camera/camif.c | 978 +++++++++++++++++++++++++++
17 arch/arm/mach-s3c2440/camera/camif.h | 304 +++++++++
18 arch/arm/mach-s3c2440/camera/camif_fsm.c | 427 ++++++++++++
19 arch/arm/mach-s3c2440/camera/imgsensor.c | 255 +++++++
20 arch/arm/mach-s3c2440/camera/miscdevice.h | 18 +
21 arch/arm/mach-s3c2440/camera/qt-driver.c | 169 +++++
22 arch/arm/mach-s3c2440/camera/qt.h | 18 +
23 arch/arm/mach-s3c2440/camera/s5x532.h | 143 ++++
24 arch/arm/mach-s3c2440/camera/s5x532_rev36.h | 208 ++++++
25 arch/arm/mach-s3c2440/camera/sensor.h | 20 +
26 arch/arm/mach-s3c2440/camera/sxga.h | 504 ++++++++++++++
27 arch/arm/mach-s3c2440/camera/userapp.h | 44 ++
28 arch/arm/mach-s3c2440/camera/v4l2_api.c | 311 +++++++++
29 arch/arm/mach-s3c2440/camera/video-driver.c | 591 ++++++++++++++++
30 arch/arm/mach-s3c2440/camera/videodev.c | 342 ++++++++++
31 arch/arm/mach-s3c2440/camera/videodev.h | 110 +++
32 arch/arm/mach-s3c2440/camera/videodev2.h | 938 +++++++++++++++++++++++++
33 23 files changed, 5668 insertions(+), 8 deletions(-)
34 create mode 100644 arch/arm/mach-s3c2440/camera/Kconfig
35 create mode 100644 arch/arm/mach-s3c2440/camera/Makefile
36 create mode 100644 arch/arm/mach-s3c2440/camera/bits.h
37 create mode 100644 arch/arm/mach-s3c2440/camera/cam_reg.h
38 create mode 100644 arch/arm/mach-s3c2440/camera/camif.c
39 create mode 100644 arch/arm/mach-s3c2440/camera/camif.h
40 create mode 100644 arch/arm/mach-s3c2440/camera/camif_fsm.c
41 create mode 100644 arch/arm/mach-s3c2440/camera/imgsensor.c
42 create mode 100644 arch/arm/mach-s3c2440/camera/miscdevice.h
43 create mode 100644 arch/arm/mach-s3c2440/camera/qt-driver.c
44 create mode 100644 arch/arm/mach-s3c2440/camera/qt.h
45 create mode 100644 arch/arm/mach-s3c2440/camera/s5x532.h
46 create mode 100644 arch/arm/mach-s3c2440/camera/s5x532_rev36.h
47 create mode 100644 arch/arm/mach-s3c2440/camera/sensor.h
48 create mode 100644 arch/arm/mach-s3c2440/camera/sxga.h
49 create mode 100644 arch/arm/mach-s3c2440/camera/userapp.h
50 create mode 100644 arch/arm/mach-s3c2440/camera/v4l2_api.c
51 create mode 100644 arch/arm/mach-s3c2440/camera/video-driver.c
52 create mode 100644 arch/arm/mach-s3c2440/camera/videodev.c
53 create mode 100644 arch/arm/mach-s3c2440/camera/videodev.h
54 create mode 100644 arch/arm/mach-s3c2440/camera/videodev2.h
56 diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
57 index 3e9e9f1..e042965 100644
58 --- a/arch/arm/mach-s3c2440/Kconfig
59 +++ b/arch/arm/mach-s3c2440/Kconfig
60 @@ -30,6 +30,9 @@ config S3C2440_C_FIQ
61 Support for S3C2440 FIQ support in C -- see
62 ./arch/arm/macs3c2440/fiq_c_isr.c
64 +source "arch/arm/mach-s3c2440/camera/Kconfig"
67 menu "S3C2440 Machines"
70 @@ -93,4 +96,3 @@ config NEO1973_GTA02_2440
71 of the FIC/Openmoko Neo1973 GTA02 GSM Phone.
75 diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
76 index 4932232..e9c6334 100644
77 --- a/arch/arm/mach-s3c2440/Makefile
78 +++ b/arch/arm/mach-s3c2440/Makefile
80 -# arch/arm/mach-s3c2440/Makefile
82 -# Copyright 2007 Simtec Electronics
84 -# Licensed under GPLv2
91 diff --git a/arch/arm/mach-s3c2440/camera/Kconfig b/arch/arm/mach-s3c2440/camera/Kconfig
93 index 0000000..36f127d
95 +++ b/arch/arm/mach-s3c2440/camera/Kconfig
98 +config S3C2440_CAMERA
99 + bool "S3C24xx Camera interface"
100 + depends on ARCH_S3C2410
102 + Camera driver for S3C2440 camera unit
104 diff --git a/arch/arm/mach-s3c2440/camera/Makefile b/arch/arm/mach-s3c2440/camera/Makefile
106 index 0000000..a46d3be
108 +++ b/arch/arm/mach-s3c2440/camera/Makefile
110 +obj-$(CONFIG_S3C2440_CAMERA) += \
119 diff --git a/arch/arm/mach-s3c2440/camera/bits.h b/arch/arm/mach-s3c2440/camera/bits.h
121 index 0000000..8d83c2e
123 +++ b/arch/arm/mach-s3c2440/camera/bits.h
126 + * Copyright (C) Samsung Electroincs 2003
127 + * Author: SW.LEE <hitchcar@samsung.com>
129 + * This program is free software; you can redistribute it and/or modify
130 + * it under the terms of the GNU General Public License as published by
131 + * the Free Software Foundation; either version 2 of the License, or
132 + * (at your option) any later version.
139 +#define BIT0 0x00000001
140 +#define BIT1 0x00000002
141 +#define BIT2 0x00000004
142 +#define BIT3 0x00000008
143 +#define BIT4 0x00000010
144 +#define BIT5 0x00000020
145 +#define BIT6 0x00000040
146 +#define BIT7 0x00000080
147 +#define BIT8 0x00000100
148 +#define BIT9 0x00000200
149 +#define BIT10 0x00000400
150 +#define BIT11 0x00000800
151 +#define BIT12 0x00001000
152 +#define BIT13 0x00002000
153 +#define BIT14 0x00004000
154 +#define BIT15 0x00008000
155 +#define BIT16 0x00010000
156 +#define BIT17 0x00020000
157 +#define BIT18 0x00040000
158 +#define BIT19 0x00080000
159 +#define BIT20 0x00100000
160 +#define BIT21 0x00200000
161 +#define BIT22 0x00400000
162 +#define BIT23 0x00800000
163 +#define BIT24 0x01000000
164 +#define BIT25 0x02000000
165 +#define BIT26 0x04000000
166 +#define BIT27 0x08000000
167 +#define BIT28 0x10000000
168 +#define BIT29 0x20000000
169 +#define BIT30 0x40000000
170 +#define BIT31 0x80000000
173 diff --git a/arch/arm/mach-s3c2440/camera/cam_reg.h b/arch/arm/mach-s3c2440/camera/cam_reg.h
175 index 0000000..7247a4e
177 +++ b/arch/arm/mach-s3c2440/camera/cam_reg.h
179 + /*----------------------------------------------------------
180 + * (C) 2004 Samsung Electronics
181 + * SW.LEE < hitchcar@samsung.com>
183 + ----------------------------------------------------------- */
185 +#ifndef __FIMC20_CAMERA_H__
186 +#define __FIMC20_CAMERA_H__
189 +#ifdef CONFIG_ARCH_S3C24A0
190 +#define CAM_BASE_ADD 0x48000000
191 +#else /* S3C2440A */
192 +#define CAM_BASE_ADD 0x4F000000
198 + * P-port is used as RGB Capturing device which including scale and crop
199 + * those who want to see(preview ) the image on display needs RGB image.
201 + * C-port is used as YCbCr(4:2:0, 4:2:2) Capturing device which including the scale and crop
202 + * the prefix of C-port have the meaning of "Codec" ex. mpeg4, h263.. which requries the
203 + YCBCB format not RGB
206 +#define CISRCFMT __REG(CAM_BASE_ADD+0x00) // RW Input Source Format
207 +#define CIWDOFST __REG(CAM_BASE_ADD+0x04) // Window offset register
208 +#define CIGCTRL __REG(CAM_BASE_ADD+0x08) // Global control register
209 +#define CICOYSA0 __REG(CAM_BASE_ADD+0x18) // Y 1 st frame start address
210 +#define CICOYSA1 __REG(CAM_BASE_ADD+0x1C) // Y 2 nd frame start address
211 +#define CICOYSA2 __REG(CAM_BASE_ADD+0x20) // Y 3 rd frame start address
212 +#define CICOYSA3 __REG(CAM_BASE_ADD+0x24) // Y 4 th frame start address
213 +#define CICOCBSA0 __REG(CAM_BASE_ADD+0x28) // Cb 1 st frame start address
214 +#define CICOCBSA1 __REG(CAM_BASE_ADD+0x2C) // Cb 2 nd frame start address
215 +#define CICOCBSA2 __REG(CAM_BASE_ADD+0x30) // Cb 3 rd frame start address
216 +#define CICOCBSA3 __REG(CAM_BASE_ADD+0x34) // Cb 4 th frame start address
217 +#define CICOCRSA0 __REG(CAM_BASE_ADD+0x38) // Cr 1 st frame start address
218 +#define CICOCRSA1 __REG(CAM_BASE_ADD+0x3C) // Cr 2 nd frame start address
219 +#define CICOCRSA2 __REG(CAM_BASE_ADD+0x40) // Cr 3 rd frame start address
220 +#define CICOCRSA3 __REG(CAM_BASE_ADD+0x44) // Cr 4 th frame start address
221 +#define CICOTRGFMT __REG(CAM_BASE_ADD+0x48) // Target image format of codec
222 +#define CICOCTRL __REG(CAM_BASE_ADD+0x4C) // Codec DMA control related
223 +#define CICOSCPRERATIO __REG(CAM_BASE_ADD+0x50) // Codec pre-scaler ratio control
224 +#define CICOSCPREDST __REG(CAM_BASE_ADD+0x54) // Codec pre-scaler destination
225 +#define CICOSCCTRL __REG(CAM_BASE_ADD+0x58) // Codec main-scaler control
226 +#define CICOTAREA __REG(CAM_BASE_ADD+0x5C) // Codec pre-scaler destination
227 +#define CICOSTATUS __REG(CAM_BASE_ADD+0x64) // Codec path status
228 +#define CIPRCLRSA0 __REG(CAM_BASE_ADD+0x6C) // RGB 1 st frame start address
229 +#define CIPRCLRSA1 __REG(CAM_BASE_ADD+0x70) // RGB 2 nd frame start address
230 +#define CIPRCLRSA2 __REG(CAM_BASE_ADD+0x74) // RGB 3 rd frame start address
231 +#define CIPRCLRSA3 __REG(CAM_BASE_ADD+0x78) // RGB 4 th frame start address
232 +#define CIPRTRGFMT __REG(CAM_BASE_ADD+0x7C) // Target image format of preview
233 +#define CIPRCTRL __REG(CAM_BASE_ADD+0x80) // Preview DMA control related
234 +#define CIPRSCPRERATIO __REG(CAM_BASE_ADD+0x84) // Preview pre-scaler ratio control
235 +#define CIPRSCPREDST __REG(CAM_BASE_ADD+0x88) // Preview pre-scaler destination
236 +#define CIPRSCCTRL __REG(CAM_BASE_ADD+0x8C) // Preview main-scaler control
237 +#define CIPRTAREA __REG(CAM_BASE_ADD+0x90) // Preview pre-scaler destination
238 +#define CIPRSTATUS __REG(CAM_BASE_ADD+0x98) // Preview path status
239 +#define CIIMGCPT __REG(CAM_BASE_ADD+0xA0) // Image capture enable command
241 +#define CICOYSA(__x) __REG(CAM_BASE_ADD+0x18 + (__x)*4 )
242 +#define CICOCBSA(__x) __REG(CAM_BASE_ADD+0x28 + (__x)*4 )
243 +#define CICOCRSA(__x) __REG(CAM_BASE_ADD+0x38 + (__x)*4 )
244 +#define CIPRCLRSA(__x) __REG(CAM_BASE_ADD+0x6C + (__x)*4 )
246 +/* CISRCFMT BitField */
247 +#define SRCFMT_ITU601 BIT31
248 +#define SRCFMT_ITU656 0
249 +#define SRCFMT_UVOFFSET_128 BIT30
250 +#define fCAM_SIZE_H Fld(13, 16)
251 +#define fCAM_SIZE_V Fld(13, 0)
252 +#define SOURCE_HSIZE(x) FInsrt((x), fCAM_SIZE_H)
253 +#define SOURCE_VSIZE(x) FInsrt((x), fCAM_SIZE_V)
256 +/* Window Option Register */
257 +#define WINOFEN BIT31
258 +#define CO_FIFO_Y BIT30
259 +#define CO_FIFO_CB BIT15
260 +#define CO_FIFO_CR BIT14
261 +#define PR_FIFO_CB BIT13
262 +#define PR_FIFO_CR BIT12
263 +#define fWINHOR Fld(11, 16)
264 +#define fWINVER Fld(11, 0)
265 +#define WINHOROFST(x) FInsrt((x), fWINHOR)
266 +#define WINVEROFST(x) FInsrt((x), fWINVER)
268 +/* Global Control Register */
269 +#define GC_SWRST BIT31
270 +#define GC_CAMRST BIT30
271 +#define GC_INVPOLPCLK BIT26
272 +#define GC_INVPOLVSYNC BIT25
273 +#define GC_INVPOLHREF BIT24
275 +/*--------------------------------------------------
276 + REGISTER BIT FIELD DEFINITION TO
278 +----------------------------------------------------*/
279 +/* Codec Target Format Register */
280 +#define IN_YCBCR420 0
281 +#define IN_YCBCR422 BIT31
282 +#define OUT_YCBCR420 0
283 +#define OUT_YCBCR422 BIT30
286 +#define FLIP_NORMAL 0
287 +#define FLIP_X (BIT14)
288 +#define FLIP_Y (BIT15)
289 +#define FLIP_MIRROR (BIT14|BIT15)
292 +/** BEGIN ************************************/
293 +/* Cotents: Common in both P and C port */
294 +#define fTARGET_HSIZE Fld(13,16)
295 +#define TARGET_HSIZE(x) FInsrt((x), fTARGET_HSIZE)
296 +#define fTARGET_VSIZE Fld(13,0)
297 +#define TARGET_VSIZE(x) FInsrt((x), fTARGET_VSIZE)
298 +#define FLIP_X_MIRROR BIT14
299 +#define FLIP_Y_MIRROR BIT15
300 +#define FLIP_180_MIRROR (BIT14 | BIT15)
301 +/** END *************************************/
303 +/* Codec DMA Control Register */
304 +#define fYBURST_M Fld(5,19)
305 +#define fYBURST_R Fld(5,14)
306 +#define fCBURST_M Fld(5,9)
307 +#define fCBURST_R Fld(5,4)
308 +#define YBURST_M(x) FInsrt((x), fYBURST_M)
309 +#define CBURST_M(x) FInsrt((x), fCBURST_M)
310 +#define YBURST_R(x) FInsrt((x), fYBURST_R)
311 +#define CBURST_R(x) FInsrt((x), fCBURST_R)
312 +#define LAST_IRQ_EN BIT2 /* Common in both P and C port */
314 + * Check the done signal of capturing image for JPEG
315 + * !!! AutoClear Bit
319 +/* (Codec, Preview ) Pre-Scaler Control Register 1 */
320 +#define fSHIFT Fld(4,28)
321 +#define PRE_SHIFT(x) FInsrt((x), fSHIFT)
322 +#define fRATIO_H Fld(7,16)
323 +#define PRE_HRATIO(x) FInsrt((x), fRATIO_H)
324 +#define fRATIO_V Fld(7,0)
325 +#define PRE_VRATIO(x) FInsrt((x), fRATIO_V)
327 +/* (Codec, Preview ) Pre-Scaler Control Register 2*/
328 +#define fDST_WIDTH Fld(12,16)
329 +#define fDST_HEIGHT Fld(12,0)
330 +#define PRE_DST_WIDTH(x) FInsrt((x), fDST_WIDTH)
331 +#define PRE_DST_HEIGHT(x) FInsrt((x), fDST_HEIGHT)
334 +/* (Codec, Preview) Main-scaler control Register */
335 +#define S_METHOD BIT31 /* Sampling method only for P-port */
336 +#define SCALERSTART BIT15
337 +/* Codec scaler bypass for upper 2048x2048
338 + where ImgCptEn_CoSC and ImgCptEn_PrSC should be 0
341 +#define SCALERBYPASS BIT31
342 +#define RGB_FMT24 BIT30
346 +#define SCALE_UP_H BIT29
347 +#define SCALE_UP_V BIT28
350 +#define fMAIN_HRATIO Fld(9, 16)
351 +#define MAIN_HRATIO(x) FInsrt((x), fMAIN_HRATIO)
353 +#define SCALER_START BIT15
355 +#define fMAIN_VRATIO Fld(9, 0)
356 +#define MAIN_VRATIO(x) FInsrt((x), fMAIN_VRATIO)
358 +/* (Codec, Preview ) DMA Target AREA Register */
359 +#define fCICOTAREA Fld(26,0)
360 +#define TARGET_DMA_AREA(x) FInsrt((x), fCICOTAREA)
362 +/* Preview DMA Control Register */
363 +#define fRGBURST_M Fld(5,19)
364 +#define fRGBURST_R Fld(5,14)
365 +#define RGBURST_M(x) FInsrt((x), fRGBURST_M)
366 +#define RGBURST_R(x) FInsrt((x), fRGBURST_R)
369 +/* (Codec, Preview) Status Register */
370 +#define CO_OVERFLOW_Y BIT31
371 +#define CO_OVERFLOW_CB BIT30
372 +#define CO_OVERFLOW_CR BIT29
373 +#define PR_OVERFLOW_CB BIT31
374 +#define PR_OVERFLOW_CR BIT30
378 +#define fFRAME_CNT Fld(2,26)
379 +#define FRAME_CNT(x) FExtr((x),fFRAME_CNT)
381 +#define WIN_OFF_EN BIT25
382 +#define fFLIP_MODE Fld(2,23)
383 +#define FLIP_MODE(x) EExtr((x), fFLIP_MODE)
384 +#define CAP_STATUS_CAMIF BIT22
385 +#define CAP_STATUS_CODEC BIT21
386 +#define CAP_STATUS_PREVIEW BIT21
387 +#define VSYNC_A BIT20
388 +#define VSYNC_B BIT19
390 +/* Image Capture Enable Regiser */
391 +#define CAMIF_CAP_ON BIT31
392 +#define CAMIF_CAP_CODEC_ON BIT30
393 +#define CAMIF_CAP_PREVIEW_ON BIT29
398 +#endif /* S3C2440_CAMER_H */
399 diff --git a/arch/arm/mach-s3c2440/camera/camif.c b/arch/arm/mach-s3c2440/camera/camif.c
401 index 0000000..36d4ccc
403 +++ b/arch/arm/mach-s3c2440/camera/camif.c
406 + * Copyright (C) 2004 Samsung Electronics
407 + * SW.LEE <hitchcar@samsung.com>
409 + * This file is subject to the terms and conditions of the GNU General Public
410 + * License 2. See the file COPYING in the main directory of this archive
411 + * for more details.
414 +#include <linux/config.h>
415 +#include <linux/module.h>
416 +#include <linux/kernel.h>
417 +#include <linux/init.h>
418 +#include <linux/sched.h>
419 +#include <linux/irq.h>
420 +#include <linux/tqueue.h>
421 +#include <linux/locks.h>
422 +#include <linux/completion.h>
423 +#include <linux/delay.h>
424 +#include <linux/slab.h>
425 +#include <linux/vmalloc.h>
426 +#include <linux/miscdevice.h>
427 +#include <linux/wait.h>
428 +#include <linux/miscdevice.h>
430 +#include <asm/semaphore.h>
431 +#include <asm/hardware.h>
432 +#include <asm/uaccess.h>
434 +#ifdef CONFIG_ARCH_S3C24A0A
435 +#include <asm/arch/S3C24A0.h>
436 +#include <asm/arch/clocks.h>
438 +#include <asm/arch/S3C2440.h>
439 +#include <asm/arch/clocks.h>
442 +#include "cam_reg.h"
445 +#include "videodev.h"
446 +#include "miscdevice.h"
449 +static int camif_dma_burst(camif_cfg_t *);
450 +static int camif_scaler(camif_cfg_t *);
452 +static const char *camif_version =
453 + "$Id: camif.c,v 1.10 2004/06/04 04:24:14 swlee Exp $";
455 +/* For SXGA Image */
456 +#define RESERVE_MEM 15*1024*1024
457 +#define YUV_MEM 10*1024*1024
458 +#define RGB_MEM (RESERVE_MEM - YUV_MEM)
460 +static int camif_malloc(camif_cfg_t *cfg)
462 + unsigned int t_size;
463 + unsigned int daon = cfg->target_x *cfg->target_y;
465 + if(cfg->dma_type & CAMIF_CODEC) {
466 + if (cfg->fmt & CAMIF_OUT_YCBCR420) {
467 + t_size = daon * 3 / 2 ;
469 + else { t_size = daon * 2; /* CAMIF_OUT_YCBCR422 */ }
470 + t_size = t_size *cfg->pp_num;
472 +#ifndef SAMSUNG_SXGA_CAM
473 + cfg->pp_virt_buf = consistent_alloc(GFP_KERNEL, t_size, &cfg->pp_phys_buf);
475 + printk(KERN_INFO "Reserving High RAM Addresses \n");
476 + cfg->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVE_MEM);
477 + cfg->pp_virt_buf = ioremap_nocache(cfg->pp_phys_buf,YUV_MEM);
480 + if ( !cfg->pp_virt_buf ) {
481 + printk(KERN_ERR"CAMERA:Failed to request YCBCR MEM\n");
484 + memset(cfg->pp_virt_buf, 0, t_size);
485 + cfg->pp_totalsize = t_size;
488 + if ( cfg->dma_type & CAMIF_PREVIEW ) {
489 + if (cfg->fmt & CAMIF_RGB16)
490 + t_size = daon * 2; /* 4byte per two pixel*/
492 + assert(cfg->fmt & CAMIF_RGB24);
493 + t_size = daon * 4; /* 4byte per one pixel */
495 + t_size = t_size * cfg->pp_num;
496 +#ifndef SAMSUNG_SXGA_CAM
497 + cfg->pp_virt_buf = consistent_alloc(GFP_KERNEL, t_size, &cfg->pp_phys_buf);
499 + printk(KERN_INFO "Reserving High RAM Addresses \n");
500 + cfg->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVE_MEM ) + YUV_MEM;
501 + cfg->pp_virt_buf = ioremap_nocache(cfg->pp_phys_buf,RGB_MEM);
503 + if ( !cfg->pp_virt_buf ) {
504 + printk(KERN_ERR"CAMERA:Failed to request RGB MEM\n");
507 + memset(cfg->pp_virt_buf, 0, t_size);
508 + cfg->pp_totalsize = t_size;
512 + return 0; /* Never come. */
515 +static int camif_demalloc(camif_cfg_t *cfg)
517 +#ifndef SAMSUNG_SXGA_CAM
518 + if ( cfg->pp_virt_buf ) {
519 + consistent_free(cfg->pp_virt_buf,cfg->pp_totalsize,cfg->pp_phys_buf);
520 + cfg->pp_virt_buf = 0;
523 + iounmap(cfg->pp_virt_buf);
524 + cfg->pp_virt_buf = 0;
530 + * advise a person to use this func in ISR
531 + * index value indicates the next frame count to be used
533 +int camif_g_frame_num(camif_cfg_t *cfg)
537 + if (cfg->dma_type & CAMIF_CODEC ) {
538 + index = FRAME_CNT(CICOSTATUS);
539 + DPRINTK("CAMIF_CODEC frame %d \n", index);
542 + assert(cfg->dma_type & CAMIF_PREVIEW );
543 + index = FRAME_CNT(CIPRSTATUS);
544 + DPRINTK("CAMIF_PREVIEW frame %d 0x%08X \n", index, CIPRSTATUS);
546 + cfg->now_frame_num = (index + 2) % 4; /* When 4 PingPong */
547 + return index; /* meaningless */
550 +static int camif_pp_codec(camif_cfg_t *cfg)
552 + u32 i, c_size; /* Cb,Cr size */
554 + u32 daon = cfg->target_x * cfg->target_y;
555 + if (cfg->fmt & CAMIF_OUT_YCBCR420) {
559 + assert(cfg->fmt & CAMIF_OUT_YCBCR422);
562 + switch ( cfg->pp_num ) {
564 + for ( i =0 ; i < 4; i=i+1) {
565 + cfg->img_buf[i].virt_y = cfg->pp_virt_buf;
566 + cfg->img_buf[i].phys_y = cfg->pp_phys_buf;
567 + cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon;
568 + cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon;
569 + cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size;
570 + cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size;
571 + CICOYSA(i) = cfg->img_buf[i].phys_y;
572 + CICOCBSA(i) = cfg->img_buf[i].phys_cb;
573 + CICOCRSA(i) = cfg->img_buf[i].phys_cr;
577 +#define TRY (( i%2 ) ? 1 :0)
578 + one_p_size = daon + 2*c_size;
579 + for (i = 0; i < 4 ; i++) {
580 + cfg->img_buf[i].virt_y = cfg->pp_virt_buf + TRY * one_p_size;
581 + cfg->img_buf[i].phys_y = cfg->pp_phys_buf + TRY * one_p_size;
582 + cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon + TRY * one_p_size;
583 + cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon + TRY * one_p_size;
584 + cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size + TRY * one_p_size;
585 + cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size + TRY * one_p_size;
586 + CICOYSA(i) = cfg->img_buf[i].phys_y;
587 + CICOCBSA(i) = cfg->img_buf[i].phys_cb;
588 + CICOCRSA(i) = cfg->img_buf[i].phys_cr;
592 + one_p_size = daon + 2*c_size;
593 + for (i = 0; i < 4 ; i++) {
594 + cfg->img_buf[i].virt_y = cfg->pp_virt_buf + i * one_p_size;
595 + cfg->img_buf[i].phys_y = cfg->pp_phys_buf + i * one_p_size;
596 + cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon + i * one_p_size;
597 + cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon + i * one_p_size;
598 + cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size + i * one_p_size;
599 + cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size + i * one_p_size;
600 + CICOYSA(i) = cfg->img_buf[i].phys_y;
601 + CICOCBSA(i) = cfg->img_buf[i].phys_cb;
602 + CICOCRSA(i) = cfg->img_buf[i].phys_cr;
606 + printk("Invalid PingPong Number %d \n",cfg->pp_num);
612 +/* RGB Buffer Allocation */
613 +static int camif_pp_preview(camif_cfg_t *cfg)
616 + u32 daon = cfg->target_x * cfg->target_y;
618 + if(cfg->fmt & CAMIF_RGB24)
621 + assert (cfg->fmt & CAMIF_RGB16);
624 + switch ( cfg->pp_num ) {
626 + for ( i = 0; i < 4 ; i++ ) {
627 + cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf ;
628 + cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf ;
629 + CIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;
633 + for ( i = 0; i < 4 ; i++) {
634 + cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + TRY * daon;
635 + cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + TRY * daon;
636 + CIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;
640 + for ( i = 0; i < 4 ; i++) {
641 + cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + i * daon;
642 + cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + i * daon;
643 + CIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;
647 + printk("Invalid PingPong Number %d \n",cfg->pp_num);
653 +static int camif_pingpong(camif_cfg_t *cfg)
655 + if (cfg->dma_type & CAMIF_CODEC ) {
656 + camif_pp_codec(cfg);
659 + if ( cfg->dma_type & CAMIF_PREVIEW) {
660 + camif_pp_preview(cfg);
666 +/*********** Image Convert *******************************/
668 + * Supported by Hardware
669 + * V4L2_PIX_FMT_YUV420,
670 + * V4L2_PIX_FMT_YUV422P,
671 + * V4L2_PIX_FMT_BGR32 (BGR4)
672 + * -----------------------------------
673 + * V4L2_PIX_FMT_RGB565(X)
674 + * Currenly 2byte --> BGR656 Format
675 + * S3C2440A,S3C24A0 supports vairants with reversed FMT_RGB565
676 + i.e blue toward the least, red towards the most significant bit
682 + * After calling camif_g_frame_num,
683 + * this func must be called
685 +u8 * camif_g_frame(camif_cfg_t *cfg)
688 + int cnt = cfg->now_frame_num;
690 + if(cfg->dma_type & CAMIF_PREVIEW) {
691 + ret = cfg->img_buf[cnt].virt_rgb;
693 + if (cfg->dma_type & CAMIF_CODEC) {
694 + ret = cfg->img_buf[cnt].virt_y;
699 +/* This function must be called in module initial time */
700 +static int camif_source_fmt(camif_gc_t *gc)
704 + /* Configure CISRCFMT --Source Format */
705 + if (gc->itu_fmt & CAMIF_ITU601) {
706 + cmd = CAMIF_ITU601;
709 + assert ( gc->itu_fmt & CAMIF_ITU656);
710 + cmd = CAMIF_ITU656;
712 + cmd |= SOURCE_HSIZE(gc->source_x)| SOURCE_VSIZE(gc->source_y);
714 + cmd |= gc->order422;
722 + * Codec Input YCBCR422 will be Fixed
724 +static int camif_target_fmt(camif_cfg_t *cfg)
728 + if (cfg->dma_type & CAMIF_CODEC) {
729 + /* YCBCR setting */
730 + cmd = TARGET_HSIZE(cfg->target_x)| TARGET_VSIZE(cfg->target_y);
731 + if ( cfg->fmt & CAMIF_OUT_YCBCR420 ) {
732 + cmd |= OUT_YCBCR420|IN_YCBCR422;
735 + assert(cfg->fmt & CAMIF_OUT_YCBCR422);
736 + cmd |= OUT_YCBCR422|IN_YCBCR422;
738 + CICOTRGFMT = cmd | cfg->flip;
741 + assert(cfg->dma_type & CAMIF_PREVIEW);
743 + TARGET_HSIZE(cfg->target_x)|TARGET_VSIZE(cfg->target_y)|cfg->flip;
748 +void camif_change_flip(camif_cfg_t *cfg)
752 + if (cfg->dma_type & CAMIF_CODEC ) {
753 + /* YCBCR setting */
755 + cmd &= ~(BIT14|BIT15); /* Clear FLIP Mode */
761 + cmd &= ~(BIT14|BIT15);
770 + * Before calling this function,
771 + * you must use "camif_dynamic_open"
772 + * If you want to enable both CODEC and preview
773 + * you must do it at the same time.
775 +int camif_capture_start(camif_cfg_t *cfg)
777 + u32 n_cmd = 0; /* Next Command */
779 + switch(cfg->exec) {
780 + case CAMIF_BOTH_DMA_ON:
781 + camif_reset(CAMIF_RESET,0); /* Flush Camera Core Buffer */
782 + CIPRSCCTRL |= SCALERSTART;
783 + CICOSCCTRL |= SCALERSTART;
784 + n_cmd = CAMIF_CAP_PREVIEW_ON|CAMIF_CAP_CODEC_ON;
787 + camif_reset(CAMIF_RESET,0); /* Flush Camera Core Buffer */
788 + if (cfg->dma_type&CAMIF_CODEC) {
789 + CICOSCCTRL |= SCALERSTART;
790 + n_cmd = CAMIF_CAP_CODEC_ON;
792 + CIPRSCCTRL |= SCALERSTART;
793 + n_cmd = CAMIF_CAP_PREVIEW_ON;
796 + /* wait until Sync Time expires */
797 + /* First settting, to wait VSYNC fall */
798 + /* By VESA spec,in 640x480 @60Hz
799 + MAX Delay Time is around 64us which "while" has.*/
800 + while(VSYNC & CICOSTATUS);
805 + CIIMGCPT = n_cmd|CAMIF_CAP_ON;
810 +int camif_capture_stop(camif_cfg_t *cfg)
812 + u32 n_cmd = CIIMGCPT; /* Next Command */
814 + switch(cfg->exec) {
815 + case CAMIF_BOTH_DMA_OFF:
816 + CIPRSCCTRL &= ~SCALERSTART;
817 + CICOSCCTRL &= ~SCALERSTART;
820 + case CAMIF_DMA_OFF_L_IRQ: /* fall thru */
821 + case CAMIF_DMA_OFF:
822 + if (cfg->dma_type&CAMIF_CODEC) {
823 + CICOSCCTRL &= ~SCALERSTART;
824 + n_cmd &= ~CAMIF_CAP_CODEC_ON;
825 + if (!(n_cmd & CAMIF_CAP_PREVIEW_ON))
828 + CIPRSCCTRL &= ~SCALERSTART;
829 + n_cmd &= ~CAMIF_CAP_PREVIEW_ON;
830 + if (!(n_cmd & CAMIF_CAP_CODEC_ON))
835 + panic("Unexpected \n");
838 + if(cfg->exec == CAMIF_DMA_OFF_L_IRQ) { /* Last IRQ */
839 + if (cfg->dma_type & CAMIF_CODEC)
840 + CICOCTRL |= LAST_IRQ_EN;
842 + CIPRCTRL |= LAST_IRQ_EN;
845 + else { /* to make internal state machine of CAMERA stop */
846 + camif_reset(CAMIF_RESET, 0);
853 +/* LastIRQEn is autoclear */
854 +void camif_last_irq_en(camif_cfg_t *cfg)
856 + if(cfg->exec == CAMIF_BOTH_DMA_ON) {
857 + CIPRCTRL |= LAST_IRQ_EN;
858 + CICOCTRL |= LAST_IRQ_EN;
861 + if (cfg->dma_type & CAMIF_CODEC)
862 + CICOCTRL |= LAST_IRQ_EN;
864 + CIPRCTRL |= LAST_IRQ_EN;
869 +camif_scaler_internal(u32 srcWidth, u32 dstWidth, u32 *ratio, u32 *shift)
871 + if(srcWidth>=64*dstWidth){
872 + printk(KERN_ERR"CAMERA:out of prescaler range: srcWidth /dstWidth = %d(< 64)\n",
873 + srcWidth/dstWidth);
876 + else if(srcWidth>=32*dstWidth){
880 + else if(srcWidth>=16*dstWidth){
884 + else if(srcWidth>=8*dstWidth){
888 + else if(srcWidth>=4*dstWidth){
892 + else if(srcWidth>=2*dstWidth){
904 +int camif_g_fifo_status(camif_cfg_t *cfg)
908 + if (cfg->dma_type & CAMIF_CODEC) {
909 + u32 flag = CO_OVERFLOW_Y|CO_OVERFLOW_CB|CO_OVERFLOW_CR;
912 + printk("CODEC: FIFO error(0x%08x) and corrected\n",reg);
913 + /* FIFO Error Count ++ */
914 + CIWDOFST |= CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR;
915 + CIWDOFST &= ~(CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR);
916 + return 1; /* Error */
919 + if (cfg->dma_type & CAMIF_PREVIEW) {
920 + u32 flag = PR_OVERFLOW_CB|PR_OVERFLOW_CR;
923 + printk("PREVIEW:FIFO error(0x%08x) and corrected\n",reg);
924 + CIWDOFST |= PR_FIFO_CB|PR_FIFO_CR;
925 + CIWDOFST &= ~(CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR);
926 + /* FIFO Error Count ++ */
927 + return 1; /* Error */
930 + return 0; /* No Error */
935 + * if codec or preview define the win offset,
936 + * other must follow that value.
938 +int camif_win_offset(camif_gc_t *gc )
940 + u32 h = gc->win_hor_ofst;
941 + u32 v = gc->win_ver_ofst;
943 + /*Clear Overflow */
944 + CIWDOFST = CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR|PR_FIFO_CB|PR_FIFO_CB;
945 + CIWDOFST = 0; /* ? Dummy */
950 + CIWDOFST = WINOFEN | WINHOROFST(h) | WINVEROFST(v);
955 + * when you change the resolution in a specific camera,
956 + * sometimes, it is necessary to change the polarity
959 +static void camif_polarity(camif_gc_t *gc)
963 + cmd = cmd & ~(BIT26|BIT25|BIT24); /* clear polarity */
964 + if (gc->polarity_pclk)
965 + cmd |= GC_INVPOLPCLK;
966 + if (gc->polarity_vsync)
967 + cmd |= GC_INVPOLVSYNC;
968 + if (gc->polarity_href)
969 + cmd |= GC_INVPOLHREF;
974 +int camif_dynamic_open(camif_cfg_t *cfg)
976 + camif_win_offset(cfg->gc);
977 + camif_polarity(cfg->gc);
979 + if(camif_scaler(cfg)) {
980 + printk(KERN_ERR "CAMERA:Preview Scaler, Change WinHorOfset or Target Size\n");
983 + camif_target_fmt(cfg);
984 + if (camif_dma_burst(cfg)) {
985 + printk(KERN_ERR "CAMERA:DMA Busrt Length Error \n");
988 + if(camif_malloc(cfg) ) {
989 + printk(KERN_ERR " Instead of using consistent_alloc()\n"
990 + " lease use dedicated memory allocation for DMA memory\n");
993 + camif_pingpong(cfg);
997 +int camif_dynamic_close(camif_cfg_t *cfg)
999 + camif_demalloc(cfg);
1003 +static int camif_target_area(camif_cfg_t *cfg)
1005 + u32 rect = cfg->target_x * cfg->target_y;
1006 + if (cfg->dma_type & CAMIF_CODEC ) {
1009 + if (cfg->dma_type & CAMIF_PREVIEW) {
1015 +static int inline camif_hw_reg(camif_cfg_t *cfg)
1019 + if (cfg->dma_type & CAMIF_CODEC) {
1020 + CICOSCPRERATIO = PRE_SHIFT(cfg->sc.shfactor)
1021 + |PRE_HRATIO(cfg->sc.prehratio)|PRE_VRATIO(cfg->sc.prevratio);
1023 + PRE_DST_WIDTH(cfg->sc.predst_x)|PRE_DST_HEIGHT(cfg->sc.predst_y);
1025 + /* Differ from Preview */
1026 + if (cfg->sc.scalerbypass)
1027 + cmd |= SCALERBYPASS;
1028 + if (cfg->sc.scaleup_h & cfg->sc.scaleup_v)
1029 + cmd |= BIT30|BIT29;
1030 + CICOSCCTRL = cmd | MAIN_HRATIO(cfg->sc.mainhratio)
1031 + |MAIN_VRATIO(cfg->sc.mainvratio);
1034 + else if (cfg->dma_type & CAMIF_PREVIEW) {
1035 + CIPRSCPRERATIO = PRE_SHIFT(cfg->sc.shfactor)
1036 + |PRE_HRATIO(cfg->sc.prehratio)|PRE_VRATIO(cfg->sc.prevratio);
1038 + PRE_DST_WIDTH(cfg->sc.predst_x)|PRE_DST_HEIGHT(cfg->sc.predst_y);
1039 + /* Differ from Codec */
1040 + if (cfg->fmt & CAMIF_RGB24) {
1046 + if (cfg->sc.scaleup_h & cfg->sc.scaleup_v)
1047 + cmd |= BIT29|BIT28;
1048 + CIPRSCCTRL = cmd |MAIN_HRATIO(cfg->sc.mainhratio)|S_METHOD
1049 + |MAIN_VRATIO(cfg->sc.mainvratio);
1051 + panic("CAMERA:DMA_TYPE Wrong \n");
1058 +/* Configure Pre-scaler control & main scaler control register */
1059 +static int camif_scaler(camif_cfg_t *cfg)
1061 + int tx = cfg->target_x,ty=cfg->target_y;
1064 + if (tx <= 0 || ty<= 0) panic("CAMERA: Invalid target size \n");
1066 + sx = cfg->gc->source_x - 2*cfg->gc->win_hor_ofst;
1067 + sy = cfg->gc->source_y - 2*cfg->gc->win_ver_ofst;
1068 + if (sx <= 0 || sy<= 0) panic("CAMERA: Invalid source size \n");
1069 + cfg->sc.modified_src_x = sx;
1070 + cfg->sc.modified_src_y = sy;
1072 + /* Pre-scaler control register 1 */
1073 + camif_scaler_internal(sx,tx,&cfg->sc.prehratio,&cfg->sc.hfactor);
1074 + camif_scaler_internal(sy,ty,&cfg->sc.prevratio,&cfg->sc.vfactor);
1076 + if (cfg->dma_type & CAMIF_PREVIEW) {
1077 + if ( (sx /cfg->sc.prehratio) <= 640 ) {}
1079 + printk(KERN_INFO "CAMERA: Internal Preview line buffer is 640 pixels\n");
1080 + return 1; /* Error */
1084 + cfg->sc.shfactor = 10-(cfg->sc.hfactor+cfg->sc.vfactor);
1085 + /* Pre-scaler control register 2 */
1086 + cfg->sc.predst_x = sx / cfg->sc.prehratio;
1087 + cfg->sc.predst_y = sy / cfg->sc.prevratio;
1089 + /* Main-scaler control register */
1090 + cfg->sc.mainhratio = (sx << 8)/(tx << cfg->sc.hfactor);
1091 + cfg->sc.mainvratio = (sy << 8)/(ty << cfg->sc.vfactor);
1092 + DPRINTK(" sx %d, sy %d tx %d ty %d \n",sx,sy,tx,ty);
1093 + DPRINTK(" hfactor %d vfactor %d \n",cfg->sc.hfactor,cfg->sc.vfactor);
1095 + cfg->sc.scaleup_h = (sx <= tx) ? 1: 0;
1096 + cfg->sc.scaleup_v = (sy <= ty) ? 1: 0;
1097 + if ( cfg->sc.scaleup_h != cfg->sc.scaleup_v)
1098 + printk(KERN_ERR "scaleup_h must be same to scaleup_v \n");
1099 + camif_hw_reg(cfg);
1100 + camif_target_area(cfg);
1104 +/******************************************************
1105 + CalculateBurstSize - Calculate the busrt lengths
1107 + - dstHSize: the number of the byte of H Size.
1108 +********************************************************/
1109 +static void camif_g_bsize(u32 hsize, u32 *mburst, u32 *rburst)
1113 + tmp = (hsize/4) % 16;
1140 + *rburst= (tmp) ? tmp: 4;
1147 +/* SXGA 1028x1024*/
1155 + 1 : DMA Size Error
1157 +#define BURST_ERR 1
1158 +static int camif_dma_burst(camif_cfg_t *cfg)
1160 + int width = cfg->target_x;
1162 + if (cfg->dma_type & CAMIF_CODEC ) {
1163 + u32 yburst_m, yburst_r;
1164 + u32 cburst_m, cburst_r;
1165 + /* CODEC DMA WIDHT is multiple of 16 */
1166 + if (width %16 != 0 ) return BURST_ERR; /* DMA Burst Length Error */
1167 + camif_g_bsize(width,&yburst_m,&yburst_r);
1168 + camif_g_bsize(width/2,&cburst_m,&cburst_r);
1169 + CICOCTRL =YBURST_M(yburst_m)|CBURST_M(cburst_m)
1170 + |YBURST_R(yburst_r)|CBURST_R(cburst_r);
1173 + if (cfg->dma_type & CAMIF_PREVIEW) {
1174 + u32 rgburst_m, rgburst_r;
1175 + if(cfg->fmt == CAMIF_RGB24) {
1176 + if (width %2 != 0 ) return BURST_ERR; /* DMA Burst Length Error */
1177 + camif_g_bsize(width*4,&rgburst_m,&rgburst_r);
1179 + else { /* CAMIF_RGB16 */
1180 + if ((width/2) %2 != 0 ) return BURST_ERR; /* DMA Burst Length Error */
1181 + camif_g_bsize(width*2,&rgburst_m,&rgburst_r);
1183 + CIPRCTRL = RGBURST_M(rgburst_m) | RGBURST_R(rgburst_r);
1188 +static int camif_gpio_init(void)
1190 +#ifdef CONFIG_ARCH_S3C24A0A
1191 + /* S3C24A0A has the dedicated signal pins for Camera */
1193 + set_gpio_ctrl(GPIO_CAMDATA0);
1194 + set_gpio_ctrl(GPIO_CAMDATA1);
1195 + set_gpio_ctrl(GPIO_CAMDATA2);
1196 + set_gpio_ctrl(GPIO_CAMDATA3);
1197 + set_gpio_ctrl(GPIO_CAMDATA4);
1198 + set_gpio_ctrl(GPIO_CAMDATA5);
1199 + set_gpio_ctrl(GPIO_CAMDATA6);
1200 + set_gpio_ctrl(GPIO_CAMDATA7);
1201 + set_gpio_ctrl(GPIO_CAMPCLKIN);
1202 + set_gpio_ctrl(GPIO_CAMVSYNC);
1203 + set_gpio_ctrl(GPIO_CAMHREF);
1204 + set_gpio_ctrl(GPIO_CAMPCLKOUT);
1205 + set_gpio_ctrl(GPIO_CAMRESET);
1211 +#define ROUND_ADD 0x100000
1213 +#ifdef CONFIG_ARCH_S3C24A0A
1214 +int camif_clock_init(camif_gc_t *gc)
1216 + unsigned int upll, camclk_div, camclk;
1218 + if (!gc) camclk = 24000000;
1220 + camclk = gc->camclk;
1221 + if (camclk > 48000000)
1222 + printk(KERN_ERR "Wrong Camera Clock\n");
1225 + CLKCON |= CLKCON_CAM_UPLL | CLKCON_CAM_HCLK;
1226 + upll = get_bus_clk(GET_UPLL);
1227 + printk(KERN_INFO "CAMERA:Default UPLL %08d and Assing 96Mhz to UPLL\n",upll);
1228 + UPLLCON = FInsrt(56, fPLL_MDIV) | FInsrt(2, fPLL_PDIV)| FInsrt(1, fPLL_SDIV);
1229 + upll = get_bus_clk(GET_UPLL);
1231 + camclk_div = (upll+ROUND_ADD) / camclk - 1;
1232 + CLKDIVN = (CLKDIVN & 0xFF) | CLKDIVN_CAM(camclk_div);
1233 + printk(KERN_INFO"CAMERA:upll %d MACRO 0x%08X CLKDIVN 0x%08X \n",
1234 + upll, CLKDIVN_CAM(camclk_div),CLKDIVN);
1235 + CIIMGCPT = 0; /* Dummy ? */
1239 +int camif_clock_init(camif_gc_t *gc)
1241 + unsigned int upll, camclk_div, camclk;
1242 + if (!gc) camclk = 24000000;
1244 + camclk = gc->camclk;
1245 + if (camclk > 48000000)
1246 + printk(KERN_ERR "Wrong Camera Clock\n");
1249 + CLKCON |= CLKCON_CAMIF;
1250 + upll = elfin_get_bus_clk(GET_UPLL);
1251 + printk(KERN_INFO "CAMERA:Default UPLL %08d and Assing 96Mhz to UPLL\n",upll);
1253 + UPLLCON = FInsrt(60, fPLL_MDIV) | FInsrt(4, fPLL_PDIV)| FInsrt(1, fPLL_SDIV);
1254 + CLKDIVN |= DIVN_UPLL; /* For USB */
1255 + upll = elfin_get_bus_clk(GET_UPLL);
1258 + camclk_div = (upll+ROUND_ADD) /(camclk * 2) -1;
1259 + CAMDIVN = CAMCLK_SET_DIV|(camclk_div&0xf);
1260 + printk(KERN_INFO "CAMERA:upll %08d cam_clk %08d CAMDIVN 0x%08x \n",upll,camclk, CAMDIVN);
1261 + CIIMGCPT = 0; /* Dummy ? */
1267 + Reset Camera IP in CPU
1268 + Reset External Sensor
1270 +void camif_reset(int is, int delay)
1274 + CIGCTRL |= GC_SWRST;
1276 + CIGCTRL &= ~GC_SWRST;
1278 + case CAMIF_EX_RESET_AH: /*Active High */
1279 + CIGCTRL &= ~GC_CAMRST;
1281 + CIGCTRL |= GC_CAMRST;
1283 + CIGCTRL &= ~GC_CAMRST;
1285 + case CAMIF_EX_RESET_AL: /*Active Low */
1286 + CIGCTRL |= GC_CAMRST;
1288 + CIGCTRL &= ~GC_CAMRST;
1290 + CIGCTRL |= GC_CAMRST;
1297 +/* For Camera Operation,
1298 + * we can give the high priority to REQ2 of ARBITER1
1301 +/* Please move me into proper place
1302 + * camif_gc_t is not because "rmmod imgsenor" will delete the instance of camif_gc_t
1304 +static u32 old_priority;
1306 +static void camif_bus_priority(int flag)
1309 +#ifdef CONFIG_ARCH_S3C24A0A
1310 + old_priority = PRIORITY0;
1311 + PRIORITY0 = PRIORITY_I_FIX;
1312 + PRIORITY1 = PRIORITY_I_FIX;
1315 + old_priority = PRIORITY;
1316 + PRIORITY &= ~(3<<7);
1317 + PRIORITY |= (1<<7); /* Arbiter 1, REQ2 first */
1318 + PRIORITY &= ~(1<<1); /* Disable Priority Rotate */
1322 +#ifdef CONFIG_ARCH_S3C24A0A
1323 + PRIORITY0 = old_priority;
1324 + PRIORITY1 = old_priority;
1326 + PRIORITY = old_priority;
1331 +static void inline camif_clock_off(void)
1334 +#if defined (CONFIG_ARCH_S3C24A0A)
1335 + CLKCON &= ~CLKCON_CAM_UPLL;
1336 + CLKCON &= ~CLKCON_CAM_HCLK;
1338 + CLKCON &= ~CLKCON_CAMIF;
1343 +/* Init external image sensor
1344 + * Before make some value into image senor,
1345 + * you must set up the pixel clock.
1347 +void camif_setup_sensor(void)
1349 + camif_reset(CAMIF_RESET, 0);
1350 + camif_gpio_init();
1351 + camif_clock_init(NULL);
1352 +/* Sometimes ,Before loading I2C module, we need the reset signal */
1353 +#ifdef CONFIG_ARCH_S3C24A0A
1354 + camif_reset(CAMIF_EX_RESET_AL,1000);
1356 + camif_reset(CAMIF_EX_RESET_AH,1000);
1360 +void camif_hw_close(camif_cfg_t *cfg)
1362 + camif_bus_priority(0);
1363 + camif_clock_off();
1366 +void camif_hw_open(camif_gc_t *gc)
1368 + camif_source_fmt(gc);
1369 + camif_win_offset(gc);
1370 + camif_bus_priority(1);
1376 + * Local variables:
1378 + * c-indent-level: 8
1379 + * c-basic-offset: 8
1380 + * c-set-style: "K&R"
1383 diff --git a/arch/arm/mach-s3c2440/camera/camif.h b/arch/arm/mach-s3c2440/camera/camif.h
1384 new file mode 100644
1385 index 0000000..8b4f9aa
1387 +++ b/arch/arm/mach-s3c2440/camera/camif.h
1390 + FIMC2.0 Camera Header File
1392 + Copyright (C) 2003 Samsung Electronics (SW.LEE: hitchcar@samsung.com)
1394 + Author : SW.LEE <hitchcar@samsung.com>
1396 + This program is free software; you can redistribute it and/or modify
1397 + it under the terms of the GNU General Public License as published by
1398 + the Free Software Foundation; either version 2 of the License, or
1399 + (at your option) any later version.
1404 +#ifndef __FIMC20_CAMIF_H_
1405 +#define __FIMC20_CAMIF_H_
1410 +#include "videodev.h"
1411 +#include <asm/types.h>
1412 +#include <linux/i2c.h>
1414 +#endif /* __KERNEL__ */
1417 +#define O_NONCAP O_TRUNC
1420 +/* Codec or Preview Status */
1421 +#define CAMIF_STARTED BIT1
1422 +#define CAMIF_STOPPED BIT2
1423 +#define CAMIF_INT_HAPPEN BIT3
1425 +/* Codec or Preview : Interrupt FSM */
1426 +#define CAMIF_1nd_INT BIT7
1427 +#define CAMIF_Xnd_INT BIT8
1428 +#define CAMIF_Ynd_INT BIT9
1429 +#define CAMIF_Znd_INT BIT10
1430 +#define CAMIF_NORMAL_INT BIT11
1431 +#define CAMIF_DUMMY_INT BIT12
1432 +#define CAMIF_PENDING_INT 0
1435 +/* CAMIF RESET Definition */
1436 +#define CAMIF_RESET BIT0
1437 +#define CAMIF_EX_RESET_AL BIT1 /* Active Low */
1438 +#define CAMIF_EX_RESET_AH BIT2 /* Active High */
1441 +enum camif_itu_fmt {
1442 + CAMIF_ITU601 = BIT31,
1446 +/* It is possbie to use two device simultaneously */
1447 +enum camif_dma_type {
1448 + CAMIF_PREVIEW = BIT0,
1449 + CAMIF_CODEC = BIT1,
1452 +enum camif_order422 {
1454 + CAMIF_YCRYCB = BIT14,
1455 + CAMIF_CBYCRY = BIT15,
1456 + CAMIF_CRYCBY = BIT14 | BIT15
1461 + CAMIF_FLIP_X = BIT14,
1462 + CAMIF_FLIP_Y = BIT15,
1463 + CAMIF_FLIP_MIRROR = BIT14 |BIT15,
1466 +enum camif_codec_fmt {
1468 + CAMIF_IN_YCBCR420 = BIT0, /* Currently IN_YCBCR format fixed */
1469 + CAMIF_IN_YCBCR422 = BIT1,
1470 + CAMIF_OUT_YCBCR420 = BIT4,
1471 + CAMIF_OUT_YCBCR422 = BIT5,
1472 + /* Preview Part */
1473 + CAMIF_RGB16 = BIT2,
1474 + CAMIF_RGB24 = BIT3,
1477 +enum camif_capturing {
1478 + CAMIF_BOTH_DMA_ON = BIT4,
1479 + CAMIF_DMA_ON = BIT3,
1480 + CAMIF_BOTH_DMA_OFF = BIT1,
1481 + CAMIF_DMA_OFF = BIT0,
1482 + /*------------------------*/
1483 + CAMIF_DMA_OFF_L_IRQ= BIT5,
1486 +typedef struct camif_performance
1489 + int framesdropped;
1492 + __u32 reserved[4];
1497 + dma_addr_t phys_y;
1498 + dma_addr_t phys_cb;
1499 + dma_addr_t phys_cr;
1503 + dma_addr_t phys_rgb;
1508 +/* this structure convers the CIWDOFFST, prescaler, mainscaler */
1510 + u32 modified_src_x; /* After windows applyed to source_x */
1511 + u32 modified_src_y;
1514 + u32 shfactor; /* SHfactor = 10 - ( hfactor + vfactor ) */
1523 + u32 scalerbypass; /* only codec */
1528 + CAMIF_V4L2_INIT = BIT0,
1529 + CAMIF_v4L2_DIRTY = BIT1,
1533 +/* Global Status Definition */
1534 +#define PWANT2START BIT0
1535 +#define CWANT2START BIT1
1536 +#define BOTH_STARTED (PWANT2START|CWANT2START)
1537 +#define PNOTWORKING BIT4
1538 +#define C_WORKING BIT5
1541 + struct semaphore lock;
1542 + enum camif_itu_fmt itu_fmt;
1543 + enum camif_order422 order422;
1546 + u32 camclk; /* External Image Sensor Camera Clock */
1549 + u32 polarity_pclk;
1550 + u32 polarity_vsync;
1551 + u32 polarity_href;
1552 + struct i2c_client *sensor;
1553 + u32 user; /* MAX 2 (codec, preview) */
1554 + u32 old_priority; /* BUS PRIORITY register */
1556 + u32 init_sensor;/* initializing sensor */
1557 + void *other; /* Codec camif_cfg_t */
1558 + u32 reset_type; /* External Sensor Reset Type */
1560 +} camif_gc_t; /* gobal control register */
1563 +/* when App want to change v4l2 parameter,
1564 + * we instantly store it into v4l2_t v2
1565 + * and then reflect it to hardware
1567 +typedef struct v4l2 {
1568 + struct v4l2_fmtdesc *fmtdesc;
1569 + struct v4l2_pix_format fmt; /* current pixel format */
1570 + struct v4l2_input input;
1571 + struct video_picture picture;
1572 + enum v4l2_status status;
1573 + int used_fmt ; /* used format index */
1577 +typedef struct camif_c_t {
1578 + struct video_device *v;
1579 + /* V4L2 param only for v4l2 driver */
1581 + camif_gc_t *gc; /* Common between Codec and Preview */
1582 + /* logical parameter */
1583 + wait_queue_head_t waitq;
1584 + u32 status; /* Start/Stop */
1585 + u32 fsm; /* Start/Stop */
1586 + u32 open_count; /* duplicated */
1588 + char shortname[16];
1592 + enum flip_mode flip;
1593 + enum camif_dma_type dma_type;
1594 + /* 4 pingpong Frame memory */
1596 + dma_addr_t pp_phys_buf;
1598 + u32 pp_num; /* used pingpong memory number */
1599 + img_buf_t img_buf[4];
1600 + enum camif_codec_fmt fmt;
1601 + enum camif_capturing exec;
1602 + camif_perf_t perf;
1603 + u32 now_frame_num;
1604 + u32 auto_restart; /* Only For Preview */
1608 +#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
1610 +#define DPRINTK(fmt, args...)
1615 +#define assert(expr) \
1617 + printk( "Assertion failed! %s,%s,%s,line=%d\n", \
1618 + #expr,__FILE__,__FUNCTION__,__LINE__); \
1621 +#define assert(expr)
1626 +extern int camif_capture_start(camif_cfg_t *);
1627 +extern int camif_capture_stop(camif_cfg_t *);
1628 +extern int camif_g_frame_num(camif_cfg_t *);
1629 +extern u8 * camif_g_frame(camif_cfg_t *);
1630 +extern int camif_win_offset(camif_gc_t *);
1631 +extern void camif_hw_open(camif_gc_t *);
1632 +extern void camif_hw_close(camif_cfg_t *);
1633 +extern int camif_dynamic_open(camif_cfg_t *);
1634 +extern int camif_dynamic_close(camif_cfg_t *);
1635 +extern void camif_reset(int,int);
1636 +extern void camif_setup_sensor(void);
1637 +extern int camif_g_fifo_status(camif_cfg_t *);
1638 +extern void camif_last_irq_en(camif_cfg_t *);
1639 +extern void camif_change_flip(camif_cfg_t *);
1643 + * API Interface function to both Character and V4L2 Drivers
1645 +extern int camif_do_write(struct file *,const char *, size_t, loff_t *);
1646 +extern int camif_do_ioctl(struct inode *, struct file *,unsigned int, void *);
1650 + * API for Decoder (S5x532, OV7620..)
1652 +void camif_register_decoder(struct i2c_client *);
1653 +void camif_unregister_decoder(struct i2c_client*);
1658 +#define INSTANT_SKIP 0
1659 +#define INSTANT_GO 1
1661 +extern ssize_t camif_p_1fsm_start(camif_cfg_t *);
1662 +extern ssize_t camif_p_2fsm_start(camif_cfg_t *);
1663 +extern ssize_t camif_4fsm_start(camif_cfg_t *);
1664 +extern ssize_t camif_p_stop(camif_cfg_t *);
1665 +extern int camif_enter_p_4fsm(camif_cfg_t *);
1666 +extern int camif_enter_c_4fsm(camif_cfg_t *);
1667 +extern int camif_enter_2fsm(camif_cfg_t *);
1668 +extern int camif_enter_1fsm(camif_cfg_t *);
1669 +extern int camif_check_preview(camif_cfg_t *);
1670 +extern int camif_callback_start(camif_cfg_t *);
1671 +extern int camif_clock_init(camif_gc_t *);
1676 +#define VID_HARDWARE_SAMSUNG_FIMC20 236
1686 + * Local variables:
1688 + * c-indent-level: 8
1689 + * c-basic-offset: 8
1690 + * c-set-style: "K&R"
1693 diff --git a/arch/arm/mach-s3c2440/camera/camif_fsm.c b/arch/arm/mach-s3c2440/camera/camif_fsm.c
1694 new file mode 100644
1695 index 0000000..3e2b71a
1697 +++ b/arch/arm/mach-s3c2440/camera/camif_fsm.c
1700 + Copyright (C) 2004 Samsung Electronics
1701 + SW.LEE <hitchcar@sec.samsung.com>
1703 + This program is free software; you can redistribute it and/or modify
1704 + it under the terms of the GNU General Public License as published by
1705 + the Free Software Foundation; either version 2 of the License, or
1706 + (at your option) any later version.
1709 +#include <linux/version.h>
1710 +#include <linux/module.h>
1711 +#include <linux/delay.h>
1712 +#include <linux/errno.h>
1713 +#include <linux/fs.h>
1714 +#include <linux/kernel.h>
1715 +#include <linux/major.h>
1716 +#include <linux/slab.h>
1717 +#include <linux/poll.h>
1718 +#include <linux/signal.h>
1719 +#include <linux/ioport.h>
1720 +#include <linux/sched.h>
1721 +#include <linux/types.h>
1722 +#include <linux/interrupt.h>
1723 +#include <linux/kmod.h>
1724 +#include <linux/vmalloc.h>
1725 +#include <linux/init.h>
1726 +#include <linux/pagemap.h>
1727 +#include <asm/io.h>
1728 +#include <asm/irq.h>
1729 +#include <asm/semaphore.h>
1730 +#include <linux/miscdevice.h>
1735 +const char *fsm_version =
1736 + "$Id: camif_fsm.c,v 1.3 2004/04/27 10:26:28 swlee Exp $";
1740 + * FSM function is the place where Synchronization in not necessary
1741 + * because IRS calls this functions.
1744 +ssize_t camif_p_1fsm_start(camif_cfg_t *cfg)
1746 + //camif_reset(CAMIF_RESET,0);
1747 + cfg->exec = CAMIF_DMA_ON;
1748 + camif_capture_start(cfg);
1749 + camif_last_irq_en(cfg);
1750 + cfg->status = CAMIF_STARTED;
1751 + cfg->fsm = CAMIF_1nd_INT;
1756 +ssize_t camif_p_2fsm_start(camif_cfg_t *cfg)
1758 + camif_reset(CAMIF_RESET,0);/* FIFO Count goes to zero */
1759 + cfg->exec = CAMIF_DMA_ON;
1760 + camif_capture_start(cfg);
1761 + cfg->status = CAMIF_STARTED;
1762 + cfg->fsm = CAMIF_1nd_INT;
1767 +ssize_t camif_4fsm_start(camif_cfg_t *cfg)
1769 + camif_reset(CAMIF_RESET,0); /* FIFO Count goes to zero */
1770 + cfg->exec = CAMIF_DMA_ON;
1771 + camif_capture_start(cfg);
1772 + cfg->status = CAMIF_STARTED;
1773 + cfg->fsm = CAMIF_1nd_INT;
1774 + cfg->perf.frames = 0;
1780 + cfg->perf.frames set in camif_fsm.c
1781 + cfg->status set in video-driver.c
1785 + * Don't insert camif_reset(CAM_RESET, 0 ) into this func
1787 +ssize_t camif_p_stop(camif_cfg_t *cfg)
1789 + cfg->exec = CAMIF_DMA_OFF;
1790 +// cfg->status = CAMIF_STOPPED;
1791 + camif_capture_stop(cfg);
1792 + cfg->perf.frames = 0; /* Dupplicated ? */
1796 +/* When C working, P asks C to play togehter */
1797 +/* Only P must call this function */
1798 +void camif_start_c_with_p (camif_cfg_t *cfg, camif_cfg_t *other)
1800 +// cfg->gc->other = get_camif(CODEC_MINOR);
1801 + cfg->gc->other = other;
1802 + camif_start_p_with_c(cfg);
1805 +static void camif_start_p_with_c(camif_cfg_t *cfg)
1807 + camif_cfg_t *other = (camif_cfg_t *)cfg->gc->other;
1808 + /* Preview Stop */
1809 + cfg->exec = CAMIF_DMA_OFF;
1810 + camif_capture_stop(cfg);
1811 + /* Start P and C */
1812 + camif_reset(CAMIF_RESET, 0);
1813 + cfg->exec =CAMIF_BOTH_DMA_ON;
1814 + camif_capture_start(cfg);
1815 + cfg->fsm = CAMIF_1nd_INT; /* For Preview */
1816 + if(!other) panic("Unexpected Error \n");
1817 + other->fsm = CAMIF_1nd_INT; /* For Preview */
1820 +static void camif_auto_restart(camif_cfg_t *cfg)
1822 +// if (cfg->dma_type & CAMIF_CODEC) return;
1823 + if (cfg->auto_restart)
1824 + camif_start_p_with_c(cfg);
1828 +/* Supposed that PREVIEW already running
1829 + * request PREVIEW to start with Codec
1831 +static int camif_check_global(camif_cfg_t *cfg)
1835 + if (down_interruptible(&cfg->gc->lock))
1836 + return -ERESTARTSYS;
1837 + if ( cfg->gc->status & CWANT2START ) {
1838 + cfg->gc->status &= ~CWANT2START;
1839 + cfg->auto_restart = 1;
1843 + ret = 0; /* There is no codec */
1844 + cfg->auto_restart = 0; /* Duplicated ..Dummy */
1847 + up(&cfg->gc->lock);
1853 + * 1nd INT : Start Interrupt
1854 + * Xnd INT : enable Last IRQ : pingpong get the valid data
1855 + * Ynd INT : Stop Codec or Preview : pingpong get the valid data
1856 + * Znd INT : Last IRQ : valid data
1858 +#define CHECK_FREQ 5
1859 +int camif_enter_p_4fsm(camif_cfg_t *cfg)
1863 + cfg->perf.frames++;
1864 + if (cfg->fsm == CAMIF_NORMAL_INT)
1865 + if (cfg->perf.frames % CHECK_FREQ == 0)
1866 + ret = camif_check_global(cfg);
1867 + if (ret > 0) cfg->fsm = CAMIF_Xnd_INT; /* Codec wait for Preview */
1869 + switch (cfg->fsm) {
1870 + case CAMIF_1nd_INT: /* Start IRQ */
1871 + cfg->fsm = CAMIF_NORMAL_INT;
1872 + ret = INSTANT_SKIP;
1873 + DPRINTK(KERN_INFO "1nd INT \n");
1875 + case CAMIF_NORMAL_INT:
1876 + cfg->status = CAMIF_INT_HAPPEN;
1877 + cfg->fsm = CAMIF_NORMAL_INT;
1879 + DPRINTK(KERN_INFO "NORMAL INT \n");
1881 + case CAMIF_Xnd_INT:
1882 + camif_last_irq_en(cfg);/* IRQ for Enabling LAST IRQ */
1883 + cfg->status = CAMIF_INT_HAPPEN;
1884 + cfg->fsm = CAMIF_Ynd_INT;
1886 + DPRINTK(KERN_INFO "Xnd INT \n");
1888 + case CAMIF_Ynd_INT: /* Capture Stop */
1889 + cfg->exec = CAMIF_DMA_OFF;
1890 + cfg->status = CAMIF_INT_HAPPEN;
1891 + camif_capture_stop(cfg);
1892 + cfg->fsm = CAMIF_Znd_INT;
1894 + DPRINTK(KERN_INFO "Ynd INT \n");
1896 + case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
1897 + cfg->fsm = CAMIF_DUMMY_INT;
1898 + cfg->status = CAMIF_INT_HAPPEN;
1900 + camif_auto_restart(cfg); /* Automatically Restart Camera */
1901 + DPRINTK(KERN_INFO "Znd INT \n");
1903 + case CAMIF_DUMMY_INT:
1904 + cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
1905 + ret = INSTANT_SKIP;
1906 +// DPRINTK(KERN_INFO "Dummy INT \n");
1909 + printk(KERN_INFO "Unexpect INT %d \n",cfg->fsm);
1910 + ret = INSTANT_SKIP;
1918 + * NO autorestart included in this function
1920 +int camif_enter_c_4fsm(camif_cfg_t *cfg)
1924 + cfg->perf.frames++;
1926 + if ( (cfg->fsm==CAMIF_NORMAL_INT)
1927 + && (cfg->perf.frames>cfg->restart_limit-1)
1929 + cfg->fsm = CAMIF_Xnd_INT;
1931 + switch (cfg->fsm) {
1932 + case CAMIF_1nd_INT: /* Start IRQ */
1933 + cfg->fsm = CAMIF_NORMAL_INT;
1934 +// cfg->status = CAMIF_STARTED; /* need this to meet auto-restart */
1935 + ret = INSTANT_SKIP;
1936 + DPRINTK(KERN_INFO "1nd INT \n");
1938 + case CAMIF_NORMAL_INT:
1939 + cfg->status = CAMIF_INT_HAPPEN;
1940 + cfg->fsm = CAMIF_NORMAL_INT;
1942 + DPRINTK(KERN_INFO "NORMALd INT \n");
1944 + case CAMIF_Xnd_INT:
1945 + camif_last_irq_en(cfg);/* IRQ for Enabling LAST IRQ */
1946 + cfg->status = CAMIF_INT_HAPPEN;
1947 + cfg->fsm = CAMIF_Ynd_INT;
1949 + DPRINTK(KERN_INFO "Xnd INT \n");
1951 + case CAMIF_Ynd_INT: /* Capture Stop */
1952 + cfg->exec = CAMIF_DMA_OFF;
1953 + cfg->status = CAMIF_INT_HAPPEN;
1954 + camif_capture_stop(cfg);
1955 + cfg->fsm = CAMIF_Znd_INT;
1957 + DPRINTK(KERN_INFO "Ynd INT \n");
1959 + case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
1960 + cfg->fsm = CAMIF_DUMMY_INT;
1961 + cfg->status = CAMIF_INT_HAPPEN;
1963 + DPRINTK(KERN_INFO "Znd INT \n");
1965 + case CAMIF_DUMMY_INT:
1966 + cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
1967 + ret = INSTANT_SKIP;
1970 + printk(KERN_INFO "Unexpect INT %d \n",cfg->fsm);
1971 + ret = INSTANT_SKIP;
1977 +/* 4 Interrups State Machine is for two pingpong
1978 + * 1nd INT : Start Interrupt
1979 + * Xnd INT : enable Last IRQ : pingpong get the valid data
1980 + * Ynd INT : Stop Codec or Preview : pingpong get the valid data
1981 + * Znd INT : Last IRQ : valid data
1984 + * Before calling this func, you must call camif_reset
1987 +int camif_enter_2fsm(camif_cfg_t *cfg) /* Codec FSM */
1991 + cfg->perf.frames++;
1992 + switch (cfg->fsm) {
1993 + case CAMIF_1nd_INT: /* Start IRQ */
1994 + cfg->fsm = CAMIF_Xnd_INT;
1995 + ret = INSTANT_SKIP;
1996 +// printk(KERN_INFO "1nd INT \n");
1998 + case CAMIF_Xnd_INT:
1999 + camif_last_irq_en(cfg);/* IRQ for Enabling LAST IRQ */
2000 + cfg->now_frame_num = 0;
2001 + cfg->status = CAMIF_INT_HAPPEN;
2002 + cfg->fsm = CAMIF_Ynd_INT;
2004 +// printk(KERN_INFO "2nd INT \n");
2006 + case CAMIF_Ynd_INT: /* Capture Stop */
2007 + cfg->exec = CAMIF_DMA_OFF;
2008 + cfg->now_frame_num = 1;
2009 + cfg->status = CAMIF_INT_HAPPEN;
2010 + camif_capture_stop(cfg);
2011 + cfg->fsm = CAMIF_Znd_INT;
2013 +// printk(KERN_INFO "Ynd INT \n");
2015 + case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
2016 + cfg->now_frame_num = 0;
2017 +// cfg->fsm = CAMIF_DUMMY_INT;
2018 + cfg->status = CAMIF_INT_HAPPEN;
2020 +// printk(KERN_INFO "Znd INT \n");
2022 + case CAMIF_DUMMY_INT:
2023 + cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
2024 + ret = INSTANT_SKIP;
2025 + printk(KERN_INFO "Dummy INT \n");
2027 + default: /* CAMIF_PENDING_INT */
2028 + printk(KERN_INFO "Unexpect INT \n");
2029 + ret = INSTANT_SKIP;
2036 +/* 2 Interrups State Machine is for one pingpong
2037 + * 1nd INT : Stop Codec or Preview : pingpong get the valid data
2038 + * 2nd INT : Last IRQ : dummy data
2040 +int camif_enter_1fsm(camif_cfg_t *cfg) /* Codec FSM */
2044 + cfg->perf.frames++;
2045 + switch (cfg->fsm) {
2046 + case CAMIF_Ynd_INT: /* IRQ for Enabling LAST IRQ */
2047 + cfg->exec = CAMIF_DMA_OFF;
2048 + camif_capture_stop(cfg);
2049 + cfg->fsm = CAMIF_Znd_INT;
2050 + ret = INSTANT_SKIP;
2051 + // printk(KERN_INFO "Ynd INT \n");
2053 + case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
2054 + cfg->fsm = CAMIF_DUMMY_INT;
2055 + cfg->status = CAMIF_INT_HAPPEN;
2057 + // printk(KERN_INFO "Znd INT \n");
2059 + case CAMIF_DUMMY_INT:
2060 + cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
2061 + ret = INSTANT_SKIP;
2062 + printk(KERN_INFO "Dummy INT \n");
2065 + printk(KERN_INFO "Unexpect INT \n");
2066 + ret = INSTANT_SKIP;
2074 + * GLOBAL STATUS CONTROL FUNCTION
2079 +/* Supposed that PREVIEW already running
2080 + * request PREVIEW to start with Codec
2082 +int camif_callback_start(camif_cfg_t *cfg)
2086 + if (down_interruptible(&cfg->gc->lock)) {
2087 + return -ERESTARTSYS;
2089 + cfg->gc->status = CWANT2START;
2090 + cfg->gc->other = cfg;
2091 + up(&cfg->gc->lock);
2098 + * Return status of Preview Machine
2100 + 0: Preview is not working
2101 + X: Codec must follow PREVIEW start
2103 +int camif_check_preview(camif_cfg_t *cfg)
2107 + if (down_interruptible(&cfg->gc->lock)) {
2108 + ret = -ERESTARTSYS;
2111 + if (cfg->gc->user == 1) ret = 0;
2112 + // else if (cfg->gc->status & PNOTWORKING) ret = 0;
2114 + up(&cfg->gc->lock);
2122 + * Local variables:
2123 + * c-basic-offset: 8
2126 diff --git a/arch/arm/mach-s3c2440/camera/imgsensor.c b/arch/arm/mach-s3c2440/camera/imgsensor.c
2127 new file mode 100644
2128 index 0000000..44b7bee
2130 +++ b/arch/arm/mach-s3c2440/camera/imgsensor.c
2133 + * Copyright (C) 2004 Samsung Electronics
2134 + * SW.LEE <hitchcar@samsung.com>
2136 + * Copyright (C) 2000 Russell King : pcf8583.c
2138 + * This program is free software; you can redistribute it and/or modify
2139 + * it under the terms of the GNU General Public License version 2 as
2140 + * published by the Free Software Foundation.
2142 + * Driver for FIMC20 Camera Decoder
2145 +#include <linux/config.h>
2146 +#include <linux/module.h>
2147 +#include <linux/kernel.h>
2148 +#include <linux/init.h>
2149 +#include <linux/i2c.h>
2150 +#include <linux/slab.h>
2151 +#include <linux/string.h>
2152 +#include <linux/init.h>
2153 +#include <linux/delay.h>
2156 +#ifdef CONFIG_ARCH_S3C24A0A
2158 +#include <asm/arch/S3C2440.h>
2163 +#include "sensor.h"
2165 +#ifndef SAMSUNG_SXGA_CAM
2166 +#include "s5x532_rev36.h"
2171 +static const char *sensor_version =
2172 + "$Id: imgsensor.c,v 1.11 2004/06/10 12:45:40 swlee Exp $";
2175 +static struct i2c_driver s5x532_driver;
2176 +static camif_gc_t data = {
2177 + itu_fmt: CAMIF_ITU601,
2178 + order422: CAMIF_YCBYCR,
2180 +#ifndef SAMSUNG_SXGA_CAM
2183 + win_hor_ofst: 112,
2193 +#ifdef CONFIG_ARCH_S3C24A0A
2194 + reset_type:CAMIF_EX_RESET_AL, /* Active Low */
2196 + reset_type:CAMIF_EX_RESET_AH, /* Ref board has inverted signal */
2198 + reset_udelay:2000,
2201 +#define CAM_ID 0x5a
2203 +static unsigned short ignore[] = { I2C_CLIENT_END };
2204 +static unsigned short normal_addr[] = { (CAM_ID>>1), I2C_CLIENT_END };
2205 +static struct i2c_client_address_data addr_data = {
2206 + normal_i2c: normal_addr,
2207 + normal_i2c_range: ignore,
2209 + probe_range: ignore,
2211 + ignore_range: ignore,
2215 +s5x532_t s5x532_regs_mirror[S5X532_REGS];
2218 +s5x532_read(struct i2c_client *client,unsigned char subaddr)
2221 + unsigned char buf[1];
2222 + struct i2c_msg msg ={ client->addr, 0, 1, buf};
2225 + ret = i2c_transfer(client->adapter,&msg, 1) == 1 ? 0 : -EIO;
2226 + if (ret == -EIO) {
2227 + printk(" I2C write Error \n");
2231 + msg.flags = I2C_M_RD;
2232 + ret = i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
2239 +s5x532_write(struct i2c_client *client,
2240 + unsigned char subaddr, unsigned char val)
2242 + unsigned char buf[2];
2243 + struct i2c_msg msg = { client->addr, 0, 2, buf};
2248 + return i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
2251 +void inline s5x532_init(struct i2c_client *sam_client)
2255 + printk(KERN_ERR "s5x532_init \n");
2256 + for (i = 0; i < S5X532_INIT_REGS; i++) {
2257 + s5x532_write(sam_client,
2258 + s5x532_reg[i].subaddr, s5x532_reg[i].value );
2261 +#ifdef YOU_WANT_TO_CHECK_IMG_SENSOR
2262 + for (i = 0; i < S5X532_INIT_REGS;i++) {
2263 + if ( s5x532_reg[i].subaddr == PAGE_ADDRESS ) {
2264 + s5x532_write(sam_client,
2265 + s5x532_reg[i].subaddr, s5x532_reg[i].value);
2267 + printk(KERN_ERR "Page: Subaddr %02x = 0x%02x\n",
2268 + s5x532_reg[i].subaddr, s5x532_regs_mirror[i].value);
2273 + s5x532_regs_mirror[i].subaddr = s5x532_reg[i].subaddr;
2274 + s5x532_regs_mirror[i].value =
2275 + s5x532_read(sam_client,s5x532_reg[i].subaddr);
2276 + printk(KERN_ERR "Subaddr %02x = 0x%02x\n",
2277 + s5x532_reg[i].subaddr, s5x532_regs_mirror[i].value);
2285 +s5x532_attach(struct i2c_adapter *adap, int addr, unsigned short flags,int kind)
2287 + struct i2c_client *c;
2289 + c = kmalloc(sizeof(*c), GFP_KERNEL);
2290 + if (!c) return -ENOMEM;
2292 + strcpy(c->name, "S5X532");
2293 + c->id = s5x532_driver.id;
2294 + c->flags = I2C_CLIENT_ALLOW_USE;
2296 + c->adapter = adap;
2297 + c->driver = &s5x532_driver;
2301 + camif_register_decoder(c);
2302 + return i2c_attach_client(c);
2305 +static int s5x532_probe(struct i2c_adapter *adap)
2307 + return i2c_probe(adap, &addr_data, s5x532_attach);
2310 +static int s5x532_detach(struct i2c_client *client)
2312 + i2c_detach_client(client);
2313 + camif_unregister_decoder(client);
2318 +s5x532_command(struct i2c_client *client, unsigned int cmd, void *arg)
2322 + s5x532_init(client);
2323 + printk(KERN_INFO "CAMERA: S5X532 Sensor initialized\n");
2326 + MOD_INC_USE_COUNT;
2329 + MOD_DEC_USE_COUNT;
2332 + case SENSOR_BRIGHTNESS:
2337 + panic("Unexpect Sensor Command \n");
2343 +static struct i2c_driver s5x532_driver = {
2346 + flags: I2C_DF_NOTIFY,
2347 + attach_adapter: s5x532_probe,
2348 + detach_client: s5x532_detach,
2349 + command: s5x532_command
2352 +static void iic_gpio_port(void)
2354 +#ifdef CONFIG_ARCH_S3C24A0A
2356 + GPECON &= ~(0xf <<28);
2357 + GPECON |= 0xa <<28;
2361 +static __init int camif_sensor_init(void)
2364 + return i2c_add_driver(&s5x532_driver);
2368 +static __init void camif_sensor_exit(void)
2370 + i2c_del_driver(&s5x532_driver);
2373 +module_init(camif_sensor_init)
2374 +module_exit(camif_sensor_exit)
2376 +MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");
2377 +MODULE_DESCRIPTION("I2C Client Driver For Fimc2.0 MISC Driver");
2378 +MODULE_LICENSE("GPL");
2383 + * Local variables:
2384 + * c-basic-offset: 8
2387 diff --git a/arch/arm/mach-s3c2440/camera/miscdevice.h b/arch/arm/mach-s3c2440/camera/miscdevice.h
2388 new file mode 100644
2389 index 0000000..2e1cfbc
2391 +++ b/arch/arm/mach-s3c2440/camera/miscdevice.h
2394 + /*----------------------------------------------------------
2395 + * (C) 2004 Samsung Electronics
2396 + * SW.LEE < hitchcar@samsung.com>
2398 + ----------------------------------------------------------- */
2400 +#ifndef _LINUX_S3C_MISCDEVICE_H
2401 +#define _LINUX_S3C_MISCDEVICE_H
2403 +#define CODEC_MINOR 212
2404 +#define PREVIEW_MINOR 213
2411 diff --git a/arch/arm/mach-s3c2440/camera/qt-driver.c b/arch/arm/mach-s3c2440/camera/qt-driver.c
2412 new file mode 100644
2413 index 0000000..0c5dd40
2415 +++ b/arch/arm/mach-s3c2440/camera/qt-driver.c
2418 + * SW.LEE <hitchcar@samsung.com>
2420 + * This file is subject to the terms and conditions of the GNU General Public
2421 + * License 2. See the file COPYING in the main directory of this archive
2422 + * for more details.
2425 +#include <linux/version.h>
2426 +#include <linux/module.h>
2427 +#include <linux/delay.h>
2428 +#include <linux/errno.h>
2429 +#include <linux/fs.h>
2430 +#include <linux/kernel.h>
2431 +#include <linux/major.h>
2432 +#include <linux/slab.h>
2433 +#include <linux/poll.h>
2434 +#include <linux/signal.h>
2435 +#include <linux/ioport.h>
2436 +#include <linux/sched.h>
2437 +#include <linux/types.h>
2438 +#include <linux/interrupt.h>
2439 +#include <linux/kmod.h>
2440 +#include <linux/vmalloc.h>
2441 +#include <linux/init.h>
2442 +#include <asm/io.h>
2443 +#include <asm/page.h>
2444 +#include <asm/irq.h>
2445 +#include <asm/semaphore.h>
2446 +#include <linux/miscdevice.h>
2451 +#include "videodev.h"
2452 +#include "miscdevice.h"
2453 +#include "cam_reg.h"
2454 +#include "sensor.h"
2455 +#include "userapp.h"
2458 +/************************* Sharp Zarus API **************************
2459 +* refering to Camera Driver API for SL-5000D/SL-5600 revision 1.00
2461 + SW.LEE <hitchcar@sec.samsung.com>
2462 + I want to use Sharp Camera Application.
2466 +#define READ_MODE_STATUS 0x1
2467 +#define READ_MODE_IMAGE 0x0
2468 +#define CAPTURE_SPEED
2471 +typedef enum sharp_readmode
2473 + IMAGE = 0, STATUS = 1,
2474 + FASTER = 0, BETTER = 2,
2475 + XNOFLIP = 0, XFLIP = 4,
2476 + YNOFLIP = 0, YFLIP = 8,
2477 + AUTOMATICFLIP = -1
2481 +static struct sharp_param_t {
2482 + ReadMode_t readMode;
2483 + char CameraStatus[4];
2484 +} sharp_param = { STATUS, {'s','m','c','A'}};
2487 +camif_param_t qt_parm = { 640,480,240,320,16,0};
2489 +static void setReadMode(const char *b,size_t count)
2491 + int i = *(b+2) - 48 ;
2492 + if ( 4 == count ) {
2493 + i = (*(b+3) - 48) + i * 10;
2496 + // DPRINTK(" setReadMode %s conversion value %d \n",b , i);
2497 + if ( i & STATUS ) {
2498 + // DPRINTK(" STATUS MODE \n");
2499 + sharp_param.readMode = i;
2502 + // DPRINTK(" IMAGE MODE \n");
2503 + sharp_param.readMode = i;
2510 +extern ssize_t camif_p_read(struct file *, char *, size_t , loff_t *);
2512 +ssize_t z_read(struct file *f, char *buf, size_t count, loff_t *pos)
2516 + if (sharp_param.readMode & STATUS ) {
2517 + buf[0] = sharp_param.CameraStatus[0];
2518 + buf[1] = sharp_param.CameraStatus[1];
2519 + buf[2] = sharp_param.CameraStatus[2];
2520 + buf[3] = sharp_param.CameraStatus[3];
2524 + else { /* Image ReadMode */
2526 + if (( sharp_param.readMode & (BETTER|X FLIP|YFLIP)))
2527 + DPRINTK(" Not Supporting BETTER|XFLIP|YFLIP\n");
2529 + return camif_p_read(f,buf,count,pos);
2533 +static void z_config(camif_cfg_t *cfg,int x, int y)
2535 + cfg->target_x = x;
2536 + cfg->target_y = y;
2537 + cfg->fmt = CAMIF_RGB16;
2538 + if (camif_dynamic_open(cfg)) {
2539 + panic(" Eror Happens \n");
2544 +ssize_t z_write(struct file *f, const char *b, size_t c, loff_t *pos)
2550 + cfg = get_camif(MINOR(f->f_dentry->d_inode->i_rdev));
2551 +// DPRINTK(" param %s count %d \n",b, c );
2555 + setReadMode(b, c);
2557 + case 'B': /* Clear the latch flag of shutter button */
2558 + DPRINTK(" clear latch flag of camera's shutter button\n");
2559 + sharp_param.CameraStatus[0]='s';
2561 + case 'Y': /* I don't know how to set Shutter pressed */
2562 + DPRINTK(" set latch flag n");
2563 + sharp_param.CameraStatus[0]='S';
2565 + case 'S': /* Camera Image Resolution */
2566 + case 'R': /* Donot support Rotation */
2567 + DPRINTK(" param %s count %d \n",b, c );
2568 + get_options((char *)(b+2), 5, array);
2569 + if ( array[3] == 512 ) zoom = 2;
2570 + z_config(cfg, array[1] * zoom , array[2] * zoom );
2571 + camif_4fsm_start(cfg);
2574 + DPRINTK(" param %s count %d \n",b, c );
2575 + DPRINTK(" Start the camera to capture \n");
2576 + sharp_param.CameraStatus[2]='C';
2577 + camif_4fsm_start(cfg);
2580 + printk("Unexpected param %s count %d \n",b, c );
2586 diff --git a/arch/arm/mach-s3c2440/camera/qt.h b/arch/arm/mach-s3c2440/camera/qt.h
2587 new file mode 100644
2588 index 0000000..e58368a
2590 +++ b/arch/arm/mach-s3c2440/camera/qt.h
2593 + * SW.LEE <hitchcar@samsung.com>
2595 + * This file is subject to the terms and conditions of the GNU General Public
2596 + * License 2. See the file COPYING in the main directory of this archive
2597 + * for more details.
2603 +extern ssize_t z_read(struct file *f, char *buf, size_t count, loff_t *pos);
2604 +extern ssize_t z_write(struct file *f, const char *b, size_t c, loff_t *pos);
2610 diff --git a/arch/arm/mach-s3c2440/camera/s5x532.h b/arch/arm/mach-s3c2440/camera/s5x532.h
2611 new file mode 100644
2612 index 0000000..12725f4
2614 +++ b/arch/arm/mach-s3c2440/camera/s5x532.h
2617 + * 2004 (C) Samsung Electronics
2618 + * SW.LEE <hitchcar@sec.samsung.com>
2619 + * This file is subject to the terms and conditions of the GNU General Public
2620 + * License 2. See the file COPYING in the main directory of this archive
2621 + * for more details.
2625 +#ifndef _SMDK2440_S5X532_H_
2626 +#define _SMDK2440_S5X532_H_
2629 +#define CHIP_DELAY 0xFF
2631 +typedef struct samsung_t{
2632 + unsigned char subaddr;
2633 + unsigned char value;
2634 + unsigned char page;
2637 +s5x532_t s5x532_reg[] = {
2659 + {0x2b,0x10,0x3}, // momo clock inversion
2670 + {0x1b,0x77,0x2}, // 24MHz : 0x77, 12MHz : 0x22
2671 + {0x1c,0x77,0x2}, // 24MHz : 0x77, 12MHz : 0x22
2674 + {0x00,0x03,0x1}, //
2675 + {0x0a,0x08,0x1}, // 0x0-QQVGA, 0x06-CIF, 0x02-QCIF, 0x08-VGA, 0x04-QVGA, 0x0a-SXGA
2676 + {0x0c,0x00,0x1}, // Pattern selectio. 0-CIS, 1-Color bar, 2-Ramp, 3-Blue screen
2678 + // 0x21-ITU-R656(CrYCbY), 0x25-ITU-R601(CrYCbY), 0x26-ITU-R601(YCbYCr)
2679 + {0x50,0x21,0x1}, // Hblank
2680 + {0x51,0x00,0x1}, // Hblank
2681 + {0x52,0xA1,0x1}, // Hblank
2682 + {0x53,0x02,0x1}, // Hblank
2683 + {0x54,0x01,0x1}, // Vblank
2684 + {0x55,0x00,0x1}, // Vblank
2685 + {0x56,0xE1,0x1}, // Vblank
2686 + {0x57,0x01,0x1}, // Vblank
2687 + {0x58,0x21,0x1}, // Hsync
2688 + {0x59,0x00,0x1}, // Hsync
2689 + {0x5a,0xA1,0x1}, // Hsync
2690 + {0x5b,0x02,0x1}, // Hsync
2691 + {0x5c,0x03,0x1}, // Vref
2692 + {0x5d,0x00,0x1}, // Vref
2693 + {0x5e,0x05,0x1}, // Vref
2694 + {0x5f,0x00,0x1}, // Vref
2737 + {0x72,0x82,0x0}, // main clock = 24MHz:0xd2, 16M:0x82, 12M:0x54
2738 + {0x75,0x05,0x0} // absolute vertical mirror. junon
2743 +#define S5X532_INIT_REGS (sizeof(s5x532_reg)/sizeof(s5x532_reg[0]))
2744 +#define S5X532_RISC_REGS 0xEB
2745 +#define S5X532_ISP_REGS 0xFB /* S5C7323X */
2746 +#define S5X532_CIS_REGS 0x2F /* S5K437LA03 */
2749 +#define PAGE_ADDRESS 0xEC
2751 +//#define S5X532_REGS (S5X532_RISC_REGS+S5X532_ISP_REGS+S5X532_CIS_REGS)
2752 +#define S5X532_REGS (0x1000)
2759 diff --git a/arch/arm/mach-s3c2440/camera/s5x532_rev36.h b/arch/arm/mach-s3c2440/camera/s5x532_rev36.h
2760 new file mode 100644
2761 index 0000000..b662e9c
2763 +++ b/arch/arm/mach-s3c2440/camera/s5x532_rev36.h
2766 + * 2004 (C) Samsung Electronics
2767 + * SW.LEE <hitchcar@sec.samsung.com>
2768 + * This file is subject to the terms and conditions of the GNU General Public
2769 + * License 2. See the file COPYING in the main directory of this archive
2770 + * for more details.
2774 +#ifndef _SMDK2440_S5X532_H_
2775 +#define _SMDK2440_S5X532_H_
2778 +#define CHIP_DELAY 0xFF
2780 +typedef struct samsung_t{
2781 + unsigned char subaddr;
2782 + unsigned char value;
2783 + unsigned char page;
2786 +s5x532_t s5x532_reg[] = {
2788 + //=============== page0 ===============//
2856 + //=============== page1 ===============//
2901 + //=============== page2 ===============//
2910 + //=============== page3 ===============//
2915 + //=============== page4 ===============//
2936 + //=============== page5 ===============//
2944 + //=============== page7 ===============//
2951 + // 0x21-ITU-R656(CbYCrY), 0x25-ITU-R601(CbYCrY), 0x26-ITU-R601(YCrYCb)
2957 +#define S5X532_INIT_REGS (sizeof(s5x532_reg)/sizeof(s5x532_reg[0]))
2958 +#define S5X532_RISC_REGS 0xEB
2959 +#define S5X532_ISP_REGS 0xFB /* S5C7323X */
2960 +#define S5X532_CIS_REGS 0x2F /* S5K437LA03 */
2963 +#define PAGE_ADDRESS 0xEC
2965 +//#define S5X532_REGS (S5X532_RISC_REGS+S5X532_ISP_REGS+S5X532_CIS_REGS)
2966 +#define S5X532_REGS (0x1000)
2973 diff --git a/arch/arm/mach-s3c2440/camera/sensor.h b/arch/arm/mach-s3c2440/camera/sensor.h
2974 new file mode 100644
2975 index 0000000..e28d01c
2977 +++ b/arch/arm/mach-s3c2440/camera/sensor.h
2981 + * Copyright (C) 2004 Samsung Electronics
2982 + * SW.LEE <hitchcar@sec.samsung.com>
2984 + * This program is free software; you can redistribute it and/or modify
2985 + * it under the terms of the GNU General Public License version 2 as
2986 + * published by the Free Software Foundation.
2989 +#ifndef __SENSOR_CMD_H_
2990 +#define __SENSOR_CMD_H_
2994 +#define SENSOR_INIT BIT0
2995 +#define USER_ADD BIT1
2996 +#define USER_EXIT BIT2
2999 diff --git a/arch/arm/mach-s3c2440/camera/sxga.h b/arch/arm/mach-s3c2440/camera/sxga.h
3000 new file mode 100644
3001 index 0000000..b41305a
3003 +++ b/arch/arm/mach-s3c2440/camera/sxga.h
3006 + * 2004 (C) Samsung Electronics
3007 + * SW.LEE <hitchcar@sec.samsung.com>
3008 + * This file is subject to the terms and conditions of the GNU General Public
3009 + * License 2. See the file COPYING in the main directory of this archive
3010 + * for more details.
3014 +#ifndef _SAMSUNG_SXGA_H_
3015 +#define _SAMSUNG_SXGA_H_
3018 +#define CHIP_DELAY 0xFF
3020 +typedef struct samsung_t{
3021 + unsigned char subaddr;
3022 + unsigned char value;
3023 + unsigned char page;
3026 +s5x532_t s5x532_reg[] = {
3072 +// {0x72,0x50,0x0}, // Clock 16
3073 + {0x72,0x78,0x0}, // Clock 24Mhz
3074 +// {0x72,0xf0,0x0}, // Clock 48Mhz
3077 + {0x10,0x17,0x1}, // ITU-R601
3088 + {0x0b,0x06,0x1}, // 6
3089 + {0x20,0xa8,0x1}, //b0); // Highlight C Supp 040215
3090 + {0x22,0x26,0x1}, //2f); 040225
3092 + {0x24,0x08,0x1}, //00); //1F); 040226
3093 + {0x25,0x10,0x1}, //10); //34);
3094 + {0x26,0x40,0x1}, //56);
3095 + {0x27,0x80,0x1}, //8D);
3096 + {0x28,0x2c,0x1}, //E7);
3097 + {0x29,0xd6,0x1}, //7C);
3098 + {0x2A,0x0c,0x1}, //70);
3099 + {0x2B,0xFF,0x1}, //FF);
3100 + {0x2C,0x00,0x1}, //00);
3101 + {0x2D,0x5f,0x1}, //1B);
3103 + {0xB0,0x08,0x1}, //00); //1F); 040226
3104 + {0xB1,0x10,0x1}, //10); //34);50
3105 + {0xB2,0x40,0x1}, //36);
3106 + {0xB3,0x80,0x1}, //6D);
3107 + {0xB4,0x2c,0x1}, //b7);
3108 + {0xB5,0xd6,0x1}, //7C);
3109 + {0xB6,0x0c,0x1}, //70);
3110 + {0xB7,0xFF,0x1}, //FF);
3111 + {0xB8,0x00,0x1}, //00);
3112 + {0xB9,0x5f,0x1}, //1B);
3115 + {0xc2,0x01,0x1}, // shading On
3183 + {0x6e,0x16,0x3}, // 2.38
3184 + {0x6f,0x16,0x3}, // 2.38
3192 + {0x80,0x00,0x3}, //for 0.02 _ 44
3219 + {0x3f,0x09,0x04}, // VGA : old board :0x08 , new board ; 0X09
3220 + {0x18,0x00,0x04}, // sxga
3222 + {0x20,0x41,0x04}, // vga center 040215
3223 + {0x22,0xc1,0x04},// a1);
3226 + {0x2a,0xc1,0x04},// a1);
3229 + {0x3c,0x0b,0x04}, //f); // vga
3250 + {0x72,0xd3,0x04}, // 14
3251 + {0x73,0x05,0x04}, // 15
3254 + {0x76,0x1b,0x04}, // HendL
3255 + {0x77,0x0b,0x04}, // HendH
3256 + {0x78,0x01,0x04}, // 5.00
3257 + {0x79,0x80,0x04}, // 5.2a
3260 + {0x7c,0x38,0x04}, // 5.0e
3311 + {0x12,0x40,0x04}, // 040216 AE1 window ÁÙÀÓ
3314 + {0x1a,0x29,0x04}, // 040217 AWB window ÁÙÀÓ
3331 + {0x38,0x01,0x7}, //07); 040315
3332 + {0x39,0x01,0x7}, //02); //4); 040223 040315
3333 + {0x11,0xfe,0x7}, //fe); // green -2 040303
3341 + {0x23,0x07,0x7}, // for ESD
3425 + {0x20,0xd0,0x01}, //high light color reference
3429 + {0x73,0x11,0x00}, // 41
3436 + {0x48,0xA0,0x00}, //s48C0
3437 + {0x49,0xB0,0x00}, //s49B0
3438 + {0x4a,0x30,0x00}, //s4a20
3439 + {0x4b,0x70,0x00}, //s4b70
3440 + {0x4c,0xD0,0x00}, //s4cA0
3441 + {0x4d,0xB0,0x00}, //s4dB0
3442 + {0x4e,0x30,0x00}, //s4e30
3443 + {0x4f,0xF0,0x00}, //s4fF0
3444 + {0x50,0xA0,0x00}, //s50D0
3445 + {0x51,0xB0,0x00}, //s51B0
3446 + {0x52,0x25,0x00}, //s5210
3447 + {0x53,0x70,0x00}, //s5370
3448 + {0x54,0xD0,0x00}, //s5490
3449 + {0x55,0xD0,0x00}, //s55B0
3450 + {0x56,0x3A,0x00}, //s5640
3451 + {0x57,0xD0,0x00}, //s57D0
3452 + {0x58,0xA0,0x00}, //s58D0
3453 + {0x59,0xA0,0x00}, //s59B0
3454 + {0x5a,0x32,0x00}, //s5a0A
3455 + {0x5b,0x7A,0x00}, //s5b7A
3456 + {0x5c,0xB0,0x00}, //s5c90
3457 + {0x5d,0xC0,0x00}, //s5dC0
3458 + {0x5e,0x3E,0x00}, //s5e4A
3459 + {0x5f,0xfa,0x00}, //s5fD0
3493 +#define S5X532_INIT_REGS (sizeof(s5x532_reg)/sizeof(s5x532_reg[0]))
3494 +#define S5X532_RISC_REGS 0xEB
3495 +#define S5X532_ISP_REGS 0xFB /* S5C7323X */
3496 +#define S5X532_CIS_REGS 0x2F /* S5K437LA03 */
3499 +#define PAGE_ADDRESS 0xEC
3501 +//#define S5X532_REGS (S5X532_RISC_REGS+S5X532_ISP_REGS+S5X532_CIS_REGS)
3502 +#define S5X532_REGS (0x1000)
3509 diff --git a/arch/arm/mach-s3c2440/camera/userapp.h b/arch/arm/mach-s3c2440/camera/userapp.h
3510 new file mode 100644
3511 index 0000000..9203378
3513 +++ b/arch/arm/mach-s3c2440/camera/userapp.h
3516 + Character Driver API Interface
3518 + Copyright (C) 2003 Samsung Electronics (SW.LEE: hitchcar@samsung.com)
3520 + This program is free software; you can redistribute it and/or modify
3521 + it under the terms of the GNU General Public License as published by
3522 + the Free Software Foundation; either version 2 of the License, or
3523 + (at your option) any later version.
3527 +#ifndef __FIMC20_CAMIF_USR_APP_H_
3528 +#define __FIMC20_CAMIF_USR_APP_H_
3532 + * IOCTL Command for Character Driver
3535 +#define CMD_CAMERA_INIT 0x23
3536 +/* Test Application Usage */
3552 + * Local variables:
3554 + * c-indent-level: 8
3555 + * c-basic-offset: 8
3556 + * c-set-style: "K&R"
3559 diff --git a/arch/arm/mach-s3c2440/camera/v4l2_api.c b/arch/arm/mach-s3c2440/camera/v4l2_api.c
3560 new file mode 100644
3561 index 0000000..13aed36
3563 +++ b/arch/arm/mach-s3c2440/camera/v4l2_api.c
3566 + * . 2004-01-03: SW.LEE <hitchcar@sec.samsung.com>
3568 + * This file is subject to the terms and conditions of the GNU General Public
3569 + * License 2. See the file COPYING in the main directory of this archive
3570 + * for more details.
3573 +#include <linux/config.h>
3574 +#include <linux/module.h>
3575 +#include <linux/kernel.h>
3576 +#include <linux/init.h>
3577 +#include <linux/sched.h>
3578 +#include <linux/irq.h>
3579 +#include <linux/tqueue.h>
3580 +#include <linux/locks.h>
3581 +#include <linux/completion.h>
3582 +#include <linux/delay.h>
3583 +#include <linux/slab.h>
3584 +#include <linux/vmalloc.h>
3585 +#include <linux/miscdevice.h>
3586 +#include <linux/wait.h>
3588 +#include <asm/io.h>
3589 +#include <asm/semaphore.h>
3590 +#include <asm/hardware.h>
3591 +#include <asm/uaccess.h>
3593 +#include <asm/arch/cpu_s3c2440.h>
3594 +#include <asm/arch/S3C2440.h>
3597 +#include "videodev.h"
3600 + Codec_formats/Preview_format[0] must be same to initial value of
3601 + preview_init_param/codec_init_param
3604 +const struct v4l2_fmtdesc codec_formats[] = {
3607 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
3608 +// .flags = FORMAT_FLAGS_PLANAR,
3609 + .description = "4:2:2, planar, Y-Cb-Cr",
3610 + .pixelformat = V4L2_PIX_FMT_YUV422P,
3614 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
3615 +// .flags = FORMAT_FLAGS_PLANAR,
3616 + .name = "4:2:0, planar, Y-Cb-Cr",
3617 + .fourcc = V4L2_PIX_FMT_YUV420,
3623 + FIMC V4L2_PIX_FMT_RGB565 is not same to that of V4L2spec
3624 + and so we need image convert to FIMC V4l2_PIX_FMT_RGB565.
3626 +const struct v4l2_fmtdesc preview_formats[] = {
3629 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
3630 + .description = "16 bpp RGB, le",
3631 + .fourcc = V4L2_PIX_FMT_RGB565,
3632 +// .flags = FORMAT_FLAGS_PACKED,
3636 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
3637 +// .flags = FORMAT_FLAGS_PACKED,
3638 + .description = "32 bpp RGB, le",
3639 + .fourcc = V4L2_PIX_FMT_BGR32,
3643 +#define NUM_F ARRARY_SIZE(preview_formats)
3647 + * This function and v4l2 structure made for V4L2 API functions
3648 + * App <--> v4l2 <--> logical param <--> hardware
3650 +static int camif_get_v4l2(camif_cfg_t *cfg)
3657 +** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
3659 +static int pixfmt2depth(int pixfmt,int *fmtptr)
3664 + case V4L2_PIX_FMT_RGB565:
3665 + case V4L2_PIX_FMT_RGB565X:
3666 + fmt = CAMIF_RGB_16;
3669 + case V4L2_PIX_FMT_BGR24: /* Not tested */
3670 + case V4L2_PIX_FMT_RGB24:
3671 + fmt = CAMIF_RGB_24;
3674 + case V4L2_PIX_FMT_BGR32:
3675 + case V4L2_PIX_FMT_RGB32:
3676 + fmt = CAMIF_RGB_24;
3679 + case V4L2_PIX_FMT_GREY: /* Not tested */
3680 + fmt = CAMIF_OUT_YCBCR420;
3683 + case V4L2_PIX_FMT_YUYV:
3684 + case V4L2_PIX_FMT_UYVY:
3685 + case V4L2_PIX_FMT_YUV422P:
3686 + fmt = CAMIF_OUT_YCBCR422;
3689 + case V4L2_PIX_FMT_YUV420:
3690 + fmt = CAMIF_OUT_YCBCR420;
3694 + if (fmtptr) *fmtptr = fmt;
3700 +static int camif_s_v4l2(camif_cfg_t *cfg)
3702 + int num = cfg->v2.used_fmt;
3704 + if ( !(cfg->v2.status&CAMIF_V4L2_INIT)) {
3706 + int fourcc = v2.fmtdesc[num].pixelformat;
3708 + /* To define v4l2_fmtsdesc */
3709 + if (cfg->dma_type == CAMIF_CODEC)
3710 + cfg->v2->fmtdesc = codec_formats;
3712 + cfg->v2->fmtdesc = preview_formats;
3714 + /* To define v4l2_format used currently */
3715 + cfg->v2.fmt.width = cfg->target_x;
3716 + cfg->v2.fmt.height = cfg->target_y;
3717 + cfg->v2.fmt.field = V4L2_FIELD_NONE;
3718 + cfg->v2.fmt.pixelformat = fourcc;
3719 + depth = pixfmt2depth(fourcc,NULL);
3720 + cfg->v2.fmt.bytesperline= cfg->v2.fmt.width*depth >> 3;
3721 + cfg->v2.fmt.sizeimage =
3722 + cfg->v2.fmt.height * cfg->v2.fmt.bytesperline;
3724 + /* To define v4l2_input */
3725 + cfg->v2.input.index = 0;
3726 + if (cfg->dma_type == CAMIF_CODEC)
3727 + snprintf(cfg->v2.input.name, 31, "CAMIF CODEC");
3729 + snprintf(cfg->v2.input.name, 31, "CAMIF PREVIEW");
3730 + cfg->v2.input.type = V4L2_INPUT_TYPE_CAMERA;
3732 + /* Write the Status of v4l2 machine */
3733 + cfg->v2.status |= CAMIF_V4L2_INIT;
3739 +static int camif_g_fmt(camif_cfg_t *cfg, struct v4l2_format *f)
3741 + int size = sizeof(struct v4l2_pix_format);
3743 + switch (f->type) {
3744 + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3745 + memset(&f->fmt.pix,0,size);
3746 + memcpy(&f->fmt.pix,&cfg->v2.fmt,size);
3754 +/* Copy v4l2 parameter into other element of camif_cfg_t */
3755 +static int camif_s_try(camif_cfg_t *cfg, int f)
3758 + cfg->target_x = cfg->v2.fmt.width;
3759 + cfg->target_y = cfg->v2.fmt.height;
3760 + pixfmt2depth(cfg->v2.fmt.pixelformat,&fmt);
3762 + camif_dynamic_conf(cfg);
3766 +static int camif_s_fmt(camif_cfg_t *cfg, struct v4l2_format *f)
3770 + switch (f->type) {
3771 + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3773 + /* update our state informations */
3774 +// down(&fh->cap.lock);
3775 + cfg->v2.fmt = f->pix;
3776 + cfg->v2.status |= CAMIF_v4L2_DIRTY;
3777 + camif_dynamic_conf(cfg);
3778 + cfg->v2.status &= ~CAMIF_v4L2_DIRTY; /* dummy ? */
3779 +// up(&fh->cap.lock);
3789 +/* Refer ioctl of videodeX.c and bttv-driver.c */
3791 +(struct inode *inode, struct file *file,unsigned int cmd, void * arg)
3793 + camif_cfg_t *cfg = file->private_data;
3797 + case VIDIOC_QUERYCAP:
3799 + struct v4l2_capability *cap = arg;
3801 + strcpy(cap->driver,"Fimc Camera");
3802 + strlcpy(cap->card,cfg->v->name,sizeof(cap->card));
3803 + sprintf(cap->bus_info,"FIMC 2.0 AHB Bus");
3805 + cap->capabilities =
3806 + V4L2_CAP_VIDEO_CAPTURE |V4L2_CAP_READWRITE;
3809 + case VIDIOC_G_FMT:
3811 + struct v4l2_format *f = arg;
3812 + return camif_g_fmt(cfg,f);
3814 + case VIDIOC_S_FMT:
3816 + struct v4l2_format *f = arg;
3817 + return camif_s_fmt(cfg,f);
3820 + case VIDIOC_ENUM_FMT:
3822 + struct v4l2_fmtdesc *f = arg;
3823 + enum v4l2_buf_type type = f->type;
3824 + int index = f->index;
3826 + if (index >= NUM_F)
3828 + switch (f->type) {
3829 + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3831 + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3832 + case V4L2_BUF_TYPE_VBI_CAPTURE:
3836 + memset(f,0,sizeof(*f));
3837 + memcpy(f,cfg->v2.fmtdesc+index,sizeof(*f));
3840 + case VIDIOC_G_INPUT:
3843 + *i = cfg->v2.input;
3846 + case VIDIOC_S_INPUT:
3848 + int index = *((int *)arg);
3851 + cfg->v2.input.index = index;
3856 + return -ENOIOCTLCMD; /* errno.h */
3857 + } /* End of Switch */
3869 + * Local variables:
3871 + * c-indent-level: 8
3872 + * c-basic-offset: 8
3873 + * c-set-style: "K&R"
3876 diff --git a/arch/arm/mach-s3c2440/camera/video-driver.c b/arch/arm/mach-s3c2440/camera/video-driver.c
3877 new file mode 100644
3878 index 0000000..fe9130c
3880 +++ b/arch/arm/mach-s3c2440/camera/video-driver.c
3883 + Copyright (C) 2004 Samsung Electronics
3884 + SW.LEE <hitchcar@sec.samsung.com>
3885 + This program is free software; you can redistribute it and/or modify
3886 + it under the terms of the GNU General Public License as published by
3887 + the Free Software Foundation; either version 2 of the License, or
3888 + (at your option) any later version.
3891 +#include <linux/version.h>
3892 +#include <linux/module.h>
3893 +#include <linux/delay.h>
3894 +#include <linux/errno.h>
3895 +#include <linux/fs.h>
3896 +#include <linux/kernel.h>
3897 +#include <linux/major.h>
3898 +#include <linux/slab.h>
3899 +#include <linux/poll.h>
3900 +#include <linux/signal.h>
3901 +#include <linux/ioport.h>
3902 +#include <linux/sched.h>
3903 +#include <linux/types.h>
3904 +#include <linux/interrupt.h>
3905 +#include <linux/kmod.h>
3906 +#include <linux/vmalloc.h>
3907 +#include <linux/init.h>
3908 +#include <asm/io.h>
3909 +#include <asm/page.h>
3910 +#include <asm/irq.h>
3911 +#include <asm/semaphore.h>
3912 +#include <linux/miscdevice.h>
3917 +#include "videodev.h"
3918 +#include "miscdevice.h"
3919 +#include "cam_reg.h"
3920 +#include "sensor.h"
3921 +#include "userapp.h"
3927 +/* Codec and Preview */
3928 +#define CAMIF_NUM 2
3929 +static camif_cfg_t fimc[CAMIF_NUM];
3931 +static const char *driver_version =
3932 + "$Id: video-driver.c,v 1.9 2004/06/02 03:10:36 swlee Exp $";
3933 +extern const char *fimc_version;
3934 +extern const char *fsm_version;
3937 +camif_cfg_t * get_camif(int nr)
3939 + camif_cfg_t *ret = NULL;
3944 + case PREVIEW_MINOR:
3948 + panic("Unknow Minor Number \n");
3954 +static int camif_codec_start(camif_cfg_t *cfg)
3957 + ret =camif_check_preview(cfg);
3959 + case 0: /* Play alone */
3960 + DPRINTK("Start Alone \n");
3961 + camif_4fsm_start(cfg);
3962 + cfg->gc->status |= C_WORKING;
3964 + case -ERESTARTSYS: /* Busy , retry */
3965 + //DPRINTK("Error \n");
3966 + printk("Error \n");
3969 + DPRINTK("need callback \n");
3970 + ret = camif_callback_start(cfg);
3972 + printk(KERN_INFO "Busy RESTART \n");
3973 + return ret; /* Busy, retry */
3981 +ssize_t camif_write (struct file *f, const char *b, size_t c,loff_t *offset)
3985 + c = 0; /* return value */
3987 + cfg = get_camif(MINOR(f->f_dentry->d_inode->i_rdev));
3990 + if (cfg->dma_type & CAMIF_PREVIEW) {
3991 + if (cfg->gc->status & C_WORKING) {
3992 + camif_start_c_with_p(cfg,get_camif(CODEC_MINOR));
3995 + camif_4fsm_start(cfg);
3999 + c = camif_codec_start(cfg);
4000 + if(c < 0) c = 1; /* Error and neet to retry */
4005 + camif_p_stop(cfg);
4008 + panic("CAMERA:camif_write: Unexpected Param\n");
4016 +ssize_t camif_p_read(struct file *file, char *buf, size_t count, loff_t *pos)
4018 + camif_cfg_t *cfg = NULL;
4021 + cfg = get_camif(MINOR(file->f_dentry->d_inode->i_rdev));
4022 + cfg->status = CAMIF_STARTED;
4024 + if (wait_event_interruptible(cfg->waitq,cfg->status == CAMIF_INT_HAPPEN))
4025 + return -ERESTARTSYS;
4027 + cfg->status = CAMIF_STOPPED;
4028 + end = min_t(size_t, cfg->pp_totalsize /cfg->pp_num, count);
4029 + if (copy_to_user(buf, camif_g_frame(cfg), end))
4037 +camif_c_read(struct file *file, char *buf, size_t count, loff_t *pos)
4039 + camif_cfg_t *cfg = NULL;
4042 + /* cfg = file->private_data; */
4043 + cfg = get_camif(MINOR(file->f_dentry->d_inode->i_rdev));
4045 + if(file->f_flags & O_NONBLOCK) {
4046 + printk(KERN_ERR"Don't Support NON_BLOCK \n");
4050 + /* Change the below wait_event_interruptible func */
4051 + if (wait_event_interruptible(cfg->waitq,cfg->status == CAMIF_INT_HAPPEN))
4052 + return -ERESTARTSYS;
4053 + cfg->status = CAMIF_STOPPED;
4054 + end = min_t(size_t, cfg->pp_totalsize /cfg->pp_num, count);
4055 + if (copy_to_user(buf, camif_g_frame(cfg), end))
4061 +static void camif_c_irq(int irq, void *dev_id, struct pt_regs *regs)
4063 + camif_cfg_t *cfg = (camif_cfg_t *)dev_id;
4065 + camif_g_fifo_status(cfg);
4066 + camif_g_frame_num(cfg);
4067 + if(camif_enter_c_4fsm(cfg) == INSTANT_SKIP) return;
4068 + wake_up_interruptible(&cfg->waitq);
4071 +static void camif_p_irq(int irq, void *dev_id, struct pt_regs * regs)
4073 + camif_cfg_t *cfg = (camif_cfg_t *)dev_id;
4075 + camif_g_fifo_status(cfg);
4076 + camif_g_frame_num(cfg);
4077 + if(camif_enter_p_4fsm(cfg) == INSTANT_SKIP) return;
4078 + wake_up_interruptible(&cfg->waitq);
4080 + if( (cfg->perf.frames % 5) == 0)
4085 +static void camif_release_irq(camif_cfg_t *cfg)
4087 + disable_irq(cfg->irq);
4088 + free_irq(cfg->irq, cfg);
4091 +static int camif_irq_request(camif_cfg_t *cfg)
4095 + if (cfg->dma_type & CAMIF_CODEC) {
4096 + if ((ret = request_irq(cfg->irq, camif_c_irq,
4097 + SA_INTERRUPT,cfg->shortname, cfg))) {
4098 + printk("request_irq(CAM_C) failed.\n");
4101 + if (cfg->dma_type & CAMIF_PREVIEW) {
4102 + if ((ret = request_irq(cfg->irq, camif_p_irq,
4103 + SA_INTERRUPT,cfg->shortname, cfg))) {
4104 + printk("request_irq(CAM_P) failed.\n");
4110 +static void camif_init_sensor(camif_cfg_t *cfg)
4112 + camif_gc_t *gc = cfg->gc;
4114 + panic("CAMERA:I2C Client(Img Sensor)Not registered\n");
4115 + if(!gc->init_sensor) {
4116 + camif_reset(gc->reset_type, gc->reset_udelay);
4117 + gc->sensor->driver->command(gc->sensor,SENSOR_INIT,NULL);
4118 + gc->init_sensor = 1; /*sensor init done */
4120 + gc->sensor->driver->command(gc->sensor, USER_ADD, NULL);
4123 +static int camif_open(struct inode *inode, struct file *file)
4126 + camif_cfg_t * cfg = get_camif(MINOR(inode->i_rdev));
4128 + if(cfg->dma_type & CAMIF_PREVIEW) {
4129 + if(down_interruptible(&cfg->gc->lock))
4130 + return -ERESTARTSYS;
4131 + if (cfg->dma_type & CAMIF_PREVIEW) {
4132 + cfg->gc->status &= ~PNOTWORKING;
4134 + up(&cfg->gc->lock);
4136 + err = video_exclusive_open(inode,file);
4138 + cfg->status = CAMIF_STOPPED;
4139 + if (err < 0) return err;
4140 + if (file->f_flags & O_NONCAP ) {
4141 + printk("Don't Support Non-capturing open \n");
4144 + file->private_data = cfg;
4145 + camif_irq_request(cfg);
4146 + camif_init_sensor(cfg);
4151 +static void print_pregs(void)
4153 + printk(" CISRCFMT 0x%08X \n", CISRCFMT);
4154 + printk(" CIWDOFST 0x%08X \n", CIWDOFST);
4155 + printk(" CIGCTRL 0x%08X \n", CIGCTRL);
4156 + printk(" CIPRTRGFMT 0x%08X \n", CIPRTRGFMT);
4157 + printk(" CIPRCTRL 0x%08X \n", CIPRCTRL);
4158 + printk(" CIPRSCPRERATIO 0x%08X \n", CIPRSCPRERATIO);
4159 + printk(" CIPRSCPREDST 0x%08X \n", CIPRSCPREDST);
4160 + printk(" CIPRSCCTRL 0x%08X \n", CIPRSCCTRL);
4161 + printk(" CIPRTAREA 0x%08X \n", CIPRTAREA);
4162 + printk(" CIPRSTATUS 0x%08X \n", CIPRSTATUS);
4163 + printk(" CIIMGCPT 0x%08X \n", CIIMGCPT);
4166 +static void print_cregs(void)
4168 + printk(" CISRCFMT 0x%08X \n", CISRCFMT);
4169 + printk(" CIWDOFST 0x%08X \n", CIWDOFST);
4170 + printk(" CIGCTRL 0x%08X \n", CIGCTRL);
4171 + printk(" CICOCTRL 0x%8X \n", CICOCTRL);
4172 + printk(" CICOSCPRERATIO 0x%08X \n", CICOSCPRERATIO);
4173 + printk(" CICOSCPREDST 0x%08X \n", CICOSCPREDST);
4174 + printk(" CICOSCCTRL 0x%08X \n", CICOSCCTRL);
4175 + printk(" CICOTAREA 0x%08X \n", CICOTAREA);
4176 + printk(" CICOSTATUS 0x%8X \n", CICOSTATUS);
4177 + printk(" CIIMGCPT 0x%08X \n", CIIMGCPT);
4182 +static int camif_release(struct inode *inode, struct file *file)
4184 + camif_cfg_t * cfg = get_camif(MINOR(inode->i_rdev));
4186 + //DPRINTK(" cfg->status 0x%0X cfg->gc->status 0x%0X \n", cfg->status,cfg->gc->status );
4187 + if (cfg->dma_type & CAMIF_PREVIEW) {
4188 + if(down_interruptible(&cfg->gc->lock))
4189 + return -ERESTARTSYS;
4190 + cfg->gc->status &= ~PWANT2START;
4191 + cfg->gc->status |= PNOTWORKING;
4192 + up(&cfg->gc->lock);
4195 + cfg->gc->status &= ~CWANT2START; /* No need semaphore */
4197 + camif_dynamic_close(cfg);
4198 + camif_release_irq(cfg);
4199 + video_exclusive_release(inode,file);
4200 + camif_p_stop(cfg);
4201 + cfg->gc->sensor->driver->command(cfg->gc->sensor, USER_EXIT, NULL);
4203 + cfg->status = CAMIF_STOPPED;
4207 +static void fimc_config(camif_cfg_t *cfg,u32 x, u32 y, int bpp)
4209 + cfg->target_x = x;
4210 + cfg->target_y = y;
4214 + cfg->fmt = CAMIF_RGB16;
4217 + cfg->fmt = CAMIF_RGB24;
4220 + cfg->fmt = CAMIF_IN_YCBCR422|CAMIF_OUT_YCBCR420;
4223 + cfg->fmt = CAMIF_IN_YCBCR422|CAMIF_OUT_YCBCR422;
4226 + panic("Wrong BPP \n");
4232 +camif_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
4235 + camif_cfg_t *cfg = file->private_data;
4236 + camif_param_t par;
4239 + case CMD_CAMERA_INIT:
4240 + if (copy_from_user(&par,(camif_param_t *)arg,
4241 + sizeof(camif_param_t)))
4243 + fimc_config(cfg,par.dst_x, par.dst_y, par.bpp);
4244 + if (camif_dynamic_open(cfg)) {
4245 + printk(" Eror Happens \n");
4249 + switch (par.flip) {
4251 + cfg->flip = CAMIF_FLIP_MIRROR;
4254 + cfg->flip = CAMIF_FLIP_X;
4257 + cfg->flip = CAMIF_FLIP_Y;
4261 + cfg->flip = CAMIF_FLIP;
4265 + case CMD_SENSOR_BRIGHTNESS:
4266 + cfg->gc->sensor->driver->command(cfg->gc->sensor, SENSOR_BRIGHTNESS, NULL);
4279 +static int camif_ioctl(struct inode *inode, struct file *file,
4280 + unsigned int cmd, unsigned long arg)
4282 +// camif_cfg_t *cfg = file->private_data;
4286 +/* case Some_other_action */
4288 + return video_usercopy(inode, file, cmd, arg, camif_do_ioctl);
4293 +static struct file_operations camif_c_fops =
4295 + .owner = THIS_MODULE,
4296 + .open = camif_open,
4297 + .release = camif_release,
4298 + .ioctl = camif_ioctl,
4299 + .read = camif_c_read,
4300 + .write = camif_write,
4303 +static struct file_operations camif_p_fops =
4305 + .owner = THIS_MODULE,
4306 + .open = camif_open,
4307 + .release = camif_release,
4308 + .ioctl = camif_ioctl,
4313 + .read = camif_p_read,
4314 + .write = camif_write,
4318 +static struct video_device codec_template =
4320 + .name = "CODEC_IF",
4321 + .type = VID_TYPE_CAPTURE|VID_TYPE_CLIPPING|VID_TYPE_SCALES,
4322 + .hardware = VID_HARDWARE_SAMSUNG_FIMC20,
4323 + .fops = &camif_c_fops,
4324 +// .release = camif_release
4328 +static struct video_device preview_template =
4330 + .name = "PREVIEW_IF",
4331 + .type = VID_TYPE_CAPTURE|VID_TYPE_CLIPPING|VID_TYPE_SCALES,
4332 + .hardware = VID_HARDWARE_SAMSUNG_FIMC20,
4333 + .fops = &camif_p_fops,
4337 +static int preview_init(camif_cfg_t *cfg)
4339 + char name[16]="CAM_PREVIEW";
4341 + memset(cfg, 0, sizeof(camif_cfg_t));
4342 + cfg->target_x = 640;
4343 + cfg->target_y = 480;
4345 + cfg->dma_type = CAMIF_PREVIEW;
4346 + cfg->fmt = CAMIF_RGB16;
4347 + cfg->flip = CAMIF_FLIP_Y;
4348 + cfg->v = &preview_template;
4349 + init_MUTEX(&cfg->v->lock);
4350 + cfg->irq = IRQ_CAM_P;
4352 + strcpy(cfg->shortname,name);
4353 + init_waitqueue_head(&cfg->waitq);
4354 + cfg->status = CAMIF_STOPPED;
4355 + return cfg->status;
4358 +static int codec_init(camif_cfg_t *cfg)
4360 + char name[16]="CAM_CODEC";
4362 + memset(cfg, 0, sizeof(camif_cfg_t));
4363 + cfg->target_x = 176;
4364 + cfg->target_y = 144;
4366 + cfg->dma_type = CAMIF_CODEC;
4367 + cfg->fmt = CAMIF_IN_YCBCR422|CAMIF_OUT_YCBCR420;
4368 + cfg->flip = CAMIF_FLIP_X;
4369 + cfg->v = &codec_template;
4370 + init_MUTEX(&cfg->v->lock);
4371 + cfg->irq = IRQ_CAM_C;
4372 + strcpy(cfg->shortname,name);
4373 + init_waitqueue_head(&cfg->waitq);
4374 + cfg->status = CAMIF_STOPPED;
4375 + return cfg->status;
4378 +static void camif_init(void)
4380 + camif_setup_sensor();
4385 +static void print_version(void)
4387 + printk(KERN_INFO"FIMC built:"__DATE__ " "__TIME__"\n%s\n%s\n%s\n",
4388 + fimc_version, driver_version,fsm_version);
4392 +static int camif_m_in(void)
4395 + camif_cfg_t * cfg;
4398 + cfg = get_camif(CODEC_MINOR);
4401 + if (video_register_device(cfg->v,0,CODEC_MINOR)!=0) {
4402 + DPRINTK("Couldn't register codec driver.\n");
4405 + cfg = get_camif(PREVIEW_MINOR);
4406 + preview_init(cfg);
4407 + if (video_register_device(cfg->v,0,PREVIEW_MINOR)!=0) {
4408 + DPRINTK("Couldn't register preview driver.\n");
4416 +static void unconfig_device(camif_cfg_t *cfg)
4418 + video_unregister_device(cfg->v);
4419 + camif_hw_close(cfg);
4420 + //memset(cfg, 0, sizeof(camif_cfg_t));
4423 +static void camif_m_out(void) /* module out */
4427 + cfg = get_camif(CODEC_MINOR);
4428 + unconfig_device(cfg);
4429 + cfg = get_camif(PREVIEW_MINOR);
4430 + unconfig_device(cfg);
4434 +void camif_register_decoder(struct i2c_client *ptr)
4438 + cfg =get_camif(CODEC_MINOR);
4439 + cfg->gc = (camif_gc_t *)(ptr->data);
4441 + cfg =get_camif(PREVIEW_MINOR);
4442 + cfg->gc = (camif_gc_t *)(ptr->data);
4444 + sema_init(&cfg->gc->lock,1); /* global lock for both Codec and Preview */
4445 + cfg->gc->status |= PNOTWORKING; /* Default Value */
4446 + camif_hw_open(cfg->gc);
4449 +void camif_unregister_decoder(struct i2c_client *ptr)
4453 + gc = (camif_gc_t *)(ptr->data);
4454 + gc->init_sensor = 0; /* need to modify */
4457 +module_init(camif_m_in);
4458 +module_exit(camif_m_out);
4460 +EXPORT_SYMBOL(camif_register_decoder);
4461 +EXPORT_SYMBOL(camif_unregister_decoder);
4463 +MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");
4464 +MODULE_DESCRIPTION("Video-Driver For Fimc2.0 MISC Drivers");
4465 +MODULE_LICENSE("GPL");
4469 + * Local variables:
4470 + * c-basic-offset: 8
4473 diff --git a/arch/arm/mach-s3c2440/camera/videodev.c b/arch/arm/mach-s3c2440/camera/videodev.c
4474 new file mode 100644
4475 index 0000000..0b3498f
4477 +++ b/arch/arm/mach-s3c2440/camera/videodev.c
4480 + * Video capture interface for Linux Character Device Driver.
4482 + * Alan Cox, <alan@redhat.com> video4linux
4484 + * Author: SW.LEE <hitchcar@samsung.com>
4485 + * 2004 (C) Samsung Electronics
4486 + * Modified for S3C2440/S3C24A0 Interface
4488 + * This file is released under the GPLv2
4492 +#include <linux/module.h>
4493 +#include <linux/types.h>
4494 +#include <linux/kernel.h>
4495 +#include <linux/sched.h>
4496 +#include <linux/smp_lock.h>
4497 +#include <linux/mm.h>
4498 +#include <linux/string.h>
4499 +#include <linux/errno.h>
4500 +#include <linux/init.h>
4501 +#include <linux/kmod.h>
4502 +#include <linux/slab.h>
4503 +#include <linux/devfs_fs_kernel.h>
4504 +#include <linux/miscdevice.h>
4505 +#include <asm/uaccess.h>
4506 +#include <asm/system.h>
4507 +#include <asm/semaphore.h>
4512 +#include "videodev.h"
4513 +#include "miscdevice.h"
4516 +static DECLARE_MUTEX(videodev_lock);
4518 +const char *fimc_version = "$Id: videodev.c,v 1.1.1.1 2004/04/27 03:52:50 swlee Exp $";
4520 +#define VIDEO_NAME "video4linux"
4523 +static inline unsigned iminor(struct inode *inode)
4525 + return MINOR(inode->i_rdev);
4528 +static inline unsigned imajor(struct inode *inode)
4530 + return MAJOR(inode->i_rdev);
4534 +#define VIDEO_NUM_DEVICES 2
4535 +static struct video_device *video_device[VIDEO_NUM_DEVICES];
4537 +static inline struct video_device * get_vd(int nr)
4539 + if ( nr == CODEC_MINOR)
4540 + return video_device[0];
4542 + assert ( nr & PREVIEW_MINOR);
4543 + return video_device[1];
4547 +static inline void set_vd ( struct video_device * vd, int nr)
4549 + if ( nr == CODEC_MINOR)
4550 + video_device[0] = vd;
4552 + assert ( nr & PREVIEW_MINOR);
4553 + video_device[1] = vd;
4557 +static inline int video_release(struct inode *inode, struct file *f)
4559 + int minor = MINOR(inode->i_rdev);
4560 + struct video_device *vfd;
4562 + vfd = get_vd(minor);
4563 +#if 1 /* needed until all drivers are fixed */
4564 + if (!vfd->release)
4567 + vfd->release(vfd);
4571 +struct video_device* video_devdata(struct file *file)
4573 + return video_device[iminor(file->f_dentry->d_inode)];
4578 + * Open a video device.
4580 +static int video_open(struct inode *inode, struct file *file)
4582 + int minor = MINOR(inode->i_rdev);
4584 + struct video_device *vfl;
4585 + struct file_operations *old_fops;
4587 + down(&videodev_lock);
4589 + vfl = get_vd(minor);
4591 + old_fops = file->f_op;
4592 + file->f_op = fops_get(vfl->fops);
4593 + if(file->f_op->open)
4594 + err = file->f_op->open(inode,file);
4596 + fops_put(file->f_op);
4597 + file->f_op = fops_get(old_fops);
4599 + fops_put(old_fops);
4600 + up(&videodev_lock);
4605 + * open/release helper functions -- handle exclusive opens
4607 +extern int video_exclusive_open(struct inode *inode, struct file *file)
4609 + struct video_device *vfl = get_vd(MINOR(inode->i_rdev));
4622 +extern int video_exclusive_release(struct inode *inode, struct file *file)
4624 + struct video_device *vfl = get_vd(MINOR(inode->i_rdev));
4630 +video_usercopy(struct inode *inode, struct file *file,
4631 + unsigned int cmd, unsigned long arg,
4632 + int (*func)(struct inode *inode, struct file *file,
4633 + unsigned int cmd, void *arg))
4636 + void *mbuf = NULL;
4637 + void *parg = NULL;
4638 + int err = -EINVAL;
4640 + // cmd = video_fix_command(cmd);
4642 + /* Copy arguments into temp kernel buffer */
4643 + switch (_IOC_DIR(cmd)) {
4645 + parg = (void *)arg;
4649 + case (_IOC_WRITE | _IOC_READ):
4650 + if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
4653 + /* too big to allocate from stack */
4654 + mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
4661 + if (_IOC_DIR(cmd) & _IOC_WRITE)
4662 + if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd)))
4668 + err = func(inode, file, cmd, parg);
4669 + if (err == -ENOIOCTLCMD)
4674 + /* Copy results into user buffer */
4675 + switch (_IOC_DIR(cmd))
4678 + case (_IOC_WRITE | _IOC_READ):
4679 + if (copy_to_user((void *)arg, parg, _IOC_SIZE(cmd)))
4691 +static struct file_operations video_fops=
4693 + .owner = THIS_MODULE,
4694 + .llseek = no_llseek,
4695 + .open = video_open,
4696 + .release = video_release,
4699 +static struct miscdevice codec_dev = {
4700 + minor: CODEC_MINOR,
4702 + fops : &video_fops
4705 +static struct miscdevice preview_dev = {
4706 + minor: PREVIEW_MINOR,
4708 + fops : &video_fops
4713 + * video_register_device - register video4linux devices
4714 + * @vfd: video device structure we want to register
4715 + * @type: type of device to register
4716 + * @nr: minor number
4718 + * Zero is returned on success.
4724 +int video_register_device(struct video_device *vfd, int type, int nr)
4728 + /* pick a minor number */
4729 + down(&videodev_lock);
4732 + up(&videodev_lock);
4734 + switch (vfd->minor) {
4736 + ret = misc_register(&codec_dev);
4739 + "can't misc_register : codec on minor=%d\n", CODEC_MINOR);
4740 + panic(" Give me misc codec \n");
4743 + case PREVIEW_MINOR:
4744 + ret = misc_register(&preview_dev);
4747 + "can't misc_register (preview) on minor=%d\n", PREVIEW_MINOR);
4748 + panic(" Give me misc codec \n");
4753 +#if 0 /* needed until all drivers are fixed */
4754 + if (!vfd->release)
4755 + printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
4756 + "Please fix your driver for proper sysfs support, see "
4757 + "http://lwn.net/Articles/36850/\n", vfd->name);
4763 + * video_unregister_device - unregister a video4linux device
4764 + * @vfd: the device to unregister
4766 + * This unregisters the passed device and deassigns the minor
4767 + * number. Future open calls will be met with errors.
4770 +void video_unregister_device(struct video_device *vfd)
4772 + down(&videodev_lock);
4774 + if(get_vd(vfd->minor)!=vfd)
4775 + panic("videodev: bad unregister");
4777 + if (vfd->minor== CODEC_MINOR)
4778 + misc_deregister(&codec_dev);
4780 + misc_deregister(&preview_dev);
4781 + set_vd (NULL, vfd->minor);
4782 + up(&videodev_lock);
4787 + * Initialise video for linux
4790 +static int __init videodev_init(void)
4792 +// printk(KERN_INFO "FIMC2.0 Built:"__DATE__" "__TIME__"\n%s\n",fimc_version);
4796 +static void __exit videodev_exit(void)
4800 +module_init(videodev_init)
4801 +module_exit(videodev_exit)
4803 +EXPORT_SYMBOL(video_register_device);
4804 +EXPORT_SYMBOL(fimc_version);
4805 +EXPORT_SYMBOL(video_unregister_device);
4806 +EXPORT_SYMBOL(video_usercopy);
4807 +EXPORT_SYMBOL(video_exclusive_open);
4808 +EXPORT_SYMBOL(video_exclusive_release);
4811 +MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");
4812 +MODULE_DESCRIPTION("VideoDev For FIMC2.0 MISC Drivers");
4813 +MODULE_LICENSE("GPL");
4817 + * Local variables:
4818 + * c-basic-offset: 8
4821 diff --git a/arch/arm/mach-s3c2440/camera/videodev.h b/arch/arm/mach-s3c2440/camera/videodev.h
4822 new file mode 100644
4823 index 0000000..f12db43
4825 +++ b/arch/arm/mach-s3c2440/camera/videodev.h
4827 +#ifndef __LINUX_S3C_VIDEODEV_H
4828 +#define __LINUX_S3C_VIDEODEV_H
4830 +#include <linux/types.h>
4831 +#include <linux/version.h>
4832 +#include "videodev2.h"
4835 +struct video_device
4838 + // struct device *dev;
4840 + int type; /* v4l1 */
4841 + int type2; /* v4l2 */
4845 + /* device ops + callbacks */
4846 + struct file_operations *fops;
4847 + void (*release)(struct video_device *vfd);
4850 +#if 1 /* to be removed in 2.7.x */
4851 + /* obsolete -- fops->owner is used instead */
4852 + struct module *owner;
4853 + /* dev->driver_data will be used instead some day.
4854 + * Use the video_{get|set}_drvdata() helper functions,
4855 + * so the switch over will be transparent for you.
4856 + * Or use {pci|usb}_{get|set}_drvdata() directly. */
4860 + /* for videodev.c intenal usage -- please don't touch */
4861 + int users; /* video_exclusive_{open|close} ... */
4862 + struct semaphore lock; /* ... helper function uses these */
4863 + char devfs_name[64]; /* devfs */
4864 + // struct class_device class_dev; /* sysfs */
4867 +#define VIDEO_MAJOR 81
4869 +#define VFL_TYPE_GRABBER 0
4872 +extern int video_register_device(struct video_device *, int type, int nr);
4873 +extern void video_unregister_device(struct video_device *);
4874 +extern struct video_device* video_devdata(struct file*);
4878 +struct video_picture
4884 + __u16 whiteness; /* Black and white only */
4885 + __u16 depth; /* Capture depth */
4886 + __u16 palette; /* Palette in use */
4887 +#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
4888 +#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
4889 +#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
4890 +#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
4891 +#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
4892 +#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
4893 +#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
4894 +#define VIDEO_PALETTE_YUYV 8
4895 +#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
4896 +#define VIDEO_PALETTE_YUV420 10
4897 +#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
4898 +#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
4899 +#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
4900 +#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
4901 +#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
4902 +#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
4903 +#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
4904 +#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
4907 +extern int video_exclusive_open(struct inode *inode, struct file *file);
4908 +extern int video_exclusive_release(struct inode *inode, struct file *file);
4909 +extern int video_usercopy(struct inode *inode, struct file *file,
4910 + unsigned int cmd, unsigned long arg,
4911 + int (*func)(struct inode *inode, struct file *file,
4912 + unsigned int cmd, void *arg));
4917 +#define VID_TYPE_CAPTURE 1 /* Can capture */
4918 +#define VID_TYPE_CLIPPING 32 /* Can clip */
4919 +#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
4920 +#define VID_TYPE_SCALES 128 /* Scalable */
4921 +#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
4925 +#define VID_HARDWARE_SAMSUNG_FIMC 255
4933 + * Local variables:
4934 + * c-basic-offset: 8
4937 diff --git a/arch/arm/mach-s3c2440/camera/videodev2.h b/arch/arm/mach-s3c2440/camera/videodev2.h
4938 new file mode 100644
4939 index 0000000..1bfc45a
4941 +++ b/arch/arm/mach-s3c2440/camera/videodev2.h
4943 +#ifndef __LINUX_VIDEODEV2_H
4944 +#define __LINUX_VIDEODEV2_H
4946 + * Video for Linux Two
4948 + * Header file for v4l or V4L2 drivers and applications, for
4949 + * Linux kernels 2.2.x or 2.4.x.
4951 + * See http://bytesex.org/v4l/ for API specs and other
4952 + * v4l2 documentation.
4954 + * Author: Bill Dirks <bdirks@pacbell.net>
4959 +#include <linux/time.h> /* need struct timeval */
4963 + * M I S C E L L A N E O U S
4966 +/* Four-character-code (FOURCC) */
4967 +#define v4l2_fourcc(a,b,c,d)\
4968 + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
4974 + V4L2_FIELD_ANY = 0, /* driver can choose from none,
4975 + top, bottom, interlaced
4976 + depending on whatever it thinks
4977 + is approximate ... */
4978 + V4L2_FIELD_NONE = 1, /* this device has no fields ... */
4979 + V4L2_FIELD_TOP = 2, /* top field only */
4980 + V4L2_FIELD_BOTTOM = 3, /* bottom field only */
4981 + V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
4982 + V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one
4983 + buffer, top-bottom order */
4984 + V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */
4985 + V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into
4986 + separate buffers */
4988 +#define V4L2_FIELD_HAS_TOP(field) \
4989 + ((field) == V4L2_FIELD_TOP ||\
4990 + (field) == V4L2_FIELD_INTERLACED ||\
4991 + (field) == V4L2_FIELD_SEQ_TB ||\
4992 + (field) == V4L2_FIELD_SEQ_BT)
4993 +#define V4L2_FIELD_HAS_BOTTOM(field) \
4994 + ((field) == V4L2_FIELD_BOTTOM ||\
4995 + (field) == V4L2_FIELD_INTERLACED ||\
4996 + (field) == V4L2_FIELD_SEQ_TB ||\
4997 + (field) == V4L2_FIELD_SEQ_BT)
4998 +#define V4L2_FIELD_HAS_BOTH(field) \
4999 + ((field) == V4L2_FIELD_INTERLACED ||\
5000 + (field) == V4L2_FIELD_SEQ_TB ||\
5001 + (field) == V4L2_FIELD_SEQ_BT)
5003 +enum v4l2_buf_type {
5004 + V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
5005 + V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
5006 + V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
5007 + V4L2_BUF_TYPE_VBI_CAPTURE = 4,
5008 + V4L2_BUF_TYPE_VBI_OUTPUT = 5,
5009 + V4L2_BUF_TYPE_PRIVATE = 0x80,
5012 +enum v4l2_ctrl_type {
5013 + V4L2_CTRL_TYPE_INTEGER = 1,
5014 + V4L2_CTRL_TYPE_BOOLEAN = 2,
5015 + V4L2_CTRL_TYPE_MENU = 3,
5016 + V4L2_CTRL_TYPE_BUTTON = 4,
5019 +enum v4l2_tuner_type {
5020 + V4L2_TUNER_RADIO = 1,
5021 + V4L2_TUNER_ANALOG_TV = 2,
5025 + V4L2_MEMORY_MMAP = 1,
5026 + V4L2_MEMORY_USERPTR = 2,
5027 + V4L2_MEMORY_OVERLAY = 3,
5030 +/* see also http://vektor.theorem.ca/graphics/ycbcr/ */
5031 +enum v4l2_colorspace {
5032 + /* ITU-R 601 -- broadcast NTSC/PAL */
5033 + V4L2_COLORSPACE_SMPTE170M = 1,
5035 + /* 1125-Line (US) HDTV */
5036 + V4L2_COLORSPACE_SMPTE240M = 2,
5038 + /* HD and modern captures. */
5039 + V4L2_COLORSPACE_REC709 = 3,
5041 + /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
5042 + V4L2_COLORSPACE_BT878 = 4,
5044 + /* These should be useful. Assume 601 extents. */
5045 + V4L2_COLORSPACE_470_SYSTEM_M = 5,
5046 + V4L2_COLORSPACE_470_SYSTEM_BG = 6,
5048 + /* I know there will be cameras that send this. So, this is
5049 + * unspecified chromaticities and full 0-255 on each of the
5050 + * Y'CbCr components
5052 + V4L2_COLORSPACE_JPEG = 7,
5054 + /* For RGB colourspaces, this is probably a good start. */
5055 + V4L2_COLORSPACE_SRGB = 8,
5058 +enum v4l2_priority {
5059 + V4L2_PRIORITY_UNSET = 0, /* not initialized */
5060 + V4L2_PRIORITY_BACKGROUND = 1,
5061 + V4L2_PRIORITY_INTERACTIVE = 2,
5062 + V4L2_PRIORITY_RECORD = 3,
5063 + V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE,
5073 +struct v4l2_fract {
5075 + __u32 denominator;
5079 + * D R I V E R C A P A B I L I T I E S
5081 +struct v4l2_capability
5083 + __u8 driver[16]; /* i.e. "bttv" */
5084 + __u8 card[32]; /* i.e. "Hauppauge WinTV" */
5085 + __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */
5086 + __u32 version; /* should use KERNEL_VERSION() */
5087 + __u32 capabilities; /* Device capabilities */
5088 + __u32 reserved[4];
5091 +/* Values for 'capabilities' field */
5092 +#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
5093 +#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
5094 +#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
5095 +#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a VBI capture device */
5096 +#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a VBI output device */
5097 +#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
5099 +#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
5100 +#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
5101 +#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
5103 +#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
5104 +#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
5105 +#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
5108 + * V I D E O I M A G E F O R M A T
5111 +struct v4l2_pix_format
5115 + __u32 pixelformat;
5116 + enum v4l2_field field;
5117 + __u32 bytesperline; /* for padding, zero if unused */
5119 + enum v4l2_colorspace colorspace;
5120 + __u32 priv; /* private data, depends on pixelformat */
5123 +/* Pixel format FOURCC depth Description */
5124 +#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1') /* 8 RGB-3-3-2 */
5125 +#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O') /* 16 RGB-5-5-5 */
5126 +#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P') /* 16 RGB-5-6-5 */
5127 +#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16 RGB-5-5-5 BE */
5128 +#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16 RGB-5-6-5 BE */
5129 +#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3') /* 24 BGR-8-8-8 */
5130 +#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3') /* 24 RGB-8-8-8 */
5131 +#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */
5132 +#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */
5133 +#define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */
5134 +#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */
5135 +#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */
5136 +#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */
5137 +#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */
5138 +#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16 YVU422 planar */
5139 +#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16 YVU411 planar */
5140 +#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P') /* 12 YUV 4:1:1 */
5142 +/* two planes -- one Y, one Cr + Cb interleaved */
5143 +#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2') /* 12 Y/CbCr 4:2:0 */
5144 +#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1') /* 12 Y/CrCb 4:2:0 */
5146 +/* The following formats are not defined in the V4L2 specification */
5147 +#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */
5148 +#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */
5149 +#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */
5150 +#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4') /* 8 8-bit color */
5152 +/* compressed formats */
5153 +#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */
5154 +#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G') /* JFIF JPEG */
5155 +#define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d') /* 1394 */
5156 +#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G') /* MPEG */
5158 +/* Vendor-specific formats */
5159 +#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */
5162 + * F O R M A T E N U M E R A T I O N
5164 +struct v4l2_fmtdesc
5166 + __u32 index; /* Format number */
5167 + enum v4l2_buf_type type; /* buffer type */
5169 + __u8 description[32]; /* Description string */
5170 + __u32 pixelformat; /* Format fourcc */
5171 + __u32 reserved[4];
5174 +#define V4L2_FMT_FLAG_COMPRESSED 0x0001
5180 +struct v4l2_timecode
5192 +#define V4L2_TC_TYPE_24FPS 1
5193 +#define V4L2_TC_TYPE_25FPS 2
5194 +#define V4L2_TC_TYPE_30FPS 3
5195 +#define V4L2_TC_TYPE_50FPS 4
5196 +#define V4L2_TC_TYPE_60FPS 5
5199 +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */
5200 +#define V4L2_TC_FLAG_COLORFRAME 0x0002
5201 +#define V4L2_TC_USERBITS_field 0x000C
5202 +#define V4L2_TC_USERBITS_USERDEFINED 0x0000
5203 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008
5204 +/* The above is based on SMPTE timecodes */
5208 + * C O M P R E S S I O N P A R A M E T E R S
5211 +/* ### generic compression settings don't work, there is too much
5212 + * ### codec-specific stuff. Maybe reuse that for MPEG codec settings
5213 + * ### later ... */
5214 +struct v4l2_compression
5217 + __u32 keyframerate;
5219 + __u32 reserved[5];
5221 +/* what we'll need for MPEG, extracted from some postings on
5222 + the v4l list (Gert Vervoort, PlasmaJohn).
5225 + - type: elementary stream(ES), packatised elementary stream(s) (PES)
5226 + program stream(PS), transport stream(TS)
5228 + - PS packet size (DVD: 2048 bytes, VCD: 2324 bytes)
5232 + - TS system information tables (PAT, PMT, CAT, NIT and SIT)
5233 + - (MPEG-1 systems stream vs. MPEG-2 program stream (TS not supported
5234 + by MPEG-1 systems)
5237 + - type: MPEG (+Layer I,II,III), AC-3, LPCM
5239 + - sampling frequency (DVD: 48 Khz, VCD: 44.1 KHz, 32 kHz)
5240 + - Trick Modes? (ff, rew)
5242 + - Inverse Telecine
5245 + - picturesize (SIF, 1/2 D1, 2/3 D1, D1) and PAL/NTSC norm can be set
5246 + through excisting V4L2 controls
5247 + - noise reduction, parameters encoder specific?
5248 + - MPEG video version: MPEG-1, MPEG-2
5249 + - GOP (Group Of Pictures) definition:
5250 + - N: number of frames per GOP
5251 + - M: distance between reference (I,P) frames
5253 + - quantiser matrix: inter Q matrix (64 bytes) and intra Q matrix (64 bytes)
5254 + - quantiser scale: linear or logarithmic
5255 + - scanning: alternate or zigzag
5256 + - bitrate mode: CBR (constant bitrate) or VBR (variable bitrate).
5257 + - target video bitrate for CBR
5258 + - target video bitrate for VBR
5259 + - maximum video bitrate for VBR - min. quantiser value for VBR
5260 + - max. quantiser value for VBR
5261 + - adaptive quantisation value
5262 + - return the number of bytes per GOP or bitrate for bitrate monitoring
5268 +struct v4l2_jpegcompression
5272 + int APPn; /* Number of APP segment to be written,
5273 + * must be 0..15 */
5274 + int APP_len; /* Length of data in JPEG APPn segment */
5275 + char APP_data[60]; /* Data in the JPEG APPn segment. */
5277 + int COM_len; /* Length of data in JPEG COM segment */
5278 + char COM_data[60]; /* Data in JPEG COM segment */
5280 + __u32 jpeg_markers; /* Which markers should go into the JPEG
5281 + * output. Unless you exactly know what
5282 + * you do, leave them untouched.
5283 + * Inluding less markers will make the
5284 + * resulting code smaller, but there will
5285 + * be fewer aplications which can read it.
5286 + * The presence of the APP and COM marker
5287 + * is influenced by APP_len and COM_len
5288 + * ONLY, not by this property! */
5290 +#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
5291 +#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
5292 +#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
5293 +#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
5294 +#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will
5295 + * allways use APP0 */
5300 + * M E M O R Y - M A P P I N G B U F F E R S
5302 +struct v4l2_requestbuffers
5305 + enum v4l2_buf_type type;
5306 + enum v4l2_memory memory;
5307 + __u32 reserved[2];
5313 + enum v4l2_buf_type type;
5316 + enum v4l2_field field;
5317 + struct timeval timestamp;
5318 + struct v4l2_timecode timecode;
5321 + /* memory location */
5322 + enum v4l2_memory memory;
5325 + unsigned long userptr;
5329 + __u32 reserved[2];
5332 +/* Flags for 'flags' field */
5333 +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */
5334 +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */
5335 +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */
5336 +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */
5337 +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */
5338 +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */
5339 +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
5342 + * O V E R L A Y P R E V I E W
5344 +struct v4l2_framebuffer
5348 +/* FIXME: in theory we should pass something like PCI device + memory
5349 + * region + offset instead of some physical address */
5351 + struct v4l2_pix_format fmt;
5353 +/* Flags for the 'capability' field. Read only */
5354 +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001
5355 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002
5356 +#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
5357 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
5358 +/* Flags for the 'flags' field. */
5359 +#define V4L2_FBUF_FLAG_PRIMARY 0x0001
5360 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002
5361 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
5365 + struct v4l2_rect c;
5366 + struct v4l2_clip *next;
5371 + struct v4l2_rect w;
5372 + enum v4l2_field field;
5374 + struct v4l2_clip *clips;
5381 + * C A P T U R E P A R A M E T E R S
5383 +struct v4l2_captureparm
5385 + __u32 capability; /* Supported modes */
5386 + __u32 capturemode; /* Current mode */
5387 + struct v4l2_fract timeperframe; /* Time per frame in .1us units */
5388 + __u32 extendedmode; /* Driver-specific extensions */
5389 + __u32 readbuffers; /* # of buffers for read */
5390 + __u32 reserved[4];
5392 +/* Flags for 'capability' and 'capturemode' fields */
5393 +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */
5394 +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */
5396 +struct v4l2_outputparm
5398 + __u32 capability; /* Supported modes */
5399 + __u32 outputmode; /* Current mode */
5400 + struct v4l2_fract timeperframe; /* Time per frame in seconds */
5401 + __u32 extendedmode; /* Driver-specific extensions */
5402 + __u32 writebuffers; /* # of buffers for write */
5403 + __u32 reserved[4];
5407 + * I N P U T I M A G E C R O P P I N G
5410 +struct v4l2_cropcap {
5411 + enum v4l2_buf_type type;
5412 + struct v4l2_rect bounds;
5413 + struct v4l2_rect defrect;
5414 + struct v4l2_fract pixelaspect;
5418 + enum v4l2_buf_type type;
5419 + struct v4l2_rect c;
5423 + * A N A L O G V I D E O S T A N D A R D
5426 +typedef __u64 v4l2_std_id;
5428 +/* one bit for each */
5429 +#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
5430 +#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
5431 +#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
5432 +#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
5433 +#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
5434 +#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
5435 +#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
5436 +#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
5438 +#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
5439 +#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
5440 +#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
5441 +#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
5443 +#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
5444 +#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
5446 +#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
5447 +#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
5448 +#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
5449 +#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
5450 +#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
5451 +#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
5452 +#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
5455 +#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
5456 +#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
5458 +/* some common needed stuff */
5459 +#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
5460 + V4L2_STD_PAL_B1 |\
5462 +#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\
5463 + V4L2_STD_PAL_D1 |\
5465 +#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
5466 + V4L2_STD_PAL_DK |\
5469 +#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
5470 + V4L2_STD_NTSC_M_JP)
5471 +#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
5472 + V4L2_STD_SECAM_D |\
5473 + V4L2_STD_SECAM_G |\
5474 + V4L2_STD_SECAM_H |\
5475 + V4L2_STD_SECAM_K |\
5476 + V4L2_STD_SECAM_K1 |\
5479 +#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
5480 + V4L2_STD_PAL_60 |\
5482 +#define V4L2_STD_625_50 (V4L2_STD_PAL |\
5484 + V4L2_STD_PAL_Nc |\
5487 +#define V4L2_STD_UNKNOWN 0
5488 +#define V4L2_STD_ALL (V4L2_STD_525_60 |\
5491 +struct v4l2_standard
5496 + struct v4l2_fract frameperiod; /* Frames, not fields */
5498 + __u32 reserved[4];
5503 + * V I D E O I N P U T S
5507 + __u32 index; /* Which input */
5508 + __u8 name[32]; /* Label */
5509 + __u32 type; /* Type of input */
5510 + __u32 audioset; /* Associated audios (bitfield) */
5511 + __u32 tuner; /* Associated tuner */
5514 + __u32 reserved[4];
5516 +/* Values for the 'type' field */
5517 +#define V4L2_INPUT_TYPE_TUNER 1
5518 +#define V4L2_INPUT_TYPE_CAMERA 2
5520 +/* field 'status' - general */
5521 +#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */
5522 +#define V4L2_IN_ST_NO_SIGNAL 0x00000002
5523 +#define V4L2_IN_ST_NO_COLOR 0x00000004
5525 +/* field 'status' - analog */
5526 +#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */
5527 +#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */
5529 +/* field 'status' - digital */
5530 +#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */
5531 +#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */
5532 +#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */
5534 +/* field 'status' - VCR and set-top box */
5535 +#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */
5536 +#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */
5537 +#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */
5540 + * V I D E O O U T P U T S
5544 + __u32 index; /* Which output */
5545 + __u8 name[32]; /* Label */
5546 + __u32 type; /* Type of output */
5547 + __u32 audioset; /* Associated audios (bitfield) */
5548 + __u32 modulator; /* Associated modulator */
5550 + __u32 reserved[4];
5552 +/* Values for the 'type' field */
5553 +#define V4L2_OUTPUT_TYPE_MODULATOR 1
5554 +#define V4L2_OUTPUT_TYPE_ANALOG 2
5555 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
5560 +struct v4l2_control
5566 +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
5567 +struct v4l2_queryctrl
5570 + enum v4l2_ctrl_type type;
5571 + __u8 name[32]; /* Whatever */
5572 + __s32 minimum; /* Note signedness */
5575 + __s32 default_value;
5577 + __u32 reserved[2];
5580 +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
5581 +struct v4l2_querymenu
5585 + __u8 name[32]; /* Whatever */
5589 +/* Control flags */
5590 +#define V4L2_CTRL_FLAG_DISABLED 0x0001
5591 +#define V4L2_CTRL_FLAG_GRABBED 0x0002
5593 +/* Control IDs defined by V4L2 */
5594 +#define V4L2_CID_BASE 0x00980900
5595 +/* IDs reserved for driver specific controls */
5596 +#define V4L2_CID_PRIVATE_BASE 0x08000000
5598 +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0)
5599 +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1)
5600 +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2)
5601 +#define V4L2_CID_HUE (V4L2_CID_BASE+3)
5602 +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5)
5603 +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6)
5604 +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7)
5605 +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8)
5606 +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
5607 +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10)
5608 +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11)
5609 +#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12)
5610 +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13)
5611 +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14)
5612 +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15)
5613 +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16)
5614 +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */
5615 +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17)
5616 +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18)
5617 +#define V4L2_CID_GAIN (V4L2_CID_BASE+19)
5618 +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20)
5619 +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21)
5620 +#define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
5621 +#define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
5622 +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */
5631 + enum v4l2_tuner_type type;
5639 + __u32 reserved[4];
5642 +struct v4l2_modulator
5650 + __u32 reserved[4];
5653 +/* Flags for the 'capability' field */
5654 +#define V4L2_TUNER_CAP_LOW 0x0001
5655 +#define V4L2_TUNER_CAP_NORM 0x0002
5656 +#define V4L2_TUNER_CAP_STEREO 0x0010
5657 +#define V4L2_TUNER_CAP_LANG2 0x0020
5658 +#define V4L2_TUNER_CAP_SAP 0x0020
5659 +#define V4L2_TUNER_CAP_LANG1 0x0040
5661 +/* Flags for the 'rxsubchans' field */
5662 +#define V4L2_TUNER_SUB_MONO 0x0001
5663 +#define V4L2_TUNER_SUB_STEREO 0x0002
5664 +#define V4L2_TUNER_SUB_LANG2 0x0004
5665 +#define V4L2_TUNER_SUB_SAP 0x0004
5666 +#define V4L2_TUNER_SUB_LANG1 0x0008
5668 +/* Values for the 'audmode' field */
5669 +#define V4L2_TUNER_MODE_MONO 0x0000
5670 +#define V4L2_TUNER_MODE_STEREO 0x0001
5671 +#define V4L2_TUNER_MODE_LANG2 0x0002
5672 +#define V4L2_TUNER_MODE_SAP 0x0002
5673 +#define V4L2_TUNER_MODE_LANG1 0x0003
5675 +struct v4l2_frequency
5678 + enum v4l2_tuner_type type;
5680 + __u32 reserved[8];
5692 + __u32 reserved[2];
5694 +/* Flags for the 'capability' field */
5695 +#define V4L2_AUDCAP_STEREO 0x00001
5696 +#define V4L2_AUDCAP_AVL 0x00002
5698 +/* Flags for the 'mode' field */
5699 +#define V4L2_AUDMODE_AVL 0x00001
5701 +struct v4l2_audioout
5707 + __u32 reserved[2];
5711 + * D A T A S E R V I C E S ( V B I )
5713 + * Data services API by Michael Schimek
5716 +struct v4l2_vbi_format
5718 + __u32 sampling_rate; /* in 1 Hz */
5720 + __u32 samples_per_line;
5721 + __u32 sample_format; /* V4L2_PIX_FMT_* */
5724 + __u32 flags; /* V4L2_VBI_* */
5725 + __u32 reserved[2]; /* must be zero */
5729 +#define V4L2_VBI_UNSYNC (1<< 0)
5730 +#define V4L2_VBI_INTERLACED (1<< 1)
5734 + * A G G R E G A T E S T R U C T U R E S
5737 +/* Stream data format
5741 + enum v4l2_buf_type type;
5744 + struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
5745 + struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
5746 + struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
5747 + __u8 raw_data[200]; // user-defined
5752 +/* Stream type-dependent parameters
5754 +struct v4l2_streamparm
5756 + enum v4l2_buf_type type;
5759 + struct v4l2_captureparm capture;
5760 + struct v4l2_outputparm output;
5761 + __u8 raw_data[200]; /* user-defined */
5768 + * I O C T L C O D E S F O R V I D E O D E V I C E S
5771 +#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability)
5772 +#define VIDIOC_RESERVED _IO ('V', 1)
5773 +#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc)
5774 +#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format)
5775 +#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format)
5777 +#define VIDIOC_G_COMP _IOR ('V', 6, struct v4l2_compression)
5778 +#define VIDIOC_S_COMP _IOW ('V', 7, struct v4l2_compression)
5780 +#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers)
5781 +#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer)
5782 +#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer)
5783 +#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer)
5784 +#define VIDIOC_OVERLAY _IOW ('V', 14, int)
5785 +#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer)
5786 +#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer)
5787 +#define VIDIOC_STREAMON _IOW ('V', 18, int)
5788 +#define VIDIOC_STREAMOFF _IOW ('V', 19, int)
5789 +#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm)
5790 +#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm)
5791 +#define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id)
5792 +#define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id)
5793 +#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard)
5794 +#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input)
5795 +#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control)
5796 +#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control)
5797 +#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner)
5798 +#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner)
5799 +#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio)
5800 +#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio)
5801 +#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl)
5802 +#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu)
5803 +#define VIDIOC_G_INPUT _IOR ('V', 38, int)
5804 +#define VIDIOC_S_INPUT _IOWR ('V', 39, int)
5805 +#define VIDIOC_G_OUTPUT _IOR ('V', 46, int)
5806 +#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int)
5807 +#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output)
5808 +#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout)
5809 +#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout)
5810 +#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator)
5811 +#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator)
5812 +#define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency)
5813 +#define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency)
5814 +#define VIDIOC_CROPCAP _IOR ('V', 58, struct v4l2_cropcap)
5815 +#define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop)
5816 +#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop)
5817 +#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression)
5818 +#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression)
5819 +#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id)
5820 +#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format)
5821 +#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio)
5822 +#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout)
5823 +#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority)
5824 +#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority)
5826 +/* for compatibility, will go away some day */
5827 +#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
5828 +#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm)
5829 +#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control)
5830 +#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio)
5831 +#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout)
5833 +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
5839 + * V 4 L 2 D R I V E R H E L P E R A P I
5841 + * Some commonly needed functions for drivers (v4l2-common.o module)
5843 +#include <linux/fs.h>
5845 +/* Video standard functions */
5846 +extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
5847 +extern int v4l2_video_std_construct(struct v4l2_standard *vs,
5848 + int id, char *name);
5850 +/* prority handling */
5851 +struct v4l2_prio_state {
5852 + atomic_t prios[4];
5854 +int v4l2_prio_init(struct v4l2_prio_state *global);
5855 +int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
5856 + enum v4l2_priority new);
5857 +int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
5858 +int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local);
5859 +enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
5860 +int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local);
5862 +/* names for fancy debug output */
5863 +extern char *v4l2_field_names[];
5864 +extern char *v4l2_type_names[];
5865 +extern char *v4l2_ioctl_names[];
5867 +/* Compatibility layer interface -- v4l1-compat module */
5868 +typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
5869 + unsigned int cmd, void *arg);
5870 +int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
5871 + int cmd, void *arg, v4l2_kioctl driver_ioctl);
5873 +#endif /* __KERNEL__ */
5874 +#endif /* __LINUX_VIDEODEV2_H */
5877 + * Local variables:
5878 + * c-basic-offset: 8