camera : add icatch 7002 isp driver
authorzyc <zyc@rock-chips.com>
Wed, 25 Sep 2013 09:13:06 +0000 (17:13 +0800)
committerzyc <zyc@rock-chips.com>
Wed, 25 Sep 2013 09:14:16 +0000 (17:14 +0800)
22 files changed:
arch/arm/mach-rk3188/board-rk3188-icatch7002-camera.c [new file with mode: 0755]
arch/arm/plat-rk/include/plat/rk_camera.h
arch/arm/plat-rk/rk_camera.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/generic_sensor.c
drivers/media/video/generic_sensor.h
drivers/media/video/icatch7002/Kconfig [new file with mode: 0755]
drivers/media/video/icatch7002/Makefile [new file with mode: 0755]
drivers/media/video/icatch7002/app_i2c_lib_icatch.c [new file with mode: 0755]
drivers/media/video/icatch7002/app_i2c_lib_icatch.h [new file with mode: 0755]
drivers/media/video/icatch7002/burn_spi_sample_code_0910.c [new file with mode: 0755]
drivers/media/video/icatch7002/icatch7002_common.c [new file with mode: 0755]
drivers/media/video/icatch7002/icatch7002_common.h [new file with mode: 0755]
drivers/media/video/icatch7002/icatch7002_mi1040.c [new file with mode: 0755]
drivers/media/video/icatch7002/icatch7002_ov5693.c [new file with mode: 0755]
drivers/media/video/icatch7002/icatch_spi_host.c [new file with mode: 0755]
drivers/media/video/icatch7002/icatch_spi_host.h [new file with mode: 0755]
drivers/media/video/rk30_camera_pingpong.c
drivers/media/video/v4l2-ioctl.c
include/linux/videodev2.h
include/media/v4l2-chip-ident.h

diff --git a/arch/arm/mach-rk3188/board-rk3188-icatch7002-camera.c b/arch/arm/mach-rk3188/board-rk3188-icatch7002-camera.c
new file mode 100755 (executable)
index 0000000..34e3828
--- /dev/null
@@ -0,0 +1,333 @@
+#ifdef CONFIG_VIDEO_RK29
+#include <plat/rk_camera.h>
+#include "../../../drivers/spi/rk29_spim.h"
+#include <linux/spi/spi.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/highmem.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+#include <linux/miscdevice.h>
+#include <asm/dma.h>
+#include <linux/preempt.h>
+#include <mach/board.h>
+#include <linux/miscdevice.h>
+
+struct spi_device* g_icatch_spi_dev = NULL;
+
+
+static struct rk29xx_spi_chip spi_icatch = {
+       //.poll_mode = 1,
+       .enable_dma = 0,
+};
+//user must define this struct according to hardware config    
+static struct spi_board_info board_spi_icatch_devices[] = {    
+       {
+               .modalias  = "spi_icatch",
+               .bus_num = 0,   //0 or 1
+               .max_speed_hz  = 24*1000*1000,
+               .chip_select   = 0, 
+               .mode = SPI_MODE_0,
+               .controller_data = &spi_icatch,
+       },      
+       
+};
+
+
+static int __devinit spi_icatch_probe(struct spi_device *spi)
+{      
+       struct spi_test_data *spi_test_data;
+       int ret = 0;
+       
+       spi->bits_per_word = 8;
+       spi->mode = SPI_MODE_0;
+       ret = spi_setup(spi);
+       if (ret < 0){
+               dev_err(spi, "ERR: fail to setup spi\n");
+               return -1;
+       }       
+
+       g_icatch_spi_dev = spi;
+
+       printk("%s:bus_num=%d,ok\n",__func__,spi->master->bus_num);
+
+       return ret;
+
+}
+
+
+static struct spi_driver spi_icatch_driver = {
+       .driver = {
+               .name           = "spi_icatch",
+               .bus            = &spi_bus_type,
+               .owner          = THIS_MODULE,
+       },
+
+       .probe          = spi_icatch_probe,
+};
+
+static struct miscdevice spi_test_icatch = {
+       .minor = MISC_DYNAMIC_MINOR,
+       .name = "spi_misc_icatch",
+};
+
+static int __init spi_icatch_init(void)
+{      
+       spi_register_board_info(board_spi_icatch_devices, ARRAY_SIZE(board_spi_icatch_devices));
+       
+       misc_register(&spi_test_icatch);
+       return spi_register_driver(&spi_icatch_driver);
+}
+
+static void __exit spi_icatch_exit(void)
+{
+       
+       misc_deregister(&spi_test_icatch);
+       return spi_unregister_driver(&spi_icatch_driver);
+}
+
+module_init(spi_icatch_init);
+module_exit(spi_icatch_exit);
+
+/* Notes:
+
+Simple camera device registration:
+
+       new_camera_device(sensor_name,\       // sensor name, it is equal to CONFIG_SENSOR_X
+                          face,\              // sensor face information, it can be back or front
+                          pwdn_io,\           // power down gpio configuration, it is equal to CONFIG_SENSOR_POWERDN_PIN_XX
+                          flash_attach,\      // sensor is attach flash or not
+                          mir,\               // sensor image mirror and flip control information
+                          i2c_chl,\           // i2c channel which the sensor attached in hardware, it is equal to CONFIG_SENSOR_IIC_ADAPTER_ID_X
+                          cif_chl)  \         // cif channel which the sensor attached in hardware, it is equal to CONFIG_SENSOR_CIF_INDEX_X
+
+Comprehensive camera device registration:
+
+      new_camera_device_ex(sensor_name,\
+                             face,\
+                             ori,\            // sensor orientation, it is equal to CONFIG_SENSOR_ORIENTATION_X
+                             pwr_io,\         // sensor power gpio configuration, it is equal to CONFIG_SENSOR_POWER_PIN_XX
+                             pwr_active,\     // sensor power active level, is equal to CONFIG_SENSOR_RESETACTIVE_LEVEL_X
+                             rst_io,\         // sensor reset gpio configuration, it is equal to CONFIG_SENSOR_RESET_PIN_XX
+                             rst_active,\     // sensor reset active level, is equal to CONFIG_SENSOR_RESETACTIVE_LEVEL_X
+                             pwdn_io,\
+                             pwdn_active,\    // sensor power down active level, is equal to CONFIG_SENSOR_POWERDNACTIVE_LEVEL_X
+                             flash_attach,\
+                             res,\            // sensor resolution, this is real resolution or resoltuion after interpolate
+                             mir,\
+                             i2c_chl,\
+                             i2c_spd,\        // i2c speed , 100000 = 100KHz
+                             i2c_addr,\       // the i2c slave device address for sensor
+                             cif_chl,\
+                             mclk)\           // sensor input clock rate, 24 or 48
+                          
+*/
+static struct rkcamera_platform_data new_camera[] = {
+  new_camera_device_ex(RK29_CAM_ISP_ICATCH7002_OV5693,
+                         back,
+                         180,            // sensor orientation, it is equal to CONFIG_SENSOR_ORIENTATION_X
+                         INVALID_VALUE,         // sensor power gpio configuration, it is equal to CONFIG_SENSOR_POWER_PIN_XX
+                         INVALID_VALUE,     // sensor power active level, is equal to CONFIG_SENSOR_RESETACTIVE_LEVEL_X
+                         RK30_PIN0_PC1,         // sensor reset gpio configuration, it is equal to CONFIG_SENSOR_RESET_PIN_XX
+                         0x0,     // sensor reset active level, is equal to CONFIG_SENSOR_RESETACTIVE_LEVEL_X
+                         RK30_PIN0_PC0,
+                         0x1,    // sensor power down active level, is equal to CONFIG_SENSOR_POWERDNACTIVE_LEVEL_X
+                         INVALID_VALUE,
+                         CONS(RK29_CAM_ISP_ICATCH7002_OV5693,_FULL_RESOLUTION),            // sensor resolution, this is real resolution or resoltuion after interpolate
+                         0,
+                         3,
+                         300000,        // i2c speed , 100000 = 100KHz
+                         CONS(RK29_CAM_ISP_ICATCH7002_OV5693,_I2C_ADDR),       // the i2c slave device address for sensor
+                         0,
+                         24),           // sensor input clock rate, 24 or 48
+       new_camera_device_ex(RK29_CAM_ISP_ICATCH7002_MI1040, //RK29_CAM_ISP_ICATCH7002_MI1040,
+                         front,
+                         360,            // sensor orientation, it is equal to CONFIG_SENSOR_ORIENTATION_X
+                         INVALID_VALUE,         // sensor power gpio configuration, it is equal to CONFIG_SENSOR_POWER_PIN_XX
+                         INVALID_VALUE,     // sensor power active level, is equal to CONFIG_SENSOR_RESETACTIVE_LEVEL_X
+                         RK30_PIN0_PC1,         // sensor reset gpio configuration, it is equal to CONFIG_SENSOR_RESET_PIN_XX
+                         0x0,     // sensor reset active level, is equal to CONFIG_SENSOR_RESETACTIVE_LEVEL_X
+                         RK30_PIN0_PC0,
+                         0x1,    // sensor power down active level, is equal to CONFIG_SENSOR_POWERDNACTIVE_LEVEL_X
+                         INVALID_VALUE,
+                         CONS(RK29_CAM_ISP_ICATCH7002_MI1040,_FULL_RESOLUTION),            // sensor resolution, this is real resolution or resoltuion after interpolate
+                         0,
+                         3,
+                         300000,        // i2c speed , 100000 = 100KHz
+                         CONS(RK29_CAM_ISP_ICATCH7002_MI1040,_I2C_ADDR),       // the i2c slave device address for sensor
+                         0,
+                         24),           // sensor input clock rate, 24 or 48
+       new_camera_device_end  
+};
+#endif  //#ifdef CONFIG_VIDEO_RK29
+/*---------------- Camera Sensor Configuration Macro End------------------------*/
+#include "../../../drivers/media/video/rk30_camera.c"
+/*---------------- Camera Sensor Macro Define End  ---------*/
+
+#define PMEM_CAM_SIZE PMEM_CAM_NECESSARY
+/*****************************************************************************************
+ * camera  devices
+ * author: ddl@rock-chips.com
+ *****************************************************************************************/
+#ifdef CONFIG_VIDEO_RK29
+#define CONFIG_SENSOR_POWER_IOCTL_USR     1 //define this refer to your board layout
+#define CONFIG_SENSOR_RESET_IOCTL_USR     1
+#define CONFIG_SENSOR_POWERDOWN_IOCTL_USR         0
+#define CONFIG_SENSOR_FLASH_IOCTL_USR     0
+
+static void rk_cif_power(struct rk29camera_gpio_res *res,int on)
+{
+       struct regulator *ldo_18,*ldo_28;
+    int camera_reset = res->gpio_reset;
+    int camera_pwrdn = res->gpio_powerdown;
+
+         
+       ldo_28 = regulator_get(NULL, "ricoh_ldo8");     // vcc28_cif
+       ldo_18 = regulator_get(NULL, "ricoh_ldo5");     // vcc18_cif
+       if (ldo_28 == NULL || IS_ERR(ldo_28) || ldo_18 == NULL || IS_ERR(ldo_18)){
+               printk("get cif ldo failed!\n");
+               return;
+       }
+       if(on == 0){
+               while(regulator_is_enabled(ldo_28)>0)   
+                       regulator_disable(ldo_28);
+               regulator_put(ldo_28);
+
+               while(regulator_is_enabled(ldo_18)>0)
+                       regulator_disable(ldo_18);
+
+               iomux_set(GPIO1_A4);
+               iomux_set(GPIO1_A5) ;
+               iomux_set(GPIO1_A6);
+               iomux_set(GPIO1_A7);
+               iomux_set(GPIO3_B6);
+               iomux_set(GPIO3_B7);
+               iomux_set(GPIO0_C0);
+               gpio_set_value(RK30_PIN1_PA4,0);
+               gpio_set_value(RK30_PIN1_PA5,0);
+               gpio_set_value(RK30_PIN1_PA6,0);        //Vincent_Liu@asus.com for clk 24M
+               gpio_set_value(RK30_PIN1_PA7,0);
+               gpio_set_value(RK30_PIN3_PB6,0);
+               gpio_set_value(RK30_PIN3_PB7,0);
+               gpio_set_value(RK30_PIN0_PC0,0);
+
+               printk("%s off ldo5 vcc18_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_18));
+               regulator_put(ldo_18);
+               
+       }
+       else{
+        // reset must be low
+        if (camera_reset != INVALID_GPIO) 
+               gpio_set_value(camera_reset, 0);
+       printk("%s ResetPin=%d ..PinLevel = %x\n",res->dev_name,camera_reset,0);
+        //pwdn musb be low
+        if (camera_pwrdn != INVALID_GPIO) 
+               gpio_set_value(camera_pwrdn, 0);
+       printk("%s PwrdnPin=%d ..PinLevel = %x\n",res->dev_name,camera_pwrdn,0);
+       
+               gpio_set_value(RK30_PIN1_PA6,1);        //Vincent_Liu@asus.com for clk 24M
+
+
+               regulator_set_voltage(ldo_18, 1800000, 1800000);
+               regulator_enable(ldo_18);
+               printk("%s set ldo5 vcc18_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_18));
+               regulator_put(ldo_18);
+
+               regulator_set_voltage(ldo_28, 2800000, 2800000);
+               regulator_enable(ldo_28);
+               //printk("%s set ldo7 vcc28_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_28));
+               regulator_put(ldo_28);
+
+       }
+}
+
+#if CONFIG_SENSOR_RESET_IOCTL_USR
+static int sensor_reset_usr_cb (struct rk29camera_gpio_res *res,int on)
+{
+       //#error "CONFIG_SENSOR_RESET_IOCTL_USR is 1, sensor_reset_usr_cb function must be writed!!";
+               
+    int camera_reset = res->gpio_reset;
+    int camera_ioflag = res->gpio_flag;
+    int camera_io_init = res->gpio_init;  
+    int ret = 0;
+    
+    if (camera_reset != INVALID_GPIO) {
+               if (camera_io_init & RK29_CAM_RESETACTIVE_MASK) {
+                       if (on) {
+                       gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                       printk("%s ResetPin=%d ..PinLevel = %x\n",res->dev_name,camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                               mdelay(6);
+                       } else {
+                               gpio_set_value(camera_reset,(((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                       printk("%s ResetPin= %d..PinLevel = %x\n",res->dev_name, camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                mdelay(6);
+                       iomux_set(SPI0_CLK);
+                       iomux_set(SPI0_RXD);
+                       iomux_set(SPI0_TXD);
+                       iomux_set(SPI0_CS0);
+                       iomux_set(I2C3_SDA);
+                       iomux_set(I2C3_SCL);
+                mdelay(6);
+               }
+               } else {
+                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                       printk("%s ResetPin=%d request failed!", res->dev_name,camera_reset);
+               }
+    } else {
+               ret = RK29_CAM_EIO_INVALID;
+    }
+    return ret;
+
+}
+#endif
+
+#if CONFIG_SENSOR_POWER_IOCTL_USR
+static int sensor_power_usr_cb (struct rk29camera_gpio_res *res,int on)
+{
+       //#error "CONFIG_SENSOR_POWER_IOCTL_USR is 1, sensor_power_usr_cb function must be writed!!";
+       rk_cif_power(res,on);
+       return 0;
+}
+#endif
+
+#if CONFIG_SENSOR_FLASH_IOCTL_USR
+static int sensor_flash_usr_cb (struct rk29camera_gpio_res *res,int on)
+{
+       #error "CONFIG_SENSOR_FLASH_IOCTL_USR is 1, sensor_flash_usr_cb function must be writed!!";
+}
+#endif
+
+static struct rk29camera_platform_ioctl_cb     sensor_ioctl_cb = {
+       #if CONFIG_SENSOR_POWER_IOCTL_USR
+       .sensor_power_cb = sensor_power_usr_cb,
+       #else
+       .sensor_power_cb = NULL,
+       #endif
+
+       #if CONFIG_SENSOR_RESET_IOCTL_USR
+       .sensor_reset_cb = sensor_reset_usr_cb,
+       #else
+       .sensor_reset_cb = NULL,
+       #endif
+
+       #if CONFIG_SENSOR_POWERDOWN_IOCTL_USR
+       .sensor_powerdown_cb = sensor_powerdown_usr_cb,
+       #else
+       .sensor_powerdown_cb = NULL,
+       #endif
+
+       #if CONFIG_SENSOR_FLASH_IOCTL_USR
+       .sensor_flash_cb = sensor_flash_usr_cb,
+       #else
+       .sensor_flash_cb = NULL,
+       #endif
+};
+static rk_sensor_user_init_data_s rk_init_data_sensor[RK_CAM_NUM] ;
+#include "../../../drivers/media/video/rk30_camera.c"
+
+#endif /* CONFIG_VIDEO_RK29 */
index 5db427ae4209f4b65ab60a3f4ecf7555890fd095..cd349c8a759eea4e255c3345ce3e66f52516f511 100755 (executable)
 #define RK29_CAM_SENSOR_NT99240 nt99240  //oyyf@rock-chips.com 
 #define RK29_CAM_SENSOR_NT99252 nt99252  //oyyf@rock-chips.com 
 #define RK29_CAM_SENSOR_NT99340 nt99340  //oyyf@rock-chips.com 
-
+#define RK29_CAM_ISP_ICATCH7002_MI1040  icatchmi1040   
+#define RK29_CAM_ISP_ICATCH7002_OV5693  icatchov5693
 
 #define RK29_CAM_SENSOR_NAME_OV7675 "ov7675"
 #define RK29_CAM_SENSOR_NAME_OV9650 "ov9650"
 #define RK29_CAM_ISP_NAME_MTK9335ISP "mtk9335isp"
 #define RK29_CAM_SENSOR_NAME_HM2057  "hm2057"
 #define RK29_CAM_SENSOR_NAME_HM5065  "hm5065"
+#define RK29_CAM_ISP_NAME_ICATCH7002_MI1040 "icatchmi1040"
+#define RK29_CAM_ISP_NAME_ICATCH7002_OV5693 "icatchov5693"
 
 //Sensor full resolution define
 #define ov7675_FULL_RESOLUTION     0x30000            // 0.3 megapixel
 #define nt99240_FULL_RESOLUTION     0x200000           // oyyf@rock-chips.com:  2 megapixel 1600*1200
 #define nt99252_FULL_RESOLUTION     0x200000           // oyyf@rock-chips.com:  2 megapixel 1600*1200
 #define nt99340_FULL_RESOLUTION     0x300000           // oyyf@rock-chips.com:  3 megapixel 2048*1536
-
+#define icatchmi1040_FULL_RESOLUTION 0x200000
+#define icatchov5693_FULL_RESOLUTION 0x500000
 #define end_FULL_RESOLUTION         0x00
 
 //Sensor i2c addr define
 #define mtk9335isp_I2C_ADDR         0x50 
 #define hm2057_I2C_ADDR             0x48
 #define hm5065_I2C_ADDR             0x3e
+#define icatchmi1040_I2C_ADDR          0x78
+#define icatchov5693_I2C_ADDR       0x78
 #define end_I2C_ADDR                INVALID_VALUE
 
 
                                         SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWRDN,0)|\
                                         SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,3))
 #define mtk9335isp_PWRSEQ               sensor_PWRSEQ_DEFAULT
+#define icatchov5693_PWRSEQ               (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\
+                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\
+                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,1))
+#define icatchmi1040_PWRSEQ               (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\
+                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\
+                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,1))
+
 #define end_PWRSEQ                      0xffffffff
                                           
 
 #define Sensor_CropSet(a,b)                  a->reserved[1] = b;
 #define Sensor_CropGet(a)                    a->reserved[1]
 
+#define RK29_CAM_SUBDEV_HDR_EXPOSURE        0x04
+
+#define RK_VIDEOBUF_HDR_EXPOSURE_MINUS_1        0x00
+#define RK_VIDEOBUF_HDR_EXPOSURE_NORMAL         0x01
+#define RK_VIDEOBUF_HDR_EXPOSURE_PLUS_1         0x02
+#define RK_VIDEOBUF_HDR_EXPOSURE_FINISH         0x03
+#define RK_VIDEOBUF_CODE_SET(rk_code,type)  rk_code = (('R'<<24)|('K'<<16)|type)
+#define RK_VIDEOBUF_CODE_CHK(rk_code)       ((rk_code&(('R'<<24)|('K'<<16)))==(('R'<<24)|('K'<<16)))
+
 enum rk29camera_ioctrl_cmd
 {
        Cam_Power,
index c301bae3e35d9f32c621f72568a3ef954961d939..cca0240d13a4b54c0ca71a5a39a9866590d07b0d 100755 (executable)
 *        2. Reduce delay time after power off or power down camera;\r
 *v0.1.5:\r
 *        1. if sensor power callback failed, power down sensor;\r
+*v0.1.6:\r
+                1. when power down,HWRST just need to set to powerdown mode.\r
 */\r
-static int camio_version = KERNEL_VERSION(0,1,5);\r
+static int camio_version = KERNEL_VERSION(0,1,6);\r
 module_param(camio_version, int, S_IRUGO);\r
 \r
 \r
@@ -1491,9 +1493,13 @@ static int rk_sensor_pwrseq(struct device *dev,int powerup_sequence, int on, int
 \r
             case SENSOR_PWRSEQ_HWRST:\r
             {\r
-                ret = rk_sensor_ioctrl(dev,Cam_Reset, 1);\r
-                msleep(2);\r
-                ret |= rk_sensor_ioctrl(dev,Cam_Reset, 0); \r
+                if(!on){\r
+                    rk_sensor_ioctrl(dev,Cam_Reset, 1);\r
+                }else{\r
+                    ret = rk_sensor_ioctrl(dev,Cam_Reset, 1);\r
+                    msleep(2);\r
+                    ret |= rk_sensor_ioctrl(dev,Cam_Reset, 0); \r
+                }\r
                 if (ret<0) {\r
                     eprintk("SENSOR_PWRSEQ_HWRST failed");\r
                 } else {\r
index 0f10c615d09af6c759bdfee0c9785716e33558f2..3c76616d6d92f07e65047f3ad2b488eea81c6070 100755 (executable)
@@ -1205,6 +1205,14 @@ config SOC_CAMERA_MV9335
           MtekVision camera isp chip
 
 source "drivers/media/video/mv9335/Kconfig"    
+config SOC_CAMERA_ICATCH7002
+        tristate "Icatch camera isp chip"
+        depends on SOC_CAMERA && I2C
+               default n
+        help
+          Icatch camera isp chip
+
+source "drivers/media/video/icatch7002/Kconfig"        
 
 config VIDEO_RK29
        tristate "RKXX Camera Sensor Interface driver"
index d84dc4db05803cd4a43fe44f6a48c6f568ca85f6..f3b5433da7b40a64679c82ee6e6138dce470c866 100755 (executable)
@@ -126,7 +126,7 @@ obj-$(CONFIG_SOC_CAMERA_S5K5CA)     += s5k5ca.o
 obj-$(CONFIG_SOC_CAMERA_HM2057)        += hm2057.o
 obj-$(CONFIG_SOC_CAMERA_HM5065)        += hm5065.o
 obj-$(CONFIG_SOC_CAMERA_MV9335) += mv9335/
-
+obj-$(CONFIG_SOC_CAMERA_ICATCH7002)    += icatch7002/
 # And now the v4l2 drivers:
 
 obj-$(CONFIG_VIDEO_BT848) += bt8xx/
index 4928e6d059867ef91f15a9729dee43fdc0d98724..681fd9f2c05fc0bae4ffe7c5433c1f8df00c6e15 100755 (executable)
 *        3. support cropcap;\r
 *v.0.1.c:\r
 *        1. modify generic_sensor_s_fmt, flash will work everytime when capture\r
+*v.0.1.d:
+                1. add some callbacks for icatch
 */\r
-static int version = KERNEL_VERSION(0,1,0xc);\r
+static int version = KERNEL_VERSION(0,1,0xd);\r
 module_param(version, int, S_IRUGO);\r
 \r
 \r
@@ -951,6 +953,9 @@ int generic_sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
     struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct generic_sensor *sensor = to_generic_sensor(client);\r
     struct sensor_v4l2ctrl_info_s *ctrl_info;\r
+    struct v4l2_ext_control ext_ctrl;\r
+    struct soc_camera_device *icd = client->dev.platform_data;\r
+\r
     int ret = 0;\r
 \r
     ctrl_info = sensor_find_ctrl(sensor->ctrls,ctrl->id);\r
@@ -958,7 +963,19 @@ int generic_sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
         SENSOR_TR("v4l2_control id(0x%x) is invalidate",ctrl->id);\r
         ret = -EINVAL;\r
     } else {\r
+        ext_ctrl.value = ctrl->value;\r
+        ext_ctrl.id = ctrl->id;\r
+        \r
         ctrl->value = ctrl_info->cur_value;\r
+        \r
+        if (ctrl_info->cb) {\r
+            ret = (ctrl_info->cb)(icd,ctrl_info, &ext_ctrl,false);\r
+            if(ret == 0)\r
+                ctrl->value = ctrl_info->cur_value;\r
+        } else {\r
+            SENSOR_TR("v4l2_control id(0x%x) callback isn't exist",ctrl->id);\r
+            ret = -EINVAL;\r
+        }\r
     }\r
 \r
     return ret;\r
@@ -983,7 +1000,7 @@ int generic_sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
         ext_ctrl.value = ctrl->value;\r
         \r
         if (ctrl_info->cb) {\r
-            ret = (ctrl_info->cb)(icd,ctrl_info, &ext_ctrl);\r
+            ret = (ctrl_info->cb)(icd,ctrl_info, &ext_ctrl,true);\r
         } else {\r
             SENSOR_TR("v4l2_control id(0x%x) callback isn't exist",ctrl->id);\r
             ret = -EINVAL;\r
@@ -1006,6 +1023,13 @@ int generic_sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext
         ret = -EINVAL;\r
     } else {\r
         ext_ctrl->value = ctrl_info->cur_value;\r
+        if (ctrl_info->cb) {\r
+            ret = (ctrl_info->cb)(icd,ctrl_info, ext_ctrl,false);\r
+        } else {\r
+            SENSOR_TR("v4l2_control id(0x%x) callback isn't exist",ext_ctrl->id);\r
+            ret = -EINVAL;\r
+        }\r
+\r
     }\r
 \r
     return ret;\r
@@ -1024,7 +1048,7 @@ int generic_sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_
         ret = -EINVAL;\r
     } else {        \r
         if (ctrl_info->cb) {\r
-            ret = (ctrl_info->cb)(icd,ctrl_info, ext_ctrl);\r
+            ret = (ctrl_info->cb)(icd,ctrl_info, ext_ctrl,true);\r
         } else {\r
             SENSOR_TR("v4l2_ext_control id(0x%x) callback isn't exist",ext_ctrl->id);\r
             ret = -EINVAL;\r
@@ -1387,6 +1411,9 @@ int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable)
 \r
     SENSOR_DG("s_stream: %d %d",enable,sensor->sensor_focus.focus_state);\r
        if (enable == 1) {\r
+           if(sensor->sensor_cb.sensor_s_stream_cb){\r
+               sensor->sensor_cb.sensor_s_stream_cb(sd,enable);\r
+           }\r
                sensor->info_priv.stream = true;\r
        if (sensor->sensor_focus.sensor_wq) {\r
                        if (sensor->sensor_focus.focus_state == FocusState_Inval) {\r
@@ -1395,6 +1422,10 @@ int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable)
         }\r
        } else if (enable == 0) {
            sensor->info_priv.stream = false;\r
+           if(sensor->sensor_cb.sensor_s_stream_cb){\r
+               sensor->sensor_cb.sensor_s_stream_cb(sd,enable);\r
+           }\r
+\r
                if (sensor->sensor_focus.sensor_wq)\r
             flush_workqueue(sensor->sensor_focus.sensor_wq);\r
                \r
@@ -1402,3 +1433,15 @@ int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable)
        return 0;\r
 } \r
 \r
+int generic_sensor_enum_framesizes(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize){\r
+       struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+    struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+    if(sensor->sensor_cb.sensor_enum_framesizes){\r
+        return sensor->sensor_cb.sensor_enum_framesizes(sd,fsize);\r
+    }else{\r
+        return -1;\r
+    }\r
+\r
+}\r
+\r
index b31814eba3e366ee916c94bc7264fb0c3fdca202..65a4cd55b611448a9f9d472d3fa32db188cc7213 100755 (executable)
@@ -209,7 +209,7 @@ typedef struct rk_sensor_priv_s
 struct sensor_v4l2ctrl_info_s {\r
     struct v4l2_queryctrl *qctrl;\r
     int (*cb)(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
-              struct v4l2_ext_control *ext_ctrl);\r
+              struct v4l2_ext_control *ext_ctrl,bool is_set);\r
     struct rk_sensor_reg **sensor_Seqe;\r
     int cur_value;\r
     int num_ctrls;\r
@@ -218,7 +218,7 @@ struct sensor_v4l2ctrl_info_s {
 struct sensor_v4l2ctrl_usr_s {\r
     struct v4l2_queryctrl qctrl;\r
     int (*cb)(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
-              struct v4l2_ext_control *ext_ctrl);\r
+              struct v4l2_ext_control *ext_ctrl,bool is_set);\r
     struct rk_sensor_reg **sensor_Seqe;\r
 };\r
 \r
@@ -234,6 +234,9 @@ struct sensor_ops_cb_s{
        int (*sensor_s_fmt_cb_th)(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture);\r
        int (*sensor_s_fmt_cb_bh)(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture);\r
        int (*sensor_try_fmt_cb_th)(struct i2c_client *client,struct v4l2_mbus_framefmt *mf);\r
+       int (*sensor_s_stream_cb)(struct v4l2_subdev *sd, int enable);\r
+    int (*sensor_enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize);\r
+\r
 };\r
 //flash off in fixed time to prevent from too hot , zyc\r
 struct rk_flash_timer{\r
@@ -300,6 +303,7 @@ extern int generic_sensor_af_workqueue_set(struct soc_camera_device *icd, enum r
 extern int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable);\r
 extern int generic_sensor_writebuf(struct i2c_client *client, char *buf, int buf_size);\r
 extern int generic_sensor_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *cc);\r
+extern int generic_sensor_enum_framesizes(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize);\r
 \r
 static inline int sensor_get_full_width_height(int full_resolution, unsigned short *w, unsigned short *h)\r
 {\r
@@ -404,7 +408,7 @@ static inline void sensor_v4l2ctrl_info_init (struct sensor_v4l2ctrl_info_s *ptr
                                         int step,\r
                                         int default_val,\r
                                         int(*cb)(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
-                                                 struct v4l2_ext_control *ext_ctrl),\r
+                                                 struct v4l2_ext_control *ext_ctrl,bool is_set),\r
                                         struct rk_sensor_reg ** sensor_seqe\r
                                         )\r
 {\r
@@ -469,11 +473,15 @@ static inline int sensor_v4l2ctrl_replace_cb(struct generic_sensor *sensor, int
 }\r
 \r
 static inline int sensor_v4l2ctrl_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
-                                                     struct v4l2_ext_control *ext_ctrl)\r
+                                                     struct v4l2_ext_control *ext_ctrl,bool is_set)\r
 {\r
     struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));    \r
     int value = ext_ctrl->value;\r
     int index;\r
+    \r
+    if(!is_set){\r
+        return 0;\r
+    }\r
 \r
     if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) {\r
         printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value,\r
@@ -496,7 +504,7 @@ static inline int sensor_v4l2ctrl_default_cb(struct soc_camera_device *icd, stru
     }\r
 }\r
 static inline int sensor_v4l2ctrl_flash_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
-                                                     struct v4l2_ext_control *ext_ctrl)\r
+                                                     struct v4l2_ext_control *ext_ctrl,bool is_set)\r
 {\r
     //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
     int value = ext_ctrl->value;\r
@@ -518,7 +526,7 @@ static inline int sensor_v4l2ctrl_flash_cb(struct soc_camera_device *icd, struct
     return 0;\r
 }\r
 static inline int sensor_focus_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
-                                                                                                        struct v4l2_ext_control *ext_ctrl)\r
+                                                                                                        struct v4l2_ext_control *ext_ctrl,bool is_set)\r
 {\r
        struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));    \r
        int value = ext_ctrl->value;\r
@@ -530,7 +538,7 @@ static inline int sensor_focus_default_cb(struct soc_camera_device *icd, struct
                        ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum);\r
                return -EINVAL;\r
        }\r
-    \r
+\r
        if(sensor->sensor_focus.focus_state == FocusState_Inval){\r
                printk(KERN_ERR "%s(%d): focus have not been init success yet\n",__FUNCTION__,__LINE__);\r
                //set focus delay\r
@@ -653,7 +661,7 @@ static inline int sensor_focus_default_cb(struct soc_camera_device *icd, struct
 \r
 }\r
 static inline int sensor_face_detect_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
-                                                                                                        struct v4l2_ext_control *ext_ctrl)\r
+                                                                                                        struct v4l2_ext_control *ext_ctrl,bool is_set)\r
 {\r
        struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));    \r
        int value = ext_ctrl->value;\r
@@ -672,6 +680,24 @@ static inline int sensor_face_detect_default_cb(struct soc_camera_device *icd, s
        }\r
        return ret;\r
 }\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+                                                                                                        struct v4l2_ext_control *ext_ctrl);\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+                                                                                                        struct v4l2_ext_control *ext_ctrl);\r
+                                                                                                        \r
+static inline int sensor_v4l2ctrl_mirror_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+                                                                                                        struct v4l2_ext_control *ext_ctrl,bool is_set){\r
+       return sensor_v4l2ctrl_mirror_cb(icd,ctrl_info, ext_ctrl);\r
+                                                                                        \r
+\r
+}\r
+static inline int sensor_v4l2ctrl_flip_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+                                                                                                        struct v4l2_ext_control *ext_ctrl,bool is_set){\r
+       return sensor_v4l2ctrl_flip_cb(icd,ctrl_info, ext_ctrl);\r
+                                                                                        \r
+\r
+}\r
+\r
 #define new_user_v4l2ctrl(ctl_id,ctl_type,ctl_name,ctl_min,ctl_max,ctl_step,default_val,callback,seqe)\\r
 {\\r
     .qctrl = {\\r
@@ -1026,14 +1052,14 @@ static inline int sensor_face_detect_default_cb(struct soc_camera_device *icd, s
        }  \\r
        if (CFG_FunChk(sensor_config,CFG_Mirror)) {  \\r
         sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_HFLIP,V4L2_CTRL_TYPE_BOOLEAN, \\r
-                            "Mirror Control",0,1,1,0,sensor_v4l2ctrl_mirror_cb,NULL); \\r
+                            "Mirror Control",0,1,1,0,sensor_v4l2ctrl_mirror_default_cb,NULL); \\r
         controls++;  \\r
         ctrls++;  \\r
        }  \\r
        if (CFG_FunChk(sensor_config,CFG_Flip)) {  \\r
         ctrls->qctrl = controls; \\r
         sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_VFLIP,V4L2_CTRL_TYPE_BOOLEAN,  \\r
-                            "Flip Control",0,1,1,0,sensor_v4l2ctrl_flip_cb,NULL); \\r
+                            "Flip Control",0,1,1,0,sensor_v4l2ctrl_flip_default_cb,NULL); \\r
         controls++;  \\r
         ctrls++;  \\r
        }  \\r
@@ -1196,6 +1222,7 @@ static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {\
        .enum_mbus_fmt  = generic_sensor_enum_fmt,\\r
        .enum_frameintervals = generic_sensor_enum_frameintervals,\\r
        .s_stream   = generic_sensor_s_stream,\\r
+       .enum_framesizes = generic_sensor_enum_framesizes,\\r
 };\\r
 static struct v4l2_subdev_ops sensor_subdev_ops = {\\r
        .core   = &sensor_subdev_core_ops,\\r
diff --git a/drivers/media/video/icatch7002/Kconfig b/drivers/media/video/icatch7002/Kconfig
new file mode 100755 (executable)
index 0000000..4d0fa33
--- /dev/null
@@ -0,0 +1,15 @@
+#
+#  Fujitsu camera isp chip: m6moj.
+#
+config ICATCH7002_OV5693
+       depends on SOC_CAMERA_ICATCH7002
+       tristate "icatch7002 attached ov5693"
+       default n
+       help
+       Choose Y here if you have this this sensor and it is attach to icatch7002
+config ICATCH7002_MI1040
+       depends on SOC_CAMERA_ICATCH7002
+       tristate "icatch7002 attached mi1040"
+       default n
+       help
+       Choose Y here if you have this this sensor and it is attach to icatch7002
diff --git a/drivers/media/video/icatch7002/Makefile b/drivers/media/video/icatch7002/Makefile
new file mode 100755 (executable)
index 0000000..0377415
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Makefile for icatch isp driver
+#
+obj-$(CONFIG_SOC_CAMERA_ICATCH7002)    += icatch7002_common.o
+#obj-$(CONFIG_SOC_CAMERA_ICATCH7002)   += icatch_spi_host.o
+obj-$(CONFIG_ICATCH7002_MI1040)                += icatch7002_mi1040.o
+obj-$(CONFIG_ICATCH7002_OV5693)                += icatch7002_ov5693.o
+obj-$(CONFIG_SOC_CAMERA_ICATCH7002)    += burn_spi_sample_code_0910.o
+obj-$(CONFIG_SOC_CAMERA_ICATCH7002)    += app_i2c_lib_icatch.o
+
diff --git a/drivers/media/video/icatch7002/app_i2c_lib_icatch.c b/drivers/media/video/icatch7002/app_i2c_lib_icatch.c
new file mode 100755 (executable)
index 0000000..c85a178
--- /dev/null
@@ -0,0 +1,2298 @@
+/****************************************************************************\r
+ *\r
+ *        Copyright (c) 2006-2008 by Sunplus mMedia Inc., Ltd.\r
+ *\r
+ *  This software is copyrighted by and is the property of Sunplus\r
+ *  mMedia Inc., Ltd. All rights are reserved by Sunplus mMedia\r
+ *  Inc., Ltd. This software may only be used in accordance with the\r
+ *  corresponding license agreement. Any unauthorized use, duplication,\r
+ *  distribution, or disclosure of this software is expressly forbidden.\r
+ *\r
+ *  This Copyright notice MUST not be removed or modified without prior\r
+ *  written consent of Sunplus mMedia Inc., Ltd.\r
+ *\r
+ *  Sunplus mMedia Inc., Ltd. reserves the right to modify this\r
+ *  software without notice.\r
+ *\r
+ *  Sunplus mMedia Inc., Ltd.\r
+ *  19-1, Innovation First Road, Science-Based Industrial Park,\r
+ *  Hsin-Chu, Taiwan, R.O.C.\r
+ *\r
+ ****************************************************************************/\r
+#include <linux/spi/spi.h>\r
+#include <mach/board.h>\r
+\r
+#include "app_i2c_lib_icatch.h"\r
+#include <linux/delay.h>\r
+#include "icatch7002_common.h"\r
+\r
+#define I2CDataWrite(reg,val) icatch_sensor_write((reg),(val))\r
+#define I2CDataRead(reg)  icatch_sensor_read((reg))\r
+extern struct spi_device* g_icatch_spi_dev;\r
+\r
+/****************************************************************************\r
+ *                                             C O N S T A N T S                                                                               *\r
+ ****************************************************************************/\r
+#define FW_HEADER_SIZE 16\r
+#define RES_3ACALI_HEADER_SIZE 8\r
+#define RES_LSC_HEADER_SIZE            24\r
+#define RES_LSCDQ_HEADER_SIZE  16\r
+\r
+/****************************************************************************\r
+ *                                             M A C R O S                                                                                     *\r
+ ****************************************************************************/\r
+#ifndef tmrUsDelay\r
+#define tmrUsDelay(ulTime)     (((ulTime)>1000)?(msleep((ulTime)/1000)):udelay((ulTime)))\r
+#endif\r
+/****************************************************************************\r
+ *                                             D A T A    T Y P E S                                                                    *\r
+ ****************************************************************************/\r
+\r
+/****************************************************************************\r
+ *                                             G L O B A L    D A T A                                                                  *\r
+ ****************************************************************************/\r
+\r
+/****************************************************************************\r
+ *                                             E X T E R N A L    R E F E R E N C E S                                          *\r
+ ****************************************************************************/\r
+\r
+/****************************************************************************\r
+ *                                             F U N C T I O N    D E C L A R A T I O N S                                      *\r
+ ****************************************************************************/\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_BandSelectionSet\r
+ *  ucParam:\r
+     0x00      Reserved\r
+     0x01      50\r
+     0x02      60\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_BandSelectionSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_BANDING_SELECTION, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_ColorEffectSet\r
+ *  ucParam:\r
+     0x00      Normal\r
+     0x01      Aqua\r
+     0x02      Negative\r
+     0x03      Sepia\r
+     0x04      Grayscale\r
+     0x05      Vivid\r
+     0x06      Aura\r
+     0x07      Vintage\r
+     0x08      Vintage2\r
+     0x09      Lomo\r
+     0x0A      Red\r
+     0x0B      Blue\r
+     0x0C      Green\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_ColorEffectSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_COLOR_EFFECT, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_EvSet\r
+ *  ucParam:\r
+     0x00      +2.0\r
+     0x01      +1.7\r
+     0x02      +1.3\r
+     0x03      +1.0\r
+     0x04      +0.7\r
+     0x05      +0.3\r
+     0x06      0\r
+     0x07      -0.3\r
+     0x08      -0.7\r
+     0x09      -1.0\r
+     0x0A      -1.3\r
+     0x0B      -1.7\r
+     0x0C      -2.0\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_EvSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_EV_COMPENSATION, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_FlashModeSet\r
+ *  ucParam:\r
+     0x00      Auto\r
+     0x01      Off\r
+     0x02      On\r
+     0x03      Reserved\r
+     0x04      Torch\r
+     0xFF      Main Flash(100%, once)\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_FlashModeSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_FLASH_MODE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_FocusModeSet\r
+ *  ucParam:\r
+     0x00      Auto\r
+     0x01      Macro\r
+     0x02      Infinity Fixed\r
+     0x03      Continuous AF\r
+     0x04      Full Search\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_FocusModeSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_FOCUS_MODE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_PvSizeSet\r
+ *  ucParam:\r
+     0x00      1280x960\r
+     0x01      3264x2448\r
+     0x02      1920x1080\r
+     0x03      320x240(reserved)\r
+     0x04      1280x720\r
+     0x05      1040x780\r
+     0x06      2080x1560\r
+     0x07      3648x2736\r
+     0x08      4160x3120\r
+     0x09      3360x1890\r
+     0x0A      2592x1944\r
+     0x0B      640x480\r
+     0x0C      1408x1408\r
+     0x0D      1920x1088\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_PvSizeSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_PV_SIZE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_SceneModeSet\r
+ *  ucParam:\r
+     0x00      Normal\r
+     0x01      Action\r
+     0x02      Text\r
+     0x03      Beach\r
+     0x04      Candle light\r
+     0x05      Firework\r
+     0x06      Landscape\r
+     0x07      Night\r
+     0x08      Night Portrait\r
+     0x09      Party\r
+     0x0A      Portrait\r
+     0x0B      Snow\r
+     0x0C      Sport\r
+     0x0D      Anti-shake\r
+     0x0E      Sunset\r
+     0x0F      High Sensitivity\r
+     0x10      Landscape Portrait\r
+     0x11      Kids\r
+     0x12      Pet\r
+     0x13      Flower\r
+     0x14      Soft Flowing Water\r
+     0x15      Food\r
+     0x16      Backlight\r
+     0x17      Indoor\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_SceneModeSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_SCENE_MODE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_WhiteBalanceSet\r
+ *  ucParam:\r
+     0x00      Auto\r
+     0x01      Daylight\r
+     0x02      Cloudy\r
+     0x03      Shade\r
+     0x04      Fluorescent_L\r
+     0x05      Fluorescent_H\r
+     0x06      Tungsten\r
+     0x07      Reserved\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_WhiteBalanceSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_WHITE_BALANCE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AEModeSet\r
+ *  ucParam:\r
+     0x00      Multi\r
+     0x01      Center\r
+     0x02      Spot\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_AEModeSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_AE_MODE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CapModeSet\r
+ *  ucParam:\r
+     0x00      Single\r
+     0x01      HDR\r
+     0x02      Reserved\r
+     0x03      Burst capture(Unlimited)(ZSL)\r
+     0x04      Burst capture(Unlimited)(mode switch)\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CapModeSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CAP_MODE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_ISOSet\r
+ *  ucParam:\r
+     0x00      Auto\r
+     0x01      ISO 50\r
+     0x02      ISO 100\r
+     0x03      ISO 200\r
+     0x04      ISO 400\r
+     0x05      ISO 800\r
+     0x06      ISO 1600\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_ISOSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CAP_ISO, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AuraColorIndexSet\r
+ *  ucParam : Color index (bit control)\r
+     Effect bit : bit 0~5\r
+     1 : Color enable\r
+     0 : Color disable\r
+     bit 0 : Red\r
+     bit 1 : Orange\r
+     bit 2 : Yellow\r
+     bit 3 : Green\r
+     bit 4 : Blue\r
+     bit 5 : Violet\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_AuraColorIndexSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_AURA_COLOR_INDEX, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_OpticalZoomSet\r
+ *  ucParam:\r
+     0x00      Zoom in\r
+     0x01      Zoom out\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_OpticalZoomSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_OPTICAL_ZOOM, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_IspFuncSet\r
+ *  ucParam: Function control (bit control)\r
+     Effect bit : bit 0~1\r
+     1 : function enable\r
+     0 : function disable\r
+     bit 0 : DWDR\r
+     bit 1 : Edge information\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_IspFuncSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_ISP_FUNCTION, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_PvCapModeSet\r
+ *  ucParam:\r
+     0x00      Preview mode\r
+     0x01      Capture mode(mode switch)\r
+     0x02      Capture mode(ZSL)\r
+     0x03      Capture mode(Non-ZSL)\r
+     0x04      Idle mode\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_PvCapModeSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_PV_CAP_MODE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_PvStreamSet\r
+ *  ucParam:\r
+     0x00      Stream off\r
+     0x01      Stream on\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_PvStreamSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_PV_STREAM, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_BurstAbortSet\r
+ *  ucParam:\r
+     0x00      Burst abort(mode switch)\r
+     0x01      Burst abort(ZSL)\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_BurstAbortSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_BURST_ABORT, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CapEdgeQuantitySet\r
+ *  ucValue:\r
+     Max = 100\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CapEdgeQuantitySet(UINT8 ucValue)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CAP_EDGE_QUANTITY, ucValue);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_PvFixFrameRateSet\r
+ *  ucValue :\r
+     0x00      Disable Fix Frame Rate function\r
+     0x01~0xFF : Frame Rate\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_PvFixFrameRateSet(UINT8 ucValue)\r
+{\r
+       I2CDataWrite(SP7K_MSG_PV_FIX_FRAME_RATE, ucValue);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_PvMaxExposureTimeSet\r
+ *  ucValue : 1/N\r
+     N=0 : Disable Max. Exposure Time function\r
+     N=0x01~0xFF : Max. Exposure time\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_PvMaxExposureTimeSet(UINT8 ucValue)\r
+{\r
+       I2CDataWrite(SP7K_MSG_PV_MAX_EXPTIME, ucValue);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_HdrPositiveEvSet\r
+ *  ucValue: 2.4bits\r
+     eg. +1.5EV : 0x15\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_HdrPositiveEvSet(UINT8 ucValue)\r
+{\r
+       I2CDataWrite(SP7K_MSG_HDR_POSITIVE_EV, ucValue);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_HdrNegativeEvSet\r
+ *  ucValue: 2.4bits\r
+     eg. -0.4EV : 0x04\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_HdrNegativeEvSet(UINT8 ucValue)\r
+{\r
+       I2CDataWrite(SP7K_MSG_HDR_NEGATIVE_EV, ucValue);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_PvMinISOSet\r
+ *  ucParam:\r
+     0x00      Disable\r
+     0x01      ISO 50\r
+     0x02      ISO 100\r
+     0x03      ISO 200\r
+     0x04      ISO 400\r
+     0x05      ISO 800\r
+     0x06      ISO 1600\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_PvMinISOSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_PV_MIN_ISO, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_GSensorInfoSet\r
+ *  ucX: G sensor information X axis\r
+     ucY: G sensor information Y axis\r
+     ucZ: G sensor information Z axis\r
+     Value: ((-32.768~32.767)*1000)>>8\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_GSensorInfoSet(SINT8 ucX, SINT8 ucY, SINT8 ucZ)\r
+{\r
+       I2CDataWrite(SP7K_MSG_G_SENSOR_INFO_X, ucX);\r
+       I2CDataWrite(SP7K_MSG_G_SENSOR_INFO_Y, ucY);\r
+       I2CDataWrite(SP7K_MSG_G_SENSOR_INFO_Z, ucZ);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_GyroInfoSet\r
+ *  ucX: Gyro information X axis\r
+     ucY: Gyro information Y axis\r
+     ucZ: Gyro information Z axis\r
+     Value: ((Radian : 0~2£k)*1000)>>8\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_GyroInfoSet(UINT8 ucX, UINT8 ucY, UINT8 ucZ)\r
+{\r
+       I2CDataWrite(SP7K_MSG_GYRO_INFO_X, ucX);\r
+       I2CDataWrite(SP7K_MSG_GYRO_INFO_Y, ucY);\r
+       I2CDataWrite(SP7K_MSG_GYRO_INFO_Z, ucZ);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AFROISet\r
+ *  usSize: AF ROI size\r
+     usX: AF ROI x\r
+     usY: AF ROI y\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_AFROISet(UINT16 usSize, UINT16 usX, UINT16 usY)\r
+{\r
+       I2CDataWrite(SP7K_MSG_AF_ROI_SIZE_H, (usSize>>8)&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_AF_ROI_SIZE_L, usSize&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_AF_ROI_X_H, (usX>>8)&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_AF_ROI_X_L, usX&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_AF_ROI_Y_H, (usY>>8)&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_AF_ROI_Y_L, usY&0x00FF);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AFROITriggerSet\r
+ *  Input : None\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_AFROITriggerSet(void)\r
+{\r
+       I2CDataWrite(SP7K_MSG_AF_ROI_TRIGGER, 0x01);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AEROISet\r
+ *  usSize: AE ROI size\r
+     usX: AE ROI x\r
+     usY: AE ROI y\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_AEROISet(UINT16 usSize, UINT16 usX, UINT16 usY)\r
+{\r
+       I2CDataWrite(SP7K_MSG_AE_ROI_SIZE_H, (usSize>>8)&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_AE_ROI_SIZE_L, usSize&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_AE_ROI_X_H, (usX>>8)&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_AE_ROI_X_L, usX&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_AE_ROI_Y_H, (usY>>8)&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_AE_ROI_Y_L, usY&0x00FF);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AEROITriggerSet\r
+ *  ucParam:\r
+     0x00      TAE off\r
+     0x01      TAE on (Use TAE ROI : 0x48~0x4D)\r
+     0x02      TAE on (Use TAF ROI : 0x40~0x45)\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_AEROITriggerSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_AE_ROI_TRIGGER, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AFAbortSet\r
+ *  ucParam:\r
+     0x00      AF abort and go to infinity\r
+     0x01      AF abort and stop in the current position\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_AFAbortSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_AF_ABORT, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_VcmStepSet\r
+ *  usValue : VCM step value (0~1023)\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_VcmStepSet(UINT16 usValue)\r
+{\r
+       I2CDataWrite(SP7K_MSG_VCM_STEP_L, usValue&0x00FF);\r
+       I2CDataWrite(SP7K_MSG_VCM_STEP_H, (usValue>>8)&0x00FF);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CapEdgeInfoSet\r
+ *  ucParam:\r
+     0x00      None\r
+     0x01      Ask for capture edge\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CapEdgeInfoSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CAP_EDGE_INFO, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_RawPathSet\r
+ *  ucParam:\r
+     0x00      After Front\r
+     0x01      After WB\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_RawPathSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_RAW_PATH, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_RawFormatSet\r
+ *  ucParam:\r
+     0x00      RAW8\r
+     0x01      RAW10\r
+     0x02      RAW12\r
+     0x03      YUV8\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_RawFormatSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_RAW_FORMAT, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationRawLinearSet\r
+ *  ucParam:\r
+     0x00      Off\r
+     0x01      On\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationRawLinearSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_RAW_LINEAR, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationRawObSet\r
+ *  ucParam:\r
+     0x00      Off\r
+     0x01      On\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationRawObSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_RAW_OB, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationRawBpSet\r
+ *  ucParam:\r
+     0x00      Off\r
+     0x01      On\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationRawBpSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_RAW_BP, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationRawLscSet\r
+ *  ucParam:\r
+     0x00      Off\r
+     0x01      On\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationRawLscSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_RAW_LSC, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationRawCaSet\r
+ *  ucParam:\r
+     0x00      Off\r
+     0x01      On\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationRawCaSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_RAW_CA, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationRawArdSet\r
+ *  ucParam:\r
+     0x00      Off\r
+     0x01      On\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationRawArdSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_RAW_ARD, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationRawDepeakSet\r
+ *  ucParam:\r
+     0x00      Off\r
+     0x01      On\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationRawDepeakSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_RAW_DEPEAK, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationRawWbSet\r
+ *  ucParam:\r
+     0x00      Off\r
+     0x01      On\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationRawWbSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_RAW_WB, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : EXISP_I2C_CalibrationAwbCriteriaSet\r
+ *  ucVaule: 1~100, default 10%\r
+ *  return none\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationAwbCriteriaSet(UINT8 ucVaule)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_AWB_CRITERIA, ucVaule);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AEAWBThreadModeSet\r
+ *  ucParam:\r
+     0x00      AE/AWB thread off\r
+     0x01      AE/AWB thread on\r
+     0x02      AWB thread off\r
+     0x03      AWB thread on\r
+     0x04      AE thread off\r
+     0x05      AE thread on\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_AEAWBThreadModeSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_AEAWBTHREAD_MODE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_DqModeSet\r
+ *  ucParam:\r
+     0x00      Pause on\r
+     0x01      Pause off\r
+     0x02      Interpolation Off\r
+     0x03      Interpolation On\r
+     0x04      Fix Color Temperature On\r
+     0x05      Fix Color Temperature Off\r
+     0x06      Fix ISO On(Reserved)\r
+     0x07      Fix ISO Off(Reserved)\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_DqModeSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_DQ_MODE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CdspOnOffModeSet\r
+ *  ucParam:\r
+     0x00      CDSP all block off\r
+     0x01      CDSP all block recovery\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CdspOnOffModeSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CDSP_MODE, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationCmd1Set\r
+ *  ucParam:\r
+     bit 0 : Reserved\r
+     bit 1 : OB calibration(Reserved)\r
+     bit 2 : WB calibration\r
+     bit 3 : AF calibration(Reserved)\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationCmd1Set(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_CMD1, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationCmd2Set\r
+ *  ucParam:\r
+     bit 0 : LSC_D50 calibration\r
+     bit 1 : LSC_A calibration\r
+     bit 2 : LSC_CW calibration\r
+     bit 3 : LSC_TL84 calibration\r
+     bit 4 : LSC_D65 calibration\r
+     bit 5 : LSC_H calibration\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationCmd2Set(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_CMD2, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationInitCmdSet\r
+ *  ucParam:\r
+     bit 0, 1: Calibration data target\r
+     0x01      HOST\r
+     0x02      EEPROM\r
+     0x03      SPI\r
+     bit 2, 3: Band selection\r
+     0x00      50Hz\r
+     0x04      60Hz\r
+     bit 4, 5: LSC compression method\r
+     0x00      Differential\r
+     0x10      Non-compression\r
+     bit 6, 7: LSC table number\r
+     0x00      4 table\r
+     0x40      5 table\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationInitCmdSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_INIT_CMD, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationLscMaxGainSet\r
+ *  ucVaule : 6.2bits\r
+     Range : 0x00~0xFF\r
+     0x01      0.25%\r
+     0x02      0.50%\r
+     0x03      0.75%\r
+     0xFF      63.75%\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationLscMaxGainSet(UINT8 ucVaule)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_LENS_MAX_LUM_DECAY, ucVaule);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationDqIndexFixSet\r
+ *  ucParam:\r
+     bit 0~3: Color Temperature Index\r
+     0x00      LSC off\r
+     0x01      SPI flash is 1MB to load golden LSC & LSC_DQ table, auto\r
+     0x02      SPI flash is 1MB to load golden LSC & LSC_DQ table, fix A light table\r
+     0x03      SPI flash is 1MB to load golden LSC & LSC_DQ table, fix TL84 table\r
+     0x04      SPI flash is 1MB to load golden LSC & LSC_DQ table, fix CW table\r
+     0x05      SPI flash is 1MB to load golden LSC & LSC_DQ table, fix D50 table\r
+     0x06      SPI flash is 1MB to load golden LSC & LSC_DQ table, fix D65 table\r
+     0x07      SPI flash is 1MB to load golden LSC & LSC_DQ table, fix H table\r
+     bit 4~7: ISO index(0~5) (Reserved)\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CalibrationDqIndexFixSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_DQ_INDEX_FIX, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CaliUtilizationOptionSet\r
+ *  ucParam:\r
+     bit 0: Rear Camera(3ACALI)\r
+     0 : Use Calubration data(default)\r
+     1 : Use Golden data\r
+     bit 1: Rear Camera(LSC)\r
+     0 : Use Calubration data(default)\r
+     1 : Use Golden data\r
+     bit 2: Front Camera(3ACALI)\r
+     0 : Use Calubration data(default)\r
+     1 : Use Golden data\r
+     bit 3: Front Camera(LSC)\r
+     0 : Use Calubration data(default)\r
+     1 : Use Golden data\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_CaliUtilizationOptionSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_CALIBRATION_UTILIZATION_OPTION, ucParam);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_ROISwitchSet\r
+ *  ucParam:\r
+     0x00      ROI off\r
+     0x01      ROI on\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_ROISwitchSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_ROI_SWITCH, ucParam);\r
+}\r
+\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_VendreqIdSet\r
+ *  ucValue: vendor command ID\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_VendreqIdSet(UINT8 ucValue)\r
+{\r
+       I2CDataWrite(SP7K_MSG_VENDREQ_ID, ucValue);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_VendreqParamSet\r
+ *  ucValue: vendor command parameter\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_VendreqParamSet(UINT8 ucValue)\r
+{\r
+       I2CDataWrite(SP7K_MSG_VENDREQ_PARAM, ucValue);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_VendreqValuesSet_L\r
+ *  ucVaule: vendor command the low byte of value\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_VendreqValuesSet_L(UINT8 ucVaule)\r
+{\r
+       I2CDataWrite(SP7K_MSG_VENDREQ_VALUES_L, ucVaule);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_VendreqProcessSet\r
+ *  Input : None\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_VendreqProcessSet(void)\r
+{\r
+       I2CDataWrite(SP7K_MSG_VENDREQ_PROCESS, 0x00);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_VendreqValuesSet_H\r
+ *  ucVaule: vendor command the high byte of value\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_VendreqValuesSet_H(UINT8 ucVaule)\r
+{\r
+       I2CDataWrite(SP7K_MSG_VENDREQ_VALUES_H, ucVaule);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_VendreqCmdSet\r
+ *  ucParam:\r
+     0x00      Reserved\r
+     0x01      Reserved\r
+     0x02      Reserved\r
+     0x03      AE lock\r
+     0x04      AWB lock\r
+     0x05      AE unlock\r
+     0x06      AWB unlock\r
+ *  Return : None\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_I2C_VendreqCmdSet(UINT8 ucParam)\r
+{\r
+       I2CDataWrite(SP7K_MSG_VENDREQ_CMD, ucParam);\r
+}\r
+\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AFStatusGet\r
+ *  Input : None\r
+ *  Return : AF status\r
+     0x00      Idle\r
+     0x01      Busy\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_AFStatusGet(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_AF_STATUS);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AFResultGet\r
+ *  Input : None\r
+ *  Return : AF result\r
+     0x00      Focus success\r
+     0x01      Focus fail\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_AFResultGet(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_AF_RESULT);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_AFConsumeTimeGet\r
+ *  Input : None\r
+ *  Return : AF consuming time (ms)\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_AFConsumeTimeGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_AF_CONSUME_TIME_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_AF_CONSUME_TIME_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_VcmCurrentPosGet\r
+ *  Input : None\r
+ *  Return : VCM current position (Range 0~1023)\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_VcmCurrentPosGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_VCM_CURRENT_POS_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_VCM_CURRENT_POS_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_ExposureTimeNumeratorGet\r
+ *  Input : None\r
+ *  Return : exposure time numerator\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_ExposureTimeNumeratorGet(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_EXPTIME_NUMERATOR);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_ExposureTimeDenominatorGet\r
+ *  Input : None\r
+ *  Return : exposure time denominator\r
+ *------------------------------------------------------------------------*/\r
+UINT32 EXISP_I2C_ExposureTimeDenominatorGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_EXPTIME_DENOMINATOR_H)<<16) |\r
+                       (I2CDataRead(SP7K_RDREG_EXPTIME_DENOMINATOR_M)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_EXPTIME_DENOMINATOR_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_ExposureTimeCompensationGet\r
+ *  Input : None\r
+ *  Return : exposure time compensation\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_ExposureTimeCompensationGet(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_EXPTIME_COMPENSATION);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_LensFocalLengthGet\r
+ *  Input : None\r
+ *  Return : lens focal length\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_LensFocalLengthGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_LENS_FOCAL_LENGTH_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_LENS_FOCAL_LENGTH_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_ISOValueGet\r
+ *  Input : None\r
+ *  Return : ISO value\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_ISOValueGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_ISO_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_ISO_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_FlashModeGet\r
+ *  Input : None\r
+ *  Return : flash mode\r
+     0x00      Flash off\r
+     0x01      Flash on\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_FlashModeGet(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_FLASH_MODE);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CapEdgeInfoGet\r
+ *  Input : None\r
+ *  Return : capture edge information\r
+ *------------------------------------------------------------------------*/\r
+UINT32 EXISP_I2C_CapEdgeInfoGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_CAP_EDGE_INFO_B3)<<24) |\r
+                       (I2CDataRead(SP7K_RDREG_CAP_EDGE_INFO_B2)<<16) |\r
+                       (I2CDataRead(SP7K_RDREG_CAP_EDGE_INFO_B1)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_CAP_EDGE_INFO_B0));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_3AStatusGet\r
+ *  Input : None\r
+ *  Return : 3A status\r
+     bit 0: AE ready bit\r
+     0 : AE not ready\r
+     1 : AE ready\r
+     bit 1: AWB ready bit\r
+     0 : AWB not ready\r
+     1 : AWB ready\r
+     bit 2: flash info\r
+     0 : Do not flash fire\r
+     1 : Do flash fire\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_3AStatusGet(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_3A_STATUS);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_EdgeInfoCountGet\r
+ *  Input : None\r
+ *  Return : edge information count\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_EdgeInfoCountGet(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_EDGE_INFO_COUNT);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_RearSensorIdGet\r
+ *  Input : None\r
+ *  Return : rear sensor id\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_RearSensorIdGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_REAR_SENSORID_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_REAR_SENSORID_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_FrontSensorIdGet\r
+ *  Input : None\r
+ *  Return : front sensor id\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_FrontSensorIdGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_FRONT_SENSORID_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_FRONT_SENSORID_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_FWVersionGet\r
+ *  Input : None\r
+ *  Return : FW version\r
+ *------------------------------------------------------------------------*/\r
+UINT32 EXISP_I2C_FWVersionGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_FW_VER_H)<<16) |\r
+                       (I2CDataRead(SP7K_RDREG_FW_VER_M)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_FW_VER_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_VendorIdGet\r
+ *  Input : None\r
+ *  Return : vendor ID (0x7002)\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_VendorIdGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_VENDOR_ID_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_VENDOR_ID_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationLscMaxRGainGet\r
+ *  Input : None\r
+ *  Return : the max R gain after LSC calibration\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_CalibrationLscMaxRGainGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_CALIBRATION_LSC_MAX_RGAIN_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_CALIBRATION_LSC_MAX_RGAIN_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationLscMaxGGainGet\r
+ *  Input : None\r
+ *  Return : the max G gain after LSC calibration\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_CalibrationLscMaxGGainGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_CALIBRATION_LSC_MAX_GGAIN_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_CALIBRATION_LSC_MAX_GGAIN_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationLscMaxBGainGet\r
+ *  Input : None\r
+ *  Return : the max B gain after LSC calibration\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_CalibrationLscMaxBGainGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_CALIBRATION_LSC_MAX_BGAIN_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_CALIBRATION_LSC_MAX_BGAIN_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationAWBRGainGet\r
+ *  Input : None\r
+ *  Return : the R gain after AWB calibration\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_CalibrationAWBRGainGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_CALIBRATION_AWB_RGain_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_CALIBRATION_AWB_RGain_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationAWBGGainGet\r
+ *  Input : None\r
+ *  Return : the G gain after AWB calibration\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_CalibrationAWBGGainGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_CALIBRATION_AWB_GGain_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_CALIBRATION_AWB_GGain_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationAWBBGainGet\r
+ *  Input : None\r
+ *  Return : the B gain after AWB calibration\r
+ *------------------------------------------------------------------------*/\r
+UINT16 EXISP_I2C_CalibrationAWBBGainGet(void)\r
+{\r
+       return ((I2CDataRead(SP7K_RDREG_CALIBRATION_AWB_BGain_H)<<8) |\r
+                        I2CDataRead(SP7K_RDREG_CALIBRATION_AWB_BGain_L));\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationExecStatus1Get\r
+ *  Input : None\r
+ *  Return : OB/WB/AF calibration execution status\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_CalibrationExecStatus1Get(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_CALIBRATION_EXEC_STATUS1);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationExecStatus2Get\r
+ *  Input : None\r
+ *  Return : LSC_D50/LSC_A/LSC_CW/LSC_TL84/LSC_D65/LSC_H calibration execution status\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_CalibrationExecStatus2Get(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_CALIBRATION_EXEC_STATUS2);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationErrorStatus1Get\r
+ *  Input : None\r
+ *  Return : OB/WB/AF calibration error status\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_CalibrationErrorStatus1Get(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_CALIBRATION_ERROR_STATUS1);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationErrorStatus2Get\r
+ *  Input : None\r
+ *  Return : LSC_D50/LSC_A/LSC_CW/LSC_TL84/LSC_D65/LSC_H calibration error status\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_CalibrationErrorStatus2Get(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_CALIBRATION_ERROR_STATUS2);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationErrorCodeGet\r
+ *  Input : None\r
+ *  Return : calibration error code\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_CalibrationErrorCodeGet(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_CALIBRATION_ERROR_CODE);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_I2C_CalibrationLoadTableStatusGet\r
+ *  Input : None\r
+ *  Return : load table status\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_I2C_CalibrationLoadTableStatusGet(void)\r
+{\r
+       return I2CDataRead(SP7K_RDREG_CALIBRATION_LOAD_TABLE_STATUS);\r
+}\r
+\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_SuspendGpioCfgSet\r
+ *  Description : Suspend GPIO configuration\r
+ *  ucCtl:\r
+     0x00      GPIO_CTL_LOW(GPIO pull low)\r
+     0x01      GPIO_CTL_HIGH(GPIO pull high)\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_SuspendGpioCfgSet(UINT8 ucCtl)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       if (ucCtl >= GPIO_CTL_MAX) {\r
+               ucRet = FAIL;\r
+               return ucRet;\r
+       }\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_DigitalPowerCfgSet\r
+ *  Description : Provide digital power to external ISP\r
+     On:\r
+     0x00      Close\r
+     0x01      Open\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_DigitalPowerCfgSet(UINT8 On)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_AnalogPowerCfgSet\r
+ *  Description : Provide analog power to external ISP\r
+     On:\r
+     0x00      Close\r
+     0x01      Open\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_AnalogPowerCfgSet(UINT8 On)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_ClockCfgSet\r
+ *  Description : Provide clock or not to external ISP\r
+     ucEnable:\r
+     0x00      Don't provide clock\r
+     0x01      Provide clock\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_ClockCfgSet(UINT8 ucEnable)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_ResetGpioCfgSet\r
+ *  Description : Reset GPIO configuration\r
+ *  ucCtl:\r
+     0x00      GPIO_CTL_LOW(GPIO pull low)\r
+     0x01      GPIO_CTL_HIGH(GPIO pull high)\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_ResetGpioCfgSet(UINT8 ucCtl)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       if (ucCtl >= GPIO_CTL_MAX) {\r
+               ucRet = FAIL;\r
+               return ucRet;\r
+       }\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_PowerOn\r
+ *  Description : Power on external ISP\r
+ *  ucBoot:\r
+     0x00      BOOT_FROM_SPI(Boot from SPI)\r
+     0x01      BOOT_FROM_HOST(Boot from host)\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_PowerOn(UINT8 ucBoot)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       /* 1. Open digital power, 1.2V */\r
+       ucRet = EXISP_DigitalPowerCfgSet(0x01);\r        /* 2. Open analog power, 1.8V and 2.8V */\r
+       ucRet = EXISP_AnalogPowerCfgSet(0x01);\r
+       /* 3. Open clock */\r
+       ucRet = EXISP_ClockCfgSet(0x01);\r
+       /* 4. Suspend GPIO configuration */\r
+       if (ucBoot == BOOT_FROM_SPI) {\r
+               ucRet = EXISP_SuspendGpioCfgSet(GPIO_CTL_HIGH);\r
+       }\r
+       else if (ucBoot == BOOT_FROM_HOST) {\r
+               ucRet = EXISP_SuspendGpioCfgSet(GPIO_CTL_LOW);\r
+       }\r
+       else {\r
+               ucRet = FAIL;\r
+               return ucRet;\r
+       }\r
+       /* 5. Reset GPIO configuration */\r
+       ucRet = EXISP_ResetGpioCfgSet(GPIO_CTL_LOW);\r
+       /* Delay 10ms */\r
+       tmrUsDelay(10000);\r
+       /* 6. Reset GPIO configuration */\r
+       ucRet = EXISP_ResetGpioCfgSet(GPIO_CTL_HIGH);\r
+       /* Delay 16ms */\r
+       tmrUsDelay(16000);\r
+       /* 7. Suspend GPIO configuration for boot from SPI */\r
+       if (ucBoot == BOOT_FROM_SPI) {\r
+               ucRet = EXISP_SuspendGpioCfgSet(GPIO_CTL_LOW);\r
+       }\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_PowerOff\r
+ *  Description : Power off external ISP\r
+ *  Input : None\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_PowerOff(void)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       /* 1. Reset GPIO configuration */\r
+       ucRet = EXISP_ResetGpioCfgSet(GPIO_CTL_LOW);\r
+       /* 2. Close clock */\r
+       ucRet = EXISP_ClockCfgSet(0x00);\r
+       /* 3. Close analog power, 2.8V and 1.8V */\r
+       ucRet = EXISP_AnalogPowerCfgSet(0x00);\r
+       /* 4. Close digital power, 1.2V */\r
+       ucRet = EXISP_DigitalPowerCfgSet(0x00);\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_LoadCodeStart\r
+ *  Description : Load code start\r
+ *  ucBoot:\r
+     0x00      BOOT_FROM_SPI(Boot from SPI)\r
+     0x01      BOOT_FROM_HOST(Boot from host)\r
+     ucFwIdx: Set which FW will be loaded\r
+     is_calibration: calibration flag, calibration:1 normal:0\r
+     *pIspFw: external ISP FW pointer\r
+     *pCalibOpt: read from calibration_option.BIN\r
+     *p3acali: read from 3ACALI.BIN or 3ACALI_F.BIN\r
+     *pLsc: read from LSC.BIN or LSC_F.BIN\r
+     *pLscdq: read from LSC_DQ.BIN or LSC_DQ_F.BIN\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_LoadCodeStart(\r
+       UINT8 ucBoot,\r
+       UINT8 ucFwIdx,\r
+       UINT8 is_calibration,\r
+       UINT8 *pIspFw,\r
+       UINT8 *pCalibOpt,\r
+       UINT8 *p3acali,\r
+       UINT8 *pLsc,\r
+       UINT8 *pLscdq)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       if (ucBoot >= BOOT_FROM_MAX || ucFwIdx > 2) {\r
+               ucRet = FAIL;\r          return ucRet;\r
+       }\r
+\r
+       DEBUG_TRACE("@@@ISP FW: Load Code Start\n");\r
+       if (ucBoot == BOOT_FROM_SPI) {\r
+               I2CDataWrite(0x1011, 1); /* CPU reset */\r
+               /* Reset flash module */\r
+               I2CDataWrite(0x001C, 0x08); /* reset FM */\r
+               I2CDataWrite(0x001C, 0x00);\r
+               I2CDataWrite(0x1010, 0x02);\r
+               I2CDataWrite(0x1010, 0x00);\r
+\r
+               I2CDataWrite(0x1306, ucFwIdx); /* Set which FW will be loaded */\r
+               I2CDataWrite(0x1011, 0);\r
+       }\r
+       else if (ucBoot == BOOT_FROM_HOST) {\r
+               ucRet = EXISP_LoadCode(ucFwIdx, is_calibration, pIspFw, pCalibOpt, p3acali, pLsc, pLscdq);\r
+               I2CDataWrite(0x1306, ucFwIdx); /* Set which FW to be loaded */\r
+       }\r
+       DEBUG_TRACE("@@@ISP FW: Load Code End, sts=%d\n", ucRet);\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_LoadCode\r
+ *  Description : Load code from host, support boot from host only\r
+ *  ucFwIdx: Set which FW will be loaded\r
+     is_calibration: calibration flag, calibration:1 normal:0\r
+     *pIspFw: external ISP FW pointer\r
+     *pCaliOpt: read from calibration_option.BIN\r
+     *p3acali: read from 3ACALI.BIN or 3ACALI_F.BIN\r
+     *pLsc: read from LSC.BIN or LSC_F.BIN\r
+     *pLscdq: read from LSC_DQ.BIN or LSC_DQ_F.BIN\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_LoadCode(\r
+       UINT8 ucFwIdx,\r
+       UINT8 is_calibration,\r
+       UINT8 *pIspFw,\r
+       UINT8 *pCalibOpt,\r
+       UINT8 *p3acali,\r
+       UINT8 *pLsc,\r
+       UINT8 *pLscdq)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+       UINT32 t1=0, t2=0, t3=0, tmrCnt=0, i=0;\r
+       UINT32 checksumWrite=0, checksumRead=0;\r
+       ispFwHeaderInfo_t *pFwInfo;\r
+       ispLoadCodeRet_t loadCodeRet;\r
+\r
+       if (pIspFw == NULL) {\r
+               return LOADCODE_BOOT_FILE_ERR;\r
+       }\r
+\r
+       pFwInfo = (ispFwHeaderInfo_t *)pIspFw;\r
+       for (i = 0; i < ucFwIdx; i++) {\r
+               pIspFw += FW_HEADER_SIZE+pFwInfo->DmemFicdmemSize+pFwInfo->ImemSize;\r
+               pFwInfo = (ispFwHeaderInfo_t *)pIspFw;\r
+       }\r
+\r
+       /* Modify length to 16-alignment */\r
+       pFwInfo->DmemFicdmemSize = (pFwInfo->DmemFicdmemSize+15)&0xFFFFFFF0;\r
+       pFwInfo->ImemSize = (pFwInfo->ImemSize+15)&0xFFFFFFF0;\r
+       //DEBUG_TRACE(" %s, %d, DmemFicdmemSize=%d\n", __FUNCTION__, __LINE__, pFwInfo->DmemFicdmemSize);\r
+       //DEBUG_TRACE(" %s, %d, ImemSize=%d\n", __FUNCTION__, __LINE__, pFwInfo->ImemSize);\r
+       //DEBUG_TRACE("0.pIspFw =%x\n", pIspFw);\r
+       DEBUG_TRACE("@@@ISP FW: Get BOOT.BIN Bin File End\n");\r
+\r
+#if 1 //update golden or calibration resource\r
+       DEBUG_TRACE("@@@ISP FW: Update Resource Start\n");\r
+       if (is_calibration == 1) { //calibration\r
+               //Nothing to do\r
+       }\r
+       else { //normal\r
+               memset(&loadCodeRet, 0, sizeof(ispLoadCodeRet_t));\r
+\r
+               /* pCalibOpt check */\r
+               if (pCalibOpt == NULL) {\r
+                       loadCodeRet.retCalibOpt= LOADCODE_CALIB_OPT_FILE_ERR;\r
+                       goto _EXIT_;\r
+               }\r
+               /* p3acali check */\r
+               if (p3acali == NULL) {\r
+                       loadCodeRet.ret3acli= LOADCODE_3ACALI_FILE_ERR;\r
+               }\r
+               /* pLsc check */\r
+               if (pLsc == NULL) {\r
+                       loadCodeRet.retLsc= LOADCODE_LSC_FILE_ERR;\r
+               }\r
+               /* pLscdq check */\r
+               if (pLscdq == NULL) {\r
+                       loadCodeRet.retLscdq = LOADCODE_LSC_DQ_FILE_ERR;\r
+               }\r
+\r
+               EXISP_UpdateCalibResStart(ucFwIdx, pIspFw, pFwInfo, &loadCodeRet, *pCalibOpt, p3acali, pLsc, pLscdq);\r
+       }\r
+       DEBUG_TRACE("@@@ISP FW: Update Resource End\n");\r
+#endif\r
+\r
+_EXIT_:\r
+       if (is_calibration == 1) { //calibration\r
+               DEBUG_TRACE("********** Load Golden Res **********\n");\r
+       }\r
+       else { //normal\r
+               if (loadCodeRet.retCalibOpt == SUCCESS &&\r
+                       loadCodeRet.ret3acli == SUCCESS &&\r
+                       loadCodeRet.retLsc == SUCCESS &&\r
+                       loadCodeRet.retLscdq == SUCCESS) {\r
+                       DEBUG_TRACE("********** Load Calibration Res **********\n");\r
+               }\r
+               else {\r
+                       if (loadCodeRet.retCalibOpt != SUCCESS) {\r
+                               DEBUG_TRACE("********** Load Golden Res, retCalibOpt=%d **********\n", loadCodeRet.retCalibOpt);\r
+                       }\r
+                       else if (loadCodeRet.ret3acli != SUCCESS) {\r
+                               DEBUG_TRACE("********** Load Golden 3ACALI Res, ret3acli=%d **********\n", loadCodeRet.ret3acli);\r
+                       }\r
+                       else if (loadCodeRet.retLsc != SUCCESS || loadCodeRet.retLscdq == SUCCESS) {\r
+                               DEBUG_TRACE("********** Load Golden LSC Res, retLsc=%d, retLscdq=%d **********\n", loadCodeRet.retLsc, loadCodeRet.retLscdq);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /* CPU reset */\r
+       I2CDataWrite(0x1011, 1);\r
+\r
+       /* Set imemmode*/\r
+       t1 = pFwInfo->ImemSize/8192;\r
+       t2 = t1-32;\r
+       t3 = 1;\r
+       if ((int)t2 < 0) {\r
+               t1 = t3 << t1;\r
+               --t1;\r
+       }\r
+       else {\r
+               t3 <<= t2;\r
+               t1 = -1U;\r
+       }\r
+       --t3;\r
+       I2CDataWrite(0x1070, t1);\r
+       I2CDataWrite(0x1071, t1>>8);\r
+       I2CDataWrite(0x1072, t1>>16);\r
+       I2CDataWrite(0x1073, t1>>24);\r
+       I2CDataWrite(0x1074, t3);\r
+\r
+       /* @@@ Start load code to SPCA7002 */\r
+\r
+       /* Enable checksum mechanism */\r
+       I2CDataWrite(0x4280, 1);\r
+\r
+       /* Wait Ready For Load Code interrupt */\r
+       while (!(I2CDataRead(SP7K_RDREG_INT_STS_REG_0)&0x02)) {\r
+               tmrCnt++;\r
+               if (tmrCnt >= 10) {\r
+                       DEBUG_TRACE("@@@ISP FW: polling RFLC bit timeout\n");\r
+                       ucRet = FAIL;\r                  return ucRet;\r
+               }\r
+               tmrUsDelay(10000);\r
+       }\r
+       I2CDataWrite(SP7K_RDREG_INT_STS_REG_0, 0x02);\r
+\r
+       /* Load DMEM/FICDMEM bin file Start */\r
+       DEBUG_TRACE("@@@ISP FW: Load DMEM/FICDMEM Bin File Start\n");\r
+       pIspFw += FW_HEADER_SIZE;\r
+       /* Reset checksum value */\r
+       I2CDataWrite(0x4284, 0x00);\r
+       checksumWrite = 0;\r
+       for (i = 0; i < pFwInfo->DmemFicdmemSize; i++) {\r
+               checksumWrite += pIspFw[i];\r
+       }\r
+       checksumWrite &= 0xFF;\r
+\r
+       /* Transmit DMEM/FICDMEM data */\r
+       if(pFwInfo->DmemFicdmemSize <= 6*1024) { /* Data size <6K, load all bin file */\r
+               ucRet = EXISP_SPIDataWrite(0/*SPI mode0*/, pIspFw, pFwInfo->DmemFicdmemSize, 0x0800);\r
+               I2CDataWrite(0x1011, 0); /* Set CPU to normal operation */\r
+       }\r
+       else {\r
+               ucRet = EXISP_SPIDataWrite(0/*SPI mode0*/, pIspFw, 6*1024, 0x0800);\r
+               I2CDataWrite(0x1011, 0); /* Set CPU to normal operation */\r
+               ucRet = EXISP_SPIDataWrite(0/*SPI mode0*/, pIspFw+(6*1024), pFwInfo->DmemFicdmemSize-(6*1024), 0x0800+(6*1024));\r
+       }\r
+\r
+       /* Checksum value check */\r
+       checksumRead = I2CDataRead(0x4284);\r
+       if (checksumWrite == checksumRead) {\r
+               DEBUG_TRACE("@@@ISP FW: Checksum DMEM/FICDMEM test: OK, %x, %x\n", checksumRead, checksumWrite);\r
+       }\r
+       else {\r
+               DEBUG_TRACE("@@@ISP FW: Checksum DMEM/FICDMEM test: FAIL, %x, %x\n", checksumRead, checksumWrite);\r
+               ucRet = FAIL;\r          return ucRet;\r
+       }\r
+       DEBUG_TRACE("@@@ISP FW: Load DMEM/FICDMEM Bin File End\n");\r
+       /* Load DMEM/FICDMEM bin file End */\r
+\r
+       /* Load IMEM bin file Start */\r
+       DEBUG_TRACE("@@@ISP FW: Load IMEM Bin File Start\n");\r
+       pIspFw += pFwInfo->DmemFicdmemSize;\r
+       /* Reset checksum value */\r
+       I2CDataWrite(0x4284, 0x00);\r
+       checksumWrite = 0;\r
+       for (i = 0; i < pFwInfo->ImemSize; i++) {\r
+               checksumWrite += pIspFw[i];\r
+       }\r
+       checksumWrite &= 0xFF;\r
+\r
+       /* Transmit IMEM data */\r
+       ucRet = EXISP_SPIDataWrite(0/*SPI mode0*/, pIspFw, pFwInfo->ImemSize, (320*1024)-pFwInfo->ImemSize);\r
+\r
+       /* Checksum value check */\r
+       checksumRead = I2CDataRead(0x4284);\r
+       if (checksumWrite == checksumRead) {\r
+               DEBUG_TRACE("@@@ISP FW: Checksum IMEM test: OK, %x, %x\n", checksumRead, checksumWrite);\r
+       }\r
+       else {\r
+               DEBUG_TRACE("@@@ISP FW: Checksum IMEM test: FAIL, %x, %x\n", checksumRead, checksumWrite);\r
+               ucRet = FAIL;\r          return ucRet;\r
+       }\r
+       DEBUG_TRACE("@@@ISP FW: Load IMEM Bin File End\n");\r
+       /* Load IMEM bin file End */\r
+\r
+       /* @@@ End load code to SPCA7002 */\r
+\r
+       /* Disable checksum mechanism */\r
+       I2CDataWrite(0x4280, 0);\r
+\r
+       /* Write load code end register */\r
+       I2CDataWrite(0x1307, 0xA5);\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_UpdateCalibResStart\r
+ *  Description : Update calibration data start\r
+ *  ucFwIdx: Set which FW will be loaded\r
+     *pIspFw: external ISP FW pointer\r
+     *pFwInfo: external ISP FW header information\r
+     *pLoadCodeRet: load code status result\r
+     ucCaliOpt: read from calibration_option.BIN\r
+     *p3acali: read from 3ACALI.BIN or 3ACALI_F.BIN\r
+     *pLsc: read from LSC.BIN or LSC_F.BIN\r
+     *pLscdq: read from LSC_DQ.BIN or LSC_DQ_F.BIN\r
+ *  Return : none\r
+ *------------------------------------------------------------------------*/\r
+void EXISP_UpdateCalibResStart(\r
+       UINT8 ucFwIdx,\r
+       UINT8 *pIspFw,\r
+       ispFwHeaderInfo_t *pFwInfo,\r
+       ispLoadCodeRet_t *pLoadCodeRet,\r
+       UINT8 ucCaliOpt,\r
+       UINT8 *p3acali,\r
+       UINT8 *pLsc,\r
+       UINT8 *pLscdq)\r
+{\r
+       //DEBUG_TRACE("1.pIspFw =%x\n", pIspFw);\r
+\r
+       if ((ucFwIdx == 0) && (ucCaliOpt != 0xFF)) { //rear sensor\r
+               ucCaliOpt = ucCaliOpt & 0x03;\r
+       }\r
+       else if ((ucFwIdx == 1) && (ucCaliOpt != 0xFF)){ //front sensor\r
+               ucCaliOpt = ucCaliOpt >> 2;\r
+       }\r
+\r
+       switch (ucCaliOpt) {\r
+       case 1: /* load golden 3ACALI.BIN and calibrated LSC.BIN & LSC_DQ.BIN */\r
+               if (pLsc == NULL || pLscdq == NULL) {\r
+                       pLoadCodeRet->retLsc = LOADCODE_LSC_FILE_ERR;\r
+                       pLoadCodeRet->retLscdq = LOADCODE_LSC_DQ_FILE_ERR;\r
+                       break;\r
+               }\r
+               pLoadCodeRet->retLsc = EXISP_UpdateCalibRes(1, pIspFw, pFwInfo, p3acali, pLsc, pLscdq);\r
+               pLoadCodeRet->retLscdq = pLoadCodeRet->retLsc;\r
+               break;\r
+       case 2: /* load calibrated 3ACALI.BIN and golden LSC.BIN & LSC_DQ.BIN */\r
+               if (p3acali == NULL) {\r
+                       pLoadCodeRet->ret3acli = LOADCODE_3ACALI_FILE_ERR;\r
+                       break;\r
+               }\r
+               pLoadCodeRet->ret3acli = EXISP_UpdateCalibRes(0, pIspFw, pFwInfo, p3acali, pLsc, pLscdq);\r
+               break;\r
+       case 3: /* load golden 3ACALI.BIN and golden LSC.BIN & LSC_DQ.BIN */\r
+               //Nothing to do\r
+               break;\r
+       default: /* load calibrated 3ACALI.BIN and calibrated LSC.BIN & LSC_DQ.BIN */\r
+               if (p3acali == NULL) {\r
+                       pLoadCodeRet->ret3acli = LOADCODE_3ACALI_FILE_ERR;\r
+               }\r
+               if (pLoadCodeRet->ret3acli == SUCCESS) {\r
+                               pLoadCodeRet->ret3acli = EXISP_UpdateCalibRes(0, pIspFw, pFwInfo, p3acali, pLsc, pLscdq);\r
+               }\r
+\r
+               if (pLoadCodeRet->ret3acli == LOADCODE_GET_RES_NUM_ERR) {\r
+                       break;\r
+               }\r
+               else if (pLsc == NULL || pLscdq == NULL) {\r
+                       pLoadCodeRet->retLsc = LOADCODE_LSC_FILE_ERR;\r
+                       pLoadCodeRet->retLscdq = LOADCODE_LSC_DQ_FILE_ERR;\r
+                       break;\r
+               }\r
+               pLoadCodeRet->retLsc = EXISP_UpdateCalibRes(1, pIspFw, pFwInfo, p3acali, pLsc, pLscdq);\r
+               pLoadCodeRet->retLscdq = pLoadCodeRet->retLsc;\r
+               break;\r
+       }\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_UpdateCalibRes\r
+ *  Description : Update calibration data from host, support boot from host only\r
+ *  idx: Set which resource will be loaded\r
+     *pIspFw: external ISP FW pointer\r
+     *pFwInfo: external ISP FW header information\r
+     *p3acali: read from 3ACALI.BIN or 3ACALI_F.BIN\r
+     *pLsc: read from LSC.BIN or LSC_F.BIN\r
+     *pLscdq: read from LSC_DQ.BIN or LSC_DQ_F.BIN\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_UpdateCalibRes(\r
+       UINT8 idx,\r
+       UINT8 *pIspFw,\r
+       ispFwHeaderInfo_t *pFwInfo,\r
+       UINT8 *p3acali,\r
+       UINT8 *pLsc,\r
+       UINT8 *pLscdq)\r
+{\r
+       UINT32 iqOffset = 0, resNumCnt = 0, iqSize = 0, caliSize = 0, tempSize = 0, i;\r
+       UINT32 start3acali = 0, startLsc = 0, startLscdq = 0, size3acali = 0, sizeLsc = 0, sizeLscdq = 0;\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       /* resource header and checksum check */\r
+       ucRet = EXISP_ResCheck(idx, p3acali, pLsc, pLscdq);\r
+       if (ucRet != SUCCESS) {\r
+               goto _EXIT_;\r
+       }\r
+\r
+       /* find out where IQ.BIN is */\r
+       pIspFw += FW_HEADER_SIZE + pFwInfo->DmemSize;\r
+       //DEBUG_TRACE("2.pIspFw =%x\n", pIspFw);\r
+       if (*(pIspFw+0x38) == 0x43 &&\r
+               *(pIspFw+0x39) == 0x41 &&\r
+               *(pIspFw+0x3A) == 0x4C &&\r
+               *(pIspFw+0x3B) == 0x49) {\r
+               iqOffset = ((*(pIspFw+0x51)<<8)&0x0000FF00) + (*(pIspFw+0x50)&0x000000FF);\r
+       }\r
+       else {\r
+               iqOffset = ((*(pIspFw+0x31)<<8)&0x0000FF00) + (*(pIspFw+0x30)&0x000000FF);\r
+       }\r
+       //DEBUG_TRACE("iqOffset=%x\n", iqOffset);\r
+\r
+       /* point to IQ.BIN start position */\r
+       pIspFw += iqOffset;\r
+       //DEBUG_TRACE("3.pIspFw =%x\n", pIspFw);\r
+\r
+       /* parsing out the file size to get the start position of calibration data,\r
+       FICDMEM file size should be 16 alignment */\r
+       ucRet = EXISP_ResNumGet(&resNumCnt, pIspFw+0x10);\r
+       if (ucRet != SUCCESS) {\r
+               goto _EXIT_;\r
+       }\r
+       //DEBUG_TRACE("resNumCnt=%d\n", resNumCnt);\r
+       //DEBUG_TRACE("5.pIspFw =%x\n", pIspFw);\r
+\r
+       for (i = 0; i < resNumCnt; i++) {\r
+               tempSize = *(pIspFw+14+(1+i)*0x10);\r
+               tempSize += ((*(pIspFw+15+((1+i)*0x10)))<<8);\r
+               //DEBUG_TRACE("tempSize=0x%02x\n", tempSize);\r
+               if ((tempSize%0x10) != 0) {\r
+                       tempSize = ((tempSize+0xF)>>4)<<4;\r
+               }\r
+               //DEBUG_TRACE("size of IQ BIN files %d: 0x%02x\n", i, tempSize);\r
+               iqSize += tempSize;\r
+       }\r
+       //DEBUG_TRACE("iqSize=%d\n", iqSize);\r
+       //DEBUG_TRACE("6.pIspFw =%x\n", pIspFw);\r
+\r
+       /* find out 3ACALI.BIN & LSC.BIN & LSC_DQ.BIN start position */\r
+       start3acali = iqSize+(1+resNumCnt+3)*0x10;\r
+       for (i = 0; i < 3; i++) {\r
+               tempSize = *(pIspFw+14+(1+resNumCnt+i)*0x10);\r
+               tempSize += ((*(pIspFw+15+(1+resNumCnt+i)*0x10))<<8);\r
+               if (i == 0) {\r
+                       size3acali = tempSize;\r
+               }\r
+               else if (i == 1){\r
+                       sizeLsc = tempSize;\r
+               }\r
+               else {\r
+                       sizeLscdq = tempSize;\r
+               }\r
+\r
+               if ((tempSize%0x10) != 0) {\r
+                       tempSize = ((tempSize+0xF)>>4)<<4;\r
+               }\r
+               //DEBUG_TRACE("0.size of IQ BIN files %d: 0x%02x\n", i, tempSize);\r
+               caliSize += tempSize;\r
+               if (i == 0) {\r
+                       startLsc = start3acali + caliSize;\r
+               }\r
+               else if (i == 1) {\r
+                       startLscdq = start3acali + caliSize;\r
+               }\r
+       }\r
+       //DEBUG_TRACE("start3acali=%x, size3acali=%d\n", start3acali, size3acali);\r
+       //DEBUG_TRACE("startLsc=%x, sizeLsc=%d\n", startLsc, sizeLsc);\r
+       //DEBUG_TRACE("startLscdq=%x, size=%d\n", startLscdq, sizeLscdq);\r
+\r
+       /* update calibration data into FW buffer */\r
+       if (idx == 0) {\r
+               memcpy(pIspFw+start3acali, p3acali, size3acali);\r
+       }\r
+       else if (idx == 1) {\r
+               memcpy(pIspFw+startLsc, pLsc, sizeLsc);\r
+               memcpy(pIspFw+startLscdq, pLscdq, sizeLscdq);\r
+       }\r
+\r
+_EXIT_:\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_ResCheck\r
+ *  Description : check resource header and checksum\r
+ *  idx: Set which resource will be loaded\r
+     *p3acali: read from 3ACALI.BIN or 3ACALI_F.BIN\r
+     *pLsc: read from LSC.BIN or LSC_F.BIN\r
+     *pLscdq: read from LSC_DQ.BIN or LSC_DQ_F.BIN\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_ResCheck(UINT8 idx, UINT8 *p3acali, UINT8 *pLsc, UINT8 *Lscdq)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+       UINT32 header_3ACALI = 0, header_LSC = 0, header_LSCDQ = 0;\r
+       UINT32 chksuum_3ACALI = 0, chksuum_LSC = 0, chksuum_LSCDQ = 0, checksum = 0, dataSize = 0, i;\r
+\r
+       /* Header check */\r
+       if (idx == 0) { //3ACALI\r
+               header_3ACALI = *(p3acali);\r
+               header_3ACALI += (*(p3acali+1)<<8);\r
+               header_3ACALI += (*(p3acali+2)<<16);\r
+               header_3ACALI += (*(p3acali+3)<<24);\r
+               if (header_3ACALI == 0xFFFFFFFF || header_3ACALI == 0x00000000) {\r
+                       DEBUG_TRACE("header_3ACALI=0x%04x\n", header_3ACALI);\r
+                       ucRet = LOADCODE_3ACALI_HEADER_ERR;\r
+                       goto _EXIT_;\r
+               }\r
+       }\r
+       else if (idx == 1) { //LSC & LSC_DQ\r
+               header_LSC = *(pLsc);\r
+               header_LSC += (*(pLsc+1)<<8);\r
+               header_LSC += (*(pLsc+2)<<16);\r
+               header_LSC += (*(pLsc+3)<<24);\r
+               if (header_LSC == 0xFFFFFFFF || header_LSC == 0x00000000) {\r
+                       DEBUG_TRACE("header_LSC=0x%04x\n", header_LSC);\r
+                       ucRet = LOADCODE_LSC_HEADER_ERR;\r
+                       goto _EXIT_;\r
+               }\r
+\r
+               header_LSCDQ = *(Lscdq);\r
+               header_LSCDQ += (*(Lscdq+1)<<8);\r
+               header_LSCDQ += (*(Lscdq+2)<<16);\r
+               header_LSCDQ += (*(Lscdq+3)<<24);\r
+               if (header_LSCDQ == 0xFFFFFFFF || header_LSCDQ == 0x00000000) {\r
+                       DEBUG_TRACE("header_LSCDQ=0x%04x\n", header_LSCDQ);\r
+                       ucRet = LOADCODE_LSC_DQ_HEADER_ERR;\r
+                       goto _EXIT_;\r
+               }\r
+       }\r
+\r
+       /* Checksum check */\r
+       if (idx == 0) { //3ACALI\r
+               dataSize = *(p3acali+6);\r
+               dataSize += (*(p3acali+7)<<8);\r
+               checksum = *(p3acali+RES_3ACALI_HEADER_SIZE);\r
+               checksum += (*(p3acali+RES_3ACALI_HEADER_SIZE+1)<<8);\r
+               checksum += (*(p3acali+RES_3ACALI_HEADER_SIZE+2)<<16);\r
+               checksum += (*(p3acali+RES_3ACALI_HEADER_SIZE+3)<<24);\r
+               \r
+               for (i = 0; i < dataSize-sizeof(UINT32); i++) {\r
+                       chksuum_3ACALI = chksuum_3ACALI + (*(p3acali+RES_3ACALI_HEADER_SIZE+sizeof(UINT32)+i));\r
+               }\r
+               if (chksuum_3ACALI != checksum) {\r
+                       DEBUG_TRACE("dataSize=%d, checksum=0x%04x, chksuum_3ACALI=0x%04x\n", dataSize, checksum, chksuum_3ACALI);\r
+                       ucRet = LOADCODE_3ACALI_CHKSUM_ERR;\r
+                       goto _EXIT_;\r
+               }\r
+       }\r
+       else if (idx == 1) { //LSC & LSC_DQ\r
+               dataSize = *(pLsc+6);\r
+               dataSize += (*(pLsc+7)<<8);\r
+               checksum = *(pLsc+RES_LSC_HEADER_SIZE-4);\r
+               checksum += (*(pLsc+RES_LSC_HEADER_SIZE-3)<<8);\r
+               checksum += (*(pLsc+RES_LSC_HEADER_SIZE-2)<<16);\r
+               checksum += (*(pLsc+RES_LSC_HEADER_SIZE-1)<<24);\r
+               for (i = 0; i < dataSize; i++) {\r
+                       chksuum_LSC = chksuum_LSC + (*(pLsc+RES_LSC_HEADER_SIZE+i));\r
+               }\r
+               if (chksuum_LSC != checksum) {\r
+                       DEBUG_TRACE("dataSize=%d, checksum=0x%04x, chksuum_LSC=0x%04x\n", dataSize, checksum, chksuum_LSC);\r
+                       ucRet = LOADCODE_LSC_CHKSUM_ERR;\r
+                       goto _EXIT_;\r
+               }\r
+\r
+               dataSize = *(Lscdq+6);\r
+               dataSize += (*(Lscdq+7)<<8);\r
+               checksum = *(Lscdq+RES_LSCDQ_HEADER_SIZE-4);\r
+               checksum += (*(Lscdq+RES_LSCDQ_HEADER_SIZE-3)<<8);\r
+               checksum += (*(Lscdq+RES_LSCDQ_HEADER_SIZE-2)<<16);\r
+               checksum += (*(Lscdq+RES_LSCDQ_HEADER_SIZE-1)<<24);\r
+               for (i = 0; i < dataSize; i++) {\r
+                       chksuum_LSCDQ = chksuum_LSCDQ + (*(Lscdq+RES_LSCDQ_HEADER_SIZE+i));\r
+               }\r
+               if (chksuum_LSCDQ != checksum) {\r
+                       DEBUG_TRACE("dataSize=%d, checksum=0x%04x, chksuum_LSCDQ=0x%04x\n", dataSize, checksum, chksuum_LSCDQ);\r
+                       ucRet = LOADCODE_LSC_DQ_CHKSUN_ERR;\r
+                       goto _EXIT_;\r
+               }\r
+       }\r
+\r
+_EXIT_:\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_ResNumGet\r
+ *  Description : get the resource number in the IQ.BIN\r
+ *  *resNum: resource number\r
+     *pIspFw: external ISP FW pointer\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_ResNumGet(UINT32 *resNum, UINT8 *pIspFw)\r
+{\r
+       UINT8 i = 0, ucRet = SUCCESS;\r
+\r
+       //DEBUG_TRACE("4.pIspFw =%x\n", pIspFw);\r
+       while (1) {\r
+               //DEBUG_TRACE("[%s] %d 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n", __FUNCTION__, __LINE__,\r
+               //      *(pIspFw),*(pIspFw+1),*(pIspFw+2), *(pIspFw+3),*(pIspFw+4),*(pIspFw+5));\r
+               if ((*(pIspFw) == 0x33) && (*(pIspFw+1) == 0x41) && (*(pIspFw+2) == 0x43) &&\r
+                       (*(pIspFw+3)==0x41) && (*(pIspFw+4)==0x4C) && (*(pIspFw+5)==0x49)) {\r
+                       break;\r
+               }\r
+               i++;\r
+               pIspFw += 0x10;\r
+               if (i > 30) {\r
+                       ucRet = LOADCODE_GET_RES_NUM_ERR;\r
+                       goto _EXIT_;\r
+               }\r
+       }\r
+\r
+_EXIT_:\r
+       *resNum = i;\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_SPIDataWrite\r
+ *  Description : write data to external ISP through SPI interface\r
+ *  ucSPIMode: SPI mode\r
+     *ucStartAddr: buffer to be wrote\r
+     ulTransByteCnt: buffer size to be wrote\r
+     ulDmaAddr: SPCA7002 DMA start address\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_SPIDataWrite(UINT8 ucSPIMode, UINT8 *ucStartAddr, UINT32 ulTransByteCnt, UINT32 ulDmaAddr)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+       UINT16 tmrCnt = 0;\r
+\r
+       EXISP_7002SPICfg(ucSPIMode, ulDmaAddr, ulTransByteCnt);\r
+\r
+       /*Trigger the 7002 SPI DMA0*/\r
+       I2CDataWrite(0x4160, 0x01);\r
+               /* Enable data transaction */\r
+       if(g_icatch_spi_dev)\r
+               spi_write(g_icatch_spi_dev, (void*)ucStartAddr, ulTransByteCnt);\r
+       else{\r
+               DEBUG_TRACE("%s:g_icatch_spi_dev is null\n",__func__);\r
+               return FAIL;\r
+       }\r
+       /* Wait SPCA7002 DAM done */\r
+       while ((I2CDataRead(0x4003)&0x02) != 0x02) {\r
+               tmrUsDelay(5000);\r
+               tmrCnt++;\r
+               if (1000 < tmrCnt) {\r
+                       DEBUG_TRACE("Wait 7002 DMA0 INT Timeout.\n");\r
+                       return FAIL;\r
+               }\r
+       }\r
+\r
+       /* Restore SPCA7002 DMA setting */\r
+       I2CDataWrite(0x1084, 0);\r
+       I2CDataWrite(0x1085, 0);\r
+       I2CDataWrite(0x1086, 0);\r
+       I2CDataWrite(0x1087, 0);\r
+       I2CDataWrite(0x1088, 0);\r
+       I2CDataWrite(0x108c, 0);\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_7002SPICfg\r
+ *  Description : external SPI configuration\r
+ *  ucSPIMode: SPI mode\r
+     ulDmaAddr: SPCA7002 DMA start address\r
+     ulTransByteCnt: buffer size to be wrote\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_7002SPICfg(UINT8 ucSPIMode, UINT32 ulDmaAddr, UINT32 ulTransByteCnt)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+       UINT8 startBank, endBank, realEndBank, readData, i;\r
+       UINT32 bankEndValue=0;\r
+       const UINT16 bankSize = 8192;\r
+       const UINT32 maxTransByteCnt = 0x50000;\r
+\r
+       static UINT8 regdata1[][3] = {\r
+               {0x40, 0x10, 0x10}, /*SPI reset*/\r
+               {0x40, 0xe1, 0x00}, /*SPI mode*/\r
+               {0x40, 0x51, 0x01}, /*SPI enable*/\r
+               {0x40, 0x11, 0x10}, /*DMA0 reset*/\r
+               {0x41, 0x64, 0x01}, /*Read data from host*/\r
+               {0x41, 0x70, 0x0f}, /*Byte Cnt Low*/\r
+               {0x41, 0x71, 0x0f}, /*Byte Cnt Mid*/\r
+               {0x41, 0x72, 0x0f}, /*Byte Cnt High*/\r
+               {0x10, 0x8c, 0x00}, /*DMA master select FM*/\r
+               {0x10, 0x80, 0x00}, /*DMA start addr Low*/\r
+               {0x10, 0x81, 0x00}, /*DMA start addr Mid*/\r
+               {0x10, 0x82, 0x00}, /*DMA start addr High*/\r
+               {0x10, 0x84, 0x00}, /*DMA bank enable*/\r
+               {0x10, 0x85, 0x00},\r
+               {0x10, 0x86, 0x00},\r
+               {0x10, 0x87, 0x00},\r
+               {0x10, 0x88, 0x00},\r
+               {0x00, 0x26, 0x00},\r
+               {0x40, 0x03, 0x02}, /*Clear DMA0 INT status*/\r
+       };\r
+\r
+       regdata1[1][2] = (((UINT8)ucSPIMode) & 0xf);\r
+       regdata1[4][2] = (1&0x1);\r
+\r
+       if (maxTransByteCnt < ulTransByteCnt)\r
+               ulTransByteCnt = (maxTransByteCnt-1);\r
+       else\r
+               ulTransByteCnt--;\r
+\r
+       regdata1[5][2] = (ulTransByteCnt & 0xff);\r
+       regdata1[6][2] = ((ulTransByteCnt >> 8) & 0xff);\r
+       regdata1[7][2] = ((ulTransByteCnt >> 16) & 0xff);\r
+       regdata1[8][2] = 0<<4;\r
+       regdata1[9][2] = (ulDmaAddr & 0xff);\r
+       regdata1[10][2] = ((ulDmaAddr >> 8) & 0xff);\r
+       regdata1[11][2] = ((ulDmaAddr >> 16) & 0xff);\r
+\r
+       startBank = (ulDmaAddr&0xffffff)/bankSize;\r
+       endBank = ((ulDmaAddr&0xffffff)+ulTransByteCnt)/bankSize;\r
+       realEndBank = endBank;\r
+\r
+       if (endBank > 31) {\r
+\r
+               for (i = 32; i <= endBank; i++)\r
+                       bankEndValue |= (1 << (i-32));\r
+\r
+               regdata1[16][2] = (bankEndValue & 0xff);\r
+               realEndBank = 32;\r
+               bankEndValue = 0;\r
+       }\r
+\r
+       for (i = startBank; i <= realEndBank; i++)\r
+               bankEndValue |= (1 << i);\r
+\r
+       regdata1[12][2] = (bankEndValue & 0xff);\r
+       regdata1[13][2] = ((bankEndValue >> 8) & 0xff);\r
+       regdata1[14][2] = ((bankEndValue >>16) & 0xff);\r
+       regdata1[15][2] = ((bankEndValue >>24) & 0xff);\r
+\r
+       readData = I2CDataRead(0x0026); /*Config the SPI pin GPIO/Function mode.*/\r
+       readData &= (~0xf);\r
+       regdata1[17][2] = readData;\r
+\r
+       for (i = 0; i < sizeof(regdata1)/sizeof(regdata1[0]); i++)\r
+               I2CDataWrite(((regdata1[i][0]<<8)&0xFF00)+(regdata1[i][1]&0x00FF), regdata1[i][2]);\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_PvSizeSet\r
+ *  Description : Set preview size\r
+ *  ucResolutionIdx: resolution index\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_PvSizeSet(UINT8 ucResolutionIdx)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       EXISP_I2C_PvSizeSet(ucResolutionIdx);\r
+       EXISP_I2C_PvCapModeSet(0x00);\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_ImageCapSet\r
+ *  Description : Image capture\r
+ *  ucImageCapIdx: image capture index\r
+     0x00      IMAGE_CAP_SINGLE\r
+     0x01      IMAGE_CAP_HDR\r
+     0x02      IMAGE_CAP_ZSL_SINGLE_FLASH\r
+     0x03      IMAGE_CAP_ZSL_BURST_FLASH\r
+     0x04      IMAGE_CAP_NONZSL_SINGLE\r
+     0x05      IMAGE_CAP_NONZSL_BURST\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_ImageCapSet(UINT8 ucImageCapIdx)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       if (ucImageCapIdx >= IMAGE_CAP_MAX) {\r
+               ucRet = FAIL;\r
+               return ucRet;\r
+       }\r
+\r
+       switch (ucImageCapIdx) {\r
+       case IMAGE_CAP_SINGLE:\r
+               EXISP_I2C_CapModeSet(CAP_MODE_SINGLE);\r
+               EXISP_I2C_PvCapModeSet(PVCAP_MODE_CAP);\r
+               break;\r
+       case IMAGE_CAP_HDR:\r
+               EXISP_I2C_CapModeSet(CAP_MODE_HDR);\r
+               EXISP_I2C_PvCapModeSet(PVCAP_MODE_CAP);\r
+               break;\r
+       case IMAGE_CAP_ZSL_SINGLE_FLASH:\r
+               EXISP_I2C_CapModeSet(CAP_MODE_SINGLE);\r
+               EXISP_I2C_PvCapModeSet(PVCAP_MODE_CAP_ZSL);\r
+               break;\r
+       case IMAGE_CAP_ZSL_BURST_FLASH:\r
+               EXISP_I2C_CapModeSet(CAP_MODE_BURST);\r
+               EXISP_I2C_PvCapModeSet(PVCAP_MODE_CAP_ZSL);\r
+               break;\r
+       case IMAGE_CAP_NONZSL_SINGLE:\r
+               EXISP_I2C_CapModeSet(CAP_MODE_SINGLE);\r
+               EXISP_I2C_PvCapModeSet(PVCAP_MODE_CAP_NONZSL);\r
+               break;\r
+       case IMAGE_CAP_NONZSL_BURST:\r
+               EXISP_I2C_CapModeSet(CAP_MODE_BURST);\r
+               EXISP_I2C_PvCapModeSet(PVCAP_MODE_CAP_NONZSL);\r
+               break;\r
+       }\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_TAFTAEROISet\r
+ *  Description : Set TAF or TAE ROI and trigger\r
+ *  ucTrg:\r
+     0x00      TAFTAE_TAF_ONLY\r
+     0x01      TAFTAE_TAE_OFF\r
+     0x02      TAFTAE_TAE_USE_TAE_ROI\r
+     0x03      TAFTAE_TAE_USE_TAF_ROI\r
+     0x04      TAFTAE_TAE_ONLY\r
+     usTAFSize: AF ROI size\r
+     usTAFX: AF ROI x\r
+     usTAFY: AF ROI y\r
+     usTAESize: AE ROI size\r
+     usTAEX: AE ROI x\r
+     usTAEY: AE ROI y\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_TAFTAEROISet(\r
+       UINT8 ucTrg,\r
+       UINT16 usTAFSize,\r
+       UINT16 usTAFX,\r
+       UINT16 usTAFY,\r
+       UINT16 usTAESize,\r
+       UINT16 usTAEX,\r
+       UINT16 usTAEY)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       if (ucTrg >= TAFTAE_MAX) {\r
+               ucRet = FAIL;\r
+               return ucRet;\r
+       }\r
+\r
+       switch (ucTrg) {\r
+       case TAFTAE_TAF_ONLY:\r
+               EXISP_I2C_ROISwitchSet(0x01);\r
+               EXISP_I2C_AFROISet(usTAFSize, usTAFX, usTAFY);\r
+               EXISP_I2C_AFROITriggerSet();\r
+               break;\r
+       case TAFTAE_TAE_OFF:\r
+               EXISP_I2C_AEROITriggerSet(0x00);\r
+               break;\r
+\r
+       case TAFTAE_TAE_USE_TAE_ROI:\r
+               EXISP_I2C_ROISwitchSet(0x01);\r
+               EXISP_I2C_AEROISet(usTAESize, usTAEX, usTAEY);\r
+               EXISP_I2C_AEROITriggerSet(0x01);\r
+               EXISP_I2C_AFROISet(usTAFSize, usTAFX, usTAFY);\r
+               EXISP_I2C_AFROITriggerSet();\r
+               break;\r
+       case TAFTAE_TAE_USE_TAF_ROI:\r
+               EXISP_I2C_ROISwitchSet(0x01);\r
+               EXISP_I2C_AFROISet(usTAFSize, usTAFX, usTAFY);\r
+               EXISP_I2C_AEROITriggerSet(0x02);\r
+               EXISP_I2C_AFROITriggerSet();\r
+               break;\r
+       case TAFTAE_TAE_ONLY:\r
+               EXISP_I2C_ROISwitchSet(0x01);\r
+               EXISP_I2C_AEROISet(usTAESize, usTAEX, usTAEY);\r
+               EXISP_I2C_AEROITriggerSet(0x01);\r
+       }\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_SwitchRAWFormatSet\r
+ *  Description : Switch to RAW format from YUV format\r
+ *  Input : None\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_SwitchRAWFormatSet(void)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       EXISP_I2C_RawPathSet(0x00);\r
+       EXISP_I2C_RawFormatSet(0x01);\r
+\r
+       return ucRet;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  Function Name : EXISP_ExifInfoGet\r
+ *  Description : Get EXIF information from external ISP\r
+ *  Input : None\r
+ *  Return : status result\r
+ *------------------------------------------------------------------------*/\r
+UINT8 EXISP_ExifInfoGet(\r
+       UINT8 *ucExpTimeNumerator,\r
+       UINT32 *ulExpTimeDenominator,\r
+       UINT8 *ucExpTimeCompensation,\r
+       UINT16 *usLensFocalLength,\r
+       UINT16 *usIsoInfo,\r
+       UINT8 *ucFlashInfo)\r
+{\r
+       UINT8 ucRet = SUCCESS;\r
+\r
+       /* Get exposure time numerator */\r
+       *ucExpTimeNumerator = EXISP_I2C_ExposureTimeNumeratorGet();\r
+       /* Get exposure time denominator */\r
+       *ulExpTimeDenominator = EXISP_I2C_ExposureTimeDenominatorGet();\r
+       /* Get exposure time compensation */\r
+       *ucExpTimeCompensation = EXISP_I2C_ExposureTimeCompensationGet();\r
+       /* Get lens focal length */\r
+       *usLensFocalLength = EXISP_I2C_LensFocalLengthGet();\r
+       /* Get ISO information */\r
+       *usIsoInfo = EXISP_I2C_ISOValueGet();\r
+       /* Get flash mode information */\r
+       *ucFlashInfo = EXISP_I2C_FlashModeGet();\r
+\r
+       return ucRet;\r
+}\r
+\r
diff --git a/drivers/media/video/icatch7002/app_i2c_lib_icatch.h b/drivers/media/video/icatch7002/app_i2c_lib_icatch.h
new file mode 100755 (executable)
index 0000000..5a0a795
--- /dev/null
@@ -0,0 +1,451 @@
+/****************************************************************************\r
+ *\r
+ *        Copyright (c) 2006-2008 by Sunplus mMedia Inc., Ltd.\r
+ *\r
+ *  This software is copyrighted by and is the property of Sunplus\r
+ *  mMedia Inc., Ltd. All rights are reserved by Sunplus mMedia\r
+ *  Inc., Ltd. This software may only be used in accordance with the\r
+ *  corresponding license agreement. Any unauthorized use, duplication,\r
+ *  distribution, or disclosure of this software is expressly forbidden.\r
+ *\r
+ *  This Copyright notice MUST not be removed or modified without prior\r
+ *  written consent of Sunplus mMedia Inc., Ltd.\r
+ *\r
+ *  Sunplus mMedia Inc., Ltd. reserves the right to modify this\r
+ *  software without notice.\r
+ *\r
+ *  Sunplus mMedia Inc., Ltd.\r
+ *  19-1, Innovation First Road, Science-Based Industrial Park,\r
+ *  Hsin-Chu, Taiwan, R.O.C.\r
+ *\r
+ ****************************************************************************/\r
+#ifndef APP_I2C_LIB_ICATCH_H\r
+#define APP_I2C_LIB_ICATCH_H\r
+\r
+\r
+/****************************************************************************\r
+ *                                             C O N S T A N T S                                                                               *\r
+ ****************************************************************************/\r
+#ifndef NULL\r
+#define NULL  ((void *)0)\r
+#endif\r
+#ifndef SUCCESS\r
+#define SUCCESS        0\r
+#endif\r
+#ifndef FAIL\r
+#define FAIL   1\r
+#endif\r
+#ifndef TRUE\r
+#define TRUE   1\r
+#endif\r
+#ifndef FALSE\r
+#define FALSE  0\r
+#endif\r
+\r
+#define UINT64 unsigned long long\r
+#define UINT32 unsigned int\r
+#define UINT16 unsigned short\r
+#define UINT8  unsigned char\r
+#define SINT64 signed long long\r
+#define SINT32 signed int\r
+#define SINT16 signed short\r
+#define SINT8  signed char\r
+#define BOOL   unsigned char\r
+\r
+#define SP7K_MSG_BASE  0x7100\r
+#define SP7K_REG_BASE  0x7280\r
+\r
+/****************************************************************************\r
+ *                                             D A T A    T Y P E S                                                                    *\r
+ ****************************************************************************/\r
+typedef enum {\r
+       SP7K_MSG_BANDING_SELECTION                              = (SP7K_MSG_BASE | 0x01),\r
+       SP7K_MSG_COLOR_EFFECT                                   = (SP7K_MSG_BASE | 0x02),\r
+       SP7K_MSG_EV_COMPENSATION                                = (SP7K_MSG_BASE | 0x03),\r
+       SP7K_MSG_FLASH_MODE                                             = (SP7K_MSG_BASE | 0x04),\r
+       SP7K_MSG_FOCUS_MODE                                             = (SP7K_MSG_BASE | 0x05),\r
+       SP7K_MSG_PV_SIZE                                                = (SP7K_MSG_BASE | 0x06),\r
+       SP7K_MSG_SCENE_MODE                                             = (SP7K_MSG_BASE | 0x09),\r
+       SP7K_MSG_WHITE_BALANCE                                  = (SP7K_MSG_BASE | 0x0A),\r
+       SP7K_MSG_AE_MODE                                                = (SP7K_MSG_BASE | 0x0E),\r
+       SP7K_MSG_CAP_MODE                                               = (SP7K_MSG_BASE | 0x0F),\r
+       SP7K_MSG_CAP_ISO                                                = (SP7K_MSG_BASE | 0x10),\r
+       SP7K_MSG_AURA_COLOR_INDEX                               = (SP7K_MSG_BASE | 0x19),\r
+       SP7K_MSG_OPTICAL_ZOOM                                   = (SP7K_MSG_BASE | 0x1A),\r
+       SP7K_MSG_ISP_FUNCTION                                   = (SP7K_MSG_BASE | 0x1B),\r
+       SP7K_MSG_PV_CAP_MODE                                    = (SP7K_MSG_BASE | 0x20),\r
+       SP7K_MSG_PV_STREAM                                              = (SP7K_MSG_BASE | 0x21),\r
+       SP7K_MSG_BURST_ABORT                                    = (SP7K_MSG_BASE | 0x22),\r
+       SP7K_MSG_CAP_EDGE_QUANTITY                              = (SP7K_MSG_BASE | 0x23),\r
+       SP7K_MSG_PV_FIX_FRAME_RATE                              = (SP7K_MSG_BASE | 0x24),\r
+       SP7K_MSG_PV_MAX_EXPTIME                                 = (SP7K_MSG_BASE | 0x25),\r
+       SP7K_MSG_HDR_POSITIVE_EV                                = (SP7K_MSG_BASE | 0x27),\r
+       SP7K_MSG_HDR_NEGATIVE_EV                                = (SP7K_MSG_BASE | 0x28),\r
+       SP7K_MSG_PV_MIN_ISO                                             = (SP7K_MSG_BASE | 0x29),\r
+       SP7K_MSG_G_SENSOR_INFO_X                                = (SP7K_MSG_BASE | 0x2A),\r
+       SP7K_MSG_G_SENSOR_INFO_Y                                = (SP7K_MSG_BASE | 0x2B),\r
+       SP7K_MSG_G_SENSOR_INFO_Z                                = (SP7K_MSG_BASE | 0x2C),\r
+       SP7K_MSG_GYRO_INFO_X                                    = (SP7K_MSG_BASE | 0x2D),\r
+       SP7K_MSG_GYRO_INFO_Y                                    = (SP7K_MSG_BASE | 0x2E),\r
+       SP7K_MSG_GYRO_INFO_Z                                    = (SP7K_MSG_BASE | 0x2F),\r
+       SP7K_MSG_AF_ROI_SIZE_H                                  = (SP7K_MSG_BASE | 0x40),\r
+       SP7K_MSG_AF_ROI_SIZE_L                                  = (SP7K_MSG_BASE | 0x41),\r
+       SP7K_MSG_AF_ROI_X_H                                             = (SP7K_MSG_BASE | 0x42),\r
+       SP7K_MSG_AF_ROI_X_L                                             = (SP7K_MSG_BASE | 0x43),\r
+       SP7K_MSG_AF_ROI_Y_H                                             = (SP7K_MSG_BASE | 0x44),\r
+       SP7K_MSG_AF_ROI_Y_L                                             = (SP7K_MSG_BASE | 0x45),\r
+       SP7K_MSG_AF_ROI_TRIGGER                                 = (SP7K_MSG_BASE | 0x46),\r
+       SP7K_MSG_AE_ROI_SIZE_H                                  = (SP7K_MSG_BASE | 0x48),\r
+       SP7K_MSG_AE_ROI_SIZE_L                                  = (SP7K_MSG_BASE | 0x49),\r
+       SP7K_MSG_AE_ROI_X_H                                             = (SP7K_MSG_BASE | 0x4A),\r
+       SP7K_MSG_AE_ROI_X_L                                             = (SP7K_MSG_BASE | 0x4B),\r
+       SP7K_MSG_AE_ROI_Y_H                                             = (SP7K_MSG_BASE | 0x4C),\r
+       SP7K_MSG_AE_ROI_Y_L                                             = (SP7K_MSG_BASE | 0x4D),\r
+       SP7K_MSG_AE_ROI_TRIGGER                                 = (SP7K_MSG_BASE | 0x4E),\r
+       SP7K_MSG_AF_ABORT                                               = (SP7K_MSG_BASE | 0x4F),\r
+       SP7K_MSG_VCM_STEP_L                                             = (SP7K_MSG_BASE | 0x5C),\r
+       SP7K_MSG_VCM_STEP_H                                             = (SP7K_MSG_BASE | 0x5D),\r
+       SP7K_MSG_CAP_EDGE_INFO                                  = (SP7K_MSG_BASE | 0x5F),\r
+       SP7K_MSG_RAW_PATH                                               = (SP7K_MSG_BASE | 0x60),\r
+       SP7K_MSG_RAW_FORMAT                                             = (SP7K_MSG_BASE | 0x61),\r
+       SP7K_MSG_CALIBRATION_RAW_LINEAR                 = (SP7K_MSG_BASE | 0x62),\r
+       SP7K_MSG_CALIBRATION_RAW_OB                             = (SP7K_MSG_BASE | 0x63),\r
+       SP7K_MSG_CALIBRATION_RAW_BP                             = (SP7K_MSG_BASE | 0x64),\r
+       SP7K_MSG_CALIBRATION_RAW_LSC                    = (SP7K_MSG_BASE | 0x65),\r
+       SP7K_MSG_CALIBRATION_RAW_CA                             = (SP7K_MSG_BASE | 0x66),\r
+       SP7K_MSG_CALIBRATION_RAW_ARD                    = (SP7K_MSG_BASE | 0x67),\r
+       SP7K_MSG_CALIBRATION_RAW_DEPEAK                 = (SP7K_MSG_BASE | 0x68),\r
+       SP7K_MSG_CALIBRATION_RAW_WB                             = (SP7K_MSG_BASE | 0x69),\r
+       SP7K_MSG_CALIBRATION_AWB_CRITERIA               = (SP7K_MSG_BASE | 0x6D),\r
+       SP7K_MSG_AEAWBTHREAD_MODE                               = (SP7K_MSG_BASE | 0x70),\r
+       SP7K_MSG_DQ_MODE                                                = (SP7K_MSG_BASE | 0x71),\r
+       SP7K_MSG_CDSP_MODE                                              = (SP7K_MSG_BASE | 0x72),\r
+       SP7K_MSG_CALIBRATION_CMD1                               = (SP7K_MSG_BASE | 0x74),\r
+       SP7K_MSG_CALIBRATION_CMD2                               = (SP7K_MSG_BASE | 0x75),\r
+       SP7K_MSG_CALIBRATION_INIT_CMD                   = (SP7K_MSG_BASE | 0x76),\r
+       SP7K_MSG_CALIBRATION_LENS_MAX_LUM_DECAY = (SP7K_MSG_BASE | 0x77),\r
+       SP7K_MSG_CALIBRATION_DQ_INDEX_FIX               = (SP7K_MSG_BASE | 0x78),\r
+       SP7K_MSG_CALIBRATION_UTILIZATION_OPTION = (SP7K_MSG_BASE | 0x7F),\r
+       SP7K_MSG_ROI_SWITCH                                             = (SP7K_MSG_BASE | 0x88),\r
+\r
+       SP7K_MSG_VENDREQ_ID                                             = (SP7K_MSG_BASE | 0xE4),\r
+       SP7K_MSG_VENDREQ_PARAM                                  = (SP7K_MSG_BASE | 0xE5),\r
+       SP7K_MSG_VENDREQ_VALUES_L                               = (SP7K_MSG_BASE | 0xE6),\r
+       SP7K_MSG_VENDREQ_PROCESS                                = (SP7K_MSG_BASE | 0xE8),\r
+       SP7K_MSG_VENDREQ_VALUES_H                               = (SP7K_MSG_BASE | 0xEA),\r
+       SP7K_MSG_VENDREQ_CMD                                    = (SP7K_MSG_BASE | 0xEB),\r
+} sp7kHostMsgList_e;\r
+\r
+typedef enum {\r
+       SP7K_RDREG_AF_STATUS                                    = (SP7K_REG_BASE | 0xA0),\r
+       SP7K_RDREG_AF_RESULT                                    = (SP7K_REG_BASE | 0xA1),\r
+       SP7K_RDREG_AF_CONSUME_TIME_L                    = (SP7K_REG_BASE | 0xA2),\r
+       SP7K_RDREG_AF_CONSUME_TIME_H                    = (SP7K_REG_BASE | 0xA3),\r
+       SP7K_RDREG_VCM_CURRENT_POS_L                    = (SP7K_REG_BASE | 0xA4),\r
+       SP7K_RDREG_VCM_CURRENT_POS_H                    = (SP7K_REG_BASE | 0xA5),\r
+       SP7K_RDREG_EXPTIME_NUMERATOR                    = (SP7K_REG_BASE | 0xB0),\r
+       SP7K_RDREG_EXPTIME_DENOMINATOR_L                = (SP7K_REG_BASE | 0xB1),\r
+       SP7K_RDREG_EXPTIME_DENOMINATOR_M                = (SP7K_REG_BASE | 0xB2),\r
+       SP7K_RDREG_EXPTIME_DENOMINATOR_H                = (SP7K_REG_BASE | 0xB3),\r
+       SP7K_RDREG_EXPTIME_COMPENSATION                 = (SP7K_REG_BASE | 0xB4),\r
+       SP7K_RDREG_LENS_FOCAL_LENGTH_L                  = (SP7K_REG_BASE | 0xB5),\r
+       SP7K_RDREG_LENS_FOCAL_LENGTH_H                  = (SP7K_REG_BASE | 0xB6),\r
+       SP7K_RDREG_ISO_L                                                = (SP7K_REG_BASE | 0xB7),\r
+       SP7K_RDREG_ISO_H                                                = (SP7K_REG_BASE | 0xB8),\r
+       SP7K_RDREG_FLASH_MODE                                   = (SP7K_REG_BASE | 0xB9),\r
+       SP7K_RDREG_CAP_EDGE_INFO_B0                             = (SP7K_REG_BASE | 0xBA),\r
+       SP7K_RDREG_CAP_EDGE_INFO_B1                             = (SP7K_REG_BASE | 0xBB),\r
+       SP7K_RDREG_CAP_EDGE_INFO_B2                             = (SP7K_REG_BASE | 0xBC),\r
+       SP7K_RDREG_CAP_EDGE_INFO_B3                             = (SP7K_REG_BASE | 0xBD),\r
+       SP7K_RDREG_3A_STATUS                                    = (SP7K_REG_BASE | 0xC3),\r
+       SP7K_RDREG_EDGE_INFO_COUNT                              = (SP7K_REG_BASE | 0xC4),\r
+       SP7K_RDREG_REAR_SENSORID_L                              = (SP7K_REG_BASE | 0xC6),\r
+       SP7K_RDREG_REAR_SENSORID_H                              = (SP7K_REG_BASE | 0xC7),\r
+       SP7K_RDREG_FRONT_SENSORID_L                             = (SP7K_REG_BASE | 0xC8),\r
+       SP7K_RDREG_FRONT_SENSORID_H                             = (SP7K_REG_BASE | 0xC9),\r
+       SP7K_RDREG_FW_VER_L                                             = (SP7K_REG_BASE | 0xCA),\r
+       SP7K_RDREG_FW_VER_M                                             = (SP7K_REG_BASE | 0xCB),\r
+       SP7K_RDREG_FW_VER_H                                             = (SP7K_REG_BASE | 0xCC),\r
+       SP7K_RDREG_VENDOR_ID_L                                  = (SP7K_REG_BASE | 0xCE),\r
+       SP7K_RDREG_VENDOR_ID_H                                  = (SP7K_REG_BASE | 0xCF),\r
+       SP7K_RDREG_CALIBRATION_LSC_MAX_RGAIN_L  = (SP7K_REG_BASE | 0xD8),\r
+       SP7K_RDREG_CALIBRATION_LSC_MAX_RGAIN_H  = (SP7K_REG_BASE | 0xD9),\r
+       SP7K_RDREG_CALIBRATION_LSC_MAX_GGAIN_L  = (SP7K_REG_BASE | 0xDA),\r
+       SP7K_RDREG_CALIBRATION_LSC_MAX_GGAIN_H  = (SP7K_REG_BASE | 0xDB),\r
+       SP7K_RDREG_CALIBRATION_LSC_MAX_BGAIN_L  = (SP7K_REG_BASE | 0xDC),\r
+       SP7K_RDREG_CALIBRATION_LSC_MAX_BGAIN_H  = (SP7K_REG_BASE | 0xDD),\r
+       SP7K_RDREG_CALIBRATION_AWB_RGain_L              = (SP7K_REG_BASE | 0xE1),\r
+       SP7K_RDREG_CALIBRATION_AWB_RGain_H              = (SP7K_REG_BASE | 0xE2),\r
+       SP7K_RDREG_CALIBRATION_AWB_GGain_L              = (SP7K_REG_BASE | 0xE3),\r
+       SP7K_RDREG_CALIBRATION_AWB_GGain_H              = (SP7K_REG_BASE | 0xE4),\r
+       SP7K_RDREG_CALIBRATION_AWB_BGain_L              = (SP7K_REG_BASE | 0xE5),\r
+       SP7K_RDREG_CALIBRATION_AWB_BGain_H              = (SP7K_REG_BASE | 0xE6),\r
+       SP7K_RDREG_CALIBRATION_EXEC_STATUS1             = (SP7K_REG_BASE | 0xF0),\r
+       SP7K_RDREG_CALIBRATION_EXEC_STATUS2             = (SP7K_REG_BASE | 0xF1),\r
+       SP7K_RDREG_CALIBRATION_ERROR_STATUS1    = (SP7K_REG_BASE | 0xF2),\r
+       SP7K_RDREG_CALIBRATION_ERROR_STATUS2    = (SP7K_REG_BASE | 0xF3),\r
+       SP7K_RDREG_CALIBRATION_ERROR_CODE               = (SP7K_REG_BASE | 0xF4),\r
+       SP7K_RDREG_CALIBRATION_LOAD_TABLE_STATUS= (SP7K_REG_BASE | 0xF5),\r
+       SP7K_RDREG_INT_STS_REG_0                                = (SP7K_REG_BASE | 0xF8),\r
+       SP7K_RDREG_INT_MASK_REG_0                               = (SP7K_REG_BASE | 0xFC),\r
+} sp7kReadRegList_e;\r
+\r
+typedef enum {\r
+       GPIO_CTL_LOW,\r
+       GPIO_CTL_HIGH,\r
+       GPIO_CTL_MAX,\r
+} sp7kGpioCtlList_e;\r
+\r
+typedef enum {\r
+       BOOT_FROM_SPI,\r
+       BOOT_FROM_HOST,\r
+       BOOT_FROM_MAX,\r
+} sp7kPowerOnList_e;\r
+\r
+typedef enum {\r
+       SENSOR_ID_REAR,\r
+       SENSOR_ID_FRONT,\r
+       SENSOR_ID_REAR_CALIBRATION,\r
+       SENSOR_ID_MAX,\r
+} sp7kSensorIdList_e;\r
+\r
+typedef enum {\r
+       IMAGE_CAP_SINGLE,\r
+       IMAGE_CAP_HDR,\r
+       IMAGE_CAP_ZSL_SINGLE_FLASH,\r
+       IMAGE_CAP_ZSL_BURST_FLASH,\r
+       IMAGE_CAP_NONZSL_SINGLE,\r
+       IMAGE_CAP_NONZSL_BURST,\r
+       IMAGE_CAP_MAX,\r
+} sp7kImageCapList_e;\r
+\r
+typedef enum {\r
+       CAP_MODE_SINGLE,\r
+       CAP_MODE_HDR,\r
+       CAP_MODE_RSV,\r
+       CAP_MODE_BURST,\r
+       CAP_MODE_MAX,\r
+} sp7kCapModeList_e;\r
+\r
+typedef enum {\r
+       PVCAP_MODE_PV,\r
+       PVCAP_MODE_CAP,\r
+       PVCAP_MODE_CAP_ZSL,\r
+       PVCAP_MODE_CAP_NONZSL,\r
+       PVCAP_MODE_MAX,\r
+} sp7kPvCapModeList_e;\r
+\r
+typedef enum {\r
+       TAFTAE_TAF_ONLY,\r
+       TAFTAE_TAE_OFF,\r
+       TAFTAE_TAE_USE_TAE_ROI,\r
+       TAFTAE_TAE_USE_TAF_ROI,\r
+       TAFTAE_TAE_ONLY,\r
+       TAFTAE_MAX,\r
+} sp7kTAFTAEList_e;\r
+\r
+typedef enum {\r
+       NONE,\r
+       LOADCODE_BOOT_FILE_ERR,\r
+\r
+       LOADCODE_CALIB_OPT_FILE_ERR,\r
+       LOADCODE_CALIB_OPT_MAX_ERR,\r
+\r
+       LOADCODE_3ACALI_FILE_ERR,\r
+       LOADCODE_3ACALI_HEADER_ERR,\r
+       LOADCODE_3ACALI_CHKSUM_ERR,\r
+\r
+       LOADCODE_LSC_FILE_ERR,\r
+       LOADCODE_LSC_HEADER_ERR,\r
+       LOADCODE_LSC_CHKSUM_ERR,\r
+\r
+       LOADCODE_LSC_DQ_FILE_ERR,\r
+       LOADCODE_LSC_DQ_HEADER_ERR,\r
+       LOADCODE_LSC_DQ_CHKSUN_ERR,\r
+\r
+       LOADCODE_GET_RES_NUM_ERR,\r
+} LoadCodeErrList_e;\r
+\r
+typedef struct {\r
+       UINT32 DmemFicdmemSize; /*DMEM+FICDMEM size*/\r
+       UINT32 ImemSize; /*IMEM size*/\r
+       UINT16 FmClk; /*FM clock*/\r
+       UINT16 Checksum; /*checksum*/\r
+       UINT32 DmemSize; /*DMEM size*/\r
+} ispFwHeaderInfo_t;\r
+\r
+typedef struct {\r
+       UINT32 retCalibOpt;\r
+       UINT32 ret3acli;\r
+       UINT32 retLsc;\r
+       UINT32 retLscdq;\r
+} ispLoadCodeRet_t;\r
+\r
+/****************************************************************************\r
+ *                                              M A C R O S                                                                                    *\r
+ ****************************************************************************/\r
+\r
+/****************************************************************************\r
+ *                                              E X T E R N V A R I A B L E S    D E C L A R A T I O N S               *\r
+ ****************************************************************************/\r
+\r
+/****************************************************************************\r
+ *                                             F U N C T I O N    D E C L A R A T I O N S                                      *\r
+ ****************************************************************************/\r
+void EXISP_I2C_BandSelectionSet(UINT8 ucParam);\r
+void EXISP_I2C_ColorEffectSet(UINT8 ucParam);\r
+void EXISP_I2C_EvSet(UINT8 ucParam);\r
+void EXISP_I2C_FlashModeSet(UINT8 ucParam);\r
+void EXISP_I2C_FocusModeSet(UINT8 ucParam);\r
+void EXISP_I2C_PvSizeSet(UINT8 ucParam);\r
+void EXISP_I2C_SceneModeSet(UINT8 ucParam);\r
+void EXISP_I2C_WhiteBalanceSet(UINT8 ucParam);\r
+void EXISP_I2C_AEModeSet(UINT8 ucParam);\r
+void EXISP_I2C_CapModeSet(UINT8 ucParam);\r
+void EXISP_I2C_ISOSet(UINT8 ucParam);\r
+void EXISP_I2C_AuraColorIndexSet(UINT8 ucParam);\r
+void EXISP_I2C_OpticalZoomSet(UINT8 ucParam);\r
+void EXISP_I2C_IspFuncSet(UINT8 ucParam);\r
+void EXISP_I2C_PvCapModeSet(UINT8 ucParam);\r
+void EXISP_I2C_PvStreamSet(UINT8 ucParam);\r
+void EXISP_I2C_BurstAbortSet(UINT8 ucParam);\r
+void EXISP_I2C_CapEdgeQuantitySet(UINT8 ucValue);\r
+void EXISP_I2C_PvFixFrameRateSet(UINT8 ucValue);\r
+void EXISP_I2C_PvMaxExposureTimeSet(UINT8 ucValue);\r
+void EXISP_I2C_HdrPositiveEvSet(UINT8 ucValue);\r
+void EXISP_I2C_HdrNegativeEvSet(UINT8 ucValue);\r
+void EXISP_I2C_PvMinISOSet(UINT8 ucParam);\r
+void EXISP_I2C_GSensorInfoSet(SINT8 ucX, SINT8 ucY, SINT8 ucZ);\r
+void EXISP_I2C_GyroInfoSet(UINT8 ucX, UINT8 ucY, UINT8 ucZ);\r
+void EXISP_I2C_AFROISet(UINT16 usSize, UINT16 usX, UINT16 usY);\r
+void EXISP_I2C_AFROITriggerSet(void);\r
+void EXISP_I2C_AEROISet(UINT16 usSize, UINT16 usX, UINT16 usY);\r
+void EXISP_I2C_AEROITriggerSet(UINT8 ucParam);\r
+void EXISP_I2C_AFAbortSet(UINT8 ucParam);\r
+void EXISP_I2C_VcmStepSet(UINT16 usValue);\r
+void EXISP_I2C_CapEdgeInfoSet(UINT8 ucParam);\r
+void EXISP_I2C_RawPathSet(UINT8 ucParam);\r
+void EXISP_I2C_RawFormatSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationRawLinearSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationRawObSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationRawBpSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationRawLscSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationRawCaSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationRawArdSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationRawDepeakSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationRawWbSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationAwbCriteriaSet(UINT8 ucVaule);\r
+void EXISP_I2C_AEAWBThreadModeSet(UINT8 ucParam);\r
+void EXISP_I2C_DqModeSet(UINT8 ucParam);\r
+void EXISP_I2C_CdspOnOffModeSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationCmd1Set(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationCmd2Set(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationInitCmdSet(UINT8 ucParam);\r
+void EXISP_I2C_CalibrationLscMaxGainSet(UINT8 ucVaule);\r
+void EXISP_I2C_CalibrationDqIndexFixSet(UINT8 ucParam);\r
+void EXISP_I2C_CaliUtilizationOptionSet(UINT8 ucParam);\r
+void EXISP_I2C_ROISwitchSet(UINT8 ucParam);\r
+void EXISP_I2C_VendreqIdSet(UINT8 ucValue);\r
+void EXISP_I2C_VendreqParamSet(UINT8 ucValue);\r
+void EXISP_I2C_VendreqValuesSet_L(UINT8 ucVaule);\r
+void EXISP_I2C_VendreqProcessSet(void);\r
+void EXISP_I2C_VendreqValuesSet_H(UINT8 ucVaule);\r
+void EXISP_I2C_VendreqCmdSet(UINT8 ucParam);\r
+\r
+\r
+UINT8  EXISP_I2C_AFStatusGet(void);\r
+UINT8  EXISP_I2C_AFResultGet(void);\r
+UINT16 EXISP_I2C_AFConsumeTimeGet(void);\r
+UINT16 EXISP_I2C_VcmCurrentPosGet(void);\r
+UINT8  EXISP_I2C_ExposureTimeNumeratorGet(void);\r
+UINT32 EXISP_I2C_ExposureTimeDenominatorGet(void);\r
+UINT8  EXISP_I2C_ExposureTimeCompensationGet(void);\r
+UINT16 EXISP_I2C_LensFocalLengthGet(void);\r
+UINT16 EXISP_I2C_ISOValueGet(void);\r
+UINT8  EXISP_I2C_FlashModeGet(void);\r
+UINT32 EXISP_I2C_CapEdgeInfoGet(void);\r
+UINT8  EXISP_I2C_3AStatusGet(void);\r
+UINT8  EXISP_I2C_EdgeInfoCountGet(void);\r
+UINT16 EXISP_I2C_RearSensorIdGet(void);\r
+UINT16 EXISP_I2C_FrontSensorIdGet(void);\r
+UINT32 EXISP_I2C_FWVersionGet(void);\r
+UINT16 EXISP_I2C_VendorIdGet(void);\r
+UINT16 EXISP_I2C_CalibrationLscMaxRGainGet(void);\r
+UINT16 EXISP_I2C_CalibrationLscMaxGGainGet(void);\r
+UINT16 EXISP_I2C_CalibrationLscMaxBGainGet(void);\r
+UINT16 EXISP_I2C_CalibrationAWBRGainGet(void);\r
+UINT16 EXISP_I2C_CalibrationAWBGGainGet(void);\r
+UINT16 EXISP_I2C_CalibrationAWBBGainGet(void);\r
+UINT8  EXISP_I2C_CalibrationExecStatus1Get(void);\r
+UINT8  EXISP_I2C_CalibrationExecStatus2Get(void);\r
+UINT8  EXISP_I2C_CalibrationErrorStatus1Get(void);\r
+UINT8  EXISP_I2C_CalibrationErrorStatus2Get(void);\r
+UINT8  EXISP_I2C_CalibrationErrorCodeGet(void);\r
+UINT8  EXISP_I2C_CalibrationLoadTableStatusGet(void);\r
+\r
+\r
+UINT8 EXISP_SuspendGpioCfgSet(UINT8 ucCtl);\r
+UINT8 EXISP_DigitalPowerCfgSet(UINT8 On);\r
+UINT8 EXISP_AnalogPowerCfgSet(UINT8 On);\r
+UINT8 EXISP_ClockCfgSet(UINT8 ucEnable);\r
+UINT8 EXISP_ResetGpioCfgSet(UINT8 ucCtl);\r
+UINT8 EXISP_PowerOn(UINT8 ucBoot);\r
+UINT8 EXISP_PowerOff(void);\r
+UINT8 EXISP_LoadCodeStart(\r
+       UINT8 ucBoot,\r
+       UINT8 ucFwIdx,\r
+       UINT8 is_calibration,\r
+       UINT8 *pIspFw,\r
+       UINT8 *pCalibOpt,\r
+       UINT8 *p3acali,\r
+       UINT8 *pLsc,\r
+       UINT8 *pLscdq);\r
+UINT8 EXISP_LoadCode(\r
+       UINT8 ucFwIdx,\r
+       UINT8 is_calibration,\r
+       UINT8 *pIspFw,\r
+       UINT8 *pCalibOpt,\r
+       UINT8 *p3acali,\r
+       UINT8 *pLsc,\r
+       UINT8 *pLscdq);\r
+void EXISP_UpdateCalibResStart(\r
+       UINT8 ucFwIdx,\r
+       UINT8 *pIspFw,\r
+       ispFwHeaderInfo_t *pFwInfo,\r
+       ispLoadCodeRet_t *pLoadCodeRet,\r
+       UINT8 ucCaliOpt,\r
+       UINT8 *p3acali,\r
+       UINT8 *pLsc,\r
+       UINT8 *pLscdq);\r
+UINT8 EXISP_UpdateCalibRes(\r
+       UINT8 idx,\r
+       UINT8 *pIspFw,\r
+       ispFwHeaderInfo_t *pFwInfo,\r
+       UINT8 *p3acali,\r
+       UINT8 *pLsc,\r
+       UINT8 *pLscdq);\r
+UINT8 EXISP_ResCheck(UINT8 idx, UINT8 *p3acali, UINT8 *pLsc, UINT8 *Lscdq);\r
+UINT8 EXISP_ResNumGet(UINT32 *resNum, UINT8 *pIspFw);\r
+UINT8 EXISP_SPIDataWrite(UINT8 ucSPIMode, UINT8 *ucStartAddr, UINT32 ulTransByteCnt, UINT32 ulDmaAddr);\r
+UINT8 EXISP_7002SPICfg(UINT8 ucSPIMode, UINT32 ulDmaAddr, UINT32 ulTransByteCnt);\r
+UINT8 EXISP_PvSizeSet(UINT8 ucResolutionIdx);\r
+UINT8 EXISP_ImageCapSet(UINT8 ucImageCapIdx);\r
+UINT8 EXISP_TAFTAEROISet(\r
+       UINT8 ucTrg,\r
+       UINT16 usTAFSize,\r
+       UINT16 usTAFX,\r
+       UINT16 usTAFY,\r
+       UINT16 usTAESize,\r
+       UINT16 usTAEX,\r
+       UINT16 usTAEY);\r
+UINT8 EXISP_SwitchRAWFormatSet(void);\r
+UINT8 EXISP_ExifInfoGet(\r
+       UINT8 *ucExpTimeNumerator,\r
+       UINT32 *ulExpTimeDenominator,\r
+       UINT8 *ucExpTimeCompensation,\r
+       UINT16 *usLensFocalLength,\r
+       UINT16 *usIsoInfo,\r
+       UINT8 *ucFlashInfo);\r
+\r
+#endif  /* APP_I2C_LIB_ICATCH_H */\r
+\r
diff --git a/drivers/media/video/icatch7002/burn_spi_sample_code_0910.c b/drivers/media/video/icatch7002/burn_spi_sample_code_0910.c
new file mode 100755 (executable)
index 0000000..0053acd
--- /dev/null
@@ -0,0 +1,1247 @@
+#include "app_i2c_lib_icatch.h"\r
+#include <linux/delay.h>\r
+#include <linux/slab.h>\r
+#include <linux/firmware.h>\r
+#include "icatch7002_common.h"\r
+\r
+#define SPI_CMD_BYTE_READ                      0x03\r
+#define SPI_CMD_RD_ID                          0x9F\r
+#define        SPI_CMD_WRT_EN                          0x06\r
+#define SPI_CMD_BYTE_PROG                      0x02\r
+#define SPI_CMD_RD_STS                                 0x05\r
+#define SPI_CMD_BYTE_PROG_AAI          0xAD\r
+#define SPI_CMD_WRT_STS_EN             0x50\r
+#define SPI_CMD_WRT_STS                        0x01\r
+#define SPI_CMD_WRT_DIS                        0x04\r
+#define        SPI_CMD_ERASE_ALL                       0xC7\r
+#define        SPI_CMD_SECTOR_ERASE            0x20\r
+#define        SPI_CMD_32KB_BLOCK_ERASE        0x52\r
+#define        SPI_CMD_64KB_BLOCK_ERASE        0xD8\r
+#define WAIT_COUNT 100\r
+\r
+#define I2CDataWrite(reg,val) icatch_sensor_write((reg),(val))\r
+#define I2CDataRead(reg)  icatch_sensor_read((reg))\r
+#define osMemAlloc(len) kzalloc((len), GFP_KERNEL);\r
+#define osMemFree(pbuf) kfree(pbuf)\r
+#define seqI2CDataRead(reg,buf)  *((u8*)(buf))= icatch_sensor_read(reg)\r
+#define seqI2CDataWrite(reg,buf)  icatch_sensor_write((reg),(*(u8*)(buf)))\r
+\r
+#define hsI2CDataRead(reg)  icatch_sensor_read((reg))\r
+#define hsI2CDataWrite(reg,val) icatch_sensor_write((reg),(val)) \r
+\r
+#ifndef tmrUsDelay\r
+#define tmrUsWait(ulTime)      (((ulTime)>1000)?(msleep((ulTime)/1000)):udelay((ulTime)))\r
+#endif\r
+#define ros_thread_sleep(ulTime) (((ulTime)>1000)?(msleep((ulTime)/1000)):udelay((ulTime)))\r
+\r
+\r
+//local declare\r
+void I2C_SPIInit(void);\r
+UINT32 I2C_SPIFlashReadId(void);\r
+UINT32 BB_SerialFlashTypeCheck(UINT32 id,UINT32 *spiSize);\r
+void BB_EraseSPIFlash(UINT32 type,UINT32 spiSize);\r
+UINT32 I2C_SPISstFlashWrite(UINT32 addr,UINT32 pages,UINT8 *pbuf);\r
+UINT32 I2C_SPIFlashWrite_DMA(UINT32 addr,UINT32 pages,UINT32 usage,UINT8 *pbuf);\r
+UINT32 I2C_SPI64KBBlockErase(UINT32 address,UINT32 stFlag);\r
+UINT32 I2C_SPI32KBBlockErase(UINT32 address,UINT32 stFlag);\r
+UINT32 I2C_SPISectorErase(UINT32 address,UINT32 stFlag);\r
+\r
+static const UINT32 stSpiIdInfo[7][3] =\r
+{\r
+       /*Winbond*/\r
+       {0x00EF3017,4096, 2048},\r
+       {0x00EF3016,4096, 1024},\r
+       {0x00EF3015,4096, 512},\r
+       {0x00EF3014,4096, 256},\r
+       {0x00EF5014,4096, 256},\r
+       {0x00EF3013,4096, 128},\r
+       {0x00EF5013,4096, 128},\r
+       /*Fail*/\r
+       {0x00000000,0,0},\r
+};\r
+\r
+static const UINT32 sstSpiIdInfo[6][3] =\r
+{\r
+       /*ESMT*/\r
+       {0x008C4016,4096,512},\r
+       /*SST*/\r
+       {0x00BF254A,4096,1024},\r
+       {0x00BF2541,4096,512},\r
+       {0x00BF258E,4096,256},\r
+       {0x00BF258D,4096,128},\r
+       /*Fail*/\r
+       {0x00000000,0,0},\r
+};\r
+\r
+/* BB_WrSPIFlash Â¬Â° main function for burning SPI */\r
+UINT32 I2C_SPIStChipErase(\r
+       void\r
+);\r
+\r
+void\r
+BB_WrSPIFlash(\r
+       UINT32 size\r
+)\r
+{\r
+  UINT32 id, type;\r
+       UINT32 pages, spiSize;\r
+\r
+       UINT32 fd, fileSize;\r
+       UINT8* pbootBuf = NULL;\r
+       const struct firmware *fw = NULL;\r
+\r
+       printk("loadcode from file\n");\r
+       /*#define FILE_PATH_BOOTCODE "D:\\FPGA.IME"*/\r
+       //#define FILE_PATH_BOOTCODE "D:\\DCIM\\BOOT.BIN"\r
+\r
+       //fd = sp5kFsFileOpen( FILE_PATH_BOOTCODE, SP5K_FS_OPEN_RDONLY );\r
+       #if 0\r
+       if( icatch_request_firmware(&fw) !=0){\r
+               printk("%s:%d,requst firmware failed!!\n",__func__,__LINE__);\r
+               goto out;\r
+               }\r
+       #endif\r
+       I2CDataWrite(0x70c4,0x00);\r
+       I2CDataWrite(0x70c5,0x00);\r
+       \r
+       I2CDataWrite(0x1011,0x01); /* CPU Reset */\r
+       I2CDataWrite(0x001C,0x08);/* FM reset */\r
+       I2CDataWrite(0x001C,0x00);\r
+       I2CDataWrite(0x108C,0x00);/* DMA select */\r
+       I2CDataWrite(0x009a,0x00);/*CPU normal operation */\r
+#if 0\r
+       if(fd != 0)\r
+       {\r
+               fileSize = sp5kFsFileSizeGet(fd);\r
+               printk("fileSize:0x%x\n",fileSize);\r
+               pbootBuf= (UINT8*)sp5kMalloc(fileSize);\r
+               sp5kFsFileRead(fd, pbootBuf, fileSize);\r
+               printk("pbootBuf:0x%x\n",pbootBuf);\r
+               fsFileClose(fd);\r
+       }\r
+       else\r
+       {\r
+               printk("file open error\n");\r
+               return;\r
+       }\r
+#endif\r
+       fileSize = fw->data;\r
+       pbootBuf = fw->size;\r
+       if(pbootBuf == NULL)\r
+       {\r
+               printk("buffer allocate failed\n");\r
+               goto out;\r
+       }\r
+\r
+       I2C_SPIInit();\r
+\r
+       id = I2C_SPIFlashReadId();\r
+       if(id==0)\r
+       {\r
+               printk("read id failed\n");\r
+               goto out;\r
+       }\r
+       /*printk("spiSize:0x%x\n",&spiSize);*/\r
+       type = BB_SerialFlashTypeCheck(id, &spiSize);\r
+       if( type == 0 )\r
+       {\r
+               printk("read id failed\n");\r
+               goto out;\r
+       }\r
+\r
+       if( size > 0 && size < fileSize )\r
+       {\r
+               pages = size/0x100;\r
+               if((size%0x100)!=0)\r
+                       pages += 1;\r
+       }\r
+       else\r
+       {\r
+               pages = fileSize/0x100;\r
+       }\r
+       /*printk("pages:0x%x\n",pages);*/\r
+\r
+       //BB_EraseSPIFlash(type,spiSize);\r
+       I2C_SPIStChipErase();\r
+       msleep(4*1000);\r
+       if( type == 2 )\r
+       {\r
+               printk("SST operation\n");\r
+               I2C_SPISstFlashWrite(0,pages,pbootBuf);\r
+       }\r
+       else if( type == 1 || type == 3 )\r
+       {\r
+               printk("ST operation\n");\r
+               I2C_SPIFlashWrite_DMA(0,pages,1,pbootBuf);\r
+       }\r
+out:\r
+       if(fw)\r
+               icatch_release_firmware(fw);\r
+       return;\r
+\r
+//     osMemFree(pbootBuf);\r
+}\r
+\r
+UINT32\r
+BB_SerialFlashTypeCheck(\r
+       UINT32 id,\r
+       UINT32 *spiSize\r
+)\r
+{\r
+       UINT32 i=0;\r
+       UINT32 fullID = 1;\r
+       UINT32 shift = 0, tblId, type = 0;\r
+       /*printk("id:0x%x spiSize:0x%x\n",id,spiSize);*/\r
+       /* check whether SST type serial flash */\r
+       while( 1 ){\r
+               tblId = sstSpiIdInfo[i][0] >> shift;\r
+               if( id == tblId ) {\r
+                       printk("SST type serial flash:%x %x %x\n",i,id,sstSpiIdInfo[i][0]);\r
+                       type = 2;\r
+                       *spiSize = sstSpiIdInfo[i][1]*sstSpiIdInfo[i][2];\r
+                       break;\r
+               }\r
+               if( id == 0x00FFFFFF || id == 0x00000000) {\r
+                       return 0;\r
+               }\r
+               if( sstSpiIdInfo[i][0] == 0x00000000 ) {\r
+                       #if 0\r
+                       if( fullID ){\r
+                               fullID = 0;/* sarch partial ID */\r
+                               i = 0;\r
+                               shift = 16;\r
+                               id = id >> shift;\r
+                               continue;\r
+                       }\r
+                       #endif\r
+                       type = 3;\r
+                       break;\r
+               }\r
+               i ++;\r
+       }\r
+       if( type == 2 )\r
+               return type;\r
+\r
+       i = 0;\r
+       /* check whether ST type serial flash */\r
+       while( 1 ){\r
+               tblId = stSpiIdInfo[i][0] >> shift;\r
+               if( id == tblId ) {\r
+                       printk("ST Type serial flash:%x %x %x\n",i,id,stSpiIdInfo[i][0]);\r
+                       type = 1;\r
+                       *spiSize = stSpiIdInfo[i][1]*stSpiIdInfo[i][2];\r
+                       /*printk("spiSize:0x%x\n",*spiSize);*/\r
+                       break;\r
+               }\r
+               if( id == 0x00FFFFFF || id == 0x00000000) {\r
+                       return 0;\r
+               }\r
+               if( stSpiIdInfo[i][0] == 0x00000000 ) {\r
+                       if( fullID ){\r
+                               fullID = 0;/* sarch partial ID */\r
+                               i = 0;\r
+                               shift = 16;\r
+                               id = id >> shift;\r
+                               continue;\r
+                       }\r
+                       type = 3;\r
+                       break;\r
+               }\r
+               i ++;\r
+       }\r
+\r
+       return type;\r
+}\r
+\r
+void\r
+BB_EraseSPIFlash(\r
+       UINT32 type,\r
+       UINT32 spiSize\r
+)\r
+{\r
+       UINT8 typeFlag;\r
+       UINT32 i, temp1;\r
+       if( type == 2 )/* SST */\r
+       {\r
+               typeFlag = 0;\r
+       }\r
+       else if( type == 1 || type == 3 )/* ST */\r
+       {\r
+               typeFlag = 1;\r
+       }\r
+       /*printk("spiSize:0x%x\n",spiSize);*/\r
+       if(spiSize == (512*1024))\r
+       {\r
+               /* skip 0x7B000 ~ 0x7EFF, to keep calibration data */\r
+               temp1 = (spiSize / 0x10000)-1;\r
+               for(i=0;i<temp1;i++)\r
+               {\r
+                       I2C_SPI64KBBlockErase(i*0x10000,typeFlag);\r
+               }\r
+               I2C_SPI32KBBlockErase(temp1*0x10000,typeFlag);\r
+               temp1 = temp1*0x10000 + 0x8000;\r
+               for(i=temp1;i<spiSize-0x5000;i+=0x1000)\r
+               {\r
+                       I2C_SPISectorErase(i,typeFlag);\r
+               }\r
+               I2C_SPISectorErase(spiSize-0x1000,typeFlag);\r
+       }\r
+       else if(spiSize == (1024*1024))\r
+       {\r
+               /* only erase 256*3KB */\r
+               temp1 = (spiSize / 0x10000)-2;\r
+               for(i=0;i<temp1;i++)\r
+               {\r
+                       I2C_SPI64KBBlockErase(i*0x10000,typeFlag);\r
+               }\r
+               I2C_SPI32KBBlockErase((temp1)*0x10000,typeFlag);\r
+               I2C_SPISectorErase(spiSize-0x1000,typeFlag);\r
+       }\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : I2C_SPIInit\r
+ *  return none\r
+ *------------------------------------------------------------------------*/\r
+void I2C_SPIInit(void)\r
+{\r
+    UINT32 temp;\r
+\r
+    /*temp = I2CDataRead(0x0026);*/\r
+    I2CDataWrite(0x0026,0xc0);\r
+    I2CDataWrite(0x4051,0x01); /* spien */\r
+    I2CDataWrite(0x40e1,0x00); /* spi mode */\r
+    I2CDataWrite(0x40e0,0x12); /* spi freq */  \r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : I2C_SPIInit\r
+ *  return SUCCESS: normal\r
+           FAIL: if wait spi flash time out\r
+ *------------------------------------------------------------------------*/\r
+UINT32 I2C_SPIFlashPortWait(void)\r
+{\r
+    UINT32 cnt = WAIT_COUNT;\r
+#if 0\r
+    while(I2CDataRead(0x40e6) != 0x00){\r
+        cnt--;\r
+        if(cnt == 0x00)\r
+        {\r
+            printk("serial flash port wait time out!!\n");\r
+            return FAIL;\r
+        }\r
+    }\r
+#endif\r
+    return SUCCESS;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : I2C_SPIFlashPortWrite\r
+ *  return SUCCESS: normal\r
+           FAIL:    if wait spi flash time out\r
+ *------------------------------------------------------------------------*/\r
+UINT32 I2C_SPIFlashPortWrite(UINT32 wData)\r
+{\r
+    hsI2CDataWrite(0x40e3,(UINT8)wData);\r
+    return I2C_SPIFlashPortWait();\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : I2C_SPIFlashPortRead\r
+ *  return SUCCESS: normal\r
+           FAIL:    if wait spi flash time out\r
+ *------------------------------------------------------------------------*/\r
+UINT32 I2C_SPIFlashPortRead(void)\r
+{\r
+    UINT32 ret;\r
+\r
+    ret = hsI2CDataRead(0x40e4);\r
+    /* polling SPI state machine ready */\r
+    if (I2C_SPIFlashPortWait() != SUCCESS) {\r
+        return 0;\r
+    }\r
+       tmrUsWait(10);\r
+    ret = hsI2CDataRead(0x40e5);\r
+\r
+    return ret;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : I2C_SPIFlashReadId\r
+ *  return SPI flash ID\r
+           0: if read ID failed\r
+ *------------------------------------------------------------------------*/\r
+UINT32 I2C_SPIFlashReadId(void)\r
+{\r
+    UINT8 id[3];\r
+    UINT32 ID;\r
+    UINT32 err;\r
+    \r
+    id[0] = 0;\r
+    id[1] = 0;\r
+    id[2] = 0;\r
+    \r
+    hsI2CDataWrite(0x40e7,0x00);\r
+    \r
+    err = I2C_SPIFlashPortWrite(SPI_CMD_RD_ID); /*read ID command*/\r
+    if (err != SUCCESS) {\r
+        printk("Get serial flash ID failed\n");\r
+        return 0;\r
+    }\r
+    \r
+    id[0] = I2C_SPIFlashPortRead();    /* Manufacturer's  ID */\r
+    id[1] = I2C_SPIFlashPortRead();    /* Device ID          */\r
+    id[2] = I2C_SPIFlashPortRead();    /* Manufacturer's  ID */ \r
+    \r
+    hsI2CDataWrite(0x40e7,0x01);\r
+    \r
+    printk("ID %2x %2x %2x\n", id[0], id[1], id[2]);\r
+    \r
+    ID = ((UINT32)id[0] << 16) | ((UINT32)id[1] << 8) | \\r
+    ((UINT32)id[2] << 0);\r
+    \r
+    return ID;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : I2C_SPIFlashWrEnable\r
+ *  return none\r
+ *------------------------------------------------------------------------*/\r
+void I2C_SPIFlashWrEnable(void)\r
+{\r
+    hsI2CDataWrite(0x40e7,0x00);\r
+    I2C_SPIFlashPortWrite(SPI_CMD_WRT_EN);\r
+    hsI2CDataWrite(0x40e7,0x01);\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : I2C_SPIStsRegRead\r
+ *  return ret\r
+ *------------------------------------------------------------------------*/\r
+UINT32 I2C_SPIStsRegRead(void)\r
+{\r
+    UINT32 ret;\r
+    \r
+    hsI2CDataWrite(0x40e7,0x00);\r
+    \r
+    I2C_SPIFlashPortWrite(SPI_CMD_RD_STS);\r
+    ret = I2C_SPIFlashPortRead();\r
+    \r
+    hsI2CDataWrite(0x40e7,0x01);\r
+    \r
+    return ret;\r
+}\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : I2C_SPITimeOutWait\r
+ *  return none\r
+ *------------------------------------------------------------------------*/\r
+void I2C_SPITimeOutWait(UINT32 poll, UINT32 *ptimeOut)\r
+{\r
+    /* MAX_TIME for SECTOR/BLOCK ERASE is 25ms */\r
+    UINT32 sts;\r
+    UINT32 time = 0;\r
+    while (1) {\r
+        sts = I2C_SPIStsRegRead();\r
+        if (!(sts & poll))     /* sfStatusRead() > 4.8us */ {\r
+            break;\r
+        }\r
+        time ++;\r
+        if( *ptimeOut < time ) {\r
+            printk("TimeOut %d, sts=0x%x, poll=0x%x\n",time,sts,poll);\r
+            break;\r
+        }\r
+    }\r
+}\r
+\r
+UINT32 I2C_SPIStChipErase(\r
+       void\r
+)\r
+{\r
+       UINT32 timeout;\r
+       printk("ST Chip Erasing...\n");\r
+       \r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS);\r
+       I2C_SPIFlashPortWrite(0x02);\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+       \r
+       I2C_SPIFlashWrEnable(); \r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_ERASE_ALL);\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+       \r
+       timeout = 0xffffffff;\r
+       I2C_SPITimeOutWait(0x01, &timeout);\r
+       ros_thread_sleep(1);\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+       return SUCCESS;\r
+}\r
+\r
+\r
+UINT32 I2C_SPISstChipErase(\r
+       void\r
+)\r
+{\r
+       UINT32 timeout;\r
+       printk("SST Chip Erasing...\n");\r
+\r
+       I2C_SPIFlashWrEnable();\r
+       \r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS_EN);                              /*Write Status register command*/\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+       \r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS);\r
+       I2C_SPIFlashPortWrite(0x02);\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+\r
+       I2C_SPIFlashWrEnable();\r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_ERASE_ALL);\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+\r
+       timeout = 0xffffffff;\r
+       I2C_SPITimeOutWait(0x01, &timeout);\r
+       \r
+       return SUCCESS;\r
+}\r
+\r
+UINT32 I2C_SPISectorErase(\r
+       UINT32 address,\r
+       UINT32 stFlag\r
+)\r
+{\r
+       UINT32 timeout;\r
+       printk("addr:0x%x\n",address);\r
+       if(!stFlag)\r
+       {\r
+               I2C_SPIFlashWrEnable();\r
+       \r
+               hsI2CDataWrite(0x40e7,0x00);\r
+               I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS_EN);                              /*Write Status register command*/\r
+               hsI2CDataWrite(0x40e7,0x01);\r
+       }\r
+       \r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS);                         /*Write Status register command*/\r
+       I2C_SPIFlashPortWrite(0x02);\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+\r
+       I2C_SPIFlashWrEnable();\r
+\r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_SECTOR_ERASE);\r
+       I2C_SPIFlashPortWrite(address >> 16);   /* A23~A16 */\r
+       I2C_SPIFlashPortWrite(address >> 8);            /* A15~A08 */\r
+       I2C_SPIFlashPortWrite(address);                 /* A07~A00 */\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+       \r
+       timeout = 5000000;\r
+       I2C_SPITimeOutWait(0x01, &timeout);\r
+       \r
+       return SUCCESS;\r
+}\r
+\r
+UINT32 I2C_SPI32KBBlockErase(\r
+       UINT32 address,\r
+       UINT32 stFlag\r
+)\r
+{\r
+       UINT32 timeout;\r
+       printk("addr:0x%x\n",address);\r
+       if(!stFlag)\r
+       {\r
+               I2C_SPIFlashWrEnable();\r
+       \r
+               hsI2CDataWrite(0x40e7,0x00);\r
+               I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS_EN);                              /*Write Status register command*/\r
+               hsI2CDataWrite(0x40e7,0x01);\r
+       }\r
+\r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS);                         /*Write Status register command*/\r
+       I2C_SPIFlashPortWrite(0x02);\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+\r
+       I2C_SPIFlashWrEnable();\r
+\r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_32KB_BLOCK_ERASE);\r
+       I2C_SPIFlashPortWrite(address >> 16);   /* A23~A16 */\r
+       I2C_SPIFlashPortWrite(address >> 8);            /* A15~A08 */\r
+       I2C_SPIFlashPortWrite(address);                 /* A07~A00 */\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+       \r
+       timeout = 5000000;\r
+       I2C_SPITimeOutWait(0x01, &timeout);\r
+       \r
+       return SUCCESS;\r
+}\r
+\r
+UINT32 I2C_SPI64KBBlockErase(\r
+       UINT32 address,\r
+       UINT32 stFlag\r
+)\r
+{\r
+       UINT32 timeout;\r
+       printk("addr:0x%x\n",address);\r
+       if(!stFlag)\r
+       {\r
+               I2C_SPIFlashWrEnable();\r
+       \r
+               hsI2CDataWrite(0x40e7,0x00);\r
+               I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS_EN);                              /*Write Status register command*/\r
+               hsI2CDataWrite(0x40e7,0x01);\r
+       }\r
+\r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS);                         /*Write Status register command*/\r
+       I2C_SPIFlashPortWrite(0x02);\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+\r
+       I2C_SPIFlashWrEnable();\r
+\r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_64KB_BLOCK_ERASE);\r
+       I2C_SPIFlashPortWrite(address >> 16);   /* A23~A16 */\r
+       I2C_SPIFlashPortWrite(address >> 8);            /* A15~A08 */\r
+       I2C_SPIFlashPortWrite(address);                 /* A07~A00 */\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+       \r
+       timeout = 5000000;\r
+       I2C_SPITimeOutWait(0x01, &timeout);\r
+       \r
+       return SUCCESS;\r
+}\r
+\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : I2C_SPIFlashWrite\r
+ *  addr: SPI flash starting address\r
+    pages: pages size for data -> datasize = pages * pagesize(0x100)\r
+    pbuf: data buffer\r
+ *  return SUCCESS: normal finish\r
+           FAIL:    write failed\r
+ *------------------------------------------------------------------------*/\r
+UINT32 I2C_SPIFlashWrite(\r
+       UINT32 addr,\r
+       UINT32 pages,\r
+       UINT8 *pbuf\r
+)\r
+{\r
+    UINT32 i, err = SUCCESS;\r
+    UINT32 pageSize = 0x100;\r
+    UINT32 timeout = 100000;\r
+       UINT32 rsvSec1, rsvSec2;\r
+\r
+       rsvSec1 = pages*pageSize - 0x5000;\r
+       rsvSec2 = pages*pageSize - 0x1000;\r
+    addr = addr * pageSize;\r
+    \r
+    printk("ST type writing...\n");\r
+    while( pages ) {\r
+        if((pages%0x40)==0)printk("page:0x%x\n",pages);\r
+               if((addr>=rsvSec1) && (addr <rsvSec2))\r
+               {\r
+                       addr += 0x1000;\r
+            pbuf += 0x1000;\r
+                       pages -= 0x10;\r
+                       continue;\r
+               }\r
+               if((pages==1))\r
+               {\r
+                       for (i = 0; i < pageSize ; i++) {\r
+               printk("%2x ",*(pbuf+i));\r
+                               if((i%0x10)==0x0f) printk("\n");\r
+                       }\r
+               }\r
+        I2C_SPIFlashWrEnable();\r
+        hsI2CDataWrite(0x40e7,0x00);\r
+        I2C_SPIFlashPortWrite(SPI_CMD_BYTE_PROG);               /* Write one byte command*/\r
+        I2C_SPIFlashPortWrite((UINT8)(addr >> 16));               /* Send 3 bytes address*/\r
+        I2C_SPIFlashPortWrite((UINT8)(addr >> 8));\r
+        I2C_SPIFlashPortWrite((UINT8)(addr));\r
+\r
+        for (i = 0; i < pageSize ; i++) {\r
+            I2C_SPIFlashPortWrite(*pbuf);\r
+            pbuf++;\r
+        }\r
+        hsI2CDataWrite(0x40e7,0x01);\r
+        addr += pageSize;\r
+        pages --;\r
+               tmrUsWait(400);\r
+    }\r
+    \r
+    return err;\r
+}\r
+\r
+void I2C_SPISstStatusWrite(UINT8 dat)\r
+{\r
+    UINT32 timeout, poll;\r
+    \r
+    I2C_SPIFlashWrEnable();\r
+    \r
+    hsI2CDataWrite(0x40e7,0x00);\r
+    I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS_EN);\r
+    hsI2CDataWrite(0x40e7,0x01);\r
+    \r
+    hsI2CDataWrite(0x40e7,0x00);\r
+    I2C_SPIFlashPortWrite(SPI_CMD_WRT_STS);\r
+    I2C_SPIFlashPortWrite(dat);\r
+    hsI2CDataWrite(0x40e7,0x01);\r
+    \r
+    poll = 0x01;\r
+\r
+    timeout = 100000;\r
+    I2C_SPITimeOutWait(poll, &timeout);\r
+    return;\r
+}\r
+\r
+void I2C_SPIStStatusWrite(\r
+       UINT8 value,\r
+       UINT8 value2\r
+)\r
+{\r
+    I2C_SPIFlashWrEnable();\r
+       \r
+       #if 1\r
+    hsI2CDataWrite(0x40e7,0x00);\r
+       //has not implement spi related interface,zyc\r
+//     halSpiPortWrite(SPI_CMD_WRT_STS);                               /*Write Status register command*/\r
+//     halSpiPortWrite(value);\r
+//     halSpiPortWrite(value2);\r
+    hsI2CDataWrite(0x40e7,0x01);\r
+       \r
+    hsI2CDataWrite(0x40e7,0x00);\r
+    I2C_SPIFlashPortWrite(0x04);\r
+    hsI2CDataWrite(0x40e7,0x01);\r
+       #endif\r
+}\r
+\r
+UINT32 I2C_SPISstFlashWrite(\r
+       UINT32 addr,\r
+       UINT32 pages,\r
+       UINT8 *pbuf\r
+)\r
+{\r
+    UINT32 i, err = SUCCESS;\r
+    UINT32 pageSize = 0x100;\r
+    UINT32 timeout = 100000;\r
+    \r
+    addr = addr * pageSize;\r
+    \r
+    printk("SST type writing...\n");\r
+    I2C_SPISstStatusWrite(0x40);\r
+    while( pages ) {\r
+        printk("page:0x%x\n",pages);\r
+               if((addr>=0x7C000) && (addr <0x7F000))\r
+               {\r
+                       addr += 0x1000;\r
+                       pages -= 0x10;\r
+                       continue;\r
+               }\r
+        I2C_SPIFlashWrEnable();\r
+        hsI2CDataWrite(0x40e7,0x00);\r
+        I2C_SPIFlashPortWrite(SPI_CMD_BYTE_PROG_AAI);               /* Write one byte command*/\r
+        I2C_SPIFlashPortWrite((UINT8)(addr >> 16));               /* Send 3 bytes address*/\r
+        I2C_SPIFlashPortWrite((UINT8)(addr >> 8));\r
+        I2C_SPIFlashPortWrite((UINT8)(addr));\r
+        I2C_SPIFlashPortWrite(*pbuf);\r
+        pbuf++;\r
+        I2C_SPIFlashPortWrite(*pbuf);\r
+        pbuf++;\r
+        hsI2CDataWrite(0x40e7,0x01);\r
+        timeout = 100000;\r
+        I2C_SPITimeOutWait(0x01,&timeout);\r
+\r
+        for (i = 2; i < pageSize ; i = i+2) {\r
+                   hsI2CDataWrite(0x40e7,0x00);\r
+               I2C_SPIFlashPortWrite(SPI_CMD_BYTE_PROG_AAI); \r
+                   I2C_SPIFlashPortWrite(*pbuf);\r
+                   pbuf++;\r
+                   I2C_SPIFlashPortWrite(*pbuf);\r
+                   pbuf++;\r
+                   hsI2CDataWrite(0x40e7,0x01);\r
+                   timeout = 100000;\r
+                   I2C_SPITimeOutWait(0x01,&timeout);\r
+         }\r
+\r
+         hsI2CDataWrite(0x40e7,0x00);\r
+         I2C_SPIFlashPortWrite(SPI_CMD_WRT_DIS);\r
+         hsI2CDataWrite(0x40e7,0x01);\r
+\r
+         addr += pageSize;\r
+         pages --;\r
+    \r
+         hsI2CDataWrite(0x40e7,0x00);\r
+         I2C_SPIFlashPortWrite(SPI_CMD_WRT_DIS);\r
+         hsI2CDataWrite(0x40e7,0x01);\r
+    }\r
+    \r
+    return err;\r
+}\r
+\r
+\r
+/*-------------------------------------------------------------------------\r
+ *  File Name : I2C_SPIFlashRead\r
+ *  addr: SPI flash starting address\r
+    pages: pages size for data -> datasize = pages * pagesize(0x100)\r
+    pbuf: data buffer\r
+ *  return SUCCESS: normal finish\r
+           FAIL:    read failed\r
+ *------------------------------------------------------------------------*/\r
+UINT32 I2C_SPIFlashRead(\r
+       UINT32 addr,\r
+       UINT32 pages,\r
+       UINT8 *pbuf\r
+)\r
+{\r
+    UINT8* pbufR;\r
+    UINT32 ch, err = SUCCESS;\r
+    UINT32 i, ret, count=0, size=0, bytes, offset;\r
+    UINT32 pageSize = 0x100;\r
+    \r
+    \r
+    addr = addr * pageSize;\r
+    size = pages*pageSize;\r
+    \r
+    I2CDataWrite(0x40e7,0x00);\r
+    I2C_SPIFlashPortWrite(SPI_CMD_BYTE_READ);               /* Write one byte command*/\r
+    I2C_SPIFlashPortWrite((UINT8)(addr >> 16));               /* Send 3 bytes address*/\r
+    I2C_SPIFlashPortWrite((UINT8)(addr >> 8));\r
+    I2C_SPIFlashPortWrite((UINT8)(addr));\r
+    \r
+    for (i = 0; i < size ; i++) {\r
+        *pbuf = I2C_SPIFlashPortRead();\r
+        if((i%256)==0)\r
+            printk("page:0x%x\n",(i/256));\r
+        pbuf ++;\r
+    }\r
+    \r
+    I2CDataWrite(0x40e7,0x01);\r
+    \r
+    return err;\r
+}\r
+\r
+UINT32 I2C_7002DmemWr(\r
+       UINT32 bankNum,\r
+       UINT32 byteNum,\r
+       UINT8* pbuf\r
+)\r
+{\r
+       UINT32 i, bank;\r
+\r
+       bank = 0x40+bankNum;\r
+       I2CDataWrite(0x10A6,bank);\r
+\r
+       //for(i=0;i<byteNum;i+=4)\r
+       \r
+       for(i=0;i<byteNum;i++)\r
+       {\r
+               seqI2CDataWrite((0x1800+i),(pbuf+i)); /* sequentially write DMEM */\r
+       }\r
+\r
+       bank = 0x40 + ((bankNum+1)%2);\r
+       hsI2CDataWrite(0x10A6,bank);\r
+}\r
+\r
+/* usage: 1 will skip writing reserved block of calibration data\r
+          0 will write reserved block of calibration data */\r
+UINT32 I2C_SPIFlashWrite_DMA(\r
+       UINT32 addr,\r
+       UINT32 pages,\r
+       UINT32 usage,\r
+       UINT8 *pbuf\r
+)\r
+{\r
+    UINT32 i, temp, err = SUCCESS;\r
+    UINT32 pageSize = 0x100, size;\r
+    UINT32 timeout = 100000;\r
+    UINT32 rsvSec1, rsvSec2;\r
+    UINT32 dmemBank = 0;\r
+    UINT32 chk1=0, chk2=0;\r
+    UINT32 count = 0;\r
+\r
+    rsvSec1 = pages*pageSize - 0x7000;\r
+    rsvSec2 = pages*pageSize - 0x1000;\r
+    addr = addr * pageSize;\r
+\r
+    /* Set DMA bytecnt as 256-1 */\r
+    I2CDataWrite(0x4170,0xff);\r
+    I2CDataWrite(0x4171,0x00);\r
+    I2CDataWrite(0x4172,0x00);\r
+\r
+    /* Set DMA bank & DMA start address */\r
+    I2CDataWrite(0x1084,0x01);\r
+    I2CDataWrite(0x1080,0x00);\r
+    I2CDataWrite(0x1081,0x00);\r
+    I2CDataWrite(0x1082,0x00);\r
+\r
+    /* enable DMA checksum and reset checksum */\r
+    I2CDataWrite(0x4280,0x01);\r
+    I2CDataWrite(0x4284,0x00);\r
+    I2CDataWrite(0x4285,0x00);\r
+    I2CDataWrite(0x4164,0x00);\r
+\r
+    size = pages * pageSize;\r
+    for(i=0;i<size;i++)\r
+    {\r
+       if((i>=rsvSec2) || (i <rsvSec1))\r
+       {\r
+               chk1 += *(pbuf+i);\r
+       }\r
+       if(chk1>=0x10000)\r
+       {\r
+               chk1 -= 0x10000;\r
+       }\r
+   }\r
+\r
+    while( pages ) {\r
+        if((pages%0x40)==0)\r
+        {\r
+               printk("page:0x%x",pages);\r
+       }\r
+        if((addr>=rsvSec1) && (addr <rsvSec2) && (usage!=0))\r
+        {\r
+               addr += 0x1000;\r
+                               pbuf += 0x1000;\r
+               pages -= 0x10;\r
+               continue;\r
+       }\r
+       if((pages==1))\r
+        {\r
+               for (i = 0; i < pageSize ; i++) {\r
+                       printk("%2x ",*(pbuf+i));\r
+               if((i%0x10)==0x0f) printk("\n");\r
+               }\r
+       }\r
+\r
+       dmemBank = pages % 2;\r
+       I2CDataWrite(0x1081,dmemBank*0x20);\r
+       I2CDataWrite(0x1084,(1<<dmemBank));\r
+       I2C_7002DmemWr(dmemBank,pageSize,pbuf);         \r
+               \r
+       I2C_SPIFlashWrEnable();\r
+       I2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_BYTE_PROG);               /* Write one byte command*/\r
+       I2C_SPIFlashPortWrite((UINT8)(addr >> 16));               /* Send 3 bytes address*/\r
+       I2C_SPIFlashPortWrite((UINT8)(addr >> 8));\r
+       I2C_SPIFlashPortWrite((UINT8)(addr));\r
+\r
+       I2CDataWrite(0x4160,0x01);\r
+       count = 30;\r
+       pbuf += pageSize;\r
+       addr += pageSize;\r
+               pages --;\r
+       while( hsI2CDataRead(0x4003) == 0 )\r
+       {\r
+               count--;\r
+               tmrUsWait(200);/* wait for DMA done */\r
+               if( count == 0 )\r
+               {\r
+                       printk("DMA time out: %2x, 0x%2x%2x, %2x\n",pages,\r
+                               hsI2CDataRead(0x4179),hsI2CDataRead(0x4178),hsI2CDataRead(0x40E6));\r
+                       hsI2CDataWrite(0x4011,0x10);\r
+                       hsI2CDataWrite(0x1010,0x02);\r
+                       pbuf -= pageSize;\r
+                               addr -= pageSize;\r
+                               pages ++;\r
+                       hsI2CDataWrite(0x1010,0x00);\r
+                       break;\r
+               }\r
+       }\r
+       hsI2CDataWrite(0x4003, 0x02);\r
+       I2CDataWrite(0x40e7,0x01);\r
+    }\r
+       \r
+    tmrUsWait(500);/* wait for DMA done */\r
+\r
+    temp = hsI2CDataRead(0x4285);\r
+    chk2 = hsI2CDataRead(0x4284);\r
+    chk2 = chk2 | (temp<<8);\r
+    printk("checksum: 0x%x 0x%x\n",chk1,chk2);\r
+    \r
+    return err;\r
+}\r
+\r
+UINT32 I2C_7002DmemRd(\r
+       UINT32 bankNum,\r
+       UINT32 byteNum,\r
+       UINT8* pbuf\r
+)\r
+{\r
+       UINT32 i, bank;\r
+\r
+       bank = 0x40+bankNum;\r
+       hsI2CDataWrite(0x10A6,bank);\r
+\r
+       //for(i=0;i<byteNum;i+=4)\r
+               \r
+       for(i=0;i<byteNum;i++)\r
+       {\r
+               seqI2CDataRead((0x1800+i),(pbuf+i));\r
+       }\r
+       \r
+       bank = 0x40 + ((bankNum+1)%2);\r
+       hsI2CDataWrite(0x10A6,bank);\r
+}\r
+\r
+UINT32 I2C_SPIFlashRead_DMA(\r
+       UINT32 addr,\r
+       UINT32 size,\r
+       UINT8 *pbuf\r
+)\r
+{\r
+    UINT8* pbufR;\r
+    UINT32 ch, err = SUCCESS, dmemBank;\r
+    UINT32 i, ret, count=0, bytes, offset, tempSize;\r
+    UINT32 pageSize = 0x100;\r
+\r
+\r
+       /* Set DMA bytecnt as 256-1 */\r
+       hsI2CDataWrite(0x4170,0xff);\r
+       hsI2CDataWrite(0x4171,0x00);\r
+       hsI2CDataWrite(0x4172,0x00);\r
+\r
+       /* Set DMA bank & DMA start address */\r
+       hsI2CDataWrite(0x1084,0x01);\r
+       hsI2CDataWrite(0x1080,0x00);\r
+       hsI2CDataWrite(0x1081,0x00);\r
+       hsI2CDataWrite(0x1082,0x00);\r
+\r
+       /* enable DMA checksum and reset checksum */\r
+       hsI2CDataWrite(0x4280,0x01);\r
+       hsI2CDataWrite(0x4284,0x00);\r
+       hsI2CDataWrite(0x4285,0x00);\r
+       hsI2CDataWrite(0x4164,0x01);\r
+\r
+       while(size)\r
+       {\r
+               if( size > pageSize )\r
+               {\r
+                       tempSize = 0x100;\r
+                       size -= tempSize;\r
+               }\r
+               else\r
+               {\r
+                       tempSize = size;\r
+                       size = 0;\r
+               }\r
+               \r
+       hsI2CDataWrite(0x40e7,0x00);\r
+       I2C_SPIFlashPortWrite(SPI_CMD_BYTE_READ);               /* Write one byte command*/\r
+       I2C_SPIFlashPortWrite((UINT8)(addr >> 16));               /* Send 3 bytes address*/\r
+       I2C_SPIFlashPortWrite((UINT8)(addr >> 8));\r
+       I2C_SPIFlashPortWrite((UINT8)(addr));\r
+\r
+               if( ((size/0x100)%0x40)==0x00 )\r
+               {\r
+            printk("RE:0x%x\n",((size/0x100)%0x40));\r
+               }\r
+               dmemBank = count % 2;\r
+               hsI2CDataWrite(0x1081,dmemBank*0x20);\r
+               hsI2CDataWrite(0x1084,(1<<dmemBank));\r
+       hsI2CDataWrite(0x4160,0x01);\r
+               tmrUsWait(100);\r
+       hsI2CDataWrite(0x40e7,0x01);\r
+               I2C_7002DmemRd(dmemBank,tempSize,pbuf);\r
+\r
+               pbuf += pageSize;\r
+               addr += pageSize;\r
+               count++;\r
+       }\r
+\r
+    return err;\r
+}\r
+\r
+\r
+/*************************************************************************************************** \r
+       BB_I2CCalibResModify: used for replace calibration data \r
+       resId: resource ID (0: 3ACALI.BIN, 1:LSC.BIN, 2:LSC_DQ.BIN \r
+       resBuf: buffer of data which will be used to replace original calibration data in serial flash\r
+****************************************************************************************************/\r
+UINT32\r
+BB_I2CCalibResModify(\r
+       UINT32 resId,\r
+       UINT8* resBuf\r
+)\r
+{\r
+       UINT32 i;\r
+       UINT32 spiId, spiType;\r
+       UINT32 spiSize, sectorSize = 0x1000, pageSize = 0x100;\r
+       UINT32 resStartAddr, resEndAddr;\r
+\r
+       UINT32 resSize, residue;\r
+       \r
+#if 1 /* for 13M sensor IMX091 */\r
+       UINT32 resOffset = 0x7000;\r
+       UINT32 res3acaliSize = 528;\r
+       UINT32 resLscSize = ((3560+15)>>4)<<4;\r
+       UINT32 resLscDqSize = ((13276+15)>>4)<<4;\r
+#else /* for 8M sensor IMX175 */\r
+       UINT32 resOffset = 0x5000;\r
+       UINT32 res3acaliSize = 528;\r
+       UINT32 resLscSize = ((2292+15)>>4)<<4;\r
+       UINT32 resLscDqSize = ((8521+15)>>4)<<4;\r
+#endif\r
+\r
+       UINT32 startSector, finalSector, sectorCount;\r
+\r
+       UINT8* pBuf;\r
+       \r
+       if( resId > 0x02 )\r
+       {\r
+               printk(" ID ERROR \n");\r
+               return FAIL;\r
+       }\r
+\r
+       I2C_SPIInit();\r
+\r
+       spiId = I2C_SPIFlashReadId();\r
+       if( spiId == 0 )\r
+       {\r
+               printk("read id failed\n");\r
+               return FAIL;\r
+       }\r
+       /*printk("spiSize:0x%x\n",&spiSize);*/\r
+       spiType = BB_SerialFlashTypeCheck(spiId, &spiSize);\r
+       \r
+       if( resId == 0x00 )/* 3ACALI.BIN */\r
+       {\r
+               resStartAddr = spiSize - resOffset;\r
+               resEndAddr = resStartAddr + res3acaliSize;\r
+               resSize = res3acaliSize;\r
+       }\r
+       else if( resId == 0x01 )/* LSC.BIN */\r
+       {\r
+               resStartAddr = spiSize - resOffset + res3acaliSize;\r
+               resEndAddr = resStartAddr + resLscSize;\r
+               resSize = resLscSize;\r
+       }\r
+       else /* LSC_DQ.BIN */\r
+       {\r
+               resStartAddr = spiSize -resOffset + res3acaliSize + resLscSize;\r
+               resEndAddr = resStartAddr + resLscDqSize;\r
+               resSize = resLscDqSize;\r
+       }\r
+       printk("%x %x %x\n", resStartAddr, resEndAddr, resSize);\r
+\r
+       startSector = (resStartAddr/sectorSize)*sectorSize;\r
+       finalSector = (resEndAddr/sectorSize)*sectorSize;\r
+       sectorCount = ((finalSector - startSector)/sectorSize) + 1;\r
+       residue = resStartAddr - startSector;\r
+\r
+       pBuf = osMemAlloc( sectorCount * sectorSize );\r
+       printk("%x %x %x %x\n", startSector, finalSector, sectorCount, residue);\r
+       \r
+       I2C_SPIFlashRead_DMA(startSector,(sectorCount*sectorSize),pBuf);\r
+\r
+       memcpy((pBuf+residue), resBuf, resSize);\r
+\r
+       if( spiType == 2 )\r
+       {\r
+               for( i=0; i<sectorCount; i++ )\r
+               {\r
+                       I2C_SPISectorErase((startSector+(i*sectorSize)),0);\r
+               }\r
+       }\r
+       else if( spiType == 1 || spiType == 3 )\r
+       {\r
+               for( i=0; i<sectorCount; i++ )\r
+               {\r
+                       I2C_SPISectorErase((startSector+(i*sectorSize)),1);\r
+               }\r
+       }\r
+       tmrUsWait(0x100);\r
+       printk("pBuf:%x %x\n",pBuf,resBuf);\r
+       I2C_SPIFlashWrite_DMA( startSector/pageSize, (sectorCount * sectorSize)/pageSize, 0, pBuf );\r
+\r
+       osMemFree( pBuf );\r
+\r
+       return SUCCESS;\r
+}\r
+\r
+/*-------------------------------------------------------------------------------------------------- \r
+       BB_I2CCalibResRead: used for read calibration data \r
+       resId: resource ID (0: 3ACALI.BIN, 1:LSC.BIN, 2:LSC_DQ.BIN )\r
+       size: return resource size\r
+       bufAddr: return buffer address\r
+---------------------------------------------------------------------------------------------------*/\r
+UINT32\r
+BB_I2CCalibResRead(\r
+       UINT32 resId,\r
+       UINT32* size,\r
+       UINT32* bufAddr\r
+)\r
+{\r
+       UINT32 i;\r
+       UINT32 spiId, spiType;\r
+       UINT32 spiSize, sectorSize = 0x1000, pageSize = 0x100;\r
+       UINT32 resStartAddr, resEndAddr;\r
+\r
+       UINT32 resSize, residue;\r
+#if 1 /* for 13M sensor IMX091 */\r
+       UINT32 resOffset = 0x7000;\r
+       UINT32 res3acaliSize = 520;\r
+       UINT32 resLscSize = 3560; \r
+       UINT32 resLscDqSize = 13276; \r
+#else /* for 8M sensor IMX175 */\r
+       UINT32 resOffset = 0x5000;\r
+       UINT32 res3acaliSize = 520;\r
+       UINT32 resLscSize = 2292; \r
+       UINT32 resLscDqSize = 8521; \r
+#endif\r
+\r
+       UINT8* pBuf;\r
+\r
+       UINT32 startSector, finalSector, sectorCount;\r
+       \r
+       if( resId > 0x02 )\r
+       {\r
+               printk(" ID ERROR \n");\r
+               return FAIL;\r
+       }\r
+\r
+       I2C_SPIInit();\r
+\r
+       spiId = I2C_SPIFlashReadId();\r
+       if( spiId == 0 )\r
+       {\r
+               printk("read id failed\n");\r
+               return FAIL;\r
+       }\r
+       /*printk("spiSize:0x%x\n",&spiSize);*/\r
+       spiType = BB_SerialFlashTypeCheck(spiId, &spiSize);\r
+       \r
+       if( resId == 0x00 )/* 3ACALI.BIN */\r
+       {\r
+               resStartAddr = spiSize - resOffset;\r
+               resSize = res3acaliSize;\r
+       }\r
+       else if( resId == 0x01 )/* LSC.BIN */\r
+       {\r
+               resStartAddr = spiSize - resOffset + (((res3acaliSize+0x0f)>>4)<<4);\r
+               resSize = resLscSize;\r
+       }\r
+       else /* LSC_DQ.BIN */\r
+       {\r
+               resStartAddr = spiSize -resOffset + (((res3acaliSize+0x0f)>>4)<<4) \r
+                                                                                 + (((resLscSize+0x0f)>>4)<<4);\r
+               resSize = resLscDqSize;\r
+       }\r
+       /*printk("%x %x\n", resStartAddr, resSize);*/\r
+\r
+       /* buffer used to stored calibration data */\r
+       pBuf = osMemAlloc( resSize );\r
+       printk("pBuf resSize:%x %x\n", pBuf, resSize);\r
+       \r
+       I2C_SPIFlashRead_DMA(resStartAddr,resSize,pBuf);\r
+       *bufAddr = pBuf;\r
+       printk("pBuf resSize:%x %x\n", (*bufAddr), resSize);\r
+\r
+       *size = resSize;\r
+\r
+       return SUCCESS;\r
+}\r
diff --git a/drivers/media/video/icatch7002/icatch7002_common.c b/drivers/media/video/icatch7002/icatch7002_common.c
new file mode 100755 (executable)
index 0000000..0639212
--- /dev/null
@@ -0,0 +1,2548 @@
+#define __ICATCH7002_COMMON_CFILE__
+#include "icatch7002_common.h"
+#include <linux/proc_fs.h>
+#include <mach/iomux.h>
+
+#define CONFIG_SENSOR_I2C_SPEED        300000           /* 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_NAME_STRING() sensor->dev_name
+
+
+#define ICATCHFWNAME "icatch7002boot.bin"
+
+u8 g_Calibration_Option_Def = 0xff;
+bool IsZSL = FALSE;
+
+#ifdef CALIBRATION_MODE_FUN
+struct icatch_cali_fw_data {
+       const char * const fname_option;
+       struct firmware const*fw_option;
+       const char * const fname_3acali;
+       struct firmware const*fw_3acali;
+       const char * const fname_lsc;
+       struct firmware const*fw_lsc;
+       const char * const fname_lscdq;
+       struct firmware const*fw_lscdq;
+};
+
+struct icatch_cali_fw_data g_cali_fw_data_front = {
+       .fname_option = "icatch7002/calibration_option.BIN",
+       .fname_3acali = "icatch7002/3ACALI_F.BIN",
+       .fname_lsc = "icatch7002/LSC_F.BIN",
+       .fname_lscdq = "icatch7002/LSC_DQ_F.BIN",
+};
+
+struct icatch_cali_fw_data g_cali_fw_data_back = {
+       .fname_option = "icatch7002/calibration_option.BIN",
+       .fname_3acali = "icatch7002/3ACALI.BIN",
+       .fname_lsc = "icatch7002/LSC.BIN",
+       .fname_lscdq = "icatch7002/LSC_DQ.BIN",
+};
+#endif
+
+#define ICATCH_BOOT_FROM_SPI 0
+#define ICATCH_BOOT_FROM_HOST 1
+#define ICATCH_BOOT ICATCH_BOOT_FROM_HOST
+#define ASUS_CAMERA_SUPPORT 1
+
+#ifndef FAIL
+#define FAIL   0
+#endif
+#ifndef TRUE
+#define TRUE   1
+#endif
+#ifndef FALSE
+#define FALSE  0
+#endif
+
+#if 1
+
+static struct rk_sensor_reg rs_reset_data[]={
+       {0x1011,0x01},
+       {0x001c,0x08},
+       {0x001c,0x00},
+       {0x1010,0x02},
+       {0x1010,0x00},
+       {0x1306,0x00},//0 rear,1 front
+       {0x1011,0x00},
+       SensorEnd
+};
+
+static struct rk_sensor_reg fs_reset_data[]={
+       {0x1011,0x01},
+       {0x001c,0x08},
+       {0x001c,0x00},
+       {0x1010,0x02},
+       {0x1010,0x00},
+       {0x1306,0x01},//0 rear,1 front
+       {0x1011,0x00},
+       SensorEnd
+};
+
+static struct rk_sensor_reg init_data[]={
+       {SP7K_MSG_COLOR_EFFECT,         0x0}, // normal
+       {SP7K_MSG_EV_COMPENSATION,      0x6}, // 0
+       {SP7K_MSG_FLASH_MODE,           0x1}, // off
+       {SP7K_MSG_FOCUS_MODE,           0x0}, // auto
+       {SP7K_MSG_PV_SIZE,                      0x0}, // 1280*960
+       {SP7K_MSG_SCENE_MODE,           0x0}, // normal
+       {SP7K_MSG_WHITE_BALANCE,        0x0}, // auto
+       {SP7K_MSG_CAP_ISO,                      0x0}, //auto
+       {SP7K_MSG_AURA_COLOR_INDEX, 0x0}, // disable
+       {SP7K_MSG_PV_CAP_MODE,          0x4}, // idle
+       SensorEnd
+};
+#endif
+
+struct i2c_client *g_icatch_i2c_client = NULL;
+#if CONFIG_SENSOR_WhiteBalance
+static int icatch_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));
+       u8 set_val = 0;
+    struct generic_sensor*sensor = to_generic_sensor(client);
+
+       DEBUG_TRACE("%s: value = %d\n", __FUNCTION__, value);
+
+       if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+       {
+               switch(value){
+                       case 0: //enable auto
+                               set_val = 0x0;
+                               break;
+                       case 1: //incandescent          Tungsten
+                               set_val = 0x6;
+                               break;
+                       case 2: //fluorescent
+                               set_val = 0x5;
+                               break;
+                       case 3: //daylight
+                               set_val = 0x1;
+                               break;
+                       case 4: //cloudy-daylight
+                               set_val = 0x2;
+                               break;
+                       default:
+                               break;
+               }
+               //awb
+               EXISP_I2C_WhiteBalanceSet(set_val);
+               return 0;
+       }
+       DEBUG_TRACE("\n %s..%s valure = %d is invalidate..      \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+       return -1;
+}
+#endif
+
+#if CONFIG_SENSOR_Effect
+static int icatch_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value, int auravalue)
+{
+       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+       u8 set_val = 0;
+    struct generic_sensor*sensor = to_generic_sensor(client);
+       DEBUG_TRACE("set effect,value = %d ......\n",value);
+       if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+       {
+               switch(value){
+                       case 0: //normal
+                       case 5: //none
+                               set_val = 0x00;
+                               break;
+                       case 1: //aqua
+                               set_val = 0x01;
+                               break;
+                       case 2: //negative
+                               set_val = 0x02;
+                               break;
+                       case 3: //sepia
+                               set_val = 0x03;
+                               break;
+                       case 4: //mono  Grayscale
+                               set_val = 0x04;
+                               break;
+                       case 6: //aura
+                               set_val = 0x06;
+                               break;
+                       case 7: //vintage
+                               set_val = 0x07;
+                               break;
+                       case 8: //vintage2
+                               set_val = 0x08;
+                               break;
+                       case 9: //lomo
+                               set_val = 0x09;
+                               break;
+                       case 10: //red
+                               set_val = 0x0A;
+                               break;
+                       case 11: //blue
+                               set_val = 0x0B;
+                               break;
+                       case 12: //green
+                               set_val = 0x0C;
+                               break;
+                       default:
+                               set_val = value;
+                               break;
+               }
+               EXISP_I2C_ColorEffectSet(set_val);
+               if(set_val == 6){
+                       EXISP_I2C_AuraColorIndexSet(auravalue);
+               }
+               return 0;
+       }
+       DEBUG_TRACE("\n%s..%s valure = %d is invalidate..    \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+       return -1;
+}
+#endif
+
+#if CONFIG_SENSOR_Scene
+static int icatch_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));
+       u8 set_val = 0;
+    struct generic_sensor*sensor = to_generic_sensor(client);
+//when scene mod is working , face deteciton and awb and iso are not recomemnded.
+       if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+       {
+               switch(value){
+                       case 0: //normal
+                               set_val = 0x00;
+                               break;
+                       case 1: //auto
+                               set_val = 0x00;
+                               break;
+                       case 2: //landscape
+                               set_val = 0x10;
+                               break;
+                       case 3: //night
+                               set_val = 0x07;
+                               break;
+                       case 4: //night_portrait
+                               set_val = 0x08;
+                               break;
+                       case 5: //snow
+                               set_val = 0x0B;
+                               break;
+                       case 6: //sports
+                               set_val = 0x0C;
+                               break;
+                       case 7: //candlelight
+                               set_val = 0x04;
+                               break;
+
+                       default:
+                               break;
+               }
+
+               EXISP_I2C_SceneModeSet(set_val);
+               DEBUG_TRACE("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+               return 0;
+       }
+       DEBUG_TRACE("\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));
+       u8 set_val = 0x0;
+    struct generic_sensor*sensor = to_generic_sensor(client);
+       if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+       {
+               set_val = 6 - value;
+               EXISP_I2C_EvSet(set_val);
+               DEBUG_TRACE("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+               return 0;
+       }
+       DEBUG_TRACE("\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));
+       return 0;
+}
+#endif
+
+#if CONFIG_SENSOR_Flip
+//off 0x00;mirror 0x01,flip 0x10;
+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));
+       return 0;
+
+}
+#endif
+
+#if CONFIG_SENSOR_ISO
+static int sensor_set_iso(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+{
+       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+       u8 set_val = 0x0;
+    struct generic_sensor*sensor = to_generic_sensor(client);
+       if ((value >= qctrl->minimum) && (value <= qctrl->maximum))
+       {
+               set_val = value;
+               EXISP_I2C_ISOSet(set_val);
+               DEBUG_TRACE("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);
+               return 0;
+       }
+       DEBUG_TRACE("\n %s..%s valure = %d is invalidate..      \n",SENSOR_NAME_STRING(),__FUNCTION__,value);
+       return -EINVAL;
+}
+#endif
+void __dump_i2c(UINT16 addr_s, UINT16 addr_e);
+static void sensor_interrupt_wait_clear()
+{
+       int loop_cnt = 0;
+       
+       printk("sensor_interrupt_wait_clear() Entry\n");
+       while((icatch_sensor_read(SP7K_RDREG_INT_STS_REG_0) & 0x04) == 0){
+               msleep(10);
+               if(loop_cnt++ == 100){
+                       __dump_i2c(0x7200,0x727F);
+                       __dump_i2c(0x7072,0x7075);
+                       __dump_i2c(0x72F8,0x72F8);
+                       __dump_i2c(0x7005,0x7006);
+               }
+       }
+       icatch_sensor_write(SP7K_RDREG_INT_STS_REG_0,(icatch_sensor_read(SP7K_RDREG_INT_STS_REG_0)|0x04));
+       printk("sensor_interrupt_wait_clear() Exit\n");
+}
+
+#if CONFIG_SENSOR_Wdr
+// EXISP_I2C_IspFuncSet(), bit 0 : DWDR
+static void sensor_set_wdr(bool Enable)
+{
+       if(Enable){
+               EXISP_I2C_IspFuncSet( icatch_sensor_read(SP7K_REG_BASE|(SP7K_MSG_ISP_FUNCTION&0x7F)) | 0x01);
+       }else{
+               EXISP_I2C_IspFuncSet( icatch_sensor_read(SP7K_REG_BASE|(SP7K_MSG_ISP_FUNCTION&0x7F)) &~0x01);
+       }
+}
+#endif
+
+#if CONFIG_SENSOR_EDGE
+static void sensor_set_edge(bool Enable)
+{
+       if(Enable){
+               EXISP_I2C_IspFuncSet( icatch_sensor_read(SP7K_REG_BASE|(SP7K_MSG_ISP_FUNCTION&0x7F)) | 0x02);
+       }else{
+               EXISP_I2C_IspFuncSet( icatch_sensor_read(SP7K_REG_BASE|(SP7K_MSG_ISP_FUNCTION&0x7F)) &~0x02);
+       }
+}
+#endif
+
+
+static int icatch_sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
+{
+       return 0;
+}
+static int icatch_sensor_resume(struct soc_camera_device *icd)
+{
+       return 0;
+
+}
+static int icatch_sensor_set_bus_param(struct soc_camera_device *icd,
+                                                               unsigned long flags)
+{
+
+       return 0;
+}
+
+
+#if CALIBRATION_MODE_FUN
+struct proc_dir_entry *g_icatch7002_proc_entry = NULL;
+#define PROC_ENTRY_NAME        SENSOR_NAME_STRING()
+int g_is_calibrationMode = 0;
+char g_procbuff[1024];
+union icatch_fw_version {
+       __u32 fw;
+       struct {
+               __u8 b1;
+               __u8 b2;
+               __u8 b3;
+               __u8 b4;
+       };
+} g_fw_version;
+int icatch_proc_read(char *page, char **start, off_t off,
+                         int count, int *eof, void *data)
+{
+       int len = 0;
+       if (off > 0) {
+               *eof = 1;
+               return 0;
+       }
+
+       len = sprintf(page, "fw %02x.%02x.%02x\nis_calibration %d\n",
+                       g_fw_version.b3, g_fw_version.b2, g_fw_version.b1,
+                       g_is_calibrationMode);
+       return len;
+}
+
+int icatch_proc_write(struct file *file, const char __user *buffer,
+                          unsigned long count, void *data)
+{
+       char *ptr = NULL;
+       if (count >= sizeof(g_procbuff)) {
+               DEBUG_TRACE("%s no space\n", __FUNCTION__);
+               return -ENOSPC;
+       }
+
+       if (copy_from_user(g_procbuff, buffer, count)) {
+               DEBUG_TRACE("%s copy from user fail %d\n", __FUNCTION__, count);
+               return -EFAULT;
+       }
+       g_procbuff[count] = 0;
+
+       if ( (ptr = strstr(g_procbuff, "is_calibration")) == NULL) {
+               goto l_ret;
+       }
+
+       ptr += strlen("is_calibration");
+       while(*ptr == ' ' || *ptr == '\t' || *ptr == '\n' || *ptr == '\r') {
+               ptr++;
+       }
+
+       switch (*ptr) {
+       case '0':
+               g_is_calibrationMode = 0;
+               DEBUG_TRACE("%s disable calibration mode\n", __FUNCTION__);
+               break;
+       case '1':
+               g_is_calibrationMode = 1;
+               DEBUG_TRACE("%s enable calibration mode\n", __FUNCTION__);
+               break;
+       }
+
+l_ret:
+       return count;
+}
+
+void icatch_create_proc_entry()
+{
+    struct generic_sensor*sensor = to_generic_sensor(g_icatch_i2c_client);
+
+       if (g_icatch7002_proc_entry == NULL) {
+               DEBUG_TRACE("%s need create_proc_entry\n", __FUNCTION__);
+               g_fw_version.fw = 0;
+               g_icatch7002_proc_entry = create_proc_entry(PROC_ENTRY_NAME, O_RDWR, NULL);
+               if (g_icatch7002_proc_entry) {
+                       memset(g_procbuff, 0, sizeof(g_procbuff));
+                       g_icatch7002_proc_entry->read_proc = icatch_proc_read;
+                       g_icatch7002_proc_entry->write_proc = icatch_proc_write;
+               } else {
+                       DEBUG_TRACE("%s create_proc_entry fail\n", __FUNCTION__);
+               }
+       }
+}
+
+void icatch_remove_proc_entry()
+{
+    struct generic_sensor*sensor = to_generic_sensor(g_icatch_i2c_client);
+       if (g_icatch7002_proc_entry != NULL) {
+               remove_proc_entry(PROC_ENTRY_NAME, NULL);
+               g_icatch7002_proc_entry = NULL;
+       }
+}
+#endif
+
+#if 1//CONFIG_SENSOR_Focus
+
+void __dump_i2c(UINT16 addr_s, UINT16 addr_e) {
+       int size = (addr_e - addr_s + 1);
+       int i = 0;
+       int soffset = addr_s%16;
+       char buf[100] = {0};
+       char lbuf[12];
+
+       for (i = 0; i < soffset; i++) {
+               if (i == 0) {
+                       sprintf(lbuf, "%08X:", addr_s / 16 * 16);
+                       strcat(buf, lbuf);
+               }
+               sprintf(lbuf, "   ");
+               strcat(buf, lbuf);
+       }
+
+       size += soffset;
+       i = soffset;
+       while( i < size) {
+               if ((i%16 == 0) && (i != 0)) {
+                       printk("%s\n", buf);
+               }
+               if (i%16 == 0) {
+                       buf[0] = 0;
+                       sprintf(lbuf, "%08X:", (addr_s + i - soffset) / 16 * 16);
+                       strcat(buf, lbuf);
+               }
+               sprintf(lbuf, " %02X", icatch_sensor_read(addr_s + i - soffset));
+               strcat(buf, lbuf);
+               i++;
+       }
+
+       printk("%s\n", buf);
+}
+
+static void icatch_mapping_zone(const char * tag, struct rk_sensor_focus_zone *dst, const int *rect)
+{
+       DEBUG_TRACE("%s: %s set from (%d, %d), (%d, %d)\n",
+                       __FUNCTION__, tag,
+                       dst->lx, dst->ty,
+                       dst->rx, dst->dy);
+
+       dst->lx = ((rect[0] + 1000) * 1024)/2001;
+       dst->ty = ((rect[1] + 1000) * 1024)/2001;
+       dst->rx = ((rect[2] + 1000) * 1024)/2001;
+       dst->dy = ((rect[3] + 1000) * 1024)/2001;
+
+       DEBUG_TRACE("%s: %s to (%d, %d), (%d, %d)\n",
+                       __FUNCTION__, tag,
+                       dst->lx, dst->ty,
+                       dst->rx, dst->dy);
+}
+
+//value: disable metering area
+//force_set: if not set, it will not drive the sensor
+//                     to set metering area really if focus is
+//                     supported.
+//rect: set to NULL if don't want to change.
+static int icatch_set_metering_zone(
+               struct specific_sensor *sensor,
+               __s32 value,
+               rk_sensor_tae_zone zone,
+               int force_set)
+{
+       int ret = 0, w = 0, iret = 0;
+
+       if ( sensor->isp_priv_info.MeteringAreas != value) {
+               DEBUG_TRACE("%s set metering areas to %d\n",
+                                       __FUNCTION__,
+                                       value);
+       }
+
+       if (value == 0) {
+               if (sensor->isp_priv_info.MeteringAreas > 0) {
+                       if ( EXISP_TAFTAEROISet(
+                                       TAFTAE_TAE_OFF,
+                                       0,0,0,0,0,0 ) != SUCCESS)
+                       {
+                               ret = -EINVAL;
+                       }
+               }
+               sensor->isp_priv_info.MeteringAreas = value;
+               return ret;
+       }
+
+       sensor->isp_priv_info.MeteringAreas = value;
+
+       if (force_set) {
+               goto f_set;
+       }
+
+       if (sensor_find_ctrl(sensor->common_sensor.ctrls, V4L2_CID_FOCUS_AUTO) ||
+               sensor_find_ctrl(sensor->common_sensor.ctrls, V4L2_CID_FOCUS_CONTINUOUS) ||
+               sensor_find_ctrl(sensor->common_sensor.ctrls, V4L2_CID_FOCUS_ABSOLUTE) ) {
+                       return ret;
+       }
+
+f_set:
+       //set TAE if focus is not supported
+
+       w = sensor->isp_priv_info.tae_zone.rx - sensor->isp_priv_info.tae_zone.lx;
+       if (w < 0) {
+               w = -w;
+       }
+
+       DEBUG_TRACE("%s: set TAE zone to (%d, %d), (%d, %d)\n",
+                       __FUNCTION__,
+                       sensor->isp_priv_info.tae_zone.lx,
+                       sensor->isp_priv_info.tae_zone.ty,
+                       sensor->isp_priv_info.tae_zone.rx,
+                       sensor->isp_priv_info.tae_zone.dy);
+
+       if (w == 0) {
+               iret = EXISP_TAFTAEROISet(TAFTAE_TAE_ONLY, 0, 0, 0, 0x80, 0x1bf, 0x1bf);
+       } else {
+               iret = EXISP_TAFTAEROISet(
+                               TAFTAE_TAE_ONLY,
+                               0, 0, 0,
+                               w,
+                               sensor->isp_priv_info.tae_zone.lx,
+                               sensor->isp_priv_info.tae_zone.ty);
+       }
+
+       if (iret != SUCCESS) {
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+int icatch_sensor_set_auto_focus(struct i2c_client *client, int value,int *tmp_zone)
+{
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+
+       //u8 zone_x = 0x0,zone_y = 0x0; // 0->0x0f
+       UINT16 w = 0;
+       int ret = 0;
+       int cnt = 100;
+       int set_val;
+
+       ret = icatch_set_metering_zone(
+                       sensor,
+                       sensor->isp_priv_info.MeteringAreas,
+                       sensor->isp_priv_info.tae_zone,
+                       1);
+       if (ret) {
+               return ret;
+       }
+
+    if(value == WqCmd_af_single)
+        set_val = 0;
+    else if(value == WqCmd_af_update_zone){
+        icatch_mapping_zone(
+                       "focus zone",
+                       &sensor->isp_priv_info.focus_zone,
+                       tmp_zone);
+        return 0;
+    
+    }else if(value == WqCmd_af_continues)
+        set_val = 3;
+    else{
+
+    }
+    
+       EXISP_I2C_FocusModeSet(set_val);
+
+       //EXISP_I2C_AFROITriggerSet();
+       if (value != WqCmd_af_far_pos) {
+               //EXISP_I2C_ROISwitchSet(01);
+               //set the zone
+               DEBUG_TRACE("%s: lx = %d,rx = %d,ty = %d,dy = %d\n", __FUNCTION__, sensor->isp_priv_info.focus_zone.lx,sensor->isp_priv_info.focus_zone.rx,sensor->isp_priv_info.focus_zone.ty,sensor->isp_priv_info.focus_zone.dy);
+               w = sensor->isp_priv_info.focus_zone.rx - sensor->isp_priv_info.focus_zone.lx;
+               //zone_x = (sensor->isp_priv_info.focus_zone.lx << 4) | (sensor->isp_priv_info.focus_zone.rx & 0x0f);
+               //zone_y = (sensor->isp_priv_info.focus_zone.ty << 4) | (sensor->isp_priv_info.focus_zone.dy & 0x0f);
+               //auto focus
+               //sendI2cCmd(client, 0x0E, 0x00);
+               if( w != 0) {
+                       EXISP_TAFTAEROISet(
+                                       TAFTAE_TAF_ONLY,
+                                       w,
+                                       sensor->isp_priv_info.focus_zone.lx,
+                                       sensor->isp_priv_info.focus_zone.ty,
+                                       0, 0, 0);
+                       DEBUG_TRACE("%s:auto focus, val = %d, w = 0x%x, x = 0x%x y = 0x%x\n",__func__,value, w, sensor->isp_priv_info.focus_zone.lx, sensor->isp_priv_info.focus_zone.ty);
+               }else{
+                       EXISP_TAFTAEROISet(TAFTAE_TAF_ONLY, 0x80, 0x1bf, 0x1bf, 0, 0, 0);
+                       DEBUG_TRACE("%s:auto focus, all zero, val = %d, size=0x80, x=0x1bf, y=0x1bf\n",__func__,value);
+               }
+       }
+
+       while (cnt--) {
+               if (EXISP_I2C_AFStatusGet() == 0) {
+                        break;
+               }
+               msleep(30);
+       }
+
+       //__dump_i2c(0x7200, 0x727f);
+
+       if (cnt <= 0) {
+               DEBUG_TRACE("%s: focus timeout %d\n",__func__, value);
+               //__dump_i2c(0x7005, 0x7005);
+               return 1;
+       }
+
+       if (EXISP_I2C_AFResultGet() != 0) {
+               DEBUG_TRACE("%s: focus fail %d\n",__func__, value);
+               return 1;
+       }
+
+       DEBUG_TRACE("%s: focus success %d\n\n",__func__, value);
+       return 0;
+}
+
+
+#endif
+
+int icatch_sensor_init(struct i2c_client *client)
+{
+       struct soc_camera_device *icd = client->dev.platform_data;
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+  //  struct isp_data * sensor = spnsor->isp_priv_info;
+       struct v4l2_queryctrl* qctrl;
+       int pid = 0;
+       u8 sensorid = 0;
+       char* sensorid_str = NULL;
+       struct sensor_v4l2ctrl_info_s* qctrl_info;
+
+       sensorid_str = strstr(dev_name(icd->pdev),"front");
+       if(sensorid_str)
+           sensorid = 1;
+        else
+           sensorid = 0;
+
+#if CALIBRATION_MODE_FUN
+       if (g_is_calibrationMode == 1 ) {
+               if (sensorid == SENSOR_ID_REAR)
+                       sensorid = SENSOR_ID_REAR_CALIBRATION;
+
+               DEBUG_TRACE("%s CALIBRATION MODE is enable, SENSOR_ID:%d\n", __FUNCTION__, sensorid);
+       }
+       sensor->isp_priv_info.sensor_id = sensorid;
+#endif
+
+       DEBUG_TRACE("@@NY@@%s: %d\n", __FUNCTION__, sensorid);
+       sensor->isp_priv_info.curRes = -1;
+       sensor->isp_priv_info.curPreviewCapMode = IDLE_MODE;
+       sensor->isp_priv_info.had_setprvsize = 0;
+       sensor->isp_priv_info.hdr = false;
+
+#if CALIBRATION_MODE_FUN
+       sensor->isp_priv_info.rk_query_PreviewCapMode = IDLE_MODE;
+#endif
+       g_icatch_i2c_client = client;
+
+
+#if 0
+               //get id check
+{
+       int count = 200;
+               while(count--){
+               pid = icatch_sensor_read(0x0004);
+               DEBUG_TRACE("\n %s      pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+               mdelay(1000);
+               }
+}
+#endif
+
+       if(icatch_load_fw(icd,sensorid)<0){
+               DEBUG_TRACE("icatch7002 load sensor %d firmware failed!!-->%s:%d\n",sensorid, __FUNCTION__, __LINE__);
+               return -ENODEV;
+       }
+#if 0
+       if(sensorid == SENSOR_ID_FRONT){
+               // front camera
+               icatch_sensor_write_array((void*)fs_reset_data);
+       }
+       else{
+               // rear camera
+               icatch_sensor_write_array((void*)rs_reset_data);
+       }
+
+       //50Hz
+       EXISP_I2C_BandSelectionSet(0x01);
+       //DEBUG_TRACE("%s Set BandSelection to 50Hz\n", __FUNCTION__);
+
+       //get id check
+       mdelay(100);
+       pid = EXISP_I2C_RearSensorIdGet();
+       DEBUG_TRACE("\n %s  pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+       if (pid != SENSOR_ID) {
+               DEBUG_TRACE("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+               return -ENODEV;
+       }
+#endif
+
+       //50Hz
+       EXISP_I2C_BandSelectionSet(0x01);
+       /* sensor sensor information for initialization  */
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_DO_WHITE_BALANCE);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.whiteBalance = qctrl->default_value;
+
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_BRIGHTNESS);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.brightness = qctrl->default_value;
+
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_EFFECT);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.effect = qctrl->default_value;
+
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_EXPOSURE);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl){
+               sensor->isp_priv_info.exposure = qctrl->default_value;
+               }
+
+
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_SATURATION);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.saturation = qctrl->default_value;
+
+               
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_CONTRAST);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.contrast = qctrl->default_value;
+
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_HFLIP);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.mirror = qctrl->default_value;
+
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_VFLIP);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.flip = qctrl->default_value;
+
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_SCENE);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl){
+               sensor->isp_priv_info.scene = qctrl->default_value;
+               }
+#if    CONFIG_SENSOR_AntiBanding
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_ANTIBANDING);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+        sensor->isp_priv_info.antibanding = qctrl->default_value;
+#endif
+#if CONFIG_SENSOR_WhiteBalanceLock
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_WHITEBALANCE_LOCK);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+        sensor->isp_priv_info.WhiteBalanceLock = qctrl->default_value;
+#endif
+#if CONFIG_SENSOR_ExposureLock
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_EXPOSURE_LOCK);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+        sensor->isp_priv_info.ExposureLock = qctrl->default_value;
+#endif
+#if CONFIG_SENSOR_MeteringAreas
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_METERING_AREAS);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+        sensor->isp_priv_info.MeteringAreas = qctrl->default_value;
+#endif
+#if CONFIG_SENSOR_Wdr
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_WDR);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+        sensor->isp_priv_info.Wdr = qctrl->default_value;
+#endif
+#if CONFIG_SENSOR_EDGE
+       sensor_set_edge(1);
+#endif
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_ZOOM_ABSOLUTE);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.digitalzoom = qctrl->default_value;
+       /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code  */
+       //qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_AUTO);
+#if 0
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_FOCUS_AUTO);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.auto_focus = SENSOR_AF_AUTO;
+
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_FACEDETECT);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.face = qctrl->default_value;
+#endif
+#if CONFIG_SENSOR_ISO
+       qctrl_info =sensor_find_ctrl(sgensor->ctrls, V4L2_CID_ISO);
+       if(qctrl_info)
+       qctrl = qctrl_info->qctrl;
+       if (qctrl)
+               sensor->isp_priv_info.iso = qctrl->default_value;
+#endif
+       return 0;
+}
+
+
+
+/* sensor register read */
+static int icatch_sensor_burst_read( u16 reg, u16 len, __u8 *buffer)
+{
+    struct generic_sensor*sensor = to_generic_sensor(g_icatch_i2c_client);
+
+       int err,cnt;
+       u8 buf[2];
+       struct i2c_msg msg[2];
+       struct i2c_client* client =g_icatch_i2c_client;
+
+       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 = buffer;
+       msg[1].len = len;
+       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[0], 1);
+
+               if (err >= 0) {
+                       break;
+               } else {
+                       DEBUG_TRACE("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, buf[0]);
+                       udelay(10);
+               }
+       }
+
+       if(err <0)
+               return -FAIL;
+
+       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], 1);
+
+               if (err >= 0) {
+                       break;
+               } else {
+                       DEBUG_TRACE("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, buf[0]);
+                       udelay(10);
+               }
+       }
+       if(err >=0)
+               return 0;
+       else
+               return -FAIL;
+}
+
+struct icatch_dumpreg_dsc {
+       __u16 addr;
+       __u16 len;
+       unsigned long user_ptr;
+};
+
+static int icatch_dump_regs(void __user * arg)
+{
+       int err, ret = 0;
+       struct icatch_dumpreg_dsc dsc;
+       __u8 *buf = NULL;
+
+       err = !access_ok(VERIFY_READ,
+                       (void __user *)arg, sizeof(struct icatch_dumpreg_dsc));
+
+       if (err) {
+               DEBUG_TRACE("%s(%d) error to access argument\n",
+                       __FUNCTION__, __LINE__);
+               return -EACCES;
+       }
+
+       if (copy_from_user(
+               &dsc, arg,
+               sizeof(struct icatch_dumpreg_dsc))) {
+               return -EFAULT;
+       }
+
+       if (dsc.len == 0) {
+               DEBUG_TRACE("%s length is 0\n", __FUNCTION__);
+               return -EINVAL;
+       }
+
+       DEBUG_TRACE("%s add=0x%04x len=%d\n",
+                       __FUNCTION__,
+                       dsc.addr, dsc.len);
+
+       if ( !access_ok(VERIFY_WRITE,
+               (void __user *)dsc.user_ptr, dsc.len)) {
+               DEBUG_TRACE("%s(%d) error to access user_ptr\n",
+                       __FUNCTION__, __LINE__);
+               return -EACCES;
+       }
+
+       buf = kmalloc( dsc.len, GFP_KERNEL);
+       if (buf == NULL) {
+               return -ENOMEM;
+       }
+
+       //dump
+       ret = icatch_sensor_burst_read(dsc.addr, dsc.len, buf);
+       if (ret < 0) {
+               DEBUG_TRACE("%s(%d) error read these regs\n",
+                       __FUNCTION__, __LINE__);
+               goto l_exit;
+       }
+
+
+       if (copy_to_user(dsc.user_ptr, buf, dsc.len)) {
+               DEBUG_TRACE("%s(%d) fail to copy to user_ptr\n",
+                       __FUNCTION__, __LINE__);
+               ret = -EFAULT;
+               goto l_exit;
+       }
+
+l_exit:
+       if (buf != NULL)
+               kfree(buf);
+       DEBUG_TRACE("%s(%d) return value %d\n",
+                       __FUNCTION__, __LINE__,
+                       ret);
+       return ret;
+}
+
+static int icatch_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl,struct v4l2_queryctrl *qctrl)
+{
+       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+       int ret = 0;
+
+       switch (ext_ctrl->id)
+       {
+               case V4L2_CID_SCENE:
+                       {
+                               ext_ctrl->value = sensor->isp_priv_info.scene;
+                               break;
+                       }
+#if CONFIG_SENSOR_AntiBanding
+        case V4L2_CID_ANTIBANDING:
+            {
+                ext_ctrl->value = sensor->isp_priv_info.antibanding;
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_WhiteBalanceLock
+        case V4L2_CID_WHITEBALANCE_LOCK:
+            {
+                ext_ctrl->value = sensor->isp_priv_info.WhiteBalanceLock;
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_ExposureLock
+               case V4L2_CID_EXPOSURE_LOCK:
+            {
+                ext_ctrl->value = sensor->isp_priv_info.ExposureLock;
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_MeteringAreas
+               case V4L2_CID_METERING_AREAS:
+            {
+                ext_ctrl->value = sensor->isp_priv_info.MeteringAreas;
+                break;
+            }
+#endif
+#if CONFIG_SENSOR_Wdr
+               case V4L2_CID_WDR:
+                       {
+                               ext_ctrl->value = sensor->isp_priv_info.Wdr;
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_EDGE
+               case V4L2_CID_EDGE:
+                       {
+                               ext_ctrl->value = EXISP_I2C_CapEdgeInfoGet();
+                               break;
+                       }
+#endif
+               case V4L2_CID_EFFECT:
+                       {
+                               ext_ctrl->value = sensor->isp_priv_info.effect;
+                               break;
+                       }
+               case V4L2_CID_ZOOM_ABSOLUTE:
+                       {
+                               ext_ctrl->value = sensor->isp_priv_info.digitalzoom;
+                               break;
+                       }
+               case V4L2_CID_ZOOM_RELATIVE:
+                       {
+                               return -EINVAL;
+                       }
+               case V4L2_CID_FOCUS_ABSOLUTE:
+                       {
+                               return -EINVAL;
+                       }
+               case V4L2_CID_FOCUS_RELATIVE:
+                       {
+                               return -EINVAL;
+                       }
+               case V4L2_CID_FLASH:
+                       {
+                               ext_ctrl->value = sensor->isp_priv_info.flash;
+                               break;
+                       }
+               case V4L2_CID_FACEDETECT:
+                       {
+                               ext_ctrl->value =sensor->isp_priv_info.face ;
+                               break;
+                       }
+#if CONFIG_SENSOR_ISO
+               case V4L2_CID_ISO:
+               {
+                       ext_ctrl->value = sensor->isp_priv_info.iso;
+                       if(ext_ctrl->value == 0){
+                               ext_ctrl->value = icatch_sensor_read(SP7K_RDREG_ISO_H);
+                               ext_ctrl->value <<= 8;
+                               ext_ctrl->value |= icatch_sensor_read(SP7K_RDREG_ISO_L);
+                       }
+                       break;
+               }
+#endif
+#if CONFIG_SENSOR_JPEG_EXIF
+               case V4L2_CID_JPEG_EXIF:
+               {
+                       RkExifInfo *pExitInfo = (RkExifInfo *)ext_ctrl->value;
+
+                       UINT8 ucExpTimeNumerator;
+                       UINT32 ulExpTimeDenominator;
+                       UINT8 ucExpTimeCompensation;
+                       UINT16 usLensFocalLength;
+                       UINT16 usIsoInfo;
+                       UINT8 ucFlashInfo;
+
+                       EXISP_ExifInfoGet(
+                               &ucExpTimeNumerator,
+                               &ulExpTimeDenominator,
+                               &ucExpTimeCompensation,
+                               &usLensFocalLength,
+                               &usIsoInfo,
+                               &ucFlashInfo);
+
+                       pExitInfo->ExposureTime.num = ucExpTimeNumerator;
+                       pExitInfo->ExposureTime.denom = ulExpTimeDenominator;
+                       //pExitInfo->Flash = ucFlashInfo;
+                       pExitInfo->ISOSpeedRatings = usIsoInfo;
+                       pExitInfo->FocalPlaneYResolution.num = EXISP_I2C_CapEdgeInfoGet();
+                       pExitInfo->ExposureBiasValue.num = sensor->isp_priv_info.exposure ;
+                       pExitInfo->ExposureBiasValue.denom = 3;
+
+                       break;
+               }
+#endif
+
+#if CONFIG_SENSOR_DUMPREGS
+               case V4L2_CID_DUMPREGS:
+               {
+                       //static long icatch_dump_regs(void __user * arg);
+                       return icatch_dump_regs(ext_ctrl->string);
+               }
+#endif
+               default :
+                   ret = -1;
+                       break;
+       }
+       return ret;
+}
+
+
+static int icatch_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl,struct v4l2_queryctrl *qctrl)
+{
+       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+       int val_offset;
+       int ret = 0;
+
+       val_offset = 0;
+       switch (ext_ctrl->id)
+       {
+#if CONFIG_SENSOR_Scene
+               case V4L2_CID_SCENE:
+                       {
+                               if (ext_ctrl->value != sensor->isp_priv_info.scene)
+                               {
+                                       if (icatch_set_scene(icd, qctrl,ext_ctrl->value) != 0)
+                                               return -EINVAL;
+                                       sensor->isp_priv_info.scene = ext_ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_AntiBanding
+               case V4L2_CID_ANTIBANDING:
+                       {
+                               if (ext_ctrl->value != sensor->isp_priv_info.antibanding)
+                               {
+                                       if(ext_ctrl->value){
+                                               EXISP_I2C_BandSelectionSet(2);  //60Hz
+                                       }else{
+                                               EXISP_I2C_BandSelectionSet(1);  //50Hz
+                                       }
+                                       sensor->isp_priv_info.antibanding = ext_ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_WhiteBalanceLock
+               case V4L2_CID_WHITEBALANCE_LOCK:
+                       {
+                               if (ext_ctrl->value != sensor->isp_priv_info.WhiteBalanceLock)
+                               {
+                                       if(ext_ctrl->value){
+                                               EXISP_I2C_VendreqCmdSet(4);
+                                       }else{
+                                               EXISP_I2C_VendreqCmdSet(6);
+                                       }
+                                       sensor->isp_priv_info.WhiteBalanceLock = ext_ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_ExposureLock
+               case V4L2_CID_EXPOSURE_LOCK:
+                       {
+                               if (ext_ctrl->value != sensor->isp_priv_info.ExposureLock)
+                               {
+                                       if(ext_ctrl->value){
+                                               EXISP_I2C_VendreqCmdSet(3);
+                                       }else{
+                                               EXISP_I2C_VendreqCmdSet(5);
+                                       }
+                                       sensor->isp_priv_info.ExposureLock = ext_ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_MeteringAreas
+               case V4L2_CID_METERING_AREAS:
+                       {
+                               if (ext_ctrl->value) {
+                                       icatch_mapping_zone(
+                                               "metering zone",
+                                               &sensor->isp_priv_info.tae_zone,
+                                               ext_ctrl->rect);
+                               }
+                               ret = icatch_set_metering_zone(
+                                                       sensor,
+                                                       ext_ctrl->value,
+                                                       sensor->isp_priv_info.tae_zone,
+                                                       0);
+                               sensor->isp_priv_info.MeteringAreas = ext_ctrl->value;
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_Wdr
+               case V4L2_CID_WDR:
+                       {
+                               if (ext_ctrl->value != sensor->isp_priv_info.Wdr)
+                               {
+                                       sensor_set_wdr(ext_ctrl->value);
+                                       sensor->isp_priv_info.Wdr = ext_ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_Effect
+               case V4L2_CID_EFFECT:
+                       {
+                               if (ext_ctrl->value != sensor->isp_priv_info.effect)
+                               {
+                                       if (icatch_set_effect(icd, qctrl,ext_ctrl->value,ext_ctrl->rect[0]) != 0)
+                                               return -EINVAL;
+                                       sensor->isp_priv_info.effect= ext_ctrl->value;
+                               }
+                               if(sensor->isp_priv_info.effect == 6)
+                               {
+                                       EXISP_I2C_AuraColorIndexSet(ext_ctrl->rect[0]);
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+               case V4L2_CID_ZOOM_ABSOLUTE:
+                       {
+                               DEBUG_TRACE("V4L2_CID_ZOOM_ABSOLUTE ...... ext_ctrl->value = %d\n",ext_ctrl->value);
+                               if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)){
+                                       return -EINVAL;
+                               }
+
+                               if (ext_ctrl->value != sensor->isp_priv_info.digitalzoom)
+                               {
+                                       val_offset = ext_ctrl->value -sensor->isp_priv_info.digitalzoom;
+
+                                       if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0)
+                                               return -EINVAL;
+                                       sensor->isp_priv_info.digitalzoom += val_offset;
+
+                                       DEBUG_TRACE("%s digitalzoom is %x\n",sgensor->dev_name,  sensor->isp_priv_info.digitalzoom);
+                               }
+
+                               break;
+                       }
+               case V4L2_CID_ZOOM_RELATIVE:
+                       {
+                               if (ext_ctrl->value)
+                               {
+                                       if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0)
+                                               return -EINVAL;
+                                       sensor->isp_priv_info.digitalzoom += ext_ctrl->value;
+
+                                       DEBUG_TRACE("%s digitalzoom is %x\n", sgensor->dev_name, sensor->isp_priv_info.digitalzoom);
+                               }
+                               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;
+
+                               DEBUG_TRACE("%s flash is %x\n",sgensor->dev_name, sensor->isp_priv_info.flash);
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_FACE_DETECT
+       case V4L2_CID_FACEDETECT:
+               {
+                       if(sensor->isp_priv_info.face != ext_ctrl->value){
+                               if (sensor_set_face_detect(client, ext_ctrl->value) != 0)
+                                       return -EINVAL;
+                               sensor->isp_priv_info.face = ext_ctrl->value;
+                               DEBUG_TRACE("%s face value is %x\n",sgensor->dev_name, sensor->isp_priv_info.face);
+                               }
+                       break;
+               }
+#endif
+#if CONFIG_SENSOR_ISO
+       case V4L2_CID_ISO:
+       {
+               if (sensor->isp_priv_info.iso != ext_ctrl->value) {
+                       if (sensor_set_iso(icd, qctrl, ext_ctrl->value) != 0) {
+                               return -EINVAL;
+                       }
+                       sensor->isp_priv_info.iso = ext_ctrl->value;
+                       DEBUG_TRACE("%s set ISO to %d\n", sgensor->dev_name, sensor->isp_priv_info.iso);
+               }
+               break;
+       }
+#endif
+               default:
+                   ret = -1;
+                       break;
+       }
+
+       return ret;
+}
+
+static int icatch_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl,struct v4l2_queryctrl *qctrl)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+    int ret  = 0;
+
+
+       switch (ctrl->id)
+       {
+               case V4L2_CID_BRIGHTNESS:
+                       {
+                               ctrl->value = sensor->isp_priv_info.brightness;
+                               break;
+                       }
+               case V4L2_CID_SATURATION:
+                       {
+                               ctrl->value = sensor->isp_priv_info.saturation;
+                               break;
+                       }
+               case V4L2_CID_CONTRAST:
+                       {
+                               ctrl->value = sensor->isp_priv_info.contrast;
+                               break;
+                       }
+               case V4L2_CID_DO_WHITE_BALANCE:
+                       {
+                               ctrl->value = sensor->isp_priv_info.whiteBalance;
+                               break;
+                       }
+               case V4L2_CID_EXPOSURE:
+                       {
+                               ctrl->value = sensor->isp_priv_info.exposure;
+                               break;
+                       }
+               case V4L2_CID_HFLIP:
+                       {
+                               ctrl->value = sensor->isp_priv_info.mirror;
+                               break;
+                       }
+               case V4L2_CID_VFLIP:
+                       {
+                               ctrl->value = sensor->isp_priv_info.flip;
+                               break;
+                       }
+               case V4L2_CID_ZOOM_ABSOLUTE:
+                       {
+                               ctrl->value = sensor->isp_priv_info.digitalzoom;
+                               break;
+                       }
+               default :
+                       ret = -1;
+                               break;
+       }
+       return ret;
+}
+
+static int icatch_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl,struct v4l2_queryctrl *qctrl)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+       struct soc_camera_device *icd = client->dev.platform_data;
+    int ret  = 0;
+
+       switch (ctrl->id)
+       {
+#if CONFIG_SENSOR_Brightness
+               case V4L2_CID_BRIGHTNESS:
+                       {
+                               if (ctrl->value != sensor->isp_priv_info.brightness)
+                               {
+                                       if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0)
+                                       {
+                                               return -EINVAL;
+                                       }
+                                       sensor->isp_priv_info.brightness = ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_Exposure
+               case V4L2_CID_EXPOSURE:
+                       {
+                               if (ctrl->value != sensor->isp_priv_info.exposure)
+                               {
+                                       if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0)
+                                       {
+                                               return -EINVAL;
+                                       }
+                                       sensor->isp_priv_info.exposure = ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_Saturation
+               case V4L2_CID_SATURATION:
+                       {
+                               if (ctrl->value != sensor->isp_priv_info.saturation)
+                               {
+                                       if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0)
+                                       {
+                                               return -EINVAL;
+                                       }
+                                       sensor->isp_priv_info.saturation = ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_Contrast
+               case V4L2_CID_CONTRAST:
+                       {
+                               if (ctrl->value != sensor->isp_priv_info.contrast)
+                               {
+                                       if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0)
+                                       {
+                                               return -EINVAL;
+                                       }
+                                       sensor->isp_priv_info.contrast = ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_WhiteBalance
+               case V4L2_CID_DO_WHITE_BALANCE:
+                       {
+                               if (ctrl->value != sensor->isp_priv_info.whiteBalance)
+                               {
+                                       if (icatch_set_whiteBalance(icd, qctrl,ctrl->value) != 0)
+                                       {
+                                               return -EINVAL;
+                                       }
+                                       sensor->isp_priv_info.whiteBalance = ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_Mirror
+               case V4L2_CID_HFLIP:
+                       {
+                               if (ctrl->value != sensor->isp_priv_info.mirror)
+                               {
+                                       if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0)
+                                               return -EINVAL;
+                                       sensor->isp_priv_info.mirror = ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_Flip
+               case V4L2_CID_VFLIP:
+                       {
+                               if (ctrl->value != sensor->isp_priv_info.flip)
+                               {
+                                       if (sensor_set_flip(icd, qctrl,ctrl->value) != 0)
+                                               return -EINVAL;
+                                       sensor->isp_priv_info.flip = ctrl->value;
+                               }
+                               break;
+                       }
+#endif
+#if CONFIG_SENSOR_DigitalZoom
+               case V4L2_CID_ZOOM_ABSOLUTE:
+                       {
+                               int val_offset = 0;
+                               DEBUG_TRACE("V4L2_CID_ZOOM_ABSOLUTE ...... ctrl->value = %d\n",ctrl->value);
+                               if ((ctrl->value < qctrl->minimum) || (ctrl->value > qctrl->maximum)){
+                                       return -EINVAL;
+                                       }
+
+                               if (ctrl->value != sensor->isp_priv_info.digitalzoom)
+                               {
+                                       val_offset = ctrl->value -sensor->isp_priv_info.digitalzoom;
+
+                                       if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0)
+                                               return -EINVAL;
+                                       sensor->isp_priv_info.digitalzoom += val_offset;
+
+                                       DEBUG_TRACE("%s digitalzoom is %x\n",sgensor->dev_name,  sensor->isp_priv_info.digitalzoom);
+                               }
+
+                               break;
+                       }
+               case V4L2_CID_ZOOM_RELATIVE:
+                       {
+                               if (ctrl->value)
+                               {
+                                       if (sensor_set_digitalzoom(icd, qctrl,&ctrl->value) != 0)
+                                               return -EINVAL;
+                                       sensor->isp_priv_info.digitalzoom += ctrl->value;
+
+                                       DEBUG_TRACE("%s digitalzoom is %x\n", sgensor->dev_name, sensor->isp_priv_info.digitalzoom);
+                               }
+                               break;
+                       }
+#endif
+               default:
+                   ret = -1;
+                       break;
+       }
+
+       return ret;
+}
+
+int sensor_set_get_control_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, 
+                                                     struct v4l2_ext_control *ext_ctrl,bool is_set)
+{
+    int ret = 0;
+    struct v4l2_control ctrl;
+    
+    if(is_set){
+    // belong to ext_control ?
+        ret = icatch_s_ext_control(icd, ext_ctrl,ctrl_info->qctrl);
+        if(ret == 0){
+               ctrl_info->cur_value = ext_ctrl->value;
+               goto sensor_set_get_control_cb_end;
+               }
+    // belong to control?
+        ctrl.id = ext_ctrl->id;
+        ctrl.value = ext_ctrl->value;
+           ret = icatch_s_control(soc_camera_to_subdev(icd), &ctrl,ctrl_info->qctrl);
+        if(ret == 0){
+               ctrl_info->cur_value = ctrl.value;
+               goto sensor_set_get_control_cb_end;
+               }
+
+    }else{
+    // belong to ext_control ?
+        ret = icatch_g_ext_control(icd, ext_ctrl,ctrl_info->qctrl);
+
+        if(ret == 0){
+               ctrl_info->cur_value = ext_ctrl->value;
+               goto sensor_set_get_control_cb_end;
+               }
+    // belong to control?
+        ctrl.id = ext_ctrl->id;
+           ret = icatch_g_control(soc_camera_to_subdev(icd), &ctrl,ctrl_info->qctrl);
+        if(ret == 0){
+               ctrl_info->cur_value = ctrl.value;
+               goto sensor_set_get_control_cb_end;
+               }
+
+    }
+
+sensor_set_get_control_cb_end:   
+    return ret;
+    
+
+}
+static int sensor_hdr_exposure(struct i2c_client *client, unsigned int code)
+{
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+       //printk("sensor_hdr_exposure_cb: %d %d\n",code,sensor->isp_priv_info.exposure);
+       switch (code)
+       {
+               case RK_VIDEOBUF_HDR_EXPOSURE_MINUS_1:
+               {
+                       //if( (sensor->isp_priv_info.exposure - 1 >= -6) && (sensor->isp_priv_info.exposure - 1 <= 6) ){
+                       //      EXISP_I2C_EvSet(6 - sensor->isp_priv_info.exposure - 1);
+                       //}
+                       printk("RK_VIDEOBUF_HDR_EXPOSURE_MINUS_1\n");
+                       if(IsZSL){
+                               printk("EXISP_ImageCapSet(IMAGE_CAP_HDR)\n");
+                               EXISP_ImageCapSet(IMAGE_CAP_HDR);
+                               sensor_interrupt_wait_clear();
+                       }
+                       break;
+               }
+
+               case RK_VIDEOBUF_HDR_EXPOSURE_NORMAL:
+               {
+                       //EXISP_I2C_EvSet(6 - sensor->isp_priv_info.exposure);
+                       sensor->isp_priv_info.hdr = true;
+                       break;
+               }
+
+               case RK_VIDEOBUF_HDR_EXPOSURE_PLUS_1:
+               {
+                       //if( (sensor->isp_priv_info.exposure + 1 >= -6) && (sensor->isp_priv_info.exposure + 1 <= 6) ){
+                       //      EXISP_I2C_EvSet(6 - sensor->isp_priv_info.exposure + 1);
+                       //}
+                       break;
+               }
+
+               case RK_VIDEOBUF_HDR_EXPOSURE_FINISH:
+               {
+                       printk("HDR_EXPOSURE_FINISH\n");
+                       sensor->isp_priv_info.hdr = FALSE;
+                       //EXISP_I2C_EvSet(6 - sensor->isp_priv_info.exposure);
+                       if(IsZSL){
+                               u8 res_sel = 0;
+                               if(sensor->isp_priv_info.curRes == OUTPUT_QSXGA){
+                                       res_sel = 0xA;
+                               }else if(sensor->isp_priv_info.curRes == OUTPUT_QUADVGA){
+                                       res_sel = 0;
+                               }
+                               printk("HDR_EXPOSURE_FINISH Switch resolution\n");
+                               EXISP_PvSizeSet(res_sel);
+                               sensor_interrupt_wait_clear();
+                       }
+                       break;
+               }
+               default:
+                       break;
+       }
+       
+       return 0;
+}
+
+ long icatch_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       switch (cmd){
+               case RK29_CAM_SUBDEV_HDR_EXPOSURE:
+               {
+                       sensor_hdr_exposure(client,(unsigned int)arg);
+                       break;
+               }
+               
+               default:
+               {
+                       //SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+
+
+ int icatch_s_fmt(struct i2c_client *client, struct v4l2_mbus_framefmt *mf)
+{
+        const struct sensor_datafmt *fmt;
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+        //const struct v4l2_queryctrl *qctrl;
+        //struct soc_camera_device *icd = client->dev.platform_data;
+        int ret=0;
+        int set_w,set_h;
+        int supported_size = sensor->isp_priv_info.outputSize;
+        int res_set = 0;
+        u8 preview_cap_mode = 0;//0 is preview mode
+        set_w = mf->width;
+        set_h = mf->height;
+        if (((set_w <= 176) && (set_h <= 144)) && (supported_size & OUTPUT_QCIF))
+        {
+                set_w = 176;
+                set_h = 144;
+                res_set = OUTPUT_QCIF;
+        }
+        else if (((set_w <= 320) && (set_h <= 240)) && (supported_size & OUTPUT_QVGA))
+        {
+                set_w = 320;
+                set_h = 240;
+                res_set = OUTPUT_QVGA;
+
+        }
+        else if (((set_w <= 352) && (set_h<= 288)) && (supported_size & OUTPUT_CIF))
+        {
+                set_w = 352;
+                set_h = 288;
+                res_set = OUTPUT_CIF;
+
+        }
+        else if (((set_w <= 640) && (set_h <= 480)) && (supported_size & OUTPUT_VGA))
+        {
+                set_w = 640;
+                set_h = 480;
+                res_set = OUTPUT_VGA;
+
+        }
+        else if (((set_w <= 800) && (set_h <= 600)) && (supported_size & OUTPUT_SVGA))
+        {
+                set_w = 800;
+                set_h = 600;
+                res_set = OUTPUT_SVGA;
+
+        }
+        else if (((set_w <= 1024) && (set_h <= 768)) && (supported_size & OUTPUT_XGA))
+        {
+                set_w = 1024;
+                set_h = 768;
+                res_set = OUTPUT_XGA;
+
+        }
+        else if (((set_w <= 1280) && (set_h <= 720)) && (supported_size & OUTPUT_720P))
+        {
+                set_w = 1280;
+                set_h = 720;
+                res_set = OUTPUT_720P;
+        }
+
+        else if (((set_w <= 1280) && (set_h <= 960)) && (supported_size & OUTPUT_QUADVGA))
+        {
+                set_w = 1280;
+                set_h = 960;
+                res_set = OUTPUT_QUADVGA;
+        }
+        else if (((set_w <= 1280) && (set_h <= 1024)) && (supported_size & OUTPUT_XGA))
+        {
+                set_w = 1280;
+                set_h = 1024;
+                res_set = OUTPUT_XGA;
+        }
+        else if (((set_w <= 1600) && (set_h <= 1200)) && (supported_size & OUTPUT_UXGA))
+        {
+                set_w = 1600;
+                set_h = 1200;
+                res_set = OUTPUT_UXGA;
+        }
+        else if (((set_w <= 1920) && (set_h <= 1080)) && (supported_size & OUTPUT_1080P))
+        {
+                set_w = 1920;
+                set_h = 1080;
+                res_set = OUTPUT_1080P;
+        }
+        else if (((set_w <= 2048) && (set_h <= 1536)) && (supported_size & OUTPUT_QXGA))
+        {
+                set_w = 2048;
+                set_h = 1536;
+                res_set = OUTPUT_QXGA;
+        }
+        else if (((set_w <= 2592) && (set_h <= 1944)) && (supported_size & OUTPUT_QSXGA))
+        {
+                set_w = 2592;
+                set_h = 1944;
+                res_set = OUTPUT_QSXGA;
+        }
+        else
+        {
+                set_w = 1280;
+                set_h = 960;
+                res_set = OUTPUT_QUADVGA;
+        }
+
+        //if(res_set != sensor->isp_priv_info.curRes)
+        //  sensor_set_isp_output_res(client,res_set);
+        //res will be setted
+        sensor->isp_priv_info.curRes = res_set;
+        mf->width = set_w;
+        mf->height = set_h;
+        //enter capture or preview mode
+        //EXISP_I2C_PvCapModeSet(preview_cap_mode);
+        DEBUG_TRACE("%s:setw = %d,seth = %d\n",__func__,set_w,set_h);
+
+ sensor_s_fmt_end:
+        return ret;
+ }
+
+int icatch_enum_framesizes(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize)
+{
+       int err = 0,i=0,num = 0;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+
+       printk("icatch_enum_framesizes fsize->reserved[0](%x) fsize->reserved[1](%x)\n",fsize->reserved[0],fsize->reserved[1]);
+       if( (fsize->reserved[1] & 0xff) == 0x01){
+               IsZSL = TRUE;
+       }else{
+               IsZSL = FALSE;
+       }
+
+       //get supported framesize num
+       
+       if (fsize->index >= sensor->isp_priv_info.supportedSizeNum) {
+               err = -1;
+               goto end;
+       }
+
+       if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_QCIF))
+       {
+               
+               fsize->discrete.width = 176;
+               fsize->discrete.height = 144;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_QVGA))
+       {
+               fsize->discrete.width = 320;
+               fsize->discrete.height = 240;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_CIF) )
+       {
+       
+               fsize->discrete.width = 352;
+               fsize->discrete.height = 288;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_VGA))
+       {
+       
+               fsize->discrete.width = 640;
+               fsize->discrete.height = 480;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_SVGA))
+       {
+       
+               fsize->discrete.width = 800;
+               fsize->discrete.height = 600;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_XGA))
+       {
+       
+               fsize->discrete.width = 1024;
+               fsize->discrete.height = 768;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_720P))
+       {
+       
+               fsize->discrete.width = 1280;
+               fsize->discrete.height = 720;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_QUADVGA))
+       {
+               fsize->discrete.width = 1280;
+               fsize->discrete.height = 960;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_XGA))
+       {
+               fsize->discrete.width = 1280;
+               fsize->discrete.height = 1024;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_UXGA) )
+       {
+               fsize->discrete.width = 1600;
+               fsize->discrete.height = 1200;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_1080P))
+       {
+               fsize->discrete.width = 1920;
+               fsize->discrete.height = 1080;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_QXGA))
+       {
+               fsize->discrete.width = 2048;
+               fsize->discrete.height = 1536;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       }
+       else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_QSXGA))
+       {
+       
+               fsize->discrete.width = 2592;
+               fsize->discrete.height = 1944;
+               fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       } else {
+               err = -1;
+       }
+
+       
+       
+end:
+       return err;
+}
+
+
+/*-------------------------------------------------------------------------
+ *     Function Name : EXISP_I2C_PvSizeSet
+ *     ucParam:
+        0x00   1280x960
+        0x01   3264x2448
+        0x02   1920x1080
+        0x03   320x240(reserved)
+        0x04   1280x720
+        0x05   1040x780
+        0x06   2080x1560
+        0x07   3648x2736
+        0x08   4160x3120
+        0x09   3360x1890
+        0x0A   2592x1944
+        0x0B   640x480
+        0x0C   1408x1408
+        0x0D   1920x1088
+ *     Return : None
+ *------------------------------------------------------------------------*/
+
+static int icatch_set_isp_output_res(struct i2c_client *client,enum ISP_OUTPUT_RES outputSize){
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+#if 0  
+       u8 res_sel = 0;
+       switch(outputSize) {
+       case OUTPUT_QCIF:
+       case OUTPUT_HQVGA:
+       case OUTPUT_QVGA:
+       case OUTPUT_CIF:
+       case OUTPUT_VGA:
+       case OUTPUT_SVGA:
+       case OUTPUT_720P:
+       case OUTPUT_QUADVGA:
+               res_sel = 0;
+               break;
+       case OUTPUT_XGA:
+       case OUTPUT_SXGA:
+       case OUTPUT_UXGA:
+       case OUTPUT_1080P:
+       case OUTPUT_QXGA:
+       case OUTPUT_QSXGA:
+               res_sel = IMAGE_CAP_NONZSL_SINGLE;// non-zsl single
+               break;
+       default:
+               DEBUG_TRACE("%s %s  isp not support this resolution!\n",sgensor->dev_name,__FUNCTION__);
+               break;
+       }
+#endif
+    int cnt = 16;
+       //preview mode set
+       if(outputSize == OUTPUT_QSXGA){
+               if(sensor->isp_priv_info.hdr == FALSE){
+                       if(IsZSL){
+                                       printk("IsZSL EXISP_PvSizeSet(0x0A)\n");
+                                       EXISP_PvSizeSet(0x0A);
+                                       //polling until AE ready
+                                       while (((EXISP_I2C_3AStatusGet() & 0x1) == 0) && (cnt -- > 0)) {
+                                               DEBUG_TRACE("%s %s  polling AE ready\n",sgensor->dev_name,__FUNCTION__);
+                                               mdelay(50);
+                                       }
+                                       sensor_interrupt_wait_clear();
+                       }else{
+                               printk("Is not ZSL HdrEn FALSE EXISP_ImageCapSet(IMAGE_CAP_NONZSL_SINGLE)\n");
+                               icatch_sensor_write(SP7K_RDREG_INT_STS_REG_0,icatch_sensor_read(SP7K_RDREG_INT_STS_REG_0));
+                               EXISP_ImageCapSet(IMAGE_CAP_NONZSL_SINGLE);
+                               sensor_interrupt_wait_clear();
+                       }
+               }else{
+                       printk("HdrEn EXISP_ImageCapSet(IMAGE_CAP_HDR)\n");
+                       EXISP_ImageCapSet(IMAGE_CAP_HDR);
+                       sensor_interrupt_wait_clear();
+               }
+               sensor->isp_priv_info.curPreviewCapMode = CAPTURE_NONE_ZSL_MODE;
+       }
+       else{
+               EXISP_PvSizeSet(IMAGE_CAP_SINGLE);
+               //polling until AE ready
+               while (((EXISP_I2C_3AStatusGet() & 0x1) == 0) && (cnt -- > 0)) {
+                       DEBUG_TRACE("%s %s  polling AE ready\n",sgensor->dev_name,__FUNCTION__);
+                       mdelay(50);
+               }
+               sensor_interrupt_wait_clear();
+               sensor->isp_priv_info.curPreviewCapMode = PREVIEW_MODE;
+#if 1
+               DEBUG_TRACE("\n %s  pid = 0x%x\n", sgensor->dev_name, EXISP_I2C_VendorIdGet);
+               DEBUG_TRACE("fw version is 0x%x\n ",EXISP_I2C_FWVersionGet());
+
+               DEBUG_TRACE("front id= 0x%x,rear id = 0x%x\n ",EXISP_I2C_FrontSensorIdGet(),EXISP_I2C_RearSensorIdGet());
+#endif
+       }
+       return 0;
+}
+
+ int icatch_s_stream(struct v4l2_subdev *sd, int enable){
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_device *icd = client->dev.platform_data;
+    struct generic_sensor*sgensor = to_generic_sensor(client);
+    struct specific_sensor*sensor = to_specific_sensor(sgensor);
+       DEBUG_TRACE("%s:enable = %d\n",__func__,enable);
+       DEBUG_TRACE("@@NY@@%s: client %0x\n", __FUNCTION__, client);
+       if(enable == 0){
+               //   sensor_set_face_detect(client,0);
+               //  sensor_af_workqueue_set(icd,0,0,true);
+#if CALIBRATION_MODE_FUN
+               if (g_is_calibrationMode)
+                       EXISP_I2C_PvStreamSet(0); // stream off
+#endif
+               sensor->isp_priv_info.curPreviewCapMode = IDLE_MODE;
+       }else{
+#if CALIBRATION_MODE_FUN
+               if (g_is_calibrationMode &&
+                   sensor->isp_priv_info.sensor_id ==  SENSOR_ID_REAR_CALIBRATION &&
+                   sensor->isp_priv_info.rk_query_PreviewCapMode == PREVIEW_MODE) {
+                       EXISP_PvSizeSet(0x0A);
+                       sensor->isp_priv_info.curPreviewCapMode = PREVIEW_MODE;
+                       EXISP_I2C_PvStreamSet(1); // stream on
+                       return 0;
+               }
+#endif
+               printk(KERN_ERR"icatch_set_isp_output_res: curRes(%x)\n",sensor->isp_priv_info.curRes);
+               //sensor_set_face_detect(client,1);
+               icatch_set_isp_output_res(client, sensor->isp_priv_info.curRes);
+
+
+#if CALIBRATION_MODE_FUN
+               if (g_is_calibrationMode)
+                       EXISP_I2C_PvStreamSet(1); // stream on
+#endif
+       }
+
+        return 0;
+}
+
+
+int icatch_request_firmware(const struct firmware ** fw){
+       int ret = 0;
+       if( request_firmware(fw, ICATCHFWNAME, &g_icatch_i2c_client->dev) !=0){
+               DEBUG_TRACE("%s:%d, request firmware erro,please check firmware!\n");
+               ret = -1;
+       }else{
+               ret = 0;
+       }
+       return ret;
+}
+
+void icatch_release_firmware(const struct firmware * fw){
+       if(fw)
+               release_firmware(fw);
+}
+
+void icatch_sensor_power_ctr(struct soc_camera_device *icd ,int on,int power_mode){
+#if 0
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       struct rk29camera_platform_data* pdata = (struct rk29camera_platform_data*)(to_soc_camera_host(icd->dev.parent)->v4l2_dev.dev->platform_data);
+       if(!on){
+               //power down
+               if(icl->power)
+                       icl->power(icd->pdev,0);
+               if(pdata && pdata->sensor_mclk)
+                       pdata->sensor_mclk(RK29_CAM_PLATFORM_DEV_ID,0,24*1000*1000);
+               if(icl->powerdown)
+                       icl->powerdown(icd->pdev,0);
+               iomux_set(GPIO1_A4);
+               iomux_set(GPIO1_A5) ;
+               iomux_set(GPIO1_A6);
+               iomux_set(GPIO1_A7);
+               iomux_set(GPIO3_B6);
+               iomux_set(GPIO3_B7);
+               iomux_set(GPIO0_C0);
+               gpio_set_value(RK30_PIN1_PA4,0);
+               gpio_set_value(RK30_PIN1_PA5,0);
+               gpio_set_value(RK30_PIN1_PA6,0);        //Vincent_Liu@asus.com for clk 24M
+               gpio_set_value(RK30_PIN1_PA7,0);
+               gpio_set_value(RK30_PIN3_PB6,0);
+               gpio_set_value(RK30_PIN3_PB7,0);
+               gpio_set_value(RK30_PIN0_PC0,0);
+               //msleep(500);
+       }else{
+               //power ON
+               gpio_set_value(RK30_PIN1_PA6,1);        //Vincent_Liu@asus.com for clk 24M
+               
+               if(icl->power)
+                       icl->power(icd->pdev,1);
+               if(icl->powerdown){
+                       if(power_mode == 0)//from spi
+                               icl->powerdown(icd->pdev,1);
+                       else
+                               icl->powerdown(icd->pdev,0);
+                       }
+               if(pdata && pdata->sensor_mclk)
+                       pdata->sensor_mclk(RK29_CAM_PLATFORM_DEV_ID,1,24*1000*1000);
+                       //reset , reset pin low ,then high
+               if (icl->reset)
+                       icl->reset(icd->pdev);
+               if(power_mode == 0)//from spi
+                       icl->powerdown(icd->pdev,0);
+               iomux_set(SPI0_CLK);
+               iomux_set(SPI0_RXD);
+               iomux_set(SPI0_TXD);
+               iomux_set(SPI0_CS0);
+               iomux_set(I2C3_SDA);
+               iomux_set(I2C3_SCL);
+               msleep(100);
+       }
+       #endif
+}
+
+#if CALIBRATION_MODE_FUN
+#if 0
+void __dump(const u8 *data, size_t size) {
+       size_t i = 0;
+       char buf[100] = {0};
+       char lbuf[12];
+
+       while( i < size) {
+               if ((i%16 == 0) && (i != 0)) {
+                       DEBUG_TRACE("%s\n", buf);
+               }
+               if (i%16 == 0) {
+                       buf[0] = 0;
+                       sprintf(lbuf, "%08X:", i);
+                       strcat(buf, lbuf);
+               }
+               sprintf(lbuf, " %02X", *(data + i));
+               strcat(buf, lbuf);
+               i++;
+       }
+
+       DEBUG_TRACE("%s\n", buf);
+}
+#endif
+
+struct icatch_cali_fw_data * icatch_load_cali_fw_data(u8 sensorid) {
+
+       if (g_is_calibrationMode) {
+               return NULL;
+       }
+
+       struct icatch_cali_fw_data * fw = NULL;
+       switch (sensorid) {
+       case SENSOR_ID_FRONT:
+               fw = &g_cali_fw_data_front;
+               break;
+       case SENSOR_ID_REAR:
+               fw = &g_cali_fw_data_back;
+               break;
+       default:
+               break;
+       }
+       if (fw == NULL)
+               return NULL;
+
+       if (request_firmware(
+               &(fw->fw_option),
+               fw->fname_option,
+               &g_icatch_i2c_client->dev) != 0) {
+               DEBUG_TRACE("%s: load calibration fw data: %s fail", __FUNCTION__, fw->fname_option);
+               fw->fw_option = NULL;
+       }
+
+       if (request_firmware(
+               &(fw->fw_3acali),
+               fw->fname_3acali,
+               &g_icatch_i2c_client->dev) != 0) {
+               DEBUG_TRACE("%s: load calibration fw data: %s fail", __FUNCTION__, fw->fname_3acali);
+               fw->fw_3acali = NULL;
+       }
+#if 0
+       else {
+               DEBUG_TRACE("%s: dump %s (size: %d)\n", __FUNCTION__, fw->fname_3acali, fw->fw_3acali->size);
+               __dump(fw->fw_3acali->data, fw->fw_3acali->size);
+       }
+#endif
+
+       if (request_firmware(
+               &(fw->fw_lsc),
+               fw->fname_lsc,
+               &g_icatch_i2c_client->dev) != 0) {
+               DEBUG_TRACE("%s: load calibration fw data: %s fail", __FUNCTION__, fw->fname_lsc);
+               fw->fw_lsc = NULL;
+       }
+#if 0
+       else {
+               DEBUG_TRACE("%s: dump %s (size: %d)\n", __FUNCTION__, fw->fname_lsc, fw->fw_lsc->size);
+               __dump(fw->fw_lsc->data, fw->fw_lsc->size);
+       }
+#endif
+
+       if (request_firmware(
+               &(fw->fw_lscdq),
+               fw->fname_lscdq,
+               &g_icatch_i2c_client->dev) != 0) {
+               DEBUG_TRACE("%s: load calibration fw data: %s fail", __FUNCTION__, fw->fname_lscdq);
+               fw->fw_lscdq = NULL;
+       }
+#if 0
+       else {
+               DEBUG_TRACE("%s: dump %s (size: %d)\n", __FUNCTION__, fw->fname_lscdq, fw->fw_lscdq->size);
+               __dump(fw->fw_lscdq->data, fw->fw_lscdq->size);
+       }
+#endif
+
+       return fw;
+}
+
+void icatch_free_cali_fw_data(struct icatch_cali_fw_data * data) {
+       if (data == NULL)
+               return ;
+
+       if (data->fw_option != NULL) {
+               release_firmware(data->fw_option);
+       }
+
+       if (data->fw_3acali != NULL) {
+               release_firmware(data->fw_3acali);
+       }
+
+       if (data->fw_lsc != NULL) {
+               release_firmware(data->fw_lsc);
+       }
+
+       if (data->fw_lscdq != NULL) {
+               release_firmware(data->fw_lscdq);
+       }
+}
+#endif
+
+//#include "BOOT_OV5693_126MHz(075529).c"
+ int icatch_load_fw(struct soc_camera_device *icd,u8 sensorid){
+        struct firmware *fw =NULL;
+#if CALIBRATION_MODE_FUN
+        struct icatch_cali_fw_data * cali_data = NULL;
+#endif
+        int ret = 0;
+        icatch_sensor_power_ctr(icd,0,ICATCH_BOOT);
+        icatch_sensor_power_ctr(icd,1,ICATCH_BOOT);
+        if(ICATCH_BOOT == ICATCH_BOOT_FROM_HOST){
+                DEBUG_TRACE("@@NY@@%s: %d\n", __FUNCTION__, sensorid);
+                if(icatch_request_firmware(&fw)!= 0){
+                        ret = -1;
+                        goto icatch_load_fw_out;
+                }
+
+#if CALIBRATION_MODE_FUN
+                g_fw_version.fw = *((__u32*)(fw->data + fw->size - 4));
+
+                cali_data = icatch_load_cali_fw_data(sensorid);
+                if (cali_data != NULL) {
+                        DEBUG_TRACE("%s:%d,load calibration fw data success !!!!\n",__func__,__LINE__);
+                        ret = EXISP_LoadCodeStart(
+                                       ICATCH_BOOT,
+                                       sensorid,
+                                       g_is_calibrationMode,
+                                       (u8*)(fw->data),
+                                       cali_data->fw_option ? (u8*)(cali_data->fw_option->data) : &g_Calibration_Option_Def,
+                                       cali_data->fw_3acali ? (u8*)(cali_data->fw_3acali->data) : NULL,
+                                       cali_data->fw_lsc ? (u8*)(cali_data->fw_lsc->data) : NULL,
+                                       cali_data->fw_lscdq ? (u8*)(cali_data->fw_lscdq->data) : NULL);
+                } else {
+                        DEBUG_TRACE("%s:%d,load calibration fw data fail !!!!\n",__func__,__LINE__);
+                        ret = EXISP_LoadCodeStart(
+                                       ICATCH_BOOT,
+                                       sensorid,
+                                       g_is_calibrationMode,
+                                       (u8*)(fw->data),
+                                       &g_Calibration_Option_Def,
+                                       NULL,
+                                       NULL,
+                                       NULL);
+                }
+#else
+                ret = EXISP_LoadCodeStart(
+                               ICATCH_BOOT,
+                               sensorid,
+                               0,
+                               (u8*)(fw->data),
+                               &g_Calibration_Option_Def,
+                               NULL,
+                               NULL,
+                               NULL);
+#endif
+
+                if (ret != SUCCESS) {
+                        DEBUG_TRACE("%s:%d,load firmware failed !!!!\n",__func__,__LINE__);
+                        ret = -1;
+                } else {
+                        ret = 0;
+                }
+
+                icatch_release_firmware(fw);
+                icatch_free_cali_fw_data(cali_data);
+
+                if(ret < 0)
+                        goto icatch_load_fw_out;
+
+        }else{
+       #if 1
+                BB_WrSPIFlash(0xffffff);
+                
+                icatch_sensor_power_ctr(icd,0,0);
+                icatch_sensor_power_ctr(icd,1,0);
+                gpio_set_value(RK30_PIN1_PA6,0);       //Vincent_Liu@asus.com for clk 24M
+       #endif
+       }
+       // msleep(100);
+        return 0;
+icatch_load_fw_out:
+       return ret;
+}
+
+int icatch_get_rearid_by_lowlevelmode(struct soc_camera_device *icd,UINT16 *rear_id)
+{
+       static int ret = 0;
+       static int done = 0;
+       static UINT16 _rear_id = 0;
+
+       static const struct rk_sensor_reg reset_1[]={
+               {0x1011, 0x01}, /* CPU suspend */
+               {0x0084, 0x14},  /* To sensor clock divider */
+               {0x0034, 0xFF},  /* Turn on all clock */
+               {0x9032, 0x00},
+               {0x9033, 0x10},
+               {0x9030, 0x3f},
+               {0x9031, 0x04},
+               {0x9034, 0xf2},
+               {0x9035, 0x04},
+               {0x9032, 0x10},
+               {0x00,  0x00},
+       };
+
+       //tmrUsWait(10000); /*10ms*/
+
+       static const struct rk_sensor_reg reset_2[] = {
+               {0x9032, 0x30},
+               {0x00,  0x00},
+       };
+
+       //tmrUsWait(10000); /*10ms*/
+
+
+       static const struct rk_sensor_reg reset_3[] = {
+               /*End - Power on sensor & enable clock */
+               {0x9008, 0x00},
+               {0x9009, 0x00},
+               {0x900A, 0x00},
+               {0x900B, 0x00},
+
+               /*Start - I2C Read*/
+               {0x923C, 0x01},  /* Sub address enable */
+               {0x9238, 0x30},  /* Sub address enable */
+               {0x9240, 0x6C},  /* Slave address      */
+               {0x9200, 0x03},  /* Read mode          */
+               {0x9210, 0x00},  /* Register addr MSB  */
+               {0x9212, 0x00},  /* Register addr LSB  */
+               {0x9204, 0x01},  /* Trigger I2C read   */
+               {0x00,  0x00},
+       };
+
+       //      tmrUsWait(2000);/*2ms*/
+
+       DEBUG_TRACE("%s: entry!\n", __FUNCTION__);
+
+       if (done == 1) {
+               if (rear_id != NULL)
+                       *rear_id = _rear_id;
+               return ret;
+       }
+
+       icatch_sensor_power_ctr(icd,0,ICATCH_BOOT);
+       icatch_sensor_power_ctr(icd,1,ICATCH_BOOT);
+
+       if (icatch_sensor_write_array(reset_1) != 0) {
+               ret = -ENXIO;
+               goto l_ret;
+       }
+       msleep(10);
+
+       if (icatch_sensor_write_array(reset_2) != 0) {
+               ret = -ENXIO;
+               goto l_ret;
+       }
+
+       msleep(10);
+       if (icatch_sensor_write_array(reset_3) != 0) {
+               ret = -ENXIO;
+               goto l_ret;
+       }
+
+       msleep(2);
+       _rear_id = (UINT16)icatch_sensor_read(0x9211) << 8;
+       _rear_id += icatch_sensor_read(0x9213);
+       DEBUG_TRACE("%s: rear_id = 0x%04X\n", __FUNCTION__, _rear_id);
+       *rear_id = _rear_id;
+
+
+l_ret:
+       icatch_sensor_power_ctr(icd,0,ICATCH_BOOT);
+       done = 1;
+       return ret;
+}
+
+
+int icatch_get_frontid_by_lowlevelmode(struct soc_camera_device *icd,UINT16 *front_id)
+{
+       static int ret = 0;
+       static int done = 0;
+       static UINT16 _front_id = 0;
+
+       static const struct rk_sensor_reg reset_1[]={
+               { 0x1011, 0x01,0x0,0x0},  /* CPU Suspend */
+
+               { 0x0084, 0x14},  /* To sensor clock divider */
+               { 0x0034, 0xFF},  /* Turn on all clock */
+               { 0x9030, 0x3f},
+               { 0x9031, 0x04},
+               { 0x9034, 0xf2},
+               { 0x9035, 0x04},
+               { 0x9033, 0x04},
+               { 0x9032, 0x3c},
+       SensorEnd   
+       };
+
+       //tmrUsWait(10000); /* 10ms */
+
+       static const struct rk_sensor_reg reset_2[] = {
+               {0x9033, 0x00},
+       SensorEnd
+       };
+
+       //tmrUsWait(10000); /*10ms*/
+
+
+       static const struct rk_sensor_reg reset_3[] = {
+               { 0x9033, 0x04},
+               { 0x9032, 0x3e},
+       SensorEnd
+       };
+
+       //tmrUsWait(10000); /* 10ms */
+
+       static const struct rk_sensor_reg reset_4[] = {
+               { 0x9032, 0x3c},
+               /*End - Power on sensor & enable clock */
+
+               /*Start - I2C Read ID*/
+               { 0x9138, 0x30},  /* Sub address enable */
+               { 0x9140, 0x90},  /* Slave address      */
+               { 0x9100, 0x03},  /* Read mode          */
+               { 0x9110, 0x00},  /* Register addr MSB  */
+               { 0x9112, 0x00}, /* Register addr LSB  */
+               { 0x9104, 0x01 }, /* Trigger I2C read   */
+       SensorEnd
+       };
+
+       //tmrUsWait(100);   /* 0.1ms */
+
+       static const struct rk_sensor_reg reset_5[] = {
+               { 0x9110, 0x00},  /* Register addr MSB  */
+               { 0x9112, 0x01},  /* Register addr LSB  */
+               { 0x9104, 0x01},  /* Trigger I2C read   */
+       SensorEnd
+       };
+
+       DEBUG_TRACE("%s: entry!\n", __FUNCTION__);
+
+       if (done == 1) {
+               if (front_id != NULL)
+                       *front_id = _front_id;
+               return ret;
+       }
+
+       icatch_sensor_power_ctr(icd,0,ICATCH_BOOT);
+       icatch_sensor_power_ctr(icd,1,ICATCH_BOOT);
+
+       if (icatch_sensor_write_array(reset_1) != 0) {
+               ret = -ENXIO;
+               goto l_ret;
+       }
+       msleep(10);
+
+       if (icatch_sensor_write_array(reset_2) != 0) {
+               ret = -ENXIO;
+               goto l_ret;
+       }
+
+       msleep(10);
+       if (icatch_sensor_write_array(reset_3) != 0) {
+               ret = -ENXIO;
+               goto l_ret;
+       }
+
+       msleep(10);
+
+
+       if (icatch_sensor_write_array(reset_4) != 0) {
+               ret = -ENXIO;
+               goto l_ret;
+       }
+
+       msleep(1);
+       _front_id = (UINT16)icatch_sensor_read(0x9111) << 8;
+
+       if (icatch_sensor_write_array(reset_5) != 0) {
+               ret = -ENXIO;
+               goto l_ret;
+       }
+
+       msleep(1);
+       _front_id += icatch_sensor_read(0x9111);
+       DEBUG_TRACE("%s: front_id = 0x%04X\n", __FUNCTION__, _front_id);
+       *front_id = _front_id;
+
+l_ret:
+       icatch_sensor_power_ctr(icd,0,ICATCH_BOOT);
+       done = 1;
+       return ret;
+}
+
diff --git a/drivers/media/video/icatch7002/icatch7002_common.h b/drivers/media/video/icatch7002/icatch7002_common.h
new file mode 100755 (executable)
index 0000000..cf90ccd
--- /dev/null
@@ -0,0 +1,211 @@
+#ifndef ICATCH7002_COMMON_H
+#include "../generic_sensor.h"
+#include "app_i2c_lib_icatch.h"
+#include <linux/firmware.h>
+
+/* CAMERA_REAR_SENSOR_SETTING:V17.00.18 */
+/* CAMERA_FRONT_SENSOR_SETTING:V17.00.18 */
+#if defined(CONFIG_TRACE_LOG_PRINTK)
+ #define DEBUG_TRACE(format, ...) printk(KERN_WARNING format, ## __VA_ARGS__)
+#else
+ #define DEBUG_TRACE(format, ...)
+#endif
+#define LOG_TRACE(format, ...) printk(KERN_WARNING format, ## __VA_ARGS__)
+
+
+#define        CALIBRATION_MODE_FUN            1
+
+#define SENSOR_REGISTER_LEN                             2                 // sensor register address bytes
+#define SENSOR_VALUE_LEN                                        1                 // sensor register value bytes
+
+extern struct i2c_client *g_icatch_i2c_client;
+#define icatch_sensor_write(reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)((g_icatch_i2c_client),(reg),(v))
+#define icatch_sensor_write_array(regarry) generic_sensor_write_array(g_icatch_i2c_client,regarry)
+
+
+static inline u8 icatch_sensor_read(u16 reg)
+{
+    u8 val;
+    sensor_read_reg2val1(g_icatch_i2c_client,reg,&val);
+    return val;
+}
+
+
+enum sensor_work_state {
+       sensor_work_ready = 0,
+       sensor_working,
+};
+
+#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            1
+#define CONFIG_SENSOR_Exposure         1
+#define CONFIG_SENSOR_Flash            0
+#define CONFIG_SENSOR_Mirror           0
+#define CONFIG_SENSOR_Flip             0
+#define CONFIG_SENSOR_FOCUS_ZONE       0
+#define CONFIG_SENSOR_FACE_DETECT      0
+#define CONFIG_SENSOR_ISO              1
+#define CONFIG_SENSOR_AntiBanding      1
+#define CONFIG_SENSOR_WhiteBalanceLock 1
+#define CONFIG_SENSOR_ExposureLock     1
+#define CONFIG_SENSOR_MeteringAreas    1
+#define CONFIG_SENSOR_Wdr                      1
+#define CONFIG_SENSOR_EDGE                     1
+#define CONFIG_SENSOR_JPEG_EXIF                1
+#define CONFIG_SENSOR_DUMPREGS         0
+
+#if CONFIG_SENSOR_Focus
+extern int icatch_sensor_set_auto_focus(struct i2c_client *client, int value,int *tmp_zone);
+#endif
+
+#if CALIBRATION_MODE_FUN
+void icatch_create_proc_entry(void);
+void icatch_remove_proc_entry(void);
+#endif
+extern void BB_WrSPIFlash(u32 size);
+extern int icatch_request_firmware(const struct firmware ** fw);
+extern void icatch_release_firmware(const struct firmware * fw);
+extern void icatch_sensor_power_ctr(struct soc_camera_device *icd ,int on,int power_mode);
+extern int icatch_load_fw(struct soc_camera_device *icd,u8 sensorid);
+int icatch_get_rearid_by_lowlevelmode(struct soc_camera_device *icd,UINT16 *rear_id);
+int icatch_get_frontid_by_lowlevelmode(struct soc_camera_device *icd,UINT16 *front_id);
+extern int icatch_sensor_init(struct i2c_client *client);
+extern int icatch_s_fmt(struct i2c_client *client, struct v4l2_mbus_framefmt *mf);
+extern int icatch_s_stream(struct v4l2_subdev *sd, int enable);
+extern int sensor_set_get_control_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, 
+                                                     struct v4l2_ext_control *ext_ctrl,bool is_set);
+extern int icatch_enum_framesizes(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize);
+
+enum ISP_OUTPUT_RES{
+       OUTPUT_QCIF             =0x0001, // 176*144
+       OUTPUT_HQVGA            =0x0002,// 240*160
+       OUTPUT_QVGA             =0x0004, // 320*240
+       OUTPUT_CIF                      =0x0008,  // 352*288
+       OUTPUT_VGA                      =0x0010,  // 640*480
+       OUTPUT_SVGA             =0x0020, // 800*600
+       OUTPUT_720P             =0x0040, // 1280*720
+       OUTPUT_XGA                      =0x0080,  // 1024*768
+       OUTPUT_QUADVGA          =0x0100,  // 1280*960
+       OUTPUT_SXGA             =0x0200, // 1280*1024
+       OUTPUT_UXGA             =0x0400, // 1600*1200
+       OUTPUT_1080P            =0x0800, //1920*1080
+       OUTPUT_QXGA             =0x1000,  // 2048*1536
+       OUTPUT_QSXGA            =0x2000, // 2592*1944
+};
+
+
+
+enum sensor_preview_cap_mode{
+       PREVIEW_MODE,
+       CAPTURE_MODE,
+       CAPTURE_ZSL_MODE,
+       CAPTURE_NONE_ZSL_MODE,
+       IDLE_MODE,
+};
+
+
+typedef struct rk_sensor_focus_zone rk_sensor_tae_zone;
+typedef struct{
+       uint32_t num;
+       uint32_t denom;
+}rat_t;
+
+
+typedef struct{
+       /*IFD0*/
+       char *maker;//manufacturer of digicam, just to adjust to make inPhybusAddr to align to 64
+       int makerchars;//length of maker, contain the end '\0', so equal strlen(maker)+1
+       char *modelstr;//model number of digicam
+       int modelchars;//length of modelstr, contain the end '\0'
+       int Orientation;//usually 1
+       //XResolution, YResolution; if need be not 72, TODO...
+       char DateTime[20];//must be 20 chars->  yyyy:MM:dd0x20hh:mm:ss'\0'
+       /*Exif SubIFD*/
+       rat_t ExposureTime;//such as 1/400=0.0025s
+       rat_t ApertureFNumber;//actual f-number
+       int ISOSpeedRatings;//CCD sensitivity equivalent to Ag-Hr film speedrate
+       rat_t CompressedBitsPerPixel;
+       rat_t ShutterSpeedValue;
+       rat_t ApertureValue;
+       rat_t ExposureBiasValue;
+       rat_t MaxApertureValue;
+       int MeteringMode;
+       int Flash;
+       rat_t FocalLength;
+       rat_t FocalPlaneXResolution;
+       rat_t FocalPlaneYResolution;
+       int SensingMethod;//2 means 1 chip color area sensor
+       int FileSource;//3 means the image source is digital still camera
+       int CustomRendered;//0
+       int ExposureMode;//0
+       int WhiteBalance;//0
+       rat_t DigitalZoomRatio;// inputw/inputw
+       //int FocalLengthIn35mmFilm;
+       int SceneCaptureType;//0
+       
+}RkExifInfo;
+
+//flash and focus must be considered.
+
+//soft isp or external isp used
+//if soft isp is defined , the value in this sturct is used in cif driver . cif driver use this value to do isp func.
+//value of this sturct MUST be defined(initialized) correctly. 
+struct isp_data{
+       int focus;
+       int auto_focus;
+       int flash;
+       int whiteBalance;
+       int brightness;
+       int contrast;
+       int saturation;
+       int effect;
+       int scene;
+       int digitalzoom;
+       int exposure;
+       int iso;
+       int face;
+       int antibanding;
+       int WhiteBalanceLock;
+       int ExposureLock;
+       int MeteringAreas;
+       int Wdr;
+       int hdr;
+       //mirror or flip
+       unsigned char mirror;                                                                            /* HFLIP */
+       unsigned char flip;                                                                              /* VFLIP */
+       //preview or capture
+       int outputSize; // supported resolution
+       int curRes;
+       int curPreviewCapMode;
+       int supportedSize[10];
+       int supportedSizeNum;
+       int had_setprvsize;
+    RkExifInfo exifInfo;
+#if CALIBRATION_MODE_FUN
+       int rk_query_PreviewCapMode;
+       int sensor_id;
+#endif
+       struct rk_sensor_focus_zone focus_zone;
+       rk_sensor_tae_zone tae_zone;
+
+};
+
+
+
+
+struct specific_sensor{
+       struct generic_sensor common_sensor;
+       //define user data below
+       struct isp_data isp_priv_info;
+
+};
+
+#endif
+
+
diff --git a/drivers/media/video/icatch7002/icatch7002_mi1040.c b/drivers/media/video/icatch7002/icatch7002_mi1040.c
new file mode 100755 (executable)
index 0000000..7291b84
--- /dev/null
@@ -0,0 +1,629 @@
+
+#include "icatch7002_common.h"
+/*
+*      Driver Version Note
+*v0.0.1: this driver is compatible with generic_sensor
+*v0.0.3:
+*        add sensor_focus_af_const_pause_usr_cb;
+*/
+static int version = KERNEL_VERSION(0,0,3);
+module_param(version, int, S_IRUGO);
+
+
+
+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)
+
+/* Sensor Driver Configuration Begin */
+#define SENSOR_NAME RK29_CAM_ISP_ICATCH7002_MI1040
+#define SENSOR_V4L2_IDENT V4L2_IDENT_ICATCH7002_MI1040
+#define SENSOR_ID 0x2481
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                                                 SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\
+                                                 SOCAM_DATA_ACTIVE_HIGH|SOCAM_DATAWIDTH_8      |SOCAM_MCLK_24MHZ)
+#define SENSOR_PREVIEW_W                                        1280
+#define SENSOR_PREVIEW_H                                        960
+#define SENSOR_PREVIEW_FPS                                      30000     // 15fps 
+#define SENSOR_FULLRES_L_FPS                            15000     // 7.5fps
+#define SENSOR_FULLRES_H_FPS                            15000     // 7.5fps
+#define SENSOR_720P_FPS                                         0
+#define SENSOR_1080P_FPS                                        0
+
+                                                                       
+static unsigned int SensorConfiguration = 0;
+static unsigned int SensorChipID[] = {SENSOR_ID};
+/* Sensor Driver Configuration End */
+
+
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))
+//#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)
+
+//#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)
+//#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))
+//#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))
+//#define sensor_write_array generic_sensor_write_array
+
+
+
+/*
+*  The follow setting need been filled.
+*  
+*  Must Filled:
+*  sensor_init_data :                          Sensor initial setting;
+*  sensor_fullres_lowfps_data :        Sensor full resolution setting with best auality, recommand for video;
+*  sensor_preview_data :                       Sensor preview resolution setting, recommand it is vga or svga;
+*  sensor_softreset_data :                     Sensor software reset register;
+*  sensor_check_id_data :                      Sensir chip id register;
+*
+*  Optional filled:
+*  sensor_fullres_highfps_data:        Sensor full resolution setting with high framerate, recommand for video;
+*  sensor_720p:                                        Sensor 720p setting, it is for video;
+*  sensor_1080p:                                       Sensor 1080p setting, it is for video;
+*
+*  :::::WARNING:::::
+*  The SensorEnd which is the setting end flag must be filled int the last of each setting;
+*/
+
+/* Sensor initial setting */
+static struct rk_sensor_reg sensor_init_data[] ={
+    SensorStreamChk,
+       SensorEnd
+};
+/* Senor full resolution setting: recommand for capture */
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={
+       SensorEnd
+
+};
+
+/* Senor full resolution setting: recommand for video */
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={
+       SensorEnd
+};
+/* Preview resolution setting*/
+static struct rk_sensor_reg sensor_preview_data[] =
+{
+    SensorStreamChk,
+       SensorEnd
+};
+/* 1280x720 */
+static struct rk_sensor_reg sensor_720p[]={
+       SensorEnd
+};
+
+/* 1920x1080 */
+static struct rk_sensor_reg sensor_1080p[]={
+       SensorEnd
+};
+
+
+static struct rk_sensor_reg sensor_softreset_data[]={
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_check_id_data[]={
+       SensorEnd
+};
+/*
+*  The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx
+*/
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=
+{
+       SensorEnd
+};
+/* Cloudy Colour Temperature : 6500K - 8000K  */
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=
+{
+       SensorEnd
+};
+/* ClearDay Colour Temperature : 5000K - 6500K */
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=
+{
+       //Sunny
+       SensorEnd
+};
+/* Office Colour Temperature : 3500K - 5000K  */
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=
+{
+       //Office
+       SensorEnd
+
+};
+/* Home Colour Temperature : 2500K - 3500K     */
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=
+{
+       //Home
+       SensorEnd
+};
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,
+       sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,
+};
+
+static struct rk_sensor_reg sensor_Brightness0[]=
+{
+       // Brightness -2
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Brightness1[]=
+{
+       // Brightness -1
+
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Brightness2[]=
+{
+       //      Brightness 0
+
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Brightness3[]=
+{
+       // Brightness +1
+
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Brightness4[]=
+{
+       //      Brightness +2
+
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Brightness5[]=
+{
+       //      Brightness +3
+
+       SensorEnd
+};
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,
+       sensor_Brightness4, sensor_Brightness5,NULL,
+};
+
+static struct rk_sensor_reg sensor_Effect_Normal[] =
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Effect_WandB[] =
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Effect_Sepia[] =
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Effect_Negative[] =
+{
+       //Negative
+       SensorEnd
+};
+static struct rk_sensor_reg sensor_Effect_Bluish[] =
+{
+       // Bluish
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Effect_Green[] =
+{
+       //      Greenish
+       SensorEnd
+};
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,
+       sensor_Effect_Bluish, sensor_Effect_Green,NULL,
+};
+
+static struct rk_sensor_reg sensor_Exposure0[]=
+{
+
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Exposure1[]=
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Exposure2[]=
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Exposure3[]=
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Exposure4[]=
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Exposure5[]=
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Exposure6[]=
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,
+       sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,
+};
+
+static struct rk_sensor_reg sensor_Saturation0[]=
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Saturation1[]=
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Saturation2[]=
+{
+       SensorEnd
+};
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};
+
+static struct rk_sensor_reg sensor_Contrast0[]=
+{
+
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Contrast1[]=
+{
+
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Contrast2[]=
+{
+
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Contrast3[]=
+{
+
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Contrast4[]=
+{
+
+       SensorEnd
+};
+
+
+static struct rk_sensor_reg sensor_Contrast5[]=
+{
+
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Contrast6[]=
+{
+
+       SensorEnd
+};
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,
+       sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,
+};
+static struct rk_sensor_reg sensor_SceneAuto[] =
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_SceneNight[] =
+{
+       SensorEnd
+};
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};
+
+static struct rk_sensor_reg sensor_Zoom0[] =
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Zoom1[] =
+{
+       SensorEnd
+};
+
+static struct rk_sensor_reg sensor_Zoom2[] =
+{
+       SensorEnd
+};
+
+
+static struct rk_sensor_reg sensor_Zoom3[] =
+{
+       SensorEnd
+};
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};
+
+/*
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu
+*/
+static struct v4l2_querymenu sensor_menus[] =
+{
+       //white balance
+       new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,0,"auto",0),
+       new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,1,"incandescent",0),
+       new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,2,"fluorescent",0),
+       new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,3,"daylight",0),
+       new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,4,"cloudy-daylight",0),
+
+       //speical effect
+       new_usr_v4l2menu(V4L2_CID_EFFECT,0,"normal",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,1,"aqua",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,2,"negative",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,3,"sepia",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,4,"mono",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,5,"none",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,6,"aura",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,7,"vintage",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,8,"vintage2",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,9,"lomo",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,10,"red",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,11,"blue",0),
+       new_usr_v4l2menu(V4L2_CID_EFFECT,12,"green",0),
+
+    //scence
+       new_usr_v4l2menu(V4L2_CID_SCENE,0,"normal",0),
+       new_usr_v4l2menu(V4L2_CID_SCENE,1,"auto",0),
+       new_usr_v4l2menu(V4L2_CID_SCENE,2,"landscape",0),
+       new_usr_v4l2menu(V4L2_CID_SCENE,3,"night",0),
+       new_usr_v4l2menu(V4L2_CID_SCENE,4,"night_portrait",0),
+       new_usr_v4l2menu(V4L2_CID_SCENE,5,"snow",0),
+       new_usr_v4l2menu(V4L2_CID_SCENE,6,"sports",0),
+       new_usr_v4l2menu(V4L2_CID_SCENE,7,"candlelight",0),
+
+       //antibanding
+       new_usr_v4l2menu(V4L2_CID_ANTIBANDING,0,"50hz",0),
+       new_usr_v4l2menu(V4L2_CID_ANTIBANDING,1,"60hz",0),
+
+       //ISO
+       new_usr_v4l2menu(V4L2_CID_ISO,0,"auto",0),
+       new_usr_v4l2menu(V4L2_CID_ISO,1,"50",0),
+       new_usr_v4l2menu(V4L2_CID_ISO,2,"100",0),
+       new_usr_v4l2menu(V4L2_CID_ISO,3,"200",0),
+       new_usr_v4l2menu(V4L2_CID_ISO,4,"400",0),
+       new_usr_v4l2menu(V4L2_CID_ISO,5,"800",0),
+       new_usr_v4l2menu(V4L2_CID_ISO,6,"1600",0),
+};
+/*
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl
+*/
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =
+{
+       new_user_v4l2ctrl(V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU,"White Balance Control", 0, 4, 1, 0,sensor_set_get_control_cb, NULL),
+//     new_user_v4l2ctrl(V4L2_CID_BRIGHTNESS,V4L2_CTRL_TYPE_INTEGER,"Brightness Control", -3, 2, 1, 0,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -3, 3, 1, 0,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 12, 1, 5,sensor_set_get_control_cb, NULL),
+//     new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_SCENE,V4L2_CTRL_TYPE_MENU,"Scene Control", 0, 7, 1, 1,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_ANTIBANDING,V4L2_CTRL_TYPE_MENU,"Antibanding Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_WHITEBALANCE_LOCK,V4L2_CTRL_TYPE_BOOLEAN,"WhiteBalanceLock Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_EXPOSURE_LOCK,V4L2_CTRL_TYPE_BOOLEAN,"ExposureLock Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_METERING_AREAS,V4L2_CTRL_TYPE_INTEGER,"MeteringAreas Control", 0, 1, 1, 1,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_WDR,V4L2_CTRL_TYPE_BOOLEAN,"WDR Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_EDGE,V4L2_CTRL_TYPE_BOOLEAN,"EDGE Control", 0, 1, 1, 1,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_JPEG_EXIF,V4L2_CTRL_TYPE_BOOLEAN,"Exif Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL),
+       new_user_v4l2ctrl(V4L2_CID_ISO,V4L2_CTRL_TYPE_MENU,"Exif Control", 0, 6, 1, 0,sensor_set_get_control_cb, NULL),
+};
+
+//MUST define the current used format as the first item   
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {
+       {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} 
+};
+
+
+/*
+**********************************************************
+* Following is local code:
+* 
+* Please codeing your program here 
+**********************************************************
+*/
+/*
+**********************************************************
+* Following is callback
+* If necessary, you could coding these callback
+**********************************************************
+*/
+/*
+* the function is called in open sensor  
+*/
+static int sensor_activate_cb(struct i2c_client *client)
+{
+    return  icatch_sensor_init(client);
+}
+/*
+* the function is called in close sensor
+*/
+static int sensor_deactivate_cb(struct i2c_client *client)
+{
+       
+       return 0;
+}
+/*
+* the function is called before sensor register setting in VIDIOC_S_FMT  
+*/
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)
+{
+    return icatch_s_fmt(client, mf);
+}
+/*
+* the function is called after sensor register setting finished in VIDIOC_S_FMT  
+*/
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)
+{
+       return 0;
+}
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)
+{
+       return 0;
+}
+
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)
+{
+       
+       return 0;
+}
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)
+{
+       struct generic_sensor *sensor = to_generic_sensor(client);
+       return sensor->info_priv.chip_id[0];
+}
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
+{
+       //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+               
+       if (pm_msg.event == PM_EVENT_SUSPEND) {
+               SENSOR_DG("Suspend");
+               
+       } else {
+               SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int sensor_resume(struct soc_camera_device *icd)
+{
+
+       SENSOR_DG("Resume");
+
+       return 0;
+
+}
+/*
+* the function is v4l2 control V4L2_CID_HFLIP callback 
+*/
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, 
+                                                                                                        struct v4l2_ext_control *ext_ctrl)
+{
+       return 0;
+}
+
+/*
+* the function is v4l2 control V4L2_CID_VFLIP callback 
+*/
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, 
+                                                                                                        struct v4l2_ext_control *ext_ctrl)
+{
+       return 0;
+}
+/*
+* the function is v4l2 control V4L2_CID_HFLIP callback 
+*/
+
+static int sensor_flip_cb(struct i2c_client *client, int flip)
+{
+    int err = 0;    
+
+    return err;    
+}
+static int sensor_mirror_cb(struct i2c_client *client, int flip)
+{
+    int err = 0;    
+
+    return err;    
+}
+
+/*
+* the functions are focus callbacks
+*/
+static int sensor_focus_init_usr_cb(struct i2c_client *client){
+       return 0;
+}
+
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){
+       return 0;
+}
+
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){
+       return 0;
+}
+
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){
+       return 0;
+}
+
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){
+       return 0;
+}
+
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){
+
+       return 0;
+}
+static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client)
+{
+    return 0;
+}
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){
+       return 0;
+}
+
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client, int *zone_tm_pos)
+{
+       return 0;
+}
+
+/*
+face defect call back
+*/
+static int     sensor_face_detect_usr_cb(struct i2c_client *client,int on){
+       return 0;
+}
+
+/*
+*      The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some
+* initialization in the function. 
+*/
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)
+{
+       spsensor->common_sensor.sensor_cb.sensor_s_stream_cb = icatch_s_stream;
+    spsensor->common_sensor.sensor_cb.sensor_enum_framesizes = icatch_enum_framesizes;
+
+       spsensor->isp_priv_info.outputSize =OUTPUT_QUADVGA;
+       spsensor->isp_priv_info.supportedSizeNum = 1;
+       spsensor->isp_priv_info.supportedSize[0] = OUTPUT_QUADVGA;
+
+
+       return;
+}
+
+/*
+* :::::WARNING:::::
+* It is not allowed to modify the following code
+*/
+
+sensor_init_parameters_default_code();
+
+sensor_v4l2_struct_initialization();
+
+sensor_probe_default_code();
+
+sensor_remove_default_code();
+
+sensor_driver_default_module_code();
+
+
+
+
diff --git a/drivers/media/video/icatch7002/icatch7002_ov5693.c b/drivers/media/video/icatch7002/icatch7002_ov5693.c
new file mode 100755 (executable)
index 0000000..755d21b
--- /dev/null
@@ -0,0 +1,638 @@
+\r
+#include "icatch7002_common.h"\r
+/*\r
+*      Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*v0.0.3:\r
+*        add sensor_focus_af_const_pause_usr_cb;\r
+*/\r
+static int version = KERNEL_VERSION(0,0,3);\r
+module_param(version, int, S_IRUGO);\r
+\r
+\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
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_ISP_ICATCH7002_OV5693\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_ICATCH7002_OV5693\r
+#define SENSOR_ID 0x5690\r
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\\r
+                                                 SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
+                                                 SOCAM_DATA_ACTIVE_HIGH|SOCAM_DATAWIDTH_8      |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W                                        1280\r
+#define SENSOR_PREVIEW_H                                        960\r
+#define SENSOR_PREVIEW_FPS                                      30000     // 15fps \r
+#define SENSOR_FULLRES_L_FPS                            15000     // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS                            15000     // 7.5fps\r
+#define SENSOR_720P_FPS                                         0\r
+#define SENSOR_1080P_FPS                                        0\r
+\r
+                                                                       \r
+static unsigned int SensorConfiguration = CFG_Focus |CFG_FocusContinues|CFG_FocusZone;\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+//#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+//#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+//#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+//#define sensor_write_array generic_sensor_write_array\r
+\r
+\r
+\r
+/*\r
+*  The follow setting need been filled.\r
+*  \r
+*  Must Filled:\r
+*  sensor_init_data :                          Sensor initial setting;\r
+*  sensor_fullres_lowfps_data :        Sensor full resolution setting with best auality, recommand for video;\r
+*  sensor_preview_data :                       Sensor preview resolution setting, recommand it is vga or svga;\r
+*  sensor_softreset_data :                     Sensor software reset register;\r
+*  sensor_check_id_data :                      Sensir chip id register;\r
+*\r
+*  Optional filled:\r
+*  sensor_fullres_highfps_data:        Sensor full resolution setting with high framerate, recommand for video;\r
+*  sensor_720p:                                        Sensor 720p setting, it is for video;\r
+*  sensor_1080p:                                       Sensor 1080p setting, it is for video;\r
+*\r
+*  :::::WARNING:::::\r
+*  The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+    SensorStreamChk,\r
+       SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+    SensorStreamChk,\r
+       SensorEnd\r
+\r
+};\r
+\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+       SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+    SensorStreamChk,\r
+       SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+       SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+       SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+       SensorEnd\r
+};\r
+/*\r
+*  The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+       SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K  */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+       SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+       //Sunny\r
+       SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K  */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+       //Office\r
+       SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K     */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+       //Home\r
+       SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+       sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+       // Brightness -2\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+       // Brightness -1\r
+\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+       //      Brightness 0\r
+\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+       // Brightness +1\r
+\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+       //      Brightness +2\r
+\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+       //      Brightness +3\r
+\r
+       SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+       sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+       //Negative\r
+       SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+       // Bluish\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+       //      Greenish\r
+       SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+       sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+       sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+       SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+\r
+       SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+\r
+       SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+       sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+       SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+       SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+       SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+       SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+       //white balance\r
+       new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,0,"auto",0),\r
+       new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,1,"incandescent",0),\r
+       new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,2,"fluorescent",0),\r
+       new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,3,"daylight",0),\r
+       new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,4,"cloudy-daylight",0),\r
+\r
+       //speical effect\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,0,"normal",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,1,"aqua",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,2,"negative",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,3,"sepia",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,4,"mono",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,5,"none",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,6,"aura",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,7,"vintage",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,8,"vintage2",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,9,"lomo",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,10,"red",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,11,"blue",0),\r
+       new_usr_v4l2menu(V4L2_CID_EFFECT,12,"green",0),\r
+\r
+    //scence\r
+       new_usr_v4l2menu(V4L2_CID_SCENE,0,"normal",0),\r
+       new_usr_v4l2menu(V4L2_CID_SCENE,1,"auto",0),\r
+       new_usr_v4l2menu(V4L2_CID_SCENE,2,"landscape",0),\r
+       new_usr_v4l2menu(V4L2_CID_SCENE,3,"night",0),\r
+       new_usr_v4l2menu(V4L2_CID_SCENE,4,"night_portrait",0),\r
+       new_usr_v4l2menu(V4L2_CID_SCENE,5,"snow",0),\r
+       new_usr_v4l2menu(V4L2_CID_SCENE,6,"sports",0),\r
+       new_usr_v4l2menu(V4L2_CID_SCENE,7,"candlelight",0),\r
+\r
+       //antibanding\r
+       new_usr_v4l2menu(V4L2_CID_ANTIBANDING,0,"50hz",0),\r
+       new_usr_v4l2menu(V4L2_CID_ANTIBANDING,1,"60hz",0),\r
+\r
+       //ISO\r
+       new_usr_v4l2menu(V4L2_CID_ISO,0,"auto",0),\r
+       new_usr_v4l2menu(V4L2_CID_ISO,1,"50",0),\r
+       new_usr_v4l2menu(V4L2_CID_ISO,2,"100",0),\r
+       new_usr_v4l2menu(V4L2_CID_ISO,3,"200",0),\r
+       new_usr_v4l2menu(V4L2_CID_ISO,4,"400",0),\r
+       new_usr_v4l2menu(V4L2_CID_ISO,5,"800",0),\r
+       new_usr_v4l2menu(V4L2_CID_ISO,6,"1600",0),\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+       new_user_v4l2ctrl(V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU,"White Balance Control", 0, 4, 1, 0,sensor_set_get_control_cb, NULL),\r
+//     new_user_v4l2ctrl(V4L2_CID_BRIGHTNESS,V4L2_CTRL_TYPE_INTEGER,"Brightness Control", -3, 2, 1, 0,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -3, 3, 1, 0,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 12, 1, 5,sensor_set_get_control_cb, NULL),\r
+//     new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_SCENE,V4L2_CTRL_TYPE_MENU,"Scene Control", 0, 7, 1, 1,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_ANTIBANDING,V4L2_CTRL_TYPE_MENU,"Antibanding Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_WHITEBALANCE_LOCK,V4L2_CTRL_TYPE_BOOLEAN,"WhiteBalanceLock Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_EXPOSURE_LOCK,V4L2_CTRL_TYPE_BOOLEAN,"ExposureLock Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_METERING_AREAS,V4L2_CTRL_TYPE_INTEGER,"MeteringAreas Control", 0, 1, 1, 1,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_WDR,V4L2_CTRL_TYPE_BOOLEAN,"WDR Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_EDGE,V4L2_CTRL_TYPE_BOOLEAN,"EDGE Control", 0, 1, 1, 1,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_JPEG_EXIF,V4L2_CTRL_TYPE_BOOLEAN,"Exif Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL),\r
+       new_user_v4l2ctrl(V4L2_CID_ISO,V4L2_CTRL_TYPE_MENU,"Exif Control", 0, 6, 1, 0,sensor_set_get_control_cb, NULL),\r
+\r
+//     new_user_v4l2ctrl(V4L2_CID_FOCUSZONE,V4L2_CTRL_TYPE_BOOLEAN,"FocusZone Control", 0, 1, 1, 1,sensor_focus_default_cb, NULL),\r
+//     new_user_v4l2ctrl(V4L2_CID_FOCUS_ABSOLUTE,V4L2_CTRL_TYPE_INTEGER,"Focus Control", 0, 0xff, 1, 0,sensor_focus_default_cb, NULL),\r
+//     new_user_v4l2ctrl(V4L2_CID_FOCUS_AUTO,V4L2_CTRL_TYPE_BOOLEAN,"Focus Control", 0, 1, 1, 0,sensor_focus_default_cb, NULL),\r
+//     new_user_v4l2ctrl(V4L2_CID_FOCUS_CONTINUOUS,V4L2_CTRL_TYPE_BOOLEAN,"Focus Control", 0, 1, 1, 0,sensor_focus_default_cb, NULL),\r
+};\r
+\r
+//MUST define the current used format as the first item   \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+       {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor  \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+    return  icatch_sensor_init(client);\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+       \r
+       return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT  \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+    return icatch_s_fmt(client, mf);\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT  \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+       return 0;\r
+}\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+       return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+       \r
+       return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+       struct generic_sensor *sensor = to_generic_sensor(client);\r
+       return sensor->info_priv.chip_id[0];\r
+}\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\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("Suspend");\r
+               \r
+       } else {\r
+               SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+               return -EINVAL;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+       SENSOR_DG("Resume");\r
+\r
+       return 0;\r
+\r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+                                                                                                        struct v4l2_ext_control *ext_ctrl)\r
+{\r
+       return 0;\r
+}\r
+\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+                                                                                                        struct v4l2_ext_control *ext_ctrl)\r
+{\r
+       return 0;\r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+    int err = 0;    \r
+\r
+    return err;    \r
+}\r
+static int sensor_mirror_cb(struct i2c_client *client, int flip)\r
+{\r
+    int err = 0;    \r
+\r
+    return err;    \r
+}\r
+\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+       return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+       return icatch_sensor_set_auto_focus(client, WqCmd_af_single,NULL);\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+       return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+       return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+       return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+\r
+       return icatch_sensor_set_auto_focus(client, WqCmd_af_continues,NULL);\r
+}\r
+static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client)\r
+{\r
+    return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+       return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client, int *zone_tm_pos)\r
+{\r
+       return icatch_sensor_set_auto_focus(client, WqCmd_af_update_zone,zone_tm_pos);\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int     sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+       return 0;\r
+}\r
+\r
+/*\r
+*      The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+       spsensor->common_sensor.sensor_cb.sensor_s_stream_cb = icatch_s_stream;\r
+       spsensor->isp_priv_info.focus_zone.lx = 256;\r
+       spsensor->isp_priv_info.focus_zone.rx = 768;\r
+       spsensor->isp_priv_info.focus_zone.ty = 256;\r
+       spsensor->isp_priv_info.focus_zone.dy = 768;\r
+    spsensor->common_sensor.sensor_cb.sensor_enum_framesizes = icatch_enum_framesizes;\r
+\r
+       spsensor->isp_priv_info.outputSize = OUTPUT_QSXGA|OUTPUT_QUADVGA;\r
+       spsensor->isp_priv_info.supportedSizeNum = 2;\r
+       spsensor->isp_priv_info.supportedSize[0] = OUTPUT_QUADVGA;\r
+       spsensor->isp_priv_info.supportedSize[1] = OUTPUT_QSXGA;\r
+       return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
+\r
diff --git a/drivers/media/video/icatch7002/icatch_spi_host.c b/drivers/media/video/icatch7002/icatch_spi_host.c
new file mode 100755 (executable)
index 0000000..4d220a0
--- /dev/null
@@ -0,0 +1,82 @@
+/*icatch  host mode ,spi device \r
+ *\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ */\r
+\r
+#include <linux/dma-mapping.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/highmem.h>\r
+#include <linux/delay.h>\r
+#include <linux/slab.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/clk.h>\r
+#include <linux/cpufreq.h>\r
+#include <mach/gpio.h>\r
+#include <mach/irqs.h>\r
+#include <linux/miscdevice.h>\r
+#include <asm/dma.h>\r
+#include <linux/preempt.h>\r
+#include <mach/board.h>\r
+#include "icatch_spi_host.h"\r
+#include <linux/miscdevice.h>\r
+struct spi_device* g_icatch_spi_dev = NULL;\r
+\r
+static int __devinit spi_icatch_probe(struct spi_device *spi)\r
+{      \r
+       struct spi_test_data *spi_test_data;\r
+       int ret = 0;\r
+       \r
+       spi->bits_per_word = 8;\r
+       spi->mode = SPI_MODE_0;\r
+       ret = spi_setup(spi);\r
+       if (ret < 0){\r
+               dev_err(spi, "ERR: fail to setup spi\n");\r
+               return -1;\r
+       }       \r
+\r
+       g_icatch_spi_dev = spi;\r
+\r
+       printk("%s:bus_num=%d,ok\n",__func__,spi->master->bus_num);\r
+\r
+       return ret;\r
+\r
+}\r
+\r
+\r
+static struct spi_driver spi_icatch_driver = {\r
+       .driver = {\r
+               .name           = "spi_icatch",\r
+               .bus            = &spi_bus_type,\r
+               .owner          = THIS_MODULE,\r
+       },\r
+\r
+       .probe          = spi_icatch_probe,\r
+};\r
+\r
+static struct miscdevice spi_test_icatch = {\r
+       .minor = MISC_DYNAMIC_MINOR,\r
+       .name = "spi_misc_icatch",\r
+};\r
+\r
+static int __init spi_icatch_init(void)\r
+{      \r
+       spi_register_board_info(board_spi_icatch_devices, ARRAY_SIZE(board_spi_icatch_devices));\r
+       \r
+       misc_register(&spi_test_icatch);\r
+       return spi_register_driver(&spi_icatch_driver);\r
+}\r
+\r
+static void __exit spi_icatch_exit(void)\r
+{\r
+       \r
+       misc_deregister(&spi_test_icatch);\r
+       return spi_unregister_driver(&spi_icatch_driver);\r
+}\r
+module_init(spi_icatch_init);\r
+module_exit(spi_icatch_exit);\r
+\r
+\r
diff --git a/drivers/media/video/icatch7002/icatch_spi_host.h b/drivers/media/video/icatch7002/icatch_spi_host.h
new file mode 100755 (executable)
index 0000000..70a73c6
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef ICATCH_SPI_HOST_H\r
+#define ICATCH_SPI_HOST_H\r
+#include "../../../spi/rk29_spim.h"\r
+#include <linux/spi/spi.h>\r
+\r
+static struct rk29xx_spi_chip spi_icatch = {\r
+       //.poll_mode = 1,\r
+       .enable_dma = 0,\r
+};\r
+//user must define this struct according to hardware config    \r
+static struct spi_board_info board_spi_icatch_devices[] = {    \r
+       {\r
+               .modalias  = "spi_icatch",\r
+               .bus_num = 0,   //0 or 1\r
+               .max_speed_hz  = 24*1000*1000,\r
+               .chip_select   = 0, \r
+               .mode = SPI_MODE_0,\r
+               .controller_data = &spi_icatch,\r
+       },      \r
+       \r
+};\r
+#endif\r
+\r
index 005d8afc4ea4d2d60e266b10cf078d32ad27955a..04eef257d075bc113be2dd72ac2321a7c11ef177 100755 (executable)
 #define SOFT_RST_CIF1 (SOFT_RST_MAX+1)
 #endif
 #include <asm/cacheflush.h>
-static int debug;
+static int debug = 0;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
+#if defined(CONFIG_TRACE_LOG_PRINTK)
+ #define RK30_CAM_DEBUG_TRACE(format, ...) printk(KERN_ERR"rk30_camera: " format, ## __VA_ARGS__)
+#else
+ #define RK30_CAM_DEBUG_TRACE(format, ...)
+#endif
+#define RK30_CAM_LOG_TRACE(format, ...) printk(KERN_WARNING"rk30_camera: " format, ## __VA_ARGS__)
+
 #define dprintk(level, fmt, arg...) do {                       \
        if (debug >= level)                                     \
        printk(KERN_WARNING"rk_camera: " fmt , ## arg); } while (0)
@@ -156,8 +163,9 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 
 #define MIN(x,y)   ((x<y) ? x: y)
 #define MAX(x,y)    ((x>y) ? x: y)
+#define RK_SENSOR_12MHZ      12*1000*1000 
 #define RK_SENSOR_24MHZ      24*1000*1000          /* MHz */
-#define RK_SENSOR_48MHZ      48
+#define RK_SENSOR_48MHZ      48*1000*1000
 
 #define write_cif_reg(base,addr, val)  __raw_writel(val, addr+(base))
 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
@@ -293,8 +301,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 *         2. fix 2928 digitzoom erro(arm crop scale) of selected zone;
 *v0.x.1f:
 *         1. support rk3188
+*v0.x.21:
+                 1. cif change mode to free run.support icatch 7002.
 */
-#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 4, 0x1f)
+#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 4, 0x21)
 
 /* limit to rk29 hardware capabilities */
 #define RK_CAM_BUS_PARAM   (SOCAM_MASTER |\
@@ -313,8 +323,8 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define RK_CAM_H_MIN        32
 #define RK_CAM_W_MAX        3856            /* ddl@rock-chips.com : 10M Pixel */
 #define RK_CAM_H_MAX        2764
-#define RK_CAM_FRAME_INVAL_INIT 3
-#define RK_CAM_FRAME_INVAL_DC 3          /* ddl@rock-chips.com :  */
+#define RK_CAM_FRAME_INVAL_INIT 0
+#define RK_CAM_FRAME_INVAL_DC 0          /* ddl@rock-chips.com :  */
 #define RK30_CAM_FRAME_MEASURE  5
 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
@@ -327,6 +337,7 @@ struct rk_camera_buffer
     enum v4l2_mbus_pixelcode   code;
     int                        inwork;
 };
+
 enum rk_camera_reg_state
 {
        Reg_Invalidate,
@@ -351,18 +362,22 @@ struct rk_camera_work
        struct rk_camera_dev *pcdev;
        struct work_struct work;
     struct list_head queue;
-    unsigned int index;    
+    unsigned int index; 
+    unsigned int ts;
 };
+
 struct rk_camera_frmivalenum
 {
     struct v4l2_frmivalenum fival;
     struct rk_camera_frmivalenum *nxt;
 };
+
 struct rk_camera_frmivalinfo
 {
     struct soc_camera_device *icd;
     struct rk_camera_frmivalenum *fival_list;
 };
+
 struct rk_camera_zoominfo
 {
     struct semaphore sem;
@@ -371,6 +386,7 @@ struct rk_camera_zoominfo
    int vir_height;
     int zoom_rate;
 };
+
 #if CAMERA_VIDEOBUF_ARM_ACCESS
 struct rk29_camera_vbinfo
 {
@@ -379,11 +395,39 @@ struct rk29_camera_vbinfo
     unsigned int size;
 };
 #endif
+
 struct rk_camera_timer{
        struct rk_camera_dev *pcdev;
        struct hrtimer timer;
     bool istarted;
-       };
+};
+struct rk_cif_clk
+{
+    //************must modify start************/
+    struct clk *pd_cif;
+    struct clk *aclk_cif;
+    struct clk *hclk_cif;
+    struct clk *cif_clk_in;
+    struct clk *cif_clk_out;
+    //************must modify end************/
+
+    spinlock_t lock;
+    bool on;
+};
+static struct rk_cif_clk  cif_clk[2];
+struct hdr_exposure
+{
+    unsigned int set_ts;
+    unsigned int get_ts;
+    unsigned int code;
+};
+struct rk_hdr_info_s
+{
+    bool en;
+    struct hdr_exposure frame[3];
+};
+#define CONFIG_CIF_STOP_SYNC 1
+
 struct rk_camera_dev
 {
        struct soc_camera_host  soc_host;
@@ -414,8 +458,9 @@ struct rk_camera_dev
        unsigned int vipmem_bsize;
 #if CAMERA_VIDEOBUF_ARM_ACCESS    
     struct rk29_camera_vbinfo *vbinfo;
-    unsigned int vbinfo_count;
-#endif    
+#endif  
+       unsigned int vbinfo_count;
+
        int host_width;
        int host_height;
        int host_left;  //sensor output size ?
@@ -447,8 +492,15 @@ struct rk_camera_dev
     bool timer_get_fps;
     unsigned int reinit_times; 
     struct videobuf_queue *video_vq;
-    bool stop_cif;
+    volatile bool stop_cif;
+#if CONFIG_CIF_STOP_SYNC
+       wait_queue_head_t cif_stop_done;
+       volatile  bool cif_stopped;
+#endif
     struct timeval first_tv;
+
+    struct rk_hdr_info_s  hdr_info;
+//     spinlock_t              irq_lock;
 };
 
 static const struct v4l2_queryctrl rk_camera_controls[] =
@@ -464,6 +516,18 @@ static const struct v4l2_queryctrl rk_camera_controls[] =
         .default_value = 100,
     },
     #endif
+
+    {
+        .id            = V4L2_CID_HDR,
+        .type          = V4L2_CTRL_TYPE_BOOLEAN,
+        .name          = "HDR",
+        .minimum       = 0,
+        .maximum       = 1,
+        .step          = 1,
+        .default_value = 0,
+    }
+
+    
 };
 
 static DEFINE_MUTEX(camera_lock);
@@ -472,6 +536,7 @@ static const char *rk_cam_driver_description = "RK_Camera";
 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
 static void rk_camera_capture_process(struct work_struct *work);
 
+#define OPTIMIZE_MEMORY_USE
 
 /*
  *  Videobuf operations
@@ -514,9 +579,11 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
         #endif
         {
             BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
+        #ifndef OPTIMIZE_MEMORY_USE
                if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) {    /* Buffers must be limited, when this resolution is genered by IPP */
                        *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
                }
+               #endif
         }
                if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
                        kfree(pcdev->camera_work);
@@ -527,7 +594,7 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
                if (pcdev->camera_work == NULL) {
                        pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
                        if (pcdev->camera_work == NULL) {
-                               RKCAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__);
+                               RK30_CAM_DEBUG_TRACE("\n %s kmalloc fail\n", __FUNCTION__);
                                BUG();
                        }
             INIT_LIST_HEAD(&pcdev->camera_work_queue);
@@ -549,7 +616,7 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
         if (pcdev->vbinfo == NULL) {
             pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
             if (pcdev->vbinfo == NULL) {
-                               RKCAMERA_TR("\n %s vbinfo kmalloc fail\n", __FUNCTION__);
+                               RK30_CAM_DEBUG_TRACE("\n %s vbinfo kmalloc fail\n", __FUNCTION__);
                                BUG();
                        }
             memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
@@ -557,8 +624,10 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
         }
 #endif        
        }
+       
+       pcdev->vbinfo_count = *count;
     pcdev->video_vq = vq;
-    RKCAMERA_DG("%s..%d.. videobuf size:%d, vipmem_buf size:%d, count:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_size, *count);
+    RK30_CAM_DEBUG_TRACE("%s..%d.. videobuf size:%d, vipmem_buf size:%d, count:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_size, *count);
 
     return 0;
 }
@@ -606,9 +675,9 @@ static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer
     BUG_ON(NULL == icd->current_fmt);
 
     if (buf->code    != icd->current_fmt->code ||
-            vb->width   != icd->user_width ||
-            vb->height  != icd->user_height ||
-             vb->field   != field) {
+        vb->width   != icd->user_width ||
+        vb->height  != icd->user_height ||
+        vb->field   != field) {
         buf->code    = icd->current_fmt->code;
         vb->width   = icd->user_width;
         vb->height  = icd->user_height;
@@ -637,6 +706,38 @@ out:
     return ret;
 }
 
+#if 0
+static void rk_camera_store_register(struct rk_camera_dev *pcdev)
+{
+#if defined(CONFIG_ARCH_RK3188)
+       pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
+       pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
+       pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
+       pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
+       pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
+       pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
+       pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
+       
+       cru_set_soft_reset(SOFT_RST_CIF0, true);
+       udelay(3);
+       cru_set_soft_reset(SOFT_RST_CIF0, false);
+       
+#endif
+}
+static void rk_camera_restore_register(struct rk_camera_dev *pcdev)
+{
+#if defined(CONFIG_ARCH_RK3188)
+       write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
+       write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
+       write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
+       write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
+       write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
+       write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
+       write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
+#endif
+}
+#endif
+
 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev, int fmt_ready)
 {
        unsigned int y_addr,uv_addr;
@@ -644,13 +745,18 @@ static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_came
 
     if (vb) {
                if (CAM_WORKQUEUE_IS_EN()) {
+                   #ifdef OPTIMIZE_MEMORY_USE
+                       y_addr = vb->boff;
+                       uv_addr = y_addr + vb->width * vb->height;
+                   #else
                        y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
                        uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
                        if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
-                               RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
+                               RK30_CAM_DEBUG_TRACE("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
                                                  pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
                                BUG();
                        }
+                       #endif
                } else {
                        y_addr = vb->boff;
                        uv_addr = y_addr + vb->width * vb->height;
@@ -667,7 +773,7 @@ static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_came
                        write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
                                break;
                        default:
-                               RKCAMERA_TR("%s(%d): fmt_ready(%d) is wrong!\n", __FUNCTION__, __LINE__,fmt_ready);
+                               RK30_CAM_DEBUG_TRACE("%s(%d): fmt_ready(%d) is wrong!\n", __FUNCTION__, __LINE__,fmt_ready);
                                break;
                }
       
@@ -686,6 +792,7 @@ static void rk_videobuf_queue(struct videobuf_queue *vq,
 
     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
             vb, vb->baddr, vb->bsize);
+   // spin_lock_irqsave(&pcdev->irq_lock, flags);
 
     vb->state = VIDEOBUF_QUEUED;
        if (list_empty(&pcdev->capture)) {
@@ -716,20 +823,23 @@ static void rk_videobuf_queue(struct videobuf_queue *vq,
                 vb_info->size = vb->bsize;
                 vb_info->phy_addr = vb->boff;
             } else {
-                RKCAMERA_TR("%s..%d:ioremap videobuf %d failed\n",__FUNCTION__,__LINE__, vb->i);
+                RK30_CAM_DEBUG_TRACE("%s..%d:ioremap videobuf %d failed\n",__FUNCTION__,__LINE__, vb->i);
             }
         }
     }
-#endif    
-    if (!pcdev->active0) {
-        pcdev->active0 = vb;
-        rk_videobuf_capture(vb,pcdev,0);
-               list_del_init(&(vb->queue));
-    } else if (!pcdev->active1) {
-        pcdev->active1 = vb;
-        rk_videobuf_capture(vb,pcdev,1);
-               list_del_init(&(vb->queue));
+#endif
+    if((((read_cif_reg(pcdev->base,CIF_CIF_CTRL)) & ENABLE_CAPTURE) == 0)){
+        if (!pcdev->active0) {
+            pcdev->active0 = vb;
+            rk_videobuf_capture(vb,pcdev,0);
+               list_del_init(&(vb->queue));
+        } else if (!pcdev->active1) {
+            pcdev->active1 = vb;
+            rk_videobuf_capture(vb,pcdev,1);
+               list_del_init(&(vb->queue));
+        }
     }
+       //spin_unlock_irqrestore(&pcdev->irq_lock, flags);
 }
 static int rk_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
 {
@@ -756,6 +866,7 @@ rk_pixfmt2ippfmt_err:
        return -1;
 }
 
+#if 0
 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
 {
        switch (pixfmt)
@@ -792,6 +903,8 @@ static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
 rk_pixfmt2rgafmt_err:
        return -1;
 }
+#endif
+
 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
 static int rk_camera_scale_crop_pp(struct work_struct *work){
        struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
@@ -852,7 +965,7 @@ static int rk_camera_scale_crop_rga(struct work_struct *work){
        vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
        if((pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB565)
                && (pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB24)){
-               RKCAMERA_TR("RGA not support this format !\n");
+               RK30_CAM_DEBUG_TRACE("RGA not support this format !\n");
                goto do_ipp_err;
                }
        if ((pcdev->icd->user_width > 0x800) || (pcdev->icd->user_height > 0x800)) {
@@ -917,13 +1030,13 @@ static int rk_camera_scale_crop_rga(struct work_struct *work){
                        req.dst.x_offset =  pcdev->icd->user_width*w/scale_times;
                        req.dst.y_offset = pcdev->icd->user_height*h/scale_times;
                        req.dst.yrgb_addr = vb->boff ;
-               //      RKCAMERA_TR("src.act_w = %d , src.act_h  = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.src.act_w,req.src.act_h ,req.src.vir_w,req.src.vir_h,req.src.x_offset,req.src.y_offset);
-               //      RKCAMERA_TR("dst.act_w = %d , dst.act_h  = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.dst.act_w,req.dst.act_h ,req.dst.vir_w,req.dst.vir_h,req.dst.x_offset,req.dst.y_offset);
-               //      RKCAMERA_TR("req.src.yrgb_addr = 0x%x,req.dst.yrgb_addr = 0x%x\n",req.src.yrgb_addr,req.dst.yrgb_addr);
+               //      RK30_CAM_DEBUG_TRACE("src.act_w = %d , src.act_h  = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.src.act_w,req.src.act_h ,req.src.vir_w,req.src.vir_h,req.src.x_offset,req.src.y_offset);
+               //      RK30_CAM_DEBUG_TRACE("dst.act_w = %d , dst.act_h  = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.dst.act_w,req.dst.act_h ,req.dst.vir_w,req.dst.vir_h,req.dst.x_offset,req.dst.y_offset);
+               //      RK30_CAM_DEBUG_TRACE("req.src.yrgb_addr = 0x%x,req.dst.yrgb_addr = 0x%x\n",req.src.yrgb_addr,req.dst.yrgb_addr);
 
                        while(rga_times-- > 0) {
                                if (rga_blit_sync(&session, &req)){
-                                       RKCAMERA_TR("rga do erro,do again,rga_times = %d!\n",rga_times);
+                                       RK30_CAM_DEBUG_TRACE("rga do erro,do again,rga_times = %d!\n",rga_times);
                                 } else {
                                        break;
                                 }
@@ -967,7 +1080,7 @@ static int rk_camera_scale_crop_ipp(struct work_struct *work)
        struct rk29_ipp_req ipp_req;
        int src_y_offset,src_uv_offset,dst_y_offset,dst_uv_offset,src_y_size,dst_y_size;
        int scale_times,w,h;
-        int ret = 0;
+       int ret = 0;
     /*
     *ddl@rock-chips.com: 
     * IPP Dest image resolution is 2047x1088, so scale operation break up some times
@@ -979,7 +1092,49 @@ static int rk_camera_scale_crop_ipp(struct work_struct *work)
         scale_times = 1;
     }
     memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
-
+#ifdef OPTIMIZE_MEMORY_USE
+    //need copy to ipp buffer?
+    if((pcdev->zoominfo.a.c.width != pcdev->zoominfo.vir_width)
+        ||(pcdev->zoominfo.a.c.height != pcdev->zoominfo.vir_height)){
+            if((pcdev->zoominfo.vir_width != pcdev->icd->user_width) || (pcdev->zoominfo.vir_height != pcdev->icd->user_height)){
+                printk("OPTIMIZE_MEMORY_USE erro: src size not equal to dst size\n");
+                goto do_ipp_err;
+            }
+            ipp_req.timeout = 3000;
+            ipp_req.flag = IPP_ROT_0; 
+            ipp_req.store_clip_mode =1;
+            ipp_req.src0.w = pcdev->zoominfo.vir_width/scale_times;
+            ipp_req.src0.h = pcdev->zoominfo.vir_height/scale_times;
+            ipp_req.dst0.w = pcdev->icd->user_width/scale_times;
+            ipp_req.dst0.h = pcdev->icd->user_height/scale_times;
+            ipp_req.src_vir_w =  pcdev->zoominfo.vir_width; 
+            ipp_req.dst_vir_w = pcdev->icd->user_width; 
+            rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
+            rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
+            vipdata_base = pcdev->vipmem_phybase;
+            src_y_size = pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;  //vipmem
+            dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height;
+            for (h=0; h<scale_times; h++) {
+                for (w=0; w<scale_times; w++) {
+                    src_y_offset = (h*pcdev->zoominfo.vir_height/scale_times)* pcdev->zoominfo.vir_width 
+                                +  w*pcdev->zoominfo.vir_width/scale_times;
+                           src_uv_offset = (h*pcdev->zoominfo.vir_height/scale_times)* pcdev->zoominfo.vir_width/2
+                                + w*pcdev->zoominfo.vir_width/scale_times;
+
+                    dst_y_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times + pcdev->icd->user_width*w/scale_times;
+                    dst_uv_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times/2 + pcdev->icd->user_width*w/scale_times;
+                       ipp_req.src0.YrgbMst = vb->boff + src_y_offset;
+                       ipp_req.src0.CbrMst = vb->boff + src_y_size + src_uv_offset;
+                       ipp_req.dst0.YrgbMst = vipdata_base + dst_y_offset;
+                       ipp_req.dst0.CbrMst = vipdata_base + dst_y_size + dst_uv_offset;
+                    if (ipp_blit_sync(&ipp_req)){
+                        RK30_CAM_DEBUG_TRACE("ipp do erro\n");
+                     }
+                 }
+             }
+            memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
+        }
+#endif
 
     ipp_req.timeout = 3000;
     ipp_req.flag = IPP_ROT_0; 
@@ -992,7 +1147,16 @@ static int rk_camera_scale_crop_ipp(struct work_struct *work)
     ipp_req.dst0.h = pcdev->icd->user_height/scale_times;
     ipp_req.dst_vir_w = pcdev->icd->user_width;        
     rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
+#ifdef OPTIMIZE_MEMORY_USE
+    if((pcdev->zoominfo.a.c.width != pcdev->zoominfo.vir_width)
+        ||(pcdev->zoominfo.a.c.height != pcdev->zoominfo.vir_height)){
+        vipdata_base = pcdev->vipmem_phybase;
+    }else
+        vipdata_base = vb->boff;
+
+#else
     vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
+#endif
     src_y_size = pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;  //vipmem
     dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height;
     for (h=0; h<scale_times; h++) {
@@ -1012,7 +1176,7 @@ static int rk_camera_scale_crop_ipp(struct work_struct *work)
                ipp_req.dst0.CbrMst = vb->boff + dst_y_size + dst_uv_offset;
                while(ipp_times-- > 0) {
                 if (ipp_blit_sync(&ipp_req)){
-                    RKCAMERA_TR("ipp do erro,do again,ipp_times = %d!\n",ipp_times);
+                    RK30_CAM_DEBUG_TRACE("ipp do erro,do again,ipp_times = %d!\n",ipp_times);
                  } else {
                     break;
                  }
@@ -1022,17 +1186,17 @@ static int rk_camera_scale_crop_ipp(struct work_struct *work)
                        spin_lock_irqsave(&pcdev->lock, flags);
                        vb->state = VIDEOBUF_NEEDS_INIT;
                        spin_unlock_irqrestore(&pcdev->lock, flags);
-                       RKCAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
-                       RKCAMERA_TR("widx:%d hidx:%d ",w,h);
-                       RKCAMERA_TR("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height);
-                       RKCAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
-                       RKCAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
-                       RKCAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
-                       RKCAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
-                       RKCAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
-                       RKCAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
-                       RKCAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
-                       RKCAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
+                       RK30_CAM_DEBUG_TRACE("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
+                       RK30_CAM_DEBUG_TRACE("widx:%d hidx:%d ",w,h);
+                       RK30_CAM_DEBUG_TRACE("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height);
+                       RK30_CAM_DEBUG_TRACE("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
+                       RK30_CAM_DEBUG_TRACE("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
+                       RK30_CAM_DEBUG_TRACE("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
+                       RK30_CAM_DEBUG_TRACE("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+                       RK30_CAM_DEBUG_TRACE("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
+                       RK30_CAM_DEBUG_TRACE("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
+                       RK30_CAM_DEBUG_TRACE("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
+                       RK30_CAM_DEBUG_TRACE("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
                 
                        goto do_ipp_err;
                }
@@ -1070,8 +1234,8 @@ static int rk_camera_scale_crop_arm(struct work_struct *work)
     cropW = pcdev->zoominfo.a.c.width;
     cropH = pcdev->zoominfo.a.c.height;
        
-    psY = psY + (srcW-cropW)/2;
-    psUV = psUV + (srcW-cropW)/2
+    psY = psY + pcdev->zoominfo.a.c.top*pcdev->zoominfo.vir_width+pcdev->zoominfo.a.c.left;
+    psUV = psUV + pcdev->zoominfo.a.c.top*pcdev->zoominfo.vir_width/2+pcdev->zoominfo.a.c.left
     
     vb_info = pcdev->vbinfo+vb->i; 
     dst_phy = vb_info->phy_addr;
@@ -1080,9 +1244,8 @@ static int rk_camera_scale_crop_arm(struct work_struct *work)
     dstW = pcdev->icd->user_width;
     dstH = pcdev->icd->user_height;
 
-    zoomindstxIntInv = ((unsigned long)cropW<<16)/dstW + 1;
-    zoomindstyIntInv = ((unsigned long)cropH<<16)/dstH + 1;
+    zoomindstxIntInv = ((unsigned long)(cropW)<<16)/dstW + 1;
+    zoomindstyIntInv = ((unsigned long)(cropH)<<16)/dstH + 1;
     //y
     //for(y = 0; y<dstH - 1 ; y++ ) {   
     for(y = 0; y<dstH; y++ ) {   
@@ -1164,17 +1327,48 @@ rk_camera_scale_crop_arm_end:
        return ret;    
 }
 #endif
+
 static void rk_camera_capture_process(struct work_struct *work)
 {
     struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);    
     struct videobuf_buffer *vb = camera_work->vb;    
     struct rk_camera_dev *pcdev = camera_work->pcdev;    
     //enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code;    
+    struct device *control = to_soc_camera_control(pcdev->icd);
+    struct v4l2_subdev *sd=dev_get_drvdata(control);
     unsigned long flags = 0;    
-    int err = 0;    
+    int err = 0,i;    
 
     if (!CAM_WORKQUEUE_IS_EN())        
         goto rk_camera_capture_process_end; 
+
+    camera_work->vb->rk_code = 0x00;
+    if (pcdev->hdr_info.en) {
+               printk("rk_camera_capture_process hdr %d fps\n",camera_work->ts);
+        if (pcdev->hdr_info.frame[0].set_ts == 0) {
+            v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_HDR_EXPOSURE,(void*)pcdev->hdr_info.frame[0].code);
+            pcdev->hdr_info.frame[0].set_ts = pcdev->fps;
+            printk("set hdr %d @ %d fps\n",0,pcdev->fps);
+        } else {
+            if ((camera_work->ts - pcdev->hdr_info.frame[0].set_ts) > 1) {
+                for (i=0; i<3; i++) {
+                    if (pcdev->hdr_info.frame[i].get_ts == 0) {
+                                               printk("get hdr %d @ %d fps %dx%d\n",i,camera_work->ts,camera_work->vb->width,camera_work->vb->height);
+                        pcdev->hdr_info.frame[i].get_ts = camera_work->ts;
+                        RK_VIDEOBUF_CODE_SET(camera_work->vb->rk_code,pcdev->hdr_info.frame[i].code);
+                        break;
+                    }
+                }
+
+                if (i==2) {
+                    v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_HDR_EXPOSURE,(void*)RK_VIDEOBUF_HDR_EXPOSURE_FINISH);
+                    pcdev->hdr_info.en = false;
+                    printk("hdr off\n");
+                }
+            }
+        }
+    }
+    
     
     down(&pcdev->zoominfo.sem);
     if (pcdev->icd_cb.scale_crop_cb){
@@ -1193,13 +1387,41 @@ rk_camera_capture_process_end:
                vb->state = VIDEOBUF_DONE;
                vb->field_count++;
                }
-    }    
-    wake_up(&(camera_work->vb->done));     
+    }       
     spin_lock_irqsave(&pcdev->camera_work_lock, flags);    
-    list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);    
-    spin_unlock_irqrestore(&pcdev->camera_work_lock, flags);    
+    list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
+    spin_unlock_irqrestore(&pcdev->camera_work_lock, flags); 
+    wake_up(&(camera_work->vb->done));  
     return;
 }
+#if defined(CONFIG_ARCH_RK3188)
+static void rk_camera_store_resore_register(struct rk_camera_dev *pcdev)
+{
+
+       pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
+       pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
+       pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
+       pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
+       pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
+       pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
+       pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
+       
+       cru_set_soft_reset(SOFT_RST_CIF0, true);
+       udelay(5);
+       cru_set_soft_reset(SOFT_RST_CIF0, false);
+       
+    if (pcdev->reginfo_suspend.cifCtrl&ENABLE_CAPTURE)
+        write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
+       write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
+       write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
+       write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
+       write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
+       write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
+       write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
+       
+}
+#endif
+
 static irqreturn_t rk_camera_irq(int irq, void *data)
 {
     struct rk_camera_dev *pcdev = data;
@@ -1209,33 +1431,88 @@ static irqreturn_t rk_camera_irq(int irq, void *data)
     unsigned long tmp_intstat;
     unsigned long tmp_cifctrl; 
        unsigned long tmp_cif_frmst; 
-       struct videobuf_buffer **active;
+       struct videobuf_buffer **active = 0;
        int flag = 0;
+        unsigned int invalid_y_addr ,invalid_uv_addr;
+#ifdef OPTIMIZE_MEMORY_USE
+       invalid_y_addr = 0/*pcdev->vipmem_phybase + pcdev->vipmem_bsize*/;
+       invalid_uv_addr = 0/*invalid_y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height*/;
+#else
+       invalid_y_addr = pcdev->vipmem_phybase + pcdev->vbinfo_count *pcdev->vipmem_bsize;
+       invalid_uv_addr = invalid_y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
+#endif 
     tmp_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
     tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
        tmp_cif_frmst = read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS);
 
-    
+#if (CONFIG_CIF_STOP_SYNC == 0)
     if(pcdev->stop_cif == true) {
-        //RKCAMERA_TR("%s(%d): cif has stopped by app,needn't to deal this irq\n",__FUNCTION__,__LINE__);
-       write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);  /* clear vip interrupte single  */
-        return IRQ_HANDLED;
-    }
-    
+               //RK30_CAM_DEBUG_TRACE("%s(%d): cif has stopped by app,needn't to deal this irq\n",__FUNCTION__,__LINE__);
+               write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);  /* clear vip interrupte single  */
+               return IRQ_HANDLED;
+       }
+#endif
+
     if ((tmp_intstat & 0x0200) /*&& ((tmp_intstat & 0x1)==0)*/) {//bit9 =1 ,bit0 = 0
        write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200);  /* clear vip interrupte single  */
-        if(tmp_cifctrl & ENABLE_CAPTURE)
-            write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
//       if(tmp_cifctrl & ENABLE_CAPTURE)
//           write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
          return IRQ_HANDLED;
     }
     
     /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
     if (tmp_cif_frmst & (CIF_F0_READY | CIF_F1_READY)) {
        write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01);  /* clear vip interrupte single  */
+#if CONFIG_CIF_STOP_SYNC 
+                       if(pcdev->stop_cif == true) {
+                               //RK30_CAM_DEBUG_TRACE("%s(%d): cif has stopped by app,needn't to deal this irq\n",__FUNCTION__,__LINE__);
+                               write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);  /* clear vip interrupte single  */
+                               
+#if 1
+                               //              write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0);     //capture complete interrupt enable
+                                               {
+#if (defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928))
+                                       mdelay(100);
+                                       if(IS_CIF0()){
+                                               cru_set_soft_reset(SOFT_RST_CIF0, true);
+                                               udelay(5);
+                                               cru_set_soft_reset(SOFT_RST_CIF0, false);
+                       
+                                       }else{
+                                               cru_set_soft_reset(SOFT_RST_CIF1, true);
+                                               udelay(5);
+                                               cru_set_soft_reset(SOFT_RST_CIF1, false);
+                                       }
+#elif defined(CONFIG_ARCH_RK3188)
+                                       cru_set_soft_reset(SOFT_RST_CIF0, true);
+                                       udelay(5);
+                                       cru_set_soft_reset(SOFT_RST_CIF0, false);
+#endif
+                               }
+#endif
+                           spin_lock(&pcdev->lock);
+                               pcdev->cif_stopped = true;
+                               wake_up(&pcdev->cif_stop_done);
+                               spin_unlock(&pcdev->lock);
+                               return IRQ_HANDLED;
+                       }
+#endif
         if (!pcdev->fps) {
             do_gettimeofday(&pcdev->first_tv);            
         }
+process_another_frame: 
+        if((tmp_cif_frmst & CIF_F0_READY) && (tmp_cif_frmst & CIF_F1_READY)){
+                   printk(KERN_DEBUG"%s:f0 && f1 ready ,need to resart cif!!!!!\n",__func__);
+           spin_lock(&pcdev->lock);
+
+            rk_camera_store_resore_register(pcdev);
+                       rk_videobuf_capture(pcdev->active0,pcdev,0);
+                       rk_videobuf_capture(pcdev->active1,pcdev,1);
+                       tmp_cifctrl &=~ENABLE_CAPTURE;
+                   spin_unlock(&pcdev->lock);
+
+                       goto RK_CAMERA_IRQ_END;
+        }
                pcdev->fps++;
         
                if (tmp_cif_frmst & CIF_F0_READY){
@@ -1244,70 +1521,103 @@ static irqreturn_t rk_camera_irq(int irq, void *data)
                } else if (tmp_cif_frmst & CIF_F1_READY){
                        active = &pcdev->active1;
                        flag = 1;
+               } else {
+                       printk("irq frame status erro \n");
+                       goto RK_CAMERA_IRQ_END;
                }
-               
+#if 0  
                if (!(*active)){
                        goto RK_CAMERA_IRQ_END;
                }
+#endif
+               if (pcdev->frame_inval>0) {
+                       pcdev->frame_inval--;
+                       rk_videobuf_capture(*active,pcdev,flag);
+                       goto first_frame_done;
+               } else if (pcdev->frame_inval) {
+                       RK30_CAM_DEBUG_TRACE("frame_inval : %0x",pcdev->frame_inval);
+                       pcdev->frame_inval = 0;
+               }
         
-        if (pcdev->frame_inval>0) {
-            pcdev->frame_inval--;
-            rk_videobuf_capture(*active,pcdev,flag);
-            goto RK_CAMERA_IRQ_END;
-        } else if (pcdev->frame_inval) {
-               RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
-            pcdev->frame_inval = 0;
-        }
-        
-        if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
-            do_gettimeofday(&tv);            
-            pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
-                                    /(RK30_CAM_FRAME_MEASURE-1);
+               if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
+                       do_gettimeofday(&tv);            
+                       pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
+                                                                       /(RK30_CAM_FRAME_MEASURE-1);
         }
                
-        vb = *active;
-        if(!vb){
-            RKCAMERA_TR("no acticve buffer!!!\n");
-            goto RK_CAMERA_IRQ_END;
-        }
+               vb = *active;
+               
+#if 0
+               if(!vb){
+                       RK30_CAM_DEBUG_TRACE("no acticve buffer!!!\n");
+                       goto RK_CAMERA_IRQ_END;
+               }
 
                if (vb->stream.prev != &(pcdev->video_vq->stream)) {
-                       RKCAMERA_DG("vb(%d) isn't first node in stream list\n", vb->i);
+                       RK30_CAM_DEBUG_TRACE("vb(%d) isn't first node in stream list\n", vb->i);
                        goto RK_CAMERA_IRQ_END;
                }
-
+#endif
                *active = NULL;
-        if (!list_empty(&pcdev->capture)) {
-            *active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
+           spin_lock(&pcdev->lock);
+               if (!list_empty(&pcdev->capture)) {
+                       *active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
                        if (*active) {
-                WARN_ON((*active)->state != VIDEOBUF_QUEUED);                     
+                               WARN_ON((*active)->state != VIDEOBUF_QUEUED); 
+                               if (tmp_cif_frmst & CIF_F0_READY){
+                               pcdev->active0 = *active;
+                       } else if (tmp_cif_frmst & CIF_F1_READY){
+                               pcdev->active1 = *active;
+                       }else{
+                    printk("irq frame status erro !\n");
+                       }
                                rk_videobuf_capture((*active),pcdev,flag);
                                list_del_init(&((*active)->queue));
                        }
-        }
-        if ((*active) == NULL) {
-                       RKCAMERA_DG("%s video_buf queue is empty!\n",__FUNCTION__);
                }
-
-        do_gettimeofday(&vb->ts);
+           spin_unlock(&pcdev->lock);
+               if ((*active) == NULL) {
+               //      RK30_CAM_DEBUG_TRACE("%s video_buf queue is empty!\n",__FUNCTION__);
+                       if(flag == 0){                  
+                           pcdev->active0 = NULL;
+                               write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, invalid_y_addr);
+                               write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, invalid_uv_addr);
+                               }else{
+                           pcdev->active1 = NULL;
+                               write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, invalid_y_addr);
+                               write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, invalid_uv_addr);
+                               }
+               }
+               if(vb)
+                       do_gettimeofday(&vb->ts);
                if (CAM_WORKQUEUE_IS_EN()) {
-            if (!list_empty(&pcdev->camera_work_queue)) {
-                wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
-                list_del_init(&wk->queue);
-                INIT_WORK(&(wk->work), rk_camera_capture_process);
-                       wk->vb = vb;
-                       wk->pcdev = pcdev;
-                       queue_work(pcdev->camera_wq, &(wk->work));
-            }                                  
+                       if(vb){
+                                       if (!list_empty(&pcdev->camera_work_queue)) {
+                                               wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
+                                               list_del_init(&wk->queue);
+                                               INIT_WORK(&(wk->work), rk_camera_capture_process);
+                                               wk->vb = vb;
+                                               wk->pcdev = pcdev;
+                                       wk->ts = pcdev->fps;
+                                               queue_work(pcdev->camera_wq, &(wk->work));
+                                       }else{
+                                               printk("work queue is empty \n!!!!!!!!");
+                                       }
+                               }
                } else {
-                   if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
-               vb->state = VIDEOBUF_DONE;              
-               vb->field_count++;
-               }
+                       if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
+                               vb->state = VIDEOBUF_DONE;              
+                               vb->field_count++;
+                       }
                        wake_up(&vb->done);
                }
-               
     }
+first_frame_done:
+       if ((tmp_cif_frmst & CIF_F0_READY) && (tmp_cif_frmst & CIF_F1_READY)){
+                   printk(KERN_DEBUG"%s:f0 && f1 ready ,need to process f1 too!!!!!\n",__func__);
+            tmp_cif_frmst &=~CIF_F0_READY;
+            goto process_another_frame;
+       }
 
 RK_CAMERA_IRQ_END:
     if((tmp_cifctrl & ENABLE_CAPTURE) == 0)
@@ -1348,27 +1658,26 @@ static void rk_videobuf_release(struct videobuf_queue *vq,
     }
 #endif
 
-    #if 0   /* ddl@rock-chips.com: this wait operation is not nessary, invalidate in v0.x.1f */
+       #if 0   /* ddl@rock-chips.com: this wait operation is not nessary, invalidate in v0.x.1f */
        if (vb == pcdev->active0 || vb == pcdev->active1) {
-               RKCAMERA_DG("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb);
+               RK30_CAM_DEBUG_TRACE("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb);
                interruptible_sleep_on_timeout(&vb->done, msecs_to_jiffies(500));
-               RKCAMERA_DG("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb);
+               RK30_CAM_DEBUG_TRACE("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb);
        }
-    #endif
-    flush_workqueue(pcdev->camera_wq); 
+       #endif
+       flush_workqueue(pcdev->camera_wq); 
 #if CAMERA_VIDEOBUF_ARM_ACCESS
-    if (pcdev->vbinfo) {
-        vb_info = pcdev->vbinfo + vb->i;
+       if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
+               vb_info = pcdev->vbinfo + vb->i;
         
-        if (vb_info->vir_addr) {
-            iounmap(vb_info->vir_addr);
-            release_mem_region(vb_info->phy_addr, vb_info->size);
-            memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
-        }       
-               
+               if (vb_info->vir_addr) {
+                       iounmap(vb_info->vir_addr);
+                       release_mem_region(vb_info->phy_addr, vb_info->size);
+                       memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
+               }
        }
 #endif    
-    rk_videobuf_free(vq, buf);
+       rk_videobuf_free(vq, buf);
 }
 
 static struct videobuf_queue_ops rk_videobuf_ops =
@@ -1395,67 +1704,74 @@ static void rk_camera_init_videobuf(struct videobuf_queue *q,
                                    sizeof(struct rk_camera_buffer),
                                    icd,&icd->video_lock);
 }
-static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
-{
-    int err = 0;
-    
-    if(!pcdev->aclk_cif || !pcdev->hclk_cif || !pcdev->cif_clk_in || !pcdev->cif_clk_out){
-        RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
-        err = -ENOENT;
-        goto RK_CAMERA_ACTIVE_ERR;
-        }
 
-       clk_enable(pcdev->pd_cif);
-       clk_enable(pcdev->aclk_cif);
+static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate){
+    int err = 0,cif;
+    struct rk_cif_clk *clk;
+    struct clk *cif_clk_out_div;
 
-       clk_enable(pcdev->hclk_cif);
-       clk_enable(pcdev->cif_clk_in);
+    cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
+    if ((cif<0)||(cif>1)) {
+        RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
+        err = -1;
+        goto rk_camera_clk_ctrl_end;
+    }
 
-    //if (icd->ops->query_bus_param)                                                  /* ddl@rock-chips.com : Query Sensor's xclk */
-        //sensor_bus_flags = icd->ops->query_bus_param(icd);
-       clk_enable(pcdev->cif_clk_out);
-    clk_set_rate(pcdev->cif_clk_out,RK_SENSOR_24MHZ);
+    clk = &cif_clk[cif];
 
-       ndelay(10);
-    //soft reset  the registers
-    #if 0 //has somthing wrong when suspend and resume now
-    if(IS_CIF0()){
-        printk("before set cru register reset cif0 0x%x\n\n",read_cru_reg(CRU_CIF_RST_REG30));
-               //dump regs
-       {
-               printk("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
-               printk("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
-               printk("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
-               printk("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
-               printk("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
-               printk("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
-               printk("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
-               printk("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
-               printk("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
-               
-               printk("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
-               printk("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
-       printk("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
-       printk("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
-       printk("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
-       printk("CIF_CIF_FRAME_STATUS = 0X%x\n\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
-       }
+    if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
+        RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
+        err = -ENOENT;
+        goto rk_camera_clk_ctrl_end;
+    }
+    spin_lock(&clk->lock);
+    if (on && !clk->on) {
+        clk_enable(clk->pd_cif);
+        clk_enable(clk->aclk_cif);
+        clk_enable(clk->hclk_cif);
+        clk_enable(clk->cif_clk_in);
+        clk_enable(clk->cif_clk_out);
+        clk_set_rate(clk->cif_clk_out,clk_rate);
+        mdelay(10);
+        clk->on = true;
+        
+    } else if (!on && clk->on) {
+        clk_disable(clk->aclk_cif);
+        clk_disable(clk->hclk_cif);
+        clk_disable(clk->cif_clk_in);
+
+        clk_disable(clk->cif_clk_out);
+        clk_disable(clk->pd_cif);
+        clk->on = false;
+        if(cif){
+            cif_clk_out_div =  clk_get(NULL, "cif1_out_div");
+        }else{
+            cif_clk_out_div =  clk_get(NULL, "cif0_out_div");
+            if(IS_ERR_OR_NULL(cif_clk_out_div)) {
+                cif_clk_out_div =  clk_get(NULL, "cif_out_div");
+            }
+        }
 
-       mdelay(100);
-        write_cru_reg(CRU_CIF_RST_REG30,(/*read_cru_reg(CRU_CIF_RST_REG30)|*/MASK_RST_CIF0|RQUEST_RST_CIF0 ));
-        printk("set cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
-        write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
-       mdelay(1000);
-        printk("clean cru register reset cif0 0x%x\n",read_cru_reg(CRU_CIF_RST_REG30));
-    }else{
-        write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
-        write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
+        if(IS_ERR_OR_NULL(cif_clk_out_div)) {
+            err = clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
+            clk_put(cif_clk_out_div);
+        } else {
+            err = -1;
+        }
+
+        if(err)
+           RKCAMERA_TR("WARNING %s_%s_%d: camera sensor mclk maybe not close, please check!!!\n", __FILE__, __FUNCTION__, __LINE__);
     }
-    #endif
+    spin_unlock(&clk->lock);
+rk_camera_clk_ctrl_end:
+    return err;
+}
+static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
+{
     write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_PINGPONG|DISABLE_CAPTURE);   /* ddl@rock-chips.com : vip ahb burst 16 */
 
     write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01);    //capture complete interrupt enable
-    RKCAMERA_DG("%s..%d.. CIF_CIF_CTRL = 0x%x\n",__FUNCTION__,__LINE__,read_cif_reg(pcdev->base, CIF_CIF_CTRL));
+    RK30_CAM_DEBUG_TRACE("%s..%d.. CIF_CIF_CTRL = 0x%x\n",__FUNCTION__,__LINE__,read_cif_reg(pcdev->base, CIF_CIF_CTRL));
     return 0;
 RK_CAMERA_ACTIVE_ERR:
     return -ENODEV;
@@ -1463,18 +1779,6 @@ RK_CAMERA_ACTIVE_ERR:
 
 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
 {
-       clk_disable(pcdev->aclk_cif);
-
-       clk_disable(pcdev->hclk_cif);
-       clk_disable(pcdev->cif_clk_in);
-       
-       clk_disable(pcdev->cif_clk_out);
-       clk_enable(pcdev->cif_clk_out);
-    clk_set_rate(pcdev->cif_clk_out,48*1000*1000);
-       clk_disable(pcdev->cif_clk_out);
-    
-       clk_disable(pcdev->pd_cif);
     return;
 }
 
@@ -1496,7 +1800,7 @@ static int rk_camera_add_device(struct soc_camera_device *icd)
         goto ebusy;
     }
 
-    RKCAMERA_DG("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
+    RK30_CAM_DEBUG_TRACE("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
 
        pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
     pcdev->active0 = NULL;
@@ -1566,7 +1870,7 @@ static void rk_camera_remove_device(struct soc_camera_device *icd)
        mutex_lock(&camera_lock);
     BUG_ON(icd != pcdev->icd);
 
-    RKCAMERA_DG("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
+    RK30_CAM_DEBUG_TRACE("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
 
        /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
           stream may be turn on again before close device, if suspend and resume happened. */
@@ -1627,7 +1931,7 @@ static void rk_camera_remove_device(struct soc_camera_device *icd)
     INIT_LIST_HEAD(&pcdev->capture);
 
        mutex_unlock(&camera_lock);
-       RKCAMERA_DG("%s exit\n",__FUNCTION__);
+       RK30_CAM_DEBUG_TRACE("%s exit\n",__FUNCTION__);
 
        return;
 }
@@ -1639,7 +1943,7 @@ static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
        int ret = 0;
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
        struct rk_camera_dev *pcdev = ici->priv;
-    RKCAMERA_DG("%s..%d..\n",__FUNCTION__,__LINE__);
+    RK30_CAM_DEBUG_TRACE("%s..%d..\n",__FUNCTION__,__LINE__);
 
        fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
        if (!fmt)
@@ -1680,22 +1984,22 @@ static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
         goto RK_CAMERA_SET_BUS_PARAM_END;
 
     cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_FOR);
-       RKCAMERA_DG("%s..%d..cif_ctrl_val = 0x%x\n",__FUNCTION__,__LINE__,cif_ctrl_val);
+       RK30_CAM_DEBUG_TRACE("%s..%d..cif_ctrl_val = 0x%x\n",__FUNCTION__,__LINE__,cif_ctrl_val);
     if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
                if(IS_CIF0()) {
                write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
-            RKCAMERA_DG("enable cif0 pclk invert\n");
+            RK30_CAM_DEBUG_TRACE("enable cif0 pclk invert\n");
         } else {
                write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
-            RKCAMERA_DG("enable cif1 pclk invert\n");
+            RK30_CAM_DEBUG_TRACE("enable cif1 pclk invert\n");
         }
     } else {
                if(IS_CIF0()){
                        write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
-            RKCAMERA_DG("diable cif0 pclk invert\n");
+            RK30_CAM_DEBUG_TRACE("diable cif0 pclk invert\n");
         } else {
                        write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
-            RKCAMERA_DG("diable cif1 pclk invert\n");
+            RK30_CAM_DEBUG_TRACE("diable cif1 pclk invert\n");
         }
     }
     if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) {
@@ -1712,11 +2016,11 @@ static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
     /* ddl@rock-chips.com : Don't enable capture here, enable in stream_on */
     //vip_ctrl_val |= ENABLE_CAPTURE;
     write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_ctrl_val);
-    RKCAMERA_DG("%s..ctrl:0x%x CIF_CIF_FOR=%x  \n",__FUNCTION__,cif_ctrl_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
+    RK30_CAM_DEBUG_TRACE("%s..ctrl:0x%x CIF_CIF_FOR=%x  \n",__FUNCTION__,cif_ctrl_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
 
 RK_CAMERA_SET_BUS_PARAM_END:
        if (ret)
-       RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
+       RK30_CAM_DEBUG_TRACE("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
     return ret;
 }
 
@@ -1733,10 +2037,21 @@ static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
        }
     ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
 
-    if (ret < 0)
-        dev_warn(icd->dev.parent,
-                        "Flags incompatible: camera %lx, host %lx\n",
-                        camera_flags, bus_flags);
+       /*nelson_yang@asus.com fix: rock-chip coding bug*/
+       /* rockchip BUGBUG
+               if (ret < 0)
+                       dev_warn(icd->dev.parent,
+                                "Flags incompatible: camera %lx, host %lx\n",
+                                camera_flags, bus_flags);
+       */
+       if(!ret){
+               dev_warn(icd->dev.parent, "Flags incompatible: camera %lx, host %lx\n", camera_flags, bus_flags);
+               ret = -EINVAL;
+       }
+       else{
+               ret = 0;
+       }
+       /*nelson_yang@asus.com fix: rock-chip coding bug end*/
     return ret;
 }
 
@@ -1864,7 +2179,7 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix
                        cru_set_soft_reset(SOFT_RST_CIF1, false);
         //             pmu_set_idle_request(IDLE_REQ_VIO, false);  
             }
-#else defined(CONFIG_ARCH_RK3188)
+#elif defined(CONFIG_ARCH_RK3188)
 //             pmu_set_idle_request(IDLE_REQ_VIO, true);
                cru_set_soft_reset(SOFT_RST_CIF0, true);
                udelay(5);
@@ -1879,11 +2194,15 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix
     write_cif_reg(pcdev->base,CIF_CIF_FOR,cif_fmt_val);         /* ddl@rock-chips.com: VIP capture mode and capture format must be set before FS register set */
 
    // read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);                /* clear vip interrupte single  */
-    write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); 
-    
-       cif_crop = (rect->left+ (rect->top<<16));
-       cif_fs  = ((rect->width ) + (rect->height<<16));
-    
+    write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
+       /* 
+    if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
+               ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
+           BUG();      
+    } else*/{ // this is one frame mode
+           cif_crop = (rect->left+ (rect->top<<16));
+           cif_fs      = ((rect->width ) + (rect->height<<16));
+       }
 
        write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
        write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs);
@@ -1892,7 +2211,7 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix
 
     //MUST bypass scale 
        write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
-    RKCAMERA_DG("%s.. crop:0x%x fs:0x%x cif_fmt_val:0x%x CIF_CIF_FOR:0x%x\n",__FUNCTION__,cif_crop,cif_fs,cif_fmt_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
+    RK30_CAM_DEBUG_TRACE("%s.. crop:0x%x fs:0x%x cif_fmt_val:0x%x CIF_CIF_FOR:0x%x\n",__FUNCTION__,cif_crop,cif_fs,cif_fmt_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
        return;
 }
 
@@ -2043,7 +2362,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
 
        usr_w = pix->width;
        usr_h = pix->height;
-    RKCAMERA_DG("%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
+    RK30_CAM_DEBUG_TRACE("%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
     xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
     if (!xlate) {
         dev_err(dev, "Format %x not found\n", pix->pixelformat);
@@ -2073,43 +2392,43 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
        if ((mf.width != usr_w) || (mf.height != usr_h)) {
          int ratio;
         if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
-               RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
+               RK30_CAM_DEBUG_TRACE("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height);
                ret = -EINVAL;
                goto RK_CAMERA_SET_FMT_END;
        }       
        if (unlikely((usr_w <16)||(usr_h < 16))) {
-               RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
+               RK30_CAM_DEBUG_TRACE("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h);
                ret = -EINVAL;
             goto RK_CAMERA_SET_FMT_END;
        }
                //need crop ?
-               if((mf.width*10/mf.height) != (usr_w*10/usr_h)){
+               if((mf.width*10/mf.height) != (usr_w*10/usr_h)) {
                        ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
                        pcdev->host_width = ratio*usr_w/10;
                        pcdev->host_height = ratio*usr_h/10;
             //for ipp ,need 4 bit alligned.
                pcdev->host_width &= ~CROP_ALIGN_BYTES;
                pcdev->host_height &= ~CROP_ALIGN_BYTES;
-                       RKCAMERA_DG("ratio = %d ,host:%d*%d\n",ratio,pcdev->host_width,pcdev->host_height);
-                       }
-               else{ // needn't crop ,just scaled by ipp
+                       RK30_CAM_DEBUG_TRACE("ratio = %d ,host:%d*%d\n",ratio,pcdev->host_width,pcdev->host_height);
+               }
+               else { // needn't crop ,just scaled by ipp
                        pcdev->host_width = mf.width;
                        pcdev->host_height = mf.height;
-                       }
+               }
        }
-       else{
+       else {
                pcdev->host_width = usr_w;
                pcdev->host_height = usr_h;
-               }
+       }
        #else
        //according to crop and scale capability to change , here just cropt to user needed
         if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) {
-               RKCAMERA_TR("Senor invalid source resolution(%dx%d)\n",mf.width,mf.height);
+               RK30_CAM_DEBUG_TRACE("Senor invalid source resolution(%dx%d)\n",mf.width,mf.height);
                ret = -EINVAL;
                goto RK_CAMERA_SET_FMT_END;
        }       
        if (unlikely((usr_w <16)||(usr_h < 16))) {
-               RKCAMERA_TR("Senor  invalid destination resolution(%dx%d)\n",usr_w,usr_h);
+               RK30_CAM_DEBUG_TRACE("Senor  invalid destination resolution(%dx%d)\n",usr_w,usr_h);
                ret = -EINVAL;
             goto RK_CAMERA_SET_FMT_END;
        }
@@ -2118,7 +2437,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
        #endif
     icd->sense = NULL;
     if (!ret) {
-        RKCAMERA_DG("%s..%d.. host:%d*%d , sensor output:%d*%d,user demand:%d*%d\n",__FUNCTION__,__LINE__,
+        RK30_CAM_DEBUG_TRACE("%s..%d.. host:%d*%d , sensor output:%d*%d,user demand:%d*%d\n",__FUNCTION__,__LINE__,
                pcdev->host_width,pcdev->host_height,mf.width,mf.height,usr_w,usr_h);
         rect.width = pcdev->host_width;
         rect.height = pcdev->host_height;
@@ -2148,14 +2467,14 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
        pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
        pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
        //now digital zoom use ipp to do crop and scale
-       if(pcdev->zoominfo.zoom_rate != 100){
+       if(pcdev->zoominfo.zoom_rate != 100) {
                pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
                pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
-               }
-       else{
+       }
+       else {
                pcdev->zoominfo.a.c.left = 0;
                pcdev->zoominfo.a.c.top = 0;
-               }
+       }
        pcdev->zoominfo.vir_width = pcdev->host_width;
        pcdev->zoominfo.vir_height = pcdev->host_height;
        #endif
@@ -2165,19 +2484,19 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
         if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) {
             if (usr_w > 0x7f0) {
                 if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) {
-                    RKCAMERA_TR("IPP Destination resolution(%dx%d, ((%d div 1) mod 64)=%d is <= 8)",usr_w,usr_h, usr_w, (int)((usr_w>>1)&0x3f));
+                    RK30_CAM_DEBUG_TRACE("IPP Destination resolution(%dx%d, ((%d div 1) mod 64)=%d is <= 8)",usr_w,usr_h, usr_w, (int)((usr_w>>1)&0x3f));
                     ret = -EINVAL;
                     goto RK_CAMERA_SET_FMT_END;
                 }
             } else {
                 if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) {
-                    RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
+                    RK30_CAM_DEBUG_TRACE("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f));
                     ret = -EINVAL;
                     goto RK_CAMERA_SET_FMT_END;
                 }
             }
         }
-        RKCAMERA_DG("%s..%s icd width:%d  user width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",__FUNCTION__,xlate->host_fmt->name,
+        RK30_CAM_DEBUG_TRACE("%s..%s icd width:%d  user width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",__FUNCTION__,xlate->host_fmt->name,
                                   rect.width, pix->width, pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
                                   pix->width, pix->height);
         rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect); 
@@ -2198,7 +2517,7 @@ RK_CAMERA_SET_FMT_END:
     if (stream_on & ENABLE_CAPTURE)
         write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
        if (ret)
-       RKCAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
+       RK30_CAM_DEBUG_TRACE("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
     return ret;
 }
 static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
@@ -2220,7 +2539,7 @@ static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
        }
 
        if (ret == true)
-               RKCAMERA_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
+               RK30_CAM_DEBUG_TRACE("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
        return ret;
 }
 static int rk_camera_try_fmt(struct soc_camera_device *icd,
@@ -2246,10 +2565,10 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
         dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
                        (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
         ret = -EINVAL;
-        RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
+        RK30_CAM_DEBUG_TRACE("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
             (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
         for (i = 0; i < icd->num_user_formats; i++)
-                   RKCAMERA_TR("(%c%c%c%c)-%s\n",
+                   RK30_CAM_DEBUG_TRACE("(%c%c%c%c)-%s\n",
                    icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
                        (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
                        icd->user_formats[i].host_fmt->name);
@@ -2285,26 +2604,30 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
        if((usr_w == 10000) && (usr_h == 10000)) {
                pix->width = mf.width;
         pix->height = mf.height;
-        RKCAMERA_DG("%s: Sensor resolution : %dx%d\n",__FUNCTION__,mf.width,mf.height);
+        RK30_CAM_DEBUG_TRACE("%s: Sensor resolution : %dx%d\n",__FUNCTION__,mf.width,mf.height);
                goto RK_CAMERA_TRY_FMT_END;
        } else {
-        RKCAMERA_DG("%s: user demand: %dx%d  sensor output: %dx%d \n",__FUNCTION__,usr_w,usr_h,mf.width,mf.height);
+        RK30_CAM_DEBUG_TRACE("%s: user demand: %dx%d  sensor output: %dx%d \n",__FUNCTION__,usr_w,usr_h,mf.width,mf.height);
        }
     
        #ifdef CONFIG_VIDEO_RK29_WORK_IPP       
        if ((mf.width != usr_w) || (mf.height != usr_h)) {
         bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt); 
+        #ifndef OPTIMIZE_MEMORY_USE
                if (is_capture) {
                        vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
                } else {
                        /* Assume preview buffer minimum is 4 */
                        vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
-               }        
+               }
+               #else
+                   vipmem_is_overflow =false;
+               #endif
                if (vipmem_is_overflow == false) {
                        pix->width = usr_w;
                        pix->height = usr_h;
                } else {
-                       RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
+                       RK30_CAM_DEBUG_TRACE("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
             pix->width = mf.width;
             pix->height = mf.height;            
                }
@@ -2312,7 +2635,7 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
         #if 0     
         if ((mf.width < usr_w) || (mf.height < usr_h)) {
             if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
-                RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
+                RK30_CAM_DEBUG_TRACE("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
                 pix->width = mf.width;
                 pix->height = mf.height;
             }
@@ -2325,7 +2648,7 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
                        pix->width = usr_w;
                        pix->height = usr_h;
            } else if ((mf.width < usr_w) && (mf.height < usr_h)) {
-                       RKCAMERA_TR("%dx%d can't scale up to %dx%d!\n",mf.width,mf.height,usr_w,usr_h);
+                       RK30_CAM_DEBUG_TRACE("%dx%d can't scale up to %dx%d!\n",mf.width,mf.height,usr_w,usr_h);
             pix->width = mf.width;
                pix->height     = mf.height;    
         }
@@ -2346,7 +2669,7 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
 
 RK_CAMERA_TRY_FMT_END:
        if (ret)
-       RKCAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
+       RK30_CAM_DEBUG_TRACE("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
     return ret;
 }
 
@@ -2390,51 +2713,46 @@ static int rk_camera_querycap(struct soc_camera_host *ici,
                                 struct v4l2_capability *cap)
 {
     struct rk_camera_dev *pcdev = ici->priv;
+    struct rkcamera_platform_data *new_camera;
     char orientation[5];
+    char fov[9];
     int i;
 
-    strlcpy(cap->card, dev_name(pcdev->icd->pdev), sizeof(cap->card));    
+    strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18);
     memset(orientation,0x00,sizeof(orientation));
     for (i=0; i<RK_CAM_NUM;i++) {
         if ((pcdev->pdata->info[i].dev_name!=NULL) && (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->info[i].dev_name) == 0)) {
             sprintf(orientation,"-%d",pcdev->pdata->info[i].orientation);
+            sprintf(fov,"_50_50");
         }
     }
-    
+
+    i=0;
+    new_camera = pcdev->pdata->register_dev_new;
+    while (strstr(new_camera->dev_name,"end")==NULL) {
+        if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
+            sprintf(orientation,"-%d",new_camera->orientation);
+            sprintf(fov,"_%d_%d",new_camera->fov_h,new_camera->fov_v);
+        }
+        new_camera++;
+    }
+
     if (orientation[0] != '-') {
         RKCAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
-        if (strstr(dev_name(pcdev->icd->pdev),"front")) 
+        if (strstr(dev_name(pcdev->icd->pdev),"front"))
             strcat(cap->card,"-270");
-        else 
+        else
             strcat(cap->card,"-90");
     } else {
-        strcat(cap->card,orientation); 
+        strcat(cap->card,orientation);
     }
+
+    strcat(cap->card,fov);                          /* ddl@rock-chips.com: v0.3.f */
     cap->version = RK_CAM_VERSION_CODE;
     cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 
     return 0;
 }
-static void rk_camera_store_register(struct rk_camera_dev *pcdev)
-{
-       pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
-       pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
-       pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
-       pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
-       pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
-       pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
-       pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
-}
-static void rk_camera_restore_register(struct rk_camera_dev *pcdev)
-{
-       write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
-       write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
-       write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
-       write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
-       write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
-       write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
-       write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
-}
 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
 {
     struct soc_camera_host *ici =
@@ -2461,9 +2779,9 @@ static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
                pcdev->reginfo_suspend.Inval = Reg_Validate;
                rk_camera_deactivate(pcdev);
 
-               RKCAMERA_DG("%s Enter Success...\n", __FUNCTION__);
+               RK30_CAM_DEBUG_TRACE("%s Enter Success...\n", __FUNCTION__);
        } else {
-               RKCAMERA_DG("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
+               RK30_CAM_DEBUG_TRACE("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
        }
        mutex_unlock(&camera_lock);
     return ret;
@@ -2493,7 +2811,7 @@ static int rk_camera_resume(struct soc_camera_device *icd)
                        rk_camera_s_stream(icd, 1);
                        pcdev->reginfo_suspend.Inval = Reg_Invalidate;
                } else {
-                       RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
+                       RK30_CAM_DEBUG_TRACE("Resume fail, vip register recored is invalidate!!\n");
                        goto rk_camera_resume_end;
                }
 
@@ -2501,9 +2819,9 @@ static int rk_camera_resume(struct soc_camera_device *icd)
                sd = soc_camera_to_subdev(icd);
                v4l2_subdev_call(sd, video, s_stream, 1);
 
-               RKCAMERA_DG("%s Enter success\n",__FUNCTION__);
+               RK30_CAM_DEBUG_TRACE("%s Enter success\n",__FUNCTION__);
        } else {
-               RKCAMERA_DG("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
+               RK30_CAM_DEBUG_TRACE("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
        }
 
 rk_camera_resume_end:
@@ -2525,27 +2843,27 @@ static void rk_camera_reinit_work(struct work_struct *work)
     tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
        //dump regs
        {
-               RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
-               RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
-               RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
-               RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
-               RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
-               RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
-               RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
-               RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
-               RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
+               RK30_CAM_DEBUG_TRACE("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
+               RK30_CAM_DEBUG_TRACE("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
+               RK30_CAM_DEBUG_TRACE("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
+               RK30_CAM_DEBUG_TRACE("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
+               RK30_CAM_DEBUG_TRACE("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
+               RK30_CAM_DEBUG_TRACE("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
+               RK30_CAM_DEBUG_TRACE("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
+               RK30_CAM_DEBUG_TRACE("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
+               RK30_CAM_DEBUG_TRACE("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
                
-               RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
-               RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
-       RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
-       RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
-       RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
-       RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
+               RK30_CAM_DEBUG_TRACE("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
+               RK30_CAM_DEBUG_TRACE("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
+       RK30_CAM_DEBUG_TRACE("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
+       RK30_CAM_DEBUG_TRACE("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
+       RK30_CAM_DEBUG_TRACE("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
+       RK30_CAM_DEBUG_TRACE("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
        }
-    
+    return;
     pcdev->stop_cif = true;
        write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
-       RKCAMERA_DG("the reinit times = %d\n",pcdev->reinit_times);
+       RK30_CAM_DEBUG_TRACE("the reinit times = %d\n",pcdev->reinit_times);
    if(pcdev->video_vq && pcdev->video_vq->irqlock){
        spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
        for (index = 0; index < VIDEO_MAX_FRAME; index++) {
@@ -2562,10 +2880,10 @@ static void rk_camera_reinit_work(struct work_struct *work)
        }
        spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags); 
     }else{
-    RKCAMERA_TR("video queue has somthing wrong !!\n");
+    RK30_CAM_DEBUG_TRACE("video queue has somthing wrong !!\n");
     }
 
-       RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
+       RK30_CAM_DEBUG_TRACE("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
 }
 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
 {
@@ -2577,9 +2895,9 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
     struct soc_camera_link *tmp_soc_cam_link;
     tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
 
-       RKCAMERA_DG("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
+       RK30_CAM_DEBUG_TRACE("rk_camera_fps_func fps:%d\n",(pcdev->fps - pcdev->last_fps)/3);
        if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
-               RKCAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor delay,last fps = %d,pcdev->fps = %d!\n",pcdev->last_fps,pcdev->fps);
+               RK30_CAM_DEBUG_TRACE("Camera host haven't recevie data from sensor,Reinit sensor delay,last fps = %d,pcdev->fps = %d!\n",pcdev->last_fps,pcdev->fps);
                pcdev->camera_reinit_work.pcdev = pcdev;
                //INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
         pcdev->reinit_times++;
@@ -2596,7 +2914,7 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
         fival_pre = fival_nxt;
         while (fival_nxt != NULL) {
 
-            RKCAMERA_DG("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(&pcdev->icd->dev), 
+            RK30_CAM_DEBUG_TRACE("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(&pcdev->icd->dev),
                 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
                            (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
                            fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
@@ -2655,8 +2973,8 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
 {
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-    struct rk_camera_dev *pcdev = ici->priv;
-    int cif_ctrl_val;
+       struct rk_camera_dev *pcdev = ici->priv;
+       int cif_ctrl_val;
        int ret;
        unsigned long flags;
 
@@ -2665,39 +2983,45 @@ static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
        cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
        if (enable) {
                pcdev->fps = 0;
-        pcdev->last_fps = 0;
-        pcdev->frame_interval = 0;
+               pcdev->last_fps = 0;
+               pcdev->frame_interval = 0;
                hrtimer_cancel(&(pcdev->fps_timer.timer));
                pcdev->fps_timer.pcdev = pcdev;
-        pcdev->timer_get_fps = false;
-        pcdev->reinit_times  = 0;
-        pcdev->stop_cif = false;
-//             hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
+               pcdev->timer_get_fps = false;
+               pcdev->reinit_times  = 0;
+               pcdev->stop_cif = false;
+               pcdev->cif_stopped = false;
+               //      hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
                cif_ctrl_val |= ENABLE_CAPTURE;
-               write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
+               write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
                hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
-        pcdev->fps_timer.istarted = true;
+               pcdev->fps_timer.istarted = true;
        } else {
            //cancel timer before stop cif
                ret = hrtimer_cancel(&pcdev->fps_timer.timer);
         pcdev->fps_timer.istarted = false;
         flush_work(&(pcdev->camera_reinit_work.work));
-        
         cif_ctrl_val &= ~ENABLE_CAPTURE;
                spin_lock_irqsave(&pcdev->lock, flags);
-       write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
+               //      write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
         pcdev->stop_cif = true;
        spin_unlock_irqrestore(&pcdev->lock, flags);
+#if CONFIG_CIF_STOP_SYNC
+                               init_waitqueue_head(&pcdev->cif_stop_done);
+                               if (wait_event_timeout(pcdev->cif_stop_done, pcdev->cif_stopped, msecs_to_jiffies(1000)) == 0) {
+                                       RKCAMERA_DG("%s:%d, wait cif stop timeout!",__func__,__LINE__);
+                               }
+#endif
+               //mdelay(35);
                flush_workqueue((pcdev->camera_wq));
-               RKCAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
+               RK30_CAM_DEBUG_TRACE("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
        }
     //must be reinit,or will be somthing wrong in irq process.
-    if(enable == false){
+    if(enable == false) {
         pcdev->active0 = NULL;
                pcdev->active1 = NULL;
         INIT_LIST_HEAD(&pcdev->capture);
-        }
-       RKCAMERA_DG("%s.. enable : 0x%x , CIF_CIF_CTRL = 0x%x\n", __FUNCTION__, enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
+       }
        return 0;
 }
 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
@@ -2735,7 +3059,7 @@ int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frm
                 ret = -EINVAL;
             }
         } else {
-            RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
+            RK30_CAM_DEBUG_TRACE("%s: fival_list is NULL\n",__FUNCTION__);
             ret = -EINVAL;
         }
     }  else {  
@@ -2747,7 +3071,7 @@ int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frm
         }
         
         if (fival_head == NULL) {
-            RKCAMERA_TR("%s: %s is not registered in rk_camera_platform_data!!",__FUNCTION__,dev_name(pcdev->icd->pdev));
+            RK30_CAM_DEBUG_TRACE("%s: %s is not registered in rk_camera_platform_data!!",__FUNCTION__,dev_name(pcdev->icd->pdev));
             ret = -EINVAL;
             goto rk_camera_enum_frameintervals_end;
         }
@@ -2767,20 +3091,20 @@ int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frm
 
         if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
             memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
-            RKCAMERA_DG("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
+            RK30_CAM_DEBUG_TRACE("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->icd->pdev),
                 fival->width, fival->height,
                 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
                            (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
                             fival->discrete.denominator,fival->discrete.numerator);                        
         } else {
             if (index == 0)
-                RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
+                RK30_CAM_DEBUG_TRACE("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
                     fival->width,fival->height, 
                     fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
                            (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
                            index);
             else
-                RKCAMERA_DG("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
+                RK30_CAM_DEBUG_TRACE("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
                     fival->width,fival->height, 
                     fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
                            (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
@@ -2840,7 +3164,7 @@ static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
        up(&pcdev->zoominfo.sem);
        pcdev->stop_cif = false;
        hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
-       RKCAMERA_DG("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
+       RK30_CAM_DEBUG_TRACE("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
 #else
        a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        a.c.width = pcdev->host_width*100/zoom_rate;
@@ -2857,7 +3181,7 @@ static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
        pcdev->zoominfo.vir_width = pcdev->host_width;
        pcdev->zoominfo.vir_height= pcdev->host_height;
        up(&pcdev->zoominfo.sem);
-       RKCAMERA_DG("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
+       RK30_CAM_DEBUG_TRACE("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
 #endif 
 
        return 0;
@@ -2892,16 +3216,18 @@ static int rk_camera_set_ctrl(struct soc_camera_device *icd,
                ret = -ENOIOCTLCMD;
         goto rk_camera_set_ctrl_end;
        }
-
+       
+    if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
+               ret = -EINVAL;
+        goto rk_camera_set_ctrl_end;
+       }
+       
        switch (sctrl->id)
        {
        #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
                case V4L2_CID_ZOOM_ABSOLUTE:
                {
-                       if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
-                       ret = -EINVAL;
-                goto rk_camera_set_ctrl_end;
-               }
+                       
             ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
                        if (ret == 0) {
                                pcdev->zoominfo.zoom_rate = sctrl->value;
@@ -2911,6 +3237,31 @@ static int rk_camera_set_ctrl(struct soc_camera_device *icd,
                        break;
                }
     #endif
+
+        case V4L2_CID_HDR:
+        {            
+            if (pcdev->hdr_info.en != sctrl->value) {
+                pcdev->hdr_info.en = sctrl->value;
+                if (sctrl->value) {
+                                       struct device *control = to_soc_camera_control(pcdev->icd);
+                                       struct v4l2_subdev *sd=dev_get_drvdata(control);
+
+                    printk("hdr on\n");
+                    pcdev->hdr_info.frame[0].code = RK_VIDEOBUF_HDR_EXPOSURE_MINUS_1;
+                    pcdev->hdr_info.frame[0].set_ts = 0;
+                    pcdev->hdr_info.frame[0].get_ts = 0;
+                    pcdev->hdr_info.frame[1].code = RK_VIDEOBUF_HDR_EXPOSURE_NORMAL;
+                    pcdev->hdr_info.frame[1].set_ts = 0;
+                    pcdev->hdr_info.frame[1].get_ts = 0;
+                    pcdev->hdr_info.frame[2].code = RK_VIDEOBUF_HDR_EXPOSURE_PLUS_1;
+                    pcdev->hdr_info.frame[2].set_ts = 0;
+                    pcdev->hdr_info.frame[2].get_ts = 0;
+                    v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_HDR_EXPOSURE,RK_VIDEOBUF_HDR_EXPOSURE_NORMAL);
+                }
+            }
+            break;
+        }
+    
                default:
                        ret = -ENOIOCTLCMD;
                        break;
@@ -2919,6 +3270,16 @@ rk_camera_set_ctrl_end:
        return ret;
 }
 
+int rk_camera_enum_fsizes(struct soc_camera_device *icd, struct v4l2_frmsizeenum *fsize)
+{
+    struct device *control = to_soc_camera_control(icd);
+    struct v4l2_subdev *sd;
+
+    sd = dev_get_drvdata(control);
+    return v4l2_subdev_call(sd, video, enum_framesizes, fsize);
+
+}
+
 static struct soc_camera_host_ops rk_soc_camera_host_ops =
 {
     .owner             = THIS_MODULE,
@@ -2927,6 +3288,7 @@ static struct soc_camera_host_ops rk_soc_camera_host_ops =
     .suspend   = rk_camera_suspend,
     .resume            = rk_camera_resume,
     .enum_frameinervals = rk_camera_enum_frameintervals,
+    .enum_fsizes = rk_camera_enum_fsizes,
     .set_crop  = rk_camera_set_crop,
     .get_formats       = rk_camera_get_formats, 
     .put_formats       = rk_camera_put_formats,
@@ -2941,15 +3303,15 @@ static struct soc_camera_host_ops rk_soc_camera_host_ops =
     .set_ctrl = rk_camera_set_ctrl,
     .controls = rk_camera_controls,
     .num_controls = ARRAY_SIZE(rk_camera_controls)
-    
 };
+
 static void rk_camera_cif_iomux(int cif_index)
 {
 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
     switch(cif_index){
         case 0:
-               iomux_set(CIF0_CLKOUT);
-            write_grf_reg(GRF_IO_CON3, (CIF_DRIVER_STRENGTH_MASK|CIF_DRIVER_STRENGTH_8MA));
+                       iomux_set(CIF0_CLKOUT);
+            write_grf_reg(GRF_IO_CON3, (CIF_DRIVER_STRENGTH_MASK|CIF_DRIVER_STRENGTH_4MA));
             write_grf_reg(GRF_IO_CON4, (CIF_CLKOUT_AMP_MASK|CIF_CLKOUT_AMP_1V8));
             #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & (RK_CAM_INPUT_FMT_RAW10|RK_CAM_INPUT_FMT_RAW12))
                iomux_set(CIF0_D0);
@@ -2958,12 +3320,12 @@ static void rk_camera_cif_iomux(int cif_index)
             #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & RK_CAM_INPUT_FMT_RAW12)
                iomux_set(CIF0_D10);
                iomux_set(CIF0_D11);
-            RKCAMERA_TR("%s(%d): WARNING: Cif 0 is configurated that support RAW 12bit, so I2C3 is invalidate!!\n",__FUNCTION__,__LINE__);
+            RK30_CAM_DEBUG_TRACE("%s(%d): WARNING: Cif 0 is configurated that support RAW 12bit, so I2C3 is invalidate!!\n",__FUNCTION__,__LINE__);
             #endif
             
             break;
         default:
-            RKCAMERA_TR("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
+            RK30_CAM_DEBUG_TRACE("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
             break;
     }
 #elif defined(CONFIG_ARCH_RK30)
@@ -2999,7 +3361,7 @@ static void rk_camera_cif_iomux(int cif_index)
             rk30_mux_api_set(GPIO1D7_CIF1CLKOUT_NAME,GPIO1D_CIF1_CLKOUT);
             break;
         default:
-            RKCAMERA_TR("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
+            RK30_CAM_DEBUG_TRACE("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
             break;
         }
 #endif
@@ -3014,17 +3376,18 @@ static int rk_camera_probe(struct platform_device *pdev)
     struct rk29camera_mem_res *meminfo_ptr,*meminfo_ptrr;
     int irq,i;
     int err = 0;
+    struct rk_cif_clk *clk=NULL;
 
     printk("%s version: v%d.%d.%d  Zoom by %s\n",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
         (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);    
 
     if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
-        RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
+        RK30_CAM_DEBUG_TRACE("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
         BUG();
     }
 
     if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
-        RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
+        RK30_CAM_DEBUG_TRACE("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
         BUG();
     }
     
@@ -3045,32 +3408,33 @@ static int rk_camera_probe(struct platform_device *pdev)
        pcdev->hostid = pdev->id;
     /*config output clk*/ // must modify start
     if(IS_CIF0()){
-        pcdev->pd_cif = clk_get(NULL, "pd_cif0");
-        pcdev->aclk_cif = clk_get(NULL, "aclk_cif0");
-        pcdev->hclk_cif = clk_get(NULL, "hclk_cif0");
-        pcdev->cif_clk_in = clk_get(NULL, "cif0_in");
-        pcdev->cif_clk_out = clk_get(NULL, "cif0_out");
+        clk = &cif_clk[0];
+        cif_clk[0].pd_cif = clk_get(NULL, "pd_cif0");
+        cif_clk[0].aclk_cif = clk_get(NULL, "aclk_cif0");
+        cif_clk[0].hclk_cif = clk_get(NULL, "hclk_cif0");
+        cif_clk[0].cif_clk_in = clk_get(NULL, "cif0_in");
+        cif_clk[0].cif_clk_out = clk_get(NULL, "cif0_out");
+        spin_lock_init(&cif_clk[0].lock);
+        cif_clk[0].on = false;
         rk_camera_cif_iomux(0);
     } else {
-        pcdev->pd_cif = clk_get(NULL, "pd_cif1");
-        pcdev->aclk_cif = clk_get(NULL, "aclk_cif1");
-        pcdev->hclk_cif = clk_get(NULL, "hclk_cif1");
-        pcdev->cif_clk_in = clk_get(NULL, "cif1_in");
-        pcdev->cif_clk_out = clk_get(NULL, "cif1_out");
+        clk = &cif_clk[1];
+        cif_clk[1].pd_cif = clk_get(NULL, "pd_cif1");
+        cif_clk[1].aclk_cif = clk_get(NULL, "aclk_cif1");
+        cif_clk[1].hclk_cif = clk_get(NULL, "hclk_cif1");
+        cif_clk[1].cif_clk_in = clk_get(NULL, "cif1_in");
+        cif_clk[1].cif_clk_out = clk_get(NULL, "cif1_out");
+        spin_lock_init(&cif_clk[1].lock);
+        cif_clk[1].on = false;
         
         rk_camera_cif_iomux(1);
     }
     
-    if(IS_ERR(pcdev->pd_cif) || IS_ERR(pcdev->aclk_cif) || IS_ERR(pcdev->hclk_cif) || IS_ERR(pcdev->cif_clk_in) || IS_ERR(pcdev->cif_clk_out)){
-        RKCAMERA_TR(KERN_ERR "%s(%d): failed to get cif clock source\n",__FUNCTION__,__LINE__);
-        err = -ENOENT;
-        goto exit_reqmem_vip;
-    }
     
     dev_set_drvdata(&pdev->dev, pcdev);
     pcdev->res = res;
     pcdev->pdata = pdev->dev.platform_data;             /* ddl@rock-chips.com : Request IO in init function */
-
+       pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
        if (pcdev->pdata && pcdev->pdata->io_init) {
         pcdev->pdata->io_init();
     }
@@ -3088,12 +3452,12 @@ static int rk_camera_probe(struct platform_device *pdev)
         
             if (!request_mem_region(meminfo_ptr->start,meminfo_ptr->size,"rk29_vipmem")) {
                 err = -EBUSY;
-                RKCAMERA_TR("%s(%d): request_mem_region(start:0x%x size:0x%x) failed \n",__FUNCTION__,__LINE__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
+                RK30_CAM_DEBUG_TRACE("%s(%d): request_mem_region(start:0x%x size:0x%x) failed \n",__FUNCTION__,__LINE__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
                 goto exit_ioremap_vipmem;
             }
             meminfo_ptr->vbase = pcdev->vipmem_virbase = ioremap_cached(meminfo_ptr->start,meminfo_ptr->size);
             if (pcdev->vipmem_virbase == NULL) {
-                RKCAMERA_TR("%s(%d): ioremap of CIF internal memory(Ex:IPP process/raw process) failed\n",__FUNCTION__,__LINE__);
+                RK30_CAM_DEBUG_TRACE("%s(%d): ioremap of CIF internal memory(Ex:IPP process/raw process) failed\n",__FUNCTION__,__LINE__);
                 err = -ENXIO;
                 goto exit_ioremap_vipmem;
             }
@@ -3108,6 +3472,7 @@ static int rk_camera_probe(struct platform_device *pdev)
     INIT_LIST_HEAD(&pcdev->camera_work_queue);
     spin_lock_init(&pcdev->lock);
     spin_lock_init(&pcdev->camera_work_lock);
+ //   spin_lock_init(&pcdev->irq_lock);
     sema_init(&pcdev->zoominfo.sem,1);
 
     /*
@@ -3181,7 +3546,7 @@ static int rk_camera_probe(struct platform_device *pdev)
 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
        pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp; 
 #endif
-    RKCAMERA_DG("%s(%d) Exit  \n",__FUNCTION__,__LINE__);
+    RK30_CAM_DEBUG_TRACE("%s(%d) Exit  \n",__FUNCTION__,__LINE__);
     return 0;
 
 exit_free_irq:
@@ -3259,7 +3624,7 @@ static int __devexit rk_camera_remove(struct platform_device *pdev)
         if (meminfo_ptr->vbase == meminfo_ptrr->vbase) {
             meminfo_ptr->vbase = NULL;
         } else {
-            iounmap((void __iomem*)pcdev->vipmem_phybase);
+            iounmap((void __iomem*)pcdev->vipmem_virbase);
             release_mem_region(pcdev->vipmem_phybase, pcdev->vipmem_size);
             meminfo_ptr->vbase = NULL;
         }
@@ -3297,7 +3662,7 @@ static int rk_camera_init_async(void *unused)
 
 static int __devinit rk_camera_init(void)
 {
-    RKCAMERA_DG("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
+    RK30_CAM_DEBUG_TRACE("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
     kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
     return 0;
 }
index d27e88b33ea4e27a874bfdf215cf843b84bc2946..0348a5b6bbbf56cac6d3882322cee412ade2c23b 100644 (file)
@@ -2252,7 +2252,7 @@ static unsigned long cmd_input_size(unsigned int cmd)
                CMDINSIZE(ENCODER_CMD,          encoder_cmd,    flags);
                CMDINSIZE(TRY_ENCODER_CMD,      encoder_cmd,    flags);
                CMDINSIZE(G_SLICED_VBI_CAP,     sliced_vbi_cap, type);
-               CMDINSIZE(ENUM_FRAMESIZES,      frmsizeenum,    pixel_format);
+               CMDINSIZE(ENUM_FRAMESIZES,      frmsizeenum,    reserved[1]);
                CMDINSIZE(ENUM_FRAMEINTERVALS,  frmivalenum,    height);
        default:
                return _IOC_SIZE(cmd);
index f1ba530824d29ba7ffdae415bb22d0bf3a350843..7f001c4e68eb877966d9de14b1d08f1e2f80d1c3 100644 (file)
@@ -1404,6 +1404,18 @@ enum  v4l2_exposure_auto_type {
 #define V4L2_CID_FOCUS_CONTINUOUS              (V4L2_CID_CAMERA_CLASS_BASE_ROCK+4)
 #define V4L2_CID_FOCUSZONE       (V4L2_CID_CAMERA_CLASS_BASE_ROCK+5)
 #define V4L2_CID_FACEDETECT (V4L2_CID_CAMERA_CLASS_BASE_ROCK+6)
+#define V4L2_CID_HDR        (V4L2_CID_CAMERA_CLASS_BASE_ROCK+7) 
+
+/* nelson_yang@asus.com : Add ioctrl - V4L2_CID_ISO for camera ISO control */
+#define V4L2_CID_CAMERA_CLASS_BASE_ASUS                (V4L2_CID_CAMERA_CLASS_BASE + 50)
+#define V4L2_CID_ISO                           (V4L2_CID_CAMERA_CLASS_BASE_ASUS + 1)
+#define V4L2_CID_ANTIBANDING           (V4L2_CID_CAMERA_CLASS_BASE_ASUS + 2)
+#define V4L2_CID_WHITEBALANCE_LOCK     (V4L2_CID_CAMERA_CLASS_BASE_ASUS + 3)
+#define V4L2_CID_EXPOSURE_LOCK         (V4L2_CID_CAMERA_CLASS_BASE_ASUS + 4)
+#define V4L2_CID_METERING_AREAS                (V4L2_CID_CAMERA_CLASS_BASE_ASUS + 5)
+#define V4L2_CID_WDR                           (V4L2_CID_CAMERA_CLASS_BASE_ASUS + 6)
+#define V4L2_CID_EDGE                          (V4L2_CID_CAMERA_CLASS_BASE_ASUS + 7)
+#define V4L2_CID_JPEG_EXIF                     (V4L2_CID_CAMERA_CLASS_BASE_ASUS + 8)
 
 /* FM Modulator class control IDs */
 #define V4L2_CID_FM_TX_CLASS_BASE              (V4L2_CTRL_CLASS_FM_TX | 0x900)
index 4bddbb54b68ded5dd0b2957b03e98f14a79993b9..96d18ce42224bcbe22d63011e80c6f899138af29 100755 (executable)
@@ -93,7 +93,8 @@ enum {
        V4L2_IDENT_S5K5CA = 311,                                                        /* ddl@rock-chips.com : s5k5ca support */
 
        V4L2_IDENT_MTK9335ISP = 320,                                                    /* ddl@rock-chips.com : MTK9335ISP support */
-
+       V4L2_IDENT_ICATCH7002_MI1040 = 321,
+       V4L2_IDENT_ICATCH7002_OV5693 =322,
        /* Conexant MPEG encoder/decoders: reserved range 400-420 */
        V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */
        V4L2_IDENT_CX23415 = 415,