r4938 - in developers/werner/gta03/cam: . patches
werner at docs.openmoko.org
werner at docs.openmoko.org
Thu Feb 26 16:51:04 CET 2009
Author: werner
Date: 2009-02-26 16:51:03 +0100 (Thu, 26 Feb 2009)
New Revision: 4938
Added:
developers/werner/gta03/cam/patches/
developers/werner/gta03/cam/patches/add-64xx-cam-clock.patch
developers/werner/gta03/cam/patches/add-s3c-cam-config.patch
developers/werner/gta03/cam/patches/add-s3c-camif-regs.patch
developers/werner/gta03/cam/patches/add-s3c-camif.patch
developers/werner/gta03/cam/patches/add-s5k4.patch
developers/werner/gta03/cam/patches/add-samsung-cams-i2c.patch
developers/werner/gta03/cam/patches/series
Log:
Port of the Samsung S3C camera interface driver and the S5K4 camera driver.
(In progress.)
Added: developers/werner/gta03/cam/patches/add-64xx-cam-clock.patch
===================================================================
--- developers/werner/gta03/cam/patches/add-64xx-cam-clock.patch (rev 0)
+++ developers/werner/gta03/cam/patches/add-64xx-cam-clock.patch 2009-02-26 15:51:03 UTC (rev 4938)
@@ -0,0 +1,54 @@
+Index: cam/arch/arm/plat-s3c/include/plat/clock.h
+===================================================================
+--- cam.orig/arch/arm/plat-s3c/include/plat/clock.h 2009-02-26 23:40:41.000000000 +0800
++++ cam/arch/arm/plat-s3c/include/plat/clock.h 2009-02-26 23:40:59.000000000 +0800
+@@ -50,6 +50,7 @@
+ extern struct clk clk_ext;
+
+ /* S3C64XX specific clocks */
++extern struct clk clk_h2;
+ extern struct clk clk_27m;
+ extern struct clk clk_48m;
+
+Index: cam/arch/arm/plat-s3c64xx/clock.c
+===================================================================
+--- cam.orig/arch/arm/plat-s3c64xx/clock.c 2009-02-26 23:26:09.000000000 +0800
++++ cam/arch/arm/plat-s3c64xx/clock.c 2009-02-26 23:42:47.000000000 +0800
+@@ -27,6 +27,12 @@
+ #include <plat/devs.h>
+ #include <plat/clock.h>
+
++struct clk clk_h2 = {
++ .name = "clk_h2",
++ .id = -1,
++ .rate = 0,
++};
++
+ struct clk clk_27m = {
+ .name = "clk_27m",
+ .id = -1,
+@@ -176,6 +182,12 @@
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_SDMA1,
++ }, {
++ .name = "camera",
++ .id = -1,
++ .parent = &clk_h2,
++ .enable = s3c64xx_sclk_ctrl,
++ .ctrlbit = S3C_CLKCON_SCLK_CAM,
+ },
+ };
+
+Index: cam/arch/arm/plat-s3c64xx/s3c6400-clock.c
+===================================================================
+--- cam.orig/arch/arm/plat-s3c64xx/s3c6400-clock.c 2009-02-26 23:39:36.000000000 +0800
++++ cam/arch/arm/plat-s3c64xx/s3c6400-clock.c 2009-02-26 23:39:49.000000000 +0800
+@@ -606,6 +606,7 @@
+ clk_fout_epll.rate = epll;
+ clk_fout_apll.rate = apll;
+
++ clk_h2.rate = hclk2;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+ clk_f.rate = fclk;
Added: developers/werner/gta03/cam/patches/add-s3c-cam-config.patch
===================================================================
--- developers/werner/gta03/cam/patches/add-s3c-cam-config.patch (rev 0)
+++ developers/werner/gta03/cam/patches/add-s3c-cam-config.patch 2009-02-26 15:51:03 UTC (rev 4938)
@@ -0,0 +1,43 @@
+Index: cam/drivers/media/video/Kconfig
+===================================================================
+--- cam.orig/drivers/media/video/Kconfig 2009-02-26 19:40:37.000000000 +0800
++++ cam/drivers/media/video/Kconfig 2009-02-26 19:42:02.000000000 +0800
+@@ -711,6 +711,25 @@
+ CMOS camera controller. This is the controller found on first-
+ generation OLPC systems.
+
++config VIDEO_SAMSUNG
++ bool "S3C SMDK CAMERA support"
++ depends on VIDEO_V4L2
++
++ default n
++ ---help---
++ TBA
++
++choice
++depends on VIDEO_SAMSUNG
++prompt "Select CIS module type"
++default VIDEO_SAMSUNG_S5K3BA
++
++config VIDEO_SAMSUNG_S5K4BA
++ bool "S5K4BA (2.0M CIS module, 1600x1200)"
++ ---help---
++ TBA
++endchoice
++
+ config SOC_CAMERA
+ tristate "SoC camera support"
+ depends on VIDEO_V4L2 && HAS_DMA
+Index: cam/drivers/media/video/Makefile
+===================================================================
+--- cam.orig/drivers/media/video/Makefile 2009-02-26 19:42:41.000000000 +0800
++++ cam/drivers/media/video/Makefile 2009-02-26 19:43:10.000000000 +0800
+@@ -134,6 +134,8 @@
+ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
+ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
+
++obj-$(CONFIG_VIDEO_SAMSUNG) += s3c_camera_driver.o s3c_camif.o samsung/
++
+ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
+ obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
+ obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
Added: developers/werner/gta03/cam/patches/add-s3c-camif-regs.patch
===================================================================
--- developers/werner/gta03/cam/patches/add-s3c-camif-regs.patch (rev 0)
+++ developers/werner/gta03/cam/patches/add-s3c-camif-regs.patch 2009-02-26 15:51:03 UTC (rev 4938)
@@ -0,0 +1,644 @@
+Index: cam/arch/arm/plat-s3c64xx/include/plat/regs-camif.h
+===================================================================
+--- cam.orig/arch/arm/plat-s3c64xx/include/plat/regs-camif.h 2009-02-26 19:56:45.000000000 +0800
++++ cam/arch/arm/plat-s3c64xx/include/plat/regs-camif.h 2009-02-26 21:01:22.000000000 +0800
+@@ -457,4 +457,3 @@
+ #endif
+
+ #endif /* ___ASM_ARCH_REGS_CAMIF_H */
+-
+Index: cam/arch/arm/plat-s3c64xx/include/plat/regs-lcd.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ cam/arch/arm/plat-s3c64xx/include/plat/regs-lcd.h 2009-02-26 21:02:14.000000000 +0800
+@@ -0,0 +1,630 @@
++/* linux/include/asm-arm/arch-s3c2410/regs-lcd.h
++ *
++ * Copyright (c) 2003 Simtec Electronics <linux at simtec.co.uk>
++ * http://www.simtec.co.uk/products/SWLINUX/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++
++#ifndef ___ASM_ARCH_REGS_LCD_H
++#define ___ASM_ARCH_REGS_LCD_H "$Id: regs-lcd.h,v 1.13 2008/03/31 09:35:38 eyryu Exp $"
++
++#define S3C2410_LCDREG(x) ((x) + S3C24XX_VA_LCD)
++
++/* LCD control registers */
++#define S3C2410_LCDCON1 S3C2410_LCDREG(0x00)
++#define S3C2410_LCDCON2 S3C2410_LCDREG(0x04)
++#define S3C2410_LCDCON3 S3C2410_LCDREG(0x08)
++#define S3C2410_LCDCON4 S3C2410_LCDREG(0x0C)
++#define S3C2410_LCDCON5 S3C2410_LCDREG(0x10)
++
++#define S3C2410_LCDCON1_CLKVAL(x) ((x) << 8)
++#define S3C2410_LCDCON1_MMODE (1<<7)
++#define S3C2410_LCDCON1_DSCAN4 (0<<5)
++#define S3C2410_LCDCON1_STN4 (1<<5)
++#define S3C2410_LCDCON1_STN8 (2<<5)
++#define S3C2410_LCDCON1_TFT (3<<5)
++
++#define S3C2410_LCDCON1_STN1BPP (0<<1)
++#define S3C2410_LCDCON1_STN2GREY (1<<1)
++#define S3C2410_LCDCON1_STN4GREY (2<<1)
++#define S3C2410_LCDCON1_STN8BPP (3<<1)
++#define S3C2410_LCDCON1_STN12BPP (4<<1)
++
++#define S3C2410_LCDCON1_TFT1BPP (8<<1)
++#define S3C2410_LCDCON1_TFT2BPP (9<<1)
++#define S3C2410_LCDCON1_TFT4BPP (10<<1)
++#define S3C2410_LCDCON1_TFT8BPP (11<<1)
++#define S3C2410_LCDCON1_TFT16BPP (12<<1)
++#define S3C2410_LCDCON1_TFT24BPP (13<<1)
++
++#define S3C2410_LCDCON1_ENVID (1)
++
++#define S3C2410_LCDCON1_MODEMASK 0x1E
++
++#define S3C2410_LCDCON2_VBPD(x) ((x) << 24)
++#define S3C2410_LCDCON2_LINEVAL(x) ((x) << 14)
++#define S3C2410_LCDCON2_VFPD(x) ((x) << 6)
++#define S3C2410_LCDCON2_VSPW(x) ((x) << 0)
++
++#define S3C2410_LCDCON2_GET_VBPD(x) ( ((x) >> 24) & 0xFF)
++#define S3C2410_LCDCON2_GET_VFPD(x) ( ((x) >> 6) & 0xFF)
++#define S3C2410_LCDCON2_GET_VSPW(x) ( ((x) >> 0) & 0x3F)
++
++#define S3C2410_LCDCON3_HBPD(x) ((x) << 19)
++#define S3C2410_LCDCON3_WDLY(x) ((x) << 19)
++#define S3C2410_LCDCON3_HOZVAL(x) ((x) << 8)
++#define S3C2410_LCDCON3_HFPD(x) ((x) << 0)
++#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0)
++
++#define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F)
++#define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >> 0) & 0xFF)
++
++/* LDCCON4 changes for STN mode on the S3C2412 */
++
++#define S3C2410_LCDCON4_MVAL(x) ((x) << 8)
++#define S3C2410_LCDCON4_HSPW(x) ((x) << 0)
++#define S3C2410_LCDCON4_WLH(x) ((x) << 0)
++
++#define S3C2410_LCDCON4_GET_HSPW(x) ( ((x) >> 0) & 0xFF)
++
++#define S3C2410_LCDCON5_BPP24BL (1<<12)
++#define S3C2410_LCDCON5_FRM565 (1<<11)
++#define S3C2410_LCDCON5_INVVCLK (1<<10)
++#define S3C2410_LCDCON5_INVVLINE (1<<9)
++#define S3C2410_LCDCON5_INVVFRAME (1<<8)
++#define S3C2410_LCDCON5_INVVD (1<<7)
++#define S3C2410_LCDCON5_INVVDEN (1<<6)
++#define S3C2410_LCDCON5_INVPWREN (1<<5)
++#define S3C2410_LCDCON5_INVLEND (1<<4)
++#define S3C2410_LCDCON5_PWREN (1<<3)
++#define S3C2410_LCDCON5_ENLEND (1<<2)
++#define S3C2410_LCDCON5_BSWP (1<<1)
++#define S3C2410_LCDCON5_HWSWP (1<<0)
++
++/* framebuffer start addressed */
++#define S3C2410_LCDSADDR1 S3C2410_LCDREG(0x14)
++#define S3C2410_LCDSADDR2 S3C2410_LCDREG(0x18)
++#define S3C2410_LCDSADDR3 S3C2410_LCDREG(0x1C)
++
++#define S3C2410_LCDBANK(x) ((x) << 21)
++#define S3C2410_LCDBASEU(x) (x)
++
++#define S3C2410_OFFSIZE(x) ((x) << 11)
++#define S3C2410_PAGEWIDTH(x) (x)
++
++/* colour lookup and miscellaneous controls */
++
++#define S3C2410_REDLUT S3C2410_LCDREG(0x20)
++#define S3C2410_GREENLUT S3C2410_LCDREG(0x24)
++#define S3C2410_BLUELUT S3C2410_LCDREG(0x28)
++
++#define S3C2410_DITHMODE S3C2410_LCDREG(0x4C)
++#define S3C2410_TPAL S3C2410_LCDREG(0x50)
++
++#define S3C2410_TPAL_EN (1<<24)
++
++/* interrupt info */
++#define S3C2410_LCDINTPND S3C2410_LCDREG(0x54)
++#define S3C2410_LCDSRCPND S3C2410_LCDREG(0x58)
++#define S3C2410_LCDINTMSK S3C2410_LCDREG(0x5C)
++#define S3C2410_LCDINT_FIWSEL (1<<2)
++#define S3C2410_LCDINT_FRSYNC (1<<1)
++#define S3C2410_LCDINT_FICNT (1<<0)
++
++/* s3c2442 extra stn registers */
++
++#define S3C2442_REDLUT S3C2410_LCDREG(0x20)
++#define S3C2442_GREENLUT S3C2410_LCDREG(0x24)
++#define S3C2442_BLUELUT S3C2410_LCDREG(0x28)
++#define S3C2442_DITHMODE S3C2410_LCDREG(0x20)
++
++#define S3C2410_LPCSEL S3C2410_LCDREG(0x60)
++
++#define S3C2410_TFTPAL(x) S3C2410_LCDREG((0x400 + (x)*4))
++
++/* S3C2412 registers */
++
++#define S3C2412_TPAL S3C2410_LCDREG(0x20)
++
++#define S3C2412_LCDINTPND S3C2410_LCDREG(0x24)
++#define S3C2412_LCDSRCPND S3C2410_LCDREG(0x28)
++#define S3C2412_LCDINTMSK S3C2410_LCDREG(0x2C)
++
++#define S3C2412_TCONSEL S3C2410_LCDREG(0x30)
++
++#define S3C2412_LCDCON6 S3C2410_LCDREG(0x34)
++#define S3C2412_LCDCON7 S3C2410_LCDREG(0x38)
++#define S3C2412_LCDCON8 S3C2410_LCDREG(0x3C)
++#define S3C2412_LCDCON9 S3C2410_LCDREG(0x40)
++
++#define S3C2412_REDLUT(x) S3C2410_LCDREG(0x44 + ((x)*4))
++#define S3C2412_GREENLUT(x) S3C2410_LCDREG(0x60 + ((x)*4))
++#define S3C2412_BLUELUT(x) S3C2410_LCDREG(0x98 + ((x)*4))
++
++#define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4))
++
++
++/***************************************************************************/
++/* LCD Registers */
++#define S3C_LCDREG(x) ((x) + S3C24XX_VA_LCD)
++
++/* LCD control registers */
++#define S3C_VIDCON0 S3C_LCDREG(0x00) /* Video control 0 register */
++#define S3C_VIDCON1 S3C_LCDREG(0x04) /* Video control 1 register */
++
++
++#if defined(CONFIG_CPU_S3C2443)||defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
++#define S3C_VIDTCON0 S3C_LCDREG(0x08) /* LCD CONTROL 1 */
++#define S3C_VIDTCON1 S3C_LCDREG(0x0C) /* LCD CONTROL 1 */
++#define S3C_VIDTCON2 S3C_LCDREG(0x10) /* LCD CONTROL 1 */
++#define S3C_WINCON0 S3C_LCDREG(0x14) /* LCD CONTROL 1 */
++#define S3C_WINCON1 S3C_LCDREG(0x18) /* LCD CONTROL 1 */
++#define S3C_VIDOSD0A S3C_LCDREG(0x28) /* LCD CONTROL 1 */
++#define S3C_VIDOSD0B S3C_LCDREG(0x2C) /* LCD CONTROL 1 */
++#define S3C_VIDOSD0C S3C_LCDREG(0x30) /* LCD CONTROL 1 */
++#define S3C_VIDOSD1A S3C_LCDREG(0x34) /* LCD CONTROL 1 */
++#define S3C_VIDOSD1B S3C_LCDREG(0x38) /* LCD CONTROL 1 */
++#define S3C_VIDOSD1C S3C_LCDREG(0x3C) /* LCD CONTROL 1 */
++#define S3C_VIDW00ADD0B0 S3C_LCDREG(0x64) /* LCD CONTROL 1 */
++#define S3C_VIDW00ADD0B1 S3C_LCDREG(0x68) /* LCD CONTROL 1 */
++#define S3C_VIDW01ADD0 S3C_LCDREG(0x6C) /* LCD CONTROL 1 */
++#define S3C_VIDW00ADD1B0 S3C_LCDREG(0x7C) /* LCD CONTROL 1 */
++#define S3C_VIDW00ADD1B1 S3C_LCDREG(0x80) /* LCD CONTROL 1 */
++#define S3C_VIDW01ADD1 S3C_LCDREG(0x84) /* LCD CONTROL 1 */
++#define S3C_VIDW00ADD2B0 S3C_LCDREG(0x94) /* LCD CONTROL 1 */
++#define S3C_VIDW00ADD2B1 S3C_LCDREG(0x98) /* LCD CONTROL 1 */
++#define S3C_VIDW01ADD2 S3C_LCDREG(0x9C) /* LCD CONTROL 1 */
++#define S3C_VIDINTCON S3C_LCDREG(0xAC) /* LCD CONTROL 1 */
++#define S3C_W1KEYCON0 S3C_LCDREG(0xB0) /* LCD CONTROL 1 */
++#define S3C_W1KEYCON1 S3C_LCDREG(0xB4) /* LCD CONTROL 1 */
++#define S3C_WIN0MAP S3C_LCDREG(0xD0) /* LCD CONTROL 1 */
++#define S3C_WIN1MAP S3C_LCDREG(0xD4) /* LCD CONTROL 1 */
++#define S3C_WPALCON S3C_LCDREG(0xE4) /* LCD CONTROL 1 */
++#define S3C_SYSIFCON0 S3C_LCDREG(0x130) /* LCD CONTROL 1 */
++#define S3C_SYSIFCON1 S3C_LCDREG(0x134) /* LCD CONTROL 1 */
++#define S3C_DITHMODE S3C_LCDREG(0x138) /* LCD CONTROL 1 */
++#define S3C_SIFCCON0 S3C_LCDREG(0x13C) /* LCD CONTROL 1 */
++#define S3C_SIFCCON1 S3C_LCDREG(0x140) /* LCD CONTROL 1 */
++#define S3C_SIFCCON2 S3C_LCDREG(0x144) /* LCD CONTROL 1 */
++#define S3C_CPUTRIGCON2 S3C_LCDREG(0x160) /* LCD CONTROL 1 */
++
++#elif defined CONFIG_CPU_S3C6400 || defined CONFIG_CPU_S3C6410
++#define S3C_VIDCON2 S3C_LCDREG(0x08) /* Video control 2 register */
++#define S3C_VIDTCON0 S3C_LCDREG(0x10) /* Video time control 0 register */
++#define S3C_VIDTCON1 S3C_LCDREG(0x14) /* Video time control 1 register */
++#define S3C_VIDTCON2 S3C_LCDREG(0x18) /* Video time control 2 register */
++#define S3C_VIDTCON3 S3C_LCDREG(0x1C) /* Video time control 3 register */
++
++#define S3C_WINCON0 S3C_LCDREG(0x20) /* Window control 0 register */
++#define S3C_WINCON1 S3C_LCDREG(0x24) /* Window control 1 register */
++#define S3C_WINCON2 S3C_LCDREG(0x28) /* Window control 2 register */
++#define S3C_WINCON3 S3C_LCDREG(0x2C) /* Window control 3 register */
++#define S3C_WINCON4 S3C_LCDREG(0x30) /* Window control 4 register*/
++
++
++#define S3C_VIDOSD0A S3C_LCDREG(0x40) /* Video Window 0¡¯s position control register */
++#define S3C_VIDOSD0B S3C_LCDREG(0x44) /* Video Window 0¡¯s position control register1 */
++#define S3C_VIDOSD0C S3C_LCDREG(0x48) /* Video Window 0¡¯s position control register */
++
++#define S3C_VIDOSD1A S3C_LCDREG(0x50) /* Video Window 1¡¯s position control register */
++#define S3C_VIDOSD1B S3C_LCDREG(0x54) /* Video Window 1¡¯s position control register */
++#define S3C_VIDOSD1C S3C_LCDREG(0x58) /* Video Window 1¡¯s position control register */
++#define S3C_VIDOSD1D S3C_LCDREG(0x5C) /* Video Window 1¡¯s position control register */
++
++#define S3C_VIDOSD2A S3C_LCDREG(0x60) /* Video Window 2¡¯s position control register */
++#define S3C_VIDOSD2B S3C_LCDREG(0x64) /* Video Window 2¡¯s position control register */
++#define S3C_VIDOSD2C S3C_LCDREG(0x68) /* Video Window 2¡¯s position control register */
++#define S3C_VIDOSD2D S3C_LCDREG(0x6C) /* Video Window 2¡¯s position control register */
++
++#define S3C_VIDOSD3A S3C_LCDREG(0x70) /* Video Window 3¡¯s position control register */
++#define S3C_VIDOSD3B S3C_LCDREG(0x74) /* Video Window 3¡¯s position control register */
++#define S3C_VIDOSD3C S3C_LCDREG(0x78) /* Video Window 3¡¯s position control register */
++
++#define S3C_VIDOSD4A S3C_LCDREG(0x80) /* Video Window 4¡¯s position control register */
++#define S3C_VIDOSD4B S3C_LCDREG(0x84) /* Video Window 4¡¯s position control register */
++#define S3C_VIDOSD4C S3C_LCDREG(0x88) /* Video Window 4¡¯s position control register */
++
++#define S3C_VIDW00ADD2B0 S3C_LCDREG(0x94) /* LCD CONTROL 1 */
++#define S3C_VIDW00ADD2B1 S3C_LCDREG(0x98) /* LCD CONTROL 1 */
++
++#define S3C_VIDW00ADD0B0 S3C_LCDREG(0x0A0) /* Window 0¡¯s buffer start address register, buffer 0 */
++#define S3C_VIDW00ADD0B1 S3C_LCDREG(0x0A4) /* Window 0¡¯s buffer start address register, buffer 1 */
++#define S3C_VIDW01ADD0B0 S3C_LCDREG(0x0A8) /* Window 1¡¯s buffer start address register, buffer 0 */
++#define S3C_VIDW01ADD0B1 S3C_LCDREG(0x0AC) /* Window 1¡¯s buffer start address register, buffer 1 */
++#define S3C_VIDW02ADD0 S3C_LCDREG(0x0B0) /* Window 2¡¯s buffer start address register */
++#define S3C_VIDW03ADD0 S3C_LCDREG(0x0B8) /* Window 3¡¯s buffer start address register */
++#define S3C_VIDW04ADD0 S3C_LCDREG(0x0C0) /* Window 4¡¯s buffer start address register */
++#define S3C_VIDW00ADD1B0 S3C_LCDREG(0x0D0) /* Window 0¡¯s buffer end address register, buffer 0 */
++#define S3C_VIDW00ADD1B1 S3C_LCDREG(0x0D4) /* Window 0¡¯s buffer end address register, buffer 1 */
++#define S3C_VIDW01ADD1B0 S3C_LCDREG(0x0D8) /* Window 1¡¯s buffer end address register, buffer 0 */
++#define S3C_VIDW01ADD1B1 S3C_LCDREG(0x0DC) /* Window 1¡¯s buffer end address register, buffer 1 */
++#define S3C_VIDW02ADD1 S3C_LCDREG(0x0E0) /* Window 2¡¯s buffer end address register */
++#define S3C_VIDW03ADD1 S3C_LCDREG(0x0E8) /* Window 3¡¯s buffer end address register */
++#define S3C_VIDW04ADD1 S3C_LCDREG(0x0F0) /* Window 4¡¯s buffer end address register */
++#define S3C_VIDW00ADD2 S3C_LCDREG(0x100) /* Window 0¡¯s buffer size register */
++#define S3C_VIDW01ADD2 S3C_LCDREG(0x104) /* Window 1¡¯s buffer size register */
++
++#define S3C_VIDW02ADD2 S3C_LCDREG(0x108) /* Window 2¡¯s buffer size register */
++#define S3C_VIDW03ADD2 S3C_LCDREG(0x10C) /* Window 3¡¯s buffer size register */
++#define S3C_VIDW04ADD2 S3C_LCDREG(0x110) /* Window 4¡¯s buffer size register */
++
++#define S3C_VIDINTCON0 S3C_LCDREG(0x130) /* Indicate the Video interrupt control register */
++#define S3C_VIDINTCON1 S3C_LCDREG(0x134) /* Video Interrupt Pending register */
++#define S3C_W1KEYCON0 S3C_LCDREG(0x140) /* Color key control register */
++#define S3C_W1KEYCON1 S3C_LCDREG(0x144) /* Color key value ( transparent value) register */
++#define S3C_W2KEYCON0 S3C_LCDREG(0x148) /* Color key control register */
++#define S3C_W2KEYCON1 S3C_LCDREG(0x14C) /* Color key value (transparent value) register */
++
++#define S3C_W3KEYCON0 S3C_LCDREG(0x150) /* Color key control register */
++#define S3C_W3KEYCON1 S3C_LCDREG(0x154) /* Color key value (transparent value) register */
++#define S3C_W4KEYCON0 S3C_LCDREG(0x158) /* Color key control register */
++#define S3C_W4KEYCON1 S3C_LCDREG(0x15C) /* Color key value (transparent value) register */
++#define S3C_DITHMODE S3C_LCDREG(0x170) /* Dithering mode register. */
++
++#define S3C_WIN0MAP S3C_LCDREG(0x180) /* Window color control */
++#define S3C_WIN1MAP S3C_LCDREG(0x184) /* Window color control */
++#define S3C_WIN2MAP S3C_LCDREG(0x188) /* Window color control */
++#define S3C_WIN3MAP S3C_LCDREG(0x18C) /* Window color control */
++#define S3C_WIN4MAP S3C_LCDREG(0x190) /* Window color control */
++#define S3C_WPALCON S3C_LCDREG(0x1A0) /* Window Palette control register */
++
++#define S3C_TRIGCON S3C_LCDREG(0x1A4) /* I80 / RGB Trigger Control Regiter */
++#define S3C_I80IFCONA0 S3C_LCDREG(0x1B0) /* I80 Interface control 0 for Main LDI */
++#define S3C_I80IFCONA1 S3C_LCDREG(0x1B4) /* I80 Interface control 0 for Sub LDI */
++#define S3C_I80IFCONB0 S3C_LCDREG(0x1B8) /* I80 Inteface control 1 for Main LDI */
++#define S3C_I80IFCONB1 S3C_LCDREG(0x1BC) /* I80 Inteface control 1 for Sub LDI */
++#define S3C_LDI_CMDCON0 S3C_LCDREG(0x1D0) /* I80 Interface LDI Command Control 0 */
++#define S3C_LDI_CMDCON1 S3C_LCDREG(0x1D4) /* I80 Interface LDI Command Control 1 */
++#define S3C_SIFCCON0 S3C_LCDREG(0x1E0) /* LCD i80 System Interface Command Control 0 */
++#define S3C_SIFCCON1 S3C_LCDREG(0x1E4) /* LCD i80 System Interface Command Control 1 */
++#define S3C_SIFCCON2 S3C_LCDREG(0x1E8) /* LCD i80 System Interface Command Control 2 */
++
++#define S3C_LDI_CMD0 S3C_LCDREG(0x280) /* I80 Inteface LDI Command 0 */
++#define S3C_LDI_CMD1 S3C_LCDREG(0x284) /* I80 Inteface LDI Command 1 */
++#define S3C_LDI_CMD2 S3C_LCDREG(0x288) /* I80 Inteface LDI Command 2 */
++#define S3C_LDI_CMD3 S3C_LCDREG(0x28C) /* I80 Inteface LDI Command 3 */
++#define S3C_LDI_CMD4 S3C_LCDREG(0x290) /* I80 Inteface LDI Command 4 */
++#define S3C_LDI_CMD5 S3C_LCDREG(0x294) /* I80 Inteface LDI Command 5 */
++#define S3C_LDI_CMD6 S3C_LCDREG(0x298) /* I80 Inteface LDI Command 6 */
++#define S3C_LDI_CMD7 S3C_LCDREG(0x29C) /* I80 Inteface LDI Command 7 */
++#define S3C_LDI_CMD8 S3C_LCDREG(0x2A0) /* I80 Inteface LDI Command 8 */
++#define S3C_LDI_CMD9 S3C_LCDREG(0x2A4) /* I80 Inteface LDI Command 9 */
++#define S3C_LDI_CMD10 S3C_LCDREG(0x2A8) /* I80 Inteface LDI Command 10 */
++#define S3C_LDI_CMD11 S3C_LCDREG(0x2AC) /* I80 Inteface LDI Command 11 */
++
++#define S3C_W2PDATA01 S3C_LCDREG(0x300) /* Window 2 Palette Data of the Index 0,1 */
++#define S3C_W2PDATA23 S3C_LCDREG(0x304) /* Window 2 Palette Data of the Index 2,3 */
++#define S3C_W2PDATA45 S3C_LCDREG(0x308) /* Window 2 Palette Data of the Index 4,5 */
++#define S3C_W2PDATA67 S3C_LCDREG(0x30C) /* Window 2 Palette Data of the Index 6,7 */
++#define S3C_W2PDATA89 S3C_LCDREG(0x310) /* Window 2 Palette Data of the Index 8,9 */
++#define S3C_W2PDATAAB S3C_LCDREG(0x314) /* Window 2 Palette Data of the Index A, B */
++#define S3C_W2PDATACD S3C_LCDREG(0x318) /* Window 2 Palette Data of the Index C, D */
++#define S3C_W2PDATAEF S3C_LCDREG(0x31C) /* Window 2 Palette Data of the Index E, F */
++#define S3C_W3PDATA01 S3C_LCDREG(0x320) /* Window 3 Palette Data of the Index 0,1 */
++#define S3C_W3PDATA23 S3C_LCDREG(0x324) /* Window 3 Palette Data of the Index 2,3 */
++#define S3C_W3PDATA45 S3C_LCDREG(0x328) /* Window 3 Palette Data of the Index 4,5 */
++#define S3C_W3PDATA67 S3C_LCDREG(0x32C) /* Window 3 Palette Data of the Index 6,7 */
++#define S3C_W3PDATA89 S3C_LCDREG(0x330) /* Window 3 Palette Data of the Index 8,9 */
++#define S3C_W3PDATAAB S3C_LCDREG(0x334) /* Window 3 Palette Data of the Index A, B */
++#define S3C_W3PDATACD S3C_LCDREG(0x338) /* Window 3 Palette Data of the Index C, D */
++#define S3C_W3PDATAEF S3C_LCDREG(0x33C) /* Window 3 Palette Data of the Index E, F */
++#define S3C_W4PDATA01 S3C_LCDREG(0x340) /* Window 3 Palette Data of the Index 0,1 */
++#define S3C_W4PDATA23 S3C_LCDREG(0x344) /* Window 3 Palette Data of the Index 2,3 */
++#endif
++
++#define S3C_TFTPAL2(x) S3C_LCDREG((0x300 + (x)*4))
++#define S3C_TFTPAL3(x) S3C_LCDREG((0x320 + (x)*4))
++#define S3C_TFTPAL4(x) S3C_LCDREG((0x340 + (x)*4))
++#define S3C_TFTPAL0(x) S3C_LCDREG((0x400 + (x)*4))
++#define S3C_TFTPAL1(x) S3C_LCDREG((0x800 + (x)*4))
++
++/*--------------------------------------------------------------*/
++/* Video Main Control 0 register - VIDCON0 */
++#define S3C_VIDCON0_INTERLACE_F_PROGRESSIVE (0<<29)
++#define S3C_VIDCON0_INTERLACE_F_INTERLACE (1<<29)
++#define S3C_VIDCON0_VIDOUT(x) (((x)&0x7)<<26)
++#define S3C_VIDCON0_VIDOUT_RGB_IF (0<<26)
++#define S3C_VIDCON0_VIDOUT_TV (1<<26)
++#define S3C_VIDCON0_VIDOUT_I80IF0 (2<<26)
++#define S3C_VIDCON0_VIDOUT_I80IF1 (3<<26)
++#define S3C_VIDCON0_VIDOUT_TVNRGBIF (4<<26)
++#define S3C_VIDCON0_VIDOUT_TVNI80IF0 (6<<26)
++#define S3C_VIDCON0_VIDOUT_TVNI80IF1 (7<<26)
++#define S3C_VIDCON0_L1_DATA16(x) (((x)&0x7)<<23)
++#define S3C_VIDCON0_L1_DATA16_SUB_16_MODE (0<<23)
++#define S3C_VIDCON0_L1_DATA16_SUB_16PLUS2_MODE (1<<23)
++#define S3C_VIDCON0_L1_DATA16_SUB_9PLUS9_MODE (2<<23)
++#define S3C_VIDCON0_L1_DATA16_SUB_16PLUS8_MODE (3<<23)
++#define S3C_VIDCON0_L1_DATA16_SUB_18_MODE (4<<23)
++#define S3C_VIDCON0_L0_DATA16(x) (((x)&0x7)<<20)
++#define S3C_VIDCON0_L0_DATA16_MAIN_16_MODE (0<<20)
++#define S3C_VIDCON0_L0_DATA16_MAIN_16PLUS2_MODE (1<<20)
++#define S3C_VIDCON0_L0_DATA16_MAIN_9PLUS9_MODE (2<<20)
++#define S3C_VIDCON0_L0_DATA16_MAIN_16PLUS8_MODE (3<<20)
++#define S3C_VIDCON0_L0_DATA16_MAIN_18_MODE (4<<20)
++#define S3C_VIDCON0_PNRMODE(x) (((x)&0x3)<<17)
++#define S3C_VIDCON0_PNRMODE_RGB_P (0<<17)
++#define S3C_VIDCON0_PNRMODE_BGR_P (1<<17)
++#define S3C_VIDCON0_PNRMODE_RGB_S (2<<17)
++#define S3C_VIDCON0_PNRMODE_BGR_S (3<<17)
++#define S3C_VIDCON0_PNRMODE_MASK (3<<17)
++#define S3C_VIDCON0_CLKVALUP_ALWAYS (0<<16)
++#define S3C_VIDCON0_CLKVALUP_ST_FRM (1<<16)
++#define S3C_VIDCON0_CLKVAL_F(x) (((x)&0xFF)<<6)
++#define S3C_VIDCON0_VCLKEN_ENABLE (1<<5)
++#define S3C_VIDCON0_CLKDIR_DIVIDED (1<<4)
++#define S3C_VIDCON0_CLKDIR_DIRECTED (0<<4)
++#define S3C_VIDCON0_CLKSEL(x) (((x)&0x3)<<2)
++#define S3C_VIDCON0_CLKSEL_F_HCLK (0<<2)
++#define S3C_VIDCON0_ENVID_ENABLE (1 << 1) /* 0:Disable 1:Enable LCD video output and logic immediatly */
++#define S3C_VIDCON0_ENVID_DISABLE (0 << 1) /* 0:Disable 1:Enable LCD video output and logic immediatly */
++#define S3C_VIDCON0_ENVID_F_ENABLE (1 << 0) /* 0:Dis 1:Ena wait until Current frame end. */
++#define S3C_VIDCON0_ENVID_F_DISABLE (0 << 0) /* 0:Dis 1:Ena wait until Current frame end. */
++
++/* Video Main Control 1 register - VIDCON1 */
++#define S3C_VIDCON1_IVCLK_FALL_EDGE (0<<7)
++#define S3C_VIDCON1_IVCLK_RISE_EDGE (1<<7)
++#define S3C_VIDCON1_IHSYNC_NORMAL (0<<6)
++#define S3C_VIDCON1_IHSYNC_INVERT (1<<6)
++#define S3C_VIDCON1_IVSYNC_NORMAL (0<<5)
++#define S3C_VIDCON1_IVSYNC_INVERT (1<<5)
++#define S3C_VIDCON1_IVDEN_NORMAL (0<<4)
++#define S3C_VIDCON1_IVDEN_INVERT (1<<4)
++
++/* Video Main Control 2 register - VIDCON2 */
++#define S3C_VIDCON2_TVLFFORMAT(x) (((x)&0x7)<<7)
++
++/* VIDEO Time Control 0 register - VIDTCON0 */
++#define S3C_VIDTCON0_VBPDE(x) (((x)&0xFF)<<24)
++#define S3C_VIDTCON0_VBPD(x) (((x)&0xFF)<<16)
++#define S3C_VIDTCON0_VFPD(x) (((x)&0xFF)<<8)
++#define S3C_VIDTCON0_VSPW(x) (((x)&0xFF)<<0)
++
++/* VIDEO Time Control 1 register - VIDTCON1 */
++#define S3C_VIDTCON1_VFPDE(x) (((x)&0xFF)<<24)
++#define S3C_VIDTCON1_HBPD(x) (((x)&0xFF)<<16)
++#define S3C_VIDTCON1_HFPD(x) (((x)&0xFF)<<8)
++#define S3C_VIDTCON1_HSPW(x) (((x)&0xFF)<<0)
++
++/* VIDEO Time Control 2 register - VIDTCON2 */
++#define S3C_VIDTCON2_LINEVAL(x) (((x)&0x7FF)<<11) /* these bits determine the vertical size of lcd panel */
++#define S3C_VIDTCON2_HOZVAL(x) (((x)&0x7FF)<<0) /* these bits determine the horizontal size of lcd panel*/
++
++
++/* Window 0~4 Control register - WINCONx */
++#define S3C_WINCONx_WIDE_NARROW(x) (((x)&0x3)<<26)
++#define S3C_WINCONx_ENLOCAL_DMA (0<<22)
++#define S3C_WINCONx_ENLOCAL_POST (1<<22)
++#define S3C_WINCONx_BUFSEL_0 (0<<20)
++#define S3C_WINCONx_BUFSEL_1 (1<<20)
++#define S3C_WINCONx_BUF_MASK (1<<20)
++#define S3C_WINCONx_BUFAUTOEN_DISABLE (0<<19)
++#define S3C_WINCONx_BUFAUTOEN_ENABLE (1<<19)
++#define S3C_WINCONx_BUFAUTOEN_MASK (1<<19)
++#define S3C_WINCONx_BITSWP_DISABLE (0<<18)
++#define S3C_WINCONx_BITSWP_ENABLE (1<<18)
++#define S3C_WINCONx_BYTSWP_DISABLE (0<<17)
++#define S3C_WINCONx_BYTSWP_ENABLE (1<<17)
++#define S3C_WINCONx_HAWSWP_DISABLE (0<<16)
++#define S3C_WINCONx_HAWSWP_ENABLE (1<<16)
++#define S3C_WINCONx_INRGB_RGB (0<<13)
++#define S3C_WINCONx_INRGB_YUV (1<<13)
++#define S3C_WINCONx_INRGB_MASK (1<<13)
++#define S3C_WINCONx_BURSTLEN_16WORD (0<<9)
++#define S3C_WINCONx_BURSTLEN_8WORD (1<<9)
++#define S3C_WINCONx_BURSTLEN_4WORD (2<<9)
++#define S3C_WINCONx_BLD_PIX_PLANE (0<<6)
++#define S3C_WINCONx_BLD_PIX_PIXEL (1<<6)
++#define S3C_WINCONx_BLD_PIX_MASK (1<<6)
++#define S3C_WINCONx_BPPMODE_F_1BPP (0<<2)
++#define S3C_WINCONx_BPPMODE_F_2BPP (1<<2)
++#define S3C_WINCONx_BPPMODE_F_4BPP (2<<2)
++#define S3C_WINCONx_BPPMODE_F_8BPP_PAL (3<<2)
++#define S3C_WINCONx_BPPMODE_F_8BPP_NOPAL (4<<2)
++#define S3C_WINCONx_BPPMODE_F_16BPP_565 (5<<2)
++#define S3C_WINCONx_BPPMODE_F_16BPP_A555 (6<<2)
++#define S3C_WINCONx_BPPMODE_F_18BPP_666 (8<<2)
++#define S3C_WINCONx_BPPMODE_F_24BPP_888 (11<<2)
++#define S3C_WINCONx_BPPMODE_F_24BPP_A887 (0xc<<2)
++#define S3C_WINCONx_BPPMODE_F_MASK (0xf<<2)
++#define S3C_WINCONx_ALPHA_SEL_0 (0<<1)
++#define S3C_WINCONx_ALPHA_SEL_1 (1<<1)
++#define S3C_WINCONx_ENWIN_F_DISABLE (0<<0)
++#define S3C_WINCONx_ENWIN_F_ENABLE (1<<0)
++
++/* Window 1-2 Control register - WINCON1 */
++#define S3C_WINCON1_LOCALSEL_TV (0<<23)
++#define S3C_WINCON1_LOCALSEL_CAMERA (1<<23)
++#define S3C_WINCON2_LOCALSEL_TV (0<<23)
++#define S3C_WINCON2_LOCALSEL_CAMERA (1<<23)
++
++/* Window 0~4 Position Control A register - VIDOSDxA */
++#define S3C_VIDOSDxA_OSD_LTX_F(x) (((x)&0x7FF)<<11)
++#define S3C_VIDOSDxA_OSD_LTY_F(x) (((x)&0x7FF)<<0)
++
++/* Window 0~4 Position Control B register - VIDOSDxB */
++#define S3C_VIDOSDxB_OSD_RBX_F(x) (((x)&0x7FF)<<11)
++#define S3C_VIDOSDxB_OSD_RBY_F(x) (((x)&0x7FF)<<0)
++
++/* Window 0 Position Control C register - VIDOSD0C */
++#define S3C_VIDOSD0C_OSDSIZE(x) (((x)&0xFFFFFF)<<0)
++
++/* Window 1~4 Position Control C register - VIDOSDxC */
++#define S3C_VIDOSDxC_ALPHA0_R(x) (((x)&0xF)<<20)
++#define S3C_VIDOSDxC_ALPHA0_G(x) (((x)&0xF)<<16)
++#define S3C_VIDOSDxC_ALPHA0_B(x) (((x)&0xF)<<12)
++#define S3C_VIDOSDxC_ALPHA1_R(x) (((x)&0xF)<<8)
++#define S3C_VIDOSDxC_ALPHA1_G(x) (((x)&0xF)<<4)
++#define S3C_VIDOSDxC_ALPHA1_B(x) (((x)&0xF)<<0)
++
++/* Window 1~2 Position Control D register - VIDOSDxD */
++#define S3C_VIDOSDxD_OSDSIZE(x) (((x)&0xFFFFFF)<<0)
++
++/* Frame buffer Start Address register - VIDWxxADD0 */
++#define S3C_VIDWxxADD0_VBANK_F(x) (((x)&0xFF)<<23) /* the end address of the LCD frame buffer. */
++#define S3C_VIDWxxADD0_VBASEU_F(x) (((x)&0xFFFFFF)<<0) /* Virtual screen offset size (the number of byte). */
++
++/* Frame buffer End Address register - VIDWxxADD1 */
++#define S3C_VIDWxxADD1_VBASEL_F(x) (((x)&0xFFFFFF)<<0) /* the end address of the LCD frame buffer. */
++
++/* Frame buffer Size register - VIDWxxADD2 */
++#define S3C_VIDWxxADD2_OFFSIZE_F(x) (((x)&0x1FFF)<<13) /* Virtual screen offset size (the number of byte). */
++#define S3C_VIDWxxADD2_PAGEWIDTH_F(x) (((x)&0x1FFF)<<0) /* Virtual screen page width (the number of byte). */
++
++/* VIDEO Interrupt Control 0 register - VIDINTCON0 */
++#define S3C_VIDINTCON0_FIFOINTERVAL(x) (((x)&0x3F)<<20)
++#define S3C_VIDINTCON0_SYSMAINCON_DISABLE (0<<19)
++#define S3C_VIDINTCON0_SYSMAINCON_ENABLE (1<<19)
++#define S3C_VIDINTCON0_SYSSUBCON_DISABLE (0<<18)
++#define S3C_VIDINTCON0_SYSSUBCON_ENABLE (1<<18)
++#define S3C_VIDINTCON0_SYSIFDONE_DISABLE (0<<17)
++#define S3C_VIDINTCON0_SYSIFDONE_ENABLE (1<<17)
++#define S3C_VIDINTCON0_FRAMESEL0_BACK (0<<15)
++#define S3C_VIDINTCON0_FRAMESEL0_VSYNC (1<<15)
++#define S3C_VIDINTCON0_FRAMESEL0_ACTIVE (2<<15)
++#define S3C_VIDINTCON0_FRAMESEL0_FRONT (3<<15)
++#define S3C_VIDINTCON0_FRAMESEL0_MASK (3<<15)
++#define S3C_VIDINTCON0_FRAMESEL1_NONE (0<<13)
++#define S3C_VIDINTCON0_FRAMESEL1_BACK (1<<13)
++#define S3C_VIDINTCON0_FRAMESEL1_VSYNC (2<<13)
++#define S3C_VIDINTCON0_FRAMESEL1_FRONT (3<<13)
++#define S3C_VIDINTCON0_INTFRMEN_DISABLE (0<<12)
++#define S3C_VIDINTCON0_INTFRMEN_ENABLE (1<<12)
++#define S3C_VIDINTCON0_FRAMEINT_MASK (0x1F<<12)
++#define S3C_VIDINTCON0_FIFOSEL_WIN4 (1<<11)
++#define S3C_VIDINTCON0_FIFOSEL_WIN3 (1<<10)
++#define S3C_VIDINTCON0_FIFOSEL_WIN2 (1<<9)
++#define S3C_VIDINTCON0_FIFOSEL_WIN1 (1<<6)
++#define S3C_VIDINTCON0_FIFOSEL_WIN0 (1<<5)
++#define S3C_VIDINTCON0_FIFOSEL_ALL (0x73<<5)
++#define S3C_VIDINTCON0_FIFOLEVEL_25 (0<<2)
++#define S3C_VIDINTCON0_FIFOLEVEL_50 (1<<2)
++#define S3C_VIDINTCON0_FIFOLEVEL_75 (2<<2)
++#define S3C_VIDINTCON0_FIFOLEVEL_EMPTY (3<<2)
++#define S3C_VIDINTCON0_FIFOLEVEL_FULL (4<<2)
++#define S3C_VIDINTCON0_INTFIFOEN_DISABLE (0<<1)
++#define S3C_VIDINTCON0_INTFIFOEN_ENABLE (1<<1)
++#define S3C_VIDINTCON0_INTEN_DISABLE (0<<0)
++#define S3C_VIDINTCON0_INTEN_ENABLE (1<<0)
++#define S3C_VIDINTCON0_INTEN_MASK (1<<0)
++
++/* VIDEO Interrupt Control 1 register - VIDINTCON1 */
++#define S3C_VIDINTCON1_INTI80PEND (0<<2)
++#define S3C_VIDINTCON1_INTFRMPEND (1<<1)
++#define S3C_VIDINTCON1_INTFIFOPEND (1<<0)
++
++/* WIN 1~4 Color Key 0 register - WxKEYCON0 */
++#define S3C_WxKEYCON0_KEYBLEN_DISABLE (0<<26)
++#define S3C_WxKEYCON0_KEYBLEN_ENABLE (1<<26)
++#define S3C_WxKEYCON0_KEYEN_F_DISABLE (0<<25)
++#define S3C_WxKEYCON0_KEYEN_F_ENABLE (1<<25)
++#define S3C_WxKEYCON0_DIRCON_MATCH_FG_IMAGE (0<<24)
++#define S3C_WxKEYCON0_DIRCON_MATCH_BG_IMAGE (1<<24)
++#define S3C_WxKEYCON0_COMPKEY(x) (((x)&0xFFFFFF)<<0)
++
++/* WIN 1~4 Color Key 1 register - WxKEYCON1 */
++#define S3C_WxKEYCON1_COLVAL(x) (((x)&0xFFFFFF)<<0)
++
++/* Dithering Control 1 register - DITHMODE */
++#define S3C_DITHMODE_RDITHPOS_8BIT (0<<5)
++#define S3C_DITHMODE_RDITHPOS_6BIT (1<<5)
++#define S3C_DITHMODE_RDITHPOS_5BIT (2<<5)
++#define S3C_DITHMODE_GDITHPOS_8BIT (0<<3)
++#define S3C_DITHMODE_GDITHPOS_6BIT (1<<3)
++#define S3C_DITHMODE_GDITHPOS_5BIT (2<<3)
++#define S3C_DITHMODE_BDITHPOS_8BIT (0<<1)
++#define S3C_DITHMODE_BDITHPOS_6BIT (1<<1)
++#define S3C_DITHMODE_BDITHPOS_5BIT (2<<1)
++#define S3C_DITHMODE_RGB_DITHPOS_MASK (0x3f<<1)
++#define S3C_DITHMODE_DITHERING_DISABLE (0<<0)
++#define S3C_DITHMODE_DITHERING_ENABLE (1<<0)
++#define S3C_DITHMODE_DITHERING_MASK (1<<0)
++
++/* Window 0~4 Color map register - WINxMAP */
++#define S3C_WINxMAP_MAPCOLEN_F_ENABLE (1<<24)
++#define S3C_WINxMAP_MAPCOLEN_F_DISABLE (0<<24)
++#define S3C_WINxMAP_MAPCOLOR (((x)&0xFFFFFF)<<0)
++
++/* Window Palette Control register - WPALCON */
++#define S3C_WPALCON_PALUPDATEEN (1<<9)
++#define S3C_WPALCON_W4PAL_16BIT_A (1<<8) /* A:5:5:5 */
++#define S3C_WPALCON_W4PAL_16BIT (0<<8) /* 5:6:5 */
++#define S3C_WPALCON_W3PAL_16BIT_A (1<<7) /* A:5:5:5 */
++#define S3C_WPALCON_W3PAL_16BIT (0<<7) /* 5:6:5 */
++#define S3C_WPALCON_W2PAL_16BIT_A (1<<6) /* A:5:5:5 */
++#define S3C_WPALCON_W2PAL_16BIT (0<<6) /* 5:6:5 */
++#define S3C_WPALCON_W1PAL_25BIT_A (0<<3) /* A:8:8:8 */
++#define S3C_WPALCON_W1PAL_24BIT (1<<3) /* 8:8:8 */
++#define S3C_WPALCON_W1PAL_19BIT_A (2<<3) /* A:6:6:6 */
++#define S3C_WPALCON_W1PAL_18BIT_A (3<<3) /* A:6:6:5 */
++#define S3C_WPALCON_W1PAL_18BIT (4<<3) /* 6:6:6 */
++#define S3C_WPALCON_W1PAL_16BIT_A (5<<3) /* A:5:5:5 */
++#define S3C_WPALCON_W1PAL_16BIT (6<<3) /* 5:6:5 */
++#define S3C_WPALCON_W0PAL_25BIT_A (0<<0) /* A:8:8:8 */
++#define S3C_WPALCON_W0PAL_24BIT (1<<0) /* 8:8:8 */
++#define S3C_WPALCON_W0PAL_19BIT_A (2<<0) /* A:6:6:6 */
++#define S3C_WPALCON_W0PAL_18BIT_A (3<<0) /* A:6:6:5 */
++#define S3C_WPALCON_W0PAL_18BIT (4<<0) /* 6:6:6 */
++#define S3C_WPALCON_W0PAL_16BIT_A (5<<0) /* A:5:5:5 */
++#define S3C_WPALCON_W0PAL_16BIT (6<<0) /* 5:6:5 */
++
++/* I80/RGB Trigger Control register - TRIGCON */
++#define S3C_TRIGCON_SWFRSTATUS_REQUESTED (1<<2)
++#define S3C_TRIGCON_SWFRSTATUS_NOT_REQUESTED (0<<2)
++#define S3C_TRIGCON_SWTRGCMD (1<<1)
++#define S3C_TRIGCON_TRGMODE_ENABLE (1<<0)
++#define S3C_TRIGCON_TRGMODE_DISABLE (0<<0)
++
++/* LCD I80 Interface Control 0 register - I80IFCONA0 */
++#define S3C_I80IFCONAx_LCD_CS_SETUP(x) (((x)&0xF)<<16)
++#define S3C_I80IFCONAx_LCD_WR_SETUP(x) (((x)&0xF)<<12)
++#define S3C_I80IFCONAx_LCD_WR_ACT(x) (((x)&0xF)<<8)
++#define S3C_I80IFCONAx_LCD_WR_HOLD(x) (((x)&0xF)<<4)
++
++
++/***************************************************************************/
++/*HOST IF registers */
++/* Host I/F A - */
++#define S3C_HOSTIFAREG(x) ((x) + S3C24XX_VA_HOSTIFA)
++#define S3C_HOSTIFAREG_PHYS(x) ((x) + S3C24XX_PA_HOSTIFA)
++
++/* Host I/F B - Modem I/F */
++#define S3C_HOSTIFBREG(x) ((x) + S3C24XX_VA_HOSTIFB)
++#define S3C_HOSTIFBREG_PHYS(x) ((x) + S3C24XX_PA_HOSTIFB)
++
++#define S3C_HOSTIFB_INT2AP S3C_HOSTIFBREG(0x8000)
++#define S3C_HOSTIFB_INT2MSM S3C_HOSTIFBREG(0x8004)
++#define S3C_HOSTIFB_MIFCON S3C_HOSTIFBREG(0x8008)
++#define S3C_HOSTIFB_MIFPCON S3C_HOSTIFBREG(0x800C)
++#define S3C_HOSTIFB_MSMINTCLR S3C_HOSTIFBREG(0x8010)
++
++#define S3C_HOSTIFB_MIFCON_INT2MSM_DIS (0x0<<3)
++#define S3C_HOSTIFB_MIFCON_INT2MSM_EN (0x1<<3)
++#define S3C_HOSTIFB_MIFCON_INT2AP_DIS (0x0<<2)
++#define S3C_HOSTIFB_MIFCON_INT2AP_EN (0x1<<2)
++#define S3C_HOSTIFB_MIFCON_WAKEUP_DIS (0x0<<1)
++#define S3C_HOSTIFB_MIFCON_WAKEUP_EN (0x1<<1)
++
++#define S3C_HOSTIFB_MIFPCON_SEL_VSYNC_DIR_OUT (0x0<<5)
++#define S3C_HOSTIFB_MIFPCON_SEL_VSYNC_DIR_IN (0x1<<5)
++#define S3C_HOSTIFB_MIFPCON_INT2M_LEVEL_DIS (0x0<<4)
++#define S3C_HOSTIFB_MIFPCON_INT2M_LEVEL_EN (0x1<<4)
++#define S3C_HOSTIFB_MIFPCON_SEL_NORMAL (0x0<<3)
++#define S3C_HOSTIFB_MIFPCON_SEL_BYPASS (0x1<<3)
++
++#define S3C_HOSTIFB_MIFPCON_SEL_RS0 0
++#define S3C_HOSTIFB_MIFPCON_SEL_RS1 1
++#define S3C_HOSTIFB_MIFPCON_SEL_RS2 2
++#define S3C_HOSTIFB_MIFPCON_SEL_RS3 3
++#define S3C_HOSTIFB_MIFPCON_SEL_RS4 4
++#define S3C_HOSTIFB_MIFPCON_SEL_RS5 5
++#define S3C_HOSTIFB_MIFPCON_SEL_RS6 6
++
++#endif /* ___ASM_ARCH_REGS_LCD_H */
++
++
++
Added: developers/werner/gta03/cam/patches/add-s3c-camif.patch
===================================================================
--- developers/werner/gta03/cam/patches/add-s3c-camif.patch (rev 0)
+++ developers/werner/gta03/cam/patches/add-s3c-camif.patch 2009-02-26 15:51:03 UTC (rev 4938)
@@ -0,0 +1,4390 @@
+Index: cam/drivers/media/video/s3c_camera_driver.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ cam/drivers/media/video/s3c_camera_driver.c 2009-02-26 21:30:41.000000000 +0800
+@@ -0,0 +1,1884 @@
++/* drivers/media/video/s3c_camera_driver.c
++ *
++ * Copyright (c) 2008 Samsung Electronics
++ *
++ * Samsung S3C Camera driver
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/fs.h>
++#include <linux/kernel.h>
++#include <linux/major.h>
++#include <linux/slab.h>
++#include <linux/poll.h>
++#include <linux/signal.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/interrupt.h>
++#include <linux/kmod.h>
++#include <linux/vmalloc.h>
++#include <linux/init.h>
++#include <linux/irq.h>
++#include <linux/mm.h>
++#include <linux/videodev2.h>
++#include <linux/platform_device.h>
++#include <linux/clk.h>
++#include <linux/semaphore.h>
++#include <asm/io.h>
++#include <asm/page.h>
++#include <plat/regs-gpio.h>
++#include <plat/regs-camif.h>
++#include <media/v4l2-dev.h>
++#include <media/v4l2-ioctl.h>
++#include "s3c_camif.h"
++#include "videodev2_s3c.h"
++
++static struct clk *cam_clock;
++camif_cfg_t s3c_fimc[CAMIF_DEV_NUM];
++extern camif_cis_t msdma_input;
++extern int s3c_camif_do_postprocess(camif_cfg_t *cfg);
++
++/*************************************************************************
++ * Utility part
++ ************************************************************************/
++camif_cfg_t *s3c_camif_get_fimc_object(int nr)
++{
++ camif_cfg_t *ret = NULL;
++
++ switch (nr) {
++ case CODEC_MINOR:
++ ret = &s3c_fimc[FIMC_CODEC_INDEX];
++ break;
++
++ case PREVIEW_MINOR:
++ ret = &s3c_fimc[FIMC_PREVIEW_INDEX];
++ break;
++
++ default:
++ printk(KERN_ERR "Unknown minor number\n");
++ }
++
++ return ret;
++}
++
++#if defined(FSM_ON_PREVIEW)
++static int s3c_camif_check_global_status(camif_cfg_t *cfg)
++{
++ int ret = 0;
++
++ if (down_interruptible((struct semaphore *) &cfg->cis->lock))
++ return -ERESTARTSYS;
++
++ if (cfg->cis->status & CWANT2START) {
++ cfg->cis->status &= ~CWANT2START;
++ cfg->auto_restart = 1;
++ ret = 1;
++ } else {
++ ret = 0; /* There is no codec */
++ cfg->auto_restart = 0; /* Duplicated ..Dummy */
++ }
++
++ up((struct semaphore *) &cfg->cis->lock);
++
++ return ret;
++}
++#endif
++
++static int s3c_camif_convert_format(int pixfmt, int *fmtptr)
++{
++ int fmt = CAMIF_YCBCR420;
++ int depth = 12;
++
++ switch (pixfmt) {
++ case V4L2_PIX_FMT_RGB565:
++ case V4L2_PIX_FMT_RGB565X:
++ fmt = CAMIF_RGB16;
++ depth = 16;
++ break;
++
++ case V4L2_PIX_FMT_BGR24: /* Not tested */
++ case V4L2_PIX_FMT_RGB24:
++ fmt = CAMIF_RGB24;
++ depth = 24;
++ break;
++
++ case V4L2_PIX_FMT_BGR32:
++ case V4L2_PIX_FMT_RGB32:
++ fmt = CAMIF_RGB24;
++ depth = 32;
++ break;
++
++ case V4L2_PIX_FMT_GREY: /* Not tested */
++ fmt = CAMIF_YCBCR420;
++ depth = 8;
++ break;
++
++ case V4L2_PIX_FMT_YUYV:
++ case V4L2_PIX_FMT_UYVY:
++ fmt = CAMIF_YCBCR422I;
++ depth = 16;
++ break;
++
++ case V4L2_PIX_FMT_YUV422P:
++ fmt = CAMIF_YCBCR422;
++ depth = 16;
++ break;
++
++ case V4L2_PIX_FMT_YUV420:
++ fmt = CAMIF_YCBCR420;
++ depth = 12;
++ break;
++ }
++
++ if (fmtptr) *fmtptr = fmt;
++
++ return depth;
++}
++
++static int s3c_camif_set_fb_info(camif_cfg_t *cfg, int depth, int fourcc)
++{
++ /* To define v4l2_format used currently */
++ cfg->v2.frmbuf.fmt.width = cfg->target_x;
++ cfg->v2.frmbuf.fmt.height = cfg->target_y;
++ cfg->v2.frmbuf.fmt.field = V4L2_FIELD_NONE;
++ cfg->v2.frmbuf.fmt.pixelformat = fourcc;
++ cfg->v2.frmbuf.fmt.bytesperline = cfg->v2.frmbuf.fmt.width * depth >> 3;
++ cfg->v2.frmbuf.fmt.sizeimage = cfg->v2.frmbuf.fmt.height * cfg->v2.frmbuf.fmt.bytesperline;
++
++ return 0;
++}
++
++static int s3c_camif_convert_type(camif_cfg_t *cfg, int f)
++{
++ int pixfmt;
++ cfg->target_x = cfg->v2.frmbuf.fmt.width;
++ cfg->target_y = cfg->v2.frmbuf.fmt.height;
++
++ s3c_camif_convert_format(cfg->v2.frmbuf.fmt.pixelformat, &pixfmt);
++
++ cfg->dst_fmt = pixfmt;
++
++ return 0;
++}
++
++/*************************************************************************
++ * Control part
++ ************************************************************************/
++static int s3c_camif_start_capture(camif_cfg_t * cfg)
++{
++ int ret = 0;
++
++ cfg->capture_enable = CAMIF_DMA_ON;
++
++ s3c_camif_start_dma(cfg);
++
++ cfg->status = CAMIF_STARTED;
++
++ if (!(cfg->fsm == CAMIF_SET_LAST_INT || cfg->fsm == CAMIF_CONTINUOUS_INT)) {
++ cfg->fsm = CAMIF_DUMMY_INT;
++ cfg->perf.frames = 0;
++ }
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++ if (cfg->input_channel == MSDMA_FROM_CODEC)
++ s3c_camif_start_codec_msdma(cfg);
++#endif
++ return ret;
++}
++
++ssize_t s3c_camif_start_preview(camif_cfg_t *cfg)
++{
++ cfg->capture_enable = CAMIF_DMA_ON;
++
++ s3c_camif_start_dma(cfg);
++
++ cfg->status = CAMIF_STARTED;
++ cfg->fsm = CAMIF_1st_INT;
++ cfg->perf.frames = 0;
++
++ return 0;
++}
++
++ssize_t s3c_camif_stop_preview(camif_cfg_t *cfg)
++{
++ cfg->capture_enable = CAMIF_DMA_OFF;
++ cfg->status = CAMIF_STOPPED;
++
++ s3c_camif_stop_dma(cfg);
++
++ cfg->perf.frames = 0;
++
++ return 0;
++}
++
++ssize_t s3c_camif_stop_capture(camif_cfg_t *cfg)
++{
++ cfg->capture_enable = CAMIF_DMA_OFF;
++ cfg->status = CAMIF_STOPPED;
++
++ s3c_camif_stop_dma(cfg);
++
++ cfg->perf.frames = 0;
++
++ return 0;
++}
++
++ssize_t s3c_camif_stop_fimc(camif_cfg_t *cfg)
++{
++ cfg->capture_enable = CAMIF_BOTH_DMA_OFF;
++ cfg->fsm = CAMIF_DUMMY_INT;
++ cfg->perf.frames = 0;
++
++ s3c_camif_stop_dma(cfg);
++
++ return 0;
++}
++
++#if defined(FSM_ON_PREVIEW)
++static void s3c_camif_start_preview_with_codec(camif_cfg_t *cfg)
++{
++ camif_cfg_t *other = (camif_cfg_t *)cfg->other;
++
++ /* Preview Stop */
++ cfg->capture_enable = CAMIF_DMA_OFF;
++ s3c_camif_stop_dma(cfg);
++
++ /* Start Preview and CODEC */
++ cfg->capture_enable =CAMIF_BOTH_DMA_ON;
++
++ s3c_camif_start_dma(cfg);
++ cfg->fsm = CAMIF_1st_INT; /* For Preview */
++
++ if (!other)
++ panic("Unexpected error: other is null\n");
++
++ switch (other->pp_num) {
++ case 4:
++ other->fsm = CAMIF_1st_INT; /* For CODEC */
++ break;
++
++ case 1:
++ other->fsm = CAMIF_Yth_INT;
++ break;
++
++ default:
++ panic("Invalid pingpong number");
++ break;
++ }
++}
++
++static void s3c_camif_auto_restart(camif_cfg_t *cfg)
++{
++ if (cfg->auto_restart)
++ s3c_camif_start_preview_with_codec(cfg);
++}
++#endif
++
++static void s3c_camif_change_mode(camif_cfg_t *cfg, int mode)
++{
++ camif_cis_t *cis = cfg->cis;
++ int res;
++
++ if (mode == SENSOR_MAX) {
++#if defined(CONFIG_VIDEO_SAMSUNG_S5K3AA)
++ res = SENSOR_SXGA;
++#elif defined(CONFIG_VIDEO_SAMSUNG_S5K3BA)
++ res = SENSOR_UXGA;
++
++/* 4BA max is UXGA, but we don't have UXGA control values */
++#elif defined(CONFIG_VIDEO_SAMSUNG_S5K4BA)
++ res = SENSOR_SVGA;
++#endif
++ } else if (mode == SENSOR_DEFAULT) {
++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA)
++ res = SENSOR_SVGA;
++#else
++ res = SENSOR_VGA;
++#endif
++ } else
++ res = mode;
++
++ s3c_camif_stop_fimc(cfg);
++
++ switch (res) {
++ case SENSOR_SXGA:
++ printk(KERN_INFO "Resolution changed into SXGA (1280x1024) mode -> 1.3M\n");
++ cis->sensor->driver->command(cis->sensor, SENSOR_SXGA, NULL);
++ cis->source_x = 1280;
++ cis->source_y = 1024;
++ break;
++
++ case SENSOR_UXGA:
++ printk(KERN_INFO "Resolution changed into UXGA (1600x1200) mode -> 2.0M\n");
++ cis->sensor->driver->command(cis->sensor, SENSOR_UXGA, NULL);
++ cis->source_x = 1600;
++ cis->source_y = 1200;
++ break;
++
++ case SENSOR_SVGA:
++ printk(KERN_INFO "Resolution changed back to SVGA (800x600) mode\n");
++ cis->sensor->driver->command(cis->sensor, SENSOR_SVGA, NULL);
++ cis->source_x = 800;
++ cis->source_y = 600;
++ break;
++
++ case SENSOR_VGA:
++ printk(KERN_INFO "Resolution changed back to VGA (640x480) mode (default)\n");
++ cis->sensor->driver->command(cis->sensor, SENSOR_VGA, NULL);
++ cis->source_x = 640;
++ cis->source_y = 480;
++ break;
++ }
++
++ cis->win_hor_ofst = cis->win_hor_ofst2 = 0;
++ cis->win_ver_ofst = cis->win_ver_ofst2 = 0;
++
++ s3c_camif_set_source_format(cis);
++}
++
++static int s3c_camif_check_zoom_range(camif_cfg_t *cfg, int type)
++{
++ switch (type) {
++ case V4L2_CID_ZOOMIN:
++ if (((cfg->sc.modified_src_x - (cfg->cis->win_hor_ofst + \
++ ZOOM_AT_A_TIME_IN_PIXELS + cfg->cis->win_hor_ofst2 + \
++ ZOOM_AT_A_TIME_IN_PIXELS)) / cfg->sc.prehratio) > ZOOM_IN_MAX) {
++ printk(KERN_INFO "Invalid Zoom-in: this zoom-in on preview scaler already comes to the maximum\n");
++ return 0;
++ }
++
++ cfg->sc.zoom_in_cnt++;
++ break;
++
++ case V4L2_CID_ZOOMOUT:
++ if (cfg->sc.zoom_in_cnt > 0) {
++ cfg->sc.zoom_in_cnt--;
++ break;
++ } else {
++ printk(KERN_INFO "Invalid Zoom-out: this zoom-out on preview scaler already comes to the minimum\n");
++ return 0;
++ }
++
++ break;
++
++ default:
++ break;
++ }
++
++ return 1;
++}
++
++static int s3c_camif_restart_preview(camif_cfg_t *cfg)
++{
++ int ret = 0;
++
++ s3c_camif_stop_preview(cfg);
++
++ if (s3c_camif_control_fimc(cfg)) {
++ printk(KERN_ERR "S3C fimc control failed\n");
++ ret = -1;
++ }
++
++ s3c_camif_start_preview(cfg);
++
++ return ret;
++}
++
++static int s3c_camif_send_sensor_command(camif_cfg_t *cfg, unsigned int cmd, int arg)
++{
++ cfg->cis->sensor->driver->command(cfg->cis->sensor, cmd, (void *) arg);
++
++ return 0;
++}
++
++/*************************************************************************
++ * V4L2 part
++ ************************************************************************/
++static int s3c_camif_v4l2_querycap(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_capability *cap = arg;
++
++ strcpy(cap->driver, "S3C FIMC Camera driver");
++ strlcpy(cap->card, cfg->v->name, sizeof(cap->card));
++ sprintf(cap->bus_info, "FIMC AHB Bus");
++
++ cap->version = 0;
++ cap->capabilities = V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_g_fbuf(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_framebuffer *fb = arg;
++
++ *fb = cfg->v2.frmbuf;
++
++ fb->base = cfg->v2.frmbuf.base;
++ fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
++
++ fb->fmt.pixelformat = cfg->v2.frmbuf.fmt.pixelformat;
++ fb->fmt.width = cfg->v2.frmbuf.fmt.width;
++ fb->fmt.height = cfg->v2.frmbuf.fmt.height;
++ fb->fmt.bytesperline = cfg->v2.frmbuf.fmt.bytesperline;
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_s_fbuf(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_framebuffer *fb = arg;
++ int i, depth;
++
++ for (i = 0; i < NUMBER_OF_PREVIEW_FORMATS; i++)
++ if (fimc_preview_formats[i].pixelformat == fb->fmt.pixelformat)
++ break;
++
++ if (i == NUMBER_OF_PREVIEW_FORMATS)
++ return -EINVAL;
++
++ cfg->v2.frmbuf.base = fb->base;
++ cfg->v2.frmbuf.flags = fb->flags;
++ cfg->v2.frmbuf.capability = fb->capability;
++
++ cfg->target_x = fb->fmt.width;
++ cfg->target_y = fb->fmt.height;
++
++ depth = s3c_camif_convert_format(fb->fmt.pixelformat, (int *) &(cfg->dst_fmt));
++ s3c_camif_set_fb_info(cfg, depth, fb->fmt.pixelformat);
++
++ return s3c_camif_control_fimc(cfg);
++}
++
++static int s3c_camif_v4l2_g_fmt(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_format *f = (struct v4l2_format *) arg;
++ int size = sizeof(struct v4l2_pix_format);
++ int ret = -1;
++
++ switch (f->type) {
++ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
++ memset(&f->fmt.pix, 0, size);
++ memcpy(&f->fmt.pix, &cfg->v2.frmbuf.fmt, size);
++ ret = 0;
++ break;
++
++ default:
++ break;
++ }
++
++ return ret;
++}
++
++static int s3c_camif_v4l2_s_fmt(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_format *f = (struct v4l2_format *) arg;
++ int ret = -1;
++
++ switch (f->type) {
++ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
++ cfg->v2.frmbuf.fmt = f->fmt.pix;
++ cfg->v2.status |= CAMIF_v4L2_DIRTY;
++ cfg->v2.status &= ~CAMIF_v4L2_DIRTY; /* dummy ? */
++
++ s3c_camif_convert_type(cfg, 1);
++ s3c_camif_control_fimc(cfg);
++ ret = 0;
++ break;
++
++ default:
++ break;
++ }
++
++ return ret;
++}
++
++static int s3c_camif_v4l2_enum_fmt(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_fmtdesc *f = arg;
++ int index = f->index;
++
++ if (index >= NUMBER_OF_CODEC_FORMATS)
++ return -EINVAL;
++
++ switch (f->type) {
++ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
++ break;
++
++ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
++ default:
++ return -EINVAL;
++ }
++
++ memset(f, 0, sizeof(*f));
++ memcpy(f, cfg->v2.fmtdesc + index, sizeof(*f));
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_overlay(camif_cfg_t *cfg, void *arg)
++{
++ int on = *((int *) arg);
++ int ret;
++
++ if (on != 0)
++ ret = s3c_camif_start_preview(cfg);
++ else
++ ret = s3c_camif_stop_preview(cfg);
++
++ return ret;
++}
++
++static int s3c_camif_v4l2_g_ctrl(camif_cfg_t *cfg, void *arg)
++{
++ return 0;
++}
++
++static int s3c_camif_v4l2_s_ctrl(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_control *ctrl = (struct v4l2_control *) arg;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ORIGINAL:
++ case V4L2_CID_ARBITRARY:
++ case V4L2_CID_NEGATIVE:
++ case V4L2_CID_EMBOSSING:
++ case V4L2_CID_ART_FREEZE:
++ case V4L2_CID_SILHOUETTE:
++ cfg->effect = ctrl->value;
++ s3c_camif_change_effect(cfg);
++ break;
++
++ case V4L2_CID_HFLIP:
++ cfg->flip = CAMIF_FLIP_X;
++ s3c_camif_change_flip(cfg);
++ break;
++
++ case V4L2_CID_VFLIP:
++ cfg->flip = CAMIF_FLIP_Y;
++ s3c_camif_change_flip(cfg);
++ break;
++
++ case V4L2_CID_ROTATE_180:
++ cfg->flip = CAMIF_FLIP_MIRROR;
++ s3c_camif_change_flip(cfg);
++ break;
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++ case V4L2_CID_ROTATE_90:
++ cfg->flip = CAMIF_ROTATE_90;
++ s3c_camif_change_flip(cfg);
++ break;
++
++ case V4L2_CID_ROTATE_270:
++ cfg->flip = CAMIF_FLIP_ROTATE_270;
++ s3c_camif_change_flip(cfg);
++ break;
++#endif
++
++ case V4L2_CID_ROTATE_BYPASS:
++ cfg->flip = CAMIF_FLIP;
++ s3c_camif_change_flip(cfg);
++ break;
++
++ case V4L2_CID_ZOOMIN:
++ if (s3c_camif_check_zoom_range(cfg, ctrl->id)) {
++ cfg->cis->win_hor_ofst += ZOOM_AT_A_TIME_IN_PIXELS;
++ cfg->cis->win_ver_ofst += ZOOM_AT_A_TIME_IN_PIXELS;
++ cfg->cis->win_hor_ofst2 += ZOOM_AT_A_TIME_IN_PIXELS;
++ cfg->cis->win_ver_ofst2 += ZOOM_AT_A_TIME_IN_PIXELS;
++
++ s3c_camif_restart_preview(cfg);
++ }
++
++ break;
++
++ case V4L2_CID_ZOOMOUT:
++ if (s3c_camif_check_zoom_range(cfg, ctrl->id)) {
++ cfg->cis->win_hor_ofst -= ZOOM_AT_A_TIME_IN_PIXELS;
++ cfg->cis->win_ver_ofst -= ZOOM_AT_A_TIME_IN_PIXELS;
++ cfg->cis->win_hor_ofst2 -= ZOOM_AT_A_TIME_IN_PIXELS;
++ cfg->cis->win_ver_ofst2 -= ZOOM_AT_A_TIME_IN_PIXELS;
++
++ s3c_camif_restart_preview(cfg);
++ }
++
++ break;
++
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ s3c_camif_send_sensor_command(cfg, SENSOR_WB, ctrl->value);
++ break;
++
++ default:
++ printk(KERN_ERR "Invalid control id: %d\n", ctrl->id);
++ return -1;
++ }
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_streamon(camif_cfg_t *cfg, void *arg)
++{
++ int ret = 0;
++
++ ret = s3c_camif_start_capture(cfg);
++
++ return ret;
++}
++
++static int s3c_camif_v4l2_streamoff(camif_cfg_t *cfg, void *arg)
++{
++ int ret = 0;
++
++ cfg->cis->status &= ~C_WORKING;
++
++ s3c_camif_stop_capture(cfg);
++
++ return ret;
++}
++
++static int s3c_camif_v4l2_g_input(camif_cfg_t *cfg, void *arg)
++{
++ unsigned int index = *((int *) arg);
++
++ index = cfg->v2.input->index;
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_s_input(camif_cfg_t *cfg, unsigned int index)
++{
++ int ret = -1;
++
++ if (index >= NUMBER_OF_INPUTS)
++ ret = -1;
++ else {
++ cfg->v2.input = &fimc_inputs[index];
++
++ if (cfg->v2.input->type == V4L2_INPUT_TYPE_MSDMA) {
++ if (cfg->dma_type & CAMIF_PREVIEW) {
++ cfg->input_channel = MSDMA_FROM_PREVIEW;
++ ret = 0;
++ } else if (cfg->dma_type & CAMIF_CODEC) {
++ cfg->input_channel = MSDMA_FROM_CODEC;
++ ret = 0;
++ }
++ } else {
++ cfg->input_channel = CAMERA_INPUT;
++ ret = 0;
++ }
++ }
++
++ return ret;
++}
++
++static int s3c_camif_v4l2_g_output(camif_cfg_t *cfg, void *arg)
++{
++ unsigned int index = *((int *) arg);
++
++ index = cfg->v2.output->index;
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_s_output(camif_cfg_t *cfg, unsigned int index)
++{
++ if (index >= NUMBER_OF_OUTPUTS)
++ return -EINVAL;
++ else {
++ cfg->v2.output = (struct v4l2_output *) &fimc_outputs[index];
++ return 0;
++ }
++}
++
++static int s3c_camif_v4l2_enum_input(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_input *i = arg;
++
++ if (i->index >= NUMBER_OF_INPUTS)
++ return -EINVAL;
++
++ memcpy(i, &fimc_inputs[i->index], sizeof(struct v4l2_input));
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_enum_output(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_output *i = arg;
++
++ if ((i->index) >= NUMBER_OF_OUTPUTS)
++ return -EINVAL;
++
++ memcpy(i, &fimc_outputs[i->index], sizeof(struct v4l2_output));
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_reqbufs(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_requestbuffers *req = arg;
++
++ if (req->memory != V4L2_MEMORY_MMAP) {
++ printk(KERN_ERR "Only V4L2_MEMORY_MMAP capture is supported\n");
++ return -EINVAL;
++ }
++
++ /* control user input */
++ if (req->count > 2)
++ req->count = 4;
++ else if (req->count > 1)
++ req->count = 2;
++ else
++ req->count = 1;
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_querybuf(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_buffer *buf = arg;
++
++ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && buf->memory != V4L2_MEMORY_MMAP)
++ return -1;
++
++ buf->length = cfg->buffer_size;
++ buf->m.offset = buf->length * buf->index;
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_qbuf(camif_cfg_t *cfg, void *arg)
++{
++ return 0;
++}
++
++static int s3c_camif_v4l2_dqbuf(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_buffer *buf = arg;
++
++ buf->index = cfg->cur_frame_num % cfg->pp_num;
++
++ return 0;
++}
++
++/*
++ * S3C specific
++ */
++static int s3c_camif_v4l2_s_msdma(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_msdma_format *f = arg;
++ int ret = -1;
++
++ switch(f->input_path) {
++ case V4L2_MSDMA_PREVIEW:
++ cfg->cis->user--; /* CIS will be replaced with a CIS for MSDMA */
++
++ cfg->cis = &msdma_input;
++ cfg->cis->user++;
++ cfg->input_channel = MSDMA_FROM_PREVIEW;
++ break;
++
++ case V4L2_MSDMA_CODEC:
++ cfg->cis->user--; /* CIS will be replaced with a CIS for MSDMA */
++
++ cfg->cis = &msdma_input;
++ cfg->cis->user++;
++ cfg->input_channel = MSDMA_FROM_CODEC;
++ break;
++
++ default:
++ cfg->input_channel = CAMERA_INPUT;
++ break;
++ }
++
++ cfg->cis->source_x = f->width;
++ cfg->cis->source_y = f->height;
++
++ s3c_camif_convert_format(f->pixelformat, (int *) &cfg->src_fmt);
++
++ cfg->cis->win_hor_ofst = 0;
++ cfg->cis->win_ver_ofst = 0;
++ cfg->cis->win_hor_ofst2 = 0;
++ cfg->cis->win_ver_ofst2 = 0;
++
++ ret = s3c_camif_control_fimc(cfg);
++
++ switch(f->input_path) {
++ case V4L2_MSDMA_PREVIEW:
++ ret = s3c_camif_start_preview(cfg);
++ break;
++
++ case V4L2_MSDMA_CODEC:
++ ret = s3c_camif_start_capture(cfg);
++ break;
++
++ default:
++ break;
++
++ }
++
++ return ret;
++}
++
++static int s3c_camif_v4l2_msdma_start(camif_cfg_t *cfg, void *arg)
++{
++ if (cfg->input_channel == MSDMA_FROM_PREVIEW) {
++ cfg->msdma_status = 1;
++ s3c_camif_start_preview_msdma(cfg);
++ }
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_msdma_stop(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_msdma_format *f = arg;
++ int ret = -1;
++
++ cfg->cis->status &= ~C_WORKING;
++ cfg->msdma_status = 0;
++
++ switch(f->input_path) {
++ case V4L2_MSDMA_PREVIEW:
++ ret = s3c_camif_stop_preview(cfg);
++ break;
++
++ case V4L2_MSDMA_CODEC:
++ ret = s3c_camif_stop_capture(cfg);
++ break;
++
++ default:
++ break;
++ }
++
++ return ret;
++}
++
++static int s3c_camif_v4l2_camera_start(camif_cfg_t *cfg, void *arg)
++{
++ return 0;
++}
++
++static int s3c_camif_v4l2_camera_stop(camif_cfg_t *cfg, void *arg)
++{
++ return 0;
++}
++
++static int s3c_camif_v4l2_cropcap(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_cropcap *cap = arg;
++
++ if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
++ cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
++ return -EINVAL;
++
++ /* crop limitations */
++ cfg->v2.crop_bounds.left = 0;
++ cfg->v2.crop_bounds.top = 0;
++ cfg->v2.crop_bounds.width = cfg->cis->source_x;
++ cfg->v2.crop_bounds.height = cfg->cis->source_y;
++
++ /* crop default values */
++ cfg->v2.crop_defrect.left = (cfg->cis->source_x - CROP_DEFAULT_WIDTH) / 2;
++ cfg->v2.crop_defrect.top = (cfg->cis->source_y - CROP_DEFAULT_HEIGHT) / 2;
++ cfg->v2.crop_defrect.width = CROP_DEFAULT_WIDTH;
++ cfg->v2.crop_defrect.height = CROP_DEFAULT_HEIGHT;
++
++ cap->bounds = cfg->v2.crop_bounds;
++ cap->defrect = cfg->v2.crop_defrect;
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_g_crop(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_crop *crop = arg;
++
++ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
++ crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
++ return -EINVAL;
++
++ crop->c = cfg->v2.crop_current;
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_s_crop(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_crop *crop = arg;
++
++ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
++ crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
++ return -EINVAL;
++
++ if (crop->c.height < 0)
++ return -EINVAL;
++
++ if (crop->c.width < 0)
++ return -EINVAL;
++
++ if ((crop->c.left + crop->c.width > cfg->cis->source_x) || \
++ (crop->c.top + crop->c.height > cfg->cis->source_y))
++ return -EINVAL;
++
++ cfg->v2.crop_current = crop->c;
++
++ cfg->cis->win_hor_ofst = (cfg->cis->source_x - crop->c.width) / 2;
++ cfg->cis->win_ver_ofst = (cfg->cis->source_y - crop->c.height) / 2;
++
++ cfg->cis->win_hor_ofst2 = cfg->cis->win_hor_ofst;
++ cfg->cis->win_ver_ofst2 = cfg->cis->win_ver_ofst;
++
++ s3c_camif_restart_preview(cfg);
++
++ return 0;
++}
++
++static int s3c_camif_v4l2_s_parm(camif_cfg_t *cfg, void *arg)
++{
++ struct v4l2_streamparm *sp = arg;
++
++ if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ if (sp->parm.capture.capturemode == V4L2_MODE_HIGHQUALITY) {
++ s3c_camif_change_mode(cfg, SENSOR_MAX);
++ s3c_camif_control_fimc(cfg);
++ } else {
++ s3c_camif_change_mode(cfg, SENSOR_DEFAULT);
++ s3c_camif_control_fimc(cfg);
++ }
++
++ return 0;
++}
++
++/*************************************************************************
++ * Interrupt part
++ ************************************************************************/
++#if defined(FSM_ON_CODEC) && !defined(USE_LAST_IRQ)
++int s3c_camif_do_fsm_codec(camif_cfg_t *cfg)
++{
++ int ret;
++
++ cfg->perf.frames++;
++
++ if ((cfg->fsm == CAMIF_DUMMY_INT) && (cfg->perf.frames > CAMIF_CAPTURE_SKIP_FRAMES))
++ cfg->fsm = CAMIF_NORMAL_INT;
++
++ switch (cfg->fsm) {
++ case CAMIF_DUMMY_INT:
++ DPRINTK(KERN_INFO "CAMIF_DUMMY_INT: %d\n", cfg->perf.frames);
++ cfg->status = CAMIF_STARTED;
++ cfg->fsm = CAMIF_DUMMY_INT;
++ ret = INSTANT_SKIP;
++ break;
++
++ case CAMIF_NORMAL_INT:
++ DPRINTK(KERN_INFO "CAMIF_NORMAL_INT: %d\n", cfg->perf.frames);
++ cfg->status = CAMIF_INT_HAPPEN;
++ cfg->fsm = CAMIF_CONTINUOUS_INT;
++ ret = INSTANT_GO;
++ break;
++
++ case CAMIF_CONTINUOUS_INT:
++ DPRINTK(KERN_INFO "CAMIF_CONTINUOS_INT: %d\n", cfg->perf.frames);
++ cfg->status = CAMIF_INT_HAPPEN;
++ cfg->fsm = CAMIF_CONTINUOUS_INT;
++ ret = INSTANT_GO;
++ break;
++
++ default:
++ printk(KERN_INFO "Unexpect INT: %d\n", cfg->fsm);
++ ret = INSTANT_SKIP;
++ break;
++ }
++
++ return ret;
++}
++#endif
++
++#if defined(FSM_ON_CODEC) && defined(USE_LAST_IRQ)
++int s3c_camif_do_fsm_codec_lastirq(camif_cfg_t *cfg)
++{
++ int ret;
++
++ cfg->perf.frames++;
++
++ if ((cfg->fsm == CAMIF_DUMMY_INT) && (cfg->perf.frames > (CAMIF_CAPTURE_SKIP_FRAMES - 2)))
++ cfg->fsm = CAMIF_SET_LAST_INT;
++
++ switch (cfg->fsm) {
++ case CAMIF_DUMMY_INT:
++ DPRINTK(KERN_INFO "CAMIF_DUMMY_INT: %d\n", cfg->perf.frames);
++ cfg->status = CAMIF_STARTED;
++ cfg->fsm = CAMIF_DUMMY_INT;
++ ret = INSTANT_SKIP;
++ break;
++
++ case CAMIF_SET_LAST_INT:
++ DPRINTK(KERN_INFO "CAMIF_SET_LAST_INT: %d\n", cfg->perf.frames);
++ s3c_camif_enable_lastirq(cfg);
++
++/* in 64xx, lastirq is not auto cleared. */
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++ s3c_camif_disable_lastirq(cfg);
++#endif
++ cfg->status = CAMIF_INT_HAPPEN;
++ cfg->fsm = CAMIF_STOP_CAPTURE;
++ ret = INSTANT_SKIP;
++ break;
++
++ case CAMIF_STOP_CAPTURE:
++ DPRINTK(KERN_INFO "CAMIF_STOP_CAPTURE: %d\n", cfg->perf.frames);
++ cfg->capture_enable = CAMIF_DMA_OFF;
++ s3c_camif_stop_dma(cfg);
++ cfg->fsm = CAMIF_LAST_IRQ;
++ ret = INSTANT_SKIP;
++ break;
++
++ case CAMIF_LAST_IRQ:
++ DPRINTK(KERN_INFO "CAMIF_LAST_IRQ: %d\n", cfg->perf.frames);
++ cfg->fsm = CAMIF_SET_LAST_INT;
++ cfg->status = CAMIF_INT_HAPPEN;
++ ret = INSTANT_GO;
++ break;
++
++ default:
++ printk(KERN_INFO "Unexpect INT: %d\n", cfg->fsm);
++ ret = INSTANT_SKIP;
++ break;
++ }
++
++ return ret;
++}
++#endif
++
++#if defined(FSM_ON_PREVIEW)
++static int s3c_camif_do_lastirq_preview(camif_cfg_t *cfg)
++{
++ int ret = 0;
++
++ cfg->perf.frames++;
++
++ if (cfg->fsm == CAMIF_NORMAL_INT) {
++ if (cfg->perf.frames % CHECK_FREQ == 0)
++ ret = s3c_camif_check_global_status(cfg);
++ }
++
++ if (ret > 0)
++ cfg->fsm = CAMIF_Xth_INT;
++
++ switch (cfg->fsm) {
++ case CAMIF_1st_INT:
++ DPRINTK(KERN_INFO "CAMIF_1st_INT INT\n");
++ cfg->fsm = CAMIF_NORMAL_INT;
++ ret = INSTANT_SKIP;
++ break;
++
++ case CAMIF_NORMAL_INT:
++ DPRINTK(KERN_INFO "CAMIF_NORMAL_INT\n");
++ cfg->status = CAMIF_INT_HAPPEN;
++ cfg->fsm = CAMIF_NORMAL_INT;
++ ret = INSTANT_GO;
++ break;
++
++ case CAMIF_Xth_INT:
++ DPRINTK(KERN_INFO "CAMIF_Xth_INT\n");
++ s3c_camif_enable_lastirq(cfg);
++ cfg->status = CAMIF_INT_HAPPEN;
++ cfg->fsm = CAMIF_Yth_INT;
++ ret = INSTANT_GO;
++ break;
++
++ case CAMIF_Yth_INT:
++ DPRINTK(KERN_INFO "CAMIF_Yth_INT\n");
++ s3c_camif_disable_lastirq(cfg);
++ cfg->capture_enable = CAMIF_DMA_OFF;
++ cfg->status = CAMIF_INT_HAPPEN;
++ s3c_camif_stop_dma(cfg);
++ cfg->fsm = CAMIF_Zth_INT;
++ ret = INSTANT_GO;
++ break;
++
++ case CAMIF_Zth_INT:
++ DPRINTK(KERN_INFO "CAMIF_Zth_INT\n");
++ cfg->fsm = CAMIF_DUMMY_INT;
++ cfg->status = CAMIF_INT_HAPPEN;
++ ret = INSTANT_GO;
++ s3c_camif_auto_restart(cfg);
++ break;
++
++ case CAMIF_DUMMY_INT:
++ DPRINTK(KERN_INFO "CAMIF_DUMMY_INT\n");
++ cfg->status = CAMIF_STOPPED;
++ ret = INSTANT_SKIP;
++ break;
++
++ default:
++ printk(KERN_INFO "Unexpected INT %d\n", cfg->fsm);
++ ret = INSTANT_SKIP;
++ break;
++ }
++
++ return ret;
++}
++#endif
++
++static irqreturn_t s3c_camif_do_irq_codec(int irq, void *dev_id)
++{
++ camif_cfg_t *cfg = (camif_cfg_t *) dev_id;
++
++/* @@@ SMKD ? - WA */
++#if 0 && (defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410))
++ s3c_gpio_setpin(S3C_GPN15, 1);
++#endif
++ s3c_camif_clear_irq(irq);
++ s3c_camif_get_fifo_status(cfg);
++ s3c_camif_get_frame_num(cfg);
++
++#if defined(FSM_ON_CODEC) && !defined(USE_LAST_IRQ)
++ if (s3c_camif_do_fsm_codec(cfg) == INSTANT_SKIP)
++ return IRQ_HANDLED;
++#endif
++
++#if defined(FSM_ON_CODEC) && defined(USE_LAST_IRQ)
++ if (s3c_camif_do_fsm_codec_lastirq(cfg) == INSTANT_SKIP)
++ return IRQ_HANDLED;
++#endif
++ wake_up_interruptible(&cfg->waitq);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t s3c_camif_do_irq_preview(int irq, void *dev_id)
++{
++ camif_cfg_t *cfg = (camif_cfg_t *) dev_id;
++
++ s3c_camif_clear_irq(irq);
++ s3c_camif_get_fifo_status(cfg);
++ s3c_camif_get_frame_num(cfg);
++ wake_up_interruptible(&cfg->waitq);
++
++#if defined(FSM_ON_PREVIEW)
++ if (s3c_camif_do_lastirq_preview(cfg) == INSTANT_SKIP)
++ return IRQ_HANDLED;
++
++ wake_up_interruptible(&cfg->waitq);
++#endif
++ cfg->status = CAMIF_INT_HAPPEN;
++
++ return IRQ_HANDLED;
++}
++
++static void s3c_camif_release_irq(camif_cfg_t * cfg)
++{
++ disable_irq(cfg->irq);
++ free_irq(cfg->irq, cfg);
++}
++
++static int s3c_camif_request_irq(camif_cfg_t * cfg)
++{
++ int ret = 0;
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++ if ((ret = request_irq(cfg->irq, s3c_camif_do_irq_codec, IRQF_SHARED, cfg->shortname, cfg)))
++ printk(KERN_ERR "Request irq (CAM_C) failed\n");
++ else
++ printk(KERN_INFO "Request irq %d for codec\n", cfg->irq);
++ }
++
++ if (cfg->dma_type & CAMIF_PREVIEW) {
++ if ((ret = request_irq(cfg->irq, s3c_camif_do_irq_preview, IRQF_SHARED, cfg->shortname, cfg)))
++ printk("Request_irq (CAM_P) failed\n");
++ else
++ printk(KERN_INFO "Request irq %d for preview\n", cfg->irq);
++ }
++
++ return 0;
++}
++
++/*************************************************************************
++ * Standard file operations part
++ ************************************************************************/
++long s3c_camif_ioctl(struct file *file, unsigned int cmd, unsigned long _arg)
++{
++ camif_cfg_t *cfg = file->private_data;
++ int ret = -1;
++ void *arg = (void *) _arg; /* @@@ - WA */
++
++ switch (cmd) {
++ case VIDIOC_QUERYCAP:
++ ret = s3c_camif_v4l2_querycap(cfg, arg);
++ break;
++
++ case VIDIOC_G_FBUF:
++ ret = s3c_camif_v4l2_g_fbuf(cfg, arg);
++ break;
++
++ case VIDIOC_S_FBUF:
++ ret = s3c_camif_v4l2_s_fbuf(cfg, arg);
++ break;
++
++ case VIDIOC_G_FMT:
++ ret = s3c_camif_v4l2_g_fmt(cfg, arg);
++ break;
++
++ case VIDIOC_S_FMT:
++ ret = s3c_camif_v4l2_s_fmt(cfg, arg);
++ break;
++
++ case VIDIOC_ENUM_FMT:
++ ret = s3c_camif_v4l2_enum_fmt(cfg, arg);
++ break;
++
++ case VIDIOC_OVERLAY:
++ ret = s3c_camif_v4l2_overlay(cfg, arg);
++ break;
++
++ case VIDIOC_S_CTRL:
++ ret = s3c_camif_v4l2_s_ctrl(cfg, arg);
++ break;
++
++ case VIDIOC_G_CTRL:
++ ret = s3c_camif_v4l2_g_ctrl(cfg, arg);
++ break;
++
++ case VIDIOC_STREAMON:
++ ret = s3c_camif_v4l2_streamon(cfg, arg);
++ break;
++
++ case VIDIOC_STREAMOFF:
++ ret = s3c_camif_v4l2_streamoff(cfg, arg);
++ break;
++
++ case VIDIOC_G_INPUT:
++ ret = s3c_camif_v4l2_g_input(cfg, arg);
++ break;
++
++ case VIDIOC_S_INPUT:
++ ret = s3c_camif_v4l2_s_input(cfg, *((int *) arg));
++ break;
++
++ case VIDIOC_G_OUTPUT:
++ ret = s3c_camif_v4l2_g_output(cfg, arg);
++ break;
++
++ case VIDIOC_S_OUTPUT:
++ ret = s3c_camif_v4l2_s_output(cfg, *((int *) arg));
++ break;
++
++ case VIDIOC_ENUMINPUT:
++ ret = s3c_camif_v4l2_enum_input(cfg, arg);
++ break;
++
++ case VIDIOC_ENUMOUTPUT:
++ ret = s3c_camif_v4l2_enum_output(cfg, arg);
++ break;
++
++ case VIDIOC_REQBUFS:
++ ret = s3c_camif_v4l2_reqbufs(cfg, arg);
++ break;
++
++ case VIDIOC_QUERYBUF:
++ ret = s3c_camif_v4l2_querybuf(cfg, arg);
++ break;
++
++ case VIDIOC_QBUF:
++ ret = s3c_camif_v4l2_qbuf(cfg, arg);
++ break;
++
++ case VIDIOC_DQBUF:
++ ret = s3c_camif_v4l2_dqbuf(cfg, arg);
++ break;
++
++ case VIDIOC_S_MSDMA:
++ ret = s3c_camif_v4l2_s_msdma(cfg, arg);
++ break;
++
++ case VIDIOC_MSDMA_START:
++ ret = s3c_camif_v4l2_msdma_start(cfg, arg);
++ break;
++
++ case VIDIOC_MSDMA_STOP:
++ ret = s3c_camif_v4l2_msdma_stop(cfg, arg);
++ break;
++
++ case VIDIOC_S_CAMERA_START:
++ ret = s3c_camif_v4l2_camera_start(cfg, arg);
++ break;
++
++ case VIDIOC_S_CAMERA_STOP:
++ ret = s3c_camif_v4l2_camera_stop(cfg, arg);
++ break;
++
++ case VIDIOC_CROPCAP:
++ ret = s3c_camif_v4l2_cropcap(cfg, arg);
++ break;
++
++ case VIDIOC_G_CROP:
++ ret = s3c_camif_v4l2_g_crop(cfg, arg);
++ break;
++
++ case VIDIOC_S_CROP:
++ ret = s3c_camif_v4l2_s_crop(cfg, arg);
++ break;
++
++ case VIDIOC_S_PARM:
++ ret = s3c_camif_v4l2_s_parm(cfg, arg);
++ break;
++
++ default: /* For v4l compatability */
++ ret = v4l_compat_translate_ioctl(file, cmd, arg, s3c_camif_ioctl);
++ break;
++ } /* End of Switch */
++
++ return ret;
++}
++
++/* @@@ - WA */
++#define s3c_camif_exclusive_open(inode, file) 0
++#define s3c_camif_exclusive_release(inode, file)
++
++int s3c_camif_open(struct file *file)
++{
++ int err;
++ camif_cfg_t *cfg = s3c_camif_get_fimc_object(MINOR(file->f_dentry->d_inode->i_rdev));
++
++ if (!cfg->cis) {
++ printk(KERN_ERR "An object for a CIS is missing\n");
++ printk(KERN_ERR "Using msdma_input as a default CIS data structure\n");
++ cfg->cis = &msdma_input;
++
++ /* global lock for both Codec and Preview */
++ sema_init((struct semaphore *) &cfg->cis->lock, 1);
++ cfg->cis->status |= P_NOT_WORKING;
++ }
++
++ if (cfg->dma_type & CAMIF_PREVIEW) {
++ if (cfg->dma_type & CAMIF_PREVIEW)
++ cfg->cis->status &= ~P_NOT_WORKING;
++
++ up((struct semaphore *) &cfg->cis->lock);
++ }
++
++ err = s3c_camif_exclusive_open(inode, file);
++ cfg->cis->user++;
++ cfg->status = CAMIF_STOPPED;
++
++ if (err < 0)
++ return err;
++
++ if (file->f_flags & O_NONCAP) {
++ printk(KERN_ERR "Don't support non-capturing open\n");
++ return 0;
++ }
++
++ file->private_data = cfg;
++
++ s3c_camif_init_sensor(cfg);
++
++ return 0;
++}
++
++int s3c_camif_release(struct file *file)
++{
++ camif_cfg_t *cfg = s3c_camif_get_fimc_object(MINOR(file->f_dentry->d_inode->i_rdev));
++
++ if (cfg->dma_type & CAMIF_PREVIEW) {
++ cfg->cis->status &= ~PWANT2START;
++ cfg->cis->status |= P_NOT_WORKING;
++ s3c_camif_stop_preview(cfg);
++ up((struct semaphore *) &cfg->cis->lock);
++ } else {
++ cfg->cis->status &= ~CWANT2START;
++ s3c_camif_stop_capture(cfg);
++ }
++
++ s3c_camif_exclusive_release(inode, file);
++
++ if (cfg->cis->sensor == NULL)
++ DPRINTK("A CIS sensor for MSDMA has been used\n");
++ else
++ cfg->cis->sensor->driver->command(cfg->cis->sensor, USER_EXIT, NULL);
++
++ cfg->cis->user--;
++ cfg->status = CAMIF_STOPPED;
++
++ return 0;
++}
++
++ssize_t s3c_camif_read(struct file * file, char *buf, size_t count, loff_t * pos)
++{
++ camif_cfg_t *cfg = NULL;
++ size_t end;
++
++ cfg = s3c_camif_get_fimc_object(MINOR(file->f_dentry->d_inode->i_rdev));
++
++#if defined(FSM_ON_PREVIEW)
++ if (cfg->dma_type == CAMIF_PREVIEW) {
++ if (wait_event_interruptible(cfg->waitq, cfg->status == CAMIF_INT_HAPPEN))
++ return -ERESTARTSYS;
++
++ cfg->status = CAMIF_STOPPED;
++ }
++#endif
++
++#if defined(FSM_ON_CODEC)
++ if (cfg->dma_type == CAMIF_CODEC) {
++ if (wait_event_interruptible(cfg->waitq, cfg->status == CAMIF_INT_HAPPEN))
++ return -ERESTARTSYS;
++
++ cfg->status = CAMIF_STOPPED;
++ }
++#endif
++ end = min_t(size_t, cfg->pp_totalsize / cfg->pp_num, count);
++
++ if (copy_to_user(buf, s3c_camif_get_frame(cfg), end))
++ return -EFAULT;
++
++ return end;
++}
++
++ssize_t s3c_camif_write(struct file * f, const char *b, size_t c, loff_t * offset)
++{
++ camif_cfg_t *cfg;
++ int ret = 0;
++
++ cfg = s3c_camif_get_fimc_object(MINOR(f->f_dentry->d_inode->i_rdev));
++
++ switch (*b) {
++ case 'O':
++ if (cfg->dma_type & CAMIF_PREVIEW)
++ s3c_camif_start_preview(cfg);
++ else {
++ ret = s3c_camif_start_capture(cfg);
++
++ if (ret < 0)
++ ret = 1;
++ }
++
++ break;
++
++ case 'X':
++ if (cfg->dma_type & CAMIF_PREVIEW) {
++ s3c_camif_stop_preview(cfg);
++ cfg->cis->status |= P_NOT_WORKING;
++ } else {
++ cfg->cis->status &= ~C_WORKING;
++ s3c_camif_stop_capture(cfg);
++ }
++
++ break;
++
++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
++ case 'P':
++ if (cfg->dma_type & CAMIF_PREVIEW) {
++ s3c_camif_start_preview(cfg);
++ s3c_camif_do_postprocess(cfg);
++ return 0;
++ } else
++ return -EFAULT;
++#endif
++ default:
++ panic("s3c_camera_driver.c: s3c_camif_write() - Unexpected Parameter\n");
++ }
++
++ return ret;
++}
++
++int s3c_camif_mmap(struct file* filp, struct vm_area_struct *vma)
++{
++ camif_cfg_t *cfg = filp->private_data;
++
++ unsigned long pageFrameNo;
++ unsigned long size = vma->vm_end - vma->vm_start;
++ unsigned long total_size;
++
++ if (cfg->dma_type == CAMIF_PREVIEW)
++ total_size = RGB_MEM;
++ else
++ total_size = YUV_MEM;
++
++ /* page frame number of the address for a source RGB frame to be stored at. */
++ pageFrameNo = __phys_to_pfn(cfg->pp_phys_buf);
++
++ if (size > total_size) {
++ printk(KERN_ERR "The size of RGB_MEM mapping is too big\n");
++ return -EINVAL;
++ }
++
++ if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) {
++ printk(KERN_ERR "Writable RGB_MEM mapping must be shared\n");
++ return -EINVAL;
++ }
++
++ if (remap_pfn_range(vma, vma->vm_start, pageFrameNo + vma->vm_pgoff, size, vma->vm_page_prot))
++ return -EINVAL;
++
++ return 0;
++}
++
++static unsigned int s3c_camif_poll(struct file *file, poll_table *wait)
++{
++ unsigned int mask = 0;
++ camif_cfg_t *cfg = file->private_data;
++
++ poll_wait(file, &cfg->waitq, wait);
++
++ if (cfg->status == CAMIF_INT_HAPPEN)
++ mask = POLLIN | POLLRDNORM;
++
++ cfg->status = CAMIF_STOPPED;
++
++ return mask;
++}
++
++struct v4l2_file_operations camif_c_fops = {
++ .owner = THIS_MODULE,
++ .open = s3c_camif_open,
++ .release = s3c_camif_release,
++ .ioctl = s3c_camif_ioctl,
++ .read = s3c_camif_read,
++ .write = s3c_camif_write,
++ .mmap = s3c_camif_mmap,
++ .poll = s3c_camif_poll,
++};
++
++struct v4l2_file_operations camif_p_fops = {
++ .owner = THIS_MODULE,
++ .open = s3c_camif_open,
++ .release = s3c_camif_release,
++ .ioctl = s3c_camif_ioctl,
++ .read = s3c_camif_read,
++ .write = s3c_camif_write,
++ .mmap = s3c_camif_mmap,
++ .poll = s3c_camif_poll,
++};
++
++/*************************************************************************
++ * Templates for V4L2
++ ************************************************************************/
++void camif_vdev_release (struct video_device *vdev) {
++ kfree(vdev);
++}
++
++struct video_device codec_template = {
++ .name = CODEC_DEV_NAME,
++#if 0
++ .type = VID_TYPE_OVERLAY | VID_TYPE_CAPTURE | VID_TYPE_CLIPPING | VID_TYPE_SCALES,
++ .type2 = V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING,
++ .hardware = VID_HARDWARE_SAMSUNG_FIMC3X,
++#endif
++ .fops = &camif_c_fops,
++ .release = camif_vdev_release,
++ .minor = CODEC_MINOR,
++};
++
++struct video_device preview_template = {
++ .name = PREVIEW_DEV_NAME,
++#if 0
++ .type = VID_TYPE_OVERLAY | VID_TYPE_CAPTURE | VID_TYPE_CLIPPING | VID_TYPE_SCALES,
++ .type2 = V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING,
++ .hardware = VID_HARDWARE_SAMSUNG_FIMC3X,
++#endif
++ .fops = &camif_p_fops,
++ .release = camif_vdev_release,
++ .minor = PREVIEW_MINOR,
++};
++
++/*************************************************************************
++ * Initialize part
++ ************************************************************************/
++void s3c_camif_init_sensor(camif_cfg_t *cfg)
++{
++ camif_cis_t *cis = cfg->cis;
++ camif_cis_t *initialized_cis;
++
++ if (!cis->sensor) {
++ initialized_cis = (camif_cis_t *) get_initialized_cis();
++
++ if (initialized_cis == NULL) {
++ printk(KERN_ERR "An I2C client for CIS sensor isn't registered\n");
++ return;
++ }
++
++ cis = cfg->cis = initialized_cis;
++ cfg->input_channel = 0;
++ cfg->cis->user++;
++ }
++
++ if (!cis->init_sensor) {
++ cis->sensor->driver->command(cis->sensor, SENSOR_INIT, NULL);
++ cis->init_sensor = 1;
++
++#if defined(CONFIG_VIDEO_SAMSUNG_S5K3BA)
++ cis->sensor->driver->command(cis->sensor, SENSOR_VGA, NULL);
++ cis->source_x = 640;
++ cis->source_y = 480;
++#elif defined(CONFIG_VIDEO_SAMSUNG_S5K4BA)
++ cis->sensor->driver->command(cis->sensor, SENSOR_SVGA, NULL);
++ cis->source_x = 800;
++ cis->source_y = 600;
++#endif
++ }
++
++ cis->sensor->driver->command(cis->sensor, USER_ADD, NULL);
++}
++
++static int s3c_camif_init_preview(camif_cfg_t * cfg)
++{
++ cfg->target_x = PREVIEW_DEFAULT_WIDTH;
++ cfg->target_y = PREVIEW_DEFAULT_WIDTH;
++ cfg->pp_num = PREVIEW_DEFAULT_PPNUM;
++ cfg->dma_type = CAMIF_PREVIEW;
++ cfg->input_channel = CAMERA_INPUT;
++ cfg->src_fmt = CAMIF_YCBCR422;
++ cfg->output_channel = CAMIF_OUT_PP;
++ cfg->dst_fmt = CAMIF_RGB16;
++ cfg->flip = CAMIF_FLIP_Y;
++ cfg->v = &preview_template;
++
++ /* @@@ - WA */
++ //init_MUTEX((struct semaphore *) &cfg->v->lock);
++ init_waitqueue_head(&cfg->waitq);
++
++ cfg->status = CAMIF_STOPPED;
++
++ /* To get the handle of CODEC */
++ cfg->other = s3c_camif_get_fimc_object(CODEC_MINOR);
++
++ return cfg->status;
++}
++
++static int s3c_camif_init_codec(camif_cfg_t * cfg)
++{
++ cfg->target_x = CODEC_DEFAULT_WIDTH;
++ cfg->target_y = CODEC_DEFAULT_HEIGHT;
++ cfg->pp_num = CODEC_DEFAULT_PPNUM;
++ cfg->dma_type = CAMIF_CODEC;
++ cfg->src_fmt = CAMIF_YCBCR422;
++ cfg->input_channel = CAMERA_INPUT;
++ cfg->dst_fmt = CAMIF_YCBCR420;
++ cfg->output_channel = CAMIF_OUT_PP;
++ cfg->flip = CAMIF_FLIP_X;
++ cfg->v = &codec_template;
++
++ /* @@@ - WA */
++ //init_MUTEX((struct semaphore *) &cfg->v->lock);
++
++ init_waitqueue_head(&cfg->waitq);
++
++ cfg->status = CAMIF_STOPPED;
++
++ /* To get the handle of PREVIEW */
++ cfg->other = s3c_camif_get_fimc_object(PREVIEW_MINOR);
++
++ return cfg->status;
++}
++
++static int s3c_camif_probe(struct platform_device *pdev)
++{
++ struct resource *res;
++ camif_cfg_t *codec, *preview;
++ int ret = 0;
++
++ /* Initialize fimc objects */
++ codec = s3c_camif_get_fimc_object(CODEC_MINOR);
++ preview = s3c_camif_get_fimc_object(PREVIEW_MINOR);
++
++ memset(codec, 0, sizeof(camif_cfg_t));
++ memset(preview, 0, sizeof(camif_cfg_t));
++
++ /* Set the fimc name */
++ strcpy(codec->shortname, CODEC_DEV_NAME);
++ strcpy(preview->shortname, PREVIEW_DEV_NAME);
++
++ /* get resource for io memory */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++ if (!res) {
++ printk("Failed to get io memory region resouce.\n");
++ return -1;
++ }
++
++ /* request mem region */
++ res = request_mem_region(res->start, res->end - res->start + 1, pdev->name);
++
++ if (!res) {
++ printk("Failed to request io memory region.\n");
++ return -1;
++ }
++
++ /* ioremap for register block */
++ codec->regs = preview->regs = ioremap(res->start, res->end - res->start + 1);
++
++ if (codec->regs == NULL) {
++ printk(KERN_ERR "Failed to remap register block\n");
++ return -1;
++ }
++
++ /* ioremap for reserved memory */
++ codec->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVED_MEM);
++ codec->pp_virt_buf = ioremap_nocache(codec->pp_phys_buf, YUV_MEM);
++
++ preview->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVED_MEM) + YUV_MEM;
++ preview->pp_virt_buf = ioremap_nocache(preview->pp_phys_buf, RGB_MEM);
++
++ /* Device init */
++ s3c_camif_init();
++ s3c_camif_init_codec(codec);
++ s3c_camif_init_preview(preview);
++
++ /* Set irq */
++ codec->irq = platform_get_irq(pdev, FIMC_CODEC_INDEX);
++ preview->irq = platform_get_irq(pdev, FIMC_PREVIEW_INDEX);
++
++ s3c_camif_request_irq(codec);
++ s3c_camif_request_irq(preview);
++
++ /* Register to video device */
++ if (video_register_device(codec->v, VFL_TYPE_GRABBER, CODEC_MINOR) != 0) {
++ printk(KERN_ERR "Couldn't register this codec driver\n");
++ return -1;
++ }
++
++ if (video_register_device(preview->v, VFL_TYPE_GRABBER, PREVIEW_MINOR) != 0) {
++ printk(KERN_ERR "Couldn't register this preview driver\n");
++ return -1;
++ }
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++ cam_clock = clk_get(&pdev->dev, "camera");
++#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2450)
++ cam_clock = clk_get(&pdev->dev, "camif-upll");
++#else
++#error cam_clock should be defined
++#endif
++
++ if (IS_ERR(cam_clock)) {
++ printk("Failed to find camera clock source\n");
++ ret = PTR_ERR(cam_clock);
++ }
++
++ clk_enable(cam_clock);
++
++ /* Print banner */
++ printk(KERN_INFO "S3C FIMC v%s\n", FIMC_VER);
++
++ return 0;
++}
++
++static int s3c_camif_remove(struct platform_device *pdev)
++{
++ camif_cfg_t *codec, *preview;
++
++ codec = s3c_camif_get_fimc_object(CODEC_MINOR);
++ preview = s3c_camif_get_fimc_object(PREVIEW_MINOR);
++
++ s3c_camif_release_irq(codec);
++ s3c_camif_release_irq(preview);
++
++ iounmap(codec->pp_virt_buf);
++ codec->pp_virt_buf = 0;
++
++ iounmap(preview->pp_virt_buf);
++ preview->pp_virt_buf = 0;
++
++ video_unregister_device(codec->v);
++ video_unregister_device(preview->v);
++
++ s3c_camif_set_priority(0);
++ clk_disable(cam_clock);
++
++ memset(codec, 0, sizeof(camif_cfg_t));
++ memset(preview, 0, sizeof(camif_cfg_t));
++
++ return 0;
++}
++
++static struct platform_driver s3c_camif_driver =
++{
++ .probe = s3c_camif_probe,
++ .remove = s3c_camif_remove,
++ .driver = {
++ .name = "s3c-camif",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int s3c_camif_register(void)
++{
++ platform_driver_register(&s3c_camif_driver);
++
++ return 0;
++}
++
++static void s3c_camif_unregister(void)
++{
++ platform_driver_unregister(&s3c_camif_driver);
++}
++
++void s3c_camif_open_sensor(camif_cis_t *cis)
++{
++ clk_set_rate(cam_clock, cis->camclk);
++ s3c_camif_reset(cis->reset_type, cis->reset_udelay);
++}
++
++void s3c_camif_register_sensor(struct i2c_client *ptr)
++{
++ camif_cfg_t *codec, *preview;
++ camif_cis_t *cis = i2c_get_clientdata(ptr);
++
++ codec = s3c_camif_get_fimc_object(CODEC_MINOR);
++ preview = s3c_camif_get_fimc_object(PREVIEW_MINOR);
++
++ codec->cis = preview->cis = cis;
++
++ sema_init((struct semaphore *) &codec->cis->lock, 1);
++ sema_init((struct semaphore *) &preview->cis->lock, 1);
++
++ preview->cis->status |= P_NOT_WORKING; /* Default Value */
++
++ s3c_camif_set_polarity(preview);
++ s3c_camif_set_source_format(cis);
++ s3c_camif_set_priority(1);
++}
++
++void s3c_camif_unregister_sensor(struct i2c_client *ptr)
++{
++ camif_cis_t *cis;
++
++ cis = i2c_get_clientdata(ptr);
++ cis->init_sensor = 0;
++}
++
++module_init(s3c_camif_register);
++module_exit(s3c_camif_unregister);
++
++EXPORT_SYMBOL(s3c_camif_register_sensor);
++EXPORT_SYMBOL(s3c_camif_unregister_sensor);
++
++MODULE_AUTHOR("Jinsung Yang <jsgood.yang at samsung.com>");
++MODULE_DESCRIPTION("S3C Camera Driver for FIMC Interface");
++MODULE_LICENSE("GPL");
++
+Index: cam/drivers/media/video/s3c_camif.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ cam/drivers/media/video/s3c_camif.c 2009-02-26 22:28:44.000000000 +0800
+@@ -0,0 +1,1872 @@
++/* drivers/media/video/s3c_camif.c
++ *
++ * Copyright (c) 2008 Samsung Electronics
++ *
++ * Samsung S3C Camera driver
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/completion.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/wait.h>
++#include <linux/videodev.h>
++#include <asm/io.h>
++#include <linux/semaphore.h>
++#include <mach/hardware.h>
++#include <asm/uaccess.h>
++#include <mach/map.h>
++#include <mach/gpio.h>
++#include <mach/irqs.h>
++#include <plat/gpio-cfg.h>
++#include <plat/regs-camif.h>
++#include <plat/regs-gpio.h>
++#include <plat/gpio-bank-f.h>
++#include <plat/regs-lcd.h>
++
++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
++#include <asm/arch/regs-irq.h>
++#endif
++
++#include "s3c_camif.h"
++
++static unsigned int irq_old_priority;
++
++/*************************************************************************
++ * Utility part
++ ************************************************************************/
++int s3c_camif_get_frame_num(camif_cfg_t *cfg)
++{
++ int index = 0;
++
++ if (cfg->dma_type & CAMIF_CODEC)
++ index = (readl(cfg->regs + S3C_CICOSTATUS) >> 26) & 0x3;
++ else {
++ assert(cfg->dma_type & CAMIF_PREVIEW);
++ index = (readl(cfg->regs + S3C_CIPRSTATUS) >> 26) & 0x3;
++ }
++
++ cfg->cur_frame_num = (index + 2) % 4; /* When 4 PingPong */
++
++ return 0;
++}
++
++unsigned char* s3c_camif_get_frame(camif_cfg_t *cfg)
++{
++ unsigned char *ret = NULL;
++ int cnt = cfg->cur_frame_num;
++
++ if (cfg->dma_type & CAMIF_PREVIEW)
++ ret = cfg->img_buf[cnt].virt_rgb;
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++ if ((cfg->dst_fmt & CAMIF_RGB16) || (cfg->dst_fmt & CAMIF_RGB24))
++ ret = cfg->img_buf[cnt].virt_rgb;
++ else
++ ret = cfg->img_buf[cnt].virt_y;
++ }
++
++ return ret;
++}
++
++int s3c_camif_get_fifo_status(camif_cfg_t *cfg)
++{
++ unsigned int reg, val, flag;
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++ flag = S3C_CICOSTATUS_OVFIY_CO | S3C_CICOSTATUS_OVFICB_CO | S3C_CICOSTATUS_OVFICR_CO;
++ reg = readl(cfg->regs + S3C_CICOSTATUS);
++
++ if (reg & flag) {
++ /* FIFO Error Count ++ */
++ val = readl(cfg->regs + S3C_CIWDOFST);
++ val |= (S3C_CIWDOFST_CLROVCOFIY | S3C_CIWDOFST_CLROVCOFICB | S3C_CIWDOFST_CLROVCOFICR);
++ writel(val, cfg->regs + S3C_CIWDOFST);
++
++ val = readl(cfg->regs + S3C_CIWDOFST);
++ val &= ~(S3C_CIWDOFST_CLROVCOFIY | S3C_CIWDOFST_CLROVCOFICB | S3C_CIWDOFST_CLROVCOFICR);
++ writel(val, cfg->regs + S3C_CIWDOFST);
++
++ return 1; /* Error */
++ }
++ } else if (cfg->dma_type & CAMIF_PREVIEW) {
++ flag = S3C_CIPRSTATUS_OVFICB_PR | S3C_CIPRSTATUS_OVFICR_PR;
++ reg = readl(cfg->regs + S3C_CIPRSTATUS);
++
++ if (reg & flag) {
++ /* FIFO Error Count ++ */
++ val = readl(cfg->regs + S3C_CIWDOFST);
++ val |= (S3C_CIWDOFST_CLROVPRFICB | S3C_CIWDOFST_CLROVPRFICR);
++ writel(val, cfg->regs + S3C_CIWDOFST);
++
++ val = readl(cfg->regs + S3C_CIWDOFST);
++ val &= ~(S3C_CIWDOFST_CLROVPRFIY | S3C_CIWDOFST_CLROVPRFICB | S3C_CIWDOFST_CLROVPRFICR);
++ writel(val, cfg->regs + S3C_CIWDOFST);
++
++ return 1; /* Error */
++ }
++ }
++
++ return 0;
++}
++
++void s3c_camif_set_polarity(camif_cfg_t *cfg)
++{
++ camif_cis_t *cis = cfg->cis;
++ unsigned int val;
++ unsigned int cmd;
++
++ cmd = readl(cfg->regs + S3C_CIGCTRL);
++ cmd &= ~(0x7 << 24);
++
++ if (cis->polarity_pclk)
++ cmd |= S3C_CIGCTRL_INVPOLPCLK;
++
++ if (cis->polarity_vsync)
++ cmd |= S3C_CIGCTRL_INVPOLVSYNC;
++
++ if (cis->polarity_href)
++ cmd |= S3C_CIGCTRL_INVPOLHREF;
++
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val |= cmd;
++ writel(val, cfg->regs + S3C_CIGCTRL);
++}
++
++/*************************************************************************
++ * Memory part
++ ************************************************************************/
++static int s3c_camif_request_memory(camif_cfg_t *cfg)
++{
++ unsigned int t_size = 0, i = 0;
++ unsigned int area = 0;
++
++ area = cfg->target_x * cfg->target_y;
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++ if (cfg->dst_fmt & CAMIF_YCBCR420)
++ t_size = (area * 3 / 2); /* CAMIF_YCBCR420 */
++ else if (cfg->dst_fmt & CAMIF_YCBCR422 || cfg->dst_fmt & CAMIF_YCBCR422I)
++ t_size = (area * 2); /* CAMIF_YCBCR422 */
++ else if (cfg->dst_fmt & CAMIF_RGB16)
++ t_size = (area * 2); /* 2 bytes per one pixel */
++ else if (cfg->dst_fmt & CAMIF_RGB24)
++ t_size = (area * 4); /* 4 bytes per one pixel */
++ else
++ printk(KERN_INFO "Invalid target format\n");
++
++ if ((t_size % PAGE_SIZE) != 0) {
++ i = t_size / PAGE_SIZE;
++ t_size = (i + 1) * PAGE_SIZE;
++ }
++
++ t_size = t_size * cfg->pp_num;
++ cfg->pp_totalsize = t_size;
++
++ printk(KERN_INFO "Codec memory required: 0x%08X bytes\n", t_size);
++
++ return 0;
++ }else if (cfg->dma_type & CAMIF_PREVIEW) {
++
++ if (cfg->dst_fmt & CAMIF_RGB16)
++ t_size = (area * 2); /* 2 bytes per two pixel*/
++ else if (cfg->dst_fmt & CAMIF_RGB24)
++ t_size = (area * 4); /* 4 bytes per one pixel */
++ else
++ printk(KERN_ERR "Invalid target format\n");
++
++ if ((t_size % PAGE_SIZE) != 0) {
++ i = t_size / PAGE_SIZE;
++ t_size = (i + 1) * PAGE_SIZE;
++ }
++
++ t_size = t_size * cfg->pp_num;
++ cfg->pp_totalsize = t_size;
++
++ printk(KERN_INFO "Preview memory required: 0x%08X bytes\n", t_size);
++
++ return 0;
++ }
++
++ return 0;
++}
++
++static void s3c_camif_calc_burst_length_yuv422i(unsigned int hsize, unsigned int *mburst, unsigned int *rburst)
++{
++ unsigned int tmp, wanted;
++
++ tmp = (hsize / 2) & 0xf;
++
++ switch (tmp) {
++ case 0:
++ wanted = 16;
++ break;
++
++ case 4:
++ wanted = 4;
++ break;
++
++ case 8:
++ wanted = 8;
++ break;
++
++ default:
++ wanted = 4;
++ break;
++ }
++
++ *mburst = wanted / 2;
++ *rburst = wanted / 2;
++}
++
++static void s3c_camif_calc_burst_length(unsigned int hsize, unsigned int *mburst, unsigned int *rburst)
++{
++ unsigned int tmp;
++
++ tmp = (hsize / 4) & 0xf;
++
++ switch (tmp) {
++ case 0:
++ *mburst = 16;
++ *rburst = 16;
++ break;
++
++ case 4:
++ *mburst = 16;
++ *rburst = 4;
++ break;
++
++ case 8:
++ *mburst = 16;
++ *rburst = 8;
++ break;
++
++ default:
++ tmp = (hsize / 4) % 8;
++
++ if (tmp == 0) {
++ *mburst = 8;
++ *rburst = 8;
++ } else if (tmp == 4) {
++ *mburst = 8;
++ *rburst = 4;
++ } else {
++ tmp = (hsize / 4) % 4;
++ *mburst = 4;
++ *rburst = (tmp) ? tmp : 4;
++ }
++
++ break;
++ }
++}
++
++int s3c_camif_setup_dma(camif_cfg_t *cfg)
++{
++ int width = cfg->target_x;
++ unsigned int val, yburst_m, yburst_r, cburst_m, cburst_r;
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++ if ((cfg->dst_fmt == CAMIF_RGB16) || (cfg->dst_fmt == CAMIF_RGB24)) {
++ if (cfg->dst_fmt == CAMIF_RGB24) {
++ if (width % 2 != 0)
++ return BURST_ERR;
++
++ s3c_camif_calc_burst_length(width * 4, &yburst_m, &yburst_r);
++ } else {
++ if ((width / 2) % 2 != 0)
++ return BURST_ERR;
++
++ s3c_camif_calc_burst_length(width * 2, &yburst_m, &yburst_r);
++ }
++
++ val = readl(cfg->regs + S3C_CICOCTRL);
++ val &= ~(0xfffff << 4);
++
++ if (cfg->dst_fmt == CAMIF_RGB24) {
++ val = S3C_CICOCTRL_YBURST1_CO(yburst_m / 2) | \
++ S3C_CICOCTRL_YBURST2_CO(yburst_r / 4) | (4 << 9) | (2 << 4);
++ } else {
++ val = S3C_CICOCTRL_YBURST1_CO(yburst_m / 2) | \
++ S3C_CICOCTRL_YBURST2_CO(yburst_r / 2) | (4 << 9) | (2 << 4);
++ }
++
++ writel(val, cfg->regs + S3C_CICOCTRL);
++ } else {
++ /* CODEC DMA WIDHT is multiple of 16 */
++ if (width % 16 != 0)
++ return BURST_ERR;
++
++ if (cfg->dst_fmt == CAMIF_YCBCR422I) {
++ s3c_camif_calc_burst_length_yuv422i(width, &yburst_m, &yburst_r);
++ cburst_m = yburst_m / 2;
++ cburst_r = yburst_r / 2;
++ } else {
++ s3c_camif_calc_burst_length(width, &yburst_m, &yburst_r);
++ s3c_camif_calc_burst_length(width / 2, &cburst_m, &cburst_r);
++ }
++
++ val = readl(cfg->regs + S3C_CICOCTRL);
++ val &= ~(0xfffff << 4);
++ val |= (S3C_CICOCTRL_YBURST1_CO(yburst_m) | S3C_CICOCTRL_CBURST1_CO(cburst_m) | \
++ S3C_CICOCTRL_YBURST2_CO(yburst_r) | S3C_CICOCTRL_CBURST2_CO(cburst_r));
++ writel(val, cfg->regs + S3C_CICOCTRL);
++ }
++ } else if (cfg->dma_type & CAMIF_PREVIEW) {
++ if (cfg->dst_fmt == CAMIF_RGB24) {
++ if (width % 2 != 0)
++ return BURST_ERR;
++
++ s3c_camif_calc_burst_length(width * 4, &yburst_m, &yburst_r);
++ } else {
++ if ((width / 2) % 2 != 0)
++ return BURST_ERR;
++
++ s3c_camif_calc_burst_length(width * 2, &yburst_m, &yburst_r);
++ }
++
++ val = readl(cfg->regs + S3C_CIPRCTRL);
++ val &= ~(0x3ff << 14);
++ val |= (S3C_CICOCTRL_YBURST1_CO(yburst_m) | S3C_CICOCTRL_YBURST2_CO(yburst_r));
++ writel(val, cfg->regs + S3C_CIPRCTRL);
++ }
++
++ return 0;
++}
++
++/*************************************************************************
++ * Input path part
++ ************************************************************************/
++/*
++ * 2443 MSDMA (Preview Only)
++ */
++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
++int s3c_camif_input_msdma_preview(camif_cfg_t * cfg)
++{
++ int ret = 0;
++ unsigned int addr_start_Y = 0, addr_start_CB = 0, addr_start_CR = 0;
++ unsigned int addr_end_Y = 0, addr_end_CB = 0, addr_end_CR = 0;
++ unsigned int val, val_width;
++
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val &= ~(1 << 2);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val |= (1 << 2);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ if (cfg->src_fmt != CAMIF_YCBCR420 && cfg->src_fmt != CAMIF_YCBCR422 && cfg->src_fmt != CAMIF_YCBCR422I)
++ cfg->src_fmt = CAMIF_YCBCR420;
++
++ switch(cfg->src_fmt) {
++ case CAMIF_YCBCR420:
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val = (val & ~(0x1 << 1)) | (0x1 << 1);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ addr_start_Y = readl(cfg->regs + S3C_CIMSYSA);
++ addr_start_CB = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_start_CR = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 4);
++
++ addr_end_Y = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_end_CB = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 4);
++ addr_end_CR = addr_start_CR + (cfg->cis->source_x * cfg->cis->source_y / 4);
++ break;
++
++ case CAMIF_YCBCR422:
++ case CAMIF_YCBCR422I:
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val = (val & ~(0x1 << 5)) | (0x1 << 5); /* Interleave_MS */
++ val &= ~(0x1 << 1);
++ val &= ~(0x3 << 3); /* YCbYCr */
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ addr_start_Y = readl(cfg->regs + S3C_CIMSYSA);
++ addr_start_CB = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_start_CR = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 2);
++
++ addr_end_Y = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_end_CB = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 2);
++ addr_end_CR = addr_start_CR + (cfg->cis->source_x * cfg->cis->source_y / 2);
++ break;
++
++ default:
++ break;
++ }
++
++ /* MSDMA memory */
++ writel(addr_start_Y, cfg->regs + S3C_CIMSYSA);
++ writel(addr_start_CB, cfg->regs + S3C_CIMSCBSA);
++ writel(addr_start_CR, cfg->regs + S3C_CIMSCRSA);
++
++ writel(addr_end_Y, cfg->regs + S3C_CIMSYEND);
++ writel(addr_end_CB, cfg->regs + S3C_CIMSCBEND);
++ writel(addr_end_CR, cfg->regs + S3C_CIMSCREND);
++
++ /* MSDMA memory offset - default : 0 */
++ writel(0, cfg->regs + S3C_CIMSYOFF);
++ writel(0, cfg->regs + S3C_CIMSCBOFF);
++ writel(0, cfg->regs + S3C_CIMSCROFF);
++
++ /* MSDMA for codec source image width */
++ val_width = readl(cfg->regs + S3C_CIMSWIDTH);
++ val_width = (val_width & ~(0x1 << 31)); /* AutoLoadDisable */
++ val_width |= (cfg->cis->source_y << 16); /* MSCOHEIGHT */
++ val_width |= cfg->cis->source_x; /* MSCOWIDTH */
++ val_width = cfg->cis->source_x;
++ writel(val_width, cfg->regs + S3C_CIMSWIDTH);
++
++ return ret;
++}
++
++static int s3c_camif_input_msdma(camif_cfg_t *cfg)
++{
++ if (cfg->input_channel == MSDMA_FROM_PREVIEW)
++ s3c_camif_input_msdma_preview(cfg);
++
++ return 0;
++}
++
++/*
++ * 6400 MSDMA (Preview & Codec)
++ */
++#elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++int s3c_camif_input_msdma_codec(camif_cfg_t * cfg)
++{
++ int ret = 0;
++ u32 addr_start_Y = 0, addr_start_CB = 0, addr_start_CR = 0;
++ u32 addr_end_Y = 0, addr_end_CB = 0, addr_end_CR = 0;
++ u32 val, val_width;
++
++ /* Codec path input data selection */
++ val = readl(cfg->regs + S3C_MSCOCTRL);
++ val &= ~(1 << 3);
++ writel(val, cfg->regs + S3C_MSCOCTRL);
++
++ val = readl(cfg->regs + S3C_MSCOCTRL);
++ val |= (1 << 3);
++ writel(val, cfg->regs + S3C_MSCOCTRL);
++
++ if (cfg->src_fmt != CAMIF_YCBCR420 && cfg->src_fmt != CAMIF_YCBCR422 && cfg->src_fmt != CAMIF_YCBCR422I)
++ cfg->src_fmt = CAMIF_YCBCR420;
++
++ switch(cfg->src_fmt) {
++ case CAMIF_YCBCR420:
++ val = readl(cfg->regs + S3C_MSCOCTRL);
++ val &= ~(0x3 << 1);
++ writel(val, cfg->regs + S3C_MSCOCTRL);
++
++ addr_start_Y = cfg->pp_phys_buf;
++ addr_start_CB = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_start_CR = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 4);
++
++ addr_end_Y = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_end_CB = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 4);
++ addr_end_CR = addr_start_CR + (cfg->cis->source_x * cfg->cis->source_y / 4);
++ break;
++
++ case CAMIF_YCBCR422:
++ case CAMIF_YCBCR422I:
++ val = readl(cfg->regs + S3C_MSCOCTRL);
++ val = (val & ~(0x3 << 1)) |(0x2 << 1);
++ writel(val, cfg->regs + S3C_MSCOCTRL);
++
++ addr_start_Y = cfg->pp_phys_buf;
++ addr_start_CB = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_start_CR = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 2);
++
++ addr_end_Y = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_end_CB = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 2);
++ addr_end_CR = addr_start_CR + (cfg->cis->source_x * cfg->cis->source_y / 2);
++ break;
++
++ default:
++ break;
++ }
++
++ /* MSDMA memory */
++ writel(addr_start_Y, cfg->regs + S3C_MSCOY0SA);
++ writel(addr_start_CB, cfg->regs + S3C_MSCOCB0SA);
++ writel(addr_start_CR, cfg->regs + S3C_MSCOCR0SA);
++
++ writel(addr_end_Y, cfg->regs + S3C_MSCOY0END);
++ writel(addr_end_CB, cfg->regs + S3C_MSCOCB0END);
++ writel(addr_end_CR, cfg->regs + S3C_MSCOCR0END);
++
++ /* MSDMA memory offset */
++ writel(0, cfg->regs + S3C_MSCOYOFF);
++ writel(0, cfg->regs + S3C_MSCOCBOFF);
++ writel(0, cfg->regs + S3C_MSCOCROFF);
++
++ /* MSDMA for codec source image width */
++ val_width = readl(cfg->regs + S3C_MSCOWIDTH);
++ val_width = (val_width & ~(0x1 << 31))|(0x1 << 31); /* AutoLoadEnable */
++ val_width |= (cfg->cis->source_y << 16); /* MSCOHEIGHT */
++ val_width |= cfg->cis->source_x; /* MSCOWIDTH */
++ writel(val_width, cfg->regs + S3C_MSCOWIDTH);
++
++ return ret;
++}
++
++int s3c_camif_input_msdma_preview(camif_cfg_t * cfg)
++{
++ int ret = 0;
++ unsigned int addr_start_Y = 0, addr_start_CB = 0, addr_start_CR = 0;
++ unsigned int addr_end_Y = 0, addr_end_CB = 0, addr_end_CR = 0;
++ unsigned int val, val_width;
++
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val &= ~(0x1 << 3);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val |= (0x1 << 3);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ if (cfg->src_fmt != CAMIF_YCBCR420 && cfg->src_fmt != CAMIF_YCBCR422 && cfg->src_fmt != CAMIF_YCBCR422I)
++ cfg->src_fmt = CAMIF_YCBCR420;
++
++ switch(cfg->src_fmt) {
++ case CAMIF_YCBCR420:
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val &= ~(0x3 << 1);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ addr_start_Y = readl(cfg->regs + S3C_MSPRY0SA);
++ addr_start_CB = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_start_CR = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 4);
++
++ addr_end_Y = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_end_CB = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 4);
++ addr_end_CR = addr_start_CR + (cfg->cis->source_x * cfg->cis->source_y / 4);
++ break;
++
++ case CAMIF_YCBCR422:
++ case CAMIF_YCBCR422I:
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val = (val & ~(0x3 << 1)) | (0x2 << 1); /* YCbCr 422 Interleave */
++ val = (val & ~(0x3 << 4)) | (0x3 << 4); /* YCbYCr */
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ addr_start_Y = readl(cfg->regs + S3C_MSPRY0SA);
++ addr_start_CB = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_start_CR = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 2);
++
++ addr_end_Y = addr_start_Y + (cfg->cis->source_x * cfg->cis->source_y);
++ addr_end_CB = addr_start_CB + (cfg->cis->source_x * cfg->cis->source_y / 2);
++ addr_end_CR = addr_start_CR + (cfg->cis->source_x * cfg->cis->source_y / 2);
++ break;
++
++ default:
++ break;
++ }
++
++ /* MSDMA memory */
++ writel(addr_start_Y, cfg->regs + S3C_MSPRY0SA);
++ writel(addr_start_CB, cfg->regs + S3C_MSPRCB0SA);
++ writel(addr_start_CR, cfg->regs + S3C_MSPRCR0SA);
++
++ writel(addr_end_Y, cfg->regs + S3C_MSPRY0END);
++ writel(addr_end_CB, cfg->regs + S3C_MSPRCB0END);
++ writel(addr_end_CR, cfg->regs + S3C_MSPRCR0END);
++
++ /* MSDMA memory offset */
++ writel(0, cfg->regs + S3C_MSPRYOFF);
++ writel(0, cfg->regs + S3C_MSPRCBOFF);
++ writel(0, cfg->regs + S3C_MSPRCROFF);
++
++ /* MSDMA for codec source image width */
++ val_width = readl(cfg->regs + S3C_MSPRWIDTH);
++ val_width = (val_width & ~(0x1 << 31)); /* AutoLoadEnable */
++ val_width |= (cfg->cis->source_y << 16); /* MSCOHEIGHT */
++ val_width |= cfg->cis->source_x; /* MSCOWIDTH */
++ writel(val_width, cfg->regs + S3C_MSPRWIDTH);
++
++ return ret;
++}
++
++static int s3c_camif_input_msdma(camif_cfg_t *cfg)
++{
++ if (cfg->input_channel == MSDMA_FROM_PREVIEW)
++ s3c_camif_input_msdma_preview(cfg);
++ else if (cfg->input_channel == MSDMA_FROM_CODEC)
++ s3c_camif_input_msdma_codec(cfg);
++
++ return 0;
++}
++#endif
++
++static int s3c_camif_input_camera(camif_cfg_t *cfg)
++{
++ unsigned int val;
++
++ s3c_camif_set_offset(cfg->cis);
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++ val = readl(cfg->regs + S3C_MSCOCTRL);
++ val &= ~(1 << 3);
++ writel(val, cfg->regs + S3C_MSCOCTRL);
++#endif
++ } else if (cfg->dma_type & CAMIF_PREVIEW) {
++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450)
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val &= ~(1 << 2);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++#elif defined(CONFIG_CPU_S3C6400)
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val &= ~(1 << 3);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++#endif
++ } else
++ printk(KERN_ERR "Invalid DMA type\n");
++
++ return 0;
++}
++
++static int s3c_camif_setup_input_path(camif_cfg_t *cfg)
++{
++ if (cfg->input_channel == CAMERA_INPUT)
++ s3c_camif_input_camera(cfg);
++ else
++ s3c_camif_input_msdma(cfg);
++
++ return 0;
++}
++
++/*************************************************************************
++ * Output path part
++ ************************************************************************/
++static int s3c_camif_output_pp_codec_rgb(camif_cfg_t *cfg)
++{
++ int i;
++ unsigned int val;
++ unsigned int area = cfg->target_x * cfg->target_y;
++
++ if (cfg->dst_fmt & CAMIF_RGB24)
++ area = area * 4;
++ else {
++ assert (cfg->dst_fmt & CAMIF_RGB16);
++ area = area * 2;
++ }
++
++ if ((area % PAGE_SIZE) != 0) {
++ i = area / PAGE_SIZE;
++ area = (i + 1) * PAGE_SIZE;
++ }
++
++ cfg->buffer_size = area;
++
++ if (cfg->input_channel == MSDMA_FROM_CODEC) {
++{
++void __iomem *S3C24XX_VA_LCD = ioremap(S3C64XX_PA_FB, 1024*1024);
++ val = readl(S3C_VIDW00ADD0B0);
++}
++
++ for (i = 0; i < 4; i++)
++ writel(val, cfg->regs + S3C_CICOYSA(i));
++ } else {
++ switch ( cfg->pp_num ) {
++ case 1:
++ for (i = 0; i < 4; i++) {
++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf;
++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf;
++ writel(cfg->img_buf[i].phys_rgb, cfg->regs + S3C_CICOYSA(i));
++ }
++
++ break;
++
++ case 2:
++ for (i = 0; i < 4; i++) {
++ if (i == 0 || i == 2) {
++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf;
++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf;
++ } else {
++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + area;
++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + area;
++ }
++
++ writel(cfg->img_buf[i].phys_rgb, cfg->regs + S3C_CICOYSA(i));
++ }
++
++ break;
++
++ case 4:
++ for (i = 0; i < 4; i++) {
++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + i * area;
++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + i * area;
++ writel(cfg->img_buf[i].phys_rgb, cfg->regs + S3C_CICOYSA(i));
++ }
++
++ break;
++
++ default:
++ printk(KERN_ERR "Invalid pingpong number %d\n", cfg->pp_num);
++ panic("s3c camif halt\n");
++ }
++ }
++
++ return 0;
++}
++
++static int s3c_camif_output_pp_codec(camif_cfg_t *cfg)
++{
++ unsigned int i, cbcr_size = 0;
++ unsigned int area = cfg->target_x * cfg->target_y;
++ unsigned int one_p_size;
++
++ area = cfg->target_x * cfg->target_y;
++
++ if (cfg->dst_fmt & CAMIF_YCBCR420)
++ cbcr_size = area / 4;
++ else if (cfg->dst_fmt & CAMIF_YCBCR422 || cfg->dst_fmt & CAMIF_YCBCR422I)
++ cbcr_size = area / 2;
++ else if ((cfg->dst_fmt & CAMIF_RGB16) || (cfg->dst_fmt & CAMIF_RGB24)) {
++ s3c_camif_output_pp_codec_rgb(cfg);
++ return 0;
++ } else
++ printk(KERN_ERR "Invalid target format %d\n", cfg->dst_fmt);
++
++ one_p_size = area + (2 * cbcr_size);
++
++ if ((one_p_size % PAGE_SIZE) != 0) {
++ i = one_p_size / PAGE_SIZE;
++ one_p_size = (i + 1) * PAGE_SIZE;
++ }
++
++ cfg->buffer_size = one_p_size;
++
++ switch (cfg->pp_num) {
++ case 1 :
++ for (i = 0; i < 4; i++) {
++ cfg->img_buf[i].virt_y = cfg->pp_virt_buf;
++ cfg->img_buf[i].phys_y = cfg->pp_phys_buf;
++ cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + area;
++ cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + area;
++ cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + area + cbcr_size;
++ cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + area + cbcr_size;
++ writel(cfg->img_buf[i].phys_y, cfg->regs + S3C_CICOYSA(i));
++ writel(cfg->img_buf[i].phys_cb, cfg->regs + S3C_CICOCBSA(i));
++ writel(cfg->img_buf[i].phys_cr, cfg->regs + S3C_CICOCRSA(i));
++ }
++
++ break;
++
++ case 2:
++ for (i = 0; i < 4; i++) {
++ if (i == 0 || i == 2) {
++ cfg->img_buf[i].virt_y = cfg->pp_virt_buf;
++ cfg->img_buf[i].phys_y = cfg->pp_phys_buf;
++ cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + area;
++ cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + area;
++ cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + area + cbcr_size;
++ cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + area + cbcr_size;
++ } else {
++ cfg->img_buf[i].virt_y = cfg->pp_virt_buf + one_p_size;
++ cfg->img_buf[i].phys_y = cfg->pp_phys_buf + one_p_size;
++ cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + area + one_p_size;
++ cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + area + one_p_size;
++ cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + area + cbcr_size + one_p_size;
++ cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + area + cbcr_size + one_p_size;
++ }
++
++ writel(cfg->img_buf[i].phys_y, cfg->regs + S3C_CICOYSA(i));
++ writel(cfg->img_buf[i].phys_cb, cfg->regs + S3C_CICOCBSA(i));
++ writel(cfg->img_buf[i].phys_cr, cfg->regs + S3C_CICOCRSA(i));
++ }
++
++ break;
++
++ case 4:
++ for (i = 0; i < 4; i++) {
++ cfg->img_buf[i].virt_y = cfg->pp_virt_buf + i * one_p_size;
++ cfg->img_buf[i].phys_y = cfg->pp_phys_buf + i * one_p_size;
++ cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + area + i * one_p_size;
++ cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + area + i * one_p_size;
++ cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + area + cbcr_size + i * one_p_size;
++ cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + area + cbcr_size + i * one_p_size;
++ writel(cfg->img_buf[i].phys_y, cfg->regs + S3C_CICOYSA(i));
++ writel(cfg->img_buf[i].phys_cb, cfg->regs + S3C_CICOCBSA(i));
++ writel(cfg->img_buf[i].phys_cr, cfg->regs + S3C_CICOCRSA(i));
++ }
++
++ break;
++
++ default:
++ printk(KERN_ERR "Invalid pingpong number %d\n", cfg->pp_num);
++ }
++
++ return 0;
++}
++
++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
++static int s3c_camif_io_duplex_preview(camif_cfg_t *cfg)
++{
++ unsigned int cbcr_size = 0;
++ unsigned int area = cfg->cis->source_x * cfg->cis->source_y;
++ unsigned int val;
++ int i;
++
++ val = readl(S3C_VIDW01ADD0);
++
++ if (!((cfg->dst_fmt & CAMIF_RGB16) || (cfg->dst_fmt & CAMIF_RGB24)))
++ printk(KERN_ERR "Invalid target format\n");
++
++ for (i = 0; i < 4; i++)
++ writel(val, cfg->regs + S3C_CIPRYSA(i));
++
++ if (cfg->src_fmt & CAMIF_YCBCR420) {
++ cbcr_size = area / 4;
++ cfg->img_buf[0].virt_cb = cfg->pp_virt_buf + area;
++ cfg->img_buf[0].phys_cb = cfg->pp_phys_buf + area;
++ cfg->img_buf[0].virt_cr = cfg->pp_virt_buf + area + cbcr_size;
++ cfg->img_buf[0].phys_cr = cfg->pp_phys_buf + area + cbcr_size;
++ } else if (cfg->src_fmt & CAMIF_YCBCR422 || cfg->dst_fmt & CAMIF_YCBCR422I) {
++ area = area * 2;
++ cfg->img_buf[0].virt_cb = 0;
++ cfg->img_buf[0].phys_cb = 0;
++ cfg->img_buf[0].virt_cr = 0;
++ cfg->img_buf[0].phys_cr = 0;
++ }
++
++ cfg->img_buf[0].virt_y = cfg->pp_virt_buf;
++ cfg->img_buf[0].phys_y = cfg->pp_phys_buf;
++
++ writel(cfg->img_buf[0].phys_y, cfg->regs + S3C_CIMSYSA);
++ writel(cfg->img_buf[0].phys_y + area, cfg->regs + S3C_CIMSYEND);
++
++ writel(cfg->img_buf[0].phys_cb, cfg->regs + S3C_CIMSCBSA);
++ writel(cfg->img_buf[0].phys_cb + cbcr_size, cfg->regs + S3C_CIMSCBEND);
++
++ writel(cfg->img_buf[0].phys_cr, cfg->regs + S3C_CIMSCRSA);
++ writel(cfg->img_buf[0].phys_cr + cbcr_size, cfg->regs + S3C_CIMSCREND);
++
++ writel(cfg->cis->source_x, cfg->regs + S3C_CIMSWIDTH);
++
++ return 0;
++}
++#elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++static int s3c_camif_io_duplex_preview(camif_cfg_t *cfg)
++{
++ unsigned int cbcr_size = 0;
++ unsigned int area = cfg->cis->source_x * cfg->cis->source_y;
++ unsigned int val;
++ int i;
++
++{
++void __iomem *S3C24XX_VA_LCD = ioremap(S3C64XX_PA_FB, 1024*1024);
++ val = readl(S3C_VIDW01ADD0B0);
++}
++
++ if (!((cfg->dst_fmt & CAMIF_RGB16) || (cfg->dst_fmt & CAMIF_RGB24)))
++ printk(KERN_ERR "Invalid target format\n");
++
++ for (i = 0; i < 4; i++)
++ writel(val, cfg->regs + S3C_CIPRYSA(i));
++
++ if (cfg->src_fmt & CAMIF_YCBCR420) {
++ cbcr_size = area / 4;
++ cfg->img_buf[0].virt_cb = cfg->pp_virt_buf + area;
++ cfg->img_buf[0].phys_cb = cfg->pp_phys_buf + area;
++ cfg->img_buf[0].virt_cr = cfg->pp_virt_buf + area + cbcr_size;
++ cfg->img_buf[0].phys_cr = cfg->pp_phys_buf + area + cbcr_size;
++ } else if (cfg->src_fmt & CAMIF_YCBCR422 || cfg->dst_fmt & CAMIF_YCBCR422I){
++ area = area * 2;
++ cfg->img_buf[0].virt_cb = 0;
++ cfg->img_buf[0].phys_cb = 0;
++ cfg->img_buf[0].virt_cr = 0;
++ cfg->img_buf[0].phys_cr = 0;
++ }
++
++ cfg->img_buf[0].virt_y = cfg->pp_virt_buf;
++ cfg->img_buf[0].phys_y = cfg->pp_phys_buf;
++
++ writel(cfg->img_buf[0].phys_y, cfg->regs + S3C_MSPRY0SA);
++ writel(cfg->img_buf[0].phys_y + area, cfg->regs + S3C_MSPRY0END);
++
++ writel(cfg->img_buf[0].phys_cb, cfg->regs + S3C_MSPRCB0SA);
++ writel(cfg->img_buf[0].phys_cb + cbcr_size, cfg->regs + S3C_MSPRCB0END);
++
++ writel(cfg->img_buf[0].phys_cr, cfg->regs + S3C_MSPRCR0SA);
++ writel(cfg->img_buf[0].phys_cr + cbcr_size, cfg->regs + S3C_MSPRCR0END);
++
++ val = readl(cfg->regs + S3C_MSCOWIDTH);
++ val = (val & ~(0x1 << 31)) | (0x1 << 31);
++ val |= (cfg->cis->source_y << 16);
++ val |= cfg->cis->source_x;
++ writel(val, cfg->regs + S3C_MSPRWIDTH);
++
++ return 0;
++}
++#endif
++
++static int s3c_camif_output_pp_preview(camif_cfg_t *cfg)
++{
++ int i;
++ unsigned int cbcr_size = 0;
++ unsigned int area = cfg->target_x * cfg->target_y;
++
++ if (cfg->input_channel) {
++ s3c_camif_io_duplex_preview(cfg);
++ return 0;
++ }
++
++ if (cfg->dst_fmt & CAMIF_YCBCR420)
++ cbcr_size = area / 4;
++ else if (cfg->dst_fmt & CAMIF_YCBCR422 || cfg->dst_fmt & CAMIF_YCBCR422I)
++ cbcr_size = area / 2;
++ else if (cfg->dst_fmt & CAMIF_RGB24)
++ area = area * 4;
++ else if (cfg->dst_fmt & CAMIF_RGB16)
++ area = area * 2;
++ else
++ printk(KERN_ERR "Invalid target format %d\n", cfg->dst_fmt);
++
++ if ((area % PAGE_SIZE) != 0) {
++ i = area / PAGE_SIZE;
++ area = (i + 1) * PAGE_SIZE;
++ }
++
++ cfg->buffer_size = area;
++
++ switch (cfg->pp_num) {
++ case 1:
++ for (i = 0; i < 4; i++) {
++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf;
++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf;
++ writel(cfg->img_buf[i].phys_rgb, cfg->regs + S3C_CIPRYSA(i));
++ }
++
++ break;
++
++ case 2:
++ for (i = 0; i < 4; i++) {
++ if (i == 0 || i == 2) {
++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf;
++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf;
++ } else {
++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + area;
++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + area;
++ }
++
++ writel(cfg->img_buf[i].phys_rgb, cfg->regs + S3C_CIPRYSA(i));
++ }
++
++ break;
++
++ case 4:
++ for (i = 0; i < 4; i++) {
++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + i * area;
++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + i * area;
++ writel(cfg->img_buf[i].phys_rgb, cfg->regs + S3C_CIPRYSA(i));
++ }
++
++ break;
++
++ default:
++ printk(KERN_ERR "Invalid pingpong number %d\n", cfg->pp_num);
++ }
++
++ return 0;
++}
++
++static int s3c_camif_output_pp(camif_cfg_t *cfg)
++{
++ if (cfg->dma_type & CAMIF_CODEC)
++ s3c_camif_output_pp_codec(cfg);
++ else if ( cfg->dma_type & CAMIF_PREVIEW)
++ s3c_camif_output_pp_preview(cfg);
++
++ return 0;
++}
++
++static int s3c_camif_output_lcd(camif_cfg_t *cfg)
++{
++ /* To Be Implemented */
++ return 0;
++}
++
++static int s3c_camif_setup_output_path(camif_cfg_t *cfg)
++{
++ if (cfg->output_channel == CAMIF_OUT_FIFO)
++ s3c_camif_output_lcd(cfg);
++ else
++ s3c_camif_output_pp(cfg);
++
++ return 0;
++}
++
++/*************************************************************************
++ * Scaler part
++ ************************************************************************/
++static int s3c_camif_set_target_area(camif_cfg_t *cfg)
++{
++ unsigned int rect = cfg->target_x * cfg->target_y;
++
++ if (cfg->dma_type & CAMIF_CODEC)
++ writel(rect, cfg->regs + S3C_CICOTAREA);
++ else if (cfg->dma_type & CAMIF_PREVIEW)
++ writel(rect, cfg->regs + S3C_CIPRTAREA);
++
++ return 0;
++}
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++static inline int s3c_camif_set_ratio(camif_cfg_t *cfg)
++{
++ unsigned int cmd = (S3C_CICOSCCTRL_CSCR2Y_WIDE | S3C_CICOSCCTRL_CSCY2R_WIDE);
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++
++ writel(S3C_CICOSCPRERATIO_SHFACTOR_CO(cfg->sc.shfactor) | \
++ S3C_CICOSCPRERATIO_PREHORRATIO_CO(cfg->sc.prehratio) | \
++ S3C_CICOSCPRERATIO_PREVERRATIO_CO(cfg->sc.prevratio), cfg->regs + S3C_CICOSCPRERATIO);
++
++ writel(S3C_CICOSCPREDST_PREDSTWIDTH_CO(cfg->sc.predst_x) | \
++ S3C_CICOSCPREDST_PREDSTHEIGHT_CO(cfg->sc.predst_y), cfg->regs + S3C_CICOSCPREDST);
++
++ /* Differ from Preview */
++ if (cfg->sc.scalerbypass)
++ cmd |= S3C_CICOSCCTRL_SCALERBYPASS_CO;
++
++ /* Differ from Codec */
++ if (cfg->dst_fmt & CAMIF_RGB24)
++ cmd |= S3C_CICOSCCTRL_OUTRGB_FMT_RGB888;
++ else
++ cmd |= S3C_CICOSCCTRL_OUTRGB_FMT_RGB565;
++
++ if (cfg->sc.scaleup_h & cfg->sc.scaleup_v)
++ cmd |= (S3C_CICOSCCTRL_SCALEUP_H | S3C_CICOSCCTRL_SCALEUP_V);
++
++ writel(cmd | S3C_CICOSCCTRL_MAINHORRATIO_CO(cfg->sc.mainhratio) | \
++ S3C_CICOSCCTRL_MAINVERRATIO_CO(cfg->sc.mainvratio), cfg->regs + S3C_CICOSCCTRL);
++
++ } else if (cfg->dma_type & CAMIF_PREVIEW) {
++
++ writel(S3C_CIPRSCPRERATIO_SHFACTOR_PR(cfg->sc.shfactor) | \
++ S3C_CIPRSCPRERATIO_PREHORRATIO_PR(cfg->sc.prehratio) | \
++ S3C_CIPRSCPRERATIO_PREVERRATIO_PR(cfg->sc.prevratio), cfg->regs + S3C_CIPRSCPRERATIO);
++
++ writel(S3C_CIPRSCPREDST_PREDSTWIDTH_PR(cfg->sc.predst_x) | \
++ S3C_CIPRSCPREDST_PREDSTHEIGHT_PR(cfg->sc.predst_y), cfg->regs + S3C_CIPRSCPREDST);
++
++ if (cfg->dst_fmt & CAMIF_RGB24)
++ cmd |= S3C_CIPRSCCTRL_OUTRGB_FMT_PR_RGB888;
++ else
++ cmd |= S3C_CIPRSCCTRL_OUTRGB_FMT_PR_RGB565;
++
++ if (cfg->sc.scaleup_h & cfg->sc.scaleup_v)
++ cmd |= ((1 << 30) | (1 << 29));
++
++ writel(cmd | S3C_CIPRSCCTRL_MAINHORRATIO_PR(cfg->sc.mainhratio) | \
++ S3C_CIPRSCCTRL_MAINVERRATIO_PR(cfg->sc.mainvratio), cfg->regs + S3C_CIPRSCCTRL);
++
++ } else
++ printk(KERN_ERR "Invalid DMA type\n");
++
++ return 0;
++}
++#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
++static inline int s3c_camif_set_ratio(camif_cfg_t *cfg)
++{
++ u32 cmd = 0;
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++
++ writel(S3C_CICOSCPRERATIO_SHFACTOR_CO(cfg->sc.shfactor) | \
++ S3C_CICOSCPRERATIO_PREHORRATIO_CO(cfg->sc.prehratio) | \
++ S3C_CICOSCPRERATIO_PREVERRATIO_CO(cfg->sc.prevratio), cfg->regs + S3C_CICOSCPRERATIO);
++
++ writel(S3C_CICOSCPREDST_PREDSTWIDTH_CO(cfg->sc.predst_x) | \
++ S3C_CICOSCPREDST_PREDSTHEIGHT_CO(cfg->sc.predst_y), cfg->regs + S3C_CICOSCPREDST);
++
++ if (cfg->sc.scalerbypass)
++ cmd |= S3C_CICOSCCTRL_SCALERBYPASS_CO;
++
++ if (cfg->sc.scaleup_h & cfg->sc.scaleup_v)
++ cmd |= (S3C_CICOSCCTRL_SCALEUP_H | S3C_CICOSCCTRL_SCALEUP_V);
++
++ writel(cmd | S3C_CICOSCCTRL_MAINHORRATIO_CO(cfg->sc.mainhratio) | \
++ S3C_CICOSCCTRL_MAINVERRATIO_CO(cfg->sc.mainvratio), cfg->regs + S3C_CICOSCCTRL);
++
++ } else if (cfg->dma_type & CAMIF_PREVIEW) {
++
++ cmd |= S3C_CIPRSCCTRL_SAMPLE_PR;
++
++ writel(S3C_CIPRSCPRERATIO_SHFACTOR_PR(cfg->sc.shfactor) | \
++ S3C_CIPRSCPRERATIO_PREHORRATIO_PR(cfg->sc.prehratio) | \
++ S3C_CIPRSCPRERATIO_PREVERRATIO_PR(cfg->sc.prevratio), cfg->regs + S3C_CIPRSCPRERATIO);
++
++ writel(S3C_CIPRSCPREDST_PREDSTWIDTH_PR(cfg->sc.predst_x) | \
++ S3C_CIPRSCPREDST_PREDSTHEIGHT_PR(cfg->sc.predst_y), cfg->regs + S3C_CIPRSCPREDST);
++
++ if (cfg->dst_fmt & CAMIF_RGB24)
++ cmd |= S3C_CIPRSCCTRL_RGBFORMAT_24;
++
++ if (cfg->sc.scaleup_h & cfg->sc.scaleup_v)
++ cmd |= ((1 << 29) | (1 << 28));
++
++ writel(cmd | S3C_CIPRSCCTRL_MAINHORRATIO_PR(cfg->sc.mainhratio) | \
++ S3C_CIPRSCCTRL_MAINVERRATIO_PR(cfg->sc.mainvratio), cfg->regs + S3C_CIPRSCCTRL);
++
++ } else
++ printk(KERN_ERR "Invalid DMA type\n");
++
++ return 0;
++}
++#endif
++
++static int s3c_camif_calc_ratio(unsigned int src_width, unsigned int dst_width, unsigned int *ratio, unsigned int *shift)
++{
++ if (src_width >= 64 * dst_width) {
++ printk(KERN_ERR "Out of pre-scaler range: src_width / dst_width = %d (< 64)\n", src_width / dst_width);
++ return 1;
++ } else if (src_width >= 32 * dst_width) {
++ *ratio = 32;
++ *shift = 5;
++ } else if (src_width >= 16 * dst_width) {
++ *ratio = 16;
++ *shift = 4;
++ } else if (src_width >= 8 * dst_width) {
++ *ratio = 8;
++ *shift = 3;
++ } else if (src_width >= 4 * dst_width) {
++ *ratio = 4;
++ *shift = 2;
++ } else if (src_width >= 2 * dst_width) {
++ *ratio = 2;
++ *shift = 1;
++ } else {
++ *ratio = 1;
++ *shift = 0;
++ }
++
++ return 0;
++}
++
++static int s3c_camif_setup_scaler(camif_cfg_t *cfg)
++{
++ int tx = cfg->target_x, ty=cfg->target_y;
++ int sx, sy;
++
++ if (tx <= 0 || ty <= 0) {
++ printk(KERN_ERR "Invalid target size\n");
++ return -1;
++ }
++
++ sx = cfg->cis->source_x - (cfg->cis->win_hor_ofst + cfg->cis->win_hor_ofst2);
++ sy = cfg->cis->source_y - (cfg->cis->win_ver_ofst + cfg->cis->win_hor_ofst2);
++
++ if (sx <= 0 || sy <= 0) {
++ printk(KERN_ERR "Invalid source size\n");
++ return -1;
++ }
++
++ cfg->sc.modified_src_x = sx;
++ cfg->sc.modified_src_y = sy;
++
++ /* Pre-scaler control register 1 */
++ s3c_camif_calc_ratio(sx, tx, &cfg->sc.prehratio, &cfg->sc.hfactor);
++ s3c_camif_calc_ratio(sy, ty, &cfg->sc.prevratio, &cfg->sc.vfactor);
++
++ if (cfg->dma_type & CAMIF_PREVIEW) {
++ if ((sx / cfg->sc.prehratio) > 640) {
++ printk(KERN_INFO "Internal preview line buffer length is 640 pixels\n");
++ printk(KERN_INFO "Decrease the resolution or adjust window offset values appropriately\n");
++ }
++ }
++
++ cfg->sc.shfactor = 10 - (cfg->sc.hfactor + cfg->sc.vfactor);
++
++ /* Pre-scaler control register 2 */
++ cfg->sc.predst_x = sx / cfg->sc.prehratio;
++ cfg->sc.predst_y = sy / cfg->sc.prevratio;
++
++ /* Main-scaler control register */
++ cfg->sc.mainhratio = (sx << 8) / (tx << cfg->sc.hfactor);
++ cfg->sc.mainvratio = (sy << 8) / (ty << cfg->sc.vfactor);
++
++ cfg->sc.scaleup_h = (sx <= tx) ? 1 : 0;
++ cfg->sc.scaleup_v = (sy <= ty) ? 1 : 0;
++
++ s3c_camif_set_ratio(cfg);
++ s3c_camif_set_target_area(cfg);
++
++ return 0;
++}
++
++/*************************************************************************
++ * Format part
++ ************************************************************************/
++int s3c_camif_set_source_format(camif_cis_t *cis)
++{
++ camif_cfg_t *cfg = s3c_camif_get_fimc_object(CODEC_MINOR);
++ unsigned int cmd = 0;
++
++ /* Configure CISRCFMT --Source Format */
++ if (cis->itu_fmt & CAMIF_ITU601)
++ cmd = CAMIF_ITU601;
++ else {
++ assert(cis->itu_fmt & CAMIF_ITU656);
++ cmd = CAMIF_ITU656;
++ }
++
++ cmd |= (S3C_CISRCFMT_SOURCEHSIZE(cis->source_x) | S3C_CISRCFMT_SOURCEVSIZE(cis->source_y));
++
++ /* Order422 */
++ cmd |= cis->order422;
++ writel(cmd, cfg->regs + S3C_CISRCFMT);
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++ cmd = (cis->order422 >> 14);
++ writel((readl(cfg->regs + S3C_CICOCTRL) & ~(0x3 << 0)) | cmd, cfg->regs + S3C_CICOCTRL);
++#endif
++
++ return 0;
++}
++
++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
++static int s3c_camif_set_target_format(camif_cfg_t *cfg)
++{
++ unsigned int cmd = 0;
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++ cmd |= S3C_CICOTRGFMT_TARGETHSIZE_CO(cfg->target_x) | S3C_CICOTRGFMT_TARGETVSIZE_CO(cfg->target_y);
++
++ if (cfg->dst_fmt & CAMIF_YCBCR420) {
++ cmd |= (S3C_CICOTRGFMT_OUT422_420 | S3C_CICOTRGFMT_IN422_422);
++ writel(cmd, cfg->regs + S3C_CICOTRGFMT);
++ } else if (cfg->dst_fmt & CAMIF_YCBCR422) {
++ cmd |= (S3C_CICOTRGFMT_OUT422_422 | S3C_CICOTRGFMT_IN422_422);
++ writel(cmd, cfg->regs + S3C_CICOTRGFMT);
++ } else if ((cfg->dst_fmt & CAMIF_RGB24) || (cfg->dst_fmt & CAMIF_RGB16)) {
++ cmd |= (S3C_CICOTRGFMT_OUT422_422 | S3C_CICOTRGFMT_IN422_422);
++ writel(cmd | (1 << 29), cfg->regs + S3C_CICOTRGFMT);
++ } else
++ printk(KERN_ERR "Invalid target format\n");
++ } else {
++ assert(cfg->dma_type & CAMIF_PREVIEW);
++
++ cmd = readl(cfg->regs + S3C_CIPRTRGFMT);
++ cmd &= (S3C_CIPRTRGFMT_TARGETHSIZE_PR(0) | S3C_CIPRTRGFMT_TARGETVSIZE_PR(0));
++ cmd |= (S3C_CIPRTRGFMT_TARGETHSIZE_PR(cfg->target_x) | S3C_CIPRTRGFMT_TARGETVSIZE_PR(cfg->target_y));
++
++ writel(cmd | (2 << 30), cfg->regs + S3C_CIPRTRGFMT);
++ }
++
++ return 0;
++}
++#elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++static int s3c_camif_set_target_format(camif_cfg_t *cfg)
++{
++ unsigned int cmd = 0;
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++ cmd |= (S3C_CICOTRGFMT_TARGETHSIZE_CO(cfg->target_x) | S3C_CICOTRGFMT_TARGETVSIZE_CO(cfg->target_y));
++
++ if (cfg->dst_fmt & CAMIF_YCBCR420) {
++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR420OUT;
++ writel(cmd, cfg->regs + S3C_CICOTRGFMT);
++ } else if (cfg->dst_fmt & CAMIF_YCBCR422) {
++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR422OUT;
++ writel(cmd, cfg->regs + S3C_CICOTRGFMT);
++ } else if (cfg->dst_fmt & CAMIF_YCBCR422I) {
++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR422OUTINTERLEAVE;
++ writel(cmd, cfg->regs + S3C_CICOTRGFMT);
++ } else if ((cfg->dst_fmt & CAMIF_RGB24) || (cfg->dst_fmt & CAMIF_RGB16)) {
++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_RGBOUT;
++ writel(cmd, cfg->regs + S3C_CICOTRGFMT);
++ } else
++ printk(KERN_ERR "Invalid target format\n");
++ } else {
++ assert(cfg->dma_type & CAMIF_PREVIEW);
++
++ cmd = readl(cfg->regs + S3C_CIPRTRGFMT);
++ cmd &= (S3C_CIPRTRGFMT_TARGETHSIZE_PR(0) | S3C_CIPRTRGFMT_TARGETVSIZE_PR(0));
++ cmd |= (S3C_CIPRTRGFMT_TARGETHSIZE_PR(cfg->target_x) | S3C_CIPRTRGFMT_TARGETVSIZE_PR(cfg->target_y));
++
++ if (cfg->dst_fmt & CAMIF_YCBCR420)
++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR420OUT;
++ else if (cfg->dst_fmt & CAMIF_YCBCR422)
++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR422OUT;
++ else if (cfg->dst_fmt & CAMIF_YCBCR422I)
++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR422OUTINTERLEAVE;
++ else if ((cfg->dst_fmt & CAMIF_RGB24) || (cfg->dst_fmt & CAMIF_RGB16))
++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_RGBOUT;
++ else
++ printk(KERN_ERR "Invalid target format\n");
++
++ writel(cmd, cfg->regs + S3C_CIPRTRGFMT);
++ }
++
++ return 0;
++}
++#endif
++
++/*************************************************************************
++ * Control part
++ ************************************************************************/
++int s3c_camif_control_fimc(camif_cfg_t *cfg)
++{
++ if (s3c_camif_request_memory(cfg)) {
++ printk(KERN_ERR "Instead of using consistent_alloc(). Let me use dedicated mem for DMA\n");
++ return -1;
++ }
++
++ s3c_camif_setup_input_path(cfg);
++
++ if (s3c_camif_setup_scaler(cfg)) {
++ printk(KERN_ERR "Preview scaler fault: change WinHorOfset or target size\n");
++ return 1;
++ }
++
++ s3c_camif_set_target_format(cfg);
++
++ if (s3c_camif_setup_dma(cfg)) {
++ printk(KERN_ERR "DMA burst length error\n");
++ return 1;
++ }
++
++ s3c_camif_setup_output_path(cfg);
++
++ return 0;
++}
++
++int s3c_camif_start_dma(camif_cfg_t *cfg)
++{
++ unsigned int n_cmd = readl(cfg->regs + S3C_CIIMGCPT);
++ unsigned int val;
++
++ switch(cfg->capture_enable) {
++ case CAMIF_BOTH_DMA_ON:
++ s3c_camif_reset(CAMIF_RESET, 0); /* Flush Camera Core Buffer */
++
++ /* For Codec */
++ val = readl(cfg->regs + S3C_CICOSCCTRL);
++ val |= S3C_CICOSCCTRL_COSCALERSTART;
++ writel(val, cfg->regs + S3C_CICOSCCTRL);
++
++ /* For Preview */
++ val = readl(cfg->regs + S3C_CIPRSCCTRL);
++ val |= S3C_CIPRSCCTRL_START;
++ writel(val, cfg->regs + S3C_CIPRSCCTRL);
++
++ n_cmd |= S3C_CIIMGCPT_IMGCPTEN_COSC | S3C_CIIMGCPT_IMGCPTEN_PRSC;
++ break;
++
++ case CAMIF_DMA_ON:
++ s3c_camif_reset(CAMIF_RESET, 0); /* Flush Camera Core Buffer */
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++ val = readl(cfg->regs + S3C_CICOSCCTRL);
++ val |= S3C_CICOSCCTRL_COSCALERSTART;
++ writel(val, cfg->regs + S3C_CICOSCCTRL);
++
++ n_cmd |= S3C_CIIMGCPT_IMGCPTEN_COSC;
++
++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
++ n_cmd |= (1 << 24);
++#endif
++ } else {
++ val = readl(cfg->regs + S3C_CIPRSCCTRL);
++ val |= S3C_CIPRSCCTRL_START;
++ writel(val, cfg->regs + S3C_CIPRSCCTRL);
++ n_cmd |= S3C_CIIMGCPT_IMGCPTEN_PRSC;
++ }
++
++ /* wait until Sync Time expires */
++ /* First settting, to wait VSYNC fall */
++ /* By VESA spec,in 640x480 @60Hz
++ MAX Delay Time is around 64us which "while" has.*/
++ while (S3C_CICOSTATUS_VSYNC & readl(cfg->regs + S3C_CICOSTATUS));
++ break;
++
++ default:
++ break;
++ }
++
++#if defined(CONFIG_CPU_S3C2443)
++ if (cfg->dma_type & CAMIF_CODEC) {
++ if (cfg->dst_fmt & CAMIF_RGB24)
++ n_cmd |= (3 << 25);
++ else if (cfg->dst_fmt & CAMIF_RGB16)
++ n_cmd |= (1 << 25);
++ else if (cfg->dst_fmt & CAMIF_YCBCR420)
++ n_cmd |= (2 << 25);
++ }
++#endif
++
++ val = readl(cfg->regs + S3C_CIIMGCPT);
++ val &= ~(0x7 << 29);
++ writel(val | n_cmd | S3C_CIIMGCPT_IMGCPTEN, cfg->regs + S3C_CIIMGCPT);
++
++ return 0;
++}
++
++int s3c_camif_stop_dma(camif_cfg_t *cfg)
++{
++ unsigned int n_cmd = readl(cfg->regs + S3C_CIIMGCPT);
++ unsigned int val;
++
++ switch(cfg->capture_enable) {
++ case CAMIF_BOTH_DMA_OFF:
++ val = readl(cfg->regs + S3C_CICOSCCTRL);
++ val &= ~S3C_CICOSCCTRL_COSCALERSTART;
++ writel(val, cfg->regs + S3C_CICOSCCTRL);
++
++ val = readl(cfg->regs + S3C_CIPRSCCTRL);
++ val &= ~S3C_CIPRSCCTRL_START;
++ writel(val, cfg->regs + S3C_CIPRSCCTRL);
++
++ n_cmd = 0;
++ break;
++
++ case CAMIF_DMA_OFF_L_IRQ: /* fall thru */
++ case CAMIF_DMA_OFF:
++ if (cfg->dma_type & CAMIF_CODEC) {
++ val = readl(cfg->regs + S3C_CICOSCCTRL);
++ val &= ~S3C_CICOSCCTRL_COSCALERSTART;
++ writel(val, cfg->regs + S3C_CICOSCCTRL);
++ n_cmd &= ~S3C_CIIMGCPT_IMGCPTEN_COSC;
++
++ if (!(n_cmd & S3C_CIIMGCPT_IMGCPTEN_PRSC))
++ n_cmd = 0;
++ } else {
++ val = readl(cfg->regs + S3C_CIPRSCCTRL);
++ val &= ~S3C_CIPRSCCTRL_START;
++ writel(val, cfg->regs + S3C_CIPRSCCTRL);
++
++ n_cmd &= ~S3C_CIIMGCPT_IMGCPTEN_PRSC;
++
++ if (!(n_cmd & S3C_CIIMGCPT_IMGCPTEN_COSC))
++ n_cmd = 0;
++ }
++
++ break;
++
++ default:
++ printk(KERN_ERR "Unexpected DMA control\n");
++ }
++
++ writel(n_cmd, cfg->regs + S3C_CIIMGCPT);
++
++ if (cfg->capture_enable == CAMIF_DMA_OFF_L_IRQ) { /* Last IRQ */
++ if (cfg->dma_type & CAMIF_CODEC) {
++ val = readl(cfg->regs + S3C_CICOCTRL);
++ val |= S3C_CICOCTRL_LASTIRQEN;
++ writel(val, cfg->regs + S3C_CICOCTRL);
++ } else {
++ val = readl(cfg->regs + S3C_CIPRCTRL);
++ val |= S3C_CIPRCTRL_LASTIRQEN_ENABLE;
++ writel(val, cfg->regs + S3C_CIPRCTRL);
++ }
++ }
++
++ return 0;
++}
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++int s3c_camif_start_codec_msdma(camif_cfg_t *cfg)
++{
++ int ret = 0;
++ u32 val;
++
++ val = readl(cfg->regs + S3C_MSCOCTRL);
++ val &= ~(1 << 0);
++ writel(val, cfg->regs + S3C_MSCOCTRL);
++
++ val = readl(cfg->regs + S3C_MSCOCTRL);
++ val |= (1 << 0);
++ writel(val, cfg->regs + S3C_MSCOCTRL);
++
++ return ret;
++}
++#endif
++
++int s3c_camif_start_preview_msdma(camif_cfg_t * cfg)
++{
++ unsigned int val;
++ int ret = 0;
++
++#if !defined(CONFIG_CPU_S3C6400) && !defined(CONFIG_CPU_S3C6410)
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val &= ~(1 << 0);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++#endif
++ val = readl(cfg->regs + S3C_CIMSCTRL);
++ val |= (1 << 0);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ while((readl(cfg->regs + S3C_CIMSCTRL) & (1 << 6)) == 0);
++
++ return ret;
++}
++
++void s3c_camif_change_flip(camif_cfg_t *cfg)
++{
++ unsigned int cmd = 0;
++
++ if (cfg->dma_type & CAMIF_CODEC) {
++ cmd = readl(cfg->regs + S3C_CICOTRGFMT);
++ cmd &= ~((1 << 14) | (1 << 15));
++ cmd |= cfg->flip;
++ writel(cmd, cfg->regs + S3C_CICOTRGFMT);
++ } else {
++ /* if ROT90_Pr == 1, dma burst length must be 4 */
++ if (cfg->flip == CAMIF_ROTATE_90 || cfg->flip == CAMIF_FLIP_ROTATE_270) {
++ cmd = readl(cfg->regs + S3C_CIPRCTRL);
++ cmd &= ~(0x3ff << 14);
++ cmd |= (S3C_CICOCTRL_YBURST1_CO(4) | S3C_CICOCTRL_YBURST2_CO(4));
++ writel(cmd, cfg->regs + S3C_CIPRCTRL);
++ }
++
++ cmd = readl(cfg->regs + S3C_CIPRTRGFMT);
++ cmd &= ~(0x7 << 13);
++ cmd |= cfg->flip;
++ writel(cmd, cfg->regs + S3C_CIPRTRGFMT);
++ }
++}
++
++void s3c_camif_change_effect(camif_cfg_t *cfg)
++{
++ unsigned int val = readl(cfg->regs + S3C_CIIMGEFF);
++ val &= ~((1 << 28) | (1 << 27) | (1 << 26));
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++ val |= ((1 << 31) | (1 << 30));
++#endif
++
++ switch(cfg->effect) {
++ case CAMIF_SILHOUETTE:
++ val |= S3C_CIIMGEFF_FIN_SILHOUETTE;
++ break;
++
++ case CAMIF_EMBOSSING:
++ val |= S3C_CIIMGEFF_FIN_EMBOSSING;
++ break;
++
++ case CAMIF_ART_FREEZE:
++ val |= S3C_CIIMGEFF_FIN_ARTFREEZE;
++ break;
++
++ case CAMIF_NEGATIVE:
++ val |= S3C_CIIMGEFF_FIN_NEGATIVE;
++ break;
++
++ case CAMIF_ARBITRARY_CB_CR:
++ val |= S3C_CIIMGEFF_FIN_ARBITRARY;
++ break;
++
++ case CAMIF_BYPASS:
++ default:
++ break;
++ }
++
++ writel(val, cfg->regs + S3C_CIIMGEFF);
++}
++
++int s3c_camif_do_postprocess(camif_cfg_t *cfg)
++{
++ unsigned int val= readl(cfg->regs + S3C_CIMSCTRL);
++
++ if (cfg->dst_fmt & CAMIF_YCBCR420)
++ val |= (1 << 1);
++ else
++ val &= ~(1 << 1);
++
++ val &= ~(1 << 0);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ val |= (1 << 0);
++ writel(val, cfg->regs + S3C_CIMSCTRL);
++
++ printk(KERN_INFO "Postprocessing started\n");
++
++ while((readl(cfg->regs + S3C_CIMSCTRL) & (1 << 6)) == 0);
++
++ printk(KERN_INFO "Postprocessing finished\n");
++
++ return 0;
++}
++
++int s3c_camif_set_offset(camif_cis_t *cis)
++{
++ camif_cfg_t *cfg = s3c_camif_get_fimc_object(CODEC_MINOR);
++ unsigned int h = cis->win_hor_ofst; /* Camera input offset ONLY */
++ unsigned int v = cis->win_ver_ofst; /* Camera input offset ONLY */
++ unsigned int h2 = cis->win_hor_ofst2; /* Camera input offset ONLY */
++ unsigned int v2 = cis->win_ver_ofst2; /* Camera input offset ONLY */
++
++ /*Clear Overflow */
++ writel(S3C_CIWDOFST_CLROVCOFIY | S3C_CIWDOFST_CLROVCOFICB | \
++ S3C_CIWDOFST_CLROVCOFICR | S3C_CIWDOFST_CLROVPRFICB | \
++ S3C_CIWDOFST_CLROVPRFICR, cfg->regs + S3C_CIWDOFST);
++
++ writel(0, cfg->regs + S3C_CIWDOFST);
++
++ if (!h && !v) {
++ writel(0, cfg->regs + S3C_CIWDOFST);
++ writel(0, cfg->regs + S3C_CIDOWSFT2);
++ return 0;
++ }
++
++ writel(S3C_CIWDOFST_WINOFSEN | S3C_CIWDOFST_WINHOROFST(h) | S3C_CIWDOFST_WINVEROFST(v), cfg->regs + S3C_CIWDOFST);
++ writel(S3C_CIDOWSFT2_WINHOROFST2(h) | S3C_CIDOWSFT2_WINVEROFST2(v), cfg->regs + S3C_CIDOWSFT2);
++ writel(S3C_CIDOWSFT2_WINHOROFST2(h2) | S3C_CIDOWSFT2_WINVEROFST2(v2), cfg->regs + S3C_CIDOWSFT2);
++
++ return 0;
++}
++
++void s3c_camif_set_priority(int flag)
++{
++ unsigned int val;
++
++ if (flag) {
++ irq_old_priority = readl(S3C64XX_PRIORITY);
++ val = irq_old_priority;
++ val &= ~(3 << 7);
++ writel(val, S3C64XX_PRIORITY);
++
++ /* Arbiter 1, REQ2 first */
++ val |= (1 << 7);
++ writel(val, S3C64XX_PRIORITY);
++
++ /* Disable Priority Rotate */
++ val &= ~(1 << 1);
++ writel(val, S3C64XX_PRIORITY);
++ } else
++ writel(irq_old_priority, S3C64XX_PRIORITY);
++}
++
++/*************************************************************************
++ * Interrupt part
++ ************************************************************************/
++void s3c_camif_enable_lastirq(camif_cfg_t *cfg)
++{
++ unsigned int val;
++
++ if (cfg->capture_enable == CAMIF_BOTH_DMA_ON) {
++ val = readl(cfg->regs + S3C_CICOCTRL);
++ val |= S3C_CICOCTRL_LASTIRQEN;
++ writel(val, cfg->regs + S3C_CICOCTRL);
++
++ val = readl(cfg->regs + S3C_CIPRCTRL);
++ val |= S3C_CIPRCTRL_LASTIRQEN_ENABLE;
++ writel(val, cfg->regs + S3C_CIPRCTRL);
++ } else {
++ if (cfg->dma_type & CAMIF_CODEC) {
++ val = readl(cfg->regs + S3C_CICOCTRL);
++ val |= S3C_CICOCTRL_LASTIRQEN;
++ writel(val, cfg->regs + S3C_CICOCTRL);
++ } else {
++ val = readl(cfg->regs + S3C_CIPRCTRL);
++ val |= S3C_CIPRCTRL_LASTIRQEN_ENABLE;
++ writel(val, cfg->regs + S3C_CIPRCTRL);
++ }
++ }
++}
++
++void s3c_camif_disable_lastirq(camif_cfg_t *cfg)
++{
++ unsigned int val;
++
++ if (cfg->capture_enable == CAMIF_BOTH_DMA_ON) {
++ val = readl(cfg->regs + S3C_CICOCTRL);
++ val &= ~S3C_CICOCTRL_LASTIRQEN;
++ writel(val, cfg->regs + S3C_CICOCTRL);
++
++ val = readl(cfg->regs + S3C_CIPRCTRL);
++ val &= ~S3C_CIPRCTRL_LASTIRQEN_ENABLE;
++ writel(val, cfg->regs + S3C_CIPRCTRL);
++ } else {
++ if (cfg->dma_type & CAMIF_CODEC) {
++ val = readl(cfg->regs + S3C_CICOCTRL);
++ val &= ~S3C_CICOCTRL_LASTIRQEN;
++ writel(val, cfg->regs + S3C_CICOCTRL);
++ } else {
++ val = readl(cfg->regs + S3C_CIPRCTRL);
++ val &= ~S3C_CIPRCTRL_LASTIRQEN_ENABLE;
++ writel(val, cfg->regs + S3C_CIPRCTRL);
++ }
++ }
++}
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++void s3c_camif_clear_irq(int irq)
++{
++ camif_cfg_t *cfg = s3c_camif_get_fimc_object(CODEC_MINOR);
++ unsigned int val = 0;
++
++ if (irq == IRQ_CAMIF_C) {
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val |= (1 << 19);
++ } else if (irq == IRQ_CAMIF_P) {
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val |= (1 << 18);
++ }
++
++ writel(val, cfg->regs + S3C_CIGCTRL);
++}
++#else
++void s3c_camif_clear_irq(int irq)
++{
++}
++#endif
++
++/*************************************************************************
++ * Initialize part
++ ************************************************************************/
++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
++static int s3c_camif_set_gpio(void)
++{
++ s3c2410_gpio_cfgpin(S3C2440_GPJ0, S3C2440_GPJ0_CAMDATA0);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ1, S3C2440_GPJ1_CAMDATA1);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ2, S3C2440_GPJ2_CAMDATA2);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ3, S3C2440_GPJ3_CAMDATA3);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ4, S3C2440_GPJ4_CAMDATA4);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ5, S3C2440_GPJ5_CAMDATA5);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ6, S3C2440_GPJ6_CAMDATA6);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ7, S3C2440_GPJ7_CAMDATA7);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ8, S3C2440_GPJ8_CAMPCLK);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ9, S3C2440_GPJ9_CAMVSYNC);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ10, S3C2440_GPJ10_CAMHREF);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ11, S3C2440_GPJ11_CAMCLKOUT);
++ s3c2410_gpio_cfgpin(S3C2440_GPJ12, S3C2440_GPJ12_CAMRESET);
++
++ writel(0x1fff, S3C2443_GPJDN);
++
++ return 0;
++}
++#elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++static int s3c_camif_set_gpio(void)
++{
++ s3c_gpio_cfgpin(S3C64XX_GPF(5), S3C64XX_GPF5_CAMIF_YDATA0);
++ s3c_gpio_cfgpin(S3C64XX_GPF(6), S3C64XX_GPF6_CAMIF_YDATA1);
++ s3c_gpio_cfgpin(S3C64XX_GPF(7), S3C64XX_GPF7_CAMIF_YDATA2);
++ s3c_gpio_cfgpin(S3C64XX_GPF(8), S3C64XX_GPF8_CAMIF_YDATA3);
++ s3c_gpio_cfgpin(S3C64XX_GPF(9), S3C64XX_GPF9_CAMIF_YDATA4);
++ s3c_gpio_cfgpin(S3C64XX_GPF(10), S3C64XX_GPF10_CAMIF_YDATA5);
++ s3c_gpio_cfgpin(S3C64XX_GPF(11), S3C64XX_GPF11_CAMIF_YDATA6);
++ s3c_gpio_cfgpin(S3C64XX_GPF(12), S3C64XX_GPF12_CAMIF_YDATA7);
++ s3c_gpio_cfgpin(S3C64XX_GPF(2), S3C64XX_GPF2_CAMIF_PCLK);
++ s3c_gpio_cfgpin(S3C64XX_GPF(4), S3C64XX_GPF4_CAMIF_VSYNC);
++ s3c_gpio_cfgpin(S3C64XX_GPF(1), S3C64XX_GPF1_CAMIF_HREF);
++ s3c_gpio_cfgpin(S3C64XX_GPF(0), S3C64XX_GPF0_CAMIF_CLK);
++ s3c_gpio_cfgpin(S3C64XX_GPF(3), S3C64XX_GPF3_CAMIF_nRST);
++
++ writel(0, S3C64XX_GPFPUD);
++
++ return 0;
++}
++#endif
++
++void s3c_camif_reset(int is, int delay)
++{
++ camif_cfg_t *cfg = s3c_camif_get_fimc_object(CODEC_MINOR);
++ unsigned int val;
++ unsigned int tmp;
++
++ switch (is) {
++ case CAMIF_RESET:
++ tmp = readl(cfg->regs + S3C_CISRCFMT);
++
++ if (tmp &= (1 << 31)) {
++ /* ITU-R BT 601 */
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val |= S3C_CIGCTRL_SWRST;
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++ val |= S3C_CIGCTRL_IRQ_LEVEL;
++#endif
++ writel(val, cfg->regs + S3C_CIGCTRL);
++ mdelay(1);
++
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val &= ~S3C_CIGCTRL_SWRST;
++ writel(val, cfg->regs + S3C_CIGCTRL);
++ } else {
++ /* ITU-R BT 656 */
++ tmp = readl(cfg->regs + S3C_CISRCFMT);
++ tmp |= (1 << 31);
++ writel(tmp, cfg->regs + S3C_CISRCFMT);
++
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val |= S3C_CIGCTRL_SWRST;
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++ val |= S3C_CIGCTRL_IRQ_LEVEL;
++#endif
++ writel(val, cfg->regs + S3C_CIGCTRL);
++ mdelay(1);
++
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val &= ~S3C_CIGCTRL_SWRST;
++ writel(val, cfg->regs + S3C_CIGCTRL);
++
++ tmp = readl(cfg->regs + S3C_CISRCFMT);
++ tmp &= ~(1 << 31);
++ writel(tmp, cfg->regs + S3C_CISRCFMT);
++ }
++
++ break;
++
++ case CAMIF_EX_RESET_AH:
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val |= S3C_CIGCTRL_CAMRST;
++ writel(val, cfg->regs + S3C_CIGCTRL);
++ udelay(200);
++
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val &= ~S3C_CIGCTRL_CAMRST;
++ writel(val, cfg->regs + S3C_CIGCTRL);
++ udelay(delay);
++
++#if defined(CONFIG_VIDEO_SAMSUNG_S5K3AA)
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val |= S3C_CIGCTRL_CAMRST;
++ writel(val, cfg->regs + S3C_CIGCTRL);
++ udelay(200);
++#endif
++ break;
++
++ case CAMIF_EX_RESET_AL:
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val &= ~S3C_CIGCTRL_CAMRST;
++ writel(val, cfg->regs + S3C_CIGCTRL);
++ udelay(200);
++
++ val = readl(cfg->regs + S3C_CIGCTRL);
++ val |= S3C_CIGCTRL_CAMRST;
++ writel(val, cfg->regs + S3C_CIGCTRL);
++ udelay(delay);
++ break;
++
++ default:
++ break;
++ }
++}
++
++void s3c_camif_init(void)
++{
++ s3c_camif_reset(CAMIF_RESET, 0);
++ s3c_camif_set_gpio();
++}
++
+Index: cam/drivers/media/video/s3c_camif.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ cam/drivers/media/video/s3c_camif.h 2009-02-26 21:30:41.000000000 +0800
+@@ -0,0 +1,404 @@
++/* drivers/media/video/s3c_camif.h
++ *
++ * Copyright (c) 2008 Samsung Electronics
++ *
++ * Samsung S3C Camera driver
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef __S3C_CAMIF_H_
++#define __S3C_CAMIF_H_
++
++#ifdef __KERNEL__
++#include <linux/videodev.h>
++#include <linux/videodev2.h>
++#include <asm/types.h>
++#include <linux/i2c.h>
++#include <linux/video_decoder.h>
++#endif /* __KERNEL__ */
++
++#if !defined(O_NONCAP)
++#define O_NONCAP O_TRUNC
++#endif
++
++#if defined(CAMIF_DEBUG)
++#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
++#else
++#define DPRINTK(fmt, args...)
++#endif
++
++#if defined(CAMIF_DEBUG)
++#define assert(expr) \
++ if(!(expr)) { \
++ printk( "Assertion failed! %s,%s,%s,line=%d\n", \
++ #expr,__FILE__,__FUNCTION__,__LINE__); \
++ }
++#else
++#define assert(expr)
++#endif
++
++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
++#define MEM_SIZE 0x08000000
++#define FIMC_VER "3.0"
++#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
++#define MEM_SIZE 0x04000000
++#define FIMC_VER "2.3"
++#else
++#define MEM_SIZE 0x04000000
++#define FIMC_VER "2.x"
++#endif
++
++#undef FSM_ON_PREVIEW
++#define FSM_ON_CODEC
++
++#undef USE_LAST_IRQ /* turn on if pp count is 1 */
++
++#define CODEC_DEV_NAME "CAMIF_CODEC"
++#define PREVIEW_DEV_NAME "CAMIF_PREVIEW"
++
++#define CAMIF_DEV_NUM 2
++#define FIMC_CODEC_INDEX 0
++#define FIMC_PREVIEW_INDEX 1
++
++#define BURST_ERR 1
++#define RESERVED_MEM (15 * 1024 * 1024)
++#define YUV_MEM (10 * 1024 * 1024)
++#define RGB_MEM (RESERVED_MEM - YUV_MEM)
++
++#define CODEC_DEFAULT_WIDTH 640
++#define CODEC_DEFAULT_HEIGHT 480
++#define PREVIEW_DEFAULT_WIDTH 640
++#define PREVIEW_DEFAULT_HEIGHT 480
++
++#define CROP_DEFAULT_WIDTH 352
++#define CROP_DEFAULT_HEIGHT 272
++
++#define CODEC_DEFAULT_PPNUM 4
++#define PREVIEW_DEFAULT_PPNUM 4
++
++#define CODEC_MINOR 12
++#define PREVIEW_MINOR 13
++
++#define CHECK_FREQ 5
++#define INSTANT_SKIP 0
++#define INSTANT_GO 1
++
++#define VID_HARDWARE_SAMSUNG_FIMC3X 236
++
++#define ZOOM_AT_A_TIME_IN_PIXELS 32
++#define ZOOM_IN_MAX 640
++
++/* Codec or Preview Status */
++#define CAMIF_STARTED (1 << 1)
++#define CAMIF_STOPPED (1 << 2)
++#define CAMIF_INT_HAPPEN (1 << 3)
++
++/* Codec or Preview : Interrupt FSM */
++#define CAMIF_1st_INT (1 << 7)
++#define CAMIF_Xth_INT (1 << 8)
++#define CAMIF_Yth_INT (1 << 9)
++#define CAMIF_Zth_INT (1 << 10)
++#define CAMIF_NORMAL_INT (1 << 11)
++#define CAMIF_DUMMY_INT (1 << 12)
++#define CAMIF_CONTINUOUS_INT (1 << 13)
++#define CAMIF_SET_LAST_INT (1 << 14)
++#define CAMIF_STOP_CAPTURE (1 << 15)
++#define CAMIF_LAST_IRQ (1 << 16)
++#define CAMIF_PENDING_INT 0
++
++#define CAMIF_CAPTURE_SKIP_FRAMES 5
++
++/* CAMIF RESET Definition */
++#define CAMIF_RESET (1 << 0)
++#define CAMIF_EX_RESET_AL (1 << 1) /* Active Low */
++#define CAMIF_EX_RESET_AH (1 << 2) /* Active High */
++
++#define USER_EXIT (1 << 2)
++#define USER_ADD (1 << 1)
++#define SENSOR_INIT (1 << 0)
++
++#define SENSOR_MAX 255
++#define SENSOR_QSVGA (1 << 12)
++#define SENSOR_UXGA (1 << 11)
++#define SENSOR_SVGA (1 << 10)
++#define SENSOR_SXGA (1 << 4)
++#define SENSOR_VGA (1 << 3)
++#define SENSOR_DEFAULT 0
++
++#define SENSOR_WB (1 << 9)
++#define SENSOR_AF (1 << 8)
++#define SENSOR_MIRROR (1 << 7)
++#define SENSOR_ZOOMOUT (1 << 6)
++#define SENSOR_ZOOMIN (1 << 5)
++
++/* Global Status Definition */
++#define PWANT2START (1 << 0)
++#define CWANT2START (1 << 1)
++#define BOTH_STARTED (PWANT2START | CWANT2START)
++#define P_NOT_WORKING (1 << 4)
++#define C_WORKING (1 << 5)
++#define P_WORKING (1 << 6)
++#define C_NOT_WORKING (1 << 7)
++
++#define FORMAT_FLAGS_DITHER 0x01
++#define FORMAT_FLAGS_PACKED 0x02
++#define FORMAT_FLAGS_PLANAR 0x04
++#define FORMAT_FLAGS_RAW 0x08
++#define FORMAT_FLAGS_CrCb 0x10
++
++enum camif_itu_fmt {
++ CAMIF_ITU601 = (1 << 31),
++ CAMIF_ITU656 = 0,
++};
++
++/* It is possbie to use two device simultaneously */
++enum camif_dma_type {
++ CAMIF_PREVIEW = (1 << 0),
++ CAMIF_CODEC = (1 << 1),
++};
++
++enum camif_order422 {
++ CAMIF_YCBYCR = 0,
++ CAMIF_YCRYCB = (1 << 14),
++ CAMIF_CBYCRY = (1 << 15),
++ CAMIF_CRYCBY = (1 << 15) | (1 << 14),
++};
++
++enum flip_mode {
++ CAMIF_FLIP = 0,
++ CAMIF_ROTATE_90 = (1 << 13),
++ CAMIF_FLIP_X = (1 << 14),
++ CAMIF_FLIP_Y = (1 << 15),
++ CAMIF_FLIP_MIRROR = (1 << 15) | (1 << 14),
++ CAMIF_FLIP_ROTATE_270 = (1 << 15) | (1 << 14) | (1 << 13),
++};
++
++enum camif_fmt {
++ CAMIF_YCBCR420 = (1 << 0),
++ CAMIF_YCBCR422 = (1 << 1),
++ CAMIF_YCBCR422I = (1 << 2),
++ CAMIF_RGB16 = (1 << 3),
++ CAMIF_RGB24 = (1 << 4),
++ CAMIF_RGB32 = (1 << 5),
++};
++
++enum camif_capturing {
++ CAMIF_BOTH_DMA_ON = (1 << 4),
++ CAMIF_DMA_ON = (1 << 3),
++ CAMIF_BOTH_DMA_OFF = (1 << 1),
++ CAMIF_DMA_OFF = (1 << 0),
++ CAMIF_DMA_OFF_L_IRQ = (1 << 5),
++};
++
++enum image_effect {
++ CAMIF_BYPASS,
++ CAMIF_ARBITRARY_CB_CR,
++ CAMIF_NEGATIVE,
++ CAMIF_ART_FREEZE,
++ CAMIF_EMBOSSING ,
++ CAMIF_SILHOUETTE,
++};
++
++enum input_channel{
++ CAMERA_INPUT,
++ MSDMA_FROM_CODEC,
++ MSDMA_FROM_PREVIEW,
++};
++
++enum output_channel{
++ CAMIF_OUT_PP,
++ CAMIF_OUT_FIFO,
++};
++
++typedef struct camif_performance
++{
++ int frames;
++ int framesdropped;
++ __u64 bytesin;
++ __u64 bytesout;
++ __u32 reserved[4];
++} camif_perf_t;
++
++typedef struct {
++ dma_addr_t phys_y;
++ dma_addr_t phys_cb;
++ dma_addr_t phys_cr;
++ u8 *virt_y;
++ u8 *virt_cb;
++ u8 *virt_cr;
++ dma_addr_t phys_rgb;
++ u8 *virt_rgb;
++} img_buf_t;
++
++/* this structure convers the CIWDOFFST, prescaler, mainscaler */
++typedef struct {
++ u32 modified_src_x; /* After windows applyed to source_x */
++ u32 modified_src_y;
++ u32 hfactor;
++ u32 vfactor;
++ u32 shfactor; /* SHfactor = 10 - ( hfactor + vfactor ) */
++ u32 prehratio;
++ u32 prevratio;
++ u32 predst_x;
++ u32 predst_y;
++ u32 scaleup_h;
++ u32 scaleup_v;
++ u32 mainhratio;
++ u32 mainvratio;
++ u32 scalerbypass; /* only codec */
++ u32 zoom_in_cnt;
++} scaler_t;
++
++enum v4l2_status {
++ CAMIF_V4L2_INIT = (1 << 0),
++ CAMIF_v4L2_DIRTY = (1 << 1),
++};
++
++typedef struct {
++ struct mutex lock;
++ enum camif_itu_fmt itu_fmt;
++ enum camif_order422 order422;
++ struct i2c_client *sensor;
++ u32 win_hor_ofst;
++ u32 win_ver_ofst;
++ u32 win_hor_ofst2;
++ u32 win_ver_ofst2;
++ u32 camclk; /* External Image Sensor Camera Clock */
++ u32 source_x;
++ u32 source_y;
++ u32 polarity_pclk;
++ u32 polarity_vsync;
++ u32 polarity_href;
++ u32 user; /* MAX 2 (codec, preview) */
++ u32 irq_old_priority; /* BUS PRIORITY register */
++ u32 status;
++ u32 init_sensor; /* initializing sensor */
++ u32 reset_type; /* External Sensor Reset Type */
++ u32 reset_udelay;
++ u32 zoom_in_cnt;
++} camif_cis_t;
++
++/* when App want to change v4l2 parameter,
++ * we instantly store it into v4l2_t v2
++ * and then reflect it to hardware
++ */
++typedef struct v4l2 {
++ struct v4l2_fmtdesc *fmtdesc;
++ struct v4l2_framebuffer frmbuf; /* current frame buffer */
++ struct v4l2_input *input;
++ struct v4l2_output *output;
++ enum v4l2_status status;
++
++ /* crop */
++ struct v4l2_rect crop_bounds;
++ struct v4l2_rect crop_defrect;
++ struct v4l2_rect crop_current;
++
++} v4l2_t;
++
++
++typedef struct camif_c_t {
++ struct video_device *v;
++
++ /* V4L2 param only for v4l2 driver */
++ v4l2_t v2;
++ camif_cis_t *cis; /* Common between Codec and Preview */
++
++ /* logical parameter */
++ wait_queue_head_t waitq;
++ u32 status; /* Start/Stop */
++ u32 fsm; /* Start/Stop */
++ u32 open_count; /* duplicated */
++ int irq;
++ char shortname[16];
++ u32 target_x;
++ u32 target_y;
++ scaler_t sc;
++ enum flip_mode flip;
++ enum image_effect effect;
++ enum camif_dma_type dma_type;
++
++ /* 4 pingpong Frame memory */
++ u8 *pp_virt_buf;
++ dma_addr_t pp_phys_buf;
++ u32 pp_totalsize;
++ u32 pp_num; /* used pingpong memory number */
++ img_buf_t img_buf[4];
++ enum camif_fmt src_fmt;
++ enum camif_fmt dst_fmt;
++ enum camif_capturing capture_enable;
++ camif_perf_t perf;
++ u32 cur_frame_num;
++ u32 auto_restart; /* Only For Preview */
++ int input_channel;
++ int output_channel;
++ int buffer_size;
++ void *other; /* other camif_cfg_t */
++ u32 msdma_status; /* 0 : stop, 1 : start */
++ void __iomem *regs;
++} camif_cfg_t;
++
++/* Test Application Usage */
++typedef struct {
++ int src_x;
++ int src_y;
++ int dst_x;
++ int dst_y;
++ int src_fmt;
++ int dst_fmt;
++ int flip;
++ int awb;
++ int effect;
++ int input_channel;
++ int output_channel;
++ unsigned int h_offset;
++ unsigned int v_offset;
++ unsigned int h_offset2;
++ unsigned int v_offset2;
++} camif_param_t;
++
++/* Externs */
++extern camif_cfg_t* s3c_camif_get_fimc_object(int);
++extern int s3c_camif_start_dma(camif_cfg_t *);
++extern int s3c_camif_stop_dma(camif_cfg_t *);
++extern int s3c_camif_get_frame_num(camif_cfg_t *);
++extern unsigned char* s3c_camif_get_frame(camif_cfg_t *);
++extern int s3c_camif_control_fimc(camif_cfg_t *);
++extern void s3c_camif_reset(int, int);
++extern void s3c_camif_init(void);
++extern int s3c_camif_get_fifo_status(camif_cfg_t *);
++extern void s3c_camif_enable_lastirq(camif_cfg_t *);
++extern void s3c_camif_disable_lastirq(camif_cfg_t *);
++extern void s3c_camif_change_flip(camif_cfg_t *);
++extern void s3c_camif_change_effect(camif_cfg_t *);
++extern int s3c_camif_start_codec_msdma(camif_cfg_t *);
++extern int s3c_camif_set_clock(unsigned int camclk);
++extern void s3c_camif_disable_clock(void);
++extern int s3c_camif_start_preview_msdma(camif_cfg_t *);
++extern camif_cis_t* get_initialized_cis(void);
++extern void s3c_camif_clear_irq(int);
++extern int s3c_camif_set_source_format(camif_cis_t *);
++extern void s3c_camif_register_sensor(struct i2c_client *);
++extern void s3c_camif_unregister_sensor(struct i2c_client*);
++extern int s3c_camif_setup_dma(camif_cfg_t *);
++extern void s3c_camif_init_sensor(camif_cfg_t *);
++extern int s3c_camif_set_offset(camif_cis_t *);
++extern void s3c_camif_set_priority(int);
++extern void s3c_camif_open_sensor(camif_cis_t *);
++extern void s3c_camif_set_polarity(camif_cfg_t *cfg);
++
++#endif
++
+Index: cam/drivers/media/video/videodev2_s3c.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ cam/drivers/media/video/videodev2_s3c.h 2009-02-26 21:30:41.000000000 +0800
+@@ -0,0 +1,210 @@
++#ifndef __VIDEODEV2_S3C_H_
++#define __VIDEODEV2_S3C_H_
++
++#include <linux/videodev2.h>
++
++#define V4L2_INPUT_TYPE_MSDMA 3
++#define V4L2_INPUT_TYPE_INTERLACE 4
++
++/****************************************************************
++* struct v4l2_control
++* Control IDs defined by S3C
++*****************************************************************/
++/* Image Effect */
++#define V4L2_CID_ORIGINAL (V4L2_CID_PRIVATE_BASE + 0)
++#define V4L2_CID_ARBITRARY (V4L2_CID_PRIVATE_BASE + 1)
++#define V4L2_CID_NEGATIVE (V4L2_CID_PRIVATE_BASE + 2)
++#define V4L2_CID_ART_FREEZE (V4L2_CID_PRIVATE_BASE + 3)
++#define V4L2_CID_EMBOSSING (V4L2_CID_PRIVATE_BASE + 4)
++#define V4L2_CID_SILHOUETTE (V4L2_CID_PRIVATE_BASE + 5)
++
++/* Image Rotate */
++#define V4L2_CID_ROTATE_90 (V4L2_CID_PRIVATE_BASE + 6)
++#define V4L2_CID_ROTATE_180 (V4L2_CID_PRIVATE_BASE + 7)
++#define V4L2_CID_ROTATE_270 (V4L2_CID_PRIVATE_BASE + 8)
++#define V4L2_CID_ROTATE_BYPASS (V4L2_CID_PRIVATE_BASE + 9)
++
++/* Zoom-in, Zoom-out */
++#define V4L2_CID_ZOOMIN (V4L2_CID_PRIVATE_BASE + 10)
++#define V4L2_CID_ZOOMOUT (V4L2_CID_PRIVATE_BASE + 11)
++
++/****************************************************************
++* 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
++* It's only for S3C
++*****************************************************************/
++#define VIDIOC_S_CAMERA_START _IO ('V', BASE_VIDIOC_PRIVATE + 0)
++#define VIDIOC_S_CAMERA_STOP _IO ('V', BASE_VIDIOC_PRIVATE + 1)
++#define VIDIOC_MSDMA_START _IOW ('V', BASE_VIDIOC_PRIVATE + 2, struct v4l2_msdma_format)
++#define VIDIOC_MSDMA_STOP _IOW ('V', BASE_VIDIOC_PRIVATE + 3, struct v4l2_msdma_format)
++#define VIDIOC_S_MSDMA _IOW ('V', BASE_VIDIOC_PRIVATE + 4, struct v4l2_msdma_format)
++#define VIDIOC_S_INTERLACE_MODE _IOW ('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_interlace_format)
++
++/*
++ * INTERLACE MODE
++ */
++#define S3C_VIDEO_DECODER_PAL 1 /* can decode PAL signal */
++#define S3C_VIDEO_DECODER_NTSC 2 /* can decode NTSC */
++#define S3C_VIDEO_DECODER_SECAM 4 /* can decode SECAM */
++#define S3C_VIDEO_DECODER_AUTO 8 /* can autosense norm */
++#define S3C_VIDEO_DECODER_CCIR 16 /* CCIR-601 pixel rate (720 pixels per line) instead of square pixel rate */
++
++#define S3C_DECODER_INIT _IOW ('V', BASE_VIDIOC_PRIVATE + 14, struct s3c_video_decoder_init) /* init internal registers at once */
++#define S3C_DECODER_GET_CAPABILITIES _IOR ('V', BASE_VIDIOC_PRIVATE + 6, struct s3c_video_decoder_capability)
++#define S3C_DECODER_GET_STATUS _IOR ('V', BASE_VIDIOC_PRIVATE + 7, int)
++#define S3C_DECODER_SET_NORM _IOW ('V', BASE_VIDIOC_PRIVATE + 8, int)
++#define S3C_DECODER_SET_INPUT _IOW ('V', BASE_VIDIOC_PRIVATE + 9, int) /* 0 <= input < #inputs */
++#define S3C_DECODER_SET_OUTPUT _IOW ('V', BASE_VIDIOC_PRIVATE + 10, int) /* 0 <= output < #outputs */
++#define S3C_DECODER_ENABLE_OUTPUT _IOW ('V', BASE_VIDIOC_PRIVATE + 11, int) /* boolean output enable control */
++#define S3C_DECODER_SET_PICTURE _IOW ('V', BASE_VIDIOC_PRIVATE + 12, struct video_picture)
++#define S3C_DECODER_SET_GPIO _IOW ('V', BASE_VIDIOC_PRIVATE + 13, int) /* switch general purpose pin */
++#define S3C_DECODER_SET_VBI_BYPASS _IOW ('V', BASE_VIDIOC_PRIVATE + 15, int) /* switch vbi bypass */
++#define S3C_DECODER_DUMP _IO ('V', BASE_VIDIOC_PRIVATE + 16) /* debug hook */
++
++enum v4l2_msdma_input {
++ V4L2_MSDMA_CODEC = 1,
++ V4L2_MSDMA_PREVIEW = 2,
++};
++
++struct v4l2_msdma_format
++{
++ __u32 width; /* MSDMA INPUT : Source X size */
++ __u32 height; /* MSDMA INPUT : Source Y size */
++ __u32 pixelformat;
++ enum v4l2_msdma_input input_path;
++};
++
++struct v4l2_interlace_format
++{
++ __u32 width; /* INTERLACE INPUT : Source X size */
++ __u32 height; /* INTERLACE INPUT : Source Y size */
++};
++
++struct s3c_video_decoder_init {
++ unsigned char len;
++ const unsigned char *data;
++};
++
++struct s3c_video_decoder_capability { /* this name is too long */
++ __u32 flags;
++ int inputs; /* number of inputs */
++ int outputs; /* number of outputs */
++};
++
++static struct v4l2_input fimc_inputs[] = {
++ {
++ .index = 0,
++ .name = "S3C FIMC External Camera Input",
++ .type = V4L2_INPUT_TYPE_CAMERA,
++ .audioset = 1,
++ .tuner = 0,
++ .std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M,
++ .status = 0,
++ },
++ {
++ .index = 1,
++ .name = "Memory Input (MSDMA)",
++ .type = V4L2_INPUT_TYPE_MSDMA,
++ .audioset = 2,
++ .tuner = 0,
++ .std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M,
++ .status = 0,
++ }
++};
++
++static struct v4l2_output fimc_outputs[] = {
++ {
++ .index = 0,
++ .name = "Pingpong Memory Output",
++ .type = 0,
++ .audioset = 0,
++ .modulator = 0,
++ .std = 0,
++ },
++ {
++ .index = 1,
++ .name = "LCD FIFO Output",
++ .type = 0,
++ .audioset = 0,
++ .modulator = 0,
++ .std = 0,
++ }
++};
++
++const struct v4l2_fmtdesc fimc_codec_formats[] = {
++ {
++ .index = 0,
++ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
++ .flags = FORMAT_FLAGS_PACKED,
++ .description = "16 bpp RGB, le",
++ .pixelformat = V4L2_PIX_FMT_RGB565,
++ },
++ {
++ .index = 1,
++ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
++ .flags = FORMAT_FLAGS_PACKED,
++ .description = "32 bpp RGB, le",
++ .pixelformat = V4L2_PIX_FMT_BGR32,
++ },
++ {
++ .index = 2,
++ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
++ .flags = FORMAT_FLAGS_PLANAR,
++ .description = "4:2:2, planar, Y-Cb-Cr",
++ .pixelformat = V4L2_PIX_FMT_YUV422P,
++
++ },
++ {
++ .index = 3,
++ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
++ .flags = FORMAT_FLAGS_PLANAR,
++ .description = "4:2:0, planar, Y-Cb-Cr",
++ .pixelformat = V4L2_PIX_FMT_YUV420,
++ }
++};
++
++const struct v4l2_fmtdesc fimc_preview_formats[] = {
++ {
++ .index = 0,
++ .type = V4L2_BUF_TYPE_VIDEO_OVERLAY,
++ .flags = FORMAT_FLAGS_PACKED,
++ .description = "16 bpp RGB, le",
++ .pixelformat = V4L2_PIX_FMT_RGB565,
++ },
++ {
++ .index = 1,
++ .type = V4L2_BUF_TYPE_VIDEO_OVERLAY,
++ .flags = FORMAT_FLAGS_PACKED,
++ .description = "24 bpp RGB, le",
++ .pixelformat = V4L2_PIX_FMT_RGB24,
++ },
++ {
++ .index = 2,
++ .type = V4L2_BUF_TYPE_VIDEO_OVERLAY,
++ .flags = FORMAT_FLAGS_PACKED,
++ .description = "32 bpp RGB, le",
++ .pixelformat = V4L2_PIX_FMT_BGR32,
++ },
++ {
++ .index = 3,
++ .type = V4L2_BUF_TYPE_VIDEO_OVERLAY,
++ .flags = FORMAT_FLAGS_PLANAR,
++ .description = "4:2:2, planar, Y-Cb-Cr",
++ .pixelformat = V4L2_PIX_FMT_YUV422P,
++
++ },
++ {
++ .index = 4,
++ .type = V4L2_BUF_TYPE_VIDEO_OVERLAY,
++ .flags = FORMAT_FLAGS_PLANAR,
++ .description = "4:2:0, planar, Y-Cb-Cr",
++ .pixelformat = V4L2_PIX_FMT_YUV420,
++ }
++};
++
++#define NUMBER_OF_PREVIEW_FORMATS ARRAY_SIZE(fimc_preview_formats)
++#define NUMBER_OF_CODEC_FORMATS ARRAY_SIZE(fimc_codec_formats)
++#define NUMBER_OF_INPUTS ARRAY_SIZE(fimc_inputs)
++#define NUMBER_OF_OUTPUTS ARRAY_SIZE(fimc_outputs)
++
++#endif
++
Added: developers/werner/gta03/cam/patches/add-s5k4.patch
===================================================================
--- developers/werner/gta03/cam/patches/add-s5k4.patch (rev 0)
+++ developers/werner/gta03/cam/patches/add-s5k4.patch 2009-02-26 15:51:03 UTC (rev 4938)
@@ -0,0 +1,2743 @@
+Index: cam/drivers/media/video/samsung/4xa_sensor.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ cam/drivers/media/video/samsung/4xa_sensor.c 2009-02-26 22:47:36.000000000 +0800
+@@ -0,0 +1,345 @@
++/*
++ * Copyright (C) 2004 Samsung Electronics
++ * SW.LEE <hitchcar at samsung.com>
++ * - based on Russell King : pcf8583.c
++ * - added smdk24a0, smdk2440
++ * - added poseidon (s3c24a0+wavecom)
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Driver for FIMC2.x Camera Decoder
++ *
++ */
++
++//#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/i2c-id.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++//#define CAMIF_DEBUG
++
++#include "../s3c_camif.h"
++#include "4xa_sensor.h"
++
++static struct i2c_driver sensor_driver;
++
++/* This is an abstract CIS sensor for MSDMA input. */
++
++camif_cis_t msdma_input = {
++ itu_fmt: CAMIF_ITU601,
++ order422: CAMIF_CBYCRY, /* another case: YCRYCB */
++ camclk: 44000000, /* for 20 fps: 44MHz, for 12 fps(more stable): 26MHz */
++ source_x: 800,
++ source_y: 600,
++ win_hor_ofst: 0,
++ win_ver_ofst: 0,
++ win_hor_ofst2: 0,
++ win_ver_ofst2: 0,
++ polarity_pclk: 0,
++ polarity_vsync:1,
++ polarity_href: 0,
++ reset_type:CAMIF_EX_RESET_AL,
++ reset_udelay: 5000,
++};
++
++camif_cis_t interlace_input = {
++ itu_fmt: CAMIF_ITU601,
++ order422: CAMIF_CBYCRY, /* another case: YCRYCB */
++ camclk: 44000000, /* for 20 fps: 44MHz, for 12 fps(more stable): 26MHz */
++ source_x: 800,
++ source_y: 600,
++ win_hor_ofst: 0,
++ win_ver_ofst: 0,
++ win_hor_ofst2: 0,
++ win_ver_ofst2: 0,
++ polarity_pclk: 0,
++ polarity_vsync:1,
++ polarity_href: 0,
++ reset_type:CAMIF_EX_RESET_AL,
++ reset_udelay: 5000,
++};
++
++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA)
++static camif_cis_t data = {
++ itu_fmt: CAMIF_ITU601,
++ order422: CAMIF_YCBYCR,
++ camclk: 44000000, /* for 20 fps: 44MHz, for 12 fps(more stable): 26MHz */
++ source_x: 800,
++ source_y: 600,
++ win_hor_ofst: 0,
++ win_ver_ofst: 0,
++ win_hor_ofst2: 0,
++ win_ver_ofst2: 0,
++ polarity_pclk: 0,
++ polarity_vsync:1,
++ polarity_href: 0,
++ reset_type:CAMIF_EX_RESET_AL,
++ reset_udelay: 5000,
++};
++
++s5k4xa_t s5k4ba_regs_mirror[S5K4BA_REGS];
++#else
++#error No samsung CIS moudule here !
++#endif
++
++camif_cis_t* get_initialized_cis(void)
++{
++ if (data.init_sensor == 0)
++ return NULL;
++
++ return &data;
++}
++
++#define CAM_ID 0x5a
++
++static unsigned short ignore[] = { I2C_CLIENT_END };
++static unsigned short normal_addr[] = { (CAM_ID >> 1), I2C_CLIENT_END };
++static const unsigned short *forces[] = { NULL };
++
++static struct i2c_client_address_data addr_data = {
++ .normal_i2c = normal_addr,
++ .probe = ignore,
++ .ignore = ignore,
++ .forces = forces,
++};
++
++
++unsigned char sensor_read(struct i2c_client *client, unsigned char subaddr)
++{
++ int ret;
++ unsigned char buf[1];
++ struct i2c_msg msg = { client->addr, 0, 1, buf };
++ buf[0] = subaddr;
++
++ ret = i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
++ if (ret == -EIO) {
++ printk(" I2C write Error \n");
++ return -EIO;
++ }
++
++ msg.flags = I2C_M_RD;
++ ret = i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
++
++ return buf[0];
++}
++
++static int
++sensor_write(struct i2c_client *client,
++ unsigned char subaddr, unsigned char val)
++{
++ unsigned char buf[2];
++ struct i2c_msg msg = { client->addr, 0, 2, buf };
++
++ buf[0] = subaddr;
++ buf[1] = val;
++
++ return i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
++}
++
++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA)
++void inline sensor_init(struct i2c_client *sam_client)
++{
++ int i;
++
++ i = (sizeof(s5k4ba_reg)/sizeof(s5k4ba_reg[0]));
++ for (i = 0; i < S5K4BA_INIT_REGS; i++) {
++ sensor_write(sam_client,
++ s5k4ba_reg[i].subaddr, s5k4ba_reg[i].value);
++ }
++}
++#else
++#error No samsung CIS moudule !
++#endif
++
++static int
++s5k4xa_attach(struct i2c_adapter *adap, int addr, int kind)
++{
++ struct i2c_client *c;
++
++ c = kmalloc(sizeof(*c), GFP_KERNEL);
++ if (!c)
++ return -ENOMEM;
++
++ memset(c, 0, sizeof(struct i2c_client));
++
++ strcpy(c->name, "S5K4XA");
++ c->addr = addr;
++ c->adapter = adap;
++ c->driver = &sensor_driver;
++ i2c_set_clientdata(c, &data);
++ data.sensor = c;
++
++ s3c_camif_register_sensor(c);
++
++ return i2c_attach_client(c);
++}
++
++static int sensor_attach_adapter(struct i2c_adapter *adap)
++{
++ s3c_camif_open_sensor(&data);
++ return i2c_probe(adap, &addr_data, s5k4xa_attach);
++}
++
++static int sensor_detach(struct i2c_client *client)
++{
++ i2c_detach_client(client);
++ s3c_camif_unregister_sensor(client);
++ return 0;
++}
++
++/* Purpose:
++ This fucntion only for SVGA Camera : 4BA
++*/
++static int change_sensor_size(struct i2c_client *client, int size)
++{
++ int i;
++
++ switch (size) {
++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA)
++ case SENSOR_QSVGA:
++ for (i = 0; i < S5K4BA_QSVGA_REGS; i++) {
++ sensor_write(client, s5k4ba_reg_qsvga[i].subaddr,
++ s5k4ba_reg_qsvga[i].value);
++ }
++ break;
++
++ case SENSOR_SVGA:
++ for (i = 0; i < S5K4BA_SVGA_REGS; i++) {
++ sensor_write(client, s5k4ba_reg_svga[i].subaddr,
++ s5k4ba_reg_svga[i].value);
++ }
++ break;
++#else
++#error No samsung CIS moudule !
++#endif
++ default:
++ panic("4xa_sensor.c: unexpect value \n");
++ }
++
++ return 0;
++}
++
++static int change_sensor_wb(struct i2c_client *client, int type)
++{
++ printk("[ *** Page 0, 4XA Sensor White Balance Mode ***]\n");
++
++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA)
++ sensor_write(client, 0xFC, 0x0);
++ sensor_write(client, 0x30, type);
++#endif
++
++ switch(type){
++ case 0:
++ default:
++ printk(" -> AWB auto mode ]\n");
++ break;
++ case 1:
++ printk(" -> Indoor 3100 mode ]\n");
++ break;
++ case 2:
++ printk(" -> Outdoor 5100 mode ]\n");
++ break;
++ case 3:
++ printk(" -> Indoor 2000 mode ]\n");
++ break;
++ case 4:
++ printk(" -> AE/AWB halt ]\n");
++ break;
++ case 5:
++ printk(" -> Cloudy(6000) mode ]\n");
++ break;
++ case 6:
++ printk(" -> Sunny(8000) mode ]\n");
++ break;
++ }
++
++ return 0;
++}
++
++static int
++sensor_command(struct i2c_client *client, unsigned int cmd, void *arg)
++{
++ switch (cmd) {
++ case SENSOR_INIT:
++ sensor_init(client);
++ printk(KERN_INFO "External Camera initialized\n");
++ break;
++
++ case USER_ADD:
++ break;
++
++ case USER_EXIT:
++ break;
++
++ case SENSOR_QSVGA:
++ change_sensor_size(client, SENSOR_QSVGA);
++ break;
++
++ case SENSOR_VGA:
++ change_sensor_size(client, SENSOR_VGA);
++ break;
++
++ case SENSOR_SVGA:
++ change_sensor_size(client, SENSOR_SVGA);
++ break;
++
++ case SENSOR_SXGA:
++ change_sensor_size(client, SENSOR_SXGA);
++ break;
++
++ case SENSOR_UXGA:
++ change_sensor_size(client, SENSOR_UXGA);
++ break;
++/* Todo
++ case SENSOR_BRIGHTNESS:
++ change_sensor_setting();
++ break;
++*/
++ case SENSOR_WB:
++ printk("[ *** 4XA Sensor White Balance , No mode ***]\n");
++ change_sensor_wb(client, (int) arg);
++ break;
++
++ default:
++ panic("4xa_sensor.c : Unexpect Sensor Command \n");
++ break;
++ }
++
++ return 0;
++}
++
++static struct i2c_driver sensor_driver = {
++ .driver = {
++ .name = "s5k4xa",
++ },
++ .id = I2C_DRIVERID_S5K_4XA,
++ .attach_adapter = sensor_attach_adapter,
++ .detach_client = sensor_detach,
++ .command = sensor_command
++};
++
++static __init int camif_sensor_init(void)
++{
++ return i2c_add_driver(&sensor_driver);
++}
++
++
++static __init void camif_sensor_exit(void)
++{
++ i2c_del_driver(&sensor_driver);
++}
++
++module_init(camif_sensor_init)
++module_exit(camif_sensor_exit)
++
++MODULE_AUTHOR("Jinsung, Yang <jsgood.yang at samsung.com>");
++MODULE_DESCRIPTION("I2C Client Driver For FIMC V4L2 Driver");
++MODULE_LICENSE("GPL");
+Index: cam/drivers/media/video/samsung/4xa_sensor.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ cam/drivers/media/video/samsung/4xa_sensor.h 2009-02-26 22:35:31.000000000 +0800
+@@ -0,0 +1,2376 @@
++
++#ifndef _SAMSUNG_SXGA_H_
++#define _SAMSUNG_SXGA_H_
++
++/*******************************************************************************************
++ # Display resolution standards #
++
++ QCIF: 176 x 144
++ CIF: 352 x 288
++ QVGA: 320 x 240
++ VGA: 640 x 480
++ SVGA: 800 x 600
++ XGA: 1024 x 768
++ WXGA: 1280 x 800
++ QVGA: 1280 x 960
++ SXGA: 1280 x 1024
++ SXGA+: 1400 x 1050
++ WSXGA+: 1680 x 1050
++ UXGA: 1600 x 1200
++ WUXGA: 1920 x 1200
++ QXGA: 2048 x 1536
++********************************************************************************************/
++
++//#include "../bits.h"
++
++/* Camera information
++ * FPC Label : Samsung MEGA Pixel Camera : V4220 REV06
++ * Modified by charles -Initial function of '3AA' test routine
++ * Modified and tested by YongHwui.Kim <yonghwui.kim at samsung.com> for S5K3AAEX Camera
++ */
++
++#define CHIP_DELAY 0xFF
++
++typedef struct samsung_t{
++ unsigned char subaddr;
++ unsigned char value;
++ unsigned char page;
++} s5k4xa_t;
++
++#ifdef CONFIG_CPU_S3C24A0A
++#define TRY_HIGH_CLOCK 1
++#endif
++
++ //***************************************************
++ // name: S5K3AAEX EVT2 setfile
++ // ver: v2.61
++ // history:
++ // v0.0 start from 040908 setfile
++ // v1.0 arange register
++ // v1.01 change MCLK(25Mhz) and Frame rate(7fps)
++ // v2.0 adjust register setting for 3AA EVT2
++ // - color correction, RGB shding off, hsync start position, Mirror, fps
++ // - Color Tuning, YGRPDLY
++ // v2.1 change Frame rate(7.5fps) and Total gain to x4
++ // (because of reducing visual noise at low illumination)
++ // - change BPRM AGC Max and FrameAE start
++ // improve AE speed
++ // v2.2 modify AWB G gain and solve 50hz flicker detection fail in 25MHz 7.5fps
++ // v2.3 Adjust gamma, Dark Slice, white point, Hue gain,
++ // White Balance B control, Y gain On, Digital Clamp On
++ // lower AWB G gain
++ // v2.4 Adjust AE window weight, Y Gamma, WhitePoint, Shading and BPR Max Thres.
++ // v2.41 Adjust AE/AWB window and AWB internal window boundary to decrease skin color tracking
++ // v2.411 special version for PSCDS
++ // v2.412 RGB shading off
++ // v2.5 Lens change STW to Sekonix
++ // adjust White point and Y shading Coef (RGB shading off)
++ // v2.6 New Tuning because of Full YC off and YCbCr Coef change
++ // Gamma, Dark Slice, color matrix (not use), Color suppress
++ // R Gain and DBPR agc MIN/MAX
++ // v2.61 VCK inversion(data rising)
++ //***************************************************
++ ///////////////////////////////////////////////////
++
++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA)
++
++// For SVGA (800 x 600)
++#if 1 // from han
++s5k4xa_t s5k4ba_reg[] =
++{
++ {0xfc,0x07},
++ {0x66,0x01}, // Watch Dog Time On
++ {0xfc,0x00},
++ {0x00,0xAA}, // For EDS Check
++ {0x21,0x03}, // peter0223 Ãß°¡
++ {0xfc,0x01},
++ {0x04,0x01}, // ARM Clock Divider
++
++ {0xfc,0x02},
++ {0x30,0x90}, // Analog offset
++ {0x37,0x0d}, // Global Gain
++ {0x2d,0x48}, // Double Shutter
++ {0x60,0x00}, // Blank_Adrs
++
++ {0x45,0x1e}, //0e// CDS Timing for Average Sub_Sampling
++ {0x47,0x2f},
++ {0x02,0x0e}, // ADC Resolution
++ {0x3d,0x06}, // Frame ADLC
++ {0x4d,0x08}, // Doubler Volatage
++ {0x54,0x02}, // Double Shutter
++ {0x55,0x1e}, // Line ADLC
++ {0x56,0x30}, //
++ {0x59,0x00}, // LineADLC offset
++ {0x5b,0x08}, // R_Ref_Ctrl
++ {0x44,0x63}, // CLP_EN
++ {0x4A,0x10}, // Clamp Control
++ {0x42,0x02}, //
++ {0x43,0xef}, //
++
++ //==========================================================
++ // Table Set for Sub-Sampling
++ //==========================================================
++ {0xfc,0x03},
++ {0x2c,0x00}, // crcb_sel for Sub-Sampling Table
++ {0x05,0x46}, // Output Image Size Set for Capture
++ {0x07,0xb6},
++ {0x0e,0x04},
++ {0x12,0x03},
++
++ {0xfc,0x04},
++ {0x32,0x04},
++ {0x33,0xbc},
++
++ {0xfc,0x04},
++ {0xc5,0x26}, // Output Image Size Set for Preview
++ {0xc7,0x5e},
++ {0xce,0x04},
++ {0xd2,0x04},
++
++ {0xec,0x06}, //CrCb sel = YCBYCR(0x06) by jsgood
++ {0xc0,0x06},
++ {0xc1,0x70},
++ {0xc2,0x02},
++ {0xc3,0x87},
++
++ {0xfc,0x07},
++ {0x05,0x00},
++ {0x06,0x00},
++ {0x07,0x8b},
++ {0x08,0xf5},
++ {0x09,0x00},
++ {0x0a,0xb4},
++ {0x0b,0x00},
++ {0x0c,0xea},
++ {0x0d,0x00},
++ {0x0e,0x40},
++
++ {0xfc,0x00},
++ {0x70,0x02},
++
++ // Jeongyun added still shot cbcr_sel
++ {0xfc,0x03},
++ {0x2c,0x00},
++ {0x5c,0x00},
++ {0x8c,0x00},
++ {0xbc,0x00},
++ {0xfc,0x04},
++ {0x5c,0x00},
++
++
++ //==========================================================
++ // COMMAND SET
++ //==========================================================
++ {0xfc,0x00},
++ {0x73,0x21}, // Frmae AE Enable peter
++ {0x20,0x02}, // Change AWB Mode
++
++ {0xfc,0x00},
++ {0x6c,0xb0}, // AE target
++ {0x6d,0x00},
++
++ {0xfc,0x20},
++ {0x16,0x5a}, // for Prevating AE Hunting
++
++ {0xfc,0x00},
++ {0x78,0x6a}, // AGC Max
++ {0xfc,0x20},
++ {0x16,0x60}, // Frame AE Start
++
++ {0xfc,0x20},
++ {0x57,0x18}, // Stable_Frame_AE
++ {0x2C,0x30}, // For Forbidden Area
++ {0x2E,0x00}, // For Forbidden Area
++ {0x14,0x70},
++ {0x01,0x00}, // Stepless_Off
++
++ {0xfc,0x07},
++ {0x11,0x02}, // AWB G Gain offset
++
++ {0xfc,0x07},
++ {0x3e,0x0a}, // AWB Cut R max
++
++ {0xfc,0x01},
++ {0xc8,0xd0}, // AWB Y Max e0 Y°ªÀÌ ¾î´À ÀÌ»óÀ϶§ ±× ÀÌ»ó°ªÀ» ©¶ó³»´Â ¼¼Æðª
++ {0xfc,0x00},
++ {0x3e,0x20}, //30 AWB Y_min
++ {0x3d,0x10}, // AWB Y_min Low
++ {0xfc,0x22},
++ {0x8c,0x04}, // AWB Min Y Weight AWB ÇÒ¶§ Y½ÅÈ£¸¦ ±âÁØÀ¸·Î Çϴµ¥ °¡ÁßÄ¡¸¦ ¹Ù²Ù´Â °Í.
++ {0x8d,0x16}, // AWB Max Y Weight
++
++ {0xfc,0x00},
++ {0x32,0x04}, // AWB moving average 8 frame
++ {0x81,0x10}, // AWB G gain suppress Disable
++ {0xbc,0xf0},
++
++ {0x29,0x04}, // Y level H
++ {0x2a,0x00}, // Y level L
++ {0x2b,0x03}, // color level H
++ {0x2c,0xc8}, // color level L
++
++ {0xfc,0x07},
++ {0x37,0x00}, // Flicker Add for 32Mhz
++ {0xfc,0x00},
++ {0x72,0xa0}, // Flicker for 32MHz
++ {0x74,0x08}, // flicker 60Hz Fix
++
++ {0xfc,0x20},
++ {0x02,0x02}, // Flicker Dgain Mode
++
++ {0xfc,0x00},
++ //{0x23,0x40}, // Mirror Option
++ {0x62,0x0a}, // Mirror Option
++
++ {0xfc,0x02},
++ {0x4e,0x00}, // IO current 8mA set
++ {0x4e,0x00}, // IO current 8mA set
++ {0x4e,0x00}, // IO current 8mA set
++ {0x4e,0x00}, // IO current 8mA set
++ {0x4f,0x0a}, // 2a IO current 48mA set
++ {0x4f,0x0a}, // IO current 48mA set
++ {0x4f,0x0a}, // IO current 48mA set
++ {0x4f,0x0a}, // IO current 48mA set
++
++ {0xfc,0x01},
++ {0x0c,0x03}, // Full YC Enable
++ //{0x0c,03}, // Full YC Enable
++ //{0x02,02}, // crcb_sel
++ //{0x02,02}, // crcb_sel peter0222 Ãß°¡
++ //{0x01,01}, // pclk peter0222 Ãß°¡
++ //{0x01,01},
++
++ //==========================================================
++ // COLOR MATRIX
++ //==========================================================
++ {0xfc,0x01}, // color matrix
++ {0x51,0x0A},
++ {0x52,0x42},
++ {0x53,0xF9},
++ {0x54,0x80},
++ {0x55,0x00},
++ {0x56,0x3D},
++
++ {0x57,0xFE},
++ {0x58,0x0B},
++ {0x59,0x06},
++ {0x5A,0x9C},
++ {0x5B,0xFF},
++ {0x5C,0x59},
++
++ {0x5D,0xFF},
++ {0x5E,0xD8},
++ {0x5F,0xFC},
++ {0x60,0x2E},
++ {0x61,0x07},
++ {0x62,0xFA},
++
++ //==========================================================
++ // EDGE ENHANCEMENT
++ //==========================================================
++ {0xfc,0x00},
++ {0x89,0x03}, // Edge Suppress On
++ {0xfc,0x0b},
++ {0x42,0x50}, // Edge AGC MIN
++ {0x43,0x60}, // Edge AGC MAX
++ {0x45,0x18}, // positive gain AGC MIN
++ {0x49,0x0a}, // positive gain AGC MAX
++ {0x4d,0x18}, // negative gain AGC MIN
++ {0x51,0x0a}, // negative gain AGC MAX
++
++ {0xfc,0x05},
++ {0x34,0x20}, // APTCLP
++ {0x35,0x09}, // APTSC
++ {0x36,0x0b}, // ENHANCE
++ {0x3f,0x00}, // NON-LIN
++ {0x42,0x10}, // EGFALL
++ {0x43,0x00}, // HLFALL
++ {0x45,0xa0}, // EGREF
++ {0x46,0x7a}, // HLREF
++ {0x47,0x40}, // LLREF
++ {0x48,0x0c},
++ {0x49,0x31}, // CSSEL EGSEL CS_DLY
++
++ {0x40,0x41}, // Y delay
++
++ //==========================================================
++ // GAMMA
++ //========================================================== -
++ {0xfc,0x01},
++
++ {0x6F,0x0A}, // R
++ {0x70,0x1A},
++ {0x71,0x7A},
++ {0x72,0xF8},
++ {0x73,0x00},
++
++ {0x74,0xA0},
++ {0x75,0x18},
++ {0x76,0x65},
++ {0x77,0xAD},
++ {0x78,0x6A},
++
++ {0x79,0xE2},
++ {0x7A,0x12},
++ {0x7B,0x3D},
++ {0x7C,0x5A},
++ {0x7D,0xBF},
++
++ {0x7E,0x72},
++ {0x7F,0x88},
++ {0x80,0x9D},
++ {0x81,0xB0},
++ {0x82,0xFF},
++
++ {0x83,0xC0},
++ {0x84,0xCF},
++ {0x85,0xDA},
++ {0x86,0xFC},
++
++ {0x87,0x08}, //G
++ {0x88,0x12},
++ {0x89,0x42},
++ {0x8A,0xBA},
++ {0x8B,0x00},
++
++ {0x8C,0x75},
++ {0x8D,0xED},
++ {0x8E,0x42},
++ {0x8F,0x80},
++ {0x90,0x5A},
++
++ {0x91,0xB5},
++ {0x92,0xE5},
++ {0x93,0x10},
++ {0x94,0x35},
++ {0x95,0xAF},
++
++ {0x96,0x55},
++ {0x97,0x70},
++ {0x98,0x88},
++ {0x99,0x9D},
++ {0x9A,0xFF},
++
++ {0x9B,0xB1},
++ {0x9C,0xC4},
++ {0x9D,0xD5},
++ {0x9E,0xFC},
++
++ {0x9F,0x05}, //B
++ {0xA0,0x18},
++ {0xA1,0x42},
++ {0xA2,0xd7},
++ {0xA3,0x00},
++
++ {0xA4,0xB6},
++ {0xA5,0x3b},
++ {0xA6,0x88},
++ {0xA7,0xC8},
++ {0xA8,0x6A},
++
++ {0xA9,0x00},
++ {0xAA,0x30},
++ {0xAB,0x58},
++ {0xAC,0x78},
++ {0xAD,0xFF},
++
++ {0xAE,0x90},
++ {0xAF,0xA5},
++ {0xB0,0xB6},
++ {0xB1,0xC5},
++ {0xB2,0xFF},
++
++ {0xB3,0xD0},
++ {0xB4,0xD6},
++ {0xB5,0xDA},
++ {0xB6,0xFC},
++
++ //==========================================================
++ // HUE CONTROL
++ //==========================================================
++ {0xfc,0x00},
++ {0x48,0x34}, // 2000K
++ {0x49,0x34},
++ {0x4a,0xf4},
++ {0x4b,0x00},
++ {0x4c,0x44},
++ {0x4d,0x3c},
++ {0x4e,0xf0},
++ {0x4f,0x0c},
++
++ {0x50,0x34}, // 3000K
++ {0x51,0x34},
++ {0x52,0xf4},
++ {0x53,0x00},
++ {0x54,0x44},
++ {0x55,0x3c},
++ {0x56,0xf0},
++ {0x57,0x0c},
++
++ {0x58,0x34}, // 5100K
++ {0x59,0x30},
++ {0x5a,0x00},
++ {0x5b,0x04},
++ {0x5c,0x40},
++ {0x5d,0x2c},
++ {0x5e,0xfc},
++ {0x5f,0x04},
++ //==========================================================
++ // UPPRE0x0x FUNCTION
++ //==========================================================
++ {0xfc,0x00},
++ {0x7e,0xf4},
++
++ //==========================================================
++ // BPR
++ //==========================================================
++ {0xfc,0x01},
++ {0x3d,0x10},
++
++ {0xfc,0x0b},
++ {0x0b,0x00}, // ISP BPR On start
++ {0x0c,0x20}, // Th13 AGC Min
++ {0x0d,0x40}, // Th13 AGC Max
++ {0x0e,0x00}, // Th1 Max H for AGCMIN
++ {0x0f,0x20}, // Th1 Max L for AGCMIN
++ {0x10,0x00}, // Th1 Min H for AGCMAX
++ {0x11,0x10}, // Th1 Min L for AGCMAX
++ {0x12,0x00}, // Th3 Max H for AGCMIN
++ {0x13,0x00}, // Th3 Max L for AGCMIN
++ {0x14,0xff}, // Th3 Min H for AGCMAX
++ {0x15,0xff}, // Th3 Min L for AGCMAX
++ {0x16,0x20}, // Th57 AGC Min
++ {0x17,0x40}, // Th57 AGC Max
++ {0x18,0x00}, // Th5 Max H for AGCMIN
++ {0x19,0x00}, // Th5 Max L for AGCMIN
++ {0x1a,0x00}, // Th5 Min H for AGCMAX
++ {0x1b,0x20}, // Th5 Min L for AGCMAX
++ {0x1c,0x00}, // Th7 Max H for AGCMIN
++ {0x1d,0x00}, // Th7 Max L for AGCMIN
++ {0x1e,0x00}, // Th7 Min H for AGCMAX
++ {0x1f,0x20}, // Th7 Min L for AGCMAX
++
++ //==========================================================
++ // GR/GB CORRECTION
++ //==========================================================
++ {0xfc,0x01},
++ {0x45,0x0c},
++
++ {0xfc,0x0b},
++ {0x21,0x00}, // start AGC
++ {0x22,0x18}, // AGCMIN
++ {0x23,0x58}, // AGCMAX
++ {0x24,0x0d}, // G Th AGCMIN
++ {0x25,0x30}, // G Th AGCMAX
++ {0x26,0x0d}, // RB Th AGCMIN
++ {0x27,0x30}, // RB Th AGCMAX
++
++ //==========================================================
++ // NR
++ //==========================================================
++ {0xfc,0x01},
++ {0x4C,0x01}, // NR Enable
++ {0x49,0x15}, // Sig_Th Mult
++ {0x4B,0x0A}, // Pre_Th Mult
++
++ {0xfc,0x0b},
++ {0x28,0x00}, // NR start AGC
++ {0x29,0x00}, // SIG Th AGCMIN H
++ {0x2a,0x14}, // SIG Th AGCMIN L
++ {0x2b,0x00}, // SIG Th AGCMAX H
++ {0x2c,0x14}, // SIG Th AGCMAX L
++ {0x2d,0x00}, // PRE Th AGCMIN H
++ {0x2e,0x90}, // PRE Th AGCMIN L
++ {0x2f,0x01}, // PRE Th AGCMAX H
++ {0x30,0x00}, // PRE Th AGCMAX L
++ {0x31,0x00}, // POST Th AGCMIN H
++ {0x32,0xa0}, // POST Th AGCMIN L
++ {0x33,0x01}, // POST Th AGCMAX H
++ {0x34,0x10}, // POST Th AGCMAX L
++
++ //==========================================================
++ // 1D-Y/C-SIGMA-LPF
++ //==========================================================
++ {0xfc,0x01},
++ {0x05,0xc0},
++
++ {0xfc,0x0b},
++ {0x35,0x00}, // YLPF start AGC
++ {0x36,0x40}, // YLPF01 AGCMIN
++ {0x37,0x60}, // YLPF01 AGCMAX
++ {0x38,0x00}, // YLPF SIG01 Th AGCMINH
++ {0x39,0x18}, // YLPF SIG01 Th AGCMINL
++ {0x3a,0x00}, // YLPF SIG01 Th AGCMAXH
++ {0x3b,0x40}, // YLPF SIG01 Th AGCMAXH
++ {0x3c,0x50}, // YLPF02 AGCMIN
++ {0x3d,0x60}, // YLPF02 AGCMAX
++ {0x3e,0x00}, // YLPF SIG02 Th AGCMINH
++ {0x3f,0x30}, // YLPF SIG02 Th AGCMINL
++ {0x40,0x00}, // YLPF SIG02 Th AGCMAXH
++ {0x41,0x40}, // YLPF SIG02 Th AGCMAXH
++ {0xd4,0x40}, // CLPF AGCMIN
++ {0xd5,0x60}, // CLPF AGCMAX
++ {0xd6,0xb0}, // CLPF SIG01 Th AGCMIN
++ {0xd7,0xf0}, // CLPF SIG01 Th AGCMAX
++ {0xd8,0xb0}, // CLPF SIG02 Th AGCMIN
++ {0xd9,0xf0}, // CLPF SIG02 Th AGCMAX
++
++ //==========================================================
++ // COLOR SUPPRESS
++ //==========================================================
++ {0xfc,0x0b},
++ {0x08,0x58}, // Color suppress AGC MIN
++ {0x09,0x03}, // Color suppress MIN H
++ {0x0a,0x80}, // Color suppress MIN L
++
++ //==========================================================
++ // SHADING
++ //==========================================================
++ {0xfc,0x09},
++ //Shading file for 3BAFX
++ //s90000// shading off
++ // DSP9_SH_WIDTH_H
++ {0x01,0x06},
++ {0x02,0x40},
++ // DSP9_SH_HEIGHT_H
++ {0x03,0x04},
++ {0x04,0xB0},
++ // DSP9_SH_XCH_R
++ {0x05,0x03},
++ {0x06,0x1A},
++ {0x07,0x02},
++ {0x08,0x4E},
++ // DSP9_SH_XCH_G
++ {0x09,0x03},
++ {0x0A,0x27},
++ {0x0B,0x02},
++ {0x0C,0x11},
++ // DSP9_SH_XCH_B
++ {0x0D,0x03},
++ {0x0E,0x15},
++ {0x0F,0x01},
++ {0x10,0xE3},
++ // DSP9_SH_Del_eH_R
++ {0x1D,0x85},
++ {0x1E,0x55},
++ {0x1F,0x77},
++ {0x20,0x9E},
++ {0x23,0x7F},
++ {0x24,0xE6},
++ {0x21,0x7F},
++ {0x22,0xE6},
++ // DSP9_SH_Del_eH_G
++ {0x25,0x82},
++ {0x26,0x9A},
++ {0x27,0x78},
++ {0x28,0xC0},
++ {0x2B,0x76},
++ {0x2C,0x07},
++ {0x29,0x86},
++ {0x2A,0x09},
++ // DSP9_SH_Del_eH_B
++ {0x2D,0x85},
++ {0x2E,0x55},
++ {0x2F,0x75},
++ {0x30,0x6D},
++ {0x33,0x74},
++ {0x34,0xA2},
++ {0x31,0x84},
++ {0x32,0xA2},
++ // DSP9_SH_VAL_R0H
++ {0x35,0x01},
++ {0x36,0x01},
++ {0x37,0x01},
++ {0x38,0x14},
++ {0x39,0x01},
++ {0x3A,0x45},
++ {0x3B,0x01},
++ {0x3C,0x8A},
++ {0x3D,0x01},
++ {0x3E,0xA3},
++ {0x3F,0x01},
++ {0x40,0xB9},
++ {0x41,0x01},
++ {0x42,0xD9},
++ {0x43,0x01},
++ {0x44,0xF6},
++ // DSP9_SH_VAL_G0H
++ {0x45,0x01},
++ {0x46,0x00},
++ {0x47,0x01},
++ {0x48,0x0E},
++ {0x49,0x01},
++ {0x4A,0x34},
++ {0x4B,0x01},
++ {0x4C,0x68},
++ {0x4D,0x01},
++ {0x4E,0x76},
++ {0x4F,0x01},
++ {0x50,0x94},
++ {0x51,0x01},
++ {0x52,0xAB},
++ {0x53,0x01},
++ {0x54,0xC3},
++ // DSP9_SH_VAL_B0H
++ {0x55,0x01},
++ {0x56,0x00},
++ {0x57,0x01},
++ {0x58,0x0C},
++ {0x59,0x01},
++ {0x5A,0x2B},
++ {0x5B,0x01},
++ {0x5C,0x5D},
++ {0x5D,0x01},
++ {0x5E,0x70},
++ {0x5F,0x01},
++ {0x60,0x8A},
++ {0x61,0x01},
++ {0x62,0xA1},
++ {0x63,0x01},
++ {0x64,0xB3},
++ // DSP9_SH_M_R2_R1H
++ {0x65,0x00},
++ {0x66,0x98},
++ {0x67,0x2C},
++ {0x68,0x02},
++ {0x69,0x60},
++ {0x6A,0xB0},
++ {0x6B,0x05},
++ {0x6C,0x59},
++ {0x6D,0x8C},
++ {0x6E,0x07},
++ {0x6F,0x48},
++ {0x70,0x1B},
++ {0x71,0x09},
++ {0x72,0x82},
++ {0x73,0xC0},
++ {0x74,0x0C},
++ {0x75,0x09},
++ {0x76,0x7B},
++ {0x77,0x0E},
++ {0x78,0xDC},
++ {0x79,0x4D},
++ // DSP9_SH_M_R2_G1H
++ {0x7A,0x00},
++ {0x7B,0xAD},
++ {0x7C,0x76},
++ {0x7D,0x02},
++ {0x7E,0xB5},
++ {0x7F,0xD7},
++ {0x80,0x06},
++ {0x81,0x19},
++ {0x82,0x23},
++ {0x83,0x08},
++ {0x84,0x4C},
++ {0x85,0xE2},
++ {0x86,0x0A},
++ {0x87,0xD7},
++ {0x88,0x5C},
++ {0x89,0x0D},
++ {0x8A,0xB8},
++ {0x8B,0x90},
++ {0x8C,0x10},
++ {0x8D,0xF0},
++ {0x8E,0x7F},
++ // DSP9_SH_M_R2_B1H
++ {0x8F,0x00},
++ {0x90,0xC1},
++ {0x91,0xD0},
++ {0x92,0x03},
++ {0x93,0x07},
++ {0x94,0x3F},
++ {0x95,0x06},
++ {0x96,0xD0},
++ {0x97,0x4F},
++ {0x98,0x09},
++ {0x99,0x46},
++ {0x9A,0x32},
++ {0x9B,0x0C},
++ {0x9C,0x1C},
++ {0x9D,0xFE},
++ {0x9E,0x0F},
++ {0x9F,0x54},
++ {0xA0,0xB1},
++ {0xA1,0x12},
++ {0xA2,0xED},
++ {0xA3,0x4C},
++ // DSP9_SH_SUB_RR0H
++ {0xA4,0x6B},
++ {0xA5,0xAA},
++ {0xA6,0x23},
++ {0xA7,0xE3},
++ {0xA8,0x15},
++ {0xA9,0x88},
++ {0xAA,0x21},
++ {0xAB,0x20},
++ {0xAC,0x1C},
++ {0xAD,0xB6},
++ {0xAE,0x19},
++ {0xAF,0x55},
++ {0xB0,0x16},
++ {0xB1,0xAA},
++ // DSP9_SH_SUB_RG0H
++ {0xB2,0x5E},
++ {0xB3,0x74},
++ {0xB4,0x1F},
++ {0xB5,0x7C},
++ {0xB6,0x12},
++ {0xB7,0xE4},
++ {0xB8,0x1D},
++ {0xB9,0x10},
++ {0xBA,0x19},
++ {0xBB,0x30},
++ {0xBC,0x16},
++ {0xBD,0x39},
++ {0xBE,0x13},
++ {0xBF,0xE2},
++ // DSP9_SH_SUB_RB0H
++ {0xC0,0x54},
++ {0xC1,0x89},
++ {0xC2,0x1C},
++ {0xC3,0x2D},
++ {0xC4,0x10},
++ {0xC5,0xE8},
++ {0xC6,0x1A},
++ {0xC7,0x02},
++ {0xC8,0x16},
++ {0xC9,0x8A},
++ {0xCA,0x13},
++ {0xCB,0xE4},
++ {0xCC,0x11},
++ {0xCD,0xCC},
++
++ {0x00,0x02}, // {0xhading on
++
++ //==========================================================
++ // X-SHADING
++ //==========================================================
++ {0xfc,0x1B},
++ {0x80,0x01},
++ {0x81,0x00},
++ {0x82,0x4C},
++ {0x83,0x00},
++ {0x84,0x86},
++ {0x85,0x03},
++ {0x86,0x5E},
++ {0x87,0x00},
++ {0x88,0x07},
++ {0x89,0xA4},
++ {0x90,0x00},
++ {0x91,0x12},
++ {0x92,0x00},
++ {0x93,0x12},
++ {0x94,0x00},
++ {0x95,0x12},
++ {0x96,0x00},
++ {0x97,0x12},
++ {0x98,0x00},
++ {0x99,0x12},
++ {0x9A,0x00},
++ {0x9B,0x12},
++ {0x9C,0x00},
++ {0x9D,0x12},
++ {0x9E,0x00},
++ {0x9F,0x12},
++ {0xA0,0x00},
++ {0xA1,0x12},
++ {0xA2,0x00},
++ {0xA3,0x12},
++ {0xA4,0x00},
++ {0xA5,0x12},
++ {0xA6,0x00},
++ {0xA7,0x12},
++ {0xA8,0x00},
++ {0xA9,0x12},
++ {0xAA,0x00},
++ {0xAB,0x12},
++ {0xAC,0x00},
++ {0xAD,0x12},
++ {0xAE,0x00},
++ {0xAF,0x12},
++ {0xB0,0x00},
++ {0xB1,0x12},
++ {0xB2,0x00},
++ {0xB3,0x12},
++ {0xB4,0x00},
++ {0xB5,0x12},
++ {0xB6,0x00},
++ {0xB7,0x15},
++ {0xB8,0x00},
++ {0xB9,0x12},
++ {0xBA,0x00},
++ {0xBB,0x12},
++ {0xBC,0x00},
++ {0xBD,0x12},
++ {0xBE,0x00},
++ {0xBF,0x12},
++ {0xC0,0x00},
++ {0xC1,0x12},
++ {0xC2,0x00},
++ {0xC3,0x12},
++ {0xC4,0x00},
++ {0xC5,0x12},
++ {0xC6,0x00},
++ {0xC7,0x12},
++ {0xC8,0x00},
++ {0xC9,0x12},
++ {0xCA,0x00},
++ {0xCB,0x12},
++ {0xCC,0x00},
++ {0xCD,0x12},
++ {0xCE,0x00},
++ {0xCF,0x12},
++ {0xD0,0x00},
++ {0xD1,0x12},
++ {0xD2,0x00},
++ {0xD3,0x12},
++ {0xD4,0x00},
++ {0xD5,0x12},
++ // x-shading temp. correlation factor
++ {0xfc,0x0b},
++ {0xda,0x00}, // t0(3100K)
++ {0xdb,0xac},
++ {0xdc,0x01}, // tc(5100K)
++ {0xdd,0x30}, // default eeh
++
++ {0xfc,0x00},
++ {0x81,0x10}, // xshading tem
++
++ {0xfc,0x1b},
++ {0x80,0x01}, // X-Shading On
++
++ //==========================================================
++ // AE WINDOW WEIGHT
++ //==========================================================
++ {0xfc,0x00},
++ {0x03,0x4b}, // AE Suppress On
++
++ {0xfc,0x06},
++ {0x01,0x35}, // UXGA AE Window
++ {0x03,0xc2},
++ {0x05,0x48},
++ {0x07,0xb8},
++ {0x31,0x2a}, // Subsampling AE Window
++ {0x33,0x61},
++ {0x35,0x28},
++ {0x37,0x5c},
++ {0x39,0x28},
++ {0x3B,0x5A},
++ {0x3D,0x10}, // 1c
++ {0x3F,0x44},
++
++ {0xfc,0x20},
++ {0x60,0x11},
++ {0x61,0x11},
++ {0x62,0x11},
++ {0x63,0x11},
++ {0x64,0x11},
++ {0x65,0x22},
++ {0x66,0x22},
++ {0x67,0x11},
++ {0x68,0x11},
++ {0x69,0x33},
++ {0x6a,0x33},
++ {0x6b,0x11},
++ {0x6c,0x12},
++ {0x6d,0x55},
++ {0x6e,0x55},
++ {0x6f,0x21},
++ {0x70,0x13},
++ {0x71,0x55},
++ {0x72,0x55},
++ {0x73,0x31},
++ {0x74,0x33},
++ {0x75,0x33},
++ {0x76,0x33},
++ {0x77,0x33},
++
++ //==========================================================
++ // SAIT AWB
++ //==========================================================
++ //=================================
++ // White Point
++ //=================================
++ {0xfc,0x22}, // White Point (For Hue Control & MWB)
++ {0x01,0xD0}, // D65
++ {0x03,0x9B},
++ {0x05,0xC0}, // 5000K
++ {0x07,0xB8},
++ {0x09,0xA7}, // CWF
++ {0x0b,0xDC},
++ {0x0d,0x98}, // 3000K
++ {0x0f,0xE0},
++ {0x11,0x85}, // A
++ {0x12,0x00},
++ {0x13,0xF6},
++ {0x15,0x80}, // 2000K
++ {0x16,0x01},
++ {0x17,0x00},
++
++ //=================================
++ // Basic Setting
++ //=================================
++ {0xfc,0x22},
++ {0xA0,0x01},
++ {0xA1,0x3F},
++ {0xA2,0x0E},
++ {0xA3,0x65},
++ {0xA4,0x07},
++ {0xA5,0xF4},
++ {0xA6,0x11},
++ {0xA7,0xC8},
++ {0xA9,0x02},
++ {0xAA,0x43},
++ {0xAB,0x26},
++ {0xAC,0x1F},
++ {0xAD,0x02},
++ {0xAE,0x2C},
++ {0xAF,0x19},
++ {0xB0,0x0F},
++
++ {0x94,0x3C},
++ {0x95,0xCC},
++ {0x96,0x5C},
++ {0x97,0x4D},
++ {0xD0,0xA8},
++ {0xD1,0x29},
++ {0xD2,0x39},
++ {0xD3,0x22},
++ {0xD4,0x30},
++ {0xDB,0x29},
++ {0xDC,0x7E},
++ {0xDD,0x22},
++
++ {0xE7,0x00},
++ {0xE8,0xca},
++ {0xE9,0x00},
++ {0xEA,0x62},
++ {0xEB,0x00},
++ {0xEC,0x00},
++ {0xEE,0x97},
++
++ //=================================
++ // Pixel Filter Setting
++ //=================================
++ {0xFC,0x07},
++ {0x95,0x8F},
++
++ {0xfc,0x01},
++ {0xD3,0x4B},
++ {0xD4,0x00},
++ {0xD5,0x38},
++ {0xD6,0x00},
++ {0xD7,0x60},
++ {0xD8,0x00},
++ {0xD9,0x4E},
++ {0xDA,0x00},
++ {0xDB,0x27},
++ {0xDC,0x15},
++ {0xDD,0x23},
++ {0xDE,0xAD},
++ {0xDF,0x24},
++ {0xE0,0x01},
++ {0xE1,0x17},
++ {0xE2,0x4A},
++ {0xE3,0x36},
++ {0xE4,0x40},
++ {0xE5,0x40},
++ {0xE6,0x40},
++ {0xE7,0x40},
++ {0xE8,0x30},
++ {0xE9,0x3D},
++ {0xEA,0x17},
++ {0xEB,0x01},
++
++ //=================================
++ // Polygon AWB Region Tune
++ //=================================
++ {0xfc,0x22},
++ {0x18,0x00}, // 1
++ {0x19,0x5a},
++ {0x1a,0xf8},
++ {0x1b,0x00}, // 2
++ {0x1c,0x59},
++ {0x1d,0xCC},
++ {0x1e,0x00}, // 3
++ {0x1f,0x74},
++ {0x20,0xB3},
++ {0x21,0x00}, // 4
++ {0x22,0x86},
++ {0x23,0xA2},
++ {0x24,0x00}, // 5
++ {0x25,0x94},
++ {0x26,0x89},
++ {0x27,0x00}, // 6
++ {0x28,0xA6},
++ {0x29,0x76},
++ {0x2A,0x00}, // 7
++ {0x2B,0xd0},
++ {0x2C,0x5e},
++ {0x2D,0x00}, // 8
++ {0x2E,0xfa},
++ {0x2F,0x47},
++ {0x30,0x00}, // 9
++ {0x31,0xfD},
++ {0x32,0x5D},
++ {0x33,0x00}, // 10
++ {0x34,0xBB},
++ {0x35,0x7c},
++ {0x36,0x00}, // 11
++ {0x37,0xAD},
++ {0x38,0x88},
++ {0x39,0x00}, // 12
++ {0x3A,0x9A},
++ {0x3B,0xA3},
++ {0x3C,0x00}, // 13
++ {0x3D,0x7C},
++ {0x3E,0xDD},
++ {0x3F,0x00}, // 14
++ {0x40,0x00},
++ {0x41,0x00},
++
++ //=================================
++ // Moving Equation Weight
++ //=================================
++ {0xfc,0x22},
++ {0x98,0x07},
++
++ //=================================
++ // EIT Threshold
++ //=================================
++ {0xfc,0x22},
++ {0xb1,0x00}, // {0xunny
++ {0xb2,0x03},
++ {0xb3,0x00},
++ {0xb4,0xc1},
++
++ {0xb5,0x00}, // Cloudy
++ {0xb6,0x05},
++ {0xb7,0xc9},
++ {0xb9,0x81},
++
++ {0xd7,0x00}, // Shade
++ {0xd8,0x35},
++ {0xd9,0x20},
++ {0xda,0x81},
++
++ //=================================
++ // Gain Offset
++ //=================================
++ {0xfc,0x00},
++ {0x79,0xF9},
++ {0x7A,0x02}, // Global AWB gain off{0xet
++
++ {0xfc,0x22},
++ {0x58,0xf6}, // D65 R Off{0xet
++ {0x59,0xff}, // D65 B Off{0xet
++ {0x5A,0xfa}, // 5000K R Off{0xet
++ {0x5B,0xFe}, // 5000K B Off{0xet
++ {0x5C,0xfb}, // CWF R Off{0xet
++ {0x5D,0xFe}, // CWF B Off{0xet
++ {0x5E,0xfb}, // 3000K R Off{0xet
++ {0x5F,0xFb}, // 3000K B Off{0xet
++ {0x60,0xfb}, // A R Off0xet
++ {0x61,0xfb}, // A B Off0xet
++ {0x62,0xfb}, // 2000K R Off0xet
++ {0x63,0xfb}, // 2000K B Off0xet
++
++ {0xde,0x00}, // LARGE OBJECT BUG FIX
++ {0xf0,0x6a}, // RB Ratio
++ //=================================
++ // Green Stablity Enhance
++ //=================================
++ {0xfc,0x22},
++ {0xb9,0x00},
++ {0xba,0x00},
++ {0xbb,0x00},
++ {0xbc,0x00},
++ {0xe5,0x01},
++ {0xe6,0xff},
++
++ {0xbd,0x90},
++
++ //==========================================================
++ // Special Effect
++ //==========================================================
++ {0xfc,0x07}, // Special Effect
++ {0x30,0xc0},
++ {0x31,0x20},
++ {0x32,0x40},
++ {0x33,0xc0},
++ {0x34,0x00},
++ {0x35,0xb0},
++
++ {0xfc,0x00},
++ {0x73,0x21}, // Frmae AE Enable}, peter0223 À§Ä¡ º¯°æ
++
++ {0xfc,0x04},
++ {0xc0,0x06},
++ {0xc1,0x70},
++ {0xFF,0xFF} // REGISTER END
++};
++#else
++s5k4xa_t s5k4ba_reg[] =
++{
++//==========================================================
++// CAMERA INITIAL (Analog & Clock Setting)
++//==========================================================
++ {0xfc, 0x07},
++ {0x66, 0x01},// WDT
++ {0xfc, 0x00},
++ {0x00, 0xaa},// For EDS Check
++ {0x21, 0x03},// peter0223 added
++
++ {0xfc, 0x01},
++ {0x04, 0x01},// ARM Clock Divider
++
++ {0xfc, 0x02},// Analog setting
++ {0x55, 0x1e},// LineADLC on(s551a), off(s550a)
++ {0x56, 0x10},// BPR 16code
++ {0x30, 0x82},// Analog offset (capture =?h)
++ {0x37, 0x25},// Global Gain (default:31)
++
++ {0x57, 0x80},// // LineADLC Roffset
++ {0x58, 0x80},//89 //90 // LineADLC Goffset
++ {0x59, 0x80},//90 // LineADLC offset don't care
++
++ {0x44, 0x64},//clamp en[6]=1 on
++ {0x4a, 0x30},//clamp level 0011h [7]~[4]
++
++ {0x2d, 0x48},// double shutter (default:00)
++ {0x4d, 0x08},// Voltage doubler (default:04)
++ {0x4e, 0x00},// IO current 8mA set
++ {0x4f, 0x8a},// IO current 48mA set
++
++ {0x66, 0x41},// 1st comp current 2uA
++ {0x43, 0xef},// ec_comp
++ {0x62, 0x60},// LD control , CFPN_EN off
++
++//==========================================================
++// Table Set for Sub-Sampling
++//==========================================================
++ {0xfc, 0x03},
++ {0x01, 0x60},
++ //{0x2e, 0x00},
++ {0x2e, 0x03},//DHL
++ {0x05, 0x46},// Output Image Size Set for Capture
++ {0x07, 0xb6},
++ {0x0e, 0x04},
++ {0x12, 0x03},
++
++ {0xfc, 0x04},
++ {0xc5, 0x26},// Output Image Size Set for Preview
++ {0xc7, 0x5e},
++ {0xce, 0x04},
++ {0xd2, 0x04},
++ //{0xee, 0x00},//DHL
++ {0xee, 0x01},
++ {0xc0, 0x06},
++ {0xc1, 0x60},//frame_H
++ {0xc2, 0x02},
++ {0xc3, 0x8d},//frame_V
++
++ {0xfc, 0x07},
++ {0x05, 0x00},
++ {0x06, 0x00},
++ {0x07, 0x8b},
++ {0x08, 0xf5},
++ {0x09, 0x00},
++ {0x0a, 0xb4},
++ {0x0b, 0x00},
++ {0x0c, 0xea},
++ {0x0d, 0x00},
++ {0x0e, 0x40},
++
++#if 1
++//==========================================================
++// COMMAND SET
++//==========================================================
++ {0xfc, 0x00},
++ {0x70, 0x02},
++
++ {0xfc, 0x00},
++ {0x73, 0x11},//21 Frmae AE Enable, peter0223
++ {0x20, 0x02},// Change AWB Mode
++
++ {0xfc, 0x00},
++ {0x78, 0x6a},// AGC Max
++
++ {0xfc, 0x00},
++ {0x6c, 0xa0},// AE target
++ {0x6d, 0x00},
++
++ {0xfc, 0x20},
++ {0x16, 0x5a},// AGC frame AE start _for Prevating AE Hunting
++ {0x57, 0x18},// Stable_Frame_AE
++
++ {0xfc, 0x00},
++ {0x83, 0x06},//low condition shutter off // Double shutter off
++
++ {0xfc, 0x0b},
++ {0x5c, 0x69},//70 //AGC value to start shutter on/off suppress
++ {0x5d, 0x65},//60 //AGC value to start double shutter on/off suppress
++
++ {0xfc, 0x20},
++ {0x25, 0x00},// CINTR Min
++ {0x2a, 0x01},// forbidden
++ {0x2b, 0x02},// For Forbidden Area
++ {0x2c, 0x0a},
++ {0x2d, 0x00},// For Forbidden Area
++ {0x2e, 0x00},
++ {0x2f, 0x05},// forbidden
++ {0x14, 0x78},//70
++ {0x01, 0x00},// Stepless_Off
++
++ {0xfc, 0x00},
++ {0x29, 0x04},// Y level
++ {0x2a, 0x00},
++ {0x2b, 0x03},// C level
++ {0x2c, 0x80},//60
++
++ {0xfc, 0x07},
++ {0x37, 0x00},// Flicker
++
++ {0xfc, 0x00},
++ {0x72, 0xa0},// Flicker for 32MHz
++ {0x74, 0x08},// flicker 60Hz fix
++ {0xfc, 0x20},
++ {0x02, 0x12},//02 Flicker Dgain Mode
++ {0xfc, 0x00},
++ {0x62, 0x02},// Hue Control Enable
++
++ {0xfc, 0x01},
++ //{0x0c, 0x02},// Full YC Enable
++ {0x0C, 0x03},//Donghoon
++
++
++//==========================================================
++// COLOR MATRIX
++//==========================================================
++ {0xfc, 0x01}, //DL gain 60
++ {0x51, 0x08}, //06 //08 07
++ {0x52, 0xe8}, //df //9B E7
++ {0x53, 0xfc}, //fd //FC FB
++ {0x54, 0x33}, //09 //07 B9
++ {0x55, 0xfe}, //00 //FF 00
++ {0x56, 0xe6}, //17 //5E 5F
++ {0x57, 0xfe}, //fe //FD FD
++ {0x58, 0x3d}, //4f //0E 46
++ {0x59, 0x08}, //06 //07 05
++ {0x5a, 0x21}, //9b //EE E6
++ {0x5b, 0xfd}, //ff //FF 00
++ {0x5c, 0xa3}, //17 //05 D3
++ {0x5d, 0xff}, //ff //FF FF
++ {0x5e, 0xbc}, //81 //7A 53
++ {0x5f, 0xfc}, //fd //FC FB
++ {0x60, 0x96}, //5b //23 B1
++ {0x61, 0x07}, //07 //08 08
++ {0x62, 0xaf}, //24 //64 FD
++
++//==========================================================
++// EDGE ENHANCEMENT
++//==========================================================
++ {0xfc, 0x05},
++ {0x12, 0x3d},
++ {0x13, 0x3b},
++ {0x14, 0x38},
++ {0x15, 0x3b},
++ {0x16, 0x3d},
++
++ {0x17, 0x3b},
++ {0x18, 0x05},
++ {0x19, 0x09},
++ {0x1a, 0x05},
++ {0x1b, 0x3b},
++
++ {0x1c, 0x38},
++ {0x1d, 0x09},
++ {0x1e, 0x1c},
++ {0x1f, 0x09},
++ {0x20, 0x38},
++
++ {0x21, 0x3b},
++ {0x22, 0x05},
++ {0x23, 0x09},
++ {0x24, 0x05},
++ {0x25, 0x3b},
++
++ {0x26, 0x3d},
++ {0x27, 0x3b},
++ {0x28, 0x38},
++ {0x29, 0x3b},
++ {0x2a, 0x3d},
++
++ {0xfc, 0x00},
++ {0x89, 0x00},// Edge Suppress On
++ {0xfc, 0x0b},
++ {0x42, 0x50},// Edge AGC MIN
++ {0x43, 0x60},// Edge AGC MAX
++ {0x45, 0x18},// positive gain AGC MIN
++ {0x49, 0x06},// positive gain AGC MAX
++ {0x4d, 0x18},// negative gain AGC MIN
++ {0x51, 0x06},// negative gain AGC MAX
++
++ {0xfc, 0x05},
++ {0x34, 0x28},// APTCLP
++ {0x35, 0x03},// APTSC
++ {0x36, 0x0b},// ENHANCE
++ {0x3f, 0x00},// NON-LIN
++ {0x42, 0x10},// EGFALL
++ {0x43, 0x00},// HLFALL
++ {0x45, 0xa0},// EGREF
++ {0x46, 0x7a},// HLREF
++ {0x47, 0x40},// LLREF
++ {0x48, 0x0c},
++ {0x49, 0x31},// CSSEL EGSEL CS_DLY
++
++ {0x40, 0x41},// Y delay
++
++ // New Wide Luma Edge
++ {0xfc, 0x1d},
++ {0x86, 0x00},
++ {0x87, 0x60},
++ {0x88, 0x01},
++ {0x89, 0x20},
++ {0x8a, 0x00},
++ {0x8b, 0x00},
++ {0x8c, 0x00},
++ {0x8d, 0x00},
++ {0x8e, 0x00},
++ {0x8f, 0x20},
++ {0x90, 0x00},
++ {0x91, 0x00},
++ {0x92, 0x00},
++ {0x93, 0x0a},
++ {0x94, 0x00},
++ {0x95, 0x00},
++ {0x96, 0x00},
++ {0x97, 0x20},
++ {0x98, 0x00},
++ {0x99, 0x00},
++ {0x9a, 0xff},
++ {0x9b, 0xea},
++ {0x9c, 0xaa},
++ {0x9d, 0xab},
++ {0x9e, 0xff},
++ {0x9f, 0xf1},
++ {0xa0, 0x55},
++ {0xa1, 0x56},
++ {0xa2, 0x07},
++
++ {0x85, 0x01},
++
++//==========================================================
++// GAMMA
++//==========================================================
++ {0xfc, 0x1d},
++ {0x00, 0x0b},
++ {0x01, 0x18},
++ {0x02, 0x3d},
++ {0x03, 0x9c},
++ {0x04, 0x00},
++ {0x05, 0x0c},
++ {0x06, 0x76},
++ {0x07, 0xc2},
++ {0x08, 0x00},
++ {0x09, 0x56},
++ {0x0a, 0x34},
++ {0x0b, 0x60},
++ {0x0c, 0x85},
++ {0x0d, 0xa7},
++ {0x0e, 0xaa},
++ {0x0f, 0xc6},
++ {0x10, 0xe2},
++ {0x11, 0xfc},
++ {0x12, 0x13},
++ {0x13, 0xab},
++ {0x14, 0x29},
++ {0x15, 0x3c},
++ {0x16, 0x4b},
++ {0x17, 0x5a},
++ {0x18, 0xff},
++ {0x19, 0x69},
++ {0x1a, 0x78},
++ {0x1b, 0x84},
++ {0x1c, 0x91},
++ {0x1d, 0xff},
++ {0x1e, 0x9c},
++ {0x1f, 0xa7},
++ {0x20, 0xb2},
++ {0x21, 0xbd},
++ {0x22, 0xff},
++ {0x23, 0xc7},
++ {0x24, 0xd2},
++ {0x25, 0xdb},
++ {0x26, 0xe4},
++ {0x27, 0xff},
++ {0x28, 0xec},
++ {0x29, 0xf5},
++ {0x2a, 0xf0},
++ {0x2b, 0x0b},
++ {0x2c, 0x18},
++ {0x2d, 0x3d},
++ {0x2e, 0x9c},
++ {0x2f, 0x00},
++ {0x30, 0x0c},
++ {0x31, 0x76},
++ {0x32, 0xc2},
++ {0x33, 0x00},
++ {0x34, 0x56},
++ {0x35, 0x34},
++ {0x36, 0x60},
++ {0x37, 0x85},
++ {0x38, 0xa7},
++ {0x39, 0xaa},
++ {0x3a, 0xc6},
++ {0x3b, 0xe2},
++ {0x3c, 0xfc},
++ {0x3d, 0x13},
++ {0x3e, 0xab},
++ {0x3f, 0x29},
++ {0x40, 0x3c},
++ {0x41, 0x4b},
++ {0x42, 0x5a},
++ {0x43, 0xff},
++ {0x44, 0x69},
++ {0x45, 0x78},
++ {0x46, 0x84},
++ {0x47, 0x91},
++ {0x48, 0xff},
++ {0x49, 0x9c},
++ {0x4a, 0xa7},
++ {0x4b, 0xb2},
++ {0x4c, 0xbd},
++ {0x4d, 0xff},
++ {0x4e, 0xc7},
++ {0x4f, 0xd2},
++ {0x50, 0xdb},
++ {0x51, 0xe4},
++ {0x52, 0xff},
++ {0x53, 0xec},
++ {0x54, 0xf5},
++ {0x55, 0xf0},
++ {0x56, 0x0b},
++ {0x57, 0x18},
++ {0x58, 0x3d},
++ {0x59, 0x9c},
++ {0x5a, 0x00},
++ {0x5b, 0x0c},
++ {0x5c, 0x76},
++ {0x5d, 0xc2},
++ {0x5e, 0x00},
++ {0x5f, 0x56},
++ {0x60, 0x34},
++ {0x61, 0x60},
++ {0x62, 0x85},
++ {0x63, 0xa7},
++ {0x64, 0xaa},
++ {0x65, 0xc6},
++ {0x66, 0xe2},
++ {0x67, 0xfc},
++ {0x68, 0x13},
++ {0x69, 0xab},
++ {0x6a, 0x29},
++ {0x6b, 0x3c},
++ {0x6c, 0x4b},
++ {0x6d, 0x5a},
++ {0x6e, 0xff},
++ {0x6f, 0x69},
++ {0x70, 0x78},
++ {0x71, 0x84},
++ {0x72, 0x91},
++ {0x73, 0xff},
++ {0x74, 0x9c},
++ {0x75, 0xa7},
++ {0x76, 0xb2},
++ {0x77, 0xbd},
++ {0x78, 0xff},
++ {0x79, 0xc7},
++ {0x7a, 0xd2},
++ {0x7b, 0xdb},
++ {0x7c, 0xe4},
++ {0x7d, 0xff},
++ {0x7e, 0xec},
++ {0x7f, 0xf5},
++ {0x80, 0xf0},
++
++//==========================================================
++// HUE CONTROL
++//==========================================================
++ {0xfc, 0x00},
++ {0x48, 0x40},// 2000K
++ {0x49, 0x30},
++ {0x4a, 0x00},
++ {0x4b, 0x00},
++ {0x4c, 0x30},
++ {0x4d, 0x38},
++ {0x4e, 0x00},
++ {0x4f, 0x00},
++
++ {0x50, 0x40},// 3000K
++ {0x51, 0x30},
++ {0x52, 0x00},
++ {0x53, 0x00},
++ {0x54, 0x30},
++ {0x55, 0x38},
++ {0x56, 0x00},
++ {0x57, 0x00},
++
++ {0x58, 0x3c},//40 // 5100K
++ {0x59, 0x30},//4a //40
++ {0x5a, 0x00},//0c //00
++ {0x5b, 0x00},//00
++ {0x5c, 0x30},//4a
++ {0x5d, 0x38},//40
++ {0x5e, 0x00},//f6 //15
++ {0x5f, 0xfc},//00
++
++//==========================================================
++// SUPPRESS FUNCTION
++//==========================================================
++ {0xfc, 0x00},
++ {0x7e, 0xf4},
++
++//==========================================================
++// BPR
++//==========================================================
++ {0xfc, 0x0b},
++ {0x3d, 0x10},
++
++ {0xfc, 0x0b},
++ {0x0b, 0x00},
++ {0x0c, 0x40},
++ {0x0d, 0x5a},
++ {0x0e, 0x00},
++ {0x0f, 0x20},
++ {0x10, 0x00},
++ {0x11, 0x10},
++ {0x12, 0x00},
++ {0x13, 0x7f},
++ {0x14, 0x03},
++ {0x15, 0xff},
++ {0x16, 0x48},
++ {0x17, 0x60},
++ {0x18, 0x00},
++ {0x19, 0x00},
++ {0x1a, 0x00},
++ {0x1b, 0x20},
++ {0x1c, 0x00},
++ {0x1d, 0x00},
++ {0x1e, 0x00},
++ {0x1f, 0x20},
++
++//==========================================================
++// GR/GB CORRECTION
++//==========================================================
++ {0xfc, 0x01},
++ {0x45, 0x0c},
++ {0xfc, 0x0b},
++ {0x21, 0x00},
++ {0x22, 0x40},
++ {0x23, 0x60},
++ {0x24, 0x0d},
++ {0x25, 0x20},
++ {0x26, 0x0d},
++ {0x27, 0x20},
++
++//==========================================================
++// NR
++//==========================================================
++ {0xfc, 0x01},
++ {0x4c, 0x01},
++ {0x49, 0x15},
++ {0x4b, 0x0a},
++
++ {0xfc, 0x0b},
++ {0x28, 0x00},
++ {0x29, 0x00},
++ {0x2a, 0x14},
++ {0x2b, 0x00},
++ {0x2c, 0x14},
++ {0x2d, 0x00},
++ {0x2e, 0xD0},
++ {0x2f, 0x02},
++ {0x30, 0x00},
++ {0x31, 0x00},
++ {0x32, 0xa0},
++ {0x33, 0x00},
++ {0x34, 0xe0},
++
++//==========================================================
++// 1D-Y/C-SIGMA-LPF
++//==========================================================
++ {0xfc, 0x01},
++ {0x05, 0xC0},
++
++ {0xfc, 0x0b},
++ {0x35, 0x00},
++ {0x36, 0x40},
++ {0x37, 0x60},
++ {0x38, 0x00},
++ {0x39, 0x18},
++ {0x3a, 0x00},
++ {0x3b, 0x40},
++ {0x3c, 0x50},
++ {0x3d, 0x60},
++ {0x3e, 0x00},
++ {0x3f, 0x30},
++ {0x40, 0x00},
++ {0x41, 0x40},
++ {0xd4, 0x40},
++ {0xd5, 0x60},
++ {0xd6, 0xb0},
++ {0xd7, 0xf0},
++ {0xd8, 0xb0},
++ {0xd9, 0xf0},
++
++//==========================================================
++// COLOR SUPPRESS
++//==========================================================
++ {0xfc, 0x0b},
++ {0x08, 0x58},
++ {0x09, 0x03},
++ {0x0a, 0x00},
++
++//==========================================================
++// SHADING
++//==========================================================
++ {0xfc, 0x09},
++
++ {0x01, 0x06},
++ {0x02, 0x40},
++
++ {0x03, 0x04},
++ {0x04, 0xB0},
++
++ {0x05, 0x03},
++ {0x06, 0x20},
++ {0x07, 0x02},
++ {0x08, 0x91},
++
++ {0x09, 0x03},
++ {0x0A, 0x25},
++ {0x0B, 0x02},
++ {0x0C, 0x64},
++
++ {0x0D, 0x03},
++ {0x0E, 0x0F},
++ {0x0F, 0x02},
++ {0x10, 0x4E},
++
++ {0x1D, 0x80},
++ {0x1E, 0x00},
++ {0x1F, 0x80},
++ {0x20, 0x00},
++ {0x23, 0x85},
++ {0x24, 0x52},
++ {0x21, 0x79},
++ {0x22, 0xE6},
++
++ {0x25, 0x80},
++ {0x26, 0x00},
++ {0x27, 0x80},
++ {0x28, 0x00},
++ {0x2B, 0x81},
++ {0x2C, 0x48},
++ {0x29, 0x81},
++ {0x2A, 0x48},
++
++ {0x2D, 0x80},
++ {0x2E, 0x00},
++ {0x2F, 0x80},
++ {0x30, 0x00},
++ {0x33, 0x7C},
++ {0x34, 0x45},
++ {0x31, 0x7D},
++ {0x32, 0x7D},
++
++ {0x35, 0x01},
++ {0x36, 0x00},
++ {0x37, 0x01},
++ {0x38, 0x11},
++ {0x39, 0x01},
++ {0x3A, 0x4E},
++ {0x3B, 0x01},
++ {0x3C, 0xAB},
++ {0x3D, 0x01},
++ {0x3E, 0xDC},
++ {0x3F, 0x02},
++ {0x40, 0x1A},
++ {0x41, 0x02},
++ {0x42, 0x6A},
++ {0x43, 0x02},
++ {0x44, 0xD3},
++
++ {0x45, 0x01},
++ {0x46, 0x00},
++ {0x47, 0x01},
++ {0x48, 0x0E},
++ {0x49, 0x01},
++ {0x4A, 0x40},
++ {0x4B, 0x01},
++ {0x4C, 0x8A},
++ {0x4D, 0x01},
++ {0x4E, 0xB5},
++ {0x4F, 0x01},
++ {0x50, 0xE8},
++ {0x51, 0x02},
++ {0x52, 0x27},
++ {0x53, 0x02},
++ {0x54, 0x84},
++
++ {0x55, 0x01},
++ {0x56, 0x00},
++ {0x57, 0x01},
++ {0x58, 0x0C},
++ {0x59, 0x01},
++ {0x5A, 0x37},
++ {0x5B, 0x01},
++ {0x5C, 0x74},
++ {0x5D, 0x01},
++ {0x5E, 0x96},
++ {0x5F, 0x01},
++ {0x60, 0xC9},
++ {0x61, 0x02},
++ {0x62, 0x04},
++ {0x63, 0x02},
++ {0x64, 0x4B},
++
++ {0x65, 0x00},
++ {0x66, 0x9A},
++ {0x67, 0x2D},
++ {0x68, 0x02},
++ {0x69, 0x68},
++ {0x6A, 0xB6},
++ {0x6B, 0x05},
++ {0x6C, 0x6B},
++ {0x6D, 0x99},
++ {0x6E, 0x07},
++ {0x6F, 0x60},
++ {0x70, 0xAD},
++ {0x71, 0x09},
++ {0x72, 0xA2},
++ {0x73, 0xD7},
++ {0x74, 0x0C},
++ {0x75, 0x32},
++ {0x76, 0x19},
++ {0x77, 0x0F},
++ {0x78, 0x0E},
++ {0x79, 0x70},
++
++ {0x7A, 0x00},
++ {0x7B, 0x9C},
++ {0x7C, 0x9F},
++ {0x7D, 0x02},
++ {0x7E, 0x72},
++ {0x7F, 0x7A},
++ {0x80, 0x05},
++ {0x81, 0x81},
++ {0x82, 0x94},
++ {0x83, 0x07},
++ {0x84, 0x7E},
++ {0x85, 0x97},
++ {0x86, 0x09},
++ {0x87, 0xC9},
++ {0x88, 0xEA},
++ {0x89, 0x0C},
++ {0x8A, 0x63},
++ {0x8B, 0x8C},
++ {0x8C, 0x0F},
++ {0x8D, 0x4B},
++ {0x8E, 0x7E},
++
++ {0x8F, 0x00},
++ {0x90, 0x9E},
++ {0x91, 0xBD},
++ {0x92, 0x02},
++ {0x93, 0x7A},
++ {0x94, 0xF5},
++ {0x95, 0x05},
++ {0x96, 0x94},
++ {0x97, 0xA8},
++ {0x98, 0x07},
++ {0x99, 0x98},
++ {0x9A, 0x8F},
++ {0x9B, 0x09},
++ {0x9C, 0xEB},
++ {0x9D, 0xD5},
++ {0x9E, 0x0C},
++ {0x9F, 0x8E},
++ {0xA0, 0x7A},
++ {0xA1, 0x0F},
++ {0xA2, 0x80},
++ {0xA3, 0x7D},
++
++ {0xA4, 0x6A},
++ {0xA5, 0x44},
++ {0xA6, 0x23},
++ {0xA7, 0x6C},
++ {0xA8, 0x15},
++ {0xA9, 0x40},
++ {0xAA, 0x20},
++ {0xAB, 0xB2},
++ {0xAC, 0x1C},
++ {0xAD, 0x56},
++ {0xAE, 0x19},
++ {0xAF, 0x01},
++ {0xB0, 0x16},
++ {0xB1, 0x5F},
++
++ {0xB2, 0x68},
++ {0xB3, 0x9C},
++ {0xB4, 0x22},
++ {0xB5, 0xDE},
++ {0xB6, 0x14},
++ {0xB7, 0xEC},
++ {0xB8, 0x20},
++ {0xB9, 0x30},
++ {0xBA, 0x1B},
++ {0xBB, 0xE5},
++ {0xBC, 0x18},
++ {0xBD, 0x9D},
++ {0xBE, 0x16},
++ {0xBF, 0x05},
++
++ {0xC0, 0x67},
++ {0xC1, 0x36},
++ {0xC2, 0x22},
++ {0xC3, 0x67},
++ {0xC4, 0x14},
++ {0xC5, 0xA4},
++ {0xC6, 0x1F},
++ {0xC7, 0xC2},
++ {0xC8, 0x1B},
++ {0xC9, 0x86},
++ {0xCA, 0x18},
++ {0xCB, 0x49},
++ {0xCC, 0x15},
++ {0xCD, 0xBA},
++
++ {0x00, 0x02},// shading on
++
++//==========================================================
++// X-SHADING
++//==========================================================
++ {0xfc, 0x1B},
++ {0x80, 0x01},
++ {0x81, 0x00},
++ {0x82, 0x4C},
++ {0x83, 0x00},
++ {0x84, 0x86},
++ {0x85, 0x03},
++ {0x86, 0x5E},
++ {0x87, 0x00},
++ {0x88, 0x07},
++ {0x89, 0xA4},
++ {0x90, 0x00},
++ {0x91, 0x88},
++ {0x92, 0x00},
++ {0x93, 0xC1},
++ {0x94, 0x00},
++ {0x95, 0xF7},
++ {0x96, 0x01},
++ {0x97, 0x21},
++ {0x98, 0x01},
++ {0x99, 0x37},
++ {0x9A, 0x01},
++ {0x9B, 0x0C},
++ {0x9C, 0x00},
++ {0x9D, 0xCE},
++ {0x9E, 0x00},
++ {0x9F, 0x3B},
++ {0xA0, 0x00},
++ {0xA1, 0x5B},
++ {0xA2, 0x00},
++ {0xA3, 0x7A},
++ {0xA4, 0x00},
++ {0xA5, 0x92},
++ {0xA6, 0x00},
++ {0xA7, 0x91},
++ {0xA8, 0x00},
++ {0xA9, 0x81},
++ {0xAA, 0x00},
++ {0xAB, 0x60},
++ {0xAC, 0x07},
++ {0xAD, 0xCB},
++ {0xAE, 0x07},
++ {0xAF, 0xC5},
++ {0xB0, 0x07},
++ {0xB1, 0xBB},
++ {0xB2, 0x07},
++ {0xB3, 0xAA},
++ {0xB4, 0x07},
++ {0xB5, 0xA9},
++ {0xB6, 0x07},
++ {0xB7, 0xB2},
++ {0xB8, 0x07},
++ {0xB9, 0xBF},
++ {0xBA, 0x07},
++ {0xBB, 0x5E},
++ {0xBC, 0x07},
++ {0xBD, 0x3C},
++ {0xBE, 0x06},
++ {0xBF, 0xF9},
++ {0xC0, 0x06},
++ {0xC1, 0xBD},
++ {0xC2, 0x06},
++ {0xC3, 0xB8},
++ {0xC4, 0x06},
++ {0xC5, 0xE2},
++ {0xC6, 0x07},
++ {0xC7, 0x1A},
++ {0xC8, 0x07},
++ {0xC9, 0x15},
++ {0xCA, 0x06},
++ {0xCB, 0xDE},
++ {0xCC, 0x06},
++ {0xCD, 0x9C},
++ {0xCE, 0x06},
++ {0xCF, 0x6F},
++ {0xD0, 0x06},
++ {0xD1, 0x5E},
++ {0xD2, 0x06},
++ {0xD3, 0x84},
++ {0xD4, 0x06},
++ {0xD5, 0xCA},
++
++ {0xfc, 0x0b},
++ {0xda, 0x00},
++ {0xdb, 0x9c},
++ {0xdc, 0x00},
++ {0xdd, 0xd1},
++
++ {0xfc, 0x1b},
++ {0x80, 0x01},
++
++//==========================================================
++// AE WINDOW WEIGHT
++//==========================================================
++ {0xfc, 0x00},
++ {0x03, 0x4b},
++ {0xfc, 0x06},
++ {0x01, 0x35},
++ {0x03, 0xc2},
++ {0x05, 0x48},
++ {0x07, 0xb8},
++ {0x31, 0x2a},
++ {0x33, 0x61},
++ {0x35, 0x28},
++ {0x37, 0x5c},
++
++ {0xfc, 0x20},
++ {0x60, 0x11},
++ {0x61, 0x11},
++ {0x62, 0x11},
++ {0x63, 0x11},
++ {0x64, 0x11},
++ {0x65, 0x22},
++ {0x66, 0x22},
++ {0x67, 0x11},
++ {0x68, 0x11},
++ {0x69, 0x33},
++ {0x6a, 0x33},
++ {0x6b, 0x11},
++ {0x6c, 0x12},
++ {0x6d, 0x55},
++ {0x6e, 0x55},
++ {0x6f, 0x21},
++ {0x70, 0x13},
++ {0x71, 0x55},
++ {0x72, 0x55},
++ {0x73, 0x31},
++ {0x74, 0x33},
++ {0x75, 0x33},
++ {0x76, 0x33},
++ {0x77, 0x33},
++
++//==========================================================
++// SAIT AWB
++//==========================================================
++ {0xfc, 0x00},
++ {0x7b, 0x00},
++
++ {0xfc, 0x07},
++ {0x3c, 0x10},
++ {0x3d, 0x10},
++ {0x3e, 0x10},
++ {0x3f, 0x10},
++
++ {0xfc, 0x01},
++ {0xc8, 0xe0},
++ {0xfc, 0x00},
++ {0x3e, 0x10},
++
++ {0xfc, 0x00},
++ {0x3e, 0x10},
++ {0x3d, 0x04},
++ {0x32, 0x02},
++ {0x81, 0x10},
++ {0xbc, 0xf0},
++ {0xfc, 0x22},
++ {0x8c, 0x04},
++ {0x8d, 0x06},
++
++ {0xfc, 0x07},
++ {0x97, 0x00},
++
++//=================================
++// White Point
++//=================================
++ {0xfc, 0x22},
++ {0x01, 0xD8},
++ {0x03, 0xA1},
++ {0x05, 0xCA},
++ {0x07, 0xC8},
++ {0x09, 0xB3},
++ {0x0b, 0xE2},
++ {0x0d, 0xA0},
++ {0x0f, 0xF0},
++ {0x11, 0x94},
++ {0x12, 0x00},
++ {0x13, 0xFD},
++ {0x15, 0x88},
++ {0x16, 0x01},
++ {0x17, 0x10},
++
++//=================================
++// Basic Setting
++//=================================
++ {0xfc, 0x22},
++ {0xA8, 0xFF},
++
++ {0xA0, 0x01},
++ {0xA1, 0x38},
++ {0xA2, 0x0E},
++ {0xA3, 0x6D},
++ {0xA4, 0x07},
++ {0xA5, 0xF5},
++ {0xA6, 0x11},
++ {0xA7, 0xBE},
++ {0xA9, 0x02},
++ {0xAA, 0xD2},
++ {0xAB, 0x00},
++ {0xAC, 0x00},
++ {0xAD, 0x02},
++ {0xAE, 0x3F},
++ {0xAF, 0x19},
++ {0xB0, 0x91},
++ {0x94, 0x3D},
++ {0x95, 0x00},
++ {0x96, 0x58},
++ {0x97, 0x80},
++ {0xD0, 0xA2},
++ {0xD1, 0x2E},
++ {0xD2, 0x4D},
++ {0xD3, 0x28},
++ {0xD4, 0x90},
++ {0xDB, 0x2E},
++ {0xDC, 0x7A},
++ {0xDD, 0x28},
++ {0xE7, 0x00},
++ {0xE8, 0xc7},
++ {0xE9, 0x00},
++ {0xEA, 0x62},
++ {0xEB, 0xD2},
++ {0xEC, 0xD9},
++ {0xEE, 0xA6},
++
++ {0xfc, 0x00},
++ {0x8a, 0x02},
++
++//=================================
++// Pixel Filter Setting
++//=================================
++ {0xFC, 0x07},
++ {0x95, 0xCF},
++
++ {0xfc, 0x01},
++ {0xd3, 0x4f},
++ {0xd4, 0x00},
++ {0xd5, 0x3c},
++ {0xd6, 0x80},
++ {0xd7, 0x61},
++ {0xd8, 0x00},
++ {0xd9, 0x49},
++ {0xda, 0x00},
++ {0xdb, 0x24},
++ {0xdc, 0x4b},
++ {0xdd, 0x23},
++ {0xde, 0xf2},
++ {0xdf, 0x20},
++ {0xe0, 0x73},
++ {0xe1, 0x18},
++ {0xe2, 0x69},
++ {0xe3, 0x31},
++ {0xe4, 0x40},
++ {0xe5, 0x34},
++ {0xe6, 0x40},
++ {0xe7, 0x40},
++ {0xe8, 0x32},
++ {0xe9, 0x40},
++ {0xea, 0x1c},
++ {0xeb, 0x00},
++
++//=================================
++// Polygon AWB Region Tune
++//=================================
++
++ // AWB3 - Polygon Region
++ {0xfc, 0x22},
++ {0x18, 0x00},
++ {0x19, 0x4b},
++ {0x1a, 0xfd},
++ {0x1b, 0x00},
++ {0x1c, 0x41},
++ {0x1d, 0xd9},
++ {0x1e, 0x00},
++ {0x1f, 0x66},
++ {0x20, 0xa9},
++ {0x21, 0x00},
++ {0x22, 0x8b},
++ {0x23, 0x82},
++ {0x24, 0x00},
++ {0x25, 0xa4},
++ {0x26, 0x6c},
++ {0x27, 0x00},
++ {0x28, 0xbd},
++ {0x29, 0x5d},
++ {0x2a, 0x00},
++ {0x2b, 0xdc},
++ {0x2c, 0x4d},
++ {0x2d, 0x00},
++ {0x2e, 0xdc},
++ {0x2f, 0x63},
++ {0x30, 0x00},
++ {0x31, 0xc1},
++ {0x32, 0x72},
++ {0x33, 0x00},
++ {0x34, 0xab},
++ {0x35, 0x84},
++ {0x36, 0x00},
++ {0x37, 0x99},
++ {0x38, 0xa0},
++ {0x39, 0x00},
++ {0x3a, 0x81},
++ {0x3b, 0xe9},
++ {0x3c, 0x00},
++ {0x3d, 0x00},
++ {0x3e, 0x00},
++ {0x3f, 0x00},
++ {0x40, 0x00},
++ {0x41, 0x00},
++
++//=================================
++// Moving Equation Weight
++//=================================
++ {0xfc, 0x22},
++ {0x98, 0x07},
++
++//=================================
++// EIT Threshold
++//=================================
++ {0xfc, 0x22},
++ {0xb1, 0x00},
++ {0xb2, 0x02},
++ {0xb3, 0x00},
++ {0xb4, 0xC1},
++
++ {0xb5, 0x00},
++ {0xb6, 0x02},
++ {0xb7, 0x00},
++ {0xb9, 0xc2},
++
++ {0xd7, 0x00},
++ {0xd8, 0x35},
++ {0xd9, 0x20},
++ {0xda, 0x81},
++
++//=================================
++// Gain Offset
++//=================================
++ {0xfc, 0x00},
++ {0x79, 0xf8},
++ {0x7a, 0x08},
++
++ {0xfc, 0x07},
++ {0x11, 0x01},
++
++ {0xfc, 0x22},
++ {0x58, 0xf8},
++ {0x59, 0x00},
++ {0x5A, 0xfc},
++ {0x5B, 0x00},
++ {0x5C, 0x00},
++ {0x5D, 0x00},
++ {0x5E, 0x00},
++ {0x5F, 0x00},
++ {0x60, 0x00},
++ {0x61, 0xf8},
++ {0x62, 0x00},
++ {0x63, 0xf0},
++
++ {0xde, 0x00},
++ {0xf0, 0x6a},
++
++//=================================
++// Green Stablity Enhance
++//=================================
++ {0xfc, 0x22},
++ {0xb9, 0x00},
++ {0xba, 0x00},
++ {0xbb, 0x00},
++ {0xbc, 0x00},
++ {0xe5, 0x01},
++ {0xe6, 0xff},
++ {0xbd, 0x8c},
++
++//==========================================================
++// Special Effect
++//==========================================================
++ {0xfc, 0x07},
++ {0x30, 0xc0},
++ {0x31, 0x20},
++ {0x32, 0x40},
++ {0x33, 0xc0},
++ {0x34, 0x00},
++ {0x35, 0xb0},
++#endif
++//==========================================================
++// ETC
++//==========================================================
++ {0xfc, 0x01},
++ {0x01, 0x01},
++ {0x00, 0x90},
++ {0xfc, 0x02},
++ {0x03, 0x20},
++
++ {0xfc, 0x20},
++ {0x0f, 0x00},
++
++ {0xfc, 0x00},
++ {0x02, 0x09},
++
++ {0xfc, 0x01},
++ //{0x02, 0x00},
++ {0x02, 0x02},//Donghoon
++};
++#endif
++#else
++#error No samsung CIS moudule !
++#endif
++
++
++// For VGA ( 640 x 480) on 4BA module
++s5k4xa_t s5k4ba_reg_vga[] =
++{
++ // To do.
++};
++
++// For SVGA ( 800 x 600) on 4BA module
++s5k4xa_t s5k4ba_reg_svga[] =
++{
++ {0xfc,0x02},
++ {0x2d,0x48},
++ {0x44,0x63},
++
++ {0xfc,0x03},
++ {0x02,0x04},
++ {0xfc,0x20},
++ {0x14,0x70},
++
++ {0xfc,0x00},
++ {0x03,0x4b}, // AE/AWB On
++ {0x7e,0xf4}, // Suppress On
++ {0x89,0x03}, // Edge Suppress On
++
++ {0xfc,0x02},
++ {0x02,0x0e},//sensor BPRoff
++
++ {0xfc,0x20},
++ {0x16,0x60}, // Frame AE Start
++
++ {0xfc,0x02},
++ {0x30,0x90}, // Analog offset
++ {0x37,0x0d}, // Global Gain
++ {0x60,0x00}, // Blank_Adrs
++ {0x45,0x0e}, // CDS Timing for Average Sub_Sampling
++ {0x47,0x2f},
++
++ {0xfc,0x01},
++ {0x9F,0x05}, //B
++ {0xA0,0x18},
++ {0xA1,0x42},
++ {0xA2,0xd7},
++ {0xA3,0x00},
++
++ {0xA4,0xB6},
++ {0xA5,0x3b},
++ {0xA6,0x88},
++ {0xA7,0xC8},
++ {0xA8,0x6A},
++
++ {0xfc,0x05},
++ {0x34,0x20}, // APTCLP
++ {0x35,0x08}, //9 //APTSC
++
++ {0xfc,0x00}, // flash 0821
++ {0x32,0x04}, // AWB moving average 8 frame
++
++ {0xfc,0x01},
++ {0x01,0x01}, // Pclk inversion
++
++ {0xfc,0x00},
++ {0x02,0x09}, // 800 x 600
++
++
++ {0xFF,0xFF} // REGISTER END
++};
++
++// For SXGA (1280 x 1024 = 1.3M) on 4BA module
++s5k4xa_t s5k4ba_reg_sxga[] =
++{
++ // To do.
++};
++
++
++// For UXGA (1600 x 1200 = 2M) on 4BA module
++s5k4xa_t s5k4ba_reg_uxga[] =
++{
++ // To do.
++};
++
++
++// For SQVGA on 4BA module
++s5k4xa_t s5k4ba_reg_qsvga[] =
++{
++ // Pclk inversion
++ {0xfc,0x01},
++ {0x01,0x01},
++
++ // To setting CbCr selection on Table 14h
++ {0xfc, 0x14},
++ {0x5c, 0x00},
++
++ // To load table_11 H4V4
++ {0xfc, 0x00},
++ {0x02, 0x0B}
++};
++
++#define S5K4BA_INIT_REGS (sizeof(s5k4ba_reg)/sizeof(s5k4ba_reg[0]))
++#define S5K4BA_UXGA_REGS (sizeof(s5k4ba_reg_uxga)/sizeof(s5k4ba_reg_uxga[0]))
++#define S5K4BA_SVGA_REGS (sizeof(s5k4ba_reg_svga)/sizeof(s5k4ba_reg_svga[0]))
++#define S5K4BA_VGA_REGS (sizeof(s5k4ba_reg_vga)/sizeof(s5k4ba_reg_vga[0]))
++#define S5K4BA_QSVGA_REGS (sizeof(s5k4ba_reg_qsvga)/sizeof(s5k4ba_reg_qsvga[0]))
++
++
++
++#define S5K4BA_RISC_REGS 0xEB
++#define S5K4BA_ISP_REGS 0xFB /* S5C7323X */
++#define S5K4BA_CIS_REGS 0x2F /* S5K437LA03 */
++
++
++#define S5K4BA_REGS (0x1000)
++
++
++
++#endif
+Index: cam/drivers/media/video/samsung/Makefile
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ cam/drivers/media/video/samsung/Makefile 2009-02-26 22:35:31.000000000 +0800
+@@ -0,0 +1,4 @@
++#
++# Samsung CIS camera module
++#
++obj-$(CONFIG_VIDEO_SAMSUNG_S5K4BA) += 4xa_sensor.o
+Index: cam/drivers/media/video/samsung/4xa_sensor.o
+===================================================================
+Binary files cam.orig/drivers/media/video/samsung/4xa_sensor.o 2009-02-26 22:37:02.000000000 +0800 and cam/drivers/media/video/samsung/4xa_sensor.o 2009-02-26 22:48:08.000000000 +0800 differ
Added: developers/werner/gta03/cam/patches/add-samsung-cams-i2c.patch
===================================================================
--- developers/werner/gta03/cam/patches/add-samsung-cams-i2c.patch (rev 0)
+++ developers/werner/gta03/cam/patches/add-samsung-cams-i2c.patch 2009-02-26 15:51:03 UTC (rev 4938)
@@ -0,0 +1,17 @@
+Index: cam/include/linux/i2c-id.h
+===================================================================
+--- cam.orig/include/linux/i2c-id.h 2009-02-26 22:33:44.000000000 +0800
++++ cam/include/linux/i2c-id.h 2009-02-26 22:34:36.000000000 +0800
+@@ -77,6 +77,12 @@
+ #define I2C_DRIVERID_PCF50633 1051
+ #define I2C_DRIVERID_PCA9632 1052
+
++#define I2C_DRIVERID_S5K_3XA 1500 /* Samsung MobileAP I2C adapter */
++#define I2C_DRIVERID_S5K_53BEA 1501 /* Samsung MobileAP I2C adapter */
++#define I2C_DRIVERID_S5K_532 1502 /* Samsung MobileAP I2C adapter */
++#define I2C_DRIVERID_S5K_3BA 1503 /* Samsung MobileAP I2C adapter */
++#define I2C_DRIVERID_S5K_4XA 1504 /* Samsung MobileAP I2C adapter */
++
+ /*
+ * ---- Adapter types ----------------------------------------------------
+ */
Added: developers/werner/gta03/cam/patches/series
===================================================================
--- developers/werner/gta03/cam/patches/series (rev 0)
+++ developers/werner/gta03/cam/patches/series 2009-02-26 15:51:03 UTC (rev 4938)
@@ -0,0 +1,7 @@
+add-s3c-cam-config.patch
+#mach-gta03-add-cam.patch
+add-s3c-camif-regs.patch
+add-samsung-cams-i2c.patch
+add-s5k4.patch
+add-s3c-camif.patch
+add-64xx-cam-clock.patch
More information about the commitlog
mailing list