Merge branch 'develop' of 10.10.10.29:/home/rockchip/kernel into develop
author徐建辉 <xjh@rockchips-.com>
Thu, 28 Apr 2011 02:20:58 +0000 (10:20 +0800)
committer徐建辉 <xjh@rockchips-.com>
Thu, 28 Apr 2011 02:20:58 +0000 (10:20 +0800)
17 files changed:
arch/arm/mach-rk29/include/mach/rk29_camera.h
drivers/input/lightsensor/rk29_lightsensor.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/gc0309.c [new file with mode: 0755]
drivers/media/video/gc2015.c [new file with mode: 0755]
drivers/media/video/hi253.c [new file with mode: 0755]
drivers/media/video/hi704.c [new file with mode: 0755]
drivers/media/video/nt99250.c [new file with mode: 0755]
drivers/media/video/ov3640.c
drivers/media/video/ov3640.h [new file with mode: 0755]
drivers/media/video/ov3640_af_firmware.c [new file with mode: 0755]
drivers/media/video/ov7675.c
drivers/media/video/sid130B.c [new file with mode: 0755]
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c
include/media/v4l2-chip-ident.h
sound/soc/codecs/wm8900.c

index 0daaab9b35e4df6cde33442d979d928505375606..8dbc314b7bce0b1d57bb1e0ee1a1a3f0aa8b6e14 100644 (file)
@@ -32,6 +32,7 @@
 #define RK29_CAM_EIO_INVALID -1
 #define RK29_CAM_EIO_REQUESTFAIL -2
 
+#define RK29_CAM_SENSOR_OV7675 ov7675
 #define RK29_CAM_SENSOR_OV9650 ov9650
 #define RK29_CAM_SENSOR_OV2655 ov2655
 #define RK29_CAM_SENSOR_OV2659 ov2659
 #define RK29_CAM_SENSOR_MT9P111 mt9p111
 #define RK29_CAM_SENSOR_GT2005  gt2005
 #define RK29_CAM_SENSOR_GC0308  gc0308
+#define RK29_CAM_SENSOR_GC0309  gc0309
+#define RK29_CAM_SENSOR_GC2015  gc2015
 #define RK29_CAM_SENSOR_SIV120B  siv120b
+#define RK29_CAM_SENSOR_SID130B  sid130B
+#define RK29_CAM_SENSOR_HI253  hi253
+#define RK29_CAM_SENSOR_HI704  hi704
+#define RK29_CAM_SENSOR_NT99250 nt99250
 
+#define RK29_CAM_SENSOR_NAME_OV7675 "ov7675"
 #define RK29_CAM_SENSOR_NAME_OV9650 "ov9650"
 #define RK29_CAM_SENSOR_NAME_OV2655 "ov2655"
 #define RK29_CAM_SENSOR_NAME_OV2659 "ov2659"
 #define RK29_CAM_SENSOR_NAME_MT9P111 "mt9p111"
 #define RK29_CAM_SENSOR_NAME_GT2005  "gt2005"
 #define RK29_CAM_SENSOR_NAME_GC0308  "gc0308"
+#define RK29_CAM_SENSOR_NAME_GC0309  "gc0309"
+#define RK29_CAM_SENSOR_NAME_GC2015  "gc2015"
 #define RK29_CAM_SENSOR_NAME_SIV120B "siv120b"
+#define RK29_CAM_SENSOR_NAME_SID130B "sid130B"
+#define RK29_CAM_SENSOR_NAME_HI253  "hi253"
+#define RK29_CAM_SENSOR_NAME_HI704  "hi704"
+#define RK29_CAM_SENSOR_NAME_NT99250 "nt99250"
 
 #define RK29_CAM_POWERACTIVE_BITPOS    0x00
 #define RK29_CAM_POWERACTIVE_MASK      (1<<RK29_CAM_POWERACTIVE_BITPOS)
index 63efdc415696823d1d9ce344cc42ac53992f4080..77b1732daaa377dd750797ea8f3c8c06ca82de78 100644 (file)
 #include <linux/delay.h>
 #include <linux/string.h>
 
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
 
 #include <mach/rk29_lightsensor.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static struct early_suspend cm3202_early_suspend;
+#endif
+
 
 struct rk29_lsr_platform_data *lightsensor;
 static void lsr_report_value(struct input_dev *input_dev, int value)
 {
-    input_report_abs(input_dev, ABS_X, value);
-    //input_sync(input_dev);
+    input_report_abs(input_dev, ABS_MISC/*ABS_X*/, value);
+    input_sync(input_dev);
 }
 
 
@@ -219,7 +226,7 @@ static void rk29_lsr_input_init(struct platform_device *dev)
        pdata->input_dev->name = "lsensor";
        pdata->input_dev->dev.parent = &dev->dev;
        pdata->input_dev->evbit[0] = BIT(EV_ABS);
-       input_set_abs_params(pdata->input_dev,ABS_X,0,0x3ff,0,0);
+       input_set_abs_params(pdata->input_dev,ABS_MISC/*ABS_X*/,0,9/*0x3ff*/,0,0);
        ret = input_register_device(pdata->input_dev);
        return ;
 init_input_register_device_failed:
@@ -232,7 +239,19 @@ static void rk29_lsr_input_deinit(struct platform_device *dev)
        input_unregister_device(pdata->input_dev);
     input_free_device(pdata->input_dev);
 }
+static int lsr_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       set_lsr_timer(0);
+       set_lsr_value(LSR_OFF);
+       return 0;
+}
 
+static int lsr_resume(struct platform_device *pdev)
+{
+       set_lsr_timer(1);
+       set_lsr_value(LSR_ON);
+       return 0; 
+}
 static int __devinit lsr_probe(struct platform_device *pdev)
 {
        lightsensor = kzalloc(sizeof(struct rk29_lsr_platform_data), GFP_KERNEL);
@@ -253,6 +272,12 @@ static int __devinit lsr_probe(struct platform_device *pdev)
        rk29_lsr_adc_init(pdev);
        rk29_lsr_timer_init(pdev);
        rk29_lsr_input_init(pdev);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+       cm3202_early_suspend.suspend = lsr_suspend;
+       cm3202_early_suspend.resume  = lsr_resume; 
+       register_early_suspend(&cm3202_early_suspend);
+#endif
+
        return 0;
 
 err_kzalloc_lightsensor:
@@ -271,27 +296,11 @@ static int __devexit lsr_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int lsr_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       set_lsr_timer(0);
-       set_lsr_value(LSR_OFF);
-       return 0;
-}
-
-static int lsr_resume(struct platform_device *pdev)
-{
-       set_lsr_timer(1);
-       set_lsr_value(LSR_ON);
-       return 0; 
-}
-
-
-
 static struct platform_driver lsr_device_driver = {
        .probe          = lsr_probe,
        .remove         = __devexit_p(lsr_remove),
-       .suspend        = lsr_suspend,
-       .resume         = lsr_resume,
+//     .suspend        = lsr_suspend,
+//     .resume         = lsr_resume,
        .driver         = {
                .name   = LSR_NAME,
                .owner  = THIS_MODULE,
index 4558672b62da6809e92736cef690e47dbbad05e1..4c9e6344e2ed138f1919e2f4c641a258f2ebb720 100755 (executable)
@@ -906,11 +906,24 @@ config SOC_CAMERA_OV9650
        depends on SOC_CAMERA && I2C
        help
          This is a ov2655 camera driver
+         
 config SOC_CAMERA_OV3640
        tristate "ov3640 camera support"
        depends on SOC_CAMERA && I2C
        help
-         This is a ov3640 camera driver
+         This is a ov3640 camera driver        
+choice
+       prompt "OV3640 Module Focus select"
+       depends on SOC_CAMERA_OV3640
+       default OV3640_AUTOFOCUS
+       ---help---
+               
+config OV3640_AUTOFOCUS
+       bool "OV3640 auto focus"
+
+config OV3640_FIXEDFOCUS
+       bool "OV3640 fixed focus"
+endchoice        
          
 config SOC_CAMERA_OV5642
        tristate "ov5642 camera support"
@@ -964,11 +977,43 @@ config SOC_CAMERA_GC0308
        depends on SOC_CAMERA && I2C
        help
          This is a GC0308 camera driver
+config SOC_CAMERA_GC0309
+       tristate "GC0309 support"
+       depends on SOC_CAMERA && I2C
+       help
+         This is a GC0309 camera driver          
+config SOC_CAMERA_GC2015
+       tristate "GC2015 support"
+       depends on SOC_CAMERA && I2C
+       help
+         This is a GC2015 camera driver         
+config SOC_CAMERA_HI253
+       tristate "HI253 support"
+       depends on SOC_CAMERA && I2C
+       help
+         This is a HI253 camera driver  
+config SOC_CAMERA_HI704
+       tristate "HI704 support"
+       depends on SOC_CAMERA && I2C
+       help
+         This is a HI704 camera driver
 config SOC_CAMERA_SIV120B
        tristate "siv120b support"
        depends on SOC_CAMERA && I2C
        help
          This is a SIV120B camera driver         
+
+config SOC_CAMERA_SID130B
+       tristate "sid130b support"
+       depends on SOC_CAMERA && I2C
+       help
+         This is a SID130B camera driver               
+
+config SOC_CAMERA_NT99250
+       tristate "NT99250 support"
+       depends on SOC_CAMERA && I2C
+       help
+         This is a NT99250 camera driver                   
             
 config MX1_VIDEO
        bool
index 18b0140a5db0a139789844132146aa65eba95e2d..ff5d986bbded4bd8773cdd92536a505e30523447 100755 (executable)
@@ -92,7 +92,13 @@ obj-$(CONFIG_SOC_CAMERA_OV5642)              += ov5642.o
 obj-$(CONFIG_SOC_CAMERA_S5K6AA)                += s5k6aa.o
 obj-$(CONFIG_SOC_CAMERA_GT2005)                += gt2005.o
 obj-$(CONFIG_SOC_CAMERA_GC0308)                += gc0308.o
+obj-$(CONFIG_SOC_CAMERA_GC0309)                += gc0309.o
+obj-$(CONFIG_SOC_CAMERA_GC2015)                += gc2015.o
 obj-$(CONFIG_SOC_CAMERA_SIV120B)       += siv120b.o
+obj-$(CONFIG_SOC_CAMERA_SID130B)       += sid130B.o
+obj-$(CONFIG_SOC_CAMERA_HI253) += hi253.o
+obj-$(CONFIG_SOC_CAMERA_HI704) += hi704.o
+obj-$(CONFIG_SOC_CAMERA_NT99250)       += nt99250.o
 # And now the v4l2 drivers:
 
 obj-$(CONFIG_VIDEO_BT848) += bt8xx/
diff --git a/drivers/media/video/gc0309.c b/drivers/media/video/gc0309.c
new file mode 100755 (executable)
index 0000000..3f55a02
--- /dev/null
@@ -0,0 +1,2449 @@
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <mach/rk29_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do {                       \
+       if (debug >= level)                                     \
+       printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
+
+
+#define _CONS(a,b) a##b
+#define CONS(a,b) _CONS(a,b)
+
+#define __STR(x) #x
+#define _STR(x) __STR(x)
+#define STR(x) _STR(x)
+
+#define MIN(x,y)   ((x<y) ? x: y)
+#define MAX(x,y)    ((x>y) ? x: y)
+
+/* Sensor Driver Configuration */
+#define SENSOR_NAME RK29_CAM_SENSOR_GC0309
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0309
+#define SENSOR_ID 0xa0
+#define SENSOR_MIN_WIDTH    176
+#define SENSOR_MIN_HEIGHT   144
+#define SENSOR_MAX_WIDTH    648
+#define SENSOR_MAX_HEIGHT   488
+#define SENSOR_INIT_WIDTH      648                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  488
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY
+
+#define CONFIG_SENSOR_WhiteBalance     1
+#define CONFIG_SENSOR_Brightness       0
+#define CONFIG_SENSOR_Contrast      0
+#define CONFIG_SENSOR_Saturation    0
+#define CONFIG_SENSOR_Effect        1
+#define CONFIG_SENSOR_Scene         1
+#define CONFIG_SENSOR_DigitalZoom   0
+#define CONFIG_SENSOR_Focus         0
+#define CONFIG_SENSOR_Exposure      0
+#define CONFIG_SENSOR_Flash         0
+#define CONFIG_SENSOR_Mirror        0
+#define CONFIG_SENSOR_Flip          0
+
+#define CONFIG_SENSOR_I2C_SPEED     100000       /* Hz */
+/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */
+#define CONFIG_SENSOR_I2C_NOSCHED   0
+#define CONFIG_SENSOR_I2C_RDWRCHK   0
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
+#define COLOR_TEMPERATURE_CLOUDY_DN  6500
+#define COLOR_TEMPERATURE_CLOUDY_UP    8000
+#define COLOR_TEMPERATURE_CLEARDAY_DN  5000
+#define COLOR_TEMPERATURE_CLEARDAY_UP    6500
+#define COLOR_TEMPERATURE_OFFICE_DN     3500
+#define COLOR_TEMPERATURE_OFFICE_UP     5000
+#define COLOR_TEMPERATURE_HOME_DN       2500
+#define COLOR_TEMPERATURE_HOME_UP       3500
+
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
+
+
+struct reginfo
+{
+    u8 reg;
+    u8 val;
+};
+
+/* init SVGA preview */
+static struct reginfo sensor_init_data[] =
+{
+         /*init registers code.*/
+
+{0xfe,0x80},   // soft reset   
+               
+//     GC0309_SET_PAGE0;       // set page0
+       
+{0x1a,0x16},           
+{0xd2,0x10},   // close AEC
+{0x22,0x55},   // close AWB
+
+{0x5a,0x56}, 
+{0x5b,0x40},
+{0x5c,0x4a},                   
+
+{0x22,0x57}, 
+               
+{0x01,0xfa}, 
+{0x02,0x70}, 
+{0x0f,0x01}, 
+
+{0xe2,0x00}, 
+{0xe3,0x64}, 
+
+{0x03,0x01}, 
+{0x04,0x2c}, 
+
+       /*
+{0x01,0x6a}, 
+{0x02,0x25}, 
+{0x0f,0x00},
+
+{0xe2,0x00}, 
+{0xe3,0x4b}, 
+               
+{0xe4,0x02}, 
+{0xe5,0x0d}, 
+{0xe6,0x02}, 
+{0xe7,0x0d}, 
+{0xe8,0x02}, 
+{0xe9,0x0d}, 
+{0xea,0x05}, 
+{0xeb,0xdc}, 
+       */
+
+{0x05,0x00},
+{0x06,0x00},
+{0x07,0x00}, 
+{0x08,0x00}, 
+{0x09,0x01}, 
+{0x0a,0xe8}, 
+{0x0b,0x02}, 
+{0x0c,0x88}, 
+{0x0d,0x02}, 
+{0x0e,0x02}, 
+{0x10,0x22}, 
+{0x11,0x0d}, 
+{0x12,0x2a}, 
+{0x13,0x00}, 
+//{0x14,0x10},         
+{0x15,0x0a}, 
+{0x16,0x05}, 
+{0x17,0x01}, 
+
+{0x1b,0x03}, 
+{0x1c,0xc1}, 
+{0x1d,0x08}, 
+{0x1e,0x20},
+{0x1f,0x16}, 
+
+{0x20,0xff}, 
+{0x21,0xf8}, 
+{0x24,0xa0}, 
+{0x25,0x0f},
+       //output sync_mode
+{0x26,0x03}, 
+{0x2f,0x01}, 
+       /////////////////////////////////////////////////////////////////////
+       /////////////////////////// grab_t ////////////////////////////////
+       /////////////////////////////////////////////////////////////////////
+{0x30,0xf7}, 
+{0x31,0x40},
+{0x32,0x00}, 
+{0x39,0x04}, 
+{0x3a,0x20}, 
+{0x3b,0x20}, 
+{0x3c,0x02}, 
+{0x3d,0x02}, 
+{0x3e,0x02},
+{0x3f,0x02}, 
+       
+       //gain
+{0x50,0x24}, 
+       
+{0x53,0x82}, 
+{0x54,0x80}, 
+{0x55,0x80}, 
+{0x56,0x82}, 
+       
+       /////////////////////////////////////////////////////////////////////
+       /////////////////////////// LSC_t  ////////////////////////////////
+       /////////////////////////////////////////////////////////////////////
+{0x8b,0x20}, 
+{0x8c,0x20}, 
+{0x8d,0x20}, 
+{0x8e,0x10}, 
+{0x8f,0x10}, 
+{0x90,0x10}, 
+{0x91,0x3c}, 
+{0x92,0x50}, 
+{0x5d,0x12}, 
+{0x5e,0x1a}, 
+{0x5f,0x24}, 
+       /////////////////////////////////////////////////////////////////////
+       /////////////////////////// DNDD_t  ///////////////////////////////
+       /////////////////////////////////////////////////////////////////////
+{0x60,0x07}, 
+{0x61,0x0e}, 
+{0x62,0x0c}, 
+{0x64,0x03}, 
+{0x66,0xe8}, 
+{0x67,0x86}, 
+{0x68,0xa2}, 
+       
+       /////////////////////////////////////////////////////////////////////
+       /////////////////////////// asde_t ///////////////////////////////
+       /////////////////////////////////////////////////////////////////////
+{0x69,0x20}, 
+{0x6a,0x0f}, 
+{0x6b,0x00}, 
+{0x6c,0x53}, 
+{0x6d,0x83}, 
+{0x6e,0xac}, 
+{0x6f,0xac}, 
+{0x70,0x15}, 
+{0x71,0x33}, 
+       /////////////////////////////////////////////////////////////////////
+       /////////////////////////// eeintp_t///////////////////////////////
+};
+
+
+/* 640X480 VGA */
+static struct reginfo sensor_vga[] =
+{
+{0x45 , 0x0f}, //output enable
+ {0x0,0x0}
+};
+
+/* 352X288 CIF */
+static struct reginfo sensor_cif[] =
+{};
+
+/* 320*240 QVGA */
+static  struct reginfo sensor_qvga[] =
+{};
+
+/* 176X144 QCIF*/
+static struct reginfo sensor_qcif[] =
+{};
+
+
+static  struct reginfo sensor_ClrFmt_YUYV[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_ClrFmt_UYVY[]=
+{
+
+    {0x00, 0x00}
+};
+
+#if CONFIG_SENSOR_WhiteBalance
+static  struct reginfo sensor_WhiteB_Auto[]=
+{
+
+    {0x00, 0x00}
+};
+/* Cloudy Colour Temperature : 6500K - 8000K  */
+static  struct reginfo sensor_WhiteB_Cloudy[]=
+{
+
+    {0x00, 0x00}
+};
+/* ClearDay Colour Temperature : 5000K - 6500K  */
+static  struct reginfo sensor_WhiteB_ClearDay[]=
+{
+    //Sunny
+
+    {0x00, 0x00}
+};
+/* Office Colour Temperature : 3500K - 5000K  */
+static  struct reginfo sensor_WhiteB_TungstenLamp1[]=
+{
+    //Office
+  
+    {0x00, 0x00}
+
+};
+/* Home Colour Temperature : 2500K - 3500K  */
+static  struct reginfo sensor_WhiteB_TungstenLamp2[]=
+{
+    //Home
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,
+    sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,
+};
+#endif
+
+#if CONFIG_SENSOR_Brightness
+static  struct reginfo sensor_Brightness0[]=
+{
+    // Brightness -2
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Brightness1[]=
+{
+    // Brightness -1
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Brightness2[]=
+{
+    //  Brightness 0
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Brightness3[]=
+{
+    // Brightness +1
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Brightness4[]=
+{
+    //  Brightness +2
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Brightness5[]=
+{
+    //  Brightness +3
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,
+    sensor_Brightness4, sensor_Brightness5,NULL,
+};
+
+#endif
+
+#if CONFIG_SENSOR_Effect
+static  struct reginfo sensor_Effect_Normal[] =
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Effect_WandB[] =
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Effect_Sepia[] =
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Effect_Negative[] =
+{
+    //Negative
+
+    {0x00, 0x00}
+};
+static  struct reginfo sensor_Effect_Bluish[] =
+{
+    // Bluish
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Effect_Green[] =
+{
+    //  Greenish
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,
+    sensor_Effect_Bluish, sensor_Effect_Green,NULL,
+};
+#endif
+#if CONFIG_SENSOR_Exposure
+static  struct reginfo sensor_Exposure0[]=
+{
+    //-3
+
+};
+
+static  struct reginfo sensor_Exposure1[]=
+{
+    //-2
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Exposure2[]=
+{
+    //-0.3EV
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Exposure3[]=
+{
+    //default
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Exposure4[]=
+{
+    // 1
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Exposure5[]=
+{
+    // 2
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Exposure6[]=
+{
+    // 3
+
+    {0x00, 0x00}
+};
+
+static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,
+    sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,
+};
+#endif
+#if CONFIG_SENSOR_Saturation
+static  struct reginfo sensor_Saturation0[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Saturation1[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Saturation2[]=
+{
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};
+
+#endif
+#if CONFIG_SENSOR_Contrast
+static  struct reginfo sensor_Contrast0[]=
+{
+    //Contrast -3
+  
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Contrast1[]=
+{
+    //Contrast -2
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Contrast2[]=
+{
+    // Contrast -1
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Contrast3[]=
+{
+    //Contrast 0
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Contrast4[]=
+{
+    //Contrast +1
+
+    {0x00, 0x00}
+};
+
+
+static  struct reginfo sensor_Contrast5[]=
+{
+    //Contrast +2
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Contrast6[]=
+{
+    //Contrast +3
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,
+    sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,
+};
+
+#endif
+#if CONFIG_SENSOR_Mirror
+static  struct reginfo sensor_MirrorOn[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_MirrorOff[]=
+{
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,};
+#endif
+#if CONFIG_SENSOR_Flip
+static  struct reginfo sensor_FlipOn[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_FlipOff[]=
+{
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,};
+
+#endif
+#if CONFIG_SENSOR_Scene
+static  struct reginfo sensor_SceneAuto[] =
+{
+#if 0                           /* ddl@rock-chips.com : */
+    {0x3014, 0x04},
+    {0x3015, 0x00},
+    {0x302e, 0x00},
+    {0x302d, 0x00},
+    {0x00, 0x00}
+#else
+
+    {0x00, 0x00}
+#endif
+};
+
+static  struct reginfo sensor_SceneNight[] =
+{
+#if 1
+    //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk
+
+    {0x00, 0x00}
+#else
+    //15fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,18Mhz pclk
+    {0x300e, 0x34},
+    {0x3011, 0x01},
+    {0x302c, 0x00},
+    {0x3071, 0x00},
+    {0x3070, 0x5d},
+    {0x301c, 0x05},
+    {0x3073, 0x00},
+    {0x3072, 0x4d},
+    {0x301d, 0x07},
+    {0x3014, 0x0c},
+    {0x3015, 0x50},
+    {0x302e, 0x00},
+    {0x302d, 0x00},
+#endif
+};
+static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};
+
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+static struct reginfo sensor_Zoom0[] =
+{
+    {0x0, 0x0},
+};
+
+static struct reginfo sensor_Zoom1[] =
+{
+     {0x0, 0x0},
+};
+
+static struct reginfo sensor_Zoom2[] =
+{
+    {0x0, 0x0},
+};
+
+
+static struct reginfo sensor_Zoom3[] =
+{
+    {0x0, 0x0},
+};
+static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};
+#endif
+static const struct v4l2_querymenu sensor_menus[] =
+{
+       #if CONFIG_SENSOR_WhiteBalance
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 0,  .name = "auto",  .reserved = 0, }, {  .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 1, .name = "incandescent",  .reserved = 0,},
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 2,  .name = "fluorescent", .reserved = 0,}, {  .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3,  .name = "daylight", .reserved = 0,},
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 4,  .name = "cloudy-daylight", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Effect
+    { .id = V4L2_CID_EFFECT,  .index = 0,  .name = "none",  .reserved = 0, }, {  .id = V4L2_CID_EFFECT,  .index = 1, .name = "mono",  .reserved = 0,},
+    { .id = V4L2_CID_EFFECT,  .index = 2,  .name = "negative", .reserved = 0,}, {  .id = V4L2_CID_EFFECT, .index = 3,  .name = "sepia", .reserved = 0,},
+    { .id = V4L2_CID_EFFECT,  .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT,  .index = 5,  .name = "aqua", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Scene
+    { .id = V4L2_CID_SCENE,  .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE,  .index = 1,  .name = "night", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Flash
+    { .id = V4L2_CID_FLASH,  .index = 0,  .name = "off",  .reserved = 0, }, {  .id = V4L2_CID_FLASH,  .index = 1, .name = "auto",  .reserved = 0,},
+    { .id = V4L2_CID_FLASH,  .index = 2,  .name = "on", .reserved = 0,}, {  .id = V4L2_CID_FLASH, .index = 3,  .name = "torch", .reserved = 0,},
+    #endif
+};
+
+static const struct v4l2_queryctrl sensor_controls[] =
+{
+       #if CONFIG_SENSOR_WhiteBalance
+    {
+        .id            = V4L2_CID_DO_WHITE_BALANCE,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "White Balance Control",
+        .minimum       = 0,
+        .maximum       = 4,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Brightness
+       {
+        .id            = V4L2_CID_BRIGHTNESS,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Brightness Control",
+        .minimum       = -3,
+        .maximum       = 2,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Effect
+       {
+        .id            = V4L2_CID_EFFECT,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Effect Control",
+        .minimum       = 0,
+        .maximum       = 5,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Exposure
+       {
+        .id            = V4L2_CID_EXPOSURE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Exposure Control",
+        .minimum       = 0,
+        .maximum       = 6,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Saturation
+       {
+        .id            = V4L2_CID_SATURATION,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Saturation Control",
+        .minimum       = 0,
+        .maximum       = 2,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Contrast
+       {
+        .id            = V4L2_CID_CONTRAST,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Contrast Control",
+        .minimum       = -3,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Mirror
+       {
+        .id            = V4L2_CID_HFLIP,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Mirror Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 1,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Flip
+       {
+        .id            = V4L2_CID_VFLIP,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Flip Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 1,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Scene
+    {
+        .id            = V4L2_CID_SCENE,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Scene Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_DigitalZoom
+    {
+        .id            = V4L2_CID_ZOOM_RELATIVE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "DigitalZoom Control",
+        .minimum       = -1,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }, {
+        .id            = V4L2_CID_ZOOM_ABSOLUTE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "DigitalZoom Control",
+        .minimum       = 0,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Focus
+       {
+        .id            = V4L2_CID_FOCUS_RELATIVE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Focus Control",
+        .minimum       = -1,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }, {
+        .id            = V4L2_CID_FOCUS_ABSOLUTE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Focus Control",
+        .minimum       = 0,
+        .maximum       = 255,
+        .step          = 1,
+        .default_value = 125,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Flash
+       {
+        .id            = V4L2_CID_FLASH,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Flash Control",
+        .minimum       = 0,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+};
+
+static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did);
+static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client);
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+static int sensor_g_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);
+static int sensor_s_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);
+static int sensor_resume(struct soc_camera_device *icd);
+static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+static int sensor_deactivate(struct i2c_client *client);
+
+static struct soc_camera_ops sensor_ops =
+{
+    .suspend                     = sensor_suspend,
+    .resume                       = sensor_resume,
+    .set_bus_param             = sensor_set_bus_param,
+    .query_bus_param   = sensor_query_bus_param,
+    .controls          = sensor_controls,
+    .menus                         = sensor_menus,
+    .num_controls              = ARRAY_SIZE(sensor_controls),
+    .num_menus         = ARRAY_SIZE(sensor_menus),
+};
+
+#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
+       { .name = _name, .depth = _depth, .fourcc = _fourcc, \
+       .colorspace = _colorspace }
+
+#define JPG_FMT(_name, _depth, _fourcc) \
+       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+
+static const struct soc_camera_data_format sensor_colour_formats[] = {
+       JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY),
+       JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),
+};
+
+typedef struct sensor_info_priv_s
+{
+    int whiteBalance;
+    int brightness;
+    int contrast;
+    int saturation;
+    int effect;
+    int scene;
+    int digitalzoom;
+    int focus;
+    int flash;
+    int exposure;
+       bool snap2preview;
+       bool video2preview;
+    unsigned char mirror;                                        /* HFLIP */
+    unsigned char flip;                                          /* VFLIP */
+    unsigned int winseqe_cur_addr;
+       unsigned int pixfmt;
+
+} sensor_info_priv_t;
+
+struct sensor
+{
+    struct v4l2_subdev subdev;
+    struct i2c_client *client;
+    sensor_info_priv_t info_priv;
+    int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */
+#if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_t tasklock_cnt;
+#endif
+       struct rk29camera_platform_data *sensor_io_request;
+    struct rk29camera_gpio_res *sensor_gpio_res;
+};
+
+static struct sensor* to_sensor(const struct i2c_client *client)
+{
+    return container_of(i2c_get_clientdata(client), struct sensor, subdev);
+}
+
+static int sensor_task_lock(struct i2c_client *client, int lock)
+{
+#if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
+    struct sensor *sensor = to_sensor(client);
+
+       if (lock) {
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
+                       preempt_disable();
+               }
+
+               atomic_add(1, &sensor->tasklock_cnt);
+       } else {
+               if (atomic_read(&sensor->tasklock_cnt) > 0) {
+                       atomic_sub(1, &sensor->tasklock_cnt);
+
+                       if (atomic_read(&sensor->tasklock_cnt) == 0)
+                               preempt_enable();
+               }
+       }
+#endif
+       return 0;
+sensor_task_lock_err:
+       return -1;
+}
+
+#if 0
+/* sensor register */
+static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+       int ret = 0;
+
+       ret = i2c_master_reg8_recv(client, reg, val, 1,  CONFIG_SENSOR_I2C_SPEED);
+
+       return (ret > 0)? 0 : ret;
+}
+
+static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
+{
+       int ret = 0;
+       
+       ret = i2c_master_reg8_send(client, reg, &val, 1, CONFIG_SENSOR_I2C_SPEED);
+
+       return (ret > 0)? 0 : ret;
+}
+#else
+static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
+{
+    int err,cnt;
+    u8 buf[2];
+    struct i2c_msg msg[1];
+
+    buf[0] = reg;
+    buf[1] = val;
+
+       if (reg == 0xfe)
+               mdelay(10);
+       
+    msg->addr = client->addr;
+    msg->flags = client->flags;
+    msg->buf = buf;
+    msg->len = sizeof(buf);
+    msg->scl_rate = CONFIG_SENSOR_I2C_SPEED;         /* ddl@rock-chips.com : 100kHz */
+    msg->read_type = 0;               /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */
+
+    cnt = 3;
+    err = -EAGAIN;
+
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+        err = i2c_transfer(client->adapter, msg, 1);
+
+        if (err >= 0) {
+            return 0;
+        } else {
+            SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);
+            udelay(10);
+        }
+    }
+
+    return err;
+}
+
+/* sensor register read */
+static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+    int err,cnt;
+    u8 buf[1];
+    struct i2c_msg msg[2];
+
+    buf[0] = reg ;
+
+    msg[0].addr = client->addr;
+    msg[0].flags = client->flags;
+    msg[0].buf = buf;
+    msg[0].len = sizeof(buf);
+    msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED;       /* ddl@rock-chips.com : 100kHz */
+    msg[0].read_type = 2;   /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */
+
+    msg[1].addr = client->addr;
+    msg[1].flags = client->flags|I2C_M_RD;
+    msg[1].buf = buf;
+    msg[1].len = 1;
+    msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED;                       /* ddl@rock-chips.com : 100kHz */
+    msg[1].read_type = 2;                             /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */
+
+    cnt = 3;
+    err = -EAGAIN;
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+        err = i2c_transfer(client->adapter, msg, 2);
+
+        if (err >= 0) {
+            *val = buf[0];
+            return 0;
+        } else {
+               SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val);
+            udelay(10);
+        }
+    }
+
+    return err;
+}
+
+#endif
+
+/* write a array of registers  */
+static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int err = 0, cnt;
+    int i = 0;
+       int j = 0;
+       char valchk;
+
+       cnt = 0;
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
+    while (regarray[i].reg != 0)
+    {
+        err = sensor_write(client, regarray[i].reg, regarray[i].val);
+        if (err < 0)
+        {
+            if (cnt-- > 0) {
+                           SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg);
+                               i = 0;
+                               continue;
+            } else {
+                SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING());
+                err = -EPERM;
+                               goto sensor_write_array_end;
+            }
+        } else {
+        #if CONFIG_SENSOR_I2C_RDWRCHK
+                       //mdelay(5);
+                       sensor_read(client, regarray[i].reg, &valchk);
+                       if (valchk != regarray[i].val)
+                               SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+               #endif
+        }
+        i++;
+    }
+
+sensor_write_array_end:
+       sensor_task_lock(client,0);
+       return err;
+}
+static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int cnt;
+    int i = 0;
+       char valchk;
+
+       cnt = 0;
+       valchk = 0;
+    while (regarray[i].reg != 0)
+    {
+               sensor_read(client, regarray[i].reg, &valchk);
+               if (valchk != regarray[i].val)
+                       SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+
+        i++;
+    }
+    return 0;
+}
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
+{
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       int ret = 0;
+
+    SENSOR_DG("%s %s  cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
+       switch (cmd)
+       {
+               case Sensor_PowerDown:
+               {
+                       if (icl->powerdown) {
+                               ret = icl->powerdown(icd->pdev, on);
+                               if (ret == RK29_CAM_IO_SUCCESS) {
+                                       if (on == 0) {
+                                               mdelay(2);
+                                               if (icl->reset)
+                                                       icl->reset(icd->pdev);
+                                       }
+                               } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {
+                                       ret = -ENODEV;
+                                       goto sensor_power_end;
+                               }
+                       }
+                       break;
+               }
+               case Sensor_Flash:
+               {
+                       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+               struct sensor *sensor = to_sensor(client);
+
+                       if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
+                               sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
+                       }
+            break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_power_end:
+       return ret;
+}
+static int sensor_init(struct v4l2_subdev *sd, u32 val)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl;
+    char value;
+    int ret;
+
+    SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
+
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_INIT_ERR;
+       }
+
+    /* soft reset */
+       if (sensor_task_lock(client,1)<0)
+               goto sensor_INIT_ERR;
+    ret = sensor_write(client, 0xfe, 0x80);
+    if (ret != 0)
+    {
+        SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING());
+        ret = -ENODEV;
+               goto sensor_INIT_ERR;
+    }
+
+    mdelay(5);  //delay 5 microseconds
+       /* check if it is an sensor sensor */
+    ret = sensor_read(client, 0x00, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id high byte failed\n");
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+       
+    if (value == SENSOR_ID) {
+        sensor->model = SENSOR_V4L2_IDENT;
+    } else {
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+
+    ret = sensor_write_array(client, sensor_init_data);
+    if (ret != 0)
+    {
+        SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
+        goto sensor_INIT_ERR;
+    }
+       sensor_task_lock(client,0);
+    //icd->user_width = SENSOR_INIT_WIDTH;
+    //icd->user_height = SENSOR_INIT_HEIGHT;
+    sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;
+       sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT;
+
+    /* sensor sensor information for initialization  */
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+       if (qctrl)
+       sensor->info_priv.whiteBalance = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS);
+       if (qctrl)
+       sensor->info_priv.brightness = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+       if (qctrl)
+       sensor->info_priv.effect = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE);
+       if (qctrl)
+        sensor->info_priv.exposure = qctrl->default_value;
+
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION);
+       if (qctrl)
+        sensor->info_priv.saturation = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST);
+       if (qctrl)
+        sensor->info_priv.contrast = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP);
+       if (qctrl)
+        sensor->info_priv.mirror = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP);
+       if (qctrl)
+        sensor->info_priv.flip = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE);
+       if (qctrl)
+        sensor->info_priv.scene = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);
+       if (qctrl)
+        sensor->info_priv.digitalzoom = qctrl->default_value;
+
+    /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code  */
+       #if CONFIG_SENSOR_Focus
+    sensor_set_focus();
+    qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);
+       if (qctrl)
+        sensor->info_priv.focus = qctrl->default_value;
+       #endif
+
+       #if CONFIG_SENSOR_Flash 
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);
+       if (qctrl)
+        sensor->info_priv.flash = qctrl->default_value;
+    #endif
+
+    SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);
+
+    return 0;
+sensor_INIT_ERR:
+       sensor_task_lock(client,0);
+       sensor_deactivate(client);
+    return ret;
+}
+
+static int sensor_deactivate(struct i2c_client *client)
+{
+       struct soc_camera_device *icd = client->dev.platform_data;
+
+       SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
+
+       /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);
+
+       /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
+       icd->user_width = SENSOR_INIT_WIDTH;
+    icd->user_height = SENSOR_INIT_HEIGHT;
+       msleep(100);
+       return 0;
+}
+
+static  struct reginfo sensor_power_down_sequence[]=
+{
+    {0x00,0x00}
+};
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
+{
+    int ret;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if (pm_msg.event == PM_EVENT_SUSPEND) {
+        SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());
+        ret = sensor_write_array(client, sensor_power_down_sequence) ;
+        if (ret != 0) {
+            SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);
+            return ret;
+        } else {
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);
+            if (ret < 0) {
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
+                return -EINVAL;
+            }
+        }
+    } else {
+        SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+    return 0;
+}
+
+static int sensor_resume(struct soc_camera_device *icd)
+{
+       int ret;
+
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);
+    if (ret < 0) {
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+       SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());
+
+    return 0;
+
+}
+
+static int sensor_set_bus_param(struct soc_camera_device *icd,
+                                unsigned long flags)
+{
+
+    return 0;
+}
+
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)
+{
+    struct soc_camera_link *icl = to_soc_camera_link(icd);
+    unsigned long flags = SENSOR_BUS_PARAM;
+
+    return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+
+    pix->width         = icd->user_width;
+    pix->height                = icd->user_height;
+    pix->pixelformat   = sensor->info_priv.pixfmt;
+    pix->field         = V4L2_FIELD_NONE;
+    pix->colorspace            = V4L2_COLORSPACE_JPEG;
+
+    return 0;
+}
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+       const struct v4l2_queryctrl *qctrl;
+       struct soc_camera_device *icd = client->dev.platform_data;
+    struct reginfo *winseqe_set_addr=NULL;
+    int ret=0, set_w,set_h;
+
+       SENSOR_TR("sensor_s_fmt\n");
+       if (sensor->info_priv.pixfmt != pix->pixelformat) {
+               switch (pix->pixelformat)
+               {
+                       case V4L2_PIX_FMT_YUYV:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_YUYV;
+                               break;
+                       }
+                       case V4L2_PIX_FMT_UYVY:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_UYVY;
+                               break;
+                       }
+                       default:
+                               break;
+               }
+               if (winseqe_set_addr != NULL) {
+            sensor_write_array(client, winseqe_set_addr);
+                       sensor->info_priv.pixfmt = pix->pixelformat;
+
+                       SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+               } else {
+                       SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+               }
+       }
+
+    set_w = pix->width;
+    set_h = pix->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+               winseqe_set_addr = sensor_qcif;
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        winseqe_set_addr = sensor_qvga;
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        winseqe_set_addr = sensor_cif;
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        winseqe_set_addr = sensor_vga;
+        set_w = 640;
+        set_h = 480;
+    }
+    
+    else
+    {
+        winseqe_set_addr = SENSOR_INIT_WINSEQADR;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;
+               ret = -1;
+               SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);
+    }
+
+    if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr) {
+        #if CONFIG_SENSOR_Flash
+        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_On);
+                SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
+            }           
+        } else {                                        /* ddl@rock-chips.com : Video */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());
+            }
+        }
+        #endif
+        ret |= sensor_write_array(client, winseqe_set_addr);
+        if (ret != 0) {
+            SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
+            #if CONFIG_SENSOR_Flash
+            if (sensor_fmt_capturechk(sd,f) == true) {
+                if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                    sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                    SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
+                }
+            }
+            #endif
+            goto sensor_s_fmt_end;
+        }
+
+        sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
+
+               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       if (sensor->info_priv.whiteBalance != 0) {
+                               qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                               sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       }
+                       sensor->info_priv.snap2preview = true;
+               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       sensor->info_priv.video2preview = true;
+               } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       sensor->info_priv.video2preview = false;
+                       sensor->info_priv.snap2preview = false;
+               }
+        SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
+    }
+    else
+    {
+        SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
+    }
+
+       pix->width = set_w;
+    pix->height = set_h;
+
+sensor_s_fmt_end:
+    return ret;
+}
+
+static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+    bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY ||
+        pix->pixelformat == V4L2_PIX_FMT_YUYV;
+
+    /*
+    * With Bayer format enforce even side lengths, but let the user play
+    * with the starting pixel
+    */
+
+    if (pix->height > SENSOR_MAX_HEIGHT)
+        pix->height = SENSOR_MAX_HEIGHT;
+    else if (pix->height < SENSOR_MIN_HEIGHT)
+        pix->height = SENSOR_MIN_HEIGHT;
+    else if (bayer)
+        pix->height = ALIGN(pix->height, 2);
+
+    if (pix->width > SENSOR_MAX_WIDTH)
+        pix->width = SENSOR_MAX_WIDTH;
+    else if (pix->width < SENSOR_MIN_WIDTH)
+        pix->width = SENSOR_MIN_WIDTH;
+    else if (bayer)
+        pix->width = ALIGN(pix->width, 2);
+
+    return 0;
+}
+
+ static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
+{
+    struct i2c_client *client = sd->priv;
+
+    if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
+        return -EINVAL;
+
+    if (id->match.addr != client->addr)
+        return -ENODEV;
+
+    id->ident = SENSOR_V4L2_IDENT;      /* ddl@rock-chips.com :  Return OV2655  identifier */
+    id->revision = 0;
+
+    return 0;
+}
+#if CONFIG_SENSOR_Brightness
+static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Effect
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_EffectSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Exposure
+static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Saturation
+static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Contrast
+static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Mirror
+static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Flip
+static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_FlipSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Scene
+static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_SceneSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl_info;
+    int digitalzoom_cur, digitalzoom_total;
+
+       qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);
+       if (qctrl_info)
+               return -EINVAL;
+
+    digitalzoom_cur = sensor->info_priv.digitalzoom;
+    digitalzoom_total = qctrl_info->maximum;
+
+    if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total))
+    {
+        SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
+        return -EINVAL;
+    }
+
+    if  ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum))
+    {
+        SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
+        return -EINVAL;
+    }
+
+    if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total))
+    {
+        *value = digitalzoom_total - digitalzoom_cur;
+    }
+
+    if ((*value < 0) && ((digitalzoom_cur + *value) < 0))
+    {
+        *value = 0 - digitalzoom_cur;
+    }
+
+    digitalzoom_cur += *value;
+
+    if (sensor_ZoomSeqe[digitalzoom_cur] != NULL)
+    {
+        if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0)
+        {
+            SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+            return -EINVAL;
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value);
+        return 0;
+    }
+
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Flash
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{    
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {
+        if (value == 3) {       /* ddl@rock-chips.com: torch */
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Torch);   /* Flash On */
+        } else {
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+        return 0;
+    }
+    
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct v4l2_queryctrl *qctrl;
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ctrl->id)
+    {
+        case V4L2_CID_BRIGHTNESS:
+            {
+                ctrl->value = sensor->info_priv.brightness;
+                break;
+            }
+        case V4L2_CID_SATURATION:
+            {
+                ctrl->value = sensor->info_priv.saturation;
+                break;
+            }
+        case V4L2_CID_CONTRAST:
+            {
+                ctrl->value = sensor->info_priv.contrast;
+                break;
+            }
+        case V4L2_CID_DO_WHITE_BALANCE:
+            {
+                ctrl->value = sensor->info_priv.whiteBalance;
+                break;
+            }
+        case V4L2_CID_EXPOSURE:
+            {
+                ctrl->value = sensor->info_priv.exposure;
+                break;
+            }
+        case V4L2_CID_HFLIP:
+            {
+                ctrl->value = sensor->info_priv.mirror;
+                break;
+            }
+        case V4L2_CID_VFLIP:
+            {
+                ctrl->value = sensor->info_priv.flip;
+                break;
+            }
+        default :
+                break;
+    }
+    return 0;
+}
+
+
+
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    struct soc_camera_device *icd = client->dev.platform_data;
+    const struct v4l2_queryctrl *qctrl;
+
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ctrl->id)
+    {
+#if CONFIG_SENSOR_Brightness
+        case V4L2_CID_BRIGHTNESS:
+            {
+                if (ctrl->value != sensor->info_priv.brightness)
+                {
+                    if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.brightness = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Exposure
+        case V4L2_CID_EXPOSURE:
+            {
+                if (ctrl->value != sensor->info_priv.exposure)
+                {
+                    if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.exposure = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Saturation
+        case V4L2_CID_SATURATION:
+            {
+                if (ctrl->value != sensor->info_priv.saturation)
+                {
+                    if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.saturation = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Contrast
+        case V4L2_CID_CONTRAST:
+            {
+                if (ctrl->value != sensor->info_priv.contrast)
+                {
+                    if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.contrast = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+        case V4L2_CID_DO_WHITE_BALANCE:
+            {
+                if (ctrl->value != sensor->info_priv.whiteBalance)
+                {
+                    if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.whiteBalance = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Mirror
+        case V4L2_CID_HFLIP:
+            {
+                if (ctrl->value != sensor->info_priv.mirror)
+                {
+                    if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.mirror = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Flip
+        case V4L2_CID_VFLIP:
+            {
+                if (ctrl->value != sensor->info_priv.flip)
+                {
+                    if (sensor_set_flip(icd, qctrl,ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.flip = ctrl->value;
+                }
+                break;
+            }
+#endif
+        default:
+            break;
+    }
+
+    return 0;
+}
+static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl)
+{
+    const struct v4l2_queryctrl *qctrl;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ext_ctrl->id)
+    {
+        case V4L2_CID_SCENE:
+            {
+                ext_ctrl->value = sensor->info_priv.scene;
+                break;
+            }
+        case V4L2_CID_EFFECT:
+            {
+                ext_ctrl->value = sensor->info_priv.effect;
+                break;
+            }
+        case V4L2_CID_ZOOM_ABSOLUTE:
+            {
+                ext_ctrl->value = sensor->info_priv.digitalzoom;
+                break;
+            }
+        case V4L2_CID_ZOOM_RELATIVE:
+            {
+                return -EINVAL;
+            }
+        case V4L2_CID_FOCUS_ABSOLUTE:
+            {
+                ext_ctrl->value = sensor->info_priv.focus;
+                break;
+            }
+        case V4L2_CID_FOCUS_RELATIVE:
+            {
+                return -EINVAL;
+            }
+        case V4L2_CID_FLASH:
+            {
+                ext_ctrl->value = sensor->info_priv.flash;
+                break;
+            }
+        default :
+            break;
+    }
+    return 0;
+}
+static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl)
+{
+    const struct v4l2_queryctrl *qctrl;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+    int val_offset;
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        return -EINVAL;
+    }
+
+       val_offset = 0;
+    switch (ext_ctrl->id)
+    {
+#if CONFIG_SENSOR_Scene
+        case V4L2_CID_SCENE:
+            {
+                if (ext_ctrl->value != sensor->info_priv.scene)
+                {
+                    if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.scene = ext_ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Effect
+        case V4L2_CID_EFFECT:
+            {
+                if (ext_ctrl->value != sensor->info_priv.effect)
+                {
+                    if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.effect= ext_ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+        case V4L2_CID_ZOOM_ABSOLUTE:
+            {
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
+
+                if (ext_ctrl->value != sensor->info_priv.digitalzoom)
+                {
+                    val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom;
+
+                    if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.digitalzoom += val_offset;
+
+                    SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(),  sensor->info_priv.digitalzoom);
+                }
+
+                break;
+            }
+        case V4L2_CID_ZOOM_RELATIVE:
+            {
+                if (ext_ctrl->value)
+                {
+                    if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.digitalzoom += ext_ctrl->value;
+
+                    SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom);
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Focus
+        case V4L2_CID_FOCUS_ABSOLUTE:
+            {
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
+
+                if (ext_ctrl->value != sensor->info_priv.focus)
+                {
+                    val_offset = ext_ctrl->value -sensor->info_priv.focus;
+
+                    sensor->info_priv.focus += val_offset;
+                }
+
+                break;
+            }
+        case V4L2_CID_FOCUS_RELATIVE:
+            {
+                if (ext_ctrl->value)
+                {
+                    sensor->info_priv.focus += ext_ctrl->value;
+
+                    SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus);
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Flash
+        case V4L2_CID_FLASH:
+            {
+                if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)
+                    return -EINVAL;
+                sensor->info_priv.flash = ext_ctrl->value;
+
+                SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);
+                break;
+            }
+#endif
+        default:
+            break;
+    }
+
+    return 0;
+}
+
+static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    int i, error_cnt=0, error_idx=-1;
+
+
+    for (i=0; i<ext_ctrl->count; i++) {
+        if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+            error_cnt++;
+            error_idx = i;
+        }
+    }
+
+    if (error_cnt > 1)
+        error_idx = ext_ctrl->count;
+
+    if (error_idx != -1) {
+        ext_ctrl->error_idx = error_idx;
+        return -EINVAL;
+    } else {
+        return 0;
+    }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    int i, error_cnt=0, error_idx=-1;
+
+
+    for (i=0; i<ext_ctrl->count; i++) {
+        if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+            error_cnt++;
+            error_idx = i;
+        }
+    }
+
+    if (error_cnt > 1)
+        error_idx = ext_ctrl->count;
+
+    if (error_idx != -1) {
+        ext_ctrl->error_idx = error_idx;
+        return -EINVAL;
+    } else {
+        return 0;
+    }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+                              struct i2c_client *client)
+{
+    char value;
+    int ret;
+    struct sensor *sensor = to_sensor(client);
+
+    /* We must have a parent by now. And it cannot be a wrong one.
+     * So this entire test is completely redundant. */
+    if (!icd->dev.parent ||
+           to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+               return -ENODEV;
+
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
+
+    /* soft reset */
+    ret = sensor_write(client, 0xfe, 0x80);
+    if (ret != 0)
+    {
+        SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
+        return -ENODEV;
+    }
+    mdelay(5);          //delay 5 microseconds
+
+    /* check if it is an sensor sensor */
+    ret = sensor_read(client, 0x00, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id high byte failed\n");
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+    if (value == SENSOR_ID) {
+        sensor->model = SENSOR_V4L2_IDENT;
+               SENSOR_TR("chip id:0x%x\n",value);
+    } else {
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+    icd->formats = sensor_colour_formats;
+    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
+
+    return 0;
+
+sensor_video_probe_err:
+
+    return ret;
+}
+static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+       struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    int ret = 0;
+#if CONFIG_SENSOR_Flash        
+    int i;
+#endif
+    
+       SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+       switch (cmd)
+       {
+               case RK29_CAM_SUBDEV_DEACTIVATE:
+               {
+                       sensor_deactivate(client);
+                       break;
+               }
+
+               case RK29_CAM_SUBDEV_IOREQUEST:
+               {
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
+            /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
+               for this project */
+            #if CONFIG_SENSOR_Flash    
+               if (sensor->sensor_gpio_res) { 
+                if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {
+                    for (i = 0; i < icd->ops->num_controls; i++) {
+                               if (V4L2_CID_FLASH == icd->ops->controls[i].id) {
+                                       memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                       
+                               }
+                    }
+                    sensor->info_priv.flash = 0xff;
+                    SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());
+                }
+               }
+            #endif
+                       break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_ioctl_end:
+       return ret;
+
+}
+static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
+       .init           = sensor_init,
+       .g_ctrl         = sensor_g_control,
+       .s_ctrl         = sensor_s_control,
+       .g_ext_ctrls          = sensor_g_ext_controls,
+       .s_ext_ctrls          = sensor_s_ext_controls,
+       .g_chip_ident   = sensor_g_chip_ident,
+       .ioctl = sensor_ioctl,
+};
+
+static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {
+       .s_fmt          = sensor_s_fmt,
+       .g_fmt          = sensor_g_fmt,
+       .try_fmt        = sensor_try_fmt,
+};
+
+static struct v4l2_subdev_ops sensor_subdev_ops = {
+       .core   = &sensor_subdev_core_ops,
+       .video = &sensor_subdev_video_ops,
+};
+
+static int sensor_probe(struct i2c_client *client,
+                        const struct i2c_device_id *did)
+{
+    struct sensor *sensor;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+    struct soc_camera_link *icl;
+    int ret;
+
+    SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__);
+    if (!icd) {
+        dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+    icl = to_soc_camera_link(icd);
+    if (!icl) {
+        dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+    if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+        dev_warn(&adapter->dev,
+                "I2C-Adapter doesn't support I2C_FUNC_I2C\n");
+        return -EIO;
+    }
+
+    sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL);
+    if (!sensor)
+        return -ENOMEM;
+
+    v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops);
+
+    /* Second stage probe - when a capture adapter is there */
+    icd->ops           = &sensor_ops;
+    icd->y_skip_top            = 0;
+       #if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_set(&sensor->tasklock_cnt,0);
+       #endif
+
+    ret = sensor_video_probe(icd, client);
+    if (ret < 0) {
+        icd->ops = NULL;
+        i2c_set_clientdata(client, NULL);
+        kfree(sensor);
+               sensor = NULL;
+    }
+    SENSOR_DG("\n%s..%s..%d  ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);
+    return ret;
+}
+
+static int sensor_remove(struct i2c_client *client)
+{
+    struct sensor *sensor = to_sensor(client);
+    struct soc_camera_device *icd = client->dev.platform_data;
+
+    icd->ops = NULL;
+    i2c_set_clientdata(client, NULL);
+    client->driver = NULL;
+    kfree(sensor);
+       sensor = NULL;
+    return 0;
+}
+
+static const struct i2c_device_id sensor_id[] = {
+       {SENSOR_NAME_STRING(), 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, sensor_id);
+
+static struct i2c_driver sensor_i2c_driver = {
+       .driver = {
+               .name = SENSOR_NAME_STRING(),
+       },
+       .probe          = sensor_probe,
+       .remove         = sensor_remove,
+       .id_table       = sensor_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+    SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING());
+    return i2c_add_driver(&sensor_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+    i2c_del_driver(&sensor_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));
+MODULE_AUTHOR("ddl <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
+
+
diff --git a/drivers/media/video/gc2015.c b/drivers/media/video/gc2015.c
new file mode 100755 (executable)
index 0000000..2182563
--- /dev/null
@@ -0,0 +1,2655 @@
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <mach/rk29_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do {                       \
+       if (debug >= level)                                     \
+       printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
+
+
+#define _CONS(a,b) a##b
+#define CONS(a,b) _CONS(a,b)
+
+#define __STR(x) #x
+#define _STR(x) __STR(x)
+#define STR(x) _STR(x)
+
+#define MIN(x,y)   ((x<y) ? x: y)
+#define MAX(x,y)    ((x>y) ? x: y)
+
+/* Sensor Driver Configuration */
+#define SENSOR_NAME RK29_CAM_SENSOR_GC2015
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2015
+#define SENSOR_ID 0x2005
+#define SENSOR_MIN_WIDTH    176
+#define SENSOR_MIN_HEIGHT   144
+#define SENSOR_MAX_WIDTH    1600
+#define SENSOR_MAX_HEIGHT   1200
+#define SENSOR_INIT_WIDTH      1024                    /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  768
+#define SENSOR_INIT_WINSEQADR sensor_svga
+#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY
+
+#define CONFIG_SENSOR_WhiteBalance     1
+#define CONFIG_SENSOR_Brightness       0
+#define CONFIG_SENSOR_Contrast      0
+#define CONFIG_SENSOR_Saturation    0
+#define CONFIG_SENSOR_Effect        1
+#define CONFIG_SENSOR_Scene         1
+#define CONFIG_SENSOR_DigitalZoom   0
+#define CONFIG_SENSOR_Focus         0
+#define CONFIG_SENSOR_Exposure      0
+#define CONFIG_SENSOR_Flash         0
+#define CONFIG_SENSOR_Mirror        0
+#define CONFIG_SENSOR_Flip          0
+
+#define CONFIG_SENSOR_I2C_SPEED     100000       /* Hz */
+/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */
+#define CONFIG_SENSOR_I2C_NOSCHED   0
+#define CONFIG_SENSOR_I2C_RDWRCHK   0
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
+#define COLOR_TEMPERATURE_CLOUDY_DN  6500
+#define COLOR_TEMPERATURE_CLOUDY_UP    8000
+#define COLOR_TEMPERATURE_CLEARDAY_DN  5000
+#define COLOR_TEMPERATURE_CLEARDAY_UP    6500
+#define COLOR_TEMPERATURE_OFFICE_DN     3500
+#define COLOR_TEMPERATURE_OFFICE_UP     5000
+#define COLOR_TEMPERATURE_HOME_DN       2500
+#define COLOR_TEMPERATURE_HOME_UP       3500
+
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
+
+
+struct reginfo
+{
+    u8 reg;
+    u8 val;
+};
+
+/* init SVGA preview */
+static struct reginfo sensor_init_data[] =
+{
+//{0xfe , 0x80}, //soft reset
+{0x45 , 0x00}, //output_enable
+       //////////////////////////////////////////////////////////////////////////////////////
+       //////////////////////////preview capture switch /////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////
+       //preview
+{0x02 , 0x01}, //preview mode
+{0x2a , 0xca}, //[7]col_binning , 0x[6]even skip
+{0x48 , 0x40}, //manual_gain
+
+       ////////////////////////////////////////////////////////////////////////
+       ////////////////////////// preview LSC /////////////////////////////////
+       ////////////////////////////////////////////////////////////////////////
+       
+{0xb0 , 0x13}, //[4]Y_LSC_en [3]lsc_compensate [2]signed_b4 [1:0]pixel array select
+{0xb1 , 0x20}, //P_LSC_red_b2
+{0xb2 , 0x20}, //P_LSC_green_b2
+{0xb3 , 0x20}, //P_LSC_blue_b2
+{0xb4 , 0x20}, //P_LSC_red_b4
+{0xb5 , 0x20}, //P_LSC_green_b4
+{0xb6 , 0x20}, //P_LSC_blue_b4
+{0xb7 , 0x00}, //P_LSC_compensate_b2
+{0xb8 , 0x80}, //P_LSC_row_center , 0x344 , 0x (0x600/2-100)/2=100
+{0xb9 , 0x80}, //P_LSC_col_center , 0x544 , 0x (0x800/2-200)/2=100
+
+       ////////////////////////////////////////////////////////////////////////
+       ////////////////////////// capture LSC ///////////////////////////
+       ////////////////////////////////////////////////////////////////////////
+{0xba , 0x13}, //[4]Y_LSC_en [3]lsc_compensate [2]signed_b4 [1:0]pixel array select
+{0xbb , 0x20}, //C_LSC_red_b2
+{0xbc , 0x20}, //C_LSC_green_b2
+{0xbd , 0x20}, //C_LSC_blue_b2
+{0xbe , 0x20}, //C_LSC_red_b4
+{0xbf , 0x20}, //C_LSC_green_b4
+{0xc0 , 0x20}, //C_LSC_blue_b4
+{0xc1 , 0x00}, //C_Lsc_compensate_b2
+{0xc2 , 0x80}, //C_LSC_row_center , 0x344 , 0x (0x1200/2-344)/2=128
+{0xc3 , 0x80}, //C_LSC_col_center , 0x544 , 0x (0x1600/2-544)/2=128
+
+       //GC2015_SET_PAGE0; //page0
+
+       ////////////////////////////////////////////////////////////////////////
+       ////////////////////////// analog configure ///////////////////////////
+       ////////////////////////////////////////////////////////////////////////
+{0x29 , 0x00}, //cisctl mode 1
+{0x2b , 0x06}, //cisctl mode 3 
+{0x32 , 0x0c}, //analog mode 1
+{0x33 , 0x0f}, //analog mode 2
+{0x34 , 0x00}, //[6:4]da_rsg
+       
+{0x35 , 0x88}, //Vref_A25
+{0x37 , 0x16}, //Drive Current
+
+       /////////////////////////////////////////////////////////////////////
+       ///////////////////////////ISP Related//////////////////////////////
+       /////////////////////////////////////////////////////////////////////
+{0x40 , 0xff}, 
+{0x41 , 0x24}, //[5]skin_detectionenable[2]auto_gray , 0x[1]y_gamma
+{0x42 , 0x76}, //[7]auto_sa[6]auto_ee[5]auto_dndd[4]auto_lsc[3]na[2]abs , 0x[1]awb
+{0x4b , 0xea}, //[1]AWB_gain_mode , 0x1:atpregain0:atpostgain
+{0x4d , 0x03}, //[1]inbf_en
+{0x4f , 0x01}, //AEC enable
+
+       ////////////////////////////////////////////////////////////////////
+       /////////////////////////// BLK  ///////////////////////////////////
+       ////////////////////////////////////////////////////////////////////
+{0x63 , 0x77}, //BLK mode 1
+{0x66 , 0x00}, //BLK global offset
+{0x6d , 0x04}, 
+{0x6e , 0x18}, //BLK offset submode,offset R
+{0x6f , 0x10},
+{0x70 , 0x18},
+{0x71 , 0x10},
+{0x73 , 0x03}, 
+
+
+       ////////////////////////////////////////////////////////////////////
+       /////////////////////////// DNDD ////////////////////////////////
+       ////////////////////////////////////////////////////////////////////
+{0x80 , 0x07}, //[7]dn_inc_or_dec [4]zero_weight_mode[3]share [2]c_weight_adap [1]dn_lsc_mode [0]dn_b
+{0x82 , 0x08}, //DN lilat b base
+
+       ////////////////////////////////////////////////////////////////////
+       /////////////////////////// EEINTP ////////////////////////////////
+       ////////////////////////////////////////////////////////////////////
+{0x8a , 0x7c},
+{0x8c , 0x02},
+{0x8e , 0x02},
+{0x8f , 0x48},
+
+       /////////////////////////////////////////////////////////////////////
+       /////////////////////////// CC_t ///////////////////////////////
+       /////////////////////////////////////////////////////////////////////
+{0xb0 , 0x44},
+{0xb1 , 0xfe},
+{0xb2 , 0x00},
+{0xb3 , 0xf8},
+{0xb4 , 0x48},
+{0xb5 , 0xf8},
+{0xb6 , 0x00},
+{0xb7 , 0x04},
+{0xb8 , 0x00},
+
+       /////////////////////////////////////////////////////////////////////
+       /////////////////////////// GAMMA ///////////////////////////////////
+       /////////////////////////////////////////////////////////////////////
+       //RGB_GAMMA
+{0xbf , 0x0e},
+{0xc0 , 0x1c},
+{0xc1 , 0x34},
+{0xc2 , 0x48},
+{0xc3 , 0x5a},
+{0xc4 , 0x6b},
+{0xc5 , 0x7b},
+{0xc6 , 0x95},
+{0xc7 , 0xab},
+{0xc8 , 0xbf},
+{0xc9 , 0xce},
+{0xca , 0xd9},
+{0xcb , 0xe4},
+{0xcc , 0xec},
+{0xcd , 0xf7},
+{0xce , 0xfd},
+{0xcf , 0xff},
+
+       /////////////////////////////////////////////////////////////////////
+       /////////////////////////// YCP_t  ///////////////////////////////
+       /////////////////////////////////////////////////////////////////////
+{0xd1 , 0x38}, //saturation
+{0xd2 , 0x38}, //saturation
+{0xde , 0x21}, //auto_gray
+
+       ////////////////////////////////////////////////////////////////////
+       /////////////////////////// ASDE ////////////////////////////////
+       ////////////////////////////////////////////////////////////////////
+{0x98 , 0x30},
+{0x99 , 0xf0},
+{0x9b , 0x00},
+
+       //GC2015_SET_PAGE1; //page1
+       ////////////////////////////////////////////////////////////////////
+       /////////////////////////// AEC  ////////////////////////////////
+       ////////////////////////////////////////////////////////////////////
+{0x10 , 0x45}, //AEC mode 1
+{0x11 , 0x32}, //[7]fix target
+{0x13 , 0x60},
+{0x17 , 0x00},
+{0x1c , 0x96},
+{0x1e , 0x11},
+{0x21 , 0xc0}, //max_post_gain
+{0x22 , 0x40}, //max_pre_gain
+{0x2d , 0x06}, //P_N_AEC_exp_level_1[12:8]
+{0x2e , 0x00}, //P_N_AEC_exp_level_1[7:0]
+{0x1e , 0x32},
+{0x33 , 0x00}, //[6:5]max_exp_level [4:0]min_exp_level
+
+       ////////////////////////////////////////////////////////////////////
+       ///////////////////////////  AWB  ////////////////////////////////
+       ////////////////////////////////////////////////////////////////////
+{0x57 , 0x40}, //number limit
+{0x5d , 0x44}, //
+{0x5c , 0x35}, //show mode,close dark_mode
+{0x5e , 0x29}, //close color temp
+{0x5f , 0x50},
+{0x60 , 0x50}, 
+{0x65 , 0xc0},
+
+       ////////////////////////////////////////////////////////////////////
+       ///////////////////////////  ABS  ////////////////////////////////
+       ////////////////////////////////////////////////////////////////////
+{0x80 , 0x82},
+{0x81 , 0x00},
+{0x83 , 0x00}, //ABS Y stretch limit
+
+       //GC2015_SET_PAGE0;
+
+       //////////////////////////////////////////////////////////////////////////////////////
+       ///////////////////////////// Crop //////////////////////////////////////////////////
+       //////////////////////////////////////////////////////////////////////////////////////
+{0x50 , 0x01},//out window
+{0x51 , 0x00},
+{0x52 , 0x00},
+{0x53 , 0x00},
+{0x54 , 0x00},
+{0x55 , 0x02},
+{0x56 , 0x58},
+{0x57 , 0x03},
+{0x58 , 0x20},
+
+       ////////////////////////////////////////////////////////////////////
+       ///////////////////////////  OUT  ////////////////////////////////
+       ////////////////////////////////////////////////////////////////////
+{0x44 , 0xa0}, //YUV sequence
+{0x45 , 0x0f}, //output enable
+{0x46 , 0x02}, //sync mode
+};
+
+/* 1600X1200 UXGA capture */
+static struct reginfo sensor_uxga[] =
+{
+{0x45 , 0x0f}, //output enable
+ {0x0,0x0}
+};
+
+/* 1280X1024 SXGA */
+static struct reginfo sensor_sxga[] =
+{
+  {0x0, 0x0}
+};
+static struct reginfo sensor_xga[] =
+{
+       {0x0, 0x0}
+};
+/* 800X600 SVGA,30fps*/
+static struct reginfo sensor_svga[] =
+{
+{0x45 , 0x0f}, //output enable
+ {0x0,0x0}
+};
+
+/* 640X480 VGA */
+static struct reginfo sensor_vga[] =
+{
+{0x45 , 0x0f}, //output enable
+ {0x0,0x0}
+};
+
+/* 352X288 CIF */
+static struct reginfo sensor_cif[] =
+{};
+
+/* 320*240 QVGA */
+static  struct reginfo sensor_qvga[] =
+{};
+
+/* 176X144 QCIF*/
+static struct reginfo sensor_qcif[] =
+{};
+#if 0
+/* 160X120 QQVGA*/
+static struct reginfo ov2655_qqvga[] =
+{
+
+    {0x300E, 0x34},
+    {0x3011, 0x01},
+    {0x3012, 0x10},
+    {0x302a, 0x02},
+    {0x302b, 0xE6},
+    {0x306f, 0x14},
+    {0x3362, 0x90},
+
+    {0x3070, 0x5d},
+    {0x3072, 0x5d},
+    {0x301c, 0x07},
+    {0x301d, 0x07},
+
+    {0x3020, 0x01},
+    {0x3021, 0x18},
+    {0x3022, 0x00},
+    {0x3023, 0x06},
+    {0x3024, 0x06},
+    {0x3025, 0x58},
+    {0x3026, 0x02},
+    {0x3027, 0x61},
+    {0x3088, 0x00},
+    {0x3089, 0xa0},
+    {0x308a, 0x00},
+    {0x308b, 0x78},
+    {0x3316, 0x64},
+    {0x3317, 0x25},
+    {0x3318, 0x80},
+    {0x3319, 0x08},
+    {0x331a, 0x0a},
+    {0x331b, 0x07},
+    {0x331c, 0x80},
+    {0x331d, 0x38},
+    {0x3100, 0x00},
+    {0x3302, 0x11},
+
+    {0x0, 0x0},
+};
+
+
+
+static  struct reginfo ov2655_Sharpness_auto[] =
+{
+    {0x3306, 0x00},
+};
+
+static  struct reginfo ov2655_Sharpness1[] =
+{
+    {0x3306, 0x08},
+    {0x3371, 0x00},
+};
+
+static  struct reginfo ov2655_Sharpness2[][3] =
+{
+    //Sharpness 2
+    {0x3306, 0x08},
+    {0x3371, 0x01},
+};
+
+static  struct reginfo ov2655_Sharpness3[] =
+{
+    //default
+    {0x3306, 0x08},
+    {0x332d, 0x02},
+};
+static  struct reginfo ov2655_Sharpness4[]=
+{
+    //Sharpness 4
+    {0x3306, 0x08},
+    {0x332d, 0x03},
+};
+
+static  struct reginfo ov2655_Sharpness5[] =
+{
+    //Sharpness 5
+    {0x3306, 0x08},
+    {0x332d, 0x04},
+};
+#endif
+
+static  struct reginfo sensor_ClrFmt_YUYV[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_ClrFmt_UYVY[]=
+{
+
+    {0x00, 0x00}
+};
+
+#if CONFIG_SENSOR_WhiteBalance
+static  struct reginfo sensor_WhiteB_Auto[]=
+{
+
+    {0x00, 0x00}
+};
+/* Cloudy Colour Temperature : 6500K - 8000K  */
+static  struct reginfo sensor_WhiteB_Cloudy[]=
+{
+
+    {0x00, 0x00}
+};
+/* ClearDay Colour Temperature : 5000K - 6500K  */
+static  struct reginfo sensor_WhiteB_ClearDay[]=
+{
+    //Sunny
+
+    {0x00, 0x00}
+};
+/* Office Colour Temperature : 3500K - 5000K  */
+static  struct reginfo sensor_WhiteB_TungstenLamp1[]=
+{
+    //Office
+  
+    {0x00, 0x00}
+
+};
+/* Home Colour Temperature : 2500K - 3500K  */
+static  struct reginfo sensor_WhiteB_TungstenLamp2[]=
+{
+    //Home
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,
+    sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,
+};
+#endif
+
+#if CONFIG_SENSOR_Brightness
+static  struct reginfo sensor_Brightness0[]=
+{
+    // Brightness -2
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Brightness1[]=
+{
+    // Brightness -1
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Brightness2[]=
+{
+    //  Brightness 0
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Brightness3[]=
+{
+    // Brightness +1
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Brightness4[]=
+{
+    //  Brightness +2
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Brightness5[]=
+{
+    //  Brightness +3
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,
+    sensor_Brightness4, sensor_Brightness5,NULL,
+};
+
+#endif
+
+#if CONFIG_SENSOR_Effect
+static  struct reginfo sensor_Effect_Normal[] =
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Effect_WandB[] =
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Effect_Sepia[] =
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Effect_Negative[] =
+{
+    //Negative
+
+    {0x00, 0x00}
+};
+static  struct reginfo sensor_Effect_Bluish[] =
+{
+    // Bluish
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Effect_Green[] =
+{
+    //  Greenish
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,
+    sensor_Effect_Bluish, sensor_Effect_Green,NULL,
+};
+#endif
+#if CONFIG_SENSOR_Exposure
+static  struct reginfo sensor_Exposure0[]=
+{
+    //-3
+
+};
+
+static  struct reginfo sensor_Exposure1[]=
+{
+    //-2
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Exposure2[]=
+{
+    //-0.3EV
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Exposure3[]=
+{
+    //default
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Exposure4[]=
+{
+    // 1
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Exposure5[]=
+{
+    // 2
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Exposure6[]=
+{
+    // 3
+
+    {0x00, 0x00}
+};
+
+static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,
+    sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,
+};
+#endif
+#if CONFIG_SENSOR_Saturation
+static  struct reginfo sensor_Saturation0[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Saturation1[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Saturation2[]=
+{
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};
+
+#endif
+#if CONFIG_SENSOR_Contrast
+static  struct reginfo sensor_Contrast0[]=
+{
+    //Contrast -3
+  
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Contrast1[]=
+{
+    //Contrast -2
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Contrast2[]=
+{
+    // Contrast -1
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Contrast3[]=
+{
+    //Contrast 0
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Contrast4[]=
+{
+    //Contrast +1
+
+    {0x00, 0x00}
+};
+
+
+static  struct reginfo sensor_Contrast5[]=
+{
+    //Contrast +2
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_Contrast6[]=
+{
+    //Contrast +3
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,
+    sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,
+};
+
+#endif
+#if CONFIG_SENSOR_Mirror
+static  struct reginfo sensor_MirrorOn[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_MirrorOff[]=
+{
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,};
+#endif
+#if CONFIG_SENSOR_Flip
+static  struct reginfo sensor_FlipOn[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_FlipOff[]=
+{
+
+    {0x00, 0x00}
+};
+static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,};
+
+#endif
+#if CONFIG_SENSOR_Scene
+static  struct reginfo sensor_SceneAuto[] =
+{
+#if 0                           /* ddl@rock-chips.com : */
+    {0x3014, 0x04},
+    {0x3015, 0x00},
+    {0x302e, 0x00},
+    {0x302d, 0x00},
+    {0x00, 0x00}
+#else
+
+    {0x00, 0x00}
+#endif
+};
+
+static  struct reginfo sensor_SceneNight[] =
+{
+#if 1
+    //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk
+
+    {0x00, 0x00}
+#else
+    //15fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,18Mhz pclk
+    {0x300e, 0x34},
+    {0x3011, 0x01},
+    {0x302c, 0x00},
+    {0x3071, 0x00},
+    {0x3070, 0x5d},
+    {0x301c, 0x05},
+    {0x3073, 0x00},
+    {0x3072, 0x4d},
+    {0x301d, 0x07},
+    {0x3014, 0x0c},
+    {0x3015, 0x50},
+    {0x302e, 0x00},
+    {0x302d, 0x00},
+#endif
+};
+static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};
+
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+static struct reginfo sensor_Zoom0[] =
+{
+    {0x0, 0x0},
+};
+
+static struct reginfo sensor_Zoom1[] =
+{
+     {0x0, 0x0},
+};
+
+static struct reginfo sensor_Zoom2[] =
+{
+    {0x0, 0x0},
+};
+
+
+static struct reginfo sensor_Zoom3[] =
+{
+    {0x0, 0x0},
+};
+static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};
+#endif
+static const struct v4l2_querymenu sensor_menus[] =
+{
+       #if CONFIG_SENSOR_WhiteBalance
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 0,  .name = "auto",  .reserved = 0, }, {  .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 1, .name = "incandescent",  .reserved = 0,},
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 2,  .name = "fluorescent", .reserved = 0,}, {  .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3,  .name = "daylight", .reserved = 0,},
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 4,  .name = "cloudy-daylight", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Effect
+    { .id = V4L2_CID_EFFECT,  .index = 0,  .name = "none",  .reserved = 0, }, {  .id = V4L2_CID_EFFECT,  .index = 1, .name = "mono",  .reserved = 0,},
+    { .id = V4L2_CID_EFFECT,  .index = 2,  .name = "negative", .reserved = 0,}, {  .id = V4L2_CID_EFFECT, .index = 3,  .name = "sepia", .reserved = 0,},
+    { .id = V4L2_CID_EFFECT,  .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT,  .index = 5,  .name = "aqua", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Scene
+    { .id = V4L2_CID_SCENE,  .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE,  .index = 1,  .name = "night", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Flash
+    { .id = V4L2_CID_FLASH,  .index = 0,  .name = "off",  .reserved = 0, }, {  .id = V4L2_CID_FLASH,  .index = 1, .name = "auto",  .reserved = 0,},
+    { .id = V4L2_CID_FLASH,  .index = 2,  .name = "on", .reserved = 0,}, {  .id = V4L2_CID_FLASH, .index = 3,  .name = "torch", .reserved = 0,},
+    #endif
+};
+
+static const struct v4l2_queryctrl sensor_controls[] =
+{
+       #if CONFIG_SENSOR_WhiteBalance
+    {
+        .id            = V4L2_CID_DO_WHITE_BALANCE,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "White Balance Control",
+        .minimum       = 0,
+        .maximum       = 4,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Brightness
+       {
+        .id            = V4L2_CID_BRIGHTNESS,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Brightness Control",
+        .minimum       = -3,
+        .maximum       = 2,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Effect
+       {
+        .id            = V4L2_CID_EFFECT,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Effect Control",
+        .minimum       = 0,
+        .maximum       = 5,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Exposure
+       {
+        .id            = V4L2_CID_EXPOSURE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Exposure Control",
+        .minimum       = 0,
+        .maximum       = 6,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Saturation
+       {
+        .id            = V4L2_CID_SATURATION,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Saturation Control",
+        .minimum       = 0,
+        .maximum       = 2,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Contrast
+       {
+        .id            = V4L2_CID_CONTRAST,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Contrast Control",
+        .minimum       = -3,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Mirror
+       {
+        .id            = V4L2_CID_HFLIP,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Mirror Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 1,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Flip
+       {
+        .id            = V4L2_CID_VFLIP,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Flip Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 1,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Scene
+    {
+        .id            = V4L2_CID_SCENE,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Scene Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_DigitalZoom
+    {
+        .id            = V4L2_CID_ZOOM_RELATIVE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "DigitalZoom Control",
+        .minimum       = -1,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }, {
+        .id            = V4L2_CID_ZOOM_ABSOLUTE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "DigitalZoom Control",
+        .minimum       = 0,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Focus
+       {
+        .id            = V4L2_CID_FOCUS_RELATIVE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Focus Control",
+        .minimum       = -1,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }, {
+        .id            = V4L2_CID_FOCUS_ABSOLUTE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Focus Control",
+        .minimum       = 0,
+        .maximum       = 255,
+        .step          = 1,
+        .default_value = 125,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Flash
+       {
+        .id            = V4L2_CID_FLASH,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Flash Control",
+        .minimum       = 0,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+};
+
+static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did);
+static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client);
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+static int sensor_g_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);
+static int sensor_s_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);
+static int sensor_resume(struct soc_camera_device *icd);
+static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+static int sensor_deactivate(struct i2c_client *client);
+
+static struct soc_camera_ops sensor_ops =
+{
+    .suspend                     = sensor_suspend,
+    .resume                       = sensor_resume,
+    .set_bus_param             = sensor_set_bus_param,
+    .query_bus_param   = sensor_query_bus_param,
+    .controls          = sensor_controls,
+    .menus                         = sensor_menus,
+    .num_controls              = ARRAY_SIZE(sensor_controls),
+    .num_menus         = ARRAY_SIZE(sensor_menus),
+};
+
+#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
+       { .name = _name, .depth = _depth, .fourcc = _fourcc, \
+       .colorspace = _colorspace }
+
+#define JPG_FMT(_name, _depth, _fourcc) \
+       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+
+static const struct soc_camera_data_format sensor_colour_formats[] = {
+       JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY),
+       JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),
+};
+
+typedef struct sensor_info_priv_s
+{
+    int whiteBalance;
+    int brightness;
+    int contrast;
+    int saturation;
+    int effect;
+    int scene;
+    int digitalzoom;
+    int focus;
+    int flash;
+    int exposure;
+       bool snap2preview;
+       bool video2preview;
+    unsigned char mirror;                                        /* HFLIP */
+    unsigned char flip;                                          /* VFLIP */
+    unsigned int winseqe_cur_addr;
+       unsigned int pixfmt;
+
+} sensor_info_priv_t;
+
+struct sensor
+{
+    struct v4l2_subdev subdev;
+    struct i2c_client *client;
+    sensor_info_priv_t info_priv;
+    int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */
+#if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_t tasklock_cnt;
+#endif
+       struct rk29camera_platform_data *sensor_io_request;
+    struct rk29camera_gpio_res *sensor_gpio_res;
+};
+
+static struct sensor* to_sensor(const struct i2c_client *client)
+{
+    return container_of(i2c_get_clientdata(client), struct sensor, subdev);
+}
+
+static int sensor_task_lock(struct i2c_client *client, int lock)
+{
+#if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
+    struct sensor *sensor = to_sensor(client);
+
+       if (lock) {
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
+                       preempt_disable();
+               }
+
+               atomic_add(1, &sensor->tasklock_cnt);
+       } else {
+               if (atomic_read(&sensor->tasklock_cnt) > 0) {
+                       atomic_sub(1, &sensor->tasklock_cnt);
+
+                       if (atomic_read(&sensor->tasklock_cnt) == 0)
+                               preempt_enable();
+               }
+       }
+#endif
+       return 0;
+sensor_task_lock_err:
+       return -1;
+}
+
+#if 0
+/* sensor register */
+static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+       int ret = 0;
+
+       ret = i2c_master_reg8_recv(client, reg, val, 1,  CONFIG_SENSOR_I2C_SPEED);
+
+       return (ret > 0)? 0 : ret;
+}
+
+static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
+{
+       int ret = 0;
+       
+       ret = i2c_master_reg8_send(client, reg, &val, 1, CONFIG_SENSOR_I2C_SPEED);
+
+       return (ret > 0)? 0 : ret;
+}
+#else
+static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
+{
+    int err,cnt;
+    u8 buf[2];
+    struct i2c_msg msg[1];
+
+    buf[0] = reg;
+    buf[1] = val;
+
+       if (reg == 0xfe)
+               mdelay(20);
+       
+    msg->addr = client->addr;
+    msg->flags = client->flags;
+    msg->buf = buf;
+    msg->len = sizeof(buf);
+    msg->scl_rate = CONFIG_SENSOR_I2C_SPEED;         /* ddl@rock-chips.com : 100kHz */
+    msg->read_type = 0;               /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */
+
+    cnt = 3;
+    err = -EAGAIN;
+
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+        err = i2c_transfer(client->adapter, msg, 1);
+
+        if (err >= 0) {
+            return 0;
+        } else {
+            SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);
+            udelay(10);
+        }
+    }
+
+    return err;
+}
+
+/* sensor register read */
+static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+    int err,cnt;
+    u8 buf[1];
+    struct i2c_msg msg[2];
+
+    buf[0] = reg ;
+
+    msg[0].addr = client->addr;
+    msg[0].flags = client->flags;
+    msg[0].buf = buf;
+    msg[0].len = sizeof(buf);
+    msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED;       /* ddl@rock-chips.com : 100kHz */
+    msg[0].read_type = 2;   /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */
+
+    msg[1].addr = client->addr;
+    msg[1].flags = client->flags|I2C_M_RD;
+    msg[1].buf = buf;
+    msg[1].len = 1;
+    msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED;                       /* ddl@rock-chips.com : 100kHz */
+    msg[1].read_type = 2;                             /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */
+
+    cnt = 3;
+    err = -EAGAIN;
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+        err = i2c_transfer(client->adapter, msg, 2);
+
+        if (err >= 0) {
+            *val = buf[0];
+            return 0;
+        } else {
+               SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val);
+            udelay(10);
+        }
+    }
+
+    return err;
+}
+
+#endif
+
+/* write a array of registers  */
+static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int err = 0, cnt;
+    int i = 0;
+       int j = 0;
+       char valchk;
+
+       cnt = 0;
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
+    while (regarray[i].reg != 0)
+    {
+        err = sensor_write(client, regarray[i].reg, regarray[i].val);
+        if (err < 0)
+        {
+            if (cnt-- > 0) {
+                           SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg);
+                               i = 0;
+                               continue;
+            } else {
+                SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING());
+                err = -EPERM;
+                               goto sensor_write_array_end;
+            }
+        } else {
+        #if CONFIG_SENSOR_I2C_RDWRCHK
+                       //mdelay(5);
+                       sensor_read(client, regarray[i].reg, &valchk);
+                       if (valchk != regarray[i].val)
+                               SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+               #endif
+        }
+        i++;
+    }
+
+sensor_write_array_end:
+       sensor_task_lock(client,0);
+       return err;
+}
+static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int cnt;
+    int i = 0;
+       char valchk;
+
+       cnt = 0;
+       valchk = 0;
+    while (regarray[i].reg != 0)
+    {
+               sensor_read(client, regarray[i].reg, &valchk);
+               if (valchk != regarray[i].val)
+                       SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+
+        i++;
+    }
+    return 0;
+}
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
+{
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       int ret = 0;
+
+    SENSOR_DG("%s %s  cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
+       switch (cmd)
+       {
+               case Sensor_PowerDown:
+               {
+                       if (icl->powerdown) {
+                               ret = icl->powerdown(icd->pdev, on);
+                               if (ret == RK29_CAM_IO_SUCCESS) {
+                                       if (on == 0) {
+                                               mdelay(2);
+                                               if (icl->reset)
+                                                       icl->reset(icd->pdev);
+                                       }
+                               } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {
+                                       ret = -ENODEV;
+                                       goto sensor_power_end;
+                               }
+                       }
+                       break;
+               }
+               case Sensor_Flash:
+               {
+                       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+               struct sensor *sensor = to_sensor(client);
+
+                       if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
+                               sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
+                       }
+            break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_power_end:
+       return ret;
+}
+static int sensor_init(struct v4l2_subdev *sd, u32 val)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl;
+    char value;
+    int ret,pid = 0;
+
+    SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
+
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_INIT_ERR;
+       }
+
+    /* soft reset */
+       if (sensor_task_lock(client,1)<0)
+               goto sensor_INIT_ERR;
+    ret = sensor_write(client, 0xfe, 0x80);
+    if (ret != 0)
+    {
+        SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING());
+        ret = -ENODEV;
+               goto sensor_INIT_ERR;
+    }
+
+    mdelay(5);  //delay 5 microseconds
+       /* check if it is an sensor sensor */
+    ret = sensor_read(client, 0x00, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id high byte failed\n");
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+
+    pid |= (value << 8);
+
+    ret = sensor_read(client, 0x01, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id low byte failed\n");
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+
+    pid |= (value & 0xff);
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+    if (pid == SENSOR_ID) {
+        sensor->model = SENSOR_V4L2_IDENT;
+    } else {
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+
+    ret = sensor_write_array(client, sensor_init_data);
+    if (ret != 0)
+    {
+        SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
+        goto sensor_INIT_ERR;
+    }
+       sensor_task_lock(client,0);
+    //icd->user_width = SENSOR_INIT_WIDTH;
+    //icd->user_height = SENSOR_INIT_HEIGHT;
+    sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;
+       sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT;
+
+    /* sensor sensor information for initialization  */
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+       if (qctrl)
+       sensor->info_priv.whiteBalance = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS);
+       if (qctrl)
+       sensor->info_priv.brightness = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+       if (qctrl)
+       sensor->info_priv.effect = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE);
+       if (qctrl)
+        sensor->info_priv.exposure = qctrl->default_value;
+
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION);
+       if (qctrl)
+        sensor->info_priv.saturation = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST);
+       if (qctrl)
+        sensor->info_priv.contrast = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP);
+       if (qctrl)
+        sensor->info_priv.mirror = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP);
+       if (qctrl)
+        sensor->info_priv.flip = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE);
+       if (qctrl)
+        sensor->info_priv.scene = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);
+       if (qctrl)
+        sensor->info_priv.digitalzoom = qctrl->default_value;
+
+    /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code  */
+       #if CONFIG_SENSOR_Focus
+    sensor_set_focus();
+    qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);
+       if (qctrl)
+        sensor->info_priv.focus = qctrl->default_value;
+       #endif
+
+       #if CONFIG_SENSOR_Flash
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);
+       if (qctrl)
+        sensor->info_priv.flash = qctrl->default_value;
+    #endif
+
+    SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);
+
+    return 0;
+sensor_INIT_ERR:
+       sensor_task_lock(client,0);
+       sensor_deactivate(client);
+    return ret;
+}
+
+static int sensor_deactivate(struct i2c_client *client)
+{
+       struct soc_camera_device *icd = client->dev.platform_data;
+
+       SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
+
+       /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);
+
+       /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
+       icd->user_width = SENSOR_INIT_WIDTH;
+    icd->user_height = SENSOR_INIT_HEIGHT;
+       msleep(100);
+       return 0;
+}
+
+static  struct reginfo sensor_power_down_sequence[]=
+{
+    {0x00,0x00}
+};
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
+{
+    int ret;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if (pm_msg.event == PM_EVENT_SUSPEND) {
+        SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());
+        ret = sensor_write_array(client, sensor_power_down_sequence) ;
+        if (ret != 0) {
+            SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);
+            return ret;
+        } else {
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);
+            if (ret < 0) {
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
+                return -EINVAL;
+            }
+        }
+    } else {
+        SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+    return 0;
+}
+
+static int sensor_resume(struct soc_camera_device *icd)
+{
+       int ret;
+
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);
+    if (ret < 0) {
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+       SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());
+
+    return 0;
+
+}
+
+static int sensor_set_bus_param(struct soc_camera_device *icd,
+                                unsigned long flags)
+{
+
+    return 0;
+}
+
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)
+{
+    struct soc_camera_link *icl = to_soc_camera_link(icd);
+    unsigned long flags = SENSOR_BUS_PARAM;
+
+    return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+
+    pix->width         = icd->user_width;
+    pix->height                = icd->user_height;
+    pix->pixelformat   = sensor->info_priv.pixfmt;
+    pix->field         = V4L2_FIELD_NONE;
+    pix->colorspace            = V4L2_COLORSPACE_JPEG;
+
+    return 0;
+}
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+       const struct v4l2_queryctrl *qctrl;
+       struct soc_camera_device *icd = client->dev.platform_data;
+    struct reginfo *winseqe_set_addr=NULL;
+    int ret=0, set_w,set_h;
+
+       SENSOR_TR("sensor_s_fmt\n");
+       if (sensor->info_priv.pixfmt != pix->pixelformat) {
+               switch (pix->pixelformat)
+               {
+                       case V4L2_PIX_FMT_YUYV:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_YUYV;
+                               break;
+                       }
+                       case V4L2_PIX_FMT_UYVY:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_UYVY;
+                               break;
+                       }
+                       default:
+                               break;
+               }
+               if (winseqe_set_addr != NULL) {
+            sensor_write_array(client, winseqe_set_addr);
+                       sensor->info_priv.pixfmt = pix->pixelformat;
+
+                       SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+               } else {
+                       SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+               }
+       }
+
+    set_w = pix->width;
+    set_h = pix->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+               winseqe_set_addr = sensor_qcif;
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        winseqe_set_addr = sensor_qvga;
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        winseqe_set_addr = sensor_cif;
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        winseqe_set_addr = sensor_vga;
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)
+    {
+        winseqe_set_addr = sensor_svga;
+        set_w = 800;
+        set_h = 600;
+    }
+       else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg)
+    {
+        winseqe_set_addr = sensor_xga;
+        set_w = 1024;
+        set_h = 768;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
+    {
+        winseqe_set_addr = sensor_sxga;
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)
+    {
+        winseqe_set_addr = sensor_uxga;
+        set_w = 1600;
+        set_h = 1200;
+    }
+    else
+    {
+        winseqe_set_addr = SENSOR_INIT_WINSEQADR;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;
+               ret = -1;
+               SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);
+    }
+
+    if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr) {
+        #if CONFIG_SENSOR_Flash
+        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_On);
+                SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
+            }           
+        } else {                                        /* ddl@rock-chips.com : Video */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());
+            }
+        }
+        #endif
+        ret |= sensor_write_array(client, winseqe_set_addr);
+        if (ret != 0) {
+            SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
+            #if CONFIG_SENSOR_Flash
+            if (sensor_fmt_capturechk(sd,f) == true) {
+                if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                    sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                    SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
+                }
+            }
+            #endif
+            goto sensor_s_fmt_end;
+        }
+
+        sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
+
+               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       if (sensor->info_priv.whiteBalance != 0) {
+                               qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                               sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       }
+                       sensor->info_priv.snap2preview = true;
+               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       sensor->info_priv.video2preview = true;
+               } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       sensor->info_priv.video2preview = false;
+                       sensor->info_priv.snap2preview = false;
+               }
+        SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
+    }
+    else
+    {
+        SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
+    }
+
+       pix->width = set_w;
+    pix->height = set_h;
+
+sensor_s_fmt_end:
+    return ret;
+}
+
+static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+    bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY ||
+        pix->pixelformat == V4L2_PIX_FMT_YUYV;
+
+    /*
+    * With Bayer format enforce even side lengths, but let the user play
+    * with the starting pixel
+    */
+
+    if (pix->height > SENSOR_MAX_HEIGHT)
+        pix->height = SENSOR_MAX_HEIGHT;
+    else if (pix->height < SENSOR_MIN_HEIGHT)
+        pix->height = SENSOR_MIN_HEIGHT;
+    else if (bayer)
+        pix->height = ALIGN(pix->height, 2);
+
+    if (pix->width > SENSOR_MAX_WIDTH)
+        pix->width = SENSOR_MAX_WIDTH;
+    else if (pix->width < SENSOR_MIN_WIDTH)
+        pix->width = SENSOR_MIN_WIDTH;
+    else if (bayer)
+        pix->width = ALIGN(pix->width, 2);
+
+    return 0;
+}
+
+ static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
+{
+    struct i2c_client *client = sd->priv;
+
+    if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
+        return -EINVAL;
+
+    if (id->match.addr != client->addr)
+        return -ENODEV;
+
+    id->ident = SENSOR_V4L2_IDENT;      /* ddl@rock-chips.com :  Return OV2655  identifier */
+    id->revision = 0;
+
+    return 0;
+}
+#if CONFIG_SENSOR_Brightness
+static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Effect
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_EffectSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Exposure
+static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Saturation
+static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Contrast
+static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Mirror
+static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Flip
+static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_FlipSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Scene
+static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_SceneSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl_info;
+    int digitalzoom_cur, digitalzoom_total;
+
+       qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);
+       if (qctrl_info)
+               return -EINVAL;
+
+    digitalzoom_cur = sensor->info_priv.digitalzoom;
+    digitalzoom_total = qctrl_info->maximum;
+
+    if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total))
+    {
+        SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
+        return -EINVAL;
+    }
+
+    if  ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum))
+    {
+        SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
+        return -EINVAL;
+    }
+
+    if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total))
+    {
+        *value = digitalzoom_total - digitalzoom_cur;
+    }
+
+    if ((*value < 0) && ((digitalzoom_cur + *value) < 0))
+    {
+        *value = 0 - digitalzoom_cur;
+    }
+
+    digitalzoom_cur += *value;
+
+    if (sensor_ZoomSeqe[digitalzoom_cur] != NULL)
+    {
+        if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0)
+        {
+            SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+            return -EINVAL;
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value);
+        return 0;
+    }
+
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Flash
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{    
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {
+        if (value == 3) {       /* ddl@rock-chips.com: torch */
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Torch);   /* Flash On */
+        } else {
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+        return 0;
+    }
+    
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct v4l2_queryctrl *qctrl;
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ctrl->id)
+    {
+        case V4L2_CID_BRIGHTNESS:
+            {
+                ctrl->value = sensor->info_priv.brightness;
+                break;
+            }
+        case V4L2_CID_SATURATION:
+            {
+                ctrl->value = sensor->info_priv.saturation;
+                break;
+            }
+        case V4L2_CID_CONTRAST:
+            {
+                ctrl->value = sensor->info_priv.contrast;
+                break;
+            }
+        case V4L2_CID_DO_WHITE_BALANCE:
+            {
+                ctrl->value = sensor->info_priv.whiteBalance;
+                break;
+            }
+        case V4L2_CID_EXPOSURE:
+            {
+                ctrl->value = sensor->info_priv.exposure;
+                break;
+            }
+        case V4L2_CID_HFLIP:
+            {
+                ctrl->value = sensor->info_priv.mirror;
+                break;
+            }
+        case V4L2_CID_VFLIP:
+            {
+                ctrl->value = sensor->info_priv.flip;
+                break;
+            }
+        default :
+                break;
+    }
+    return 0;
+}
+
+
+
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    struct soc_camera_device *icd = client->dev.platform_data;
+    const struct v4l2_queryctrl *qctrl;
+
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ctrl->id)
+    {
+#if CONFIG_SENSOR_Brightness
+        case V4L2_CID_BRIGHTNESS:
+            {
+                if (ctrl->value != sensor->info_priv.brightness)
+                {
+                    if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.brightness = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Exposure
+        case V4L2_CID_EXPOSURE:
+            {
+                if (ctrl->value != sensor->info_priv.exposure)
+                {
+                    if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.exposure = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Saturation
+        case V4L2_CID_SATURATION:
+            {
+                if (ctrl->value != sensor->info_priv.saturation)
+                {
+                    if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.saturation = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Contrast
+        case V4L2_CID_CONTRAST:
+            {
+                if (ctrl->value != sensor->info_priv.contrast)
+                {
+                    if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.contrast = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+        case V4L2_CID_DO_WHITE_BALANCE:
+            {
+                if (ctrl->value != sensor->info_priv.whiteBalance)
+                {
+                    if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.whiteBalance = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Mirror
+        case V4L2_CID_HFLIP:
+            {
+                if (ctrl->value != sensor->info_priv.mirror)
+                {
+                    if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.mirror = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Flip
+        case V4L2_CID_VFLIP:
+            {
+                if (ctrl->value != sensor->info_priv.flip)
+                {
+                    if (sensor_set_flip(icd, qctrl,ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.flip = ctrl->value;
+                }
+                break;
+            }
+#endif
+        default:
+            break;
+    }
+
+    return 0;
+}
+static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl)
+{
+    const struct v4l2_queryctrl *qctrl;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ext_ctrl->id)
+    {
+        case V4L2_CID_SCENE:
+            {
+                ext_ctrl->value = sensor->info_priv.scene;
+                break;
+            }
+        case V4L2_CID_EFFECT:
+            {
+                ext_ctrl->value = sensor->info_priv.effect;
+                break;
+            }
+        case V4L2_CID_ZOOM_ABSOLUTE:
+            {
+                ext_ctrl->value = sensor->info_priv.digitalzoom;
+                break;
+            }
+        case V4L2_CID_ZOOM_RELATIVE:
+            {
+                return -EINVAL;
+            }
+        case V4L2_CID_FOCUS_ABSOLUTE:
+            {
+                ext_ctrl->value = sensor->info_priv.focus;
+                break;
+            }
+        case V4L2_CID_FOCUS_RELATIVE:
+            {
+                return -EINVAL;
+            }
+        case V4L2_CID_FLASH:
+            {
+                ext_ctrl->value = sensor->info_priv.flash;
+                break;
+            }
+        default :
+            break;
+    }
+    return 0;
+}
+static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl)
+{
+    const struct v4l2_queryctrl *qctrl;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+    int val_offset;
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        return -EINVAL;
+    }
+
+       val_offset = 0;
+    switch (ext_ctrl->id)
+    {
+#if CONFIG_SENSOR_Scene
+        case V4L2_CID_SCENE:
+            {
+                if (ext_ctrl->value != sensor->info_priv.scene)
+                {
+                    if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.scene = ext_ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Effect
+        case V4L2_CID_EFFECT:
+            {
+                if (ext_ctrl->value != sensor->info_priv.effect)
+                {
+                    if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.effect= ext_ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+        case V4L2_CID_ZOOM_ABSOLUTE:
+            {
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
+
+                if (ext_ctrl->value != sensor->info_priv.digitalzoom)
+                {
+                    val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom;
+
+                    if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.digitalzoom += val_offset;
+
+                    SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(),  sensor->info_priv.digitalzoom);
+                }
+
+                break;
+            }
+        case V4L2_CID_ZOOM_RELATIVE:
+            {
+                if (ext_ctrl->value)
+                {
+                    if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.digitalzoom += ext_ctrl->value;
+
+                    SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom);
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Focus
+        case V4L2_CID_FOCUS_ABSOLUTE:
+            {
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
+
+                if (ext_ctrl->value != sensor->info_priv.focus)
+                {
+                    val_offset = ext_ctrl->value -sensor->info_priv.focus;
+
+                    sensor->info_priv.focus += val_offset;
+                }
+
+                break;
+            }
+        case V4L2_CID_FOCUS_RELATIVE:
+            {
+                if (ext_ctrl->value)
+                {
+                    sensor->info_priv.focus += ext_ctrl->value;
+
+                    SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus);
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Flash
+        case V4L2_CID_FLASH:
+            {
+                if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)
+                    return -EINVAL;
+                sensor->info_priv.flash = ext_ctrl->value;
+
+                SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);
+                break;
+            }
+#endif
+        default:
+            break;
+    }
+
+    return 0;
+}
+
+static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    int i, error_cnt=0, error_idx=-1;
+
+
+    for (i=0; i<ext_ctrl->count; i++) {
+        if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+            error_cnt++;
+            error_idx = i;
+        }
+    }
+
+    if (error_cnt > 1)
+        error_idx = ext_ctrl->count;
+
+    if (error_idx != -1) {
+        ext_ctrl->error_idx = error_idx;
+        return -EINVAL;
+    } else {
+        return 0;
+    }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    int i, error_cnt=0, error_idx=-1;
+
+
+    for (i=0; i<ext_ctrl->count; i++) {
+        if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+            error_cnt++;
+            error_idx = i;
+        }
+    }
+
+    if (error_cnt > 1)
+        error_idx = ext_ctrl->count;
+
+    if (error_idx != -1) {
+        ext_ctrl->error_idx = error_idx;
+        return -EINVAL;
+    } else {
+        return 0;
+    }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+                              struct i2c_client *client)
+{
+    char value;
+    int ret,pid=0;
+    struct sensor *sensor = to_sensor(client);
+
+    /* We must have a parent by now. And it cannot be a wrong one.
+     * So this entire test is completely redundant. */
+    if (!icd->dev.parent ||
+           to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+               return -ENODEV;
+
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
+
+    /* soft reset */
+    ret = sensor_write(client, 0xfe, 0x80);
+    if (ret != 0)
+    {
+        SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
+        return -ENODEV;
+    }
+    mdelay(5);          //delay 5 microseconds
+
+    /* check if it is an sensor sensor */
+    ret = sensor_read(client, 0x00, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id high byte failed\n");
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+    pid |= (value << 8);
+
+    ret = sensor_read(client, 0x01, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id low byte failed\n");
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+    pid |= (value & 0xff);
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+    if (pid == SENSOR_ID) {
+        sensor->model = SENSOR_V4L2_IDENT;
+    } else {
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+    icd->formats = sensor_colour_formats;
+    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
+
+    return 0;
+
+sensor_video_probe_err:
+
+    return ret;
+}
+static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+       struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    int ret = 0;
+#if CONFIG_SENSOR_Flash        
+    int i;
+#endif
+    
+       SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+       switch (cmd)
+       {
+               case RK29_CAM_SUBDEV_DEACTIVATE:
+               {
+                       sensor_deactivate(client);
+                       break;
+               }
+
+               case RK29_CAM_SUBDEV_IOREQUEST:
+               {
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
+            /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
+               for this project */
+            #if CONFIG_SENSOR_Flash    
+               if (sensor->sensor_gpio_res) { 
+                if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {
+                    for (i = 0; i < icd->ops->num_controls; i++) {
+                               if (V4L2_CID_FLASH == icd->ops->controls[i].id) {
+                                       memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                       
+                               }
+                    }
+                    sensor->info_priv.flash = 0xff;
+                    SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());
+                }
+               }
+            #endif
+                       break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_ioctl_end:
+       return ret;
+
+}
+static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
+       .init           = sensor_init,
+       .g_ctrl         = sensor_g_control,
+       .s_ctrl         = sensor_s_control,
+       .g_ext_ctrls          = sensor_g_ext_controls,
+       .s_ext_ctrls          = sensor_s_ext_controls,
+       .g_chip_ident   = sensor_g_chip_ident,
+       .ioctl = sensor_ioctl,
+};
+
+static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {
+       .s_fmt          = sensor_s_fmt,
+       .g_fmt          = sensor_g_fmt,
+       .try_fmt        = sensor_try_fmt,
+};
+
+static struct v4l2_subdev_ops sensor_subdev_ops = {
+       .core   = &sensor_subdev_core_ops,
+       .video = &sensor_subdev_video_ops,
+};
+
+static int sensor_probe(struct i2c_client *client,
+                        const struct i2c_device_id *did)
+{
+    struct sensor *sensor;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+    struct soc_camera_link *icl;
+    int ret;
+
+    SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__);
+    if (!icd) {
+        dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+    icl = to_soc_camera_link(icd);
+    if (!icl) {
+        dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+    if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+        dev_warn(&adapter->dev,
+                "I2C-Adapter doesn't support I2C_FUNC_I2C\n");
+        return -EIO;
+    }
+
+    sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL);
+    if (!sensor)
+        return -ENOMEM;
+
+    v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops);
+
+    /* Second stage probe - when a capture adapter is there */
+    icd->ops           = &sensor_ops;
+    icd->y_skip_top            = 0;
+       #if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_set(&sensor->tasklock_cnt,0);
+       #endif
+
+    ret = sensor_video_probe(icd, client);
+    if (ret < 0) {
+        icd->ops = NULL;
+        i2c_set_clientdata(client, NULL);
+        kfree(sensor);
+               sensor = NULL;
+    }
+    SENSOR_DG("\n%s..%s..%d  ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);
+    return ret;
+}
+
+static int sensor_remove(struct i2c_client *client)
+{
+    struct sensor *sensor = to_sensor(client);
+    struct soc_camera_device *icd = client->dev.platform_data;
+
+    icd->ops = NULL;
+    i2c_set_clientdata(client, NULL);
+    client->driver = NULL;
+    kfree(sensor);
+       sensor = NULL;
+    return 0;
+}
+
+static const struct i2c_device_id sensor_id[] = {
+       {SENSOR_NAME_STRING(), 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, sensor_id);
+
+static struct i2c_driver sensor_i2c_driver = {
+       .driver = {
+               .name = SENSOR_NAME_STRING(),
+       },
+       .probe          = sensor_probe,
+       .remove         = sensor_remove,
+       .id_table       = sensor_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+    SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING());
+    return i2c_add_driver(&sensor_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+    i2c_del_driver(&sensor_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));
+MODULE_AUTHOR("ddl <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
+
diff --git a/drivers/media/video/hi253.c b/drivers/media/video/hi253.c
new file mode 100755 (executable)
index 0000000..70c3567
--- /dev/null
@@ -0,0 +1,3504 @@
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <mach/rk29_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do {                       \
+       if (debug >= level)                                     \
+       printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
+
+
+#define _CONS(a,b) a##b
+#define CONS(a,b) _CONS(a,b)
+
+#define __STR(x) #x
+#define _STR(x) __STR(x)
+#define STR(x) _STR(x)
+
+#define MIN(x,y)   ((x<y) ? x: y)
+#define MAX(x,y)    ((x>y) ? x: y)
+
+/* Sensor Driver Configuration */
+#define SENSOR_NAME RK29_CAM_SENSOR_HI253
+#define SENSOR_V4L2_IDENT V4L2_IDENT_HI253
+#define SENSOR_ID 0x92
+#define SENSOR_MIN_WIDTH    176
+#define SENSOR_MIN_HEIGHT   144
+#define SENSOR_MAX_WIDTH    1600
+#define SENSOR_MAX_HEIGHT   1200
+#define SENSOR_INIT_WIDTH      1600                    /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  1200
+#define SENSOR_INIT_WINSEQADR sensor_uxga
+#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY
+
+#define CONFIG_SENSOR_WhiteBalance     1
+#define CONFIG_SENSOR_Brightness       0
+#define CONFIG_SENSOR_Contrast      0
+#define CONFIG_SENSOR_Saturation    0
+#define CONFIG_SENSOR_Effect        1
+#define CONFIG_SENSOR_Scene         1
+#define CONFIG_SENSOR_DigitalZoom   0
+#define CONFIG_SENSOR_Focus         0
+#define CONFIG_SENSOR_Exposure      0
+#define CONFIG_SENSOR_Flash         0
+#define CONFIG_SENSOR_Mirror        0
+#define CONFIG_SENSOR_Flip          0
+
+#define CONFIG_SENSOR_I2C_SPEED     100000       /* Hz */
+/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */
+#define CONFIG_SENSOR_I2C_NOSCHED   0
+#define CONFIG_SENSOR_I2C_RDWRCHK   0
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
+#define COLOR_TEMPERATURE_CLOUDY_DN  6500
+#define COLOR_TEMPERATURE_CLOUDY_UP    8000
+#define COLOR_TEMPERATURE_CLEARDAY_DN  5000
+#define COLOR_TEMPERATURE_CLEARDAY_UP    6500
+#define COLOR_TEMPERATURE_OFFICE_DN     3500
+#define COLOR_TEMPERATURE_OFFICE_UP     5000
+#define COLOR_TEMPERATURE_HOME_DN       2500
+#define COLOR_TEMPERATURE_HOME_UP       3500
+
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
+
+
+#define END_REG 0xff
+
+struct reginfo
+{
+    u8 reg;
+    u8 val;
+};
+
+/* init SVGA preview */
+static struct reginfo sensor_init_data[] =
+{
+//     {0x01, 0xf9}, 
+       {0x08, 0x0f}, 
+       {0x01, 0xf8}, 
+
+       {0x03, 0x00}, 
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00}, 
+
+       {0x0e, 0x00}, 
+
+       {0x03, 0x00}, 
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00}, 
+
+       {0x0e, 0x00}, 
+       {0x01, 0xf1}, 
+       {0x08, 0x00}, 
+       {0x01, 0xf3},
+       {0x01, 0xf1},
+
+       {0x03, 0x20}, 
+       {0x10, 0x0c}, 
+       {0x03, 0x22}, 
+       {0x10, 0x69}, 
+       
+       //Page 00
+       {0x03, 0x00}, 
+       {0x10, 0x00}, //lxh
+       {0x11, 0x90}, 
+       {0x12, 0x04}, 
+       {0x0b, 0xaa}, 
+       {0x0c, 0xaa}, 
+       {0x0d, 0xaa}, 
+       {0x20, 0x00}, 
+       {0x21, 0x0a}, //lxh
+       {0x22, 0x00}, 
+       {0x23, 0x0a}, //lxh
+       {0x24, 0x04}, 
+       {0x25, 0xb0}, 
+       {0x26, 0x06}, 
+       {0x27, 0x40}, 
+
+       {0x40, 0x01}, 
+       {0x41, 0x98},//lxh 
+       {0x42, 0x00}, 
+       {0x43, 0x14},//lxh 
+
+       {0x45, 0x04}, 
+       {0x46, 0x18}, 
+       {0x47, 0xd8}, 
+
+       {0xe1, 0x0f},
+
+       //BLC
+       {0x80, 0x2e}, 
+       {0x81, 0x7e},
+       {0x82, 0x90},
+       {0x83, 0x00},
+       {0x84, 0x0c},
+       {0x85, 0x00},
+       {0x90, 0x0c}, 
+       {0x91, 0x0c}, 
+       {0x92, 0x78}, 
+       {0x93, 0x70}, 
+       {0x94, 0x75}, 
+       {0x95, 0x70}, 
+       {0x96, 0xdc},
+       {0x97, 0xfe},
+       {0x98, 0x20},
+
+       //OutDoor BLC
+       {0x99,0x42}, 
+       {0x9a,0x42}, 
+       {0x9b,0x42}, 
+       {0x9c,0x42}, 
+
+       //Dark BLC
+       {0xa0, 0x00},
+       {0xa2, 0x00},
+       {0xa4, 0x00},
+       {0xa6, 0x00},
+
+       //Normal BLC
+       {0xa8, 0x43},
+       {0xaa, 0x43},
+       {0xac, 0x43},
+       {0xae, 0x43},
+
+       //Page 02
+       {0x03, 0x02}, 
+       {0x12, 0x03},
+       {0x13, 0x03},
+       {0x16, 0x00},
+       {0x17, 0x8C},
+       {0x18, 0x4c}, 
+       {0x19, 0x00}, 
+       {0x1a, 0x39},
+       {0x1c, 0x09},
+       {0x1d, 0x40},
+       {0x1e, 0x30},
+       {0x1f, 0x10},
+       {0x20, 0x77},
+       {0x21, 0xde}, 
+       {0x22, 0xa7},
+       {0x23, 0x30},
+       {0x27, 0x3c},
+       {0x2b, 0x80},
+       {0x2e, 0x00},
+       {0x2f, 0x00},
+       {0x30, 0x05},
+       {0x50, 0x20},
+       {0x52, 0x01},
+       {0x53, 0xc1},
+       {0x55, 0x1c},
+       {0x56, 0x11},
+       {0x5d, 0xA2},
+       {0x5e, 0x5a},
+       {0x60, 0x87},
+       {0x61, 0x99},
+       {0x62, 0x88},
+       {0x63, 0x97},
+       {0x64, 0x88},
+       {0x65, 0x97},
+       {0x67, 0x0c},
+       {0x68, 0x0c},
+       {0x69, 0x0c},
+       {0x72, 0x89},
+       {0x73, 0x96}, 
+       {0x74, 0x89},
+       {0x75, 0x96}, 
+       {0x76, 0x89},
+       {0x77, 0x96}, 
+       {0x7C, 0x85},
+       {0x7d, 0xaf},
+       {0x80, 0x01},
+       {0x81, 0x7f}, 
+       {0x82, 0x13}, 
+       {0x83, 0x24}, 
+       {0x84, 0x7d},
+       {0x85, 0x81},
+       {0x86, 0x7d},
+       {0x87, 0x81},
+       {0x92, 0x48}, 
+       {0x93, 0x54}, 
+       {0x94, 0x7d},
+       {0x95, 0x81},
+       {0x96, 0x7d},
+       {0x97, 0x81},
+       {0xa0, 0x02},
+       {0xa1, 0x7b},
+       {0xa2, 0x02},
+       {0xa3, 0x7b},
+       {0xa4, 0x7b},
+       {0xa5, 0x02},
+       {0xa6, 0x7b},
+       {0xa7, 0x02},
+       {0xa8, 0x85},
+       {0xa9, 0x8c},
+       {0xaa, 0x85},
+       {0xab, 0x8c},
+       {0xac, 0x10},
+       {0xad, 0x16},
+       {0xae, 0x10},
+       {0xaf, 0x16},
+       {0xb0, 0x99},
+       {0xb1, 0xa3},
+       {0xb2, 0xa4},
+       {0xb3, 0xae},
+       {0xb4, 0x9b},
+       {0xb5, 0xa2},
+       {0xb6, 0xa6},
+       {0xb7, 0xac},
+       {0xb8, 0x9b},
+       {0xb9, 0x9f},
+       {0xba, 0xa6},
+       {0xbb, 0xaa},
+       {0xbc, 0x9b},
+       {0xbd, 0x9f},
+       {0xbe, 0xa6},
+       {0xbf, 0xaa},
+       {0xc4, 0x2c},
+       {0xc5, 0x43},
+       {0xc6, 0x63},
+       {0xc7, 0x79},
+       {0xc8, 0x2d},
+       {0xc9, 0x42},
+       {0xca, 0x2d},
+       {0xcb, 0x42},
+       {0xcc, 0x64},
+       {0xcd, 0x78},
+       {0xce, 0x64},
+       {0xcf, 0x78},
+       {0xd0, 0x0a},
+       {0xd1, 0x09},
+       {0xd4, 0x0c},
+       {0xd5, 0x0c},
+       {0xd6, 0xd8},
+       {0xd7, 0xd0},//lxh
+       {0xe0, 0xc4},
+       {0xe1, 0xc4},
+       {0xe2, 0xc4},
+       {0xe3, 0xc4},
+       {0xe4, 0x00},
+       {0xe8, 0x80}, 
+       {0xe9, 0x40},
+       {0xea, 0x7f}, 
+       {0xf0, 0x01}, 
+       {0xf1, 0x01}, 
+       {0xf2, 0x01}, 
+       {0xf3, 0x01}, 
+       {0xf4, 0x01}, 
+
+       //PAGE10
+       {0x03, 0x10},
+       {0x10, 0x01}, //lxh
+    {0x11, 0x03}, //lxh,normal 
+       {0x12, 0x00},
+       {0x13, 0x00},
+       {0x20, 0x00}, 
+
+       {0x40, 0x80},
+       {0x41, 0x00},
+       {0x48, 0x88},// 84
+       {0x50, 0x90},
+       {0x30, 0x00},
+       {0x31, 0x00},
+       {0x32, 0x00},
+       {0x33, 0x00},
+
+       {0x34, 0x30},
+       {0x35, 0x00},
+       {0x36, 0x00},
+       {0x38, 0x00},
+       {0x3e, 0x58},
+       {0x3f, 0x00},
+
+       //Saturation
+       {0x60, 0x6f},
+       {0x61, 0x95},// 74
+       {0x62, 0x95},// 76
+       {0x63, 0x30},
+       {0x64, 0x41},
+
+       {0x66, 0x33},
+       {0x67, 0x00},
+
+       {0x6a, 0x90}, 
+       {0x6b, 0x80}, 
+       {0x6c, 0x80}, 
+       {0x6d, 0xa0}, 
+
+       {0x76, 0x01}, 
+       {0x74, 0x66},
+       {0x79, 0x06},
+       
+       //Page 11
+       {0x03, 0x11}, 
+       {0x10, 0x7f},//lxh,3f 
+       {0x11, 0x40},
+       {0x12, 0xba},
+       {0x13, 0xcb},
+       {0x26, 0x20}, 
+       {0x27, 0x22}, 
+       {0x28, 0x0f}, 
+       {0x29, 0x10}, 
+       {0x2b, 0x30}, 
+       {0x2c, 0x32}, 
+
+       //Out2 D-LPF th
+       {0x30, 0x70}, 
+       {0x31, 0x10}, 
+       {0x32, 0x65}, 
+       {0x33, 0x09}, 
+       {0x34, 0x06}, 
+       {0x35, 0x04}, 
+
+       //Out1 D-LPF th
+       {0x36, 0x70}, 
+       {0x37, 0x18}, 
+       {0x38, 0x65}, 
+       {0x39, 0x09}, 
+       {0x3a, 0x06}, 
+       {0x3b, 0x04}, 
+
+       //Indoor D-LPF th
+       {0x3c, 0x80}, 
+       {0x3d, 0x18}, 
+       {0x3e, 0x80}, 
+       {0x3f, 0x0c}, 
+       {0x40, 0x09}, 
+       {0x41, 0x06}, 
+
+       {0x42, 0x80}, 
+       {0x43, 0x18}, 
+       {0x44, 0x80}, 
+       {0x45, 0x12}, 
+       {0x46, 0x10}, 
+       {0x47, 0x10}, 
+       {0x48, 0x90}, 
+       {0x49, 0x40}, 
+       {0x4a, 0x80}, 
+       {0x4b, 0x13}, 
+       {0x4c, 0x10}, 
+       {0x4d, 0x11}, 
+       {0x4e, 0x80}, 
+       {0x4f, 0x30}, 
+       {0x50, 0x80}, 
+       {0x51, 0x13}, 
+       {0x52, 0x10}, 
+       {0x53, 0x13}, 
+       {0x54, 0x11},
+       {0x55, 0x17},
+       {0x56, 0x20},
+       {0x57, 0x20},
+       {0x58, 0x20},
+       {0x59, 0x30},
+       {0x5a, 0x18},
+       {0x5b, 0x00},
+       {0x5c, 0x00},
+       {0x60, 0x3f},
+       {0x62, 0x50},
+       {0x70, 0x06},
+       
+       //Page 12
+       {0x03, 0x12}, 
+       {0x20, 0x0f},
+       {0x21, 0x0f},
+       {0x25, 0x30},
+       {0x28, 0x00}, 
+       {0x29, 0x00}, 
+       {0x2a, 0x00},
+       {0x30, 0x50},
+       {0x31, 0x18}, 
+       {0x32, 0x32}, 
+       {0x33, 0x40}, 
+       {0x34, 0x50}, 
+       {0x35, 0x70}, 
+       {0x36, 0xa0}, 
+
+       //Out2 th
+       {0x40, 0xa0}, 
+       {0x41, 0x40}, 
+       {0x42, 0xa0}, 
+       {0x43, 0x90}, 
+       {0x44, 0x90}, 
+       {0x45, 0x80}, 
+
+       //Out1 th
+       {0x46, 0xb0}, 
+       {0x47, 0x55}, 
+       {0x48, 0xa0}, 
+       {0x49, 0x90}, 
+       {0x4a, 0x90}, 
+       {0x4b, 0x80}, 
+
+       //In door th
+       {0x4c, 0xb0},
+       {0x4d, 0x40},
+       {0x4e, 0x90},
+       {0x4f, 0x90},
+       {0x50, 0xe6},
+       {0x51, 0x80},
+
+       //Dark1 th
+       {0x52, 0xb0},
+       {0x53, 0x60},
+       {0x54, 0xc0},
+       {0x55, 0xc0},
+       {0x56, 0xc0},
+       {0x57, 0x80},
+
+       //Dark2 th
+       {0x58, 0x90},
+       {0x59, 0x40},
+       {0x5a, 0xd0},
+       {0x5b, 0xd0},
+       {0x5c, 0xe0},
+       {0x5d, 0x80},
+
+       //Dark3 th
+       {0x5e, 0x88},
+       {0x5f, 0x40},
+       {0x60, 0xe0},
+       {0x61, 0xe6},
+       {0x62, 0xe6},
+       {0x63, 0x80},
+
+       {0x70, 0x15},
+       {0x71, 0x01},
+
+       {0x72, 0x18},
+       {0x73, 0x01},
+
+       {0x74, 0x25},
+       {0x75, 0x15},
+       {0x80, 0x30},
+       {0x81, 0x50},
+       {0x82, 0x80},
+       {0x85, 0x1a},
+       {0x88, 0x00},
+       {0x89, 0x00},
+       {0x90, 0x5d},
+
+       {0xc5, 0x30},
+       {0xc6, 0x2a},
+
+       {0xD0, 0x0c},
+       {0xD1, 0x80},
+       {0xD2, 0x67},
+       {0xD3, 0x00},
+       {0xD4, 0x00},
+       {0xD5, 0x02},
+       {0xD6, 0xff},
+       {0xD7, 0x18},
+       {0x3b, 0x06},
+       {0x3c, 0x06},
+
+       {0xc5, 0x30},
+       {0xc6, 0x2a},
+
+       //Page 13
+       {0x03, 0x13},
+       {0x10, 0xcb},
+       {0x11, 0x7b},
+       {0x12, 0x07},
+       {0x14, 0x00},
+
+       {0x20, 0x15},
+       {0x21, 0x13},
+       {0x22, 0x33},
+       {0x23, 0x04},
+       {0x24, 0x09},
+       {0x25, 0x08},
+       {0x26, 0x18},
+       {0x27, 0x30},
+       {0x29, 0x12},
+       {0x2a, 0x50},
+
+       //Low clip th
+       {0x2b, 0x06},
+       {0x2c, 0x06},
+       {0x25, 0x08},
+       {0x2d, 0x0c},
+       {0x2e, 0x12},
+       {0x2f, 0x12},
+
+       //Out2 Edge
+       {0x50, 0x10},
+       {0x51, 0x14},
+       {0x52, 0x10},
+       {0x53, 0x0c},
+       {0x54, 0x0f},
+       {0x55, 0x0c},
+
+       //Out1 Edge
+       {0x56, 0x10},
+       {0x57, 0x13},
+       {0x58, 0x10},
+       {0x59, 0x0c},
+       {0x5a, 0x0f},
+       {0x5b, 0x0c},
+
+       //Indoor Edge
+       {0x5c, 0x0a},
+       {0x5d, 0x0b},
+       {0x5e, 0x0a},
+       {0x5f, 0x08},
+       {0x60, 0x09},
+       {0x61, 0x08},
+
+       //Dark1 Edge
+       {0x62, 0x08},
+       {0x63, 0x08},
+       {0x64, 0x08},
+       {0x65, 0x06},
+       {0x66, 0x06},
+       {0x67, 0x06},
+
+       //Dark2 Edge
+       {0x68, 0x07},
+       {0x69, 0x07},
+       {0x6a, 0x07},
+       {0x6b, 0x05},
+       {0x6c, 0x05},
+       {0x6d, 0x05},
+
+       //Dark3 Edge
+       {0x6e, 0x07},
+       {0x6f, 0x07},
+       {0x70, 0x07},
+       {0x71, 0x05},
+       {0x72, 0x05},
+       {0x73, 0x05},
+
+       //2DY
+       {0x80, 0xfd},
+       {0x81, 0x1f},
+       {0x82, 0x05},
+       {0x83, 0x01},
+
+       {0x90, 0x15},
+       {0x91, 0x15},
+       {0x92, 0x33},
+       {0x93, 0x30},
+       {0x94, 0x03},
+       {0x95, 0x14},
+       {0x97, 0x30},
+       {0x99, 0x30},
+
+       {0xa0, 0x04},
+       {0xa1, 0x05},
+       {0xa2, 0x04},
+       {0xa3, 0x05},
+       {0xa4, 0x07},
+       {0xa5, 0x08},
+       {0xa6, 0x07},
+       {0xa7, 0x08},
+       {0xa8, 0x07},
+       {0xa9, 0x08},
+       {0xaa, 0x07},
+       {0xab, 0x08}, 
+
+       //Out2 
+       {0xb0, 0x22},
+       {0xb1, 0x2a},
+       {0xb2, 0x28},
+       {0xb3, 0x22},
+       {0xb4, 0x2a},
+       {0xb5, 0x28},
+
+       //Out1 
+       {0xb6, 0x22},
+       {0xb7, 0x2a},
+       {0xb8, 0x28},
+       {0xb9, 0x22},
+       {0xba, 0x2a},
+       {0xbb, 0x28},
+
+       {0xbc, 0x17},
+       {0xbd, 0x17},
+       {0xbe, 0x17},
+       {0xbf, 0x17},
+       {0xc0, 0x17},
+       {0xc1, 0x17},
+
+       //Dark1
+       {0xc2, 0x1e},
+       {0xc3, 0x12},
+       {0xc4, 0x10},
+       {0xc5, 0x1e},
+       {0xc6, 0x12},
+       {0xc7, 0x10},
+
+       //Dark2
+       {0xc8, 0x18},
+       {0xc9, 0x05},
+       {0xca, 0x05},
+       {0xcb, 0x18},
+       {0xcc, 0x05},
+       {0xcd, 0x05},
+
+       //Dark3 
+       {0xce, 0x18},
+       {0xcf, 0x05},
+       {0xd0, 0x05},
+       {0xd1, 0x18},
+       {0xd2, 0x05},
+       {0xd3, 0x05},
+       
+       //Page 14
+       {0x03, 0x14},
+       {0x10, 0x11},
+       {0x20, 0x40},
+       {0x21, 0x80},
+       {0x23, 0x80},
+       {0x22, 0x80},
+       {0x23, 0x80},
+       {0x24, 0x80},
+
+       {0x30, 0xc8},
+       {0x31, 0x2b},
+       {0x32, 0x00},
+       {0x33, 0x00},
+       {0x34, 0x90},
+
+       {0x40, 0x42},
+       {0x50, 0x2d},
+       {0x60, 0x28},
+       {0x70, 0x2d},
+
+       //Page 15
+       {0x03, 0x15}, 
+       {0x10, 0x0f}, 
+       {0x14, 0x52}, 
+       {0x15, 0x42}, 
+       {0x16, 0x32}, 
+       {0x17, 0x2f}, 
+
+       //CMC
+       {0x30, 0x8f}, 
+       {0x31, 0x59}, 
+       {0x32, 0x0a}, 
+       {0x33, 0x15}, 
+       {0x34, 0x5b}, 
+       {0x35, 0x06}, 
+       {0x36, 0x07}, 
+       {0x37, 0x40}, 
+       {0x38, 0x86}, 
+
+       //CMC OFS
+       {0x40, 0x95}, 
+       {0x41, 0x1f}, 
+       {0x42, 0x8a}, 
+       {0x43, 0x86}, 
+       {0x44, 0x0a}, 
+       {0x45, 0x84}, 
+       {0x46, 0x87}, 
+       {0x47, 0x9b}, 
+       {0x48, 0x23}, 
+
+       //CMC POFS
+       {0x50, 0x8c}, 
+       {0x51, 0x0c}, 
+       {0x52, 0x00}, 
+       {0x53, 0x07}, 
+       {0x54, 0x17}, 
+       {0x55, 0x9d}, 
+       {0x56, 0x00}, 
+       {0x57, 0x0b}, 
+       {0x58, 0x89}, 
+
+       {0x80, 0x03},
+       {0x85, 0x40},
+       {0x87, 0x02},
+       {0x88, 0x00},
+       {0x89, 0x00},
+       {0x8a, 0x00},
+
+       {0x03, 0x16}, 
+       {0x10, 0x31}, 
+       {0x18, 0x37},
+       {0x19, 0x36},
+       {0x1a, 0x0e},
+       {0x1b, 0x01},
+       {0x1c, 0xdc},
+       {0x1d, 0xfe},
+/* original
+       {0x30, 0x00}, 
+       {0x31, 0x06}, 
+       {0x32, 0x1d}, 
+       {0x33, 0x33}, 
+       {0x34, 0x53}, 
+       {0x35, 0x6c}, 
+       {0x36, 0x81}, 
+       {0x37, 0x94}, 
+       {0x38, 0xa4}, 
+       {0x39, 0xb3}, 
+       {0x3a, 0xc0}, 
+       {0x3b, 0xcb}, 
+       {0x3c, 0xd5}, 
+       {0x3d, 0xde}, 
+       {0x3e, 0xe6}, 
+       {0x3f, 0xee}, 
+       {0x40, 0xf5}, 
+       {0x41, 0xfc}, 
+       {0x42, 0xff}, 
+
+       {0x50, 0x00}, 
+       {0x51, 0x03}, 
+       {0x52, 0x19}, 
+       {0x53, 0x34}, 
+       {0x54, 0x58}, 
+       {0x55, 0x75}, 
+       {0x56, 0x8d}, 
+       {0x57, 0xa1}, 
+       {0x58, 0xb2}, 
+       {0x59, 0xbe}, 
+       {0x5a, 0xc9}, 
+       {0x5b, 0xd2}, 
+       {0x5c, 0xdb}, 
+       {0x5d, 0xe3}, 
+       {0x5e, 0xeb}, 
+       {0x5f, 0xf0}, 
+       {0x60, 0xf5}, 
+       {0x61, 0xf7}, 
+       {0x62, 0xf8}, 
+
+       {0x70, 0x00}, 
+       {0x71, 0x08}, 
+       {0x72, 0x17}, 
+       {0x73, 0x2f}, 
+       {0x74, 0x53}, 
+       {0x75, 0x6c}, 
+       {0x76, 0x81}, 
+       {0x77, 0x94}, 
+       {0x78, 0xa4}, 
+       {0x79, 0xb3}, 
+       {0x7a, 0xc0}, 
+       {0x7b, 0xcb}, 
+       {0x7c, 0xd5}, 
+       {0x7d, 0xde}, 
+       {0x7e, 0xe6}, 
+       {0x7f, 0xee}, 
+       {0x80, 0xf4}, 
+       {0x81, 0xfa}, 
+       {0x82, 0xff}, 
+*/    
+       {0x30, 0x00}, 
+       {0x31, 0x08}, 
+       {0x32, 0x1f}, 
+       {0x33, 0x35}, 
+       {0x34, 0x55}, 
+       {0x35, 0x6e}, 
+       {0x36, 0x83}, 
+       {0x37, 0x96}, 
+       {0x38, 0xa6}, 
+       {0x39, 0xb5}, 
+       {0x3a, 0xc2}, 
+       {0x3b, 0xcd}, 
+       {0x3c, 0xd7}, 
+       {0x3d, 0xe0}, 
+       {0x3e, 0xe8}, 
+       {0x3f, 0xf0}, 
+       {0x40, 0xf7}, 
+       {0x41, 0xfe}, 
+       {0x42, 0xff}, 
+
+       {0x50, 0x00}, 
+       {0x51, 0x05}, 
+       {0x52, 0x1b}, 
+       {0x53, 0x36}, 
+       {0x54, 0x5a}, 
+       {0x55, 0x77}, 
+       {0x56, 0x8f}, 
+       {0x57, 0xa3}, 
+       {0x58, 0xb4}, 
+       {0x59, 0xc0}, 
+       {0x5a, 0xcb}, 
+       {0x5b, 0xd4}, 
+       {0x5c, 0xde}, 
+       {0x5d, 0xe5}, 
+       {0x5e, 0xed}, 
+       {0x5f, 0xf2}, 
+       {0x60, 0xf7}, 
+       {0x61, 0xf9}, 
+       {0x62, 0xfa}, 
+
+       {0x70, 0x00}, 
+       {0x71, 0x0a}, 
+       {0x72, 0x19}, 
+       {0x73, 0x31}, 
+       {0x74, 0x55}, 
+       {0x75, 0x6e}, 
+       {0x76, 0x83}, 
+       {0x77, 0x96}, 
+       {0x78, 0xa6}, 
+       {0x79, 0xb5}, 
+       {0x7a, 0xc2}, 
+       {0x7b, 0xcd}, 
+       {0x7c, 0xd7}, 
+       {0x7d, 0xe0}, 
+       {0x7e, 0xe8}, 
+       {0x7f, 0xf0}, 
+       {0x80, 0xf6}, 
+       {0x81, 0xfc}, 
+       {0x82, 0xff}, 
+
+       
+       {0x03, 0x17}, 
+       {0xc4, 0x6e}, 
+       {0xc5, 0x5c}, 
+
+       {0x03, 0x20}, 
+       {0x10, 0x1c},
+       {0x18, 0x38},
+       {0x20, 0x01}, 
+       {0x21, 0x30},
+       {0x22, 0x10},
+       {0x23, 0x00},
+       {0x24, 0x04},
+
+       {0x28, 0xff},
+       {0x29, 0xad},
+
+       {0x2a, 0xf0},
+       {0x2b, 0x34},
+       {0x30, 0x78},
+       {0x2c, 0xc3},
+       {0x2d, 0x5f},
+       {0x2e, 0x33},
+       //{0x30, 0xf8},
+       {0x32, 0x03},
+       {0x33, 0x2e},
+       {0x34, 0x30},
+       {0x35, 0xd4},
+       {0x36, 0xfe},
+       {0x37, 0x32},
+       {0x38, 0x04},
+       {0x47, 0xf0},
+
+       //Y_Frame TH
+       {0x50, 0x45},
+       {0x51, 0x88},
+
+       {0x56, 0x10},
+       {0x57, 0xb7},
+       {0x58, 0x14},
+       {0x59, 0x88},
+       {0x5a, 0x04},
+
+       {0x60, 0x55}, 
+       {0x61, 0x55}, 
+       {0x62, 0x6a}, 
+       {0x63, 0xa9}, 
+       {0x64, 0x6a}, 
+       {0x65, 0xa9}, 
+       {0x66, 0x6a}, 
+       {0x67, 0xa9}, 
+       {0x68, 0x6b}, 
+       {0x69, 0xe9}, 
+       {0x6a, 0x6a}, 
+       {0x6b, 0xa9}, 
+       {0x6c, 0x6a}, 
+       {0x6d, 0xa9}, 
+       {0x6e, 0x55}, 
+       {0x6f, 0x55}, 
+       {0x70, 0x42}, 
+       {0x71, 0xBb},
+
+       // haunting control
+       {0x76, 0x21},
+       {0x77, 0x02},
+       {0x78, 0x22},
+       {0x79, 0x2a},
+
+       {0x78, 0x24},
+       {0x79, 0x23},
+       {0x7a, 0x23},
+       {0x7b, 0x22},
+       {0x7d, 0x23},
+       {0x83, 0x01},
+       {0x84, 0x5f},
+       {0x85, 0x6c},
+       {0x86, 0x02},
+       {0x87, 0x00},
+       {0x88, 0x05},
+       {0x89, 0x7c},
+       {0x8a, 0x00},
+       {0x8B, 0x75},
+       {0x8C, 0x00},
+       {0x8D, 0x61},
+       {0x8E, 0x00},
+
+       {0x98, 0xdc},
+       {0x99, 0x45},
+       {0x9a, 0x0d},
+       {0x9b, 0xde},
+       {0x9c, 0x08},
+       {0x9d, 0x0a},
+       {0x9e, 0x01},
+    {0x10, 0x9c},
+    {0x18, 0x30},
+    {0x90, 0x0c},
+    {0x91, 0x0c},
+    {0x92, 0xd8},   
+    {0x93, 0xd0},  
+    
+       {0x9f, 0x26}, 
+       {0xa0, 0x03},
+       {0xa1, 0xa9},
+       {0xa2, 0x80},
+       {0xb0, 0x1d},
+       {0xb1, 0x1a},
+       {0xb2, 0x60},
+       {0xb3, 0x1a},
+       {0xb4, 0x1a},
+       {0xb5, 0x44},
+       {0xb6, 0x2f},
+       {0xb7, 0x28},
+       {0xb8, 0x25},
+       {0xb9, 0x22},
+       {0xba, 0x21},
+       {0xbb, 0x20},
+       {0xbc, 0x1f},
+       {0xbd, 0x1f},
+       {0xc0, 0x30},
+       {0xc1, 0x20},
+       {0xc2, 0x20},
+       {0xc3, 0x20},
+       {0xc4, 0x08},
+       {0xc8, 0x60},
+       {0xc9, 0x40},
+       
+       //Page 22
+       {0x03, 0x22},
+       {0x10, 0x69},//lxh
+       {0x11, 0x2c},
+       {0x19, 0x01},
+       {0x20, 0x30},
+       {0x21, 0x80},
+       {0x23, 0x08},
+       {0x24, 0x01},
+
+       {0x30, 0x80},
+       {0x31, 0x80},
+       {0x38, 0x11},
+       {0x39, 0x34},
+       {0x40, 0xf7},
+
+       {0x41, 0x77},
+       {0x42, 0x55},
+       {0x43, 0xf0},
+       {0x44, 0x43}, 
+       {0x45, 0x33},
+       {0x46, 0x00}, 
+
+       {0x47, 0x94},
+
+       {0x50, 0xb2},
+       {0x51, 0x81},
+       {0x52, 0x98},
+
+       {0x80, 0x3d},//lxh 
+       {0x81, 0x20}, 
+       {0x82, 0x32},//lxh 
+
+       {0x83, 0x50}, 
+       {0x84, 0x20}, 
+       {0x85, 0x50}, 
+       {0x86, 0x20}, 
+
+       {0x87, 0x54}, 
+       {0x88, 0x20}, 
+       {0x89, 0x45}, 
+       {0x8a, 0x2a}, 
+
+       {0x8b, 0x46}, 
+       {0x8c, 0x3f}, 
+       {0x8d, 0x34}, 
+       {0x8e, 0x2c}, 
+
+       {0x8f, 0x60}, 
+       {0x90, 0x5f}, 
+       {0x91, 0x5c}, 
+       {0x92, 0x4C}, 
+       {0x93, 0x41}, 
+       {0x94, 0x3b}, 
+       {0x95, 0x36}, 
+       {0x96, 0x30}, 
+       {0x97, 0x27}, 
+       {0x98, 0x20}, 
+       {0x99, 0x1C}, 
+       {0x9a, 0x19}, 
+
+       {0x9b, 0x88}, 
+       {0x9c, 0x88}, 
+       {0x9d, 0x48}, 
+       {0x9e, 0x38}, 
+       {0x9f, 0x30}, 
+
+       {0xa0, 0x74}, 
+       {0xa1, 0x35}, 
+       {0xa2, 0xaf}, 
+       {0xa3, 0xf7}, 
+
+       {0xa4, 0x10}, 
+       {0xa5, 0x50}, 
+       {0xa6, 0xc4}, 
+
+       {0xad, 0x40},
+       {0xae, 0x4a},
+
+       {0xaf, 0x2a},
+       {0xb0, 0x29},
+
+       {0xb1, 0x20},
+       {0xb4, 0xff},
+       {0xb8, 0x6b},
+       {0xb9, 0x00},
+
+       {0x03, 0x24}, 
+       {0x10, 0x01}, 
+       {0x18, 0x06},
+       {0x30, 0x06},
+       {0x31, 0x90},
+       {0x32, 0x25},
+       {0x33, 0xa2},
+       {0x34, 0x26},
+       {0x35, 0x58},
+       {0x36, 0x60},
+       {0x37, 0x00},
+       {0x38, 0x50},
+       {0x39, 0x00},
+
+       {0x03, 0x20}, 
+       {0x10, 0x9c}, 
+       {0x03, 0x22}, 
+       {0x10, 0xe9}, 
+       
+       //Page 00
+       {0x03, 0x00}, 
+       {0x0e, 0x03}, 
+       {0x0e, 0x73}, 
+
+       {0x03, 0x00}, 
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00},
+       {0x03, 0x00}, 
+
+       {0x03, 0x00}, 
+       {0x01, 0xf8},
+
+       {END_REG, END_REG},
+
+};
+
+
+/* 1600X1200 UXGA capture */
+static struct reginfo sensor_uxga[] =
+{
+       {0x03, 0x00},
+       //{0x11, 0xa0}, 
+
+       {0x20, 0x00}, 
+       {0x21, 0x0a}, 
+       {0x22, 0x00}, 
+       {0x23, 0x0a}, 
+
+       {0x03, 0x10},
+       {0x3f, 0x00},
+
+       //Page12
+       {0x03, 0x12},
+       {0x20, 0x0f},
+       {0x21, 0x0f},
+       {0x90, 0x5d},
+
+       //Page13
+       {0x03, 0x13},
+       {0x80, 0xfd},
+
+       // 1600*1200    
+       {0x03,0x00},
+       {0x10,0x00},
+       
+       {END_REG, END_REG},
+};
+
+/* 1280X1024 SXGA */
+static struct reginfo sensor_sxga[] =
+{
+       {END_REG, END_REG},
+};
+static struct reginfo sensor_xga[] =
+{
+       {0x01, 0xf8},
+       {END_REG, END_REG},
+};
+/* 800X600 SVGA,30fps*/
+static struct reginfo sensor_svga[] =
+{
+#if 1
+       {0x03, 0x10},
+       {0x3f, 0x00},
+       
+
+       //Page12
+       {0x03, 0x12}, //Function
+       {0x20, 0x0f},
+       {0x21, 0x0f},
+       {0x90, 0x5d},  
+
+       //Page13
+       {0x03, 0x13}, //Function
+       {0x80, 0xfd}, //Function
+
+       // 800*600      
+       {0x03,0x00},
+       {0x10,0x91},//11
+       {0x20, 0x00},
+       {0x21, 0x04},
+       {0x22, 0x00},
+       {0x23, 0x07},
+       {0x24, 0x04},
+       {0x25, 0xb0},
+       {0x26, 0x06},
+       {0x27, 0x40},
+       
+       {0x03, 0x20},
+       {0x8b, 0x1d},
+       {0x8c, 0x4c},
+       {0x8d, 0x18},
+       {0x8e, 0x6a},
+       
+       {0x03, 0x20},
+       {0x03, 0x20}, 
+#endif
+       {END_REG, END_REG},
+};
+
+/* 640X480 VGA */
+static struct reginfo sensor_vga[] =
+{
+       {END_REG, END_REG},
+};
+
+/* 352X288 CIF */
+static struct reginfo sensor_cif[] =
+{};
+
+/* 320*240 QVGA */
+static  struct reginfo sensor_qvga[] =
+{};
+
+/* 176X144 QCIF*/
+static struct reginfo sensor_qcif[] =
+{};
+
+
+static  struct reginfo sensor_ClrFmt_YUYV[]=
+{
+
+    {0x00, 0x00}
+};
+
+static  struct reginfo sensor_ClrFmt_UYVY[]=
+{
+
+    {0x00, 0x00}
+};
+
+#if CONFIG_SENSOR_WhiteBalance
+static  struct reginfo sensor_WhiteB_Auto[]=
+{
+       {0x03, 0x22},
+       {0x10, 0x69},
+       {0x80, 0x3d},
+       {0x81, 0x20},
+       {0x82, 0x32},
+       {0x83, 0x50},
+       {0x84, 0x20},
+       {0x85, 0x50},
+       {0x86, 0x20},
+       {0x10, 0xe9},   
+       {END_REG, END_REG},
+};
+/* Cloudy Colour Temperature : 6500K - 8000K  */
+static  struct reginfo sensor_WhiteB_Cloudy[]=
+{
+       {0x03, 0x22},
+       {0x10, 0x69},
+       {0x80, 0x49},
+       {0x81, 0x20},
+       {0x82, 0x24},
+       {0x83, 0x50},
+       {0x84, 0x45},
+       {0x85, 0x24},
+       {0x86, 0x1e},
+       {0x10, 0xe9},   
+       {END_REG, END_REG},
+};
+/* ClearDay Colour Temperature : 5000K - 6500K  */
+static  struct reginfo sensor_WhiteB_ClearDay[]=
+{
+    //Sunny
+       {0x03, 0x22},
+       {0x10, 0x69},
+       {0x80, 0x45},
+       {0x81, 0x20},
+       {0x82, 0x27},
+       {0x83, 0x44},
+       {0x84, 0x3f},
+       {0x85, 0x29},
+       {0x86, 0x23},
+       {END_REG, END_REG},
+};
+/* Office Colour Temperature : 3500K - 5000K  */
+static  struct reginfo sensor_WhiteB_TungstenLamp1[]=
+{
+    //incandescense
+       {0x03, 0x22},
+       {0x10, 0x69},
+       {0x80, 0x33},
+       {0x81, 0x20},
+       {0x82, 0x3d},
+       {0x83, 0x2e},
+       {0x84, 0x24},
+       {0x85, 0x43},
+       {0x86, 0x3d},
+       {END_REG, END_REG},
+
+};
+/* Home Colour Temperature : 2500K - 3500K  */
+static  struct reginfo sensor_WhiteB_TungstenLamp2[]=
+{
+    //Home
+       {0x03, 0x22},
+       {0x10, 0x69},
+       {0x80, 0x45},
+       {0x81, 0x20},
+       {0x82, 0x2f},
+       {0x83, 0x38},
+       {0x84, 0x32},
+       {0x85, 0x39},
+       {0x86, 0x33},   
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,
+    sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,
+};
+#endif
+
+#if CONFIG_SENSOR_Brightness
+static  struct reginfo sensor_Brightness0[]=
+{
+    // Brightness -2
+    {0x03, 0x10},
+    {0x40, 0xa0},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Brightness1[]=
+{
+    // Brightness -1
+       {0x03, 0x10},
+    {0x40, 0x90},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Brightness2[]=
+{
+    //  Brightness 0
+       {0x03, 0x10},
+    {0x40, 0x00},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Brightness3[]=
+{
+    // Brightness +1
+       {0x03, 0x10},
+    {0x40, 0x10},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Brightness4[]=
+{
+    //  Brightness +2
+       {0x03, 0x10},
+    {0x40, 0x20},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Brightness5[]=
+{
+    //  Brightness +3
+    {0x03, 0x10},
+    {0x40, 0x30},
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,
+    sensor_Brightness4, sensor_Brightness5,NULL,
+};
+
+#endif
+
+#if CONFIG_SENSOR_Effect
+static  struct reginfo sensor_Effect_Normal[] =
+{
+       {0x03, 0x10},
+       {0x11, 0x03},
+       {0x12, 0x00},
+       {0x13, 0x00},   
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Effect_WandB[] =
+{
+       {0x03, 0x10},
+       {0x11, 0x03},
+       {0x12, 0x03},
+       {0x13, 0x02},
+       {0x44, 0x80},
+       {0x45, 0x80},
+       {0x47, 0x7f},   
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Effect_Sepia[] =
+{
+       {0x03, 0x10},
+       {0x11, 0x03},
+       {0x12, 0x23},
+       {0x13, 0x00},
+       {0x44, 0x70},
+       {0x45, 0x98},
+       {0x47, 0x7f},   
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Effect_Negative[] =
+{
+    //Negative
+       {0x03, 0x10},
+       {0x11, 0x03},
+       {0x12, 0x08},
+       {0x13, 0x02},
+       {0x14, 0x00},   
+       {0x44, 0x80},
+       {0x45, 0x80},
+       {0x47, 0x7f},   
+       {END_REG, END_REG},
+};
+static  struct reginfo sensor_Effect_Bluish[] =
+{
+    // Bluish
+       {0x03, 0x10},
+       {0x11, 0x03},
+       {0x12, 0x03},
+       {0x13, 0x02},
+       {0x44, 0xb0},
+       {0x45, 0x40},
+       {0x47, 0x7f},   
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Effect_Green[] =
+{
+    //  Greenish
+    {0x03, 0x10},
+       {0x11, 0x03},
+       {0x12, 0x03},
+       {0x13, 0x02},
+       {0x44, 0x30},
+       {0x45, 0x50},
+       {0x47, 0x7f},   
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,
+    sensor_Effect_Bluish, sensor_Effect_Green,NULL,
+};
+#endif
+#if CONFIG_SENSOR_Exposure
+static  struct reginfo sensor_Exposure0[]=
+{
+    //-3
+
+};
+
+static  struct reginfo sensor_Exposure1[]=
+{
+    //-2
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Exposure2[]=
+{
+    //-0.3EV
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Exposure3[]=
+{
+    //default
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Exposure4[]=
+{
+    // 1
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Exposure5[]=
+{
+    // 2
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Exposure6[]=
+{
+    // 3
+
+       {END_REG, END_REG},
+};
+
+static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,
+    sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,
+};
+#endif
+#if CONFIG_SENSOR_Saturation
+static  struct reginfo sensor_Saturation0[]=
+{
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Saturation1[]=
+{
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Saturation2[]=
+{
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};
+
+#endif
+#if CONFIG_SENSOR_Contrast
+static  struct reginfo sensor_Contrast0[]=
+{
+    //Contrast -3
+  
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Contrast1[]=
+{
+    //Contrast -2
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Contrast2[]=
+{
+    // Contrast -1
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Contrast3[]=
+{
+    //Contrast 0
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Contrast4[]=
+{
+    //Contrast +1
+
+       {END_REG, END_REG},
+};
+
+
+static  struct reginfo sensor_Contrast5[]=
+{
+    //Contrast +2
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Contrast6[]=
+{
+    //Contrast +3
+
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,
+    sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,
+};
+
+#endif
+#if CONFIG_SENSOR_Mirror
+static  struct reginfo sensor_MirrorOn[]=
+{
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_MirrorOff[]=
+{
+
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,};
+#endif
+#if CONFIG_SENSOR_Flip
+static  struct reginfo sensor_FlipOn[]=
+{
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_FlipOff[]=
+{
+
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,};
+
+#endif
+#if CONFIG_SENSOR_Scene
+static  struct reginfo sensor_SceneAuto[] =
+{
+
+       {END_REG, END_REG},     
+};
+
+static  struct reginfo sensor_SceneNight[] =
+{
+
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};
+
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+static struct reginfo sensor_Zoom0[] =
+{
+       {END_REG, END_REG},
+};
+
+static struct reginfo sensor_Zoom1[] =
+{
+       {END_REG, END_REG},
+};
+
+static struct reginfo sensor_Zoom2[] =
+{
+       {END_REG, END_REG},
+};
+
+
+static struct reginfo sensor_Zoom3[] =
+{
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};
+#endif
+static const struct v4l2_querymenu sensor_menus[] =
+{
+       #if CONFIG_SENSOR_WhiteBalance
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 0,  .name = "auto",  .reserved = 0, }, {  .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 1, .name = "incandescent",  .reserved = 0,},
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 2,  .name = "fluorescent", .reserved = 0,}, {  .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3,  .name = "daylight", .reserved = 0,},
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 4,  .name = "cloudy-daylight", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Effect
+    { .id = V4L2_CID_EFFECT,  .index = 0,  .name = "none",  .reserved = 0, }, {  .id = V4L2_CID_EFFECT,  .index = 1, .name = "mono",  .reserved = 0,},
+    { .id = V4L2_CID_EFFECT,  .index = 2,  .name = "negative", .reserved = 0,}, {  .id = V4L2_CID_EFFECT, .index = 3,  .name = "sepia", .reserved = 0,},
+    { .id = V4L2_CID_EFFECT,  .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT,  .index = 5,  .name = "aqua", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Scene
+    { .id = V4L2_CID_SCENE,  .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE,  .index = 1,  .name = "night", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Flash
+    { .id = V4L2_CID_FLASH,  .index = 0,  .name = "off",  .reserved = 0, }, {  .id = V4L2_CID_FLASH,  .index = 1, .name = "auto",  .reserved = 0,},
+    { .id = V4L2_CID_FLASH,  .index = 2,  .name = "on", .reserved = 0,}, {  .id = V4L2_CID_FLASH, .index = 3,  .name = "torch", .reserved = 0,},
+    #endif
+};
+
+static const struct v4l2_queryctrl sensor_controls[] =
+{
+       #if CONFIG_SENSOR_WhiteBalance
+    {
+        .id            = V4L2_CID_DO_WHITE_BALANCE,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "White Balance Control",
+        .minimum       = 0,
+        .maximum       = 4,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Brightness
+       {
+        .id            = V4L2_CID_BRIGHTNESS,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Brightness Control",
+        .minimum       = -3,
+        .maximum       = 2,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Effect
+       {
+        .id            = V4L2_CID_EFFECT,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Effect Control",
+        .minimum       = 0,
+        .maximum       = 5,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Exposure
+       {
+        .id            = V4L2_CID_EXPOSURE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Exposure Control",
+        .minimum       = 0,
+        .maximum       = 6,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Saturation
+       {
+        .id            = V4L2_CID_SATURATION,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Saturation Control",
+        .minimum       = 0,
+        .maximum       = 2,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Contrast
+       {
+        .id            = V4L2_CID_CONTRAST,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Contrast Control",
+        .minimum       = -3,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Mirror
+       {
+        .id            = V4L2_CID_HFLIP,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Mirror Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 1,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Flip
+       {
+        .id            = V4L2_CID_VFLIP,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Flip Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 1,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Scene
+    {
+        .id            = V4L2_CID_SCENE,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Scene Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_DigitalZoom
+    {
+        .id            = V4L2_CID_ZOOM_RELATIVE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "DigitalZoom Control",
+        .minimum       = -1,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }, {
+        .id            = V4L2_CID_ZOOM_ABSOLUTE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "DigitalZoom Control",
+        .minimum       = 0,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Focus
+       {
+        .id            = V4L2_CID_FOCUS_RELATIVE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Focus Control",
+        .minimum       = -1,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }, {
+        .id            = V4L2_CID_FOCUS_ABSOLUTE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Focus Control",
+        .minimum       = 0,
+        .maximum       = 255,
+        .step          = 1,
+        .default_value = 125,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Flash
+       {
+        .id            = V4L2_CID_FLASH,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Flash Control",
+        .minimum       = 0,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+};
+
+static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did);
+static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client);
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+static int sensor_g_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);
+static int sensor_s_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);
+static int sensor_resume(struct soc_camera_device *icd);
+static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);
+#if CONFIG_SENSOR_Effect
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+#endif
+static int sensor_deactivate(struct i2c_client *client);
+
+static struct soc_camera_ops sensor_ops =
+{
+    .suspend                     = sensor_suspend,
+    .resume                       = sensor_resume,
+    .set_bus_param             = sensor_set_bus_param,
+    .query_bus_param   = sensor_query_bus_param,
+    .controls          = sensor_controls,
+    .menus                         = sensor_menus,
+    .num_controls              = ARRAY_SIZE(sensor_controls),
+    .num_menus         = ARRAY_SIZE(sensor_menus),
+};
+
+#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
+       { .name = _name, .depth = _depth, .fourcc = _fourcc, \
+       .colorspace = _colorspace }
+
+#define JPG_FMT(_name, _depth, _fourcc) \
+       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+
+static const struct soc_camera_data_format sensor_colour_formats[] = {
+       JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY),
+       JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),
+};
+
+typedef struct sensor_info_priv_s
+{
+    int whiteBalance;
+    int brightness;
+    int contrast;
+    int saturation;
+    int effect;
+    int scene;
+    int digitalzoom;
+    int focus;
+    int flash;
+    int exposure;
+       bool snap2preview;
+       bool video2preview;
+    unsigned char mirror;                                        /* HFLIP */
+    unsigned char flip;                                          /* VFLIP */
+    unsigned int winseqe_cur_addr;
+       unsigned int pixfmt;
+
+} sensor_info_priv_t;
+
+struct sensor
+{
+    struct v4l2_subdev subdev;
+    struct i2c_client *client;
+    sensor_info_priv_t info_priv;
+    int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */
+#if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_t tasklock_cnt;
+#endif
+       struct rk29camera_platform_data *sensor_io_request;
+    struct rk29camera_gpio_res *sensor_gpio_res;
+};
+
+static struct sensor* to_sensor(const struct i2c_client *client)
+{
+    return container_of(i2c_get_clientdata(client), struct sensor, subdev);
+}
+
+static int sensor_task_lock(struct i2c_client *client, int lock)
+{
+#if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
+    struct sensor *sensor = to_sensor(client);
+
+       if (lock) {
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
+                       preempt_disable();
+               }
+
+               atomic_add(1, &sensor->tasklock_cnt);
+       } else {
+               if (atomic_read(&sensor->tasklock_cnt) > 0) {
+                       atomic_sub(1, &sensor->tasklock_cnt);
+
+                       if (atomic_read(&sensor->tasklock_cnt) == 0)
+                               preempt_enable();
+               }
+       }
+       return 0;
+sensor_task_lock_err:
+       return -1;  
+#else
+    return 0;
+#endif
+}
+
+static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
+{
+    int err,cnt;
+    u8 buf[2];
+    struct i2c_msg msg[1];
+
+    buf[0] = reg;
+    buf[1] = val;
+       
+    msg->addr = client->addr;
+    msg->flags = client->flags;
+    msg->buf = buf;
+    msg->len = sizeof(buf);
+    msg->scl_rate = CONFIG_SENSOR_I2C_SPEED;         /* ddl@rock-chips.com : 100kHz */
+    msg->read_type = 0;               /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */
+
+    cnt = 3;
+    err = -EAGAIN;
+
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+        err = i2c_transfer(client->adapter, msg, 1);
+
+        if (err >= 0) {
+            return 0;
+        } else {
+               SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);
+            udelay(10);
+        }
+    }
+
+    return err;
+}
+
+/* sensor register read */
+static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+    int err,cnt;
+    u8 buf[1];
+    struct i2c_msg msg[2];
+
+    buf[0] = reg ;
+
+    msg[0].addr = client->addr;
+    msg[0].flags = client->flags;
+    msg[0].buf = buf;
+    msg[0].len = sizeof(buf);
+    msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED;       /* ddl@rock-chips.com : 100kHz */
+    msg[0].read_type = 2;   /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */
+
+    msg[1].addr = client->addr;
+    msg[1].flags = client->flags|I2C_M_RD;
+    msg[1].buf = buf;
+    msg[1].len = 1;
+    msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED;                       /* ddl@rock-chips.com : 100kHz */
+    msg[1].read_type = 2;                             /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */
+
+    cnt = 3;
+    err = -EAGAIN;
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+        err = i2c_transfer(client->adapter, msg, 2);
+
+        if (err >= 0) {
+            *val = buf[0];
+            return 0;
+        } else {
+               SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val);
+            udelay(10);
+        }
+    }
+
+    return err;
+}
+
+
+/* write a array of registers  */
+static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int err = 0, cnt;
+    int i = 0;
+#if CONFIG_SENSOR_I2C_RDWRCHK    
+       char valchk;
+#endif
+
+       cnt = 0;
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
+    while (regarray[i].reg != END_REG)
+    {
+        err = sensor_write(client, regarray[i].reg, regarray[i].val);
+        if (err < 0)
+        {
+            if (cnt-- > 0) {
+                           SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg);
+                               i = 0;
+                               continue;
+            } else {
+                SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING());
+                err = -EPERM;
+                               goto sensor_write_array_end;
+            }
+        } else {
+        #if CONFIG_SENSOR_I2C_RDWRCHK
+                       //mdelay(5);
+                       sensor_read(client, regarray[i].reg, &valchk);
+                       if (valchk != regarray[i].val)
+                               SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+               #endif
+        }
+        i++;
+    }
+
+sensor_write_array_end:
+       sensor_task_lock(client,0);
+       return err;
+}
+static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int cnt;
+    int i = 0;
+       char valchk;
+
+       cnt = 0;
+       valchk = 0;
+    while (regarray[i].reg != 0)
+    {
+               sensor_read(client, regarray[i].reg, &valchk);
+               if (valchk != regarray[i].val)
+                       SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+
+        i++;
+    }
+    return 0;
+}
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
+{
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       int ret = 0;
+
+    SENSOR_DG("%s %s  cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
+       switch (cmd)
+       {
+               case Sensor_PowerDown:
+               {
+                       if (icl->powerdown) {
+                               ret = icl->powerdown(icd->pdev, on);
+                               if (ret == RK29_CAM_IO_SUCCESS) {
+                                       if (on == 0) {
+                                               mdelay(2);
+                                               if (icl->reset)
+                                                       icl->reset(icd->pdev);
+                                       }
+                               } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {
+                                       ret = -ENODEV;
+                                       goto sensor_power_end;
+                               }
+                       }
+                       break;
+               }
+               case Sensor_Flash:
+               {
+                       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+               struct sensor *sensor = to_sensor(client);
+
+                       if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
+                               sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
+                       }
+            break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_power_end:
+       return ret;
+}
+static int sensor_init(struct v4l2_subdev *sd, u32 val)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl;
+    char value;
+    int ret;
+
+    SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
+
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_INIT_ERR;
+       }
+
+    /* soft reset */
+       if (sensor_task_lock(client,1)<0)
+               goto sensor_INIT_ERR;
+#if 1  
+    ret = sensor_write(client, 0x01, 0xF9);
+    if (ret != 0)
+    {
+        SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING());
+        ret = -ENODEV;
+               goto sensor_INIT_ERR;
+    }
+
+    mdelay(5);  //delay 5 microseconds
+       /* check if it is an sensor sensor */
+    ret = sensor_read(client, 0x04, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id high byte failed\n");
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+
+   
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+    if (value == SENSOR_ID) {
+        sensor->model = SENSOR_V4L2_IDENT;
+    } else {
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+#endif
+    ret = sensor_write_array(client, sensor_init_data);
+    if (ret != 0)
+    {
+        SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
+        goto sensor_INIT_ERR;
+    }
+       sensor_task_lock(client,0);
+    //icd->user_width = SENSOR_INIT_WIDTH;
+    //icd->user_height = SENSOR_INIT_HEIGHT;
+    sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;
+       sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT;
+
+    /* sensor sensor information for initialization  */
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+       if (qctrl)
+       sensor->info_priv.whiteBalance = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS);
+       if (qctrl)
+       sensor->info_priv.brightness = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+       if (qctrl)
+       sensor->info_priv.effect = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE);
+       if (qctrl)
+        sensor->info_priv.exposure = qctrl->default_value;
+
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION);
+       if (qctrl)
+        sensor->info_priv.saturation = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST);
+       if (qctrl)
+        sensor->info_priv.contrast = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP);
+       if (qctrl)
+        sensor->info_priv.mirror = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP);
+       if (qctrl)
+        sensor->info_priv.flip = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE);
+       if (qctrl)
+        sensor->info_priv.scene = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);
+       if (qctrl)
+        sensor->info_priv.digitalzoom = qctrl->default_value;
+
+    /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code  */
+       #if CONFIG_SENSOR_Focus
+    sensor_set_focus();
+    qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);
+       if (qctrl)
+        sensor->info_priv.focus = qctrl->default_value;
+       #endif
+
+       #if CONFIG_SENSOR_Flash
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);
+       if (qctrl)
+        sensor->info_priv.flash = qctrl->default_value;
+    #endif
+
+    SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);
+
+    return 0;
+sensor_INIT_ERR:
+       sensor_task_lock(client,0);
+       sensor_deactivate(client);
+    return ret;
+}
+
+static int sensor_deactivate(struct i2c_client *client)
+{
+       struct soc_camera_device *icd = client->dev.platform_data;
+
+       SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
+
+       /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);
+
+       /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
+       icd->user_width = SENSOR_INIT_WIDTH;
+    icd->user_height = SENSOR_INIT_HEIGHT;
+       msleep(100);
+       return 0;
+}
+
+static  struct reginfo sensor_power_down_sequence[]=
+{
+    {0x00,0x00}
+};
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
+{
+    int ret;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if (pm_msg.event == PM_EVENT_SUSPEND) {
+        SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());
+        ret = sensor_write_array(client, sensor_power_down_sequence) ;
+        if (ret != 0) {
+            SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);
+            return ret;
+        } else {
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);
+            if (ret < 0) {
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
+                return -EINVAL;
+            }
+        }
+    } else {
+        SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+    return 0;
+}
+
+static int sensor_resume(struct soc_camera_device *icd)
+{
+       int ret;
+
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);
+    if (ret < 0) {
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+       SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());
+
+    return 0;
+
+}
+
+static int sensor_set_bus_param(struct soc_camera_device *icd,
+                                unsigned long flags)
+{
+
+    return 0;
+}
+
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)
+{
+    struct soc_camera_link *icl = to_soc_camera_link(icd);
+    unsigned long flags = SENSOR_BUS_PARAM;
+
+    return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+
+    pix->width         = icd->user_width;
+    pix->height                = icd->user_height;
+    pix->pixelformat   = sensor->info_priv.pixfmt;
+    pix->field         = V4L2_FIELD_NONE;
+    pix->colorspace            = V4L2_COLORSPACE_JPEG;
+
+    return 0;
+}
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+       const struct v4l2_queryctrl *qctrl;
+       struct soc_camera_device *icd = client->dev.platform_data;
+    struct reginfo *winseqe_set_addr=NULL;
+    int ret=0, set_w,set_h;
+
+       if (sensor->info_priv.pixfmt != pix->pixelformat) {
+               switch (pix->pixelformat)
+               {
+                       case V4L2_PIX_FMT_YUYV:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_YUYV;
+                               break;
+                       }
+                       case V4L2_PIX_FMT_UYVY:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_UYVY;
+                               break;
+                       }
+                       default:
+                               break;
+               }
+               if (winseqe_set_addr != NULL) {
+            sensor_write_array(client, winseqe_set_addr);
+                       sensor->info_priv.pixfmt = pix->pixelformat;
+
+                       SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+               } else {
+                       SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+               }
+       }
+
+    set_w = pix->width;
+    set_h = pix->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg != END_REG))
+       {
+               winseqe_set_addr = sensor_qcif;
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg != END_REG))
+    {
+        winseqe_set_addr = sensor_qvga;
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg != END_REG))
+    {
+        winseqe_set_addr = sensor_cif;
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg != END_REG))
+    {
+        winseqe_set_addr = sensor_vga;
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg != END_REG))
+    {
+        winseqe_set_addr = sensor_svga;
+        set_w = 800;
+        set_h = 600;
+    }
+       else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg != END_REG))
+    {
+        winseqe_set_addr = sensor_xga;
+        set_w = 1024;
+        set_h = 768;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg != END_REG))
+    {
+        winseqe_set_addr = sensor_sxga;
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg != END_REG))
+    {
+        winseqe_set_addr = sensor_uxga;
+        set_w = 1600;
+        set_h = 1200;
+    }
+    else
+    {
+        winseqe_set_addr = SENSOR_INIT_WINSEQADR;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;
+
+               SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);
+    }
+
+    if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr) {
+        #if CONFIG_SENSOR_Flash
+        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_On);
+                SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
+            }           
+        } else {                                        /* ddl@rock-chips.com : Video */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());
+            }
+        }
+        #endif
+        ret |= sensor_write_array(client, winseqe_set_addr);
+        if (ret != 0) {
+            SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
+            #if CONFIG_SENSOR_Flash
+            if (sensor_fmt_capturechk(sd,f) == true) {
+                if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                    sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                    SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
+                }
+            }
+            #endif
+            goto sensor_s_fmt_end;
+        }
+
+        sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
+
+               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+        #if CONFIG_SENSOR_Effect
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+        #endif
+        #if CONFIG_SENSOR_WhiteBalance
+                       if (sensor->info_priv.whiteBalance != 0) {
+                               qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                               sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       }
+        #endif
+                       sensor->info_priv.snap2preview = true;
+               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               #if CONFIG_SENSOR_Effect
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+        #endif
+        #if CONFIG_SENSOR_WhiteBalance
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+        #endif
+                       sensor->info_priv.video2preview = true;
+               } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {
+               #if CONFIG_SENSOR_Effect
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+        #endif
+        #if CONFIG_SENSOR_WhiteBalance
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+        #endif
+                       sensor->info_priv.video2preview = false;
+                       sensor->info_priv.snap2preview = false;
+               }
+
+        SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
+    }
+    else
+    {
+        SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
+    }
+
+       pix->width = set_w;
+    pix->height = set_h;
+
+sensor_s_fmt_end:
+    return ret;
+}
+
+static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+    bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY ||
+        pix->pixelformat == V4L2_PIX_FMT_YUYV;
+
+    /*
+    * With Bayer format enforce even side lengths, but let the user play
+    * with the starting pixel
+    */
+
+    if (pix->height > SENSOR_MAX_HEIGHT)
+        pix->height = SENSOR_MAX_HEIGHT;
+    else if (pix->height < SENSOR_MIN_HEIGHT)
+        pix->height = SENSOR_MIN_HEIGHT;
+    else if (bayer)
+        pix->height = ALIGN(pix->height, 2);
+
+    if (pix->width > SENSOR_MAX_WIDTH)
+        pix->width = SENSOR_MAX_WIDTH;
+    else if (pix->width < SENSOR_MIN_WIDTH)
+        pix->width = SENSOR_MIN_WIDTH;
+    else if (bayer)
+        pix->width = ALIGN(pix->width, 2);
+
+    return 0;
+}
+
+ static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
+{
+    struct i2c_client *client = sd->priv;
+
+    if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
+        return -EINVAL;
+
+    if (id->match.addr != client->addr)
+        return -ENODEV;
+
+    id->ident = SENSOR_V4L2_IDENT;      /* ddl@rock-chips.com :  Return OV2655  identifier */
+    id->revision = 0;
+
+    return 0;
+}
+#if CONFIG_SENSOR_Brightness
+static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Effect
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_EffectSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Exposure
+static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Saturation
+static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Contrast
+static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Mirror
+static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Flip
+static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_FlipSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Scene
+static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_SceneSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl_info;
+    int digitalzoom_cur, digitalzoom_total;
+
+       qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);
+       if (qctrl_info)
+               return -EINVAL;
+
+    digitalzoom_cur = sensor->info_priv.digitalzoom;
+    digitalzoom_total = qctrl_info->maximum;
+
+    if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total))
+    {
+        SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
+        return -EINVAL;
+    }
+
+    if  ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum))
+    {
+        SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
+        return -EINVAL;
+    }
+
+    if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total))
+    {
+        *value = digitalzoom_total - digitalzoom_cur;
+    }
+
+    if ((*value < 0) && ((digitalzoom_cur + *value) < 0))
+    {
+        *value = 0 - digitalzoom_cur;
+    }
+
+    digitalzoom_cur += *value;
+
+    if (sensor_ZoomSeqe[digitalzoom_cur] != NULL)
+    {
+        if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0)
+        {
+            SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+            return -EINVAL;
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value);
+        return 0;
+    }
+
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Flash
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{    
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {
+        if (value == 3) {       /* ddl@rock-chips.com: torch */
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Torch);   /* Flash On */
+        } else {
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+        return 0;
+    }
+    
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct v4l2_queryctrl *qctrl;
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ctrl->id)
+    {
+        case V4L2_CID_BRIGHTNESS:
+            {
+                ctrl->value = sensor->info_priv.brightness;
+                break;
+            }
+        case V4L2_CID_SATURATION:
+            {
+                ctrl->value = sensor->info_priv.saturation;
+                break;
+            }
+        case V4L2_CID_CONTRAST:
+            {
+                ctrl->value = sensor->info_priv.contrast;
+                break;
+            }
+        case V4L2_CID_DO_WHITE_BALANCE:
+            {
+                ctrl->value = sensor->info_priv.whiteBalance;
+                break;
+            }
+        case V4L2_CID_EXPOSURE:
+            {
+                ctrl->value = sensor->info_priv.exposure;
+                break;
+            }
+        case V4L2_CID_HFLIP:
+            {
+                ctrl->value = sensor->info_priv.mirror;
+                break;
+            }
+        case V4L2_CID_VFLIP:
+            {
+                ctrl->value = sensor->info_priv.flip;
+                break;
+            }
+        default :
+                break;
+    }
+    return 0;
+}
+
+
+
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    struct soc_camera_device *icd = client->dev.platform_data;
+    const struct v4l2_queryctrl *qctrl;
+
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ctrl->id)
+    {
+#if CONFIG_SENSOR_Brightness
+        case V4L2_CID_BRIGHTNESS:
+            {
+                if (ctrl->value != sensor->info_priv.brightness)
+                {
+                    if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.brightness = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Exposure
+        case V4L2_CID_EXPOSURE:
+            {
+                if (ctrl->value != sensor->info_priv.exposure)
+                {
+                    if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.exposure = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Saturation
+        case V4L2_CID_SATURATION:
+            {
+                if (ctrl->value != sensor->info_priv.saturation)
+                {
+                    if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.saturation = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Contrast
+        case V4L2_CID_CONTRAST:
+            {
+                if (ctrl->value != sensor->info_priv.contrast)
+                {
+                    if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.contrast = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+        case V4L2_CID_DO_WHITE_BALANCE:
+            {
+                if (ctrl->value != sensor->info_priv.whiteBalance)
+                {
+                    if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.whiteBalance = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Mirror
+        case V4L2_CID_HFLIP:
+            {
+                if (ctrl->value != sensor->info_priv.mirror)
+                {
+                    if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.mirror = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Flip
+        case V4L2_CID_VFLIP:
+            {
+                if (ctrl->value != sensor->info_priv.flip)
+                {
+                    if (sensor_set_flip(icd, qctrl,ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.flip = ctrl->value;
+                }
+                break;
+            }
+#endif
+        default:
+            break;
+    }
+
+    return 0;
+}
+static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl)
+{
+    const struct v4l2_queryctrl *qctrl;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ext_ctrl->id)
+    {
+        case V4L2_CID_SCENE:
+            {
+                ext_ctrl->value = sensor->info_priv.scene;
+                break;
+            }
+        case V4L2_CID_EFFECT:
+            {
+                ext_ctrl->value = sensor->info_priv.effect;
+                break;
+            }
+        case V4L2_CID_ZOOM_ABSOLUTE:
+            {
+                ext_ctrl->value = sensor->info_priv.digitalzoom;
+                break;
+            }
+        case V4L2_CID_ZOOM_RELATIVE:
+            {
+                return -EINVAL;
+            }
+        case V4L2_CID_FOCUS_ABSOLUTE:
+            {
+                ext_ctrl->value = sensor->info_priv.focus;
+                break;
+            }
+        case V4L2_CID_FOCUS_RELATIVE:
+            {
+                return -EINVAL;
+            }
+        case V4L2_CID_FLASH:
+            {
+                ext_ctrl->value = sensor->info_priv.flash;
+                break;
+            }
+        default :
+            break;
+    }
+    return 0;
+}
+static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl)
+{
+    const struct v4l2_queryctrl *qctrl;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+    int val_offset;
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        return -EINVAL;
+    }
+
+       val_offset = 0;
+    switch (ext_ctrl->id)
+    {
+#if CONFIG_SENSOR_Scene
+        case V4L2_CID_SCENE:
+            {
+                if (ext_ctrl->value != sensor->info_priv.scene)
+                {
+                    if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.scene = ext_ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Effect
+        case V4L2_CID_EFFECT:
+            {
+                if (ext_ctrl->value != sensor->info_priv.effect)
+                {
+                    if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.effect= ext_ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+        case V4L2_CID_ZOOM_ABSOLUTE:
+            {
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
+
+                if (ext_ctrl->value != sensor->info_priv.digitalzoom)
+                {
+                    val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom;
+
+                    if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.digitalzoom += val_offset;
+
+                    SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(),  sensor->info_priv.digitalzoom);
+                }
+
+                break;
+            }
+        case V4L2_CID_ZOOM_RELATIVE:
+            {
+                if (ext_ctrl->value)
+                {
+                    if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.digitalzoom += ext_ctrl->value;
+
+                    SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom);
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Focus
+        case V4L2_CID_FOCUS_ABSOLUTE:
+            {
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
+
+                if (ext_ctrl->value != sensor->info_priv.focus)
+                {
+                    val_offset = ext_ctrl->value -sensor->info_priv.focus;
+
+                    sensor->info_priv.focus += val_offset;
+                }
+
+                break;
+            }
+        case V4L2_CID_FOCUS_RELATIVE:
+            {
+                if (ext_ctrl->value)
+                {
+                    sensor->info_priv.focus += ext_ctrl->value;
+
+                    SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus);
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Flash
+        case V4L2_CID_FLASH:
+            {
+                if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)
+                    return -EINVAL;
+                sensor->info_priv.flash = ext_ctrl->value;
+
+                SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);
+                break;
+            }
+#endif
+        default:
+            break;
+    }
+
+    return 0;
+}
+
+static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    int i, error_cnt=0, error_idx=-1;
+
+
+    for (i=0; i<ext_ctrl->count; i++) {
+        if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+            error_cnt++;
+            error_idx = i;
+        }
+    }
+
+    if (error_cnt > 1)
+        error_idx = ext_ctrl->count;
+
+    if (error_idx != -1) {
+        ext_ctrl->error_idx = error_idx;
+        return -EINVAL;
+    } else {
+        return 0;
+    }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    int i, error_cnt=0, error_idx=-1;
+
+
+    for (i=0; i<ext_ctrl->count; i++) {
+        if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+            error_cnt++;
+            error_idx = i;
+        }
+    }
+
+    if (error_cnt > 1)
+        error_idx = ext_ctrl->count;
+
+    if (error_idx != -1) {
+        ext_ctrl->error_idx = error_idx;
+        return -EINVAL;
+    } else {
+        return 0;
+    }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+                              struct i2c_client *client)
+{
+    char value;
+    int ret;
+    struct sensor *sensor = to_sensor(client);
+
+    /* We must have a parent by now. And it cannot be a wrong one.
+     * So this entire test is completely redundant. */
+    if (!icd->dev.parent ||
+           to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+               return -ENODEV;
+
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
+
+    /* soft reset */
+    ret = sensor_write(client, 0x01, 0xf9);
+    if (ret != 0)
+    {
+        SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
+        return -ENODEV;
+    }
+    mdelay(5);          //delay 5 microseconds
+
+    /* check if it is an sensor sensor */
+    ret = sensor_read(client, 0x04, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id high byte failed\n");
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+    if (value == SENSOR_ID) {
+        sensor->model = SENSOR_V4L2_IDENT;
+    } else {
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+               
+    icd->formats = sensor_colour_formats;
+    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
+
+    return 0;
+
+sensor_video_probe_err:
+
+    return ret;
+}
+static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+       struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    int ret = 0;
+#if CONFIG_SENSOR_Flash        
+    int i;
+#endif
+    
+       SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+       switch (cmd)
+       {
+               case RK29_CAM_SUBDEV_DEACTIVATE:
+               {
+                       sensor_deactivate(client);
+                       break;
+               }
+
+               case RK29_CAM_SUBDEV_IOREQUEST:
+               {
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
+            /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
+               for this project */
+            #if CONFIG_SENSOR_Flash    
+               if (sensor->sensor_gpio_res) { 
+                if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {
+                    for (i = 0; i < icd->ops->num_controls; i++) {
+                               if (V4L2_CID_FLASH == icd->ops->controls[i].id) {
+                                       memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                       
+                               }
+                    }
+                    sensor->info_priv.flash = 0xff;
+                    SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());
+                }
+               }
+            #endif
+                       break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_ioctl_end:
+       return ret;
+
+}
+static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
+       .init           = sensor_init,
+       .g_ctrl         = sensor_g_control,
+       .s_ctrl         = sensor_s_control,
+       .g_ext_ctrls          = sensor_g_ext_controls,
+       .s_ext_ctrls          = sensor_s_ext_controls,
+       .g_chip_ident   = sensor_g_chip_ident,
+       .ioctl = sensor_ioctl,
+};
+
+static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {
+       .s_fmt          = sensor_s_fmt,
+       .g_fmt          = sensor_g_fmt,
+       .try_fmt        = sensor_try_fmt,
+};
+
+static struct v4l2_subdev_ops sensor_subdev_ops = {
+       .core   = &sensor_subdev_core_ops,
+       .video = &sensor_subdev_video_ops,
+};
+
+static int sensor_probe(struct i2c_client *client,
+                        const struct i2c_device_id *did)
+{
+    struct sensor *sensor;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+    struct soc_camera_link *icl;
+    int ret;
+
+    SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__);
+    if (!icd) {
+        dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+    icl = to_soc_camera_link(icd);
+    if (!icl) {
+        dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+    if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+        dev_warn(&adapter->dev,
+                "I2C-Adapter doesn't support I2C_FUNC_I2C\n");
+        return -EIO;
+    }
+
+    sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL);
+    if (!sensor)
+        return -ENOMEM;
+
+    v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops);
+
+    /* Second stage probe - when a capture adapter is there */
+    icd->ops           = &sensor_ops;
+    icd->y_skip_top            = 0;
+       #if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_set(&sensor->tasklock_cnt,0);
+       #endif
+
+    ret = sensor_video_probe(icd, client);
+    if (ret < 0) {
+        icd->ops = NULL;
+        i2c_set_clientdata(client, NULL);
+        kfree(sensor);
+               sensor = NULL;
+    }
+    SENSOR_DG("\n%s..%s..%d  ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);
+    return ret;
+}
+
+static int sensor_remove(struct i2c_client *client)
+{
+    struct sensor *sensor = to_sensor(client);
+    struct soc_camera_device *icd = client->dev.platform_data;
+
+    icd->ops = NULL;
+    i2c_set_clientdata(client, NULL);
+    client->driver = NULL;
+    kfree(sensor);
+       sensor = NULL;
+    return 0;
+}
+
+static const struct i2c_device_id sensor_id[] = {
+       {SENSOR_NAME_STRING(), 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, sensor_id);
+
+static struct i2c_driver sensor_i2c_driver = {
+       .driver = {
+               .name = SENSOR_NAME_STRING(),
+       },
+       .probe          = sensor_probe,
+       .remove         = sensor_remove,
+       .id_table       = sensor_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+    SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING());
+    return i2c_add_driver(&sensor_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+    i2c_del_driver(&sensor_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));
+MODULE_AUTHOR("lxh@wisky.com.cn");
+MODULE_LICENSE("GPL");
+
+
+
diff --git a/drivers/media/video/hi704.c b/drivers/media/video/hi704.c
new file mode 100755 (executable)
index 0000000..0a24955
--- /dev/null
@@ -0,0 +1,2957 @@
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <mach/rk29_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do {                       \
+       if (debug >= level)                                     \
+       printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
+
+
+#define _CONS(a,b) a##b
+#define CONS(a,b) _CONS(a,b)
+
+#define __STR(x) #x
+#define _STR(x) __STR(x)
+#define STR(x) _STR(x)
+
+#define MIN(x,y)   ((x<y) ? x: y)
+#define MAX(x,y)    ((x>y) ? x: y)
+
+/* Sensor Driver Configuration */
+#define SENSOR_NAME RK29_CAM_SENSOR_HI704
+#define SENSOR_V4L2_IDENT V4L2_IDENT_HI704
+#define SENSOR_ID 0x96
+#define SENSOR_MIN_WIDTH    176
+#define SENSOR_MIN_HEIGHT   144
+#define SENSOR_MAX_WIDTH    640
+#define SENSOR_MAX_HEIGHT   480
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY
+
+#define CONFIG_SENSOR_WhiteBalance     1
+#define CONFIG_SENSOR_Brightness       0
+#define CONFIG_SENSOR_Contrast      0
+#define CONFIG_SENSOR_Saturation    0
+#define CONFIG_SENSOR_Effect        1
+#define CONFIG_SENSOR_Scene         1
+#define CONFIG_SENSOR_DigitalZoom   0
+#define CONFIG_SENSOR_Focus         0
+#define CONFIG_SENSOR_Exposure      0
+#define CONFIG_SENSOR_Flash         0
+#define CONFIG_SENSOR_Mirror        0
+#define CONFIG_SENSOR_Flip          0
+
+#define CONFIG_SENSOR_I2C_SPEED     100000       /* Hz */
+/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */
+#define CONFIG_SENSOR_I2C_NOSCHED   0
+#define CONFIG_SENSOR_I2C_RDWRCHK   0
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
+#define COLOR_TEMPERATURE_CLOUDY_DN  6500
+#define COLOR_TEMPERATURE_CLOUDY_UP    8000
+#define COLOR_TEMPERATURE_CLEARDAY_DN  5000
+#define COLOR_TEMPERATURE_CLEARDAY_UP    6500
+#define COLOR_TEMPERATURE_OFFICE_DN     3500
+#define COLOR_TEMPERATURE_OFFICE_UP     5000
+#define COLOR_TEMPERATURE_HOME_DN       2500
+#define COLOR_TEMPERATURE_HOME_UP       3500
+
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
+
+//lxh end of reg flag
+#define END_REG 0xff
+
+struct reginfo
+{
+    u8 reg;
+    u8 val;
+};
+
+/* init SVGA preview */
+static struct reginfo sensor_init_data[] =
+{
+           //PAGE 0
+    //Image Size/Windowing/HSYNC/VSYNC[Type1]
+{0x03, 0x00},   //PAGEMODE(0x03)
+{0x01, 0xf1},
+{0x01, 0xf3},   //PWRCTL(0x01[P0])Bit[1]:Software Reset.
+{0x01, 0xf1},
+{0x10, 0x00},//vga mode
+{0x11, 0x91},   //For No Fixed Framerate Bit[2]
+{0x12, 0x04},
+    
+{0x20, 0x00},
+{0x21, 0x04},
+{0x22, 0x00},
+{0x23, 0x04},
+
+{0x24, 0x01},
+{0x25, 0xe0},
+{0x26, 0x02},
+{0x27, 0x80},
+
+{0x40, 0x00},   //HBLANK: 0x70 = 112
+{0x41, 0x70},
+{0x42, 0x00},   //VBLANK: 0x40 = 64
+{0x43, 0x40},   //0x04 -> 0x40: For Max Framerate = 30fps
+        
+//BLC
+{0x80, 0x2e},
+{0x81, 0x7e},
+{0x82, 0x90},
+{0x83, 0x30},
+{0x84, 0x2c},
+{0x85, 0x4b},
+{0x89, 0x48},
+    
+{0x90, 0x0b},
+{0x91, 0x0b},    
+{0x92, 0x48},
+{0x93, 0x48},
+{0x98, 0x38},
+{0x99, 0x40},
+{0xa0, 0x00},
+{0xa8, 0x40},
+
+//PAGE 2
+//Analog Circuit
+{0x03, 0x02},      
+{0x13, 0x40},
+{0x14, 0x04},
+{0x1a, 0x00},
+{0x1b, 0x08},
+    
+{0x20, 0x33},
+{0x21, 0xaa},
+{0x22, 0xa7},
+{0x23, 0xb1},       //For Sun Pot
+    
+{0x3b, 0x48},
+    
+{0x50, 0x21},
+{0x52, 0xa2},
+{0x53, 0x0a},
+{0x54, 0x30},
+{0x55, 0x10},
+{0x56, 0x0c},
+{0x59, 0x0F},
+    
+{0x60, 0x54},
+{0x61, 0x5d},
+{0x62, 0x56},
+{0x63, 0x5c},
+{0x64, 0x56},
+{0x65, 0x5c},
+{0x72, 0x57},
+{0x73, 0x5b},
+{0x74, 0x57},
+{0x75, 0x5b},
+{0x80, 0x02},
+{0x81, 0x46},
+{0x82, 0x07},
+{0x83, 0x10},
+{0x84, 0x07},
+{0x85, 0x10},
+{0x92, 0x24},
+{0x93, 0x30},
+{0x94, 0x24},
+{0x95, 0x30},
+{0xa0, 0x03},
+{0xa1, 0x45},
+{0xa4, 0x45},
+{0xa5, 0x03},
+{0xa8, 0x12},
+{0xa9, 0x20},
+{0xaa, 0x34},
+{0xab, 0x40},
+{0xb8, 0x55},
+{0xb9, 0x59},
+{0xbc, 0x05},
+{0xbd, 0x09},
+{0xc0, 0x5f},
+{0xc1, 0x67},
+{0xc2, 0x5f},
+{0xc3, 0x67},
+{0xc4, 0x60},
+{0xc5, 0x66},
+{0xc6, 0x60},
+{0xc7, 0x66},
+{0xc8, 0x61},
+{0xc9, 0x65},
+{0xca, 0x61},
+{0xcb, 0x65},
+{0xcc, 0x62},
+{0xcd, 0x64},
+{0xce, 0x62},
+{0xcf, 0x64},
+{0xd0, 0x53},
+{0xd1, 0x68},
+     
+    //PAGE 10
+    //Image Format, Image Effect
+{0x03, 0x10},
+{0x10, 0x01},//lxh
+{0x11, 0x43},
+{0x12, 0x30},
+    
+{0x40, 0x10},//brightness +1
+{0x41, 0x02},
+{0x48, 0x98},//contrast level +1
+    
+{0x50, 0x48},
+       
+{0x60, 0x7f},
+{0x61, 0x00}, //Use default
+{0x62, 0xa0}, //SATB  (1.4x)
+{0x63, 0xa0}, //SATR  (1.2x)
+{0x64, 0x48}, //AGSAT
+{0x66, 0x90}, //wht_th2
+{0x67, 0x36}, //wht_gain  Dark (0.4x), Normal (0.75x)
+
+//LPF
+{0x03, 0x11},
+{0x10, 0x25},   
+{0x11, 0x1f},   
+    
+{0x20, 0x00},   
+{0x21, 0x38},   
+{0x23, 0x0a},
+    
+{0x60, 0x10},   
+{0x61, 0x82},
+{0x62, 0x00},   
+{0x63, 0x83},   
+{0x64, 0x83},      
+{0x67, 0xF0},   
+{0x68, 0x20},//30   
+{0x69, 0x10},   
+    
+    //PAGE 12
+    //2D
+{0x03, 0x12},
+    
+{0x40, 0xe9},
+{0x41, 0x09},
+    
+{0x50, 0x18},
+{0x51, 0x24},
+    
+{0x70, 0x1f},
+{0x71, 0x00},
+{0x72, 0x00},
+{0x73, 0x00},
+{0x74, 0x10},
+{0x75, 0x10},
+{0x76, 0x20},
+{0x77, 0x80},
+{0x78, 0x88},
+{0x79, 0x18},
+    
+{0xb0, 0x7d},
+
+//Edge
+{0x03, 0x13},
+{0x10, 0x01},  
+{0x11, 0x89},  
+{0x12, 0x14},  
+{0x13, 0x19},  
+{0x14, 0x08},  //Test Setting
+{0x20, 0x06},  //SHARP_Negative
+{0x21, 0x03},  //SHARP_Positive
+{0x23, 0x30},  //SHARP_DY_CTL
+{0x24, 0x33},  //40->33
+{0x25, 0x08},  //SHARP_PGA_TH
+{0x26, 0x18},  //Test Setting
+{0x27, 0x00},  //Test Setting
+{0x28, 0x08},  //Test Setting
+{0x29, 0x50},  //AG_TH
+{0x2a, 0xe0},  //region ratio
+{0x2b, 0x10},  //Test Setting
+{0x2c, 0x28},  //Test Setting
+{0x2d, 0x40},  //Test Setting
+{0x2e, 0x00},  //Test Setting
+{0x2f, 0x00},  //Test Setting
+{0x30, 0x11},  //Test Setting
+{0x80, 0x03},  //SHARP2D_CTL
+{0x81, 0x07},  //Test Setting
+{0x90, 0x04},  //SHARP2D_SLOPE
+{0x91, 0x02},  //SHARP2D_DIFF_CTL
+{0x92, 0x00},  //SHARP2D_HI_CLIP
+{0x93, 0x20},  //SHARP2D_DY_CTL
+{0x94, 0x42},  //Test Setting
+{0x95, 0x60},  //Test Setting
+
+//Shading
+{0x03, 0x14},
+{0x10, 0x01},
+{0x20, 0x60}, //XCEN
+{0x21, 0x60}, //YCEN 80
+{0x22, 0x66}, //76, 34, 2b
+{0x23, 0x50}, //4b, 15, 0d
+{0x24, 0x44}, //3b, 10, 0b
+
+//Page 15 CMC
+{0x03, 0x15}, 
+{0x10, 0x03},
+       
+{0x14, 0x3c},
+{0x16, 0x2c},
+{0x17, 0x2f},
+
+{0x30, 0xcb},
+{0x31, 0x61},
+{0x32, 0x16},
+{0x33, 0x23},
+{0x34, 0xce},
+{0x35, 0x2b},
+{0x36, 0x01},
+{0x37, 0x34},
+{0x38, 0x75},
+       
+{0x40, 0x87},
+{0x41, 0x18},
+{0x42, 0x91},
+{0x43, 0x94},
+{0x44, 0x9f},
+{0x45, 0x33},
+{0x46, 0x00},
+{0x47, 0x94},
+{0x48, 0x14},
+
+//Gamma
+//normal
+{0x03,0x16},
+{0x30,0x00},
+{0x31,0x0a},
+{0x32,0x1b},
+{0x33,0x2e},
+{0x34,0x5c},
+{0x35,0x79},
+{0x36,0x95},
+{0x37,0xa4},
+{0x38,0xb1},
+{0x39,0xbd},
+{0x3a,0xc8},
+{0x3b,0xd9},
+{0x3c,0xe8},
+{0x3d,0xf5},
+{0x3e,0xff},
+ //0930
+//{0x03,0x16},
+//{0x30,0x00},
+//{0x31,0x08},
+//{0x32,0x0e},
+//{0x33,0x1b},
+//{0x34,0x33},
+//{0x35,0x4d},
+//{0x36,0x66},
+//{0x37,0x7e},
+//{0x38,0x95},
+//{0x39,0xa9},
+//{0x3a,0xbb},
+//{0x3b,0xd7},
+//{0x3c,0xeb},
+//{0x3d,0xf7},
+//{0x3e,0xff},
+
+//night mode
+//{0x03,0x16},
+//{0x30,0x00},
+//{0x31,0x1c},
+//{0x32,0x2d},
+//{0x33,0x4e},
+//{0x34,0x6d},
+//{0x35,0x8b},
+//{0x36,0xa2},
+//{0x37,0xb5},
+//{0x38,0xc4},
+//{0x39,0xd0},
+//{0x3a,0xda},
+//{0x3b,0xea},
+//{0x3c,0xf4},
+//{0x3d,0xfb},
+//{0x3e,0xff},
+
+//Page 17 AE 
+{0x03, 0x17},
+{0xc4, 0x3c},
+{0xc5, 0x32},
+
+//Page 20 AE 
+{0x03, 0x20},
+{0x10, 0x0c},
+{0x11, 0x04},
+       
+{0x20, 0x01},
+{0x28, 0x27},
+{0x29, 0xa1},
+
+{0x2a, 0xf0},
+{0x2b, 0x34},
+{0x2c, 0x2b}, //23->2b 2010_04_06 hhzin
+       
+{0x30, 0xf8},
+
+{0x39, 0x22},
+{0x3a, 0xde},
+{0x3b, 0x22}, //23->22 _10_04_06 hhzin
+{0x3c, 0xde},
+
+{0x60, 0x95}, //d5, 99
+{0x68, 0x3c},
+{0x69, 0x64},
+{0x6A, 0x28},
+{0x6B, 0xc8},
+
+{0x70, 0x42},//Y Target 42
+
+{0x76, 0x22}, //Unlock bnd1
+{0x77, 0x02}, //Unlock bnd2 02->a2 _10_04_06 hhzin
+
+{0x78, 0x12}, //Yth 1
+{0x79, 0x27}, //Yth 2 26->27 _10_04_06 hhzin
+{0x7a, 0x23}, //Yth 3
+
+{0x7c, 0x1d}, //1c->1d _10_04_06 hhzin
+{0x7d, 0x22},
+
+//50Hz
+{0x83, 0x00},//ExpTime 30fps
+{0x84, 0xaf},
+{0x85, 0xc8},
+
+//60Hz
+//{0x83, 0x00},//ExpTime 30fps
+//{0x84, 0xc3},
+//{0x85, 0x50},
+
+{0x86, 0x00},//ExpMin
+{0x87, 0xfa},
+
+//50Hz_8fps
+{0x88, 0x02},//ExpMax 8fps(8fps)
+{0x89, 0xbf},
+{0x8a, 0x20},
+
+//50Hz_5fps
+//{0x88, 0x04},//ExpMax 8fps(8fps)
+//{0x89, 0x93},
+//{0x8a, 0xe0},
+
+//60Hz_8fps
+//{0x88, 0x02},//ExpMax 8fps(8fps)
+//{0x89, 0xdc},
+//{0x8a, 0x6c},
+
+{0x8b, 0x3a},//Exp100
+{0x8c, 0x98},
+
+{0x8d, 0x30},//Exp120
+{0x8e, 0xd4},
+
+{0x91, 0x02},
+{0x92, 0xdc},
+{0x93, 0x6c},
+
+{0x94, 0x01}, //fix_step
+{0x95, 0xb7},
+{0x96, 0x74},
+
+{0x98, 0x8C},
+{0x99, 0x23},
+
+{0x9c, 0x0b}, //4shared limit_10_04_06 hhzin
+{0x9d, 0x3b}, // 0x06d3 --> 0x0b3b
+{0x9e, 0x00}, //4shared Unit_10_04_06 hhzin
+{0x9f, 0xfa}, // 0x01f4 --> 0xfa
+
+{0xb1, 0x14},
+{0xb2, 0x50},
+{0xb4, 0x14},
+{0xb5, 0x38},
+{0xb6, 0x26},
+{0xb7, 0x20},
+{0xb8, 0x1d},
+{0xb9, 0x1b},
+{0xba, 0x1a},
+{0xbb, 0x19},
+{0xbc, 0x19},
+{0xbd, 0x18},
+
+{0xc0, 0x1a},
+{0xc3, 0x48},
+{0xc4, 0x48},
+
+
+//Page 22 AWB
+{0x03, 0x22},
+{0x10, 0xe2},
+{0x11, 0x26},
+{0x21, 0x40},
+       
+{0x30, 0x80},
+{0x31, 0x80},
+{0x38, 0x12},
+{0x39, 0x33},
+{0x40, 0xf0},
+{0x41, 0x33},
+{0x42, 0x33},
+{0x43, 0xf3},
+{0x44, 0x55},
+{0x45, 0x44},
+{0x46, 0x02},
+       
+{0x80, 0x45},
+{0x81, 0x20},
+{0x82, 0x48},
+{0x83, 0x52}, //RMAX Default : 50 -> 48 -> 52 
+{0x84, 0x1b}, //RMIN Default : 20
+{0x85, 0x50}, //BMAX Default : 50, 5a -> 58 -> 55
+{0x86, 0x25}, //BMIN Default : 20
+{0x87, 0x4d}, //RMAXB Default : 50, 4d
+{0x88, 0x38}, //RMINB Default : 3e, 45 --> 42
+{0x89, 0x3e}, //BMAXB Default : 2e, 2d --> 30
+{0x8a, 0x29}, //BMINB Default : 20, 22 --> 26 --> 29
+{0x8b, 0x02}, //OUT TH
+{0x8d, 0x22},
+{0x8e, 0x71},
+
+{0x8f, 0x63},
+{0x90, 0x60},
+{0x91, 0x5c},
+{0x92, 0x56},
+{0x93, 0x52},
+{0x94, 0x4c},
+{0x95, 0x36},
+{0x96, 0x31},
+{0x97, 0x2e},
+{0x98, 0x2a},
+{0x99, 0x29},
+{0x9a, 0x26},
+{0x9b, 0x09},
+       
+{0x03, 0x22},
+{0x10, 0xfb},
+
+//PAGE 20
+{0x03, 0x20},
+{0x10, 0x9c},
+
+{0x01, 0xf0},
+
+//PAGE 0
+{0x03, 0x00},
+{0x01, 0x90},   //0xf1 ->0x41 : For Preview Green/Red Line.
+{0xff, 0xff}    //End of Initial Setting
+};
+
+
+/* 640X480 VGA */
+static struct reginfo sensor_vga[] =
+{
+{0x03, 0x00},
+{0x10, 0x00},        //VGA Size
+
+{0x20, 0x00},
+{0x21, 0x04},
+
+{0x40, 0x00},        //HBLANK: 0x70 = 112
+{0x41, 0x70},
+{0x42, 0x00},        //VBLANK: 0x04 = 4
+{0x43, 0x40},
+
+{0x03, 0x11},
+{0x10, 0x25},  
+
+{0x03, 0x20},
+{0x83, 0x00},
+{0x84, 0xaf},
+{0x85, 0x80},
+{0x86, 0x00},
+{0x87, 0xc0},
+
+{0x8b, 0x3a},
+{0x8c, 0x80},
+{0x8d, 0x30},
+{0x8e, 0xc0},
+
+{0x9c, 0x08},
+{0x9d, 0xa0},
+{0x9e, 0x00},
+{0x9f, 0xc0},
+{END_REG, END_REG},
+};
+
+/* 352X288 CIF */
+static struct reginfo sensor_cif[] =
+{
+       {END_REG, END_REG},
+};
+
+/* 320*240 QVGA */
+static  struct reginfo sensor_qvga[] =
+{
+{0x03, 0x00},
+{0x10, 0x01},        //QVGA Size: 0x10 -> 0x01
+
+{0x20, 0x00},
+{0x21, 0x02},
+
+{0x40, 0x01},        //HBLANK:  0x0158 = 344
+{0x41, 0x58},
+{0x42, 0x00},        //VBLANK:  0x14 = 20
+{0x43, 0x14},
+
+{0x03, 0x11},        //QVGA Fixframerate
+{0x10, 0x21},  
+
+{0x03, 0x20},
+
+{0x83, 0x00},
+{0x84, 0xaf},
+{0x85, 0xc8},
+{0x86, 0x00},
+{0x87, 0xfa},
+
+{0x8b, 0x3a},
+{0x8c, 0x98},
+{0x8d, 0x30},
+{0x8e, 0xd4},
+
+{0x9c, 0x0b},
+{0x9d, 0x3b},
+{0x9e, 0x00},
+{0x9f, 0xfa},
+{END_REG, END_REG},
+};
+
+/* 176X144 QCIF*/
+static struct reginfo sensor_qcif[] =
+{
+       {END_REG, END_REG},
+};
+
+
+static  struct reginfo sensor_ClrFmt_YUYV[]=
+{
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_ClrFmt_UYVY[]=
+{
+
+    {END_REG, END_REG},
+};
+
+#if CONFIG_SENSOR_WhiteBalance
+static  struct reginfo sensor_WhiteB_Auto[]=
+{
+       {0x03, 0x22},
+       {0x10, 0x6a},
+       {0x80, 0x48},
+       {0x81, 0x20},
+       {0x82, 0x40},
+       {0x83, 0x58},
+       {0x84, 0x10},
+       {0x85, 0x70},   
+       {0x86, 0x10},
+       {0x10, 0xea},   
+       {END_REG, END_REG},
+};
+/* Cloudy Colour Temperature : 6500K - 8000K  */
+static  struct reginfo sensor_WhiteB_Cloudy[]=
+{
+       {0x03, 0x22},
+       {0x10, 0x6a},
+       {0x80, 0x62},
+       {0x81, 0x20},
+       {0x82, 0x2e},
+       {0x83, 0x6d},
+       {0x84, 0x65},
+       {0x85, 0x30},   
+       {0x86, 0x25},   
+       {END_REG, END_REG},
+};
+/* ClearDay Colour Temperature : 5000K - 6500K  */
+static  struct reginfo sensor_WhiteB_ClearDay[]=
+{
+    //Sunny
+       {0x03, 0x22},
+       {0x10, 0x6a},
+       {0x80, 0x50},
+       {0x81, 0x20},
+       {0x82, 0x2d},
+       {0x83, 0x52},
+       {0x84, 0x40},
+       {0x85, 0x30},   
+       {0x86, 0x1c},   
+       {END_REG, END_REG},
+};
+/* Office Colour Temperature : 3500K - 5000K  */
+static  struct reginfo sensor_WhiteB_TungstenLamp1[]=
+{
+    //Office£¬Ó«¹âµÆ
+       {0x03, 0x22},
+       {0x10, 0x6a},
+       {0x80, 0x40},
+       {0x81, 0x20},
+       {0x82, 0x4f},
+       {0x83, 0x44},
+       {0x84, 0x3a},
+       {0x85, 0x47},   
+       {0x86, 0x3a},    
+       {END_REG, END_REG},
+
+};
+/* Home Colour Temperature : 2500K - 3500K  */
+static  struct reginfo sensor_WhiteB_TungstenLamp2[]=
+{
+    //Home,°×³ãµÆ
+       {0x03, 0x22},
+       {0x10, 0x6a},
+       {0x80, 0x26},
+       {0x81, 0x20},
+       {0x82, 0x55},
+       {0x83, 0x24},
+       {0x84, 0x1e},
+       {0x85, 0x58},   
+       {0x86, 0x4a},   
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,
+    sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,
+};
+#endif
+
+#if CONFIG_SENSOR_Brightness
+static  struct reginfo sensor_Brightness0[]=
+{
+    // Brightness -2
+    {0x03, 0x10},
+    {0x40, 0xa0},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Brightness1[]=
+{
+    // Brightness -1
+       {0x03, 0x10},
+    {0x40, 0x90},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Brightness2[]=
+{
+    //  Brightness 0
+    {0x03, 0x10},
+    {0x40, 0x00},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Brightness3[]=
+{
+    // Brightness +1
+    {0x03, 0x10},
+    {0x40, 0x10},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Brightness4[]=
+{
+    //  Brightness +2
+    {0x03, 0x10},
+    {0x40, 0x20},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Brightness5[]=
+{
+    //  Brightness +3
+    {0x03, 0x10},
+    {0x40, 0x30},   
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,
+    sensor_Brightness4, sensor_Brightness5,NULL,
+};
+
+#endif
+
+#if CONFIG_SENSOR_Effect
+static  struct reginfo sensor_Effect_Normal[] =
+{
+    {0x03, 0x10},
+    {0x11, 0x03},      
+    {0x12, 0x30},
+    {0x13, 0x00},
+    {0x44, 0x80},
+    {0x45, 0x80}, 
+    {0x47, 0x7f}, 
+    {0x03, 0x13},    
+    {0x20, 0x06},  
+    {0x21, 0x04},      
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Effect_WandB[] =
+{
+    {0x03, 0x10},
+    {0x11, 0x03},      
+    {0x12, 0x30},
+    {0x13, 0x00},
+    {0x44, 0x80},
+    {0x45, 0x80}, 
+    {0x47, 0x7f}, 
+    {0x03, 0x13},    
+    {0x20, 0x06},  
+    {0x21, 0x04},  
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Effect_Sepia[] =
+{
+    {0x03, 0x10},
+    {0x11, 0x03},      
+    {0x12, 0x23},
+    {0x13, 0x00},
+    {0x44, 0x70},
+    {0x45, 0x98}, 
+    {0x47, 0x7f}, 
+    {0x03, 0x13},    
+    {0x20, 0x07},  
+    {0x21, 0x03},  
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Effect_Negative[] =
+{
+    //Negative
+    {0x03, 0x10},
+    {0x11, 0x03},      
+    {0x12, 0x28},
+    {0x13, 0x00},
+    {0x44, 0x80},
+    {0x45, 0x80}, 
+    {0x47, 0x7f}, 
+    {0x03, 0x13},    
+    {0x20, 0x07},  
+    {0x21, 0x03},  
+       {END_REG, END_REG},
+};
+static  struct reginfo sensor_Effect_Bluish[] =
+{
+    // Bluish
+    {0x03, 0x10},
+    {0x11, 0x03},      
+    {0x12, 0x33},
+    {0x13, 0x00},
+    {0x44, 0xb0},
+    {0x45, 0x40}, 
+    {0x47, 0x7f}, 
+    {0x03, 0x13},    
+    {0x20, 0x07},  
+    {0x21, 0x03},  
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Effect_Green[] =
+{
+    //  Greenish
+    {0x03, 0x10},
+    {0x11, 0x03},      
+    {0x12, 0x33},
+    {0x13, 0x00},
+    {0x44, 0x60},
+    {0x45, 0x60}, 
+    {0x47, 0x7f}, 
+    {0x03, 0x13},    
+    {0x20, 0x07},  
+    {0x21, 0x03},      
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,
+    sensor_Effect_Bluish, sensor_Effect_Green,NULL,
+};
+#endif
+#if CONFIG_SENSOR_Exposure
+static  struct reginfo sensor_Exposure0[]=
+{
+    //-3
+
+};
+
+static  struct reginfo sensor_Exposure1[]=
+{
+    //-2
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Exposure2[]=
+{
+    //-0.3EV
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Exposure3[]=
+{
+    //default
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Exposure4[]=
+{
+    // 1
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Exposure5[]=
+{
+    // 2
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Exposure6[]=
+{
+    // 3
+
+       {END_REG, END_REG},
+};
+
+static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,
+    sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,
+};
+#endif
+#if CONFIG_SENSOR_Saturation
+static  struct reginfo sensor_Saturation0[]=
+{
+       //-3 level
+       {0x03, 0x10},
+       {0x62, 0x60},
+       {0x63, 0x60},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Saturation1[]=
+{
+               //00 level
+       {0x03, 0x10},
+       {0x62, 0x90},
+       {0x63, 0x90},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Saturation2[]=
+{
+       //+3 level
+       {0x03, 0x10},
+       {0x62, 0xc0},
+       {0x63, 0xc0},
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};
+
+#endif
+#if CONFIG_SENSOR_Contrast
+static  struct reginfo sensor_Contrast0[]=
+{
+    //Contrast -3
+    {0x03, 0x10},
+    {0x48, 0x54},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Contrast1[]=
+{
+    //Contrast -2
+    {0x03, 0x10},
+    {0x48, 0x64},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Contrast2[]=
+{
+    // Contrast -1
+    {0x03, 0x10},
+    {0x48, 0x74},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Contrast3[]=
+{
+    //Contrast 0
+    {0x03, 0x10},
+    {0x48, 0x84},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Contrast4[]=
+{
+    //Contrast +1
+    {0x03, 0x10},
+    {0x48, 0x94},
+       {END_REG, END_REG},
+};
+
+
+static  struct reginfo sensor_Contrast5[]=
+{
+    //Contrast +2
+    {0x03, 0x10},
+    {0x48, 0xa4},
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_Contrast6[]=
+{
+    //Contrast +3
+    {0x03, 0x10},
+    {0x48, 0xb4},
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,
+    sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,
+};
+
+#endif
+#if CONFIG_SENSOR_Mirror
+static  struct reginfo sensor_MirrorOn[]=
+{
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_MirrorOff[]=
+{
+
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,};
+#endif
+#if CONFIG_SENSOR_Flip
+static  struct reginfo sensor_FlipOn[]=
+{
+
+       {END_REG, END_REG},
+};
+
+static  struct reginfo sensor_FlipOff[]=
+{
+
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,};
+
+#endif
+#if CONFIG_SENSOR_Scene
+static  struct reginfo sensor_SceneAuto[] =
+{
+
+};
+
+static  struct reginfo sensor_SceneNight[] =
+{
+
+};
+static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};
+
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+static struct reginfo sensor_Zoom0[] =
+{
+       {END_REG, END_REG},
+};
+
+static struct reginfo sensor_Zoom1[] =
+{
+       {END_REG, END_REG},
+};
+
+static struct reginfo sensor_Zoom2[] =
+{
+       {END_REG, END_REG},
+};
+
+
+static struct reginfo sensor_Zoom3[] =
+{
+       {END_REG, END_REG},
+};
+static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};
+#endif
+static const struct v4l2_querymenu sensor_menus[] =
+{
+       #if CONFIG_SENSOR_WhiteBalance
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 0,  .name = "auto",  .reserved = 0, }, {  .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 1, .name = "incandescent",  .reserved = 0,},
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 2,  .name = "fluorescent", .reserved = 0,}, {  .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3,  .name = "daylight", .reserved = 0,},
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 4,  .name = "cloudy-daylight", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Effect
+    { .id = V4L2_CID_EFFECT,  .index = 0,  .name = "none",  .reserved = 0, }, {  .id = V4L2_CID_EFFECT,  .index = 1, .name = "mono",  .reserved = 0,},
+    { .id = V4L2_CID_EFFECT,  .index = 2,  .name = "negative", .reserved = 0,}, {  .id = V4L2_CID_EFFECT, .index = 3,  .name = "sepia", .reserved = 0,},
+    { .id = V4L2_CID_EFFECT,  .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT,  .index = 5,  .name = "aqua", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Scene
+    { .id = V4L2_CID_SCENE,  .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE,  .index = 1,  .name = "night", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Flash
+    { .id = V4L2_CID_FLASH,  .index = 0,  .name = "off",  .reserved = 0, }, {  .id = V4L2_CID_FLASH,  .index = 1, .name = "auto",  .reserved = 0,},
+    { .id = V4L2_CID_FLASH,  .index = 2,  .name = "on", .reserved = 0,}, {  .id = V4L2_CID_FLASH, .index = 3,  .name = "torch", .reserved = 0,},
+    #endif
+};
+
+static const struct v4l2_queryctrl sensor_controls[] =
+{
+       #if CONFIG_SENSOR_WhiteBalance
+    {
+        .id            = V4L2_CID_DO_WHITE_BALANCE,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "White Balance Control",
+        .minimum       = 0,
+        .maximum       = 4,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Brightness
+       {
+        .id            = V4L2_CID_BRIGHTNESS,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Brightness Control",
+        .minimum       = -3,
+        .maximum       = 2,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Effect
+       {
+        .id            = V4L2_CID_EFFECT,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Effect Control",
+        .minimum       = 0,
+        .maximum       = 5,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Exposure
+       {
+        .id            = V4L2_CID_EXPOSURE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Exposure Control",
+        .minimum       = 0,
+        .maximum       = 6,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Saturation
+       {
+        .id            = V4L2_CID_SATURATION,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Saturation Control",
+        .minimum       = 0,
+        .maximum       = 2,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Contrast
+       {
+        .id            = V4L2_CID_CONTRAST,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Contrast Control",
+        .minimum       = -3,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Mirror
+       {
+        .id            = V4L2_CID_HFLIP,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Mirror Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 1,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Flip
+       {
+        .id            = V4L2_CID_VFLIP,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Flip Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 1,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Scene
+    {
+        .id            = V4L2_CID_SCENE,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Scene Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_DigitalZoom
+    {
+        .id            = V4L2_CID_ZOOM_RELATIVE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "DigitalZoom Control",
+        .minimum       = -1,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }, {
+        .id            = V4L2_CID_ZOOM_ABSOLUTE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "DigitalZoom Control",
+        .minimum       = 0,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Focus
+       {
+        .id            = V4L2_CID_FOCUS_RELATIVE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Focus Control",
+        .minimum       = -1,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }, {
+        .id            = V4L2_CID_FOCUS_ABSOLUTE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Focus Control",
+        .minimum       = 0,
+        .maximum       = 255,
+        .step          = 1,
+        .default_value = 125,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Flash
+       {
+        .id            = V4L2_CID_FLASH,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Flash Control",
+        .minimum       = 0,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+};
+
+static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did);
+static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client);
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+static int sensor_g_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);
+static int sensor_s_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);
+static int sensor_resume(struct soc_camera_device *icd);
+static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);
+#if CONFIG_SENSOR_Effect
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+#endif
+static int sensor_deactivate(struct i2c_client *client);
+
+static struct soc_camera_ops sensor_ops =
+{
+    .suspend                     = sensor_suspend,
+    .resume                       = sensor_resume,
+    .set_bus_param             = sensor_set_bus_param,
+    .query_bus_param   = sensor_query_bus_param,
+    .controls          = sensor_controls,
+    .menus                         = sensor_menus,
+    .num_controls              = ARRAY_SIZE(sensor_controls),
+    .num_menus         = ARRAY_SIZE(sensor_menus),
+};
+
+#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
+       { .name = _name, .depth = _depth, .fourcc = _fourcc, \
+       .colorspace = _colorspace }
+
+#define JPG_FMT(_name, _depth, _fourcc) \
+       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+
+static const struct soc_camera_data_format sensor_colour_formats[] = {
+       JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY),
+       JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),
+};
+
+typedef struct sensor_info_priv_s
+{
+    int whiteBalance;
+    int brightness;
+    int contrast;
+    int saturation;
+    int effect;
+    int scene;
+    int digitalzoom;
+    int focus;
+    int flash;
+    int exposure;
+       bool snap2preview;
+       bool video2preview;
+    unsigned char mirror;                                        /* HFLIP */
+    unsigned char flip;                                          /* VFLIP */
+    unsigned int winseqe_cur_addr;
+       unsigned int pixfmt;
+
+} sensor_info_priv_t;
+
+struct sensor
+{
+    struct v4l2_subdev subdev;
+    struct i2c_client *client;
+    sensor_info_priv_t info_priv;
+    int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */
+#if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_t tasklock_cnt;
+#endif
+       struct rk29camera_platform_data *sensor_io_request;
+    struct rk29camera_gpio_res *sensor_gpio_res;
+};
+
+static struct sensor* to_sensor(const struct i2c_client *client)
+{
+    return container_of(i2c_get_clientdata(client), struct sensor, subdev);
+}
+
+static int sensor_task_lock(struct i2c_client *client, int lock)
+{
+#if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
+    struct sensor *sensor = to_sensor(client);
+
+       if (lock) {
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
+                       preempt_disable();
+               }
+
+               atomic_add(1, &sensor->tasklock_cnt);
+       } else {
+               if (atomic_read(&sensor->tasklock_cnt) > 0) {
+                       atomic_sub(1, &sensor->tasklock_cnt);
+
+                       if (atomic_read(&sensor->tasklock_cnt) == 0)
+                               preempt_enable();
+               }
+       }
+#endif
+       return 0;
+sensor_task_lock_err:
+       return -1;
+}
+
+#if 0
+/* sensor register */
+static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+       int ret = 0;
+
+       ret = i2c_master_reg8_recv(client, reg, val, 1,  CONFIG_SENSOR_I2C_SPEED);
+
+       return (ret > 0)? 0 : ret;
+}
+
+static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
+{
+       int ret = 0;
+       
+       ret = i2c_master_reg8_send(client, reg, &val, 1, CONFIG_SENSOR_I2C_SPEED);
+
+       return (ret > 0)? 0 : ret;
+}
+#else
+static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
+{
+    int err,cnt;
+    u8 buf[2];
+    struct i2c_msg msg[1];
+
+    buf[0] = reg;
+    buf[1] = val;
+       
+    msg->addr = client->addr;
+    msg->flags = client->flags;
+    msg->buf = buf;
+    msg->len = sizeof(buf);
+    msg->scl_rate = CONFIG_SENSOR_I2C_SPEED;         /* ddl@rock-chips.com : 100kHz */
+    msg->read_type = 0;               /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */
+
+    cnt = 3;
+    err = -EAGAIN;
+
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+        err = i2c_transfer(client->adapter, msg, 1);
+
+        if (err >= 0) {
+            return 0;
+        } else {
+               SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);
+            udelay(10);
+        }
+    }
+
+    return err;
+}
+
+/* sensor register read */
+static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
+{
+    int err,cnt;
+    u8 buf[1];
+    struct i2c_msg msg[2];
+
+    buf[0] = reg ;
+
+    msg[0].addr = client->addr;
+    msg[0].flags = client->flags;
+    msg[0].buf = buf;
+    msg[0].len = sizeof(buf);
+    msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED;       /* ddl@rock-chips.com : 100kHz */
+    msg[0].read_type = 2;   /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */
+
+    msg[1].addr = client->addr;
+    msg[1].flags = client->flags|I2C_M_RD;
+    msg[1].buf = buf;
+    msg[1].len = 1;
+    msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED;                       /* ddl@rock-chips.com : 100kHz */
+    msg[1].read_type = 2;                             /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */
+
+    cnt = 3;
+    err = -EAGAIN;
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+        err = i2c_transfer(client->adapter, msg, 2);
+
+        if (err >= 0) {
+            *val = buf[0];
+            return 0;
+        } else {
+               SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val);
+            udelay(10);
+        }
+    }
+
+    return err;
+}
+
+#endif
+
+/* write a array of registers  */
+static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int err = 0, cnt;
+    int i = 0;
+#if CONFIG_SENSOR_I2C_RDWRCHK    
+       char valchk;
+#endif
+
+       cnt = 0;
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
+    while (regarray[i].reg != END_REG)
+    {
+        err = sensor_write(client, regarray[i].reg, regarray[i].val);
+        if (err < 0)
+        {
+            if (cnt-- > 0) {
+                           SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg);
+                               i = 0;
+                               continue;
+            } else {
+                SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING());
+                err = -EPERM;
+                               goto sensor_write_array_end;
+            }
+        } else {
+        #if CONFIG_SENSOR_I2C_RDWRCHK
+                       //mdelay(5);
+                       sensor_read(client, regarray[i].reg, &valchk);
+                       if (valchk != regarray[i].val)
+                               SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+               #endif
+        }
+        i++;
+    }
+
+sensor_write_array_end:
+       sensor_task_lock(client,0);
+       return err;
+}
+static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int cnt;
+    int i = 0;
+       char valchk;
+
+       cnt = 0;
+       valchk = 0;
+    while (regarray[i].reg != 0)
+    {
+               sensor_read(client, regarray[i].reg, &valchk);
+               if (valchk != regarray[i].val)
+                       SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+
+        i++;
+    }
+    return 0;
+}
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
+{
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       int ret = 0;
+
+    SENSOR_DG("%s %s  cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
+       switch (cmd)
+       {
+               case Sensor_PowerDown:
+               {
+                       if (icl->powerdown) {
+                               ret = icl->powerdown(icd->pdev, on);
+                               if (ret == RK29_CAM_IO_SUCCESS) {
+                                       if (on == 0) {
+                                               mdelay(2);
+                                               if (icl->reset)
+                                                       icl->reset(icd->pdev);
+                                       }
+                               } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {
+                                       ret = -ENODEV;
+                                       goto sensor_power_end;
+                               }
+                       }
+                       break;
+               }
+               case Sensor_Flash:
+               {
+                       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+               struct sensor *sensor = to_sensor(client);
+
+                       if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
+                               sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
+                       }
+            break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_power_end:
+       return ret;
+}
+static int sensor_init(struct v4l2_subdev *sd, u32 val)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl;
+    char value;
+    int ret;
+
+    SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
+
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_INIT_ERR;
+       }
+
+    /* soft reset */
+       if (sensor_task_lock(client,1)<0)
+               goto sensor_INIT_ERR;
+#if 1  
+    ret = sensor_write(client, 0x01, 0xF3);
+    if (ret != 0)
+    {
+        SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING());
+        ret = -ENODEV;
+               goto sensor_INIT_ERR;
+    }
+
+    mdelay(5);  //delay 5 microseconds
+       /* check if it is an sensor sensor */
+    ret = sensor_read(client, 0x04, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id high byte failed\n");
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+
+   
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+    if (value == SENSOR_ID) {
+        sensor->model = SENSOR_V4L2_IDENT;
+    } else {
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+#endif
+    ret = sensor_write_array(client, sensor_init_data);
+    if (ret != 0)
+    {
+        SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
+        goto sensor_INIT_ERR;
+    }
+       sensor_task_lock(client,0);
+    //icd->user_width = SENSOR_INIT_WIDTH;
+    //icd->user_height = SENSOR_INIT_HEIGHT;
+    sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;
+       sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT;
+
+    /* sensor sensor information for initialization  */
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+       if (qctrl)
+       sensor->info_priv.whiteBalance = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS);
+       if (qctrl)
+       sensor->info_priv.brightness = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+       if (qctrl)
+       sensor->info_priv.effect = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE);
+       if (qctrl)
+        sensor->info_priv.exposure = qctrl->default_value;
+
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION);
+       if (qctrl)
+        sensor->info_priv.saturation = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST);
+       if (qctrl)
+        sensor->info_priv.contrast = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP);
+       if (qctrl)
+        sensor->info_priv.mirror = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP);
+       if (qctrl)
+        sensor->info_priv.flip = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE);
+       if (qctrl)
+        sensor->info_priv.scene = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);
+       if (qctrl)
+        sensor->info_priv.digitalzoom = qctrl->default_value;
+
+    /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code  */
+       #if CONFIG_SENSOR_Focus
+    sensor_set_focus();
+    qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);
+       if (qctrl)
+        sensor->info_priv.focus = qctrl->default_value;
+       #endif
+
+       #if CONFIG_SENSOR_Flash
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);
+       if (qctrl)
+        sensor->info_priv.flash = qctrl->default_value;
+    #endif
+
+    SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);
+
+    return 0;
+sensor_INIT_ERR:
+       sensor_task_lock(client,0);
+       sensor_deactivate(client);
+    return ret;
+}
+
+static int sensor_deactivate(struct i2c_client *client)
+{
+       struct soc_camera_device *icd = client->dev.platform_data;
+
+       SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
+
+       /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);
+
+       /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
+       icd->user_width = SENSOR_INIT_WIDTH;
+    icd->user_height = SENSOR_INIT_HEIGHT;
+       msleep(100);
+       return 0;
+}
+
+static  struct reginfo sensor_power_down_sequence[]=
+{
+    {0x00,0x00}
+};
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
+{
+    int ret;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if (pm_msg.event == PM_EVENT_SUSPEND) {
+        SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());
+        ret = sensor_write_array(client, sensor_power_down_sequence) ;
+        if (ret != 0) {
+            SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);
+            return ret;
+        } else {
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);
+            if (ret < 0) {
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
+                return -EINVAL;
+            }
+        }
+    } else {
+        SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+    return 0;
+}
+
+static int sensor_resume(struct soc_camera_device *icd)
+{
+       int ret;
+
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);
+    if (ret < 0) {
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+       SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());
+
+    return 0;
+
+}
+
+static int sensor_set_bus_param(struct soc_camera_device *icd,
+                                unsigned long flags)
+{
+
+    return 0;
+}
+
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)
+{
+    struct soc_camera_link *icl = to_soc_camera_link(icd);
+    unsigned long flags = SENSOR_BUS_PARAM;
+
+    return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+
+    pix->width         = icd->user_width;
+    pix->height                = icd->user_height;
+    pix->pixelformat   = sensor->info_priv.pixfmt;
+    pix->field         = V4L2_FIELD_NONE;
+    pix->colorspace            = V4L2_COLORSPACE_JPEG;
+
+    return 0;
+}
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+       const struct v4l2_queryctrl *qctrl;
+       struct soc_camera_device *icd = client->dev.platform_data;
+    struct reginfo *winseqe_set_addr=NULL;
+    int ret=0, set_w,set_h;
+
+       if (sensor->info_priv.pixfmt != pix->pixelformat) {
+               switch (pix->pixelformat)
+               {
+                       case V4L2_PIX_FMT_YUYV:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_YUYV;
+                               break;
+                       }
+                       case V4L2_PIX_FMT_UYVY:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_UYVY;
+                               break;
+                       }
+                       default:
+                               break;
+               }
+               if (winseqe_set_addr != NULL) {
+            sensor_write_array(client, winseqe_set_addr);
+                       sensor->info_priv.pixfmt = pix->pixelformat;
+
+                       SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+               } else {
+                       SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+               }
+       }
+
+    set_w = pix->width;
+    set_h = pix->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg != END_REG))
+       {
+               winseqe_set_addr = sensor_qcif;
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg != END_REG))
+    {
+        winseqe_set_addr = sensor_qvga;
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg != END_REG))
+    {
+        winseqe_set_addr = sensor_cif;
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg != END_REG))
+    {
+        winseqe_set_addr = sensor_vga;
+        set_w = 640;
+        set_h = 480;
+    }
+    else
+    {
+        winseqe_set_addr = SENSOR_INIT_WINSEQADR;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;
+
+               SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);
+    }
+
+    if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr) {
+        #if CONFIG_SENSOR_Flash
+        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_On);
+                SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
+            }           
+        } else {                                        /* ddl@rock-chips.com : Video */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());
+            }
+        }
+        #endif
+        ret |= sensor_write_array(client, winseqe_set_addr);
+        if (ret != 0) {
+            SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
+            #if CONFIG_SENSOR_Flash
+            if (sensor_fmt_capturechk(sd,f) == true) {
+                if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                    sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                    SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
+                }
+            }
+            #endif
+            goto sensor_s_fmt_end;
+        }
+
+        sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
+
+               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+        #if CONFIG_SENSOR_Effect
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+        #endif
+        #if CONFIG_SENSOR_WhiteBalance
+                       if (sensor->info_priv.whiteBalance != 0) {
+                               qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                               sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       }
+        #endif
+                       sensor->info_priv.snap2preview = true;
+               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               #if CONFIG_SENSOR_Effect
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+        #endif
+        #if CONFIG_SENSOR_WhiteBalance
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+        #endif
+                       sensor->info_priv.video2preview = true;
+               } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {
+               #if CONFIG_SENSOR_Effect
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+        #endif
+        #if CONFIG_SENSOR_WhiteBalance
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+        #endif
+                       sensor->info_priv.video2preview = false;
+                       sensor->info_priv.snap2preview = false;
+               }
+
+        SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
+    }
+    else
+    {
+        SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
+    }
+
+       pix->width = set_w;
+    pix->height = set_h;
+
+sensor_s_fmt_end:
+    return ret;
+}
+
+static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+    bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY ||
+        pix->pixelformat == V4L2_PIX_FMT_YUYV;
+
+    /*
+    * With Bayer format enforce even side lengths, but let the user play
+    * with the starting pixel
+    */
+
+    if (pix->height > SENSOR_MAX_HEIGHT)
+        pix->height = SENSOR_MAX_HEIGHT;
+    else if (pix->height < SENSOR_MIN_HEIGHT)
+        pix->height = SENSOR_MIN_HEIGHT;
+    else if (bayer)
+        pix->height = ALIGN(pix->height, 2);
+
+    if (pix->width > SENSOR_MAX_WIDTH)
+        pix->width = SENSOR_MAX_WIDTH;
+    else if (pix->width < SENSOR_MIN_WIDTH)
+        pix->width = SENSOR_MIN_WIDTH;
+    else if (bayer)
+        pix->width = ALIGN(pix->width, 2);
+
+    return 0;
+}
+
+ static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
+{
+    struct i2c_client *client = sd->priv;
+
+    if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
+        return -EINVAL;
+
+    if (id->match.addr != client->addr)
+        return -ENODEV;
+
+    id->ident = SENSOR_V4L2_IDENT;      /* ddl@rock-chips.com :  Return OV2655  identifier */
+    id->revision = 0;
+
+    return 0;
+}
+#if CONFIG_SENSOR_Brightness
+static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Effect
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_EffectSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Exposure
+static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Saturation
+static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Contrast
+static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Mirror
+static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Flip
+static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_FlipSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Scene
+static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_SceneSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl_info;
+    int digitalzoom_cur, digitalzoom_total;
+
+       qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);
+       if (qctrl_info)
+               return -EINVAL;
+
+    digitalzoom_cur = sensor->info_priv.digitalzoom;
+    digitalzoom_total = qctrl_info->maximum;
+
+    if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total))
+    {
+        SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
+        return -EINVAL;
+    }
+
+    if  ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum))
+    {
+        SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
+        return -EINVAL;
+    }
+
+    if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total))
+    {
+        *value = digitalzoom_total - digitalzoom_cur;
+    }
+
+    if ((*value < 0) && ((digitalzoom_cur + *value) < 0))
+    {
+        *value = 0 - digitalzoom_cur;
+    }
+
+    digitalzoom_cur += *value;
+
+    if (sensor_ZoomSeqe[digitalzoom_cur] != NULL)
+    {
+        if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0)
+        {
+            SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+            return -EINVAL;
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value);
+        return 0;
+    }
+
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Flash
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{    
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {
+        if (value == 3) {       /* ddl@rock-chips.com: torch */
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Torch);   /* Flash On */
+        } else {
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+        return 0;
+    }
+    
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct v4l2_queryctrl *qctrl;
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ctrl->id)
+    {
+        case V4L2_CID_BRIGHTNESS:
+            {
+                ctrl->value = sensor->info_priv.brightness;
+                break;
+            }
+        case V4L2_CID_SATURATION:
+            {
+                ctrl->value = sensor->info_priv.saturation;
+                break;
+            }
+        case V4L2_CID_CONTRAST:
+            {
+                ctrl->value = sensor->info_priv.contrast;
+                break;
+            }
+        case V4L2_CID_DO_WHITE_BALANCE:
+            {
+                ctrl->value = sensor->info_priv.whiteBalance;
+                break;
+            }
+        case V4L2_CID_EXPOSURE:
+            {
+                ctrl->value = sensor->info_priv.exposure;
+                break;
+            }
+        case V4L2_CID_HFLIP:
+            {
+                ctrl->value = sensor->info_priv.mirror;
+                break;
+            }
+        case V4L2_CID_VFLIP:
+            {
+                ctrl->value = sensor->info_priv.flip;
+                break;
+            }
+        default :
+                break;
+    }
+    return 0;
+}
+
+
+
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    struct soc_camera_device *icd = client->dev.platform_data;
+    const struct v4l2_queryctrl *qctrl;
+
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ctrl->id)
+    {
+#if CONFIG_SENSOR_Brightness
+        case V4L2_CID_BRIGHTNESS:
+            {
+                if (ctrl->value != sensor->info_priv.brightness)
+                {
+                    if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.brightness = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Exposure
+        case V4L2_CID_EXPOSURE:
+            {
+                if (ctrl->value != sensor->info_priv.exposure)
+                {
+                    if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.exposure = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Saturation
+        case V4L2_CID_SATURATION:
+            {
+                if (ctrl->value != sensor->info_priv.saturation)
+                {
+                    if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.saturation = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Contrast
+        case V4L2_CID_CONTRAST:
+            {
+                if (ctrl->value != sensor->info_priv.contrast)
+                {
+                    if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.contrast = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+        case V4L2_CID_DO_WHITE_BALANCE:
+            {
+                if (ctrl->value != sensor->info_priv.whiteBalance)
+                {
+                    if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.whiteBalance = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Mirror
+        case V4L2_CID_HFLIP:
+            {
+                if (ctrl->value != sensor->info_priv.mirror)
+                {
+                    if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.mirror = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Flip
+        case V4L2_CID_VFLIP:
+            {
+                if (ctrl->value != sensor->info_priv.flip)
+                {
+                    if (sensor_set_flip(icd, qctrl,ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.flip = ctrl->value;
+                }
+                break;
+            }
+#endif
+        default:
+            break;
+    }
+
+    return 0;
+}
+static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl)
+{
+    const struct v4l2_queryctrl *qctrl;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ext_ctrl->id)
+    {
+        case V4L2_CID_SCENE:
+            {
+                ext_ctrl->value = sensor->info_priv.scene;
+                break;
+            }
+        case V4L2_CID_EFFECT:
+            {
+                ext_ctrl->value = sensor->info_priv.effect;
+                break;
+            }
+        case V4L2_CID_ZOOM_ABSOLUTE:
+            {
+                ext_ctrl->value = sensor->info_priv.digitalzoom;
+                break;
+            }
+        case V4L2_CID_ZOOM_RELATIVE:
+            {
+                return -EINVAL;
+            }
+        case V4L2_CID_FOCUS_ABSOLUTE:
+            {
+                ext_ctrl->value = sensor->info_priv.focus;
+                break;
+            }
+        case V4L2_CID_FOCUS_RELATIVE:
+            {
+                return -EINVAL;
+            }
+        case V4L2_CID_FLASH:
+            {
+                ext_ctrl->value = sensor->info_priv.flash;
+                break;
+            }
+        default :
+            break;
+    }
+    return 0;
+}
+static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl)
+{
+    const struct v4l2_queryctrl *qctrl;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+    int val_offset;
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        return -EINVAL;
+    }
+
+       val_offset = 0;
+    switch (ext_ctrl->id)
+    {
+#if CONFIG_SENSOR_Scene
+        case V4L2_CID_SCENE:
+            {
+                if (ext_ctrl->value != sensor->info_priv.scene)
+                {
+                    if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.scene = ext_ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Effect
+        case V4L2_CID_EFFECT:
+            {
+                if (ext_ctrl->value != sensor->info_priv.effect)
+                {
+                    if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.effect= ext_ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+        case V4L2_CID_ZOOM_ABSOLUTE:
+            {
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
+
+                if (ext_ctrl->value != sensor->info_priv.digitalzoom)
+                {
+                    val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom;
+
+                    if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.digitalzoom += val_offset;
+
+                    SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(),  sensor->info_priv.digitalzoom);
+                }
+
+                break;
+            }
+        case V4L2_CID_ZOOM_RELATIVE:
+            {
+                if (ext_ctrl->value)
+                {
+                    if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.digitalzoom += ext_ctrl->value;
+
+                    SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom);
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Focus
+        case V4L2_CID_FOCUS_ABSOLUTE:
+            {
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
+
+                if (ext_ctrl->value != sensor->info_priv.focus)
+                {
+                    val_offset = ext_ctrl->value -sensor->info_priv.focus;
+
+                    sensor->info_priv.focus += val_offset;
+                }
+
+                break;
+            }
+        case V4L2_CID_FOCUS_RELATIVE:
+            {
+                if (ext_ctrl->value)
+                {
+                    sensor->info_priv.focus += ext_ctrl->value;
+
+                    SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus);
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Flash
+        case V4L2_CID_FLASH:
+            {
+                if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)
+                    return -EINVAL;
+                sensor->info_priv.flash = ext_ctrl->value;
+
+                SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);
+                break;
+            }
+#endif
+        default:
+            break;
+    }
+
+    return 0;
+}
+
+static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    int i, error_cnt=0, error_idx=-1;
+
+
+    for (i=0; i<ext_ctrl->count; i++) {
+        if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+            error_cnt++;
+            error_idx = i;
+        }
+    }
+
+    if (error_cnt > 1)
+        error_idx = ext_ctrl->count;
+
+    if (error_idx != -1) {
+        ext_ctrl->error_idx = error_idx;
+        return -EINVAL;
+    } else {
+        return 0;
+    }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    int i, error_cnt=0, error_idx=-1;
+
+
+    for (i=0; i<ext_ctrl->count; i++) {
+        if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+            error_cnt++;
+            error_idx = i;
+        }
+    }
+
+    if (error_cnt > 1)
+        error_idx = ext_ctrl->count;
+
+    if (error_idx != -1) {
+        ext_ctrl->error_idx = error_idx;
+        return -EINVAL;
+    } else {
+        return 0;
+    }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+                              struct i2c_client *client)
+{
+    char value;
+    int ret;
+    struct sensor *sensor = to_sensor(client);
+
+    /* We must have a parent by now. And it cannot be a wrong one.
+     * So this entire test is completely redundant. */
+    if (!icd->dev.parent ||
+           to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+               return -ENODEV;
+
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
+
+    /* soft reset */
+    ret = sensor_write(client, 0x01, 0xf3);
+    if (ret != 0)
+    {
+        SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
+        return -ENODEV;
+    }
+    mdelay(5);          //delay 5 microseconds    
+
+    /* check if it is an sensor sensor */
+    ret = sensor_read(client, 0x04, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id high byte failed\n");
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+
+    if (value == SENSOR_ID) {
+        sensor->model = SENSOR_V4L2_IDENT;
+    } else {
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+               
+    icd->formats = sensor_colour_formats;
+    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
+
+    return 0;
+
+sensor_video_probe_err:
+
+    return ret;
+}
+static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+       struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    int ret = 0;
+#if CONFIG_SENSOR_Flash        
+    int i;
+#endif
+    
+       SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+       switch (cmd)
+       {
+               case RK29_CAM_SUBDEV_DEACTIVATE:
+               {
+                       sensor_deactivate(client);
+                       break;
+               }
+
+               case RK29_CAM_SUBDEV_IOREQUEST:
+               {
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
+            /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
+               for this project */
+            #if CONFIG_SENSOR_Flash    
+               if (sensor->sensor_gpio_res) { 
+                if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {
+                    for (i = 0; i < icd->ops->num_controls; i++) {
+                               if (V4L2_CID_FLASH == icd->ops->controls[i].id) {
+                                       memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                       
+                               }
+                    }
+                    sensor->info_priv.flash = 0xff;
+                    SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());
+                }
+               }
+            #endif
+                       break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_ioctl_end:
+       return ret;
+
+}
+static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
+       .init           = sensor_init,
+       .g_ctrl         = sensor_g_control,
+       .s_ctrl         = sensor_s_control,
+       .g_ext_ctrls          = sensor_g_ext_controls,
+       .s_ext_ctrls          = sensor_s_ext_controls,
+       .g_chip_ident   = sensor_g_chip_ident,
+       .ioctl = sensor_ioctl,
+};
+
+static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {
+       .s_fmt          = sensor_s_fmt,
+       .g_fmt          = sensor_g_fmt,
+       .try_fmt        = sensor_try_fmt,
+};
+
+static struct v4l2_subdev_ops sensor_subdev_ops = {
+       .core   = &sensor_subdev_core_ops,
+       .video = &sensor_subdev_video_ops,
+};
+
+static int sensor_probe(struct i2c_client *client,
+                        const struct i2c_device_id *did)
+{
+    struct sensor *sensor;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+    struct soc_camera_link *icl;
+    int ret;
+
+    SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__);
+    if (!icd) {
+        dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+    icl = to_soc_camera_link(icd);
+    if (!icl) {
+        dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+    if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+        dev_warn(&adapter->dev,
+                "I2C-Adapter doesn't support I2C_FUNC_I2C\n");
+        return -EIO;
+    }
+
+    sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL);
+    if (!sensor)
+        return -ENOMEM;
+
+    v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops);
+
+    /* Second stage probe - when a capture adapter is there */
+    icd->ops           = &sensor_ops;
+    icd->y_skip_top            = 0;
+       #if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_set(&sensor->tasklock_cnt,0);
+       #endif
+
+    ret = sensor_video_probe(icd, client);
+    if (ret < 0) {
+        icd->ops = NULL;
+        i2c_set_clientdata(client, NULL);
+        kfree(sensor);
+               sensor = NULL;
+    }
+    SENSOR_DG("\n%s..%s..%d  ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);
+    return ret;
+}
+
+static int sensor_remove(struct i2c_client *client)
+{
+    struct sensor *sensor = to_sensor(client);
+    struct soc_camera_device *icd = client->dev.platform_data;
+
+    icd->ops = NULL;
+    i2c_set_clientdata(client, NULL);
+    client->driver = NULL;
+    kfree(sensor);
+       sensor = NULL;
+    return 0;
+}
+
+static const struct i2c_device_id sensor_id[] = {
+       {SENSOR_NAME_STRING(), 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, sensor_id);
+
+static struct i2c_driver sensor_i2c_driver = {
+       .driver = {
+               .name = SENSOR_NAME_STRING(),
+       },
+       .probe          = sensor_probe,
+       .remove         = sensor_remove,
+       .id_table       = sensor_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+    SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING());
+    return i2c_add_driver(&sensor_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+    i2c_del_driver(&sensor_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));
+MODULE_AUTHOR("lxh@wisky.com.cn");
+MODULE_LICENSE("GPL");
+
+
+
diff --git a/drivers/media/video/nt99250.c b/drivers/media/video/nt99250.c
new file mode 100755 (executable)
index 0000000..25c3e5f
--- /dev/null
@@ -0,0 +1,2842 @@
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <mach/rk29_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do {                       \
+       if (debug >= level)                                     \
+       printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
+
+
+#define _CONS(a,b) a##b
+#define CONS(a,b) _CONS(a,b)
+
+#define __STR(x) #x
+#define _STR(x) __STR(x)
+#define STR(x) _STR(x)
+
+#define MIN(x,y)   ((x<y) ? x: y)
+#define MAX(x,y)    ((x>y) ? x: y)
+
+/* Sensor Driver Configuration */
+#define SENSOR_NAME RK29_CAM_SENSOR_NT99250
+#define SENSOR_V4L2_IDENT V4L2_IDENT_NT99250
+#define SENSOR_ID 0x0105
+#define SENSOR_MIN_WIDTH    176
+#define SENSOR_MIN_HEIGHT   144
+#define SENSOR_MAX_WIDTH    1600
+#define SENSOR_MAX_HEIGHT   1200
+#define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  600
+#define SENSOR_INIT_WINSEQADR sensor_svga
+#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY
+
+#define CONFIG_SENSOR_WhiteBalance     0
+#define CONFIG_SENSOR_Brightness       0
+#define CONFIG_SENSOR_Contrast      0
+#define CONFIG_SENSOR_Saturation    0
+#define CONFIG_SENSOR_Effect        0
+#define CONFIG_SENSOR_Scene         0
+#define CONFIG_SENSOR_DigitalZoom   0
+#define CONFIG_SENSOR_Focus         0
+#define CONFIG_SENSOR_Exposure      0
+#define CONFIG_SENSOR_Flash         0
+#define CONFIG_SENSOR_Mirror        0
+#define CONFIG_SENSOR_Flip          0
+
+#define CONFIG_SENSOR_I2C_SPEED     250000       /* Hz */
+/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */
+#define CONFIG_SENSOR_I2C_NOSCHED   0
+#define CONFIG_SENSOR_I2C_RDWRCHK   0
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
+#define COLOR_TEMPERATURE_CLOUDY_DN  6500
+#define COLOR_TEMPERATURE_CLOUDY_UP    8000
+#define COLOR_TEMPERATURE_CLEARDAY_DN  5000
+#define COLOR_TEMPERATURE_CLEARDAY_UP    6500
+#define COLOR_TEMPERATURE_OFFICE_DN     3500
+#define COLOR_TEMPERATURE_OFFICE_UP     5000
+#define COLOR_TEMPERATURE_HOME_DN       2500
+#define COLOR_TEMPERATURE_HOME_UP       3500
+
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
+
+struct reginfo
+{
+    u16 reg;
+    u8 val;
+};
+
+/* init 352X288 SVGA */
+static struct reginfo sensor_init_data[] =
+{
+{0x3024,0x02}, //TG   //0x02     
+{0x32F0,0x00},//0:UYVY 2:VYUY  1:YUYV   3:YVYU
+{0x301e,0x54},
+{0x301f,0x48},
+//gamma ++++
+{0x3270,0x00},
+{0x3271,0x04},
+{0x3272,0x0E},
+{0x3273,0x28},
+{0x3274,0x3F},
+{0x3275,0x50},
+{0x3276,0x6E},
+{0x3277,0x88},
+{0x3278,0xA0},
+{0x3279,0xB3},
+{0x327A,0xD2},
+{0x327B,0xE8},
+{0x327C,0xF5},
+{0x327D,0xFF},
+{0x327E,0xFF},
+//gamma ----
+//CC ++++
+{0x3302,0x00},
+{0x3303,0x2E},
+{0x3304,0x00},
+{0x3305,0xB7},
+{0x3306,0x00},
+{0x3307,0x1A},
+{0x3308,0x07},
+{0x3309,0xE7},
+{0x330A,0x07},
+{0x330B,0x44},
+{0x330C,0x00},
+{0x330D,0xD6},
+{0x330E,0x01},
+{0x330F,0x01},
+{0x3310,0x07},
+{0x3311,0x1A},
+{0x3312,0x07},
+{0x3313,0xE5},
+//CC ----
+//LSC_+++++
+{0x3250,0x01},         
+{0x3251,0x87}, 
+{0x3252,0x01}, 
+{0x3253,0x88}, 
+{0x3254,0x01}, 
+{0x3255,0x89}, 
+{0x3256,0x01}, 
+{0x3257,0x33}, 
+{0x3258,0x01}, 
+{0x3259,0x34}, 
+{0x325A,0x01}, 
+{0x325B,0x35}, 
+{0x325C,0x00}, 
+{0x325D,0x00}, 
+{0x325E,0x00}, 
+{0x325F,0x00}, 
+{0x3260,0x00}, 
+{0x3261,0x00}, 
+{0x3262,0x09}, 
+{0x3263,0x08}, 
+{0x3264,0x08}, 
+{0x3265,0x17}, 
+{0x3266,0x00},         
+{0x3200,0x3e},
+//LSC_----  
+//analog ++++
+{0x3102,0x0b},
+{0x3103,0x46},
+{0x3105,0x33},
+{0x3107,0x32},
+{0x310A,0x03},
+{0x310B,0x18},
+{0x310f,0x08},
+{0x3110,0x03},
+{0x3113,0x0F},
+{0x3119,0x17},
+{0x3114,0x03},
+{0x3117,0x03},
+{0x3118,0x01},
+{0x3380,0x03},
+//analog ----
+//DAC&DPC ++++
+{0x3044,0x02},
+{0x3045,0xd0},
+{0x3046,0x02},
+{0x3047,0xd0},
+{0x3048,0x02},
+{0x3049,0xd0},
+{0x304a,0x02},
+{0x304b,0xd0},
+{0x303e,0x02},
+{0x303f,0x2b},
+{0x3052,0x80},
+{0x3059,0x10},
+{0x305a,0x28},
+{0x305b,0x20},
+{0x305c,0x04},
+{0x305d,0x28},
+{0x305e,0x04},
+{0x305f,0x52},
+{0x3058,0x01},
+//DAC&DPC ----
+{0x3080,0x80},
+{0x3081,0x80},
+{0x3082,0x80},
+{0x3083,0x40},
+{0x3084,0x80},
+{0x3085,0x40},
+//AEC AGC ++++
+{0x32b0,0x00},
+{0x32b1,0x90},
+{0x32BB,0x0b},
+{0x32bd,0x05},
+{0x32be,0x05},
+{0x32cd,0x01},
+{0x32d3,0x13},
+{0x32d7,0x82},
+{0x32d8,0x3F},
+{0x32d9,0x18},
+{0x32c5,0x18},
+//AEC AGC ----
+{0x32f6,0x0c},//effect function
+{0x3069, 0x00}, //Pix   //01 :for M1002     00 :for other
+{0x306d, 0x01}, //pclk   //00 :for M1002     01 :for other
+
+       //==============================
+       //Output  size 
+       //==============================
+       //[800X600]
+       //edge & denoise +++
+       {0x3300,0x30},
+       {0x3301,0x80},
+       {0x3320,0x28},
+       {0x3331,0x04},
+       {0x3332,0x40},
+       {0x3339,0x10},
+       {0x333a,0x1a},
+       //edge & denoise ---
+       //AE AWB mode ++
+       {0x329C,0x4b},
+       {0x32bf,0x52},
+       {0x32c0,0x10},
+       {0x3200,0x3e},
+       {0x3201,0x3f},
+       {0x32b0,0x02},
+       {0x32b1,0xc0},
+       //AE AWB mode ---
+       {0x3052,0x80},  //OB
+       {0x32e0,0x03}, 
+       {0x32e1,0x20}, 
+       {0x32e2,0x02}, 
+       {0x32e3,0x58}, 
+       {0x32e4,0x01}, 
+       {0x32e5,0x00}, 
+       {0x32e6,0x00}, 
+       {0x32e7,0x00}, 
+       {0x301e,0x00},  //pll
+       {0x301f,0x20},  //pll
+       {0x3022,0x25}, 
+       {0x3023,0x64}, 
+       {0x3002,0x00}, 
+       {0x3003,0x04}, 
+       {0x3004,0x00}, 
+       {0x3005,0x04}, 
+       {0x3006,0x06}, 
+       {0x3007,0x43}, 
+       {0x3008,0x04}, 
+       {0x3009,0xb3}, 
+       {0x300a,0x09}, 
+       {0x300b,0x91}, 
+       {0x300c,0x02}, 
+       {0x300d,0x64}, 
+       {0x300e,0x06}, 
+       {0x300f,0x40}, 
+       {0x3010,0x02}, 
+       {0x3011,0x58}, 
+       {0x32bb,0x0b}, 
+       {0x32bc,0x3a}, 
+       {0x32c1,0x25}, 
+       {0x32c2,0x5c},   //7.14fps @ 48M 
+       {0x32c8,0x62}, 
+       {0x32c9,0x52}, 
+       {0x32c4,0x00}, 
+       {0x3290,0x01},  //awb init ++++
+       {0x3291,0x68},
+       {0x3296,0x01},
+       {0x3297,0x75},  
+       {0x32A9,0x11},
+       {0x32AA,0x01},  
+       {0x329b,0x01},
+       {0x32a2,0x60},
+       {0x32a4,0xa0},
+       {0x32a6,0x60},
+       {0x32a8,0xa0},   //awb init ----
+       {0x3012,0x02},  //AE init +++
+       {0x3013,0xae},
+       {0x301d,0x08}, 
+       {0x3201,0x7f},  //AE init ---
+       {0x3021,0x06}, 
+       {0x3060,0x01}, 
+       {0x0, 0x0},   //end flag        
+       
+};
+
+/* 1600X1200 UXGA */
+static struct reginfo sensor_uxga[] =
+{
+       //Output format & size
+       {0x3300, 0x3f},
+       {0x3301, 0xa0},
+       {0x3331, 0x08},
+       {0x3332, 0x80}, //0x20
+       {0x3320, 0x20}, //0x28
+
+       {0x329C, 0x4b},
+       {0x32bf, 0x52},
+       {0x3200, 0x3e},
+
+       {0x32e0,0x06},
+       {0x32e1,0x40},
+       {0x32e2,0x04},
+       {0x32e3,0xb0},
+       {0x32e4,0x00},
+       {0x32e5,0x00},
+       {0x32e6,0x00},
+       {0x32e7,0x00},
+
+       {0x301e, 0x00}, 
+       {0x301f, 0x20}, 
+
+       {0x3022, 0x25},
+       {0x3023, 0x24},
+               
+       //Capture_1600x1200s
+       {0x3002, 0x00}, 
+       {0x3003, 0x04}, 
+       {0x3004, 0x00}, 
+       {0x3005, 0x04}, 
+       {0x3006, 0x06}, 
+       {0x3007, 0x43}, 
+       {0x3008, 0x00}, 
+       {0x3009, 0xb3}, 
+       {0x300a, 0x09}, 
+       {0x300b, 0x82}, 
+       {0x300c, 0x07}, 
+       {0x300d, 0xb4}, 
+       {0x300e, 0x06}, 
+       {0x300f, 0x40}, 
+       {0x3010, 0x04}, 
+       {0x3011, 0xb0},
+
+       {0x32bb, 0x0b}, 
+       //{0x32bc, 0x38}, 
+
+       {0x32c4, 0x00}, 
+       //{0x3201, 0x3f}, 
+       {0x3021, 0x06}, 
+       {0x3060, 0x01}, 
+
+    {0x0, 0x0},
+};
+
+/* 1280X1024 SXGA */
+static struct reginfo sensor_sxga[] =
+{
+       {0x3300, 0x3f},
+       {0x3301, 0xa0},
+       {0x3331, 0x0c},
+       {0x3332, 0x80},
+       {0x3320, 0x20}, 
+       {0x329C, 0x4b},
+       {0x32bf, 0x52},
+       {0x3200, 0x3e},
+//1280x1024
+       {0x32e0, 0x05}, 
+       {0x32e1, 0x00}, 
+       {0x32e2, 0x04}, 
+       {0x32e3, 0x00}, 
+       {0x32e4, 0x00}, 
+       {0x32e5, 0x40}, 
+       {0x32e6, 0x00}, 
+       {0x32e7, 0x2c}, 
+       
+       {0x301e, 0x00}, 
+       {0x3022, 0x25}, 
+       {0x3023, 0x24}, 
+       {0x3002, 0x00}, 
+       {0x3003, 0x04}, 
+       {0x3004, 0x00}, 
+       {0x3005, 0x04}, 
+       {0x3006, 0x06}, 
+       {0x3007, 0x43}, 
+       {0x3008, 0x04}, 
+       {0x3009, 0xb3}, 
+       {0x300a, 0x09}, 
+       {0x300b, 0x82}, 
+       {0x300c, 0x07}, 
+       {0x300d, 0xb4}, 
+       {0x300e, 0x06}, 
+       {0x300f, 0x40}, 
+       {0x3010, 0x04}, 
+       {0x3011, 0xb0}, 
+       {0x32bb, 0x0b}, 
+
+       //{0x3201, 0x7f}, 
+       {0x3021, 0x06}, 
+       {0x3060, 0x01}, 
+    {0x0, 0x0},
+};
+
+/* 800X600 SVGA*/
+static struct reginfo sensor_svga[] =
+{
+//edge & denoise +++
+{0x3300,0x30},
+{0x3301,0x80},
+{0x3320,0x30},
+{0x3331,0x0c},
+{0x3332,0x40},
+{0x3339,0x10},
+{0x333a,0x1a},
+//edge & denoise ---
+//AE AWB mode ++
+{0x329C,0x4b},
+{0x32bf,0x52},
+{0x32c0,0x10},
+{0x3200,0x3e},
+//{0x3201,0x3f},
+{0x32b0,0x02},
+{0x32b1,0xc0},
+//AE AWB mode ---
+{0x3052,0x80}, //OB
+       {0x32e0,0x03}, 
+       {0x32e1,0x20}, 
+       {0x32e2,0x02}, 
+       {0x32e3,0x58}, 
+       {0x32e4,0x01}, 
+       {0x32e5,0x00}, 
+       {0x32e6,0x00}, 
+       {0x32e7,0x00}, 
+{0x301e,0x00}, //pll
+{0x301f,0x20}, //pll     0x20  48Mhz    0x24  32Mhz
+{0x3022,0x25}, 
+{0x3023,0x64}, 
+       {0x3002,0x00}, 
+       {0x3003,0x04}, 
+       {0x3004,0x00}, 
+       {0x3005,0x04}, 
+       {0x3006,0x06}, 
+       {0x3007,0x43}, 
+       {0x3008,0x04}, 
+       {0x3009,0xb3}, 
+       {0x300a,0x09}, 
+       {0x300b,0x91}, 
+       {0x300c,0x02}, 
+       {0x300d,0x64}, 
+       {0x300e,0x06}, 
+       {0x300f,0x40}, 
+       {0x3010,0x02}, 
+       {0x3011,0x58}, 
+{0x32bb,0x0b}, 
+{0x32bc,0x30}, 
+{0x32c1,0x25}, 
+{0x32c2,0x5c},  //7.14fps @ 48M 
+//{0x32c1,0x23}, 
+//{0x32c2,0xd4},  //10fps @ 48M 
+{0x32c8,0x62}, 
+{0x32c9,0x52}, 
+{0x32c4,0x00}, 
+//{0x3290,0x01},       //awb init ++++
+//{0x3291,0x68},
+//{0x3296,0x01},
+//{0x3297,0x75},       
+{0x32A9,0x11},
+{0x32AA,0x01}, 
+{0x329b,0x01},
+{0x32a2,0x60},
+{0x32a4,0xa0},
+{0x32a6,0x60},
+{0x32a8,0xa0},  //awb init ----
+//{0x3012,0x02},       //AE init +++
+//{0x3013,0xae},
+//{0x301d,0x08}, 
+//{0x3201,0x7f},       //AE init ---
+{0x3021,0x06}, 
+{0x3060,0x01}, 
+    {0x0, 0x0}, 
+    {0x0, 0x0},
+};
+
+/* 640X480 VGA */
+static struct reginfo sensor_vga[] =
+{
+//[640X480]
+//edge & denoise +++
+{0x3300,0x30},
+{0x3301,0x80},
+{0x3320,0x28},
+{0x3331,0x04},
+{0x3332,0x40},
+{0x3339,0x10},
+{0x333a,0x1a},
+//edge & denoise ---
+//AE AWB mode ++
+{0x329C,0x4b},
+{0x32bf,0x52},
+{0x32c0,0x10},
+{0x3200,0x3e},
+//{0x3201,0x3f},
+{0x32b0,0x02},
+{0x32b1,0xc0},
+//AE AWB mode ---
+{0x3052,0x80}, //OB
+{0x32e0,0x02}, 
+{0x32e1,0x80}, 
+{0x32e2,0x01}, 
+{0x32e3,0xe0}, 
+{0x32e4,0x01}, 
+{0x32e5,0x81}, 
+{0x32e6,0x00}, 
+{0x32e7,0x40}, 
+{0x301e,0x00}, //pll
+{0x301f,0x20}, //pll     0x20  48Mhz    0x24  32Mhz
+{0x3022,0x25}, 
+{0x3023,0x64}, 
+{0x3002,0x00}, 
+{0x3003,0x04}, 
+{0x3004,0x00}, 
+{0x3005,0x04}, 
+{0x3006,0x06}, 
+{0x3007,0x43}, 
+{0x3008,0x04}, 
+{0x3009,0xb3}, 
+{0x300a,0x09}, 
+{0x300b,0x91}, 
+{0x300c,0x02}, 
+{0x300d,0x91}, 
+{0x300e,0x06}, 
+{0x300f,0x40}, 
+{0x3010,0x02}, 
+{0x3011,0x58}, 
+{0x32bb,0x0b}, 
+{0x32bc,0x30}, 
+//{0x32c1,0x25}, 
+//{0x32c2,0x5c},  //7.14fps @ 48M 
+{0x32c1,0x23}, 
+{0x32c2,0xd4},  //10fps @ 48M 
+{0x32c8,0x62}, 
+{0x32c9,0x52}, 
+{0x32c4,0x00}, 
+//{0x3290,0x01},       //awb init ++++
+//{0x3291,0x68},
+//{0x3296,0x01},
+//{0x3297,0x75},       
+{0x32A9,0x11},
+{0x32AA,0x01}, 
+{0x329b,0x01},
+{0x32a2,0x60},
+{0x32a4,0xa0},
+{0x32a6,0x60},
+{0x32a8,0xa0},  //awb init ----
+//{0x3012,0x02},       //AE init +++
+//{0x3013,0xae},
+//{0x301d,0x08}, 
+//{0x3201,0x7f},       //AE init ---
+{0x3021,0x06}, 
+{0x3060,0x01}, 
+    {0x0, 0x0}, 
+};
+
+/* 352X288 CIF */
+static struct reginfo sensor_cif[] =
+{
+    {0x0, 0x0},
+};
+
+/* 320*240 QVGA */
+static  struct reginfo sensor_qvga[] =
+{
+    {0x0, 0x0},
+};
+
+/* 176X144 QCIF*/
+static struct reginfo sensor_qcif[] =
+{
+    {0x0, 0x0},
+};
+
+
+static  struct reginfo sensor_ClrFmt_YUYV[]=
+{
+    {0x32f0, 0x00},    //0:UYVY        2:VYUY  1:YUYV   3:YVYU
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_ClrFmt_UYVY[]=
+{
+    {0x32F0, 0x00},    //0:UYVY        2:VYUY  1:YUYV   3:YVYU
+    {0x0000, 0x00}
+};
+
+#if CONFIG_SENSOR_WhiteBalance
+static  struct reginfo sensor_WhiteB_Auto[]=
+{
+    {0x3201, 0x3f},  //AWB auto, bit[1]:0,auto
+    {0x0000, 0x00}
+};
+/* Cloudy Colour Temperature : 6500K - 8000K  */
+static  struct reginfo sensor_WhiteB_Cloudy[]=
+{
+    {0x3201, 0x2f},
+    {0x3290, 0x01},
+    {0x3291, 0x48},
+    {0x3296, 0x01},
+    {0x3297, 0x58},
+    {0x0000, 0x00}
+};
+/* ClearDay Colour Temperature : 5000K - 6500K  */
+static  struct reginfo sensor_WhiteB_ClearDay[]=
+{
+    //Sunny
+    {0x3201, 0x2f},
+    {0x3290, 0x01},
+    {0x3291, 0x38},
+    {0x3296, 0x01},
+    {0x3297, 0x68},
+    {0x0000, 0x00}
+
+};
+/* Office Colour Temperature : 3500K - 5000K  */
+static  struct reginfo sensor_WhiteB_TungstenLamp1[]=
+{
+    //Office
+    {0x3201, 0x2f},
+    {0x3290, 0x01},
+    {0x3291, 0x24},
+    {0x3296, 0x01},
+    {0x3297, 0x78},
+    {0x0000, 0x00}
+
+};
+/* Home Colour Temperature : 2500K - 3500K  */
+static  struct reginfo sensor_WhiteB_TungstenLamp2[]=
+{
+    //Home
+    {0x3201, 0x2f},
+    {0x3290, 0x01},
+    {0x3291, 0x30},
+    {0x3296, 0x01},
+    {0x3297, 0x70},
+    {0x0000, 0x00}
+};
+static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,
+    sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,
+};
+#endif
+
+#if CONFIG_SENSOR_Brightness
+static  struct reginfo sensor_Brightness0[]=
+{
+    // Brightness -2
+    {0x32f1, 0x05},
+    {0x32f2, 0x60},
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Brightness1[]=
+{
+    // Brightness -1
+    {0x32f1, 0x05},
+    {0x32f2, 0x70},
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Brightness2[]=
+{
+    //  Brightness 0
+    {0x32f1, 0x05},
+    {0x32f2, 0x80},
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Brightness3[]=
+{
+    // Brightness +1
+    {0x32f1, 0x05},
+    {0x32f2, 0x90},
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Brightness4[]=
+{
+    //  Brightness +2
+    {0x32f1, 0x05},
+    {0x32f2, 0xa0},
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Brightness5[]=
+{
+    //  Brightness +3
+    {0x32f1, 0x05},
+    {0x32f2, 0xb0},
+    {0x0000, 0x00}
+};
+static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,
+    sensor_Brightness4, sensor_Brightness5,NULL,
+};
+
+#endif
+
+#if CONFIG_SENSOR_Effect
+static  struct reginfo sensor_Effect_Normal[] =
+{
+    {0x32f1, 0x00},    
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Effect_WandB[] =
+{
+    {0x32f1, 0x01},
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Effect_Sepia[] =
+{
+    {0x32f1, 0x02},
+    {0x32f6, 0x20},
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Effect_Negative[] =
+{
+    //Negative
+    {0x32f1, 0x03},
+    {0x32f6, 0x10},    
+    {0x0000, 0x00}
+};
+static  struct reginfo sensor_Effect_Bluish[] =
+{
+    // Bluish
+    {0x32f1, 0x05},
+    {0x32f6, 0x04},
+    {0x32f4, 0x80},
+    {0x32f6, 0x0c},
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Effect_Green[] =
+{
+    //  Greenish
+    {0x32f1, 0x05},
+    {0x32f4, 0x60},
+    {0x32f5, 0x20},
+    {0x32f6, 0x0c},
+    {0x0000, 0x00}
+};
+static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,
+    sensor_Effect_Bluish, sensor_Effect_Green,NULL,
+};
+#endif
+#if CONFIG_SENSOR_Exposure
+static  struct reginfo sensor_Exposure0[]=
+{
+    //-3
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Exposure1[]=
+{
+    //-2
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Exposure2[]=
+{
+    //-0.3EV
+     {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Exposure3[]=
+{
+    //default
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Exposure4[]=
+{
+    // 1
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Exposure5[]=
+{
+    // 2
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Exposure6[]=
+{
+    // 3
+    {0x0000, 0x00}
+};
+
+static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,
+    sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,
+};
+#endif
+#if CONFIG_SENSOR_Saturation
+static  struct reginfo sensor_Saturation0[]=
+{
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Saturation1[]=
+{
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Saturation2[]=
+{
+    {0x0000, 0x00}
+};
+static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};
+
+#endif
+#if CONFIG_SENSOR_Contrast
+static  struct reginfo sensor_Contrast0[]=
+{
+    //Contrast -3
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Contrast1[]=
+{
+    //Contrast -2
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Contrast2[]=
+{
+    // Contrast -1
+      {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Contrast3[]=
+{
+    //Contrast 0
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Contrast4[]=
+{
+    //Contrast +1
+    {0x0000, 0x00}
+};
+
+
+static  struct reginfo sensor_Contrast5[]=
+{
+    //Contrast +2
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_Contrast6[]=
+{
+    //Contrast +3
+    {0x0000, 0x00}
+};
+static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,
+    sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,
+};
+
+#endif
+#if CONFIG_SENSOR_Mirror
+static  struct reginfo sensor_MirrorOn[]=
+{
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_MirrorOff[]=
+{
+    {0x0000, 0x00}
+};
+static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,};
+#endif
+#if CONFIG_SENSOR_Flip
+static  struct reginfo sensor_FlipOn[]=
+{
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_FlipOff[]=
+{
+    {0x0000, 0x00}
+};
+static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,};
+
+#endif
+#if CONFIG_SENSOR_Scene
+static  struct reginfo sensor_SceneAuto[] =
+{
+    {0x301e, 0x00},
+    {0x0000, 0x00}
+};
+
+static  struct reginfo sensor_SceneNight[] =
+{
+    //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk
+    {0x301e, 0x04},
+    {0x0000, 0x00}
+};
+static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};
+
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+static struct reginfo sensor_Zoom0[] =
+{
+    {0x0, 0x0},
+};
+
+static struct reginfo sensor_Zoom1[] =
+{
+     {0x0, 0x0},
+};
+
+static struct reginfo sensor_Zoom2[] =
+{
+    {0x0, 0x0},
+};
+
+
+static struct reginfo sensor_Zoom3[] =
+{
+    {0x0, 0x0},
+};
+static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};
+#endif
+static const struct v4l2_querymenu sensor_menus[] =
+{
+       #if CONFIG_SENSOR_WhiteBalance
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 0,  .name = "auto",  .reserved = 0, }, {  .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 1, .name = "incandescent",  .reserved = 0,},
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 2,  .name = "fluorescent", .reserved = 0,}, {  .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3,  .name = "daylight", .reserved = 0,},
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 4,  .name = "cloudy-daylight", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Effect
+    { .id = V4L2_CID_EFFECT,  .index = 0,  .name = "none",  .reserved = 0, }, {  .id = V4L2_CID_EFFECT,  .index = 1, .name = "mono",  .reserved = 0,},
+    { .id = V4L2_CID_EFFECT,  .index = 2,  .name = "negative", .reserved = 0,}, {  .id = V4L2_CID_EFFECT, .index = 3,  .name = "sepia", .reserved = 0,},
+    { .id = V4L2_CID_EFFECT,  .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT,  .index = 5,  .name = "aqua", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Scene
+    { .id = V4L2_CID_SCENE,  .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE,  .index = 1,  .name = "night", .reserved = 0,},
+    #endif
+
+       #if CONFIG_SENSOR_Flash
+    { .id = V4L2_CID_FLASH,  .index = 0,  .name = "off",  .reserved = 0, }, {  .id = V4L2_CID_FLASH,  .index = 1, .name = "auto",  .reserved = 0,},
+    { .id = V4L2_CID_FLASH,  .index = 2,  .name = "on", .reserved = 0,}, {  .id = V4L2_CID_FLASH, .index = 3,  .name = "torch", .reserved = 0,},
+    #endif
+};
+
+static const struct v4l2_queryctrl sensor_controls[] =
+{
+       #if CONFIG_SENSOR_WhiteBalance
+    {
+        .id            = V4L2_CID_DO_WHITE_BALANCE,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "White Balance Control",
+        .minimum       = 0,
+        .maximum       = 4,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Brightness
+       {
+        .id            = V4L2_CID_BRIGHTNESS,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Brightness Control",
+        .minimum       = -3,
+        .maximum       = 2,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Effect
+       {
+        .id            = V4L2_CID_EFFECT,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Effect Control",
+        .minimum       = 0,
+        .maximum       = 5,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Exposure
+       {
+        .id            = V4L2_CID_EXPOSURE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Exposure Control",
+        .minimum       = 0,
+        .maximum       = 6,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Saturation
+       {
+        .id            = V4L2_CID_SATURATION,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Saturation Control",
+        .minimum       = 0,
+        .maximum       = 2,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Contrast
+       {
+        .id            = V4L2_CID_CONTRAST,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Contrast Control",
+        .minimum       = -3,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+
+       #if CONFIG_SENSOR_Mirror
+       {
+        .id            = V4L2_CID_HFLIP,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Mirror Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 1,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Flip
+       {
+        .id            = V4L2_CID_VFLIP,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Flip Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 1,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Scene
+    {
+        .id            = V4L2_CID_SCENE,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Scene Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_DigitalZoom
+    {
+        .id            = V4L2_CID_ZOOM_RELATIVE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "DigitalZoom Control",
+        .minimum       = -1,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }, {
+        .id            = V4L2_CID_ZOOM_ABSOLUTE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "DigitalZoom Control",
+        .minimum       = 0,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Focus
+       {
+        .id            = V4L2_CID_FOCUS_RELATIVE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Focus Control",
+        .minimum       = -1,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }, {
+        .id            = V4L2_CID_FOCUS_ABSOLUTE,
+        .type          = V4L2_CTRL_TYPE_INTEGER,
+        .name          = "Focus Control",
+        .minimum       = 0,
+        .maximum       = 255,
+        .step          = 1,
+        .default_value = 125,
+    },
+    #endif
+
+       #if CONFIG_SENSOR_Flash
+       {
+        .id            = V4L2_CID_FLASH,
+        .type          = V4L2_CTRL_TYPE_MENU,
+        .name          = "Flash Control",
+        .minimum       = 0,
+        .maximum       = 3,
+        .step          = 1,
+        .default_value = 0,
+    },
+       #endif
+};
+
+static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did);
+static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client);
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+static int sensor_g_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);
+static int sensor_s_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);
+static int sensor_resume(struct soc_camera_device *icd);
+static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);
+#if CONFIG_SENSOR_Effect
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+#endif
+static int sensor_deactivate(struct i2c_client *client);
+
+static struct soc_camera_ops sensor_ops =
+{
+    .suspend                     = sensor_suspend,
+    .resume                       = sensor_resume,
+    .set_bus_param             = sensor_set_bus_param,
+    .query_bus_param   = sensor_query_bus_param,
+    .controls          = sensor_controls,
+    .menus                         = sensor_menus,
+    .num_controls              = ARRAY_SIZE(sensor_controls),
+    .num_menus         = ARRAY_SIZE(sensor_menus),
+};
+
+#define COL_FMT(_name, _depth, _fourcc, _colorspace) \
+       { .name = _name, .depth = _depth, .fourcc = _fourcc, \
+       .colorspace = _colorspace }
+
+#define JPG_FMT(_name, _depth, _fourcc) \
+       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)
+
+static const struct soc_camera_data_format sensor_colour_formats[] = {
+       JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY),
+       JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),
+};
+
+typedef struct sensor_info_priv_s
+{
+    int whiteBalance;
+    int brightness;
+    int contrast;
+    int saturation;
+    int effect;
+    int scene;
+    int digitalzoom;
+    int focus;
+    int flash;
+    int exposure;
+       bool snap2preview;
+       bool video2preview;
+    unsigned char mirror;                                        /* HFLIP */
+    unsigned char flip;                                          /* VFLIP */
+    unsigned int winseqe_cur_addr;
+       unsigned int pixfmt;
+
+} sensor_info_priv_t;
+
+struct sensor
+{
+    struct v4l2_subdev subdev;
+    struct i2c_client *client;
+    sensor_info_priv_t info_priv;
+    int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */
+#if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_t tasklock_cnt;
+#endif
+       struct rk29camera_platform_data *sensor_io_request;
+    struct rk29camera_gpio_res *sensor_gpio_res;
+};
+
+
+static struct sensor* to_sensor(const struct i2c_client *client)
+{
+    return container_of(i2c_get_clientdata(client), struct sensor, subdev);
+}
+
+static int sensor_task_lock(struct i2c_client *client, int lock)
+{
+#if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
+    struct sensor *sensor = to_sensor(client);
+
+       if (lock) {
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
+                       preempt_disable();
+               }
+
+               atomic_add(1, &sensor->tasklock_cnt);
+       } else {
+               if (atomic_read(&sensor->tasklock_cnt) > 0) {
+                       atomic_sub(1, &sensor->tasklock_cnt);
+
+                       if (atomic_read(&sensor->tasklock_cnt) == 0)
+                               preempt_enable();
+               }
+       }
+       return 0;
+sensor_task_lock_err:
+       return -1;  
+#else
+    return 0;
+#endif
+
+}
+
+/* sensor register write */
+static int sensor_write(struct i2c_client *client, u16 reg, u8 val)
+{
+    int err,cnt;
+    u8 buf[3];
+    struct i2c_msg msg[1];
+
+    buf[0] = reg >> 8;
+    buf[1] = reg & 0xFF;
+    buf[2] = val;
+
+    msg->addr = client->addr;
+    msg->flags = client->flags;
+    msg->buf = buf;
+    msg->len = sizeof(buf);
+    msg->scl_rate = CONFIG_SENSOR_I2C_SPEED;         /* ddl@rock-chips.com : 100kHz */
+    msg->read_type = 0;               /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */
+
+    cnt = 8;
+    err = -EAGAIN;
+
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+        err = i2c_transfer(client->adapter, msg, 1);
+
+        if (err >= 0) {
+            return 0;
+        } else {
+            SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);
+            udelay(10);
+        }
+    }
+
+    return err;
+}
+
+/* sensor register read */
+static int sensor_read(struct i2c_client *client, u16 reg, u8 *val)
+{
+    int err,cnt;
+    u8 buf[2];
+    struct i2c_msg msg[2];
+
+    buf[0] = reg >> 8;
+    buf[1] = reg & 0xFF;
+
+    msg[0].addr = client->addr;
+    msg[0].flags = client->flags;
+    msg[0].buf = buf;
+    msg[0].len = sizeof(buf);
+    msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED;       /* ddl@rock-chips.com : 100kHz */
+    msg[0].read_type = 2;   /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */
+
+    msg[1].addr = client->addr;
+    msg[1].flags = client->flags|I2C_M_RD;
+    msg[1].buf = buf;
+    msg[1].len = 1;
+    msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED;                       /* ddl@rock-chips.com : 100kHz */
+    msg[1].read_type = 2;                             /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */
+
+    cnt = 3;
+    err = -EAGAIN;
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+        err = i2c_transfer(client->adapter, msg, 2);
+
+        if (err >= 0) {
+            *val = buf[0];
+            return 0;
+        } else {
+               SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val);
+            udelay(10);
+        }
+    }
+
+    return err;
+}
+
+/* write a array of registers  */
+static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int err = 0, cnt;
+    int i = 0;
+#if CONFIG_SENSOR_I2C_RDWRCHK    
+       char valchk;
+#endif
+
+       cnt = 0;
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
+
+    while (regarray[i].reg != 0)
+    {
+        err = sensor_write(client, regarray[i].reg, regarray[i].val);
+        if (err < 0)
+        {
+            if (cnt-- > 0) {
+                           SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg);
+                               i = 0;
+                               continue;
+            } else {
+                SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING());
+                err = -EPERM;
+                               goto sensor_write_array_end;
+            }
+        } else {
+        #if CONFIG_SENSOR_I2C_RDWRCHK
+                       sensor_read(client, regarray[i].reg, &valchk);
+                       if (valchk != regarray[i].val)
+                               SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+               #endif
+        }
+        i++;
+    }
+
+sensor_write_array_end:
+       sensor_task_lock(client,0);
+       return err;
+}
+static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int cnt;
+    int i = 0;
+       char valchk;
+
+       cnt = 0;
+       valchk = 0;
+    while (regarray[i].reg != 0)
+    {
+               sensor_read(client, regarray[i].reg, &valchk);
+               if (valchk != regarray[i].val)
+                       SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+
+        i++;
+    }
+    return 0;
+}
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
+{
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       int ret = 0;
+
+    SENSOR_DG("%s %s  cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
+       switch (cmd)
+       {
+               case Sensor_PowerDown:
+               {
+                       if (icl->powerdown) {
+                               ret = icl->powerdown(icd->pdev, on);
+                               if (ret == RK29_CAM_IO_SUCCESS) {
+                                       if (on == 0) {
+                                               mdelay(2);
+                                               if (icl->reset)
+                                                       icl->reset(icd->pdev);
+                                       }
+                               } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {
+                                       ret = -ENODEV;
+                                       goto sensor_power_end;
+                               }
+                       }
+                       break;
+               }
+               case Sensor_Flash:
+               {
+                       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+               struct sensor *sensor = to_sensor(client);
+
+                       if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
+                               sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
+                       }
+            break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_power_end:
+       return ret;
+}
+static int sensor_init(struct v4l2_subdev *sd, u32 val)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl;
+    char value;
+    int ret,pid = 0;
+
+    SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
+
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_INIT_ERR;
+       }
+
+    /* soft reset */
+       sensor_task_lock(client,1);
+    ret = sensor_write(client, 0x3021, 0x61);
+    if (ret != 0)
+    {
+        SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING());
+        ret = -ENODEV;
+               goto sensor_INIT_ERR;
+    }
+
+    mdelay(5);  //delay 5 microseconds
+       /* check if it is an sensor sensor */
+    ret = sensor_read(client, 0x307e, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id high byte failed\n");
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+
+    pid |= (value << 8);
+
+    ret = sensor_read(client, 0x307f, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id low byte failed\n");
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+
+    pid |= (value & 0xff);
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+       #if 1
+    if (pid == SENSOR_ID) {
+        sensor->model = SENSOR_V4L2_IDENT;
+    } else {
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+        ret = -ENODEV;
+        goto sensor_INIT_ERR;
+    }
+       #endif
+
+    ret = sensor_write_array(client, sensor_init_data);
+    if (ret != 0)
+    {
+        SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
+        goto sensor_INIT_ERR;
+    }
+       sensor_task_lock(client,0);
+    //icd->user_width = SENSOR_INIT_WIDTH;
+    //icd->user_height = SENSOR_INIT_HEIGHT;
+    sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;
+       sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT;
+
+    /* sensor sensor information for initialization  */
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+       if (qctrl)
+       sensor->info_priv.whiteBalance = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS);
+       if (qctrl)
+       sensor->info_priv.brightness = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+       if (qctrl)
+       sensor->info_priv.effect = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE);
+       if (qctrl)
+        sensor->info_priv.exposure = qctrl->default_value;
+
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION);
+       if (qctrl)
+        sensor->info_priv.saturation = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST);
+       if (qctrl)
+        sensor->info_priv.contrast = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP);
+       if (qctrl)
+        sensor->info_priv.mirror = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP);
+       if (qctrl)
+        sensor->info_priv.flip = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE);
+       if (qctrl)
+        sensor->info_priv.scene = qctrl->default_value;
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);
+       if (qctrl)
+        sensor->info_priv.digitalzoom = qctrl->default_value;
+
+    /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code  */
+       #if CONFIG_SENSOR_Focus
+    sensor_set_focus();
+    qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);
+       if (qctrl)
+        sensor->info_priv.focus = qctrl->default_value;
+       #endif
+
+       #if CONFIG_SENSOR_Flash
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);
+       if (qctrl)
+        sensor->info_priv.flash = qctrl->default_value;
+    #endif
+
+    SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);
+
+    return 0;
+sensor_INIT_ERR:
+       sensor_task_lock(client,0);
+       sensor_deactivate(client);
+    return ret;
+}
+
+static int sensor_deactivate(struct i2c_client *client)
+{
+       struct soc_camera_device *icd = client->dev.platform_data;
+       //u8 reg_val;
+
+       SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
+
+       /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);
+
+       /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
+       icd->user_width = SENSOR_INIT_WIDTH;
+    icd->user_height = SENSOR_INIT_HEIGHT;
+       msleep(100);
+       return 0;
+}
+
+static  struct reginfo sensor_power_down_sequence[]=
+{
+    //{0x30ab, 0x00},
+    //{0x30ad, 0x0a},
+    //{0x30ae,0x27},
+    //{0x363b,0x01},
+    {0x00,0x00}
+};
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
+{
+    int ret;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if (pm_msg.event == PM_EVENT_SUSPEND) {
+        SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());
+        ret = sensor_write_array(client, sensor_power_down_sequence) ;
+        if (ret != 0) {
+            SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);
+            return ret;
+        } else {
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);
+            if (ret < 0) {
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
+                return -EINVAL;
+            }
+        }
+    } else {
+        SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+    return 0;
+}
+
+static int sensor_resume(struct soc_camera_device *icd)
+{
+       int ret;
+
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);
+    if (ret < 0) {
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+       SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());
+
+    return 0;
+
+}
+
+static int sensor_set_bus_param(struct soc_camera_device *icd,
+                                unsigned long flags)
+{
+
+    return 0;
+}
+
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)
+{
+    struct soc_camera_link *icl = to_soc_camera_link(icd);
+    unsigned long flags = SENSOR_BUS_PARAM;
+
+    return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+
+    pix->width         = icd->user_width;
+    pix->height                = icd->user_height;
+    pix->pixelformat   = sensor->info_priv.pixfmt;
+    pix->field         = V4L2_FIELD_NONE;
+    pix->colorspace            = V4L2_COLORSPACE_JPEG;
+
+    return 0;
+}
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+       const struct v4l2_queryctrl *qctrl;
+       struct soc_camera_device *icd = client->dev.platform_data;
+    struct reginfo *winseqe_set_addr=NULL;
+       char readval;
+    int ret=0, set_w,set_h;
+    
+u16    AE_reg, AGC_reg;        
+       u8      temp_reg12,temp_reg13;  
+       u16 shutter,reg_1, reg;         
+       
+       //turn on scaler for preivew
+       sensor_read(client ,0x3201, &reg_1);    
+       sensor_write(client, 0x3201, (reg_1|0x40) );    
+       //for preview
+       sensor_read(client ,0x32f1, &reg); 
+       sensor_write(client, 0x32f1, (reg|0x10) ); 
+
+       #if 0  //preview_fastmode
+       // turn off AE  for preview
+       sensor_read(client ,0x3201, &AE_reg);   
+       sensor_write(client, 0x3201, (AE_reg|0x20) );   
+       // turn off AGC   for preview
+       sensor_read(client ,0x32bb, &AGC_reg);  
+       sensor_write(client, 0x32bb, (AGC_reg|0x01) );
+
+       sensor_read(client, 0x3012, &temp_reg12);       
+       sensor_read(client, 0x3013, &temp_reg13);       
+       shutter = (temp_reg13 & 0x00FF) | (temp_reg12 << 8);    
+       #endif
+       if (sensor->info_priv.pixfmt != pix->pixelformat) {
+               switch (pix->pixelformat)
+               {
+                       case V4L2_PIX_FMT_YUYV:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_YUYV;
+                               break;
+                       }
+                       case V4L2_PIX_FMT_UYVY:
+                       {
+                               winseqe_set_addr = sensor_ClrFmt_UYVY;
+                               break;
+                       }
+                       default:
+                               break;
+               }
+               if (winseqe_set_addr != NULL) {
+            sensor_write_array(client, winseqe_set_addr);
+                       sensor->info_priv.pixfmt = pix->pixelformat;
+
+                       SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+               } else {
+                       SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat);
+               }
+       }
+
+    set_w = pix->width;
+    set_h = pix->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+               winseqe_set_addr = sensor_qcif;
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        winseqe_set_addr = sensor_qvga;
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        winseqe_set_addr = sensor_cif;
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        winseqe_set_addr = sensor_vga;
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)
+    {
+        winseqe_set_addr = sensor_svga;
+        set_w = 800;
+        set_h = 600;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
+    {
+        winseqe_set_addr = sensor_sxga;
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)
+    {
+        winseqe_set_addr = sensor_uxga;
+        set_w = 1600;
+        set_h = 1200;
+    }
+    else
+    {
+        winseqe_set_addr = SENSOR_INIT_WINSEQADR;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;
+               ret = -1;
+               SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);
+    }
+
+    if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr) {
+        #if CONFIG_SENSOR_Flash
+        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_On);
+                SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
+            }           
+        } else {                                        /* ddl@rock-chips.com : Video */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());
+            }
+        }
+        #endif
+        ret |= sensor_write_array(client, winseqe_set_addr);
+        if (ret != 0) {
+            SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
+            #if CONFIG_SENSOR_Flash
+            if (sensor_fmt_capturechk(sd,f) == true) {
+                if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                    sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                    SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
+                }
+            }
+            #endif
+            goto sensor_s_fmt_end;
+        }
+
+        sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
+
+       if ((set_w <= 640) && (set_h <= 480))    
+               {               
+               shutter = shutter;    
+               }    
+       else
+               {
+                       //for capture
+                       sensor_read(client ,0x32f1, &reg); 
+                       sensor_write(client, 0x32f1, (reg&(~0x10)) );   
+                        if ((set_w <= 1600) && (set_h <= 1200))    
+                       {               
+                               //turn off scaler for UXGA capture
+                       sensor_read(client ,0x3201, &reg_1);    
+                       sensor_write(client, 0x3201, (reg_1&(~0x40)) ); 
+                       }       
+               #if 0  //preview_fastmode
+                       // turn off AE  
+                       sensor_read(client ,0x3201, &AE_reg);   
+                       sensor_write(client, 0x3201, (AE_reg&(~0x20)) );        
+                       // turn off AGC 
+                       sensor_read(client ,0x32bb, &AGC_reg);  
+                       sensor_write(client, 0x32bb, (AGC_reg&(~0x01)) );
+                if ((set_w <= 800) && (set_h <= 600))    
+                       {               
+                       shutter = shutter*1984/2434;    
+                       }    
+               else if ((set_w <= 2434) && (set_h <= 1024))    
+                       {               
+                       shutter = shutter*1984/2434;    
+                       }    
+               else if ((set_w <= 1600) && (set_h <= 1200))    
+                       {               
+                       shutter = shutter*1984/2434;    
+                       }               
+               if (shutter < 1)        
+                       {               
+                       shutter = 1;    
+                       }       
+               sensor_write(client, 0x3012, sizeof((shutter >> 8) & 0xff) );   
+               sensor_write(client, 0x3013, sizeof(shutter & 0xFF) );
+               #endif
+               }
+               mdelay(250);
+
+        SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
+    }
+    else
+    {
+        SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
+    }
+
+       pix->width = set_w;
+    pix->height = set_h;
+
+sensor_s_fmt_end:
+    return ret;
+}
+
+static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    struct v4l2_pix_format *pix = &f->fmt.pix;
+    bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY ||
+        pix->pixelformat == V4L2_PIX_FMT_YUYV;
+
+    /*
+    * With Bayer format enforce even side lengths, but let the user play
+    * with the starting pixel
+    */
+
+    if (pix->height > SENSOR_MAX_HEIGHT)
+        pix->height = SENSOR_MAX_HEIGHT;
+    else if (pix->height < SENSOR_MIN_HEIGHT)
+        pix->height = SENSOR_MIN_HEIGHT;
+    else if (bayer)
+        pix->height = ALIGN(pix->height, 2);
+
+    if (pix->width > SENSOR_MAX_WIDTH)
+        pix->width = SENSOR_MAX_WIDTH;
+    else if (pix->width < SENSOR_MIN_WIDTH)
+        pix->width = SENSOR_MIN_WIDTH;
+    else if (bayer)
+        pix->width = ALIGN(pix->width, 2);
+/*not support 720p video*/     
+       if(pix->height == 720 && pix->width == 1280){
+               pix->height = 480;
+               pix->width = 640;
+       }
+    return 0;
+}
+
+ static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
+{
+    struct i2c_client *client = sd->priv;
+
+    if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
+        return -EINVAL;
+
+    if (id->match.addr != client->addr)
+        return -ENODEV;
+
+    id->ident = SENSOR_V4L2_IDENT;      /* ddl@rock-chips.com :  Return OV2655  identifier */
+    id->revision = 0;
+
+    return 0;
+}
+#if CONFIG_SENSOR_Brightness
+static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Effect
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_EffectSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Exposure
+static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Saturation
+static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Contrast
+static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Mirror
+static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Flip
+static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_FlipSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Scene
+static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_SceneSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+    {
+        if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL)
+        {
+            if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0)
+            {
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+                return -EINVAL;
+            }
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+            return 0;
+        }
+    }
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl_info;
+    int digitalzoom_cur, digitalzoom_total;
+
+       qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);
+       if (qctrl_info)
+               return -EINVAL;
+
+    digitalzoom_cur = sensor->info_priv.digitalzoom;
+    digitalzoom_total = qctrl_info->maximum;
+
+    if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total))
+    {
+        SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
+        return -EINVAL;
+    }
+
+    if  ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum))
+    {
+        SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);
+        return -EINVAL;
+    }
+
+    if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total))
+    {
+        *value = digitalzoom_total - digitalzoom_cur;
+    }
+
+    if ((*value < 0) && ((digitalzoom_cur + *value) < 0))
+    {
+        *value = 0 - digitalzoom_cur;
+    }
+
+    digitalzoom_cur += *value;
+
+    if (sensor_ZoomSeqe[digitalzoom_cur] != NULL)
+    {
+        if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0)
+        {
+            SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);
+            return -EINVAL;
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value);
+        return 0;
+    }
+
+    return -EINVAL;
+}
+#endif
+#if CONFIG_SENSOR_Flash
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{    
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {
+        if (value == 3) {       /* ddl@rock-chips.com: torch */
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Torch);   /* Flash On */
+        } else {
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+        return 0;
+    }
+    
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    const struct v4l2_queryctrl *qctrl;
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ctrl->id)
+    {
+        case V4L2_CID_BRIGHTNESS:
+            {
+                ctrl->value = sensor->info_priv.brightness;
+                break;
+            }
+        case V4L2_CID_SATURATION:
+            {
+                ctrl->value = sensor->info_priv.saturation;
+                break;
+            }
+        case V4L2_CID_CONTRAST:
+            {
+                ctrl->value = sensor->info_priv.contrast;
+                break;
+            }
+        case V4L2_CID_DO_WHITE_BALANCE:
+            {
+                ctrl->value = sensor->info_priv.whiteBalance;
+                break;
+            }
+        case V4L2_CID_EXPOSURE:
+            {
+                ctrl->value = sensor->info_priv.exposure;
+                break;
+            }
+        case V4L2_CID_HFLIP:
+            {
+                ctrl->value = sensor->info_priv.mirror;
+                break;
+            }
+        case V4L2_CID_VFLIP:
+            {
+                ctrl->value = sensor->info_priv.flip;
+                break;
+            }
+        default :
+                break;
+    }
+    return 0;
+}
+
+
+
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    struct soc_camera_device *icd = client->dev.platform_data;
+    const struct v4l2_queryctrl *qctrl;
+
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ctrl->id)
+    {
+#if CONFIG_SENSOR_Brightness
+        case V4L2_CID_BRIGHTNESS:
+            {
+                if (ctrl->value != sensor->info_priv.brightness)
+                {
+                    if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.brightness = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Exposure
+        case V4L2_CID_EXPOSURE:
+            {
+                if (ctrl->value != sensor->info_priv.exposure)
+                {
+                    if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.exposure = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Saturation
+        case V4L2_CID_SATURATION:
+            {
+                if (ctrl->value != sensor->info_priv.saturation)
+                {
+                    if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.saturation = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Contrast
+        case V4L2_CID_CONTRAST:
+            {
+                if (ctrl->value != sensor->info_priv.contrast)
+                {
+                    if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.contrast = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+        case V4L2_CID_DO_WHITE_BALANCE:
+            {
+                if (ctrl->value != sensor->info_priv.whiteBalance)
+                {
+                    if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0)
+                    {
+                        return -EINVAL;
+                    }
+                    sensor->info_priv.whiteBalance = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Mirror
+        case V4L2_CID_HFLIP:
+            {
+                if (ctrl->value != sensor->info_priv.mirror)
+                {
+                    if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.mirror = ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Flip
+        case V4L2_CID_VFLIP:
+            {
+                if (ctrl->value != sensor->info_priv.flip)
+                {
+                    if (sensor_set_flip(icd, qctrl,ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.flip = ctrl->value;
+                }
+                break;
+            }
+#endif
+        default:
+            break;
+    }
+
+    return 0;
+}
+static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl)
+{
+    const struct v4l2_queryctrl *qctrl;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        return -EINVAL;
+    }
+
+    switch (ext_ctrl->id)
+    {
+        case V4L2_CID_SCENE:
+            {
+                ext_ctrl->value = sensor->info_priv.scene;
+                break;
+            }
+        case V4L2_CID_EFFECT:
+            {
+                ext_ctrl->value = sensor->info_priv.effect;
+                break;
+            }
+        case V4L2_CID_ZOOM_ABSOLUTE:
+            {
+                ext_ctrl->value = sensor->info_priv.digitalzoom;
+                break;
+            }
+        case V4L2_CID_ZOOM_RELATIVE:
+            {
+                return -EINVAL;
+            }
+        case V4L2_CID_FOCUS_ABSOLUTE:
+            {
+                ext_ctrl->value = sensor->info_priv.focus;
+                break;
+            }
+        case V4L2_CID_FOCUS_RELATIVE:
+            {
+                return -EINVAL;
+            }
+        case V4L2_CID_FLASH:
+            {
+                ext_ctrl->value = sensor->info_priv.flash;
+                break;
+            }
+        default :
+            break;
+    }
+    return 0;
+}
+static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl)
+{
+    const struct v4l2_queryctrl *qctrl;
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+    int val_offset;
+
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
+
+    if (!qctrl)
+    {
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        return -EINVAL;
+    }
+
+       val_offset = 0;
+    switch (ext_ctrl->id)
+    {
+#if CONFIG_SENSOR_Scene
+        case V4L2_CID_SCENE:
+            {
+                if (ext_ctrl->value != sensor->info_priv.scene)
+                {
+                    if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.scene = ext_ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Effect
+        case V4L2_CID_EFFECT:
+            {
+                if (ext_ctrl->value != sensor->info_priv.effect)
+                {
+                    if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.effect= ext_ctrl->value;
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+        case V4L2_CID_ZOOM_ABSOLUTE:
+            {
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
+
+                if (ext_ctrl->value != sensor->info_priv.digitalzoom)
+                {
+                    val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom;
+
+                    if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.digitalzoom += val_offset;
+
+                    SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(),  sensor->info_priv.digitalzoom);
+                }
+
+                break;
+            }
+        case V4L2_CID_ZOOM_RELATIVE:
+            {
+                if (ext_ctrl->value)
+                {
+                    if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0)
+                        return -EINVAL;
+                    sensor->info_priv.digitalzoom += ext_ctrl->value;
+
+                    SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom);
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Focus
+        case V4L2_CID_FOCUS_ABSOLUTE:
+            {
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
+
+                if (ext_ctrl->value != sensor->info_priv.focus)
+                {
+                    val_offset = ext_ctrl->value -sensor->info_priv.focus;
+
+                    sensor->info_priv.focus += val_offset;
+                }
+
+                break;
+            }
+        case V4L2_CID_FOCUS_RELATIVE:
+            {
+                if (ext_ctrl->value)
+                {
+                    sensor->info_priv.focus += ext_ctrl->value;
+
+                    SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus);
+                }
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Flash
+        case V4L2_CID_FLASH:
+            {
+                if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)
+                    return -EINVAL;
+                sensor->info_priv.flash = ext_ctrl->value;
+
+                SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);
+                break;
+            }
+#endif
+        default:
+            break;
+    }
+
+    return 0;
+}
+
+static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    int i, error_cnt=0, error_idx=-1;
+
+
+    for (i=0; i<ext_ctrl->count; i++) {
+        if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+            error_cnt++;
+            error_idx = i;
+        }
+    }
+
+    if (error_cnt > 1)
+        error_idx = ext_ctrl->count;
+
+    if (error_idx != -1) {
+        ext_ctrl->error_idx = error_idx;
+        return -EINVAL;
+    } else {
+        return 0;
+    }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+    struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    int i, error_cnt=0, error_idx=-1;
+
+
+    for (i=0; i<ext_ctrl->count; i++) {
+        if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+            error_cnt++;
+            error_idx = i;
+        }
+    }
+
+    if (error_cnt > 1)
+        error_idx = ext_ctrl->count;
+
+    if (error_idx != -1) {
+        ext_ctrl->error_idx = error_idx;
+        return -EINVAL;
+    } else {
+        return 0;
+    }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+                              struct i2c_client *client)
+{
+    char value;
+    int ret,pid = 0;
+    struct sensor *sensor = to_sensor(client);
+
+    /* We must have a parent by now. And it cannot be a wrong one.
+     * So this entire test is completely redundant. */
+    if (!icd->dev.parent ||
+           to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+               return -ENODEV;
+
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
+
+    /* soft reset */
+    ret = sensor_write(client, 0x3021, 0x61);
+    if (ret != 0)
+    {
+        SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
+        return -ENODEV;
+    }
+    mdelay(5);          //delay 5 microseconds
+
+    /* check if it is an sensor sensor */
+    ret = sensor_read(client, 0x307e, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id high byte failed\n");
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+    pid |= (value << 8);
+
+    ret = sensor_read(client, 0x307f, &value);
+    if (ret != 0) {
+        SENSOR_TR("read chip id low byte failed\n");
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+    pid |= (value & 0xff);
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+    if (pid == SENSOR_ID) {
+        sensor->model = SENSOR_V4L2_IDENT;
+    } else {
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+        ret = -ENODEV;
+        goto sensor_video_probe_err;
+    }
+
+    icd->formats = sensor_colour_formats;
+    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);
+
+    return 0;
+
+sensor_video_probe_err:
+
+    return ret;
+}
+static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+       struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    int ret = 0;
+#if CONFIG_SENSOR_Flash        
+    int i;
+#endif
+    
+       SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+       switch (cmd)
+       {
+               case RK29_CAM_SUBDEV_DEACTIVATE:
+               {
+                       sensor_deactivate(client);
+                       break;
+               }
+
+               case RK29_CAM_SUBDEV_IOREQUEST:
+               {
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
+            /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
+               for this project */
+            #if CONFIG_SENSOR_Flash    
+               if (sensor->sensor_gpio_res) {
+                if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {
+                    for (i = 0; i < icd->ops->num_controls; i++) {
+                               if (V4L2_CID_FLASH == icd->ops->controls[i].id) {
+                                       memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                       
+                               }
+                    }
+                    sensor->info_priv.flash = 0xff;
+                    SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());
+                }
+               }
+            #endif
+                       break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_ioctl_end:
+       return ret;
+
+}
+static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
+       .init           = sensor_init,
+       .g_ctrl         = sensor_g_control,
+       .s_ctrl         = sensor_s_control,
+       .g_ext_ctrls          = sensor_g_ext_controls,
+       .s_ext_ctrls          = sensor_s_ext_controls,
+       .g_chip_ident   = sensor_g_chip_ident,
+       .ioctl = sensor_ioctl,
+};
+
+static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {
+       .s_fmt          = sensor_s_fmt,
+       .g_fmt          = sensor_g_fmt,
+       .try_fmt        = sensor_try_fmt,
+};
+
+static struct v4l2_subdev_ops sensor_subdev_ops = {
+       .core   = &sensor_subdev_core_ops,
+       .video = &sensor_subdev_video_ops,
+};
+
+static int sensor_probe(struct i2c_client *client,
+                        const struct i2c_device_id *did)
+{
+    struct sensor *sensor;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+    struct soc_camera_link *icl;
+    int ret;
+
+    SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__);
+    if (!icd) {
+        dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+    icl = to_soc_camera_link(icd);
+    if (!icl) {
+        dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING());
+        return -EINVAL;
+    }
+
+    if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+        dev_warn(&adapter->dev,
+                "I2C-Adapter doesn't support I2C_FUNC_I2C\n");
+        return -EIO;
+    }
+
+    sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL);
+    if (!sensor)
+        return -ENOMEM;
+
+    v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops);
+
+    /* Second stage probe - when a capture adapter is there */
+    icd->ops           = &sensor_ops;
+    icd->y_skip_top            = 0;
+       #if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_set(&sensor->tasklock_cnt,0);
+       #endif
+
+    ret = sensor_video_probe(icd, client);
+    if (ret < 0) {
+        icd->ops = NULL;
+        i2c_set_clientdata(client, NULL);
+        kfree(sensor);
+               sensor = NULL;
+    }
+    SENSOR_DG("\n%s..%s..%d  ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);
+    return ret;
+}
+
+static int sensor_remove(struct i2c_client *client)
+{
+    struct sensor *sensor = to_sensor(client);
+    struct soc_camera_device *icd = client->dev.platform_data;
+
+    icd->ops = NULL;
+    i2c_set_clientdata(client, NULL);
+    client->driver = NULL;
+    kfree(sensor);
+       sensor = NULL;
+    return 0;
+}
+
+static const struct i2c_device_id sensor_id[] = {
+       {SENSOR_NAME_STRING(), 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, sensor_id);
+
+static struct i2c_driver sensor_i2c_driver = {
+       .driver = {
+               .name = SENSOR_NAME_STRING(),
+       },
+       .probe          = sensor_probe,
+       .remove         = sensor_remove,
+       .id_table       = sensor_id,
+};
+
+static int __init sensor_mod_init(void)
+{
+    SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING());
+    return i2c_add_driver(&sensor_i2c_driver);
+}
+
+static void __exit sensor_mod_exit(void)
+{
+    i2c_del_driver(&sensor_i2c_driver);
+}
+
+device_initcall_sync(sensor_mod_init);
+module_exit(sensor_mod_exit);
+
+MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));
+MODULE_AUTHOR("ddl <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
index 8fca3208ea51eba5f0249ce682d1117178718376..51f16390be054fba53c68a5f0b44678d8f092233 100755 (executable)
@@ -16,11 +16,21 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <linux/delay.h>
 #include <linux/circ_buf.h>
 #include <linux/miscdevice.h>
-
-
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
+#include <mach/rk29_camera.h>
+#include "ov3640.h"
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do {                       \
+       if (debug >= level)                                     \
+       printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
 
 #define _CONS(a,b) a##b
 #define CONS(a,b) _CONS(a,b)
@@ -29,8 +39,11 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #define _STR(x) __STR(x)
 #define STR(x) _STR(x)
 
+#define MIN(x,y)   ((x<y) ? x: y)
+#define MAX(x,y)    ((x>y) ? x: y)
+
 /* Sensor Driver Configuration */
-#define SENSOR_NAME ov3640
+#define SENSOR_NAME RK29_CAM_SENSOR_OV3640
 #define SENSOR_V4L2_IDENT V4L2_IDENT_OV3640
 #define SENSOR_ID 0x364c
 #define SENSOR_MIN_WIDTH    176
@@ -49,33 +62,23 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #define CONFIG_SENSOR_Effect        1
 #define CONFIG_SENSOR_Scene         1
 #define CONFIG_SENSOR_DigitalZoom   0
-#define CONFIG_SENSOR_Focus         0
 #define CONFIG_SENSOR_Exposure      0
-#define CONFIG_SENSOR_Flash         0
+#define CONFIG_SENSOR_Flash         1
 #define CONFIG_SENSOR_Mirror        0
 #define CONFIG_SENSOR_Flip          0
-#define CONFIG_SENSOR_I2C_SPEED     200000       /* Hz */
-
-#define CONFIG_SENSOR_TR      1
-#define CONFIG_SENSOR_DEBUG      1
-
-#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
-#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
-
-#define MIN(x,y)   ((x<y) ? x: y)
-#define MAX(x,y)    ((x>y) ? x: y)
-
-#if (CONFIG_SENSOR_TR)
-       #define SENSOR_TR(format, ...)      printk(format, ## __VA_ARGS__)
-       #if (CONFIG_SENSOR_DEBUG)
-       #define SENSOR_DG(format, ...)      printk(format, ## __VA_ARGS__)
-       #else
-       #define SENSOR_DG(format, ...)
-       #endif
+#ifdef CONFIG_OV3640_AUTOFOCUS
+#define CONFIG_SENSOR_Focus         1
+#include "ov3640_af_firmware.c"
 #else
-       #define SENSOR_TR(format, ...)
+#define CONFIG_SENSOR_Focus         0
 #endif
 
+#define CONFIG_SENSOR_I2C_SPEED     100000       /* Hz */
+/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */
+#define CONFIG_SENSOR_I2C_NOSCHED   0
+#define CONFIG_SENSOR_I2C_RDWRCHK   0
+
+
 #define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
                           SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
                           SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
@@ -89,15 +92,105 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #define COLOR_TEMPERATURE_HOME_DN       2500
 #define COLOR_TEMPERATURE_HOME_UP       3500
 
-struct reginfo
-{
-    u16 reg;
-    u8 val;
-};
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
+
+#define SENSOR_AF_IS_ERR    (0x00<<0)
+#define SENSOR_AF_IS_OK                (0x01<<0)
+
+#if CONFIG_SENSOR_Focus
+#define SENSOR_AF_MODE_INFINITY    0
+#define SENSOR_AF_MODE_MACRO       1
+#define SENSOR_AF_MODE_FIXED       2
+#define SENSOR_AF_MODE_AUTO        3
+#define SENSOR_AF_MODE_CONTINUOUS  4
+#define SENSOR_AF_MODE_CLOSE       5
+
+#endif
+
+#define VCM_FIRMWARE                           1
+
+#define VCM_STARTADDR                          0x8000
+
+#define S_IDLE                                         0x00
+#if (VCM_FIRMWARE==1)
+#define S_FOCUSING                                     0x01
+#define S_FOCUSED                                      0x02
+#define S_CAPTURE                                      0x12
+#define STA_FOCUS                                      0x3f07
+#elif (VCM_FIRMWARE==2)
+#define S_FOCUSING                                     0x01
+#define S_FOCUSED                                      0x02
+#define S_CAPTURE                                      0x12
+#define STA_FOCUS                                      0x3f01
+#else
+#define S_FOCUSING                                     0x65
+#define S_FOCUSED                                      0x46
+#define S_CAPTURE                                      0x47
+#define STA_FOCUS                                      0x3f01
+#endif
+
+
+#if CONFIG_SENSOR_Focus
+/* ov3640 VCM Command and Status Registers */
+#define CMD_MAIN_Reg      0x3F00
+#define CMD_TAG_Reg       0x3F01
+#define CMD_PARA0_Reg     0x3F05
+#define CMD_PARA1_Reg     0x3F04
+#define CMD_PARA2_Reg     0x3F03
+#define CMD_PARA3_Reg     0x3F02
+#define STA_ZONE_Reg      0x3F06
+#define STA_FOCUS_Reg     0x3F07
+
+/* ov3640 VCM Command  */
+#define OverlayEn_Cmd     0x01
+#define OverlayDis_Cmd    0x02
+#define SingleFocus_Cmd   0x03
+#define ConstFocus_Cmd    0x04
+#define StepMode_Cmd      0x05
+#define PauseFocus_Cmd    0x06
+#define ReturnIdle_Cmd    0x08
+#define SetZone_Cmd       0x10
+#define UpdateZone_Cmd    0x12
+#define SetMotor_Cmd      0x20
+
+/* ov3640 Focus State */
+#define S_FIRWRE          0xFF
+#define S_STARTUP         0xFA
+#define S_ERROR           0xFE
+#define S_DRVICERR        0xEE
+#define S_IDLE            0x00
+#define S_FOCUSING        0x01
+#define S_FOCUSED         0x02
+#define S_CAPTURE         0x12
+#define S_STEP            0x20
+
+/* ovxxxx Zone State */
+#define Zone_Is_Focused(a, zone_val)    (zone_val&(1<<(a-3)))
+#define Zone_Get_ID(zone_val)           (zone_val&0x03)
+
+#define Zone_CenterMode   0x01
+#define Zone_5xMode       0x02
+#define Zone_5PlusMode    0x03
+#define Zone_4fMode       0x04
+
+#define ZoneSel_Auto      0x0b
+#define ZoneSel_SemiAuto  0x0c
+#define ZoneSel_Manual    0x0d
+#define ZoneSel_Rotate    0x0e
+
+/* ovxxxx Step Focus Commands */
+#define StepFocus_Near_Tag       0x01
+#define StepFocus_Far_Tag        0x02
+#define StepFocus_Furthest_Tag   0x03
+#define StepFocus_Nearest_Tag    0x04
+#define StepFocus_Spec_Tag       0x10
+#endif
 
 /* init VGA 640*480 */
 static struct reginfo sensor_init_data[] =
 {
+#if 1
        {0x3078, 0x02},
        {0x304d, 0x45},
        {0x30a7, 0x5e},
@@ -107,7 +200,8 @@ static struct reginfo sensor_init_data[] =
        {0x30aa, 0x42},
        {0x30b0, 0xff},
        {0x30b1, 0xff},
-       {0x30b2, 0x10},
+       //{0x30b2, 0x10},
+       {0x30b2, 0x18}, // by FAE
        {0x300e, 0x39},
        {0x300f, 0x21},
        {0x3010, 0x20},
@@ -119,6 +213,9 @@ static struct reginfo sensor_init_data[] =
        {0x3018, 0x48},
        {0x3019, 0x40},
        {0x301a, 0x82},
+
+       {0x30a9, 0xbd},//disable internal DVDD, by FAE.
+       
        {0x307d, 0x00},
        {0x3087, 0x02},
        {0x3082, 0x20},
@@ -247,13 +344,63 @@ static struct reginfo sensor_init_data[] =
        {0x332e, 0x04},
        {0x332f, 0x06},
        {0x3331, 0x03},
-
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // flip && mirror ,by FAE.
+  {0x3090, 0xc8},
+#else
+//640 480 ;XGA-&gt;XGA;;
+     {0x3012, 0x10},
+     {0x3023, 0x06},
+     {0x3026, 0x03},
+     {0x3027, 0x04},
+     {0x302a, 0x03},
+     {0x302b, 0x10},
+     {0x3075, 0x24},
+     {0x300d, 0x01},
+     {0x30d7, 0x90},
+     {0x3069, 0x04},
+     {0x303e, 0x00},
+     {0x303f, 0xc0},
+     {0x3302, 0xef},
+     {0x335f, 0x34},
+     {0x3360, 0x0c},
+     {0x3361, 0x04},
+     {0x3362, 0x34},
+     {0x3363, 0x08},
+     {0x3364, 0x04},
+     {0x3403, 0x42},
+     {0x3088, 0x04},
+     {0x3089, 0x00},
+     {0x308a, 0x03},
+     {0x308b, 0x00},
+     {0x300e, 0x32},
+     {0x300f, 0x21},
+     {0x3010, 0x20},
+     {0x3011, 0x01},
+     {0x304c, 0x82},
+
+//;XGA-&gt;VGA
+     {0x3302, 0xef},
+     {0x335f, 0x34},
+     {0x3360, 0x0c},
+     {0x3361, 0x04},
+     {0x3362, 0x12},
+     {0x3363, 0x88},
+     {0x3364, 0xe4},
+     {0x3403, 0x42},
+     {0x3088, 0x12},
+     {0x3089, 0x80},
+     {0x308a, 0x01},
+     {0x308b, 0xe0},
+     {0x304c, 0x85},
+#endif
        {0x0000 ,0x00},
 };
 
 /* 2048X1536 QXGA */
 static struct reginfo sensor_qxga_preview[] =
 {
+#if 1
        {0x3012, 0x00},
        {0x3366, 0x10},
        {0x3020, 0x01},
@@ -291,7 +438,47 @@ static struct reginfo sensor_qxga_preview[] =
        {0x3010, 0x20},
        {0x3011, 0x01},
        {0x304c, 0x81},
-               
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // flip && mirror, by FAE.
+  {0x3090, 0xc8},
+
+#else
+//[Sensor.YUV.2048x1536] XGA-&gt;QXGA
+  {0x3012, 0x00},
+  {0x3020, 0x01},
+  {0x3021, 0x1d},
+  {0x3022, 0x00},
+  {0x3023, 0x0a},
+  {0x3024, 0x08},
+  {0x3025, 0x18},
+  {0x3026, 0x06},
+  {0x3027, 0x0c},
+  {0x302a, 0x06},
+  {0x302b, 0x20},
+  {0x3075, 0x44},
+  {0x300d, 0x00},
+  {0x30d7, 0x10},
+  {0x3069, 0x44},
+  {0x303e, 0x01},
+  {0x303f, 0x80},
+  {0x3302, 0xcf},
+  {0x335f, 0x68},
+  {0x3360, 0x18},
+  {0x3361, 0x0c},
+  {0x3362, 0x68},
+  {0x3363, 0x08},
+  {0x3364, 0x04},
+  {0x3403, 0x42},
+  {0x3088, 0x08},
+  {0x3089, 0x00},
+  {0x308a, 0x06},
+  {0x308b, 0x00},
+  {0x300e, 0x39},
+  {0x300f, 0x21},
+  {0x3010, 0x20},
+  {0x3011, 0x01},
+  {0x304c, 0x81},
+#endif         
        {0x0000 ,0x00}
 };
 static struct reginfo sensor_qxga_capture[] = {
@@ -308,6 +495,7 @@ static struct reginfo sensor_qxga_capture[] = {
        {0x302a, 0x06},
        {0x302b, 0x20},
        {0x3075, 0x44},
+       //{0x307C, 0x13}, // by FAE.
        {0x300d, 0x00},
        {0x30d7, 0x10},
        {0x3069, 0x44},
@@ -332,6 +520,10 @@ static struct reginfo sensor_qxga_capture[] = {
        {0x3010, 0x20},
        {0x3011, 0x01},
        {0x304c, 0x81},
+       
+       //{0x307c, 0x13},// flip && mirror 
+       {0x307c, 0x11},// flip && mirror , by FAE.
+  {0x3090, 0xc8},
                
        {0x0000 ,0x00}
 };
@@ -378,6 +570,9 @@ static struct reginfo sensor_uxga_preview[] =
        {0x308a, 0x04},
        {0x308b, 0xb0},
        {0x304c, 0x81},//56Mhz PCLK output
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // flip && mirror, by FAE.
+  {0x3090, 0xc8},
        
        {0x0000 ,0x00},
 };
@@ -396,6 +591,9 @@ static struct reginfo sensor_uxga_capture[] =
        {0x308a, 0x04},
        {0x308b, 0xb0},
        {0x304c, 0x81},//56Mhz PCLK output
+       //{0x307c, 0x13}, // flip && mirror, by FAE.
+       {0x307c, 0x11},
+  {0x3090, 0xc8},
 
        {0x0000 ,0x00},
 };
@@ -442,6 +640,9 @@ static struct reginfo sensor_sxga_preview[] =
        {0x308a, 0x03},
        {0x308b, 0xc0},
        {0x304c, 0x81},//56Mhz PCLK output
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // by FAE.
+  {0x3090, 0xc8},
        
        {0x0000 ,0x00},
 };
@@ -460,7 +661,9 @@ static struct reginfo sensor_sxga_capture[] =
        {0x308a, 0x03},
        {0x308b, 0xc0},
        {0x304c, 0x81},//56Mhz PCLK output
-       
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // by FAE.
+  {0x3090, 0xc8},
        {0x0000 ,0x00},
 };
 static struct reginfo *sensor_sxga[2] = {
@@ -502,6 +705,9 @@ static struct reginfo sensor_xga_preview[] =
        {0x308a, 0x03},
        {0x308b, 0x00},
        {0x304c, 0x82},//28Mhz PCLK output
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11},// by FAE.
+  {0x3090, 0xc8},
 
        {0x0000 ,0x00},
 };
@@ -520,6 +726,9 @@ static struct reginfo sensor_xga_capture[] =
        {0x308a, 0x03},
        {0x308b, 0x00},
        {0x304c, 0x82},//28Mhz PCLK output
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // by FAE.
+  {0x3090, 0xc8},
 
        {0x0000 ,0x00},
 };
@@ -563,6 +772,9 @@ static struct reginfo sensor_svga_preview[] =
        {0x308b, 0x58},
        {0x304c, 0x83},//28Mhz PCLK output
 
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // flip && mirror, by FAE.
+  {0x3090, 0xc8},
        {0x0000 ,0x00},
 };
 static struct reginfo sensor_svga_capture[] =
@@ -581,6 +793,9 @@ static struct reginfo sensor_svga_capture[] =
        {0x308b, 0x58},
        {0x304c, 0x82},//28Mhz PCLK output
 
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // flip && mirror, by FAE.
+  {0x3090, 0xc8},
        {0x0000 ,0x00},
 };
 static struct reginfo * sensor_svga[2] = {
@@ -618,13 +833,29 @@ static struct reginfo sensor_vga_preview[] =
        {0x3364, 0xe4},
        {0x3403, 0x42},
        {0x3088, 0x02},
-       {0x3089, 0x80},
+       {0x3089, 0x88},// 0x80, by FAE.
        {0x308a, 0x01},
-       {0x308b, 0xe0},
-       {0x304c, 0x83}, //85
+       {0x308b, 0xe4},// 0xe0, by FAE.
+       {0x304c, 0x84}, //0x83, by FAE.
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // flip && mirror, by FAE.
+       {0x3090, 0xc8},
+// by FAE.
+//AWB short
+      // {0x33a7, 0x60},
+       //{0x33a8, 0x40},
+       //{0x33a9, 0x68},
+       //{0x332b, 0x08},
+       //{0x330a, 0x22},
+       
+       //{0x332b, 0x00},
+       //{0x330a, 0x02},
+//end
+       
 
        {0x0000 ,0x00},
 };
+
 static struct reginfo sensor_vga_capture[] =
 {
        {0x3302, 0xef},
@@ -640,6 +871,9 @@ static struct reginfo sensor_vga_capture[] =
        {0x308a, 0x01},
        {0x308b, 0xe0},
        {0x304c, 0x82},//14Mhz PCLK output 84
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11},// by FAE.
+  {0x3090, 0xc8},
 
        {0x0000 ,0x00},
 };
@@ -669,6 +903,7 @@ static struct reginfo sensor_cif_preview[] =
        {0x3010, 0x20},
        {0x3011, 0x01},
        //XGA->CIF(352*288)
+#if 0  // by FAE.
        {0x3302, 0xef},
        {0x335f, 0x34},
        {0x3360, 0x0c},
@@ -682,6 +917,24 @@ static struct reginfo sensor_cif_preview[] =
        {0x308a, 0x01},
        {0x308b, 0x20},
        {0x304c, 0x82}, //89
+#else  
+       {0x3302, 0xef},
+       {0x335f, 0x34},
+       {0x3360, 0x0c},
+       {0x3361, 0x04},
+       {0x3362, 0x11},
+       {0x3363, 0x68}, //?
+       {0x3364, 0x24},//?
+       {0x3403, 0x42},
+       {0x3088, 0x01},
+       {0x3089, 0x68},
+       {0x308a, 0x01},
+       {0x308b, 0x24},
+       {0x304c, 0x85}, //89    
+#endif 
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // flip && mirror, by FAE.
+  {0x3090, 0xc8},
 
        {0x0000 ,0x00},
 };
@@ -700,6 +953,9 @@ static struct reginfo sensor_cif_capture[] =
        {0x308a, 0x01},
        {0x308b, 0x20},
        {0x304c, 0x84},//14Mhz PCLK output
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11},//by FAE.
+  {0x3090, 0xc8},
 
        {0x0000 ,0x00},
 };
@@ -742,6 +998,9 @@ static struct reginfo sensor_qvga_preview[] =
        {0x308a, 0x00},
        {0x308b, 0xf0},
        {0x304c, 0x89},//14Mhz PCLK output 
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // by FAE.
+  {0x3090, 0xc8},
 
        {0x0000 ,0x00},
 };
@@ -761,6 +1020,9 @@ static struct reginfo sensor_qvga_capture[] =
        {0x308b, 0xf0},
        {0x304c, 0x84},//14Mhz PCLK output
 
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11},// by FAE.
+  {0x3090, 0xc8},
        {0x0000 ,0x00},
 };
 static  struct reginfo *sensor_qvga[2] = {
@@ -802,7 +1064,9 @@ static struct reginfo sensor_qcif_preview[] =
        {0x308a, 0x00},
        {0x308b, 0x90},
        {0x304c, 0x82},//14Mhz PCLK output 89
-
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11},// by FAE.
+  {0x3090, 0xc8},
        {0x0000 ,0x00},
 };
 static struct reginfo sensor_qcif_capture[] =
@@ -821,6 +1085,9 @@ static struct reginfo sensor_qcif_capture[] =
        {0x308b, 0x90},
        {0x304c, 0x84},//14Mhz PCLK output
 
+       //{0x307c, 0x13}, // flip && mirror
+       {0x307c, 0x11}, // by FAE.
+  {0x3090, 0xc8},
        {0x0000 ,0x00},
 };
 static  struct reginfo *sensor_qcif[2] = {
@@ -1636,6 +1903,26 @@ static const struct v4l2_queryctrl sensor_controls[] =
         .step          = 1,
         .default_value = 125,
     },
+    {
+        .id            = V4L2_CID_FOCUS_AUTO,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Focus Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    },
+#if 0 //IF CONTINOUS IS SUPPORT, SET TO 1
+    {
+        .id            = V4L2_CID_FOCUS_CONTINUOUS,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "Focus Control",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    },
+#endif 
     #endif
 
        #if CONFIG_SENSOR_Flash
@@ -1661,7 +1948,9 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);
 static int sensor_resume(struct soc_camera_device *icd);
 static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);
 static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);
-static int sensor_set_flashLed(struct soc_camera_device *icd, int value);
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+static int sensor_deactivate(struct i2c_client *client);
 
 static struct soc_camera_ops sensor_ops =
 {
@@ -1686,6 +1975,19 @@ static const struct soc_camera_data_format sensor_colour_formats[] = {
        JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),
        JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),
 };
+
+enum sensor_work_state
+{
+       sensor_work_ready = 0,
+       sensor_working,
+};
+struct sensor_work
+{
+       struct i2c_client *client;
+       struct delayed_work dwork;
+       enum sensor_work_state state;
+};
+
 typedef struct sensor_info_priv_s
 {
     int whiteBalance;
@@ -1696,12 +1998,18 @@ typedef struct sensor_info_priv_s
     int scene;
     int digitalzoom;
     int focus;
+       int auto_focus;
+       int affm_reinit;
     int flash;
     int exposure;
+       bool snap2preview;
+       bool video2preview;
     unsigned char mirror;                                        /* HFLIP */
     unsigned char flip;                                          /* VFLIP */
     unsigned int winseqe_cur_addr;
        unsigned int pixfmt;
+       unsigned int enable;
+       unsigned int funmodule_state;
 } sensor_info_priv_t;
 
 struct sensor
@@ -1709,7 +2017,15 @@ struct sensor
     struct v4l2_subdev subdev;
     struct i2c_client *client;
     sensor_info_priv_t info_priv;
+       struct workqueue_struct *sensor_wq;
+       struct sensor_work sensor_wk;
+       struct mutex wq_lock;
     int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */
+#if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_t tasklock_cnt;
+#endif
+       struct rk29camera_platform_data *sensor_io_request;
+    struct rk29camera_gpio_res *sensor_gpio_res;
 };
 
 static struct sensor* to_sensor(const struct i2c_client *client)
@@ -1717,6 +2033,44 @@ static struct sensor* to_sensor(const struct i2c_client *client)
     return container_of(i2c_get_clientdata(client), struct sensor, subdev);
 }
 
+static int sensor_task_lock(struct i2c_client *client, int lock)
+{
+#if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
+    struct sensor *sensor = to_sensor(client);
+
+       if (lock) {
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
+                       preempt_disable();
+               }
+
+               atomic_add(1, &sensor->tasklock_cnt);
+       } else {
+               if (atomic_read(&sensor->tasklock_cnt) > 0) {
+                       atomic_sub(1, &sensor->tasklock_cnt);
+
+                       if (atomic_read(&sensor->tasklock_cnt) == 0)
+                               preempt_enable();
+               }
+       }
+       return 0;
+sensor_task_lock_err:
+       return -1;   
+#else
+    return 0;
+#endif
+
+}
+
 /* sensor register write */
 static int sensor_write(struct i2c_client *client, u16 reg, u8 val)
 {
@@ -1738,13 +2092,13 @@ static int sensor_write(struct i2c_client *client, u16 reg, u8 val)
     cnt = 1;
     err = -EAGAIN;
 
-    while ((cnt--) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
         err = i2c_transfer(client->adapter, msg, 1);
 
         if (err >= 0) {
             return 0;
         } else {
-            SENSOR_TR("\n %s write reg failed, try to write again! reg:0x%x val:0x%x ,err=%d\n",SENSOR_NAME_STRING(), reg, val,err);
+            SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);
             udelay(10);
         }
     }
@@ -1778,14 +2132,14 @@ static int sensor_read(struct i2c_client *client, u16 reg, u8 *val)
 
     cnt = 1;
     err = -EAGAIN;
-    while ((cnt--) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
         err = i2c_transfer(client->adapter, msg, 2);
 
         if (err >= 0) {
             *val = buf[0];
             return 0;
         } else {
-               SENSOR_TR("\n %s read reg failed, try to read again! reg:0x%x \n",SENSOR_NAME_STRING(),*val);
+               SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val);
             udelay(10);
         }
     }
@@ -1796,12 +2150,28 @@ static int sensor_read(struct i2c_client *client, u16 reg, u8 *val)
 /* write a array of registers  */
 static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)
 {
-    int err, cnt;
+    int err=0, cnt;
     int i = 0;
+#if CONFIG_SENSOR_Focus
+       struct sensor *sensor = to_sensor(client);
+#endif
+#if CONFIG_SENSOR_I2C_RDWRCHK
+       char valchk;
+#endif
 
        cnt = 0;
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
     while (regarray[i].reg != 0)
     {
+    #if CONFIG_SENSOR_Focus
+       if ((regarray == sensor_af_firmware) && (sensor->info_priv.enable == 0)) {
+                       SENSOR_DG("%s disable, Download af firmware terminated!\n",SENSOR_NAME_STRING());
+                       err = -EINVAL;
+                       goto sensor_write_array_end;
+       }
+               #endif
+               
         err = sensor_write(client, regarray[i].reg, regarray[i].val);
         if (err < 0)
         {
@@ -1811,14 +2181,400 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
                                continue;
             } else {
                 SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING());
-                return -EPERM;
+
+               err = -EPERM;
+               goto sensor_write_array_end;
             }
+        } else {
+        #if CONFIG_SENSOR_I2C_RDWRCHK
+                       sensor_read(client, regarray[i].reg, &valchk);
+                       if (valchk != regarray[i].val)
+                               SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+               #endif
         }
         i++;
     }
+
+               #if CONFIG_SENSOR_Focus
+       if (((regarray->reg == SEQUENCE_PROPERTY) && (regarray->val == SEQUENCE_INIT))
+               || (regarray == sensor_init_data)) {
+               sensor->info_priv.affm_reinit = 1;
+       }
+       #endif
+       
+sensor_write_array_end:
+       sensor_task_lock(client,0);
+    return err;
+}
+#if CONFIG_SENSOR_I2C_RDWRCHK
+static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)
+{
+    int cnt;
+    int i = 0;
+       char valchk;
+
+       cnt = 0;
+       valchk = 0;
+    while (regarray[i].reg != 0)
+    {
+               sensor_read(client, regarray[i].reg, &valchk);
+               if (valchk != regarray[i].val)
+                       SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+
+        i++;
+    }
     return 0;
 }
+#endif
+#if CONFIG_SENSOR_Focus
+struct af_cmdinfo
+{
+       char cmd_tag;
+       char cmd_para[4];
+       char validate_bit;
+};
+static int sensor_af_cmdset(struct i2c_client *client, int cmd_main, struct af_cmdinfo *cmdinfo)
+{
+       int i;
+       char read_tag=0xff,cnt;
+
+       if (cmdinfo) {
+               if (cmdinfo->validate_bit & 0x80) {
+                       if (sensor_write(client, CMD_TAG_Reg, cmdinfo->cmd_tag)) {
+                               SENSOR_TR("%s write CMD_TAG_Reg(main:0x%x tag:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag);
+                               goto sensor_af_cmdset_err;
+                       }
+                       SENSOR_DG("%s write CMD_TAG_Reg(main:0x%x tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag);
+               }
+               for (i=0; i<4; i++) {
+                       if (cmdinfo->validate_bit & (1<<i)) {
+                               if (sensor_write(client, CMD_PARA0_Reg-i, cmdinfo->cmd_para[i])) {
+                                       SENSOR_TR("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]);
+                                       goto sensor_af_cmdset_err;
+                               }
+                               SENSOR_DG("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]);
+                       }
+               }
+       } else {
+               if (sensor_write(client, CMD_TAG_Reg, 0xff)) {
+                       SENSOR_TR("%s write CMD_TAG_Reg(main:0x%x no tag) error!\n",SENSOR_NAME_STRING(),cmd_main);
+                       goto sensor_af_cmdset_err;
+               }
+               SENSOR_DG("%s write CMD_TAG_Reg(main:0x%x no tag) success!\n",SENSOR_NAME_STRING(),cmd_main);
+       }
+
+       if (sensor_write(client, CMD_MAIN_Reg, cmd_main)) {
+               SENSOR_TR("%s write CMD_MAIN_Reg(main:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main);
+               goto sensor_af_cmdset_err;
+       }
+
+       cnt = 0;
+       do
+       {
+               msleep(5);
+               if (sensor_read(client,CMD_TAG_Reg,&read_tag)){
+                  SENSOR_TR("%s[%d] read TAG failed\n",SENSOR_NAME_STRING(),__LINE__);
+                  break;
+               }
+    } while((read_tag != 0x00)&& (cnt++<100));
+
+       SENSOR_DG("%s write CMD_MAIN_Reg(main:0x%x read tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,read_tag);
+       return 0;
+sensor_af_cmdset_err:
+       return -1;
+}
+
+static int sensor_af_idlechk(struct i2c_client *client)
+{
+       int ret = 0;
+       char state,cnt;
+
+       cnt = 0;
+       do
+       {
+               ret = sensor_read(client, STA_FOCUS_Reg, &state);
+               if (ret != 0){
+                  SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__);
+                  ret = -1;
+                  goto sensor_af_idlechk_end;
+               }
+
+               if (state != S_IDLE) {
+                       sensor_af_cmdset(client, ReturnIdle_Cmd, NULL);
+                       msleep(1);
+                       cnt++;
+               }
+    } while((state != S_IDLE)&& (cnt<100));
+
+       ret = (state == S_IDLE) ? 0 : -1;
+
+sensor_af_idlechk_end:
+       return ret;
+}
+
+static int sensor_af_single(struct i2c_client *client)
+{
+       int ret = 0;
+       char state,cnt;
+
+       if (sensor_af_idlechk(client))
+               goto sensor_af_single_end;
+
+       if (sensor_af_cmdset(client, SingleFocus_Cmd, NULL)) {
+               SENSOR_TR("%s single focus mode set error!\n",SENSOR_NAME_STRING());
+               ret = -1;
+               goto sensor_af_single_end;
+       }
+
+       cnt = 0;
+    do
+    {
+       if (cnt != 0) {
+                       msleep(1);
+       }
+       cnt++;
+               ret = sensor_read(client, STA_FOCUS_Reg, &state);
+               if (ret != 0){
+                  SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__);
+                  ret = -1;
+                  goto sensor_af_single_end;
+               }
+    }while((state == S_FOCUSING) && (cnt<100));
+
+       if (state != S_FOCUSED) {
+        SENSOR_TR("%s[%d] focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),__LINE__,state);
+               ret = -1;
+               goto sensor_af_single_end;
+    }
+
+       //sensor_af_cmdset(client, ReturnIdle_Cmd, NULL); // by duanyp. fix af blur when taking pictures
+sensor_af_single_end:
+       return ret;
+}
+
+static int sensor_af_const(struct i2c_client *client)
+{
+       int ret = 0;
+
+       if (sensor_af_idlechk(client))
+               goto sensor_af_const_end;
+
+       if (sensor_af_cmdset(client, ConstFocus_Cmd, NULL)) {
+               SENSOR_TR("%s const focus mode set error!\n",SENSOR_NAME_STRING());
+               ret = -1;
+               goto sensor_af_const_end;
+       }
+sensor_af_const_end:
+       return ret;
+}
+static int sensor_af_pause2capture(struct i2c_client *client)
+{
+       int ret = 0;
+       char state,cnt;
+
+       if (sensor_af_cmdset(client, PauseFocus_Cmd, NULL)) {
+               SENSOR_TR("%s pause focus mode set error!\n",SENSOR_NAME_STRING());
+               ret = -1;
+               goto sensor_af_pause_end;
+       }
+
+       cnt = 0;
+    do
+    {
+       if (cnt != 0) {
+                       msleep(1);
+       }
+       cnt++;
+               ret = sensor_read(client, STA_FOCUS_Reg, &state);
+               if (ret != 0){
+                  SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__);
+                  ret = -1;
+                  goto sensor_af_pause_end;
+               }
+    }while((state != S_CAPTURE) && (cnt<100));
+
+       if (state != S_CAPTURE) {
+        SENSOR_TR("%s[%d] focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),__LINE__,state);
+               ret = -1;
+               goto sensor_af_pause_end;
+    }
+sensor_af_pause_end:
+       return ret;
+}
+static int sensor_af_zoneupdate(struct i2c_client *client)
+{
+       int ret = 0;
+
+       if (sensor_af_idlechk(client))
+               goto sensor_af_zoneupdate_end;
+
+       if (sensor_af_cmdset(client, UpdateZone_Cmd, NULL)) {
+               SENSOR_TR("%s update zone fail!\n",SENSOR_NAME_STRING());
+               ret = -1;
+               goto sensor_af_zoneupdate_end;
+       }
+
+sensor_af_zoneupdate_end:
+       return ret;
+}
+static int sensor_af_init(struct i2c_client *client)
+{
+       int ret = 0;
+       char state,cnt;
+
+       ret = sensor_write_array(client, sensor_af_firmware);
+    if (ret != 0) {
+       SENSOR_TR("%s Download firmware failed\n",SENSOR_NAME_STRING());
+       ret = -1;
+          goto sensor_af_init_end;
+    }
+
+       cnt = 0;
+    do
+    {
+       if (cnt != 0) {
+                       msleep(1);
+       }
+       cnt++;
+               ret = sensor_read(client, STA_FOCUS_Reg, &state);
+               if (ret != 0){
+                  SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__);
+                  ret = -1;
+                  goto sensor_af_init_end;
+               }
+    }while((state == S_STARTUP) && (cnt<100));
+
+    if (state != S_IDLE) {
+        SENSOR_TR("%s focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),state);
+               ret = -1;
+               goto sensor_af_init_end;
+    }
+
+sensor_af_init_end:
+       SENSOR_DG("%s %s ret:0x%x \n",SENSOR_NAME_STRING(),__FUNCTION__,ret);
+       return ret;
+}
+
+static int sensor_af_wq_function(struct i2c_client *client)
+{
+       struct sensor *sensor = to_sensor(client);
+       struct af_cmdinfo cmdinfo;
+       int ret=0, focus_pos = 0xfe;
+
+       SENSOR_DG("%s %s Enter\n",SENSOR_NAME_STRING(), __FUNCTION__);
+
+       mutex_lock(&sensor->wq_lock);
+       if (sensor_af_init(client)) {
+               sensor->info_priv.funmodule_state &= (~SENSOR_AF_IS_OK);
+               ret = -1;
+       } else {
+               sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK;
+
+               switch (sensor->info_priv.auto_focus)
+               {
+                       case SENSOR_AF_MODE_INFINITY:
+                       {
+                               focus_pos = 0x00;
+                       }
+                       case SENSOR_AF_MODE_MACRO:
+                       {
+                               if (focus_pos != 0x00)
+                                       focus_pos = 0xff;
+
+                               sensor_af_idlechk(client);
+                               cmdinfo.cmd_tag = StepFocus_Spec_Tag;
+                               cmdinfo.cmd_para[0] = focus_pos;
+                               cmdinfo.validate_bit = 0x81;
+                               ret = sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo);
+                               break;
+                       }
+                       case SENSOR_AF_MODE_AUTO:
+                       {
+                               ret = sensor_af_single(client);
+                               break;
+                       }
+                       case SENSOR_AF_MODE_CONTINUOUS:
+                       {
+                               ret = sensor_af_const(client);
+                               break;
+                       }
+                       case SENSOR_AF_MODE_CLOSE:
+                       {
+                               ret = 0;
+                               break;
+                       }
+                       default:
+            {
+                               SENSOR_DG("%s focus mode(0x%x) is unkonwn\n",SENSOR_NAME_STRING(),sensor->info_priv.auto_focus);
+                goto sensor_af_wq_function_end;
+                       }
+               }
+
+               SENSOR_DG("%s sensor_af_wq_function set focus mode(0x%x) ret:0x%x\n",SENSOR_NAME_STRING(), sensor->info_priv.auto_focus,ret);
+       }
+
+sensor_af_wq_function_end:
+       sensor->sensor_wk.state = sensor_work_ready;
+       mutex_unlock(&sensor->wq_lock);
+       return ret;
+}
+static void sensor_af_workqueue(struct work_struct *work)
+{
+       struct sensor_work *sensor_work = container_of(work, struct sensor_work, dwork.work);
+       struct i2c_client *client = sensor_work->client;
+
+       if (sensor_af_wq_function(client) < 0) {
+               SENSOR_TR("%s af workqueue return false\n",SENSOR_NAME_STRING());
+       }
+}
+#endif
+
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
+{
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       int ret = 0;
+
+    SENSOR_DG("%s %s  cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
+
+       switch (cmd)
+       {
+               case Sensor_PowerDown:
+               {
+                       if (icl->powerdown) {
+                               ret = icl->powerdown(icd->pdev, on);
+                               if (ret == RK29_CAM_IO_SUCCESS) {
+                                       if (on == 0) {
+                                               mdelay(2);
+                                               if (icl->reset)
+                                                       icl->reset(icd->pdev);
+                                       }
+                               } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {
+                                       ret = -ENODEV;
+                                       goto sensor_power_end;
+                               }
+                       }
+                       break;
+               }
+               case Sensor_Flash:
+               {
+                       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+               struct sensor *sensor = to_sensor(client);
+
+                       if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
+                               sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
+                       }
+                       break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),cmd);
+                       break;
+               }
+       }
 
+sensor_power_end:
+       return ret;
+}
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = sd->priv;
@@ -1829,11 +2585,16 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     int ret,pid = 0;
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
-    
 
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_INIT_ERR;
+       }
 /* ddl@rock-chips.com : ov3640_powerOn have hardware reset */
 #if 0
     /* soft reset */
+       if (sensor_task_lock(client,1)<0)
+               goto sensor_INIT_ERR;
     ret = sensor_write(client, 0x3012, 0x80);
     if (ret != 0)
     {
@@ -1877,9 +2638,9 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
         goto sensor_INIT_ERR;
     }
-
-    icd->user_width = SENSOR_INIT_WIDTH;
-    icd->user_height = SENSOR_INIT_HEIGHT;
+       sensor_task_lock(client,0);
+    //icd->user_width = SENSOR_INIT_WIDTH;
+    //icd->user_height = SENSOR_INIT_HEIGHT;
     sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;
        sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT;
 
@@ -1918,8 +2679,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code  */
        #if CONFIG_SENSOR_Focus
-    sensor_set_focus();
-    qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);
+       //    sensor_set_focus(); 
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);//?,JYK
        if (qctrl)
         sensor->info_priv.focus = qctrl->default_value;
        #endif
@@ -1931,13 +2692,28 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         sensor->info_priv.flash = qctrl->default_value;
     #endif
 
-    SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,icd->user_width,icd->user_height);
+    SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);
 
     return 0;
 sensor_INIT_ERR:
+       sensor_task_lock(client,0);
+       sensor_deactivate(client);
     return ret;
 }
+static int sensor_deactivate(struct i2c_client *client)
+{
+       struct soc_camera_device *icd = client->dev.platform_data;
+
+       SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
 
+       /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);
+       /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
+       icd->user_width = SENSOR_INIT_WIDTH;
+    icd->user_height = SENSOR_INIT_HEIGHT;
+       msleep(100);
+       return 0;
+}
 static  struct reginfo sensor_power_down_sequence[]=
 {
                {0x361e, 0x00},
@@ -1951,56 +2727,40 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
 {
     int ret;
     struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-    struct soc_camera_link *icl;
 
-
-    if (pm_msg.event == PM_EVENT_SUSPEND)
-    {
+    if (pm_msg.event == PM_EVENT_SUSPEND) {
         SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());
         ret = sensor_write_array(client, sensor_power_down_sequence) ;
-        if (ret != 0)
-        {
+        if (ret != 0) {
             SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);
             return ret;
-        }
-        else
-        {
-            icl = to_soc_camera_link(icd);
-            if (icl->power) {
-                ret = icl->power(icd->pdev, 0);
-                if (ret < 0) {
-                                   SENSOR_TR("\n %s suspend fail for turn on power!\n",__FUNCTION__);
-                    return -EINVAL;
-                }
+        } else {
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);
+            if (ret < 0) {
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
+                return -EINVAL;
             }
         }
-    }
-    else
-    {
+    } else {
         SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());
         return -EINVAL;
     }
+
     return 0;
 }
 
 static int sensor_resume(struct soc_camera_device *icd)
 {
-    struct soc_camera_link *icl;
-    int ret;
+       int ret;
 
-    icl = to_soc_camera_link(icd);
-    if (icl->power) {
-        ret = icl->power(icd->pdev, 1);
-        if (ret < 0) {
-                       SENSOR_TR("\n %s resume fail for turn on power!\n",__FUNCTION__);
-            return -EINVAL;
-        }
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);
+    if (ret < 0) {
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
+        return -EINVAL;
     }
 
        SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());
-
-    return 0;
-
+       return 0;
 }
 
 static int sensor_set_bus_param(struct soc_camera_device *icd,
@@ -2034,28 +2794,51 @@ static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
     return 0;
 }
 
-static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
-{
-       struct i2c_client *client = sd->priv;
-       struct soc_camera_device *icd = client->dev.platform_data;
 
-       if (!enable) {
-               sensor_set_flashLed(icd,0);
-               return 0;
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
+               ret = true;
        }
 
-       return 0;
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
 }
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
 
+       if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
 static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
     struct i2c_client *client = sd->priv;
        struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
     struct v4l2_pix_format *pix = &f->fmt.pix;
+    const struct v4l2_queryctrl *qctrl;
     struct reginfo *winseqe_set_addr=NULL;
-    int ret, set_w,set_h;
-       int isCapture = 0; // 1--ÅÄÕÕÐòÁР0--Ô¤ÀÀÐòÁÐ
+    int ret=0, set_w,set_h;
+       int isCapture = 0; 
        
        if (sensor->info_priv.pixfmt != pix->pixelformat) {
                switch (pix->pixelformat)
@@ -2085,14 +2868,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
     set_w = pix->width;
     set_h = pix->height;
-       isCapture = pix->priv;
-       
-       if(isCapture)
-          sensor_set_flashLed(icd,1);
-       
-       SENSOR_DG("%s %c,%c,%c,%c\n", SENSOR_NAME_STRING(),
-               ((pix->pixelformat) & 0xff),((pix->pixelformat>>8) & 0xff),
-               ((pix->pixelformat>>16) & 0xff),((pix->pixelformat>>24) & 0xff));
+       isCapture = sensor_fmt_capturechk(sd, f);
        
        if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[isCapture][0].reg)
        {
@@ -2108,6 +2884,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
     }
     else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[isCapture][0].reg)
     {
+        //printk("===> isCapture: %d!\n", isCapture);
         winseqe_set_addr = sensor_cif[isCapture];
         set_w = 352;
         set_h = 288;
@@ -2148,17 +2925,13 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         set_w = 2048;
         set_h = 1536;
     }
-    else if (sensor_qcif[isCapture][0].reg)
+    else
     {
-               winseqe_set_addr = sensor_qcif[isCapture]; /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
-        set_w = 176;
-        set_h = 144;
-    }
-       else
-       {
+        winseqe_set_addr = SENSOR_INIT_WINSEQADR;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;            
                SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);
-               return -EINVAL;
-       }
+    }
 
     if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr)
     {
@@ -2168,23 +2941,74 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                {
                        SENSOR_DG("%s  write sensor_qxga[1]\n", SENSOR_NAME_STRING());
                        ret = sensor_write_array(client, sensor_qxga[isCapture]);
-               if (ret != 0)
-               {
-                   SENSOR_TR("%s  write sensor_qxga[1] failed\n", SENSOR_NAME_STRING());
-                   return ret;
-               }
+                       if (ret != 0)
+                       {
+                           SENSOR_TR("%s  write sensor_qxga[1] failed\n", SENSOR_NAME_STRING());
+                           return ret;
+                       }
                }
+
+               #if CONFIG_SENSOR_Focus
+                       //sensor_af_idlechk(client);
+                       if (sensor->info_priv.auto_focus == SENSOR_AF_MODE_CONTINUOUS)
+                       {
+                               sensor_af_idlechk(client); // by duanyp
+                               sensor_af_cmdset(client, PauseFocus_Cmd, NULL);
+                       }
+               #endif
+
+        #if CONFIG_SENSOR_Flash
+        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_On);
+                SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
+            }           
+        } else {                                        /* ddl@rock-chips.com : Video */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());
+            }
+        }
+        #endif
                
-        ret = sensor_write_array(client, winseqe_set_addr);
-        if (ret != 0)
-        {
+        ret = sensor_write_array(client, winseqe_set_addr);        
+        if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
-            return ret;
+            #if CONFIG_SENSOR_Flash
+            if (sensor_fmt_capturechk(sd,f) == true) {
+                if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                    sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                    SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
+                }
+            }
+            #endif
+            goto sensor_s_fmt_end;
+        } else {
+            sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
+            if (sensor_fmt_capturechk(sd,f) == true) {                             /* ddl@rock-chips.com : Capture */
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       if (sensor->info_priv.whiteBalance != 0) {
+                               qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                               sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       }
+                       sensor->info_priv.snap2preview = true;
+               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       sensor->info_priv.video2preview = true;
+               } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       sensor->info_priv.video2preview = false;
+                       sensor->info_priv.snap2preview = false;
+               }
+            mdelay(100);  // by FAE.
         }
-
-        sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
-        //mdelay(250);
-
         SENSOR_DG("\n%s..%s.. icd->width=%d..icd->height=%d..isCapture=%d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h,isCapture);
     }
     else
@@ -2192,7 +3016,11 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
         SENSOR_TR("\n %s .. Current Format is validate. icd->width=%d..icd->height=%d..isCapture=%d\n",SENSOR_NAME_STRING(),set_w,set_h,isCapture);
     }
 
-    return 0;
+    //add by duanyp. Improve the green phenomenon when startup camera every time.
+    //mdelay(500);
+
+sensor_s_fmt_end:
+    return ret;
 }
 
 static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
@@ -2238,58 +3066,6 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
     return 0;
 }
-
-static int sensor_set_flashLed(struct soc_camera_device *icd, int value)
-{
-#if CONFIG_SENSOR_Flash        
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-    struct sensor *sensor = to_sensor(client);
-       int ret;
-       
-       SENSOR_DG("sensor_set_flashLed - %d,%d\n", sensor->info_priv.flash,value);
-       
-       if(icl->flash_led == NULL)
-       {
-               SENSOR_TR("icl->flash_led == NULL\n ");
-               return -1;
-       }
-               
-       switch(sensor->info_priv.flash)
-       {
-               case 0: // off
-               {
-                       ret = icl->flash_led(icd->pdev, 0);
-                       break;
-               }
-               case 1: //auto
-               {
-                       ret = icl->flash_led(icd->pdev,value);
-                       break;
-               }
-               case 2: // on
-               {
-                       ret = icl->flash_led(icd->pdev,1);
-                       break;
-               }
-               default: // off
-               {
-                       ret = icl->flash_led(icd->pdev,0);
-                       break;
-               }
-
-       }
-
-       if(ret)
-       {
-               SENSOR_TR("icl->flash_led failed\n ");
-       }
-#endif
-
-    return 0;
-}
-
 #if CONFIG_SENSOR_Brightness
 static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
 {
@@ -2541,6 +3317,150 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4
     return -EINVAL;
 }
 #endif
+
+#if CONFIG_SENSOR_Focus
+static int sensor_set_focus_absolute(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl_info;
+       struct af_cmdinfo cmdinfo;
+       int ret = 0;
+
+       qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);
+       if (!qctrl_info)
+               return -EINVAL;
+
+       if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) {
+               if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) {
+
+                       if (sensor_af_idlechk(client))
+                               goto sensor_set_focus_absolute_end;
+
+                       cmdinfo.cmd_tag = StepFocus_Spec_Tag;
+                       cmdinfo.cmd_para[0] = value;
+                       cmdinfo.validate_bit = 0x81;
+                       ret = sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo);
+                       //ret |= sensor_af_cmdset(client, ReturnIdle_Cmd, NULL);
+                       SENSOR_DG("%s..%s : %d  ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret);
+               } else {
+                       ret = -EINVAL;
+                       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+               }
+       } else {
+               ret = -EACCES;
+               SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__,
+                       sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit);
+       }
+
+sensor_set_focus_absolute_end:
+       return ret;
+}
+static int sensor_set_focus_relative(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+       struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl_info;
+       struct af_cmdinfo cmdinfo;
+       int ret = 0;
+
+       qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_RELATIVE);
+       if (!qctrl_info)
+               return -EINVAL;
+
+       if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) {
+               if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) {
+
+                       if (sensor_af_idlechk(client))
+                               goto sensor_set_focus_relative_end;
+
+                       if (value > 0) {
+                               cmdinfo.cmd_tag = StepFocus_Near_Tag;
+                       } else if (value < 0) {
+                               cmdinfo.cmd_tag = StepFocus_Far_Tag;
+                       }
+                       cmdinfo.validate_bit = 0x80;
+                       ret = sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo);
+
+                       SENSOR_DG("%s..%s : %d  ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret);
+               } else {
+                       ret = -EINVAL;
+                       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+               }
+       } else {
+               ret = -EACCES;
+               SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__,
+                       sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit);
+       }
+sensor_set_focus_relative_end:
+       return ret;
+}
+
+static int sensor_set_focus_mode(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+       struct sensor *sensor = to_sensor(client);
+       int ret = 0;
+
+       if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)  && (sensor->info_priv.affm_reinit == 0)) {
+               switch (value)
+               {
+                       case SENSOR_AF_MODE_AUTO:
+                       {
+                               ret = sensor_af_single(client);                         
+                               break;
+                       }
+
+                       case SENSOR_AF_MODE_MACRO:
+                       {
+                               ret = sensor_set_focus_absolute(icd, qctrl, 0xff);
+                               break;
+                       }
+
+                       case SENSOR_AF_MODE_INFINITY:
+                       {
+                               ret = sensor_set_focus_absolute(icd, qctrl, 0x00);
+                               break;
+                       }
+
+                       case SENSOR_AF_MODE_CONTINUOUS:
+                       {
+                               ret = sensor_af_const(client);
+                               break;
+                       }
+                       default:
+                               SENSOR_TR("\n %s..%s AF value(0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+                               break;
+
+               }
+
+               SENSOR_DG("%s..%s : %d  ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret);
+       } else {
+               ret = -EACCES;
+               SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__,
+                       sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit);
+       }
+
+       return ret;
+}
+#endif
+#if CONFIG_SENSOR_Flash
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{    
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {
+        if (value == 3) {       /* ddl@rock-chips.com: torch */
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Torch);   /* Flash On */
+        } else {
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+        }
+        SENSOR_DG("%s..%s : %d\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+        return 0;
+    }
+    
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
 static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
     struct i2c_client *client = sd->priv;
@@ -2551,7 +3471,7 @@ static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 
     if (!qctrl)
     {
-        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        SENSOR_TR("\n %s ioctrl id = 0x%x  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
         return -EINVAL;
     }
 
@@ -2612,7 +3532,7 @@ static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 
     if (!qctrl)
     {
-        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
+        SENSOR_TR("\n %s ioctrl id = 0x%x  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);
         return -EINVAL;
     }
 
@@ -2728,7 +3648,7 @@ static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_
 
     if (!qctrl)
     {
-        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        SENSOR_TR("\n %s ioctrl id = 0x%x  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
         return -EINVAL;
     }
 
@@ -2783,7 +3703,7 @@ static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_c
 
     if (!qctrl)
     {
-        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
+        SENSOR_TR("\n %s ioctrl id = 0x%x  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);
         return -EINVAL;
     }
 
@@ -2852,31 +3772,61 @@ static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_c
                 if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
                     return -EINVAL;
 
-                if (ext_ctrl->value != sensor->info_priv.focus)
-                {
-                    val_offset = ext_ctrl->value -sensor->info_priv.focus;
-
-                    sensor->info_priv.focus += val_offset;
-                }
+                               if (sensor_set_focus_absolute(icd, qctrl,ext_ctrl->value) == 0) {
+                                       if (ext_ctrl->value == qctrl->minimum) {
+                                               sensor->info_priv.auto_focus = SENSOR_AF_MODE_INFINITY;
+                                       } else if (ext_ctrl->value == qctrl->maximum) {
+                                               sensor->info_priv.auto_focus = SENSOR_AF_MODE_MACRO;
+                                       } else {
+                                               sensor->info_priv.auto_focus = SENSOR_AF_MODE_FIXED;
+                                       }
+                               }
 
                 break;
-            }
-        case V4L2_CID_FOCUS_RELATIVE:
+            }          
+         case V4L2_CID_FOCUS_RELATIVE:
             {
-                if (ext_ctrl->value)
-                {
-                    sensor->info_priv.focus += ext_ctrl->value;
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))
+                    return -EINVAL;
 
-                    SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus);
-                }
+                sensor_set_focus_relative(icd, qctrl,ext_ctrl->value);
                 break;
             }
+               case V4L2_CID_FOCUS_AUTO:
+                       {
+                               if (ext_ctrl->value == 1) {
+                                       if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_AUTO) != 0)
+                                               return -EINVAL;
+                                       sensor->info_priv.auto_focus = SENSOR_AF_MODE_AUTO;
+                               } else if (SENSOR_AF_MODE_AUTO == sensor->info_priv.auto_focus){
+                                       if (ext_ctrl->value == 0)
+                                               sensor->info_priv.auto_focus = SENSOR_AF_MODE_CLOSE;
+                               }
+                               break;
+                       }
+               /*
+               case V4L2_CID_FOCUS_CONTINUOUS:
+                       {
+                               if (SENSOR_AF_MODE_CONTINUOUS != sensor->info_priv.auto_focus) {
+                                       if (ext_ctrl->value == 1) {
+                                               if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_CONTINUOUS) != 0)
+                                                       return -EINVAL;
+                                               sensor->info_priv.auto_focus = SENSOR_AF_MODE_CONTINUOUS;
+                                       }
+                               } else {
+                                       if (ext_ctrl->value == 0)
+                                               sensor->info_priv.auto_focus = SENSOR_AF_MODE_CLOSE;
+                               }
+                               break;
+                       }*/
 #endif
 #if CONFIG_SENSOR_Flash
         case V4L2_CID_FLASH:
             {
+                if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)
+                    return -EINVAL;
                 sensor->info_priv.flash = ext_ctrl->value;
-                               sensor_set_flashLed(icd,0);
+
                 SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);
                 break;
             }
@@ -2938,6 +3888,54 @@ static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_control
     }
 }
 
+static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+    #if CONFIG_SENSOR_Focus
+       struct soc_camera_device *icd = client->dev.platform_data;
+       struct v4l2_format fmt;
+    #endif
+
+       if (enable == 1) {
+               sensor->info_priv.enable = 1;
+               #if CONFIG_SENSOR_Focus
+               fmt.fmt.pix.width = icd->user_width;
+               fmt.fmt.pix.height = icd->user_height;
+               /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */
+               if (sensor_fmt_capturechk(sd, &fmt) == false) {
+                       if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) {
+                               if (sensor->sensor_wq != NULL) {
+                                       mutex_lock(&sensor->wq_lock);
+                                       if (sensor->sensor_wk.state == sensor_working) {
+                                               SENSOR_DG("%s sensor af firmware thread is runing, Ingore current work",SENSOR_NAME_STRING());
+                                               mutex_unlock(&sensor->wq_lock);
+                                               goto sensor_s_stream_end;
+                                       }
+                                       sensor->sensor_wk.state = sensor_working;
+                                       mutex_unlock(&sensor->wq_lock);
+                                       sensor->sensor_wk.client = client;
+                                       INIT_WORK(&(sensor->sensor_wk.dwork.work), sensor_af_workqueue);
+                                       queue_delayed_work(sensor->sensor_wq,&(sensor->sensor_wk.dwork), 0);
+                               }
+                               sensor->info_priv.affm_reinit = 0;
+                       }
+               }
+               #endif
+       } else if (enable == 0) {
+               sensor->info_priv.enable = 0;
+               #if CONFIG_SENSOR_Focus
+               flush_work(&(sensor->sensor_wk.dwork.work));
+               mutex_lock(&sensor->wq_lock);
+               sensor->sensor_wk.state = sensor_work_ready;
+               mutex_unlock(&sensor->wq_lock);
+               #endif
+       }
+
+sensor_s_stream_end:
+       return 0;
+}
+
 /* Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one */
 static int sensor_video_probe(struct soc_camera_device *icd,
@@ -2953,12 +3951,16 @@ static int sensor_video_probe(struct soc_camera_device *icd,
            to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
                return -ENODEV;
 
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
     /* soft reset */
     ret = sensor_write(client, 0x3012, 0x80);
-    if (ret != 0)
-    {
+    if (ret != 0) {
         SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
-        return -ENODEV;
+        ret = -ENODEV;
+               goto sensor_video_probe_err;
     }
     mdelay(5);          //delay 5 microseconds
 
@@ -2995,9 +3997,68 @@ static int sensor_video_probe(struct soc_camera_device *icd,
     return 0;
 
 sensor_video_probe_err:
-
     return ret;
 }
+static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+       struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    int ret = 0,i;
+
+       SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+       switch (cmd)
+       {
+               case RK29_CAM_SUBDEV_DEACTIVATE:
+               {
+                       sensor_deactivate(client);
+                       break;
+               }
+               case RK29_CAM_SUBDEV_IOREQUEST:
+               {
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
+            /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
+               for this project */
+            #if CONFIG_SENSOR_Flash    
+               if (sensor->sensor_gpio_res) {
+                printk("flash io:%d\n",sensor->sensor_gpio_res->gpio_flash);
+                if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {
+                    for (i = 0; i < icd->ops->num_controls; i++) {
+                               if (V4L2_CID_FLASH == icd->ops->controls[i].id) {
+                                       memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                       
+                               }
+                    }
+                    sensor->info_priv.flash = 0xff;
+                    SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());
+                }
+               }
+            #endif
+                       break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+
+sensor_ioctl_end:
+       return ret;
+
+}
 
 static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
        .init           = sensor_init,
@@ -3006,13 +4067,14 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
        .g_ext_ctrls          = sensor_g_ext_controls,
        .s_ext_ctrls          = sensor_s_ext_controls,
        .g_chip_ident   = sensor_g_chip_ident,
+       .ioctl = sensor_ioctl,
 };
 
 static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {
-       .s_stream       = sensor_s_stream,
        .s_fmt          = sensor_s_fmt,
        .g_fmt          = sensor_g_fmt,
        .try_fmt        = sensor_try_fmt,
+       .s_stream   = sensor_s_stream,
 };
 
 static struct v4l2_subdev_ops sensor_subdev_ops = {
@@ -3056,12 +4118,24 @@ static int sensor_probe(struct i2c_client *client,
     /* Second stage probe - when a capture adapter is there */
     icd->ops           = &sensor_ops;
     icd->y_skip_top            = 0;
+       #if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_set(&sensor->tasklock_cnt,0);
+       #endif
 
     ret = sensor_video_probe(icd, client);
-    if (ret) {
+    if (ret < 0) {
         icd->ops = NULL;
         i2c_set_clientdata(client, NULL);
         kfree(sensor);
+       sensor = NULL;
+    } else {
+               #if CONFIG_SENSOR_Focus
+               sensor->sensor_wq = create_workqueue(SENSOR_NAME_STRING( wq));
+               if (sensor->sensor_wq == NULL)
+                       SENSOR_TR("%s workqueue create fail!", SENSOR_NAME_STRING( wq));
+               mutex_init(&sensor->wq_lock);
+               sensor->sensor_wk.state = sensor_work_ready;
+               #endif
     }
     SENSOR_DG("\n%s..%s..%d  ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);
     return ret;
@@ -3072,11 +4146,18 @@ static int sensor_remove(struct i2c_client *client)
     struct sensor *sensor = to_sensor(client);
     struct soc_camera_device *icd = client->dev.platform_data;
 
+       #if CONFIG_SENSOR_Focus
+       if (sensor->sensor_wq) {
+               destroy_workqueue(sensor->sensor_wq);
+               sensor->sensor_wq = NULL;
+       }
+       #endif
+       
     icd->ops = NULL;
     i2c_set_clientdata(client, NULL);
     client->driver = NULL;
     kfree(sensor);
-
+    sensor = NULL;
     return 0;
 }
 
@@ -3110,6 +4191,6 @@ device_initcall_sync(sensor_mod_init);
 module_exit(sensor_mod_exit);
 
 MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));
-MODULE_AUTHOR("srt <kernel@rock-chips>");
+MODULE_AUTHOR("ddl <kernel@rock-chips>");
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/media/video/ov3640.h b/drivers/media/video/ov3640.h
new file mode 100755 (executable)
index 0000000..3435c12
--- /dev/null
@@ -0,0 +1,26 @@
+/*\r
+ * Driver for OV5642 CMOS Image Sensor from OmniVision\r
+ *\r
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License version 2 as\r
+ * published by the Free Software Foundation.\r
+ */\r
+\r
+#ifndef __OV3640_H__\r
+#define __OV3640_H__\r
+struct reginfo\r
+{\r
+    u16 reg;\r
+    u8 val;\r
+};\r
+\r
+#define SEQUENCE_INIT        0x00\r
+#define SEQUENCE_NORMAL      0x01\r
+\r
+#define SEQUENCE_PROPERTY    0xFFFD\r
+#define SEQUENCE_WAIT_MS     0xFFFE\r
+#define SEQUENCE_END        0xFFFF\r
+#endif\r
+\r
diff --git a/drivers/media/video/ov3640_af_firmware.c b/drivers/media/video/ov3640_af_firmware.c
new file mode 100755 (executable)
index 0000000..f110193
--- /dev/null
@@ -0,0 +1,3477 @@
+/*\r
+ * Driver for OV5642 CMOS Image Sensor from OmniVision\r
+ *\r
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License version 2 as\r
+ * published by the Free Software Foundation.\r
+ */\r
+\r
+#define VCM_DRIVER_A3907   0\r
+#define VCM_DRIVER_AD5820  1\r
+#define VCM_DRIVER_DW9710  2\r
+#define VCM_DRIVER         VCM_DRIVER_AD5820\r
+\r
+\r
+#if (VCM_DRIVER == VCM_DRIVER_AD5820)\r
+static struct reginfo sensor_af_firmware[ ]=\r
+{\r
+       {0x308c,0x00},\r
+       {0x3104,0x02},\r
+       {0x3105,0xff},\r
+       {0x3106,0x00},\r
+       {0x3107,0xff},\r
+       {0x8000,0x02},\r
+       {0x8001,0x00},\r
+       {0x8002,0x06},\r
+       {0x8003,0x02},\r
+       {0x8004,0x07},\r
+       {0x8005,0xa9},\r
+       {0x8006,0x78},\r
+       {0x8007,0x7f},\r
+       {0x8008,0xe4},\r
+       {0x8009,0xf6},\r
+       {0x800a,0xd8},\r
+       {0x800b,0xfd},\r
+       {0x800c,0x75},\r
+       {0x800d,0x81},\r
+       {0x800e,0x45},\r
+       {0x800f,0x02},\r
+       {0x8010,0x0a},\r
+       {0x8011,0xdf},\r
+       {0x8012,0x32},\r
+       {0x8013,0x02},\r
+       {0x8014,0x00},\r
+       {0x8015,0x12},\r
+       {0x8016,0xe8},\r
+       {0x8017,0x8f},\r
+       {0x8018,0xf0},\r
+       {0x8019,0xa4},\r
+       {0x801a,0xcc},\r
+       {0x801b,0x8b},\r
+       {0x801c,0xf0},\r
+       {0x801d,0xa4},\r
+       {0x801e,0x2c},\r
+       {0x801f,0xfc},\r
+       {0x8020,0xe9},\r
+       {0x8021,0x8e},\r
+       {0x8022,0xf0},\r
+       {0x8023,0xa4},\r
+       {0x8024,0x2c},\r
+       {0x8025,0xfc},\r
+       {0x8026,0x8a},\r
+       {0x8027,0xf0},\r
+       {0x8028,0xed},\r
+       {0x8029,0xa4},\r
+       {0x802a,0x2c},\r
+       {0x802b,0xfc},\r
+       {0x802c,0xea},\r
+       {0x802d,0x8e},\r
+       {0x802e,0xf0},\r
+       {0x802f,0xa4},\r
+       {0x8030,0xcd},\r
+       {0x8031,0xa8},\r
+       {0x8032,0xf0},\r
+       {0x8033,0x8b},\r
+       {0x8034,0xf0},\r
+       {0x8035,0xa4},\r
+       {0x8036,0x2d},\r
+       {0x8037,0xcc},\r
+       {0x8038,0x38},\r
+       {0x8039,0x25},\r
+       {0x803a,0xf0},\r
+       {0x803b,0xfd},\r
+       {0x803c,0xe9},\r
+       {0x803d,0x8f},\r
+       {0x803e,0xf0},\r
+       {0x803f,0xa4},\r
+       {0x8040,0x2c},\r
+       {0x8041,0xcd},\r
+       {0x8042,0x35},\r
+       {0x8043,0xf0},\r
+       {0x8044,0xfc},\r
+       {0x8045,0xeb},\r
+       {0x8046,0x8e},\r
+       {0x8047,0xf0},\r
+       {0x8048,0xa4},\r
+       {0x8049,0xfe},\r
+       {0x804a,0xa9},\r
+       {0x804b,0xf0},\r
+       {0x804c,0xeb},\r
+       {0x804d,0x8f},\r
+       {0x804e,0xf0},\r
+       {0x804f,0xa4},\r
+       {0x8050,0xcf},\r
+       {0x8051,0xc5},\r
+       {0x8052,0xf0},\r
+       {0x8053,0x2e},\r
+       {0x8054,0xcd},\r
+       {0x8055,0x39},\r
+       {0x8056,0xfe},\r
+       {0x8057,0xe4},\r
+       {0x8058,0x3c},\r
+       {0x8059,0xfc},\r
+       {0x805a,0xea},\r
+       {0x805b,0xa4},\r
+       {0x805c,0x2d},\r
+       {0x805d,0xce},\r
+       {0x805e,0x35},\r
+       {0x805f,0xf0},\r
+       {0x8060,0xfd},\r
+       {0x8061,0xe4},\r
+       {0x8062,0x3c},\r
+       {0x8063,0xfc},\r
+       {0x8064,0x22},\r
+       {0x8065,0x75},\r
+       {0x8066,0xf0},\r
+       {0x8067,0x08},\r
+       {0x8068,0x75},\r
+       {0x8069,0x82},\r
+       {0x806a,0x00},\r
+       {0x806b,0xef},\r
+       {0x806c,0x2f},\r
+       {0x806d,0xff},\r
+       {0x806e,0xee},\r
+       {0x806f,0x33},\r
+       {0x8070,0xfe},\r
+       {0x8071,0xcd},\r
+       {0x8072,0x33},\r
+       {0x8073,0xcd},\r
+       {0x8074,0xcc},\r
+       {0x8075,0x33},\r
+       {0x8076,0xcc},\r
+       {0x8077,0xc5},\r
+       {0x8078,0x82},\r
+       {0x8079,0x33},\r
+       {0x807a,0xc5},\r
+       {0x807b,0x82},\r
+       {0x807c,0x9b},\r
+       {0x807d,0xed},\r
+       {0x807e,0x9a},\r
+       {0x807f,0xec},\r
+       {0x8080,0x99},\r
+       {0x8081,0xe5},\r
+       {0x8082,0x82},\r
+       {0x8083,0x98},\r
+       {0x8084,0x40},\r
+       {0x8085,0x0c},\r
+       {0x8086,0xf5},\r
+       {0x8087,0x82},\r
+       {0x8088,0xee},\r
+       {0x8089,0x9b},\r
+       {0x808a,0xfe},\r
+       {0x808b,0xed},\r
+       {0x808c,0x9a},\r
+       {0x808d,0xfd},\r
+       {0x808e,0xec},\r
+       {0x808f,0x99},\r
+       {0x8090,0xfc},\r
+       {0x8091,0x0f},\r
+       {0x8092,0xd5},\r
+       {0x8093,0xf0},\r
+       {0x8094,0xd6},\r
+       {0x8095,0xe4},\r
+       {0x8096,0xce},\r
+       {0x8097,0xfb},\r
+       {0x8098,0xe4},\r
+       {0x8099,0xcd},\r
+       {0x809a,0xfa},\r
+       {0x809b,0xe4},\r
+       {0x809c,0xcc},\r
+       {0x809d,0xf9},\r
+       {0x809e,0xa8},\r
+       {0x809f,0x82},\r
+       {0x80a0,0x22},\r
+       {0x80a1,0xb8},\r
+       {0x80a2,0x00},\r
+       {0x80a3,0xc1},\r
+       {0x80a4,0xb9},\r
+       {0x80a5,0x00},\r
+       {0x80a6,0x59},\r
+       {0x80a7,0xba},\r
+       {0x80a8,0x00},\r
+       {0x80a9,0x2d},\r
+       {0x80aa,0xec},\r
+       {0x80ab,0x8b},\r
+       {0x80ac,0xf0},\r
+       {0x80ad,0x84},\r
+       {0x80ae,0xcf},\r
+       {0x80af,0xce},\r
+       {0x80b0,0xcd},\r
+       {0x80b1,0xfc},\r
+       {0x80b2,0xe5},\r
+       {0x80b3,0xf0},\r
+       {0x80b4,0xcb},\r
+       {0x80b5,0xf9},\r
+       {0x80b6,0x78},\r
+       {0x80b7,0x18},\r
+       {0x80b8,0xef},\r
+       {0x80b9,0x2f},\r
+       {0x80ba,0xff},\r
+       {0x80bb,0xee},\r
+       {0x80bc,0x33},\r
+       {0x80bd,0xfe},\r
+       {0x80be,0xed},\r
+       {0x80bf,0x33},\r
+       {0x80c0,0xfd},\r
+       {0x80c1,0xec},\r
+       {0x80c2,0x33},\r
+       {0x80c3,0xfc},\r
+       {0x80c4,0xeb},\r
+       {0x80c5,0x33},\r
+       {0x80c6,0xfb},\r
+       {0x80c7,0x10},\r
+       {0x80c8,0xd7},\r
+       {0x80c9,0x03},\r
+       {0x80ca,0x99},\r
+       {0x80cb,0x40},\r
+       {0x80cc,0x04},\r
+       {0x80cd,0xeb},\r
+       {0x80ce,0x99},\r
+       {0x80cf,0xfb},\r
+       {0x80d0,0x0f},\r
+       {0x80d1,0xd8},\r
+       {0x80d2,0xe5},\r
+       {0x80d3,0xe4},\r
+       {0x80d4,0xf9},\r
+       {0x80d5,0xfa},\r
+       {0x80d6,0x22},\r
+       {0x80d7,0x78},\r
+       {0x80d8,0x18},\r
+       {0x80d9,0xef},\r
+       {0x80da,0x2f},\r
+       {0x80db,0xff},\r
+       {0x80dc,0xee},\r
+       {0x80dd,0x33},\r
+       {0x80de,0xfe},\r
+       {0x80df,0xed},\r
+       {0x80e0,0x33},\r
+       {0x80e1,0xfd},\r
+       {0x80e2,0xec},\r
+       {0x80e3,0x33},\r
+       {0x80e4,0xfc},\r
+       {0x80e5,0xc9},\r
+       {0x80e6,0x33},\r
+       {0x80e7,0xc9},\r
+       {0x80e8,0x10},\r
+       {0x80e9,0xd7},\r
+       {0x80ea,0x05},\r
+       {0x80eb,0x9b},\r
+       {0x80ec,0xe9},\r
+       {0x80ed,0x9a},\r
+       {0x80ee,0x40},\r
+       {0x80ef,0x07},\r
+       {0x80f0,0xec},\r
+       {0x80f1,0x9b},\r
+       {0x80f2,0xfc},\r
+       {0x80f3,0xe9},\r
+       {0x80f4,0x9a},\r
+       {0x80f5,0xf9},\r
+       {0x80f6,0x0f},\r
+       {0x80f7,0xd8},\r
+       {0x80f8,0xe0},\r
+       {0x80f9,0xe4},\r
+       {0x80fa,0xc9},\r
+       {0x80fb,0xfa},\r
+       {0x80fc,0xe4},\r
+       {0x80fd,0xcc},\r
+       {0x80fe,0xfb},\r
+       {0x80ff,0x22},\r
+       {0x8100,0x75},\r
+       {0x8101,0xf0},\r
+       {0x8102,0x10},\r
+       {0x8103,0xef},\r
+       {0x8104,0x2f},\r
+       {0x8105,0xff},\r
+       {0x8106,0xee},\r
+       {0x8107,0x33},\r
+       {0x8108,0xfe},\r
+       {0x8109,0xed},\r
+       {0x810a,0x33},\r
+       {0x810b,0xfd},\r
+       {0x810c,0xcc},\r
+       {0x810d,0x33},\r
+       {0x810e,0xcc},\r
+       {0x810f,0xc8},\r
+       {0x8110,0x33},\r
+       {0x8111,0xc8},\r
+       {0x8112,0x10},\r
+       {0x8113,0xd7},\r
+       {0x8114,0x07},\r
+       {0x8115,0x9b},\r
+       {0x8116,0xec},\r
+       {0x8117,0x9a},\r
+       {0x8118,0xe8},\r
+       {0x8119,0x99},\r
+       {0x811a,0x40},\r
+       {0x811b,0x0a},\r
+       {0x811c,0xed},\r
+       {0x811d,0x9b},\r
+       {0x811e,0xfd},\r
+       {0x811f,0xec},\r
+       {0x8120,0x9a},\r
+       {0x8121,0xfc},\r
+       {0x8122,0xe8},\r
+       {0x8123,0x99},\r
+       {0x8124,0xf8},\r
+       {0x8125,0x0f},\r
+       {0x8126,0xd5},\r
+       {0x8127,0xf0},\r
+       {0x8128,0xda},\r
+       {0x8129,0xe4},\r
+       {0x812a,0xcd},\r
+       {0x812b,0xfb},\r
+       {0x812c,0xe4},\r
+       {0x812d,0xcc},\r
+       {0x812e,0xfa},\r
+       {0x812f,0xe4},\r
+       {0x8130,0xc8},\r
+       {0x8131,0xf9},\r
+       {0x8132,0x22},\r
+       {0x8133,0xe8},\r
+       {0x8134,0x60},\r
+       {0x8135,0x0f},\r
+       {0x8136,0xef},\r
+       {0x8137,0xc3},\r
+       {0x8138,0x33},\r
+       {0x8139,0xff},\r
+       {0x813a,0xee},\r
+       {0x813b,0x33},\r
+       {0x813c,0xfe},\r
+       {0x813d,0xed},\r
+       {0x813e,0x33},\r
+       {0x813f,0xfd},\r
+       {0x8140,0xec},\r
+       {0x8141,0x33},\r
+       {0x8142,0xfc},\r
+       {0x8143,0xd8},\r
+       {0x8144,0xf1},\r
+       {0x8145,0x22},\r
+       {0x8146,0xa4},\r
+       {0x8147,0x25},\r
+       {0x8148,0x82},\r
+       {0x8149,0xf5},\r
+       {0x814a,0x82},\r
+       {0x814b,0xe5},\r
+       {0x814c,0xf0},\r
+       {0x814d,0x35},\r
+       {0x814e,0x83},\r
+       {0x814f,0xf5},\r
+       {0x8150,0x83},\r
+       {0x8151,0x22},\r
+       {0x8152,0xd0},\r
+       {0x8153,0x83},\r
+       {0x8154,0xd0},\r
+       {0x8155,0x82},\r
+       {0x8156,0xf8},\r
+       {0x8157,0xe4},\r
+       {0x8158,0x93},\r
+       {0x8159,0x70},\r
+       {0x815a,0x12},\r
+       {0x815b,0x74},\r
+       {0x815c,0x01},\r
+       {0x815d,0x93},\r
+       {0x815e,0x70},\r
+       {0x815f,0x0d},\r
+       {0x8160,0xa3},\r
+       {0x8161,0xa3},\r
+       {0x8162,0x93},\r
+       {0x8163,0xf8},\r
+       {0x8164,0x74},\r
+       {0x8165,0x01},\r
+       {0x8166,0x93},\r
+       {0x8167,0xf5},\r
+       {0x8168,0x82},\r
+       {0x8169,0x88},\r
+       {0x816a,0x83},\r
+       {0x816b,0xe4},\r
+       {0x816c,0x73},\r
+       {0x816d,0x74},\r
+       {0x816e,0x02},\r
+       {0x816f,0x93},\r
+       {0x8170,0x68},\r
+       {0x8171,0x60},\r
+       {0x8172,0xef},\r
+       {0x8173,0xa3},\r
+       {0x8174,0xa3},\r
+       {0x8175,0xa3},\r
+       {0x8176,0x80},\r
+       {0x8177,0xdf},\r
+       {0x8178,0x75},\r
+       {0x8179,0x0c},\r
+       {0x817a,0x0a},\r
+       {0x817b,0xa2},\r
+       {0x817c,0xaf},\r
+       {0x817d,0x92},\r
+       {0x817e,0x22},\r
+       {0x817f,0xc2},\r
+       {0x8180,0xaf},\r
+       {0x8181,0xc2},\r
+       {0x8182,0x23},\r
+       {0x8183,0x12},\r
+       {0x8184,0x04},\r
+       {0x8185,0x07},\r
+       {0x8186,0x12},\r
+       {0x8187,0x04},\r
+       {0x8188,0x4d},\r
+       {0x8189,0x12},\r
+       {0x818a,0x04},\r
+       {0x818b,0x07},\r
+       {0x818c,0x75},\r
+       {0x818d,0x32},\r
+       {0x818e,0x05},\r
+       {0x818f,0xaf},\r
+       {0x8190,0x32},\r
+       {0x8191,0x15},\r
+       {0x8192,0x32},\r
+       {0x8193,0xef},\r
+       {0x8194,0x70},\r
+       {0x8195,0xf9},\r
+       {0x8196,0xd2},\r
+       {0x8197,0x18},\r
+       {0x8198,0x12},\r
+       {0x8199,0x04},\r
+       {0x819a,0x09},\r
+       {0x819b,0x75},\r
+       {0x819c,0x32},\r
+       {0x819d,0x0a},\r
+       {0x819e,0xaf},\r
+       {0x819f,0x32},\r
+       {0x81a0,0x15},\r
+       {0x81a1,0x32},\r
+       {0x81a2,0xef},\r
+       {0x81a3,0x70},\r
+       {0x81a4,0xf9},\r
+       {0x81a5,0xc2},\r
+       {0x81a6,0x19},\r
+       {0x81a7,0x12},\r
+       {0x81a8,0x04},\r
+       {0x81a9,0x09},\r
+       {0x81aa,0x75},\r
+       {0x81ab,0x32},\r
+       {0x81ac,0x05},\r
+       {0x81ad,0xaf},\r
+       {0x81ae,0x32},\r
+       {0x81af,0x15},\r
+       {0x81b0,0x32},\r
+       {0x81b1,0xef},\r
+       {0x81b2,0x70},\r
+       {0x81b3,0xf9},\r
+       {0x81b4,0xc2},\r
+       {0x81b5,0x18},\r
+       {0x81b6,0x12},\r
+       {0x81b7,0x04},\r
+       {0x81b8,0x09},\r
+       {0x81b9,0x75},\r
+       {0x81ba,0x32},\r
+       {0x81bb,0x05},\r
+       {0x81bc,0xaf},\r
+       {0x81bd,0x32},\r
+       {0x81be,0x15},\r
+       {0x81bf,0x32},\r
+       {0x81c0,0xef},\r
+       {0x81c1,0x70},\r
+       {0x81c2,0xf9},\r
+       {0x81c3,0x75},\r
+       {0x81c4,0x0d},\r
+       {0x81c5,0x18},\r
+       {0x81c6,0x12},\r
+       {0x81c7,0x02},\r
+       {0x81c8,0xb8},\r
+       {0x81c9,0x75},\r
+       {0x81ca,0x32},\r
+       {0x81cb,0x0a},\r
+       {0x81cc,0xaf},\r
+       {0x81cd,0x32},\r
+       {0x81ce,0x15},\r
+       {0x81cf,0x32},\r
+       {0x81d0,0xef},\r
+       {0x81d1,0x70},\r
+       {0x81d2,0xf9},\r
+       {0x81d3,0xd2},\r
+       {0x81d4,0x18},\r
+       {0x81d5,0x12},\r
+       {0x81d6,0x04},\r
+       {0x81d7,0x09},\r
+       {0x81d8,0x12},\r
+       {0x81d9,0x04},\r
+       {0x81da,0x97},\r
+       {0x81db,0xaf},\r
+       {0x81dc,0x32},\r
+       {0x81dd,0x15},\r
+       {0x81de,0x32},\r
+       {0x81df,0xef},\r
+       {0x81e0,0x70},\r
+       {0x81e1,0xf9},\r
+       {0x81e2,0xc2},\r
+       {0x81e3,0x18},\r
+       {0x81e4,0x12},\r
+       {0x81e5,0x04},\r
+       {0x81e6,0x09},\r
+       {0x81e7,0x75},\r
+       {0x81e8,0x32},\r
+       {0x81e9,0x0a},\r
+       {0x81ea,0xaf},\r
+       {0x81eb,0x32},\r
+       {0x81ec,0x15},\r
+       {0x81ed,0x32},\r
+       {0x81ee,0xef},\r
+       {0x81ef,0x70},\r
+       {0x81f0,0xf9},\r
+       {0x81f1,0x30},\r
+       {0x81f2,0x11},\r
+       {0x81f3,0x03},\r
+       {0x81f4,0x02},\r
+       {0x81f5,0x02},\r
+       {0x81f6,0x6f},\r
+       {0x81f7,0x12},\r
+       {0x81f8,0x04},\r
+       {0x81f9,0x07},\r
+       {0x81fa,0x12},\r
+       {0x81fb,0x04},\r
+       {0x81fc,0x4d},\r
+       {0x81fd,0xe5},\r
+       {0x81fe,0x0a},\r
+       {0x81ff,0xf5},\r
+       {0x8200,0x0d},\r
+       {0x8201,0x12},\r
+       {0x8202,0x02},\r
+       {0x8203,0xb8},\r
+       {0x8204,0x75},\r
+       {0x8205,0x32},\r
+       {0x8206,0x0a},\r
+       {0x8207,0xaf},\r
+       {0x8208,0x32},\r
+       {0x8209,0x15},\r
+       {0x820a,0x32},\r
+       {0x820b,0xef},\r
+       {0x820c,0x70},\r
+       {0x820d,0xf9},\r
+       {0x820e,0xd2},\r
+       {0x820f,0x18},\r
+       {0x8210,0x12},\r
+       {0x8211,0x04},\r
+       {0x8212,0x09},\r
+       {0x8213,0x12},\r
+       {0x8214,0x04},\r
+       {0x8215,0x97},\r
+       {0x8216,0xaf},\r
+       {0x8217,0x32},\r
+       {0x8218,0x15},\r
+       {0x8219,0x32},\r
+       {0x821a,0xef},\r
+       {0x821b,0x70},\r
+       {0x821c,0xf9},\r
+       {0x821d,0xc2},\r
+       {0x821e,0x18},\r
+       {0x821f,0x12},\r
+       {0x8220,0x04},\r
+       {0x8221,0x09},\r
+       {0x8222,0x75},\r
+       {0x8223,0x32},\r
+       {0x8224,0x0a},\r
+       {0x8225,0xaf},\r
+       {0x8226,0x32},\r
+       {0x8227,0x15},\r
+       {0x8228,0x32},\r
+       {0x8229,0xef},\r
+       {0x822a,0x70},\r
+       {0x822b,0xf9},\r
+       {0x822c,0x30},\r
+       {0x822d,0x11},\r
+       {0x822e,0x04},\r
+       {0x822f,0x15},\r
+       {0x8230,0x0c},\r
+       {0x8231,0x80},\r
+       {0x8232,0x45},\r
+       {0x8233,0x12},\r
+       {0x8234,0x04},\r
+       {0x8235,0x07},\r
+       {0x8236,0x12},\r
+       {0x8237,0x04},\r
+       {0x8238,0x4d},\r
+       {0x8239,0x85},\r
+       {0x823a,0x0b},\r
+       {0x823b,0x0d},\r
+       {0x823c,0x12},\r
+       {0x823d,0x0a},\r
+       {0x823e,0x9b},\r
+       {0x823f,0xc2},\r
+       {0x8240,0x0f},\r
+       {0x8241,0x12},\r
+       {0x8242,0x04},\r
+       {0x8243,0x4f},\r
+       {0x8244,0x75},\r
+       {0x8245,0x32},\r
+       {0x8246,0x0a},\r
+       {0x8247,0xaf},\r
+       {0x8248,0x32},\r
+       {0x8249,0x15},\r
+       {0x824a,0x32},\r
+       {0x824b,0xef},\r
+       {0x824c,0x70},\r
+       {0x824d,0xf9},\r
+       {0x824e,0xd2},\r
+       {0x824f,0x18},\r
+       {0x8250,0x12},\r
+       {0x8251,0x04},\r
+       {0x8252,0x09},\r
+       {0x8253,0x12},\r
+       {0x8254,0x04},\r
+       {0x8255,0x97},\r
+       {0x8256,0xaf},\r
+       {0x8257,0x32},\r
+       {0x8258,0x15},\r
+       {0x8259,0x32},\r
+       {0x825a,0xef},\r
+       {0x825b,0x70},\r
+       {0x825c,0xf9},\r
+       {0x825d,0xc2},\r
+       {0x825e,0x18},\r
+       {0x825f,0x12},\r
+       {0x8260,0x04},\r
+       {0x8261,0x09},\r
+       {0x8262,0x75},\r
+       {0x8263,0x32},\r
+       {0x8264,0x0a},\r
+       {0x8265,0xaf},\r
+       {0x8266,0x32},\r
+       {0x8267,0x15},\r
+       {0x8268,0x32},\r
+       {0x8269,0xef},\r
+       {0x826a,0x70},\r
+       {0x826b,0xf9},\r
+       {0x826c,0x30},\r
+       {0x826d,0x11},\r
+       {0x826e,0x06},\r
+       {0x826f,0x15},\r
+       {0x8270,0x0c},\r
+       {0x8271,0xd2},\r
+       {0x8272,0x23},\r
+       {0x8273,0x80},\r
+       {0x8274,0x03},\r
+       {0x8275,0xe4},\r
+       {0x8276,0xf5},\r
+       {0x8277,0x0c},\r
+       {0x8278,0x12},\r
+       {0x8279,0x04},\r
+       {0x827a,0x07},\r
+       {0x827b,0x12},\r
+       {0x827c,0x04},\r
+       {0x827d,0x4d},\r
+       {0x827e,0xc2},\r
+       {0x827f,0x19},\r
+       {0x8280,0x12},\r
+       {0x8281,0x04},\r
+       {0x8282,0x09},\r
+       {0x8283,0x75},\r
+       {0x8284,0x32},\r
+       {0x8285,0x05},\r
+       {0x8286,0xaf},\r
+       {0x8287,0x32},\r
+       {0x8288,0x15},\r
+       {0x8289,0x32},\r
+       {0x828a,0xef},\r
+       {0x828b,0x70},\r
+       {0x828c,0xf9},\r
+       {0x828d,0xd2},\r
+       {0x828e,0x18},\r
+       {0x828f,0x12},\r
+       {0x8290,0x04},\r
+       {0x8291,0x09},\r
+       {0x8292,0x75},\r
+       {0x8293,0x32},\r
+       {0x8294,0x05},\r
+       {0x8295,0xaf},\r
+       {0x8296,0x32},\r
+       {0x8297,0x15},\r
+       {0x8298,0x32},\r
+       {0x8299,0xef},\r
+       {0x829a,0x70},\r
+       {0x829b,0xf9},\r
+       {0x829c,0x12},\r
+       {0x829d,0x04},\r
+       {0x829e,0x07},\r
+       {0x829f,0x75},\r
+       {0x82a0,0x32},\r
+       {0x82a1,0x05},\r
+       {0x82a2,0xaf},\r
+       {0x82a3,0x32},\r
+       {0x82a4,0x15},\r
+       {0x82a5,0x32},\r
+       {0x82a6,0xef},\r
+       {0x82a7,0x70},\r
+       {0x82a8,0xf9},\r
+       {0x82a9,0xa2},\r
+       {0x82aa,0x22},\r
+       {0x82ab,0x92},\r
+       {0x82ac,0xaf},\r
+       {0x82ad,0xe5},\r
+       {0x82ae,0x0c},\r
+       {0x82af,0xd3},\r
+       {0x82b0,0x94},\r
+       {0x82b1,0x00},\r
+       {0x82b2,0x40},\r
+       {0x82b3,0x03},\r
+       {0x82b4,0x02},\r
+       {0x82b5,0x01},\r
+       {0x82b6,0x7f},\r
+       {0x82b7,0x22},\r
+       {0x82b8,0x12},\r
+       {0x82b9,0x0a},\r
+       {0x82ba,0x9b},\r
+       {0x82bb,0xc2},\r
+       {0x82bc,0x0f},\r
+       {0x82bd,0x90},\r
+       {0x82be,0x30},\r
+       {0x82bf,0xb1},\r
+       {0x82c0,0xe5},\r
+       {0x82c1,0x21},\r
+       {0x82c2,0xf0},\r
+       {0x82c3,0x22},\r
+       {0x82c4,0x90},\r
+       {0x82c5,0x33},\r
+       {0x82c6,0x5f},\r
+       {0x82c7,0xe0},\r
+       {0x82c8,0x54},\r
+       {0x82c9,0x0f},\r
+       {0x82ca,0xfe},\r
+       {0x82cb,0xa3},\r
+       {0x82cc,0xe0},\r
+       {0x82cd,0xfd},\r
+       {0x82ce,0xed},\r
+       {0x82cf,0xff},\r
+       {0x82d0,0xee},\r
+       {0x82d1,0x54},\r
+       {0x82d2,0x0f},\r
+       {0x82d3,0xf5},\r
+       {0x82d4,0x0d},\r
+       {0x82d5,0x8f},\r
+       {0x82d6,0x0e},\r
+       {0x82d7,0x90},\r
+       {0x82d8,0x33},\r
+       {0x82d9,0x5f},\r
+       {0x82da,0xe0},\r
+       {0x82db,0x54},\r
+       {0x82dc,0x70},\r
+       {0x82dd,0x75},\r
+       {0x82de,0xf0},\r
+       {0x82df,0x10},\r
+       {0x82e0,0xa4},\r
+       {0x82e1,0xff},\r
+       {0x82e2,0x90},\r
+       {0x82e3,0x33},\r
+       {0x82e4,0x61},\r
+       {0x82e5,0xe0},\r
+       {0x82e6,0xfd},\r
+       {0x82e7,0xef},\r
+       {0x82e8,0x4d},\r
+       {0x82e9,0xff},\r
+       {0x82ea,0xe5},\r
+       {0x82eb,0xf0},\r
+       {0x82ec,0x54},\r
+       {0x82ed,0x07},\r
+       {0x82ee,0xf5},\r
+       {0x82ef,0x0f},\r
+       {0x82f0,0x8f},\r
+       {0x82f1,0x10},\r
+       {0x82f2,0xe5},\r
+       {0x82f3,0x0e},\r
+       {0x82f4,0xae},\r
+       {0x82f5,0x0d},\r
+       {0x82f6,0x78},\r
+       {0x82f7,0x05},\r
+       {0x82f8,0xce},\r
+       {0x82f9,0xc3},\r
+       {0x82fa,0x13},\r
+       {0x82fb,0xce},\r
+       {0x82fc,0x13},\r
+       {0x82fd,0xd8},\r
+       {0x82fe,0xf9},\r
+       {0x82ff,0xf5},\r
+       {0x8300,0x0e},\r
+       {0x8301,0x8e},\r
+       {0x8302,0x0d},\r
+       {0x8303,0xe5},\r
+       {0x8304,0x10},\r
+       {0x8305,0xae},\r
+       {0x8306,0x0f},\r
+       {0x8307,0x78},\r
+       {0x8308,0x03},\r
+       {0x8309,0xce},\r
+       {0x830a,0xc3},\r
+       {0x830b,0x13},\r
+       {0x830c,0xce},\r
+       {0x830d,0x13},\r
+       {0x830e,0xd8},\r
+       {0x830f,0xf9},\r
+       {0x8310,0xf5},\r
+       {0x8311,0x10},\r
+       {0x8312,0x8e},\r
+       {0x8313,0x0f},\r
+       {0x8314,0x85},\r
+       {0x8315,0x2a},\r
+       {0x8316,0x11},\r
+       {0x8317,0x85},\r
+       {0x8318,0x2b},\r
+       {0x8319,0x13},\r
+       {0x831a,0x85},\r
+       {0x831b,0x2c},\r
+       {0x831c,0x12},\r
+       {0x831d,0x85},\r
+       {0x831e,0x2d},\r
+       {0x831f,0x14},\r
+       {0x8320,0x12},\r
+       {0x8321,0x04},\r
+       {0x8322,0xab},\r
+       {0x8323,0xaf},\r
+       {0x8324,0x11},\r
+       {0x8325,0x12},\r
+       {0x8326,0x03},\r
+       {0x8327,0xdf},\r
+       {0x8328,0x8f},\r
+       {0x8329,0x11},\r
+       {0x832a,0x12},\r
+       {0x832b,0x04},\r
+       {0x832c,0xab},\r
+       {0x832d,0xaf},\r
+       {0x832e,0x12},\r
+       {0x832f,0x12},\r
+       {0x8330,0x03},\r
+       {0x8331,0xdf},\r
+       {0x8332,0x8f},\r
+       {0x8333,0x12},\r
+       {0x8334,0x12},\r
+       {0x8335,0x04},\r
+       {0x8336,0x56},\r
+       {0x8337,0xaf},\r
+       {0x8338,0x13},\r
+       {0x8339,0xfc},\r
+       {0x833a,0xfd},\r
+       {0x833b,0xfe},\r
+       {0x833c,0x12},\r
+       {0x833d,0x00},\r
+       {0x833e,0x16},\r
+       {0x833f,0x12},\r
+       {0x8340,0x03},\r
+       {0x8341,0xfe},\r
+       {0x8342,0x7b},\r
+       {0x8343,0x1e},\r
+       {0x8344,0x12},\r
+       {0x8345,0x03},\r
+       {0x8346,0xf7},\r
+       {0x8347,0x8f},\r
+       {0x8348,0x13},\r
+       {0x8349,0x12},\r
+       {0x834a,0x04},\r
+       {0x834b,0x56},\r
+       {0x834c,0xaf},\r
+       {0x834d,0x14},\r
+       {0x834e,0xfc},\r
+       {0x834f,0xfd},\r
+       {0x8350,0xfe},\r
+       {0x8351,0x12},\r
+       {0x8352,0x00},\r
+       {0x8353,0x16},\r
+       {0x8354,0x12},\r
+       {0x8355,0x03},\r
+       {0x8356,0xfe},\r
+       {0x8357,0xe4},\r
+       {0x8358,0x7b},\r
+       {0x8359,0x1e},\r
+       {0x835a,0x12},\r
+       {0x835b,0x03},\r
+       {0x835c,0xf8},\r
+       {0x835d,0x8f},\r
+       {0x835e,0x14},\r
+       {0x835f,0xc3},\r
+       {0x8360,0xe5},\r
+       {0x8361,0x12},\r
+       {0x8362,0x95},\r
+       {0x8363,0x11},\r
+       {0x8364,0xff},\r
+       {0x8365,0x0f},\r
+       {0x8366,0xef},\r
+       {0x8367,0xc3},\r
+       {0x8368,0x13},\r
+       {0x8369,0xff},\r
+       {0x836a,0xc3},\r
+       {0x836b,0x94},\r
+       {0x836c,0x02},\r
+       {0x836d,0x50},\r
+       {0x836e,0x27},\r
+       {0x836f,0xe5},\r
+       {0x8370,0x11},\r
+       {0x8371,0x9f},\r
+       {0x8372,0x40},\r
+       {0x8373,0x06},\r
+       {0x8374,0xe5},\r
+       {0x8375,0x11},\r
+       {0x8376,0x9f},\r
+       {0x8377,0xfe},\r
+       {0x8378,0x80},\r
+       {0x8379,0x02},\r
+       {0x837a,0x7e},\r
+       {0x837b,0x00},\r
+       {0x837c,0x8e},\r
+       {0x837d,0x11},\r
+       {0x837e,0xef},\r
+       {0x837f,0xfd},\r
+       {0x8380,0xe5},\r
+       {0x8381,0x12},\r
+       {0x8382,0x2d},\r
+       {0x8383,0xfd},\r
+       {0x8384,0xe4},\r
+       {0x8385,0x33},\r
+       {0x8386,0xfc},\r
+       {0x8387,0xc3},\r
+       {0x8388,0xed},\r
+       {0x8389,0x95},\r
+       {0x838a,0x0e},\r
+       {0x838b,0xec},\r
+       {0x838c,0x95},\r
+       {0x838d,0x0d},\r
+       {0x838e,0x50},\r
+       {0x838f,0x02},\r
+       {0x8390,0x80},\r
+       {0x8391,0x02},\r
+       {0x8392,0xad},\r
+       {0x8393,0x0e},\r
+       {0x8394,0x8d},\r
+       {0x8395,0x12},\r
+       {0x8396,0xc3},\r
+       {0x8397,0xe5},\r
+       {0x8398,0x14},\r
+       {0x8399,0x95},\r
+       {0x839a,0x13},\r
+       {0x839b,0xff},\r
+       {0x839c,0xc3},\r
+       {0x839d,0x94},\r
+       {0x839e,0x08},\r
+       {0x839f,0x50},\r
+       {0x83a0,0x29},\r
+       {0x83a1,0xe5},\r
+       {0x83a2,0x13},\r
+       {0x83a3,0x9f},\r
+       {0x83a4,0x40},\r
+       {0x83a5,0x06},\r
+       {0x83a6,0xe5},\r
+       {0x83a7,0x13},\r
+       {0x83a8,0x9f},\r
+       {0x83a9,0xfe},\r
+       {0x83aa,0x80},\r
+       {0x83ab,0x02},\r
+       {0x83ac,0x7e},\r
+       {0x83ad,0x00},\r
+       {0x83ae,0x8e},\r
+       {0x83af,0x13},\r
+       {0x83b0,0xef},\r
+       {0x83b1,0xfd},\r
+       {0x83b2,0xe5},\r
+       {0x83b3,0x14},\r
+       {0x83b4,0x2d},\r
+       {0x83b5,0xfd},\r
+       {0x83b6,0xe4},\r
+       {0x83b7,0x33},\r
+       {0x83b8,0xfc},\r
+       {0x83b9,0xc3},\r
+       {0x83ba,0xed},\r
+       {0x83bb,0x95},\r
+       {0x83bc,0x10},\r
+       {0x83bd,0xec},\r
+       {0x83be,0x95},\r
+       {0x83bf,0x0f},\r
+       {0x83c0,0x50},\r
+       {0x83c1,0x04},\r
+       {0x83c2,0xaf},\r
+       {0x83c3,0x05},\r
+       {0x83c4,0x80},\r
+       {0x83c5,0x02},\r
+       {0x83c6,0xaf},\r
+       {0x83c7,0x10},\r
+       {0x83c8,0x8f},\r
+       {0x83c9,0x14},\r
+       {0x83ca,0x90},\r
+       {0x83cb,0x39},\r
+       {0x83cc,0x0a},\r
+       {0x83cd,0xe5},\r
+       {0x83ce,0x11},\r
+       {0x83cf,0xf0},\r
+       {0x83d0,0xa3},\r
+       {0x83d1,0xe5},\r
+       {0x83d2,0x13},\r
+       {0x83d3,0xf0},\r
+       {0x83d4,0xa3},\r
+       {0x83d5,0xe5},\r
+       {0x83d6,0x12},\r
+       {0x83d7,0xf0},\r
+       {0x83d8,0xa3},\r
+       {0x83d9,0xe5},\r
+       {0x83da,0x14},\r
+       {0x83db,0xf0},\r
+       {0x83dc,0xc2},\r
+       {0x83dd,0x20},\r
+       {0x83de,0x22},\r
+       {0x83df,0xab},\r
+       {0x83e0,0x0c},\r
+       {0x83e1,0xaa},\r
+       {0x83e2,0x0b},\r
+       {0x83e3,0xa9},\r
+       {0x83e4,0x0a},\r
+       {0x83e5,0xa8},\r
+       {0x83e6,0x09},\r
+       {0x83e7,0xfc},\r
+       {0x83e8,0xfd},\r
+       {0x83e9,0xfe},\r
+       {0x83ea,0x12},\r
+       {0x83eb,0x00},\r
+       {0x83ec,0x16},\r
+       {0x83ed,0x8f},\r
+       {0x83ee,0x0c},\r
+       {0x83ef,0x8e},\r
+       {0x83f0,0x0b},\r
+       {0x83f1,0x8d},\r
+       {0x83f2,0x0a},\r
+       {0x83f3,0x8c},\r
+       {0x83f4,0x09},\r
+       {0x83f5,0x7b},\r
+       {0x83f6,0x28},\r
+       {0x83f7,0xe4},\r
+       {0x83f8,0xfa},\r
+       {0x83f9,0xf9},\r
+       {0x83fa,0xf8},\r
+       {0x83fb,0x12},\r
+       {0x83fc,0x00},\r
+       {0x83fd,0xa1},\r
+       {0x83fe,0x8f},\r
+       {0x83ff,0x0c},\r
+       {0x8400,0x8e},\r
+       {0x8401,0x0b},\r
+       {0x8402,0x8d},\r
+       {0x8403,0x0a},\r
+       {0x8404,0x8c},\r
+       {0x8405,0x09},\r
+       {0x8406,0x22},\r
+       {0x8407,0xd2},\r
+       {0x8408,0x19},\r
+       {0x8409,0x90},\r
+       {0x840a,0x30},\r
+       {0x840b,0xb4},\r
+       {0x840c,0xe5},\r
+       {0x840d,0x23},\r
+       {0x840e,0xf0},\r
+       {0x840f,0x22},\r
+       {0x8410,0x85},\r
+       {0x8411,0x2f},\r
+       {0x8412,0x82},\r
+       {0x8413,0x85},\r
+       {0x8414,0x2e},\r
+       {0x8415,0x83},\r
+       {0x8416,0xe5},\r
+       {0x8417,0x43},\r
+       {0x8418,0x75},\r
+       {0x8419,0xf0},\r
+       {0x841a,0x02},\r
+       {0x841b,0x12},\r
+       {0x841c,0x01},\r
+       {0x841d,0x46},\r
+       {0x841e,0xe4},\r
+       {0x841f,0x93},\r
+       {0x8420,0xfe},\r
+       {0x8421,0x74},\r
+       {0x8422,0x01},\r
+       {0x8423,0x93},\r
+       {0x8424,0xff},\r
+       {0x8425,0x85},\r
+       {0x8426,0x2f},\r
+       {0x8427,0x82},\r
+       {0x8428,0x85},\r
+       {0x8429,0x2e},\r
+       {0x842a,0x83},\r
+       {0x842b,0xe4},\r
+       {0x842c,0x93},\r
+       {0x842d,0xfc},\r
+       {0x842e,0x74},\r
+       {0x842f,0x01},\r
+       {0x8430,0x93},\r
+       {0x8431,0xfd},\r
+       {0x8432,0xc3},\r
+       {0x8433,0xef},\r
+       {0x8434,0x9d},\r
+       {0x8435,0xff},\r
+       {0x8436,0xee},\r
+       {0x8437,0x9c},\r
+       {0x8438,0x22},\r
+       {0x8439,0x12},\r
+       {0x843a,0x00},\r
+       {0x843b,0x16},\r
+       {0x843c,0x8f},\r
+       {0x843d,0x3c},\r
+       {0x843e,0x8e},\r
+       {0x843f,0x3b},\r
+       {0x8440,0x8d},\r
+       {0x8441,0x3a},\r
+       {0x8442,0x8c},\r
+       {0x8443,0x39},\r
+       {0x8444,0xaf},\r
+       {0x8445,0x3c},\r
+       {0x8446,0xae},\r
+       {0x8447,0x3b},\r
+       {0x8448,0xad},\r
+       {0x8449,0x3a},\r
+       {0x844a,0xac},\r
+       {0x844b,0x39},\r
+       {0x844c,0x22},\r
+       {0x844d,0xd2},\r
+       {0x844e,0x0f},\r
+       {0x844f,0x90},\r
+       {0x8450,0x30},\r
+       {0x8451,0xb1},\r
+       {0x8452,0xe5},\r
+       {0x8453,0x21},\r
+       {0x8454,0xf0},\r
+       {0x8455,0x22},\r
+       {0x8456,0xe4},\r
+       {0x8457,0x85},\r
+       {0x8458,0x10},\r
+       {0x8459,0x0c},\r
+       {0x845a,0x85},\r
+       {0x845b,0x0f},\r
+       {0x845c,0x0b},\r
+       {0x845d,0xf5},\r
+       {0x845e,0x0a},\r
+       {0x845f,0xf5},\r
+       {0x8460,0x09},\r
+       {0x8461,0xab},\r
+       {0x8462,0x0c},\r
+       {0x8463,0xaa},\r
+       {0x8464,0x0b},\r
+       {0x8465,0xa9},\r
+       {0x8466,0x0a},\r
+       {0x8467,0xa8},\r
+       {0x8468,0x09},\r
+       {0x8469,0x22},\r
+       {0x846a,0x85},\r
+       {0x846b,0x2f},\r
+       {0x846c,0x82},\r
+       {0x846d,0x85},\r
+       {0x846e,0x2e},\r
+       {0x846f,0x83},\r
+       {0x8470,0x22},\r
+       {0x8471,0xff},\r
+       {0x8472,0xe4},\r
+       {0x8473,0x94},\r
+       {0x8474,0x00},\r
+       {0x8475,0xfe},\r
+       {0x8476,0xe4},\r
+       {0x8477,0xfc},\r
+       {0x8478,0xfd},\r
+       {0x8479,0x02},\r
+       {0x847a,0x01},\r
+       {0x847b,0x33},\r
+       {0x847c,0xc2},\r
+       {0x847d,0x07},\r
+       {0x847e,0xc2},\r
+       {0x847f,0x06},\r
+       {0x8480,0xc2},\r
+       {0x8481,0x02},\r
+       {0x8482,0xc2},\r
+       {0x8483,0x01},\r
+       {0x8484,0xc2},\r
+       {0x8485,0x00},\r
+       {0x8486,0xc2},\r
+       {0x8487,0x03},\r
+       {0x8488,0xd2},\r
+       {0x8489,0x04},\r
+       {0x848a,0x22},\r
+       {0x848b,0x90},\r
+       {0x848c,0x33},\r
+       {0x848d,0xb3},\r
+       {0x848e,0xe4},\r
+       {0x848f,0xf0},\r
+       {0x8490,0xa3},\r
+       {0x8491,0xf0},\r
+       {0x8492,0xa3},\r
+       {0x8493,0xf0},\r
+       {0x8494,0xa3},\r
+       {0x8495,0xf0},\r
+       {0x8496,0x22},\r
+       {0x8497,0xa3},\r
+       {0x8498,0xe0},\r
+       {0x8499,0xf5},\r
+       {0x849a,0x22},\r
+       {0x849b,0x75},\r
+       {0x849c,0x32},\r
+       {0x849d,0x0a},\r
+       {0x849e,0x22},\r
+       {0x849f,0x12},\r
+       {0x84a0,0x00},\r
+       {0x84a1,0xa1},\r
+       {0x84a2,0x8f},\r
+       {0x84a3,0x3c},\r
+       {0x84a4,0x8e},\r
+       {0x84a5,0x3b},\r
+       {0x84a6,0x8d},\r
+       {0x84a7,0x3a},\r
+       {0x84a8,0x8c},\r
+       {0x84a9,0x39},\r
+       {0x84aa,0x22},\r
+       {0x84ab,0xe4},\r
+       {0x84ac,0x85},\r
+       {0x84ad,0x0e},\r
+       {0x84ae,0x0c},\r
+       {0x84af,0x85},\r
+       {0x84b0,0x0d},\r
+       {0x84b1,0x0b},\r
+       {0x84b2,0xf5},\r
+       {0x84b3,0x0a},\r
+       {0x84b4,0xf5},\r
+       {0x84b5,0x09},\r
+       {0x84b6,0x22},\r
+       {0x84b7,0xe4},\r
+       {0x84b8,0xfc},\r
+       {0x84b9,0xfd},\r
+       {0x84ba,0xfe},\r
+       {0x84bb,0x02},\r
+       {0x84bc,0x01},\r
+       {0x84bd,0x33},\r
+       {0x84be,0x90},\r
+       {0x84bf,0x0b},\r
+       {0x84c0,0x4c},\r
+       {0x84c1,0xe4},\r
+       {0x84c2,0x93},\r
+       {0x84c3,0xff},\r
+       {0x84c4,0x90},\r
+       {0x84c5,0x30},\r
+       {0x84c6,0x0a},\r
+       {0x84c7,0xe0},\r
+       {0x84c8,0x22},\r
+       {0x84c9,0xc2},\r
+       {0x84ca,0x02},\r
+       {0x84cb,0xc2},\r
+       {0x84cc,0x01},\r
+       {0x84cd,0xd2},\r
+       {0x84ce,0x00},\r
+       {0x84cf,0xc2},\r
+       {0x84d0,0x03},\r
+       {0x84d1,0xc2},\r
+       {0x84d2,0x04},\r
+       {0x84d3,0x22},\r
+       {0x84d4,0x75},\r
+       {0x84d5,0xf0},\r
+       {0x84d6,0x02},\r
+       {0x84d7,0x02},\r
+       {0x84d8,0x01},\r
+       {0x84d9,0x46},\r
+       {0x84da,0xe4},\r
+       {0x84db,0x93},\r
+       {0x84dc,0xf5},\r
+       {0x84dd,0x43},\r
+       {0x84de,0xa3},\r
+       {0x84df,0xe4},\r
+       {0x84e0,0x93},\r
+       {0x84e1,0xf5},\r
+       {0x84e2,0x28},\r
+       {0x84e3,0x22},\r
+       {0x84e4,0xd2},\r
+       {0x84e5,0x02},\r
+       {0x84e6,0xd2},\r
+       {0x84e7,0x01},\r
+       {0x84e8,0xc2},\r
+       {0x84e9,0x00},\r
+       {0x84ea,0x22},\r
+       {0x84eb,0xd3},\r
+       {0x84ec,0xe5},\r
+       {0x84ed,0x3c},\r
+       {0x84ee,0x94},\r
+       {0x84ef,0xff},\r
+       {0x84f0,0xe5},\r
+       {0x84f1,0x3b},\r
+       {0x84f2,0x94},\r
+       {0x84f3,0x03},\r
+       {0x84f4,0x22},\r
+       {0x84f5,0x30},\r
+       {0x84f6,0x04},\r
+       {0x84f7,0x03},\r
+       {0x84f8,0x02},\r
+       {0x84f9,0x05},\r
+       {0x84fa,0xd5},\r
+       {0x84fb,0xd2},\r
+       {0x84fc,0x04},\r
+       {0x84fd,0xe5},\r
+       {0x84fe,0x45},\r
+       {0x84ff,0xb4},\r
+       {0x8500,0x01},\r
+       {0x8501,0x06},\r
+       {0x8502,0x12},\r
+       {0x8503,0x0c},\r
+       {0x8504,0xfe},\r
+       {0x8505,0x02},\r
+       {0x8506,0x05},\r
+       {0x8507,0xce},\r
+       {0x8508,0xe5},\r
+       {0x8509,0x45},\r
+       {0x850a,0xb4},\r
+       {0x850b,0x02},\r
+       {0x850c,0x06},\r
+       {0x850d,0x12},\r
+       {0x850e,0x0d},\r
+       {0x850f,0x0f},\r
+       {0x8510,0x02},\r
+       {0x8511,0x05},\r
+       {0x8512,0xce},\r
+       {0x8513,0xe5},\r
+       {0x8514,0x45},\r
+       {0x8515,0xb4},\r
+       {0x8516,0x03},\r
+       {0x8517,0x05},\r
+       {0x8518,0xe4},\r
+       {0x8519,0xf5},\r
+       {0x851a,0x09},\r
+       {0x851b,0x80},\r
+       {0x851c,0x08},\r
+       {0x851d,0xe5},\r
+       {0x851e,0x45},\r
+       {0x851f,0xb4},\r
+       {0x8520,0x04},\r
+       {0x8521,0x09},\r
+       {0x8522,0x85},\r
+       {0x8523,0x43},\r
+       {0x8524,0x09},\r
+       {0x8525,0x12},\r
+       {0x8526,0x09},\r
+       {0x8527,0xee},\r
+       {0x8528,0x02},\r
+       {0x8529,0x05},\r
+       {0x852a,0xce},\r
+       {0x852b,0xe5},\r
+       {0x852c,0x45},\r
+       {0x852d,0x64},\r
+       {0x852e,0x0f},\r
+       {0x852f,0x70},\r
+       {0x8530,0x15},\r
+       {0x8531,0x12},\r
+       {0x8532,0x04},\r
+       {0x8533,0xeb},\r
+       {0x8534,0x40},\r
+       {0x8535,0x06},\r
+       {0x8536,0x7e},\r
+       {0x8537,0x03},\r
+       {0x8538,0x7f},\r
+       {0x8539,0xff},\r
+       {0x853a,0x80},\r
+       {0x853b,0x04},\r
+       {0x853c,0xae},\r
+       {0x853d,0x3b},\r
+       {0x853e,0xaf},\r
+       {0x853f,0x3c},\r
+       {0x8540,0x12},\r
+       {0x8541,0x05},\r
+       {0x8542,0xd6},\r
+       {0x8543,0x02},\r
+       {0x8544,0x05},\r
+       {0x8545,0xce},\r
+       {0x8546,0xe5},\r
+       {0x8547,0x45},\r
+       {0x8548,0x64},\r
+       {0x8549,0x10},\r
+       {0x854a,0x60},\r
+       {0x854b,0x03},\r
+       {0x854c,0x02},\r
+       {0x854d,0x05},\r
+       {0x854e,0xce},\r
+       {0x854f,0xf5},\r
+       {0x8550,0x39},\r
+       {0x8551,0xf5},\r
+       {0x8552,0x3a},\r
+       {0x8553,0xf5},\r
+       {0x8554,0x3b},\r
+       {0x8555,0xab},\r
+       {0x8556,0x3c},\r
+       {0x8557,0xaa},\r
+       {0x8558,0x3b},\r
+       {0x8559,0xa9},\r
+       {0x855a,0x3a},\r
+       {0x855b,0xa8},\r
+       {0x855c,0x39},\r
+       {0x855d,0x12},\r
+       {0x855e,0x04},\r
+       {0x855f,0x10},\r
+       {0x8560,0xfe},\r
+       {0x8561,0xe4},\r
+       {0x8562,0xfc},\r
+       {0x8563,0xfd},\r
+       {0x8564,0x12},\r
+       {0x8565,0x04},\r
+       {0x8566,0x39},\r
+       {0x8567,0xe4},\r
+       {0x8568,0x7b},\r
+       {0x8569,0xff},\r
+       {0x856a,0xfa},\r
+       {0x856b,0xf9},\r
+       {0x856c,0xf8},\r
+       {0x856d,0x12},\r
+       {0x856e,0x04},\r
+       {0x856f,0x9f},\r
+       {0x8570,0x12},\r
+       {0x8571,0x04},\r
+       {0x8572,0x6a},\r
+       {0x8573,0xe4},\r
+       {0x8574,0x93},\r
+       {0x8575,0xfe},\r
+       {0x8576,0x74},\r
+       {0x8577,0x01},\r
+       {0x8578,0x93},\r
+       {0x8579,0xff},\r
+       {0x857a,0xe4},\r
+       {0x857b,0xfc},\r
+       {0x857c,0xfd},\r
+       {0x857d,0xe5},\r
+       {0x857e,0x3c},\r
+       {0x857f,0x2f},\r
+       {0x8580,0xf5},\r
+       {0x8581,0x3c},\r
+       {0x8582,0xe5},\r
+       {0x8583,0x3b},\r
+       {0x8584,0x3e},\r
+       {0x8585,0xf5},\r
+       {0x8586,0x3b},\r
+       {0x8587,0xed},\r
+       {0x8588,0x35},\r
+       {0x8589,0x3a},\r
+       {0x858a,0xf5},\r
+       {0x858b,0x3a},\r
+       {0x858c,0xec},\r
+       {0x858d,0x35},\r
+       {0x858e,0x39},\r
+       {0x858f,0xf5},\r
+       {0x8590,0x39},\r
+       {0x8591,0x12},\r
+       {0x8592,0x04},\r
+       {0x8593,0xeb},\r
+       {0x8594,0x40},\r
+       {0x8595,0x06},\r
+       {0x8596,0x7e},\r
+       {0x8597,0x03},\r
+       {0x8598,0x7f},\r
+       {0x8599,0xff},\r
+       {0x859a,0x80},\r
+       {0x859b,0x04},\r
+       {0x859c,0xae},\r
+       {0x859d,0x3b},\r
+       {0x859e,0xaf},\r
+       {0x859f,0x3c},\r
+       {0x85a0,0x12},\r
+       {0x85a1,0x05},\r
+       {0x85a2,0xd6},\r
+       {0x85a3,0xe4},\r
+       {0x85a4,0xf5},\r
+       {0x85a5,0x3a},\r
+       {0x85a6,0xf5},\r
+       {0x85a7,0x3a},\r
+       {0x85a8,0xe5},\r
+       {0x85a9,0x3a},\r
+       {0x85aa,0xd3},\r
+       {0x85ab,0x95},\r
+       {0x85ac,0x43},\r
+       {0x85ad,0x50},\r
+       {0x85ae,0x1c},\r
+       {0x85af,0x12},\r
+       {0x85b0,0x04},\r
+       {0x85b1,0x6a},\r
+       {0x85b2,0xaf},\r
+       {0x85b3,0x3a},\r
+       {0x85b4,0x75},\r
+       {0x85b5,0xf0},\r
+       {0x85b6,0x02},\r
+       {0x85b7,0xef},\r
+       {0x85b8,0x12},\r
+       {0x85b9,0x01},\r
+       {0x85ba,0x46},\r
+       {0x85bb,0xc3},\r
+       {0x85bc,0x74},\r
+       {0x85bd,0x01},\r
+       {0x85be,0x93},\r
+       {0x85bf,0x95},\r
+       {0x85c0,0x3c},\r
+       {0x85c1,0xe4},\r
+       {0x85c2,0x93},\r
+       {0x85c3,0x95},\r
+       {0x85c4,0x3b},\r
+       {0x85c5,0x50},\r
+       {0x85c6,0x04},\r
+       {0x85c7,0x05},\r
+       {0x85c8,0x3a},\r
+       {0x85c9,0x80},\r
+       {0x85ca,0xdd},\r
+       {0x85cb,0x85},\r
+       {0x85cc,0x3a},\r
+       {0x85cd,0x44},\r
+       {0x85ce,0x90},\r
+       {0x85cf,0x3f},\r
+       {0x85d0,0x01},\r
+       {0x85d1,0xe4},\r
+       {0x85d2,0xf0},\r
+       {0x85d3,0xd2},\r
+       {0x85d4,0x25},\r
+       {0x85d5,0x22},\r
+       {0x85d6,0x8e},\r
+       {0x85d7,0x3b},\r
+       {0x85d8,0x8f},\r
+       {0x85d9,0x3c},\r
+       {0x85da,0x85},\r
+       {0x85db,0x3b},\r
+       {0x85dc,0x37},\r
+       {0x85dd,0x85},\r
+       {0x85de,0x3c},\r
+       {0x85df,0x38},\r
+       {0x85e0,0xe5},\r
+       {0x85e1,0x3c},\r
+       {0x85e2,0xc4},\r
+       {0x85e3,0xf8},\r
+       {0x85e4,0x54},\r
+       {0x85e5,0x0f},\r
+       {0x85e6,0xc8},\r
+       {0x85e7,0x68},\r
+       {0x85e8,0xf5},\r
+       {0x85e9,0x3c},\r
+       {0x85ea,0xe5},\r
+       {0x85eb,0x3b},\r
+       {0x85ec,0xc4},\r
+       {0x85ed,0x54},\r
+       {0x85ee,0xf0},\r
+       {0x85ef,0x48},\r
+       {0x85f0,0xf5},\r
+       {0x85f1,0x3b},\r
+       {0x85f2,0x85},\r
+       {0x85f3,0x3b},\r
+       {0x85f4,0x0a},\r
+       {0x85f5,0x85},\r
+       {0x85f6,0x3c},\r
+       {0x85f7,0x0b},\r
+       {0x85f8,0x12},\r
+       {0x85f9,0x01},\r
+       {0x85fa,0x78},\r
+       {0x85fb,0x22},\r
+       {0x85fc,0xe5},\r
+       {0x85fd,0x29},\r
+       {0x85fe,0x70},\r
+       {0x85ff,0x03},\r
+       {0x8600,0x02},\r
+       {0x8601,0x06},\r
+       {0x8602,0xd4},\r
+       {0x8603,0xc2},\r
+       {0x8604,0xaf},\r
+       {0x8605,0xaf},\r
+       {0x8606,0x29},\r
+       {0x8607,0xe4},\r
+       {0x8608,0xf5},\r
+       {0x8609,0x29},\r
+       {0x860a,0xd2},\r
+       {0x860b,0xaf},\r
+       {0x860c,0x90},\r
+       {0x860d,0x3f},\r
+       {0x860e,0x01},\r
+       {0x860f,0xe0},\r
+       {0x8610,0xf5},\r
+       {0x8611,0x45},\r
+       {0x8612,0xa3},\r
+       {0x8613,0xe0},\r
+       {0x8614,0xf5},\r
+       {0x8615,0x39},\r
+       {0x8616,0xa3},\r
+       {0x8617,0xe0},\r
+       {0x8618,0xf5},\r
+       {0x8619,0x3a},\r
+       {0x861a,0xa3},\r
+       {0x861b,0xe0},\r
+       {0x861c,0xf5},\r
+       {0x861d,0x3b},\r
+       {0x861e,0xa3},\r
+       {0x861f,0xe0},\r
+       {0x8620,0xf5},\r
+       {0x8621,0x3c},\r
+       {0x8622,0xef},\r
+       {0x8623,0x12},\r
+       {0x8624,0x01},\r
+       {0x8625,0x52},\r
+       {0x8626,0x06},\r
+       {0x8627,0x4b},\r
+       {0x8628,0x03},\r
+       {0x8629,0x06},\r
+       {0x862a,0x5a},\r
+       {0x862b,0x05},\r
+       {0x862c,0x06},\r
+       {0x862d,0x81},\r
+       {0x862e,0x06},\r
+       {0x862f,0x06},\r
+       {0x8630,0x6f},\r
+       {0x8631,0x08},\r
+       {0x8632,0x06},\r
+       {0x8633,0xa2},\r
+       {0x8634,0x09},\r
+       {0x8635,0x06},\r
+       {0x8636,0x8e},\r
+       {0x8637,0x10},\r
+       {0x8638,0x06},\r
+       {0x8639,0xa2},\r
+       {0x863a,0x12},\r
+       {0x863b,0x06},\r
+       {0x863c,0xa7},\r
+       {0x863d,0x20},\r
+       {0x863e,0x06},\r
+       {0x863f,0xb5},\r
+       {0x8640,0x21},\r
+       {0x8641,0x06},\r
+       {0x8642,0xba},\r
+       {0x8643,0x30},\r
+       {0x8644,0x06},\r
+       {0x8645,0xc5},\r
+       {0x8646,0xd0},\r
+       {0x8647,0x00},\r
+       {0x8648,0x00},\r
+       {0x8649,0x06},\r
+       {0x864a,0xc9},\r
+       {0x864b,0x30},\r
+       {0x864c,0x05},\r
+       {0x864d,0x7b},\r
+       {0x864e,0x20},\r
+       {0x864f,0x00},\r
+       {0x8650,0x78},\r
+       {0x8651,0xd2},\r
+       {0x8652,0x07},\r
+       {0x8653,0xc2},\r
+       {0x8654,0x06},\r
+       {0x8655,0x12},\r
+       {0x8656,0x04},\r
+       {0x8657,0xc9},\r
+       {0x8658,0x80},\r
+       {0x8659,0x21},\r
+       {0x865a,0x30},\r
+       {0x865b,0x05},\r
+       {0x865c,0x6c},\r
+       {0x865d,0x20},\r
+       {0x865e,0x00},\r
+       {0x865f,0x69},\r
+       {0x8660,0xc2},\r
+       {0x8661,0x07},\r
+       {0x8662,0xd2},\r
+       {0x8663,0x06},\r
+       {0x8664,0xc2},\r
+       {0x8665,0x03},\r
+       {0x8666,0x12},\r
+       {0x8667,0x04},\r
+       {0x8668,0xe4},\r
+       {0x8669,0xc2},\r
+       {0x866a,0x04},\r
+       {0x866b,0xc2},\r
+       {0x866c,0x21},\r
+       {0x866d,0x80},\r
+       {0x866e,0x5a},\r
+       {0x866f,0x12},\r
+       {0x8670,0x04},\r
+       {0x8671,0x7c},\r
+       {0x8672,0x30},\r
+       {0x8673,0x05},\r
+       {0x8674,0x06},\r
+       {0x8675,0xe4},\r
+       {0x8676,0xf5},\r
+       {0x8677,0x09},\r
+       {0x8678,0x12},\r
+       {0x8679,0x09},\r
+       {0x867a,0xee},\r
+       {0x867b,0xc2},\r
+       {0x867c,0x21},\r
+       {0x867d,0xd2},\r
+       {0x867e,0x25},\r
+       {0x867f,0x80},\r
+       {0x8680,0x48},\r
+       {0x8681,0x30},\r
+       {0x8682,0x07},\r
+       {0x8683,0x45},\r
+       {0x8684,0x30},\r
+       {0x8685,0x06},\r
+       {0x8686,0x42},\r
+       {0x8687,0x12},\r
+       {0x8688,0x04},\r
+       {0x8689,0xc9},\r
+       {0x868a,0xd2},\r
+       {0x868b,0x21},\r
+       {0x868c,0x80},\r
+       {0x868d,0x3b},\r
+       {0x868e,0x20},\r
+       {0x868f,0x07},\r
+       {0x8690,0x03},\r
+       {0x8691,0x30},\r
+       {0x8692,0x06},\r
+       {0x8693,0x09},\r
+       {0x8694,0xe5},\r
+       {0x8695,0x45},\r
+       {0x8696,0x64},\r
+       {0x8697,0x0e},\r
+       {0x8698,0x70},\r
+       {0x8699,0x2f},\r
+       {0x869a,0x20},\r
+       {0x869b,0x00},\r
+       {0x869c,0x2c},\r
+       {0x869d,0x12},\r
+       {0x869e,0x06},\r
+       {0x869f,0xd5},\r
+       {0x86a0,0x80},\r
+       {0x86a1,0x27},\r
+       {0x86a2,0x12},\r
+       {0x86a3,0x02},\r
+       {0x86a4,0xc4},\r
+       {0x86a5,0x80},\r
+       {0x86a6,0x22},\r
+       {0x86a7,0x30},\r
+       {0x86a8,0x05},\r
+       {0x86a9,0x1f},\r
+       {0x86aa,0x20},\r
+       {0x86ab,0x07},\r
+       {0x86ac,0x1c},\r
+       {0x86ad,0x20},\r
+       {0x86ae,0x06},\r
+       {0x86af,0x19},\r
+       {0x86b0,0x12},\r
+       {0x86b1,0x0c},\r
+       {0x86b2,0xa6},\r
+       {0x86b3,0x80},\r
+       {0x86b4,0x14},\r
+       {0x86b5,0x12},\r
+       {0x86b6,0x09},\r
+       {0x86b7,0x85},\r
+       {0x86b8,0x80},\r
+       {0x86b9,0x0f},\r
+       {0x86ba,0x20},\r
+       {0x86bb,0x07},\r
+       {0x86bc,0x0c},\r
+       {0x86bd,0x20},\r
+       {0x86be,0x06},\r
+       {0x86bf,0x09},\r
+       {0x86c0,0x12},\r
+       {0x86c1,0x0d},\r
+       {0x86c2,0x3c},\r
+       {0x86c3,0x80},\r
+       {0x86c4,0x04},\r
+       {0x86c5,0xd2},\r
+       {0x86c6,0x26},\r
+       {0x86c7,0xc2},\r
+       {0x86c8,0x26},\r
+       {0x86c9,0x20},\r
+       {0x86ca,0x07},\r
+       {0x86cb,0x03},\r
+       {0x86cc,0x20},\r
+       {0x86cd,0x06},\r
+       {0x86ce,0x05},\r
+       {0x86cf,0x90},\r
+       {0x86d0,0x3f},\r
+       {0x86d1,0x01},\r
+       {0x86d2,0xe4},\r
+       {0x86d3,0xf0},\r
+       {0x86d4,0x22},\r
+       {0x86d5,0xe5},\r
+       {0x86d6,0x45},\r
+       {0x86d7,0x24},\r
+       {0x86d8,0xfe},\r
+       {0x86d9,0x60},\r
+       {0x86da,0x19},\r
+       {0x86db,0x14},\r
+       {0x86dc,0x60},\r
+       {0x86dd,0x2c},\r
+       {0x86de,0x24},\r
+       {0x86df,0x02},\r
+       {0x86e0,0x60},\r
+       {0x86e1,0x03},\r
+       {0x86e2,0x02},\r
+       {0x86e3,0x07},\r
+       {0x86e4,0xa8},\r
+       {0x86e5,0xe5},\r
+       {0x86e6,0x3c},\r
+       {0x86e7,0xd3},\r
+       {0x86e8,0x94},\r
+       {0x86e9,0x03},\r
+       {0x86ea,0x40},\r
+       {0x86eb,0x03},\r
+       {0x86ec,0x75},\r
+       {0x86ed,0x3c},\r
+       {0x86ee,0x03},\r
+       {0x86ef,0xe4},\r
+       {0x86f0,0xf5},\r
+       {0x86f1,0x09},\r
+       {0x86f2,0x80},\r
+       {0x86f3,0x0d},\r
+       {0x86f4,0xe5},\r
+       {0x86f5,0x3c},\r
+       {0x86f6,0xd3},\r
+       {0x86f7,0x94},\r
+       {0x86f8,0x05},\r
+       {0x86f9,0x40},\r
+       {0x86fa,0x03},\r
+       {0x86fb,0x75},\r
+       {0x86fc,0x3c},\r
+       {0x86fd,0x05},\r
+       {0x86fe,0x75},\r
+       {0x86ff,0x09},\r
+       {0x8700,0x01},\r
+       {0x8701,0x85},\r
+       {0x8702,0x3c},\r
+       {0x8703,0x0a},\r
+       {0x8704,0x12},\r
+       {0x8705,0x08},\r
+       {0x8706,0xfa},\r
+       {0x8707,0xd2},\r
+       {0x8708,0x20},\r
+       {0x8709,0x22},\r
+       {0x870a,0xe5},\r
+       {0x870b,0x39},\r
+       {0x870c,0xd3},\r
+       {0x870d,0x94},\r
+       {0x870e,0x28},\r
+       {0x870f,0x40},\r
+       {0x8710,0x04},\r
+       {0x8711,0x7f},\r
+       {0x8712,0x28},\r
+       {0x8713,0x80},\r
+       {0x8714,0x02},\r
+       {0x8715,0xaf},\r
+       {0x8716,0x39},\r
+       {0x8717,0x8f},\r
+       {0x8718,0x39},\r
+       {0x8719,0xe5},\r
+       {0x871a,0x3a},\r
+       {0x871b,0xd3},\r
+       {0x871c,0x94},\r
+       {0x871d,0x1e},\r
+       {0x871e,0x40},\r
+       {0x871f,0x04},\r
+       {0x8720,0x7f},\r
+       {0x8721,0x1e},\r
+       {0x8722,0x80},\r
+       {0x8723,0x02},\r
+       {0x8724,0xaf},\r
+       {0x8725,0x3a},\r
+       {0x8726,0x8f},\r
+       {0x8727,0x3a},\r
+       {0x8728,0xe5},\r
+       {0x8729,0x3b},\r
+       {0x872a,0xd3},\r
+       {0x872b,0x94},\r
+       {0x872c,0x28},\r
+       {0x872d,0x40},\r
+       {0x872e,0x04},\r
+       {0x872f,0x7f},\r
+       {0x8730,0x28},\r
+       {0x8731,0x80},\r
+       {0x8732,0x02},\r
+       {0x8733,0xaf},\r
+       {0x8734,0x3b},\r
+       {0x8735,0x8f},\r
+       {0x8736,0x3b},\r
+       {0x8737,0xe5},\r
+       {0x8738,0x3c},\r
+       {0x8739,0xd3},\r
+       {0x873a,0x94},\r
+       {0x873b,0x1e},\r
+       {0x873c,0x40},\r
+       {0x873d,0x04},\r
+       {0x873e,0x7f},\r
+       {0x873f,0x1e},\r
+       {0x8740,0x80},\r
+       {0x8741,0x02},\r
+       {0x8742,0xaf},\r
+       {0x8743,0x3c},\r
+       {0x8744,0x8f},\r
+       {0x8745,0x3c},\r
+       {0x8746,0xaf},\r
+       {0x8747,0x3a},\r
+       {0x8748,0x78},\r
+       {0x8749,0x10},\r
+       {0x874a,0x12},\r
+       {0x874b,0x04},\r
+       {0x874c,0xb7},\r
+       {0x874d,0xc0},\r
+       {0x874e,0x04},\r
+       {0x874f,0xc0},\r
+       {0x8750,0x05},\r
+       {0x8751,0xc0},\r
+       {0x8752,0x06},\r
+       {0x8753,0xc0},\r
+       {0x8754,0x07},\r
+       {0x8755,0xaf},\r
+       {0x8756,0x39},\r
+       {0x8757,0x78},\r
+       {0x8758,0x18},\r
+       {0x8759,0x12},\r
+       {0x875a,0x04},\r
+       {0x875b,0xb7},\r
+       {0x875c,0xd0},\r
+       {0x875d,0x03},\r
+       {0x875e,0xd0},\r
+       {0x875f,0x02},\r
+       {0x8760,0xd0},\r
+       {0x8761,0x01},\r
+       {0x8762,0xd0},\r
+       {0x8763,0x00},\r
+       {0x8764,0xef},\r
+       {0x8765,0x4b},\r
+       {0x8766,0xff},\r
+       {0x8767,0xee},\r
+       {0x8768,0x4a},\r
+       {0x8769,0xfe},\r
+       {0x876a,0xed},\r
+       {0x876b,0x49},\r
+       {0x876c,0xfd},\r
+       {0x876d,0xec},\r
+       {0x876e,0x48},\r
+       {0x876f,0xfc},\r
+       {0x8770,0xc0},\r
+       {0x8771,0x04},\r
+       {0x8772,0xc0},\r
+       {0x8773,0x05},\r
+       {0x8774,0xc0},\r
+       {0x8775,0x06},\r
+       {0x8776,0xc0},\r
+       {0x8777,0x07},\r
+       {0x8778,0xaf},\r
+       {0x8779,0x3b},\r
+       {0x877a,0xe4},\r
+       {0x877b,0xfc},\r
+       {0x877c,0xfd},\r
+       {0x877d,0xfe},\r
+       {0x877e,0x78},\r
+       {0x877f,0x08},\r
+       {0x8780,0x12},\r
+       {0x8781,0x01},\r
+       {0x8782,0x33},\r
+       {0x8783,0xd0},\r
+       {0x8784,0x03},\r
+       {0x8785,0xd0},\r
+       {0x8786,0x02},\r
+       {0x8787,0xd0},\r
+       {0x8788,0x01},\r
+       {0x8789,0xd0},\r
+       {0x878a,0x00},\r
+       {0x878b,0xef},\r
+       {0x878c,0x4b},\r
+       {0x878d,0xfb},\r
+       {0x878e,0xee},\r
+       {0x878f,0x4a},\r
+       {0x8790,0xfa},\r
+       {0x8791,0xed},\r
+       {0x8792,0x49},\r
+       {0x8793,0xf9},\r
+       {0x8794,0xec},\r
+       {0x8795,0x48},\r
+       {0x8796,0xf8},\r
+       {0x8797,0xaf},\r
+       {0x8798,0x3c},\r
+       {0x8799,0xeb},\r
+       {0x879a,0x4f},\r
+       {0x879b,0xf5},\r
+       {0x879c,0x2d},\r
+       {0x879d,0xea},\r
+       {0x879e,0xf5},\r
+       {0x879f,0x2c},\r
+       {0x87a0,0xe9},\r
+       {0x87a1,0xf5},\r
+       {0x87a2,0x2b},\r
+       {0x87a3,0xe8},\r
+       {0x87a4,0xf5},\r
+       {0x87a5,0x2a},\r
+       {0x87a6,0xd2},\r
+       {0x87a7,0x20},\r
+       {0x87a8,0x22},\r
+       {0x87a9,0xc0},\r
+       {0x87aa,0xe0},\r
+       {0x87ab,0xc0},\r
+       {0x87ac,0x83},\r
+       {0x87ad,0xc0},\r
+       {0x87ae,0x82},\r
+       {0x87af,0xc0},\r
+       {0x87b0,0xd0},\r
+       {0x87b1,0x75},\r
+       {0x87b2,0xd0},\r
+       {0x87b3,0x00},\r
+       {0x87b4,0xc0},\r
+       {0x87b5,0x00},\r
+       {0x87b6,0xc0},\r
+       {0x87b7,0x06},\r
+       {0x87b8,0xc0},\r
+       {0x87b9,0x07},\r
+       {0x87ba,0x90},\r
+       {0x87bb,0x37},\r
+       {0x87bc,0x08},\r
+       {0x87bd,0xe0},\r
+       {0x87be,0xf5},\r
+       {0x87bf,0x08},\r
+       {0x87c0,0xe5},\r
+       {0x87c1,0x08},\r
+       {0x87c2,0x30},\r
+       {0x87c3,0xe3},\r
+       {0x87c4,0x23},\r
+       {0x87c5,0x20},\r
+       {0x87c6,0x26},\r
+       {0x87c7,0x20},\r
+       {0x87c8,0x90},\r
+       {0x87c9,0x3a},\r
+       {0x87ca,0x00},\r
+       {0x87cb,0x74},\r
+       {0x87cc,0x81},\r
+       {0x87cd,0xf0},\r
+       {0x87ce,0x90},\r
+       {0x87cf,0x3a},\r
+       {0x87d0,0x03},\r
+       {0x87d1,0xe0},\r
+       {0x87d2,0xf5},\r
+       {0x87d3,0x3e},\r
+       {0x87d4,0xe0},\r
+       {0x87d5,0xf5},\r
+       {0x87d6,0x3d},\r
+       {0x87d7,0x90},\r
+       {0x87d8,0x3a},\r
+       {0x87d9,0x00},\r
+       {0x87da,0x74},\r
+       {0x87db,0x85},\r
+       {0x87dc,0xf0},\r
+       {0x87dd,0x90},\r
+       {0x87de,0x3a},\r
+       {0x87df,0x03},\r
+       {0x87e0,0xe0},\r
+       {0x87e1,0xf5},\r
+       {0x87e2,0x40},\r
+       {0x87e3,0xe0},\r
+       {0x87e4,0xf5},\r
+       {0x87e5,0x3f},\r
+       {0x87e6,0xd2},\r
+       {0x87e7,0x2f},\r
+       {0x87e8,0xe5},\r
+       {0x87e9,0x08},\r
+       {0x87ea,0x30},\r
+       {0x87eb,0xe5},\r
+       {0x87ec,0x56},\r
+       {0x87ed,0x90},\r
+       {0x87ee,0x30},\r
+       {0x87ef,0x1b},\r
+       {0x87f0,0xe0},\r
+       {0x87f1,0xf5},\r
+       {0x87f2,0x42},\r
+       {0x87f3,0xe5},\r
+       {0x87f4,0x41},\r
+       {0x87f5,0x24},\r
+       {0x87f6,0x02},\r
+       {0x87f7,0xff},\r
+       {0x87f8,0xe4},\r
+       {0x87f9,0x33},\r
+       {0x87fa,0xfe},\r
+       {0x87fb,0xc3},\r
+       {0x87fc,0xef},\r
+       {0x87fd,0x95},\r
+       {0x87fe,0x42},\r
+       {0x87ff,0x74},\r
+       {0x8800,0x80},\r
+       {0x8801,0xf8},\r
+       {0x8802,0x6e},\r
+       {0x8803,0x98},\r
+       {0x8804,0x50},\r
+       {0x8805,0x02},\r
+       {0x8806,0x80},\r
+       {0x8807,0x01},\r
+       {0x8808,0xc3},\r
+       {0x8809,0x92},\r
+       {0x880a,0x24},\r
+       {0x880b,0xe5},\r
+       {0x880c,0x42},\r
+       {0x880d,0x24},\r
+       {0x880e,0x02},\r
+       {0x880f,0xff},\r
+       {0x8810,0xe4},\r
+       {0x8811,0x33},\r
+       {0x8812,0xfe},\r
+       {0x8813,0xc3},\r
+       {0x8814,0xef},\r
+       {0x8815,0x95},\r
+       {0x8816,0x41},\r
+       {0x8817,0x74},\r
+       {0x8818,0x80},\r
+       {0x8819,0xf8},\r
+       {0x881a,0x6e},\r
+       {0x881b,0x98},\r
+       {0x881c,0x50},\r
+       {0x881d,0x02},\r
+       {0x881e,0x80},\r
+       {0x881f,0x02},\r
+       {0x8820,0xa2},\r
+       {0x8821,0x24},\r
+       {0x8822,0x92},\r
+       {0x8823,0x24},\r
+       {0x8824,0x30},\r
+       {0x8825,0x24},\r
+       {0x8826,0x04},\r
+       {0x8827,0xaf},\r
+       {0x8828,0x42},\r
+       {0x8829,0x80},\r
+       {0x882a,0x02},\r
+       {0x882b,0xaf},\r
+       {0x882c,0x41},\r
+       {0x882d,0x8f},\r
+       {0x882e,0x41},\r
+       {0x882f,0x30},\r
+       {0x8830,0x27},\r
+       {0x8831,0x11},\r
+       {0x8832,0x90},\r
+       {0x8833,0x33},\r
+       {0x8834,0x00},\r
+       {0x8835,0xe0},\r
+       {0x8836,0x30},\r
+       {0x8837,0x29},\r
+       {0x8838,0x05},\r
+       {0x8839,0x44},\r
+       {0x883a,0x40},\r
+       {0x883b,0xf0},\r
+       {0x883c,0x80},\r
+       {0x883d,0x03},\r
+       {0x883e,0x54},\r
+       {0x883f,0xbf},\r
+       {0x8840,0xf0},\r
+       {0x8841,0xc2},\r
+       {0x8842,0x27},\r
+       {0x8843,0xe5},\r
+       {0x8844,0x08},\r
+       {0x8845,0x30},\r
+       {0x8846,0xe1},\r
+       {0x8847,0x08},\r
+       {0x8848,0x90},\r
+       {0x8849,0x3f},\r
+       {0x884a,0x00},\r
+       {0x884b,0xe0},\r
+       {0x884c,0xf5},\r
+       {0x884d,0x29},\r
+       {0x884e,0xe4},\r
+       {0x884f,0xf0},\r
+       {0x8850,0x90},\r
+       {0x8851,0x37},\r
+       {0x8852,0x08},\r
+       {0x8853,0xe5},\r
+       {0x8854,0x08},\r
+       {0x8855,0xf0},\r
+       {0x8856,0xd0},\r
+       {0x8857,0x07},\r
+       {0x8858,0xd0},\r
+       {0x8859,0x06},\r
+       {0x885a,0xd0},\r
+       {0x885b,0x00},\r
+       {0x885c,0xd0},\r
+       {0x885d,0xd0},\r
+       {0x885e,0xd0},\r
+       {0x885f,0x82},\r
+       {0x8860,0xd0},\r
+       {0x8861,0x83},\r
+       {0x8862,0xd0},\r
+       {0x8863,0xe0},\r
+       {0x8864,0x32},\r
+       {0x8865,0x12},\r
+       {0x8866,0x04},\r
+       {0x8867,0xbe},\r
+       {0x8868,0xb5},\r
+       {0x8869,0x07},\r
+       {0x886a,0x03},\r
+       {0x886b,0xd3},\r
+       {0x886c,0x80},\r
+       {0x886d,0x01},\r
+       {0x886e,0xc3},\r
+       {0x886f,0x40},\r
+       {0x8870,0x03},\r
+       {0x8871,0x02},\r
+       {0x8872,0x08},\r
+       {0x8873,0xf9},\r
+       {0x8874,0x90},\r
+       {0x8875,0x31},\r
+       {0x8876,0x00},\r
+       {0x8877,0xe0},\r
+       {0x8878,0x54},\r
+       {0x8879,0xfe},\r
+       {0x887a,0xf0},\r
+       {0x887b,0xe0},\r
+       {0x887c,0x54},\r
+       {0x887d,0xfd},\r
+       {0x887e,0xf0},\r
+       {0x887f,0xa3},\r
+       {0x8880,0xe4},\r
+       {0x8881,0xf0},\r
+       {0x8882,0x90},\r
+       {0x8883,0x33},\r
+       {0x8884,0x00},\r
+       {0x8885,0xe0},\r
+       {0x8886,0x54},\r
+       {0x8887,0xbf},\r
+       {0x8888,0xf0},\r
+       {0x8889,0x12},\r
+       {0x888a,0x04},\r
+       {0x888b,0x8b},\r
+       {0x888c,0x90},\r
+       {0x888d,0x33},\r
+       {0x888e,0xb0},\r
+       {0x888f,0xf0},\r
+       {0x8890,0xa3},\r
+       {0x8891,0xf0},\r
+       {0x8892,0xa3},\r
+       {0x8893,0xf0},\r
+       {0x8894,0x90},\r
+       {0x8895,0x30},\r
+       {0x8896,0xb2},\r
+       {0x8897,0xe0},\r
+       {0x8898,0x44},\r
+       {0x8899,0x08},\r
+       {0x889a,0xf0},\r
+       {0x889b,0x90},\r
+       {0x889c,0x30},\r
+       {0x889d,0xb0},\r
+       {0x889e,0xe0},\r
+       {0x889f,0x44},\r
+       {0x88a0,0x01},\r
+       {0x88a1,0xf0},\r
+       {0x88a2,0xa3},\r
+       {0x88a3,0xe0},\r
+       {0x88a4,0x44},\r
+       {0x88a5,0x0c},\r
+       {0x88a6,0xf0},\r
+       {0x88a7,0x90},\r
+       {0x88a8,0x30},\r
+       {0x88a9,0xb4},\r
+       {0x88aa,0xe0},\r
+       {0x88ab,0x44},\r
+       {0x88ac,0x07},\r
+       {0x88ad,0xf0},\r
+       {0x88ae,0xe0},\r
+       {0x88af,0xf5},\r
+       {0x88b0,0x23},\r
+       {0x88b1,0x90},\r
+       {0x88b2,0x30},\r
+       {0x88b3,0xb1},\r
+       {0x88b4,0xe0},\r
+       {0x88b5,0xf5},\r
+       {0x88b6,0x21},\r
+       {0x88b7,0x90},\r
+       {0x88b8,0x39},\r
+       {0x88b9,0x01},\r
+       {0x88ba,0x74},\r
+       {0x88bb,0x35},\r
+       {0x88bc,0xf0},\r
+       {0x88bd,0x90},\r
+       {0x88be,0x39},\r
+       {0x88bf,0x00},\r
+       {0x88c0,0x74},\r
+       {0x88c1,0x20},\r
+       {0x88c2,0xf0},\r
+       {0x88c3,0x90},\r
+       {0x88c4,0x37},\r
+       {0x88c5,0x00},\r
+       {0x88c6,0x74},\r
+       {0x88c7,0xff},\r
+       {0x88c8,0xf0},\r
+       {0x88c9,0xa3},\r
+       {0x88ca,0xf0},\r
+       {0x88cb,0x90},\r
+       {0x88cc,0x37},\r
+       {0x88cd,0x00},\r
+       {0x88ce,0xe0},\r
+       {0x88cf,0x54},\r
+       {0x88d0,0xf7},\r
+       {0x88d1,0xf0},\r
+       {0x88d2,0xe0},\r
+       {0x88d3,0x54},\r
+       {0x88d4,0xdf},\r
+       {0x88d5,0xf0},\r
+       {0x88d6,0x90},\r
+       {0x88d7,0x31},\r
+       {0x88d8,0x0f},\r
+       {0x88d9,0x74},\r
+       {0x88da,0x3f},\r
+       {0x88db,0xf0},\r
+       {0x88dc,0xa3},\r
+       {0x88dd,0xe4},\r
+       {0x88de,0xf0},\r
+       {0x88df,0xa3},\r
+       {0x88e0,0x74},\r
+       {0x88e1,0x3f},\r
+       {0x88e2,0xf0},\r
+       {0x88e3,0xa3},\r
+       {0x88e4,0x74},\r
+       {0x88e5,0x01},\r
+       {0x88e6,0xf0},\r
+       {0x88e7,0x90},\r
+       {0x88e8,0x37},\r
+       {0x88e9,0x00},\r
+       {0x88ea,0xe0},\r
+       {0x88eb,0x54},\r
+       {0x88ec,0xfd},\r
+       {0x88ed,0xf0},\r
+       {0x88ee,0x90},\r
+       {0x88ef,0x37},\r
+       {0x88f0,0x08},\r
+       {0x88f1,0x74},\r
+       {0x88f2,0xff},\r
+       {0x88f3,0xf0},\r
+       {0x88f4,0xa3},\r
+       {0x88f5,0xf0},\r
+       {0x88f6,0x75},\r
+       {0x88f7,0xa8},\r
+       {0x88f8,0x01},\r
+       {0x88f9,0x22},\r
+       {0x88fa,0xe5},\r
+       {0x88fb,0x0a},\r
+       {0x88fc,0x25},\r
+       {0x88fd,0xe0},\r
+       {0x88fe,0x25},\r
+       {0x88ff,0xe0},\r
+       {0x8900,0xf5},\r
+       {0x8901,0x0b},\r
+       {0x8902,0xe5},\r
+       {0x8903,0x09},\r
+       {0x8904,0x60},\r
+       {0x8905,0x09},\r
+       {0x8906,0xe5},\r
+       {0x8907,0x0a},\r
+       {0x8908,0x75},\r
+       {0x8909,0xf0},\r
+       {0x890a,0x03},\r
+       {0x890b,0xa4},\r
+       {0x890c,0xff},\r
+       {0x890d,0x80},\r
+       {0x890e,0x02},\r
+       {0x890f,0xaf},\r
+       {0x8910,0x0b},\r
+       {0x8911,0x8f},\r
+       {0x8912,0x0c},\r
+       {0x8913,0xc3},\r
+       {0x8914,0x74},\r
+       {0x8915,0x0f},\r
+       {0x8916,0x9f},\r
+       {0x8917,0x78},\r
+       {0x8918,0x10},\r
+       {0x8919,0x12},\r
+       {0x891a,0x04},\r
+       {0x891b,0x71},\r
+       {0x891c,0xc0},\r
+       {0x891d,0x04},\r
+       {0x891e,0xc0},\r
+       {0x891f,0x05},\r
+       {0x8920,0xc0},\r
+       {0x8921,0x06},\r
+       {0x8922,0xc0},\r
+       {0x8923,0x07},\r
+       {0x8924,0xc3},\r
+       {0x8925,0x74},\r
+       {0x8926,0x14},\r
+       {0x8927,0x95},\r
+       {0x8928,0x0b},\r
+       {0x8929,0x78},\r
+       {0x892a,0x18},\r
+       {0x892b,0x12},\r
+       {0x892c,0x04},\r
+       {0x892d,0x71},\r
+       {0x892e,0xd0},\r
+       {0x892f,0x03},\r
+       {0x8930,0xd0},\r
+       {0x8931,0x02},\r
+       {0x8932,0xd0},\r
+       {0x8933,0x01},\r
+       {0x8934,0xd0},\r
+       {0x8935,0x00},\r
+       {0x8936,0xef},\r
+       {0x8937,0x4b},\r
+       {0x8938,0xff},\r
+       {0x8939,0xee},\r
+       {0x893a,0x4a},\r
+       {0x893b,0xfe},\r
+       {0x893c,0xed},\r
+       {0x893d,0x49},\r
+       {0x893e,0xfd},\r
+       {0x893f,0xec},\r
+       {0x8940,0x48},\r
+       {0x8941,0xfc},\r
+       {0x8942,0xc0},\r
+       {0x8943,0x04},\r
+       {0x8944,0xc0},\r
+       {0x8945,0x05},\r
+       {0x8946,0xc0},\r
+       {0x8947,0x06},\r
+       {0x8948,0xc0},\r
+       {0x8949,0x07},\r
+       {0x894a,0xe5},\r
+       {0x894b,0x0b},\r
+       {0x894c,0x24},\r
+       {0x894d,0x14},\r
+       {0x894e,0xff},\r
+       {0x894f,0xe4},\r
+       {0x8950,0x33},\r
+       {0x8951,0xfe},\r
+       {0x8952,0xe4},\r
+       {0x8953,0xfc},\r
+       {0x8954,0xfd},\r
+       {0x8955,0x78},\r
+       {0x8956,0x08},\r
+       {0x8957,0x12},\r
+       {0x8958,0x01},\r
+       {0x8959,0x33},\r
+       {0x895a,0xd0},\r
+       {0x895b,0x03},\r
+       {0x895c,0xd0},\r
+       {0x895d,0x02},\r
+       {0x895e,0xd0},\r
+       {0x895f,0x01},\r
+       {0x8960,0xd0},\r
+       {0x8961,0x00},\r
+       {0x8962,0xef},\r
+       {0x8963,0x4b},\r
+       {0x8964,0xfb},\r
+       {0x8965,0xee},\r
+       {0x8966,0x4a},\r
+       {0x8967,0xfa},\r
+       {0x8968,0xed},\r
+       {0x8969,0x49},\r
+       {0x896a,0xf9},\r
+       {0x896b,0xec},\r
+       {0x896c,0x48},\r
+       {0x896d,0xf8},\r
+       {0x896e,0xe5},\r
+       {0x896f,0x0c},\r
+       {0x8970,0x24},\r
+       {0x8971,0x0f},\r
+       {0x8972,0xff},\r
+       {0x8973,0xe4},\r
+       {0x8974,0x33},\r
+       {0x8975,0xfe},\r
+       {0x8976,0xeb},\r
+       {0x8977,0x4f},\r
+       {0x8978,0xf5},\r
+       {0x8979,0x2d},\r
+       {0x897a,0xea},\r
+       {0x897b,0x4e},\r
+       {0x897c,0xf5},\r
+       {0x897d,0x2c},\r
+       {0x897e,0xe9},\r
+       {0x897f,0xf5},\r
+       {0x8980,0x2b},\r
+       {0x8981,0xe8},\r
+       {0x8982,0xf5},\r
+       {0x8983,0x2a},\r
+       {0x8984,0x22},\r
+       {0x8985,0xe5},\r
+       {0x8986,0x45},\r
+       {0x8987,0x64},\r
+       {0x8988,0x01},\r
+       {0x8989,0x70},\r
+       {0x898a,0x50},\r
+       {0x898b,0x12},\r
+       {0x898c,0x04},\r
+       {0x898d,0x6a},\r
+       {0x898e,0xe5},\r
+       {0x898f,0x44},\r
+       {0x8990,0x12},\r
+       {0x8991,0x04},\r
+       {0x8992,0x18},\r
+       {0x8993,0xfe},\r
+       {0x8994,0xe4},\r
+       {0x8995,0x8f},\r
+       {0x8996,0x3c},\r
+       {0x8997,0x8e},\r
+       {0x8998,0x3b},\r
+       {0x8999,0xf5},\r
+       {0x899a,0x3a},\r
+       {0x899b,0xf5},\r
+       {0x899c,0x39},\r
+       {0x899d,0x12},\r
+       {0x899e,0x04},\r
+       {0x899f,0x44},\r
+       {0x89a0,0x7b},\r
+       {0x89a1,0xff},\r
+       {0x89a2,0xfa},\r
+       {0x89a3,0xf9},\r
+       {0x89a4,0xf8},\r
+       {0x89a5,0x12},\r
+       {0x89a6,0x04},\r
+       {0x89a7,0x39},\r
+       {0x89a8,0xc0},\r
+       {0x89a9,0x04},\r
+       {0x89aa,0xc0},\r
+       {0x89ab,0x05},\r
+       {0x89ac,0xc0},\r
+       {0x89ad,0x06},\r
+       {0x89ae,0xc0},\r
+       {0x89af,0x07},\r
+       {0x89b0,0x12},\r
+       {0x89b1,0x04},\r
+       {0x89b2,0x10},\r
+       {0x89b3,0xab},\r
+       {0x89b4,0x07},\r
+       {0x89b5,0xfa},\r
+       {0x89b6,0xe4},\r
+       {0x89b7,0xf9},\r
+       {0x89b8,0xf8},\r
+       {0x89b9,0xd0},\r
+       {0x89ba,0x07},\r
+       {0x89bb,0xd0},\r
+       {0x89bc,0x06},\r
+       {0x89bd,0xd0},\r
+       {0x89be,0x05},\r
+       {0x89bf,0xd0},\r
+       {0x89c0,0x04},\r
+       {0x89c1,0x12},\r
+       {0x89c2,0x04},\r
+       {0x89c3,0x9f},\r
+       {0x89c4,0x85},\r
+       {0x89c5,0x3c},\r
+       {0x89c6,0x39},\r
+       {0x89c7,0x85},\r
+       {0x89c8,0x44},\r
+       {0x89c9,0x3a},\r
+       {0x89ca,0x12},\r
+       {0x89cb,0x04},\r
+       {0x89cc,0x6a},\r
+       {0x89cd,0xe5},\r
+       {0x89ce,0x44},\r
+       {0x89cf,0x12},\r
+       {0x89d0,0x04},\r
+       {0x89d1,0xd4},\r
+       {0x89d2,0xe4},\r
+       {0x89d3,0x93},\r
+       {0x89d4,0xf5},\r
+       {0x89d5,0x3b},\r
+       {0x89d6,0x74},\r
+       {0x89d7,0x01},\r
+       {0x89d8,0x93},\r
+       {0x89d9,0xf5},\r
+       {0x89da,0x3c},\r
+       {0x89db,0x90},\r
+       {0x89dc,0x3f},\r
+       {0x89dd,0x02},\r
+       {0x89de,0xe5},\r
+       {0x89df,0x39},\r
+       {0x89e0,0xf0},\r
+       {0x89e1,0xa3},\r
+       {0x89e2,0xe5},\r
+       {0x89e3,0x3a},\r
+       {0x89e4,0xf0},\r
+       {0x89e5,0xa3},\r
+       {0x89e6,0xe5},\r
+       {0x89e7,0x3b},\r
+       {0x89e8,0xf0},\r
+       {0x89e9,0xa3},\r
+       {0x89ea,0xe5},\r
+       {0x89eb,0x3c},\r
+       {0x89ec,0xf0},\r
+       {0x89ed,0x22},\r
+       {0x89ee,0xe5},\r
+       {0x89ef,0x09},\r
+       {0x89f0,0xd3},\r
+       {0x89f1,0x95},\r
+       {0x89f2,0x43},\r
+       {0x89f3,0x40},\r
+       {0x89f4,0x01},\r
+       {0x89f5,0x22},\r
+       {0x89f6,0x12},\r
+       {0x89f7,0x04},\r
+       {0x89f8,0x6a},\r
+       {0x89f9,0xe5},\r
+       {0x89fa,0x09},\r
+       {0x89fb,0x12},\r
+       {0x89fc,0x04},\r
+       {0x89fd,0xd4},\r
+       {0x89fe,0xe4},\r
+       {0x89ff,0x93},\r
+       {0x8a00,0xfe},\r
+       {0x8a01,0x74},\r
+       {0x8a02,0x01},\r
+       {0x8a03,0x93},\r
+       {0x8a04,0xff},\r
+       {0x8a05,0x4e},\r
+       {0x8a06,0x60},\r
+       {0x8a07,0x21},\r
+       {0x8a08,0x8e},\r
+       {0x8a09,0x37},\r
+       {0x8a0a,0x8f},\r
+       {0x8a0b,0x38},\r
+       {0x8a0c,0xef},\r
+       {0x8a0d,0xc4},\r
+       {0x8a0e,0xf8},\r
+       {0x8a0f,0x54},\r
+       {0x8a10,0x0f},\r
+       {0x8a11,0xc8},\r
+       {0x8a12,0x68},\r
+       {0x8a13,0xff},\r
+       {0x8a14,0xee},\r
+       {0x8a15,0xc4},\r
+       {0x8a16,0x54},\r
+       {0x8a17,0xf0},\r
+       {0x8a18,0x48},\r
+       {0x8a19,0xfe},\r
+       {0x8a1a,0x43},\r
+       {0x8a1b,0x07},\r
+       {0x8a1c,0x0d},\r
+       {0x8a1d,0x8e},\r
+       {0x8a1e,0x0a},\r
+       {0x8a1f,0x8f},\r
+       {0x8a20,0x0b},\r
+       {0x8a21,0x12},\r
+       {0x8a22,0x01},\r
+       {0x8a23,0x78},\r
+       {0x8a24,0x30},\r
+       {0x8a25,0x23},\r
+       {0x8a26,0x22},\r
+       {0x8a27,0xc3},\r
+       {0x8a28,0x22},\r
+       {0x8a29,0x75},\r
+       {0x8a2a,0x0a},\r
+       {0x8a2b,0x00},\r
+       {0x8a2c,0x75},\r
+       {0x8a2d,0x0b},\r
+       {0x8a2e,0x0d},\r
+       {0x8a2f,0x12},\r
+       {0x8a30,0x01},\r
+       {0x8a31,0x78},\r
+       {0x8a32,0x30},\r
+       {0x8a33,0x23},\r
+       {0x8a34,0x02},\r
+       {0x8a35,0xc3},\r
+       {0x8a36,0x22},\r
+       {0x8a37,0x75},\r
+       {0x8a38,0x0a},\r
+       {0x8a39,0x00},\r
+       {0x8a3a,0x75},\r
+       {0x8a3b,0x0b},\r
+       {0x8a3c,0x64},\r
+       {0x8a3d,0x12},\r
+       {0x8a3e,0x0c},\r
+       {0x8a3f,0x67},\r
+       {0x8a40,0x75},\r
+       {0x8a41,0x0a},\r
+       {0x8a42,0x80},\r
+       {0x8a43,0x75},\r
+       {0x8a44,0x0b},\r
+       {0x8a45,0x00},\r
+       {0x8a46,0x12},\r
+       {0x8a47,0x01},\r
+       {0x8a48,0x78},\r
+       {0x8a49,0x85},\r
+       {0x8a4a,0x09},\r
+       {0x8a4b,0x44},\r
+       {0x8a4c,0xd3},\r
+       {0x8a4d,0x22},\r
+       {0x8a4e,0xc2},\r
+       {0x8a4f,0x25},\r
+       {0x8a50,0x20},\r
+       {0x8a51,0x05},\r
+       {0x8a52,0x05},\r
+       {0x8a53,0x75},\r
+       {0x8a54,0x09},\r
+       {0x8a55,0xee},\r
+       {0x8a56,0x80},\r
+       {0x8a57,0x36},\r
+       {0x8a58,0x20},\r
+       {0x8a59,0x07},\r
+       {0x8a5a,0x08},\r
+       {0x8a5b,0x20},\r
+       {0x8a5c,0x06},\r
+       {0x8a5d,0x05},\r
+       {0x8a5e,0xe4},\r
+       {0x8a5f,0xf5},\r
+       {0x8a60,0x09},\r
+       {0x8a61,0x80},\r
+       {0x8a62,0x2b},\r
+       {0x8a63,0x20},\r
+       {0x8a64,0x07},\r
+       {0x8a65,0x08},\r
+       {0x8a66,0x30},\r
+       {0x8a67,0x06},\r
+       {0x8a68,0x05},\r
+       {0x8a69,0x75},\r
+       {0x8a6a,0x09},\r
+       {0x8a6b,0x20},\r
+       {0x8a6c,0x80},\r
+       {0x8a6d,0x20},\r
+       {0x8a6e,0x30},\r
+       {0x8a6f,0x00},\r
+       {0x8a70,0x05},\r
+       {0x8a71,0x75},\r
+       {0x8a72,0x09},\r
+       {0x8a73,0x01},\r
+       {0x8a74,0x80},\r
+       {0x8a75,0x18},\r
+       {0x8a76,0xe5},\r
+       {0x8a77,0x20},\r
+       {0x8a78,0x54},\r
+       {0x8a79,0x07},\r
+       {0x8a7a,0xff},\r
+       {0x8a7b,0xbf},\r
+       {0x8a7c,0x06},\r
+       {0x8a7d,0x0d},\r
+       {0x8a7e,0x30},\r
+       {0x8a7f,0x21},\r
+       {0x8a80,0x04},\r
+       {0x8a81,0x7f},\r
+       {0x8a82,0x12},\r
+       {0x8a83,0x80},\r
+       {0x8a84,0x02},\r
+       {0x8a85,0x7f},\r
+       {0x8a86,0x02},\r
+       {0x8a87,0x8f},\r
+       {0x8a88,0x09},\r
+       {0x8a89,0x80},\r
+       {0x8a8a,0x03},\r
+       {0x8a8b,0x75},\r
+       {0x8a8c,0x09},\r
+       {0x8a8d,0xfe},\r
+       {0x8a8e,0x90},\r
+       {0x8a8f,0x3f},\r
+       {0x8a90,0x07},\r
+       {0x8a91,0xe5},\r
+       {0x8a92,0x09},\r
+       {0x8a93,0xf0},\r
+       {0x8a94,0x90},\r
+       {0x8a95,0x3f},\r
+       {0x8a96,0x06},\r
+       {0x8a97,0xe5},\r
+       {0x8a98,0x44},\r
+       {0x8a99,0xf0},\r
+       {0x8a9a,0x22},\r
+       {0x8a9b,0x85},\r
+       {0x8a9c,0x0d},\r
+       {0x8a9d,0x0e},\r
+       {0x8a9e,0x7f},\r
+       {0x8a9f,0x08},\r
+       {0x8aa0,0xe5},\r
+       {0x8aa1,0x0e},\r
+       {0x8aa2,0x30},\r
+       {0x8aa3,0xe7},\r
+       {0x8aa4,0x04},\r
+       {0x8aa5,0xd2},\r
+       {0x8aa6,0x19},\r
+       {0x8aa7,0x80},\r
+       {0x8aa8,0x02},\r
+       {0x8aa9,0xc2},\r
+       {0x8aaa,0x19},\r
+       {0x8aab,0x12},\r
+       {0x8aac,0x04},\r
+       {0x8aad,0x09},\r
+       {0x8aae,0x75},\r
+       {0x8aaf,0x32},\r
+       {0x8ab0,0x0a},\r
+       {0x8ab1,0xae},\r
+       {0x8ab2,0x32},\r
+       {0x8ab3,0x15},\r
+       {0x8ab4,0x32},\r
+       {0x8ab5,0xee},\r
+       {0x8ab6,0x70},\r
+       {0x8ab7,0xf9},\r
+       {0x8ab8,0xe5},\r
+       {0x8ab9,0x0e},\r
+       {0x8aba,0x25},\r
+       {0x8abb,0xe0},\r
+       {0x8abc,0xf5},\r
+       {0x8abd,0x0e},\r
+       {0x8abe,0xd2},\r
+       {0x8abf,0x18},\r
+       {0x8ac0,0x12},\r
+       {0x8ac1,0x04},\r
+       {0x8ac2,0x09},\r
+       {0x8ac3,0x75},\r
+       {0x8ac4,0x32},\r
+       {0x8ac5,0x0a},\r
+       {0x8ac6,0xae},\r
+       {0x8ac7,0x32},\r
+       {0x8ac8,0x15},\r
+       {0x8ac9,0x32},\r
+       {0x8aca,0xee},\r
+       {0x8acb,0x70},\r
+       {0x8acc,0xf9},\r
+       {0x8acd,0xc2},\r
+       {0x8ace,0x18},\r
+       {0x8acf,0x12},\r
+       {0x8ad0,0x04},\r
+       {0x8ad1,0x09},\r
+       {0x8ad2,0x75},\r
+       {0x8ad3,0x32},\r
+       {0x8ad4,0x05},\r
+       {0x8ad5,0xae},\r
+       {0x8ad6,0x32},\r
+       {0x8ad7,0x15},\r
+       {0x8ad8,0x32},\r
+       {0x8ad9,0xee},\r
+       {0x8ada,0x70},\r
+       {0x8adb,0xf9},\r
+       {0x8adc,0xdf},\r
+       {0x8add,0xc2},\r
+       {0x8ade,0x22},\r
+       {0x8adf,0x90},\r
+       {0x8ae0,0x3f},\r
+       {0x8ae1,0x07},\r
+       {0x8ae2,0x74},\r
+       {0x8ae3,0xfa},\r
+       {0x8ae4,0xf0},\r
+       {0x8ae5,0x12},\r
+       {0x8ae6,0x08},\r
+       {0x8ae7,0x65},\r
+       {0x8ae8,0x12},\r
+       {0x8ae9,0x0b},\r
+       {0x8aea,0xfb},\r
+       {0x8aeb,0xe4},\r
+       {0x8aec,0xf5},\r
+       {0x8aed,0x29},\r
+       {0x8aee,0xd2},\r
+       {0x8aef,0xaf},\r
+       {0x8af0,0x12},\r
+       {0x8af1,0x05},\r
+       {0x8af2,0xfc},\r
+       {0x8af3,0x30},\r
+       {0x8af4,0x20},\r
+       {0x8af5,0x03},\r
+       {0x8af6,0x12},\r
+       {0x8af7,0x02},\r
+       {0x8af8,0xc4},\r
+       {0x8af9,0x30},\r
+       {0x8afa,0x25},\r
+       {0x8afb,0x03},\r
+       {0x8afc,0x12},\r
+       {0x8afd,0x0a},\r
+       {0x8afe,0x4e},\r
+       {0x8aff,0x30},\r
+       {0x8b00,0x2f},\r
+       {0x8b01,0xee},\r
+       {0x8b02,0xc2},\r
+       {0x8b03,0x2f},\r
+       {0x8b04,0xd2},\r
+       {0x8b05,0x26},\r
+       {0x8b06,0x30},\r
+       {0x8b07,0x00},\r
+       {0x8b08,0x05},\r
+       {0x8b09,0x12},\r
+       {0x8b0a,0x0b},\r
+       {0x8b0b,0x7b},\r
+       {0x8b0c,0x80},\r
+       {0x8b0d,0x09},\r
+       {0x8b0e,0x20},\r
+       {0x8b0f,0x07},\r
+       {0x8b10,0x06},\r
+       {0x8b11,0x30},\r
+       {0x8b12,0x06},\r
+       {0x8b13,0x03},\r
+       {0x8b14,0x12},\r
+       {0x8b15,0x04},\r
+       {0x8b16,0xf5},\r
+       {0x8b17,0xc2},\r
+       {0x8b18,0x26},\r
+       {0x8b19,0x80},\r
+       {0x8b1a,0xd5},\r
+       {0x8b1b,0xe5},\r
+       {0x8b1c,0x44},\r
+       {0x8b1d,0x70},\r
+       {0x8b1e,0x19},\r
+       {0x8b1f,0x12},\r
+       {0x8b20,0x0d},\r
+       {0x8b21,0x4b},\r
+       {0x8b22,0xc2},\r
+       {0x8b23,0x30},\r
+       {0x8b24,0x12},\r
+       {0x8b25,0x0b},\r
+       {0x8b26,0xd2},\r
+       {0x8b27,0xc2},\r
+       {0x8b28,0x30},\r
+       {0x8b29,0x12},\r
+       {0x8b2a,0x0c},\r
+       {0x8b2b,0x89},\r
+       {0x8b2c,0xc2},\r
+       {0x8b2d,0x03},\r
+       {0x8b2e,0x12},\r
+       {0x8b2f,0x0c},\r
+       {0x8b30,0xfe},\r
+       {0x8b31,0xd2},\r
+       {0x8b32,0x02},\r
+       {0x8b33,0xd2},\r
+       {0x8b34,0x01},\r
+       {0x8b35,0xd2},\r
+       {0x8b36,0x00},\r
+       {0x8b37,0x22},\r
+       {0x8b38,0x30},\r
+       {0x8b39,0x03},\r
+       {0x8b3a,0x08},\r
+       {0x8b3b,0xc2},\r
+       {0x8b3c,0x03},\r
+       {0x8b3d,0xc2},\r
+       {0x8b3e,0x04},\r
+       {0x8b3f,0x12},\r
+       {0x8b40,0x04},\r
+       {0x8b41,0xe4},\r
+       {0x8b42,0x22},\r
+       {0x8b43,0xe4},\r
+       {0x8b44,0xf5},\r
+       {0x8b45,0x09},\r
+       {0x8b46,0x12},\r
+       {0x8b47,0x09},\r
+       {0x8b48,0xee},\r
+       {0x8b49,0xd2},\r
+       {0x8b4a,0x03},\r
+       {0x8b4b,0x22},\r
+       {0x8b4c,0x36},\r
+       {0x8b4d,0x0c},\r
+       {0x8b4e,0x04},\r
+       {0x8b4f,0x00},\r
+       {0x8b50,0x00},\r
+       {0x8b51,0x00},\r
+       {0x8b52,0xc8},\r
+       {0x8b53,0x01},\r
+       {0x8b54,0x2c},\r
+       {0x8b55,0x01},\r
+       {0x8b56,0x5e},\r
+       {0x8b57,0x01},\r
+       {0x8b58,0x8b},\r
+       {0x8b59,0x01},\r
+       {0x8b5a,0xb8},\r
+       {0x8b5b,0x01},\r
+       {0x8b5c,0xe5},\r
+       {0x8b5d,0x02},\r
+       {0x8b5e,0x12},\r
+       {0x8b5f,0x02},\r
+       {0x8b60,0x3f},\r
+       {0x8b61,0x02},\r
+       {0x8b62,0x6c},\r
+       {0x8b63,0x02},\r
+       {0x8b64,0x99},\r
+       {0x8b65,0x02},\r
+       {0x8b66,0xc6},\r
+       {0x8b67,0x02},\r
+       {0x8b68,0xf3},\r
+       {0x8b69,0x07},\r
+       {0x8b6a,0x00},\r
+       {0x8b6b,0x02},\r
+       {0x8b6c,0x4e},\r
+       {0x8b6d,0x02},\r
+       {0x8b6e,0x6c},\r
+       {0x8b6f,0x02},\r
+       {0x8b70,0x8a},\r
+       {0x8b71,0x02},\r
+       {0x8b72,0xa8},\r
+       {0x8b73,0x02},\r
+       {0x8b74,0xc6},\r
+       {0x8b75,0x02},\r
+       {0x8b76,0xe4},\r
+       {0x8b77,0x03},\r
+       {0x8b78,0x02},\r
+       {0x8b79,0x03},\r
+       {0x8b7a,0x20},\r
+       {0x8b7b,0xe5},\r
+       {0x8b7c,0x20},\r
+       {0x8b7d,0x54},\r
+       {0x8b7e,0x07},\r
+       {0x8b7f,0xff},\r
+       {0x8b80,0xbf},\r
+       {0x8b81,0x01},\r
+       {0x8b82,0x03},\r
+       {0x8b83,0x02},\r
+       {0x8b84,0x0b},\r
+       {0x8b85,0x1b},\r
+       {0x8b86,0xe5},\r
+       {0x8b87,0x20},\r
+       {0x8b88,0x54},\r
+       {0x8b89,0x07},\r
+       {0x8b8a,0xff},\r
+       {0x8b8b,0xbf},\r
+       {0x8b8c,0x07},\r
+       {0x8b8d,0x03},\r
+       {0x8b8e,0x02},\r
+       {0x8b8f,0x0c},\r
+       {0x8b90,0x44},\r
+       {0x8b91,0xe5},\r
+       {0x8b92,0x20},\r
+       {0x8b93,0x54},\r
+       {0x8b94,0x07},\r
+       {0x8b95,0xff},\r
+       {0x8b96,0xbf},\r
+       {0x8b97,0x03},\r
+       {0x8b98,0x03},\r
+       {0x8b99,0x02},\r
+       {0x8b9a,0x0b},\r
+       {0x8b9b,0xa8},\r
+       {0x8b9c,0xe5},\r
+       {0x8b9d,0x20},\r
+       {0x8b9e,0x54},\r
+       {0x8b9f,0x07},\r
+       {0x8ba0,0xff},\r
+       {0x8ba1,0xbf},\r
+       {0x8ba2,0x05},\r
+       {0x8ba3,0x03},\r
+       {0x8ba4,0x12},\r
+       {0x8ba5,0x0d},\r
+       {0x8ba6,0x59},\r
+       {0x8ba7,0x22},\r
+       {0x8ba8,0x12},\r
+       {0x8ba9,0x0c},\r
+       {0x8baa,0x21},\r
+       {0x8bab,0xd2},\r
+       {0x8bac,0x30},\r
+       {0x8bad,0x12},\r
+       {0x8bae,0x0b},\r
+       {0x8baf,0xd2},\r
+       {0x8bb0,0xd2},\r
+       {0x8bb1,0x30},\r
+       {0x8bb2,0x12},\r
+       {0x8bb3,0x0c},\r
+       {0x8bb4,0x89},\r
+       {0x8bb5,0xe5},\r
+       {0x8bb6,0x43},\r
+       {0x8bb7,0xd3},\r
+       {0x8bb8,0x95},\r
+       {0x8bb9,0x44},\r
+       {0x8bba,0x40},\r
+       {0x8bbb,0x03},\r
+       {0x8bbc,0xd3},\r
+       {0x8bbd,0x80},\r
+       {0x8bbe,0x01},\r
+       {0x8bbf,0xc3},\r
+       {0x8bc0,0x50},\r
+       {0x8bc1,0x0c},\r
+       {0x8bc2,0x20},\r
+       {0x8bc3,0x28},\r
+       {0x8bc4,0x06},\r
+       {0x8bc5,0x30},\r
+       {0x8bc6,0x2d},\r
+       {0x8bc7,0x03},\r
+       {0x8bc8,0x20},\r
+       {0x8bc9,0x2e},\r
+       {0x8bca,0x03},\r
+       {0x8bcb,0x02},\r
+       {0x8bcc,0x0c},\r
+       {0x8bcd,0xfe},\r
+       {0x8bce,0x12},\r
+       {0x8bcf,0x0c},\r
+       {0x8bd0,0xbf},\r
+       {0x8bd1,0x22},\r
+       {0x8bd2,0x30},\r
+       {0x8bd3,0x30},\r
+       {0x8bd4,0x09},\r
+       {0x8bd5,0x30},\r
+       {0x8bd6,0x2d},\r
+       {0x8bd7,0x06},\r
+       {0x8bd8,0xae},\r
+       {0x8bd9,0x33},\r
+       {0x8bda,0xaf},\r
+       {0x8bdb,0x34},\r
+       {0x8bdc,0x80},\r
+       {0x8bdd,0x04},\r
+       {0x8bde,0xae},\r
+       {0x8bdf,0x3d},\r
+       {0x8be0,0xaf},\r
+       {0x8be1,0x3e},\r
+       {0x8be2,0x8e},\r
+       {0x8be3,0x33},\r
+       {0x8be4,0x8f},\r
+       {0x8be5,0x34},\r
+       {0x8be6,0x30},\r
+       {0x8be7,0x30},\r
+       {0x8be8,0x09},\r
+       {0x8be9,0x30},\r
+       {0x8bea,0x2e},\r
+       {0x8beb,0x06},\r
+       {0x8bec,0xae},\r
+       {0x8bed,0x35},\r
+       {0x8bee,0xaf},\r
+       {0x8bef,0x36},\r
+       {0x8bf0,0x80},\r
+       {0x8bf1,0x04},\r
+       {0x8bf2,0xae},\r
+       {0x8bf3,0x3f},\r
+       {0x8bf4,0xaf},\r
+       {0x8bf5,0x40},\r
+       {0x8bf6,0x8e},\r
+       {0x8bf7,0x35},\r
+       {0x8bf8,0x8f},\r
+       {0x8bf9,0x36},\r
+       {0x8bfa,0x22},\r
+       {0x8bfb,0x12},\r
+       {0x8bfc,0x0c},\r
+       {0x8bfd,0xec},\r
+       {0x8bfe,0x12},\r
+       {0x8bff,0x0d},\r
+       {0x8c00,0x67},\r
+       {0x8c01,0x50},\r
+       {0x8c02,0x04},\r
+       {0x8c03,0xd2},\r
+       {0x8c04,0x05},\r
+       {0x8c05,0x80},\r
+       {0x8c06,0x02},\r
+       {0x8c07,0xc2},\r
+       {0x8c08,0x05},\r
+       {0x8c09,0x12},\r
+       {0x8c0a,0x04},\r
+       {0x8c0b,0x7c},\r
+       {0x8c0c,0xc2},\r
+       {0x8c0d,0x28},\r
+       {0x8c0e,0xc2},\r
+       {0x8c0f,0x21},\r
+       {0x8c10,0xd2},\r
+       {0x8c11,0x25},\r
+       {0x8c12,0x12},\r
+       {0x8c13,0x04},\r
+       {0x8c14,0xbe},\r
+       {0x8c15,0xb5},\r
+       {0x8c16,0x07},\r
+       {0x8c17,0x03},\r
+       {0x8c18,0xd3},\r
+       {0x8c19,0x80},\r
+       {0x8c1a,0x01},\r
+       {0x8c1b,0xc3},\r
+       {0x8c1c,0x40},\r
+       {0x8c1d,0x02},\r
+       {0x8c1e,0xc2},\r
+       {0x8c1f,0x05},\r
+       {0x8c20,0x22},\r
+       {0x8c21,0xd3},\r
+       {0x8c22,0xe5},\r
+       {0x8c23,0x34},\r
+       {0x8c24,0x95},\r
+       {0x8c25,0x3e},\r
+       {0x8c26,0xe5},\r
+       {0x8c27,0x33},\r
+       {0x8c28,0x95},\r
+       {0x8c29,0x3d},\r
+       {0x8c2a,0x40},\r
+       {0x8c2b,0x03},\r
+       {0x8c2c,0xd3},\r
+       {0x8c2d,0x80},\r
+       {0x8c2e,0x01},\r
+       {0x8c2f,0xc3},\r
+       {0x8c30,0x92},\r
+       {0x8c31,0x2d},\r
+       {0x8c32,0xd3},\r
+       {0x8c33,0xe5},\r
+       {0x8c34,0x36},\r
+       {0x8c35,0x95},\r
+       {0x8c36,0x40},\r
+       {0x8c37,0xe5},\r
+       {0x8c38,0x35},\r
+       {0x8c39,0x95},\r
+       {0x8c3a,0x3f},\r
+       {0x8c3b,0x40},\r
+       {0x8c3c,0x03},\r
+       {0x8c3d,0xd3},\r
+       {0x8c3e,0x80},\r
+       {0x8c3f,0x01},\r
+       {0x8c40,0xc3},\r
+       {0x8c41,0x92},\r
+       {0x8c42,0x2e},\r
+       {0x8c43,0x22},\r
+       {0x8c44,0x12},\r
+       {0x8c45,0x0c},\r
+       {0x8c46,0x21},\r
+       {0x8c47,0xd2},\r
+       {0x8c48,0x30},\r
+       {0x8c49,0x12},\r
+       {0x8c4a,0x0b},\r
+       {0x8c4b,0xd2},\r
+       {0x8c4c,0xd2},\r
+       {0x8c4d,0x30},\r
+       {0x8c4e,0x12},\r
+       {0x8c4f,0x0c},\r
+       {0x8c50,0x89},\r
+       {0x8c51,0x12},\r
+       {0x8c52,0x0c},\r
+       {0x8c53,0xfe},\r
+       {0x8c54,0xe5},\r
+       {0x8c55,0x28},\r
+       {0x8c56,0xd3},\r
+       {0x8c57,0x95},\r
+       {0x8c58,0x44},\r
+       {0x8c59,0x40},\r
+       {0x8c5a,0x05},\r
+       {0x8c5b,0xe4},\r
+       {0x8c5c,0x95},\r
+       {0x8c5d,0x44},\r
+       {0x8c5e,0x40},\r
+       {0x8c5f,0x06},\r
+       {0x8c60,0xc2},\r
+       {0x8c61,0x02},\r
+       {0x8c62,0xd2},\r
+       {0x8c63,0x01},\r
+       {0x8c64,0xd2},\r
+       {0x8c65,0x00},\r
+       {0x8c66,0x22},\r
+       {0x8c67,0xe4},\r
+       {0x8c68,0xff},\r
+       {0x8c69,0xfe},\r
+       {0x8c6a,0xc3},\r
+       {0x8c6b,0xef},\r
+       {0x8c6c,0x95},\r
+       {0x8c6d,0x0b},\r
+       {0x8c6e,0xee},\r
+       {0x8c6f,0x95},\r
+       {0x8c70,0x0a},\r
+       {0x8c71,0x50},\r
+       {0x8c72,0x15},\r
+       {0x8c73,0x7d},\r
+       {0x8c74,0x8a},\r
+       {0x8c75,0x7c},\r
+       {0x8c76,0x02},\r
+       {0x8c77,0xed},\r
+       {0x8c78,0x1d},\r
+       {0x8c79,0xaa},\r
+       {0x8c7a,0x04},\r
+       {0x8c7b,0x70},\r
+       {0x8c7c,0x01},\r
+       {0x8c7d,0x1c},\r
+       {0x8c7e,0x4a},\r
+       {0x8c7f,0x70},\r
+       {0x8c80,0xf6},\r
+       {0x8c81,0x0f},\r
+       {0x8c82,0xbf},\r
+       {0x8c83,0x00},\r
+       {0x8c84,0x01},\r
+       {0x8c85,0x0e},\r
+       {0x8c86,0x80},\r
+       {0x8c87,0xe2},\r
+       {0x8c88,0x22},\r
+       {0x8c89,0x30},\r
+       {0x8c8a,0x30},\r
+       {0x8c8b,0x07},\r
+       {0x8c8c,0x30},\r
+       {0x8c8d,0x2d},\r
+       {0x8c8e,0x04},\r
+       {0x8c8f,0xaf},\r
+       {0x8c90,0x30},\r
+       {0x8c91,0x80},\r
+       {0x8c92,0x02},\r
+       {0x8c93,0xaf},\r
+       {0x8c94,0x44},\r
+       {0x8c95,0x8f},\r
+       {0x8c96,0x30},\r
+       {0x8c97,0x30},\r
+       {0x8c98,0x30},\r
+       {0x8c99,0x07},\r
+       {0x8c9a,0x30},\r
+       {0x8c9b,0x2e},\r
+       {0x8c9c,0x04},\r
+       {0x8c9d,0xaf},\r
+       {0x8c9e,0x31},\r
+       {0x8c9f,0x80},\r
+       {0x8ca0,0x02},\r
+       {0x8ca1,0xaf},\r
+       {0x8ca2,0x44},\r
+       {0x8ca3,0x8f},\r
+       {0x8ca4,0x31},\r
+       {0x8ca5,0x22},\r
+       {0x8ca6,0xe5},\r
+       {0x8ca7,0x45},\r
+       {0x8ca8,0xb4},\r
+       {0x8ca9,0x01},\r
+       {0x8caa,0x05},\r
+       {0x8cab,0x12},\r
+       {0x8cac,0x0d},\r
+       {0x8cad,0x1e},\r
+       {0x8cae,0x80},\r
+       {0x8caf,0x08},\r
+       {0x8cb0,0xe5},\r
+       {0x8cb1,0x45},\r
+       {0x8cb2,0xb4},\r
+       {0x8cb3,0x02},\r
+       {0x8cb4,0x09},\r
+       {0x8cb5,0x12},\r
+       {0x8cb6,0x0d},\r
+       {0x8cb7,0x2d},\r
+       {0x8cb8,0xe4},\r
+       {0x8cb9,0xf5},\r
+       {0x8cba,0x09},\r
+       {0x8cbb,0x12},\r
+       {0x8cbc,0x09},\r
+       {0x8cbd,0xee},\r
+       {0x8cbe,0x22},\r
+       {0x8cbf,0xaf},\r
+       {0x8cc0,0x31},\r
+       {0x8cc1,0xe5},\r
+       {0x8cc2,0x44},\r
+       {0x8cc3,0xb5},\r
+       {0x8cc4,0x07},\r
+       {0x8cc5,0x03},\r
+       {0x8cc6,0x02},\r
+       {0x8cc7,0x0c},\r
+       {0x8cc8,0xd8},\r
+       {0x8cc9,0x8f},\r
+       {0x8cca,0x09},\r
+       {0x8ccb,0x12},\r
+       {0x8ccc,0x09},\r
+       {0x8ccd,0xee},\r
+       {0x8cce,0xd2},\r
+       {0x8ccf,0x02},\r
+       {0x8cd0,0xc2},\r
+       {0x8cd1,0x01},\r
+       {0x8cd2,0xd2},\r
+       {0x8cd3,0x00},\r
+       {0x8cd4,0x75},\r
+       {0x8cd5,0x27},\r
+       {0x8cd6,0x03},\r
+       {0x8cd7,0x22},\r
+       {0x8cd8,0xc2},\r
+       {0x8cd9,0x03},\r
+       {0x8cda,0xd2},\r
+       {0x8cdb,0x04},\r
+       {0x8cdc,0x12},\r
+       {0x8cdd,0x04},\r
+       {0x8cde,0xe4},\r
+       {0x8cdf,0xc2},\r
+       {0x8ce0,0x30},\r
+       {0x8ce1,0x12},\r
+       {0x8ce2,0x0b},\r
+       {0x8ce3,0xd2},\r
+       {0x8ce4,0xc2},\r
+       {0x8ce5,0x30},\r
+       {0x8ce6,0x12},\r
+       {0x8ce7,0x0c},\r
+       {0x8ce8,0x89},\r
+       {0x8ce9,0xd2},\r
+       {0x8cea,0x25},\r
+       {0x8ceb,0x22},\r
+       {0x8cec,0x12},\r
+       {0x8ced,0x04},\r
+       {0x8cee,0x8b},\r
+       {0x8cef,0xf5},\r
+       {0x8cf0,0x09},\r
+       {0x8cf1,0x75},\r
+       {0x8cf2,0x0a},\r
+       {0x8cf3,0x01},\r
+       {0x8cf4,0x12},\r
+       {0x8cf5,0x08},\r
+       {0x8cf6,0xfa},\r
+       {0x8cf7,0xd2},\r
+       {0x8cf8,0x20},\r
+       {0x8cf9,0xc2},\r
+       {0x8cfa,0x26},\r
+       {0x8cfb,0xc2},\r
+       {0x8cfc,0x2f},\r
+       {0x8cfd,0x22},\r
+       {0x8cfe,0xe5},\r
+       {0x8cff,0x44},\r
+       {0x8d00,0xc3},\r
+       {0x8d01,0x95},\r
+       {0x8d02,0x43},\r
+       {0x8d03,0x40},\r
+       {0x8d04,0x01},\r
+       {0x8d05,0x22},\r
+       {0x8d06,0xe5},\r
+       {0x8d07,0x44},\r
+       {0x8d08,0x04},\r
+       {0x8d09,0xf5},\r
+       {0x8d0a,0x09},\r
+       {0x8d0b,0x12},\r
+       {0x8d0c,0x09},\r
+       {0x8d0d,0xee},\r
+       {0x8d0e,0x22},\r
+       {0x8d0f,0xe5},\r
+       {0x8d10,0x44},\r
+       {0x8d11,0x70},\r
+       {0x8d12,0x02},\r
+       {0x8d13,0xc3},\r
+       {0x8d14,0x22},\r
+       {0x8d15,0xe5},\r
+       {0x8d16,0x44},\r
+       {0x8d17,0x14},\r
+       {0x8d18,0xf5},\r
+       {0x8d19,0x09},\r
+       {0x8d1a,0x12},\r
+       {0x8d1b,0x09},\r
+       {0x8d1c,0xee},\r
+       {0x8d1d,0x22},\r
+       {0x8d1e,0x75},\r
+       {0x8d1f,0x2e},\r
+       {0x8d20,0x0b},\r
+       {0x8d21,0x75},\r
+       {0x8d22,0x2f},\r
+       {0x8d23,0x4f},\r
+       {0x8d24,0x90},\r
+       {0x8d25,0x0b},\r
+       {0x8d26,0x4d},\r
+       {0x8d27,0x12},\r
+       {0x8d28,0x04},\r
+       {0x8d29,0xda},\r
+       {0x8d2a,0xc2},\r
+       {0x8d2b,0x2c},\r
+       {0x8d2c,0x22},\r
+       {0x8d2d,0x75},\r
+       {0x8d2e,0x2e},\r
+       {0x8d2f,0x0b},\r
+       {0x8d30,0x75},\r
+       {0x8d31,0x2f},\r
+       {0x8d32,0x6b},\r
+       {0x8d33,0x90},\r
+       {0x8d34,0x0b},\r
+       {0x8d35,0x69},\r
+       {0x8d36,0x12},\r
+       {0x8d37,0x04},\r
+       {0x8d38,0xda},\r
+       {0x8d39,0xd2},\r
+       {0x8d3a,0x2c},\r
+       {0x8d3b,0x22},\r
+       {0x8d3c,0xe5},\r
+       {0x8d3d,0x45},\r
+       {0x8d3e,0x24},\r
+       {0x8d3f,0xfe},\r
+       {0x8d40,0x60},\r
+       {0x8d41,0x06},\r
+       {0x8d42,0x04},\r
+       {0x8d43,0x70},\r
+       {0x8d44,0x05},\r
+       {0x8d45,0xd2},\r
+       {0x8d46,0x28},\r
+       {0x8d47,0x22},\r
+       {0x8d48,0xc2},\r
+       {0x8d49,0x28},\r
+       {0x8d4a,0x22},\r
+       {0x8d4b,0xe4},\r
+       {0x8d4c,0xf5},\r
+       {0x8d4d,0x33},\r
+       {0x8d4e,0xf5},\r
+       {0x8d4f,0x34},\r
+       {0x8d50,0xf5},\r
+       {0x8d51,0x35},\r
+       {0x8d52,0xf5},\r
+       {0x8d53,0x36},\r
+       {0x8d54,0xc2},\r
+       {0x8d55,0x2d},\r
+       {0x8d56,0xc2},\r
+       {0x8d57,0x2e},\r
+       {0x8d58,0x22},\r
+       {0x8d59,0xe5},\r
+       {0x8d5a,0x27},\r
+       {0x8d5b,0xd3},\r
+       {0x8d5c,0x94},\r
+       {0x8d5d,0x00},\r
+       {0x8d5e,0x40},\r
+       {0x8d5f,0x03},\r
+       {0x8d60,0x15},\r
+       {0x8d61,0x27},\r
+       {0x8d62,0x22},\r
+       {0x8d63,0x12},\r
+       {0x8d64,0x0c},\r
+       {0x8d65,0xd8},\r
+       {0x8d66,0x22},\r
+       {0x8d67,0x12},\r
+       {0x8d68,0x0d},\r
+       {0x8d69,0x1e},\r
+       {0x8d6a,0xe4},\r
+       {0x8d6b,0xf5},\r
+       {0x8d6c,0x09},\r
+       {0x8d6d,0x12},\r
+       {0x8d6e,0x09},\r
+       {0x8d6f,0xee},\r
+       {0x8d70,0x22},\r
+       {0x3F00,0x00},\r
+       {0x3F01,0x00},\r
+       {0x3F02,0x00},\r
+       {0x3F03,0x00},\r
+       {0x3F04,0x00},\r
+       {0x3F05,0x00},\r
+       {0x3F06,0x00},\r
+       {0x3F07,0xFF},\r
+       {0x3104,0x00},\r
+       {0x0000,0x00}\r
+};\r
+#endif 
\ No newline at end of file
index 809b41ea4ff5463ce82ca4cd050857249ef17d2f..c9a427147d1ca0582a7286ad3116b19ad51ce7f5 100755 (executable)
@@ -22,6 +22,17 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/soc_camera.h>
 #include <mach/rk29_camera.h>
 
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do {                       \
+       if (debug >= level)                                     \
+       printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
+
+
 #define _CONS(a,b) a##b
 #define CONS(a,b) _CONS(a,b)
 
@@ -29,8 +40,11 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #define _STR(x) __STR(x)
 #define STR(x) _STR(x)
 
+#define MIN(x,y)   ((x<y) ? x: y)
+#define MAX(x,y)    ((x>y) ? x: y)
+
 /* Sensor Driver Configuration */
-#define SENSOR_NAME ov7675
+#define SENSOR_NAME RK29_CAM_SENSOR_OV7675
 #define SENSOR_V4L2_IDENT V4L2_IDENT_OV7675
 #define SENSOR_ID 0x76
 #define SENSOR_MIN_WIDTH    640//176
@@ -55,27 +69,10 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #define CONFIG_SENSOR_Mirror        0
 #define CONFIG_SENSOR_Flip          0
 
-#define CONFIG_SENSOR_I2C_SPEED     100000       /* Hz */
-
-#define CONFIG_SENSOR_TR      1
-#define CONFIG_SENSOR_DEBUG      1
-
-#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
-#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
-
-#define MIN(x,y)   ((x<y) ? x: y)
-#define MAX(x,y)    ((x>y) ? x: y)
-
-#if (CONFIG_SENSOR_TR)
-       #define SENSOR_TR(format, ...)      printk(format, ## __VA_ARGS__)
-       #if (CONFIG_SENSOR_DEBUG)
-       #define SENSOR_DG(format, ...)      printk(format, ## __VA_ARGS__)
-       #else
-       #define SENSOR_DG(format, ...)
-       #endif
-#else
-       #define SENSOR_TR(format, ...)
-#endif
+#define CONFIG_SENSOR_I2C_SPEED     250000       /* Hz */
+/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */
+#define CONFIG_SENSOR_I2C_NOSCHED   0
+#define CONFIG_SENSOR_I2C_RDWRCHK   0
 
 #define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
                           SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
@@ -90,6 +87,9 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #define COLOR_TEMPERATURE_HOME_DN       2500
 #define COLOR_TEMPERATURE_HOME_UP       3500
 
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
+
 struct reginfo
 {
     u8 reg;
@@ -144,7 +144,7 @@ static struct reginfo sensor_init_data[] =
        {0x0e, 0x61},
        {0x0f, 0x4b},
        {0x16, 0x02},
-       {0x1e, 0x07},
+       {0x1e, 0x07},       //0x27
        {0x21, 0x02},
        {0x22, 0x91},
        {0x29, 0x07},
@@ -1082,6 +1082,14 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);
 static int sensor_resume(struct soc_camera_device *icd);
 static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);
 static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);
+#if CONFIG_SENSOR_Effect
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);
+#endif
+static int sensor_deactivate(struct i2c_client *client);
+
 
 static struct soc_camera_ops sensor_ops =
 {
@@ -1119,6 +1127,8 @@ typedef struct sensor_info_priv_s
     int focus;
     int flash;
     int exposure;
+       bool snap2preview;
+       bool video2preview;
     unsigned char mirror;                                        /* HFLIP */
     unsigned char flip;                                          /* VFLIP */
     unsigned int winseqe_cur_addr;
@@ -1132,6 +1142,11 @@ struct sensor
     struct i2c_client *client;
     sensor_info_priv_t info_priv;
     int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */
+#if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_t tasklock_cnt;
+#endif
+       struct rk29camera_platform_data *sensor_io_request;
+    struct rk29camera_gpio_res *sensor_gpio_res;
 };
 
 static struct sensor* to_sensor(const struct i2c_client *client)
@@ -1139,6 +1154,44 @@ static struct sensor* to_sensor(const struct i2c_client *client)
     return container_of(i2c_get_clientdata(client), struct sensor, subdev);
 }
 
+static int sensor_task_lock(struct i2c_client *client, int lock)
+{
+#if CONFIG_SENSOR_I2C_NOSCHED
+       int cnt = 3;
+    struct sensor *sensor = to_sensor(client);
+
+       if (lock) {
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());
+                               msleep(35);
+                               cnt--;
+                       }
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());
+                               goto sensor_task_lock_err;
+                       }
+                       preempt_disable();
+               }
+
+               atomic_add(1, &sensor->tasklock_cnt);
+       } else {
+               if (atomic_read(&sensor->tasklock_cnt) > 0) {
+                       atomic_sub(1, &sensor->tasklock_cnt);
+
+                       if (atomic_read(&sensor->tasklock_cnt) == 0)
+                               preempt_enable();
+               }
+       }
+       return 0;
+sensor_task_lock_err:
+       return -1;  
+#else
+    return 0;
+#endif
+
+}
+
 /* sensor register write */
 static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
 {
@@ -1159,14 +1212,14 @@ static int sensor_write(struct i2c_client *client, u8 reg, u8 val)
     cnt = 3;
     err = -EAGAIN;
 
-    while ((cnt--) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
         err = i2c_transfer(client->adapter, msg, 1);
 
         if (err >= 0) {
             return 0;
         } else {
-            SENSOR_TR("\n %s write reg failed, try to write again!\n",SENSOR_NAME_STRING());
-            udelay(10);
+               SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);
+               udelay(10);
         }
     }
 
@@ -1201,14 +1254,14 @@ static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
 
     cnt = 1;
     err = -EAGAIN;
-    while ((cnt--) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
         err = i2c_transfer(client->adapter, msg, 2);
 
         if (err >= 0) {
             *val = buf[0];
             return 0;
         } else {
-               SENSOR_TR("\n %s read reg failed, try to read again! reg:0x%x \n",SENSOR_NAME_STRING(),(unsigned int)val);
+               SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val);
             udelay(10);
         }
     }
@@ -1220,20 +1273,43 @@ static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)
 #if 1
 static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)
 {
-    int err;
+    int err = 0, cnt;
     int i = 0;
+#if CONFIG_SENSOR_I2C_RDWRCHK    
+       char valchk;
+#endif
+
+       cnt = 0;
+       if (sensor_task_lock(client, 1) < 0)
+               goto sensor_write_array_end;
 
     while (regarray[i].reg != 0)
     {
         err = sensor_write(client, regarray[i].reg, regarray[i].val);
-        if (err != 0)
+        if (err < 0)
         {
-            SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i);
-            return err;
+            if (cnt-- > 0) {
+                           SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg);
+                               i = 0;
+                               continue;
+            } else {
+                SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING());
+                err = -EPERM;
+                               goto sensor_write_array_end;
+            }
+        } else {
+        #if CONFIG_SENSOR_I2C_RDWRCHK
+                       sensor_read(client, regarray[i].reg, &valchk);
+                       if (valchk != regarray[i].val)
+                               SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);
+               #endif
         }
         i++;
     }
-    return 0;
+
+sensor_write_array_end:
+       sensor_task_lock(client,0);
+       return err;
 }
 #else
 static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)
@@ -1256,7 +1332,50 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
     return 0;
 }
 #endif
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
+{
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       int ret = 0;
 
+    SENSOR_DG("%s %s  cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
+       switch (cmd)
+       {
+               case Sensor_PowerDown:
+               {
+                       if (icl->powerdown) {
+                               ret = icl->powerdown(icd->pdev, on);
+                               if (ret == RK29_CAM_IO_SUCCESS) {
+                                       if (on == 0) {
+                                               mdelay(2);
+                                               if (icl->reset)
+                                                       icl->reset(icd->pdev);
+                                       }
+                               } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {
+                                       ret = -ENODEV;
+                                       goto sensor_power_end;
+                               }
+                       }
+                       break;
+               }
+               case Sensor_Flash:
+               {
+                       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+               struct sensor *sensor = to_sensor(client);
+
+                       if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
+                               sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
+                       }
+            break;
+               }
+               default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+sensor_power_end:
+       return ret;
+}
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = sd->priv;
@@ -1267,7 +1386,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_INIT_ERR;
+       }
+
     /* soft reset */
+       if (sensor_task_lock(client,1)<0)
+               goto sensor_INIT_ERR;
     ret = sensor_write(client, 0x12, 0x80);
     if (ret != 0)
     {
@@ -1284,9 +1410,9 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
         goto sensor_INIT_ERR;
     }
-
-    icd->user_width = SENSOR_INIT_WIDTH;
-    icd->user_height = SENSOR_INIT_HEIGHT;
+       sensor_task_lock(client,0);
+    //icd->user_width = SENSOR_INIT_WIDTH;
+    //icd->user_height = SENSOR_INIT_HEIGHT;
     sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;
        sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT;
 
@@ -1331,30 +1457,35 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         sensor->info_priv.focus = qctrl->default_value;
        #endif
 
-       #if CONFIG_SENSOR_Flash
-       sensor_set_flash();
+       #if CONFIG_SENSOR_Flash 
        qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);
        if (qctrl)
         sensor->info_priv.flash = qctrl->default_value;
     #endif
 
-    SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,icd->user_width,icd->user_height);
+    SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);
 
     return 0;
 sensor_INIT_ERR:
+       sensor_task_lock(client,0);
+       sensor_deactivate(client);
     return ret;
 }
 
-static int sensor_deactivate(struct v4l2_subdev *sd)
+static int sensor_deactivate(struct i2c_client *client)
 {
-       //struct i2c_client *client = sd->priv;
+       struct soc_camera_device *icd = client->dev.platform_data;
        //u8 reg_val;
 
-       SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
+       SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);
 
-
+       /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
+       icd->user_width = SENSOR_INIT_WIDTH;
+    icd->user_height = SENSOR_INIT_HEIGHT;
+       msleep(100);
        return 0;
 }
 static  struct reginfo sensor_power_down_sequence[]=
@@ -1365,32 +1496,21 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
 {
     int ret;
     struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-    struct soc_camera_link *icl;
 
-
-    if (pm_msg.event == PM_EVENT_SUSPEND)
-    {
+    if (pm_msg.event == PM_EVENT_SUSPEND) {
         SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());
         ret = sensor_write_array(client, sensor_power_down_sequence) ;
-        if (ret != 0)
-        {
+        if (ret != 0) {
             SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);
             return ret;
-        }
-        else
-        {
-            icl = to_soc_camera_link(icd);
-            if (icl->power) {
-                ret = icl->power(icd->pdev, 0);
-                if (ret < 0) {
-                                   SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
-                    return -EINVAL;
-                }
+        } else {
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);
+            if (ret < 0) {
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
+                return -EINVAL;
             }
         }
-    }
-    else
-    {
+    } else {
         SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());
         return -EINVAL;
     }
@@ -1399,16 +1519,12 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
 
 static int sensor_resume(struct soc_camera_device *icd)
 {
-    struct soc_camera_link *icl;
-    int ret;
+       int ret;
 
-    icl = to_soc_camera_link(icd);
-    if (icl->power) {
-        ret = icl->power(icd->pdev, 1);
-        if (ret < 0) {
-                       SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
-            return -EINVAL;
-        }
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);
+    if (ret < 0) {
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
+        return -EINVAL;
     }
 
        SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());
@@ -1447,11 +1563,48 @@ static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 
     return 0;
 }
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
+
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+    bool ret = false;
+
+       if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) {
+               ret = true;
+       }
+
+       if (ret == true)
+               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
+}
 static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
     struct i2c_client *client = sd->priv;
     struct sensor *sensor = to_sensor(client);
     struct v4l2_pix_format *pix = &f->fmt.pix;
+       const struct v4l2_queryctrl *qctrl;
+       struct soc_camera_device *icd = client->dev.platform_data;
     struct reginfo *winseqe_set_addr=NULL;
        char readval;
     int ret=0, set_w,set_h;
@@ -1538,22 +1691,76 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);
     }
 
-    if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr)
-    {
+    if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr) {
+        #if CONFIG_SENSOR_Flash
+        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_On);
+                SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());
+            }           
+        } else {                                        /* ddl@rock-chips.com : Video */
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());
+            }
+        }
+        #endif
         ret |= sensor_write_array(client, winseqe_set_addr);
         if (ret != 0) {
             SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());
+            #if CONFIG_SENSOR_Flash
+            if (sensor_fmt_capturechk(sd,f) == true) {
+                if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
+                    sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+                    SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());
+                }
+            }
+            #endif
             goto sensor_s_fmt_end;
         }
 
         sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;
 
+               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */
+        #if CONFIG_SENSOR_Effect
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+        #endif
+        #if CONFIG_SENSOR_WhiteBalance
+                       if (sensor->info_priv.whiteBalance != 0) {
+                               qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                               sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+                       }
+        #endif
+                       sensor->info_priv.snap2preview = true;
+               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */
+               #if CONFIG_SENSOR_Effect
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+        #endif
+        #if CONFIG_SENSOR_WhiteBalance
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+        #endif
+                       sensor->info_priv.video2preview = true;
+               } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {
+               #if CONFIG_SENSOR_Effect
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);
+        #endif
+        #if CONFIG_SENSOR_WhiteBalance
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);
+        #endif
+                       sensor->info_priv.video2preview = false;
+                       sensor->info_priv.snap2preview = false;
+               }
 
         SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
     }
     else
     {
-        SENSOR_TR("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
+        SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
     }
 
        pix->width = set_w;
@@ -1857,6 +2064,24 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4
     return -EINVAL;
 }
 #endif
+#if CONFIG_SENSOR_Flash
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{    
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {
+        if (value == 3) {       /* ddl@rock-chips.com: torch */
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Torch);   /* Flash On */
+        } else {
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Off);
+        }
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+        return 0;
+    }
+    
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+    return -EINVAL;
+}
+#endif
+
 static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
     struct i2c_client *client = sd->priv;
@@ -2191,6 +2416,8 @@ static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_c
 #if CONFIG_SENSOR_Flash
         case V4L2_CID_FLASH:
             {
+                if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)
+                    return -EINVAL;
                 sensor->info_priv.flash = ext_ctrl->value;
 
                 SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);
@@ -2269,6 +2496,10 @@ static int sensor_video_probe(struct soc_camera_device *icd,
            to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
                return -ENODEV;
 
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
     /* soft reset */
     ret = sensor_write(client, 0x12, 0x80);
     if (ret != 0)
@@ -2307,19 +2538,64 @@ sensor_video_probe_err:
 
 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
+       struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
+    struct sensor *sensor = to_sensor(client);
+    int ret = 0;
+#if CONFIG_SENSOR_Flash        
+    int i;
+#endif
+    
        SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
        switch (cmd)
        {
                case RK29_CAM_SUBDEV_DEACTIVATE:
                {
-                       sensor_deactivate(sd);
+                       sensor_deactivate(client);
+                       break;
+               }
+
+               case RK29_CAM_SUBDEV_IOREQUEST:
+               {
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
+            /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
+               for this project */
+            #if CONFIG_SENSOR_Flash    
+               if (sensor->sensor_gpio_res) { 
+                if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {
+                    for (i = 0; i < icd->ops->num_controls; i++) {
+                               if (V4L2_CID_FLASH == icd->ops->controls[i].id) {
+                                       memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                       
+                               }
+                    }
+                    sensor->info_priv.flash = 0xff;
+                    SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());
+                }
+               }
+            #endif
                        break;
                }
                default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
                        break;
+               }
        }
-
-       return 0;
+sensor_ioctl_end:
+       return ret;
 
 }
 static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {
@@ -2379,12 +2655,16 @@ static int sensor_probe(struct i2c_client *client,
     /* Second stage probe - when a capture adapter is there */
     icd->ops           = &sensor_ops;
     icd->y_skip_top            = 0;
+       #if CONFIG_SENSOR_I2C_NOSCHED
+       atomic_set(&sensor->tasklock_cnt,0);
+       #endif
 
     ret = sensor_video_probe(icd, client);
-    if (ret) {
+    if (ret < 0) {
         icd->ops = NULL;
         i2c_set_clientdata(client, NULL);
         kfree(sensor);
+               sensor = NULL;
     }
     SENSOR_DG("\n%s..%s..%d  ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);
     return ret;
@@ -2399,7 +2679,7 @@ static int sensor_remove(struct i2c_client *client)
     i2c_set_clientdata(client, NULL);
     client->driver = NULL;
     kfree(sensor);
-
+       sensor = NULL;
     return 0;
 }
 
diff --git a/drivers/media/video/sid130B.c b/drivers/media/video/sid130B.c
new file mode 100755 (executable)
index 0000000..3bd9085
--- /dev/null
@@ -0,0 +1,3052 @@
+/*\r
+o* Driver for MT9M001 CMOS Image Sensor from Micron\r
+ *\r
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License version 2 as\r
+ * published by the Free Software Foundation.\r
+ */\r
+\r
+#include <linux/videodev2.h>\r
+#include <linux/slab.h>\r
+#include <linux/i2c.h>\r
+#include <linux/log2.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/delay.h>\r
+#include <linux/circ_buf.h>\r
+#include <linux/miscdevice.h>\r
+#include <media/v4l2-common.h>\r
+#include <media/v4l2-chip-ident.h>\r
+#include <media/soc_camera.h>\r
+#include <mach/rk29_camera.h>\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do {                       \\r
+       if (debug >= level)                                     \\r
+       printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)\r
+#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)\r
+\r
+\r
+#define _CONS(a,b) a##b\r
+#define CONS(a,b) _CONS(a,b)\r
+\r
+#define __STR(x) #x\r
+#define _STR(x) __STR(x)\r
+#define STR(x) _STR(x)\r
+\r
+#define MIN(x,y)   ((x<y) ? x: y)\r
+#define MAX(x,y)    ((x>y) ? x: y)\r
+\r
+/* Sensor Driver Configuration */\r
+#define SENSOR_NAME sid130B\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_SID130B\r
+#define SENSOR_ID 0x1B\r
+#define SENSOR_MIN_WIDTH    176\r
+#define SENSOR_MIN_HEIGHT   144\r
+#define SENSOR_MAX_WIDTH    1600\r
+#define SENSOR_MAX_HEIGHT   1200\r
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */\r
+#define SENSOR_INIT_HEIGHT  480\r
+#define SENSOR_INIT_WINSEQADR sensor_vga\r
+#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY\r
+\r
+#define CONFIG_SENSOR_WhiteBalance 1\r
+#define CONFIG_SENSOR_Brightness       0\r
+#define CONFIG_SENSOR_Contrast      0\r
+#define CONFIG_SENSOR_Saturation    0\r
+#define CONFIG_SENSOR_Effect        1\r
+#define CONFIG_SENSOR_Scene         0\r
+#define CONFIG_SENSOR_DigitalZoom   0\r
+#define CONFIG_SENSOR_Focus         0\r
+#define CONFIG_SENSOR_Exposure      0\r
+#define CONFIG_SENSOR_Flash         0\r
+#define CONFIG_SENSOR_Mirror        0\r
+#define CONFIG_SENSOR_Flip          0\r
+\r
+#define CONFIG_SENSOR_I2C_SPEED     80000       /* Hz */\r
+/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */\r
+#define CONFIG_SENSOR_I2C_NOSCHED   0\r
+#define CONFIG_SENSOR_I2C_RDWRCHK   0\r
+\r
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\\r
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW|\\r
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)\r
+\r
+#define COLOR_TEMPERATURE_CLOUDY_DN  6500\r
+#define COLOR_TEMPERATURE_CLOUDY_UP    8000\r
+#define COLOR_TEMPERATURE_CLEARDAY_DN  5000\r
+#define COLOR_TEMPERATURE_CLEARDAY_UP    6500\r
+#define COLOR_TEMPERATURE_OFFICE_DN     3500\r
+#define COLOR_TEMPERATURE_OFFICE_UP     5000\r
+#define COLOR_TEMPERATURE_HOME_DN       2500\r
+#define COLOR_TEMPERATURE_HOME_UP       3500\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+struct reginfo\r
+{\r
+    u8 reg;\r
+    u8 val;\r
+};\r
+\r
+/* init 352X288 SVGA */\r
+static struct reginfo sensor_init_data[] =\r
+{\r
+       {0x00,  0x00},  \r
+       {0x04,  0x00},  //Group A 0x10\r
+       {0x05,  0x0F},  //UXGA Output\r
+       {0x06,  0x86}, \r
+       {0x07,  0x08}, \r
+\r
+\r
+       {0x08,  0xa2},  //PLL off\r
+       {0x09,  0x12},  \r
+       {0x0A,  0x12},  \r
+       {0x10,  0x17},  \r
+       {0x11,  0x01}, \r
+       {0x12,  0x8A}, \r
+       {0x13,  0x1a}, \r
+       {0x14,  0x27}, \r
+       {0x15,  0x22}, \r
+\r
+       {0x17,  0xCb},  \r
+       {0x18,  0x38},  \r
+       \r
+       {0x40,  0x0f}, \r
+       {0x41,  0x17}, \r
+       {0x42,  0x52}, \r
+       {0x43,  0x80}, \r
+       {0x44,  0x00}, \r
+       {0x45,  0x00}, \r
+\r
+//Flicker - 50Hz  - Still mode ,     \r
+       {0x00,  0x00}, \r
+       {0x20,  0x00}, \r
+       {0x21,  0x02}, \r
+       {0x23,  0x29},//15}, \r
+       {0x00,  0x01}, \r
+       {0x35,  0x50},//3c}, \r
+\r
+//Flicker - 50Hz - Preview mode 24MHz MCLK\r
+       {0x00,  0x00}, \r
+       {0x24,  0x00}, \r
+       {0x25,  0xe6},//10}, \r
+       {0x27,  0x0d},//4b}, \r
+       {0x00,  0x01}, \r
+       {0x34,  0x80},//64}, \r
+\r
+\r
+//AE Block \r
+       {0x00,  0x01}, \r
+       {0x10,  0x00}, \r
+       {0x11,  0x0a}, //.0c\r
+       {0x12,  0x78}, \r
+       {0x13,  0x78}, \r
+       {0x14,  0x78}, \r
+       {0x17,  0xC4}, \r
+       {0x1c,  0x05},    \r
+\r
+       {0x36,  0x28},  //26\r
+\r
+       {0x40,  0x40},  //Max Again  //anyuan\r
+       //{0x41,  0x20}, \r
+       //{0x42,  0x20}, \r
+       //{0x43,  0x00}, \r
+       //{0x44,  0x00}, \r
+       //{0x45,  0x01}, \r
+       //{0x46,  0x1c}, \r
+       //{0x47,  0x11}, \r
+       //{0x48,  0x15}, \r
+       //{0x49,  0x17}, \r
+       //{0x4A,  0x1a}, \r
+       //{0x4B,  0x1c}, \r
+       //{0x4C,  0x1e}, \r
+       //{0x4D,  0x1e}, \r
+       //{0x4E,  0x0f}, \r
+       //{0x4F,  0x09}, \r
+       //{0x50,  0x07}, \r
+       //{0x51,  0x05}, \r
+       //{0x52,  0x04}, \r
+       //{0x53,  0x03}, \r
+       //{0x54,  0x02}, \r
+       //{0x55,  0x01}, \r
+       //{0x66,  0x00}, \r
+       //{0x67,  0x00}, \r
+       //{0x68,  0x00}, \r
+       //{0x69,  0x00}, \r
+       //{0x6a,  0x00}, \r
+       //{0x6b,  0x00},\r
+\r
+       {0x70,  0xc4}, \r
+       {0x73,  0x22}, \r
+       {0x74,  0x07}, \r
+       {0x77,  0xd0}, \r
+       {0x78,  0xd8}, \r
+       {0x79,  0x70}, \r
+  //\r
+       {0x90,  0x00}, \r
+       {0x92,  0x0c}, //0bank 0x11 °ú µ¿ÀÏ \r
+       {0x95,  0x40},  //0 bank 0x40 °ú µ¿ÀÏ  \r
+       //AWB Block\r
+\r
+       {0x00,  0x02}, \r
+       {0x10,  0xD3}, \r
+       {0x11,  0x11}, \r
+       {0x13,  0x7e}, \r
+       {0x14,  0x7c}, \r
+       {0x15,  0xee}, \r
+       {0x16,  0x80}, \r
+       {0x17,  0xd0}, \r
+       {0x18,  0x80}, \r
+       {0x19,  0x98}, \r
+       {0x1A,  0x68}, \r
+       {0x1B,  0x98}, \r
+       {0x1C,  0x68}, \r
+       {0x1D,  0x90}, \r
+       {0x1E,  0x74}, \r
+       {0x20,  0xF0}, \r
+       {0x21,  0x85}, \r
+       {0x22,  0xB4}, \r
+       {0x23,  0x20}, \r
+       {0x25,  0x20}, \r
+       {0x26,  0x05}, \r
+       {0x27,  0x78}, \r
+       {0x28,  0xd8}, \r
+       {0x29,  0xb8}, \r
+       {0x2A,  0x88}, \r
+       {0x30,  0x00}, \r
+       {0x31,  0x10}, \r
+       {0x32,  0x00}, \r
+       {0x33,  0x10}, \r
+       {0x34,  0x06}, \r
+       {0x35,  0x30}, \r
+       {0x36,  0x04}, \r
+       {0x37,  0xA0}, \r
+       {0x40,  0x01}, \r
+       {0x41,  0x04}, \r
+       {0x42,  0x08}, \r
+       {0x43,  0x10}, \r
+       {0x44,  0x13}, \r
+       {0x45,  0x6B}, \r
+       {0x46,  0x82},  \r
+\r
+\r
+\r
+//CMA change  -D65~A\r
+       {0x53,  0xa1},  //AWB R Gain for D30 to D20\r
+       {0x54,  0xc0},  //AWB B Gain for D30 to D20\r
+       {0x55,  0xa1},  //AWB R Gain for D20 to D30\r
+       {0x56,  0xc0},  //AWB B Gain for D20 to D30\r
+       {0x57,  0xc8},  //AWB R Gain for D65 to D30\r
+       {0x58,  0xa0},  //AWB B Gain for D65 to D30\r
+       {0x59,  0xc8},  //AWB R Gain for D30 to D65\r
+       {0x5A,  0xa0},  //AWB B Gain for D30 to D65\r
+\r
+  {0x64,  0x00},\r
+  {0x65,  0x00},\r
+  {0x66,  0x00},\r
+  {0x67,  0x00},\r
+  {0x68,  0xa5},\r
+  {0x69,  0xb4},\r
+  {0x6a,  0xb3},\r
+  {0x6b,  0xac},\r
+  {0x6c,  0xb7},\r
+  {0x6d,  0x98},\r
+  {0x6e,  0xba},\r
+  {0x6f,  0x90},\r
+  \r
+  {0x70,  0xbf},\r
+  {0x71,  0x9b},\r
+  {0x72,  0xce},\r
+  {0x73,  0x8c},\r
+  {0x74,  0x7f},\r
+  {0x75,  0x8c},\r
+  {0x76,  0xad},\r
+  {0x77,  0xba},\r
+  {0x78,  0x8f},\r
+  {0x79,  0x9a},\r
+  {0x7A,  0xa3},\r
+  {0x7B,  0xac},\r
+  {0x7C,  0xa0},\r
+  {0x7D,  0xa9},\r
+  {0x7E,  0x95},\r
+  {0x7F,  0xac},\r
+  {0x80,  0xad},\r
+  {0x81,  0xbc},\r
+  {0x82,  0x98},\r
+  {0x83,  0xa4},\r
+  {0x84,  0x00},\r
+  {0x85,  0x00},\r
+  {0x86,  0x00},\r
+  {0x87,  0x00},\r
+  {0x88,  0xc9},\r
+  {0x89,  0xd5},\r
+  {0x8a,  0x70},\r
+  {0x8b,  0x7b},\r
+  {0x8c,  0xd0},\r
+  {0x8d,  0xe5},\r
+  {0x8e,  0x58},\r
+  {0x8f,  0x70},\r
+    \r
+       {0xB4,  0x05},  \r
+       {0xB5,  0x0F},  \r
+       {0xB6,  0x06},  \r
+       {0xB7,  0x06},  \r
+       {0xB8,  0x40},  \r
+       {0xB9,  0x10},  \r
+       {0xBA,  0x06},  \r
+\r
+//IDP\r
+       {0x00,  0x03}, \r
+       {0x10,  0xFF}, \r
+       {0x11,  0x1D}, \r
+       {0x12,  0x1D}, \r
+       {0x13,  0xFF}, \r
+       {0x14,  0x00}, \r
+       {0x15,  0xc0}, \r
+\r
+//DPC\r
+       {0x30,  0x88},  //DPCNRCTRL\r
+       {0x31,  0x14},  //DPTHR @ AGAIN = 00\r
+       {0x32,  0x10},  //DPTHR @ AGAIN = 20\r
+       {0x33,  0x0c},  //DPTHR @ AGAIN = 40\r
+       {0x34,  0x08},  //DPTHR @ AGAIN = 60\r
+       {0x35,  0x04},  //DPTHR @ AGAIN = 80\r
+       {0x36,  0x44},  //DPTHVRNG\r
+       {0x37,  0x66},  //DPNUMBER\r
+       {0x38,  0x00},  //0x00  // NRTHR0 @ AGAIN = 00\r
+       {0x39,  0x04},  //0x0C  // NRTHR1 @ AGAIN = 20\r
+       {0x3A,  0x04},  //0x18  // NRTHR2 @ AGAIN = 40\r
+       {0x3B,  0x2c},  //0x30  // NRTHR3 @ AGAIN = 60\r
+       {0x3C,  0x3c},  //                 NRTHR4 @ AGAIN = 80\r
+       {0x3D,  0x04},  //NRTHVRNG0 @ AGAIN = 00\r
+       {0x3E,  0x04},  //NRTHVRNG1 @ AGAIN = 20\r
+       {0x3F,  0x04},  //NRTHVRNG2 @ AGAIN = 40\r
+       {0x40,  0x2c},  //NRTHVRNG3 @ AGAIN = 60\r
+       {0x41,  0x3c},  //NRTHVRNG4 @ AGAIN = 80\r
+       {0x42,  0xff},  //NRTHVRNGMAX\r
+       {0x43,  0x40},  //NRTHRWGT\r
+       {0x44,  0x40},  //BASELVL\r
+       {0x45,  0x06},  //SHUMAXH\r
+       {0x46,  0x40},  //SHUMAXL\r
+       {0x47,  0x30},  //ILLUMITHDRK\r
+\r
+// shading\r
+       {0x50,  0x0a},  //0x00      \r
+       {0x51,  0x20},  //0x45  \r
+       {0x52,  0x12},  //0x24      \r
+       {0x53,  0x12},  //0x24 \r
+                                      \r
+       {0x54,  0x22},  //0x00      \r
+       {0x55,  0x18},  //0x40  \r
+       {0x56,  0x08},  //0x10      \r
+       {0x57,  0x10},  //0x20 \r
+                                        \r
+       {0x58,  0x22},  //0x00      \r
+       {0x59,  0x18},  //0x40  \r
+       {0x5A,  0x08},  //0x10      \r
+       {0x5B,  0x10},  //0x20 \r
+                                       \r
+       {0x5C,  0x25},  //0x04      \r
+       {0x5D,  0x1a},  //0x55  \r
+       {0x5E,  0x12},  //0x25    \r
+       {0x5F,  0x10},  //0x20 \r
+             \r
+       {0x60,  0x32},  //0x32                   \r
+       {0x61,  0x20},  //20//\r
+       {0x62,  0x58},  //67\r
+//     {0x63,  0x89 //8c R Center start gain\r
+//     {0x66,  0x79 //B Center start gain   73               \r
+       {0x6B,  0x00}, //01 //01                 \r
+       {0x6C,  0x01}, //22                   \r
+       {0x6D,  0x23}, //22                   \r
+       {0x6E,  0x55}, //55                   \r
+       {0x6F,  0x55}, //77                   \r
+       {0x70,  0x55}, //65                   \r
+       {0x71,  0x00}, //01 //AB (6)               \r
+       {0x72,  0x01}, //23     (5)             \r
+       {0x73,  0x23}, //33     (4)            \r
+       {0x74,  0x44}, //45     (3)             \r
+       {0x75,  0x45}, //55     (2)               \r
+       {0x76,  0x66}, //55     (1)             \r
+       {0x77,  0x00}, //01 //AB (6)                 \r
+       {0x78,  0x01}, //23     (5)              \r
+       {0x79,  0x23}, //33     (4)              \r
+       {0x7A,  0x44}, //45     (3)              \r
+       {0x7B,  0x45}, //55     (2)                \r
+       {0x7C,  0x66}, //55     (1)              \r
+       {0x7D,  0x00}, //00    //00                   \r
+       {0x7E,  0x00}, //00    //00                   \r
+       {0x7F,  0x12}, //11    //12                   \r
+       {0x80,  0x33}, //33    //33 //44               \r
+       {0x81,  0x44}, //33    //33 //44                  \r
+       {0x82,  0x55}, //22    //44 //45 \r
+       //{0x83,  0x14}, \r
+       //{0x84,  0x0f}, \r
+\r
+       {0x94,0x02},\r
+       {0x95,0x80},\r
+       {0x96,0x01},\r
+       {0x97,0xe0}, \r
+\r
+//Interpolation\r
+       {0xA0,  0x3F},\r
+       {0xA1,  0x05},\r
+       {0xA2,  0xB7},\r
+       {0xA3,  0xB7},\r
+       {0xA4,  0x04},\r
+       {0xA5,  0xFF},\r
+       {0xA6,  0x04},\r
+       {0xA7,  0xFF},\r
+       {0xA8,  0x00},\r
+       {0xA9,  0x00},\r
+       {0xAA,  0x00},\r
+       {0xAB,  0x00},\r
+       {0xAC,  0x60},\r
+       {0xAD,  0x18},\r
+       {0xAE,  0x10},\r
+       {0xAF,  0x20},\r
+       {0xB0,  0x08},\r
+       {0xB1,  0x00},\r
+\r
+//Color Matrix for D65\r
+#if 0\r
+       {0xC0,  0x2F}, // CMASB D20 or D30 or Dark Condition Color Matrix Selection\r
+       {0xC1,  0x66}, \r
+       {0xC2,  0xd4}, \r
+       {0xC3,  0x05}, \r
+       {0xC4,  0xf0}, \r
+       {0xC5,  0x5a}, \r
+       {0xC6,  0xf5}, \r
+       {0xC7,  0xf9}, \r
+       {0xC8,  0xbf}, \r
+       {0xC9,  0x88}, \r
+       {0xCA,  0xa0}, \r
+       {0xCB,  0x50}, \r
+       {0xCC,  0xe2}, \r
+       {0xCD,  0x00}, \r
+       {0xCE,  0x00}, \r
+#else\r
+{0xC0,  0x2F}, // CMASB D20 or D30 or Dark Condition Color Matrix Selection\r
+{0xC1,  0x71}, \r
+{0xC2,  0xcc}, \r
+{0xC3,  0x01}, \r
+{0xC4,  0xe8}, \r
+{0xC5,  0x68}, \r
+{0xC6,  0xef}, \r
+{0xC7,  0xfa}, \r
+{0xC8,  0xc6}, \r
+{0xC9,  0x7e}, \r
+{0xCA,  0xec}, \r
+{0xCB,  0x67}, \r
+{0xCC,  0x34}, \r
+{0xCD,  0x3a}, \r
+{0xCE,  0x08},\r
+\r
+#endif\r
+//Color Matrix for CWF\r
+       {0xD0,  0x2F}, \r
+       {0xD1,  0x66}, \r
+       {0xD2,  0xd4}, \r
+       {0xD3,  0x05}, \r
+       {0xD4,  0xf0}, \r
+       {0xD5,  0x5a}, \r
+       {0xD6,  0xf5}, \r
+       {0xD7,  0xe9}, \r
+       {0xD8,  0xbf}, \r
+       {0xD9,  0x88},\r
+       {0xDA,  0xa0}, \r
+       {0xDB,  0x50}, \r
+       {0xDC,  0xe2}, \r
+       {0xDD,  0x00}, \r
+       {0xDE,  0x00}, \r
+\r
+//Color Matrix for A\r
+       {0xE0,  0x2F}, \r
+       {0xE1,  0x6e}, \r
+       {0xE2,  0xc7}, \r
+       {0xE3,  0x0d}, \r
+       {0xE4,  0xe3}, \r
+       {0xE5,  0x61}, \r
+       {0xE6,  0xfa}, \r
+       {0xE7,  0xe5}, \r
+       {0xE8,  0xcb}, \r
+       {0xE9,  0x8e}, \r
+       {0xEA,  0xc4}, \r
+       {0xEB,  0x04}, \r
+       {0xEC,  0xf3}, \r
+       {0xED,  0xdd}, \r
+       {0xEE,  0x06}, \r
+\r
+//IDP 4\r
+       {0x00,  0x04}, \r
+\r
+//Gamma - r   \r
+       {0x10,  0x00}, \r
+       {0x11,  0x04}, \r
+       {0x12,  0x10},\r
+       {0x13,  0x20},\r
+       {0x14,  0x40},\r
+       {0x15,  0x5c},\r
+       {0x16,  0x74},\r
+       {0x17,  0x84},\r
+       {0x18,  0x98},\r
+       {0x19,  0xa4},\r
+       {0x1A,  0xb0},\r
+       {0x1B,  0xc8},\r
+       {0x1C,  0xdc},\r
+       {0x1D,  0xf0},\r
+       {0x1E,  0xf8},\r
+       {0x1F,  0xFF},\r
+                        \r
+//Gamma - G             \r
+       {0x20,  0x00}, \r
+       {0x21,  0x04}, \r
+       {0x22,  0x10},\r
+       {0x23,  0x20},\r
+       {0x24,  0x40},\r
+       {0x25,  0x5c},\r
+       {0x26,  0x74},\r
+       {0x27,  0x84},\r
+       {0x28,  0x98},\r
+       {0x29,  0xa4},\r
+       {0x2A,  0xb0},\r
+       {0x2B,  0xc8},\r
+       {0x2C,  0xdc},\r
+       {0x2D,  0xf0},\r
+       {0x2E,  0xf8},\r
+       {0x2F,  0xFF},\r
+                        \r
+//Gamma - B             \r
+       {0x30,  0x00}, \r
+       {0x31,  0x04}, \r
+       {0x32,  0x10},\r
+       {0x33,  0x20},\r
+       {0x34,  0x40},\r
+       {0x35,  0x5c},\r
+       {0x36,  0x74},\r
+       {0x37,  0x84},\r
+       {0x38,  0x98},\r
+       {0x39,  0xa4},\r
+       {0x3A,  0xb0},\r
+       {0x3B,  0xc8},\r
+       {0x3C,  0xdc},\r
+       {0x3D,  0xf0},\r
+       {0x3E,  0xf8},\r
+       {0x3F,  0xFF},\r
+\r
+//DARK GAMMA\r
+       {0x40,  0x00}, \r
+       {0x41,  0x0b}, \r
+       {0x42,  0x15},\r
+       {0x43,  0x29},\r
+       {0x44,  0x47},\r
+       {0x45,  0x5D},\r
+       {0x46,  0x72},\r
+       {0x47,  0x83},\r
+       {0x48,  0x92},\r
+       {0x49,  0xA0},\r
+       {0x4A,  0xac},\r
+       {0x4B,  0xc6},\r
+       {0x4C,  0xdA},\r
+       {0x4D,  0xeC},\r
+       {0x4E,  0xf6},\r
+       {0x4F,  0xFF},\r
+  \r
+       {0x50,  0x00}, //DARK GAMMA on/off\r
+       \r
+//CSC                   \r
+       {0x60,  0x33}, \r
+       {0x61,  0x20}, \r
+       {0x62,  0xE4}, \r
+       {0x63,  0xFA}, \r
+       {0x64,  0x13}, \r
+       {0x65,  0x25}, \r
+       {0x66,  0x07}, \r
+       {0x67,  0xF5}, \r
+       {0x68,  0xEA}, \r
+       {0x69,  0x20}, \r
+       {0x6A,  0xC8}, \r
+       {0x6B,  0xC4}, \r
+       {0x6C,  0x84}, \r
+       {0x6D,  0x04}, \r
+       {0x6E,  0x0C}, \r
+       {0x6F,  0x00}, \r
+                        \r
+//Edge                  \r
+// {0x70,  0x00},\r
+// {0x71,  0x18},\r
+// {0x72,  0x18},\r
+// {0x73,  0x04},\r
+// {0x74,  0x08},\r
+// {0x76,  0x20},\r
+// {0x77,  0x04},\r
+// {0x78,  0x08},\r
+// {0x7a,  0x20},\r
+// {0x7d,  0x08},\r
+// {0X7e,  0x30},\r
+\r
+       {0x80,  0x22}, \r
+       {0x81,  0x14}, \r
+       {0x82,  0x14}, \r
+       {0x83,  0x04}, \r
+       {0x84,  0x06}, \r
+       {0x85,  0x06}, \r
+       {0x87,  0x04},\r
+       {0x88,  0x10},\r
+       {0x89,  0x06},\r
+       {0X90,  0x06},\r
+       {0x91,  0x03},\r
+       {0x93,  0xe0},\r
+\r
+//Cr/Cb Coring\r
+       {0x94,  0x00}, \r
+       {0x95,  0x00}, \r
+       {0x96,  0x4C}, \r
+       {0x97,  0x76}, \r
+       {0x9A,  0xf5}, \r
+\r
+       {0xA1,  0x08},   //@ 0\r
+       {0xA2,  0x10},   //@ 20\r
+       {0xA3,  0x16},   //@ 40\r
+       {0xA4,  0x20},   //@ 60\r
+       {0xA5,  0x30},   //@ 80\r
+       {0xA6,  0xa0}, \r
+       {0xA7,  0x06}, \r
+       {0xA8,  0x40}, \r
+\r
+       {0xA9,  0x38}, \r
+       {0xAa,  0x35}, \r
+\r
+       {0xAc,  0xff}, \r
+       {0xAd,  0x09}, \r
+       {0xAe,  0x96}, \r
+       {0xAf,  0x18}, \r
+\r
+       {0xB2,  0x38},   //color suppression start\r
+       {0xB3,  0x53}, \r
+       {0xB6,  0x00}, \r
+       \r
+//Color Saturation\r
+       {0xBC, 0x10}, \r
+       {0xBD, 0x10}, \r
+       {0xBE, 0x10}, \r
+       {0xBF, 0x10}, \r
+       {0xc0, 0x10}, \r
+       {0xc1, 0x10},   \r
+       {0xc2, 0x10}, \r
+       {0xc3, 0x10}, \r
+       {0xc4, 0x10}, \r
+       {0xc5, 0x10}, \r
+\r
+       {0xcc, 0x04}, \r
+       {0xcd, 0x40}, \r
+       {0xce, 0x00}, \r
+                      \r
+//IDP 3                 \r
+       {0x00,  0x05}, \r
+                        \r
+//Memory                \r
+       {0x40,  0x15}, \r
+       {0x41,  0x28}, \r
+       {0x42,  0x04}, \r
+       {0x43,  0x15}, \r
+       {0x44,  0x28}, \r
+       {0x45,  0x04}, \r
+       {0x46,  0x15}, \r
+       {0x47,  0x28}, \r
+       {0x48,  0x04}, \r
+                        \r
+//Knee                  \r
+       {0x90,  0xca},  //\r
+       {0x91,  0x81},  //knee function selection/knee point H\r
+       {0x92,  0x00},  //knee point L\r
+       {0x93,  0x50},  //Knee gain\r
+       {0x94,  0x41},  //[6:4]knee start H/[2:0]Knee END H\r
+       {0x95,  0x7e},  //knee start L\r
+       {0x96,  0x48},  //knee END L\r
+                        \r
+//ADG                   \r
+       {0x99,  0xC0}, \r
+       {0xA0,  0x10}, \r
+       {0xA1,  0x22}, \r
+       {0xA2,  0x36}, \r
+       {0xA3,  0x49}, \r
+       {0xA4,  0x5D}, \r
+       {0xA5,  0x70}, \r
+       {0xA6,  0x82}, \r
+       {0xA7,  0x94}, \r
+       {0xA8,  0xA5}, \r
+       {0xA9,  0xB5}, \r
+       {0xAA,  0xC3}, \r
+       {0xAB,  0xD1}, \r
+       {0xAC,  0xDE}, \r
+       {0xAD,  0xEA}, \r
+       {0xAE,  0xF5}, \r
+       {0xAF,  0xFF}, \r
+                        \r
+//YXGMA                 \r
+       {0xB0,  0xc0},  //YGMACTRL\r
+       {0xB1,  0x04},  //YGMASLOP\r
+       {0xB8,  0x0f},  //DRKTHR1\r
+       {0xB9,  0x10},  //DRKTHR2\r
+       //{0xBA,  0x38},  //DRKTHR3\r
+       //{0xBB,  0x39},  //DRKTHR4\r
+       {0xC0,  0x03}, \r
+       {0xC1,  0x0E}, \r
+       {0xC2,  0x16}, \r
+       {0xC3,  0x24}, \r
+       {0xC4,  0x3F}, \r
+       {0xC5,  0x56}, \r
+       {0xC6,  0x6A}, \r
+       {0xC7,  0x7C}, \r
+       {0xC8,  0x8C}, \r
+       {0xC9,  0x98}, \r
+       {0xCA,  0xA2}, \r
+       {0xCB,  0xB8}, \r
+       {0xCC,  0xCD}, \r
+       {0xCD,  0xE2}, \r
+       {0xCE,  0xF0}, \r
+       {0xCF,  0xFF}, \r
+\r
+\r
+// edge value adjustment\r
+       {0xe0,  0x81}, \r
+       {0xe1,  0x83}, \r
+       {0xe2,  0x07}, \r
+       {0xe3,  0x0c}, \r
+       {0xe4,  0x14}, \r
+       {0xe5,  0x1c}, \r
+\r
+\r
+//Sensor on\r
+       {0x00,  0x00}, \r
+       {0x03,  0xc5}, \r
+       {0x00,  0x01}, \r
+       {0x10,  0x84}, \r
+       {0x00,  0x02}, \r
+       {0x10,  0xd3}, \r
+       {0xff,  0xff}, \r
+\r
+\r
+};\r
+\r
+/* 1600X1200 UXGA */\r
+static struct reginfo sensor_uxga[] =\r
+{\r
+   {0x00,0x00},\r
+   {0x04,0x10},\r
+   {0x05,0x8f},\r
+   {0x00,0x03},\r
+   {0x94,0x06},\r
+   {0x95,0x40},\r
+   {0x96,0x04},\r
+   {0x97,0xb0}, \r
+   {0xff, 0xff},\r
+};\r
+\r
+/* 1280X1024 SXGA */\r
+static struct reginfo sensor_sxga[] =\r
+{\r
+       {0x00,0x00},\r
+       {0x04,0x10},\r
+       {0x05,0x8b},\r
+       {0x00,0x03},\r
+       {0x94,0x05},\r
+       {0x95,0x00},\r
+       {0x96,0x04},\r
+       {0x97,0x00}, \r
+       {0xff, 0xff}, \r
+};\r
+static struct reginfo sensor_xga[] =\r
+{\r
+       {0xff, 0xff}\r
+};\r
+/* 800X600 SVGA*/\r
+static struct reginfo sensor_svga[] =\r
+{\r
+    {0x00,0x03},\r
+    {0x94,0x03},\r
+    {0x95,0x20},\r
+    {0x96,0x02},\r
+    {0x97,0x58}, \r
+    {0xff, 0xff}\r
+};\r
+\r
+/* 640X480 VGA */\r
+static struct reginfo sensor_vga[] =\r
+{\r
+      {0x00,0x00},\r
+      {0x04,0x00},\r
+      {0x05,0x0f},\r
+      {0x00,0x03},\r
+      {0x94,0x02}, //0x02\r
+      {0x95,0x80}, //0x80\r
+      {0x96,0x01},//0x01\r
+      {0x97,0xe0}, //0xe0\r
+      {0xff, 0xff}, \r
+};\r
+\r
+/* 352X288 CIF */\r
+static struct reginfo sensor_cif[] =\r
+{\r
+    {0x00,0x03},\r
+    {0x94,0x01},\r
+    {0x95,0x60},\r
+    {0x96,0x01},\r
+    {0x97,0x20}, \r
+    {0xff, 0xff}, \r
+};\r
+\r
+/* 320*240 QVGA */\r
+static  struct reginfo sensor_qvga[] =\r
+{\r
+       {0x00,0x03},\r
+       {0x94,0x01},\r
+       {0x95,0x40},\r
+       {0x96,0x00},\r
+       {0x97,0xf0}, \r
+       {0xff, 0xff}, \r
+};\r
+\r
+/* 176X144 QCIF*/\r
+static struct reginfo sensor_qcif[] =\r
+{\r
+       {0x00,0x03},\r
+       {0x94,0x00},\r
+       {0x95,0xB0},\r
+       {0x96,0x00},\r
+       {0x97,0x90}, \r
+       {0xff, 0xff},\r
+};\r
+\r
+static  struct reginfo sensor_ClrFmt_YUYV[]=\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_ClrFmt_UYVY[]=\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+#if CONFIG_SENSOR_WhiteBalance\r
+static  struct reginfo sensor_WhiteB_Auto[]={\r
+    {0x00, 0x02},\r
+    {0x10, 0xd3},\r
+    {0xff, 0xff}\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K  */\r
+static  struct reginfo sensor_WhiteB_Cloudy[]=\r
+{\r
+    {0x00, 0x02},\r
+    {0x10, 0x00},\r
+    {0x50, 0xd0},\r
+    {0x51, 0x88},\r
+    {0xff, 0xff}\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K  */\r
+static  struct reginfo sensor_WhiteB_ClearDay[]=\r
+{\r
+    {0x00, 0x02},\r
+    {0x10, 0x00},\r
+    {0x50, 0xaa},\r
+    {0x51, 0x90},\r
+    {0xff, 0xff}\r
+\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K  */\r
+static  struct reginfo sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+    {0x00, 0x02},\r
+    {0x10, 0x00},\r
+    {0x50, 0xc2},\r
+    {0x51, 0x9e},\r
+    {0xff, 0xff}\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K  */\r
+static  struct reginfo sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+    {0x00, 0x02},\r
+    {0x10, 0x00},\r
+    {0x50, 0xaa},\r
+    {0x51, 0xbe},\r
+    {0xff, 0xff}\r
+};\r
+static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+    sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+#endif\r
+\r
+#if CONFIG_SENSOR_Brightness\r
+static  struct reginfo sensor_Brightness0[]=\r
+{\r
+    // Brightness -2\r
+    {0x00, 0x04},\r
+    {0xb6, 0xa0},\r
+    {0xff, 0xff}\r
+\r
+};\r
+\r
+static  struct reginfo sensor_Brightness1[]=\r
+{\r
+    // Brightness -1\r
+    {0x00, 0x04},\r
+    {0xb6, 0x90},\r
+    {0xff, 0xff}\r
+\r
+};\r
+\r
+static  struct reginfo sensor_Brightness2[]=\r
+{\r
+    //  Brightness 0\r
+    {0x00, 0x04},\r
+    {0xb6, 0x00},\r
+    {0xff, 0xff}\r
+\r
+};\r
+\r
+static  struct reginfo sensor_Brightness3[]=\r
+{\r
+    // Brightness +1\r
+   {0x00, 0x04},\r
+   {0xb6, 0x10},\r
+   {0xff, 0xff}\r
+\r
+};\r
+\r
+static  struct reginfo sensor_Brightness4[]=\r
+{\r
+    //  Brightness +2\r
+   {0x00, 0x04},\r
+   {0xb6, 0x20},\r
+   {0xff, 0xff}\r
+\r
+};\r
+\r
+static  struct reginfo sensor_Brightness5[]=\r
+{\r
+   {0x00, 0x04},\r
+   {0xb6, 0x30},\r
+   {0xff, 0xff}\r
+};\r
+static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+    sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+#endif\r
+\r
+#if CONFIG_SENSOR_Effect\r
+static  struct reginfo sensor_Effect_Normal[] =\r
+{\r
+    {0x00, 0x04},\r
+    {0xd9, 0x00},\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Effect_WandB[] =\r
+{\r
+    {0x00, 0x04},\r
+    {0xd9, 0x40},\r
+    {0x00, 0x00},\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Effect_Sepia[] =\r
+{\r
+    {0x00, 0x04},\r
+    {0xd9, 0x80},\r
+    {0xda, 0x60},\r
+    {0xdb, 0xa0},\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Effect_Negative[] =\r
+{\r
+   {0x00, 0x04},\r
+   {0xd9, 0x20},\r
+   {0xff, 0xff}\r
+};\r
+static  struct reginfo sensor_Effect_Bluish[] =\r
+{\r
+    // Bluish\r
+    {0x00, 0x04},\r
+    {0xd9, 0x80},\r
+    {0xda, 0xc0},\r
+    {0xdb, 0x60},\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Effect_Green[] =\r
+{\r
+    //  Greenish\r
+    {0x00, 0x04},\r
+    {0xd9, 0x80},\r
+    {0xda, 0x50},\r
+    {0xdb, 0x50},\r
+    {0xff, 0xff}\r
+};\r
+static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+    sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+#endif\r
+#if CONFIG_SENSOR_Exposure\r
+static  struct reginfo sensor_Exposure0[]=\r
+{\r
+    //-3\r
+   {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Exposure1[]=\r
+{\r
+    //-2\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Exposure2[]=\r
+{\r
+    //-0.3EV\r
+   {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Exposure3[]=\r
+{\r
+    //default\r
+  {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Exposure4[]=\r
+{\r
+    // 1\r
+  {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Exposure5[]=\r
+{\r
+    // 2\r
+  {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Exposure6[]=\r
+{\r
+    // 3\r
+   {0xff, 0xff}\r
+};\r
+\r
+static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+    sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+#endif\r
+#if CONFIG_SENSOR_Saturation\r
+static  struct reginfo sensor_Saturation0[]=\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Saturation1[]=\r
+{\r
+   {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Saturation2[]=\r
+{\r
+  {0xff, 0xff}\r
+};\r
+static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+#endif\r
+#if CONFIG_SENSOR_Contrast\r
+static  struct reginfo sensor_Contrast0[]=\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Contrast1[]=\r
+{\r
+   {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Contrast2[]=\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Contrast3[]=\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Contrast4[]=\r
+{\r
+   {0xff, 0xff}\r
+};\r
+\r
+\r
+static  struct reginfo sensor_Contrast5[]=\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_Contrast6[]=\r
+{\r
+    {0xff, 0xff}\r
+};\r
+static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+    sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+\r
+#endif\r
+#if CONFIG_SENSOR_Mirror\r
+static  struct reginfo sensor_MirrorOn[]=\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_MirrorOff[]=\r
+{\r
+     {0xff, 0xff}\r
+};\r
+static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,};\r
+#endif\r
+#if CONFIG_SENSOR_Flip\r
+static  struct reginfo sensor_FlipOn[]=\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_FlipOff[]=\r
+{\r
+     {0xff, 0xff}\r
+};\r
+static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,};\r
+\r
+#endif\r
+#if CONFIG_SENSOR_Scene\r
+static  struct reginfo sensor_SceneAuto[] =\r
+{\r
+   {0x00, 0x01},\r
+   {0x11, 0x0a},\r
+   {0x00, 0x04},\r
+   {0xb6, 0x00},\r
+   {0xff, 0xff}\r
+};\r
+\r
+static  struct reginfo sensor_SceneNight[] =\r
+{\r
+   {0x00, 0x01},\r
+   {0x11, 0x14},\r
+   {0x00, 0x04},\r
+   {0xb6, 0x10},\r
+   {0xff, 0xff}\r
+};\r
+static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+#endif\r
+#if CONFIG_SENSOR_DigitalZoom\r
+static struct reginfo sensor_Zoom0[] =\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+static struct reginfo sensor_Zoom1[] =\r
+{\r
+     {0xff, 0xff}\r
+};\r
+\r
+static struct reginfo sensor_Zoom2[] =\r
+{\r
+    {0xff, 0xff}\r
+};\r
+\r
+\r
+static struct reginfo sensor_Zoom3[] =\r
+{\r
+    {0xff, 0xff}\r
+};\r
+static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+#endif\r
+static const struct v4l2_querymenu sensor_menus[] =\r
+{\r
+       #if CONFIG_SENSOR_WhiteBalance\r
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 0,  .name = "auto",  .reserved = 0, }, {  .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 1, .name = "incandescent",  .reserved = 0,},\r
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 2,  .name = "fluorescent", .reserved = 0,}, {  .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3,  .name = "daylight", .reserved = 0,},\r
+    { .id = V4L2_CID_DO_WHITE_BALANCE,  .index = 4,  .name = "cloudy-daylight", .reserved = 0,},\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_Effect\r
+    { .id = V4L2_CID_EFFECT,  .index = 0,  .name = "none",  .reserved = 0, }, {  .id = V4L2_CID_EFFECT,  .index = 1, .name = "mono",  .reserved = 0,},\r
+    { .id = V4L2_CID_EFFECT,  .index = 2,  .name = "negative", .reserved = 0,}, {  .id = V4L2_CID_EFFECT, .index = 3,  .name = "sepia", .reserved = 0,},\r
+    { .id = V4L2_CID_EFFECT,  .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT,  .index = 5,  .name = "aqua", .reserved = 0,},\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_Scene\r
+    { .id = V4L2_CID_SCENE,  .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE,  .index = 1,  .name = "night", .reserved = 0,},\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_Flash\r
+    { .id = V4L2_CID_FLASH,  .index = 0,  .name = "off",  .reserved = 0, }, {  .id = V4L2_CID_FLASH,  .index = 1, .name = "auto",  .reserved = 0,},\r
+    { .id = V4L2_CID_FLASH,  .index = 2,  .name = "on", .reserved = 0,}, {  .id = V4L2_CID_FLASH, .index = 3,  .name = "torch", .reserved = 0,},\r
+    #endif\r
+};\r
+\r
+static const struct v4l2_queryctrl sensor_controls[] =\r
+{\r
+       #if CONFIG_SENSOR_WhiteBalance\r
+    {\r
+        .id            = V4L2_CID_DO_WHITE_BALANCE,\r
+        .type          = V4L2_CTRL_TYPE_MENU,\r
+        .name          = "White Balance Control",\r
+        .minimum       = 0,\r
+        .maximum       = 4,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    },\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_Brightness\r
+       {\r
+        .id            = V4L2_CID_BRIGHTNESS,\r
+        .type          = V4L2_CTRL_TYPE_INTEGER,\r
+        .name          = "Brightness Control",\r
+        .minimum       = -3,\r
+        .maximum       = 2,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    },\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_Effect\r
+       {\r
+        .id            = V4L2_CID_EFFECT,\r
+        .type          = V4L2_CTRL_TYPE_MENU,\r
+        .name          = "Effect Control",\r
+        .minimum       = 0,\r
+        .maximum       = 5,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    },\r
+       #endif\r
+\r
+       #if CONFIG_SENSOR_Exposure\r
+       {\r
+        .id            = V4L2_CID_EXPOSURE,\r
+        .type          = V4L2_CTRL_TYPE_INTEGER,\r
+        .name          = "Exposure Control",\r
+        .minimum       = 0,\r
+        .maximum       = 6,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    },\r
+       #endif\r
+\r
+       #if CONFIG_SENSOR_Saturation\r
+       {\r
+        .id            = V4L2_CID_SATURATION,\r
+        .type          = V4L2_CTRL_TYPE_INTEGER,\r
+        .name          = "Saturation Control",\r
+        .minimum       = 0,\r
+        .maximum       = 2,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    },\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_Contrast\r
+       {\r
+        .id            = V4L2_CID_CONTRAST,\r
+        .type          = V4L2_CTRL_TYPE_INTEGER,\r
+        .name          = "Contrast Control",\r
+        .minimum       = -3,\r
+        .maximum       = 3,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    },\r
+       #endif\r
+\r
+       #if CONFIG_SENSOR_Mirror\r
+       {\r
+        .id            = V4L2_CID_HFLIP,\r
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,\r
+        .name          = "Mirror Control",\r
+        .minimum       = 0,\r
+        .maximum       = 1,\r
+        .step          = 1,\r
+        .default_value = 1,\r
+    },\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_Flip\r
+       {\r
+        .id            = V4L2_CID_VFLIP,\r
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,\r
+        .name          = "Flip Control",\r
+        .minimum       = 0,\r
+        .maximum       = 1,\r
+        .step          = 1,\r
+        .default_value = 1,\r
+    },\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_Scene\r
+    {\r
+        .id            = V4L2_CID_SCENE,\r
+        .type          = V4L2_CTRL_TYPE_MENU,\r
+        .name          = "Scene Control",\r
+        .minimum       = 0,\r
+        .maximum       = 1,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    },\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_DigitalZoom\r
+    {\r
+        .id            = V4L2_CID_ZOOM_RELATIVE,\r
+        .type          = V4L2_CTRL_TYPE_INTEGER,\r
+        .name          = "DigitalZoom Control",\r
+        .minimum       = -1,\r
+        .maximum       = 1,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    }, {\r
+        .id            = V4L2_CID_ZOOM_ABSOLUTE,\r
+        .type          = V4L2_CTRL_TYPE_INTEGER,\r
+        .name          = "DigitalZoom Control",\r
+        .minimum       = 0,\r
+        .maximum       = 3,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    },\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_Focus\r
+       {\r
+        .id            = V4L2_CID_FOCUS_RELATIVE,\r
+        .type          = V4L2_CTRL_TYPE_INTEGER,\r
+        .name          = "Focus Control",\r
+        .minimum       = -1,\r
+        .maximum       = 1,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    }, {\r
+        .id            = V4L2_CID_FOCUS_ABSOLUTE,\r
+        .type          = V4L2_CTRL_TYPE_INTEGER,\r
+        .name          = "Focus Control",\r
+        .minimum       = 0,\r
+        .maximum       = 255,\r
+        .step          = 1,\r
+        .default_value = 125,\r
+    },\r
+    #endif\r
+\r
+       #if CONFIG_SENSOR_Flash\r
+       {\r
+        .id            = V4L2_CID_FLASH,\r
+        .type          = V4L2_CTRL_TYPE_MENU,\r
+        .name          = "Flash Control",\r
+        .minimum       = 0,\r
+        .maximum       = 3,\r
+        .step          = 1,\r
+        .default_value = 0,\r
+    },\r
+       #endif\r
+};\r
+\r
+static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did);\r
+static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client);\r
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);\r
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);\r
+static int sensor_g_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);\r
+static int sensor_s_ext_controls(struct v4l2_subdev *sd,  struct v4l2_ext_controls *ext_ctrl);\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);\r
+static int sensor_resume(struct soc_camera_device *icd);\r
+static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);\r
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);\r
+#if CONFIG_SENSOR_Effect\r
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);\r
+#endif\r
+#if CONFIG_SENSOR_WhiteBalance\r
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);\r
+#endif\r
+static int sensor_deactivate(struct i2c_client *client);\r
+\r
+static struct soc_camera_ops sensor_ops =\r
+{\r
+    .suspend                     = sensor_suspend,\r
+    .resume                       = sensor_resume,\r
+    .set_bus_param             = sensor_set_bus_param,\r
+    .query_bus_param   = sensor_query_bus_param,\r
+    .controls          = sensor_controls,\r
+    .menus                         = sensor_menus,\r
+    .num_controls              = ARRAY_SIZE(sensor_controls),\r
+    .num_menus         = ARRAY_SIZE(sensor_menus),\r
+};\r
+\r
+#define COL_FMT(_name, _depth, _fourcc, _colorspace) \\r
+       { .name = _name, .depth = _depth, .fourcc = _fourcc, \\r
+       .colorspace = _colorspace }\r
+\r
+#define JPG_FMT(_name, _depth, _fourcc) \\r
+       COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG)\r
+\r
+static const struct soc_camera_data_format sensor_colour_formats[] = {\r
+       JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY),\r
+       JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV),\r
+};\r
+\r
+typedef struct sensor_info_priv_s\r
+{\r
+    int whiteBalance;\r
+    int brightness;\r
+    int contrast;\r
+    int saturation;\r
+    int effect;\r
+    int scene;\r
+    int digitalzoom;\r
+    int focus;\r
+    int flash;\r
+    int exposure;\r
+       bool snap2preview;\r
+       bool video2preview;\r
+    unsigned char mirror;                                        /* HFLIP */\r
+    unsigned char flip;                                          /* VFLIP */\r
+    unsigned int winseqe_cur_addr;\r
+       unsigned int pixfmt;\r
+\r
+} sensor_info_priv_t;\r
+\r
+struct sensor\r
+{\r
+    struct v4l2_subdev subdev;\r
+    struct i2c_client *client;\r
+    sensor_info_priv_t info_priv;\r
+    int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */\r
+#if CONFIG_SENSOR_I2C_NOSCHED\r
+       atomic_t tasklock_cnt;\r
+#endif\r
+       struct rk29camera_platform_data *sensor_io_request;\r
+    struct rk29camera_gpio_res *sensor_gpio_res;\r
+};\r
+\r
+static struct sensor* to_sensor(const struct i2c_client *client)\r
+{\r
+    return container_of(i2c_get_clientdata(client), struct sensor, subdev);\r
+}\r
+\r
+static int sensor_task_lock(struct i2c_client *client, int lock)\r
+{\r
+#if CONFIG_SENSOR_I2C_NOSCHED\r
+       int cnt = 3;\r
+    struct sensor *sensor = to_sensor(client);\r
+\r
+       if (lock) {\r
+               if (atomic_read(&sensor->tasklock_cnt) == 0) {\r
+                       while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {\r
+                               SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());\r
+                               msleep(35);\r
+                               cnt--;\r
+                       }\r
+                       if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {\r
+                               SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());\r
+                               goto sensor_task_lock_err;\r
+                       }\r
+                       preempt_disable();\r
+               }\r
+\r
+               atomic_add(1, &sensor->tasklock_cnt);\r
+       } else {\r
+               if (atomic_read(&sensor->tasklock_cnt) > 0) {\r
+                       atomic_sub(1, &sensor->tasklock_cnt);\r
+\r
+                       if (atomic_read(&sensor->tasklock_cnt) == 0)\r
+                               preempt_enable();\r
+               }\r
+       }\r
+       return 0;\r
+sensor_task_lock_err:\r
+       return -1;  \r
+#else\r
+    return 0;\r
+#endif\r
+\r
+}\r
+\r
+/* sensor register write */\r
+static int sensor_write(struct i2c_client *client, u8 reg, u8 val)\r
+{\r
+    int err,cnt;\r
+    u8 buf[2];\r
+    struct i2c_msg msg[1];\r
+\r
+    //buf[0] = reg >> 8;\r
+    buf[0] = reg & 0xFF;\r
+    buf[1] = val;\r
+\r
+    msg->addr = client->addr;\r
+    msg->flags = client->flags;\r
+    msg->buf = buf;\r
+    msg->len = sizeof(buf);\r
+    msg->scl_rate = CONFIG_SENSOR_I2C_SPEED;         /* ddl@rock-chips.com : 100kHz */\r
+    msg->read_type = 0;               /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */\r
+\r
+    cnt = 3;\r
+    err = -EAGAIN;\r
+\r
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */\r
+        err = i2c_transfer(client->adapter, msg, 1);\r
+\r
+        if (err >= 0) {\r
+            return 0;\r
+        } else {\r
+            SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);\r
+            udelay(10);\r
+        }\r
+    }\r
+\r
+    return err;\r
+}\r
+\r
+/* sensor register read */\r
+static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)\r
+{\r
+    int err,cnt;\r
+    u8 buf[1];\r
+    struct i2c_msg msg[2];\r
+\r
+   // buf[0] = reg >> 8;\r
+    buf[0] = reg & 0xFF;\r
+\r
+    msg[0].addr = client->addr;\r
+    msg[0].flags = client->flags;\r
+    msg[0].buf = buf;\r
+    msg[0].len = sizeof(buf);\r
+    msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED;       /* ddl@rock-chips.com : 100kHz */\r
+    msg[0].read_type = 2;   /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */\r
+\r
+    msg[1].addr = client->addr;\r
+    msg[1].flags = client->flags|I2C_M_RD;\r
+    msg[1].buf = buf;\r
+    msg[1].len = 1;\r
+    msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED;                       /* ddl@rock-chips.com : 100kHz */\r
+    msg[1].read_type = 2;                             /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */\r
+\r
+    cnt = 3;\r
+    err = -EAGAIN;\r
+    while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */\r
+        err = i2c_transfer(client->adapter, msg, 2);\r
+\r
+        if (err >= 0) {\r
+            *val = buf[0];\r
+            return 0;\r
+        } else {\r
+               SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val);\r
+            udelay(10);\r
+        }\r
+    }\r
+\r
+    return err;\r
+}\r
+\r
+/* write a array of registers  */\r
+static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)\r
+{\r
+    int err = 0, cnt;\r
+    int i = 0;\r
+#if CONFIG_SENSOR_I2C_RDWRCHK    \r
+       char valchk;\r
+#endif\r
+\r
+       cnt = 0;\r
+       if (sensor_task_lock(client, 1) < 0)\r
+               goto sensor_write_array_end;\r
+    while (regarray[i].reg != 0xff)\r
+    {\r
+        err = sensor_write(client, regarray[i].reg, regarray[i].val);\r
+        if (err < 0)\r
+        {\r
+            if (cnt-- > 0) {\r
+                           SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg);\r
+                               i = 0;\r
+                               continue;\r
+            } else {\r
+                SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING());\r
+                err = -EPERM;\r
+                               goto sensor_write_array_end;\r
+            }\r
+        } else {\r
+        #if CONFIG_SENSOR_I2C_RDWRCHK\r
+                       sensor_read(client, regarray[i].reg, &valchk);\r
+                       if (valchk != regarray[i].val)\r
+                               SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);\r
+               #endif\r
+        }\r
+        i++;\r
+    }\r
+\r
+sensor_write_array_end:\r
+       sensor_task_lock(client,0);\r
+       return err;\r
+}\r
+#if CONFIG_SENSOR_I2C_RDWRCHK\r
+static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray)\r
+{\r
+    int cnt;\r
+    int i = 0;\r
+       char valchk;\r
+\r
+       cnt = 0;\r
+       valchk = 0;\r
+    while (regarray[i].reg != 0xff)\r
+    {\r
+               sensor_read(client, regarray[i].reg, &valchk);\r
+               if (valchk != regarray[i].val)\r
+                       SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);\r
+\r
+        i++;\r
+    }\r
+    return 0;\r
+}\r
+#endif\r
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)\r
+{\r
+       struct soc_camera_link *icl = to_soc_camera_link(icd);\r
+       int ret = 0;\r
+\r
+    SENSOR_DG("%s %s  cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);\r
+       switch (cmd)\r
+       {\r
+               case Sensor_PowerDown:\r
+               {\r
+                       if (icl->powerdown) {\r
+                               ret = icl->powerdown(icd->pdev, on);\r
+                               if (ret == RK29_CAM_IO_SUCCESS) {\r
+                                       if (on == 0) {\r
+                                               mdelay(2);\r
+                                               if (icl->reset)\r
+                                                       icl->reset(icd->pdev);\r
+                                       }\r
+                               } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {\r
+                                       ret = -ENODEV;\r
+                                       goto sensor_power_end;\r
+                               }\r
+                       }\r
+                       break;\r
+               }\r
+               case Sensor_Flash:\r
+               {\r
+                       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+               struct sensor *sensor = to_sensor(client);\r
+\r
+                       if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {\r
+                               sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);\r
+                       }\r
+            break;\r
+               }\r
+               default:\r
+               {\r
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);\r
+                       break;\r
+               }\r
+       }\r
+sensor_power_end:\r
+       return ret;\r
+}\r
+static int sensor_init(struct v4l2_subdev *sd, u32 val)\r
+{\r
+    struct i2c_client *client = sd->priv;\r
+    struct soc_camera_device *icd = client->dev.platform_data;\r
+    struct sensor *sensor = to_sensor(client);\r
+       const struct v4l2_queryctrl *qctrl;\r
+    char value;\r
+    int ret,pid = 0;\r
+\r
+    SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);\r
+\r
+     if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {\r
+          ret = -ENODEV;\r
+          goto sensor_INIT_ERR;\r
+     }\r
+     msleep(100);\r
+#if 0\r
+    /* soft reset */\r
+       if (sensor_task_lock(client,1)<0)\r
+               goto sensor_INIT_ERR;\r
+    ret = sensor_write(client, 0x3012, 0x80);\r
+    if (ret != 0)\r
+    {\r
+        SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING());\r
+        ret = -ENODEV;\r
+               goto sensor_INIT_ERR;\r
+    }\r
+\r
+    mdelay(5);  //delay 5 microseconds\r
+       /* check if it is an sensor sensor */\r
+    ret = sensor_read(client, 0x300a, &value);\r
+    if (ret != 0) {\r
+        SENSOR_TR("read chip id high byte failed\n");\r
+        ret = -ENODEV;\r
+        goto sensor_INIT_ERR;\r
+    }\r
+\r
+    pid |= (value << 8);\r
+\r
+    ret = sensor_read(client, 0x300b, &value);\r
+    if (ret != 0) {\r
+        SENSOR_TR("read chip id low byte failed\n");\r
+        ret = -ENODEV;\r
+        goto sensor_INIT_ERR;\r
+    }\r
+\r
+    pid |= (value & 0xff);\r
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+    if (pid == SENSOR_ID) {\r
+        sensor->model = SENSOR_V4L2_IDENT;\r
+    } else {\r
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+        ret = -ENODEV;\r
+        goto sensor_INIT_ERR;\r
+    }\r
+#endif\r
+#if 0\r
+   sensor_read(client,0x01,&value);\r
+    pid = (value & 0xff);\r
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+    if (pid == SENSOR_ID) {\r
+        sensor->model = SENSOR_V4L2_IDENT;\r
+    } else {\r
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+        ret = -ENODEV;\r
+        goto sensor_INIT_ERR;\r
+    }\r
+#endif\r
+    ret = sensor_write_array(client, sensor_init_data);\r
+    if (ret != 0)\r
+    {\r
+        SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());\r
+        goto sensor_INIT_ERR;\r
+    }\r
+    sensor_task_lock(client,0);\r
+   // icd->user_width = SENSOR_INIT_WIDTH;\r
+    //icd->user_height = SENSOR_INIT_HEIGHT;\r
+      sensor->info_priv.winseqe_cur_addr  = (int)SENSOR_INIT_WINSEQADR;\r
+      sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT;\r
+\r
+    /* sensor sensor information for initialization  */\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
+       if (qctrl)\r
+       sensor->info_priv.whiteBalance = qctrl->default_value;\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS);\r
+       if (qctrl)\r
+       sensor->info_priv.brightness = qctrl->default_value;\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
+       if (qctrl)\r
+       sensor->info_priv.effect = qctrl->default_value;\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE);\r
+       if (qctrl)\r
+        sensor->info_priv.exposure = qctrl->default_value;\r
+\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION);\r
+       if (qctrl)\r
+        sensor->info_priv.saturation = qctrl->default_value;\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST);\r
+       if (qctrl)\r
+        sensor->info_priv.contrast = qctrl->default_value;\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP);\r
+       if (qctrl)\r
+        sensor->info_priv.mirror = qctrl->default_value;\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP);\r
+       if (qctrl)\r
+        sensor->info_priv.flip = qctrl->default_value;\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE);\r
+       if (qctrl)\r
+        sensor->info_priv.scene = qctrl->default_value;\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);\r
+       if (qctrl)\r
+        sensor->info_priv.digitalzoom = qctrl->default_value;\r
+\r
+    /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code  */\r
+       #if CONFIG_SENSOR_Focus\r
+    sensor_set_focus();\r
+    qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);\r
+       if (qctrl)\r
+        sensor->info_priv.focus = qctrl->default_value;\r
+       #endif\r
+\r
+       #if CONFIG_SENSOR_Flash\r
+       sensor_set_flash();\r
+       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);\r
+       if (qctrl)\r
+        sensor->info_priv.flash = qctrl->default_value;\r
+    #endif\r
+\r
+    SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);\r
+\r
+    return 0;\r
+sensor_INIT_ERR:\r
+       sensor_task_lock(client,0);\r
+       sensor_deactivate(client);\r
+    return ret;\r
+}\r
+\r
+static int sensor_deactivate(struct i2c_client *client)\r
+{\r
+       struct soc_camera_device *icd = client->dev.platform_data;\r
+\r
+       SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);\r
+\r
+       /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */\r
+       //sensor_task_lock(client, 1);\r
+       //sensor_write(client, 0x30b0, 0x00);\r
+       //sensor_write(client, 0x30b1, 0x00);\r
+       //sensor_task_lock(client, 0);\r
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);\r
+\r
+       /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */\r
+       icd->user_width = SENSOR_INIT_WIDTH;\r
+       icd->user_height = SENSOR_INIT_HEIGHT;\r
+       msleep(100);\r
+       return 0;\r
+}\r
+\r
+static  struct reginfo sensor_power_down_sequence[]=\r
+{\r
+    {0xff,0xff}\r
+};\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+    int ret;\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+    if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+        SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());\r
+        ret = sensor_write_array(client, sensor_power_down_sequence) ;\r
+        if (ret != 0) {\r
+            SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);\r
+            return ret;\r
+        } else {\r
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);\r
+            if (ret < 0) {\r
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());\r
+                return -EINVAL;\r
+            }\r
+        }\r
+    } else {\r
+        SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());\r
+        return -EINVAL;\r
+    }\r
+    return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+       int ret;\r
+\r
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);\r
+    if (ret < 0) {\r
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());\r
+        return -EINVAL;\r
+    }\r
+\r
+       SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());\r
+\r
+    return 0;\r
+\r
+}\r
+\r
+static int sensor_set_bus_param(struct soc_camera_device *icd,\r
+                                unsigned long flags)\r
+{\r
+\r
+    return 0;\r
+}\r
+\r
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)\r
+{\r
+    struct soc_camera_link *icl = to_soc_camera_link(icd);\r
+    unsigned long flags = SENSOR_BUS_PARAM;\r
+\r
+    return soc_camera_apply_sensor_flags(icl, flags);\r
+}\r
+\r
+static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)\r
+{\r
+    struct i2c_client *client = sd->priv;\r
+    struct soc_camera_device *icd = client->dev.platform_data;\r
+    struct sensor *sensor = to_sensor(client);\r
+    struct v4l2_pix_format *pix = &f->fmt.pix;\r
+\r
+    pix->width         = icd->user_width;\r
+    pix->height                = icd->user_height;\r
+    pix->pixelformat   = sensor->info_priv.pixfmt;\r
+    pix->field         = V4L2_FIELD_NONE;\r
+    pix->colorspace            = V4L2_COLORSPACE_JPEG;\r
+\r
+    return 0;\r
+}\r
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f)\r
+{\r
+    bool ret = false;\r
+\r
+       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {\r
+               ret = true;\r
+       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {\r
+               ret = true;\r
+       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {\r
+               ret = true;\r
+       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {\r
+               ret = true;\r
+       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {\r
+               ret = true;\r
+       }\r
+\r
+       if (ret == true)\r
+               SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);\r
+       return ret;\r
+}\r
+\r
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)\r
+{\r
+    bool ret = false;\r
+\r
+       if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) {\r
+               ret = true;\r
+       } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) {\r
+               ret = true;\r
+       }\r
+\r
+       if (ret == true)\r
+               SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);\r
+       return ret;\r
+}\r
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)\r
+{\r
+    struct i2c_client *client = sd->priv;\r
+    struct sensor *sensor = to_sensor(client);\r
+    struct v4l2_pix_format *pix = &f->fmt.pix;\r
+       const struct v4l2_queryctrl *qctrl;\r
+       struct soc_camera_device *icd = client->dev.platform_data;\r
+    struct reginfo *winseqe_set_addr=NULL;\r
+    int ret=0, set_w,set_h;\r
+\r
+       if (sensor->info_priv.pixfmt != pix->pixelformat) {\r
+               switch (pix->pixelformat)\r
+               {\r
+                       case V4L2_PIX_FMT_YUYV:\r
+                       {\r
+                               winseqe_set_addr = sensor_ClrFmt_YUYV;\r
+                               break;\r
+                       }\r
+                       case V4L2_PIX_FMT_UYVY:\r
+                       {\r
+                               winseqe_set_addr = sensor_ClrFmt_UYVY;\r
+                               break;\r
+                       }\r
+                       default:\r
+                               break;\r
+               }\r
+               if (winseqe_set_addr != NULL) {\r
+            sensor_write_array(client, winseqe_set_addr);\r
+                       sensor->info_priv.pixfmt = pix->pixelformat;\r
+\r
+                       SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat);\r
+               } else {\r
+                       SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat);\r
+               }\r
+       }\r
+\r
+    set_w = pix->width;\r
+    set_h = pix->height;\r
+\r
+       if (((set_w <= 176) && (set_h <= 144)) &&( sensor_qcif[0].reg!=0xff))\r
+       {\r
+               winseqe_set_addr = sensor_qcif;\r
+        set_w = 176;\r
+        set_h = 144;\r
+       }\r
+       else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=0xff))\r
+    {\r
+        winseqe_set_addr = sensor_qvga;\r
+        set_w = 320;\r
+        set_h = 240;\r
+    }\r
+    else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=0xff))\r
+    {\r
+        winseqe_set_addr = sensor_cif;\r
+        set_w = 352;\r
+        set_h = 288;\r
+    }\r
+    else if (((set_w <= 640) && (set_h <= 480)) &&( sensor_vga[0].reg!=0xff))\r
+    {\r
+        winseqe_set_addr = sensor_vga;\r
+        set_w =640;\r
+        set_h = 480;\r
+    }\r
+    else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=0xff))\r
+    {\r
+        winseqe_set_addr = sensor_svga;\r
+        set_w = 800;\r
+        set_h = 600;\r
+    }\r
+       else if (((set_w <= 1024) && (set_h <= 768)) &&( sensor_xga[0].reg!=0xff))\r
+    {\r
+        winseqe_set_addr = sensor_xga;\r
+        set_w = 1024;\r
+        set_h = 768;\r
+    }\r
+    else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=0xff))\r
+    {\r
+        winseqe_set_addr = sensor_sxga;\r
+        set_w = 1280;\r
+        set_h = 1024;\r
+    }\r
+    else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=0xff))\r
+    {\r
+        winseqe_set_addr = sensor_uxga;\r
+        set_w = 1600;\r
+        set_h = 1200;\r
+    }\r
+    else\r
+    {\r
+        winseqe_set_addr = SENSOR_INIT_WINSEQADR;               /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */\r
+        set_w = SENSOR_INIT_WIDTH;\r
+        set_h = SENSOR_INIT_HEIGHT;\r
+               ret = -1;\r
+               SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height);\r
+    }\r
+\r
+    if ((int)winseqe_set_addr  != sensor->info_priv.winseqe_cur_addr) {\r
+        #if CONFIG_SENSOR_Flash\r
+        if (sensor_fmt_capturechk(sd,f) == true) {      /* ddl@rock-chips.com : Capture */\r
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {\r
+                sensor_ioctrl(icd, Sensor_Flash, Flash_On);\r
+                SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());\r
+            }           \r
+        } else {                                        /* ddl@rock-chips.com : Video */\r
+            if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {\r
+                sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
+                SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());\r
+            }\r
+        }\r
+        #endif\r
+        ret |= sensor_write_array(client, winseqe_set_addr);\r
+        if (ret != 0) {\r
+            SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());\r
+            #if CONFIG_SENSOR_Flash\r
+            if (sensor_fmt_capturechk(sd,f) == true) {\r
+                if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {\r
+                    sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
+                    SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());\r
+                }\r
+            }\r
+            #endif\r
+            goto sensor_s_fmt_end;\r
+        }\r
+\r
+        sensor->info_priv.winseqe_cur_addr  = (int)winseqe_set_addr;\r
+\r
+               if (sensor_fmt_capturechk(sd,f) == true) {                                  /* ddl@rock-chips.com : Capture */\r
+        #if CONFIG_SENSOR_Effect\r
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
+        #endif\r
+        #if CONFIG_SENSOR_WhiteBalance\r
+                       if (sensor->info_priv.whiteBalance != 0) {\r
+                               qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
+                               sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);\r
+                       }\r
+        #endif\r
+                       sensor->info_priv.snap2preview = true;\r
+               } else if (sensor_fmt_videochk(sd,f) == true) {                 /* ddl@rock-chips.com : Video */\r
+               #if CONFIG_SENSOR_Effect\r
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
+        #endif\r
+        #if CONFIG_SENSOR_WhiteBalance\r
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);\r
+        #endif\r
+                       sensor->info_priv.video2preview = true;\r
+               } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {\r
+               #if CONFIG_SENSOR_Effect\r
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
+                       sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
+        #endif\r
+        #if CONFIG_SENSOR_WhiteBalance\r
+                       qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
+                       sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);\r
+        #endif\r
+                       sensor->info_priv.video2preview = false;\r
+                       sensor->info_priv.snap2preview = false;\r
+               }\r
+        SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);\r
+    }\r
+    else\r
+    {\r
+        SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);\r
+    }\r
+\r
+       pix->width = set_w;\r
+    pix->height = set_h;\r
+\r
+sensor_s_fmt_end:\r
+    return ret;\r
+}\r
+\r
+static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)\r
+{\r
+    struct v4l2_pix_format *pix = &f->fmt.pix;\r
+    bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY ||\r
+        pix->pixelformat == V4L2_PIX_FMT_YUYV;\r
+\r
+    /*\r
+    * With Bayer format enforce even side lengths, but let the user play\r
+    * with the starting pixel\r
+    */\r
+    if (pix->height > SENSOR_MAX_HEIGHT)\r
+        pix->height = SENSOR_MAX_HEIGHT;\r
+    else if (pix->height < SENSOR_MIN_HEIGHT)\r
+        pix->height = SENSOR_MIN_HEIGHT;\r
+    else if (bayer)\r
+        pix->height = ALIGN(pix->height, 2);\r
+\r
+    if (pix->width > SENSOR_MAX_WIDTH)\r
+        pix->width = SENSOR_MAX_WIDTH;\r
+    else if (pix->width < SENSOR_MIN_WIDTH)\r
+        pix->width = SENSOR_MIN_WIDTH;\r
+    else if (bayer)\r
+        pix->width = ALIGN(pix->width, 2);\r
+    return 0;\r
+}\r
+\r
+ static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)\r
+{\r
+    struct i2c_client *client = sd->priv;\r
+\r
+    if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)\r
+        return -EINVAL;\r
+\r
+    if (id->match.addr != client->addr)\r
+        return -ENODEV;\r
+\r
+    id->ident = SENSOR_V4L2_IDENT;      /* ddl@rock-chips.com :  Return OV2655  identifier */\r
+    id->revision = 0;\r
+\r
+    return 0;\r
+}\r
+#if CONFIG_SENSOR_Brightness\r
+static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+    {\r
+        if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL)\r
+        {\r
+            if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0)\r
+            {\r
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+                return -EINVAL;\r
+            }\r
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+            return 0;\r
+        }\r
+    }\r
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+    return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Effect\r
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+    {\r
+        if (sensor_EffectSeqe[value - qctrl->minimum] != NULL)\r
+        {\r
+            if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0)\r
+            {\r
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+                return -EINVAL;\r
+            }\r
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+            return 0;\r
+        }\r
+    }\r
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+    return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Exposure\r
+static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+    {\r
+        if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL)\r
+        {\r
+            if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0)\r
+            {\r
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+                return -EINVAL;\r
+            }\r
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+            return 0;\r
+        }\r
+    }\r
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+    return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Saturation\r
+static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+    {\r
+        if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL)\r
+        {\r
+            if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0)\r
+            {\r
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+                return -EINVAL;\r
+            }\r
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+            return 0;\r
+        }\r
+    }\r
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+    return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Contrast\r
+static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+    {\r
+        if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL)\r
+        {\r
+            if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0)\r
+            {\r
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+                return -EINVAL;\r
+            }\r
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+            return 0;\r
+        }\r
+    }\r
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+    return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Mirror\r
+static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+    {\r
+        if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL)\r
+        {\r
+            if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0)\r
+            {\r
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+                return -EINVAL;\r
+            }\r
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+            return 0;\r
+        }\r
+    }\r
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+    return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Flip\r
+static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+    {\r
+        if (sensor_FlipSeqe[value - qctrl->minimum] != NULL)\r
+        {\r
+            if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0)\r
+            {\r
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+                return -EINVAL;\r
+            }\r
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+            return 0;\r
+        }\r
+    }\r
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+    return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Scene\r
+static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+    {\r
+        if (sensor_SceneSeqe[value - qctrl->minimum] != NULL)\r
+        {\r
+            if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0)\r
+            {\r
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+                return -EINVAL;\r
+            }\r
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+            return 0;\r
+        }\r
+    }\r
+    SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+    return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_WhiteBalance\r
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+    {\r
+        if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL)\r
+        {\r
+            if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0)\r
+            {\r
+                SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+                return -EINVAL;\r
+            }\r
+            SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+            return 0;\r
+        }\r
+    }\r
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+    return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_DigitalZoom\r
+static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)\r
+{\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+    struct sensor *sensor = to_sensor(client);\r
+       const struct v4l2_queryctrl *qctrl_info;\r
+    int digitalzoom_cur, digitalzoom_total;\r
+\r
+       qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);\r
+       if (qctrl_info)\r
+               return -EINVAL;\r
+\r
+    digitalzoom_cur = sensor->info_priv.digitalzoom;\r
+    digitalzoom_total = qctrl_info->maximum;\r
+\r
+    if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total))\r
+    {\r
+        SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);\r
+        return -EINVAL;\r
+    }\r
+\r
+    if  ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum))\r
+    {\r
+        SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);\r
+        return -EINVAL;\r
+    }\r
+\r
+    if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total))\r
+    {\r
+        *value = digitalzoom_total - digitalzoom_cur;\r
+    }\r
+\r
+    if ((*value < 0) && ((digitalzoom_cur + *value) < 0))\r
+    {\r
+        *value = 0 - digitalzoom_cur;\r
+    }\r
+\r
+    digitalzoom_cur += *value;\r
+\r
+    if (sensor_ZoomSeqe[digitalzoom_cur] != NULL)\r
+    {\r
+        if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0)\r
+        {\r
+            SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+            return -EINVAL;\r
+        }\r
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value);\r
+        return 0;\r
+    }\r
+\r
+    return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Flash\r
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{    \r
+    if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {\r
+        if (value == 3) {       /* ddl@rock-chips.com: torch */\r
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Torch);   /* Flash On */\r
+        } else {\r
+            sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
+        }\r
+        SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+        return 0;\r
+    }\r
+    \r
+       SENSOR_TR("\n %s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+    return -EINVAL;\r
+}\r
+#endif\r
+\r
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)\r
+{\r
+    struct i2c_client *client = sd->priv;\r
+    struct sensor *sensor = to_sensor(client);\r
+    const struct v4l2_queryctrl *qctrl;\r
+\r
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);\r
+\r
+    if (!qctrl)\r
+    {\r
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);\r
+        return -EINVAL;\r
+    }\r
+\r
+    switch (ctrl->id)\r
+    {\r
+        case V4L2_CID_BRIGHTNESS:\r
+            {\r
+                ctrl->value = sensor->info_priv.brightness;\r
+                break;\r
+            }\r
+        case V4L2_CID_SATURATION:\r
+            {\r
+                ctrl->value = sensor->info_priv.saturation;\r
+                break;\r
+            }\r
+        case V4L2_CID_CONTRAST:\r
+            {\r
+                ctrl->value = sensor->info_priv.contrast;\r
+                break;\r
+            }\r
+        case V4L2_CID_DO_WHITE_BALANCE:\r
+            {\r
+                ctrl->value = sensor->info_priv.whiteBalance;\r
+                break;\r
+            }\r
+        case V4L2_CID_EXPOSURE:\r
+            {\r
+                ctrl->value = sensor->info_priv.exposure;\r
+                break;\r
+            }\r
+        case V4L2_CID_HFLIP:\r
+            {\r
+                ctrl->value = sensor->info_priv.mirror;\r
+                break;\r
+            }\r
+        case V4L2_CID_VFLIP:\r
+            {\r
+                ctrl->value = sensor->info_priv.flip;\r
+                break;\r
+            }\r
+        default :\r
+                break;\r
+    }\r
+    return 0;\r
+}\r
+\r
+\r
+\r
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)\r
+{\r
+    struct i2c_client *client = sd->priv;\r
+    struct sensor *sensor = to_sensor(client);\r
+    struct soc_camera_device *icd = client->dev.platform_data;\r
+    const struct v4l2_queryctrl *qctrl;\r
+\r
+\r
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);\r
+\r
+    if (!qctrl)\r
+    {\r
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);\r
+        return -EINVAL;\r
+    }\r
+\r
+    switch (ctrl->id)\r
+    {\r
+#if CONFIG_SENSOR_Brightness\r
+        case V4L2_CID_BRIGHTNESS:\r
+            {\r
+                if (ctrl->value != sensor->info_priv.brightness)\r
+                {\r
+                    if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0)\r
+                    {\r
+                        return -EINVAL;\r
+                    }\r
+                    sensor->info_priv.brightness = ctrl->value;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+#if CONFIG_SENSOR_Exposure\r
+        case V4L2_CID_EXPOSURE:\r
+            {\r
+                if (ctrl->value != sensor->info_priv.exposure)\r
+                {\r
+                    if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0)\r
+                    {\r
+                        return -EINVAL;\r
+                    }\r
+                    sensor->info_priv.exposure = ctrl->value;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+#if CONFIG_SENSOR_Saturation\r
+        case V4L2_CID_SATURATION:\r
+            {\r
+                if (ctrl->value != sensor->info_priv.saturation)\r
+                {\r
+                    if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0)\r
+                    {\r
+                        return -EINVAL;\r
+                    }\r
+                    sensor->info_priv.saturation = ctrl->value;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+#if CONFIG_SENSOR_Contrast\r
+        case V4L2_CID_CONTRAST:\r
+            {\r
+                if (ctrl->value != sensor->info_priv.contrast)\r
+                {\r
+                    if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0)\r
+                    {\r
+                        return -EINVAL;\r
+                    }\r
+                    sensor->info_priv.contrast = ctrl->value;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+#if CONFIG_SENSOR_WhiteBalance\r
+        case V4L2_CID_DO_WHITE_BALANCE:\r
+            {\r
+                if (ctrl->value != sensor->info_priv.whiteBalance)\r
+                {\r
+                    if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0)\r
+                    {\r
+                        return -EINVAL;\r
+                    }\r
+                    sensor->info_priv.whiteBalance = ctrl->value;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+#if CONFIG_SENSOR_Mirror\r
+        case V4L2_CID_HFLIP:\r
+            {\r
+                if (ctrl->value != sensor->info_priv.mirror)\r
+                {\r
+                    if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0)\r
+                        return -EINVAL;\r
+                    sensor->info_priv.mirror = ctrl->value;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+#if CONFIG_SENSOR_Flip\r
+        case V4L2_CID_VFLIP:\r
+            {\r
+                if (ctrl->value != sensor->info_priv.flip)\r
+                {\r
+                    if (sensor_set_flip(icd, qctrl,ctrl->value) != 0)\r
+                        return -EINVAL;\r
+                    sensor->info_priv.flip = ctrl->value;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+        default:\r
+            break;\r
+    }\r
+\r
+    return 0;\r
+}\r
+static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl)\r
+{\r
+    const struct v4l2_queryctrl *qctrl;\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+    struct sensor *sensor = to_sensor(client);\r
+\r
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);\r
+\r
+    if (!qctrl)\r
+    {\r
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);\r
+        return -EINVAL;\r
+    }\r
+\r
+    switch (ext_ctrl->id)\r
+    {\r
+        case V4L2_CID_SCENE:\r
+            {\r
+                ext_ctrl->value = sensor->info_priv.scene;\r
+                break;\r
+            }\r
+        case V4L2_CID_EFFECT:\r
+            {\r
+                ext_ctrl->value = sensor->info_priv.effect;\r
+                break;\r
+            }\r
+        case V4L2_CID_ZOOM_ABSOLUTE:\r
+            {\r
+                ext_ctrl->value = sensor->info_priv.digitalzoom;\r
+                break;\r
+            }\r
+        case V4L2_CID_ZOOM_RELATIVE:\r
+            {\r
+                return -EINVAL;\r
+            }\r
+        case V4L2_CID_FOCUS_ABSOLUTE:\r
+            {\r
+                ext_ctrl->value = sensor->info_priv.focus;\r
+                break;\r
+            }\r
+        case V4L2_CID_FOCUS_RELATIVE:\r
+            {\r
+                return -EINVAL;\r
+            }\r
+        case V4L2_CID_FLASH:\r
+            {\r
+                ext_ctrl->value = sensor->info_priv.flash;\r
+                break;\r
+            }\r
+        default :\r
+            break;\r
+    }\r
+    return 0;\r
+}\r
+static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl)\r
+{\r
+    const struct v4l2_queryctrl *qctrl;\r
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+    struct sensor *sensor = to_sensor(client);\r
+    int val_offset;\r
+\r
+    qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);\r
+\r
+    if (!qctrl)\r
+    {\r
+        SENSOR_TR("\n %s ioctrl id = %d  is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);\r
+        return -EINVAL;\r
+    }\r
+\r
+       val_offset = 0;\r
+    switch (ext_ctrl->id)\r
+    {\r
+#if CONFIG_SENSOR_Scene\r
+        case V4L2_CID_SCENE:\r
+            {\r
+                if (ext_ctrl->value != sensor->info_priv.scene)\r
+                {\r
+                    if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0)\r
+                        return -EINVAL;\r
+                    sensor->info_priv.scene = ext_ctrl->value;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+#if CONFIG_SENSOR_Effect\r
+        case V4L2_CID_EFFECT:\r
+            {\r
+                if (ext_ctrl->value != sensor->info_priv.effect)\r
+                {\r
+                    if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0)\r
+                        return -EINVAL;\r
+                    sensor->info_priv.effect= ext_ctrl->value;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+#if CONFIG_SENSOR_DigitalZoom\r
+        case V4L2_CID_ZOOM_ABSOLUTE:\r
+            {\r
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))\r
+                    return -EINVAL;\r
+\r
+                if (ext_ctrl->value != sensor->info_priv.digitalzoom)\r
+                {\r
+                    val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom;\r
+\r
+                    if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0)\r
+                        return -EINVAL;\r
+                    sensor->info_priv.digitalzoom += val_offset;\r
+\r
+                    SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(),  sensor->info_priv.digitalzoom);\r
+                }\r
+\r
+                break;\r
+            }\r
+        case V4L2_CID_ZOOM_RELATIVE:\r
+            {\r
+                if (ext_ctrl->value)\r
+                {\r
+                    if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0)\r
+                        return -EINVAL;\r
+                    sensor->info_priv.digitalzoom += ext_ctrl->value;\r
+\r
+                    SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom);\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+#if CONFIG_SENSOR_Focus\r
+        case V4L2_CID_FOCUS_ABSOLUTE:\r
+            {\r
+                if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))\r
+                    return -EINVAL;\r
+\r
+                if (ext_ctrl->value != sensor->info_priv.focus)\r
+                {\r
+                    val_offset = ext_ctrl->value -sensor->info_priv.focus;\r
+\r
+                    sensor->info_priv.focus += val_offset;\r
+                }\r
+\r
+                break;\r
+            }\r
+        case V4L2_CID_FOCUS_RELATIVE:\r
+            {\r
+                if (ext_ctrl->value)\r
+                {\r
+                    sensor->info_priv.focus += ext_ctrl->value;\r
+\r
+                    SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus);\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+#if CONFIG_SENSOR_Flash\r
+        case V4L2_CID_FLASH:\r
+            {\r
+                if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)\r
+                    return -EINVAL;\r
+                sensor->info_priv.flash = ext_ctrl->value;\r
+\r
+                SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);\r
+                break;\r
+            }\r
+#endif\r
+        default:\r
+            break;\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)\r
+{\r
+    struct i2c_client *client = sd->priv;\r
+    struct soc_camera_device *icd = client->dev.platform_data;\r
+    int i, error_cnt=0, error_idx=-1;\r
+\r
+\r
+    for (i=0; i<ext_ctrl->count; i++) {\r
+        if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {\r
+            error_cnt++;\r
+            error_idx = i;\r
+        }\r
+    }\r
+\r
+    if (error_cnt > 1)\r
+        error_idx = ext_ctrl->count;\r
+\r
+    if (error_idx != -1) {\r
+        ext_ctrl->error_idx = error_idx;\r
+        return -EINVAL;\r
+    } else {\r
+        return 0;\r
+    }\r
+}\r
+\r
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)\r
+{\r
+    struct i2c_client *client = sd->priv;\r
+    struct soc_camera_device *icd = client->dev.platform_data;\r
+    int i, error_cnt=0, error_idx=-1;\r
+\r
+\r
+    for (i=0; i<ext_ctrl->count; i++) {\r
+        if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {\r
+            error_cnt++;\r
+            error_idx = i;\r
+        }\r
+    }\r
+\r
+    if (error_cnt > 1)\r
+        error_idx = ext_ctrl->count;\r
+\r
+    if (error_idx != -1) {\r
+        ext_ctrl->error_idx = error_idx;\r
+        return -EINVAL;\r
+    } else {\r
+        return 0;\r
+    }\r
+}\r
+\r
+/* Interface active, can use i2c. If it fails, it can indeed mean, that\r
+ * this wasn't our capture interface, so, we wait for the right one */\r
+static int sensor_video_probe(struct soc_camera_device *icd,\r
+                              struct i2c_client *client)\r
+{\r
+    char value;\r
+    int ret,pid = 0;\r
+    struct sensor *sensor = to_sensor(client);\r
+\r
+    /* We must have a parent by now. And it cannot be a wrong one.\r
+     * So this entire test is completely redundant. */\r
+    if (!icd->dev.parent ||\r
+           to_soc_camera_host(icd->dev.parent)->nr != icd->iface)\r
+               return -ENODEV;\r
+\r
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {\r
+               ret = -ENODEV;\r
+               goto sensor_video_probe_err;\r
+       }\r
+#if 0\r
+    /* soft reset */\r
+    ret = sensor_write(client, 0x3012, 0x80);\r
+    if (ret != 0)\r
+    {\r
+        SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());\r
+        return -ENODEV;\r
+    }\r
+    mdelay(5);          //delay 5 microseconds\r
+\r
+    /* check if it is an sensor sensor */\r
+    ret = sensor_read(client, 0x300a, &value);\r
+    if (ret != 0) {\r
+        SENSOR_TR("read chip id high byte failed\n");\r
+        ret = -ENODEV;\r
+        goto sensor_video_probe_err;\r
+    }\r
+\r
+    \r
+    ret = sensor_read(client, 0x01, &value);\r
+    if (ret != 0) {\r
+        SENSOR_TR("read chip id low byte failed\n");\r
+        ret = -ENODEV;\r
+        goto sensor_video_probe_err;\r
+    }\r
+\r
+    pid = (value & 0xff);\r
+    SENSOR_DG("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+    if (pid == SENSOR_ID) {\r
+        sensor->model = SENSOR_V4L2_IDENT;\r
+    } else {\r
+        SENSOR_TR("error: %s mismatched   pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+        ret = -ENODEV;\r
+        goto sensor_video_probe_err;\r
+    }\r
+#endif\r
+    icd->formats = sensor_colour_formats;\r
+    icd->num_formats = ARRAY_SIZE(sensor_colour_formats);\r
+\r
+    return 0;\r
+\r
+sensor_video_probe_err:\r
+\r
+    return ret;\r
+}\r
+static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)\r
+{\r
+       struct i2c_client *client = sd->priv;\r
+    struct soc_camera_device *icd = client->dev.platform_data;\r
+    struct sensor *sensor = to_sensor(client);\r
+    int ret = 0;\r
+#if CONFIG_SENSOR_Flash        \r
+    int i;\r
+#endif\r
+    \r
+       SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);\r
+       switch (cmd)\r
+       {\r
+               case RK29_CAM_SUBDEV_DEACTIVATE:\r
+               {\r
+                       sensor_deactivate(client);\r
+                       break;\r
+               }\r
+\r
+               case RK29_CAM_SUBDEV_IOREQUEST:\r
+               {\r
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           \r
+            if (sensor->sensor_io_request != NULL) { \r
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && \r
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {\r
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];\r
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && \r
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {\r
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];\r
+                }\r
+            } else {\r
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);\r
+                ret = -EINVAL;\r
+                goto sensor_ioctl_end;\r
+            }\r
+            /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control \r
+               for this project */\r
+            #if CONFIG_SENSOR_Flash    \r
+               if (sensor->sensor_gpio_res) { \r
+                if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {\r
+                    for (i = 0; i < icd->ops->num_controls; i++) {\r
+                               if (V4L2_CID_FLASH == icd->ops->controls[i].id) {\r
+                                       memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));                                       \r
+                               }\r
+                    }\r
+                    sensor->info_priv.flash = 0xff;\r
+                    SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());\r
+                }\r
+               }\r
+            #endif\r
+                       break;\r
+               }\r
+               default:\r
+               {\r
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);\r
+                       break;\r
+               }\r
+       }\r
+sensor_ioctl_end:\r
+       return ret;\r
+\r
+}\r
+static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {\r
+       .init           = sensor_init,\r
+       .g_ctrl         = sensor_g_control,\r
+       .s_ctrl         = sensor_s_control,\r
+       .g_ext_ctrls          = sensor_g_ext_controls,\r
+       .s_ext_ctrls          = sensor_s_ext_controls,\r
+       .g_chip_ident   = sensor_g_chip_ident,\r
+       .ioctl = sensor_ioctl,\r
+};\r
+\r
+static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {\r
+       .s_fmt          = sensor_s_fmt,\r
+       .g_fmt          = sensor_g_fmt,\r
+       .try_fmt        = sensor_try_fmt,\r
+};\r
+\r
+static struct v4l2_subdev_ops sensor_subdev_ops = {\r
+       .core   = &sensor_subdev_core_ops,\r
+       .video = &sensor_subdev_video_ops,\r
+};\r
+\r
+static int sensor_probe(struct i2c_client *client,\r
+                        const struct i2c_device_id *did)\r
+{\r
+    struct sensor *sensor;\r
+    struct soc_camera_device *icd = client->dev.platform_data;\r
+    struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);\r
+    struct soc_camera_link *icl;\r
+    int ret;\r
+\r
+    SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__);\r
+    if (!icd) {\r
+        dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING());\r
+        return -EINVAL;\r
+    }\r
+\r
+    icl = to_soc_camera_link(icd);\r
+    if (!icl) {\r
+        dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING());\r
+        return -EINVAL;\r
+    }\r
+\r
+    if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {\r
+        dev_warn(&adapter->dev,\r
+                "I2C-Adapter doesn't support I2C_FUNC_I2C\n");\r
+        return -EIO;\r
+    }\r
+\r
+    sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL);\r
+    if (!sensor)\r
+        return -ENOMEM;\r
+\r
+    v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops);\r
+\r
+    /* Second stage probe - when a capture adapter is there */\r
+    icd->ops           = &sensor_ops;\r
+    icd->y_skip_top            = 0;\r
+       #if CONFIG_SENSOR_I2C_NOSCHED\r
+       atomic_set(&sensor->tasklock_cnt,0);\r
+       #endif\r
+\r
+    ret = sensor_video_probe(icd, client);\r
+    if (ret < 0) {\r
+        icd->ops = NULL;\r
+        i2c_set_clientdata(client, NULL);\r
+        kfree(sensor);\r
+               sensor = NULL;\r
+    }\r
+    SENSOR_DG("\n%s..%s..%d  ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);\r
+    return ret;\r
+}\r
+\r
+static int sensor_remove(struct i2c_client *client)\r
+{\r
+    struct sensor *sensor = to_sensor(client);\r
+    struct soc_camera_device *icd = client->dev.platform_data;\r
+\r
+    icd->ops = NULL;\r
+    i2c_set_clientdata(client, NULL);\r
+    client->driver = NULL;\r
+    kfree(sensor);\r
+       sensor = NULL;\r
+    return 0;\r
+}\r
+\r
+static const struct i2c_device_id sensor_id[] = {\r
+       {SENSOR_NAME_STRING(), 0 },\r
+       { }\r
+};\r
+MODULE_DEVICE_TABLE(i2c, sensor_id);\r
+\r
+static struct i2c_driver sensor_i2c_driver = {\r
+       .driver = {\r
+               .name = SENSOR_NAME_STRING(),\r
+       },\r
+       .probe          = sensor_probe,\r
+       .remove         = sensor_remove,\r
+       .id_table       = sensor_id,\r
+};\r
+\r
+static int __init sensor_mod_init(void)\r
+{\r
+    SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING());\r
+    return i2c_add_driver(&sensor_i2c_driver);\r
+}\r
+\r
+static void __exit sensor_mod_exit(void)\r
+{\r
+    i2c_del_driver(&sensor_i2c_driver);\r
+}\r
+\r
+device_initcall_sync(sensor_mod_init);\r
+module_exit(sensor_mod_exit);\r
+\r
+MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));\r
+MODULE_AUTHOR("ddl <kernel@rock-chips>");\r
+MODULE_LICENSE("GPL");
\ No newline at end of file
index 70d75240c8aac962fd0ffc58b3cd7eba3043e316..8a4477522ad50a8cc9f06a120555e4a9af797783 100755 (executable)
@@ -45,7 +45,7 @@
 
 #define _GC_OBJ_ZONE    gcvZONE_OS
 
-#define PAGE_ALLOC_LIMIT                    1   // ÏÞÖÆPageÉêÇë
+#define PAGE_ALLOC_LIMIT                    0   // ÏÞÖÆPageÉêÇë
 #define PAGE_ALLOC_LIMIT_SIZE               0   // ÏÞÖÆPageÉêÇëµÄ´óС,µ¥Î»ÎªM
 
 #if PAGE_ALLOC_LIMIT
index 59700c73eb588ea612fd934d08de6afb9cd427e6..64e8b17da990f728378d75971ee1989a62e15340 100644 (file)
@@ -281,7 +281,15 @@ enum {
 
     V4L2_IDENT_GT2005 = 64100,       /* ddl@rock-chips.com : GT2005 support */
     V4L2_IDENT_GC0308 = 64101,      /* ddl@rock-chips.com : GC0308 support */
-    V4L2_IDENT_SIV120B = 64102,      /* ddl@rock-chips.com : siv120b support */
+    V4L2_IDENT_GC0309 = 64102,      /* ddl@rock-chips.com : GC0309 support */
+    V4L2_IDENT_SIV120B = 64103,      /* ddl@rock-chips.com : siv120b support */    
+    
+    V4L2_IDENT_GC2015 = 64105,      /* ddl@rock-chips.com : gc2015 support */
+    V4L2_IDENT_HI253 = 64106,      /* ddl@rock-chips.com : hi253 support */
+    V4L2_IDENT_HI704 = 64107,      /* ddl@rock-chips.com : hi704 support */
+    V4L2_IDENT_NT99250 = 64108,    /* ddl@rock-chips.com : nt99250 support */
+    V4L2_IDENT_SID130B = 64109,      /* ddl@rock-chips.com : sid130B support */
+    
 };
 
 #endif
index 7722e2e43713150e08eec6ece8b971c7f689014a..c95ec5e755ad5217ebdbb0878e3d72a9b9c5961c 100755 (executable)
 #define WM8900_LRC_MASK 0xfc00
 #define SPK_CON                RK29_PIN6_PB6
 
+#define WM8900_IS_SHUTDOWN     0
 #define WM8900_IS_STARTUP      1
-#define WM8900_IS_SHUTDOWN     2
 
 static void wm8900_work(struct work_struct *work);
 
@@ -225,454 +225,36 @@ static void wm8900_reset(struct snd_soc_codec *codec)
               sizeof(codec->reg_cache));
 }
 
-static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
-                          struct snd_kcontrol *kcontrol, int event)
+static void wm8900_powerdown(void)
 {
-       struct snd_soc_codec *codec = w->codec;
-       u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1);
-       
-       WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__);
-
-       switch (event) {
-       case SND_SOC_DAPM_PRE_PMU:
-               /* Clamp headphone outputs */
-               hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP |
-                       WM8900_REG_HPCTL1_HP_CLAMP_OP;
-               snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-               WM8900_DBG("Enter:%s, %d, HPCTL=0x%04X \n", __FUNCTION__, __LINE__, hpctl1);
-               break;
-
-       case SND_SOC_DAPM_POST_PMU:
-               /* Enable the input stage */
-               hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_IP;
-               hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT |
-                       WM8900_REG_HPCTL1_HP_SHORT2 |
-                       WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
-               snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-
-               msleep(400);
-
-               /* Enable the output stage */
-               hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP;
-               hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
-               snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-
-               /* Remove the shorts */
-               hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2;
-               snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-               hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT;
-               snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-               WM8900_DBG("Enter:%s, %d, HPCTL=0x%04X \n", __FUNCTION__, __LINE__, hpctl1);
-               break;
+       printk("Power down wm8900\n");
 
-       case SND_SOC_DAPM_PRE_PMD:
-               /* Short the output */
-               hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT;
-               snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-
-               /* Disable the output stage */
-               hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
-               snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-
-               /* Clamp the outputs and power down input */
-               hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP |
-                       WM8900_REG_HPCTL1_HP_CLAMP_OP;
-               hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
-               snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
-               WM8900_DBG("Enter:%s, %d, HPCTL=0x%04X \n", __FUNCTION__, __LINE__, hpctl1);
-               break;
-
-       case SND_SOC_DAPM_POST_PMD:
-               /* Disable everything */
-               snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
-               WM8900_DBG("Enter:%s, %d, HPCTL=0x%04X \n", __FUNCTION__, __LINE__, hpctl1);
-               break;
-
-       default:
-               BUG();
+       if (wm8900_current_status != WM8900_IS_SHUTDOWN) {
+#ifdef SPK_CON
+               gpio_set_value(SPK_CON, GPIO_LOW);
+#endif
+               msleep(20);
+               snd_soc_write(wm8900_codec, WM8900_REG_RESET, 0);
+               wm8900_current_status = WM8900_IS_SHUTDOWN;
        }
-
-       return 0;
-}
-
-static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 100, 0);
-
-static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 0);
-
-static const DECLARE_TLV_DB_SCALE(in_boost_tlv, -1200, 600, 0);
-
-static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1200, 100, 0);
-
-static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
-
-static const DECLARE_TLV_DB_SCALE(dac_tlv, -7200, 75, 1);
-
-static const DECLARE_TLV_DB_SCALE(adc_svol_tlv, -3600, 300, 0);
-
-static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
-
-static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" };
-
-static const struct soc_enum mic_bias_level =
-SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt);
-
-static const char *dac_mute_rate_txt[] = { "Fast", "Slow" };
-
-static const struct soc_enum dac_mute_rate =
-SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt);
-
-static const char *dac_deemphasis_txt[] = {
-       "Disabled", "32kHz", "44.1kHz", "48kHz"
-};
-
-static const struct soc_enum dac_deemphasis =
-SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt);
-
-static const char *adc_hpf_cut_txt[] = {
-       "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"
-};
-
-static const struct soc_enum adc_hpf_cut =
-SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt);
-
-static const char *lr_txt[] = {
-       "Left", "Right"
-};
-
-static const struct soc_enum aifl_src =
-SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt);
-
-static const struct soc_enum aifr_src =
-SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt);
-
-static const struct soc_enum dacl_src =
-SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt);
-
-static const struct soc_enum dacr_src =
-SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt);
-
-static const char *sidetone_txt[] = {
-       "Disabled", "Left ADC", "Right ADC"
-};
-
-static const struct soc_enum dacl_sidetone =
-SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt);
-
-static const struct soc_enum dacr_sidetone =
-SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt);
-
-static const struct snd_kcontrol_new wm8900_snd_controls[] = {
-SOC_ENUM("Mic Bias Level", mic_bias_level),
-
-SOC_SINGLE_TLV("Left Input PGA Volume", WM8900_REG_LINVOL, 0, 31, 0,
-              in_pga_tlv),
-SOC_SINGLE("Left Input PGA Switch", WM8900_REG_LINVOL, 6, 1, 1),
-SOC_SINGLE("Left Input PGA ZC Switch", WM8900_REG_LINVOL, 7, 1, 0),
-
-SOC_SINGLE_TLV("Right Input PGA Volume", WM8900_REG_RINVOL, 0, 31, 0,
-              in_pga_tlv),
-SOC_SINGLE("Right Input PGA Switch", WM8900_REG_RINVOL, 6, 1, 1),
-SOC_SINGLE("Right Input PGA ZC Switch", WM8900_REG_RINVOL, 7, 1, 0),
-
-SOC_SINGLE("DAC Soft Mute Switch", WM8900_REG_DACCTRL, 6, 1, 1),
-SOC_ENUM("DAC Mute Rate", dac_mute_rate),
-SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0),
-SOC_ENUM("DAC Deemphasis", dac_deemphasis),
-SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL,
-          12, 1, 0),
-
-SOC_SINGLE("ADC HPF Switch", WM8900_REG_ADCCTRL, 8, 1, 0),
-SOC_ENUM("ADC HPF Cut-Off", adc_hpf_cut),
-SOC_DOUBLE("ADC Invert Switch", WM8900_REG_ADCCTRL, 1, 0, 1, 0),
-SOC_SINGLE_TLV("Left ADC Sidetone Volume", WM8900_REG_SIDETONE, 9, 12, 0,
-              adc_svol_tlv),
-SOC_SINGLE_TLV("Right ADC Sidetone Volume", WM8900_REG_SIDETONE, 5, 12, 0,
-              adc_svol_tlv),
-SOC_ENUM("Left Digital Audio Source", aifl_src),
-SOC_ENUM("Right Digital Audio Source", aifr_src),
-
-SOC_SINGLE_TLV("DAC Input Boost Volume", WM8900_REG_AUDIO2, 10, 4, 0,
-              dac_boost_tlv),
-SOC_ENUM("Left DAC Source", dacl_src),
-SOC_ENUM("Right DAC Source", dacr_src),
-SOC_ENUM("Left DAC Sidetone", dacl_sidetone),
-SOC_ENUM("Right DAC Sidetone", dacr_sidetone),
-SOC_DOUBLE("DAC Invert Switch", WM8900_REG_DACCTRL, 1, 0, 1, 0),
-
-SOC_DOUBLE_R_TLV("Digital Playback Volume",
-                WM8900_REG_LDAC_DV, WM8900_REG_RDAC_DV,
-                1, 96, 0, dac_tlv),
-SOC_DOUBLE_R_TLV("Digital Capture Volume",
-                WM8900_REG_LADC_DV, WM8900_REG_RADC_DV, 1, 119, 0, adc_tlv),
-
-SOC_SINGLE_TLV("LINPUT3 Bypass Volume", WM8900_REG_LOUTMIXCTL1, 4, 7, 0,
-              out_mix_tlv),
-SOC_SINGLE_TLV("RINPUT3 Bypass Volume", WM8900_REG_ROUTMIXCTL1, 4, 7, 0,
-              out_mix_tlv),
-SOC_SINGLE_TLV("Left AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 4, 7, 0,
-              out_mix_tlv),
-SOC_SINGLE_TLV("Right AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 0, 7, 0,
-              out_mix_tlv),
-
-SOC_SINGLE_TLV("LeftIn to RightOut Mixer Volume", WM8900_REG_BYPASS1, 0, 7, 0,
-              out_mix_tlv),
-SOC_SINGLE_TLV("LeftIn to LeftOut Mixer Volume", WM8900_REG_BYPASS1, 4, 7, 0,
-              out_mix_tlv),
-SOC_SINGLE_TLV("RightIn to LeftOut Mixer Volume", WM8900_REG_BYPASS2, 0, 7, 0,
-              out_mix_tlv),
-SOC_SINGLE_TLV("RightIn to RightOut Mixer Volume", WM8900_REG_BYPASS2, 4, 7, 0,
-              out_mix_tlv),
-
-SOC_SINGLE_TLV("IN2L Boost Volume", WM8900_REG_INBOOSTMIX1, 0, 3, 0,
-              in_boost_tlv),
-SOC_SINGLE_TLV("IN3L Boost Volume", WM8900_REG_INBOOSTMIX1, 4, 3, 0,
-              in_boost_tlv),
-SOC_SINGLE_TLV("IN2R Boost Volume", WM8900_REG_INBOOSTMIX2, 0, 3, 0,
-              in_boost_tlv),
-SOC_SINGLE_TLV("IN3R Boost Volume", WM8900_REG_INBOOSTMIX2, 4, 3, 0,
-              in_boost_tlv),
-SOC_SINGLE_TLV("Left AUX Boost Volume", WM8900_REG_AUXBOOST, 4, 3, 0,
-              in_boost_tlv),
-SOC_SINGLE_TLV("Right AUX Boost Volume", WM8900_REG_AUXBOOST, 0, 3, 0,
-              in_boost_tlv),
-
-SOC_DOUBLE_R_TLV("LINEOUT1 Volume", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
-              0, 63, 0, out_pga_tlv),
-SOC_DOUBLE_R("LINEOUT1 Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
-            6, 1, 1),
-SOC_DOUBLE_R("LINEOUT1 ZC Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
-            7, 1, 0),
-
-SOC_DOUBLE_R_TLV("LINEOUT2 Volume",
-                WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL,
-                0, 63, 0, out_pga_tlv),
-SOC_DOUBLE_R("LINEOUT2 Switch",
-            WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 6, 1, 1),
-SOC_DOUBLE_R("LINEOUT2 ZC Switch",
-            WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 7, 1, 0),
-SOC_SINGLE("LINEOUT2 LP -12dB", WM8900_REG_LOUTMIXCTL1,
-          0, 1, 1),
-
-};
-
-static const struct snd_kcontrol_new wm8900_dapm_loutput2_control[] = {
-SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0),};
-
-static const struct snd_kcontrol_new wm8900_dapm_routput2_control[] = {
-SOC_DAPM_SINGLE("LINEOUT2R Switch", WM8900_REG_POWER3, 5, 1, 0),};
-
-static const struct snd_kcontrol_new wm8900_loutmix_controls[] = {
-SOC_DAPM_SINGLE("LINPUT3 Bypass Switch", WM8900_REG_LOUTMIXCTL1, 7, 1, 0),
-SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 7, 1, 0),
-SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 7, 1, 0),
-SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 3, 1, 0),
-SOC_DAPM_SINGLE("DACL Switch", WM8900_REG_LOUTMIXCTL1, 8, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_routmix_controls[] = {
-SOC_DAPM_SINGLE("RINPUT3 Bypass Switch", WM8900_REG_ROUTMIXCTL1, 7, 1, 0),
-SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 3, 1, 0),
-SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 3, 1, 0),
-SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 7, 1, 0),
-SOC_DAPM_SINGLE("DACR Switch", WM8900_REG_ROUTMIXCTL1, 8, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_linmix_controls[] = {
-SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INBOOSTMIX1, 2, 1, 1),
-SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INBOOSTMIX1, 6, 1, 1),
-SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 6, 1, 1),
-SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 6, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_rinmix_controls[] = {
-SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INBOOSTMIX2, 2, 1, 1),
-SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INBOOSTMIX2, 6, 1, 1),
-SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 2, 1, 1),
-SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 2, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_linpga_controls[] = {
-SOC_SINGLE("MIC LINPUT1 Switch", WM8900_REG_INCTL, 6, 1, 0),
-SOC_SINGLE("MIC LINPUT2 Switch", WM8900_REG_INCTL, 5, 1, 0),
-SOC_SINGLE("MIC LINPUT3 Switch", WM8900_REG_INCTL, 4, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_rinpga_controls[] = {
-SOC_SINGLE("MIC RINPUT1 Switch", WM8900_REG_INCTL, 2, 1, 0),
-SOC_SINGLE("MIC RINPUT2 Switch", WM8900_REG_INCTL, 1, 1, 0),
-SOC_SINGLE("MIC RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0),
-};
-
-static const struct snd_kcontrol_new wm8900_inmix_controls[] = {
-SOC_SINGLE("LINPUT PGA Switch", WM8900_REG_ADCPATH, 6, 1, 0),
-SOC_SINGLE("RINPUT PGA Switch", WM8900_REG_ADCPATH, 2, 1, 0),
-};
-
-static const char *wm9700_lp_mux[] = { "Disabled", "Enabled" };
-
-static const struct soc_enum wm8900_lineout2_lp_mux =
-SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm9700_lp_mux);
-
-static const struct snd_kcontrol_new wm8900_lineout2_lp =
-SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux);
-
-static const struct snd_soc_dapm_widget wm8900_dapm_widgets[] = {
-
-/* Externally visible pins */
-SND_SOC_DAPM_OUTPUT("LINEOUT1L"),
-SND_SOC_DAPM_OUTPUT("LINEOUT1R"),
-SND_SOC_DAPM_OUTPUT("LINEOUT2L"),
-SND_SOC_DAPM_OUTPUT("LINEOUT2R"),
-SND_SOC_DAPM_OUTPUT("HP_L"),
-SND_SOC_DAPM_OUTPUT("HP_R"),
-
-SND_SOC_DAPM_INPUT("RINPUT1"),
-SND_SOC_DAPM_INPUT("LINPUT1"),
-SND_SOC_DAPM_INPUT("RINPUT2"),
-SND_SOC_DAPM_INPUT("LINPUT2"),
-SND_SOC_DAPM_INPUT("RINPUT3"),
-SND_SOC_DAPM_INPUT("LINPUT3"),
-SND_SOC_DAPM_INPUT("AUX"),
-
-SND_SOC_DAPM_VMID("VMID"),
-
-/* Input */
-SND_SOC_DAPM_MIXER("Left Input PGA", WM8900_REG_POWER2, 3, 0,
-                  wm8900_linpga_controls,
-                  ARRAY_SIZE(wm8900_linpga_controls)),
-SND_SOC_DAPM_MIXER("Right Input PGA", WM8900_REG_POWER2, 2, 0,
-                  wm8900_rinpga_controls,
-                  ARRAY_SIZE(wm8900_rinpga_controls)),
-
-SND_SOC_DAPM_MIXER("Left Input Mixer", WM8900_REG_POWER2, 5, 0,
-                  wm8900_linmix_controls,
-                  ARRAY_SIZE(wm8900_linmix_controls)),
-SND_SOC_DAPM_MIXER("Right Input Mixer", WM8900_REG_POWER2, 4, 0,
-                  wm8900_rinmix_controls,
-                  ARRAY_SIZE(wm8900_rinmix_controls)),
-
-SND_SOC_DAPM_MICBIAS("Mic Bias", WM8900_REG_POWER1, 4, 0),
-
-SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8900_REG_POWER2, 1, 0),
-SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8900_REG_POWER2, 0, 0),
-
-/* Output */
-SND_SOC_DAPM_DAC("DACL", "Left HiFi Playback", WM8900_REG_POWER3, 1, 0),
-SND_SOC_DAPM_DAC("DACR", "Right HiFi Playback", WM8900_REG_POWER3, 0, 0),
-
-/*SND_SOC_DAPM_PGA_E("Headphone Amplifier", WM8900_REG_POWER3, 7, 0, NULL, 0,
-                  wm8900_hp_event,
-                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),*/
-
-SND_SOC_DAPM_PGA("LINEOUT1L PGA", WM8900_REG_POWER2, 8, 0, NULL, 0),
-SND_SOC_DAPM_PGA("LINEOUT1R PGA", WM8900_REG_POWER2, 7, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("LINEOUT2 LP", SND_SOC_NOPM, 0, 0, &wm8900_lineout2_lp),
-SND_SOC_DAPM_PGA("LINEOUT2L PGA", WM8900_REG_POWER3, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("LINEOUT2R PGA", WM8900_REG_POWER3, 5, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("Left Output Mixer", WM8900_REG_POWER3, 3, 0,
-                  wm8900_loutmix_controls,
-                  ARRAY_SIZE(wm8900_loutmix_controls)),
-SND_SOC_DAPM_MIXER("Right Output Mixer", WM8900_REG_POWER3, 2, 0,
-                  wm8900_routmix_controls,
-                  ARRAY_SIZE(wm8900_routmix_controls)),
-};
-
-/* Target, Path, Source */
-static const struct snd_soc_dapm_route audio_map[] = {
-/* Inputs */
-{"Left Input PGA", "LINPUT1 Switch", "LINPUT1"},
-{"Left Input PGA", "LINPUT2 Switch", "LINPUT2"},
-{"Left Input PGA", "LINPUT3 Switch", "LINPUT3"},
-
-{"Right Input PGA", "RINPUT1 Switch", "RINPUT1"},
-{"Right Input PGA", "RINPUT2 Switch", "RINPUT2"},
-{"Right Input PGA", "RINPUT3 Switch", "RINPUT3"},
-
-{"Left Input Mixer", "LINPUT2 Switch", "LINPUT2"},
-{"Left Input Mixer", "LINPUT3 Switch", "LINPUT3"},
-{"Left Input Mixer", "AUX Switch", "AUX"},
-{"Left Input Mixer", "Input PGA Switch", "Left Input PGA"},
-
-{"Right Input Mixer", "RINPUT2 Switch", "RINPUT2"},
-{"Right Input Mixer", "RINPUT3 Switch", "RINPUT3"},
-{"Right Input Mixer", "AUX Switch", "AUX"},
-{"Right Input Mixer", "Input PGA Switch", "Right Input PGA"},
-
-{"ADCL", NULL, "Left Input Mixer"},
-{"ADCR", NULL, "Right Input Mixer"},
-
-/* Outputs */
-{"LINEOUT1L", NULL, "LINEOUT1L PGA"},
-{"LINEOUT1L PGA", NULL, "Left Output Mixer"},
-{"LINEOUT1R", NULL, "LINEOUT1R PGA"},
-{"LINEOUT1R PGA", NULL, "Right Output Mixer"},
-
-{"LINEOUT2L PGA", NULL, "Left Output Mixer"},
-{"LINEOUT2 LP", "Disabled", "LINEOUT2L PGA"},
-{"LINEOUT2 LP", "Enabled", "Left Output Mixer"},
-{"LINEOUT2L", NULL, "LINEOUT2 LP"},
-
-{"LINEOUT2R PGA", NULL, "Right Output Mixer"},
-{"LINEOUT2 LP", "Disabled", "LINEOUT2R PGA"},
-{"LINEOUT2 LP", "Enabled", "Right Output Mixer"},
-{"LINEOUT2R", NULL, "LINEOUT2 LP"},
-
-{"Left Output Mixer", "LINPUT3 Bypass Switch", "LINPUT3"},
-{"Left Output Mixer", "AUX Bypass Switch", "AUX"},
-{"Left Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},
-{"Left Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"},
-{"Left Output Mixer", "DACL Switch", "DACL"},
-
-{"Right Output Mixer", "RINPUT3 Bypass Switch", "RINPUT3"},
-{"Right Output Mixer", "AUX Bypass Switch", "AUX"},
-{"Right Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},
-{"Right Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"},
-{"Right Output Mixer", "DACR Switch", "DACR"},
-
-/* Note that the headphone output stage needs to be connected
- * externally to LINEOUT2 via DC blocking capacitors.  Other
- * configurations are not supported.
- *
- * Note also that left and right headphone paths are treated as a
- * mono path.
- */
-{"Headphone Amplifier", NULL, "LINEOUT2 LP"},
-{"Headphone Amplifier", NULL, "LINEOUT2 LP"},
-{"HP_L", NULL, "Headphone Amplifier"},
-{"HP_R", NULL, "Headphone Amplifier"},
-};
-
-static int wm8900_add_widgets(struct snd_soc_codec *codec)
-{
-       WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__);
-        
-       snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets,
-                               ARRAY_SIZE(wm8900_dapm_widgets));
-       snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
-       snd_soc_dapm_new_widgets(codec);
-
-       return 0;
 }
 
 static void wm8900_work(struct work_struct *work)
 {
-       WM8900_DBG("Enter::wm8900 work, power down wm8900\n");
+       WM8900_DBG("Enter::wm8900_work\n");
 
-#ifdef SPK_CON
-       gpio_set_value(SPK_CON, GPIO_LOW);
-#endif
-       snd_soc_write(wm8900_codec, WM8900_REG_RESET, 0);
-
-       wm8900_current_status = WM8900_IS_SHUTDOWN;
+       wm8900_powerdown();
 }
 
 static void wm8900_set_hw(struct snd_soc_codec *codec)
 {
+       u16 reg;
+
        WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__);
 
+       //snd_soc_write(codec, WM8900_REG_LOUT2CTL, 0x140);
+       //snd_soc_write(codec, WM8900_REG_ROUT2CTL, 0x140);
+
        snd_soc_write(codec, WM8900_REG_HPCTL1, 0x30);
        snd_soc_write(codec, WM8900_REG_POWER1, 0x0100);
        snd_soc_write(codec, WM8900_REG_POWER3, 0x60);
@@ -682,7 +264,7 @@ static void wm8900_set_hw(struct snd_soc_codec *codec)
        snd_soc_write(codec, WM8900_REG_ADDCTL, 0x02);
        snd_soc_write(codec, WM8900_REG_POWER1, 0x09);
        snd_soc_write(codec, WM8900_REG_POWER3, 0xEF);
-       snd_soc_write(codec, WM8900_REG_DACCTRL, 0x00);
+       snd_soc_write(codec, WM8900_REG_DACCTRL, WM8900_REG_DACCTRL_MUTE);
        snd_soc_write(codec, WM8900_REG_LOUTMIXCTL1, 0x150);
        snd_soc_write(codec, WM8900_REG_ROUTMIXCTL1, 0x150);
 
@@ -705,6 +287,26 @@ static void wm8900_set_hw(struct snd_soc_codec *codec)
        snd_soc_write(codec, WM8900_REG_INBOOSTMIX2, 0x0042);
        snd_soc_write(codec, WM8900_REG_ADCPATH, 0x0055);
 
+       reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
+
+       reg &= ~WM8900_REG_DACCTRL_MUTE;
+       snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
+
+       snd_soc_write(codec, WM8900_REG_LOUT1CTL, 0x130);
+       snd_soc_write(codec, WM8900_REG_ROUT1CTL, 0x130);
+
+       /* Turn up vol slowly, for HP out pop noise */
+
+       for (reg = 0; reg <= 0x33; reg += 0x10) {
+                       snd_soc_write(codec, WM8900_REG_LOUT2CTL, 0x100 + reg);
+                       snd_soc_write(codec, WM8900_REG_ROUT2CTL, 0x100 + reg);
+                       msleep(5);
+       }
+       snd_soc_write(codec, WM8900_REG_LOUT2CTL, 0x133);
+       snd_soc_write(codec, WM8900_REG_ROUT2CTL, 0x133);
+
+       msleep(20);
+
 #ifdef SPK_CON
        gpio_set_value(SPK_CON, GPIO_HIGH);
 #endif
@@ -1074,41 +676,8 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       u16 reg;
-
        WM8900_DBG("Enter:%s, %d , mute = %d \n", __FUNCTION__, __LINE__, mute);
 
-       if (mute)
-               return 0;
-
-       reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
-
-       reg &= ~WM8900_REG_DACCTRL_MUTE;
-       snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
-
-       /* Turn up vol slowly, for SPK out pop */
-       for (reg = 0; reg <= 0x30; reg += 0x10) {
-               if (snd_soc_read(codec, WM8900_REG_LOUT1CTL) < 0x30)
-                       snd_soc_write(codec, WM8900_REG_LOUT1CTL, 0x100 + reg);
-
-               if (snd_soc_read(codec, WM8900_REG_ROUT1CTL) < 0x30)
-                       snd_soc_write(codec, WM8900_REG_ROUT1CTL, 0x100 + reg);
-       }
-       snd_soc_write(codec, WM8900_REG_LOUT1CTL, 0x130);
-       snd_soc_write(codec, WM8900_REG_ROUT1CTL, 0x130);
-
-       /* Turn up vol slowly, for HP out pop */
-       for (reg = 0; reg <= 0x33; reg += 0x10) {
-               if (snd_soc_read(codec, WM8900_REG_LOUT2CTL) < 0x33)
-                       snd_soc_write(codec, WM8900_REG_LOUT2CTL, 0x100 + reg);
-
-               if (snd_soc_read(codec, WM8900_REG_ROUT2CTL) < 0x33)
-                       snd_soc_write(codec, WM8900_REG_ROUT2CTL, 0x100 + reg);
-       }
-       snd_soc_write(codec, WM8900_REG_LOUT2CTL, 0x133);
-       snd_soc_write(codec, WM8900_REG_ROUT2CTL, 0x133);
-
        return 0;
 }
 
@@ -1117,21 +686,16 @@ static int wm8900_startup(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
-       struct snd_soc_dai_link *machine = rtd->dai;
-       struct snd_soc_dai *codec_dai = machine->codec_dai;
        struct snd_soc_codec *codec = socdev->card->codec;
 
        WM8900_DBG("Enter::%s----%d substream->stream:%s \n",__FUNCTION__,__LINE__,
                   substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "PLAYBACK":"CAPTURE");
 
-       if (!(codec_dai->playback.active || codec_dai->capture.active)) {
+       cancel_delayed_work_sync(&delayed_work);
 
-               cancel_delayed_work_sync(&delayed_work);
-
-               if (wm8900_current_status & WM8900_IS_STARTUP)
-                       return 0;
+       if (wm8900_current_status == WM8900_IS_SHUTDOWN) {
 
-               WM8900_DBG("Power up wm8900\n");
+               printk("Power up wm8900\n");
 
                wm8900_set_hw(codec);
                wm8900_current_status |= WM8900_IS_STARTUP;
@@ -1140,7 +704,7 @@ static int wm8900_startup(struct snd_pcm_substream *substream,
 }
 
 static void wm8900_shutdown(struct snd_pcm_substream *substream,
-                         struct snd_soc_dai *dai)
+                           struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai_link *machine = rtd->dai;
@@ -1159,8 +723,14 @@ static void wm8900_shutdown(struct snd_pcm_substream *substream,
 
                WM8900_DBG("Is going to power down wm8900\n");
 
-               queue_delayed_work(wm8900_workq, &delayed_work,
-                       msecs_to_jiffies(3000));
+               /* If codec is useless, queue work to close it */
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                       queue_delayed_work(wm8900_workq, &delayed_work,
+                               msecs_to_jiffies(1000));
+               } else {
+                       queue_delayed_work(wm8900_workq, &delayed_work,
+                               msecs_to_jiffies(3000));
+               }
        }
 }
 
@@ -1320,7 +890,6 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
                break;
        }
 
-       
        codec->bias_level = level;
        return 0;
 }
@@ -1337,7 +906,9 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
 
        WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__);
 
-       snd_soc_write(codec, WM8900_REG_RESET, 0);
+       cancel_delayed_work_sync(&delayed_work);
+
+       wm8900_powerdown();
 
        /* Stop the FLL in an orderly fashion */
        ret = wm8900_set_fll(codec, 0, 0, 0);
@@ -1481,7 +1052,7 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
 void wm8900_i2c_shutdown(struct i2c_client *client)
 {
        WM8900_DBG("Enter:%s, %d \n", __FUNCTION__, __LINE__);
-       snd_soc_write(wm8900_codec, WM8900_REG_RESET, 0);
+       wm8900_powerdown();
 }
 
 #ifdef CONFIG_PM
@@ -1531,6 +1102,7 @@ static int wm8900_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "I2C client not yet instantiated\n");
                return -ENODEV;
        }
+
 #if defined(SPK_CON)
        gpio_request(SPK_CON,NULL);
        gpio_direction_output(SPK_CON, GPIO_LOW);
@@ -1546,17 +1118,6 @@ static int wm8900_probe(struct platform_device *pdev)
                goto pcm_err;
        }
 
-       snd_soc_add_controls(codec, wm8900_snd_controls,
-                               ARRAY_SIZE(wm8900_snd_controls));
-       snd_soc_add_controls(codec, wm8900_linpga_controls,
-                               ARRAY_SIZE(wm8900_linpga_controls));
-        snd_soc_add_controls(codec, wm8900_rinpga_controls,
-                               ARRAY_SIZE(wm8900_rinpga_controls));
-        snd_soc_add_controls(codec, wm8900_inmix_controls,
-                                ARRAY_SIZE(wm8900_inmix_controls));
-                              
-       wm8900_add_widgets(codec);
-
        ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to register card\n");