1 From 8602650d636b32c01fd11337dffc1df310f024e6 Mon Sep 17 00:00:00 2001
2 From: SW.LEE <hitchcar@samsung.com>
3 Date: Wed, 2 Jul 2008 22:36:46 +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 | 26 +-
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(+), 26 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 c40aaca..c350511 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 @@ -99,4 +102,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 e3ca9e3..7112231 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
92 -obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o
93 -obj-$(CONFIG_CPU_S3C2440) += irq.o
94 -obj-$(CONFIG_CPU_S3C2440) += clock.o
95 -obj-$(CONFIG_S3C2440_DMA) += dma.o
96 -obj-$(CONFIG_S3C2440_C_FIQ) += fiq_c_isr.o
100 -obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
101 -obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o
102 -obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
103 -obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
104 -obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
105 -obj-$(CONFIG_MACH_HXD8) += mach-hxd8.o
106 -obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
107 diff --git a/arch/arm/mach-s3c2440/camera/Kconfig b/arch/arm/mach-s3c2440/camera/Kconfig
109 index 0000000..36f127d
111 +++ b/arch/arm/mach-s3c2440/camera/Kconfig
114 +config S3C2440_CAMERA
115 + bool "S3C24xx Camera interface"
116 + depends on ARCH_S3C2410
118 + Camera driver for S3C2440 camera unit
120 diff --git a/arch/arm/mach-s3c2440/camera/Makefile b/arch/arm/mach-s3c2440/camera/Makefile
122 index 0000000..a46d3be
124 +++ b/arch/arm/mach-s3c2440/camera/Makefile
126 +obj-$(CONFIG_S3C2440_CAMERA) += \
135 diff --git a/arch/arm/mach-s3c2440/camera/bits.h b/arch/arm/mach-s3c2440/camera/bits.h
137 index 0000000..8d83c2e
139 +++ b/arch/arm/mach-s3c2440/camera/bits.h
142 + * Copyright (C) Samsung Electroincs 2003
143 + * Author: SW.LEE <hitchcar@samsung.com>
145 + * This program is free software; you can redistribute it and/or modify
146 + * it under the terms of the GNU General Public License as published by
147 + * the Free Software Foundation; either version 2 of the License, or
148 + * (at your option) any later version.
155 +#define BIT0 0x00000001
156 +#define BIT1 0x00000002
157 +#define BIT2 0x00000004
158 +#define BIT3 0x00000008
159 +#define BIT4 0x00000010
160 +#define BIT5 0x00000020
161 +#define BIT6 0x00000040
162 +#define BIT7 0x00000080
163 +#define BIT8 0x00000100
164 +#define BIT9 0x00000200
165 +#define BIT10 0x00000400
166 +#define BIT11 0x00000800
167 +#define BIT12 0x00001000
168 +#define BIT13 0x00002000
169 +#define BIT14 0x00004000
170 +#define BIT15 0x00008000
171 +#define BIT16 0x00010000
172 +#define BIT17 0x00020000
173 +#define BIT18 0x00040000
174 +#define BIT19 0x00080000
175 +#define BIT20 0x00100000
176 +#define BIT21 0x00200000
177 +#define BIT22 0x00400000
178 +#define BIT23 0x00800000
179 +#define BIT24 0x01000000
180 +#define BIT25 0x02000000
181 +#define BIT26 0x04000000
182 +#define BIT27 0x08000000
183 +#define BIT28 0x10000000
184 +#define BIT29 0x20000000
185 +#define BIT30 0x40000000
186 +#define BIT31 0x80000000
189 diff --git a/arch/arm/mach-s3c2440/camera/cam_reg.h b/arch/arm/mach-s3c2440/camera/cam_reg.h
191 index 0000000..7247a4e
193 +++ b/arch/arm/mach-s3c2440/camera/cam_reg.h
195 + /*----------------------------------------------------------
196 + * (C) 2004 Samsung Electronics
197 + * SW.LEE < hitchcar@samsung.com>
199 + ----------------------------------------------------------- */
201 +#ifndef __FIMC20_CAMERA_H__
202 +#define __FIMC20_CAMERA_H__
205 +#ifdef CONFIG_ARCH_S3C24A0
206 +#define CAM_BASE_ADD 0x48000000
207 +#else /* S3C2440A */
208 +#define CAM_BASE_ADD 0x4F000000
214 + * P-port is used as RGB Capturing device which including scale and crop
215 + * those who want to see(preview ) the image on display needs RGB image.
217 + * C-port is used as YCbCr(4:2:0, 4:2:2) Capturing device which including the scale and crop
218 + * the prefix of C-port have the meaning of "Codec" ex. mpeg4, h263.. which requries the
219 + YCBCB format not RGB
222 +#define CISRCFMT __REG(CAM_BASE_ADD+0x00) // RW Input Source Format
223 +#define CIWDOFST __REG(CAM_BASE_ADD+0x04) // Window offset register
224 +#define CIGCTRL __REG(CAM_BASE_ADD+0x08) // Global control register
225 +#define CICOYSA0 __REG(CAM_BASE_ADD+0x18) // Y 1 st frame start address
226 +#define CICOYSA1 __REG(CAM_BASE_ADD+0x1C) // Y 2 nd frame start address
227 +#define CICOYSA2 __REG(CAM_BASE_ADD+0x20) // Y 3 rd frame start address
228 +#define CICOYSA3 __REG(CAM_BASE_ADD+0x24) // Y 4 th frame start address
229 +#define CICOCBSA0 __REG(CAM_BASE_ADD+0x28) // Cb 1 st frame start address
230 +#define CICOCBSA1 __REG(CAM_BASE_ADD+0x2C) // Cb 2 nd frame start address
231 +#define CICOCBSA2 __REG(CAM_BASE_ADD+0x30) // Cb 3 rd frame start address
232 +#define CICOCBSA3 __REG(CAM_BASE_ADD+0x34) // Cb 4 th frame start address
233 +#define CICOCRSA0 __REG(CAM_BASE_ADD+0x38) // Cr 1 st frame start address
234 +#define CICOCRSA1 __REG(CAM_BASE_ADD+0x3C) // Cr 2 nd frame start address
235 +#define CICOCRSA2 __REG(CAM_BASE_ADD+0x40) // Cr 3 rd frame start address
236 +#define CICOCRSA3 __REG(CAM_BASE_ADD+0x44) // Cr 4 th frame start address
237 +#define CICOTRGFMT __REG(CAM_BASE_ADD+0x48) // Target image format of codec
238 +#define CICOCTRL __REG(CAM_BASE_ADD+0x4C) // Codec DMA control related
239 +#define CICOSCPRERATIO __REG(CAM_BASE_ADD+0x50) // Codec pre-scaler ratio control
240 +#define CICOSCPREDST __REG(CAM_BASE_ADD+0x54) // Codec pre-scaler destination
241 +#define CICOSCCTRL __REG(CAM_BASE_ADD+0x58) // Codec main-scaler control
242 +#define CICOTAREA __REG(CAM_BASE_ADD+0x5C) // Codec pre-scaler destination
243 +#define CICOSTATUS __REG(CAM_BASE_ADD+0x64) // Codec path status
244 +#define CIPRCLRSA0 __REG(CAM_BASE_ADD+0x6C) // RGB 1 st frame start address
245 +#define CIPRCLRSA1 __REG(CAM_BASE_ADD+0x70) // RGB 2 nd frame start address
246 +#define CIPRCLRSA2 __REG(CAM_BASE_ADD+0x74) // RGB 3 rd frame start address
247 +#define CIPRCLRSA3 __REG(CAM_BASE_ADD+0x78) // RGB 4 th frame start address
248 +#define CIPRTRGFMT __REG(CAM_BASE_ADD+0x7C) // Target image format of preview
249 +#define CIPRCTRL __REG(CAM_BASE_ADD+0x80) // Preview DMA control related
250 +#define CIPRSCPRERATIO __REG(CAM_BASE_ADD+0x84) // Preview pre-scaler ratio control
251 +#define CIPRSCPREDST __REG(CAM_BASE_ADD+0x88) // Preview pre-scaler destination
252 +#define CIPRSCCTRL __REG(CAM_BASE_ADD+0x8C) // Preview main-scaler control
253 +#define CIPRTAREA __REG(CAM_BASE_ADD+0x90) // Preview pre-scaler destination
254 +#define CIPRSTATUS __REG(CAM_BASE_ADD+0x98) // Preview path status
255 +#define CIIMGCPT __REG(CAM_BASE_ADD+0xA0) // Image capture enable command
257 +#define CICOYSA(__x) __REG(CAM_BASE_ADD+0x18 + (__x)*4 )
258 +#define CICOCBSA(__x) __REG(CAM_BASE_ADD+0x28 + (__x)*4 )
259 +#define CICOCRSA(__x) __REG(CAM_BASE_ADD+0x38 + (__x)*4 )
260 +#define CIPRCLRSA(__x) __REG(CAM_BASE_ADD+0x6C + (__x)*4 )
262 +/* CISRCFMT BitField */
263 +#define SRCFMT_ITU601 BIT31
264 +#define SRCFMT_ITU656 0
265 +#define SRCFMT_UVOFFSET_128 BIT30
266 +#define fCAM_SIZE_H Fld(13, 16)
267 +#define fCAM_SIZE_V Fld(13, 0)
268 +#define SOURCE_HSIZE(x) FInsrt((x), fCAM_SIZE_H)
269 +#define SOURCE_VSIZE(x) FInsrt((x), fCAM_SIZE_V)
272 +/* Window Option Register */
273 +#define WINOFEN BIT31
274 +#define CO_FIFO_Y BIT30
275 +#define CO_FIFO_CB BIT15
276 +#define CO_FIFO_CR BIT14
277 +#define PR_FIFO_CB BIT13
278 +#define PR_FIFO_CR BIT12
279 +#define fWINHOR Fld(11, 16)
280 +#define fWINVER Fld(11, 0)
281 +#define WINHOROFST(x) FInsrt((x), fWINHOR)
282 +#define WINVEROFST(x) FInsrt((x), fWINVER)
284 +/* Global Control Register */
285 +#define GC_SWRST BIT31
286 +#define GC_CAMRST BIT30
287 +#define GC_INVPOLPCLK BIT26
288 +#define GC_INVPOLVSYNC BIT25
289 +#define GC_INVPOLHREF BIT24
291 +/*--------------------------------------------------
292 + REGISTER BIT FIELD DEFINITION TO
294 +----------------------------------------------------*/
295 +/* Codec Target Format Register */
296 +#define IN_YCBCR420 0
297 +#define IN_YCBCR422 BIT31
298 +#define OUT_YCBCR420 0
299 +#define OUT_YCBCR422 BIT30
302 +#define FLIP_NORMAL 0
303 +#define FLIP_X (BIT14)
304 +#define FLIP_Y (BIT15)
305 +#define FLIP_MIRROR (BIT14|BIT15)
308 +/** BEGIN ************************************/
309 +/* Cotents: Common in both P and C port */
310 +#define fTARGET_HSIZE Fld(13,16)
311 +#define TARGET_HSIZE(x) FInsrt((x), fTARGET_HSIZE)
312 +#define fTARGET_VSIZE Fld(13,0)
313 +#define TARGET_VSIZE(x) FInsrt((x), fTARGET_VSIZE)
314 +#define FLIP_X_MIRROR BIT14
315 +#define FLIP_Y_MIRROR BIT15
316 +#define FLIP_180_MIRROR (BIT14 | BIT15)
317 +/** END *************************************/
319 +/* Codec DMA Control Register */
320 +#define fYBURST_M Fld(5,19)
321 +#define fYBURST_R Fld(5,14)
322 +#define fCBURST_M Fld(5,9)
323 +#define fCBURST_R Fld(5,4)
324 +#define YBURST_M(x) FInsrt((x), fYBURST_M)
325 +#define CBURST_M(x) FInsrt((x), fCBURST_M)
326 +#define YBURST_R(x) FInsrt((x), fYBURST_R)
327 +#define CBURST_R(x) FInsrt((x), fCBURST_R)
328 +#define LAST_IRQ_EN BIT2 /* Common in both P and C port */
330 + * Check the done signal of capturing image for JPEG
331 + * !!! AutoClear Bit
335 +/* (Codec, Preview ) Pre-Scaler Control Register 1 */
336 +#define fSHIFT Fld(4,28)
337 +#define PRE_SHIFT(x) FInsrt((x), fSHIFT)
338 +#define fRATIO_H Fld(7,16)
339 +#define PRE_HRATIO(x) FInsrt((x), fRATIO_H)
340 +#define fRATIO_V Fld(7,0)
341 +#define PRE_VRATIO(x) FInsrt((x), fRATIO_V)
343 +/* (Codec, Preview ) Pre-Scaler Control Register 2*/
344 +#define fDST_WIDTH Fld(12,16)
345 +#define fDST_HEIGHT Fld(12,0)
346 +#define PRE_DST_WIDTH(x) FInsrt((x), fDST_WIDTH)
347 +#define PRE_DST_HEIGHT(x) FInsrt((x), fDST_HEIGHT)
350 +/* (Codec, Preview) Main-scaler control Register */
351 +#define S_METHOD BIT31 /* Sampling method only for P-port */
352 +#define SCALERSTART BIT15
353 +/* Codec scaler bypass for upper 2048x2048
354 + where ImgCptEn_CoSC and ImgCptEn_PrSC should be 0
357 +#define SCALERBYPASS BIT31
358 +#define RGB_FMT24 BIT30
362 +#define SCALE_UP_H BIT29
363 +#define SCALE_UP_V BIT28
366 +#define fMAIN_HRATIO Fld(9, 16)
367 +#define MAIN_HRATIO(x) FInsrt((x), fMAIN_HRATIO)
369 +#define SCALER_START BIT15
371 +#define fMAIN_VRATIO Fld(9, 0)
372 +#define MAIN_VRATIO(x) FInsrt((x), fMAIN_VRATIO)
374 +/* (Codec, Preview ) DMA Target AREA Register */
375 +#define fCICOTAREA Fld(26,0)
376 +#define TARGET_DMA_AREA(x) FInsrt((x), fCICOTAREA)
378 +/* Preview DMA Control Register */
379 +#define fRGBURST_M Fld(5,19)
380 +#define fRGBURST_R Fld(5,14)
381 +#define RGBURST_M(x) FInsrt((x), fRGBURST_M)
382 +#define RGBURST_R(x) FInsrt((x), fRGBURST_R)
385 +/* (Codec, Preview) Status Register */
386 +#define CO_OVERFLOW_Y BIT31
387 +#define CO_OVERFLOW_CB BIT30
388 +#define CO_OVERFLOW_CR BIT29
389 +#define PR_OVERFLOW_CB BIT31
390 +#define PR_OVERFLOW_CR BIT30
394 +#define fFRAME_CNT Fld(2,26)
395 +#define FRAME_CNT(x) FExtr((x),fFRAME_CNT)
397 +#define WIN_OFF_EN BIT25
398 +#define fFLIP_MODE Fld(2,23)
399 +#define FLIP_MODE(x) EExtr((x), fFLIP_MODE)
400 +#define CAP_STATUS_CAMIF BIT22
401 +#define CAP_STATUS_CODEC BIT21
402 +#define CAP_STATUS_PREVIEW BIT21
403 +#define VSYNC_A BIT20
404 +#define VSYNC_B BIT19
406 +/* Image Capture Enable Regiser */
407 +#define CAMIF_CAP_ON BIT31
408 +#define CAMIF_CAP_CODEC_ON BIT30
409 +#define CAMIF_CAP_PREVIEW_ON BIT29
414 +#endif /* S3C2440_CAMER_H */
415 diff --git a/arch/arm/mach-s3c2440/camera/camif.c b/arch/arm/mach-s3c2440/camera/camif.c
417 index 0000000..36d4ccc
419 +++ b/arch/arm/mach-s3c2440/camera/camif.c
422 + * Copyright (C) 2004 Samsung Electronics
423 + * SW.LEE <hitchcar@samsung.com>
425 + * This file is subject to the terms and conditions of the GNU General Public
426 + * License 2. See the file COPYING in the main directory of this archive
427 + * for more details.
430 +#include <linux/config.h>
431 +#include <linux/module.h>
432 +#include <linux/kernel.h>
433 +#include <linux/init.h>
434 +#include <linux/sched.h>
435 +#include <linux/irq.h>
436 +#include <linux/tqueue.h>
437 +#include <linux/locks.h>
438 +#include <linux/completion.h>
439 +#include <linux/delay.h>
440 +#include <linux/slab.h>
441 +#include <linux/vmalloc.h>
442 +#include <linux/miscdevice.h>
443 +#include <linux/wait.h>
444 +#include <linux/miscdevice.h>
446 +#include <asm/semaphore.h>
447 +#include <asm/hardware.h>
448 +#include <asm/uaccess.h>
450 +#ifdef CONFIG_ARCH_S3C24A0A
451 +#include <asm/arch/S3C24A0.h>
452 +#include <asm/arch/clocks.h>
454 +#include <asm/arch/S3C2440.h>
455 +#include <asm/arch/clocks.h>
458 +#include "cam_reg.h"
461 +#include "videodev.h"
462 +#include "miscdevice.h"
465 +static int camif_dma_burst(camif_cfg_t *);
466 +static int camif_scaler(camif_cfg_t *);
468 +static const char *camif_version =
469 + "$Id: camif.c,v 1.10 2004/06/04 04:24:14 swlee Exp $";
471 +/* For SXGA Image */
472 +#define RESERVE_MEM 15*1024*1024
473 +#define YUV_MEM 10*1024*1024
474 +#define RGB_MEM (RESERVE_MEM - YUV_MEM)
476 +static int camif_malloc(camif_cfg_t *cfg)
478 + unsigned int t_size;
479 + unsigned int daon = cfg->target_x *cfg->target_y;
481 + if(cfg->dma_type & CAMIF_CODEC) {
482 + if (cfg->fmt & CAMIF_OUT_YCBCR420) {
483 + t_size = daon * 3 / 2 ;
485 + else { t_size = daon * 2; /* CAMIF_OUT_YCBCR422 */ }
486 + t_size = t_size *cfg->pp_num;
488 +#ifndef SAMSUNG_SXGA_CAM
489 + cfg->pp_virt_buf = consistent_alloc(GFP_KERNEL, t_size, &cfg->pp_phys_buf);
491 + printk(KERN_INFO "Reserving High RAM Addresses \n");
492 + cfg->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVE_MEM);
493 + cfg->pp_virt_buf = ioremap_nocache(cfg->pp_phys_buf,YUV_MEM);
496 + if ( !cfg->pp_virt_buf ) {
497 + printk(KERN_ERR"CAMERA:Failed to request YCBCR MEM\n");
500 + memset(cfg->pp_virt_buf, 0, t_size);
501 + cfg->pp_totalsize = t_size;
504 + if ( cfg->dma_type & CAMIF_PREVIEW ) {
505 + if (cfg->fmt & CAMIF_RGB16)
506 + t_size = daon * 2; /* 4byte per two pixel*/
508 + assert(cfg->fmt & CAMIF_RGB24);
509 + t_size = daon * 4; /* 4byte per one pixel */
511 + t_size = t_size * cfg->pp_num;
512 +#ifndef SAMSUNG_SXGA_CAM
513 + cfg->pp_virt_buf = consistent_alloc(GFP_KERNEL, t_size, &cfg->pp_phys_buf);
515 + printk(KERN_INFO "Reserving High RAM Addresses \n");
516 + cfg->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVE_MEM ) + YUV_MEM;
517 + cfg->pp_virt_buf = ioremap_nocache(cfg->pp_phys_buf,RGB_MEM);
519 + if ( !cfg->pp_virt_buf ) {
520 + printk(KERN_ERR"CAMERA:Failed to request RGB MEM\n");
523 + memset(cfg->pp_virt_buf, 0, t_size);
524 + cfg->pp_totalsize = t_size;
528 + return 0; /* Never come. */
531 +static int camif_demalloc(camif_cfg_t *cfg)
533 +#ifndef SAMSUNG_SXGA_CAM
534 + if ( cfg->pp_virt_buf ) {
535 + consistent_free(cfg->pp_virt_buf,cfg->pp_totalsize,cfg->pp_phys_buf);
536 + cfg->pp_virt_buf = 0;
539 + iounmap(cfg->pp_virt_buf);
540 + cfg->pp_virt_buf = 0;
546 + * advise a person to use this func in ISR
547 + * index value indicates the next frame count to be used
549 +int camif_g_frame_num(camif_cfg_t *cfg)
553 + if (cfg->dma_type & CAMIF_CODEC ) {
554 + index = FRAME_CNT(CICOSTATUS);
555 + DPRINTK("CAMIF_CODEC frame %d \n", index);
558 + assert(cfg->dma_type & CAMIF_PREVIEW );
559 + index = FRAME_CNT(CIPRSTATUS);
560 + DPRINTK("CAMIF_PREVIEW frame %d 0x%08X \n", index, CIPRSTATUS);
562 + cfg->now_frame_num = (index + 2) % 4; /* When 4 PingPong */
563 + return index; /* meaningless */
566 +static int camif_pp_codec(camif_cfg_t *cfg)
568 + u32 i, c_size; /* Cb,Cr size */
570 + u32 daon = cfg->target_x * cfg->target_y;
571 + if (cfg->fmt & CAMIF_OUT_YCBCR420) {
575 + assert(cfg->fmt & CAMIF_OUT_YCBCR422);
578 + switch ( cfg->pp_num ) {
580 + for ( i =0 ; i < 4; i=i+1) {
581 + cfg->img_buf[i].virt_y = cfg->pp_virt_buf;
582 + cfg->img_buf[i].phys_y = cfg->pp_phys_buf;
583 + cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon;
584 + cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon;
585 + cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size;
586 + cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size;
587 + CICOYSA(i) = cfg->img_buf[i].phys_y;
588 + CICOCBSA(i) = cfg->img_buf[i].phys_cb;
589 + CICOCRSA(i) = cfg->img_buf[i].phys_cr;
593 +#define TRY (( i%2 ) ? 1 :0)
594 + one_p_size = daon + 2*c_size;
595 + for (i = 0; i < 4 ; i++) {
596 + cfg->img_buf[i].virt_y = cfg->pp_virt_buf + TRY * one_p_size;
597 + cfg->img_buf[i].phys_y = cfg->pp_phys_buf + TRY * one_p_size;
598 + cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon + TRY * one_p_size;
599 + cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon + TRY * one_p_size;
600 + cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size + TRY * one_p_size;
601 + cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size + TRY * one_p_size;
602 + CICOYSA(i) = cfg->img_buf[i].phys_y;
603 + CICOCBSA(i) = cfg->img_buf[i].phys_cb;
604 + CICOCRSA(i) = cfg->img_buf[i].phys_cr;
608 + one_p_size = daon + 2*c_size;
609 + for (i = 0; i < 4 ; i++) {
610 + cfg->img_buf[i].virt_y = cfg->pp_virt_buf + i * one_p_size;
611 + cfg->img_buf[i].phys_y = cfg->pp_phys_buf + i * one_p_size;
612 + cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon + i * one_p_size;
613 + cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon + i * one_p_size;
614 + cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size + i * one_p_size;
615 + cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size + i * one_p_size;
616 + CICOYSA(i) = cfg->img_buf[i].phys_y;
617 + CICOCBSA(i) = cfg->img_buf[i].phys_cb;
618 + CICOCRSA(i) = cfg->img_buf[i].phys_cr;
622 + printk("Invalid PingPong Number %d \n",cfg->pp_num);
628 +/* RGB Buffer Allocation */
629 +static int camif_pp_preview(camif_cfg_t *cfg)
632 + u32 daon = cfg->target_x * cfg->target_y;
634 + if(cfg->fmt & CAMIF_RGB24)
637 + assert (cfg->fmt & CAMIF_RGB16);
640 + switch ( cfg->pp_num ) {
642 + for ( i = 0; i < 4 ; i++ ) {
643 + cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf ;
644 + cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf ;
645 + CIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;
649 + for ( i = 0; i < 4 ; i++) {
650 + cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + TRY * daon;
651 + cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + TRY * daon;
652 + CIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;
656 + for ( i = 0; i < 4 ; i++) {
657 + cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + i * daon;
658 + cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + i * daon;
659 + CIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;
663 + printk("Invalid PingPong Number %d \n",cfg->pp_num);
669 +static int camif_pingpong(camif_cfg_t *cfg)
671 + if (cfg->dma_type & CAMIF_CODEC ) {
672 + camif_pp_codec(cfg);
675 + if ( cfg->dma_type & CAMIF_PREVIEW) {
676 + camif_pp_preview(cfg);
682 +/*********** Image Convert *******************************/
684 + * Supported by Hardware
685 + * V4L2_PIX_FMT_YUV420,
686 + * V4L2_PIX_FMT_YUV422P,
687 + * V4L2_PIX_FMT_BGR32 (BGR4)
688 + * -----------------------------------
689 + * V4L2_PIX_FMT_RGB565(X)
690 + * Currenly 2byte --> BGR656 Format
691 + * S3C2440A,S3C24A0 supports vairants with reversed FMT_RGB565
692 + i.e blue toward the least, red towards the most significant bit
698 + * After calling camif_g_frame_num,
699 + * this func must be called
701 +u8 * camif_g_frame(camif_cfg_t *cfg)
704 + int cnt = cfg->now_frame_num;
706 + if(cfg->dma_type & CAMIF_PREVIEW) {
707 + ret = cfg->img_buf[cnt].virt_rgb;
709 + if (cfg->dma_type & CAMIF_CODEC) {
710 + ret = cfg->img_buf[cnt].virt_y;
715 +/* This function must be called in module initial time */
716 +static int camif_source_fmt(camif_gc_t *gc)
720 + /* Configure CISRCFMT --Source Format */
721 + if (gc->itu_fmt & CAMIF_ITU601) {
722 + cmd = CAMIF_ITU601;
725 + assert ( gc->itu_fmt & CAMIF_ITU656);
726 + cmd = CAMIF_ITU656;
728 + cmd |= SOURCE_HSIZE(gc->source_x)| SOURCE_VSIZE(gc->source_y);
730 + cmd |= gc->order422;
738 + * Codec Input YCBCR422 will be Fixed
740 +static int camif_target_fmt(camif_cfg_t *cfg)
744 + if (cfg->dma_type & CAMIF_CODEC) {
745 + /* YCBCR setting */
746 + cmd = TARGET_HSIZE(cfg->target_x)| TARGET_VSIZE(cfg->target_y);
747 + if ( cfg->fmt & CAMIF_OUT_YCBCR420 ) {
748 + cmd |= OUT_YCBCR420|IN_YCBCR422;
751 + assert(cfg->fmt & CAMIF_OUT_YCBCR422);
752 + cmd |= OUT_YCBCR422|IN_YCBCR422;
754 + CICOTRGFMT = cmd | cfg->flip;
757 + assert(cfg->dma_type & CAMIF_PREVIEW);
759 + TARGET_HSIZE(cfg->target_x)|TARGET_VSIZE(cfg->target_y)|cfg->flip;
764 +void camif_change_flip(camif_cfg_t *cfg)
768 + if (cfg->dma_type & CAMIF_CODEC ) {
769 + /* YCBCR setting */
771 + cmd &= ~(BIT14|BIT15); /* Clear FLIP Mode */
777 + cmd &= ~(BIT14|BIT15);
786 + * Before calling this function,
787 + * you must use "camif_dynamic_open"
788 + * If you want to enable both CODEC and preview
789 + * you must do it at the same time.
791 +int camif_capture_start(camif_cfg_t *cfg)
793 + u32 n_cmd = 0; /* Next Command */
795 + switch(cfg->exec) {
796 + case CAMIF_BOTH_DMA_ON:
797 + camif_reset(CAMIF_RESET,0); /* Flush Camera Core Buffer */
798 + CIPRSCCTRL |= SCALERSTART;
799 + CICOSCCTRL |= SCALERSTART;
800 + n_cmd = CAMIF_CAP_PREVIEW_ON|CAMIF_CAP_CODEC_ON;
803 + camif_reset(CAMIF_RESET,0); /* Flush Camera Core Buffer */
804 + if (cfg->dma_type&CAMIF_CODEC) {
805 + CICOSCCTRL |= SCALERSTART;
806 + n_cmd = CAMIF_CAP_CODEC_ON;
808 + CIPRSCCTRL |= SCALERSTART;
809 + n_cmd = CAMIF_CAP_PREVIEW_ON;
812 + /* wait until Sync Time expires */
813 + /* First settting, to wait VSYNC fall */
814 + /* By VESA spec,in 640x480 @60Hz
815 + MAX Delay Time is around 64us which "while" has.*/
816 + while(VSYNC & CICOSTATUS);
821 + CIIMGCPT = n_cmd|CAMIF_CAP_ON;
826 +int camif_capture_stop(camif_cfg_t *cfg)
828 + u32 n_cmd = CIIMGCPT; /* Next Command */
830 + switch(cfg->exec) {
831 + case CAMIF_BOTH_DMA_OFF:
832 + CIPRSCCTRL &= ~SCALERSTART;
833 + CICOSCCTRL &= ~SCALERSTART;
836 + case CAMIF_DMA_OFF_L_IRQ: /* fall thru */
837 + case CAMIF_DMA_OFF:
838 + if (cfg->dma_type&CAMIF_CODEC) {
839 + CICOSCCTRL &= ~SCALERSTART;
840 + n_cmd &= ~CAMIF_CAP_CODEC_ON;
841 + if (!(n_cmd & CAMIF_CAP_PREVIEW_ON))
844 + CIPRSCCTRL &= ~SCALERSTART;
845 + n_cmd &= ~CAMIF_CAP_PREVIEW_ON;
846 + if (!(n_cmd & CAMIF_CAP_CODEC_ON))
851 + panic("Unexpected \n");
854 + if(cfg->exec == CAMIF_DMA_OFF_L_IRQ) { /* Last IRQ */
855 + if (cfg->dma_type & CAMIF_CODEC)
856 + CICOCTRL |= LAST_IRQ_EN;
858 + CIPRCTRL |= LAST_IRQ_EN;
861 + else { /* to make internal state machine of CAMERA stop */
862 + camif_reset(CAMIF_RESET, 0);
869 +/* LastIRQEn is autoclear */
870 +void camif_last_irq_en(camif_cfg_t *cfg)
872 + if(cfg->exec == CAMIF_BOTH_DMA_ON) {
873 + CIPRCTRL |= LAST_IRQ_EN;
874 + CICOCTRL |= LAST_IRQ_EN;
877 + if (cfg->dma_type & CAMIF_CODEC)
878 + CICOCTRL |= LAST_IRQ_EN;
880 + CIPRCTRL |= LAST_IRQ_EN;
885 +camif_scaler_internal(u32 srcWidth, u32 dstWidth, u32 *ratio, u32 *shift)
887 + if(srcWidth>=64*dstWidth){
888 + printk(KERN_ERR"CAMERA:out of prescaler range: srcWidth /dstWidth = %d(< 64)\n",
889 + srcWidth/dstWidth);
892 + else if(srcWidth>=32*dstWidth){
896 + else if(srcWidth>=16*dstWidth){
900 + else if(srcWidth>=8*dstWidth){
904 + else if(srcWidth>=4*dstWidth){
908 + else if(srcWidth>=2*dstWidth){
920 +int camif_g_fifo_status(camif_cfg_t *cfg)
924 + if (cfg->dma_type & CAMIF_CODEC) {
925 + u32 flag = CO_OVERFLOW_Y|CO_OVERFLOW_CB|CO_OVERFLOW_CR;
928 + printk("CODEC: FIFO error(0x%08x) and corrected\n",reg);
929 + /* FIFO Error Count ++ */
930 + CIWDOFST |= CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR;
931 + CIWDOFST &= ~(CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR);
932 + return 1; /* Error */
935 + if (cfg->dma_type & CAMIF_PREVIEW) {
936 + u32 flag = PR_OVERFLOW_CB|PR_OVERFLOW_CR;
939 + printk("PREVIEW:FIFO error(0x%08x) and corrected\n",reg);
940 + CIWDOFST |= PR_FIFO_CB|PR_FIFO_CR;
941 + CIWDOFST &= ~(CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR);
942 + /* FIFO Error Count ++ */
943 + return 1; /* Error */
946 + return 0; /* No Error */
951 + * if codec or preview define the win offset,
952 + * other must follow that value.
954 +int camif_win_offset(camif_gc_t *gc )
956 + u32 h = gc->win_hor_ofst;
957 + u32 v = gc->win_ver_ofst;
959 + /*Clear Overflow */
960 + CIWDOFST = CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR|PR_FIFO_CB|PR_FIFO_CB;
961 + CIWDOFST = 0; /* ? Dummy */
966 + CIWDOFST = WINOFEN | WINHOROFST(h) | WINVEROFST(v);
971 + * when you change the resolution in a specific camera,
972 + * sometimes, it is necessary to change the polarity
975 +static void camif_polarity(camif_gc_t *gc)
979 + cmd = cmd & ~(BIT26|BIT25|BIT24); /* clear polarity */
980 + if (gc->polarity_pclk)
981 + cmd |= GC_INVPOLPCLK;
982 + if (gc->polarity_vsync)
983 + cmd |= GC_INVPOLVSYNC;
984 + if (gc->polarity_href)
985 + cmd |= GC_INVPOLHREF;
990 +int camif_dynamic_open(camif_cfg_t *cfg)
992 + camif_win_offset(cfg->gc);
993 + camif_polarity(cfg->gc);
995 + if(camif_scaler(cfg)) {
996 + printk(KERN_ERR "CAMERA:Preview Scaler, Change WinHorOfset or Target Size\n");
999 + camif_target_fmt(cfg);
1000 + if (camif_dma_burst(cfg)) {
1001 + printk(KERN_ERR "CAMERA:DMA Busrt Length Error \n");
1004 + if(camif_malloc(cfg) ) {
1005 + printk(KERN_ERR " Instead of using consistent_alloc()\n"
1006 + " lease use dedicated memory allocation for DMA memory\n");
1009 + camif_pingpong(cfg);
1013 +int camif_dynamic_close(camif_cfg_t *cfg)
1015 + camif_demalloc(cfg);
1019 +static int camif_target_area(camif_cfg_t *cfg)
1021 + u32 rect = cfg->target_x * cfg->target_y;
1022 + if (cfg->dma_type & CAMIF_CODEC ) {
1025 + if (cfg->dma_type & CAMIF_PREVIEW) {
1031 +static int inline camif_hw_reg(camif_cfg_t *cfg)
1035 + if (cfg->dma_type & CAMIF_CODEC) {
1036 + CICOSCPRERATIO = PRE_SHIFT(cfg->sc.shfactor)
1037 + |PRE_HRATIO(cfg->sc.prehratio)|PRE_VRATIO(cfg->sc.prevratio);
1039 + PRE_DST_WIDTH(cfg->sc.predst_x)|PRE_DST_HEIGHT(cfg->sc.predst_y);
1041 + /* Differ from Preview */
1042 + if (cfg->sc.scalerbypass)
1043 + cmd |= SCALERBYPASS;
1044 + if (cfg->sc.scaleup_h & cfg->sc.scaleup_v)
1045 + cmd |= BIT30|BIT29;
1046 + CICOSCCTRL = cmd | MAIN_HRATIO(cfg->sc.mainhratio)
1047 + |MAIN_VRATIO(cfg->sc.mainvratio);
1050 + else if (cfg->dma_type & CAMIF_PREVIEW) {
1051 + CIPRSCPRERATIO = PRE_SHIFT(cfg->sc.shfactor)
1052 + |PRE_HRATIO(cfg->sc.prehratio)|PRE_VRATIO(cfg->sc.prevratio);
1054 + PRE_DST_WIDTH(cfg->sc.predst_x)|PRE_DST_HEIGHT(cfg->sc.predst_y);
1055 + /* Differ from Codec */
1056 + if (cfg->fmt & CAMIF_RGB24) {
1062 + if (cfg->sc.scaleup_h & cfg->sc.scaleup_v)
1063 + cmd |= BIT29|BIT28;
1064 + CIPRSCCTRL = cmd |MAIN_HRATIO(cfg->sc.mainhratio)|S_METHOD
1065 + |MAIN_VRATIO(cfg->sc.mainvratio);
1067 + panic("CAMERA:DMA_TYPE Wrong \n");
1074 +/* Configure Pre-scaler control & main scaler control register */
1075 +static int camif_scaler(camif_cfg_t *cfg)
1077 + int tx = cfg->target_x,ty=cfg->target_y;
1080 + if (tx <= 0 || ty<= 0) panic("CAMERA: Invalid target size \n");
1082 + sx = cfg->gc->source_x - 2*cfg->gc->win_hor_ofst;
1083 + sy = cfg->gc->source_y - 2*cfg->gc->win_ver_ofst;
1084 + if (sx <= 0 || sy<= 0) panic("CAMERA: Invalid source size \n");
1085 + cfg->sc.modified_src_x = sx;
1086 + cfg->sc.modified_src_y = sy;
1088 + /* Pre-scaler control register 1 */
1089 + camif_scaler_internal(sx,tx,&cfg->sc.prehratio,&cfg->sc.hfactor);
1090 + camif_scaler_internal(sy,ty,&cfg->sc.prevratio,&cfg->sc.vfactor);
1092 + if (cfg->dma_type & CAMIF_PREVIEW) {
1093 + if ( (sx /cfg->sc.prehratio) <= 640 ) {}
1095 + printk(KERN_INFO "CAMERA: Internal Preview line buffer is 640 pixels\n");
1096 + return 1; /* Error */
1100 + cfg->sc.shfactor = 10-(cfg->sc.hfactor+cfg->sc.vfactor);
1101 + /* Pre-scaler control register 2 */
1102 + cfg->sc.predst_x = sx / cfg->sc.prehratio;
1103 + cfg->sc.predst_y = sy / cfg->sc.prevratio;
1105 + /* Main-scaler control register */
1106 + cfg->sc.mainhratio = (sx << 8)/(tx << cfg->sc.hfactor);
1107 + cfg->sc.mainvratio = (sy << 8)/(ty << cfg->sc.vfactor);
1108 + DPRINTK(" sx %d, sy %d tx %d ty %d \n",sx,sy,tx,ty);
1109 + DPRINTK(" hfactor %d vfactor %d \n",cfg->sc.hfactor,cfg->sc.vfactor);
1111 + cfg->sc.scaleup_h = (sx <= tx) ? 1: 0;
1112 + cfg->sc.scaleup_v = (sy <= ty) ? 1: 0;
1113 + if ( cfg->sc.scaleup_h != cfg->sc.scaleup_v)
1114 + printk(KERN_ERR "scaleup_h must be same to scaleup_v \n");
1115 + camif_hw_reg(cfg);
1116 + camif_target_area(cfg);
1120 +/******************************************************
1121 + CalculateBurstSize - Calculate the busrt lengths
1123 + - dstHSize: the number of the byte of H Size.
1124 +********************************************************/
1125 +static void camif_g_bsize(u32 hsize, u32 *mburst, u32 *rburst)
1129 + tmp = (hsize/4) % 16;
1156 + *rburst= (tmp) ? tmp: 4;
1163 +/* SXGA 1028x1024*/
1171 + 1 : DMA Size Error
1173 +#define BURST_ERR 1
1174 +static int camif_dma_burst(camif_cfg_t *cfg)
1176 + int width = cfg->target_x;
1178 + if (cfg->dma_type & CAMIF_CODEC ) {
1179 + u32 yburst_m, yburst_r;
1180 + u32 cburst_m, cburst_r;
1181 + /* CODEC DMA WIDHT is multiple of 16 */
1182 + if (width %16 != 0 ) return BURST_ERR; /* DMA Burst Length Error */
1183 + camif_g_bsize(width,&yburst_m,&yburst_r);
1184 + camif_g_bsize(width/2,&cburst_m,&cburst_r);
1185 + CICOCTRL =YBURST_M(yburst_m)|CBURST_M(cburst_m)
1186 + |YBURST_R(yburst_r)|CBURST_R(cburst_r);
1189 + if (cfg->dma_type & CAMIF_PREVIEW) {
1190 + u32 rgburst_m, rgburst_r;
1191 + if(cfg->fmt == CAMIF_RGB24) {
1192 + if (width %2 != 0 ) return BURST_ERR; /* DMA Burst Length Error */
1193 + camif_g_bsize(width*4,&rgburst_m,&rgburst_r);
1195 + else { /* CAMIF_RGB16 */
1196 + if ((width/2) %2 != 0 ) return BURST_ERR; /* DMA Burst Length Error */
1197 + camif_g_bsize(width*2,&rgburst_m,&rgburst_r);
1199 + CIPRCTRL = RGBURST_M(rgburst_m) | RGBURST_R(rgburst_r);
1204 +static int camif_gpio_init(void)
1206 +#ifdef CONFIG_ARCH_S3C24A0A
1207 + /* S3C24A0A has the dedicated signal pins for Camera */
1209 + set_gpio_ctrl(GPIO_CAMDATA0);
1210 + set_gpio_ctrl(GPIO_CAMDATA1);
1211 + set_gpio_ctrl(GPIO_CAMDATA2);
1212 + set_gpio_ctrl(GPIO_CAMDATA3);
1213 + set_gpio_ctrl(GPIO_CAMDATA4);
1214 + set_gpio_ctrl(GPIO_CAMDATA5);
1215 + set_gpio_ctrl(GPIO_CAMDATA6);
1216 + set_gpio_ctrl(GPIO_CAMDATA7);
1217 + set_gpio_ctrl(GPIO_CAMPCLKIN);
1218 + set_gpio_ctrl(GPIO_CAMVSYNC);
1219 + set_gpio_ctrl(GPIO_CAMHREF);
1220 + set_gpio_ctrl(GPIO_CAMPCLKOUT);
1221 + set_gpio_ctrl(GPIO_CAMRESET);
1227 +#define ROUND_ADD 0x100000
1229 +#ifdef CONFIG_ARCH_S3C24A0A
1230 +int camif_clock_init(camif_gc_t *gc)
1232 + unsigned int upll, camclk_div, camclk;
1234 + if (!gc) camclk = 24000000;
1236 + camclk = gc->camclk;
1237 + if (camclk > 48000000)
1238 + printk(KERN_ERR "Wrong Camera Clock\n");
1241 + CLKCON |= CLKCON_CAM_UPLL | CLKCON_CAM_HCLK;
1242 + upll = get_bus_clk(GET_UPLL);
1243 + printk(KERN_INFO "CAMERA:Default UPLL %08d and Assing 96Mhz to UPLL\n",upll);
1244 + UPLLCON = FInsrt(56, fPLL_MDIV) | FInsrt(2, fPLL_PDIV)| FInsrt(1, fPLL_SDIV);
1245 + upll = get_bus_clk(GET_UPLL);
1247 + camclk_div = (upll+ROUND_ADD) / camclk - 1;
1248 + CLKDIVN = (CLKDIVN & 0xFF) | CLKDIVN_CAM(camclk_div);
1249 + printk(KERN_INFO"CAMERA:upll %d MACRO 0x%08X CLKDIVN 0x%08X \n",
1250 + upll, CLKDIVN_CAM(camclk_div),CLKDIVN);
1251 + CIIMGCPT = 0; /* Dummy ? */
1255 +int camif_clock_init(camif_gc_t *gc)
1257 + unsigned int upll, camclk_div, camclk;
1258 + if (!gc) camclk = 24000000;
1260 + camclk = gc->camclk;
1261 + if (camclk > 48000000)
1262 + printk(KERN_ERR "Wrong Camera Clock\n");
1265 + CLKCON |= CLKCON_CAMIF;
1266 + upll = elfin_get_bus_clk(GET_UPLL);
1267 + printk(KERN_INFO "CAMERA:Default UPLL %08d and Assing 96Mhz to UPLL\n",upll);
1269 + UPLLCON = FInsrt(60, fPLL_MDIV) | FInsrt(4, fPLL_PDIV)| FInsrt(1, fPLL_SDIV);
1270 + CLKDIVN |= DIVN_UPLL; /* For USB */
1271 + upll = elfin_get_bus_clk(GET_UPLL);
1274 + camclk_div = (upll+ROUND_ADD) /(camclk * 2) -1;
1275 + CAMDIVN = CAMCLK_SET_DIV|(camclk_div&0xf);
1276 + printk(KERN_INFO "CAMERA:upll %08d cam_clk %08d CAMDIVN 0x%08x \n",upll,camclk, CAMDIVN);
1277 + CIIMGCPT = 0; /* Dummy ? */
1283 + Reset Camera IP in CPU
1284 + Reset External Sensor
1286 +void camif_reset(int is, int delay)
1290 + CIGCTRL |= GC_SWRST;
1292 + CIGCTRL &= ~GC_SWRST;
1294 + case CAMIF_EX_RESET_AH: /*Active High */
1295 + CIGCTRL &= ~GC_CAMRST;
1297 + CIGCTRL |= GC_CAMRST;
1299 + CIGCTRL &= ~GC_CAMRST;
1301 + case CAMIF_EX_RESET_AL: /*Active Low */
1302 + CIGCTRL |= GC_CAMRST;
1304 + CIGCTRL &= ~GC_CAMRST;
1306 + CIGCTRL |= GC_CAMRST;
1313 +/* For Camera Operation,
1314 + * we can give the high priority to REQ2 of ARBITER1
1317 +/* Please move me into proper place
1318 + * camif_gc_t is not because "rmmod imgsenor" will delete the instance of camif_gc_t
1320 +static u32 old_priority;
1322 +static void camif_bus_priority(int flag)
1325 +#ifdef CONFIG_ARCH_S3C24A0A
1326 + old_priority = PRIORITY0;
1327 + PRIORITY0 = PRIORITY_I_FIX;
1328 + PRIORITY1 = PRIORITY_I_FIX;
1331 + old_priority = PRIORITY;
1332 + PRIORITY &= ~(3<<7);
1333 + PRIORITY |= (1<<7); /* Arbiter 1, REQ2 first */
1334 + PRIORITY &= ~(1<<1); /* Disable Priority Rotate */
1338 +#ifdef CONFIG_ARCH_S3C24A0A
1339 + PRIORITY0 = old_priority;
1340 + PRIORITY1 = old_priority;
1342 + PRIORITY = old_priority;
1347 +static void inline camif_clock_off(void)
1350 +#if defined (CONFIG_ARCH_S3C24A0A)
1351 + CLKCON &= ~CLKCON_CAM_UPLL;
1352 + CLKCON &= ~CLKCON_CAM_HCLK;
1354 + CLKCON &= ~CLKCON_CAMIF;
1359 +/* Init external image sensor
1360 + * Before make some value into image senor,
1361 + * you must set up the pixel clock.
1363 +void camif_setup_sensor(void)
1365 + camif_reset(CAMIF_RESET, 0);
1366 + camif_gpio_init();
1367 + camif_clock_init(NULL);
1368 +/* Sometimes ,Before loading I2C module, we need the reset signal */
1369 +#ifdef CONFIG_ARCH_S3C24A0A
1370 + camif_reset(CAMIF_EX_RESET_AL,1000);
1372 + camif_reset(CAMIF_EX_RESET_AH,1000);
1376 +void camif_hw_close(camif_cfg_t *cfg)
1378 + camif_bus_priority(0);
1379 + camif_clock_off();
1382 +void camif_hw_open(camif_gc_t *gc)
1384 + camif_source_fmt(gc);
1385 + camif_win_offset(gc);
1386 + camif_bus_priority(1);
1392 + * Local variables:
1394 + * c-indent-level: 8
1395 + * c-basic-offset: 8
1396 + * c-set-style: "K&R"
1399 diff --git a/arch/arm/mach-s3c2440/camera/camif.h b/arch/arm/mach-s3c2440/camera/camif.h
1400 new file mode 100644
1401 index 0000000..8b4f9aa
1403 +++ b/arch/arm/mach-s3c2440/camera/camif.h
1406 + FIMC2.0 Camera Header File
1408 + Copyright (C) 2003 Samsung Electronics (SW.LEE: hitchcar@samsung.com)
1410 + Author : SW.LEE <hitchcar@samsung.com>
1412 + This program is free software; you can redistribute it and/or modify
1413 + it under the terms of the GNU General Public License as published by
1414 + the Free Software Foundation; either version 2 of the License, or
1415 + (at your option) any later version.
1420 +#ifndef __FIMC20_CAMIF_H_
1421 +#define __FIMC20_CAMIF_H_
1426 +#include "videodev.h"
1427 +#include <asm/types.h>
1428 +#include <linux/i2c.h>
1430 +#endif /* __KERNEL__ */
1433 +#define O_NONCAP O_TRUNC
1436 +/* Codec or Preview Status */
1437 +#define CAMIF_STARTED BIT1
1438 +#define CAMIF_STOPPED BIT2
1439 +#define CAMIF_INT_HAPPEN BIT3
1441 +/* Codec or Preview : Interrupt FSM */
1442 +#define CAMIF_1nd_INT BIT7
1443 +#define CAMIF_Xnd_INT BIT8
1444 +#define CAMIF_Ynd_INT BIT9
1445 +#define CAMIF_Znd_INT BIT10
1446 +#define CAMIF_NORMAL_INT BIT11
1447 +#define CAMIF_DUMMY_INT BIT12
1448 +#define CAMIF_PENDING_INT 0
1451 +/* CAMIF RESET Definition */
1452 +#define CAMIF_RESET BIT0
1453 +#define CAMIF_EX_RESET_AL BIT1 /* Active Low */
1454 +#define CAMIF_EX_RESET_AH BIT2 /* Active High */
1457 +enum camif_itu_fmt {
1458 + CAMIF_ITU601 = BIT31,
1462 +/* It is possbie to use two device simultaneously */
1463 +enum camif_dma_type {
1464 + CAMIF_PREVIEW = BIT0,
1465 + CAMIF_CODEC = BIT1,
1468 +enum camif_order422 {
1470 + CAMIF_YCRYCB = BIT14,
1471 + CAMIF_CBYCRY = BIT15,
1472 + CAMIF_CRYCBY = BIT14 | BIT15
1477 + CAMIF_FLIP_X = BIT14,
1478 + CAMIF_FLIP_Y = BIT15,
1479 + CAMIF_FLIP_MIRROR = BIT14 |BIT15,
1482 +enum camif_codec_fmt {
1484 + CAMIF_IN_YCBCR420 = BIT0, /* Currently IN_YCBCR format fixed */
1485 + CAMIF_IN_YCBCR422 = BIT1,
1486 + CAMIF_OUT_YCBCR420 = BIT4,
1487 + CAMIF_OUT_YCBCR422 = BIT5,
1488 + /* Preview Part */
1489 + CAMIF_RGB16 = BIT2,
1490 + CAMIF_RGB24 = BIT3,
1493 +enum camif_capturing {
1494 + CAMIF_BOTH_DMA_ON = BIT4,
1495 + CAMIF_DMA_ON = BIT3,
1496 + CAMIF_BOTH_DMA_OFF = BIT1,
1497 + CAMIF_DMA_OFF = BIT0,
1498 + /*------------------------*/
1499 + CAMIF_DMA_OFF_L_IRQ= BIT5,
1502 +typedef struct camif_performance
1505 + int framesdropped;
1508 + __u32 reserved[4];
1513 + dma_addr_t phys_y;
1514 + dma_addr_t phys_cb;
1515 + dma_addr_t phys_cr;
1519 + dma_addr_t phys_rgb;
1524 +/* this structure convers the CIWDOFFST, prescaler, mainscaler */
1526 + u32 modified_src_x; /* After windows applyed to source_x */
1527 + u32 modified_src_y;
1530 + u32 shfactor; /* SHfactor = 10 - ( hfactor + vfactor ) */
1539 + u32 scalerbypass; /* only codec */
1544 + CAMIF_V4L2_INIT = BIT0,
1545 + CAMIF_v4L2_DIRTY = BIT1,
1549 +/* Global Status Definition */
1550 +#define PWANT2START BIT0
1551 +#define CWANT2START BIT1
1552 +#define BOTH_STARTED (PWANT2START|CWANT2START)
1553 +#define PNOTWORKING BIT4
1554 +#define C_WORKING BIT5
1557 + struct semaphore lock;
1558 + enum camif_itu_fmt itu_fmt;
1559 + enum camif_order422 order422;
1562 + u32 camclk; /* External Image Sensor Camera Clock */
1565 + u32 polarity_pclk;
1566 + u32 polarity_vsync;
1567 + u32 polarity_href;
1568 + struct i2c_client *sensor;
1569 + u32 user; /* MAX 2 (codec, preview) */
1570 + u32 old_priority; /* BUS PRIORITY register */
1572 + u32 init_sensor;/* initializing sensor */
1573 + void *other; /* Codec camif_cfg_t */
1574 + u32 reset_type; /* External Sensor Reset Type */
1576 +} camif_gc_t; /* gobal control register */
1579 +/* when App want to change v4l2 parameter,
1580 + * we instantly store it into v4l2_t v2
1581 + * and then reflect it to hardware
1583 +typedef struct v4l2 {
1584 + struct v4l2_fmtdesc *fmtdesc;
1585 + struct v4l2_pix_format fmt; /* current pixel format */
1586 + struct v4l2_input input;
1587 + struct video_picture picture;
1588 + enum v4l2_status status;
1589 + int used_fmt ; /* used format index */
1593 +typedef struct camif_c_t {
1594 + struct video_device *v;
1595 + /* V4L2 param only for v4l2 driver */
1597 + camif_gc_t *gc; /* Common between Codec and Preview */
1598 + /* logical parameter */
1599 + wait_queue_head_t waitq;
1600 + u32 status; /* Start/Stop */
1601 + u32 fsm; /* Start/Stop */
1602 + u32 open_count; /* duplicated */
1604 + char shortname[16];
1608 + enum flip_mode flip;
1609 + enum camif_dma_type dma_type;
1610 + /* 4 pingpong Frame memory */
1612 + dma_addr_t pp_phys_buf;
1614 + u32 pp_num; /* used pingpong memory number */
1615 + img_buf_t img_buf[4];
1616 + enum camif_codec_fmt fmt;
1617 + enum camif_capturing exec;
1618 + camif_perf_t perf;
1619 + u32 now_frame_num;
1620 + u32 auto_restart; /* Only For Preview */
1624 +#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
1626 +#define DPRINTK(fmt, args...)
1631 +#define assert(expr) \
1633 + printk( "Assertion failed! %s,%s,%s,line=%d\n", \
1634 + #expr,__FILE__,__FUNCTION__,__LINE__); \
1637 +#define assert(expr)
1642 +extern int camif_capture_start(camif_cfg_t *);
1643 +extern int camif_capture_stop(camif_cfg_t *);
1644 +extern int camif_g_frame_num(camif_cfg_t *);
1645 +extern u8 * camif_g_frame(camif_cfg_t *);
1646 +extern int camif_win_offset(camif_gc_t *);
1647 +extern void camif_hw_open(camif_gc_t *);
1648 +extern void camif_hw_close(camif_cfg_t *);
1649 +extern int camif_dynamic_open(camif_cfg_t *);
1650 +extern int camif_dynamic_close(camif_cfg_t *);
1651 +extern void camif_reset(int,int);
1652 +extern void camif_setup_sensor(void);
1653 +extern int camif_g_fifo_status(camif_cfg_t *);
1654 +extern void camif_last_irq_en(camif_cfg_t *);
1655 +extern void camif_change_flip(camif_cfg_t *);
1659 + * API Interface function to both Character and V4L2 Drivers
1661 +extern int camif_do_write(struct file *,const char *, size_t, loff_t *);
1662 +extern int camif_do_ioctl(struct inode *, struct file *,unsigned int, void *);
1666 + * API for Decoder (S5x532, OV7620..)
1668 +void camif_register_decoder(struct i2c_client *);
1669 +void camif_unregister_decoder(struct i2c_client*);
1674 +#define INSTANT_SKIP 0
1675 +#define INSTANT_GO 1
1677 +extern ssize_t camif_p_1fsm_start(camif_cfg_t *);
1678 +extern ssize_t camif_p_2fsm_start(camif_cfg_t *);
1679 +extern ssize_t camif_4fsm_start(camif_cfg_t *);
1680 +extern ssize_t camif_p_stop(camif_cfg_t *);
1681 +extern int camif_enter_p_4fsm(camif_cfg_t *);
1682 +extern int camif_enter_c_4fsm(camif_cfg_t *);
1683 +extern int camif_enter_2fsm(camif_cfg_t *);
1684 +extern int camif_enter_1fsm(camif_cfg_t *);
1685 +extern int camif_check_preview(camif_cfg_t *);
1686 +extern int camif_callback_start(camif_cfg_t *);
1687 +extern int camif_clock_init(camif_gc_t *);
1692 +#define VID_HARDWARE_SAMSUNG_FIMC20 236
1702 + * Local variables:
1704 + * c-indent-level: 8
1705 + * c-basic-offset: 8
1706 + * c-set-style: "K&R"
1709 diff --git a/arch/arm/mach-s3c2440/camera/camif_fsm.c b/arch/arm/mach-s3c2440/camera/camif_fsm.c
1710 new file mode 100644
1711 index 0000000..3e2b71a
1713 +++ b/arch/arm/mach-s3c2440/camera/camif_fsm.c
1716 + Copyright (C) 2004 Samsung Electronics
1717 + SW.LEE <hitchcar@sec.samsung.com>
1719 + This program is free software; you can redistribute it and/or modify
1720 + it under the terms of the GNU General Public License as published by
1721 + the Free Software Foundation; either version 2 of the License, or
1722 + (at your option) any later version.
1725 +#include <linux/version.h>
1726 +#include <linux/module.h>
1727 +#include <linux/delay.h>
1728 +#include <linux/errno.h>
1729 +#include <linux/fs.h>
1730 +#include <linux/kernel.h>
1731 +#include <linux/major.h>
1732 +#include <linux/slab.h>
1733 +#include <linux/poll.h>
1734 +#include <linux/signal.h>
1735 +#include <linux/ioport.h>
1736 +#include <linux/sched.h>
1737 +#include <linux/types.h>
1738 +#include <linux/interrupt.h>
1739 +#include <linux/kmod.h>
1740 +#include <linux/vmalloc.h>
1741 +#include <linux/init.h>
1742 +#include <linux/pagemap.h>
1743 +#include <asm/io.h>
1744 +#include <asm/irq.h>
1745 +#include <asm/semaphore.h>
1746 +#include <linux/miscdevice.h>
1751 +const char *fsm_version =
1752 + "$Id: camif_fsm.c,v 1.3 2004/04/27 10:26:28 swlee Exp $";
1756 + * FSM function is the place where Synchronization in not necessary
1757 + * because IRS calls this functions.
1760 +ssize_t camif_p_1fsm_start(camif_cfg_t *cfg)
1762 + //camif_reset(CAMIF_RESET,0);
1763 + cfg->exec = CAMIF_DMA_ON;
1764 + camif_capture_start(cfg);
1765 + camif_last_irq_en(cfg);
1766 + cfg->status = CAMIF_STARTED;
1767 + cfg->fsm = CAMIF_1nd_INT;
1772 +ssize_t camif_p_2fsm_start(camif_cfg_t *cfg)
1774 + camif_reset(CAMIF_RESET,0);/* FIFO Count goes to zero */
1775 + cfg->exec = CAMIF_DMA_ON;
1776 + camif_capture_start(cfg);
1777 + cfg->status = CAMIF_STARTED;
1778 + cfg->fsm = CAMIF_1nd_INT;
1783 +ssize_t camif_4fsm_start(camif_cfg_t *cfg)
1785 + camif_reset(CAMIF_RESET,0); /* FIFO Count goes to zero */
1786 + cfg->exec = CAMIF_DMA_ON;
1787 + camif_capture_start(cfg);
1788 + cfg->status = CAMIF_STARTED;
1789 + cfg->fsm = CAMIF_1nd_INT;
1790 + cfg->perf.frames = 0;
1796 + cfg->perf.frames set in camif_fsm.c
1797 + cfg->status set in video-driver.c
1801 + * Don't insert camif_reset(CAM_RESET, 0 ) into this func
1803 +ssize_t camif_p_stop(camif_cfg_t *cfg)
1805 + cfg->exec = CAMIF_DMA_OFF;
1806 +// cfg->status = CAMIF_STOPPED;
1807 + camif_capture_stop(cfg);
1808 + cfg->perf.frames = 0; /* Dupplicated ? */
1812 +/* When C working, P asks C to play togehter */
1813 +/* Only P must call this function */
1814 +void camif_start_c_with_p (camif_cfg_t *cfg, camif_cfg_t *other)
1816 +// cfg->gc->other = get_camif(CODEC_MINOR);
1817 + cfg->gc->other = other;
1818 + camif_start_p_with_c(cfg);
1821 +static void camif_start_p_with_c(camif_cfg_t *cfg)
1823 + camif_cfg_t *other = (camif_cfg_t *)cfg->gc->other;
1824 + /* Preview Stop */
1825 + cfg->exec = CAMIF_DMA_OFF;
1826 + camif_capture_stop(cfg);
1827 + /* Start P and C */
1828 + camif_reset(CAMIF_RESET, 0);
1829 + cfg->exec =CAMIF_BOTH_DMA_ON;
1830 + camif_capture_start(cfg);
1831 + cfg->fsm = CAMIF_1nd_INT; /* For Preview */
1832 + if(!other) panic("Unexpected Error \n");
1833 + other->fsm = CAMIF_1nd_INT; /* For Preview */
1836 +static void camif_auto_restart(camif_cfg_t *cfg)
1838 +// if (cfg->dma_type & CAMIF_CODEC) return;
1839 + if (cfg->auto_restart)
1840 + camif_start_p_with_c(cfg);
1844 +/* Supposed that PREVIEW already running
1845 + * request PREVIEW to start with Codec
1847 +static int camif_check_global(camif_cfg_t *cfg)
1851 + if (down_interruptible(&cfg->gc->lock))
1852 + return -ERESTARTSYS;
1853 + if ( cfg->gc->status & CWANT2START ) {
1854 + cfg->gc->status &= ~CWANT2START;
1855 + cfg->auto_restart = 1;
1859 + ret = 0; /* There is no codec */
1860 + cfg->auto_restart = 0; /* Duplicated ..Dummy */
1863 + up(&cfg->gc->lock);
1869 + * 1nd INT : Start Interrupt
1870 + * Xnd INT : enable Last IRQ : pingpong get the valid data
1871 + * Ynd INT : Stop Codec or Preview : pingpong get the valid data
1872 + * Znd INT : Last IRQ : valid data
1874 +#define CHECK_FREQ 5
1875 +int camif_enter_p_4fsm(camif_cfg_t *cfg)
1879 + cfg->perf.frames++;
1880 + if (cfg->fsm == CAMIF_NORMAL_INT)
1881 + if (cfg->perf.frames % CHECK_FREQ == 0)
1882 + ret = camif_check_global(cfg);
1883 + if (ret > 0) cfg->fsm = CAMIF_Xnd_INT; /* Codec wait for Preview */
1885 + switch (cfg->fsm) {
1886 + case CAMIF_1nd_INT: /* Start IRQ */
1887 + cfg->fsm = CAMIF_NORMAL_INT;
1888 + ret = INSTANT_SKIP;
1889 + DPRINTK(KERN_INFO "1nd INT \n");
1891 + case CAMIF_NORMAL_INT:
1892 + cfg->status = CAMIF_INT_HAPPEN;
1893 + cfg->fsm = CAMIF_NORMAL_INT;
1895 + DPRINTK(KERN_INFO "NORMAL INT \n");
1897 + case CAMIF_Xnd_INT:
1898 + camif_last_irq_en(cfg);/* IRQ for Enabling LAST IRQ */
1899 + cfg->status = CAMIF_INT_HAPPEN;
1900 + cfg->fsm = CAMIF_Ynd_INT;
1902 + DPRINTK(KERN_INFO "Xnd INT \n");
1904 + case CAMIF_Ynd_INT: /* Capture Stop */
1905 + cfg->exec = CAMIF_DMA_OFF;
1906 + cfg->status = CAMIF_INT_HAPPEN;
1907 + camif_capture_stop(cfg);
1908 + cfg->fsm = CAMIF_Znd_INT;
1910 + DPRINTK(KERN_INFO "Ynd INT \n");
1912 + case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
1913 + cfg->fsm = CAMIF_DUMMY_INT;
1914 + cfg->status = CAMIF_INT_HAPPEN;
1916 + camif_auto_restart(cfg); /* Automatically Restart Camera */
1917 + DPRINTK(KERN_INFO "Znd INT \n");
1919 + case CAMIF_DUMMY_INT:
1920 + cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
1921 + ret = INSTANT_SKIP;
1922 +// DPRINTK(KERN_INFO "Dummy INT \n");
1925 + printk(KERN_INFO "Unexpect INT %d \n",cfg->fsm);
1926 + ret = INSTANT_SKIP;
1934 + * NO autorestart included in this function
1936 +int camif_enter_c_4fsm(camif_cfg_t *cfg)
1940 + cfg->perf.frames++;
1942 + if ( (cfg->fsm==CAMIF_NORMAL_INT)
1943 + && (cfg->perf.frames>cfg->restart_limit-1)
1945 + cfg->fsm = CAMIF_Xnd_INT;
1947 + switch (cfg->fsm) {
1948 + case CAMIF_1nd_INT: /* Start IRQ */
1949 + cfg->fsm = CAMIF_NORMAL_INT;
1950 +// cfg->status = CAMIF_STARTED; /* need this to meet auto-restart */
1951 + ret = INSTANT_SKIP;
1952 + DPRINTK(KERN_INFO "1nd INT \n");
1954 + case CAMIF_NORMAL_INT:
1955 + cfg->status = CAMIF_INT_HAPPEN;
1956 + cfg->fsm = CAMIF_NORMAL_INT;
1958 + DPRINTK(KERN_INFO "NORMALd INT \n");
1960 + case CAMIF_Xnd_INT:
1961 + camif_last_irq_en(cfg);/* IRQ for Enabling LAST IRQ */
1962 + cfg->status = CAMIF_INT_HAPPEN;
1963 + cfg->fsm = CAMIF_Ynd_INT;
1965 + DPRINTK(KERN_INFO "Xnd INT \n");
1967 + case CAMIF_Ynd_INT: /* Capture Stop */
1968 + cfg->exec = CAMIF_DMA_OFF;
1969 + cfg->status = CAMIF_INT_HAPPEN;
1970 + camif_capture_stop(cfg);
1971 + cfg->fsm = CAMIF_Znd_INT;
1973 + DPRINTK(KERN_INFO "Ynd INT \n");
1975 + case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
1976 + cfg->fsm = CAMIF_DUMMY_INT;
1977 + cfg->status = CAMIF_INT_HAPPEN;
1979 + DPRINTK(KERN_INFO "Znd INT \n");
1981 + case CAMIF_DUMMY_INT:
1982 + cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
1983 + ret = INSTANT_SKIP;
1986 + printk(KERN_INFO "Unexpect INT %d \n",cfg->fsm);
1987 + ret = INSTANT_SKIP;
1993 +/* 4 Interrups State Machine is for two pingpong
1994 + * 1nd INT : Start Interrupt
1995 + * Xnd INT : enable Last IRQ : pingpong get the valid data
1996 + * Ynd INT : Stop Codec or Preview : pingpong get the valid data
1997 + * Znd INT : Last IRQ : valid data
2000 + * Before calling this func, you must call camif_reset
2003 +int camif_enter_2fsm(camif_cfg_t *cfg) /* Codec FSM */
2007 + cfg->perf.frames++;
2008 + switch (cfg->fsm) {
2009 + case CAMIF_1nd_INT: /* Start IRQ */
2010 + cfg->fsm = CAMIF_Xnd_INT;
2011 + ret = INSTANT_SKIP;
2012 +// printk(KERN_INFO "1nd INT \n");
2014 + case CAMIF_Xnd_INT:
2015 + camif_last_irq_en(cfg);/* IRQ for Enabling LAST IRQ */
2016 + cfg->now_frame_num = 0;
2017 + cfg->status = CAMIF_INT_HAPPEN;
2018 + cfg->fsm = CAMIF_Ynd_INT;
2020 +// printk(KERN_INFO "2nd INT \n");
2022 + case CAMIF_Ynd_INT: /* Capture Stop */
2023 + cfg->exec = CAMIF_DMA_OFF;
2024 + cfg->now_frame_num = 1;
2025 + cfg->status = CAMIF_INT_HAPPEN;
2026 + camif_capture_stop(cfg);
2027 + cfg->fsm = CAMIF_Znd_INT;
2029 +// printk(KERN_INFO "Ynd INT \n");
2031 + case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
2032 + cfg->now_frame_num = 0;
2033 +// cfg->fsm = CAMIF_DUMMY_INT;
2034 + cfg->status = CAMIF_INT_HAPPEN;
2036 +// printk(KERN_INFO "Znd INT \n");
2038 + case CAMIF_DUMMY_INT:
2039 + cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
2040 + ret = INSTANT_SKIP;
2041 + printk(KERN_INFO "Dummy INT \n");
2043 + default: /* CAMIF_PENDING_INT */
2044 + printk(KERN_INFO "Unexpect INT \n");
2045 + ret = INSTANT_SKIP;
2052 +/* 2 Interrups State Machine is for one pingpong
2053 + * 1nd INT : Stop Codec or Preview : pingpong get the valid data
2054 + * 2nd INT : Last IRQ : dummy data
2056 +int camif_enter_1fsm(camif_cfg_t *cfg) /* Codec FSM */
2060 + cfg->perf.frames++;
2061 + switch (cfg->fsm) {
2062 + case CAMIF_Ynd_INT: /* IRQ for Enabling LAST IRQ */
2063 + cfg->exec = CAMIF_DMA_OFF;
2064 + camif_capture_stop(cfg);
2065 + cfg->fsm = CAMIF_Znd_INT;
2066 + ret = INSTANT_SKIP;
2067 + // printk(KERN_INFO "Ynd INT \n");
2069 + case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
2070 + cfg->fsm = CAMIF_DUMMY_INT;
2071 + cfg->status = CAMIF_INT_HAPPEN;
2073 + // printk(KERN_INFO "Znd INT \n");
2075 + case CAMIF_DUMMY_INT:
2076 + cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
2077 + ret = INSTANT_SKIP;
2078 + printk(KERN_INFO "Dummy INT \n");
2081 + printk(KERN_INFO "Unexpect INT \n");
2082 + ret = INSTANT_SKIP;
2090 + * GLOBAL STATUS CONTROL FUNCTION
2095 +/* Supposed that PREVIEW already running
2096 + * request PREVIEW to start with Codec
2098 +int camif_callback_start(camif_cfg_t *cfg)
2102 + if (down_interruptible(&cfg->gc->lock)) {
2103 + return -ERESTARTSYS;
2105 + cfg->gc->status = CWANT2START;
2106 + cfg->gc->other = cfg;
2107 + up(&cfg->gc->lock);
2114 + * Return status of Preview Machine
2116 + 0: Preview is not working
2117 + X: Codec must follow PREVIEW start
2119 +int camif_check_preview(camif_cfg_t *cfg)
2123 + if (down_interruptible(&cfg->gc->lock)) {
2124 + ret = -ERESTARTSYS;
2127 + if (cfg->gc->user == 1) ret = 0;
2128 + // else if (cfg->gc->status & PNOTWORKING) ret = 0;
2130 + up(&cfg->gc->lock);
2138 + * Local variables:
2139 + * c-basic-offset: 8
2142 diff --git a/arch/arm/mach-s3c2440/camera/imgsensor.c b/arch/arm/mach-s3c2440/camera/imgsensor.c
2143 new file mode 100644
2144 index 0000000..44b7bee
2146 +++ b/arch/arm/mach-s3c2440/camera/imgsensor.c
2149 + * Copyright (C) 2004 Samsung Electronics
2150 + * SW.LEE <hitchcar@samsung.com>
2152 + * Copyright (C) 2000 Russell King : pcf8583.c
2154 + * This program is free software; you can redistribute it and/or modify
2155 + * it under the terms of the GNU General Public License version 2 as
2156 + * published by the Free Software Foundation.
2158 + * Driver for FIMC20 Camera Decoder
2161 +#include <linux/config.h>
2162 +#include <linux/module.h>
2163 +#include <linux/kernel.h>
2164 +#include <linux/init.h>
2165 +#include <linux/i2c.h>
2166 +#include <linux/slab.h>
2167 +#include <linux/string.h>
2168 +#include <linux/init.h>
2169 +#include <linux/delay.h>
2172 +#ifdef CONFIG_ARCH_S3C24A0A
2174 +#include <asm/arch/S3C2440.h>
2179 +#include "sensor.h"
2181 +#ifndef SAMSUNG_SXGA_CAM
2182 +#include "s5x532_rev36.h"
2187 +static const char *sensor_version =
2188 + "$Id: imgsensor.c,v 1.11 2004/06/10 12:45:40 swlee Exp $";
2191 +static struct i2c_driver s5x532_driver;
2192 +static camif_gc_t data = {
2193 + itu_fmt: CAMIF_ITU601,
2194 + order422: CAMIF_YCBYCR,
2196 +#ifndef SAMSUNG_SXGA_CAM
2199 + win_hor_ofst: 112,
2209 +#ifdef CONFIG_ARCH_S3C24A0A
2210 + reset_type:CAMIF_EX_RESET_AL, /* Active Low */
2212 + reset_type:CAMIF_EX_RESET_AH, /* Ref board has inverted signal */
2214 + reset_udelay:2000,
2217 +#define CAM_ID 0x5a
2219 +static unsigned short ignore[] = { I2C_CLIENT_END };
2220 +static unsigned short normal_addr[] = { (CAM_ID>>1), I2C_CLIENT_END };
2221 +static struct i2c_client_address_data addr_data = {
2222 + normal_i2c: normal_addr,
2223 + normal_i2c_range: ignore,
2225 + probe_range: ignore,
2227 + ignore_range: ignore,
2231 +s5x532_t s5x532_regs_mirror[S5X532_REGS];
2234 +s5x532_read(struct i2c_client *client,unsigned char subaddr)
2237 + unsigned char buf[1];
2238 + struct i2c_msg msg ={ client->addr, 0, 1, buf};
2241 + ret = i2c_transfer(client->adapter,&msg, 1) == 1 ? 0 : -EIO;
2242 + if (ret == -EIO) {
2243 + printk(" I2C write Error \n");
2247 + msg.flags = I2C_M_RD;
2248 + ret = i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
2255 +s5x532_write(struct i2c_client *client,
2256 + unsigned char subaddr, unsigned char val)
2258 + unsigned char buf[2];
2259 + struct i2c_msg msg = { client->addr, 0, 2, buf};
2264 + return i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
2267 +void inline s5x532_init(struct i2c_client *sam_client)
2271 + printk(KERN_ERR "s5x532_init \n");
2272 + for (i = 0; i < S5X532_INIT_REGS; i++) {
2273 + s5x532_write(sam_client,
2274 + s5x532_reg[i].subaddr, s5x532_reg[i].value );
2277 +#ifdef YOU_WANT_TO_CHECK_IMG_SENSOR
2278 + for (i = 0; i < S5X532_INIT_REGS;i++) {
2279 + if ( s5x532_reg[i].subaddr == PAGE_ADDRESS ) {
2280 + s5x532_write(sam_client,
2281 + s5x532_reg[i].subaddr, s5x532_reg[i].value);
2283 + printk(KERN_ERR "Page: Subaddr %02x = 0x%02x\n",
2284 + s5x532_reg[i].subaddr, s5x532_regs_mirror[i].value);
2289 + s5x532_regs_mirror[i].subaddr = s5x532_reg[i].subaddr;
2290 + s5x532_regs_mirror[i].value =
2291 + s5x532_read(sam_client,s5x532_reg[i].subaddr);
2292 + printk(KERN_ERR "Subaddr %02x = 0x%02x\n",
2293 + s5x532_reg[i].subaddr, s5x532_regs_mirror[i].value);
2301 +s5x532_attach(struct i2c_adapter *adap, int addr, unsigned short flags,int kind)
2303 + struct i2c_client *c;
2305 + c = kmalloc(sizeof(*c), GFP_KERNEL);
2306 + if (!c) return -ENOMEM;
2308 + strcpy(c->name, "S5X532");
2309 + c->id = s5x532_driver.id;
2310 + c->flags = I2C_CLIENT_ALLOW_USE;
2312 + c->adapter = adap;
2313 + c->driver = &s5x532_driver;
2317 + camif_register_decoder(c);
2318 + return i2c_attach_client(c);
2321 +static int s5x532_probe(struct i2c_adapter *adap)
2323 + return i2c_probe(adap, &addr_data, s5x532_attach);
2326 +static int s5x532_detach(struct i2c_client *client)
2328 + i2c_detach_client(client);
2329 + camif_unregister_decoder(client);
2334 +s5x532_command(struct i2c_client *client, unsigned int cmd, void *arg)
2338 + s5x532_init(client);
2339 + printk(KERN_INFO "CAMERA: S5X532 Sensor initialized\n");
2342 + MOD_INC_USE_COUNT;
2345 + MOD_DEC_USE_COUNT;
2348 + case SENSOR_BRIGHTNESS:
2353 + panic("Unexpect Sensor Command \n");
2359 +static struct i2c_driver s5x532_driver = {
2362 + flags: I2C_DF_NOTIFY,
2363 + attach_adapter: s5x532_probe,
2364 + detach_client: s5x532_detach,
2365 + command: s5x532_command
2368 +static void iic_gpio_port(void)
2370 +#ifdef CONFIG_ARCH_S3C24A0A
2372 + GPECON &= ~(0xf <<28);
2373 + GPECON |= 0xa <<28;
2377 +static __init int camif_sensor_init(void)
2380 + return i2c_add_driver(&s5x532_driver);
2384 +static __init void camif_sensor_exit(void)
2386 + i2c_del_driver(&s5x532_driver);
2389 +module_init(camif_sensor_init)
2390 +module_exit(camif_sensor_exit)
2392 +MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");
2393 +MODULE_DESCRIPTION("I2C Client Driver For Fimc2.0 MISC Driver");
2394 +MODULE_LICENSE("GPL");
2399 + * Local variables:
2400 + * c-basic-offset: 8
2403 diff --git a/arch/arm/mach-s3c2440/camera/miscdevice.h b/arch/arm/mach-s3c2440/camera/miscdevice.h
2404 new file mode 100644
2405 index 0000000..2e1cfbc
2407 +++ b/arch/arm/mach-s3c2440/camera/miscdevice.h
2410 + /*----------------------------------------------------------
2411 + * (C) 2004 Samsung Electronics
2412 + * SW.LEE < hitchcar@samsung.com>
2414 + ----------------------------------------------------------- */
2416 +#ifndef _LINUX_S3C_MISCDEVICE_H
2417 +#define _LINUX_S3C_MISCDEVICE_H
2419 +#define CODEC_MINOR 212
2420 +#define PREVIEW_MINOR 213
2427 diff --git a/arch/arm/mach-s3c2440/camera/qt-driver.c b/arch/arm/mach-s3c2440/camera/qt-driver.c
2428 new file mode 100644
2429 index 0000000..0c5dd40
2431 +++ b/arch/arm/mach-s3c2440/camera/qt-driver.c
2434 + * SW.LEE <hitchcar@samsung.com>
2436 + * This file is subject to the terms and conditions of the GNU General Public
2437 + * License 2. See the file COPYING in the main directory of this archive
2438 + * for more details.
2441 +#include <linux/version.h>
2442 +#include <linux/module.h>
2443 +#include <linux/delay.h>
2444 +#include <linux/errno.h>
2445 +#include <linux/fs.h>
2446 +#include <linux/kernel.h>
2447 +#include <linux/major.h>
2448 +#include <linux/slab.h>
2449 +#include <linux/poll.h>
2450 +#include <linux/signal.h>
2451 +#include <linux/ioport.h>
2452 +#include <linux/sched.h>
2453 +#include <linux/types.h>
2454 +#include <linux/interrupt.h>
2455 +#include <linux/kmod.h>
2456 +#include <linux/vmalloc.h>
2457 +#include <linux/init.h>
2458 +#include <asm/io.h>
2459 +#include <asm/page.h>
2460 +#include <asm/irq.h>
2461 +#include <asm/semaphore.h>
2462 +#include <linux/miscdevice.h>
2467 +#include "videodev.h"
2468 +#include "miscdevice.h"
2469 +#include "cam_reg.h"
2470 +#include "sensor.h"
2471 +#include "userapp.h"
2474 +/************************* Sharp Zarus API **************************
2475 +* refering to Camera Driver API for SL-5000D/SL-5600 revision 1.00
2477 + SW.LEE <hitchcar@sec.samsung.com>
2478 + I want to use Sharp Camera Application.
2482 +#define READ_MODE_STATUS 0x1
2483 +#define READ_MODE_IMAGE 0x0
2484 +#define CAPTURE_SPEED
2487 +typedef enum sharp_readmode
2489 + IMAGE = 0, STATUS = 1,
2490 + FASTER = 0, BETTER = 2,
2491 + XNOFLIP = 0, XFLIP = 4,
2492 + YNOFLIP = 0, YFLIP = 8,
2493 + AUTOMATICFLIP = -1
2497 +static struct sharp_param_t {
2498 + ReadMode_t readMode;
2499 + char CameraStatus[4];
2500 +} sharp_param = { STATUS, {'s','m','c','A'}};
2503 +camif_param_t qt_parm = { 640,480,240,320,16,0};
2505 +static void setReadMode(const char *b,size_t count)
2507 + int i = *(b+2) - 48 ;
2508 + if ( 4 == count ) {
2509 + i = (*(b+3) - 48) + i * 10;
2512 + // DPRINTK(" setReadMode %s conversion value %d \n",b , i);
2513 + if ( i & STATUS ) {
2514 + // DPRINTK(" STATUS MODE \n");
2515 + sharp_param.readMode = i;
2518 + // DPRINTK(" IMAGE MODE \n");
2519 + sharp_param.readMode = i;
2526 +extern ssize_t camif_p_read(struct file *, char *, size_t , loff_t *);
2528 +ssize_t z_read(struct file *f, char *buf, size_t count, loff_t *pos)
2532 + if (sharp_param.readMode & STATUS ) {
2533 + buf[0] = sharp_param.CameraStatus[0];
2534 + buf[1] = sharp_param.CameraStatus[1];
2535 + buf[2] = sharp_param.CameraStatus[2];
2536 + buf[3] = sharp_param.CameraStatus[3];
2540 + else { /* Image ReadMode */
2542 + if (( sharp_param.readMode & (BETTER|X FLIP|YFLIP)))
2543 + DPRINTK(" Not Supporting BETTER|XFLIP|YFLIP\n");
2545 + return camif_p_read(f,buf,count,pos);
2549 +static void z_config(camif_cfg_t *cfg,int x, int y)
2551 + cfg->target_x = x;
2552 + cfg->target_y = y;
2553 + cfg->fmt = CAMIF_RGB16;
2554 + if (camif_dynamic_open(cfg)) {
2555 + panic(" Eror Happens \n");
2560 +ssize_t z_write(struct file *f, const char *b, size_t c, loff_t *pos)
2566 + cfg = get_camif(MINOR(f->f_dentry->d_inode->i_rdev));
2567 +// DPRINTK(" param %s count %d \n",b, c );
2571 + setReadMode(b, c);
2573 + case 'B': /* Clear the latch flag of shutter button */
2574 + DPRINTK(" clear latch flag of camera's shutter button\n");
2575 + sharp_param.CameraStatus[0]='s';
2577 + case 'Y': /* I don't know how to set Shutter pressed */
2578 + DPRINTK(" set latch flag n");
2579 + sharp_param.CameraStatus[0]='S';
2581 + case 'S': /* Camera Image Resolution */
2582 + case 'R': /* Donot support Rotation */
2583 + DPRINTK(" param %s count %d \n",b, c );
2584 + get_options((char *)(b+2), 5, array);
2585 + if ( array[3] == 512 ) zoom = 2;
2586 + z_config(cfg, array[1] * zoom , array[2] * zoom );
2587 + camif_4fsm_start(cfg);
2590 + DPRINTK(" param %s count %d \n",b, c );
2591 + DPRINTK(" Start the camera to capture \n");
2592 + sharp_param.CameraStatus[2]='C';
2593 + camif_4fsm_start(cfg);
2596 + printk("Unexpected param %s count %d \n",b, c );
2602 diff --git a/arch/arm/mach-s3c2440/camera/qt.h b/arch/arm/mach-s3c2440/camera/qt.h
2603 new file mode 100644
2604 index 0000000..e58368a
2606 +++ b/arch/arm/mach-s3c2440/camera/qt.h
2609 + * SW.LEE <hitchcar@samsung.com>
2611 + * This file is subject to the terms and conditions of the GNU General Public
2612 + * License 2. See the file COPYING in the main directory of this archive
2613 + * for more details.
2619 +extern ssize_t z_read(struct file *f, char *buf, size_t count, loff_t *pos);
2620 +extern ssize_t z_write(struct file *f, const char *b, size_t c, loff_t *pos);
2626 diff --git a/arch/arm/mach-s3c2440/camera/s5x532.h b/arch/arm/mach-s3c2440/camera/s5x532.h
2627 new file mode 100644
2628 index 0000000..12725f4
2630 +++ b/arch/arm/mach-s3c2440/camera/s5x532.h
2633 + * 2004 (C) Samsung Electronics
2634 + * SW.LEE <hitchcar@sec.samsung.com>
2635 + * This file is subject to the terms and conditions of the GNU General Public
2636 + * License 2. See the file COPYING in the main directory of this archive
2637 + * for more details.
2641 +#ifndef _SMDK2440_S5X532_H_
2642 +#define _SMDK2440_S5X532_H_
2645 +#define CHIP_DELAY 0xFF
2647 +typedef struct samsung_t{
2648 + unsigned char subaddr;
2649 + unsigned char value;
2650 + unsigned char page;
2653 +s5x532_t s5x532_reg[] = {
2675 + {0x2b,0x10,0x3}, // momo clock inversion
2686 + {0x1b,0x77,0x2}, // 24MHz : 0x77, 12MHz : 0x22
2687 + {0x1c,0x77,0x2}, // 24MHz : 0x77, 12MHz : 0x22
2690 + {0x00,0x03,0x1}, //
2691 + {0x0a,0x08,0x1}, // 0x0-QQVGA, 0x06-CIF, 0x02-QCIF, 0x08-VGA, 0x04-QVGA, 0x0a-SXGA
2692 + {0x0c,0x00,0x1}, // Pattern selectio. 0-CIS, 1-Color bar, 2-Ramp, 3-Blue screen
2694 + // 0x21-ITU-R656(CrYCbY), 0x25-ITU-R601(CrYCbY), 0x26-ITU-R601(YCbYCr)
2695 + {0x50,0x21,0x1}, // Hblank
2696 + {0x51,0x00,0x1}, // Hblank
2697 + {0x52,0xA1,0x1}, // Hblank
2698 + {0x53,0x02,0x1}, // Hblank
2699 + {0x54,0x01,0x1}, // Vblank
2700 + {0x55,0x00,0x1}, // Vblank
2701 + {0x56,0xE1,0x1}, // Vblank
2702 + {0x57,0x01,0x1}, // Vblank
2703 + {0x58,0x21,0x1}, // Hsync
2704 + {0x59,0x00,0x1}, // Hsync
2705 + {0x5a,0xA1,0x1}, // Hsync
2706 + {0x5b,0x02,0x1}, // Hsync
2707 + {0x5c,0x03,0x1}, // Vref
2708 + {0x5d,0x00,0x1}, // Vref
2709 + {0x5e,0x05,0x1}, // Vref
2710 + {0x5f,0x00,0x1}, // Vref
2753 + {0x72,0x82,0x0}, // main clock = 24MHz:0xd2, 16M:0x82, 12M:0x54
2754 + {0x75,0x05,0x0} // absolute vertical mirror. junon
2759 +#define S5X532_INIT_REGS (sizeof(s5x532_reg)/sizeof(s5x532_reg[0]))
2760 +#define S5X532_RISC_REGS 0xEB
2761 +#define S5X532_ISP_REGS 0xFB /* S5C7323X */
2762 +#define S5X532_CIS_REGS 0x2F /* S5K437LA03 */
2765 +#define PAGE_ADDRESS 0xEC
2767 +//#define S5X532_REGS (S5X532_RISC_REGS+S5X532_ISP_REGS+S5X532_CIS_REGS)
2768 +#define S5X532_REGS (0x1000)
2775 diff --git a/arch/arm/mach-s3c2440/camera/s5x532_rev36.h b/arch/arm/mach-s3c2440/camera/s5x532_rev36.h
2776 new file mode 100644
2777 index 0000000..b662e9c
2779 +++ b/arch/arm/mach-s3c2440/camera/s5x532_rev36.h
2782 + * 2004 (C) Samsung Electronics
2783 + * SW.LEE <hitchcar@sec.samsung.com>
2784 + * This file is subject to the terms and conditions of the GNU General Public
2785 + * License 2. See the file COPYING in the main directory of this archive
2786 + * for more details.
2790 +#ifndef _SMDK2440_S5X532_H_
2791 +#define _SMDK2440_S5X532_H_
2794 +#define CHIP_DELAY 0xFF
2796 +typedef struct samsung_t{
2797 + unsigned char subaddr;
2798 + unsigned char value;
2799 + unsigned char page;
2802 +s5x532_t s5x532_reg[] = {
2804 + //=============== page0 ===============//
2872 + //=============== page1 ===============//
2917 + //=============== page2 ===============//
2926 + //=============== page3 ===============//
2931 + //=============== page4 ===============//
2952 + //=============== page5 ===============//
2960 + //=============== page7 ===============//
2967 + // 0x21-ITU-R656(CbYCrY), 0x25-ITU-R601(CbYCrY), 0x26-ITU-R601(YCrYCb)
2973 +#define S5X532_INIT_REGS (sizeof(s5x532_reg)/sizeof(s5x532_reg[0]))
2974 +#define S5X532_RISC_REGS 0xEB
2975 +#define S5X532_ISP_REGS 0xFB /* S5C7323X */
2976 +#define S5X532_CIS_REGS 0x2F /* S5K437LA03 */
2979 +#define PAGE_ADDRESS 0xEC
2981 +//#define S5X532_REGS (S5X532_RISC_REGS+S5X532_ISP_REGS+S5X532_CIS_REGS)
2982 +#define S5X532_REGS (0x1000)
2989 diff --git a/arch/arm/mach-s3c2440/camera/sensor.h b/arch/arm/mach-s3c2440/camera/sensor.h
2990 new file mode 100644
2991 index 0000000..e28d01c
2993 +++ b/arch/arm/mach-s3c2440/camera/sensor.h
2997 + * Copyright (C) 2004 Samsung Electronics
2998 + * SW.LEE <hitchcar@sec.samsung.com>
3000 + * This program is free software; you can redistribute it and/or modify
3001 + * it under the terms of the GNU General Public License version 2 as
3002 + * published by the Free Software Foundation.
3005 +#ifndef __SENSOR_CMD_H_
3006 +#define __SENSOR_CMD_H_
3010 +#define SENSOR_INIT BIT0
3011 +#define USER_ADD BIT1
3012 +#define USER_EXIT BIT2
3015 diff --git a/arch/arm/mach-s3c2440/camera/sxga.h b/arch/arm/mach-s3c2440/camera/sxga.h
3016 new file mode 100644
3017 index 0000000..b41305a
3019 +++ b/arch/arm/mach-s3c2440/camera/sxga.h
3022 + * 2004 (C) Samsung Electronics
3023 + * SW.LEE <hitchcar@sec.samsung.com>
3024 + * This file is subject to the terms and conditions of the GNU General Public
3025 + * License 2. See the file COPYING in the main directory of this archive
3026 + * for more details.
3030 +#ifndef _SAMSUNG_SXGA_H_
3031 +#define _SAMSUNG_SXGA_H_
3034 +#define CHIP_DELAY 0xFF
3036 +typedef struct samsung_t{
3037 + unsigned char subaddr;
3038 + unsigned char value;
3039 + unsigned char page;
3042 +s5x532_t s5x532_reg[] = {
3088 +// {0x72,0x50,0x0}, // Clock 16
3089 + {0x72,0x78,0x0}, // Clock 24Mhz
3090 +// {0x72,0xf0,0x0}, // Clock 48Mhz
3093 + {0x10,0x17,0x1}, // ITU-R601
3104 + {0x0b,0x06,0x1}, // 6
3105 + {0x20,0xa8,0x1}, //b0); // Highlight C Supp 040215
3106 + {0x22,0x26,0x1}, //2f); 040225
3108 + {0x24,0x08,0x1}, //00); //1F); 040226
3109 + {0x25,0x10,0x1}, //10); //34);
3110 + {0x26,0x40,0x1}, //56);
3111 + {0x27,0x80,0x1}, //8D);
3112 + {0x28,0x2c,0x1}, //E7);
3113 + {0x29,0xd6,0x1}, //7C);
3114 + {0x2A,0x0c,0x1}, //70);
3115 + {0x2B,0xFF,0x1}, //FF);
3116 + {0x2C,0x00,0x1}, //00);
3117 + {0x2D,0x5f,0x1}, //1B);
3119 + {0xB0,0x08,0x1}, //00); //1F); 040226
3120 + {0xB1,0x10,0x1}, //10); //34);50
3121 + {0xB2,0x40,0x1}, //36);
3122 + {0xB3,0x80,0x1}, //6D);
3123 + {0xB4,0x2c,0x1}, //b7);
3124 + {0xB5,0xd6,0x1}, //7C);
3125 + {0xB6,0x0c,0x1}, //70);
3126 + {0xB7,0xFF,0x1}, //FF);
3127 + {0xB8,0x00,0x1}, //00);
3128 + {0xB9,0x5f,0x1}, //1B);
3131 + {0xc2,0x01,0x1}, // shading On
3199 + {0x6e,0x16,0x3}, // 2.38
3200 + {0x6f,0x16,0x3}, // 2.38
3208 + {0x80,0x00,0x3}, //for 0.02 _ 44
3235 + {0x3f,0x09,0x04}, // VGA : old board :0x08 , new board ; 0X09
3236 + {0x18,0x00,0x04}, // sxga
3238 + {0x20,0x41,0x04}, // vga center 040215
3239 + {0x22,0xc1,0x04},// a1);
3242 + {0x2a,0xc1,0x04},// a1);
3245 + {0x3c,0x0b,0x04}, //f); // vga
3266 + {0x72,0xd3,0x04}, // 14
3267 + {0x73,0x05,0x04}, // 15
3270 + {0x76,0x1b,0x04}, // HendL
3271 + {0x77,0x0b,0x04}, // HendH
3272 + {0x78,0x01,0x04}, // 5.00
3273 + {0x79,0x80,0x04}, // 5.2a
3276 + {0x7c,0x38,0x04}, // 5.0e
3327 + {0x12,0x40,0x04}, // 040216 AE1 window ÁÙÀÓ
3330 + {0x1a,0x29,0x04}, // 040217 AWB window ÁÙÀÓ
3347 + {0x38,0x01,0x7}, //07); 040315
3348 + {0x39,0x01,0x7}, //02); //4); 040223 040315
3349 + {0x11,0xfe,0x7}, //fe); // green -2 040303
3357 + {0x23,0x07,0x7}, // for ESD
3441 + {0x20,0xd0,0x01}, //high light color reference
3445 + {0x73,0x11,0x00}, // 41
3452 + {0x48,0xA0,0x00}, //s48C0
3453 + {0x49,0xB0,0x00}, //s49B0
3454 + {0x4a,0x30,0x00}, //s4a20
3455 + {0x4b,0x70,0x00}, //s4b70
3456 + {0x4c,0xD0,0x00}, //s4cA0
3457 + {0x4d,0xB0,0x00}, //s4dB0
3458 + {0x4e,0x30,0x00}, //s4e30
3459 + {0x4f,0xF0,0x00}, //s4fF0
3460 + {0x50,0xA0,0x00}, //s50D0
3461 + {0x51,0xB0,0x00}, //s51B0
3462 + {0x52,0x25,0x00}, //s5210
3463 + {0x53,0x70,0x00}, //s5370
3464 + {0x54,0xD0,0x00}, //s5490
3465 + {0x55,0xD0,0x00}, //s55B0
3466 + {0x56,0x3A,0x00}, //s5640
3467 + {0x57,0xD0,0x00}, //s57D0
3468 + {0x58,0xA0,0x00}, //s58D0
3469 + {0x59,0xA0,0x00}, //s59B0
3470 + {0x5a,0x32,0x00}, //s5a0A
3471 + {0x5b,0x7A,0x00}, //s5b7A
3472 + {0x5c,0xB0,0x00}, //s5c90
3473 + {0x5d,0xC0,0x00}, //s5dC0
3474 + {0x5e,0x3E,0x00}, //s5e4A
3475 + {0x5f,0xfa,0x00}, //s5fD0
3509 +#define S5X532_INIT_REGS (sizeof(s5x532_reg)/sizeof(s5x532_reg[0]))
3510 +#define S5X532_RISC_REGS 0xEB
3511 +#define S5X532_ISP_REGS 0xFB /* S5C7323X */
3512 +#define S5X532_CIS_REGS 0x2F /* S5K437LA03 */
3515 +#define PAGE_ADDRESS 0xEC
3517 +//#define S5X532_REGS (S5X532_RISC_REGS+S5X532_ISP_REGS+S5X532_CIS_REGS)
3518 +#define S5X532_REGS (0x1000)
3525 diff --git a/arch/arm/mach-s3c2440/camera/userapp.h b/arch/arm/mach-s3c2440/camera/userapp.h
3526 new file mode 100644
3527 index 0000000..9203378
3529 +++ b/arch/arm/mach-s3c2440/camera/userapp.h
3532 + Character Driver API Interface
3534 + Copyright (C) 2003 Samsung Electronics (SW.LEE: hitchcar@samsung.com)
3536 + This program is free software; you can redistribute it and/or modify
3537 + it under the terms of the GNU General Public License as published by
3538 + the Free Software Foundation; either version 2 of the License, or
3539 + (at your option) any later version.
3543 +#ifndef __FIMC20_CAMIF_USR_APP_H_
3544 +#define __FIMC20_CAMIF_USR_APP_H_
3548 + * IOCTL Command for Character Driver
3551 +#define CMD_CAMERA_INIT 0x23
3552 +/* Test Application Usage */
3568 + * Local variables:
3570 + * c-indent-level: 8
3571 + * c-basic-offset: 8
3572 + * c-set-style: "K&R"
3575 diff --git a/arch/arm/mach-s3c2440/camera/v4l2_api.c b/arch/arm/mach-s3c2440/camera/v4l2_api.c
3576 new file mode 100644
3577 index 0000000..13aed36
3579 +++ b/arch/arm/mach-s3c2440/camera/v4l2_api.c
3582 + * . 2004-01-03: SW.LEE <hitchcar@sec.samsung.com>
3584 + * This file is subject to the terms and conditions of the GNU General Public
3585 + * License 2. See the file COPYING in the main directory of this archive
3586 + * for more details.
3589 +#include <linux/config.h>
3590 +#include <linux/module.h>
3591 +#include <linux/kernel.h>
3592 +#include <linux/init.h>
3593 +#include <linux/sched.h>
3594 +#include <linux/irq.h>
3595 +#include <linux/tqueue.h>
3596 +#include <linux/locks.h>
3597 +#include <linux/completion.h>
3598 +#include <linux/delay.h>
3599 +#include <linux/slab.h>
3600 +#include <linux/vmalloc.h>
3601 +#include <linux/miscdevice.h>
3602 +#include <linux/wait.h>
3604 +#include <asm/io.h>
3605 +#include <asm/semaphore.h>
3606 +#include <asm/hardware.h>
3607 +#include <asm/uaccess.h>
3609 +#include <asm/arch/cpu_s3c2440.h>
3610 +#include <asm/arch/S3C2440.h>
3613 +#include "videodev.h"
3616 + Codec_formats/Preview_format[0] must be same to initial value of
3617 + preview_init_param/codec_init_param
3620 +const struct v4l2_fmtdesc codec_formats[] = {
3623 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
3624 +// .flags = FORMAT_FLAGS_PLANAR,
3625 + .description = "4:2:2, planar, Y-Cb-Cr",
3626 + .pixelformat = V4L2_PIX_FMT_YUV422P,
3630 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
3631 +// .flags = FORMAT_FLAGS_PLANAR,
3632 + .name = "4:2:0, planar, Y-Cb-Cr",
3633 + .fourcc = V4L2_PIX_FMT_YUV420,
3639 + FIMC V4L2_PIX_FMT_RGB565 is not same to that of V4L2spec
3640 + and so we need image convert to FIMC V4l2_PIX_FMT_RGB565.
3642 +const struct v4l2_fmtdesc preview_formats[] = {
3645 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
3646 + .description = "16 bpp RGB, le",
3647 + .fourcc = V4L2_PIX_FMT_RGB565,
3648 +// .flags = FORMAT_FLAGS_PACKED,
3652 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
3653 +// .flags = FORMAT_FLAGS_PACKED,
3654 + .description = "32 bpp RGB, le",
3655 + .fourcc = V4L2_PIX_FMT_BGR32,
3659 +#define NUM_F ARRARY_SIZE(preview_formats)
3663 + * This function and v4l2 structure made for V4L2 API functions
3664 + * App <--> v4l2 <--> logical param <--> hardware
3666 +static int camif_get_v4l2(camif_cfg_t *cfg)
3673 +** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
3675 +static int pixfmt2depth(int pixfmt,int *fmtptr)
3680 + case V4L2_PIX_FMT_RGB565:
3681 + case V4L2_PIX_FMT_RGB565X:
3682 + fmt = CAMIF_RGB_16;
3685 + case V4L2_PIX_FMT_BGR24: /* Not tested */
3686 + case V4L2_PIX_FMT_RGB24:
3687 + fmt = CAMIF_RGB_24;
3690 + case V4L2_PIX_FMT_BGR32:
3691 + case V4L2_PIX_FMT_RGB32:
3692 + fmt = CAMIF_RGB_24;
3695 + case V4L2_PIX_FMT_GREY: /* Not tested */
3696 + fmt = CAMIF_OUT_YCBCR420;
3699 + case V4L2_PIX_FMT_YUYV:
3700 + case V4L2_PIX_FMT_UYVY:
3701 + case V4L2_PIX_FMT_YUV422P:
3702 + fmt = CAMIF_OUT_YCBCR422;
3705 + case V4L2_PIX_FMT_YUV420:
3706 + fmt = CAMIF_OUT_YCBCR420;
3710 + if (fmtptr) *fmtptr = fmt;
3716 +static int camif_s_v4l2(camif_cfg_t *cfg)
3718 + int num = cfg->v2.used_fmt;
3720 + if ( !(cfg->v2.status&CAMIF_V4L2_INIT)) {
3722 + int fourcc = v2.fmtdesc[num].pixelformat;
3724 + /* To define v4l2_fmtsdesc */
3725 + if (cfg->dma_type == CAMIF_CODEC)
3726 + cfg->v2->fmtdesc = codec_formats;
3728 + cfg->v2->fmtdesc = preview_formats;
3730 + /* To define v4l2_format used currently */
3731 + cfg->v2.fmt.width = cfg->target_x;
3732 + cfg->v2.fmt.height = cfg->target_y;
3733 + cfg->v2.fmt.field = V4L2_FIELD_NONE;
3734 + cfg->v2.fmt.pixelformat = fourcc;
3735 + depth = pixfmt2depth(fourcc,NULL);
3736 + cfg->v2.fmt.bytesperline= cfg->v2.fmt.width*depth >> 3;
3737 + cfg->v2.fmt.sizeimage =
3738 + cfg->v2.fmt.height * cfg->v2.fmt.bytesperline;
3740 + /* To define v4l2_input */
3741 + cfg->v2.input.index = 0;
3742 + if (cfg->dma_type == CAMIF_CODEC)
3743 + snprintf(cfg->v2.input.name, 31, "CAMIF CODEC");
3745 + snprintf(cfg->v2.input.name, 31, "CAMIF PREVIEW");
3746 + cfg->v2.input.type = V4L2_INPUT_TYPE_CAMERA;
3748 + /* Write the Status of v4l2 machine */
3749 + cfg->v2.status |= CAMIF_V4L2_INIT;
3755 +static int camif_g_fmt(camif_cfg_t *cfg, struct v4l2_format *f)
3757 + int size = sizeof(struct v4l2_pix_format);
3759 + switch (f->type) {
3760 + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3761 + memset(&f->fmt.pix,0,size);
3762 + memcpy(&f->fmt.pix,&cfg->v2.fmt,size);
3770 +/* Copy v4l2 parameter into other element of camif_cfg_t */
3771 +static int camif_s_try(camif_cfg_t *cfg, int f)
3774 + cfg->target_x = cfg->v2.fmt.width;
3775 + cfg->target_y = cfg->v2.fmt.height;
3776 + pixfmt2depth(cfg->v2.fmt.pixelformat,&fmt);
3778 + camif_dynamic_conf(cfg);
3782 +static int camif_s_fmt(camif_cfg_t *cfg, struct v4l2_format *f)
3786 + switch (f->type) {
3787 + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3789 + /* update our state informations */
3790 +// down(&fh->cap.lock);
3791 + cfg->v2.fmt = f->pix;
3792 + cfg->v2.status |= CAMIF_v4L2_DIRTY;
3793 + camif_dynamic_conf(cfg);
3794 + cfg->v2.status &= ~CAMIF_v4L2_DIRTY; /* dummy ? */
3795 +// up(&fh->cap.lock);
3805 +/* Refer ioctl of videodeX.c and bttv-driver.c */
3807 +(struct inode *inode, struct file *file,unsigned int cmd, void * arg)
3809 + camif_cfg_t *cfg = file->private_data;
3813 + case VIDIOC_QUERYCAP:
3815 + struct v4l2_capability *cap = arg;
3817 + strcpy(cap->driver,"Fimc Camera");
3818 + strlcpy(cap->card,cfg->v->name,sizeof(cap->card));
3819 + sprintf(cap->bus_info,"FIMC 2.0 AHB Bus");
3821 + cap->capabilities =
3822 + V4L2_CAP_VIDEO_CAPTURE |V4L2_CAP_READWRITE;
3825 + case VIDIOC_G_FMT:
3827 + struct v4l2_format *f = arg;
3828 + return camif_g_fmt(cfg,f);
3830 + case VIDIOC_S_FMT:
3832 + struct v4l2_format *f = arg;
3833 + return camif_s_fmt(cfg,f);
3836 + case VIDIOC_ENUM_FMT:
3838 + struct v4l2_fmtdesc *f = arg;
3839 + enum v4l2_buf_type type = f->type;
3840 + int index = f->index;
3842 + if (index >= NUM_F)
3844 + switch (f->type) {
3845 + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3847 + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3848 + case V4L2_BUF_TYPE_VBI_CAPTURE:
3852 + memset(f,0,sizeof(*f));
3853 + memcpy(f,cfg->v2.fmtdesc+index,sizeof(*f));
3856 + case VIDIOC_G_INPUT:
3859 + *i = cfg->v2.input;
3862 + case VIDIOC_S_INPUT:
3864 + int index = *((int *)arg);
3867 + cfg->v2.input.index = index;
3872 + return -ENOIOCTLCMD; /* errno.h */
3873 + } /* End of Switch */
3885 + * Local variables:
3887 + * c-indent-level: 8
3888 + * c-basic-offset: 8
3889 + * c-set-style: "K&R"
3892 diff --git a/arch/arm/mach-s3c2440/camera/video-driver.c b/arch/arm/mach-s3c2440/camera/video-driver.c
3893 new file mode 100644
3894 index 0000000..fe9130c
3896 +++ b/arch/arm/mach-s3c2440/camera/video-driver.c
3899 + Copyright (C) 2004 Samsung Electronics
3900 + SW.LEE <hitchcar@sec.samsung.com>
3901 + This program is free software; you can redistribute it and/or modify
3902 + it under the terms of the GNU General Public License as published by
3903 + the Free Software Foundation; either version 2 of the License, or
3904 + (at your option) any later version.
3907 +#include <linux/version.h>
3908 +#include <linux/module.h>
3909 +#include <linux/delay.h>
3910 +#include <linux/errno.h>
3911 +#include <linux/fs.h>
3912 +#include <linux/kernel.h>
3913 +#include <linux/major.h>
3914 +#include <linux/slab.h>
3915 +#include <linux/poll.h>
3916 +#include <linux/signal.h>
3917 +#include <linux/ioport.h>
3918 +#include <linux/sched.h>
3919 +#include <linux/types.h>
3920 +#include <linux/interrupt.h>
3921 +#include <linux/kmod.h>
3922 +#include <linux/vmalloc.h>
3923 +#include <linux/init.h>
3924 +#include <asm/io.h>
3925 +#include <asm/page.h>
3926 +#include <asm/irq.h>
3927 +#include <asm/semaphore.h>
3928 +#include <linux/miscdevice.h>
3933 +#include "videodev.h"
3934 +#include "miscdevice.h"
3935 +#include "cam_reg.h"
3936 +#include "sensor.h"
3937 +#include "userapp.h"
3943 +/* Codec and Preview */
3944 +#define CAMIF_NUM 2
3945 +static camif_cfg_t fimc[CAMIF_NUM];
3947 +static const char *driver_version =
3948 + "$Id: video-driver.c,v 1.9 2004/06/02 03:10:36 swlee Exp $";
3949 +extern const char *fimc_version;
3950 +extern const char *fsm_version;
3953 +camif_cfg_t * get_camif(int nr)
3955 + camif_cfg_t *ret = NULL;
3960 + case PREVIEW_MINOR:
3964 + panic("Unknow Minor Number \n");
3970 +static int camif_codec_start(camif_cfg_t *cfg)
3973 + ret =camif_check_preview(cfg);
3975 + case 0: /* Play alone */
3976 + DPRINTK("Start Alone \n");
3977 + camif_4fsm_start(cfg);
3978 + cfg->gc->status |= C_WORKING;
3980 + case -ERESTARTSYS: /* Busy , retry */
3981 + //DPRINTK("Error \n");
3982 + printk("Error \n");
3985 + DPRINTK("need callback \n");
3986 + ret = camif_callback_start(cfg);
3988 + printk(KERN_INFO "Busy RESTART \n");
3989 + return ret; /* Busy, retry */
3997 +ssize_t camif_write (struct file *f, const char *b, size_t c,loff_t *offset)
4001 + c = 0; /* return value */
4003 + cfg = get_camif(MINOR(f->f_dentry->d_inode->i_rdev));
4006 + if (cfg->dma_type & CAMIF_PREVIEW) {
4007 + if (cfg->gc->status & C_WORKING) {
4008 + camif_start_c_with_p(cfg,get_camif(CODEC_MINOR));
4011 + camif_4fsm_start(cfg);
4015 + c = camif_codec_start(cfg);
4016 + if(c < 0) c = 1; /* Error and neet to retry */
4021 + camif_p_stop(cfg);
4024 + panic("CAMERA:camif_write: Unexpected Param\n");
4032 +ssize_t camif_p_read(struct file *file, char *buf, size_t count, loff_t *pos)
4034 + camif_cfg_t *cfg = NULL;
4037 + cfg = get_camif(MINOR(file->f_dentry->d_inode->i_rdev));
4038 + cfg->status = CAMIF_STARTED;
4040 + if (wait_event_interruptible(cfg->waitq,cfg->status == CAMIF_INT_HAPPEN))
4041 + return -ERESTARTSYS;
4043 + cfg->status = CAMIF_STOPPED;
4044 + end = min_t(size_t, cfg->pp_totalsize /cfg->pp_num, count);
4045 + if (copy_to_user(buf, camif_g_frame(cfg), end))
4053 +camif_c_read(struct file *file, char *buf, size_t count, loff_t *pos)
4055 + camif_cfg_t *cfg = NULL;
4058 + /* cfg = file->private_data; */
4059 + cfg = get_camif(MINOR(file->f_dentry->d_inode->i_rdev));
4061 + if(file->f_flags & O_NONBLOCK) {
4062 + printk(KERN_ERR"Don't Support NON_BLOCK \n");
4066 + /* Change the below wait_event_interruptible func */
4067 + if (wait_event_interruptible(cfg->waitq,cfg->status == CAMIF_INT_HAPPEN))
4068 + return -ERESTARTSYS;
4069 + cfg->status = CAMIF_STOPPED;
4070 + end = min_t(size_t, cfg->pp_totalsize /cfg->pp_num, count);
4071 + if (copy_to_user(buf, camif_g_frame(cfg), end))
4077 +static void camif_c_irq(int irq, void *dev_id, struct pt_regs *regs)
4079 + camif_cfg_t *cfg = (camif_cfg_t *)dev_id;
4081 + camif_g_fifo_status(cfg);
4082 + camif_g_frame_num(cfg);
4083 + if(camif_enter_c_4fsm(cfg) == INSTANT_SKIP) return;
4084 + wake_up_interruptible(&cfg->waitq);
4087 +static void camif_p_irq(int irq, void *dev_id, struct pt_regs * regs)
4089 + camif_cfg_t *cfg = (camif_cfg_t *)dev_id;
4091 + camif_g_fifo_status(cfg);
4092 + camif_g_frame_num(cfg);
4093 + if(camif_enter_p_4fsm(cfg) == INSTANT_SKIP) return;
4094 + wake_up_interruptible(&cfg->waitq);
4096 + if( (cfg->perf.frames % 5) == 0)
4101 +static void camif_release_irq(camif_cfg_t *cfg)
4103 + disable_irq(cfg->irq);
4104 + free_irq(cfg->irq, cfg);
4107 +static int camif_irq_request(camif_cfg_t *cfg)
4111 + if (cfg->dma_type & CAMIF_CODEC) {
4112 + if ((ret = request_irq(cfg->irq, camif_c_irq,
4113 + SA_INTERRUPT,cfg->shortname, cfg))) {
4114 + printk("request_irq(CAM_C) failed.\n");
4117 + if (cfg->dma_type & CAMIF_PREVIEW) {
4118 + if ((ret = request_irq(cfg->irq, camif_p_irq,
4119 + SA_INTERRUPT,cfg->shortname, cfg))) {
4120 + printk("request_irq(CAM_P) failed.\n");
4126 +static void camif_init_sensor(camif_cfg_t *cfg)
4128 + camif_gc_t *gc = cfg->gc;
4130 + panic("CAMERA:I2C Client(Img Sensor)Not registered\n");
4131 + if(!gc->init_sensor) {
4132 + camif_reset(gc->reset_type, gc->reset_udelay);
4133 + gc->sensor->driver->command(gc->sensor,SENSOR_INIT,NULL);
4134 + gc->init_sensor = 1; /*sensor init done */
4136 + gc->sensor->driver->command(gc->sensor, USER_ADD, NULL);
4139 +static int camif_open(struct inode *inode, struct file *file)
4142 + camif_cfg_t * cfg = get_camif(MINOR(inode->i_rdev));
4144 + if(cfg->dma_type & CAMIF_PREVIEW) {
4145 + if(down_interruptible(&cfg->gc->lock))
4146 + return -ERESTARTSYS;
4147 + if (cfg->dma_type & CAMIF_PREVIEW) {
4148 + cfg->gc->status &= ~PNOTWORKING;
4150 + up(&cfg->gc->lock);
4152 + err = video_exclusive_open(inode,file);
4154 + cfg->status = CAMIF_STOPPED;
4155 + if (err < 0) return err;
4156 + if (file->f_flags & O_NONCAP ) {
4157 + printk("Don't Support Non-capturing open \n");
4160 + file->private_data = cfg;
4161 + camif_irq_request(cfg);
4162 + camif_init_sensor(cfg);
4167 +static void print_pregs(void)
4169 + printk(" CISRCFMT 0x%08X \n", CISRCFMT);
4170 + printk(" CIWDOFST 0x%08X \n", CIWDOFST);
4171 + printk(" CIGCTRL 0x%08X \n", CIGCTRL);
4172 + printk(" CIPRTRGFMT 0x%08X \n", CIPRTRGFMT);
4173 + printk(" CIPRCTRL 0x%08X \n", CIPRCTRL);
4174 + printk(" CIPRSCPRERATIO 0x%08X \n", CIPRSCPRERATIO);
4175 + printk(" CIPRSCPREDST 0x%08X \n", CIPRSCPREDST);
4176 + printk(" CIPRSCCTRL 0x%08X \n", CIPRSCCTRL);
4177 + printk(" CIPRTAREA 0x%08X \n", CIPRTAREA);
4178 + printk(" CIPRSTATUS 0x%08X \n", CIPRSTATUS);
4179 + printk(" CIIMGCPT 0x%08X \n", CIIMGCPT);
4182 +static void print_cregs(void)
4184 + printk(" CISRCFMT 0x%08X \n", CISRCFMT);
4185 + printk(" CIWDOFST 0x%08X \n", CIWDOFST);
4186 + printk(" CIGCTRL 0x%08X \n", CIGCTRL);
4187 + printk(" CICOCTRL 0x%8X \n", CICOCTRL);
4188 + printk(" CICOSCPRERATIO 0x%08X \n", CICOSCPRERATIO);
4189 + printk(" CICOSCPREDST 0x%08X \n", CICOSCPREDST);
4190 + printk(" CICOSCCTRL 0x%08X \n", CICOSCCTRL);
4191 + printk(" CICOTAREA 0x%08X \n", CICOTAREA);
4192 + printk(" CICOSTATUS 0x%8X \n", CICOSTATUS);
4193 + printk(" CIIMGCPT 0x%08X \n", CIIMGCPT);
4198 +static int camif_release(struct inode *inode, struct file *file)
4200 + camif_cfg_t * cfg = get_camif(MINOR(inode->i_rdev));
4202 + //DPRINTK(" cfg->status 0x%0X cfg->gc->status 0x%0X \n", cfg->status,cfg->gc->status );
4203 + if (cfg->dma_type & CAMIF_PREVIEW) {
4204 + if(down_interruptible(&cfg->gc->lock))
4205 + return -ERESTARTSYS;
4206 + cfg->gc->status &= ~PWANT2START;
4207 + cfg->gc->status |= PNOTWORKING;
4208 + up(&cfg->gc->lock);
4211 + cfg->gc->status &= ~CWANT2START; /* No need semaphore */
4213 + camif_dynamic_close(cfg);
4214 + camif_release_irq(cfg);
4215 + video_exclusive_release(inode,file);
4216 + camif_p_stop(cfg);
4217 + cfg->gc->sensor->driver->command(cfg->gc->sensor, USER_EXIT, NULL);
4219 + cfg->status = CAMIF_STOPPED;
4223 +static void fimc_config(camif_cfg_t *cfg,u32 x, u32 y, int bpp)
4225 + cfg->target_x = x;
4226 + cfg->target_y = y;
4230 + cfg->fmt = CAMIF_RGB16;
4233 + cfg->fmt = CAMIF_RGB24;
4236 + cfg->fmt = CAMIF_IN_YCBCR422|CAMIF_OUT_YCBCR420;
4239 + cfg->fmt = CAMIF_IN_YCBCR422|CAMIF_OUT_YCBCR422;
4242 + panic("Wrong BPP \n");
4248 +camif_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
4251 + camif_cfg_t *cfg = file->private_data;
4252 + camif_param_t par;
4255 + case CMD_CAMERA_INIT:
4256 + if (copy_from_user(&par,(camif_param_t *)arg,
4257 + sizeof(camif_param_t)))
4259 + fimc_config(cfg,par.dst_x, par.dst_y, par.bpp);
4260 + if (camif_dynamic_open(cfg)) {
4261 + printk(" Eror Happens \n");
4265 + switch (par.flip) {
4267 + cfg->flip = CAMIF_FLIP_MIRROR;
4270 + cfg->flip = CAMIF_FLIP_X;
4273 + cfg->flip = CAMIF_FLIP_Y;
4277 + cfg->flip = CAMIF_FLIP;
4281 + case CMD_SENSOR_BRIGHTNESS:
4282 + cfg->gc->sensor->driver->command(cfg->gc->sensor, SENSOR_BRIGHTNESS, NULL);
4295 +static int camif_ioctl(struct inode *inode, struct file *file,
4296 + unsigned int cmd, unsigned long arg)
4298 +// camif_cfg_t *cfg = file->private_data;
4302 +/* case Some_other_action */
4304 + return video_usercopy(inode, file, cmd, arg, camif_do_ioctl);
4309 +static struct file_operations camif_c_fops =
4311 + .owner = THIS_MODULE,
4312 + .open = camif_open,
4313 + .release = camif_release,
4314 + .ioctl = camif_ioctl,
4315 + .read = camif_c_read,
4316 + .write = camif_write,
4319 +static struct file_operations camif_p_fops =
4321 + .owner = THIS_MODULE,
4322 + .open = camif_open,
4323 + .release = camif_release,
4324 + .ioctl = camif_ioctl,
4329 + .read = camif_p_read,
4330 + .write = camif_write,
4334 +static struct video_device codec_template =
4336 + .name = "CODEC_IF",
4337 + .type = VID_TYPE_CAPTURE|VID_TYPE_CLIPPING|VID_TYPE_SCALES,
4338 + .hardware = VID_HARDWARE_SAMSUNG_FIMC20,
4339 + .fops = &camif_c_fops,
4340 +// .release = camif_release
4344 +static struct video_device preview_template =
4346 + .name = "PREVIEW_IF",
4347 + .type = VID_TYPE_CAPTURE|VID_TYPE_CLIPPING|VID_TYPE_SCALES,
4348 + .hardware = VID_HARDWARE_SAMSUNG_FIMC20,
4349 + .fops = &camif_p_fops,
4353 +static int preview_init(camif_cfg_t *cfg)
4355 + char name[16]="CAM_PREVIEW";
4357 + memset(cfg, 0, sizeof(camif_cfg_t));
4358 + cfg->target_x = 640;
4359 + cfg->target_y = 480;
4361 + cfg->dma_type = CAMIF_PREVIEW;
4362 + cfg->fmt = CAMIF_RGB16;
4363 + cfg->flip = CAMIF_FLIP_Y;
4364 + cfg->v = &preview_template;
4365 + init_MUTEX(&cfg->v->lock);
4366 + cfg->irq = IRQ_CAM_P;
4368 + strcpy(cfg->shortname,name);
4369 + init_waitqueue_head(&cfg->waitq);
4370 + cfg->status = CAMIF_STOPPED;
4371 + return cfg->status;
4374 +static int codec_init(camif_cfg_t *cfg)
4376 + char name[16]="CAM_CODEC";
4378 + memset(cfg, 0, sizeof(camif_cfg_t));
4379 + cfg->target_x = 176;
4380 + cfg->target_y = 144;
4382 + cfg->dma_type = CAMIF_CODEC;
4383 + cfg->fmt = CAMIF_IN_YCBCR422|CAMIF_OUT_YCBCR420;
4384 + cfg->flip = CAMIF_FLIP_X;
4385 + cfg->v = &codec_template;
4386 + init_MUTEX(&cfg->v->lock);
4387 + cfg->irq = IRQ_CAM_C;
4388 + strcpy(cfg->shortname,name);
4389 + init_waitqueue_head(&cfg->waitq);
4390 + cfg->status = CAMIF_STOPPED;
4391 + return cfg->status;
4394 +static void camif_init(void)
4396 + camif_setup_sensor();
4401 +static void print_version(void)
4403 + printk(KERN_INFO"FIMC built:"__DATE__ " "__TIME__"\n%s\n%s\n%s\n",
4404 + fimc_version, driver_version,fsm_version);
4408 +static int camif_m_in(void)
4411 + camif_cfg_t * cfg;
4414 + cfg = get_camif(CODEC_MINOR);
4417 + if (video_register_device(cfg->v,0,CODEC_MINOR)!=0) {
4418 + DPRINTK("Couldn't register codec driver.\n");
4421 + cfg = get_camif(PREVIEW_MINOR);
4422 + preview_init(cfg);
4423 + if (video_register_device(cfg->v,0,PREVIEW_MINOR)!=0) {
4424 + DPRINTK("Couldn't register preview driver.\n");
4432 +static void unconfig_device(camif_cfg_t *cfg)
4434 + video_unregister_device(cfg->v);
4435 + camif_hw_close(cfg);
4436 + //memset(cfg, 0, sizeof(camif_cfg_t));
4439 +static void camif_m_out(void) /* module out */
4443 + cfg = get_camif(CODEC_MINOR);
4444 + unconfig_device(cfg);
4445 + cfg = get_camif(PREVIEW_MINOR);
4446 + unconfig_device(cfg);
4450 +void camif_register_decoder(struct i2c_client *ptr)
4454 + cfg =get_camif(CODEC_MINOR);
4455 + cfg->gc = (camif_gc_t *)(ptr->data);
4457 + cfg =get_camif(PREVIEW_MINOR);
4458 + cfg->gc = (camif_gc_t *)(ptr->data);
4460 + sema_init(&cfg->gc->lock,1); /* global lock for both Codec and Preview */
4461 + cfg->gc->status |= PNOTWORKING; /* Default Value */
4462 + camif_hw_open(cfg->gc);
4465 +void camif_unregister_decoder(struct i2c_client *ptr)
4469 + gc = (camif_gc_t *)(ptr->data);
4470 + gc->init_sensor = 0; /* need to modify */
4473 +module_init(camif_m_in);
4474 +module_exit(camif_m_out);
4476 +EXPORT_SYMBOL(camif_register_decoder);
4477 +EXPORT_SYMBOL(camif_unregister_decoder);
4479 +MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");
4480 +MODULE_DESCRIPTION("Video-Driver For Fimc2.0 MISC Drivers");
4481 +MODULE_LICENSE("GPL");
4485 + * Local variables:
4486 + * c-basic-offset: 8
4489 diff --git a/arch/arm/mach-s3c2440/camera/videodev.c b/arch/arm/mach-s3c2440/camera/videodev.c
4490 new file mode 100644
4491 index 0000000..0b3498f
4493 +++ b/arch/arm/mach-s3c2440/camera/videodev.c
4496 + * Video capture interface for Linux Character Device Driver.
4498 + * Alan Cox, <alan@redhat.com> video4linux
4500 + * Author: SW.LEE <hitchcar@samsung.com>
4501 + * 2004 (C) Samsung Electronics
4502 + * Modified for S3C2440/S3C24A0 Interface
4504 + * This file is released under the GPLv2
4508 +#include <linux/module.h>
4509 +#include <linux/types.h>
4510 +#include <linux/kernel.h>
4511 +#include <linux/sched.h>
4512 +#include <linux/smp_lock.h>
4513 +#include <linux/mm.h>
4514 +#include <linux/string.h>
4515 +#include <linux/errno.h>
4516 +#include <linux/init.h>
4517 +#include <linux/kmod.h>
4518 +#include <linux/slab.h>
4519 +#include <linux/devfs_fs_kernel.h>
4520 +#include <linux/miscdevice.h>
4521 +#include <asm/uaccess.h>
4522 +#include <asm/system.h>
4523 +#include <asm/semaphore.h>
4528 +#include "videodev.h"
4529 +#include "miscdevice.h"
4532 +static DECLARE_MUTEX(videodev_lock);
4534 +const char *fimc_version = "$Id: videodev.c,v 1.1.1.1 2004/04/27 03:52:50 swlee Exp $";
4536 +#define VIDEO_NAME "video4linux"
4539 +static inline unsigned iminor(struct inode *inode)
4541 + return MINOR(inode->i_rdev);
4544 +static inline unsigned imajor(struct inode *inode)
4546 + return MAJOR(inode->i_rdev);
4550 +#define VIDEO_NUM_DEVICES 2
4551 +static struct video_device *video_device[VIDEO_NUM_DEVICES];
4553 +static inline struct video_device * get_vd(int nr)
4555 + if ( nr == CODEC_MINOR)
4556 + return video_device[0];
4558 + assert ( nr & PREVIEW_MINOR);
4559 + return video_device[1];
4563 +static inline void set_vd ( struct video_device * vd, int nr)
4565 + if ( nr == CODEC_MINOR)
4566 + video_device[0] = vd;
4568 + assert ( nr & PREVIEW_MINOR);
4569 + video_device[1] = vd;
4573 +static inline int video_release(struct inode *inode, struct file *f)
4575 + int minor = MINOR(inode->i_rdev);
4576 + struct video_device *vfd;
4578 + vfd = get_vd(minor);
4579 +#if 1 /* needed until all drivers are fixed */
4580 + if (!vfd->release)
4583 + vfd->release(vfd);
4587 +struct video_device* video_devdata(struct file *file)
4589 + return video_device[iminor(file->f_dentry->d_inode)];
4594 + * Open a video device.
4596 +static int video_open(struct inode *inode, struct file *file)
4598 + int minor = MINOR(inode->i_rdev);
4600 + struct video_device *vfl;
4601 + struct file_operations *old_fops;
4603 + down(&videodev_lock);
4605 + vfl = get_vd(minor);
4607 + old_fops = file->f_op;
4608 + file->f_op = fops_get(vfl->fops);
4609 + if(file->f_op->open)
4610 + err = file->f_op->open(inode,file);
4612 + fops_put(file->f_op);
4613 + file->f_op = fops_get(old_fops);
4615 + fops_put(old_fops);
4616 + up(&videodev_lock);
4621 + * open/release helper functions -- handle exclusive opens
4623 +extern int video_exclusive_open(struct inode *inode, struct file *file)
4625 + struct video_device *vfl = get_vd(MINOR(inode->i_rdev));
4638 +extern int video_exclusive_release(struct inode *inode, struct file *file)
4640 + struct video_device *vfl = get_vd(MINOR(inode->i_rdev));
4646 +video_usercopy(struct inode *inode, struct file *file,
4647 + unsigned int cmd, unsigned long arg,
4648 + int (*func)(struct inode *inode, struct file *file,
4649 + unsigned int cmd, void *arg))
4652 + void *mbuf = NULL;
4653 + void *parg = NULL;
4654 + int err = -EINVAL;
4656 + // cmd = video_fix_command(cmd);
4658 + /* Copy arguments into temp kernel buffer */
4659 + switch (_IOC_DIR(cmd)) {
4661 + parg = (void *)arg;
4665 + case (_IOC_WRITE | _IOC_READ):
4666 + if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
4669 + /* too big to allocate from stack */
4670 + mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
4677 + if (_IOC_DIR(cmd) & _IOC_WRITE)
4678 + if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd)))
4684 + err = func(inode, file, cmd, parg);
4685 + if (err == -ENOIOCTLCMD)
4690 + /* Copy results into user buffer */
4691 + switch (_IOC_DIR(cmd))
4694 + case (_IOC_WRITE | _IOC_READ):
4695 + if (copy_to_user((void *)arg, parg, _IOC_SIZE(cmd)))
4707 +static struct file_operations video_fops=
4709 + .owner = THIS_MODULE,
4710 + .llseek = no_llseek,
4711 + .open = video_open,
4712 + .release = video_release,
4715 +static struct miscdevice codec_dev = {
4716 + minor: CODEC_MINOR,
4718 + fops : &video_fops
4721 +static struct miscdevice preview_dev = {
4722 + minor: PREVIEW_MINOR,
4724 + fops : &video_fops
4729 + * video_register_device - register video4linux devices
4730 + * @vfd: video device structure we want to register
4731 + * @type: type of device to register
4732 + * @nr: minor number
4734 + * Zero is returned on success.
4740 +int video_register_device(struct video_device *vfd, int type, int nr)
4744 + /* pick a minor number */
4745 + down(&videodev_lock);
4748 + up(&videodev_lock);
4750 + switch (vfd->minor) {
4752 + ret = misc_register(&codec_dev);
4755 + "can't misc_register : codec on minor=%d\n", CODEC_MINOR);
4756 + panic(" Give me misc codec \n");
4759 + case PREVIEW_MINOR:
4760 + ret = misc_register(&preview_dev);
4763 + "can't misc_register (preview) on minor=%d\n", PREVIEW_MINOR);
4764 + panic(" Give me misc codec \n");
4769 +#if 0 /* needed until all drivers are fixed */
4770 + if (!vfd->release)
4771 + printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
4772 + "Please fix your driver for proper sysfs support, see "
4773 + "http://lwn.net/Articles/36850/\n", vfd->name);
4779 + * video_unregister_device - unregister a video4linux device
4780 + * @vfd: the device to unregister
4782 + * This unregisters the passed device and deassigns the minor
4783 + * number. Future open calls will be met with errors.
4786 +void video_unregister_device(struct video_device *vfd)
4788 + down(&videodev_lock);
4790 + if(get_vd(vfd->minor)!=vfd)
4791 + panic("videodev: bad unregister");
4793 + if (vfd->minor== CODEC_MINOR)
4794 + misc_deregister(&codec_dev);
4796 + misc_deregister(&preview_dev);
4797 + set_vd (NULL, vfd->minor);
4798 + up(&videodev_lock);
4803 + * Initialise video for linux
4806 +static int __init videodev_init(void)
4808 +// printk(KERN_INFO "FIMC2.0 Built:"__DATE__" "__TIME__"\n%s\n",fimc_version);
4812 +static void __exit videodev_exit(void)
4816 +module_init(videodev_init)
4817 +module_exit(videodev_exit)
4819 +EXPORT_SYMBOL(video_register_device);
4820 +EXPORT_SYMBOL(fimc_version);
4821 +EXPORT_SYMBOL(video_unregister_device);
4822 +EXPORT_SYMBOL(video_usercopy);
4823 +EXPORT_SYMBOL(video_exclusive_open);
4824 +EXPORT_SYMBOL(video_exclusive_release);
4827 +MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");
4828 +MODULE_DESCRIPTION("VideoDev For FIMC2.0 MISC Drivers");
4829 +MODULE_LICENSE("GPL");
4833 + * Local variables:
4834 + * c-basic-offset: 8
4837 diff --git a/arch/arm/mach-s3c2440/camera/videodev.h b/arch/arm/mach-s3c2440/camera/videodev.h
4838 new file mode 100644
4839 index 0000000..f12db43
4841 +++ b/arch/arm/mach-s3c2440/camera/videodev.h
4843 +#ifndef __LINUX_S3C_VIDEODEV_H
4844 +#define __LINUX_S3C_VIDEODEV_H
4846 +#include <linux/types.h>
4847 +#include <linux/version.h>
4848 +#include "videodev2.h"
4851 +struct video_device
4854 + // struct device *dev;
4856 + int type; /* v4l1 */
4857 + int type2; /* v4l2 */
4861 + /* device ops + callbacks */
4862 + struct file_operations *fops;
4863 + void (*release)(struct video_device *vfd);
4866 +#if 1 /* to be removed in 2.7.x */
4867 + /* obsolete -- fops->owner is used instead */
4868 + struct module *owner;
4869 + /* dev->driver_data will be used instead some day.
4870 + * Use the video_{get|set}_drvdata() helper functions,
4871 + * so the switch over will be transparent for you.
4872 + * Or use {pci|usb}_{get|set}_drvdata() directly. */
4876 + /* for videodev.c intenal usage -- please don't touch */
4877 + int users; /* video_exclusive_{open|close} ... */
4878 + struct semaphore lock; /* ... helper function uses these */
4879 + char devfs_name[64]; /* devfs */
4880 + // struct class_device class_dev; /* sysfs */
4883 +#define VIDEO_MAJOR 81
4885 +#define VFL_TYPE_GRABBER 0
4888 +extern int video_register_device(struct video_device *, int type, int nr);
4889 +extern void video_unregister_device(struct video_device *);
4890 +extern struct video_device* video_devdata(struct file*);
4894 +struct video_picture
4900 + __u16 whiteness; /* Black and white only */
4901 + __u16 depth; /* Capture depth */
4902 + __u16 palette; /* Palette in use */
4903 +#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
4904 +#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
4905 +#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
4906 +#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
4907 +#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
4908 +#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
4909 +#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
4910 +#define VIDEO_PALETTE_YUYV 8
4911 +#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
4912 +#define VIDEO_PALETTE_YUV420 10
4913 +#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
4914 +#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
4915 +#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
4916 +#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
4917 +#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
4918 +#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
4919 +#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
4920 +#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
4923 +extern int video_exclusive_open(struct inode *inode, struct file *file);
4924 +extern int video_exclusive_release(struct inode *inode, struct file *file);
4925 +extern int video_usercopy(struct inode *inode, struct file *file,
4926 + unsigned int cmd, unsigned long arg,
4927 + int (*func)(struct inode *inode, struct file *file,
4928 + unsigned int cmd, void *arg));
4933 +#define VID_TYPE_CAPTURE 1 /* Can capture */
4934 +#define VID_TYPE_CLIPPING 32 /* Can clip */
4935 +#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
4936 +#define VID_TYPE_SCALES 128 /* Scalable */
4937 +#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
4941 +#define VID_HARDWARE_SAMSUNG_FIMC 255
4949 + * Local variables:
4950 + * c-basic-offset: 8
4953 diff --git a/arch/arm/mach-s3c2440/camera/videodev2.h b/arch/arm/mach-s3c2440/camera/videodev2.h
4954 new file mode 100644
4955 index 0000000..1bfc45a
4957 +++ b/arch/arm/mach-s3c2440/camera/videodev2.h
4959 +#ifndef __LINUX_VIDEODEV2_H
4960 +#define __LINUX_VIDEODEV2_H
4962 + * Video for Linux Two
4964 + * Header file for v4l or V4L2 drivers and applications, for
4965 + * Linux kernels 2.2.x or 2.4.x.
4967 + * See http://bytesex.org/v4l/ for API specs and other
4968 + * v4l2 documentation.
4970 + * Author: Bill Dirks <bdirks@pacbell.net>
4975 +#include <linux/time.h> /* need struct timeval */
4979 + * M I S C E L L A N E O U S
4982 +/* Four-character-code (FOURCC) */
4983 +#define v4l2_fourcc(a,b,c,d)\
4984 + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
4990 + V4L2_FIELD_ANY = 0, /* driver can choose from none,
4991 + top, bottom, interlaced
4992 + depending on whatever it thinks
4993 + is approximate ... */
4994 + V4L2_FIELD_NONE = 1, /* this device has no fields ... */
4995 + V4L2_FIELD_TOP = 2, /* top field only */
4996 + V4L2_FIELD_BOTTOM = 3, /* bottom field only */
4997 + V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
4998 + V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one
4999 + buffer, top-bottom order */
5000 + V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */
5001 + V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into
5002 + separate buffers */
5004 +#define V4L2_FIELD_HAS_TOP(field) \
5005 + ((field) == V4L2_FIELD_TOP ||\
5006 + (field) == V4L2_FIELD_INTERLACED ||\
5007 + (field) == V4L2_FIELD_SEQ_TB ||\
5008 + (field) == V4L2_FIELD_SEQ_BT)
5009 +#define V4L2_FIELD_HAS_BOTTOM(field) \
5010 + ((field) == V4L2_FIELD_BOTTOM ||\
5011 + (field) == V4L2_FIELD_INTERLACED ||\
5012 + (field) == V4L2_FIELD_SEQ_TB ||\
5013 + (field) == V4L2_FIELD_SEQ_BT)
5014 +#define V4L2_FIELD_HAS_BOTH(field) \
5015 + ((field) == V4L2_FIELD_INTERLACED ||\
5016 + (field) == V4L2_FIELD_SEQ_TB ||\
5017 + (field) == V4L2_FIELD_SEQ_BT)
5019 +enum v4l2_buf_type {
5020 + V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
5021 + V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
5022 + V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
5023 + V4L2_BUF_TYPE_VBI_CAPTURE = 4,
5024 + V4L2_BUF_TYPE_VBI_OUTPUT = 5,
5025 + V4L2_BUF_TYPE_PRIVATE = 0x80,
5028 +enum v4l2_ctrl_type {
5029 + V4L2_CTRL_TYPE_INTEGER = 1,
5030 + V4L2_CTRL_TYPE_BOOLEAN = 2,
5031 + V4L2_CTRL_TYPE_MENU = 3,
5032 + V4L2_CTRL_TYPE_BUTTON = 4,
5035 +enum v4l2_tuner_type {
5036 + V4L2_TUNER_RADIO = 1,
5037 + V4L2_TUNER_ANALOG_TV = 2,
5041 + V4L2_MEMORY_MMAP = 1,
5042 + V4L2_MEMORY_USERPTR = 2,
5043 + V4L2_MEMORY_OVERLAY = 3,
5046 +/* see also http://vektor.theorem.ca/graphics/ycbcr/ */
5047 +enum v4l2_colorspace {
5048 + /* ITU-R 601 -- broadcast NTSC/PAL */
5049 + V4L2_COLORSPACE_SMPTE170M = 1,
5051 + /* 1125-Line (US) HDTV */
5052 + V4L2_COLORSPACE_SMPTE240M = 2,
5054 + /* HD and modern captures. */
5055 + V4L2_COLORSPACE_REC709 = 3,
5057 + /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
5058 + V4L2_COLORSPACE_BT878 = 4,
5060 + /* These should be useful. Assume 601 extents. */
5061 + V4L2_COLORSPACE_470_SYSTEM_M = 5,
5062 + V4L2_COLORSPACE_470_SYSTEM_BG = 6,
5064 + /* I know there will be cameras that send this. So, this is
5065 + * unspecified chromaticities and full 0-255 on each of the
5066 + * Y'CbCr components
5068 + V4L2_COLORSPACE_JPEG = 7,
5070 + /* For RGB colourspaces, this is probably a good start. */
5071 + V4L2_COLORSPACE_SRGB = 8,
5074 +enum v4l2_priority {
5075 + V4L2_PRIORITY_UNSET = 0, /* not initialized */
5076 + V4L2_PRIORITY_BACKGROUND = 1,
5077 + V4L2_PRIORITY_INTERACTIVE = 2,
5078 + V4L2_PRIORITY_RECORD = 3,
5079 + V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE,
5089 +struct v4l2_fract {
5091 + __u32 denominator;
5095 + * D R I V E R C A P A B I L I T I E S
5097 +struct v4l2_capability
5099 + __u8 driver[16]; /* i.e. "bttv" */
5100 + __u8 card[32]; /* i.e. "Hauppauge WinTV" */
5101 + __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */
5102 + __u32 version; /* should use KERNEL_VERSION() */
5103 + __u32 capabilities; /* Device capabilities */
5104 + __u32 reserved[4];
5107 +/* Values for 'capabilities' field */
5108 +#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
5109 +#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
5110 +#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
5111 +#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a VBI capture device */
5112 +#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a VBI output device */
5113 +#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
5115 +#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
5116 +#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
5117 +#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
5119 +#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
5120 +#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
5121 +#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
5124 + * V I D E O I M A G E F O R M A T
5127 +struct v4l2_pix_format
5131 + __u32 pixelformat;
5132 + enum v4l2_field field;
5133 + __u32 bytesperline; /* for padding, zero if unused */
5135 + enum v4l2_colorspace colorspace;
5136 + __u32 priv; /* private data, depends on pixelformat */
5139 +/* Pixel format FOURCC depth Description */
5140 +#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1') /* 8 RGB-3-3-2 */
5141 +#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O') /* 16 RGB-5-5-5 */
5142 +#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P') /* 16 RGB-5-6-5 */
5143 +#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16 RGB-5-5-5 BE */
5144 +#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16 RGB-5-6-5 BE */
5145 +#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3') /* 24 BGR-8-8-8 */
5146 +#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3') /* 24 RGB-8-8-8 */
5147 +#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */
5148 +#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */
5149 +#define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */
5150 +#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */
5151 +#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */
5152 +#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */
5153 +#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */
5154 +#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16 YVU422 planar */
5155 +#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16 YVU411 planar */
5156 +#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P') /* 12 YUV 4:1:1 */
5158 +/* two planes -- one Y, one Cr + Cb interleaved */
5159 +#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2') /* 12 Y/CbCr 4:2:0 */
5160 +#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1') /* 12 Y/CrCb 4:2:0 */
5162 +/* The following formats are not defined in the V4L2 specification */
5163 +#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */
5164 +#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */
5165 +#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */
5166 +#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4') /* 8 8-bit color */
5168 +/* compressed formats */
5169 +#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */
5170 +#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G') /* JFIF JPEG */
5171 +#define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d') /* 1394 */
5172 +#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G') /* MPEG */
5174 +/* Vendor-specific formats */
5175 +#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */
5178 + * F O R M A T E N U M E R A T I O N
5180 +struct v4l2_fmtdesc
5182 + __u32 index; /* Format number */
5183 + enum v4l2_buf_type type; /* buffer type */
5185 + __u8 description[32]; /* Description string */
5186 + __u32 pixelformat; /* Format fourcc */
5187 + __u32 reserved[4];
5190 +#define V4L2_FMT_FLAG_COMPRESSED 0x0001
5196 +struct v4l2_timecode
5208 +#define V4L2_TC_TYPE_24FPS 1
5209 +#define V4L2_TC_TYPE_25FPS 2
5210 +#define V4L2_TC_TYPE_30FPS 3
5211 +#define V4L2_TC_TYPE_50FPS 4
5212 +#define V4L2_TC_TYPE_60FPS 5
5215 +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */
5216 +#define V4L2_TC_FLAG_COLORFRAME 0x0002
5217 +#define V4L2_TC_USERBITS_field 0x000C
5218 +#define V4L2_TC_USERBITS_USERDEFINED 0x0000
5219 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008
5220 +/* The above is based on SMPTE timecodes */
5224 + * C O M P R E S S I O N P A R A M E T E R S
5227 +/* ### generic compression settings don't work, there is too much
5228 + * ### codec-specific stuff. Maybe reuse that for MPEG codec settings
5229 + * ### later ... */
5230 +struct v4l2_compression
5233 + __u32 keyframerate;
5235 + __u32 reserved[5];
5237 +/* what we'll need for MPEG, extracted from some postings on
5238 + the v4l list (Gert Vervoort, PlasmaJohn).
5241 + - type: elementary stream(ES), packatised elementary stream(s) (PES)
5242 + program stream(PS), transport stream(TS)
5244 + - PS packet size (DVD: 2048 bytes, VCD: 2324 bytes)
5248 + - TS system information tables (PAT, PMT, CAT, NIT and SIT)
5249 + - (MPEG-1 systems stream vs. MPEG-2 program stream (TS not supported
5250 + by MPEG-1 systems)
5253 + - type: MPEG (+Layer I,II,III), AC-3, LPCM
5255 + - sampling frequency (DVD: 48 Khz, VCD: 44.1 KHz, 32 kHz)
5256 + - Trick Modes? (ff, rew)
5258 + - Inverse Telecine
5261 + - picturesize (SIF, 1/2 D1, 2/3 D1, D1) and PAL/NTSC norm can be set
5262 + through excisting V4L2 controls
5263 + - noise reduction, parameters encoder specific?
5264 + - MPEG video version: MPEG-1, MPEG-2
5265 + - GOP (Group Of Pictures) definition:
5266 + - N: number of frames per GOP
5267 + - M: distance between reference (I,P) frames
5269 + - quantiser matrix: inter Q matrix (64 bytes) and intra Q matrix (64 bytes)
5270 + - quantiser scale: linear or logarithmic
5271 + - scanning: alternate or zigzag
5272 + - bitrate mode: CBR (constant bitrate) or VBR (variable bitrate).
5273 + - target video bitrate for CBR
5274 + - target video bitrate for VBR
5275 + - maximum video bitrate for VBR - min. quantiser value for VBR
5276 + - max. quantiser value for VBR
5277 + - adaptive quantisation value
5278 + - return the number of bytes per GOP or bitrate for bitrate monitoring
5284 +struct v4l2_jpegcompression
5288 + int APPn; /* Number of APP segment to be written,
5289 + * must be 0..15 */
5290 + int APP_len; /* Length of data in JPEG APPn segment */
5291 + char APP_data[60]; /* Data in the JPEG APPn segment. */
5293 + int COM_len; /* Length of data in JPEG COM segment */
5294 + char COM_data[60]; /* Data in JPEG COM segment */
5296 + __u32 jpeg_markers; /* Which markers should go into the JPEG
5297 + * output. Unless you exactly know what
5298 + * you do, leave them untouched.
5299 + * Inluding less markers will make the
5300 + * resulting code smaller, but there will
5301 + * be fewer aplications which can read it.
5302 + * The presence of the APP and COM marker
5303 + * is influenced by APP_len and COM_len
5304 + * ONLY, not by this property! */
5306 +#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
5307 +#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
5308 +#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
5309 +#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
5310 +#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will
5311 + * allways use APP0 */
5316 + * M E M O R Y - M A P P I N G B U F F E R S
5318 +struct v4l2_requestbuffers
5321 + enum v4l2_buf_type type;
5322 + enum v4l2_memory memory;
5323 + __u32 reserved[2];
5329 + enum v4l2_buf_type type;
5332 + enum v4l2_field field;
5333 + struct timeval timestamp;
5334 + struct v4l2_timecode timecode;
5337 + /* memory location */
5338 + enum v4l2_memory memory;
5341 + unsigned long userptr;
5345 + __u32 reserved[2];
5348 +/* Flags for 'flags' field */
5349 +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */
5350 +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */
5351 +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */
5352 +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */
5353 +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */
5354 +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */
5355 +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
5358 + * O V E R L A Y P R E V I E W
5360 +struct v4l2_framebuffer
5364 +/* FIXME: in theory we should pass something like PCI device + memory
5365 + * region + offset instead of some physical address */
5367 + struct v4l2_pix_format fmt;
5369 +/* Flags for the 'capability' field. Read only */
5370 +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001
5371 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002
5372 +#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
5373 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
5374 +/* Flags for the 'flags' field. */
5375 +#define V4L2_FBUF_FLAG_PRIMARY 0x0001
5376 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002
5377 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
5381 + struct v4l2_rect c;
5382 + struct v4l2_clip *next;
5387 + struct v4l2_rect w;
5388 + enum v4l2_field field;
5390 + struct v4l2_clip *clips;
5397 + * C A P T U R E P A R A M E T E R S
5399 +struct v4l2_captureparm
5401 + __u32 capability; /* Supported modes */
5402 + __u32 capturemode; /* Current mode */
5403 + struct v4l2_fract timeperframe; /* Time per frame in .1us units */
5404 + __u32 extendedmode; /* Driver-specific extensions */
5405 + __u32 readbuffers; /* # of buffers for read */
5406 + __u32 reserved[4];
5408 +/* Flags for 'capability' and 'capturemode' fields */
5409 +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */
5410 +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */
5412 +struct v4l2_outputparm
5414 + __u32 capability; /* Supported modes */
5415 + __u32 outputmode; /* Current mode */
5416 + struct v4l2_fract timeperframe; /* Time per frame in seconds */
5417 + __u32 extendedmode; /* Driver-specific extensions */
5418 + __u32 writebuffers; /* # of buffers for write */
5419 + __u32 reserved[4];
5423 + * I N P U T I M A G E C R O P P I N G
5426 +struct v4l2_cropcap {
5427 + enum v4l2_buf_type type;
5428 + struct v4l2_rect bounds;
5429 + struct v4l2_rect defrect;
5430 + struct v4l2_fract pixelaspect;
5434 + enum v4l2_buf_type type;
5435 + struct v4l2_rect c;
5439 + * A N A L O G V I D E O S T A N D A R D
5442 +typedef __u64 v4l2_std_id;
5444 +/* one bit for each */
5445 +#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
5446 +#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
5447 +#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
5448 +#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
5449 +#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
5450 +#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
5451 +#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
5452 +#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
5454 +#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
5455 +#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
5456 +#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
5457 +#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
5459 +#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
5460 +#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
5462 +#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
5463 +#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
5464 +#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
5465 +#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
5466 +#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
5467 +#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
5468 +#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
5471 +#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
5472 +#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
5474 +/* some common needed stuff */
5475 +#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
5476 + V4L2_STD_PAL_B1 |\
5478 +#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\
5479 + V4L2_STD_PAL_D1 |\
5481 +#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
5482 + V4L2_STD_PAL_DK |\
5485 +#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
5486 + V4L2_STD_NTSC_M_JP)
5487 +#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
5488 + V4L2_STD_SECAM_D |\
5489 + V4L2_STD_SECAM_G |\
5490 + V4L2_STD_SECAM_H |\
5491 + V4L2_STD_SECAM_K |\
5492 + V4L2_STD_SECAM_K1 |\
5495 +#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
5496 + V4L2_STD_PAL_60 |\
5498 +#define V4L2_STD_625_50 (V4L2_STD_PAL |\
5500 + V4L2_STD_PAL_Nc |\
5503 +#define V4L2_STD_UNKNOWN 0
5504 +#define V4L2_STD_ALL (V4L2_STD_525_60 |\
5507 +struct v4l2_standard
5512 + struct v4l2_fract frameperiod; /* Frames, not fields */
5514 + __u32 reserved[4];
5519 + * V I D E O I N P U T S
5523 + __u32 index; /* Which input */
5524 + __u8 name[32]; /* Label */
5525 + __u32 type; /* Type of input */
5526 + __u32 audioset; /* Associated audios (bitfield) */
5527 + __u32 tuner; /* Associated tuner */
5530 + __u32 reserved[4];
5532 +/* Values for the 'type' field */
5533 +#define V4L2_INPUT_TYPE_TUNER 1
5534 +#define V4L2_INPUT_TYPE_CAMERA 2
5536 +/* field 'status' - general */
5537 +#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */
5538 +#define V4L2_IN_ST_NO_SIGNAL 0x00000002
5539 +#define V4L2_IN_ST_NO_COLOR 0x00000004
5541 +/* field 'status' - analog */
5542 +#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */
5543 +#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */
5545 +/* field 'status' - digital */
5546 +#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */
5547 +#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */
5548 +#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */
5550 +/* field 'status' - VCR and set-top box */
5551 +#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */
5552 +#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */
5553 +#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */
5556 + * V I D E O O U T P U T S
5560 + __u32 index; /* Which output */
5561 + __u8 name[32]; /* Label */
5562 + __u32 type; /* Type of output */
5563 + __u32 audioset; /* Associated audios (bitfield) */
5564 + __u32 modulator; /* Associated modulator */
5566 + __u32 reserved[4];
5568 +/* Values for the 'type' field */
5569 +#define V4L2_OUTPUT_TYPE_MODULATOR 1
5570 +#define V4L2_OUTPUT_TYPE_ANALOG 2
5571 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
5576 +struct v4l2_control
5582 +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
5583 +struct v4l2_queryctrl
5586 + enum v4l2_ctrl_type type;
5587 + __u8 name[32]; /* Whatever */
5588 + __s32 minimum; /* Note signedness */
5591 + __s32 default_value;
5593 + __u32 reserved[2];
5596 +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
5597 +struct v4l2_querymenu
5601 + __u8 name[32]; /* Whatever */
5605 +/* Control flags */
5606 +#define V4L2_CTRL_FLAG_DISABLED 0x0001
5607 +#define V4L2_CTRL_FLAG_GRABBED 0x0002
5609 +/* Control IDs defined by V4L2 */
5610 +#define V4L2_CID_BASE 0x00980900
5611 +/* IDs reserved for driver specific controls */
5612 +#define V4L2_CID_PRIVATE_BASE 0x08000000
5614 +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0)
5615 +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1)
5616 +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2)
5617 +#define V4L2_CID_HUE (V4L2_CID_BASE+3)
5618 +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5)
5619 +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6)
5620 +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7)
5621 +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8)
5622 +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
5623 +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10)
5624 +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11)
5625 +#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12)
5626 +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13)
5627 +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14)
5628 +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15)
5629 +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16)
5630 +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */
5631 +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17)
5632 +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18)
5633 +#define V4L2_CID_GAIN (V4L2_CID_BASE+19)
5634 +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20)
5635 +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21)
5636 +#define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
5637 +#define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
5638 +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */
5647 + enum v4l2_tuner_type type;
5655 + __u32 reserved[4];
5658 +struct v4l2_modulator
5666 + __u32 reserved[4];
5669 +/* Flags for the 'capability' field */
5670 +#define V4L2_TUNER_CAP_LOW 0x0001
5671 +#define V4L2_TUNER_CAP_NORM 0x0002
5672 +#define V4L2_TUNER_CAP_STEREO 0x0010
5673 +#define V4L2_TUNER_CAP_LANG2 0x0020
5674 +#define V4L2_TUNER_CAP_SAP 0x0020
5675 +#define V4L2_TUNER_CAP_LANG1 0x0040
5677 +/* Flags for the 'rxsubchans' field */
5678 +#define V4L2_TUNER_SUB_MONO 0x0001
5679 +#define V4L2_TUNER_SUB_STEREO 0x0002
5680 +#define V4L2_TUNER_SUB_LANG2 0x0004
5681 +#define V4L2_TUNER_SUB_SAP 0x0004
5682 +#define V4L2_TUNER_SUB_LANG1 0x0008
5684 +/* Values for the 'audmode' field */
5685 +#define V4L2_TUNER_MODE_MONO 0x0000
5686 +#define V4L2_TUNER_MODE_STEREO 0x0001
5687 +#define V4L2_TUNER_MODE_LANG2 0x0002
5688 +#define V4L2_TUNER_MODE_SAP 0x0002
5689 +#define V4L2_TUNER_MODE_LANG1 0x0003
5691 +struct v4l2_frequency
5694 + enum v4l2_tuner_type type;
5696 + __u32 reserved[8];
5708 + __u32 reserved[2];
5710 +/* Flags for the 'capability' field */
5711 +#define V4L2_AUDCAP_STEREO 0x00001
5712 +#define V4L2_AUDCAP_AVL 0x00002
5714 +/* Flags for the 'mode' field */
5715 +#define V4L2_AUDMODE_AVL 0x00001
5717 +struct v4l2_audioout
5723 + __u32 reserved[2];
5727 + * D A T A S E R V I C E S ( V B I )
5729 + * Data services API by Michael Schimek
5732 +struct v4l2_vbi_format
5734 + __u32 sampling_rate; /* in 1 Hz */
5736 + __u32 samples_per_line;
5737 + __u32 sample_format; /* V4L2_PIX_FMT_* */
5740 + __u32 flags; /* V4L2_VBI_* */
5741 + __u32 reserved[2]; /* must be zero */
5745 +#define V4L2_VBI_UNSYNC (1<< 0)
5746 +#define V4L2_VBI_INTERLACED (1<< 1)
5750 + * A G G R E G A T E S T R U C T U R E S
5753 +/* Stream data format
5757 + enum v4l2_buf_type type;
5760 + struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
5761 + struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
5762 + struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
5763 + __u8 raw_data[200]; // user-defined
5768 +/* Stream type-dependent parameters
5770 +struct v4l2_streamparm
5772 + enum v4l2_buf_type type;
5775 + struct v4l2_captureparm capture;
5776 + struct v4l2_outputparm output;
5777 + __u8 raw_data[200]; /* user-defined */
5784 + * 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
5787 +#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability)
5788 +#define VIDIOC_RESERVED _IO ('V', 1)
5789 +#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc)
5790 +#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format)
5791 +#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format)
5793 +#define VIDIOC_G_COMP _IOR ('V', 6, struct v4l2_compression)
5794 +#define VIDIOC_S_COMP _IOW ('V', 7, struct v4l2_compression)
5796 +#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers)
5797 +#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer)
5798 +#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer)
5799 +#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer)
5800 +#define VIDIOC_OVERLAY _IOW ('V', 14, int)
5801 +#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer)
5802 +#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer)
5803 +#define VIDIOC_STREAMON _IOW ('V', 18, int)
5804 +#define VIDIOC_STREAMOFF _IOW ('V', 19, int)
5805 +#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm)
5806 +#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm)
5807 +#define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id)
5808 +#define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id)
5809 +#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard)
5810 +#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input)
5811 +#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control)
5812 +#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control)
5813 +#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner)
5814 +#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner)
5815 +#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio)
5816 +#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio)
5817 +#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl)
5818 +#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu)
5819 +#define VIDIOC_G_INPUT _IOR ('V', 38, int)
5820 +#define VIDIOC_S_INPUT _IOWR ('V', 39, int)
5821 +#define VIDIOC_G_OUTPUT _IOR ('V', 46, int)
5822 +#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int)
5823 +#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output)
5824 +#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout)
5825 +#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout)
5826 +#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator)
5827 +#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator)
5828 +#define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency)
5829 +#define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency)
5830 +#define VIDIOC_CROPCAP _IOR ('V', 58, struct v4l2_cropcap)
5831 +#define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop)
5832 +#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop)
5833 +#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression)
5834 +#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression)
5835 +#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id)
5836 +#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format)
5837 +#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio)
5838 +#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout)
5839 +#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority)
5840 +#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority)
5842 +/* for compatibility, will go away some day */
5843 +#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
5844 +#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm)
5845 +#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control)
5846 +#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio)
5847 +#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout)
5849 +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
5855 + * V 4 L 2 D R I V E R H E L P E R A P I
5857 + * Some commonly needed functions for drivers (v4l2-common.o module)
5859 +#include <linux/fs.h>
5861 +/* Video standard functions */
5862 +extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
5863 +extern int v4l2_video_std_construct(struct v4l2_standard *vs,
5864 + int id, char *name);
5866 +/* prority handling */
5867 +struct v4l2_prio_state {
5868 + atomic_t prios[4];
5870 +int v4l2_prio_init(struct v4l2_prio_state *global);
5871 +int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
5872 + enum v4l2_priority new);
5873 +int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
5874 +int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local);
5875 +enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
5876 +int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local);
5878 +/* names for fancy debug output */
5879 +extern char *v4l2_field_names[];
5880 +extern char *v4l2_type_names[];
5881 +extern char *v4l2_ioctl_names[];
5883 +/* Compatibility layer interface -- v4l1-compat module */
5884 +typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
5885 + unsigned int cmd, void *arg);
5886 +int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
5887 + int cmd, void *arg, v4l2_kioctl driver_ioctl);
5889 +#endif /* __KERNEL__ */
5890 +#endif /* __LINUX_VIDEODEV2_H */
5893 + * Local variables:
5894 + * c-basic-offset: 8